From 77e094524a968f7c2e3c0634baba214eb2f405ff Mon Sep 17 00:00:00 2001 From: Bosch Sensortec Date: Tue, 1 Dec 2020 11:37:52 +0100 Subject: [PATCH] Updated BMI270 sensor API and added the variants. Added more examples. --- LICENSE | 10 +- OIS_README.md | 8 +- bmi2.c | 17677 ++++------------ bmi2.h | 1064 +- bmi270.c | 3895 +++- bmi270.h | 355 +- bmi270_context.c | 2581 ++- bmi270_context.h | 440 +- bmi270_hc.c | 3165 +++ bmi270_hc.h | 483 + bmi270_maximum_fifo.c | 208 + bmi270_maximum_fifo.h | 117 + bmi270_wh.c | 3431 +++ bmi270_wh.h | 402 + bmi2_defs.h | 509 +- bmi2_ois.c | 8 +- bmi2_ois.h | 22 +- examples/bmi270/accel/Makefile | 18 + examples/bmi270/accel/accel.c | 200 + examples/bmi270/accel_gyro/Makefile | 18 + examples/bmi270/accel_gyro/accel_gyro.c | 268 + examples/bmi270/any_motion_interrupt/Makefile | 18 + .../any_motion_interrupt.c | 272 +- .../bmi2_common.c => common/common.c} | 716 +- examples/bmi270/common/common.h | 122 + examples/bmi270/component_retrim/Makefile | 18 + .../component_retrim.c | 101 +- .../bmi270/fifo_full_header_mode/Makefile | 18 + .../fifo_full_header_mode.c | 613 +- .../bmi270/fifo_full_headerless_mode/Makefile | 18 + .../fifo_full_headerless_mode.c | 588 +- .../fifo_watermark_header_mode/Makefile | 18 + .../fifo_watermark_header_mode.c | 335 + .../fifo_watermark_headerless_mode/Makefile | 18 + .../fifo_watermark_headerless_mode.c | 331 + examples/bmi270/generic/bmi2_common.h | 141 - examples/bmi270/gyro/Makefile | 18 + examples/bmi270/gyro/gyro.c | 195 + examples/bmi270/no_motion_interrupt/Makefile | 18 + .../no_motion_interrupt.c | 271 +- examples/bmi270/read_aux_data_mode/Makefile | 23 + .../read_aux_data_mode/read_aux_data_mode.c | 327 + examples/bmi270/read_aux_manual_mode/Makefile | 23 + .../read_aux_manual_mode.c | 322 + examples/bmi270/sig_motion/Makefile | 18 + .../{generic => sig_motion}/sig_motion.c | 187 +- examples/bmi270/step_activity/Makefile | 18 + .../step_activity.c | 221 +- examples/bmi270/step_counter/Makefile | 18 + .../{generic => step_counter}/step_counter.c | 293 +- examples/bmi270/wrist_gesture/Makefile | 18 + .../wrist_gesture.c | 295 +- examples/bmi270/wrist_wear_wakeup/Makefile | 18 + .../wrist_wear_wakeup.c | 264 +- examples/bmi270_context/accel/Makefile | 18 + examples/bmi270_context/accel/accel.c | 200 + examples/bmi270_context/accel_gyro/Makefile | 18 + .../bmi270_context/accel_gyro/accel_gyro.c | 268 + .../activity_recognition/Makefile | 18 + .../activity_recognition.c | 154 + examples/bmi270_context/common/common.c | 372 + examples/bmi270_context/common/common.h | 122 + .../bmi270_context/component_retrim/Makefile | 18 + .../component_retrim/component_retrim.c | 52 + .../fifo_full_header_mode/Makefile | 18 + .../fifo_full_header_mode.c | 315 + .../fifo_full_headerless_mode/Makefile | 18 + .../fifo_full_headerless_mode.c | 304 + .../fifo_watermark_header_mode/Makefile | 18 + .../fifo_watermark_header_mode.c | 335 + .../fifo_watermark_headerless_mode/Makefile | 18 + .../fifo_watermark_headerless_mode.c | 331 + examples/bmi270_context/gyro/Makefile | 18 + examples/bmi270_context/gyro/gyro.c | 195 + examples/bmi270_context/step_counter/Makefile | 18 + .../step_counter/step_counter.c | 146 + examples/bmi270_hc/accel/Makefile | 18 + examples/bmi270_hc/accel/accel.c | 201 + examples/bmi270_hc/accel_gyro/Makefile | 18 + examples/bmi270_hc/accel_gyro/accel_gyro.c | 268 + .../bmi270_hc/activity_recognition/Makefile | 18 + .../activity_recognition.c | 154 + examples/bmi270_hc/common/common.c | 372 + examples/bmi270_hc/common/common.h | 122 + examples/bmi270_hc/component_retrim/Makefile | 18 + .../component_retrim/component_retrim.c | 52 + .../bmi270_hc/fifo_full_header_mode/Makefile | 18 + .../fifo_full_header_mode.c | 316 + .../fifo_full_headerless_mode/Makefile | 18 + .../fifo_full_headerless_mode.c | 304 + .../fifo_watermark_header_mode/Makefile | 18 + .../fifo_watermark_header_mode.c | 335 + .../fifo_watermark_headerless_mode/Makefile | 18 + .../fifo_watermark_headerless_mode.c | 331 + examples/bmi270_hc/gyro/Makefile | 18 + examples/bmi270_hc/gyro/gyro.c | 195 + examples/bmi270_hc/step_counter/Makefile | 18 + .../bmi270_hc/step_counter/step_counter.c | 146 + examples/bmi270_maximum_fifo/accel/Makefile | 18 + .../accel}/accel.c | 396 +- .../bmi270_maximum_fifo/accel_gyro/Makefile | 18 + .../accel_gyro/accel_gyro.c | 268 + examples/bmi270_maximum_fifo/common/common.c | 372 + examples/bmi270_maximum_fifo/common/common.h | 122 + .../component_retrim/Makefile | 18 + .../component_retrim/component_retrim.c | 52 + .../fifo_watermark_header_mode/Makefile | 18 + .../fifo_watermark_header_mode.c | 652 +- .../fifo_watermark_headerless_mode/Makefile | 18 + .../fifo_watermark_headerless_mode.c | 640 +- examples/bmi270_maximum_fifo/gyro/Makefile | 18 + .../gyro}/gyro.c | 386 +- examples/bmi270_wh/accel/Makefile | 18 + examples/bmi270_wh/accel/accel.c | 201 + examples/bmi270_wh/accel_gyro/Makefile | 18 + examples/bmi270_wh/accel_gyro/accel_gyro.c | 268 + .../bmi270_wh/any_motion_interrupt/Makefile | 18 + .../any_motion_interrupt.c | 134 + examples/bmi270_wh/common/common.c | 372 + examples/bmi270_wh/common/common.h | 122 + .../bmi270_wh/fifo_full_header_mode/Makefile | 18 + .../fifo_full_header_mode.c | 316 + .../fifo_full_headerless_mode/Makefile | 18 + .../fifo_full_headerless_mode.c | 304 + .../fifo_watermark_header_mode/Makefile | 18 + .../fifo_watermark_header_mode.c | 335 + .../fifo_watermark_headerless_mode/Makefile | 18 + .../fifo_watermark_headerless_mode.c | 331 + examples/bmi270_wh/gyro/Makefile | 18 + examples/bmi270_wh/gyro/gyro.c | 195 + .../bmi270_wh/no_motion_interrupt/Makefile | 18 + .../no_motion_interrupt/no_motion_interrupt.c | 135 + .../bmi270_wh/read_aux_data_mode/Makefile | 23 + .../read_aux_data_mode/read_aux_data_mode.c | 327 + .../bmi270_wh/read_aux_manual_mode/Makefile | 23 + .../read_aux_manual_mode.c | 322 + examples/bmi270_wh/step_activity/Makefile | 18 + .../bmi270_wh/step_activity/step_activity.c | 110 + examples/bmi270_wh/step_counter/Makefile | 18 + .../bmi270_wh/step_counter/step_counter.c | 146 + examples/bmi270_wh/wrist_wear_wakeup/Makefile | 18 + .../wrist_wear_wakeup/wrist_wear_wakeup.c | 131 + examples/bmi2_ois/common/common.c | 153 + examples/bmi2_ois/common/common.h | 92 + examples/bmi2_ois/ois_accel_gyro/Makefile | 18 + .../ois_accel_gyro}/ois_accel_gyro.c | 233 +- examples/ois/generic/bmi2_ois_common.c | 119 - examples/ois/generic/bmi2_ois_common.h | 90 - 148 files changed, 36331 insertions(+), 18084 deletions(-) create mode 100644 bmi270_hc.c create mode 100644 bmi270_hc.h create mode 100644 bmi270_maximum_fifo.c create mode 100644 bmi270_maximum_fifo.h create mode 100644 bmi270_wh.c create mode 100644 bmi270_wh.h create mode 100644 examples/bmi270/accel/Makefile create mode 100644 examples/bmi270/accel/accel.c create mode 100644 examples/bmi270/accel_gyro/Makefile create mode 100644 examples/bmi270/accel_gyro/accel_gyro.c create mode 100644 examples/bmi270/any_motion_interrupt/Makefile rename examples/bmi270/{generic => any_motion_interrupt}/any_motion_interrupt.c (87%) rename examples/bmi270/{generic/bmi2_common.c => common/common.c} (68%) create mode 100644 examples/bmi270/common/common.h create mode 100644 examples/bmi270/component_retrim/Makefile rename examples/bmi270/{generic => component_retrim}/component_retrim.c (81%) create mode 100644 examples/bmi270/fifo_full_header_mode/Makefile rename examples/bmi270/{generic => fifo_full_header_mode}/fifo_full_header_mode.c (82%) create mode 100644 examples/bmi270/fifo_full_headerless_mode/Makefile rename examples/bmi270/{generic => fifo_full_headerless_mode}/fifo_full_headerless_mode.c (83%) create mode 100644 examples/bmi270/fifo_watermark_header_mode/Makefile create mode 100644 examples/bmi270/fifo_watermark_header_mode/fifo_watermark_header_mode.c create mode 100644 examples/bmi270/fifo_watermark_headerless_mode/Makefile create mode 100644 examples/bmi270/fifo_watermark_headerless_mode/fifo_watermark_headerless_mode.c delete mode 100644 examples/bmi270/generic/bmi2_common.h create mode 100644 examples/bmi270/gyro/Makefile create mode 100644 examples/bmi270/gyro/gyro.c create mode 100644 examples/bmi270/no_motion_interrupt/Makefile rename examples/bmi270/{generic => no_motion_interrupt}/no_motion_interrupt.c (87%) create mode 100644 examples/bmi270/read_aux_data_mode/Makefile create mode 100644 examples/bmi270/read_aux_data_mode/read_aux_data_mode.c create mode 100644 examples/bmi270/read_aux_manual_mode/Makefile create mode 100644 examples/bmi270/read_aux_manual_mode/read_aux_manual_mode.c create mode 100644 examples/bmi270/sig_motion/Makefile rename examples/bmi270/{generic => sig_motion}/sig_motion.c (85%) create mode 100644 examples/bmi270/step_activity/Makefile rename examples/bmi270/{generic => step_activity}/step_activity.c (83%) create mode 100644 examples/bmi270/step_counter/Makefile rename examples/bmi270/{generic => step_counter}/step_counter.c (84%) create mode 100644 examples/bmi270/wrist_gesture/Makefile rename examples/bmi270/{generic => wrist_gesture}/wrist_gesture.c (86%) create mode 100644 examples/bmi270/wrist_wear_wakeup/Makefile rename examples/bmi270/{generic => wrist_wear_wakeup}/wrist_wear_wakeup.c (86%) create mode 100644 examples/bmi270_context/accel/Makefile create mode 100644 examples/bmi270_context/accel/accel.c create mode 100644 examples/bmi270_context/accel_gyro/Makefile create mode 100644 examples/bmi270_context/accel_gyro/accel_gyro.c create mode 100644 examples/bmi270_context/activity_recognition/Makefile create mode 100644 examples/bmi270_context/activity_recognition/activity_recognition.c create mode 100644 examples/bmi270_context/common/common.c create mode 100644 examples/bmi270_context/common/common.h create mode 100644 examples/bmi270_context/component_retrim/Makefile create mode 100644 examples/bmi270_context/component_retrim/component_retrim.c create mode 100644 examples/bmi270_context/fifo_full_header_mode/Makefile create mode 100644 examples/bmi270_context/fifo_full_header_mode/fifo_full_header_mode.c create mode 100644 examples/bmi270_context/fifo_full_headerless_mode/Makefile create mode 100644 examples/bmi270_context/fifo_full_headerless_mode/fifo_full_headerless_mode.c create mode 100644 examples/bmi270_context/fifo_watermark_header_mode/Makefile create mode 100644 examples/bmi270_context/fifo_watermark_header_mode/fifo_watermark_header_mode.c create mode 100644 examples/bmi270_context/fifo_watermark_headerless_mode/Makefile create mode 100644 examples/bmi270_context/fifo_watermark_headerless_mode/fifo_watermark_headerless_mode.c create mode 100644 examples/bmi270_context/gyro/Makefile create mode 100644 examples/bmi270_context/gyro/gyro.c create mode 100644 examples/bmi270_context/step_counter/Makefile create mode 100644 examples/bmi270_context/step_counter/step_counter.c create mode 100644 examples/bmi270_hc/accel/Makefile create mode 100644 examples/bmi270_hc/accel/accel.c create mode 100644 examples/bmi270_hc/accel_gyro/Makefile create mode 100644 examples/bmi270_hc/accel_gyro/accel_gyro.c create mode 100644 examples/bmi270_hc/activity_recognition/Makefile create mode 100644 examples/bmi270_hc/activity_recognition/activity_recognition.c create mode 100644 examples/bmi270_hc/common/common.c create mode 100644 examples/bmi270_hc/common/common.h create mode 100644 examples/bmi270_hc/component_retrim/Makefile create mode 100644 examples/bmi270_hc/component_retrim/component_retrim.c create mode 100644 examples/bmi270_hc/fifo_full_header_mode/Makefile create mode 100644 examples/bmi270_hc/fifo_full_header_mode/fifo_full_header_mode.c create mode 100644 examples/bmi270_hc/fifo_full_headerless_mode/Makefile create mode 100644 examples/bmi270_hc/fifo_full_headerless_mode/fifo_full_headerless_mode.c create mode 100644 examples/bmi270_hc/fifo_watermark_header_mode/Makefile create mode 100644 examples/bmi270_hc/fifo_watermark_header_mode/fifo_watermark_header_mode.c create mode 100644 examples/bmi270_hc/fifo_watermark_headerless_mode/Makefile create mode 100644 examples/bmi270_hc/fifo_watermark_headerless_mode/fifo_watermark_headerless_mode.c create mode 100644 examples/bmi270_hc/gyro/Makefile create mode 100644 examples/bmi270_hc/gyro/gyro.c create mode 100644 examples/bmi270_hc/step_counter/Makefile create mode 100644 examples/bmi270_hc/step_counter/step_counter.c create mode 100644 examples/bmi270_maximum_fifo/accel/Makefile rename examples/{bmi270/generic => bmi270_maximum_fifo/accel}/accel.c (81%) create mode 100644 examples/bmi270_maximum_fifo/accel_gyro/Makefile create mode 100644 examples/bmi270_maximum_fifo/accel_gyro/accel_gyro.c create mode 100644 examples/bmi270_maximum_fifo/common/common.c create mode 100644 examples/bmi270_maximum_fifo/common/common.h create mode 100644 examples/bmi270_maximum_fifo/component_retrim/Makefile create mode 100644 examples/bmi270_maximum_fifo/component_retrim/component_retrim.c create mode 100644 examples/bmi270_maximum_fifo/fifo_watermark_header_mode/Makefile rename examples/{bmi270/generic => bmi270_maximum_fifo/fifo_watermark_header_mode}/fifo_watermark_header_mode.c (83%) create mode 100644 examples/bmi270_maximum_fifo/fifo_watermark_headerless_mode/Makefile rename examples/{bmi270/generic => bmi270_maximum_fifo/fifo_watermark_headerless_mode}/fifo_watermark_headerless_mode.c (83%) create mode 100644 examples/bmi270_maximum_fifo/gyro/Makefile rename examples/{bmi270/generic => bmi270_maximum_fifo/gyro}/gyro.c (82%) create mode 100644 examples/bmi270_wh/accel/Makefile create mode 100644 examples/bmi270_wh/accel/accel.c create mode 100644 examples/bmi270_wh/accel_gyro/Makefile create mode 100644 examples/bmi270_wh/accel_gyro/accel_gyro.c create mode 100644 examples/bmi270_wh/any_motion_interrupt/Makefile create mode 100644 examples/bmi270_wh/any_motion_interrupt/any_motion_interrupt.c create mode 100644 examples/bmi270_wh/common/common.c create mode 100644 examples/bmi270_wh/common/common.h create mode 100644 examples/bmi270_wh/fifo_full_header_mode/Makefile create mode 100644 examples/bmi270_wh/fifo_full_header_mode/fifo_full_header_mode.c create mode 100644 examples/bmi270_wh/fifo_full_headerless_mode/Makefile create mode 100644 examples/bmi270_wh/fifo_full_headerless_mode/fifo_full_headerless_mode.c create mode 100644 examples/bmi270_wh/fifo_watermark_header_mode/Makefile create mode 100644 examples/bmi270_wh/fifo_watermark_header_mode/fifo_watermark_header_mode.c create mode 100644 examples/bmi270_wh/fifo_watermark_headerless_mode/Makefile create mode 100644 examples/bmi270_wh/fifo_watermark_headerless_mode/fifo_watermark_headerless_mode.c create mode 100644 examples/bmi270_wh/gyro/Makefile create mode 100644 examples/bmi270_wh/gyro/gyro.c create mode 100644 examples/bmi270_wh/no_motion_interrupt/Makefile create mode 100644 examples/bmi270_wh/no_motion_interrupt/no_motion_interrupt.c create mode 100644 examples/bmi270_wh/read_aux_data_mode/Makefile create mode 100644 examples/bmi270_wh/read_aux_data_mode/read_aux_data_mode.c create mode 100644 examples/bmi270_wh/read_aux_manual_mode/Makefile create mode 100644 examples/bmi270_wh/read_aux_manual_mode/read_aux_manual_mode.c create mode 100644 examples/bmi270_wh/step_activity/Makefile create mode 100644 examples/bmi270_wh/step_activity/step_activity.c create mode 100644 examples/bmi270_wh/step_counter/Makefile create mode 100644 examples/bmi270_wh/step_counter/step_counter.c create mode 100644 examples/bmi270_wh/wrist_wear_wakeup/Makefile create mode 100644 examples/bmi270_wh/wrist_wear_wakeup/wrist_wear_wakeup.c create mode 100644 examples/bmi2_ois/common/common.c create mode 100644 examples/bmi2_ois/common/common.h create mode 100644 examples/bmi2_ois/ois_accel_gyro/Makefile rename examples/{ois/generic => bmi2_ois/ois_accel_gyro}/ois_accel_gyro.c (82%) delete mode 100644 examples/ois/generic/bmi2_ois_common.c delete mode 100644 examples/ois/generic/bmi2_ois_common.h diff --git a/LICENSE b/LICENSE index df241f2..315dfa2 100644 --- a/LICENSE +++ b/LICENSE @@ -6,15 +6,15 @@ 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. + 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. + 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. + 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 diff --git a/OIS_README.md b/OIS_README.md index 0ee7418..6c05c68 100644 --- a/OIS_README.md +++ b/OIS_README.md @@ -15,7 +15,7 @@ - User has to include _bmi2_ois.h_ in the code to call OIS related APIs and a _variant header_ for initialization as well as BMI2 related API calls, as shown below: ``` c -#include "bmi261.h" +#include "bmi270.h" #include "bmi2_ois.h" ```` ### Driver files information @@ -86,7 +86,7 @@ if (rslt != BMI2_OK) { } /* Enable accelerometer and gyroscope through host interface */ -rslt = bmi2_sensor_enable(sens_list, 2, &dev); +rslt = bmi270_sensor_enable(sens_list, 2, &dev); if (rslt != BMI2_OK) { printf("Error: %d\n", rslt); return; @@ -167,6 +167,4 @@ if (rslt != BMI2_OK) { printf("Error: %d\n", rslt); return; } -``` - - \ No newline at end of file +``` \ No newline at end of file diff --git a/bmi2.c b/bmi2.c index 13b8b9a..30f3203 100644 --- a/bmi2.c +++ b/bmi2.c @@ -1,40 +1,40 @@ /** - * 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 bmi2.c - * @date 2020-06-05 - * @version v2.53.2 - * - */ +* 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 bmi2.c +* @date 2020-11-04 +* @version v2.63.1 +* +*/ /******************************************************************************/ @@ -110,9 +110,8 @@ struct bmi2_accel_offset * @param[in] dev : Structure instance of bmi2_dev. * * @return Result of API execution status - * - * @retval BMI2_OK - Success. - * @retval BMI2_E_COM_FAIL - Error: Communication fail + * @retval 0 -> Success + * @retval < 0 -> Fail */ static int8_t write_config_file(struct bmi2_dev *dev); @@ -124,9 +123,8 @@ static int8_t write_config_file(struct bmi2_dev *dev); * @param[in] dev : Structure instance of bmi2_dev. * * @return Result of API execution status - * - * @retval BMI2_OK - Success. - * @retval BMI2_E_COM_FAIL - Error: Communication fail + * @retval 0 -> Success + * @retval < 0 -> Fail */ static int8_t set_config_load(uint8_t enable, struct bmi2_dev *dev); @@ -138,10460 +136,1824 @@ static int8_t set_config_load(uint8_t enable, struct bmi2_dev *dev); * @param[in] dev : Structure instance of bmi2_dev. * * @return Result of API execution status - * - * @retval BMI2_OK - Success. - * @retval BMI2_E_COM_FAIL - Error: Communication fail + * @retval 0 -> Success + * @retval < 0 -> Fail */ static int8_t upload_file(const uint8_t *config_data, uint16_t index, uint16_t write_len, struct bmi2_dev *dev); /*! - * @brief This internal API enables the selected sensor/features. + * @brief This internal API sets accelerometer configurations like ODR, + * bandwidth, performance mode and g-range. * - * @param[in] sensor_sel : Selects the desired sensor. - * @param[in, out] dev : Structure instance of bmi2_dev. + * @param[in,out] config : Structure instance of bmi2_accel_config. + * @param[in,out] dev : Structure instance of bmi2_dev. * * @return Result of API execution status - * - * @retval BMI2_OK - Success. - * @retval BMI2_E_COM_FAIL - Error: Communication fail - * @retval BMI2_E_SET_APS_FAIL - Error: Set Advance Power Save Fail + * @retval 0 -> Success + * @retval < 0 -> Fail */ -static int8_t sensor_enable(uint64_t sensor_sel, struct bmi2_dev *dev); +static int8_t set_accel_config(struct bmi2_accel_config *config, struct bmi2_dev *dev); /*! - * @brief This internal API disables the selected sensor/features. + * @brief This internal API validates bandwidth and performance mode of the + * accelerometer set by the user. * - * @param[in] sensor_sel : Selects the desired sensor. - * @param[in, out] dev : Structure instance of bmi2_dev. + * @param[in, out] bandwidth : Pointer to bandwidth value set by the user. + * @param[in, out] perf_mode : Pointer to performance mode set by the user. + * @param[in, out] dev : Structure instance of bmi2_dev. * - * @return Result of API execution status + * @note dev->info contains two warnings: BMI2_I_MIN_VALUE and BMI2_I_MAX_VALUE * - * @retval BMI2_OK - Success. - * @retval BMI2_E_COM_FAIL - Error: Communication fail - * @retval BMI2_E_SET_APS_FAIL - Error: Set Advance Power Save Fail + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail */ -static int8_t sensor_disable(uint64_t sensor_sel, struct bmi2_dev *dev); +static int8_t validate_bw_perf_mode(uint8_t *bandwidth, uint8_t *perf_mode, struct bmi2_dev *dev); /*! - * @brief This internal API selects the sensors/features to be enabled or - * disabled. + * @brief This internal API validates ODR and range of the accelerometer set by + * the user. * - * @param[in] sens_list : Pointer to select the sensor. - * @param[in] n_sens : Number of sensors selected. - * @param[out] sensor_sel : Gets the selected sensor. + * @param[in, out] odr : Pointer to ODR value set by the user. + * @param[in, out] range : Pointer to range value set by the user. + * @param[in, out] dev : Structure instance of bmi2_dev. * - * @return Result of API execution status + * @note dev->info contains two warnings: BMI2_I_MIN_VALUE and BMI2_I_MAX_VALUE * - * @retval BMI2_OK - Success. - * @retval BMI2_E_INVALID_SENSOR - Error: Invalid sensor + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail */ -static int8_t select_sensor(const uint8_t *sens_list, uint8_t n_sens, uint64_t *sensor_sel); +static int8_t validate_odr_range(uint8_t *odr, uint8_t *range, struct bmi2_dev *dev); /*! - * @brief This internal API is used to enable/disable any-motion feature. - * - * @param[in] dev : Structure instance of bmi2_dev. - * @param[in] enable : Enables/Disables any-motion. + * @brief This internal API sets gyroscope configurations like ODR, bandwidth, + * low power/high performance mode, performance mode and range. * - * Enable | Description - * -------------|--------------- - * BMI2_DISABLE | Disables any-motion. - * BMI2_ENABLE | Enables any-motion. + * @param[in,out] config : Structure instance of bmi2_gyro_config. + * @param[in,out] dev : Structure instance of bmi2_dev. * * @return Result of API execution status - * - * @retval BMI2_OK - Success. - * @retval BMI2_E_COM_FAIL - Error: Communication fail - * @retval BMI2_E_INVALID_SENSOR - Error: Invalid sensor - * @retval BMI2_E_INVALID_PAGE - Error: Invalid Page + * @retval 0 -> Success + * @retval < 0 -> Fail */ -static int8_t set_any_motion(uint8_t enable, struct bmi2_dev *dev); +static int8_t set_gyro_config(struct bmi2_gyro_config *config, struct bmi2_dev *dev); /*! - * @brief This internal API is used to enable/disable no-motion feature. + * @brief This internal API validates bandwidth, performance mode, low power/ + * high performance mode, ODR, and range set by the user. * - * @param[in] dev : Structure instance of bmi2_dev. - * @param[in] enable : Enables/Disables no-motion. + * @param[in] config : Structure instance of bmi2_gyro_config. + * @param[in] dev : Structure instance of bmi2_dev. * - * Enable | Description - * -------------|--------------- - * BMI2_DISABLE | Disables no-motion. - * BMI2_ENABLE | Enables no-motion. + * @note dev->info contains two warnings: BMI2_I_MIN_VALUE and BMI2_I_MAX_VALUE * * @return Result of API execution status - * - * @retval BMI2_OK - Success. - * @retval BMI2_E_COM_FAIL - Error: Communication fail - * @retval BMI2_E_INVALID_SENSOR - Error: Invalid sensor - * @retval BMI2_E_INVALID_PAGE - Error: Invalid Page + * @retval 0 -> Success + * @retval < 0 -> Fail */ -static int8_t set_no_motion(uint8_t enable, struct bmi2_dev *dev); +static int8_t validate_gyro_config(struct bmi2_gyro_config *config, struct bmi2_dev *dev); /*! - * @brief This internal API is used to enable/disable sig-motion feature. - * - * @param[in] dev : Structure instance of bmi2_dev. - * @param[in] enable : Enables/Disables sig-motion. + * @brief This internal API shows the error status when illegal sensor + * configuration is set. * - * Enable | Description - * -------------|--------------- - * BMI2_DISABLE | Disables sig-motion. - * BMI2_ENABLE | Enables sig-motion. + * @param[in] dev : Structure instance of bmi2_dev. * * @return Result of API execution status - * - * @retval BMI2_OK - Success. - * @retval BMI2_E_COM_FAIL - Error: Communication fail - * @retval BMI2_E_INVALID_SENSOR - Error: Invalid sensor - * @retval BMI2_E_INVALID_PAGE - Error: Invalid Page + * @retval 0 -> Success + * @retval < 0 -> Fail */ -static int8_t set_sig_motion(uint8_t enable, struct bmi2_dev *dev); +static int8_t cfg_error_status(struct bmi2_dev *dev); /*! - * @brief This internal API is used to enable/disable step detector feature. - * - * @param[in] dev : Structure instance of bmi2_dev. - * @param[in] enable : Enables/Disables step-detector. + * @brief This internal API: + * 1) Enables/Disables auxiliary interface. + * 2) Sets auxiliary interface configurations like I2C address, manual/auto + * mode enable, manual burst read length, AUX burst read length and AUX read + * address. + * 3)It maps/un-maps data interrupts to that of hardware interrupt line. * - * Enable | Description - * -------------|--------------- - * BMI2_DISABLE | Disables step detector - * BMI2_ENABLE | Enables step detector + * @param[in] config : Structure instance of bmi2_aux_config. + * @param[in, out] dev : Structure instance of bmi2_dev. * * @return Result of API execution status - * - * @retval BMI2_OK - Success. - * @retval BMI2_E_COM_FAIL - Error: Communication fail - * @retval BMI2_E_INVALID_SENSOR - Error: Invalid sensor - * @retval BMI2_E_INVALID_PAGE - Error: Invalid Page + * @retval 0 -> Success + * @retval < 0 -> Fail */ -static int8_t set_step_detector(uint8_t enable, struct bmi2_dev *dev); +static int8_t set_aux_config(struct bmi2_aux_config *config, struct bmi2_dev *dev); /*! - * @brief This internal API is used to enable/disable step counter feature. + * @brief This internal API sets gyroscope user-gain configurations like gain + * update value for x, y and z-axis. * - * @param[in] dev : Structure instance of bmi2_dev. - * @param[in] enable : Enables/Disables step counter. + * @param[in] config : Structure instance of bmi2_gyro_user_gain_config. + * @param[in] dev : Structure instance of bmi2_dev. * - * Enable | Description - * -------------|--------------- - * BMI2_DISABLE | Disables step counter - * BMI2_ENABLE | Enables step counter + * @verbatim + *---------------------------------------------------------------------------- + * bmi2_gyro_user_gain_config| + * Structure parameters | Description + *--------------------------|-------------------------------------------------- + * ratio_x | Gain update value for x-axis + * -------------------------|--------------------------------------------------- + * ratio_y | Gain update value for y-axis + * -------------------------|--------------------------------------------------- + * ratio_z | Gain update value for z-axis + * @endverbatim * * @return Result of API execution status - * - * @retval BMI2_OK - Success. - * @retval BMI2_E_COM_FAIL - Error: Communication fail - * @retval BMI2_E_INVALID_SENSOR - Error: Invalid sensor - * @retval BMI2_E_INVALID_PAGE - Error: Invalid Page + * @retval 0 -> Success + * @retval < 0 -> Fail */ -static int8_t set_step_counter(uint8_t enable, struct bmi2_dev *dev); +static int8_t set_gyro_user_gain_config(const struct bmi2_gyro_user_gain_config *config, struct bmi2_dev *dev); /*! - * @brief This internal API is used to enable/disable step activity detection. - * - * @param[in] dev : Structure instance of bmi2_dev. - * @param[in] enable : Enables/Disables step activity. + * @brief This internal API enables/disables auxiliary interface. * - * Enable | Description - * -------------|--------------- - * BMI2_DISABLE | Disables step activity - * BMI2_ENABLE | Enables step activity + * @param[in] config : Structure instance of bmi2_aux_config. + * @param[in] dev : Structure instance of bmi2_dev. * * @return Result of API execution status - * - * @retval BMI2_OK - Success. - * @retval BMI2_E_COM_FAIL - Error: Communication fail - * @retval BMI2_E_INVALID_SENSOR - Error: Invalid sensor - * @retval BMI2_E_INVALID_PAGE - Error: Invalid Page + * @retval 0 -> Success + * @retval < 0 -> Fail */ -static int8_t set_step_activity(uint8_t enable, struct bmi2_dev *dev); +static int8_t set_aux_interface(const struct bmi2_aux_config *config, struct bmi2_dev *dev); /*! - * @brief This internal API is used to enable/disable tilt feature. + * @brief This internal API sets auxiliary configurations like manual/auto mode + * FCU write command enable and read burst length for both data and manual mode. * - * @param[in] dev : Structure instance of bmi2_dev. - * @param[in] enable : Enables/Disables tilt. + * @param[in] config : Structure instance of bmi2_aux_config. + * @param[in] dev : Structure instance of bmi2_dev. * - * Enable | Description - * -------------|--------------- - * BMI2_DISABLE | Disables tilt - * BMI2_ENABLE | Enables tilt + * @note Auxiliary sensor should not be busy when configuring aux_i2c_addr, + * man_rd_burst_len, aux_rd_burst_len and aux_rd_addr. * * @return Result of API execution status - * - * @retval BMI2_OK - Success. - * @retval BMI2_E_COM_FAIL - Error: Communication fail - * @retval BMI2_E_INVALID_SENSOR - Error: Invalid sensor - * @retval BMI2_E_INVALID_PAGE - Error: Invalid Page + * @retval 0 -> Success + * @retval < 0 -> Fail */ -static int8_t set_tilt(uint8_t enable, struct bmi2_dev *dev); +static int8_t config_aux_interface(const struct bmi2_aux_config *config, struct bmi2_dev *dev); /*! - * @brief This internal API is used to enable/disable uphold to wake feature. - * - * @param[in] dev : Structure instance of bmi2_dev. - * @param[in] enable : Enables/Disables uphold to wake. + * @brief This internal API triggers read out offset and sets ODR of the + * auxiliary sensor. * - * Enable | Description - * -------------|--------------- - * BMI2_DISABLE | Disables uphold to wake - * BMI2_ENABLE | Enables uphold to wake + * @param[in] config : Structure instance of bmi2_aux_config. + * @param[in] dev : Structure instance of bmi2_dev. * * @return Result of API execution status - * - * @retval BMI2_OK - Success. - * @retval BMI2_E_COM_FAIL - Error: Communication fail - * @retval BMI2_E_INVALID_SENSOR - Error: Invalid sensor - * @retval BMI2_E_INVALID_PAGE - Error: Invalid Page + * @retval 0 -> Success + * @retval < 0 -> Fail */ -static int8_t set_up_hold_to_wake(uint8_t enable, struct bmi2_dev *dev); +static int8_t config_aux(const struct bmi2_aux_config *config, struct bmi2_dev *dev); /*! - * @brief This internal API is used to enable/disable glance detector feature. + * @brief This internal API validates auxiliary configuration set by the user. * - * @param[in] dev : Structure instance of bmi2_dev. - * @param[in] enable : Enables/Disables glance. + * @param[in, out] config : Structure instance of bmi2_aux_config. + * @param[in, out] dev : Structure instance of bmi2_dev. * - * Enable | Description - * -------------|--------------- - * BMI2_DISABLE | Disables glance detector - * BMI2_ENABLE | Enables glance detector + * @note dev->info contains two warnings: BMI2_I_MIN_VALUE and BMI2_I_MAX_VALUE * * @return Result of API execution status - * - * @retval BMI2_OK - Success. - * @retval BMI2_E_COM_FAIL - Error: Communication fail - * @retval BMI2_E_INVALID_SENSOR - Error: Invalid sensor - * @retval BMI2_E_INVALID_PAGE - Error: Invalid Page + * @retval 0 -> Success + * @retval < 0 -> Fail */ -static int8_t set_glance_detector(uint8_t enable, struct bmi2_dev *dev); +static int8_t validate_aux_config(struct bmi2_aux_config *config, struct bmi2_dev *dev); /*! - * @brief This internal API is used to enable/disable wake-up feature through - * single or double tap. - * - * @param[in] dev : Structure instance of bmi2_dev. - * @param[in] enable : Enables/Disables single or double tap. + * @brief This internal API gets accelerometer configurations like ODR, + * bandwidth, performance mode and g-range. * - * Enable | Description - * -------------|--------------- - * BMI2_DISABLE | Disables single, double and triple tap. - * BMI2_ENABLE | Enables single, double and triple tap. + * @param[out] config : Structure instance of bmi2_accel_config. + * @param[in] dev : Structure instance of bmi2_dev. * * @return Result of API execution status - * - * @retval BMI2_OK - Success. - * @retval BMI2_E_COM_FAIL - Error: Communication fail - * @retval BMI2_E_INVALID_SENSOR - Error: Invalid sensor - * @retval BMI2_E_INVALID_PAGE - Error: Invalid Page + * @retval 0 -> Success + * @retval < 0 -> Fail */ -static int8_t set_wake_up(uint8_t enable, struct bmi2_dev *dev); +static int8_t get_accel_config(struct bmi2_accel_config *config, struct bmi2_dev *dev); /*! - * @brief This internal API is used to enable/disable wake-up feature through - * single tap. - * - * @param[in] dev : Structure instance of bmi2_dev. - * @param[in] enable : Enables/Disables single tap. + * @brief This internal API gets gyroscope configurations like ODR, bandwidth, + * low power/ high performance mode, performance mode and range. * - * Enable | Description - * -------------|--------------- - * BMI2_DISABLE | Disables single tap. - * BMI2_ENABLE | Enables single tap + * @param[out] config : Structure instance of bmi2_gyro_config. + * @param[in] dev : Structure instance of bmi2_dev. * * @return Result of API execution status - * - * @retval BMI2_OK - Success. - * @retval BMI2_E_COM_FAIL - Error: Communication fail - * @retval BMI2_E_INVALID_SENSOR - Error: Invalid sensor - * @retval BMI2_E_INVALID_PAGE - Error: Invalid Page + * @retval 0 -> Success + * @retval < 0 -> Fail */ -static int8_t set_single_tap(uint8_t enable, struct bmi2_dev *dev); +static int8_t get_gyro_config(struct bmi2_gyro_config *config, struct bmi2_dev *dev); /*! - * @brief This internal API is used to enable/disable wake-up feature through - * double tap. - * - * @param[in] dev : Structure instance of bmi2_dev. - * @param[in] enable : Enables/Disables double tap. + * @brief This internal API: + * 1) Gets the status of auxiliary interface enable. + * 2) Gets auxiliary interface configurations like I2C address, manual/auto + * mode enable, manual burst read length, AUX burst read length and AUX read + * address. + * 3) Gets ODR and offset. * - * Enable | Description - * -------------|--------------- - * BMI2_DISABLE | Disables double tap. - * BMI2_ENABLE | Enables double tap + * @param[out] config : Structure instance of bmi2_aux_config. + * @param[in] dev : Structure instance of bmi2_dev. * * @return Result of API execution status - * - * @retval BMI2_OK - Success. - * @retval BMI2_E_COM_FAIL - Error: Communication fail - * @retval BMI2_E_INVALID_SENSOR - Error: Invalid sensor - * @retval BMI2_E_INVALID_PAGE - Error: Invalid Page + * @retval 0 -> Success + * @retval < 0 -> Fail */ -static int8_t set_double_tap(uint8_t enable, struct bmi2_dev *dev); +static int8_t get_aux_config(struct bmi2_aux_config *config, struct bmi2_dev *dev); /*! - * @brief This internal API is used to enable/disable wake-up feature through - * triple tap. + * @brief This internal API gets gyroscope user-gain configurations like gain + * update value for x, y and z-axis. * - * @param[in] dev : Structure instance of bmi2_dev. - * @param[in] enable : Enables/Disables triple tap. + * @param[out] config : Structure instance of bmi2_gyro_user_gain_config. + * @param[in] dev : Structure instance of bmi2_dev. * - * Enable | Description - * -------------|--------------- - * BMI2_DISABLE | Disables triple tap. - * BMI2_ENABLE | Enables triple tap + * @verbatim + *---------------------------------------------------------------------------- + * bmi2_gyro_user_gain_config| + * Structure parameters | Description + *-------------------------|-------------------------------------------------- + * ratio_x | Gain update value for x-axis + * ------------------------|--------------------------------------------------- + * ratio_y | Gain update value for y-axis + * ------------------------|--------------------------------------------------- + * ratio_z | Gain update value for z-axis * - * @return Result of API execution status + * @endverbatim * - * @retval BMI2_OK - Success. - * @retval BMI2_E_COM_FAIL - Error: Communication fail - * @retval BMI2_E_INVALID_SENSOR - Error: Invalid sensor - * @retval BMI2_E_INVALID_PAGE - Error: Invalid Page + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail */ -static int8_t set_triple_tap(uint8_t enable, struct bmi2_dev *dev); +static int8_t get_gyro_gain_update_config(struct bmi2_gyro_user_gain_config *config, struct bmi2_dev *dev); /*! - * @brief This internal API is used to enable/disable orientation feature. - * - * @param[in] dev : Structure instance of bmi2_dev. - * @param[in] enable : Enables/Disables orientation. + * @brief This internal API gets the enable status of auxiliary interface. * - * Enable | Description - * -------------|--------------- - * BMI2_DISABLE | Disables orientation - * BMI2_ENABLE | Enables orientation + * @param[out] config : Structure instance of bmi2_aux_config. + * @param[in] dev : Structure instance of bmi2_dev. * * @return Result of API execution status - * - * @retval BMI2_OK - Success. - * @retval BMI2_E_COM_FAIL - Error: Communication fail - * @retval BMI2_E_INVALID_SENSOR - Error: Invalid sensor - * @retval BMI2_E_INVALID_PAGE - Error: Invalid Page + * @retval 0 -> Success + * @retval < 0 -> Fail */ -static int8_t set_orientation(uint8_t enable, struct bmi2_dev *dev); +static int8_t get_aux_interface(struct bmi2_aux_config *config, struct bmi2_dev *dev); /*! - * @brief This internal API is used to enable/disable high-g feature. - * - * @param[in] dev : Structure instance of bmi2_dev. - * @param[in] enable : Enables/Disables high-g. + * @brief This internal API gets auxiliary configurations like manual/auto mode + * FCU write command enable and read burst length for both data and manual mode. * - * Enable | Description - * -------------|--------------- - * BMI2_DISABLE | Disables high-g - * BMI2_ENABLE | Enables high-g + * @param[out] config : Structure instance of bmi2_aux_config. + * @param[in] dev : Structure instance of bmi2_dev. * * @return Result of API execution status - * - * @retval BMI2_OK - Success. - * @retval BMI2_E_COM_FAIL - Error: Communication fail - * @retval BMI2_E_INVALID_SENSOR - Error: Invalid sensor - * @retval BMI2_E_INVALID_PAGE - Error: Invalid Page + * @retval 0 -> Success + * @retval < 0 -> Fail */ -static int8_t set_high_g(uint8_t enable, struct bmi2_dev *dev); +static int8_t get_aux_interface_config(struct bmi2_aux_config *config, struct bmi2_dev *dev); /*! - * @brief This internal API is used to enable/disable low-g feature. - * - * @param[in] dev : Structure instance of bmi2_dev. - * @param[in] enable : Enables/Disables low-g. + * @brief This internal API gets read out offset and ODR of the auxiliary + * sensor. * - * Enable | Description - * -------------|--------------- - * BMI2_DISABLE | Disables low-g - * BMI2_ENABLE | Enables low-g + * @param[out] config : Structure instance of bmi2_aux_config. + * @param[in] dev : Structure instance of bmi2_dev. * * @return Result of API execution status - * - * @retval BMI2_OK - Success. - * @retval BMI2_E_COM_FAIL - Error: Communication fail - * @retval BMI2_E_INVALID_SENSOR - Error: Invalid sensor - * @retval BMI2_E_INVALID_PAGE - Error: Invalid Page + * @retval 0 -> Success + * @retval < 0 -> Fail */ -static int8_t set_low_g(uint8_t enable, struct bmi2_dev *dev); +static int8_t get_aux_cfg(struct bmi2_aux_config *config, struct bmi2_dev *dev); /*! - * @brief This internal API is used to enable/disable flat feature. - * - * @param[in] dev : Structure instance of bmi2_dev. - * @param[in] enable : Enables/Disables flat. + * @brief This internal API gets the saturation status for the gyroscope user + * gain update. * - * Enable | Description - * -------------|--------------- - * BMI2_DISABLE | Disables flat - * BMI2_ENABLE | Enables flat + * @param[out] user_gain_stat : Stores the saturation status of the axes. + * @param[in] dev : Structure instance of bmi2_dev. * * @return Result of API execution status - * - * @retval BMI2_OK - Success. - * @retval BMI2_E_COM_FAIL - Error: Communication fail - * @retval BMI2_E_INVALID_SENSOR - Error: Invalid sensor - * @retval BMI2_E_INVALID_PAGE - Error: Invalid Page + * @retval 0 -> Success + * @retval < 0 -> Fail */ -static int8_t set_flat(uint8_t enable, struct bmi2_dev *dev); +static int8_t get_gyro_gain_update_status(struct bmi2_gyr_user_gain_status *user_gain, struct bmi2_dev *dev); /*! - * @brief This internal API is used to enable/disable ext-sensor-sync feature. - * - * @param[in] dev : Structure instance of bmi2_dev. - * @param[in] enable : Enables/Disables ext-sensor-sync. + * @brief This internal API is used to extract the output feature configuration + * details like page and start address from the look-up table. * - * Enable | Description - * -------------|--------------- - * BMI2_DISABLE | Disables ext-sensor-sync - * BMI2_ENABLE | Enables ext-sensor-sync + * @param[out] feat_output : Structure that stores output feature + * configurations. + * @param[in] type : Type of feature or sensor. + * @param[in] dev : Structure instance of bmi2_dev. * - * @return Result of API execution status + * @return Returns the feature found flag. * - * @retval BMI2_OK - Success. - * @retval BMI2_E_COM_FAIL - Error: Communication fail - * @retval BMI2_E_INVALID_SENSOR - Error: Invalid sensor - * @retval BMI2_E_INVALID_PAGE - Error: Invalid Page + * @retval BMI2_FALSE : Feature not found + * BMI2_TRUE : Feature found */ -static int8_t set_ext_sens_sync(uint8_t enable, struct bmi2_dev *dev); +static uint8_t extract_output_feat_config(struct bmi2_feature_config *feat_output, + uint8_t type, + const struct bmi2_dev *dev); /*! - * @brief This internal API gives an option to enable offset correction - * feature of gyroscope, either internally or by the host. - * - * @param[in] enable : Enables/Disables self-offset correction. - * @param[in] dev : Structure instance of bmi2_dev. + * @brief This internal API gets the cross sensitivity coefficient between + * gyroscope's X and Z axes. * - * enable | Description - * -------------|--------------- - * BMI2_ENABLE | gyroscope offset correction values are set internally - * BMI2_DISABLE | gyroscope offset correction values has to be set by host + * @param[out] cross_sense : Pointer to the stored cross sensitivity + * coefficient. + * @param[in] dev : Structure instance of bmi2_dev. * * @return Result of API execution status - * - * @retval BMI2_OK - Success. - * @retval BMI2_E_COM_FAIL - Error: Communication fail - * @retval BMI2_E_INVALID_SENSOR - Error: Invalid sensor - * @retval BMI2_E_INVALID_PAGE - Error: Invalid Page + * @retval 0 -> Success + * @retval < 0 -> Fail */ -static int8_t set_gyro_self_offset_corr(uint8_t enable, struct bmi2_dev *dev); +static int8_t get_gyro_cross_sense(int16_t *cross_sense, struct bmi2_dev *dev); /*! - * @brief This internal API is used to enable/disable gyroscope user gain - * feature. - * - * @param[in] dev : Structure instance of bmi2_dev. - * @param[in] enable : Enables/Disables gyroscope user gain. + * @brief This internal API gets the accelerometer data from the register. * - * Enable | Description - * -------------|--------------- - * BMI2_DISABLE | Disables gyroscope user gain - * BMI2_ENABLE | Enables gyroscope user gain + * @param[out] data : Structure instance of sensor_data. + * @param[in] reg_addr : Register address where data is stored. + * @param[in] dev : Structure instance of bmi2_dev. * * @return Result of API execution status - * - * @retval BMI2_OK - Success. - * @retval BMI2_E_COM_FAIL - Error: Communication fail - * @retval BMI2_E_INVALID_SENSOR - Error: Invalid sensor - * @retval BMI2_E_INVALID_PAGE - Error: Invalid Page + * @retval 0 -> Success + * @retval < 0 -> Fail */ -static int8_t set_gyro_user_gain(uint8_t enable, struct bmi2_dev *dev); +static int8_t get_accel_sensor_data(struct bmi2_sens_axes_data *data, uint8_t reg_addr, struct bmi2_dev *dev); /*! - * @brief This internal API enables the wrist gesture feature. - * - * @param[in] dev : Structure instance of bmi2_dev. - * @param[in] enable : Enables/Disables wrist gesture. + * @brief This internal API gets the gyroscope data from the register. * - * Enable | Description - * -------------|--------------- - * BMI2_DISABLE | Disables wrist gesture - * BMI2_ENABLE | Enables wrist gesture + * @param[out] data : Structure instance of sensor_data. + * @param[in] reg_addr : Register address where data is stored. + * @param[in] dev : Structure instance of bmi2_dev. * * @return Result of API execution status - * - * @retval BMI2_OK - Success. - * @retval BMI2_E_COM_FAIL - Error: Communication fail - * @retval BMI2_E_INVALID_SENSOR - Error: Invalid sensor - * @retval BMI2_E_INVALID_PAGE - Error: Invalid Page + * @retval 0 -> Success + * @retval < 0 -> Fail */ -static int8_t set_wrist_gesture(uint8_t enable, struct bmi2_dev *dev); +static int8_t get_gyro_sensor_data(struct bmi2_sens_axes_data *data, uint8_t reg_addr, struct bmi2_dev *dev); /*! - * @brief This internal API enables the wrist wear wake up feature. - * - * @param[in] dev : Structure instance of bmi2_dev. - * @param[in] enable : Enables/Disables wrist wear wake up. + * @brief This internal API gets the accelerometer/gyroscope data. * - * Enable | Description - * -------------|--------------- - * BMI2_DISABLE | Disables wrist wear wake up - * BMI2_ENABLE | Enables wrist wear wake up + * @param[out] data : Structure instance of sensor_data. + * @param[in] reg_data : Data stored in the register. * - * @return Result of API execution status + * @return None * - * @retval BMI2_OK - Success. - * @retval BMI2_E_COM_FAIL - Error: Communication fail - * @retval BMI2_E_INVALID_SENSOR - Error: Invalid sensor - * @retval BMI2_E_INVALID_PAGE - Error: Invalid Page + * @retval None */ -static int8_t set_wrist_wear_wake_up(uint8_t enable, struct bmi2_dev *dev); +static void get_acc_gyr_data(struct bmi2_sens_axes_data *data, const uint8_t *reg_data); /*! - * @brief This internal API enables the wrist gesture feature for wearable variant. - * - * @param[in] dev : Structure instance of bmi2_dev. - * @param[in] enable : Enables/Disables wrist gesture. + * @brief This internal API gets the re-mapped accelerometer/gyroscope data. * - * Enable | Description - * -------------|--------------- - * BMI2_DISABLE | Disables wrist gesture - * BMI2_ENABLE | Enables wrist gesture + * @param[out] data : Structure instance of sensor_data. + * @param[in] dev : Structure instance of bmi2_dev. * - * @return Result of API execution status + * @return None * - * @retval BMI2_OK - Success. - * @retval BMI2_E_COM_FAIL - Error: Communication fail - * @retval BMI2_E_INVALID_SENSOR - Error: Invalid sensor - * @retval BMI2_E_INVALID_PAGE - Error: Invalid Page + * @retval None */ -static int8_t set_wrist_gesture_wh(uint8_t enable, struct bmi2_dev *dev); +static void get_remapped_data(struct bmi2_sens_axes_data *data, const struct bmi2_dev *dev); /*! - * @brief This internal API enables the wrist wear wake up feature for wearable variant. - * - * @param[in] dev : Structure instance of bmi2_dev. - * @param[in] enable : Enables/Disables wrist wear wake up. + * @brief This internal API reads the user-defined bytes of data from the given + * register address of auxiliary sensor in data mode. * - * Enable | Description - * -------------|--------------- - * BMI2_DISABLE | Disables wrist wear wake up - * BMI2_ENABLE | Enables wrist wear wake up + * @param[out] aux_data : Pointer to the stored auxiliary data. + * @param[in] dev : Structure instance of bmi2_dev. * * @return Result of API execution status - * - * @retval BMI2_OK - Success. - * @retval BMI2_E_COM_FAIL - Error: Communication fail - * @retval BMI2_E_INVALID_SENSOR - Error: Invalid sensor - * @retval BMI2_E_INVALID_PAGE - Error: Invalid Page + * @retval 0 -> Success + * @retval < 0 -> Fail */ -static int8_t set_wrist_wear_wake_up_wh(uint8_t enable, struct bmi2_dev *dev); +static int8_t read_aux_data_mode(uint8_t *aux_data, struct bmi2_dev *dev); /*! - * @brief This internal API enables/disables the activity recognition feature. - * - * @param[in] enable : Enables/Disables activity recognition. - * @param[in] dev : Structure instance of bmi2_dev. + * @brief This internal API reads the user-defined bytes of data from the given + * register address of auxiliary sensor in manual mode. * - * enable | Description - * -------------|--------------- - * BMI2_ENABLE | Enables activity recognition. - * BMI2_DISABLE | Disables activity recognition. + * @param[in] reg_addr : AUX address from where data is read. + * @param[out] aux_data : Pointer to the stored auxiliary data. + * @param[in] len : Total bytes to be read. + * @param[in] burst_len : Bytes of data to be read in bursts. + * @param[in] dev : Structure instance of bmi2_dev. * * @return Result of API execution status - * - * @retval BMI2_OK - Success. - * @retval BMI2_E_COM_FAIL - Error: Communication fail - * @retval BMI2_E_INVALID_SENSOR - Error: Invalid sensor - * @retval BMI2_E_INVALID_PAGE - Error: Invalid Page + * @retval 0 -> Success + * @retval < 0 -> Fail */ -static int8_t set_act_recog(uint8_t enable, struct bmi2_dev *dev); +static int8_t read_aux_data(uint8_t reg_addr, uint8_t *aux_data, uint16_t len, uint8_t burst_len, struct bmi2_dev *dev); /*! - * @brief This internal API gives an option to enable accelerometer self-test - * in the feature register. - * - * @param[in] enable : Enables/Disables accelerometer self-test. - * @param[in] dev : Structure instance of bmi2_dev. + * @brief This internal API checks the busy status of auxiliary sensor and sets + * the auxiliary register addresses when not busy. * - * enable | Description - * -------------|--------------- - * BMI2_ENABLE | Enables accelerometer self-test. - * BMI2_DISABLE | Disables accelerometer self-test. + * @param[in] reg_addr : Address in which AUX register address is + * set. + * @param[in] reg_data : Auxiliary register address to be set when AUX is + * not busy. + * @param[in] dev : Structure instance of bmi2_dev. * * @return Result of API execution status - * - * @retval BMI2_OK - Success. - * @retval BMI2_E_COM_FAIL - Error: Communication fail - * @retval BMI2_E_INVALID_SENSOR - Error: Invalid sensor - * @retval BMI2_E_INVALID_PAGE - Error: Invalid Page + * @retval 0 -> Success + * @retval < 0 -> Fail */ -static int8_t set_feat_accel_self_test(uint8_t enable, struct bmi2_dev *dev); +static int8_t set_if_aux_not_busy(uint8_t reg_addr, uint8_t reg_data, struct bmi2_dev *dev); /*! - * @brief This internal API gives an option to enable low pass filter - * in the feature register. - * - * @param[in] enable : Enables/Disables accelerometer self-test. - * @param[in] dev : Structure instance of bmi2_dev. + * @brief his internal API maps the actual burst read length with that of the + * register value set by user. * - * enable | Description - * -------------|--------------- - * BMI2_ENABLE | Enables low pass filter. - * BMI2_DISABLE | Disables low pass filter. + * @param[out] len : Actual burst length. + * @param[in] dev : Structure instance of bmi2_dev. * * @return Result of API execution status - * - * @retval BMI2_OK - Success. - * @retval BMI2_E_COM_FAIL - Error: Communication fail - * @retval BMI2_E_INVALID_SENSOR - Error: Invalid sensor - * @retval BMI2_E_INVALID_PAGE - Error: Invalid Page + * @retval 0 -> Success + * @retval < 0 -> Fail */ -static int8_t set_primary_ois_low_pass_filter(uint8_t enable, struct bmi2_dev *dev); +static int8_t map_read_len(uint8_t *len, const struct bmi2_dev *dev); /*! - * @brief This internal API sets accelerometer configurations like ODR, - * bandwidth, performance mode and g-range. + * @brief This internal API writes AUX write address and the user-defined bytes + * of data to the AUX sensor in manual mode. * - * @param[in,out] config : Structure instance of bmi2_accel_config. - * @param[in,out] dev : Structure instance of bmi2_dev. + * @note Change of BMI2_AUX_WR_ADDR is only allowed if AUX is not busy. * - * @return Result of API execution status + * @param[in] reg_addr : AUX address in which data is to be written. + * @param[in] reg_data : Data to be written + * @param[in] dev : Structure instance of bmi2_dev. * - * @retval BMI2_OK - Success. - * @retval BMI2_E_COM_FAIL - Error: Communication fail - * @retval BMI2_E_ACC_INVALID_CFG - Error: Invalid accelerometer configuration - * @retval BMI2_E_ACC_GYR_INVALID_CFG - Error: Invalid accelerometer and - * gyroscope configuration + * @note Change of BMI2_AUX_WR_ADDR is only allowed if AUX is not busy. * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail */ -static int8_t set_accel_config(struct bmi2_accel_config *config, struct bmi2_dev *dev); +static int8_t write_aux_data(uint8_t reg_addr, uint8_t reg_data, struct bmi2_dev *dev); /*! - * @brief This internal API validates bandwidth and performance mode of the - * accelerometer set by the user. + * @brief This internal API maps/unmaps feature interrupts to that of interrupt + * pins. * - * @param[in, out] bandwidth : Pointer to bandwidth value set by the user. - * @param[in, out] perf_mode : Pointer to performance mode set by the user. - * @param[in, out] dev : Structure instance of bmi2_dev. + * @param[in] int_pin : Interrupt pin selected. + * @param[in] feat_int : Type of feature interrupt to be mapped. + * @param[in] dev : Structure instance of bmi2_dev. * * @return Result of API execution status - * - * @note dev->info contains two warnings: BMI2_I_MIN_VALUE and BMI2_I_MAX_VALUE - * - * @retval BMI2_OK - Success. - * @retval BMI2_E_NULL_PTR - Error: Null pointer error - * @retval BMI2_E_COM_FAIL - Error: Communication fail + * @retval 0 -> Success + * @retval < 0 -> Fail */ -static int8_t validate_bw_perf_mode(uint8_t *bandwidth, uint8_t *perf_mode, struct bmi2_dev *dev); +static int8_t map_feat_int(uint8_t *reg_data_array, enum bmi2_hw_int_pin int_pin, uint8_t int_mask); /*! - * @brief This internal API validates ODR and range of the accelerometer set by - * the user. + * @brief This internal API computes the number of bytes of accelerometer FIFO + * data which is to be parsed in header-less mode. * - * @param[in, out] odr : Pointer to ODR value set by the user. - * @param[in, out] range : Pointer to range value set by the user. - * @param[in, out] dev : Structure instance of bmi2_dev. + * @param[out] start_idx : The start index for parsing data. + * @param[out] len : Number of bytes to be parsed. + * @param[in] acc_count : Number of accelerometer frames to be read. + * @param[in] fifo : Structure instance of bmi2_fifo_frame. * * @return Result of API execution status - * - * @note dev->info contains two warnings: BMI2_I_MIN_VALUE and BMI2_I_MAX_VALUE - * - * @retval BMI2_OK - Success. - * @retval BMI2_E_NULL_PTR - Error: Null pointer error + * @retval 0 -> Success + * @retval < 0 -> Fail */ -static int8_t validate_odr_range(uint8_t *odr, uint8_t *range, struct bmi2_dev *dev); +static int8_t parse_fifo_accel_len(uint16_t *start_idx, + uint16_t *len, + const uint16_t *acc_count, + const struct bmi2_fifo_frame *fifo); /*! - * @brief This internal API sets gyroscope configurations like ODR, bandwidth, - * low power/high performance mode, performance mode and range. + * @brief This internal API is used to parse accelerometer data from the FIFO + * data in header mode. * - * @param[in,out] config : Structure instance of bmi2_gyro_config. - * @param[in,out] dev : Structure instance of bmi2_dev. + * @param[out] acc : Structure instance of bmi2_sens_axes_data where + * the parsed accelerometer data bytes are stored. + * @param[in] accel_length : Number of accelerometer frames (x,y,z data). + * @param[in] fifo : Structure instance of bmi2_fifo_frame. + * @param[in] dev : Structure instance of bmi2_dev. * * @return Result of API execution status - * - * @retval BMI2_OK - Success. - * @retval BMI2_E_COM_FAIL - Error: Communication fail - * @retval BMI2_E_GYRO_INVALID_CFG - Error: Invalid accelerometer configuration - * @retval BMI2_E_ACC_GYR_INVALID_CFG - Error: Invalid accelerometer and - * gyroscope configuration + * @retval 0 -> Success + * @retval < 0 -> Fail */ -static int8_t set_gyro_config(struct bmi2_gyro_config *config, struct bmi2_dev *dev); +static int8_t extract_accel_header_mode(struct bmi2_sens_axes_data *acc, + uint16_t *accel_length, + struct bmi2_fifo_frame *fifo, + const struct bmi2_dev *dev); /*! - * @brief This internal API validates bandwidth, performance mode, low power/ - * high performance mode, ODR, and range set by the user. + * @brief This internal API is used to parse the accelerometer data from the + * FIFO data in both header and header-less mode. It updates the current data + * byte to be parsed. * - * @param[in] config : Structure instance of bmi2_gyro_config. - * @param[in] dev : Structure instance of bmi2_dev. + * @param[in,out] acc : Structure instance of bmi2_sens_axes_data where + * where the parsed data bytes are stored. + * @param[in,out] idx : Index value of number of bytes parsed. + * @param[in,out] acc_idx : Index value of accelerometer data (x,y,z axes) + * frame to be parsed. + * @param[in] frame : Either data is enabled by user in header-less + * mode or header frame value in header mode. + * @param[in] fifo : Structure instance of bmi2_fifo_frame. + * @param[in] dev : Structure instance of bmi2_dev. * * @return Result of API execution status - * - * @note dev->info contains two warnings: BMI2_I_MIN_VALUE and BMI2_I_MAX_VALUE - * - * @retval BMI2_OK - Success. - * @retval BMI2_E_NULL_PTR - Error: Null pointer error + * @retval 0 -> Success + * @retval < 0 -> Fail */ -static int8_t validate_gyro_config(struct bmi2_gyro_config *config, struct bmi2_dev *dev); +static int8_t unpack_accel_frame(struct bmi2_sens_axes_data *acc, + uint16_t *idx, + uint16_t *acc_idx, + uint8_t frame, + const struct bmi2_fifo_frame *fifo, + const struct bmi2_dev *dev); /*! - * @brief This internal API shows the error status when illegal sensor - * configuration is set. - * - * @param[in] dev : Structure instance of bmi2_dev. + * @brief This internal API is used to parse accelerometer data from the FIFO + * data. * - * @return Result of API execution status + * @param[out] acc : Structure instance of bmi2_sens_axes_data + * where the parsed data bytes are stored. + * @param[in] data_start_index : Index value of the accelerometer data bytes + * which is to be parsed from the FIFO data. + * @param[in] fifo : Structure instance of bmi2_fifo_frame. + * @param[in] dev : Structure instance of bmi2_dev. * - * @retval BMI2_OK - Success. - * @retval BMI2_E_COM_FAIL - Error: Communication fail - * @retval BMI2_E_ACC_INVALID_CFG - Error: Invalid accelerometer configuration - * @retval BMI2_E_GYRO_INVALID_CFG - Error: Invalid accelerometer configuration - * @retval BMI2_E_ACC_GYR_INVALID_CFG - Error: Invalid accelerometer and - * gyroscope configuration + * @return None + * @retval None */ -static int8_t cfg_error_status(struct bmi2_dev *dev); +static void unpack_accel_data(struct bmi2_sens_axes_data *acc, + uint16_t data_start_index, + const struct bmi2_fifo_frame *fifo, + const struct bmi2_dev *dev); /*! - * @brief This internal API: - * 1) Enables/Disables auxiliary interface. - * 2) Sets auxiliary interface configurations like I2C address, manual/auto - * mode enable, manual burst read length, AUX burst read length and AUX read - * address. - * 3)It maps/un-maps data interrupts to that of hardware interrupt line. + * @brief This internal API computes the number of bytes of gyroscope FIFO data + * which is to be parsed in header-less mode. * - * @param[in] config : Structure instance of bmi2_aux_config. - * @param[in, out] dev : Structure instance of bmi2_dev. + * @param[out] start_idx : The start index for parsing data. + * @param[out] len : Number of bytes to be parsed. + * @param[in] gyr_count : Number of gyroscope frames to be read. + * @param[in] frame : Either data enabled by user in header-less + * mode or header frame value in header mode. + * @param[in] fifo : Structure instance of bmi2_fifo_frame. * * @return Result of API execution status - * - * @retval BMI2_OK - Success. - * @retval BMI2_E_COM_FAIL - Error: Communication fail - * @retval BMI2_E_AUX_BUSY - Error: Auxiliary sensor is busy + * @retval 0 -> Success + * @retval < 0 -> Fail */ -static int8_t set_aux_config(struct bmi2_aux_config *config, struct bmi2_dev *dev); +static int8_t parse_fifo_gyro_len(uint16_t *start_idx, + uint16_t(*len), + const uint16_t *gyr_count, + const struct bmi2_fifo_frame *fifo); /*! - * @brief This internal API enables/disables auxiliary interface. + * @brief This internal API is used to parse the gyroscope data from the FIFO + * data in both header and header-less mode It updates the current data byte to + * be parsed. * - * @param[in] config : Structure instance of bmi2_aux_config. - * @param[in] dev : Structure instance of bmi2_dev. + * @param[in,out] gyr : Structure instance of bmi2_sens_axes_data. + * @param[in,out] idx : Index value of number of bytes parsed + * @param[in,out] gyr_idx : Index value of gyroscope data (x,y,z axes) + * frame to be parsed. + * @param[in] frame : Either data is enabled by user in header-less + * mode or header frame value in header mode. + * @param[in] fifo : Structure instance of bmi2_fifo_frame. + * @param[in] dev : Structure instance of bmi2_dev. * * @return Result of API execution status - * - * @retval BMI2_OK - Success. - * @retval BMI2_E_COM_FAIL - Error: Communication fail + * @retval 0 -> Success + * @retval < 0 -> Fail */ -static int8_t set_aux_interface(const struct bmi2_aux_config *config, struct bmi2_dev *dev); +static int8_t unpack_gyro_frame(struct bmi2_sens_axes_data *gyr, + uint16_t *idx, + uint16_t *gyr_idx, + uint8_t frame, + const struct bmi2_fifo_frame *fifo, + const struct bmi2_dev *dev); /*! - * @brief This internal API sets auxiliary configurations like manual/auto mode - * FCU write command enable and read burst length for both data and manual mode. - * - * @param[in] config : Structure instance of bmi2_aux_config. - * @param[in] dev : Structure instance of bmi2_dev. - * - * @note Auxiliary sensor should not be busy when configuring aux_i2c_addr, - * man_rd_burst_len, aux_rd_burst_len and aux_rd_addr. + * @brief This internal API is used to parse gyroscope data from the FIFO data. * - * @return Result of API execution status + * @param[out] gyr : Structure instance of bmi2_sens_axes_data where + * the parsed gyroscope data bytes are stored. + * @param[in] data_start_index : Index value of the gyroscope data bytes + * which is to be parsed from the FIFO data. + * @param[in] fifo : Structure instance of bmi2_fifo_frame. + * @param[in] dev : Structure instance of bmi2_dev. * - * @retval BMI2_OK - Success. - * @retval BMI2_E_COM_FAIL - Error: Communication fail - * @retval BMI2_E_AUX_BUSY - Error: Auxiliary sensor is busy + * @return None + * @retval None */ -static int8_t config_aux_interface(const struct bmi2_aux_config *config, struct bmi2_dev *dev); +static void unpack_gyro_data(struct bmi2_sens_axes_data *gyr, + uint16_t data_start_index, + const struct bmi2_fifo_frame *fifo, + const struct bmi2_dev *dev); /*! - * @brief This internal API triggers read out offset and sets ODR of the - * auxiliary sensor. + * @brief This internal API is used to parse the gyroscope data from the + * FIFO data in header mode. * - * @param[in] config : Structure instance of bmi2_aux_config. - * @param[in] dev : Structure instance of bmi2_dev. + * @param[out] gyr : Structure instance of bmi2_sens_axes_data where + * the parsed gyroscope data bytes are stored. + * @param[in] gyro_length : Number of gyroscope frames (x,y,z data). + * @param[in] fifo : Structure instance of bmi2_fifo_frame. + * @param[in] dev : Structure instance of bmi2_dev. * * @return Result of API execution status - * - * @retval BMI2_OK - Success. - * @retval BMI2_E_COM_FAIL - Error: Communication fail + * @retval 0 -> Success + * @retval < 0 -> Fail */ -static int8_t config_aux(const struct bmi2_aux_config *config, struct bmi2_dev *dev); +static int8_t extract_gyro_header_mode(struct bmi2_sens_axes_data *gyr, + uint16_t *gyro_length, + struct bmi2_fifo_frame *fifo, + const struct bmi2_dev *dev); /*! - * @brief This internal API validates auxiliary configuration set by the user. + * @brief This API computes the number of bytes of auxiliary FIFO data + * which is to be parsed in header-less mode. * - * @param[in, out] config : Structure instance of bmi2_aux_config. - * @param[in, out] dev : Structure instance of bmi2_dev. + * @param[out] start_idx : The start index for parsing data. + * @param[out] len : Number of bytes to be parsed. + * @param[in] aux_count : Number of accelerometer frames to be read. + * @param[in] fifo : Structure instance of bmi2_fifo_frame. * * @return Result of API execution status - * - * @note dev->info contains two warnings: BMI2_I_MIN_VALUE and BMI2_I_MAX_VALUE - * - * @retval BMI2_OK - Success. - * @retval BMI2_E_NULL_PTR - Error: Null pointer error + * @retval 0 -> Success + * @retval < 0 -> Fail */ -static int8_t validate_aux_config(struct bmi2_aux_config *config, struct bmi2_dev *dev); +static int8_t parse_fifo_aux_len(uint16_t *start_idx, + uint16_t(*len), + const uint16_t *aux_count, + const struct bmi2_fifo_frame *fifo); /*! - * @brief This internal API sets any-motion configurations like axes select, - * duration, threshold and output-configuration. - * - * @param[in] config : Structure instance of bmi2_any_motion_config. - * @param[in, out] dev : Structure instance of bmi2_dev. + * @brief This API is used to parse auxiliary data from the FIFO data. * - * @verbatim - *---------------------------------------------------------------------------- - * bmi2_any_motion_config | - * Structure parameters | Description - *--------------------------|-------------------------------------------------- - * | Defines the number of consecutive data points for - * | which the threshold condition must be respected, - * | for interrupt assertion. It is expressed in 50 Hz - * duration | samples (20 msec). - * | Range is 0 to 163sec. - * | Default value is 5 = 100ms. - * -------------------------|--------------------------------------------------- - * | Slope threshold value for in 5.11g format. - * threshold | Range is 0 to 1g. - * | Default value is 0xAA = 83mg. - * -------------------------|--------------------------------------------------- - * x_sel, y_sel, z_sel | Selects the feature on a per-axis basis - * -------------------------|--------------------------------------------------- - * | Enable bits for enabling output into the - * out_conf | register status bits and, if desired, onto the - * | interrupt pin. - * @endverbatim + * @param[out] aux : Pointer to buffer where the parsed auxiliary data + * bytes are stored. + * @param[in] aux_length : Number of auxiliary frames (x,y,z data). + * @param[in] fifo : Structure instance of bmi2_fifo_frame. + * @param[in] dev : Structure instance of bmi2_dev. * * @return Result of API execution status - * - * @retval BMI2_OK - Success. - * @retval BMI2_E_COM_FAIL - Error: Communication fail - * @retval BMI2_E_INVALID_SENSOR - Error: Invalid sensor - * @retval BMI2_E_INVALID_PAGE - Error: Invalid Page + * @retval 0 -> Success + * @retval < 0 -> Fail */ -static int8_t set_any_motion_config(const struct bmi2_any_motion_config *config, struct bmi2_dev *dev); +static int8_t extract_aux_header_mode(struct bmi2_aux_fifo_data *aux, + uint16_t *aux_length, + struct bmi2_fifo_frame *fifo, + const struct bmi2_dev *dev); /*! - * @brief This internal API sets no-motion configurations like axes select, - * duration, threshold and output-configuration. - * - * @param[in] config : Structure instance of bmi2_no_motion_config. - * @param[in, out] dev : Structure instance of bmi2_dev. + * @brief This API is used to parse the auxiliary data from the FIFO data in + * both header and header-less mode. It updates the current data byte to be + * parsed. * - * @verbatim - *---------------------------------------------------------------------------- - * bmi2_no_motion_config | - * Structure parameters | Description - *--------------------------|-------------------------------------------------- - * | Defines the number of consecutive data points for - * | which the threshold condition must be respected, - * | for interrupt assertion. It is expressed in 50 Hz - * duration | samples (20 msec). - * | Range is 0 to 163sec. - * | Default value is 5 = 100ms. - * -------------------------|--------------------------------------------------- - * | Slope threshold value for in 5.11g format. - * threshold | Range is 0 to 1g. - * | Default value is 0xAA = 83mg. - * -------------------------|--------------------------------------------------- - * x_sel, y_sel, z_sel | Selects the feature on a per-axis basis - * -------------------------|--------------------------------------------------- - * | Enable bits for enabling output into the - * out_conf | register status bits and, if desired, onto the - * | interrupt pin. - * @endverbatim + * @param[out] aux : Pointer to structure where the parsed auxiliary data + * bytes are stored. + * @param[in,out] idx : Index value of number of bytes parsed + * @param[in,out] aux_idx : Index value of auxiliary data (x,y,z axes) + * frame to be parsed + * @param[in] frame : Either data is enabled by user in header-less + * mode or header frame value in header mode. + * @param[in] fifo : Structure instance of bmi2_fifo_frame. + * @param[in] dev : Structure instance of bmi2_dev. * * @return Result of API execution status - * - * @retval BMI2_OK - Success. - * @retval BMI2_E_COM_FAIL - Error: Communication fail - * @retval BMI2_E_INVALID_SENSOR - Error: Invalid sensor - * @retval BMI2_E_INVALID_PAGE - Error: Invalid Page + * @retval 0 -> Success + * @retval < 0 -> Fail */ -static int8_t set_no_motion_config(const struct bmi2_no_motion_config *config, struct bmi2_dev *dev); +static int8_t unpack_aux_frame(struct bmi2_aux_fifo_data *aux, + uint16_t *idx, + uint16_t *aux_idx, + uint8_t frame, + const struct bmi2_fifo_frame *fifo, + const struct bmi2_dev *dev); /*! - * @brief This internal API sets sig-motion configurations like block-size, - * output-configuration and other parameters. + * @brief This API is used to parse auxiliary data from the FIFO data. * - * @param[in] config : Structure instance of bmi2_sig_motion_config. - * @param[in, out] dev : Structure instance of bmi2_dev. + * @param[out] aux : Pointer to structure where the parsed + * auxiliary data bytes are stored. + * @param[in] data_start_index : Index value of the auxiliary data bytes which + * is to be parsed from the FIFO data. + * @param[in] fifo : Structure instance of bmi2_fifo_frame. * - *---------------------------------------------------------------------------- - * bmi2_sig_motion_config | - * Structure parameters | Description - * -------------------------|--------------------------------------------------- - * | Defines the duration after which the significant - * block_size | motion interrupt is triggered. It is expressed in - * | 50 Hz samples (20 ms). Default value is 0xFA=5sec. - *--------------------------|--------------------------------------------------- - * | Enable bits for enabling output into the - * out_conf | register status bits and, if desired, onto the - * | interrupt pin. - *--------------------------|--------------------------------------------------- + * @return None + * @retval None + */ +static void unpack_aux_data(struct bmi2_aux_fifo_data *aux, + uint16_t data_start_index, + const struct bmi2_fifo_frame *fifo); + +/*! + * @brief This internal API is used to reset the FIFO related configurations + * in the FIFO frame structure for the next FIFO read. * - * @return Result of API execution status + * @param[in, out] fifo : Structure instance of bmi2_fifo_frame. + * @param[in] dev : Structure instance of bmi2_dev. * - * @retval BMI2_OK - Success. - * @retval BMI2_E_COM_FAIL - Error: Communication fail - * @retval BMI2_E_INVALID_SENSOR - Error: Invalid sensor - * @retval BMI2_E_INVALID_PAGE - Error: Invalid Page + * @return None + * @retval None */ -static int8_t set_sig_motion_config(const struct bmi2_sig_motion_config *config, struct bmi2_dev *dev); +static void reset_fifo_frame_structure(struct bmi2_fifo_frame *fifo, const struct bmi2_dev *dev); /*! - * @brief This internal API sets step counter parameter configurations. + * @brief This internal API checks whether the FIFO data read is an empty frame. + * If empty frame, index is moved to the last byte. * - * @param[in] step_count_params : Array that stores parameters 1 to 25. - * @param[in] dev : Structure instance of bmi2_dev. + * @param[in,out] data_index : The index of the current data to be parsed from + * FIFO data. + * @param[in] fifo : Structure instance of bmi2_fifo_frame. * * @return Result of API execution status * * @retval BMI2_OK - Success. - * @retval BMI2_E_COM_FAIL - Error: Communication fail - * @retval BMI2_E_INVALID_SENSOR - Error: Invalid sensor - * @retval BMI2_E_INVALID_PAGE - Error: Invalid Page + * @retval BMI2_W_FIFO_EMPTY - Warning : FIFO is empty + * @retval BMI2_W_PARTIAL_READ - Warning : There are more frames to be read */ -static int8_t set_step_count_params_config(const uint16_t *step_count_params, struct bmi2_dev *dev); +static int8_t check_empty_fifo(uint16_t *data_index, const struct bmi2_fifo_frame *fifo); /*! - * @brief This internal API sets step counter/detector/activity configurations. - * - * @param[in] config : Structure instance of bmi2_step_config. - * @param[in] dev : Structure instance of bmi2_dev. + * @brief This internal API is used to move the data index ahead of the + * current frame length parameter when unnecessary FIFO data appears while + * extracting the user specified data. * - *--------------------------------------------------------------------------- - * bmi2_step_config | - * Structure parameters | Description - *--------------------------|-------------------------------------------------- - * | The Step-counter will trigger output every time - * | the number of steps are counted. Holds implicitly - * water-mark level | a 20x factor, so the range is 0 to 10230, - * | with resolution of 20 steps. - * -------------------------|--------------------------------------------------- - * reset counter | Flag to reset the counted steps. - * -------------------------|--------------------------------------------------- - * | Enable bits for enabling output into the - * step_det_out_conf | register status bits and, if desired, onto the - * | interrupt pin for step detector. - * -------------------------|--------------------------------------------------- - * | Enable bits for enabling output into the - * step_act_out_conf | register status bits and, if desired, onto the - * | interrupt pin for step activity. - * -------------------------|--------------------------------------------------- - * @endverbatim + * @param[in,out] data_index : Index of the FIFO data which is to be + * moved ahead of the current frame length + * @param[in] current_frame_length : Number of bytes in the current frame. + * @param[in] fifo : Structure instance of bmi2_fifo_frame. * * @return Result of API execution status - * - * @retval BMI2_OK - Success. - * @retval BMI2_E_COM_FAIL - Error: Communication fail - * @retval BMI2_E_INVALID_SENSOR - Error: Invalid sensor - * @retval BMI2_E_INVALID_PAGE - Error: Invalid Page + * @retval 0 -> Success + * @retval < 0 -> Fail */ -static int8_t set_step_config(const struct bmi2_step_config *config, struct bmi2_dev *dev); +static int8_t move_next_frame(uint16_t *data_index, uint8_t current_frame_length, const struct bmi2_fifo_frame *fifo); /*! - * @brief This internal API sets gyroscope user-gain configurations like gain - * update value for x, y and z-axis. - * - * @param[in] config : Structure instance of bmi2_gyro_user_gain_config. - * @param[in] dev : Structure instance of bmi2_dev. + * @brief This internal API is used to parse and store the sensor time from the + * FIFO data. * - * @verbatim - *---------------------------------------------------------------------------- - * bmi2_gyro_user_gain_config| - * Structure parameters | Description - *--------------------------|-------------------------------------------------- - * ratio_x | Gain update value for x-axis - * -------------------------|--------------------------------------------------- - * ratio_y | Gain update value for y-axis - * -------------------------|--------------------------------------------------- - * ratio_z | Gain update value for z-axis - * @endverbatim + * @param[in,out] data_index : Index of the FIFO data which has the sensor time. + * @param[in] fifo : Structure instance of bmi2_fifo_frame. * * @return Result of API execution status - * - * @retval BMI2_OK - Success. - * @retval BMI2_E_COM_FAIL - Error: Communication fail - * @retval BMI2_E_INVALID_SENSOR - Error: Invalid sensor - * @retval BMI2_E_INVALID_PAGE - Error: Invalid Page + * @retval 0 -> Success + * @retval < 0 -> Fail */ -static int8_t set_gyro_user_gain_config(const struct bmi2_gyro_user_gain_config *config, struct bmi2_dev *dev); +static int8_t unpack_sensortime_frame(uint16_t *data_index, struct bmi2_fifo_frame *fifo); /*! - * @brief This internal API sets tilt configurations like output-configuration. - * - * @param[in] config : Structure instance of bmi2_tilt_config. - * @param[in, out] dev : Structure instance of bmi2_dev. + * @brief This internal API is used to parse and store the skipped frame count + * from the FIFO data. * - * @verbatim - *---------------------------------------------------------------------------- - * bmi2_tilt_config | - * Structure parameters | Description - *------------------------- |-------------------------------------------------- - * | Enable bits for enabling output into the - * out_conf | register status bits and, if desired, onto the - * | interrupt pin. - * ------------------------ |--------------------------------------------------- - * @endverbatim + * @param[in,out] data_index : Index of the FIFO data which contains skipped + * frame count. + * @param[in] fifo : Structure instance of bmi2_fifo_frame. * * @return Result of API execution status - * - * @retval BMI2_OK - Success. - * @retval BMI2_E_COM_FAIL - Error: Communication fail - * @retval BMI2_E_INVALID_SENSOR - Error: Invalid sensor - * @retval BMI2_E_INVALID_PAGE - Error: Invalid Page + * @retval 0 -> Success + * @retval < 0 -> Fail */ -static int8_t set_tilt_config(const struct bmi2_tilt_config *config, struct bmi2_dev *dev); +static int8_t unpack_skipped_frame(uint16_t *data_index, struct bmi2_fifo_frame *fifo); /*! - * @brief This internal API sets uphold to wake configurations like output - * configuration. - * - * @param[in] config : Structure instance of bmi2_uphold_to_wake_config. - * @param[in, out] dev : Structure instance of bmi2_dev. + * @brief This internal API enables and configures the accelerometer which is + * needed for self-test operation. It also sets the amplitude for the self-test. * - * @verbatim - *---------------------------------------------------------------------------- - * bmi2_uphold_to_wake_config | - * Structure parameters | Description - *--------------------------|-------------------------------------------------- - * | Enable bits for enabling output into the - * out_conf | register status bits and, if desired, onto the - * | interrupt pin. - * -------------------------|--------------------------------------------------- - * @endverbatim + * @param[in] dev : Structure instance of bmi2_dev. * * @return Result of API execution status - * - * @retval BMI2_OK - Success. - * @retval BMI2_E_COM_FAIL - Error: Communication fail - * @retval BMI2_E_INVALID_SENSOR - Error: Invalid sensor - * @retval BMI2_E_INVALID_PAGE - Error: Invalid Page + * @retval 0 -> Success + * @retval < 0 -> Fail */ -static int8_t set_up_hold_to_wake_config(const struct bmi2_up_hold_to_wake_config *config, struct bmi2_dev *dev); +static int8_t pre_self_test_config(struct bmi2_dev *dev); /*! - * @brief This internal API sets glance detector configurations like output - * configuration. + * @brief This internal API performs the steps needed for self-test operation + * before reading the accelerometer self-test data. * - * @param[in] config : Structure instance of bmi2_glance_det_config. - * @param[in, out] dev : Structure instance of bmi2_dev. + * @param[in] sign : Selects sign of self-test excitation + * @param[in] dev : Structure instance of bmi2_dev. * - * @verbatim - *---------------------------------------------------------------------------- - * bmi2_glance_det_config| - * Structure parameters | Description - *-------------------------|-------------------------------------------------- - * | Enable bits for enabling output into the - * out_conf | register status bits and, if desired, onto the - * | interrupt pin. - * ------------------------|---------------------------------------------------- - * @endverbatim + * sign | Description + * -------------|--------------- + * BMI2_ENABLE | positive excitation + * BMI2_DISABLE | negative excitation * * @return Result of API execution status - * - * @retval BMI2_OK - Success. - * @retval BMI2_E_COM_FAIL - Error: Communication fail - * @retval BMI2_E_INVALID_SENSOR - Error: Invalid sensor - * @retval BMI2_E_INVALID_PAGE - Error: Invalid Page + * @retval 0 -> Success + * @retval < 0 -> Fail */ -static int8_t set_glance_detect_config(const struct bmi2_glance_det_config *config, struct bmi2_dev *dev); +static int8_t self_test_config(uint8_t sign, struct bmi2_dev *dev); /*! - * @brief This internal API sets wake-up configurations like sensitivity, - * single, double and triple tap enable and output-configuration. + * @brief This internal API enables or disables the accelerometer self-test + * feature in the sensor. * - * @param[in] config : Structure instance of bmi2_wake_up_config. - * @param[in, out] dev : Structure instance of bmi2_dev. + * @param[in] enable : Enables/ Disables self-test. + * @param[in] dev : Structure instance of bmi2_dev. * - * @verbatim - *----------------------------------------------------------------------------- - * bmi2_wake_up_config | - * Structure parameters | Description - *--------------------------|-------------------------------------------------- - * | Configures wake-up sensitivity, the range goes - * sensitivity | from 0 (high sensitive) to 7 (low sensitive). - * -------------------------|--------------------------------------------------- - * | Enable - Single Tap detection - * single_tap_en | Disable- Double Tap detection (Default value) - * -------------------------|--------------------------------------------------- - * | Enable bits for enabling output into the - * out_conf | register status bits and, if desired, onto the - * | interrupt pin. - * -------------------------|--------------------------------------------------- - * @endverbatim + * sign | Description + * -------------|--------------- + * BMI2_ENABLE | Enables self-test + * BMI2_DISABLE | Disables self-test * * @return Result of API execution status - * - * @retval BMI2_OK - Success. - * @retval BMI2_E_COM_FAIL - Error: Communication fail - * @retval BMI2_E_INVALID_SENSOR - Error: Invalid sensor - * @retval BMI2_E_INVALID_PAGE - Error: Invalid Page + * @retval 0 -> Success + * @retval < 0 -> Fail */ -static int8_t set_wake_up_config(struct bmi2_wake_up_config *config, struct bmi2_dev *dev); +static int8_t set_accel_self_test_enable(uint8_t enable, struct bmi2_dev *dev); /*! - * @brief This internal API sets orientation configurations like upside/down - * detection, symmetrical modes, blocking mode, theta, hysteresis and output - * configuration. - * - * @param[in] config : Structure instance of bmi2_orient_config. - * @param[in, out] dev : Structure instance of bmi2_dev. + * @brief This internal API selects the sign for accelerometer self-test + * excitation. * - * @verbatim - *----------------------------------------------------------------------------- - * bmi2_orient_config | - * Structure parameters | Description - *--------------------------|-------------------------------------------------- - * upside/down | Enables upside/down detection, if set to 1. - * detection | - * -------------------------|--------------------------------------------------- - * | Sets the mode: - * mode | Values 0 or 3 - symmetrical. - * | Value 1 - high asymmetrical - * | Value 2 - low asymmetrical - * -------------------------|--------------------------------------------------- - * | Enable - no orientation interrupt will be set. - * blocking | Default value: 3, the most restrictive blocking. - * -------------------------|--------------------------------------------------- - * | Threshold angle used in blocking mode. - * theta | Theta = 64 * (tan(angle)^2) - * | Default value: 40, equivalent to 38 degrees angle. - * -------------------------|--------------------------------------------------- - * | Acceleration hysteresis for Orientation detection - * | is expressed in 5.11g format. - * hysteresis | Default value is 128 = 0.0625g. - * | Range is 0 to 1g. - * -------------------------|--------------------------------------------------- - * | Enable bits for enabling output into the - * out_conf | register status bits and, if desired, onto the - * | interrupt pin. - * -------------------------|--------------------------------------------------- + * @param[in] sign : Selects sign of self-test excitation + * @param[in] dev : Structure instance of bmi2_dev. * - * @endverbatim + * sign | Description + * -------------|--------------- + * BMI2_ENABLE | positive excitation + * BMI2_DISABLE | negative excitation * * @return Result of API execution status - * - * @retval BMI2_OK - Success. - * @retval BMI2_E_COM_FAIL - Error: Communication fail - * @retval BMI2_E_INVALID_SENSOR - Error: Invalid sensor - * @retval BMI2_E_INVALID_PAGE - Error: Invalid Page + * @retval 0 -> Success + * @retval < 0 -> Fail */ -static int8_t set_orient_config(const struct bmi2_orient_config *config, struct bmi2_dev *dev); +static int8_t set_acc_self_test_sign(uint8_t sign, struct bmi2_dev *dev); /*! - * @brief This internal API sets high-g configurations like threshold, - * hysteresis, duration, and output configuration. + * @brief This internal API sets the amplitude of the accelerometer self-test + * deflection in the sensor. * - * @param[in] config : Structure instance of bmi2_high_g_config. - * @param[in, out] dev : Structure instance of bmi2_dev. + * @param[in] amp : Select amplitude of the self-test deflection. + * @param[in] dev : Structure instance of bmi2_dev. * - * @verbatim - *----------------------------------------------------------------------------- - * bmi2_high_g_config | - * Structure parameter | Description - *--------------------------|-------------------------------------------------- - * threshold | The acceleration threshold above which the - * | high_g motion is signaled. - * | Holds threshold in 5.11 g format. - * | Default is 3072 = 1.5 g. - * | Range is 0 to 16g. - * -------------------------|--------------------------------------------------- - * | Acceleration hysteresis for high-g detection - * | is expressed in 1.11g format. - * hysteresis | Default value is 256 = 0.125 g. - * | Range is 0 to 2g. - * | Should be smaller than threshold. - * -------------------------|--------------------------------------------------- - * | Holds the duration in 200 Hz samples (5 ms) for - * | which the threshold has to be exceeded. - * duration | Default value 4 = 20 msec. - * | Range is 0 to 20sec. - * -------------------------|--------------------------------------------------- - * x_sel, y_sel, z_sel | Selects the feature on a per-axis basis - * -------------------------|--------------------------------------------------- - * | Enable bits for enabling output into the - * out_conf | register status bits and, if desired, onto the - * | interrupt pin. - * -------------------------|--------------------------------------------------- - * @endverbatim + * amp | Description + * -------------|--------------- + * BMI2_ENABLE | self-test amplitude is high + * BMI2_DISABLE | self-test amplitude is low * * @return Result of API execution status - * - * @retval BMI2_OK - Success. - * @retval BMI2_E_COM_FAIL - Error: Communication fail - * @retval BMI2_E_INVALID_SENSOR - Error: Invalid sensor - * @retval BMI2_E_INVALID_PAGE - Error: Invalid Page + * @retval 0 -> Success + * @retval < 0 -> Fail */ -static int8_t set_high_g_config(const struct bmi2_high_g_config *config, struct bmi2_dev *dev); +static int8_t set_accel_self_test_amp(uint8_t amp, struct bmi2_dev *dev); /*! - * @brief This internal API sets low-g configurations like threshold, - * hysteresis, duration, and output configuration. - * - * @param[in] config : Structure instance of bmi2_low_g_config. - * @param[in, out] dev : Structure instance of bmi2_dev. + * @brief This internal API reads the accelerometer data for x,y and z axis from + * the sensor. The data units is in LSB format. * - * @verbatim - *---------------------------------------------------------------------------- - * bmi2_low_g_config | - * Structure parameters | Description - *--------------------------|-------------------------------------------------- - * threshold | The acceleration threshold above which the - * | low-g motion is signaled. - * | Holds threshold in 5.11 g format. - * | Default is 3072 = 1.5 g. - * -------------------------|--------------------------------------------------- - * | Acceleration hysteresis for low-g detection - * hysteresis | is expressed in 1.11g format. - * | Default value is 512 = 0.250 g. - * | Should be smaller than threshold. - * -------------------------|--------------------------------------------------- - * | Holds the duration in 50 Hz samples (20 ms) for - * | which the threshold has to be exceeded. - * duration | Default value 0 = 1 validation sample = (0+1)*20 - * | = 20 ms. - * -------------------------|--------------------------------------------------- - * | Enable bits for enabling output into the - * out_conf | register status bits and, if desired, onto the - * | interrupt pin. - * -------------------------|--------------------------------------------------- - * @endverbatim + * @param[out] accel : Buffer to store the acceleration value. + * @param[in] dev : Structure instance of bmi2_dev. * * @return Result of API execution status - * - * @retval BMI2_OK - Success. - * @retval BMI2_E_COM_FAIL - Error: Communication fail - * @retval BMI2_E_INVALID_SENSOR - Error: Invalid sensor - * @retval BMI2_E_INVALID_PAGE - Error: Invalid Page + * @retval 0 -> Success + * @retval < 0 -> Fail */ -static int8_t set_low_g_config(const struct bmi2_low_g_config *config, struct bmi2_dev *dev); +static int8_t read_accel_xyz(struct bmi2_sens_axes_data *accel, struct bmi2_dev *dev); /*! - * @brief This internal API sets flat configurations like theta, blocking, - * hold-time, hysteresis, and output configuration. - * - * @param[in] config : Structure instance of bmi2_flat_config. - * @param[in, out] dev : Structure instance of bmi2_dev. - * - * @verbatim - *---------------------------------------------------------------------------- - * bmi2_flat_config | - * Structure parameters| Description - *--------------------------|-------------------------------------------------- - * | Sets the theta angle, used for detecting flat - * | position. - * theta | Theta = 64 * (tan(angle)^2); - * | Default value is 8, equivalent to 20 degrees angle - * -------------------------|--------------------------------------------------- - * | Hysteresis for Theta Flat detection. - * hysteresis | Default value is 9 = 2.5 degrees, corresponding - * | to the default Theta angle of 20 degrees. - * -------------------------|--------------------------------------------------- - * | Sets the blocking mode. If blocking is set, no - * | Flat interrupt will be triggered. - * blocking | Default value is 2, the most restrictive blocking - * | mode. - * -------------------------|--------------------------------------------------- - * | Holds the duration in 50Hz samples for which the - * | condition has to be respected. - * hold-time | Default value is 32 = 640 m-sec. - * | Range is 0 to 5.1 sec. - * -------------------------|--------------------------------------------------- - * | Enable bits for enabling output into the - * out_conf | register status bits and, if desired, onto the - * | interrupt pin. - * -------------------------|--------------------------------------------------- - * @endverbatim + * @brief This internal API converts LSB value of accelerometer axes to form + * 'g' to 'mg' for self-test. * - * @return Result of API execution status + * @param[in] acc_data_diff : Stores the acceleration value difference in g. + * @param[out]acc_data_diff_mg : Stores the acceleration value difference in mg. + * @param[in] dev : Structure instance of bmi2_dev. * - * @retval BMI2_OK - Success. - * @retval BMI2_E_COM_FAIL - Error: Communication fail - * @retval BMI2_E_INVALID_SENSOR - Error: Invalid sensor - * @retval BMI2_E_INVALID_PAGE - Error: Invalid Page + * @return None + * @retval None */ -static int8_t set_flat_config(const struct bmi2_flat_config *config, struct bmi2_dev *dev); +static void convert_lsb_g(const struct bmi2_selftest_delta_limit *acc_data_diff, + struct bmi2_selftest_delta_limit *acc_data_diff_mg, + const struct bmi2_dev *dev); /*! - * @brief This internal API sets external sensor sync configurations like output - * configuration. - * - * @param[out] config : Structure instance of bmi2_ext_sens_sync_config. - * @param[in, out] dev : Structure instance of bmi2_dev. - * - *---------------------------------------------------------------------------- - * bmi2_ext_sens_sync_config | - * Structure parameters | Description - * -----------------------------|---------------------------------------------- - * |Enable bits for enabling output into the - * out_conf |register status bits and, if desired, onto the - * |interrupt pin. - * -----------------------------|---------------------------------------------- + * @brief This internal API is used to calculate the power of a value. * - * @return Result of API execution status + * @param[in] base : base for power calculation. + * @param[in] resolution : exponent for power calculation. * - * @retval BMI2_OK - Success. - * @retval BMI2_E_COM_FAIL - Error: Communication fail - * @retval BMI2_E_INVALID_SENSOR - Error: Invalid sensor - * @retval BMI2_E_INVALID_PAGE - Error: Invalid Page + * @return the calculated power + * @retval the power value */ -static int8_t set_ext_sens_sync_config(const struct bmi2_ext_sens_sync_config *config, struct bmi2_dev *dev); +static int32_t power(int16_t base, uint8_t resolution); /*! - * @brief This internal API sets wrist gesture configurations like wearable-arm, - * and output-configuration. - * - * @param[in] config : Structure instance of bmi2_wrist_gest_config. - * @param[in, out] dev : Structure instance of bmi2_dev. + * @brief This internal API validates the accelerometer self-test data and + * decides the result of self-test operation. * - * @verbatim - *----------------------------------------------------------------------------- - * bmi2_wrist_gest_config | - * Structure parameters | Description - *--------------------------|-------------------------------------------------- - * | Device in left (0) or right (1) arm. By default, - * wear_arm | the wearable device is assumed to be in left arm - * | i.e. default value is 0. - * -------------------------|--------------------------------------------------- - * | Enable bits for enabling output into the - * out_conf | register status bits and, if desired, onto the - * | interrupt pin. - * -------------------------|--------------------------------------------------- - * @endverbatim + * @param[in] accel_data_diff : Stores the acceleration value difference. * * @return Result of API execution status - * - * @retval BMI2_OK - Success. - * @retval BMI2_E_COM_FAIL - Error: Communication fail - * @retval BMI2_E_INVALID_SENSOR - Error: Invalid sensor - * @retval BMI2_E_INVALID_PAGE - Error: Invalid Page + * @retval 0 -> Success + * @retval < 0 -> Fail */ -static int8_t set_wrist_gest_config(const struct bmi2_wrist_gest_config *config, struct bmi2_dev *dev); +static int8_t validate_self_test(const struct bmi2_selftest_delta_limit *accel_data_diff); /*! - * @brief This internal API sets wrist wear wake-up configurations like - * output-configuration. - * - * @param[in] config : Structure instance of - * bmi2_wrist_wear_wake_up_config. - * @param[in, out] dev : Structure instance of bmi2_dev. + * @brief This internal API gets the re-mapped x, y and z axes from the sensor. * - * @verbatim - *----------------------------------------------------------------------------- - * bmi2_wrist_wear_wake_up_config | - * Structure parameters | Description - *----------------------------------|------------------------------------------- - * | Enable bits for enabling output into the - * out_conf | register status bits and, if desired, onto - * | the interrupt pin. - * ---------------------------------|------------------------------------------- - * @endverbatim + * @param[out] remap : Structure that stores local copy of re-mapped axes. + * @param[in] dev : Structure instance of bmi2_dev. * * @return Result of API execution status - * - * @retval BMI2_OK - Success. - * @retval BMI2_E_COM_FAIL - Error: Communication fail - * @retval BMI2_E_INVALID_SENSOR - Error: Invalid sensor - * @retval BMI2_E_INVALID_PAGE - Error: Invalid Page + * @retval 0 -> Success + * @retval < 0 -> Fail */ -static int8_t set_wrist_wear_wake_up_config(const struct bmi2_wrist_wear_wake_up_config *config, struct bmi2_dev *dev); +static int8_t get_remap_axes(struct bmi2_axes_remap *remap, struct bmi2_dev *dev); /*! - * @brief This internal API sets wrist gesture configurations like wearable-arm, - * and output-configuration for wearable variant. - * - * @param[in] config : Structure instance of bmi2_wrist_gest_config. - * @param[in, out] dev : Structure instance of bmi2_dev. + * @brief This internal API sets the re-mapped x, y and z axes in the sensor. * - * @verbatim - *----------------------------------------------------------------------------- - * bmi2_wrist_gest_config | - * Structure parameters | Description - *--------------------------|-------------------------------------------------- - * | Device in left (0) or right (1) arm. By default, - * wear_arm | the wearable device is assumed to be in left arm - * | i.e. default value is 0. - * -------------------------|--------------------------------------------------- - * | Enable bits for enabling output into the - * out_conf | register status bits and, if desired, onto the - * | interrupt pin. - * -------------------------|--------------------------------------------------- - * @endverbatim + * @param[in] remap : Structure that stores local copy of re-mapped axes. + * @param[in] dev : Structure instance of bmi2_dev. * * @return Result of API execution status - * - * @retval BMI2_OK - Success. - * @retval BMI2_E_COM_FAIL - Error: Communication fail - * @retval BMI2_E_INVALID_SENSOR - Error: Invalid sensor - * @retval BMI2_E_INVALID_PAGE - Error: Invalid Page + * @retval 0 -> Success + * @retval < 0 -> Fail */ -static int8_t set_wrist_gest_w_config(const struct bmi2_wrist_gest_w_config *config, struct bmi2_dev *dev); +static int8_t set_remap_axes(const struct bmi2_axes_remap *remap, struct bmi2_dev *dev); /*! - * @brief This internal API sets wrist wear wake-up configurations like - * output-configuration for wearable variant. - * - * @param[in] config : Structure instance of - * bmi2_wrist_wear_wake_up_config. - * @param[in, out] dev : Structure instance of bmi2_dev. + * @brief Interface to get max burst length * - * @verbatim - *----------------------------------------------------------------------------- - * bmi2_wrist_wear_wake_up_config | - * Structure parameters | Description - *----------------------------------|------------------------------------------- - * | Enable bits for enabling output into the - * out_conf | register status bits and, if desired, onto - * | the interrupt pin. - * ---------------------------------|------------------------------------------- - * @endverbatim + * @param[in] max_burst_len : Pointer to store max burst length + * @param[in] dev : Structure instance of bmi2_dev. * * @return Result of API execution status - * - * @retval BMI2_OK - Success. - * @retval BMI2_E_COM_FAIL - Error: Communication fail - * @retval BMI2_E_INVALID_SENSOR - Error: Invalid sensor - * @retval BMI2_E_INVALID_PAGE - Error: Invalid Page + * @retval 0 -> Success + * @retval < 0 -> Fail */ -static int8_t set_wrist_wear_wake_up_wh_config(const struct bmi2_wrist_wear_wake_up_wh_config *config, - struct bmi2_dev *dev); +static int8_t get_maxburst_len(uint8_t *max_burst_len, struct bmi2_dev *dev); /*! - * @brief This internal API gets accelerometer configurations like ODR, - * bandwidth, performance mode and g-range. + * @brief This internal API sets the max burst length. * - * @param[out] config : Structure instance of bmi2_accel_config. - * @param[in] dev : Structure instance of bmi2_dev. + * @param[in] write_len_byte : read & write length + * @param[in] dev : Structure instance of bmi2_dev. * * @return Result of API execution status - * - * @retval BMI2_OK - Success. - * @retval BMI2_E_NULL_PTR - Error: Null pointer error + * @retval 0 -> Success + * @retval < 0 -> Fail */ -static int8_t get_accel_config(struct bmi2_accel_config *config, struct bmi2_dev *dev); +static int8_t set_maxburst_len(const uint16_t write_len_byte, struct bmi2_dev *dev); /*! - * @brief This internal API gets gyroscope configurations like ODR, bandwidth, - * low power/ high performance mode, performance mode and range. - * - * @param[out] config : Structure instance of bmi2_gyro_config. - * @param[in] dev : Structure instance of bmi2_dev. + * @brief This internal API parses virtual frame header from the FIFO data. * - * @return Result of API execution status + * @param[in, out] frame_header : FIFO frame header. + * @param[in, out] data_index : Index value of the FIFO data bytes + * from which sensor frame header is to be parsed + * @param[in] fifo : Structure instance of bmi2_fifo_frame. * - * @retval BMI2_OK - Success. - * @retval BMI2_E_NULL_PTR - Error: Null pointer error - * @retval BMI2_E_INVALID_PAGE - Error: Invalid Page + * @return None + * @retval None */ -static int8_t get_gyro_config(struct bmi2_gyro_config *config, struct bmi2_dev *dev); +static void parse_if_virtual_header(uint8_t *frame_header, uint16_t *data_index, const struct bmi2_fifo_frame *fifo); /*! - * @brief This internal API: - * 1) Gets the status of auxiliary interface enable. - * 2) Gets auxiliary interface configurations like I2C address, manual/auto - * mode enable, manual burst read length, AUX burst read length and AUX read - * address. - * 3) Gets ODR and offset. - * - * @param[out] config : Structure instance of bmi2_aux_config. - * @param[in] dev : Structure instance of bmi2_dev. + * @brief This internal API gets sensor time from the accelerometer and + * gyroscope virtual frames and updates in the data structure. * - * @return Result of API execution status + * @param[out] sens : Sensor data structure + * @param[in, out] idx : Index of FIFO from where the data is to retrieved. + * @param[in] fifo : Structure instance of bmi2_fifo_frame. * - * @retval BMI2_OK - Success. - * @retval BMI2_E_COM_FAIL - Error: Communication fail - * @retval BMI2_E_INVALID_PAGE - Error: Invalid Page + * @return None + * @retval None */ -static int8_t get_aux_config(struct bmi2_aux_config *config, struct bmi2_dev *dev); +static void unpack_virt_sensor_time(struct bmi2_sens_axes_data *sens, uint16_t *idx, + const struct bmi2_fifo_frame *fifo); /*! - * @brief This internal API gets the enable status of auxiliary interface. - * - * @param[out] config : Structure instance of bmi2_aux_config. - * @param[in] dev : Structure instance of bmi2_dev. + * @brief This internal API gets sensor time from the auxiliary virtual + * frames and updates in the data structure. * - * @return Result of API execution status + * @param[out] aux : Auxiliary sensor data structure + * @param[in, out] idx : Index of FIFO from where the data is to retrieved. + * @param[in] fifo : Structure instance of bmi2_fifo_frame. * - * @retval BMI2_OK - Success. - * @retval BMI2_E_COM_FAIL - Error: Communication fail - * @retval BMI2_E_INVALID_PAGE - Error: Invalid Page + * @return None + * @retval None */ -static int8_t get_aux_interface(struct bmi2_aux_config *config, struct bmi2_dev *dev); +static void unpack_virt_aux_sensor_time(struct bmi2_aux_fifo_data *aux, + uint16_t *idx, + const struct bmi2_fifo_frame *fifo); /*! - * @brief This internal API gets auxiliary configurations like manual/auto mode - * FCU write command enable and read burst length for both data and manual mode. + * @brief This internal API corrects the gyroscope cross-axis sensitivity + * between the z and the x axis. * - * @param[out] config : Structure instance of bmi2_aux_config. - * @param[in] dev : Structure instance of bmi2_dev. + * @param[in] dev : Structure instance of bmi2_dev. + * @param[out] gyr_data : Structure instance of gyroscope data * * @return Result of API execution status * - * @retval BMI2_OK - Success. - * @retval BMI2_E_COM_FAIL - Error: Communication fail - * @retval BMI2_E_INVALID_PAGE - Error: Invalid Page + * @return None + * @retval None */ -static int8_t get_aux_interface_config(struct bmi2_aux_config *config, struct bmi2_dev *dev); +static void comp_gyro_cross_axis_sensitivity(struct bmi2_sens_axes_data *gyr_data, const struct bmi2_dev *dev); /*! - * @brief This internal API gets read out offset and ODR of the auxiliary - * sensor. + * @brief This internal API saves the configurations before performing FOC. * - * @param[out] config : Structure instance of bmi2_aux_config. - * @param[in] dev : Structure instance of bmi2_dev. + * @param[out] acc_cfg : Accelerometer configuration value + * @param[out] aps : Advance power mode value + * @param[out] acc_en : Accelerometer enable value + * @param[in] dev : Structure instance of bmi2_dev * * @return Result of API execution status - * - * @retval BMI2_OK - Success. - * @retval BMI2_E_COM_FAIL - Error: Communication fail - * @retval BMI2_E_INVALID_PAGE - Error: Invalid Page + * @retval 0 -> Success + * @retval < 0 -> Fail */ -static int8_t get_aux_cfg(struct bmi2_aux_config *config, struct bmi2_dev *dev); +static int8_t save_accel_foc_config(struct bmi2_accel_config *acc_cfg, + uint8_t *aps, + uint8_t *acc_en, + struct bmi2_dev *dev); /*! - * @brief This internal API gets any-motion configurations like axes select, - * duration, threshold and output-configuration. + * @brief This internal API performs Fast Offset Compensation for accelerometer. * - * @param[out] config : Structure instance of bmi2_any_motion_config. - * @param[in, out] dev : Structure instance of bmi2_dev. + * @param[in] accel_g_value : This parameter selects the accel foc + * axis to be performed * - * @verbatim - *---------------------------------------------------------------------------- - * bmi2_any_motion_config | - * Structure parameters | Description - *--------------------------|-------------------------------------------------- - * | Defines the number of consecutive data points for - * | which the threshold condition must be respected, - * | for interrupt assertion. It is expressed in 50 Hz - * duration | samples (20 msec). - * | Range is 0 to 163sec. - * | Default value is 5 = 100ms. - * -------------------------|--------------------------------------------------- - * | Slope threshold value for in 5.11g format. - * threshold | Range is 0 to 1g. - * | Default value is 0xAA = 83mg. - * -------------------------|--------------------------------------------------- - * x_sel, y_sel, z_sel | Selects the feature on a per-axis basis - * -------------------------|--------------------------------------------------- - * | Enable bits for enabling output into the - * out_conf | register status bits and, if desired, onto the - * | interrupt pin. - * @endverbatim + * input format is {x, y, z, sign}. '1' to enable. '0' to disable * - * @return Result of API execution status + * eg to choose x axis {1, 0, 0, 0} + * eg to choose -x axis {1, 0, 0, 1} * - * @retval BMI2_OK - Success. - * @retval BMI2_E_COM_FAIL - Error: Communication fail - * @retval BMI2_E_INVALID_SENSOR - Error: Invalid sensor - * @retval BMI2_E_INVALID_PAGE - Error: Invalid Page + * @param[in] acc_cfg : Accelerometer configuration value + * @param[in] dev : Structure instance of bmi2_dev. + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail */ -static int8_t get_any_motion_config(struct bmi2_any_motion_config *config, struct bmi2_dev *dev); +static int8_t perform_accel_foc(const struct bmi2_accel_foc_g_value *accel_g_value, + const struct bmi2_accel_config *acc_cfg, + struct bmi2_dev *dev); /*! - * @brief This internal API gets no-motion configurations like axes select, - * duration, threshold and output-configuration. - * - * @param[out] config : Structure instance of bmi2_no_motion_config. - * @param[in, out] dev : Structure instance of bmi2_dev. + * @brief This internal sets configurations for performing accelerometer FOC. * - * @verbatim - *---------------------------------------------------------------------------- - * bmi2_no_motion_config | - * Structure parameters | Description - *--------------------------|-------------------------------------------------- - * | Defines the number of consecutive data points for - * | which the threshold condition must be respected, - * | for interrupt assertion. It is expressed in 50 Hz - * duration | samples (20 msec). - * | Range is 0 to 163sec. - * | Default value is 5 = 100ms. - * -------------------------|--------------------------------------------------- - * | Slope threshold value for in 5.11g format. - * threshold | Range is 0 to 1g. - * | Default value is 0xAA = 83mg. - * -------------------------|--------------------------------------------------- - * x_sel, y_sel, z_sel | Selects the feature on a per-axis basis - * -------------------------|--------------------------------------------------- - * | Enable bits for enabling output into the - * out_conf | register status bits and, if desired, onto the - * | interrupt pin. - * @endverbatim + * @param[in] dev : Structure instance of bmi2_dev * * @return Result of API execution status - * - * @retval BMI2_OK - Success. - * @retval BMI2_E_COM_FAIL - Error: Communication fail - * @retval BMI2_E_INVALID_SENSOR - Error: Invalid sensor - * @retval BMI2_E_INVALID_PAGE - Error: Invalid Page + * @retval 0 -> Success + * @retval < 0 -> Fail */ -static int8_t get_no_motion_config(struct bmi2_no_motion_config *config, struct bmi2_dev *dev); +static int8_t set_accel_foc_config(struct bmi2_dev *dev); /*! - * @brief This internal API gets sig-motion configurations like block-size, - * output-configuration and other parameters. - * - * @param[out] config : Structure instance of bmi2_sig_motion_config. - * @param[in, out] dev : Structure instance of bmi2_dev. + * @brief This internal API enables/disables the offset compensation for + * filtered and un-filtered accelerometer data. * - *---------------------------------------------------------------------------- - * bmi2_sig_motion_config | - * Structure parameters | Description - * -------------------------|--------------------------------------------------- - * | Defines the duration after which the significant - * block_size | motion interrupt is triggered. It is expressed in - * | 50 Hz samples (20 ms). Default value is 0xFA=5sec. - *--------------------------|--------------------------------------------------- - * | Enable bits for enabling output into the - * out_conf | register status bits and, if desired, onto the - * | interrupt pin. - *--------------------------|--------------------------------------------------- + * @param[in] offset_en : enables/disables offset compensation. + * @param[in] dev : Structure instance of bmi2_dev * * @return Result of API execution status - * - * @retval BMI2_OK - Success. - * @retval BMI2_E_COM_FAIL - Error: Communication fail - * @retval BMI2_E_INVALID_SENSOR - Error: Invalid sensor - * @retval BMI2_E_INVALID_PAGE - Error: Invalid Page + * @retval 0 -> Success + * @retval < 0 -> Fail */ -static int8_t get_sig_motion_config(struct bmi2_sig_motion_config *config, struct bmi2_dev *dev); +static int8_t set_accel_offset_comp(uint8_t offset_en, struct bmi2_dev *dev); /*! - * @brief This internal API gets step counter parameter configurations. - * - * @param[in] step_count_params : Array that stores parameters 1 to 25. - * @param[in] dev : Structure instance of bmi2_dev. + * @brief This internal API converts the range value into accelerometer + * corresponding integer value. * - * @return Result of API execution status + * @param[in] range_in : Input range value. + * @param[out] range_out : Stores the integer value of range. * - * @retval BMI2_OK - Success. - * @retval BMI2_E_COM_FAIL - Error: Communication fail - * @retval BMI2_E_INVALID_SENSOR - Error: Invalid sensor - * @retval BMI2_E_INVALID_PAGE - Error: Invalid Page + * @return None + * @retval None */ -static int8_t get_step_count_params_config(uint16_t *step_count_params, struct bmi2_dev *dev); +static void map_accel_range(uint8_t range_in, uint8_t *range_out); /*! - * @brief This internal API gets step counter/detector/activity configurations. + * @brief This internal API compensate the accelerometer data against gravity. * - * @param[out] config : Structure instance of bmi2_step_config. - * @param[in] dev : Structure instance of bmi2_dev. + * @param[in] lsb_per_g : LSB value pre 1g. + * @param[in] g_val : G reference value of all axis. + * @param[in] data : Accelerometer data + * @param[out] comp_data : Stores the data that is compensated by taking the + * difference in accelerometer data and lsb_per_g + * value. * - * @return Result of API execution status + * @return None + * @retval None + */ +static void comp_for_gravity(uint16_t lsb_per_g, + const struct bmi2_accel_foc_g_value *g_val, + const struct bmi2_sens_axes_data *data, + struct bmi2_offset_delta *comp_data); + +/*! + * @brief This internal API scales the compensated accelerometer data according + * to the offset register resolution. * - * @verbatim - *---------------------------------------------------------------------------- - * bmi2_step_config | - * Structure parameters | Description - *--------------------------|-------------------------------------------------- - * | The Step-counter will trigger output every time - * | the number of steps are counted. Holds implicitly - * water-mark level | a 20x factor, so the range is 0 to 10230, - * | with resolution of 20 steps. - * -------------------------|--------------------------------------------------- - * reset counter | Flag to reset the counted steps. - * -------------------------|--------------------------------------------------- - * | Enable bits for enabling output into the - * step_det_out_conf | register status bits and, if desired, onto the - * | interrupt pin for step detector. - * -------------------------|--------------------------------------------------- - * | Enable bits for enabling output into the - * step_act_out_conf | register status bits and, if desired, onto the - * | interrupt pin for step activity. - * -------------------------|--------------------------------------------------- - * @endverbatim + * @param[in] range : G-range of the accelerometer. + * @param[out] comp_data : Data that is compensated by taking the + * difference in accelerometer data and lsb_per_g + * value. + * @param[out] data : Stores offset data * - * @retval BMI2_OK - Success. - * @retval BMI2_E_COM_FAIL - Error: Communication fail - * @retval BMI2_E_INVALID_SENSOR - Error: Invalid sensor - * @retval BMI2_E_INVALID_PAGE - Error: Invalid Page + * @return None + * @retval None */ -static int8_t get_step_config(struct bmi2_step_config *config, struct bmi2_dev *dev); +static void scale_accel_offset(uint8_t range, const struct bmi2_offset_delta *comp_data, + struct bmi2_accel_offset *data); /*! - * @brief This internal API gets gyroscope user-gain configurations like gain - * update value for x, y and z-axis. - * - * @param[out] config : Structure instance of bmi2_gyro_user_gain_config. - * @param[in] dev : Structure instance of bmi2_dev. + * @brief This internal API finds the bit position of 3.9mg according to given + * range and resolution. * - * @verbatim - *---------------------------------------------------------------------------- - * bmi2_gyro_user_gain_config| - * Structure parameters | Description - *-------------------------|-------------------------------------------------- - * ratio_x | Gain update value for x-axis - * ------------------------|--------------------------------------------------- - * ratio_y | Gain update value for y-axis - * ------------------------|--------------------------------------------------- - * ratio_z | Gain update value for z-axis - * @endverbatim + * @param[in] range : G-range of the accelerometer. * * @return Result of API execution status - * - * @retval BMI2_OK - Success. - * @retval BMI2_E_COM_FAIL - Error: Communication fail - * @retval BMI2_E_INVALID_SENSOR - Error: Invalid sensor - * @retval BMI2_E_INVALID_PAGE - Error: Invalid Page + * @retval Bit position of 3.9mg */ -static int8_t get_gyro_gain_update_config(struct bmi2_gyro_user_gain_config *config, struct bmi2_dev *dev); +static int8_t get_bit_pos_3_9mg(uint8_t range); /*! - * @brief This internal API gets tilt configurations like output-configuration. - * - * @param[out] config : Structure instance of bmi2_tilt_config. - * @param[in, out] dev : Structure instance of bmi2_dev. - * - * @verbatim - *---------------------------------------------------------------------------- - * bmi2_tilt_config | - * Structure parameters | Description - *--------------------------|-------------------------------------------------- - * | Enable bits for enabling output into the - * out_conf | register status bits and, if desired, onto the - * | interrupt pin. - * -------------------------|--------------------------------------------------- - * @endverbatim + * @brief This internal API inverts the accelerometer offset data. * - * @return Result of API execution status + * @param[out] offset_data : Stores the inverted offset data * - * @retval BMI2_OK - Success. - * @retval BMI2_E_COM_FAIL - Error: Communication fail - * @retval BMI2_E_INVALID_SENSOR - Error: Invalid sensor - * @retval BMI2_E_INVALID_PAGE - Error: Invalid Page + * @return None + * @retval None */ -static int8_t get_tilt_config(struct bmi2_tilt_config *config, struct bmi2_dev *dev); +static void invert_accel_offset(struct bmi2_accel_offset *offset_data); /*! - * @brief This internal API gets uphold to wake configurations like output - * configuration. - * - * @param[out] config : Structure instance of bmi2_up_hold_to_wake_config. - * @param[in, out] dev : Structure instance of bmi2_dev. + * @brief This internal API writes the offset data in the offset compensation + * register. * - * @verbatim - *---------------------------------------------------------------------------- - * bmi2_up_hold_to_wake_config | - * Structure parameters | Description - *--------------------------|-------------------------------------------------- - * | Enable bits for enabling output into the - * out_conf | register status bits and, if desired, onto the - * | interrupt pin. - * -------------------------|--------------------------------------------------- - * @endverbatim + * @param[in] offset : offset data + * @param[in] dev : Structure instance of bmi2_dev * * @return Result of API execution status - * - * @retval BMI2_OK - Success. - * @retval BMI2_E_COM_FAIL - Error: Communication fail - * @retval BMI2_E_INVALID_SENSOR - Error: Invalid sensor - * @retval BMI2_E_INVALID_PAGE - Error: Invalid Page + * @retval 0 -> Success + * @retval < 0 -> Fail */ -static int8_t get_up_hold_to_wake_config(struct bmi2_up_hold_to_wake_config *config, struct bmi2_dev *dev); +static int8_t write_accel_offset(const struct bmi2_accel_offset *offset, struct bmi2_dev *dev); /*! - * @brief This internal API gets glance detector configurations like output - * configuration. - * - * @param[out] config : Structure instance of bmi2_glance_det_config. - * @param[in, out] dev : Structure instance of bmi2_dev. + * @brief This internal API restores the configurations saved before performing + * accelerometer FOC. * - * @verbatim - *---------------------------------------------------------------------------- - * bmi2_glance_det_config| - * Structure parameters | Description - *-------------------------|-------------------------------------------------- - * | Enable bits for enabling output into the - * out_conf | register status bits and, if desired, onto the - * | interrupt pin. - * ------------------------|---------------------------------------------------- - * @endverbatim + * @param[in] acc_cfg : Accelerometer configuration value + * @param[in] acc_en : Accelerometer enable value + * @param[in] aps : Advance power mode value + * @param[in] dev : Structure instance of bmi2_dev * * @return Result of API execution status - * - * @retval BMI2_OK - Success. - * @retval BMI2_E_COM_FAIL - Error: Communication fail - * @retval BMI2_E_INVALID_SENSOR - Error: Invalid sensor - * @retval BMI2_E_INVALID_PAGE - Error: Invalid Page + * @retval 0 -> Success + * @retval < 0 -> Fail */ -static int8_t get_glance_detect_config(struct bmi2_glance_det_config *config, struct bmi2_dev *dev); +static int8_t restore_accel_foc_config(struct bmi2_accel_config *acc_cfg, + uint8_t aps, + uint8_t acc_en, + struct bmi2_dev *dev); /*! - * @brief This internal API gets wake-up configurations like sensitivity, - * single, double and triple tap enable and output-configuration. - * - * @param[out] config : Structure instance of bmi2_wake_up_config. - * @param[in, out] dev : Structure instance of bmi2_dev. + * @brief This internal API saves the configurations before performing gyroscope + * FOC. * - * @verbatim - *----------------------------------------------------------------------------- - * bmi2_wake_up_config | - * Structure parameters | Description - *--------------------------|-------------------------------------------------- - * | Configures wake-up sensitivity, the range goes - * sensitivity | from 0 (high sensitive) to 7 (low sensitive). - * -------------------------|--------------------------------------------------- - * | Enable - Single Tap detection - * single_tap_en | Disable- Double Tap detection (Default value) - * -------------------------|--------------------------------------------------- - * | Enable bits for enabling output into the - * out_conf | register status bits and, if desired, onto the - * | interrupt pin. - * -------------------------|--------------------------------------------------- - * @endverbatim + * @param[out] gyr_cfg : Gyroscope configuration value + * @param[out] gyr_en : Gyroscope enable value + * @param[out] aps : Advance power mode value + * @param[in] dev : Structure instance of bmi2_dev * * @return Result of API execution status - * - * @retval BMI2_OK - Success. - * @retval BMI2_E_COM_FAIL - Error: Communication fail - * @retval BMI2_E_INVALID_SENSOR - Error: Invalid sensor - * @retval BMI2_E_INVALID_PAGE - Error: Invalid Page + * @retval 0 -> Success + * @retval < 0 -> Fail */ -static int8_t get_wake_up_config(struct bmi2_wake_up_config *config, struct bmi2_dev *dev); +static int8_t save_gyro_config(struct bmi2_gyro_config *gyr_cfg, uint8_t *aps, uint8_t *gyr_en, struct bmi2_dev *dev); /*! - * @brief This internal API gets wrist gesture configurations like wearable-arm, - * and output-configuration. - * - * @param[out] config : Structure instance of bmi2_wrist_gest_config. - * @param[in, out] dev : Structure instance of bmi2_dev. + * @brief This internal sets configurations for performing gyroscope FOC. * - * @verbatim - *----------------------------------------------------------------------------- - * bmi2_wrist_gest_config | - * Structure parameters | Description - *--------------------------|-------------------------------------------------- - * | Device in left (0) or right (1) arm. By default, - * wear_arm | the wearable device is assumed to be in left arm - * | i.e. default value is 0. - * -------------------------|--------------------------------------------------- - * | Enable bits for enabling output into the - * out_conf | register status bits and, if desired, onto the - * | interrupt pin. - * -------------------------|--------------------------------------------------- - * @endverbatim + * @param[in] dev : Structure instance of bmi2_dev * * @return Result of API execution status - * - * @retval BMI2_OK - Success. - * @retval BMI2_E_COM_FAIL - Error: Communication fail - * @retval BMI2_E_INVALID_SENSOR - Error: Invalid sensor - * @retval BMI2_E_INVALID_PAGE - Error: Invalid Page + * @retval 0 -> Success + * @retval < 0 -> Fail */ -static int8_t get_wrist_gest_config(struct bmi2_wrist_gest_config *config, struct bmi2_dev *dev); +static int8_t set_gyro_foc_config(struct bmi2_dev *dev); /*! - * @brief This internal API gets wrist wear wake-up configurations like - * output-configuration. - * - * @param[out] config : Structure instance of - * bmi2_wrist_wear_wake_up_config. - * @param[in, out] dev : Structure instance of bmi2_dev. - * - * @verbatim - *----------------------------------------------------------------------------- - * bmi2_wrist_wear_wake_up_config | - * Structure parameters | Description - *----------------------------------|------------------------------------------- - * | Enable bits for enabling output into the - * out_conf | register status bits and, if desired, onto - * | the interrupt pin. - * ---------------------------------|------------------------------------------- - * @endverbatim + * @brief This internal API inverts the gyroscope offset data. * - * @return Result of API execution status + * @param[out] offset_data : Stores the inverted offset data * - * @retval BMI2_OK - Success. - * @retval BMI2_E_COM_FAIL - Error: Communication fail - * @retval BMI2_E_INVALID_SENSOR - Error: Invalid sensor - * @retval BMI2_E_INVALID_PAGE - Error: Invalid Page + * @return None + * @retval None */ -static int8_t get_wrist_wear_wake_up_config(struct bmi2_wrist_wear_wake_up_config *config, struct bmi2_dev *dev); +static void invert_gyro_offset(struct bmi2_sens_axes_data *offset_data); /*! - * @brief This internal API gets wrist gesture configurations like wearable-arm, - * and output-configuration for wearable variant. - * - * @param[out] config : Structure instance of bmi2_wrist_gest_config. - * @param[in, out] dev : Structure instance of bmi2_dev. + * @brief This internal API restores the gyroscope configurations saved + * before performing FOC. * - * @verbatim - *----------------------------------------------------------------------------- - * bmi2_wrist_gest_config | - * Structure parameters | Description - *--------------------------|-------------------------------------------------- - * | Device in left (0) or right (1) arm. By default, - * wear_arm | the wearable device is assumed to be in left arm - * | i.e. default value is 0. - * -------------------------|--------------------------------------------------- - * | Enable bits for enabling output into the - * out_conf | register status bits and, if desired, onto the - * | interrupt pin. - * -------------------------|--------------------------------------------------- - * @endverbatim + * @param[in] gyr_cfg : Gyroscope configuration value + * @param[in] gyr_en : Gyroscope enable value + * @param[in] aps : Advance power mode value + * @param[in] dev : Structure instance of bmi2_dev * * @return Result of API execution status - * - * @retval BMI2_OK - Success. - * @retval BMI2_E_COM_FAIL - Error: Communication fail - * @retval BMI2_E_INVALID_SENSOR - Error: Invalid sensor - * @retval BMI2_E_INVALID_PAGE - Error: Invalid Page + * @retval 0 -> Success + * @retval < 0 -> Fail */ -static int8_t get_wrist_gest_w_config(struct bmi2_wrist_gest_w_config *config, struct bmi2_dev *dev); +static int8_t restore_gyro_config(struct bmi2_gyro_config *gyr_cfg, uint8_t aps, uint8_t gyr_en, struct bmi2_dev *dev); /*! - * @brief This internal API gets wrist wear wake-up configurations like - * output-configuration for wearable variant. + * @brief This internal API saturates the gyroscope data value before writing to + * to 10 bit offset register. * - * @param[out] config : Structure instance of - * bmi2_wrist_wear_wake_up_config. - * @param[in, out] dev : Structure instance of bmi2_dev. + * @param[in, out] gyr_off : Gyroscope data to be stored in offset register * - * @verbatim - *----------------------------------------------------------------------------- - * bmi2_wrist_wear_wake_up_config | - * Structure parameters | Description - *----------------------------------|------------------------------------------- - * | Enable bits for enabling output into the - * out_conf | register status bits and, if desired, onto - * | the interrupt pin. - * ---------------------------------|------------------------------------------- - * @endverbatim + * @return None + * @retval None + */ +static void saturate_gyro_data(struct bmi2_sens_axes_data *gyr_off); + +/*! + * @brief This internal API reads the gyroscope data for x, y and z axis from + * the sensor. * - * @return Result of API execution status + * @param[out] gyro : Buffer to store the gyroscope value. + * @param[in] dev : Structure instance of bmi2_dev. * - * @retval BMI2_OK - Success. - * @retval BMI2_E_COM_FAIL - Error: Communication fail - * @retval BMI2_E_INVALID_SENSOR - Error: Invalid sensor - * @retval BMI2_E_INVALID_PAGE - Error: Invalid Page + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail */ -static int8_t get_wrist_wear_wake_up_wh_config(struct bmi2_wrist_wear_wake_up_wh_config *config, struct bmi2_dev *dev); +static int8_t read_gyro_xyz(struct bmi2_sens_axes_data *gyro, struct bmi2_dev *dev); /*! - * @brief This internal API gets orientation configurations like upside/down - * detection, symmetrical modes, blocking mode, theta, hysteresis and output - * configuration. - * - * @param[out] config : Structure instance of bmi2_orient_config. - * @param[in, out] dev : Structure instance of bmi2_dev. + * @brief This internal API is used to check the boundary conditions. * - * @verbatim - *----------------------------------------------------------------------------- - * bmi2_orient_config | - * Structure parameters | Description - *--------------------------|-------------------------------------------------- - * upside/down | Enables upside/down detection, if set to 1. - * detection | - * -------------------------|--------------------------------------------------- - * | Sets the mode: - * mode | Values 0 or 3 - symmetrical. - * | Value 1 - high asymmetrical - * | Value 2 - low asymmetrical - * -------------------------|--------------------------------------------------- - * | Enable - no orientation interrupt will be set. - * blocking | Default value: 3, the most restrictive blocking. - * -------------------------|--------------------------------------------------- - * | Threshold angle used in blocking mode. - * theta | Theta = 64 * (tan(angle)^2) - * | Default value: 40, equivalent to 38 degrees angle. - * -------------------------|--------------------------------------------------- - * | Acceleration hysteresis for Orientation detection - * | is expressed in 5.11g format. - * hysteresis | Default value is 128 = 0.0625g. - * | Range is 0 to 1g. - * -------------------------|--------------------------------------------------- - * | Enable bits for enabling output into the - * out_conf | register status bits and, if desired, onto the - * | interrupt pin. - * -------------------------|--------------------------------------------------- - * @endverbatim + * @param[in] dev : Structure instance of bmi2_dev. + * @param[in,out] val : Pointer to the value to be validated. + * @param[in] min : minimum value. + * @param[in] max : maximum value. * * @return Result of API execution status - * - * @retval BMI2_OK - Success. - * @retval BMI2_E_COM_FAIL - Error: Communication fail - * @retval BMI2_E_INVALID_SENSOR - Error: Invalid sensor - * @retval BMI2_E_INVALID_PAGE - Error: Invalid Page + * @retval 0 -> Success + * @retval < 0 -> Fail */ -static int8_t get_orient_config(struct bmi2_orient_config *config, struct bmi2_dev *dev); +static int8_t check_boundary_val(uint8_t *val, uint8_t min, uint8_t max, struct bmi2_dev *dev); /*! - * @brief This internal API gets high-g configurations like threshold, - * hysteresis, duration, and output configuration. - * - * @param[out] config : Structure instance of bmi2_high_g_config. - * @param[in, out] dev : Structure instance of bmi2_dev. + * @brief This internal API is used to validate the device pointer for + * null conditions. * - * @verbatim - *----------------------------------------------------------------------------- - * bmi2_high_g_config | - * Structure parameter | Description - *--------------------------|-------------------------------------------------- - * threshold | The acceleration threshold above which the - * | high_g motion is signaled. - * | Holds threshold in 5.11 g format. - * | Default is 3072 = 1.5 g. - * | Range is 0 to 16g. - * -------------------------|--------------------------------------------------- - * | Acceleration hysteresis for high-g detection - * | is expressed in 1.11g format. - * hysteresis | Default value is 256 = 0.125 g. - * | Range is 0 to 2g. - * | Should be smaller than threshold. - * -------------------------|--------------------------------------------------- - * | Holds the duration in 200 Hz samples (5 ms) for - * | which the threshold has to be exceeded. - * duration |Default value 4 = 20 msec. - * | Range is 0 to 20sec. - * -------------------------|--------------------------------------------------- - * x_sel, y_sel, z_sel | Selects the feature on a per-axis basis - * -------------------------|--------------------------------------------------- - * | Enable bits for enabling output into the - * out_conf | register status bits and, if desired, onto the - * | interrupt pin. - * -------------------------|--------------------------------------------------- - * @endverbatim + * @param[in] dev : Structure instance of bmi2_dev. * * @return Result of API execution status - * - * @retval BMI2_OK - Success. - * @retval BMI2_E_COM_FAIL - Error: Communication fail - * @retval BMI2_E_INVALID_SENSOR - Error: Invalid sensor - * @retval BMI2_E_INVALID_PAGE - Error: Invalid Page + * @retval 0 -> Success + * @retval < 0 -> Fail */ -static int8_t get_high_g_config(struct bmi2_high_g_config *config, struct bmi2_dev *dev); +static int8_t null_ptr_check(const struct bmi2_dev *dev); /*! - * @brief This internal API gets low-g configurations like threshold, - * hysteresis, duration, and output configuration. + * @brief This updates the result for CRT or gyro self-test. * - * @param[out] config : Structure instance of bmi2_low_g_config. - * @param[in, out] dev : Structure instance of bmi2_dev. - * - * @verbatim - * bmi2_low_g_config | - * Structure parameters | Description - *--------------------------|-------------------------------------------------- - * threshold | The acceleration threshold above which the - * | low-g motion is signaled. - * | Holds threshold in 5.11 g format. - * | Default is 3072 = 1.5 g. - * -------------------------|--------------------------------------------------- - * | Acceleration hysteresis for low-g detection - * hysteresis | is expressed in 1.11g format. - * | Default value is 512 = 0.250 g. - * | Should be smaller than threshold. - * -------------------------|--------------------------------------------------- - * | Holds the duration in 50 Hz samples (20 ms) for - * | which the threshold has to be exceeded. - * duration | Default value 0 = 1 validation sample = (0+1)*20 - * | = 20 ms. - * -------------------------|--------------------------------------------------- - * | Enable bits for enabling output into the - * out_conf | register status bits and, if desired, onto the - * | interrupt pin. - * -------------------------|--------------------------------------------------- - * @endverbatim + * @param[in] dev : Structure instance of bmi2_dev. * * @return Result of API execution status - * - * @retval BMI2_OK - Success. - * @retval BMI2_E_COM_FAIL - Error: Communication fail - * @retval BMI2_E_INVALID_SENSOR - Error: Invalid sensor - * @retval BMI2_E_INVALID_PAGE - Error: Invalid Page + * @retval 0 -> Success + * @retval < 0 -> Fail */ -static int8_t get_low_g_config(struct bmi2_low_g_config *config, struct bmi2_dev *dev); +static int8_t crt_gyro_st_update_result(struct bmi2_dev *dev); /*! - * @brief This internal API gets flat configurations like theta, blocking, - * hold-time, hysteresis, and output configuration. - * - * @param[out] config : Structure instance of bmi2_flat_config. - * @param[in, out] dev : Structure instance of bmi2_dev. + * @brief This function is to get the st_status status. * - * @verbatim - *---------------------------------------------------------------------------- - * bmi2_flat_config | - * Structure parameters| Description - *--------------------------|-------------------------------------------------- - * | Theta angle, used for detecting flat - * | position. - * theta | Theta = 64 * (tan(angle)^2); - * | Default value is 8, equivalent to 20 degrees angle - * -------------------------|--------------------------------------------------- - * | Hysteresis for Theta Flat detection. - * hysteresis | Default value is 9 = 2.5 degrees, corresponding - * | to the default Theta angle of 20 degrees. - * -------------------------|--------------------------------------------------- - * | Sets the blocking mode. If blocking is set, no - * | Flat interrupt will be triggered. - * blocking | Default value is 2, the most restrictive blocking - * | mode. - * -------------------------|--------------------------------------------------- - * | Holds the duration in 50Hz samples for which the - * | condition has to be respected. - * hold-time | Default value is 32 = 640 m-sec. - * | Range is 0 to 5.1 sec. - * -------------------------|--------------------------------------------------- - * | Enable bits for enabling output into the - * out_conf | register status bits and, if desired, onto the - * | interrupt pin. - * -------------------------|--------------------------------------------------- - * @endverbatim + * @param[in] *st_status: gets the crt running status + * @param[in] dev : Structure instance of bmi2_dev * * @return Result of API execution status - * - * @retval BMI2_OK - Success. - * @retval BMI2_E_COM_FAIL - Error: Communication fail - * @retval BMI2_E_INVALID_SENSOR - Error: Invalid sensor - * @retval BMI2_E_INVALID_PAGE - Error: Invalid Page + * @retval 0 -> Success + * @retval < 0 -> Fail */ -static int8_t get_flat_config(struct bmi2_flat_config *config, struct bmi2_dev *dev); +static int8_t get_st_running(uint8_t *st_status, struct bmi2_dev *dev); /*! - * @brief This internal API gets external sensor sync configurations like output - * configuration. - * - * @param[out] config : Structure instance of bmi2_ext_sens_sync_config. - * @param[in, out] dev : Structure instance of bmi2_dev. + * @brief This function is to set crt bit to running. * - * @verbatim - *---------------------------------------------------------------------------- - * bmi2_ext_sens_sync_config | - * Structure parameters | Description - * -----------------------------|---------------------------------------------- - * |Enable bits for enabling output into the - * out_conf |register status bits and, if desired, onto the - * |interrupt pin. - * -----------------------------|---------------------------------------------- - * @endverbatim + * @param[in] enable + * @param[in] dev : Structure instance of bmi2_dev * * @return Result of API execution status - * - * @retval BMI2_OK - Success. - * @retval BMI2_E_COM_FAIL - Error: Communication fail - * @retval BMI2_E_INVALID_SENSOR - Error: Invalid sensor - * @retval BMI2_E_INVALID_PAGE - Error: Invalid Page + * @retval 0 -> Success + * @retval < 0 -> Fail */ -static int8_t get_ext_sens_sync_config(struct bmi2_ext_sens_sync_config *config, struct bmi2_dev *dev); +static int8_t set_st_running(uint8_t st_status, struct bmi2_dev *dev); /*! - * @brief This internal API gets the accelerometer data from the register. + * @brief This function is to make the initial changes for CRT. + * Disable the gyro, OIS, aps + * Note: For the purpose of preparing CRT Gyro, OIS and APS are disabled * - * @param[out] data : Structure instance of sensor_data. - * @param[in] reg_addr : Register address where data is stored. - * @param[in] dev : Structure instance of bmi2_dev. + * @param[in] dev : Structure instance of bmi2_dev * * @return Result of API execution status - * - * @retval BMI2_OK - Success. - * @retval BMI2_E_COM_FAIL - Error: Communication fail + * @retval 0 -> Success + * @retval < 0 -> Fail */ -static int8_t get_accel_sensor_data(struct bmi2_sens_axes_data *data, uint8_t reg_addr, struct bmi2_dev *dev); +static int8_t crt_prepare_setup(struct bmi2_dev *dev); + +static int8_t do_gtrigger_test(uint8_t gyro_st_crt, struct bmi2_dev *dev); /*! - * @brief This internal API gets the gyroscope data from the register. + * @brief This function is to get the rdy for dl bit status + * this will toggle from 0 to 1 and visevers according to the + * dowload status * - * @param[out] data : Structure instance of sensor_data. - * @param[in] reg_addr : Register address where data is stored. - * @param[in] dev : Structure instance of bmi2_dev. + * @param[in] *rdy_for_dl: gets the rdy_for_dl status + * @param[in] dev : Structure instance of bmi2_dev * * @return Result of API execution status - * - * @retval BMI2_OK - Success. - * @retval BMI2_E_COM_FAIL - Error: Communication fail + * @retval 0 -> Success + * @retval < 0 -> Fail */ -static int8_t get_gyro_sensor_data(struct bmi2_sens_axes_data *data, uint8_t reg_addr, struct bmi2_dev *dev); +static int8_t get_rdy_for_dl(uint8_t *rdy_for_dl, struct bmi2_dev *dev); /*! - * @brief This internal API gets the accelerometer/gyroscope data. - * - * @param[out] data : Structure instance of sensor_data. - * @param[in] reg_data : Data stored in the register. + * @brief This function is to write the config file in the given location for crt. + * which inter checks the status of the rdy_for_dl bit and also the crt running, and + * wirtes the given size. * - * @return None + * @param[in] write_len: length of the words to be written + * @param[in] config_file_size: length of the words to be written + * @param[in] start_index: provide the start index from where config file has to written + * @param[in] dev : Structure instance of bmi2_dev * - * @retval None + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail */ -static void get_acc_gyr_data(struct bmi2_sens_axes_data *data, const uint8_t *reg_data); +static int8_t write_crt_config_file(uint16_t write_len, + uint16_t config_file_size, + uint16_t start_index, + struct bmi2_dev *dev); /*! - * @brief This internal API gets the re-mapped accelerometer/gyroscope data. - * - * @param[out] data : Structure instance of sensor_data. - * @param[in] dev : Structure instance of bmi2_dev. + * @brief This function is to check for rdy_for_dl bit to toggle for CRT process * - * @return None + * @param[in] retry_complete: wait for given time to toggle + * @param[in] download_ready: get the status for rdy_for_dl + * @param[in] dev : Structure instance of bmi2_dev * - * @retval None + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail */ -static void get_remapped_data(struct bmi2_sens_axes_data *data, const struct bmi2_dev *dev); +static int8_t wait_rdy_for_dl_toggle(uint8_t retry_complete, uint8_t download_ready, struct bmi2_dev *dev); /*! - * @brief This internal API reads the user-defined bytes of data from the given - * register address of auxiliary sensor in data mode. + * @brief This function is to wait till the CRT or gyro self-test process is completed * - * @param[out] aux_data : Pointer to the stored auxiliary data. - * @param[in] dev : Structure instance of bmi2_dev. + * @param[in] retry_complete: wait for given time to complete the crt process + * @param[in] dev : Structure instance of bmi2_dev * * @return Result of API execution status - * - * @retval BMI2_OK - Success. - * @retval BMI2_E_COM_FAIL - Error: Communication fail - * @retval BMI2_E_AUX_INVALID_CFG - Error: Invalid auxiliary configuration + * @retval 0 -> Success + * @retval < 0 -> Fail */ -static int8_t read_aux_data_mode(uint8_t *aux_data, struct bmi2_dev *dev); +static int8_t wait_st_running(uint8_t retry_complete, struct bmi2_dev *dev); /*! - * @brief This internal API reads the user-defined bytes of data from the given - * register address of auxiliary sensor in manual mode. + * @brief This function is to complete the crt process if max burst length is not zero + * this checks for the crt status and rdy_for_dl bit to toggle * - * @param[in] reg_addr : AUX address from where data is read. - * @param[out] aux_data : Pointer to the stored auxiliary data. - * @param[in] len : Total bytes to be read. - * @param[in] burst_len : Bytes of data to be read in bursts. - * @param[in] dev : Structure instance of bmi2_dev. + * @param[in] last_byte_flag: to provide the last toggled state + * @param[in] dev : Structure instance of bmi2_dev * * @return Result of API execution status - * - * @retval BMI2_OK - Success. - * @retval BMI2_E_COM_FAIL - Error: Communication fail - * @retval BMI2_E_AUX_BUSY - Error: Auxiliary sensor is busy + * @retval 0 -> Success + * @retval < 0 -> Fail */ -static int8_t read_aux_data(uint8_t reg_addr, uint8_t *aux_data, uint16_t len, uint8_t burst_len, struct bmi2_dev *dev); +static int8_t process_crt_download(uint8_t last_byte_flag, struct bmi2_dev *dev); /*! - * @brief This internal API checks the busy status of auxiliary sensor and sets - * the auxiliary register addresses when not busy. + * @brief This api is used to enable the gyro self-test or crt. * - * @param[in] reg_addr : Address in which AUX register address is - * set. - * @param[in] reg_data : Auxiliary register address to be set when AUX is - * not busy. - * @param[in] dev : Structure instance of bmi2_dev. + * @param[in] dev : Structure instance of bmi2_dev. * * @return Result of API execution status - * - * @retval BMI2_OK - Success. - * @retval BMI2_E_COM_FAIL - Error: Communication fail - * @retval BMI2_E_AUX_BUSY - Error: Auxiliary sensor is busy + * @retval 0 -> Success + * @retval < 0 -> Fail */ -static int8_t set_if_aux_not_busy(uint8_t reg_addr, uint8_t reg_data, struct bmi2_dev *dev); +static int8_t select_self_test(uint8_t gyro_st_crt, struct bmi2_dev *dev); /*! - * @brief his internal API maps the actual burst read length with that of the - * register value set by user. + * @brief This api is used to enable/disable abort. * - * @param[out] len : Actual burst length. - * @param[in] dev : Structure instance of bmi2_dev. + * @param[in] abort_enable : variable to enable the abort feature. + * @param[in] dev : Structure instance of bmi2_dev. * * @return Result of API execution status - * - * @retval BMI2_OK - Success. - * @retval BMI2_E_AUX_INVALID_CFG - Error: Invalid auxiliary configuration + * @retval 0 -> Success + * @retval < 0 -> Fail */ -static int8_t map_read_len(uint8_t *len, const struct bmi2_dev *dev); +static int8_t abort_bmi2(uint8_t abort_enable, struct bmi2_dev *dev); /*! - * @brief This internal API writes AUX write address and the user-defined bytes - * of data to the AUX sensor in manual mode. - * - * @note Change of BMI2_AUX_WR_ADDR is only allowed if AUX is not busy. - * - * @param[in] reg_addr : AUX address in which data is to be written. - * @param[in] reg_data : Data to be written - * @param[in] dev : Structure instance of bmi2_dev. + * @brief This api is use to wait till gyro self-test is completed and update the status of gyro + * self-test. * - * @note Change of BMI2_AUX_WR_ADDR is only allowed if AUX is not busy. + * @param[in] dev : Structure instance of bmi2_dev. * * @return Result of API execution status - * - * @retval BMI2_OK - Success. - * @retval BMI2_E_COM_FAIL - Error: Communication fail - * @retval BMI2_E_AUX_BUSY - Error: Auxiliary sensor is busy + * @retval 0 -> Success + * @retval < 0 -> Fail */ -static int8_t write_aux_data(uint8_t reg_addr, uint8_t reg_data, struct bmi2_dev *dev); +static int8_t gyro_self_test_completed(struct bmi2_gyro_self_test_status *gyro_st_result, struct bmi2_dev *dev); /*! - * @brief This internal API gets the output values of step counter. + * @brief This api is used to trigger the preparation for system for NVM programming. * - * @param[out] step_count : Pointer to the stored step counter data. - * @param[in] dev : Structure instance of bmi2_dev. + * @param[out] nvm_prep : pointer to variable to store the status of nvm_prep_prog. + * @param[in] dev : Structure instance of bmi2_dev. * * @return Result of API execution status - * - * @retval BMI2_OK - Success. - * @retval BMI2_E_COM_FAIL - Error: Communication fail - * @retval BMI2_E_INVALID_SENSOR - Error: Invalid sensor - * @retval BMI2_E_INVALID_PAGE - Error: Invalid Page + * @retval 0 -> Success + * @retval < 0 -> Fail */ -static int8_t get_step_counter_output(uint32_t *step_count, struct bmi2_dev *dev); +static int8_t set_nvm_prep_prog(uint8_t nvm_prep, struct bmi2_dev *dev); /*! - * @brief This internal API gets the output values of step activity. - * - * @param[out] step_act : Pointer to the stored step activity data. - * @param[in] dev : Structure instance of bmi2_dev. + * @brief This api validates accel foc position as per the range * - * *step_act | Output - * -----------|------------ - * 0x00 | STILL - * 0x01 | WALKING - * 0x02 | RUNNING - * 0x03 | UNKNOWN + * @param[in] sens_list : Sensor type + * @param[in] accel_g_axis : accel axis to foc. NA for gyro foc + * @param[in] avg_foc_data : average value of sensor sample datas + * @param[in] dev : Structure instance of bmi2_dev. * * @return Result of API execution status - * - * @retval BMI2_OK - Success. - * @retval BMI2_E_COM_FAIL - Error: Communication fail - * @retval BMI2_E_INVALID_SENSOR - Error: Invalid sensor - * @retval BMI2_E_INVALID_PAGE - Error: Invalid Page + * @retval 0 -> Success + * @retval < 0 -> Fail */ -static int8_t get_step_activity_output(uint8_t *step_act, struct bmi2_dev *dev); +static int8_t validate_foc_position(uint8_t sens_list, + const struct bmi2_accel_foc_g_value *accel_g_axis, + struct bmi2_sens_axes_data avg_foc_data, + struct bmi2_dev *dev); /*! - * @brief This internal API gets the output values of orientation: portrait- - * landscape and face up-down. - * - * @param[out] orient_out : Structure pointer to the orientation data. - * @param[in] dev : Structure instance of bmi2_dev. - * - * - * portrait | - * landscape | Output - * -----------|------------ - * 0x00 | PORTRAIT UPRIGHT - * 0x01 | LANDSCAPE LEFT - * 0x02 | PORTRAIT UPSIDE DOWN - * 0x03 | LANDSCAPE RIGHT + * @brief This api validates accel foc axis given as input * - * Face | - * up-down | Output - * -----------|------------ - * 0x00 | FACE-UP - * 0x01 | FACE-DOWN + * @param[in] avg_foc_data : average value of sensor sample datas + * @param[in] dev : Structure instance of bmi2_dev. * * @return Result of API execution status - * - * @retval BMI2_OK - Success. - * @retval BMI2_E_COM_FAIL - Error: Communication fail - * @retval BMI2_E_INVALID_SENSOR - Error: Invalid sensor - * @retval BMI2_E_INVALID_PAGE - Error: Invalid Page + * @retval 0 -> Success + * @retval < 0 -> Fail */ -static int8_t get_orient_output(struct bmi2_orientation_output *orient_out, struct bmi2_dev *dev); +static int8_t validate_foc_accel_axis(int16_t avg_foc_data, struct bmi2_dev *dev); /*! - * @brief This internal API gets the output values of high-g. + * @brief This api is used to verify the right position of the sensor before doing accel foc * - * @param[out] high_g_out : Pointer to the stored high-g output. - * @param[in] dev : Structure instance of bmi2_dev. + * @param[in] dev : Structure instance of bmi2_dev. + * @param[in] sens_list: Sensor type + * @param[in] accel_g_axis: Accel Foc axis and sign input * * @return Result of API execution status - * - * @retval BMI2_OK - Success. - * @retval BMI2_E_COM_FAIL - Error: Communication fail - * @retval BMI2_E_INVALID_SENSOR - Error: Invalid sensor - * @retval BMI2_E_INVALID_PAGE - Error: Invalid Page + * @retval 0 -> Success + * @retval < 0 -> Fail */ -static int8_t get_high_g_output(uint8_t *high_g_out, struct bmi2_dev *dev); +static int8_t verify_foc_position(uint8_t sens_list, + const struct bmi2_accel_foc_g_value *accel_g_axis, + struct bmi2_dev *dev); /*! - * @brief This internal API gets the output values of wrist gesture. - * - * @param[out] wrist_gest : Pointer to the stored wrist gesture. - * @param[in] dev : Structure instance of bmi2_dev. + * @brief This API reads and provides average for 128 samples of sensor data for foc operation + * gyro. * - * *wrist_gest | Output - * -------------|------------ - * 0x00 | UNKNOWN - * 0x01 | PUSH_ARM_DOWN - * 0x02 | PIVOT_UP - * 0x03 | WRIST_SHAKE_JIGGLE - * 0x04 | FLICK_IN - * 0x05 | FLICK_OUT + * @param[in] sens_list : Sensor type. + * @param[in] bmi2_dev: Structure instance of bmi2_dev. + * @param[in] temp_foc_data: to store data samples * * @return Result of API execution status - * - * @retval BMI2_OK - Success. - * @retval BMI2_E_COM_FAIL - Error: Communication fail - * @retval BMI2_E_INVALID_SENSOR - Error: Invalid sensor - * @retval BMI2_E_INVALID_PAGE - Error: Invalid Page + * @retval 0 -> Success + * @retval < 0 -> Fail */ -static int8_t get_wrist_gest_status(uint8_t *wrist_gest, struct bmi2_dev *dev); +static int8_t get_average_of_sensor_data(uint8_t sens_list, + struct bmi2_foc_temp_value *temp_foc_data, + struct bmi2_dev *dev); /*! - * @brief This internal API gets the cross sensitivity coefficient between - * gyroscope's X and Z axes. + * @brief This internal api gets major and minor version for config file * - * @param[out] cross_sense : Pointer to the stored cross sensitivity - * coefficient. - * @param[in] dev : Structure instance of bmi2_dev. + * @param[out] config_major : Pointer to store the major version + * @param[out] config_minor : Pointer to store the minor version + * @param[in] dev : Structure instance of bmi2_dev * * @return Result of API execution status - * - * @retval BMI2_OK - Success. - * @retval BMI2_E_COM_FAIL - Error: Communication fail - * @retval BMI2_E_INVALID_SENSOR - Error: Invalid sensor - * @retval BMI2_E_INVALID_PAGE - Error: Invalid Page + * @retval 0 -> Success + * @retval < 0 -> Fail */ -static int8_t get_gyro_cross_sense(int16_t *cross_sense, struct bmi2_dev *dev); +static int8_t extract_config_file(uint8_t *config_major, uint8_t *config_minor, struct bmi2_dev *dev); /*! - * @brief This internal API gets the saturation status for the gyroscope user - * gain update. - * - * @param[out] user_gain_stat : Stores the saturation status of the axes. - * @param[in] dev : Structure instance of bmi2_dev. + * @brief This internal API is used to map the interrupts to the sensor. * - * @return Result of API execution status + * @param[in] map_int : Structure instance of bmi2_map_int. + * @param[in] type : Type of feature or sensor. + * @param[in] dev : Structure instance of bmi2_dev. * - * @retval BMI2_OK - Success. - * @retval BMI2_E_COM_FAIL - Error: Communication fail - * @retval BMI2_E_INVALID_SENSOR - Error: Invalid sensor - * @retval BMI2_E_INVALID_PAGE - Error: Invalid Page + * @return None + * @retval None */ -static int8_t get_gyro_gain_update_status(struct bmi2_gyr_user_gain_status *user_gain, struct bmi2_dev *dev); +static void extract_feat_int_map(struct bmi2_map_int *map_int, uint8_t type, const struct bmi2_dev *dev); /*! - * @brief This internal API gets the error status related to NVM. + * @brief This internal API selects the sensors/features to be enabled or + * disabled. * - * @param[out] nvm_err_stat : Stores the NVM error status. - * @param[in] dev : Structure instance of bmi2_dev. + * @param[in] sens_list : Pointer to select the sensor. + * @param[in] n_sens : Number of sensors selected. + * @param[out] sensor_sel : Gets the selected sensor. * * @return Result of API execution status - * - * @retval BMI2_OK - Success. - * @retval BMI2_E_COM_FAIL - Error: Communication fail - * @retval BMI2_E_INVALID_SENSOR - Error: Invalid sensor - * @retval BMI2_E_INVALID_PAGE - Error: Invalid Page + * @retval 0 -> Success + * @retval < 0 -> Fail */ -static int8_t get_nvm_error_status(struct bmi2_nvm_err_status *nvm_err_stat, struct bmi2_dev *dev); +static int8_t select_sensor(const uint8_t *sens_list, uint8_t n_sens, uint64_t *sensor_sel); /*! - * @brief This internal API gets the error status related to virtual frames. + * @brief This internal API enables the selected sensor/features. * - * @param[out] vfrm_err_stat : Stores the VFRM related error status. - * @param[in] dev : Structure instance of bmi2_dev. + * @param[in] sensor_sel : Selects the desired sensor. + * @param[in, out] dev : Structure instance of bmi2_dev. * * @return Result of API execution status - * - * @retval BMI2_OK - Success. - * @retval BMI2_E_COM_FAIL - Error: Communication fail - * @retval BMI2_E_INVALID_SENSOR - Error: Invalid sensor - * @retval BMI2_E_INVALID_PAGE - Error: Invalid Page + * @retval 0 -> Success + * @retval < 0 -> Fail */ -static int8_t get_vfrm_error_status(struct bmi2_vfrm_err_status *vfrm_err_stat, struct bmi2_dev *dev); +static int8_t sensor_enable(uint64_t sensor_sel, struct bmi2_dev *dev); /*! - * @brief This internal API is used to parse and store the activity recognition - * output from the FIFO data. + * @brief This internal API disables the selected sensor/features. * - * @param[out] act_recog : Structure to retrieve output of activity - * recognition frame. - * @param[in] data_index : Index of the FIFO data which contains - * activity recognition frame. - * @param[out] fifo : Structure instance of bmi2_dev. + * @param[in] sensor_sel : Selects the desired sensor. + * @param[in, out] dev : Structure instance of bmi2_dev. * * @return Result of API execution status - * - * @retval BMI2_OK - Success. - * @retval BMI2_W_FIFO_EMPTY - Warning : FIFO is empty - * @retval BMI2_W_PARTIAL_READ - Warning : There are more frames to be read - */ -static int8_t unpack_act_recog_output(struct bmi2_act_recog_output *act_recog, - uint16_t *data_index, - const struct bmi2_fifo_frame *fifo); - -/*! - * @brief This internal API is used to get enable status of gyroscope user gain - * update. - * - * @param[out] status : Stores status of gyroscope user gain update. - * @param[in] dev : Structure instance of bmi2_dev. - * - * @return Result of API execution status - * - * @retval BMI2_OK - Success. - * @retval BMI2_E_COM_FAIL - Error: Communication fail - * @retval BMI2_E_INVALID_SENSOR - Error: Invalid sensor - * @retval BMI2_E_INVALID_PAGE - Error: Invalid Page - */ -static int8_t get_user_gain_upd_status(uint8_t *status, struct bmi2_dev *dev); - -/*! - * @brief This internal API gets the accelerometer self-test status. - * - * @param[out] acc_self_test_stat : Stores status of accelerometer self- - * test. - * @param[in] dev : Structure instance of bmi2_dev. - * - * @return Result of API execution status - * - * @retval BMI2_OK - Success. - * @retval BMI2_E_COM_FAIL - Error: Communication fail - * @retval BMI2_E_INVALID_SENSOR - Error: Invalid sensor - * @retval BMI2_E_INVALID_PAGE - Error: Invalid Page - */ -static int8_t get_accel_self_test_status(struct bmi2_acc_self_test_status *acc_self_test_stat, struct bmi2_dev *dev); - -/*! - * @brief This internal API maps/unmaps feature interrupts to that of interrupt - * pins. - * - * @param[in] int_pin : Interrupt pin selected. - * @param[in] feat_int : Type of feature interrupt to be mapped or the value - * of out_conf. - * @param[in] dev : Structure instance of bmi2_dev. - * - * @return Result of API execution status - * - * @retval BMI2_OK - Success. - * @retval BMI2_E_NULL_PTR - Error: Null pointer error - * @retval BMI2_E_COM_FAIL - Error: Communication fail - * @retval BMI2_E_INVALID_FEAT_BIT - Error: Invalid feature Interrupt - */ -static int8_t map_feat_int(uint8_t *reg_data_array, enum bmi2_hw_int_pin int_pin, uint8_t int_mask); - -/*! - * @brief This internal API computes the number of bytes of accelerometer FIFO - * data which is to be parsed in header-less mode. - * - * @param[out] start_idx : The start index for parsing data. - * @param[out] len : Number of bytes to be parsed. - * @param[in] acc_count : Number of accelerometer frames to be read. - * @param[in] fifo : Structure instance of bmi2_fifo_frame. - * - * @return Result of API execution status - * - * @retval BMI2_OK - Success. - * @retval BMI2_W_FIFO_EMPTY - Warning : FIFO is empty - */ -static int8_t parse_fifo_accel_len(uint16_t *start_idx, - uint16_t *len, - const uint16_t *acc_count, - const struct bmi2_fifo_frame *fifo); - -/*! - * @brief This internal API is used to parse accelerometer data from the FIFO - * data in header mode. - * - * @param[out] acc : Structure instance of bmi2_sens_axes_data where - * the parsed accelerometer data bytes are stored. - * @param[in] accel_length : Number of accelerometer frames (x,y,z data). - * @param[in] fifo : Structure instance of bmi2_fifo_frame. - * @param[in] dev : Structure instance of bmi2_dev. - * - * @return Result of API execution status - * - * @retval BMI2_OK - Success. - * @retval BMI2_W_FIFO_EMPTY - Warning : FIFO is empty - * @retval BMI2_W_PARTIAL_READ - Warning : There are more frames to be read - */ -static int8_t extract_accel_header_mode(struct bmi2_sens_axes_data *acc, - uint16_t *accel_length, - struct bmi2_fifo_frame *fifo, - const struct bmi2_dev *dev); - -/*! - * @brief This internal API is used to parse the accelerometer data from the - * FIFO data in both header and header-less mode. It updates the current data - * byte to be parsed. - * - * @param[in,out] acc : Structure instance of bmi2_sens_axes_data where - * where the parsed data bytes are stored. - * @param[in,out] idx : Index value of number of bytes parsed. - * @param[in,out] acc_idx : Index value of accelerometer data (x,y,z axes) - * frame to be parsed. - * @param[in] frame : Either data is enabled by user in header-less - * mode or header frame value in header mode. - * @param[in] fifo : Structure instance of bmi2_fifo_frame. - * @param[in] dev : Structure instance of bmi2_dev. - * - * @return Result of API execution status - * - * @retval BMI2_OK - Success. - * @retval BMI2_W_FIFO_EMPTY - Warning : FIFO is empty - * @retval BMI2_W_PARTIAL_READ - Warning : There are more frames to be read - */ -static int8_t unpack_accel_frame(struct bmi2_sens_axes_data *acc, - uint16_t *idx, - uint16_t *acc_idx, - uint8_t frame, - const struct bmi2_fifo_frame *fifo, - const struct bmi2_dev *dev); - -/*! - * @brief This internal API is used to parse accelerometer data from the FIFO - * data. - * - * @param[out] acc : Structure instance of bmi2_sens_axes_data - * where the parsed data bytes are stored. - * @param[in] data_start_index : Index value of the accelerometer data bytes - * which is to be parsed from the FIFO data. - * @param[in] fifo : Structure instance of bmi2_fifo_frame. - * @param[in] dev : Structure instance of bmi2_dev. - * - * @return None - * @retval None - */ -static void unpack_accel_data(struct bmi2_sens_axes_data *acc, - uint16_t data_start_index, - const struct bmi2_fifo_frame *fifo, - const struct bmi2_dev *dev); - -/*! - * @brief This internal API computes the number of bytes of gyroscope FIFO data - * which is to be parsed in header-less mode. - * - * @param[out] start_idx : The start index for parsing data. - * @param[out] len : Number of bytes to be parsed. - * @param[in] gyr_count : Number of gyroscope frames to be read. - * @param[in] frame : Either data enabled by user in header-less - * mode or header frame value in header mode. - * @param[in] fifo : Structure instance of bmi2_fifo_frame. - * - * @return Result of API execution status - * - * @retval BMI2_OK - Success. - * @retval BMI2_W_FIFO_EMPTY - Warning : FIFO is empty - */ -static int8_t parse_fifo_gyro_len(uint16_t *start_idx, - uint16_t(*len), - const uint16_t *gyr_count, - const struct bmi2_fifo_frame *fifo); - -/*! - * @brief This internal API is used to parse the gyroscope data from the FIFO - * data in both header and header-less mode It updates the current data byte to - * be parsed. - * - * @param[in,out] gyr : Structure instance of bmi2_sens_axes_data. - * @param[in,out] idx : Index value of number of bytes parsed - * @param[in,out] gyr_idx : Index value of gyroscope data (x,y,z axes) - * frame to be parsed. - * @param[in] frame : Either data is enabled by user in header-less - * mode or header frame value in header mode. - * @param[in] fifo : Structure instance of bmi2_fifo_frame. - * @param[in] dev : Structure instance of bmi2_dev. - * - * @return Result of API execution status - * - * @retval BMI2_OK - Success. - * @retval BMI2_W_FIFO_EMPTY - Warning : FIFO is empty - * @retval BMI2_W_PARTIAL_READ - Warning : There are more frames to be read - */ -static int8_t unpack_gyro_frame(struct bmi2_sens_axes_data *gyr, - uint16_t *idx, - uint16_t *gyr_idx, - uint8_t frame, - const struct bmi2_fifo_frame *fifo, - const struct bmi2_dev *dev); - -/*! - * @brief This internal API is used to parse gyroscope data from the FIFO data. - * - * @param[out] gyr : Structure instance of bmi2_sens_axes_data where - * the parsed gyroscope data bytes are stored. - * @param[in] data_start_index : Index value of the gyroscope data bytes - * which is to be parsed from the FIFO data. - * @param[in] fifo : Structure instance of bmi2_fifo_frame. - * @param[in] dev : Structure instance of bmi2_dev. - * - * @return None - * @retval None - */ -static void unpack_gyro_data(struct bmi2_sens_axes_data *gyr, - uint16_t data_start_index, - const struct bmi2_fifo_frame *fifo, - const struct bmi2_dev *dev); - -/*! - * @brief This internal API is used to parse the gyroscope data from the - * FIFO data in header mode. - * - * @param[out] gyr : Structure instance of bmi2_sens_axes_data where - * the parsed gyroscope data bytes are stored. - * @param[in] gyro_length : Number of gyroscope frames (x,y,z data). - * @param[in] fifo : Structure instance of bmi2_fifo_frame. - * @param[in] dev : Structure instance of bmi2_dev. - * - * @return Result of API execution status - * - * @retval BMI2_OK - Success. - * @retval BMI2_W_FIFO_EMPTY - Warning : FIFO is empty - * @retval BMI2_W_PARTIAL_READ - Warning : There are more frames to be read - */ -static int8_t extract_gyro_header_mode(struct bmi2_sens_axes_data *gyr, - uint16_t *gyro_length, - struct bmi2_fifo_frame *fifo, - const struct bmi2_dev *dev); - -/*! - * @brief This API computes the number of bytes of auxiliary FIFO data - * which is to be parsed in header-less mode. - * - * @param[out] start_idx : The start index for parsing data. - * @param[out] len : Number of bytes to be parsed. - * @param[in] aux_count : Number of accelerometer frames to be read. - * @param[in] fifo : Structure instance of bmi2_fifo_frame. - * - * - * @return Result of API execution status - * - * @retval BMI2_OK - Success. - * @retval BMI2_W_FIFO_EMPTY - Warning : FIFO is empty - */ -static int8_t parse_fifo_aux_len(uint16_t *start_idx, - uint16_t(*len), - const uint16_t *aux_count, - const struct bmi2_fifo_frame *fifo); - -/*! - * @brief This API is used to parse auxiliary data from the FIFO data. - * - * @param[out] aux : Pointer to buffer where the parsed auxiliary data - * bytes are stored. - * @param[in] aux_length : Number of auxiliary frames (x,y,z data). - * @param[in] fifo : Structure instance of bmi2_fifo_frame. - * @param[in] dev : Structure instance of bmi2_dev. - * - * @return Result of API execution status - * - * @retval BMI2_OK - Success. - * @retval BMI2_W_FIFO_EMPTY - Warning : FIFO is empty - * @retval BMI2_W_PARTIAL_READ - Warning : There are more frames to be read - */ -static int8_t extract_aux_header_mode(struct bmi2_aux_fifo_data *aux, - uint16_t *aux_length, - struct bmi2_fifo_frame *fifo, - const struct bmi2_dev *dev); - -/*! - * @brief This API is used to parse the auxiliary data from the FIFO data in - * both header and header-less mode. It updates the current data byte to be - * parsed. - * - * @param[out] aux : Pointer to structure where the parsed auxiliary data - * bytes are stored. - * @param[in,out] idx : Index value of number of bytes parsed - * @param[in,out] aux_idx : Index value of auxiliary data (x,y,z axes) - * frame to be parsed - * @param[in] frame : Either data is enabled by user in header-less - * mode or header frame value in header mode. - * @param[in] fifo : Structure instance of bmi2_fifo_frame. - * @param[in] dev : Structure instance of bmi2_dev. - * - * @return Result of API execution status - * - * @retval BMI2_OK - Success. - * @retval BMI2_W_FIFO_EMPTY - Warning : FIFO is empty - * @retval BMI2_W_PARTIAL_READ - Warning : There are more frames to be read - */ -static int8_t unpack_aux_frame(struct bmi2_aux_fifo_data *aux, - uint16_t *idx, - uint16_t *aux_idx, - uint8_t frame, - const struct bmi2_fifo_frame *fifo, - const struct bmi2_dev *dev); - -/*! - * @brief This API is used to parse auxiliary data from the FIFO data. - * - * @param[out] aux : Pointer to structure where the parsed - * auxiliary data bytes are stored. - * @param[in] data_start_index : Index value of the auxiliary data bytes which - * is to be parsed from the FIFO data. - * @param[in] fifo : Structure instance of bmi2_fifo_frame. - * - * @return None - * @retval None - */ -static void unpack_aux_data(struct bmi2_aux_fifo_data *aux, - uint16_t data_start_index, - const struct bmi2_fifo_frame *fifo); - -/*! - * @brief This internal API is used to reset the FIFO related configurations - * in the FIFO frame structure for the next FIFO read. - * - * @param[in, out] fifo : Structure instance of bmi2_fifo_frame. - * @param[in] dev : Structure instance of bmi2_dev. - * - * @return None - * @retval None - */ -static void reset_fifo_frame_structure(struct bmi2_fifo_frame *fifo, const struct bmi2_dev *dev); - -/*! - * @brief This internal API checks whether the FIFO data read is an empty frame. - * If empty frame, index is moved to the last byte. - * - * @param[in,out] data_index : The index of the current data to be parsed from - * FIFO data. - * @param[in] fifo : Structure instance of bmi2_fifo_frame. - * - * @return Result of API execution status - * - * @retval BMI2_OK - Success. - * @retval BMI2_W_FIFO_EMPTY - Warning : FIFO is empty - * @retval BMI2_W_PARTIAL_READ - Warning : There are more frames to be read - */ -static int8_t check_empty_fifo(uint16_t *data_index, const struct bmi2_fifo_frame *fifo); - -/*! - * @brief This internal API is used to move the data index ahead of the - * current frame length parameter when unnecessary FIFO data appears while - * extracting the user specified data. - * - * @param[in,out] data_index : Index of the FIFO data which is to be - * moved ahead of the current frame length - * @param[in] current_frame_length : Number of bytes in the current frame. - * @param[in] fifo : Structure instance of bmi2_fifo_frame. - * - * @return Result of API execution status - * - * @retval BMI2_OK - Success. - * @retval BMI2_W_FIFO_EMPTY - Warning : FIFO is empty - * @retval BMI2_W_PARTIAL_READ - Warning : There are more frames to be read - */ -static int8_t move_next_frame(uint16_t *data_index, uint8_t current_frame_length, const struct bmi2_fifo_frame *fifo); - -/*! - * @brief This internal API is used to parse and store the sensor time from the - * FIFO data. - * - * @param[in,out] data_index : Index of the FIFO data which has the sensor time. - * @param[in] fifo : Structure instance of bmi2_fifo_frame. - * - * @return Result of API execution status - * - * @retval BMI2_OK - Success. - * @retval BMI2_W_FIFO_EMPTY - Warning : FIFO is empty - * @retval BMI2_W_PARTIAL_READ - Warning : There are more frames to be read - */ -static int8_t unpack_sensortime_frame(uint16_t *data_index, struct bmi2_fifo_frame *fifo); - -/*! - * @brief This internal API is used to parse and store the skipped frame count - * from the FIFO data. - * - * @param[in,out] data_index : Index of the FIFO data which contains skipped - * frame count. - * @param[in] fifo : Structure instance of bmi2_fifo_frame. - * - * @return Result of API execution status - * - * @retval BMI2_OK - Success. - * @retval BMI2_W_FIFO_EMPTY - Warning : FIFO is empty - * @retval BMI2_W_PARTIAL_READ - Warning : There are more frames to be read - */ -static int8_t unpack_skipped_frame(uint16_t *data_index, struct bmi2_fifo_frame *fifo); - -/*! - * @brief This internal API enables and configures the accelerometer which is - * needed for self-test operation. It also sets the amplitude for the self-test. - * - * @param[in] dev : Structure instance of bmi2_dev. - * - * @return Result of API execution status - * - * @retval BMI2_OK - Success. - * @retval BMI2_E_NULL_PTR - Error: Null pointer error - * @retval BMI2_E_COM_FAIL - Error: Communication fail - * @retval BMI2_E_INVALID_SENSOR - Error: Invalid sensor - */ -static int8_t pre_self_test_config(struct bmi2_dev *dev); - -/*! - * @brief This internal API performs the steps needed for self-test operation - * before reading the accelerometer self-test data. - * - * @param[in] sign : Selects sign of self-test excitation - * @param[in] dev : Structure instance of bmi2_dev. - * - * sign | Description - * -------------|--------------- - * BMI2_ENABLE | positive excitation - * BMI2_DISABLE | negative excitation - * - * @return Result of API execution status - * - * @retval BMI2_OK - Success. - * @retval BMI2_E_COM_FAIL - Error: Communication fail - */ -static int8_t self_test_config(uint8_t sign, struct bmi2_dev *dev); - -/*! - * @brief This internal API enables or disables the accelerometer self-test - * feature in the sensor. - * - * @param[in] enable : Enables/ Disables self-test. - * @param[in] dev : Structure instance of bmi2_dev. - * - * sign | Description - * -------------|--------------- - * BMI2_ENABLE | Enables self-test - * BMI2_DISABLE | Disables self-test - * - * @return Result of API execution status - * - * @retval BMI2_OK - Success. - * @retval BMI2_E_COM_FAIL - Error: Communication fail - */ -static int8_t set_accel_self_test_enable(uint8_t enable, struct bmi2_dev *dev); - -/*! - * @brief This internal API selects the sign for accelerometer self-test - * excitation. - * - * @param[in] sign : Selects sign of self-test excitation - * @param[in] dev : Structure instance of bmi2_dev. - * - * sign | Description - * -------------|--------------- - * BMI2_ENABLE | positive excitation - * BMI2_DISABLE | negative excitation - * - * @return Result of API execution status - * - * @retval BMI2_OK - Success. - * @retval BMI2_E_COM_FAIL - Error: Communication fail - */ -static int8_t set_acc_self_test_sign(uint8_t sign, struct bmi2_dev *dev); - -/*! - * @brief This internal API sets the amplitude of the accelerometer self-test - * deflection in the sensor. - * - * @param[in] amp : Select amplitude of the self-test deflection. - * @param[in] dev : Structure instance of bmi2_dev. - * - * amp | Description - * -------------|--------------- - * BMI2_ENABLE | self-test amplitude is high - * BMI2_DISABLE | self-test amplitude is low - * - * @return Result of API execution status - * - * @retval BMI2_OK - Success. - * @retval BMI2_E_COM_FAIL - Error: Communication fail - */ -static int8_t set_accel_self_test_amp(uint8_t amp, struct bmi2_dev *dev); - -/*! - * @brief This internal API reads the accelerometer data for x,y and z axis from - * the sensor. The data units is in LSB format. - * - * @param[out] accel : Buffer to store the acceleration value. - * @param[in] dev : Structure instance of bmi2_dev. - * - * @return Result of API execution status - * - * @retval BMI2_OK - Success. - * @retval BMI2_E_COM_FAIL - Error: Communication fail - */ -static int8_t read_accel_xyz(struct bmi2_sens_axes_data *accel, struct bmi2_dev *dev); - -/*! - * @brief This internal API converts LSB value of accelerometer axes to form - * 'g' to 'mg' for self-test. - * - * @param[in] acc_data_diff : Stores the acceleration value difference in g. - * @param[out]acc_data_diff_mg : Stores the acceleration value difference in mg. - * @param[in] dev : Structure instance of bmi2_dev. - * - * @return None - * @retval None - */ -static void convert_lsb_g(const struct bmi2_selftest_delta_limit *acc_data_diff, - struct bmi2_selftest_delta_limit *acc_data_diff_mg, - const struct bmi2_dev *dev); - -/*! - * @brief This internal API is used to calculate the power of a value. - * - * @param[in] base : base for power calculation. - * @param[in] resolution : exponent for power calculation. - * - * @return the calculated power - * @retval the power value - */ -static int32_t power(int16_t base, uint8_t resolution); - -/*! - * @brief This internal API validates the accelerometer self-test data and - * decides the result of self-test operation. - * - * @param[in] accel_data_diff : Stores the acceleration value difference. - * - * @return Result of API execution status - * - * @retval BMI2_OK - Success. - * @retval BMI2_E_SELF_TEST_FAIL - Error: Self-test fail - */ -static int8_t validate_self_test(const struct bmi2_selftest_delta_limit *accel_data_diff); - -/*! - * @brief This internal API gets the re-mapped x, y and z axes from the sensor. - * - * @param[out] remap : Structure that stores local copy of re-mapped axes. - * @param[in] dev : Structure instance of bmi2_dev. - * - * @return Result of API execution status - * - * @retval BMI2_OK - Success. - * @retval BMI2_E_COM_FAIL - Error: Communication fail - * @retval BMI2_E_INVALID_SENSOR - Error: Invalid sensor - * @retval BMI2_E_INVALID_PAGE - Error: Invalid Page - */ -static int8_t get_remap_axes(struct bmi2_axes_remap *remap, struct bmi2_dev *dev); - -/*! - * @brief This internal API sets the re-mapped x, y and z axes in the sensor. - * - * @param[in] remap : Structure that stores local copy of re-mapped axes. - * @param[in] dev : Structure instance of bmi2_dev. - * - * @return Result of API execution status - * - * @retval BMI2_OK - Success. - * @retval BMI2_E_COM_FAIL - Error: Communication fail - * @retval BMI2_E_INVALID_SENSOR - Error: Invalid sensor - * @retval BMI2_E_INVALID_PAGE - Error: Invalid Page - */ -static int8_t set_remap_axes(const struct bmi2_axes_remap *remap, struct bmi2_dev *dev); - -/*! - * @brief Interface to get max burst length - * - * @param[in] max_burst_len : Pointer to store max burst length - * @param[in] dev : Structure instance of bmi2_dev. - * - * @return Result of API execution status - * - * @retval BMI2_OK - Success. - * @retval BMI2_E_COM_FAIL - Error: Communication fail - * @retval BMI2_E_INVALID_SENSOR - Error: Invalid sensor - * @retval BMI2_E_INVALID_PAGE - Error: Invalid Page - */ -static int8_t get_maxburst_len(uint8_t *max_burst_len, struct bmi2_dev *dev); - -/*! - * @brief This internal API sets the max burst length. - * - * @param[in] write_len_byte : read & write length - * @param[in] dev : Structure instance of bmi2_dev. - * - * @return Result of API execution status - * - * @retval BMI2_OK - Success. - * @retval BMI2_E_COM_FAIL - Error: Communication fail - * @retval BMI2_E_INVALID_SENSOR - Error: Invalid sensor - * @retval BMI2_E_INVALID_PAGE - Error: Invalid Page - */ -static int8_t set_maxburst_len(const uint16_t write_len_byte, struct bmi2_dev *dev); - -/*! - * @brief This internal API enables/disables compensation of the gain defined - * in the GAIN register. - * - * @param[in] enable : Enables/Disables gain compensation - * @param[in] dev : Structure instance of bmi2_dev. - * - * enable | Description - * -------------|--------------- - * BMI2_ENABLE | Enable gain compensation. - * BMI2_DISABLE | Disable gain compensation. - * - * @return Result of API execution status - * - * @retval BMI2_OK - Success. - * @retval BMI2_E_COM_FAIL - Error: Communication fail - */ -static int8_t enable_gyro_gain(uint8_t enable, struct bmi2_dev *dev); - -/*! - * @brief This internal API parses virtual frame header from the FIFO data. - * - * @param[in, out] frame_header : FIFO frame header. - * @param[in, out] data_index : Index value of the FIFO data bytes - * from which sensor frame header is to be parsed - * @param[in] fifo : Structure instance of bmi2_fifo_frame. - * - * @return None - * @retval None - */ -static void parse_if_virtual_header(uint8_t *frame_header, uint16_t *data_index, const struct bmi2_fifo_frame *fifo); - -/*! - * @brief This internal API gets sensor time from the accelerometer and - * gyroscope virtual frames and updates in the data structure. - * - * @param[out] sens : Sensor data structure - * @param[in, out] idx : Index of FIFO from where the data is to retrieved. - * @param[in] fifo : Structure instance of bmi2_fifo_frame. - * - * @return None - * @retval None - */ -static void unpack_virt_sensor_time(struct bmi2_sens_axes_data *sens, uint16_t *idx, - const struct bmi2_fifo_frame *fifo); - -/*! - * @brief This internal API gets sensor time from the auxiliary virtual - * frames and updates in the data structure. - * - * @param[out] aux : Auxiliary sensor data structure - * @param[in, out] idx : Index of FIFO from where the data is to retrieved. - * @param[in] fifo : Structure instance of bmi2_fifo_frame. - * - * @return None - * @retval None - */ -static void unpack_virt_aux_sensor_time(struct bmi2_aux_fifo_data *aux, - uint16_t *idx, - const struct bmi2_fifo_frame *fifo); - -/*! - * @brief This internal API skips S4S frame in the FIFO data while getting - * activity recognition output. - * - * @param[in, out] frame_header : FIFO frame header. - * @param[in, out] data_index : Index value of the FIFO data bytes - * from which S4S frame header is to be - * skipped. - * @param[in] fifo : Structure instance of bmi2_fifo_frame. - * - * @return Result of API execution status - * - * @retval BMI2_OK - Success. - * @retval BMI2_W_FIFO_EMPTY - Warning : FIFO is empty - * @retval BMI2_W_PARTIAL_READ - Warning : There are more frames to be read - */ -static int8_t move_if_s4s_frame(const uint8_t *frame_header, uint16_t *data_index, const struct bmi2_fifo_frame *fifo); - -/*! - * @brief This internal API corrects the gyroscope cross-axis sensitivity - * between the z and the x axis. - * - * @param[in] dev : Structure instance of bmi2_dev. - * @param[out] gyr_data : Structure instance of gyroscope data - * - * @return Result of API execution status - * - * @return None - * @retval None - */ -static void comp_gyro_cross_axis_sensitivity(struct bmi2_sens_axes_data *gyr_data, const struct bmi2_dev *dev); - -/*! - * @brief This internal API is used to extract the output feature configuration - * details like page and start address from the look-up table. - * - * @param[out] feat_output : Structure that stores output feature - * configurations. - * @param[in] type : Type of feature or sensor. - * @param[in] dev : Structure instance of bmi2_dev. - * - * @return Returns the feature found flag. - * - * @retval BMI2_FALSE : Feature not found - * BMI2_TRUE : Feature found - */ -static uint8_t extract_output_feat_config(struct bmi2_feature_config *feat_output, - uint8_t type, - const struct bmi2_dev *dev); - -/*! - * @brief This internal API saves the configurations before performing FOC. - * - * @param[out] acc_cfg : Accelerometer configuration value - * @param[out] aps : Advance power mode value - * @param[out] acc_en : Accelerometer enable value - * @param[in] dev : Structure instance of bmi2_dev - * - * @return Result of API execution status - * @retval BMI2_OK - Success. - * @retval BMI2_E_COM_FAIL - Error: Communication fail - * @retval BMI2_E_INVALID_SENSOR - Error: Invalid sensor - */ -static int8_t save_accel_foc_config(struct bmi2_accel_config *acc_cfg, - uint8_t *aps, - uint8_t *acc_en, - struct bmi2_dev *dev); - -/*! - * @brief This internal API performs Fast Offset Compensation for accelerometer. - * - * @param[in] accel_g_value : This parameter selects the accel foc - * axis to be performed - * - * input format is {x, y, z, sign}. '1' to enable. '0' to disable - * - * eg to choose x axis {1, 0, 0, 0} - * eg to choose -x axis {1, 0, 0, 1} - * - * @param[in] acc_cfg : Accelerometer configuration value - * @param[in] dev : Structure instance of bmi2_dev. - * - * @return Result of API execution status - * - * @retval BMI2_OK - Success. - * @retval BMI2_E_NULL_PTR - Error: Null pointer error - * @retval BMI2_E_COM_FAIL - Error: Communication fail - */ -static int8_t perform_accel_foc(const struct bmi2_accel_foc_g_value *accel_g_value, - const struct bmi2_accel_config *acc_cfg, - struct bmi2_dev *dev); - -/*! - * @brief This internal sets configurations for performing accelerometer FOC. - * - * @param[in] dev : Structure instance of bmi2_dev - * - * @return Result of API execution status - * @retval BMI2_OK - Success. - * @retval BMI2_E_COM_FAIL - Error: Communication fail - * @retval BMI2_E_INVALID_SENSOR - Error: Invalid sensor - */ -static int8_t set_accel_foc_config(struct bmi2_dev *dev); - -/*! - * @brief This internal API enables/disables the offset compensation for - * filtered and un-filtered accelerometer data. - * - * @param[in] offset_en : enables/disables offset compensation. - * @param[in] dev : Structure instance of bmi2_dev - * - * @return Result of API execution status - * @retval BMI2_OK - Success. - * @retval BMI2_E_COM_FAIL - Error: Communication fail - */ -static int8_t set_accel_offset_comp(uint8_t offset_en, struct bmi2_dev *dev); - -/*! - * @brief This internal API converts the range value into accelerometer - * corresponding integer value. - * - * @param[in] range_in : Input range value. - * @param[out] range_out : Stores the integer value of range. - * - * @return None - * @retval None - */ -static void map_accel_range(uint8_t range_in, uint8_t *range_out); - -/*! - * @brief This internal API compensate the accelerometer data against gravity. - * - * @param[in] lsb_per_g : LSB value pre 1g. - * @param[in] g_val : G reference value of all axis. - * @param[in] data : Accelerometer data - * @param[out] comp_data : Stores the data that is compensated by taking the - * difference in accelerometer data and lsb_per_g - * value. - * - * @return None - * @retval None - */ -static void comp_for_gravity(uint16_t lsb_per_g, - const struct bmi2_accel_foc_g_value *g_val, - const struct bmi2_sens_axes_data *data, - struct bmi2_offset_delta *comp_data); - -/*! - * @brief This internal API scales the compensated accelerometer data according - * to the offset register resolution. - * - * @param[in] range : G-range of the accelerometer. - * @param[out] comp_data : Data that is compensated by taking the - * difference in accelerometer data and lsb_per_g - * value. - * @param[out] data : Stores offset data - * - * @return None - * @retval None - */ -static void scale_accel_offset(uint8_t range, const struct bmi2_offset_delta *comp_data, - struct bmi2_accel_offset *data); - -/*! - * @brief This internal API finds the bit position of 3.9mg according to given - * range and resolution. - * - * @param[in] range : G-range of the accelerometer. - * - * @return Result of API execution status - * @retval Bit position of 3.9mg - */ -static int8_t get_bit_pos_3_9mg(uint8_t range); - -/*! - * @brief This internal API inverts the accelerometer offset data. - * - * @param[out] offset_data : Stores the inverted offset data - * - * @return None - * @retval None - */ -static void invert_accel_offset(struct bmi2_accel_offset *offset_data); - -/*! - * @brief This internal API writes the offset data in the offset compensation - * register. - * - * @param[in] offset : offset data - * @param[in] dev : Structure instance of bmi2_dev - * - * @return Result of API execution status - * @retval BMI2_OK - Success. - * @retval BMI2_E_COM_FAIL - Error: Communication fail - */ -static int8_t write_accel_offset(const struct bmi2_accel_offset *offset, struct bmi2_dev *dev); - -/*! - * @brief This internal API restores the configurations saved before performing - * accelerometer FOC. - * - * @param[in] acc_cfg : Accelerometer configuration value - * @param[in] acc_en : Accelerometer enable value - * @param[in] aps : Advance power mode value - * @param[in] dev : Structure instance of bmi2_dev - * - * @return Result of API execution status - * @retval BMI2_OK - Success. - * @retval BMI2_E_COM_FAIL - Error: Communication fail - * @retval BMI2_E_INVALID_SENSOR - Error: Invalid sensor - * @retval BMI2_E_SET_APS_FAIL - Error: Set Advance Power Save Fail - */ -static int8_t restore_accel_foc_config(struct bmi2_accel_config *acc_cfg, - uint8_t aps, - uint8_t acc_en, - struct bmi2_dev *dev); - -/*! - * @brief This internal API saves the configurations before performing gyroscope - * FOC. - * - * @param[out] gyr_cfg : Gyroscope configuration value - * @param[out] gyr_en : Gyroscope enable value - * @param[out] aps : Advance power mode value - * @param[in] dev : Structure instance of bmi2_dev - * - * @return Result of API execution status - * @retval BMI2_OK - Success. - * @retval BMI2_E_COM_FAIL - Error: Communication fail - * @retval BMI2_E_INVALID_SENSOR - Error: Invalid sensor - */ -static int8_t save_gyro_config(struct bmi2_gyro_config *gyr_cfg, uint8_t *aps, uint8_t *gyr_en, struct bmi2_dev *dev); - -/*! - * @brief This internal sets configurations for performing gyroscope FOC. - * - * @param[in] dev : Structure instance of bmi2_dev - * - * @return Result of API execution status - * @retval BMI2_OK - Success. - * @retval BMI2_E_COM_FAIL - Error: Communication fail - * @retval BMI2_E_INVALID_SENSOR - Error: Invalid sensor - */ -static int8_t set_gyro_foc_config(struct bmi2_dev *dev); - -/*! - * @brief This internal API inverts the gyroscope offset data. - * - * @param[out] offset_data : Stores the inverted offset data - * - * @return None - * @retval None - */ -static void invert_gyro_offset(struct bmi2_sens_axes_data *offset_data); - -/*! - * @brief This internal API restores the gyroscope configurations saved - * before performing FOC. - * - * @param[in] gyr_cfg : Gyroscope configuration value - * @param[in] gyr_en : Gyroscope enable value - * @param[in] aps : Advance power mode value - * @param[in] dev : Structure instance of bmi2_dev - * - * @return Result of API execution status - * @retval BMI2_OK - Success. - * @retval BMI2_E_COM_FAIL - Error: Communication fail - * @retval BMI2_E_INVALID_SENSOR - Error: Invalid sensor - */ -static int8_t restore_gyro_config(struct bmi2_gyro_config *gyr_cfg, uint8_t aps, uint8_t gyr_en, struct bmi2_dev *dev); - -/*! - * @brief This internal API saturates the gyroscope data value before writing to - * to 10 bit offset register. - * - * @param[in, out] gyr_off : Gyroscope data to be stored in offset register - * - * @return None - * @retval None - */ -static void saturate_gyro_data(struct bmi2_sens_axes_data *gyr_off); - -/*! - * @brief This internal API reads the gyroscope data for x, y and z axis from - * the sensor. - * - * @param[out] gyro : Buffer to store the gyroscope value. - * @param[in] dev : Structure instance of bmi2_dev. - * - * @return Result of API execution status - * - * @retval BMI2_OK - Success. - * @retval BMI2_E_COM_FAIL - Error: Communication fail - */ -static int8_t read_gyro_xyz(struct bmi2_sens_axes_data *gyro, struct bmi2_dev *dev); - -/*! - * @brief This internal API is used to check the boundary conditions. - * - * @param[in] dev : Structure instance of bmi2_dev. - * @param[in,out] val : Pointer to the value to be validated. - * @param[in] min : minimum value. - * @param[in] max : maximum value. - * - * @return Result of API execution status - * - * @retval BMI2_OK - Success. - * @retval BMI2_E_NULL_PTR - Error: Null pointer error - * - */ -static int8_t check_boundary_val(uint8_t *val, uint8_t min, uint8_t max, struct bmi2_dev *dev); - -/*! - * @brief This internal API is used to validate the device pointer for - * null conditions. - * - * @param[in] dev : Structure instance of bmi2_dev. - * - * @return Result of API execution status - * - * @retval BMI2_OK - Success. - * @retval BMI2_E_NULL_PTR - Error: Null pointer error - */ -static int8_t null_ptr_check(const struct bmi2_dev *dev); - -/*! - * @brief This updates the result for CRT or gyro self-test. - * - * @param[in] dev : Structure instance of bmi2_dev. - * - * @return Result of API execution status - * @retval BMI2_OK - Success. - * @retval BMI2_E_CRT_ERROR - Error: CRT Fail - * - */ -static int8_t crt_gyro_st_update_result(struct bmi2_dev *dev); - -/*! - * @brief This function is to get the st_status status. - * - * @param[in] *st_status: gets the crt running status - * @param[in] dev : Structure instance of bmi2_dev - * - * @return Result of API execution status - * @retval BMI2_OK - Success. - * @retval BMI2_E_COM_FAIL - Error: Communication fail - * @retval BMI2_E_INVALID_SENSOR - Error: Invalid sensor - * - */ -static int8_t get_st_running(uint8_t *st_status, struct bmi2_dev *dev); - -/*! - * @brief This function is to set crt bit to running. - * - * @param[in] enable - * @param[in] dev : Structure instance of bmi2_dev - * - * @return Result of API execution status - * @retval BMI2_OK - Success. - * @retval BMI2_E_COM_FAIL - Error: Communication fail - * @retval BMI2_E_INVALID_SENSOR - Error: Invalid sensor - * - */ -static int8_t set_st_running(uint8_t st_status, struct bmi2_dev *dev); - -/*! - * @brief This function is to make the initial changes for CRT. - * Disable the gyro, OIS, aps - * Note: For the purpose of preparing CRT Gyro, OIS and APS are disabled - * - * @param[in] dev : Structure instance of bmi2_dev - * - * @return Result of API execution status - * @retval BMI2_OK - Success. - * @retval BMI2_E_COM_FAIL - Error: Communication fail - * @retval BMI2_E_INVALID_SENSOR - Error: Invalid sensor - * - */ -static int8_t crt_prepare_setup(struct bmi2_dev *dev); - -static int8_t do_gtrigger_test(uint8_t gyro_st_crt, struct bmi2_dev *dev); - -/*! - * @brief This function is to get the rdy for dl bit status - * this will toggle from 0 to 1 and visevers according to the - * dowload status - * - * @param[in] *rdy_for_dl: gets the rdy_for_dl status - * @param[in] dev : Structure instance of bmi2_dev - * - * @return Result of API execution status - * @retval BMI2_OK - Success. - * @retval BMI2_E_COM_FAIL - Error: Communication fail - * @retval BMI2_E_INVALID_SENSOR - Error: Invalid sensor - * - */ -static int8_t get_rdy_for_dl(uint8_t *rdy_for_dl, struct bmi2_dev *dev); - -/*! - * @brief This function is to write the config file in the given location for crt. - * which inter checks the status of the rdy_for_dl bit and also the crt running, and - * wirtes the given size. - * - * @param[in] write_len: length of the words to be written - * @param[in] config_file_size: length of the words to be written - * @param[in] start_index: provide the start index from where config file has to written - * @param[in] dev : Structure instance of bmi2_dev - * - * @return Result of API execution status - * @retval BMI2_OK - Success. - * @retval BMI2_E_COM_FAIL - Error: Communication fail - * @retval BMI2_E_INVALID_SENSOR - Error: Invalid sensor - * - */ -static int8_t write_crt_config_file(uint16_t write_len, - uint16_t config_file_size, - uint16_t start_index, - struct bmi2_dev *dev); - -/*! - * @brief This function is to check for rdy_for_dl bit to toggle for CRT process - * - * @param[in] retry_complete: wait for given time to toggle - * @param[in] download_ready: get the status for rdy_for_dl - * @param[in] dev : Structure instance of bmi2_dev - * - * @return Result of API execution status - * @retval BMI2_OK - Success. - * @retval BMI2_E_COM_FAIL - Error: Communication fail - * @retval BMI2_E_INVALID_SENSOR - Error: Invalid sensor - * - */ -static int8_t wait_rdy_for_dl_toggle(uint8_t retry_complete, uint8_t download_ready, struct bmi2_dev *dev); - -/*! - * @brief This function is to wait till the CRT or gyro self-test process is completed - * - * @param[in] retry_complete: wait for given time to complete the crt process - * @param[in] dev : Structure instance of bmi2_dev - * - * @return Result of API execution status - * @retval BMI2_OK - Success. - * @retval BMI2_E_COM_FAIL - Error: Communication fail - * @retval BMI2_E_INVALID_SENSOR - Error: Invalid sensor - * - */ -static int8_t wait_st_running(uint8_t retry_complete, struct bmi2_dev *dev); - -/*! - * @brief This function is to complete the crt process if max burst length is not zero - * this checks for the crt status and rdy_for_dl bit to toggle - * - * @param[in] last_byte_flag: to provide the last toggled state - * @param[in] dev : Structure instance of bmi2_dev - * - * @return Result of API execution status - * @retval BMI2_OK - Success. - * @retval BMI2_E_COM_FAIL - Error: Communication fail - * @retval BMI2_E_INVALID_SENSOR - Error: Invalid sensor - * - */ -static int8_t process_crt_download(uint8_t last_byte_flag, struct bmi2_dev *dev); - -/*! - * @brief This api is used to enable the gyro self-test or crt. - * - * @param[in] dev : Structure instance of bmi2_dev. - * - * @return Result of API execution status - * - * @retval BMI2_OK - Success. - * @retval BMI2_E_NULL_PTR - Error: Null pointer error - * @retval BMI2_E_COM_FAIL - Error: Communication fail - */ -static int8_t select_self_test(uint8_t gyro_st_crt, struct bmi2_dev *dev); - -/*! - * @brief This api is used to enable/disable abort. - * - * @param[in] abort_enable : variable to enable the abort feature. - * @param[in] dev : Structure instance of bmi2_dev. - * - * @return Result of API execution status - * - * @retval BMI2_OK - Success. - * @retval BMI2_E_NULL_PTR - Error: Null pointer error - * @retval BMI2_E_COM_FAIL - Error: Communication fail - */ -static int8_t abort_bmi2(uint8_t abort_enable, struct bmi2_dev *dev); - -/*! - * @brief This api is use to wait till gyro self-test is completed and update the status of gyro - * self-test. - * - * @param[in] dev : Structure instance of bmi2_dev. - * - * @return Result of API execution status - * - * @retval BMI2_OK - Success. - * @retval <0 - Fail - */ -static int8_t gyro_self_test_completed(struct bmi2_gyro_self_test_status *gyro_st_result, struct bmi2_dev *dev); - -/*! - * @brief This api is used to trigger the preparation for system for NVM programming. - * - * @param[out] nvm_prep : pointer to variable to store the status of nvm_prep_prog. - * @param[in] dev : Structure instance of bmi2_dev. - * - * @return Result of API execution status - * - * @retval BMI2_OK - Success. - * @retval BMI2_E_NULL_PTR - Error: Null pointer error - * @retval BMI2_E_COM_FAIL - Error: Communication fail - */ -static int8_t set_nvm_prep_prog(uint8_t nvm_prep, struct bmi2_dev *dev); - -/*! - * @brief This api validates accel foc position as per the range - * - * @param[in] sens_list : Sensor type - * @param[in] accel_g_axis : accel axis to foc. NA for gyro foc - * @param[in] avg_foc_data : average value of sensor sample datas - * @param[in] dev : Structure instance of bmi2_dev. - * - * @return Result of API execution status - * - * @retval BMI2_OK - Success. - * @retval BMI2_E_INVALID_INPUT - Error: Invalid input - */ -static int8_t validate_foc_position(uint8_t sens_list, - const struct bmi2_accel_foc_g_value *accel_g_axis, - struct bmi2_sens_axes_data avg_foc_data, - struct bmi2_dev *dev); - -/*! - * @brief This api validates accel foc axis given as input - * - * @param[in] avg_foc_data : average value of sensor sample datas - * @param[in] dev : Structure instance of bmi2_dev. - * - * @return Result of API execution status - * - * @retval BMI2_OK - Success. - * @retval BMI2_E_INVALID_INPUT - Error: Invalid input - */ -static int8_t validate_foc_accel_axis(int16_t avg_foc_data, struct bmi2_dev *dev); - -/*! - * @brief This api is used to verify the right position of the sensor before doing accel foc - * - * @param[in] dev : Structure instance of bmi2_dev. - * @param[in] sens_list: Sensor type - * @param[in] accel_g_axis: Accel Foc axis and sign input - * - * @return Result of API execution status - * - * @retval BMI2_OK - Success. - * @retval BMI2_E_NULL_PTR - Error: Null pointer error - * @retval BMI2_E_INVALID_INPUT - Error: Invalid input - */ -static int8_t verify_foc_position(uint8_t sens_list, - const struct bmi2_accel_foc_g_value *accel_g_axis, - struct bmi2_dev *dev); - -/*! - * @brief This API reads and provides average for 128 samples of sensor data for foc operation - * gyro. - * - * @param[in] sens_list : Sensor type. - * @param[in] bmi2_dev: Structure instance of bmi2_dev. - * @param[in] temp_foc_data: to store data samples - * - * @return Result of API execution status - * - * @retval BMI2_OK - */ -static int8_t get_average_of_sensor_data(uint8_t sens_list, - struct bmi2_foc_temp_value *temp_foc_data, - struct bmi2_dev *dev); - -/*! - * @brief This internal API sets primary OIS configurations, - * low pass filter cut-off frequency. - * - * @param[in] config : Structure instance of bmi2_primary_ois_config. - * @param[in, out] dev : Structure instance of bmi2_dev. - * - * @verbatim - *---------------------------------------------------------------------------- - * bmi2_primary_ois_config | - * Structure parameters | Description - *--------------------------|-------------------------------------------------- - * lp filter config | Lp filter cut off frequency - * | Value Name Description - * | 00 280_Hz Cut off frequency configured to 280 Hz - * | 01 350_Hz Cut off frequency configured to 350 Hz - * | 10 410_Hz Cut off frequency configured to 410 Hz - * | 11 612_Hz Cut off frequency configured to 612 Hz - * ---------------------------------------------------------------------------- - * - * @endverbatim - * - * @return Result of API execution status - * - * @retval BMI2_OK - Success. - * @retval BMI2_E_COM_FAIL - Error: Communication fail - * @retval BMI2_E_INVALID_SENSOR - Error: Invalid sensor - * @retval BMI2_E_INVALID_PAGE - Error: Invalid Page - */ -static int8_t set_primary_ois_config(const struct bmi2_primary_ois_config *config, struct bmi2_dev *dev); - -/*! - * @brief This internal API gets primary OIS configurations, - * low pass filter cut-off frequency. - * - * @param[out] config : Structure instance of bmi2_primary_ois_config. - * @param[in, out] dev : Structure instance of bmi2_dev. - * - * @verbatim - *---------------------------------------------------------------------------- - * bmi2_primary_ois_config | - * Structure parameters | Description - *--------------------------|-------------------------------------------------- - * lp filter config | Lp filter cut off frequency - * | Value Name Description - * | 00 280_Hz Cut off frequency configured to 280 Hz - * | 01 350_Hz Cut off frequency configured to 350 Hz - * | 10 410_Hz Cut off frequency configured to 410 Hz - * | 11 612_Hz Cut off frequency configured to 612 Hz - * ---------------------------------------------------------------------------- - * - * @endverbatim - * - * @return Result of API execution status - * - * @retval BMI2_OK - Success. - * @retval BMI2_E_COM_FAIL - Error: Communication fail - * @retval BMI2_E_INVALID_SENSOR - Error: Invalid sensor - * @retval BMI2_E_INVALID_PAGE - Error: Invalid Page - */ -static int8_t get_primary_ois_config(struct bmi2_primary_ois_config *config, struct bmi2_dev *dev); - -/*! - * @brief This internal API gets the output data of OIS. - * - * @param[out] ois_output : Structure instance to the stored OIS data. - * @param[in] dev : Structure instance of bmi2_dev. - * - * @return Result of API execution status - * - * @retval BMI2_OK - Success. - * @retval BMI2_E_COM_FAIL - Error: Communication fail - * @retval BMI2_E_INVALID_SENSOR - Error: Invalid sensor - * @retval BMI2_E_INVALID_PAGE - Error: Invalid Page - */ -static int8_t get_ois_output(struct bmi2_ois_output *ois_output, struct bmi2_dev *dev); - -/*! - * @brief This internal api gets major and minor version for config file - * - * @param[out] config_major : Pointer to store the major version - * @param[out] config_minor : Pointer to store the minor version - * @param[in] dev : Structure instance of bmi2_dev - * - * @return Result of API execution status - * - * @retval BMI2_OK - Success. - * @retval BMI2_E_INVALID_SENSOR - Error: Invalid sensor - * @retval BMI2_E_INVALID_PAGE - Error: Invalid Page - */ -static int8_t extract_config_file(uint16_t *config_major, uint8_t *config_minor, struct bmi2_dev *dev); - -/*! - * @brief This internal API gets free-fall configurations like free-fall accel settings, - * and output configuration. - * - * @param[in] config : Structure instance of bmi2_free_fall_det_config. - * @param[in, out] dev : Structure instance of bmi2_dev. - * - * @verbatim - *---------------------------------------------------------------------------- - * bmi2_free_fall_det_config | - * Structure parameters | Description - *------------------------------|-------------------------------------------------- - * free-fall accel settings | Free-fall accel settings. - * 1 - 7 | - * -----------------------------|--------------------------------------------------- - * | Enable bits for enabling output into the - * out_conf | register status bits and, if desired, onto the - * | interrupt pin. - * -----------------------------|--------------------------------------------------- - * @endverbatim - * - * @return Result of API execution status - * - * @retval BMI2_OK - Success. - * @retval BMI2_E_COM_FAIL - Error: Communication fail - * @retval BMI2_E_INVALID_SENSOR - Error: Invalid sensor - * @retval BMI2_E_INVALID_PAGE - Error: Invalid Page - */ -static int8_t get_free_fall_det_config(struct bmi2_free_fall_det_config *config, struct bmi2_dev *dev); - -/*! - * @brief This internal API sets free-fall configurations like free-fall accel settings, - * and output configuration. - * - * @param[in] config : Structure instance of bmi2_free_fall_det_config. - * @param[in, out] dev : Structure instance of bmi2_dev. - * - * @verbatim - *---------------------------------------------------------------------------- - * bmi2_free_fall_det_config | - * Structure parameters | Description - *------------------------------|-------------------------------------------------- - * free-fall accel settings | Free-fall accel settings. - * 1 - 7 | - * -----------------------------|--------------------------------------------------- - * | Enable bits for enabling output into the - * out_conf | register status bits and, if desired, onto the - * | interrupt pin. - * -----------------------------|--------------------------------------------------- - * @endverbatim - * - * @return Result of API execution status - * - * @retval BMI2_OK - Success. - * @retval BMI2_E_COM_FAIL - Error: Communication fail - * @retval BMI2_E_INVALID_SENSOR - Error: Invalid sensor - * @retval BMI2_E_INVALID_PAGE - Error: Invalid Page - */ -static int8_t set_free_fall_det_config(const struct bmi2_free_fall_det_config *config, struct bmi2_dev *dev); - -/*! - * @brief This internal API is used to enable/disable free-fall detection feature. - * - * @param[in] dev : Structure instance of bmi2_dev. - * @param[in] enable : Enables/Disables free-fall detection. - * - * Enable | Description - * -------------|--------------- - * BMI2_DISABLE | Disables free-fall detection - * BMI2_ENABLE | Enables free-fall detection - * - * @return Result of API execution status - * - * @retval BMI2_OK - Success. - * @retval BMI2_E_COM_FAIL - Error: Communication fail - * @retval BMI2_E_INVALID_SENSOR - Error: Invalid sensor - * @retval BMI2_E_INVALID_PAGE - Error: Invalid Page - */ -static int8_t set_free_fall_det(uint8_t enable, struct bmi2_dev *dev); - -/******************************************************************************/ -/*! @name User Interface Definitions */ -/******************************************************************************/ - -/*! - * @brief This API is the entry point for bmi2 sensor. It selects between - * I2C/SPI interface, based on user selection. It reads and validates the - * chip-id of the sensor. - */ -int8_t bmi2_sec_init(struct bmi2_dev *dev) -{ - /* Variable to define error */ - int8_t rslt; - - /* Variable to assign chip id */ - uint8_t chip_id = 0; - - /* Structure to define the default values for axes re-mapping */ - struct bmi2_axes_remap axes_remap = { - .x_axis = BMI2_MAP_X_AXIS, .x_axis_sign = BMI2_POS_SIGN, .y_axis = BMI2_MAP_Y_AXIS, - .y_axis_sign = BMI2_POS_SIGN, .z_axis = BMI2_MAP_Z_AXIS, .z_axis_sign = BMI2_POS_SIGN - }; - - /* Null-pointer check */ - rslt = null_ptr_check(dev); - if (rslt == BMI2_OK) - { - /* Perform soft-reset to bring all register values to their - * default values - */ - rslt = bmi2_soft_reset(dev); - if (rslt == BMI2_OK) - { - /* Read chip-id of the BMI2 sensor */ - rslt = bmi2_get_regs(BMI2_CHIP_ID_ADDR, &chip_id, 1, dev); - if (rslt == BMI2_OK) - { - /* Validate chip-id */ - if (chip_id == dev->chip_id) - { - /* Assign resolution to the structure */ - dev->resolution = 16; - - /* Set manual enable flag */ - dev->aux_man_en = 1; - - /* Set the default values for axis - * re-mapping in the device structure - */ - dev->remap = axes_remap; - } - else - { - /* Storing the chip-id value read from - * the register to identify the sensor - */ - dev->chip_id = chip_id; - rslt = BMI2_E_DEV_NOT_FOUND; - } - } - } - } - - return rslt; -} - -/*! - * @brief This API reads the data from the given register address of bmi2 - * sensor. - * - * @note For most of the registers auto address increment applies, with the - * exception of a few special registers, which trap the address. For e.g., - * Register address - 0x26, 0x5E. - */ -int8_t bmi2_get_regs(uint8_t reg_addr, uint8_t *data, uint16_t len, struct bmi2_dev *dev) -{ - /* Variable to define error */ - int8_t rslt; - - /* Variable to define loop */ - uint16_t index = 0; - - /* Null-pointer check */ - rslt = null_ptr_check(dev); - if ((rslt == BMI2_OK) && (data != NULL)) - { - /* Variable to define temporary length */ - uint16_t temp_len = len + dev->dummy_byte; - - /* Variable to define temporary buffer */ - uint8_t temp_buf[temp_len]; - - /* Configuring reg_addr for SPI Interface */ - if (dev->intf == BMI2_SPI_INTF) - { - reg_addr = (reg_addr | BMI2_SPI_RD_MASK); - } - - if (dev->aps_status == BMI2_ENABLE) - { - dev->intf_rslt = dev->read(reg_addr, temp_buf, temp_len, dev->intf_ptr); - dev->delay_us(450, dev->intf_ptr); - } - else - { - dev->intf_rslt = dev->read(reg_addr, temp_buf, temp_len, dev->intf_ptr); - dev->delay_us(20, dev->intf_ptr); - } - - if (dev->intf_rslt == BMI2_INTF_RET_SUCCESS) - { - /* Read the data from the position next to dummy byte */ - while (index < len) - { - data[index] = temp_buf[index + dev->dummy_byte]; - index++; - } - } - else - { - rslt = BMI2_E_COM_FAIL; - } - } - else - { - rslt = BMI2_E_NULL_PTR; - } - - return rslt; -} - -/*! - * @brief This API writes data to the given register address of bmi2 sensor. - */ -int8_t bmi2_set_regs(uint8_t reg_addr, const uint8_t *data, uint16_t len, struct bmi2_dev *dev) -{ - /* Variable to define error */ - int8_t rslt; - - /* Variable to define loop */ - uint16_t loop = 0; - - /* Null-pointer check */ - rslt = null_ptr_check(dev); - if ((rslt == BMI2_OK) && (data != NULL)) - { - /* Configuring reg_addr for SPI Interface */ - if (dev->intf == BMI2_SPI_INTF) - { - reg_addr = (reg_addr & BMI2_SPI_WR_MASK); - } - - if (dev->aps_status == BMI2_ENABLE) - { - for (loop = 0; loop < len; loop++) - { - /* Byte write if APS is enabled */ - dev->intf_rslt = dev->write((uint8_t)((uint16_t) reg_addr + loop), &data[loop], 1, dev->intf_ptr); - dev->delay_us(450, dev->intf_ptr); - if (dev->intf_rslt != BMI2_INTF_RET_SUCCESS) - { - break; - } - } - } - else - { - /* Burst write if APS is disabled */ - dev->intf_rslt = dev->write(reg_addr, data, len, dev->intf_ptr); - dev->delay_us(20, dev->intf_ptr); - } - - /* updating the advance power saver flag */ - if (reg_addr == BMI2_PWR_CONF_ADDR) - { - if (*data & BMI2_ADV_POW_EN_MASK) - { - dev->aps_status = BMI2_ENABLE; - } - else - { - dev->aps_status = BMI2_DISABLE; - } - } - - if (dev->intf_rslt != BMI2_INTF_RET_SUCCESS) - { - rslt = BMI2_E_COM_FAIL; - } - } - else - { - rslt = BMI2_E_NULL_PTR; - } - - return rslt; -} - -/*! - * @brief This API resets bmi2 sensor. All registers are overwritten with - * their default values. - */ -int8_t bmi2_soft_reset(struct bmi2_dev *dev) -{ - /* Variable to define error */ - int8_t rslt; - - /* Variable to define soft reset value */ - uint8_t data = BMI2_SOFT_RESET_CMD; - - /* Variable to read the dummy byte */ - uint8_t dummy_read = 0; - - /* Null-pointer check */ - rslt = null_ptr_check(dev); - if (rslt == BMI2_OK) - { - /* Reset bmi2 device */ - rslt = bmi2_set_regs(BMI2_CMD_REG_ADDR, &data, 1, dev); - dev->delay_us(2000, dev->intf_ptr); - - /* set APS flag as after soft reset the sensor is on advance power save mode */ - dev->aps_status = BMI2_ENABLE; - - /* Performing a dummy read to bring interface back to SPI from - * I2C after a soft-reset - */ - if ((rslt == BMI2_OK) && (dev->intf == BMI2_SPI_INTF)) - { - rslt = bmi2_get_regs(BMI2_CHIP_ID_ADDR, &dummy_read, 1, dev); - } - - if (rslt == BMI2_OK) - { - /* Write the configuration file */ - rslt = bmi2_write_config_file(dev); - } - - /* Reset the sensor status flag in the device structure */ - if (rslt == BMI2_OK) - { - dev->sens_en_stat = 0; - } - } - - return rslt; -} - -/*! - * @brief This API is used to get the config file major and minor version information. - */ -int8_t bmi2_get_config_file_version(uint16_t *config_major, uint8_t *config_minor, struct bmi2_dev *dev) -{ - /* Variable to define error */ - int8_t rslt; - - /* NULL pointer check */ - rslt = null_ptr_check(dev); - if ((rslt == BMI2_OK) && (config_major != NULL) && (config_minor != NULL)) - { - /* Extract the config file identification from the dmr page and get the major and minor version */ - rslt = extract_config_file(config_major, config_minor, dev); - } - else - { - rslt = BMI2_E_NULL_PTR; - } - - return rslt; -} - -/*! - * @brief This API selects the sensors/features to be enabled. - */ -int8_t bmi2_sensor_enable(const uint8_t *sens_list, uint8_t n_sens, struct bmi2_dev *dev) -{ - /* Variable to define error */ - int8_t rslt; - - /* Variable to select sensor */ - uint64_t sensor_sel = 0; - - /* Null-pointer check */ - rslt = null_ptr_check(dev); - if ((rslt == BMI2_OK) && (sens_list != NULL)) - { - /* Get the selected sensors */ - rslt = select_sensor(sens_list, n_sens, &sensor_sel); - if (rslt == BMI2_OK) - { - /* Enable the selected sensors */ - rslt = sensor_enable(sensor_sel, dev); - } - } - else - { - rslt = BMI2_E_NULL_PTR; - } - - return rslt; -} - -/*! - * @brief This API selects the sensors/features to be disabled. - */ -int8_t bmi2_sensor_disable(const uint8_t *sens_list, uint8_t n_sens, struct bmi2_dev *dev) -{ - /* Variable to define error */ - int8_t rslt; - - /* Variable to select sensor */ - uint64_t sensor_sel = 0; - - /* Null-pointer check */ - rslt = null_ptr_check(dev); - if ((rslt == BMI2_OK) && (sens_list != NULL)) - { - /* Get the selected sensors */ - rslt = select_sensor(sens_list, n_sens, &sensor_sel); - if (rslt == BMI2_OK) - { - /* Disable the selected sensors */ - rslt = sensor_disable(sensor_sel, dev); - } - } - else - { - rslt = BMI2_E_NULL_PTR; - } - - return rslt; -} - -/*! - * @brief This API sets the sensor/feature configuration. - */ -int8_t bmi2_set_sensor_config(struct bmi2_sens_config *sens_cfg, uint8_t n_sens, struct bmi2_dev *dev) -{ - /* Variable to define error */ - int8_t rslt; - - /* Variable to define loop */ - uint8_t loop; - - /* Variable to get the status of advance power save */ - uint8_t aps_stat = 0; - - /* Null-pointer check */ - rslt = null_ptr_check(dev); - if ((rslt == BMI2_OK) && (sens_cfg != NULL)) - { - /* Get status of advance power save mode */ - aps_stat = dev->aps_status; - - for (loop = 0; loop < n_sens; loop++) - { - /* Disable Advance power save if enabled for auxiliary - * and feature configurations - */ - if (aps_stat == BMI2_ENABLE) - { - /* Disable advance power save if - * enabled - */ - rslt = bmi2_set_adv_power_save(BMI2_DISABLE, dev); - } - - if (rslt == BMI2_OK) - { - switch (sens_cfg[loop].type) - { - /* Set accelerometer configuration */ - case BMI2_ACCEL: - rslt = set_accel_config(&sens_cfg[loop].cfg.acc, dev); - break; - - /* Set gyroscope configuration */ - case BMI2_GYRO: - rslt = set_gyro_config(&sens_cfg[loop].cfg.gyr, dev); - break; - - /* Set auxiliary configuration */ - case BMI2_AUX: - rslt = set_aux_config(&sens_cfg[loop].cfg.aux, dev); - break; - - /* Set any motion configuration */ - case BMI2_ANY_MOTION: - rslt = set_any_motion_config(&sens_cfg[loop].cfg.any_motion, dev); - break; - - /* Set no motion configuration */ - case BMI2_NO_MOTION: - rslt = set_no_motion_config(&sens_cfg[loop].cfg.no_motion, dev); - break; - - /* Set sig-motion configuration */ - case BMI2_SIG_MOTION: - rslt = set_sig_motion_config(&sens_cfg[loop].cfg.sig_motion, dev); - break; - - /* Set the step counter parameters */ - case BMI2_STEP_COUNTER_PARAMS: - rslt = set_step_count_params_config(sens_cfg[loop].cfg.step_counter_params, dev); - break; - - /* Set step counter/detector/activity configuration */ - case BMI2_STEP_DETECTOR: - case BMI2_STEP_COUNTER: - case BMI2_STEP_ACTIVITY: - rslt = set_step_config(&sens_cfg[loop].cfg.step_counter, dev); - break; - - /* Set gyroscope user gain configuration */ - case BMI2_GYRO_GAIN_UPDATE: - rslt = set_gyro_user_gain_config(&sens_cfg[loop].cfg.gyro_gain_update, dev); - break; - - /* Set tilt configuration */ - case BMI2_TILT: - rslt = set_tilt_config(&sens_cfg[loop].cfg.tilt, dev); - break; - - /* Set uphold to wake configuration */ - case BMI2_UP_HOLD_TO_WAKE: - rslt = set_up_hold_to_wake_config(&sens_cfg[loop].cfg.up_hold_to_wake, dev); - break; - - /* Set glance detector configuration */ - case BMI2_GLANCE_DETECTOR: - rslt = set_glance_detect_config(&sens_cfg[loop].cfg.glance_det, dev); - break; - - /* Set wake-up configuration */ - case BMI2_WAKE_UP: - case BMI2_SINGLE_TAP: - case BMI2_DOUBLE_TAP: - case BMI2_TRIPLE_TAP: - rslt = set_wake_up_config(&sens_cfg[loop].cfg.tap, dev); - break; - - /* Set orientation configuration */ - case BMI2_ORIENTATION: - rslt = set_orient_config(&sens_cfg[loop].cfg.orientation, dev); - break; - - /* Set high-g configuration */ - case BMI2_HIGH_G: - rslt = set_high_g_config(&sens_cfg[loop].cfg.high_g, dev); - break; - - /* Set low-g configuration */ - case BMI2_LOW_G: - rslt = set_low_g_config(&sens_cfg[loop].cfg.low_g, dev); - break; - - /* Set flat configuration */ - case BMI2_FLAT: - rslt = set_flat_config(&sens_cfg[loop].cfg.flat, dev); - break; - - /* Set external sensor sync configuration */ - case BMI2_EXT_SENS_SYNC: - rslt = set_ext_sens_sync_config(&sens_cfg[loop].cfg.ext_sens_sync, dev); - break; - - /* Set the wrist gesture configuration */ - case BMI2_WRIST_GESTURE: - rslt = set_wrist_gest_config(&sens_cfg[loop].cfg.wrist_gest, dev); - break; - - /* Set the wrist wear wake-up configuration */ - case BMI2_WRIST_WEAR_WAKE_UP: - rslt = set_wrist_wear_wake_up_config(&sens_cfg[loop].cfg.wrist_wear_wake_up, dev); - break; - - /* Set the wrist gesture configuration */ - case BMI2_WRIST_GESTURE_WH: - rslt = set_wrist_gest_w_config(&sens_cfg[loop].cfg.wrist_gest_w, dev); - break; - - /* Set the wrist wear wake-up configuration for wearable variant */ - case BMI2_WRIST_WEAR_WAKE_UP_WH: - rslt = set_wrist_wear_wake_up_wh_config(&sens_cfg[loop].cfg.wrist_wear_wake_up_wh, dev); - break; - - /* Set primary OIS configuration */ - case BMI2_PRIMARY_OIS: - rslt = set_primary_ois_config(&sens_cfg[loop].cfg.primary_ois, dev); - break; - - /* Set the free-fall detection configurations */ - case BMI2_FREE_FALL_DET: - rslt = set_free_fall_det_config(&sens_cfg[loop].cfg.free_fall_det, dev); - break; - - default: - rslt = BMI2_E_INVALID_SENSOR; - break; - } - } - - /* Return error if any of the set configurations fail */ - if (rslt != BMI2_OK) - { - break; - } - } - - /* Enable Advance power save if disabled while configuring and - * not when already disabled - */ - if ((aps_stat == BMI2_ENABLE) && (rslt == BMI2_OK)) - { - rslt = bmi2_set_adv_power_save(BMI2_ENABLE, dev); - } - } - else - { - rslt = BMI2_E_NULL_PTR; - } - - return rslt; -} - -/*! - * @brief This API gets the sensor/feature configuration. - */ -int8_t bmi2_get_sensor_config(struct bmi2_sens_config *sens_cfg, uint8_t n_sens, struct bmi2_dev *dev) -{ - /* Variable to define error */ - int8_t rslt; - - /* Variable to define loop */ - uint8_t loop; - - /* Variable to get the status of advance power save */ - uint8_t aps_stat = 0; - - /* Null-pointer check */ - rslt = null_ptr_check(dev); - if ((rslt == BMI2_OK) && (sens_cfg != NULL)) - { - /* Get status of advance power save mode */ - aps_stat = dev->aps_status; - for (loop = 0; loop < n_sens; loop++) - { - /* Disable Advance power save if enabled for auxiliary - * and feature configurations - */ - if ((sens_cfg[loop].type >= BMI2_MAIN_SENS_MAX_NUM) || (sens_cfg[loop].type == BMI2_AUX)) - { - - if (aps_stat == BMI2_ENABLE) - { - /* Disable advance power save if - * enabled - */ - rslt = bmi2_set_adv_power_save(BMI2_DISABLE, dev); - } - } - - if (rslt == BMI2_OK) - { - switch (sens_cfg[loop].type) - { - /* Get accelerometer configuration */ - case BMI2_ACCEL: - rslt = get_accel_config(&sens_cfg[loop].cfg.acc, dev); - break; - - /* Get gyroscope configuration */ - case BMI2_GYRO: - rslt = get_gyro_config(&sens_cfg[loop].cfg.gyr, dev); - break; - - /* Get auxiliary configuration */ - case BMI2_AUX: - rslt = get_aux_config(&sens_cfg[loop].cfg.aux, dev); - break; - - /* Get sig-motion configuration */ - case BMI2_SIG_MOTION: - rslt = get_sig_motion_config(&sens_cfg[loop].cfg.sig_motion, dev); - break; - - /* Get any motion configuration */ - case BMI2_ANY_MOTION: - rslt = get_any_motion_config(&sens_cfg[loop].cfg.any_motion, dev); - break; - - /* Get no motion configuration */ - case BMI2_NO_MOTION: - rslt = get_no_motion_config(&sens_cfg[loop].cfg.no_motion, dev); - break; - - /* Set the step counter parameters */ - case BMI2_STEP_COUNTER_PARAMS: - rslt = get_step_count_params_config(sens_cfg[loop].cfg.step_counter_params, dev); - break; - - /* Get step counter/detector/activity configuration */ - case BMI2_STEP_DETECTOR: - case BMI2_STEP_COUNTER: - case BMI2_STEP_ACTIVITY: - rslt = get_step_config(&sens_cfg[loop].cfg.step_counter, dev); - break; - - /* Get gyroscope user gain configuration */ - case BMI2_GYRO_GAIN_UPDATE: - rslt = get_gyro_gain_update_config(&sens_cfg[loop].cfg.gyro_gain_update, dev); - break; - - /* Get tilt configuration */ - case BMI2_TILT: - rslt = get_tilt_config(&sens_cfg[loop].cfg.tilt, dev); - break; - - /* Get up hold to wake configuration */ - case BMI2_UP_HOLD_TO_WAKE: - rslt = get_up_hold_to_wake_config(&sens_cfg[loop].cfg.up_hold_to_wake, dev); - break; - - /* Get glance detector configuration */ - case BMI2_GLANCE_DETECTOR: - rslt = get_glance_detect_config(&sens_cfg[loop].cfg.glance_det, dev); - break; - - /* Get wake-up configuration */ - case BMI2_WAKE_UP: - case BMI2_SINGLE_TAP: - case BMI2_DOUBLE_TAP: - case BMI2_TRIPLE_TAP: - rslt = get_wake_up_config(&sens_cfg[loop].cfg.tap, dev); - break; - - /* Get orientation configuration */ - case BMI2_ORIENTATION: - rslt = get_orient_config(&sens_cfg[loop].cfg.orientation, dev); - break; - - /* Get high-g configuration */ - case BMI2_HIGH_G: - rslt = get_high_g_config(&sens_cfg[loop].cfg.high_g, dev); - break; - - /* Get low-g configuration */ - case BMI2_LOW_G: - rslt = get_low_g_config(&sens_cfg[loop].cfg.low_g, dev); - break; - - /* Get flat configuration */ - case BMI2_FLAT: - rslt = get_flat_config(&sens_cfg[loop].cfg.flat, dev); - break; - - /* Get external sensor sync configuration */ - case BMI2_EXT_SENS_SYNC: - rslt = get_ext_sens_sync_config(&sens_cfg[loop].cfg.ext_sens_sync, dev); - break; - - /* Get the wrist gesture configuration */ - case BMI2_WRIST_GESTURE: - rslt = get_wrist_gest_config(&sens_cfg[loop].cfg.wrist_gest, dev); - break; - - /* Get the wrist wear wake-up configuration */ - case BMI2_WRIST_WEAR_WAKE_UP: - rslt = get_wrist_wear_wake_up_config(&sens_cfg[loop].cfg.wrist_wear_wake_up, dev); - break; - - /* Get the wrist gesture configuration for wearable variant */ - case BMI2_WRIST_GESTURE_WH: - rslt = get_wrist_gest_w_config(&sens_cfg[loop].cfg.wrist_gest_w, dev); - break; - - /* Get the wrist wear wake-up configuration for wearable variant */ - case BMI2_WRIST_WEAR_WAKE_UP_WH: - rslt = get_wrist_wear_wake_up_wh_config(&sens_cfg[loop].cfg.wrist_wear_wake_up_wh, dev); - break; - - /* Get the primary OIS filter configuration */ - case BMI2_PRIMARY_OIS: - rslt = get_primary_ois_config(&sens_cfg[loop].cfg.primary_ois, dev); - break; - - /* Get the free-fall detection configurations */ - case BMI2_FREE_FALL_DET: - rslt = get_free_fall_det_config(&sens_cfg[loop].cfg.free_fall_det, dev); - break; - - default: - rslt = BMI2_E_INVALID_SENSOR; - break; - } - } - - /* Return error if any of the get configurations fail */ - if (rslt != BMI2_OK) - { - break; - } - } - - /* Enable Advance power save if disabled while configuring and - * not when already disabled - */ - if ((aps_stat == BMI2_ENABLE) && (rslt == BMI2_OK)) - { - rslt = bmi2_set_adv_power_save(BMI2_ENABLE, dev); - } - } - else - { - rslt = BMI2_E_NULL_PTR; - } - - return rslt; -} - -/*! - * @brief This API gets the sensor/feature data for accelerometer, gyroscope, - * auxiliary sensor, step counter, high-g, gyroscope user-gain update, - * orientation, gyroscope cross sensitivity and error status for NVM and VFRM. - */ -int8_t bmi2_get_sensor_data(struct bmi2_sensor_data *sensor_data, uint8_t n_sens, struct bmi2_dev *dev) -{ - /* Variable to define error */ - int8_t rslt; - - /* Variable to define loop */ - uint8_t loop; - - /* Variable to get the status of advance power save */ - uint8_t aps_stat = 0; - - /* Null-pointer check */ - rslt = null_ptr_check(dev); - if ((rslt == BMI2_OK) && (sensor_data != NULL)) - { - /* Get status of advance power save mode */ - aps_stat = dev->aps_status; - for (loop = 0; loop < n_sens; loop++) - { - /* Disable Advance power save if enabled for feature - * configurations - */ - if (sensor_data[loop].type >= BMI2_MAIN_SENS_MAX_NUM) - { - if (aps_stat == BMI2_ENABLE) - { - /* Disable advance power save if - * enabled - */ - rslt = bmi2_set_adv_power_save(BMI2_DISABLE, dev); - } - } - - if (rslt == BMI2_OK) - { - switch (sensor_data[loop].type) - { - case BMI2_ACCEL: - - /* Get accelerometer data */ - rslt = get_accel_sensor_data(&sensor_data[loop].sens_data.acc, BMI2_ACC_X_LSB_ADDR, dev); - break; - case BMI2_GYRO: - - /* Get gyroscope data */ - rslt = get_gyro_sensor_data(&sensor_data[loop].sens_data.gyr, BMI2_GYR_X_LSB_ADDR, dev); - break; - case BMI2_AUX: - - /* Get auxiliary sensor data in data mode */ - rslt = read_aux_data_mode(sensor_data[loop].sens_data.aux_data, dev); - break; - case BMI2_STEP_COUNTER: - - /* Get step counter output */ - rslt = get_step_counter_output(&sensor_data[loop].sens_data.step_counter_output, dev); - break; - case BMI2_STEP_ACTIVITY: - - /* Get step activity output */ - rslt = get_step_activity_output(&sensor_data[loop].sens_data.activity_output, dev); - break; - case BMI2_ORIENTATION: - - /* Get orientation output */ - rslt = get_orient_output(&sensor_data[loop].sens_data.orient_output, dev); - break; - case BMI2_HIGH_G: - - /* Get high-g output */ - rslt = get_high_g_output(&sensor_data[loop].sens_data.high_g_output, dev); - break; - case BMI2_GYRO_GAIN_UPDATE: - - /* Get saturation status of gyroscope user gain update */ - rslt = get_gyro_gain_update_status(&sensor_data[loop].sens_data.gyro_user_gain_status, dev); - break; - case BMI2_NVM_STATUS: - - /* Get NVM error status */ - rslt = get_nvm_error_status(&sensor_data[loop].sens_data.nvm_status, dev); - break; - case BMI2_VFRM_STATUS: - - /* Get VFRM error status */ - rslt = get_vfrm_error_status(&sensor_data[loop].sens_data.vfrm_status, dev); - break; - case BMI2_WRIST_GESTURE: - case BMI2_WRIST_GESTURE_WH: - - /* Get wrist gesture status */ - rslt = get_wrist_gest_status(&sensor_data[loop].sens_data.wrist_gesture_output, dev); - break; - case BMI2_GYRO_CROSS_SENSE: - - /* Get Gyroscope cross sense value of z axis */ - rslt = get_gyro_cross_sense(&sensor_data[loop].sens_data.correction_factor_zx, dev); - break; - case BMI2_ACCEL_SELF_TEST: - - /* Get accelerometer self-test */ - rslt = get_accel_self_test_status(&sensor_data[loop].sens_data.accel_self_test_output, dev); - break; - case BMI2_OIS_OUTPUT: - - /* Get OIS accel and gyro x,y,z data */ - rslt = get_ois_output(&sensor_data[loop].sens_data.ois_output, dev); - break; - default: - rslt = BMI2_E_INVALID_SENSOR; - break; - } - - /* Return error if any of the get sensor data fails */ - if (rslt != BMI2_OK) - { - break; - } - } - - /* Enable Advance power save if disabled while - * configuring and not when already disabled - */ - if ((aps_stat == BMI2_ENABLE) && (rslt == BMI2_OK)) - { - rslt = bmi2_set_adv_power_save(BMI2_ENABLE, dev); - } - } - } - else - { - rslt = BMI2_E_NULL_PTR; - } - - return rslt; -} - -/*! - * @brief This API enables/disables the advance power save mode in the sensor. - */ -int8_t bmi2_set_adv_power_save(uint8_t enable, struct bmi2_dev *dev) -{ - /* Variable to define error */ - int8_t rslt; - - /* Variable to store data */ - uint8_t reg_data = 0; - - /* Null-pointer check */ - rslt = null_ptr_check(dev); - if (rslt == BMI2_OK) - { - rslt = bmi2_get_regs(BMI2_PWR_CONF_ADDR, ®_data, 1, dev); - if (rslt == BMI2_OK) - { - reg_data = BMI2_SET_BIT_POS0(reg_data, BMI2_ADV_POW_EN, enable); - rslt = bmi2_set_regs(BMI2_PWR_CONF_ADDR, ®_data, 1, dev); - dev->delay_us(500, dev->intf_ptr); - if (rslt != BMI2_OK) - { - /* Return error if enable/disable APS fails */ - rslt = BMI2_E_SET_APS_FAIL; - } - - if (rslt == BMI2_OK) - { - dev->aps_status = BMI2_GET_BIT_POS0(reg_data, BMI2_ADV_POW_EN); - } - } - } - - return rslt; -} - -/*! - * @brief This API gets the status of advance power save mode in the sensor. - */ -int8_t bmi2_get_adv_power_save(uint8_t *aps_status, struct bmi2_dev *dev) -{ - /* Variable to define error */ - int8_t rslt; - - /* Variable to store data */ - uint8_t reg_data = 0; - - /* Null-pointer check */ - rslt = null_ptr_check(dev); - if ((rslt == BMI2_OK) && (aps_status != NULL)) - { - rslt = bmi2_get_regs(BMI2_PWR_CONF_ADDR, ®_data, 1, dev); - if (rslt == BMI2_OK) - { - *aps_status = BMI2_GET_BIT_POS0(reg_data, BMI2_ADV_POW_EN); - dev->aps_status = *aps_status; - } - } - else - { - rslt = BMI2_E_NULL_PTR; - } - - return rslt; -} - -/*! - * @brief This API loads the configuration file into the bmi2 sensor. - */ -int8_t bmi2_write_config_file(struct bmi2_dev *dev) -{ - /* Variable to define error */ - int8_t rslt; - - /* Variable to know the load status */ - uint8_t load_status = 0; - - /* Null-pointer check */ - rslt = null_ptr_check(dev); - if ((rslt == BMI2_OK) && (dev->config_size != 0)) - { - /* Bytes written are multiples of 2 */ - if ((dev->read_write_len % 2) != 0) - { - dev->read_write_len = dev->read_write_len - 1; - } - - if (dev->read_write_len < 2) - { - dev->read_write_len = 2; - } - - /* Write the configuration file */ - rslt = write_config_file(dev); - if (rslt == BMI2_OK) - { - /* Check the configuration load status */ - rslt = bmi2_get_internal_status(&load_status, dev); - - /* Return error if loading not successful */ - if ((rslt == BMI2_OK) && (!(load_status & BMI2_CONFIG_LOAD_SUCCESS))) - { - rslt = BMI2_E_CONFIG_LOAD; - } - } - } - else - { - rslt = BMI2_E_NULL_PTR; - } - - return rslt; -} - -/*! - * @brief This API sets: - * 1) The input output configuration of the selected interrupt pin: - * INT1 or INT2. - * 2) The interrupt mode: permanently latched or non-latched. - */ -int8_t bmi2_set_int_pin_config(const struct bmi2_int_pin_config *int_cfg, struct bmi2_dev *dev) -{ - /* Variable to define error */ - int8_t rslt; - - /* Variable to define data array */ - uint8_t data_array[3] = { 0 }; - - /* Variable to store register data */ - uint8_t reg_data = 0; - - /* Variable to define type of interrupt pin */ - uint8_t int_pin = 0; - - /* Null-pointer check */ - rslt = null_ptr_check(dev); - if ((rslt == BMI2_OK) && (int_cfg != NULL)) - { - /* Copy the pin type to a local variable */ - int_pin = int_cfg->pin_type; - if ((int_pin > BMI2_INT_NONE) && (int_pin < BMI2_INT_PIN_MAX)) - { - /* Get the previous configuration data */ - rslt = bmi2_get_regs(BMI2_INT1_IO_CTRL_ADDR, data_array, 3, dev); - if (rslt == BMI2_OK) - { - /* Set interrupt pin 1 configuration */ - if ((int_pin == BMI2_INT1) || (int_pin == BMI2_INT_BOTH)) - { - /* Configure active low or high */ - reg_data = BMI2_SET_BITS(data_array[0], BMI2_INT_LEVEL, int_cfg->pin_cfg[0].lvl); - - /* Configure push-pull or open drain */ - reg_data = BMI2_SET_BITS(reg_data, BMI2_INT_OPEN_DRAIN, int_cfg->pin_cfg[0].od); - - /* Configure output enable */ - reg_data = BMI2_SET_BITS(reg_data, BMI2_INT_OUTPUT_EN, int_cfg->pin_cfg[0].output_en); - - /* Configure input enable */ - reg_data = BMI2_SET_BITS(reg_data, BMI2_INT_INPUT_EN, int_cfg->pin_cfg[0].input_en); - - /* Copy the data to be written in the respective array */ - data_array[0] = reg_data; - } - - /* Set interrupt pin 2 configuration */ - if ((int_pin == BMI2_INT2) || (int_pin == BMI2_INT_BOTH)) - { - /* Configure active low or high */ - reg_data = BMI2_SET_BITS(data_array[1], BMI2_INT_LEVEL, int_cfg->pin_cfg[1].lvl); - - /* Configure push-pull or open drain */ - reg_data = BMI2_SET_BITS(reg_data, BMI2_INT_OPEN_DRAIN, int_cfg->pin_cfg[1].od); - - /* Configure output enable */ - reg_data = BMI2_SET_BITS(reg_data, BMI2_INT_OUTPUT_EN, int_cfg->pin_cfg[1].output_en); - - /* Configure input enable */ - reg_data = BMI2_SET_BITS(reg_data, BMI2_INT_INPUT_EN, int_cfg->pin_cfg[1].input_en); - - /* Copy the data to be written in the respective array */ - data_array[1] = reg_data; - } - - /* Configure the interrupt mode */ - data_array[2] = BMI2_SET_BIT_POS0(data_array[2], BMI2_INT_LATCH, int_cfg->int_latch); - - /* Set the configurations simultaneously as - * INT1_IO_CTRL, INT2_IO_CTRL, and INT_LATCH lie - * in consecutive addresses - */ - rslt = bmi2_set_regs(BMI2_INT1_IO_CTRL_ADDR, data_array, 3, dev); - } - } - else - { - rslt = BMI2_E_INVALID_INT_PIN; - } - } - else - { - rslt = BMI2_E_NULL_PTR; - } - - return rslt; -} - -/*! - * @brief This API gets: - * 1) The input output configuration of the selected interrupt pin: - * INT1 or INT2. - * 2) The interrupt mode: permanently latched or non-latched. - */ -int8_t bmi2_get_int_pin_config(struct bmi2_int_pin_config *int_cfg, struct bmi2_dev *dev) -{ - /* Variable to define error */ - int8_t rslt; - - /* Variable to define data array */ - uint8_t data_array[3] = { 0 }; - - /* Variable to define type of interrupt pin */ - uint8_t int_pin = 0; - - /* Null-pointer check */ - rslt = null_ptr_check(dev); - if ((rslt == BMI2_OK) && (int_cfg != NULL)) - { - /* Copy the pin type to a local variable */ - int_pin = int_cfg->pin_type; - - /* Get the previous configuration data */ - rslt = bmi2_get_regs(BMI2_INT1_IO_CTRL_ADDR, data_array, 3, dev); - if (rslt == BMI2_OK) - { - /* Get interrupt pin 1 configuration */ - if ((int_pin == BMI2_INT1) || (int_pin == BMI2_INT_BOTH)) - { - /* Get active low or high */ - int_cfg->pin_cfg[0].lvl = BMI2_GET_BITS(data_array[0], BMI2_INT_LEVEL); - - /* Get push-pull or open drain */ - int_cfg->pin_cfg[0].od = BMI2_GET_BITS(data_array[0], BMI2_INT_OPEN_DRAIN); - - /* Get output enable */ - int_cfg->pin_cfg[0].output_en = BMI2_GET_BITS(data_array[0], BMI2_INT_OUTPUT_EN); - - /* Get input enable */ - int_cfg->pin_cfg[0].input_en = BMI2_GET_BITS(data_array[0], BMI2_INT_INPUT_EN); - } - - /* Get interrupt pin 2 configuration */ - if ((int_pin == BMI2_INT2) || (int_pin == BMI2_INT_BOTH)) - { - /* Get active low or high */ - int_cfg->pin_cfg[1].lvl = BMI2_GET_BITS(data_array[1], BMI2_INT_LEVEL); - - /* Get push-pull or open drain */ - int_cfg->pin_cfg[1].od = BMI2_GET_BITS(data_array[1], BMI2_INT_OPEN_DRAIN); - - /* Get output enable */ - int_cfg->pin_cfg[1].output_en = BMI2_GET_BITS(data_array[1], BMI2_INT_OUTPUT_EN); - - /* Get input enable */ - int_cfg->pin_cfg[1].input_en = BMI2_GET_BITS(data_array[1], BMI2_INT_INPUT_EN); - } - - /* Get interrupt mode */ - int_cfg->int_latch = BMI2_GET_BIT_POS0(data_array[2], BMI2_INT_LATCH); - } - } - else - { - rslt = BMI2_E_NULL_PTR; - } - - return rslt; -} - -/*! - * @brief This API gets the interrupt status of both feature and data - * interrupts - */ -int8_t bmi2_get_int_status(uint16_t *int_status, struct bmi2_dev *dev) -{ - /* Variable to define error */ - int8_t rslt; - - /* Array to store data */ - uint8_t data_array[2] = { 0 }; - - /* Null-pointer check */ - rslt = null_ptr_check(dev); - if ((rslt == BMI2_OK) && (int_status != NULL)) - { - /* Get the interrupt status */ - rslt = bmi2_get_regs(BMI2_INT_STATUS_0_ADDR, data_array, 2, dev); - if (rslt == BMI2_OK) - { - *int_status = (uint16_t) data_array[0] | ((uint16_t) data_array[1] << 8); - } - } - else - { - rslt = BMI2_E_NULL_PTR; - } - - return rslt; -} - -/*! - * @brief This API sets the FIFO configuration in the sensor. - */ -int8_t bmi2_set_fifo_config(uint16_t config, uint8_t enable, struct bmi2_dev *dev) -{ - int8_t rslt; - uint8_t data[2] = { 0 }; - uint8_t max_burst_len = 0; - - /* Variable to store data of FIFO configuration register 0 */ - uint8_t fifo_config_0 = (uint8_t)(config & BMI2_FIFO_CONFIG_0_MASK); - - /* Variable to store data of FIFO configuration register 1 */ - uint8_t fifo_config_1 = (uint8_t)((config & BMI2_FIFO_CONFIG_1_MASK) >> 8); - - rslt = null_ptr_check(dev); - if (rslt == BMI2_OK) - { - rslt = bmi2_get_regs(BMI2_FIFO_CONFIG_0_ADDR, data, BMI2_FIFO_CONFIG_LENGTH, dev); - if (rslt == BMI2_OK) - { - /* Get data to set FIFO configuration register 0 */ - if (fifo_config_0 > 0) - { - if (enable == BMI2_ENABLE) - { - data[0] = data[0] | fifo_config_0; - } - else - { - data[0] = data[0] & (~fifo_config_0); - } - } - - /* Get data to set FIFO configuration register 1 */ - if (enable == BMI2_ENABLE) - { - data[1] = data[1] | fifo_config_1; - if (dev->variant_feature & BMI2_CRT_RTOSK_ENABLE) - { - - /* Burst length is needed for CRT - * FIFO enable will reset the default values - * So configure the max burst length again. - */ - rslt = get_maxburst_len(&max_burst_len, dev); - if (rslt == BMI2_OK && max_burst_len == 0) - { - rslt = set_maxburst_len(BMI2_CRT_MIN_BURST_WORD_LENGTH, dev); - } - } - } - else - { - data[1] = data[1] & (~fifo_config_1); - } - - /* Set the FIFO configurations */ - if (rslt == BMI2_OK) - { - rslt = bmi2_set_regs(BMI2_FIFO_CONFIG_0_ADDR, data, 2, dev); - } - } - } - - return rslt; -} - -/*! - * @brief This API reads the FIFO configuration from the sensor. - */ -int8_t bmi2_get_fifo_config(uint16_t *fifo_config, struct bmi2_dev *dev) -{ - /* Variable to define error */ - int8_t rslt; - - /* Array to store data */ - uint8_t data[2] = { 0 }; - - /* Null-pointer check */ - rslt = null_ptr_check(dev); - if ((rslt == BMI2_OK) && (fifo_config != NULL)) - { - /* Get the FIFO configuration value */ - rslt = bmi2_get_regs(BMI2_FIFO_CONFIG_0_ADDR, data, BMI2_FIFO_CONFIG_LENGTH, dev); - if (rslt == BMI2_OK) - { - (*fifo_config) = (uint16_t)((uint16_t) data[0] & BMI2_FIFO_CONFIG_0_MASK); - (*fifo_config) |= (uint16_t)(((uint16_t) data[1] << 8) & BMI2_FIFO_CONFIG_1_MASK); - } - } - else - { - rslt = BMI2_E_NULL_PTR; - } - - return rslt; -} - -/*! - * @brief This API reads the FIFO data. - */ -int8_t bmi2_read_fifo_data(struct bmi2_fifo_frame *fifo, struct bmi2_dev *dev) -{ - /* Variable to define error */ - int8_t rslt; - - /* Array to store FIFO configuration data */ - uint8_t config_data[2] = { 0 }; - - /* Variable to define FIFO address */ - uint8_t addr = BMI2_FIFO_DATA_ADDR; - - /* Null-pointer check */ - rslt = null_ptr_check(dev); - if ((rslt == BMI2_OK) && (fifo != NULL)) - { - /* Clear the FIFO data structure */ - reset_fifo_frame_structure(fifo, dev); - - /* Read FIFO data */ - rslt = bmi2_get_regs(addr, fifo->data, fifo->length, dev); - if (rslt == BMI2_OK) - { - - /* Get the set FIFO frame configurations */ - rslt = bmi2_get_regs(BMI2_FIFO_CONFIG_0_ADDR, config_data, 2, dev); - if (rslt == BMI2_OK) - { - /* Get FIFO header status */ - fifo->header_enable = (uint8_t)((config_data[1]) & (BMI2_FIFO_HEADER_EN >> 8)); - - /* Get sensor enable status, of which the data is to be read */ - fifo->data_enable = - (uint16_t)(((config_data[0]) | ((uint16_t) config_data[1] << 8)) & BMI2_FIFO_ALL_EN); - } - } - else - { - rslt = BMI2_E_COM_FAIL; - } - } - else - { - rslt = BMI2_E_NULL_PTR; - } - - return rslt; -} - -/*! - * @brief This API parses and extracts the accelerometer frames from FIFO data - * read by the "bmi2_read_fifo_data" API and stores it in the "accel_data" - * structure instance. - */ -int8_t bmi2_extract_accel(struct bmi2_sens_axes_data *accel_data, - uint16_t *accel_length, - struct bmi2_fifo_frame *fifo, - const struct bmi2_dev *dev) -{ - /* Variable to define error */ - int8_t rslt; - - /* Variable to index the bytes */ - uint16_t data_index = 0; - - /* Variable to index accelerometer frames */ - uint16_t accel_index = 0; - - /* Variable to store the number of bytes to be read */ - uint16_t data_read_length = 0; - - /* Variable to define the data enable byte */ - uint8_t data_enable = 0; - - /* Null-pointer check */ - rslt = null_ptr_check(dev); - if ((rslt == BMI2_OK) && (accel_data != NULL) && (accel_length != NULL) && (fifo != NULL)) - { - /* Parsing the FIFO data in header-less mode */ - if (fifo->header_enable == 0) - { - - /* Get the number of accelerometer bytes to be read */ - rslt = parse_fifo_accel_len(&data_index, &data_read_length, accel_length, fifo); - - /* Convert word to byte since all sensor enables are in a byte */ - data_enable = (uint8_t)(fifo->data_enable >> 8); - for (; (data_index < data_read_length) && (rslt != BMI2_W_FIFO_EMPTY);) - { - /* Unpack frame to get the accelerometer data */ - rslt = unpack_accel_frame(accel_data, &data_index, &accel_index, data_enable, fifo, dev); - if (rslt != BMI2_W_FIFO_EMPTY) - { - /* Check for the availability of next two bytes of FIFO data */ - rslt = check_empty_fifo(&data_index, fifo); - } - } - - /* Update number of accelerometer frames to be read */ - (*accel_length) = accel_index; - - /* Update the accelerometer byte index */ - fifo->acc_byte_start_idx = data_index; - } - else - { - /* Parsing the FIFO data in header mode */ - rslt = extract_accel_header_mode(accel_data, accel_length, fifo, dev); - } - } - else - { - rslt = BMI2_E_NULL_PTR; - } - - return rslt; -} - -/*! - * @brief This API parses and extracts the gyroscope frames from FIFO data - * read by the "bmi2_read_fifo_data" API and stores it in the "gyro_data" - * structure instance. - */ -int8_t bmi2_extract_gyro(struct bmi2_sens_axes_data *gyro_data, - uint16_t *gyro_length, - struct bmi2_fifo_frame *fifo, - const struct bmi2_dev *dev) -{ - /* Variable to define error */ - int8_t rslt; - - /* Variable to index the bytes */ - uint16_t data_index = 0; - - /* Variable to index gyroscope frames */ - uint16_t gyro_index = 0; - - /* Variable to store the number of bytes to be read */ - uint16_t data_read_length = 0; - - /* Variable to define the data enable byte */ - uint8_t data_enable = 0; - - /* Null-pointer check */ - rslt = null_ptr_check(dev); - if ((rslt == BMI2_OK) && (gyro_data != NULL) && (gyro_length != NULL) && (fifo != NULL)) - { - /* Parsing the FIFO data in header-less mode */ - if (fifo->header_enable == 0) - { - /* Get the number of gyro bytes to be read */ - rslt = parse_fifo_gyro_len(&data_index, &data_read_length, gyro_length, fifo); - - /* Convert word to byte since all sensor enables are in a byte */ - data_enable = (uint8_t)(fifo->data_enable >> 8); - for (; (data_index < data_read_length) && (rslt != BMI2_W_FIFO_EMPTY);) - { - /* Unpack frame to get gyroscope data */ - rslt = unpack_gyro_frame(gyro_data, &data_index, &gyro_index, data_enable, fifo, dev); - if (rslt != BMI2_W_FIFO_EMPTY) - { - /* Check for the availability of next two bytes of FIFO data */ - rslt = check_empty_fifo(&data_index, fifo); - } - } - - /* Update number of gyroscope frames to be read */ - (*gyro_length) = gyro_index; - - /* Update the gyroscope byte index */ - fifo->acc_byte_start_idx = data_index; - } - else - { - /* Parsing the FIFO data in header mode */ - rslt = extract_gyro_header_mode(gyro_data, gyro_length, fifo, dev); - } - } - else - { - rslt = BMI2_E_NULL_PTR; - } - - return rslt; -} - -/*! - * @brief This API parses and extracts the auxiliary frames from FIFO data - * read by the "bmi2_read_fifo_data" API and stores it in "aux_data" buffer. - */ -int8_t bmi2_extract_aux(struct bmi2_aux_fifo_data *aux, - uint16_t *aux_length, - struct bmi2_fifo_frame *fifo, - const struct bmi2_dev *dev) -{ - /* Variable to define error */ - int8_t rslt; - - /* Variable to index the bytes */ - uint16_t data_index = 0; - - /* Variable to index auxiliary frames */ - uint16_t aux_index = 0; - - /* Variable to store the number of bytes to be read */ - uint16_t data_read_length = 0; - - /* Variable to define the data enable byte */ - uint8_t data_enable = 0; - - /* Null-pointer check */ - rslt = null_ptr_check(dev); - if ((rslt == BMI2_OK) && (aux != NULL) && (aux_length != NULL) && (fifo != NULL)) - { - /* Parsing the FIFO data in header-less mode */ - if (fifo->header_enable == 0) - { - rslt = parse_fifo_aux_len(&data_index, &data_read_length, aux_length, fifo); - - /* Convert word to byte since all sensor enables are in - * a byte - */ - data_enable = (uint8_t)(fifo->data_enable >> 8); - for (; (data_index < data_read_length) && (rslt != BMI2_W_FIFO_EMPTY);) - { - /* Unpack frame to get auxiliary data */ - rslt = unpack_aux_frame(aux, &data_index, &aux_index, data_enable, fifo, dev); - if (rslt != BMI2_W_FIFO_EMPTY) - { - /* Check for the availability of next - * two bytes of FIFO data - */ - rslt = check_empty_fifo(&data_index, fifo); - } - } - - /* Update number of auxiliary frames to be read */ - *aux_length = aux_index; - - /* Update the auxiliary byte index */ - fifo->aux_byte_start_idx = data_index; - } - else - { - /* Parsing the FIFO data in header mode */ - rslt = extract_aux_header_mode(aux, aux_length, fifo, dev); - } - } - else - { - rslt = BMI2_E_NULL_PTR; - } - - return rslt; -} - -/*! - * @brief This API writes the available sensor specific commands to the sensor. - */ -int8_t bmi2_set_command_register(uint8_t command, struct bmi2_dev *dev) -{ - /* Variable to define error */ - int8_t rslt; - - /* Null-pointer check */ - rslt = null_ptr_check(dev); - if (rslt == BMI2_OK) - { - /* Set the command in the command register */ - rslt = bmi2_set_regs(BMI2_CMD_REG_ADDR, &command, 1, dev); - } - - return rslt; -} - -/* - * @brief This API sets the FIFO self wake up functionality in the sensor. - */ -int8_t bmi2_set_fifo_self_wake_up(uint8_t fifo_self_wake_up, struct bmi2_dev *dev) -{ - /* Variable to define error */ - int8_t rslt; - - /* Variable to store data */ - uint8_t data = 0; - - /* Null-pointer check */ - rslt = null_ptr_check(dev); - if (rslt == BMI2_OK) - { - /* Set FIFO self wake-up */ - rslt = bmi2_get_regs(BMI2_PWR_CONF_ADDR, &data, 1, dev); - if (rslt == BMI2_OK) - { - data = BMI2_SET_BITS(data, BMI2_FIFO_SELF_WAKE_UP, fifo_self_wake_up); - rslt = bmi2_set_regs(BMI2_PWR_CONF_ADDR, &data, 1, dev); - } - } - - return rslt; -} - -/*! - * @brief This API gets the status of FIFO self wake up functionality from - * the sensor. - */ -int8_t bmi2_get_fifo_self_wake_up(uint8_t *fifo_self_wake_up, struct bmi2_dev *dev) -{ - /* Variable to define error */ - int8_t rslt; - - /* Variable to store data */ - uint8_t data = 0; - - /* Null-pointer check */ - rslt = null_ptr_check(dev); - if ((rslt == BMI2_OK) && (fifo_self_wake_up != NULL)) - { - /* Get the status of FIFO self wake-up */ - rslt = bmi2_get_regs(BMI2_PWR_CONF_ADDR, &data, 1, dev); - if (rslt == BMI2_OK) - { - (*fifo_self_wake_up) = BMI2_GET_BITS(data, BMI2_FIFO_SELF_WAKE_UP); - } - } - else - { - rslt = BMI2_E_NULL_PTR; - } - - return rslt; -} - -/*! - * @brief This API sets the FIFO water-mark level in the sensor. - */ -int8_t bmi2_set_fifo_wm(uint16_t fifo_wm, struct bmi2_dev *dev) -{ - /* Variable to define error */ - int8_t rslt; - - /* Array to store data */ - uint8_t data[2] = { 0 }; - - /* Null-pointer check */ - rslt = null_ptr_check(dev); - if (rslt == BMI2_OK) - { - /* Get LSB value of FIFO water-mark */ - data[0] = BMI2_GET_LSB(fifo_wm); - - /* Get MSB value of FIFO water-mark */ - data[1] = BMI2_GET_MSB(fifo_wm); - - /* Set the FIFO water-mark level */ - rslt = bmi2_set_regs(BMI2_FIFO_WTM_0_ADDR, data, 2, dev); - } - - return rslt; -} - -/*! - * @brief This API reads the FIFO water mark level set in the sensor. - */ -int8_t bmi2_get_fifo_wm(uint16_t *fifo_wm, struct bmi2_dev *dev) -{ - /* Variable to define error */ - int8_t rslt; - - /* Array to to store data */ - uint8_t data[2] = { 0 }; - - /* Null-pointer check */ - rslt = null_ptr_check(dev); - if ((rslt == BMI2_OK) && (fifo_wm != NULL)) - { - /* Read the FIFO water mark level */ - rslt = bmi2_get_regs(BMI2_FIFO_WTM_0_ADDR, data, BMI2_FIFO_WM_LENGTH, dev); - if (rslt == BMI2_OK) - { - (*fifo_wm) = (uint16_t)((uint16_t) data[1] << 8) | (data[0]); - } - } - else - { - rslt = BMI2_E_NULL_PTR; - } - - return rslt; -} - -/*! - * @brief This API sets either filtered or un-filtered FIFO accelerometer or - * gyroscope data. - */ -int8_t bmi2_set_fifo_filter_data(uint8_t sens_sel, uint8_t fifo_filter_data, struct bmi2_dev *dev) -{ - /* Variable to define error */ - int8_t rslt; - - /* Variable to store data */ - uint8_t data = 0; - - /* Null-pointer check */ - rslt = null_ptr_check(dev); - if (rslt == BMI2_OK) - { - switch (sens_sel) - { - case BMI2_ACCEL: - - /* Validate filter mode */ - if (fifo_filter_data <= BMI2_MAX_VALUE_FIFO_FILTER) - { - /* Set the accelerometer FIFO filter data */ - rslt = bmi2_get_regs(BMI2_FIFO_DOWNS_ADDR, &data, 1, dev); - if (rslt == BMI2_OK) - { - data = BMI2_SET_BITS(data, BMI2_ACC_FIFO_FILT_DATA, fifo_filter_data); - rslt = bmi2_set_regs(BMI2_FIFO_DOWNS_ADDR, &data, 1, dev); - } - } - else - { - rslt = BMI2_E_OUT_OF_RANGE; - } - - break; - case BMI2_GYRO: - - /* Validate filter mode */ - if (fifo_filter_data <= BMI2_MAX_VALUE_FIFO_FILTER) - { - /* Set the gyroscope FIFO filter data */ - rslt = bmi2_get_regs(BMI2_FIFO_DOWNS_ADDR, &data, 1, dev); - if (rslt == BMI2_OK) - { - data = BMI2_SET_BITS(data, BMI2_GYR_FIFO_FILT_DATA, fifo_filter_data); - rslt = bmi2_set_regs(BMI2_FIFO_DOWNS_ADDR, &data, 1, dev); - } - } - else - { - rslt = BMI2_E_OUT_OF_RANGE; - } - - break; - default: - rslt = BMI2_E_INVALID_SENSOR; - break; - } - } - - return rslt; -} - -/*! - * @brief This API gets the FIFO accelerometer or gyroscope filter data. - */ -int8_t bmi2_get_fifo_filter_data(uint8_t sens_sel, uint8_t *fifo_filter_data, struct bmi2_dev *dev) -{ - /* Variable to define error */ - int8_t rslt; - - /* Variable to store FIFO filter mode */ - uint8_t data = 0; - - /* Null-pointer check */ - rslt = null_ptr_check(dev); - if ((rslt == BMI2_OK) && (fifo_filter_data != NULL)) - { - switch (sens_sel) - { - case BMI2_ACCEL: - - /* Read the accelerometer FIFO filter data */ - rslt = bmi2_get_regs(BMI2_FIFO_DOWNS_ADDR, &data, 1, dev); - if (rslt == BMI2_OK) - { - (*fifo_filter_data) = BMI2_GET_BITS(data, BMI2_ACC_FIFO_FILT_DATA); - } - - break; - case BMI2_GYRO: - - /* Read the gyroscope FIFO filter data */ - rslt = bmi2_get_regs(BMI2_FIFO_DOWNS_ADDR, &data, 1, dev); - if (rslt == BMI2_OK) - { - (*fifo_filter_data) = BMI2_GET_BITS(data, BMI2_GYR_FIFO_FILT_DATA); - } - - break; - default: - rslt = BMI2_E_INVALID_SENSOR; - break; - } - } - else - { - rslt = BMI2_E_NULL_PTR; - } - - return rslt; -} - -/*! - * @brief This API sets the down-sampling rates for accelerometer or gyroscope - * FIFO data. - */ -int8_t bmi2_set_fifo_down_sample(uint8_t sens_sel, uint8_t fifo_down_samp, struct bmi2_dev *dev) -{ - /* Variable to define error */ - int8_t rslt; - - /* Variable to store sampling rate */ - uint8_t data = 0; - - /* Null-pointer check */ - rslt = null_ptr_check(dev); - if (rslt == BMI2_OK) - { - switch (sens_sel) - { - case BMI2_ACCEL: - - /* Set the accelerometer FIFO down sampling rate */ - rslt = bmi2_get_regs(BMI2_FIFO_DOWNS_ADDR, &data, 1, dev); - if (rslt == BMI2_OK) - { - data = BMI2_SET_BITS(data, BMI2_ACC_FIFO_DOWNS, fifo_down_samp); - rslt = bmi2_set_regs(BMI2_FIFO_DOWNS_ADDR, &data, 1, dev); - } - - break; - case BMI2_GYRO: - - /* Set the gyroscope FIFO down sampling rate */ - rslt = bmi2_get_regs(BMI2_FIFO_DOWNS_ADDR, &data, 1, dev); - if (rslt == BMI2_OK) - { - data = BMI2_SET_BIT_POS0(data, BMI2_GYR_FIFO_DOWNS, fifo_down_samp); - rslt = bmi2_set_regs(BMI2_FIFO_DOWNS_ADDR, &data, 1, dev); - } - - break; - default: - rslt = BMI2_E_INVALID_SENSOR; - break; - } - } - - return rslt; -} - -/*! - * @brief This API reads the down sampling rates which is configured for - * accelerometer or gyroscope FIFO data. - */ -int8_t bmi2_get_fifo_down_sample(uint8_t sens_sel, uint8_t *fifo_down_samp, struct bmi2_dev *dev) -{ - /* Variable to define error */ - int8_t rslt; - - /* Variable to store sampling rate */ - uint8_t data = 0; - - /* Null-pointer check */ - rslt = null_ptr_check(dev); - if ((rslt == BMI2_OK) && (fifo_down_samp != NULL)) - { - switch (sens_sel) - { - case BMI2_ACCEL: - - /* Read the accelerometer FIFO down data sampling rate */ - rslt = bmi2_get_regs(BMI2_FIFO_DOWNS_ADDR, &data, 1, dev); - if (rslt == BMI2_OK) - { - (*fifo_down_samp) = BMI2_GET_BITS(data, BMI2_ACC_FIFO_DOWNS); - } - - break; - case BMI2_GYRO: - - /* Read the gyroscope FIFO down data sampling rate */ - rslt = bmi2_get_regs(BMI2_FIFO_DOWNS_ADDR, &data, 1, dev); - if (rslt == BMI2_OK) - { - (*fifo_down_samp) = BMI2_GET_BIT_POS0(data, BMI2_GYR_FIFO_DOWNS); - } - - break; - default: - rslt = BMI2_E_INVALID_SENSOR; - break; - } - } - else - { - rslt = BMI2_E_NULL_PTR; - } - - return rslt; -} - -/*! - * @brief This API gets the length of FIFO data available in the sensor in - * bytes. - */ -int8_t bmi2_get_fifo_length(uint16_t *fifo_length, struct bmi2_dev *dev) -{ - /* Variable to define error */ - int8_t rslt; - - /* Variable to define byte index */ - uint8_t index = 0; - - /* Array to store FIFO data length */ - uint8_t data[BMI2_FIFO_DATA_LENGTH] = { 0 }; - - /* Null-pointer check */ - rslt = null_ptr_check(dev); - if ((rslt == BMI2_OK) && (fifo_length != NULL)) - { - /* Read FIFO length */ - rslt = bmi2_get_regs(BMI2_FIFO_LENGTH_0_ADDR, data, BMI2_FIFO_DATA_LENGTH, dev); - if (rslt == BMI2_OK) - { - /* Get the MSB byte index */ - index = BMI2_FIFO_LENGTH_MSB_BYTE; - - /* Get the MSB byte of FIFO length */ - data[index] = BMI2_GET_BIT_POS0(data[index], BMI2_FIFO_BYTE_COUNTER_MSB); - - /* Get total FIFO length */ - (*fifo_length) = ((data[index] << 8) | data[index - 1]); - } - } - else - { - rslt = BMI2_E_NULL_PTR; - } - - return rslt; -} - -/*! - * @brief This API reads the user-defined bytes of data from the given register - * address of auxiliary sensor in manual mode. - * - * @note Change of BMI2_AUX_RD_ADDR is only allowed if AUX is not busy. - */ -int8_t bmi2_read_aux_man_mode(uint8_t reg_addr, uint8_t *aux_data, uint16_t len, struct bmi2_dev *dev) -{ - /* Variable to define error */ - int8_t rslt; - - /* Variable to store burst length */ - uint8_t burst_len = 0; - - /* Variable to define APS status */ - uint8_t aps_stat = 0; - - /* Null-pointer check */ - rslt = null_ptr_check(dev); - if ((rslt == BMI2_OK) && (aux_data != NULL)) - { - /* Validate if manual mode */ - if (dev->aux_man_en) - { - /* Get status of advance power save mode */ - aps_stat = dev->aps_status; - if (aps_stat == BMI2_ENABLE) - { - /* Disable APS if enabled */ - rslt = bmi2_set_adv_power_save(BMI2_DISABLE, dev); - } - - if (rslt == BMI2_OK) - { - /* Map the register value set to that of burst - * length - */ - rslt = map_read_len(&burst_len, dev); - if (rslt == BMI2_OK) - { - /* Read auxiliary data */ - rslt = read_aux_data(reg_addr, aux_data, len, burst_len, dev); - } - } - - /* Enable Advance power save if disabled for reading - * data and not when already disabled - */ - if ((rslt == BMI2_OK) && (aps_stat == BMI2_ENABLE)) - { - rslt = bmi2_set_adv_power_save(BMI2_ENABLE, dev); - } - } - else - { - rslt = BMI2_E_AUX_INVALID_CFG; - } - } - else - { - rslt = BMI2_E_NULL_PTR; - } - - return rslt; -} - -/*! - * @brief This API writes the user-defined bytes of data and the address of - * auxiliary sensor where data is to be written in manual mode. - * - * @note Change of BMI2_AUX_WR_ADDR is only allowed if AUX is not busy. - */ -int8_t bmi2_write_aux_man_mode(uint8_t reg_addr, const uint8_t *aux_data, uint16_t len, struct bmi2_dev *dev) -{ - /* Variable to define error */ - int8_t rslt; - - /* Variable to define loop */ - uint8_t loop = 0; - - /* Variable to define APS status */ - uint8_t aps_stat = 0; - - /* Null-pointer check */ - rslt = null_ptr_check(dev); - if ((rslt == BMI2_OK) && (aux_data != NULL)) - { - /* Validate if manual mode */ - if (dev->aux_man_en) - { - /* Get status of advance power save mode */ - aps_stat = dev->aps_status; - if (aps_stat == BMI2_ENABLE) - { - /* Disable APS if enabled */ - rslt = bmi2_set_adv_power_save(BMI2_DISABLE, dev); - } - - /* Byte write data in the corresponding address */ - if (rslt == BMI2_OK) - { - for (; ((loop < len) && (rslt == BMI2_OK)); loop++) - { - rslt = write_aux_data((reg_addr + loop), aux_data[loop], dev); - dev->delay_us(1000, dev->intf_ptr); - } - } - - /* Enable Advance power save if disabled for writing - * data and not when already disabled - */ - if ((rslt == BMI2_OK) && (aps_stat == BMI2_ENABLE)) - { - rslt = bmi2_set_adv_power_save(BMI2_ENABLE, dev); - } - } - else - { - rslt = BMI2_E_AUX_INVALID_CFG; - } - } - else - { - rslt = BMI2_E_NULL_PTR; - } - - return rslt; -} - -/*! - * @brief This API writes the user-defined bytes of data and the address of - * auxiliary sensor where data is to be written, from an interleaved input, - * in manual mode. - * - * @note Change of BMI2_AUX_WR_ADDR is only allowed if AUX is not busy. - */ -int8_t bmi2_write_aux_interleaved(uint8_t reg_addr, const uint8_t *aux_data, uint16_t len, struct bmi2_dev *dev) -{ - /* Variable to define error */ - int8_t rslt; - - /* Variable to define loop */ - uint8_t loop = 1; - - /* Variable to define APS status */ - uint8_t aps_stat = 0; - - /* Null-pointer check */ - rslt = null_ptr_check(dev); - if ((rslt == BMI2_OK) && (aux_data != NULL)) - { - /* Validate if manual mode */ - if (dev->aux_man_en) - { - /* Get status of advance power save mode */ - aps_stat = dev->aps_status; - if (aps_stat == BMI2_ENABLE) - { - /* Disable APS if enabled */ - rslt = bmi2_set_adv_power_save(BMI2_DISABLE, dev); - } - - if (rslt == BMI2_OK) - { - /* Write the start register address extracted - * from the interleaved data - */ - rslt = write_aux_data(reg_addr, aux_data[0], dev); - - /* Extract the remaining address and data from - * the interleaved data and write it in the - * corresponding addresses byte by byte - */ - for (; ((loop < len) && (rslt == BMI2_OK)); loop += 2) - { - rslt = write_aux_data(aux_data[loop], aux_data[loop + 1], dev); - dev->delay_us(1000, dev->intf_ptr); - } - - /* Enable Advance power save if disabled for - * writing data and not when already disabled - */ - if ((rslt == BMI2_OK) && (aps_stat == BMI2_ENABLE)) - { - rslt = bmi2_set_adv_power_save(BMI2_ENABLE, dev); - } - } - } - else - { - rslt = BMI2_E_AUX_INVALID_CFG; - } - } - else - { - rslt = BMI2_E_NULL_PTR; - } - - return rslt; -} - -/*! - * @brief This API gets the data ready status of accelerometer, gyroscope, - * auxiliary, command decoder and busy status of auxiliary. - */ -int8_t bmi2_get_status(uint8_t *status, struct bmi2_dev *dev) -{ - /* Variable to define error */ - int8_t rslt; - - /* Null-pointer check */ - rslt = null_ptr_check(dev); - if ((rslt == BMI2_OK) && (status != NULL)) - { - rslt = bmi2_get_regs(BMI2_STATUS_ADDR, status, 1, dev); - } - else - { - rslt = BMI2_E_NULL_PTR; - } - - return rslt; -} - -/*! - * @brief This API enables/disables OIS interface. - */ -int8_t bmi2_set_ois_interface(uint8_t enable, struct bmi2_dev *dev) -{ - /* Variable to define error */ - int8_t rslt; - - /* Variable to store data */ - uint8_t reg_data = 0; - - /* Null-pointer check */ - rslt = null_ptr_check(dev); - if (rslt == BMI2_OK) - { - rslt = bmi2_get_regs(BMI2_IF_CONF_ADDR, ®_data, 1, dev); - if (rslt == BMI2_OK) - { - /* Enable/Disable OIS interface */ - reg_data = BMI2_SET_BITS(reg_data, BMI2_OIS_IF_EN, enable); - if (enable) - { - /* Disable auxiliary interface if OIS is enabled */ - reg_data = BMI2_SET_BIT_VAL0(reg_data, BMI2_AUX_IF_EN); - } - - /* Set the OIS interface configurations */ - rslt = bmi2_set_regs(BMI2_IF_CONF_ADDR, ®_data, 1, dev); - } - } - - return rslt; -} - -/*! - * @brief This API can be used to write sync commands like ODR, sync period, - * frequency and phase, resolution ratio, sync time and delay time. - */ -int8_t bmi2_write_sync_commands(const uint8_t *command, uint8_t n_comm, struct bmi2_dev *dev) -{ - /* Variable to define error */ - int8_t rslt; - - /* Null-pointer check */ - rslt = null_ptr_check(dev); - if ((rslt == BMI2_OK) && (command != NULL)) - { - rslt = bmi2_set_regs(BMI2_SYNC_COMMAND_ADDR, command, n_comm, dev); - } - else - { - rslt = BMI2_E_NULL_PTR; - } - - return rslt; -} - -/*! - * @brief This API performs self-test to check the proper functionality of the - * accelerometer sensor. - */ -int8_t bmi2_perform_accel_self_test(struct bmi2_dev *dev) -{ - /* Variable to define error */ - int8_t rslt; - - /* Variable to store self-test result */ - int8_t st_rslt = 0; - - /* Structure to define positive accelerometer axes */ - struct bmi2_sens_axes_data positive = { 0, 0, 0, 0 }; - - /* Structure to define negative accelerometer axes */ - struct bmi2_sens_axes_data negative = { 0, 0, 0, 0 }; - - /* Structure for difference of accelerometer values in g */ - struct bmi2_selftest_delta_limit accel_data_diff = { 0, 0, 0 }; - - /* Structure for difference of accelerometer values in mg */ - struct bmi2_selftest_delta_limit accel_data_diff_mg = { 0, 0, 0 }; - - /* Initialize the polarity of self-test as positive */ - int8_t sign = BMI2_ENABLE; - - /* Null-pointer check */ - rslt = null_ptr_check(dev); - if (rslt == BMI2_OK) - { - /* Sets the configuration required before enabling self-test */ - rslt = pre_self_test_config(dev); - - /* Wait for greater than 2 milliseconds */ - dev->delay_us(3000, dev->intf_ptr); - if (rslt == BMI2_OK) - { - do - { - /* Select positive first, then negative polarity - * after enabling self-test - */ - rslt = self_test_config((uint8_t) sign, dev); - if (rslt == BMI2_OK) - { - /* Wait for greater than 50 milli-sec */ - dev->delay_us(51000, dev->intf_ptr); - - /* If polarity is positive */ - if (sign == BMI2_ENABLE) - { - /* Read and store positive acceleration value */ - rslt = read_accel_xyz(&positive, dev); - } - /* If polarity is negative */ - else if (sign == BMI2_DISABLE) - { - /* Read and store negative acceleration value */ - rslt = read_accel_xyz(&negative, dev); - } - } - else - { - /* Break if error */ - break; - } - - /* Break if error */ - if (rslt != BMI2_OK) - { - break; - } - - /* Turn the polarity of self-test negative */ - sign--; - } while (sign >= 0); - if (rslt == BMI2_OK) - { - /* Subtract -ve acceleration values from that of +ve values */ - accel_data_diff.x = (positive.x) - (negative.x); - accel_data_diff.y = (positive.y) - (negative.y); - accel_data_diff.z = (positive.z) - (negative.z); - - /* Convert differences of acceleration values - * from 'g' to 'mg' - */ - convert_lsb_g(&accel_data_diff, &accel_data_diff_mg, dev); - - /* Validate self-test for acceleration values - * in mg and get the self-test result - */ - st_rslt = validate_self_test(&accel_data_diff_mg); - - /* Trigger a soft reset after performing self-test */ - rslt = bmi2_soft_reset(dev); - - /* Return the self-test result */ - if (rslt == BMI2_OK) - { - rslt = st_rslt; - } - } - } - } - - return rslt; -} - -/*! - * @brief This API maps/unmaps feature interrupts to that of interrupt pins. - */ -int8_t bmi2_map_feat_int(const struct bmi2_sens_int_config *sens_int, uint8_t n_sens, struct bmi2_dev *dev) -{ - /* Variable to define error */ - int8_t rslt; - - /* Variable to define loop */ - uint8_t loop; - - /* Variable to define the value of feature interrupts */ - uint8_t feat_int = 0; - - /* Variable to define the mask bits of feature interrupts */ - uint8_t feat_int_mask = 0; - - /* Array to store the interrupt mask bits */ - uint8_t data_array[2] = { 0 }; - - /* Null-pointer check */ - rslt = null_ptr_check(dev); - if ((rslt == BMI2_OK) && (sens_int != NULL)) - { - /* Read interrupt map1 and map2 and register */ - rslt = bmi2_get_regs(BMI2_INT1_MAP_FEAT_ADDR, data_array, 2, dev); - if (rslt == BMI2_OK) - { - for (loop = 0; loop < n_sens; loop++) - { - switch (sens_int[loop].type) - { - case BMI2_SIG_MOTION: - - /* Get the value of the feature interrupt to be mapped */ - feat_int = dev->int_map.sig_mot_out_conf; - break; - case BMI2_ANY_MOTION: - - /* Get the value of the feature interrupt to be mapped */ - feat_int = dev->int_map.any_mot_out_conf; - break; - case BMI2_NO_MOTION: - - /* Get the value of the feature interrupt to be mapped */ - feat_int = dev->int_map.no_mot_out_conf; - break; - case BMI2_STEP_DETECTOR: - case BMI2_STEP_COUNTER: - - /* Get the value of the feature interrupt to be mapped */ - feat_int = dev->int_map.step_det_out_conf; - break; - case BMI2_STEP_ACTIVITY: - - /* Get the value of the feature interrupt to be mapped */ - feat_int = dev->int_map.step_act_out_conf; - break; - case BMI2_TILT: - - /* Get the value of the feature interrupt to be mapped */ - feat_int = dev->int_map.tilt_out_conf; - break; - case BMI2_UP_HOLD_TO_WAKE: - - /* Get the value of the feature interrupt to be mapped */ - feat_int = dev->int_map.up_hold_to_wake_out_conf; - break; - case BMI2_GLANCE_DETECTOR: - - /* Get the value of the feature interrupt to be mapped */ - feat_int = dev->int_map.glance_out_conf; - break; - case BMI2_WAKE_UP: - case BMI2_SINGLE_TAP: - case BMI2_DOUBLE_TAP: - case BMI2_TRIPLE_TAP: - - /* Get the value of the feature interrupt to be mapped */ - feat_int = dev->int_map.wake_up_out_conf; - break; - case BMI2_ORIENTATION: - - /* Get the value of the feature interrupt to be mapped */ - feat_int = dev->int_map.orient_out_conf; - break; - case BMI2_HIGH_G: - - /* Get the value of the feature interrupt to be mapped */ - feat_int = dev->int_map.high_g_out_conf; - break; - case BMI2_LOW_G: - - /* Get the value of the feature interrupt to be mapped */ - feat_int = dev->int_map.low_g_out_conf; - break; - case BMI2_FLAT: - - /* Get the value of the feature interrupt to be mapped */ - feat_int = dev->int_map.flat_out_conf; - break; - case BMI2_EXT_SENS_SYNC: - - /* Get the value of the feature interrupt to be mapped */ - feat_int = dev->int_map.ext_sync_out_conf; - break; - case BMI2_WRIST_GESTURE: - - /* Get the value of the feature interrupt to be mapped */ - feat_int = dev->int_map.wrist_gest_out_conf; - break; - case BMI2_WRIST_WEAR_WAKE_UP: - - /* Get the value of the feature interrupt to be mapped */ - feat_int = dev->int_map.wrist_wear_wake_up_out_conf; - break; - case BMI2_WRIST_GESTURE_WH: - - /* Get the value of the feature interrupt to be mapped for wearable variant */ - feat_int = dev->int_map.wrist_gest_out_conf; - break; - case BMI2_WRIST_WEAR_WAKE_UP_WH: - - /* Get the value of the feature interrupt to be mapped for wearable variant */ - feat_int = dev->int_map.wrist_wear_wake_up_out_conf; - break; - case BMI2_FREE_FALL_DET: - - /* Get the value of the feature interrupt to be mapped for free-fall detection */ - feat_int = dev->int_map.freefall_out_conf; - break; - default: - rslt = BMI2_E_INVALID_SENSOR; - break; - } - - /* Map the features to the required interrupt */ - if (rslt != BMI2_E_INVALID_SENSOR) - { - if ((feat_int > BMI2_FEAT_BIT_DISABLE) && (feat_int < BMI2_FEAT_BIT_MAX)) - { - /* Get the interrupt mask */ - feat_int_mask = (uint8_t)((uint32_t) 1 << (feat_int - 1)); - - /* Map the interrupts */ - rslt = map_feat_int(data_array, sens_int[loop].hw_int_pin, feat_int_mask); - } - else - { - rslt = BMI2_E_INVALID_FEAT_BIT; - } - } - - /* Return error if interrupt mapping fails */ - if (rslt != BMI2_OK) - { - break; - } - } - - /* Map the interrupts to INT1 and INT2 map register */ - if (rslt == BMI2_OK) - { - rslt = bmi2_set_regs(BMI2_INT1_MAP_FEAT_ADDR, data_array, 2, dev); - } - } - } - else - { - rslt = BMI2_E_NULL_PTR; - } - - return rslt; -} - -/*! - * @brief This API maps/un-maps data interrupts to that of interrupt pins. - */ -int8_t bmi2_map_data_int(uint8_t data_int, enum bmi2_hw_int_pin int_pin, struct bmi2_dev *dev) -{ - /* Variable to define error */ - int8_t rslt; - - /* Variable to mask interrupt pin 1 - lower nibble */ - uint8_t int1_mask = data_int; - - /* Variable to mask interrupt pin 2 - higher nibble */ - uint8_t int2_mask = (uint8_t)(data_int << 4); - - /* Variable to store register data */ - uint8_t reg_data = 0; - - /* Read interrupt map1 and map2 and register */ - rslt = bmi2_get_regs(BMI2_INT_MAP_DATA_ADDR, ®_data, 1, dev); - if (rslt == BMI2_OK) - { - if (int_pin < BMI2_INT_PIN_MAX) - { - switch (int_pin) - { - case BMI2_INT_NONE: - - /* Un-Map the corresponding data - * interrupt to both interrupt pin 1 and 2 - */ - reg_data &= ~(int1_mask | int2_mask); - break; - case BMI2_INT1: - - /* Map the corresponding data interrupt to - * interrupt pin 1 - */ - reg_data |= int1_mask; - break; - case BMI2_INT2: - - /* Map the corresponding data interrupt to - * interrupt pin 2 - */ - reg_data |= int2_mask; - break; - case BMI2_INT_BOTH: - - /* Map the corresponding data - * interrupt to both interrupt pin 1 and 2 - */ - reg_data |= (int1_mask | int2_mask); - break; - default: - break; - } - - /* Set the interrupts in the map register */ - rslt = bmi2_set_regs(BMI2_INT_MAP_DATA_ADDR, ®_data, 1, dev); - } - else - { - /* Return error if invalid pin selection */ - rslt = BMI2_E_INVALID_INT_PIN; - } - } - - return rslt; -} - -/*! - * @brief This API gets the re-mapped x, y and z axes from the sensor and - * updates the values in the device structure. - */ -int8_t bmi2_get_remap_axes(struct bmi2_remap *remapped_axis, struct bmi2_dev *dev) -{ - /* Variable to define error */ - int8_t rslt; - - /* Initialize the local structure for axis re-mapping */ - struct bmi2_axes_remap remap = { 0, 0, 0, 0, 0, 0 }; - - /* Null-pointer check */ - rslt = null_ptr_check(dev); - if ((rslt == BMI2_OK) && (remapped_axis != NULL)) - { - /* Get the re-mapped axes from the sensor */ - rslt = get_remap_axes(&remap, dev); - if (rslt == BMI2_OK) - { - /* Store the re-mapped x-axis value in device structure - * and its user-value in the interface structure - */ - switch (remap.x_axis) - { - case BMI2_MAP_X_AXIS: - - /* If mapped to x-axis */ - dev->remap.x_axis = BMI2_MAP_X_AXIS; - remapped_axis->x = BMI2_X; - break; - case BMI2_MAP_Y_AXIS: - - /* If mapped to y-axis */ - dev->remap.x_axis = BMI2_MAP_Y_AXIS; - remapped_axis->x = BMI2_Y; - break; - case BMI2_MAP_Z_AXIS: - - /* If mapped to z-axis */ - dev->remap.x_axis = BMI2_MAP_Z_AXIS; - remapped_axis->x = BMI2_Z; - break; - default: - break; - } - - /* Store the re-mapped x-axis sign in device structure - * and its user-value in the interface structure - */ - if (remap.x_axis_sign) - { - /* If x-axis is mapped to -ve sign */ - dev->remap.x_axis_sign = BMI2_NEG_SIGN; - remapped_axis->x |= BMI2_AXIS_SIGN; - } - else - { - dev->remap.x_axis_sign = BMI2_POS_SIGN; - } - - /* Store the re-mapped y-axis value in device structure - * and its user-value in the interface structure - */ - switch (remap.y_axis) - { - case BMI2_MAP_X_AXIS: - - /* If mapped to x-axis */ - dev->remap.y_axis = BMI2_MAP_X_AXIS; - remapped_axis->y = BMI2_X; - break; - case BMI2_MAP_Y_AXIS: - - /* If mapped to y-axis */ - dev->remap.y_axis = BMI2_MAP_Y_AXIS; - remapped_axis->y = BMI2_Y; - break; - case BMI2_MAP_Z_AXIS: - - /* If mapped to z-axis */ - dev->remap.y_axis = BMI2_MAP_Z_AXIS; - remapped_axis->y = BMI2_Z; - break; - default: - break; - } - - /* Store the re-mapped y-axis sign in device structure - * and its user-value in the interface structure - */ - if (remap.y_axis_sign) - { - /* If y-axis is mapped to -ve sign */ - dev->remap.y_axis_sign = BMI2_NEG_SIGN; - remapped_axis->y |= BMI2_AXIS_SIGN; - } - else - { - dev->remap.y_axis_sign = BMI2_POS_SIGN; - } - - /* Store the re-mapped z-axis value in device structure - * and its user-value in the interface structure - */ - switch (remap.z_axis) - { - case BMI2_MAP_X_AXIS: - - /* If mapped to x-axis */ - dev->remap.z_axis = BMI2_MAP_X_AXIS; - remapped_axis->z = BMI2_X; - break; - case BMI2_MAP_Y_AXIS: - - /* If mapped to y-axis */ - dev->remap.z_axis = BMI2_MAP_Y_AXIS; - remapped_axis->z = BMI2_Y; - break; - case BMI2_MAP_Z_AXIS: - - /* If mapped to z-axis */ - dev->remap.z_axis = BMI2_MAP_Z_AXIS; - remapped_axis->z = BMI2_Z; - break; - default: - break; - } - - /* Store the re-mapped z-axis sign in device structure - * and its user-value in the interface structure - */ - if (remap.z_axis_sign) - { - /* If z-axis is mapped to -ve sign */ - dev->remap.z_axis_sign = BMI2_NEG_SIGN; - remapped_axis->z |= BMI2_AXIS_SIGN; - } - else - { - dev->remap.z_axis_sign = BMI2_POS_SIGN; - } - } - } - else - { - rslt = BMI2_E_NULL_PTR; - } - - return rslt; -} - -/*! - * @brief This API sets the re-mapped x, y and z axes to the sensor and - * updates the them in the device structure. - */ -int8_t bmi2_set_remap_axes(const struct bmi2_remap *remapped_axis, struct bmi2_dev *dev) -{ - /* Variable to define error */ - int8_t rslt; - - /* Variable to store all the re-mapped axes */ - uint8_t remap_axes = 0; - - /* Variable to store the re-mapped x-axes */ - uint8_t remap_x = 0; - - /* Variable to store the re-mapped y-axes */ - uint8_t remap_y = 0; - - /* Variable to store the re-mapped z-axes */ - uint8_t remap_z = 0; - - /* Initialize the local structure for axis re-mapping */ - struct bmi2_axes_remap remap = { 0, 0, 0, 0, 0, 0 }; - - /* Null-pointer check */ - rslt = null_ptr_check(dev); - if ((rslt == BMI2_OK) && (remapped_axis != NULL)) - { - /* Check whether all the axes are re-mapped */ - remap_axes = remapped_axis->x | remapped_axis->y | remapped_axis->z; - - /* If all the axes are re-mapped */ - if ((remap_axes & BMI2_AXIS_MASK) == BMI2_AXIS_MASK) - { - /* Get the re-mapped value of x, y and z axis */ - remap_x = remapped_axis->x & BMI2_AXIS_MASK; - remap_y = remapped_axis->y & BMI2_AXIS_MASK; - remap_z = remapped_axis->z & BMI2_AXIS_MASK; - - /* Store the value of re-mapped x-axis in both - * device structure and the local structure - */ - switch (remap_x) - { - case BMI2_X: - - /* If mapped to x-axis */ - dev->remap.x_axis = BMI2_MAP_X_AXIS; - remap.x_axis = BMI2_MAP_X_AXIS; - break; - case BMI2_Y: - - /* If mapped to y-axis */ - dev->remap.x_axis = BMI2_MAP_Y_AXIS; - remap.x_axis = BMI2_MAP_Y_AXIS; - break; - case BMI2_Z: - - /* If mapped to z-axis */ - dev->remap.x_axis = BMI2_MAP_Z_AXIS; - remap.x_axis = BMI2_MAP_Z_AXIS; - break; - default: - break; - } - - /* Store the re-mapped x-axis sign in the device - * structure and its value in local structure - */ - if (remapped_axis->x & BMI2_AXIS_SIGN) - { - /* If x-axis is mapped to -ve sign */ - dev->remap.x_axis_sign = BMI2_NEG_SIGN; - remap.x_axis_sign = BMI2_MAP_NEGATIVE; - } - else - { - dev->remap.x_axis_sign = BMI2_POS_SIGN; - remap.x_axis_sign = BMI2_MAP_POSITIVE; - } - - /* Store the value of re-mapped y-axis in both - * device structure and the local structure - */ - switch (remap_y) - { - case BMI2_X: - - /* If mapped to x-axis */ - dev->remap.y_axis = BMI2_MAP_X_AXIS; - remap.y_axis = BMI2_MAP_X_AXIS; - break; - case BMI2_Y: - - /* If mapped to y-axis */ - dev->remap.y_axis = BMI2_MAP_Y_AXIS; - remap.y_axis = BMI2_MAP_Y_AXIS; - break; - case BMI2_Z: - - /* If mapped to z-axis */ - dev->remap.y_axis = BMI2_MAP_Z_AXIS; - remap.y_axis = BMI2_MAP_Z_AXIS; - break; - default: - break; - } - - /* Store the re-mapped y-axis sign in the device - * structure and its value in local structure - */ - if (remapped_axis->y & BMI2_AXIS_SIGN) - { - /* If y-axis is mapped to -ve sign */ - dev->remap.y_axis_sign = BMI2_NEG_SIGN; - remap.y_axis_sign = BMI2_MAP_NEGATIVE; - } - else - { - dev->remap.y_axis_sign = BMI2_POS_SIGN; - remap.y_axis_sign = BMI2_MAP_POSITIVE; - } - - /* Store the value of re-mapped z-axis in both - * device structure and the local structure - */ - switch (remap_z) - { - case BMI2_X: - - /* If mapped to x-axis */ - dev->remap.z_axis = BMI2_MAP_X_AXIS; - remap.z_axis = BMI2_MAP_X_AXIS; - break; - case BMI2_Y: - - /* If mapped to y-axis */ - dev->remap.z_axis = BMI2_MAP_Y_AXIS; - remap.z_axis = BMI2_MAP_Y_AXIS; - break; - case BMI2_Z: - - /* If mapped to z-axis */ - dev->remap.z_axis = BMI2_MAP_Z_AXIS; - remap.z_axis = BMI2_MAP_Z_AXIS; - break; - default: - break; - } - - /* Store the re-mapped z-axis sign in the device - * structure and its value in local structure - */ - if (remapped_axis->z & BMI2_AXIS_SIGN) - { - /* If z-axis is mapped to -ve sign */ - dev->remap.z_axis_sign = BMI2_NEG_SIGN; - remap.z_axis_sign = BMI2_MAP_NEGATIVE; - } - else - { - dev->remap.z_axis_sign = BMI2_POS_SIGN; - remap.z_axis_sign = BMI2_MAP_POSITIVE; - } - - /* Set the re-mapped axes in the sensor */ - rslt = set_remap_axes(&remap, dev); - } - else - { - rslt = BMI2_E_REMAP_ERROR; - } - } - else - { - rslt = BMI2_E_NULL_PTR; - } - - return rslt; -} - -/*! - * @brief This API updates the gyroscope user-gain. - */ -int8_t bmi2_update_gyro_user_gain(const struct bmi2_gyro_user_gain_config *user_gain, struct bmi2_dev *dev) -{ - /* Variable to define error */ - int8_t rslt; - - /* Variable to select sensor */ - uint8_t sens_sel[2] = { BMI2_GYRO, BMI2_GYRO_GAIN_UPDATE }; - - /* Structure to define sensor configurations */ - struct bmi2_sens_config sens_cfg; - - /* Variable to store status of user-gain update module */ - uint8_t status = 0; - - /* Variable to define count */ - uint8_t count = 100; - - /* Null-pointer check */ - rslt = null_ptr_check(dev); - if ((rslt == BMI2_OK) && (user_gain != NULL)) - { - /* Select type of feature */ - sens_cfg.type = BMI2_GYRO_GAIN_UPDATE; - - /* Get the user gain configurations */ - rslt = bmi2_get_sensor_config(&sens_cfg, 1, dev); - if (rslt == BMI2_OK) - { - /* Get the user-defined ratio */ - sens_cfg.cfg.gyro_gain_update = *user_gain; - - /* Set rate ratio for all axes */ - rslt = bmi2_set_sensor_config(&sens_cfg, 1, dev); - } - - /* Disable gyroscope */ - if (rslt == BMI2_OK) - { - rslt = bmi2_sensor_disable(&sens_sel[0], 1, dev); - } - - /* Enable gyroscope user-gain update module */ - if (rslt == BMI2_OK) - { - rslt = bmi2_sensor_enable(&sens_sel[1], 1, dev); - } - - /* Set the command to trigger the computation */ - if (rslt == BMI2_OK) - { - rslt = bmi2_set_command_register(BMI2_USR_GAIN_CMD, dev); - } - - if (rslt == BMI2_OK) - { - /* Poll until enable bit of user-gain update is 0 */ - while (count--) - { - rslt = get_user_gain_upd_status(&status, dev); - if ((rslt == BMI2_OK) && (status == 0)) - { - /* Enable compensation of gain defined - * in the GAIN register - */ - rslt = enable_gyro_gain(BMI2_ENABLE, dev); - - /* Enable gyroscope */ - if (rslt == BMI2_OK) - { - rslt = bmi2_sensor_enable(&sens_sel[0], 1, dev); - } - - break; - } - - dev->delay_us(10000, dev->intf_ptr); - } - - /* Return error if user-gain update is failed */ - if ((rslt == BMI2_OK) && (status != 0)) - { - rslt = BMI2_E_GYR_USER_GAIN_UPD_FAIL; - } - } - } - else - { - rslt = BMI2_E_NULL_PTR; - } - - return rslt; -} - -/*! - * @brief This API reads the compensated gyroscope user-gain values. - */ -int8_t bmi2_read_gyro_user_gain(struct bmi2_gyro_user_gain_data *gyr_usr_gain, struct bmi2_dev *dev) -{ - /* Variable to define error */ - int8_t rslt; - - /* Variable to define register data */ - uint8_t reg_data[3] = { 0 }; - - /* Null-pointer check */ - rslt = null_ptr_check(dev); - if ((rslt == BMI2_OK) && (gyr_usr_gain != NULL)) - { - /* Get the gyroscope compensated gain values */ - rslt = bmi2_get_regs(BMI2_GYR_USR_GAIN_0_ADDR, reg_data, 3, dev); - if (rslt == BMI2_OK) - { - /* Gyroscope user gain correction X-axis */ - gyr_usr_gain->x = (int8_t)BMI2_GET_BIT_POS0(reg_data[0], BMI2_GYR_USR_GAIN_X); - - /* Gyroscope user gain correction Y-axis */ - gyr_usr_gain->y = (int8_t)BMI2_GET_BIT_POS0(reg_data[1], BMI2_GYR_USR_GAIN_Y); - - /* Gyroscope user gain correction z-axis */ - gyr_usr_gain->z = (int8_t)BMI2_GET_BIT_POS0(reg_data[2], BMI2_GYR_USR_GAIN_Z); - } - } - else - { - rslt = BMI2_E_NULL_PTR; - } - - return rslt; -} - -/*! - * @brief This API enables/disables gyroscope offset compensation. It adds the - * offsets defined in the offset register with gyroscope data. - */ -int8_t bmi2_set_gyro_offset_comp(uint8_t enable, struct bmi2_dev *dev) -{ - /* Variable to define error */ - int8_t rslt; - - /* Variable to define register data */ - uint8_t reg_data = 0; - - /* Null-pointer check */ - rslt = null_ptr_check(dev); - if (rslt == BMI2_OK) - { - /* Get the status of gyroscope offset enable */ - rslt = bmi2_get_regs(BMI2_GYR_OFF_COMP_6_ADDR, ®_data, 1, dev); - if (rslt == BMI2_OK) - { - reg_data = BMI2_SET_BITS(reg_data, BMI2_GYR_OFF_COMP_EN, enable); - - /* Enable/Disable gyroscope offset compensation */ - rslt = bmi2_set_regs(BMI2_GYR_OFF_COMP_6_ADDR, ®_data, 1, dev); - } - } - else - { - rslt = BMI2_E_NULL_PTR; - } - - return rslt; -} - -/*! - * @brief This API reads the gyroscope bias values for each axis which is used - * for gyroscope offset compensation. - */ -int8_t bmi2_read_gyro_offset_comp_axes(struct bmi2_sens_axes_data *gyr_off_comp_axes, struct bmi2_dev *dev) -{ - /* Variable to define error */ - int8_t rslt; - - /* Variable to define register data */ - uint8_t reg_data[4] = { 0 }; - - /* Variable to store LSB value of offset compensation for x-axis */ - uint8_t gyr_off_lsb_x; - - /* Variable to store LSB value of offset compensation for y-axis */ - uint8_t gyr_off_lsb_y; - - /* Variable to store LSB value of offset compensation for z-axis */ - uint8_t gyr_off_lsb_z; - - /* Variable to store MSB value of offset compensation for x-axis */ - uint8_t gyr_off_msb_x; - - /* Variable to store MSB value of offset compensation for y-axis */ - uint8_t gyr_off_msb_y; - - /* Variable to store MSB value of offset compensation for z-axis */ - uint8_t gyr_off_msb_z; - - /* Null-pointer check */ - rslt = null_ptr_check(dev); - if ((rslt == BMI2_OK) && (gyr_off_comp_axes != NULL)) - { - /* Get the gyroscope compensated offset values */ - rslt = bmi2_get_regs(BMI2_GYR_OFF_COMP_3_ADDR, reg_data, 4, dev); - if (rslt == BMI2_OK) - { - /* Get LSB and MSB values of offset compensation for - * x, y and z axis - */ - gyr_off_lsb_x = reg_data[0]; - gyr_off_lsb_y = reg_data[1]; - gyr_off_lsb_z = reg_data[2]; - gyr_off_msb_x = reg_data[3] & BMI2_GYR_OFF_COMP_MSB_X_MASK; - gyr_off_msb_y = reg_data[3] & BMI2_GYR_OFF_COMP_MSB_Y_MASK; - gyr_off_msb_z = reg_data[3] & BMI2_GYR_OFF_COMP_MSB_Z_MASK; - - /* Gyroscope offset compensation value for x-axis */ - gyr_off_comp_axes->x = (int16_t)(((uint16_t) gyr_off_msb_x << 8) | gyr_off_lsb_x); - - /* Gyroscope offset compensation value for y-axis */ - gyr_off_comp_axes->y = (int16_t)(((uint16_t) gyr_off_msb_y << 6) | gyr_off_lsb_y); - - /* Gyroscope offset compensation value for z-axis */ - gyr_off_comp_axes->z = (int16_t)(((uint16_t) gyr_off_msb_z << 4) | gyr_off_lsb_z); - } - } - else - { - rslt = BMI2_E_NULL_PTR; - } - - return rslt; -} - -/*! - * @brief This API writes the gyroscope bias values for each axis which is used - * for gyroscope offset compensation. - */ -int8_t bmi2_write_gyro_offset_comp_axes(const struct bmi2_sens_axes_data *gyr_off_comp_axes, struct bmi2_dev *dev) -{ - /* Variable to define error */ - int8_t rslt; - - /* Variable to define register data */ - uint8_t reg_data[4] = { 0 }; - - /* Variable to store MSB value of offset compensation for x-axis */ - uint8_t gyr_off_msb_x; - - /* Variable to store MSB value of offset compensation for y-axis */ - uint8_t gyr_off_msb_y; - - /* Variable to store MSB value of offset compensation for z-axis */ - uint8_t gyr_off_msb_z; - - /* Null-pointer check */ - rslt = null_ptr_check(dev); - if ((rslt == BMI2_OK) && (gyr_off_comp_axes != NULL)) - { - /* Get the MSB values of gyroscope compensated offset values */ - rslt = bmi2_get_regs(BMI2_GYR_OFF_COMP_6_ADDR, ®_data[3], 1, dev); - if (rslt == BMI2_OK) - { - /* Get MSB value of x-axis from user-input */ - gyr_off_msb_x = (uint8_t)((gyr_off_comp_axes->x & BMI2_GYR_OFF_COMP_MSB_MASK) >> 8); - - /* Get MSB value of y-axis from user-input */ - gyr_off_msb_y = (uint8_t)((gyr_off_comp_axes->y & BMI2_GYR_OFF_COMP_MSB_MASK) >> 8); - - /* Get MSB value of z-axis from user-input */ - gyr_off_msb_z = (uint8_t)((gyr_off_comp_axes->z & BMI2_GYR_OFF_COMP_MSB_MASK) >> 8); - - /* Get LSB value of x-axis from user-input */ - reg_data[0] = (uint8_t)(gyr_off_comp_axes->x & BMI2_GYR_OFF_COMP_LSB_MASK); - - /* Get LSB value of y-axis from user-input */ - reg_data[1] = (uint8_t)(gyr_off_comp_axes->y & BMI2_GYR_OFF_COMP_LSB_MASK); - - /* Get LSB value of z-axis from user-input */ - reg_data[2] = (uint8_t)(gyr_off_comp_axes->z & BMI2_GYR_OFF_COMP_LSB_MASK); - - /* Get MSB value of x-axis to be set */ - reg_data[3] = BMI2_SET_BIT_POS0(reg_data[3], BMI2_GYR_OFF_COMP_MSB_X, gyr_off_msb_x); - - /* Get MSB value of y-axis to be set */ - reg_data[3] = BMI2_SET_BITS(reg_data[3], BMI2_GYR_OFF_COMP_MSB_Y, gyr_off_msb_y); - - /* Get MSB value of z-axis to be set */ - reg_data[3] = BMI2_SET_BITS(reg_data[3], BMI2_GYR_OFF_COMP_MSB_Z, gyr_off_msb_z); - - /* Set the offset compensation values of axes */ - rslt = bmi2_set_regs(BMI2_GYR_OFF_COMP_3_ADDR, reg_data, 4, dev); - } - } - else - { - rslt = BMI2_E_NULL_PTR; - } - - return rslt; -} - -/*! - * @brief This internal API is used to parse the activity output from the - * FIFO in header mode. - */ -int8_t bmi2_get_act_recog_output(struct bmi2_act_recog_output *act_recog, - uint16_t *act_frm_len, - struct bmi2_fifo_frame *fifo, - const struct bmi2_dev *dev) -{ - /* Variable to define error */ - int8_t rslt; - - /* Variable to define header frame */ - uint8_t frame_header = 0; - - /* Variable to index the data bytes */ - uint16_t data_index; - - /* Variable to index activity frames */ - uint16_t act_idx = 0; - - /* Variable to indicate activity frames read */ - uint16_t frame_to_read = 0; - - /* Null-pointer check */ - rslt = null_ptr_check(dev); - if ((rslt == BMI2_OK) && (act_recog != NULL) && (act_frm_len != NULL) && (fifo != NULL)) - { - - /* Store the number of frames to be read */ - frame_to_read = *act_frm_len; - for (data_index = fifo->act_recog_byte_start_idx; data_index < fifo->length;) - { - /* Get frame header byte */ - frame_header = fifo->data[data_index] & BMI2_FIFO_TAG_INTR_MASK; - - /* Skip S4S frames if S4S is enabled */ - rslt = move_if_s4s_frame(&frame_header, &data_index, fifo); - - /* Break if FIFO is empty */ - if (rslt == BMI2_W_FIFO_EMPTY) - { - break; - } - - /* Index shifted to next byte where data starts */ - data_index++; - switch (frame_header) - { - /* If header defines accelerometer frame */ - case BMI2_FIFO_HEADER_ACC_FRM: - rslt = move_next_frame(&data_index, fifo->acc_frm_len, fifo); - break; - - /* If header defines accelerometer and auxiliary frames */ - case BMI2_FIFO_HEADER_AUX_ACC_FRM: - rslt = move_next_frame(&data_index, fifo->acc_aux_frm_len, fifo); - break; - - /* If header defines accelerometer and gyroscope frames */ - case BMI2_FIFO_HEADER_GYR_ACC_FRM: - rslt = move_next_frame(&data_index, fifo->acc_gyr_frm_len, fifo); - break; - - /* If header defines accelerometer, auxiliary and gyroscope frames */ - case BMI2_FIFO_HEADER_ALL_FRM: - rslt = move_next_frame(&data_index, fifo->all_frm_len, fifo); - break; - - /* If header defines only gyroscope frame */ - case BMI2_FIFO_HEADER_GYR_FRM: - rslt = move_next_frame(&data_index, fifo->gyr_frm_len, fifo); - break; - - /* If header defines only auxiliary frame */ - case BMI2_FIFO_HEADER_AUX_FRM: - rslt = move_next_frame(&data_index, fifo->aux_frm_len, fifo); - break; - - /* If header defines auxiliary and gyroscope frame */ - case BMI2_FIFO_HEADER_AUX_GYR_FRM: - rslt = move_next_frame(&data_index, fifo->aux_gyr_frm_len, fifo); - break; - - /* If header defines sensor time frame */ - case BMI2_FIFO_HEADER_SENS_TIME_FRM: - rslt = move_next_frame(&data_index, BMI2_SENSOR_TIME_LENGTH, fifo); - break; - - /* If header defines skip frame */ - case BMI2_FIFO_HEADER_SKIP_FRM: - rslt = move_next_frame(&data_index, BMI2_FIFO_SKIP_FRM_LENGTH, fifo); - break; - - /* If header defines Input configuration frame */ - case BMI2_FIFO_HEADER_INPUT_CFG_FRM: - rslt = move_next_frame(&data_index, BMI2_FIFO_INPUT_CFG_LENGTH, fifo); - break; - - /* If header defines invalid frame or end of valid data */ - case BMI2_FIFO_HEAD_OVER_READ_MSB: - - /* Move the data index to the last byte to mark completion */ - data_index = fifo->length; - - /* FIFO is empty */ - rslt = BMI2_W_FIFO_EMPTY; - break; - - /* If header defines activity recognition frame */ - case BMI2_FIFO_VIRT_ACT_RECOG_FRM: - - /* Get the activity output */ - rslt = unpack_act_recog_output(&act_recog[(act_idx)], &data_index, fifo); - - /* Update activity frame index */ - (act_idx)++; - break; - default: - - /* Move the data index to the last byte in case of invalid values */ - data_index = fifo->length; - - /* FIFO is empty */ - rslt = BMI2_W_FIFO_EMPTY; - break; - } - - /* Number of frames to be read is complete or FIFO is empty */ - if ((frame_to_read == act_idx) || (rslt == BMI2_W_FIFO_EMPTY)) - { - break; - } - } - - /* Update the activity frame index */ - (*act_frm_len) = act_idx; - - /* Update the activity byte index */ - fifo->act_recog_byte_start_idx = data_index; - } - else - { - rslt = BMI2_E_NULL_PTR; - } - - return rslt; -} - -/*! - * @brief This API updates the cross sensitivity coefficient between gyroscope's - * X and Z axes. - */ -int8_t bmi2_get_gyro_cross_sense(struct bmi2_dev *dev) -{ - /* Variable to define error */ - int8_t rslt = BMI2_OK; - struct bmi2_sensor_data data; - - /* Check if the feature is supported by this variant */ - if (dev->variant_feature & BMI2_GYRO_CROSS_SENS_ENABLE) - { - rslt = null_ptr_check(dev); - if (rslt == BMI2_OK) - { - /* Select the feature whose data is to be acquired */ - data.type = BMI2_GYRO_CROSS_SENSE; - - /* Get the respective data */ - rslt = bmi2_get_sensor_data(&data, 1, dev); - if (rslt == BMI2_OK) - { - /* Update the gyroscope cross sense value of z axis - * in the device structure - */ - dev->gyr_cross_sens_zx = data.sens_data.correction_factor_zx; - } - } - else - { - rslt = BMI2_E_NULL_PTR; - } - } - - return rslt; -} - -/*! - * @brief This API gets Error bits and message indicating internal status. - */ -int8_t bmi2_get_internal_status(uint8_t *int_stat, struct bmi2_dev *dev) -{ - /* Variable to define error */ - int8_t rslt; - - /* Null-pointer check */ - rslt = null_ptr_check(dev); - if ((rslt == BMI2_OK) && (int_stat != NULL)) - { - /* Delay to read the internal status */ - dev->delay_us(20000, dev->intf_ptr); - - /* Get the error bits and message */ - rslt = bmi2_get_regs(BMI2_INTERNAL_STATUS_ADDR, int_stat, 1, dev); - } - else - { - rslt = BMI2_E_NULL_PTR; - } - - return rslt; -} - -/*! @cond DOXYGEN_SUPRESS */ - -/* Suppressing doxygen warnings triggered for same static function names present across various sensor variant - * directories */ - -/*! - * @brief This API verifies and allows only the correct position to do Fast Offset Compensation for - * accelerometer & gyro. - */ -static int8_t verify_foc_position(uint8_t sens_list, - const struct bmi2_accel_foc_g_value *accel_g_axis, - struct bmi2_dev *dev) -{ - int8_t rslt; - - struct bmi2_sens_axes_data avg_foc_data = { 0 }; - struct bmi2_foc_temp_value temp_foc_data = { 0 }; - - rslt = null_ptr_check(dev); - if (rslt == BMI2_OK) - { - /* Enable sensor */ - rslt = bmi2_sensor_enable(&sens_list, 1, dev); - } - - if (rslt == BMI2_OK) - { - - rslt = get_average_of_sensor_data(sens_list, &temp_foc_data, dev); - if (rslt == BMI2_OK) - { - if (sens_list == BMI2_ACCEL) - { - - /* Taking modulus to make negative values as positive */ - if ((accel_g_axis->x == 1) && (accel_g_axis->sign == 1)) - { - temp_foc_data.x = temp_foc_data.x * -1; - } - else if ((accel_g_axis->y == 1) && (accel_g_axis->sign == 1)) - { - temp_foc_data.y = temp_foc_data.y * -1; - } - else if ((accel_g_axis->z == 1) && (accel_g_axis->sign == 1)) - { - temp_foc_data.z = temp_foc_data.z * -1; - } - } - - /* Typecasting into 16bit */ - avg_foc_data.x = (int16_t)(temp_foc_data.x); - avg_foc_data.y = (int16_t)(temp_foc_data.y); - avg_foc_data.z = (int16_t)(temp_foc_data.z); - - rslt = validate_foc_position(sens_list, accel_g_axis, avg_foc_data, dev); - } - } - - return rslt; -} - -/*! @endcond */ - -/*! - * @brief This API performs Fast Offset Compensation for accelerometer. - */ -int8_t bmi2_perform_accel_foc(const struct bmi2_accel_foc_g_value *accel_g_value, struct bmi2_dev *dev) -{ - /* Variable to define error */ - int8_t rslt; - - /* Structure to define the accelerometer configurations */ - struct bmi2_accel_config acc_cfg = { 0, 0, 0, 0 }; - - /* Variable to store status of advance power save */ - uint8_t aps = 0; - - /* Variable to store status of accelerometer enable */ - uint8_t acc_en = 0; - - /* Null-pointer check */ - rslt = null_ptr_check(dev); - if ((rslt == BMI2_OK) && (accel_g_value != NULL)) - { - /* Check for input validity */ - if ((((BMI2_ABS(accel_g_value->x)) + (BMI2_ABS(accel_g_value->y)) + (BMI2_ABS(accel_g_value->z))) == 1) && - ((accel_g_value->sign == 1) || (accel_g_value->sign == 0))) - { - rslt = verify_foc_position(BMI2_ACCEL, accel_g_value, dev); - if (rslt == BMI2_OK) - { - - /* Save accelerometer configurations, accelerometer - * enable status and advance power save status - */ - rslt = save_accel_foc_config(&acc_cfg, &aps, &acc_en, dev); - } - - /* Set configurations for FOC */ - if (rslt == BMI2_OK) - { - rslt = set_accel_foc_config(dev); - } - - /* Perform accelerometer FOC */ - if (rslt == BMI2_OK) - { - rslt = perform_accel_foc(accel_g_value, &acc_cfg, dev); - } - - /* Restore the saved configurations */ - if (rslt == BMI2_OK) - { - rslt = restore_accel_foc_config(&acc_cfg, aps, acc_en, dev); - } - } - else - { - rslt = BMI2_E_INVALID_INPUT; - } - } - else - { - rslt = BMI2_E_NULL_PTR; - } - - return rslt; -} - -/*! - * @brief This API performs Fast Offset Compensation for gyroscope. - */ -int8_t bmi2_perform_gyro_foc(struct bmi2_dev *dev) -{ - /* Variable to define error */ - int8_t rslt; - - /* Structure to define the gyroscope configurations */ - struct bmi2_gyro_config gyr_cfg = { 0, 0, 0, 0, 0, 0 }; - - /* Variable to store status of advance power save */ - uint8_t aps = 0; - - /* Variable to store status of gyroscope enable */ - uint8_t gyr_en = 0; - - /* Array of structure to store gyroscope data */ - struct bmi2_sens_axes_data gyr_value[128]; - - /* Structure to store gyroscope data temporarily */ - struct bmi2_foc_temp_value temp = { 0, 0, 0 }; - - /* Variable to store status read from the status register */ - uint8_t reg_status = 0; - - /* Variable to define count */ - uint8_t loop = 0; - - /* Structure to store the offset values to be stored in the register */ - struct bmi2_sens_axes_data gyro_offset = { 0, 0, 0, 0 }; - - /* Null-pointer check */ - rslt = null_ptr_check(dev); - if (rslt == BMI2_OK) - { - /* Argument2 is not applicable for gyro */ - rslt = verify_foc_position(BMI2_GYRO, 0, dev); - if (rslt == BMI2_OK) - { - /* Save gyroscope configurations, gyroscope enable - * status and advance power save status - */ - rslt = save_gyro_config(&gyr_cfg, &aps, &gyr_en, dev); - - /* Set configurations for gyroscope FOC */ - if (rslt == BMI2_OK) - { - rslt = set_gyro_foc_config(dev); - } - - /* Perform FOC */ - if (rslt == BMI2_OK) - { - for (loop = 0; loop < 128; loop++) - { - /* Giving a delay of more than 40ms since ODR is configured as 25Hz */ - dev->delay_us(50000, dev->intf_ptr); - - /* Get gyroscope data ready interrupt status */ - rslt = bmi2_get_status(®_status, dev); - - /* Read 128 samples of gyroscope data on data ready interrupt */ - if ((rslt == BMI2_OK) && (reg_status & BMI2_DRDY_GYR)) - { - rslt = read_gyro_xyz(&gyr_value[loop], dev); - if (rslt == BMI2_OK) - { - /* Store the data in a temporary structure */ - temp.x = temp.x + (int32_t)gyr_value[loop].x; - temp.y = temp.y + (int32_t)gyr_value[loop].y; - temp.z = temp.z + (int32_t)gyr_value[loop].z; - } - } - - if (rslt != BMI2_OK) - { - break; - } - else if ((reg_status & BMI2_DRDY_GYR) != BMI2_DRDY_GYR) - { - rslt = BMI2_E_INVALID_STATUS; - break; - } - } - - if (rslt == BMI2_OK) - { - /* Take average of x, y and z data for lesser - * noise. It is same as offset data since lsb/dps - * is same for both data and offset register - */ - gyro_offset.x = (int16_t)(temp.x / 128); - gyro_offset.y = (int16_t)(temp.y / 128); - gyro_offset.z = (int16_t)(temp.z / 128); - - /* Saturate gyroscope data since the offset - * registers are of 10 bit value where as the - * gyroscope data is of 16 bit value - */ - saturate_gyro_data(&gyro_offset); - - /* Invert the gyroscope offset data */ - invert_gyro_offset(&gyro_offset); - - /* Write offset data in the gyroscope offset - * compensation register - */ - rslt = bmi2_write_gyro_offset_comp_axes(&gyro_offset, dev); - } - - /* Enable gyroscope offset compensation */ - if (rslt == BMI2_OK) - { - rslt = bmi2_set_gyro_offset_comp(BMI2_ENABLE, dev); - } - - /* Restore the saved gyroscope configurations */ - if (rslt == BMI2_OK) - { - rslt = restore_gyro_config(&gyr_cfg, aps, gyr_en, dev); - } - } - } - } - - return rslt; -} - -/*! - * @brief This api is used for retrieving the activity recognition settings currently set. - */ -int8_t bmi2_get_act_recg_sett(struct bmi2_act_recg_sett *sett, struct bmi2_dev *dev) -{ - /* Variable to define error */ - int8_t rslt; - - /* Array to define the feature configuration */ - uint8_t feat_config[BMI2_FEAT_SIZE_IN_BYTES] = { 0 }; - - /* Variable to define the array offset */ - uint8_t idx = 0; - - /* Variable to get the status of advance power save */ - uint8_t aps_stat; - - /* Variable to set flag */ - uint8_t feat_found; - uint16_t msb_lsb; - uint8_t lsb; - uint8_t msb; - - /* Initialize feature configuration for activity recognition */ - struct bmi2_feature_config bmi2_act_recg_sett = { 0, 0, 0 }; - - /* Null-pointer check */ - rslt = null_ptr_check(dev); - if (rslt == BMI2_OK) - { - - /* Search for bmi2 Abort feature and extract its configuration details */ - feat_found = bmi2_extract_input_feat_config(&bmi2_act_recg_sett, BMI2_ACTIVITY_RECOGNITION_SETTINGS, dev); - if (feat_found) - { - aps_stat = dev->aps_status; - if (aps_stat == BMI2_ENABLE) - { - /* Disable advance power save if enabled */ - rslt = bmi2_set_adv_power_save(BMI2_DISABLE, dev); - } - - /* Get the configuration from the page where activity recognition setting feature resides */ - if (rslt == BMI2_OK) - { - rslt = bmi2_get_feat_config(bmi2_act_recg_sett.page, feat_config, dev); - } - - if (rslt == BMI2_OK) - { - /* Define the offset in bytes */ - idx = bmi2_act_recg_sett.start_addr; - - /* get the status of enable/disable post processing */ - sett->act_rec_1 = BMI2_GET_BIT_POS0(feat_config[idx], BMI2_ACT_RECG_POST_PROS_EN_DIS); - - /* increment idx by 2 to point min gdi thres addres */ - idx = idx + 2; - lsb = feat_config[idx]; - idx++; - msb = feat_config[idx]; - msb_lsb = (uint16_t)(lsb | msb << 8); - sett->act_rec_2 = msb_lsb; - - /* increment idx by 1 to point max gdi thres addres */ - idx++; - lsb = feat_config[idx]; - idx++; - msb = feat_config[idx]; - msb_lsb = (uint16_t)(lsb | msb << 8); - sett->act_rec_3 = msb_lsb; - - /* increment idx by 1 to point buffer size */ - idx++; - sett->act_rec_4 = BMI2_GET_BIT_POS0(feat_config[idx], BMI2_ACT_RECG_BUFF_SIZE); - - /* increment idx by 2 to to point to min segment confidence */ - idx = idx + 2; - sett->act_rec_5 = BMI2_GET_BIT_POS0(feat_config[idx], BMI2_ACT_RECG_MIN_SEG_CONF); - } - - /* Enable Advance power save if disabled while - * configuring and not when already disabled - */ - if ((aps_stat == BMI2_ENABLE) && (rslt == BMI2_OK)) - { - rslt = bmi2_set_adv_power_save(BMI2_ENABLE, dev); - } - } - else - { - rslt = BMI2_E_INVALID_SENSOR; - } - } - - return rslt; -} - -/*! - * @brief This api is used for setting the activity recognition settings. - */ -int8_t bmi2_set_act_recg_sett(const struct bmi2_act_recg_sett *sett, struct bmi2_dev *dev) -{ - /* Variable to define error */ - int8_t rslt; - - /* Array to define the feature configuration */ - uint8_t feat_config[BMI2_FEAT_SIZE_IN_BYTES] = { 0 }; - - /* Variable to define the array offset */ - uint8_t idx = 0; - - /* Variable to get the status of advance power save */ - uint8_t aps_stat; - - /* Variable to set flag */ - uint8_t feat_found; - - /* Initialize feature configuration for activity recognition */ - struct bmi2_feature_config bmi2_act_recg_sett = { 0, 0, 0 }; - - /* Null-pointer check */ - rslt = null_ptr_check(dev); - if (rslt == BMI2_OK) - { - - /* Search for bmi2 Abort feature and extract its configuration details */ - feat_found = bmi2_extract_input_feat_config(&bmi2_act_recg_sett, BMI2_ACTIVITY_RECOGNITION_SETTINGS, dev); - if (feat_found) - { - aps_stat = dev->aps_status; - if (aps_stat == BMI2_ENABLE) - { - /* Disable advance power save if enabled */ - rslt = bmi2_set_adv_power_save(BMI2_DISABLE, dev); - } - - /* Get the configuration from the page where activity recognition setting feature resides */ - if (rslt == BMI2_OK) - { - rslt = bmi2_get_feat_config(bmi2_act_recg_sett.page, feat_config, dev); - } - - if (rslt == BMI2_OK) - { - /* Define the offset in bytes */ - idx = bmi2_act_recg_sett.start_addr; - if ((sett->act_rec_4 > 10) || (sett->act_rec_5 > 10)) - { - rslt = BMI2_E_INVALID_INPUT; - } - - if (rslt == BMI2_OK) - { - feat_config[idx] = BMI2_SET_BIT_POS0(feat_config[idx], - BMI2_ACT_RECG_POST_PROS_EN_DIS, - sett->act_rec_1); - - /* Increment idx by 2 to point min gdi thres addres */ - idx = idx + 2; - feat_config[idx] = BMI2_GET_LSB(sett->act_rec_2); - idx++; - feat_config[idx] = BMI2_GET_MSB(sett->act_rec_2); - - /* Increment idx by 1 to point max gdi thres addres */ - idx++; - feat_config[idx] = BMI2_GET_LSB(sett->act_rec_3); - idx++; - feat_config[idx] = BMI2_GET_MSB(sett->act_rec_3); - - /* Increment idx by 1 to point buffer size */ - idx++; - feat_config[idx] = BMI2_SET_BIT_POS0(feat_config[idx], BMI2_ACT_RECG_BUFF_SIZE, sett->act_rec_4); - - /* Increment idx by 2 to to point to min segment confidence */ - idx = idx + 2; - feat_config[idx] = BMI2_SET_BIT_POS0(feat_config[idx], BMI2_ACT_RECG_MIN_SEG_CONF, sett->act_rec_5); - - rslt = bmi2_set_regs(BMI2_FEATURES_REG_ADDR, feat_config, BMI2_FEAT_SIZE_IN_BYTES, dev); - } - } - - /* Enable Advance power save if disabled while - * configuring and not when already disabled - */ - if ((aps_stat == BMI2_ENABLE) && (rslt == BMI2_OK)) - { - rslt = bmi2_set_adv_power_save(BMI2_ENABLE, dev); - } - } - else - { - rslt = BMI2_E_INVALID_SENSOR; - } - } - - return rslt; -} - -/*! - * @brief This API is used to get the feature configuration from the - * selected page. - */ -int8_t bmi2_get_feat_config(uint8_t sw_page, uint8_t *feat_config, struct bmi2_dev *dev) -{ - /* Variable to define error */ - int8_t rslt; - - /* Variable to define bytes remaining to read */ - uint8_t bytes_remain = BMI2_FEAT_SIZE_IN_BYTES; - - /* Variable to define the read-write length */ - uint8_t read_write_len = 0; - - /* Variable to define the feature configuration address */ - uint8_t addr = BMI2_FEATURES_REG_ADDR; - - /* Variable to define index */ - uint8_t index = 0; - - if ((feat_config == NULL) || (dev == NULL)) - { - rslt = BMI2_E_NULL_PTR; - } - else - { - /* Check whether the page is valid */ - if (sw_page < dev->page_max) - { - /* Switch page */ - rslt = bmi2_set_regs(BMI2_FEAT_PAGE_ADDR, &sw_page, 1, dev); - - /* If user length is less than feature length */ - if ((rslt == BMI2_OK) && (dev->read_write_len < BMI2_FEAT_SIZE_IN_BYTES)) - { - /* Read-write should be even */ - if ((dev->read_write_len % 2) != 0) - { - dev->read_write_len--; - } - - while (bytes_remain > 0) - { - if (bytes_remain >= dev->read_write_len) - { - /* Read from the page */ - rslt = bmi2_get_regs(addr, &feat_config[index], dev->read_write_len, dev); - - /* Update index */ - index += (uint8_t) dev->read_write_len; - - /* Update address */ - addr += (uint8_t) dev->read_write_len; - - /* Update read-write length */ - read_write_len += (uint8_t) dev->read_write_len; - } - else - { - /* Read from the page */ - rslt = bmi2_get_regs(addr, (uint8_t *) (feat_config + index), (uint16_t) bytes_remain, dev); - - /* Update read-write length */ - read_write_len += bytes_remain; - } - - /* Remaining bytes */ - bytes_remain = BMI2_FEAT_SIZE_IN_BYTES - read_write_len; - - if (rslt != BMI2_OK) - { - break; - } - } - } - else if (rslt == BMI2_OK) - { - /* Get configuration from the page */ - rslt = bmi2_get_regs(BMI2_FEATURES_REG_ADDR, feat_config, BMI2_FEAT_SIZE_IN_BYTES, dev); - } - } - else - { - rslt = BMI2_E_INVALID_PAGE; - } - } - - return rslt; -} - -/*! - * @brief This API is used to extract the input feature configuration - * details from the look-up table. - */ -uint8_t bmi2_extract_input_feat_config(struct bmi2_feature_config *feat_config, uint8_t type, - const struct bmi2_dev *dev) -{ - /* Variable to define loop */ - uint8_t loop = 0; - - /* Variable to set flag */ - uint8_t feat_found = BMI2_FALSE; - - /* Search for the input feature from the input configuration array */ - while (loop < dev->input_sens) - { - if (dev->feat_config[loop].type == type) - { - *feat_config = dev->feat_config[loop]; - feat_found = BMI2_TRUE; - break; - } - - loop++; - } - - /* Return flag */ - return feat_found; -} - -/***************************************************************************/ - -/*! Local Function Definitions - ****************************************************************************/ - -/*! @cond DOXYGEN_SUPRESS */ - -/* Suppressing doxygen warnings triggered for same static function names present across various sensor variant - * directories */ - -/*! - * @brief This internal API writes the configuration file. - */ -static int8_t write_config_file(struct bmi2_dev *dev) -{ - /* Variable to define error */ - int8_t rslt; - - /* Variable to update the configuration file index */ - uint16_t index = 0; - - /* config file size */ - uint16_t config_size = dev->config_size; - - /* Variable to get the remainder */ - uint8_t remain = (uint8_t)(config_size % dev->read_write_len); - - /* Variable to get the balance bytes */ - uint16_t bal_byte = 0; - - /* Variable to define temporary read/write length */ - uint16_t read_write_len = 0; - - /* Disable advanced power save mode */ - rslt = bmi2_set_adv_power_save(BMI2_DISABLE, dev); - if (rslt == BMI2_OK) - { - /* Disable loading of the configuration */ - rslt = set_config_load(BMI2_DISABLE, dev); - if (rslt == BMI2_OK) - { - if (!remain) - { - /* Write the configuration file */ - for (index = 0; (index < config_size) && (rslt == BMI2_OK); index += dev->read_write_len) - { - rslt = upload_file((dev->config_file_ptr + index), index, dev->read_write_len, dev); - } - } - else - { - /* Get the balance bytes */ - bal_byte = (uint16_t) config_size - (uint16_t) remain; - - /* Write the configuration file for the balancem bytes */ - for (index = 0; (index < bal_byte) && (rslt == BMI2_OK); index += dev->read_write_len) - { - rslt = upload_file((dev->config_file_ptr + index), index, dev->read_write_len, dev); - } - - if (rslt == BMI2_OK) - { - /* Update length in a temporary variable */ - read_write_len = dev->read_write_len; - - /* Write the remaining bytes in 2 bytes length */ - dev->read_write_len = 2; - - /* Write the configuration file for the remaining bytes */ - for (index = bal_byte; - (index < config_size) && (rslt == BMI2_OK); - index += dev->read_write_len) - { - rslt = upload_file((dev->config_file_ptr + index), index, dev->read_write_len, dev); - } - - /* Restore the user set length back from the temporary variable */ - dev->read_write_len = read_write_len; - } - } - - if (rslt == BMI2_OK) - { - /* Enable loading of the configuration */ - rslt = set_config_load(BMI2_ENABLE, dev); - - /* Wait till ASIC is initialized */ - dev->delay_us(150000, dev->intf_ptr); - if (rslt == BMI2_OK) - { - /* Enable advanced power save mode */ - rslt = bmi2_set_adv_power_save(BMI2_ENABLE, dev); - dev->delay_us(1000, dev->intf_ptr); - } - } - } - } - - return rslt; -} - -/*! - * @brief This internal API enables/disables the loading of the configuration - * file. - */ -static int8_t set_config_load(uint8_t enable, struct bmi2_dev *dev) -{ - /* Variable to define error */ - int8_t rslt; - - /* Variable to store data */ - uint8_t reg_data = 0; - - rslt = bmi2_get_regs(BMI2_INIT_CTRL_ADDR, ®_data, 1, dev); - if (rslt == BMI2_OK) - { - reg_data = BMI2_SET_BIT_POS0(reg_data, BMI2_CONF_LOAD_EN, enable); - rslt = bmi2_set_regs(BMI2_INIT_CTRL_ADDR, ®_data, 1, dev); - } - - return rslt; -} - -/*! - * @brief This internal API loads the configuration file. - */ -static int8_t upload_file(const uint8_t *config_data, uint16_t index, uint16_t write_len, struct bmi2_dev *dev) -{ - /* Variable to define error */ - int8_t rslt; - - /* Array to store address */ - uint8_t addr_array[2] = { 0 }; - - if (config_data != NULL) - { - /* Store 0 to 3 bits of address in first byte */ - addr_array[0] = (uint8_t)((index / 2) & 0x0F); - - /* Store 4 to 11 bits of address in the second byte */ - addr_array[1] = (uint8_t)((index / 2) >> 4); - - /* Write the 2 bytes of address in consecutive locations */ - rslt = bmi2_set_regs(BMI2_INIT_ADDR_0, addr_array, 2, dev); - if (rslt == BMI2_OK) - { - /* Burst write configuration file data corresponding to user set length */ - rslt = bmi2_set_regs(BMI2_INIT_DATA_ADDR, (uint8_t *)config_data, write_len, dev); - } - } - else - { - rslt = BMI2_E_NULL_PTR; - } - - return rslt; -} - -/*! - * @brief This internal API enables the selected sensor/features. - */ -static int8_t sensor_enable(uint64_t sensor_sel, struct bmi2_dev *dev) -{ - /* Variable to define error */ - int8_t rslt; - - /* Variable to store register values */ - uint8_t reg_data = 0; - - /* Variable to define loop */ - uint8_t loop = 1; - - /* Variable to get the status of advance power save */ - uint8_t aps_stat = 0; - - rslt = bmi2_get_regs(BMI2_PWR_CTRL_ADDR, ®_data, 1, dev); - if (rslt == BMI2_OK) - { - /* Enable accelerometer */ - if (sensor_sel & BMI2_ACCEL_SENS_SEL) - { - reg_data = BMI2_SET_BITS(reg_data, BMI2_ACC_EN, BMI2_ENABLE); - } - - /* Enable gyroscope */ - if (sensor_sel & BMI2_GYRO_SENS_SEL) - { - reg_data = BMI2_SET_BITS(reg_data, BMI2_GYR_EN, BMI2_ENABLE); - } - - /* Enable auxiliary sensor */ - if (sensor_sel & BMI2_AUX_SENS_SEL) - { - reg_data = BMI2_SET_BIT_POS0(reg_data, BMI2_AUX_EN, BMI2_ENABLE); - } - - /* Enable temperature sensor */ - if (sensor_sel & BMI2_TEMP_SENS_SEL) - { - reg_data = BMI2_SET_BITS(reg_data, BMI2_TEMP_EN, BMI2_ENABLE); - } - - /* Enable the sensors that are set in the power control register */ - if (sensor_sel & BMI2_MAIN_SENSORS) - { - rslt = bmi2_set_regs(BMI2_PWR_CTRL_ADDR, ®_data, 1, dev); - } - } - - if ((rslt == BMI2_OK) && (sensor_sel & ~(BMI2_MAIN_SENSORS))) - { - /* Get status of advance power save mode */ - aps_stat = dev->aps_status; - if (aps_stat == BMI2_ENABLE) - { - /* Disable advance power save if enabled */ - rslt = bmi2_set_adv_power_save(BMI2_DISABLE, dev); - } - - if (rslt == BMI2_OK) - { - while (loop--) - { - /* Enable sig-motion feature */ - if (sensor_sel & BMI2_SIG_MOTION_SEL) - { - rslt = set_sig_motion(BMI2_ENABLE, dev); - if (rslt == BMI2_OK) - { - dev->sens_en_stat |= BMI2_SIG_MOTION_SEL; - } - else - { - break; - } - } - - /* Enable any motion feature */ - if (sensor_sel & BMI2_ANY_MOT_SEL) - { - rslt = set_any_motion(BMI2_ENABLE, dev); - if (rslt == BMI2_OK) - { - dev->sens_en_stat |= BMI2_ANY_MOT_SEL; - } - else - { - break; - } - } - - /* Enable no motion feature */ - if (sensor_sel & BMI2_NO_MOT_SEL) - { - rslt = set_no_motion(BMI2_ENABLE, dev); - if (rslt == BMI2_OK) - { - dev->sens_en_stat |= BMI2_NO_MOT_SEL; - } - else - { - break; - } - } - - /* Enable step detector feature */ - if (sensor_sel & BMI2_STEP_DETECT_SEL) - { - rslt = set_step_detector(BMI2_ENABLE, dev); - if (rslt == BMI2_OK) - { - dev->sens_en_stat |= BMI2_STEP_DETECT_SEL; - } - else - { - break; - } - } - - /* Enable step counter feature */ - if (sensor_sel & BMI2_STEP_COUNT_SEL) - { - rslt = set_step_counter(BMI2_ENABLE, dev); - if (rslt == BMI2_OK) - { - dev->sens_en_stat |= BMI2_STEP_COUNT_SEL; - } - else - { - break; - } - } - - /* Enable step activity feature */ - if (sensor_sel & BMI2_STEP_ACT_SEL) - { - rslt = set_step_activity(BMI2_ENABLE, dev); - if (rslt == BMI2_OK) - { - dev->sens_en_stat |= BMI2_STEP_ACT_SEL; - } - else - { - break; - } - } - - /* Enable gyroscope user gain */ - if (sensor_sel & BMI2_GYRO_GAIN_UPDATE_SEL) - { - rslt = set_gyro_user_gain(BMI2_ENABLE, dev); - if (rslt == BMI2_OK) - { - dev->sens_en_stat |= BMI2_GYRO_GAIN_UPDATE_SEL; - } - else - { - break; - } - } - - /* Enable tilt feature */ - if (sensor_sel & BMI2_TILT_SEL) - { - rslt = set_tilt(BMI2_ENABLE, dev); - if (rslt == BMI2_OK) - { - dev->sens_en_stat |= BMI2_TILT_SEL; - } - else - { - break; - } - } - - /* Enable uphold to wake feature */ - if (sensor_sel & BMI2_UP_HOLD_TO_WAKE_SEL) - { - rslt = set_up_hold_to_wake(BMI2_ENABLE, dev); - if (rslt == BMI2_OK) - { - dev->sens_en_stat |= BMI2_UP_HOLD_TO_WAKE_SEL; - } - else - { - break; - } - } - - /* Enable glance feature */ - if (sensor_sel & BMI2_GLANCE_DET_SEL) - { - rslt = set_glance_detector(BMI2_ENABLE, dev); - if (rslt == BMI2_OK) - { - dev->sens_en_stat |= BMI2_GLANCE_DET_SEL; - } - else - { - break; - } - } - - /* Enable wake-up feature */ - if (sensor_sel & BMI2_WAKE_UP_SEL) - { - if (dev->chip_id == BMI261_CHIP_IDENTIFIER) - { - rslt = set_wake_up(BMI2_ENABLE, dev); - if (rslt == BMI2_OK) - { - dev->sens_en_stat |= BMI2_WAKE_UP_SEL; - } - else - { - break; - } - } - } - - /* Enable single tap feature */ - if (sensor_sel & BMI2_SINGLE_TAP_SEL) - { - rslt = set_single_tap(BMI2_ENABLE, dev); - if (rslt == BMI2_OK) - { - dev->sens_en_stat |= BMI2_SINGLE_TAP_SEL; - } - else - { - break; - } - } - - /* Enable double tap feature */ - if (sensor_sel & BMI2_DOUBLE_TAP_SEL) - { - rslt = set_double_tap(BMI2_ENABLE, dev); - if (rslt == BMI2_OK) - { - dev->sens_en_stat |= BMI2_DOUBLE_TAP_SEL; - } - else - { - break; - } - } - - /* Enable triple tap feature */ - if (sensor_sel & BMI2_TRIPLE_TAP_SEL) - { - rslt = set_triple_tap(BMI2_ENABLE, dev); - if (rslt == BMI2_OK) - { - dev->sens_en_stat |= BMI2_TRIPLE_TAP_SEL; - } - else - { - break; - } - } - - /* Enable orientation feature */ - if (sensor_sel & BMI2_ORIENT_SEL) - { - rslt = set_orientation(BMI2_ENABLE, dev); - if (rslt == BMI2_OK) - { - dev->sens_en_stat |= BMI2_ORIENT_SEL; - } - else - { - break; - } - } - - /* Enable high-g feature */ - if (sensor_sel & BMI2_HIGH_G_SEL) - { - rslt = set_high_g(BMI2_ENABLE, dev); - if (rslt == BMI2_OK) - { - dev->sens_en_stat |= BMI2_HIGH_G_SEL; - } - else - { - break; - } - } - - /* Enable low-g feature */ - if (sensor_sel & BMI2_LOW_G_SEL) - { - rslt = set_low_g(BMI2_ENABLE, dev); - if (rslt == BMI2_OK) - { - dev->sens_en_stat |= BMI2_LOW_G_SEL; - } - else - { - break; - } - } - - /* Enable flat feature */ - if (sensor_sel & BMI2_FLAT_SEL) - { - rslt = set_flat(BMI2_ENABLE, dev); - if (rslt == BMI2_OK) - { - dev->sens_en_stat |= BMI2_FLAT_SEL; - } - else - { - break; - } - } - - /* Enable external sensor feature */ - if (sensor_sel & BMI2_EXT_SENS_SEL) - { - rslt = set_ext_sens_sync(BMI2_ENABLE, dev); - if (rslt == BMI2_OK) - { - dev->sens_en_stat |= BMI2_EXT_SENS_SEL; - } - else - { - break; - } - } - - /* Enable gyroscope self-offset correction feature */ - if (sensor_sel & BMI2_GYRO_SELF_OFF_SEL) - { - rslt = set_gyro_self_offset_corr(BMI2_ENABLE, dev); - if (rslt == BMI2_OK) - { - dev->sens_en_stat |= BMI2_GYRO_SELF_OFF_SEL; - } - else - { - break; - } - } - - /* Enable wrist gesture feature */ - if (sensor_sel & BMI2_WRIST_GEST_SEL) - { - rslt = set_wrist_gesture(BMI2_ENABLE, dev); - if (rslt == BMI2_OK) - { - dev->sens_en_stat |= BMI2_WRIST_GEST_SEL; - } - else - { - break; - } - } - - /* Enable wrist wear wake-up feature */ - if (sensor_sel & BMI2_WRIST_WEAR_WAKE_UP_SEL) - { - rslt = set_wrist_wear_wake_up(BMI2_ENABLE, dev); - if (rslt == BMI2_OK) - { - dev->sens_en_stat |= BMI2_WRIST_WEAR_WAKE_UP_SEL; - } - else - { - break; - } - } - - /* Enable wrist gesture feature for wearable variant */ - if (sensor_sel & BMI2_WRIST_GEST_W_SEL) - { - rslt = set_wrist_gesture_wh(BMI2_ENABLE, dev); - if (rslt == BMI2_OK) - { - dev->sens_en_stat |= BMI2_WRIST_GEST_SEL; - } - else - { - break; - } - } - - /* Enable wrist wear wake-up feature for wearable variant */ - if (sensor_sel & BMI2_WRIST_WEAR_WAKE_UP_WH_SEL) - { - rslt = set_wrist_wear_wake_up_wh(BMI2_ENABLE, dev); - if (rslt == BMI2_OK) - { - dev->sens_en_stat |= BMI2_WRIST_WEAR_WAKE_UP_SEL; - } - else - { - break; - } - } - - /* Enable activity recognition feature */ - if (sensor_sel & BMI2_ACTIVITY_RECOGNITION_SEL) - { - rslt = set_act_recog(BMI2_ENABLE, dev); - if (rslt == BMI2_OK) - { - dev->sens_en_stat |= BMI2_ACTIVITY_RECOGNITION_SEL; - } - else - { - break; - } - } - - /* Enable accelerometer self-test feature */ - if (sensor_sel & BMI2_ACCEL_SELF_TEST_SEL) - { - rslt = set_feat_accel_self_test(BMI2_ENABLE, dev); - if (rslt == BMI2_OK) - { - dev->sens_en_stat |= BMI2_ACCEL_SELF_TEST_SEL; - } - else - { - break; - } - } - - /* Enable low pass filter feature for wearable variant */ - if (sensor_sel & BMI2_PRIMARY_OIS_SEL) - { - rslt = set_primary_ois_low_pass_filter(BMI2_ENABLE, dev); - if (rslt == BMI2_OK) - { - dev->sens_en_stat |= BMI2_PRIMARY_OIS_SEL; - } - else - { - break; - } - } - - if (sensor_sel & BMI2_FREE_FALL_DET_SEL) - { - rslt = set_free_fall_det(BMI2_ENABLE, dev); - if (rslt == BMI2_OK) - { - dev->sens_en_stat |= BMI2_FREE_FALL_DET_SEL; - } - else - { - break; - } - } - } - - /* Enable Advance power save if disabled while - * configuring and not when already disabled - */ - if ((aps_stat == BMI2_ENABLE) && (rslt == BMI2_OK)) - { - rslt = bmi2_set_adv_power_save(BMI2_ENABLE, dev); - } - } - } - - return rslt; -} - -/*! - * @brief This internal API disables the selected sensors/features. - */ -static int8_t sensor_disable(uint64_t sensor_sel, struct bmi2_dev *dev) -{ - /* Variable to define error */ - int8_t rslt; - - /* Variable to store register values */ - uint8_t reg_data = 0; - - /* Variable to define loop */ - uint8_t loop = 1; - - /* Variable to get the status of advance power save */ - uint8_t aps_stat = 0; - - rslt = bmi2_get_regs(BMI2_PWR_CTRL_ADDR, ®_data, 1, dev); - if (rslt == BMI2_OK) - { - /* Disable accelerometer */ - if (sensor_sel & BMI2_ACCEL_SENS_SEL) - { - reg_data = BMI2_SET_BIT_VAL0(reg_data, BMI2_ACC_EN); - } - - /* Disable gyroscope */ - if (sensor_sel & BMI2_GYRO_SENS_SEL) - { - reg_data = BMI2_SET_BIT_VAL0(reg_data, BMI2_GYR_EN); - } - - /* Disable auxiliary sensor */ - if (sensor_sel & BMI2_AUX_SENS_SEL) - { - reg_data = BMI2_SET_BIT_VAL0(reg_data, BMI2_AUX_EN); - } - - /* Disable temperature sensor */ - if (sensor_sel & BMI2_TEMP_SENS_SEL) - { - reg_data = BMI2_SET_BIT_VAL0(reg_data, BMI2_TEMP_EN); - } - - /* Disable the sensors that are set in the power control register */ - if (sensor_sel & BMI2_MAIN_SENSORS) - { - rslt = bmi2_set_regs(BMI2_PWR_CTRL_ADDR, ®_data, 1, dev); - } - } - - if ((rslt == BMI2_OK) && (sensor_sel & ~(BMI2_MAIN_SENSORS))) - { - /* Get status of advance power save mode */ - aps_stat = dev->aps_status; - if (aps_stat == BMI2_ENABLE) - { - /* Disable advance power save if enabled */ - rslt = bmi2_set_adv_power_save(BMI2_DISABLE, dev); - } - - if (rslt == BMI2_OK) - { - while (loop--) - { - /* Disable sig-motion feature */ - if (sensor_sel & BMI2_SIG_MOTION_SEL) - { - rslt = set_sig_motion(BMI2_DISABLE, dev); - if (rslt == BMI2_OK) - { - dev->sens_en_stat &= ~BMI2_SIG_MOTION_SEL; - } - else - { - break; - } - } - - /* Disable any-motion feature */ - if (sensor_sel & BMI2_ANY_MOT_SEL) - { - rslt = set_any_motion(BMI2_DISABLE, dev); - if (rslt == BMI2_OK) - { - dev->sens_en_stat &= ~BMI2_ANY_MOT_SEL; - } - else - { - break; - } - } - - /* Disable no-motion feature */ - if (sensor_sel & BMI2_NO_MOT_SEL) - { - rslt = set_no_motion(BMI2_DISABLE, dev); - if (rslt == BMI2_OK) - { - dev->sens_en_stat &= ~BMI2_NO_MOT_SEL; - } - else - { - break; - } - } - - /* Disable step detector feature */ - if (sensor_sel & BMI2_STEP_DETECT_SEL) - { - rslt = set_step_detector(BMI2_DISABLE, dev); - if (rslt == BMI2_OK) - { - dev->sens_en_stat &= ~BMI2_STEP_DETECT_SEL; - } - else - { - break; - } - } - - /* Disable step counter feature */ - if (sensor_sel & BMI2_STEP_COUNT_SEL) - { - rslt = set_step_counter(BMI2_DISABLE, dev); - if (rslt == BMI2_OK) - { - dev->sens_en_stat &= ~BMI2_STEP_COUNT_SEL; - } - else - { - break; - } - } - - /* Disable step activity feature */ - if (sensor_sel & BMI2_STEP_ACT_SEL) - { - rslt = set_step_activity(BMI2_DISABLE, dev); - if (rslt == BMI2_OK) - { - dev->sens_en_stat &= ~BMI2_STEP_ACT_SEL; - } - else - { - break; - } - } - - /* Disable gyroscope user gain */ - if (sensor_sel & BMI2_GYRO_GAIN_UPDATE_SEL) - { - rslt = set_gyro_user_gain(BMI2_DISABLE, dev); - if (rslt == BMI2_OK) - { - dev->sens_en_stat &= ~BMI2_GYRO_GAIN_UPDATE_SEL; - } - else - { - break; - } - } - - /* Disable tilt feature */ - if (sensor_sel & BMI2_TILT_SEL) - { - rslt = set_tilt(BMI2_DISABLE, dev); - if (rslt == BMI2_OK) - { - dev->sens_en_stat &= ~BMI2_TILT_SEL; - } - else - { - break; - } - } - - /* Disable uphold to wake feature */ - if (sensor_sel & BMI2_UP_HOLD_TO_WAKE_SEL) - { - rslt = set_up_hold_to_wake(BMI2_DISABLE, dev); - if (rslt == BMI2_OK) - { - dev->sens_en_stat &= ~BMI2_UP_HOLD_TO_WAKE_SEL; - } - else - { - break; - } - } - - /* Disable glance feature */ - if (sensor_sel & BMI2_GLANCE_DET_SEL) - { - rslt = set_glance_detector(BMI2_DISABLE, dev); - if (rslt == BMI2_OK) - { - dev->sens_en_stat &= ~BMI2_GLANCE_DET_SEL; - } - else - { - break; - } - } - - /* Disable wake-up feature */ - if (sensor_sel & BMI2_WAKE_UP_SEL) - { - rslt = set_wake_up(BMI2_DISABLE, dev); - if (rslt == BMI2_OK) - { - dev->sens_en_stat &= ~BMI2_WAKE_UP_SEL; - } - else - { - break; - } - } - - /* Disable single tap feature */ - if (sensor_sel & BMI2_SINGLE_TAP_SEL) - { - rslt = set_single_tap(BMI2_DISABLE, dev); - if (rslt == BMI2_OK) - { - dev->sens_en_stat &= ~BMI2_SINGLE_TAP_SEL; - } - else - { - break; - } - } - - /* Disable double tap feature */ - if (sensor_sel & BMI2_DOUBLE_TAP_SEL) - { - rslt = set_double_tap(BMI2_DISABLE, dev); - if (rslt == BMI2_OK) - { - dev->sens_en_stat &= ~BMI2_DOUBLE_TAP_SEL; - } - else - { - break; - } - } - - /* Disable triple tap feature */ - if (sensor_sel & BMI2_TRIPLE_TAP_SEL) - { - rslt = set_triple_tap(BMI2_DISABLE, dev); - if (rslt == BMI2_OK) - { - dev->sens_en_stat &= ~BMI2_TRIPLE_TAP_SEL; - } - else - { - break; - } - } - - /* Disable orientation feature */ - if (sensor_sel & BMI2_ORIENT_SEL) - { - rslt = set_orientation(BMI2_DISABLE, dev); - if (rslt == BMI2_OK) - { - dev->sens_en_stat &= ~BMI2_ORIENT_SEL; - } - else - { - break; - } - } - - /* Disable high-g feature */ - if (sensor_sel & BMI2_HIGH_G_SEL) - { - rslt = set_high_g(BMI2_DISABLE, dev); - if (rslt == BMI2_OK) - { - dev->sens_en_stat &= ~BMI2_HIGH_G_SEL; - } - else - { - break; - } - } - - /* Disable low-g feature */ - if (sensor_sel & BMI2_LOW_G_SEL) - { - rslt = set_low_g(BMI2_DISABLE, dev); - if (rslt == BMI2_OK) - { - dev->sens_en_stat &= ~BMI2_LOW_G_SEL; - } - else - { - break; - } - } - - /* Disable flat feature */ - if (sensor_sel & BMI2_FLAT_SEL) - { - rslt = set_flat(BMI2_DISABLE, dev); - if (rslt == BMI2_OK) - { - dev->sens_en_stat &= ~BMI2_FLAT_SEL; - } - else - { - break; - } - } - - /* Disable external sensor feature */ - if (sensor_sel & BMI2_EXT_SENS_SEL) - { - rslt = set_ext_sens_sync(BMI2_DISABLE, dev); - if (rslt == BMI2_OK) - { - dev->sens_en_stat &= ~BMI2_EXT_SENS_SEL; - } - else - { - break; - } - } - - /* Disable gyroscope self-offset correction feature */ - if (sensor_sel & BMI2_GYRO_SELF_OFF_SEL) - { - rslt = set_gyro_self_offset_corr(BMI2_DISABLE, dev); - if (rslt == BMI2_OK) - { - dev->sens_en_stat &= ~BMI2_GYRO_SELF_OFF_SEL; - } - else - { - break; - } - } - - /* Disable wrist gesture feature */ - if (sensor_sel & BMI2_WRIST_GEST_SEL) - { - rslt = set_wrist_gesture(BMI2_DISABLE, dev); - if (rslt == BMI2_OK) - { - dev->sens_en_stat &= ~BMI2_WRIST_GEST_SEL; - } - else - { - break; - } - } - - /* Disable wrist wear wake-up feature */ - if (sensor_sel & BMI2_WRIST_WEAR_WAKE_UP_SEL) - { - rslt = set_wrist_wear_wake_up(BMI2_DISABLE, dev); - if (rslt == BMI2_OK) - { - dev->sens_en_stat &= ~BMI2_WRIST_WEAR_WAKE_UP_SEL; - } - else - { - break; - } - } - - /* Disable wrist gesture feature for wearable variant*/ - if (sensor_sel & BMI2_WRIST_GEST_W_SEL) - { - rslt = set_wrist_gesture_wh(BMI2_DISABLE, dev); - if (rslt == BMI2_OK) - { - dev->sens_en_stat &= ~BMI2_WRIST_GEST_W_SEL; - } - else - { - break; - } - } - - /* Disable wrist wear wake-up feature for wearable variant */ - if (sensor_sel & BMI2_WRIST_WEAR_WAKE_UP_WH_SEL) - { - rslt = set_wrist_wear_wake_up_wh(BMI2_DISABLE, dev); - if (rslt == BMI2_OK) - { - dev->sens_en_stat &= ~BMI2_WRIST_WEAR_WAKE_UP_WH_SEL; - } - else - { - break; - } - } - - /* Disable activity recognition feature */ - if (sensor_sel & BMI2_ACTIVITY_RECOGNITION_SEL) - { - rslt = set_act_recog(BMI2_DISABLE, dev); - if (rslt == BMI2_OK) - { - dev->sens_en_stat |= BMI2_ACTIVITY_RECOGNITION_SEL; - } - else - { - break; - } - } - - /* Disable accelerometer self-test feature */ - if (sensor_sel & BMI2_ACCEL_SELF_TEST_SEL) - { - rslt = set_feat_accel_self_test(BMI2_DISABLE, dev); - if (rslt == BMI2_OK) - { - dev->sens_en_stat &= ~BMI2_ACCEL_SELF_TEST_SEL; - } - else - { - break; - } - } - - /* Disable accelerometer free-fall detection feature */ - if (sensor_sel & BMI2_FREE_FALL_DET_SEL) - { - rslt = set_free_fall_det(BMI2_DISABLE, dev); - if (rslt == BMI2_OK) - { - dev->sens_en_stat |= BMI2_FREE_FALL_DET_SEL; - } - else - { - break; - } - } - - /* Enable Advance power save if disabled while - * configuring and not when already disabled - */ - if ((aps_stat == BMI2_ENABLE) && (rslt == BMI2_OK)) - { - rslt = bmi2_set_adv_power_save(BMI2_ENABLE, dev); - } - } - } - } - - return rslt; -} - -/*! - * @brief This internal API selects the sensor/features to be enabled or - * disabled. - */ -static int8_t select_sensor(const uint8_t *sens_list, uint8_t n_sens, uint64_t *sensor_sel) -{ - /* Variable to define error */ - int8_t rslt = BMI2_OK; - - /* Variable to define loop */ - uint8_t count; - - for (count = 0; count < n_sens; count++) - { - switch (sens_list[count]) - { - case BMI2_ACCEL: - *sensor_sel |= BMI2_ACCEL_SENS_SEL; - break; - case BMI2_GYRO: - *sensor_sel |= BMI2_GYRO_SENS_SEL; - break; - case BMI2_AUX: - *sensor_sel |= BMI2_AUX_SENS_SEL; - break; - case BMI2_TEMP: - *sensor_sel |= BMI2_TEMP_SENS_SEL; - break; - case BMI2_SIG_MOTION: - *sensor_sel |= BMI2_SIG_MOTION_SEL; - break; - case BMI2_ANY_MOTION: - *sensor_sel |= BMI2_ANY_MOT_SEL; - break; - case BMI2_NO_MOTION: - *sensor_sel |= BMI2_NO_MOT_SEL; - break; - case BMI2_STEP_DETECTOR: - *sensor_sel |= BMI2_STEP_DETECT_SEL; - break; - case BMI2_STEP_COUNTER: - *sensor_sel |= BMI2_STEP_COUNT_SEL; - break; - case BMI2_STEP_ACTIVITY: - *sensor_sel |= BMI2_STEP_ACT_SEL; - break; - case BMI2_GYRO_GAIN_UPDATE: - *sensor_sel |= BMI2_GYRO_GAIN_UPDATE_SEL; - break; - case BMI2_TILT: - *sensor_sel |= BMI2_TILT_SEL; - break; - case BMI2_UP_HOLD_TO_WAKE: - *sensor_sel |= BMI2_UP_HOLD_TO_WAKE_SEL; - break; - case BMI2_GLANCE_DETECTOR: - *sensor_sel |= BMI2_GLANCE_DET_SEL; - break; - case BMI2_WAKE_UP: - *sensor_sel |= BMI2_WAKE_UP_SEL; - break; - case BMI2_SINGLE_TAP: - *sensor_sel |= BMI2_SINGLE_TAP_SEL; - break; - case BMI2_DOUBLE_TAP: - *sensor_sel |= BMI2_DOUBLE_TAP_SEL; - break; - case BMI2_TRIPLE_TAP: - *sensor_sel |= BMI2_TRIPLE_TAP_SEL; - break; - case BMI2_ORIENTATION: - *sensor_sel |= BMI2_ORIENT_SEL; - break; - case BMI2_HIGH_G: - *sensor_sel |= BMI2_HIGH_G_SEL; - break; - case BMI2_LOW_G: - *sensor_sel |= BMI2_LOW_G_SEL; - break; - case BMI2_FLAT: - *sensor_sel |= BMI2_FLAT_SEL; - break; - case BMI2_EXT_SENS_SYNC: - *sensor_sel |= BMI2_EXT_SENS_SEL; - break; - case BMI2_GYRO_SELF_OFF: - *sensor_sel |= BMI2_GYRO_SELF_OFF_SEL; - break; - case BMI2_WRIST_GESTURE: - *sensor_sel |= BMI2_WRIST_GEST_SEL; - break; - - case BMI2_WRIST_GESTURE_WH: - *sensor_sel |= BMI2_WRIST_GEST_W_SEL; - break; - case BMI2_WRIST_WEAR_WAKE_UP: - *sensor_sel |= BMI2_WRIST_WEAR_WAKE_UP_SEL; - break; - case BMI2_WRIST_WEAR_WAKE_UP_WH: - *sensor_sel |= BMI2_WRIST_WEAR_WAKE_UP_WH_SEL; - break; - case BMI2_ACTIVITY_RECOGNITION: - *sensor_sel |= BMI2_ACTIVITY_RECOGNITION_SEL; - break; - case BMI2_ACCEL_SELF_TEST: - *sensor_sel |= BMI2_ACCEL_SELF_TEST_SEL; - break; - case BMI2_PRIMARY_OIS: - *sensor_sel |= BMI2_PRIMARY_OIS_SEL; - break; - case BMI2_FREE_FALL_DET: - *sensor_sel |= BMI2_FREE_FALL_DET_SEL; - break; - default: - rslt = BMI2_E_INVALID_SENSOR; - break; - } - } - - return rslt; -} - -/*! - * @brief This internal API is used to enable/disable any motion feature. - */ -static int8_t set_any_motion(uint8_t enable, struct bmi2_dev *dev) -{ - /* Variable to define error */ - int8_t rslt; - - /* Array to define the feature configuration */ - uint8_t feat_config[BMI2_FEAT_SIZE_IN_BYTES] = { 0 }; - - /* Variable to define the array offset */ - uint8_t idx = 0; - - /* Variable to set flag */ - uint8_t feat_found; - - /* Initialize feature configuration for any-motion */ - struct bmi2_feature_config any_mot_config = { 0, 0, 0 }; - - /* Search for any-motion feature and extract its configurations details */ - feat_found = bmi2_extract_input_feat_config(&any_mot_config, BMI2_ANY_MOTION, dev); - if (feat_found) - { - /* Get the configuration from the page where any-motion feature resides */ - rslt = bmi2_get_feat_config(any_mot_config.page, feat_config, dev); - if (rslt == BMI2_OK) - { - /* Define the offset for enable/disable of any-motion axes */ - idx = any_mot_config.start_addr + BMI2_ANY_MOT_FEAT_EN_OFFSET; - - /* Set the feature enable bit */ - feat_config[idx] = BMI2_SET_BITS(feat_config[idx], BMI2_ANY_NO_MOT_EN, enable); - - /* Set the configuration back to the page */ - rslt = bmi2_set_regs(BMI2_FEATURES_REG_ADDR, feat_config, BMI2_FEAT_SIZE_IN_BYTES, dev); - } - } - else - { - rslt = BMI2_E_INVALID_SENSOR; - } - - return rslt; -} - -/*! - * @brief This internal API is used to enable/disable no-motion feature. - */ -static int8_t set_no_motion(uint8_t enable, struct bmi2_dev *dev) -{ - /* Variable to define error */ - int8_t rslt; - - /* Array to define the feature configuration */ - uint8_t feat_config[BMI2_FEAT_SIZE_IN_BYTES] = { 0 }; - - /* Variable to define the array offset */ - uint8_t idx = 0; - - /* Variable to set flag */ - uint8_t feat_found; - - /* Initialize feature configuration for no-motion */ - struct bmi2_feature_config no_mot_config = { 0, 0, 0 }; - - /* Search for no-motion feature and extract its configurations details */ - feat_found = bmi2_extract_input_feat_config(&no_mot_config, BMI2_NO_MOTION, dev); - if (feat_found) - { - /* Get the configuration from the page where any/no-motion feature resides */ - rslt = bmi2_get_feat_config(no_mot_config.page, feat_config, dev); - if (rslt == BMI2_OK) - { - /* Define the offset for enable/disable of no-motion axes */ - idx = no_mot_config.start_addr + BMI2_NO_MOT_FEAT_EN_OFFSET; - - /* Set the feature enable bit */ - feat_config[idx] = BMI2_SET_BITS(feat_config[idx], BMI2_ANY_NO_MOT_EN, enable); - - /* Set the configuration back to the page */ - rslt = bmi2_set_regs(BMI2_FEATURES_REG_ADDR, feat_config, BMI2_FEAT_SIZE_IN_BYTES, dev); - } - } - else - { - rslt = BMI2_E_INVALID_SENSOR; - } - - return rslt; -} - -/*! - * @brief This internal API is used to enable/disable sig-motion feature. - */ -static int8_t set_sig_motion(uint8_t enable, struct bmi2_dev *dev) -{ - /* Variable to define error */ - int8_t rslt; - - /* Array to define the feature configuration */ - uint8_t feat_config[BMI2_FEAT_SIZE_IN_BYTES] = { 0 }; - - /* Variable to define the array offset */ - uint8_t idx = 0; - - /* Variable to set flag */ - uint8_t feat_found; - - /* Initialize feature configuration for sig-motion */ - struct bmi2_feature_config sig_mot_config = { 0, 0, 0 }; - - /* Search for sig-motion feature and extract its configuration details */ - feat_found = bmi2_extract_input_feat_config(&sig_mot_config, BMI2_SIG_MOTION, dev); - if (feat_found) - { - /* Get the configuration from the page where sig-motion feature resides */ - rslt = bmi2_get_feat_config(sig_mot_config.page, feat_config, dev); - if (rslt == BMI2_OK) - { - /* Define the offset for enable/disable of sig-motion */ - idx = sig_mot_config.start_addr + BMI2_SIG_MOT_FEAT_EN_OFFSET; - - /* Set the feature enable bit */ - feat_config[idx] = BMI2_SET_BIT_POS0(feat_config[idx], BMI2_SIG_MOT_FEAT_EN, enable); - - /* Set the configuration back to the page */ - rslt = bmi2_set_regs(BMI2_FEATURES_REG_ADDR, feat_config, BMI2_FEAT_SIZE_IN_BYTES, dev); - } - } - else - { - rslt = BMI2_E_INVALID_SENSOR; - } - - return rslt; -} - -/*! - * @brief This internal API is used to enable/disable step detector feature. - */ -static int8_t set_step_detector(uint8_t enable, struct bmi2_dev *dev) -{ - /* Variable to define error */ - int8_t rslt; - - /* Array to define the feature configuration */ - uint8_t feat_config[BMI2_FEAT_SIZE_IN_BYTES] = { 0 }; - - /* Variable to define the array offset */ - uint8_t idx = 0; - - /* Variable to set flag */ - uint8_t feat_found; - - /* Initialize feature configuration for step detector */ - struct bmi2_feature_config step_det_config = { 0, 0, 0 }; - - /* Search for step detector feature and extract its configuration details */ - feat_found = bmi2_extract_input_feat_config(&step_det_config, BMI2_STEP_DETECTOR, dev); - if (feat_found) - { - /* Get the configuration from the page where step detector feature resides */ - rslt = bmi2_get_feat_config(step_det_config.page, feat_config, dev); - if (rslt == BMI2_OK) - { - /* Define the offset for enable/disable of step detector */ - idx = step_det_config.start_addr + BMI2_STEP_COUNT_FEAT_EN_OFFSET; - - /* Set the feature enable bit */ - feat_config[idx] = BMI2_SET_BITS(feat_config[idx], BMI2_STEP_DET_FEAT_EN, enable); - - /* Set the configuration back to the page */ - rslt = bmi2_set_regs(BMI2_FEATURES_REG_ADDR, feat_config, BMI2_FEAT_SIZE_IN_BYTES, dev); - } - } - else - { - rslt = BMI2_E_INVALID_SENSOR; - } - - return rslt; -} - -/*! - * @brief This internal API is used to enable/disable step counter feature. - */ -static int8_t set_step_counter(uint8_t enable, struct bmi2_dev *dev) -{ - /* Variable to define error */ - int8_t rslt; - - /* Array to define the feature configuration */ - uint8_t feat_config[BMI2_FEAT_SIZE_IN_BYTES] = { 0 }; - - /* Variable to define the array offset */ - uint8_t idx = 0; - - /* Variable to set flag */ - uint8_t feat_found; - - /* Initialize feature configuration for step counter */ - struct bmi2_feature_config step_count_config = { 0, 0, 0 }; - - /* Search for step counter feature and extract its configuration details */ - feat_found = bmi2_extract_input_feat_config(&step_count_config, BMI2_STEP_COUNTER, dev); - if (feat_found) - { - /* Get the configuration from the page where step-counter feature resides */ - rslt = bmi2_get_feat_config(step_count_config.page, feat_config, dev); - if (rslt == BMI2_OK) - { - /* Define the offset for enable/disable of step counter */ - idx = step_count_config.start_addr + BMI2_STEP_COUNT_FEAT_EN_OFFSET; - - /* Set the feature enable bit */ - feat_config[idx] = BMI2_SET_BITS(feat_config[idx], BMI2_STEP_COUNT_FEAT_EN, enable); - - /* Set the configuration back to the page */ - rslt = bmi2_set_regs(BMI2_FEATURES_REG_ADDR, feat_config, BMI2_FEAT_SIZE_IN_BYTES, dev); - } - } - else - { - rslt = BMI2_E_INVALID_SENSOR; - } - - return rslt; -} - -/*! - * @brief This internal API is used to enable/disable step activity detection. - */ -static int8_t set_step_activity(uint8_t enable, struct bmi2_dev *dev) -{ - /* Variable to define error */ - int8_t rslt; - - /* Array to define the feature configuration */ - uint8_t feat_config[BMI2_FEAT_SIZE_IN_BYTES] = { 0 }; - - /* Variable to define the array offset */ - uint8_t idx = 0; - - /* Variable to set flag */ - uint8_t feat_found; - - /* Initialize feature configuration for step activity */ - struct bmi2_feature_config step_act_config = { 0, 0, 0 }; - - /* Search for step activity feature and extract its configuration details */ - feat_found = bmi2_extract_input_feat_config(&step_act_config, BMI2_STEP_ACTIVITY, dev); - if (feat_found) - { - /* Get the configuration from the page where step-activity - * feature resides - */ - rslt = bmi2_get_feat_config(step_act_config.page, feat_config, dev); - if (rslt == BMI2_OK) - { - /* Define the offset for enable/disable of step activity */ - idx = step_act_config.start_addr + BMI2_STEP_COUNT_FEAT_EN_OFFSET; - - /* Set the feature enable bit */ - feat_config[idx] = BMI2_SET_BITS(feat_config[idx], BMI2_STEP_ACT_FEAT_EN, enable); - - /* Set the configuration back to the page */ - rslt = bmi2_set_regs(BMI2_FEATURES_REG_ADDR, feat_config, BMI2_FEAT_SIZE_IN_BYTES, dev); - } - } - else - { - rslt = BMI2_E_INVALID_SENSOR; - } - - return rslt; -} - -/*! - * @brief This internal API is used to enable/disable tilt feature. - */ -static int8_t set_tilt(uint8_t enable, struct bmi2_dev *dev) -{ - /* Variable to define error */ - int8_t rslt; - - /* Array to define the feature configuration */ - uint8_t feat_config[BMI2_FEAT_SIZE_IN_BYTES] = { 0 }; - - /* Variable to define the array offset */ - uint8_t idx = 0; - - /* Variable to set flag */ - uint8_t feat_found; - - /* Initialize feature configuration for tilt */ - struct bmi2_feature_config tilt_config = { 0, 0, 0 }; - - /* Search for tilt feature and extract its configuration details */ - feat_found = bmi2_extract_input_feat_config(&tilt_config, BMI2_TILT, dev); - if (feat_found) - { - /* Get the configuration from the page where tilt feature resides */ - rslt = bmi2_get_feat_config(tilt_config.page, feat_config, dev); - if (rslt == BMI2_OK) - { - /* Define the offset for enable/disable of tilt */ - idx = tilt_config.start_addr; - - /* Set the feature enable bit */ - feat_config[idx] = BMI2_SET_BIT_POS0(feat_config[idx], BMI2_TILT_FEAT_EN, enable); - - /* Set the configuration back to the page */ - rslt = bmi2_set_regs(BMI2_FEATURES_REG_ADDR, feat_config, BMI2_FEAT_SIZE_IN_BYTES, dev); - } - } - else - { - rslt = BMI2_E_INVALID_SENSOR; - } - - return rslt; -} - -/*! - * @brief This internal API is used to enable/disable uphold to wake feature. - */ -static int8_t set_up_hold_to_wake(uint8_t enable, struct bmi2_dev *dev) -{ - /* Variable to define error */ - int8_t rslt; - - /* Array to define the feature configuration */ - uint8_t feat_config[BMI2_FEAT_SIZE_IN_BYTES] = { 0 }; - - /* Variable to define the array offset */ - uint8_t idx = 0; - - /* Variable to set flag */ - uint8_t feat_found; - - /* Initialize feature configuration for uphold to wake */ - struct bmi2_feature_config up_hold_to_wake_config = { 0, 0, 0 }; - - /* Search for uphold to wake feature and extract its configuration details */ - feat_found = bmi2_extract_input_feat_config(&up_hold_to_wake_config, BMI2_UP_HOLD_TO_WAKE, dev); - if (feat_found) - { - /* Get the configuration from the page where uphold to wake feature resides */ - rslt = bmi2_get_feat_config(up_hold_to_wake_config.page, feat_config, dev); - if (rslt == BMI2_OK) - { - /* Define the offset for enable/disable of uphold to wake */ - idx = up_hold_to_wake_config.start_addr; - - /* Set the feature enable bit */ - feat_config[idx] = BMI2_SET_BIT_POS0(feat_config[idx], BMI2_UP_HOLD_TO_WAKE_FEAT_EN, enable); - - /* Set the configuration back to the page */ - rslt = bmi2_set_regs(BMI2_FEATURES_REG_ADDR, feat_config, BMI2_FEAT_SIZE_IN_BYTES, dev); - } - } - else - { - rslt = BMI2_E_INVALID_SENSOR; - } - - return rslt; -} - -/*! - * @brief This internal API is used to enable/disable glance detector feature. - */ -static int8_t set_glance_detector(uint8_t enable, struct bmi2_dev *dev) -{ - /* Variable to define error */ - int8_t rslt; - - /* Array to define the feature configuration */ - uint8_t feat_config[BMI2_FEAT_SIZE_IN_BYTES] = { 0 }; - - /* Variable to define the array offset */ - uint8_t idx = 0; - - /* Variable to set flag */ - uint8_t feat_found; - - /* Initialize feature configuration for glance detector */ - struct bmi2_feature_config glance_det_config = { 0, 0, 0 }; - - /* Search for glance detector feature and extract its configuration details */ - feat_found = bmi2_extract_input_feat_config(&glance_det_config, BMI2_GLANCE_DETECTOR, dev); - if (feat_found) - { - /* Get the configuration from the page where glance detector - * feature resides - */ - rslt = bmi2_get_feat_config(glance_det_config.page, feat_config, dev); - if (rslt == BMI2_OK) - { - /* Define the offset for enable/disable of glance */ - idx = glance_det_config.start_addr; - - /* Set the feature enable bit */ - feat_config[idx] = BMI2_SET_BIT_POS0(feat_config[idx], BMI2_GLANCE_FEAT_EN, enable); - - /* Set the configuration back to the page */ - rslt = bmi2_set_regs(BMI2_FEATURES_REG_ADDR, feat_config, BMI2_FEAT_SIZE_IN_BYTES, dev); - } - } - else - { - rslt = BMI2_E_INVALID_SENSOR; - } - - return rslt; -} - -/*! - * @brief This internal API is used to enable/disable wake-up feature through - * single or double tap. - */ -static int8_t set_wake_up(uint8_t enable, struct bmi2_dev *dev) -{ - /* Variable to define error */ - int8_t rslt; - - /* Array to define the feature configuration */ - uint8_t feat_config[BMI2_FEAT_SIZE_IN_BYTES] = { 0 }; - - /* Variable to define the array offset */ - uint8_t idx = 0; - - /* Variable to set flag */ - uint8_t feat_found; - - /* Initialize feature configuration for wake-up */ - struct bmi2_feature_config wake_up_config = { 0, 0, 0 }; - - /* Search for wake-up feature and extract its configuration details */ - feat_found = bmi2_extract_input_feat_config(&wake_up_config, BMI2_WAKE_UP, dev); - if (feat_found) - { - /* Get the configuration from the page where wake-up feature resides */ - rslt = bmi2_get_feat_config(wake_up_config.page, feat_config, dev); - if (rslt == BMI2_OK) - { - /* Define the offset for enable/disable of wake-up */ - idx = wake_up_config.start_addr; - - /* Set the feature enable bit */ - feat_config[idx] = BMI2_SET_BIT_POS0(feat_config[idx], BMI2_WAKE_UP_FEAT_EN, enable); - - /* Set the configuration back to the page */ - rslt = bmi2_set_regs(BMI2_FEATURES_REG_ADDR, feat_config, BMI2_FEAT_SIZE_IN_BYTES, dev); - } - } - else - { - rslt = BMI2_E_INVALID_SENSOR; - } - - return rslt; -} - -/*! - * @brief This internal API is used to enable/disable wake-up feature through - * single tap. - */ -static int8_t set_single_tap(uint8_t enable, struct bmi2_dev *dev) -{ - /* Variable to define error */ - int8_t rslt; - - /* Array to define the feature configuration */ - uint8_t feat_config[BMI2_FEAT_SIZE_IN_BYTES] = { 0 }; - - /* Variable to define the array offset */ - uint8_t idx = 0; - - /* Variable to set flag */ - uint8_t feat_found; - - /* Initialize feature configuration for wake-up */ - struct bmi2_feature_config wake_up_config = { 0, 0, 0 }; - - /* Search for wake-up feature and extract its configuration details */ - feat_found = bmi2_extract_input_feat_config(&wake_up_config, BMI2_SINGLE_TAP, dev); - if (feat_found) - { - /* Get the configuration from the page where wake-up feature resides */ - rslt = bmi2_get_feat_config(wake_up_config.page, feat_config, dev); - if (rslt == BMI2_OK) - { - /* Define the offset for enable/disable of wake-up */ - idx = wake_up_config.start_addr; - - /* Set the feature enable bit */ - feat_config[idx] = BMI2_SET_BIT_POS0(feat_config[idx], BMI2_WAKEUP_SINGLE_TAP_EN, enable); - - /* Set the configuration back to the page */ - rslt = bmi2_set_regs(BMI2_FEATURES_REG_ADDR, feat_config, BMI2_FEAT_SIZE_IN_BYTES, dev); - } - } - else - { - rslt = BMI2_E_INVALID_SENSOR; - } - - return rslt; -} - -/*! - * @brief This internal API is used to enable/disable wake-up feature through - * double tap. - */ -static int8_t set_double_tap(uint8_t enable, struct bmi2_dev *dev) -{ - /* Variable to define error */ - int8_t rslt; - - /* Array to define the feature configuration */ - uint8_t feat_config[BMI2_FEAT_SIZE_IN_BYTES] = { 0 }; - - /* Variable to define the array offset */ - uint8_t idx = 0; - - /* Variable to set flag */ - uint8_t feat_found; - - /* Initialize feature configuration for wake-up */ - struct bmi2_feature_config wake_up_config = { 0, 0, 0 }; - - /* Search for wake-up feature and extract its configuration details */ - feat_found = bmi2_extract_input_feat_config(&wake_up_config, BMI2_DOUBLE_TAP, dev); - if (feat_found) - { - /* Get the configuration from the page where wake-up feature resides */ - rslt = bmi2_get_feat_config(wake_up_config.page, feat_config, dev); - if (rslt == BMI2_OK) - { - /* Define the offset for enable/disable of wake-up */ - idx = wake_up_config.start_addr; - - /* Set the feature enable bit */ - feat_config[idx] = BMI2_SET_BITS(feat_config[idx], BMI2_WAKEUP_DOUBLE_TAP_EN, enable); - - /* Set the configuration back to the page */ - rslt = bmi2_set_regs(BMI2_FEATURES_REG_ADDR, feat_config, BMI2_FEAT_SIZE_IN_BYTES, dev); - } - } - else - { - rslt = BMI2_E_INVALID_SENSOR; - } - - return rslt; -} - -/*! - * @brief This internal API is used to enable/disable wake-up feature through - * triple tap. - */ -static int8_t set_triple_tap(uint8_t enable, struct bmi2_dev *dev) -{ - /* Variable to define error */ - int8_t rslt; - - /* Array to define the feature configuration */ - uint8_t feat_config[BMI2_FEAT_SIZE_IN_BYTES] = { 0 }; - - /* Variable to define the array offset */ - uint8_t idx = 0; - - /* Variable to set flag */ - uint8_t feat_found; - - /* Initialize feature configuration for wake-up */ - struct bmi2_feature_config wake_up_config = { 0, 0, 0 }; - - /* Search for wake-up feature and extract its configuration details */ - feat_found = bmi2_extract_input_feat_config(&wake_up_config, BMI2_TRIPLE_TAP, dev); - if (feat_found) - { - /* Get the configuration from the page where wake-up feature resides */ - rslt = bmi2_get_feat_config(wake_up_config.page, feat_config, dev); - if (rslt == BMI2_OK) - { - /* Define the offset for enable/disable of wake-up */ - idx = wake_up_config.start_addr; - - /* Set the feature enable bit */ - feat_config[idx] = BMI2_SET_BITS(feat_config[idx], BMI2_WAKEUP_TRIPLE_TAP_EN, enable); - - /* Set the configuration back to the page */ - rslt = bmi2_set_regs(BMI2_FEATURES_REG_ADDR, feat_config, BMI2_FEAT_SIZE_IN_BYTES, dev); - } - } - else - { - rslt = BMI2_E_INVALID_SENSOR; - } - - return rslt; -} - -/*! - * @brief This internal API is used to enable/disable orientation feature. - */ -static int8_t set_orientation(uint8_t enable, struct bmi2_dev *dev) -{ - /* Variable to define error */ - int8_t rslt; - - /* Array to define the feature configuration */ - uint8_t feat_config[BMI2_FEAT_SIZE_IN_BYTES] = { 0 }; - - /* Variable to define the array offset */ - uint8_t idx = 0; - - /* Variable to set flag */ - uint8_t feat_found; - - /* Initialize feature configuration for orientation */ - struct bmi2_feature_config orient_config = { 0, 0, 0 }; - - /* Search for orientation feature and extract its configuration details */ - feat_found = bmi2_extract_input_feat_config(&orient_config, BMI2_ORIENTATION, dev); - if (feat_found) - { - /* Get the configuration from the page where orientation feature resides */ - rslt = bmi2_get_feat_config(orient_config.page, feat_config, dev); - if (rslt == BMI2_OK) - { - /* Define the offset for enable/disable of orientation */ - idx = orient_config.start_addr; - - /* Set the feature enable bit */ - feat_config[idx] = BMI2_SET_BIT_POS0(feat_config[idx], BMI2_ORIENT_FEAT_EN, enable); - - /* Set the configuration back to the page */ - rslt = bmi2_set_regs(BMI2_FEATURES_REG_ADDR, feat_config, BMI2_FEAT_SIZE_IN_BYTES, dev); - } - } - else - { - rslt = BMI2_E_INVALID_SENSOR; - } - - return rslt; -} - -/*! - * @brief This internal API is used to enable/disable high-g feature. - */ -static int8_t set_high_g(uint8_t enable, struct bmi2_dev *dev) -{ - /* Variable to define error */ - int8_t rslt; - - /* Array to define the feature configuration */ - uint8_t feat_config[BMI2_FEAT_SIZE_IN_BYTES] = { 0 }; - - /* Variable to define the array offset */ - uint8_t idx = 0; - - /* Variable to set flag */ - uint8_t feat_found; - - /* Initialize feature configuration for high-g */ - struct bmi2_feature_config high_g_config = { 0, 0, 0 }; - - /* Search for high-g feature and extract its configuration details */ - feat_found = bmi2_extract_input_feat_config(&high_g_config, BMI2_HIGH_G, dev); - if (feat_found) - { - /* Get the configuration from the page where high-g feature resides */ - rslt = bmi2_get_feat_config(high_g_config.page, feat_config, dev); - if (rslt == BMI2_OK) - { - /* Define the offset for enable/disable of high-g */ - idx = high_g_config.start_addr + BMI2_HIGH_G_FEAT_EN_OFFSET; - - /* Set the feature enable bit */ - feat_config[idx] = BMI2_SET_BITS(feat_config[idx], BMI2_HIGH_G_FEAT_EN, enable); - - /* Set the configuration back to the page */ - rslt = bmi2_set_regs(BMI2_FEATURES_REG_ADDR, feat_config, BMI2_FEAT_SIZE_IN_BYTES, dev); - } - } - else - { - rslt = BMI2_E_INVALID_SENSOR; - } - - return rslt; -} - -/*! - * @brief This internal API is used to enable/disable low-g feature. - */ -static int8_t set_low_g(uint8_t enable, struct bmi2_dev *dev) -{ - /* Variable to define error */ - int8_t rslt; - - /* Array to define the feature configuration */ - uint8_t feat_config[BMI2_FEAT_SIZE_IN_BYTES] = { 0 }; - - /* Variable to define the array offset */ - uint8_t idx = 0; - - /* Variable to set flag */ - uint8_t feat_found; - - /* Initialize feature configuration for low-g */ - struct bmi2_feature_config low_g_config = { 0, 0, 0 }; - - /* Search for low-g feature and extract its configuration details */ - feat_found = bmi2_extract_input_feat_config(&low_g_config, BMI2_LOW_G, dev); - if (feat_found) - { - /* Get the configuration from the page where low-g feature resides */ - rslt = bmi2_get_feat_config(low_g_config.page, feat_config, dev); - if (rslt == BMI2_OK) - { - /* Define the offset for enable/disable of low-g */ - idx = low_g_config.start_addr + BMI2_LOW_G_FEAT_EN_OFFSET; - - /* Set the feature enable bit */ - feat_config[idx] = BMI2_SET_BITS(feat_config[idx], BMI2_LOW_G_FEAT_EN, enable); - - /* Set the configuration back to the page */ - rslt = bmi2_set_regs(BMI2_FEATURES_REG_ADDR, feat_config, BMI2_FEAT_SIZE_IN_BYTES, dev); - } - } - else - { - rslt = BMI2_E_INVALID_SENSOR; - } - - return rslt; -} - -/*! - * @brief This internal API is used to enable/disable flat feature. - */ -static int8_t set_flat(uint8_t enable, struct bmi2_dev *dev) -{ - /* Variable to define error */ - int8_t rslt; - - /* Array to define the feature configuration */ - uint8_t feat_config[BMI2_FEAT_SIZE_IN_BYTES] = { 0 }; - - /* Variable to define the array offset */ - uint8_t idx = 0; - - /* Variable to set flag */ - uint8_t feat_found; - - /* Initialize feature configuration for flat */ - struct bmi2_feature_config flat_config = { 0, 0, 0 }; - - /* Search for flat feature and extract its configuration details */ - feat_found = bmi2_extract_input_feat_config(&flat_config, BMI2_FLAT, dev); - if (feat_found) - { - /* Get the configuration from the page where flat feature resides */ - rslt = bmi2_get_feat_config(flat_config.page, feat_config, dev); - if (rslt == BMI2_OK) - { - /* Define the offset for enable/disable of flat */ - idx = flat_config.start_addr; - - /* Set the feature enable bit */ - feat_config[idx] = BMI2_SET_BIT_POS0(feat_config[idx], BMI2_FLAT_FEAT_EN, enable); - - /* Set the configuration back to the page */ - rslt = bmi2_set_regs(BMI2_FEATURES_REG_ADDR, feat_config, BMI2_FEAT_SIZE_IN_BYTES, dev); - } - } - else - { - rslt = BMI2_E_INVALID_SENSOR; - } - - return rslt; -} - -/*! - * @brief This internal API is used to enable/disable external sensor sync - * feature. - */ -static int8_t set_ext_sens_sync(uint8_t enable, struct bmi2_dev *dev) -{ - /* Variable to define error */ - int8_t rslt; - - /* Array to define the feature configuration */ - uint8_t feat_config[BMI2_FEAT_SIZE_IN_BYTES] = { 0 }; - - /* Variable to define the array offset */ - uint8_t idx = 0; - - /* Variable to set flag */ - uint8_t feat_found; - - /* Initialize feature configuration for external sensor sync */ - struct bmi2_feature_config ext_sens_sync_cfg = { 0, 0, 0 }; - - /* Search for sync feature and extract its configuration details */ - feat_found = bmi2_extract_input_feat_config(&ext_sens_sync_cfg, BMI2_EXT_SENS_SYNC, dev); - if (feat_found) - { - /* Get the configuration from the page where sync feature resides */ - rslt = bmi2_get_feat_config(ext_sens_sync_cfg.page, feat_config, dev); - if (rslt == BMI2_OK) - { - /* Define the offset for enable/disable of sync */ - idx = ext_sens_sync_cfg.start_addr; - - /* Set the feature enable bit */ - feat_config[idx] = BMI2_SET_BIT_POS0(feat_config[idx], BMI2_EXT_SENS_SYNC_FEAT_EN, enable); - - /* Set the configuration back to the page */ - rslt = bmi2_set_regs(BMI2_FEATURES_REG_ADDR, feat_config, BMI2_FEAT_SIZE_IN_BYTES, dev); - } - } - else - { - rslt = BMI2_E_INVALID_SENSOR; - } - - return rslt; -} - -/*! - * @brief This internal API gives an option to enable self-offset correction - * feature of gyroscope, either internally or by the host. - */ -static int8_t set_gyro_self_offset_corr(uint8_t enable, struct bmi2_dev *dev) -{ - /* Variable to define error */ - int8_t rslt; - - /* Array to define the feature configuration */ - uint8_t feat_config[BMI2_FEAT_SIZE_IN_BYTES] = { 0 }; - - /* Variable to define the array offset */ - uint8_t idx = 0; - - /* Variable to set flag */ - uint8_t feat_found; - - /* Initialize feature configuration for self-offset correction */ - struct bmi2_feature_config self_off_corr_cfg = { 0, 0, 0 }; - - /* Search for self-offset correction and extract its configuration details */ - feat_found = bmi2_extract_input_feat_config(&self_off_corr_cfg, BMI2_GYRO_SELF_OFF, dev); - if (feat_found) - { - /* Get the configuration from the page where self-offset - * correction feature resides - */ - rslt = bmi2_get_feat_config(self_off_corr_cfg.page, feat_config, dev); - if (rslt == BMI2_OK) - { - /* Define the offset for enable/disable of self-offset correction */ - idx = self_off_corr_cfg.start_addr; - - /* Set the feature enable bit */ - feat_config[idx] = BMI2_SET_BITS(feat_config[idx], BMI2_GYR_SELF_OFF_CORR_FEAT_EN, enable); - - /* Set the configuration back to the page */ - rslt = bmi2_set_regs(BMI2_FEATURES_REG_ADDR, feat_config, BMI2_FEAT_SIZE_IN_BYTES, dev); - } - } - else - { - rslt = BMI2_E_INVALID_SENSOR; - } - - return rslt; -} - -/*! - * @brief This internal API enables the wrist gesture feature. - */ -static int8_t set_wrist_gesture(uint8_t enable, struct bmi2_dev *dev) -{ - /* Variable to define error */ - int8_t rslt; - - /* Array to define the feature configuration */ - uint8_t feat_config[BMI2_FEAT_SIZE_IN_BYTES] = { 0 }; - - /* Variable to define the array offset */ - uint8_t idx = 0; - - /* Variable to set flag */ - uint8_t feat_found; - - /* Initialize feature configuration for wrist gesture */ - struct bmi2_feature_config wrist_gest_cfg = { 0, 0, 0 }; - - /* Search for wrist gesture and extract its configuration details */ - feat_found = bmi2_extract_input_feat_config(&wrist_gest_cfg, BMI2_WRIST_GESTURE, dev); - if (feat_found) - { - /* Get the configuration from the page where wrist gesture feature resides */ - rslt = bmi2_get_feat_config(wrist_gest_cfg.page, feat_config, dev); - if (rslt == BMI2_OK) - { - /* Define the offset for enable/disable of wrist gesture */ - idx = wrist_gest_cfg.start_addr; - - /* Set the feature enable bit */ - feat_config[idx] = BMI2_SET_BITS(feat_config[idx], BMI2_WRIST_GEST_FEAT_EN, enable); - - /* Set the configuration back to the page */ - rslt = bmi2_set_regs(BMI2_FEATURES_REG_ADDR, feat_config, BMI2_FEAT_SIZE_IN_BYTES, dev); - } - } - else - { - rslt = BMI2_E_INVALID_SENSOR; - } - - return rslt; -} - -/*! - * @brief This internal API enables the wrist wear wake up feature. - */ -static int8_t set_wrist_wear_wake_up(uint8_t enable, struct bmi2_dev *dev) -{ - /* Variable to define error */ - int8_t rslt; - - /* Array to define the feature configuration */ - uint8_t feat_config[BMI2_FEAT_SIZE_IN_BYTES] = { 0 }; - - /* Variable to define the array offset */ - uint8_t idx = 0; - - /* Variable to set flag */ - uint8_t feat_found; - - /* Initialize feature configuration for wrist wear wake up */ - struct bmi2_feature_config wrist_wake_up_cfg = { 0, 0, 0 }; - - /* Search for wrist wear wake up and extract its configuration details */ - feat_found = bmi2_extract_input_feat_config(&wrist_wake_up_cfg, BMI2_WRIST_WEAR_WAKE_UP, dev); - if (feat_found) - { - /* Get the configuration from the page where wrist wear wake up - * feature resides - */ - rslt = bmi2_get_feat_config(wrist_wake_up_cfg.page, feat_config, dev); - if (rslt == BMI2_OK) - { - /* Define the offset for enable/disable of wrist wear wake up */ - idx = wrist_wake_up_cfg.start_addr; - - /* Set the feature enable bit */ - feat_config[idx] = BMI2_SET_BITS(feat_config[idx], BMI2_WRIST_WEAR_WAKE_UP_FEAT_EN, enable); - - /* Set the configuration back to the page */ - rslt = bmi2_set_regs(BMI2_FEATURES_REG_ADDR, feat_config, BMI2_FEAT_SIZE_IN_BYTES, dev); - } - } - else - { - rslt = BMI2_E_INVALID_SENSOR; - } - - return rslt; -} - -/*! - * @brief This internal API enables the wrist gesture feature. - */ -static int8_t set_wrist_gesture_wh(uint8_t enable, struct bmi2_dev *dev) -{ - /* Variable to define error */ - int8_t rslt; - - /* Array to define the feature configuration */ - uint8_t feat_config[BMI2_FEAT_SIZE_IN_BYTES] = { 0 }; - - /* Variable to define the array offset */ - uint8_t idx = 0; - - /* Variable to set flag */ - uint8_t feat_found; - - /* Initialize feature configuration for wrist gesture */ - struct bmi2_feature_config wrist_gest_cfg = { 0, 0, 0 }; - - /* Search for wrist gesture and extract its configuration details */ - feat_found = bmi2_extract_input_feat_config(&wrist_gest_cfg, BMI2_WRIST_GESTURE_WH, dev); - if (feat_found) - { - /* Get the configuration from the page where wrist gesture feature resides */ - rslt = bmi2_get_feat_config(wrist_gest_cfg.page, feat_config, dev); - if (rslt == BMI2_OK) - { - /* Define the offset for enable/disable of wrist gesture */ - idx = wrist_gest_cfg.start_addr; - - /* Set the feature enable bit */ - feat_config[idx] = BMI2_SET_BITS(feat_config[idx], BMI2_WRIST_GEST_FEAT_EN, enable); - - /* Set the configuration back to the page */ - rslt = bmi2_set_regs(BMI2_FEATURES_REG_ADDR, feat_config, BMI2_FEAT_SIZE_IN_BYTES, dev); - } - } - else - { - rslt = BMI2_E_INVALID_SENSOR; - } - - return rslt; -} - -/*! - * @brief This internal API enables the wrist wear wake up feature. - */ -static int8_t set_wrist_wear_wake_up_wh(uint8_t enable, struct bmi2_dev *dev) -{ - /* Variable to define error */ - int8_t rslt; - - /* Array to define the feature configuration */ - uint8_t feat_config[BMI2_FEAT_SIZE_IN_BYTES] = { 0 }; - - /* Variable to define the array offset */ - uint8_t idx = 0; - - /* Variable to set flag */ - uint8_t feat_found; - - /* Initialize feature configuration for wrist wear wake up */ - struct bmi2_feature_config wrist_wake_up_cfg = { 0, 0, 0 }; - - /* Search for wrist wear wake up and extract its configuration details */ - feat_found = bmi2_extract_input_feat_config(&wrist_wake_up_cfg, BMI2_WRIST_WEAR_WAKE_UP_WH, dev); - if (feat_found) - { - /* Get the configuration from the page where wrist wear wake up - * feature resides - */ - rslt = bmi2_get_feat_config(wrist_wake_up_cfg.page, feat_config, dev); - if (rslt == BMI2_OK) - { - /* Define the offset for enable/disable of wrist wear wake up */ - idx = wrist_wake_up_cfg.start_addr; - - /* Set the feature enable bit */ - feat_config[idx] = BMI2_SET_BITS(feat_config[idx], BMI2_WRIST_WEAR_WAKE_UP_FEAT_EN, enable); - - /* Set the configuration back to the page */ - rslt = bmi2_set_regs(BMI2_FEATURES_REG_ADDR, feat_config, BMI2_FEAT_SIZE_IN_BYTES, dev); - } - } - else - { - rslt = BMI2_E_INVALID_SENSOR; - } - - return rslt; -} - -/*! - * @brief This internal API enables/disables the activity recognition feature. + * @retval 0 -> Success + * @retval < 0 -> Fail */ -static int8_t set_act_recog(uint8_t enable, struct bmi2_dev *dev) -{ - /* Variable to define error */ - int8_t rslt; - - /* Array to define the feature configuration */ - uint8_t feat_config[BMI2_FEAT_SIZE_IN_BYTES] = { 0 }; - - /* Variable to define the array offset */ - uint8_t idx = 0; - - /* Variable to set flag */ - uint8_t feat_found; - - /* Initialize feature configuration for activity recognition */ - struct bmi2_feature_config act_recog_cfg = { 0, 0, 0 }; - - /* Search for activity recognition and extract its configuration details */ - feat_found = bmi2_extract_input_feat_config(&act_recog_cfg, BMI2_ACTIVITY_RECOGNITION, dev); - if (feat_found) - { - /* Get the configuration from the page where activity - * recognition feature resides - */ - rslt = bmi2_get_feat_config(act_recog_cfg.page, feat_config, dev); - if (rslt == BMI2_OK) - { - /* Define the offset for enable/disable of activity recognition */ - idx = act_recog_cfg.start_addr; - - /* Set the feature enable bit */ - feat_config[idx] = BMI2_SET_BIT_POS0(feat_config[idx], BMI2_ACTIVITY_RECOG_EN, enable); - - /* Set the configuration back to the page */ - rslt = bmi2_set_regs(BMI2_FEATURES_REG_ADDR, feat_config, BMI2_FEAT_SIZE_IN_BYTES, dev); - } - } - else - { - rslt = BMI2_E_INVALID_SENSOR; - } +static int8_t sensor_disable(uint64_t sensor_sel, struct bmi2_dev *dev); - return rslt; -} +/******************************************************************************/ +/*! @name User Interface Definitions */ +/******************************************************************************/ /*! - * @brief This internal API is used to enable/disable gyroscope user gain - * feature. + * @brief This API is the entry point for bmi2 sensor. It selects between + * I2C/SPI interface, based on user selection. It reads and validates the + * chip-id of the sensor. */ -static int8_t set_gyro_user_gain(uint8_t enable, struct bmi2_dev *dev) +int8_t bmi2_sec_init(struct bmi2_dev *dev) { /* Variable to define error */ int8_t rslt; - /* Array to define the feature configuration */ - uint8_t feat_config[BMI2_FEAT_SIZE_IN_BYTES] = { 0 }; - - /* Variable to define the array offset */ - uint8_t idx = 0; - - /* Variable to set flag */ - uint8_t feat_found; - - /* Initialize feature configuration for gyroscope user gain */ - struct bmi2_feature_config gyr_user_gain_cfg = { 0, 0, 0 }; - - /* Search for user gain feature and extract its configuration details */ - feat_found = bmi2_extract_input_feat_config(&gyr_user_gain_cfg, BMI2_GYRO_GAIN_UPDATE, dev); - if (feat_found) - { - /* Get the configuration from the page where user gain feature resides */ - rslt = bmi2_get_feat_config(gyr_user_gain_cfg.page, feat_config, dev); - if (rslt == BMI2_OK) - { - /* Define the offset for enable/disable of user gain */ - idx = gyr_user_gain_cfg.start_addr + BMI2_GYR_USER_GAIN_FEAT_EN_OFFSET; - - /* Set the feature enable bit */ - feat_config[idx] = BMI2_SET_BITS(feat_config[idx], BMI2_GYR_USER_GAIN_FEAT_EN, enable); - - /* Set the configuration back to the page */ - rslt = bmi2_set_regs(BMI2_FEATURES_REG_ADDR, feat_config, BMI2_FEAT_SIZE_IN_BYTES, dev); - } - } - else - { - rslt = BMI2_E_INVALID_SENSOR; - } - - return rslt; -} - -/*! - * @brief This internal API gives an option to enable accelerometer self-test - * in the feature register. - */ -static int8_t set_feat_accel_self_test(uint8_t enable, struct bmi2_dev *dev) -{ - int8_t rslt = BMI2_OK; - uint8_t feat_config[BMI2_FEAT_SIZE_IN_BYTES] = { 0 }; - uint8_t idx = 0; - uint8_t feat_found; - struct bmi2_feature_config acc_feat_self_test_cfg = { 0, 0, 0 }; - - /* Search for accelerometer self-test and extract its configuration details */ - feat_found = bmi2_extract_input_feat_config(&acc_feat_self_test_cfg, BMI2_ACCEL_SELF_TEST, dev); - if (feat_found) - { - /* Get the configuration from the page where accelerometer self-test feature resides */ - rslt = bmi2_get_feat_config(acc_feat_self_test_cfg.page, feat_config, dev); - if (rslt == BMI2_OK) - { - /* Define the offset for enable/disable of accelerometer self-test */ - idx = acc_feat_self_test_cfg.start_addr; - - /* Set the feature enable bit */ - feat_config[idx] = BMI2_SET_BITS(feat_config[idx], BMI2_ACC_SELF_TEST_FEAT_EN, enable); - - /* Set the configuration back to the page */ - rslt = bmi2_set_regs(BMI2_FEATURES_REG_ADDR, feat_config, BMI2_FEAT_SIZE_IN_BYTES, dev); - - /* Delay added as per the firmware spec */ - dev->delay_us(160000, dev->intf_ptr); - } - } - else - { - rslt = BMI2_E_INVALID_SENSOR; - } - - return rslt; -} + /* Variable to assign chip id */ + uint8_t chip_id = 0; -/*! - * @brief This internal API gives an option to enable low pass filter - * in the feature register. - */ -static int8_t set_primary_ois_low_pass_filter(uint8_t enable, struct bmi2_dev *dev) -{ - int8_t rslt = BMI2_OK; - uint8_t feat_config[BMI2_FEAT_SIZE_IN_BYTES] = { 0 }; - uint8_t idx = 0; - uint8_t feat_found; - struct bmi2_feature_config primary_ois_lp_filter_cfg = { 0, 0, 0 }; + /* Structure to define the default values for axes re-mapping */ + struct bmi2_axes_remap axes_remap = { + .x_axis = BMI2_MAP_X_AXIS, .x_axis_sign = BMI2_POS_SIGN, .y_axis = BMI2_MAP_Y_AXIS, + .y_axis_sign = BMI2_POS_SIGN, .z_axis = BMI2_MAP_Z_AXIS, .z_axis_sign = BMI2_POS_SIGN + }; - /* Search for low pass filter and extract its configuration details */ - feat_found = bmi2_extract_input_feat_config(&primary_ois_lp_filter_cfg, BMI2_PRIMARY_OIS, dev); - if (feat_found) + /* Null-pointer check */ + rslt = null_ptr_check(dev); + if (rslt == BMI2_OK) { - /* Get the configuration from the page where low pass filter feature resides */ - rslt = bmi2_get_feat_config(primary_ois_lp_filter_cfg.page, feat_config, dev); + /* Perform soft-reset to bring all register values to their + * default values + */ + rslt = bmi2_soft_reset(dev); + if (rslt == BMI2_OK) { - /* Define the offset for enable/disable of low pass filter */ - idx = primary_ois_lp_filter_cfg.start_addr; + /* Read chip-id of the BMI2 sensor */ + rslt = bmi2_get_regs(BMI2_CHIP_ID_ADDR, &chip_id, 1, dev); - /* Set the feature enable bit */ - feat_config[idx] = BMI2_SET_BIT_POS0(feat_config[idx], BMI2_LP_FILTER_EN, enable); + if (rslt == BMI2_OK) + { + /* Validate chip-id */ + if (chip_id == dev->chip_id) + { + /* Assign resolution to the structure */ + dev->resolution = 16; - /* Set the configuration back to the page */ - rslt = bmi2_set_regs(BMI2_FEATURES_REG_ADDR, feat_config, BMI2_FEAT_SIZE_IN_BYTES, dev); + /* Set manual enable flag */ + dev->aux_man_en = 1; + /* Set the default values for axis + * re-mapping in the device structure + */ + dev->remap = axes_remap; + } + else + { + /* Storing the chip-id value read from + * the register to identify the sensor + */ + dev->chip_id = chip_id; + rslt = BMI2_E_DEV_NOT_FOUND; + } + } } } - else - { - rslt = BMI2_E_INVALID_SENSOR; - } return rslt; } /*! - * @brief This internal API sets accelerometer configurations like ODR, - * bandwidth, performance mode and g-range. + * @brief This API reads the data from the given register address of bmi2 + * sensor. + * + * @note For most of the registers auto address increment applies, with the + * exception of a few special registers, which trap the address. For e.g., + * Register address - 0x26, 0x5E. */ -static int8_t set_accel_config(struct bmi2_accel_config *config, struct bmi2_dev *dev) +int8_t bmi2_get_regs(uint8_t reg_addr, uint8_t *data, uint16_t len, struct bmi2_dev *dev) { /* Variable to define error */ int8_t rslt; - /* Variable to store data */ - uint8_t reg_data; - - /* Array to store the default value of accelerometer configuration - * reserved registers - */ - uint8_t data_array[2] = { 0 }; + /* Variable to define loop */ + uint16_t index = 0; - /* Validate bandwidth and performance mode */ - rslt = validate_bw_perf_mode(&config->bwp, &config->filter_perf, dev); - if (rslt == BMI2_OK) + /* Null-pointer check */ + rslt = null_ptr_check(dev); + if ((rslt == BMI2_OK) && (data != NULL)) { - /* Validate ODR and range */ - rslt = validate_odr_range(&config->odr, &config->range, dev); - if (rslt == BMI2_OK) - { - /* Set accelerometer performance mode */ - reg_data = BMI2_SET_BITS(data_array[0], BMI2_ACC_FILTER_PERF_MODE, config->filter_perf); - - /* Set accelerometer bandwidth */ - reg_data = BMI2_SET_BITS(reg_data, BMI2_ACC_BW_PARAM, config->bwp); - - /* Set accelerometer ODR */ - reg_data = BMI2_SET_BIT_POS0(reg_data, BMI2_ACC_ODR, config->odr); + /* Variable to define temporary length */ + uint16_t temp_len = len + dev->dummy_byte; - /* Copy the register data to the array */ - data_array[0] = reg_data; + /* Variable to define temporary buffer */ + uint8_t temp_buf[temp_len]; - /* Set accelerometer range */ - reg_data = BMI2_SET_BIT_POS0(data_array[1], BMI2_ACC_RANGE, config->range); + /* Configuring reg_addr for SPI Interface */ + if (dev->intf == BMI2_SPI_INTF) + { + reg_addr = (reg_addr | BMI2_SPI_RD_MASK); + } - /* Copy the register data to the array */ - data_array[1] = reg_data; + dev->intf_rslt = dev->read(reg_addr, temp_buf, temp_len, dev->intf_ptr); - /* Write accelerometer configuration to ACC_CONFand - * ACC_RANGE registers simultaneously as they lie in consecutive places - */ - rslt = bmi2_set_regs(BMI2_ACC_CONF_ADDR, data_array, 2, dev); + if (dev->aps_status == BMI2_ENABLE) + { + dev->delay_us(450, dev->intf_ptr); + } + else + { + dev->delay_us(2, dev->intf_ptr); + } - /* Get error status to check for invalid configurations */ - if (rslt == BMI2_OK) + if (dev->intf_rslt == BMI2_INTF_RET_SUCCESS) + { + /* Read the data from the position next to dummy byte */ + while (index < len) { - rslt = cfg_error_status(dev); + data[index] = temp_buf[index + dev->dummy_byte]; + index++; } } + else + { + rslt = BMI2_E_COM_FAIL; + } + } + else + { + rslt = BMI2_E_NULL_PTR; } return rslt; } /*! - * @brief This internal API validates bandwidth and performance mode of the - * accelerometer set by the user. + * @brief This API writes data to the given register address of bmi2 sensor. */ -static int8_t validate_bw_perf_mode(uint8_t *bandwidth, uint8_t *perf_mode, struct bmi2_dev *dev) +int8_t bmi2_set_regs(uint8_t reg_addr, const uint8_t *data, uint16_t len, struct bmi2_dev *dev) { /* Variable to define error */ int8_t rslt; - /* Validate and auto-correct performance mode */ - rslt = check_boundary_val(perf_mode, BMI2_POWER_OPT_MODE, BMI2_PERF_OPT_MODE, dev); - if (rslt == BMI2_OK) + /* Null-pointer check */ + rslt = null_ptr_check(dev); + if ((rslt == BMI2_OK) && (data != NULL)) { - /* Validate and auto-correct bandwidth parameter */ - if (*perf_mode == BMI2_PERF_OPT_MODE) + /* Configuring reg_addr for SPI Interface */ + if (dev->intf == BMI2_SPI_INTF) { - /* Validate for continuous filter mode */ - rslt = check_boundary_val(bandwidth, BMI2_ACC_OSR4_AVG1, BMI2_ACC_CIC_AVG8, dev); + reg_addr = (reg_addr & BMI2_SPI_WR_MASK); + } + + dev->intf_rslt = dev->write(reg_addr, data, len, dev->intf_ptr); + + /* Delay for Low power mode of the sensor is 450 us */ + if (dev->aps_status == BMI2_ENABLE) + { + dev->delay_us(450, dev->intf_ptr); } + /* Delay for Normal mode of the sensor is 2 us */ else { - /* Validate for CIC averaging mode */ - rslt = check_boundary_val(bandwidth, BMI2_ACC_OSR4_AVG1, BMI2_ACC_RES_AVG128, dev); + dev->delay_us(2, dev->intf_ptr); } - } - return rslt; -} - -/*! - * @brief This internal API validates ODR and range of the accelerometer set by - * the user. - */ -static int8_t validate_odr_range(uint8_t *odr, uint8_t *range, struct bmi2_dev *dev) -{ - /* Variable to define error */ - int8_t rslt; + /* updating the advance power saver flag */ + if (reg_addr == BMI2_PWR_CONF_ADDR) + { + if (*data & BMI2_ADV_POW_EN_MASK) + { + dev->aps_status = BMI2_ENABLE; + } + else + { + dev->aps_status = BMI2_DISABLE; + } + } - /* Validate and auto correct ODR */ - rslt = check_boundary_val(odr, BMI2_ACC_ODR_0_78HZ, BMI2_ACC_ODR_1600HZ, dev); - if (rslt == BMI2_OK) + if (dev->intf_rslt != BMI2_INTF_RET_SUCCESS) + { + rslt = BMI2_E_COM_FAIL; + } + } + else { - /* Validate and auto correct Range */ - rslt = check_boundary_val(range, BMI2_ACC_RANGE_2G, BMI2_ACC_RANGE_16G, dev); + rslt = BMI2_E_NULL_PTR; } return rslt; } /*! - * @brief This internal API sets gyroscope configurations like ODR, bandwidth, - * low power/high performance mode, performance mode and range. It also - * maps/un-maps data interrupts to that of hardware interrupt line. + * @brief This API resets bmi2 sensor. All registers are overwritten with + * their default values. */ -static int8_t set_gyro_config(struct bmi2_gyro_config *config, struct bmi2_dev *dev) +int8_t bmi2_soft_reset(struct bmi2_dev *dev) { /* Variable to define error */ int8_t rslt; - /* Variable to store data */ - uint8_t reg_data; + /* Variable to define soft reset value */ + uint8_t data = BMI2_SOFT_RESET_CMD; - /* Array to store the default value of gyroscope configuration reserved registers */ - uint8_t data_array[2] = { 0 }; + /* Variable to read the dummy byte */ + uint8_t dummy_read = 0; - /* Validate gyroscope configurations */ - rslt = validate_gyro_config(config, dev); + /* Null-pointer check */ + rslt = null_ptr_check(dev); if (rslt == BMI2_OK) { - /* Set gyroscope performance mode */ - reg_data = BMI2_SET_BITS(data_array[0], BMI2_GYR_FILTER_PERF_MODE, config->filter_perf); - - /* Set gyroscope noise performance mode */ - reg_data = BMI2_SET_BITS(reg_data, BMI2_GYR_NOISE_PERF_MODE, config->noise_perf); - - /* Set gyroscope bandwidth */ - reg_data = BMI2_SET_BITS(reg_data, BMI2_GYR_BW_PARAM, config->bwp); - - /* Set gyroscope ODR */ - reg_data = BMI2_SET_BIT_POS0(reg_data, BMI2_GYR_ODR, config->odr); - - /* Copy the register data to the array */ - data_array[0] = reg_data; - - /* Set gyroscope OIS range */ - reg_data = BMI2_SET_BITS(data_array[1], BMI2_GYR_OIS_RANGE, config->ois_range); - - /* Set gyroscope range */ - reg_data = BMI2_SET_BIT_POS0(reg_data, BMI2_GYR_RANGE, config->range); + /* Reset bmi2 device */ + rslt = bmi2_set_regs(BMI2_CMD_REG_ADDR, &data, 1, dev); + dev->delay_us(2000, dev->intf_ptr); - /* Copy the register data to the array */ - data_array[1] = reg_data; + /* set APS flag as after soft reset the sensor is on advance power save mode */ + dev->aps_status = BMI2_ENABLE; - /* Write accelerometer configuration to GYR_CONF and GYR_RANGE - * registers simultaneously as they lie in consecutive places + /* Performing a dummy read to bring interface back to SPI from + * I2C after a soft-reset */ - rslt = bmi2_set_regs(BMI2_GYR_CONF_ADDR, data_array, 2, dev); + if ((rslt == BMI2_OK) && (dev->intf == BMI2_SPI_INTF)) + { + rslt = bmi2_get_regs(BMI2_CHIP_ID_ADDR, &dummy_read, 1, dev); + } - /* Get error status to check for invalid configurations */ if (rslt == BMI2_OK) { - rslt = cfg_error_status(dev); + /* Write the configuration file */ + rslt = bmi2_write_config_file(dev); + } + + /* Reset the sensor status flag in the device structure */ + if (rslt == BMI2_OK) + { + dev->sens_en_stat = 0; } } @@ -10599,38 +1961,58 @@ static int8_t set_gyro_config(struct bmi2_gyro_config *config, struct bmi2_dev * } /*! - * @brief This internal API validates bandwidth, performance mode, low power/ - * high performance mode, ODR, and range set by the user. + * @brief This API is used to get the config file major and minor version information. + */ +int8_t bmi2_get_config_file_version(uint8_t *config_major, uint8_t *config_minor, struct bmi2_dev *dev) +{ + /* Variable to define error */ + int8_t rslt; + + /* NULL pointer check */ + rslt = null_ptr_check(dev); + if ((rslt == BMI2_OK) && (config_major != NULL) && (config_minor != NULL)) + { + /* Extract the config file identification from the dmr page and get the major and minor version */ + rslt = extract_config_file(config_major, config_minor, dev); + } + else + { + rslt = BMI2_E_NULL_PTR; + } + + return rslt; +} + +/*! + * @brief This API enables/disables the advance power save mode in the sensor. */ -static int8_t validate_gyro_config(struct bmi2_gyro_config *config, struct bmi2_dev *dev) +int8_t bmi2_set_adv_power_save(uint8_t enable, struct bmi2_dev *dev) { /* Variable to define error */ int8_t rslt; - /* Validate and auto-correct performance mode */ - rslt = check_boundary_val(&config->filter_perf, BMI2_POWER_OPT_MODE, BMI2_PERF_OPT_MODE, dev); + /* Variable to store data */ + uint8_t reg_data = 0; + + /* Null-pointer check */ + rslt = null_ptr_check(dev); if (rslt == BMI2_OK) { - /* Validate and auto-correct bandwidth parameter */ - rslt = check_boundary_val(&config->bwp, BMI2_GYR_OSR4_MODE, BMI2_GYR_CIC_MODE, dev); + rslt = bmi2_get_regs(BMI2_PWR_CONF_ADDR, ®_data, 1, dev); if (rslt == BMI2_OK) { - /* Validate and auto-correct low power/high-performance parameter */ - rslt = check_boundary_val(&config->noise_perf, BMI2_POWER_OPT_MODE, BMI2_PERF_OPT_MODE, dev); + reg_data = BMI2_SET_BIT_POS0(reg_data, BMI2_ADV_POW_EN, enable); + rslt = bmi2_set_regs(BMI2_PWR_CONF_ADDR, ®_data, 1, dev); + + if (rslt != BMI2_OK) + { + /* Return error if enable/disable APS fails */ + rslt = BMI2_E_SET_APS_FAIL; + } + if (rslt == BMI2_OK) { - /* Validate and auto-correct ODR parameter */ - rslt = check_boundary_val(&config->odr, BMI2_GYR_ODR_25HZ, BMI2_GYR_ODR_3200HZ, dev); - if (rslt == BMI2_OK) - { - /* Validate and auto-correct OIS range */ - rslt = check_boundary_val(&config->ois_range, BMI2_GYR_OIS_250, BMI2_GYR_OIS_2000, dev); - if (rslt == BMI2_OK) - { - /* Validate and auto-correct range parameter */ - rslt = check_boundary_val(&config->range, BMI2_GYR_RANGE_2000, BMI2_GYR_RANGE_125, dev); - } - } + dev->aps_status = BMI2_GET_BIT_POS0(reg_data, BMI2_ADV_POW_EN); } } } @@ -10639,2023 +2021,1557 @@ static int8_t validate_gyro_config(struct bmi2_gyro_config *config, struct bmi2_ } /*! - * @brief This internal API shows the error status when illegal sensor - * configuration is set. + * @brief This API gets the status of advance power save mode in the sensor. */ -static int8_t cfg_error_status(struct bmi2_dev *dev) +int8_t bmi2_get_adv_power_save(uint8_t *aps_status, struct bmi2_dev *dev) { /* Variable to define error */ int8_t rslt; /* Variable to store data */ - uint8_t reg_data; + uint8_t reg_data = 0; - /* Get error status of the set sensor configuration */ - rslt = bmi2_get_regs(BMI2_EVENT_ADDR, ®_data, 1, dev); - if (rslt == BMI2_OK) + /* Null-pointer check */ + rslt = null_ptr_check(dev); + if ((rslt == BMI2_OK) && (aps_status != NULL)) { - reg_data = BMI2_GET_BITS(reg_data, BMI2_EVENT_FLAG); - switch (reg_data) + rslt = bmi2_get_regs(BMI2_PWR_CONF_ADDR, ®_data, 1, dev); + if (rslt == BMI2_OK) { - case BMI2_NO_ERROR: - rslt = BMI2_OK; - break; - case BMI2_ACC_ERROR: - rslt = BMI2_E_ACC_INVALID_CFG; - break; - case BMI2_GYR_ERROR: - rslt = BMI2_E_GYRO_INVALID_CFG; - break; - case BMI2_ACC_GYR_ERROR: - rslt = BMI2_E_ACC_GYR_INVALID_CFG; - break; - default: - break; + *aps_status = BMI2_GET_BIT_POS0(reg_data, BMI2_ADV_POW_EN); + dev->aps_status = *aps_status; } } + else + { + rslt = BMI2_E_NULL_PTR; + } return rslt; } /*! - * @brief This internal API: - * 1) Enables/Disables auxiliary interface. - * 2) Sets auxiliary interface configurations like I2C address, manual/auto - * mode enable, manual burst read length, AUX burst read length and AUX read - * address. - * 3)It maps/un-maps data interrupts to that of hardware interrupt line. + * @brief This API loads the configuration file into the bmi2 sensor. */ -static int8_t set_aux_config(struct bmi2_aux_config *config, struct bmi2_dev *dev) +int8_t bmi2_write_config_file(struct bmi2_dev *dev) { /* Variable to define error */ int8_t rslt; - /* Validate auxiliary configurations */ - rslt = validate_aux_config(config, dev); - if (rslt == BMI2_OK) + /* Variable to know the load status */ + uint8_t load_status = 0; + + /* Null-pointer check */ + rslt = null_ptr_check(dev); + if ((rslt == BMI2_OK) && (dev->config_size != 0)) { - /* Enable/Disable auxiliary interface */ - rslt = set_aux_interface(config, dev); + /* Bytes written are multiples of 2 */ + if ((dev->read_write_len % 2) != 0) + { + dev->read_write_len = dev->read_write_len - 1; + } + + if (dev->read_write_len < 2) + { + dev->read_write_len = 2; + } + + /* Write the configuration file */ + rslt = write_config_file(dev); if (rslt == BMI2_OK) { - /* Set the auxiliary interface configurations */ - rslt = config_aux_interface(config, dev); - if (rslt == BMI2_OK) + /* Check the configuration load status */ + rslt = bmi2_get_internal_status(&load_status, dev); + + /* Return error if loading not successful */ + if ((rslt == BMI2_OK) && (!(load_status & BMI2_CONFIG_LOAD_SUCCESS))) { - /* Set read out offset and ODR */ - rslt = config_aux(config, dev); + rslt = BMI2_E_CONFIG_LOAD; } } } - - return rslt; -} - -/*! - * @brief This internal API enables/disables auxiliary interface. - */ -static int8_t set_aux_interface(const struct bmi2_aux_config *config, struct bmi2_dev *dev) -{ - /* Variable to define error */ - int8_t rslt; - - /* Variable to store data */ - uint8_t reg_data; - - rslt = bmi2_get_regs(BMI2_IF_CONF_ADDR, ®_data, 1, dev); - if (rslt == BMI2_OK) + else { - reg_data = BMI2_SET_BITS(reg_data, BMI2_AUX_IF_EN, config->aux_en); - - /* Enable/Disable auxiliary interface */ - rslt = bmi2_set_regs(BMI2_IF_CONF_ADDR, ®_data, 1, dev); + rslt = BMI2_E_NULL_PTR; } return rslt; } /*! - * @brief This internal API sets auxiliary configurations like manual/auto mode - * FCU write command enable and read burst length for both data and manual mode. - * - * @note Auxiliary sensor should not be busy when configuring aux_i2c_addr, - * man_rd_burst_len, aux_rd_burst_len and aux_rd_addr. + * @brief This API sets: + * 1) The input output configuration of the selected interrupt pin: + * INT1 or INT2. + * 2) The interrupt mode: permanently latched or non-latched. */ -static int8_t config_aux_interface(const struct bmi2_aux_config *config, struct bmi2_dev *dev) +int8_t bmi2_set_int_pin_config(const struct bmi2_int_pin_config *int_cfg, struct bmi2_dev *dev) { /* Variable to define error */ int8_t rslt; - /* Variable to store data */ - uint8_t reg_data[2] = { 0 }; + /* Variable to define data array */ + uint8_t data_array[3] = { 0 }; - /* Variable to store status */ - uint8_t status = 0; + /* Variable to store register data */ + uint8_t reg_data = 0; - /* Variable to define count */ - uint8_t count = 0; + /* Variable to define type of interrupt pin */ + uint8_t int_pin = 0; - rslt = bmi2_get_regs(BMI2_AUX_DEV_ID_ADDR, reg_data, 2, dev); - if (rslt == BMI2_OK) + /* Null-pointer check */ + rslt = null_ptr_check(dev); + if ((rslt == BMI2_OK) && (int_cfg != NULL)) { - /* Set I2C address for AUX sensor */ - reg_data[0] = BMI2_SET_BITS(reg_data[0], BMI2_AUX_SET_I2C_ADDR, config->i2c_device_addr); + /* Copy the pin type to a local variable */ + int_pin = int_cfg->pin_type; + if ((int_pin > BMI2_INT_NONE) && (int_pin < BMI2_INT_PIN_MAX)) + { + /* Get the previous configuration data */ + rslt = bmi2_get_regs(BMI2_INT1_IO_CTRL_ADDR, data_array, 3, dev); + if (rslt == BMI2_OK) + { + /* Set interrupt pin 1 configuration */ + if ((int_pin == BMI2_INT1) || (int_pin == BMI2_INT_BOTH)) + { + /* Configure active low or high */ + reg_data = BMI2_SET_BITS(data_array[0], BMI2_INT_LEVEL, int_cfg->pin_cfg[0].lvl); - /* Set the AUX IF to either manual or auto mode */ - reg_data[1] = BMI2_SET_BITS(reg_data[1], BMI2_AUX_MAN_MODE_EN, config->manual_en); + /* Configure push-pull or open drain */ + reg_data = BMI2_SET_BITS(reg_data, BMI2_INT_OPEN_DRAIN, int_cfg->pin_cfg[0].od); - /* Enables FCU write command on AUX IF for auxiliary sensors that need a trigger */ - reg_data[1] = BMI2_SET_BITS(reg_data[1], BMI2_AUX_FCU_WR_EN, config->fcu_write_en); + /* Configure output enable */ + reg_data = BMI2_SET_BITS(reg_data, BMI2_INT_OUTPUT_EN, int_cfg->pin_cfg[0].output_en); - /* Set the burst read length for manual mode */ - reg_data[1] = BMI2_SET_BITS(reg_data[1], BMI2_AUX_MAN_READ_BURST, config->man_rd_burst); + /* Configure input enable */ + reg_data = BMI2_SET_BITS(reg_data, BMI2_INT_INPUT_EN, int_cfg->pin_cfg[0].input_en); - /* Set the burst read length for data mode */ - reg_data[1] = BMI2_SET_BIT_POS0(reg_data[1], BMI2_AUX_READ_BURST, config->aux_rd_burst); - for (;;) - { - /* Check if auxiliary sensor is busy */ - rslt = bmi2_get_status(&status, dev); - if ((rslt == BMI2_OK) && (!(status & BMI2_AUX_BUSY))) - { - /* Set the configurations if AUX is not busy */ - rslt = bmi2_set_regs(BMI2_AUX_DEV_ID_ADDR, reg_data, 2, dev); - dev->delay_us(1000, dev->intf_ptr); - if (rslt == BMI2_OK) + /* Copy the data to be written in the respective array */ + data_array[0] = reg_data; + } + + /* Set interrupt pin 2 configuration */ + if ((int_pin == BMI2_INT2) || (int_pin == BMI2_INT_BOTH)) { - /* If data mode */ - if (!config->manual_en) - { - /* Disable manual enable flag in device structure */ - dev->aux_man_en = 0; + /* Configure active low or high */ + reg_data = BMI2_SET_BITS(data_array[1], BMI2_INT_LEVEL, int_cfg->pin_cfg[1].lvl); - /* Set the read address of the AUX sensor */ - rslt = bmi2_set_regs(BMI2_AUX_RD_ADDR, (uint8_t *) &config->read_addr, 1, dev); - dev->delay_us(1000, dev->intf_ptr); - } - else - { - /* Enable manual enable flag in device structure */ - dev->aux_man_en = 1; + /* Configure push-pull or open drain */ + reg_data = BMI2_SET_BITS(reg_data, BMI2_INT_OPEN_DRAIN, int_cfg->pin_cfg[1].od); - /* Update manual read burst length in device structure */ - dev->aux_man_rd_burst_len = config->man_rd_burst; - } - } + /* Configure output enable */ + reg_data = BMI2_SET_BITS(reg_data, BMI2_INT_OUTPUT_EN, int_cfg->pin_cfg[1].output_en); - /* Break after setting the register */ - break; - } + /* Configure input enable */ + reg_data = BMI2_SET_BITS(reg_data, BMI2_INT_INPUT_EN, int_cfg->pin_cfg[1].input_en); + + /* Copy the data to be written in the respective array */ + data_array[1] = reg_data; + } - /* Increment count after every 10 seconds */ - dev->delay_us(10000, dev->intf_ptr); - count++; + /* Configure the interrupt mode */ + data_array[2] = BMI2_SET_BIT_POS0(data_array[2], BMI2_INT_LATCH, int_cfg->int_latch); - /* Break after 2 seconds if AUX still busy - since slowest ODR is 0.78Hz*/ - if (count > 20) - { - rslt = BMI2_E_AUX_BUSY; - break; + /* Set the configurations simultaneously as + * INT1_IO_CTRL, INT2_IO_CTRL, and INT_LATCH lie + * in consecutive addresses + */ + rslt = bmi2_set_regs(BMI2_INT1_IO_CTRL_ADDR, data_array, 3, dev); } } + else + { + rslt = BMI2_E_INVALID_INT_PIN; + } + } + else + { + rslt = BMI2_E_NULL_PTR; } return rslt; } /*! - * @brief This internal API triggers read out offset and sets ODR of the - * auxiliary sensor. + * @brief This API gets: + * 1) The input output configuration of the selected interrupt pin: + * INT1 or INT2. + * 2) The interrupt mode: permanently latched or non-latched. */ -static int8_t config_aux(const struct bmi2_aux_config *config, struct bmi2_dev *dev) +int8_t bmi2_get_int_pin_config(struct bmi2_int_pin_config *int_cfg, struct bmi2_dev *dev) { /* Variable to define error */ int8_t rslt; - /* Variable to store data */ - uint8_t reg_data; + /* Variable to define data array */ + uint8_t data_array[3] = { 0 }; - rslt = bmi2_get_regs(BMI2_AUX_CONF_ADDR, ®_data, 1, dev); - if (rslt == BMI2_OK) + /* Variable to define type of interrupt pin */ + uint8_t int_pin = 0; + + /* Null-pointer check */ + rslt = null_ptr_check(dev); + if ((rslt == BMI2_OK) && (int_cfg != NULL)) { - /* Trigger read out offset */ - reg_data = BMI2_SET_BITS(reg_data, BMI2_AUX_OFFSET_READ_OUT, config->offset); + /* Copy the pin type to a local variable */ + int_pin = int_cfg->pin_type; - /* Set ODR */ - reg_data = BMI2_SET_BIT_POS0(reg_data, BMI2_AUX_ODR_EN, config->odr); + /* Get the previous configuration data */ + rslt = bmi2_get_regs(BMI2_INT1_IO_CTRL_ADDR, data_array, 3, dev); + if (rslt == BMI2_OK) + { + /* Get interrupt pin 1 configuration */ + if ((int_pin == BMI2_INT1) || (int_pin == BMI2_INT_BOTH)) + { + /* Get active low or high */ + int_cfg->pin_cfg[0].lvl = BMI2_GET_BITS(data_array[0], BMI2_INT_LEVEL); - /* Set auxiliary configuration register */ - rslt = bmi2_set_regs(BMI2_AUX_CONF_ADDR, ®_data, 1, dev); - dev->delay_us(1000, dev->intf_ptr); + /* Get push-pull or open drain */ + int_cfg->pin_cfg[0].od = BMI2_GET_BITS(data_array[0], BMI2_INT_OPEN_DRAIN); + + /* Get output enable */ + int_cfg->pin_cfg[0].output_en = BMI2_GET_BITS(data_array[0], BMI2_INT_OUTPUT_EN); + + /* Get input enable */ + int_cfg->pin_cfg[0].input_en = BMI2_GET_BITS(data_array[0], BMI2_INT_INPUT_EN); + } + + /* Get interrupt pin 2 configuration */ + if ((int_pin == BMI2_INT2) || (int_pin == BMI2_INT_BOTH)) + { + /* Get active low or high */ + int_cfg->pin_cfg[1].lvl = BMI2_GET_BITS(data_array[1], BMI2_INT_LEVEL); + + /* Get push-pull or open drain */ + int_cfg->pin_cfg[1].od = BMI2_GET_BITS(data_array[1], BMI2_INT_OPEN_DRAIN); + + /* Get output enable */ + int_cfg->pin_cfg[1].output_en = BMI2_GET_BITS(data_array[1], BMI2_INT_OUTPUT_EN); + + /* Get input enable */ + int_cfg->pin_cfg[1].input_en = BMI2_GET_BITS(data_array[1], BMI2_INT_INPUT_EN); + } + + /* Get interrupt mode */ + int_cfg->int_latch = BMI2_GET_BIT_POS0(data_array[2], BMI2_INT_LATCH); + } + } + else + { + rslt = BMI2_E_NULL_PTR; } return rslt; } /*! - * @brief This internal API checks the busy status of auxiliary sensor and sets - * the auxiliary register addresses when not busy. + * @brief This API gets the interrupt status of both feature and data + * interrupts */ -static int8_t set_if_aux_not_busy(uint8_t reg_addr, uint8_t reg_data, struct bmi2_dev *dev) +int8_t bmi2_get_int_status(uint16_t *int_status, struct bmi2_dev *dev) { /* Variable to define error */ int8_t rslt; - /* Variable to get status of AUX_BUSY */ - uint8_t status = 0; - - /* Variable to define count for time-out */ - uint8_t count = 0; + /* Array to store data */ + uint8_t data_array[2] = { 0 }; - for (;;) + /* Null-pointer check */ + rslt = null_ptr_check(dev); + if ((rslt == BMI2_OK) && (int_status != NULL)) { - /* Check if AUX is busy */ - rslt = bmi2_get_status(&status, dev); - - /* Set the registers if not busy */ - if ((rslt == BMI2_OK) && (!(status & BMI2_AUX_BUSY))) - { - rslt = bmi2_set_regs(reg_addr, ®_data, 1, dev); - dev->delay_us(1000, dev->intf_ptr); - - /* Break after setting the register */ - break; - } - - /* Increment count after every 10 seconds */ - dev->delay_us(10000, dev->intf_ptr); - count++; - - /* Break after 2 seconds if AUX still busy - since slowest ODR is 0.78Hz*/ - if (count > 20) + /* Get the interrupt status */ + rslt = bmi2_get_regs(BMI2_INT_STATUS_0_ADDR, data_array, 2, dev); + if (rslt == BMI2_OK) { - rslt = BMI2_E_AUX_BUSY; - break; + *int_status = (uint16_t) data_array[0] | ((uint16_t) data_array[1] << 8); } } + else + { + rslt = BMI2_E_NULL_PTR; + } return rslt; } /*! - * @brief This internal API validates auxiliary configuration set by the user. + * @brief This API selects the sensors/features to be enabled. */ -static int8_t validate_aux_config(struct bmi2_aux_config *config, struct bmi2_dev *dev) +int8_t bmi2_sensor_enable(const uint8_t *sens_list, uint8_t n_sens, struct bmi2_dev *dev) { /* Variable to define error */ int8_t rslt; - /* Validate ODR for auxiliary sensor */ - rslt = check_boundary_val(&config->odr, BMI2_AUX_ODR_0_78HZ, BMI2_AUX_ODR_800HZ, dev); + /* Variable to select sensor */ + uint64_t sensor_sel = 0; + + /* Null-pointer check */ + rslt = null_ptr_check(dev); + if ((rslt == BMI2_OK) && (sens_list != NULL)) + { + /* Get the selected sensors */ + rslt = select_sensor(sens_list, n_sens, &sensor_sel); + if (rslt == BMI2_OK) + { + /* Enable the selected sensors */ + rslt = sensor_enable(sensor_sel, dev); + } + } + else + { + rslt = BMI2_E_NULL_PTR; + } return rslt; } /*! - * @brief This internal API sets any-motion configurations like axes select, - * duration, threshold and output-configuration. + * @brief This API selects the sensors/features to be disabled. */ -static int8_t set_any_motion_config(const struct bmi2_any_motion_config *config, struct bmi2_dev *dev) +int8_t bmi2_sensor_disable(const uint8_t *sens_list, uint8_t n_sens, struct bmi2_dev *dev) { /* Variable to define error */ int8_t rslt; - /* Array to define the feature configuration */ - uint8_t feat_config[BMI2_FEAT_SIZE_IN_BYTES] = { 0 }; - - /* Variable to define the array offset */ - uint8_t idx = 0; - - /* Variable to define count */ - uint8_t index = 0; - - /* Variable to set flag */ - uint8_t feat_found; - - /* Initialize feature configuration for any motion */ - struct bmi2_feature_config any_mot_config = { 0, 0, 0 }; - - /* Copy the feature configuration address to a local pointer */ - uint16_t *data_p = (uint16_t *) (void *)feat_config; + /* Variable to select sensor */ + uint64_t sensor_sel = 0; - /* Search for any-motion feature and extract its configuration details */ - feat_found = bmi2_extract_input_feat_config(&any_mot_config, BMI2_ANY_MOTION, dev); - if (feat_found) + /* Null-pointer check */ + rslt = null_ptr_check(dev); + if ((rslt == BMI2_OK) && (sens_list != NULL)) { - /* Get the configuration from the page where any-motion feature resides */ - rslt = bmi2_get_feat_config(any_mot_config.page, feat_config, dev); + /* Get the selected sensors */ + rslt = select_sensor(sens_list, n_sens, &sensor_sel); if (rslt == BMI2_OK) { - /* Define the offset in bytes for any-motion select */ - idx = any_mot_config.start_addr; - - /* Get offset in words since all the features are set in words length */ - idx = idx / 2; - - /* Set duration */ - *(data_p + idx) = BMI2_SET_BIT_POS0(*(data_p + idx), BMI2_ANY_NO_MOT_DUR, config->duration); - - /* Set x-select */ - *(data_p + idx) = BMI2_SET_BITS(*(data_p + idx), BMI2_ANY_NO_MOT_X_SEL, config->select_x); - - /* Set y-select */ - *(data_p + idx) = BMI2_SET_BITS(*(data_p + idx), BMI2_ANY_NO_MOT_Y_SEL, config->select_y); - - /* Set z-select */ - *(data_p + idx) = BMI2_SET_BITS(*(data_p + idx), BMI2_ANY_NO_MOT_Z_SEL, config->select_z); - - /* Increment offset by 1 word to set threshold and output configuration */ - idx++; - - /* Set threshold */ - *(data_p + idx) = BMI2_SET_BIT_POS0(*(data_p + idx), BMI2_ANY_NO_MOT_THRES, config->threshold); - - /* Set output configuration */ - *(data_p + idx) = BMI2_SET_BITS(*(data_p + idx), BMI2_ANY_NO_MOT_OUT_CONF, config->out_conf); - - /* Increment offset by 1 more word to get the total length in words */ - idx++; - - /* Get total length in bytes to copy from local pointer to the array */ - idx = (uint8_t)(idx * 2) - any_mot_config.start_addr; - - /* Copy the bytes to be set back to the array */ - for (index = 0; index < idx; index++) - { - feat_config[any_mot_config.start_addr + - index] = *((uint8_t *) data_p + any_mot_config.start_addr + index); - } - - /* Set the configuration back to the page */ - rslt = bmi2_set_regs(BMI2_FEATURES_REG_ADDR, feat_config, BMI2_FEAT_SIZE_IN_BYTES, dev); - if (rslt == BMI2_OK) - { - /* Copy out_conf value to a local copy in device structure */ - dev->int_map.any_mot_out_conf = (uint8_t) config->out_conf; - } + /* Disable the selected sensors */ + rslt = sensor_disable(sensor_sel, dev); } } else { - rslt = BMI2_E_INVALID_SENSOR; + rslt = BMI2_E_NULL_PTR; } return rslt; } /*! - * @brief This internal API sets no-motion configurations like axes select, - * duration, threshold and output-configuration. + * @brief This API sets the sensor/feature configuration. */ -static int8_t set_no_motion_config(const struct bmi2_no_motion_config *config, struct bmi2_dev *dev) +int8_t bmi2_set_sensor_config(struct bmi2_sens_config *sens_cfg, uint8_t n_sens, struct bmi2_dev *dev) { /* Variable to define error */ int8_t rslt; - /* Array to define the feature configuration */ - uint8_t feat_config[BMI2_FEAT_SIZE_IN_BYTES] = { 0 }; - - /* Variable to define the array offset */ - uint8_t idx = 0; - - /* Variable to define count */ - uint8_t index = 0; - - /* Variable to set flag */ - uint8_t feat_found; - - /* Initialize feature configuration for no-motion */ - struct bmi2_feature_config no_mot_config = { 0, 0, 0 }; + /* Variable to define loop */ + uint8_t loop; - /* Copy the feature configuration address to a local pointer */ - uint16_t *data_p = (uint16_t *) (void *)feat_config; + /* Variable to get the status of advance power save */ + uint8_t aps_stat = 0; - /* Search for no-motion feature and extract its configuration details */ - feat_found = bmi2_extract_input_feat_config(&no_mot_config, BMI2_NO_MOTION, dev); - if (feat_found) + /* Null-pointer check */ + rslt = null_ptr_check(dev); + if ((rslt == BMI2_OK) && (sens_cfg != NULL)) { - /* Get the configuration from the page where no-motion feature resides */ - rslt = bmi2_get_feat_config(no_mot_config.page, feat_config, dev); - if (rslt == BMI2_OK) - { - /* Define the offset in bytes for no-motion select */ - idx = no_mot_config.start_addr; - - /* Get offset in words since all the features are set in words length */ - idx = idx / 2; - - /* Set duration */ - *(data_p + idx) = BMI2_SET_BIT_POS0(*(data_p + idx), BMI2_ANY_NO_MOT_DUR, config->duration); - - /* Set x-select */ - *(data_p + idx) = BMI2_SET_BITS(*(data_p + idx), BMI2_ANY_NO_MOT_X_SEL, config->select_x); - - /* Set y-select */ - *(data_p + idx) = BMI2_SET_BITS(*(data_p + idx), BMI2_ANY_NO_MOT_Y_SEL, config->select_y); - - /* Set z-select */ - *(data_p + idx) = BMI2_SET_BITS(*(data_p + idx), BMI2_ANY_NO_MOT_Z_SEL, config->select_z); + /* Get status of advance power save mode */ + aps_stat = dev->aps_status; - /* Increment offset by 1 word to set threshold and output configuration */ - idx++; + for (loop = 0; loop < n_sens; loop++) + { + /* Disable Advance power save if enabled for auxiliary + * and feature configurations + */ + if (aps_stat == BMI2_ENABLE) + { + /* Disable advance power save if + * enabled + */ + rslt = bmi2_set_adv_power_save(BMI2_DISABLE, dev); + } - /* Set threshold */ - *(data_p + idx) = BMI2_SET_BIT_POS0(*(data_p + idx), BMI2_ANY_NO_MOT_THRES, config->threshold); + if (rslt == BMI2_OK) + { + switch (sens_cfg[loop].type) + { + /* Set accelerometer configuration */ + case BMI2_ACCEL: + rslt = set_accel_config(&sens_cfg[loop].cfg.acc, dev); + break; - /* Set output configuration */ - *(data_p + idx) = BMI2_SET_BITS(*(data_p + idx), BMI2_ANY_NO_MOT_OUT_CONF, config->out_conf); + /* Set gyroscope configuration */ + case BMI2_GYRO: + rslt = set_gyro_config(&sens_cfg[loop].cfg.gyr, dev); + break; - /* Increment offset by 1 more word to get the total length in words */ - idx++; + /* Set auxiliary configuration */ + case BMI2_AUX: + rslt = set_aux_config(&sens_cfg[loop].cfg.aux, dev); + break; - /* Get total length in bytes to copy from local pointer to the array */ - idx = (uint8_t)(idx * 2) - no_mot_config.start_addr; + /* Set gyroscope user gain configuration */ + case BMI2_GYRO_GAIN_UPDATE: + rslt = set_gyro_user_gain_config(&sens_cfg[loop].cfg.gyro_gain_update, dev); + break; - /* Copy the bytes to be set back to the array */ - for (index = 0; index < idx; index++) - { - feat_config[no_mot_config.start_addr + - index] = *((uint8_t *) data_p + no_mot_config.start_addr + index); + default: + rslt = BMI2_E_INVALID_SENSOR; + break; + } } - /* Set the configuration back to the page */ - rslt = bmi2_set_regs(BMI2_FEATURES_REG_ADDR, feat_config, BMI2_FEAT_SIZE_IN_BYTES, dev); - if (rslt == BMI2_OK) + /* Return error if any of the set configurations fail */ + if (rslt != BMI2_OK) { - /* Copy out_conf value to a local copy in device structure */ - dev->int_map.no_mot_out_conf = (uint8_t) config->out_conf; + break; } } + + /* Enable Advance power save if disabled while configuring and + * not when already disabled + */ + if ((aps_stat == BMI2_ENABLE) && (rslt == BMI2_OK)) + { + rslt = bmi2_set_adv_power_save(BMI2_ENABLE, dev); + } } else { - rslt = BMI2_E_INVALID_SENSOR; + rslt = BMI2_E_NULL_PTR; } return rslt; } /*! - * @brief This internal API sets sig-motion configurations like block-size, - * output-configuration and other parameters. + * @brief This API gets the sensor/feature configuration. */ -static int8_t set_sig_motion_config(const struct bmi2_sig_motion_config *config, struct bmi2_dev *dev) +int8_t bmi2_get_sensor_config(struct bmi2_sens_config *sens_cfg, uint8_t n_sens, struct bmi2_dev *dev) { /* Variable to define error */ int8_t rslt; - /* Array to define the feature configuration */ - uint8_t feat_config[BMI2_FEAT_SIZE_IN_BYTES] = { 0 }; - - /* Variable to define the array offset */ - uint8_t idx = 0; - - /* Variable to define index */ - uint8_t index = 0; - - /* Variable to set flag */ - uint8_t feat_found; - - /* Initialize feature configuration for sig-motion */ - struct bmi2_feature_config sig_mot_config = { 0, 0, 0 }; + /* Variable to define loop */ + uint8_t loop; - /* Copy the feature configuration address to a local pointer */ - uint16_t *data_p = (uint16_t *) (void *)feat_config; + /* Variable to get the status of advance power save */ + uint8_t aps_stat = 0; - /* Search for sig-motion feature and extract its configuration details */ - feat_found = bmi2_extract_input_feat_config(&sig_mot_config, BMI2_SIG_MOTION, dev); - if (feat_found) + /* Null-pointer check */ + rslt = null_ptr_check(dev); + if ((rslt == BMI2_OK) && (sens_cfg != NULL)) { - /* Get the configuration from the page where sig-motion feature resides */ - rslt = bmi2_get_feat_config(sig_mot_config.page, feat_config, dev); - if (rslt == BMI2_OK) + /* Get status of advance power save mode */ + aps_stat = dev->aps_status; + for (loop = 0; loop < n_sens; loop++) { - /* Define the offset in bytes for sig-motion select */ - idx = sig_mot_config.start_addr; - - /* Get offset in words since all the features are set in words length */ - idx = idx / 2; - - /* Set parameter 1 */ - *(data_p + idx) = BMI2_SET_BIT_POS0(*(data_p + idx), BMI2_SIG_MOT_PARAM_1, config->block_size); - - /* Increment offset by 1 word to set parameter 2 */ - idx++; - - /* Set parameter 2 */ - *(data_p + idx) = BMI2_SET_BIT_POS0(*(data_p + idx), BMI2_SIG_MOT_PARAM_2, config->param_2); - - /* Increment offset by 1 word to set parameter 3 */ - idx++; - - /* Set parameter 3 */ - *(data_p + idx) = BMI2_SET_BIT_POS0(*(data_p + idx), BMI2_SIG_MOT_PARAM_3, config->param_3); - - /* Increment offset by 1 word to set parameter 4 */ - idx++; - - /* Set parameter 4 */ - *(data_p + idx) = BMI2_SET_BIT_POS0(*(data_p + idx), BMI2_SIG_MOT_PARAM_4, config->param_4); - - /* Increment offset by 1 word to set parameter 5 */ - idx++; + /* Disable Advance power save if enabled for auxiliary + * and feature configurations + */ + if ((sens_cfg[loop].type >= BMI2_MAIN_SENS_MAX_NUM) || (sens_cfg[loop].type == BMI2_AUX)) + { - /* Set parameter 5 */ - *(data_p + idx) = BMI2_SET_BIT_POS0(*(data_p + idx), BMI2_SIG_MOT_PARAM_5, config->param_5); + if (aps_stat == BMI2_ENABLE) + { + /* Disable advance power save if + * enabled + */ + rslt = bmi2_set_adv_power_save(BMI2_DISABLE, dev); + } + } - /* Increment offset by 1 word to set output- configuration */ - idx++; + if (rslt == BMI2_OK) + { + switch (sens_cfg[loop].type) + { + /* Get accelerometer configuration */ + case BMI2_ACCEL: + rslt = get_accel_config(&sens_cfg[loop].cfg.acc, dev); + break; - /* Set output configuration */ - *(data_p + idx) = BMI2_SET_BITS(*(data_p + idx), BMI2_SIG_MOT_OUT_CONF, config->out_conf); + /* Get gyroscope configuration */ + case BMI2_GYRO: + rslt = get_gyro_config(&sens_cfg[loop].cfg.gyr, dev); + break; - /* Increment offset by 1 more word to get the total length in words */ - idx++; + /* Get auxiliary configuration */ + case BMI2_AUX: + rslt = get_aux_config(&sens_cfg[loop].cfg.aux, dev); + break; - /* Get total length in bytes to copy from local pointer to the array */ - idx = (uint8_t)(idx * 2) - sig_mot_config.start_addr; + /* Get gyroscope user gain configuration */ + case BMI2_GYRO_GAIN_UPDATE: + rslt = get_gyro_gain_update_config(&sens_cfg[loop].cfg.gyro_gain_update, dev); + break; - /* Copy the bytes to be set back to the array */ - for (index = 0; index < idx; index++) - { - feat_config[sig_mot_config.start_addr + - index] = *((uint8_t *) data_p + sig_mot_config.start_addr + index); + default: + rslt = BMI2_E_INVALID_SENSOR; + break; + } } - /* Set the configuration back to the page */ - rslt = bmi2_set_regs(BMI2_FEATURES_REG_ADDR, feat_config, BMI2_FEAT_SIZE_IN_BYTES, dev); - if (rslt == BMI2_OK) + /* Return error if any of the get configurations fail */ + if (rslt != BMI2_OK) { - /* Copy out_conf value to a local copy in device structure for mapping */ - dev->int_map.sig_mot_out_conf = (uint8_t) config->out_conf; + break; } } + + /* Enable Advance power save if disabled while configuring and + * not when already disabled + */ + if ((aps_stat == BMI2_ENABLE) && (rslt == BMI2_OK)) + { + rslt = bmi2_set_adv_power_save(BMI2_ENABLE, dev); + } } else { - rslt = BMI2_E_INVALID_SENSOR; + rslt = BMI2_E_NULL_PTR; } return rslt; } /*! - * @brief This internal API sets step counter parameter configurations. + * @brief This API gets the sensor/feature data for accelerometer, gyroscope, + * auxiliary sensor, step counter, high-g, gyroscope user-gain update, + * orientation, gyroscope cross sensitivity and error status for NVM and VFRM. */ -static int8_t set_step_count_params_config(const uint16_t *step_count_params, struct bmi2_dev *dev) +int8_t bmi2_get_sensor_data(struct bmi2_sensor_data *sensor_data, uint8_t n_sens, struct bmi2_dev *dev) { /* Variable to define error */ - int8_t rslt = BMI2_OK; - - /* Array to define the feature configuration */ - uint8_t feat_config[BMI2_FEAT_SIZE_IN_BYTES] = { 0 }; - - /* Variable to define index */ - uint8_t index = 0; - - /* Variable to set flag */ - uint8_t feat_found; - - /* Initialize feature configuration for step counter parameters */ - struct bmi2_feature_config step_params_config = { 0, 0, 0 }; - - /* Variable to index the page number */ - uint8_t page_idx; - - /* Variable to define the start page */ - uint8_t start_page; - - /* Variable to define start address of the parameters */ - uint8_t start_addr; - - /* Variable to define number of bytes */ - uint8_t n_bytes = (BMI2_STEP_CNT_N_PARAMS * 2); - - /* Variable to store number of pages */ - uint8_t n_pages = (n_bytes / 16); - - /* Variable to define the end page */ - uint8_t end_page; - - /* Variable to define the remaining bytes to be read */ - uint8_t remain_len; - - /* Variable to define the maximum words(16 bytes or 8 words) to be read in a page */ - uint8_t max_len = 8; - - /* Variable index bytes in a page */ - uint8_t page_byte_idx; + int8_t rslt; - /* Variable to index the parameters */ - uint8_t param_idx = 0; + /* Variable to define loop */ + uint8_t loop; - /* Copy the feature configuration address to a local pointer */ - uint16_t *data_p = (uint16_t *) (void *)feat_config; + /* Variable to get the status of advance power save */ + uint8_t aps_stat = 0; - /* Search for step counter parameter feature and extract its configuration details */ - feat_found = bmi2_extract_input_feat_config(&step_params_config, BMI2_STEP_COUNTER_PARAMS, dev); - if (feat_found) + /* Null-pointer check */ + rslt = null_ptr_check(dev); + if ((rslt == BMI2_OK) && (sensor_data != NULL)) { - /* Get the start page for the step counter parameters */ - start_page = step_params_config.page; - - /* Get the end page for the step counter parameters */ - end_page = start_page + n_pages; - - /* Get the start address for the step counter parameters */ - start_addr = step_params_config.start_addr; - - /* Get the remaining length of bytes to be read */ - remain_len = (uint8_t)((n_bytes - (n_pages * 16)) + start_addr); - for (page_idx = start_page; page_idx <= end_page; page_idx++) + /* Get status of advance power save mode */ + aps_stat = dev->aps_status; + for (loop = 0; loop < n_sens; loop++) { - /* Get the configuration from the respective page */ - rslt = bmi2_get_feat_config(page_idx, feat_config, dev); - if (rslt == BMI2_OK) + /* Disable Advance power save if enabled for feature + * configurations + */ + if (sensor_data[loop].type >= BMI2_MAIN_SENS_MAX_NUM) { - /* Start from address 0x00 when switched to next page */ - if (page_idx > start_page) + if (aps_stat == BMI2_ENABLE) { - start_addr = 0; + /* Disable advance power save if + * enabled + */ + rslt = bmi2_set_adv_power_save(BMI2_DISABLE, dev); } + } - /* Remaining number of words to be read in the page */ - if (page_idx == end_page) + if (rslt == BMI2_OK) + { + switch (sensor_data[loop].type) { - max_len = (remain_len / 2); - } + case BMI2_ACCEL: - /* Get offset in words since all the features are set in words length */ - page_byte_idx = start_addr / 2; - for (; page_byte_idx < max_len;) - { - /* Set parameters 1 to 25 */ - *(data_p + page_byte_idx) = BMI2_SET_BIT_POS0(*(data_p + page_byte_idx), - BMI2_STEP_COUNT_PARAMS, - step_count_params[param_idx]); + /* Get accelerometer data */ + rslt = get_accel_sensor_data(&sensor_data[loop].sens_data.acc, BMI2_ACC_X_LSB_ADDR, dev); + break; + case BMI2_GYRO: - /* Increment offset by 1 word to set to the next parameter */ - page_byte_idx++; + /* Get gyroscope data */ + rslt = get_gyro_sensor_data(&sensor_data[loop].sens_data.gyr, BMI2_GYR_X_LSB_ADDR, dev); + break; + case BMI2_AUX: - /* Increment to next parameter */ - param_idx++; - } + /* Get auxiliary sensor data in data mode */ + rslt = read_aux_data_mode(sensor_data[loop].sens_data.aux_data, dev); + break; + + case BMI2_GYRO_CROSS_SENSE: + + /* Get Gyroscope cross sense value of z axis */ + rslt = get_gyro_cross_sense(&sensor_data[loop].sens_data.correction_factor_zx, dev); + break; - /* Get total length in bytes to copy from local pointer to the array */ - page_byte_idx = (uint8_t)(page_byte_idx * 2) - step_params_config.start_addr; + case BMI2_GYRO_GAIN_UPDATE: + + /* Get saturation status of gyroscope user gain update */ + rslt = get_gyro_gain_update_status(&sensor_data[loop].sens_data.gyro_user_gain_status, dev); + break; + default: + rslt = BMI2_E_INVALID_SENSOR; + break; + } - /* Copy the bytes to be set back to the array */ - for (index = 0; index < page_byte_idx; index++) + /* Return error if any of the get sensor data fails */ + if (rslt != BMI2_OK) { - feat_config[step_params_config.start_addr + - index] = *((uint8_t *) data_p + step_params_config.start_addr + index); + break; } + } - /* Set the configuration back to the page */ - rslt = bmi2_set_regs(BMI2_FEATURES_REG_ADDR, feat_config, BMI2_FEAT_SIZE_IN_BYTES, dev); + /* Enable Advance power save if disabled while + * configuring and not when already disabled + */ + if ((aps_stat == BMI2_ENABLE) && (rslt == BMI2_OK)) + { + rslt = bmi2_set_adv_power_save(BMI2_ENABLE, dev); } } } else { - rslt = BMI2_E_INVALID_SENSOR; + rslt = BMI2_E_NULL_PTR; } return rslt; } /*! - * @brief This internal API sets step counter configurations like water-mark - * level, reset-counter and output-configuration step detector and activity. + * @brief This API sets the FIFO configuration in the sensor. */ -static int8_t set_step_config(const struct bmi2_step_config *config, struct bmi2_dev *dev) +int8_t bmi2_set_fifo_config(uint16_t config, uint8_t enable, struct bmi2_dev *dev) { - /* Variable to define error */ int8_t rslt; + uint8_t data[2] = { 0 }; + uint8_t max_burst_len = 0; - /* Array to define the feature configuration */ - uint8_t feat_config[BMI2_FEAT_SIZE_IN_BYTES] = { 0 }; - - /* Variable to define the array offset */ - uint8_t idx = 0; - - /* Variable to define index */ - uint8_t index = 0; - - /* Variable to set flag */ - uint8_t feat_found; - - /* Initialize feature configuration for step counter 4 */ - struct bmi2_feature_config step_count_config = { 0, 0, 0 }; + /* Variable to store data of FIFO configuration register 0 */ + uint8_t fifo_config_0 = (uint8_t)(config & BMI2_FIFO_CONFIG_0_MASK); - /* Copy the feature configuration address to a local pointer */ - uint16_t *data_p = (uint16_t *) (void *)feat_config; + /* Variable to store data of FIFO configuration register 1 */ + uint8_t fifo_config_1 = (uint8_t)((config & BMI2_FIFO_CONFIG_1_MASK) >> 8); - /* Search for step counter feature and extract its configuration details */ - feat_found = bmi2_extract_input_feat_config(&step_count_config, BMI2_STEP_COUNTER, dev); - if (feat_found) + rslt = null_ptr_check(dev); + if (rslt == BMI2_OK) { - /* Get the configuration from the page where step counter resides */ - rslt = bmi2_get_feat_config(step_count_config.page, feat_config, dev); + rslt = bmi2_get_regs(BMI2_FIFO_CONFIG_0_ADDR, data, BMI2_FIFO_CONFIG_LENGTH, dev); if (rslt == BMI2_OK) { - /* Define the offset in bytes */ - idx = step_count_config.start_addr; - - /* Get offset in words since all the features are set in words length */ - idx = idx / 2; - - /* Set water-mark level */ - *(data_p + idx) = BMI2_SET_BIT_POS0(*(data_p + idx), BMI2_STEP_COUNT_WM_LEVEL, config->watermark_level); - - /* Set reset-counter */ - *(data_p + idx) = BMI2_SET_BITS(*(data_p + idx), BMI2_STEP_COUNT_RST_CNT, config->reset_counter); - - /* Increment offset by 1 word to set output - * configuration of step detector and step activity - */ - idx++; - - /* Set output configuration of step-detector */ - *(data_p + - idx) = BMI2_SET_BIT_POS0(*(data_p + idx), BMI2_STEP_DET_OUT_CONF, config->out_conf_step_detector); - - /* Set output configuration of step-activity */ - *(data_p + idx) = BMI2_SET_BITS(*(data_p + idx), BMI2_STEP_ACT_OUT_CONF, config->out_conf_activity); - - /* Set step buffer size */ - *(data_p + idx) = BMI2_SET_BITS(*(data_p + idx), BMI2_STEP_BUFFER_SIZE, config->step_buffer_size); - - /* Increment offset by 1 more word to get the total length in words */ - idx++; + /* Get data to set FIFO configuration register 0 */ + if (fifo_config_0 > 0) + { + if (enable == BMI2_ENABLE) + { + data[0] = data[0] | fifo_config_0; + } + else + { + data[0] = data[0] & (~fifo_config_0); + } + } - /* Get total length in bytes to copy from local pointer to the array */ - idx = (uint8_t)(idx * 2) - step_count_config.start_addr; + /* Get data to set FIFO configuration register 1 */ + if (enable == BMI2_ENABLE) + { + data[1] = data[1] | fifo_config_1; + if (dev->variant_feature & BMI2_CRT_RTOSK_ENABLE) + { - /* Copy the bytes to be set back to the array */ - for (index = 0; index < idx; index++) + /* Burst length is needed for CRT + * FIFO enable will reset the default values + * So configure the max burst length again. + */ + rslt = get_maxburst_len(&max_burst_len, dev); + if (rslt == BMI2_OK && max_burst_len == 0) + { + rslt = set_maxburst_len(BMI2_CRT_MIN_BURST_WORD_LENGTH, dev); + } + } + } + else { - feat_config[step_count_config.start_addr + - index] = *((uint8_t *) data_p + step_count_config.start_addr + index); + data[1] = data[1] & (~fifo_config_1); } - /* Set the configuration back to the page */ - rslt = bmi2_set_regs(BMI2_FEATURES_REG_ADDR, feat_config, BMI2_FEAT_SIZE_IN_BYTES, dev); + /* Set the FIFO configurations */ if (rslt == BMI2_OK) { - /* Copy out_conf value to a local copy in device structure for step-detector */ - dev->int_map.step_det_out_conf = (uint8_t) config->out_conf_step_detector; - - /* Copy out_conf value to a local copy in device structure for step-activity */ - dev->int_map.step_act_out_conf = (uint8_t) config->out_conf_activity; + rslt = bmi2_set_regs(BMI2_FIFO_CONFIG_0_ADDR, data, 2, dev); } } } - else - { - rslt = BMI2_E_INVALID_SENSOR; - } return rslt; } /*! - * @brief This internal API sets gyroscope user-gain configurations like gain - * update value for x, y and z-axis. + * @brief This API reads the FIFO configuration from the sensor. */ -static int8_t set_gyro_user_gain_config(const struct bmi2_gyro_user_gain_config *config, struct bmi2_dev *dev) +int8_t bmi2_get_fifo_config(uint16_t *fifo_config, struct bmi2_dev *dev) { /* Variable to define error */ int8_t rslt; - /* Array to define the feature configuration */ - uint8_t feat_config[BMI2_FEAT_SIZE_IN_BYTES] = { 0 }; - - /* Variable to define the array offset */ - uint8_t idx = 0; - - /* Variable to define index */ - uint8_t index = 0; - - /* Variable to set flag */ - uint8_t feat_found; - - /* Initialize feature configuration for user-gain */ - struct bmi2_feature_config user_gain_config = { 0, 0, 0 }; - - /* Copy the feature configuration address to a local pointer */ - uint16_t *data_p = (uint16_t *) (void *)feat_config; + /* Array to store data */ + uint8_t data[2] = { 0 }; - /* Search for user-gain feature and extract its configuration details */ - feat_found = bmi2_extract_input_feat_config(&user_gain_config, BMI2_GYRO_GAIN_UPDATE, dev); - if (feat_found) + /* Null-pointer check */ + rslt = null_ptr_check(dev); + if ((rslt == BMI2_OK) && (fifo_config != NULL)) { - /* Get the configuration from the page where user-gain feature resides */ - rslt = bmi2_get_feat_config(user_gain_config.page, feat_config, dev); + /* Get the FIFO configuration value */ + rslt = bmi2_get_regs(BMI2_FIFO_CONFIG_0_ADDR, data, BMI2_FIFO_CONFIG_LENGTH, dev); if (rslt == BMI2_OK) { - /* Define the offset in bytes for user-gain select */ - idx = user_gain_config.start_addr; - - /* Get offset in words since all the features are set in words length */ - idx = idx / 2; - - /* Set ratio_x */ - *(data_p + idx) = BMI2_SET_BIT_POS0(*(data_p + idx), BMI2_GYR_USER_GAIN_RATIO_X, config->ratio_x); - - /* Increment offset by 1 word to set ratio_y */ - idx++; - - /* Set ratio_y */ - *(data_p + idx) = BMI2_SET_BIT_POS0(*(data_p + idx), BMI2_GYR_USER_GAIN_RATIO_Y, config->ratio_y); - - /* Increment offset by 1 word to set ratio_z */ - idx++; - - /* Set ratio_z */ - *(data_p + idx) = BMI2_SET_BIT_POS0(*(data_p + idx), BMI2_GYR_USER_GAIN_RATIO_Z, config->ratio_z); - - /* Increment offset by 1 more word to get the total length in words */ - idx++; - - /* Get total length in bytes to copy from local pointer to the array */ - idx = (uint8_t)(idx * 2) - user_gain_config.start_addr; - - /* Copy the bytes to be set back to the array */ - for (index = 0; index < idx; index++) - { - feat_config[user_gain_config.start_addr + - index] = *((uint8_t *) data_p + user_gain_config.start_addr + index); - } - - /* Set the configuration back to the page */ - rslt = bmi2_set_regs(BMI2_FEATURES_REG_ADDR, feat_config, BMI2_FEAT_SIZE_IN_BYTES, dev); + (*fifo_config) = (uint16_t)((uint16_t) data[0] & BMI2_FIFO_CONFIG_0_MASK); + (*fifo_config) |= (uint16_t)(((uint16_t) data[1] << 8) & BMI2_FIFO_CONFIG_1_MASK); } } else { - rslt = BMI2_E_INVALID_SENSOR; + rslt = BMI2_E_NULL_PTR; } return rslt; } /*! - * @brief This internal API sets tilt configurations like output-configuration. + * @brief This API reads the FIFO data. */ -static int8_t set_tilt_config(const struct bmi2_tilt_config *config, struct bmi2_dev *dev) +int8_t bmi2_read_fifo_data(struct bmi2_fifo_frame *fifo, struct bmi2_dev *dev) { /* Variable to define error */ int8_t rslt; - /* Array to define the feature configuration */ - uint8_t feat_config[BMI2_FEAT_SIZE_IN_BYTES] = { 0 }; - - /* Variable to define the array offset */ - uint8_t idx = 0; - - /* Variable to define index */ - uint8_t index = 0; + /* Array to store FIFO configuration data */ + uint8_t config_data[2] = { 0 }; - /* Variable to set flag */ - uint8_t feat_found; + /* Variable to define FIFO address */ + uint8_t addr = BMI2_FIFO_DATA_ADDR; - /* Initialize feature configuration for tilt */ - struct bmi2_feature_config tilt_config = { 0, 0, 0 }; + /* Null-pointer check */ + rslt = null_ptr_check(dev); + if ((rslt == BMI2_OK) && (fifo != NULL)) + { + /* Clear the FIFO data structure */ + reset_fifo_frame_structure(fifo, dev); - /* Copy the feature configuration address to a local pointer */ - uint16_t *data_p = (uint16_t *) (void *)feat_config; + /* Read FIFO data */ + rslt = bmi2_get_regs(addr, fifo->data, fifo->length, dev); - /* Search for tilt feature and extract its configuration details */ - feat_found = bmi2_extract_input_feat_config(&tilt_config, BMI2_TILT, dev); - if (feat_found) - { - /* Get the configuration from the page where tilt feature resides */ - rslt = bmi2_get_feat_config(tilt_config.page, feat_config, dev); if (rslt == BMI2_OK) { - /* Define the offset in bytes for tilt select */ - idx = tilt_config.start_addr; - - /* Get offset in words since all the features are set in words length */ - idx = idx / 2; - - /* Set output configuration */ - *(data_p + idx) = BMI2_SET_BITS(*(data_p + idx), BMI2_TILT_OUT_CONF, config->out_conf); - - /* Increment offset by 1 more word to get the total length in words */ - idx++; - /* Get total length in bytes to copy from local pointer to the array */ - idx = (uint8_t)(idx * 2) - tilt_config.start_addr; - - /* Copy the bytes to be set back to the array */ - for (index = 0; index < idx; index++) - { - feat_config[tilt_config.start_addr + index] = *((uint8_t *) data_p + tilt_config.start_addr + index); - } - - /* Set the configuration back to the page */ - rslt = bmi2_set_regs(BMI2_FEATURES_REG_ADDR, feat_config, BMI2_FEAT_SIZE_IN_BYTES, dev); + /* Get the set FIFO frame configurations */ + rslt = bmi2_get_regs(BMI2_FIFO_CONFIG_0_ADDR, config_data, 2, dev); if (rslt == BMI2_OK) { - /* Copy out_conf value to a local copy in device structure */ - dev->int_map.tilt_out_conf = (uint8_t) config->out_conf; + /* Get FIFO header status */ + fifo->header_enable = (uint8_t)((config_data[1]) & (BMI2_FIFO_HEADER_EN >> 8)); + + /* Get sensor enable status, of which the data is to be read */ + fifo->data_enable = + (uint16_t)(((config_data[0]) | ((uint16_t) config_data[1] << 8)) & BMI2_FIFO_ALL_EN); } } + else + { + rslt = BMI2_E_COM_FAIL; + } } else { - rslt = BMI2_E_INVALID_SENSOR; + rslt = BMI2_E_NULL_PTR; } return rslt; } /*! - * @brief This internal API sets uphold to wake config configurations like output - * configuration. + * @brief This API parses and extracts the accelerometer frames from FIFO data + * read by the "bmi2_read_fifo_data" API and stores it in the "accel_data" + * structure instance. */ -static int8_t set_up_hold_to_wake_config(const struct bmi2_up_hold_to_wake_config *config, struct bmi2_dev *dev) +int8_t bmi2_extract_accel(struct bmi2_sens_axes_data *accel_data, + uint16_t *accel_length, + struct bmi2_fifo_frame *fifo, + const struct bmi2_dev *dev) { /* Variable to define error */ int8_t rslt; - /* Array to define the feature configuration */ - uint8_t feat_config[BMI2_FEAT_SIZE_IN_BYTES] = { 0 }; - - /* Variable to define the array offset */ - uint8_t idx = 0; - - /* Variable to define index */ - uint8_t index = 0; + /* Variable to index the bytes */ + uint16_t data_index = 0; - /* Variable to set flag */ - uint8_t feat_found; + /* Variable to index accelerometer frames */ + uint16_t accel_index = 0; - /* Initialize feature configuration for uphold to wake */ - struct bmi2_feature_config up_hold_to_wake_config = { 0, 0, 0 }; + /* Variable to store the number of bytes to be read */ + uint16_t data_read_length = 0; - /* Copy the feature configuration address to a local pointer */ - uint16_t *data_p = (uint16_t *) (void *)feat_config; + /* Variable to define the data enable byte */ + uint8_t data_enable = 0; - /* Search for uphold to wake feature and extract its configuration details */ - feat_found = bmi2_extract_input_feat_config(&up_hold_to_wake_config, BMI2_UP_HOLD_TO_WAKE, dev); - if (feat_found) + /* Null-pointer check */ + rslt = null_ptr_check(dev); + if ((rslt == BMI2_OK) && (accel_data != NULL) && (accel_length != NULL) && (fifo != NULL)) { - /* Get the configuration from the page where uphold to wake feature resides */ - rslt = bmi2_get_feat_config(up_hold_to_wake_config.page, feat_config, dev); - if (rslt == BMI2_OK) + /* Parsing the FIFO data in header-less mode */ + if (fifo->header_enable == 0) { - /* Define the offset in bytes for uphold to wake select */ - idx = up_hold_to_wake_config.start_addr; - - /* Get offset in words since all the features are set in words length */ - idx = idx / 2; - - /* Set output configuration */ - *(data_p + idx) = BMI2_SET_BITS(*(data_p + idx), BMI2_UP_HOLD_TO_WAKE_OUT_CONF, config->out_conf); - - /* Increment offset by 1 more word to get the total length in words */ - idx++; - /* Get total length in bytes to copy from local pointer to the array */ - idx = (uint8_t)(idx * 2) - up_hold_to_wake_config.start_addr; + /* Get the number of accelerometer bytes to be read */ + rslt = parse_fifo_accel_len(&data_index, &data_read_length, accel_length, fifo); - /* Copy the bytes to be set back to the array */ - for (index = 0; index < idx; index++) + /* Convert word to byte since all sensor enables are in a byte */ + data_enable = (uint8_t)(fifo->data_enable >> 8); + for (; (data_index < data_read_length) && (rslt != BMI2_W_FIFO_EMPTY);) { - feat_config[up_hold_to_wake_config.start_addr + - index] = *((uint8_t *) data_p + up_hold_to_wake_config.start_addr + index); - } + /* Unpack frame to get the accelerometer data */ + rslt = unpack_accel_frame(accel_data, &data_index, &accel_index, data_enable, fifo, dev); - /* Set the configuration back to the page */ - rslt = bmi2_set_regs(BMI2_FEATURES_REG_ADDR, feat_config, BMI2_FEAT_SIZE_IN_BYTES, dev); - if (rslt == BMI2_OK) - { - /* Copy out_conf value to a local copy in device structure */ - dev->int_map.up_hold_to_wake_out_conf = (uint8_t) config->out_conf; + if (rslt != BMI2_W_FIFO_EMPTY) + { + /* Check for the availability of next two bytes of FIFO data */ + rslt = check_empty_fifo(&data_index, fifo); + } } + + /* Update number of accelerometer frames to be read */ + (*accel_length) = accel_index; + + /* Update the accelerometer byte index */ + fifo->acc_byte_start_idx = data_index; + } + else + { + /* Parsing the FIFO data in header mode */ + rslt = extract_accel_header_mode(accel_data, accel_length, fifo, dev); } } else { - rslt = BMI2_E_INVALID_SENSOR; + rslt = BMI2_E_NULL_PTR; } return rslt; } /*! - * @brief This internal API sets glance detector configurations like output - * configuration. + * @brief This API parses and extracts the gyroscope frames from FIFO data + * read by the "bmi2_read_fifo_data" API and stores it in the "gyro_data" + * structure instance. */ -static int8_t set_glance_detect_config(const struct bmi2_glance_det_config *config, struct bmi2_dev *dev) +int8_t bmi2_extract_gyro(struct bmi2_sens_axes_data *gyro_data, + uint16_t *gyro_length, + struct bmi2_fifo_frame *fifo, + const struct bmi2_dev *dev) { /* Variable to define error */ int8_t rslt; - /* Array to define the feature configuration */ - uint8_t feat_config[BMI2_FEAT_SIZE_IN_BYTES] = { 0 }; - - /* Variable to define the array offset */ - uint8_t idx = 0; - - /* Variable to define index */ - uint8_t index = 0; + /* Variable to index the bytes */ + uint16_t data_index = 0; - /* Variable to set flag */ - uint8_t feat_found; + /* Variable to index gyroscope frames */ + uint16_t gyro_index = 0; - /* Initialize feature configuration for glance detector */ - struct bmi2_feature_config glance_det_config = { 0, 0, 0 }; + /* Variable to store the number of bytes to be read */ + uint16_t data_read_length = 0; - /* Copy the feature configuration address to a local pointer */ - uint16_t *data_p = (uint16_t *) (void *)feat_config; + /* Variable to define the data enable byte */ + uint8_t data_enable = 0; - /* Search for glance detector feature and extract its configuration details */ - feat_found = bmi2_extract_input_feat_config(&glance_det_config, BMI2_GLANCE_DETECTOR, dev); - if (feat_found) + /* Null-pointer check */ + rslt = null_ptr_check(dev); + if ((rslt == BMI2_OK) && (gyro_data != NULL) && (gyro_length != NULL) && (fifo != NULL)) { - /* Get the configuration from the page where glance detector feature resides */ - rslt = bmi2_get_feat_config(glance_det_config.page, feat_config, dev); - if (rslt == BMI2_OK) + /* Parsing the FIFO data in header-less mode */ + if (fifo->header_enable == 0) { - /* Define the offset in bytes for glance detector select */ - idx = glance_det_config.start_addr; - - /* Get offset in words since all the features are set in words length */ - idx = idx / 2; - - /* Set output configuration */ - *(data_p + idx) = BMI2_SET_BITS(*(data_p + idx), BMI2_GLANCE_DET_OUT_CONF, config->out_conf); - - /* Increment offset by 1 more word to get the total length in words */ - idx++; - - /* Get total length in bytes to copy from local pointer to the array */ - idx = (uint8_t)(idx * 2) - glance_det_config.start_addr; + /* Get the number of gyro bytes to be read */ + rslt = parse_fifo_gyro_len(&data_index, &data_read_length, gyro_length, fifo); - /* Copy the bytes to be set back to the array */ - for (index = 0; index < idx; index++) + /* Convert word to byte since all sensor enables are in a byte */ + data_enable = (uint8_t)(fifo->data_enable >> 8); + for (; (data_index < data_read_length) && (rslt != BMI2_W_FIFO_EMPTY);) { - feat_config[glance_det_config.start_addr + - index] = *((uint8_t *) data_p + glance_det_config.start_addr + index); + /* Unpack frame to get gyroscope data */ + rslt = unpack_gyro_frame(gyro_data, &data_index, &gyro_index, data_enable, fifo, dev); + if (rslt != BMI2_W_FIFO_EMPTY) + { + /* Check for the availability of next two bytes of FIFO data */ + rslt = check_empty_fifo(&data_index, fifo); + } } - /* Set the configuration back to the page */ - rslt = bmi2_set_regs(BMI2_FEATURES_REG_ADDR, feat_config, BMI2_FEAT_SIZE_IN_BYTES, dev); - if (rslt == BMI2_OK) - { - /* Copy out_conf value to a local copy in device structure */ - dev->int_map.glance_out_conf = (uint8_t) config->out_conf; - } + /* Update number of gyroscope frames to be read */ + (*gyro_length) = gyro_index; + + /* Update the gyroscope byte index */ + fifo->acc_byte_start_idx = data_index; + } + else + { + /* Parsing the FIFO data in header mode */ + rslt = extract_gyro_header_mode(gyro_data, gyro_length, fifo, dev); } } else { - rslt = BMI2_E_INVALID_SENSOR; + rslt = BMI2_E_NULL_PTR; } return rslt; } /*! - * @brief This internal API sets wake-up configurations like sensitivity, - * single, double and triple tap enable and output-configuration. + * @brief This API parses and extracts the auxiliary frames from FIFO data + * read by the "bmi2_read_fifo_data" API and stores it in "aux_data" buffer. */ -static int8_t set_wake_up_config(struct bmi2_wake_up_config *config, struct bmi2_dev *dev) +int8_t bmi2_extract_aux(struct bmi2_aux_fifo_data *aux, + uint16_t *aux_length, + struct bmi2_fifo_frame *fifo, + const struct bmi2_dev *dev) { /* Variable to define error */ - int8_t rslt = BMI2_OK; - - /* Array to define the feature configuration */ - uint8_t feat_config[BMI2_FEAT_SIZE_IN_BYTES] = { 0 }; - - /* Variable to define the array offset */ - uint8_t idx = 0; + int8_t rslt; - /* Variable to define index */ - uint8_t i = 0; + /* Variable to index the bytes */ + uint16_t data_index = 0; - /* Variable to set flag */ - uint8_t feat_found; + /* Variable to index auxiliary frames */ + uint16_t aux_index = 0; - /* Initialize feature configuration for wake-up */ - struct bmi2_feature_config wake_up_config = { 0, 0, 0 }; + /* Variable to store the number of bytes to be read */ + uint16_t data_read_length = 0; - /* Copy the feature configuration address to a local pointer */ - uint16_t *data_p = (uint16_t *) (void *)feat_config; + /* Variable to define the data enable byte */ + uint8_t data_enable = 0; - if (dev->chip_id == BMI260_CHIP_IDENTIFIER) - { - rslt = dev->set_wakeup_config(config, dev); - } - else if (dev->chip_id == BMI261_CHIP_IDENTIFIER) + /* Null-pointer check */ + rslt = null_ptr_check(dev); + if ((rslt == BMI2_OK) && (aux != NULL) && (aux_length != NULL) && (fifo != NULL)) { - /* Search for wake-up feature and extract its configuration details */ - feat_found = bmi2_extract_input_feat_config(&wake_up_config, BMI2_WAKE_UP, dev); - if (feat_found) + /* Parsing the FIFO data in header-less mode */ + if (fifo->header_enable == 0) { - /* Get the configuration from the page where wake-up feature resides */ - rslt = bmi2_get_feat_config(wake_up_config.page, feat_config, dev); - if (rslt == BMI2_OK) - { - /* Define the offset in bytes for wake-up select */ - idx = wake_up_config.start_addr; - - /* Get offset in words since all the features are set in words length */ - idx = idx / 2; - - /* Set sensitivity */ - *(data_p + idx) = BMI2_SET_BITS(*(data_p + idx), BMI2_WAKE_UP_SENSITIVITY, config->sensitivity); - - /* Set single/double tap enable */ - *(data_p + idx) = BMI2_SET_BITS(*(data_p + idx), BMI2_WAKE_UP_SINGLE_TAP_EN, config->single_tap_en); - - /* Set output configuration */ - *(data_p + idx) = BMI2_SET_BITS(*(data_p + idx), BMI2_WAKE_UP_OUT_CONF, config->out_conf); - - /* Increment offset by 1 more word to get the total length in words */ - idx++; - - /* Get total length in bytes to copy from local pointer to the array */ - idx = (uint8_t)(idx * 2) - wake_up_config.start_addr; - - /* Copy the bytes to be set back to the array */ - for (i = 0; i < idx; i++) - { - feat_config[wake_up_config.start_addr + i] = *((uint8_t *) data_p + wake_up_config.start_addr + i); - } + rslt = parse_fifo_aux_len(&data_index, &data_read_length, aux_length, fifo); - /* Set the configuration back to the page */ - rslt = bmi2_set_regs(BMI2_FEATURES_REG_ADDR, feat_config, BMI2_FEAT_SIZE_IN_BYTES, dev); - if (rslt == BMI2_OK) + /* Convert word to byte since all sensor enables are in + * a byte + */ + data_enable = (uint8_t)(fifo->data_enable >> 8); + for (; (data_index < data_read_length) && (rslt != BMI2_W_FIFO_EMPTY);) + { + /* Unpack frame to get auxiliary data */ + rslt = unpack_aux_frame(aux, &data_index, &aux_index, data_enable, fifo, dev); + if (rslt != BMI2_W_FIFO_EMPTY) { - /* Copy out_conf value to a local copy in device structure */ - dev->int_map.wake_up_out_conf = (uint8_t) config->out_conf; + /* Check for the availability of next + * two bytes of FIFO data + */ + rslt = check_empty_fifo(&data_index, fifo); } } + + /* Update number of auxiliary frames to be read */ + *aux_length = aux_index; + + /* Update the auxiliary byte index */ + fifo->aux_byte_start_idx = data_index; + } + else + { + /* Parsing the FIFO data in header mode */ + rslt = extract_aux_header_mode(aux, aux_length, fifo, dev); } } else { - rslt = BMI2_E_INVALID_SENSOR; + rslt = BMI2_E_NULL_PTR; } return rslt; } /*! - * @brief This internal API sets orientation configurations like upside/down - * detection, symmetrical modes, blocking mode, theta, hysteresis and output - * configuration. + * @brief This API writes the available sensor specific commands to the sensor. */ -static int8_t set_orient_config(const struct bmi2_orient_config *config, struct bmi2_dev *dev) +int8_t bmi2_set_command_register(uint8_t command, struct bmi2_dev *dev) { /* Variable to define error */ int8_t rslt; - /* Array to define the feature configuration */ - uint8_t feat_config[BMI2_FEAT_SIZE_IN_BYTES] = { 0 }; - - /* Variable to define the array offset */ - uint8_t idx = 0; - - /* Variable to define index */ - uint8_t index = 0; - - /* Variable to set flag */ - uint8_t feat_found; - - /* Initialize feature configuration for orient */ - struct bmi2_feature_config orient_config = { 0, 0, 0 }; - - /* Copy the feature configuration address to a local pointer */ - uint16_t *data_p = (uint16_t *) (void *)feat_config; - - /* Search for orient feature and extract its configuration details */ - feat_found = bmi2_extract_input_feat_config(&orient_config, BMI2_ORIENTATION, dev); - if (feat_found) + /* Null-pointer check */ + rslt = null_ptr_check(dev); + if (rslt == BMI2_OK) { - /* Get the configuration from the page where orient feature resides */ - rslt = bmi2_get_feat_config(orient_config.page, feat_config, dev); - if (rslt == BMI2_OK) - { - /* Define the offset in bytes for orient select */ - idx = orient_config.start_addr; - - /* Get offset in words since all the features are set in words length */ - idx = idx / 2; - - /* Set upside/down detection */ - *(data_p + idx) = BMI2_SET_BITS(*(data_p + idx), BMI2_ORIENT_UP_DOWN, config->ud_en); - - /* Set symmetrical modes */ - *(data_p + idx) = BMI2_SET_BITS(*(data_p + idx), BMI2_ORIENT_SYMM_MODE, config->mode); - - /* Set blocking mode */ - *(data_p + idx) = BMI2_SET_BITS(*(data_p + idx), BMI2_ORIENT_BLOCK_MODE, config->blocking); - - /* Set theta */ - *(data_p + idx) = BMI2_SET_BITS(*(data_p + idx), BMI2_ORIENT_THETA, config->theta); - - /* Increment offset by 1 more word to set hysteresis and output configuration */ - idx++; - - /* Set hysteresis */ - *(data_p + idx) = BMI2_SET_BIT_POS0(*(data_p + idx), BMI2_ORIENT_HYST, config->hysteresis); - - /* Set output configuration */ - *(data_p + idx) = BMI2_SET_BITS(*(data_p + idx), BMI2_ORIENT_OUT_CONF, config->out_conf); + /* Set the command in the command register */ + rslt = bmi2_set_regs(BMI2_CMD_REG_ADDR, &command, 1, dev); + } - /* Increment offset by 1 more word to get the total length in words */ - idx++; + return rslt; +} - /* Get total length in bytes to copy from local pointer to the array */ - idx = (uint8_t)(idx * 2) - orient_config.start_addr; +/* + * @brief This API sets the FIFO self wake up functionality in the sensor. + */ +int8_t bmi2_set_fifo_self_wake_up(uint8_t fifo_self_wake_up, struct bmi2_dev *dev) +{ + /* Variable to define error */ + int8_t rslt; - /* Copy the bytes to be set back to the array */ - for (index = 0; index < idx; index++) - { - feat_config[orient_config.start_addr + - index] = *((uint8_t *) data_p + orient_config.start_addr + index); - } + /* Variable to store data */ + uint8_t data = 0; - /* Set the configuration back to the page */ - rslt = bmi2_set_regs(BMI2_FEATURES_REG_ADDR, feat_config, BMI2_FEAT_SIZE_IN_BYTES, dev); - if (rslt == BMI2_OK) - { - /* Copy out_conf value to a local copy in device structure */ - dev->int_map.orient_out_conf = (uint8_t) config->out_conf; - } - } - } - else + /* Null-pointer check */ + rslt = null_ptr_check(dev); + if (rslt == BMI2_OK) { - rslt = BMI2_E_INVALID_SENSOR; + /* Set FIFO self wake-up */ + rslt = bmi2_get_regs(BMI2_PWR_CONF_ADDR, &data, 1, dev); + if (rslt == BMI2_OK) + { + data = BMI2_SET_BITS(data, BMI2_FIFO_SELF_WAKE_UP, fifo_self_wake_up); + rslt = bmi2_set_regs(BMI2_PWR_CONF_ADDR, &data, 1, dev); + } } return rslt; } /*! - * @brief This internal API sets high-g configurations like threshold, - * hysteresis, duration, and out0put configuration. + * @brief This API gets the status of FIFO self wake up functionality from + * the sensor. */ -static int8_t set_high_g_config(const struct bmi2_high_g_config *config, struct bmi2_dev *dev) +int8_t bmi2_get_fifo_self_wake_up(uint8_t *fifo_self_wake_up, struct bmi2_dev *dev) { /* Variable to define error */ int8_t rslt; - /* Array to define the feature configuration */ - uint8_t feat_config[BMI2_FEAT_SIZE_IN_BYTES] = { 0 }; - - /* Variable to define the array offset */ - uint8_t idx = 0; - - /* Variable to define index */ - uint8_t index = 0; - - /* Variable to set flag */ - uint8_t feat_found; - - /* Initialize feature configuration for high-g */ - struct bmi2_feature_config high_g_config = { 0, 0, 0 }; - - /* Copy the feature configuration address to a local pointer */ - uint16_t *data_p = (uint16_t *) (void *)feat_config; + /* Variable to store data */ + uint8_t data = 0; - /* Search for high-g feature and extract its configuration details */ - feat_found = bmi2_extract_input_feat_config(&high_g_config, BMI2_HIGH_G, dev); - if (feat_found) + /* Null-pointer check */ + rslt = null_ptr_check(dev); + if ((rslt == BMI2_OK) && (fifo_self_wake_up != NULL)) { - /* Get the configuration from the page where high-g feature resides */ - rslt = bmi2_get_feat_config(high_g_config.page, feat_config, dev); + /* Get the status of FIFO self wake-up */ + rslt = bmi2_get_regs(BMI2_PWR_CONF_ADDR, &data, 1, dev); if (rslt == BMI2_OK) { - /* Define the offset in bytes for high-g select */ - idx = high_g_config.start_addr; - - /* Get offset in words since all the features are set in words length */ - idx = idx / 2; - - /* Set threshold */ - *(data_p + idx) = BMI2_SET_BIT_POS0(*(data_p + idx), BMI2_HIGH_G_THRES, config->threshold); - - /* Increment offset by 1 more word to set hysteresis */ - idx++; - - /* Set hysteresis */ - *(data_p + idx) = BMI2_SET_BIT_POS0(*(data_p + idx), BMI2_HIGH_G_HYST, config->hysteresis); - - /* Set x-select */ - *(data_p + idx) = BMI2_SET_BITS(*(data_p + idx), BMI2_HIGH_G_X_SEL, config->select_x); - - /* Set y-select */ - *(data_p + idx) = BMI2_SET_BITS(*(data_p + idx), BMI2_HIGH_G_Y_SEL, config->select_y); - - /* Set z-select */ - *(data_p + idx) = BMI2_SET_BITS(*(data_p + idx), BMI2_HIGH_G_Z_SEL, config->select_z); - - /* Increment offset by 1 more word to set duration and output configuration */ - idx++; - - /* Set duration */ - *(data_p + idx) = BMI2_SET_BIT_POS0(*(data_p + idx), BMI2_HIGH_G_DUR, config->duration); - - /* Set output configuration */ - *(data_p + idx) = BMI2_SET_BITS(*(data_p + idx), BMI2_HIGH_G_OUT_CONF, config->out_conf); - - /* Increment offset by 1 more word to get the total length in words */ - idx++; - - /* Get total length in bytes to copy from local pointer to the array */ - idx = (uint8_t)(idx * 2) - high_g_config.start_addr; - - /* Copy the bytes to be set back to the array */ - for (index = 0; index < idx; index++) - { - feat_config[high_g_config.start_addr + - index] = *((uint8_t *) data_p + high_g_config.start_addr + index); - } - - /* Set the configuration back to the page */ - rslt = bmi2_set_regs(BMI2_FEATURES_REG_ADDR, feat_config, BMI2_FEAT_SIZE_IN_BYTES, dev); - if (rslt == BMI2_OK) - { - /* Copy out_conf value to a local copy in device structure */ - dev->int_map.high_g_out_conf = (uint8_t) config->out_conf; - } + (*fifo_self_wake_up) = BMI2_GET_BITS(data, BMI2_FIFO_SELF_WAKE_UP); } } else { - rslt = BMI2_E_INVALID_SENSOR; + rslt = BMI2_E_NULL_PTR; } return rslt; } /*! - * @brief This internal API sets low-g configurations like threshold, - * hysteresis, duration, and output configuration. + * @brief This API sets the FIFO water-mark level in the sensor. */ -static int8_t set_low_g_config(const struct bmi2_low_g_config *config, struct bmi2_dev *dev) +int8_t bmi2_set_fifo_wm(uint16_t fifo_wm, struct bmi2_dev *dev) { /* Variable to define error */ int8_t rslt; - /* Array to define the feature configuration */ - uint8_t feat_config[BMI2_FEAT_SIZE_IN_BYTES] = { 0 }; + /* Array to store data */ + uint8_t data[2] = { 0 }; - /* Variable to define the array offset */ - uint8_t idx = 0; + /* Null-pointer check */ + rslt = null_ptr_check(dev); + if (rslt == BMI2_OK) + { + /* Get LSB value of FIFO water-mark */ + data[0] = BMI2_GET_LSB(fifo_wm); - /* Variable to define index */ - uint8_t index = 0; + /* Get MSB value of FIFO water-mark */ + data[1] = BMI2_GET_MSB(fifo_wm); - /* Variable to set flag */ - uint8_t feat_found; + /* Set the FIFO water-mark level */ + rslt = bmi2_set_regs(BMI2_FIFO_WTM_0_ADDR, data, 2, dev); + } - /* Initialize feature configuration for low-g */ - struct bmi2_feature_config low_g_config = { 0, 0, 0 }; + return rslt; +} - /* Copy the feature configuration address to a local pointer */ - uint16_t *data_p = (uint16_t *) (void *)feat_config; +/*! + * @brief This API reads the FIFO water mark level set in the sensor. + */ +int8_t bmi2_get_fifo_wm(uint16_t *fifo_wm, struct bmi2_dev *dev) +{ + /* Variable to define error */ + int8_t rslt; - /* Search for low-g feature and extract its configuration details */ - feat_found = bmi2_extract_input_feat_config(&low_g_config, BMI2_LOW_G, dev); - if (feat_found) + /* Array to to store data */ + uint8_t data[2] = { 0 }; + + /* Null-pointer check */ + rslt = null_ptr_check(dev); + if ((rslt == BMI2_OK) && (fifo_wm != NULL)) { - /* Get the configuration from the page where low-g feature resides */ - rslt = bmi2_get_feat_config(low_g_config.page, feat_config, dev); + /* Read the FIFO water mark level */ + rslt = bmi2_get_regs(BMI2_FIFO_WTM_0_ADDR, data, BMI2_FIFO_WM_LENGTH, dev); if (rslt == BMI2_OK) { - /* Define the offset in bytes for low-g select */ - idx = low_g_config.start_addr; - - /* Get offset in words since all the features are set in words length */ - idx = idx / 2; - - /* Set threshold */ - *(data_p + idx) = BMI2_SET_BIT_POS0(*(data_p + idx), BMI2_LOW_G_THRES, config->threshold); - - /* Increment offset by 1 more word to set hysteresis */ - idx++; - - /* Set hysteresis */ - *(data_p + idx) = BMI2_SET_BIT_POS0(*(data_p + idx), BMI2_LOW_G_HYST, config->hysteresis); - - /* Increment offset by 1 more word to set duration and output configuration */ - idx++; - - /* Set duration */ - *(data_p + idx) = BMI2_SET_BIT_POS0(*(data_p + idx), BMI2_LOW_G_DUR, config->duration); - - /* Set output configuration */ - *(data_p + idx) = BMI2_SET_BITS(*(data_p + idx), BMI2_LOW_G_OUT_CONF, config->out_conf); - - /* Increment offset by 1 more word to get the total length in words */ - idx++; - - /* Get total length in bytes to copy from local pointer to the array */ - idx = (uint8_t)(idx * 2) - low_g_config.start_addr; - - /* Copy the bytes to be set back to the array */ - for (index = 0; index < idx; index++) - { - feat_config[low_g_config.start_addr + index] = *((uint8_t *) data_p + low_g_config.start_addr + index); - } - - /* Set the configuration back to the page */ - rslt = bmi2_set_regs(BMI2_FEATURES_REG_ADDR, feat_config, BMI2_FEAT_SIZE_IN_BYTES, dev); - if (rslt == BMI2_OK) - { - /* Copy out_conf value to a local copy in device structure */ - dev->int_map.low_g_out_conf = (uint8_t) config->out_conf; - } + (*fifo_wm) = (uint16_t)((uint16_t) data[1] << 8) | (data[0]); } } else { - rslt = BMI2_E_INVALID_SENSOR; + rslt = BMI2_E_NULL_PTR; } return rslt; } /*! - * @brief This internal API sets flat configurations like theta, blocking, - * hold-time, hysteresis, and output configuration. + * @brief This API sets either filtered or un-filtered FIFO accelerometer or + * gyroscope data. */ -static int8_t set_flat_config(const struct bmi2_flat_config *config, struct bmi2_dev *dev) +int8_t bmi2_set_fifo_filter_data(uint8_t sens_sel, uint8_t fifo_filter_data, struct bmi2_dev *dev) { /* Variable to define error */ int8_t rslt; - /* Array to define the feature configuration */ - uint8_t feat_config[BMI2_FEAT_SIZE_IN_BYTES] = { 0 }; - - /* Variable to define the array offset */ - uint8_t idx = 0; - - /* Variable to define index */ - uint8_t index = 0; - - /* Variable to set flag */ - uint8_t feat_found; - - /* Initialize feature configuration for flat */ - struct bmi2_feature_config flat_config = { 0, 0, 0 }; - - /* Copy the feature configuration address to a local pointer */ - uint16_t *data_p = (uint16_t *) (void *)feat_config; + /* Variable to store data */ + uint8_t data = 0; - /* Search for flat feature and extract its configuration details */ - feat_found = bmi2_extract_input_feat_config(&flat_config, BMI2_FLAT, dev); - if (feat_found) + /* Null-pointer check */ + rslt = null_ptr_check(dev); + if (rslt == BMI2_OK) { - /* Get the configuration from the page where flat feature resides */ - rslt = bmi2_get_feat_config(flat_config.page, feat_config, dev); - if (rslt == BMI2_OK) + switch (sens_sel) { - /* Define the offset in bytes for flat select */ - idx = flat_config.start_addr; + case BMI2_ACCEL: - /* Get offset in words since all the features are set in words length */ - idx = idx / 2; + /* Validate filter mode */ + if (fifo_filter_data <= BMI2_MAX_VALUE_FIFO_FILTER) + { + /* Set the accelerometer FIFO filter data */ + rslt = bmi2_get_regs(BMI2_FIFO_DOWNS_ADDR, &data, 1, dev); + if (rslt == BMI2_OK) + { + data = BMI2_SET_BITS(data, BMI2_ACC_FIFO_FILT_DATA, fifo_filter_data); + rslt = bmi2_set_regs(BMI2_FIFO_DOWNS_ADDR, &data, 1, dev); + } + } + else + { + rslt = BMI2_E_OUT_OF_RANGE; + } + + break; + case BMI2_GYRO: - /* Set theta */ - *(data_p + idx) = BMI2_SET_BITS(*(data_p + idx), BMI2_FLAT_THETA, config->theta); + /* Validate filter mode */ + if (fifo_filter_data <= BMI2_MAX_VALUE_FIFO_FILTER) + { + /* Set the gyroscope FIFO filter data */ + rslt = bmi2_get_regs(BMI2_FIFO_DOWNS_ADDR, &data, 1, dev); + if (rslt == BMI2_OK) + { + data = BMI2_SET_BITS(data, BMI2_GYR_FIFO_FILT_DATA, fifo_filter_data); + rslt = bmi2_set_regs(BMI2_FIFO_DOWNS_ADDR, &data, 1, dev); + } + } + else + { + rslt = BMI2_E_OUT_OF_RANGE; + } - /* Set blocking */ - *(data_p + idx) = BMI2_SET_BITS(*(data_p + idx), BMI2_FLAT_BLOCK, config->blocking); + break; + default: + rslt = BMI2_E_INVALID_SENSOR; + break; + } + } - /* Set output configuration */ - *(data_p + idx) = BMI2_SET_BITS(*(data_p + idx), BMI2_FLAT_OUT_CONF, config->out_conf); + return rslt; +} - /* Increment offset by 1 more word to set hysteresis and hold-time */ - idx++; +/*! + * @brief This API gets the FIFO accelerometer or gyroscope filter data. + */ +int8_t bmi2_get_fifo_filter_data(uint8_t sens_sel, uint8_t *fifo_filter_data, struct bmi2_dev *dev) +{ + /* Variable to define error */ + int8_t rslt; - /* Set hysteresis */ - *(data_p + idx) = BMI2_SET_BIT_POS0(*(data_p + idx), BMI2_FLAT_HYST, config->hysteresis); + /* Variable to store FIFO filter mode */ + uint8_t data = 0; - /* Set hold-time */ - *(data_p + idx) = BMI2_SET_BITS(*(data_p + idx), BMI2_FLAT_HOLD_TIME, config->hold_time); + /* Null-pointer check */ + rslt = null_ptr_check(dev); + if ((rslt == BMI2_OK) && (fifo_filter_data != NULL)) + { + switch (sens_sel) + { + case BMI2_ACCEL: - /* Increment offset by 1 more word to get the total length in words */ - idx++; + /* Read the accelerometer FIFO filter data */ + rslt = bmi2_get_regs(BMI2_FIFO_DOWNS_ADDR, &data, 1, dev); + if (rslt == BMI2_OK) + { + (*fifo_filter_data) = BMI2_GET_BITS(data, BMI2_ACC_FIFO_FILT_DATA); + } - /* Get total length in bytes to copy from local pointer to the array */ - idx = (uint8_t)(idx * 2) - flat_config.start_addr; + break; + case BMI2_GYRO: - /* Copy the bytes to be set back to the array */ - for (index = 0; index < idx; index++) - { - feat_config[flat_config.start_addr + index] = *((uint8_t *) data_p + flat_config.start_addr + index); - } + /* Read the gyroscope FIFO filter data */ + rslt = bmi2_get_regs(BMI2_FIFO_DOWNS_ADDR, &data, 1, dev); + if (rslt == BMI2_OK) + { + (*fifo_filter_data) = BMI2_GET_BITS(data, BMI2_GYR_FIFO_FILT_DATA); + } - /* Set the configuration back to the page */ - rslt = bmi2_set_regs(BMI2_FEATURES_REG_ADDR, feat_config, BMI2_FEAT_SIZE_IN_BYTES, dev); - if (rslt == BMI2_OK) - { - /* Copy out_conf value to a local copy in device structure */ - dev->int_map.flat_out_conf = (uint8_t) config->out_conf; - } + break; + default: + rslt = BMI2_E_INVALID_SENSOR; + break; } } else { - rslt = BMI2_E_INVALID_SENSOR; + rslt = BMI2_E_NULL_PTR; } return rslt; } /*! - * @brief This internal API sets external sensor sync configurations like output - * configuration. + * @brief This API sets the down-sampling rates for accelerometer or gyroscope + * FIFO data. */ -static int8_t set_ext_sens_sync_config(const struct bmi2_ext_sens_sync_config *config, struct bmi2_dev *dev) +int8_t bmi2_set_fifo_down_sample(uint8_t sens_sel, uint8_t fifo_down_samp, struct bmi2_dev *dev) { /* Variable to define error */ int8_t rslt; - /* Array to define the feature configuration */ - uint8_t feat_config[BMI2_FEAT_SIZE_IN_BYTES] = { 0 }; - - /* Variable to define the array offset */ - uint8_t idx = 0; - - /* Variable to define index */ - uint8_t index = 0; - - /* Variable to set flag */ - uint8_t feat_found; - - /* Initialize feature configuration for external sensor sync */ - struct bmi2_feature_config ext_sens_sync_config = { 0, 0, 0 }; - - /* Copy the feature configuration address to a local pointer */ - uint16_t *data_p = (uint16_t *) (void *)feat_config; + /* Variable to store sampling rate */ + uint8_t data = 0; - /* Search for external sensor sync feature and extract its configuration details */ - feat_found = bmi2_extract_input_feat_config(&ext_sens_sync_config, BMI2_EXT_SENS_SYNC, dev); - if (feat_found) + /* Null-pointer check */ + rslt = null_ptr_check(dev); + if (rslt == BMI2_OK) { - /* Get the configuration from the page where external sensor sync feature resides */ - rslt = bmi2_get_feat_config(ext_sens_sync_config.page, feat_config, dev); - if (rslt == BMI2_OK) + switch (sens_sel) { - /* Define the offset in bytes for external sensor sync select */ - idx = ext_sens_sync_config.start_addr; - - /* Get offset in words since all the features are set in words length */ - idx = idx / 2; - - /* Set output configuration */ - *(data_p + idx) = BMI2_SET_BITS(*(data_p + idx), BMI2_EXT_SENS_SYNC_OUT_CONF, config->out_conf); + case BMI2_ACCEL: - /* Increment offset by 1 more word to get the total length in words */ - idx++; + /* Set the accelerometer FIFO down sampling rate */ + rslt = bmi2_get_regs(BMI2_FIFO_DOWNS_ADDR, &data, 1, dev); + if (rslt == BMI2_OK) + { + data = BMI2_SET_BITS(data, BMI2_ACC_FIFO_DOWNS, fifo_down_samp); + rslt = bmi2_set_regs(BMI2_FIFO_DOWNS_ADDR, &data, 1, dev); + } - /* Get total length in bytes to copy from local pointer to the array */ - idx = (uint8_t)(idx * 2) - ext_sens_sync_config.start_addr; + break; + case BMI2_GYRO: - /* Copy the bytes to be set back to the array */ - for (index = 0; index < idx; index++) - { - feat_config[ext_sens_sync_config.start_addr + - index] = *((uint8_t *) data_p + ext_sens_sync_config.start_addr + index); - } + /* Set the gyroscope FIFO down sampling rate */ + rslt = bmi2_get_regs(BMI2_FIFO_DOWNS_ADDR, &data, 1, dev); + if (rslt == BMI2_OK) + { + data = BMI2_SET_BIT_POS0(data, BMI2_GYR_FIFO_DOWNS, fifo_down_samp); + rslt = bmi2_set_regs(BMI2_FIFO_DOWNS_ADDR, &data, 1, dev); + } - /* Set the configuration back to the page */ - rslt = bmi2_set_regs(BMI2_FEATURES_REG_ADDR, feat_config, BMI2_FEAT_SIZE_IN_BYTES, dev); - if (rslt == BMI2_OK) - { - /* Copy out_conf value to a local copy in device structure */ - dev->int_map.ext_sync_out_conf = (uint8_t) config->out_conf; - } + break; + default: + rslt = BMI2_E_INVALID_SENSOR; + break; } } - else - { - rslt = BMI2_E_INVALID_SENSOR; - } return rslt; } /*! - * @brief This internal API sets wrist gesture configurations like wearable-arm, - * and output-configuration. + * @brief This API reads the down sampling rates which is configured for + * accelerometer or gyroscope FIFO data. */ -static int8_t set_wrist_gest_config(const struct bmi2_wrist_gest_config *config, struct bmi2_dev *dev) +int8_t bmi2_get_fifo_down_sample(uint8_t sens_sel, uint8_t *fifo_down_samp, struct bmi2_dev *dev) { /* Variable to define error */ int8_t rslt; - /* Array to define the feature configuration */ - uint8_t feat_config[BMI2_FEAT_SIZE_IN_BYTES] = { 0 }; - - /* Variable to define the array offset */ - uint8_t idx = 0; - - /* Variable to define index */ - uint8_t index = 0; - - /* Variable to set flag */ - uint8_t feat_found; - - /* Initialize feature configuration for wrist gesture */ - struct bmi2_feature_config wrist_gest_config = { 0, 0, 0 }; - - /* Copy the feature configuration address to a local pointer */ - uint16_t *data_p = (uint16_t *) (void *)feat_config; + /* Variable to store sampling rate */ + uint8_t data = 0; - /* Search for wrist gesture feature and extract its configuration details */ - feat_found = bmi2_extract_input_feat_config(&wrist_gest_config, BMI2_WRIST_GESTURE, dev); - if (feat_found) + /* Null-pointer check */ + rslt = null_ptr_check(dev); + if ((rslt == BMI2_OK) && (fifo_down_samp != NULL)) { - /* Get the configuration from the page where wrist gesture feature resides */ - rslt = bmi2_get_feat_config(wrist_gest_config.page, feat_config, dev); - if (rslt == BMI2_OK) + switch (sens_sel) { - /* Define the offset in bytes for gesture select */ - idx = wrist_gest_config.start_addr; - - /* Get offset in words since all the features are set in words length */ - idx = idx / 2; - - /* Set wearable arm */ - *(data_p + idx) = BMI2_SET_BITS(*(data_p + idx), BMI2_WRIST_GEST_WEAR_ARM, config->wearable_arm); - - /* Set output configuration */ - *(data_p + idx) = BMI2_SET_BIT_POS0(*(data_p + idx), BMI2_WRIST_GEST_OUT_CONF, config->out_conf); - - /* Increment offset by 1 more word to set minimum tilt angle (min_flick_peak) */ - idx++; - *(data_p + idx) = config->min_flick_peak; - - /* Increment offset by 1 more word to set min_flick_samples */ - idx++; - *(data_p + idx) = config->min_flick_samples; - - /* Increment offset by 1 more word to set max time within gesture moment has to be completed */ - idx++; - *(data_p + idx) = config->max_duration; + case BMI2_ACCEL: - /* Increment offset by 1 more word to get the total length in words */ - idx++; + /* Read the accelerometer FIFO down data sampling rate */ + rslt = bmi2_get_regs(BMI2_FIFO_DOWNS_ADDR, &data, 1, dev); + if (rslt == BMI2_OK) + { + (*fifo_down_samp) = BMI2_GET_BITS(data, BMI2_ACC_FIFO_DOWNS); + } - /* Get total length in bytes to copy from local pointer to the array */ - idx = (uint8_t)(idx * 2) - wrist_gest_config.start_addr; + break; + case BMI2_GYRO: - /* Copy the bytes to be set back to the array */ - for (index = 0; index < idx; index++) - { - feat_config[wrist_gest_config.start_addr + - index] = *((uint8_t *) data_p + wrist_gest_config.start_addr + index); - } + /* Read the gyroscope FIFO down data sampling rate */ + rslt = bmi2_get_regs(BMI2_FIFO_DOWNS_ADDR, &data, 1, dev); + if (rslt == BMI2_OK) + { + (*fifo_down_samp) = BMI2_GET_BIT_POS0(data, BMI2_GYR_FIFO_DOWNS); + } - /* Set the configuration back to the page */ - rslt = bmi2_set_regs(BMI2_FEATURES_REG_ADDR, feat_config, BMI2_FEAT_SIZE_IN_BYTES, dev); - if (rslt == BMI2_OK) - { - /* Copy out_conf value to a local copy in device structure */ - dev->int_map.wrist_gest_out_conf = (uint8_t) config->out_conf; - } + break; + default: + rslt = BMI2_E_INVALID_SENSOR; + break; } } else { - rslt = BMI2_E_INVALID_SENSOR; + rslt = BMI2_E_NULL_PTR; } return rslt; } /*! - * @brief This internal API sets wrist wear wake-up configurations like - * output-configuration. + * @brief This API gets the length of FIFO data available in the sensor in + * bytes. */ -static int8_t set_wrist_wear_wake_up_config(const struct bmi2_wrist_wear_wake_up_config *config, struct bmi2_dev *dev) +int8_t bmi2_get_fifo_length(uint16_t *fifo_length, struct bmi2_dev *dev) { /* Variable to define error */ int8_t rslt; - /* Array to define the feature configuration */ - uint8_t feat_config[BMI2_FEAT_SIZE_IN_BYTES] = { 0 }; - - /* Variable to define the array offset */ - uint8_t idx = 0; - - /* Variable to define index */ + /* Variable to define byte index */ uint8_t index = 0; - /* Variable to set flag */ - uint8_t feat_found; - - /* Initialize feature configuration for wrist wear wake-up */ - struct bmi2_feature_config wrist_wake_up_config = { 0, 0, 0 }; - - /* Copy the feature configuration address to a local pointer */ - uint16_t *data_p = (uint16_t *) (void *)feat_config; + /* Array to store FIFO data length */ + uint8_t data[BMI2_FIFO_DATA_LENGTH] = { 0 }; - /* Search for wrist wear wake-up feature and extract its configuration details */ - feat_found = bmi2_extract_input_feat_config(&wrist_wake_up_config, BMI2_WRIST_WEAR_WAKE_UP, dev); - if (feat_found) + /* Null-pointer check */ + rslt = null_ptr_check(dev); + if ((rslt == BMI2_OK) && (fifo_length != NULL)) { - /* Get the configuration from the page where wrist wear wake-up feature resides */ - rslt = bmi2_get_feat_config(wrist_wake_up_config.page, feat_config, dev); + /* Read FIFO length */ + rslt = bmi2_get_regs(BMI2_FIFO_LENGTH_0_ADDR, data, BMI2_FIFO_DATA_LENGTH, dev); if (rslt == BMI2_OK) { - /* Define the offset in bytes for wrist wear wake-up select */ - idx = wrist_wake_up_config.start_addr; - - /* Get offset in words since all the features are set in words length */ - idx = idx / 2; - - /* Set output configuration */ - *(data_p + idx) = BMI2_SET_BIT_POS0(*(data_p + idx), BMI2_WRIST_WAKE_UP_OUT_CONF, config->out_conf); - - /* Increment offset by 1 more word to set min_angle_focus */ - idx++; - *(data_p + idx) = config->min_angle_focus; - - /* Increment offset by 1 more word to set min_angle_nonfocus */ - idx++; - *(data_p + idx) = config->min_angle_nonfocus; - - /* Increment offset by 1 more word to set max_tilt_lr */ - idx++; - *(data_p + idx) = config->max_tilt_lr; - - /* Increment offset by 1 more word to set max_tilt_ll */ - idx++; - *(data_p + idx) = config->max_tilt_ll; - - /* Increment offset by 1 more word to set max_tilt_pd */ - idx++; - *(data_p + idx) = config->max_tilt_pd; - - /* Increment offset by 1 more word to set max_tilt_pu */ - idx++; - *(data_p + idx) = config->max_tilt_pu; - - /* Increment offset by 1 more word to get the total length in words */ - idx++; - - /* Get total length in bytes to copy from local pointer to the array */ - idx = (uint8_t)(idx * 2) - wrist_wake_up_config.start_addr; + /* Get the MSB byte index */ + index = BMI2_FIFO_LENGTH_MSB_BYTE; - /* Copy the bytes to be set back to the array */ - for (index = 0; index < idx; index++) - { - feat_config[wrist_wake_up_config.start_addr + - index] = *((uint8_t *) data_p + wrist_wake_up_config.start_addr + index); - } + /* Get the MSB byte of FIFO length */ + data[index] = BMI2_GET_BIT_POS0(data[index], BMI2_FIFO_BYTE_COUNTER_MSB); - /* Set the configuration back to the page */ - rslt = bmi2_set_regs(BMI2_FEATURES_REG_ADDR, feat_config, BMI2_FEAT_SIZE_IN_BYTES, dev); - if (rslt == BMI2_OK) - { - /* Copy out_conf value to a local copy in device structure */ - dev->int_map.wrist_wear_wake_up_out_conf = (uint8_t) config->out_conf; - } + /* Get total FIFO length */ + (*fifo_length) = ((data[index] << 8) | data[index - 1]); } } else { - rslt = BMI2_E_INVALID_SENSOR; + rslt = BMI2_E_NULL_PTR; } return rslt; } /*! - * @brief This internal API sets wrist gesture configurations like wearable-arm, - * and output-configuration for wearable variant. + * @brief This API reads the user-defined bytes of data from the given register + * address of auxiliary sensor in manual mode. + * + * @note Change of BMI2_AUX_RD_ADDR is only allowed if AUX is not busy. */ -static int8_t set_wrist_gest_w_config(const struct bmi2_wrist_gest_w_config *config, struct bmi2_dev *dev) +int8_t bmi2_read_aux_man_mode(uint8_t reg_addr, uint8_t *aux_data, uint16_t len, struct bmi2_dev *dev) { /* Variable to define error */ int8_t rslt; - /* Array to define the feature configuration */ - uint8_t feat_config[BMI2_FEAT_SIZE_IN_BYTES] = { 0 }; - - /* Variable to define the array offset */ - uint8_t idx = 0; - - /* Variable to define index */ - uint8_t index = 0; - - /* Variable to set flag */ - uint8_t feat_found; - - /* Initialize feature configuration for wrist gesture */ - struct bmi2_feature_config wrist_gest_config = { 0, 0, 0 }; + /* Variable to store burst length */ + uint8_t burst_len = 0; - /* Copy the feature configuration address to a local pointer */ - uint16_t *data_p = (uint16_t *) (void *)feat_config; + /* Variable to define APS status */ + uint8_t aps_stat = 0; - /* Search for wrist gesture feature and extract its configuration details */ - feat_found = bmi2_extract_input_feat_config(&wrist_gest_config, BMI2_WRIST_GESTURE_WH, dev); - if (feat_found) + /* Null-pointer check */ + rslt = null_ptr_check(dev); + if ((rslt == BMI2_OK) && (aux_data != NULL)) { - /* Get the configuration from the page where wrist gesture feature resides */ - rslt = bmi2_get_feat_config(wrist_gest_config.page, feat_config, dev); - if (rslt == BMI2_OK) + /* Validate if manual mode */ + if (dev->aux_man_en) { - /* Define the offset in bytes for gesture select */ - idx = wrist_gest_config.start_addr; - - /* Get offset in words since all the features are set in words length */ - idx = idx / 2; - - /* Set wearable arm */ - *(data_p + idx) = BMI2_SET_BITS(*(data_p + idx), BMI2_WRIST_GEST_WEAR_ARM, config->wearable_arm); - - /* Set output configuration */ - *(data_p + idx) = BMI2_SET_BIT_POS0(*(data_p + idx), BMI2_WRIST_GEST_OUT_CONF, config->out_conf); - - /* Increment offset by 1 more word to set minimum tilt angle (min_flick_peak) */ - idx++; - *(data_p + idx) = config->min_flick_peak; - - /* Increment offset by 1 more word to set min_flick_samples */ - idx++; - *(data_p + idx) = config->min_flick_samples; - - /* Increment offset by 1 more word to set max time within gesture moment has to be completed */ - idx++; - *(data_p + idx) = config->max_duration; - - /* Increment offset by 1 more word to set reporting delay */ - idx++; - *(data_p + idx) = config->reporting_delay; - - /* Increment offset by 1 more word to get the total length in words */ - idx++; - - /* Get total length in bytes to copy from local pointer to the array */ - idx = (uint8_t)(idx * 2) - wrist_gest_config.start_addr; - - /* Copy the bytes to be set back to the array */ - for (index = 0; index < idx; index++) + /* Get status of advance power save mode */ + aps_stat = dev->aps_status; + if (aps_stat == BMI2_ENABLE) { - feat_config[wrist_gest_config.start_addr + - index] = *((uint8_t *) data_p + wrist_gest_config.start_addr + index); + /* Disable APS if enabled */ + rslt = bmi2_set_adv_power_save(BMI2_DISABLE, dev); } - /* Set the configuration back to the page */ - rslt = bmi2_set_regs(BMI2_FEATURES_REG_ADDR, feat_config, BMI2_FEAT_SIZE_IN_BYTES, dev); if (rslt == BMI2_OK) { - /* Copy out_conf value to a local copy in device structure */ - dev->int_map.wrist_gest_out_conf = (uint8_t) config->out_conf; + /* Map the register value set to that of burst + * length + */ + rslt = map_read_len(&burst_len, dev); + if (rslt == BMI2_OK) + { + /* Read auxiliary data */ + rslt = read_aux_data(reg_addr, aux_data, len, burst_len, dev); + } + } + + /* Enable Advance power save if disabled for reading + * data and not when already disabled + */ + if ((rslt == BMI2_OK) && (aps_stat == BMI2_ENABLE)) + { + rslt = bmi2_set_adv_power_save(BMI2_ENABLE, dev); } } + else + { + rslt = BMI2_E_AUX_INVALID_CFG; + } } else { - rslt = BMI2_E_INVALID_SENSOR; + rslt = BMI2_E_NULL_PTR; } return rslt; } /*! - * @brief This internal API sets wrist wear wake-up configurations like - * output-configuration for wearable variant. + * @brief This API writes the user-defined bytes of data and the address of + * auxiliary sensor where data is to be written in manual mode. + * + * @note Change of BMI2_AUX_WR_ADDR is only allowed if AUX is not busy. */ -static int8_t set_wrist_wear_wake_up_wh_config(const struct bmi2_wrist_wear_wake_up_wh_config *config, - struct bmi2_dev *dev) +int8_t bmi2_write_aux_man_mode(uint8_t reg_addr, const uint8_t *aux_data, uint16_t len, struct bmi2_dev *dev) { /* Variable to define error */ int8_t rslt; - /* Array to define the feature configuration */ - uint8_t feat_config[BMI2_FEAT_SIZE_IN_BYTES] = { 0 }; - - /* Variable to define the array offset */ - uint8_t idx = 0; - - /* Variable to define index */ - uint8_t index = 0; - - /* Variable to set flag */ - uint8_t feat_found; - - /* Initialize feature configuration for wrist wear wake-up */ - struct bmi2_feature_config wrist_wake_up_config = { 0, 0, 0 }; + /* Variable to define loop */ + uint8_t loop = 0; - /* Copy the feature configuration address to a local pointer */ - uint16_t *data_p = (uint16_t *) (void *)feat_config; + /* Variable to define APS status */ + uint8_t aps_stat = 0; - /* Search for wrist wear wake-up feature and extract its configuration details */ - feat_found = bmi2_extract_input_feat_config(&wrist_wake_up_config, BMI2_WRIST_WEAR_WAKE_UP_WH, dev); - if (feat_found) + /* Null-pointer check */ + rslt = null_ptr_check(dev); + if ((rslt == BMI2_OK) && (aux_data != NULL)) { - /* Get the configuration from the page where wrist wear wake-up feature resides */ - rslt = bmi2_get_feat_config(wrist_wake_up_config.page, feat_config, dev); - if (rslt == BMI2_OK) + /* Validate if manual mode */ + if (dev->aux_man_en) { - /* Define the offset in bytes for wrist wear wake-up select */ - idx = wrist_wake_up_config.start_addr; - - /* Get offset in words since all the features are set in words length */ - idx = idx / 2; - - /* Set output configuration */ - *(data_p + idx) = BMI2_SET_BIT_POS0(*(data_p + idx), BMI2_WRIST_WAKE_UP_OUT_CONF, config->out_conf); - - /* Increment offset by 1 more word to set min_angle_focus */ - idx++; - *(data_p + idx) = config->min_angle_focus; - - /* Increment offset by 1 more word to set min_angle_nonfocus */ - idx++; - *(data_p + idx) = config->min_angle_nonfocus; - - /* Increment offset by 1 more word to set angle landscape right and angle landscape left */ - idx++; - *(data_p + idx) = BMI2_SET_BIT_POS0(*(data_p + idx), BMI2_WRIST_WAKE_UP_ANGLE_LR, config->angle_lr); - *(data_p + idx) = BMI2_SET_BITS(*(data_p + idx), BMI2_WRIST_WAKE_UP_ANGLE_LL, config->angle_ll); - - /* Increment offset by 1 more word to set angle portrait down and angle portrait left */ - idx++; - *(data_p + idx) = BMI2_SET_BIT_POS0(*(data_p + idx), BMI2_WRIST_WAKE_UP_ANGLE_PD, config->angle_pd); - *(data_p + idx) = BMI2_SET_BITS(*(data_p + idx), BMI2_WRIST_WAKE_UP_ANGLE_PU, config->angle_pu); - - /* Increment offset by 1 more word to set min duration moved and min duration quite */ - idx++; - *(data_p + idx) = BMI2_SET_BIT_POS0(*(data_p + idx), BMI2_WRIST_WAKE_UP_MIN_DUR_MOVED, config->min_dur_mov); - *(data_p + idx) = BMI2_SET_BITS(*(data_p + idx), BMI2_WRIST_WAKE_UP_MIN_DUR_QUITE, config->min_dur_quite); - - /* Increment offset by 1 more word to get the total length in words */ - idx++; - - /* Get total length in bytes to copy from local pointer to the array */ - idx = (uint8_t)(idx * 2) - wrist_wake_up_config.start_addr; - - /* Copy the bytes to be set back to the array */ - for (index = 0; index < idx; index++) + /* Get status of advance power save mode */ + aps_stat = dev->aps_status; + if (aps_stat == BMI2_ENABLE) { - feat_config[wrist_wake_up_config.start_addr + - index] = *((uint8_t *) data_p + wrist_wake_up_config.start_addr + index); + /* Disable APS if enabled */ + rslt = bmi2_set_adv_power_save(BMI2_DISABLE, dev); } - /* Set the configuration back to the page */ - rslt = bmi2_set_regs(BMI2_FEATURES_REG_ADDR, feat_config, BMI2_FEAT_SIZE_IN_BYTES, dev); + /* Byte write data in the corresponding address */ if (rslt == BMI2_OK) { - /* Copy out_conf value to a local copy in device structure */ - dev->int_map.wrist_wear_wake_up_out_conf = (uint8_t) config->out_conf; + for (; ((loop < len) && (rslt == BMI2_OK)); loop++) + { + rslt = write_aux_data((reg_addr + loop), aux_data[loop], dev); + dev->delay_us(1000, dev->intf_ptr); + } + } + + /* Enable Advance power save if disabled for writing + * data and not when already disabled + */ + if ((rslt == BMI2_OK) && (aps_stat == BMI2_ENABLE)) + { + rslt = bmi2_set_adv_power_save(BMI2_ENABLE, dev); } } + else + { + rslt = BMI2_E_AUX_INVALID_CFG; + } } else { - rslt = BMI2_E_INVALID_SENSOR; + rslt = BMI2_E_NULL_PTR; } return rslt; } /*! - * @brief This internal API gets accelerometer configurations like ODR, - * bandwidth, performance mode and g-range. + * @brief This API writes the user-defined bytes of data and the address of + * auxiliary sensor where data is to be written, from an interleaved input, + * in manual mode. + * + * @note Change of BMI2_AUX_WR_ADDR is only allowed if AUX is not busy. */ -static int8_t get_accel_config(struct bmi2_accel_config *config, struct bmi2_dev *dev) +int8_t bmi2_write_aux_interleaved(uint8_t reg_addr, const uint8_t *aux_data, uint16_t len, struct bmi2_dev *dev) { /* Variable to define error */ int8_t rslt; - /* Array to store data */ - uint8_t data_array[2] = { 0 }; + /* Variable to define loop */ + uint8_t loop = 1; + + /* Variable to define APS status */ + uint8_t aps_stat = 0; /* Null-pointer check */ rslt = null_ptr_check(dev); - if ((rslt == BMI2_OK) && (config != NULL)) + if ((rslt == BMI2_OK) && (aux_data != NULL)) { - /* Read the sensor configuration details */ - rslt = bmi2_get_regs(BMI2_ACC_CONF_ADDR, data_array, 2, dev); - if (rslt == BMI2_OK) + /* Validate if manual mode */ + if (dev->aux_man_en) { - /* Get accelerometer performance mode */ - config->filter_perf = BMI2_GET_BITS(data_array[0], BMI2_ACC_FILTER_PERF_MODE); + /* Get status of advance power save mode */ + aps_stat = dev->aps_status; + if (aps_stat == BMI2_ENABLE) + { + /* Disable APS if enabled */ + rslt = bmi2_set_adv_power_save(BMI2_DISABLE, dev); + } - /* Get accelerometer bandwidth */ - config->bwp = BMI2_GET_BITS(data_array[0], BMI2_ACC_BW_PARAM); + if (rslt == BMI2_OK) + { + /* Write the start register address extracted + * from the interleaved data + */ + rslt = write_aux_data(reg_addr, aux_data[0], dev); - /* Get accelerometer ODR */ - config->odr = BMI2_GET_BIT_POS0(data_array[0], BMI2_ACC_ODR); + /* Extract the remaining address and data from + * the interleaved data and write it in the + * corresponding addresses byte by byte + */ + for (; ((loop < len) && (rslt == BMI2_OK)); loop += 2) + { + rslt = write_aux_data(aux_data[loop], aux_data[loop + 1], dev); + dev->delay_us(1000, dev->intf_ptr); + } - /* Get accelerometer range */ - config->range = BMI2_GET_BIT_POS0(data_array[1], BMI2_ACC_RANGE); + /* Enable Advance power save if disabled for + * writing data and not when already disabled + */ + if ((rslt == BMI2_OK) && (aps_stat == BMI2_ENABLE)) + { + rslt = bmi2_set_adv_power_save(BMI2_ENABLE, dev); + } + } + } + else + { + rslt = BMI2_E_AUX_INVALID_CFG; } } else @@ -12667,43 +3583,19 @@ static int8_t get_accel_config(struct bmi2_accel_config *config, struct bmi2_dev } /*! - * @brief This internal API gets gyroscope configurations like ODR, bandwidth, - * low power/high performance mode, performance mode and range. + * @brief This API gets the data ready status of accelerometer, gyroscope, + * auxiliary, command decoder and busy status of auxiliary. */ -static int8_t get_gyro_config(struct bmi2_gyro_config *config, struct bmi2_dev *dev) +int8_t bmi2_get_status(uint8_t *status, struct bmi2_dev *dev) { /* Variable to define error */ int8_t rslt; - /* Array to store data */ - uint8_t data_array[2] = { 0 }; - /* Null-pointer check */ rslt = null_ptr_check(dev); - if ((rslt == BMI2_OK) && (config != NULL)) + if ((rslt == BMI2_OK) && (status != NULL)) { - /* Read the sensor configuration details */ - rslt = bmi2_get_regs(BMI2_GYR_CONF_ADDR, data_array, 2, dev); - if (rslt == BMI2_OK) - { - /* Get gyroscope performance mode */ - config->filter_perf = BMI2_GET_BITS(data_array[0], BMI2_GYR_FILTER_PERF_MODE); - - /* Get gyroscope noise performance mode */ - config->noise_perf = BMI2_GET_BITS(data_array[0], BMI2_GYR_NOISE_PERF_MODE); - - /* Get gyroscope bandwidth */ - config->bwp = BMI2_GET_BITS(data_array[0], BMI2_GYR_BW_PARAM); - - /* Get gyroscope ODR */ - config->odr = BMI2_GET_BIT_POS0(data_array[0], BMI2_GYR_ODR); - - /* Get gyroscope OIS range */ - config->ois_range = BMI2_GET_BITS(data_array[1], BMI2_GYR_OIS_RANGE); - - /* Get gyroscope range */ - config->range = BMI2_GET_BIT_POS0(data_array[1], BMI2_GYR_RANGE); - } + rslt = bmi2_get_regs(BMI2_STATUS_ADDR, status, 1, dev); } else { @@ -12714,35 +3606,54 @@ static int8_t get_gyro_config(struct bmi2_gyro_config *config, struct bmi2_dev * } /*! - * @brief This internal API: - * 1) Gets the status of auxiliary interface enable. - * 2) Gets auxiliary interface configurations like I2C address, manual/auto - * mode enable, manual burst read length, AUX burst read length and AUX read - * address. - * 3) Gets ODR and offset. + * @brief This API enables/disables OIS interface. */ -static int8_t get_aux_config(struct bmi2_aux_config *config, struct bmi2_dev *dev) +int8_t bmi2_set_ois_interface(uint8_t enable, struct bmi2_dev *dev) { /* Variable to define error */ int8_t rslt; + /* Variable to store data */ + uint8_t reg_data = 0; + /* Null-pointer check */ rslt = null_ptr_check(dev); - if ((rslt == BMI2_OK) && (config != NULL)) + if (rslt == BMI2_OK) { - /* Get enable status of auxiliary interface */ - rslt = get_aux_interface(config, dev); + rslt = bmi2_get_regs(BMI2_IF_CONF_ADDR, ®_data, 1, dev); if (rslt == BMI2_OK) { - /* Get the auxiliary interface configurations */ - rslt = get_aux_interface_config(config, dev); - if (rslt == BMI2_OK) + /* Enable/Disable OIS interface */ + reg_data = BMI2_SET_BITS(reg_data, BMI2_OIS_IF_EN, enable); + if (enable) { - /* Get read out offset and ODR */ - rslt = get_aux_cfg(config, dev); + /* Disable auxiliary interface if OIS is enabled */ + reg_data = BMI2_SET_BIT_VAL0(reg_data, BMI2_AUX_IF_EN); } + + /* Set the OIS interface configurations */ + rslt = bmi2_set_regs(BMI2_IF_CONF_ADDR, ®_data, 1, dev); } } + + return rslt; +} + +/*! + * @brief This API can be used to write sync commands like ODR, sync period, + * frequency and phase, resolution ratio, sync time and delay time. + */ +int8_t bmi2_write_sync_commands(const uint8_t *command, uint8_t n_comm, struct bmi2_dev *dev) +{ + /* Variable to define error */ + int8_t rslt; + + /* Null-pointer check */ + rslt = null_ptr_check(dev); + if ((rslt == BMI2_OK) && (command != NULL)) + { + rslt = bmi2_set_regs(BMI2_SYNC_COMMAND_ADDR, command, n_comm, dev); + } else { rslt = BMI2_E_NULL_PTR; @@ -12752,2070 +3663,1912 @@ static int8_t get_aux_config(struct bmi2_aux_config *config, struct bmi2_dev *de } /*! - * @brief This internal API gets the enable status of auxiliary interface. + * @brief This API performs self-test to check the proper functionality of the + * accelerometer sensor. */ -static int8_t get_aux_interface(struct bmi2_aux_config *config, struct bmi2_dev *dev) +int8_t bmi2_perform_accel_self_test(struct bmi2_dev *dev) { /* Variable to define error */ int8_t rslt; - /* Variable to store data */ - uint8_t reg_data; + /* Variable to store self-test result */ + int8_t st_rslt = 0; - /* Get the enable status of auxiliary interface */ - rslt = bmi2_get_regs(BMI2_IF_CONF_ADDR, ®_data, 1, dev); - if (rslt == BMI2_OK) - { - config->aux_en = BMI2_GET_BITS(reg_data, BMI2_AUX_IF_EN); - } + /* Structure to define positive accelerometer axes */ + struct bmi2_sens_axes_data positive = { 0, 0, 0, 0 }; - return rslt; -} + /* Structure to define negative accelerometer axes */ + struct bmi2_sens_axes_data negative = { 0, 0, 0, 0 }; -/*! - * @brief This internal API gets auxiliary configurations like manual/auto mode - * FCU write command enable and read burst length for both data and manual mode. - */ -static int8_t get_aux_interface_config(struct bmi2_aux_config *config, struct bmi2_dev *dev) -{ - /* Variable to define error */ - int8_t rslt; + /* Structure for difference of accelerometer values in g */ + struct bmi2_selftest_delta_limit accel_data_diff = { 0, 0, 0 }; - /* Variable to store data */ - uint8_t reg_data[2] = { 0 }; + /* Structure for difference of accelerometer values in mg */ + struct bmi2_selftest_delta_limit accel_data_diff_mg = { 0, 0, 0 }; - rslt = bmi2_get_regs(BMI2_AUX_DEV_ID_ADDR, reg_data, 2, dev); + /* Initialize the polarity of self-test as positive */ + int8_t sign = BMI2_ENABLE; + + /* Null-pointer check */ + rslt = null_ptr_check(dev); if (rslt == BMI2_OK) { - /* Get I2C address for auxiliary sensor */ - config->i2c_device_addr = BMI2_GET_BITS(reg_data[0], BMI2_AUX_SET_I2C_ADDR); - - /* Get the AUX IF to either manual or auto mode */ - config->manual_en = BMI2_GET_BITS(reg_data[1], BMI2_AUX_MAN_MODE_EN); - - /* Enables FCU write command on AUX IF for auxiliary sensors that need a trigger */ - config->fcu_write_en = BMI2_GET_BITS(reg_data[1], BMI2_AUX_FCU_WR_EN); + /* Sets the configuration required before enabling self-test */ + rslt = pre_self_test_config(dev); - /* Get the burst read length for manual mode */ - config->man_rd_burst = BMI2_GET_BITS(reg_data[1], BMI2_AUX_MAN_READ_BURST); + /* Wait for greater than 2 milliseconds */ + dev->delay_us(3000, dev->intf_ptr); + if (rslt == BMI2_OK) + { + do + { + /* Select positive first, then negative polarity + * after enabling self-test + */ + rslt = self_test_config((uint8_t) sign, dev); + if (rslt == BMI2_OK) + { + /* Wait for greater than 50 milli-sec */ + dev->delay_us(51000, dev->intf_ptr); - /* Get the burst read length for data mode */ - config->aux_rd_burst = BMI2_GET_BIT_POS0(reg_data[1], BMI2_AUX_READ_BURST); + /* If polarity is positive */ + if (sign == BMI2_ENABLE) + { + /* Read and store positive acceleration value */ + rslt = read_accel_xyz(&positive, dev); + } + /* If polarity is negative */ + else if (sign == BMI2_DISABLE) + { + /* Read and store negative acceleration value */ + rslt = read_accel_xyz(&negative, dev); + } + } + else + { + /* Break if error */ + break; + } - /* If data mode, get the read address of the auxiliary sensor from where data is to be read */ - if (!config->manual_en) - { - rslt = bmi2_get_regs(BMI2_AUX_RD_ADDR, &config->read_addr, 1, dev); - } - } + /* Break if error */ + if (rslt != BMI2_OK) + { + break; + } - return rslt; -} + /* Turn the polarity of self-test negative */ + sign--; + } while (sign >= 0); + if (rslt == BMI2_OK) + { + /* Subtract -ve acceleration values from that of +ve values */ + accel_data_diff.x = (positive.x) - (negative.x); + accel_data_diff.y = (positive.y) - (negative.y); + accel_data_diff.z = (positive.z) - (negative.z); -/*! - * @brief This internal API gets read out offset and ODR of the auxiliary - * sensor. - */ -static int8_t get_aux_cfg(struct bmi2_aux_config *config, struct bmi2_dev *dev) -{ - /* Variable to define error */ - int8_t rslt; + /* Convert differences of acceleration values + * from 'g' to 'mg' + */ + convert_lsb_g(&accel_data_diff, &accel_data_diff_mg, dev); - /* Variable to store data */ - uint8_t reg_data; + /* Validate self-test for acceleration values + * in mg and get the self-test result + */ + st_rslt = validate_self_test(&accel_data_diff_mg); - rslt = bmi2_get_regs(BMI2_AUX_CONF_ADDR, ®_data, 1, dev); - if (rslt == BMI2_OK) - { - /* Get read out offset */ - config->offset = BMI2_GET_BITS(reg_data, BMI2_AUX_OFFSET_READ_OUT); + /* Trigger a soft reset after performing self-test */ + rslt = bmi2_soft_reset(dev); - /* Get ODR */ - config->odr = BMI2_GET_BIT_POS0(reg_data, BMI2_AUX_ODR_EN); + /* Return the self-test result */ + if (rslt == BMI2_OK) + { + rslt = st_rslt; + } + } + } } return rslt; } /*! - * @brief This internal API gets any-motion configurations like axes select, - * duration, threshold and output-configuration. + * @brief This API maps/unmaps feature interrupts to that of interrupt pins. */ -static int8_t get_any_motion_config(struct bmi2_any_motion_config *config, struct bmi2_dev *dev) +int8_t bmi2_map_feat_int(uint8_t type, enum bmi2_hw_int_pin hw_int_pin, struct bmi2_dev *dev) { /* Variable to define error */ int8_t rslt; - /* Array to define the feature configuration */ - uint8_t feat_config[BMI2_FEAT_SIZE_IN_BYTES] = { 0 }; - - /* Variable to define the array offset */ - uint8_t idx = 0; - - /* Variable to define LSB */ - uint16_t lsb; - - /* Variable to define MSB */ - uint16_t msb; - - /* Variable to define a word */ - uint16_t lsb_msb; + /* Variable to define the value of feature interrupts */ + uint8_t feat_int = 0; - /* Variable to set flag */ - uint8_t feat_found; + /* Array to store the interrupt mask bits */ + uint8_t data_array[2] = { 0 }; - /* Initialize feature configuration for any-motion */ - struct bmi2_feature_config any_mot_config = { 0, 0, 0 }; + /* Structure to define map the interrupts */ + struct bmi2_map_int map_int = { 0 }; - /* Search for any-motion feature and extract its configuration details */ - feat_found = bmi2_extract_input_feat_config(&any_mot_config, BMI2_ANY_MOTION, dev); - if (feat_found) + /* Null-pointer check */ + rslt = null_ptr_check(dev); + if (rslt == BMI2_OK) { - /* Get the configuration from the page where any-motion feature resides */ - rslt = bmi2_get_feat_config(any_mot_config.page, feat_config, dev); + /* Read interrupt map1 and map2 and register */ + rslt = bmi2_get_regs(BMI2_INT1_MAP_FEAT_ADDR, data_array, 2, dev); + if (rslt == BMI2_OK) { - /* Define the offset for feature enable for any-motion */ - idx = any_mot_config.start_addr; - - /* Get word to calculate duration, x, y and z select */ - lsb = (uint16_t) feat_config[idx++]; - msb = ((uint16_t) feat_config[idx++] << 8); - lsb_msb = lsb | msb; - - /* Get duration */ - config->duration = lsb_msb & BMI2_ANY_NO_MOT_DUR_MASK; - - /* Get x-select */ - config->select_x = (lsb_msb & BMI2_ANY_NO_MOT_X_SEL_MASK) >> BMI2_ANY_NO_MOT_X_SEL_POS; - - /* Get y-select */ - config->select_y = (lsb_msb & BMI2_ANY_NO_MOT_Y_SEL_MASK) >> BMI2_ANY_NO_MOT_Y_SEL_POS; + /* Get the value of the feature interrupt to be mapped */ + extract_feat_int_map(&map_int, type, dev); - /* Get z-select */ - config->select_z = (lsb_msb & BMI2_ANY_NO_MOT_Z_SEL_MASK) >> BMI2_ANY_NO_MOT_Z_SEL_POS; + feat_int = map_int.sens_map_int; - /* Get word to calculate threshold, output configuration from the same word */ - lsb = (uint16_t) feat_config[idx++]; - msb = ((uint16_t) feat_config[idx++] << 8); - lsb_msb = lsb | msb; - - /* Get threshold */ - config->threshold = lsb_msb & BMI2_ANY_NO_MOT_THRES_MASK; + /* Map the interrupts */ + rslt = map_feat_int(data_array, hw_int_pin, feat_int); - /* Get output configuration */ - config->out_conf = (lsb_msb & BMI2_ANY_NO_MOT_OUT_CONF_MASK) >> BMI2_ANY_NO_MOT_OUT_CONF_POS; - - /* Copy out_conf value to a local copy in device structure */ - dev->int_map.any_mot_out_conf = (uint8_t) config->out_conf; + /* Map the interrupts to INT1 and INT2 map register */ + if (rslt == BMI2_OK) + { + rslt = bmi2_set_regs(BMI2_INT1_MAP_FEAT_ADDR, &data_array[0], 1, dev); + if (rslt == BMI2_OK) + { + rslt = bmi2_set_regs(BMI2_INT2_MAP_FEAT_ADDR, &data_array[1], 1, dev); + } + } } } else { - rslt = BMI2_E_INVALID_SENSOR; + rslt = BMI2_E_NULL_PTR; } return rslt; } /*! - * @brief This internal API gets no-motion configurations like axes select, - * duration, threshold and output-configuration. + * @brief This API maps/un-maps data interrupts to that of interrupt pins. */ -static int8_t get_no_motion_config(struct bmi2_no_motion_config *config, struct bmi2_dev *dev) +int8_t bmi2_map_data_int(uint8_t data_int, enum bmi2_hw_int_pin int_pin, struct bmi2_dev *dev) { /* Variable to define error */ int8_t rslt; - /* Array to define the feature configuration */ - uint8_t feat_config[BMI2_FEAT_SIZE_IN_BYTES] = { 0 }; - - /* Variable to define the array offset */ - uint8_t idx = 0; - - /* Variable to define LSB */ - uint16_t lsb = 0; - - /* Variable to define MSB */ - uint16_t msb = 0; - - /* Variable to define a word */ - uint16_t lsb_msb = 0; + /* Variable to mask interrupt pin 1 - lower nibble */ + uint8_t int1_mask = data_int; - /* Variable to set flag */ - uint8_t feat_found; + /* Variable to mask interrupt pin 2 - higher nibble */ + uint8_t int2_mask = (uint8_t)(data_int << 4); - /* Initialize feature configuration for no-motion */ - struct bmi2_feature_config no_mot_config = { 0, 0, 0 }; + /* Variable to store register data */ + uint8_t reg_data = 0; - /* Search for no-motion feature and extract its configuration details */ - feat_found = bmi2_extract_input_feat_config(&no_mot_config, BMI2_NO_MOTION, dev); - if (feat_found) + /* Read interrupt map1 and map2 and register */ + rslt = bmi2_get_regs(BMI2_INT_MAP_DATA_ADDR, ®_data, 1, dev); + if (rslt == BMI2_OK) { - /* Get the configuration from the page where no-motion feature resides */ - rslt = bmi2_get_feat_config(no_mot_config.page, feat_config, dev); - if (rslt == BMI2_OK) + if (int_pin < BMI2_INT_PIN_MAX) { - /* Define the offset for feature enable for no-motion */ - idx = no_mot_config.start_addr; - - /* Get word to calculate duration, x, y and z select */ - lsb = (uint16_t) feat_config[idx++]; - msb = ((uint16_t) feat_config[idx++] << 8); - lsb_msb = lsb | msb; - - /* Get duration */ - config->duration = lsb_msb & BMI2_ANY_NO_MOT_DUR_MASK; - - /* Get x-select */ - config->select_x = (lsb_msb & BMI2_ANY_NO_MOT_X_SEL_MASK) >> BMI2_ANY_NO_MOT_X_SEL_POS; - - /* Get y-select */ - config->select_y = (lsb_msb & BMI2_ANY_NO_MOT_Y_SEL_MASK) >> BMI2_ANY_NO_MOT_Y_SEL_POS; + switch (int_pin) + { + case BMI2_INT_NONE: - /* Get z-select */ - config->select_z = (lsb_msb & BMI2_ANY_NO_MOT_Z_SEL_MASK) >> BMI2_ANY_NO_MOT_Z_SEL_POS; + /* Un-Map the corresponding data + * interrupt to both interrupt pin 1 and 2 + */ + reg_data &= ~(int1_mask | int2_mask); + break; + case BMI2_INT1: - /* Get word to calculate threshold, output configuration from the same word */ - lsb = (uint16_t) feat_config[idx++]; - msb = ((uint16_t) feat_config[idx++] << 8); - lsb_msb = lsb | msb; + /* Map the corresponding data interrupt to + * interrupt pin 1 + */ + reg_data |= int1_mask; + break; + case BMI2_INT2: - /* Get threshold */ - config->threshold = lsb_msb & BMI2_ANY_NO_MOT_THRES_MASK; + /* Map the corresponding data interrupt to + * interrupt pin 2 + */ + reg_data |= int2_mask; + break; + case BMI2_INT_BOTH: - /* Get output configuration */ - config->out_conf = (lsb_msb & BMI2_ANY_NO_MOT_OUT_CONF_MASK) >> BMI2_ANY_NO_MOT_OUT_CONF_POS; + /* Map the corresponding data + * interrupt to both interrupt pin 1 and 2 + */ + reg_data |= (int1_mask | int2_mask); + break; + default: + break; + } - /* Copy out_conf value to a local copy in device structure */ - dev->int_map.no_mot_out_conf = (uint8_t) config->out_conf; + /* Set the interrupts in the map register */ + rslt = bmi2_set_regs(BMI2_INT_MAP_DATA_ADDR, ®_data, 1, dev); + } + else + { + /* Return error if invalid pin selection */ + rslt = BMI2_E_INVALID_INT_PIN; } - } - else - { - rslt = BMI2_E_INVALID_SENSOR; } return rslt; } /*! - * @brief This internal API gets sig-motion configurations like block-size, - * output-configuration and other parameters. + * @brief This API gets the re-mapped x, y and z axes from the sensor and + * updates the values in the device structure. */ -static int8_t get_sig_motion_config(struct bmi2_sig_motion_config *config, struct bmi2_dev *dev) +int8_t bmi2_get_remap_axes(struct bmi2_remap *remapped_axis, struct bmi2_dev *dev) { /* Variable to define error */ int8_t rslt; - /* Array to define the feature configuration */ - uint8_t feat_config[BMI2_FEAT_SIZE_IN_BYTES] = { 0 }; - - /* Variable to define the array offset */ - uint8_t idx = 0; - - /* Variable to define LSB */ - uint16_t lsb = 0; - - /* Variable to define MSB */ - uint16_t msb = 0; - - /* Variable to define a word */ - uint16_t lsb_msb = 0; - - /* Variable to set flag */ - uint8_t feat_found; - - /* Initialize feature configuration sig-motion */ - struct bmi2_feature_config sig_mot_config = { 0, 0, 0 }; + /* Initialize the local structure for axis re-mapping */ + struct bmi2_axes_remap remap = { 0, 0, 0, 0, 0, 0 }; - /* Search for sig-motion feature and extract its configuration details */ - feat_found = bmi2_extract_input_feat_config(&sig_mot_config, BMI2_SIG_MOTION, dev); - if (feat_found) + /* Null-pointer check */ + rslt = null_ptr_check(dev); + if ((rslt == BMI2_OK) && (remapped_axis != NULL)) { - /* Get the configuration from the page where sig-motion feature resides */ - rslt = bmi2_get_feat_config(sig_mot_config.page, feat_config, dev); + /* Get the re-mapped axes from the sensor */ + rslt = get_remap_axes(&remap, dev); if (rslt == BMI2_OK) { - /* Define the offset for feature enable for sig-motion */ - idx = sig_mot_config.start_addr; + /* Store the re-mapped x-axis value in device structure + * and its user-value in the interface structure + */ + switch (remap.x_axis) + { + case BMI2_MAP_X_AXIS: - /* Get word to calculate parameter 1 */ - lsb = (uint16_t) feat_config[idx++]; - msb = ((uint16_t) feat_config[idx++] << 8); - lsb_msb = lsb | msb; + /* If mapped to x-axis */ + dev->remap.x_axis = BMI2_MAP_X_AXIS; + remapped_axis->x = BMI2_X; + break; + case BMI2_MAP_Y_AXIS: - /* Get parameter 1 */ - config->block_size = lsb_msb & BMI2_SIG_MOT_PARAM_1_MASK; + /* If mapped to y-axis */ + dev->remap.x_axis = BMI2_MAP_Y_AXIS; + remapped_axis->x = BMI2_Y; + break; + case BMI2_MAP_Z_AXIS: - /* Get word to calculate parameter 2 */ - lsb = (uint16_t) feat_config[idx++]; - msb = ((uint16_t) feat_config[idx++] << 8); - lsb_msb = lsb | msb; + /* If mapped to z-axis */ + dev->remap.x_axis = BMI2_MAP_Z_AXIS; + remapped_axis->x = BMI2_Z; + break; + default: + break; + } - /* Get parameter 2 */ - config->param_2 = lsb_msb & BMI2_SIG_MOT_PARAM_2_MASK; + /* Store the re-mapped x-axis sign in device structure + * and its user-value in the interface structure + */ + if (remap.x_axis_sign) + { + /* If x-axis is mapped to -ve sign */ + dev->remap.x_axis_sign = BMI2_NEG_SIGN; + remapped_axis->x |= BMI2_AXIS_SIGN; + } + else + { + dev->remap.x_axis_sign = BMI2_POS_SIGN; + } - /* Get word to calculate parameter 3 */ - lsb = (uint16_t) feat_config[idx++]; - msb = ((uint16_t) feat_config[idx++] << 8); - lsb_msb = lsb | msb; + /* Store the re-mapped y-axis value in device structure + * and its user-value in the interface structure + */ + switch (remap.y_axis) + { + case BMI2_MAP_X_AXIS: - /* Get parameter 3 */ - config->param_3 = lsb_msb & BMI2_SIG_MOT_PARAM_3_MASK; + /* If mapped to x-axis */ + dev->remap.y_axis = BMI2_MAP_X_AXIS; + remapped_axis->y = BMI2_X; + break; + case BMI2_MAP_Y_AXIS: - /* Get word to calculate parameter 4 */ - lsb = (uint16_t) feat_config[idx++]; - msb = ((uint16_t) feat_config[idx++] << 8); - lsb_msb = lsb | msb; + /* If mapped to y-axis */ + dev->remap.y_axis = BMI2_MAP_Y_AXIS; + remapped_axis->y = BMI2_Y; + break; + case BMI2_MAP_Z_AXIS: - /* Get parameter 4 */ - config->param_4 = lsb_msb & BMI2_SIG_MOT_PARAM_4_MASK; + /* If mapped to z-axis */ + dev->remap.y_axis = BMI2_MAP_Z_AXIS; + remapped_axis->y = BMI2_Z; + break; + default: + break; + } - /* Get word to calculate parameter 5 */ - lsb = (uint16_t) feat_config[idx++]; - msb = ((uint16_t) feat_config[idx++] << 8); - lsb_msb = lsb | msb; + /* Store the re-mapped y-axis sign in device structure + * and its user-value in the interface structure + */ + if (remap.y_axis_sign) + { + /* If y-axis is mapped to -ve sign */ + dev->remap.y_axis_sign = BMI2_NEG_SIGN; + remapped_axis->y |= BMI2_AXIS_SIGN; + } + else + { + dev->remap.y_axis_sign = BMI2_POS_SIGN; + } - /* Get parameter 5 */ - config->param_5 = lsb_msb & BMI2_SIG_MOT_PARAM_5_MASK; + /* Store the re-mapped z-axis value in device structure + * and its user-value in the interface structure + */ + switch (remap.z_axis) + { + case BMI2_MAP_X_AXIS: - /* Get word to calculate and output configuration */ - lsb = (uint16_t) feat_config[idx++]; - msb = ((uint16_t) feat_config[idx++] << 8); - lsb_msb = lsb | msb; + /* If mapped to x-axis */ + dev->remap.z_axis = BMI2_MAP_X_AXIS; + remapped_axis->z = BMI2_X; + break; + case BMI2_MAP_Y_AXIS: - /* Get output configuration */ - config->out_conf = (lsb_msb & BMI2_SIG_MOT_OUT_CONF_MASK) >> BMI2_SIG_MOT_OUT_CONF_POS; + /* If mapped to y-axis */ + dev->remap.z_axis = BMI2_MAP_Y_AXIS; + remapped_axis->z = BMI2_Y; + break; + case BMI2_MAP_Z_AXIS: + + /* If mapped to z-axis */ + dev->remap.z_axis = BMI2_MAP_Z_AXIS; + remapped_axis->z = BMI2_Z; + break; + default: + break; + } - /* Copy out_conf value to a local copy in device structure */ - dev->int_map.sig_mot_out_conf = (uint8_t) config->out_conf; + /* Store the re-mapped z-axis sign in device structure + * and its user-value in the interface structure + */ + if (remap.z_axis_sign) + { + /* If z-axis is mapped to -ve sign */ + dev->remap.z_axis_sign = BMI2_NEG_SIGN; + remapped_axis->z |= BMI2_AXIS_SIGN; + } + else + { + dev->remap.z_axis_sign = BMI2_POS_SIGN; + } } } else { - rslt = BMI2_E_INVALID_SENSOR; + rslt = BMI2_E_NULL_PTR; } return rslt; } /*! - * @brief This internal API gets step counter parameter configurations. + * @brief This API sets the re-mapped x, y and z axes to the sensor and + * updates the them in the device structure. */ -static int8_t get_step_count_params_config(uint16_t *step_count_params, struct bmi2_dev *dev) +int8_t bmi2_set_remap_axes(const struct bmi2_remap *remapped_axis, struct bmi2_dev *dev) { /* Variable to define error */ - int8_t rslt = BMI2_OK; - - /* Array to define the feature configuration */ - uint8_t feat_config[BMI2_FEAT_SIZE_IN_BYTES] = { 0 }; - - /* Variable to set flag */ - uint8_t feat_found; - - /* Variable to define LSB */ - uint16_t lsb = 0; + int8_t rslt; - /* Variable to define MSB */ - uint16_t msb = 0; + /* Variable to store all the re-mapped axes */ + uint8_t remap_axes = 0; - /* Variable to define a word */ - uint16_t lsb_msb = 0; + /* Variable to store the re-mapped x-axes */ + uint8_t remap_x = 0; - /* Initialize feature configuration for step counter 1 */ - struct bmi2_feature_config step_params_config = { 0, 0, 0 }; + /* Variable to store the re-mapped y-axes */ + uint8_t remap_y = 0; - /* Variable to index the page number */ - uint8_t page_idx; + /* Variable to store the re-mapped z-axes */ + uint8_t remap_z = 0; - /* Variable to define the start page */ - uint8_t start_page; + /* Initialize the local structure for axis re-mapping */ + struct bmi2_axes_remap remap = { 0, 0, 0, 0, 0, 0 }; - /* Variable to define start address of the parameters */ - uint8_t start_addr; + /* Null-pointer check */ + rslt = null_ptr_check(dev); + if ((rslt == BMI2_OK) && (remapped_axis != NULL)) + { + /* Check whether all the axes are re-mapped */ + remap_axes = remapped_axis->x | remapped_axis->y | remapped_axis->z; - /* Variable to define number of bytes */ - uint8_t n_bytes = (BMI2_STEP_CNT_N_PARAMS * 2); + /* If all the axes are re-mapped */ + if ((remap_axes & BMI2_AXIS_MASK) == BMI2_AXIS_MASK) + { + /* Get the re-mapped value of x, y and z axis */ + remap_x = remapped_axis->x & BMI2_AXIS_MASK; + remap_y = remapped_axis->y & BMI2_AXIS_MASK; + remap_z = remapped_axis->z & BMI2_AXIS_MASK; - /* Variable to store number of pages */ - uint8_t n_pages = (n_bytes / 16); + /* Store the value of re-mapped x-axis in both + * device structure and the local structure + */ + switch (remap_x) + { + case BMI2_X: - /* Variable to define the end page */ - uint8_t end_page; + /* If mapped to x-axis */ + dev->remap.x_axis = BMI2_MAP_X_AXIS; + remap.x_axis = BMI2_MAP_X_AXIS; + break; + case BMI2_Y: - /* Variable to define the remaining bytes to be read */ - uint8_t remain_len; + /* If mapped to y-axis */ + dev->remap.x_axis = BMI2_MAP_Y_AXIS; + remap.x_axis = BMI2_MAP_Y_AXIS; + break; + case BMI2_Z: - /* Variable to define the maximum words to be read in a page */ - uint8_t max_len = BMI2_FEAT_SIZE_IN_BYTES; + /* If mapped to z-axis */ + dev->remap.x_axis = BMI2_MAP_Z_AXIS; + remap.x_axis = BMI2_MAP_Z_AXIS; + break; + default: + break; + } - /* Variable index bytes in a page */ - uint8_t page_byte_idx; + /* Store the re-mapped x-axis sign in the device + * structure and its value in local structure + */ + if (remapped_axis->x & BMI2_AXIS_SIGN) + { + /* If x-axis is mapped to -ve sign */ + dev->remap.x_axis_sign = BMI2_NEG_SIGN; + remap.x_axis_sign = BMI2_MAP_NEGATIVE; + } + else + { + dev->remap.x_axis_sign = BMI2_POS_SIGN; + remap.x_axis_sign = BMI2_MAP_POSITIVE; + } - /* Variable to index the parameters */ - uint8_t param_idx = 0; + /* Store the value of re-mapped y-axis in both + * device structure and the local structure + */ + switch (remap_y) + { + case BMI2_X: - /* Search for step counter parameter feature and extract its configuration details */ - feat_found = bmi2_extract_input_feat_config(&step_params_config, BMI2_STEP_COUNTER_PARAMS, dev); - if (feat_found) - { - /* Get the start page for the step counter parameters */ - start_page = step_params_config.page; + /* If mapped to x-axis */ + dev->remap.y_axis = BMI2_MAP_X_AXIS; + remap.y_axis = BMI2_MAP_X_AXIS; + break; + case BMI2_Y: - /* Get the end page for the step counter parameters */ - end_page = start_page + n_pages; + /* If mapped to y-axis */ + dev->remap.y_axis = BMI2_MAP_Y_AXIS; + remap.y_axis = BMI2_MAP_Y_AXIS; + break; + case BMI2_Z: - /* Get the start address for the step counter parameters */ - start_addr = step_params_config.start_addr; + /* If mapped to z-axis */ + dev->remap.y_axis = BMI2_MAP_Z_AXIS; + remap.y_axis = BMI2_MAP_Z_AXIS; + break; + default: + break; + } - /* Get the remaining length of bytes to be read */ - remain_len = (uint8_t)((n_bytes - (n_pages * 16)) + start_addr); - for (page_idx = start_page; page_idx <= end_page; page_idx++) - { - /* Get the configuration from the respective page */ - rslt = bmi2_get_feat_config(page_idx, feat_config, dev); - if (rslt == BMI2_OK) + /* Store the re-mapped y-axis sign in the device + * structure and its value in local structure + */ + if (remapped_axis->y & BMI2_AXIS_SIGN) { - /* Start from address 0x00 when switched to next page */ - if (page_idx > start_page) - { - start_addr = 0; - } + /* If y-axis is mapped to -ve sign */ + dev->remap.y_axis_sign = BMI2_NEG_SIGN; + remap.y_axis_sign = BMI2_MAP_NEGATIVE; + } + else + { + dev->remap.y_axis_sign = BMI2_POS_SIGN; + remap.y_axis_sign = BMI2_MAP_POSITIVE; + } - /* Remaining number of bytes to be read in the page */ - if (page_idx == end_page) - { - max_len = remain_len; - } + /* Store the value of re-mapped z-axis in both + * device structure and the local structure + */ + switch (remap_z) + { + case BMI2_X: - /* Get the offset */ - page_byte_idx = start_addr; - while (page_byte_idx < max_len) - { - /* Get word to calculate the parameter*/ - lsb = (uint16_t) feat_config[page_byte_idx++]; - if (page_byte_idx < max_len) - { - msb = ((uint16_t) feat_config[page_byte_idx++] << 8); - } + /* If mapped to x-axis */ + dev->remap.z_axis = BMI2_MAP_X_AXIS; + remap.z_axis = BMI2_MAP_X_AXIS; + break; + case BMI2_Y: - lsb_msb = lsb | msb; + /* If mapped to y-axis */ + dev->remap.z_axis = BMI2_MAP_Y_AXIS; + remap.z_axis = BMI2_MAP_Y_AXIS; + break; + case BMI2_Z: - /* Get parameters 1 to 25 */ - step_count_params[param_idx] = lsb_msb & BMI2_STEP_COUNT_PARAMS_MASK; + /* If mapped to z-axis */ + dev->remap.z_axis = BMI2_MAP_Z_AXIS; + remap.z_axis = BMI2_MAP_Z_AXIS; + break; + default: + break; + } - /* Increment to next parameter */ - param_idx++; - } + /* Store the re-mapped z-axis sign in the device + * structure and its value in local structure + */ + if (remapped_axis->z & BMI2_AXIS_SIGN) + { + /* If z-axis is mapped to -ve sign */ + dev->remap.z_axis_sign = BMI2_NEG_SIGN; + remap.z_axis_sign = BMI2_MAP_NEGATIVE; + } + else + { + dev->remap.z_axis_sign = BMI2_POS_SIGN; + remap.z_axis_sign = BMI2_MAP_POSITIVE; } + + /* Set the re-mapped axes in the sensor */ + rslt = set_remap_axes(&remap, dev); + } + else + { + rslt = BMI2_E_REMAP_ERROR; } } else { - rslt = BMI2_E_INVALID_SENSOR; + rslt = BMI2_E_NULL_PTR; } return rslt; } /*! - * @brief This internal API gets step counter/detector/activity configurations. + * @brief This API enables/disables gyroscope offset compensation. It adds the + * offsets defined in the offset register with gyroscope data. */ -static int8_t get_step_config(struct bmi2_step_config *config, struct bmi2_dev *dev) +int8_t bmi2_set_gyro_offset_comp(uint8_t enable, struct bmi2_dev *dev) { /* Variable to define error */ int8_t rslt; - /* Array to define the feature configuration */ - uint8_t feat_config[BMI2_FEAT_SIZE_IN_BYTES] = { 0 }; - - /* Variable to define the array offset */ - uint8_t idx = 0; - - /* Variable to define LSB */ - uint16_t lsb = 0; - - /* Variable to define MSB */ - uint16_t msb = 0; - - /* Variable to define a word */ - uint16_t lsb_msb = 0; - - /* Variable to set flag */ - uint8_t feat_found; - - /* Initialize feature configuration for step counter */ - struct bmi2_feature_config step_count_config = { 0, 0, 0 }; + /* Variable to define register data */ + uint8_t reg_data = 0; - /* Search for step counter 4 feature and extract its configuration details */ - feat_found = bmi2_extract_input_feat_config(&step_count_config, BMI2_STEP_COUNTER, dev); - if (feat_found) + /* Null-pointer check */ + rslt = null_ptr_check(dev); + if (rslt == BMI2_OK) { - /* Get the configuration from the page where step counter 4 parameter resides */ - rslt = bmi2_get_feat_config(step_count_config.page, feat_config, dev); + /* Get the status of gyroscope offset enable */ + rslt = bmi2_get_regs(BMI2_GYR_OFF_COMP_6_ADDR, ®_data, 1, dev); if (rslt == BMI2_OK) { - /* Define the offset for feature enable for step counter/detector/activity */ - idx = step_count_config.start_addr; - - /* Get word to calculate water-mark level and reset counter */ - lsb = (uint16_t) feat_config[idx++]; - msb = ((uint16_t) feat_config[idx++] << 8); - lsb_msb = lsb | msb; - - /* Get water-mark level */ - config->watermark_level = lsb_msb & BMI2_STEP_COUNT_WM_LEVEL_MASK; - - /* Get reset counter */ - config->reset_counter = (lsb_msb & BMI2_STEP_COUNT_RST_CNT_MASK) >> BMI2_STEP_COUNT_RST_CNT_POS; - - /* Get word to calculate output configuration of step detector and activity */ - lsb = (uint16_t) feat_config[idx++]; - msb = ((uint16_t) feat_config[idx++] << 8); - lsb_msb = lsb | msb; - - /* Get output configuration of step detector */ - config->out_conf_step_detector = lsb_msb & BMI2_STEP_DET_OUT_CONF_MASK; - - /* Get output configuration of step activity */ - config->out_conf_activity = (lsb_msb & BMI2_STEP_ACT_OUT_CONF_MASK) >> BMI2_STEP_ACT_OUT_CONF_POS; - - /* Get step buffer size */ - config->step_buffer_size = (lsb_msb & BMI2_STEP_BUFFER_SIZE_MASK) >> BMI2_STEP_BUFFER_SIZE_POS; + reg_data = BMI2_SET_BITS(reg_data, BMI2_GYR_OFF_COMP_EN, enable); - /* Copy out_conf value to a local copy in device structure */ - dev->int_map.step_det_out_conf = (uint8_t) config->out_conf_step_detector; - dev->int_map.step_act_out_conf = (uint8_t) config->out_conf_activity; + /* Enable/Disable gyroscope offset compensation */ + rslt = bmi2_set_regs(BMI2_GYR_OFF_COMP_6_ADDR, ®_data, 1, dev); } } else { - rslt = BMI2_E_INVALID_SENSOR; + rslt = BMI2_E_NULL_PTR; } return rslt; } /*! - * @brief This internal API gets gyroscope user-gain configurations like gain - * update value for x, y and z-axis. + * @brief This API reads the gyroscope bias values for each axis which is used + * for gyroscope offset compensation. */ -static int8_t get_gyro_gain_update_config(struct bmi2_gyro_user_gain_config *config, struct bmi2_dev *dev) +int8_t bmi2_read_gyro_offset_comp_axes(struct bmi2_sens_axes_data *gyr_off_comp_axes, struct bmi2_dev *dev) { /* Variable to define error */ int8_t rslt; - /* Array to define the feature configuration */ - uint8_t feat_config[BMI2_FEAT_SIZE_IN_BYTES] = { 0 }; + /* Variable to define register data */ + uint8_t reg_data[4] = { 0 }; - /* Variable to define the array offset */ - uint8_t idx = 0; + /* Variable to store LSB value of offset compensation for x-axis */ + uint8_t gyr_off_lsb_x; - /* Variable to define LSB */ - uint16_t lsb = 0; + /* Variable to store LSB value of offset compensation for y-axis */ + uint8_t gyr_off_lsb_y; - /* Variable to define MSB */ - uint16_t msb = 0; + /* Variable to store LSB value of offset compensation for z-axis */ + uint8_t gyr_off_lsb_z; - /* Variable to define a word */ - uint16_t lsb_msb = 0; + /* Variable to store MSB value of offset compensation for x-axis */ + uint8_t gyr_off_msb_x; - /* Variable to set flag */ - uint8_t feat_found; + /* Variable to store MSB value of offset compensation for y-axis */ + uint8_t gyr_off_msb_y; - /* Initialize feature configuration for user-gain */ - struct bmi2_feature_config user_gain_config = { 0, 0, 0 }; + /* Variable to store MSB value of offset compensation for z-axis */ + uint8_t gyr_off_msb_z; - /* Search for user-gain feature and extract its configuration details */ - feat_found = bmi2_extract_input_feat_config(&user_gain_config, BMI2_GYRO_GAIN_UPDATE, dev); - if (feat_found) + /* Null-pointer check */ + rslt = null_ptr_check(dev); + if ((rslt == BMI2_OK) && (gyr_off_comp_axes != NULL)) { - /* Get the configuration from the page where user-gain feature resides */ - rslt = bmi2_get_feat_config(user_gain_config.page, feat_config, dev); + /* Get the gyroscope compensated offset values */ + rslt = bmi2_get_regs(BMI2_GYR_OFF_COMP_3_ADDR, reg_data, 4, dev); if (rslt == BMI2_OK) { - /* Define the offset in bytes for user-gain select */ - idx = user_gain_config.start_addr; - - /* Get word to calculate ratio_x */ - lsb = (uint16_t) feat_config[idx++]; - msb = ((uint16_t) feat_config[idx++] << 8); - lsb_msb = lsb | msb; - - /* Get ratio_x */ - config->ratio_x = lsb_msb & BMI2_GYR_USER_GAIN_RATIO_X_MASK; - - /* Get word to calculate ratio_y */ - lsb = (uint16_t) feat_config[idx++]; - msb = ((uint16_t) feat_config[idx++] << 8); - lsb_msb = lsb | msb; + /* Get LSB and MSB values of offset compensation for + * x, y and z axis + */ + gyr_off_lsb_x = reg_data[0]; + gyr_off_lsb_y = reg_data[1]; + gyr_off_lsb_z = reg_data[2]; + gyr_off_msb_x = reg_data[3] & BMI2_GYR_OFF_COMP_MSB_X_MASK; + gyr_off_msb_y = reg_data[3] & BMI2_GYR_OFF_COMP_MSB_Y_MASK; + gyr_off_msb_z = reg_data[3] & BMI2_GYR_OFF_COMP_MSB_Z_MASK; - /* Get ratio_y */ - config->ratio_y = lsb_msb & BMI2_GYR_USER_GAIN_RATIO_Y_MASK; + /* Gyroscope offset compensation value for x-axis */ + gyr_off_comp_axes->x = (int16_t)(((uint16_t) gyr_off_msb_x << 8) | gyr_off_lsb_x); - /* Get word to calculate ratio_z */ - lsb = (uint16_t) feat_config[idx++]; - msb = ((uint16_t) feat_config[idx++] << 8); - lsb_msb = lsb | msb; + /* Gyroscope offset compensation value for y-axis */ + gyr_off_comp_axes->y = (int16_t)(((uint16_t) gyr_off_msb_y << 6) | gyr_off_lsb_y); - /* Get ratio_z */ - config->ratio_z = lsb_msb & BMI2_GYR_USER_GAIN_RATIO_Z_MASK; + /* Gyroscope offset compensation value for z-axis */ + gyr_off_comp_axes->z = (int16_t)(((uint16_t) gyr_off_msb_z << 4) | gyr_off_lsb_z); } } else { - rslt = BMI2_E_INVALID_SENSOR; + rslt = BMI2_E_NULL_PTR; } return rslt; } /*! - * @brief This internal API gets tilt configurations like output-configuration. + * @brief This API writes the gyroscope bias values for each axis which is used + * for gyroscope offset compensation. */ -static int8_t get_tilt_config(struct bmi2_tilt_config *config, struct bmi2_dev *dev) +int8_t bmi2_write_gyro_offset_comp_axes(const struct bmi2_sens_axes_data *gyr_off_comp_axes, struct bmi2_dev *dev) { /* Variable to define error */ int8_t rslt; - /* Array to define the feature configuration */ - uint8_t feat_config[BMI2_FEAT_SIZE_IN_BYTES] = { 0 }; + /* Variable to define register data */ + uint8_t reg_data[4] = { 0 }; - /* Variable to define the array offset */ - uint8_t idx = 0; + /* Variable to store MSB value of offset compensation for x-axis */ + uint8_t gyr_off_msb_x; - /* Variable to define LSB */ - uint16_t lsb = 0; + /* Variable to store MSB value of offset compensation for y-axis */ + uint8_t gyr_off_msb_y; - /* Variable to define MSB */ - uint16_t msb = 0; + /* Variable to store MSB value of offset compensation for z-axis */ + uint8_t gyr_off_msb_z; - /* Variable to define a word */ - uint16_t lsb_msb = 0; + /* Null-pointer check */ + rslt = null_ptr_check(dev); + if ((rslt == BMI2_OK) && (gyr_off_comp_axes != NULL)) + { + /* Get the MSB values of gyroscope compensated offset values */ + rslt = bmi2_get_regs(BMI2_GYR_OFF_COMP_6_ADDR, ®_data[3], 1, dev); + if (rslt == BMI2_OK) + { + /* Get MSB value of x-axis from user-input */ + gyr_off_msb_x = (uint8_t)((gyr_off_comp_axes->x & BMI2_GYR_OFF_COMP_MSB_MASK) >> 8); + + /* Get MSB value of y-axis from user-input */ + gyr_off_msb_y = (uint8_t)((gyr_off_comp_axes->y & BMI2_GYR_OFF_COMP_MSB_MASK) >> 8); + + /* Get MSB value of z-axis from user-input */ + gyr_off_msb_z = (uint8_t)((gyr_off_comp_axes->z & BMI2_GYR_OFF_COMP_MSB_MASK) >> 8); + + /* Get LSB value of x-axis from user-input */ + reg_data[0] = (uint8_t)(gyr_off_comp_axes->x & BMI2_GYR_OFF_COMP_LSB_MASK); - /* Variable to set flag */ - uint8_t feat_found; + /* Get LSB value of y-axis from user-input */ + reg_data[1] = (uint8_t)(gyr_off_comp_axes->y & BMI2_GYR_OFF_COMP_LSB_MASK); - /* Initialize feature configuration for tilt */ - struct bmi2_feature_config tilt_config = { 0, 0, 0 }; + /* Get LSB value of z-axis from user-input */ + reg_data[2] = (uint8_t)(gyr_off_comp_axes->z & BMI2_GYR_OFF_COMP_LSB_MASK); - /* Search for tilt feature and extract its configuration details */ - feat_found = bmi2_extract_input_feat_config(&tilt_config, BMI2_TILT, dev); - if (feat_found) - { - /* Get the configuration from the page where tilt feature resides */ - rslt = bmi2_get_feat_config(tilt_config.page, feat_config, dev); - if (rslt == BMI2_OK) - { - /* Define the offset in bytes for tilt select */ - idx = tilt_config.start_addr; + /* Get MSB value of x-axis to be set */ + reg_data[3] = BMI2_SET_BIT_POS0(reg_data[3], BMI2_GYR_OFF_COMP_MSB_X, gyr_off_msb_x); - /* Get word to calculate threshold and output configuration */ - lsb = (uint16_t) feat_config[idx++]; - msb = ((uint16_t) feat_config[idx++] << 8); - lsb_msb = lsb | msb; + /* Get MSB value of y-axis to be set */ + reg_data[3] = BMI2_SET_BITS(reg_data[3], BMI2_GYR_OFF_COMP_MSB_Y, gyr_off_msb_y); - /* Get output configuration */ - config->out_conf = (lsb_msb & BMI2_TILT_OUT_CONF_MASK) >> BMI2_TILT_OUT_CONF_POS; + /* Get MSB value of z-axis to be set */ + reg_data[3] = BMI2_SET_BITS(reg_data[3], BMI2_GYR_OFF_COMP_MSB_Z, gyr_off_msb_z); - /* Copy out_conf value to a local copy in device structure */ - dev->int_map.tilt_out_conf = (uint8_t) config->out_conf; + /* Set the offset compensation values of axes */ + rslt = bmi2_set_regs(BMI2_GYR_OFF_COMP_3_ADDR, reg_data, 4, dev); } } else { - rslt = BMI2_E_INVALID_SENSOR; + rslt = BMI2_E_NULL_PTR; } return rslt; } /*! - * @brief This internal API gets uphold to wake configurations like output - * configuration. + * @brief This API updates the cross sensitivity coefficient between gyroscope's + * X and Z axes. */ -static int8_t get_up_hold_to_wake_config(struct bmi2_up_hold_to_wake_config *config, struct bmi2_dev *dev) +int8_t bmi2_get_gyro_cross_sense(struct bmi2_dev *dev) { /* Variable to define error */ - int8_t rslt; - - /* Array to define the feature configuration */ - uint8_t feat_config[BMI2_FEAT_SIZE_IN_BYTES] = { 0 }; - - /* Variable to define the array offset */ - uint8_t idx = 0; - - /* Variable to define LSB */ - uint16_t lsb = 0; - - /* Variable to define MSB */ - uint16_t msb = 0; - - /* Variable to define a word */ - uint16_t lsb_msb = 0; - - /* Variable to set flag */ - uint8_t feat_found; - - /* Initialize feature configuration for uphold to wake */ - struct bmi2_feature_config up_hold_to_wake_config = { 0, 0, 0 }; + int8_t rslt = BMI2_OK; + struct bmi2_sensor_data data; - /* Search for uphold to wake feature and extract its configuration details */ - feat_found = bmi2_extract_input_feat_config(&up_hold_to_wake_config, BMI2_UP_HOLD_TO_WAKE, dev); - if (feat_found) + /* Check if the feature is supported by this variant */ + if (dev->variant_feature & BMI2_GYRO_CROSS_SENS_ENABLE) { - /* Get the configuration from the page where uphold to wake feature resides */ - rslt = bmi2_get_feat_config(up_hold_to_wake_config.page, feat_config, dev); + rslt = null_ptr_check(dev); if (rslt == BMI2_OK) { - /* Define the offset in bytes for uphold to wake select */ - idx = up_hold_to_wake_config.start_addr; - - /* Get word to calculate output configuration */ - lsb = (uint16_t) feat_config[idx++]; - msb = ((uint16_t) feat_config[idx++] << 8); - lsb_msb = lsb | msb; - - /* Get output configuration */ - config->out_conf = (lsb_msb & BMI2_UP_HOLD_TO_WAKE_OUT_CONF_MASK) >> BMI2_UP_HOLD_TO_WAKE_OUT_CONF_POS; + /* Select the feature whose data is to be acquired */ + data.type = BMI2_GYRO_CROSS_SENSE; - /* Copy out_conf value to a local copy in device structure */ - dev->int_map.up_hold_to_wake_out_conf = (uint8_t) config->out_conf; + /* Get the respective data */ + rslt = bmi2_get_sensor_data(&data, 1, dev); + if (rslt == BMI2_OK) + { + /* Update the gyroscope cross sense value of z axis + * in the device structure + */ + dev->gyr_cross_sens_zx = data.sens_data.correction_factor_zx; + } + } + else + { + rslt = BMI2_E_NULL_PTR; } - } - else - { - rslt = BMI2_E_INVALID_SENSOR; } return rslt; } /*! - * @brief This internal API gets glance detector configurations like output - * configuration. + * @brief This API gets Error bits and message indicating internal status. */ -static int8_t get_glance_detect_config(struct bmi2_glance_det_config *config, struct bmi2_dev *dev) +int8_t bmi2_get_internal_status(uint8_t *int_stat, struct bmi2_dev *dev) { /* Variable to define error */ int8_t rslt; - /* Array to define the feature configuration */ - uint8_t feat_config[BMI2_FEAT_SIZE_IN_BYTES] = { 0 }; - - /* Variable to define the array offset */ - uint8_t idx = 0; - - /* Variable to define LSB */ - uint16_t lsb = 0; - - /* Variable to define MSB */ - uint16_t msb = 0; - - /* Variable to define a word */ - uint16_t lsb_msb = 0; - - /* Variable to set flag */ - uint8_t feat_found; - - /* Initialize feature configuration for glance detector */ - struct bmi2_feature_config glance_det_config = { 0, 0, 0 }; - - /* Search for glance detector feature and extract its configuration details */ - feat_found = bmi2_extract_input_feat_config(&glance_det_config, BMI2_GLANCE_DETECTOR, dev); - if (feat_found) + /* Null-pointer check */ + rslt = null_ptr_check(dev); + if ((rslt == BMI2_OK) && (int_stat != NULL)) { - /* Get the configuration from the page where glance detector feature resides */ - rslt = bmi2_get_feat_config(glance_det_config.page, feat_config, dev); - if (rslt == BMI2_OK) - { - /* Define the offset in bytes for glance detector select */ - idx = glance_det_config.start_addr; - - /* Get word to calculate output configuration */ - lsb = (uint16_t) feat_config[idx++]; - msb = ((uint16_t) feat_config[idx++] << 8); - lsb_msb = lsb | msb; - - /* Get output configuration */ - config->out_conf = (lsb_msb & BMI2_GLANCE_DET_OUT_CONF_MASK) >> BMI2_GLANCE_DET_OUT_CONF_POS; + /* Delay to read the internal status */ + dev->delay_us(20000, dev->intf_ptr); - /* Copy out_conf value to a local copy in device structure */ - dev->int_map.glance_out_conf = (uint8_t) config->out_conf; - } + /* Get the error bits and message */ + rslt = bmi2_get_regs(BMI2_INTERNAL_STATUS_ADDR, int_stat, 1, dev); } else { - rslt = BMI2_E_INVALID_SENSOR; + rslt = BMI2_E_NULL_PTR; } return rslt; } +/*! @cond DOXYGEN_SUPRESS */ + +/* Suppressing doxygen warnings triggered for same static function names present across various sensor variant + * directories */ + /*! - * @brief This internal API gets wake-up configurations like sensitivity, - * single, double and triple tap enable and output-configuration. + * @brief This API verifies and allows only the correct position to do Fast Offset Compensation for + * accelerometer & gyro. */ -static int8_t get_wake_up_config(struct bmi2_wake_up_config *config, struct bmi2_dev *dev) +static int8_t verify_foc_position(uint8_t sens_list, + const struct bmi2_accel_foc_g_value *accel_g_axis, + struct bmi2_dev *dev) { - /* Variable to define error */ - int8_t rslt = BMI2_OK; - - /* Array to define the feature configuration */ - uint8_t feat_config[BMI2_FEAT_SIZE_IN_BYTES] = { 0 }; - - /* Variable to define the array offset */ - uint8_t idx = 0; - - /* Variable to define LSB */ - uint16_t lsb = 0; - - /* Variable to define MSB */ - uint16_t msb = 0; - - /* Variable to define a word */ - uint16_t lsb_msb = 0; - - /* Variable to set flag */ - uint8_t feat_found; + int8_t rslt; - /* Initialize feature configuration for wake-up */ - struct bmi2_feature_config wake_up_config = { 0, 0, 0 }; + struct bmi2_sens_axes_data avg_foc_data = { 0 }; + struct bmi2_foc_temp_value temp_foc_data = { 0 }; - if (dev->chip_id == BMI260_CHIP_IDENTIFIER) + rslt = null_ptr_check(dev); + if (rslt == BMI2_OK) { - rslt = dev->get_wakeup_config(config, dev); + /* Enable sensor */ + rslt = bmi2_sensor_enable(&sens_list, 1, dev); } - else if (dev->chip_id == BMI261_CHIP_IDENTIFIER) + + if (rslt == BMI2_OK) { - /* Search for wake-up feature and extract its configuration details */ - feat_found = bmi2_extract_input_feat_config(&wake_up_config, BMI2_WAKE_UP, dev); - if (feat_found) + + rslt = get_average_of_sensor_data(sens_list, &temp_foc_data, dev); + if (rslt == BMI2_OK) { - /* Get the configuration from the page where wake-up feature resides */ - rslt = bmi2_get_feat_config(wake_up_config.page, feat_config, dev); - if (rslt == BMI2_OK) + if (sens_list == BMI2_ACCEL) { - /* Define the offset in bytes for wake-up select */ - idx = wake_up_config.start_addr; - - /* Get word to calculate sensitivity, single/double tap - * enable and output configuration - */ - lsb = (uint16_t) feat_config[idx++]; - msb = ((uint16_t) feat_config[idx++] << 8); - lsb_msb = lsb | msb; - - /* Get sensitivity */ - config->sensitivity = (lsb_msb & BMI2_WAKE_UP_SENSITIVITY_MASK) >> BMI2_WAKE_UP_SENSITIVITY_POS; - /* Get single/double tap enable */ - config->single_tap_en = (lsb_msb & BMI2_WAKE_UP_SINGLE_TAP_EN_MASK) >> BMI2_WAKE_UP_SINGLE_TAP_EN_POS; + /* Taking modulus to make negative values as positive */ + if ((accel_g_axis->x == 1) && (accel_g_axis->sign == 1)) + { + temp_foc_data.x = temp_foc_data.x * -1; + } + else if ((accel_g_axis->y == 1) && (accel_g_axis->sign == 1)) + { + temp_foc_data.y = temp_foc_data.y * -1; + } + else if ((accel_g_axis->z == 1) && (accel_g_axis->sign == 1)) + { + temp_foc_data.z = temp_foc_data.z * -1; + } + } - /* Get output configuration */ - config->out_conf = (lsb_msb & BMI2_WAKE_UP_OUT_CONF_MASK) >> BMI2_WAKE_UP_OUT_CONF_POS; + /* Typecasting into 16bit */ + avg_foc_data.x = (int16_t)(temp_foc_data.x); + avg_foc_data.y = (int16_t)(temp_foc_data.y); + avg_foc_data.z = (int16_t)(temp_foc_data.z); - /* Copy out_conf value to a local copy in device structure */ - dev->int_map.wake_up_out_conf = (uint8_t) config->out_conf; - } + rslt = validate_foc_position(sens_list, accel_g_axis, avg_foc_data, dev); } } - else - { - rslt = BMI2_E_INVALID_SENSOR; - } return rslt; } +/*! @endcond */ + /*! - * @brief This internal API gets wrist gesture configurations like wearable-arm, - * and output-configuration. + * @brief This API performs Fast Offset Compensation for accelerometer. */ -static int8_t get_wrist_gest_config(struct bmi2_wrist_gest_config *config, struct bmi2_dev *dev) +int8_t bmi2_perform_accel_foc(const struct bmi2_accel_foc_g_value *accel_g_value, struct bmi2_dev *dev) { /* Variable to define error */ int8_t rslt; - /* Array to define the feature configuration */ - uint8_t feat_config[BMI2_FEAT_SIZE_IN_BYTES] = { 0 }; - - /* Variable to define the array offset */ - uint8_t idx = 0; - - /* Variable to set flag */ - uint8_t feat_found; + /* Structure to define the accelerometer configurations */ + struct bmi2_accel_config acc_cfg = { 0, 0, 0, 0 }; - /* Initialize feature configuration for wrist gesture */ - struct bmi2_feature_config wrist_gest_config = { 0, 0, 0 }; + /* Variable to store status of advance power save */ + uint8_t aps = 0; - /* Copy the feature configuration address to a local pointer */ - uint16_t *data_p = (uint16_t *) (void *)feat_config; + /* Variable to store status of accelerometer enable */ + uint8_t acc_en = 0; - /* Search for wrist gesture feature and extract its configuration details */ - feat_found = bmi2_extract_input_feat_config(&wrist_gest_config, BMI2_WRIST_GESTURE, dev); - if (feat_found) + /* Null-pointer check */ + rslt = null_ptr_check(dev); + if ((rslt == BMI2_OK) && (accel_g_value != NULL)) { - /* Get the configuration from the page where wrist gesture feature resides */ - rslt = bmi2_get_feat_config(wrist_gest_config.page, feat_config, dev); - if (rslt == BMI2_OK) + /* Check for input validity */ + if ((((BMI2_ABS(accel_g_value->x)) + (BMI2_ABS(accel_g_value->y)) + (BMI2_ABS(accel_g_value->z))) == 1) && + ((accel_g_value->sign == 1) || (accel_g_value->sign == 0))) { - /* Define the offset in bytes for wrist gesture select */ - idx = wrist_gest_config.start_addr; - - /* Get offset in words since all the features are set in words length */ - idx = idx / 2; - - /* Get wearable arm */ - config->wearable_arm = (*(data_p + idx) & BMI2_WRIST_GEST_WEAR_ARM_MASK) >> BMI2_WRIST_GEST_WEAR_ARM_POS; - - /* Get output configuration */ - config->out_conf = BMI2_GET_BIT_POS0(*(data_p + idx), BMI2_WRIST_GEST_OUT_CONF); + rslt = verify_foc_position(BMI2_ACCEL, accel_g_value, dev); + if (rslt == BMI2_OK) + { - /* Copy out_conf value to a local copy in device structure */ - dev->int_map.wrist_gest_out_conf = (uint8_t) config->out_conf; + /* Save accelerometer configurations, accelerometer + * enable status and advance power save status + */ + rslt = save_accel_foc_config(&acc_cfg, &aps, &acc_en, dev); + } - /* Increment the offset by 1 word to get min_flick_peak */ - idx++; - config->min_flick_peak = *(data_p + idx); + /* Set configurations for FOC */ + if (rslt == BMI2_OK) + { + rslt = set_accel_foc_config(dev); + } - /* Increment the offset by 1 word to get min_flick_samples */ - idx++; - config->min_flick_samples = *(data_p + idx); + /* Perform accelerometer FOC */ + if (rslt == BMI2_OK) + { + rslt = perform_accel_foc(accel_g_value, &acc_cfg, dev); + } - /* Increment the offset by 1 word to get max_duration */ - idx++; - config->max_duration = *(data_p + idx); + /* Restore the saved configurations */ + if (rslt == BMI2_OK) + { + rslt = restore_accel_foc_config(&acc_cfg, aps, acc_en, dev); + } + } + else + { + rslt = BMI2_E_INVALID_INPUT; } } else { - rslt = BMI2_E_INVALID_SENSOR; + rslt = BMI2_E_NULL_PTR; } return rslt; } /*! - * @brief This internal API gets wrist wear wake-up configurations like - * output-configuration. + * @brief This API performs Fast Offset Compensation for gyroscope. */ -static int8_t get_wrist_wear_wake_up_config(struct bmi2_wrist_wear_wake_up_config *config, struct bmi2_dev *dev) +int8_t bmi2_perform_gyro_foc(struct bmi2_dev *dev) { /* Variable to define error */ int8_t rslt; - /* Array to define the feature configuration */ - uint8_t feat_config[BMI2_FEAT_SIZE_IN_BYTES] = { 0 }; + /* Structure to define the gyroscope configurations */ + struct bmi2_gyro_config gyr_cfg = { 0, 0, 0, 0, 0, 0 }; - /* Variable to define the array offset */ - uint8_t idx = 0; + /* Variable to store status of advance power save */ + uint8_t aps = 0; - /* Variable to set flag */ - uint8_t feat_found; + /* Variable to store status of gyroscope enable */ + uint8_t gyr_en = 0; + + /* Array of structure to store gyroscope data */ + struct bmi2_sens_axes_data gyr_value[128]; - /* Initialize feature configuration for wrist wear wake-up */ - struct bmi2_feature_config wrist_wake_up_config = { 0, 0, 0 }; + /* Structure to store gyroscope data temporarily */ + struct bmi2_foc_temp_value temp = { 0, 0, 0 }; - /* Copy the feature configuration address to a local pointer */ - uint16_t *data_p = (uint16_t *) (void *)feat_config; + /* Variable to store status read from the status register */ + uint8_t reg_status = 0; - /* Search for wrist wear wake-up feature and extract its configuration details */ - feat_found = bmi2_extract_input_feat_config(&wrist_wake_up_config, BMI2_WRIST_WEAR_WAKE_UP, dev); - if (feat_found) + /* Variable to define count */ + uint8_t loop = 0; + + /* Structure to store the offset values to be stored in the register */ + struct bmi2_sens_axes_data gyro_offset = { 0, 0, 0, 0 }; + + /* Null-pointer check */ + rslt = null_ptr_check(dev); + if (rslt == BMI2_OK) { - /* Get the configuration from the page where wrist wear wake-up feature resides */ - rslt = bmi2_get_feat_config(wrist_wake_up_config.page, feat_config, dev); + /* Argument2 is not applicable for gyro */ + rslt = verify_foc_position(BMI2_GYRO, 0, dev); if (rslt == BMI2_OK) { - /* Define the offset in bytes for wrist wear wake-up select */ - idx = wrist_wake_up_config.start_addr; + /* Save gyroscope configurations, gyroscope enable + * status and advance power save status + */ + rslt = save_gyro_config(&gyr_cfg, &aps, &gyr_en, dev); - /* Get offset in words since all the features are set in words length */ - idx = idx / 2; + /* Set configurations for gyroscope FOC */ + if (rslt == BMI2_OK) + { + rslt = set_gyro_foc_config(dev); + } - /* Get output configuration */ - config->out_conf = BMI2_GET_BIT_POS0(*(data_p + idx), BMI2_WRIST_WAKE_UP_OUT_CONF); + /* Perform FOC */ + if (rslt == BMI2_OK) + { + for (loop = 0; loop < 128; loop++) + { + /* Giving a delay of more than 40ms since ODR is configured as 25Hz */ + dev->delay_us(50000, dev->intf_ptr); - /* Copy out_conf value to a local copy in device structure */ - dev->int_map.wrist_wear_wake_up_out_conf = (uint8_t) config->out_conf; + /* Get gyroscope data ready interrupt status */ + rslt = bmi2_get_status(®_status, dev); - /* Increment the offset value by 1 word to get min_angle_focus */ - idx++; - config->min_angle_focus = *(data_p + idx); + /* Read 128 samples of gyroscope data on data ready interrupt */ + if ((rslt == BMI2_OK) && (reg_status & BMI2_DRDY_GYR)) + { + rslt = read_gyro_xyz(&gyr_value[loop], dev); + if (rslt == BMI2_OK) + { + /* Store the data in a temporary structure */ + temp.x = temp.x + (int32_t)gyr_value[loop].x; + temp.y = temp.y + (int32_t)gyr_value[loop].y; + temp.z = temp.z + (int32_t)gyr_value[loop].z; + } + } - /* Increment the offset value by 1 word to get min_angle_nonfocus */ - idx++; - config->min_angle_nonfocus = *(data_p + idx); + if (rslt != BMI2_OK) + { + break; + } + else if ((reg_status & BMI2_DRDY_GYR) != BMI2_DRDY_GYR) + { + rslt = BMI2_E_INVALID_STATUS; + break; + } + } - /* Increment the offset value by 1 word to get max_tilt_lr */ - idx++; - config->max_tilt_lr = *(data_p + idx); + if (rslt == BMI2_OK) + { + /* Take average of x, y and z data for lesser + * noise. It is same as offset data since lsb/dps + * is same for both data and offset register + */ + gyro_offset.x = (int16_t)(temp.x / 128); + gyro_offset.y = (int16_t)(temp.y / 128); + gyro_offset.z = (int16_t)(temp.z / 128); - /* Increment the offset value by 1 word to get max_tilt_ll */ - idx++; - config->max_tilt_ll = *(data_p + idx); + /* Saturate gyroscope data since the offset + * registers are of 10 bit value where as the + * gyroscope data is of 16 bit value + */ + saturate_gyro_data(&gyro_offset); - /* Increment the offset value by 1 word to get max_tilt_pd */ - idx++; - config->max_tilt_pd = *(data_p + idx); + /* Invert the gyroscope offset data */ + invert_gyro_offset(&gyro_offset); - /* Increment the offset value by 1 word to get max_tilt_pu */ - idx++; - config->max_tilt_pu = *(data_p + idx); + /* Write offset data in the gyroscope offset + * compensation register + */ + rslt = bmi2_write_gyro_offset_comp_axes(&gyro_offset, dev); + } + + /* Enable gyroscope offset compensation */ + if (rslt == BMI2_OK) + { + rslt = bmi2_set_gyro_offset_comp(BMI2_ENABLE, dev); + } + /* Restore the saved gyroscope configurations */ + if (rslt == BMI2_OK) + { + rslt = restore_gyro_config(&gyr_cfg, aps, gyr_en, dev); + } + } } } - else - { - rslt = BMI2_E_INVALID_SENSOR; - } return rslt; } /*! - * @brief This internal API gets wrist gesture configurations like wearable-arm, - * and output-configuration for wearable variant. + * @brief This API is used to get the feature configuration from the + * selected page. */ -static int8_t get_wrist_gest_w_config(struct bmi2_wrist_gest_w_config *config, struct bmi2_dev *dev) +int8_t bmi2_get_feat_config(uint8_t sw_page, uint8_t *feat_config, struct bmi2_dev *dev) { /* Variable to define error */ int8_t rslt; - /* Array to define the feature configuration */ - uint8_t feat_config[BMI2_FEAT_SIZE_IN_BYTES] = { 0 }; - - /* Variable to define the array offset */ - uint8_t idx = 0; + /* Variable to define bytes remaining to read */ + uint8_t bytes_remain = BMI2_FEAT_SIZE_IN_BYTES; - /* Variable to set flag */ - uint8_t feat_found; + /* Variable to define the read-write length */ + uint8_t read_write_len = 0; - /* Initialize feature configuration for wrist gesture */ - struct bmi2_feature_config wrist_gest_config = { 0, 0, 0 }; + /* Variable to define the feature configuration address */ + uint8_t addr = BMI2_FEATURES_REG_ADDR; - /* Copy the feature configuration address to a local pointer */ - uint16_t *data_p = (uint16_t *) (void *)feat_config; + /* Variable to define index */ + uint8_t index = 0; - /* Search for wrist gesture feature and extract its configuration details */ - feat_found = bmi2_extract_input_feat_config(&wrist_gest_config, BMI2_WRIST_GESTURE_WH, dev); - if (feat_found) + if ((feat_config == NULL) || (dev == NULL)) { - /* Get the configuration from the page where wrist gesture feature resides */ - rslt = bmi2_get_feat_config(wrist_gest_config.page, feat_config, dev); - if (rslt == BMI2_OK) + rslt = BMI2_E_NULL_PTR; + } + else + { + /* Check whether the page is valid */ + if (sw_page < dev->page_max) { - /* Define the offset in bytes for wrist gesture select */ - idx = wrist_gest_config.start_addr; + /* Switch page */ + rslt = bmi2_set_regs(BMI2_FEAT_PAGE_ADDR, &sw_page, 1, dev); - /* Get offset in words since all the features are set in words length */ - idx = idx / 2; + /* If user length is less than feature length */ + if ((rslt == BMI2_OK) && (dev->read_write_len < BMI2_FEAT_SIZE_IN_BYTES)) + { + /* Read-write should be even */ + if ((dev->read_write_len % 2) != 0) + { + dev->read_write_len--; + } - /* Get wearable arm */ - config->wearable_arm = (*(data_p + idx) & BMI2_WRIST_GEST_WEAR_ARM_MASK) >> BMI2_WRIST_GEST_WEAR_ARM_POS; + while (bytes_remain > 0) + { + if (bytes_remain >= dev->read_write_len) + { + /* Read from the page */ + rslt = bmi2_get_regs(addr, &feat_config[index], dev->read_write_len, dev); - /* Get output configuration */ - config->out_conf = BMI2_GET_BIT_POS0(*(data_p + idx), BMI2_WRIST_GEST_OUT_CONF); + /* Update index */ + index += (uint8_t) dev->read_write_len; - /* Copy out_conf value to a local copy in device structure */ - dev->int_map.wrist_gest_out_conf = (uint8_t) config->out_conf; + /* Update address */ + addr += (uint8_t) dev->read_write_len; - /* Increment the offset by 1 word to get min_flick_peak */ - idx++; - config->min_flick_peak = *(data_p + idx); + /* Update read-write length */ + read_write_len += (uint8_t) dev->read_write_len; + } + else + { + /* Read from the page */ + rslt = bmi2_get_regs(addr, (uint8_t *) (feat_config + index), (uint16_t) bytes_remain, dev); - /* Increment the offset by 1 word to get min_flick_samples */ - idx++; - config->min_flick_samples = *(data_p + idx); + /* Update read-write length */ + read_write_len += bytes_remain; + } - /* Increment the offset by 1 word to get max_duration */ - idx++; - config->max_duration = *(data_p + idx); + /* Remaining bytes */ + bytes_remain = BMI2_FEAT_SIZE_IN_BYTES - read_write_len; - /* Increment the offset by 1 word to get reporting delay */ - idx++; - config->reporting_delay = *(data_p + idx); + if (rslt != BMI2_OK) + { + break; + } + } + } + else if (rslt == BMI2_OK) + { + /* Get configuration from the page */ + rslt = bmi2_get_regs(BMI2_FEATURES_REG_ADDR, feat_config, BMI2_FEAT_SIZE_IN_BYTES, dev); + } + } + else + { + rslt = BMI2_E_INVALID_PAGE; } - } - else - { - rslt = BMI2_E_INVALID_SENSOR; } return rslt; } /*! - * @brief This internal API gets wrist wear wake-up configurations like - * output-configuration for wearable variant. + * @brief This API is used to extract the input feature configuration + * details from the look-up table. */ -static int8_t get_wrist_wear_wake_up_wh_config(struct bmi2_wrist_wear_wake_up_wh_config *config, struct bmi2_dev *dev) +uint8_t bmi2_extract_input_feat_config(struct bmi2_feature_config *feat_config, uint8_t type, + const struct bmi2_dev *dev) { - /* Variable to define error */ - int8_t rslt; - - /* Array to define the feature configuration */ - uint8_t feat_config[BMI2_FEAT_SIZE_IN_BYTES] = { 0 }; - - /* Variable to define the array offset */ - uint8_t idx = 0; + /* Variable to define loop */ + uint8_t loop = 0; /* Variable to set flag */ - uint8_t feat_found; - - /* Initialize feature configuration for wrist wear wake-up */ - struct bmi2_feature_config wrist_wake_up_config = { 0, 0, 0 }; - - /* Copy the feature configuration address to a local pointer */ - uint16_t *data_p = (uint16_t *) (void *)feat_config; + uint8_t feat_found = BMI2_FALSE; - /* Search for wrist wear wake-up feature and extract its configuration details */ - feat_found = bmi2_extract_input_feat_config(&wrist_wake_up_config, BMI2_WRIST_WEAR_WAKE_UP_WH, dev); - if (feat_found) + /* Search for the input feature from the input configuration array */ + while (loop < dev->input_sens) { - /* Get the configuration from the page where wrist wear wake-up feature resides */ - rslt = bmi2_get_feat_config(wrist_wake_up_config.page, feat_config, dev); - if (rslt == BMI2_OK) + if (dev->feat_config[loop].type == type) { - /* Define the offset in bytes for wrist wear wake-up select */ - idx = wrist_wake_up_config.start_addr; - - /* Get offset in words since all the features are set in words length */ - idx = idx / 2; - - /* Get output configuration */ - config->out_conf = BMI2_GET_BIT_POS0(*(data_p + idx), BMI2_WRIST_WAKE_UP_OUT_CONF); - - /* Copy out_conf value to a local copy in device structure */ - dev->int_map.wrist_wear_wake_up_out_conf = (uint8_t) config->out_conf; - - /* Increment the offset value by 1 word to get min_angle_focus */ - idx++; - config->min_angle_focus = *(data_p + idx); - - /* Increment the offset value by 1 word to get min_angle_nonfocus */ - idx++; - config->min_angle_nonfocus = *(data_p + idx); - - /* Increment the offset value by 1 word to get angle landscape right and angle landscape left */ - idx++; - config->angle_lr = BMI2_GET_BIT_POS0(*(data_p + idx), BMI2_WRIST_WAKE_UP_ANGLE_LR); - config->angle_ll = BMI2_GET_BITS(*(data_p + idx), BMI2_WRIST_WAKE_UP_ANGLE_LL); - - /* Increment the offset value by 1 word to get angle portrait down and angle portrait up */ - idx++; - config->angle_pd = BMI2_GET_BIT_POS0(*(data_p + idx), BMI2_WRIST_WAKE_UP_ANGLE_PD); - config->angle_pu = BMI2_GET_BITS(*(data_p + idx), BMI2_WRIST_WAKE_UP_ANGLE_PU); - - /* Increment the offset value by 1 word to get min duration quite and min duration moved */ - idx++; - config->min_dur_mov = BMI2_GET_BIT_POS0(*(data_p + idx), BMI2_WRIST_WAKE_UP_MIN_DUR_MOVED); - config->min_dur_quite = BMI2_GET_BITS(*(data_p + idx), BMI2_WRIST_WAKE_UP_MIN_DUR_QUITE); - + *feat_config = dev->feat_config[loop]; + feat_found = BMI2_TRUE; + break; } - } - else - { - rslt = BMI2_E_INVALID_SENSOR; + + loop++; } - return rslt; + /* Return flag */ + return feat_found; } +/***************************************************************************/ + +/*! Local Function Definitions + ****************************************************************************/ + +/*! @cond DOXYGEN_SUPRESS */ + +/* Suppressing doxygen warnings triggered for same static function names present across various sensor variant + * directories */ + /*! - * @brief This internal API gets orientation configurations like upside/down - * detection, symmetrical modes, blocking mode, theta, hysteresis and output - * configuration. + * @brief This internal API writes the configuration file. */ -static int8_t get_orient_config(struct bmi2_orient_config *config, struct bmi2_dev *dev) +static int8_t write_config_file(struct bmi2_dev *dev) { /* Variable to define error */ int8_t rslt; - /* Array to define the feature configuration */ - uint8_t feat_config[BMI2_FEAT_SIZE_IN_BYTES] = { 0 }; - - /* Variable to define the array offset */ - uint8_t idx = 0; - - /* Variable to define LSB */ - uint16_t lsb = 0; + /* Variable to update the configuration file index */ + uint16_t index = 0; - /* Variable to define MSB */ - uint16_t msb = 0; + /* config file size */ + uint16_t config_size = dev->config_size; - /* Variable to define a word */ - uint16_t lsb_msb = 0; + /* Variable to get the remainder */ + uint8_t remain = (uint8_t)(config_size % dev->read_write_len); - /* Variable to set flag */ - uint8_t feat_found; + /* Variable to get the balance bytes */ + uint16_t bal_byte = 0; - /* Initialize feature configuration for orient */ - struct bmi2_feature_config orient_config = { 0, 0, 0 }; + /* Variable to define temporary read/write length */ + uint16_t read_write_len = 0; - /* Search for orient feature and extract its configuration details */ - feat_found = bmi2_extract_input_feat_config(&orient_config, BMI2_ORIENTATION, dev); - if (feat_found) + /* Disable advanced power save mode */ + rslt = bmi2_set_adv_power_save(BMI2_DISABLE, dev); + if (rslt == BMI2_OK) { - /* Get the configuration from the page where orient feature resides */ - rslt = bmi2_get_feat_config(orient_config.page, feat_config, dev); + /* Disable loading of the configuration */ + rslt = set_config_load(BMI2_DISABLE, dev); if (rslt == BMI2_OK) { - /* Define the offset in bytes for orient select */ - idx = orient_config.start_addr; - - /* Get word to calculate upside/down detection, - * symmetrical modes, blocking mode and theta - */ - lsb = (uint16_t) feat_config[idx++]; - msb = ((uint16_t) feat_config[idx++] << 8); - lsb_msb = lsb | msb; - - /* Get upside/down detection */ - config->ud_en = (lsb_msb & BMI2_ORIENT_UP_DOWN_MASK) >> BMI2_ORIENT_UP_DOWN_POS; + if (!remain) + { + /* Write the configuration file */ + for (index = 0; (index < config_size) && (rslt == BMI2_OK); index += dev->read_write_len) + { + rslt = upload_file((dev->config_file_ptr + index), index, dev->read_write_len, dev); + } + } + else + { + /* Get the balance bytes */ + bal_byte = (uint16_t) config_size - (uint16_t) remain; - /* Get symmetrical modes */ - config->mode = (lsb_msb & BMI2_ORIENT_SYMM_MODE_MASK) >> BMI2_ORIENT_SYMM_MODE_POS; + /* Write the configuration file for the balancem bytes */ + for (index = 0; (index < bal_byte) && (rslt == BMI2_OK); index += dev->read_write_len) + { + rslt = upload_file((dev->config_file_ptr + index), index, dev->read_write_len, dev); + } - /* Get blocking mode */ - config->blocking = (lsb_msb & BMI2_ORIENT_BLOCK_MODE_MASK) >> BMI2_ORIENT_BLOCK_MODE_POS; + if (rslt == BMI2_OK) + { + /* Update length in a temporary variable */ + read_write_len = dev->read_write_len; - /* Get theta */ - config->theta = (lsb_msb & BMI2_ORIENT_THETA_MASK) >> BMI2_ORIENT_THETA_POS; + /* Write the remaining bytes in 2 bytes length */ + dev->read_write_len = 2; - /* Get the next word to calculate hysteresis and output configuration */ - lsb = (uint16_t) feat_config[idx++]; - msb = ((uint16_t) feat_config[idx++] << 8); - lsb_msb = lsb | msb; + /* Write the configuration file for the remaining bytes */ + for (index = bal_byte; + (index < config_size) && (rslt == BMI2_OK); + index += dev->read_write_len) + { + rslt = upload_file((dev->config_file_ptr + index), index, dev->read_write_len, dev); + } - /* Get hysteresis */ - config->hysteresis = lsb_msb & BMI2_ORIENT_HYST_MASK; + /* Restore the user set length back from the temporary variable */ + dev->read_write_len = read_write_len; + } + } - /* Get output configuration */ - config->out_conf = (lsb_msb & BMI2_ORIENT_OUT_CONF_MASK) >> BMI2_ORIENT_OUT_CONF_POS; + if (rslt == BMI2_OK) + { + /* Enable loading of the configuration */ + rslt = set_config_load(BMI2_ENABLE, dev); - /* Copy out_conf value to a local copy in device structure */ - dev->int_map.orient_out_conf = (uint8_t) config->out_conf; + /* Wait till ASIC is initialized */ + dev->delay_us(150000, dev->intf_ptr); + if (rslt == BMI2_OK) + { + /* Enable advanced power save mode */ + rslt = bmi2_set_adv_power_save(BMI2_ENABLE, dev); + } + } } } - else - { - rslt = BMI2_E_INVALID_SENSOR; - } return rslt; } /*! - * @brief This internal API gets high-g configurations like threshold, - * hysteresis, duration, and output configuration. + * @brief This internal API enables/disables the loading of the configuration + * file. */ -static int8_t get_high_g_config(struct bmi2_high_g_config *config, struct bmi2_dev *dev) +static int8_t set_config_load(uint8_t enable, struct bmi2_dev *dev) { /* Variable to define error */ int8_t rslt; - /* Array to define the feature configuration */ - uint8_t feat_config[BMI2_FEAT_SIZE_IN_BYTES] = { 0 }; - - /* Variable to define the array offset */ - uint8_t idx = 0; - - /* Variable to define LSB */ - uint16_t lsb = 0; - - /* Variable to define MSB */ - uint16_t msb = 0; - - /* Variable to define a word */ - uint16_t lsb_msb = 0; - - /* Variable to set flag */ - uint8_t feat_found; - - /* Initialize feature configuration for high-g */ - struct bmi2_feature_config high_g_config = { 0, 0, 0 }; - - /* Search for high-g feature and extract its configuration details */ - feat_found = bmi2_extract_input_feat_config(&high_g_config, BMI2_HIGH_G, dev); - if (feat_found) - { - /* Get the configuration from the page where high-g feature resides */ - rslt = bmi2_get_feat_config(high_g_config.page, feat_config, dev); - if (rslt == BMI2_OK) - { - /* Define the offset in bytes for high-g select */ - idx = high_g_config.start_addr; - - /* Get word to calculate threshold */ - lsb = (uint16_t) feat_config[idx++]; - msb = ((uint16_t) feat_config[idx++] << 8); - lsb_msb = lsb | msb; - - /* Get threshold */ - config->threshold = lsb_msb & BMI2_HIGH_G_THRES_MASK; - - /* Get word to calculate hysteresis */ - lsb = (uint16_t) feat_config[idx++]; - msb = ((uint16_t) feat_config[idx++] << 8); - lsb_msb = lsb | msb; - - /* Get hysteresis */ - config->hysteresis = lsb_msb & BMI2_HIGH_G_HYST_MASK; - - /* Get x_select */ - config->select_x = (lsb_msb & BMI2_HIGH_G_X_SEL_MASK) >> BMI2_HIGH_G_X_SEL_POS; - - /* Get y_select */ - config->select_y = (lsb_msb & BMI2_HIGH_G_Y_SEL_MASK) >> BMI2_HIGH_G_Y_SEL_POS; - - /* Get z_select */ - config->select_z = (lsb_msb & BMI2_HIGH_G_Z_SEL_MASK) >> BMI2_HIGH_G_Z_SEL_POS; - - /* Get word to calculate duration and output configuration */ - lsb = (uint16_t) feat_config[idx++]; - msb = ((uint16_t) feat_config[idx++] << 8); - lsb_msb = lsb | msb; - - /* Get duration */ - config->duration = lsb_msb & BMI2_HIGH_G_DUR_MASK; - - /* Get output configuration */ - config->out_conf = (lsb_msb & BMI2_HIGH_G_OUT_CONF_MASK) >> BMI2_HIGH_G_OUT_CONF_POS; + /* Variable to store data */ + uint8_t reg_data = 0; - /* Copy out_conf value to a local copy in device structure */ - dev->int_map.high_g_out_conf = (uint8_t) config->out_conf; - } - } - else + rslt = bmi2_get_regs(BMI2_INIT_CTRL_ADDR, ®_data, 1, dev); + if (rslt == BMI2_OK) { - rslt = BMI2_E_INVALID_SENSOR; + reg_data = BMI2_SET_BIT_POS0(reg_data, BMI2_CONF_LOAD_EN, enable); + rslt = bmi2_set_regs(BMI2_INIT_CTRL_ADDR, ®_data, 1, dev); } return rslt; } /*! - * @brief This internal API gets low-g configurations like threshold, - * hysteresis, duration, and output configuration. + * @brief This internal API loads the configuration file. */ -static int8_t get_low_g_config(struct bmi2_low_g_config *config, struct bmi2_dev *dev) +static int8_t upload_file(const uint8_t *config_data, uint16_t index, uint16_t write_len, struct bmi2_dev *dev) { /* Variable to define error */ int8_t rslt; - /* Array to define the feature configuration */ - uint8_t feat_config[BMI2_FEAT_SIZE_IN_BYTES] = { 0 }; - - /* Variable to define the array offset */ - uint8_t idx = 0; - - /* Variable to define LSB */ - uint16_t lsb = 0; - - /* Variable to define MSB */ - uint16_t msb = 0; - - /* Variable to define a word */ - uint16_t lsb_msb = 0; + /* Array to store address */ + uint8_t addr_array[2] = { 0 }; - /* Variable to set flag */ - uint8_t feat_found; + if (config_data != NULL) + { + /* Store 0 to 3 bits of address in first byte */ + addr_array[0] = (uint8_t)((index / 2) & 0x0F); - /* Initialize feature configuration for low-g */ - struct bmi2_feature_config low_g_config = { 0, 0, 0 }; + /* Store 4 to 11 bits of address in the second byte */ + addr_array[1] = (uint8_t)((index / 2) >> 4); - /* Search for low-g feature and extract its configuration details */ - feat_found = bmi2_extract_input_feat_config(&low_g_config, BMI2_LOW_G, dev); - if (feat_found) - { - /* Get the configuration from the page where low-g feature resides */ - rslt = bmi2_get_feat_config(low_g_config.page, feat_config, dev); + /* Write the 2 bytes of address in consecutive locations */ + rslt = bmi2_set_regs(BMI2_INIT_ADDR_0, addr_array, 2, dev); if (rslt == BMI2_OK) { - /* Define the offset in bytes for low-g select */ - idx = low_g_config.start_addr; - - /* Get word to calculate threshold */ - lsb = (uint16_t) feat_config[idx++]; - msb = ((uint16_t) feat_config[idx++] << 8); - lsb_msb = lsb | msb; - - /* Get threshold */ - config->threshold = lsb_msb & BMI2_LOW_G_THRES_MASK; - - /* Get word to calculate hysteresis */ - lsb = (uint16_t) feat_config[idx++]; - msb = ((uint16_t) feat_config[idx++] << 8); - lsb_msb = lsb | msb; - - /* Get hysteresis */ - config->hysteresis = lsb_msb & BMI2_LOW_G_HYST_MASK; - - /* Get word to calculate duration and output configuration */ - lsb = (uint16_t) feat_config[idx++]; - msb = ((uint16_t) feat_config[idx++] << 8); - lsb_msb = lsb | msb; - - /* Get duration */ - config->duration = lsb_msb & BMI2_LOW_G_DUR_MASK; - - /* Get output configuration */ - config->out_conf = (lsb_msb & BMI2_LOW_G_OUT_CONF_MASK) >> BMI2_LOW_G_OUT_CONF_POS; - - /* Copy out_conf value to a local copy in device structure */ - dev->int_map.low_g_out_conf = (uint8_t) config->out_conf; + /* Burst write configuration file data corresponding to user set length */ + rslt = bmi2_set_regs(BMI2_INIT_DATA_ADDR, (uint8_t *)config_data, write_len, dev); } } else { - rslt = BMI2_E_INVALID_SENSOR; + rslt = BMI2_E_NULL_PTR; } return rslt; } /*! - * @brief This internal API gets flat configurations like theta, blocking, - * hold-time, hysteresis, and output configuration. + * @brief This internal API validates bandwidth and performance mode of the + * accelerometer set by the user. */ -static int8_t get_flat_config(struct bmi2_flat_config *config, struct bmi2_dev *dev) +static int8_t validate_bw_perf_mode(uint8_t *bandwidth, uint8_t *perf_mode, struct bmi2_dev *dev) { /* Variable to define error */ int8_t rslt; - /* Array to define the feature configuration */ - uint8_t feat_config[BMI2_FEAT_SIZE_IN_BYTES] = { 0 }; - - /* Variable to define the array offset */ - uint8_t idx = 0; - - /* Variable to define LSB */ - uint16_t lsb = 0; - - /* Variable to define MSB */ - uint16_t msb = 0; - - /* Variable to define a word */ - uint16_t lsb_msb = 0; - - /* Variable to set flag */ - uint8_t feat_found; - - /* Initialize feature configuration for flat */ - struct bmi2_feature_config flat_config = { 0, 0, 0 }; - - /* Search for flat feature and extract its configuration details */ - feat_found = bmi2_extract_input_feat_config(&flat_config, BMI2_FLAT, dev); - if (feat_found) + /* Validate and auto-correct performance mode */ + rslt = check_boundary_val(perf_mode, BMI2_POWER_OPT_MODE, BMI2_PERF_OPT_MODE, dev); + if (rslt == BMI2_OK) { - /* Get the configuration from the page where flat feature resides */ - rslt = bmi2_get_feat_config(flat_config.page, feat_config, dev); - if (rslt == BMI2_OK) + /* Validate and auto-correct bandwidth parameter */ + if (*perf_mode == BMI2_PERF_OPT_MODE) { - /* Define the offset in bytes for flat select */ - idx = flat_config.start_addr; - - /* Get word to calculate theta, blocking mode and output configuration */ - lsb = (uint16_t) feat_config[idx++]; - msb = ((uint16_t) feat_config[idx++] << 8); - lsb_msb = lsb | msb; - - /* Get theta */ - config->theta = (lsb_msb & BMI2_FLAT_THETA_MASK) >> BMI2_FLAT_THETA_POS; - - /* Get blocking mode */ - config->blocking = (lsb_msb & BMI2_FLAT_BLOCK_MASK) >> BMI2_FLAT_BLOCK_POS; - - /* Get output configuration */ - config->out_conf = (lsb_msb & BMI2_FLAT_OUT_CONF_MASK) >> BMI2_FLAT_OUT_CONF_POS; - - /* Get word to calculate hysteresis and hold-time */ - lsb = (uint16_t) feat_config[idx++]; - msb = ((uint16_t) feat_config[idx++] << 8); - lsb_msb = lsb | msb; - - /* Get hysteresis */ - config->hysteresis = lsb_msb & BMI2_FLAT_HYST_MASK; - - /* Get hold-time */ - config->hold_time = (lsb_msb & BMI2_FLAT_HOLD_TIME_MASK) >> BMI2_FLAT_HOLD_TIME_POS; - - /* Copy out_conf value to a local copy in device structure */ - dev->int_map.flat_out_conf = (uint8_t) config->out_conf; + /* Validate for continuous filter mode */ + rslt = check_boundary_val(bandwidth, BMI2_ACC_OSR4_AVG1, BMI2_ACC_CIC_AVG8, dev); + } + else + { + /* Validate for CIC averaging mode */ + rslt = check_boundary_val(bandwidth, BMI2_ACC_OSR4_AVG1, BMI2_ACC_RES_AVG128, dev); } - } - else - { - rslt = BMI2_E_INVALID_SENSOR; } return rslt; } /*! - * @brief This internal API gets external sensor sync configurations like output - * configuration. + * @brief This internal API validates ODR and range of the accelerometer set by + * the user. */ -static int8_t get_ext_sens_sync_config(struct bmi2_ext_sens_sync_config *config, struct bmi2_dev *dev) +static int8_t validate_odr_range(uint8_t *odr, uint8_t *range, struct bmi2_dev *dev) { /* Variable to define error */ int8_t rslt; - /* Array to define the feature configuration */ - uint8_t feat_config[BMI2_FEAT_SIZE_IN_BYTES] = { 0 }; - - /* Variable to define the array offset */ - uint8_t idx = 0; - - /* Variable to define LSB */ - uint16_t lsb = 0; - - /* Variable to define MSB */ - uint16_t msb = 0; - - /* Variable to define a word */ - uint16_t lsb_msb = 0; - - /* Variable to set flag */ - uint8_t feat_found; - - /* Initialize feature configuration for external sensor sync */ - struct bmi2_feature_config ext_sens_sync_config = { 0, 0, 0 }; - - /* Search for external sensor sync feature and extract its configuration details */ - feat_found = bmi2_extract_input_feat_config(&ext_sens_sync_config, BMI2_EXT_SENS_SYNC, dev); - if (feat_found) - { - /* Get the configuration from the page where external sensor sync feature resides */ - rslt = bmi2_get_feat_config(ext_sens_sync_config.page, feat_config, dev); - if (rslt == BMI2_OK) - { - /* Define the offset in bytes for external sensor sync select */ - idx = ext_sens_sync_config.start_addr; - - /* Get word to calculate output configuration */ - lsb = (uint16_t) feat_config[idx++]; - msb = ((uint16_t) feat_config[idx++] << 8); - lsb_msb = lsb | msb; - - /* Get output configuration */ - config->out_conf = (lsb_msb & BMI2_EXT_SENS_SYNC_OUT_CONF_MASK) >> BMI2_EXT_SENS_SYNC_OUT_CONF_POS; - - /* Copy out_conf value to a local copy in device structure */ - dev->int_map.ext_sync_out_conf = (uint8_t) config->out_conf; - } - } - else + /* Validate and auto correct ODR */ + rslt = check_boundary_val(odr, BMI2_ACC_ODR_0_78HZ, BMI2_ACC_ODR_1600HZ, dev); + if (rslt == BMI2_OK) { - rslt = BMI2_E_INVALID_SENSOR; + /* Validate and auto correct Range */ + rslt = check_boundary_val(range, BMI2_ACC_RANGE_2G, BMI2_ACC_RANGE_16G, dev); } return rslt; } /*! - * @brief This internal API maps/un-maps feature interrupts to that of interrupt - * pins. + * @brief This internal API validates bandwidth, performance mode, low power/ + * high performance mode, ODR, and range set by the user. */ -static int8_t map_feat_int(uint8_t *reg_data_array, enum bmi2_hw_int_pin int_pin, uint8_t int_mask) +static int8_t validate_gyro_config(struct bmi2_gyro_config *config, struct bmi2_dev *dev) { /* Variable to define error */ - int8_t rslt = BMI2_OK; + int8_t rslt; - /* Check for NULL error */ - if (reg_data_array != NULL) + /* Validate and auto-correct performance mode */ + rslt = check_boundary_val(&config->filter_perf, BMI2_POWER_OPT_MODE, BMI2_PERF_OPT_MODE, dev); + if (rslt == BMI2_OK) { - /* Check validity on interrupt pin selection */ - if (int_pin < BMI2_INT_PIN_MAX) + /* Validate and auto-correct bandwidth parameter */ + rslt = check_boundary_val(&config->bwp, BMI2_GYR_OSR4_MODE, BMI2_GYR_CIC_MODE, dev); + if (rslt == BMI2_OK) { - switch (int_pin) + /* Validate and auto-correct low power/high-performance parameter */ + rslt = check_boundary_val(&config->noise_perf, BMI2_POWER_OPT_MODE, BMI2_PERF_OPT_MODE, dev); + if (rslt == BMI2_OK) { - case BMI2_INT_NONE: - - /* Un-Map the corresponding feature interrupt to interrupt pin 1 and 2 */ - reg_data_array[0] &= ~(int_mask); - reg_data_array[1] &= ~(int_mask); - break; - case BMI2_INT1: - - /* Map the corresponding feature interrupt to interrupt pin 1 */ - reg_data_array[0] |= int_mask; - - /* Un-map the corresponding feature interrupt to interrupt pin 2 */ - reg_data_array[1] &= ~(int_mask); - break; - case BMI2_INT2: - - /* Map the corresponding feature interrupt to interrupt pin 2 */ - reg_data_array[1] |= int_mask; - - /* Un-map the corresponding feature interrupt to interrupt pin 1 */ - reg_data_array[0] &= ~(int_mask); - break; - case BMI2_INT_BOTH: - - /* Map the corresponding feature interrupt to interrupt pin 1 and 2 */ - reg_data_array[0] |= int_mask; - reg_data_array[1] |= int_mask; - break; - default: - break; + /* Validate and auto-correct ODR parameter */ + rslt = check_boundary_val(&config->odr, BMI2_GYR_ODR_25HZ, BMI2_GYR_ODR_3200HZ, dev); + if (rslt == BMI2_OK) + { + /* Validate and auto-correct OIS range */ + rslt = check_boundary_val(&config->ois_range, BMI2_GYR_OIS_250, BMI2_GYR_OIS_2000, dev); + if (rslt == BMI2_OK) + { + /* Validate and auto-correct range parameter */ + rslt = check_boundary_val(&config->range, BMI2_GYR_RANGE_2000, BMI2_GYR_RANGE_125, dev); + } + } } } - else - { - /* Return error if invalid pin selection */ - rslt = BMI2_E_INVALID_INT_PIN; - } - } - else - { - rslt = BMI2_E_NULL_PTR; } return rslt; } /*! - * @brief This internal API gets the accelerometer data from the register. + * @brief This internal API shows the error status when illegal sensor + * configuration is set. */ -static int8_t get_accel_sensor_data(struct bmi2_sens_axes_data *data, uint8_t reg_addr, struct bmi2_dev *dev) +static int8_t cfg_error_status(struct bmi2_dev *dev) { /* Variable to define error */ int8_t rslt; - /* Array to define data stored in register */ - uint8_t reg_data[BMI2_ACC_GYR_NUM_BYTES] = { 0 }; + /* Variable to store data */ + uint8_t reg_data; - /* Read the sensor data */ - rslt = bmi2_get_regs(reg_addr, reg_data, BMI2_ACC_GYR_NUM_BYTES, dev); + /* Get error status of the set sensor configuration */ + rslt = bmi2_get_regs(BMI2_EVENT_ADDR, ®_data, 1, dev); if (rslt == BMI2_OK) { - /* Get accelerometer data from the register */ - get_acc_gyr_data(data, reg_data); - - /* Get the re-mapped accelerometer data */ - get_remapped_data(data, dev); + reg_data = BMI2_GET_BITS(reg_data, BMI2_EVENT_FLAG); + switch (reg_data) + { + case BMI2_NO_ERROR: + rslt = BMI2_OK; + break; + case BMI2_ACC_ERROR: + rslt = BMI2_E_ACC_INVALID_CFG; + break; + case BMI2_GYR_ERROR: + rslt = BMI2_E_GYRO_INVALID_CFG; + break; + case BMI2_ACC_GYR_ERROR: + rslt = BMI2_E_ACC_GYR_INVALID_CFG; + break; + default: + break; + } } return rslt; } /*! - * @brief This internal API gets the gyroscope data from the register. + * @brief This internal API: + * 1) Enables/Disables auxiliary interface. + * 2) Sets auxiliary interface configurations like I2C address, manual/auto + * mode enable, manual burst read length, AUX burst read length and AUX read + * address. + * 3)It maps/un-maps data interrupts to that of hardware interrupt line. */ -static int8_t get_gyro_sensor_data(struct bmi2_sens_axes_data *data, uint8_t reg_addr, struct bmi2_dev *dev) +static int8_t set_aux_config(struct bmi2_aux_config *config, struct bmi2_dev *dev) { /* Variable to define error */ int8_t rslt; - /* Array to define data stored in register */ - uint8_t reg_data[BMI2_ACC_GYR_NUM_BYTES] = { 0 }; - - /* Read the sensor data */ - rslt = bmi2_get_regs(reg_addr, reg_data, BMI2_ACC_GYR_NUM_BYTES, dev); + /* Validate auxiliary configurations */ + rslt = validate_aux_config(config, dev); if (rslt == BMI2_OK) { - /* Get gyroscope data from the register */ - get_acc_gyr_data(data, reg_data); - - /* Get the compensated gyroscope data */ - comp_gyro_cross_axis_sensitivity(data, dev); - - /* Get the re-mapped gyroscope data */ - get_remapped_data(data, dev); - + /* Enable/Disable auxiliary interface */ + rslt = set_aux_interface(config, dev); + if (rslt == BMI2_OK) + { + /* Set the auxiliary interface configurations */ + rslt = config_aux_interface(config, dev); + if (rslt == BMI2_OK) + { + /* Set read out offset and ODR */ + rslt = config_aux(config, dev); + } + } } return rslt; } /*! - * @brief This internal API gets the accelerometer/gyroscope data. + * @brief This internal API sets gyroscope user-gain configurations like gain + * update value for x, y and z-axis. */ -static void get_acc_gyr_data(struct bmi2_sens_axes_data *data, const uint8_t *reg_data) +static int8_t set_gyro_user_gain_config(const struct bmi2_gyro_user_gain_config *config, struct bmi2_dev *dev) { - /* Variables to store msb value */ - uint8_t msb; + /* Variable to define error */ + int8_t rslt; - /* Variables to store lsb value */ - uint8_t lsb; + /* Array to define the feature configuration */ + uint8_t feat_config[BMI2_FEAT_SIZE_IN_BYTES] = { 0 }; - /* Variables to store both msb and lsb value */ - uint16_t msb_lsb; + /* Variable to define the array offset */ + uint8_t idx = 0; + + /* Variable to define index */ + uint8_t index = 0; + + /* Variable to set flag */ + uint8_t feat_found; + + /* Initialize feature configuration for user-gain */ + struct bmi2_feature_config user_gain_config = { 0, 0, 0 }; + + /* Copy the feature configuration address to a local pointer */ + uint16_t *data_p = (uint16_t *) (void *)feat_config; + + /* Search for user-gain feature and extract its configuration details */ + feat_found = bmi2_extract_input_feat_config(&user_gain_config, BMI2_GYRO_GAIN_UPDATE, dev); + if (feat_found) + { + /* Get the configuration from the page where user-gain feature resides */ + rslt = bmi2_get_feat_config(user_gain_config.page, feat_config, dev); + if (rslt == BMI2_OK) + { + /* Define the offset in bytes for user-gain select */ + idx = user_gain_config.start_addr; + + /* Get offset in words since all the features are set in words length */ + idx = idx / 2; + + /* Set ratio_x */ + *(data_p + idx) = BMI2_SET_BIT_POS0(*(data_p + idx), BMI2_GYR_USER_GAIN_RATIO_X, config->ratio_x); + + /* Increment offset by 1 word to set ratio_y */ + idx++; + + /* Set ratio_y */ + *(data_p + idx) = BMI2_SET_BIT_POS0(*(data_p + idx), BMI2_GYR_USER_GAIN_RATIO_Y, config->ratio_y); + + /* Increment offset by 1 word to set ratio_z */ + idx++; + + /* Set ratio_z */ + *(data_p + idx) = BMI2_SET_BIT_POS0(*(data_p + idx), BMI2_GYR_USER_GAIN_RATIO_Z, config->ratio_z); + + /* Increment offset by 1 more word to get the total length in words */ + idx++; - /* Variables to define index */ - uint8_t index = 0; + /* Get total length in bytes to copy from local pointer to the array */ + idx = (uint8_t)(idx * 2) - user_gain_config.start_addr; - /* Read x-axis data */ - lsb = reg_data[index++]; - msb = reg_data[index++]; - msb_lsb = ((uint16_t) msb << 8) | (uint16_t) lsb; - data->x = (int16_t) msb_lsb; + /* Copy the bytes to be set back to the array */ + for (index = 0; index < idx; index++) + { + feat_config[user_gain_config.start_addr + + index] = *((uint8_t *) data_p + user_gain_config.start_addr + index); + } - /* Read y-axis data */ - lsb = reg_data[index++]; - msb = reg_data[index++]; - msb_lsb = ((uint16_t) msb << 8) | (uint16_t) lsb; - data->y = (int16_t) msb_lsb; + /* Set the configuration back to the page */ + rslt = bmi2_set_regs(BMI2_FEATURES_REG_ADDR, feat_config, BMI2_FEAT_SIZE_IN_BYTES, dev); + } + } + else + { + rslt = BMI2_E_INVALID_SENSOR; + } - /* Read z-axis data */ - lsb = reg_data[index++]; - msb = reg_data[index++]; - msb_lsb = ((uint16_t) msb << 8) | (uint16_t) lsb; - data->z = (int16_t) msb_lsb; + return rslt; } /*! - * @brief This internal API gets the re-mapped accelerometer/gyroscope data. + * @brief This internal API enables/disables auxiliary interface. */ -static void get_remapped_data(struct bmi2_sens_axes_data *data, const struct bmi2_dev *dev) +static int8_t set_aux_interface(const struct bmi2_aux_config *config, struct bmi2_dev *dev) { - /* Array to defined the re-mapped sensor data */ - int16_t remap_data[3] = { 0 }; - int16_t pos_multiplier = INT16_C(1); - int16_t neg_multiplier = INT16_C(-1); + /* Variable to define error */ + int8_t rslt; - /* Fill the array with the un-mapped sensor data */ - remap_data[0] = data->x; - remap_data[1] = data->y; - remap_data[2] = data->z; + /* Variable to store data */ + uint8_t reg_data; - /* Get the re-mapped x axis data */ - if (dev->remap.x_axis_sign == BMI2_POS_SIGN) - { - data->x = (int16_t)(remap_data[dev->remap.x_axis] * pos_multiplier); - } - else + rslt = bmi2_get_regs(BMI2_IF_CONF_ADDR, ®_data, 1, dev); + if (rslt == BMI2_OK) { - data->x = (int16_t)(remap_data[dev->remap.x_axis] * neg_multiplier); - } + reg_data = BMI2_SET_BITS(reg_data, BMI2_AUX_IF_EN, config->aux_en); - /* Get the re-mapped y axis data */ - if (dev->remap.y_axis_sign == BMI2_POS_SIGN) - { - data->y = (int16_t)(remap_data[dev->remap.y_axis] * pos_multiplier); - } - else - { - data->y = (int16_t)(remap_data[dev->remap.y_axis] * neg_multiplier); + /* Enable/Disable auxiliary interface */ + rslt = bmi2_set_regs(BMI2_IF_CONF_ADDR, ®_data, 1, dev); } - /* Get the re-mapped z axis data */ - if (dev->remap.z_axis_sign == BMI2_POS_SIGN) - { - data->z = (int16_t)(remap_data[dev->remap.z_axis] * pos_multiplier); - } - else - { - data->z = (int16_t)(remap_data[dev->remap.z_axis] * neg_multiplier); - } + return rslt; } /*! - * @brief This internal API reads the user-defined bytes of data from the given - * register address of auxiliary sensor in manual mode. + * @brief This internal API sets auxiliary configurations like manual/auto mode + * FCU write command enable and read burst length for both data and manual mode. + * + * @note Auxiliary sensor should not be busy when configuring aux_i2c_addr, + * man_rd_burst_len, aux_rd_burst_len and aux_rd_addr. */ -static int8_t read_aux_data(uint8_t reg_addr, uint8_t *aux_data, uint16_t len, uint8_t burst_len, struct bmi2_dev *dev) +static int8_t config_aux_interface(const struct bmi2_aux_config *config, struct bmi2_dev *dev) { /* Variable to define error */ - int8_t rslt = BMI2_OK; - - /* Array to store the register data */ - uint8_t reg_data[15] = { 0 }; + int8_t rslt; - /* Variable to define number of bytes to read */ - uint16_t read_length = 0; + /* Variable to store data */ + uint8_t reg_data[2] = { 0 }; - /* Variable to define loop */ - uint8_t loop = 0; + /* Variable to store status */ + uint8_t status = 0; - /* Variable to define counts to get the correct array index */ + /* Variable to define count */ uint8_t count = 0; - /* Variable to define index for the array */ - uint8_t idx = 0; - - while (len > 0) + rslt = bmi2_get_regs(BMI2_AUX_DEV_ID_ADDR, reg_data, 2, dev); + if (rslt == BMI2_OK) { - /* Set the read address if AUX is not busy */ - rslt = set_if_aux_not_busy(BMI2_AUX_RD_ADDR, reg_addr, dev); - if (rslt == BMI2_OK) + /* Set I2C address for AUX sensor */ + reg_data[0] = BMI2_SET_BITS(reg_data[0], BMI2_AUX_SET_I2C_ADDR, config->i2c_device_addr); + + /* Set the AUX IF to either manual or auto mode */ + reg_data[1] = BMI2_SET_BITS(reg_data[1], BMI2_AUX_MAN_MODE_EN, config->manual_en); + + /* Enables FCU write command on AUX IF for auxiliary sensors that need a trigger */ + reg_data[1] = BMI2_SET_BITS(reg_data[1], BMI2_AUX_FCU_WR_EN, config->fcu_write_en); + + /* Set the burst read length for manual mode */ + reg_data[1] = BMI2_SET_BITS(reg_data[1], BMI2_AUX_MAN_READ_BURST, config->man_rd_burst); + + /* Set the burst read length for data mode */ + reg_data[1] = BMI2_SET_BIT_POS0(reg_data[1], BMI2_AUX_READ_BURST, config->aux_rd_burst); + for (;;) { - /* Read data from bmi2 data register */ - rslt = bmi2_get_regs(BMI2_AUX_X_LSB_ADDR, reg_data, (uint16_t) burst_len, dev); - dev->delay_us(1000, dev->intf_ptr); - if (rslt == BMI2_OK) + /* Check if auxiliary sensor is busy */ + rslt = bmi2_get_status(&status, dev); + if ((rslt == BMI2_OK) && (!(status & BMI2_AUX_BUSY))) { - /* Get number of bytes to be read */ - if (len < burst_len) - { - read_length = (uint8_t) len; - } - else + /* Set the configurations if AUX is not busy */ + rslt = bmi2_set_regs(BMI2_AUX_DEV_ID_ADDR, reg_data, 2, dev); + dev->delay_us(1000, dev->intf_ptr); + if (rslt == BMI2_OK) { - read_length = burst_len; - } + /* If data mode */ + if (!config->manual_en) + { + /* Disable manual enable flag in device structure */ + dev->aux_man_en = 0; - /* Update array index and store the data */ - for (loop = 0; loop < read_length; loop++) - { - idx = loop + count; - aux_data[idx] = reg_data[loop]; + /* Set the read address of the AUX sensor */ + rslt = bmi2_set_regs(BMI2_AUX_RD_ADDR, (uint8_t *) &config->read_addr, 1, dev); + dev->delay_us(1000, dev->intf_ptr); + } + else + { + /* Enable manual enable flag in device structure */ + dev->aux_man_en = 1; + + /* Update manual read burst length in device structure */ + dev->aux_man_rd_burst_len = config->man_rd_burst; + } } - } - } - /* Update address for the next read */ - reg_addr += burst_len; + /* Break after setting the register */ + break; + } - /* Update count for the array index */ - count += burst_len; + /* Increment count after every 10 seconds */ + dev->delay_us(10000, dev->intf_ptr); + count++; - /* Update no of bytes left to read */ - len -= read_length; + /* Break after 2 seconds if AUX still busy - since slowest ODR is 0.78Hz*/ + if (count > 20) + { + rslt = BMI2_E_AUX_BUSY; + break; + } + } } return rslt; } /*! - * @brief This internal API writes AUX write address and the user-defined bytes - * of data to the AUX sensor in manual mode. - * - * @note Change of BMI2_AUX_WR_ADDR is only allowed if AUX is not busy. + * @brief This internal API triggers read out offset and sets ODR of the + * auxiliary sensor. */ -static int8_t write_aux_data(uint8_t reg_addr, uint8_t reg_data, struct bmi2_dev *dev) +static int8_t config_aux(const struct bmi2_aux_config *config, struct bmi2_dev *dev) { /* Variable to define error */ int8_t rslt; - /* Write data to be written to the AUX sensor in bmi2 register */ - rslt = bmi2_set_regs(BMI2_AUX_WR_DATA_ADDR, ®_data, 1, dev); + /* Variable to store data */ + uint8_t reg_data; + + rslt = bmi2_get_regs(BMI2_AUX_CONF_ADDR, ®_data, 1, dev); if (rslt == BMI2_OK) { - /* Write the AUX address where data is to be stored when AUX is not busy */ - rslt = set_if_aux_not_busy(BMI2_AUX_WR_ADDR, reg_addr, dev); + /* Trigger read out offset */ + reg_data = BMI2_SET_BITS(reg_data, BMI2_AUX_OFFSET_READ_OUT, config->offset); + + /* Set ODR */ + reg_data = BMI2_SET_BIT_POS0(reg_data, BMI2_AUX_ODR_EN, config->odr); + + /* Set auxiliary configuration register */ + rslt = bmi2_set_regs(BMI2_AUX_CONF_ADDR, ®_data, 1, dev); + dev->delay_us(1000, dev->intf_ptr); } return rslt; } /*! - * @brief This internal API reads the user-defined bytes of data from the given - * register address of auxiliary sensor in data mode. + * @brief This internal API checks the busy status of auxiliary sensor and sets + * the auxiliary register addresses when not busy. */ -static int8_t read_aux_data_mode(uint8_t *aux_data, struct bmi2_dev *dev) +static int8_t set_if_aux_not_busy(uint8_t reg_addr, uint8_t reg_data, struct bmi2_dev *dev) { /* Variable to define error */ int8_t rslt; - /* Variables to define loop */ + /* Variable to get status of AUX_BUSY */ + uint8_t status = 0; + + /* Variable to define count for time-out */ uint8_t count = 0; - /* Variables to define index */ - uint8_t index = 0; + for (;;) + { + /* Check if AUX is busy */ + rslt = bmi2_get_status(&status, dev); - /* Array to define data stored in register */ - uint8_t reg_data[BMI2_AUX_NUM_BYTES] = { 0 }; + /* Set the registers if not busy */ + if ((rslt == BMI2_OK) && (!(status & BMI2_AUX_BUSY))) + { + rslt = bmi2_set_regs(reg_addr, ®_data, 1, dev); + dev->delay_us(1000, dev->intf_ptr); - /* Check if data mode */ - if (!dev->aux_man_en) - { - /* Read the auxiliary sensor data */ - rslt = bmi2_get_regs(BMI2_AUX_X_LSB_ADDR, reg_data, BMI2_AUX_NUM_BYTES, dev); - if (rslt == BMI2_OK) + /* Break after setting the register */ + break; + } + + /* Increment count after every 10 seconds */ + dev->delay_us(10000, dev->intf_ptr); + count++; + + /* Break after 2 seconds if AUX still busy - since slowest ODR is 0.78Hz*/ + if (count > 20) { - /* Get the 8 bytes of auxiliary data */ - do - { - *(aux_data + count++) = *(reg_data + index++); - } while (count < BMI2_AUX_NUM_BYTES); + rslt = BMI2_E_AUX_BUSY; + break; } } - else - { - rslt = BMI2_E_AUX_INVALID_CFG; - } return rslt; } /*! - * @brief This internal API maps the actual burst read length with that of the - * register value set by user. + * @brief This internal API validates auxiliary configuration set by the user. */ -static int8_t map_read_len(uint8_t *len, const struct bmi2_dev *dev) +static int8_t validate_aux_config(struct bmi2_aux_config *config, struct bmi2_dev *dev) { /* Variable to define error */ - int8_t rslt = BMI2_OK; + int8_t rslt; - /* Get the burst read length against the values set by the user */ - switch (dev->aux_man_rd_burst_len) - { - case BMI2_AUX_READ_LEN_0: - *len = 1; - break; - case BMI2_AUX_READ_LEN_1: - *len = 2; - break; - case BMI2_AUX_READ_LEN_2: - *len = 6; - break; - case BMI2_AUX_READ_LEN_3: - *len = 8; - break; - default: - rslt = BMI2_E_AUX_INVALID_CFG; - break; - } + /* Validate ODR for auxiliary sensor */ + rslt = check_boundary_val(&config->odr, BMI2_AUX_ODR_0_78HZ, BMI2_AUX_ODR_800HZ, dev); return rslt; } /*! - * @brief This internal API gets the output values of step counter. + * @brief This internal API gets accelerometer configurations like ODR, + * bandwidth, performance mode and g-range. */ -static int8_t get_step_counter_output(uint32_t *step_count, struct bmi2_dev *dev) +static int8_t get_accel_config(struct bmi2_accel_config *config, struct bmi2_dev *dev) { /* Variable to define error */ int8_t rslt; - /* Array to define the feature configuration */ - uint8_t feat_config[BMI2_FEAT_SIZE_IN_BYTES] = { 0 }; - - /* Variables to define index */ - uint8_t idx = 0; - - /* Variable to set flag */ - uint8_t feat_found; - - /* Initialize feature output for step counter */ - struct bmi2_feature_config step_cnt_out_config = { 0, 0, 0 }; + /* Array to store data */ + uint8_t data_array[2] = { 0 }; - /* Search for step counter output feature and extract its configuration details */ - feat_found = extract_output_feat_config(&step_cnt_out_config, BMI2_STEP_COUNTER, dev); - if (feat_found) + /* Null-pointer check */ + rslt = null_ptr_check(dev); + if ((rslt == BMI2_OK) && (config != NULL)) { - /* Get the feature output configuration for step-counter */ - rslt = bmi2_get_feat_config(step_cnt_out_config.page, feat_config, dev); + /* Read the sensor configuration details */ + rslt = bmi2_get_regs(BMI2_ACC_CONF_ADDR, data_array, 2, dev); if (rslt == BMI2_OK) { - /* Define the offset in bytes for step counter output */ - idx = step_cnt_out_config.start_addr; - - /* Get the step counter output in 4 bytes */ - *step_count = (uint32_t) feat_config[idx++]; - *step_count |= ((uint32_t) feat_config[idx++] << 8); - *step_count |= ((uint32_t) feat_config[idx++] << 16); - *step_count |= ((uint32_t) feat_config[idx++] << 24); + /* Get accelerometer performance mode */ + config->filter_perf = BMI2_GET_BITS(data_array[0], BMI2_ACC_FILTER_PERF_MODE); + + /* Get accelerometer bandwidth */ + config->bwp = BMI2_GET_BITS(data_array[0], BMI2_ACC_BW_PARAM); + + /* Get accelerometer ODR */ + config->odr = BMI2_GET_BIT_POS0(data_array[0], BMI2_ACC_ODR); + + /* Get accelerometer range */ + config->range = BMI2_GET_BIT_POS0(data_array[1], BMI2_ACC_RANGE); } } else { - rslt = BMI2_E_INVALID_SENSOR; + rslt = BMI2_E_NULL_PTR; } return rslt; } /*! - * @brief This internal API gets the output values of step activity. + * @brief This internal API gets gyroscope configurations like ODR, bandwidth, + * low power/high performance mode, performance mode and range. */ -static int8_t get_step_activity_output(uint8_t *step_act, struct bmi2_dev *dev) +static int8_t get_gyro_config(struct bmi2_gyro_config *config, struct bmi2_dev *dev) { /* Variable to define error */ int8_t rslt; - /* Array to define the feature configuration */ - uint8_t feat_config[BMI2_FEAT_SIZE_IN_BYTES] = { 0 }; - - /* Variables to define index */ - uint8_t idx = 0; - - /* Variable to set flag */ - uint8_t feat_found; - - /* Initialize feature output for step activity */ - struct bmi2_feature_config step_act_out_config = { 0, 0, 0 }; + /* Array to store data */ + uint8_t data_array[2] = { 0 }; - /* Search for step activity output feature and extract its configuration details */ - feat_found = extract_output_feat_config(&step_act_out_config, BMI2_STEP_ACTIVITY, dev); - if (feat_found) + /* Null-pointer check */ + rslt = null_ptr_check(dev); + if ((rslt == BMI2_OK) && (config != NULL)) { - /* Get the feature output configuration for step-activity */ - rslt = bmi2_get_feat_config(step_act_out_config.page, feat_config, dev); + /* Read the sensor configuration details */ + rslt = bmi2_get_regs(BMI2_GYR_CONF_ADDR, data_array, 2, dev); if (rslt == BMI2_OK) { - /* Define the offset in bytes for step activity output */ - idx = step_act_out_config.start_addr; + /* Get gyroscope performance mode */ + config->filter_perf = BMI2_GET_BITS(data_array[0], BMI2_GYR_FILTER_PERF_MODE); + + /* Get gyroscope noise performance mode */ + config->noise_perf = BMI2_GET_BITS(data_array[0], BMI2_GYR_NOISE_PERF_MODE); + + /* Get gyroscope bandwidth */ + config->bwp = BMI2_GET_BITS(data_array[0], BMI2_GYR_BW_PARAM); + + /* Get gyroscope ODR */ + config->odr = BMI2_GET_BIT_POS0(data_array[0], BMI2_GYR_ODR); - /* Get the step activity output */ - *step_act = feat_config[idx]; + /* Get gyroscope OIS range */ + config->ois_range = BMI2_GET_BITS(data_array[1], BMI2_GYR_OIS_RANGE); + + /* Get gyroscope range */ + config->range = BMI2_GET_BIT_POS0(data_array[1], BMI2_GYR_RANGE); } } else { - rslt = BMI2_E_INVALID_SENSOR; + rslt = BMI2_E_NULL_PTR; } return rslt; } /*! - * @brief This internal API gets the output values of orientation: portrait- - * landscape and face up-down. + * @brief This internal API: + * 1) Gets the status of auxiliary interface enable. + * 2) Gets auxiliary interface configurations like I2C address, manual/auto + * mode enable, manual burst read length, AUX burst read length and AUX read + * address. + * 3) Gets ODR and offset. */ -static int8_t get_orient_output(struct bmi2_orientation_output *orient_out, struct bmi2_dev *dev) +static int8_t get_aux_config(struct bmi2_aux_config *config, struct bmi2_dev *dev) { /* Variable to define error */ int8_t rslt; - /* Array to define the feature configuration */ - uint8_t feat_config[BMI2_FEAT_SIZE_IN_BYTES] = { 0 }; - - /* Variables to define index */ - uint8_t idx = 0; - - /* Variable to set flag */ - uint8_t feat_found; - - /* Initialize feature output for orientation */ - struct bmi2_feature_config orient_out_config = { 0, 0, 0 }; - - /* Search for orientation output feature and extract its configuration details */ - feat_found = extract_output_feat_config(&orient_out_config, BMI2_ORIENTATION, dev); - if (feat_found) + /* Null-pointer check */ + rslt = null_ptr_check(dev); + if ((rslt == BMI2_OK) && (config != NULL)) { - /* Get the feature output configuration for orientation */ - rslt = bmi2_get_feat_config(orient_out_config.page, feat_config, dev); + /* Get enable status of auxiliary interface */ + rslt = get_aux_interface(config, dev); if (rslt == BMI2_OK) { - /* Define the offset in bytes for orientation output */ - idx = orient_out_config.start_addr; - - /* Get the output value of the orientation detection feature */ - orient_out->portrait_landscape = BMI2_GET_BIT_POS0(feat_config[idx], BMI2_ORIENT_DETECT); - - /* Get the output value of the orientation face up-down feature */ - orient_out->faceup_down = BMI2_GET_BITS(feat_config[idx], BMI2_ORIENT_FACE_UP_DWN); + /* Get the auxiliary interface configurations */ + rslt = get_aux_interface_config(config, dev); + if (rslt == BMI2_OK) + { + /* Get read out offset and ODR */ + rslt = get_aux_cfg(config, dev); + } } } else { - rslt = BMI2_E_INVALID_SENSOR; + rslt = BMI2_E_NULL_PTR; } return rslt; } /*! - * @brief This internal API gets the output values of high-g. + * @brief This internal API gets gyroscope user-gain configurations like gain + * update value for x, y and z-axis. */ -static int8_t get_high_g_output(uint8_t *high_g_out, struct bmi2_dev *dev) +static int8_t get_gyro_gain_update_config(struct bmi2_gyro_user_gain_config *config, struct bmi2_dev *dev) { /* Variable to define error */ int8_t rslt; @@ -14823,28 +5576,58 @@ static int8_t get_high_g_output(uint8_t *high_g_out, struct bmi2_dev *dev) /* Array to define the feature configuration */ uint8_t feat_config[BMI2_FEAT_SIZE_IN_BYTES] = { 0 }; - /* Variables to define index */ + /* Variable to define the array offset */ uint8_t idx = 0; + /* Variable to define LSB */ + uint16_t lsb = 0; + + /* Variable to define MSB */ + uint16_t msb = 0; + + /* Variable to define a word */ + uint16_t lsb_msb = 0; + /* Variable to set flag */ uint8_t feat_found; - /* Initialize feature output for high-g */ - struct bmi2_feature_config high_g_out_config = { 0, 0, 0 }; + /* Initialize feature configuration for user-gain */ + struct bmi2_feature_config user_gain_config = { 0, 0, 0 }; - /* Search for high-g output feature and extract its configuration details */ - feat_found = extract_output_feat_config(&high_g_out_config, BMI2_HIGH_G, dev); + /* Search for user-gain feature and extract its configuration details */ + feat_found = bmi2_extract_input_feat_config(&user_gain_config, BMI2_GYRO_GAIN_UPDATE, dev); if (feat_found) { - /* Get the feature output configuration for high-g */ - rslt = bmi2_get_feat_config(high_g_out_config.page, feat_config, dev); + /* Get the configuration from the page where user-gain feature resides */ + rslt = bmi2_get_feat_config(user_gain_config.page, feat_config, dev); if (rslt == BMI2_OK) { - /* Define the offset in bytes for high-g output */ - idx = high_g_out_config.start_addr; + /* Define the offset in bytes for user-gain select */ + idx = user_gain_config.start_addr; + + /* Get word to calculate ratio_x */ + lsb = (uint16_t) feat_config[idx++]; + msb = ((uint16_t) feat_config[idx++] << 8); + lsb_msb = lsb | msb; + + /* Get ratio_x */ + config->ratio_x = lsb_msb & BMI2_GYR_USER_GAIN_RATIO_X_MASK; + + /* Get word to calculate ratio_y */ + lsb = (uint16_t) feat_config[idx++]; + msb = ((uint16_t) feat_config[idx++] << 8); + lsb_msb = lsb | msb; + + /* Get ratio_y */ + config->ratio_y = lsb_msb & BMI2_GYR_USER_GAIN_RATIO_Y_MASK; + + /* Get word to calculate ratio_z */ + lsb = (uint16_t) feat_config[idx++]; + msb = ((uint16_t) feat_config[idx++] << 8); + lsb_msb = lsb | msb; - /* Get the high-g output byte */ - *high_g_out = feat_config[idx]; + /* Get ratio_z */ + config->ratio_z = lsb_msb & BMI2_GYR_USER_GAIN_RATIO_Z_MASK; } } else @@ -14856,391 +5639,446 @@ static int8_t get_high_g_output(uint8_t *high_g_out, struct bmi2_dev *dev) } /*! - * @brief This internal API gets the saturation status for the gyroscope user - * gain update. + * @brief This internal API gets the enable status of auxiliary interface. */ -static int8_t get_gyro_gain_update_status(struct bmi2_gyr_user_gain_status *user_gain_stat, struct bmi2_dev *dev) +static int8_t get_aux_interface(struct bmi2_aux_config *config, struct bmi2_dev *dev) { /* Variable to define error */ int8_t rslt; - /* Array to define the feature configuration */ - uint8_t feat_config[BMI2_FEAT_SIZE_IN_BYTES] = { 0 }; + /* Variable to store data */ + uint8_t reg_data; - /* Variables to define index */ - uint8_t idx = 0; + /* Get the enable status of auxiliary interface */ + rslt = bmi2_get_regs(BMI2_IF_CONF_ADDR, ®_data, 1, dev); + if (rslt == BMI2_OK) + { + config->aux_en = BMI2_GET_BITS(reg_data, BMI2_AUX_IF_EN); + } - /* Variable to set flag */ - uint8_t feat_found; + return rslt; +} - /* Initialize feature output for gyroscope user gain status */ - struct bmi2_feature_config user_gain_cfg = { 0, 0, 0 }; +/*! + * @brief This internal API gets auxiliary configurations like manual/auto mode + * FCU write command enable and read burst length for both data and manual mode. + */ +static int8_t get_aux_interface_config(struct bmi2_aux_config *config, struct bmi2_dev *dev) +{ + /* Variable to define error */ + int8_t rslt; - /* Search for gyroscope user gain status output feature and extract its - * configuration details - */ - feat_found = extract_output_feat_config(&user_gain_cfg, BMI2_GYRO_GAIN_UPDATE, dev); - if (feat_found) + /* Variable to store data */ + uint8_t reg_data[2] = { 0 }; + + rslt = bmi2_get_regs(BMI2_AUX_DEV_ID_ADDR, reg_data, 2, dev); + if (rslt == BMI2_OK) { - /* Get the feature output configuration for gyroscope user gain status */ - rslt = bmi2_get_feat_config(user_gain_cfg.page, feat_config, dev); - if (rslt == BMI2_OK) - { - /* Define the offset in bytes for gyroscope user gain status */ - idx = user_gain_cfg.start_addr; + /* Get I2C address for auxiliary sensor */ + config->i2c_device_addr = BMI2_GET_BITS(reg_data[0], BMI2_AUX_SET_I2C_ADDR); - /* Get the saturation status for x-axis */ - user_gain_stat->sat_x = BMI2_GET_BIT_POS0(feat_config[idx], BMI2_GYR_USER_GAIN_SAT_STAT_X); + /* Get the AUX IF to either manual or auto mode */ + config->manual_en = BMI2_GET_BITS(reg_data[1], BMI2_AUX_MAN_MODE_EN); - /* Get the saturation status for y-axis */ - user_gain_stat->sat_y = BMI2_GET_BITS(feat_config[idx], BMI2_GYR_USER_GAIN_SAT_STAT_Y); + /* Enables FCU write command on AUX IF for auxiliary sensors that need a trigger */ + config->fcu_write_en = BMI2_GET_BITS(reg_data[1], BMI2_AUX_FCU_WR_EN); - /* Get the saturation status for z-axis */ - user_gain_stat->sat_z = BMI2_GET_BITS(feat_config[idx], BMI2_GYR_USER_GAIN_SAT_STAT_Z); + /* Get the burst read length for manual mode */ + config->man_rd_burst = BMI2_GET_BITS(reg_data[1], BMI2_AUX_MAN_READ_BURST); - /* Get g trigger status */ - user_gain_stat->g_trigger_status = BMI2_GET_BITS(feat_config[idx], BMI2_G_TRIGGER_STAT); + /* Get the burst read length for data mode */ + config->aux_rd_burst = BMI2_GET_BIT_POS0(reg_data[1], BMI2_AUX_READ_BURST); + + /* If data mode, get the read address of the auxiliary sensor from where data is to be read */ + if (!config->manual_en) + { + rslt = bmi2_get_regs(BMI2_AUX_RD_ADDR, &config->read_addr, 1, dev); } } - else - { - rslt = BMI2_E_INVALID_SENSOR; - } return rslt; } /*! - * @brief This internal API gets the error status related to NVM. + * @brief This internal API gets read out offset and ODR of the auxiliary + * sensor. */ -static int8_t get_nvm_error_status(struct bmi2_nvm_err_status *nvm_err_stat, struct bmi2_dev *dev) +static int8_t get_aux_cfg(struct bmi2_aux_config *config, struct bmi2_dev *dev) { /* Variable to define error */ int8_t rslt; - /* Array to define the feature configuration */ - uint8_t feat_config[BMI2_FEAT_SIZE_IN_BYTES] = { 0 }; + /* Variable to store data */ + uint8_t reg_data; - /* Variables to define index */ - uint8_t idx = 0; + rslt = bmi2_get_regs(BMI2_AUX_CONF_ADDR, ®_data, 1, dev); + if (rslt == BMI2_OK) + { + /* Get read out offset */ + config->offset = BMI2_GET_BITS(reg_data, BMI2_AUX_OFFSET_READ_OUT); - /* Variable to set flag */ - uint8_t feat_found; + /* Get ODR */ + config->odr = BMI2_GET_BIT_POS0(reg_data, BMI2_AUX_ODR_EN); + } - /* Initialize feature output for NVM error status */ - struct bmi2_feature_config nvm_err_cfg = { 0, 0, 0 }; + return rslt; +} - /* Search for NVM error status feature and extract its configuration details */ - feat_found = extract_output_feat_config(&nvm_err_cfg, BMI2_NVM_STATUS, dev); - if (feat_found) +/*! + * @brief This internal API maps/un-maps feature interrupts to that of interrupt + * pins. + */ +static int8_t map_feat_int(uint8_t *reg_data_array, enum bmi2_hw_int_pin int_pin, uint8_t int_mask) +{ + /* Variable to define error */ + int8_t rslt = BMI2_OK; + + /* Check for NULL error */ + if (reg_data_array != NULL) { - /* Get the feature output configuration for NVM error status */ - rslt = bmi2_get_feat_config(nvm_err_cfg.page, feat_config, dev); - if (rslt == BMI2_OK) + /* Check validity on interrupt pin selection */ + if (int_pin < BMI2_INT_PIN_MAX) { - /* Define the offset in bytes for NVM error status */ - idx = nvm_err_cfg.start_addr; + switch (int_pin) + { + case BMI2_INT_NONE: - /* Increment index to get the error status */ - idx++; + /* Un-Map the corresponding feature interrupt to interrupt pin 1 and 2 */ + reg_data_array[0] &= ~(int_mask); + reg_data_array[1] &= ~(int_mask); + break; + case BMI2_INT1: - /* Error when NVM load action fails */ - nvm_err_stat->load_error = BMI2_GET_BIT_POS0(feat_config[idx], BMI2_NVM_LOAD_ERR_STATUS); + /* Map the corresponding feature interrupt to interrupt pin 1 */ + reg_data_array[0] |= int_mask; - /* Error when NVM program action fails */ - nvm_err_stat->prog_error = BMI2_GET_BITS(feat_config[idx], BMI2_NVM_PROG_ERR_STATUS); + /* Un-map the corresponding feature interrupt to interrupt pin 2 */ + reg_data_array[1] &= ~(int_mask); + break; + case BMI2_INT2: - /* Error when NVM erase action fails */ - nvm_err_stat->erase_error = BMI2_GET_BITS(feat_config[idx], BMI2_NVM_ERASE_ERR_STATUS); + /* Map the corresponding feature interrupt to interrupt pin 2 */ + reg_data_array[1] |= int_mask; - /* Error when NVM program limit is exceeded */ - nvm_err_stat->exceed_error = BMI2_GET_BITS(feat_config[idx], BMI2_NVM_END_EXCEED_STATUS); + /* Un-map the corresponding feature interrupt to interrupt pin 1 */ + reg_data_array[0] &= ~(int_mask); + break; + case BMI2_INT_BOTH: - /* Error when NVM privilege mode is not acquired */ - nvm_err_stat->privil_error = BMI2_GET_BITS(feat_config[idx], BMI2_NVM_PRIV_ERR_STATUS); + /* Map the corresponding feature interrupt to interrupt pin 1 and 2 */ + reg_data_array[0] |= int_mask; + reg_data_array[1] |= int_mask; + break; + default: + break; + } + } + else + { + /* Return error if invalid pin selection */ + rslt = BMI2_E_INVALID_INT_PIN; } } else { - rslt = BMI2_E_INVALID_SENSOR; + rslt = BMI2_E_NULL_PTR; } return rslt; } /*! - * @brief This internal API gets the error status related to virtual frames. + * @brief This internal API gets the accelerometer data from the register. */ -static int8_t get_vfrm_error_status(struct bmi2_vfrm_err_status *vfrm_err_stat, struct bmi2_dev *dev) +static int8_t get_accel_sensor_data(struct bmi2_sens_axes_data *data, uint8_t reg_addr, struct bmi2_dev *dev) { /* Variable to define error */ int8_t rslt; - /* Array to define the feature configuration */ - uint8_t feat_config[BMI2_FEAT_SIZE_IN_BYTES] = { 0 }; + /* Array to define data stored in register */ + uint8_t reg_data[BMI2_ACC_GYR_NUM_BYTES] = { 0 }; - /* Variables to define index */ - uint8_t idx = 0; + /* Read the sensor data */ + rslt = bmi2_get_regs(reg_addr, reg_data, BMI2_ACC_GYR_NUM_BYTES, dev); + if (rslt == BMI2_OK) + { + /* Get accelerometer data from the register */ + get_acc_gyr_data(data, reg_data); - /* Variable to set flag */ - uint8_t feat_found; + /* Get the re-mapped accelerometer data */ + get_remapped_data(data, dev); + } - /* Initialize feature output for VFRM error status */ - struct bmi2_feature_config vfrm_err_cfg = { 0, 0, 0 }; + return rslt; +} - /* Search for VFRM error status feature and extract its configuration details */ - feat_found = extract_output_feat_config(&vfrm_err_cfg, BMI2_VFRM_STATUS, dev); - if (feat_found) - { - /* Get the feature output configuration for VFRM error status */ - rslt = bmi2_get_feat_config(vfrm_err_cfg.page, feat_config, dev); - if (rslt == BMI2_OK) - { - /* Define the offset in bytes for VFRM error status */ - idx = vfrm_err_cfg.start_addr; +/*! + * @brief This internal API gets the gyroscope data from the register. + */ +static int8_t get_gyro_sensor_data(struct bmi2_sens_axes_data *data, uint8_t reg_addr, struct bmi2_dev *dev) +{ + /* Variable to define error */ + int8_t rslt; - /* Increment index to get the error status */ - idx++; + /* Array to define data stored in register */ + uint8_t reg_data[BMI2_ACC_GYR_NUM_BYTES] = { 0 }; - /* Internal error while acquiring lock for FIFO */ - vfrm_err_stat->lock_error = BMI2_GET_BITS(feat_config[idx], BMI2_VFRM_LOCK_ERR_STATUS); + /* Read the sensor data */ + rslt = bmi2_get_regs(reg_addr, reg_data, BMI2_ACC_GYR_NUM_BYTES, dev); + if (rslt == BMI2_OK) + { + /* Get gyroscope data from the register */ + get_acc_gyr_data(data, reg_data); - /* Internal error while writing byte into FIFO */ - vfrm_err_stat->write_error = BMI2_GET_BITS(feat_config[idx], BMI2_VFRM_WRITE_ERR_STATUS); + /* Get the compensated gyroscope data */ + comp_gyro_cross_axis_sensitivity(data, dev); + + /* Get the re-mapped gyroscope data */ + get_remapped_data(data, dev); - /* Internal error while writing into FIFO */ - vfrm_err_stat->fatal_error = BMI2_GET_BITS(feat_config[idx], BMI2_VFRM_FATAL_ERR_STATUS); - } - } - else - { - rslt = BMI2_E_INVALID_SENSOR; } return rslt; } /*! - * @brief This internal API gets the output values of the wrist gesture. + * @brief This internal API gets the accelerometer/gyroscope data. */ -static int8_t get_wrist_gest_status(uint8_t *wrist_gest, struct bmi2_dev *dev) +static void get_acc_gyr_data(struct bmi2_sens_axes_data *data, const uint8_t *reg_data) { - /* Variable to define error */ - int8_t rslt; + /* Variables to store msb value */ + uint8_t msb; - /* Array to define the feature configuration */ - uint8_t feat_config[BMI2_FEAT_SIZE_IN_BYTES] = { 0 }; + /* Variables to store lsb value */ + uint8_t lsb; + + /* Variables to store both msb and lsb value */ + uint16_t msb_lsb; /* Variables to define index */ - uint8_t idx = 0; + uint8_t index = 0; - /* Variable to set flag */ - uint8_t feat_found; + /* Read x-axis data */ + lsb = reg_data[index++]; + msb = reg_data[index++]; + msb_lsb = ((uint16_t) msb << 8) | (uint16_t) lsb; + data->x = (int16_t) msb_lsb; - /* Initialize feature output for wrist gesture */ - struct bmi2_feature_config wrist_gest_out_config = { 0, 0, 0 }; + /* Read y-axis data */ + lsb = reg_data[index++]; + msb = reg_data[index++]; + msb_lsb = ((uint16_t) msb << 8) | (uint16_t) lsb; + data->y = (int16_t) msb_lsb; - /* Search for wrist gesture feature and extract its configuration details */ - feat_found = extract_output_feat_config(&wrist_gest_out_config, BMI2_WRIST_GESTURE, dev); - if (feat_found) + /* Read z-axis data */ + lsb = reg_data[index++]; + msb = reg_data[index++]; + msb_lsb = ((uint16_t) msb << 8) | (uint16_t) lsb; + data->z = (int16_t) msb_lsb; +} + +/*! + * @brief This internal API gets the re-mapped accelerometer/gyroscope data. + */ +static void get_remapped_data(struct bmi2_sens_axes_data *data, const struct bmi2_dev *dev) +{ + /* Array to defined the re-mapped sensor data */ + int16_t remap_data[3] = { 0 }; + int16_t pos_multiplier = INT16_C(1); + int16_t neg_multiplier = INT16_C(-1); + + /* Fill the array with the un-mapped sensor data */ + remap_data[0] = data->x; + remap_data[1] = data->y; + remap_data[2] = data->z; + + /* Get the re-mapped x axis data */ + if (dev->remap.x_axis_sign == BMI2_POS_SIGN) { - /* Get the feature output configuration for wrist gesture */ - rslt = bmi2_get_feat_config(wrist_gest_out_config.page, feat_config, dev); - if (rslt == BMI2_OK) - { - /* Define the offset in bytes for wrist gesture output */ - idx = wrist_gest_out_config.start_addr; + data->x = (int16_t)(remap_data[dev->remap.x_axis] * pos_multiplier); + } + else + { + data->x = (int16_t)(remap_data[dev->remap.x_axis] * neg_multiplier); + } - /* Get the wrist gesture output */ - *wrist_gest = feat_config[idx]; - } + /* Get the re-mapped y axis data */ + if (dev->remap.y_axis_sign == BMI2_POS_SIGN) + { + data->y = (int16_t)(remap_data[dev->remap.y_axis] * pos_multiplier); } else { - rslt = BMI2_E_INVALID_SENSOR; + data->y = (int16_t)(remap_data[dev->remap.y_axis] * neg_multiplier); } - return rslt; + /* Get the re-mapped z axis data */ + if (dev->remap.z_axis_sign == BMI2_POS_SIGN) + { + data->z = (int16_t)(remap_data[dev->remap.z_axis] * pos_multiplier); + } + else + { + data->z = (int16_t)(remap_data[dev->remap.z_axis] * neg_multiplier); + } } /*! - * @brief This internal API gets the cross sensitivity coefficient between - * gyroscope's X and Z axes. + * @brief This internal API reads the user-defined bytes of data from the given + * register address of auxiliary sensor in manual mode. */ -static int8_t get_gyro_cross_sense(int16_t *cross_sense, struct bmi2_dev *dev) +static int8_t read_aux_data(uint8_t reg_addr, uint8_t *aux_data, uint16_t len, uint8_t burst_len, struct bmi2_dev *dev) { /* Variable to define error */ - int8_t rslt; + int8_t rslt = BMI2_OK; - /* Array to define the feature configuration */ - uint8_t feat_config[BMI2_FEAT_SIZE_IN_BYTES] = { 0 }; + /* Array to store the register data */ + uint8_t reg_data[15] = { 0 }; - /* Variable to define index */ - uint8_t idx = 0; + /* Variable to define number of bytes to read */ + uint16_t read_length = 0; - /* Variable to set flag */ - uint8_t feat_found; + /* Variable to define loop */ + uint8_t loop = 0; - uint8_t corr_fact_zx; + /* Variable to define counts to get the correct array index */ + uint8_t count = 0; - /* Initialize feature output for gyroscope cross sensitivity */ - struct bmi2_feature_config cross_sense_out_config = { 0, 0, 0 }; + /* Variable to define index for the array */ + uint8_t idx = 0; - if (dev->variant_feature & BMI2_MAXIMUM_FIFO_VARIANT) - { - /* For maximum_fifo variant fetch the correction factor from GPIO0 */ - rslt = bmi2_get_regs(BMI2_GYR_CAS_GPIO0_ADDR, &corr_fact_zx, 1, dev); - if (rslt == BMI2_OK) - { - /* Get the gyroscope cross sensitivity coefficient */ - if (corr_fact_zx & BMI2_GYRO_CROSS_AXES_SENSE_SIGN_BIT_MASK) - { - *cross_sense = (int16_t)(((int16_t)corr_fact_zx) - 128); - } - else - { - *cross_sense = (int16_t)(corr_fact_zx); - } - } - } - else - { - /* Search for gyroscope cross sensitivity feature and extract its configuration details */ - feat_found = extract_output_feat_config(&cross_sense_out_config, BMI2_GYRO_CROSS_SENSE, dev); - if (feat_found) + while (len > 0) + { + /* Set the read address if AUX is not busy */ + rslt = set_if_aux_not_busy(BMI2_AUX_RD_ADDR, reg_addr, dev); + if (rslt == BMI2_OK) { - /* Get the feature output configuration for gyroscope cross sensitivity - * feature */ - rslt = bmi2_get_feat_config(cross_sense_out_config.page, feat_config, dev); + /* Read data from bmi2 data register */ + rslt = bmi2_get_regs(BMI2_AUX_X_LSB_ADDR, reg_data, (uint16_t) burst_len, dev); + dev->delay_us(1000, dev->intf_ptr); if (rslt == BMI2_OK) { - /* Define the offset in bytes for gyroscope cross sensitivity output */ - idx = cross_sense_out_config.start_addr; - - /* discard the MSB as GYR_CAS is of only 7 bit */ - feat_config[idx] = feat_config[idx] & BMI2_GYRO_CROSS_AXES_SENSE_MASK; - - /* Get the gyroscope cross sensitivity coefficient */ - if (feat_config[idx] & BMI2_GYRO_CROSS_AXES_SENSE_SIGN_BIT_MASK) + /* Get number of bytes to be read */ + if (len < burst_len) { - *cross_sense = (int16_t)(((int16_t)feat_config[idx]) - 128); + read_length = (uint8_t) len; } else { - *cross_sense = (int16_t)(feat_config[idx]); + read_length = burst_len; + } + + /* Update array index and store the data */ + for (loop = 0; loop < read_length; loop++) + { + idx = loop + count; + aux_data[idx] = reg_data[loop]; } } } - else - { - rslt = BMI2_E_INVALID_SENSOR; - } + + /* Update address for the next read */ + reg_addr += burst_len; + + /* Update count for the array index */ + count += burst_len; + + /* Update no of bytes left to read */ + len -= read_length; } return rslt; } /*! - * @brief This internal API is used to get enable status of gyroscope user gain - * update. + * @brief This internal API writes AUX write address and the user-defined bytes + * of data to the AUX sensor in manual mode. + * + * @note Change of BMI2_AUX_WR_ADDR is only allowed if AUX is not busy. */ -static int8_t get_user_gain_upd_status(uint8_t *status, struct bmi2_dev *dev) +static int8_t write_aux_data(uint8_t reg_addr, uint8_t reg_data, struct bmi2_dev *dev) { /* Variable to define error */ - int8_t rslt = BMI2_OK; + int8_t rslt; - /* Array to define the feature configuration */ - uint8_t feat_config[BMI2_FEAT_SIZE_IN_BYTES] = { 0 }; + /* Write data to be written to the AUX sensor in bmi2 register */ + rslt = bmi2_set_regs(BMI2_AUX_WR_DATA_ADDR, ®_data, 1, dev); + if (rslt == BMI2_OK) + { + /* Write the AUX address where data is to be stored when AUX is not busy */ + rslt = set_if_aux_not_busy(BMI2_AUX_WR_ADDR, reg_addr, dev); + } - /* Variable to define the array offset */ - uint8_t idx = 0; + return rslt; +} - /* Variable to set flag */ - uint8_t feat_found; +/*! + * @brief This internal API reads the user-defined bytes of data from the given + * register address of auxiliary sensor in data mode. + */ +static int8_t read_aux_data_mode(uint8_t *aux_data, struct bmi2_dev *dev) +{ + /* Variable to define error */ + int8_t rslt; - /* Variable to check APS status */ - uint8_t aps_stat = 0; + /* Variables to define loop */ + uint8_t count = 0; + + /* Variables to define index */ + uint8_t index = 0; - /* Initialize feature configuration for gyroscope user gain */ - struct bmi2_feature_config gyr_user_gain_cfg = { 0, 0, 0 }; + /* Array to define data stored in register */ + uint8_t reg_data[BMI2_AUX_NUM_BYTES] = { 0 }; - /* Search for user gain feature and extract its configuration details */ - feat_found = bmi2_extract_input_feat_config(&gyr_user_gain_cfg, BMI2_GYRO_GAIN_UPDATE, dev); - if (feat_found) + /* Check if data mode */ + if (!dev->aux_man_en) { - /* Disable advance power save */ - aps_stat = dev->aps_status; - if (aps_stat == BMI2_ENABLE) - { - rslt = bmi2_set_adv_power_save(BMI2_DISABLE, dev); - } - + /* Read the auxiliary sensor data */ + rslt = bmi2_get_regs(BMI2_AUX_X_LSB_ADDR, reg_data, BMI2_AUX_NUM_BYTES, dev); if (rslt == BMI2_OK) { - /* Get the configuration from the page where user gain feature resides */ - rslt = bmi2_get_feat_config(gyr_user_gain_cfg.page, feat_config, dev); - if (rslt == BMI2_OK) + /* Get the 8 bytes of auxiliary data */ + do { - /* Define the offset for enable/disable of user gain */ - idx = gyr_user_gain_cfg.start_addr + BMI2_GYR_USER_GAIN_FEAT_EN_OFFSET; - - /* Set the feature enable status */ - *status = BMI2_GET_BITS(feat_config[idx], BMI2_GYR_USER_GAIN_FEAT_EN); - } + *(aux_data + count++) = *(reg_data + index++); + } while (count < BMI2_AUX_NUM_BYTES); } } else { - rslt = BMI2_E_INVALID_SENSOR; - } - - /* Enable Advance power save if disabled while configuring and not when already disabled */ - if ((rslt == BMI2_OK) && (aps_stat == BMI2_ENABLE)) - { - rslt = bmi2_set_adv_power_save(BMI2_ENABLE, dev); + rslt = BMI2_E_AUX_INVALID_CFG; } return rslt; } /*! - * @brief This internal API gets the accelerometer self-test status. + * @brief This internal API maps the actual burst read length with that of the + * register value set by user. */ -static int8_t get_accel_self_test_status(struct bmi2_acc_self_test_status *acc_self_test_stat, struct bmi2_dev *dev) +static int8_t map_read_len(uint8_t *len, const struct bmi2_dev *dev) { + /* Variable to define error */ int8_t rslt = BMI2_OK; - uint8_t feat_config[BMI2_FEAT_SIZE_IN_BYTES] = { 0 }; - uint8_t idx = 0; - uint8_t feat_found; - struct bmi2_feature_config acc_self_test_cfg = { 0, 0, 0 }; - - /* Search for accelerometer self-test feature and extract its configuration details */ - feat_found = extract_output_feat_config(&acc_self_test_cfg, BMI2_ACCEL_SELF_TEST, dev); - if (feat_found) - { - /* Get the feature output configuration for accelerometer self-test status */ - rslt = bmi2_get_feat_config(acc_self_test_cfg.page, feat_config, dev); - if (rslt == BMI2_OK) - { - /* Define the offset in bytes for accelerometer self-test */ - idx = acc_self_test_cfg.start_addr; - - /* Bit to check if self-test is done */ - acc_self_test_stat->acc_self_test_done = BMI2_GET_BIT_POS0(feat_config[idx], BMI2_ACC_SELF_TEST_DONE); - - /* Bit to check if accelerometer X-axis test is passed */ - acc_self_test_stat->acc_x_ok = BMI2_GET_BITS(feat_config[idx], BMI2_ACC_X_OK); - /* Bit to check if accelerometer Y-axis test is passed */ - acc_self_test_stat->acc_y_ok = BMI2_GET_BITS(feat_config[idx], BMI2_ACC_Y_OK); - - /* Bit to check if accelerometer Z-axis test is passed */ - acc_self_test_stat->acc_z_ok = BMI2_GET_BITS(feat_config[idx], BMI2_ACC_Z_OK); - } - } - else + /* Get the burst read length against the values set by the user */ + switch (dev->aux_man_rd_burst_len) { - rslt = BMI2_E_INVALID_SENSOR; + case BMI2_AUX_READ_LEN_0: + *len = 1; + break; + case BMI2_AUX_READ_LEN_1: + *len = 2; + break; + case BMI2_AUX_READ_LEN_2: + *len = 6; + break; + case BMI2_AUX_READ_LEN_3: + *len = 8; + break; + default: + rslt = BMI2_E_AUX_INVALID_CFG; + break; } return rslt; @@ -16575,11 +7413,15 @@ static int8_t check_empty_fifo(uint16_t *data_index, const struct bmi2_fifo_fram int8_t rslt = BMI2_OK; /* Validate data index */ - if (((*data_index) + 2) < fifo->length) + if (((*data_index) + 6) < fifo->length) { /* Check if FIFO is empty */ - if ((fifo->data[(*data_index)] == BMI2_FIFO_MSB_CONFIG_CHECK) && - (fifo->data[(*data_index) + 1] == BMI2_FIFO_LSB_CONFIG_CHECK)) + if (((fifo->data[(*data_index)] == BMI2_FIFO_MSB_CONFIG_CHECK) && + (fifo->data[(*data_index) + 1] == BMI2_FIFO_LSB_CONFIG_CHECK)) && + ((fifo->data[(*data_index) + 2] == BMI2_FIFO_MSB_CONFIG_CHECK) && + (fifo->data[(*data_index) + 3] == BMI2_FIFO_LSB_CONFIG_CHECK)) && + ((fifo->data[(*data_index) + 4] == BMI2_FIFO_MSB_CONFIG_CHECK) && + (fifo->data[(*data_index) + 5] == BMI2_FIFO_LSB_CONFIG_CHECK))) { /* Move the data index to the last byte to mark completion */ (*data_index) = fifo->length; @@ -16704,65 +7546,6 @@ static int8_t unpack_skipped_frame(uint16_t *data_index, struct bmi2_fifo_frame return rslt; } -/*! - * @brief This internal API is used to parse and store the activity recognition - * output from the FIFO data. - */ -static int8_t unpack_act_recog_output(struct bmi2_act_recog_output *act_recog, - uint16_t *data_index, - const struct bmi2_fifo_frame *fifo) -{ - /* Variable to define error */ - int8_t rslt = BMI2_OK; - - /* Variables to define 4 bytes of sensor time */ - uint32_t time_stamp_byte4 = 0; - uint32_t time_stamp_byte3 = 0; - uint32_t time_stamp_byte2 = 0; - uint32_t time_stamp_byte1 = 0; - - /* Validate data index */ - if ((*data_index + BMI2_FIFO_VIRT_ACT_DATA_LENGTH) >= fifo->length) - { - /* Update the data index to the last byte */ - (*data_index) = fifo->length; - - /* FIFO is empty */ - rslt = BMI2_W_FIFO_EMPTY; - } - else - { - /* Get time-stamp from the activity recognition frame */ - time_stamp_byte4 = ((uint32_t)(fifo->data[(*data_index) + 3]) << 24); - time_stamp_byte3 = ((uint32_t)(fifo->data[(*data_index) + 2]) << 16); - time_stamp_byte2 = fifo->data[(*data_index) + 1] << 8; - time_stamp_byte1 = fifo->data[(*data_index)]; - - /* Update time-stamp from the virtual frame */ - act_recog->time_stamp = (time_stamp_byte4 | time_stamp_byte3 | time_stamp_byte2 | time_stamp_byte1); - - /* Move the data index by 4 bytes */ - (*data_index) = (*data_index) + BMI2_FIFO_VIRT_ACT_TIME_LENGTH; - - /* Update the previous activity from the virtual frame */ - act_recog->prev_act = fifo->data[(*data_index)]; - - /* Move the data index by 1 byte */ - (*data_index) = (*data_index) + BMI2_FIFO_VIRT_ACT_TYPE_LENGTH; - - /* Update the current activity from the virtual frame */ - act_recog->curr_act = fifo->data[(*data_index)]; - - /* Move the data index by 1 byte */ - (*data_index) = (*data_index) + BMI2_FIFO_VIRT_ACT_STAT_LENGTH; - - /* More frames could be read */ - rslt = BMI2_W_PARTIAL_READ; - } - - return rslt; -} - /*! * @brief This internal API enables and configures the accelerometer which is * needed for self-test operation. It also sets the amplitude for the self-test. @@ -16980,47 +7763,6 @@ static int8_t read_gyro_xyz(struct bmi2_sens_axes_data *gyro, struct bmi2_dev *d return rslt; } -/*! - * @brief This internal API skips S4S frame in the FIFO data while getting - * step activity output. - */ -static int8_t move_if_s4s_frame(const uint8_t *frame_header, uint16_t *data_index, const struct bmi2_fifo_frame *fifo) -{ - /* Variable to define error */ - int8_t rslt = BMI2_OK; - - /* Variable to extract virtual header byte */ - uint8_t virtual_header_mode; - - /* Variable to define pay-load in words */ - uint8_t payload_word = 0; - - /* Variable to define pay-load in bytes */ - uint8_t payload_bytes = 0; - - /* Extract virtual header mode from the frame header */ - virtual_header_mode = BMI2_GET_BITS(*frame_header, BMI2_FIFO_VIRT_FRM_MODE); - - /* If the extracted header byte is a virtual header */ - if (virtual_header_mode == BMI2_FIFO_VIRT_FRM_MODE) - { - /* If frame header is not activity recognition header */ - if (*frame_header != 0xC8) - { - /* Extract pay-load in words from the header byte */ - payload_word = BMI2_GET_BITS(*frame_header, BMI2_FIFO_VIRT_PAYLOAD) + 1; - - /* Convert to bytes */ - payload_bytes = (uint8_t)(payload_word * 2); - - /* Move the data index by those pay-load bytes */ - rslt = move_next_frame(data_index, payload_bytes, fifo); - } - } - - return rslt; -} - /*! * @brief This internal API converts LSB value of accelerometer axes to form * 'g' to 'mg' for self-test. @@ -17294,28 +8036,6 @@ static int8_t set_remap_axes(const struct bmi2_axes_remap *remap, struct bmi2_de return rslt; } -/*! - * @brief This internal API enables/disables compensation of the gain defined - * in the GAIN register. - */ -static int8_t enable_gyro_gain(uint8_t enable, struct bmi2_dev *dev) -{ - /* Variable to define error */ - int8_t rslt; - - /* Variable to define register data */ - uint8_t reg_data = 0; - - rslt = bmi2_get_regs(BMI2_GYR_OFF_COMP_6_ADDR, ®_data, 1, dev); - if (rslt == BMI2_OK) - { - reg_data = BMI2_SET_BITS(reg_data, BMI2_GYR_GAIN_EN, enable); - rslt = bmi2_set_regs(BMI2_GYR_OFF_COMP_6_ADDR, ®_data, 1, dev); - } - - return rslt; -} - /*! * @brief This internal API corrects the gyroscope cross-axis sensitivity * between the z and the x axis. @@ -17326,37 +8046,6 @@ static void comp_gyro_cross_axis_sensitivity(struct bmi2_sens_axes_data *gyr_dat gyr_data->x = gyr_data->x - (int16_t)(((int32_t) dev->gyr_cross_sens_zx * (int32_t) gyr_data->z) / 512); } -/*! - * @brief This internal API is used to extract the output feature configuration - * details from the look-up table. - */ -static uint8_t extract_output_feat_config(struct bmi2_feature_config *feat_output, - uint8_t type, - const struct bmi2_dev *dev) -{ - /* Variable to define loop */ - uint8_t loop = 0; - - /* Variable to set flag */ - uint8_t feat_found = BMI2_FALSE; - - /* Search for the output feature from the output configuration array */ - while (loop < dev->out_sens) - { - if (dev->feat_output[loop].type == type) - { - *feat_output = dev->feat_output[loop]; - feat_found = BMI2_TRUE; - break; - } - - loop++; - } - - /* Return flag */ - return feat_found; -} - /*! * @brief This internal API is used to validate the boundary conditions. */ @@ -17431,12 +8120,12 @@ static int8_t set_accel_foc_config(struct bmi2_dev *dev) /* Variable to define error */ int8_t rslt; - /* Variable to set the accelerometer configuration value */ - uint8_t acc_conf_data = BMI2_FOC_ACC_CONF_VAL; - /* Variable to select the sensor */ uint8_t sens_list = BMI2_ACCEL; + /* Variable to set the accelerometer configuration value */ + uint8_t acc_conf_data = BMI2_FOC_ACC_CONF_VAL; + /* Disabling offset compensation */ rslt = set_accel_offset_comp(BMI2_DISABLE, dev); if (rslt == BMI2_OK) @@ -17447,6 +8136,7 @@ static int8_t set_accel_foc_config(struct bmi2_dev *dev) { /* Set accelerometer to normal mode by enabling it */ rslt = bmi2_sensor_enable(&sens_list, 1, dev); + if (rslt == BMI2_OK) { /* Disable advance power save mode */ @@ -17779,6 +8469,124 @@ static int8_t restore_accel_foc_config(struct bmi2_accel_config *acc_cfg, return rslt; } +/*! + * @brief This internal API sets accelerometer configurations like ODR, + * bandwidth, performance mode and g-range. + */ +static int8_t set_accel_config(struct bmi2_accel_config *config, struct bmi2_dev *dev) +{ + /* Variable to define error */ + int8_t rslt; + + /* Variable to store data */ + uint8_t reg_data; + + /* Array to store the default value of accelerometer configuration + * reserved registers + */ + uint8_t data_array[2] = { 0 }; + + /* Validate bandwidth and performance mode */ + rslt = validate_bw_perf_mode(&config->bwp, &config->filter_perf, dev); + if (rslt == BMI2_OK) + { + /* Validate ODR and range */ + rslt = validate_odr_range(&config->odr, &config->range, dev); + if (rslt == BMI2_OK) + { + /* Set accelerometer performance mode */ + reg_data = BMI2_SET_BITS(data_array[0], BMI2_ACC_FILTER_PERF_MODE, config->filter_perf); + + /* Set accelerometer bandwidth */ + reg_data = BMI2_SET_BITS(reg_data, BMI2_ACC_BW_PARAM, config->bwp); + + /* Set accelerometer ODR */ + reg_data = BMI2_SET_BIT_POS0(reg_data, BMI2_ACC_ODR, config->odr); + + /* Copy the register data to the array */ + data_array[0] = reg_data; + + /* Set accelerometer range */ + reg_data = BMI2_SET_BIT_POS0(data_array[1], BMI2_ACC_RANGE, config->range); + + /* Copy the register data to the array */ + data_array[1] = reg_data; + + /* Write accelerometer configuration to ACC_CONFand + * ACC_RANGE registers simultaneously as they lie in consecutive places + */ + rslt = bmi2_set_regs(BMI2_ACC_CONF_ADDR, data_array, 2, dev); + + /* Get error status to check for invalid configurations */ + if (rslt == BMI2_OK) + { + rslt = cfg_error_status(dev); + } + } + } + + return rslt; +} + +/*! + * @brief This internal API sets gyroscope configurations like ODR, bandwidth, + * low power/high performance mode, performance mode and range. It also + * maps/un-maps data interrupts to that of hardware interrupt line. + */ +static int8_t set_gyro_config(struct bmi2_gyro_config *config, struct bmi2_dev *dev) +{ + /* Variable to define error */ + int8_t rslt; + + /* Variable to store data */ + uint8_t reg_data; + + /* Array to store the default value of gyroscope configuration reserved registers */ + uint8_t data_array[2] = { 0 }; + + /* Validate gyroscope configurations */ + rslt = validate_gyro_config(config, dev); + if (rslt == BMI2_OK) + { + /* Set gyroscope performance mode */ + reg_data = BMI2_SET_BITS(data_array[0], BMI2_GYR_FILTER_PERF_MODE, config->filter_perf); + + /* Set gyroscope noise performance mode */ + reg_data = BMI2_SET_BITS(reg_data, BMI2_GYR_NOISE_PERF_MODE, config->noise_perf); + + /* Set gyroscope bandwidth */ + reg_data = BMI2_SET_BITS(reg_data, BMI2_GYR_BW_PARAM, config->bwp); + + /* Set gyroscope ODR */ + reg_data = BMI2_SET_BIT_POS0(reg_data, BMI2_GYR_ODR, config->odr); + + /* Copy the register data to the array */ + data_array[0] = reg_data; + + /* Set gyroscope OIS range */ + reg_data = BMI2_SET_BITS(data_array[1], BMI2_GYR_OIS_RANGE, config->ois_range); + + /* Set gyroscope range */ + reg_data = BMI2_SET_BIT_POS0(reg_data, BMI2_GYR_RANGE, config->range); + + /* Copy the register data to the array */ + data_array[1] = reg_data; + + /* Write accelerometer configuration to GYR_CONF and GYR_RANGE + * registers simultaneously as they lie in consecutive places + */ + rslt = bmi2_set_regs(BMI2_GYR_CONF_ADDR, data_array, 2, dev); + + /* Get error status to check for invalid configurations */ + if (rslt == BMI2_OK) + { + rslt = cfg_error_status(dev); + } + } + + return rslt; +} + /*! * @brief This internal API saves the configurations before performing gyroscope * FOC. @@ -17816,14 +8624,14 @@ static int8_t set_gyro_foc_config(struct bmi2_dev *dev) { int8_t rslt; + /* Variable to select the sensor */ + uint8_t sens_list = BMI2_GYRO; + /* Array to set the gyroscope configuration value (ODR, Performance mode * and bandwidth) and gyroscope range */ uint8_t gyr_conf_data[2] = { BMI2_FOC_GYR_CONF_VAL, BMI2_GYR_RANGE_2000 }; - /* Variable to select the sensor */ - uint8_t sens_list = BMI2_GYRO; - /* Disabling gyroscope offset compensation */ rslt = bmi2_set_gyro_offset_comp(BMI2_DISABLE, dev); if (rslt == BMI2_OK) @@ -17836,6 +8644,7 @@ static int8_t set_gyro_foc_config(struct bmi2_dev *dev) { /* Set gyroscope to normal mode by enabling it */ rslt = bmi2_sensor_enable(&sens_list, 1, dev); + if (rslt == BMI2_OK) { /* Disable advance power save mode */ @@ -19126,149 +9935,11 @@ static int8_t get_average_of_sensor_data(uint8_t sens_list, return rslt; } -/*! - * @brief This internal API sets primary OIS configurations for - * selecting filter cut-off frequency . - */ -static int8_t set_primary_ois_config(const struct bmi2_primary_ois_config *config, struct bmi2_dev *dev) -{ - /* Variable to define error */ - int8_t rslt; - - /* Array to define the feature configuration */ - uint8_t feat_config[BMI2_FEAT_SIZE_IN_BYTES] = { 0 }; - - /* Variable to define the array offset */ - uint8_t idx = 0; - - /* Variable to define count */ - uint8_t i = 0; - - /* Variable to set flag */ - uint8_t feat_found; - - /* Initialize feature configuration for primary OIS */ - struct bmi2_feature_config primary_ois_config = { 0, 0, 0 }; - - /* Copy the feature configuration address to a local pointer */ - uint16_t *data_p = (uint16_t *)(void *)feat_config; - - /* Search for priamry OIS feature and extract its configuration details */ - feat_found = bmi2_extract_input_feat_config(&primary_ois_config, BMI2_PRIMARY_OIS, dev); - if (feat_found) - { - /* Get the configuration from the page where primary OIS feature resides */ - rslt = bmi2_get_feat_config(primary_ois_config.page, feat_config, dev); - if (rslt == BMI2_OK) - { - /* Define the offset in bytes for priamry OIS select */ - idx = primary_ois_config.start_addr; - - /* Get offset in words since all the features are set in words length */ - idx = idx / 2; - - /* Enable lp filter */ - *(data_p + idx) = BMI2_SET_BIT_POS0(*(data_p + idx), BMI2_LP_FILTER_EN, config->lp_filter_enable); - - /* Set lp filter cut-off frequency */ - *(data_p + idx) = BMI2_SET_BITS(*(data_p + idx), BMI2_LP_FILTER_CONFIG, config->lp_filter_config); - - /* Enable Gyro on OIS */ - *(data_p + idx) = BMI2_SET_BITS(*(data_p + idx), BMI2_PRIMARY_OIS_GYR_EN, config->primary_ois_gyro_en); - - /* Enable Accel on OIS */ - *(data_p + idx) = BMI2_SET_BITS(*(data_p + idx), BMI2_PRIMARY_OIS_ACC_EN, config->primary_ois_accel_en); - - /* Increment offset by 1 more word to get the total length in words */ - idx++; - - /* Get total length in bytes to copy from local pointer to the array */ - idx = (uint8_t)(idx * 2) - primary_ois_config.start_addr; - - /* Copy the bytes to be set back to the array */ - for (i = 0; i < idx; i++) - { - feat_config[primary_ois_config.start_addr + - i] = *((uint8_t *)data_p + primary_ois_config.start_addr + i); - } - - /* Set the configuration back to the page */ - rslt = bmi2_set_regs(BMI2_FEATURES_REG_ADDR, feat_config, BMI2_FEAT_SIZE_IN_BYTES, dev); - } - } - else - { - rslt = BMI2_E_INVALID_SENSOR; - } - - return rslt; -} - -/*! - * @brief This internal API gets priamry OIS configurations for - * low pass cut-off frequency. - */ -static int8_t get_primary_ois_config(struct bmi2_primary_ois_config *config, struct bmi2_dev *dev) -{ - /* Variable to define error */ - int8_t rslt; - - /* Array to define the feature configuration */ - uint8_t feat_config[BMI2_FEAT_SIZE_IN_BYTES] = { 0 }; - - /* Variable to define the array offset */ - uint8_t idx = 0; - - /* Variable to define LSB */ - uint16_t lsb; - - /* Variable to set flag */ - uint8_t feat_found; - - /* Initialize feature configuration for primary OIS */ - struct bmi2_feature_config primary_ois_config = { 0, 0, 0 }; - - /* Search for primary OIS feature and extract its configuration details */ - feat_found = bmi2_extract_input_feat_config(&primary_ois_config, BMI2_PRIMARY_OIS, dev); - if (feat_found) - { - /* Get the configuration from the page where primary OIS feature resides */ - rslt = bmi2_get_feat_config(primary_ois_config.page, feat_config, dev); - if (rslt == BMI2_OK) - { - /* Define the offset for feature enable for primary OIS */ - idx = primary_ois_config.start_addr; - - /* Get word to calculate filter state, cut-off frequency, gyro-OIS, - * accel-OIS select */ - lsb = (uint16_t)feat_config[idx++]; - - /* Get low pass filter state */ - config->lp_filter_enable = lsb & BMI2_LP_FILTER_EN_MASK; - - /* Get lp filter cut-off frequency */ - config->lp_filter_config = (lsb & BMI2_LP_FILTER_CONFIG_MASK) >> BMI2_LP_FILTER_CONFIG_POS; - - /* Get primary OIS gyro on ois state */ - config->primary_ois_gyro_en = (lsb & BMI2_PRIMARY_OIS_GYR_EN_MASK) >> BMI2_PRIMARY_OIS_GYR_EN_POS; - - /* Get primary OIS accel on ois state */ - config->primary_ois_accel_en = (lsb & BMI2_PRIMARY_OIS_ACC_EN_MASK) >> BMI2_PRIMARY_OIS_ACC_EN_POS; - } - } - else - { - rslt = BMI2_E_INVALID_SENSOR; - } - - return rslt; -} - /*! * @brief This internal API extract the identification feature from the DMR page * and retrieve the config file major and minor version. */ -static int8_t extract_config_file(uint16_t *config_major, uint8_t *config_minor, struct bmi2_dev *dev) +static int8_t extract_config_file(uint8_t *config_major, uint8_t *config_minor, struct bmi2_dev *dev) { /* Variable to define the result */ int8_t rslt = BMI2_OK; @@ -19348,9 +10019,31 @@ static int8_t extract_config_file(uint16_t *config_major, uint8_t *config_minor, } /*! - * @brief This internal API gets the output data of OIS. + *@brief This internal API is used to map the interrupts to the sensor. + */ +static void extract_feat_int_map(struct bmi2_map_int *map_int, uint8_t type, const struct bmi2_dev *dev) +{ + /* Variable to define loop */ + uint8_t loop = 0; + + /* Search for the interrupts from the input configuration array */ + while (loop < dev->sens_int_map) + { + if (dev->map_int[loop].type == type) + { + *map_int = dev->map_int[loop]; + break; + } + + loop++; + } +} + +/*! + * @brief This internal API gets the saturation status for the gyroscope user + * gain update. */ -static int8_t get_ois_output(struct bmi2_ois_output *ois_output, struct bmi2_dev *dev) +static int8_t get_gyro_gain_update_status(struct bmi2_gyr_user_gain_status *user_gain_stat, struct bmi2_dev *dev) { /* Variable to define error */ int8_t rslt; @@ -19358,71 +10051,39 @@ static int8_t get_ois_output(struct bmi2_ois_output *ois_output, struct bmi2_dev /* Array to define the feature configuration */ uint8_t feat_config[BMI2_FEAT_SIZE_IN_BYTES] = { 0 }; - /* Variables to store MSB value */ - uint8_t msb = 0; - - /* Variables to store LSB value */ - uint8_t lsb = 0; - - /* Variables to store both MSB and LSB value */ - uint16_t lsb_msb = 0; - /* Variables to define index */ uint8_t idx = 0; /* Variable to set flag */ uint8_t feat_found; - /* Initialize feature output for OIS */ - struct bmi2_feature_config ois_config = { 0, 0, 0 }; + /* Initialize feature output for gyroscope user gain status */ + struct bmi2_feature_config user_gain_cfg = { 0, 0, 0 }; + + /* Search for gyroscope user gain status output feature and extract its + * configuration details + */ + feat_found = extract_output_feat_config(&user_gain_cfg, BMI2_GYRO_GAIN_UPDATE, dev); + if (feat_found) + { + /* Get the feature output configuration for gyroscope user gain status */ + rslt = bmi2_get_feat_config(user_gain_cfg.page, feat_config, dev); + if (rslt == BMI2_OK) + { + /* Define the offset in bytes for gyroscope user gain status */ + idx = user_gain_cfg.start_addr; + + /* Get the saturation status for x-axis */ + user_gain_stat->sat_x = BMI2_GET_BIT_POS0(feat_config[idx], BMI2_GYR_USER_GAIN_SAT_STAT_X); - /* Search for OIS output feature and extract its configuration details */ - feat_found = extract_output_feat_config(&ois_config, BMI2_OIS_OUTPUT, dev); - if (feat_found) - { - /* Get the feature output configuration for OIS */ - rslt = bmi2_get_feat_config(ois_config.page, feat_config, dev); + /* Get the saturation status for y-axis */ + user_gain_stat->sat_y = BMI2_GET_BITS(feat_config[idx], BMI2_GYR_USER_GAIN_SAT_STAT_Y); - if (rslt == BMI2_OK) - { - /* Define the offset in bytes for OIS output start address */ - idx = ois_config.start_addr; - - /* Read OIS accel x axis */ - lsb = feat_config[idx++]; - msb = feat_config[idx++]; - lsb_msb = (uint16_t)lsb | (uint16_t)msb << 8; - ois_output->ois_acc_x = (int16_t)lsb_msb; - - /* Read OIS accel y axis */ - lsb = feat_config[idx++]; - msb = feat_config[idx++]; - lsb_msb = (uint16_t)lsb | (uint16_t)msb << 8; - ois_output->ois_acc_y = (int16_t)lsb_msb; - - /* Read OIS accel z axis */ - lsb = feat_config[idx++]; - msb = feat_config[idx++]; - lsb_msb = (uint16_t)lsb | (uint16_t)msb << 8; - ois_output->ois_acc_z = (int16_t)lsb_msb; - - /* Read OIS gyro x axis */ - lsb = feat_config[idx++]; - msb = feat_config[idx++]; - lsb_msb = (uint16_t)lsb | (uint16_t)msb << 8; - ois_output->ois_gyro_x = (int16_t)lsb_msb; - - /* Read OIS gyro y axis */ - lsb = feat_config[idx++]; - msb = feat_config[idx++]; - lsb_msb = (uint16_t)lsb | (uint16_t)msb << 8; - ois_output->ois_gyro_y = (int16_t)lsb_msb; - - /* Read OIS gyro z axis */ - lsb = feat_config[idx++]; - msb = feat_config[idx++]; - lsb_msb = (uint16_t)lsb | (uint16_t)msb << 8; - ois_output->ois_gyro_z = (int16_t)lsb_msb; + /* Get the saturation status for z-axis */ + user_gain_stat->sat_z = BMI2_GET_BITS(feat_config[idx], BMI2_GYR_USER_GAIN_SAT_STAT_Z); + + /* Get g trigger status */ + user_gain_stat->g_trigger_status = BMI2_GET_BITS(feat_config[idx], BMI2_G_TRIGGER_STAT); } } else @@ -19434,56 +10095,41 @@ static int8_t get_ois_output(struct bmi2_ois_output *ois_output, struct bmi2_dev } /*! - * @brief This internal API is used to enable/disable free-fall detection feature. + * @brief This internal API is used to extract the output feature configuration + * details from the look-up table. */ -static int8_t set_free_fall_det(uint8_t enable, struct bmi2_dev *dev) +static uint8_t extract_output_feat_config(struct bmi2_feature_config *feat_output, + uint8_t type, + const struct bmi2_dev *dev) { - /* Variable to define error */ - int8_t rslt; - - /* Array to define the feature configuration */ - uint8_t feat_config[BMI2_FEAT_SIZE_IN_BYTES] = { 0 }; - - /* Variable to define the array offset */ - uint8_t idx = 0; + /* Variable to define loop */ + uint8_t loop = 0; /* Variable to set flag */ - uint8_t feat_found; - - /* Initialize feature configuration for free-fall detection */ - struct bmi2_feature_config freefall_config = { 0, 0, 0 }; + uint8_t feat_found = BMI2_FALSE; - /* Search for free-fall detection feature and extract its configuration details */ - feat_found = bmi2_extract_input_feat_config(&freefall_config, BMI2_FREE_FALL_DET, dev); - if (feat_found) + /* Search for the output feature from the output configuration array */ + while (loop < dev->out_sens) { - /* Get the configuration from the page where free-fall detection feature resides */ - rslt = bmi2_get_feat_config(freefall_config.page, feat_config, dev); - if (rslt == BMI2_OK) + if (dev->feat_output[loop].type == type) { - /* Assign the offset address for free-fall detection */ - idx = freefall_config.start_addr; - - /* Set the feature enable bit */ - feat_config[idx] = BMI2_SET_BIT_POS0(feat_config[idx], BMI2_FREE_FALL_DET_FEAT_EN, enable); - - /* Set the configuration back to the page */ - rslt = bmi2_set_regs(BMI2_FEATURES_REG_ADDR, feat_config, BMI2_FEAT_SIZE_IN_BYTES, dev); + *feat_output = dev->feat_output[loop]; + feat_found = BMI2_TRUE; + break; } - } - else - { - rslt = BMI2_E_INVALID_SENSOR; + + loop++; } - return rslt; + /* Return flag */ + return feat_found; } /*! - * @brief This internal API sets free-fall detection configurations like - * free-fall accel settings, and output configuration. + * @brief This internal API gets the cross sensitivity coefficient between + * gyroscope's X and Z axes. */ -static int8_t set_free_fall_det_config(const struct bmi2_free_fall_det_config *config, struct bmi2_dev *dev) +static int8_t get_gyro_cross_sense(int16_t *cross_sense, struct bmi2_dev *dev) { /* Variable to define error */ int8_t rslt; @@ -19491,155 +10137,200 @@ static int8_t set_free_fall_det_config(const struct bmi2_free_fall_det_config *c /* Array to define the feature configuration */ uint8_t feat_config[BMI2_FEAT_SIZE_IN_BYTES] = { 0 }; - /* Variable to define the array offset */ - uint8_t idx = 0; - /* Variable to define index */ - uint8_t index = 0; - - /* Variable to define set accel settings in loop */ - uint8_t indx; + uint8_t idx = 0; /* Variable to set flag */ uint8_t feat_found; - /* Initialize feature configuration for free-fall */ - struct bmi2_feature_config freefall_config = { 0, 0, 0 }; + uint8_t corr_fact_zx; - /* Copy the feature configuration address to a local pointer */ - uint16_t *data_p = (uint16_t *) (void *)feat_config; + /* Initialize feature output for gyroscope cross sensitivity */ + struct bmi2_feature_config cross_sense_out_config = { 0, 0, 0 }; - /* Search for free-fall detection feature and extract its configuration details */ - feat_found = bmi2_extract_input_feat_config(&freefall_config, BMI2_FREE_FALL_DET, dev); - if (feat_found) + if (dev->variant_feature & BMI2_MAXIMUM_FIFO_VARIANT) { - /* Get the configuration from the page where low-g feature resides */ - rslt = bmi2_get_feat_config(freefall_config.page, feat_config, dev); + /* For maximum_fifo variant fetch the correction factor from GPIO0 */ + rslt = bmi2_get_regs(BMI2_GYR_CAS_GPIO0_ADDR, &corr_fact_zx, 1, dev); if (rslt == BMI2_OK) { - /* Define the offset in bytes for free-fall detection select */ - idx = freefall_config.start_addr; - - /* Get offset in words since all the features are set in words length */ - idx = idx / 2; - - /* Set output configuration */ - *(data_p + idx) = BMI2_SET_BITS(*(data_p + idx), BMI2_FREE_FALL_OUT_CONF, config->out_conf); - - /* Increment offset by 1 more word to set free-fall detection accel settings 1 configuration */ - idx++; - - /* Set the free-fall accel param settings */ - for (indx = 0; indx < BMI2_FREE_FALL_ACCEL_SET_PARAMS; indx++) + /* Get the gyroscope cross sensitivity coefficient */ + if (corr_fact_zx & BMI2_GYRO_CROSS_AXES_SENSE_SIGN_BIT_MASK) { - /* Set free-fall detection accel settings */ - *(data_p + idx) = BMI2_SET_BIT_POS0(*(data_p + idx), - BMI2_FREE_FALL_ACCEL_SETT, - config->freefall_accel_settings[indx]); - - /* Increment offset by 1 more word to set free-fall detection accel settings configuration */ - idx++; + *cross_sense = (int16_t)(((int16_t)corr_fact_zx) - 128); } - - /* Get total length in bytes to copy from local pointer to the array */ - idx = (uint8_t)(idx * 2) - freefall_config.start_addr; - - /* Copy the bytes to be set back to the array */ - for (index = 0; index < idx; index++) + else { - feat_config[freefall_config.start_addr + - index] = *((uint8_t *) data_p + freefall_config.start_addr + index); + *cross_sense = (int16_t)(corr_fact_zx); } - - /* Set the configuration back to the page */ - rslt = bmi2_set_regs(BMI2_FEATURES_REG_ADDR, feat_config, BMI2_FEAT_SIZE_IN_BYTES, dev); + } + } + else + { + /* Search for gyroscope cross sensitivity feature and extract its configuration details */ + feat_found = extract_output_feat_config(&cross_sense_out_config, BMI2_GYRO_CROSS_SENSE, dev); + if (feat_found) + { + /* Get the feature output configuration for gyroscope cross sensitivity + * feature */ + rslt = bmi2_get_feat_config(cross_sense_out_config.page, feat_config, dev); if (rslt == BMI2_OK) { - /* Copy out_conf value to a local copy in device structure */ - dev->int_map.freefall_out_conf = (uint8_t) config->out_conf; + /* Define the offset in bytes for gyroscope cross sensitivity output */ + idx = cross_sense_out_config.start_addr; + + /* discard the MSB as GYR_CAS is of only 7 bit */ + feat_config[idx] = feat_config[idx] & BMI2_GYRO_CROSS_AXES_SENSE_MASK; + + /* Get the gyroscope cross sensitivity coefficient */ + if (feat_config[idx] & BMI2_GYRO_CROSS_AXES_SENSE_SIGN_BIT_MASK) + { + *cross_sense = (int16_t)(((int16_t)feat_config[idx]) - 128); + } + else + { + *cross_sense = (int16_t)(feat_config[idx]); + } } } + else + { + rslt = BMI2_E_INVALID_SENSOR; + } } - else + + return rslt; +} + +/*! + * @brief This internal API selects the sensor/features to be enabled or + * disabled. + */ +static int8_t select_sensor(const uint8_t *sens_list, uint8_t n_sens, uint64_t *sensor_sel) +{ + /* Variable to define error */ + int8_t rslt = BMI2_OK; + + /* Variable to define loop */ + uint8_t count; + + for (count = 0; count < n_sens; count++) { - rslt = BMI2_E_INVALID_SENSOR; + switch (sens_list[count]) + { + case BMI2_ACCEL: + *sensor_sel |= BMI2_ACCEL_SENS_SEL; + break; + case BMI2_GYRO: + *sensor_sel |= BMI2_GYRO_SENS_SEL; + break; + case BMI2_AUX: + *sensor_sel |= BMI2_AUX_SENS_SEL; + break; + case BMI2_TEMP: + *sensor_sel |= BMI2_TEMP_SENS_SEL; + break; + default: + rslt = BMI2_E_INVALID_SENSOR; + break; + } } return rslt; } /*! - * @brief This internal API gets free-fall detection configurations like - * free-fall detection accel settings, and output configuration. + * @brief This internal API enables the selected sensor/features. */ -static int8_t get_free_fall_det_config(struct bmi2_free_fall_det_config *config, struct bmi2_dev *dev) +static int8_t sensor_enable(uint64_t sensor_sel, struct bmi2_dev *dev) { /* Variable to define error */ int8_t rslt; - /* Array to define the feature configuration */ - uint8_t feat_config[BMI2_FEAT_SIZE_IN_BYTES] = { 0 }; + /* Variable to store register values */ + uint8_t reg_data = 0; - /* Variable to define the array offset */ - uint8_t idx = 0; + rslt = bmi2_get_regs(BMI2_PWR_CTRL_ADDR, ®_data, 1, dev); + if (rslt == BMI2_OK) + { + /* Enable accelerometer */ + if (sensor_sel & BMI2_ACCEL_SENS_SEL) + { + reg_data = BMI2_SET_BITS(reg_data, BMI2_ACC_EN, BMI2_ENABLE); + } - /* Variable to define get accel settings in loop */ - uint8_t indx; + /* Enable gyroscope */ + if (sensor_sel & BMI2_GYRO_SENS_SEL) + { + reg_data = BMI2_SET_BITS(reg_data, BMI2_GYR_EN, BMI2_ENABLE); + } - /* Variable to define LSB */ - uint16_t lsb = 0; + /* Enable auxiliary sensor */ + if (sensor_sel & BMI2_AUX_SENS_SEL) + { + reg_data = BMI2_SET_BIT_POS0(reg_data, BMI2_AUX_EN, BMI2_ENABLE); + } - /* Variable to define MSB */ - uint16_t msb = 0; + /* Enable temperature sensor */ + if (sensor_sel & BMI2_TEMP_SENS_SEL) + { + reg_data = BMI2_SET_BITS(reg_data, BMI2_TEMP_EN, BMI2_ENABLE); + } - /* Variable to define a word */ - uint16_t lsb_msb = 0; + /* Enable the sensors that are set in the power control register */ + if (sensor_sel & BMI2_MAIN_SENSORS) + { + rslt = bmi2_set_regs(BMI2_PWR_CTRL_ADDR, ®_data, 1, dev); + } + } - /* Variable to set flag */ - uint8_t feat_found; + return rslt; +} + +/*! + * @brief This internal API disables the selected sensors/features. + */ +static int8_t sensor_disable(uint64_t sensor_sel, struct bmi2_dev *dev) +{ + /* Variable to define error */ + int8_t rslt; - /* Initialize feature configuration for free-fall detection */ - struct bmi2_feature_config freefall_config = { 0, 0, 0 }; + /* Variable to store register values */ + uint8_t reg_data = 0; - /* Search for free-fall detection feature and extract its configuration details */ - feat_found = bmi2_extract_input_feat_config(&freefall_config, BMI2_FREE_FALL_DET, dev); - if (feat_found) + rslt = bmi2_get_regs(BMI2_PWR_CTRL_ADDR, ®_data, 1, dev); + if (rslt == BMI2_OK) { - /* Get the configuration from the page where free-fall detection feature resides */ - rslt = bmi2_get_feat_config(freefall_config.page, feat_config, dev); - if (rslt == BMI2_OK) + /* Disable accelerometer */ + if (sensor_sel & BMI2_ACCEL_SENS_SEL) { - /* Define the offset in bytes for free-fall detection select */ - idx = freefall_config.start_addr; - - /* Get word to calculate out conf */ - lsb = (uint16_t) feat_config[idx++]; - msb = ((uint16_t) feat_config[idx++] << 8); - lsb_msb = lsb | msb; + reg_data = BMI2_SET_BIT_VAL0(reg_data, BMI2_ACC_EN); + } - /* Get out conf */ - config->out_conf = (lsb_msb & BMI2_FREE_FALL_OUT_CONF_MASK) >> BMI2_FREE_FALL_OUT_CONF_POS; + /* Disable gyroscope */ + if (sensor_sel & BMI2_GYRO_SENS_SEL) + { + reg_data = BMI2_SET_BIT_VAL0(reg_data, BMI2_GYR_EN); + } - /* Get the free-fall accel param settings */ - for (indx = 0; indx < BMI2_FREE_FALL_ACCEL_SET_PARAMS; indx++) - { - /* Get word to calculate free-fall detection accel settings */ - lsb = (uint16_t) feat_config[idx++]; - msb = ((uint16_t) feat_config[idx++] << 8); - lsb_msb = lsb | msb; + /* Disable auxiliary sensor */ + if (sensor_sel & BMI2_AUX_SENS_SEL) + { + reg_data = BMI2_SET_BIT_VAL0(reg_data, BMI2_AUX_EN); + } - /* Get free-fall detection accel settings */ - config->freefall_accel_settings[indx] = lsb_msb & BMI2_FREE_FALL_ACCEL_SETT_MASK; - } + /* Disable temperature sensor */ + if (sensor_sel & BMI2_TEMP_SENS_SEL) + { + reg_data = BMI2_SET_BIT_VAL0(reg_data, BMI2_TEMP_EN); + } - /* Copy out_conf value to a local copy in device structure */ - dev->int_map.freefall_out_conf = (uint8_t) config->out_conf; + /* Enable the sensors that are set in the power control register */ + if (sensor_sel & BMI2_MAIN_SENSORS) + { + rslt = bmi2_set_regs(BMI2_PWR_CTRL_ADDR, ®_data, 1, dev); } } - else - { - rslt = BMI2_E_INVALID_SENSOR; - } return rslt; } diff --git a/bmi2.h b/bmi2.h index e483eba..1f51339 100644 --- a/bmi2.h +++ b/bmi2.h @@ -1,40 +1,40 @@ /** - * 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 bmi2.h - * @date 2020-06-05 - * @version v2.53.2 - * - */ +* 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 bmi2.h +* @date 2020-11-04 +* @version v2.63.1 +* +*/ /*! * @defgroup bmi2xy BMI2XY @@ -84,11 +84,8 @@ extern "C" { * @param[in,out] dev : Structure instance of bmi2_dev. * * @return Result of API execution status - * - * @retval BMI2_OK - Success - * @retval BMI2_E_NULL_PTR - Error: Null pointer error - * @retval BMI2_E_COM_FAIL - Error: Communication fail - * @retval BMI2_E_DEV_NOT_FOUND - Invalid device + * @retval 0 -> Success + * @retval < 0 -> Fail */ int8_t bmi2_sec_init(struct bmi2_dev *dev); @@ -117,10 +114,8 @@ int8_t bmi2_sec_init(struct bmi2_dev *dev); * Register address - 0x26, 0x5E. * * @return Result of API execution status - * - * @retval BMI2_OK - Success - * @retval BMI2_E_NULL_PTR - Error: Null pointer error - * @retval BMI2_E_COM_FAIL - Error: Communication fail + * @retval 0 -> Success + * @retval < 0 -> Fail */ int8_t bmi2_get_regs(uint8_t reg_addr, uint8_t *data, uint16_t len, struct bmi2_dev *dev); @@ -139,10 +134,8 @@ int8_t bmi2_get_regs(uint8_t reg_addr, uint8_t *data, uint16_t len, struct bmi2_ * @param[in] dev : Structure instance of bmi2_dev. * * @return Result of API execution status - * - * @retval BMI2_OK - Success - * @retval BMI2_E_NULL_PTR - Error: Null pointer error - * @retval BMI2_E_COM_FAIL - Error: Communication fail + * @retval 0 -> Success + * @retval < 0 -> Fail */ int8_t bmi2_set_regs(uint8_t reg_addr, const uint8_t *data, uint16_t len, struct bmi2_dev *dev); @@ -167,10 +160,8 @@ int8_t bmi2_set_regs(uint8_t reg_addr, const uint8_t *data, uint16_t len, struct * @param[in] dev : Structure instance of bmi2_dev. * * @return Result of API execution status - * - * @retval BMI2_OK - Success. - * @retval BMI2_E_NULL_PTR - Error: Null pointer error - * @retval BMI2_E_COM_FAIL - Error: Communication fail + * @retval 0 -> Success + * @retval < 0 -> Fail */ int8_t bmi2_soft_reset(struct bmi2_dev *dev); @@ -184,7 +175,7 @@ int8_t bmi2_soft_reset(struct bmi2_dev *dev); * \ingroup bmi2ApiConfig * \page bmi2_api_bmi2_get_config_file_version bmi2_get_config_file_version * \code - * int8_t bmi2_get_config_file_version(uint16_t *config_major, uint8_t *config_minor, struct bmi2_dev *dev); + * int8_t bmi2_get_config_file_version(uint8_t *config_major, uint8_t *config_minor, struct bmi2_dev *dev); * \endcode * @details This API is used to get the config file major and minor information. * @@ -192,321 +183,11 @@ int8_t bmi2_soft_reset(struct bmi2_dev *dev); * @param[out] config_major : pointer to data buffer to store the config major. * @param[out] config_minor : pointer to data buffer to store the config minor. * - * @retval BMI2_OK - Success. - * @retval BMI2_E_NULL_PTR - Error: Null pointer error - * @retval BMI2_E_COM_FAIL - Error: Communication fail - */ -int8_t bmi2_get_config_file_version(uint16_t *config_major, uint8_t *config_minor, struct bmi2_dev *dev); - -/*! @cond DOXYGEN_SUPRESS */ - -/** - * \ingroup bmi2 - * \defgroup bmi2ApiSensor Feature Set - * @brief Enable / Disable features of the sensor - */ - -/*! - * \ingroup bmi2ApiSensor - * \page bmi2_api_bmi2_sensor_enable bmi2_sensor_enable - * \code - * int8_t bmi2_sensor_enable(const uint8_t *sens_list, uint8_t n_sens, struct bmi2_dev *dev); - * \endcode - * @details This API selects the sensors/features to be enabled. - * - * @param[in] sens_list : Pointer to select the sensor/feature. - * @param[in] n_sens : Number of sensors selected. - * @param[in, out] dev : Structure instance of bmi2_dev. - * - * @note Sensors/features that can be enabled. - * - *@verbatim - * sens_list | Values - * -------------------------|----------- - * BMI2_ACCEL | 0 - * BMI2_GYRO | 1 - * BMI2_AUX | 2 - * BMI2_SIG_MOTION | 3 - * BMI2_ANY_MOTION | 4 - * BMI2_NO_MOTION | 5 - * BMI2_STEP_DETECTOR | 6 - * BMI2_STEP_COUNTER | 7 - * BMI2_STEP_ACTIVITY | 8 - * BMI2_GYRO_GAIN_UPDATE | 9 - * BMI2_TILT | 10 - * BMI2_UP_HOLD_TO_WAKE | 11 - * BMI2_GLANCE_DETECTOR | 12 - * BMI2_WAKE_UP | 13 - * BMI2_ORIENTATION | 14 - * BMI2_HIGH_G | 15 - * BMI2_LOW_G | 16 - * BMI2_FLAT | 17 - * BMI2_EXT_SENS_SYNC | 18 - * BMI2_WRIST_GESTURE | 19 - * BMI2_WRIST_WEAR_WAKE_UP | 20 - * BMI2_WRIST_WEAR_WAKE_UP_WH | 21 - * BMI2_WRIST_GESTURE_WH | 22 - * BMI2_PRIMARY_OIS | 23 - * BMI2_FREE_FALL_DET | 24 - * BMI2_SINGLE_TAP | 25 - * BMI2_DOUBLE_TAP | 26 - * BMI2_TRIPLE_TAP | 27 - * BMI2_TEMP | 31 - * BMI2_GYRO_SELF_OFF | 33 - * BMI2_ACTIVITY_RECOGNITION | 34 - *@endverbatim - * - * @example uint8_t sens_list[2] = {BMI2_ACCEL, BMI2_GYRO}; - * uint8_t n_sens = 2; - * - * @return Result of API execution status - * - * @retval BMI2_OK - Success. - * @retval BMI2_E_NULL_PTR - Error: Null pointer error - * @retval BMI2_E_COM_FAIL - Error: Communication fail - * @retval BMI2_E_INVALID_SENSOR - Error: Invalid sensor - */ -int8_t bmi2_sensor_enable(const uint8_t *sens_list, uint8_t n_sens, struct bmi2_dev *dev); - -/*! - * \ingroup bmi2ApiSensor - * \page bmi2_api_bmi2_sensor_disable bmi2_sensor_disable - * \code - * int8_t bmi2_sensor_disable(const uint8_t *sens_list, uint8_t n_sens, struct bmi2_dev *dev); - * \endcode - * @details This API selects the sensors/features to be disabled. - * - * @param[in] sens_list : Pointer to select the sensor/feature. - * @param[in] n_sens : Number of sensors selected. - * @param[in, out] dev : Structure instance of bmi2_dev. - * - * @note Sensors/features that can be disabled. - * - *@verbatim - * sens_list | Values - * ----------------------------|----------- - * BMI2_ACCEL | 0 - * BMI2_GYRO | 1 - * BMI2_AUX | 2 - * BMI2_SIG_MOTION | 3 - * BMI2_ANY_MOTION | 4 - * BMI2_NO_MOTION | 5 - * BMI2_STEP_DETECTOR | 6 - * BMI2_STEP_COUNTER | 7 - * BMI2_STEP_ACTIVITY | 8 - * BMI2_GYRO_GAIN_UPDATE | 9 - * BMI2_TILT | 10 - * BMI2_UP_HOLD_TO_WAKE | 11 - * BMI2_GLANCE_DETECTOR | 12 - * BMI2_WAKE_UP | 13 - * BMI2_ORIENTATION | 14 - * BMI2_HIGH_G | 15 - * BMI2_LOW_G | 16 - * BMI2_FLAT | 17 - * BMI2_EXT_SENS_SYNC | 18 - * BMI2_WRIST_GESTURE | 19 - * BMI2_WRIST_WEAR_WAKE_UP | 20 - * BMI2_WRIST_WEAR_WAKE_UP_WH | 21 - * BMI2_WRIST_GESTURE_WH | 22 - * BMI2_PRIMARY_OIS | 23 - * BMI2_FREE_FALL_DET | 24 - * BMI2_SINGLE_TAP | 25 - * BMI2_DOUBLE_TAP | 26 - * BMI2_TRIPLE_TAP | 27 - * BMI2_TEMP | 31 - * BMI2_GYRO_SELF_OFF | 33 - * BMI2_ACTIVITY_RECOGNITION | 34 - *@endverbatim - * - * @example uint8_t sens_list[2] = {BMI2_ACCEL, BMI2_GYRO}; - * uint8_t n_sens = 2; - * * @return Result of API execution status - * - * @retval BMI2_OK - Success. - * @retval BMI2_E_NULL_PTR - Error: Null pointer error - * @retval BMI2_E_COM_FAIL - Error: Communication fail - * @retval BMI2_E_INVALID_SENSOR - Error: Invalid sensor - */ -int8_t bmi2_sensor_disable(const uint8_t *sens_list, uint8_t n_sens, struct bmi2_dev *dev); - -/*! @endcond */ - -/** - * \ingroup bmi2 - * \defgroup bmi2ApiSensorC Sensor Configuration - * @brief Enable / Disable feature configuration of the sensor - */ - -/*! - * \ingroup bmi2ApiSensorC - * \page bmi2_api_bmi2_set_sensor_config bmi2_set_sensor_config - * \code - * int8_t bmi2_set_sensor_config(struct bmi2_sens_config *sens_cfg, uint8_t n_sens, struct bmi2_dev *dev); - * \endcode - * @details This API sets the sensor/feature configuration. - * - * @param[in] sens_cfg : Structure instance of bmi2_sens_config. - * @param[in] n_sens : Number of sensors selected. - * @param[in, out] dev : Structure instance of bmi2_dev. - * - * @note Sensors/features that can be configured - * - *@verbatim - * sens_list | Values - * ----------------------------|----------- - * BMI2_ACCEL | 0 - * BMI2_GYRO | 1 - * BMI2_AUX | 2 - * BMI2_SIG_MOTION | 3 - * BMI2_ANY_MOTION | 4 - * BMI2_NO_MOTION | 5 - * BMI2_STEP_DETECTOR | 6 - * BMI2_STEP_COUNTER | 7 - * BMI2_STEP_ACTIVITY | 8 - * BMI2_GYRO_GAIN_UPDATE | 9 - * BMI2_TILT | 10 - * BMI2_UP_HOLD_TO_WAKE | 11 - * BMI2_GLANCE_DETECTOR | 12 - * BMI2_WAKE_UP | 13 - * BMI2_ORIENTATION | 14 - * BMI2_HIGH_G | 15 - * BMI2_LOW_G | 16 - * BMI2_FLAT | 17 - * BMI2_EXT_SENS_SYNC | 18 - * BMI2_WRIST_GESTURE | 19 - * BMI2_WRIST_WEAR_WAKE_UP | 20 - * BMI2_WRIST_WEAR_WAKE_UP_WH | 21 - * BMI2_WRIST_GESTURE_WH | 22 - * BMI2_PRIMARY_OIS | 23 - * BMI2_FREE_FALL_DET | 24 - * BMI2_SINGLE_TAP | 25 - * BMI2_DOUBLE_TAP | 26 - * BMI2_TRIPLE_TAP | 27 - * BMI2_TEMP | 31 - * BMI2_GYRO_SELF_OFF | 33 - * BMI2_ACTIVITY_RECOGNITION | 34 - *@endverbatim - * - * @return Result of API execution status - * - * @retval BMI2_OK - Success. - * @retval BMI2_E_NULL_PTR - Error: Null pointer error - * @retval BMI2_E_COM_FAIL - Error: Communication fail - * @retval BMI2_E_INVALID_SENSOR - Error: Invalid sensor - * @retval BMI2_E_SET_APS_FAIL - Error: Set Advance Power Save Fail - * @retval BMI2_E_INVALID_PAGE - Error: Invalid Page - */ -int8_t bmi2_set_sensor_config(struct bmi2_sens_config *sens_cfg, uint8_t n_sens, struct bmi2_dev *dev); - -/*! - * \ingroup bmi2ApiSensorC - * \page bmi2_api_bmi2_get_sensor_config bmi2_get_sensor_config - * \code - * int8_t bmi2_get_sensor_config(struct bmi2_sens_config *sens_cfg, uint8_t n_sens, struct bmi2_dev *dev); - * \endcode - * @details This API gets the sensor/feature configuration. - * - * @param[in] sens_cfg : Structure instance of bmi2_sens_config. - * @param[in] n_sens : Number of sensors selected. - * @param[in, out] dev : Structure instance of bmi2_dev. - * - * @note Sensors/features whose configurations can be read. - * - *@verbatim - * sens_list | Values - * -------------------------|----------- - * BMI2_ACCEL | 0 - * BMI2_GYRO | 1 - * BMI2_AUX | 2 - * BMI2_SIG_MOTION | 3 - * BMI2_ANY_MOTION | 4 - * BMI2_NO_MOTION | 5 - * BMI2_STEP_DETECTOR | 6 - * BMI2_STEP_COUNTER | 7 - * BMI2_STEP_ACTIVITY | 8 - * BMI2_GYRO_GAIN_UPDATE | 9 - * BMI2_TILT | 10 - * BMI2_UP_HOLD_TO_WAKE | 11 - * BMI2_GLANCE_DETECTOR | 12 - * BMI2_WAKE_UP | 13 - * BMI2_ORIENTATION | 14 - * BMI2_HIGH_G | 15 - * BMI2_LOW_G | 16 - * BMI2_FLAT | 17 - * BMI2_EXT_SENS_SYNC | 18 - * BMI2_WRIST_GESTURE | 19 - * BMI2_WRIST_WEAR_WAKE_UP | 20 - * BMI2_WRIST_WEAR_WAKE_UP_WH | 21 - * BMI2_WRIST_GESTURE_WH | 22 - * BMI2_PRIMARY_OIS | 23 - * BMI2_FREE_FALL_DET | 24 - * BMI2_SINGLE_TAP | 25 - * BMI2_DOUBLE_TAP | 26 - * BMI2_TRIPLE_TAP | 27 - * BMI2_TEMP | 31 - * BMI2_GYRO_SELF_OFF | 33 - * BMI2_ACTIVITY_RECOGNITION | 34 - *@endverbatim - * - * @return Result of API execution status - * - * @retval BMI2_OK - Success. - * @retval BMI2_E_NULL_PTR - Error: Null pointer error - * @retval BMI2_E_COM_FAIL - Error: Communication fail - * @retval BMI2_E_INVALID_SENSOR - Error: Invalid sensor - * @retval BMI2_E_SET_APS_FAIL - Error: Set Advance Power Save Fail - * @retval BMI2_E_INVALID_PAGE - Error: Invalid Page + * @retval 0 -> Success + * @retval < 0 -> Fail */ -int8_t bmi2_get_sensor_config(struct bmi2_sens_config *sens_cfg, uint8_t n_sens, struct bmi2_dev *dev); - -/** - * \ingroup bmi2 - * \defgroup bmi2ApiSensorD Sensor Data - * @brief Get sensor data - */ - -/*! - * \ingroup bmi2ApiSensorD - * \page bmi2_api_bmi2_get_sensor_data bmi2_get_sensor_data - * \code - * int8_t bmi2_get_sensor_data(struct bmi2_sensor_data *sensor_data, uint8_t n_sens, struct bmi2_dev *dev); - * \endcode - * @details This API gets the sensor/feature data for accelerometer, gyroscope, - * auxiliary sensor, step counter, high-g, gyroscope user-gain update, - * orientation, gyroscope cross sensitivity and error status for NVM and VFRM. - * - * @param[out] sensor_data : Structure instance of bmi2_sensor_data. - * @param[in] n_sens : Number of sensors selected. - * @param[in] dev : Structure instance of bmi2_dev. - * - * @note Sensors/features whose data can be read - * - *@verbatim - * sens_list | Values - * ---------------------|----------- - * BMI2_ACCEL | 0 - * BMI2_GYRO | 1 - * BMI2_AUX | 2 - * BMI2_ORIENTATION | 7 - * BMI2_STEP_COUNTER | 10 - * BMI2_GYRO_GAIN_UPDATE| 12 - * BMI2_HIGH_G | 16 - * BMI2_NVM_STATUS | 26 - * BMI2_VFRM_STATUS | 27 - * BMI2_GYRO_CROSS_SENSE| 28 - *@endverbatim - * - * @return Result of API execution status - * - * @retval BMI2_OK - Success. - * @retval BMI2_E_NULL_PTR - Error: Null pointer error - * @retval BMI2_E_COM_FAIL - Error: Communication fail - * @retval BMI2_E_INVALID_SENSOR - Error: Invalid sensor - * @retval BMI2_E_SET_APS_FAIL - Error: Set Advance Power Save Fail - * @retval BMI2_E_INVALID_PAGE - Error: Invalid Page - */ -int8_t bmi2_get_sensor_data(struct bmi2_sensor_data *sensor_data, uint8_t n_sens, struct bmi2_dev *dev); +int8_t bmi2_get_config_file_version(uint8_t *config_major, uint8_t *config_minor, struct bmi2_dev *dev); /** * \ingroup bmi2 @@ -533,11 +214,8 @@ int8_t bmi2_get_sensor_data(struct bmi2_sensor_data *sensor_data, uint8_t n_sens *@endverbatim * * @return Result of API execution status - * - * @retval BMI2_OK - Success. - * @retval BMI2_E_NULL_PTR - Error: Null pointer error - * @retval BMI2_E_COM_FAIL - Error: Communication fail - * @retval BMI2_E_SET_APS_FAIL - Error: Set Advance Power Save Fail + * @retval 0 -> Success + * @retval < 0 -> Fail */ int8_t bmi2_set_adv_power_save(uint8_t enable, struct bmi2_dev *dev); @@ -579,12 +257,8 @@ int8_t bmi2_get_adv_power_save(uint8_t *aps_status, struct bmi2_dev *dev); * @param[in] dev : Structure instance of bmi2_dev. * * @return Result of API execution status - * - * @retval BMI2_OK - Success. - * @retval BMI2_E_NULL_PTR - Error: Null pointer error - * @retval BMI2_E_COM_FAIL - Error: Communication fail - * @retval BMI2_E_SET_APS_FAIL - Error: Set Advance Power Save Fail - * @retval BMI2_E_CONFIG_LOAD - Configuration load fail + * @retval 0 -> Success + * @retval < 0 -> Fail */ int8_t bmi2_write_config_file(struct bmi2_dev *dev); @@ -609,11 +283,8 @@ int8_t bmi2_write_config_file(struct bmi2_dev *dev); * @param[in] dev : Structure instance of bmi2_dev. * * @return Result of API execution status - * - * @retval BMI2_OK - Success. - * @retval BMI2_E_NULL_PTR - Error: Null pointer error - * @retval BMI2_E_COM_FAIL - Error: Communication fail - * @retval BMI2_E_INVALID_INT_PIN - Error: Invalid interrupt pin + * @retval 0 -> Success + * @retval < 0 -> Fail */ int8_t bmi2_set_int_pin_config(const struct bmi2_int_pin_config *int_cfg, struct bmi2_dev *dev); @@ -632,11 +303,8 @@ int8_t bmi2_set_int_pin_config(const struct bmi2_int_pin_config *int_cfg, struct * @param[in] dev : Structure instance of bmi2_dev. * * @return Result of API execution status - * - * @retval BMI2_OK - Success. - * @retval BMI2_E_NULL_PTR - Error: Null pointer error - * @retval BMI2_E_COM_FAIL - Error: Communication fail - * @retval BMI2_E_INVALID_INT_PIN - Error: Invalid interrupt pin + * @retval 0 -> Success + * @retval < 0 -> Fail */ int8_t bmi2_get_int_pin_config(struct bmi2_int_pin_config *int_cfg, struct bmi2_dev *dev); @@ -666,12 +334,184 @@ int8_t bmi2_get_int_pin_config(struct bmi2_int_pin_config *int_cfg, struct bmi2_ *@endverbatim * * @return Result of API execution status - * - * @retval BMI2_OK - Success. - * @retval BMI2_E_NULL_PTR - Error: Null pointer error - * @retval BMI2_E_COM_FAIL - Error: Communication fail + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +int8_t bmi2_get_int_status(uint16_t *int_status, struct bmi2_dev *dev); + +/** + * \ingroup bmi2 + * \defgroup bmi2ApiSensorC Sensor Configuration + * @brief Enable / Disable feature configuration of the sensor + */ + +/*! + * \ingroup bmi2ApiSensorC + * \page bmi2_api_bmi2_set_sensor_config bmi2_set_sensor_config + * \code + * int8_t bmi2_set_sensor_config(struct bmi2_sens_config *sens_cfg, uint8_t n_sens, struct bmi2_dev *dev); + * \endcode + * @details This API sets the sensor/feature configuration. + * + * @param[in] sens_cfg : Structure instance of bmi2_sens_config. + * @param[in] n_sens : Number of sensors selected. + * @param[in, out] dev : Structure instance of bmi2_dev. + * + * @note Sensors/features that can be configured + * + *@verbatim + * sens_list | Values + * ----------------------------|----------- + * BMI2_ACCEL | 0 + * BMI2_GYRO | 1 + * BMI2_AUX | 2 + * BMI2_GYRO_GAIN_UPDATE | 9 + *@endverbatim + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +int8_t bmi2_set_sensor_config(struct bmi2_sens_config *sens_cfg, uint8_t n_sens, struct bmi2_dev *dev); + +/*! + * \ingroup bmi2ApiSensorC + * \page bmi2_api_bmi2_get_sensor_config bmi2_get_sensor_config + * \code + * int8_t bmi2_get_sensor_config(struct bmi2_sens_config *sens_cfg, uint8_t n_sens, struct bmi2_dev *dev); + * \endcode + * @details This API gets the sensor/feature configuration. + * + * @param[in] sens_cfg : Structure instance of bmi2_sens_config. + * @param[in] n_sens : Number of sensors selected. + * @param[in, out] dev : Structure instance of bmi2_dev. + * + * @note Sensors/features whose configurations can be read. + * + *@verbatim + * sens_list | Values + * -------------------------|----------- + * BMI2_ACCEL | 0 + * BMI2_GYRO | 1 + * BMI2_AUX | 2 + * BMI2_GYRO_GAIN_UPDATE | 9 + *@endverbatim + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +int8_t bmi2_get_sensor_config(struct bmi2_sens_config *sens_cfg, uint8_t n_sens, struct bmi2_dev *dev); + +/** + * \ingroup bmi2 + * \defgroup bmi2ApiSensor Feature Set + * @brief Enable / Disable features of the sensor + */ + +/*! + * \ingroup bmi2ApiSensor + * \page bmi2_api_bmi2_sensor_enable bmi2_sensor_enable + * \code + * int8_t bmi2_sensor_enable(const uint8_t *sens_list, uint8_t n_sens, struct bmi2_dev *dev); + * \endcode + * @details This API selects the sensors/features to be enabled. + * + * @param[in] sens_list : Pointer to select the sensor/feature. + * @param[in] n_sens : Number of sensors selected. + * @param[in, out] dev : Structure instance of bmi2_dev. + * + * @note Sensors/features that can be enabled. + * + *@verbatim + * sens_list | Values + * -------------------------|----------- + * BMI2_ACCEL | 0 + * BMI2_GYRO | 1 + * BMI2_AUX | 2 + * BMI2_TEMP | 31 + *@endverbatim + * + * @note : + * example uint8_t sens_list[2] = {BMI2_ACCEL, BMI2_GYRO}; + * uint8_t n_sens = 2; + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +int8_t bmi2_sensor_enable(const uint8_t *sens_list, uint8_t n_sens, struct bmi2_dev *dev); + +/*! + * \ingroup bmi2ApiSensor + * \page bmi2_api_bmi2_sensor_disable bmi2_sensor_disable + * \code + * int8_t bmi2_sensor_disable(const uint8_t *sens_list, uint8_t n_sens, struct bmi2_dev *dev); + * \endcode + * @details This API selects the sensors/features to be disabled. + * + * @param[in] sens_list : Pointer to select the sensor/feature. + * @param[in] n_sens : Number of sensors selected. + * @param[in, out] dev : Structure instance of bmi2_dev. + * + * @note Sensors/features that can be disabled. + * + *@verbatim + * sens_list | Values + * ----------------------------|----------- + * BMI2_ACCEL | 0 + * BMI2_GYRO | 1 + * BMI2_AUX | 2 + * BMI2_TEMP | 31 + *@endverbatim + * + * @note : + * example uint8_t sens_list[2] = {BMI2_ACCEL, BMI2_GYRO}; + * uint8_t n_sens = 2; + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +int8_t bmi2_sensor_disable(const uint8_t *sens_list, uint8_t n_sens, struct bmi2_dev *dev); + +/** + * \ingroup bmi2 + * \defgroup bmi2ApiSensorD Sensor Data + * @brief Get sensor data + */ + +/*! + * \ingroup bmi2ApiSensorD + * \page bmi2_api_bmi2_get_sensor_data bmi2_get_sensor_data + * \code + * int8_t bmi2_get_sensor_data(struct bmi2_sensor_data *sensor_data, uint8_t n_sens, struct bmi2_dev *dev); + * \endcode + * @details This API gets the sensor/feature data for accelerometer, gyroscope, + * auxiliary sensor, step counter, high-g, gyroscope user-gain update, + * orientation, gyroscope cross sensitivity and error status for NVM and VFRM. + * + * @param[out] sensor_data : Structure instance of bmi2_sensor_data. + * @param[in] n_sens : Number of sensors selected. + * @param[in] dev : Structure instance of bmi2_dev. + * + * @note Sensors/features whose data can be read + * + *@verbatim + * sens_list | Values + * ---------------------|----------- + * BMI2_ACCEL | 0 + * BMI2_GYRO | 1 + * BMI2_AUX | 2 + * BMI2_GYRO_GAIN_UPDATE| 12 + * BMI2_GYRO_CROSS_SENSE| 28 + *@endverbatim + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail */ -int8_t bmi2_get_int_status(uint16_t *int_status, struct bmi2_dev *dev); +int8_t bmi2_get_sensor_data(struct bmi2_sensor_data *sensor_data, uint8_t n_sens, struct bmi2_dev *dev); /** * \ingroup bmi2 @@ -699,10 +539,8 @@ int8_t bmi2_get_int_status(uint16_t *int_status, struct bmi2_dev *dev); *@endverbatim * * @return Result of API execution status - * - * @retval BMI2_OK - Success. - * @retval BMI2_E_NULL_PTR - Error: Null pointer error - * @retval BMI2_E_COM_FAIL - Error: Communication fail + * @retval 0 -> Success + * @retval < 0 -> Fail */ int8_t bmi2_set_fifo_config(uint16_t config, uint8_t enable, struct bmi2_dev *dev); @@ -718,10 +556,8 @@ int8_t bmi2_set_fifo_config(uint16_t config, uint8_t enable, struct bmi2_dev *de * @param[in] dev : Structure instance of bmi2_dev. * * @return Result of API execution status - * - * @retval BMI2_OK - Success. - * @retval BMI2_E_NULL_PTR - Error: Null pointer error - * @retval BMI2_E_COM_FAIL - Error: Communication fail + * @retval 0 -> Success + * @retval < 0 -> Fail */ int8_t bmi2_get_fifo_config(uint16_t *fifo_config, struct bmi2_dev *dev); @@ -739,10 +575,8 @@ int8_t bmi2_get_fifo_config(uint16_t *fifo_config, struct bmi2_dev *dev); * @note APS has to be disabled before calling this function. * * @return Result of API execution status - * - * @retval BMI2_OK - Success. - * @retval BMI2_E_NULL_PTR - Error: Null pointer error - * @retval BMI2_E_COM_FAIL - Error: Communication fail + * @retval 0 -> Success + * @retval < 0 -> Fail */ int8_t bmi2_read_fifo_data(struct bmi2_fifo_frame *fifo, struct bmi2_dev *dev); @@ -766,11 +600,8 @@ int8_t bmi2_read_fifo_data(struct bmi2_fifo_frame *fifo, struct bmi2_dev *dev); * @param[in] dev : Structure instance of bmi2_dev. * * @return Result of API execution status - * - * @retval BMI2_OK - Success. - * @retval BMI2_E_NULL_PTR - Error: Null pointer error - * @retval BMI2_W_FIFO_EMPTY - Warning : FIFO is empty - * @retval BMI2_W_PARTIAL_READ - Warning : There are more frames to be read + * @retval 0 -> Success + * @retval < 0 -> Fail */ int8_t bmi2_extract_accel(struct bmi2_sens_axes_data *accel_data, uint16_t *accel_length, @@ -797,11 +628,8 @@ int8_t bmi2_extract_accel(struct bmi2_sens_axes_data *accel_data, * @param[in] dev : Structure instance of bmi2_dev. * * @return Result of API execution status - * - * @retval BMI2_OK - Success. - * @retval BMI2_E_NULL_PTR - Error: Null pointer error - * @retval BMI2_W_FIFO_EMPTY - Warning : FIFO is empty - * @retval BMI2_W_PARTIAL_READ - Warning : There are more frames to be read + * @retval 0 -> Success + * @retval < 0 -> Fail */ int8_t bmi2_extract_aux(struct bmi2_aux_fifo_data *aux, uint16_t *aux_length, @@ -828,11 +656,8 @@ int8_t bmi2_extract_aux(struct bmi2_aux_fifo_data *aux, * @param[in] dev : Structure instance of bmi2_dev. * * @return Result of API execution status - * - * @retval BMI2_OK - Success. - * @retval BMI2_E_NULL_PTR - Error: Null pointer error - * @retval BMI2_W_FIFO_EMPTY - Warning : FIFO is empty - * @retval BMI2_W_PARTIAL_READ - Warning : There are more frames to be read + * @retval 0 -> Success + * @retval < 0 -> Fail */ int8_t bmi2_extract_gyro(struct bmi2_sens_axes_data *gyro_data, uint16_t *gyro_length, @@ -865,10 +690,8 @@ int8_t bmi2_extract_gyro(struct bmi2_sens_axes_data *gyro_data, *@endverbatim * * @return Result of API execution status - * - * @retval BMI2_OK - Success. - * @retval BMI2_E_NULL_PTR - Error: Null pointer error - * @retval BMI2_E_COM_FAIL - Error: Communication fail + * @retval 0 -> Success + * @retval < 0 -> Fail */ int8_t bmi2_set_command_register(uint8_t command, struct bmi2_dev *dev); @@ -891,10 +714,8 @@ int8_t bmi2_set_command_register(uint8_t command, struct bmi2_dev *dev); *@endverbatim * * @return Result of API execution status - * - * @retval BMI2_OK - Success. - * @retval BMI2_E_NULL_PTR - Error: Null pointer error - * @retval BMI2_E_COM_FAIL - Error: Communication fail + * @retval 0 -> Success + * @retval < 0 -> Fail */ int8_t bmi2_set_fifo_self_wake_up(uint8_t fifo_self_wake_up, struct bmi2_dev *dev); @@ -918,10 +739,8 @@ int8_t bmi2_set_fifo_self_wake_up(uint8_t fifo_self_wake_up, struct bmi2_dev *de *@endverbatim * * @return Result of API execution status - * - * @retval BMI2_OK - Success. - * @retval BMI2_E_NULL_PTR - Error: Null pointer error - * @retval BMI2_E_COM_FAIL - Error: Communication fail + * @retval 0 -> Success + * @retval < 0 -> Fail */ int8_t bmi2_get_fifo_self_wake_up(uint8_t *fifo_self_wake_up, struct bmi2_dev *dev); @@ -937,10 +756,8 @@ int8_t bmi2_get_fifo_self_wake_up(uint8_t *fifo_self_wake_up, struct bmi2_dev *d * @param[in] dev : Structure instance of bmi2_dev. * * @return Result of API execution status - * - * @retval BMI2_OK - Success. - * @retval BMI2_E_NULL_PTR - Error: Null pointer error - * @retval BMI2_E_COM_FAIL - Error: Communication fail + * @retval 0 -> Success + * @retval < 0 -> Fail */ int8_t bmi2_set_fifo_wm(uint16_t fifo_wm, struct bmi2_dev *dev); @@ -956,10 +773,8 @@ int8_t bmi2_set_fifo_wm(uint16_t fifo_wm, struct bmi2_dev *dev); * @param[in] dev : Structure instance of bmi2_dev. * * @return Result of API execution status - * - * @retval BMI2_OK - Success. - * @retval BMI2_E_NULL_PTR - Error: Null pointer error - * @retval BMI2_E_COM_FAIL - Error: Communication fail + * @retval 0 -> Success + * @retval < 0 -> Fail */ int8_t bmi2_get_fifo_wm(uint16_t *fifo_wm, struct bmi2_dev *dev); @@ -992,12 +807,8 @@ int8_t bmi2_get_fifo_wm(uint16_t *fifo_wm, struct bmi2_dev *dev); *@endverbatim * * @return Result of API execution status - * - * @retval BMI2_OK - Success. - * @retval BMI2_E_NULL_PTR - Error: Null pointer error - * @retval BMI2_E_COM_FAIL - Error: Communication fail - * @retval BMI2_E_INVALID_SENSOR - Error: Invalid sensor - * @retval BMI2_E_OUT_OF_RANGE - Error: Out of range + * @retval 0 -> Success + * @retval < 0 -> Fail */ int8_t bmi2_set_fifo_filter_data(uint8_t sens_sel, uint8_t fifo_filter_data, struct bmi2_dev *dev); @@ -1029,11 +840,8 @@ int8_t bmi2_set_fifo_filter_data(uint8_t sens_sel, uint8_t fifo_filter_data, str *@endverbatim * * @return Result of API execution status - * - * @retval BMI2_OK - Success. - * @retval BMI2_E_NULL_PTR - Error: Null pointer error - * @retval BMI2_E_COM_FAIL - Error: Communication fail - * @retval BMI2_E_INVALID_SENSOR - Error: Invalid sensor + * @retval 0 -> Success + * @retval < 0 -> Fail */ int8_t bmi2_get_fifo_filter_data(uint8_t sens_sel, uint8_t *fifo_filter_data, struct bmi2_dev *dev); @@ -1059,12 +867,8 @@ int8_t bmi2_get_fifo_filter_data(uint8_t sens_sel, uint8_t *fifo_filter_data, st *@endverbatim * * @return Result of API execution status - * - * @retval BMI2_OK - Success. - * @retval BMI2_E_NULL_PTR - Error: Null pointer error - * @retval BMI2_E_COM_FAIL - Error: Communication fail - * @retval BMI2_E_INVALID_SENSOR - Error: Invalid sensor - * @retval BMI2_E_OUT_OF_RANGE - Error: Out of range + * @retval 0 -> Success + * @retval < 0 -> Fail */ int8_t bmi2_set_fifo_down_sample(uint8_t sens_sel, uint8_t fifo_down_samp, struct bmi2_dev *dev); @@ -1090,11 +894,8 @@ int8_t bmi2_set_fifo_down_sample(uint8_t sens_sel, uint8_t fifo_down_samp, struc *@endverbatim * * @return Result of API execution status - * - * @retval BMI2_OK - Success. - * @retval BMI2_E_NULL_PTR - Error: Null pointer error - * @retval BMI2_E_COM_FAIL - Error: Communication fail - * @retval BMI2_E_INVALID_SENSOR - Error: Invalid sensor + * @retval 0 -> Success + * @retval < 0 -> Fail */ int8_t bmi2_get_fifo_down_sample(uint8_t sens_sel, uint8_t *fifo_down_samp, struct bmi2_dev *dev); @@ -1115,10 +916,8 @@ int8_t bmi2_get_fifo_down_sample(uint8_t sens_sel, uint8_t *fifo_down_samp, stru * written. * * @return Result of API execution status - * - * @retval BMI2_OK - Success. - * @retval BMI2_E_NULL_PTR - Error: Null pointer error - * @retval BMI2_E_COM_FAIL - Error: Communication fail + * @retval 0 -> Success + * @retval < 0 -> Fail */ int8_t bmi2_get_fifo_length(uint16_t *fifo_length, struct bmi2_dev *dev); @@ -1147,10 +946,8 @@ int8_t bmi2_get_fifo_length(uint16_t *fifo_length, struct bmi2_dev *dev); *@endverbatim * * @return Result of API execution status - * - * @retval BMI2_OK - Success. - * @retval BMI2_E_NULL_PTR - Error: Null pointer error - * @retval BMI2_E_COM_FAIL - Error: Communication fail + * @retval 0 -> Success + * @retval < 0 -> Fail */ int8_t bmi2_set_ois_interface(uint8_t enable, struct bmi2_dev *dev); @@ -1177,12 +974,8 @@ int8_t bmi2_set_ois_interface(uint8_t enable, struct bmi2_dev *dev); * @note Change of BMI2_AUX_RD_ADDR is only allowed if AUX is not busy. * * @return Result of API execution status - * - * @retval BMI2_OK - Success. - * @retval BMI2_E_NULL_PTR - Error: Null pointer error - * @retval BMI2_E_COM_FAIL - Error: Communication fail - * @retval BMI2_E_SET_APS_FAIL - Error: Set Advance Power Save Fail - * @retval BMI2_E_AUX_INVALID_CFG - Error: Invalid auxiliary configuration. + * @retval 0 -> Success + * @retval < 0 -> Fail */ int8_t bmi2_read_aux_man_mode(uint8_t reg_addr, uint8_t *aux_data, uint16_t len, struct bmi2_dev *dev); @@ -1203,12 +996,8 @@ int8_t bmi2_read_aux_man_mode(uint8_t reg_addr, uint8_t *aux_data, uint16_t len, * @note Change of BMI2_AUX_WR_ADDR is only allowed if AUX is not busy. * * @return Result of API execution status - * - * @retval BMI2_OK - Success. - * @retval BMI2_E_NULL_PTR - Error: Null pointer error - * @retval BMI2_E_COM_FAIL - Error: Communication fail - * @retval BMI2_E_SET_APS_FAIL - Error: Set Advance Power Save Fail - * @retval BMI2_E_AUX_INVALID_CFG - Error: Invalid auxiliary configuration. + * @retval 0 -> Success + * @retval < 0 -> Fail */ int8_t bmi2_write_aux_man_mode(uint8_t reg_addr, const uint8_t *aux_data, uint16_t len, struct bmi2_dev *dev); @@ -1230,12 +1019,8 @@ int8_t bmi2_write_aux_man_mode(uint8_t reg_addr, const uint8_t *aux_data, uint16 * @note Change of BMI2_AUX_WR_ADDR is only allowed if AUX is not busy. * * @return Result of API execution status - * - * @retval BMI2_OK - Success. - * @retval BMI2_E_NULL_PTR - Error: Null pointer error - * @retval BMI2_E_COM_FAIL - Error: Communication fail - * @retval BMI2_E_SET_APS_FAIL - Error: Set Advance Power Save Fail - * @retval BMI2_E_AUX_INVALID_CFG - Error: Invalid auxiliary configuration. + * @retval 0 -> Success + * @retval < 0 -> Fail */ int8_t bmi2_write_aux_interleaved(uint8_t reg_addr, const uint8_t *aux_data, uint16_t len, struct bmi2_dev *dev); @@ -1268,10 +1053,8 @@ int8_t bmi2_write_aux_interleaved(uint8_t reg_addr, const uint8_t *aux_data, uin *@endverbatim * * @return Result of API execution status - * - * @retval BMI2_OK - Success. - * @retval BMI2_E_NULL_PTR - Error: Null pointer error - * @retval BMI2_E_COM_FAIL - Error: Communication fail + * @retval 0 -> Success + * @retval < 0 -> Fail */ int8_t bmi2_get_status(uint8_t *status, struct bmi2_dev *dev); @@ -1295,10 +1078,8 @@ int8_t bmi2_get_status(uint8_t *status, struct bmi2_dev *dev); * @param[in] dev : Structure instance of bmi2_dev. * * @return Result of API execution status - * - * @retval BMI2_OK - Success. - * @retval BMI2_E_NULL_PTR - Error: Null pointer error - * @retval BMI2_E_COM_FAIL - Error: Communication fail + * @retval 0 -> Success + * @retval < 0 -> Fail */ int8_t bmi2_write_sync_commands(const uint8_t *command, uint8_t n_comm, struct bmi2_dev *dev); @@ -1320,11 +1101,8 @@ int8_t bmi2_write_sync_commands(const uint8_t *command, uint8_t n_comm, struct b * @param[in] dev : Structure instance of bmi2_dev. * * @return Result of API execution status - * - * @retval BMI2_OK - Success. - * @retval BMI2_E_NULL_PTR - Error: Null pointer error - * @retval BMI2_E_COM_FAIL - Error: Communication fail - * @retval BMI2_E_SELF_TEST_FAIL - Error: Self test fail + * @retval 0 -> Success + * @retval < 0 -> Fail */ int8_t bmi2_perform_accel_self_test(struct bmi2_dev *dev); @@ -1332,23 +1110,18 @@ int8_t bmi2_perform_accel_self_test(struct bmi2_dev *dev); * \ingroup bmi2ApiInt * \page bmi2_api_bmi2_map_feat_int bmi2_map_feat_int * \code - * int8_t bbmi2_map_feat_int(const struct bmi2_sens_int_config *sens_int, uint8_t n_sens, struct bmi2_dev *dev); + * int8_t bmi2_map_feat_int(const struct bmi2_sens_int_config *sens_int, struct bmi2_dev *dev); * \endcode * @details This API maps/unmaps feature interrupts to that of interrupt pins. * * @param[in] sens_int : Structure instance of bmi2_sens_int_config. - * @param[in] n_sens : Number of features to be mapped. * @param[in] dev : Structure instance of bmi2_dev. * * @return Result of API execution status - * - * @retval BMI2_OK - Success. - * @retval BMI2_E_NULL_PTR - Error: Null pointer error - * @retval BMI2_E_COM_FAIL - Error: Communication fail - * @retval BMI2_E_INVALID_SENSOR - Error: Invalid sensor - * @retval BMI2_E_INVALID_FEAT_INT - Error: Invalid feature Interrupt + * @retval 0 -> Success + * @retval < 0 -> Fail */ -int8_t bmi2_map_feat_int(const struct bmi2_sens_int_config *sens_int, uint8_t n_sens, struct bmi2_dev *dev); +int8_t bmi2_map_feat_int(uint8_t type, enum bmi2_hw_int_pin hw_int_pin, struct bmi2_dev *dev); /*! * \ingroup bmi2ApiInt @@ -1372,11 +1145,8 @@ int8_t bmi2_map_feat_int(const struct bmi2_sens_int_config *sens_int, uint8_t n_ *@endverbatim * * @return Result of API execution status - * - * @retval BMI2_OK - Success. - * @retval BMI2_E_NULL_PTR - Error: Null pointer error - * @retval BMI2_E_COM_FAIL - Error: Communication fail - * @retval BMI2_E_INVALID_INT_PIN - Error: Invalid interrupt pin + * @retval 0 -> Success + * @retval < 0 -> Fail */ int8_t bmi2_map_data_int(uint8_t data_int, enum bmi2_hw_int_pin int_pin, struct bmi2_dev *dev); @@ -1399,12 +1169,8 @@ int8_t bmi2_map_data_int(uint8_t data_int, enum bmi2_hw_int_pin int_pin, struct * @param[in] dev : Structure instance of bmi2_dev. * * @return Result of API execution status - * - * @retval BMI2_OK - Success. - * @retval BMI2_E_NULL_PTR - Error: Null pointer error - * @retval BMI2_E_COM_FAIL - Error: Communication fail - * @retval BMI2_E_INVALID_SENSOR - Error: Invalid sensor - * @retval BMI2_E_INVALID_PAGE - Error: Invalid Page + * @retval 0 -> Success + * @retval < 0 -> Fail */ int8_t bmi2_get_remap_axes(struct bmi2_remap *remapped_axis, struct bmi2_dev *dev); @@ -1421,60 +1187,11 @@ int8_t bmi2_get_remap_axes(struct bmi2_remap *remapped_axis, struct bmi2_dev *de * @param[in] dev : Structure instance of bmi2_dev. * * @return Result of API execution status - * - * @retval BMI2_OK - Success. - * @retval BMI2_E_NULL_PTR - Error: Null pointer error - * @retval BMI2_E_COM_FAIL - Error: Communication fail - * @retval BMI2_E_INVALID_SENSOR - Error: Invalid sensor - * @retval BMI2_E_INVALID_PAGE - Error: Invalid Page + * @retval 0 -> Success + * @retval < 0 -> Fail */ int8_t bmi2_set_remap_axes(const struct bmi2_remap *remapped_axis, struct bmi2_dev *dev); -/** - * \ingroup bmi2 - * \defgroup bmi2ApiGyroUG Gyro User Gain - * @brief Set / Get Gyro User Gain of the sensor - */ - -/*! - * \ingroup bmi2ApiGyroUG - * \page bmi2_api_bmi2_update_gyro_user_gain bmi2_update_gyro_user_gain - * \code - * int8_t bmi2_update_gyro_user_gain(const struct bmi2_gyro_user_gain_config *user_gain, struct bmi2_dev *dev); - * \endcode - * @details This API updates the gyroscope user-gain. - * - * @param[in] user_gain : Structure that stores user-gain configurations. - * @param[in] dev : Structure instance of bmi2_dev. - * - * @return Result of API execution status - * - * @retval BMI2_OK - Success. - * @retval BMI2_E_NULL_PTR - Error: Null pointer error - * @retval BMI2_E_COM_FAIL - Error: Communication fail - * @retval BMI2_E_GYR_USER_GAIN_UPD_FAIL - Gyroscope user gain update fail - */ -int8_t bmi2_update_gyro_user_gain(const struct bmi2_gyro_user_gain_config *user_gain, struct bmi2_dev *dev); - -/*! - * \ingroup bmi2ApiGyroUG - * \page bmi2_api_bmi2_read_gyro_user_gain bmi2_read_gyro_user_gain - * \code - * int8_t bmi2_read_gyro_user_gain(struct bmi2_gyro_user_gain_data *gyr_usr_gain, const struct bmi2_dev *dev); - * \endcode - * @details This API reads the compensated gyroscope user-gain values. - * - * @param[out] gyr_usr_gain : Structure that stores gain values. - * @param[in] dev : Structure instance of bmi2_dev. - * - * @return Result of API execution status - * - * @retval BMI2_OK - Success. - * @retval BMI2_E_NULL_PTR - Error: Null pointer error - * @retval BMI2_E_COM_FAIL - Error: Communication fail - */ -int8_t bmi2_read_gyro_user_gain(struct bmi2_gyro_user_gain_data *gyr_usr_gain, struct bmi2_dev *dev); - /** * \ingroup bmi2 * \defgroup bmi2ApiGyroOC Gyro Offset Compensation @@ -1501,10 +1218,8 @@ int8_t bmi2_read_gyro_user_gain(struct bmi2_gyro_user_gain_data *gyr_usr_gain, s *@endverbatim * * @return Result of API execution status - * - * @retval BMI2_OK - Success. - * @retval BMI2_E_NULL_PTR - Error: Null pointer error - * @retval BMI2_E_COM_FAIL - Error: Communication fail + * @retval 0 -> Success + * @retval < 0 -> Fail */ int8_t bmi2_set_gyro_offset_comp(uint8_t enable, struct bmi2_dev *dev); @@ -1522,10 +1237,8 @@ int8_t bmi2_set_gyro_offset_comp(uint8_t enable, struct bmi2_dev *dev); * @param[in] dev : Structure instance of bmi2_dev. * * @return Result of API execution status - * - * @retval BMI2_OK - Success. - * @retval BMI2_E_NULL_PTR - Error: Null pointer error - * @retval BMI2_E_COM_FAIL - Error: Communication fail + * @retval 0 -> Success + * @retval < 0 -> Fail */ int8_t bmi2_read_gyro_offset_comp_axes(struct bmi2_sens_axes_data *gyr_off_comp_axes, struct bmi2_dev *dev); @@ -1543,83 +1256,11 @@ int8_t bmi2_read_gyro_offset_comp_axes(struct bmi2_sens_axes_data *gyr_off_comp_ * @param[in] dev : Structure instance of bmi2_dev. * * @return Result of API execution status - * - * @retval BMI2_OK - Success. - * @retval BMI2_E_NULL_PTR - Error: Null pointer error - * @retval BMI2_E_COM_FAIL - Error: Communication fail + * @retval 0 -> Success + * @retval < 0 -> Fail */ int8_t bmi2_write_gyro_offset_comp_axes(const struct bmi2_sens_axes_data *gyr_off_comp_axes, struct bmi2_dev *dev); -/** - * \ingroup bmi2 - * \defgroup bmi2ApiactOut Activity Output - * @brief Activity output operations of the sensor - */ - -/*! - * \ingroup bmi2ApiactOut - * \page bmi2_api_bmi2_get_act_recog_output bmi2_get_act_recog_output - * \code - * int8_t bmi2_get_act_recog_output(struct bmi2_act_recog_output *act_recog, - * uint16_t *act_frm_len, - * struct bmi2_fifo_frame *fifo, - * const struct bmi2_dev *dev); - * - * \endcode - * @details This internal API is used to parse the activity output from the - * FIFO in header mode. - * - * @param[out] act_recog : Pointer to buffer where the parsed activity data - * bytes are stored. - * @param[in] act_frm_len : Number of activity frames parsed. - * @param[in] fifo : Structure instance of bmi2_fifo_frame. - * @param[in] dev : Structure instance of bmi2_dev. - * - * @verbatim - * ---------------------------------------------------------------------------- - * bmi2_act_rec_output | - * Structure parameters | Description - *--------------------------|-------------------------------------------------- - * time_stamp | time-stamp (expressed in 50Hz ticks) - * -------------------------|--------------------------------------------------- - * type | Type of activity - * -------------------------|--------------------------------------------------- - * stat | Activity status - * -------------------------|--------------------------------------------------- - * @endverbatim - * - *@verbatim - * type | Activities - *----------|--------------------- - * 0 | UNKNOWN - * 1 | STILL - * 2 | WALK - * 3 | RUN - * 4 | BIKE - * 5 | VEHICLE - * 6 | TILTED - *@endverbatim - * - * - *@verbatim - * stat | Activity status - *----------|--------------------- - * 1 | START - * 2 | END - *@endverbatim - * - * @return Result of API execution status - * - * @retval BMI2_OK - Success. - * @retval BMI2_E_NULL_PTR - Error: Null pointer error - * @retval BMI2_W_FIFO_EMPTY - Warning : FIFO is empty - * @retval BMI2_W_PARTIAL_READ - Warning : There are more frames to be read - */ -int8_t bmi2_get_act_recog_output(struct bmi2_act_recog_output *act_recog, - uint16_t *act_frm_len, - struct bmi2_fifo_frame *fifo, - const struct bmi2_dev *dev); - /** * \ingroup bmi2 * \defgroup bmi2ApiGyroCS Gyro cross sensitivity @@ -1638,10 +1279,8 @@ int8_t bmi2_get_act_recog_output(struct bmi2_act_recog_output *act_recog, * @param[in, out] dev : Structure instance of bmi2_dev. * * @return Result of API execution status - * - * @retval BMI2_OK - Success. - * @retval BMI2_E_NULL_PTR - Error: Null pointer error - * @retval BMI2_E_COM_FAIL - Error: Communication fail + * @retval 0 -> Success + * @retval < 0 -> Fail */ int8_t bmi2_get_gyro_cross_sense(struct bmi2_dev *dev); @@ -1681,10 +1320,8 @@ int8_t bmi2_get_gyro_cross_sense(struct bmi2_dev *dev); *@endverbatim * * @return Result of API execution status - * - * @retval BMI2_OK - Success. - * @retval BMI2_E_NULL_PTR - Error: Null pointer error - * @retval BMI2_E_COM_FAIL - Error: Communication fail + * @retval 0 -> Success + * @retval < 0 -> Fail */ int8_t bmi2_get_internal_status(uint8_t *int_stat, struct bmi2_dev *dev); @@ -1714,12 +1351,8 @@ int8_t bmi2_get_internal_status(uint8_t *int_stat, struct bmi2_dev *dev); * @param[in] dev : Structure instance of bmi2_dev. * * @return Result of API execution status - * - * @retval BMI2_OK - Success. - * @retval BMI2_E_NULL_PTR - Error: Null pointer error - * @retval BMI2_E_COM_FAIL - Error: Communication fail - * @retval BMI2_E_INVALID_SENSOR - Error: Invalid sensor - * @retval BMI2_E_SET_APS_FAIL - Error: Set Advance Power Save Fail + * @retval 0 -> Success + * @retval < 0 -> Fail */ int8_t bmi2_perform_accel_foc(const struct bmi2_accel_foc_g_value *accel_g_value, struct bmi2_dev *dev); @@ -1734,12 +1367,8 @@ int8_t bmi2_perform_accel_foc(const struct bmi2_accel_foc_g_value *accel_g_value * @param[in] dev : Structure instance of bmi2_dev. * * @return Result of API execution status - * - * @retval BMI2_OK - Success. - * @retval BMI2_E_NULL_PTR - Error: Null pointer error - * @retval BMI2_E_COM_FAIL - Error: Communication fail - * @retval BMI2_E_INVALID_SENSOR - Error: Invalid sensor - * @retval BMI2_E_SET_APS_FAIL - Error: Set Advance Power Save Fail + * @retval 0 -> Success + * @retval < 0 -> Fail */ int8_t bmi2_perform_gyro_foc(struct bmi2_dev *dev); @@ -1761,9 +1390,8 @@ int8_t bmi2_perform_gyro_foc(struct bmi2_dev *dev); * @param[in] dev : Structure instance of bmi2_dev. * * @return Result of API execution status - * @retval BMI2_OK - Success. - * @retval BMI2_E_NULL_PTR - Error: Null pointer error - * @retval BMI2_E_CRT_ERROR - Error in CRT download + * @retval 0 -> Success + * @retval < 0 -> Fail * * @note CRT calibration takes approximately 500ms & maximum time out configured as 2 seconds */ @@ -1789,10 +1417,8 @@ int8_t bmi2_do_crt(struct bmi2_dev *dev); * @param[in] dev : Structure instance of bmi2_dev. * * @return Result of API execution status - * - * @retval BMI2_OK - Success. - * @retval BMI2_E_NULL_PTR - Error: Null pointer error - * @retval BMI2_E_COM_FAIL - Error: Communication fail + * @retval 0 -> Success + * @retval < 0 -> Fail */ int8_t bmi2_set_gyro_self_test_crt(uint8_t *gyro_self_test_crt, struct bmi2_dev *dev); @@ -1807,12 +1433,9 @@ int8_t bmi2_set_gyro_self_test_crt(uint8_t *gyro_self_test_crt, struct bmi2_dev * @param[in] dev : Structure instance of bmi2_dev. * * @return Result of API execution status - * - * @retval BMI2_OK - Success. - * @retval BMI2_E_NULL_PTR - Error: Null pointer error - * @retval BMI2_E_COM_FAIL - Error: Communication fail + * @retval 0 -> Success + * @retval < 0 -> Fail */ - int8_t bmi2_abort_crt_gyro_st(struct bmi2_dev *dev); /*! @@ -1826,9 +1449,8 @@ int8_t bmi2_abort_crt_gyro_st(struct bmi2_dev *dev); * @param[in] dev : Structure instance of bmi2_dev. * * @return Result of API execution status - * - * @retval BMI2_OK - Success. - * @retval < 0 - Fail + * @retval 0 -> Success + * @retval < 0 -> Fail */ int8_t bmi2_do_gyro_st(struct bmi2_dev *dev); @@ -1849,64 +1471,11 @@ int8_t bmi2_do_gyro_st(struct bmi2_dev *dev); * @param[in] dev : Structure instance of bmi2_dev. * * @return Result of API execution status - * - * @retval BMI2_OK - Success. - * @retval < 0 - Fail + * @retval 0 -> Success + * @retval < 0 -> Fail */ int8_t bmi2_nvm_prog(struct bmi2_dev *dev); -/** - * \ingroup bmi2 - * \defgroup bmi2ApiARecog Activity recognition settings - * @brief Set / Get activity recognition settings of the sensor - */ - -/*! - * \ingroup bmi2ApiARecog - * \page bmi2_api_bmi2_get_act_recg_sett bmi2_get_act_recg_sett - * \code - * int8_t bmi2_get_act_recg_sett(struct bmi2_act_recg_sett *sett, struct bmi2_dev *dev); - * \endcode - * @details This api is used for retrieving the following activity recognition settings currently set. - * enable/disable post processing(0/1) by default -> 1(enable), - * Setting the min & max Gini's diversity index (GDI) threshold. min_GDI_tres(0-0XFFFF) by default ->(0x06e1) - * max_GDI_tres(0-0xFFFF) by default ->(0x0A66) - * buffer size for post processing. range (1-0x0A) default -> (0x0A) - * min segment confidence. range (1-0x0A) default -> (0x0A) - * - * @param[in] sett : Structure instance of bmi2_act_recg_sett. - * @param[in] dev : Structure instance of bmi2_dev. - * - * @return Result of API execution status. - * - * @retval BMI2_OK - Success. - * @retval < 0 - Fail - */ -int8_t bmi2_get_act_recg_sett(struct bmi2_act_recg_sett *sett, struct bmi2_dev *dev); - -/*! - * \ingroup bmi2ApiARecog - * \page bmi2_api_bmi2_set_act_recg_sett bmi2_set_act_recg_sett - * \code - * int8_t bmi2_set_act_recg_sett(const struct bmi2_act_recg_sett *sett, struct bmi2_dev *dev); - * \endcode - * @details This api is used for setting the following activity recognition settings - * enable/disable post processing(0/1) by default -> 1(enable), - * Setting the min & max Gini's diversity index (GDI) threshold. min_GDI_tres(0-0XFFFF) by default ->(0x06e1) - * max_GDI_tres(0-0xFFFF) by default ->(0x0A66) - * buffer size for post processing. range (1-0x0A) default -> (0x0A) - * min segment confidence. range (1-0x0A) default -> (0x0A) - * - * @param[in] sett : Structure instance of bmi2_act_recg_sett. - * @param[in] dev : Structure instance of bmi2_dev. - * - * @return Result of API execution status. - * - * @retval BMI2_OK - Success. - * @retval < 0 - Fail - */ -int8_t bmi2_set_act_recg_sett(const struct bmi2_act_recg_sett *sett, struct bmi2_dev *dev); - /*! * @brief This API extracts the input feature configuration * details like page and start address from the look-up table. @@ -1932,11 +1501,8 @@ uint8_t bmi2_extract_input_feat_config(struct bmi2_feature_config *feat_config, * @param[in] dev : Structure instance of bmi2_dev. * * @return Result of API execution status - * - * @retval BMI2_OK - Success. - * @retval BMI2_E_COM_FAIL - Error: Communication fail - * @retval BMI2_E_NULL_PTR - Error: Null pointer error - * @retval BMI2_E_INVALID_PAGE - Error: Invalid Page + * @retval 0 -> Success + * @retval < 0 -> Fail */ int8_t bmi2_get_feat_config(uint8_t sw_page, uint8_t *feat_config, struct bmi2_dev *dev); diff --git a/bmi270.c b/bmi270.c index 92ecb43..9ad7cda 100644 --- a/bmi270.c +++ b/bmi270.c @@ -1,40 +1,40 @@ /** - * 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 bmi270.c - * @date 2020-06-05 - * @version v2.53.2 - * - */ +* 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 bmi270.c +* @date 2020-11-04 +* @version v2.63.1 +* +*/ /***************************************************************************/ @@ -485,6 +485,7 @@ const uint8_t bmi270_config_file[] = { /*! @name Global array that stores the feature input configuration of BMI270 */ const struct bmi2_feature_config bmi270_feat_in[BMI270_MAX_FEAT_IN] = { + { .type = BMI2_CONFIG_ID, .page = BMI2_PAGE_1, .start_addr = BMI270_CONFIG_ID_STRT_ADDR }, { .type = BMI2_MAX_BURST_LEN, .page = BMI2_PAGE_1, .start_addr = BMI270_MAX_BURST_LEN_STRT_ADDR }, { .type = BMI2_CRT_GYRO_SELF_TEST, .page = BMI2_PAGE_1, .start_addr = BMI270_CRT_GYRO_SELF_TEST_STRT_ADDR }, { .type = BMI2_ABORT_CRT_GYRO_SELF_TEST, .page = BMI2_PAGE_1, .start_addr = BMI270_ABORT_STRT_ADDR }, @@ -514,6 +515,18 @@ const struct bmi2_feature_config bmi270_feat_out[BMI270_MAX_FEAT_OUT] = { { .type = BMI2_VFRM_STATUS, .page = BMI2_PAGE_0, .start_addr = BMI270_NVM_VFRM_OUT_STRT_ADDR } }; +/*! @name Global array that stores the feature interrupts of BMI270 */ +struct bmi2_map_int bmi270_map_int[BMI270_MAX_INT_MAP] = { + { .type = BMI2_SIG_MOTION, .sens_map_int = BMI270_INT_SIG_MOT_MASK }, + { .type = BMI2_STEP_COUNTER, .sens_map_int = BMI270_INT_STEP_COUNTER_MASK }, + { .type = BMI2_STEP_DETECTOR, .sens_map_int = BMI270_INT_STEP_DETECTOR_MASK }, + { .type = BMI2_STEP_ACTIVITY, .sens_map_int = BMI270_INT_STEP_ACT_MASK }, + { .type = BMI2_WRIST_GESTURE, .sens_map_int = BMI270_INT_WRIST_GEST_MASK }, + { .type = BMI2_WRIST_WEAR_WAKE_UP, .sens_map_int = BMI270_INT_WRIST_WEAR_WAKEUP_MASK }, + { .type = BMI2_ANY_MOTION, .sens_map_int = BMI270_INT_ANY_MOT_MASK }, + { .type = BMI2_NO_MOTION, .sens_map_int = BMI270_INT_NO_MOT_MASK }, +}; + /******************************************************************************/ /*! Local Function Prototypes @@ -526,10 +539,697 @@ const struct bmi2_feature_config bmi270_feat_out[BMI270_MAX_FEAT_OUT] = { * @param[in] dev : Structure instance of bmi2_dev. * * @return Result of API execution status - * @retval zero -> Success / +ve value -> Warning / -ve value -> Error + * @retval 0 -> Success + * @retval < 0 -> Fail */ static int8_t null_ptr_check(const struct bmi2_dev *dev); +/*! + * @brief This internal API enables the selected sensor/features. + * + * @param[in] sensor_sel : Selects the desired sensor. + * @param[in, out] dev : Structure instance of bmi2_dev. + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +static int8_t sensor_enable(uint64_t sensor_sel, struct bmi2_dev *dev); + +/*! + * @brief This internal API disables the selected sensor/features. + * + * @param[in] sensor_sel : Selects the desired sensor. + * @param[in, out] dev : Structure instance of bmi2_dev. + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +static int8_t sensor_disable(uint64_t sensor_sel, struct bmi2_dev *dev); + +/*! + * @brief This internal API selects the sensors/features to be enabled or + * disabled. + * + * @param[in] sens_list : Pointer to select the sensor. + * @param[in] n_sens : Number of sensors selected. + * @param[out] sensor_sel : Gets the selected sensor. + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +static int8_t select_sensor(const uint8_t *sens_list, uint8_t n_sens, uint64_t *sensor_sel); + +/*! + * @brief This internal API is used to enable/disable any-motion feature. + * + * @param[in] dev : Structure instance of bmi2_dev. + * @param[in] enable : Enables/Disables any-motion. + * + * Enable | Description + * -------------|--------------- + * BMI2_DISABLE | Disables any-motion. + * BMI2_ENABLE | Enables any-motion. + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +static int8_t set_any_motion(uint8_t enable, struct bmi2_dev *dev); + +/*! + * @brief This internal API is used to enable/disable no-motion feature. + * + * @param[in] dev : Structure instance of bmi2_dev. + * @param[in] enable : Enables/Disables no-motion. + * + * Enable | Description + * -------------|--------------- + * BMI2_DISABLE | Disables no-motion. + * BMI2_ENABLE | Enables no-motion. + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +static int8_t set_no_motion(uint8_t enable, struct bmi2_dev *dev); + +/*! + * @brief This internal API is used to enable/disable sig-motion feature. + * + * @param[in] dev : Structure instance of bmi2_dev. + * @param[in] enable : Enables/Disables sig-motion. + * + * Enable | Description + * -------------|--------------- + * BMI2_DISABLE | Disables sig-motion. + * BMI2_ENABLE | Enables sig-motion. + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +static int8_t set_sig_motion(uint8_t enable, struct bmi2_dev *dev); + +/*! + * @brief This internal API is used to enable/disable step detector feature. + * + * @param[in] dev : Structure instance of bmi2_dev. + * @param[in] enable : Enables/Disables step-detector. + * + * Enable | Description + * -------------|--------------- + * BMI2_DISABLE | Disables step detector + * BMI2_ENABLE | Enables step detector + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +static int8_t set_step_detector(uint8_t enable, struct bmi2_dev *dev); + +/*! + * @brief This internal API is used to enable/disable step counter feature. + * + * @param[in] dev : Structure instance of bmi2_dev. + * @param[in] enable : Enables/Disables step counter. + * + * Enable | Description + * -------------|--------------- + * BMI2_DISABLE | Disables step counter + * BMI2_ENABLE | Enables step counter + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +static int8_t set_step_counter(uint8_t enable, struct bmi2_dev *dev); + +/*! + * @brief This internal API is used to enable/disable step activity detection. + * + * @param[in] dev : Structure instance of bmi2_dev. + * @param[in] enable : Enables/Disables step activity. + * + * Enable | Description + * -------------|--------------- + * BMI2_DISABLE | Disables step activity + * BMI2_ENABLE | Enables step activity + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +static int8_t set_step_activity(uint8_t enable, struct bmi2_dev *dev); + +/*! + * @brief This internal API gives an option to enable offset correction + * feature of gyroscope, either internally or by the host. + * + * @param[in] enable : Enables/Disables self-offset correction. + * @param[in] dev : Structure instance of bmi2_dev. + * + * enable | Description + * -------------|--------------- + * BMI2_ENABLE | gyroscope offset correction values are set internally + * BMI2_DISABLE | gyroscope offset correction values has to be set by host + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +static int8_t set_gyro_self_offset_corr(uint8_t enable, struct bmi2_dev *dev); + +/*! + * @brief This internal API is used to enable/disable gyroscope user gain + * feature. + * + * @param[in] dev : Structure instance of bmi2_dev. + * @param[in] enable : Enables/Disables gyroscope user gain. + * + * Enable | Description + * -------------|--------------- + * BMI2_DISABLE | Disables gyroscope user gain + * BMI2_ENABLE | Enables gyroscope user gain + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +static int8_t set_gyro_user_gain(uint8_t enable, struct bmi2_dev *dev); + +/*! + * @brief This internal API enables the wrist gesture feature. + * + * @param[in] dev : Structure instance of bmi2_dev. + * @param[in] enable : Enables/Disables wrist gesture. + * + * Enable | Description + * -------------|--------------- + * BMI2_DISABLE | Disables wrist gesture + * BMI2_ENABLE | Enables wrist gesture + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +static int8_t set_wrist_gesture(uint8_t enable, struct bmi2_dev *dev); + +/*! + * @brief This internal API enables the wrist wear wake up feature. + * + * @param[in] dev : Structure instance of bmi2_dev. + * @param[in] enable : Enables/Disables wrist wear wake up. + * + * Enable | Description + * -------------|--------------- + * BMI2_DISABLE | Disables wrist wear wake up + * BMI2_ENABLE | Enables wrist wear wake up + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +static int8_t set_wrist_wear_wake_up(uint8_t enable, struct bmi2_dev *dev); + +/*! + * @brief This internal API sets any-motion configurations like axes select, + * duration, threshold and output-configuration. + * + * @param[in] config : Structure instance of bmi2_any_motion_config. + * @param[in, out] dev : Structure instance of bmi2_dev. + * + * @verbatim + *---------------------------------------------------------------------------- + * bmi2_any_motion_config | + * Structure parameters | Description + *--------------------------|-------------------------------------------------- + * | Defines the number of consecutive data points for + * | which the threshold condition must be respected, + * | for interrupt assertion. It is expressed in 50 Hz + * duration | samples (20 msec). + * | Range is 0 to 163sec. + * | Default value is 5 = 100ms. + * -------------------------|--------------------------------------------------- + * | Slope threshold value for in 5.11g format. + * threshold | Range is 0 to 1g. + * | Default value is 0xAA = 83mg. + * -------------------------|--------------------------------------------------- + * x_sel, y_sel, z_sel | Selects the feature on a per-axis basis + * -------------------------|--------------------------------------------------- + * @endverbatim + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +static int8_t set_any_motion_config(const struct bmi2_any_motion_config *config, struct bmi2_dev *dev); + +/*! + * @brief This internal API sets no-motion configurations like axes select, + * duration, threshold and output-configuration. + * + * @param[in] config : Structure instance of bmi2_no_motion_config. + * @param[in, out] dev : Structure instance of bmi2_dev. + * + * @verbatim + *---------------------------------------------------------------------------- + * bmi2_no_motion_config | + * Structure parameters | Description + *--------------------------|-------------------------------------------------- + * | Defines the number of consecutive data points for + * | which the threshold condition must be respected, + * | for interrupt assertion. It is expressed in 50 Hz + * duration | samples (20 msec). + * | Range is 0 to 163sec. + * | Default value is 5 = 100ms. + * -------------------------|--------------------------------------------------- + * | Slope threshold value for in 5.11g format. + * threshold | Range is 0 to 1g. + * | Default value is 0xAA = 83mg. + * -------------------------|--------------------------------------------------- + * x_sel, y_sel, z_sel | Selects the feature on a per-axis basis + * -------------------------|--------------------------------------------------- + * @endverbatim + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +static int8_t set_no_motion_config(const struct bmi2_no_motion_config *config, struct bmi2_dev *dev); + +/*! + * @brief This internal API sets sig-motion configurations like block-size, + * output-configuration and other parameters. + * + * @param[in] config : Structure instance of bmi2_sig_motion_config. + * @param[in, out] dev : Structure instance of bmi2_dev. + * + *---------------------------------------------------------------------------- + * bmi2_sig_motion_config | + * Structure parameters | Description + * -------------------------|--------------------------------------------------- + * | Defines the duration after which the significant + * block_size | motion interrupt is triggered. It is expressed in + * | 50 Hz samples (20 ms). Default value is 0xFA=5sec. + *--------------------------|--------------------------------------------------- + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +static int8_t set_sig_motion_config(const struct bmi2_sig_motion_config *config, struct bmi2_dev *dev); + +/*! + * @brief This internal API sets step counter parameter configurations. + * + * @param[in] step_count_params : Array that stores parameters 1 to 25. + * @param[in] dev : Structure instance of bmi2_dev. + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +static int8_t set_step_count_params_config(const uint16_t *step_count_params, struct bmi2_dev *dev); + +/*! + * @brief This internal API sets step counter/detector/activity configurations. + * + * @param[in] config : Structure instance of bmi2_step_config. + * @param[in] dev : Structure instance of bmi2_dev. + * + *--------------------------------------------------------------------------- + * bmi2_step_config | + * Structure parameters | Description + *--------------------------|-------------------------------------------------- + * | The Step-counter will trigger output every time + * | the number of steps are counted. Holds implicitly + * water-mark level | a 20x factor, so the range is 0 to 10230, + * | with resolution of 20 steps. + * -------------------------|--------------------------------------------------- + * reset counter | Flag to reset the counted steps. + * -------------------------|--------------------------------------------------- + * @endverbatim + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +static int8_t set_step_config(const struct bmi2_step_config *config, struct bmi2_dev *dev); + +/*! + * @brief This internal API sets wrist gesture configurations like wearable-arm, + * and output-configuration. + * + * @param[in] config : Structure instance of bmi2_wrist_gest_config. + * @param[in, out] dev : Structure instance of bmi2_dev. + * + * @verbatim + *----------------------------------------------------------------------------- + * bmi2_wrist_gest_config | + * Structure parameters | Description + *--------------------------|-------------------------------------------------- + * | Device in left (0) or right (1) arm. By default, + * wear_arm | the wearable device is assumed to be in left arm + * | i.e. default value is 0. + * -------------------------|--------------------------------------------------- + * @endverbatim + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +static int8_t set_wrist_gest_config(const struct bmi2_wrist_gest_config *config, struct bmi2_dev *dev); + +/*! + * @brief This internal API sets wrist wear wake-up configurations like + * output-configuration. + * + * @param[in] config : Structure instance of + * bmi2_wrist_wear_wake_up_config. + * @param[in, out] dev : Structure instance of bmi2_dev. + * + * @verbatim + *----------------------------------------------------------------------------- + * bmi2_wrist_wear_wake_up_config | + * Structure parameters | Description + *----------------------------------|------------------------------------------- + * | To set the wrist wear wake-up parameters like + * | min_angle_focus, min_angle_nonfocus, + * wrist_wear_wakeup_params | angle_landscape_left, angle_landscape_right, + * | angle_potrait_up and down. + * ---------------------------------|------------------------------------------- + * @endverbatim + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +static int8_t set_wrist_wear_wake_up_config(const struct bmi2_wrist_wear_wake_up_config *config, struct bmi2_dev *dev); + +/*! + * @brief This internal API gets any-motion configurations like axes select, + * duration, threshold and output-configuration. + * + * @param[out] config : Structure instance of bmi2_any_motion_config. + * @param[in, out] dev : Structure instance of bmi2_dev. + * + * @verbatim + *---------------------------------------------------------------------------- + * bmi2_any_motion_config | + * Structure parameters | Description + *--------------------------|-------------------------------------------------- + * | Defines the number of consecutive data points for + * | which the threshold condition must be respected, + * | for interrupt assertion. It is expressed in 50 Hz + * duration | samples (20 msec). + * | Range is 0 to 163sec. + * | Default value is 5 = 100ms. + * -------------------------|--------------------------------------------------- + * | Slope threshold value for in 5.11g format. + * threshold | Range is 0 to 1g. + * | Default value is 0xAA = 83mg. + * -------------------------|--------------------------------------------------- + * x_sel, y_sel, z_sel | Selects the feature on a per-axis basis + * -------------------------|--------------------------------------------------- + * @endverbatim + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +static int8_t get_any_motion_config(struct bmi2_any_motion_config *config, struct bmi2_dev *dev); + +/*! + * @brief This internal API gets no-motion configurations like axes select, + * duration, threshold and output-configuration. + * + * @param[out] config : Structure instance of bmi2_no_motion_config. + * @param[in, out] dev : Structure instance of bmi2_dev. + * + * @verbatim + *---------------------------------------------------------------------------- + * bmi2_no_motion_config | + * Structure parameters | Description + *--------------------------|-------------------------------------------------- + * | Defines the number of consecutive data points for + * | which the threshold condition must be respected, + * | for interrupt assertion. It is expressed in 50 Hz + * duration | samples (20 msec). + * | Range is 0 to 163sec. + * | Default value is 5 = 100ms. + * -------------------------|--------------------------------------------------- + * | Slope threshold value for in 5.11g format. + * threshold | Range is 0 to 1g. + * | Default value is 0xAA = 83mg. + * -------------------------|--------------------------------------------------- + * x_sel, y_sel, z_sel | Selects the feature on a per-axis basis + * -------------------------|--------------------------------------------------- + * @endverbatim + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +static int8_t get_no_motion_config(struct bmi2_no_motion_config *config, struct bmi2_dev *dev); + +/*! + * @brief This internal API gets sig-motion configurations like block-size, + * output-configuration and other parameters. + * + * @param[out] config : Structure instance of bmi2_sig_motion_config. + * @param[in, out] dev : Structure instance of bmi2_dev. + * + *---------------------------------------------------------------------------- + * bmi2_sig_motion_config | + * Structure parameters | Description + * -------------------------|--------------------------------------------------- + * | Defines the duration after which the significant + * block_size | motion interrupt is triggered. It is expressed in + * | 50 Hz samples (20 ms). Default value is 0xFA=5sec. + *--------------------------|--------------------------------------------------- + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +static int8_t get_sig_motion_config(struct bmi2_sig_motion_config *config, struct bmi2_dev *dev); + +/*! + * @brief This internal API gets step counter parameter configurations. + * + * @param[in] step_count_params : Array that stores parameters 1 to 25. + * @param[in] dev : Structure instance of bmi2_dev. + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +static int8_t get_step_count_params_config(uint16_t *step_count_params, struct bmi2_dev *dev); + +/*! + * @brief This internal API gets step counter/detector/activity configurations. + * + * @param[out] config : Structure instance of bmi2_step_config. + * @param[in] dev : Structure instance of bmi2_dev. + * + * @verbatim + *---------------------------------------------------------------------------- + * bmi2_step_config | + * Structure parameters | Description + *--------------------------|-------------------------------------------------- + * | The Step-counter will trigger output every time + * | the number of steps are counted. Holds implicitly + * water-mark level | a 20x factor, so the range is 0 to 10230, + * | with resolution of 20 steps. + * -------------------------|--------------------------------------------------- + * reset counter | Flag to reset the counted steps. + * -------------------------|--------------------------------------------------- + * @endverbatim + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +static int8_t get_step_config(struct bmi2_step_config *config, struct bmi2_dev *dev); + +/*! + * @brief This internal API gets wrist gesture configurations like wearable-arm, + * and output-configuration. + * + * @param[out] config : Structure instance of bmi2_wrist_gest_config. + * @param[in, out] dev : Structure instance of bmi2_dev. + * + * @verbatim + *----------------------------------------------------------------------------- + * bmi2_wrist_gest_config | + * Structure parameters | Description + *--------------------------|-------------------------------------------------- + * | Device in left (0) or right (1) arm. By default, + * wear_arm | the wearable device is assumed to be in left arm + * | i.e. default value is 0. + * -------------------------|--------------------------------------------------- + * @endverbatim + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +static int8_t get_wrist_gest_config(struct bmi2_wrist_gest_config *config, struct bmi2_dev *dev); + +/*! + * @brief This internal API gets wrist wear wake-up configurations like + * output-configuration. + * + * @param[out] config : Structure instance of + * bmi2_wrist_wear_wake_up_config. + * @param[in, out] dev : Structure instance of bmi2_dev. + * + * @verbatim + *------------------------------------|--------------------------------------- + * bmi2_wrist_wear_wake_up_wh_config | + * Structure parameters | Description + *------------------------------------|------------------------------------------- + * | To get the wrist wear wake-up parameters like + * | min_angle_focus, min_angle_nonfocus, + * wrist_wear_wake_params | angle_landscape_left, angle_landscape_right, + * | angle_potrait_up and down. + * -----------------------------------|------------------------------------------- + * @endverbatim + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +static int8_t get_wrist_wear_wake_up_config(struct bmi2_wrist_wear_wake_up_config *config, struct bmi2_dev *dev); + +/*! + * @brief This internal API gets the output values of wrist gesture. + * + * @param[out] wrist_gest : Pointer to the stored wrist gesture. + * @param[in] dev : Structure instance of bmi2_dev. + * + * *wrist_gest | Output + * -------------|------------ + * 0x00 | UNKNOWN + * 0x01 | PUSH_ARM_DOWN + * 0x02 | PIVOT_UP + * 0x03 | WRIST_SHAKE_JIGGLE + * 0x04 | FLICK_IN + * 0x05 | FLICK_OUT + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +static int8_t get_wrist_gest_status(uint8_t *wrist_gest, struct bmi2_dev *dev); + +/*! + * @brief This internal API gets the output values of step activity. + * + * @param[out] step_act : Pointer to the stored step activity data. + * @param[in] dev : Structure instance of bmi2_dev. + * + * *step_act | Output + * -----------|------------ + * 0x00 | STILL + * 0x01 | WALKING + * 0x02 | RUNNING + * 0x03 | UNKNOWN + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fails + */ +static int8_t get_step_activity_output(uint8_t *step_act, struct bmi2_dev *dev); + +/*! + * @brief This internal API gets the output values of step counter. + * + * @param[out] step_count : Pointer to the stored step counter data. + * @param[in] dev : Structure instance of bmi2_dev. + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +static int8_t get_step_counter_output(uint32_t *step_count, struct bmi2_dev *dev); + +/*! + * @brief This internal API gets the error status related to NVM. + * + * @param[out] nvm_err_stat : Stores the NVM error status. + * @param[in] dev : Structure instance of bmi2_dev. + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +static int8_t get_nvm_error_status(struct bmi2_nvm_err_status *nvm_err_stat, struct bmi2_dev *dev); + +/*! + * @brief This internal API gets the error status related to virtual frames. + * + * @param[out] vfrm_err_stat : Stores the VFRM related error status. + * @param[in] dev : Structure instance of bmi2_dev. + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +static int8_t get_vfrm_error_status(struct bmi2_vfrm_err_status *vfrm_err_stat, struct bmi2_dev *dev); + +/*! + * @brief This internal API is used to get enable status of gyroscope user gain + * update. + * + * @param[out] status : Stores status of gyroscope user gain update. + * @param[in] dev : Structure instance of bmi2_dev. + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +static int8_t get_user_gain_upd_status(uint8_t *status, struct bmi2_dev *dev); + +/*! + * @brief This internal API enables/disables compensation of the gain defined + * in the GAIN register. + * + * @param[in] enable : Enables/Disables gain compensation + * @param[in] dev : Structure instance of bmi2_dev. + * + * enable | Description + * -------------|--------------- + * BMI2_ENABLE | Enable gain compensation. + * BMI2_DISABLE | Disable gain compensation. + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +static int8_t enable_gyro_gain(uint8_t enable, struct bmi2_dev *dev); + +/*! + * @brief This internal API is used to extract the output feature configuration + * details like page and start address from the look-up table. + * + * @param[out] feat_output : Structure that stores output feature + * configurations. + * @param[in] type : Type of feature or sensor. + * @param[in] dev : Structure instance of bmi2_dev. + * + * @return Returns the feature found flag. + * + * @retval BMI2_FALSE : Feature not found + * BMI2_TRUE : Feature found + */ +static uint8_t extract_output_feat_config(struct bmi2_feature_config *feat_output, + uint8_t type, + const struct bmi2_dev *dev); + /***************************************************************************/ /*! User Interface Definitions @@ -609,20 +1309,606 @@ int8_t bmi270_init(struct bmi2_dev *dev) */ dev->out_sens = BMI270_MAX_FEAT_OUT; + /* Assign the offsets of the feature interrupt + * to the device structure + */ + dev->map_int = bmi270_map_int; + + /* Assign maximum number of feature interrupts + * to device structure + */ + dev->sens_int_map = BMI270_MAX_INT_MAP; + /* Get the gyroscope cross axis sensitivity */ rslt = bmi2_get_gyro_cross_sense(dev); - } } return rslt; } -/***************************************************************************/ - -/*! Local Function Definitions - ****************************************************************************/ - +/*! + * @brief This API selects the sensors/features to be enabled. + */ +int8_t bmi270_sensor_enable(const uint8_t *sens_list, uint8_t n_sens, struct bmi2_dev *dev) +{ + /* Variable to define error */ + int8_t rslt; + + /* Variable to select sensor */ + uint64_t sensor_sel = 0; + + /* Null-pointer check */ + rslt = null_ptr_check(dev); + if ((rslt == BMI2_OK) && (sens_list != NULL)) + { + /* Get the selected sensors */ + rslt = select_sensor(sens_list, n_sens, &sensor_sel); + if (rslt == BMI2_OK) + { + /* Enable the selected sensors */ + rslt = sensor_enable(sensor_sel, dev); + } + } + else + { + rslt = BMI2_E_NULL_PTR; + } + + return rslt; +} + +/*! + * @brief This API selects the sensors/features to be disabled. + */ +int8_t bmi270_sensor_disable(const uint8_t *sens_list, uint8_t n_sens, struct bmi2_dev *dev) +{ + /* Variable to define error */ + int8_t rslt; + + /* Variable to select sensor */ + uint64_t sensor_sel = 0; + + /* Null-pointer check */ + rslt = null_ptr_check(dev); + if ((rslt == BMI2_OK) && (sens_list != NULL)) + { + /* Get the selected sensors */ + rslt = select_sensor(sens_list, n_sens, &sensor_sel); + if (rslt == BMI2_OK) + { + /* Disable the selected sensors */ + rslt = sensor_disable(sensor_sel, dev); + } + } + else + { + rslt = BMI2_E_NULL_PTR; + } + + return rslt; +} + +/*! + * @brief This API sets the sensor/feature configuration. + */ +int8_t bmi270_set_sensor_config(struct bmi2_sens_config *sens_cfg, uint8_t n_sens, struct bmi2_dev *dev) +{ + /* Variable to define error */ + int8_t rslt; + + /* Variable to define loop */ + uint8_t loop; + + /* Variable to get the status of advance power save */ + uint8_t aps_stat = 0; + + /* Null-pointer check */ + rslt = null_ptr_check(dev); + if ((rslt == BMI2_OK) && (sens_cfg != NULL)) + { + /* Get status of advance power save mode */ + aps_stat = dev->aps_status; + + for (loop = 0; loop < n_sens; loop++) + { + if ((sens_cfg[loop].type == BMI2_ACCEL) || (sens_cfg[loop].type == BMI2_GYRO) || + (sens_cfg[loop].type == BMI2_AUX) || (sens_cfg[loop].type == BMI2_GYRO_GAIN_UPDATE)) + { + rslt = bmi2_set_sensor_config(&sens_cfg[loop], 1, dev); + } + else + { + /* Disable Advance power save if enabled for auxiliary + * and feature configurations + */ + if (aps_stat == BMI2_ENABLE) + { + /* Disable advance power save if + * enabled + */ + rslt = bmi2_set_adv_power_save(BMI2_DISABLE, dev); + } + + if (rslt == BMI2_OK) + { + switch (sens_cfg[loop].type) + { + /* Set any motion configuration */ + case BMI2_ANY_MOTION: + rslt = set_any_motion_config(&sens_cfg[loop].cfg.any_motion, dev); + break; + + /* Set no motion configuration */ + case BMI2_NO_MOTION: + rslt = set_no_motion_config(&sens_cfg[loop].cfg.no_motion, dev); + break; + + /* Set sig-motion configuration */ + case BMI2_SIG_MOTION: + rslt = set_sig_motion_config(&sens_cfg[loop].cfg.sig_motion, dev); + break; + + /* Set the step counter parameters */ + case BMI2_STEP_COUNTER_PARAMS: + rslt = set_step_count_params_config(sens_cfg[loop].cfg.step_counter_params, dev); + break; + + /* Set step counter/detector/activity configuration */ + case BMI2_STEP_DETECTOR: + case BMI2_STEP_COUNTER: + case BMI2_STEP_ACTIVITY: + rslt = set_step_config(&sens_cfg[loop].cfg.step_counter, dev); + break; + + /* Set the wrist gesture configuration */ + case BMI2_WRIST_GESTURE: + rslt = set_wrist_gest_config(&sens_cfg[loop].cfg.wrist_gest, dev); + break; + + /* Set the wrist wear wake-up configuration */ + case BMI2_WRIST_WEAR_WAKE_UP: + rslt = set_wrist_wear_wake_up_config(&sens_cfg[loop].cfg.wrist_wear_wake_up, dev); + break; + + default: + rslt = BMI2_E_INVALID_SENSOR; + break; + } + } + + /* Return error if any of the set configurations fail */ + if (rslt != BMI2_OK) + { + break; + } + } + } + + /* Enable Advance power save if disabled while configuring and + * not when already disabled + */ + if ((aps_stat == BMI2_ENABLE) && (rslt == BMI2_OK)) + { + rslt = bmi2_set_adv_power_save(BMI2_ENABLE, dev); + } + } + else + { + rslt = BMI2_E_NULL_PTR; + } + + return rslt; +} + +/*! + * @brief This API gets the sensor/feature configuration. + */ +int8_t bmi270_get_sensor_config(struct bmi2_sens_config *sens_cfg, uint8_t n_sens, struct bmi2_dev *dev) +{ + /* Variable to define error */ + int8_t rslt; + + /* Variable to define loop */ + uint8_t loop; + + /* Variable to get the status of advance power save */ + uint8_t aps_stat = 0; + + /* Null-pointer check */ + rslt = null_ptr_check(dev); + if ((rslt == BMI2_OK) && (sens_cfg != NULL)) + { + /* Get status of advance power save mode */ + aps_stat = dev->aps_status; + for (loop = 0; loop < n_sens; loop++) + { + if ((sens_cfg[loop].type == BMI2_ACCEL) || (sens_cfg[loop].type == BMI2_GYRO) || + (sens_cfg[loop].type == BMI2_AUX) || (sens_cfg[loop].type == BMI2_GYRO_GAIN_UPDATE)) + { + rslt = bmi2_get_sensor_config(&sens_cfg[loop], 1, dev); + } + else + { + /* Disable Advance power save if enabled for auxiliary + * and feature configurations + */ + if ((sens_cfg[loop].type >= BMI2_MAIN_SENS_MAX_NUM) || (sens_cfg[loop].type == BMI2_AUX)) + { + + if (aps_stat == BMI2_ENABLE) + { + /* Disable advance power save if + * enabled + */ + rslt = bmi2_set_adv_power_save(BMI2_DISABLE, dev); + } + } + + if (rslt == BMI2_OK) + { + switch (sens_cfg[loop].type) + { + /* Get sig-motion configuration */ + case BMI2_SIG_MOTION: + rslt = get_sig_motion_config(&sens_cfg[loop].cfg.sig_motion, dev); + break; + + /* Get any motion configuration */ + case BMI2_ANY_MOTION: + rslt = get_any_motion_config(&sens_cfg[loop].cfg.any_motion, dev); + break; + + /* Get no motion configuration */ + case BMI2_NO_MOTION: + rslt = get_no_motion_config(&sens_cfg[loop].cfg.no_motion, dev); + break; + + /* Set the step counter parameters */ + case BMI2_STEP_COUNTER_PARAMS: + rslt = get_step_count_params_config(sens_cfg[loop].cfg.step_counter_params, dev); + break; + + /* Get step counter/detector/activity configuration */ + case BMI2_STEP_DETECTOR: + case BMI2_STEP_COUNTER: + case BMI2_STEP_ACTIVITY: + rslt = get_step_config(&sens_cfg[loop].cfg.step_counter, dev); + break; + + /* Get the wrist gesture configuration */ + case BMI2_WRIST_GESTURE: + rslt = get_wrist_gest_config(&sens_cfg[loop].cfg.wrist_gest, dev); + break; + + /* Get the wrist wear wake-up configuration */ + case BMI2_WRIST_WEAR_WAKE_UP: + rslt = get_wrist_wear_wake_up_config(&sens_cfg[loop].cfg.wrist_wear_wake_up, dev); + break; + + default: + rslt = BMI2_E_INVALID_SENSOR; + break; + } + } + + /* Return error if any of the get configurations fail */ + if (rslt != BMI2_OK) + { + break; + } + } + } + + /* Enable Advance power save if disabled while configuring and + * not when already disabled + */ + if ((aps_stat == BMI2_ENABLE) && (rslt == BMI2_OK)) + { + rslt = bmi2_set_adv_power_save(BMI2_ENABLE, dev); + } + } + else + { + rslt = BMI2_E_NULL_PTR; + } + + return rslt; +} + +/*! + * @brief This API gets the sensor/feature data for accelerometer, gyroscope, + * auxiliary sensor, step counter, high-g, gyroscope user-gain update, + * orientation, gyroscope cross sensitivity and error status for NVM and VFRM. + */ +int8_t bmi270_get_sensor_data(struct bmi2_sensor_data *sensor_data, uint8_t n_sens, struct bmi2_dev *dev) +{ + /* Variable to define error */ + int8_t rslt; + + /* Variable to define loop */ + uint8_t loop; + + /* Variable to get the status of advance power save */ + uint8_t aps_stat = 0; + + /* Null-pointer check */ + rslt = null_ptr_check(dev); + if ((rslt == BMI2_OK) && (sensor_data != NULL)) + { + /* Get status of advance power save mode */ + aps_stat = dev->aps_status; + for (loop = 0; loop < n_sens; loop++) + { + if ((sensor_data[loop].type == BMI2_ACCEL) || (sensor_data[loop].type == BMI2_GYRO) || + (sensor_data[loop].type == BMI2_AUX) || (sensor_data[loop].type == BMI2_GYRO_GAIN_UPDATE) || + (sensor_data[loop].type == BMI2_GYRO_CROSS_SENSE)) + { + rslt = bmi2_get_sensor_data(&sensor_data[loop], 1, dev); + } + else + { + /* Disable Advance power save if enabled for feature + * configurations + */ + if (sensor_data[loop].type >= BMI2_MAIN_SENS_MAX_NUM) + { + if (aps_stat == BMI2_ENABLE) + { + /* Disable advance power save if + * enabled + */ + rslt = bmi2_set_adv_power_save(BMI2_DISABLE, dev); + } + } + + if (rslt == BMI2_OK) + { + switch (sensor_data[loop].type) + { + case BMI2_STEP_COUNTER: + + /* Get step counter output */ + rslt = get_step_counter_output(&sensor_data[loop].sens_data.step_counter_output, dev); + break; + case BMI2_STEP_ACTIVITY: + + /* Get step activity output */ + rslt = get_step_activity_output(&sensor_data[loop].sens_data.activity_output, dev); + break; + case BMI2_NVM_STATUS: + + /* Get NVM error status */ + rslt = get_nvm_error_status(&sensor_data[loop].sens_data.nvm_status, dev); + break; + case BMI2_VFRM_STATUS: + + /* Get VFRM error status */ + rslt = get_vfrm_error_status(&sensor_data[loop].sens_data.vfrm_status, dev); + break; + case BMI2_WRIST_GESTURE: + + /* Get wrist gesture status */ + rslt = get_wrist_gest_status(&sensor_data[loop].sens_data.wrist_gesture_output, dev); + break; + default: + rslt = BMI2_E_INVALID_SENSOR; + break; + } + + /* Return error if any of the get sensor data fails */ + if (rslt != BMI2_OK) + { + break; + } + } + } + + /* Enable Advance power save if disabled while + * configuring and not when already disabled + */ + if ((aps_stat == BMI2_ENABLE) && (rslt == BMI2_OK)) + { + rslt = bmi2_set_adv_power_save(BMI2_ENABLE, dev); + } + } + } + else + { + rslt = BMI2_E_NULL_PTR; + } + + return rslt; +} + +/*! + * @brief This API updates the gyroscope user-gain. + */ +int8_t bmi270_update_gyro_user_gain(const struct bmi2_gyro_user_gain_config *user_gain, struct bmi2_dev *dev) +{ + /* Variable to define error */ + int8_t rslt; + + /* Variable to select sensor */ + uint8_t sens_sel[2] = { BMI2_GYRO, BMI2_GYRO_GAIN_UPDATE }; + + /* Structure to define sensor configurations */ + struct bmi2_sens_config sens_cfg; + + /* Variable to store status of user-gain update module */ + uint8_t status = 0; + + /* Variable to define count */ + uint8_t count = 100; + + /* Null-pointer check */ + rslt = null_ptr_check(dev); + if ((rslt == BMI2_OK) && (user_gain != NULL)) + { + /* Select type of feature */ + sens_cfg.type = BMI2_GYRO_GAIN_UPDATE; + + /* Get the user gain configurations */ + rslt = bmi270_get_sensor_config(&sens_cfg, 1, dev); + if (rslt == BMI2_OK) + { + /* Get the user-defined ratio */ + sens_cfg.cfg.gyro_gain_update = *user_gain; + + /* Set rate ratio for all axes */ + rslt = bmi270_set_sensor_config(&sens_cfg, 1, dev); + } + + /* Disable gyroscope */ + if (rslt == BMI2_OK) + { + rslt = bmi270_sensor_disable(&sens_sel[0], 1, dev); + } + + /* Enable gyroscope user-gain update module */ + if (rslt == BMI2_OK) + { + rslt = bmi270_sensor_enable(&sens_sel[1], 1, dev); + } + + /* Set the command to trigger the computation */ + if (rslt == BMI2_OK) + { + rslt = bmi2_set_command_register(BMI2_USR_GAIN_CMD, dev); + } + + if (rslt == BMI2_OK) + { + /* Poll until enable bit of user-gain update is 0 */ + while (count--) + { + rslt = get_user_gain_upd_status(&status, dev); + if ((rslt == BMI2_OK) && (status == 0)) + { + /* Enable compensation of gain defined + * in the GAIN register + */ + rslt = enable_gyro_gain(BMI2_ENABLE, dev); + + /* Enable gyroscope */ + if (rslt == BMI2_OK) + { + rslt = bmi270_sensor_enable(&sens_sel[0], 1, dev); + } + + break; + } + + dev->delay_us(10000, dev->intf_ptr); + } + + /* Return error if user-gain update is failed */ + if ((rslt == BMI2_OK) && (status != 0)) + { + rslt = BMI2_E_GYR_USER_GAIN_UPD_FAIL; + } + } + } + else + { + rslt = BMI2_E_NULL_PTR; + } + + return rslt; +} + +/*! + * @brief This API reads the compensated gyroscope user-gain values. + */ +int8_t bmi270_read_gyro_user_gain(struct bmi2_gyro_user_gain_data *gyr_usr_gain, struct bmi2_dev *dev) +{ + /* Variable to define error */ + int8_t rslt; + + /* Variable to define register data */ + uint8_t reg_data[3] = { 0 }; + + /* Null-pointer check */ + rslt = null_ptr_check(dev); + if ((rslt == BMI2_OK) && (gyr_usr_gain != NULL)) + { + /* Get the gyroscope compensated gain values */ + rslt = bmi2_get_regs(BMI2_GYR_USR_GAIN_0_ADDR, reg_data, 3, dev); + if (rslt == BMI2_OK) + { + /* Gyroscope user gain correction X-axis */ + gyr_usr_gain->x = (int8_t)BMI2_GET_BIT_POS0(reg_data[0], BMI2_GYR_USR_GAIN_X); + + /* Gyroscope user gain correction Y-axis */ + gyr_usr_gain->y = (int8_t)BMI2_GET_BIT_POS0(reg_data[1], BMI2_GYR_USR_GAIN_Y); + + /* Gyroscope user gain correction z-axis */ + gyr_usr_gain->z = (int8_t)BMI2_GET_BIT_POS0(reg_data[2], BMI2_GYR_USR_GAIN_Z); + } + } + else + { + rslt = BMI2_E_NULL_PTR; + } + + return rslt; +} + +/*! + * @brief This API maps/unmaps feature interrupts to that of interrupt pins. + */ +int8_t bmi270_map_feat_int(const struct bmi2_sens_int_config *sens_int, uint8_t n_sens, struct bmi2_dev *dev) +{ + /* Variable to define error */ + int8_t rslt; + + /* Variable to define loop */ + uint8_t loop; + + /* Null-pointer check */ + rslt = null_ptr_check(dev); + if ((rslt == BMI2_OK) && (sens_int != NULL)) + { + for (loop = 0; loop < n_sens; loop++) + { + switch (sens_int[loop].type) + { + case BMI2_SIG_MOTION: + case BMI2_WRIST_GESTURE: + case BMI2_ANY_MOTION: + case BMI2_NO_MOTION: + case BMI2_STEP_COUNTER: + case BMI2_STEP_DETECTOR: + case BMI2_STEP_ACTIVITY: + case BMI2_WRIST_WEAR_WAKE_UP: + + rslt = bmi2_map_feat_int(sens_int[loop].type, sens_int[loop].hw_int_pin, dev); + break; + default: + rslt = BMI2_E_INVALID_SENSOR; + break; + } + + /* Return error if interrupt mapping fails */ + if (rslt != BMI2_OK) + { + break; + } + } + } + else + { + rslt = BMI2_E_NULL_PTR; + } + + return rslt; +} + +/***************************************************************************/ + +/*! Local Function Definitions + ****************************************************************************/ + /*! * @brief This internal API is used to validate the device structure pointer for * null conditions. @@ -640,3 +1926,2526 @@ static int8_t null_ptr_check(const struct bmi2_dev *dev) return rslt; } + +/*! + * @brief This internal API selects the sensor/features to be enabled or + * disabled. + */ +static int8_t select_sensor(const uint8_t *sens_list, uint8_t n_sens, uint64_t *sensor_sel) +{ + /* Variable to define error */ + int8_t rslt = BMI2_OK; + + /* Variable to define loop */ + uint8_t count; + + for (count = 0; count < n_sens; count++) + { + switch (sens_list[count]) + { + case BMI2_ACCEL: + *sensor_sel |= BMI2_ACCEL_SENS_SEL; + break; + case BMI2_GYRO: + *sensor_sel |= BMI2_GYRO_SENS_SEL; + break; + case BMI2_AUX: + *sensor_sel |= BMI2_AUX_SENS_SEL; + break; + case BMI2_TEMP: + *sensor_sel |= BMI2_TEMP_SENS_SEL; + break; + case BMI2_SIG_MOTION: + *sensor_sel |= BMI2_SIG_MOTION_SEL; + break; + case BMI2_ANY_MOTION: + *sensor_sel |= BMI2_ANY_MOT_SEL; + break; + case BMI2_NO_MOTION: + *sensor_sel |= BMI2_NO_MOT_SEL; + break; + case BMI2_STEP_DETECTOR: + *sensor_sel |= BMI2_STEP_DETECT_SEL; + break; + case BMI2_STEP_COUNTER: + *sensor_sel |= BMI2_STEP_COUNT_SEL; + break; + case BMI2_STEP_ACTIVITY: + *sensor_sel |= BMI2_STEP_ACT_SEL; + break; + case BMI2_GYRO_GAIN_UPDATE: + *sensor_sel |= BMI2_GYRO_GAIN_UPDATE_SEL; + break; + case BMI2_GYRO_SELF_OFF: + *sensor_sel |= BMI2_GYRO_SELF_OFF_SEL; + break; + case BMI2_WRIST_GESTURE: + *sensor_sel |= BMI2_WRIST_GEST_SEL; + break; + case BMI2_WRIST_WEAR_WAKE_UP: + *sensor_sel |= BMI2_WRIST_WEAR_WAKE_UP_SEL; + break; + default: + rslt = BMI2_E_INVALID_SENSOR; + break; + } + } + + return rslt; +} + +/*! + * @brief This internal API enables the selected sensor/features. + */ +static int8_t sensor_enable(uint64_t sensor_sel, struct bmi2_dev *dev) +{ + /* Variable to define error */ + int8_t rslt; + + /* Variable to store register values */ + uint8_t reg_data = 0; + + /* Variable to define loop */ + uint8_t loop = 1; + + /* Variable to get the status of advance power save */ + uint8_t aps_stat = 0; + + rslt = bmi2_get_regs(BMI2_PWR_CTRL_ADDR, ®_data, 1, dev); + if (rslt == BMI2_OK) + { + /* Enable accelerometer */ + if (sensor_sel & BMI2_ACCEL_SENS_SEL) + { + reg_data = BMI2_SET_BITS(reg_data, BMI2_ACC_EN, BMI2_ENABLE); + } + + /* Enable gyroscope */ + if (sensor_sel & BMI2_GYRO_SENS_SEL) + { + reg_data = BMI2_SET_BITS(reg_data, BMI2_GYR_EN, BMI2_ENABLE); + } + + /* Enable auxiliary sensor */ + if (sensor_sel & BMI2_AUX_SENS_SEL) + { + reg_data = BMI2_SET_BIT_POS0(reg_data, BMI2_AUX_EN, BMI2_ENABLE); + } + + /* Enable temperature sensor */ + if (sensor_sel & BMI2_TEMP_SENS_SEL) + { + reg_data = BMI2_SET_BITS(reg_data, BMI2_TEMP_EN, BMI2_ENABLE); + } + + /* Enable the sensors that are set in the power control register */ + if (sensor_sel & BMI2_MAIN_SENSORS) + { + rslt = bmi2_set_regs(BMI2_PWR_CTRL_ADDR, ®_data, 1, dev); + } + } + + if ((rslt == BMI2_OK) && (sensor_sel & ~(BMI2_MAIN_SENSORS))) + { + /* Get status of advance power save mode */ + aps_stat = dev->aps_status; + if (aps_stat == BMI2_ENABLE) + { + /* Disable advance power save if enabled */ + rslt = bmi2_set_adv_power_save(BMI2_DISABLE, dev); + } + + if (rslt == BMI2_OK) + { + while (loop--) + { + /* Enable sig-motion feature */ + if (sensor_sel & BMI2_SIG_MOTION_SEL) + { + rslt = set_sig_motion(BMI2_ENABLE, dev); + if (rslt == BMI2_OK) + { + dev->sens_en_stat |= BMI2_SIG_MOTION_SEL; + } + else + { + break; + } + } + + /* Enable any motion feature */ + if (sensor_sel & BMI2_ANY_MOT_SEL) + { + rslt = set_any_motion(BMI2_ENABLE, dev); + if (rslt == BMI2_OK) + { + dev->sens_en_stat |= BMI2_ANY_MOT_SEL; + } + else + { + break; + } + } + + /* Enable no motion feature */ + if (sensor_sel & BMI2_NO_MOT_SEL) + { + rslt = set_no_motion(BMI2_ENABLE, dev); + if (rslt == BMI2_OK) + { + dev->sens_en_stat |= BMI2_NO_MOT_SEL; + } + else + { + break; + } + } + + /* Enable step detector feature */ + if (sensor_sel & BMI2_STEP_DETECT_SEL) + { + rslt = set_step_detector(BMI2_ENABLE, dev); + if (rslt == BMI2_OK) + { + dev->sens_en_stat |= BMI2_STEP_DETECT_SEL; + } + else + { + break; + } + } + + /* Enable step counter feature */ + if (sensor_sel & BMI2_STEP_COUNT_SEL) + { + rslt = set_step_counter(BMI2_ENABLE, dev); + if (rslt == BMI2_OK) + { + dev->sens_en_stat |= BMI2_STEP_COUNT_SEL; + } + else + { + break; + } + } + + /* Enable step activity feature */ + if (sensor_sel & BMI2_STEP_ACT_SEL) + { + rslt = set_step_activity(BMI2_ENABLE, dev); + if (rslt == BMI2_OK) + { + dev->sens_en_stat |= BMI2_STEP_ACT_SEL; + } + else + { + break; + } + } + + /* Enable gyroscope user gain */ + if (sensor_sel & BMI2_GYRO_GAIN_UPDATE_SEL) + { + rslt = set_gyro_user_gain(BMI2_ENABLE, dev); + if (rslt == BMI2_OK) + { + dev->sens_en_stat |= BMI2_GYRO_GAIN_UPDATE_SEL; + } + else + { + break; + } + } + + /* Enable gyroscope self-offset correction feature */ + if (sensor_sel & BMI2_GYRO_SELF_OFF_SEL) + { + rslt = set_gyro_self_offset_corr(BMI2_ENABLE, dev); + if (rslt == BMI2_OK) + { + dev->sens_en_stat |= BMI2_GYRO_SELF_OFF_SEL; + } + else + { + break; + } + } + + /* Enable wrist gesture feature for wearable variant */ + if (sensor_sel & BMI2_WRIST_GEST_SEL) + { + rslt = set_wrist_gesture(BMI2_ENABLE, dev); + if (rslt == BMI2_OK) + { + dev->sens_en_stat |= BMI2_WRIST_GEST_SEL; + } + else + { + break; + } + } + + /* Enable wrist wear wake-up feature */ + if (sensor_sel & BMI2_WRIST_WEAR_WAKE_UP_SEL) + { + rslt = set_wrist_wear_wake_up(BMI2_ENABLE, dev); + if (rslt == BMI2_OK) + { + dev->sens_en_stat |= BMI2_WRIST_WEAR_WAKE_UP_SEL; + } + else + { + break; + } + } + } + + /* Enable Advance power save if disabled while + * configuring and not when already disabled + */ + if ((aps_stat == BMI2_ENABLE) && (rslt == BMI2_OK)) + { + rslt = bmi2_set_adv_power_save(BMI2_ENABLE, dev); + } + } + } + + return rslt; +} + +/*! + * @brief This internal API disables the selected sensors/features. + */ +static int8_t sensor_disable(uint64_t sensor_sel, struct bmi2_dev *dev) +{ + /* Variable to define error */ + int8_t rslt; + + /* Variable to store register values */ + uint8_t reg_data = 0; + + /* Variable to define loop */ + uint8_t loop = 1; + + /* Variable to get the status of advance power save */ + uint8_t aps_stat = 0; + + rslt = bmi2_get_regs(BMI2_PWR_CTRL_ADDR, ®_data, 1, dev); + if (rslt == BMI2_OK) + { + /* Disable accelerometer */ + if (sensor_sel & BMI2_ACCEL_SENS_SEL) + { + reg_data = BMI2_SET_BIT_VAL0(reg_data, BMI2_ACC_EN); + } + + /* Disable gyroscope */ + if (sensor_sel & BMI2_GYRO_SENS_SEL) + { + reg_data = BMI2_SET_BIT_VAL0(reg_data, BMI2_GYR_EN); + } + + /* Disable auxiliary sensor */ + if (sensor_sel & BMI2_AUX_SENS_SEL) + { + reg_data = BMI2_SET_BIT_VAL0(reg_data, BMI2_AUX_EN); + } + + /* Disable temperature sensor */ + if (sensor_sel & BMI2_TEMP_SENS_SEL) + { + reg_data = BMI2_SET_BIT_VAL0(reg_data, BMI2_TEMP_EN); + } + + /* Disable the sensors that are set in the power control register */ + if (sensor_sel & BMI2_MAIN_SENSORS) + { + rslt = bmi2_set_regs(BMI2_PWR_CTRL_ADDR, ®_data, 1, dev); + } + } + + if ((rslt == BMI2_OK) && (sensor_sel & ~(BMI2_MAIN_SENSORS))) + { + /* Get status of advance power save mode */ + aps_stat = dev->aps_status; + if (aps_stat == BMI2_ENABLE) + { + /* Disable advance power save if enabled */ + rslt = bmi2_set_adv_power_save(BMI2_DISABLE, dev); + } + + if (rslt == BMI2_OK) + { + while (loop--) + { + /* Disable sig-motion feature */ + if (sensor_sel & BMI2_SIG_MOTION_SEL) + { + rslt = set_sig_motion(BMI2_DISABLE, dev); + if (rslt == BMI2_OK) + { + dev->sens_en_stat &= ~BMI2_SIG_MOTION_SEL; + } + else + { + break; + } + } + + /* Disable any-motion feature */ + if (sensor_sel & BMI2_ANY_MOT_SEL) + { + rslt = set_any_motion(BMI2_DISABLE, dev); + if (rslt == BMI2_OK) + { + dev->sens_en_stat &= ~BMI2_ANY_MOT_SEL; + } + else + { + break; + } + } + + /* Disable no-motion feature */ + if (sensor_sel & BMI2_NO_MOT_SEL) + { + rslt = set_no_motion(BMI2_DISABLE, dev); + if (rslt == BMI2_OK) + { + dev->sens_en_stat &= ~BMI2_NO_MOT_SEL; + } + else + { + break; + } + } + + /* Disable step detector feature */ + if (sensor_sel & BMI2_STEP_DETECT_SEL) + { + rslt = set_step_detector(BMI2_DISABLE, dev); + if (rslt == BMI2_OK) + { + dev->sens_en_stat &= ~BMI2_STEP_DETECT_SEL; + } + else + { + break; + } + } + + /* Disable step counter feature */ + if (sensor_sel & BMI2_STEP_COUNT_SEL) + { + rslt = set_step_counter(BMI2_DISABLE, dev); + if (rslt == BMI2_OK) + { + dev->sens_en_stat &= ~BMI2_STEP_COUNT_SEL; + } + else + { + break; + } + } + + /* Disable step activity feature */ + if (sensor_sel & BMI2_STEP_ACT_SEL) + { + rslt = set_step_activity(BMI2_DISABLE, dev); + if (rslt == BMI2_OK) + { + dev->sens_en_stat &= ~BMI2_STEP_ACT_SEL; + } + else + { + break; + } + } + + /* Disable gyroscope user gain */ + if (sensor_sel & BMI2_GYRO_GAIN_UPDATE_SEL) + { + rslt = set_gyro_user_gain(BMI2_DISABLE, dev); + if (rslt == BMI2_OK) + { + dev->sens_en_stat &= ~BMI2_GYRO_GAIN_UPDATE_SEL; + } + else + { + break; + } + } + + /* Disable gyroscope self-offset correction feature */ + if (sensor_sel & BMI2_GYRO_SELF_OFF_SEL) + { + rslt = set_gyro_self_offset_corr(BMI2_DISABLE, dev); + if (rslt == BMI2_OK) + { + dev->sens_en_stat &= ~BMI2_GYRO_SELF_OFF_SEL; + } + else + { + break; + } + } + + /* Disable wrist gesture feature for wearable variant*/ + if (sensor_sel & BMI2_WRIST_GEST_SEL) + { + rslt = set_wrist_gesture(BMI2_DISABLE, dev); + if (rslt == BMI2_OK) + { + dev->sens_en_stat &= ~BMI2_WRIST_GEST_SEL; + } + else + { + break; + } + } + + /* Enable wrist wear wake-up feature */ + if (sensor_sel & BMI2_WRIST_WEAR_WAKE_UP_SEL) + { + rslt = set_wrist_wear_wake_up(BMI2_DISABLE, dev); + if (rslt == BMI2_OK) + { + dev->sens_en_stat &= ~BMI2_WRIST_WEAR_WAKE_UP_SEL; + } + else + { + break; + } + } + + /* Enable Advance power save if disabled while + * configuring and not when already disabled + */ + if ((aps_stat == BMI2_ENABLE) && (rslt == BMI2_OK)) + { + rslt = bmi2_set_adv_power_save(BMI2_ENABLE, dev); + } + } + } + } + + return rslt; +} + +/*! + * @brief This internal API is used to enable/disable any motion feature. + */ +static int8_t set_any_motion(uint8_t enable, struct bmi2_dev *dev) +{ + /* Variable to define error */ + int8_t rslt; + + /* Array to define the feature configuration */ + uint8_t feat_config[BMI2_FEAT_SIZE_IN_BYTES] = { 0 }; + + /* Variable to define the array offset */ + uint8_t idx = 0; + + /* Variable to set flag */ + uint8_t feat_found; + + /* Initialize feature configuration for any-motion */ + struct bmi2_feature_config any_mot_config = { 0, 0, 0 }; + + /* Search for any-motion feature and extract its configurations details */ + feat_found = bmi2_extract_input_feat_config(&any_mot_config, BMI2_ANY_MOTION, dev); + if (feat_found) + { + /* Get the configuration from the page where any-motion feature resides */ + rslt = bmi2_get_feat_config(any_mot_config.page, feat_config, dev); + if (rslt == BMI2_OK) + { + /* Define the offset for enable/disable of any-motion axes */ + idx = any_mot_config.start_addr + BMI2_ANY_MOT_FEAT_EN_OFFSET; + + /* Set the feature enable bit */ + feat_config[idx] = BMI2_SET_BITS(feat_config[idx], BMI2_ANY_NO_MOT_EN, enable); + + /* Set the configuration back to the page */ + rslt = bmi2_set_regs(BMI2_FEATURES_REG_ADDR, feat_config, BMI2_FEAT_SIZE_IN_BYTES, dev); + } + } + else + { + rslt = BMI2_E_INVALID_SENSOR; + } + + return rslt; +} + +/*! + * @brief This internal API is used to enable/disable no-motion feature. + */ +static int8_t set_no_motion(uint8_t enable, struct bmi2_dev *dev) +{ + /* Variable to define error */ + int8_t rslt; + + /* Array to define the feature configuration */ + uint8_t feat_config[BMI2_FEAT_SIZE_IN_BYTES] = { 0 }; + + /* Variable to define the array offset */ + uint8_t idx = 0; + + /* Variable to set flag */ + uint8_t feat_found; + + /* Initialize feature configuration for no-motion */ + struct bmi2_feature_config no_mot_config = { 0, 0, 0 }; + + /* Search for no-motion feature and extract its configurations details */ + feat_found = bmi2_extract_input_feat_config(&no_mot_config, BMI2_NO_MOTION, dev); + if (feat_found) + { + /* Get the configuration from the page where any/no-motion feature resides */ + rslt = bmi2_get_feat_config(no_mot_config.page, feat_config, dev); + if (rslt == BMI2_OK) + { + /* Define the offset for enable/disable of no-motion axes */ + idx = no_mot_config.start_addr + BMI2_NO_MOT_FEAT_EN_OFFSET; + + /* Set the feature enable bit */ + feat_config[idx] = BMI2_SET_BITS(feat_config[idx], BMI2_ANY_NO_MOT_EN, enable); + + /* Set the configuration back to the page */ + rslt = bmi2_set_regs(BMI2_FEATURES_REG_ADDR, feat_config, BMI2_FEAT_SIZE_IN_BYTES, dev); + } + } + else + { + rslt = BMI2_E_INVALID_SENSOR; + } + + return rslt; +} + +/*! + * @brief This internal API is used to enable/disable step detector feature. + */ +static int8_t set_step_detector(uint8_t enable, struct bmi2_dev *dev) +{ + /* Variable to define error */ + int8_t rslt; + + /* Array to define the feature configuration */ + uint8_t feat_config[BMI2_FEAT_SIZE_IN_BYTES] = { 0 }; + + /* Variable to define the array offset */ + uint8_t idx = 0; + + /* Variable to set flag */ + uint8_t feat_found; + + /* Initialize feature configuration for step detector */ + struct bmi2_feature_config step_det_config = { 0, 0, 0 }; + + /* Search for step detector feature and extract its configuration details */ + feat_found = bmi2_extract_input_feat_config(&step_det_config, BMI2_STEP_DETECTOR, dev); + if (feat_found) + { + /* Get the configuration from the page where step detector feature resides */ + rslt = bmi2_get_feat_config(step_det_config.page, feat_config, dev); + if (rslt == BMI2_OK) + { + /* Define the offset for enable/disable of step detector */ + idx = step_det_config.start_addr + BMI2_STEP_COUNT_FEAT_EN_OFFSET; + + /* Set the feature enable bit */ + feat_config[idx] = BMI2_SET_BITS(feat_config[idx], BMI2_STEP_DET_FEAT_EN, enable); + + /* Set the configuration back to the page */ + rslt = bmi2_set_regs(BMI2_FEATURES_REG_ADDR, feat_config, BMI2_FEAT_SIZE_IN_BYTES, dev); + } + } + else + { + rslt = BMI2_E_INVALID_SENSOR; + } + + return rslt; +} + +/*! + * @brief This internal API is used to enable/disable step counter feature. + */ +static int8_t set_step_counter(uint8_t enable, struct bmi2_dev *dev) +{ + /* Variable to define error */ + int8_t rslt; + + /* Array to define the feature configuration */ + uint8_t feat_config[BMI2_FEAT_SIZE_IN_BYTES] = { 0 }; + + /* Variable to define the array offset */ + uint8_t idx = 0; + + /* Variable to set flag */ + uint8_t feat_found; + + /* Initialize feature configuration for step counter */ + struct bmi2_feature_config step_count_config = { 0, 0, 0 }; + + /* Search for step counter feature and extract its configuration details */ + feat_found = bmi2_extract_input_feat_config(&step_count_config, BMI2_STEP_COUNTER, dev); + if (feat_found) + { + /* Get the configuration from the page where step-counter feature resides */ + rslt = bmi2_get_feat_config(step_count_config.page, feat_config, dev); + if (rslt == BMI2_OK) + { + /* Define the offset for enable/disable of step counter */ + idx = step_count_config.start_addr + BMI2_STEP_COUNT_FEAT_EN_OFFSET; + + /* Set the feature enable bit */ + feat_config[idx] = BMI2_SET_BITS(feat_config[idx], BMI2_STEP_COUNT_FEAT_EN, enable); + + /* Set the configuration back to the page */ + rslt = bmi2_set_regs(BMI2_FEATURES_REG_ADDR, feat_config, BMI2_FEAT_SIZE_IN_BYTES, dev); + } + } + else + { + rslt = BMI2_E_INVALID_SENSOR; + } + + return rslt; +} + +/*! + * @brief This internal API is used to enable/disable sig-motion feature. + */ +static int8_t set_sig_motion(uint8_t enable, struct bmi2_dev *dev) +{ + /* Variable to define error */ + int8_t rslt; + + /* Array to define the feature configuration */ + uint8_t feat_config[BMI2_FEAT_SIZE_IN_BYTES] = { 0 }; + + /* Variable to define the array offset */ + uint8_t idx = 0; + + /* Variable to set flag */ + uint8_t feat_found; + + /* Initialize feature configuration for sig-motion */ + struct bmi2_feature_config sig_mot_config = { 0, 0, 0 }; + + /* Search for sig-motion feature and extract its configuration details */ + feat_found = bmi2_extract_input_feat_config(&sig_mot_config, BMI2_SIG_MOTION, dev); + if (feat_found) + { + /* Get the configuration from the page where sig-motion feature resides */ + rslt = bmi2_get_feat_config(sig_mot_config.page, feat_config, dev); + if (rslt == BMI2_OK) + { + /* Define the offset for enable/disable of sig-motion */ + idx = sig_mot_config.start_addr + BMI2_SIG_MOT_FEAT_EN_OFFSET; + + /* Set the feature enable bit */ + feat_config[idx] = BMI2_SET_BIT_POS0(feat_config[idx], BMI2_SIG_MOT_FEAT_EN, enable); + + /* Set the configuration back to the page */ + rslt = bmi2_set_regs(BMI2_FEATURES_REG_ADDR, feat_config, BMI2_FEAT_SIZE_IN_BYTES, dev); + } + } + else + { + rslt = BMI2_E_INVALID_SENSOR; + } + + return rslt; +} + +/*! + * @brief This internal API is used to enable/disable step activity detection. + */ +static int8_t set_step_activity(uint8_t enable, struct bmi2_dev *dev) +{ + /* Variable to define error */ + int8_t rslt; + + /* Array to define the feature configuration */ + uint8_t feat_config[BMI2_FEAT_SIZE_IN_BYTES] = { 0 }; + + /* Variable to define the array offset */ + uint8_t idx = 0; + + /* Variable to set flag */ + uint8_t feat_found; + + /* Initialize feature configuration for step activity */ + struct bmi2_feature_config step_act_config = { 0, 0, 0 }; + + /* Search for step activity feature and extract its configuration details */ + feat_found = bmi2_extract_input_feat_config(&step_act_config, BMI2_STEP_ACTIVITY, dev); + if (feat_found) + { + /* Get the configuration from the page where step-activity + * feature resides + */ + rslt = bmi2_get_feat_config(step_act_config.page, feat_config, dev); + if (rslt == BMI2_OK) + { + /* Define the offset for enable/disable of step activity */ + idx = step_act_config.start_addr + BMI2_STEP_COUNT_FEAT_EN_OFFSET; + + /* Set the feature enable bit */ + feat_config[idx] = BMI2_SET_BITS(feat_config[idx], BMI2_STEP_ACT_FEAT_EN, enable); + + /* Set the configuration back to the page */ + rslt = bmi2_set_regs(BMI2_FEATURES_REG_ADDR, feat_config, BMI2_FEAT_SIZE_IN_BYTES, dev); + } + } + else + { + rslt = BMI2_E_INVALID_SENSOR; + } + + return rslt; +} + +/*! + * @brief This internal API gives an option to enable self-offset correction + * feature of gyroscope, either internally or by the host. + */ +static int8_t set_gyro_self_offset_corr(uint8_t enable, struct bmi2_dev *dev) +{ + /* Variable to define error */ + int8_t rslt; + + /* Array to define the feature configuration */ + uint8_t feat_config[BMI2_FEAT_SIZE_IN_BYTES] = { 0 }; + + /* Variable to define the array offset */ + uint8_t idx = 0; + + /* Variable to set flag */ + uint8_t feat_found; + + /* Initialize feature configuration for self-offset correction */ + struct bmi2_feature_config self_off_corr_cfg = { 0, 0, 0 }; + + /* Search for self-offset correction and extract its configuration details */ + feat_found = bmi2_extract_input_feat_config(&self_off_corr_cfg, BMI2_GYRO_SELF_OFF, dev); + if (feat_found) + { + /* Get the configuration from the page where self-offset + * correction feature resides + */ + rslt = bmi2_get_feat_config(self_off_corr_cfg.page, feat_config, dev); + if (rslt == BMI2_OK) + { + /* Define the offset for enable/disable of self-offset correction */ + idx = self_off_corr_cfg.start_addr; + + /* Set the feature enable bit */ + feat_config[idx] = BMI2_SET_BITS(feat_config[idx], BMI2_GYR_SELF_OFF_CORR_FEAT_EN, enable); + + /* Set the configuration back to the page */ + rslt = bmi2_set_regs(BMI2_FEATURES_REG_ADDR, feat_config, BMI2_FEAT_SIZE_IN_BYTES, dev); + } + } + else + { + rslt = BMI2_E_INVALID_SENSOR; + } + + return rslt; +} + +/*! + * @brief This internal API enables the wrist gesture feature. + */ +static int8_t set_wrist_gesture(uint8_t enable, struct bmi2_dev *dev) +{ + /* Variable to define error */ + int8_t rslt; + + /* Array to define the feature configuration */ + uint8_t feat_config[BMI2_FEAT_SIZE_IN_BYTES] = { 0 }; + + /* Variable to define the array offset */ + uint8_t idx = 0; + + /* Variable to set flag */ + uint8_t feat_found; + + /* Initialize feature configuration for wrist gesture */ + struct bmi2_feature_config wrist_gest_cfg = { 0, 0, 0 }; + + /* Search for wrist gesture and extract its configuration details */ + feat_found = bmi2_extract_input_feat_config(&wrist_gest_cfg, BMI2_WRIST_GESTURE, dev); + if (feat_found) + { + /* Get the configuration from the page where wrist gesture feature resides */ + rslt = bmi2_get_feat_config(wrist_gest_cfg.page, feat_config, dev); + if (rslt == BMI2_OK) + { + /* Define the offset for enable/disable of wrist gesture */ + idx = wrist_gest_cfg.start_addr; + + /* Set the feature enable bit */ + feat_config[idx] = BMI2_SET_BITS(feat_config[idx], BMI2_WRIST_GEST_FEAT_EN, enable); + + /* Set the configuration back to the page */ + rslt = bmi2_set_regs(BMI2_FEATURES_REG_ADDR, feat_config, BMI2_FEAT_SIZE_IN_BYTES, dev); + } + } + else + { + rslt = BMI2_E_INVALID_SENSOR; + } + + return rslt; +} + +/*! + * @brief This internal API enables the wrist wear wake up feature. + */ +static int8_t set_wrist_wear_wake_up(uint8_t enable, struct bmi2_dev *dev) +{ + /* Variable to define error */ + int8_t rslt; + + /* Array to define the feature configuration */ + uint8_t feat_config[BMI2_FEAT_SIZE_IN_BYTES] = { 0 }; + + /* Variable to define the array offset */ + uint8_t idx = 0; + + /* Variable to set flag */ + uint8_t feat_found; + + /* Initialize feature configuration for wrist wear wake up */ + struct bmi2_feature_config wrist_wake_up_cfg = { 0, 0, 0 }; + + /* Search for wrist wear wake up and extract its configuration details */ + feat_found = bmi2_extract_input_feat_config(&wrist_wake_up_cfg, BMI2_WRIST_WEAR_WAKE_UP, dev); + if (feat_found) + { + /* Get the configuration from the page where wrist wear wake up + * feature resides + */ + rslt = bmi2_get_feat_config(wrist_wake_up_cfg.page, feat_config, dev); + if (rslt == BMI2_OK) + { + /* Define the offset for enable/disable of wrist wear wake up */ + idx = wrist_wake_up_cfg.start_addr; + + /* Set the feature enable bit */ + feat_config[idx] = BMI2_SET_BITS(feat_config[idx], BMI2_WRIST_WEAR_WAKE_UP_FEAT_EN, enable); + + /* Set the configuration back to the page */ + rslt = bmi2_set_regs(BMI2_FEATURES_REG_ADDR, feat_config, BMI2_FEAT_SIZE_IN_BYTES, dev); + } + } + else + { + rslt = BMI2_E_INVALID_SENSOR; + } + + return rslt; +} + +/*! + * @brief This internal API is used to enable/disable gyroscope user gain + * feature. + */ +static int8_t set_gyro_user_gain(uint8_t enable, struct bmi2_dev *dev) +{ + /* Variable to define error */ + int8_t rslt; + + /* Array to define the feature configuration */ + uint8_t feat_config[BMI2_FEAT_SIZE_IN_BYTES] = { 0 }; + + /* Variable to define the array offset */ + uint8_t idx = 0; + + /* Variable to set flag */ + uint8_t feat_found; + + /* Initialize feature configuration for gyroscope user gain */ + struct bmi2_feature_config gyr_user_gain_cfg = { 0, 0, 0 }; + + /* Search for user gain feature and extract its configuration details */ + feat_found = bmi2_extract_input_feat_config(&gyr_user_gain_cfg, BMI2_GYRO_GAIN_UPDATE, dev); + if (feat_found) + { + /* Get the configuration from the page where user gain feature resides */ + rslt = bmi2_get_feat_config(gyr_user_gain_cfg.page, feat_config, dev); + if (rslt == BMI2_OK) + { + /* Define the offset for enable/disable of user gain */ + idx = gyr_user_gain_cfg.start_addr + BMI2_GYR_USER_GAIN_FEAT_EN_OFFSET; + + /* Set the feature enable bit */ + feat_config[idx] = BMI2_SET_BITS(feat_config[idx], BMI2_GYR_USER_GAIN_FEAT_EN, enable); + + /* Set the configuration back to the page */ + rslt = bmi2_set_regs(BMI2_FEATURES_REG_ADDR, feat_config, BMI2_FEAT_SIZE_IN_BYTES, dev); + } + } + else + { + rslt = BMI2_E_INVALID_SENSOR; + } + + return rslt; +} + +/*! + * @brief This internal API sets any-motion configurations like axes select, + * duration, threshold and output-configuration. + */ +static int8_t set_any_motion_config(const struct bmi2_any_motion_config *config, struct bmi2_dev *dev) +{ + /* Variable to define error */ + int8_t rslt; + + /* Array to define the feature configuration */ + uint8_t feat_config[BMI2_FEAT_SIZE_IN_BYTES] = { 0 }; + + /* Variable to define the array offset */ + uint8_t idx = 0; + + /* Variable to define count */ + uint8_t index = 0; + + /* Variable to set flag */ + uint8_t feat_found; + + /* Initialize feature configuration for any motion */ + struct bmi2_feature_config any_mot_config = { 0, 0, 0 }; + + /* Copy the feature configuration address to a local pointer */ + uint16_t *data_p = (uint16_t *) (void *)feat_config; + + /* Search for any-motion feature and extract its configuration details */ + feat_found = bmi2_extract_input_feat_config(&any_mot_config, BMI2_ANY_MOTION, dev); + if (feat_found) + { + /* Get the configuration from the page where any-motion feature resides */ + rslt = bmi2_get_feat_config(any_mot_config.page, feat_config, dev); + if (rslt == BMI2_OK) + { + /* Define the offset in bytes for any-motion select */ + idx = any_mot_config.start_addr; + + /* Get offset in words since all the features are set in words length */ + idx = idx / 2; + + /* Set duration */ + *(data_p + idx) = BMI2_SET_BIT_POS0(*(data_p + idx), BMI2_ANY_NO_MOT_DUR, config->duration); + + /* Set x-select */ + *(data_p + idx) = BMI2_SET_BITS(*(data_p + idx), BMI2_ANY_NO_MOT_X_SEL, config->select_x); + + /* Set y-select */ + *(data_p + idx) = BMI2_SET_BITS(*(data_p + idx), BMI2_ANY_NO_MOT_Y_SEL, config->select_y); + + /* Set z-select */ + *(data_p + idx) = BMI2_SET_BITS(*(data_p + idx), BMI2_ANY_NO_MOT_Z_SEL, config->select_z); + + /* Increment offset by 1 word to set threshold and output configuration */ + idx++; + + /* Set threshold */ + *(data_p + idx) = BMI2_SET_BIT_POS0(*(data_p + idx), BMI2_ANY_NO_MOT_THRES, config->threshold); + + /* Increment offset by 1 more word to get the total length in words */ + idx++; + + /* Get total length in bytes to copy from local pointer to the array */ + idx = (uint8_t)(idx * 2) - any_mot_config.start_addr; + + /* Copy the bytes to be set back to the array */ + for (index = 0; index < idx; index++) + { + feat_config[any_mot_config.start_addr + + index] = *((uint8_t *) data_p + any_mot_config.start_addr + index); + } + + /* Set the configuration back to the page */ + rslt = bmi2_set_regs(BMI2_FEATURES_REG_ADDR, feat_config, BMI2_FEAT_SIZE_IN_BYTES, dev); + } + } + else + { + rslt = BMI2_E_INVALID_SENSOR; + } + + return rslt; +} + +/*! + * @brief This internal API sets no-motion configurations like axes select, + * duration, threshold and output-configuration. + */ +static int8_t set_no_motion_config(const struct bmi2_no_motion_config *config, struct bmi2_dev *dev) +{ + /* Variable to define error */ + int8_t rslt; + + /* Array to define the feature configuration */ + uint8_t feat_config[BMI2_FEAT_SIZE_IN_BYTES] = { 0 }; + + /* Variable to define the array offset */ + uint8_t idx = 0; + + /* Variable to define count */ + uint8_t index = 0; + + /* Variable to set flag */ + uint8_t feat_found; + + /* Initialize feature configuration for no-motion */ + struct bmi2_feature_config no_mot_config = { 0, 0, 0 }; + + /* Copy the feature configuration address to a local pointer */ + uint16_t *data_p = (uint16_t *) (void *)feat_config; + + /* Search for no-motion feature and extract its configuration details */ + feat_found = bmi2_extract_input_feat_config(&no_mot_config, BMI2_NO_MOTION, dev); + if (feat_found) + { + /* Get the configuration from the page where no-motion feature resides */ + rslt = bmi2_get_feat_config(no_mot_config.page, feat_config, dev); + if (rslt == BMI2_OK) + { + /* Define the offset in bytes for no-motion select */ + idx = no_mot_config.start_addr; + + /* Get offset in words since all the features are set in words length */ + idx = idx / 2; + + /* Set duration */ + *(data_p + idx) = BMI2_SET_BIT_POS0(*(data_p + idx), BMI2_ANY_NO_MOT_DUR, config->duration); + + /* Set x-select */ + *(data_p + idx) = BMI2_SET_BITS(*(data_p + idx), BMI2_ANY_NO_MOT_X_SEL, config->select_x); + + /* Set y-select */ + *(data_p + idx) = BMI2_SET_BITS(*(data_p + idx), BMI2_ANY_NO_MOT_Y_SEL, config->select_y); + + /* Set z-select */ + *(data_p + idx) = BMI2_SET_BITS(*(data_p + idx), BMI2_ANY_NO_MOT_Z_SEL, config->select_z); + + /* Increment offset by 1 word to set threshold and output configuration */ + idx++; + + /* Set threshold */ + *(data_p + idx) = BMI2_SET_BIT_POS0(*(data_p + idx), BMI2_ANY_NO_MOT_THRES, config->threshold); + + /* Increment offset by 1 more word to get the total length in words */ + idx++; + + /* Get total length in bytes to copy from local pointer to the array */ + idx = (uint8_t)(idx * 2) - no_mot_config.start_addr; + + /* Copy the bytes to be set back to the array */ + for (index = 0; index < idx; index++) + { + feat_config[no_mot_config.start_addr + + index] = *((uint8_t *) data_p + no_mot_config.start_addr + index); + } + + /* Set the configuration back to the page */ + rslt = bmi2_set_regs(BMI2_FEATURES_REG_ADDR, feat_config, BMI2_FEAT_SIZE_IN_BYTES, dev); + } + } + else + { + rslt = BMI2_E_INVALID_SENSOR; + } + + return rslt; +} + +/*! + * @brief This internal API sets sig-motion configurations like block-size, + * output-configuration and other parameters. + */ +static int8_t set_sig_motion_config(const struct bmi2_sig_motion_config *config, struct bmi2_dev *dev) +{ + /* Variable to define error */ + int8_t rslt; + + /* Array to define the feature configuration */ + uint8_t feat_config[BMI2_FEAT_SIZE_IN_BYTES] = { 0 }; + + /* Variable to define the array offset */ + uint8_t idx = 0; + + /* Variable to define index */ + uint8_t index = 0; + + /* Variable to set flag */ + uint8_t feat_found; + + /* Initialize feature configuration for sig-motion */ + struct bmi2_feature_config sig_mot_config = { 0, 0, 0 }; + + /* Copy the feature configuration address to a local pointer */ + uint16_t *data_p = (uint16_t *) (void *)feat_config; + + /* Search for sig-motion feature and extract its configuration details */ + feat_found = bmi2_extract_input_feat_config(&sig_mot_config, BMI2_SIG_MOTION, dev); + if (feat_found) + { + /* Get the configuration from the page where sig-motion feature resides */ + rslt = bmi2_get_feat_config(sig_mot_config.page, feat_config, dev); + if (rslt == BMI2_OK) + { + /* Define the offset in bytes for sig-motion select */ + idx = sig_mot_config.start_addr; + + /* Get offset in words since all the features are set in words length */ + idx = idx / 2; + + /* Set parameter 1 */ + *(data_p + idx) = BMI2_SET_BIT_POS0(*(data_p + idx), BMI2_SIG_MOT_PARAM_1, config->block_size); + + /* Increment offset by 1 word to set parameter 2 */ + idx++; + + /* Set parameter 2 */ + *(data_p + idx) = BMI2_SET_BIT_POS0(*(data_p + idx), BMI2_SIG_MOT_PARAM_2, config->param_2); + + /* Increment offset by 1 word to set parameter 3 */ + idx++; + + /* Set parameter 3 */ + *(data_p + idx) = BMI2_SET_BIT_POS0(*(data_p + idx), BMI2_SIG_MOT_PARAM_3, config->param_3); + + /* Increment offset by 1 word to set parameter 4 */ + idx++; + + /* Set parameter 4 */ + *(data_p + idx) = BMI2_SET_BIT_POS0(*(data_p + idx), BMI2_SIG_MOT_PARAM_4, config->param_4); + + /* Increment offset by 1 word to set parameter 5 */ + idx++; + + /* Set parameter 5 */ + *(data_p + idx) = BMI2_SET_BIT_POS0(*(data_p + idx), BMI2_SIG_MOT_PARAM_5, config->param_5); + + /* Increment offset by 1 word to set output- configuration */ + idx++; + + /* Get total length in bytes to copy from local pointer to the array */ + idx = (uint8_t)(idx * 2) - sig_mot_config.start_addr; + + /* Copy the bytes to be set back to the array */ + for (index = 0; index < idx; index++) + { + feat_config[sig_mot_config.start_addr + + index] = *((uint8_t *) data_p + sig_mot_config.start_addr + index); + } + + /* Set the configuration back to the page */ + rslt = bmi2_set_regs(BMI2_FEATURES_REG_ADDR, feat_config, BMI2_FEAT_SIZE_IN_BYTES, dev); + } + } + else + { + rslt = BMI2_E_INVALID_SENSOR; + } + + return rslt; +} + +/*! + * @brief This internal API sets step counter parameter configurations. + */ +static int8_t set_step_count_params_config(const uint16_t *step_count_params, struct bmi2_dev *dev) +{ + /* Variable to define error */ + int8_t rslt = BMI2_OK; + + /* Array to define the feature configuration */ + uint8_t feat_config[BMI2_FEAT_SIZE_IN_BYTES] = { 0 }; + + /* Variable to define index */ + uint8_t index = 0; + + /* Variable to set flag */ + uint8_t feat_found; + + /* Initialize feature configuration for step counter parameters */ + struct bmi2_feature_config step_params_config = { 0, 0, 0 }; + + /* Variable to index the page number */ + uint8_t page_idx; + + /* Variable to define the start page */ + uint8_t start_page; + + /* Variable to define start address of the parameters */ + uint8_t start_addr; + + /* Variable to define number of bytes */ + uint8_t n_bytes = (BMI2_STEP_CNT_N_PARAMS * 2); + + /* Variable to store number of pages */ + uint8_t n_pages = (n_bytes / 16); + + /* Variable to define the end page */ + uint8_t end_page; + + /* Variable to define the remaining bytes to be read */ + uint8_t remain_len; + + /* Variable to define the maximum words(16 bytes or 8 words) to be read in a page */ + uint8_t max_len = 8; + + /* Variable index bytes in a page */ + uint8_t page_byte_idx; + + /* Variable to index the parameters */ + uint8_t param_idx = 0; + + /* Copy the feature configuration address to a local pointer */ + uint16_t *data_p = (uint16_t *) (void *)feat_config; + + /* Search for step counter parameter feature and extract its configuration details */ + feat_found = bmi2_extract_input_feat_config(&step_params_config, BMI2_STEP_COUNTER_PARAMS, dev); + if (feat_found) + { + /* Get the start page for the step counter parameters */ + start_page = step_params_config.page; + + /* Get the end page for the step counter parameters */ + end_page = start_page + n_pages; + + /* Get the start address for the step counter parameters */ + start_addr = step_params_config.start_addr; + + /* Get the remaining length of bytes to be read */ + remain_len = (uint8_t)((n_bytes - (n_pages * 16)) + start_addr); + for (page_idx = start_page; page_idx <= end_page; page_idx++) + { + /* Get the configuration from the respective page */ + rslt = bmi2_get_feat_config(page_idx, feat_config, dev); + if (rslt == BMI2_OK) + { + /* Start from address 0x00 when switched to next page */ + if (page_idx > start_page) + { + start_addr = 0; + } + + /* Remaining number of words to be read in the page */ + if (page_idx == end_page) + { + max_len = (remain_len / 2); + } + + /* Get offset in words since all the features are set in words length */ + page_byte_idx = start_addr / 2; + for (; page_byte_idx < max_len;) + { + /* Set parameters 1 to 25 */ + *(data_p + page_byte_idx) = BMI2_SET_BIT_POS0(*(data_p + page_byte_idx), + BMI2_STEP_COUNT_PARAMS, + step_count_params[param_idx]); + + /* Increment offset by 1 word to set to the next parameter */ + page_byte_idx++; + + /* Increment to next parameter */ + param_idx++; + } + + /* Get total length in bytes to copy from local pointer to the array */ + page_byte_idx = (uint8_t)(page_byte_idx * 2) - step_params_config.start_addr; + + /* Copy the bytes to be set back to the array */ + for (index = 0; index < page_byte_idx; index++) + { + feat_config[step_params_config.start_addr + + index] = *((uint8_t *) data_p + step_params_config.start_addr + index); + } + + /* Set the configuration back to the page */ + rslt = bmi2_set_regs(BMI2_FEATURES_REG_ADDR, feat_config, BMI2_FEAT_SIZE_IN_BYTES, dev); + } + } + } + else + { + rslt = BMI2_E_INVALID_SENSOR; + } + + return rslt; +} + +/* @brief This internal API sets step counter configurations like water-mark + * level, reset-counter and output-configuration step detector and activity. + */ +static int8_t set_step_config(const struct bmi2_step_config *config, struct bmi2_dev *dev) +{ + /* Variable to define error */ + int8_t rslt; + + /* Array to define the feature configuration */ + uint8_t feat_config[BMI2_FEAT_SIZE_IN_BYTES] = { 0 }; + + /* Variable to define the array offset */ + uint8_t idx = 0; + + /* Variable to define index */ + uint8_t index = 0; + + /* Variable to set flag */ + uint8_t feat_found; + + /* Initialize feature configuration for step counter 4 */ + struct bmi2_feature_config step_count_config = { 0, 0, 0 }; + + /* Copy the feature configuration address to a local pointer */ + uint16_t *data_p = (uint16_t *) (void *)feat_config; + + /* Search for step counter feature and extract its configuration details */ + feat_found = bmi2_extract_input_feat_config(&step_count_config, BMI2_STEP_COUNTER, dev); + if (feat_found) + { + /* Get the configuration from the page where step counter resides */ + rslt = bmi2_get_feat_config(step_count_config.page, feat_config, dev); + if (rslt == BMI2_OK) + { + /* Define the offset in bytes */ + idx = step_count_config.start_addr; + + /* Get offset in words since all the features are set in words length */ + idx = idx / 2; + + /* Set water-mark level */ + *(data_p + idx) = BMI2_SET_BIT_POS0(*(data_p + idx), BMI2_STEP_COUNT_WM_LEVEL, config->watermark_level); + + /* Set reset-counter */ + *(data_p + idx) = BMI2_SET_BITS(*(data_p + idx), BMI2_STEP_COUNT_RST_CNT, config->reset_counter); + + /* Increment offset by 1 word to set output + * configuration of step detector and step activity + */ + idx++; + + /* Set step buffer size */ + *(data_p + idx) = BMI2_SET_BITS(*(data_p + idx), BMI2_STEP_BUFFER_SIZE, config->step_buffer_size); + + /* Increment offset by 1 more word to get the total length in words */ + idx++; + + /* Get total length in bytes to copy from local pointer to the array */ + idx = (uint8_t)(idx * 2) - step_count_config.start_addr; + + /* Copy the bytes to be set back to the array */ + for (index = 0; index < idx; index++) + { + feat_config[step_count_config.start_addr + + index] = *((uint8_t *) data_p + step_count_config.start_addr + index); + } + + /* Set the configuration back to the page */ + rslt = bmi2_set_regs(BMI2_FEATURES_REG_ADDR, feat_config, BMI2_FEAT_SIZE_IN_BYTES, dev); + } + } + else + { + rslt = BMI2_E_INVALID_SENSOR; + } + + return rslt; +} + +/*! + * @brief This internal API sets wrist gesture configurations like wearable-arm, + * and output-configuration. + */ +static int8_t set_wrist_gest_config(const struct bmi2_wrist_gest_config *config, struct bmi2_dev *dev) +{ + /* Variable to define error */ + int8_t rslt; + + /* Array to define the feature configuration */ + uint8_t feat_config[BMI2_FEAT_SIZE_IN_BYTES] = { 0 }; + + /* Variable to define the array offset */ + uint8_t idx = 0; + + /* Variable to define index */ + uint8_t index = 0; + + /* Variable to set flag */ + uint8_t feat_found; + + /* Initialize feature configuration for wrist gesture */ + struct bmi2_feature_config wrist_gest_config = { 0, 0, 0 }; + + /* Copy the feature configuration address to a local pointer */ + uint16_t *data_p = (uint16_t *) (void *)feat_config; + + /* Search for wrist gesture feature and extract its configuration details */ + feat_found = bmi2_extract_input_feat_config(&wrist_gest_config, BMI2_WRIST_GESTURE, dev); + if (feat_found) + { + /* Get the configuration from the page where wrist gesture feature resides */ + rslt = bmi2_get_feat_config(wrist_gest_config.page, feat_config, dev); + if (rslt == BMI2_OK) + { + /* Define the offset in bytes for gesture select */ + idx = wrist_gest_config.start_addr; + + /* Get offset in words since all the features are set in words length */ + idx = idx / 2; + + /* Set wearable arm */ + *(data_p + idx) = BMI2_SET_BITS(*(data_p + idx), BMI2_WRIST_GEST_WEAR_ARM, config->wearable_arm); + + /* Increment offset by 1 more word to set minimum tilt angle (min_flick_peak) */ + idx++; + *(data_p + idx) = config->min_flick_peak; + + /* Increment offset by 1 more word to set min_flick_samples */ + idx++; + *(data_p + idx) = config->min_flick_samples; + + /* Increment offset by 1 more word to set max time within gesture moment has to be completed */ + idx++; + *(data_p + idx) = config->max_duration; + + /* Increment offset by 1 more word to get the total length in words */ + idx++; + + /* Get total length in bytes to copy from local pointer to the array */ + idx = (uint8_t)(idx * 2) - wrist_gest_config.start_addr; + + /* Copy the bytes to be set back to the array */ + for (index = 0; index < idx; index++) + { + feat_config[wrist_gest_config.start_addr + + index] = *((uint8_t *) data_p + wrist_gest_config.start_addr + index); + } + + /* Set the configuration back to the page */ + rslt = bmi2_set_regs(BMI2_FEATURES_REG_ADDR, feat_config, BMI2_FEAT_SIZE_IN_BYTES, dev); + } + } + else + { + rslt = BMI2_E_INVALID_SENSOR; + } + + return rslt; +} + +/*! + * @brief This internal API sets wrist wear wake-up configurations like + * output-configuration. + */ +static int8_t set_wrist_wear_wake_up_config(const struct bmi2_wrist_wear_wake_up_config *config, struct bmi2_dev *dev) +{ + /* Variable to define error */ + int8_t rslt; + + /* Array to define the feature configuration */ + uint8_t feat_config[BMI2_FEAT_SIZE_IN_BYTES] = { 0 }; + + /* Variable to define the array offset */ + uint8_t idx = 0; + + /* Variable to define index */ + uint8_t index = 0; + + /* Variable to set flag */ + uint8_t feat_found; + + /* Initialize feature configuration for wrist wear wake-up */ + struct bmi2_feature_config wrist_wake_up_config = { 0, 0, 0 }; + + /* Copy the feature configuration address to a local pointer */ + uint16_t *data_p = (uint16_t *) (void *)feat_config; + + /* Search for wrist wear wake-up feature and extract its configuration details */ + feat_found = bmi2_extract_input_feat_config(&wrist_wake_up_config, BMI2_WRIST_WEAR_WAKE_UP, dev); + if (feat_found) + { + /* Get the configuration from the page where wrist wear wake-up feature resides */ + rslt = bmi2_get_feat_config(wrist_wake_up_config.page, feat_config, dev); + if (rslt == BMI2_OK) + { + /* Define the offset in bytes for wrist wear wake-up select */ + idx = wrist_wake_up_config.start_addr; + + /* Get offset in words since all the features are set in words length */ + idx = idx / 2; + + *(data_p + idx) = config->min_angle_focus; + + /* Increment offset by 1 more word to set min_angle_nonfocus */ + idx++; + *(data_p + idx) = config->min_angle_nonfocus; + + /* Increment offset by 1 more word to set max_tilt_lr */ + idx++; + *(data_p + idx) = config->max_tilt_lr; + + /* Increment offset by 1 more word to set max_tilt_ll */ + idx++; + *(data_p + idx) = config->max_tilt_ll; + + /* Increment offset by 1 more word to set max_tilt_pd */ + idx++; + *(data_p + idx) = config->max_tilt_pd; + + /* Increment offset by 1 more word to set max_tilt_pu */ + idx++; + *(data_p + idx) = config->max_tilt_pu; + + /* Increment offset by 1 more word to get the total length in words */ + idx++; + + /* Get total length in bytes to copy from local pointer to the array */ + idx = (uint8_t)(idx * 2) - wrist_wake_up_config.start_addr; + + /* Copy the bytes to be set back to the array */ + for (index = 0; index < idx; index++) + { + feat_config[wrist_wake_up_config.start_addr + + index] = *((uint8_t *) data_p + wrist_wake_up_config.start_addr + index); + } + + /* Set the configuration back to the page */ + rslt = bmi2_set_regs(BMI2_FEATURES_REG_ADDR, feat_config, BMI2_FEAT_SIZE_IN_BYTES, dev); + } + } + else + { + rslt = BMI2_E_INVALID_SENSOR; + } + + return rslt; +} + +/*! + * @brief This internal API gets any-motion configurations like axes select, + * duration, threshold and output-configuration. + */ +static int8_t get_any_motion_config(struct bmi2_any_motion_config *config, struct bmi2_dev *dev) +{ + /* Variable to define error */ + int8_t rslt; + + /* Array to define the feature configuration */ + uint8_t feat_config[BMI2_FEAT_SIZE_IN_BYTES] = { 0 }; + + /* Variable to define the array offset */ + uint8_t idx = 0; + + /* Variable to define LSB */ + uint16_t lsb; + + /* Variable to define MSB */ + uint16_t msb; + + /* Variable to define a word */ + uint16_t lsb_msb; + + /* Variable to set flag */ + uint8_t feat_found; + + /* Initialize feature configuration for any-motion */ + struct bmi2_feature_config any_mot_config = { 0, 0, 0 }; + + /* Search for any-motion feature and extract its configuration details */ + feat_found = bmi2_extract_input_feat_config(&any_mot_config, BMI2_ANY_MOTION, dev); + if (feat_found) + { + /* Get the configuration from the page where any-motion feature resides */ + rslt = bmi2_get_feat_config(any_mot_config.page, feat_config, dev); + if (rslt == BMI2_OK) + { + /* Define the offset for feature enable for any-motion */ + idx = any_mot_config.start_addr; + + /* Get word to calculate duration, x, y and z select */ + lsb = (uint16_t) feat_config[idx++]; + msb = ((uint16_t) feat_config[idx++] << 8); + lsb_msb = lsb | msb; + + /* Get duration */ + config->duration = lsb_msb & BMI2_ANY_NO_MOT_DUR_MASK; + + /* Get x-select */ + config->select_x = (lsb_msb & BMI2_ANY_NO_MOT_X_SEL_MASK) >> BMI2_ANY_NO_MOT_X_SEL_POS; + + /* Get y-select */ + config->select_y = (lsb_msb & BMI2_ANY_NO_MOT_Y_SEL_MASK) >> BMI2_ANY_NO_MOT_Y_SEL_POS; + + /* Get z-select */ + config->select_z = (lsb_msb & BMI2_ANY_NO_MOT_Z_SEL_MASK) >> BMI2_ANY_NO_MOT_Z_SEL_POS; + + /* Get word to calculate threshold, output configuration from the same word */ + lsb = (uint16_t) feat_config[idx++]; + msb = ((uint16_t) feat_config[idx++] << 8); + lsb_msb = lsb | msb; + + /* Get threshold */ + config->threshold = lsb_msb & BMI2_ANY_NO_MOT_THRES_MASK; + } + } + else + { + rslt = BMI2_E_INVALID_SENSOR; + } + + return rslt; +} + +/*! + * @brief This internal API gets no-motion configurations like axes select, + * duration, threshold and output-configuration. + */ +static int8_t get_no_motion_config(struct bmi2_no_motion_config *config, struct bmi2_dev *dev) +{ + /* Variable to define error */ + int8_t rslt; + + /* Array to define the feature configuration */ + uint8_t feat_config[BMI2_FEAT_SIZE_IN_BYTES] = { 0 }; + + /* Variable to define the array offset */ + uint8_t idx = 0; + + /* Variable to define LSB */ + uint16_t lsb = 0; + + /* Variable to define MSB */ + uint16_t msb = 0; + + /* Variable to define a word */ + uint16_t lsb_msb = 0; + + /* Variable to set flag */ + uint8_t feat_found; + + /* Initialize feature configuration for no-motion */ + struct bmi2_feature_config no_mot_config = { 0, 0, 0 }; + + /* Search for no-motion feature and extract its configuration details */ + feat_found = bmi2_extract_input_feat_config(&no_mot_config, BMI2_NO_MOTION, dev); + if (feat_found) + { + /* Get the configuration from the page where no-motion feature resides */ + rslt = bmi2_get_feat_config(no_mot_config.page, feat_config, dev); + if (rslt == BMI2_OK) + { + /* Define the offset for feature enable for no-motion */ + idx = no_mot_config.start_addr; + + /* Get word to calculate duration, x, y and z select */ + lsb = (uint16_t) feat_config[idx++]; + msb = ((uint16_t) feat_config[idx++] << 8); + lsb_msb = lsb | msb; + + /* Get duration */ + config->duration = lsb_msb & BMI2_ANY_NO_MOT_DUR_MASK; + + /* Get x-select */ + config->select_x = (lsb_msb & BMI2_ANY_NO_MOT_X_SEL_MASK) >> BMI2_ANY_NO_MOT_X_SEL_POS; + + /* Get y-select */ + config->select_y = (lsb_msb & BMI2_ANY_NO_MOT_Y_SEL_MASK) >> BMI2_ANY_NO_MOT_Y_SEL_POS; + + /* Get z-select */ + config->select_z = (lsb_msb & BMI2_ANY_NO_MOT_Z_SEL_MASK) >> BMI2_ANY_NO_MOT_Z_SEL_POS; + + /* Get word to calculate threshold, output configuration from the same word */ + lsb = (uint16_t) feat_config[idx++]; + msb = ((uint16_t) feat_config[idx++] << 8); + lsb_msb = lsb | msb; + + /* Get threshold */ + config->threshold = lsb_msb & BMI2_ANY_NO_MOT_THRES_MASK; + } + } + else + { + rslt = BMI2_E_INVALID_SENSOR; + } + + return rslt; +} + +/*! + * @brief This internal API gets sig-motion configurations like block-size, + * output-configuration and other parameters. + */ +static int8_t get_sig_motion_config(struct bmi2_sig_motion_config *config, struct bmi2_dev *dev) +{ + /* Variable to define error */ + int8_t rslt; + + /* Array to define the feature configuration */ + uint8_t feat_config[BMI2_FEAT_SIZE_IN_BYTES] = { 0 }; + + /* Variable to define the array offset */ + uint8_t idx = 0; + + /* Variable to define LSB */ + uint16_t lsb = 0; + + /* Variable to define MSB */ + uint16_t msb = 0; + + /* Variable to define a word */ + uint16_t lsb_msb = 0; + + /* Variable to set flag */ + uint8_t feat_found; + + /* Initialize feature configuration sig-motion */ + struct bmi2_feature_config sig_mot_config = { 0, 0, 0 }; + + /* Search for sig-motion feature and extract its configuration details */ + feat_found = bmi2_extract_input_feat_config(&sig_mot_config, BMI2_SIG_MOTION, dev); + if (feat_found) + { + /* Get the configuration from the page where sig-motion feature resides */ + rslt = bmi2_get_feat_config(sig_mot_config.page, feat_config, dev); + if (rslt == BMI2_OK) + { + /* Define the offset for feature enable for sig-motion */ + idx = sig_mot_config.start_addr; + + /* Get word to calculate parameter 1 */ + lsb = (uint16_t) feat_config[idx++]; + msb = ((uint16_t) feat_config[idx++] << 8); + lsb_msb = lsb | msb; + + /* Get parameter 1 */ + config->block_size = lsb_msb & BMI2_SIG_MOT_PARAM_1_MASK; + + /* Get word to calculate parameter 2 */ + lsb = (uint16_t) feat_config[idx++]; + msb = ((uint16_t) feat_config[idx++] << 8); + lsb_msb = lsb | msb; + + /* Get parameter 2 */ + config->param_2 = lsb_msb & BMI2_SIG_MOT_PARAM_2_MASK; + + /* Get word to calculate parameter 3 */ + lsb = (uint16_t) feat_config[idx++]; + msb = ((uint16_t) feat_config[idx++] << 8); + lsb_msb = lsb | msb; + + /* Get parameter 3 */ + config->param_3 = lsb_msb & BMI2_SIG_MOT_PARAM_3_MASK; + + /* Get word to calculate parameter 4 */ + lsb = (uint16_t) feat_config[idx++]; + msb = ((uint16_t) feat_config[idx++] << 8); + lsb_msb = lsb | msb; + + /* Get parameter 4 */ + config->param_4 = lsb_msb & BMI2_SIG_MOT_PARAM_4_MASK; + + /* Get word to calculate parameter 5 */ + lsb = (uint16_t) feat_config[idx++]; + msb = ((uint16_t) feat_config[idx++] << 8); + lsb_msb = lsb | msb; + + /* Get parameter 5 */ + config->param_5 = lsb_msb & BMI2_SIG_MOT_PARAM_5_MASK; + } + } + else + { + rslt = BMI2_E_INVALID_SENSOR; + } + + return rslt; +} + +/*! + * @brief This internal API gets step counter parameter configurations. + */ +static int8_t get_step_count_params_config(uint16_t *step_count_params, struct bmi2_dev *dev) +{ + /* Variable to define error */ + int8_t rslt = BMI2_OK; + + /* Array to define the feature configuration */ + uint8_t feat_config[BMI2_FEAT_SIZE_IN_BYTES] = { 0 }; + + /* Variable to set flag */ + uint8_t feat_found; + + /* Variable to define LSB */ + uint16_t lsb = 0; + + /* Variable to define MSB */ + uint16_t msb = 0; + + /* Variable to define a word */ + uint16_t lsb_msb = 0; + + /* Initialize feature configuration for step counter 1 */ + struct bmi2_feature_config step_params_config = { 0, 0, 0 }; + + /* Variable to index the page number */ + uint8_t page_idx; + + /* Variable to define the start page */ + uint8_t start_page; + + /* Variable to define start address of the parameters */ + uint8_t start_addr; + + /* Variable to define number of bytes */ + uint8_t n_bytes = (BMI2_STEP_CNT_N_PARAMS * 2); + + /* Variable to store number of pages */ + uint8_t n_pages = (n_bytes / 16); + + /* Variable to define the end page */ + uint8_t end_page; + + /* Variable to define the remaining bytes to be read */ + uint8_t remain_len; + + /* Variable to define the maximum words to be read in a page */ + uint8_t max_len = BMI2_FEAT_SIZE_IN_BYTES; + + /* Variable index bytes in a page */ + uint8_t page_byte_idx; + + /* Variable to index the parameters */ + uint8_t param_idx = 0; + + /* Search for step counter parameter feature and extract its configuration details */ + feat_found = bmi2_extract_input_feat_config(&step_params_config, BMI2_STEP_COUNTER_PARAMS, dev); + if (feat_found) + { + /* Get the start page for the step counter parameters */ + start_page = step_params_config.page; + + /* Get the end page for the step counter parameters */ + end_page = start_page + n_pages; + + /* Get the start address for the step counter parameters */ + start_addr = step_params_config.start_addr; + + /* Get the remaining length of bytes to be read */ + remain_len = (uint8_t)((n_bytes - (n_pages * 16)) + start_addr); + for (page_idx = start_page; page_idx <= end_page; page_idx++) + { + /* Get the configuration from the respective page */ + rslt = bmi2_get_feat_config(page_idx, feat_config, dev); + if (rslt == BMI2_OK) + { + /* Start from address 0x00 when switched to next page */ + if (page_idx > start_page) + { + start_addr = 0; + } + + /* Remaining number of bytes to be read in the page */ + if (page_idx == end_page) + { + max_len = remain_len; + } + + /* Get the offset */ + page_byte_idx = start_addr; + while (page_byte_idx < max_len) + { + /* Get word to calculate the parameter*/ + lsb = (uint16_t) feat_config[page_byte_idx++]; + if (page_byte_idx < max_len) + { + msb = ((uint16_t) feat_config[page_byte_idx++] << 8); + } + + lsb_msb = lsb | msb; + + /* Get parameters 1 to 25 */ + step_count_params[param_idx] = lsb_msb & BMI2_STEP_COUNT_PARAMS_MASK; + + /* Increment to next parameter */ + param_idx++; + } + } + } + } + else + { + rslt = BMI2_E_INVALID_SENSOR; + } + + return rslt; +} + +/*! + * @brief This internal API gets step counter/detector/activity configurations. + */ +static int8_t get_step_config(struct bmi2_step_config *config, struct bmi2_dev *dev) +{ + /* Variable to define error */ + int8_t rslt; + + /* Array to define the feature configuration */ + uint8_t feat_config[BMI2_FEAT_SIZE_IN_BYTES] = { 0 }; + + /* Variable to define the array offset */ + uint8_t idx = 0; + + /* Variable to define LSB */ + uint16_t lsb = 0; + + /* Variable to define MSB */ + uint16_t msb = 0; + + /* Variable to define a word */ + uint16_t lsb_msb = 0; + + /* Variable to set flag */ + uint8_t feat_found; + + /* Initialize feature configuration for step counter */ + struct bmi2_feature_config step_count_config = { 0, 0, 0 }; + + /* Search for step counter 4 feature and extract its configuration details */ + feat_found = bmi2_extract_input_feat_config(&step_count_config, BMI2_STEP_COUNTER, dev); + if (feat_found) + { + /* Get the configuration from the page where step counter 4 parameter resides */ + rslt = bmi2_get_feat_config(step_count_config.page, feat_config, dev); + if (rslt == BMI2_OK) + { + /* Define the offset for feature enable for step counter/detector/activity */ + idx = step_count_config.start_addr; + + /* Get word to calculate water-mark level and reset counter */ + lsb = (uint16_t) feat_config[idx++]; + msb = ((uint16_t) feat_config[idx++] << 8); + lsb_msb = lsb | msb; + + /* Get water-mark level */ + config->watermark_level = lsb_msb & BMI2_STEP_COUNT_WM_LEVEL_MASK; + + /* Get reset counter */ + config->reset_counter = (lsb_msb & BMI2_STEP_COUNT_RST_CNT_MASK) >> BMI2_STEP_COUNT_RST_CNT_POS; + + /* Get word to calculate output configuration of step detector and activity */ + lsb = (uint16_t) feat_config[idx++]; + msb = ((uint16_t) feat_config[idx++] << 8); + lsb_msb = lsb | msb; + + config->step_buffer_size = (lsb_msb & BMI2_STEP_BUFFER_SIZE_MASK) >> BMI2_STEP_BUFFER_SIZE_POS; + } + } + else + { + rslt = BMI2_E_INVALID_SENSOR; + } + + return rslt; +} + +/*! + * @brief This internal API gets wrist gesture configurations like wearable-arm, + * and output-configuration. + */ +static int8_t get_wrist_gest_config(struct bmi2_wrist_gest_config *config, struct bmi2_dev *dev) +{ + /* Variable to define error */ + int8_t rslt; + + /* Array to define the feature configuration */ + uint8_t feat_config[BMI2_FEAT_SIZE_IN_BYTES] = { 0 }; + + /* Variable to define the array offset */ + uint8_t idx = 0; + + /* Variable to set flag */ + uint8_t feat_found; + + /* Initialize feature configuration for wrist gesture */ + struct bmi2_feature_config wrist_gest_config = { 0, 0, 0 }; + + /* Copy the feature configuration address to a local pointer */ + uint16_t *data_p = (uint16_t *) (void *)feat_config; + + /* Search for wrist gesture feature and extract its configuration details */ + feat_found = bmi2_extract_input_feat_config(&wrist_gest_config, BMI2_WRIST_GESTURE, dev); + if (feat_found) + { + /* Get the configuration from the page where wrist gesture feature resides */ + rslt = bmi2_get_feat_config(wrist_gest_config.page, feat_config, dev); + if (rslt == BMI2_OK) + { + /* Define the offset in bytes for wrist gesture select */ + idx = wrist_gest_config.start_addr; + + /* Get offset in words since all the features are set in words length */ + idx = idx / 2; + + /* Get wearable arm */ + config->wearable_arm = (*(data_p + idx) & BMI2_WRIST_GEST_WEAR_ARM_MASK) >> BMI2_WRIST_GEST_WEAR_ARM_POS; + + /* Increment the offset by 1 word to get min_flick_peak */ + idx++; + config->min_flick_peak = *(data_p + idx); + + /* Increment the offset by 1 word to get min_flick_samples */ + idx++; + config->min_flick_samples = *(data_p + idx); + + /* Increment the offset by 1 word to get max_duration */ + idx++; + config->max_duration = *(data_p + idx); + } + } + else + { + rslt = BMI2_E_INVALID_SENSOR; + } + + return rslt; +} + +/*! + * @brief This internal API gets wrist wear wake-up configurations like + * output-configuration. + */ +static int8_t get_wrist_wear_wake_up_config(struct bmi2_wrist_wear_wake_up_config *config, struct bmi2_dev *dev) +{ + /* Variable to define error */ + int8_t rslt; + + /* Array to define the feature configuration */ + uint8_t feat_config[BMI2_FEAT_SIZE_IN_BYTES] = { 0 }; + + /* Variable to define the array offset */ + uint8_t idx = 0; + + /* Variable to set flag */ + uint8_t feat_found; + + /* Initialize feature configuration for wrist wear wake-up */ + struct bmi2_feature_config wrist_wake_up_config = { 0, 0, 0 }; + + /* Copy the feature configuration address to a local pointer */ + uint16_t *data_p = (uint16_t *) (void *)feat_config; + + /* Search for wrist wear wake-up feature and extract its configuration details */ + feat_found = bmi2_extract_input_feat_config(&wrist_wake_up_config, BMI2_WRIST_WEAR_WAKE_UP, dev); + if (feat_found) + { + /* Get the configuration from the page where wrist wear wake-up feature resides */ + rslt = bmi2_get_feat_config(wrist_wake_up_config.page, feat_config, dev); + if (rslt == BMI2_OK) + { + /* Define the offset in bytes for wrist wear wake-up select */ + idx = wrist_wake_up_config.start_addr; + + /* Get offset in words since all the features are set in words length */ + idx = idx / 2; + + config->min_angle_focus = *(data_p + idx); + + /* Increment the offset value by 1 word to get min_angle_nonfocus */ + idx++; + config->min_angle_nonfocus = *(data_p + idx); + + /* Increment the offset value by 1 word to get max_tilt_lr */ + idx++; + config->max_tilt_lr = *(data_p + idx); + + /* Increment the offset value by 1 word to get max_tilt_ll */ + idx++; + config->max_tilt_ll = *(data_p + idx); + + /* Increment the offset value by 1 word to get max_tilt_pd */ + idx++; + config->max_tilt_pd = *(data_p + idx); + + /* Increment the offset value by 1 word to get max_tilt_pu */ + idx++; + config->max_tilt_pu = *(data_p + idx); + + } + } + else + { + rslt = BMI2_E_INVALID_SENSOR; + } + + return rslt; +} + +/*! + * @brief This internal API gets the output values of the wrist gesture. + */ +static int8_t get_wrist_gest_status(uint8_t *wrist_gest, struct bmi2_dev *dev) +{ + /* Variable to define error */ + int8_t rslt; + + /* Array to define the feature configuration */ + uint8_t feat_config[BMI2_FEAT_SIZE_IN_BYTES] = { 0 }; + + /* Variables to define index */ + uint8_t idx = 0; + + /* Variable to set flag */ + uint8_t feat_found; + + /* Initialize feature output for wrist gesture */ + struct bmi2_feature_config wrist_gest_out_config = { 0, 0, 0 }; + + /* Search for wrist gesture feature and extract its configuration details */ + feat_found = extract_output_feat_config(&wrist_gest_out_config, BMI2_WRIST_GESTURE, dev); + if (feat_found) + { + /* Get the feature output configuration for wrist gesture */ + rslt = bmi2_get_feat_config(wrist_gest_out_config.page, feat_config, dev); + if (rslt == BMI2_OK) + { + /* Define the offset in bytes for wrist gesture output */ + idx = wrist_gest_out_config.start_addr; + + /* Get the wrist gesture output */ + *wrist_gest = feat_config[idx]; + } + } + else + { + rslt = BMI2_E_INVALID_SENSOR; + } + + return rslt; +} + +/*! + * @brief This internal API gets the output values of step counter. + */ +static int8_t get_step_counter_output(uint32_t *step_count, struct bmi2_dev *dev) +{ + /* Variable to define error */ + int8_t rslt; + + /* Array to define the feature configuration */ + uint8_t feat_config[BMI2_FEAT_SIZE_IN_BYTES] = { 0 }; + + /* Variables to define index */ + uint8_t idx = 0; + + /* Variable to set flag */ + uint8_t feat_found; + + /* Initialize feature output for step counter */ + struct bmi2_feature_config step_cnt_out_config = { 0, 0, 0 }; + + /* Search for step counter output feature and extract its configuration details */ + feat_found = extract_output_feat_config(&step_cnt_out_config, BMI2_STEP_COUNTER, dev); + if (feat_found) + { + /* Get the feature output configuration for step-counter */ + rslt = bmi2_get_feat_config(step_cnt_out_config.page, feat_config, dev); + if (rslt == BMI2_OK) + { + /* Define the offset in bytes for step counter output */ + idx = step_cnt_out_config.start_addr; + + /* Get the step counter output in 4 bytes */ + *step_count = (uint32_t) feat_config[idx++]; + *step_count |= ((uint32_t) feat_config[idx++] << 8); + *step_count |= ((uint32_t) feat_config[idx++] << 16); + *step_count |= ((uint32_t) feat_config[idx++] << 24); + } + } + else + { + rslt = BMI2_E_INVALID_SENSOR; + } + + return rslt; +} + +/*! + * @brief This internal API gets the error status related to NVM. + */ +static int8_t get_nvm_error_status(struct bmi2_nvm_err_status *nvm_err_stat, struct bmi2_dev *dev) +{ + /* Variable to define error */ + int8_t rslt; + + /* Array to define the feature configuration */ + uint8_t feat_config[BMI2_FEAT_SIZE_IN_BYTES] = { 0 }; + + /* Variables to define index */ + uint8_t idx = 0; + + /* Variable to set flag */ + uint8_t feat_found; + + /* Initialize feature output for NVM error status */ + struct bmi2_feature_config nvm_err_cfg = { 0, 0, 0 }; + + /* Search for NVM error status feature and extract its configuration details */ + feat_found = extract_output_feat_config(&nvm_err_cfg, BMI2_NVM_STATUS, dev); + if (feat_found) + { + /* Get the feature output configuration for NVM error status */ + rslt = bmi2_get_feat_config(nvm_err_cfg.page, feat_config, dev); + if (rslt == BMI2_OK) + { + /* Define the offset in bytes for NVM error status */ + idx = nvm_err_cfg.start_addr; + + /* Increment index to get the error status */ + idx++; + + /* Error when NVM load action fails */ + nvm_err_stat->load_error = BMI2_GET_BIT_POS0(feat_config[idx], BMI2_NVM_LOAD_ERR_STATUS); + + /* Error when NVM program action fails */ + nvm_err_stat->prog_error = BMI2_GET_BITS(feat_config[idx], BMI2_NVM_PROG_ERR_STATUS); + + /* Error when NVM erase action fails */ + nvm_err_stat->erase_error = BMI2_GET_BITS(feat_config[idx], BMI2_NVM_ERASE_ERR_STATUS); + + /* Error when NVM program limit is exceeded */ + nvm_err_stat->exceed_error = BMI2_GET_BITS(feat_config[idx], BMI2_NVM_END_EXCEED_STATUS); + + /* Error when NVM privilege mode is not acquired */ + nvm_err_stat->privil_error = BMI2_GET_BITS(feat_config[idx], BMI2_NVM_PRIV_ERR_STATUS); + } + } + else + { + rslt = BMI2_E_INVALID_SENSOR; + } + + return rslt; +} + +/*! + * @brief This internal API is used to get enable status of gyroscope user gain + * update. + */ +static int8_t get_user_gain_upd_status(uint8_t *status, struct bmi2_dev *dev) +{ + /* Variable to define error */ + int8_t rslt = BMI2_OK; + + /* Array to define the feature configuration */ + uint8_t feat_config[BMI2_FEAT_SIZE_IN_BYTES] = { 0 }; + + /* Variable to define the array offset */ + uint8_t idx = 0; + + /* Variable to set flag */ + uint8_t feat_found; + + /* Variable to check APS status */ + uint8_t aps_stat = 0; + + /* Initialize feature configuration for gyroscope user gain */ + struct bmi2_feature_config gyr_user_gain_cfg = { 0, 0, 0 }; + + /* Search for user gain feature and extract its configuration details */ + feat_found = bmi2_extract_input_feat_config(&gyr_user_gain_cfg, BMI2_GYRO_GAIN_UPDATE, dev); + if (feat_found) + { + /* Disable advance power save */ + aps_stat = dev->aps_status; + if (aps_stat == BMI2_ENABLE) + { + rslt = bmi2_set_adv_power_save(BMI2_DISABLE, dev); + } + + if (rslt == BMI2_OK) + { + /* Get the configuration from the page where user gain feature resides */ + rslt = bmi2_get_feat_config(gyr_user_gain_cfg.page, feat_config, dev); + if (rslt == BMI2_OK) + { + /* Define the offset for enable/disable of user gain */ + idx = gyr_user_gain_cfg.start_addr + BMI2_GYR_USER_GAIN_FEAT_EN_OFFSET; + + /* Set the feature enable status */ + *status = BMI2_GET_BITS(feat_config[idx], BMI2_GYR_USER_GAIN_FEAT_EN); + } + } + } + else + { + rslt = BMI2_E_INVALID_SENSOR; + } + + /* Enable Advance power save if disabled while configuring and not when already disabled */ + if ((rslt == BMI2_OK) && (aps_stat == BMI2_ENABLE)) + { + rslt = bmi2_set_adv_power_save(BMI2_ENABLE, dev); + } + + return rslt; +} + +/*! + * @brief This internal API gets the output values of step activity. + */ +static int8_t get_step_activity_output(uint8_t *step_act, struct bmi2_dev *dev) +{ + /* Variable to define error */ + int8_t rslt; + + /* Array to define the feature configuration */ + uint8_t feat_config[BMI2_FEAT_SIZE_IN_BYTES] = { 0 }; + + /* Variables to define index */ + uint8_t idx = 0; + + /* Variable to set flag */ + uint8_t feat_found; + + /* Initialize feature output for step activity */ + struct bmi2_feature_config step_act_out_config = { 0, 0, 0 }; + + /* Search for step activity output feature and extract its configuration details */ + feat_found = extract_output_feat_config(&step_act_out_config, BMI2_STEP_ACTIVITY, dev); + if (feat_found) + { + /* Get the feature output configuration for step-activity */ + rslt = bmi2_get_feat_config(step_act_out_config.page, feat_config, dev); + if (rslt == BMI2_OK) + { + /* Define the offset in bytes for step activity output */ + idx = step_act_out_config.start_addr; + + /* Get the step activity output */ + *step_act = feat_config[idx]; + } + } + else + { + rslt = BMI2_E_INVALID_SENSOR; + } + + return rslt; +} + +/*! + * @brief This internal API gets the error status related to virtual frames. + */ +static int8_t get_vfrm_error_status(struct bmi2_vfrm_err_status *vfrm_err_stat, struct bmi2_dev *dev) +{ + /* Variable to define error */ + int8_t rslt; + + /* Array to define the feature configuration */ + uint8_t feat_config[BMI2_FEAT_SIZE_IN_BYTES] = { 0 }; + + /* Variables to define index */ + uint8_t idx = 0; + + /* Variable to set flag */ + uint8_t feat_found; + + /* Initialize feature output for VFRM error status */ + struct bmi2_feature_config vfrm_err_cfg = { 0, 0, 0 }; + + /* Search for VFRM error status feature and extract its configuration details */ + feat_found = extract_output_feat_config(&vfrm_err_cfg, BMI2_VFRM_STATUS, dev); + if (feat_found) + { + /* Get the feature output configuration for VFRM error status */ + rslt = bmi2_get_feat_config(vfrm_err_cfg.page, feat_config, dev); + if (rslt == BMI2_OK) + { + /* Define the offset in bytes for VFRM error status */ + idx = vfrm_err_cfg.start_addr; + + /* Increment index to get the error status */ + idx++; + + /* Internal error while acquiring lock for FIFO */ + vfrm_err_stat->lock_error = BMI2_GET_BITS(feat_config[idx], BMI2_VFRM_LOCK_ERR_STATUS); + + /* Internal error while writing byte into FIFO */ + vfrm_err_stat->write_error = BMI2_GET_BITS(feat_config[idx], BMI2_VFRM_WRITE_ERR_STATUS); + + /* Internal error while writing into FIFO */ + vfrm_err_stat->fatal_error = BMI2_GET_BITS(feat_config[idx], BMI2_VFRM_FATAL_ERR_STATUS); + } + } + else + { + rslt = BMI2_E_INVALID_SENSOR; + } + + return rslt; +} + +/*! + * @brief This internal API enables/disables compensation of the gain defined + * in the GAIN register. + */ +static int8_t enable_gyro_gain(uint8_t enable, struct bmi2_dev *dev) +{ + /* Variable to define error */ + int8_t rslt; + + /* Variable to define register data */ + uint8_t reg_data = 0; + + rslt = bmi2_get_regs(BMI2_GYR_OFF_COMP_6_ADDR, ®_data, 1, dev); + if (rslt == BMI2_OK) + { + reg_data = BMI2_SET_BITS(reg_data, BMI2_GYR_GAIN_EN, enable); + rslt = bmi2_set_regs(BMI2_GYR_OFF_COMP_6_ADDR, ®_data, 1, dev); + } + + return rslt; +} + +/*! + * @brief This internal API is used to extract the output feature configuration + * details from the look-up table. + */ +static uint8_t extract_output_feat_config(struct bmi2_feature_config *feat_output, + uint8_t type, + const struct bmi2_dev *dev) +{ + /* Variable to define loop */ + uint8_t loop = 0; + + /* Variable to set flag */ + uint8_t feat_found = BMI2_FALSE; + + /* Search for the output feature from the output configuration array */ + while (loop < dev->out_sens) + { + if (dev->feat_output[loop].type == type) + { + *feat_output = dev->feat_output[loop]; + feat_found = BMI2_TRUE; + break; + } + + loop++; + } + + /* Return flag */ + return feat_found; +} diff --git a/bmi270.h b/bmi270.h index 356749c..968366a 100644 --- a/bmi270.h +++ b/bmi270.h @@ -1,40 +1,40 @@ /** - * 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 bmi270.h - * @date 2020-06-05 - * @version v2.53.2 - * - */ +* 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 bmi270.h +* @date 2020-11-04 +* @version v2.63.1 +* +*/ /** * \ingroup bmi2xy @@ -65,6 +65,7 @@ extern "C" { #define BMI270_CHIP_ID UINT8_C(0x24) /*! @name BMI270 feature input start addresses */ +#define BMI270_CONFIG_ID_STRT_ADDR UINT8_C(0x00) #define BMI270_MAX_BURST_LEN_STRT_ADDR UINT8_C(0x02) #define BMI270_CRT_GYRO_SELF_TEST_STRT_ADDR UINT8_C(0x03) #define BMI270_ABORT_STRT_ADDR UINT8_C(0x03) @@ -92,7 +93,7 @@ extern "C" { #define BMI270_MAX_PAGE_NUM UINT8_C(8) /*! @name Defines maximum number of feature input configurations */ -#define BMI270_MAX_FEAT_IN UINT8_C(16) +#define BMI270_MAX_FEAT_IN UINT8_C(17) /*! @name Defines maximum number of feature outputs */ #define BMI270_MAX_FEAT_OUT UINT8_C(7) @@ -106,6 +107,19 @@ extern "C" { #define BMI270_NO_MOT_STATUS_MASK UINT8_C(0x20) #define BMI270_ANY_MOT_STATUS_MASK UINT8_C(0x40) +/*! @name Mask definitions for feature interrupt mapping bits */ +#define BMI270_INT_SIG_MOT_MASK UINT8_C(0x01) +#define BMI270_INT_STEP_COUNTER_MASK UINT8_C(0x02) +#define BMI270_INT_STEP_DETECTOR_MASK UINT8_C(0x02) +#define BMI270_INT_STEP_ACT_MASK UINT8_C(0x04) +#define BMI270_INT_WRIST_WEAR_WAKEUP_MASK UINT8_C(0x08) +#define BMI270_INT_WRIST_GEST_MASK UINT8_C(0x10) +#define BMI270_INT_NO_MOT_MASK UINT8_C(0x20) +#define BMI270_INT_ANY_MOT_MASK UINT8_C(0x40) + +/*! @name Defines maximum number of feature interrupts */ +#define BMI270_MAX_INT_MAP UINT8_C(8) + /***************************************************************************/ /*! BMI270 User Interface function prototypes @@ -133,14 +147,271 @@ extern "C" { * @param[in, out] dev : Structure instance of bmi2_dev. * * @return Result of API execution status - * - * @retval BMI2_OK - Success - * @retval BMI2_E_NULL_PTR - Error: Null pointer error - * @retval BMI2_E_COM_FAIL - Error: Communication fail - * @retval BMI2_E_DEV_NOT_FOUND - Invalid device + * @retval 0 -> Success + * @retval < 0 -> Fail */ int8_t bmi270_init(struct bmi2_dev *dev); +/** + * \ingroup bmi270 + * \defgroup bmi270ApiSensor Feature Set + * @brief Enable / Disable features of the sensor + */ + +/*! + * \ingroup bmi270ApiSensor + * \page bmi270_api_bmi270_sensor_enable bmi270_sensor_enable + * \code + * int8_t bmi270_sensor_enable(const uint8_t *sens_list, uint8_t n_sens, struct bmi2_dev *dev); + * \endcode + * @details This API selects the sensors/features to be enabled. + * + * @param[in] sens_list : Pointer to select the sensor/feature. + * @param[in] n_sens : Number of sensors selected. + * @param[in, out] dev : Structure instance of bmi2_dev. + * + * @note Sensors/features that can be enabled. + * + *@verbatim + * sens_list | Values + * ----------------------------|----------- + * BMI2_ACCEL | 0 + * BMI2_GYRO | 1 + * BMI2_AUX | 2 + * BMI2_SIG_MOTION | 3 + * BMI2_ANY_MOTION | 4 + * BMI2_NO_MOTION | 5 + * BMI2_STEP_DETECTOR | 6 + * BMI2_STEP_COUNTER | 7 + * BMI2_STEP_ACTIVITY | 8 + * BMI2_GYRO_GAIN_UPDATE | 9 + * BMI2_WRIST_GESTURE | 19 + * BMI2_WRIST_WEAR_WAKE_UP | 20 + * BMI2_GYRO_SELF_OFF | 33 + *@endverbatim + * + * @note : + * example uint8_t sens_list[2] = {BMI2_ACCEL, BMI2_GYRO}; + * uint8_t n_sens = 2; + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +int8_t bmi270_sensor_enable(const uint8_t *sens_list, uint8_t n_sens, struct bmi2_dev *dev); + +/*! + * \ingroup bmi270ApiSensor + * \page bmi270_api_bmi270_sensor_disable bmi270_sensor_disable + * \code + * int8_t bmi270_sensor_disable(const uint8_t *sens_list, uint8_t n_sens, struct bmi2_dev *dev); + * \endcode + * @details This API selects the sensors/features to be disabled. + * + * @param[in] sens_list : Pointer to select the sensor/feature. + * @param[in] n_sens : Number of sensors selected. + * @param[in, out] dev : Structure instance of bmi2_dev. + * + * @note Sensors/features that can be disabled. + * + *@verbatim + * sens_list | Values + * ----------------------------|----------- + * BMI2_ACCEL | 0 + * BMI2_GYRO | 1 + * BMI2_AUX | 2 + * BMI2_SIG_MOTION | 3 + * BMI2_ANY_MOTION | 4 + * BMI2_NO_MOTION | 5 + * BMI2_STEP_DETECTOR | 6 + * BMI2_STEP_COUNTER | 7 + * BMI2_STEP_ACTIVITY | 8 + * BMI2_GYRO_GAIN_UPDATE | 9 + * BMI2_WRIST_GESTURE | 19 + * BMI2_WRIST_WEAR_WAKE_UP | 20 + * BMI2_GYRO_SELF_OFF | 33 + *@endverbatim + * + * @note : + * example uint8_t sens_list[2] = {BMI2_ACCEL, BMI2_GYRO}; + * uint8_t n_sens = 2; + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +int8_t bmi270_sensor_disable(const uint8_t *sens_list, uint8_t n_sens, struct bmi2_dev *dev); + +/** + * \ingroup bmi270 + * \defgroup bmi270ApiSensorC Sensor Configuration + * @brief Enable / Disable feature configuration of the sensor + */ + +/*! + * \ingroup bmi270ApiSensorC + * \page bmi270_api_bmi270_set_sensor_config bmi270_set_sensor_config + * \code + * int8_t bmi270_set_sensor_config(struct bmi2_sens_config *sens_cfg, uint8_t n_sens, struct bmi2_dev *dev); + * \endcode + * @details This API sets the sensor/feature configuration. + * + * @param[in] sens_cfg : Structure instance of bmi2_sens_config. + * @param[in] n_sens : Number of sensors selected. + * @param[in, out] dev : Structure instance of bmi2_dev. + * + * @note Sensors/features that can be configured + * + *@verbatim + * sens_list | Values + * ----------------------------|----------- + * BMI2_SIG_MOTION | 3 + * BMI2_ANY_MOTION | 4 + * BMI2_NO_MOTION | 5 + * BMI2_STEP_DETECTOR | 6 + * BMI2_STEP_COUNTER | 7 + * BMI2_STEP_ACTIVITY | 8 + * BMI2_WRIST_GESTURE | 19 + * BMI2_WRIST_WEAR_WAKE_UP | 20 + * BMI2_STEP_COUNTER_PARAMS | 28 + *@endverbatim + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +int8_t bmi270_set_sensor_config(struct bmi2_sens_config *sens_cfg, uint8_t n_sens, struct bmi2_dev *dev); + +/*! + * \ingroup bmi270ApiSensorC + * \page bmi270_api_bmi270_get_sensor_config bmi270_get_sensor_config + * \code + * int8_t bmi270_get_sensor_config(struct bmi2_sens_config *sens_cfg, uint8_t n_sens, struct bmi2_dev *dev); + * \endcode + * @details This API gets the sensor/feature configuration. + * + * @param[in] sens_cfg : Structure instance of bmi2_sens_config. + * @param[in] n_sens : Number of sensors selected. + * @param[in, out] dev : Structure instance of bmi2_dev. + * + * @note Sensors/features whose configurations can be read. + * + *@verbatim + * sens_list | Values + * ----------------------------|----------- + * BMI2_SIG_MOTION | 3 + * BMI2_ANY_MOTION | 4 + * BMI2_NO_MOTION | 5 + * BMI2_STEP_DETECTOR | 6 + * BMI2_STEP_COUNTER | 7 + * BMI2_STEP_ACTIVITY | 8 + * BMI2_WRIST_GESTURE | 19 + * BMI2_WRIST_WEAR_WAKE_UP | 20 + * BMI2_STEP_COUNTER_PARAMS | 28 + *@endverbatim + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +int8_t bmi270_get_sensor_config(struct bmi2_sens_config *sens_cfg, uint8_t n_sens, struct bmi2_dev *dev); + +/** + * \ingroup bmi270 + * \defgroup bmi270ApiSensorD Sensor Data + * @brief Get sensor data + */ + +/*! + * \ingroup bmi270ApiSensorD + * \page bmi270_api_bmi270_get_sensor_data bmi270_get_sensor_data + * \code + * int8_t bmi270_get_sensor_data(struct bmi2_sensor_data *sensor_data, uint8_t n_sens, struct bmi2_dev *dev); + * \endcode + * @details This API gets the sensor/feature data for accelerometer, gyroscope, + * auxiliary sensor, step counter, high-g, gyroscope user-gain update, + * orientation, gyroscope cross sensitivity and error status for NVM and VFRM. + * + * @param[out] sensor_data : Structure instance of bmi2_sensor_data. + * @param[in] n_sens : Number of sensors selected. + * @param[in] dev : Structure instance of bmi2_dev. + * + * @note Sensors/features whose data can be read + * + *@verbatim + * sens_list | Values + * ----------------------------|----------- + * BMI2_STEP_COUNTER | 7 + * BMI2_STEP_ACTIVITY | 8 + * BMI2_WRIST_GESTURE | 19 + * BMI2_NVM_STATUS | 38 + * BMI2_VFRM_STATUS | 39 + *@endverbatim + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +int8_t bmi270_get_sensor_data(struct bmi2_sensor_data *sensor_data, uint8_t n_sens, struct bmi2_dev *dev); + +/** + * \ingroup bmi270 + * \defgroup bmi270ApiGyroUG Gyro User Gain + * @brief Set / Get Gyro User Gain of the sensor + */ + +/*! + * \ingroup bmi270ApiGyroUG + * \page bmi270_api_bmi270_update_gyro_user_gain bmi270_update_gyro_user_gain + * \code + * int8_t bmi270_update_gyro_user_gain(const struct bmi2_gyro_user_gain_config *user_gain, struct bmi2_dev *dev); + * \endcode + * @details This API updates the gyroscope user-gain. + * + * @param[in] user_gain : Structure that stores user-gain configurations. + * @param[in] dev : Structure instance of bmi2_dev. + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +int8_t bmi270_update_gyro_user_gain(const struct bmi2_gyro_user_gain_config *user_gain, struct bmi2_dev *dev); + +/*! + * \ingroup bmi270ApiGyroUG + * \page bmi270_api_bmi270_read_gyro_user_gain bmi270_read_gyro_user_gain + * \code + * int8_t bmi270_read_gyro_user_gain(struct bmi2_gyro_user_gain_data *gyr_usr_gain, const struct bmi2_dev *dev); + * \endcode + * @details This API reads the compensated gyroscope user-gain values. + * + * @param[out] gyr_usr_gain : Structure that stores gain values. + * @param[in] dev : Structure instance of bmi2_dev. + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +int8_t bmi270_read_gyro_user_gain(struct bmi2_gyro_user_gain_data *gyr_usr_gain, struct bmi2_dev *dev); + +/*! + * \ingroup bmi270ApiInt + * \page bmi270_api_bmi270_map_feat_int bmi270_map_feat_int + * \code + * int8_t bmi270_map_feat_int(const struct bmi2_sens_int_config *sens_int, uint8_t n_sens, struct bmi2_dev *dev) + * \endcode + * @details This API maps/unmaps feature interrupts to that of interrupt pins. + * + * @param[in] sens_int : Structure instance of bmi2_sens_int_config. + * @param[in] n_sens : Number of interrupts to be mapped. + * @param[in] dev : Structure instance of bmi2_dev. + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +int8_t bmi270_map_feat_int(const struct bmi2_sens_int_config *sens_int, uint8_t n_sens, struct bmi2_dev *dev); + /******************************************************************************/ /*! @name C++ Guard Macros */ /******************************************************************************/ diff --git a/bmi270_context.c b/bmi270_context.c index 7ec5a14..a6ea2d8 100644 --- a/bmi270_context.c +++ b/bmi270_context.c @@ -1,40 +1,40 @@ /** - * 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 bmi270_context.c - * @date 2020-06-05 - * @version v2.53.2 - * - */ +* 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 bmi270_context.c +* @date 2020-11-04 +* @version v2.63.1 +* +*/ /***************************************************************************/ @@ -487,6 +487,7 @@ const uint8_t bmi270_context_config_file[] = { * BMI270_CONTEXT */ const struct bmi2_feature_config bmi270_context_feat_in[BMI270_CONTEXT_MAX_FEAT_IN] = { + { .type = BMI2_CONFIG_ID, .page = BMI2_PAGE_4, .start_addr = BMI270_CONTEXT_CONFIG_ID_STRT_ADDR }, { .type = BMI2_STEP_COUNTER_PARAMS, .page = BMI2_PAGE_1, .start_addr = BMI270_CONTEXT_STEP_CNT_1_STRT_ADDR }, { .type = BMI2_STEP_DETECTOR, .page = BMI2_PAGE_4, .start_addr = BMI270_CONTEXT_STEP_CNT_4_STRT_ADDR }, { .type = BMI2_STEP_COUNTER, .page = BMI2_PAGE_4, .start_addr = BMI270_CONTEXT_STEP_CNT_4_STRT_ADDR }, @@ -508,6 +509,12 @@ const struct bmi2_feature_config bmi270_context_feat_out[BMI270_CONTEXT_MAX_FEAT { .type = BMI2_VFRM_STATUS, .page = BMI2_PAGE_0, .start_addr = BMI270_CONTEXT_NVM_VFRM_OUT_STRT_ADDR } }; +/*! @name Global array that stores the feature interrupts of BMI270_CONTEXT */ +struct bmi2_map_int bmi270_c_map_int[BMI270_C_MAX_INT_MAP] = { + { .type = BMI2_STEP_COUNTER, .sens_map_int = BMI270_C_INT_STEP_COUNTER_MASK }, + { .type = BMI2_STEP_DETECTOR, .sens_map_int = BMI270_C_INT_STEP_DETECTOR_MASK }, +}; + /******************************************************************************/ /*! Local Function Prototypes @@ -520,10 +527,328 @@ const struct bmi2_feature_config bmi270_context_feat_out[BMI270_CONTEXT_MAX_FEAT * @param[in] dev : Structure instance of bmi2_dev. * * @return Result of API execution status - * @retval zero -> Success / +ve value -> Warning / -ve value -> Error + * @retval 0 -> Success + * @retval < 0 -> Fail */ static int8_t null_ptr_check(const struct bmi2_dev *dev); +/*! + * @brief This internal API enables the selected sensor/features. + * + * @param[in] sensor_sel : Selects the desired sensor. + * @param[in, out] dev : Structure instance of bmi2_dev. + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +static int8_t sensor_enable(uint64_t sensor_sel, struct bmi2_dev *dev); + +/*! + * @brief This internal API disables the selected sensor/features. + * + * @param[in] sensor_sel : Selects the desired sensor. + * @param[in, out] dev : Structure instance of bmi2_dev. + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +static int8_t sensor_disable(uint64_t sensor_sel, struct bmi2_dev *dev); + +/*! + * @brief This internal API selects the sensors/features to be enabled or + * disabled. + * + * @param[in] sens_list : Pointer to select the sensor. + * @param[in] n_sens : Number of sensors selected. + * @param[out] sensor_sel : Gets the selected sensor. + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +static int8_t select_sensor(const uint8_t *sens_list, uint8_t n_sens, uint64_t *sensor_sel); + +/*! + * @brief This internal API is used to enable/disable step detector feature. + * + * @param[in] dev : Structure instance of bmi2_dev. + * @param[in] enable : Enables/Disables step-detector. + * + * Enable | Description + * -------------|--------------- + * BMI2_DISABLE | Disables step detector + * BMI2_ENABLE | Enables step detector + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +static int8_t set_step_detector(uint8_t enable, struct bmi2_dev *dev); + +/*! + * @brief This internal API is used to enable/disable step counter feature. + * + * @param[in] dev : Structure instance of bmi2_dev. + * @param[in] enable : Enables/Disables step counter. + * + * Enable | Description + * -------------|--------------- + * BMI2_DISABLE | Disables step counter + * BMI2_ENABLE | Enables step counter + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +static int8_t set_step_counter(uint8_t enable, struct bmi2_dev *dev); + +/*! + * @brief This internal API is used to enable/disable gyroscope user gain + * feature. + * + * @param[in] dev : Structure instance of bmi2_dev. + * @param[in] enable : Enables/Disables gyroscope user gain. + * + * Enable | Description + * -------------|--------------- + * BMI2_DISABLE | Disables gyroscope user gain + * BMI2_ENABLE | Enables gyroscope user gain + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +static int8_t set_gyro_user_gain(uint8_t enable, struct bmi2_dev *dev); + +/*! + * @brief This internal API enables/disables the activity recognition feature. + * + * @param[in] enable : Enables/Disables activity recognition. + * @param[in] dev : Structure instance of bmi2_dev. + * + * enable | Description + * -------------|--------------- + * BMI2_ENABLE | Enables activity recognition. + * BMI2_DISABLE | Disables activity recognition. + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +static int8_t set_act_recog(uint8_t enable, struct bmi2_dev *dev); + +/*! + * @brief This internal API sets step counter parameter configurations. + * + * @param[in] step_count_params : Array that stores parameters 1 to 25. + * @param[in] dev : Structure instance of bmi2_dev. + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +static int8_t set_step_count_params_config(const uint16_t *step_count_params, struct bmi2_dev *dev); + +/*! + * @brief This internal API sets step counter/detector/activity configurations. + * + * @param[in] config : Structure instance of bmi2_step_config. + * @param[in] dev : Structure instance of bmi2_dev. + * + *--------------------------------------------------------------------------- + * bmi2_step_config | + * Structure parameters | Description + *--------------------------|-------------------------------------------------- + * | The Step-counter will trigger output every time + * | the number of steps are counted. Holds implicitly + * water-mark level | a 20x factor, so the range is 0 to 10230, + * | with resolution of 20 steps. + * -------------------------|--------------------------------------------------- + * reset counter | Flag to reset the counted steps. + * -------------------------|--------------------------------------------------- + * @endverbatim + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +static int8_t set_step_config(const struct bmi2_step_config *config, struct bmi2_dev *dev); + +/*! + * @brief This internal API gets step counter parameter configurations. + * + * @param[in] step_count_params : Array that stores parameters 1 to 25. + * @param[in] dev : Structure instance of bmi2_dev. + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +static int8_t get_step_count_params_config(uint16_t *step_count_params, struct bmi2_dev *dev); + +/*! + * @brief This internal API gets step counter/detector/activity configurations. + * + * @param[out] config : Structure instance of bmi2_step_config. + * @param[in] dev : Structure instance of bmi2_dev. + * + * @verbatim + *---------------------------------------------------------------------------- + * bmi2_step_config | + * Structure parameters | Description + *--------------------------|-------------------------------------------------- + * | The Step-counter will trigger output every time + * | the number of steps are counted. Holds implicitly + * water-mark level | a 20x factor, so the range is 0 to 10230, + * | with resolution of 20 steps. + * -------------------------|--------------------------------------------------- + * reset counter | Flag to reset the counted steps. + * -------------------------|--------------------------------------------------- + * @endverbatim + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +static int8_t get_step_config(struct bmi2_step_config *config, struct bmi2_dev *dev); + +/*! + * @brief This internal API is used to parse and store the activity recognition + * output from the FIFO data. + * + * @param[out] act_recog : Structure to retrieve output of activity + * recognition frame. + * @param[in] data_index : Index of the FIFO data which contains + * activity recognition frame. + * @param[out] fifo : Structure instance of bmi2_dev. + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +static int8_t unpack_act_recog_output(struct bmi2_act_recog_output *act_recog, + uint16_t *data_index, + const struct bmi2_fifo_frame *fifo); + +/*! + * @brief This internal API gets the output values of step counter. + * + * @param[out] step_count : Pointer to the stored step counter data. + * @param[in] dev : Structure instance of bmi2_dev. + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +static int8_t get_step_counter_output(uint32_t *step_count, struct bmi2_dev *dev); + +/*! + * @brief This internal API gets the error status related to NVM. + * + * @param[out] nvm_err_stat : Stores the NVM error status. + * @param[in] dev : Structure instance of bmi2_dev. + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +static int8_t get_nvm_error_status(struct bmi2_nvm_err_status *nvm_err_stat, struct bmi2_dev *dev); + +/*! + * @brief This internal API gets the error status related to virtual frames. + * + * @param[out] vfrm_err_stat : Stores the VFRM related error status. + * @param[in] dev : Structure instance of bmi2_dev. + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +static int8_t get_vfrm_error_status(struct bmi2_vfrm_err_status *vfrm_err_stat, struct bmi2_dev *dev); + +/*! + * @brief This internal API is used to get enable status of gyroscope user gain + * update. + * + * @param[out] status : Stores status of gyroscope user gain update. + * @param[in] dev : Structure instance of bmi2_dev. + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +static int8_t get_user_gain_upd_status(uint8_t *status, struct bmi2_dev *dev); + +/*! + * @brief This internal API skips S4S frame in the FIFO data while getting + * activity recognition output. + * + * @param[in, out] frame_header : FIFO frame header. + * @param[in, out] data_index : Index value of the FIFO data bytes + * from which S4S frame header is to be + * skipped. + * @param[in] fifo : Structure instance of bmi2_fifo_frame. + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +static int8_t move_if_s4s_frame(const uint8_t *frame_header, uint16_t *data_index, const struct bmi2_fifo_frame *fifo); + +/*! + * @brief This internal API enables/disables compensation of the gain defined + * in the GAIN register. + * + * @param[in] enable : Enables/Disables gain compensation + * @param[in] dev : Structure instance of bmi2_dev. + * + * enable | Description + * -------------|--------------- + * BMI2_ENABLE | Enable gain compensation. + * BMI2_DISABLE | Disable gain compensation. + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +static int8_t enable_gyro_gain(uint8_t enable, struct bmi2_dev *dev); + +/*! + * @brief This internal API is used to extract the output feature configuration + * details like page and start address from the look-up table. + * + * @param[out] feat_output : Structure that stores output feature + * configurations. + * @param[in] type : Type of feature or sensor. + * @param[in] dev : Structure instance of bmi2_dev. + * + * @return Returns the feature found flag. + * + * @retval BMI2_FALSE : Feature not found + * BMI2_TRUE : Feature found + */ +static uint8_t extract_output_feat_config(struct bmi2_feature_config *feat_output, + uint8_t type, + const struct bmi2_dev *dev); + +/*! + * @brief This internal API is used to move the data index ahead of the + * current frame length parameter when unnecessary FIFO data appears while + * extracting the user specified data. + * + * @param[in,out] data_index : Index of the FIFO data which is to be + * moved ahead of the current frame length + * @param[in] current_frame_length : Number of bytes in the current frame. + * @param[in] fifo : Structure instance of bmi2_fifo_frame. + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +static int8_t move_next_frame(uint16_t *data_index, uint8_t current_frame_length, const struct bmi2_fifo_frame *fifo); + /***************************************************************************/ /*! User Interface Definitions @@ -603,31 +928,2195 @@ int8_t bmi270_context_init(struct bmi2_dev *dev) */ dev->out_sens = BMI270_CONTEXT_MAX_FEAT_OUT; + /* Assign the offsets of the feature interrupt + * to the device structure + */ + dev->map_int = bmi270_c_map_int; + + /* Assign maximum number of feature interrupts + * to device structure + */ + dev->sens_int_map = BMI270_C_MAX_INT_MAP; } } return rslt; } -/***************************************************************************/ +/*! + * @brief This API selects the sensors/features to be enabled. + */ +int8_t bmi270_context_sensor_enable(const uint8_t *sens_list, uint8_t n_sens, struct bmi2_dev *dev) +{ + /* Variable to define error */ + int8_t rslt; -/*! Local Function Definitions - ****************************************************************************/ + /* Variable to select sensor */ + uint64_t sensor_sel = 0; + + /* Null-pointer check */ + rslt = null_ptr_check(dev); + if ((rslt == BMI2_OK) && (sens_list != NULL)) + { + /* Get the selected sensors */ + rslt = select_sensor(sens_list, n_sens, &sensor_sel); + if (rslt == BMI2_OK) + { + /* Enable the selected sensors */ + rslt = sensor_enable(sensor_sel, dev); + } + } + else + { + rslt = BMI2_E_NULL_PTR; + } + + return rslt; +} /*! - * @brief This internal API is used to validate the device structure pointer for - * null conditions. + * @brief This API selects the sensors/features to be disabled. */ -static int8_t null_ptr_check(const struct bmi2_dev *dev) +int8_t bmi270_context_sensor_disable(const uint8_t *sens_list, uint8_t n_sens, struct bmi2_dev *dev) { /* Variable to define error */ - int8_t rslt = BMI2_OK; + int8_t rslt; - if ((dev == NULL) || (dev->read == NULL) || (dev->write == NULL) || (dev->delay_us == NULL)) + /* Variable to select sensor */ + uint64_t sensor_sel = 0; + + /* Null-pointer check */ + rslt = null_ptr_check(dev); + if ((rslt == BMI2_OK) && (sens_list != NULL)) + { + /* Get the selected sensors */ + rslt = select_sensor(sens_list, n_sens, &sensor_sel); + if (rslt == BMI2_OK) + { + /* Disable the selected sensors */ + rslt = sensor_disable(sensor_sel, dev); + } + } + else + { + rslt = BMI2_E_NULL_PTR; + } + + return rslt; +} + +/*! + * @brief This API sets the sensor/feature configuration. + */ +int8_t bmi270_context_set_sensor_config(struct bmi2_sens_config *sens_cfg, uint8_t n_sens, struct bmi2_dev *dev) +{ + /* Variable to define error */ + int8_t rslt; + + /* Variable to define loop */ + uint8_t loop; + + /* Variable to get the status of advance power save */ + uint8_t aps_stat = 0; + + /* Null-pointer check */ + rslt = null_ptr_check(dev); + if ((rslt == BMI2_OK) && (sens_cfg != NULL)) + { + /* Get status of advance power save mode */ + aps_stat = dev->aps_status; + + for (loop = 0; loop < n_sens; loop++) + { + if ((sens_cfg[loop].type == BMI2_ACCEL) || (sens_cfg[loop].type == BMI2_GYRO) || + (sens_cfg[loop].type == BMI2_AUX) || (sens_cfg[loop].type == BMI2_GYRO_GAIN_UPDATE)) + { + rslt = bmi2_set_sensor_config(&sens_cfg[loop], 1, dev); + } + else + { + /* Disable Advance power save if enabled for auxiliary + * and feature configurations + */ + if (aps_stat == BMI2_ENABLE) + { + /* Disable advance power save if + * enabled + */ + rslt = bmi2_set_adv_power_save(BMI2_DISABLE, dev); + } + + if (rslt == BMI2_OK) + { + switch (sens_cfg[loop].type) + { + /* Set the step counter parameters */ + case BMI2_STEP_COUNTER_PARAMS: + rslt = set_step_count_params_config(sens_cfg[loop].cfg.step_counter_params, dev); + break; + + /* Set step counter/detector/activity configuration */ + case BMI2_STEP_DETECTOR: + case BMI2_STEP_COUNTER: + rslt = set_step_config(&sens_cfg[loop].cfg.step_counter, dev); + break; + + default: + rslt = BMI2_E_INVALID_SENSOR; + break; + } + } + + /* Return error if any of the set configurations fail */ + if (rslt != BMI2_OK) + { + break; + } + } + } + + /* Enable Advance power save if disabled while configuring and + * not when already disabled + */ + if ((aps_stat == BMI2_ENABLE) && (rslt == BMI2_OK)) + { + rslt = bmi2_set_adv_power_save(BMI2_ENABLE, dev); + } + } + else + { + rslt = BMI2_E_NULL_PTR; + } + + return rslt; +} + +/*! + * @brief This API gets the sensor/feature configuration. + */ +int8_t bmi270_context_get_sensor_config(struct bmi2_sens_config *sens_cfg, uint8_t n_sens, struct bmi2_dev *dev) +{ + /* Variable to define error */ + int8_t rslt; + + /* Variable to define loop */ + uint8_t loop; + + /* Variable to get the status of advance power save */ + uint8_t aps_stat = 0; + + /* Null-pointer check */ + rslt = null_ptr_check(dev); + if ((rslt == BMI2_OK) && (sens_cfg != NULL)) + { + /* Get status of advance power save mode */ + aps_stat = dev->aps_status; + for (loop = 0; loop < n_sens; loop++) + { + if ((sens_cfg[loop].type == BMI2_ACCEL) || (sens_cfg[loop].type == BMI2_GYRO) || + (sens_cfg[loop].type == BMI2_AUX) || (sens_cfg[loop].type == BMI2_GYRO_GAIN_UPDATE)) + { + rslt = bmi2_get_sensor_config(&sens_cfg[loop], 1, dev); + } + else + { + /* Disable Advance power save if enabled for auxiliary + * and feature configurations + */ + if ((sens_cfg[loop].type >= BMI2_MAIN_SENS_MAX_NUM) || (sens_cfg[loop].type == BMI2_AUX)) + { + + if (aps_stat == BMI2_ENABLE) + { + /* Disable advance power save if + * enabled + */ + rslt = bmi2_set_adv_power_save(BMI2_DISABLE, dev); + } + } + + if (rslt == BMI2_OK) + { + switch (sens_cfg[loop].type) + { + /* Set the step counter parameters */ + case BMI2_STEP_COUNTER_PARAMS: + rslt = get_step_count_params_config(sens_cfg[loop].cfg.step_counter_params, dev); + break; + + /* Get step counter/detector/activity configuration */ + case BMI2_STEP_DETECTOR: + case BMI2_STEP_COUNTER: + rslt = get_step_config(&sens_cfg[loop].cfg.step_counter, dev); + break; + + default: + rslt = BMI2_E_INVALID_SENSOR; + break; + } + } + + /* Return error if any of the get configurations fail */ + if (rslt != BMI2_OK) + { + break; + } + } + } + + /* Enable Advance power save if disabled while configuring and + * not when already disabled + */ + if ((aps_stat == BMI2_ENABLE) && (rslt == BMI2_OK)) + { + rslt = bmi2_set_adv_power_save(BMI2_ENABLE, dev); + } + } + else { - /* Device structure pointer is not valid */ rslt = BMI2_E_NULL_PTR; } return rslt; } + +/*! + * @brief This API gets the sensor/feature data for accelerometer, gyroscope, + * auxiliary sensor, step counter, high-g, gyroscope user-gain update, + * orientation, gyroscope cross sensitivity and error status for NVM and VFRM. + */ +int8_t bmi270_context_get_sensor_data(struct bmi2_sensor_data *sensor_data, uint8_t n_sens, struct bmi2_dev *dev) +{ + /* Variable to define error */ + int8_t rslt; + + /* Variable to define loop */ + uint8_t loop; + + /* Variable to get the status of advance power save */ + uint8_t aps_stat = 0; + + /* Null-pointer check */ + rslt = null_ptr_check(dev); + if ((rslt == BMI2_OK) && (sensor_data != NULL)) + { + /* Get status of advance power save mode */ + aps_stat = dev->aps_status; + for (loop = 0; loop < n_sens; loop++) + { + if ((sensor_data[loop].type == BMI2_ACCEL) || (sensor_data[loop].type == BMI2_GYRO) || + (sensor_data[loop].type == BMI2_AUX) || (sensor_data[loop].type == BMI2_GYRO_GAIN_UPDATE) || + (sensor_data[loop].type == BMI2_GYRO_CROSS_SENSE)) + { + rslt = bmi2_get_sensor_data(&sensor_data[loop], 1, dev); + } + else + { + /* Disable Advance power save if enabled for feature + * configurations + */ + if (sensor_data[loop].type >= BMI2_MAIN_SENS_MAX_NUM) + { + if (aps_stat == BMI2_ENABLE) + { + /* Disable advance power save if + * enabled + */ + rslt = bmi2_set_adv_power_save(BMI2_DISABLE, dev); + } + } + + if (rslt == BMI2_OK) + { + switch (sensor_data[loop].type) + { + case BMI2_STEP_COUNTER: + + /* Get step counter output */ + rslt = get_step_counter_output(&sensor_data[loop].sens_data.step_counter_output, dev); + break; + case BMI2_NVM_STATUS: + + /* Get NVM error status */ + rslt = get_nvm_error_status(&sensor_data[loop].sens_data.nvm_status, dev); + break; + case BMI2_VFRM_STATUS: + + /* Get VFRM error status */ + rslt = get_vfrm_error_status(&sensor_data[loop].sens_data.vfrm_status, dev); + break; + default: + rslt = BMI2_E_INVALID_SENSOR; + break; + } + + /* Return error if any of the get sensor data fails */ + if (rslt != BMI2_OK) + { + break; + } + } + } + + /* Enable Advance power save if disabled while + * configuring and not when already disabled + */ + if ((aps_stat == BMI2_ENABLE) && (rslt == BMI2_OK)) + { + rslt = bmi2_set_adv_power_save(BMI2_ENABLE, dev); + } + } + } + else + { + rslt = BMI2_E_NULL_PTR; + } + + return rslt; +} + +/*! + * @brief This api is used for retrieving the activity recognition settings currently set. + */ +int8_t bmi270_context_get_act_recg_sett(struct bmi2_act_recg_sett *sett, struct bmi2_dev *dev) +{ + /* Variable to define error */ + int8_t rslt; + + /* Array to define the feature configuration */ + uint8_t feat_config[BMI2_FEAT_SIZE_IN_BYTES] = { 0 }; + + /* Variable to define the array offset */ + uint8_t idx = 0; + + /* Variable to get the status of advance power save */ + uint8_t aps_stat; + + /* Variable to set flag */ + uint8_t feat_found; + uint16_t msb_lsb; + uint8_t lsb; + uint8_t msb; + + /* Initialize feature configuration for activity recognition */ + struct bmi2_feature_config bmi2_act_recg_sett = { 0, 0, 0 }; + + /* Null-pointer check */ + rslt = null_ptr_check(dev); + if (rslt == BMI2_OK) + { + + /* Search for bmi2 Abort feature and extract its configuration details */ + feat_found = bmi2_extract_input_feat_config(&bmi2_act_recg_sett, BMI2_ACTIVITY_RECOGNITION_SETTINGS, dev); + if (feat_found) + { + aps_stat = dev->aps_status; + if (aps_stat == BMI2_ENABLE) + { + /* Disable advance power save if enabled */ + rslt = bmi2_set_adv_power_save(BMI2_DISABLE, dev); + } + + /* Get the configuration from the page where activity recognition setting feature resides */ + if (rslt == BMI2_OK) + { + rslt = bmi2_get_feat_config(bmi2_act_recg_sett.page, feat_config, dev); + } + + if (rslt == BMI2_OK) + { + /* Define the offset in bytes */ + idx = bmi2_act_recg_sett.start_addr; + + /* get the status of enable/disable post processing */ + sett->act_rec_1 = BMI2_GET_BIT_POS0(feat_config[idx], BMI2_ACT_RECG_POST_PROS_EN_DIS); + + /* increment idx by 2 to point min gdi thres addres */ + idx = idx + 2; + lsb = feat_config[idx]; + idx++; + msb = feat_config[idx]; + msb_lsb = (uint16_t)(lsb | msb << 8); + sett->act_rec_2 = msb_lsb; + + /* increment idx by 1 to point max gdi thres addres */ + idx++; + lsb = feat_config[idx]; + idx++; + msb = feat_config[idx]; + msb_lsb = (uint16_t)(lsb | msb << 8); + sett->act_rec_3 = msb_lsb; + + /* increment idx by 1 to point buffer size */ + idx++; + sett->act_rec_4 = BMI2_GET_BIT_POS0(feat_config[idx], BMI2_ACT_RECG_BUFF_SIZE); + + /* increment idx by 2 to to point to min segment confidence */ + idx = idx + 2; + sett->act_rec_5 = BMI2_GET_BIT_POS0(feat_config[idx], BMI2_ACT_RECG_MIN_SEG_CONF); + } + + /* Enable Advance power save if disabled while + * configuring and not when already disabled + */ + if ((aps_stat == BMI2_ENABLE) && (rslt == BMI2_OK)) + { + rslt = bmi2_set_adv_power_save(BMI2_ENABLE, dev); + } + } + else + { + rslt = BMI2_E_INVALID_SENSOR; + } + } + + return rslt; +} + +/*! + * @brief This api is used for setting the activity recognition settings. + */ +int8_t bmi270_context_set_act_recg_sett(const struct bmi2_act_recg_sett *sett, struct bmi2_dev *dev) +{ + /* Variable to define error */ + int8_t rslt; + + /* Array to define the feature configuration */ + uint8_t feat_config[BMI2_FEAT_SIZE_IN_BYTES] = { 0 }; + + /* Variable to define the array offset */ + uint8_t idx = 0; + + /* Variable to get the status of advance power save */ + uint8_t aps_stat; + + /* Variable to set flag */ + uint8_t feat_found; + + /* Initialize feature configuration for activity recognition */ + struct bmi2_feature_config bmi2_act_recg_sett = { 0, 0, 0 }; + + /* Null-pointer check */ + rslt = null_ptr_check(dev); + if (rslt == BMI2_OK) + { + + /* Search for bmi2 Abort feature and extract its configuration details */ + feat_found = bmi2_extract_input_feat_config(&bmi2_act_recg_sett, BMI2_ACTIVITY_RECOGNITION_SETTINGS, dev); + if (feat_found) + { + aps_stat = dev->aps_status; + if (aps_stat == BMI2_ENABLE) + { + /* Disable advance power save if enabled */ + rslt = bmi2_set_adv_power_save(BMI2_DISABLE, dev); + } + + /* Get the configuration from the page where activity recognition setting feature resides */ + if (rslt == BMI2_OK) + { + rslt = bmi2_get_feat_config(bmi2_act_recg_sett.page, feat_config, dev); + } + + if (rslt == BMI2_OK) + { + /* Define the offset in bytes */ + idx = bmi2_act_recg_sett.start_addr; + if ((sett->act_rec_4 > 10) || (sett->act_rec_5 > 10)) + { + rslt = BMI2_E_INVALID_INPUT; + } + + if (rslt == BMI2_OK) + { + feat_config[idx] = BMI2_SET_BIT_POS0(feat_config[idx], + BMI2_ACT_RECG_POST_PROS_EN_DIS, + sett->act_rec_1); + + /* Increment idx by 2 to point min gdi thres addres */ + idx = idx + 2; + feat_config[idx] = BMI2_GET_LSB(sett->act_rec_2); + idx++; + feat_config[idx] = BMI2_GET_MSB(sett->act_rec_2); + + /* Increment idx by 1 to point max gdi thres addres */ + idx++; + feat_config[idx] = BMI2_GET_LSB(sett->act_rec_3); + idx++; + feat_config[idx] = BMI2_GET_MSB(sett->act_rec_3); + + /* Increment idx by 1 to point buffer size */ + idx++; + feat_config[idx] = BMI2_SET_BIT_POS0(feat_config[idx], BMI2_ACT_RECG_BUFF_SIZE, sett->act_rec_4); + + /* Increment idx by 2 to to point to min segment confidence */ + idx = idx + 2; + feat_config[idx] = BMI2_SET_BIT_POS0(feat_config[idx], BMI2_ACT_RECG_MIN_SEG_CONF, sett->act_rec_5); + + rslt = bmi2_set_regs(BMI2_FEATURES_REG_ADDR, feat_config, BMI2_FEAT_SIZE_IN_BYTES, dev); + } + } + + /* Enable Advance power save if disabled while + * configuring and not when already disabled + */ + if ((aps_stat == BMI2_ENABLE) && (rslt == BMI2_OK)) + { + rslt = bmi2_set_adv_power_save(BMI2_ENABLE, dev); + } + } + else + { + rslt = BMI2_E_INVALID_SENSOR; + } + } + + return rslt; +} + +/*! + * @brief This internal API is used to parse the activity output from the + * FIFO in header mode. + */ +int8_t bmi270_context_get_act_recog_output(struct bmi2_act_recog_output *act_recog, + uint16_t *act_frm_len, + struct bmi2_fifo_frame *fifo, + const struct bmi2_dev *dev) +{ + /* Variable to define error */ + int8_t rslt; + + /* Variable to define header frame */ + uint8_t frame_header = 0; + + /* Variable to index the data bytes */ + uint16_t data_index; + + /* Variable to index activity frames */ + uint16_t act_idx = 0; + + /* Variable to indicate activity frames read */ + uint16_t frame_to_read = 0; + + /* Null-pointer check */ + rslt = null_ptr_check(dev); + if ((rslt == BMI2_OK) && (act_recog != NULL) && (act_frm_len != NULL) && (fifo != NULL)) + { + + /* Store the number of frames to be read */ + frame_to_read = *act_frm_len; + for (data_index = fifo->act_recog_byte_start_idx; data_index < fifo->length;) + { + /* Get frame header byte */ + frame_header = fifo->data[data_index] & BMI2_FIFO_TAG_INTR_MASK; + + /* Skip S4S frames if S4S is enabled */ + rslt = move_if_s4s_frame(&frame_header, &data_index, fifo); + + /* Break if FIFO is empty */ + if (rslt == BMI2_W_FIFO_EMPTY) + { + break; + } + + /* Index shifted to next byte where data starts */ + data_index++; + switch (frame_header) + { + /* If header defines accelerometer frame */ + case BMI2_FIFO_HEADER_ACC_FRM: + rslt = move_next_frame(&data_index, fifo->acc_frm_len, fifo); + break; + + /* If header defines accelerometer and auxiliary frames */ + case BMI2_FIFO_HEADER_AUX_ACC_FRM: + rslt = move_next_frame(&data_index, fifo->acc_aux_frm_len, fifo); + break; + + /* If header defines accelerometer and gyroscope frames */ + case BMI2_FIFO_HEADER_GYR_ACC_FRM: + rslt = move_next_frame(&data_index, fifo->acc_gyr_frm_len, fifo); + break; + + /* If header defines accelerometer, auxiliary and gyroscope frames */ + case BMI2_FIFO_HEADER_ALL_FRM: + rslt = move_next_frame(&data_index, fifo->all_frm_len, fifo); + break; + + /* If header defines only gyroscope frame */ + case BMI2_FIFO_HEADER_GYR_FRM: + rslt = move_next_frame(&data_index, fifo->gyr_frm_len, fifo); + break; + + /* If header defines only auxiliary frame */ + case BMI2_FIFO_HEADER_AUX_FRM: + rslt = move_next_frame(&data_index, fifo->aux_frm_len, fifo); + break; + + /* If header defines auxiliary and gyroscope frame */ + case BMI2_FIFO_HEADER_AUX_GYR_FRM: + rslt = move_next_frame(&data_index, fifo->aux_gyr_frm_len, fifo); + break; + + /* If header defines sensor time frame */ + case BMI2_FIFO_HEADER_SENS_TIME_FRM: + rslt = move_next_frame(&data_index, BMI2_SENSOR_TIME_LENGTH, fifo); + break; + + /* If header defines skip frame */ + case BMI2_FIFO_HEADER_SKIP_FRM: + rslt = move_next_frame(&data_index, BMI2_FIFO_SKIP_FRM_LENGTH, fifo); + break; + + /* If header defines Input configuration frame */ + case BMI2_FIFO_HEADER_INPUT_CFG_FRM: + rslt = move_next_frame(&data_index, BMI2_FIFO_INPUT_CFG_LENGTH, fifo); + break; + + /* If header defines invalid frame or end of valid data */ + case BMI2_FIFO_HEAD_OVER_READ_MSB: + + /* Move the data index to the last byte to mark completion */ + data_index = fifo->length; + + /* FIFO is empty */ + rslt = BMI2_W_FIFO_EMPTY; + break; + + /* If header defines activity recognition frame */ + case BMI2_FIFO_VIRT_ACT_RECOG_FRM: + + /* Get the activity output */ + rslt = unpack_act_recog_output(&act_recog[(act_idx)], &data_index, fifo); + + /* Update activity frame index */ + (act_idx)++; + break; + default: + + /* Move the data index to the last byte in case of invalid values */ + data_index = fifo->length; + + /* FIFO is empty */ + rslt = BMI2_W_FIFO_EMPTY; + break; + } + + /* Number of frames to be read is complete or FIFO is empty */ + if ((frame_to_read == act_idx) || (rslt == BMI2_W_FIFO_EMPTY)) + { + break; + } + } + + /* Update the activity frame index */ + (*act_frm_len) = act_idx; + + /* Update the activity byte index */ + fifo->act_recog_byte_start_idx = data_index; + } + else + { + rslt = BMI2_E_NULL_PTR; + } + + return rslt; +} + +/*! + * @brief This API updates the gyroscope user-gain. + */ +int8_t bmi270_context_update_gyro_user_gain(const struct bmi2_gyro_user_gain_config *user_gain, struct bmi2_dev *dev) +{ + /* Variable to define error */ + int8_t rslt; + + /* Variable to select sensor */ + uint8_t sens_sel[2] = { BMI2_GYRO, BMI2_GYRO_GAIN_UPDATE }; + + /* Structure to define sensor configurations */ + struct bmi2_sens_config sens_cfg; + + /* Variable to store status of user-gain update module */ + uint8_t status = 0; + + /* Variable to define count */ + uint8_t count = 100; + + /* Null-pointer check */ + rslt = null_ptr_check(dev); + if ((rslt == BMI2_OK) && (user_gain != NULL)) + { + /* Select type of feature */ + sens_cfg.type = BMI2_GYRO_GAIN_UPDATE; + + /* Get the user gain configurations */ + rslt = bmi270_context_get_sensor_config(&sens_cfg, 1, dev); + if (rslt == BMI2_OK) + { + /* Get the user-defined ratio */ + sens_cfg.cfg.gyro_gain_update = *user_gain; + + /* Set rate ratio for all axes */ + rslt = bmi270_context_set_sensor_config(&sens_cfg, 1, dev); + } + + /* Disable gyroscope */ + if (rslt == BMI2_OK) + { + rslt = bmi270_context_sensor_disable(&sens_sel[0], 1, dev); + } + + /* Enable gyroscope user-gain update module */ + if (rslt == BMI2_OK) + { + rslt = bmi270_context_sensor_enable(&sens_sel[1], 1, dev); + } + + /* Set the command to trigger the computation */ + if (rslt == BMI2_OK) + { + rslt = bmi2_set_command_register(BMI2_USR_GAIN_CMD, dev); + } + + if (rslt == BMI2_OK) + { + /* Poll until enable bit of user-gain update is 0 */ + while (count--) + { + rslt = get_user_gain_upd_status(&status, dev); + if ((rslt == BMI2_OK) && (status == 0)) + { + /* Enable compensation of gain defined + * in the GAIN register + */ + rslt = enable_gyro_gain(BMI2_ENABLE, dev); + + /* Enable gyroscope */ + if (rslt == BMI2_OK) + { + rslt = bmi270_context_sensor_enable(&sens_sel[0], 1, dev); + } + + break; + } + + dev->delay_us(10000, dev->intf_ptr); + } + + /* Return error if user-gain update is failed */ + if ((rslt == BMI2_OK) && (status != 0)) + { + rslt = BMI2_E_GYR_USER_GAIN_UPD_FAIL; + } + } + } + else + { + rslt = BMI2_E_NULL_PTR; + } + + return rslt; +} + +/*! + * @brief This API reads the compensated gyroscope user-gain values. + */ +int8_t bmi270_context_read_gyro_user_gain(struct bmi2_gyro_user_gain_data *gyr_usr_gain, struct bmi2_dev *dev) +{ + /* Variable to define error */ + int8_t rslt; + + /* Variable to define register data */ + uint8_t reg_data[3] = { 0 }; + + /* Null-pointer check */ + rslt = null_ptr_check(dev); + if ((rslt == BMI2_OK) && (gyr_usr_gain != NULL)) + { + /* Get the gyroscope compensated gain values */ + rslt = bmi2_get_regs(BMI2_GYR_USR_GAIN_0_ADDR, reg_data, 3, dev); + if (rslt == BMI2_OK) + { + /* Gyroscope user gain correction X-axis */ + gyr_usr_gain->x = (int8_t)BMI2_GET_BIT_POS0(reg_data[0], BMI2_GYR_USR_GAIN_X); + + /* Gyroscope user gain correction Y-axis */ + gyr_usr_gain->y = (int8_t)BMI2_GET_BIT_POS0(reg_data[1], BMI2_GYR_USR_GAIN_Y); + + /* Gyroscope user gain correction z-axis */ + gyr_usr_gain->z = (int8_t)BMI2_GET_BIT_POS0(reg_data[2], BMI2_GYR_USR_GAIN_Z); + } + } + else + { + rslt = BMI2_E_NULL_PTR; + } + + return rslt; +} + +/*! + * @brief This API maps/unmaps feature interrupts to that of interrupt pins. + */ +int8_t bmi270_context_map_feat_int(const struct bmi2_sens_int_config *sens_int, uint8_t n_sens, struct bmi2_dev *dev) +{ + /* Variable to define error */ + int8_t rslt; + + /* Variable to define loop */ + uint8_t loop; + + /* Null-pointer check */ + rslt = null_ptr_check(dev); + if ((rslt == BMI2_OK) && (sens_int != NULL)) + { + for (loop = 0; loop < n_sens; loop++) + { + switch (sens_int[loop].type) + { + case BMI2_STEP_COUNTER: + case BMI2_STEP_DETECTOR: + + rslt = bmi2_map_feat_int(sens_int[loop].type, sens_int[loop].hw_int_pin, dev); + break; + default: + rslt = BMI2_E_INVALID_SENSOR; + break; + } + + /* Return error if interrupt mapping fails */ + if (rslt != BMI2_OK) + { + break; + } + } + } + else + { + rslt = BMI2_E_NULL_PTR; + } + + return rslt; +} + +/***************************************************************************/ + +/*! Local Function Definitions + ****************************************************************************/ + +/*! + * @brief This internal API is used to validate the device structure pointer for + * null conditions. + */ +static int8_t null_ptr_check(const struct bmi2_dev *dev) +{ + /* Variable to define error */ + int8_t rslt = BMI2_OK; + + if ((dev == NULL) || (dev->read == NULL) || (dev->write == NULL) || (dev->delay_us == NULL)) + { + /* Device structure pointer is not valid */ + rslt = BMI2_E_NULL_PTR; + } + + return rslt; +} + +/*! + * @brief This internal API selects the sensor/features to be enabled or + * disabled. + */ +static int8_t select_sensor(const uint8_t *sens_list, uint8_t n_sens, uint64_t *sensor_sel) +{ + /* Variable to define error */ + int8_t rslt = BMI2_OK; + + /* Variable to define loop */ + uint8_t count; + + for (count = 0; count < n_sens; count++) + { + switch (sens_list[count]) + { + case BMI2_ACCEL: + *sensor_sel |= BMI2_ACCEL_SENS_SEL; + break; + case BMI2_GYRO: + *sensor_sel |= BMI2_GYRO_SENS_SEL; + break; + case BMI2_AUX: + *sensor_sel |= BMI2_AUX_SENS_SEL; + break; + case BMI2_TEMP: + *sensor_sel |= BMI2_TEMP_SENS_SEL; + break; + case BMI2_STEP_DETECTOR: + *sensor_sel |= BMI2_STEP_DETECT_SEL; + break; + case BMI2_STEP_COUNTER: + *sensor_sel |= BMI2_STEP_COUNT_SEL; + break; + case BMI2_GYRO_GAIN_UPDATE: + *sensor_sel |= BMI2_GYRO_GAIN_UPDATE_SEL; + break; + case BMI2_ACTIVITY_RECOGNITION: + *sensor_sel |= BMI2_ACTIVITY_RECOGNITION_SEL; + break; + default: + rslt = BMI2_E_INVALID_SENSOR; + break; + } + } + + return rslt; +} + +/*! + * @brief This internal API enables the selected sensor/features. + */ +static int8_t sensor_enable(uint64_t sensor_sel, struct bmi2_dev *dev) +{ + /* Variable to define error */ + int8_t rslt; + + /* Variable to store register values */ + uint8_t reg_data = 0; + + /* Variable to define loop */ + uint8_t loop = 1; + + /* Variable to get the status of advance power save */ + uint8_t aps_stat = 0; + + rslt = bmi2_get_regs(BMI2_PWR_CTRL_ADDR, ®_data, 1, dev); + if (rslt == BMI2_OK) + { + /* Enable accelerometer */ + if (sensor_sel & BMI2_ACCEL_SENS_SEL) + { + reg_data = BMI2_SET_BITS(reg_data, BMI2_ACC_EN, BMI2_ENABLE); + } + + /* Enable gyroscope */ + if (sensor_sel & BMI2_GYRO_SENS_SEL) + { + reg_data = BMI2_SET_BITS(reg_data, BMI2_GYR_EN, BMI2_ENABLE); + } + + /* Enable auxiliary sensor */ + if (sensor_sel & BMI2_AUX_SENS_SEL) + { + reg_data = BMI2_SET_BIT_POS0(reg_data, BMI2_AUX_EN, BMI2_ENABLE); + } + + /* Enable temperature sensor */ + if (sensor_sel & BMI2_TEMP_SENS_SEL) + { + reg_data = BMI2_SET_BITS(reg_data, BMI2_TEMP_EN, BMI2_ENABLE); + } + + /* Enable the sensors that are set in the power control register */ + if (sensor_sel & BMI2_MAIN_SENSORS) + { + rslt = bmi2_set_regs(BMI2_PWR_CTRL_ADDR, ®_data, 1, dev); + } + } + + if ((rslt == BMI2_OK) && (sensor_sel & ~(BMI2_MAIN_SENSORS))) + { + /* Get status of advance power save mode */ + aps_stat = dev->aps_status; + if (aps_stat == BMI2_ENABLE) + { + /* Disable advance power save if enabled */ + rslt = bmi2_set_adv_power_save(BMI2_DISABLE, dev); + } + + if (rslt == BMI2_OK) + { + while (loop--) + { + /* Enable step detector feature */ + if (sensor_sel & BMI2_STEP_DETECT_SEL) + { + rslt = set_step_detector(BMI2_ENABLE, dev); + if (rslt == BMI2_OK) + { + dev->sens_en_stat |= BMI2_STEP_DETECT_SEL; + } + else + { + break; + } + } + + /* Enable step counter feature */ + if (sensor_sel & BMI2_STEP_COUNT_SEL) + { + rslt = set_step_counter(BMI2_ENABLE, dev); + if (rslt == BMI2_OK) + { + dev->sens_en_stat |= BMI2_STEP_COUNT_SEL; + } + else + { + break; + } + } + + /* Enable gyroscope user gain */ + if (sensor_sel & BMI2_GYRO_GAIN_UPDATE_SEL) + { + rslt = set_gyro_user_gain(BMI2_ENABLE, dev); + if (rslt == BMI2_OK) + { + dev->sens_en_stat |= BMI2_GYRO_GAIN_UPDATE_SEL; + } + else + { + break; + } + } + + /* Enable activity recognition feature */ + if (sensor_sel & BMI2_ACTIVITY_RECOGNITION_SEL) + { + rslt = set_act_recog(BMI2_ENABLE, dev); + if (rslt == BMI2_OK) + { + dev->sens_en_stat |= BMI2_ACTIVITY_RECOGNITION_SEL; + } + else + { + break; + } + } + } + + /* Enable Advance power save if disabled while + * configuring and not when already disabled + */ + if ((aps_stat == BMI2_ENABLE) && (rslt == BMI2_OK)) + { + rslt = bmi2_set_adv_power_save(BMI2_ENABLE, dev); + } + } + } + + return rslt; +} + +/*! + * @brief This internal API disables the selected sensors/features. + */ +static int8_t sensor_disable(uint64_t sensor_sel, struct bmi2_dev *dev) +{ + /* Variable to define error */ + int8_t rslt; + + /* Variable to store register values */ + uint8_t reg_data = 0; + + /* Variable to define loop */ + uint8_t loop = 1; + + /* Variable to get the status of advance power save */ + uint8_t aps_stat = 0; + + rslt = bmi2_get_regs(BMI2_PWR_CTRL_ADDR, ®_data, 1, dev); + if (rslt == BMI2_OK) + { + /* Disable accelerometer */ + if (sensor_sel & BMI2_ACCEL_SENS_SEL) + { + reg_data = BMI2_SET_BIT_VAL0(reg_data, BMI2_ACC_EN); + } + + /* Disable gyroscope */ + if (sensor_sel & BMI2_GYRO_SENS_SEL) + { + reg_data = BMI2_SET_BIT_VAL0(reg_data, BMI2_GYR_EN); + } + + /* Disable auxiliary sensor */ + if (sensor_sel & BMI2_AUX_SENS_SEL) + { + reg_data = BMI2_SET_BIT_VAL0(reg_data, BMI2_AUX_EN); + } + + /* Disable temperature sensor */ + if (sensor_sel & BMI2_TEMP_SENS_SEL) + { + reg_data = BMI2_SET_BIT_VAL0(reg_data, BMI2_TEMP_EN); + } + + /* Disable the sensors that are set in the power control register */ + if (sensor_sel & BMI2_MAIN_SENSORS) + { + rslt = bmi2_set_regs(BMI2_PWR_CTRL_ADDR, ®_data, 1, dev); + } + } + + if ((rslt == BMI2_OK) && (sensor_sel & ~(BMI2_MAIN_SENSORS))) + { + /* Get status of advance power save mode */ + aps_stat = dev->aps_status; + if (aps_stat == BMI2_ENABLE) + { + /* Disable advance power save if enabled */ + rslt = bmi2_set_adv_power_save(BMI2_DISABLE, dev); + } + + if (rslt == BMI2_OK) + { + while (loop--) + { + /* Disable step detector feature */ + if (sensor_sel & BMI2_STEP_DETECT_SEL) + { + rslt = set_step_detector(BMI2_DISABLE, dev); + if (rslt == BMI2_OK) + { + dev->sens_en_stat &= ~BMI2_STEP_DETECT_SEL; + } + else + { + break; + } + } + + /* Disable step counter feature */ + if (sensor_sel & BMI2_STEP_COUNT_SEL) + { + rslt = set_step_counter(BMI2_DISABLE, dev); + if (rslt == BMI2_OK) + { + dev->sens_en_stat &= ~BMI2_STEP_COUNT_SEL; + } + else + { + break; + } + } + + /* Disable gyroscope user gain */ + if (sensor_sel & BMI2_GYRO_GAIN_UPDATE_SEL) + { + rslt = set_gyro_user_gain(BMI2_DISABLE, dev); + if (rslt == BMI2_OK) + { + dev->sens_en_stat &= ~BMI2_GYRO_GAIN_UPDATE_SEL; + } + else + { + break; + } + } + + if (sensor_sel & BMI2_ACTIVITY_RECOGNITION_SEL) + { + rslt = set_act_recog(BMI2_DISABLE, dev); + if (rslt == BMI2_OK) + { + dev->sens_en_stat |= BMI2_ACTIVITY_RECOGNITION_SEL; + } + else + { + break; + } + } + + /* Enable Advance power save if disabled while + * configuring and not when already disabled + */ + if ((aps_stat == BMI2_ENABLE) && (rslt == BMI2_OK)) + { + rslt = bmi2_set_adv_power_save(BMI2_ENABLE, dev); + } + } + } + } + + return rslt; +} + +/*! + * @brief This internal API is used to enable/disable step detector feature. + */ +static int8_t set_step_detector(uint8_t enable, struct bmi2_dev *dev) +{ + /* Variable to define error */ + int8_t rslt; + + /* Array to define the feature configuration */ + uint8_t feat_config[BMI2_FEAT_SIZE_IN_BYTES] = { 0 }; + + /* Variable to define the array offset */ + uint8_t idx = 0; + + /* Variable to set flag */ + uint8_t feat_found; + + /* Initialize feature configuration for step detector */ + struct bmi2_feature_config step_det_config = { 0, 0, 0 }; + + /* Search for step detector feature and extract its configuration details */ + feat_found = bmi2_extract_input_feat_config(&step_det_config, BMI2_STEP_DETECTOR, dev); + if (feat_found) + { + /* Get the configuration from the page where step detector feature resides */ + rslt = bmi2_get_feat_config(step_det_config.page, feat_config, dev); + if (rslt == BMI2_OK) + { + /* Define the offset for enable/disable of step detector */ + idx = step_det_config.start_addr + BMI2_STEP_COUNT_FEAT_EN_OFFSET; + + /* Set the feature enable bit */ + feat_config[idx] = BMI2_SET_BITS(feat_config[idx], BMI2_STEP_DET_FEAT_EN, enable); + + /* Set the configuration back to the page */ + rslt = bmi2_set_regs(BMI2_FEATURES_REG_ADDR, feat_config, BMI2_FEAT_SIZE_IN_BYTES, dev); + } + } + else + { + rslt = BMI2_E_INVALID_SENSOR; + } + + return rslt; +} + +/*! + * @brief This internal API is used to enable/disable step counter feature. + */ +static int8_t set_step_counter(uint8_t enable, struct bmi2_dev *dev) +{ + /* Variable to define error */ + int8_t rslt; + + /* Array to define the feature configuration */ + uint8_t feat_config[BMI2_FEAT_SIZE_IN_BYTES] = { 0 }; + + /* Variable to define the array offset */ + uint8_t idx = 0; + + /* Variable to set flag */ + uint8_t feat_found; + + /* Initialize feature configuration for step counter */ + struct bmi2_feature_config step_count_config = { 0, 0, 0 }; + + /* Search for step counter feature and extract its configuration details */ + feat_found = bmi2_extract_input_feat_config(&step_count_config, BMI2_STEP_COUNTER, dev); + if (feat_found) + { + /* Get the configuration from the page where step-counter feature resides */ + rslt = bmi2_get_feat_config(step_count_config.page, feat_config, dev); + if (rslt == BMI2_OK) + { + /* Define the offset for enable/disable of step counter */ + idx = step_count_config.start_addr + BMI2_STEP_COUNT_FEAT_EN_OFFSET; + + /* Set the feature enable bit */ + feat_config[idx] = BMI2_SET_BITS(feat_config[idx], BMI2_STEP_COUNT_FEAT_EN, enable); + + /* Set the configuration back to the page */ + rslt = bmi2_set_regs(BMI2_FEATURES_REG_ADDR, feat_config, BMI2_FEAT_SIZE_IN_BYTES, dev); + } + } + else + { + rslt = BMI2_E_INVALID_SENSOR; + } + + return rslt; +} + +/*! + * @brief This internal API is used to enable/disable gyroscope user gain + * feature. + */ +static int8_t set_gyro_user_gain(uint8_t enable, struct bmi2_dev *dev) +{ + /* Variable to define error */ + int8_t rslt; + + /* Array to define the feature configuration */ + uint8_t feat_config[BMI2_FEAT_SIZE_IN_BYTES] = { 0 }; + + /* Variable to define the array offset */ + uint8_t idx = 0; + + /* Variable to set flag */ + uint8_t feat_found; + + /* Initialize feature configuration for gyroscope user gain */ + struct bmi2_feature_config gyr_user_gain_cfg = { 0, 0, 0 }; + + /* Search for user gain feature and extract its configuration details */ + feat_found = bmi2_extract_input_feat_config(&gyr_user_gain_cfg, BMI2_GYRO_GAIN_UPDATE, dev); + if (feat_found) + { + /* Get the configuration from the page where user gain feature resides */ + rslt = bmi2_get_feat_config(gyr_user_gain_cfg.page, feat_config, dev); + if (rslt == BMI2_OK) + { + /* Define the offset for enable/disable of user gain */ + idx = gyr_user_gain_cfg.start_addr + BMI2_GYR_USER_GAIN_FEAT_EN_OFFSET; + + /* Set the feature enable bit */ + feat_config[idx] = BMI2_SET_BITS(feat_config[idx], BMI2_GYR_USER_GAIN_FEAT_EN, enable); + + /* Set the configuration back to the page */ + rslt = bmi2_set_regs(BMI2_FEATURES_REG_ADDR, feat_config, BMI2_FEAT_SIZE_IN_BYTES, dev); + } + } + else + { + rslt = BMI2_E_INVALID_SENSOR; + } + + return rslt; +} + +/*! + * @brief This internal API enables/disables the activity recognition feature. + */ +static int8_t set_act_recog(uint8_t enable, struct bmi2_dev *dev) +{ + /* Variable to define error */ + int8_t rslt; + + /* Array to define the feature configuration */ + uint8_t feat_config[BMI2_FEAT_SIZE_IN_BYTES] = { 0 }; + + /* Variable to define the array offset */ + uint8_t idx = 0; + + /* Variable to set flag */ + uint8_t feat_found; + + /* Initialize feature configuration for activity recognition */ + struct bmi2_feature_config act_recog_cfg = { 0, 0, 0 }; + + /* Search for activity recognition and extract its configuration details */ + feat_found = bmi2_extract_input_feat_config(&act_recog_cfg, BMI2_ACTIVITY_RECOGNITION, dev); + if (feat_found) + { + /* Get the configuration from the page where activity + * recognition feature resides + */ + rslt = bmi2_get_feat_config(act_recog_cfg.page, feat_config, dev); + if (rslt == BMI2_OK) + { + /* Define the offset for enable/disable of activity recognition */ + idx = act_recog_cfg.start_addr; + + /* Set the feature enable bit */ + feat_config[idx] = BMI2_SET_BIT_POS0(feat_config[idx], BMI2_ACTIVITY_RECOG_EN, enable); + + /* Set the configuration back to the page */ + rslt = bmi2_set_regs(BMI2_FEATURES_REG_ADDR, feat_config, BMI2_FEAT_SIZE_IN_BYTES, dev); + } + } + else + { + rslt = BMI2_E_INVALID_SENSOR; + } + + return rslt; +} + +/*! + * @brief This internal API sets step counter parameter configurations. + */ +static int8_t set_step_count_params_config(const uint16_t *step_count_params, struct bmi2_dev *dev) +{ + /* Variable to define error */ + int8_t rslt = BMI2_OK; + + /* Array to define the feature configuration */ + uint8_t feat_config[BMI2_FEAT_SIZE_IN_BYTES] = { 0 }; + + /* Variable to define index */ + uint8_t index = 0; + + /* Variable to set flag */ + uint8_t feat_found; + + /* Initialize feature configuration for step counter parameters */ + struct bmi2_feature_config step_params_config = { 0, 0, 0 }; + + /* Variable to index the page number */ + uint8_t page_idx; + + /* Variable to define the start page */ + uint8_t start_page; + + /* Variable to define start address of the parameters */ + uint8_t start_addr; + + /* Variable to define number of bytes */ + uint8_t n_bytes = (BMI2_STEP_CNT_N_PARAMS * 2); + + /* Variable to store number of pages */ + uint8_t n_pages = (n_bytes / 16); + + /* Variable to define the end page */ + uint8_t end_page; + + /* Variable to define the remaining bytes to be read */ + uint8_t remain_len; + + /* Variable to define the maximum words(16 bytes or 8 words) to be read in a page */ + uint8_t max_len = 8; + + /* Variable index bytes in a page */ + uint8_t page_byte_idx; + + /* Variable to index the parameters */ + uint8_t param_idx = 0; + + /* Copy the feature configuration address to a local pointer */ + uint16_t *data_p = (uint16_t *) (void *)feat_config; + + /* Search for step counter parameter feature and extract its configuration details */ + feat_found = bmi2_extract_input_feat_config(&step_params_config, BMI2_STEP_COUNTER_PARAMS, dev); + if (feat_found) + { + /* Get the start page for the step counter parameters */ + start_page = step_params_config.page; + + /* Get the end page for the step counter parameters */ + end_page = start_page + n_pages; + + /* Get the start address for the step counter parameters */ + start_addr = step_params_config.start_addr; + + /* Get the remaining length of bytes to be read */ + remain_len = (uint8_t)((n_bytes - (n_pages * 16)) + start_addr); + for (page_idx = start_page; page_idx <= end_page; page_idx++) + { + /* Get the configuration from the respective page */ + rslt = bmi2_get_feat_config(page_idx, feat_config, dev); + if (rslt == BMI2_OK) + { + /* Start from address 0x00 when switched to next page */ + if (page_idx > start_page) + { + start_addr = 0; + } + + /* Remaining number of words to be read in the page */ + if (page_idx == end_page) + { + max_len = (remain_len / 2); + } + + /* Get offset in words since all the features are set in words length */ + page_byte_idx = start_addr / 2; + for (; page_byte_idx < max_len;) + { + /* Set parameters 1 to 25 */ + *(data_p + page_byte_idx) = BMI2_SET_BIT_POS0(*(data_p + page_byte_idx), + BMI2_STEP_COUNT_PARAMS, + step_count_params[param_idx]); + + /* Increment offset by 1 word to set to the next parameter */ + page_byte_idx++; + + /* Increment to next parameter */ + param_idx++; + } + + /* Get total length in bytes to copy from local pointer to the array */ + page_byte_idx = (uint8_t)(page_byte_idx * 2) - step_params_config.start_addr; + + /* Copy the bytes to be set back to the array */ + for (index = 0; index < page_byte_idx; index++) + { + feat_config[step_params_config.start_addr + + index] = *((uint8_t *) data_p + step_params_config.start_addr + index); + } + + /* Set the configuration back to the page */ + rslt = bmi2_set_regs(BMI2_FEATURES_REG_ADDR, feat_config, BMI2_FEAT_SIZE_IN_BYTES, dev); + } + } + } + else + { + rslt = BMI2_E_INVALID_SENSOR; + } + + return rslt; +} + +/* @brief This internal API sets step counter configurations like water-mark + * level, reset-counter and output-configuration step detector and activity. + */ +static int8_t set_step_config(const struct bmi2_step_config *config, struct bmi2_dev *dev) +{ + /* Variable to define error */ + int8_t rslt; + + /* Array to define the feature configuration */ + uint8_t feat_config[BMI2_FEAT_SIZE_IN_BYTES] = { 0 }; + + /* Variable to define the array offset */ + uint8_t idx = 0; + + /* Variable to define index */ + uint8_t index = 0; + + /* Variable to set flag */ + uint8_t feat_found; + + /* Initialize feature configuration for step counter 4 */ + struct bmi2_feature_config step_count_config = { 0, 0, 0 }; + + /* Copy the feature configuration address to a local pointer */ + uint16_t *data_p = (uint16_t *) (void *)feat_config; + + /* Search for step counter feature and extract its configuration details */ + feat_found = bmi2_extract_input_feat_config(&step_count_config, BMI2_STEP_COUNTER, dev); + if (feat_found) + { + /* Get the configuration from the page where step counter resides */ + rslt = bmi2_get_feat_config(step_count_config.page, feat_config, dev); + if (rslt == BMI2_OK) + { + /* Define the offset in bytes */ + idx = step_count_config.start_addr; + + /* Get offset in words since all the features are set in words length */ + idx = idx / 2; + + /* Set water-mark level */ + *(data_p + idx) = BMI2_SET_BIT_POS0(*(data_p + idx), BMI2_STEP_COUNT_WM_LEVEL, config->watermark_level); + + /* Set reset-counter */ + *(data_p + idx) = BMI2_SET_BITS(*(data_p + idx), BMI2_STEP_COUNT_RST_CNT, config->reset_counter); + + /* Increment offset by 1 word to set output + * configuration of step detector and step activity + */ + idx++; + + /* Set step buffer size */ + *(data_p + idx) = BMI2_SET_BITS(*(data_p + idx), BMI2_STEP_BUFFER_SIZE, config->step_buffer_size); + + /* Increment offset by 1 more word to get the total length in words */ + idx++; + + /* Get total length in bytes to copy from local pointer to the array */ + idx = (uint8_t)(idx * 2) - step_count_config.start_addr; + + /* Copy the bytes to be set back to the array */ + for (index = 0; index < idx; index++) + { + feat_config[step_count_config.start_addr + + index] = *((uint8_t *) data_p + step_count_config.start_addr + index); + } + + /* Set the configuration back to the page */ + rslt = bmi2_set_regs(BMI2_FEATURES_REG_ADDR, feat_config, BMI2_FEAT_SIZE_IN_BYTES, dev); + } + } + else + { + rslt = BMI2_E_INVALID_SENSOR; + } + + return rslt; +} + +/*! + * @brief This internal API gets step counter parameter configurations. + */ +static int8_t get_step_count_params_config(uint16_t *step_count_params, struct bmi2_dev *dev) +{ + /* Variable to define error */ + int8_t rslt = BMI2_OK; + + /* Array to define the feature configuration */ + uint8_t feat_config[BMI2_FEAT_SIZE_IN_BYTES] = { 0 }; + + /* Variable to set flag */ + uint8_t feat_found; + + /* Variable to define LSB */ + uint16_t lsb = 0; + + /* Variable to define MSB */ + uint16_t msb = 0; + + /* Variable to define a word */ + uint16_t lsb_msb = 0; + + /* Initialize feature configuration for step counter 1 */ + struct bmi2_feature_config step_params_config = { 0, 0, 0 }; + + /* Variable to index the page number */ + uint8_t page_idx; + + /* Variable to define the start page */ + uint8_t start_page; + + /* Variable to define start address of the parameters */ + uint8_t start_addr; + + /* Variable to define number of bytes */ + uint8_t n_bytes = (BMI2_STEP_CNT_N_PARAMS * 2); + + /* Variable to store number of pages */ + uint8_t n_pages = (n_bytes / 16); + + /* Variable to define the end page */ + uint8_t end_page; + + /* Variable to define the remaining bytes to be read */ + uint8_t remain_len; + + /* Variable to define the maximum words to be read in a page */ + uint8_t max_len = BMI2_FEAT_SIZE_IN_BYTES; + + /* Variable index bytes in a page */ + uint8_t page_byte_idx; + + /* Variable to index the parameters */ + uint8_t param_idx = 0; + + /* Search for step counter parameter feature and extract its configuration details */ + feat_found = bmi2_extract_input_feat_config(&step_params_config, BMI2_STEP_COUNTER_PARAMS, dev); + if (feat_found) + { + /* Get the start page for the step counter parameters */ + start_page = step_params_config.page; + + /* Get the end page for the step counter parameters */ + end_page = start_page + n_pages; + + /* Get the start address for the step counter parameters */ + start_addr = step_params_config.start_addr; + + /* Get the remaining length of bytes to be read */ + remain_len = (uint8_t)((n_bytes - (n_pages * 16)) + start_addr); + for (page_idx = start_page; page_idx <= end_page; page_idx++) + { + /* Get the configuration from the respective page */ + rslt = bmi2_get_feat_config(page_idx, feat_config, dev); + if (rslt == BMI2_OK) + { + /* Start from address 0x00 when switched to next page */ + if (page_idx > start_page) + { + start_addr = 0; + } + + /* Remaining number of bytes to be read in the page */ + if (page_idx == end_page) + { + max_len = remain_len; + } + + /* Get the offset */ + page_byte_idx = start_addr; + while (page_byte_idx < max_len) + { + /* Get word to calculate the parameter*/ + lsb = (uint16_t) feat_config[page_byte_idx++]; + if (page_byte_idx < max_len) + { + msb = ((uint16_t) feat_config[page_byte_idx++] << 8); + } + + lsb_msb = lsb | msb; + + /* Get parameters 1 to 25 */ + step_count_params[param_idx] = lsb_msb & BMI2_STEP_COUNT_PARAMS_MASK; + + /* Increment to next parameter */ + param_idx++; + } + } + } + } + else + { + rslt = BMI2_E_INVALID_SENSOR; + } + + return rslt; +} + +/*! + * @brief This internal API gets step counter/detector/activity configurations. + */ +static int8_t get_step_config(struct bmi2_step_config *config, struct bmi2_dev *dev) +{ + /* Variable to define error */ + int8_t rslt; + + /* Array to define the feature configuration */ + uint8_t feat_config[BMI2_FEAT_SIZE_IN_BYTES] = { 0 }; + + /* Variable to define the array offset */ + uint8_t idx = 0; + + /* Variable to define LSB */ + uint16_t lsb = 0; + + /* Variable to define MSB */ + uint16_t msb = 0; + + /* Variable to define a word */ + uint16_t lsb_msb = 0; + + /* Variable to set flag */ + uint8_t feat_found; + + /* Initialize feature configuration for step counter */ + struct bmi2_feature_config step_count_config = { 0, 0, 0 }; + + /* Search for step counter 4 feature and extract its configuration details */ + feat_found = bmi2_extract_input_feat_config(&step_count_config, BMI2_STEP_COUNTER, dev); + if (feat_found) + { + /* Get the configuration from the page where step counter 4 parameter resides */ + rslt = bmi2_get_feat_config(step_count_config.page, feat_config, dev); + if (rslt == BMI2_OK) + { + /* Define the offset for feature enable for step counter/detector/activity */ + idx = step_count_config.start_addr; + + /* Get word to calculate water-mark level and reset counter */ + lsb = (uint16_t) feat_config[idx++]; + msb = ((uint16_t) feat_config[idx++] << 8); + lsb_msb = lsb | msb; + + /* Get water-mark level */ + config->watermark_level = lsb_msb & BMI2_STEP_COUNT_WM_LEVEL_MASK; + + /* Get reset counter */ + config->reset_counter = (lsb_msb & BMI2_STEP_COUNT_RST_CNT_MASK) >> BMI2_STEP_COUNT_RST_CNT_POS; + + /* Get word to calculate output configuration of step detector and activity */ + lsb = (uint16_t) feat_config[idx++]; + msb = ((uint16_t) feat_config[idx++] << 8); + lsb_msb = lsb | msb; + + config->step_buffer_size = (lsb_msb & BMI2_STEP_BUFFER_SIZE_MASK) >> BMI2_STEP_BUFFER_SIZE_POS; + } + } + else + { + rslt = BMI2_E_INVALID_SENSOR; + } + + return rslt; +} + +/*! + * @brief This internal API gets the output values of step counter. + */ +static int8_t get_step_counter_output(uint32_t *step_count, struct bmi2_dev *dev) +{ + /* Variable to define error */ + int8_t rslt; + + /* Array to define the feature configuration */ + uint8_t feat_config[BMI2_FEAT_SIZE_IN_BYTES] = { 0 }; + + /* Variables to define index */ + uint8_t idx = 0; + + /* Variable to set flag */ + uint8_t feat_found; + + /* Initialize feature output for step counter */ + struct bmi2_feature_config step_cnt_out_config = { 0, 0, 0 }; + + /* Search for step counter output feature and extract its configuration details */ + feat_found = extract_output_feat_config(&step_cnt_out_config, BMI2_STEP_COUNTER, dev); + if (feat_found) + { + /* Get the feature output configuration for step-counter */ + rslt = bmi2_get_feat_config(step_cnt_out_config.page, feat_config, dev); + if (rslt == BMI2_OK) + { + /* Define the offset in bytes for step counter output */ + idx = step_cnt_out_config.start_addr; + + /* Get the step counter output in 4 bytes */ + *step_count = (uint32_t) feat_config[idx++]; + *step_count |= ((uint32_t) feat_config[idx++] << 8); + *step_count |= ((uint32_t) feat_config[idx++] << 16); + *step_count |= ((uint32_t) feat_config[idx++] << 24); + } + } + else + { + rslt = BMI2_E_INVALID_SENSOR; + } + + return rslt; +} + +/*! + * @brief This internal API gets the error status related to NVM. + */ +static int8_t get_nvm_error_status(struct bmi2_nvm_err_status *nvm_err_stat, struct bmi2_dev *dev) +{ + /* Variable to define error */ + int8_t rslt; + + /* Array to define the feature configuration */ + uint8_t feat_config[BMI2_FEAT_SIZE_IN_BYTES] = { 0 }; + + /* Variables to define index */ + uint8_t idx = 0; + + /* Variable to set flag */ + uint8_t feat_found; + + /* Initialize feature output for NVM error status */ + struct bmi2_feature_config nvm_err_cfg = { 0, 0, 0 }; + + /* Search for NVM error status feature and extract its configuration details */ + feat_found = extract_output_feat_config(&nvm_err_cfg, BMI2_NVM_STATUS, dev); + if (feat_found) + { + /* Get the feature output configuration for NVM error status */ + rslt = bmi2_get_feat_config(nvm_err_cfg.page, feat_config, dev); + if (rslt == BMI2_OK) + { + /* Define the offset in bytes for NVM error status */ + idx = nvm_err_cfg.start_addr; + + /* Increment index to get the error status */ + idx++; + + /* Error when NVM load action fails */ + nvm_err_stat->load_error = BMI2_GET_BIT_POS0(feat_config[idx], BMI2_NVM_LOAD_ERR_STATUS); + + /* Error when NVM program action fails */ + nvm_err_stat->prog_error = BMI2_GET_BITS(feat_config[idx], BMI2_NVM_PROG_ERR_STATUS); + + /* Error when NVM erase action fails */ + nvm_err_stat->erase_error = BMI2_GET_BITS(feat_config[idx], BMI2_NVM_ERASE_ERR_STATUS); + + /* Error when NVM program limit is exceeded */ + nvm_err_stat->exceed_error = BMI2_GET_BITS(feat_config[idx], BMI2_NVM_END_EXCEED_STATUS); + + /* Error when NVM privilege mode is not acquired */ + nvm_err_stat->privil_error = BMI2_GET_BITS(feat_config[idx], BMI2_NVM_PRIV_ERR_STATUS); + } + } + else + { + rslt = BMI2_E_INVALID_SENSOR; + } + + return rslt; +} + +/*! + * @brief This internal API is used to get enable status of gyroscope user gain + * update. + */ +static int8_t get_user_gain_upd_status(uint8_t *status, struct bmi2_dev *dev) +{ + /* Variable to define error */ + int8_t rslt = BMI2_OK; + + /* Array to define the feature configuration */ + uint8_t feat_config[BMI2_FEAT_SIZE_IN_BYTES] = { 0 }; + + /* Variable to define the array offset */ + uint8_t idx = 0; + + /* Variable to set flag */ + uint8_t feat_found; + + /* Variable to check APS status */ + uint8_t aps_stat = 0; + + /* Initialize feature configuration for gyroscope user gain */ + struct bmi2_feature_config gyr_user_gain_cfg = { 0, 0, 0 }; + + /* Search for user gain feature and extract its configuration details */ + feat_found = bmi2_extract_input_feat_config(&gyr_user_gain_cfg, BMI2_GYRO_GAIN_UPDATE, dev); + if (feat_found) + { + /* Disable advance power save */ + aps_stat = dev->aps_status; + if (aps_stat == BMI2_ENABLE) + { + rslt = bmi2_set_adv_power_save(BMI2_DISABLE, dev); + } + + if (rslt == BMI2_OK) + { + /* Get the configuration from the page where user gain feature resides */ + rslt = bmi2_get_feat_config(gyr_user_gain_cfg.page, feat_config, dev); + if (rslt == BMI2_OK) + { + /* Define the offset for enable/disable of user gain */ + idx = gyr_user_gain_cfg.start_addr + BMI2_GYR_USER_GAIN_FEAT_EN_OFFSET; + + /* Set the feature enable status */ + *status = BMI2_GET_BITS(feat_config[idx], BMI2_GYR_USER_GAIN_FEAT_EN); + } + } + } + else + { + rslt = BMI2_E_INVALID_SENSOR; + } + + /* Enable Advance power save if disabled while configuring and not when already disabled */ + if ((rslt == BMI2_OK) && (aps_stat == BMI2_ENABLE)) + { + rslt = bmi2_set_adv_power_save(BMI2_ENABLE, dev); + } + + return rslt; +} + +/*! + * @brief This internal API is used to parse and store the activity recognition + * output from the FIFO data. + */ +static int8_t unpack_act_recog_output(struct bmi2_act_recog_output *act_recog, + uint16_t *data_index, + const struct bmi2_fifo_frame *fifo) +{ + /* Variable to define error */ + int8_t rslt = BMI2_OK; + + /* Variables to define 4 bytes of sensor time */ + uint32_t time_stamp_byte4 = 0; + uint32_t time_stamp_byte3 = 0; + uint32_t time_stamp_byte2 = 0; + uint32_t time_stamp_byte1 = 0; + + /* Validate data index */ + if ((*data_index + BMI2_FIFO_VIRT_ACT_DATA_LENGTH) >= fifo->length) + { + /* Update the data index to the last byte */ + (*data_index) = fifo->length; + + /* FIFO is empty */ + rslt = BMI2_W_FIFO_EMPTY; + } + else + { + /* Get time-stamp from the activity recognition frame */ + time_stamp_byte4 = ((uint32_t)(fifo->data[(*data_index) + 3]) << 24); + time_stamp_byte3 = ((uint32_t)(fifo->data[(*data_index) + 2]) << 16); + time_stamp_byte2 = fifo->data[(*data_index) + 1] << 8; + time_stamp_byte1 = fifo->data[(*data_index)]; + + /* Update time-stamp from the virtual frame */ + act_recog->time_stamp = (time_stamp_byte4 | time_stamp_byte3 | time_stamp_byte2 | time_stamp_byte1); + + /* Move the data index by 4 bytes */ + (*data_index) = (*data_index) + BMI2_FIFO_VIRT_ACT_TIME_LENGTH; + + /* Update the previous activity from the virtual frame */ + act_recog->prev_act = fifo->data[(*data_index)]; + + /* Move the data index by 1 byte */ + (*data_index) = (*data_index) + BMI2_FIFO_VIRT_ACT_TYPE_LENGTH; + + /* Update the current activity from the virtual frame */ + act_recog->curr_act = fifo->data[(*data_index)]; + + /* Move the data index by 1 byte */ + (*data_index) = (*data_index) + BMI2_FIFO_VIRT_ACT_STAT_LENGTH; + + /* More frames could be read */ + rslt = BMI2_W_PARTIAL_READ; + } + + return rslt; +} + +/*! + * @brief This internal API gets the error status related to virtual frames. + */ +static int8_t get_vfrm_error_status(struct bmi2_vfrm_err_status *vfrm_err_stat, struct bmi2_dev *dev) +{ + /* Variable to define error */ + int8_t rslt; + + /* Array to define the feature configuration */ + uint8_t feat_config[BMI2_FEAT_SIZE_IN_BYTES] = { 0 }; + + /* Variables to define index */ + uint8_t idx = 0; + + /* Variable to set flag */ + uint8_t feat_found; + + /* Initialize feature output for VFRM error status */ + struct bmi2_feature_config vfrm_err_cfg = { 0, 0, 0 }; + + /* Search for VFRM error status feature and extract its configuration details */ + feat_found = extract_output_feat_config(&vfrm_err_cfg, BMI2_VFRM_STATUS, dev); + if (feat_found) + { + /* Get the feature output configuration for VFRM error status */ + rslt = bmi2_get_feat_config(vfrm_err_cfg.page, feat_config, dev); + if (rslt == BMI2_OK) + { + /* Define the offset in bytes for VFRM error status */ + idx = vfrm_err_cfg.start_addr; + + /* Increment index to get the error status */ + idx++; + + /* Internal error while acquiring lock for FIFO */ + vfrm_err_stat->lock_error = BMI2_GET_BITS(feat_config[idx], BMI2_VFRM_LOCK_ERR_STATUS); + + /* Internal error while writing byte into FIFO */ + vfrm_err_stat->write_error = BMI2_GET_BITS(feat_config[idx], BMI2_VFRM_WRITE_ERR_STATUS); + + /* Internal error while writing into FIFO */ + vfrm_err_stat->fatal_error = BMI2_GET_BITS(feat_config[idx], BMI2_VFRM_FATAL_ERR_STATUS); + } + } + else + { + rslt = BMI2_E_INVALID_SENSOR; + } + + return rslt; +} + +/*! + * @brief This internal API skips S4S frame in the FIFO data while getting + * step activity output. + */ +static int8_t move_if_s4s_frame(const uint8_t *frame_header, uint16_t *data_index, const struct bmi2_fifo_frame *fifo) +{ + /* Variable to define error */ + int8_t rslt = BMI2_OK; + + /* Variable to extract virtual header byte */ + uint8_t virtual_header_mode; + + /* Variable to define pay-load in words */ + uint8_t payload_word = 0; + + /* Variable to define pay-load in bytes */ + uint8_t payload_bytes = 0; + + /* Extract virtual header mode from the frame header */ + virtual_header_mode = BMI2_GET_BITS(*frame_header, BMI2_FIFO_VIRT_FRM_MODE); + + /* If the extracted header byte is a virtual header */ + if (virtual_header_mode == BMI2_FIFO_VIRT_FRM_MODE) + { + /* If frame header is not activity recognition header */ + if (*frame_header != 0xC8) + { + /* Extract pay-load in words from the header byte */ + payload_word = BMI2_GET_BITS(*frame_header, BMI2_FIFO_VIRT_PAYLOAD) + 1; + + /* Convert to bytes */ + payload_bytes = (uint8_t)(payload_word * 2); + + /* Move the data index by those pay-load bytes */ + rslt = move_next_frame(data_index, payload_bytes, fifo); + } + } + + return rslt; +} + +/*! + * @brief This internal API enables/disables compensation of the gain defined + * in the GAIN register. + */ +static int8_t enable_gyro_gain(uint8_t enable, struct bmi2_dev *dev) +{ + /* Variable to define error */ + int8_t rslt; + + /* Variable to define register data */ + uint8_t reg_data = 0; + + rslt = bmi2_get_regs(BMI2_GYR_OFF_COMP_6_ADDR, ®_data, 1, dev); + if (rslt == BMI2_OK) + { + reg_data = BMI2_SET_BITS(reg_data, BMI2_GYR_GAIN_EN, enable); + rslt = bmi2_set_regs(BMI2_GYR_OFF_COMP_6_ADDR, ®_data, 1, dev); + } + + return rslt; +} + +/*! + * @brief This internal API is used to extract the output feature configuration + * details from the look-up table. + */ +static uint8_t extract_output_feat_config(struct bmi2_feature_config *feat_output, + uint8_t type, + const struct bmi2_dev *dev) +{ + /* Variable to define loop */ + uint8_t loop = 0; + + /* Variable to set flag */ + uint8_t feat_found = BMI2_FALSE; + + /* Search for the output feature from the output configuration array */ + while (loop < dev->out_sens) + { + if (dev->feat_output[loop].type == type) + { + *feat_output = dev->feat_output[loop]; + feat_found = BMI2_TRUE; + break; + } + + loop++; + } + + /* Return flag */ + return feat_found; +} + +/*! + * @brief This internal API is used to move the data index ahead of the + * current_frame_length parameter when unnecessary FIFO data appears while + * extracting the user specified data. + */ +static int8_t move_next_frame(uint16_t *data_index, uint8_t current_frame_length, const struct bmi2_fifo_frame *fifo) +{ + /* Variables to define error */ + int8_t rslt = BMI2_OK; + + /* Validate data index */ + if (((*data_index) + current_frame_length) > fifo->length) + { + /* Move the data index to the last byte */ + (*data_index) = fifo->length; + + /* FIFO is empty */ + rslt = BMI2_W_FIFO_EMPTY; + } + else + { + /* Move the data index to next frame */ + (*data_index) = (*data_index) + current_frame_length; + + /* More frames could be read */ + rslt = BMI2_W_PARTIAL_READ; + } + + return rslt; +} diff --git a/bmi270_context.h b/bmi270_context.h index 2e7f97c..7078f23 100644 --- a/bmi270_context.h +++ b/bmi270_context.h @@ -1,40 +1,40 @@ /** - * 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 bmi270_context.h - * @date 2020-06-05 - * @version v2.53.2 - * - */ +* 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 bmi270_context.h +* @date 2020-11-04 +* @version v2.63.1 +* +*/ /** * \ingroup bmi2xy @@ -65,6 +65,7 @@ extern "C" { #define BMI270_CONTEXT_CHIP_ID UINT8_C(0x24) /*! @name BMI270_CONTEXT feature input start addresses */ +#define BMI270_CONTEXT_CONFIG_ID_STRT_ADDR UINT8_C(0x06) #define BMI270_CONTEXT_STEP_CNT_1_STRT_ADDR UINT8_C(0x00) #define BMI270_CONTEXT_STEP_CNT_4_STRT_ADDR UINT8_C(0x02) #define BMI270_CONTEXT_MAX_BURST_LEN_STRT_ADDR UINT8_C(0x08) @@ -84,7 +85,7 @@ extern "C" { #define BMI270_CONTEXT_MAX_PAGE_NUM UINT8_C(8) /*! @name Defines maximum number of feature input configurations */ -#define BMI270_CONTEXT_MAX_FEAT_IN UINT8_C(9) +#define BMI270_CONTEXT_MAX_FEAT_IN UINT8_C(10) /*! @name Defines maximum number of feature outputs */ #define BMI270_CONTEXT_MAX_FEAT_OUT UINT8_C(5) @@ -92,6 +93,13 @@ extern "C" { /*! @name Mask definitions for feature interrupt status bits */ #define BMI270_CONTEXT_STEP_CNT_STATUS_MASK UINT8_C(0x01) +/*! @name Mask definitions for feature interrupt mapping bits */ +#define BMI270_C_INT_STEP_COUNTER_MASK UINT8_C(0x01) +#define BMI270_C_INT_STEP_DETECTOR_MASK UINT8_C(0x01) + +/*! @name Defines maximum number of feature interrupts */ +#define BMI270_C_MAX_INT_MAP UINT8_C(2) + /***************************************************************************/ /*! BMI270_CONTEXT User Interface function prototypes @@ -119,14 +127,362 @@ extern "C" { * @param[in, out] dev : Structure instance of bmi2_dev. * * @return Result of API execution status - * - * @retval BMI2_OK - Success - * @retval BMI2_E_NULL_PTR - Error: Null pointer error - * @retval BMI2_E_COM_FAIL - Error: Communication fail - * @retval BMI2_E_DEV_NOT_FOUND - Invalid device + * @retval 0 -> Success + * @retval < 0 -> Fail */ int8_t bmi270_context_init(struct bmi2_dev *dev); +/** + * \ingroup bmi270_context + * \defgroup bmi270_contextApiSensor Feature Set + * @brief Enable / Disable features of the sensor + */ + +/*! + * \ingroup bmi270_contextApiSensor + * \page bmi270_context_api_bmi270_context_sensor_enable bmi270_context_sensor_enable + * \code + * int8_t bmi270_context_sensor_enable(const uint8_t *sens_list, uint8_t n_sens, struct bmi2_dev *dev); + * \endcode + * @details This API selects the sensors/features to be enabled. + * + * @param[in] sens_list : Pointer to select the sensor/feature. + * @param[in] n_sens : Number of sensors selected. + * @param[in, out] dev : Structure instance of bmi2_dev. + * + * @note Sensors/features that can be enabled. + * + *@verbatim + * sens_list | Values + * ----------------------------|----------- + * BMI2_ACCEL | 0 + * BMI2_GYRO | 1 + * BMI2_AUX | 2 + * BMI2_STEP_DETECTOR | 6 + * BMI2_STEP_COUNTER | 7 + * BMI2_GYRO_GAIN_UPDATE | 9 + * BMI2_ACTIVITY_RECOGNITION | 34 + *@endverbatim + * + * @note : + * example uint8_t sens_list[2] = {BMI2_ACCEL, BMI2_GYRO}; + * uint8_t n_sens = 2; + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +int8_t bmi270_context_sensor_enable(const uint8_t *sens_list, uint8_t n_sens, struct bmi2_dev *dev); + +/*! + * \ingroup bmi270_contextApiSensor + * \page bmi270_context_api_bmi270_context_sensor_disable bmi270_context_sensor_disable + * \code + * int8_t bmi270_context_sensor_disable(const uint8_t *sens_list, uint8_t n_sens, struct bmi2_dev *dev); + * \endcode + * @details This API selects the sensors/features to be disabled. + * + * @param[in] sens_list : Pointer to select the sensor/feature. + * @param[in] n_sens : Number of sensors selected. + * @param[in, out] dev : Structure instance of bmi2_dev. + * + * @note Sensors/features that can be disabled. + * + *@verbatim + * sens_list | Values + * ----------------------------|----------- + * BMI2_ACCEL | 0 + * BMI2_GYRO | 1 + * BMI2_AUX | 2 + * BMI2_STEP_DETECTOR | 6 + * BMI2_STEP_COUNTER | 7 + * BMI2_GYRO_GAIN_UPDATE | 9 + * BMI2_ACTIVITY_RECOGNITION | 34 + *@endverbatim + * + * @note : + * example uint8_t sens_list[2] = {BMI2_ACCEL, BMI2_GYRO}; + * uint8_t n_sens = 2; + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +int8_t bmi270_context_sensor_disable(const uint8_t *sens_list, uint8_t n_sens, struct bmi2_dev *dev); + +/** + * \ingroup bmi270_context + * \defgroup bmi270_contextApiSensorC Sensor Configuration + * @brief Enable / Disable feature configuration of the sensor + */ + +/*! + * \ingroup bmi270_contextApiSensorC + * \page bmi270_context_api_bmi270_context_set_sensor_config bmi270_context_set_sensor_config + * \code + * int8_t bmi270_context_set_sensor_config(struct bmi2_sens_config *sens_cfg, uint8_t n_sens, struct bmi2_dev *dev); + * \endcode + * @details This API sets the sensor/feature configuration. + * + * @param[in] sens_cfg : Structure instance of bmi2_sens_config. + * @param[in] n_sens : Number of sensors selected. + * @param[in, out] dev : Structure instance of bmi2_dev. + * + * @note Sensors/features that can be configured + * + *@verbatim + * sens_list | Values + * ----------------------------|----------- + * BMI2_STEP_DETECTOR | 6 + * BMI2_STEP_COUNTER | 7 + * BMI2_STEP_COUNTER_PARAMS | 28 + *@endverbatim + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +int8_t bmi270_context_set_sensor_config(struct bmi2_sens_config *sens_cfg, uint8_t n_sens, struct bmi2_dev *dev); + +/*! + * \ingroup bmi270_contextApiSensorC + * \page bmi270_context_api_bmi270_context_get_sensor_config bmi270_context_get_sensor_config + * \code + * int8_t bmi270_context_get_sensor_config(struct bmi2_sens_config *sens_cfg, uint8_t n_sens, struct bmi2_dev *dev); + * \endcode + * @details This API gets the sensor/feature configuration. + * + * @param[in] sens_cfg : Structure instance of bmi2_sens_config. + * @param[in] n_sens : Number of sensors selected. + * @param[in, out] dev : Structure instance of bmi2_dev. + * + * @note Sensors/features whose configurations can be read. + * + *@verbatim + * sens_list | Values + * ----------------------------|----------- + * BMI2_STEP_DETECTOR | 6 + * BMI2_STEP_COUNTER | 7 + * BMI2_STEP_COUNTER_PARAMS | 28 + *@endverbatim + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +int8_t bmi270_context_get_sensor_config(struct bmi2_sens_config *sens_cfg, uint8_t n_sens, struct bmi2_dev *dev); + +/** + * \ingroup bmi270_context + * \defgroup bmi270_contextApiSensorD Sensor Data + * @brief Get sensor data + */ + +/*! + * \ingroup bmi270_contextApiSensorD + * \page bmi270_context_api_bmi270_context_get_sensor_data bmi270_context_get_sensor_data + * \code + * int8_t bmi270_context_get_sensor_data(struct bmi2_sensor_data *sensor_data, uint8_t n_sens, struct bmi2_dev *dev); + * \endcode + * @details This API gets the sensor/feature data for accelerometer, gyroscope, + * auxiliary sensor, step counter, high-g, gyroscope user-gain update, + * orientation, gyroscope cross sensitivity and error status for NVM and VFRM. + * + * @param[out] sensor_data : Structure instance of bmi2_sensor_data. + * @param[in] n_sens : Number of sensors selected. + * @param[in] dev : Structure instance of bmi2_dev. + * + * @note Sensors/features whose data can be read + * + *@verbatim + * sens_list | Values + * ---------------------|----------- + * BMI2_STEP_COUNTER | 7 + * BMI2_NVM_STATUS | 38 + * BMI2_VFRM_STATUS | 39 + *@endverbatim + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +int8_t bmi270_context_get_sensor_data(struct bmi2_sensor_data *sensor_data, uint8_t n_sens, struct bmi2_dev *dev); + +/** + * \ingroup bmi270_context + * \defgroup bmi270_contextApiARecog Activity recognition settings + * @brief Set / Get activity recognition settings of the sensor + */ + +/*! + * \ingroup bmi270_contextApiARecog + * \page bmi270_context_api_bmi270_context_get_act_recg_sett bmi270_context_get_act_recg_sett + * \code + * int8_t bmi270_context_get_act_recg_sett(struct bmi2_act_recg_sett *sett, struct bmi2_dev *dev); + * \endcode + * @details This api is used for retrieving the following activity recognition settings currently set. + * enable/disable post processing(0/1) by default -> 1(enable), + * Setting the min & max Gini's diversity index (GDI) threshold. min_GDI_tres(0-0XFFFF) by default ->(0x06e1) + * max_GDI_tres(0-0xFFFF) by default ->(0x0A66) + * buffer size for post processing. range (1-0x0A) default -> (0x0A) + * min segment confidence. range (1-0x0A) default -> (0x0A) + * + * @param[in] sett : Structure instance of bmi2_act_recg_sett. + * @param[in] dev : Structure instance of bmi2_dev. + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +int8_t bmi270_context_get_act_recg_sett(struct bmi2_act_recg_sett *sett, struct bmi2_dev *dev); + +/*! + * \ingroup bmi270_contextApiARecog + * \page bmi270_context_api_bmi270_context_set_act_recg_sett bmi270_context_set_act_recg_sett + * \code + * int8_t bmi270_context_set_act_recg_sett(const struct bmi2_act_recg_sett *sett, struct bmi2_dev *dev); + * \endcode + * @details This api is used for setting the following activity recognition settings + * enable/disable post processing(0/1) by default -> 1(enable), + * Setting the min & max Gini's diversity index (GDI) threshold. min_GDI_tres(0-0XFFFF) by default ->(0x06e1) + * max_GDI_tres(0-0xFFFF) by default ->(0x0A66) + * buffer size for post processing. range (1-0x0A) default -> (0x0A) + * min segment confidence. range (1-0x0A) default -> (0x0A) + * + * @param[in] sett : Structure instance of bmi2_act_recg_sett. + * @param[in] dev : Structure instance of bmi2_dev. + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +int8_t bmi270_context_set_act_recg_sett(const struct bmi2_act_recg_sett *sett, struct bmi2_dev *dev); + +/** + * \ingroup bmi270_contex + * \defgroup bmi270_contextApiactOut Activity Output + * @brief Activity output operations of the sensor + */ + +/*! + * \ingroup bmi270_contextApiactOut + * \page bmi270_context_api_bmi270_context_get_act_recog_output bmi270_context_get_act_recog_output + * \code + * int8_t bmi270_context_get_act_recog_output(struct bmi2_act_recog_output *act_recog, + * uint16_t *act_frm_len, + * struct bmi2_fifo_frame *fifo, + * const struct bmi2_dev *dev); + * + * \endcode + * @details This internal API is used to parse the activity output from the + * FIFO in header mode. + * + * @param[out] act_recog : Pointer to buffer where the parsed activity data + * bytes are stored. + * @param[in] act_frm_len : Number of activity frames parsed. + * @param[in] fifo : Structure instance of bmi2_fifo_frame. + * @param[in] dev : Structure instance of bmi2_dev. + * + * @verbatim + * ---------------------------------------------------------------------------- + * bmi2_act_rec_output | + * Structure parameters | Description + *--------------------------|-------------------------------------------------- + * time_stamp | time-stamp (expressed in 50Hz ticks) + * -------------------------|--------------------------------------------------- + * type | Type of activity + * -------------------------|--------------------------------------------------- + * stat | Activity status + * -------------------------|--------------------------------------------------- + * @endverbatim + * + *@verbatim + * type | Activities + *----------|--------------------- + * 0 | UNKNOWN + * 1 | STILL + * 2 | WALK + * 3 | RUN + * 4 | BIKE + * 5 | VEHICLE + * 6 | TILTED + *@endverbatim + * + * + *@verbatim + * stat | Activity status + *----------|--------------------- + * 1 | START + * 2 | END + *@endverbatim + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +int8_t bmi270_context_get_act_recog_output(struct bmi2_act_recog_output *act_recog, + uint16_t *act_frm_len, + struct bmi2_fifo_frame *fifo, + const struct bmi2_dev *dev); + +/** + * \ingroup bmi270_contex + * \defgroup bmi270_contextApiGyroUG Gyro User Gain + * @brief Set / Get Gyro User Gain of the sensor + */ + +/*! + * \ingroup bmi270_contextApiGyroUG + * \page bmi270_context_api_bmi270_context_update_gyro_user_gain bmi270_context_update_gyro_user_gain + * \code + * int8_t bmi270_context_update_gyro_user_gain(const struct bmi2_gyro_user_gain_config *user_gain, struct bmi2_dev *dev); + * \endcode + * @details This API updates the gyroscope user-gain. + * + * @param[in] user_gain : Structure that stores user-gain configurations. + * @param[in] dev : Structure instance of bmi2_dev. + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +int8_t bmi270_context_update_gyro_user_gain(const struct bmi2_gyro_user_gain_config *user_gain, struct bmi2_dev *dev); + +/*! + * \ingroup bmi270_contextApiGyroUG + * \page bmi270_context_api_bmi270_context_read_gyro_user_gain bmi270_context_read_gyro_user_gain + * \code + * int8_t bmi270_context_read_gyro_user_gain(struct bmi2_gyro_user_gain_data *gyr_usr_gain, const struct bmi2_dev *dev); + * \endcode + * @details This API reads the compensated gyroscope user-gain values. + * + * @param[out] gyr_usr_gain : Structure that stores gain values. + * @param[in] dev : Structure instance of bmi2_dev. + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +int8_t bmi270_context_read_gyro_user_gain(struct bmi2_gyro_user_gain_data *gyr_usr_gain, struct bmi2_dev *dev); + +/*! + * \ingroup bmi270_contextApiInt + * \page bmi270_context_api_bmi270_context_map_feat_int bmi270_context_map_feat_int + * \code + * int8_t bmi270_context_map_feat_int(const struct bmi2_sens_int_config *sens_int, uint8_t n_sens, struct bmi2_dev *dev) + * \endcode + * @details This API maps/unmaps feature interrupts to that of interrupt pins. + * + * @param[in] sens_int : Structure instance of bmi2_sens_int_config. + * @param[in] n_sens : Number of interrupts to be mapped. + * @param[in] dev : Structure instance of bmi2_dev. + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +int8_t bmi270_context_map_feat_int(const struct bmi2_sens_int_config *sens_int, uint8_t n_sens, struct bmi2_dev *dev); + /******************************************************************************/ /*! @name C++ Guard Macros */ /******************************************************************************/ diff --git a/bmi270_hc.c b/bmi270_hc.c new file mode 100644 index 0000000..a7c9172 --- /dev/null +++ b/bmi270_hc.c @@ -0,0 +1,3165 @@ +/** +* 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 bmi270_hc.c +* @date 2020-11-04 +* @version v2.63.1 +* +*/ + +/***************************************************************************/ + +/*! Header files + ****************************************************************************/ +#include "bmi270_hc.h" + +/***************************************************************************/ + +/*! Global Variable + ****************************************************************************/ + +/*! @name Global array that stores the configuration file of BMI270_huawei_context */ +const uint8_t bmi270_hc_config_file[] = { + 0xc8, 0x2e, 0x00, 0x2e, 0x80, 0x2e, 0x00, 0xb0, 0xc8, 0x2e, 0x00, 0x2e, 0xc8, 0x2e, 0x00, 0x2e, 0x80, 0x2e, 0xa8, + 0x03, 0x80, 0x2e, 0x91, 0x03, 0xc8, 0x2e, 0x00, 0x2e, 0x80, 0x2e, 0x7d, 0xb0, 0x50, 0x30, 0x21, 0x2e, 0x59, 0xf5, + 0x10, 0x30, 0x21, 0x2e, 0x6a, 0xf5, 0x80, 0x2e, 0xae, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x39, 0x01, 0x00, 0x22, + 0x00, 0x76, 0x00, 0x00, 0x10, 0x00, 0x10, 0xd1, 0x00, 0x72, 0xb3, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, + 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, + 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, + 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, + 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, + 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, + 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, + 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, + 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, + 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0xfd, 0x2d, 0xd0, 0x86, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x03, 0x00, 0x08, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x24, 0x22, 0x00, 0x80, 0x2e, 0x48, 0x02, 0x01, 0x2e, 0x49, 0xf1, 0x0b, + 0xbc, 0x10, 0x50, 0x0f, 0xb8, 0x00, 0x90, 0xfb, 0x7f, 0x07, 0x2f, 0x03, 0x2e, 0x21, 0xf2, 0x02, 0x31, 0x4a, 0x0a, + 0x23, 0x2e, 0x21, 0xf2, 0x09, 0x2c, 0x00, 0x30, 0x98, 0x2e, 0x0e, 0xc7, 0x03, 0x2e, 0x21, 0xf2, 0xf2, 0x3e, 0x4a, + 0x08, 0x23, 0x2e, 0x21, 0xf2, 0xfb, 0x6f, 0xf0, 0x5f, 0xb8, 0x2e, 0x13, 0x52, 0x00, 0x2e, 0x60, 0x40, 0x41, 0x40, + 0x0d, 0xbc, 0x98, 0xbc, 0xc0, 0x2e, 0x01, 0x0a, 0x0f, 0xb8, 0x43, 0x86, 0x25, 0x40, 0x04, 0x40, 0xd8, 0xbe, 0x2c, + 0x0b, 0x22, 0x11, 0x54, 0x42, 0x03, 0x80, 0x4b, 0x0e, 0xf6, 0x2f, 0xb8, 0x2e, 0x15, 0x50, 0x10, 0x50, 0x17, 0x52, + 0x05, 0x2e, 0x7e, 0x00, 0xfb, 0x7f, 0x00, 0x2e, 0x13, 0x40, 0x93, 0x42, 0x41, 0x0e, 0xfb, 0x2f, 0x98, 0x2e, 0xe0, + 0x03, 0x98, 0x2e, 0x87, 0xcf, 0x01, 0x2e, 0x8b, 0x00, 0x00, 0xb2, 0x08, 0x2f, 0x01, 0x2e, 0x69, 0xf7, 0xb1, 0x3f, + 0x01, 0x08, 0x01, 0x30, 0x23, 0x2e, 0x8b, 0x00, 0x21, 0x2e, 0x69, 0xf7, 0xfb, 0x6f, 0xf0, 0x5f, 0xb8, 0x2e, 0x98, + 0x00, 0xff, 0x3f, 0x00, 0x0c, 0xff, 0x0f, 0x00, 0x04, 0xc0, 0x00, 0x5b, 0xf5, 0x8f, 0x00, 0x1e, 0xf2, 0xfd, 0xf5, + 0x8d, 0x00, 0x95, 0x00, 0x95, 0x00, 0xe0, 0x00, 0x19, 0xf4, 0x66, 0xf5, 0x00, 0x18, 0xff, 0x00, 0x64, 0xf5, 0x9c, + 0x00, 0x81, 0x00, 0x83, 0x00, 0x7f, 0x00, 0xff, 0xfb, 0x21, 0x02, 0x00, 0x10, 0x00, 0x40, 0x3a, 0x0f, 0xeb, 0x00, + 0x7f, 0xff, 0xc2, 0xf5, 0x68, 0xf7, 0x34, 0x0f, 0x28, 0x0f, 0x2e, 0x0f, 0x80, 0x00, 0x4d, 0x0f, 0x58, 0xf7, 0x5b, + 0xf7, 0x50, 0x0f, 0x00, 0x80, 0xff, 0x7f, 0x86, 0x00, 0x3f, 0x0f, 0x52, 0x0f, 0xb3, 0xf1, 0x4c, 0x0f, 0x6c, 0xf7, + 0xb9, 0xf1, 0xc6, 0xf1, 0x00, 0xe0, 0x00, 0xff, 0xd1, 0xf5, 0x54, 0x0f, 0x57, 0x0f, 0xff, 0x03, 0x00, 0xfc, 0xf0, + 0x3f, 0xb9, 0x00, 0x2d, 0xf5, 0xca, 0xf5, 0x6d, 0x03, 0xf0, 0x07, 0xc3, 0x11, 0x1d, 0x08, 0x12, 0x08, 0xb7, 0x15, + 0x9c, 0x01, 0xed, 0x14, 0xc2, 0x53, 0xca, 0x10, 0xa2, 0x00, 0x74, 0x01, 0xba, 0x17, 0xb4, 0x56, 0xe8, 0x16, 0x9f, + 0x00, 0xd7, 0x13, 0x2f, 0x52, 0x8a, 0x51, 0x64, 0x01, 0xc6, 0x53, 0xf4, 0x0b, 0x06, 0x08, 0xfc, 0x57, 0xe3, 0x44, + 0xad, 0x55, 0x4c, 0x01, 0x62, 0x01, 0x0b, 0x08, 0xa0, 0x18, 0x39, 0x59, 0x56, 0x2b, 0x14, 0x01, 0x2a, 0x58, 0x5e, + 0x0c, 0xc1, 0x47, 0x16, 0x5a, 0xd2, 0x07, 0x2b, 0x21, 0x7f, 0x53, 0x03, 0x08, 0xca, 0x59, 0x1a, 0x0b, 0x5f, 0x57, + 0x36, 0x47, 0xa6, 0x17, 0x02, 0x01, 0x33, 0x49, 0xdd, 0x58, 0x71, 0x0c, 0x32, 0x08, 0xc6, 0x59, 0xd4, 0x42, 0x65, + 0x54, 0x15, 0x59, 0x64, 0x08, 0x0c, 0x08, 0x8c, 0x01, 0x98, 0x00, 0x0f, 0x48, 0x02, 0x58, 0x96, 0x0c, 0x1c, 0x43, + 0x77, 0x48, 0xe9, 0x00, 0x1e, 0x0c, 0xf5, 0x41, 0xf6, 0x46, 0x64, 0x51, 0x98, 0x41, 0xcc, 0x01, 0x66, 0x58, 0x70, + 0x45, 0x28, 0x21, 0xe7, 0x59, 0x22, 0x30, 0x00, 0x08, 0x71, 0x7d, 0x49, 0x01, 0x92, 0x02, 0xf5, 0xd6, 0xe8, 0x63, + 0x7a, 0xfa, 0x87, 0x05, 0x0f, 0xcb, 0xa3, 0x72, 0x37, 0xfc, 0xca, 0x03, 0x95, 0xc7, 0x2e, 0x6d, 0x39, 0xc4, 0xc8, + 0x3b, 0x91, 0x37, 0x29, 0x02, 0x9e, 0x01, 0x00, 0xf0, 0x33, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x2e, 0xd5, 0xb5, 0x80, 0x2e, 0x00, 0xc1, 0xfd, 0x2d, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x01, 0xd4, 0x7b, 0x3b, + 0x01, 0xdb, 0x7a, 0x04, 0x00, 0x3f, 0x7b, 0xcd, 0x6c, 0xc3, 0x04, 0x85, 0x09, 0xc3, 0x04, 0xec, 0xe6, 0x0c, 0x46, + 0x01, 0x00, 0x27, 0x00, 0x19, 0x00, 0x96, 0x00, 0xa0, 0x00, 0x01, 0x00, 0x0c, 0x00, 0xf0, 0x3c, 0x00, 0x01, 0x01, + 0x00, 0x03, 0x00, 0x01, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xe1, 0x06, 0x66, 0x0a, 0x0a, 0x00, 0x0a, 0x00, 0x5a, 0x8d, 0x33, + 0x73, 0xcd, 0x8c, 0x9a, 0x99, 0x71, 0x7d, 0xcd, 0x8c, 0xcd, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x50, 0x98, 0x2e, 0xbd, 0x0e, 0x50, 0x32, 0x98, 0x2e, + 0x48, 0x03, 0x10, 0x30, 0x21, 0x2e, 0x21, 0xf2, 0x00, 0x30, 0x00, 0x2e, 0x00, 0x2e, 0xd0, 0x2e, 0x00, 0x2e, 0x01, + 0x80, 0x06, 0xa2, 0xfb, 0x2f, 0x01, 0x2e, 0x9b, 0x00, 0x00, 0xb2, 0x10, 0x2f, 0x01, 0x2e, 0x18, 0x00, 0x00, 0xb2, + 0x0c, 0x2f, 0x01, 0x54, 0x03, 0x52, 0x01, 0x50, 0x98, 0x2e, 0xc2, 0xc0, 0x98, 0x2e, 0x0e, 0xb1, 0x01, 0x50, 0x98, + 0x2e, 0xdd, 0xb5, 0x10, 0x30, 0x21, 0x2e, 0x19, 0x00, 0x01, 0x2e, 0x86, 0x00, 0x04, 0xae, 0x0b, 0x2f, 0x01, 0x2e, + 0x9b, 0x00, 0x00, 0xb2, 0x07, 0x2f, 0x01, 0x52, 0x98, 0x2e, 0x74, 0x0e, 0x00, 0xb2, 0x02, 0x2f, 0x10, 0x30, 0x21, + 0x2e, 0x79, 0x00, 0x01, 0x2e, 0x79, 0x00, 0x00, 0x90, 0x90, 0x2e, 0x14, 0x03, 0x01, 0x2e, 0x89, 0x00, 0x00, 0xb2, + 0x04, 0x2f, 0x98, 0x2e, 0x15, 0x0e, 0x00, 0x30, 0x21, 0x2e, 0x7c, 0x00, 0x01, 0x2e, 0x7c, 0x00, 0x00, 0xb2, 0x12, + 0x2f, 0x01, 0x2e, 0x86, 0x00, 0x00, 0x90, 0x02, 0x2f, 0x98, 0x2e, 0x05, 0x0e, 0x09, 0x2d, 0x98, 0x2e, 0x5d, 0x0d, + 0x01, 0x2e, 0x86, 0x00, 0x04, 0x90, 0x02, 0x2f, 0x50, 0x32, 0x98, 0x2e, 0x48, 0x03, 0x00, 0x30, 0x21, 0x2e, 0x7c, + 0x00, 0x01, 0x2e, 0x78, 0x00, 0x00, 0xb2, 0x90, 0x2e, 0x2c, 0x03, 0x01, 0x2e, 0x78, 0x00, 0x81, 0x30, 0x01, 0x08, + 0x00, 0xb2, 0x61, 0x2f, 0x03, 0x2e, 0x24, 0x02, 0x01, 0x2e, 0x86, 0x00, 0x98, 0xbc, 0x98, 0xb8, 0x05, 0xb2, 0x0d, + 0x58, 0x23, 0x2f, 0x07, 0x90, 0x07, 0x54, 0x00, 0x30, 0x37, 0x2f, 0x15, 0x41, 0x04, 0x41, 0xdc, 0xbe, 0x44, 0xbe, + 0xdc, 0xba, 0x2c, 0x01, 0x61, 0x00, 0x0d, 0x56, 0x4a, 0x0f, 0x0c, 0x2f, 0xd1, 0x42, 0x94, 0xb8, 0xc1, 0x42, 0x11, + 0x30, 0x05, 0x2e, 0x6a, 0xf7, 0x2c, 0xbd, 0x2f, 0xb9, 0x80, 0xb2, 0x08, 0x22, 0x98, 0x2e, 0xa4, 0xb1, 0x21, 0x2d, + 0x61, 0x30, 0x23, 0x2e, 0x86, 0x00, 0x98, 0x2e, 0xa4, 0xb1, 0x00, 0x30, 0x21, 0x2e, 0x5a, 0xf5, 0x18, 0x2d, 0xf1, + 0x7f, 0x50, 0x30, 0x98, 0x2e, 0x48, 0x03, 0x0d, 0x52, 0x05, 0x50, 0x50, 0x42, 0x70, 0x30, 0x0b, 0x54, 0x42, 0x42, + 0x7e, 0x82, 0xf2, 0x6f, 0x80, 0xb2, 0x42, 0x42, 0x05, 0x2f, 0x21, 0x2e, 0x86, 0x00, 0x10, 0x30, 0x98, 0x2e, 0xa4, + 0xb1, 0x03, 0x2d, 0x60, 0x30, 0x21, 0x2e, 0x86, 0x00, 0x01, 0x2e, 0x86, 0x00, 0x06, 0x90, 0x18, 0x2f, 0x01, 0x2e, + 0x77, 0x00, 0x09, 0x54, 0x05, 0x52, 0xf0, 0x7f, 0x98, 0x2e, 0x7a, 0xc1, 0xf1, 0x6f, 0x08, 0x1a, 0x40, 0x30, 0x08, + 0x2f, 0x21, 0x2e, 0x86, 0x00, 0x20, 0x30, 0x98, 0x2e, 0xea, 0x03, 0x50, 0x32, 0x98, 0x2e, 0x48, 0x03, 0x05, 0x2d, + 0x98, 0x2e, 0x1e, 0x0e, 0x00, 0x30, 0x21, 0x2e, 0x86, 0x00, 0x00, 0x30, 0x21, 0x2e, 0x78, 0x00, 0x18, 0x2d, 0x01, + 0x2e, 0x86, 0x00, 0x03, 0xaa, 0x01, 0x2f, 0x98, 0x2e, 0x2b, 0x0e, 0x01, 0x2e, 0x86, 0x00, 0x3f, 0x80, 0x03, 0xa2, + 0x01, 0x2f, 0x00, 0x2e, 0x02, 0x2d, 0x98, 0x2e, 0x41, 0x0e, 0x30, 0x30, 0x98, 0x2e, 0xaf, 0xb1, 0x00, 0x30, 0x21, + 0x2e, 0x79, 0x00, 0x50, 0x32, 0x98, 0x2e, 0x48, 0x03, 0x01, 0x2e, 0x19, 0x00, 0x00, 0xb2, 0x10, 0x2f, 0x01, 0x2e, + 0x87, 0x00, 0x21, 0x2e, 0x8f, 0x00, 0x0f, 0x52, 0x7e, 0x82, 0x11, 0x50, 0x41, 0x40, 0x18, 0xb9, 0x11, 0x42, 0x02, + 0x42, 0x02, 0x80, 0x00, 0x2e, 0x01, 0x40, 0x01, 0x42, 0x98, 0x2e, 0xe1, 0x00, 0x00, 0x30, 0x21, 0x2e, 0x19, 0x00, + 0x21, 0x2e, 0x9b, 0x00, 0x80, 0x2e, 0x52, 0x02, 0x21, 0x2e, 0x59, 0xf5, 0x10, 0x30, 0xc0, 0x2e, 0x21, 0x2e, 0x4a, + 0xf1, 0x80, 0x2e, 0x00, 0xc1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9a, 0x01, + 0x34, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x20, 0x50, 0xe7, 0x7f, 0xf6, 0x7f, 0x46, 0x30, 0x0f, 0x2e, 0xa4, 0xf1, 0xbe, 0x09, 0x80, 0xb3, 0x06, + 0x2f, 0x0d, 0x2e, 0x86, 0x00, 0x84, 0xaf, 0x02, 0x2f, 0x16, 0x30, 0x2d, 0x2e, 0x7c, 0x00, 0x86, 0x30, 0x2d, 0x2e, + 0x60, 0xf5, 0xf6, 0x6f, 0xe7, 0x6f, 0xe0, 0x5f, 0xc8, 0x2e, 0xa0, 0x50, 0x80, 0x7f, 0xe7, 0x7f, 0xd5, 0x7f, 0xc4, + 0x7f, 0xb3, 0x7f, 0xa2, 0x7f, 0x91, 0x7f, 0xf6, 0x7f, 0x7b, 0x7f, 0x00, 0x2e, 0x01, 0x2e, 0x60, 0xf5, 0x60, 0x7f, + 0x98, 0x2e, 0xcd, 0x00, 0x62, 0x6f, 0x01, 0x32, 0x91, 0x08, 0x80, 0xb2, 0x0d, 0x2f, 0x00, 0xb2, 0x03, 0x2f, 0x05, + 0x2e, 0x18, 0x00, 0x80, 0x90, 0x05, 0x2f, 0x25, 0x56, 0x02, 0x30, 0xc1, 0x42, 0xc2, 0x86, 0x00, 0x2e, 0xc2, 0x42, + 0x23, 0x2e, 0x60, 0xf5, 0x00, 0x90, 0x00, 0x30, 0x06, 0x2f, 0x21, 0x2e, 0x7a, 0x00, 0x23, 0x50, 0x21, 0x2e, 0x5a, + 0xf2, 0x98, 0x2e, 0xfb, 0x01, 0xf6, 0x6f, 0x80, 0x6f, 0x91, 0x6f, 0xa2, 0x6f, 0xb3, 0x6f, 0xc4, 0x6f, 0xd5, 0x6f, + 0xe7, 0x6f, 0x7b, 0x6f, 0x60, 0x5f, 0xc8, 0x2e, 0x03, 0x2e, 0x7e, 0x00, 0x16, 0xb8, 0x02, 0x34, 0x4a, 0x0c, 0x21, + 0x2e, 0x2d, 0xf5, 0xc0, 0x2e, 0x23, 0x2e, 0x7e, 0x00, 0x03, 0xbc, 0x21, 0x2e, 0x87, 0x00, 0x03, 0x2e, 0x87, 0x00, + 0x40, 0xb2, 0x10, 0x30, 0x21, 0x2e, 0x19, 0x00, 0x01, 0x30, 0x05, 0x2f, 0x05, 0x2e, 0x8a, 0x00, 0x80, 0x90, 0x01, + 0x2f, 0x23, 0x2e, 0x6f, 0xf5, 0xc0, 0x2e, 0x21, 0x2e, 0x8b, 0x00, 0x80, 0x2e, 0x00, 0xc1, 0xc0, 0x50, 0xe7, 0x7f, + 0xf6, 0x7f, 0x26, 0x30, 0x0f, 0x2e, 0x61, 0xf5, 0x2f, 0x2e, 0x78, 0x00, 0x0f, 0x2e, 0x78, 0x00, 0xbe, 0x09, 0xa2, + 0x7f, 0x91, 0x7f, 0x80, 0x7f, 0x80, 0xb3, 0xd5, 0x7f, 0xc4, 0x7f, 0xb3, 0x7f, 0x7b, 0x7f, 0x11, 0x2f, 0x19, 0x50, + 0x1a, 0x25, 0x12, 0x40, 0x42, 0x7f, 0x74, 0x82, 0x12, 0x40, 0x52, 0x7f, 0x00, 0x2e, 0x00, 0x40, 0x60, 0x7f, 0x98, + 0x2e, 0x6a, 0xd6, 0x01, 0x2e, 0x61, 0xf7, 0x01, 0x31, 0x01, 0x0a, 0x21, 0x2e, 0x61, 0xf7, 0x80, 0x30, 0x03, 0x2e, + 0x78, 0x00, 0x08, 0x08, 0x00, 0xb2, 0x42, 0x2f, 0x03, 0x2e, 0x24, 0x02, 0x01, 0x2e, 0x24, 0x02, 0x97, 0xbc, 0x06, + 0xbc, 0x9f, 0xb8, 0x0f, 0xb8, 0x00, 0x90, 0x23, 0x2e, 0x8a, 0x00, 0x10, 0x30, 0x01, 0x30, 0x2a, 0x2f, 0x03, 0x2e, + 0x86, 0x00, 0x44, 0xb2, 0x05, 0x2f, 0x47, 0xb2, 0x00, 0x30, 0x2d, 0x2f, 0x21, 0x2e, 0x78, 0x00, 0x2b, 0x2d, 0x03, + 0x2e, 0xfd, 0xf5, 0x9e, 0xbc, 0x9f, 0xb8, 0x40, 0x90, 0x14, 0x2f, 0x03, 0x2e, 0xfc, 0xf5, 0x99, 0xbc, 0x9f, 0xb8, + 0x40, 0x90, 0x0e, 0x2f, 0x03, 0x2e, 0x49, 0xf1, 0x1b, 0x54, 0x4a, 0x08, 0x40, 0x90, 0x08, 0x2f, 0x98, 0x2e, 0xcd, + 0x00, 0x00, 0xb2, 0x10, 0x30, 0x03, 0x2f, 0x50, 0x30, 0x21, 0x2e, 0x86, 0x00, 0x10, 0x2d, 0x98, 0x2e, 0xea, 0x03, + 0x00, 0x30, 0x21, 0x2e, 0x78, 0x00, 0x0a, 0x2d, 0x05, 0x2e, 0x69, 0xf7, 0x2d, 0xbd, 0x2f, 0xb9, 0x80, 0xb2, 0x01, + 0x2f, 0x21, 0x2e, 0x79, 0x00, 0x23, 0x2e, 0x78, 0x00, 0xe0, 0x31, 0x21, 0x2e, 0x61, 0xf5, 0xf6, 0x6f, 0xe7, 0x6f, + 0x80, 0x6f, 0xa2, 0x6f, 0xb3, 0x6f, 0xc4, 0x6f, 0xd5, 0x6f, 0x7b, 0x6f, 0x91, 0x6f, 0x40, 0x5f, 0xc8, 0x2e, 0x90, + 0x50, 0xf7, 0x7f, 0xe6, 0x7f, 0xd5, 0x7f, 0xc4, 0x7f, 0xb3, 0x7f, 0xa1, 0x7f, 0x90, 0x7f, 0x82, 0x7f, 0x7b, 0x7f, + 0x98, 0x2e, 0xcd, 0x00, 0x00, 0xb2, 0x12, 0x30, 0x5c, 0x2f, 0x01, 0x2e, 0x21, 0x02, 0x03, 0x2e, 0x28, 0x02, 0x9f, + 0xbc, 0x9f, 0xb8, 0x21, 0x56, 0x8a, 0x08, 0x03, 0x08, 0x82, 0x0a, 0x25, 0x2e, 0x18, 0x00, 0x05, 0x2e, 0xc1, 0xf5, + 0x2e, 0xbc, 0x05, 0x2e, 0x86, 0x00, 0x84, 0xa2, 0x0e, 0xb8, 0x31, 0x30, 0x88, 0x04, 0x07, 0x2f, 0x01, 0x2e, 0x18, + 0x00, 0x00, 0x90, 0x03, 0x2f, 0x01, 0x2e, 0x7b, 0x00, 0x00, 0xb2, 0x19, 0x2f, 0x1d, 0x50, 0x01, 0x52, 0x98, 0x2e, + 0xd6, 0x00, 0x05, 0x2e, 0x7a, 0x00, 0x25, 0x2e, 0x9b, 0x00, 0x05, 0x2e, 0x7a, 0x00, 0x80, 0x90, 0x02, 0x2f, 0x12, + 0x30, 0x25, 0x2e, 0x7a, 0x00, 0x01, 0x2e, 0x7b, 0x00, 0x00, 0xb2, 0x05, 0x2e, 0x18, 0x00, 0x02, 0x2f, 0x10, 0x30, + 0x21, 0x2e, 0x18, 0x00, 0x25, 0x2e, 0x7b, 0x00, 0x05, 0x2e, 0x18, 0x00, 0x80, 0xb2, 0x20, 0x2f, 0x01, 0x2e, 0xc0, + 0xf5, 0xf2, 0x30, 0x02, 0x08, 0x07, 0xaa, 0x73, 0x30, 0x03, 0x2e, 0x7d, 0x00, 0x18, 0x22, 0x41, 0x1a, 0x05, 0x2f, + 0x03, 0x2e, 0x66, 0xf5, 0x9f, 0xbc, 0x9f, 0xb8, 0x40, 0x90, 0x0c, 0x2f, 0x1f, 0x52, 0x03, 0x30, 0x53, 0x42, 0x2b, + 0x30, 0x90, 0x04, 0x5b, 0x42, 0x21, 0x2e, 0x7d, 0x00, 0x24, 0xbd, 0x7e, 0x80, 0x81, 0x84, 0x43, 0x42, 0x02, 0x42, + 0x02, 0x32, 0x25, 0x2e, 0x62, 0xf5, 0x05, 0x2e, 0x88, 0x00, 0x81, 0x84, 0x25, 0x2e, 0x88, 0x00, 0x02, 0x31, 0x25, + 0x2e, 0x60, 0xf5, 0x05, 0x2e, 0x25, 0x02, 0x10, 0x30, 0x90, 0x08, 0x80, 0xb2, 0x0b, 0x2f, 0x05, 0x2e, 0xca, 0xf5, + 0xf0, 0x3e, 0x90, 0x08, 0x25, 0x2e, 0xca, 0xf5, 0x05, 0x2e, 0x59, 0xf5, 0xe0, 0x3f, 0x90, 0x08, 0x25, 0x2e, 0x59, + 0xf5, 0x90, 0x6f, 0xa1, 0x6f, 0xb3, 0x6f, 0xc4, 0x6f, 0xd5, 0x6f, 0xe6, 0x6f, 0xf7, 0x6f, 0x7b, 0x6f, 0x82, 0x6f, + 0x70, 0x5f, 0xc8, 0x2e, 0x31, 0x50, 0xe0, 0x50, 0x12, 0x40, 0x06, 0x40, 0x1a, 0x25, 0x77, 0x88, 0x75, 0x8a, 0x21, + 0x56, 0x6c, 0xbf, 0x00, 0x30, 0xd3, 0x08, 0x6c, 0xbb, 0x60, 0x7f, 0x00, 0x43, 0x40, 0x43, 0xc0, 0xb2, 0xd6, 0x7f, + 0xe5, 0x7f, 0xf4, 0x7f, 0xc3, 0x7f, 0xbb, 0x7f, 0x74, 0x2f, 0x01, 0x2e, 0x85, 0x00, 0x00, 0xb2, 0x0b, 0x2f, 0x27, + 0x52, 0x01, 0x2e, 0x80, 0x00, 0xa2, 0x7f, 0x98, 0x2e, 0xbb, 0xcc, 0x01, 0x30, 0x23, 0x2e, 0x85, 0x00, 0xa2, 0x6f, + 0xc3, 0x6f, 0x1a, 0x25, 0x26, 0xbc, 0x86, 0xba, 0x25, 0xbc, 0x0f, 0xb8, 0x54, 0xb1, 0x00, 0xb2, 0xa6, 0x7f, 0x0c, + 0x2f, 0x29, 0x50, 0x2b, 0x54, 0x0b, 0x30, 0x0b, 0x2e, 0x21, 0x02, 0x2f, 0x58, 0x1b, 0x42, 0x9b, 0x42, 0x6c, 0x09, + 0x0b, 0x42, 0x2b, 0x2e, 0x21, 0x02, 0x8b, 0x42, 0x72, 0x84, 0x33, 0x50, 0x58, 0x09, 0x03, 0x52, 0x01, 0x50, 0x92, + 0x7f, 0x85, 0x7f, 0x98, 0x2e, 0xc2, 0xc0, 0x01, 0x2e, 0x80, 0x00, 0xf5, 0x6f, 0xe4, 0x6f, 0x83, 0x6f, 0x92, 0x6f, + 0x27, 0x52, 0x2d, 0x5c, 0x98, 0x2e, 0x06, 0xcd, 0xc3, 0x6f, 0x29, 0x50, 0x72, 0x6f, 0xb4, 0xbc, 0x14, 0x40, 0x80, + 0xb2, 0x9f, 0xba, 0x02, 0x40, 0x01, 0x30, 0xf0, 0x7f, 0x05, 0x2f, 0x40, 0xb3, 0x03, 0x2f, 0x2b, 0x5c, 0x11, 0x30, + 0x94, 0x43, 0x82, 0x43, 0xb3, 0xbd, 0xbf, 0xb9, 0xc0, 0xb2, 0x1c, 0x2f, 0x53, 0x6f, 0x23, 0x01, 0x63, 0x6f, 0x93, + 0x02, 0x02, 0x42, 0x40, 0x91, 0x29, 0x2e, 0x81, 0x00, 0x2b, 0x50, 0x12, 0x2f, 0x2b, 0x56, 0x00, 0x2e, 0xd5, 0x40, + 0xc3, 0x40, 0x65, 0x05, 0xd3, 0x06, 0xc0, 0xaa, 0x04, 0x2f, 0xc0, 0x90, 0x08, 0x2f, 0xa3, 0x6f, 0x5d, 0x0f, 0x05, + 0x2f, 0xa5, 0x6f, 0x40, 0xb3, 0x02, 0x2f, 0x14, 0x42, 0x02, 0x42, 0x11, 0x30, 0xd0, 0x6f, 0x98, 0x2e, 0x95, 0xcf, + 0xf2, 0x6f, 0x15, 0x52, 0x01, 0x2e, 0x81, 0x00, 0x82, 0x40, 0x50, 0x42, 0x08, 0x2c, 0x42, 0x42, 0x11, 0x30, 0x23, + 0x2e, 0x85, 0x00, 0x01, 0x30, 0xd0, 0x6f, 0x98, 0x2e, 0x95, 0xcf, 0x00, 0x2e, 0xbb, 0x6f, 0x20, 0x5f, 0xb8, 0x2e, + 0x11, 0x30, 0x81, 0x08, 0x01, 0x2e, 0x6a, 0xf7, 0x71, 0x3f, 0x23, 0xbd, 0x01, 0x08, 0x02, 0x0a, 0xc0, 0x2e, 0x21, + 0x2e, 0x6a, 0xf7, 0x30, 0x25, 0x00, 0x30, 0x21, 0x2e, 0x5a, 0xf5, 0x10, 0x50, 0x21, 0x2e, 0x7c, 0x00, 0x21, 0x2e, + 0x78, 0x00, 0xfb, 0x7f, 0x98, 0x2e, 0xa4, 0xb1, 0x40, 0x30, 0x21, 0x2e, 0x86, 0x00, 0xfb, 0x6f, 0xf0, 0x5f, 0x03, + 0x25, 0x80, 0x2e, 0xea, 0x03, 0x51, 0x56, 0x05, 0x40, 0x69, 0x18, 0x0d, 0x17, 0xe1, 0x18, 0x19, 0x05, 0x16, 0x25, + 0x37, 0x25, 0x4a, 0x17, 0x54, 0x18, 0xec, 0x18, 0x04, 0x30, 0x64, 0x07, 0xea, 0x18, 0x8e, 0x00, 0x5f, 0x02, 0x35, + 0x56, 0x93, 0x00, 0x4c, 0x02, 0x2f, 0xb9, 0x91, 0xbc, 0x91, 0x0a, 0x02, 0x42, 0xb8, 0x2e, 0x0b, 0x00, 0x40, 0xb3, + 0x94, 0x02, 0x0b, 0x2f, 0x50, 0xa1, 0x03, 0x2f, 0x70, 0x8b, 0x85, 0x14, 0x07, 0x2c, 0x00, 0x30, 0x04, 0x31, 0x25, + 0x05, 0x04, 0x13, 0x95, 0x14, 0x05, 0x14, 0x94, 0x0a, 0x47, 0x5a, 0x45, 0x01, 0x04, 0x30, 0x94, 0x02, 0xd8, 0xba, + 0xc0, 0x2e, 0x28, 0xbd, 0x2a, 0x0a, 0x4a, 0x18, 0x00, 0x30, 0xc1, 0x18, 0x6f, 0xb8, 0xc0, 0x2e, 0xf1, 0xbc, 0x01, + 0x0a, 0x4e, 0x86, 0x80, 0x40, 0x70, 0x50, 0xd1, 0x40, 0x86, 0x84, 0xf0, 0x7f, 0x84, 0x30, 0xce, 0x8a, 0xe2, 0x7f, + 0x20, 0x04, 0x54, 0x41, 0xc2, 0x40, 0x4c, 0x04, 0x43, 0x41, 0x93, 0x06, 0x49, 0x18, 0x03, 0x31, 0xd8, 0x04, 0x30, + 0x88, 0xd1, 0x18, 0xd4, 0x7f, 0x00, 0xb2, 0x72, 0x8b, 0xd1, 0x18, 0xc3, 0x7f, 0xbb, 0x7f, 0x0a, 0x2f, 0x10, 0xa0, + 0x03, 0x2f, 0xd1, 0x6f, 0xb9, 0x13, 0x06, 0x2c, 0x07, 0x30, 0xc1, 0x6f, 0x79, 0x14, 0xb0, 0x12, 0xf8, 0x13, 0x91, + 0x0b, 0x51, 0x41, 0x4e, 0x85, 0x00, 0xb2, 0x94, 0x40, 0xb2, 0x86, 0x82, 0x40, 0x26, 0x01, 0xa3, 0x7f, 0x97, 0x02, + 0x43, 0x41, 0x4c, 0x00, 0x9a, 0x02, 0x0a, 0x2f, 0x10, 0xa0, 0x03, 0x2f, 0xd1, 0x6f, 0x51, 0x12, 0x06, 0x2c, 0x02, + 0x30, 0xc3, 0x6f, 0xd3, 0x14, 0x48, 0x12, 0x90, 0x12, 0x4b, 0x0a, 0x98, 0x2e, 0x79, 0xc0, 0xa1, 0x6f, 0x4f, 0x8a, + 0x72, 0x8d, 0x43, 0x41, 0x42, 0x40, 0xf5, 0x6f, 0xab, 0xbc, 0x35, 0xba, 0x25, 0xb9, 0xbb, 0xbd, 0xf0, 0x7f, 0x75, + 0x25, 0x98, 0x2e, 0xdb, 0xb1, 0xd0, 0x7f, 0x57, 0x25, 0x91, 0x41, 0x8e, 0x81, 0x82, 0x41, 0x13, 0x40, 0x04, 0x40, + 0x32, 0x8c, 0x98, 0x2e, 0xdb, 0xb1, 0xc0, 0x7f, 0x57, 0x25, 0x91, 0x41, 0x8e, 0x81, 0x82, 0x41, 0x13, 0x40, 0x04, + 0x40, 0x32, 0x8c, 0x98, 0x2e, 0xdb, 0xb1, 0xa0, 0x7f, 0x57, 0x25, 0x91, 0x41, 0x8e, 0x81, 0x82, 0x41, 0x13, 0x40, + 0x04, 0x40, 0x32, 0x8c, 0x98, 0x2e, 0xdb, 0xb1, 0x90, 0x7f, 0x57, 0x25, 0x91, 0x41, 0x8e, 0x81, 0x82, 0x41, 0x13, + 0x40, 0x04, 0x40, 0x32, 0x8c, 0x98, 0x2e, 0xdb, 0xb1, 0x57, 0x25, 0x91, 0x41, 0x8e, 0x89, 0xe7, 0x6f, 0x13, 0x41, + 0x82, 0x41, 0x04, 0x41, 0xe0, 0x7f, 0x98, 0x2e, 0xdb, 0xb1, 0x57, 0x25, 0xf1, 0x6f, 0x52, 0x41, 0xf0, 0x7f, 0x98, + 0x2e, 0xf3, 0xb1, 0xd1, 0x6f, 0x52, 0x41, 0x30, 0x25, 0x98, 0x2e, 0xf3, 0xb1, 0xc1, 0x6f, 0x52, 0x41, 0xd0, 0x7f, + 0x98, 0x2e, 0xf3, 0xb1, 0xa1, 0x6f, 0x52, 0x41, 0xc0, 0x7f, 0x98, 0x2e, 0xf3, 0xb1, 0x91, 0x6f, 0x52, 0x41, 0xa0, + 0x7f, 0x98, 0x2e, 0xf3, 0xb1, 0xe1, 0x6f, 0x52, 0x41, 0x40, 0x25, 0x98, 0x2e, 0xf3, 0xb1, 0x70, 0x25, 0x42, 0x41, + 0xf1, 0x6f, 0x57, 0x25, 0x98, 0x2e, 0xf3, 0xb1, 0x7b, 0x52, 0xd9, 0x0f, 0x90, 0x2e, 0x70, 0xb3, 0x81, 0x32, 0x69, + 0x0e, 0x06, 0x2f, 0x01, 0x32, 0x41, 0x0e, 0x0d, 0x53, 0x0f, 0x55, 0x0a, 0x22, 0x80, 0x2e, 0x71, 0xb3, 0x51, 0x34, + 0x59, 0x0e, 0xd1, 0x6f, 0xc2, 0x6f, 0x90, 0x2e, 0x4f, 0xb3, 0x99, 0x5e, 0x57, 0x0e, 0x7c, 0x2f, 0xaf, 0x5e, 0x4f, + 0x0e, 0x4d, 0x2f, 0x02, 0xa2, 0x2f, 0x2f, 0xe9, 0x50, 0x60, 0x0e, 0x06, 0x2f, 0x07, 0x55, 0x4a, 0x0e, 0x09, 0x53, + 0x0b, 0x55, 0x0a, 0x22, 0x80, 0x2e, 0x71, 0xb3, 0xeb, 0x50, 0x60, 0x0e, 0x10, 0x2f, 0xfb, 0x52, 0xd1, 0x0f, 0x0a, + 0x2f, 0x45, 0xa3, 0x01, 0x53, 0x03, 0x55, 0x4a, 0x22, 0xa2, 0x6f, 0xfd, 0x50, 0x50, 0x0e, 0xff, 0x54, 0x11, 0x22, + 0x80, 0x2e, 0x71, 0xb3, 0x05, 0x51, 0x80, 0x2e, 0x71, 0xb3, 0xed, 0x54, 0x4a, 0x0e, 0x07, 0x2f, 0xa1, 0x6f, 0xf5, + 0x54, 0x4a, 0x0e, 0xf7, 0x52, 0xf9, 0x54, 0x0a, 0x22, 0x80, 0x2e, 0x71, 0xb3, 0xef, 0x52, 0x59, 0x0e, 0xf1, 0x52, + 0xf3, 0x54, 0x0a, 0x22, 0x80, 0x2e, 0x71, 0xb3, 0xcb, 0x52, 0x61, 0x0e, 0x0e, 0x2f, 0xa1, 0x6f, 0xdd, 0x54, 0xca, + 0x0f, 0x08, 0x2f, 0x01, 0xa2, 0xe1, 0x52, 0xe3, 0x54, 0x4a, 0x22, 0xdf, 0x54, 0x62, 0x0e, 0xe5, 0x54, 0x77, 0x2c, + 0x0a, 0x22, 0x75, 0x2c, 0xe7, 0x50, 0xd7, 0x52, 0x51, 0x0e, 0xd9, 0x52, 0xdb, 0x54, 0x4a, 0x22, 0x72, 0x35, 0x5a, + 0x0e, 0xd5, 0x54, 0x6b, 0x2c, 0x11, 0x22, 0xb1, 0x56, 0x53, 0x0e, 0x0a, 0x2f, 0xa1, 0x6f, 0xcf, 0x54, 0x4a, 0x0e, + 0xd1, 0x52, 0xd3, 0x54, 0x4a, 0x22, 0xcb, 0x54, 0x62, 0x0e, 0xcd, 0x54, 0x5d, 0x2c, 0x11, 0x22, 0x0c, 0xa2, 0x05, + 0x2f, 0xc5, 0x52, 0x61, 0x0e, 0xc7, 0x52, 0xc9, 0x54, 0x55, 0x2c, 0x0a, 0x22, 0xb3, 0x54, 0x62, 0x0e, 0x0a, 0x2f, + 0xa2, 0x6f, 0xbf, 0x50, 0x50, 0x0e, 0xc1, 0x54, 0xc3, 0x50, 0x90, 0x22, 0xbb, 0x50, 0x48, 0x0e, 0xbd, 0x52, 0x47, + 0x2c, 0x0a, 0x22, 0x43, 0xa3, 0xb5, 0x52, 0xb7, 0x54, 0x4a, 0x22, 0x54, 0xa3, 0xb9, 0x54, 0x3f, 0x2c, 0x0a, 0x22, + 0x41, 0xa3, 0x14, 0x2f, 0xa0, 0x37, 0x50, 0x0e, 0x0f, 0x2f, 0xa1, 0x54, 0x4a, 0x0e, 0x0a, 0x2f, 0xa7, 0x52, 0x61, + 0x0e, 0xa9, 0x52, 0xab, 0x54, 0x4a, 0x22, 0xa2, 0x6f, 0xa5, 0x50, 0x50, 0x0e, 0xad, 0x54, 0x2c, 0x2c, 0x0a, 0x22, + 0x2a, 0x2c, 0xa3, 0x50, 0x28, 0x2c, 0x9f, 0x50, 0x01, 0xa2, 0x9b, 0x52, 0x9d, 0x54, 0x23, 0x2c, 0x0a, 0x22, 0x20, + 0x33, 0x58, 0x0e, 0x09, 0x2f, 0x91, 0x50, 0x48, 0x0e, 0x93, 0x52, 0x95, 0x50, 0x48, 0x22, 0x8f, 0x50, 0x50, 0x0e, + 0x97, 0x54, 0x16, 0x2c, 0x0a, 0x22, 0x7d, 0x54, 0x62, 0x0e, 0x0e, 0x2f, 0x81, 0x54, 0xe2, 0x0f, 0x09, 0x2f, 0x87, + 0x54, 0x4a, 0x0e, 0x89, 0x52, 0x8b, 0x54, 0x4a, 0x22, 0x83, 0x54, 0x62, 0x0e, 0x85, 0x54, 0x06, 0x2c, 0x11, 0x22, + 0x04, 0x2c, 0x8d, 0x50, 0x02, 0x2c, 0x7f, 0x50, 0x11, 0x51, 0xbb, 0x6f, 0x90, 0x5f, 0xb8, 0x2e, 0x32, 0x25, 0xb0, + 0x51, 0xc2, 0x32, 0x82, 0x00, 0xe0, 0x7f, 0xd2, 0x7f, 0x04, 0x30, 0x80, 0x40, 0x01, 0x80, 0x90, 0x42, 0xc2, 0x7f, + 0x10, 0x30, 0x85, 0x40, 0x2c, 0x03, 0x94, 0x42, 0x4a, 0x25, 0x85, 0x40, 0x28, 0x28, 0x80, 0x42, 0x25, 0x3d, 0xc3, + 0x80, 0x2b, 0x89, 0x95, 0x00, 0x81, 0x7f, 0xb2, 0x7f, 0xa4, 0x7f, 0x90, 0x7f, 0x7b, 0x7f, 0x00, 0x2e, 0xd1, 0x40, + 0x03, 0x54, 0x53, 0x7f, 0x64, 0x7f, 0x98, 0x2e, 0xd9, 0xc0, 0x64, 0x6f, 0x53, 0x6f, 0x91, 0x6f, 0x10, 0x43, 0x59, + 0x0e, 0xf3, 0x2f, 0xa1, 0x6f, 0x98, 0x2e, 0xb3, 0xc0, 0xb1, 0x6f, 0x13, 0x33, 0x40, 0x42, 0x00, 0xac, 0xcb, 0x00, + 0x02, 0x2f, 0xe1, 0x6f, 0x53, 0x54, 0x42, 0x42, 0xd1, 0x3d, 0x59, 0x00, 0xc3, 0x40, 0xcf, 0xb0, 0xce, 0x00, 0x72, + 0x80, 0xc2, 0x40, 0x11, 0x40, 0x91, 0x00, 0xd2, 0x42, 0x89, 0x16, 0xc4, 0x40, 0x22, 0x03, 0x02, 0x40, 0x05, 0x33, + 0x05, 0x00, 0xd4, 0x42, 0xb3, 0x7f, 0x90, 0x7f, 0x98, 0x2e, 0xfe, 0xc9, 0x91, 0x6f, 0xd2, 0x3d, 0xb3, 0x6f, 0x00, + 0x18, 0x8a, 0x00, 0xc0, 0x40, 0xb2, 0x88, 0x06, 0x00, 0xd0, 0x42, 0xa0, 0x35, 0xc5, 0x40, 0x6f, 0x03, 0x46, 0x40, + 0x8f, 0xb1, 0x96, 0x00, 0x20, 0x00, 0xc5, 0x42, 0x92, 0x7f, 0xb0, 0x7f, 0x02, 0x32, 0x01, 0x41, 0x33, 0x30, 0x98, + 0x2e, 0x0f, 0xca, 0xb5, 0x6f, 0x11, 0x3b, 0x63, 0x41, 0x64, 0x41, 0x44, 0x85, 0x45, 0x41, 0xa6, 0x40, 0x87, 0x40, + 0x51, 0x00, 0xf7, 0x7f, 0xb1, 0x7f, 0x20, 0x25, 0x98, 0x2e, 0x67, 0xcc, 0xb1, 0x6f, 0xb3, 0x33, 0xcb, 0x00, 0xea, + 0x82, 0xc2, 0x40, 0x1a, 0xa4, 0xe5, 0x6f, 0x04, 0x30, 0x13, 0x30, 0x01, 0x2f, 0x80, 0xa0, 0x03, 0x2f, 0x2e, 0xac, + 0x0a, 0x2f, 0x80, 0xa4, 0x08, 0x2f, 0x90, 0x6f, 0x04, 0x80, 0x77, 0x34, 0x06, 0x40, 0x6f, 0x01, 0xa2, 0x04, 0xf3, + 0x28, 0x42, 0x43, 0x03, 0x42, 0xd3, 0x3d, 0x42, 0x40, 0xcb, 0x00, 0xf2, 0x82, 0x8f, 0xb0, 0xde, 0x00, 0x43, 0x80, + 0x42, 0x40, 0xb3, 0x7f, 0x90, 0x7f, 0xb3, 0x30, 0x13, 0x53, 0x98, 0x2e, 0x5a, 0xca, 0x3a, 0x25, 0xe8, 0x82, 0xee, + 0x86, 0xe2, 0x6f, 0x82, 0x84, 0x43, 0x7f, 0x20, 0x7f, 0x51, 0x7f, 0x61, 0x7f, 0x32, 0x7f, 0x05, 0x30, 0xa4, 0x6f, + 0x83, 0x30, 0x00, 0x30, 0x11, 0x41, 0x22, 0x6f, 0x14, 0x7f, 0x00, 0x7f, 0xf5, 0x7e, 0x98, 0x2e, 0x0f, 0xca, 0x33, + 0x6f, 0x51, 0x6f, 0xc3, 0x40, 0x50, 0x42, 0x51, 0x7f, 0xe0, 0x7e, 0xc0, 0x90, 0x02, 0x2f, 0x91, 0x6f, 0x00, 0x2e, + 0x40, 0x42, 0x00, 0x2e, 0xe2, 0x6e, 0x90, 0x6f, 0x15, 0x53, 0x98, 0x2e, 0xc3, 0xb1, 0x93, 0x6f, 0xe1, 0x6e, 0xd2, + 0x40, 0x0a, 0x18, 0x01, 0x6f, 0x0e, 0x00, 0x93, 0x7f, 0x83, 0x30, 0x14, 0x6f, 0xf1, 0x6e, 0x42, 0x6f, 0x62, 0x0e, + 0x4f, 0x03, 0xd9, 0x2f, 0x35, 0x52, 0xc1, 0x00, 0x01, 0x30, 0xa9, 0x02, 0x91, 0x6f, 0x7c, 0x82, 0x21, 0xbd, 0xbf, + 0xb9, 0x1b, 0x30, 0x0a, 0x25, 0xda, 0x0a, 0x5b, 0x42, 0x25, 0x80, 0x33, 0x7f, 0x51, 0x7f, 0x20, 0x7f, 0x90, 0x7f, + 0xd3, 0x30, 0x64, 0x6f, 0x55, 0x6f, 0x10, 0x41, 0x52, 0x41, 0x31, 0x6f, 0x55, 0x7f, 0x10, 0x7f, 0x04, 0x7f, 0x98, + 0x2e, 0x0f, 0xca, 0x11, 0x6f, 0x20, 0x25, 0x98, 0x2e, 0xfe, 0xc9, 0x21, 0x6f, 0x04, 0x6f, 0x50, 0x42, 0x21, 0x7f, + 0xd3, 0x30, 0xa1, 0x6f, 0x61, 0x0e, 0xea, 0x2f, 0xb1, 0x6f, 0x45, 0x84, 0x32, 0x25, 0x90, 0x40, 0x84, 0x40, 0x91, + 0x6f, 0xb4, 0x7f, 0x92, 0x7f, 0x30, 0x7f, 0x23, 0x7f, 0x98, 0x2e, 0xb3, 0xc0, 0x53, 0x6f, 0xb1, 0x32, 0x19, 0x01, + 0x83, 0xb9, 0x31, 0x6f, 0x4b, 0x00, 0x02, 0x41, 0xb0, 0x6f, 0x03, 0x30, 0xc3, 0x02, 0x8f, 0xb0, 0xb4, 0x7f, 0xd5, + 0x3d, 0x25, 0x01, 0xa2, 0x6f, 0xa4, 0x7f, 0x26, 0x01, 0x27, 0x6f, 0x90, 0x6f, 0x07, 0x89, 0xc1, 0x43, 0x94, 0x7f, + 0x03, 0x42, 0x00, 0x2e, 0x11, 0x41, 0x31, 0x7f, 0x54, 0x7f, 0x00, 0x2e, 0x91, 0x40, 0x03, 0x41, 0x23, 0x7f, 0x12, + 0x7f, 0x98, 0x2e, 0x74, 0xc0, 0x31, 0x6f, 0xc8, 0x00, 0x90, 0x6f, 0x01, 0x30, 0x54, 0x6f, 0x22, 0x6f, 0x03, 0x42, + 0xd1, 0x02, 0x41, 0x6f, 0x12, 0x6f, 0x23, 0x43, 0x94, 0x7f, 0x51, 0x0e, 0xe7, 0x2f, 0xb1, 0x6f, 0xa3, 0x6f, 0x42, + 0x40, 0x8f, 0xb0, 0xf8, 0x82, 0xde, 0x00, 0xc9, 0x86, 0x52, 0x34, 0xb3, 0x7f, 0x8a, 0x00, 0xc6, 0x86, 0xa2, 0x7f, + 0x93, 0x7f, 0x00, 0x2e, 0xa5, 0x6f, 0xe2, 0x6f, 0x63, 0x41, 0x64, 0x41, 0x44, 0x8f, 0x82, 0x40, 0xe6, 0x41, 0xc0, + 0x41, 0xc4, 0x8f, 0x45, 0x41, 0xf0, 0x7f, 0xa7, 0x7f, 0x51, 0x7f, 0x98, 0x2e, 0x67, 0xcc, 0x00, 0x18, 0x09, 0x52, + 0x71, 0x00, 0x03, 0x30, 0xbb, 0x02, 0x1b, 0xba, 0xb3, 0x6f, 0x25, 0xbc, 0x51, 0x6f, 0xc5, 0x40, 0x42, 0x82, 0x20, + 0x0a, 0x28, 0x00, 0xd0, 0x42, 0x2b, 0xb9, 0xc0, 0x40, 0x82, 0x02, 0xd2, 0x42, 0xb3, 0x7f, 0x00, 0x2e, 0x92, 0x6f, + 0x5a, 0x0e, 0xd9, 0x2f, 0xa1, 0x6f, 0x43, 0x3d, 0x8b, 0x00, 0x9a, 0x82, 0x83, 0x6f, 0x41, 0x40, 0xc3, 0x40, 0xe0, + 0x6f, 0x14, 0x33, 0x04, 0x00, 0x82, 0x40, 0x4b, 0x12, 0x51, 0x0e, 0xb0, 0x7f, 0x90, 0x2e, 0x7a, 0xb5, 0x02, 0x40, + 0x8f, 0xb0, 0xd1, 0x3d, 0x41, 0x00, 0x72, 0x30, 0xd3, 0x04, 0x73, 0x80, 0x4e, 0x00, 0x02, 0x31, 0xd3, 0x05, 0xa0, + 0x7f, 0xf0, 0x8c, 0x04, 0x40, 0x52, 0x40, 0xc0, 0xb2, 0x50, 0x40, 0x4c, 0x17, 0x96, 0x7f, 0x57, 0x7f, 0x0a, 0x2f, + 0xd0, 0xa0, 0x03, 0x2f, 0x95, 0x6f, 0x65, 0x15, 0x06, 0x2c, 0x04, 0x30, 0x56, 0x6f, 0xa6, 0x13, 0x6b, 0x15, 0x23, + 0x15, 0x6e, 0x0b, 0x14, 0x05, 0x64, 0x18, 0x45, 0x07, 0xec, 0x18, 0xc0, 0xb2, 0xec, 0x18, 0x0a, 0x2f, 0xd0, 0xa0, + 0x03, 0x2f, 0x94, 0x6f, 0xbc, 0x13, 0x06, 0x2c, 0x07, 0x30, 0x54, 0x6f, 0x3c, 0x15, 0x73, 0x13, 0xfb, 0x13, 0xac, + 0x0b, 0x44, 0x40, 0x26, 0x05, 0x54, 0x42, 0xc0, 0xb2, 0x44, 0x40, 0x27, 0x07, 0x44, 0x42, 0x08, 0x2f, 0xd0, 0xa0, + 0x02, 0x2f, 0x91, 0x6f, 0x05, 0x2c, 0x81, 0x10, 0x51, 0x6f, 0x41, 0x14, 0xd3, 0x12, 0x99, 0x0a, 0xa1, 0x6f, 0xf3, + 0x32, 0x42, 0x42, 0x4b, 0x00, 0x13, 0x30, 0x42, 0x40, 0xd3, 0x28, 0x53, 0x42, 0xa1, 0x7f, 0xc2, 0xa2, 0x30, 0x2f, + 0x82, 0x6f, 0xe1, 0x6f, 0x98, 0x2e, 0xfa, 0xb1, 0x81, 0x6f, 0x41, 0x84, 0x00, 0x2e, 0x81, 0x40, 0x40, 0x90, 0x02, + 0x2f, 0x00, 0x2e, 0x07, 0x2c, 0x0c, 0xb8, 0x30, 0x25, 0xe1, 0x6f, 0x20, 0x33, 0x48, 0x00, 0x98, 0x2e, 0x07, 0xb6, + 0xe1, 0x6f, 0xf3, 0x32, 0x4b, 0x00, 0xe0, 0x7f, 0x00, 0x2e, 0x44, 0x40, 0x20, 0x1a, 0x15, 0x2f, 0xd3, 0x6f, 0xc1, + 0x6f, 0xc3, 0x40, 0x23, 0x5a, 0x42, 0x40, 0x83, 0x7e, 0x08, 0xbc, 0x25, 0x09, 0x92, 0x7e, 0xc4, 0x0a, 0x42, 0x82, + 0xa3, 0x7e, 0xd1, 0x7f, 0x34, 0x30, 0x63, 0x6f, 0x82, 0x30, 0x31, 0x30, 0x98, 0x2e, 0xb2, 0x00, 0xd1, 0x6f, 0xe3, + 0x6f, 0x43, 0x42, 0x00, 0x2e, 0xa1, 0x6f, 0xb2, 0x6f, 0x43, 0x40, 0xc1, 0x86, 0xc2, 0xa2, 0x43, 0x42, 0x03, 0x30, + 0x00, 0x2f, 0x83, 0x42, 0xd2, 0x3d, 0x40, 0x40, 0x0f, 0xb0, 0x0a, 0x01, 0x26, 0x00, 0x05, 0x32, 0x98, 0x2e, 0x7e, + 0xb5, 0x65, 0x00, 0x00, 0x2e, 0x43, 0x42, 0x00, 0x2e, 0x7b, 0x6f, 0x50, 0x5e, 0xb8, 0x2e, 0x0f, 0x82, 0x02, 0x30, + 0x12, 0x42, 0x41, 0x0e, 0xfc, 0x2f, 0xb8, 0x2e, 0xc1, 0x35, 0x40, 0x51, 0x01, 0x01, 0x02, 0x30, 0x1a, 0x25, 0x13, + 0x30, 0x12, 0x42, 0x44, 0x0e, 0xfc, 0x2f, 0x54, 0x3a, 0x04, 0x01, 0x1d, 0x5b, 0x05, 0x7f, 0x75, 0x34, 0x13, 0x5f, + 0x07, 0x43, 0x25, 0x01, 0x47, 0x5a, 0x05, 0x43, 0x27, 0x89, 0x67, 0x5a, 0x05, 0x43, 0x18, 0x8b, 0x19, 0x59, 0x17, + 0x51, 0xd4, 0x7e, 0x43, 0x43, 0xc0, 0x7e, 0xe0, 0x7e, 0x6c, 0x88, 0x1b, 0x5d, 0xf6, 0x7e, 0x71, 0x86, 0x42, 0x81, + 0x15, 0x41, 0x15, 0x42, 0x63, 0x0e, 0xfb, 0x2f, 0x21, 0x59, 0x1f, 0x5d, 0x25, 0x5f, 0x23, 0x5b, 0x34, 0x7f, 0x16, + 0x7f, 0x45, 0x7f, 0x57, 0x7f, 0x22, 0x7f, 0x76, 0x88, 0xd5, 0x40, 0x15, 0x42, 0x5c, 0x0e, 0xfb, 0x2f, 0x29, 0x57, + 0x27, 0x5d, 0x2d, 0x5f, 0x2b, 0x5b, 0x83, 0x7f, 0x66, 0x7f, 0x95, 0x7f, 0xa7, 0x7f, 0x72, 0x7f, 0x7b, 0x86, 0x15, + 0x41, 0x15, 0x42, 0x63, 0x0e, 0xfb, 0x2f, 0x31, 0x59, 0x33, 0x5d, 0x2f, 0x5b, 0xc5, 0x7f, 0xd4, 0x7f, 0xf6, 0x7f, + 0xb2, 0x7f, 0xe2, 0x7f, 0x40, 0x82, 0xd2, 0x40, 0x12, 0x42, 0x59, 0x0e, 0xfb, 0x2f, 0xc0, 0x5e, 0xb8, 0x2e, 0x00, + 0x30, 0xc0, 0x2e, 0x21, 0x2e, 0x8c, 0x00, 0x35, 0x51, 0xc0, 0x2e, 0x21, 0x2e, 0xad, 0x00, 0x05, 0x2e, 0x28, 0x02, + 0x2f, 0xbd, 0x2f, 0xb9, 0x20, 0x50, 0x80, 0xb2, 0x16, 0x2f, 0x20, 0x25, 0x01, 0x2e, 0x8c, 0x00, 0x00, 0x90, 0x0b, + 0x2f, 0x37, 0x51, 0xf2, 0x7f, 0xeb, 0x7f, 0x98, 0x2e, 0x84, 0xb5, 0x01, 0x2e, 0x8c, 0x00, 0x01, 0x80, 0x21, 0x2e, + 0x8c, 0x00, 0xf2, 0x6f, 0xeb, 0x6f, 0xe0, 0x5f, 0x03, 0x2e, 0xad, 0x00, 0x37, 0x51, 0x80, 0x2e, 0x74, 0xb3, 0x00, + 0x30, 0x21, 0x2e, 0x8c, 0x00, 0xe0, 0x5f, 0xb8, 0x2e, 0x02, 0x30, 0x02, 0x2c, 0x41, 0x00, 0x12, 0x42, 0x41, 0x0e, + 0xfc, 0x2f, 0xb8, 0x2e, 0x81, 0x8e, 0x39, 0x51, 0x07, 0x5c, 0x58, 0x09, 0x9e, 0x09, 0xc3, 0x41, 0x50, 0x50, 0xc3, + 0x89, 0xf3, 0x0e, 0x41, 0x80, 0xf0, 0x7f, 0xdc, 0xb9, 0xe4, 0x7f, 0x44, 0x80, 0x84, 0x8e, 0x43, 0x88, 0xd1, 0x7f, + 0x05, 0x30, 0xc2, 0x7f, 0x21, 0x2f, 0xf1, 0x6f, 0x00, 0x2e, 0x41, 0x40, 0x19, 0x1a, 0x1c, 0x2f, 0x82, 0x84, 0x00, + 0x2e, 0x82, 0x40, 0xf2, 0x0e, 0x05, 0x2f, 0x02, 0x41, 0x81, 0x84, 0x01, 0x30, 0x03, 0x30, 0x22, 0x2c, 0x02, 0x43, + 0xff, 0x84, 0x42, 0x00, 0x60, 0x25, 0x43, 0x40, 0xc1, 0x86, 0x43, 0x42, 0x11, 0x30, 0xc2, 0x41, 0x03, 0x30, 0x97, + 0x41, 0xc1, 0x86, 0xfa, 0x0f, 0x13, 0x2f, 0xc5, 0xa2, 0xf9, 0x2f, 0x03, 0x30, 0x10, 0x2c, 0x01, 0x30, 0xd2, 0x6f, + 0x00, 0x2e, 0x82, 0x40, 0x80, 0x90, 0x04, 0x2f, 0xd2, 0x6f, 0xf1, 0x6f, 0x17, 0x30, 0x87, 0x42, 0x43, 0x42, 0x00, + 0x2e, 0x3b, 0x55, 0xf2, 0x0e, 0x12, 0x30, 0x55, 0x22, 0x40, 0xb2, 0xbb, 0x7f, 0x06, 0x2f, 0x51, 0x30, 0x60, 0x25, + 0x98, 0x2e, 0x00, 0xb6, 0xbf, 0x81, 0x00, 0x2e, 0x05, 0x42, 0x00, 0x2e, 0xe2, 0x6f, 0x01, 0x41, 0x82, 0x40, 0xd0, + 0x6f, 0x13, 0x88, 0xca, 0x0f, 0x49, 0x2f, 0xf2, 0x6f, 0xc0, 0xa6, 0x87, 0x40, 0x43, 0x2f, 0xc5, 0x6f, 0x02, 0x82, + 0x43, 0x8d, 0x42, 0x40, 0x81, 0x8a, 0x86, 0x41, 0x6e, 0x0e, 0x45, 0x42, 0x47, 0x8a, 0xaa, 0x00, 0x1b, 0x30, 0x83, + 0x42, 0x09, 0x84, 0xf2, 0x7f, 0x02, 0x30, 0x03, 0x2f, 0x0b, 0x43, 0x2f, 0x89, 0x00, 0x2e, 0x02, 0x43, 0x51, 0x88, + 0x41, 0x40, 0x15, 0x41, 0x40, 0xb3, 0x4e, 0x22, 0x5f, 0x1a, 0x14, 0x80, 0x03, 0x41, 0x06, 0x2f, 0xc1, 0x84, 0xd6, + 0x0e, 0x02, 0x42, 0x22, 0x2f, 0x00, 0x2e, 0x21, 0x2c, 0x06, 0x42, 0xff, 0x80, 0x41, 0x0f, 0x91, 0xb9, 0x10, 0x22, + 0xf4, 0x6f, 0x61, 0x00, 0xc3, 0x0f, 0x12, 0x2f, 0x13, 0x30, 0x04, 0x30, 0xf6, 0x6f, 0x05, 0x30, 0x05, 0x2c, 0xe7, + 0x7f, 0x97, 0x41, 0x3c, 0x1a, 0xda, 0x23, 0x6f, 0x01, 0x71, 0x0e, 0xf9, 0x2f, 0x68, 0x0f, 0xe6, 0x6f, 0xe6, 0x23, + 0x01, 0x89, 0x28, 0x22, 0x05, 0xa7, 0xee, 0x2f, 0xf2, 0x6f, 0xb8, 0x84, 0x93, 0x82, 0x87, 0x42, 0x40, 0x42, 0x08, + 0x2c, 0x07, 0x25, 0x13, 0x30, 0x50, 0x25, 0x98, 0x2e, 0xb3, 0xb6, 0x00, 0x30, 0x43, 0x43, 0x03, 0x43, 0x00, 0x2e, + 0xbb, 0x6f, 0xb0, 0x5f, 0xb8, 0x2e, 0x15, 0x82, 0x02, 0x30, 0x12, 0x42, 0x41, 0x0e, 0xfc, 0x2f, 0xb8, 0x2e, 0x80, + 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, + 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, + 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, + 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, + 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, + 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, + 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, + 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, + 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, + 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, + 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, + 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, + 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, + 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, + 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, + 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, + 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, + 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, + 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, + 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, + 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, + 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, + 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, + 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, + 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, + 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, + 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, + 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, + 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, + 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, + 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, + 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, + 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, + 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, + 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0xfd, 0x2d, 0x01, 0x2e, 0x5d, 0xf7, 0x08, 0xbc, 0x80, 0xac, 0x0e, 0xbb, 0x02, 0x2f, + 0x00, 0x30, 0x41, 0x04, 0x82, 0x06, 0xc0, 0xa4, 0x00, 0x30, 0x11, 0x2f, 0x40, 0xa9, 0x03, 0x2f, 0x40, 0x91, 0x0d, + 0x2f, 0x00, 0xa7, 0x0b, 0x2f, 0x80, 0xb3, 0x35, 0x58, 0x02, 0x2f, 0x90, 0xa1, 0x26, 0x13, 0x20, 0x23, 0x80, 0x90, + 0x10, 0x30, 0x01, 0x2f, 0xcc, 0x0e, 0x00, 0x2f, 0x00, 0x30, 0xb8, 0x2e, 0x3d, 0x56, 0x37, 0x54, 0xd0, 0x40, 0xc4, + 0x40, 0x0b, 0x2e, 0xfd, 0xf3, 0x3d, 0x52, 0x90, 0x42, 0x94, 0x42, 0x95, 0x42, 0x05, 0x30, 0x3f, 0x50, 0x0f, 0x88, + 0x06, 0x40, 0x04, 0x41, 0x96, 0x42, 0xc5, 0x42, 0x48, 0xbe, 0x73, 0x30, 0x0d, 0x2e, 0x8a, 0x00, 0x4f, 0xba, 0x84, + 0x42, 0x03, 0x42, 0x81, 0xb3, 0x02, 0x2f, 0x2b, 0x2e, 0x6f, 0xf5, 0x06, 0x2d, 0x05, 0x2e, 0x77, 0xf7, 0x3b, 0x56, + 0x93, 0x08, 0x25, 0x2e, 0x77, 0xf7, 0x39, 0x54, 0x25, 0x2e, 0xc2, 0xf5, 0x07, 0x2e, 0xfd, 0xf3, 0x42, 0x30, 0xb4, + 0x33, 0xda, 0x0a, 0x4c, 0x00, 0x27, 0x2e, 0xfd, 0xf3, 0x43, 0x40, 0xd4, 0x3f, 0xdc, 0x08, 0x43, 0x42, 0x00, 0x2e, + 0x00, 0x2e, 0x43, 0x40, 0x24, 0x30, 0xdc, 0x0a, 0x43, 0x42, 0x04, 0x80, 0x03, 0x2e, 0xfd, 0xf3, 0x4a, 0x0a, 0x23, + 0x2e, 0xfd, 0xf3, 0x61, 0x34, 0xc0, 0x2e, 0x01, 0x42, 0x00, 0x2e, 0xd0, 0x51, 0xfb, 0x7f, 0x98, 0x2e, 0xcf, 0x0d, + 0x5a, 0x25, 0x98, 0x2e, 0xf6, 0x0d, 0x6b, 0x87, 0x49, 0x54, 0xe1, 0x7f, 0xa3, 0x7f, 0xb3, 0x7f, 0xb2, 0x88, 0x41, + 0x52, 0xc2, 0x7f, 0x65, 0x8b, 0x43, 0x56, 0x84, 0x7f, 0x61, 0x7f, 0x75, 0x7f, 0xd0, 0x7f, 0x95, 0x7f, 0x53, 0x7f, + 0x14, 0x30, 0x45, 0x54, 0x81, 0x6f, 0x42, 0x7f, 0x00, 0x2e, 0x53, 0x40, 0x45, 0x8c, 0x42, 0x40, 0x90, 0x41, 0xbb, + 0x83, 0x86, 0x41, 0xd8, 0x04, 0x16, 0x06, 0x00, 0xac, 0x81, 0x7f, 0x02, 0x2f, 0x02, 0x30, 0xd3, 0x04, 0x10, 0x06, + 0xc1, 0x84, 0x01, 0x30, 0xc1, 0x02, 0x0b, 0x16, 0x04, 0x09, 0x14, 0x01, 0x99, 0x02, 0xc1, 0xb9, 0xaf, 0xbc, 0x59, + 0x0a, 0x64, 0x6f, 0x51, 0x43, 0xa1, 0xb4, 0x12, 0x41, 0x13, 0x41, 0x41, 0x43, 0x35, 0x7f, 0x64, 0x7f, 0x26, 0x31, + 0xe5, 0x6f, 0xd4, 0x6f, 0x98, 0x2e, 0x37, 0xca, 0x32, 0x6f, 0x75, 0x6f, 0x83, 0x40, 0x42, 0x41, 0x23, 0x7f, 0x12, + 0x7f, 0xf6, 0x30, 0x40, 0x25, 0x51, 0x25, 0x98, 0x2e, 0x37, 0xca, 0x14, 0x6f, 0x20, 0x05, 0x70, 0x6f, 0x25, 0x6f, + 0x69, 0x07, 0xa2, 0x6f, 0x31, 0x6f, 0x0b, 0x30, 0x04, 0x42, 0x9b, 0x42, 0x8b, 0x42, 0x55, 0x42, 0x32, 0x7f, 0x40, + 0xa9, 0xc3, 0x6f, 0x71, 0x7f, 0x02, 0x30, 0xd0, 0x40, 0xc3, 0x7f, 0x03, 0x2f, 0x40, 0x91, 0x15, 0x2f, 0x00, 0xa7, + 0x13, 0x2f, 0x00, 0xa4, 0x11, 0x2f, 0x84, 0xbd, 0x98, 0x2e, 0x79, 0xca, 0x55, 0x6f, 0x51, 0x54, 0x54, 0x41, 0x82, + 0x00, 0xf3, 0x3f, 0x45, 0x41, 0xcb, 0x02, 0xf6, 0x30, 0x98, 0x2e, 0x37, 0xca, 0x33, 0x6f, 0xa4, 0x6f, 0xc1, 0x42, + 0x03, 0x2c, 0x00, 0x43, 0xa4, 0x6f, 0x33, 0x6f, 0x00, 0x2e, 0x42, 0x6f, 0x55, 0x6f, 0x91, 0x40, 0x42, 0x8b, 0x00, + 0x41, 0x41, 0x00, 0x01, 0x43, 0x55, 0x7f, 0x14, 0x30, 0xc1, 0x40, 0x95, 0x40, 0x4d, 0x02, 0xc5, 0x6f, 0x4f, 0x50, + 0x68, 0x0e, 0x75, 0x6f, 0xd1, 0x42, 0xa3, 0x7f, 0x8a, 0x2f, 0x09, 0x2e, 0x8a, 0x00, 0x01, 0xb3, 0x22, 0x2f, 0x49, + 0x58, 0x90, 0x6f, 0x17, 0x30, 0x13, 0x41, 0xb6, 0x6f, 0xe4, 0x7f, 0x00, 0x2e, 0x91, 0x41, 0x14, 0x40, 0x92, 0x41, + 0x15, 0x40, 0x17, 0x2e, 0x6f, 0xf5, 0xb6, 0x7f, 0xd0, 0x7f, 0xcb, 0x7f, 0x98, 0x2e, 0x00, 0x0c, 0x07, 0x15, 0xc2, + 0x6f, 0x14, 0x0b, 0x29, 0x2e, 0x6f, 0xf5, 0xc3, 0xa3, 0xc1, 0x8f, 0xe4, 0x6f, 0xd0, 0x6f, 0xe6, 0x2f, 0x14, 0x30, + 0x05, 0x2e, 0x6f, 0xf5, 0x14, 0x0b, 0x29, 0x2e, 0x6f, 0xf5, 0x44, 0x2d, 0x4b, 0x54, 0x01, 0x32, 0x51, 0x58, 0x05, + 0x30, 0x23, 0x50, 0x83, 0x40, 0xd8, 0x08, 0x91, 0x01, 0xb8, 0xbd, 0x38, 0xb5, 0xe6, 0x7f, 0x0a, 0x16, 0xb1, 0x6f, + 0x2a, 0xbb, 0xa6, 0xbd, 0x1c, 0x01, 0x06, 0xbc, 0x52, 0x40, 0x06, 0x0a, 0x53, 0x40, 0x45, 0x03, 0xb1, 0x7f, 0xf6, + 0x30, 0x98, 0x2e, 0x37, 0xca, 0x1a, 0xbd, 0x16, 0xb6, 0x86, 0xba, 0x00, 0xa9, 0xaa, 0x0a, 0x53, 0x52, 0x0f, 0x2f, + 0x00, 0x91, 0x53, 0x52, 0x03, 0x2f, 0x53, 0x5a, 0x55, 0x0f, 0x53, 0x52, 0x08, 0x2f, 0x3f, 0xa1, 0x04, 0x2f, 0x3f, + 0x91, 0x03, 0x2f, 0x51, 0x58, 0xd4, 0x0f, 0x00, 0x2f, 0x51, 0x54, 0x12, 0x25, 0xf2, 0x33, 0x98, 0x2e, 0xd9, 0xc0, + 0xe4, 0x6f, 0xf5, 0x37, 0x45, 0x09, 0x21, 0x85, 0x05, 0x43, 0x05, 0x30, 0x4d, 0x52, 0x51, 0x0e, 0x01, 0x32, 0x51, + 0x58, 0xc5, 0x2f, 0x47, 0x54, 0x09, 0x2e, 0x77, 0xf7, 0x22, 0x0b, 0x29, 0x2e, 0x77, 0xf7, 0xfb, 0x6f, 0x30, 0x5e, + 0xb8, 0x2e, 0x10, 0x50, 0x01, 0x2e, 0x86, 0x00, 0x00, 0xb2, 0xfb, 0x7f, 0x5d, 0x2f, 0x01, 0xb2, 0x54, 0x2f, 0x02, + 0xb2, 0x4e, 0x2f, 0x03, 0x90, 0x63, 0x2f, 0x59, 0x50, 0x39, 0x82, 0x02, 0x40, 0x81, 0x88, 0x5b, 0x54, 0x41, 0x40, + 0x61, 0x56, 0x04, 0x42, 0x00, 0x2e, 0x94, 0x40, 0x95, 0x40, 0xd8, 0xbe, 0x2c, 0x0b, 0x45, 0x40, 0x6c, 0x01, 0x55, + 0x42, 0x0c, 0x17, 0x45, 0x40, 0x2c, 0x03, 0x54, 0x42, 0x53, 0x0e, 0xf2, 0x2f, 0x63, 0x56, 0x3e, 0x82, 0xe2, 0x40, + 0xc3, 0x40, 0x28, 0xbd, 0x93, 0x0a, 0x43, 0x40, 0xda, 0x00, 0x53, 0x42, 0x8a, 0x16, 0x43, 0x40, 0x9a, 0x02, 0x52, + 0x42, 0x00, 0x2e, 0x41, 0x40, 0x47, 0x54, 0x4a, 0x0e, 0x3b, 0x2f, 0x3a, 0x82, 0x00, 0x30, 0x41, 0x40, 0x21, 0x2e, + 0x52, 0x0f, 0x40, 0xb2, 0x0a, 0x2f, 0x98, 0x2e, 0x61, 0x0c, 0x98, 0x2e, 0x2b, 0x0e, 0x98, 0x2e, 0x41, 0x0e, 0xfb, + 0x6f, 0xf0, 0x5f, 0x00, 0x30, 0x80, 0x2e, 0xaf, 0xb1, 0x5f, 0x54, 0x55, 0x56, 0x83, 0x42, 0x8f, 0x86, 0x74, 0x30, + 0x5d, 0x54, 0xc4, 0x42, 0x11, 0x30, 0x23, 0x2e, 0x86, 0x00, 0xa1, 0x42, 0x23, 0x30, 0x27, 0x2e, 0x89, 0x00, 0x21, + 0x2e, 0x88, 0x00, 0xba, 0x82, 0x18, 0x2c, 0x81, 0x42, 0x30, 0x30, 0x21, 0x2e, 0x86, 0x00, 0x13, 0x2d, 0x21, 0x30, + 0x00, 0x30, 0x23, 0x2e, 0x86, 0x00, 0x21, 0x2e, 0x7b, 0xf7, 0x0c, 0x2d, 0x77, 0x30, 0x98, 0x2e, 0x1f, 0x0c, 0x57, + 0x50, 0x0c, 0x82, 0x12, 0x30, 0x40, 0x42, 0x25, 0x2e, 0x86, 0x00, 0x2f, 0x2e, 0x7b, 0xf7, 0xfb, 0x6f, 0xf0, 0x5f, + 0xb8, 0x2e, 0x70, 0x50, 0x0a, 0x25, 0x39, 0x86, 0xfb, 0x7f, 0xe1, 0x32, 0x62, 0x30, 0x98, 0x2e, 0xc2, 0xc4, 0x23, + 0x56, 0xa5, 0x6f, 0xab, 0x08, 0x91, 0x6f, 0x4b, 0x08, 0x65, 0x56, 0xc4, 0x6f, 0x23, 0x09, 0x4d, 0xba, 0x93, 0xbc, + 0x8c, 0x0b, 0xd1, 0x6f, 0x0b, 0x09, 0x49, 0x52, 0x67, 0x5e, 0x56, 0x42, 0xaf, 0x09, 0x4d, 0xba, 0x23, 0xbd, 0x94, + 0x0a, 0xe5, 0x6f, 0x68, 0xbb, 0xeb, 0x08, 0xbd, 0xb9, 0x63, 0xbe, 0xfb, 0x6f, 0x52, 0x42, 0xe3, 0x0a, 0xc0, 0x2e, + 0x43, 0x42, 0x90, 0x5f, 0x4f, 0x50, 0x03, 0x2e, 0x25, 0xf3, 0x12, 0x40, 0x00, 0x40, 0x28, 0xba, 0x9b, 0xbc, 0x88, + 0xbd, 0x93, 0xb4, 0xe3, 0x0a, 0x89, 0x16, 0x08, 0xb6, 0xc0, 0x2e, 0x19, 0x00, 0x62, 0x02, 0x10, 0x50, 0xfb, 0x7f, + 0x98, 0x2e, 0x5d, 0x0d, 0x01, 0x2e, 0x86, 0x00, 0x31, 0x30, 0x08, 0x04, 0xfb, 0x6f, 0x01, 0x30, 0xf0, 0x5f, 0x23, + 0x2e, 0x88, 0x00, 0x21, 0x2e, 0x89, 0x00, 0xb8, 0x2e, 0x01, 0x2e, 0x89, 0x00, 0x03, 0x2e, 0x88, 0x00, 0x48, 0x0e, + 0x01, 0x2f, 0x80, 0x2e, 0x05, 0x0e, 0xb8, 0x2e, 0x69, 0x50, 0x21, 0x34, 0x01, 0x42, 0x82, 0x30, 0xc1, 0x32, 0x25, + 0x2e, 0x62, 0xf5, 0x01, 0x00, 0x22, 0x30, 0x01, 0x40, 0x4a, 0x0a, 0x01, 0x42, 0xb8, 0x2e, 0x69, 0x54, 0xf0, 0x3b, + 0x83, 0x40, 0xd8, 0x08, 0x6b, 0x52, 0x83, 0x42, 0x00, 0x30, 0x83, 0x30, 0x50, 0x42, 0xc4, 0x32, 0x27, 0x2e, 0x64, + 0xf5, 0x94, 0x00, 0x50, 0x42, 0x40, 0x42, 0xd3, 0x3f, 0x84, 0x40, 0x7d, 0x82, 0xe3, 0x08, 0x40, 0x42, 0x83, 0x42, + 0xb8, 0x2e, 0x5f, 0x52, 0x00, 0x30, 0x40, 0x42, 0x7c, 0x86, 0x37, 0x52, 0x09, 0x2e, 0x3d, 0x0f, 0x3d, 0x54, 0xc4, + 0x42, 0xd3, 0x86, 0x54, 0x40, 0x55, 0x40, 0x94, 0x42, 0x85, 0x42, 0x21, 0x2e, 0x89, 0x00, 0x42, 0x40, 0x25, 0x2e, + 0xfd, 0xf3, 0xc0, 0x42, 0x7e, 0x82, 0x05, 0x2e, 0x79, 0x00, 0x80, 0xb2, 0x14, 0x2f, 0x05, 0x2e, 0x24, 0x02, 0x27, + 0xbd, 0x2f, 0xb9, 0x80, 0x90, 0x02, 0x2f, 0x21, 0x2e, 0x6f, 0xf5, 0x0c, 0x2d, 0x07, 0x2e, 0x3e, 0x0f, 0x14, 0x30, + 0x1c, 0x09, 0x05, 0x2e, 0x77, 0xf7, 0x3b, 0x56, 0x47, 0xbe, 0x93, 0x08, 0x94, 0x0a, 0x25, 0x2e, 0x77, 0xf7, 0x6d, + 0x54, 0x50, 0x42, 0x4a, 0x0e, 0xfc, 0x2f, 0xb8, 0x2e, 0x50, 0x50, 0x02, 0x30, 0x43, 0x86, 0x6b, 0x50, 0xfb, 0x7f, + 0xe3, 0x7f, 0xd2, 0x7f, 0xc0, 0x7f, 0xb1, 0x7f, 0x00, 0x2e, 0x41, 0x40, 0x00, 0x40, 0x48, 0x04, 0x98, 0x2e, 0x74, + 0xc0, 0x1e, 0xaa, 0xd3, 0x6f, 0x14, 0x30, 0xb1, 0x6f, 0xe3, 0x22, 0xc0, 0x6f, 0x52, 0x40, 0xe4, 0x6f, 0x4c, 0x0e, + 0x12, 0x42, 0xd3, 0x7f, 0xeb, 0x2f, 0x03, 0x2e, 0x53, 0x0f, 0x40, 0x90, 0x11, 0x30, 0x03, 0x2f, 0x23, 0x2e, 0x53, + 0x0f, 0x02, 0x2c, 0x00, 0x30, 0xd0, 0x6f, 0xfb, 0x6f, 0xb0, 0x5f, 0xb8, 0x2e, 0x40, 0x50, 0xf1, 0x7f, 0x0a, 0x25, + 0x3c, 0x86, 0xeb, 0x7f, 0x41, 0x33, 0x22, 0x30, 0x98, 0x2e, 0xc2, 0xc4, 0xd3, 0x6f, 0xf4, 0x30, 0xdc, 0x09, 0x71, + 0x58, 0xc2, 0x6f, 0x94, 0x09, 0x73, 0x58, 0x6a, 0xbb, 0xdc, 0x08, 0xb4, 0xb9, 0xb1, 0xbd, 0x6f, 0x5a, 0x95, 0x08, + 0x21, 0xbd, 0xf6, 0xbf, 0x77, 0x0b, 0x51, 0xbe, 0xf1, 0x6f, 0xeb, 0x6f, 0x52, 0x42, 0x54, 0x42, 0xc0, 0x2e, 0x43, + 0x42, 0xc0, 0x5f, 0x50, 0x50, 0x77, 0x52, 0x93, 0x30, 0x53, 0x42, 0xfb, 0x7f, 0x7b, 0x30, 0x4b, 0x42, 0x13, 0x30, + 0x42, 0x82, 0x20, 0x33, 0x43, 0x42, 0xc8, 0x00, 0x01, 0x2e, 0x80, 0x03, 0x05, 0x2e, 0x7e, 0x00, 0x19, 0x52, 0xe2, + 0x7f, 0xd0, 0x7f, 0xc3, 0x7f, 0x98, 0x2e, 0x9c, 0x0e, 0xd1, 0x6f, 0x48, 0x0a, 0xd1, 0x7f, 0x3a, 0x25, 0xfb, 0x86, + 0x01, 0x33, 0x12, 0x30, 0x98, 0x2e, 0xc2, 0xc4, 0xd1, 0x6f, 0x48, 0x0a, 0x40, 0xb2, 0x0d, 0x2f, 0xe0, 0x6f, 0x03, + 0x2e, 0x80, 0x03, 0x53, 0x30, 0x07, 0x80, 0x27, 0x2e, 0x21, 0xf2, 0x98, 0xbc, 0x01, 0x42, 0x98, 0x2e, 0xe0, 0x03, + 0x00, 0x2e, 0x00, 0x2e, 0xd0, 0x2e, 0xb1, 0x6f, 0x9b, 0xb8, 0x07, 0x2e, 0x1b, 0x00, 0x19, 0x1a, 0xb1, 0x7f, 0x71, + 0x30, 0x04, 0x2f, 0x23, 0x2e, 0x21, 0xf2, 0x00, 0x2e, 0x00, 0x2e, 0xd0, 0x2e, 0x98, 0x2e, 0x6d, 0xc0, 0x98, 0x2e, + 0x5d, 0xc0, 0x98, 0x2e, 0xd9, 0xb5, 0x20, 0x26, 0xc1, 0x6f, 0x02, 0x31, 0x52, 0x42, 0xab, 0x30, 0x4b, 0x42, 0x20, + 0x33, 0x79, 0x56, 0xf1, 0x37, 0xc4, 0x40, 0xa2, 0x0a, 0xc2, 0x42, 0xd8, 0x00, 0x01, 0x2e, 0x5e, 0xf7, 0x41, 0x08, + 0x23, 0x2e, 0x93, 0x00, 0xe3, 0x7f, 0x98, 0x2e, 0xe1, 0x00, 0xe1, 0x6f, 0x83, 0x30, 0x43, 0x42, 0x03, 0x30, 0xfb, + 0x6f, 0x75, 0x50, 0x02, 0x30, 0x00, 0x2e, 0x00, 0x2e, 0x81, 0x84, 0x50, 0x0e, 0xfa, 0x2f, 0x43, 0x42, 0x11, 0x30, + 0xb0, 0x5f, 0x23, 0x2e, 0x21, 0xf2, 0xb8, 0x2e, 0xc1, 0x4a, 0x00, 0x00, 0x6d, 0x57, 0x00, 0x00, 0x77, 0x8e, 0x00, + 0x00, 0xe0, 0xff, 0xff, 0xff, 0xd3, 0xff, 0xff, 0xff, 0xe5, 0xff, 0xff, 0xff, 0xee, 0xe1, 0xff, 0xff, 0x7c, 0x13, + 0x00, 0x00, 0x46, 0xe6, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, + 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, + 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, + 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, + 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, + 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, + 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, + 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, + 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, + 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, + 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, + 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, + 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, + 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, + 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, + 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, + 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, + 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, + 0xc1, 0xfd, 0x2d +}; + +/*! @name Global array that stores the feature input configuration of + * BMI270_HUAWEI_CONTEXT + */ +const struct bmi2_feature_config bmi270_hc_feat_in[BMI270_HC_MAX_FEAT_IN] = { + { .type = BMI2_CONFIG_ID, .page = BMI2_PAGE_4, .start_addr = BMI270_HC_CONFIG_ID_STRT_ADDR }, + { .type = BMI2_STEP_COUNTER_PARAMS, .page = BMI2_PAGE_1, .start_addr = BMI270_HC_STEP_CNT_1_STRT_ADDR }, + { .type = BMI2_STEP_DETECTOR, .page = BMI2_PAGE_4, .start_addr = BMI270_HC_STEP_CNT_4_STRT_ADDR }, + { .type = BMI2_STEP_COUNTER, .page = BMI2_PAGE_4, .start_addr = BMI270_HC_STEP_CNT_4_STRT_ADDR }, + { .type = BMI2_NVM_PROG_PREP, .page = BMI2_PAGE_4, .start_addr = BMI270_HC_NVM_PROG_PREP_STRT_ADDR }, + { .type = BMI2_MAX_BURST_LEN, .page = BMI2_PAGE_4, .start_addr = BMI270_HC_MAX_BURST_LEN_STRT_ADDR }, + { .type = BMI2_CRT_GYRO_SELF_TEST, .page = BMI2_PAGE_4, .start_addr = BMI270_HC_CRT_GYRO_SELF_TEST_STRT_ADDR }, + { .type = BMI2_ABORT_CRT_GYRO_SELF_TEST, .page = BMI2_PAGE_4, .start_addr = BMI270_HC_ABORT_STRT_ADDR }, + { .type = BMI2_ACTIVITY_RECOGNITION_SETTINGS, .page = BMI2_PAGE_5, .start_addr = BMI270_HC_ACT_RGN_SETT_STRT_ADDR }, + { .type = BMI2_ACTIVITY_RECOGNITION, .page = BMI2_PAGE_5, .start_addr = BMI270_HC_ACT_RGN_STRT_ADDR }, +}; + +/*! @name Global array that stores the feature output configuration */ +const struct bmi2_feature_config bmi270_hc_feat_out[BMI270_HC_MAX_FEAT_OUT] = { + { .type = BMI2_STEP_COUNTER, .page = BMI2_PAGE_0, .start_addr = BMI270_HC_STEP_CNT_OUT_STRT_ADDR }, + { .type = BMI2_GYRO_CROSS_SENSE, .page = BMI2_PAGE_0, .start_addr = BMI270_HC_GYRO_CROSS_SENSE_STRT_ADDR }, + { .type = BMI2_GYRO_GAIN_UPDATE, .page = BMI2_PAGE_0, .start_addr = BMI270_HC_GYR_USER_GAIN_OUT_STRT_ADDR }, + { .type = BMI2_NVM_STATUS, .page = BMI2_PAGE_0, .start_addr = BMI270_HC_NVM_VFRM_OUT_STRT_ADDR }, + { .type = BMI2_VFRM_STATUS, .page = BMI2_PAGE_0, .start_addr = BMI270_HC_NVM_VFRM_OUT_STRT_ADDR } +}; + +/*! @name Global array that stores the feature interrupts of BMI270_HUAWEI_CONTEXT */ +struct bmi2_map_int bmi270_hc_map_int[BMI270_HC_MAX_INT_MAP] = { + { .type = BMI2_STEP_COUNTER, .sens_map_int = BMI270_HC_INT_STEP_COUNTER_MASK }, + { .type = BMI2_STEP_DETECTOR, .sens_map_int = BMI270_HC_INT_STEP_DETECTOR_MASK }, +}; + +/******************************************************************************/ + +/*! Local Function Prototypes + ******************************************************************************/ + +/*! + * @brief This internal API is used to validate the device pointer for + * null conditions. + * + * @param[in] dev : Structure instance of bmi2_dev. + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +static int8_t null_ptr_check(const struct bmi2_dev *dev); + +/*! + * @brief This internal API enables the selected sensor/features. + * + * @param[in] sensor_sel : Selects the desired sensor. + * @param[in, out] dev : Structure instance of bmi2_dev. + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +static int8_t sensor_enable(uint64_t sensor_sel, struct bmi2_dev *dev); + +/*! + * @brief This internal API disables the selected sensor/features. + * + * @param[in] sensor_sel : Selects the desired sensor. + * @param[in, out] dev : Structure instance of bmi2_dev. + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +static int8_t sensor_disable(uint64_t sensor_sel, struct bmi2_dev *dev); + +/*! + * @brief This internal API selects the sensors/features to be enabled or + * disabled. + * + * @param[in] sens_list : Pointer to select the sensor. + * @param[in] n_sens : Number of sensors selected. + * @param[out] sensor_sel : Gets the selected sensor. + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +static int8_t select_sensor(const uint8_t *sens_list, uint8_t n_sens, uint64_t *sensor_sel); + +/*! + * @brief This internal API is used to enable/disable step detector feature. + * + * @param[in] dev : Structure instance of bmi2_dev. + * @param[in] enable : Enables/Disables step-detector. + * + * Enable | Description + * -------------|--------------- + * BMI2_DISABLE | Disables step detector + * BMI2_ENABLE | Enables step detector + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +static int8_t set_step_detector(uint8_t enable, struct bmi2_dev *dev); + +/*! + * @brief This internal API is used to enable/disable step counter feature. + * + * @param[in] dev : Structure instance of bmi2_dev. + * @param[in] enable : Enables/Disables step counter. + * + * Enable | Description + * -------------|--------------- + * BMI2_DISABLE | Disables step counter + * BMI2_ENABLE | Enables step counter + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +static int8_t set_step_counter(uint8_t enable, struct bmi2_dev *dev); + +/*! + * @brief This internal API enables/disables the activity recognition feature. + * + * @param[in] enable : Enables/Disables activity recognition. + * @param[in] dev : Structure instance of bmi2_dev. + * + * enable | Description + * -------------|--------------- + * BMI2_ENABLE | Enables activity recognition. + * BMI2_DISABLE | Disables activity recognition. + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +static int8_t set_act_recog(uint8_t enable, struct bmi2_dev *dev); + +/*! + * @brief This internal API is used to enable/disable gyroscope user gain + * feature. + * + * @param[in] dev : Structure instance of bmi2_dev. + * @param[in] enable : Enables/Disables gyroscope user gain. + * + * Enable | Description + * -------------|--------------- + * BMI2_DISABLE | Disables gyroscope user gain + * BMI2_ENABLE | Enables gyroscope user gain + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +static int8_t set_gyro_user_gain(uint8_t enable, struct bmi2_dev *dev); + +/*! + * @brief This internal API sets step counter parameter configurations. + * + * @param[in] step_count_params : Array that stores parameters 1 to 25. + * @param[in] dev : Structure instance of bmi2_dev. + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +static int8_t set_step_count_params_config(const uint16_t *step_count_params, struct bmi2_dev *dev); + +/*! + * @brief This internal API sets step counter/detector/activity configurations. + * + * @param[in] config : Structure instance of bmi2_step_config. + * @param[in] dev : Structure instance of bmi2_dev. + * + *--------------------------------------------------------------------------- + * bmi2_step_config | + * Structure parameters | Description + *--------------------------|-------------------------------------------------- + * | The Step-counter will trigger output every time + * | the number of steps are counted. Holds implicitly + * water-mark level | a 20x factor, so the range is 0 to 10230, + * | with resolution of 20 steps. + * -------------------------|--------------------------------------------------- + * reset counter | Flag to reset the counted steps. + * -------------------------|--------------------------------------------------- + * @endverbatim + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +static int8_t set_step_config(const struct bmi2_step_config *config, struct bmi2_dev *dev); + +/*! + * @brief This internal API gets step counter parameter configurations. + * + * @param[in] step_count_params : Array that stores parameters 1 to 25. + * @param[in] dev : Structure instance of bmi2_dev. + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +static int8_t get_step_count_params_config(uint16_t *step_count_params, struct bmi2_dev *dev); + +/*! + * @brief This internal API gets step counter/detector/activity configurations. + * + * @param[out] config : Structure instance of bmi2_step_config. + * @param[in] dev : Structure instance of bmi2_dev. + * + * @verbatim + *---------------------------------------------------------------------------- + * bmi2_step_config | + * Structure parameters | Description + *--------------------------|-------------------------------------------------- + * | The Step-counter will trigger output every time + * | the number of steps are counted. Holds implicitly + * water-mark level | a 20x factor, so the range is 0 to 10230, + * | with resolution of 20 steps. + * -------------------------|--------------------------------------------------- + * reset counter | Flag to reset the counted steps. + * -------------------------|--------------------------------------------------- + * @endverbatim + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +static int8_t get_step_config(struct bmi2_step_config *config, struct bmi2_dev *dev); + +/*! + * @brief This internal API is used to parse and store the activity recognition + * output from the FIFO data. + * + * @param[out] act_recog : Structure to retrieve output of activity + * recognition frame. + * @param[in] data_index : Index of the FIFO data which contains + * activity recognition frame. + * @param[out] fifo : Structure instance of bmi2_dev. + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +static int8_t unpack_act_recog_output(struct bmi2_act_recog_output *act_recog, + uint16_t *data_index, + const struct bmi2_fifo_frame *fifo); + +/*! + * @brief This internal API gets the output values of step counter. + * + * @param[out] step_count : Pointer to the stored step counter data. + * @param[in] dev : Structure instance of bmi2_dev. + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +static int8_t get_step_counter_output(uint32_t *step_count, struct bmi2_dev *dev); + +/*! + * @brief This internal API gets the error status related to NVM. + * + * @param[out] nvm_err_stat : Stores the NVM error status. + * @param[in] dev : Structure instance of bmi2_dev. + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +static int8_t get_nvm_error_status(struct bmi2_nvm_err_status *nvm_err_stat, struct bmi2_dev *dev); + +/*! + * @brief This internal API gets the error status related to virtual frames. + * + * @param[out] vfrm_err_stat : Stores the VFRM related error status. + * @param[in] dev : Structure instance of bmi2_dev. + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +static int8_t get_vfrm_error_status(struct bmi2_vfrm_err_status *vfrm_err_stat, struct bmi2_dev *dev); + +/*! + * @brief This internal API is used to get enable status of gyroscope user gain + * update. + * + * @param[out] status : Stores status of gyroscope user gain update. + * @param[in] dev : Structure instance of bmi2_dev. + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +static int8_t get_user_gain_upd_status(uint8_t *status, struct bmi2_dev *dev); + +/*! + * @brief This internal API skips S4S frame in the FIFO data while getting + * activity recognition output. + * + * @param[in, out] frame_header : FIFO frame header. + * @param[in, out] data_index : Index value of the FIFO data bytes + * from which S4S frame header is to be + * skipped. + * @param[in] fifo : Structure instance of bmi2_fifo_frame. + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +static int8_t move_if_s4s_frame(const uint8_t *frame_header, uint16_t *data_index, const struct bmi2_fifo_frame *fifo); + +/*! + * @brief This internal API enables/disables compensation of the gain defined + * in the GAIN register. + * + * @param[in] enable : Enables/Disables gain compensation + * @param[in] dev : Structure instance of bmi2_dev. + * + * enable | Description + * -------------|--------------- + * BMI2_ENABLE | Enable gain compensation. + * BMI2_DISABLE | Disable gain compensation. + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +static int8_t enable_gyro_gain(uint8_t enable, struct bmi2_dev *dev); + +/*! + * @brief This internal API is used to extract the output feature configuration + * details like page and start address from the look-up table. + * + * @param[out] feat_output : Structure that stores output feature + * configurations. + * @param[in] type : Type of feature or sensor. + * @param[in] dev : Structure instance of bmi2_dev. + * + * @return Returns the feature found flag. + * + * @retval BMI2_FALSE : Feature not found + * BMI2_TRUE : Feature found + */ +static uint8_t extract_output_feat_config(struct bmi2_feature_config *feat_output, + uint8_t type, + const struct bmi2_dev *dev); + +/*! + * @brief This internal API is used to move the data index ahead of the + * current frame length parameter when unnecessary FIFO data appears while + * extracting the user specified data. + * + * @param[in,out] data_index : Index of the FIFO data which is to be + * moved ahead of the current frame length + * @param[in] current_frame_length : Number of bytes in the current frame. + * @param[in] fifo : Structure instance of bmi2_fifo_frame. + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +static int8_t move_next_frame(uint16_t *data_index, uint8_t current_frame_length, const struct bmi2_fifo_frame *fifo); + +/***************************************************************************/ + +/*! User Interface Definitions + ****************************************************************************/ + +/*! + * @brief This API: + * 1) Updates the device structure with address of the configuration file. + * 2) Initializes BMI270_HUAWEI_CONTEXT sensor. + * 3) Writes the configuration file. + * 4) Updates the feature offset parameters in the device structure. + * 5) Updates the maximum number of pages, in the device structure. + */ +int8_t bmi270_hc_init(struct bmi2_dev *dev) +{ + /* Variable to define error */ + int8_t rslt; + + /* Null-pointer check */ + rslt = null_ptr_check(dev); + if (rslt == BMI2_OK) + { + /* Assign chip id of BMI270_HUAWEI_CONTEXT */ + dev->chip_id = BMI270_HC_CHIP_ID; + + /* Get the size of config array */ + dev->config_size = sizeof(bmi270_hc_config_file); + + /* Enable the variant specific features if any */ + dev->variant_feature = BMI2_CRT_RTOSK_ENABLE | BMI2_GYRO_CROSS_SENS_ENABLE; + + /* An extra dummy byte is read during SPI read */ + if (dev->intf == BMI2_SPI_INTF) + { + dev->dummy_byte = 1; + } + else + { + dev->dummy_byte = 0; + } + + /* If configuration file pointer is not assigned any address */ + if (!dev->config_file_ptr) + { + /* Give the address of the configuration file array to + * the device pointer + */ + dev->config_file_ptr = bmi270_hc_config_file; + } + + /* Initialize BMI2 sensor */ + rslt = bmi2_sec_init(dev); + if (rslt == BMI2_OK) + { + /* Assign the offsets of the feature input + * configuration to the device structure + */ + dev->feat_config = bmi270_hc_feat_in; + + /* Assign the offsets of the feature output to + * the device structure + */ + dev->feat_output = bmi270_hc_feat_out; + + /* Assign the maximum number of pages to the + * device structure + */ + dev->page_max = BMI270_HC_MAX_PAGE_NUM; + + /* Assign maximum number of input sensors/ + * features to device structure + */ + dev->input_sens = BMI270_HC_MAX_FEAT_IN; + + /* Assign maximum number of output sensors/ + * features to device structure + */ + dev->out_sens = BMI270_HC_MAX_FEAT_OUT; + + /* Assign the offsets of the feature interrupt + * to the device structure + */ + dev->map_int = bmi270_hc_map_int; + + /* Assign maximum number of feature interrupts + * to device structure + */ + dev->sens_int_map = BMI270_HC_MAX_INT_MAP; + } + } + + return rslt; +} + +/*! + * @brief This API selects the sensors/features to be enabled. + */ +int8_t bmi270_hc_sensor_enable(const uint8_t *sens_list, uint8_t n_sens, struct bmi2_dev *dev) +{ + /* Variable to define error */ + int8_t rslt; + + /* Variable to select sensor */ + uint64_t sensor_sel = 0; + + /* Null-pointer check */ + rslt = null_ptr_check(dev); + if ((rslt == BMI2_OK) && (sens_list != NULL)) + { + /* Get the selected sensors */ + rslt = select_sensor(sens_list, n_sens, &sensor_sel); + if (rslt == BMI2_OK) + { + /* Enable the selected sensors */ + rslt = sensor_enable(sensor_sel, dev); + } + } + else + { + rslt = BMI2_E_NULL_PTR; + } + + return rslt; +} + +/*! + * @brief This API selects the sensors/features to be disabled. + */ +int8_t bmi270_hc_sensor_disable(const uint8_t *sens_list, uint8_t n_sens, struct bmi2_dev *dev) +{ + /* Variable to define error */ + int8_t rslt; + + /* Variable to select sensor */ + uint64_t sensor_sel = 0; + + /* Null-pointer check */ + rslt = null_ptr_check(dev); + if ((rslt == BMI2_OK) && (sens_list != NULL)) + { + /* Get the selected sensors */ + rslt = select_sensor(sens_list, n_sens, &sensor_sel); + if (rslt == BMI2_OK) + { + /* Disable the selected sensors */ + rslt = sensor_disable(sensor_sel, dev); + } + } + else + { + rslt = BMI2_E_NULL_PTR; + } + + return rslt; +} + +/*! + * @brief This API sets the sensor/feature configuration. + */ +int8_t bmi270_hc_set_sensor_config(struct bmi2_sens_config *sens_cfg, uint8_t n_sens, struct bmi2_dev *dev) +{ + /* Variable to define error */ + int8_t rslt; + + /* Variable to define loop */ + uint8_t loop; + + /* Variable to get the status of advance power save */ + uint8_t aps_stat = 0; + + /* Null-pointer check */ + rslt = null_ptr_check(dev); + if ((rslt == BMI2_OK) && (sens_cfg != NULL)) + { + /* Get status of advance power save mode */ + aps_stat = dev->aps_status; + + for (loop = 0; loop < n_sens; loop++) + { + if ((sens_cfg[loop].type == BMI2_ACCEL) || (sens_cfg[loop].type == BMI2_GYRO) || + (sens_cfg[loop].type == BMI2_AUX) || (sens_cfg[loop].type == BMI2_GYRO_GAIN_UPDATE)) + { + rslt = bmi2_set_sensor_config(&sens_cfg[loop], 1, dev); + } + else + { + /* Disable Advance power save if enabled for auxiliary + * and feature configurations + */ + if (aps_stat == BMI2_ENABLE) + { + /* Disable advance power save if + * enabled + */ + rslt = bmi2_set_adv_power_save(BMI2_DISABLE, dev); + } + + if (rslt == BMI2_OK) + { + switch (sens_cfg[loop].type) + { + /* Set the step counter parameters */ + case BMI2_STEP_COUNTER_PARAMS: + rslt = set_step_count_params_config(sens_cfg[loop].cfg.step_counter_params, dev); + break; + + /* Set step counter/detector/activity configuration */ + case BMI2_STEP_DETECTOR: + case BMI2_STEP_COUNTER: + rslt = set_step_config(&sens_cfg[loop].cfg.step_counter, dev); + break; + + default: + rslt = BMI2_E_INVALID_SENSOR; + break; + } + } + + /* Return error if any of the set configurations fail */ + if (rslt != BMI2_OK) + { + break; + } + } + } + + /* Enable Advance power save if disabled while configuring and + * not when already disabled + */ + if ((aps_stat == BMI2_ENABLE) && (rslt == BMI2_OK)) + { + rslt = bmi2_set_adv_power_save(BMI2_ENABLE, dev); + } + } + else + { + rslt = BMI2_E_NULL_PTR; + } + + return rslt; +} + +/*! + * @brief This API gets the sensor/feature configuration. + */ +int8_t bmi270_hc_get_sensor_config(struct bmi2_sens_config *sens_cfg, uint8_t n_sens, struct bmi2_dev *dev) +{ + /* Variable to define error */ + int8_t rslt; + + /* Variable to define loop */ + uint8_t loop; + + /* Variable to get the status of advance power save */ + uint8_t aps_stat = 0; + + /* Null-pointer check */ + rslt = null_ptr_check(dev); + if ((rslt == BMI2_OK) && (sens_cfg != NULL)) + { + /* Get status of advance power save mode */ + aps_stat = dev->aps_status; + for (loop = 0; loop < n_sens; loop++) + { + if ((sens_cfg[loop].type == BMI2_ACCEL) || (sens_cfg[loop].type == BMI2_GYRO) || + (sens_cfg[loop].type == BMI2_AUX) || (sens_cfg[loop].type == BMI2_GYRO_GAIN_UPDATE)) + { + rslt = bmi2_get_sensor_config(&sens_cfg[loop], 1, dev); + } + else + { + /* Disable Advance power save if enabled for auxiliary + * and feature configurations + */ + if ((sens_cfg[loop].type >= BMI2_MAIN_SENS_MAX_NUM) || (sens_cfg[loop].type == BMI2_AUX)) + { + + if (aps_stat == BMI2_ENABLE) + { + /* Disable advance power save if + * enabled + */ + rslt = bmi2_set_adv_power_save(BMI2_DISABLE, dev); + } + } + + if (rslt == BMI2_OK) + { + switch (sens_cfg[loop].type) + { + /* Set the step counter parameters */ + case BMI2_STEP_COUNTER_PARAMS: + rslt = get_step_count_params_config(sens_cfg[loop].cfg.step_counter_params, dev); + break; + + /* Get step counter/detector/activity configuration */ + case BMI2_STEP_DETECTOR: + case BMI2_STEP_COUNTER: + rslt = get_step_config(&sens_cfg[loop].cfg.step_counter, dev); + break; + + default: + rslt = BMI2_E_INVALID_SENSOR; + break; + } + } + + /* Return error if any of the get configurations fail */ + if (rslt != BMI2_OK) + { + break; + } + } + } + + /* Enable Advance power save if disabled while configuring and + * not when already disabled + */ + if ((aps_stat == BMI2_ENABLE) && (rslt == BMI2_OK)) + { + rslt = bmi2_set_adv_power_save(BMI2_ENABLE, dev); + } + } + else + { + rslt = BMI2_E_NULL_PTR; + } + + return rslt; +} + +/*! + * @brief This API gets the sensor/feature data for accelerometer, gyroscope, + * auxiliary sensor, step counter, high-g, gyroscope user-gain update, + * orientation, gyroscope cross sensitivity and error status for NVM and VFRM. + */ +int8_t bmi270_hc_get_sensor_data(struct bmi2_sensor_data *sensor_data, uint8_t n_sens, struct bmi2_dev *dev) +{ + /* Variable to define error */ + int8_t rslt; + + /* Variable to define loop */ + uint8_t loop; + + /* Variable to get the status of advance power save */ + uint8_t aps_stat = 0; + + /* Null-pointer check */ + rslt = null_ptr_check(dev); + if ((rslt == BMI2_OK) && (sensor_data != NULL)) + { + /* Get status of advance power save mode */ + aps_stat = dev->aps_status; + for (loop = 0; loop < n_sens; loop++) + { + if ((sensor_data[loop].type == BMI2_ACCEL) || (sensor_data[loop].type == BMI2_GYRO) || + (sensor_data[loop].type == BMI2_AUX) || (sensor_data[loop].type == BMI2_GYRO_GAIN_UPDATE) || + (sensor_data[loop].type == BMI2_GYRO_CROSS_SENSE)) + { + rslt = bmi2_get_sensor_data(&sensor_data[loop], 1, dev); + } + else + { + /* Disable Advance power save if enabled for feature + * configurations + */ + if (sensor_data[loop].type >= BMI2_MAIN_SENS_MAX_NUM) + { + if (aps_stat == BMI2_ENABLE) + { + /* Disable advance power save if + * enabled + */ + rslt = bmi2_set_adv_power_save(BMI2_DISABLE, dev); + } + } + + if (rslt == BMI2_OK) + { + switch (sensor_data[loop].type) + { + case BMI2_STEP_COUNTER: + + /* Get step counter output */ + rslt = get_step_counter_output(&sensor_data[loop].sens_data.step_counter_output, dev); + break; + case BMI2_NVM_STATUS: + + /* Get NVM error status */ + rslt = get_nvm_error_status(&sensor_data[loop].sens_data.nvm_status, dev); + break; + case BMI2_VFRM_STATUS: + + /* Get VFRM error status */ + rslt = get_vfrm_error_status(&sensor_data[loop].sens_data.vfrm_status, dev); + break; + default: + rslt = BMI2_E_INVALID_SENSOR; + break; + } + + /* Return error if any of the get sensor data fails */ + if (rslt != BMI2_OK) + { + break; + } + } + } + + /* Enable Advance power save if disabled while + * configuring and not when already disabled + */ + if ((aps_stat == BMI2_ENABLE) && (rslt == BMI2_OK)) + { + rslt = bmi2_set_adv_power_save(BMI2_ENABLE, dev); + } + } + } + else + { + rslt = BMI2_E_NULL_PTR; + } + + return rslt; +} + +/*! + * @brief This api is used for retrieving the activity recognition settings currently set for bmi270hc. + */ +int8_t bmi270_hc_get_act_recg_sett(struct bmi2_hc_act_recg_sett *sett, struct bmi2_dev *dev) +{ + /* Variable to define error */ + int8_t rslt; + + /* Array to define the feature configuration */ + uint8_t feat_config[BMI2_FEAT_SIZE_IN_BYTES] = { 0 }; + + /* Variable to define the array offset */ + uint8_t idx = 0; + + /* Variable to get the status of advance power save */ + uint8_t aps_stat; + + /* Variable to set flag */ + uint8_t feat_found; + uint16_t msb_lsb; + uint8_t lsb; + uint8_t msb; + + /* Initialize feature configuration for activity recognition */ + struct bmi2_feature_config bmi2_act_recg_sett = { 0, 0, 0 }; + + /* Null-pointer check */ + rslt = null_ptr_check(dev); + if (rslt == BMI2_OK) + { + /* Search for activity recognition feature and extract its configuration details */ + feat_found = bmi2_extract_input_feat_config(&bmi2_act_recg_sett, BMI2_ACTIVITY_RECOGNITION_SETTINGS, dev); + if (feat_found) + { + aps_stat = dev->aps_status; + if (aps_stat == BMI2_ENABLE) + { + /* Disable advance power save if enabled */ + rslt = bmi2_set_adv_power_save(BMI2_DISABLE, dev); + } + + /* Get the configuration from the page where activity recognition setting feature resides */ + if (rslt == BMI2_OK) + { + rslt = bmi2_get_feat_config(bmi2_act_recg_sett.page, feat_config, dev); + } + + if (rslt == BMI2_OK) + { + /* Define the offset in bytes */ + idx = bmi2_act_recg_sett.start_addr; + + lsb = feat_config[idx++]; + msb = feat_config[idx++]; + msb_lsb = ((uint16_t)msb << 8) | lsb; + + sett->segment_size = msb_lsb & BMI2_HC_ACT_RECG_SEGMENT_SIZE_MASK; + + /* Increment idx by 2 to point post processing enable/disable address */ + idx = 4; + lsb = feat_config[idx++]; + msb = feat_config[idx++]; + msb_lsb = ((uint16_t)msb << 8) | lsb; + sett->pp_en = msb_lsb & BMI2_HC_ACT_RECG_PP_EN_MASK; + + /* Increment idx by 2 to point mix gdi thres addres */ + idx = 6; + lsb = feat_config[idx++]; + msb = feat_config[idx++]; + msb_lsb = ((uint16_t)msb << 8) | lsb; + sett->min_gdi_thres = msb_lsb & BMI2_HC_ACT_RECG_MIN_GDI_THRES_MASK; + + /* Increment idx by 2 to point max gdi thres addres */ + idx = 8; + lsb = feat_config[idx++]; + msb = feat_config[idx++]; + msb_lsb = ((uint16_t)msb << 8) | lsb; + sett->max_gdi_thres = msb_lsb & BMI2_HC_ACT_RECG_MAX_GDI_THRES_MASK; + + /* Increment idx by 2 to point to buffer size */ + idx = 10; + lsb = feat_config[idx++]; + msb = feat_config[idx++]; + msb_lsb = ((uint16_t)msb << 8) | lsb; + sett->buf_size = msb_lsb & BMI2_HC_ACT_RECG_BUF_SIZE_MASK; + + /* Increment idx by 2 to to point to min segment confidence */ + idx = 12; + lsb = feat_config[idx++]; + msb = feat_config[idx++]; + msb_lsb = ((uint16_t)msb << 8) | lsb; + sett->min_seg_conf = msb_lsb & BMI2_HC_ACT_RECG_MIN_SEG_CONF_MASK; + } + + /* Enable Advance power save if disabled while + * configuring and not when already disabled + */ + if ((aps_stat == BMI2_ENABLE) && (rslt == BMI2_OK)) + { + rslt = bmi2_set_adv_power_save(BMI2_ENABLE, dev); + } + } + else + { + rslt = BMI2_E_INVALID_SENSOR; + } + } + + return rslt; +} + +/*! + * @brief This api is used for setting the activity recognition settings for bmi270hc. + */ +int8_t bmi270_hc_set_act_recg_sett(const struct bmi2_hc_act_recg_sett *sett, struct bmi2_dev *dev) +{ + /* Variable to define error */ + int8_t rslt; + + /* Array to define the feature configuration */ + uint8_t feat_config[BMI2_FEAT_SIZE_IN_BYTES] = { 0 }; + + /* Variable to define the array offset */ + uint8_t idx = 0; + + /* Variable to get the status of advance power save */ + uint8_t aps_stat; + + /* Variable to set flag */ + uint8_t feat_found; + + /* Variable to define index */ + uint8_t index = 0; + + /* Initialize feature configuration for activity recognition */ + struct bmi2_feature_config bmi2_act_recg_sett = { 0, 0, 0 }; + + /* Copy the feature configuration address to a local pointer */ + uint16_t *data_p = (uint16_t *) (void *)feat_config; + + /* Null-pointer check */ + rslt = null_ptr_check(dev); + if (rslt == BMI2_OK) + { + /* Search for activity recognition feature and extract its configuration details */ + feat_found = bmi2_extract_input_feat_config(&bmi2_act_recg_sett, BMI2_ACTIVITY_RECOGNITION_SETTINGS, dev); + if (feat_found) + { + aps_stat = dev->aps_status; + if (aps_stat == BMI2_ENABLE) + { + /* Disable advance power save if enabled */ + rslt = bmi2_set_adv_power_save(BMI2_DISABLE, dev); + } + + if (rslt == BMI2_OK) + { + /* Get the configuration from the page where activity recognition setting feature resides */ + rslt = bmi2_get_feat_config(bmi2_act_recg_sett.page, feat_config, dev); + if (rslt == BMI2_OK) + { + /* Define the offset in bytes */ + idx = bmi2_act_recg_sett.start_addr; + + /* Get offset in words since all the features are set in words length */ + idx = idx / 2; + + /* Set segment size */ + *(data_p + idx) = BMI2_SET_BIT_POS0(*(data_p + idx), + BMI2_HC_ACT_RECG_SEGMENT_SIZE, + sett->segment_size); + + /* Starting address of post processing represented in word length */ + idx = 2; + + /* Set post processing */ + *(data_p + idx) = BMI2_SET_BIT_POS0(*(data_p + idx), BMI2_HC_ACT_RECG_PP_EN, sett->pp_en); + + /* Starting address of min_gdi_thres represented in word length */ + idx = 3; + + /* Set minimum gdi threshold */ + *(data_p + idx) = BMI2_SET_BIT_POS0(*(data_p + idx), + BMI2_HC_ACT_RECG_MIN_GDI_THRES, + sett->min_gdi_thres); + + /* Starting address of max_gdi_thres represented in word length */ + idx = 4; + + /* Set maximum gdi threshold */ + *(data_p + idx) = BMI2_SET_BIT_POS0(*(data_p + idx), + BMI2_HC_ACT_RECG_MAX_GDI_THRES, + sett->max_gdi_thres); + + /* Starting address of buffer size represented in word length */ + idx = 5; + + /* Set buffer size */ + *(data_p + idx) = BMI2_SET_BIT_POS0(*(data_p + idx), BMI2_HC_ACT_RECG_BUF_SIZE, sett->buf_size); + + /* Starting address of min_seg_conf represented in word length */ + idx = 6; + + /* Set min segment confidence */ + *(data_p + idx) = BMI2_SET_BIT_POS0(*(data_p + idx), + BMI2_HC_ACT_RECG_MIN_SEG_CONF, + sett->min_seg_conf); + + /* Increment offset by 1 more word to get the total length in words */ + idx++; + + /* Get total length in bytes to copy from local pointer to the array */ + idx = (uint8_t)(idx * 2) - bmi2_act_recg_sett.start_addr; + + /* Copy the bytes to be set back to the array */ + for (index = 0; index <= idx; index++) + { + feat_config[bmi2_act_recg_sett.start_addr + + index] = *((uint8_t *) data_p + bmi2_act_recg_sett.start_addr + index); + } + + rslt = bmi2_set_regs(BMI2_FEATURES_REG_ADDR, feat_config, BMI2_FEAT_SIZE_IN_BYTES, dev); + } + } + + /* Enable Advance power save if disabled while + * configuring and not when already disabled + */ + if ((aps_stat == BMI2_ENABLE) && (rslt == BMI2_OK)) + { + rslt = bmi2_set_adv_power_save(BMI2_ENABLE, dev); + } + } + else + { + rslt = BMI2_E_INVALID_SENSOR; + } + } + + return rslt; +} + +/*! + * @brief This internal API is used to parse the activity output from the + * FIFO in header mode. + */ +int8_t bmi270_hc_get_act_recog_output(struct bmi2_act_recog_output *act_recog, + uint16_t *act_frm_len, + struct bmi2_fifo_frame *fifo, + const struct bmi2_dev *dev) +{ + /* Variable to define error */ + int8_t rslt; + + /* Variable to define header frame */ + uint8_t frame_header = 0; + + /* Variable to index the data bytes */ + uint16_t data_index; + + /* Variable to index activity frames */ + uint16_t act_idx = 0; + + /* Variable to indicate activity frames read */ + uint16_t frame_to_read = 0; + + /* Null-pointer check */ + rslt = null_ptr_check(dev); + if ((rslt == BMI2_OK) && (act_recog != NULL) && (act_frm_len != NULL) && (fifo != NULL)) + { + + /* Store the number of frames to be read */ + frame_to_read = *act_frm_len; + for (data_index = fifo->act_recog_byte_start_idx; data_index < fifo->length;) + { + /* Get frame header byte */ + frame_header = fifo->data[data_index] & BMI2_FIFO_TAG_INTR_MASK; + + /* Skip S4S frames if S4S is enabled */ + rslt = move_if_s4s_frame(&frame_header, &data_index, fifo); + + /* Break if FIFO is empty */ + if (rslt == BMI2_W_FIFO_EMPTY) + { + break; + } + + /* Index shifted to next byte where data starts */ + data_index++; + switch (frame_header) + { + /* If header defines accelerometer frame */ + case BMI2_FIFO_HEADER_ACC_FRM: + rslt = move_next_frame(&data_index, fifo->acc_frm_len, fifo); + break; + + /* If header defines accelerometer and auxiliary frames */ + case BMI2_FIFO_HEADER_AUX_ACC_FRM: + rslt = move_next_frame(&data_index, fifo->acc_aux_frm_len, fifo); + break; + + /* If header defines accelerometer and gyroscope frames */ + case BMI2_FIFO_HEADER_GYR_ACC_FRM: + rslt = move_next_frame(&data_index, fifo->acc_gyr_frm_len, fifo); + break; + + /* If header defines accelerometer, auxiliary and gyroscope frames */ + case BMI2_FIFO_HEADER_ALL_FRM: + rslt = move_next_frame(&data_index, fifo->all_frm_len, fifo); + break; + + /* If header defines only gyroscope frame */ + case BMI2_FIFO_HEADER_GYR_FRM: + rslt = move_next_frame(&data_index, fifo->gyr_frm_len, fifo); + break; + + /* If header defines only auxiliary frame */ + case BMI2_FIFO_HEADER_AUX_FRM: + rslt = move_next_frame(&data_index, fifo->aux_frm_len, fifo); + break; + + /* If header defines auxiliary and gyroscope frame */ + case BMI2_FIFO_HEADER_AUX_GYR_FRM: + rslt = move_next_frame(&data_index, fifo->aux_gyr_frm_len, fifo); + break; + + /* If header defines sensor time frame */ + case BMI2_FIFO_HEADER_SENS_TIME_FRM: + rslt = move_next_frame(&data_index, BMI2_SENSOR_TIME_LENGTH, fifo); + break; + + /* If header defines skip frame */ + case BMI2_FIFO_HEADER_SKIP_FRM: + rslt = move_next_frame(&data_index, BMI2_FIFO_SKIP_FRM_LENGTH, fifo); + break; + + /* If header defines Input configuration frame */ + case BMI2_FIFO_HEADER_INPUT_CFG_FRM: + rslt = move_next_frame(&data_index, BMI2_FIFO_INPUT_CFG_LENGTH, fifo); + break; + + /* If header defines invalid frame or end of valid data */ + case BMI2_FIFO_HEAD_OVER_READ_MSB: + + /* Move the data index to the last byte to mark completion */ + data_index = fifo->length; + + /* FIFO is empty */ + rslt = BMI2_W_FIFO_EMPTY; + break; + + /* If header defines activity recognition frame */ + case BMI2_FIFO_VIRT_ACT_RECOG_FRM: + + /* Get the activity output */ + rslt = unpack_act_recog_output(&act_recog[(act_idx)], &data_index, fifo); + + /* Update activity frame index */ + (act_idx)++; + break; + default: + + /* Move the data index to the last byte in case of invalid values */ + data_index = fifo->length; + + /* FIFO is empty */ + rslt = BMI2_W_FIFO_EMPTY; + break; + } + + /* Number of frames to be read is complete or FIFO is empty */ + if ((frame_to_read == act_idx) || (rslt == BMI2_W_FIFO_EMPTY)) + { + break; + } + } + + /* Update the activity frame index */ + (*act_frm_len) = act_idx; + + /* Update the activity byte index */ + fifo->act_recog_byte_start_idx = data_index; + } + else + { + rslt = BMI2_E_NULL_PTR; + } + + return rslt; +} + +/*! + * @brief This API updates the gyroscope user-gain. + */ +int8_t bmi270_hc_update_gyro_user_gain(const struct bmi2_gyro_user_gain_config *user_gain, struct bmi2_dev *dev) +{ + /* Variable to define error */ + int8_t rslt; + + /* Variable to select sensor */ + uint8_t sens_sel[2] = { BMI2_GYRO, BMI2_GYRO_GAIN_UPDATE }; + + /* Structure to define sensor configurations */ + struct bmi2_sens_config sens_cfg; + + /* Variable to store status of user-gain update module */ + uint8_t status = 0; + + /* Variable to define count */ + uint8_t count = 100; + + /* Null-pointer check */ + rslt = null_ptr_check(dev); + if ((rslt == BMI2_OK) && (user_gain != NULL)) + { + /* Select type of feature */ + sens_cfg.type = BMI2_GYRO_GAIN_UPDATE; + + /* Get the user gain configurations */ + rslt = bmi270_hc_get_sensor_config(&sens_cfg, 1, dev); + if (rslt == BMI2_OK) + { + /* Get the user-defined ratio */ + sens_cfg.cfg.gyro_gain_update = *user_gain; + + /* Set rate ratio for all axes */ + rslt = bmi270_hc_set_sensor_config(&sens_cfg, 1, dev); + } + + /* Disable gyroscope */ + if (rslt == BMI2_OK) + { + rslt = bmi270_hc_sensor_disable(&sens_sel[0], 1, dev); + } + + /* Enable gyroscope user-gain update module */ + if (rslt == BMI2_OK) + { + rslt = bmi270_hc_sensor_enable(&sens_sel[1], 1, dev); + } + + /* Set the command to trigger the computation */ + if (rslt == BMI2_OK) + { + rslt = bmi2_set_command_register(BMI2_USR_GAIN_CMD, dev); + } + + if (rslt == BMI2_OK) + { + /* Poll until enable bit of user-gain update is 0 */ + while (count--) + { + rslt = get_user_gain_upd_status(&status, dev); + if ((rslt == BMI2_OK) && (status == 0)) + { + /* Enable compensation of gain defined + * in the GAIN register + */ + rslt = enable_gyro_gain(BMI2_ENABLE, dev); + + /* Enable gyroscope */ + if (rslt == BMI2_OK) + { + rslt = bmi270_hc_sensor_enable(&sens_sel[0], 1, dev); + } + + break; + } + + dev->delay_us(10000, dev->intf_ptr); + } + + /* Return error if user-gain update is failed */ + if ((rslt == BMI2_OK) && (status != 0)) + { + rslt = BMI2_E_GYR_USER_GAIN_UPD_FAIL; + } + } + } + else + { + rslt = BMI2_E_NULL_PTR; + } + + return rslt; +} + +/*! + * @brief This API reads the compensated gyroscope user-gain values. + */ +int8_t bmi270_hc_read_gyro_user_gain(struct bmi2_gyro_user_gain_data *gyr_usr_gain, struct bmi2_dev *dev) +{ + /* Variable to define error */ + int8_t rslt; + + /* Variable to define register data */ + uint8_t reg_data[3] = { 0 }; + + /* Null-pointer check */ + rslt = null_ptr_check(dev); + if ((rslt == BMI2_OK) && (gyr_usr_gain != NULL)) + { + /* Get the gyroscope compensated gain values */ + rslt = bmi2_get_regs(BMI2_GYR_USR_GAIN_0_ADDR, reg_data, 3, dev); + if (rslt == BMI2_OK) + { + /* Gyroscope user gain correction X-axis */ + gyr_usr_gain->x = (int8_t)BMI2_GET_BIT_POS0(reg_data[0], BMI2_GYR_USR_GAIN_X); + + /* Gyroscope user gain correction Y-axis */ + gyr_usr_gain->y = (int8_t)BMI2_GET_BIT_POS0(reg_data[1], BMI2_GYR_USR_GAIN_Y); + + /* Gyroscope user gain correction z-axis */ + gyr_usr_gain->z = (int8_t)BMI2_GET_BIT_POS0(reg_data[2], BMI2_GYR_USR_GAIN_Z); + } + } + else + { + rslt = BMI2_E_NULL_PTR; + } + + return rslt; +} + +/*! + * @brief This API maps/unmaps feature interrupts to that of interrupt pins. + */ +int8_t bmi270_hc_map_feat_int(const struct bmi2_sens_int_config *sens_int, uint8_t n_sens, struct bmi2_dev *dev) +{ + /* Variable to define error */ + int8_t rslt; + + /* Variable to define loop */ + uint8_t loop; + + /* Null-pointer check */ + rslt = null_ptr_check(dev); + if ((rslt == BMI2_OK) && (sens_int != NULL)) + { + for (loop = 0; loop < n_sens; loop++) + { + switch (sens_int[loop].type) + { + case BMI2_STEP_COUNTER: + case BMI2_STEP_DETECTOR: + + rslt = bmi2_map_feat_int(sens_int[loop].type, sens_int[loop].hw_int_pin, dev); + break; + default: + rslt = BMI2_E_INVALID_SENSOR; + break; + } + + /* Return error if interrupt mapping fails */ + if (rslt != BMI2_OK) + { + break; + } + } + } + else + { + rslt = BMI2_E_NULL_PTR; + } + + return rslt; +} + +/***************************************************************************/ + +/*! Local Function Definitions + ****************************************************************************/ + +/*! + * @brief This internal API is used to validate the device structure pointer for + * null conditions. + */ +static int8_t null_ptr_check(const struct bmi2_dev *dev) +{ + /* Variable to define error */ + int8_t rslt = BMI2_OK; + + if ((dev == NULL) || (dev->read == NULL) || (dev->write == NULL) || (dev->delay_us == NULL)) + { + /* Device structure pointer is not valid */ + rslt = BMI2_E_NULL_PTR; + } + + return rslt; +} + +/*! + * @brief This internal API selects the sensor/features to be enabled or + * disabled. + */ +static int8_t select_sensor(const uint8_t *sens_list, uint8_t n_sens, uint64_t *sensor_sel) +{ + /* Variable to define error */ + int8_t rslt = BMI2_OK; + + /* Variable to define loop */ + uint8_t count; + + for (count = 0; count < n_sens; count++) + { + switch (sens_list[count]) + { + case BMI2_ACCEL: + *sensor_sel |= BMI2_ACCEL_SENS_SEL; + break; + case BMI2_GYRO: + *sensor_sel |= BMI2_GYRO_SENS_SEL; + break; + case BMI2_AUX: + *sensor_sel |= BMI2_AUX_SENS_SEL; + break; + case BMI2_TEMP: + *sensor_sel |= BMI2_TEMP_SENS_SEL; + break; + case BMI2_STEP_DETECTOR: + *sensor_sel |= BMI2_STEP_DETECT_SEL; + break; + case BMI2_STEP_COUNTER: + *sensor_sel |= BMI2_STEP_COUNT_SEL; + break; + case BMI2_GYRO_GAIN_UPDATE: + *sensor_sel |= BMI2_GYRO_GAIN_UPDATE_SEL; + break; + case BMI2_ACTIVITY_RECOGNITION: + *sensor_sel |= BMI2_ACTIVITY_RECOGNITION_SEL; + break; + default: + rslt = BMI2_E_INVALID_SENSOR; + break; + } + } + + return rslt; +} + +/*! + * @brief This internal API enables the selected sensor/features. + */ +static int8_t sensor_enable(uint64_t sensor_sel, struct bmi2_dev *dev) +{ + /* Variable to define error */ + int8_t rslt; + + /* Variable to store register values */ + uint8_t reg_data = 0; + + /* Variable to define loop */ + uint8_t loop = 1; + + /* Variable to get the status of advance power save */ + uint8_t aps_stat = 0; + + rslt = bmi2_get_regs(BMI2_PWR_CTRL_ADDR, ®_data, 1, dev); + if (rslt == BMI2_OK) + { + /* Enable accelerometer */ + if (sensor_sel & BMI2_ACCEL_SENS_SEL) + { + reg_data = BMI2_SET_BITS(reg_data, BMI2_ACC_EN, BMI2_ENABLE); + } + + /* Enable gyroscope */ + if (sensor_sel & BMI2_GYRO_SENS_SEL) + { + reg_data = BMI2_SET_BITS(reg_data, BMI2_GYR_EN, BMI2_ENABLE); + } + + /* Enable auxiliary sensor */ + if (sensor_sel & BMI2_AUX_SENS_SEL) + { + reg_data = BMI2_SET_BIT_POS0(reg_data, BMI2_AUX_EN, BMI2_ENABLE); + } + + /* Enable temperature sensor */ + if (sensor_sel & BMI2_TEMP_SENS_SEL) + { + reg_data = BMI2_SET_BITS(reg_data, BMI2_TEMP_EN, BMI2_ENABLE); + } + + /* Enable the sensors that are set in the power control register */ + if (sensor_sel & BMI2_MAIN_SENSORS) + { + rslt = bmi2_set_regs(BMI2_PWR_CTRL_ADDR, ®_data, 1, dev); + } + } + + if ((rslt == BMI2_OK) && (sensor_sel & ~(BMI2_MAIN_SENSORS))) + { + /* Get status of advance power save mode */ + aps_stat = dev->aps_status; + if (aps_stat == BMI2_ENABLE) + { + /* Disable advance power save if enabled */ + rslt = bmi2_set_adv_power_save(BMI2_DISABLE, dev); + } + + if (rslt == BMI2_OK) + { + while (loop--) + { + /* Enable step detector feature */ + if (sensor_sel & BMI2_STEP_DETECT_SEL) + { + rslt = set_step_detector(BMI2_ENABLE, dev); + if (rslt == BMI2_OK) + { + dev->sens_en_stat |= BMI2_STEP_DETECT_SEL; + } + else + { + break; + } + } + + /* Enable step counter feature */ + if (sensor_sel & BMI2_STEP_COUNT_SEL) + { + rslt = set_step_counter(BMI2_ENABLE, dev); + if (rslt == BMI2_OK) + { + dev->sens_en_stat |= BMI2_STEP_COUNT_SEL; + } + else + { + break; + } + } + + /* Enable activity recognition feature */ + if (sensor_sel & BMI2_ACTIVITY_RECOGNITION_SEL) + { + rslt = set_act_recog(BMI2_ENABLE, dev); + if (rslt == BMI2_OK) + { + dev->sens_en_stat |= BMI2_ACTIVITY_RECOGNITION_SEL; + } + else + { + break; + } + } + + /* Enable gyroscope user gain */ + if (sensor_sel & BMI2_GYRO_GAIN_UPDATE_SEL) + { + rslt = set_gyro_user_gain(BMI2_ENABLE, dev); + if (rslt == BMI2_OK) + { + dev->sens_en_stat |= BMI2_GYRO_GAIN_UPDATE_SEL; + } + else + { + break; + } + } + } + + /* Enable Advance power save if disabled while + * configuring and not when already disabled + */ + if ((aps_stat == BMI2_ENABLE) && (rslt == BMI2_OK)) + { + rslt = bmi2_set_adv_power_save(BMI2_ENABLE, dev); + } + } + } + + return rslt; +} + +/*! + * @brief This internal API disables the selected sensors/features. + */ +static int8_t sensor_disable(uint64_t sensor_sel, struct bmi2_dev *dev) +{ + /* Variable to define error */ + int8_t rslt; + + /* Variable to store register values */ + uint8_t reg_data = 0; + + /* Variable to define loop */ + uint8_t loop = 1; + + /* Variable to get the status of advance power save */ + uint8_t aps_stat = 0; + + rslt = bmi2_get_regs(BMI2_PWR_CTRL_ADDR, ®_data, 1, dev); + if (rslt == BMI2_OK) + { + /* Disable accelerometer */ + if (sensor_sel & BMI2_ACCEL_SENS_SEL) + { + reg_data = BMI2_SET_BIT_VAL0(reg_data, BMI2_ACC_EN); + } + + /* Disable gyroscope */ + if (sensor_sel & BMI2_GYRO_SENS_SEL) + { + reg_data = BMI2_SET_BIT_VAL0(reg_data, BMI2_GYR_EN); + } + + /* Disable auxiliary sensor */ + if (sensor_sel & BMI2_AUX_SENS_SEL) + { + reg_data = BMI2_SET_BIT_VAL0(reg_data, BMI2_AUX_EN); + } + + /* Disable temperature sensor */ + if (sensor_sel & BMI2_TEMP_SENS_SEL) + { + reg_data = BMI2_SET_BIT_VAL0(reg_data, BMI2_TEMP_EN); + } + + /* Disable the sensors that are set in the power control register */ + if (sensor_sel & BMI2_MAIN_SENSORS) + { + rslt = bmi2_set_regs(BMI2_PWR_CTRL_ADDR, ®_data, 1, dev); + } + } + + if ((rslt == BMI2_OK) && (sensor_sel & ~(BMI2_MAIN_SENSORS))) + { + /* Get status of advance power save mode */ + aps_stat = dev->aps_status; + if (aps_stat == BMI2_ENABLE) + { + /* Disable advance power save if enabled */ + rslt = bmi2_set_adv_power_save(BMI2_DISABLE, dev); + } + + if (rslt == BMI2_OK) + { + while (loop--) + { + /* Disable step detector feature */ + if (sensor_sel & BMI2_STEP_DETECT_SEL) + { + rslt = set_step_detector(BMI2_DISABLE, dev); + if (rslt == BMI2_OK) + { + dev->sens_en_stat &= ~BMI2_STEP_DETECT_SEL; + } + else + { + break; + } + } + + /* Disable step counter feature */ + if (sensor_sel & BMI2_STEP_COUNT_SEL) + { + rslt = set_step_counter(BMI2_DISABLE, dev); + if (rslt == BMI2_OK) + { + dev->sens_en_stat &= ~BMI2_STEP_COUNT_SEL; + } + else + { + break; + } + } + + /* Disable activity recognition feature */ + if (sensor_sel & BMI2_ACTIVITY_RECOGNITION_SEL) + { + rslt = set_act_recog(BMI2_DISABLE, dev); + if (rslt == BMI2_OK) + { + dev->sens_en_stat |= BMI2_ACTIVITY_RECOGNITION_SEL; + } + else + { + break; + } + } + + /* Disable gyroscope user gain */ + if (sensor_sel & BMI2_GYRO_GAIN_UPDATE_SEL) + { + rslt = set_gyro_user_gain(BMI2_DISABLE, dev); + if (rslt == BMI2_OK) + { + dev->sens_en_stat &= ~BMI2_GYRO_GAIN_UPDATE_SEL; + } + else + { + break; + } + } + + /* Enable Advance power save if disabled while + * configuring and not when already disabled + */ + if ((aps_stat == BMI2_ENABLE) && (rslt == BMI2_OK)) + { + rslt = bmi2_set_adv_power_save(BMI2_ENABLE, dev); + } + } + } + } + + return rslt; +} + +/*! + * @brief This internal API is used to enable/disable step detector feature. + */ +static int8_t set_step_detector(uint8_t enable, struct bmi2_dev *dev) +{ + /* Variable to define error */ + int8_t rslt; + + /* Array to define the feature configuration */ + uint8_t feat_config[BMI2_FEAT_SIZE_IN_BYTES] = { 0 }; + + /* Variable to define the array offset */ + uint8_t idx = 0; + + /* Variable to set flag */ + uint8_t feat_found; + + /* Initialize feature configuration for step detector */ + struct bmi2_feature_config step_det_config = { 0, 0, 0 }; + + /* Search for step detector feature and extract its configuration details */ + feat_found = bmi2_extract_input_feat_config(&step_det_config, BMI2_STEP_DETECTOR, dev); + if (feat_found) + { + /* Get the configuration from the page where step detector feature resides */ + rslt = bmi2_get_feat_config(step_det_config.page, feat_config, dev); + if (rslt == BMI2_OK) + { + /* Define the offset for enable/disable of step detector */ + idx = step_det_config.start_addr + BMI2_STEP_COUNT_FEAT_EN_OFFSET; + + /* Set the feature enable bit */ + feat_config[idx] = BMI2_SET_BITS(feat_config[idx], BMI2_STEP_DET_FEAT_EN, enable); + + /* Set the configuration back to the page */ + rslt = bmi2_set_regs(BMI2_FEATURES_REG_ADDR, feat_config, BMI2_FEAT_SIZE_IN_BYTES, dev); + } + } + else + { + rslt = BMI2_E_INVALID_SENSOR; + } + + return rslt; +} + +/*! + * @brief This internal API is used to enable/disable step counter feature. + */ +static int8_t set_step_counter(uint8_t enable, struct bmi2_dev *dev) +{ + /* Variable to define error */ + int8_t rslt; + + /* Array to define the feature configuration */ + uint8_t feat_config[BMI2_FEAT_SIZE_IN_BYTES] = { 0 }; + + /* Variable to define the array offset */ + uint8_t idx = 0; + + /* Variable to set flag */ + uint8_t feat_found; + + /* Initialize feature configuration for step counter */ + struct bmi2_feature_config step_count_config = { 0, 0, 0 }; + + /* Search for step counter feature and extract its configuration details */ + feat_found = bmi2_extract_input_feat_config(&step_count_config, BMI2_STEP_COUNTER, dev); + if (feat_found) + { + /* Get the configuration from the page where step-counter feature resides */ + rslt = bmi2_get_feat_config(step_count_config.page, feat_config, dev); + if (rslt == BMI2_OK) + { + /* Define the offset for enable/disable of step counter */ + idx = step_count_config.start_addr + BMI2_STEP_COUNT_FEAT_EN_OFFSET; + + /* Set the feature enable bit */ + feat_config[idx] = BMI2_SET_BITS(feat_config[idx], BMI2_STEP_COUNT_FEAT_EN, enable); + + /* Set the configuration back to the page */ + rslt = bmi2_set_regs(BMI2_FEATURES_REG_ADDR, feat_config, BMI2_FEAT_SIZE_IN_BYTES, dev); + } + } + else + { + rslt = BMI2_E_INVALID_SENSOR; + } + + return rslt; +} + +/*! +* @brief This internal API enables/disables the activity recognition feature. +*/ +static int8_t set_act_recog(uint8_t enable, struct bmi2_dev *dev) +{ + /* Variable to define error */ + int8_t rslt; + + /* Array to define the feature configuration */ + uint8_t feat_config[BMI2_FEAT_SIZE_IN_BYTES] = { 0 }; + + /* Variable to define the array offset */ + uint8_t idx = 0; + + /* Variable to set flag */ + uint8_t feat_found; + + /* Initialize feature configuration for activity recognition */ + struct bmi2_feature_config act_recog_cfg = { 0, 0, 0 }; + + /* Search for activity recognition and extract its configuration details */ + feat_found = bmi2_extract_input_feat_config(&act_recog_cfg, BMI2_ACTIVITY_RECOGNITION, dev); + if (feat_found) + { + /* Get the configuration from the page where activity + * recognition feature resides + */ + rslt = bmi2_get_feat_config(act_recog_cfg.page, feat_config, dev); + if (rslt == BMI2_OK) + { + /* Define the offset for enable/disable of activity recognition */ + idx = act_recog_cfg.start_addr; + + /* Set the feature enable bit */ + feat_config[idx] = BMI2_SET_BIT_POS0(feat_config[idx], BMI2_ACTIVITY_RECOG_EN, enable); + + /* Set the configuration back to the page */ + rslt = bmi2_set_regs(BMI2_FEATURES_REG_ADDR, feat_config, BMI2_FEAT_SIZE_IN_BYTES, dev); + } + } + else + { + rslt = BMI2_E_INVALID_SENSOR; + } + + return rslt; +} + +/*! + * @brief This internal API is used to enable/disable gyroscope user gain + * feature. + */ +static int8_t set_gyro_user_gain(uint8_t enable, struct bmi2_dev *dev) +{ + /* Variable to define error */ + int8_t rslt; + + /* Array to define the feature configuration */ + uint8_t feat_config[BMI2_FEAT_SIZE_IN_BYTES] = { 0 }; + + /* Variable to define the array offset */ + uint8_t idx = 0; + + /* Variable to set flag */ + uint8_t feat_found; + + /* Initialize feature configuration for gyroscope user gain */ + struct bmi2_feature_config gyr_user_gain_cfg = { 0, 0, 0 }; + + /* Search for user gain feature and extract its configuration details */ + feat_found = bmi2_extract_input_feat_config(&gyr_user_gain_cfg, BMI2_GYRO_GAIN_UPDATE, dev); + if (feat_found) + { + /* Get the configuration from the page where user gain feature resides */ + rslt = bmi2_get_feat_config(gyr_user_gain_cfg.page, feat_config, dev); + if (rslt == BMI2_OK) + { + /* Define the offset for enable/disable of user gain */ + idx = gyr_user_gain_cfg.start_addr + BMI2_GYR_USER_GAIN_FEAT_EN_OFFSET; + + /* Set the feature enable bit */ + feat_config[idx] = BMI2_SET_BITS(feat_config[idx], BMI2_GYR_USER_GAIN_FEAT_EN, enable); + + /* Set the configuration back to the page */ + rslt = bmi2_set_regs(BMI2_FEATURES_REG_ADDR, feat_config, BMI2_FEAT_SIZE_IN_BYTES, dev); + } + } + else + { + rslt = BMI2_E_INVALID_SENSOR; + } + + return rslt; +} + +/*! + * @brief This internal API sets step counter parameter configurations. + */ +static int8_t set_step_count_params_config(const uint16_t *step_count_params, struct bmi2_dev *dev) +{ + /* Variable to define error */ + int8_t rslt = BMI2_OK; + + /* Array to define the feature configuration */ + uint8_t feat_config[BMI2_FEAT_SIZE_IN_BYTES] = { 0 }; + + /* Variable to define index */ + uint8_t index = 0; + + /* Variable to set flag */ + uint8_t feat_found; + + /* Initialize feature configuration for step counter parameters */ + struct bmi2_feature_config step_params_config = { 0, 0, 0 }; + + /* Variable to index the page number */ + uint8_t page_idx; + + /* Variable to define the start page */ + uint8_t start_page; + + /* Variable to define start address of the parameters */ + uint8_t start_addr; + + /* Variable to define number of bytes */ + uint8_t n_bytes = (BMI2_STEP_CNT_N_PARAMS * 2); + + /* Variable to store number of pages */ + uint8_t n_pages = (n_bytes / 16); + + /* Variable to define the end page */ + uint8_t end_page; + + /* Variable to define the remaining bytes to be read */ + uint8_t remain_len; + + /* Variable to define the maximum words(16 bytes or 8 words) to be read in a page */ + uint8_t max_len = 8; + + /* Variable index bytes in a page */ + uint8_t page_byte_idx; + + /* Variable to index the parameters */ + uint8_t param_idx = 0; + + /* Copy the feature configuration address to a local pointer */ + uint16_t *data_p = (uint16_t *) (void *)feat_config; + + /* Search for step counter parameter feature and extract its configuration details */ + feat_found = bmi2_extract_input_feat_config(&step_params_config, BMI2_STEP_COUNTER_PARAMS, dev); + if (feat_found) + { + /* Get the start page for the step counter parameters */ + start_page = step_params_config.page; + + /* Get the end page for the step counter parameters */ + end_page = start_page + n_pages; + + /* Get the start address for the step counter parameters */ + start_addr = step_params_config.start_addr; + + /* Get the remaining length of bytes to be read */ + remain_len = (uint8_t)((n_bytes - (n_pages * 16)) + start_addr); + for (page_idx = start_page; page_idx <= end_page; page_idx++) + { + /* Get the configuration from the respective page */ + rslt = bmi2_get_feat_config(page_idx, feat_config, dev); + if (rslt == BMI2_OK) + { + /* Start from address 0x00 when switched to next page */ + if (page_idx > start_page) + { + start_addr = 0; + } + + /* Remaining number of words to be read in the page */ + if (page_idx == end_page) + { + max_len = (remain_len / 2); + } + + /* Get offset in words since all the features are set in words length */ + page_byte_idx = start_addr / 2; + for (; page_byte_idx < max_len;) + { + /* Set parameters 1 to 25 */ + *(data_p + page_byte_idx) = BMI2_SET_BIT_POS0(*(data_p + page_byte_idx), + BMI2_STEP_COUNT_PARAMS, + step_count_params[param_idx]); + + /* Increment offset by 1 word to set to the next parameter */ + page_byte_idx++; + + /* Increment to next parameter */ + param_idx++; + } + + /* Get total length in bytes to copy from local pointer to the array */ + page_byte_idx = (uint8_t)(page_byte_idx * 2) - step_params_config.start_addr; + + /* Copy the bytes to be set back to the array */ + for (index = 0; index < page_byte_idx; index++) + { + feat_config[step_params_config.start_addr + + index] = *((uint8_t *) data_p + step_params_config.start_addr + index); + } + + /* Set the configuration back to the page */ + rslt = bmi2_set_regs(BMI2_FEATURES_REG_ADDR, feat_config, BMI2_FEAT_SIZE_IN_BYTES, dev); + } + } + } + else + { + rslt = BMI2_E_INVALID_SENSOR; + } + + return rslt; +} + +/* @brief This internal API sets step counter configurations like water-mark + * level, reset-counter and output-configuration step detector and activity. + */ +static int8_t set_step_config(const struct bmi2_step_config *config, struct bmi2_dev *dev) +{ + /* Variable to define error */ + int8_t rslt; + + /* Array to define the feature configuration */ + uint8_t feat_config[BMI2_FEAT_SIZE_IN_BYTES] = { 0 }; + + /* Variable to define the array offset */ + uint8_t idx = 0; + + /* Variable to define index */ + uint8_t index = 0; + + /* Variable to set flag */ + uint8_t feat_found; + + /* Initialize feature configuration for step counter 4 */ + struct bmi2_feature_config step_count_config = { 0, 0, 0 }; + + /* Copy the feature configuration address to a local pointer */ + uint16_t *data_p = (uint16_t *) (void *)feat_config; + + /* Search for step counter feature and extract its configuration details */ + feat_found = bmi2_extract_input_feat_config(&step_count_config, BMI2_STEP_COUNTER, dev); + if (feat_found) + { + /* Get the configuration from the page where step counter resides */ + rslt = bmi2_get_feat_config(step_count_config.page, feat_config, dev); + if (rslt == BMI2_OK) + { + /* Define the offset in bytes */ + idx = step_count_config.start_addr; + + /* Get offset in words since all the features are set in words length */ + idx = idx / 2; + + /* Set water-mark level */ + *(data_p + idx) = BMI2_SET_BIT_POS0(*(data_p + idx), BMI2_STEP_COUNT_WM_LEVEL, config->watermark_level); + + /* Set reset-counter */ + *(data_p + idx) = BMI2_SET_BITS(*(data_p + idx), BMI2_STEP_COUNT_RST_CNT, config->reset_counter); + + /* Increment offset by 1 word to set output + * configuration of step detector and step activity + */ + idx++; + + /* Set step buffer size */ + *(data_p + idx) = BMI2_SET_BITS(*(data_p + idx), BMI2_STEP_BUFFER_SIZE, config->step_buffer_size); + + /* Increment offset by 1 more word to get the total length in words */ + idx++; + + /* Get total length in bytes to copy from local pointer to the array */ + idx = (uint8_t)(idx * 2) - step_count_config.start_addr; + + /* Copy the bytes to be set back to the array */ + for (index = 0; index < idx; index++) + { + feat_config[step_count_config.start_addr + + index] = *((uint8_t *) data_p + step_count_config.start_addr + index); + } + + /* Set the configuration back to the page */ + rslt = bmi2_set_regs(BMI2_FEATURES_REG_ADDR, feat_config, BMI2_FEAT_SIZE_IN_BYTES, dev); + } + } + else + { + rslt = BMI2_E_INVALID_SENSOR; + } + + return rslt; +} + +/*! + * @brief This internal API gets step counter parameter configurations. + */ +static int8_t get_step_count_params_config(uint16_t *step_count_params, struct bmi2_dev *dev) +{ + /* Variable to define error */ + int8_t rslt = BMI2_OK; + + /* Array to define the feature configuration */ + uint8_t feat_config[BMI2_FEAT_SIZE_IN_BYTES] = { 0 }; + + /* Variable to set flag */ + uint8_t feat_found; + + /* Variable to define LSB */ + uint16_t lsb = 0; + + /* Variable to define MSB */ + uint16_t msb = 0; + + /* Variable to define a word */ + uint16_t lsb_msb = 0; + + /* Initialize feature configuration for step counter 1 */ + struct bmi2_feature_config step_params_config = { 0, 0, 0 }; + + /* Variable to index the page number */ + uint8_t page_idx; + + /* Variable to define the start page */ + uint8_t start_page; + + /* Variable to define start address of the parameters */ + uint8_t start_addr; + + /* Variable to define number of bytes */ + uint8_t n_bytes = (BMI2_STEP_CNT_N_PARAMS * 2); + + /* Variable to store number of pages */ + uint8_t n_pages = (n_bytes / 16); + + /* Variable to define the end page */ + uint8_t end_page; + + /* Variable to define the remaining bytes to be read */ + uint8_t remain_len; + + /* Variable to define the maximum words to be read in a page */ + uint8_t max_len = BMI2_FEAT_SIZE_IN_BYTES; + + /* Variable index bytes in a page */ + uint8_t page_byte_idx; + + /* Variable to index the parameters */ + uint8_t param_idx = 0; + + /* Search for step counter parameter feature and extract its configuration details */ + feat_found = bmi2_extract_input_feat_config(&step_params_config, BMI2_STEP_COUNTER_PARAMS, dev); + if (feat_found) + { + /* Get the start page for the step counter parameters */ + start_page = step_params_config.page; + + /* Get the end page for the step counter parameters */ + end_page = start_page + n_pages; + + /* Get the start address for the step counter parameters */ + start_addr = step_params_config.start_addr; + + /* Get the remaining length of bytes to be read */ + remain_len = (uint8_t)((n_bytes - (n_pages * 16)) + start_addr); + for (page_idx = start_page; page_idx <= end_page; page_idx++) + { + /* Get the configuration from the respective page */ + rslt = bmi2_get_feat_config(page_idx, feat_config, dev); + if (rslt == BMI2_OK) + { + /* Start from address 0x00 when switched to next page */ + if (page_idx > start_page) + { + start_addr = 0; + } + + /* Remaining number of bytes to be read in the page */ + if (page_idx == end_page) + { + max_len = remain_len; + } + + /* Get the offset */ + page_byte_idx = start_addr; + while (page_byte_idx < max_len) + { + /* Get word to calculate the parameter*/ + lsb = (uint16_t) feat_config[page_byte_idx++]; + if (page_byte_idx < max_len) + { + msb = ((uint16_t) feat_config[page_byte_idx++] << 8); + } + + lsb_msb = lsb | msb; + + /* Get parameters 1 to 25 */ + step_count_params[param_idx] = lsb_msb & BMI2_STEP_COUNT_PARAMS_MASK; + + /* Increment to next parameter */ + param_idx++; + } + } + } + } + else + { + rslt = BMI2_E_INVALID_SENSOR; + } + + return rslt; +} + +/*! + * @brief This internal API gets step counter/detector/activity configurations. + */ +static int8_t get_step_config(struct bmi2_step_config *config, struct bmi2_dev *dev) +{ + /* Variable to define error */ + int8_t rslt; + + /* Array to define the feature configuration */ + uint8_t feat_config[BMI2_FEAT_SIZE_IN_BYTES] = { 0 }; + + /* Variable to define the array offset */ + uint8_t idx = 0; + + /* Variable to define LSB */ + uint16_t lsb = 0; + + /* Variable to define MSB */ + uint16_t msb = 0; + + /* Variable to define a word */ + uint16_t lsb_msb = 0; + + /* Variable to set flag */ + uint8_t feat_found; + + /* Initialize feature configuration for step counter */ + struct bmi2_feature_config step_count_config = { 0, 0, 0 }; + + /* Search for step counter 4 feature and extract its configuration details */ + feat_found = bmi2_extract_input_feat_config(&step_count_config, BMI2_STEP_COUNTER, dev); + if (feat_found) + { + /* Get the configuration from the page where step counter 4 parameter resides */ + rslt = bmi2_get_feat_config(step_count_config.page, feat_config, dev); + if (rslt == BMI2_OK) + { + /* Define the offset for feature enable for step counter/detector/activity */ + idx = step_count_config.start_addr; + + /* Get word to calculate water-mark level and reset counter */ + lsb = (uint16_t) feat_config[idx++]; + msb = ((uint16_t) feat_config[idx++] << 8); + lsb_msb = lsb | msb; + + /* Get water-mark level */ + config->watermark_level = lsb_msb & BMI2_STEP_COUNT_WM_LEVEL_MASK; + + /* Get reset counter */ + config->reset_counter = (lsb_msb & BMI2_STEP_COUNT_RST_CNT_MASK) >> BMI2_STEP_COUNT_RST_CNT_POS; + + /* Get word to calculate output configuration of step detector and activity */ + lsb = (uint16_t) feat_config[idx++]; + msb = ((uint16_t) feat_config[idx++] << 8); + lsb_msb = lsb | msb; + + config->step_buffer_size = (lsb_msb & BMI2_STEP_BUFFER_SIZE_MASK) >> BMI2_STEP_BUFFER_SIZE_POS; + } + } + else + { + rslt = BMI2_E_INVALID_SENSOR; + } + + return rslt; +} + +/*! + * @brief This internal API gets the output values of step counter. + */ +static int8_t get_step_counter_output(uint32_t *step_count, struct bmi2_dev *dev) +{ + /* Variable to define error */ + int8_t rslt; + + /* Array to define the feature configuration */ + uint8_t feat_config[BMI2_FEAT_SIZE_IN_BYTES] = { 0 }; + + /* Variables to define index */ + uint8_t idx = 0; + + /* Variable to set flag */ + uint8_t feat_found; + + /* Initialize feature output for step counter */ + struct bmi2_feature_config step_cnt_out_config = { 0, 0, 0 }; + + /* Search for step counter output feature and extract its configuration details */ + feat_found = extract_output_feat_config(&step_cnt_out_config, BMI2_STEP_COUNTER, dev); + if (feat_found) + { + /* Get the feature output configuration for step-counter */ + rslt = bmi2_get_feat_config(step_cnt_out_config.page, feat_config, dev); + if (rslt == BMI2_OK) + { + /* Define the offset in bytes for step counter output */ + idx = step_cnt_out_config.start_addr; + + /* Get the step counter output in 4 bytes */ + *step_count = (uint32_t) feat_config[idx++]; + *step_count |= ((uint32_t) feat_config[idx++] << 8); + *step_count |= ((uint32_t) feat_config[idx++] << 16); + *step_count |= ((uint32_t) feat_config[idx++] << 24); + } + } + else + { + rslt = BMI2_E_INVALID_SENSOR; + } + + return rslt; +} + +/*! + * @brief This internal API gets the error status related to NVM. + */ +static int8_t get_nvm_error_status(struct bmi2_nvm_err_status *nvm_err_stat, struct bmi2_dev *dev) +{ + /* Variable to define error */ + int8_t rslt; + + /* Array to define the feature configuration */ + uint8_t feat_config[BMI2_FEAT_SIZE_IN_BYTES] = { 0 }; + + /* Variables to define index */ + uint8_t idx = 0; + + /* Variable to set flag */ + uint8_t feat_found; + + /* Initialize feature output for NVM error status */ + struct bmi2_feature_config nvm_err_cfg = { 0, 0, 0 }; + + /* Search for NVM error status feature and extract its configuration details */ + feat_found = extract_output_feat_config(&nvm_err_cfg, BMI2_NVM_STATUS, dev); + if (feat_found) + { + /* Get the feature output configuration for NVM error status */ + rslt = bmi2_get_feat_config(nvm_err_cfg.page, feat_config, dev); + if (rslt == BMI2_OK) + { + /* Define the offset in bytes for NVM error status */ + idx = nvm_err_cfg.start_addr; + + /* Increment index to get the error status */ + idx++; + + /* Error when NVM load action fails */ + nvm_err_stat->load_error = BMI2_GET_BIT_POS0(feat_config[idx], BMI2_NVM_LOAD_ERR_STATUS); + + /* Error when NVM program action fails */ + nvm_err_stat->prog_error = BMI2_GET_BITS(feat_config[idx], BMI2_NVM_PROG_ERR_STATUS); + + /* Error when NVM erase action fails */ + nvm_err_stat->erase_error = BMI2_GET_BITS(feat_config[idx], BMI2_NVM_ERASE_ERR_STATUS); + + /* Error when NVM program limit is exceeded */ + nvm_err_stat->exceed_error = BMI2_GET_BITS(feat_config[idx], BMI2_NVM_END_EXCEED_STATUS); + + /* Error when NVM privilege mode is not acquired */ + nvm_err_stat->privil_error = BMI2_GET_BITS(feat_config[idx], BMI2_NVM_PRIV_ERR_STATUS); + } + } + else + { + rslt = BMI2_E_INVALID_SENSOR; + } + + return rslt; +} + +/*! + * @brief This internal API is used to get enable status of gyroscope user gain + * update. + */ +static int8_t get_user_gain_upd_status(uint8_t *status, struct bmi2_dev *dev) +{ + /* Variable to define error */ + int8_t rslt = BMI2_OK; + + /* Array to define the feature configuration */ + uint8_t feat_config[BMI2_FEAT_SIZE_IN_BYTES] = { 0 }; + + /* Variable to define the array offset */ + uint8_t idx = 0; + + /* Variable to set flag */ + uint8_t feat_found; + + /* Variable to check APS status */ + uint8_t aps_stat = 0; + + /* Initialize feature configuration for gyroscope user gain */ + struct bmi2_feature_config gyr_user_gain_cfg = { 0, 0, 0 }; + + /* Search for user gain feature and extract its configuration details */ + feat_found = bmi2_extract_input_feat_config(&gyr_user_gain_cfg, BMI2_GYRO_GAIN_UPDATE, dev); + if (feat_found) + { + /* Disable advance power save */ + aps_stat = dev->aps_status; + if (aps_stat == BMI2_ENABLE) + { + rslt = bmi2_set_adv_power_save(BMI2_DISABLE, dev); + } + + if (rslt == BMI2_OK) + { + /* Get the configuration from the page where user gain feature resides */ + rslt = bmi2_get_feat_config(gyr_user_gain_cfg.page, feat_config, dev); + if (rslt == BMI2_OK) + { + /* Define the offset for enable/disable of user gain */ + idx = gyr_user_gain_cfg.start_addr + BMI2_GYR_USER_GAIN_FEAT_EN_OFFSET; + + /* Set the feature enable status */ + *status = BMI2_GET_BITS(feat_config[idx], BMI2_GYR_USER_GAIN_FEAT_EN); + } + } + } + else + { + rslt = BMI2_E_INVALID_SENSOR; + } + + /* Enable Advance power save if disabled while configuring and not when already disabled */ + if ((rslt == BMI2_OK) && (aps_stat == BMI2_ENABLE)) + { + rslt = bmi2_set_adv_power_save(BMI2_ENABLE, dev); + } + + return rslt; +} + +/*! + * @brief This internal API is used to parse and store the activity recognition + * output from the FIFO data. + */ +static int8_t unpack_act_recog_output(struct bmi2_act_recog_output *act_recog, + uint16_t *data_index, + const struct bmi2_fifo_frame *fifo) +{ + /* Variable to define error */ + int8_t rslt = BMI2_OK; + + /* Variables to define 4 bytes of sensor time */ + uint32_t time_stamp_byte4 = 0; + uint32_t time_stamp_byte3 = 0; + uint32_t time_stamp_byte2 = 0; + uint32_t time_stamp_byte1 = 0; + + /* Validate data index */ + if ((*data_index + BMI2_FIFO_VIRT_ACT_DATA_LENGTH) >= fifo->length) + { + /* Update the data index to the last byte */ + (*data_index) = fifo->length; + + /* FIFO is empty */ + rslt = BMI2_W_FIFO_EMPTY; + } + else + { + /* Get time-stamp from the activity recognition frame */ + time_stamp_byte4 = ((uint32_t)(fifo->data[(*data_index) + 3]) << 24); + time_stamp_byte3 = ((uint32_t)(fifo->data[(*data_index) + 2]) << 16); + time_stamp_byte2 = fifo->data[(*data_index) + 1] << 8; + time_stamp_byte1 = fifo->data[(*data_index)]; + + /* Update time-stamp from the virtual frame */ + act_recog->time_stamp = (time_stamp_byte4 | time_stamp_byte3 | time_stamp_byte2 | time_stamp_byte1); + + /* Move the data index by 4 bytes */ + (*data_index) = (*data_index) + BMI2_FIFO_VIRT_ACT_TIME_LENGTH; + + /* Update the previous activity from the virtual frame */ + act_recog->prev_act = fifo->data[(*data_index)]; + + /* Move the data index by 1 byte */ + (*data_index) = (*data_index) + BMI2_FIFO_VIRT_ACT_TYPE_LENGTH; + + /* Update the current activity from the virtual frame */ + act_recog->curr_act = fifo->data[(*data_index)]; + + /* Move the data index by 1 byte */ + (*data_index) = (*data_index) + BMI2_FIFO_VIRT_ACT_STAT_LENGTH; + + /* More frames could be read */ + rslt = BMI2_W_PARTIAL_READ; + } + + return rslt; +} + +/*! + * @brief This internal API gets the error status related to virtual frames. + */ +static int8_t get_vfrm_error_status(struct bmi2_vfrm_err_status *vfrm_err_stat, struct bmi2_dev *dev) +{ + /* Variable to define error */ + int8_t rslt; + + /* Array to define the feature configuration */ + uint8_t feat_config[BMI2_FEAT_SIZE_IN_BYTES] = { 0 }; + + /* Variables to define index */ + uint8_t idx = 0; + + /* Variable to set flag */ + uint8_t feat_found; + + /* Initialize feature output for VFRM error status */ + struct bmi2_feature_config vfrm_err_cfg = { 0, 0, 0 }; + + /* Search for VFRM error status feature and extract its configuration details */ + feat_found = extract_output_feat_config(&vfrm_err_cfg, BMI2_VFRM_STATUS, dev); + if (feat_found) + { + /* Get the feature output configuration for VFRM error status */ + rslt = bmi2_get_feat_config(vfrm_err_cfg.page, feat_config, dev); + if (rslt == BMI2_OK) + { + /* Define the offset in bytes for VFRM error status */ + idx = vfrm_err_cfg.start_addr; + + /* Increment index to get the error status */ + idx++; + + /* Internal error while acquiring lock for FIFO */ + vfrm_err_stat->lock_error = BMI2_GET_BITS(feat_config[idx], BMI2_VFRM_LOCK_ERR_STATUS); + + /* Internal error while writing byte into FIFO */ + vfrm_err_stat->write_error = BMI2_GET_BITS(feat_config[idx], BMI2_VFRM_WRITE_ERR_STATUS); + + /* Internal error while writing into FIFO */ + vfrm_err_stat->fatal_error = BMI2_GET_BITS(feat_config[idx], BMI2_VFRM_FATAL_ERR_STATUS); + } + } + else + { + rslt = BMI2_E_INVALID_SENSOR; + } + + return rslt; +} + +/*! + * @brief This internal API skips S4S frame in the FIFO data while getting + * step activity output. + */ +static int8_t move_if_s4s_frame(const uint8_t *frame_header, uint16_t *data_index, const struct bmi2_fifo_frame *fifo) +{ + /* Variable to define error */ + int8_t rslt = BMI2_OK; + + /* Variable to extract virtual header byte */ + uint8_t virtual_header_mode; + + /* Variable to define pay-load in words */ + uint8_t payload_word = 0; + + /* Variable to define pay-load in bytes */ + uint8_t payload_bytes = 0; + + /* Extract virtual header mode from the frame header */ + virtual_header_mode = BMI2_GET_BITS(*frame_header, BMI2_FIFO_VIRT_FRM_MODE); + + /* If the extracted header byte is a virtual header */ + if (virtual_header_mode == BMI2_FIFO_VIRT_FRM_MODE) + { + /* If frame header is not activity recognition header */ + if (*frame_header != 0xC8) + { + /* Extract pay-load in words from the header byte */ + payload_word = BMI2_GET_BITS(*frame_header, BMI2_FIFO_VIRT_PAYLOAD) + 1; + + /* Convert to bytes */ + payload_bytes = (uint8_t)(payload_word * 2); + + /* Move the data index by those pay-load bytes */ + rslt = move_next_frame(data_index, payload_bytes, fifo); + } + } + + return rslt; +} + +/*! + * @brief This internal API enables/disables compensation of the gain defined + * in the GAIN register. + */ +static int8_t enable_gyro_gain(uint8_t enable, struct bmi2_dev *dev) +{ + /* Variable to define error */ + int8_t rslt; + + /* Variable to define register data */ + uint8_t reg_data = 0; + + rslt = bmi2_get_regs(BMI2_GYR_OFF_COMP_6_ADDR, ®_data, 1, dev); + if (rslt == BMI2_OK) + { + reg_data = BMI2_SET_BITS(reg_data, BMI2_GYR_GAIN_EN, enable); + rslt = bmi2_set_regs(BMI2_GYR_OFF_COMP_6_ADDR, ®_data, 1, dev); + } + + return rslt; +} + +/*! + * @brief This internal API is used to extract the output feature configuration + * details from the look-up table. + */ +static uint8_t extract_output_feat_config(struct bmi2_feature_config *feat_output, + uint8_t type, + const struct bmi2_dev *dev) +{ + /* Variable to define loop */ + uint8_t loop = 0; + + /* Variable to set flag */ + uint8_t feat_found = BMI2_FALSE; + + /* Search for the output feature from the output configuration array */ + while (loop < dev->out_sens) + { + if (dev->feat_output[loop].type == type) + { + *feat_output = dev->feat_output[loop]; + feat_found = BMI2_TRUE; + break; + } + + loop++; + } + + /* Return flag */ + return feat_found; +} + +/*! + * @brief This internal API is used to move the data index ahead of the + * current_frame_length parameter when unnecessary FIFO data appears while + * extracting the user specified data. + */ +static int8_t move_next_frame(uint16_t *data_index, uint8_t current_frame_length, const struct bmi2_fifo_frame *fifo) +{ + /* Variables to define error */ + int8_t rslt = BMI2_OK; + + /* Validate data index */ + if (((*data_index) + current_frame_length) > fifo->length) + { + /* Move the data index to the last byte */ + (*data_index) = fifo->length; + + /* FIFO is empty */ + rslt = BMI2_W_FIFO_EMPTY; + } + else + { + /* Move the data index to next frame */ + (*data_index) = (*data_index) + current_frame_length; + + /* More frames could be read */ + rslt = BMI2_W_PARTIAL_READ; + } + + return rslt; +} diff --git a/bmi270_hc.h b/bmi270_hc.h new file mode 100644 index 0000000..2a1b5bc --- /dev/null +++ b/bmi270_hc.h @@ -0,0 +1,483 @@ +/** +* 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 bmi270_hc.h +* @date 2020-11-04 +* @version v2.63.1 +* +*/ + +/** + * \ingroup bmi2xy + * \defgroup bmi270_hc BMI270_HC + * @brief Sensor driver for BMI270_HC sensor + */ + +#ifndef BMI270_HC_H_ +#define BMI270_HC_H_ + +/*! CPP guard */ +#ifdef __cplusplus +extern "C" { +#endif + +/***************************************************************************/ + +/*! Header files + ****************************************************************************/ +#include "bmi2.h" + +/***************************************************************************/ + +/*! Macro definitions + ****************************************************************************/ + +/*! @name BMI270_HC Chip identifier */ +#define BMI270_HC_CHIP_ID UINT8_C(0x24) + +/*! @name BMI270_HC feature input start addresses */ +#define BMI270_HC_CONFIG_ID_STRT_ADDR UINT8_C(0x06) +#define BMI270_HC_STEP_CNT_1_STRT_ADDR UINT8_C(0x00) +#define BMI270_HC_STEP_CNT_4_STRT_ADDR UINT8_C(0x02) +#define BMI270_HC_MAX_BURST_LEN_STRT_ADDR UINT8_C(0x08) +#define BMI270_HC_CRT_GYRO_SELF_TEST_STRT_ADDR UINT8_C(0x09) +#define BMI270_HC_ABORT_STRT_ADDR UINT8_C(0x09) +#define BMI270_HC_NVM_PROG_PREP_STRT_ADDR UINT8_C(0x0A) +#define BMI270_HC_ACT_RGN_SETT_STRT_ADDR UINT8_C(0x02) +#define BMI270_HC_ACT_RGN_STRT_ADDR UINT8_C(0x00) + +/*! @name BMI270_HC feature output start addresses */ +#define BMI270_HC_STEP_CNT_OUT_STRT_ADDR UINT8_C(0x00) +#define BMI270_HC_GYR_USER_GAIN_OUT_STRT_ADDR UINT8_C(0x04) +#define BMI270_HC_GYRO_CROSS_SENSE_STRT_ADDR UINT8_C(0x0C) +#define BMI270_HC_NVM_VFRM_OUT_STRT_ADDR UINT8_C(0x0E) + +/*! @name Defines maximum number of pages */ +#define BMI270_HC_MAX_PAGE_NUM UINT8_C(8) + +/*! @name Defines maximum number of feature input configurations */ +#define BMI270_HC_MAX_FEAT_IN UINT8_C(10) + +/*! @name Defines maximum number of feature outputs */ +#define BMI270_HC_MAX_FEAT_OUT UINT8_C(5) + +/*! @name Mask definitions for feature interrupt status bits */ +#define BMI270_HC_STEP_CNT_STATUS_MASK UINT8_C(0x01) + +/*! @name Mask definitions for feature interrupt mapping bits */ +#define BMI270_HC_INT_STEP_COUNTER_MASK UINT8_C(0x01) +#define BMI270_HC_INT_STEP_DETECTOR_MASK UINT8_C(0x01) + +/*! @name Defines maximum number of feature interrupts */ +#define BMI270_HC_MAX_INT_MAP UINT8_C(2) + +/***************************************************************************/ + +/*! BMI270_HC User Interface function prototypes + ****************************************************************************/ + +/** + * \ingroup bmi270_hc + * \defgroup bmi270_hcApiInit Initialization + * @brief Initialize the sensor and device structure + */ + +/*! + * \ingroup bmi270_hcApiInit + * \page bmi270_hc_api_bmi270_hc_init bmi270_hc_init + * \code + * int8_t bmi270_hc_init(struct bmi2_dev *dev); + * \endcode + * @details This API: + * 1) updates the device structure with address of the configuration file. + * 2) Initializes BMI270_HC sensor. + * 3) Writes the configuration file. + * 4) Updates the feature offset parameters in the device structure. + * 5) Updates the maximum number of pages, in the device structure. + * + * @param[in, out] dev : Structure instance of bmi2_dev. + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +int8_t bmi270_hc_init(struct bmi2_dev *dev); + +/** + * \ingroup bmi270_hc + * \defgroup bmi270_hcApiSensor Feature Set + * @brief Enable / Disable features of the sensor + */ + +/*! + * \ingroup bmi270_hcApiSensor + * \page bmi270_hc_api_bmi270_hc_sensor_enable bmi270_hc_sensor_enable + * \code + * int8_t bmi270_hc_sensor_enable(const uint8_t *sens_list, uint8_t n_sens, struct bmi2_dev *dev); + * \endcode + * @details This API selects the sensors/features to be enabled. + * + * @param[in] sens_list : Pointer to select the sensor/feature. + * @param[in] n_sens : Number of sensors selected. + * @param[in, out] dev : Structure instance of bmi2_dev. + * + * @note Sensors/features that can be enabled. + * + *@verbatim + * sens_list | Values + * ----------------------------|----------- + * BMI2_ACCEL | 0 + * BMI2_GYRO | 1 + * BMI2_AUX | 2 + * BMI2_STEP_DETECTOR | 6 + * BMI2_STEP_COUNTER | 7 + * BMI2_GYRO_GAIN_UPDATE | 9 + * BMI2_ACTIVITY_RECOGNITION | 34 + *@endverbatim + * + * @note : + * example uint8_t sens_list[2] = {BMI2_ACCEL, BMI2_GYRO}; + * uint8_t n_sens = 2; + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +int8_t bmi270_hc_sensor_enable(const uint8_t *sens_list, uint8_t n_sens, struct bmi2_dev *dev); + +/*! + * \ingroup bmi270_hcApiSensor + * \page bmi270_hc_api_bmi270_hc_sensor_disable bmi270_hc_sensor_disable + * \code + * int8_t bmi270_hc_sensor_disable(const uint8_t *sens_list, uint8_t n_sens, struct bmi2_dev *dev); + * \endcode + * @details This API selects the sensors/features to be disabled. + * + * @param[in] sens_list : Pointer to select the sensor/feature. + * @param[in] n_sens : Number of sensors selected. + * @param[in, out] dev : Structure instance of bmi2_dev. + * + * @note Sensors/features that can be disabled. + * + *@verbatim + * sens_list | Values + * ----------------------------|----------- + * BMI2_ACCEL | 0 + * BMI2_GYRO | 1 + * BMI2_AUX | 2 + * BMI2_STEP_DETECTOR | 6 + * BMI2_STEP_COUNTER | 7 + * BMI2_GYRO_GAIN_UPDATE | 9 + * BMI2_ACTIVITY_RECOGNITION | 34 + *@endverbatim + * + * @note : + * example uint8_t sens_list[2] = {BMI2_ACCEL, BMI2_GYRO}; + * uint8_t n_sens = 2; + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +int8_t bmi270_hc_sensor_disable(const uint8_t *sens_list, uint8_t n_sens, struct bmi2_dev *dev); + +/** + * \ingroup bmi270_hc + * \defgroup bmi270_hcApiSensorC Sensor Configuration + * @brief Enable / Disable feature configuration of the sensor + */ + +/*! + * \ingroup bmi270_hcApiSensorC + * \page bmi270_hc_api_bmi270_hc_set_sensor_config bmi270_hc_set_sensor_config + * \code + * int8_t bmi270_hc_set_sensor_config(struct bmi2_sens_config *sens_cfg, uint8_t n_sens, struct bmi2_dev *dev); + * \endcode + * @details This API sets the sensor/feature configuration. + * + * @param[in] sens_cfg : Structure instance of bmi2_sens_config. + * @param[in] n_sens : Number of sensors selected. + * @param[in, out] dev : Structure instance of bmi2_dev. + * + * @note Sensors/features that can be configured + * + *@verbatim + * sens_list | Values + * ----------------------------|----------- + * BMI2_STEP_DETECTOR | 6 + * BMI2_STEP_COUNTER | 7 + * BMI2_STEP_COUNTER_PARAMS | 28 + *@endverbatim + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +int8_t bmi270_hc_set_sensor_config(struct bmi2_sens_config *sens_cfg, uint8_t n_sens, struct bmi2_dev *dev); + +/*! + * \ingroup bmi270_hcApiSensorC + * \page bmi270_hc_api_bmi270_hc_get_sensor_config bmi270_hc_get_sensor_config + * \code + * int8_t bmi270_hc_get_sensor_config(struct bmi2_sens_config *sens_cfg, uint8_t n_sens, struct bmi2_dev *dev); + * \endcode + * @details This API gets the sensor/feature configuration. + * + * @param[in] sens_cfg : Structure instance of bmi2_sens_config. + * @param[in] n_sens : Number of sensors selected. + * @param[in, out] dev : Structure instance of bmi2_dev. + * + * @note Sensors/features whose configurations can be read. + * + *@verbatim + * sens_list | Values + * ----------------------------|----------- + * BMI2_STEP_DETECTOR | 6 + * BMI2_STEP_COUNTER | 7 + * BMI2_STEP_COUNTER_PARAMS | 28 + *@endverbatim + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +int8_t bmi270_hc_get_sensor_config(struct bmi2_sens_config *sens_cfg, uint8_t n_sens, struct bmi2_dev *dev); + +/** + * \ingroup bmi270_hc + * \defgroup bmi270_hcApiSensorD Sensor Data + * @brief Get sensor data + */ + +/*! + * \ingroup bmi270_hcApiSensorD + * \page bmi270_hc_api_bmi270_hc_get_sensor_data bmi270_hc_get_sensor_data + * \code + * int8_t bmi270_hc_get_sensor_data(struct bmi2_sensor_data *sensor_data, uint8_t n_sens, struct bmi2_dev *dev); + * \endcode + * @details This API gets the sensor/feature data for accelerometer, gyroscope, + * auxiliary sensor, step counter, high-g, gyroscope user-gain update, + * orientation, gyroscope cross sensitivity and error status for NVM and VFRM. + * + * @param[out] sensor_data : Structure instance of bmi2_sensor_data. + * @param[in] n_sens : Number of sensors selected. + * @param[in] dev : Structure instance of bmi2_dev. + * + * @note Sensors/features whose data can be read + * + *@verbatim + * sens_list | Values + * ---------------------|----------- + * BMI2_STEP_COUNTER | 7 + * BMI2_NVM_STATUS | 38 + * BMI2_VFRM_STATUS | 39 + *@endverbatim + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +int8_t bmi270_hc_get_sensor_data(struct bmi2_sensor_data *sensor_data, uint8_t n_sens, struct bmi2_dev *dev); + +/** + * \ingroup bmi270_hc + * \defgroup bmi270_hcApiARecoghc Activity recognition settings + * @brief Set / Get activity recognition settings of bmi270hc sensor + */ + +/*! + * \ingroup bmi270_hcApiARecoghc + * \page bmi270_hc_api_bmi270_hc_get_act_recg_sett bmi270_hc_get_act_recg_sett + * \code + * int8_t bmi270_hc_get_act_recg_sett(struct bmi2_hc_act_recg_sett *sett, struct bmi2_dev *dev); + * \endcode + * @details This api is used for retrieving the following activity recognition settings currently set. + * + * @param[in] sett : Structure instance of bmi2_hc_act_recg_sett. + * @param[in] dev : Structure instance of bmi2_dev. + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +int8_t bmi270_hc_get_act_recg_sett(struct bmi2_hc_act_recg_sett *sett, struct bmi2_dev *dev); + +/*! + * \ingroup bmi270_hcApiARecoghc + * \page bmi270_hc_api_bmi270_hc_set_act_recg_sett bmi270_hc_set_act_recg_sett + * \code + * int8_t bmi270_hc_set_act_recg_sett(const struct bmi2_hc_act_recg_sett *sett, struct bmi2_dev *dev); + * \endcode + * @details This api is used for setting the following activity recognition settings + * + * @param[in] sett : Structure instance of bmi2_hc_act_recg_sett. + * @param[in] dev : Structure instance of bmi2_dev. + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +int8_t bmi270_hc_set_act_recg_sett(const struct bmi2_hc_act_recg_sett *sett, struct bmi2_dev *dev); + +/** + * \ingroup bmi270_hc + * \defgroup bmi270_hcApiactOut Activity Output + * @brief Activity output operations of the sensor + */ + +/*! + * \ingroup bmi270_hcApiactOut + * \page bmi270_hc_api_bmi270_hc_get_act_recog_output bmi270_hc_get_act_recog_output + * \code + * int8_t bmi270_hc_get_act_recog_output(struct bmi2_act_recog_output *act_recog, + * uint16_t *act_frm_len, + * struct bmi2_fifo_frame *fifo, + * const struct bmi2_dev *dev); + * + * \endcode + * @details This internal API is used to parse the activity output from the + * FIFO in header mode. + * + * @param[out] act_recog : Pointer to buffer where the parsed activity data + * bytes are stored. + * @param[in] act_frm_len : Number of activity frames parsed. + * @param[in] fifo : Structure instance of bmi2_fifo_frame. + * @param[in] dev : Structure instance of bmi2_dev. + * + * @verbatim + * ---------------------------------------------------------------------------- + * bmi2_act_rec_output | + * Structure parameters | Description + *--------------------------|-------------------------------------------------- + * time_stamp | time-stamp (expressed in 50Hz ticks) + * -------------------------|--------------------------------------------------- + * type | Type of activity + * -------------------------|--------------------------------------------------- + * stat | Activity status + * -------------------------|--------------------------------------------------- + * @endverbatim + * + *@verbatim + * type | Activities + *----------|--------------------- + * 0 | UNKNOWN + * 1 | STILL + * 2 | WALK + * 3 | RUN + * 4 | BIKE + * 5 | VEHICLE + * 6 | TILTED + *@endverbatim + * + * + *@verbatim + * stat | Activity status + *----------|--------------------- + * 1 | START + * 2 | END + *@endverbatim + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +int8_t bmi270_hc_get_act_recog_output(struct bmi2_act_recog_output *act_recog, + uint16_t *act_frm_len, + struct bmi2_fifo_frame *fifo, + const struct bmi2_dev *dev); + +/** + * \ingroup bmi270_hc + * \defgroup bmi270_hcApiGyroUG Gyro User Gain + * @brief Set / Get Gyro User Gain of the sensor + */ + +/*! + * \ingroup bmi270_hcApiGyroUG + * \page bmi270_hc_api_bmi270_hc_update_gyro_user_gain bmi270_hc_update_gyro_user_gain + * \code + * int8_t bmi270_hc_update_gyro_user_gain(const struct bmi2_gyro_user_gain_config *user_gain, struct bmi2_dev *dev); + * \endcode + * @details This API updates the gyroscope user-gain. + * + * @param[in] user_gain : Structure that stores user-gain configurations. + * @param[in] dev : Structure instance of bmi2_dev. + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +int8_t bmi270_hc_update_gyro_user_gain(const struct bmi2_gyro_user_gain_config *user_gain, struct bmi2_dev *dev); + +/*! + * \ingroup bmi270_hcApiGyroUG + * \page bmi270_hc_api_bmi270_hc_read_gyro_user_gain bmi270_hc_read_gyro_user_gain + * \code + * int8_t bmi270_hc_read_gyro_user_gain(struct bmi2_gyro_user_gain_data *gyr_usr_gain, const struct bmi2_dev *dev); + * \endcode + * @details This API reads the compensated gyroscope user-gain values. + * + * @param[out] gyr_usr_gain : Structure that stores gain values. + * @param[in] dev : Structure instance of bmi2_dev. + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +int8_t bmi270_hc_read_gyro_user_gain(struct bmi2_gyro_user_gain_data *gyr_usr_gain, struct bmi2_dev *dev); + +/*! + * \ingroup bmi270_hcApiInt + * \page bmi270_hc_api_bmi270_hc_map_feat_int bmi270_hc_map_feat_int + * \code + * int8_t bmi270_hc_map_feat_int(const struct bmi2_sens_int_config *sens_int, uint8_t n_sens, struct bmi2_dev *dev) + * \endcode + * @details This API maps/unmaps feature interrupts to that of interrupt pins. + * + * @param[in] sens_int : Structure instance of bmi2_sens_int_config. + * @param[in] n_sens : Number of interrupts to be mapped. + * @param[in] dev : Structure instance of bmi2_dev. + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +int8_t bmi270_hc_map_feat_int(const struct bmi2_sens_int_config *sens_int, uint8_t n_sens, struct bmi2_dev *dev); + +/******************************************************************************/ +/*! @name C++ Guard Macros */ +/******************************************************************************/ +#ifdef __cplusplus +} +#endif /* End of CPP guard */ + +#endif /* BMI270_HC_H_ */ diff --git a/bmi270_maximum_fifo.c b/bmi270_maximum_fifo.c new file mode 100644 index 0000000..cfa89a5 --- /dev/null +++ b/bmi270_maximum_fifo.c @@ -0,0 +1,208 @@ +/** +* 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 bmi270_maximum_fifo.c +* @date 2020-11-04 +* @version v2.63.1 +* +*/ + +/***************************************************************************/ + +/*! Header files + ****************************************************************************/ +#include "bmi270_maximum_fifo.h" + +/***************************************************************************/ + +/*! Global Variable + ****************************************************************************/ + +/*! @name Global array that stores the configuration file of BMI270 */ +const uint8_t bmi270_maximum_fifo_config_file[] = { + 0xc8, 0x2e, 0x00, 0x2e, 0x80, 0x2e, 0x1a, 0x00, 0xc8, 0x2e, 0x00, 0x2e, 0xc8, 0x2e, 0x00, 0x2e, 0xc8, 0x2e, 0x00, + 0x2e, 0xc8, 0x2e, 0x00, 0x2e, 0xc8, 0x2e, 0x00, 0x2e, 0xc8, 0x2e, 0x00, 0x2e, 0x90, 0x32, 0x21, 0x2e, 0x59, 0xf5, + 0x10, 0x30, 0x21, 0x2e, 0x6a, 0xf5, 0x1a, 0x24, 0x22, 0x00, 0x80, 0x2e, 0x3b, 0x00, 0xc8, 0x2e, 0x44, 0x47, 0x22, + 0x00, 0x37, 0x00, 0xa4, 0x00, 0xff, 0x0f, 0xd1, 0x00, 0x07, 0xad, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, + 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, + 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x11, 0x24, 0xfc, 0xf5, 0x80, 0x30, 0x40, 0x42, 0x50, 0x50, 0x00, 0x30, 0x12, 0x24, 0xeb, + 0x00, 0x03, 0x30, 0x00, 0x2e, 0xc1, 0x86, 0x5a, 0x0e, 0xfb, 0x2f, 0x21, 0x2e, 0xfc, 0xf5, 0x13, 0x24, 0x63, 0xf5, + 0xe0, 0x3c, 0x48, 0x00, 0x22, 0x30, 0xf7, 0x80, 0xc2, 0x42, 0xe1, 0x7f, 0x3a, 0x25, 0xfc, 0x86, 0xf0, 0x7f, 0x41, + 0x33, 0x98, 0x2e, 0xc2, 0xc4, 0xd6, 0x6f, 0xf1, 0x30, 0xf1, 0x08, 0xc4, 0x6f, 0x11, 0x24, 0xff, 0x03, 0x12, 0x24, + 0x00, 0xfc, 0x61, 0x09, 0xa2, 0x08, 0x36, 0xbe, 0x2a, 0xb9, 0x13, 0x24, 0x38, 0x00, 0x64, 0xbb, 0xd1, 0xbe, 0x94, + 0x0a, 0x71, 0x08, 0xd5, 0x42, 0x21, 0xbd, 0x91, 0xbc, 0xd2, 0x42, 0xc1, 0x42, 0x00, 0xb2, 0xfe, 0x82, 0x05, 0x2f, + 0x50, 0x30, 0x21, 0x2e, 0x21, 0xf2, 0x00, 0x2e, 0x00, 0x2e, 0xd0, 0x2e, 0xf0, 0x6f, 0x02, 0x30, 0x02, 0x42, 0x20, + 0x26, 0xe0, 0x6f, 0x02, 0x31, 0x03, 0x40, 0x9a, 0x0a, 0x02, 0x42, 0xf0, 0x37, 0x05, 0x2e, 0x5e, 0xf7, 0x10, 0x08, + 0x12, 0x24, 0x1e, 0xf2, 0x80, 0x42, 0x83, 0x84, 0xf1, 0x7f, 0x0a, 0x25, 0x13, 0x30, 0x83, 0x42, 0x3b, 0x82, 0xf0, + 0x6f, 0x00, 0x2e, 0x00, 0x2e, 0xd0, 0x2e, 0x12, 0x40, 0x52, 0x42, 0x00, 0x2e, 0x12, 0x40, 0x52, 0x42, 0x3e, 0x84, + 0x00, 0x40, 0x40, 0x42, 0x7e, 0x82, 0xe1, 0x7f, 0xf2, 0x7f, 0x98, 0x2e, 0x6a, 0xd6, 0x21, 0x30, 0x23, 0x2e, 0x61, + 0xf5, 0xeb, 0x2c, 0xe1, 0x6f +}; + +/*! @name Global array that stores the feature input configuration of BMI270 */ +const struct bmi2_feature_config bmi270_maximum_fifo_feat_in[BMI270_MAXIMUM_FIFO_MAX_FEAT_IN] = { + +}; + +/*! @name Global array that stores the feature output configuration */ +const struct bmi2_feature_config bmi270_maximum_fifo_feat_out[BMI270_MAXIMUM_FIFO_MAX_FEAT_OUT] = { + +}; + +/******************************************************************************/ + +/*! Local Function Prototypes + ******************************************************************************/ + +/*! + * @brief This internal API is used to validate the device pointer for + * null conditions. + * + * @param[in] dev : Structure instance of bmi2_dev. + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +static int8_t null_ptr_check(const struct bmi2_dev *dev); + +/***************************************************************************/ + +/*! User Interface Definitions + ****************************************************************************/ + +/*! + * @brief This API: + * 1) updates the device structure with address of the configuration file. + * 2) Initializes BMI270 sensor. + * 3) Writes the configuration file. + * 4) Updates the feature offset parameters in the device structure. + * 5) Updates the maximum number of pages, in the device structure. + */ +int8_t bmi270_maximum_fifo_init(struct bmi2_dev *dev) +{ + /* Variable to define result */ + int8_t rslt; + + /* Null-pointer check */ + rslt = null_ptr_check(dev); + + if (rslt == BMI2_OK) + { + /* Assign chip id of BMI270 */ + dev->chip_id = BMI270_MAXIMUM_FIFO_CHIP_ID; + + dev->config_size = sizeof(bmi270_maximum_fifo_config_file); + + /* Enable the variant specific features if any */ + dev->variant_feature = BMI2_GYRO_CROSS_SENS_ENABLE | BMI2_MAXIMUM_FIFO_VARIANT; + + /* An extra dummy byte is read during SPI read */ + if (dev->intf == BMI2_SPI_INTF) + { + dev->dummy_byte = 1; + } + else + { + dev->dummy_byte = 0; + } + + /* If configuration file pointer is not assigned any address */ + if (!dev->config_file_ptr) + { + /* Give the address of the configuration file array to + * the device pointer + */ + dev->config_file_ptr = bmi270_maximum_fifo_config_file; + } + + /* Initialize BMI2 sensor */ + rslt = bmi2_sec_init(dev); + + if (rslt == BMI2_OK) + { + /* Assign the offsets of the feature input + * configuration to the device structure + */ + dev->feat_config = bmi270_maximum_fifo_feat_in; + + /* Assign the offsets of the feature output to + * the device structure + */ + dev->feat_output = bmi270_maximum_fifo_feat_out; + + /* Assign the maximum number of pages to the + * device structure + */ + dev->page_max = BMI270_MAXIMUM_FIFO_MAX_PAGE_NUM; + + /* Assign maximum number of input sensors/ + * features to device structure + */ + dev->input_sens = BMI270_MAXIMUM_FIFO_MAX_FEAT_IN; + + /* Assign maximum number of output sensors/ + * features to device structure + */ + dev->out_sens = BMI270_MAXIMUM_FIFO_MAX_FEAT_OUT; + + /* Get the gyroscope cross axis sensitivity */ + rslt = bmi2_get_gyro_cross_sense(dev); + } + } + + return rslt; +} + +/***************************************************************************/ + +/*! Local Function Definitions + ****************************************************************************/ + +/*! + * @brief This internal API is used to validate the device structure pointer for + * null conditions. + */ +static int8_t null_ptr_check(const struct bmi2_dev *dev) +{ + /* Variable to define result */ + int8_t rslt = BMI2_OK; + + if ((dev == NULL) || (dev->read == NULL) || (dev->write == NULL) || (dev->delay_us == NULL)) + { + /* Device structure pointer is not valid */ + rslt = BMI2_E_NULL_PTR; + } + + return rslt; +} diff --git a/bmi270_maximum_fifo.h b/bmi270_maximum_fifo.h new file mode 100644 index 0000000..e912a96 --- /dev/null +++ b/bmi270_maximum_fifo.h @@ -0,0 +1,117 @@ +/** +* 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 bmi270_maximum_fifo.h +* @date 2020-11-04 +* @version v2.63.1 +* +*/ + +/** + * \ingroup bmi2xy + * \defgroup bmi270_maximum_fifo BMI270_MAXIMUM_FIFO + * @brief Sensor driver for BMI270_MAXIMUM_FIFO sensor + */ + +#ifndef BMI270_MAXIMUM_FIFO_H_ +#define BMI270_MAXIMUM_FIFO_H_ + +/*! CPP guard */ +#ifdef __cplusplus +extern "C" { +#endif + +/***************************************************************************/ + +/*! Header files + ****************************************************************************/ +#include "bmi2.h" + +/***************************************************************************/ + +/*! Macro definitions + ****************************************************************************/ + +/*! @name BMI270 Chip identifier */ +#define BMI270_MAXIMUM_FIFO_CHIP_ID UINT8_C(0x24) + +/*! @name Defines maximum number of pages */ +#define BMI270_MAXIMUM_FIFO_MAX_PAGE_NUM UINT8_C(0) + +/*! @name Defines maximum number of feature input configurations */ +#define BMI270_MAXIMUM_FIFO_MAX_FEAT_IN UINT8_C(0) + +/*! @name Defines maximum number of feature outputs */ +#define BMI270_MAXIMUM_FIFO_MAX_FEAT_OUT UINT8_C(0) + +/*! @name Mask definitions for feature interrupt status bits */ + +/***************************************************************************/ + +/*! BMI270 User Interface function prototypes + ****************************************************************************/ + +/** + * \ingroup bmi270_maximum_fifo + * \defgroup bmi270_maximum_fifoApiInit Initialization + * @brief Initialize the sensor and device structure + */ + +/*! + * \ingroup bmi270_maximum_fifoApiInit + * \page bmi270_maximum_fifo_api_bmi270_maximum_fifo_init bmi270_maximum_fifo_init + * \code + * int8_t bmi270_maximum_fifo_init(struct bmi2_dev *dev); + * \endcode + * @details This API: + * 1) updates the device structure with address of the configuration file. + * 2) Initializes BMI270 sensor. + * 3) Writes the configuration file. + * 4) Updates the feature offset parameters in the device structure. + * 5) Updates the maximum number of pages, in the device structure. + * + * @param[in, out] dev : Structure instance of bmi2_dev. + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +int8_t bmi270_maximum_fifo_init(struct bmi2_dev *dev); + +/******************************************************************************/ +/*! @name C++ Guard Macros */ +/******************************************************************************/ +#ifdef __cplusplus +} +#endif /* End of CPP guard */ + +#endif /* BMI270_MAXIMUM_FIFO_H_ */ diff --git a/bmi270_wh.c b/bmi270_wh.c new file mode 100644 index 0000000..eda23cc --- /dev/null +++ b/bmi270_wh.c @@ -0,0 +1,3431 @@ +/** +* 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 bmi270_wh.c +* @date 2020-11-04 +* @version v2.63.1 +* +*/ + +/***************************************************************************/ + +/*! Header files + ****************************************************************************/ +#include "bmi270_wh.h" + +/***************************************************************************/ + +/*! Global Variable + ****************************************************************************/ + +/*! @name Global array that stores the configuration file of BMI270_WH */ +const uint8_t bmi270_wh_config_file[] = { + 0xc8, 0x2e, 0x00, 0x2e, 0x80, 0x2e, 0xf8, 0x02, 0xc8, 0x2e, 0x00, 0x2e, 0x80, 0x2e, 0xe1, 0x00, 0x80, 0x2e, 0xc0, + 0x02, 0x80, 0x2e, 0xe2, 0x00, 0xc8, 0x2e, 0x00, 0x2e, 0x80, 0x2e, 0x2c, 0x02, 0x80, 0x2e, 0xe4, 0x07, 0x59, 0xf5, + 0x10, 0x30, 0x21, 0x2e, 0x6a, 0xf5, 0x80, 0x2e, 0xdd, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x31, 0x01, 0x00, 0x22, + 0x00, 0x80, 0x00, 0xfa, 0x07, 0xff, 0x0f, 0xd1, 0x00, 0x65, 0x9d, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, + 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, + 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, + 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, + 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, + 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, + 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, + 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, + 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, + 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, + 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0xfd, 0x2d, 0x7b, 0xaf, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x03, 0x00, 0x18, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x12, + 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x24, 0x22, 0x00, 0x80, 0x2e, 0x8e, 0x01, 0xc8, 0x2e, 0xc8, 0x2e, 0xbb, 0x52, + 0x00, 0x2e, 0x60, 0x40, 0x41, 0x40, 0x0d, 0xbc, 0x98, 0xbc, 0xc0, 0x2e, 0x01, 0x0a, 0x0f, 0xb8, 0x43, 0x86, 0x25, + 0x40, 0x04, 0x40, 0xd8, 0xbe, 0x2c, 0x0b, 0x22, 0x11, 0x54, 0x42, 0x03, 0x80, 0x4b, 0x0e, 0xf6, 0x2f, 0xb8, 0x2e, + 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0xfd, 0x2d, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x31, 0x00, 0x00, + 0x88, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0xe0, 0xaa, 0x38, 0x05, 0xe0, 0x90, 0x30, 0x04, 0x00, 0xee, + 0x06, 0xf2, 0x05, 0x80, 0x80, 0x16, 0xf1, 0x02, 0x02, 0x2d, 0x01, 0xd4, 0x7b, 0x3b, 0x01, 0xdb, 0x7a, 0x04, 0x00, + 0x3f, 0x7b, 0xcd, 0x6c, 0xc3, 0x04, 0x85, 0x09, 0xc3, 0x04, 0xec, 0xe6, 0x0c, 0x46, 0x01, 0x00, 0x27, 0x00, 0x19, + 0x00, 0x96, 0x00, 0xa0, 0x00, 0x01, 0x00, 0x0c, 0x00, 0xf0, 0x3c, 0x00, 0x01, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, + 0x0e, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x92, 0x00, 0x98, 0xf1, 0xaf, 0x00, 0xae, 0x00, 0x1e, + 0xf2, 0x19, 0xf4, 0x66, 0xf5, 0x00, 0x04, 0xff, 0x00, 0x64, 0xf5, 0x96, 0x00, 0xaa, 0x00, 0x86, 0x00, 0x99, 0x00, + 0x88, 0x00, 0x8a, 0x00, 0xff, 0x3f, 0xff, 0xfb, 0x31, 0x01, 0x00, 0x38, 0x00, 0x30, 0xfd, 0xf5, 0xb2, 0x00, 0xff, + 0x03, 0x00, 0xfc, 0xf0, 0x3f, 0x0b, 0x01, 0x0e, 0x01, 0x10, 0x01, 0xb9, 0x00, 0x2d, 0xf5, 0xca, 0xf5, 0xb0, 0x00, + 0x20, 0xf2, 0xb2, 0x00, 0xff, 0x1f, 0x00, 0x40, 0x80, 0x2e, 0xc0, 0x08, 0x1d, 0x6c, 0xad, 0x00, 0x59, 0x01, 0x31, + 0xd1, 0xff, 0x7f, 0x00, 0x08, 0xee, 0x7a, 0xe4, 0x0c, 0x12, 0x02, 0xb3, 0x00, 0xb4, 0x04, 0x62, 0x03, 0xc0, 0x02, + 0x1f, 0xf8, 0xe1, 0x07, 0xd3, 0x07, 0xd7, 0x00, 0xd3, 0x00, 0xb9, 0x00, 0xc3, 0x00, 0xc5, 0x00, 0xbd, 0x00, 0xbc, + 0x00, 0xbf, 0x00, 0xdd, 0x00, 0x95, 0x00, 0xc2, 0x00, 0xd6, 0x00, 0xf0, 0x00, 0x00, 0xff, 0x00, 0x80, 0x30, 0x50, + 0x98, 0x2e, 0xc3, 0xb0, 0x02, 0x30, 0x00, 0x30, 0x00, 0x2e, 0x00, 0x2e, 0xd0, 0x2e, 0x01, 0x30, 0x00, 0x2e, 0x41, + 0x82, 0x48, 0xa2, 0xfb, 0x2f, 0x03, 0x2e, 0x95, 0x00, 0x40, 0xb2, 0x1a, 0x2f, 0x05, 0x2e, 0x0a, 0x01, 0x91, 0x52, + 0x98, 0x2e, 0xc7, 0xc1, 0x05, 0x2e, 0x18, 0x00, 0x80, 0xb2, 0x02, 0x30, 0x10, 0x2f, 0xf0, 0x7f, 0x00, 0x2e, 0x91, + 0x50, 0x98, 0x2e, 0x4d, 0xc3, 0x91, 0x50, 0x98, 0x2e, 0x5a, 0xc7, 0x98, 0x2e, 0xbc, 0x03, 0x98, 0x2e, 0x00, 0xb0, + 0x10, 0x30, 0x21, 0x2e, 0x19, 0x00, 0xf0, 0x6f, 0x02, 0x30, 0x03, 0x2e, 0x85, 0x00, 0x40, 0xb2, 0x40, 0x2f, 0x03, + 0x2e, 0x85, 0x00, 0x03, 0x31, 0x4b, 0x08, 0x40, 0xb2, 0x07, 0x2f, 0xf0, 0x7f, 0x98, 0x2e, 0x47, 0xcb, 0x10, 0x30, + 0x21, 0x2e, 0x19, 0x00, 0xf0, 0x6f, 0x02, 0x30, 0x03, 0x2e, 0x85, 0x00, 0x43, 0x30, 0x4b, 0x08, 0x40, 0xb2, 0x2a, + 0x2f, 0x03, 0x2e, 0x90, 0x00, 0xf0, 0x7f, 0x40, 0xb2, 0x0e, 0x2f, 0x41, 0x90, 0x20, 0x2f, 0x05, 0x2e, 0x3f, 0x01, + 0x07, 0x2e, 0x91, 0x00, 0xa1, 0x32, 0x95, 0x58, 0x98, 0x2e, 0x97, 0xb3, 0x02, 0x30, 0x25, 0x2e, 0x90, 0x00, 0x15, + 0x2c, 0xf0, 0x6f, 0x93, 0x58, 0xa3, 0x32, 0x10, 0x41, 0x11, 0x41, 0x18, 0xb9, 0x04, 0x41, 0x98, 0xbc, 0x41, 0x0a, + 0x94, 0x0a, 0x98, 0x2e, 0xf1, 0x03, 0x12, 0x30, 0x21, 0x2e, 0x91, 0x00, 0x21, 0x2e, 0xaf, 0x00, 0x25, 0x2e, 0x90, + 0x00, 0xf0, 0x6f, 0x02, 0x30, 0x11, 0x30, 0x23, 0x2e, 0x19, 0x00, 0x25, 0x2e, 0x85, 0x00, 0x03, 0x2e, 0x19, 0x00, + 0x40, 0xb2, 0x22, 0x2f, 0xf0, 0x7f, 0x98, 0x2e, 0xf5, 0xcb, 0x97, 0x54, 0xbc, 0x84, 0x21, 0x2e, 0xae, 0x00, 0x81, + 0x40, 0x82, 0x86, 0x99, 0x54, 0x18, 0xb8, 0xc3, 0x40, 0x91, 0x42, 0x90, 0x42, 0x33, 0xbc, 0x90, 0x42, 0xe2, 0x7f, + 0xf0, 0x31, 0x82, 0x40, 0x10, 0x08, 0xf2, 0x6f, 0x25, 0xbd, 0x02, 0x0a, 0xd0, 0x7f, 0x98, 0x2e, 0xa8, 0xcf, 0x06, + 0xbc, 0xd2, 0x6f, 0xe1, 0x6f, 0x10, 0x0a, 0x40, 0x42, 0x98, 0x2e, 0x2c, 0x03, 0xf0, 0x6f, 0x02, 0x30, 0x25, 0x2e, + 0x19, 0x00, 0x25, 0x2e, 0x95, 0x00, 0x80, 0x2e, 0x93, 0x01, 0x90, 0x50, 0xf7, 0x7f, 0xe6, 0x7f, 0xd5, 0x7f, 0xc4, + 0x7f, 0xb3, 0x7f, 0xa1, 0x7f, 0x90, 0x7f, 0x82, 0x7f, 0x7b, 0x7f, 0x98, 0x2e, 0xe3, 0x00, 0x00, 0xb2, 0x65, 0x2f, + 0x05, 0x2e, 0x31, 0x01, 0x01, 0x2e, 0x11, 0x01, 0x03, 0x2e, 0x0f, 0x01, 0x8f, 0xb9, 0x23, 0xbe, 0x9f, 0xb8, 0xcb, + 0x0a, 0x24, 0xbc, 0x4f, 0xba, 0x03, 0x2e, 0x12, 0x01, 0x0f, 0xb8, 0x22, 0xbd, 0xdc, 0x0a, 0x2f, 0xb9, 0x9b, 0xbc, + 0x18, 0x0a, 0x9f, 0xb8, 0x82, 0x0a, 0x91, 0x0a, 0x25, 0x2e, 0x18, 0x00, 0x05, 0x2e, 0xc1, 0xf5, 0x2e, 0xbd, 0x2e, + 0xb9, 0x01, 0x2e, 0x18, 0x00, 0x31, 0x30, 0x8a, 0x04, 0x00, 0x90, 0x03, 0x2f, 0x01, 0x2e, 0x83, 0x00, 0x00, 0xb2, + 0x19, 0x2f, 0x9b, 0x50, 0x91, 0x52, 0x98, 0x2e, 0xec, 0x00, 0x05, 0x2e, 0x82, 0x00, 0x25, 0x2e, 0x95, 0x00, 0x05, + 0x2e, 0x82, 0x00, 0x80, 0x90, 0x02, 0x2f, 0x12, 0x30, 0x25, 0x2e, 0x82, 0x00, 0x01, 0x2e, 0x83, 0x00, 0x00, 0xb2, + 0x10, 0x30, 0x05, 0x2e, 0x18, 0x00, 0x01, 0x2f, 0x21, 0x2e, 0x18, 0x00, 0x25, 0x2e, 0x83, 0x00, 0x05, 0x2e, 0x18, + 0x00, 0x80, 0xb2, 0x20, 0x2f, 0x01, 0x2e, 0xc0, 0xf5, 0xf2, 0x30, 0x02, 0x08, 0x07, 0xaa, 0x73, 0x30, 0x03, 0x2e, + 0x84, 0x00, 0x18, 0x22, 0x41, 0x1a, 0x05, 0x2f, 0x03, 0x2e, 0x66, 0xf5, 0x9f, 0xbc, 0x9f, 0xb8, 0x40, 0x90, 0x0c, + 0x2f, 0x9d, 0x52, 0x03, 0x30, 0x53, 0x42, 0x2b, 0x30, 0x90, 0x04, 0x5b, 0x42, 0x21, 0x2e, 0x84, 0x00, 0x24, 0xbd, + 0x7e, 0x80, 0x81, 0x84, 0x43, 0x42, 0x02, 0x42, 0x02, 0x32, 0x25, 0x2e, 0x62, 0xf5, 0x9f, 0x52, 0x05, 0x2e, 0x0a, + 0x01, 0x91, 0x08, 0x00, 0x31, 0x21, 0x2e, 0x60, 0xf5, 0x80, 0xb2, 0x0b, 0x2f, 0xf2, 0x3e, 0x01, 0x2e, 0xca, 0xf5, + 0x82, 0x08, 0x25, 0x2e, 0xca, 0xf5, 0x05, 0x2e, 0x59, 0xf5, 0xe0, 0x3f, 0x90, 0x08, 0x25, 0x2e, 0x59, 0xf5, 0xa1, + 0x6f, 0xb3, 0x6f, 0xc4, 0x6f, 0xd5, 0x6f, 0xe6, 0x6f, 0xf7, 0x6f, 0x7b, 0x6f, 0x82, 0x6f, 0x90, 0x6f, 0x70, 0x5f, + 0xc8, 0x2e, 0xa0, 0x50, 0x80, 0x7f, 0xe7, 0x7f, 0xd5, 0x7f, 0xc4, 0x7f, 0xb3, 0x7f, 0xa2, 0x7f, 0x91, 0x7f, 0xf6, + 0x7f, 0x7b, 0x7f, 0x00, 0x2e, 0x01, 0x2e, 0x60, 0xf5, 0x60, 0x7f, 0x98, 0x2e, 0xe3, 0x00, 0x62, 0x6f, 0x01, 0x32, + 0x91, 0x08, 0x80, 0xb2, 0x0d, 0x2f, 0x00, 0xb2, 0x03, 0x2f, 0x05, 0x2e, 0x18, 0x00, 0x80, 0x90, 0x05, 0x2f, 0xa3, + 0x56, 0x02, 0x30, 0xc1, 0x42, 0xc2, 0x86, 0x00, 0x2e, 0xc2, 0x42, 0x23, 0x2e, 0x60, 0xf5, 0x00, 0x90, 0x00, 0x30, + 0x06, 0x2f, 0x21, 0x2e, 0x82, 0x00, 0xa1, 0x50, 0x21, 0x2e, 0x5a, 0xf2, 0x98, 0x2e, 0x3d, 0x03, 0xf6, 0x6f, 0x80, + 0x6f, 0x91, 0x6f, 0xa2, 0x6f, 0xb3, 0x6f, 0xc4, 0x6f, 0xd5, 0x6f, 0xe7, 0x6f, 0x7b, 0x6f, 0x60, 0x5f, 0xc8, 0x2e, + 0xc0, 0x50, 0xe7, 0x7f, 0xf6, 0x7f, 0x26, 0x30, 0x0f, 0x2e, 0x61, 0xf5, 0x2f, 0x2e, 0x85, 0x00, 0x0f, 0x2e, 0x85, + 0x00, 0xbe, 0x09, 0xd5, 0x7f, 0xc4, 0x7f, 0xb3, 0x7f, 0xa2, 0x7f, 0x90, 0x7f, 0x7b, 0x7f, 0x80, 0xb3, 0x81, 0x7f, + 0x11, 0x2f, 0xa5, 0x50, 0x1a, 0x25, 0x12, 0x40, 0x42, 0x7f, 0x74, 0x82, 0x12, 0x40, 0x52, 0x7f, 0x00, 0x2e, 0x00, + 0x40, 0x60, 0x7f, 0x98, 0x2e, 0x6a, 0xd6, 0x03, 0x2e, 0x61, 0xf7, 0x00, 0x31, 0x48, 0x0a, 0x23, 0x2e, 0x61, 0xf7, + 0xe1, 0x31, 0x23, 0x2e, 0x61, 0xf5, 0xf6, 0x6f, 0xe7, 0x6f, 0x81, 0x6f, 0x90, 0x6f, 0xa2, 0x6f, 0xb3, 0x6f, 0xc4, + 0x6f, 0xd5, 0x6f, 0x7b, 0x6f, 0x40, 0x5f, 0xc8, 0x2e, 0xa7, 0x50, 0x10, 0x50, 0xbd, 0x52, 0x05, 0x2e, 0x8d, 0x00, + 0xfb, 0x7f, 0x00, 0x2e, 0x13, 0x40, 0x93, 0x42, 0x41, 0x0e, 0xfb, 0x2f, 0x98, 0x2e, 0x91, 0x03, 0xfb, 0x6f, 0xf0, + 0x5f, 0x80, 0x2e, 0x87, 0xcf, 0x10, 0x50, 0xfb, 0x7f, 0x98, 0x2e, 0x56, 0xc7, 0x98, 0x2e, 0x49, 0xc3, 0x11, 0x30, + 0x30, 0x30, 0xfb, 0x6f, 0xf0, 0x5f, 0x23, 0x2e, 0x8f, 0x00, 0x21, 0x2e, 0x86, 0x00, 0x23, 0x2e, 0x19, 0x00, 0x21, + 0x2e, 0xac, 0x00, 0xb8, 0x2e, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9a, 0x01, + 0x34, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x03, 0x2e, 0x8d, 0x00, 0x16, 0xb8, 0x02, 0x34, 0x4a, 0x0c, 0x21, 0x2e, 0x2d, 0xf5, 0xc0, 0x2e, 0x23, + 0x2e, 0x8d, 0x00, 0x40, 0x50, 0xf1, 0x7f, 0x0a, 0x25, 0x3c, 0x86, 0xeb, 0x7f, 0x41, 0x33, 0x22, 0x30, 0x98, 0x2e, + 0xc2, 0xc4, 0xd3, 0x6f, 0xf4, 0x30, 0xdc, 0x09, 0xc1, 0x58, 0xc2, 0x6f, 0x94, 0x09, 0xc3, 0x58, 0x6a, 0xbb, 0xdc, + 0x08, 0xb4, 0xb9, 0xb1, 0xbd, 0xbf, 0x5a, 0x95, 0x08, 0x21, 0xbd, 0xf6, 0xbf, 0x77, 0x0b, 0x51, 0xbe, 0xf1, 0x6f, + 0xeb, 0x6f, 0x52, 0x42, 0x54, 0x42, 0xc0, 0x2e, 0x43, 0x42, 0xc0, 0x5f, 0x03, 0x2e, 0x12, 0x01, 0x00, 0x31, 0x08, + 0x08, 0xf2, 0x30, 0x20, 0x50, 0x4a, 0x08, 0xe1, 0x7f, 0x00, 0xb2, 0xfb, 0x7f, 0x01, 0x30, 0x15, 0x2f, 0x01, 0x2e, + 0x8f, 0x00, 0x01, 0x90, 0x03, 0x2f, 0x23, 0x2e, 0x8f, 0x00, 0x98, 0x2e, 0xe7, 0x03, 0x98, 0x2e, 0xa8, 0xcf, 0x11, + 0x30, 0x41, 0x08, 0x23, 0x2e, 0xd5, 0x00, 0x98, 0x2e, 0x41, 0xb1, 0x10, 0x25, 0xfb, 0x6f, 0xe0, 0x6f, 0xe0, 0x5f, + 0x80, 0x2e, 0x95, 0xcf, 0xe0, 0x6f, 0x98, 0x2e, 0x95, 0xcf, 0x11, 0x30, 0x23, 0x2e, 0x8f, 0x00, 0xfb, 0x6f, 0xe0, + 0x5f, 0xb8, 0x2e, 0xd5, 0x50, 0x01, 0x30, 0x0f, 0x55, 0x11, 0x42, 0x42, 0x0e, 0xfc, 0x2f, 0x10, 0x30, 0xc0, 0x2e, + 0x21, 0x2e, 0xbc, 0x00, 0x40, 0x50, 0x0a, 0x25, 0x3c, 0x80, 0xfb, 0x7f, 0x01, 0x42, 0xd2, 0x7f, 0xe3, 0x7f, 0x32, + 0x30, 0x10, 0x25, 0x98, 0x2e, 0x7a, 0xc1, 0xfb, 0x6f, 0xc0, 0x5f, 0xb8, 0x2e, 0x44, 0x47, 0xb5, 0x50, 0xf0, 0x50, + 0x12, 0x40, 0x06, 0x40, 0x1a, 0x25, 0x6c, 0xbe, 0x76, 0x8a, 0x74, 0x80, 0xfb, 0x7f, 0x68, 0xbf, 0xb7, 0x56, 0x0b, + 0x30, 0xd3, 0x08, 0x4c, 0xba, 0x6c, 0xbb, 0x5b, 0x7f, 0x4b, 0x43, 0x0b, 0x42, 0xc0, 0xb2, 0xc6, 0x7f, 0xb4, 0x7f, + 0xd0, 0x7f, 0xe5, 0x7f, 0xa3, 0x7f, 0x90, 0x2e, 0xaf, 0xb0, 0x01, 0x2e, 0x8c, 0x00, 0x00, 0xb2, 0x0b, 0x2f, 0xab, + 0x52, 0x01, 0x2e, 0x87, 0x00, 0x92, 0x7f, 0x98, 0x2e, 0xbb, 0xcc, 0x01, 0x30, 0x23, 0x2e, 0x8c, 0x00, 0x92, 0x6f, + 0xa3, 0x6f, 0x1a, 0x25, 0x26, 0xbc, 0x86, 0xba, 0x25, 0xbc, 0x0f, 0xb8, 0x54, 0xb1, 0x00, 0xb2, 0x96, 0x7f, 0x0c, + 0x2f, 0xad, 0x50, 0xaf, 0x54, 0x0b, 0x30, 0x0b, 0x2e, 0x31, 0x01, 0xb3, 0x58, 0x1b, 0x42, 0x9b, 0x42, 0x6c, 0x09, + 0x0b, 0x42, 0x2b, 0x2e, 0x31, 0x01, 0x8b, 0x42, 0x71, 0x84, 0xb9, 0x50, 0x58, 0x09, 0xb1, 0x52, 0x91, 0x50, 0x82, + 0x7f, 0x75, 0x7f, 0x98, 0x2e, 0xc2, 0xc0, 0x01, 0x2e, 0x87, 0x00, 0xe5, 0x6f, 0xd4, 0x6f, 0x73, 0x6f, 0x82, 0x6f, + 0xab, 0x52, 0xa9, 0x5c, 0x98, 0x2e, 0x06, 0xcd, 0x65, 0x6f, 0xa0, 0x6f, 0xad, 0x52, 0x40, 0xb3, 0x04, 0xbd, 0x53, + 0x40, 0xaf, 0xba, 0x44, 0x40, 0xe1, 0x7f, 0x02, 0x30, 0x06, 0x2f, 0x40, 0xb3, 0x02, 0x30, 0x03, 0x2f, 0xaf, 0x5c, + 0x12, 0x30, 0x93, 0x43, 0x84, 0x43, 0x03, 0xbf, 0x6f, 0xbb, 0x80, 0xb3, 0x20, 0x2f, 0x46, 0x6f, 0xde, 0x00, 0x56, + 0x6f, 0x26, 0x03, 0x44, 0x42, 0x40, 0x91, 0x27, 0x2e, 0x88, 0x00, 0xaf, 0x52, 0x14, 0x2f, 0xaf, 0x5c, 0x00, 0x2e, + 0x95, 0x41, 0x86, 0x41, 0x5d, 0x05, 0xa6, 0x07, 0x80, 0xab, 0x04, 0x2f, 0x80, 0x91, 0x0a, 0x2f, 0x96, 0x6f, 0x75, + 0x0f, 0x07, 0x2f, 0x95, 0x6f, 0x40, 0xb3, 0x04, 0x2f, 0x53, 0x42, 0x44, 0x42, 0x12, 0x30, 0x04, 0x2c, 0x11, 0x30, + 0x02, 0x2c, 0x11, 0x30, 0x11, 0x30, 0x02, 0xbc, 0x0f, 0xb8, 0xd2, 0x7f, 0x00, 0x90, 0x06, 0x2f, 0x31, 0x30, 0x23, + 0x2e, 0xac, 0x00, 0x23, 0x2e, 0x86, 0x00, 0x0b, 0x2c, 0x01, 0x30, 0x01, 0x2e, 0x86, 0x00, 0x05, 0x2e, 0xac, 0x00, + 0x10, 0x1a, 0x02, 0x2f, 0x21, 0x2e, 0xac, 0x00, 0x01, 0x2d, 0x01, 0x30, 0xc0, 0x6f, 0x98, 0x2e, 0x95, 0xcf, 0xd1, + 0x6f, 0xb0, 0x6f, 0x98, 0x2e, 0x95, 0xcf, 0xe2, 0x6f, 0xa7, 0x52, 0x01, 0x2e, 0x88, 0x00, 0x82, 0x40, 0x50, 0x42, + 0x11, 0x2c, 0x42, 0x42, 0x10, 0x30, 0x31, 0x30, 0x21, 0x2e, 0x8c, 0x00, 0x23, 0x2e, 0xac, 0x00, 0x23, 0x2e, 0x86, + 0x00, 0xc0, 0x6f, 0x01, 0x30, 0x98, 0x2e, 0x95, 0xcf, 0xb0, 0x6f, 0x01, 0x30, 0x98, 0x2e, 0x95, 0xcf, 0x00, 0x2e, + 0xfb, 0x6f, 0x10, 0x5f, 0xb8, 0x2e, 0x50, 0x50, 0xcd, 0x50, 0x51, 0x30, 0x11, 0x42, 0xfb, 0x7f, 0x7b, 0x30, 0x0b, + 0x42, 0x11, 0x30, 0x02, 0x80, 0x23, 0x33, 0x01, 0x42, 0x03, 0x00, 0x07, 0x2e, 0x80, 0x03, 0x05, 0x2e, 0x8d, 0x00, + 0xa5, 0x52, 0xe2, 0x7f, 0xd3, 0x7f, 0xc0, 0x7f, 0x98, 0x2e, 0x9b, 0x03, 0xd1, 0x6f, 0x08, 0x0a, 0x1a, 0x25, 0x7b, + 0x86, 0xd0, 0x7f, 0x01, 0x33, 0x12, 0x30, 0x98, 0x2e, 0xc2, 0xc4, 0xd1, 0x6f, 0x08, 0x0a, 0x00, 0xb2, 0x0d, 0x2f, + 0xe3, 0x6f, 0x01, 0x2e, 0x80, 0x03, 0x51, 0x30, 0xc7, 0x86, 0x23, 0x2e, 0x21, 0xf2, 0x08, 0xbc, 0xc0, 0x42, 0x98, + 0x2e, 0x91, 0x03, 0x00, 0x2e, 0x00, 0x2e, 0xd0, 0x2e, 0xb0, 0x6f, 0x0b, 0xb8, 0x03, 0x2e, 0x1b, 0x00, 0x08, 0x1a, + 0xb0, 0x7f, 0x70, 0x30, 0x04, 0x2f, 0x21, 0x2e, 0x21, 0xf2, 0x00, 0x2e, 0x00, 0x2e, 0xd0, 0x2e, 0x98, 0x2e, 0x6d, + 0xc0, 0x98, 0x2e, 0x5d, 0xc0, 0xc5, 0x50, 0x98, 0x2e, 0x44, 0xcb, 0xc7, 0x50, 0x98, 0x2e, 0x46, 0xc3, 0xc9, 0x50, + 0x98, 0x2e, 0x53, 0xc7, 0x20, 0x26, 0xc0, 0x6f, 0x02, 0x31, 0x12, 0x42, 0x6b, 0x31, 0x0b, 0x42, 0x37, 0x80, 0x0b, + 0x30, 0x0b, 0x42, 0xf3, 0x37, 0xcf, 0x52, 0xd3, 0x50, 0x44, 0x40, 0xa2, 0x0a, 0x42, 0x42, 0x8b, 0x31, 0x09, 0x2e, + 0x5e, 0xf7, 0xd1, 0x54, 0xe3, 0x08, 0x83, 0x42, 0x1b, 0x42, 0x23, 0x33, 0x4b, 0x00, 0xbc, 0x84, 0x0b, 0x40, 0x33, + 0x30, 0x83, 0x42, 0x0b, 0x42, 0xe0, 0x7f, 0xd1, 0x7f, 0x98, 0x2e, 0x2c, 0x03, 0xd1, 0x6f, 0x80, 0x30, 0x40, 0x42, + 0x03, 0x30, 0xe0, 0x6f, 0xcb, 0x54, 0x04, 0x30, 0x00, 0x2e, 0x00, 0x2e, 0x01, 0x89, 0x62, 0x0e, 0xfa, 0x2f, 0x43, + 0x42, 0x11, 0x30, 0xfb, 0x6f, 0xc0, 0x2e, 0x01, 0x42, 0xb0, 0x5f, 0x50, 0x51, 0x91, 0x54, 0xeb, 0x7f, 0x11, 0x30, + 0x0a, 0x25, 0xff, 0x56, 0x11, 0x5d, 0x95, 0x40, 0xc4, 0x40, 0x25, 0x01, 0xd4, 0x42, 0x4d, 0x17, 0xc4, 0x40, 0x65, + 0x03, 0xd5, 0x42, 0x56, 0x0e, 0xf5, 0x2f, 0x15, 0x57, 0x02, 0x30, 0xc6, 0x40, 0xb1, 0x29, 0xe6, 0x42, 0x00, 0x2e, + 0xc3, 0x40, 0xc0, 0xb2, 0x0a, 0x23, 0x4c, 0x14, 0x71, 0x0e, 0xd4, 0x7f, 0x90, 0x2e, 0x93, 0xb3, 0x03, 0x31, 0xe1, + 0x52, 0xe3, 0x54, 0x5c, 0x05, 0x8a, 0x28, 0x2b, 0x82, 0x03, 0x57, 0xdd, 0x5e, 0x2e, 0x80, 0xde, 0x8c, 0x30, 0x89, + 0xff, 0x29, 0x96, 0x7f, 0x60, 0x7f, 0xc5, 0x7f, 0xb3, 0x7f, 0xa4, 0x7f, 0x82, 0x7f, 0x77, 0x7f, 0x51, 0x7f, 0x00, + 0x2e, 0x90, 0x41, 0x92, 0x41, 0xd3, 0x6f, 0xc0, 0xb2, 0x46, 0x7f, 0x31, 0x7f, 0x08, 0x2f, 0xd0, 0xa0, 0x02, 0x2f, + 0xa0, 0x6f, 0x05, 0x2c, 0x10, 0x10, 0xc6, 0x6f, 0x96, 0x14, 0x03, 0x12, 0x02, 0x0a, 0x05, 0x2e, 0xd3, 0x00, 0x80, + 0x90, 0xd7, 0x54, 0x40, 0x42, 0x4a, 0x2f, 0x41, 0x40, 0x98, 0x2e, 0xd9, 0xc0, 0xdb, 0x54, 0xd9, 0x52, 0x20, 0x7f, + 0x98, 0x2e, 0xfe, 0xc9, 0x72, 0x6f, 0x10, 0x25, 0x98, 0x2e, 0xfe, 0xc9, 0x22, 0x6f, 0xe3, 0x30, 0x10, 0x25, 0x98, + 0x2e, 0x0f, 0xca, 0x91, 0x6f, 0x76, 0x86, 0xd9, 0x52, 0xdd, 0x54, 0xd0, 0x42, 0x93, 0x7f, 0x98, 0x2e, 0xfe, 0xc9, + 0x22, 0x6f, 0xe3, 0x30, 0x10, 0x25, 0x98, 0x2e, 0x0f, 0xca, 0x91, 0x6f, 0xdf, 0x54, 0x40, 0x42, 0x79, 0x80, 0xd9, + 0x52, 0x90, 0x7f, 0x98, 0x2e, 0xfe, 0xc9, 0x82, 0x6f, 0x10, 0x25, 0x98, 0x2e, 0xfe, 0xc9, 0x22, 0x6f, 0xe3, 0x30, + 0x10, 0x25, 0x98, 0x2e, 0x0f, 0xca, 0x93, 0x6f, 0xe1, 0x54, 0xd9, 0x52, 0xd0, 0x42, 0x13, 0x7f, 0x98, 0x2e, 0xfe, + 0xc9, 0x22, 0x6f, 0xe3, 0x30, 0x10, 0x25, 0x98, 0x2e, 0x0f, 0xca, 0x13, 0x6f, 0xe5, 0x5e, 0xc0, 0x42, 0xf7, 0x7f, + 0x00, 0x2e, 0x22, 0x6f, 0x91, 0x6f, 0xe1, 0x5a, 0xe3, 0x58, 0xdf, 0x5c, 0xe1, 0x56, 0x98, 0x2e, 0x67, 0xcc, 0xb1, + 0x6f, 0x02, 0x2c, 0x40, 0x42, 0xb1, 0x6f, 0x41, 0x80, 0x32, 0x6f, 0x81, 0x82, 0x62, 0x6f, 0x46, 0x6f, 0x96, 0x7f, + 0x4a, 0x0e, 0xb0, 0x7f, 0x94, 0x2f, 0xf1, 0x3d, 0x01, 0x55, 0x10, 0x30, 0x53, 0x6f, 0x91, 0x00, 0x21, 0x2e, 0xd3, + 0x00, 0x66, 0x6f, 0xd1, 0x40, 0x80, 0x40, 0x01, 0x00, 0x90, 0x42, 0x09, 0x16, 0x85, 0x40, 0x28, 0x02, 0x80, 0x42, + 0x9a, 0x80, 0xd7, 0x54, 0xd6, 0x7f, 0xc3, 0x7f, 0xb0, 0x7f, 0x98, 0x2e, 0xd9, 0xc0, 0x05, 0x30, 0xf5, 0x7f, 0x20, + 0x25, 0xb1, 0x6f, 0xdd, 0x58, 0xdb, 0x5c, 0xdd, 0x56, 0x98, 0x2e, 0x67, 0xcc, 0xd6, 0x6f, 0xc3, 0x6f, 0xb2, 0x6f, + 0x61, 0x6f, 0xa7, 0x84, 0x90, 0x43, 0x59, 0x0e, 0xdf, 0x2f, 0x10, 0x30, 0x81, 0x40, 0x08, 0x28, 0x90, 0x42, 0xd2, + 0x7f, 0x02, 0xa0, 0x27, 0x2f, 0xd5, 0x54, 0x03, 0x53, 0x03, 0x30, 0x96, 0x40, 0x80, 0x40, 0x08, 0x17, 0x15, 0x30, + 0x65, 0x09, 0xb5, 0x01, 0xc3, 0x02, 0x61, 0xb8, 0x94, 0x8c, 0xb6, 0x7f, 0xbf, 0xbd, 0xd7, 0x54, 0xc1, 0x7f, 0x43, + 0x0a, 0x98, 0x2e, 0xd9, 0xc0, 0xe5, 0x54, 0xf2, 0x7f, 0x20, 0x25, 0xb1, 0x6f, 0xe1, 0x5a, 0xe3, 0x58, 0xdf, 0x5c, + 0xe1, 0x56, 0x98, 0x2e, 0x67, 0xcc, 0xb2, 0x6f, 0x03, 0x30, 0xc1, 0x6f, 0xab, 0x84, 0x0b, 0x5d, 0x93, 0x42, 0x50, + 0x42, 0x4e, 0x0e, 0x93, 0x42, 0xdb, 0x2f, 0x83, 0x42, 0x00, 0x2e, 0xd1, 0x6f, 0x98, 0x2e, 0xb3, 0xc0, 0x61, 0x6f, + 0xc0, 0x7f, 0x98, 0x2e, 0xb3, 0xc0, 0x51, 0x6f, 0xb0, 0x7f, 0x98, 0x2e, 0xb3, 0xc0, 0x00, 0xa0, 0xe7, 0x52, 0x08, + 0x22, 0xb2, 0x6f, 0xc1, 0x6f, 0xa0, 0x7f, 0xb3, 0x30, 0x98, 0x2e, 0x0f, 0xca, 0xb2, 0x6f, 0xb0, 0x7f, 0xb3, 0x30, + 0xe9, 0x52, 0x98, 0x2e, 0x5a, 0xca, 0xd6, 0x6f, 0x02, 0x30, 0x61, 0x6f, 0xd2, 0x7f, 0x90, 0x7f, 0x81, 0x7f, 0xb3, + 0x30, 0x42, 0x40, 0x91, 0x41, 0x76, 0x7f, 0x98, 0x2e, 0x0f, 0xca, 0xd2, 0x6f, 0x81, 0x6f, 0x10, 0x28, 0x41, 0x40, + 0x92, 0x6f, 0xd0, 0x7f, 0xb3, 0x30, 0x98, 0x2e, 0x0f, 0xca, 0x81, 0x6f, 0x76, 0x6f, 0x0b, 0x55, 0x50, 0x42, 0x72, + 0x0e, 0xe9, 0x2f, 0xc2, 0x6f, 0xa1, 0x6f, 0x98, 0x2e, 0xfe, 0xc9, 0x10, 0x25, 0xb3, 0x30, 0x21, 0x25, 0x98, 0x2e, + 0x0f, 0xca, 0x20, 0x25, 0x13, 0x51, 0xeb, 0x52, 0x98, 0x2e, 0xcb, 0xb3, 0xc5, 0x6f, 0x13, 0x51, 0xed, 0x5c, 0x12, + 0x40, 0x75, 0x05, 0x31, 0x30, 0x11, 0x86, 0x05, 0x5d, 0xc1, 0x7f, 0x15, 0x0f, 0x00, 0x40, 0x08, 0x2f, 0x3f, 0x80, + 0x00, 0xa8, 0x21, 0x2e, 0xc3, 0x00, 0x00, 0x30, 0x0a, 0x2f, 0x90, 0x43, 0x09, 0x2c, 0x80, 0x43, 0x01, 0x80, 0x03, + 0xa0, 0x21, 0x2e, 0xc3, 0x00, 0x10, 0x30, 0x01, 0x2f, 0x91, 0x43, 0x80, 0x43, 0x00, 0x2e, 0xef, 0x54, 0x00, 0x6f, + 0x82, 0x0f, 0x03, 0x2f, 0xf0, 0x6e, 0xf1, 0x54, 0x02, 0x0f, 0x14, 0x2f, 0xe1, 0x6e, 0xc3, 0x7f, 0x98, 0x2e, 0x74, + 0xc0, 0xc3, 0x6f, 0xf3, 0x54, 0x01, 0x30, 0xc1, 0x7f, 0xc2, 0x0f, 0x0a, 0x2f, 0xf0, 0x6e, 0xf5, 0x52, 0x81, 0x0e, + 0x11, 0x30, 0x04, 0x2f, 0x00, 0x6f, 0x00, 0xa4, 0x11, 0x30, 0x00, 0x2f, 0x21, 0x30, 0xc1, 0x7f, 0xf1, 0x80, 0xc2, + 0x40, 0x80, 0x90, 0x07, 0x2f, 0x07, 0x55, 0xb8, 0x86, 0x12, 0x30, 0xc1, 0x42, 0xd7, 0x86, 0x23, 0x2e, 0xc5, 0x00, + 0xc2, 0x42, 0x38, 0x8a, 0x02, 0x40, 0x0a, 0x1a, 0x07, 0x55, 0x00, 0x30, 0x02, 0x2f, 0x91, 0x42, 0x0e, 0x2c, 0x80, + 0x42, 0x03, 0x2e, 0xc6, 0x00, 0x12, 0x30, 0x4a, 0x28, 0x23, 0x2e, 0xc6, 0x00, 0x50, 0xa0, 0x04, 0x2f, 0x09, 0x55, + 0x89, 0x82, 0xc3, 0x6f, 0x83, 0x42, 0x40, 0x42, 0x00, 0x2e, 0x05, 0x2e, 0x8e, 0x00, 0x84, 0x8c, 0x47, 0x41, 0xa1, + 0x41, 0xa1, 0x56, 0xc0, 0xb3, 0x0b, 0x09, 0xc4, 0x05, 0x44, 0x89, 0x85, 0x41, 0xf3, 0xbf, 0x82, 0x8d, 0xa7, 0x7f, + 0x94, 0x7f, 0x0a, 0x2f, 0x09, 0x2e, 0xc4, 0x00, 0x00, 0x91, 0x06, 0x2f, 0x81, 0x80, 0xf9, 0x58, 0x0b, 0x40, 0xfb, + 0x5a, 0x84, 0x7f, 0x0c, 0x2c, 0xfb, 0x50, 0x2b, 0x09, 0x98, 0xb9, 0x44, 0x04, 0xd8, 0xba, 0x82, 0x84, 0x53, 0xbc, + 0xf7, 0x5e, 0xb3, 0xbe, 0x8b, 0x40, 0x13, 0xbe, 0x87, 0x7f, 0xb3, 0x30, 0x86, 0x41, 0xfd, 0x52, 0xb2, 0x6f, 0x76, + 0x7f, 0x60, 0x7f, 0x55, 0x7f, 0x4b, 0x7f, 0x34, 0x7f, 0x98, 0x2e, 0x0f, 0xca, 0xd1, 0x6f, 0x88, 0x0e, 0x03, 0x2f, + 0x01, 0x2e, 0xbc, 0x00, 0x00, 0xb2, 0x03, 0x2f, 0x00, 0x30, 0x21, 0x2e, 0xbe, 0x00, 0x10, 0x2d, 0x03, 0x2e, 0xbe, + 0x00, 0x10, 0x30, 0x48, 0x28, 0x72, 0x6f, 0xa8, 0xb9, 0x23, 0x2e, 0xbe, 0x00, 0x0b, 0x0e, 0xc1, 0x6f, 0x0b, 0x55, + 0x03, 0x2f, 0x90, 0x42, 0x91, 0x42, 0x00, 0x30, 0x80, 0x42, 0xb3, 0x30, 0xb2, 0x6f, 0x41, 0x6f, 0x98, 0x2e, 0x0f, + 0xca, 0xd1, 0x6f, 0x08, 0x0f, 0x03, 0x2f, 0x01, 0x2e, 0xbc, 0x00, 0x00, 0x90, 0x03, 0x2f, 0x00, 0x30, 0x21, 0x2e, + 0xc0, 0x00, 0x12, 0x2d, 0x01, 0x2e, 0xc0, 0x00, 0x71, 0x6f, 0xa1, 0x54, 0x01, 0x80, 0x4a, 0x08, 0x21, 0x2e, 0xc0, + 0x00, 0x01, 0x0e, 0x07, 0x2f, 0x0d, 0x51, 0x02, 0x80, 0x01, 0x30, 0x21, 0x42, 0x12, 0x30, 0x01, 0x42, 0x25, 0x2e, + 0xbf, 0x00, 0x91, 0x6f, 0x7e, 0x84, 0x43, 0x40, 0x82, 0x40, 0x7c, 0x80, 0x9a, 0x29, 0x03, 0x40, 0x46, 0x42, 0xc3, + 0xb2, 0x06, 0x30, 0x00, 0x30, 0x2b, 0x2f, 0xc0, 0x6f, 0x00, 0xb2, 0x00, 0x30, 0x27, 0x2f, 0x01, 0x2e, 0xc4, 0x00, + 0x00, 0x90, 0x00, 0x30, 0x05, 0x2f, 0xc2, 0x90, 0x03, 0x2f, 0xc0, 0x6f, 0x03, 0x90, 0x00, 0x30, 0x1c, 0x2f, 0x00, + 0x6f, 0x83, 0x6f, 0x83, 0x0e, 0x00, 0x30, 0x17, 0x2f, 0xf3, 0x6e, 0x50, 0x6f, 0x98, 0x0f, 0x00, 0x30, 0x12, 0x2f, + 0xa0, 0x6f, 0x98, 0x0e, 0x00, 0x30, 0x0e, 0x2f, 0xe3, 0x6e, 0x60, 0x6f, 0x98, 0x0f, 0x00, 0x30, 0x09, 0x2f, 0x30, + 0x6f, 0x98, 0x0e, 0x00, 0x30, 0x05, 0x2f, 0x80, 0xb2, 0x00, 0x30, 0x02, 0x2f, 0x2d, 0x2e, 0xbc, 0x00, 0x10, 0x30, + 0x42, 0x40, 0x82, 0xac, 0x56, 0x82, 0x01, 0x2f, 0x00, 0xb2, 0x05, 0x2f, 0x0d, 0x55, 0x82, 0x84, 0x2d, 0x2e, 0xbf, + 0x00, 0x86, 0x42, 0x00, 0x2e, 0x0f, 0x55, 0x56, 0x42, 0x56, 0x42, 0x4a, 0x0e, 0xfb, 0x2f, 0x2d, 0x2e, 0xd6, 0x00, + 0x01, 0x2d, 0x00, 0x30, 0xeb, 0x6f, 0xb0, 0x5e, 0xb8, 0x2e, 0x70, 0x50, 0x0a, 0x25, 0x39, 0x80, 0xf3, 0x7f, 0x03, + 0x42, 0xa1, 0x7f, 0xc2, 0x7f, 0xd1, 0x7f, 0x03, 0x30, 0x03, 0x43, 0xe4, 0x7f, 0xbb, 0x7f, 0x22, 0x30, 0x10, 0x25, + 0x98, 0x2e, 0x7a, 0xc1, 0xd2, 0x6f, 0x02, 0x17, 0x04, 0x08, 0xc1, 0x6f, 0x0c, 0x09, 0x04, 0x1a, 0x10, 0x30, 0x04, + 0x30, 0x20, 0x22, 0x01, 0xb2, 0x14, 0x2f, 0x17, 0x59, 0x14, 0x09, 0xf3, 0x30, 0x93, 0x08, 0x24, 0xbd, 0x44, 0xba, + 0x94, 0x0a, 0x02, 0x17, 0xf3, 0x6f, 0x4c, 0x08, 0x9a, 0x08, 0x8a, 0x0a, 0x19, 0x53, 0x51, 0x08, 0xa1, 0x58, 0x94, + 0x08, 0x28, 0xbd, 0x98, 0xb8, 0xe4, 0x6f, 0x51, 0x0a, 0x01, 0x43, 0x00, 0x2e, 0xbb, 0x6f, 0x90, 0x5f, 0xb8, 0x2e, + 0x1b, 0x57, 0x05, 0x40, 0x69, 0x18, 0x0d, 0x17, 0xe1, 0x18, 0x19, 0x05, 0x16, 0x25, 0x37, 0x25, 0x4a, 0x17, 0x54, + 0x18, 0xec, 0x18, 0x04, 0x30, 0x64, 0x07, 0xea, 0x18, 0x8e, 0x00, 0x5f, 0x02, 0xd9, 0x56, 0x93, 0x00, 0x4c, 0x02, + 0x2f, 0xb9, 0x91, 0xbc, 0x91, 0x0a, 0x02, 0x42, 0xb8, 0x2e, 0x00, 0x2e, 0x10, 0x24, 0xfa, 0x07, 0x11, 0x24, 0x00, + 0x10, 0x12, 0x24, 0x80, 0x2e, 0x13, 0x24, 0x00, 0xc1, 0x12, 0x42, 0x13, 0x42, 0x41, 0x1a, 0xfb, 0x2f, 0x10, 0x24, + 0x50, 0x32, 0x11, 0x24, 0x21, 0x2e, 0x21, 0x2e, 0x10, 0x00, 0x23, 0x2e, 0x11, 0x00, 0x80, 0x2e, 0x10, 0x00 +}; + +/*! @name Global array that stores the feature input configuration of BMI270_WH */ +const struct bmi2_feature_config bmi270_wh_feat_in[BMI270_WH_MAX_FEAT_IN] = { + { .type = BMI2_CONFIG_ID, .page = BMI2_PAGE_1, .start_addr = BMI270_WH_CONFIG_ID_STRT_ADDR }, + { .type = BMI2_MAX_BURST_LEN, .page = BMI2_PAGE_1, .start_addr = BMI270_WH_MAX_BURST_LEN_STRT_ADDR }, + { .type = BMI2_AXIS_MAP, .page = BMI2_PAGE_1, .start_addr = BMI270_WH_AXIS_MAP_STRT_ADDR }, + { .type = BMI2_NVM_PROG_PREP, .page = BMI2_PAGE_1, .start_addr = BMI270_WH_NVM_PROG_PREP_STRT_ADDR }, + { .type = BMI2_GYRO_GAIN_UPDATE, .page = BMI2_PAGE_1, .start_addr = BMI270_WH_GYRO_GAIN_UPDATE_STRT_ADDR }, + { .type = BMI2_ANY_MOTION, .page = BMI2_PAGE_1, .start_addr = BMI270_WH_ANY_MOT_STRT_ADDR }, + { .type = BMI2_NO_MOTION, .page = BMI2_PAGE_2, .start_addr = BMI270_WH_NO_MOT_STRT_ADDR }, + { .type = BMI2_STEP_COUNTER_PARAMS, .page = BMI2_PAGE_3, .start_addr = BMI270_WH_STEP_CNT_1_STRT_ADDR }, + { .type = BMI2_STEP_DETECTOR, .page = BMI2_PAGE_6, .start_addr = BMI270_WH_STEP_CNT_4_STRT_ADDR }, + { .type = BMI2_STEP_COUNTER, .page = BMI2_PAGE_6, .start_addr = BMI270_WH_STEP_CNT_4_STRT_ADDR }, + { .type = BMI2_STEP_ACTIVITY, .page = BMI2_PAGE_6, .start_addr = BMI270_WH_STEP_CNT_4_STRT_ADDR }, + { .type = BMI2_WRIST_WEAR_WAKE_UP_WH, .page = BMI2_PAGE_2, .start_addr = BMI270_WH_WRIST_WEAR_WAKE_UP_STRT_ADDR }, +}; + +/*! @name Global array that stores the feature output configuration */ +const struct bmi2_feature_config bmi270_wh_feat_out[BMI270_WH_MAX_FEAT_OUT] = { + { .type = BMI2_STEP_COUNTER, .page = BMI2_PAGE_0, .start_addr = BMI270_WH_STEP_CNT_OUT_STRT_ADDR }, + { .type = BMI2_STEP_ACTIVITY, .page = BMI2_PAGE_0, .start_addr = BMI270_WH_STEP_ACT_OUT_STRT_ADDR }, + { .type = BMI2_GYRO_GAIN_UPDATE, .page = BMI2_PAGE_0, .start_addr = BMI270_WH_GYR_USER_GAIN_OUT_STRT_ADDR }, + { .type = BMI2_GYRO_CROSS_SENSE, .page = BMI2_PAGE_0, .start_addr = BMI270_WH_GYRO_CROSS_SENSE_STRT_ADDR }, + { .type = BMI2_NVM_STATUS, .page = BMI2_PAGE_0, .start_addr = BMI270_WH_NVM_VFRM_OUT_STRT_ADDR }, + { .type = BMI2_VFRM_STATUS, .page = BMI2_PAGE_0, .start_addr = BMI270_WH_NVM_VFRM_OUT_STRT_ADDR } +}; + +/*! @name Global array that stores the feature interrupts of BMI270_WH */ +struct bmi2_map_int bmi270wh_map_int[BMI270_WH_MAX_INT_MAP] = { + { .type = BMI2_STEP_COUNTER, .sens_map_int = BMI270_WH_INT_STEP_COUNTER_MASK }, + { .type = BMI2_STEP_DETECTOR, .sens_map_int = BMI270_WH_INT_STEP_DETECTOR_MASK }, + { .type = BMI2_STEP_ACTIVITY, .sens_map_int = BMI270_WH_INT_STEP_ACT_MASK }, + { .type = BMI2_WRIST_WEAR_WAKE_UP_WH, .sens_map_int = BMI270_WH_INT_WRIST_WEAR_WAKEUP_WH_MASK }, + { .type = BMI2_ANY_MOTION, .sens_map_int = BMI270_WH_INT_ANY_MOT_MASK }, + { .type = BMI2_NO_MOTION, .sens_map_int = BMI270_WH_INT_NO_MOT_MASK }, +}; + +/******************************************************************************/ + +/*! Local Function Prototypes + ******************************************************************************/ + +/*! + * @brief This internal API is used to validate the device pointer for + * null conditions. + * + * @param[in] dev : Structure instance of bmi2_dev. + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +static int8_t null_ptr_check(const struct bmi2_dev *dev); + +/*! + * @brief This internal API enables the selected sensor/features. + * + * @param[in] sensor_sel : Selects the desired sensor. + * @param[in, out] dev : Structure instance of bmi2_dev. + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +static int8_t sensor_enable(uint64_t sensor_sel, struct bmi2_dev *dev); + +/*! + * @brief This internal API disables the selected sensor/features. + * + * @param[in] sensor_sel : Selects the desired sensor. + * @param[in, out] dev : Structure instance of bmi2_dev. + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +static int8_t sensor_disable(uint64_t sensor_sel, struct bmi2_dev *dev); + +/*! + * @brief This internal API selects the sensors/features to be enabled or + * disabled. + * + * @param[in] sens_list : Pointer to select the sensor. + * @param[in] n_sens : Number of sensors selected. + * @param[out] sensor_sel : Gets the selected sensor. + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +static int8_t select_sensor(const uint8_t *sens_list, uint8_t n_sens, uint64_t *sensor_sel); + +/*! + * @brief This internal API is used to enable/disable any-motion feature. + * + * @param[in] dev : Structure instance of bmi2_dev. + * @param[in] enable : Enables/Disables any-motion. + * + * Enable | Description + * -------------|--------------- + * BMI2_DISABLE | Disables any-motion. + * BMI2_ENABLE | Enables any-motion. + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +static int8_t set_any_motion(uint8_t enable, struct bmi2_dev *dev); + +/*! + * @brief This internal API is used to enable/disable no-motion feature. + * + * @param[in] dev : Structure instance of bmi2_dev. + * @param[in] enable : Enables/Disables no-motion. + * + * Enable | Description + * -------------|--------------- + * BMI2_DISABLE | Disables no-motion. + * BMI2_ENABLE | Enables no-motion. + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +static int8_t set_no_motion(uint8_t enable, struct bmi2_dev *dev); + +/*! + * @brief This internal API is used to enable/disable step detector feature. + * + * @param[in] dev : Structure instance of bmi2_dev. + * @param[in] enable : Enables/Disables step-detector. + * + * Enable | Description + * -------------|--------------- + * BMI2_DISABLE | Disables step detector + * BMI2_ENABLE | Enables step detector + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +static int8_t set_step_detector(uint8_t enable, struct bmi2_dev *dev); + +/*! + * @brief This internal API is used to enable/disable step counter feature. + * + * @param[in] dev : Structure instance of bmi2_dev. + * @param[in] enable : Enables/Disables step counter. + * + * Enable | Description + * -------------|--------------- + * BMI2_DISABLE | Disables step counter + * BMI2_ENABLE | Enables step counter + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +static int8_t set_step_counter(uint8_t enable, struct bmi2_dev *dev); + +/*! + * @brief This internal API is used to enable/disable step activity detection. + * + * @param[in] dev : Structure instance of bmi2_dev. + * @param[in] enable : Enables/Disables step activity. + * + * Enable | Description + * -------------|--------------- + * BMI2_DISABLE | Disables step activity + * BMI2_ENABLE | Enables step activity + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +static int8_t set_step_activity(uint8_t enable, struct bmi2_dev *dev); + +/*! + * @brief This internal API is used to enable/disable gyroscope user gain + * feature. + * + * @param[in] dev : Structure instance of bmi2_dev. + * @param[in] enable : Enables/Disables gyroscope user gain. + * + * Enable | Description + * -------------|--------------- + * BMI2_DISABLE | Disables gyroscope user gain + * BMI2_ENABLE | Enables gyroscope user gain + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +static int8_t set_gyro_user_gain(uint8_t enable, struct bmi2_dev *dev); + +/*! + * @brief This internal API enables the wrist wear wake up feature for wearable variant. + * + * @param[in] dev : Structure instance of bmi2_dev. + * @param[in] enable : Enables/Disables wrist wear wake up. + * + * Enable | Description + * -------------|--------------- + * BMI2_DISABLE | Disables wrist wear wake up + * BMI2_ENABLE | Enables wrist wear wake up + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +static int8_t set_wrist_wear_wake_up_wh(uint8_t enable, struct bmi2_dev *dev); + +/*! + * @brief This internal API sets any-motion configurations like axes select, + * duration, threshold and output-configuration. + * + * @param[in] config : Structure instance of bmi2_any_motion_config. + * @param[in, out] dev : Structure instance of bmi2_dev. + * + * @verbatim + *---------------------------------------------------------------------------- + * bmi2_any_motion_config | + * Structure parameters | Description + *--------------------------|-------------------------------------------------- + * | Defines the number of consecutive data points for + * | which the threshold condition must be respected, + * | for interrupt assertion. It is expressed in 50 Hz + * duration | samples (20 msec). + * | Range is 0 to 163sec. + * | Default value is 5 = 100ms. + * -------------------------|--------------------------------------------------- + * | Slope threshold value for in 5.11g format. + * threshold | Range is 0 to 1g. + * | Default value is 0xAA = 83mg. + * -------------------------|--------------------------------------------------- + * x_sel, y_sel, z_sel | Selects the feature on a per-axis basis + * -------------------------|--------------------------------------------------- + * @endverbatim + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +static int8_t set_any_motion_config(const struct bmi2_any_motion_config *config, struct bmi2_dev *dev); + +/*! + * @brief This internal API sets no-motion configurations like axes select, + * duration, threshold and output-configuration. + * + * @param[in] config : Structure instance of bmi2_no_motion_config. + * @param[in, out] dev : Structure instance of bmi2_dev. + * + * @verbatim + *---------------------------------------------------------------------------- + * bmi2_no_motion_config | + * Structure parameters | Description + *--------------------------|-------------------------------------------------- + * | Defines the number of consecutive data points for + * | which the threshold condition must be respected, + * | for interrupt assertion. It is expressed in 50 Hz + * duration | samples (20 msec). + * | Range is 0 to 163sec. + * | Default value is 5 = 100ms. + * -------------------------|--------------------------------------------------- + * | Slope threshold value for in 5.11g format. + * threshold | Range is 0 to 1g. + * | Default value is 0xAA = 83mg. + * -------------------------|--------------------------------------------------- + * x_sel, y_sel, z_sel | Selects the feature on a per-axis basis + * -------------------------|--------------------------------------------------- + * @endverbatim + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +static int8_t set_no_motion_config(const struct bmi2_no_motion_config *config, struct bmi2_dev *dev); + +/*! + * @brief This internal API sets step counter parameter configurations. + * + * @param[in] step_count_params : Array that stores parameters 1 to 25. + * @param[in] dev : Structure instance of bmi2_dev. + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +static int8_t set_step_count_params_config(const uint16_t *step_count_params, struct bmi2_dev *dev); + +/*! + * @brief This internal API sets step counter/detector/activity configurations. + * + * @param[in] config : Structure instance of bmi2_step_config. + * @param[in] dev : Structure instance of bmi2_dev. + * + *--------------------------------------------------------------------------- + * bmi2_step_config | + * Structure parameters | Description + *--------------------------|-------------------------------------------------- + * | The Step-counter will trigger output every time + * | the number of steps are counted. Holds implicitly + * water-mark level | a 20x factor, so the range is 0 to 10230, + * | with resolution of 20 steps. + * -------------------------|--------------------------------------------------- + * reset counter | Flag to reset the counted steps. + * -------------------------|--------------------------------------------------- + * @endverbatim + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +static int8_t set_step_config(const struct bmi2_step_config *config, struct bmi2_dev *dev); + +/*! + * @brief This internal API sets wrist wear wake-up configurations like + * output-configuration for wearable variant. + * + * @param[in] config : Structure instance of + * bmi2_wrist_wear_wake_up_config. + * @param[in, out] dev : Structure instance of bmi2_dev. + * + * @verbatim + *-------------------------------------|---------------------------------------- + * bmi2_wrist_wear_wake_up_wh_config | + * Structure parameters | Description + *-------------------------------------|------------------------------------------- + * | To set the wrist wear wake-up parameters like + * | min_angle_focus, min_angle_nonfocus, + * wrist_wear_wake_wh_params | angle_landscape_left, angle_landscape_right, + * | angle_potrait_up and down. + * ------------------------------------|------------------------------------------- + * @endverbatim + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +static int8_t set_wrist_wear_wake_up_wh_config(const struct bmi2_wrist_wear_wake_up_wh_config *config, + struct bmi2_dev *dev); + +/*! + * @brief This internal API gets any-motion configurations like axes select, + * duration, threshold and output-configuration. + * + * @param[out] config : Structure instance of bmi2_any_motion_config. + * @param[in, out] dev : Structure instance of bmi2_dev. + * + * @verbatim + *---------------------------------------------------------------------------- + * bmi2_any_motion_config | + * Structure parameters | Description + *--------------------------|-------------------------------------------------- + * | Defines the number of consecutive data points for + * | which the threshold condition must be respected, + * | for interrupt assertion. It is expressed in 50 Hz + * duration | samples (20 msec). + * | Range is 0 to 163sec. + * | Default value is 5 = 100ms. + * -------------------------|--------------------------------------------------- + * | Slope threshold value for in 5.11g format. + * threshold | Range is 0 to 1g. + * | Default value is 0xAA = 83mg. + * -------------------------|--------------------------------------------------- + * x_sel, y_sel, z_sel | Selects the feature on a per-axis basis + * -------------------------|--------------------------------------------------- + * @endverbatim + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +static int8_t get_any_motion_config(struct bmi2_any_motion_config *config, struct bmi2_dev *dev); + +/*! + * @brief This internal API gets no-motion configurations like axes select, + * duration, threshold and output-configuration. + * + * @param[out] config : Structure instance of bmi2_no_motion_config. + * @param[in, out] dev : Structure instance of bmi2_dev. + * + * @verbatim + *---------------------------------------------------------------------------- + * bmi2_no_motion_config | + * Structure parameters | Description + *--------------------------|-------------------------------------------------- + * | Defines the number of consecutive data points for + * | which the threshold condition must be respected, + * | for interrupt assertion. It is expressed in 50 Hz + * duration | samples (20 msec). + * | Range is 0 to 163sec. + * | Default value is 5 = 100ms. + * -------------------------|--------------------------------------------------- + * | Slope threshold value for in 5.11g format. + * threshold | Range is 0 to 1g. + * | Default value is 0xAA = 83mg. + * -------------------------|--------------------------------------------------- + * x_sel, y_sel, z_sel | Selects the feature on a per-axis basis + * -------------------------|--------------------------------------------------- + * @endverbatim + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +static int8_t get_no_motion_config(struct bmi2_no_motion_config *config, struct bmi2_dev *dev); + +/*! + * @brief This internal API gets step counter parameter configurations. + * + * @param[in] step_count_params : Array that stores parameters 1 to 25. + * @param[in] dev : Structure instance of bmi2_dev. + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +static int8_t get_step_count_params_config(uint16_t *step_count_params, struct bmi2_dev *dev); + +/*! + * @brief This internal API gets step counter/detector/activity configurations. + * + * @param[out] config : Structure instance of bmi2_step_config. + * @param[in] dev : Structure instance of bmi2_dev. + * + * @verbatim + *---------------------------------------------------------------------------- + * bmi2_step_config | + * Structure parameters | Description + *--------------------------|-------------------------------------------------- + * | The Step-counter will trigger output every time + * | the number of steps are counted. Holds implicitly + * water-mark level | a 20x factor, so the range is 0 to 10230, + * | with resolution of 20 steps. + * -------------------------|--------------------------------------------------- + * reset counter | Flag to reset the counted steps. + * -------------------------|--------------------------------------------------- + * @endverbatim + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +static int8_t get_step_config(struct bmi2_step_config *config, struct bmi2_dev *dev); + +/*! + * @brief This internal API gets wrist wear wake-up configurations like + * output-configuration for wearable variant. + * + * @param[out] config : Structure instance of + * bmi2_wrist_wear_wake_up_config. + * @param[in, out] dev : Structure instance of bmi2_dev. + * + * @verbatim + *----------------------------------------------------------------------------- + * bmi2_wrist_wear_wake_up_config | + * Structure parameters | Description + *----------------------------------|------------------------------------------- + * | To get the wrist wear wake-up parameters like + * | min_angle_focus, min_angle_nonfocus, + * wrist_wear_wake_params | angle_landscape_left, angle_landscape_right, + * | angle_potrait_up and down. + * ---------------------------------|------------------------------------------- + * @endverbatim + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +static int8_t get_wrist_wear_wake_up_wh_config(struct bmi2_wrist_wear_wake_up_wh_config *config, struct bmi2_dev *dev); + +/*! + * @brief This internal API gets the output values of step activity. + * + * @param[out] step_act : Pointer to the stored step activity data. + * @param[in] dev : Structure instance of bmi2_dev. + * + * *step_act | Output + * -----------|------------ + * 0x00 | STILL + * 0x01 | WALKING + * 0x02 | RUNNING + * 0x03 | UNKNOWN + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +static int8_t get_step_activity_output(uint8_t *step_act, struct bmi2_dev *dev); + +/*! + * @brief This internal API gets the output values of step counter. + * + * @param[out] step_count : Pointer to the stored step counter data. + * @param[in] dev : Structure instance of bmi2_dev. + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +static int8_t get_step_counter_output(uint32_t *step_count, struct bmi2_dev *dev); + +/*! + * @brief This internal API gets the error status related to NVM. + * + * @param[out] nvm_err_stat : Stores the NVM error status. + * @param[in] dev : Structure instance of bmi2_dev. + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +static int8_t get_nvm_error_status(struct bmi2_nvm_err_status *nvm_err_stat, struct bmi2_dev *dev); + +/*! + * @brief This internal API gets the error status related to virtual frames. + * + * @param[out] vfrm_err_stat : Stores the VFRM related error status. + * @param[in] dev : Structure instance of bmi2_dev. + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +static int8_t get_vfrm_error_status(struct bmi2_vfrm_err_status *vfrm_err_stat, struct bmi2_dev *dev); + +/*! + * @brief This internal API is used to get enable status of gyroscope user gain + * update. + * + * @param[out] status : Stores status of gyroscope user gain update. + * @param[in] dev : Structure instance of bmi2_dev. + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +static int8_t get_user_gain_upd_status(uint8_t *status, struct bmi2_dev *dev); + +/*! + * @brief This internal API enables/disables compensation of the gain defined + * in the GAIN register. + * + * @param[in] enable : Enables/Disables gain compensation + * @param[in] dev : Structure instance of bmi2_dev. + * + * enable | Description + * -------------|--------------- + * BMI2_ENABLE | Enable gain compensation. + * BMI2_DISABLE | Disable gain compensation. + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +static int8_t enable_gyro_gain(uint8_t enable, struct bmi2_dev *dev); + +/*! + * @brief This internal API is used to extract the output feature configuration + * details like page and start address from the look-up table. + * + * @param[out] feat_output : Structure that stores output feature + * configurations. + * @param[in] type : Type of feature or sensor. + * @param[in] dev : Structure instance of bmi2_dev. + * + * @return Returns the feature found flag. + * + * @retval BMI2_FALSE : Feature not found + * BMI2_TRUE : Feature found + */ +static uint8_t extract_output_feat_config(struct bmi2_feature_config *feat_output, + uint8_t type, + const struct bmi2_dev *dev); + +/***************************************************************************/ + +/*! User Interface Definitions + ****************************************************************************/ + +/*! + * @brief This API: + * 1) updates the device structure with address of the configuration file. + * 2) Initializes BMI270_WH sensor. + * 3) Writes the configuration file. + * 4) Updates the feature offset parameters in the device structure. + * 5) Updates the maximum number of pages, in the device structure. + */ +int8_t bmi270_wh_init(struct bmi2_dev *dev) +{ + /* Variable to define error */ + int8_t rslt; + + /* Null-pointer check */ + rslt = null_ptr_check(dev); + if (rslt == BMI2_OK) + { + /* Assign chip id of BMI270_WH */ + dev->chip_id = BMI270_WH_CHIP_ID; + + /* get the size of config array */ + dev->config_size = sizeof(bmi270_wh_config_file); + + /* Enable the variant specific features if any */ + dev->variant_feature = BMI2_GYRO_CROSS_SENS_ENABLE | BMI2_CRT_RTOSK_ENABLE; + + /* An extra dummy byte is read during SPI read */ + if (dev->intf == BMI2_SPI_INTF) + { + dev->dummy_byte = 1; + } + else + { + dev->dummy_byte = 0; + } + + /* If configuration file pointer is not assigned any address */ + if (!dev->config_file_ptr) + { + /* Give the address of the configuration file array to + * the device pointer + */ + dev->config_file_ptr = bmi270_wh_config_file; + } + + /* Initialize BMI2 sensor */ + rslt = bmi2_sec_init(dev); + if (rslt == BMI2_OK) + { + /* Assign the offsets of the feature input + * configuration to the device structure + */ + dev->feat_config = bmi270_wh_feat_in; + + /* Assign the offsets of the feature output to + * the device structure + */ + dev->feat_output = bmi270_wh_feat_out; + + /* Assign the maximum number of pages to the + * device structure + */ + dev->page_max = BMI270_WH_MAX_PAGE_NUM; + + /* Assign maximum number of input sensors/ + * features to device structure + */ + dev->input_sens = BMI270_WH_MAX_FEAT_IN; + + /* Assign maximum number of output sensors/ + * features to device structure + */ + dev->out_sens = BMI270_WH_MAX_FEAT_OUT; + + /* Assign the offsets of the feature interrupt + * to the device structure + */ + dev->map_int = bmi270wh_map_int; + + /* Assign maximum number of feature interrupts + * to device structure + */ + dev->sens_int_map = BMI270_WH_MAX_INT_MAP; + + /* Get the gyroscope cross axis sensitivity */ + rslt = bmi2_get_gyro_cross_sense(dev); + } + } + + return rslt; +} + +/*! + * @brief This API selects the sensors/features to be enabled. + */ +int8_t bmi270_wh_sensor_enable(const uint8_t *sens_list, uint8_t n_sens, struct bmi2_dev *dev) +{ + /* Variable to define error */ + int8_t rslt; + + /* Variable to select sensor */ + uint64_t sensor_sel = 0; + + /* Null-pointer check */ + rslt = null_ptr_check(dev); + if ((rslt == BMI2_OK) && (sens_list != NULL)) + { + /* Get the selected sensors */ + rslt = select_sensor(sens_list, n_sens, &sensor_sel); + if (rslt == BMI2_OK) + { + /* Enable the selected sensors */ + rslt = sensor_enable(sensor_sel, dev); + } + } + else + { + rslt = BMI2_E_NULL_PTR; + } + + return rslt; +} + +/*! + * @brief This API selects the sensors/features to be disabled. + */ +int8_t bmi270_wh_sensor_disable(const uint8_t *sens_list, uint8_t n_sens, struct bmi2_dev *dev) +{ + /* Variable to define error */ + int8_t rslt; + + /* Variable to select sensor */ + uint64_t sensor_sel = 0; + + /* Null-pointer check */ + rslt = null_ptr_check(dev); + if ((rslt == BMI2_OK) && (sens_list != NULL)) + { + /* Get the selected sensors */ + rslt = select_sensor(sens_list, n_sens, &sensor_sel); + if (rslt == BMI2_OK) + { + /* Disable the selected sensors */ + rslt = sensor_disable(sensor_sel, dev); + } + } + else + { + rslt = BMI2_E_NULL_PTR; + } + + return rslt; +} + +/*! + * @brief This API sets the sensor/feature configuration. + */ +int8_t bmi270_wh_set_sensor_config(struct bmi2_sens_config *sens_cfg, uint8_t n_sens, struct bmi2_dev *dev) +{ + /* Variable to define error */ + int8_t rslt; + + /* Variable to define loop */ + uint8_t loop; + + /* Variable to get the status of advance power save */ + uint8_t aps_stat = 0; + + /* Null-pointer check */ + rslt = null_ptr_check(dev); + if ((rslt == BMI2_OK) && (sens_cfg != NULL)) + { + /* Get status of advance power save mode */ + aps_stat = dev->aps_status; + + for (loop = 0; loop < n_sens; loop++) + { + if ((sens_cfg[loop].type == BMI2_ACCEL) || (sens_cfg[loop].type == BMI2_GYRO) || + (sens_cfg[loop].type == BMI2_AUX) || (sens_cfg[loop].type == BMI2_GYRO_GAIN_UPDATE)) + { + rslt = bmi2_set_sensor_config(&sens_cfg[loop], 1, dev); + } + else + { + /* Disable Advance power save if enabled for auxiliary + * and feature configurations + */ + if (aps_stat == BMI2_ENABLE) + { + /* Disable advance power save if + * enabled + */ + rslt = bmi2_set_adv_power_save(BMI2_DISABLE, dev); + } + + if (rslt == BMI2_OK) + { + switch (sens_cfg[loop].type) + { + /* Set any motion configuration */ + case BMI2_ANY_MOTION: + rslt = set_any_motion_config(&sens_cfg[loop].cfg.any_motion, dev); + break; + + /* Set no motion configuration */ + case BMI2_NO_MOTION: + rslt = set_no_motion_config(&sens_cfg[loop].cfg.no_motion, dev); + break; + + /* Set the step counter parameters */ + case BMI2_STEP_COUNTER_PARAMS: + rslt = set_step_count_params_config(sens_cfg[loop].cfg.step_counter_params, dev); + break; + + /* Set step counter/detector/activity configuration */ + case BMI2_STEP_DETECTOR: + case BMI2_STEP_COUNTER: + case BMI2_STEP_ACTIVITY: + rslt = set_step_config(&sens_cfg[loop].cfg.step_counter, dev); + break; + + /* Set the wrist wear wake-up configuration for wearable variant */ + case BMI2_WRIST_WEAR_WAKE_UP_WH: + rslt = set_wrist_wear_wake_up_wh_config(&sens_cfg[loop].cfg.wrist_wear_wake_up_wh, dev); + break; + + default: + rslt = BMI2_E_INVALID_SENSOR; + break; + } + } + + /* Return error if any of the set configurations fail */ + if (rslt != BMI2_OK) + { + break; + } + } + } + + /* Enable Advance power save if disabled while configuring and + * not when already disabled + */ + if ((aps_stat == BMI2_ENABLE) && (rslt == BMI2_OK)) + { + rslt = bmi2_set_adv_power_save(BMI2_ENABLE, dev); + } + } + else + { + rslt = BMI2_E_NULL_PTR; + } + + return rslt; +} + +/*! + * @brief This API gets the sensor/feature configuration. + */ +int8_t bmi270_wh_get_sensor_config(struct bmi2_sens_config *sens_cfg, uint8_t n_sens, struct bmi2_dev *dev) +{ + /* Variable to define error */ + int8_t rslt; + + /* Variable to define loop */ + uint8_t loop; + + /* Variable to get the status of advance power save */ + uint8_t aps_stat = 0; + + /* Null-pointer check */ + rslt = null_ptr_check(dev); + if ((rslt == BMI2_OK) && (sens_cfg != NULL)) + { + /* Get status of advance power save mode */ + aps_stat = dev->aps_status; + for (loop = 0; loop < n_sens; loop++) + { + if ((sens_cfg[loop].type == BMI2_ACCEL) || (sens_cfg[loop].type == BMI2_GYRO) || + (sens_cfg[loop].type == BMI2_AUX) || (sens_cfg[loop].type == BMI2_GYRO_GAIN_UPDATE)) + { + rslt = bmi2_get_sensor_config(&sens_cfg[loop], 1, dev); + } + else + { + /* Disable Advance power save if enabled for auxiliary + * and feature configurations + */ + if ((sens_cfg[loop].type >= BMI2_MAIN_SENS_MAX_NUM) || (sens_cfg[loop].type == BMI2_AUX)) + { + + if (aps_stat == BMI2_ENABLE) + { + /* Disable advance power save if + * enabled + */ + rslt = bmi2_set_adv_power_save(BMI2_DISABLE, dev); + } + } + + if (rslt == BMI2_OK) + { + switch (sens_cfg[loop].type) + { + /* Get any motion configuration */ + case BMI2_ANY_MOTION: + rslt = get_any_motion_config(&sens_cfg[loop].cfg.any_motion, dev); + break; + + /* Get no motion configuration */ + case BMI2_NO_MOTION: + rslt = get_no_motion_config(&sens_cfg[loop].cfg.no_motion, dev); + break; + + /* Set the step counter parameters */ + case BMI2_STEP_COUNTER_PARAMS: + rslt = get_step_count_params_config(sens_cfg[loop].cfg.step_counter_params, dev); + break; + + /* Get step counter/detector/activity configuration */ + case BMI2_STEP_DETECTOR: + case BMI2_STEP_COUNTER: + case BMI2_STEP_ACTIVITY: + rslt = get_step_config(&sens_cfg[loop].cfg.step_counter, dev); + break; + + /* Get the wrist wear wake-up configuration for wearable variant */ + case BMI2_WRIST_WEAR_WAKE_UP_WH: + rslt = get_wrist_wear_wake_up_wh_config(&sens_cfg[loop].cfg.wrist_wear_wake_up_wh, dev); + break; + + default: + rslt = BMI2_E_INVALID_SENSOR; + break; + } + } + + /* Return error if any of the get configurations fail */ + if (rslt != BMI2_OK) + { + break; + } + } + } + + /* Enable Advance power save if disabled while configuring and + * not when already disabled + */ + if ((aps_stat == BMI2_ENABLE) && (rslt == BMI2_OK)) + { + rslt = bmi2_set_adv_power_save(BMI2_ENABLE, dev); + } + } + else + { + rslt = BMI2_E_NULL_PTR; + } + + return rslt; +} + +/*! + * @brief This API gets the sensor/feature data for accelerometer, gyroscope, + * auxiliary sensor, step counter, high-g, gyroscope user-gain update, + * orientation, gyroscope cross sensitivity and error status for NVM and VFRM. + */ +int8_t bmi270_wh_get_sensor_data(struct bmi2_sensor_data *sensor_data, uint8_t n_sens, struct bmi2_dev *dev) +{ + /* Variable to define error */ + int8_t rslt; + + /* Variable to define loop */ + uint8_t loop; + + /* Variable to get the status of advance power save */ + uint8_t aps_stat = 0; + + /* Null-pointer check */ + rslt = null_ptr_check(dev); + if ((rslt == BMI2_OK) && (sensor_data != NULL)) + { + /* Get status of advance power save mode */ + aps_stat = dev->aps_status; + for (loop = 0; loop < n_sens; loop++) + { + if ((sensor_data[loop].type == BMI2_ACCEL) || (sensor_data[loop].type == BMI2_GYRO) || + (sensor_data[loop].type == BMI2_AUX) || (sensor_data[loop].type == BMI2_GYRO_GAIN_UPDATE) || + (sensor_data[loop].type == BMI2_GYRO_CROSS_SENSE)) + { + rslt = bmi2_get_sensor_data(&sensor_data[loop], 1, dev); + } + else + { + /* Disable Advance power save if enabled for feature + * configurations + */ + if (sensor_data[loop].type >= BMI2_MAIN_SENS_MAX_NUM) + { + if (aps_stat == BMI2_ENABLE) + { + /* Disable advance power save if + * enabled + */ + rslt = bmi2_set_adv_power_save(BMI2_DISABLE, dev); + } + } + + if (rslt == BMI2_OK) + { + switch (sensor_data[loop].type) + { + case BMI2_STEP_COUNTER: + + /* Get step counter output */ + rslt = get_step_counter_output(&sensor_data[loop].sens_data.step_counter_output, dev); + break; + case BMI2_STEP_ACTIVITY: + + /* Get step activity output */ + rslt = get_step_activity_output(&sensor_data[loop].sens_data.activity_output, dev); + break; + case BMI2_NVM_STATUS: + + /* Get NVM error status */ + rslt = get_nvm_error_status(&sensor_data[loop].sens_data.nvm_status, dev); + break; + case BMI2_VFRM_STATUS: + + /* Get VFRM error status */ + rslt = get_vfrm_error_status(&sensor_data[loop].sens_data.vfrm_status, dev); + break; + default: + rslt = BMI2_E_INVALID_SENSOR; + break; + } + + /* Return error if any of the get sensor data fails */ + if (rslt != BMI2_OK) + { + break; + } + } + } + + /* Enable Advance power save if disabled while + * configuring and not when already disabled + */ + if ((aps_stat == BMI2_ENABLE) && (rslt == BMI2_OK)) + { + rslt = bmi2_set_adv_power_save(BMI2_ENABLE, dev); + } + } + } + else + { + rslt = BMI2_E_NULL_PTR; + } + + return rslt; +} + +/*! + * @brief This API updates the gyroscope user-gain. + */ +int8_t bmi270_wh_update_gyro_user_gain(const struct bmi2_gyro_user_gain_config *user_gain, struct bmi2_dev *dev) +{ + /* Variable to define error */ + int8_t rslt; + + /* Variable to select sensor */ + uint8_t sens_sel[2] = { BMI2_GYRO, BMI2_GYRO_GAIN_UPDATE }; + + /* Structure to define sensor configurations */ + struct bmi2_sens_config sens_cfg; + + /* Variable to store status of user-gain update module */ + uint8_t status = 0; + + /* Variable to define count */ + uint8_t count = 100; + + /* Null-pointer check */ + rslt = null_ptr_check(dev); + if ((rslt == BMI2_OK) && (user_gain != NULL)) + { + /* Select type of feature */ + sens_cfg.type = BMI2_GYRO_GAIN_UPDATE; + + /* Get the user gain configurations */ + rslt = bmi270_wh_get_sensor_config(&sens_cfg, 1, dev); + if (rslt == BMI2_OK) + { + /* Get the user-defined ratio */ + sens_cfg.cfg.gyro_gain_update = *user_gain; + + /* Set rate ratio for all axes */ + rslt = bmi270_wh_set_sensor_config(&sens_cfg, 1, dev); + } + + /* Disable gyroscope */ + if (rslt == BMI2_OK) + { + rslt = bmi270_wh_sensor_disable(&sens_sel[0], 1, dev); + } + + /* Enable gyroscope user-gain update module */ + if (rslt == BMI2_OK) + { + rslt = bmi270_wh_sensor_enable(&sens_sel[1], 1, dev); + } + + /* Set the command to trigger the computation */ + if (rslt == BMI2_OK) + { + rslt = bmi2_set_command_register(BMI2_USR_GAIN_CMD, dev); + } + + if (rslt == BMI2_OK) + { + /* Poll until enable bit of user-gain update is 0 */ + while (count--) + { + rslt = get_user_gain_upd_status(&status, dev); + if ((rslt == BMI2_OK) && (status == 0)) + { + /* Enable compensation of gain defined + * in the GAIN register + */ + rslt = enable_gyro_gain(BMI2_ENABLE, dev); + + /* Enable gyroscope */ + if (rslt == BMI2_OK) + { + rslt = bmi270_wh_sensor_enable(&sens_sel[0], 1, dev); + } + + break; + } + + dev->delay_us(10000, dev->intf_ptr); + } + + /* Return error if user-gain update is failed */ + if ((rslt == BMI2_OK) && (status != 0)) + { + rslt = BMI2_E_GYR_USER_GAIN_UPD_FAIL; + } + } + } + else + { + rslt = BMI2_E_NULL_PTR; + } + + return rslt; +} + +/*! + * @brief This API reads the compensated gyroscope user-gain values. + */ +int8_t bmi270_wh_read_gyro_user_gain(struct bmi2_gyro_user_gain_data *gyr_usr_gain, struct bmi2_dev *dev) +{ + /* Variable to define error */ + int8_t rslt; + + /* Variable to define register data */ + uint8_t reg_data[3] = { 0 }; + + /* Null-pointer check */ + rslt = null_ptr_check(dev); + if ((rslt == BMI2_OK) && (gyr_usr_gain != NULL)) + { + /* Get the gyroscope compensated gain values */ + rslt = bmi2_get_regs(BMI2_GYR_USR_GAIN_0_ADDR, reg_data, 3, dev); + if (rslt == BMI2_OK) + { + /* Gyroscope user gain correction X-axis */ + gyr_usr_gain->x = (int8_t)BMI2_GET_BIT_POS0(reg_data[0], BMI2_GYR_USR_GAIN_X); + + /* Gyroscope user gain correction Y-axis */ + gyr_usr_gain->y = (int8_t)BMI2_GET_BIT_POS0(reg_data[1], BMI2_GYR_USR_GAIN_Y); + + /* Gyroscope user gain correction z-axis */ + gyr_usr_gain->z = (int8_t)BMI2_GET_BIT_POS0(reg_data[2], BMI2_GYR_USR_GAIN_Z); + } + } + else + { + rslt = BMI2_E_NULL_PTR; + } + + return rslt; +} + +/*! + * @brief This API maps/unmaps feature interrupts to that of interrupt pins. + */ +int8_t bmi270_wh_map_feat_int(const struct bmi2_sens_int_config *sens_int, uint8_t n_sens, struct bmi2_dev *dev) +{ + /* Variable to define error */ + int8_t rslt; + + /* Variable to define loop */ + uint8_t loop; + + /* Null-pointer check */ + rslt = null_ptr_check(dev); + if ((rslt == BMI2_OK) && (sens_int != NULL)) + { + for (loop = 0; loop < n_sens; loop++) + { + switch (sens_int[loop].type) + { + case BMI2_ANY_MOTION: + case BMI2_NO_MOTION: + case BMI2_STEP_COUNTER: + case BMI2_STEP_DETECTOR: + case BMI2_STEP_ACTIVITY: + case BMI2_WRIST_WEAR_WAKE_UP_WH: + + rslt = bmi2_map_feat_int(sens_int[loop].type, sens_int[loop].hw_int_pin, dev); + break; + default: + rslt = BMI2_E_INVALID_SENSOR; + break; + } + + /* Return error if interrupt mapping fails */ + if (rslt != BMI2_OK) + { + break; + } + } + } + else + { + rslt = BMI2_E_NULL_PTR; + } + + return rslt; +} + +/***************************************************************************/ + +/*! Local Function Definitions + ****************************************************************************/ + +/*! + * @brief This internal API is used to validate the device structure pointer for + * null conditions. + */ +static int8_t null_ptr_check(const struct bmi2_dev *dev) +{ + /* Variable to define error */ + int8_t rslt = BMI2_OK; + + if ((dev == NULL) || (dev->read == NULL) || (dev->write == NULL) || (dev->delay_us == NULL)) + { + /* Device structure pointer is not valid */ + rslt = BMI2_E_NULL_PTR; + } + + return rslt; +} + +/*! + * @brief This internal API selects the sensor/features to be enabled or + * disabled. + */ +static int8_t select_sensor(const uint8_t *sens_list, uint8_t n_sens, uint64_t *sensor_sel) +{ + /* Variable to define error */ + int8_t rslt = BMI2_OK; + + /* Variable to define loop */ + uint8_t count; + + for (count = 0; count < n_sens; count++) + { + switch (sens_list[count]) + { + case BMI2_ACCEL: + *sensor_sel |= BMI2_ACCEL_SENS_SEL; + break; + case BMI2_GYRO: + *sensor_sel |= BMI2_GYRO_SENS_SEL; + break; + case BMI2_AUX: + *sensor_sel |= BMI2_AUX_SENS_SEL; + break; + case BMI2_TEMP: + *sensor_sel |= BMI2_TEMP_SENS_SEL; + break; + case BMI2_ANY_MOTION: + *sensor_sel |= BMI2_ANY_MOT_SEL; + break; + case BMI2_NO_MOTION: + *sensor_sel |= BMI2_NO_MOT_SEL; + break; + case BMI2_STEP_DETECTOR: + *sensor_sel |= BMI2_STEP_DETECT_SEL; + break; + case BMI2_STEP_COUNTER: + *sensor_sel |= BMI2_STEP_COUNT_SEL; + break; + case BMI2_STEP_ACTIVITY: + *sensor_sel |= BMI2_STEP_ACT_SEL; + break; + case BMI2_GYRO_GAIN_UPDATE: + *sensor_sel |= BMI2_GYRO_GAIN_UPDATE_SEL; + break; + case BMI2_WRIST_WEAR_WAKE_UP_WH: + *sensor_sel |= BMI2_WRIST_WEAR_WAKE_UP_WH_SEL; + break; + default: + rslt = BMI2_E_INVALID_SENSOR; + break; + } + } + + return rslt; +} + +/*! + * @brief This internal API enables the selected sensor/features. + */ +static int8_t sensor_enable(uint64_t sensor_sel, struct bmi2_dev *dev) +{ + /* Variable to define error */ + int8_t rslt; + + /* Variable to store register values */ + uint8_t reg_data = 0; + + /* Variable to define loop */ + uint8_t loop = 1; + + /* Variable to get the status of advance power save */ + uint8_t aps_stat = 0; + + rslt = bmi2_get_regs(BMI2_PWR_CTRL_ADDR, ®_data, 1, dev); + if (rslt == BMI2_OK) + { + /* Enable accelerometer */ + if (sensor_sel & BMI2_ACCEL_SENS_SEL) + { + reg_data = BMI2_SET_BITS(reg_data, BMI2_ACC_EN, BMI2_ENABLE); + } + + /* Enable gyroscope */ + if (sensor_sel & BMI2_GYRO_SENS_SEL) + { + reg_data = BMI2_SET_BITS(reg_data, BMI2_GYR_EN, BMI2_ENABLE); + } + + /* Enable auxiliary sensor */ + if (sensor_sel & BMI2_AUX_SENS_SEL) + { + reg_data = BMI2_SET_BIT_POS0(reg_data, BMI2_AUX_EN, BMI2_ENABLE); + } + + /* Enable temperature sensor */ + if (sensor_sel & BMI2_TEMP_SENS_SEL) + { + reg_data = BMI2_SET_BITS(reg_data, BMI2_TEMP_EN, BMI2_ENABLE); + } + + /* Enable the sensors that are set in the power control register */ + if (sensor_sel & BMI2_MAIN_SENSORS) + { + rslt = bmi2_set_regs(BMI2_PWR_CTRL_ADDR, ®_data, 1, dev); + } + } + + if ((rslt == BMI2_OK) && (sensor_sel & ~(BMI2_MAIN_SENSORS))) + { + /* Get status of advance power save mode */ + aps_stat = dev->aps_status; + if (aps_stat == BMI2_ENABLE) + { + /* Disable advance power save if enabled */ + rslt = bmi2_set_adv_power_save(BMI2_DISABLE, dev); + } + + if (rslt == BMI2_OK) + { + while (loop--) + { + /* Enable any motion feature */ + if (sensor_sel & BMI2_ANY_MOT_SEL) + { + rslt = set_any_motion(BMI2_ENABLE, dev); + if (rslt == BMI2_OK) + { + dev->sens_en_stat |= BMI2_ANY_MOT_SEL; + } + else + { + break; + } + } + + /* Enable no motion feature */ + if (sensor_sel & BMI2_NO_MOT_SEL) + { + rslt = set_no_motion(BMI2_ENABLE, dev); + if (rslt == BMI2_OK) + { + dev->sens_en_stat |= BMI2_NO_MOT_SEL; + } + else + { + break; + } + } + + /* Enable step detector feature */ + if (sensor_sel & BMI2_STEP_DETECT_SEL) + { + rslt = set_step_detector(BMI2_ENABLE, dev); + if (rslt == BMI2_OK) + { + dev->sens_en_stat |= BMI2_STEP_DETECT_SEL; + } + else + { + break; + } + } + + /* Enable step counter feature */ + if (sensor_sel & BMI2_STEP_COUNT_SEL) + { + rslt = set_step_counter(BMI2_ENABLE, dev); + if (rslt == BMI2_OK) + { + dev->sens_en_stat |= BMI2_STEP_COUNT_SEL; + } + else + { + break; + } + } + + /* Enable step activity feature */ + if (sensor_sel & BMI2_STEP_ACT_SEL) + { + rslt = set_step_activity(BMI2_ENABLE, dev); + if (rslt == BMI2_OK) + { + dev->sens_en_stat |= BMI2_STEP_ACT_SEL; + } + else + { + break; + } + } + + /* Enable gyroscope user gain */ + if (sensor_sel & BMI2_GYRO_GAIN_UPDATE_SEL) + { + rslt = set_gyro_user_gain(BMI2_ENABLE, dev); + if (rslt == BMI2_OK) + { + dev->sens_en_stat |= BMI2_GYRO_GAIN_UPDATE_SEL; + } + else + { + break; + } + } + + /* Enable wrist wear wake-up feature for wearable variant */ + if (sensor_sel & BMI2_WRIST_WEAR_WAKE_UP_WH_SEL) + { + rslt = set_wrist_wear_wake_up_wh(BMI2_ENABLE, dev); + if (rslt == BMI2_OK) + { + dev->sens_en_stat |= BMI2_WRIST_WEAR_WAKE_UP_WH_SEL; + } + else + { + break; + } + } + } + + /* Enable Advance power save if disabled while + * configuring and not when already disabled + */ + if ((aps_stat == BMI2_ENABLE) && (rslt == BMI2_OK)) + { + rslt = bmi2_set_adv_power_save(BMI2_ENABLE, dev); + } + } + } + + return rslt; +} + +/*! + * @brief This internal API disables the selected sensors/features. + */ +static int8_t sensor_disable(uint64_t sensor_sel, struct bmi2_dev *dev) +{ + /* Variable to define error */ + int8_t rslt; + + /* Variable to store register values */ + uint8_t reg_data = 0; + + /* Variable to define loop */ + uint8_t loop = 1; + + /* Variable to get the status of advance power save */ + uint8_t aps_stat = 0; + + rslt = bmi2_get_regs(BMI2_PWR_CTRL_ADDR, ®_data, 1, dev); + if (rslt == BMI2_OK) + { + /* Disable accelerometer */ + if (sensor_sel & BMI2_ACCEL_SENS_SEL) + { + reg_data = BMI2_SET_BIT_VAL0(reg_data, BMI2_ACC_EN); + } + + /* Disable gyroscope */ + if (sensor_sel & BMI2_GYRO_SENS_SEL) + { + reg_data = BMI2_SET_BIT_VAL0(reg_data, BMI2_GYR_EN); + } + + /* Disable auxiliary sensor */ + if (sensor_sel & BMI2_AUX_SENS_SEL) + { + reg_data = BMI2_SET_BIT_VAL0(reg_data, BMI2_AUX_EN); + } + + /* Disable temperature sensor */ + if (sensor_sel & BMI2_TEMP_SENS_SEL) + { + reg_data = BMI2_SET_BIT_VAL0(reg_data, BMI2_TEMP_EN); + } + + /* Disable the sensors that are set in the power control register */ + if (sensor_sel & BMI2_MAIN_SENSORS) + { + rslt = bmi2_set_regs(BMI2_PWR_CTRL_ADDR, ®_data, 1, dev); + } + } + + if ((rslt == BMI2_OK) && (sensor_sel & ~(BMI2_MAIN_SENSORS))) + { + /* Get status of advance power save mode */ + aps_stat = dev->aps_status; + if (aps_stat == BMI2_ENABLE) + { + /* Disable advance power save if enabled */ + rslt = bmi2_set_adv_power_save(BMI2_DISABLE, dev); + } + + if (rslt == BMI2_OK) + { + while (loop--) + { + /* Disable any-motion feature */ + if (sensor_sel & BMI2_ANY_MOT_SEL) + { + rslt = set_any_motion(BMI2_DISABLE, dev); + if (rslt == BMI2_OK) + { + dev->sens_en_stat &= ~BMI2_ANY_MOT_SEL; + } + else + { + break; + } + } + + /* Disable no-motion feature */ + if (sensor_sel & BMI2_NO_MOT_SEL) + { + rslt = set_no_motion(BMI2_DISABLE, dev); + if (rslt == BMI2_OK) + { + dev->sens_en_stat &= ~BMI2_NO_MOT_SEL; + } + else + { + break; + } + } + + /* Disable step detector feature */ + if (sensor_sel & BMI2_STEP_DETECT_SEL) + { + rslt = set_step_detector(BMI2_DISABLE, dev); + if (rslt == BMI2_OK) + { + dev->sens_en_stat &= ~BMI2_STEP_DETECT_SEL; + } + else + { + break; + } + } + + /* Disable step counter feature */ + if (sensor_sel & BMI2_STEP_COUNT_SEL) + { + rslt = set_step_counter(BMI2_DISABLE, dev); + if (rslt == BMI2_OK) + { + dev->sens_en_stat &= ~BMI2_STEP_COUNT_SEL; + } + else + { + break; + } + } + + /* Disable step activity feature */ + if (sensor_sel & BMI2_STEP_ACT_SEL) + { + rslt = set_step_activity(BMI2_DISABLE, dev); + if (rslt == BMI2_OK) + { + dev->sens_en_stat &= ~BMI2_STEP_ACT_SEL; + } + else + { + break; + } + } + + /* Disable gyroscope user gain */ + if (sensor_sel & BMI2_GYRO_GAIN_UPDATE_SEL) + { + rslt = set_gyro_user_gain(BMI2_DISABLE, dev); + if (rslt == BMI2_OK) + { + dev->sens_en_stat &= ~BMI2_GYRO_GAIN_UPDATE_SEL; + } + else + { + break; + } + } + + /* Disable wrist wear wake-up feature for wearable variant */ + if (sensor_sel & BMI2_WRIST_WEAR_WAKE_UP_WH_SEL) + { + rslt = set_wrist_wear_wake_up_wh(BMI2_DISABLE, dev); + if (rslt == BMI2_OK) + { + dev->sens_en_stat &= ~BMI2_WRIST_WEAR_WAKE_UP_WH_SEL; + } + else + { + break; + } + } + + /* Enable Advance power save if disabled while + * configuring and not when already disabled + */ + if ((aps_stat == BMI2_ENABLE) && (rslt == BMI2_OK)) + { + rslt = bmi2_set_adv_power_save(BMI2_ENABLE, dev); + } + } + } + } + + return rslt; +} + +/*! + * @brief This internal API is used to enable/disable any motion feature. + */ +static int8_t set_any_motion(uint8_t enable, struct bmi2_dev *dev) +{ + /* Variable to define error */ + int8_t rslt; + + /* Array to define the feature configuration */ + uint8_t feat_config[BMI2_FEAT_SIZE_IN_BYTES] = { 0 }; + + /* Variable to define the array offset */ + uint8_t idx = 0; + + /* Variable to set flag */ + uint8_t feat_found; + + /* Initialize feature configuration for any-motion */ + struct bmi2_feature_config any_mot_config = { 0, 0, 0 }; + + /* Search for any-motion feature and extract its configurations details */ + feat_found = bmi2_extract_input_feat_config(&any_mot_config, BMI2_ANY_MOTION, dev); + if (feat_found) + { + /* Get the configuration from the page where any-motion feature resides */ + rslt = bmi2_get_feat_config(any_mot_config.page, feat_config, dev); + if (rslt == BMI2_OK) + { + /* Define the offset for enable/disable of any-motion axes */ + idx = any_mot_config.start_addr + BMI2_ANY_MOT_FEAT_EN_OFFSET; + + /* Set the feature enable bit */ + feat_config[idx] = BMI2_SET_BITS(feat_config[idx], BMI2_ANY_NO_MOT_EN, enable); + + /* Set the configuration back to the page */ + rslt = bmi2_set_regs(BMI2_FEATURES_REG_ADDR, feat_config, BMI2_FEAT_SIZE_IN_BYTES, dev); + } + } + else + { + rslt = BMI2_E_INVALID_SENSOR; + } + + return rslt; +} + +/*! + * @brief This internal API is used to enable/disable no-motion feature. + */ +static int8_t set_no_motion(uint8_t enable, struct bmi2_dev *dev) +{ + /* Variable to define error */ + int8_t rslt; + + /* Array to define the feature configuration */ + uint8_t feat_config[BMI2_FEAT_SIZE_IN_BYTES] = { 0 }; + + /* Variable to define the array offset */ + uint8_t idx = 0; + + /* Variable to set flag */ + uint8_t feat_found; + + /* Initialize feature configuration for no-motion */ + struct bmi2_feature_config no_mot_config = { 0, 0, 0 }; + + /* Search for no-motion feature and extract its configurations details */ + feat_found = bmi2_extract_input_feat_config(&no_mot_config, BMI2_NO_MOTION, dev); + if (feat_found) + { + /* Get the configuration from the page where any/no-motion feature resides */ + rslt = bmi2_get_feat_config(no_mot_config.page, feat_config, dev); + if (rslt == BMI2_OK) + { + /* Define the offset for enable/disable of no-motion axes */ + idx = no_mot_config.start_addr + BMI2_NO_MOT_FEAT_EN_OFFSET; + + /* Set the feature enable bit */ + feat_config[idx] = BMI2_SET_BITS(feat_config[idx], BMI2_ANY_NO_MOT_EN, enable); + + /* Set the configuration back to the page */ + rslt = bmi2_set_regs(BMI2_FEATURES_REG_ADDR, feat_config, BMI2_FEAT_SIZE_IN_BYTES, dev); + } + } + else + { + rslt = BMI2_E_INVALID_SENSOR; + } + + return rslt; +} + +/*! + * @brief This internal API is used to enable/disable step detector feature. + */ +static int8_t set_step_detector(uint8_t enable, struct bmi2_dev *dev) +{ + /* Variable to define error */ + int8_t rslt; + + /* Array to define the feature configuration */ + uint8_t feat_config[BMI2_FEAT_SIZE_IN_BYTES] = { 0 }; + + /* Variable to define the array offset */ + uint8_t idx = 0; + + /* Variable to set flag */ + uint8_t feat_found; + + /* Initialize feature configuration for step detector */ + struct bmi2_feature_config step_det_config = { 0, 0, 0 }; + + /* Search for step detector feature and extract its configuration details */ + feat_found = bmi2_extract_input_feat_config(&step_det_config, BMI2_STEP_DETECTOR, dev); + if (feat_found) + { + /* Get the configuration from the page where step detector feature resides */ + rslt = bmi2_get_feat_config(step_det_config.page, feat_config, dev); + if (rslt == BMI2_OK) + { + /* Define the offset for enable/disable of step detector */ + idx = step_det_config.start_addr + BMI2_STEP_COUNT_FEAT_EN_OFFSET; + + /* Set the feature enable bit */ + feat_config[idx] = BMI2_SET_BITS(feat_config[idx], BMI2_STEP_DET_FEAT_EN, enable); + + /* Set the configuration back to the page */ + rslt = bmi2_set_regs(BMI2_FEATURES_REG_ADDR, feat_config, BMI2_FEAT_SIZE_IN_BYTES, dev); + } + } + else + { + rslt = BMI2_E_INVALID_SENSOR; + } + + return rslt; +} + +/*! + * @brief This internal API is used to enable/disable step counter feature. + */ +static int8_t set_step_counter(uint8_t enable, struct bmi2_dev *dev) +{ + /* Variable to define error */ + int8_t rslt; + + /* Array to define the feature configuration */ + uint8_t feat_config[BMI2_FEAT_SIZE_IN_BYTES] = { 0 }; + + /* Variable to define the array offset */ + uint8_t idx = 0; + + /* Variable to set flag */ + uint8_t feat_found; + + /* Initialize feature configuration for step counter */ + struct bmi2_feature_config step_count_config = { 0, 0, 0 }; + + /* Search for step counter feature and extract its configuration details */ + feat_found = bmi2_extract_input_feat_config(&step_count_config, BMI2_STEP_COUNTER, dev); + if (feat_found) + { + /* Get the configuration from the page where step-counter feature resides */ + rslt = bmi2_get_feat_config(step_count_config.page, feat_config, dev); + if (rslt == BMI2_OK) + { + /* Define the offset for enable/disable of step counter */ + idx = step_count_config.start_addr + BMI2_STEP_COUNT_FEAT_EN_OFFSET; + + /* Set the feature enable bit */ + feat_config[idx] = BMI2_SET_BITS(feat_config[idx], BMI2_STEP_COUNT_FEAT_EN, enable); + + /* Set the configuration back to the page */ + rslt = bmi2_set_regs(BMI2_FEATURES_REG_ADDR, feat_config, BMI2_FEAT_SIZE_IN_BYTES, dev); + } + } + else + { + rslt = BMI2_E_INVALID_SENSOR; + } + + return rslt; +} + +/*! + * @brief This internal API is used to enable/disable step activity detection. + */ +static int8_t set_step_activity(uint8_t enable, struct bmi2_dev *dev) +{ + /* Variable to define error */ + int8_t rslt; + + /* Array to define the feature configuration */ + uint8_t feat_config[BMI2_FEAT_SIZE_IN_BYTES] = { 0 }; + + /* Variable to define the array offset */ + uint8_t idx = 0; + + /* Variable to set flag */ + uint8_t feat_found; + + /* Initialize feature configuration for step activity */ + struct bmi2_feature_config step_act_config = { 0, 0, 0 }; + + /* Search for step activity feature and extract its configuration details */ + feat_found = bmi2_extract_input_feat_config(&step_act_config, BMI2_STEP_ACTIVITY, dev); + if (feat_found) + { + /* Get the configuration from the page where step-activity + * feature resides + */ + rslt = bmi2_get_feat_config(step_act_config.page, feat_config, dev); + if (rslt == BMI2_OK) + { + /* Define the offset for enable/disable of step activity */ + idx = step_act_config.start_addr + BMI2_STEP_COUNT_FEAT_EN_OFFSET; + + /* Set the feature enable bit */ + feat_config[idx] = BMI2_SET_BITS(feat_config[idx], BMI2_STEP_ACT_FEAT_EN, enable); + + /* Set the configuration back to the page */ + rslt = bmi2_set_regs(BMI2_FEATURES_REG_ADDR, feat_config, BMI2_FEAT_SIZE_IN_BYTES, dev); + } + } + else + { + rslt = BMI2_E_INVALID_SENSOR; + } + + return rslt; +} + +/*! + * @brief This internal API enables the wrist wear wake up feature. + */ +static int8_t set_wrist_wear_wake_up_wh(uint8_t enable, struct bmi2_dev *dev) +{ + /* Variable to define error */ + int8_t rslt; + + /* Array to define the feature configuration */ + uint8_t feat_config[BMI2_FEAT_SIZE_IN_BYTES] = { 0 }; + + /* Variable to define the array offset */ + uint8_t idx = 0; + + /* Variable to set flag */ + uint8_t feat_found; + + /* Initialize feature configuration for wrist wear wake up */ + struct bmi2_feature_config wrist_wake_up_cfg = { 0, 0, 0 }; + + /* Search for wrist wear wake up and extract its configuration details */ + feat_found = bmi2_extract_input_feat_config(&wrist_wake_up_cfg, BMI2_WRIST_WEAR_WAKE_UP_WH, dev); + if (feat_found) + { + /* Get the configuration from the page where wrist wear wake up + * feature resides + */ + rslt = bmi2_get_feat_config(wrist_wake_up_cfg.page, feat_config, dev); + if (rslt == BMI2_OK) + { + /* Define the offset for enable/disable of wrist wear wake up */ + idx = wrist_wake_up_cfg.start_addr; + + /* Set the feature enable bit */ + feat_config[idx] = BMI2_SET_BITS(feat_config[idx], BMI2_WRIST_WEAR_WAKE_UP_FEAT_EN, enable); + + /* Set the configuration back to the page */ + rslt = bmi2_set_regs(BMI2_FEATURES_REG_ADDR, feat_config, BMI2_FEAT_SIZE_IN_BYTES, dev); + } + } + else + { + rslt = BMI2_E_INVALID_SENSOR; + } + + return rslt; +} + +/*! + * @brief This internal API is used to enable/disable gyroscope user gain + * feature. + */ +static int8_t set_gyro_user_gain(uint8_t enable, struct bmi2_dev *dev) +{ + /* Variable to define error */ + int8_t rslt; + + /* Array to define the feature configuration */ + uint8_t feat_config[BMI2_FEAT_SIZE_IN_BYTES] = { 0 }; + + /* Variable to define the array offset */ + uint8_t idx = 0; + + /* Variable to set flag */ + uint8_t feat_found; + + /* Initialize feature configuration for gyroscope user gain */ + struct bmi2_feature_config gyr_user_gain_cfg = { 0, 0, 0 }; + + /* Search for user gain feature and extract its configuration details */ + feat_found = bmi2_extract_input_feat_config(&gyr_user_gain_cfg, BMI2_GYRO_GAIN_UPDATE, dev); + if (feat_found) + { + /* Get the configuration from the page where user gain feature resides */ + rslt = bmi2_get_feat_config(gyr_user_gain_cfg.page, feat_config, dev); + if (rslt == BMI2_OK) + { + /* Define the offset for enable/disable of user gain */ + idx = gyr_user_gain_cfg.start_addr + BMI2_GYR_USER_GAIN_FEAT_EN_OFFSET; + + /* Set the feature enable bit */ + feat_config[idx] = BMI2_SET_BITS(feat_config[idx], BMI2_GYR_USER_GAIN_FEAT_EN, enable); + + /* Set the configuration back to the page */ + rslt = bmi2_set_regs(BMI2_FEATURES_REG_ADDR, feat_config, BMI2_FEAT_SIZE_IN_BYTES, dev); + } + } + else + { + rslt = BMI2_E_INVALID_SENSOR; + } + + return rslt; +} + +/*! + * @brief This internal API sets any-motion configurations like axes select, + * duration, threshold and output-configuration. + */ +static int8_t set_any_motion_config(const struct bmi2_any_motion_config *config, struct bmi2_dev *dev) +{ + /* Variable to define error */ + int8_t rslt; + + /* Array to define the feature configuration */ + uint8_t feat_config[BMI2_FEAT_SIZE_IN_BYTES] = { 0 }; + + /* Variable to define the array offset */ + uint8_t idx = 0; + + /* Variable to define count */ + uint8_t index = 0; + + /* Variable to set flag */ + uint8_t feat_found; + + /* Initialize feature configuration for any motion */ + struct bmi2_feature_config any_mot_config = { 0, 0, 0 }; + + /* Copy the feature configuration address to a local pointer */ + uint16_t *data_p = (uint16_t *) (void *)feat_config; + + /* Search for any-motion feature and extract its configuration details */ + feat_found = bmi2_extract_input_feat_config(&any_mot_config, BMI2_ANY_MOTION, dev); + if (feat_found) + { + /* Get the configuration from the page where any-motion feature resides */ + rslt = bmi2_get_feat_config(any_mot_config.page, feat_config, dev); + if (rslt == BMI2_OK) + { + /* Define the offset in bytes for any-motion select */ + idx = any_mot_config.start_addr; + + /* Get offset in words since all the features are set in words length */ + idx = idx / 2; + + /* Set duration */ + *(data_p + idx) = BMI2_SET_BIT_POS0(*(data_p + idx), BMI2_ANY_NO_MOT_DUR, config->duration); + + /* Set x-select */ + *(data_p + idx) = BMI2_SET_BITS(*(data_p + idx), BMI2_ANY_NO_MOT_X_SEL, config->select_x); + + /* Set y-select */ + *(data_p + idx) = BMI2_SET_BITS(*(data_p + idx), BMI2_ANY_NO_MOT_Y_SEL, config->select_y); + + /* Set z-select */ + *(data_p + idx) = BMI2_SET_BITS(*(data_p + idx), BMI2_ANY_NO_MOT_Z_SEL, config->select_z); + + /* Increment offset by 1 word to set threshold and output configuration */ + idx++; + + /* Set threshold */ + *(data_p + idx) = BMI2_SET_BIT_POS0(*(data_p + idx), BMI2_ANY_NO_MOT_THRES, config->threshold); + + /* Increment offset by 1 more word to get the total length in words */ + idx++; + + /* Get total length in bytes to copy from local pointer to the array */ + idx = (uint8_t)(idx * 2) - any_mot_config.start_addr; + + /* Copy the bytes to be set back to the array */ + for (index = 0; index < idx; index++) + { + feat_config[any_mot_config.start_addr + + index] = *((uint8_t *) data_p + any_mot_config.start_addr + index); + } + + /* Set the configuration back to the page */ + rslt = bmi2_set_regs(BMI2_FEATURES_REG_ADDR, feat_config, BMI2_FEAT_SIZE_IN_BYTES, dev); + } + } + else + { + rslt = BMI2_E_INVALID_SENSOR; + } + + return rslt; +} + +/*! + * @brief This internal API sets no-motion configurations like axes select, + * duration, threshold and output-configuration. + */ +static int8_t set_no_motion_config(const struct bmi2_no_motion_config *config, struct bmi2_dev *dev) +{ + /* Variable to define error */ + int8_t rslt; + + /* Array to define the feature configuration */ + uint8_t feat_config[BMI2_FEAT_SIZE_IN_BYTES] = { 0 }; + + /* Variable to define the array offset */ + uint8_t idx = 0; + + /* Variable to define count */ + uint8_t index = 0; + + /* Variable to set flag */ + uint8_t feat_found; + + /* Initialize feature configuration for no-motion */ + struct bmi2_feature_config no_mot_config = { 0, 0, 0 }; + + /* Copy the feature configuration address to a local pointer */ + uint16_t *data_p = (uint16_t *) (void *)feat_config; + + /* Search for no-motion feature and extract its configuration details */ + feat_found = bmi2_extract_input_feat_config(&no_mot_config, BMI2_NO_MOTION, dev); + if (feat_found) + { + /* Get the configuration from the page where no-motion feature resides */ + rslt = bmi2_get_feat_config(no_mot_config.page, feat_config, dev); + if (rslt == BMI2_OK) + { + /* Define the offset in bytes for no-motion select */ + idx = no_mot_config.start_addr; + + /* Get offset in words since all the features are set in words length */ + idx = idx / 2; + + /* Set duration */ + *(data_p + idx) = BMI2_SET_BIT_POS0(*(data_p + idx), BMI2_ANY_NO_MOT_DUR, config->duration); + + /* Set x-select */ + *(data_p + idx) = BMI2_SET_BITS(*(data_p + idx), BMI2_ANY_NO_MOT_X_SEL, config->select_x); + + /* Set y-select */ + *(data_p + idx) = BMI2_SET_BITS(*(data_p + idx), BMI2_ANY_NO_MOT_Y_SEL, config->select_y); + + /* Set z-select */ + *(data_p + idx) = BMI2_SET_BITS(*(data_p + idx), BMI2_ANY_NO_MOT_Z_SEL, config->select_z); + + /* Increment offset by 1 word to set threshold and output configuration */ + idx++; + + /* Set threshold */ + *(data_p + idx) = BMI2_SET_BIT_POS0(*(data_p + idx), BMI2_ANY_NO_MOT_THRES, config->threshold); + + /* Increment offset by 1 more word to get the total length in words */ + idx++; + + /* Get total length in bytes to copy from local pointer to the array */ + idx = (uint8_t)(idx * 2) - no_mot_config.start_addr; + + /* Copy the bytes to be set back to the array */ + for (index = 0; index < idx; index++) + { + feat_config[no_mot_config.start_addr + + index] = *((uint8_t *) data_p + no_mot_config.start_addr + index); + } + + /* Set the configuration back to the page */ + rslt = bmi2_set_regs(BMI2_FEATURES_REG_ADDR, feat_config, BMI2_FEAT_SIZE_IN_BYTES, dev); + } + } + else + { + rslt = BMI2_E_INVALID_SENSOR; + } + + return rslt; +} + +/*! + * @brief This internal API sets step counter parameter configurations. + */ +static int8_t set_step_count_params_config(const uint16_t *step_count_params, struct bmi2_dev *dev) +{ + /* Variable to define error */ + int8_t rslt = BMI2_OK; + + /* Array to define the feature configuration */ + uint8_t feat_config[BMI2_FEAT_SIZE_IN_BYTES] = { 0 }; + + /* Variable to define index */ + uint8_t index = 0; + + /* Variable to set flag */ + uint8_t feat_found; + + /* Initialize feature configuration for step counter parameters */ + struct bmi2_feature_config step_params_config = { 0, 0, 0 }; + + /* Variable to index the page number */ + uint8_t page_idx; + + /* Variable to define the start page */ + uint8_t start_page; + + /* Variable to define start address of the parameters */ + uint8_t start_addr; + + /* Variable to define number of bytes */ + uint8_t n_bytes = (BMI2_STEP_CNT_N_PARAMS * 2); + + /* Variable to store number of pages */ + uint8_t n_pages = (n_bytes / 16); + + /* Variable to define the end page */ + uint8_t end_page; + + /* Variable to define the remaining bytes to be read */ + uint8_t remain_len; + + /* Variable to define the maximum words(16 bytes or 8 words) to be read in a page */ + uint8_t max_len = 8; + + /* Variable index bytes in a page */ + uint8_t page_byte_idx; + + /* Variable to index the parameters */ + uint8_t param_idx = 0; + + /* Copy the feature configuration address to a local pointer */ + uint16_t *data_p = (uint16_t *) (void *)feat_config; + + /* Search for step counter parameter feature and extract its configuration details */ + feat_found = bmi2_extract_input_feat_config(&step_params_config, BMI2_STEP_COUNTER_PARAMS, dev); + if (feat_found) + { + /* Get the start page for the step counter parameters */ + start_page = step_params_config.page; + + /* Get the end page for the step counter parameters */ + end_page = start_page + n_pages; + + /* Get the start address for the step counter parameters */ + start_addr = step_params_config.start_addr; + + /* Get the remaining length of bytes to be read */ + remain_len = (uint8_t)((n_bytes - (n_pages * 16)) + start_addr); + for (page_idx = start_page; page_idx <= end_page; page_idx++) + { + /* Get the configuration from the respective page */ + rslt = bmi2_get_feat_config(page_idx, feat_config, dev); + if (rslt == BMI2_OK) + { + /* Start from address 0x00 when switched to next page */ + if (page_idx > start_page) + { + start_addr = 0; + } + + /* Remaining number of words to be read in the page */ + if (page_idx == end_page) + { + max_len = (remain_len / 2); + } + + /* Get offset in words since all the features are set in words length */ + page_byte_idx = start_addr / 2; + for (; page_byte_idx < max_len;) + { + /* Set parameters 1 to 25 */ + *(data_p + page_byte_idx) = BMI2_SET_BIT_POS0(*(data_p + page_byte_idx), + BMI2_STEP_COUNT_PARAMS, + step_count_params[param_idx]); + + /* Increment offset by 1 word to set to the next parameter */ + page_byte_idx++; + + /* Increment to next parameter */ + param_idx++; + } + + /* Get total length in bytes to copy from local pointer to the array */ + page_byte_idx = (uint8_t)(page_byte_idx * 2) - step_params_config.start_addr; + + /* Copy the bytes to be set back to the array */ + for (index = 0; index < page_byte_idx; index++) + { + feat_config[step_params_config.start_addr + + index] = *((uint8_t *) data_p + step_params_config.start_addr + index); + } + + /* Set the configuration back to the page */ + rslt = bmi2_set_regs(BMI2_FEATURES_REG_ADDR, feat_config, BMI2_FEAT_SIZE_IN_BYTES, dev); + } + } + } + else + { + rslt = BMI2_E_INVALID_SENSOR; + } + + return rslt; +} + +/* @brief This internal API sets step counter configurations like water-mark + * level, reset-counter and output-configuration step detector and activity. + */ +static int8_t set_step_config(const struct bmi2_step_config *config, struct bmi2_dev *dev) +{ + /* Variable to define error */ + int8_t rslt; + + /* Array to define the feature configuration */ + uint8_t feat_config[BMI2_FEAT_SIZE_IN_BYTES] = { 0 }; + + /* Variable to define the array offset */ + uint8_t idx = 0; + + /* Variable to define index */ + uint8_t index = 0; + + /* Variable to set flag */ + uint8_t feat_found; + + /* Initialize feature configuration for step counter 4 */ + struct bmi2_feature_config step_count_config = { 0, 0, 0 }; + + /* Copy the feature configuration address to a local pointer */ + uint16_t *data_p = (uint16_t *) (void *)feat_config; + + /* Search for step counter feature and extract its configuration details */ + feat_found = bmi2_extract_input_feat_config(&step_count_config, BMI2_STEP_COUNTER, dev); + if (feat_found) + { + /* Get the configuration from the page where step counter resides */ + rslt = bmi2_get_feat_config(step_count_config.page, feat_config, dev); + if (rslt == BMI2_OK) + { + /* Define the offset in bytes */ + idx = step_count_config.start_addr; + + /* Get offset in words since all the features are set in words length */ + idx = idx / 2; + + /* Set water-mark level */ + *(data_p + idx) = BMI2_SET_BIT_POS0(*(data_p + idx), BMI2_STEP_COUNT_WM_LEVEL, config->watermark_level); + + /* Set reset-counter */ + *(data_p + idx) = BMI2_SET_BITS(*(data_p + idx), BMI2_STEP_COUNT_RST_CNT, config->reset_counter); + + /* Increment offset by 1 word to set output + * configuration of step detector and step activity + */ + idx++; + + /* Set step buffer size */ + *(data_p + idx) = BMI2_SET_BITS(*(data_p + idx), BMI2_STEP_BUFFER_SIZE, config->step_buffer_size); + + /* Increment offset by 1 more word to get the total length in words */ + idx++; + + /* Get total length in bytes to copy from local pointer to the array */ + idx = (uint8_t)(idx * 2) - step_count_config.start_addr; + + /* Copy the bytes to be set back to the array */ + for (index = 0; index < idx; index++) + { + feat_config[step_count_config.start_addr + + index] = *((uint8_t *) data_p + step_count_config.start_addr + index); + } + + /* Set the configuration back to the page */ + rslt = bmi2_set_regs(BMI2_FEATURES_REG_ADDR, feat_config, BMI2_FEAT_SIZE_IN_BYTES, dev); + } + } + else + { + rslt = BMI2_E_INVALID_SENSOR; + } + + return rslt; +} + +/*! + * @brief This internal API sets wrist wear wake-up configurations like + * output-configuration for wearable variant. + */ +static int8_t set_wrist_wear_wake_up_wh_config(const struct bmi2_wrist_wear_wake_up_wh_config *config, + struct bmi2_dev *dev) +{ + /* Variable to define error */ + int8_t rslt; + + /* Array to define the feature configuration */ + uint8_t feat_config[BMI2_FEAT_SIZE_IN_BYTES] = { 0 }; + + /* Variable to define the array offset */ + uint8_t idx = 0; + + /* Variable to define index */ + uint8_t index = 0; + + /* Variable to set flag */ + uint8_t feat_found; + + /* Initialize feature configuration for wrist wear wake-up */ + struct bmi2_feature_config wrist_wake_up_config = { 0, 0, 0 }; + + /* Copy the feature configuration address to a local pointer */ + uint16_t *data_p = (uint16_t *) (void *)feat_config; + + /* Search for wrist wear wake-up feature and extract its configuration details */ + feat_found = bmi2_extract_input_feat_config(&wrist_wake_up_config, BMI2_WRIST_WEAR_WAKE_UP_WH, dev); + if (feat_found) + { + /* Get the configuration from the page where wrist wear wake-up feature resides */ + rslt = bmi2_get_feat_config(wrist_wake_up_config.page, feat_config, dev); + if (rslt == BMI2_OK) + { + /* Define the offset in bytes for wrist wear wake-up select */ + idx = wrist_wake_up_config.start_addr; + + /* Get offset in words since all the features are set in words length */ + idx = idx / 2; + + *(data_p + idx) = config->min_angle_focus; + + /* Increment offset by 1 more word to set min_angle_nonfocus */ + idx++; + *(data_p + idx) = config->min_angle_nonfocus; + + /* Increment offset by 1 more word to set angle landscape right and angle landscape left */ + idx++; + *(data_p + idx) = BMI2_SET_BIT_POS0(*(data_p + idx), BMI2_WRIST_WAKE_UP_ANGLE_LR, config->angle_lr); + *(data_p + idx) = BMI2_SET_BITS(*(data_p + idx), BMI2_WRIST_WAKE_UP_ANGLE_LL, config->angle_ll); + + /* Increment offset by 1 more word to set angle portrait down and angle portrait left */ + idx++; + *(data_p + idx) = BMI2_SET_BIT_POS0(*(data_p + idx), BMI2_WRIST_WAKE_UP_ANGLE_PD, config->angle_pd); + *(data_p + idx) = BMI2_SET_BITS(*(data_p + idx), BMI2_WRIST_WAKE_UP_ANGLE_PU, config->angle_pu); + + /* Increment offset by 1 more word to set min duration moved and min duration quite */ + idx++; + *(data_p + idx) = BMI2_SET_BIT_POS0(*(data_p + idx), BMI2_WRIST_WAKE_UP_MIN_DUR_MOVED, config->min_dur_mov); + *(data_p + idx) = BMI2_SET_BITS(*(data_p + idx), BMI2_WRIST_WAKE_UP_MIN_DUR_QUITE, config->min_dur_quite); + + /* Increment offset by 1 more word to get the total length in words */ + idx++; + + /* Get total length in bytes to copy from local pointer to the array */ + idx = (uint8_t)(idx * 2) - wrist_wake_up_config.start_addr; + + /* Copy the bytes to be set back to the array */ + for (index = 0; index < idx; index++) + { + feat_config[wrist_wake_up_config.start_addr + + index] = *((uint8_t *) data_p + wrist_wake_up_config.start_addr + index); + } + + /* Set the configuration back to the page */ + rslt = bmi2_set_regs(BMI2_FEATURES_REG_ADDR, feat_config, BMI2_FEAT_SIZE_IN_BYTES, dev); + } + } + else + { + rslt = BMI2_E_INVALID_SENSOR; + } + + return rslt; +} + +/*! + * @brief This internal API gets any-motion configurations like axes select, + * duration, threshold and output-configuration. + */ +static int8_t get_any_motion_config(struct bmi2_any_motion_config *config, struct bmi2_dev *dev) +{ + /* Variable to define error */ + int8_t rslt; + + /* Array to define the feature configuration */ + uint8_t feat_config[BMI2_FEAT_SIZE_IN_BYTES] = { 0 }; + + /* Variable to define the array offset */ + uint8_t idx = 0; + + /* Variable to define LSB */ + uint16_t lsb; + + /* Variable to define MSB */ + uint16_t msb; + + /* Variable to define a word */ + uint16_t lsb_msb; + + /* Variable to set flag */ + uint8_t feat_found; + + /* Initialize feature configuration for any-motion */ + struct bmi2_feature_config any_mot_config = { 0, 0, 0 }; + + /* Search for any-motion feature and extract its configuration details */ + feat_found = bmi2_extract_input_feat_config(&any_mot_config, BMI2_ANY_MOTION, dev); + if (feat_found) + { + /* Get the configuration from the page where any-motion feature resides */ + rslt = bmi2_get_feat_config(any_mot_config.page, feat_config, dev); + if (rslt == BMI2_OK) + { + /* Define the offset for feature enable for any-motion */ + idx = any_mot_config.start_addr; + + /* Get word to calculate duration, x, y and z select */ + lsb = (uint16_t) feat_config[idx++]; + msb = ((uint16_t) feat_config[idx++] << 8); + lsb_msb = lsb | msb; + + /* Get duration */ + config->duration = lsb_msb & BMI2_ANY_NO_MOT_DUR_MASK; + + /* Get x-select */ + config->select_x = (lsb_msb & BMI2_ANY_NO_MOT_X_SEL_MASK) >> BMI2_ANY_NO_MOT_X_SEL_POS; + + /* Get y-select */ + config->select_y = (lsb_msb & BMI2_ANY_NO_MOT_Y_SEL_MASK) >> BMI2_ANY_NO_MOT_Y_SEL_POS; + + /* Get z-select */ + config->select_z = (lsb_msb & BMI2_ANY_NO_MOT_Z_SEL_MASK) >> BMI2_ANY_NO_MOT_Z_SEL_POS; + + /* Get word to calculate threshold, output configuration from the same word */ + lsb = (uint16_t) feat_config[idx++]; + msb = ((uint16_t) feat_config[idx++] << 8); + lsb_msb = lsb | msb; + + /* Get threshold */ + config->threshold = lsb_msb & BMI2_ANY_NO_MOT_THRES_MASK; + } + } + else + { + rslt = BMI2_E_INVALID_SENSOR; + } + + return rslt; +} + +/*! + * @brief This internal API gets no-motion configurations like axes select, + * duration, threshold and output-configuration. + */ +static int8_t get_no_motion_config(struct bmi2_no_motion_config *config, struct bmi2_dev *dev) +{ + /* Variable to define error */ + int8_t rslt; + + /* Array to define the feature configuration */ + uint8_t feat_config[BMI2_FEAT_SIZE_IN_BYTES] = { 0 }; + + /* Variable to define the array offset */ + uint8_t idx = 0; + + /* Variable to define LSB */ + uint16_t lsb = 0; + + /* Variable to define MSB */ + uint16_t msb = 0; + + /* Variable to define a word */ + uint16_t lsb_msb = 0; + + /* Variable to set flag */ + uint8_t feat_found; + + /* Initialize feature configuration for no-motion */ + struct bmi2_feature_config no_mot_config = { 0, 0, 0 }; + + /* Search for no-motion feature and extract its configuration details */ + feat_found = bmi2_extract_input_feat_config(&no_mot_config, BMI2_NO_MOTION, dev); + if (feat_found) + { + /* Get the configuration from the page where no-motion feature resides */ + rslt = bmi2_get_feat_config(no_mot_config.page, feat_config, dev); + if (rslt == BMI2_OK) + { + /* Define the offset for feature enable for no-motion */ + idx = no_mot_config.start_addr; + + /* Get word to calculate duration, x, y and z select */ + lsb = (uint16_t) feat_config[idx++]; + msb = ((uint16_t) feat_config[idx++] << 8); + lsb_msb = lsb | msb; + + /* Get duration */ + config->duration = lsb_msb & BMI2_ANY_NO_MOT_DUR_MASK; + + /* Get x-select */ + config->select_x = (lsb_msb & BMI2_ANY_NO_MOT_X_SEL_MASK) >> BMI2_ANY_NO_MOT_X_SEL_POS; + + /* Get y-select */ + config->select_y = (lsb_msb & BMI2_ANY_NO_MOT_Y_SEL_MASK) >> BMI2_ANY_NO_MOT_Y_SEL_POS; + + /* Get z-select */ + config->select_z = (lsb_msb & BMI2_ANY_NO_MOT_Z_SEL_MASK) >> BMI2_ANY_NO_MOT_Z_SEL_POS; + + /* Get word to calculate threshold, output configuration from the same word */ + lsb = (uint16_t) feat_config[idx++]; + msb = ((uint16_t) feat_config[idx++] << 8); + lsb_msb = lsb | msb; + + /* Get threshold */ + config->threshold = lsb_msb & BMI2_ANY_NO_MOT_THRES_MASK; + } + } + else + { + rslt = BMI2_E_INVALID_SENSOR; + } + + return rslt; +} + +/*! + * @brief This internal API gets step counter parameter configurations. + */ +static int8_t get_step_count_params_config(uint16_t *step_count_params, struct bmi2_dev *dev) +{ + /* Variable to define error */ + int8_t rslt = BMI2_OK; + + /* Array to define the feature configuration */ + uint8_t feat_config[BMI2_FEAT_SIZE_IN_BYTES] = { 0 }; + + /* Variable to set flag */ + uint8_t feat_found; + + /* Variable to define LSB */ + uint16_t lsb = 0; + + /* Variable to define MSB */ + uint16_t msb = 0; + + /* Variable to define a word */ + uint16_t lsb_msb = 0; + + /* Initialize feature configuration for step counter 1 */ + struct bmi2_feature_config step_params_config = { 0, 0, 0 }; + + /* Variable to index the page number */ + uint8_t page_idx; + + /* Variable to define the start page */ + uint8_t start_page; + + /* Variable to define start address of the parameters */ + uint8_t start_addr; + + /* Variable to define number of bytes */ + uint8_t n_bytes = (BMI2_STEP_CNT_N_PARAMS * 2); + + /* Variable to store number of pages */ + uint8_t n_pages = (n_bytes / 16); + + /* Variable to define the end page */ + uint8_t end_page; + + /* Variable to define the remaining bytes to be read */ + uint8_t remain_len; + + /* Variable to define the maximum words to be read in a page */ + uint8_t max_len = BMI2_FEAT_SIZE_IN_BYTES; + + /* Variable index bytes in a page */ + uint8_t page_byte_idx; + + /* Variable to index the parameters */ + uint8_t param_idx = 0; + + /* Search for step counter parameter feature and extract its configuration details */ + feat_found = bmi2_extract_input_feat_config(&step_params_config, BMI2_STEP_COUNTER_PARAMS, dev); + if (feat_found) + { + /* Get the start page for the step counter parameters */ + start_page = step_params_config.page; + + /* Get the end page for the step counter parameters */ + end_page = start_page + n_pages; + + /* Get the start address for the step counter parameters */ + start_addr = step_params_config.start_addr; + + /* Get the remaining length of bytes to be read */ + remain_len = (uint8_t)((n_bytes - (n_pages * 16)) + start_addr); + for (page_idx = start_page; page_idx <= end_page; page_idx++) + { + /* Get the configuration from the respective page */ + rslt = bmi2_get_feat_config(page_idx, feat_config, dev); + if (rslt == BMI2_OK) + { + /* Start from address 0x00 when switched to next page */ + if (page_idx > start_page) + { + start_addr = 0; + } + + /* Remaining number of bytes to be read in the page */ + if (page_idx == end_page) + { + max_len = remain_len; + } + + /* Get the offset */ + page_byte_idx = start_addr; + while (page_byte_idx < max_len) + { + /* Get word to calculate the parameter*/ + lsb = (uint16_t) feat_config[page_byte_idx++]; + if (page_byte_idx < max_len) + { + msb = ((uint16_t) feat_config[page_byte_idx++] << 8); + } + + lsb_msb = lsb | msb; + + /* Get parameters 1 to 25 */ + step_count_params[param_idx] = lsb_msb & BMI2_STEP_COUNT_PARAMS_MASK; + + /* Increment to next parameter */ + param_idx++; + } + } + } + } + else + { + rslt = BMI2_E_INVALID_SENSOR; + } + + return rslt; +} + +/*! + * @brief This internal API gets step counter/detector/activity configurations. + */ +static int8_t get_step_config(struct bmi2_step_config *config, struct bmi2_dev *dev) +{ + /* Variable to define error */ + int8_t rslt; + + /* Array to define the feature configuration */ + uint8_t feat_config[BMI2_FEAT_SIZE_IN_BYTES] = { 0 }; + + /* Variable to define the array offset */ + uint8_t idx = 0; + + /* Variable to define LSB */ + uint16_t lsb = 0; + + /* Variable to define MSB */ + uint16_t msb = 0; + + /* Variable to define a word */ + uint16_t lsb_msb = 0; + + /* Variable to set flag */ + uint8_t feat_found; + + /* Initialize feature configuration for step counter */ + struct bmi2_feature_config step_count_config = { 0, 0, 0 }; + + /* Search for step counter 4 feature and extract its configuration details */ + feat_found = bmi2_extract_input_feat_config(&step_count_config, BMI2_STEP_COUNTER, dev); + if (feat_found) + { + /* Get the configuration from the page where step counter 4 parameter resides */ + rslt = bmi2_get_feat_config(step_count_config.page, feat_config, dev); + if (rslt == BMI2_OK) + { + /* Define the offset for feature enable for step counter/detector/activity */ + idx = step_count_config.start_addr; + + /* Get word to calculate water-mark level and reset counter */ + lsb = (uint16_t) feat_config[idx++]; + msb = ((uint16_t) feat_config[idx++] << 8); + lsb_msb = lsb | msb; + + /* Get water-mark level */ + config->watermark_level = lsb_msb & BMI2_STEP_COUNT_WM_LEVEL_MASK; + + /* Get reset counter */ + config->reset_counter = (lsb_msb & BMI2_STEP_COUNT_RST_CNT_MASK) >> BMI2_STEP_COUNT_RST_CNT_POS; + + /* Get word to calculate output configuration of step detector and activity */ + lsb = (uint16_t) feat_config[idx++]; + msb = ((uint16_t) feat_config[idx++] << 8); + lsb_msb = lsb | msb; + + config->step_buffer_size = (lsb_msb & BMI2_STEP_BUFFER_SIZE_MASK) >> BMI2_STEP_BUFFER_SIZE_POS; + } + } + else + { + rslt = BMI2_E_INVALID_SENSOR; + } + + return rslt; +} + +/*! + * @brief This internal API gets wrist wear wake-up configurations like min_angle_focus, + * min_angle_nonfocus for wearable variant. + */ +static int8_t get_wrist_wear_wake_up_wh_config(struct bmi2_wrist_wear_wake_up_wh_config *config, struct bmi2_dev *dev) +{ + /* Variable to define error */ + int8_t rslt; + + /* Array to define the feature configuration */ + uint8_t feat_config[BMI2_FEAT_SIZE_IN_BYTES] = { 0 }; + + /* Variable to define the array offset */ + uint8_t idx = 0; + + /* Variable to set flag */ + uint8_t feat_found; + + /* Initialize feature configuration for wrist wear wake-up */ + struct bmi2_feature_config wrist_wake_up_config = { 0, 0, 0 }; + + /* Copy the feature configuration address to a local pointer */ + uint16_t *data_p = (uint16_t *) (void *)feat_config; + + /* Search for wrist wear wake-up feature and extract its configuration details */ + feat_found = bmi2_extract_input_feat_config(&wrist_wake_up_config, BMI2_WRIST_WEAR_WAKE_UP_WH, dev); + if (feat_found) + { + /* Get the configuration from the page where wrist wear wake-up feature resides */ + rslt = bmi2_get_feat_config(wrist_wake_up_config.page, feat_config, dev); + if (rslt == BMI2_OK) + { + /* Define the offset in bytes for wrist wear wake-up select */ + idx = wrist_wake_up_config.start_addr; + + /* Get offset in words since all the features are set in words length */ + idx = idx / 2; + + config->min_angle_focus = *(data_p + idx); + + /* Increment the offset value by 1 word to get min_angle_nonfocus */ + idx++; + config->min_angle_nonfocus = *(data_p + idx); + + /* Increment the offset value by 1 word to get angle landscape right and angle landscape left */ + idx++; + config->angle_lr = BMI2_GET_BIT_POS0(*(data_p + idx), BMI2_WRIST_WAKE_UP_ANGLE_LR); + config->angle_ll = BMI2_GET_BITS(*(data_p + idx), BMI2_WRIST_WAKE_UP_ANGLE_LL); + + /* Increment the offset value by 1 word to get angle portrait down and angle portrait up */ + idx++; + config->angle_pd = BMI2_GET_BIT_POS0(*(data_p + idx), BMI2_WRIST_WAKE_UP_ANGLE_PD); + config->angle_pu = BMI2_GET_BITS(*(data_p + idx), BMI2_WRIST_WAKE_UP_ANGLE_PU); + + /* Increment the offset value by 1 word to get min duration quite and min duration moved */ + idx++; + config->min_dur_mov = BMI2_GET_BIT_POS0(*(data_p + idx), BMI2_WRIST_WAKE_UP_MIN_DUR_MOVED); + config->min_dur_quite = BMI2_GET_BITS(*(data_p + idx), BMI2_WRIST_WAKE_UP_MIN_DUR_QUITE); + + } + } + else + { + rslt = BMI2_E_INVALID_SENSOR; + } + + return rslt; +} + +/*! + * @brief This internal API gets the output values of step counter. + */ +static int8_t get_step_counter_output(uint32_t *step_count, struct bmi2_dev *dev) +{ + /* Variable to define error */ + int8_t rslt; + + /* Array to define the feature configuration */ + uint8_t feat_config[BMI2_FEAT_SIZE_IN_BYTES] = { 0 }; + + /* Variables to define index */ + uint8_t idx = 0; + + /* Variable to set flag */ + uint8_t feat_found; + + /* Initialize feature output for step counter */ + struct bmi2_feature_config step_cnt_out_config = { 0, 0, 0 }; + + /* Search for step counter output feature and extract its configuration details */ + feat_found = extract_output_feat_config(&step_cnt_out_config, BMI2_STEP_COUNTER, dev); + if (feat_found) + { + /* Get the feature output configuration for step-counter */ + rslt = bmi2_get_feat_config(step_cnt_out_config.page, feat_config, dev); + if (rslt == BMI2_OK) + { + /* Define the offset in bytes for step counter output */ + idx = step_cnt_out_config.start_addr; + + /* Get the step counter output in 4 bytes */ + *step_count = (uint32_t) feat_config[idx++]; + *step_count |= ((uint32_t) feat_config[idx++] << 8); + *step_count |= ((uint32_t) feat_config[idx++] << 16); + *step_count |= ((uint32_t) feat_config[idx++] << 24); + } + } + else + { + rslt = BMI2_E_INVALID_SENSOR; + } + + return rslt; +} + +/*! + * @brief This internal API gets the error status related to NVM. + */ +static int8_t get_nvm_error_status(struct bmi2_nvm_err_status *nvm_err_stat, struct bmi2_dev *dev) +{ + /* Variable to define error */ + int8_t rslt; + + /* Array to define the feature configuration */ + uint8_t feat_config[BMI2_FEAT_SIZE_IN_BYTES] = { 0 }; + + /* Variables to define index */ + uint8_t idx = 0; + + /* Variable to set flag */ + uint8_t feat_found; + + /* Initialize feature output for NVM error status */ + struct bmi2_feature_config nvm_err_cfg = { 0, 0, 0 }; + + /* Search for NVM error status feature and extract its configuration details */ + feat_found = extract_output_feat_config(&nvm_err_cfg, BMI2_NVM_STATUS, dev); + if (feat_found) + { + /* Get the feature output configuration for NVM error status */ + rslt = bmi2_get_feat_config(nvm_err_cfg.page, feat_config, dev); + if (rslt == BMI2_OK) + { + /* Define the offset in bytes for NVM error status */ + idx = nvm_err_cfg.start_addr; + + /* Increment index to get the error status */ + idx++; + + /* Error when NVM load action fails */ + nvm_err_stat->load_error = BMI2_GET_BIT_POS0(feat_config[idx], BMI2_NVM_LOAD_ERR_STATUS); + + /* Error when NVM program action fails */ + nvm_err_stat->prog_error = BMI2_GET_BITS(feat_config[idx], BMI2_NVM_PROG_ERR_STATUS); + + /* Error when NVM erase action fails */ + nvm_err_stat->erase_error = BMI2_GET_BITS(feat_config[idx], BMI2_NVM_ERASE_ERR_STATUS); + + /* Error when NVM program limit is exceeded */ + nvm_err_stat->exceed_error = BMI2_GET_BITS(feat_config[idx], BMI2_NVM_END_EXCEED_STATUS); + + /* Error when NVM privilege mode is not acquired */ + nvm_err_stat->privil_error = BMI2_GET_BITS(feat_config[idx], BMI2_NVM_PRIV_ERR_STATUS); + } + } + else + { + rslt = BMI2_E_INVALID_SENSOR; + } + + return rslt; +} + +/*! + * @brief This internal API is used to get enable status of gyroscope user gain + * update. + */ +static int8_t get_user_gain_upd_status(uint8_t *status, struct bmi2_dev *dev) +{ + /* Variable to define error */ + int8_t rslt = BMI2_OK; + + /* Array to define the feature configuration */ + uint8_t feat_config[BMI2_FEAT_SIZE_IN_BYTES] = { 0 }; + + /* Variable to define the array offset */ + uint8_t idx = 0; + + /* Variable to set flag */ + uint8_t feat_found; + + /* Variable to check APS status */ + uint8_t aps_stat = 0; + + /* Initialize feature configuration for gyroscope user gain */ + struct bmi2_feature_config gyr_user_gain_cfg = { 0, 0, 0 }; + + /* Search for user gain feature and extract its configuration details */ + feat_found = bmi2_extract_input_feat_config(&gyr_user_gain_cfg, BMI2_GYRO_GAIN_UPDATE, dev); + if (feat_found) + { + /* Disable advance power save */ + aps_stat = dev->aps_status; + if (aps_stat == BMI2_ENABLE) + { + rslt = bmi2_set_adv_power_save(BMI2_DISABLE, dev); + } + + if (rslt == BMI2_OK) + { + /* Get the configuration from the page where user gain feature resides */ + rslt = bmi2_get_feat_config(gyr_user_gain_cfg.page, feat_config, dev); + if (rslt == BMI2_OK) + { + /* Define the offset for enable/disable of user gain */ + idx = gyr_user_gain_cfg.start_addr + BMI2_GYR_USER_GAIN_FEAT_EN_OFFSET; + + /* Set the feature enable status */ + *status = BMI2_GET_BITS(feat_config[idx], BMI2_GYR_USER_GAIN_FEAT_EN); + } + } + } + else + { + rslt = BMI2_E_INVALID_SENSOR; + } + + /* Enable Advance power save if disabled while configuring and not when already disabled */ + if ((rslt == BMI2_OK) && (aps_stat == BMI2_ENABLE)) + { + rslt = bmi2_set_adv_power_save(BMI2_ENABLE, dev); + } + + return rslt; +} + +/*! + * @brief This internal API gets the output values of step activity. + */ +static int8_t get_step_activity_output(uint8_t *step_act, struct bmi2_dev *dev) +{ + /* Variable to define error */ + int8_t rslt; + + /* Array to define the feature configuration */ + uint8_t feat_config[BMI2_FEAT_SIZE_IN_BYTES] = { 0 }; + + /* Variables to define index */ + uint8_t idx = 0; + + /* Variable to set flag */ + uint8_t feat_found; + + /* Initialize feature output for step activity */ + struct bmi2_feature_config step_act_out_config = { 0, 0, 0 }; + + /* Search for step activity output feature and extract its configuration details */ + feat_found = extract_output_feat_config(&step_act_out_config, BMI2_STEP_ACTIVITY, dev); + if (feat_found) + { + /* Get the feature output configuration for step-activity */ + rslt = bmi2_get_feat_config(step_act_out_config.page, feat_config, dev); + if (rslt == BMI2_OK) + { + /* Define the offset in bytes for step activity output */ + idx = step_act_out_config.start_addr; + + /* Get the step activity output */ + *step_act = feat_config[idx]; + } + } + else + { + rslt = BMI2_E_INVALID_SENSOR; + } + + return rslt; +} + +/*! + * @brief This internal API gets the error status related to virtual frames. + */ +static int8_t get_vfrm_error_status(struct bmi2_vfrm_err_status *vfrm_err_stat, struct bmi2_dev *dev) +{ + /* Variable to define error */ + int8_t rslt; + + /* Array to define the feature configuration */ + uint8_t feat_config[BMI2_FEAT_SIZE_IN_BYTES] = { 0 }; + + /* Variables to define index */ + uint8_t idx = 0; + + /* Variable to set flag */ + uint8_t feat_found; + + /* Initialize feature output for VFRM error status */ + struct bmi2_feature_config vfrm_err_cfg = { 0, 0, 0 }; + + /* Search for VFRM error status feature and extract its configuration details */ + feat_found = extract_output_feat_config(&vfrm_err_cfg, BMI2_VFRM_STATUS, dev); + if (feat_found) + { + /* Get the feature output configuration for VFRM error status */ + rslt = bmi2_get_feat_config(vfrm_err_cfg.page, feat_config, dev); + if (rslt == BMI2_OK) + { + /* Define the offset in bytes for VFRM error status */ + idx = vfrm_err_cfg.start_addr; + + /* Increment index to get the error status */ + idx++; + + /* Internal error while acquiring lock for FIFO */ + vfrm_err_stat->lock_error = BMI2_GET_BITS(feat_config[idx], BMI2_VFRM_LOCK_ERR_STATUS); + + /* Internal error while writing byte into FIFO */ + vfrm_err_stat->write_error = BMI2_GET_BITS(feat_config[idx], BMI2_VFRM_WRITE_ERR_STATUS); + + /* Internal error while writing into FIFO */ + vfrm_err_stat->fatal_error = BMI2_GET_BITS(feat_config[idx], BMI2_VFRM_FATAL_ERR_STATUS); + } + } + else + { + rslt = BMI2_E_INVALID_SENSOR; + } + + return rslt; +} + +/*! + * @brief This internal API enables/disables compensation of the gain defined + * in the GAIN register. + */ +static int8_t enable_gyro_gain(uint8_t enable, struct bmi2_dev *dev) +{ + /* Variable to define error */ + int8_t rslt; + + /* Variable to define register data */ + uint8_t reg_data = 0; + + rslt = bmi2_get_regs(BMI2_GYR_OFF_COMP_6_ADDR, ®_data, 1, dev); + if (rslt == BMI2_OK) + { + reg_data = BMI2_SET_BITS(reg_data, BMI2_GYR_GAIN_EN, enable); + rslt = bmi2_set_regs(BMI2_GYR_OFF_COMP_6_ADDR, ®_data, 1, dev); + } + + return rslt; +} + +/*! + * @brief This internal API is used to extract the output feature configuration + * details from the look-up table. + */ +static uint8_t extract_output_feat_config(struct bmi2_feature_config *feat_output, + uint8_t type, + const struct bmi2_dev *dev) +{ + /* Variable to define loop */ + uint8_t loop = 0; + + /* Variable to set flag */ + uint8_t feat_found = BMI2_FALSE; + + /* Search for the output feature from the output configuration array */ + while (loop < dev->out_sens) + { + if (dev->feat_output[loop].type == type) + { + *feat_output = dev->feat_output[loop]; + feat_found = BMI2_TRUE; + break; + } + + loop++; + } + + /* Return flag */ + return feat_found; +} diff --git a/bmi270_wh.h b/bmi270_wh.h new file mode 100644 index 0000000..d46251b --- /dev/null +++ b/bmi270_wh.h @@ -0,0 +1,402 @@ +/** +* 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 bmi270_wh.h +* @date 2020-11-04 +* @version v2.63.1 +* +*/ + +/** + * \ingroup bmi2xy + * \defgroup bmi270_wh BMI270_WH + * @brief Sensor driver for BMI270_WH sensor + */ + +#ifndef BMI270_WH_H_ +#define BMI270_WH_H_ + +/*! CPP guard */ +#ifdef __cplusplus +extern "C" { +#endif + +/***************************************************************************/ + +/*! Header files + ****************************************************************************/ +#include "bmi2.h" + +/***************************************************************************/ + +/*! Macro definitions + ****************************************************************************/ + +/*! @name BMI270_WH Chip identifier */ +#define BMI270_WH_CHIP_ID UINT8_C(0x24) + +/*! @name BMI270_WH feature input start addresses */ +#define BMI270_WH_CONFIG_ID_STRT_ADDR UINT8_C(0x00) +#define BMI270_WH_MAX_BURST_LEN_STRT_ADDR UINT8_C(0x02) +#define BMI270_WH_AXIS_MAP_STRT_ADDR UINT8_C(0x04) +#define BMI270_WH_NVM_PROG_PREP_STRT_ADDR UINT8_C(0x05) +#define BMI270_WH_GYRO_GAIN_UPDATE_STRT_ADDR UINT8_C(0x06) +#define BMI270_WH_ANY_MOT_STRT_ADDR UINT8_C(0x0C) +#define BMI270_WH_NO_MOT_STRT_ADDR UINT8_C(0x00) +#define BMI270_WH_STEP_CNT_1_STRT_ADDR UINT8_C(0x00) +#define BMI270_WH_STEP_CNT_4_STRT_ADDR UINT8_C(0x02) +#define BMI270_WH_WRIST_WEAR_WAKE_UP_STRT_ADDR UINT8_C(0x04) + +/*! @name BMI270_WH feature output start addresses */ +#define BMI270_WH_STEP_CNT_OUT_STRT_ADDR UINT8_C(0x00) +#define BMI270_WH_STEP_ACT_OUT_STRT_ADDR UINT8_C(0x04) +#define BMI270_WH_WRIST_GEST_OUT_STRT_ADDR UINT8_C(0x06) +#define BMI270_WH_GYR_USER_GAIN_OUT_STRT_ADDR UINT8_C(0x08) +#define BMI270_WH_GYRO_CROSS_SENSE_STRT_ADDR UINT8_C(0x0C) +#define BMI270_WH_NVM_VFRM_OUT_STRT_ADDR UINT8_C(0x0E) + +/*! @name Defines maximum number of pages */ +#define BMI270_WH_MAX_PAGE_NUM UINT8_C(8) + +/*! @name Defines maximum number of feature input configurations */ +#define BMI270_WH_MAX_FEAT_IN UINT8_C(12) + +/*! @name Defines maximum number of feature outputs */ +#define BMI270_WH_MAX_FEAT_OUT UINT8_C(6) + +/*! @name Mask definitions for feature interrupt status bits */ +#define BMI270_WH_STEP_CNT_STATUS_MASK UINT8_C(0x02) +#define BMI270_WH_STEP_ACT_STATUS_MASK UINT8_C(0x04) +#define BMI270_WH_WRIST_WEAR_WAKEUP_WH_STATUS_MASK UINT8_C(0x08) +#define BMI270_WH_NO_MOT_STATUS_MASK UINT8_C(0x20) +#define BMI270_WH_ANY_MOT_STATUS_MASK UINT8_C(0x40) + +/*! @name Mask definitions for feature interrupt mapping bits */ +#define BMI270_WH_INT_STEP_COUNTER_MASK UINT8_C(0x02) +#define BMI270_WH_INT_STEP_DETECTOR_MASK UINT8_C(0x02) +#define BMI270_WH_INT_STEP_ACT_MASK UINT8_C(0x04) +#define BMI270_WH_INT_WRIST_WEAR_WAKEUP_WH_MASK UINT8_C(0x08) +#define BMI270_WH_INT_NO_MOT_MASK UINT8_C(0x20) +#define BMI270_WH_INT_ANY_MOT_MASK UINT8_C(0x40) + +/*! @name Defines maximum number of feature interrupts */ +#define BMI270_WH_MAX_INT_MAP UINT8_C(6) + +/***************************************************************************/ + +/*! BMI270_WH User Interface function prototypes + ****************************************************************************/ + +/** + * \ingroup bmi270_wh + * \defgroup bmi270_whApiInit Initialization + * @brief Initialize the sensor and device structure + */ + +/*! + * \ingroup bmi270_whApiInit + * \page bmi270_wh_api_bmi270_wh_init bmi270_wh_init + * \code + * int8_t bmi270_wh_init(struct bmi2_dev *dev); + * \endcode + * @details This API: + * 1) updates the device structure with address of the configuration file. + * 2) Initializes BMI270_WH sensor. + * 3) Writes the configuration file. + * 4) Updates the feature offset parameters in the device structure. + * 5) Updates the maximum number of pages, in the device structure. + * + * @param[in, out] dev : Structure instance of bmi2_dev. + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +int8_t bmi270_wh_init(struct bmi2_dev *dev); + +/** + * \ingroup bmi270_wh + * \defgroup bmi270_whApiSensor Feature Set + * @brief Enable / Disable features of the sensor + */ + +/*! + * \ingroup bmi270_whApiSensor + * \page bmi270_wh_api_bmi270_wh_sensor_enable bmi270_wh_sensor_enable + * \code + * int8_t bmi270_wh_sensor_enable(const uint8_t *sens_list, uint8_t n_sens, struct bmi2_dev *dev); + * \endcode + * @details This API selects the sensors/features to be enabled. + * + * @param[in] sens_list : Pointer to select the sensor/feature. + * @param[in] n_sens : Number of sensors selected. + * @param[in, out] dev : Structure instance of bmi2_dev. + * + * @note Sensors/features that can be enabled. + * + *@verbatim + * sens_list | Values + * ----------------------------|----------- + * BMI2_ACCEL | 0 + * BMI2_GYRO | 1 + * BMI2_AUX | 2 + * BMI2_ANY_MOTION | 4 + * BMI2_NO_MOTION | 5 + * BMI2_STEP_DETECTOR | 6 + * BMI2_STEP_COUNTER | 7 + * BMI2_STEP_ACTIVITY | 8 + * BMI2_GYRO_GAIN_UPDATE | 9 + * BMI2_WRIST_WEAR_WAKE_UP_WH | 21 + *@endverbatim + * + * @note : + * example uint8_t sens_list[2] = {BMI2_ACCEL, BMI2_GYRO}; + * uint8_t n_sens = 2; + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +int8_t bmi270_wh_sensor_enable(const uint8_t *sens_list, uint8_t n_sens, struct bmi2_dev *dev); + +/*! + * \ingroup bmi270_whApiSensor + * \page bmi270_wh_api_bmi270_wh_sensor_disable bmi270_wh_sensor_disable + * \code + * int8_t bmi270_wh_sensor_disable(const uint8_t *sens_list, uint8_t n_sens, struct bmi2_dev *dev); + * \endcode + * @details This API selects the sensors/features to be disabled. + * + * @param[in] sens_list : Pointer to select the sensor/feature. + * @param[in] n_sens : Number of sensors selected. + * @param[in, out] dev : Structure instance of bmi2_dev. + * + * @note Sensors/features that can be disabled. + * + *@verbatim + * sens_list | Values + * ----------------------------|----------- + * BMI2_ACCEL | 0 + * BMI2_GYRO | 1 + * BMI2_AUX | 2 + * BMI2_ANY_MOTION | 4 + * BMI2_NO_MOTION | 5 + * BMI2_STEP_DETECTOR | 6 + * BMI2_STEP_COUNTER | 7 + * BMI2_STEP_ACTIVITY | 8 + * BMI2_GYRO_GAIN_UPDATE | 9 + * BMI2_WRIST_WEAR_WAKE_UP_WH | 21 + *@endverbatim + * + * @note : + * example uint8_t sens_list[2] = {BMI2_ACCEL, BMI2_GYRO}; + * uint8_t n_sens = 2; + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +int8_t bmi270_wh_sensor_disable(const uint8_t *sens_list, uint8_t n_sens, struct bmi2_dev *dev); + +/** + * \ingroup bmi270_wh + * \defgroup bmi270_whApiSensorC Sensor Configuration + * @brief Enable / Disable feature configuration of the sensor + */ + +/*! + * \ingroup bmi270_whApiSensorC + * \page bmi270_wh_api_bmi270_wh_set_sensor_config bmi270_wh_set_sensor_config + * \code + * int8_t bmi270_wh_set_sensor_config(struct bmi2_sens_config *sens_cfg, uint8_t n_sens, struct bmi2_dev *dev); + * \endcode + * @details This API sets the sensor/feature configuration. + * + * @param[in] sens_cfg : Structure instance of bmi2_sens_config. + * @param[in] n_sens : Number of sensors selected. + * @param[in, out] dev : Structure instance of bmi2_dev. + * + * @note Sensors/features that can be configured + * + *@verbatim + * sens_list | Values + * ----------------------------|----------- + * BMI2_ANY_MOTION | 4 + * BMI2_NO_MOTION | 5 + * BMI2_STEP_DETECTOR | 6 + * BMI2_STEP_COUNTER | 7 + * BMI2_STEP_ACTIVITY | 8 + * BMI2_WRIST_WEAR_WAKE_UP_WH | 21 + * BMI2_STEP_COUNTER_PARAMS | 28 + *@endverbatim + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +int8_t bmi270_wh_set_sensor_config(struct bmi2_sens_config *sens_cfg, uint8_t n_sens, struct bmi2_dev *dev); + +/*! + * \ingroup bmi270_whApiSensorC + * \page bmi270_wh_api_bmi270_wh_get_sensor_config bmi270_wh_get_sensor_config + * \code + * int8_t bmi270_wh_get_sensor_config(struct bmi2_sens_config *sens_cfg, uint8_t n_sens, struct bmi2_dev *dev); + * \endcode + * @details This API gets the sensor/feature configuration. + * + * @param[in] sens_cfg : Structure instance of bmi2_sens_config. + * @param[in] n_sens : Number of sensors selected. + * @param[in, out] dev : Structure instance of bmi2_dev. + * + * @note Sensors/features whose configurations can be read. + * + *@verbatim + * sens_list | Values + * ----------------------------|----------- + * BMI2_ANY_MOTION | 4 + * BMI2_NO_MOTION | 5 + * BMI2_STEP_DETECTOR | 6 + * BMI2_STEP_COUNTER | 7 + * BMI2_STEP_ACTIVITY | 8 + * BMI2_WRIST_WEAR_WAKE_UP_WH | 21 + * BMI2_STEP_COUNTER_PARAMS | 28 + *@endverbatim + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +int8_t bmi270_wh_get_sensor_config(struct bmi2_sens_config *sens_cfg, uint8_t n_sens, struct bmi2_dev *dev); + +/** + * \ingroup bmi270_wh + * \defgroup bmi270_whApiSensorD Sensor Data + * @brief Get sensor data + */ + +/*! + * \ingroup bmi270_whApiSensorD + * \page bmi270_wh_api_bmi270_wh_get_sensor_data bmi270_wh_get_sensor_data + * \code + * int8_t bmi270_wh_get_sensor_data(struct bmi2_sensor_data *sensor_data, uint8_t n_sens, struct bmi2_dev *dev); + * \endcode + * @details This API gets the sensor/feature data for accelerometer, gyroscope, + * auxiliary sensor, step counter, high-g, gyroscope user-gain update, + * orientation, gyroscope cross sensitivity and error status for NVM and VFRM. + * + * @param[out] sensor_data : Structure instance of bmi2_sensor_data. + * @param[in] n_sens : Number of sensors selected. + * @param[in] dev : Structure instance of bmi2_dev. + * + * @note Sensors/features whose data can be read + * + *@verbatim + * sens_list | Values + * ---------------------|----------- + * BMI2_STEP_COUNTER | 7 + * BMI2_STEP_ACTIVITY | 8 + * BMI2_NVM_STATUS | 38 + * BMI2_VFRM_STATUS | 39 + *@endverbatim + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +int8_t bmi270_wh_get_sensor_data(struct bmi2_sensor_data *sensor_data, uint8_t n_sens, struct bmi2_dev *dev); + +/** + * \ingroup bmi270_wh + * \defgroup bmi270_whApiGyroUG Gyro User Gain + * @brief Set / Get Gyro User Gain of the sensor + */ + +/*! + * \ingroup bmi270_whApiGyroUG + * \page bmi270_wh_api_bmi270_wh_update_gyro_user_gain bmi270_wh_update_gyro_user_gain + * \code + * int8_t bmi270_wh_update_gyro_user_gain(const struct bmi2_gyro_user_gain_config *user_gain, struct bmi2_dev *dev); + * \endcode + * @details This API updates the gyroscope user-gain. + * + * @param[in] user_gain : Structure that stores user-gain configurations. + * @param[in] dev : Structure instance of bmi2_dev. + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +int8_t bmi270_wh_update_gyro_user_gain(const struct bmi2_gyro_user_gain_config *user_gain, struct bmi2_dev *dev); + +/*! + * \ingroup bmi270_whApiGyroUG + * \page bmi270_wh_api_bmi270_wh_read_gyro_user_gain bmi270_wh_read_gyro_user_gain + * \code + * int8_t bmi270_wh_read_gyro_user_gain(struct bmi2_gyro_user_gain_data *gyr_usr_gain, const struct bmi2_dev *dev); + * \endcode + * @details This API reads the compensated gyroscope user-gain values. + * + * @param[out] gyr_usr_gain : Structure that stores gain values. + * @param[in] dev : Structure instance of bmi2_dev. + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +int8_t bmi270_wh_read_gyro_user_gain(struct bmi2_gyro_user_gain_data *gyr_usr_gain, struct bmi2_dev *dev); + +/*! + * \ingroup bmi270_whApiInt + * \page bmi270_wh_api_bmi270_wh_map_feat_int bmi270_wh_map_feat_int + * \code + * int8_t bmi270_wh_map_feat_int(const struct bmi2_sens_int_config *sens_int, uint8_t n_sens, struct bmi2_dev *dev) + * \endcode + * @details This API maps/unmaps feature interrupts to that of interrupt pins. + * + * @param[in] sens_int : Structure instance of bmi2_sens_int_config. + * @param[in] n_sens : Number of interrupts to be mapped. + * @param[in] dev : Structure instance of bmi2_dev. + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +int8_t bmi270_wh_map_feat_int(const struct bmi2_sens_int_config *sens_int, uint8_t n_sens, struct bmi2_dev *dev); + +/******************************************************************************/ +/*! @name C++ Guard Macros */ +/******************************************************************************/ +#ifdef __cplusplus +} +#endif /* End of CPP guard */ + +#endif /* BMI270_WH_H_ */ diff --git a/bmi2_defs.h b/bmi2_defs.h index 34d5d66..08f89d6 100644 --- a/bmi2_defs.h +++ b/bmi2_defs.h @@ -1,40 +1,40 @@ /** - * 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 bmi2_defs.h - * @date 2020-06-05 - * @version v2.53.2 - * - */ +* 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 bmi2_defs.h +* @date 2020-11-04 +* @version v2.63.1 +* +*/ #ifndef BMI2_DEFS_H_ #define BMI2_DEFS_H_ @@ -315,6 +315,14 @@ #define BMI2_ACT_RECG_BUFF_SIZE_MASK UINT8_C(0x0F) #define BMI2_ACT_RECG_MIN_SEG_CONF_MASK UINT8_C(0x0F) +/*! @name mask and bit position for activity recognition hc settings */ +#define BMI2_HC_ACT_RECG_SEGMENT_SIZE_MASK UINT8_C(0x03) +#define BMI2_HC_ACT_RECG_PP_EN_MASK UINT8_C(0x01) +#define BMI2_HC_ACT_RECG_MIN_GDI_THRES_MASK UINT16_C(0xFFFF) +#define BMI2_HC_ACT_RECG_MAX_GDI_THRES_MASK UINT16_C(0xFFFF) +#define BMI2_HC_ACT_RECG_BUF_SIZE_MASK UINT16_C(0xFFFF) +#define BMI2_HC_ACT_RECG_MIN_SEG_CONF_MASK UINT16_C(0xFFFF) + #define BMI2_GYRO_CROSS_AXES_SENSE_MASK UINT8_C(0x7F) #define BMI2_GYRO_CROSS_AXES_SENSE_SIGN_BIT_MASK UINT8_C(0x40) @@ -404,27 +412,28 @@ #define BMI2_SINGLE_TAP UINT8_C(25) #define BMI2_DOUBLE_TAP UINT8_C(26) #define BMI2_TRIPLE_TAP UINT8_C(27) +#define BMI2_TAP UINT8_C(28) /* Non virtual sensor features */ -#define BMI2_STEP_COUNTER_PARAMS UINT8_C(28) -#define BMI2_TAP_DETECTOR_1 UINT8_C(29) -#define BMI2_TAP_DETECTOR_2 UINT8_C(30) -#define BMI2_TEMP UINT8_C(31) -#define BMI2_ACCEL_SELF_TEST UINT8_C(32) -#define BMI2_GYRO_SELF_OFF UINT8_C(33) -#define BMI2_ACTIVITY_RECOGNITION UINT8_C(34) -#define BMI2_MAX_BURST_LEN UINT8_C(35) -#define BMI2_SENS_MAX_NUM UINT8_C(36) -#define BMI2_AXIS_MAP UINT8_C(37) -#define BMI2_NVM_STATUS UINT8_C(38) -#define BMI2_VFRM_STATUS UINT8_C(39) -#define BMI2_GYRO_CROSS_SENSE UINT8_C(40) -#define BMI2_CRT_GYRO_SELF_TEST UINT8_C(41) -#define BMI2_ABORT_CRT_GYRO_SELF_TEST UINT8_C(42) -#define BMI2_NVM_PROG_PREP UINT8_C(43) -#define BMI2_ACTIVITY_RECOGNITION_SETTINGS UINT8_C(44) -#define BMI2_OIS_OUTPUT UINT8_C(45) -#define BMI2_CONFIG_ID UINT8_C(46) +#define BMI2_STEP_COUNTER_PARAMS UINT8_C(29) +#define BMI2_TAP_DETECTOR_1 UINT8_C(30) +#define BMI2_TAP_DETECTOR_2 UINT8_C(31) +#define BMI2_TEMP UINT8_C(32) +#define BMI2_ACCEL_SELF_TEST UINT8_C(33) +#define BMI2_GYRO_SELF_OFF UINT8_C(34) +#define BMI2_ACTIVITY_RECOGNITION UINT8_C(35) +#define BMI2_MAX_BURST_LEN UINT8_C(36) +#define BMI2_SENS_MAX_NUM UINT8_C(37) +#define BMI2_AXIS_MAP UINT8_C(38) +#define BMI2_NVM_STATUS UINT8_C(39) +#define BMI2_VFRM_STATUS UINT8_C(40) +#define BMI2_GYRO_CROSS_SENSE UINT8_C(41) +#define BMI2_CRT_GYRO_SELF_TEST UINT8_C(42) +#define BMI2_ABORT_CRT_GYRO_SELF_TEST UINT8_C(43) +#define BMI2_NVM_PROG_PREP UINT8_C(44) +#define BMI2_ACTIVITY_RECOGNITION_SETTINGS UINT8_C(45) +#define BMI2_OIS_OUTPUT UINT8_C(46) +#define BMI2_CONFIG_ID UINT8_C(47) /*! @name Bit wise for selecting BMI2 sensors/features */ #define BMI2_ACCEL_SENS_SEL (1) @@ -443,6 +452,7 @@ #define BMI2_UP_HOLD_TO_WAKE_SEL (1 << BMI2_UP_HOLD_TO_WAKE) #define BMI2_GLANCE_DET_SEL (1 << BMI2_GLANCE_DETECTOR) #define BMI2_WAKE_UP_SEL (1 << BMI2_WAKE_UP) +#define BMI2_TAP_SEL (1 << BMI2_TAP) #define BMI2_HIGH_G_SEL (1 << BMI2_HIGH_G) #define BMI2_LOW_G_SEL (1 << BMI2_LOW_G) #define BMI2_FLAT_SEL (1 << BMI2_FLAT) @@ -466,7 +476,6 @@ #define BMI2_WAKEUP_DOUBLE_TAP_EN_MASK UINT8_C(0x02) #define BMI2_WAKEUP_TRIPLE_TAP_EN_MASK UINT8_C(0x04) #define BMI2_WAKEUP_DATA_REG_EN_MASK UINT8_C(0x08) -#define BMI2_WAKEUP_OUT_CONF_MASK UINT8_C(0xF0) #define BMI2_WAKEUP_AXIS_SEL_MASK UINT8_C(0x03) /*! @name Bit position definitions for BMI2 wake-up feature configuration for bmi260 */ @@ -474,17 +483,28 @@ #define BMI2_WAKEUP_DOUBLE_TAP_EN_POS UINT8_C(0x01) #define BMI2_WAKEUP_TRIPLE_TAP_EN_POS UINT8_C(0x02) #define BMI2_WAKEUP_DATA_REG_EN_POS UINT8_C(0x03) -#define BMI2_WAKEUP_OUT_CONF_POS UINT8_C(0x04) + +/*! @name Mask definitions for BMI2 tap feature configuration for bmi260t */ +#define BMI2_TAP_SENSITIVITY_MASK UINT8_C(0x0E) +#define BMI2_TAP_SINGLE_TAP_EN_MASK UINT8_C(0x01) +#define BMI2_TAP_DOUBLE_TAP_EN_MASK UINT8_C(0x02) +#define BMI2_TAP_TRIPLE_TAP_EN_MASK UINT8_C(0x04) +#define BMI2_TAP_DATA_REG_EN_MASK UINT8_C(0x08) +#define BMI2_TAP_AXIS_SEL_MASK UINT8_C(0x03) + +/*! @name Bit position definitions for BMI2 tap feature configuration for bmi260t */ +#define BMI2_TAP_SENSITIVITY_POS UINT8_C(0x01) +#define BMI2_TAP_DOUBLE_TAP_EN_POS UINT8_C(0x01) +#define BMI2_TAP_TRIPLE_TAP_EN_POS UINT8_C(0x02) +#define BMI2_TAP_DATA_REG_EN_POS UINT8_C(0x03) /*! @name Mask definitions for BMI2 wake-up feature configuration for other than bmi261 */ #define BMI2_WAKE_UP_SENSITIVITY_MASK UINT16_C(0x000E) #define BMI2_WAKE_UP_SINGLE_TAP_EN_MASK UINT16_C(0x0010) -#define BMI2_WAKE_UP_OUT_CONF_MASK UINT16_C(0x01E0) /*! @name Bit position definitions for BMI2 wake-up feature configuration for other than bmi261 */ #define BMI2_WAKE_UP_SENSITIVITY_POS UINT8_C(0x01) #define BMI2_WAKE_UP_SINGLE_TAP_EN_POS UINT8_C(0x04) -#define BMI2_WAKE_UP_OUT_CONF_POS UINT8_C(0x05) /*! @name Offsets from feature start address for BMI2 feature enable/disable */ #define BMI2_ANY_MOT_FEAT_EN_OFFSET UINT8_C(0x03) @@ -508,6 +528,7 @@ #define BMI2_UP_HOLD_TO_WAKE_FEAT_EN_MASK UINT8_C(0x01) #define BMI2_GLANCE_FEAT_EN_MASK UINT8_C(0x01) #define BMI2_WAKE_UP_FEAT_EN_MASK UINT8_C(0x01) +#define BMI2_TAP_FEAT_EN_MASK UINT8_C(0x01) #define BMI2_HIGH_G_FEAT_EN_MASK UINT8_C(0x80) #define BMI2_LOW_G_FEAT_EN_MASK UINT8_C(0x10) #define BMI2_FLAT_FEAT_EN_MASK UINT8_C(0x01) @@ -521,6 +542,7 @@ #define BMI2_ABORT_FEATURE_EN_MASK UINT8_C(0x02) #define BMI2_NVM_PREP_FEATURE_EN_MASK UINT8_C(0x04) #define BMI2_FREE_FALL_DET_FEAT_EN_MASK UINT8_C(0x01) +#define BMI2_WRIST_GEST_WH_FEAT_EN_MASK UINT8_C(0x02) /*! @name Bit position definitions for BMI2 feature enable/disable */ #define BMI2_ANY_NO_MOT_EN_POS UINT8_C(0x07) @@ -536,6 +558,7 @@ #define BMI2_ACC_SELF_TEST_FEAT_EN_POS UINT8_C(0x01) #define BMI2_ABORT_FEATURE_EN_POS UINT8_C(0x1) #define BMI2_NVM_PREP_FEATURE_EN_POS UINT8_C(0x02) +#define BMI2_WRIST_GEST_WH_FEAT_EN_POS UINT8_C(0x01) /*! Primary OIS low pass filter configuration position and mask */ #define BMI2_LP_FILTER_EN_MASK UINT8_C(0x01) @@ -555,7 +578,10 @@ #define BMI2_ANY_NO_MOT_Y_SEL_MASK UINT16_C(0x4000) #define BMI2_ANY_NO_MOT_Z_SEL_MASK UINT16_C(0x8000) #define BMI2_ANY_NO_MOT_THRES_MASK UINT16_C(0x07FF) -#define BMI2_ANY_NO_MOT_OUT_CONF_MASK UINT16_C(0x7800) +#define BMI2_ANY_MOT_INT_MASK UINT8_C(0x40) + +/*! @name Mask definitions for BMI2 no-motion interrupt mapping */ +#define BMI2_NO_MOT_INT_MASK UINT8_C(0x20) /*! @name Bit position definitions for BMI2 any and no-motion feature * configuration @@ -563,13 +589,6 @@ #define BMI2_ANY_NO_MOT_X_SEL_POS UINT8_C(0x0D) #define BMI2_ANY_NO_MOT_Y_SEL_POS UINT8_C(0x0E) #define BMI2_ANY_NO_MOT_Z_SEL_POS UINT8_C(0x0F) -#define BMI2_ANY_NO_MOT_OUT_CONF_POS UINT8_C(0x0B) - -/*! @name Mask definitions for BMI2 tilt feature configuration */ -#define BMI2_TILT_OUT_CONF_MASK UINT16_C(0x001E) - -/*! @name Bit position definitions for BMI2 tilt feature configuration */ -#define BMI2_TILT_OUT_CONF_POS UINT8_C(0x01) /*! @name Mask definitions for BMI2 orientation feature configuration */ #define BMI2_ORIENT_UP_DOWN_MASK UINT16_C(0x0002) @@ -577,14 +596,12 @@ #define BMI2_ORIENT_BLOCK_MODE_MASK UINT16_C(0x0030) #define BMI2_ORIENT_THETA_MASK UINT16_C(0x0FC0) #define BMI2_ORIENT_HYST_MASK UINT16_C(0x07FF) -#define BMI2_ORIENT_OUT_CONF_MASK UINT16_C(0x7800) /*! @name Bit position definitions for BMI2 orientation feature configuration */ #define BMI2_ORIENT_UP_DOWN_POS UINT8_C(0x01) #define BMI2_ORIENT_SYMM_MODE_POS UINT8_C(0x02) #define BMI2_ORIENT_BLOCK_MODE_POS UINT8_C(0x04) #define BMI2_ORIENT_THETA_POS UINT8_C(0x06) -#define BMI2_ORIENT_OUT_CONF_POS UINT8_C(0x0B) /*! @name Mask definitions for BMI2 sig-motion feature configuration */ #define BMI2_SIG_MOT_PARAM_1_MASK UINT16_C(0xFFFF) @@ -592,10 +609,6 @@ #define BMI2_SIG_MOT_PARAM_3_MASK UINT16_C(0xFFFF) #define BMI2_SIG_MOT_PARAM_4_MASK UINT16_C(0xFFFF) #define BMI2_SIG_MOT_PARAM_5_MASK UINT16_C(0xFFFF) -#define BMI2_SIG_MOT_OUT_CONF_MASK UINT16_C(0x001E) - -/*! @name Bit position definitions for BMI2 sig-motion feature configuration */ -#define BMI2_SIG_MOT_OUT_CONF_POS UINT8_C(0x01) /*! @name Mask definitions for BMI2 parameter configurations */ #define BMI2_STEP_COUNT_PARAMS_MASK UINT16_C(0xFFFF) @@ -603,15 +616,14 @@ /*! @name Mask definitions for BMI2 step-counter/detector feature configuration */ #define BMI2_STEP_COUNT_WM_LEVEL_MASK UINT16_C(0x03FF) #define BMI2_STEP_COUNT_RST_CNT_MASK UINT16_C(0x0400) -#define BMI2_STEP_DET_OUT_CONF_MASK UINT16_C(0x000F) -#define BMI2_STEP_ACT_OUT_CONF_MASK UINT16_C(0x00F0) #define BMI2_STEP_BUFFER_SIZE_MASK UINT16_C(0XFF00) +#define BMI2_STEP_COUNT_INT_MASK UINT8_C(0x02) +#define BMI2_STEP_ACT_INT_MASK UINT8_C(0x04) /*! @name Bit position definitions for BMI2 step-counter/detector feature * configuration */ #define BMI2_STEP_COUNT_RST_CNT_POS UINT8_C(0x0A) -#define BMI2_STEP_ACT_OUT_CONF_POS UINT8_C(0x04) #define BMI2_STEP_BUFFER_SIZE_POS UINT8_C(0X08) /*! @name Mask definitions for BMI2 gyroscope user gain feature @@ -682,20 +694,6 @@ #define BMI2_ACC_Y_OK_POS UINT8_C(0x02) #define BMI2_ACC_Z_OK_POS UINT8_C(0x03) -/*! @name Mask definitions for BMI2 uphold to wake feature configuration */ -#define BMI2_UP_HOLD_TO_WAKE_OUT_CONF_MASK UINT16_C(0x001E) - -/*! @name Bit position definitions for BMI2 uphold to wake feature configuration */ -#define BMI2_UP_HOLD_TO_WAKE_OUT_CONF_POS UINT8_C(0x01) - -/*! @name Mask definitions for BMI2 glance detector feature configuration */ -#define BMI2_GLANCE_DET_OUT_CONF_MASK UINT16_C(0x001E) - -/*! @name Bit position definitions for BMI2 glance detector feature - * configuration - */ -#define BMI2_GLANCE_DET_OUT_CONF_POS UINT8_C(0x01) - /*! @name Mask definitions for BMI2 high-g feature configuration */ #define BMI2_HIGH_G_THRES_MASK UINT16_C(0x7FFF) #define BMI2_HIGH_G_HYST_MASK UINT16_C(0x0FFF) @@ -703,10 +701,8 @@ #define BMI2_HIGH_G_Y_SEL_MASK UINT16_C(0x2000) #define BMI2_HIGH_G_Z_SEL_MASK UINT16_C(0x4000) #define BMI2_HIGH_G_DUR_MASK UINT16_C(0x0FFF) -#define BMI2_HIGH_G_OUT_CONF_MASK UINT16_C(0xF000) /*! @name Bit position definitions for BMI2 high-g feature configuration */ -#define BMI2_HIGH_G_OUT_CONF_POS UINT8_C(0x0C) #define BMI2_HIGH_G_X_SEL_POS UINT8_C(0x0C) #define BMI2_HIGH_G_Y_SEL_POS UINT8_C(0x0D) #define BMI2_HIGH_G_Z_SEL_POS UINT8_C(0x0E) @@ -715,46 +711,34 @@ #define BMI2_LOW_G_THRES_MASK UINT16_C(0x7FFF) #define BMI2_LOW_G_HYST_MASK UINT16_C(0x0FFF) #define BMI2_LOW_G_DUR_MASK UINT16_C(0x0FFF) -#define BMI2_LOW_G_OUT_CONF_MASK UINT16_C(0xF000) /*! @name Mask definitions for BMI2 free-fall detection feature configuration */ -#define BMI2_FREE_FALL_OUT_CONF_MASK UINT16_C(0x001E) #define BMI2_FREE_FALL_ACCEL_SETT_MASK UINT16_C(0xFFFF) -/*! @name Bit position definitions for BMI2 free-fall detection feature configuration */ -#define BMI2_FREE_FALL_OUT_CONF_POS UINT8_C(0x01) - -/*! @name Bit position definitions for BMI2 low-g feature configuration */ -#define BMI2_LOW_G_OUT_CONF_POS UINT8_C(0x0C) - /*! @name Mask definitions for BMI2 flat feature configuration */ #define BMI2_FLAT_THETA_MASK UINT16_C(0x007E) #define BMI2_FLAT_BLOCK_MASK UINT16_C(0x0180) -#define BMI2_FLAT_OUT_CONF_MASK UINT16_C(0x1E00) #define BMI2_FLAT_HYST_MASK UINT16_C(0x003F) #define BMI2_FLAT_HOLD_TIME_MASK UINT16_C(0x3FC0) /*! @name Bit position definitions for BMI2 flat feature configuration */ #define BMI2_FLAT_THETA_POS UINT8_C(0x01) #define BMI2_FLAT_BLOCK_POS UINT8_C(0x07) -#define BMI2_FLAT_OUT_CONF_POS UINT8_C(0x09) #define BMI2_FLAT_HOLD_TIME_POS UINT8_C(0x06) -/*! @name Mask definitions for BMI2 external sensor sync configuration */ -#define BMI2_EXT_SENS_SYNC_OUT_CONF_MASK UINT16_C(0x001E) - -/*! @name Bit position definitions for external sensor sync configuration */ -#define BMI2_EXT_SENS_SYNC_OUT_CONF_POS UINT8_C(0x01) - /*! @name Mask definitions for BMI2 wrist gesture configuration */ #define BMI2_WRIST_GEST_WEAR_ARM_MASK UINT16_C(0x0010) -#define BMI2_WRIST_GEST_OUT_CONF_MASK UINT16_C(0x000F) /*! @name Bit position definitions for wrist gesture configuration */ #define BMI2_WRIST_GEST_WEAR_ARM_POS UINT8_C(0x04) +/*! @name Mask definitions for BMI2 wrist gesture wh configuration */ +#define BMI2_WRIST_GEST_WH_DEVICE_POS_MASK UINT16_C(0x0001) +#define BMI2_WRIST_GEST_WH_INT UINT8_C(0x10) +#define BMI2_WRIST_GEST_WH_START_ADD UINT8_C(0x08) + /*! @name Mask definitions for BMI2 wrist wear wake-up configuration */ -#define BMI2_WRIST_WAKE_UP_OUT_CONF_MASK UINT16_C(0x000F) +#define BMI2_WRIST_WAKE_UP_WH_INT_MASK UINT8_C(0x08) /*! @name Mask definition for BMI2 wrist wear wake-up configuration for wearable variant */ #define BMI2_WRIST_WAKE_UP_ANGLE_LR_MASK UINT16_C(0x00FF) @@ -1275,16 +1259,6 @@ #define BMI2_ASDA_PUPSEL_10K UINT8_C(0x02) #define BMI2_ASDA_PUPSEL_2K UINT8_C(0x03) -/******************************************************************************/ -/*! @name CHIP ID MACROS */ -/******************************************************************************/ - -/*! @name BMI260 chip identifier */ -#define BMI260_CHIP_IDENTIFIER UINT8_C(0x27) - -/*! @name BMI261 chip identifier */ -#define BMI261_CHIP_IDENTIFIER UINT8_C(0x21) - /******************************************************************************/ /*! @name Function Pointers */ /******************************************************************************/ @@ -1350,6 +1324,22 @@ typedef void (*bmi2_delay_fptr_t)(uint32_t period, void *intf_ptr); */ typedef int8_t (*bmi2_wake_up_fptr_t)(void *wake_up, void *bmi2_dev); +/*! + * @brief To get the configurations for tap feature. + * + * @param[out] tap : Void pointer to store bmi2_tap_config structure. + * @param[in, out] bmi2_dev : Void pointer to store bmi2_dev structure. + * + * @return Result of API execution status + * + * @retval BMI2_OK - Success. + * @retval BMI2_E_COM_FAIL - Error: Communication fail + * @retval BMI2_E_NULL_PTR - Error: Null pointer error + * @retval BMI2_E_INVALID_PAGE - Error: Invalid Page + * + */ +typedef int8_t (*bmi2_tap_fptr_t)(void *tap, void *bmi2_dev); + /******************************************************************************/ /*! @name Enum Declarations */ /******************************************************************************/ @@ -1463,61 +1453,6 @@ struct bmi2_sens_int_config enum bmi2_hw_int_pin hw_int_pin; }; -/*! @name Structure to define the output configuration value of features */ -struct bmi2_int_map -{ - /*! Output configuration value of sig-motion */ - uint8_t sig_mot_out_conf; - - /*! Output configuration value of any-motion */ - uint8_t any_mot_out_conf; - - /*! Output configuration value of no-motion */ - uint8_t no_mot_out_conf; - - /*! Output configuration value of step-detector */ - uint8_t step_det_out_conf; - - /*! Output configuration value of step-activity */ - uint8_t step_act_out_conf; - - /*! Output configuration value of tilt */ - uint8_t tilt_out_conf; - - /*! Output configuration value of uphold to wake */ - uint8_t up_hold_to_wake_out_conf; - - /*! Output configuration value of glance */ - uint8_t glance_out_conf; - - /*! Output configuration value of wake-up */ - uint8_t wake_up_out_conf; - - /*! Output configuration value of orientation */ - uint8_t orient_out_conf; - - /*! Output configuration value of high-g */ - uint8_t high_g_out_conf; - - /*! Output configuration value of low-g */ - uint8_t low_g_out_conf; - - /*! Output configuration value of flat */ - uint8_t flat_out_conf; - - /*! Output configuration value of S4S */ - uint8_t ext_sync_out_conf; - - /*! Output configuration value of wrist gesture */ - uint8_t wrist_gest_out_conf; - - /*! Output configuration value of wrist wear wake-up */ - uint8_t wrist_wear_wake_up_out_conf; - - /*! Output configuration value of free-fall detection */ - uint8_t freefall_out_conf; -}; - /*! @name Structure to define output for activity recognition */ struct bmi2_act_recog_output { @@ -1905,9 +1840,6 @@ struct bmi2_any_motion_config /*! To select per z-axis */ uint16_t select_z; - - /*! Enable bits for enabling output into the register status bits */ - uint16_t out_conf; }; /*! @name Structure to define no-motion configuration */ @@ -1927,9 +1859,6 @@ struct bmi2_no_motion_config /*! To select per z-axis */ uint16_t select_z; - - /*! Enable bits for enabling output into the register status bits */ - uint16_t out_conf; }; /*! @name Structure to define sig-motion configuration */ @@ -1949,9 +1878,6 @@ struct bmi2_sig_motion_config /*! Parameter 5 */ uint16_t param_5; - - /*! Enable bits for enabling output into the register status bits */ - uint16_t out_conf; }; /*! @name Structure to define step counter/detector/activity configuration */ @@ -1963,15 +1889,7 @@ struct bmi2_step_config /*! Reset counter */ uint16_t reset_counter; - /*! Enable bits for enabling output into the register status bits - * for step-detector - */ - uint16_t out_conf_step_detector; - - /*! Enable bits for enabling output into the register status bits - * for step-activity - */ - uint16_t out_conf_activity; + /*! Step buffer size */ uint8_t step_buffer_size; }; @@ -1988,27 +1906,6 @@ struct bmi2_gyro_user_gain_config uint16_t ratio_z; }; -/*! @name Structure to define tilt configuration */ -struct bmi2_tilt_config -{ - /*! Enable bits for enabling output into the register status bits */ - uint16_t out_conf; -}; - -/*! @name Structure to define uphold to wake configuration */ -struct bmi2_up_hold_to_wake_config -{ - /*! Enable bits for enabling output into the register status bits */ - uint16_t out_conf; -}; - -/*! @name Structure to define glance detector configuration */ -struct bmi2_glance_det_config -{ - /*! Enable bits for enabling output into the register status bits */ - uint16_t out_conf; -}; - /*! @name Structure to define wake-up configuration */ struct bmi2_wake_up_config { @@ -2038,9 +1935,37 @@ struct bmi2_wake_up_config /*! Axis selection */ uint16_t axis_sel; +}; + +/*! @name Structure to define tap configuration */ +struct bmi2_tap_config +{ + /*! Tap sensitivity */ + uint16_t sensitivity; + + /*! Tap feature. + * For Single tap, single_tap_en = 1 + * For Double tap, single_tap_en = 0 + */ + uint16_t single_tap_en; - /*! Enable bits for enabling output into the register status bits for bmi260 and bmi261 */ - uint16_t out_conf; + /*! Enable -> Filtered tap data, Disable -> Unfiltered data */ + uint16_t data_reg_en; + + /*! Scaling factor of threshold */ + uint16_t tap_sens_thres; + + /*! Maximum duration between each taps */ + uint16_t max_gest_dur; + + /*! Minimum quite time between the two gesture detection */ + uint16_t quite_time_after_gest; + + /*! Wait time */ + uint16_t wait_for_timeout; + + /*! Axis selection */ + uint16_t axis_sel; }; /*! @name Structure to define orientation configuration */ @@ -2060,9 +1985,6 @@ struct bmi2_orient_config /*! Acceleration hysteresis for orientation detection */ uint16_t hysteresis; - - /*! Enable bits for enabling output into the register status bits */ - uint16_t out_conf; }; /*! @name Structure to define high-g configuration */ @@ -2085,9 +2007,6 @@ struct bmi2_high_g_config /*! Duration interval */ uint16_t duration; - - /*! Enable bits for enabling output into the register status bits */ - uint16_t out_conf; }; /*! @name Structure to define low-g configuration */ @@ -2101,10 +2020,6 @@ struct bmi2_low_g_config /*! Duration interval */ uint16_t duration; - - /*! Enable bits for enabling output into the register status bits */ - uint16_t out_conf; - }; /*! @name Structure to define flat configuration */ @@ -2121,16 +2036,6 @@ struct bmi2_flat_config /*! Holds the duration in 50Hz samples(20msec) */ uint16_t hold_time; - - /*! Enable bits for enabling output into the register status bits */ - uint16_t out_conf; -}; - -/*! @name Structure to define external sensor sync configuration */ -struct bmi2_ext_sens_sync_config -{ - /*! Enable bits for enabling output into the register status bits */ - uint16_t out_conf; }; /*! @name Structure to define wrist gesture configuration */ @@ -2139,9 +2044,6 @@ struct bmi2_wrist_gest_config /*! Wearable arm (left or right) */ uint16_t wearable_arm; - /*! Enable bits for enabling output into the register status bits */ - uint16_t out_conf; - /*! Sine of the minimum tilt angle in portrait down direction of the device when wrist is rolled * away from user. The configuration parameter is scaled by 2048 i.e. 2048 * sin(angle). * Range is 1448 to 1774. Default value is 1774. */ @@ -2159,9 +2061,6 @@ struct bmi2_wrist_gest_config /*! @name Structure to define wrist wear wake-up configuration */ struct bmi2_wrist_wear_wake_up_config { - /*! Enable bits for enabling output into the register status bits */ - uint16_t out_conf; - /*! Cosine of min expected attitude change of the device within 1 second time window when * moving within focus position. * The parameter is scaled by 2048 i.e. 2048 * cos(angle). Range is 1024 to 1774. @@ -2207,36 +2106,43 @@ struct bmi2_wrist_wear_wake_up_config struct bmi2_wrist_gest_w_config { /*! Wearable arm (left or right) */ - uint8_t wearable_arm : 1; + uint8_t device_position; - /*! Enable bits for enabling output into the register status bits */ - uint8_t out_conf : 4; + /*! Minimum threshold for flick peak on y-axis */ + uint16_t min_flick_peak_y_threshold; - /*! Sine of the minimum tilt angle in portrait down direction of the device when wrist is rolled - * away from user. The configuration parameter is scaled by 2048 i.e. 2048 * sin(angle). - * Range is 1448 to 1774. Default value is 1774. */ - uint16_t min_flick_peak; + /*! Minimum threshold for flick peak on z-axis */ + uint16_t min_flick_peak_z_threshold; - /*! Value of minimum time difference between wrist roll-out and roll-in movement during flick gesture. - * Range is 3 to 5 samples at 50Hz. Default value is 4 (i.e. 0.08 seconds). */ - uint16_t min_flick_samples; + /*! Maximum expected value of positive gravitational acceleration on x-axis + * when arm is in focus pose */ + uint16_t gravity_bounds_x_pos; - /*! Maximum time within which gesture movement has to be completed. Range is 150 to 250 samples at 50Hz. - * Default value is 200 (i.e. 4 seconds). */ - uint16_t max_duration; + /*! Maximum expected value of negative gravitational acceleration on x-axis + * when arm is in focus pose */ + uint16_t gravity_bounds_x_neg; - /*! Defines the Wait time between the detection of the wrist gesture and reporting the wrist gesture. - * The sample resolution is 20ms. The default value is 25 which is equal to reporting delay 500ms . - */ - uint16_t reporting_delay; + /*! Maximum expected value of negative gravitational acceleration on y-axis + * when arm is in focus pose */ + uint16_t gravity_bounds_y_neg; + + /*! Maximum expected value of negative gravitational acceleration on z-axis + * when arm is in focus pose */ + uint16_t gravity_bounds_z_neg; + + /*! Exponential smoothing coefficient for adaptive peak threshold decay */ + uint16_t flick_peak_decay_coeff; + + /*! Exponential smoothing coefficient for acceleration mean estimation */ + uint16_t lp_mean_filter_coeff; + + /*! Maximum duration between 2 peaks of jiggle in samples @50Hz */ + uint16_t max_duration_jiggle_peaks; }; /*! @name Structure to define wrist wear wake-up configuration for wearable configuration */ struct bmi2_wrist_wear_wake_up_wh_config { - /*! Enable bits for enabling output into the register status bits */ - uint16_t out_conf; - /*! Cosine of min expected attitude change of the device within 1 second time window when * moving within focus position. * The parameter is scaled by 2048 i.e. 2048 * cos(angle). Range is 1024 to 1774. @@ -2301,9 +2207,6 @@ struct bmi2_primary_ois_config /*! @name Structure to configure free-fall detection settings */ struct bmi2_free_fall_det_config { - /*! Enable bits for enabling output into the register status bits */ - uint16_t out_conf; - /*! free-fall accel settings */ uint16_t freefall_accel_settings[BMI2_FREE_FALL_ACCEL_SET_PARAMS]; }; @@ -2338,18 +2241,12 @@ union bmi2_sens_config_types /*! Gyroscope user gain configuration */ struct bmi2_gyro_user_gain_config gyro_gain_update; - /*! Tilt configuration */ - struct bmi2_tilt_config tilt; - - /*! uphold to wake configuration */ - struct bmi2_up_hold_to_wake_config up_hold_to_wake; - - /*! Glance detector configuration */ - struct bmi2_glance_det_config glance_det; - /*! Wake-up configuration */ struct bmi2_wake_up_config tap; + /*! Tap configuration */ + struct bmi2_tap_config tap_conf; + /*! Orientation configuration */ struct bmi2_orient_config orientation; @@ -2362,9 +2259,6 @@ union bmi2_sens_config_types /*! Flat configuration */ struct bmi2_flat_config flat; - /*! External sensor sync configuration */ - struct bmi2_ext_sens_sync_config ext_sens_sync; - /*! Wrist gesture configuration */ struct bmi2_wrist_gest_config wrist_gest; @@ -2407,6 +2301,16 @@ struct bmi2_feature_config uint8_t start_addr; }; +/*! @name Structure to define the feature interrupt configurations */ +struct bmi2_map_int +{ + /*! Defines the type of sensor */ + uint8_t type; + + /*! Defines the feature interrupt */ + uint8_t sens_map_int; +}; + /*! @name Structure to define BMI2 sensor configurations */ struct bmi2_dev { @@ -2462,9 +2366,6 @@ struct bmi2_dev /*! Array of feature output configuration structure */ const struct bmi2_feature_config *feat_output; - /*! Structure to maintain a copy of feature out_conf values */ - struct bmi2_int_map int_map; - /*! Structure to maintain a copy of the re-mapped axis */ struct bmi2_axes_remap remap; @@ -2500,37 +2401,75 @@ struct bmi2_dev /*! Function pointer to set wakeup configurations */ bmi2_wake_up_fptr_t set_wakeup_config; + + /*! Function pointer to get tap configurations */ + bmi2_tap_fptr_t get_tap_config; + + /*! Function pointer to set tap configurations */ + bmi2_tap_fptr_t set_tap_config; + + /*! Array of feature interrupts configuration structure */ + struct bmi2_map_int *map_int; + + /*! To define maximum number of interrupts */ + uint8_t sens_int_map; }; /*! @name Structure to enable an accel axis for foc */ struct bmi2_accel_foc_g_value { - /* '0' to disable x axis and '1' to enable x axis */ + /*! '0' to disable x axis and '1' to enable x axis */ uint8_t x; - /* '0' to disable y axis and '1' to enable y axis */ + /*! '0' to disable y axis and '1' to enable y axis */ uint8_t y; - /* '0' to disable z axis and '1' to enable z axis */ + /*! '0' to disable z axis and '1' to enable z axis */ uint8_t z; - /* '0' for positive input and '1' for negative input */ + /*! '0' for positive input and '1' for negative input */ uint8_t sign; }; /*! @name Structure to configure activity recognition settings */ struct bmi2_act_recg_sett { - /* 1 to enable & 0 to disable post processing */ + /*! Activity recognition register 1 */ uint8_t act_rec_1 : 1; + /*! Activity recognition register 2 */ uint16_t act_rec_2; + /*! Activity recognition register 3 */ uint16_t act_rec_3; + /*! Activity recognition register 4 */ uint8_t act_rec_4 : 4; + /*! Activity recognition register 5 */ uint8_t act_rec_5 : 4; }; +/*! @name Structure to configure activity recognition settings for bmi270hc */ +struct bmi2_hc_act_recg_sett +{ + /*! Static segment size for activity classification. */ + uint8_t segment_size; + + /*! Enable/Disable post processing of the activity detected */ + uint8_t pp_en; + + /*! Minimum threshold of the Gini's diversity index (GDI) */ + uint16_t min_gdi_thres; + + /*! Maximum threshold of the Gini's diversity index (GDI) */ + uint16_t max_gdi_thres; + + /*! Buffer size for post processing of the activity detected */ + uint16_t buf_size; + + /*! Minimum segments belonging to a certain activity type */ + uint16_t min_seg_conf; +}; + #endif /* BMI2_DEFS_H_ */ diff --git a/bmi2_ois.c b/bmi2_ois.c index dd318c0..80b14f4 100644 --- a/bmi2_ois.c +++ b/bmi2_ois.c @@ -32,7 +32,7 @@ * * @file bmi2_ois.c * @date 2020-05-05 - * @version v2.53.2 + * @version v2.23.2 * */ @@ -57,7 +57,8 @@ * bmi2xy_init(), refer the example ois_accel_gyro.c for more info" * * @return Result of API execution status - * @retval zero -> Success / +ve value -> Warning / -ve value -> Error + * @retval 0 -> Success + * @retval < 0 -> Fail */ static int8_t get_ois_acc_gyr_data(struct bmi2_ois_sens_axes_data *ois_data, uint8_t reg_addr, @@ -71,7 +72,8 @@ static int8_t get_ois_acc_gyr_data(struct bmi2_ois_sens_axes_data *ois_data, * @param[in] ois_dev : Structure instance of bmi2_ois_dev. * * @return Result of API execution status - * @retval zero -> Success / +ve value -> Warning / -ve value -> Error + * @retval 0 -> Success + * @retval < 0 -> Fail */ static int8_t null_ptr_check(const struct bmi2_ois_dev *ois_dev); diff --git a/bmi2_ois.h b/bmi2_ois.h index 443d4dc..770d7c2 100644 --- a/bmi2_ois.h +++ b/bmi2_ois.h @@ -32,7 +32,7 @@ * * @file bmi2_ois.h * @date 2020-05-05 - * @version v2.53.2 + * @version v2.23.2 * */ @@ -268,8 +268,8 @@ struct bmi2_ois_dev * @param[in] ois_dev : Structure instance of bmi2_ois_dev. * * @return Result of API execution status - * @retval Zero Success - * @retval Negative Error + * @retval 0 -> Success + * @retval < 0 -> Fail */ int8_t bmi2_ois_get_regs(uint8_t ois_reg_addr, uint8_t *ois_reg_data, uint16_t data_len, struct bmi2_ois_dev *ois_dev); @@ -291,8 +291,8 @@ int8_t bmi2_ois_get_regs(uint8_t ois_reg_addr, uint8_t *ois_reg_data, uint16_t d * @param[in] ois_dev : Structure instance of bmi2_ois_dev. * * @return Result of API execution status - * @retval Zero Success - * @retval Negative Error + * @retval 0 -> Success + * @retval < 0 -> Fail */ int8_t bmi2_ois_set_regs(uint8_t ois_reg_addr, const uint8_t *ois_reg_data, @@ -317,8 +317,8 @@ int8_t bmi2_ois_set_regs(uint8_t ois_reg_addr, * @param[in] ois_dev : Structure instance of bmi2_ois_dev. * * @return Result of API execution status - * @retval Zero Success - * @retval Negative Error + * @retval 0 -> Success + * @retval < 0 -> Fail */ int8_t bmi2_ois_set_config(struct bmi2_ois_dev *ois_dev); @@ -336,8 +336,8 @@ int8_t bmi2_ois_set_config(struct bmi2_ois_dev *ois_dev); * @note Enabling and disabling is done during OIS structure initialization. * * @return Result of API execution status - * @retval Zero Success - * @retval Negative Error + * @retval 0 -> Success + * @retval < 0 -> Fail */ int8_t bmi2_ois_get_config(struct bmi2_ois_dev *ois_dev); @@ -372,8 +372,8 @@ int8_t bmi2_ois_get_config(struct bmi2_ois_dev *ois_dev); *@endverbatim * * @return Result of API execution status - * @retval Zero Success - * @retval Negative Error + * @retval 0 -> Success + * @retval < 0 -> Fail */ int8_t bmi2_ois_read_data(const uint8_t *sens_sel, uint8_t n_sens, diff --git a/examples/bmi270/accel/Makefile b/examples/bmi270/accel/Makefile new file mode 100644 index 0000000..c63d602 --- /dev/null +++ b/examples/bmi270/accel/Makefile @@ -0,0 +1,18 @@ +COINES_INSTALL_PATH ?= ../../../.. + +EXAMPLE_FILE ?= accel.c + +API_LOCATION ?= ../.. + +COMMON_LOCATION ?= .. + +C_SRCS += \ +$(API_LOCATION)/bmi2.c \ +$(API_LOCATION)/bmi270.c \ +$(COMMON_LOCATION)/common/common.c + +INCLUDEPATHS += \ +$(API_LOCATION) \ +$(COMMON_LOCATION)/common + +include $(COINES_INSTALL_PATH)/coines.mk \ No newline at end of file diff --git a/examples/bmi270/accel/accel.c b/examples/bmi270/accel/accel.c new file mode 100644 index 0000000..ea385d7 --- /dev/null +++ b/examples/bmi270/accel/accel.c @@ -0,0 +1,200 @@ +/**\ + * Copyright (c) 2020 Bosch Sensortec GmbH. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + **/ + +/******************************************************************************/ +/*! Header Files */ +#include +#include "bmi270.h" +#include "common.h" + +/******************************************************************************/ +/*! Macro definition */ + +/*! Earth's gravity in m/s^2 */ +#define GRAVITY_EARTH (9.80665f) + +/******************************************************************************/ +/*! Static Function Declaration */ + +/*! + * @brief This internal API is used to set configurations for accel. + * + * @param[in] dev : Structure instance of bmi2_dev. + * + * @return Status of execution. + */ +static int8_t set_accel_config(struct bmi2_dev *bmi2_dev); + +/*! + * @brief This function converts lsb to meter per second squared for 16 bit accelerometer at + * range 2G, 4G, 8G or 16G. + * + * @param[in] val : LSB from each axis. + * @param[in] g_range : Gravity range. + * @param[in] bit_width : Resolution for accel. + * + * @return Gravity. + */ +static float lsb_to_mps2(int16_t val, float g_range, uint8_t bit_width); + +/******************************************************************************/ +/*! Functions */ + +/* This function starts the execution of program. */ +int main(void) +{ + /* Status of api are returned to this variable. */ + int8_t rslt; + + /* Variable to define limit to print accel data. */ + uint8_t limit = 20; + + /* Assign accel sensor to variable. */ + uint8_t sensor_list = BMI2_ACCEL; + + /* Sensor initialization configuration. */ + struct bmi2_dev bmi2_dev; + + /* Create an instance of sensor data structure. */ + struct bmi2_sensor_data sensor_data = { 0 }; + + /* Initialize the interrupt status of accel. */ + uint16_t int_status = 0; + + uint8_t indx = 0; + float x = 0, y = 0, z = 0; + + /* Interface reference is given as a parameter + * For I2C : BMI2_I2C_INTF + * For SPI : BMI2_SPI_INTF + */ + rslt = bmi2_interface_init(&bmi2_dev, BMI2_I2C_INTF); + bmi2_error_codes_print_result(rslt); + + /* Initialize bmi270. */ + rslt = bmi270_init(&bmi2_dev); + bmi2_error_codes_print_result(rslt); + + if (rslt == BMI2_OK) + { + /* Enable the accel sensor. */ + rslt = bmi270_sensor_enable(&sensor_list, 1, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + if (rslt == BMI2_OK) + { + /* Accel configuration settings. */ + rslt = set_accel_config(&bmi2_dev); + bmi2_error_codes_print_result(rslt); + + /* Assign accel sensor. */ + sensor_data.type = BMI2_ACCEL; + printf("Accel and m/s2 data \n"); + printf("Accel data collected at 2G Range with 16-bit resolution\n"); + + /* Loop to print the accel data when interrupt occurs. */ + while (indx <= limit) + { + /* To get the status of accel data ready interrupt. */ + rslt = bmi2_get_int_status(&int_status, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + /* To check the accel data ready interrupt status and print the status for 10 samples. */ + if (int_status & BMI2_ACC_DRDY_INT_MASK) + { + /* Get accelerometer data for x, y and z axis. */ + rslt = bmi270_get_sensor_data(&sensor_data, 1, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + printf("\nAcc_X = %d\t", sensor_data.sens_data.acc.x); + printf("Acc_Y = %d\t", sensor_data.sens_data.acc.y); + printf("Acc_Z = %d\r\n", sensor_data.sens_data.acc.z); + + /* Converting lsb to meter per second squared for 16 bit accelerometer at 2G range. */ + x = lsb_to_mps2(sensor_data.sens_data.acc.x, 2, bmi2_dev.resolution); + y = lsb_to_mps2(sensor_data.sens_data.acc.y, 2, bmi2_dev.resolution); + z = lsb_to_mps2(sensor_data.sens_data.acc.z, 2, bmi2_dev.resolution); + + /* Print the data in m/s2. */ + printf("\nAcc_ms2_X = %4.2f, Acc_ms2_Y = %4.2f, Acc_ms2_Z = %4.2f\n", x, y, z); + + indx++; + } + } + } + } + + bmi2_coines_deinit(); + + return rslt; +} + +/*! + * @brief This internal API is used to set configurations for accel. + */ +static int8_t set_accel_config(struct bmi2_dev *bmi2_dev) +{ + /* Status of api are returned to this variable. */ + int8_t rslt; + + /* Structure to define accelerometer configuration. */ + struct bmi2_sens_config config; + + /* Configure the type of feature. */ + config.type = BMI2_ACCEL; + + /* Get default configurations for the type of feature selected. */ + rslt = bmi270_get_sensor_config(&config, 1, bmi2_dev); + bmi2_error_codes_print_result(rslt); + + if (rslt == BMI2_OK) + { + /* NOTE: The user can change the following configuration parameters according to their requirement. */ + /* Set Output Data Rate */ + config.cfg.acc.odr = BMI2_ACC_ODR_200HZ; + + /* Gravity range of the sensor (+/- 2G, 4G, 8G, 16G). */ + config.cfg.acc.range = BMI2_ACC_RANGE_2G; + + /* The bandwidth parameter is used to configure the number of sensor samples that are averaged + * if it is set to 2, then 2^(bandwidth parameter) samples + * are averaged, resulting in 4 averaged samples. + * Note1 : For more information, refer the datasheet. + * Note2 : A higher number of averaged samples will result in a lower noise level of the signal, but + * this has an adverse effect on the power consumed. + */ + config.cfg.acc.bwp = BMI2_ACC_NORMAL_AVG4; + + /* Enable the filter performance mode where averaging of samples + * will be done based on above set bandwidth and ODR. + * There are two modes + * 0 -> Ultra low power mode + * 1 -> High performance mode(Default) + * For more info refer datasheet. + */ + config.cfg.acc.filter_perf = BMI2_PERF_OPT_MODE; + + /* Set the accel configurations. */ + rslt = bmi270_set_sensor_config(&config, 1, bmi2_dev); + bmi2_error_codes_print_result(rslt); + + /* Map data ready interrupt to interrupt pin. */ + rslt = bmi2_map_data_int(BMI2_DRDY_INT, BMI2_INT1, bmi2_dev); + bmi2_error_codes_print_result(rslt); + } + + return rslt; +} + +/*! + * @brief This function converts lsb to meter per second squared for 16 bit accelerometer at + * range 2G, 4G, 8G or 16G. + */ +static float lsb_to_mps2(int16_t val, float g_range, uint8_t bit_width) +{ + float half_scale = ((float)(1 << bit_width) / 2.0f); + + return (GRAVITY_EARTH * val * g_range) / half_scale; +} diff --git a/examples/bmi270/accel_gyro/Makefile b/examples/bmi270/accel_gyro/Makefile new file mode 100644 index 0000000..c0617d0 --- /dev/null +++ b/examples/bmi270/accel_gyro/Makefile @@ -0,0 +1,18 @@ +COINES_INSTALL_PATH ?= ../../../.. + +EXAMPLE_FILE ?= accel_gyro.c + +API_LOCATION ?= ../.. + +COMMON_LOCATION ?= .. + +C_SRCS += \ +$(API_LOCATION)/bmi2.c \ +$(API_LOCATION)/bmi270.c \ +$(COMMON_LOCATION)/common/common.c + +INCLUDEPATHS += \ +$(API_LOCATION) \ +$(COMMON_LOCATION)/common + +include $(COINES_INSTALL_PATH)/coines.mk \ No newline at end of file diff --git a/examples/bmi270/accel_gyro/accel_gyro.c b/examples/bmi270/accel_gyro/accel_gyro.c new file mode 100644 index 0000000..1e7c9df --- /dev/null +++ b/examples/bmi270/accel_gyro/accel_gyro.c @@ -0,0 +1,268 @@ +/**\ + * Copyright (c) 2020 Bosch Sensortec GmbH. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + **/ + +/******************************************************************************/ +/*! Header Files */ +#include +#include "bmi270.h" +#include "common.h" + +/******************************************************************************/ +/*! Macro definition */ + +/*! Earth's gravity in m/s^2 */ +#define GRAVITY_EARTH (9.80665f) + +/*! Macros to select the sensors */ +#define ACCEL UINT8_C(0x00) +#define GYRO UINT8_C(0x01) + +/******************************************************************************/ +/*! Static Function Declaration */ + +/*! + * @brief This internal API is used to set configurations for accel. + * + * @param[in] dev : Structure instance of bmi2_dev. + * + * @return Status of execution. + */ +static int8_t set_accel_gyro_config(struct bmi2_dev *bmi2_dev); + +/*! + * @brief This function converts lsb to meter per second squared for 16 bit accelerometer at + * range 2G, 4G, 8G or 16G. + * + * @param[in] val : LSB from each axis. + * @param[in] g_range : Gravity range. + * @param[in] bit_width : Resolution for accel. + * + * @return Gravity. + */ +static float lsb_to_mps2(int16_t val, float g_range, uint8_t bit_width); + +/*! + * @brief This function converts lsb to degree per second for 16 bit gyro at + * range 125, 250, 500, 1000 or 2000dps. + * + * @param[in] val : LSB from each axis. + * @param[in] dps : Degree per second. + * @param[in] bit_width : Resolution for gyro. + * + * @return Degree per second. + */ +static float lsb_to_dps(int16_t val, float dps, uint8_t bit_width); + +/******************************************************************************/ +/*! Functions */ + +/* This function starts the execution of program. */ +int main(void) +{ + /* Status of api are returned to this variable. */ + int8_t rslt; + + /* Variable to define limit to print accel data. */ + uint8_t limit = 10; + + /* Assign accel and gyro sensor to variable. */ + uint8_t sensor_list[2] = { BMI2_ACCEL, BMI2_GYRO }; + + /* Sensor initialization configuration. */ + struct bmi2_dev bmi2_dev; + + /* Create an instance of sensor data structure. */ + struct bmi2_sensor_data sensor_data[2] = { { 0 } }; + + /* Initialize the interrupt status of accel and gyro. */ + uint16_t int_status = 0; + + uint8_t indx = 1; + + float x = 0, y = 0, z = 0; + + /* Interface reference is given as a parameter + * For I2C : BMI2_I2C_INTF + * For SPI : BMI2_SPI_INTF + */ + rslt = bmi2_interface_init(&bmi2_dev, BMI2_SPI_INTF); + bmi2_error_codes_print_result(rslt); + + /* Initialize bmi270. */ + rslt = bmi270_init(&bmi2_dev); + bmi2_error_codes_print_result(rslt); + + if (rslt == BMI2_OK) + { + /* Enable the accel and gyro sensor. */ + rslt = bmi270_sensor_enable(sensor_list, 2, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + if (rslt == BMI2_OK) + { + /* Accel and gyro configuration settings. */ + rslt = set_accel_gyro_config(&bmi2_dev); + bmi2_error_codes_print_result(rslt); + + /* Assign accel and gyro sensor. */ + sensor_data[ACCEL].type = BMI2_ACCEL; + sensor_data[GYRO].type = BMI2_GYRO; + + /* Loop to print accel and gyro data when interrupt occurs. */ + while (indx <= limit) + { + /* To get the data ready interrupt status of accel and gyro. */ + rslt = bmi2_get_int_status(&int_status, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + /* To check the data ready interrupt status and print the status for 10 samples. */ + if ((int_status & BMI2_ACC_DRDY_INT_MASK) && (int_status & BMI2_GYR_DRDY_INT_MASK)) + { + /* Get accel and gyro data for x, y and z axis. */ + rslt = bmi270_get_sensor_data(sensor_data, 2, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + printf("\n******* Accel(Raw and m/s2) Gyro(Raw and dps) data : %d *******\n", indx); + + printf("\nAcc_x = %d\t", sensor_data[ACCEL].sens_data.acc.x); + printf("Acc_y = %d\t", sensor_data[ACCEL].sens_data.acc.y); + printf("Acc_z = %d", sensor_data[ACCEL].sens_data.acc.z); + + /* Converting lsb to meter per second squared for 16 bit accelerometer at 2G range. */ + x = lsb_to_mps2(sensor_data[ACCEL].sens_data.acc.x, 2, bmi2_dev.resolution); + y = lsb_to_mps2(sensor_data[ACCEL].sens_data.acc.y, 2, bmi2_dev.resolution); + z = lsb_to_mps2(sensor_data[ACCEL].sens_data.acc.z, 2, bmi2_dev.resolution); + + /* Print the data in m/s2. */ + printf("\nAcc_ms2_X = %4.2f, Acc_ms2_Y = %4.2f, Acc_ms2_Z = %4.2f\n", x, y, z); + + printf("\nGyr_X = %d\t", sensor_data[GYRO].sens_data.gyr.x); + printf("Gyr_Y = %d\t", sensor_data[GYRO].sens_data.gyr.y); + printf("Gyr_Z= %d\n", sensor_data[GYRO].sens_data.gyr.z); + + /* Converting lsb to degree per second for 16 bit gyro at 2000dps range. */ + x = lsb_to_dps(sensor_data[GYRO].sens_data.gyr.x, 2000, bmi2_dev.resolution); + y = lsb_to_dps(sensor_data[GYRO].sens_data.gyr.y, 2000, bmi2_dev.resolution); + z = lsb_to_dps(sensor_data[GYRO].sens_data.gyr.z, 2000, bmi2_dev.resolution); + + /* Print the data in dps. */ + printf("Gyro_DPS_X = %4.2f, Gyro_DPS_Y = %4.2f, Gyro_DPS_Z = %4.2f\n", x, y, z); + + indx++; + } + } + } + } + + bmi2_coines_deinit(); + + return rslt; +} + +/*! + * @brief This internal API is used to set configurations for accel and gyro. + */ +static int8_t set_accel_gyro_config(struct bmi2_dev *bmi2_dev) +{ + /* Status of api are returned to this variable. */ + int8_t rslt; + + /* Structure to define accelerometer and gyro configuration. */ + struct bmi2_sens_config config[2]; + + /* Configure the type of feature. */ + config[ACCEL].type = BMI2_ACCEL; + config[GYRO].type = BMI2_GYRO; + + /* Get default configurations for the type of feature selected. */ + rslt = bmi270_get_sensor_config(config, 2, bmi2_dev); + bmi2_error_codes_print_result(rslt); + + /* Map data ready interrupt to interrupt pin. */ + rslt = bmi2_map_data_int(BMI2_DRDY_INT, BMI2_INT1, bmi2_dev); + bmi2_error_codes_print_result(rslt); + + if (rslt == BMI2_OK) + { + /* NOTE: The user can change the following configuration parameters according to their requirement. */ + /* Set Output Data Rate */ + config[ACCEL].cfg.acc.odr = BMI2_ACC_ODR_200HZ; + + /* Gravity range of the sensor (+/- 2G, 4G, 8G, 16G). */ + config[ACCEL].cfg.acc.range = BMI2_ACC_RANGE_2G; + + /* The bandwidth parameter is used to configure the number of sensor samples that are averaged + * if it is set to 2, then 2^(bandwidth parameter) samples + * are averaged, resulting in 4 averaged samples. + * Note1 : For more information, refer the datasheet. + * Note2 : A higher number of averaged samples will result in a lower noise level of the signal, but + * this has an adverse effect on the power consumed. + */ + config[ACCEL].cfg.acc.bwp = BMI2_ACC_NORMAL_AVG4; + + /* Enable the filter performance mode where averaging of samples + * will be done based on above set bandwidth and ODR. + * There are two modes + * 0 -> Ultra low power mode + * 1 -> High performance mode(Default) + * For more info refer datasheet. + */ + config[ACCEL].cfg.acc.filter_perf = BMI2_PERF_OPT_MODE; + + /* The user can change the following configuration parameters according to their requirement. */ + /* Set Output Data Rate */ + config[GYRO].cfg.gyr.odr = BMI2_GYR_ODR_200HZ; + + /* Gyroscope Angular Rate Measurement Range.By default the range is 2000dps. */ + config[GYRO].cfg.gyr.range = BMI2_GYR_RANGE_2000; + + /* Gyroscope bandwidth parameters. By default the gyro bandwidth is in normal mode. */ + config[GYRO].cfg.gyr.bwp = BMI2_GYR_NORMAL_MODE; + + /* Enable/Disable the noise performance mode for precision yaw rate sensing + * There are two modes + * 0 -> Ultra low power mode(Default) + * 1 -> High performance mode + */ + config[GYRO].cfg.gyr.noise_perf = BMI2_POWER_OPT_MODE; + + /* Enable/Disable the filter performance mode where averaging of samples + * will be done based on above set bandwidth and ODR. + * There are two modes + * 0 -> Ultra low power mode + * 1 -> High performance mode(Default) + */ + config[GYRO].cfg.gyr.filter_perf = BMI2_PERF_OPT_MODE; + + /* Set the accel and gyro configurations. */ + rslt = bmi270_set_sensor_config(config, 2, bmi2_dev); + bmi2_error_codes_print_result(rslt); + } + + return rslt; +} + +/*! + * @brief This function converts lsb to meter per second squared for 16 bit accelerometer at + * range 2G, 4G, 8G or 16G. + */ +static float lsb_to_mps2(int16_t val, float g_range, uint8_t bit_width) +{ + float half_scale = ((float)(1 << bit_width) / 2.0f); + + return (GRAVITY_EARTH * val * g_range) / half_scale; +} + +/*! + * @brief This function converts lsb to degree per second for 16 bit gyro at + * range 125, 250, 500, 1000 or 2000dps. + */ +static float lsb_to_dps(int16_t val, float dps, uint8_t bit_width) +{ + float half_scale = ((float)(1 << bit_width) / 2.0f); + + return (dps / ((half_scale) + BMI2_GYR_RANGE_2000)) * (val); +} diff --git a/examples/bmi270/any_motion_interrupt/Makefile b/examples/bmi270/any_motion_interrupt/Makefile new file mode 100644 index 0000000..9158f05 --- /dev/null +++ b/examples/bmi270/any_motion_interrupt/Makefile @@ -0,0 +1,18 @@ +COINES_INSTALL_PATH ?= ../../../.. + +EXAMPLE_FILE ?= any_motion_interrupt.c + +API_LOCATION ?= ../.. + +COMMON_LOCATION ?= .. + +C_SRCS += \ +$(API_LOCATION)/bmi2.c \ +$(API_LOCATION)/bmi270.c \ +$(COMMON_LOCATION)/common/common.c + +INCLUDEPATHS += \ +$(API_LOCATION) \ +$(COMMON_LOCATION)/common + +include $(COINES_INSTALL_PATH)/coines.mk \ No newline at end of file diff --git a/examples/bmi270/generic/any_motion_interrupt.c b/examples/bmi270/any_motion_interrupt/any_motion_interrupt.c similarity index 87% rename from examples/bmi270/generic/any_motion_interrupt.c rename to examples/bmi270/any_motion_interrupt/any_motion_interrupt.c index 59beb94..062b29e 100644 --- a/examples/bmi270/generic/any_motion_interrupt.c +++ b/examples/bmi270/any_motion_interrupt/any_motion_interrupt.c @@ -1,137 +1,135 @@ -/**\ - * Copyright (c) 2020 Bosch Sensortec GmbH. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - **/ - -/******************************************************************************/ -/*! Header Files */ -#include -#include "bmi2.h" -#include "bmi270.h" -#include "bmi2_common.h" - -/******************************************************************************/ -/*! Static Function Declaration */ - -/*! - * @brief This internal API is used to set configurations for any-motion. - * - * @param[in] bmi2_dev : Structure instance of bmi2_dev. - * - * @return Status of execution. - */ -static int8_t set_feature_config(struct bmi2_dev *bmi2_dev); - -/******************************************************************************/ -/*! Functions */ - -/* This function starts the execution of program. */ -int main(void) -{ - - /* Status of api are returned to this variable. */ - int8_t rslt; - - /* Accel sensor and any-motion feature are listed in array. */ - uint8_t sens_list[2] = { BMI2_ACCEL, BMI2_ANY_MOTION }; - - /* Variable to get any-motion interrupt status. */ - uint16_t int_status = 0; - - /*! Sensor initialization configuration. */ - struct bmi2_dev bmi2_dev; - - /* Select features and their pins to be mapped to. */ - struct bmi2_sens_int_config sens_int = { .type = BMI2_ANY_MOTION, .hw_int_pin = BMI2_INT1 }; - - /* Initialize the dev structure */ - rslt = bmi2_interface_selection(&bmi2_dev); - bmi2_error_codes_print_result(rslt); - - /* Initialize bmi270. */ - rslt = bmi270_init(&bmi2_dev); - bmi2_error_codes_print_result(rslt); - - if (rslt == BMI2_OK) - { - - /* Enable the selected sensors. */ - rslt = bmi2_sensor_enable(sens_list, 2, &bmi2_dev); - bmi2_error_codes_print_result(rslt); - - if (rslt == BMI2_OK) - { - - /* Set feature configurations for any-motion. */ - rslt = set_feature_config(&bmi2_dev); - bmi2_error_codes_print_result(rslt); - - if (rslt == BMI2_OK) - { - - /* Map the feature interrupt for any-motion. */ - rslt = bmi2_map_feat_int(&sens_int, 1, &bmi2_dev); - bmi2_error_codes_print_result(rslt); - printf("Move the board\n"); - - /* Loop to get any-motion interrupt. */ - do - { - - /* Clear buffer. */ - int_status = 0; - - /* To get the interrupt status of any-motion. */ - rslt = bmi2_get_int_status(&int_status, &bmi2_dev); - bmi2_error_codes_print_result(rslt); - - /* To check the interrupt status of any-motion. */ - if (int_status & BMI270_ANY_MOT_STATUS_MASK) - { - printf("Any-motion interrupt is generated\n"); - break; - } - } while (rslt == BMI2_OK); - } - } - } - - return rslt; -} - -/*! - * @brief This internal API is used to set configurations for any-motion. - */ -static int8_t set_feature_config(struct bmi2_dev *bmi2_dev) -{ - - /* Status of api are returned to this variable. */ - int8_t rslt; - - /* Structure to define the type of sensor and its configurations. */ - struct bmi2_sens_config config; - - /* Configure the type of feature. */ - config.type = BMI2_ANY_MOTION; - - /* Get default configurations for the type of feature selected. */ - rslt = bmi2_get_sensor_config(&config, 1, bmi2_dev); - bmi2_error_codes_print_result(rslt); - if (rslt == BMI2_OK) - { - - /* NOTE: The user can change the following configuration parameters according to their requirement. */ - /* 1LSB equals 20ms. Default is 100ms, setting to 80ms. */ - config.cfg.any_motion.duration = 0x04; - - /* 1LSB equals to 0.48mg. Default is 83mg, setting to 50mg. */ - config.cfg.any_motion.threshold = 0x68; - - /* Set new configurations. */ - rslt = bmi2_set_sensor_config(&config, 1, bmi2_dev); - bmi2_error_codes_print_result(rslt); - } - - return rslt; -} +/**\ + * Copyright (c) 2020 Bosch Sensortec GmbH. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + **/ + +/******************************************************************************/ +/*! Header Files */ +#include +#include "bmi270.h" +#include "common.h" + +/******************************************************************************/ +/*! Static Function Declaration */ + +/*! + * @brief This internal API is used to set configurations for any-motion. + * + * @param[in] bmi2_dev : Structure instance of bmi2_dev. + * + * @return Status of execution. + */ +static int8_t set_feature_config(struct bmi2_dev *bmi2_dev); + +/******************************************************************************/ +/*! Functions */ + +/* This function starts the execution of program. */ +int main(void) +{ + /* Status of api are returned to this variable. */ + int8_t rslt; + + /* Accel sensor and any-motion feature are listed in array. */ + uint8_t sens_list[2] = { BMI2_ACCEL, BMI2_ANY_MOTION }; + + /* Variable to get any-motion interrupt status. */ + uint16_t int_status = 0; + + /* Sensor initialization configuration. */ + struct bmi2_dev bmi2_dev; + + /* Select features and their pins to be mapped to. */ + struct bmi2_sens_int_config sens_int = { .type = BMI2_ANY_MOTION, .hw_int_pin = BMI2_INT1 }; + + /* Interface reference is given as a parameter + * For I2C : BMI2_I2C_INTF + * For SPI : BMI2_SPI_INTF + */ + rslt = bmi2_interface_init(&bmi2_dev, BMI2_I2C_INTF); + bmi2_error_codes_print_result(rslt); + + /* Initialize bmi270. */ + rslt = bmi270_init(&bmi2_dev); + bmi2_error_codes_print_result(rslt); + + if (rslt == BMI2_OK) + { + /* Enable the selected sensors. */ + rslt = bmi270_sensor_enable(sens_list, 2, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + if (rslt == BMI2_OK) + { + /* Set feature configurations for any-motion. */ + rslt = set_feature_config(&bmi2_dev); + bmi2_error_codes_print_result(rslt); + + if (rslt == BMI2_OK) + { + /* Map the feature interrupt for any-motion. */ + rslt = bmi270_map_feat_int(&sens_int, 1, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + printf("Move the board\n"); + + /* Loop to get any-motion interrupt. */ + do + { + /* Clear buffer. */ + int_status = 0; + + /* To get the interrupt status of any-motion. */ + rslt = bmi2_get_int_status(&int_status, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + /* To check the interrupt status of any-motion. */ + if (int_status & BMI270_ANY_MOT_STATUS_MASK) + { + printf("Any-motion interrupt is generated\n"); + break; + } + } while (rslt == BMI2_OK); + } + } + } + + bmi2_coines_deinit(); + + return rslt; +} + +/*! + * @brief This internal API is used to set configurations for any-motion. + */ +static int8_t set_feature_config(struct bmi2_dev *bmi2_dev) +{ + + /* Status of api are returned to this variable. */ + int8_t rslt; + + /* Structure to define the type of sensor and its configurations. */ + struct bmi2_sens_config config; + + /* Configure the type of feature. */ + config.type = BMI2_ANY_MOTION; + + /* Get default configurations for the type of feature selected. */ + rslt = bmi270_get_sensor_config(&config, 1, bmi2_dev); + bmi2_error_codes_print_result(rslt); + if (rslt == BMI2_OK) + { + /* NOTE: The user can change the following configuration parameters according to their requirement. */ + /* 1LSB equals 20ms. Default is 100ms, setting to 80ms. */ + config.cfg.any_motion.duration = 0x04; + + /* 1LSB equals to 0.48mg. Default is 83mg, setting to 50mg. */ + config.cfg.any_motion.threshold = 0x68; + + /* Set new configurations. */ + rslt = bmi270_set_sensor_config(&config, 1, bmi2_dev); + bmi2_error_codes_print_result(rslt); + } + + return rslt; +} diff --git a/examples/bmi270/generic/bmi2_common.c b/examples/bmi270/common/common.c similarity index 68% rename from examples/bmi270/generic/bmi2_common.c rename to examples/bmi270/common/common.c index 7014da5..afff37b 100644 --- a/examples/bmi270/generic/bmi2_common.c +++ b/examples/bmi270/common/common.c @@ -1,344 +1,372 @@ -/**\ - * Copyright (c) 2020 Bosch Sensortec GmbH. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - **/ - -/******************************************************************************/ -#include -#include "bmi2_common.h" -#include "bmi2.h" - -/******************************************************************************/ -/*! Static variable definition */ - -/*! Variable that holds the I2C device address or SPI chip selection */ -static uint8_t dev_addr; - -/******************************************************************************/ -/*! User interface functions */ - -/*! - * @brief Function for initialization of I2C bus. - */ -int8_t bmi2_user_i2c_init(void) -{ - - /* Implement I2C bus initialization according to the target machine. */ - return 0; -} - -/*! - * @brief Function for initialization of SPI bus. - */ -int8_t bmi2_user_spi_init(void) -{ - - /* Implement SPI bus initialization according to the target machine. */ - return 0; -} - -/*! - * @brief This function provides the delay for required time (Microseconds) as per the input provided in some of the - * APIs. - */ -void user_delay_us(uint32_t period_us, void *intf_ptr) -{ - /* Wait for a period amount of microseconds. */ -} - -/*! - * @brief This function provides the delay for required time (Milliseconds) as per the input provided in some of the - * APIs. - */ -void user_delay_ms(uint32_t period_ms) -{ - /* Wait for a period amount of milliseconds. */ -} - -/*! - * @brief This function is for writing the sensor's registers through I2C bus. - */ -int8_t user_i2c_reg_write(uint8_t reg_addr, const uint8_t *reg_data, uint32_t length, void *intf_ptr) -{ - - /* Write to registers using I2C. Return 0 for a successful execution. */ - return 0; -} - -/*! - * @brief This function is for reading the sensor's registers through I2C bus. - */ -int8_t user_i2c_reg_read(uint8_t reg_addr, uint8_t *reg_data, uint32_t length, void *intf_ptr) -{ - - /* Read from registers using I2C. Return 0 for a successful execution. */ - return 0; -} - -/*! - * @brief This function is for writing the sensor's registers through SPI bus. - */ -int8_t user_spi_reg_write(uint8_t reg_addr, const uint8_t *reg_data, uint32_t length, void *intf_ptr) -{ - - /* Write to registers using SPI. Return 0 for a successful execution. */ - return 0; -} - -/*! - * @brief This function is for reading the sensor's registers through SPI bus. - */ -int8_t user_spi_reg_read(uint8_t reg_addr, uint8_t *reg_data, uint32_t length, void *intf_ptr) -{ - - /* Read from registers using SPI. Return 0 for a successful execution. */ - return 0; -} - -/*! - * @brief This function is to select the interface between SPI and I2C. - */ -int8_t bmi2_interface_selection(struct bmi2_dev *dev) -{ - int8_t rslt = BMI2_OK; - - if (dev != NULL) - { - /* Select the interface for execution - * For I2C : BMI2_I2C_INTF - * For SPI : BMI2_SPI_INTF - */ - dev->intf = BMI2_I2C_INTF; - - /* Bus configuration : I2C */ - if (dev->intf == BMI2_I2C_INTF) - { - printf("I2C Interface \n"); - - /* To initialize the user I2C function */ - bmi2_user_i2c_init(); - dev_addr = BMI2_I2C_PRIM_ADDR; - dev->read = user_i2c_reg_read; - dev->write = user_i2c_reg_write; - } - /* Bus configuration : SPI */ - else if (dev->intf == BMI2_SPI_INTF) - { - printf("SPI Interface \n"); - - /* To initialize the user SPI function */ - bmi2_user_spi_init(); - dev_addr = 0; - dev->read = user_spi_reg_read; - dev->write = user_spi_reg_write; - } - - /* Assign device address to interface pointer */ - dev->intf_ptr = &dev_addr; - - /* Configure delay in microseconds */ - dev->delay_us = user_delay_us; - - /* Configure max read/write length (in bytes) ( Supported length depends on target machine) */ - dev->read_write_len = 8; - - /* Assign to NULL to load the default config file. */ - dev->config_file_ptr = NULL; - } - else - { - rslt = BMI2_E_NULL_PTR; - } - - return rslt; -} - -/*! - * @brief This internal API prints the execution status - */ -void bmi2_error_codes_print_result(int8_t rslt) -{ - switch (rslt) - { - case BMI2_OK: - - /*! Do nothing */ - break; - - case BMI2_E_NULL_PTR: - printf( - "Error [%d] : Null pointer error. It occurs when the user tries to assign value (not address) to a pointer," " which has been initialized to NULL.\r\n", - rslt); - break; - - case BMI2_E_COM_FAIL: - printf( - "Error [%d] : Communication failure error. It occurs due to read/write operation failure and also due " "to power failure during communication\r\n", - rslt); - break; - - case BMI2_E_DEV_NOT_FOUND: - printf("Error [%d] : Device not found error. It occurs when the device chip id is incorrectly read\r\n", - rslt); - break; - - case BMI2_E_INVALID_SENSOR: - printf( - "Error [%d] : Invalid sensor error. It occurs when there is a mismatch in the requested feature with the " "available one\r\n", - rslt); - break; - - case BMI2_E_SELF_TEST_FAIL: - printf( - "Error [%d] : Self-test failed error. It occurs when the validation of accel self-test data is " "not satisfied\r\n", - rslt); - break; - - case BMI2_E_INVALID_INT_PIN: - printf( - "Error [%d] : Invalid interrupt pin error. It occurs when the user tries to configure interrupt pins " "apart from INT1 and INT2\r\n", - rslt); - break; - - case BMI2_E_OUT_OF_RANGE: - printf( - "Error [%d] : Out of range error. It occurs when the data exceeds from filtered or unfiltered data from " "fifo and also when the range exceeds the maximum range for accel and gyro while performing FOC\r\n", - rslt); - break; - - case BMI2_E_ACC_INVALID_CFG: - printf( - "Error [%d] : Invalid Accel configuration error. It occurs when there is an error in accel configuration" " register which could be one among range, BW or filter performance in reg address 0x40\r\n", - rslt); - break; - - case BMI2_E_GYRO_INVALID_CFG: - printf( - "Error [%d] : Invalid Gyro configuration error. It occurs when there is a error in gyro configuration" "register which could be one among range, BW or filter performance in reg address 0x42\r\n", - rslt); - break; - - case BMI2_E_ACC_GYR_INVALID_CFG: - printf( - "Error [%d] : Invalid Accel-Gyro configuration error. It occurs when there is a error in accel and gyro" " configuration registers which could be one among range, BW or filter performance in reg address 0x40 " "and 0x42\r\n", - rslt); - break; - - case BMI2_E_CONFIG_LOAD: - printf( - "Error [%d] : Configuration load error. It occurs when failure observed while loading the configuration " "into the sensor\r\n", - rslt); - break; - - case BMI2_E_INVALID_PAGE: - printf( - "Error [%d] : Invalid page error. It occurs due to failure in writing the correct feature configuration " "from selected page\r\n", - rslt); - break; - - case BMI2_E_SET_APS_FAIL: - printf( - "Error [%d] : APS failure error. It occurs due to failure in write of advance power mode configuration " "register\r\n", - rslt); - break; - - case BMI2_E_AUX_INVALID_CFG: - printf( - "Error [%d] : Invalid AUX configuration error. It occurs when the auxiliary interface settings are not " "enabled properly\r\n", - rslt); - break; - - case BMI2_E_AUX_BUSY: - printf( - "Error [%d] : AUX busy error. It occurs when the auxiliary interface buses are engaged while configuring" " the AUX\r\n", - rslt); - break; - - case BMI2_E_REMAP_ERROR: - printf( - "Error [%d] : Remap error. It occurs due to failure in assigning the remap axes data for all the axes " "after change in axis position\r\n", - rslt); - break; - - case BMI2_E_GYR_USER_GAIN_UPD_FAIL: - printf( - "Error [%d] : Gyro user gain update fail error. It occurs when the reading of user gain update status " "fails\r\n", - rslt); - break; - - case BMI2_E_SELF_TEST_NOT_DONE: - printf( - "Error [%d] : Self-test not done error. It occurs when the self-test process is ongoing or not " "completed\r\n", - rslt); - break; - - case BMI2_E_INVALID_INPUT: - printf("Error [%d] : Invalid input error. It occurs when the sensor input validity fails\r\n", rslt); - break; - - case BMI2_E_INVALID_STATUS: - printf("Error [%d] : Invalid status error. It occurs when the feature/sensor validity fails\r\n", rslt); - break; - - case BMI2_E_CRT_ERROR: - printf("Error [%d] : CRT error. It occurs when the CRT test has failed\r\n", rslt); - break; - - case BMI2_E_ST_ALREADY_RUNNING: - printf( - "Error [%d] : Self-test already running error. It occurs when the self-test is already running and " "another has been initiated\r\n", - rslt); - break; - - case BMI2_E_CRT_READY_FOR_DL_FAIL_ABORT: - printf( - "Error [%d] : CRT ready for download fail abort error. It occurs when download in CRT fails due to wrong " "address location\r\n", - rslt); - break; - - case BMI2_E_DL_ERROR: - printf( - "Error [%d] : Download error. It occurs when write length exceeds that of the maximum burst length\r\n", - rslt); - break; - - case BMI2_E_PRECON_ERROR: - printf( - "Error [%d] : Pre-conditional error. It occurs when precondition to start the feature was not " "completed\r\n", - rslt); - break; - - case BMI2_E_ABORT_ERROR: - printf("Error [%d] : Abort error. It occurs when the device was shaken during CRT test\r\n", rslt); - break; - - case BMI2_E_WRITE_CYCLE_ONGOING: - printf( - "Error [%d] : Write cycle ongoing error. It occurs when the write cycle is already running and another " "has been initiated\r\n", - rslt); - break; - - case BMI2_E_ST_NOT_RUNING: - printf( - "Error [%d] : Self-test is not running error. It occurs when self-test running is disabled while it's " "running\r\n", - rslt); - break; - - case BMI2_E_DATA_RDY_INT_FAILED: - printf( - "Error [%d] : Data ready interrupt error. It occurs when the sample count exceeds the FOC sample limit " "and data ready status is not updated\r\n", - rslt); - break; - - case BMI2_E_INVALID_FOC_POSITION: - printf( - "Error [%d] : Invalid FOC position error. It occurs when average FOC data is obtained for the wrong" " axes\r\n", - rslt); - break; - - default: - printf("Error [%d] : Unknown error code\r\n", rslt); - break; - } -} +/** + * Copyright (C) 2020 Bosch Sensortec GmbH. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include + +#include "coines.h" +#include "bmi2_defs.h" + +/******************************************************************************/ +/*! Macro definitions */ +#define BMI2XY_SHUTTLE_ID UINT16_C(0x1B8) + +/*! Macro that defines read write length */ +#define READ_WRITE_LEN UINT8_C(46) + +/******************************************************************************/ +/*! Static variable definition */ + +/*! Variable that holds the I2C device address or SPI chip selection */ +static uint8_t dev_addr; + +/******************************************************************************/ +/*! User interface functions */ + +/*! + * I2C read function map to COINES platform + */ +BMI2_INTF_RETURN_TYPE bmi2_i2c_read(uint8_t reg_addr, uint8_t *reg_data, uint32_t len, void *intf_ptr) +{ + uint8_t dev_addr = *(uint8_t*)intf_ptr; + + return coines_read_i2c(dev_addr, reg_addr, reg_data, (uint16_t)len); +} + +/*! + * I2C write function map to COINES platform + */ +BMI2_INTF_RETURN_TYPE bmi2_i2c_write(uint8_t reg_addr, const uint8_t *reg_data, uint32_t len, void *intf_ptr) +{ + uint8_t dev_addr = *(uint8_t*)intf_ptr; + + return coines_write_i2c(dev_addr, reg_addr, (uint8_t *)reg_data, (uint16_t)len); +} + +/*! + * SPI read function map to COINES platform + */ +BMI2_INTF_RETURN_TYPE bmi2_spi_read(uint8_t reg_addr, uint8_t *reg_data, uint32_t len, void *intf_ptr) +{ + uint8_t dev_addr = *(uint8_t*)intf_ptr; + + return coines_read_spi(dev_addr, reg_addr, reg_data, (uint16_t)len); +} + +/*! + * SPI write function map to COINES platform + */ +BMI2_INTF_RETURN_TYPE bmi2_spi_write(uint8_t reg_addr, const uint8_t *reg_data, uint32_t len, void *intf_ptr) +{ + uint8_t dev_addr = *(uint8_t*)intf_ptr; + + return coines_write_spi(dev_addr, reg_addr, (uint8_t *)reg_data, (uint16_t)len); +} + +/*! + * Delay function map to COINES platform + */ +void bmi2_delay_us(uint32_t period, void *intf_ptr) +{ + coines_delay_usec(period); +} + +/*! + * @brief Function to select the interface between SPI and I2C. + * Also to initialize coines platform + */ +int8_t bmi2_interface_init(struct bmi2_dev *bmi, uint8_t intf) +{ + int8_t rslt = BMI2_OK; + struct coines_board_info board_info; + + if (bmi != NULL) + { + int16_t result = coines_open_comm_intf(COINES_COMM_INTF_USB); + if (result < COINES_SUCCESS) + { + printf( + "\n Unable to connect with Application Board ! \n" " 1. Check if the board is connected and powered on. \n" " 2. Check if Application Board USB driver is installed. \n" + " 3. Check if board is in use by another application. (Insufficient permissions to access USB) \n"); + exit(result); + } + + result = coines_get_board_info(&board_info); + +#if defined(PC) + setbuf(stdout, NULL); +#endif + + if (result == COINES_SUCCESS) + { + if ((board_info.shuttle_id != BMI2XY_SHUTTLE_ID)) + { + printf("! Warning invalid sensor shuttle \n ," "This application will not support this sensor \n"); + exit(COINES_E_FAILURE); + } + } + + coines_set_shuttleboard_vdd_vddio_config(0, 0); + coines_delay_msec(100); + + /* Bus configuration : I2C */ + if (intf == BMI2_I2C_INTF) + { + printf("I2C Interface \n"); + + /* To initialize the user I2C function */ + dev_addr = BMI2_I2C_PRIM_ADDR; + bmi->intf = BMI2_I2C_INTF; + bmi->read = bmi2_i2c_read; + bmi->write = bmi2_i2c_write; + coines_config_i2c_bus(COINES_I2C_BUS_0, COINES_I2C_FAST_MODE); + } + /* Bus configuration : SPI */ + else if (intf == BMI2_SPI_INTF) + { + printf("SPI Interface \n"); + + /* To initialize the user SPI function */ + dev_addr = COINES_SHUTTLE_PIN_7; + bmi->intf = BMI2_SPI_INTF; + bmi->read = bmi2_spi_read; + bmi->write = bmi2_spi_write; + coines_config_spi_bus(COINES_SPI_BUS_0, COINES_SPI_SPEED_5_MHZ, COINES_SPI_MODE3); + coines_set_pin_config(COINES_SHUTTLE_PIN_7, COINES_PIN_DIRECTION_OUT, COINES_PIN_VALUE_HIGH); + } + + /* Assign device address to interface pointer */ + bmi->intf_ptr = &dev_addr; + + /* Configure delay in microseconds */ + bmi->delay_us = bmi2_delay_us; + + /* Configure max read/write length (in bytes) ( Supported length depends on target machine) */ + bmi->read_write_len = READ_WRITE_LEN; + + /* Assign to NULL to load the default config file. */ + bmi->config_file_ptr = NULL; + + coines_delay_usec(10000); + + coines_set_shuttleboard_vdd_vddio_config(3300, 3300); + + coines_delay_usec(10000); + } + else + { + rslt = BMI2_E_NULL_PTR; + } + + return rslt; + +} + +/*! + * @brief Prints the execution status of the APIs. + */ +void bmi2_error_codes_print_result(int8_t rslt) +{ + switch (rslt) + { + case BMI2_OK: + + /* Do nothing */ + break; + + case BMI2_W_FIFO_EMPTY: + printf("Warning [%d] : FIFO empty\r\n", rslt); + break; + case BMI2_W_PARTIAL_READ: + printf("Warning [%d] : FIFO partial read\r\n", rslt); + break; + case BMI2_E_NULL_PTR: + printf( + "Error [%d] : Null pointer error. It occurs when the user tries to assign value (not address) to a pointer," " which has been initialized to NULL.\r\n", + rslt); + break; + + case BMI2_E_COM_FAIL: + printf( + "Error [%d] : Communication failure error. It occurs due to read/write operation failure and also due " "to power failure during communication\r\n", + rslt); + break; + + case BMI2_E_DEV_NOT_FOUND: + printf("Error [%d] : Device not found error. It occurs when the device chip id is incorrectly read\r\n", + rslt); + break; + + case BMI2_E_INVALID_SENSOR: + printf( + "Error [%d] : Invalid sensor error. It occurs when there is a mismatch in the requested feature with the " "available one\r\n", + rslt); + break; + + case BMI2_E_SELF_TEST_FAIL: + printf( + "Error [%d] : Self-test failed error. It occurs when the validation of accel self-test data is " "not satisfied\r\n", + rslt); + break; + + case BMI2_E_INVALID_INT_PIN: + printf( + "Error [%d] : Invalid interrupt pin error. It occurs when the user tries to configure interrupt pins " "apart from INT1 and INT2\r\n", + rslt); + break; + + case BMI2_E_OUT_OF_RANGE: + printf( + "Error [%d] : Out of range error. It occurs when the data exceeds from filtered or unfiltered data from " "fifo and also when the range exceeds the maximum range for accel and gyro while performing FOC\r\n", + rslt); + break; + + case BMI2_E_ACC_INVALID_CFG: + printf( + "Error [%d] : Invalid Accel configuration error. It occurs when there is an error in accel configuration" " register which could be one among range, BW or filter performance in reg address 0x40\r\n", + rslt); + break; + + case BMI2_E_GYRO_INVALID_CFG: + printf( + "Error [%d] : Invalid Gyro configuration error. It occurs when there is a error in gyro configuration" "register which could be one among range, BW or filter performance in reg address 0x42\r\n", + rslt); + break; + + case BMI2_E_ACC_GYR_INVALID_CFG: + printf( + "Error [%d] : Invalid Accel-Gyro configuration error. It occurs when there is a error in accel and gyro" " configuration registers which could be one among range, BW or filter performance in reg address 0x40 " "and 0x42\r\n", + rslt); + break; + + case BMI2_E_CONFIG_LOAD: + printf( + "Error [%d] : Configuration load error. It occurs when failure observed while loading the configuration " "into the sensor\r\n", + rslt); + break; + + case BMI2_E_INVALID_PAGE: + printf( + "Error [%d] : Invalid page error. It occurs due to failure in writing the correct feature configuration " "from selected page\r\n", + rslt); + break; + + case BMI2_E_SET_APS_FAIL: + printf( + "Error [%d] : APS failure error. It occurs due to failure in write of advance power mode configuration " "register\r\n", + rslt); + break; + + case BMI2_E_AUX_INVALID_CFG: + printf( + "Error [%d] : Invalid AUX configuration error. It occurs when the auxiliary interface settings are not " "enabled properly\r\n", + rslt); + break; + + case BMI2_E_AUX_BUSY: + printf( + "Error [%d] : AUX busy error. It occurs when the auxiliary interface buses are engaged while configuring" " the AUX\r\n", + rslt); + break; + + case BMI2_E_REMAP_ERROR: + printf( + "Error [%d] : Remap error. It occurs due to failure in assigning the remap axes data for all the axes " "after change in axis position\r\n", + rslt); + break; + + case BMI2_E_GYR_USER_GAIN_UPD_FAIL: + printf( + "Error [%d] : Gyro user gain update fail error. It occurs when the reading of user gain update status " "fails\r\n", + rslt); + break; + + case BMI2_E_SELF_TEST_NOT_DONE: + printf( + "Error [%d] : Self-test not done error. It occurs when the self-test process is ongoing or not " "completed\r\n", + rslt); + break; + + case BMI2_E_INVALID_INPUT: + printf("Error [%d] : Invalid input error. It occurs when the sensor input validity fails\r\n", rslt); + break; + + case BMI2_E_INVALID_STATUS: + printf("Error [%d] : Invalid status error. It occurs when the feature/sensor validity fails\r\n", rslt); + break; + + case BMI2_E_CRT_ERROR: + printf("Error [%d] : CRT error. It occurs when the CRT test has failed\r\n", rslt); + break; + + case BMI2_E_ST_ALREADY_RUNNING: + printf( + "Error [%d] : Self-test already running error. It occurs when the self-test is already running and " "another has been initiated\r\n", + rslt); + break; + + case BMI2_E_CRT_READY_FOR_DL_FAIL_ABORT: + printf( + "Error [%d] : CRT ready for download fail abort error. It occurs when download in CRT fails due to wrong " "address location\r\n", + rslt); + break; + + case BMI2_E_DL_ERROR: + printf( + "Error [%d] : Download error. It occurs when write length exceeds that of the maximum burst length\r\n", + rslt); + break; + + case BMI2_E_PRECON_ERROR: + printf( + "Error [%d] : Pre-conditional error. It occurs when precondition to start the feature was not " "completed\r\n", + rslt); + break; + + case BMI2_E_ABORT_ERROR: + printf("Error [%d] : Abort error. It occurs when the device was shaken during CRT test\r\n", rslt); + break; + + case BMI2_E_WRITE_CYCLE_ONGOING: + printf( + "Error [%d] : Write cycle ongoing error. It occurs when the write cycle is already running and another " "has been initiated\r\n", + rslt); + break; + + case BMI2_E_ST_NOT_RUNING: + printf( + "Error [%d] : Self-test is not running error. It occurs when self-test running is disabled while it's " "running\r\n", + rslt); + break; + + case BMI2_E_DATA_RDY_INT_FAILED: + printf( + "Error [%d] : Data ready interrupt error. It occurs when the sample count exceeds the FOC sample limit " "and data ready status is not updated\r\n", + rslt); + break; + + case BMI2_E_INVALID_FOC_POSITION: + printf( + "Error [%d] : Invalid FOC position error. It occurs when average FOC data is obtained for the wrong" " axes\r\n", + rslt); + break; + + default: + printf("Error [%d] : Unknown error code\r\n", rslt); + break; + } +} + +/*! + * @brief Deinitializes coines platform + * + * @return void. + */ +void bmi2_coines_deinit(void) +{ + coines_close_comm_intf(COINES_COMM_INTF_USB); +} diff --git a/examples/bmi270/common/common.h b/examples/bmi270/common/common.h new file mode 100644 index 0000000..763983d --- /dev/null +++ b/examples/bmi270/common/common.h @@ -0,0 +1,122 @@ +/**\ + * Copyright (c) 2020 Bosch Sensortec GmbH. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + **/ + +#ifndef _COMMON_H +#define _COMMON_H + +/*! CPP guard */ +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include "bmi2.h" + +/*! + * @brief Function for reading the sensor's registers through I2C bus. + * + * @param[in] reg_addr : Register address. + * @param[out] reg_data : Pointer to the data buffer to store the read data. + * @param[in] length : No of bytes to read. + * @param[in] intf_ptr : Interface pointer + * + * @return Status of execution + * @retval = BMI2_INTF_RET_SUCCESS -> Success + * @retval != BMI2_INTF_RET_SUCCESS -> Failure Info + * + */ +BMI2_INTF_RETURN_TYPE bmi2_i2c_read(uint8_t reg_addr, uint8_t *reg_data, uint32_t len, void *intf_ptr); + +/*! + * @brief Function for writing the sensor's registers through I2C bus. + * + * @param[in] reg_addr : Register address. + * @param[in] reg_data : Pointer to the data buffer whose value is to be written. + * @param[in] length : No of bytes to write. + * @param[in] intf_ptr : Interface pointer + * + * @return Status of execution + * @retval = BMI2_INTF_RET_SUCCESS -> Success + * @retval != BMI2_INTF_RET_SUCCESS -> Failure Info + * + */ +BMI2_INTF_RETURN_TYPE bmi2_i2c_write(uint8_t reg_addr, const uint8_t *reg_data, uint32_t len, void *intf_ptr); + +/*! + * @brief Function for reading the sensor's registers through SPI bus. + * + * @param[in] reg_addr : Register address. + * @param[out] reg_data : Pointer to the data buffer to store the read data. + * @param[in] length : No of bytes to read. + * @param[in] intf_ptr : Interface pointer + * + * @return Status of execution + * @retval = BMI2_INTF_RET_SUCCESS -> Success + * @retval != BMI2_INTF_RET_SUCCESS -> Failure Info + * + */ +BMI2_INTF_RETURN_TYPE bmi2_spi_read(uint8_t reg_addr, uint8_t *reg_data, uint32_t len, void *intf_ptr); + +/*! + * @brief Function for writing the sensor's registers through SPI bus. + * + * @param[in] reg_addr : Register address. + * @param[in] reg_data : Pointer to the data buffer whose data has to be written. + * @param[in] length : No of bytes to write. + * @param[in] intf_ptr : Interface pointer + * + * @return Status of execution + * @retval = BMI2_INTF_RET_SUCCESS -> Success + * @retval != BMI2_INTF_RET_SUCCESS -> Failure Info + * + */ +BMI2_INTF_RETURN_TYPE bmi2_spi_write(uint8_t reg_addr, const uint8_t *reg_data, uint32_t len, void *intf_ptr); + +/*! + * @brief This function provides the delay for required time (Microsecond) as per the input provided in some of the + * APIs. + * + * @param[in] period_us : The required wait time in microsecond. + * @param[in] intf_ptr : Interface pointer + * + * @return void. + * + */ +void bmi2_delay_us(uint32_t period, void *intf_ptr); + +/*! + * @brief Function to select the interface between SPI and I2C. + * + * @param[in] bma : Structure instance of bmi2_dev + * @param[in] intf : Interface selection parameter + * + * @return Status of execution + * @retval 0 -> Success + * @retval < 0 -> Failure Info + */ +int8_t bmi2_interface_init(struct bmi2_dev *bma, uint8_t intf); + +/*! + * @brief Prints the execution status of the APIs. + * + * @param[in] rslt : Error code returned by the API whose execution status has to be printed. + * + * @return void. + */ +void bmi2_error_codes_print_result(int8_t rslt); + +/*! + * @brief Deinitializes coines platform + * + * @return void. + */ +void bmi2_coines_deinit(void); + +#ifdef __cplusplus +} +#endif /* End of CPP guard */ + +#endif /* _COMMON_H */ diff --git a/examples/bmi270/component_retrim/Makefile b/examples/bmi270/component_retrim/Makefile new file mode 100644 index 0000000..aad6a0b --- /dev/null +++ b/examples/bmi270/component_retrim/Makefile @@ -0,0 +1,18 @@ +COINES_INSTALL_PATH ?= ../../../.. + +EXAMPLE_FILE ?= component_retrim.c + +API_LOCATION ?= ../.. + +COMMON_LOCATION ?= .. + +C_SRCS += \ +$(API_LOCATION)/bmi2.c \ +$(API_LOCATION)/bmi270.c \ +$(COMMON_LOCATION)/common/common.c + +INCLUDEPATHS += \ +$(API_LOCATION) \ +$(COMMON_LOCATION)/common + +include $(COINES_INSTALL_PATH)/coines.mk \ No newline at end of file diff --git a/examples/bmi270/generic/component_retrim.c b/examples/bmi270/component_retrim/component_retrim.c similarity index 81% rename from examples/bmi270/generic/component_retrim.c rename to examples/bmi270/component_retrim/component_retrim.c index 53b5ed3..d85c148 100644 --- a/examples/bmi270/generic/component_retrim.c +++ b/examples/bmi270/component_retrim/component_retrim.c @@ -1,49 +1,52 @@ -/**\ - * Copyright (c) 2020 Bosch Sensortec GmbH. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - **/ - -/******************************************************************************/ -/*! Header Files */ -#include -#include "bmi2.h" -#include "bmi270.h" -#include "bmi2_common.h" - -/******************************************************************************/ -/*! Functions */ - -/* This function starts the execution of program. */ -int main(void) -{ - - /*! Sensor initialization configuration. */ - struct bmi2_dev bmi2_dev; - - /* Status of api are returned to this variable. */ - int8_t rslt; - - /* Initialize the dev structure */ - rslt = bmi2_interface_selection(&bmi2_dev); - bmi2_error_codes_print_result(rslt); - - /* Initialize bmi270. */ - rslt = bmi270_init(&bmi2_dev); - bmi2_error_codes_print_result(rslt); - - if (rslt == BMI2_OK) - { - /* This API runs the CRT process. */ - rslt = bmi2_do_crt(&bmi2_dev); - bmi2_error_codes_print_result(rslt); - - /* Do not move the board while doing CRT. If so, it will throw an abort error. */ - if (rslt == BMI2_OK) - { - printf("CRT successfully completed."); - } - } - - return rslt; -} +/**\ + * Copyright (c) 2020 Bosch Sensortec GmbH. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + **/ + +/******************************************************************************/ +/*! Header Files */ +#include +#include "bmi270.h" +#include "common.h" + +/******************************************************************************/ +/*! Functions */ + +/* This function starts the execution of program. */ +int main(void) +{ + /* Sensor initialization configuration. */ + struct bmi2_dev bmi2_dev; + + /* Status of api are returned to this variable. */ + int8_t rslt; + + /* Interface reference is given as a parameter + * For I2C : BMI2_I2C_INTF + * For SPI : BMI2_SPI_INTF + */ + rslt = bmi2_interface_init(&bmi2_dev, BMI2_I2C_INTF); + bmi2_error_codes_print_result(rslt); + + /* Initialize bmi270. */ + rslt = bmi270_init(&bmi2_dev); + bmi2_error_codes_print_result(rslt); + + if (rslt == BMI2_OK) + { + /* This API runs the CRT process. */ + rslt = bmi2_do_crt(&bmi2_dev); + bmi2_error_codes_print_result(rslt); + + /* Do not move the board while doing CRT. If so, it will throw an abort error. */ + if (rslt == BMI2_OK) + { + printf("CRT successfully completed."); + } + } + + bmi2_coines_deinit(); + + return rslt; +} diff --git a/examples/bmi270/fifo_full_header_mode/Makefile b/examples/bmi270/fifo_full_header_mode/Makefile new file mode 100644 index 0000000..83a8f49 --- /dev/null +++ b/examples/bmi270/fifo_full_header_mode/Makefile @@ -0,0 +1,18 @@ +COINES_INSTALL_PATH ?= ../../../.. + +EXAMPLE_FILE ?= fifo_full_header_mode.c + +API_LOCATION ?= ../.. + +COMMON_LOCATION ?= .. + +C_SRCS += \ +$(API_LOCATION)/bmi2.c \ +$(API_LOCATION)/bmi270.c \ +$(COMMON_LOCATION)/common/common.c + +INCLUDEPATHS += \ +$(API_LOCATION) \ +$(COMMON_LOCATION)/common + +include $(COINES_INSTALL_PATH)/coines.mk \ No newline at end of file diff --git a/examples/bmi270/generic/fifo_full_header_mode.c b/examples/bmi270/fifo_full_header_mode/fifo_full_header_mode.c similarity index 82% rename from examples/bmi270/generic/fifo_full_header_mode.c rename to examples/bmi270/fifo_full_header_mode/fifo_full_header_mode.c index d31b393..2118c24 100644 --- a/examples/bmi270/generic/fifo_full_header_mode.c +++ b/examples/bmi270/fifo_full_header_mode/fifo_full_header_mode.c @@ -1,298 +1,315 @@ -/**\ - * Copyright (c) 2020 Bosch Sensortec GmbH. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - **/ - -/******************************************************************************/ -/*! Header Files */ -#include -#include "bmi2.h" -#include "bmi270.h" -#include "bmi2_common.h" - -/******************************************************************************/ -/*! Macros */ - -/*! Buffer size allocated to store raw FIFO data. */ -#define BMI270_FIFO_RAW_DATA_BUFFER_SIZE UINT16_C(2048) - -/*! Length of data to be read from FIFO. */ -#define BMI270_FIFO_RAW_DATA_USER_LENGTH UINT16_C(2048) - -/*! Number of accel frames to be extracted from FIFO. */ - -/*! Calculation for frame count: Total frame count = Fifo buffer size(2048)/ Total frames(6 Accel, 6 Gyro and 1 header, - * totaling to 13) which equals to 157. - */ -#define BMI270_FIFO_ACCEL_FRAME_COUNT UINT8_C(157) - -/*! Number of gyro frames to be extracted from FIFO. */ -#define BMI270_FIFO_GYRO_FRAME_COUNT UINT8_C(157) - -/*! Macro to read sensortime byte in FIFO. */ -#define SENSORTIME_OVERHEAD_BYTE UINT8_C(3) - -/******************************************************************************/ -/*! Static Function Declaration */ - -/*! - * @brief This internal API is used to set configurations for accel and gyro. - * @param[in] dev : Structure instance of bmi2_dev. - * @return Status of execution. - */ -static int8_t set_accel_gyro_config(struct bmi2_dev *dev); - -/******************************************************************************/ - -/* This function starts the execution of program. */ -int main(void) -{ - - /* Status of api are returned to this variable. */ - int8_t rslt; - - uint16_t index = 0; - uint16_t fifo_length = 0; - uint16_t config = 0; - - /* Variable to hold sensor time */ - uint32_t sensor_time = 0; - - /* To read sensortime, extra 3 bytes are added to fifo buffer. */ - uint16_t fifo_buffer_size = BMI270_FIFO_RAW_DATA_BUFFER_SIZE + SENSORTIME_OVERHEAD_BYTE; - - /* Variable to get fifo full interrupt status. */ - uint16_t int_status = 0; - - uint16_t accel_frame_length; - - uint16_t gyro_frame_length; - - /* Variable to store the available frame length count in FIFO */ - uint8_t frame_count; - - /* Number of bytes of FIFO data. */ - uint8_t fifo_data[fifo_buffer_size]; - - /* Sensor initialization configuration. */ - struct bmi2_dev bmi2_dev; - - /* Array of accelerometer frames -> Total bytes = - * 157 * (6 axes + 1 header bytes) = 1099 bytes */ - struct bmi2_sens_axes_data fifo_accel_data[BMI270_FIFO_ACCEL_FRAME_COUNT] = { 0 }; - - /* Array of gyro frames -> Total bytes = - * 157 * (6 axes + 1 header bytes) = 1099 bytes */ - struct bmi2_sens_axes_data fifo_gyro_data[BMI270_FIFO_GYRO_FRAME_COUNT] = { 0 }; - - /* Initialize FIFO frame structure. */ - struct bmi2_fifo_frame fifoframe = { 0 }; - - /* Accel and gyro sensor are listed in array. */ - uint8_t sensor_sel[2] = { BMI2_ACCEL, BMI2_GYRO }; - - /* Initialize the dev structure */ - rslt = bmi2_interface_selection(&bmi2_dev); - bmi2_error_codes_print_result(rslt); - - /* Initialize bmi270. */ - rslt = bmi270_init(&bmi2_dev); - bmi2_error_codes_print_result(rslt); - - /* Enable accel and gyro sensor. */ - rslt = bmi2_sensor_enable(sensor_sel, 2, &bmi2_dev); - bmi2_error_codes_print_result(rslt); - - /* Configuration settings for accel and gyro. */ - rslt = set_accel_gyro_config(&bmi2_dev); - bmi2_error_codes_print_result(rslt); - - /* Before setting FIFO, disable the advance power save mode. */ - rslt = bmi2_set_adv_power_save(BMI2_DISABLE, &bmi2_dev); - bmi2_error_codes_print_result(rslt); - - /* Initially disable all configurations in fifo. */ - rslt = bmi2_get_fifo_config(&config, &bmi2_dev); - bmi2_error_codes_print_result(rslt); - - /* Initially disable all configurations in fifo. */ - rslt = bmi2_set_fifo_config(BMI2_FIFO_ALL_EN, BMI2_DISABLE, &bmi2_dev); - bmi2_error_codes_print_result(rslt); - - /* Update FIFO structure. */ - /* Mapping the buffer to store the fifo data. */ - fifoframe.data = fifo_data; - - /* Length of FIFO frame. */ - /* To read sensortime, extra 3 bytes are added to fifo user length. */ - fifoframe.length = BMI270_FIFO_RAW_DATA_USER_LENGTH + SENSORTIME_OVERHEAD_BYTE; - - /* Set FIFO configuration by enabling accel, gyro and timestamp. - * NOTE 1: The header mode is enabled by default. - * NOTE 2: By default the FIFO operating mode is in FIFO mode. - * NOTE 3: Sensortime is enabled by default */ - printf("FIFO is configured in header mode\n"); - rslt = bmi2_set_fifo_config(BMI2_FIFO_ACC_EN | BMI2_FIFO_GYR_EN, BMI2_ENABLE, &bmi2_dev); - bmi2_error_codes_print_result(rslt); - - /* Map FIFO full interrupt. */ - fifoframe.data_int_map = BMI2_FFULL_INT; - rslt = bmi2_map_data_int(fifoframe.data_int_map, BMI2_INT1, &bmi2_dev); - bmi2_error_codes_print_result(rslt); - while (1) - { - - /* Read FIFO data on interrupt. */ - rslt = bmi2_get_int_status(&int_status, &bmi2_dev); - bmi2_error_codes_print_result(rslt); - - if ((rslt == BMI2_OK) && (int_status & BMI2_FFULL_INT_STATUS_MASK)) - { - rslt = bmi2_get_fifo_length(&fifo_length, &bmi2_dev); - bmi2_error_codes_print_result(rslt); - - accel_frame_length = BMI270_FIFO_ACCEL_FRAME_COUNT; - gyro_frame_length = BMI270_FIFO_GYRO_FRAME_COUNT; - - printf("\nFIFO data bytes available : %d \n", fifo_length); - printf("\nFIFO data bytes requested : %d \n", fifoframe.length); - - /* Read FIFO data. */ - rslt = bmi2_read_fifo_data(&fifoframe, &bmi2_dev); - bmi2_error_codes_print_result(rslt); - - if (rslt == BMI2_OK) - { - printf("\nFIFO accel frames requested : %d \n", accel_frame_length); - - /* Parse the FIFO data to extract accelerometer data from the FIFO buffer. */ - rslt = bmi2_extract_accel(fifo_accel_data, &accel_frame_length, &fifoframe, &bmi2_dev); - printf("\nFIFO accel frames extracted : %d \n", accel_frame_length); - - printf("\nFIFO gyro frames requested : %d \n", gyro_frame_length); - - /* Parse the FIFO data to extract gyro data from the FIFO buffer. */ - rslt = bmi2_extract_gyro(fifo_gyro_data, &gyro_frame_length, &fifoframe, &bmi2_dev); - printf("\nFIFO gyro frames extracted : %d \n", gyro_frame_length); - - /* Calculating the frame count from the available bytes in FIFO - * frame_length = (available_fifo_bytes / (acc_frame_len + gyro_frame_len + header_byte)) */ - frame_count = (fifo_length / (BMI2_FIFO_ACC_GYR_LENGTH + 1)); - printf("\nAvailable frame count from available bytes: %d\n", frame_count); - - printf("\nExtracted accel frames\n"); - - /* Print the parsed accelerometer data from the FIFO buffer. */ - for (index = 0; index < frame_count; index++) - { - printf("ACCEL[%d] X : %d\t Y : %d\t Z : %d\n", index, fifo_accel_data[index].x, - fifo_accel_data[index].y, fifo_accel_data[index].z); - } - - printf("\nExtracted gyro frames\n"); - - /* Print the parsed gyro data from the FIFO buffer. */ - for (index = 0; index < frame_count; index++) - { - printf("GYRO[%d] X : %d\t Y : %d\t Z : %d\n", - index, - fifo_gyro_data[index].x, - fifo_gyro_data[index].y, - fifo_gyro_data[index].z); - } - - /* Print control frames like sensor time and skipped frame count. */ - printf("\nSkipped frame count = %d\n", fifoframe.skipped_frame_count); - - printf("Sensor time = %lu\r\n", fifoframe.sensor_time); - } - - break; - } - } - - return rslt; -} - -/*! - * @brief This internal API is used to set configurations for accel and gyro. - */ -static int8_t set_accel_gyro_config(struct bmi2_dev *bmi2_dev) -{ - - /* Status of api are returned to this variable. */ - int8_t rslt; - - /* Structure to define accel and gyro configurations. */ - struct bmi2_sens_config config[2]; - - /* Configure the type of feature. */ - config[0].type = BMI2_ACCEL; - config[1].type = BMI2_GYRO; - - /* Get default configurations for the type of feature selected. */ - rslt = bmi2_get_sensor_config(config, 2, bmi2_dev); - bmi2_error_codes_print_result(rslt); - - if (rslt == BMI2_OK) - { - - /* NOTE: The user can change the following configuration parameters according to their requirement. */ - /* Accel configuration settings. */ - /* Output Data Rate. By default ODR is set as 100Hz for accel. */ - config[0].cfg.acc.odr = BMI2_ACC_ODR_100HZ; - - /* Gravity range of the sensor (+/- 2G, 4G, 8G, 16G). */ - config[0].cfg.acc.range = BMI2_ACC_RANGE_2G; - - /* The bandwidth parameter is used to configure the number of sensor samples that are averaged - * if it is set to 2, then 2^(bandwidth parameter) samples - * are averaged, resulting in 4 averaged samples - * Note1 : For more information, refer the datasheet. - * Note2 : A higher number of averaged samples will result in a lower noise level of the signal, but - * this has an adverse effect on the power consumed. - */ - config[0].cfg.acc.bwp = BMI2_ACC_NORMAL_AVG4; - - /* Enable the filter performance mode where averaging of samples - * will be done based on above set bandwidth and ODR. - * There are two modes - * 0 -> Ultra low power mode - * 1 -> High performance mode(Default) - * For more info refer datasheet. - */ - config[0].cfg.acc.filter_perf = BMI2_PERF_OPT_MODE; - - /* Gyro configuration settings. */ - /* Output data Rate. Default ODR is 200Hz, setting to 100Hz. */ - config[1].cfg.gyr.odr = BMI2_GYR_ODR_100HZ; - - /* Gyroscope Angular Rate Measurement Range.By default the range is 2000dps. */ - config[1].cfg.gyr.range = BMI2_GYR_RANGE_2000; - - /* Gyroscope Bandwidth parameters. By default the gyro bandwidth is in normal mode. */ - config[1].cfg.gyr.bwp = BMI2_GYR_NORMAL_MODE; - - /* Enable/Disable the noise performance mode for precision yaw rate sensing - * There are two modes - * 0 -> Ultra low power mode(Default) - * 1 -> High performance mode - */ - config[1].cfg.gyr.noise_perf = BMI2_POWER_OPT_MODE; - - /* Enable/Disable the filter performance mode where averaging of samples - * will be done based on above set bandwidth and ODR. - * There are two modes - * 0 -> Ultra low power mode - * 1 -> High performance mode(Default) - */ - config[1].cfg.gyr.filter_perf = BMI2_PERF_OPT_MODE; - - /* Set new configurations. */ - rslt = bmi2_set_sensor_config(config, 2, bmi2_dev); - bmi2_error_codes_print_result(rslt); - } - - return rslt; -} +/**\ + * Copyright (c) 2020 Bosch Sensortec GmbH. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + **/ + +/******************************************************************************/ +/*! Header Files */ +#include +#include "bmi270.h" +#include "common.h" + +/******************************************************************************/ +/*! Macros */ + +/*! Buffer size allocated to store raw FIFO data. */ +#define BMI2_FIFO_RAW_DATA_BUFFER_SIZE UINT16_C(2048) + +/*! Length of data to be read from FIFO. */ +#define BMI2_FIFO_RAW_DATA_USER_LENGTH UINT16_C(2048) + +/*! Number of accel frames to be extracted from FIFO. */ + +/*! Calculation for frame count: Total frame count = Fifo buffer size(2048)/ Total frames(6 Accel, 6 Gyro and 1 header, + * totaling to 13) which equals to 157. + */ +#define BMI2_FIFO_ACCEL_FRAME_COUNT UINT8_C(157) + +/*! Number of gyro frames to be extracted from FIFO. */ +#define BMI2_FIFO_GYRO_FRAME_COUNT UINT8_C(157) + +/*! Macro to read sensortime byte in FIFO. */ +#define SENSORTIME_OVERHEAD_BYTE UINT8_C(3) + +/******************************************************************************/ +/*! Static Function Declaration */ + +/*! + * @brief This internal API is used to set configurations for accel and gyro. + * @param[in] dev : Structure instance of bmi2_dev. + * @return Status of execution. + */ +static int8_t set_accel_gyro_config(struct bmi2_dev *dev); + +/******************************************************************************/ + +/* This function starts the execution of program. */ +int main(void) +{ + /* Status of api are returned to this variable. */ + int8_t rslt; + + uint16_t index = 0; + uint16_t fifo_length = 0; + uint16_t config = 0; + + /* To read sensortime, extra 3 bytes are added to fifo buffer. */ + uint16_t fifo_buffer_size = BMI2_FIFO_RAW_DATA_BUFFER_SIZE + SENSORTIME_OVERHEAD_BYTE; + + /* Variable to get fifo full interrupt status. */ + uint16_t int_status = 0; + + uint16_t accel_frame_length = BMI2_FIFO_ACCEL_FRAME_COUNT; + + uint16_t gyro_frame_length = BMI2_FIFO_GYRO_FRAME_COUNT; + + /* Variable to store the available frame length count in FIFO */ + uint8_t frame_count; + + int8_t try = 1; + + /* Number of bytes of FIFO data. */ + uint8_t fifo_data[fifo_buffer_size]; + + /* Sensor initialization configuration. */ + struct bmi2_dev bmi2_dev; + + /* Array of accelerometer frames -> Total bytes = + * 157 * (6 axes + 1 header bytes) = 1099 bytes */ + struct bmi2_sens_axes_data fifo_accel_data[BMI2_FIFO_ACCEL_FRAME_COUNT] = { { 0 } }; + + /* Array of gyro frames -> Total bytes = + * 157 * (6 axes + 1 header bytes) = 1099 bytes */ + struct bmi2_sens_axes_data fifo_gyro_data[BMI2_FIFO_GYRO_FRAME_COUNT] = { { 0 } }; + + /* Initialize FIFO frame structure. */ + struct bmi2_fifo_frame fifoframe = { 0 }; + + /* Accel and gyro sensor are listed in array. */ + uint8_t sensor_sel[2] = { BMI2_ACCEL, BMI2_GYRO }; + + /* Interface reference is given as a parameter + * For I2C : BMI2_I2C_INTF + * For SPI : BMI2_SPI_INTF + */ + rslt = bmi2_interface_init(&bmi2_dev, BMI2_I2C_INTF); + bmi2_error_codes_print_result(rslt); + + /* Initialize bmi270. */ + rslt = bmi270_init(&bmi2_dev); + bmi2_error_codes_print_result(rslt); + + /* Enable accel and gyro sensor. */ + rslt = bmi270_sensor_enable(sensor_sel, 2, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + /* Configuration settings for accel and gyro. */ + rslt = set_accel_gyro_config(&bmi2_dev); + bmi2_error_codes_print_result(rslt); + + /* Before setting FIFO, disable the advance power save mode. */ + rslt = bmi2_set_adv_power_save(BMI2_DISABLE, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + /* Initially disable all configurations in fifo. */ + rslt = bmi2_get_fifo_config(&config, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + /* Initially disable all configurations in fifo. */ + rslt = bmi2_set_fifo_config(BMI2_FIFO_ALL_EN, BMI2_DISABLE, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + /* Update FIFO structure. */ + /* Mapping the buffer to store the fifo data. */ + fifoframe.data = fifo_data; + + /* Length of FIFO frame. */ + /* To read sensortime, extra 3 bytes are added to fifo user length. */ + fifoframe.length = BMI2_FIFO_RAW_DATA_USER_LENGTH + SENSORTIME_OVERHEAD_BYTE; + + /* Set FIFO configuration by enabling accel, gyro and timestamp. + * NOTE 1: The header mode is enabled by default. + * NOTE 2: By default the FIFO operating mode is in FIFO mode. + * NOTE 3: Sensortime is enabled by default */ + printf("FIFO is configured in header mode\n"); + rslt = bmi2_set_fifo_config(BMI2_FIFO_ACC_EN | BMI2_FIFO_GYR_EN, BMI2_ENABLE, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + /* Map FIFO full interrupt. */ + fifoframe.data_int_map = BMI2_FFULL_INT; + rslt = bmi2_map_data_int(fifoframe.data_int_map, BMI2_INT1, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + while (try <= 10) + { + /* Read FIFO data on interrupt. */ + rslt = bmi2_get_int_status(&int_status, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + if ((rslt == BMI2_OK) && (int_status & BMI2_FFULL_INT_STATUS_MASK)) + { + printf("\nIteration : %d\n", try); + + accel_frame_length = BMI2_FIFO_ACCEL_FRAME_COUNT; + + gyro_frame_length = BMI2_FIFO_GYRO_FRAME_COUNT; + + rslt = bmi2_get_fifo_length(&fifo_length, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + printf("\nFIFO data bytes available : %d \n", fifo_length); + printf("\nFIFO data bytes requested : %d \n", fifoframe.length); + + /* Read FIFO data. */ + rslt = bmi2_read_fifo_data(&fifoframe, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + /* Read FIFO data on interrupt. */ + rslt = bmi2_get_int_status(&int_status, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + if (rslt == BMI2_OK) + { + printf("\nFIFO accel frames requested : %d \n", accel_frame_length); + + /* Parse the FIFO data to extract accelerometer data from the FIFO buffer. */ + rslt = bmi2_extract_accel(fifo_accel_data, &accel_frame_length, &fifoframe, &bmi2_dev); + printf("\nFIFO accel frames extracted : %d \n", accel_frame_length); + + printf("\nFIFO gyro frames requested : %d \n", gyro_frame_length); + + /* Parse the FIFO data to extract gyro data from the FIFO buffer. */ + rslt = bmi2_extract_gyro(fifo_gyro_data, &gyro_frame_length, &fifoframe, &bmi2_dev); + printf("\nFIFO gyro frames extracted : %d \n", gyro_frame_length); + + /* Calculating the frame count from the available bytes in FIFO + * frame_length = (available_fifo_bytes / (acc_frame_len + gyro_frame_len + header_byte)) */ + frame_count = (fifo_length / (BMI2_FIFO_ACC_GYR_LENGTH + 1)); + printf("\nAvailable frame count from available bytes: %d\n", frame_count); + + printf("\nExtracted accel frames\n"); + + if (accel_frame_length > frame_count) + { + accel_frame_length = frame_count; + } + + /* Print the parsed accelerometer data from the FIFO buffer. */ + for (index = 0; index < accel_frame_length; index++) + { + printf("ACCEL[%d] X : %d\t Y : %d\t Z : %d\n", index, fifo_accel_data[index].x, + fifo_accel_data[index].y, fifo_accel_data[index].z); + } + + printf("\nExtracted gyro frames\n"); + + if (gyro_frame_length > frame_count) + { + gyro_frame_length = frame_count; + } + + /* Print the parsed gyro data from the FIFO buffer. */ + for (index = 0; index < gyro_frame_length; index++) + { + printf("GYRO[%d] X : %d\t Y : %d\t Z : %d\n", + index, + fifo_gyro_data[index].x, + fifo_gyro_data[index].y, + fifo_gyro_data[index].z); + } + + /* Print control frames like sensor time and skipped frame count. */ + printf("\nSkipped frame count = %d\n", fifoframe.skipped_frame_count); + + printf("Sensor time = %lu\r\n", fifoframe.sensor_time); + + try++; + } + } + } + + bmi2_coines_deinit(); + + return rslt; +} + +/*! + * @brief This internal API is used to set configurations for accel and gyro. + */ +static int8_t set_accel_gyro_config(struct bmi2_dev *bmi2_dev) +{ + /* Status of api are returned to this variable. */ + int8_t rslt; + + /* Structure to define accel and gyro configurations. */ + struct bmi2_sens_config config[2]; + + /* Configure the type of feature. */ + config[0].type = BMI2_ACCEL; + config[1].type = BMI2_GYRO; + + /* Get default configurations for the type of feature selected. */ + rslt = bmi270_get_sensor_config(config, 2, bmi2_dev); + bmi2_error_codes_print_result(rslt); + + if (rslt == BMI2_OK) + { + /* NOTE: The user can change the following configuration parameters according to their requirement. */ + /* Accel configuration settings. */ + /* Set Output Data Rate */ + config[0].cfg.acc.odr = BMI2_ACC_ODR_25HZ; + + /* Gravity range of the sensor (+/- 2G, 4G, 8G, 16G). */ + config[0].cfg.acc.range = BMI2_ACC_RANGE_2G; + + /* The bandwidth parameter is used to configure the number of sensor samples that are averaged + * if it is set to 2, then 2^(bandwidth parameter) samples + * are averaged, resulting in 4 averaged samples + * Note1 : For more information, refer the datasheet. + * Note2 : A higher number of averaged samples will result in a lower noise level of the signal, but + * this has an adverse effect on the power consumed. + */ + config[0].cfg.acc.bwp = BMI2_ACC_NORMAL_AVG4; + + /* Enable the filter performance mode where averaging of samples + * will be done based on above set bandwidth and ODR. + * There are two modes + * 0 -> Ultra low power mode + * 1 -> High performance mode(Default) + * For more info refer datasheet. + */ + config[0].cfg.acc.filter_perf = BMI2_PERF_OPT_MODE; + + /* Gyro configuration settings. */ + /* Set Output Data Rate */ + config[1].cfg.gyr.odr = BMI2_GYR_ODR_25HZ; + + /* Gyroscope Angular Rate Measurement Range.By default the range is 2000dps. */ + config[1].cfg.gyr.range = BMI2_GYR_RANGE_2000; + + /* Gyroscope Bandwidth parameters. By default the gyro bandwidth is in normal mode. */ + config[1].cfg.gyr.bwp = BMI2_GYR_NORMAL_MODE; + + /* Enable/Disable the noise performance mode for precision yaw rate sensing + * There are two modes + * 0 -> Ultra low power mode(Default) + * 1 -> High performance mode + */ + config[1].cfg.gyr.noise_perf = BMI2_POWER_OPT_MODE; + + /* Enable/Disable the filter performance mode where averaging of samples + * will be done based on above set bandwidth and ODR. + * There are two modes + * 0 -> Ultra low power mode + * 1 -> High performance mode(Default) + */ + config[1].cfg.gyr.filter_perf = BMI2_PERF_OPT_MODE; + + /* Set new configurations. */ + rslt = bmi270_set_sensor_config(config, 2, bmi2_dev); + bmi2_error_codes_print_result(rslt); + } + + return rslt; +} diff --git a/examples/bmi270/fifo_full_headerless_mode/Makefile b/examples/bmi270/fifo_full_headerless_mode/Makefile new file mode 100644 index 0000000..ae9a413 --- /dev/null +++ b/examples/bmi270/fifo_full_headerless_mode/Makefile @@ -0,0 +1,18 @@ +COINES_INSTALL_PATH ?= ../../../.. + +EXAMPLE_FILE ?= fifo_full_headerless_mode.c + +API_LOCATION ?= ../.. + +COMMON_LOCATION ?= .. + +C_SRCS += \ +$(API_LOCATION)/bmi2.c \ +$(API_LOCATION)/bmi270.c \ +$(COMMON_LOCATION)/common/common.c + +INCLUDEPATHS += \ +$(API_LOCATION) \ +$(COMMON_LOCATION)/common + +include $(COINES_INSTALL_PATH)/coines.mk \ No newline at end of file diff --git a/examples/bmi270/generic/fifo_full_headerless_mode.c b/examples/bmi270/fifo_full_headerless_mode/fifo_full_headerless_mode.c similarity index 83% rename from examples/bmi270/generic/fifo_full_headerless_mode.c rename to examples/bmi270/fifo_full_headerless_mode/fifo_full_headerless_mode.c index 2eb209a..53dddc4 100644 --- a/examples/bmi270/generic/fifo_full_headerless_mode.c +++ b/examples/bmi270/fifo_full_headerless_mode/fifo_full_headerless_mode.c @@ -1,284 +1,304 @@ -/**\ - * Copyright (c) 2020 Bosch Sensortec GmbH. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - **/ - -/******************************************************************************/ -/*! Header Files */ -#include -#include "bmi2.h" -#include "bmi270.h" -#include "bmi2_common.h" - -/******************************************************************************/ -/*! Macros */ - -/*! Buffer size allocated to store raw FIFO data */ -#define BMI270_FIFO_RAW_DATA_BUFFER_SIZE UINT16_C(2048) - -/*! Length of data to be read from FIFO */ -#define BMI270_FIFO_RAW_DATA_USER_LENGTH UINT16_C(2048) - -/*! Number of accel frames to be extracted from FIFO */ - -/*! Calculation for frame count: Total frame count = Fifo buffer size(2048)/ Total frames(6 Accel, 6 Gyro totaling to - * 12) which equals to 170. - */ -#define BMI270_FIFO_ACCEL_FRAME_COUNT UINT8_C(167) - -/*! Number of gyro frames to be extracted from FIFO */ -#define BMI270_FIFO_GYRO_FRAME_COUNT UINT8_C(167) - -/******************************************************************************/ -/*! Static Function Declaration */ - -/*! - * @brief This internal API is used to set configurations for accel and gyro. - * @param[in] dev : Structure instance of bmi2_dev. - * @return Status of execution. - */ -static int8_t set_accel_gyro_config(struct bmi2_dev *dev); - -/******************************************************************************/ - -/* This function starts the execution of program. */ -int main(void) -{ - - /* Status of api are returned to this variable. */ - int8_t rslt; - - uint16_t index = 0; - uint16_t fifo_length = 0; - - /* Variable to get fifo full interrupt status. */ - uint16_t int_status = 0; - - uint16_t accel_frame_length; - - uint16_t gyro_frame_length; - - /* Variable to store the available frame length count in FIFO */ - uint8_t frame_count; - - /* Number of bytes of FIFO data. */ - uint8_t fifo_data[BMI270_FIFO_RAW_DATA_BUFFER_SIZE] = { 0 }; - - /* Sensor initialization configuration. */ - struct bmi2_dev bmi2_dev; - - /* Array of accelerometer frames -> Total bytes = - * 170 * (6 axes bytes) = 1020 bytes */ - struct bmi2_sens_axes_data fifo_accel_data[BMI270_FIFO_ACCEL_FRAME_COUNT] = { 0 }; - - /* Array of gyro frames -> Total bytes = - * 170 * (6 axes bytes) = 1020 bytes */ - struct bmi2_sens_axes_data fifo_gyro_data[BMI270_FIFO_GYRO_FRAME_COUNT] = { 0 }; - - /* Initialize FIFO frame structure. */ - struct bmi2_fifo_frame fifoframe = { 0 }; - - /* Accel and gyro sensor are listed in array. */ - uint8_t sensor_sel[2] = { BMI2_ACCEL, BMI2_GYRO }; - - /* Initialize the dev structure */ - rslt = bmi2_interface_selection(&bmi2_dev); - bmi2_error_codes_print_result(rslt); - - /* Initialize bmi270. */ - rslt = bmi270_init(&bmi2_dev); - bmi2_error_codes_print_result(rslt); - - /* Enable accel and gyro sensor. */ - rslt = bmi2_sensor_enable(sensor_sel, 2, &bmi2_dev); - bmi2_error_codes_print_result(rslt); - - /* Configuration settings for accel and gyro. */ - rslt = set_accel_gyro_config(&bmi2_dev); - bmi2_error_codes_print_result(rslt); - - /* Before setting FIFO, disable the advance power save mode. */ - rslt = bmi2_set_adv_power_save(BMI2_DISABLE, &bmi2_dev); - bmi2_error_codes_print_result(rslt); - - /* Initially disable all configurations in fifo. */ - rslt = bmi2_set_fifo_config(BMI2_FIFO_ALL_EN, BMI2_DISABLE, &bmi2_dev); - bmi2_error_codes_print_result(rslt); - - /* Update FIFO structure. */ - /* Mapping the buffer to store the fifo data. */ - fifoframe.data = fifo_data; - - /* Length of FIFO frame. */ - fifoframe.length = BMI270_FIFO_RAW_DATA_USER_LENGTH; - - /* Set FIFO configuration by enabling accel, gyro. - * NOTE 1: The header mode is enabled by default. - * NOTE 2: By default the FIFO operating mode is FIFO mode. */ - rslt = bmi2_set_fifo_config(BMI2_FIFO_ACC_EN | BMI2_FIFO_GYR_EN, BMI2_ENABLE, &bmi2_dev); - bmi2_error_codes_print_result(rslt); - - printf("FIFO is configured in headerless mode\n"); - - /* To enable headerless mode, disable the header. */ - if (rslt == BMI2_OK) - { - rslt = bmi2_set_fifo_config(BMI2_FIFO_HEADER_EN, BMI2_DISABLE, &bmi2_dev); - } - - /* Map FIFO full interrupt. */ - fifoframe.data_int_map = BMI2_FFULL_INT; - rslt = bmi2_map_data_int(fifoframe.data_int_map, BMI2_INT1, &bmi2_dev); - bmi2_error_codes_print_result(rslt); - - while (1) - { - - /* Read FIFO data on interrupt. */ - rslt = bmi2_get_int_status(&int_status, &bmi2_dev); - bmi2_error_codes_print_result(rslt); - - if ((rslt == BMI2_OK) && (int_status & BMI2_FFULL_INT_STATUS_MASK)) - { - rslt = bmi2_get_fifo_length(&fifo_length, &bmi2_dev); - bmi2_error_codes_print_result(rslt); - - accel_frame_length = BMI270_FIFO_ACCEL_FRAME_COUNT; - gyro_frame_length = BMI270_FIFO_GYRO_FRAME_COUNT; - - printf("\nFIFO data bytes available : %d \n", fifo_length); - printf("\nFIFO data bytes requested : %d \n", fifoframe.length); - - /* Read FIFO data. */ - rslt = bmi2_read_fifo_data(&fifoframe, &bmi2_dev); - bmi2_error_codes_print_result(rslt); - - if (rslt == BMI2_OK) - { - printf("\nFIFO accel frames requested : %d \n", accel_frame_length); - - /* Parse the FIFO data to extract accelerometer data from the FIFO buffer. */ - rslt = bmi2_extract_accel(fifo_accel_data, &accel_frame_length, &fifoframe, &bmi2_dev); - printf("\nFIFO accel frames extracted : %d \n", accel_frame_length); - - printf("\nFIFO gyro frames requested : %d \n", gyro_frame_length); - - /* Parse the FIFO data to extract gyro data from the FIFO buffer. */ - rslt = bmi2_extract_gyro(fifo_gyro_data, &gyro_frame_length, &fifoframe, &bmi2_dev); - printf("\nFIFO gyro frames extracted : %d \n", gyro_frame_length); - - /* Calculating the frame count from the available bytes in FIFO - * frame_length = (available_fifo_bytes / (acc_frame_len + gyro_frame_len)) */ - frame_count = (fifo_length / (BMI2_FIFO_ACC_GYR_LENGTH)); - printf("\nAvailable frame count from available bytes: %d\n", frame_count); - - printf("\nExtracted accel frames\n"); - - /* Print the parsed accelerometer data from the FIFO buffer. */ - for (index = 0; index < frame_count; index++) - { - printf("ACCEL[%d] X : %d\t Y : %d\t Z : %d\n", index, fifo_accel_data[index].x, - fifo_accel_data[index].y, fifo_accel_data[index].z); - } - - printf("\nExtracted gyro frames\n"); - - /* Print the parsed gyro data from the FIFO buffer. */ - for (index = 0; index < frame_count; index++) - { - printf("GYRO[%d] X : %d\t Y : %d\t Z : %d\n", - index, - fifo_gyro_data[index].x, - fifo_gyro_data[index].y, - fifo_gyro_data[index].z); - } - } - - break; - } - } - - return rslt; -} - -/*! - * @brief This internal API is used to set configurations for accel and gyro. - */ -static int8_t set_accel_gyro_config(struct bmi2_dev *bmi2_dev) -{ - - /* Status of api are returned to this variable. */ - int8_t rslt; - - /* Structure to define accel and gyro configurations. */ - struct bmi2_sens_config config[2]; - - /* Configure the type of feature. */ - config[0].type = BMI2_ACCEL; - config[1].type = BMI2_GYRO; - - /* Get default configurations for the type of feature selected. */ - rslt = bmi2_get_sensor_config(config, 2, bmi2_dev); - bmi2_error_codes_print_result(rslt); - - if (rslt == BMI2_OK) - { - /* NOTE: The user can change the following configuration parameters according to their requirement. */ - /* Accel configuration settings. */ - /* Output Data Rate. By default ODR is set as 100Hz for accel. */ - config[0].cfg.acc.odr = BMI2_ACC_ODR_100HZ; - - /* Gravity range of the sensor (+/- 2G, 4G, 8G, 16G). */ - config[0].cfg.acc.range = BMI2_ACC_RANGE_2G; - - /* The bandwidth parameter is used to configure the number of sensor samples that are averaged - * if it is set to 2, then 2^(bandwidth parameter) samples - * are averaged, resulting in 4 averaged samples - * Note1 : For more information, refer the datasheet. - * Note2 : A higher number of averaged samples will result in a lower noise level of the signal, but - * this has an adverse effect on the power consumed. - */ - config[0].cfg.acc.bwp = BMI2_ACC_NORMAL_AVG4; - - /* Enable the filter performance mode where averaging of samples - * will be done based on above set bandwidth and ODR. - * There are two modes - * 0 -> Ultra low power mode - * 1 -> High performance mode(Default) - * For more info refer datasheet. - */ - config[0].cfg.acc.filter_perf = BMI2_PERF_OPT_MODE; - - /* Gyro configuration settings. */ - /* Output data Rate. Default ODR is 200Hz, setting to 100Hz. */ - config[1].cfg.gyr.odr = BMI2_GYR_ODR_100HZ; - - /* Gyroscope Angular Rate Measurement Range.By default the range is 2000dps. */ - config[1].cfg.gyr.range = BMI2_GYR_RANGE_2000; - - /* Gyroscope Bandwidth parameters. By default the gyro bandwidth is in normal mode. */ - config[1].cfg.gyr.bwp = BMI2_GYR_NORMAL_MODE; - - /* Enable/Disable the noise performance mode for precision yaw rate sensing - * There are two modes - * 0 -> Ultra low power mode(Default) - * 1 -> High performance mode - */ - config[1].cfg.gyr.noise_perf = BMI2_POWER_OPT_MODE; - - /* Enable/Disable the filter performance mode where averaging of samples - * will be done based on above set bandwidth and ODR. - * There are two modes - * 0 -> Ultra low power mode - * 1 -> High performance mode(Default) - */ - config[1].cfg.gyr.filter_perf = BMI2_PERF_OPT_MODE; - - /* Set new configurations. */ - rslt = bmi2_set_sensor_config(config, 2, bmi2_dev); - bmi2_error_codes_print_result(rslt); - } - - return rslt; -} +/**\ + * Copyright (c) 2020 Bosch Sensortec GmbH. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + **/ + +/******************************************************************************/ +/*! Header Files */ +#include +#include "bmi270.h" +#include "common.h" + +/******************************************************************************/ +/*! Macros */ + +/*! Buffer size allocated to store raw FIFO data */ +#define BMI2_FIFO_RAW_DATA_BUFFER_SIZE UINT16_C(2048) + +/*! Length of data to be read from FIFO */ +#define BMI2_FIFO_RAW_DATA_USER_LENGTH UINT16_C(2048) + +/*! Number of accel frames to be extracted from FIFO */ + +/*! Calculation for frame count: Total frame count = Fifo buffer size(2048)/ Total frames(6 Accel, 6 Gyro totaling to + * 12) which equals to 170. + */ +#define BMI2_FIFO_ACCEL_FRAME_COUNT UINT8_C(169) + +/*! Number of gyro frames to be extracted from FIFO */ +#define BMI2_FIFO_GYRO_FRAME_COUNT UINT8_C(169) + +/******************************************************************************/ +/*! Static Function Declaration */ + +/*! + * @brief This internal API is used to set configurations for accel and gyro. + * @param[in] dev : Structure instance of bmi2_dev. + * @return Status of execution. + */ +static int8_t set_accel_gyro_config(struct bmi2_dev *dev); + +/******************************************************************************/ + +/* This function starts the execution of program. */ +int main(void) +{ + /* Status of api are returned to this variable. */ + int8_t rslt; + + uint16_t index = 0; + + uint16_t fifo_length = 0; + + uint8_t try = 1; + + /* Variable to get fifo full interrupt status. */ + uint16_t int_status = 0; + + uint16_t accel_frame_length; + + uint16_t gyro_frame_length; + + /* Variable to store the available frame length count in FIFO */ + uint8_t frame_count; + + /* Number of bytes of FIFO data. */ + uint8_t fifo_data[BMI2_FIFO_RAW_DATA_BUFFER_SIZE] = { 0 }; + + /* Sensor initialization configuration. */ + struct bmi2_dev bmi2_dev; + + /* Array of accelerometer frames -> Total bytes = + * 170 * (6 axes bytes) = 1020 bytes */ + struct bmi2_sens_axes_data fifo_accel_data[BMI2_FIFO_ACCEL_FRAME_COUNT] = { { 0 } }; + + /* Array of gyro frames -> Total bytes = + * 170 * (6 axes bytes) = 1020 bytes */ + struct bmi2_sens_axes_data fifo_gyro_data[BMI2_FIFO_GYRO_FRAME_COUNT] = { { 0 } }; + + /* Initialize FIFO frame structure. */ + struct bmi2_fifo_frame fifoframe = { 0 }; + + /* Accel and gyro sensor are listed in array. */ + uint8_t sensor_sel[2] = { BMI2_ACCEL, BMI2_GYRO }; + + /* Interface reference is given as a parameter + * For I2C : BMI2_I2C_INTF + * For SPI : BMI2_SPI_INTF + */ + rslt = bmi2_interface_init(&bmi2_dev, BMI2_I2C_INTF); + bmi2_error_codes_print_result(rslt); + + /* Initialize bmi270. */ + rslt = bmi270_init(&bmi2_dev); + bmi2_error_codes_print_result(rslt); + + /* Enable accel and gyro sensor. */ + rslt = bmi270_sensor_enable(sensor_sel, 2, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + /* Configuration settings for accel and gyro. */ + rslt = set_accel_gyro_config(&bmi2_dev); + bmi2_error_codes_print_result(rslt); + + /* Before setting FIFO, disable the advance power save mode. */ + rslt = bmi2_set_adv_power_save(BMI2_DISABLE, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + /* Initially disable all configurations in fifo. */ + rslt = bmi2_set_fifo_config(BMI2_FIFO_ALL_EN, BMI2_DISABLE, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + /* Update FIFO structure. */ + /* Mapping the buffer to store the fifo data. */ + fifoframe.data = fifo_data; + + /* Length of FIFO frame. */ + fifoframe.length = BMI2_FIFO_RAW_DATA_USER_LENGTH; + + /* Set FIFO configuration by enabling accel, gyro. + * NOTE 1: The header mode is enabled by default. + * NOTE 2: By default the FIFO operating mode is FIFO mode. */ + rslt = bmi2_set_fifo_config(BMI2_FIFO_ACC_EN | BMI2_FIFO_GYR_EN, BMI2_ENABLE, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + printf("FIFO is configured in headerless mode\n"); + + /* To enable headerless mode, disable the header. */ + if (rslt == BMI2_OK) + { + rslt = bmi2_set_fifo_config(BMI2_FIFO_HEADER_EN, BMI2_DISABLE, &bmi2_dev); + } + + /* Map FIFO full interrupt. */ + fifoframe.data_int_map = BMI2_FFULL_INT; + rslt = bmi2_map_data_int(fifoframe.data_int_map, BMI2_INT1, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + while (try <= 10) + { + /* Read FIFO data on interrupt. */ + rslt = bmi2_get_int_status(&int_status, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + if ((rslt == BMI2_OK) && (int_status & BMI2_FFULL_INT_STATUS_MASK)) + { + printf("\nIteration : %d\n", try); + + rslt = bmi2_get_fifo_length(&fifo_length, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + accel_frame_length = BMI2_FIFO_ACCEL_FRAME_COUNT; + gyro_frame_length = BMI2_FIFO_GYRO_FRAME_COUNT; + + printf("\nFIFO data bytes available : %d \n", fifo_length); + printf("\nFIFO data bytes requested : %d \n", fifoframe.length); + + /* Read FIFO data. */ + rslt = bmi2_read_fifo_data(&fifoframe, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + /* Read FIFO data on interrupt. */ + rslt = bmi2_get_int_status(&int_status, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + if (rslt == BMI2_OK) + { + printf("\nFIFO accel frames requested : %d \n", accel_frame_length); + + /* Parse the FIFO data to extract accelerometer data from the FIFO buffer. */ + rslt = bmi2_extract_accel(fifo_accel_data, &accel_frame_length, &fifoframe, &bmi2_dev); + printf("\nFIFO accel frames extracted : %d \n", accel_frame_length); + + printf("\nFIFO gyro frames requested : %d \n", gyro_frame_length); + + /* Parse the FIFO data to extract gyro data from the FIFO buffer. */ + rslt = bmi2_extract_gyro(fifo_gyro_data, &gyro_frame_length, &fifoframe, &bmi2_dev); + printf("\nFIFO gyro frames extracted : %d \n", gyro_frame_length); + + /* Calculating the frame count from the available bytes in FIFO + * frame_length = (available_fifo_bytes / (acc_frame_len + gyro_frame_len)) */ + frame_count = (fifo_length / (BMI2_FIFO_ACC_GYR_LENGTH)); + printf("\nAvailable frame count from available bytes: %d\n", frame_count); + + printf("\nExtracted accel frames\n"); + + if (accel_frame_length > frame_count) + { + accel_frame_length = frame_count; + } + + /* Print the parsed accelerometer data from the FIFO buffer. */ + for (index = 0; index < accel_frame_length; index++) + { + printf("ACCEL[%d] X : %d\t Y : %d\t Z : %d\n", index, fifo_accel_data[index].x, + fifo_accel_data[index].y, fifo_accel_data[index].z); + } + + printf("\nExtracted gyro frames\n"); + + if (gyro_frame_length > frame_count) + { + gyro_frame_length = frame_count; + } + + /* Print the parsed gyro data from the FIFO buffer. */ + for (index = 0; index < gyro_frame_length; index++) + { + printf("GYRO[%d] X : %d\t Y : %d\t Z : %d\n", + index, + fifo_gyro_data[index].x, + fifo_gyro_data[index].y, + fifo_gyro_data[index].z); + } + } + + try++; + } + } + + bmi2_coines_deinit(); + + return rslt; +} + +/*! + * @brief This internal API is used to set configurations for accel and gyro. + */ +static int8_t set_accel_gyro_config(struct bmi2_dev *bmi2_dev) +{ + /* Status of api are returned to this variable. */ + int8_t rslt; + + /* Structure to define accel and gyro configurations. */ + struct bmi2_sens_config config[2]; + + /* Configure the type of feature. */ + config[0].type = BMI2_ACCEL; + config[1].type = BMI2_GYRO; + + /* Get default configurations for the type of feature selected. */ + rslt = bmi270_get_sensor_config(config, 2, bmi2_dev); + bmi2_error_codes_print_result(rslt); + + if (rslt == BMI2_OK) + { + /* NOTE: The user can change the following configuration parameters according to their requirement. */ + /* Accel configuration settings. */ + /* Set Output Data Rate */ + config[0].cfg.acc.odr = BMI2_ACC_ODR_100HZ; + + /* Gravity range of the sensor (+/- 2G, 4G, 8G, 16G). */ + config[0].cfg.acc.range = BMI2_ACC_RANGE_2G; + + /* The bandwidth parameter is used to configure the number of sensor samples that are averaged + * if it is set to 2, then 2^(bandwidth parameter) samples + * are averaged, resulting in 4 averaged samples + * Note1 : For more information, refer the datasheet. + * Note2 : A higher number of averaged samples will result in a lower noise level of the signal, but + * this has an adverse effect on the power consumed. + */ + config[0].cfg.acc.bwp = BMI2_ACC_NORMAL_AVG4; + + /* Enable the filter performance mode where averaging of samples + * will be done based on above set bandwidth and ODR. + * There are two modes + * 0 -> Ultra low power mode + * 1 -> High performance mode(Default) + * For more info refer datasheet. + */ + config[0].cfg.acc.filter_perf = BMI2_PERF_OPT_MODE; + + /* Gyro configuration settings. */ + /* Set Output Data Rate */ + config[1].cfg.gyr.odr = BMI2_GYR_ODR_100HZ; + + /* Gyroscope Angular Rate Measurement Range.By default the range is 2000dps. */ + config[1].cfg.gyr.range = BMI2_GYR_RANGE_2000; + + /* Gyroscope Bandwidth parameters. By default the gyro bandwidth is in normal mode. */ + config[1].cfg.gyr.bwp = BMI2_GYR_NORMAL_MODE; + + /* Enable/Disable the noise performance mode for precision yaw rate sensing + * There are two modes + * 0 -> Ultra low power mode(Default) + * 1 -> High performance mode + */ + config[1].cfg.gyr.noise_perf = BMI2_POWER_OPT_MODE; + + /* Enable/Disable the filter performance mode where averaging of samples + * will be done based on above set bandwidth and ODR. + * There are two modes + * 0 -> Ultra low power mode + * 1 -> High performance mode(Default) + */ + config[1].cfg.gyr.filter_perf = BMI2_PERF_OPT_MODE; + + /* Set new configurations. */ + rslt = bmi270_set_sensor_config(config, 2, bmi2_dev); + bmi2_error_codes_print_result(rslt); + } + + return rslt; +} diff --git a/examples/bmi270/fifo_watermark_header_mode/Makefile b/examples/bmi270/fifo_watermark_header_mode/Makefile new file mode 100644 index 0000000..0815820 --- /dev/null +++ b/examples/bmi270/fifo_watermark_header_mode/Makefile @@ -0,0 +1,18 @@ +COINES_INSTALL_PATH ?= ../../../.. + +EXAMPLE_FILE ?= fifo_watermark_header_mode.c + +API_LOCATION ?= ../.. + +COMMON_LOCATION ?= .. + +C_SRCS += \ +$(API_LOCATION)/bmi2.c \ +$(API_LOCATION)/bmi270.c \ +$(COMMON_LOCATION)/common/common.c + +INCLUDEPATHS += \ +$(API_LOCATION) \ +$(COMMON_LOCATION)/common + +include $(COINES_INSTALL_PATH)/coines.mk \ No newline at end of file diff --git a/examples/bmi270/fifo_watermark_header_mode/fifo_watermark_header_mode.c b/examples/bmi270/fifo_watermark_header_mode/fifo_watermark_header_mode.c new file mode 100644 index 0000000..faaeb30 --- /dev/null +++ b/examples/bmi270/fifo_watermark_header_mode/fifo_watermark_header_mode.c @@ -0,0 +1,335 @@ +/**\ + * Copyright (c) 2020 Bosch Sensortec GmbH. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + **/ + +/******************************************************************************/ +/*! Header Files */ +#include +#include "bmi270.h" +#include "common.h" + +/******************************************************************************/ +/*! Macros */ + +/*! Buffer size allocated to store raw FIFO data */ +#define BMI2_FIFO_RAW_DATA_BUFFER_SIZE UINT16_C(2048) + +/*! Length of data to be read from FIFO */ +#define BMI2_FIFO_RAW_DATA_USER_LENGTH UINT16_C(2048) + +/*! Number of accel frames to be extracted from FIFO */ + +/*! + * Calculation: + * fifo_watermark_level = 650, accel_frame_len = 6, gyro_frame_len = 6 header_byte = 1. + * fifo_accel_frame_count = (650 / (6 + 6 + 1 )) = 50 frames + * NOTE: Extra frames are read in order to get sensor time + */ +#define BMI2_FIFO_ACCEL_FRAME_COUNT UINT8_C(55) + +/*! Number of gyro frames to be extracted from FIFO */ +#define BMI2_FIFO_GYRO_FRAME_COUNT UINT8_C(55) + +/*! Setting a watermark level in FIFO */ +#define BMI270_FIFO_WATERMARK_LEVEL UINT16_C(650) + +/*! Macro to read sensortime byte in FIFO */ +#define SENSORTIME_OVERHEAD_BYTE UINT8_C(3) + +/******************************************************************************/ +/*! Static Function Declaration */ + +/*! + * @brief This internal API is used to set configurations for accel and gyro. + * @param[in] dev : Structure instance of bmi2_dev. + * @return Status of execution. + */ +static int8_t set_accel_gyro_config(struct bmi2_dev *dev); + +/******************************************************************************/ +/*! Functions */ + +/* This function starts the execution of program. */ +int main(void) +{ + /* Status of api are returned to this variable. */ + int8_t rslt; + + /* Variable to store the available frame length count in FIFO */ + uint8_t frame_count; + + /* Variable to index bytes. */ + uint16_t index = 0; + + uint16_t fifo_length = 0; + + uint16_t accel_frame_length; + + uint16_t gyro_frame_length; + + uint8_t try = 1; + + /* To read sensortime, extra 3 bytes are added to fifo buffer */ + uint16_t fifo_buffer_size = BMI2_FIFO_RAW_DATA_BUFFER_SIZE + SENSORTIME_OVERHEAD_BYTE; + + /* Number of bytes of FIFO data. */ + uint8_t fifo_data[fifo_buffer_size]; + + /* Sensor initialization configuration. */ + struct bmi2_dev bmi2_dev; + + /* Array of accelerometer frames -> Total bytes = + * 55 * (6 axes bytes) = 330 bytes */ + struct bmi2_sens_axes_data fifo_accel_data[BMI2_FIFO_ACCEL_FRAME_COUNT] = { { 0 } }; + + /* Array of gyro frames -> Total bytes = + * 55 * (6 axes bytes) = 330 bytes */ + struct bmi2_sens_axes_data fifo_gyro_data[BMI2_FIFO_GYRO_FRAME_COUNT] = { { 0 } }; + + /* Initialize FIFO frame structure. */ + struct bmi2_fifo_frame fifoframe = { 0 }; + + /* Accel and gyro sensor are listed in array. */ + uint8_t sensor_sel[2] = { BMI2_ACCEL, BMI2_GYRO }; + + /* Variable to get fifo water-mark interrupt status. */ + uint16_t int_status = 0; + + uint16_t watermark = 0; + + /* Interface reference is given as a parameter + * For I2C : BMI2_I2C_INTF + * For SPI : BMI2_SPI_INTF + */ + rslt = bmi2_interface_init(&bmi2_dev, BMI2_I2C_INTF); + bmi2_error_codes_print_result(rslt); + + /* Initialize bmi270. */ + rslt = bmi270_init(&bmi2_dev); + bmi2_error_codes_print_result(rslt); + + /* Enable accel and gyro sensor. */ + rslt = bmi270_sensor_enable(sensor_sel, 2, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + /* Configuration settings for accel and gyro. */ + rslt = set_accel_gyro_config(&bmi2_dev); + bmi2_error_codes_print_result(rslt); + + /* Before setting FIFO, disable the advance power save mode. */ + rslt = bmi2_set_adv_power_save(BMI2_DISABLE, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + /* Initially disable all configurations in fifo. */ + rslt = bmi2_set_fifo_config(BMI2_FIFO_ALL_EN, BMI2_DISABLE, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + /* Update FIFO structure. */ + /* Mapping the buffer to store the fifo data. */ + fifoframe.data = fifo_data; + + /* Length of FIFO frame. */ + /* To read sensortime, extra 3 bytes are added to fifo user length. */ + fifoframe.length = BMI2_FIFO_RAW_DATA_USER_LENGTH + SENSORTIME_OVERHEAD_BYTE; + + /* Set FIFO configuration by enabling accel, gyro and timestamp. + * NOTE 1: The header mode is enabled by default. + * NOTE 2: By default the FIFO operating mode is FIFO mode. + * NOTE 3: Sensortime is enabled by default */ + printf("FIFO is configured in header mode\n"); + rslt = bmi2_set_fifo_config(BMI2_FIFO_ACC_EN | BMI2_FIFO_GYR_EN, BMI2_ENABLE, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + /* FIFO water-mark interrupt is enabled. */ + fifoframe.data_int_map = BMI2_FWM_INT; + + /* Map water-mark interrupt to the required interrupt pin. */ + rslt = bmi2_map_data_int(fifoframe.data_int_map, BMI2_INT1, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + /* Set water-mark level. */ + fifoframe.wm_lvl = BMI270_FIFO_WATERMARK_LEVEL; + + /* Set the water-mark level if water-mark interrupt is mapped. */ + rslt = bmi2_set_fifo_wm(fifoframe.wm_lvl, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + rslt = bmi2_get_fifo_wm(&watermark, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + printf("\nFIFO watermark level is %d\n", watermark); + + while (try <= 10) + { + /* Read FIFO data on interrupt. */ + rslt = bmi2_get_int_status(&int_status, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + /* To check the status of FIFO watermark interrupt. */ + if ((rslt == BMI2_OK) && (int_status & BMI2_FWM_INT_STATUS_MASK)) + { + printf("\nIteration : %d\n", try); + + printf("\nWatermark interrupt occurred\n"); + + rslt = bmi2_get_fifo_length(&fifo_length, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + accel_frame_length = BMI2_FIFO_ACCEL_FRAME_COUNT; + gyro_frame_length = BMI2_FIFO_GYRO_FRAME_COUNT; + + printf("\nFIFO data bytes available : %d \n", fifo_length); + printf("\nFIFO data bytes requested : %d \n", fifoframe.length); + + /* Read FIFO data. */ + rslt = bmi2_read_fifo_data(&fifoframe, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + /* Read FIFO data on interrupt. */ + rslt = bmi2_get_int_status(&int_status, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + if (rslt == BMI2_OK) + { + printf("\nFIFO accel frames requested : %d \n", accel_frame_length); + + /* Parse the FIFO data to extract accelerometer data from the FIFO buffer. */ + rslt = bmi2_extract_accel(fifo_accel_data, &accel_frame_length, &fifoframe, &bmi2_dev); + printf("\nFIFO accel frames extracted : %d \n", accel_frame_length); + + printf("\nFIFO gyro frames requested : %d \n", gyro_frame_length); + + /* Parse the FIFO data to extract gyro data from the FIFO buffer. */ + rslt = bmi2_extract_gyro(fifo_gyro_data, &gyro_frame_length, &fifoframe, &bmi2_dev); + printf("\nFIFO gyro frames extracted : %d \n", gyro_frame_length); + + /* Calculating the frame count from the available bytes in FIFO + * frame_length = (available_fifo_bytes / (acc_frame_len + gyro_frame_len + header_byte)) */ + frame_count = (fifo_length / (BMI2_FIFO_ACC_GYR_LENGTH + 1)); + printf("\nAvailable frame count from available bytes: %d\n", frame_count); + + printf("\nExracted accel frames\n"); + + if (accel_frame_length > frame_count) + { + accel_frame_length = frame_count; + } + + /* Print the parsed accelerometer data from the FIFO buffer. */ + for (index = 0; index < accel_frame_length; index++) + { + printf("ACCEL[%d] X : %d\t Y : %d\t Z : %d\n", index, fifo_accel_data[index].x, + fifo_accel_data[index].y, fifo_accel_data[index].z); + } + + printf("\nExtracted gyro frames\n"); + + if (gyro_frame_length > frame_count) + { + gyro_frame_length = frame_count; + } + + /* Print the parsed gyro data from the FIFO buffer. */ + for (index = 0; index < gyro_frame_length; index++) + { + printf("GYRO[%d] X : %d\t Y : %d\t Z : %d\n", + index, + fifo_gyro_data[index].x, + fifo_gyro_data[index].y, + fifo_gyro_data[index].z); + } + + /* Print control frames like sensor time and skipped frame count. */ + printf("Skipped frame count = %d\n", fifoframe.skipped_frame_count); + printf("Sensor time = %lu\r\n", fifoframe.sensor_time); + + try++; + } + } + } + + bmi2_coines_deinit(); + + return rslt; +} + +/*! + * @brief This internal API is used to set configurations for accel and gyro. + */ +static int8_t set_accel_gyro_config(struct bmi2_dev *dev) +{ + /* Status of api are returned to this variable. */ + int8_t rslt; + + /* Structure to define accel and gyro configurations. */ + struct bmi2_sens_config config[2]; + + /* Configure the type of feature. */ + config[0].type = BMI2_ACCEL; + config[1].type = BMI2_GYRO; + + /* Get default configurations for the type of feature selected. */ + rslt = bmi270_get_sensor_config(config, 2, dev); + bmi2_error_codes_print_result(rslt); + + if (rslt == BMI2_OK) + { + /* NOTE: The user can change the following configuration parameters according to their requirement. */ + /* Accel configuration settings. */ + /* Set Output Data Rate */ + config[0].cfg.acc.odr = BMI2_ACC_ODR_25HZ; + + /* Gravity range of the sensor (+/- 2G, 4G, 8G, 16G). */ + config[0].cfg.acc.range = BMI2_ACC_RANGE_2G; + + /* The bandwidth parameter is used to configure the number of sensor samples that are averaged + * if it is set to 2, then 2^(bandwidth parameter) samples + * are averaged, resulting in 4 averaged samples + * Note1 : For more information, refer the datasheet. + * Note2 : A higher number of averaged samples will result in a lower noise level of the signal, but + * this has an adverse effect on the power consumed. + */ + config[0].cfg.acc.bwp = BMI2_ACC_NORMAL_AVG4; + + /* Enable the filter performance mode where averaging of samples + * will be done based on above set bandwidth and ODR. + * There are two modes + * 0 -> Ultra low power mode + * 1 -> High performance mode(Default) + * For more info refer datasheet. + */ + config[0].cfg.acc.filter_perf = BMI2_PERF_OPT_MODE; + + /* Gyro configuration settings. */ + /* Set Output Data Rate */ + config[1].cfg.gyr.odr = BMI2_GYR_ODR_25HZ; + + /* Gyroscope Angular Rate Measurement Range.By default the range is 2000dps. */ + config[1].cfg.gyr.range = BMI2_GYR_RANGE_2000; + + /* Gyroscope Bandwidth parameters. By default the gyro bandwidth is in normal mode. */ + config[1].cfg.gyr.bwp = BMI2_GYR_NORMAL_MODE; + + /* Enable/Disable the noise performance mode for precision yaw rate sensing + * There are two modes + * 0 -> Ultra low power mode(Default) + * 1 -> High performance mode + */ + config[1].cfg.gyr.noise_perf = BMI2_POWER_OPT_MODE; + + /* Enable/Disable the filter performance mode where averaging of samples + * will be done based on above set bandwidth and ODR. + * There are two modes + * 0 -> Ultra low power mode + * 1 -> High performance mode(Default) + */ + config[1].cfg.gyr.filter_perf = BMI2_PERF_OPT_MODE; + + /* Set new configurations. */ + rslt = bmi270_set_sensor_config(config, 2, dev); + bmi2_error_codes_print_result(rslt); + } + + return rslt; +} diff --git a/examples/bmi270/fifo_watermark_headerless_mode/Makefile b/examples/bmi270/fifo_watermark_headerless_mode/Makefile new file mode 100644 index 0000000..527a18a --- /dev/null +++ b/examples/bmi270/fifo_watermark_headerless_mode/Makefile @@ -0,0 +1,18 @@ +COINES_INSTALL_PATH ?= ../../../.. + +EXAMPLE_FILE ?= fifo_watermark_headerless_mode.c + +API_LOCATION ?= ../.. + +COMMON_LOCATION ?= .. + +C_SRCS += \ +$(API_LOCATION)/bmi2.c \ +$(API_LOCATION)/bmi270.c \ +$(COMMON_LOCATION)/common/common.c + +INCLUDEPATHS += \ +$(API_LOCATION) \ +$(COMMON_LOCATION)/common + +include $(COINES_INSTALL_PATH)/coines.mk \ No newline at end of file diff --git a/examples/bmi270/fifo_watermark_headerless_mode/fifo_watermark_headerless_mode.c b/examples/bmi270/fifo_watermark_headerless_mode/fifo_watermark_headerless_mode.c new file mode 100644 index 0000000..b3adf89 --- /dev/null +++ b/examples/bmi270/fifo_watermark_headerless_mode/fifo_watermark_headerless_mode.c @@ -0,0 +1,331 @@ +/**\ + * Copyright (c) 2020 Bosch Sensortec GmbH. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + **/ + +/******************************************************************************/ +/*! Header Files */ +#include +#include "bmi270.h" +#include "common.h" + +/******************************************************************************/ +/*! Macros */ + +/*! Buffer size allocated to store raw FIFO data */ +#define BMI2_FIFO_RAW_DATA_BUFFER_SIZE UINT16_C(2048) + +/*! Length of data to be read from FIFO */ +#define BMI2_FIFO_RAW_DATA_USER_LENGTH UINT16_C(2048) + +/*! Number of accel frames to be extracted from FIFO */ + +/*! + * Calculation: + * fifo_watermark_level = 650, accel_frame_len = 6, gyro_frame_len = 6. + * fifo_accel_frame_count = (650 / (6 + 6 )) = 54 frames + */ +#define BMI2_FIFO_ACCEL_FRAME_COUNT UINT8_C(55) + +/*! Number of gyro frames to be extracted from FIFO */ +#define BMI2_FIFO_GYRO_FRAME_COUNT UINT8_C(55) + +/*! Setting a watermark level in FIFO */ +#define BMI270_FIFO_WATERMARK_LEVEL UINT16_C(650) + +/******************************************************************************/ +/*! Static Function Declaration */ + +/*! + * @brief This internal API is used to set configurations for accel and gyro. + * @param[in] dev : Structure instance of bmi2_dev. + * @return Status of execution. + */ +static int8_t set_accel_gyro_config(struct bmi2_dev *dev); + +/******************************************************************************/ +/*! Functions */ + +/* This function starts the execution of program. */ +int main(void) +{ + /* Status of api are returned to this variable. */ + int8_t rslt; + + /* Variable to index bytes. */ + uint16_t index = 0; + + /* Variable to store the available frame length count in FIFO */ + uint8_t frame_count; + + uint16_t fifo_length = 0; + + uint16_t accel_frame_length; + + uint16_t gyro_frame_length; + + uint8_t try = 1; + + /* Number of bytes of FIFO data. */ + uint8_t fifo_data[BMI2_FIFO_RAW_DATA_BUFFER_SIZE] = { 0 }; + + /* Sensor initialization configuration. */ + struct bmi2_dev bmi2_dev; + + /* Array of accelerometer frames -> Total bytes = + * 50 * (6 axes bytes) = 300 bytes */ + struct bmi2_sens_axes_data fifo_accel_data[BMI2_FIFO_ACCEL_FRAME_COUNT] = { { 0 } }; + + /* Array of gyro frames -> Total bytes = + * 50 * (6 axes bytes) = 300 bytes */ + struct bmi2_sens_axes_data fifo_gyro_data[BMI2_FIFO_GYRO_FRAME_COUNT] = { { 0 } }; + + /* Initialize FIFO frame structure. */ + struct bmi2_fifo_frame fifoframe = { 0 }; + + /* Accel and gyro sensor are listed in array. */ + uint8_t sensor_sel[2] = { BMI2_ACCEL, BMI2_GYRO }; + + /* Variable to get fifo water-mark interrupt status. */ + uint16_t int_status = 0; + + uint16_t watermark = 0; + + /* Interface reference is given as a parameter + * For I2C : BMI2_I2C_INTF + * For SPI : BMI2_SPI_INTF + */ + rslt = bmi2_interface_init(&bmi2_dev, BMI2_I2C_INTF); + bmi2_error_codes_print_result(rslt); + + /* Initialize bmi270. */ + rslt = bmi270_init(&bmi2_dev); + bmi2_error_codes_print_result(rslt); + + /* Enable accel and gyro sensor. */ + rslt = bmi270_sensor_enable(sensor_sel, 2, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + /* Configuration settings for accel and gyro. */ + rslt = set_accel_gyro_config(&bmi2_dev); + bmi2_error_codes_print_result(rslt); + + /* Before setting FIFO, disable the advance power save mode. */ + rslt = bmi2_set_adv_power_save(BMI2_DISABLE, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + /* Initially disable all configurations in fifo. */ + rslt = bmi2_set_fifo_config(BMI2_FIFO_ALL_EN, BMI2_DISABLE, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + /* Update FIFO structure. */ + /* Mapping the buffer to store the fifo data. */ + fifoframe.data = fifo_data; + + /* Length of FIFO frame. */ + fifoframe.length = BMI2_FIFO_RAW_DATA_USER_LENGTH; + + /* Set FIFO configuration by enabling accel, gyro. + * NOTE 1: The header mode is enabled by default. + * NOTE 2: By default the FIFO operating mode is FIFO mode. */ + rslt = bmi2_set_fifo_config(BMI2_FIFO_ACC_EN | BMI2_FIFO_GYR_EN, BMI2_ENABLE, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + printf("FIFO is configured in headerless mode\n"); + + /* To enable headerless mode, disable the header. */ + if (rslt == BMI2_OK) + { + rslt = bmi2_set_fifo_config(BMI2_FIFO_HEADER_EN, BMI2_DISABLE, &bmi2_dev); + } + + /* FIFO water-mark interrupt is enabled. */ + fifoframe.data_int_map = BMI2_FWM_INT; + + /* Map water-mark interrupt to the required interrupt pin. */ + rslt = bmi2_map_data_int(fifoframe.data_int_map, BMI2_INT1, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + /* Set water-mark level. */ + fifoframe.wm_lvl = BMI270_FIFO_WATERMARK_LEVEL; + + fifoframe.length = BMI2_FIFO_RAW_DATA_USER_LENGTH; + + /* Set the water-mark level if water-mark interrupt is mapped. */ + rslt = bmi2_set_fifo_wm(fifoframe.wm_lvl, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + rslt = bmi2_get_fifo_wm(&watermark, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + printf("\nFIFO watermark level is %d\n", watermark); + + while (try <= 10) + { + /* Read FIFO data on interrupt. */ + rslt = bmi2_get_int_status(&int_status, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + /* To check the status of FIFO watermark interrupt. */ + if ((rslt == BMI2_OK) && (int_status & BMI2_FWM_INT_STATUS_MASK)) + { + printf("\nIteration : %d\n", try); + + printf("\nWatermark interrupt occurred\n"); + + rslt = bmi2_get_fifo_length(&fifo_length, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + accel_frame_length = BMI2_FIFO_ACCEL_FRAME_COUNT; + gyro_frame_length = BMI2_FIFO_GYRO_FRAME_COUNT; + + printf("\nFIFO data bytes available : %d \n", fifo_length); + printf("\nFIFO data bytes requested : %d \n", fifoframe.length); + + /* Read FIFO data. */ + rslt = bmi2_read_fifo_data(&fifoframe, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + /* Read FIFO data on interrupt. */ + rslt = bmi2_get_int_status(&int_status, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + if (rslt == BMI2_OK) + { + printf("\nFIFO accel frames requested : %d \n", accel_frame_length); + + /* Parse the FIFO data to extract accelerometer data from the FIFO buffer. */ + rslt = bmi2_extract_accel(fifo_accel_data, &accel_frame_length, &fifoframe, &bmi2_dev); + printf("\nFIFO accel frames extracted : %d \n", accel_frame_length); + + printf("\nFIFO gyro frames requested : %d \n", gyro_frame_length); + + /* Parse the FIFO data to extract gyro data from the FIFO buffer. */ + rslt = bmi2_extract_gyro(fifo_gyro_data, &gyro_frame_length, &fifoframe, &bmi2_dev); + printf("\nFIFO gyro frames extracted : %d \n", gyro_frame_length); + + /* Calculating the frame count from the available bytes in FIFO + * frame_length = (available_fifo_bytes / (acc_frame_len + gyro_frame_len)) */ + frame_count = (fifo_length / (BMI2_FIFO_ACC_GYR_LENGTH)); + printf("\nAvailable frame count from available bytes: %d\n", frame_count); + + printf("\nExracted accel frames\n"); + + if (accel_frame_length > frame_count) + { + accel_frame_length = frame_count; + } + + /* Print the parsed accelerometer data from the FIFO buffer. */ + for (index = 0; index < accel_frame_length; index++) + { + printf("ACCEL[%d] X : %d\t Y : %d\t Z : %d\n", index, fifo_accel_data[index].x, + fifo_accel_data[index].y, fifo_accel_data[index].z); + } + + printf("\nExtracted gyro frames\n"); + + if (gyro_frame_length > frame_count) + { + gyro_frame_length = frame_count; + } + + /* Print the parsed gyro data from the FIFO buffer. */ + for (index = 0; index < gyro_frame_length; index++) + { + printf("GYRO[%d] X : %d\t Y : %d\t Z : %d\n", + index, + fifo_gyro_data[index].x, + fifo_gyro_data[index].y, + fifo_gyro_data[index].z); + } + } + + try++; + } + } + + bmi2_coines_deinit(); + + return rslt; +} + +/*! + * @brief This internal API is used to set configurations for accel. + */ +static int8_t set_accel_gyro_config(struct bmi2_dev *dev) +{ + /* Status of api are returned to this variable. */ + int8_t rslt; + + /* Structure to define accel and gyro configurations. */ + struct bmi2_sens_config config[2]; + + /* Configure the type of feature. */ + config[0].type = BMI2_ACCEL; + config[1].type = BMI2_GYRO; + + /* Get default configurations for the type of feature selected. */ + rslt = bmi270_get_sensor_config(config, 2, dev); + bmi2_error_codes_print_result(rslt); + + if (rslt == BMI2_OK) + { + /* NOTE: The user can change the following configuration parameter according to their requirement. */ + /* Accel configuration settings. */ + /* Set Output Data Rate */ + config[0].cfg.acc.odr = BMI2_ACC_ODR_100HZ; + + /* Gravity range of the sensor (+/- 2G, 4G, 8G, 16G). */ + config[0].cfg.acc.range = BMI2_ACC_RANGE_2G; + + /* The bandwidth parameter is used to configure the number of sensor samples that are averaged + * if it is set to 2, then 2^(bandwidth parameter) samples + * are averaged, resulting in 4 averaged samples + * Note1 : For more information, refer the datasheet. + * Note2 : A higher number of averaged samples will result in a lower noise level of the signal, but + * this has an adverse effect on the power consumed. + */ + config[0].cfg.acc.bwp = BMI2_ACC_NORMAL_AVG4; + + /* Enable the filter performance mode where averaging of samples + * will be done based on above set bandwidth and ODR. + * There are two modes + * 0 -> Ultra low power mode + * 1 -> High performance mode(Default) + * For more info refer datasheet. + */ + config[0].cfg.acc.filter_perf = BMI2_PERF_OPT_MODE; + + /* Gyro configuration settings. */ + /* Set Output Data Rate */ + config[1].cfg.gyr.odr = BMI2_GYR_ODR_100HZ; + + /* Gyroscope Angular Rate Measurement Range.By default the range is 2000dps. */ + config[1].cfg.gyr.range = BMI2_GYR_RANGE_2000; + + /* Gyroscope Bandwidth parameters. By default the gyro bandwidth is in normal mode. */ + config[1].cfg.gyr.bwp = BMI2_GYR_NORMAL_MODE; + + /* Enable/Disable the noise performance mode for precision yaw rate sensing + * There are two modes + * 0 -> Ultra low power mode(Default) + * 1 -> High performance mode + */ + config[1].cfg.gyr.noise_perf = BMI2_POWER_OPT_MODE; + + /* Enable/Disable the filter performance mode where averaging of samples + * will be done based on above set bandwidth and ODR. + * There are two modes + * 0 -> Ultra low power mode + * 1 -> High performance mode(Default) + */ + config[1].cfg.gyr.filter_perf = BMI2_PERF_OPT_MODE; + + /* Set new configurations. */ + rslt = bmi270_set_sensor_config(config, 2, dev); + bmi2_error_codes_print_result(rslt); + } + + return rslt; +} diff --git a/examples/bmi270/generic/bmi2_common.h b/examples/bmi270/generic/bmi2_common.h deleted file mode 100644 index 092821c..0000000 --- a/examples/bmi270/generic/bmi2_common.h +++ /dev/null @@ -1,141 +0,0 @@ -/**\ - * Copyright (c) 2020 Bosch Sensortec GmbH. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - **/ - -#ifndef __BMI2_COMMON_H__ -#define __BMI2_COMMON_H__ - -/*! CPP guard */ -#ifdef __cplusplus -extern "C" { -#endif - -#include -#include "bmi2.h" - -/*! - * @brief Function for initialization of I2C bus - * - * @retval 0 -> Success - * @retval < 0 -> Failure Info - */ -int8_t bmi2_user_i2c_init(void); - -/*! - * @brief Function for initialization of SPI bus - * - * @retval 0 -> Success - * @retval < 0 -> Failure Info - */ -int8_t bmi2_user_spi_init(void); - -/*! - * @brief This function provides the delay for required time (Microseconds) as per the input provided in some of the - * APIs. - * @param[in] period_us : The required wait time in microseconds. - * @param[in] intf_ptr : Pointer to interface. - * @return void. - * - */ -void user_delay_us(uint32_t period_us, void *intf_ptr); - -/*! - * @brief This function provides the delay for required time (Milliseconds) as per the input provided in some of the - * APIs. - * @param[in] period_ms : The required wait time in milliseconds. - * @return void. - * - */ -void user_delay_ms(uint32_t period_ms); - -/*! - * @brief This function is for reading the sensor's registers through I2C bus. - * - * @param[in] reg_addr : Register address. - * @param[out] reg_data: Pointer to the data buffer to store the read data. - * @param[in] length : No of bytes to read. - * @param[in] intf_ptr : Pointer to interface. - * - * @return Status of execution - * - * @retval = BMI2_INTF_RET_SUCCESS -> Success - * @retval != BMI2_INTF_RET_SUCCESS -> Failure - * - */ -int8_t user_i2c_reg_read(uint8_t reg_addr, uint8_t *reg_data, uint32_t length, void *intf_ptr); - -/*! - * @brief This function is for writing the sensor's registers through I2C bus. - * - * @param[in] reg_addr : Register address. - * @param[in] reg_data : Pointer to the data buffer whose value is to be written. - * @param[in] length : No of bytes to write. - * @param[in] intf_ptr : Pointer to interface. - * - * @return Status of execution - * - * @retval = BMI2_INTF_RET_SUCCESS -> Success - * @retval != BMI2_INTF_RET_SUCCESS -> Failure - * - */ -int8_t user_i2c_reg_write(uint8_t reg_addr, const uint8_t *reg_data, uint32_t length, void *intf_ptr); - -/*! - * @brief This function is for reading the sensor's registers through SPI bus. - * - * @param[in] reg_addr : Register address. - * @param[out] reg_data : Pointer to the data buffer to store the read data. - * @param[in] length : No of bytes to read. - * @param[in] intf_ptr : Pointer to interface. - * - * @return Status of execution - * - * @retval = BMI2_INTF_RET_SUCCESS -> Success - * @retval != BMI2_INTF_RET_SUCCESS -> Failure - * - */ -int8_t user_spi_reg_read(uint8_t reg_addr, uint8_t *reg_data, uint32_t length, void *intf_ptr); - -/*! - * @brief This function is for writing the sensor's registers through SPI bus. - * - * @param[in] reg_addr : Register address. - * @param[in] reg_data : Pointer to the data buffer whose data has to be written. - * @param[in] length : No of bytes to write. - * @param[in] intf_ptr : Pointer to interface. - * - * @return Status of execution - * - * @retval = BMI2_INTF_RET_SUCCESS -> Success - * @retval != BMI2_INTF_RET_SUCCESS -> Failure - * - */ -int8_t user_spi_reg_write(uint8_t reg_addr, const uint8_t *reg_data, uint32_t length, void *intf_ptr); - -/*! - * @brief This function is to select the interface between SPI and I2C. - * - * @param[in] dev : Structure instance of bmi2_dev - * - * @return Status of execution - * @retval 0 -> Success - * @retval < 0 -> Failure Info - */ -int8_t bmi2_interface_selection(struct bmi2_dev *dev); - -/*! - * @brief This API is used to print the execution status. - * - * @param[in] rslt : Error code returned by the API whose execution status has to be printed. - * - * @return void. - */ -void bmi2_error_codes_print_result(int8_t rslt); - -#ifdef __cplusplus -} -#endif /* End of CPP guard */ - -#endif /* __BMI2_COMMON_H__ */ diff --git a/examples/bmi270/gyro/Makefile b/examples/bmi270/gyro/Makefile new file mode 100644 index 0000000..e1f03b8 --- /dev/null +++ b/examples/bmi270/gyro/Makefile @@ -0,0 +1,18 @@ +COINES_INSTALL_PATH ?= ../../../.. + +EXAMPLE_FILE ?= gyro.c + +API_LOCATION ?= ../.. + +COMMON_LOCATION ?= .. + +C_SRCS += \ +$(API_LOCATION)/bmi2.c \ +$(API_LOCATION)/bmi270.c \ +$(COMMON_LOCATION)/common/common.c + +INCLUDEPATHS += \ +$(API_LOCATION) \ +$(COMMON_LOCATION)/common + +include $(COINES_INSTALL_PATH)/coines.mk \ No newline at end of file diff --git a/examples/bmi270/gyro/gyro.c b/examples/bmi270/gyro/gyro.c new file mode 100644 index 0000000..1bb0ca4 --- /dev/null +++ b/examples/bmi270/gyro/gyro.c @@ -0,0 +1,195 @@ +/**\ + * Copyright (c) 2020 Bosch Sensortec GmbH. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + **/ + +/******************************************************************************/ +/*! Header Files */ +#include +#include "bmi270.h" +#include "common.h" + +/******************************************************************************/ +/*! Static Function Declaration */ + +/*! + * @brief This internal API is used to set configurations for gyro. + * + * @param[in] dev : Structure instance of bmi2_dev. + * + * @return Status of execution. + */ +static int8_t set_gyro_config(struct bmi2_dev *dev); + +/*! + * @brief This function converts lsb to degree per second for 16 bit gyro at + * range 125, 250, 500, 1000 or 2000dps. + * + * @param[in] val : LSB from each axis. + * @param[in] dps : Degree per second. + * @param[in] bit_width : Resolution for gyro. + * + * @return Degree per second. + */ +static float lsb_to_dps(int16_t val, float dps, uint8_t bit_width); + +/******************************************************************************/ +/*! Functions */ + +/* This function starts the execution of program. */ +int main(void) +{ + /* Status of api are returned to this variable. */ + int8_t rslt; + + /* Variable to define limit to print gyro data. */ + uint8_t limit = 10; + + uint8_t indx = 0; + + float x = 0, y = 0, z = 0; + + /* Sensor initialization configuration. */ + struct bmi2_dev bmi2_dev; + + /* Create an instance of sensor data structure. */ + struct bmi2_sensor_data sensor_data = { 0 }; + + /* Assign gyro sensor to variable. */ + uint8_t sens_list = BMI2_GYRO; + + /* Initialize the interrupt status of gyro. */ + uint16_t int_status = 0; + + /* Interface reference is given as a parameter + * For I2C : BMI2_I2C_INTF + * For SPI : BMI2_SPI_INTF + */ + rslt = bmi2_interface_init(&bmi2_dev, BMI2_I2C_INTF); + bmi2_error_codes_print_result(rslt); + + /* Initialize bmi270. */ + rslt = bmi270_init(&bmi2_dev); + bmi2_error_codes_print_result(rslt); + + if (rslt == BMI2_OK) + { + /* Enable the selected sensors. */ + rslt = bmi270_sensor_enable(&sens_list, 1, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + if (rslt == BMI2_OK) + { + /* Gyro configuration settings. */ + rslt = set_gyro_config(&bmi2_dev); + bmi2_error_codes_print_result(rslt); + + /* Select gyro sensor. */ + sensor_data.type = BMI2_GYRO; + printf("Gyro and DPS data\n"); + printf("Gyro data collected at Range 2000 dps with 16-bit resolution\n"); + + /* Loop to print gyro data when interrupt occurs. */ + while (indx <= limit) + { + /* To get the data ready interrupt status of gyro. */ + rslt = bmi2_get_int_status(&int_status, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + /* To check the data ready interrupt status and print the status for 10 samples. */ + if (int_status & BMI2_GYR_DRDY_INT_MASK) + { + /* Get gyro data for x, y and z axis. */ + rslt = bmi270_get_sensor_data(&sensor_data, 1, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + printf("\nGyr_X = %d\t", sensor_data.sens_data.gyr.x); + printf("Gyr_Y = %d\t", sensor_data.sens_data.gyr.y); + printf("Gyr_Z = %d\r\n", sensor_data.sens_data.gyr.z); + + /* Converting lsb to degree per second for 16 bit gyro at 2000dps range. */ + x = lsb_to_dps(sensor_data.sens_data.gyr.x, 2000, bmi2_dev.resolution); + y = lsb_to_dps(sensor_data.sens_data.gyr.y, 2000, bmi2_dev.resolution); + z = lsb_to_dps(sensor_data.sens_data.gyr.z, 2000, bmi2_dev.resolution); + + /* Print the data in dps. */ + printf("Gyr_DPS_X = %4.2f, Gyr_DPS_Y = %4.2f, Gyr_DPS_Z = %4.2f\n", x, y, z); + + indx++; + } + } + } + } + + bmi2_coines_deinit(); + + return rslt; +} + +/*! + * @brief This internal API is used to set configurations for gyro. + */ +static int8_t set_gyro_config(struct bmi2_dev *dev) +{ + /* Status of api are returned to this variable. */ + int8_t rslt; + + /* Structure to define the type of sensor and its configurations. */ + struct bmi2_sens_config config; + + /* Configure the type of feature. */ + config.type = BMI2_GYRO; + + /* Get default configurations for the type of feature selected. */ + rslt = bmi270_get_sensor_config(&config, 1, dev); + bmi2_error_codes_print_result(rslt); + + /* Map data ready interrupt to interrupt pin. */ + rslt = bmi2_map_data_int(BMI2_DRDY_INT, BMI2_INT2, dev); + bmi2_error_codes_print_result(rslt); + + if (rslt == BMI2_OK) + { + /* The user can change the following configuration parameters according to their requirement. */ + /* Set Output Data Rate */ + config.cfg.gyr.odr = BMI2_GYR_ODR_100HZ; + + /* Gyroscope Angular Rate Measurement Range.By default the range is 2000dps. */ + config.cfg.gyr.range = BMI2_GYR_RANGE_2000; + + /* Gyroscope bandwidth parameters. By default the gyro bandwidth is in normal mode. */ + config.cfg.gyr.bwp = BMI2_GYR_NORMAL_MODE; + + /* Enable/Disable the noise performance mode for precision yaw rate sensing + * There are two modes + * 0 -> Ultra low power mode(Default) + * 1 -> High performance mode + */ + config.cfg.gyr.noise_perf = BMI2_POWER_OPT_MODE; + + /* Enable/Disable the filter performance mode where averaging of samples + * will be done based on above set bandwidth and ODR. + * There are two modes + * 0 -> Ultra low power mode + * 1 -> High performance mode(Default) + */ + config.cfg.gyr.filter_perf = BMI2_PERF_OPT_MODE; + + /* Set the gyro configurations. */ + rslt = bmi270_set_sensor_config(&config, 1, dev); + } + + return rslt; +} + +/*! + * @brief This function converts lsb to degree per second for 16 bit gyro at + * range 125, 250, 500, 1000 or 2000dps. + */ +static float lsb_to_dps(int16_t val, float dps, uint8_t bit_width) +{ + float half_scale = ((float)(1 << bit_width) / 2.0f); + + return (dps / ((half_scale) + BMI2_GYR_RANGE_2000)) * (val); +} diff --git a/examples/bmi270/no_motion_interrupt/Makefile b/examples/bmi270/no_motion_interrupt/Makefile new file mode 100644 index 0000000..c5df6df --- /dev/null +++ b/examples/bmi270/no_motion_interrupt/Makefile @@ -0,0 +1,18 @@ +COINES_INSTALL_PATH ?= ../../../.. + +EXAMPLE_FILE ?= no_motion_interrupt.c + +API_LOCATION ?= ../.. + +COMMON_LOCATION ?= .. + +C_SRCS += \ +$(API_LOCATION)/bmi2.c \ +$(API_LOCATION)/bmi270.c \ +$(COMMON_LOCATION)/common/common.c + +INCLUDEPATHS += \ +$(API_LOCATION) \ +$(COMMON_LOCATION)/common + +include $(COINES_INSTALL_PATH)/coines.mk \ No newline at end of file diff --git a/examples/bmi270/generic/no_motion_interrupt.c b/examples/bmi270/no_motion_interrupt/no_motion_interrupt.c similarity index 87% rename from examples/bmi270/generic/no_motion_interrupt.c rename to examples/bmi270/no_motion_interrupt/no_motion_interrupt.c index 6b42545..5c46306 100644 --- a/examples/bmi270/generic/no_motion_interrupt.c +++ b/examples/bmi270/no_motion_interrupt/no_motion_interrupt.c @@ -1,137 +1,134 @@ -/**\ - * Copyright (c) 2020 Bosch Sensortec GmbH. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - **/ - -/******************************************************************************/ -/*! Header Files */ -#include -#include "bmi2.h" -#include "bmi270.h" -#include "bmi2_common.h" - -/******************************************************************************/ -/*! Static Function Declaration */ - -/*! - * @brief This internal API is used to set configurations for no-motion. - * - * @param[in] bmi2_dev : Structure instance of bmi2_dev. - * - * @return Status of execution. - */ -static int8_t set_feature_config(struct bmi2_dev *bmi2_dev); - -/******************************************************************************/ -/*! Functions */ - -/* This function starts the execution of program. */ -int main(void) -{ - - /* Status of api are returned to this variable. */ - int8_t rslt; - - /* Accel sensor and no-motion feature are listed in array. */ - uint8_t sens_list[2] = { BMI2_ACCEL, BMI2_NO_MOTION }; - - /* Variable to get no-motion interrupt status. */ - uint16_t int_status = 0; - - /*! Sensor initialization configuration. */ - struct bmi2_dev bmi2_dev; - - /* Select features and their pins to be mapped to. */ - struct bmi2_sens_int_config sens_int = { .type = BMI2_NO_MOTION, .hw_int_pin = BMI2_INT1 }; - - /* Initialize the dev structure */ - rslt = bmi2_interface_selection(&bmi2_dev); - bmi2_error_codes_print_result(rslt); - - /* Initialize bmi270. */ - rslt = bmi270_init(&bmi2_dev); - bmi2_error_codes_print_result(rslt); - - if (rslt == BMI2_OK) - { - - /* Enable the selected sensors. */ - rslt = bmi2_sensor_enable(sens_list, 2, &bmi2_dev); - bmi2_error_codes_print_result(rslt); - - if (rslt == BMI2_OK) - { - - /* Set feature configurations for no-motion. */ - rslt = set_feature_config(&bmi2_dev); - bmi2_error_codes_print_result(rslt); - - if (rslt == BMI2_OK) - { - - /* Map the feature interrupt for no-motion. */ - rslt = bmi2_map_feat_int(&sens_int, 1, &bmi2_dev); - bmi2_error_codes_print_result(rslt); - printf("Do not move the board\n"); - - /* Loop to get no-motion interrupt. */ - do - { - - /* Clear buffer. */ - int_status = 0; - - /* To get the interrupt status of no-motion. */ - rslt = bmi2_get_int_status(&int_status, &bmi2_dev); - bmi2_error_codes_print_result(rslt); - - /* To check the interrupt status of no-motion. */ - if (int_status & BMI270_NO_MOT_STATUS_MASK) - { - printf("No-motion interrupt is generated\n"); - break; - } - } while (rslt == BMI2_OK); - } - } - } - - return rslt; -} - -/*! - * @brief This internal API is used to set configurations for no-motion. - */ -static int8_t set_feature_config(struct bmi2_dev *bmi2_dev) -{ - - /* Status of api are returned to this variable. */ - int8_t rslt; - - /* Structure to define the type of sensor and its configurations. */ - struct bmi2_sens_config config; - - /* Configure the type of feature. */ - config.type = BMI2_NO_MOTION; - - /* Get default configurations for the type of feature selected. */ - rslt = bmi2_get_sensor_config(&config, 1, bmi2_dev); - bmi2_error_codes_print_result(rslt); - if (rslt == BMI2_OK) - { - - /* NOTE: The user can change the following configuration parameters according to their requirement. */ - /* 1LSB equals 20ms. Default is 100ms, setting to 80ms. */ - config.cfg.no_motion.duration = 0x04; - - /* 1LSB equals to 0.48mg. Default is 83mg, setting to 50mg. */ - config.cfg.no_motion.threshold = 0x68; - - /* Set new configurations. */ - rslt = bmi2_set_sensor_config(&config, 1, bmi2_dev); - bmi2_error_codes_print_result(rslt); - } - - return rslt; -} +/**\ + * Copyright (c) 2020 Bosch Sensortec GmbH. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + **/ + +/******************************************************************************/ +/*! Header Files */ +#include +#include "bmi270.h" +#include "common.h" + +/******************************************************************************/ +/*! Static Function Declaration */ + +/*! + * @brief This internal API is used to set configurations for no-motion. + * + * @param[in] bmi2_dev : Structure instance of bmi2_dev. + * + * @return Status of execution. + */ +static int8_t set_feature_config(struct bmi2_dev *bmi2_dev); + +/******************************************************************************/ +/*! Functions */ + +/* This function starts the execution of program. */ +int main(void) +{ + /* Status of api are returned to this variable. */ + int8_t rslt; + + /* Accel sensor and no-motion feature are listed in array. */ + uint8_t sens_list[2] = { BMI2_ACCEL, BMI2_NO_MOTION }; + + /* Variable to get no-motion interrupt status. */ + uint16_t int_status = 0; + + /* Sensor initialization configuration. */ + struct bmi2_dev bmi2_dev; + + /* Select features and their pins to be mapped to. */ + struct bmi2_sens_int_config sens_int = { .type = BMI2_NO_MOTION, .hw_int_pin = BMI2_INT1 }; + + /* Interface reference is given as a parameter + * For I2C : BMI2_I2C_INTF + * For SPI : BMI2_SPI_INTF + */ + rslt = bmi2_interface_init(&bmi2_dev, BMI2_I2C_INTF); + bmi2_error_codes_print_result(rslt); + + /* Initialize bmi270. */ + rslt = bmi270_init(&bmi2_dev); + bmi2_error_codes_print_result(rslt); + + if (rslt == BMI2_OK) + { + /* Enable the selected sensors. */ + rslt = bmi270_sensor_enable(sens_list, 2, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + if (rslt == BMI2_OK) + { + /* Set feature configurations for no-motion. */ + rslt = set_feature_config(&bmi2_dev); + bmi2_error_codes_print_result(rslt); + + if (rslt == BMI2_OK) + { + /* Map the feature interrupt for no-motion. */ + rslt = bmi270_map_feat_int(&sens_int, 1, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + printf("Do not move the board\n"); + + /* Loop to get no-motion interrupt. */ + do + { + /* Clear buffer. */ + int_status = 0; + + /* To get the interrupt status of no-motion. */ + rslt = bmi2_get_int_status(&int_status, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + /* To check the interrupt status of no-motion. */ + if (int_status & BMI270_NO_MOT_STATUS_MASK) + { + printf("No-motion interrupt is generated\n"); + break; + } + } while (rslt == BMI2_OK); + } + } + } + + bmi2_coines_deinit(); + + return rslt; +} + +/*! + * @brief This internal API is used to set configurations for no-motion. + */ +static int8_t set_feature_config(struct bmi2_dev *bmi2_dev) +{ + /* Status of api are returned to this variable. */ + int8_t rslt; + + /* Structure to define the type of sensor and its configurations. */ + struct bmi2_sens_config config; + + /* Configure the type of feature. */ + config.type = BMI2_NO_MOTION; + + /* Get default configurations for the type of feature selected. */ + rslt = bmi270_get_sensor_config(&config, 1, bmi2_dev); + bmi2_error_codes_print_result(rslt); + if (rslt == BMI2_OK) + { + /* NOTE: The user can change the following configuration parameters according to their requirement. */ + /* 1LSB equals 20ms. Default is 100ms, setting to 80ms. */ + config.cfg.no_motion.duration = 0x04; + + /* 1LSB equals to 0.48mg. Default is 83mg, setting to 50mg. */ + config.cfg.no_motion.threshold = 0x68; + + /* Set new configurations. */ + rslt = bmi270_set_sensor_config(&config, 1, bmi2_dev); + bmi2_error_codes_print_result(rslt); + } + + return rslt; +} diff --git a/examples/bmi270/read_aux_data_mode/Makefile b/examples/bmi270/read_aux_data_mode/Makefile new file mode 100644 index 0000000..db669c0 --- /dev/null +++ b/examples/bmi270/read_aux_data_mode/Makefile @@ -0,0 +1,23 @@ +COINES_INSTALL_PATH ?= ../../../.. + +EXAMPLE_FILE ?= read_aux_data_mode.c + +API_LOCATION ?= ../.. + +COMMON_LOCATION ?= .. + +BMM150_SOURCE ?= ../../../bmm150 + +C_SRCS += \ +$(API_LOCATION)/bmi2.c \ +$(API_LOCATION)/bmi270.c \ +$(BMM150_SOURCE)/bmm150.c \ +$(COMMON_LOCATION)/common/common.c + +INCLUDEPATHS += \ +$(API_LOCATION) \ +$(BMM150_SOURCE) \ +$(COMMON_LOCATION)/common + + +include $(COINES_INSTALL_PATH)/coines.mk \ No newline at end of file diff --git a/examples/bmi270/read_aux_data_mode/read_aux_data_mode.c b/examples/bmi270/read_aux_data_mode/read_aux_data_mode.c new file mode 100644 index 0000000..a542f97 --- /dev/null +++ b/examples/bmi270/read_aux_data_mode/read_aux_data_mode.c @@ -0,0 +1,327 @@ +/**\ + * Copyright (c) 2020 Bosch Sensortec GmbH. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + **/ + +/******************************************************************************/ +/*! Header Files */ +#include +#include "bmi270.h" +#include "bmm150.h" +#include "coines.h" +#include "common.h" + +/******************************************************************************/ +/*! Macro definition */ + +/*! Macros to select the sensors */ +#define ACCEL UINT8_C(0x00) +#define GYRO UINT8_C(0x01) +#define AUX UINT8_C(0x02) + +/*! Earth's gravity in m/s^2 */ +#define GRAVITY_EARTH (9.80665f) + +/*****************************************************************************/ +/*! Structure declaration */ + +/* Sensor initialization configuration. */ +struct bmi2_dev bmi2_dev; + +/*******************************************************************************/ +/*! Functions */ + +/** + * user_aux_read - Reads data from auxiliary sensor in manual mode. + * + * @param[in] reg_addr : Register address. + * @param[out] aux_data : Aux data pointer to store the read data. + * @param[in] length : No of bytes to read. + * @param[in] intf_ptr : Interface pointer + * + * @return Status of execution + * @retval 0 -> Success + * @retval < 0 -> Failure Info + */ +static int8_t user_aux_read(uint8_t reg_addr, uint8_t *aux_data, uint32_t len, void *intf_ptr); + +/** + * user_aux_write - Writes data to the auxiliary sensor in manual mode. + * + * @param[in] reg_addr : Register address. + * @param[out] aux_data : Aux data pointer to store the data being written. + * @param[in] length : No of bytes to read. + * @param[in] intf_ptr : Interface pointer + * + * @return Status of execution + * @retval 0 -> Success + * @retval < 0 -> Failure Info + */ +static int8_t user_aux_write(uint8_t reg_addr, const uint8_t *aux_data, uint32_t len, void *intf_ptr); + +/*! + * @brief This function provides the delay for required time (Microsecond) as per the input provided in some of the + * APIs. + * + * @param[in] period_us : The required wait time in microsecond. + * @param[in] intf_ptr : Interface pointer + * + * @return void. + */ +static void user_delay_us(uint32_t period, void *intf_ptr); + +/*! + * @brief This function converts lsb to meter per second squared for 16 bit accelerometer at + * range 2G, 4G, 8G or 16G. + * + * @param[in] val : LSB from each axis. + * @param[in] g_range : Gravity range. + * @param[in] bit_width : Resolution for accel. + * + * @return Gravity. + */ +static float lsb_to_mps2(int16_t val, float g_range, uint8_t bit_width); + +/*! + * @brief This function converts lsb to degree per second for 16 bit gyro at + * range 125, 250, 500, 1000 or 2000dps. + * + * @param[in] val : LSB from each axis. + * @param[in] dps : Degree per second. + * @param[in] bit_width : Resolution for gyro. + * + * @return Degree per second. + */ +static float lsb_to_dps(int16_t val, float dps, uint8_t bit_width); + +/* This function starts the execution of program. */ +int main(void) +{ + /* Status of api are returned to this variable. */ + int8_t rslt; + + /* Variable to select the pull-up resistor which is set to trim register */ + uint8_t regdata; + + /* Variable to define limit to print aux data. */ + uint8_t limit = 20; + + /* Accel, Gyro and Aux sensors are listed in array. */ + uint8_t sensor_list[3] = { BMI2_ACCEL, BMI2_GYRO, BMI2_AUX }; + + /* Structure to define the type of the sensor and its configurations. */ + struct bmi2_sens_config config[3]; + + /* Sensor initialization configuration. */ + struct bmm150_dev bmm150_dev; + + /* bmm150 settings configuration */ + struct bmm150_settings settings; + + /* bmm150 magnetometer data */ + struct bmm150_mag_data mag_data; + + /* Structure to define type of sensor and their respective data. */ + struct bmi2_sensor_data sensor_data[3]; + + /* Variables to define read the accel and gyro data in float */ + float x = 0, y = 0, z = 0; + + config[ACCEL].type = BMI2_ACCEL; + config[GYRO].type = BMI2_GYRO; + config[AUX].type = BMI2_AUX; + + /* To enable the i2c interface settings for bmm150. */ + uint8_t bmm150_dev_addr = BMM150_DEFAULT_I2C_ADDRESS; + bmm150_dev.intf_ptr = &bmm150_dev_addr; + bmm150_dev.read = user_aux_read; + bmm150_dev.write = user_aux_write; + bmm150_dev.delay_us = user_delay_us; + + /* As per datasheet, aux interface with bmi270 will support only for I2C */ + bmm150_dev.intf = BMM150_I2C_INTF; + + sensor_data[ACCEL].type = BMI2_ACCEL; + sensor_data[GYRO].type = BMI2_GYRO; + sensor_data[AUX].type = BMI2_AUX; + + /* Interface reference is given as a parameter + * For I2C : BMI2_I2C_INTF + * For SPI : BMI2_SPI_INTF + */ + rslt = bmi2_interface_init(&bmi2_dev, BMI2_I2C_INTF); + bmi2_error_codes_print_result(rslt); + + /* Initialize bmi270. */ + rslt = bmi270_init(&bmi2_dev); + bmi2_error_codes_print_result(rslt); + + /* Pull-up resistor 2k is set to the trim regiter */ + regdata = BMI2_ASDA_PUPSEL_2K; + rslt = bmi2_set_regs(BMI2_AUX_IF_TRIM, ®data, 1, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + /* Enable the accel, gyro and aux sensor. */ + rslt = bmi270_sensor_enable(sensor_list, 3, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + /* Get default configurations for the type of feature selected. */ + rslt = bmi270_get_sensor_config(config, 3, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + /* Configurations for accel. */ + config[ACCEL].cfg.acc.filter_perf = BMI2_PERF_OPT_MODE; + config[ACCEL].cfg.acc.bwp = BMI2_ACC_OSR2_AVG2; + config[ACCEL].cfg.acc.odr = BMI2_ACC_ODR_100HZ; + config[ACCEL].cfg.acc.range = BMI2_ACC_RANGE_2G; + + /* Configurations for gyro. */ + config[GYRO].cfg.gyr.filter_perf = BMI2_PERF_OPT_MODE; + config[GYRO].cfg.gyr.noise_perf = BMI2_GYR_RANGE_2000; + config[GYRO].cfg.gyr.bwp = BMI2_GYR_OSR2_MODE; + config[GYRO].cfg.gyr.odr = BMI2_GYR_ODR_100HZ; + config[GYRO].cfg.gyr.range = BMI2_GYR_RANGE_2000; + config[GYRO].cfg.gyr.ois_range = BMI2_GYR_OIS_2000; + + /* Configurations for aux. */ + config[AUX].cfg.aux.odr = BMI2_AUX_ODR_100HZ; + config[AUX].cfg.aux.aux_en = BMI2_ENABLE; + config[AUX].cfg.aux.i2c_device_addr = BMM150_DEFAULT_I2C_ADDRESS; + config[AUX].cfg.aux.manual_en = BMI2_ENABLE; + config[AUX].cfg.aux.fcu_write_en = BMI2_ENABLE; + config[AUX].cfg.aux.man_rd_burst = BMI2_AUX_READ_LEN_3; + config[AUX].cfg.aux.read_addr = BMM150_REG_DATA_X_LSB; + + /* Set new configurations for accel, gyro and aux. */ + rslt = bmi270_set_sensor_config(config, 3, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + /* Initialize bmm150. */ + rslt = bmm150_init(&bmm150_dev); + bmi2_error_codes_print_result(rslt); + + /* Set the power mode to normal mode. */ + settings.pwr_mode = BMM150_POWERMODE_NORMAL; + rslt = bmm150_set_op_mode(&settings, &bmm150_dev); + bmi2_error_codes_print_result(rslt); + + rslt = bmi270_get_sensor_config(config, 3, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + /* Disable manual mode so that the data mode is enabled. */ + config[AUX].cfg.aux.manual_en = BMI2_DISABLE; + + /* Set the aux configurations. */ + rslt = bmi270_set_sensor_config(config, 3, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + printf("MAGNETOMETER, ACCEL, AND GYRO DATA IN DATA MODE\n"); + + if (bmm150_dev.chip_id == BMM150_CHIP_ID) + { + while (limit--) + { + /* Delay has been added to get aux, accel and gyro data at the interval of every 0.05 second. */ + bmi2_dev.delay_us(50000, bmi2_dev.intf_ptr); + + rslt = bmi270_get_sensor_data(sensor_data, 3, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + if (rslt == BMI2_OK) + { + printf("\nAcc_x = %d\t", sensor_data[ACCEL].sens_data.acc.x); + printf("Acc_y = %d\t", sensor_data[ACCEL].sens_data.acc.y); + printf("Acc_z = %d", sensor_data[ACCEL].sens_data.acc.z); + + /* Converting lsb to meter per second squared for 16 bit accelerometer at 2G range. */ + x = lsb_to_mps2(sensor_data[ACCEL].sens_data.acc.x, 2, bmi2_dev.resolution); + y = lsb_to_mps2(sensor_data[ACCEL].sens_data.acc.y, 2, bmi2_dev.resolution); + z = lsb_to_mps2(sensor_data[ACCEL].sens_data.acc.z, 2, bmi2_dev.resolution); + + /* Print the data in m/s2. */ + printf("\nAcc_ms2_X = %4.2f, Acc_ms2_Y = %4.2f, Acc_ms2_Z = %4.2f\n", x, y, z); + + printf("\nGyr_X = %d\t", sensor_data[GYRO].sens_data.gyr.x); + printf("Gyr_Y = %d\t", sensor_data[GYRO].sens_data.gyr.y); + printf("Gyr_Z= %d", sensor_data[GYRO].sens_data.gyr.z); + + /* Converting lsb to degree per second for 16 bit gyro at 2000dps range. */ + x = lsb_to_dps(sensor_data[GYRO].sens_data.gyr.x, 2000, bmi2_dev.resolution); + y = lsb_to_dps(sensor_data[GYRO].sens_data.gyr.y, 2000, bmi2_dev.resolution); + z = lsb_to_dps(sensor_data[GYRO].sens_data.gyr.z, 2000, bmi2_dev.resolution); + + /* Print the data in dps. */ + printf("\nGyro_DPS_X = %4.2f, Gyro_DPS_Y = %4.2f, Gyro_DPS_Z = %4.2f\n", x, y, z); + + /* Compensating the raw auxiliary data available from the BMM150 API. */ + rslt = bmm150_aux_mag_data(sensor_data[AUX].sens_data.aux_data, &mag_data, &bmm150_dev); + bmi2_error_codes_print_result(rslt); + printf("\nMag_x_axis = %d \t Mag_y_axis = %d \t Mag_z_axis = %d \t\n", + mag_data.x, + mag_data.y, + mag_data.z); + } + } + } + + bmi2_coines_deinit(); + + return rslt; +} + +/*! + * @brief This function reads the data from auxiliary sensor in manual mode. + */ +static int8_t user_aux_read(uint8_t reg_addr, uint8_t *aux_data, uint32_t len, void *intf_ptr) +{ + int8_t rslt; + + /* Discarding the parameter id as it is redundant */ + rslt = bmi2_read_aux_man_mode(reg_addr, aux_data, len, &bmi2_dev); + + return rslt; +} + +/*! + * @brief This function writes the data to auxiliary sensor in manual mode. + */ +static int8_t user_aux_write(uint8_t reg_addr, const uint8_t *aux_data, uint32_t len, void *intf_ptr) +{ + int8_t rslt; + + /* Discarding the parameter id as it is redundant */ + rslt = bmi2_write_aux_man_mode(reg_addr, aux_data, len, &bmi2_dev); + + return rslt; +} + +/*! + * Delay function map to COINES platform + */ +static void user_delay_us(uint32_t period, void *intf_ptr) +{ + coines_delay_usec(period); +} + +/*! + * @brief This function converts lsb to meter per second squared for 16 bit accelerometer at + * range 2G, 4G, 8G or 16G. + */ +static float lsb_to_mps2(int16_t val, float g_range, uint8_t bit_width) +{ + float half_scale = ((float)(1 << bit_width) / 2.0f); + + return (GRAVITY_EARTH * val * g_range) / half_scale; +} + +/*! + * @brief This function converts lsb to degree per second for 16 bit gyro at + * range 125, 250, 500, 1000 or 2000dps. + */ +static float lsb_to_dps(int16_t val, float dps, uint8_t bit_width) +{ + float half_scale = ((float)(1 << bit_width) / 2.0f); + + return (dps / ((half_scale) + BMI2_GYR_RANGE_2000)) * (val); +} diff --git a/examples/bmi270/read_aux_manual_mode/Makefile b/examples/bmi270/read_aux_manual_mode/Makefile new file mode 100644 index 0000000..cc9e6e4 --- /dev/null +++ b/examples/bmi270/read_aux_manual_mode/Makefile @@ -0,0 +1,23 @@ +COINES_INSTALL_PATH ?= ../../../.. + +EXAMPLE_FILE ?= read_aux_manual_mode.c + +API_LOCATION ?= ../.. + +COMMON_LOCATION ?= .. + +BMM150_SOURCE ?= ../../../bmm150 + +C_SRCS += \ +$(API_LOCATION)/bmi2.c \ +$(API_LOCATION)/bmi270.c \ +$(BMM150_SOURCE)/bmm150.c \ +$(COMMON_LOCATION)/common/common.c + +INCLUDEPATHS += \ +$(API_LOCATION) \ +$(BMM150_SOURCE) \ +$(COMMON_LOCATION)/common + + +include $(COINES_INSTALL_PATH)/coines.mk \ No newline at end of file diff --git a/examples/bmi270/read_aux_manual_mode/read_aux_manual_mode.c b/examples/bmi270/read_aux_manual_mode/read_aux_manual_mode.c new file mode 100644 index 0000000..ced8f59 --- /dev/null +++ b/examples/bmi270/read_aux_manual_mode/read_aux_manual_mode.c @@ -0,0 +1,322 @@ +/**\ + * Copyright (c) 2020 Bosch Sensortec GmbH. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + **/ + +/******************************************************************************/ +/*! Header Files */ +#include +#include "bmi270.h" +#include "bmm150.h" +#include "coines.h" +#include "common.h" + +/******************************************************************************/ +/*! Macro definition */ + +/*! Macros to select the sensors */ +#define ACCEL UINT8_C(0x00) +#define GYRO UINT8_C(0x01) +#define AUX UINT8_C(0x02) + +/*! Earth's gravity in m/s^2 */ +#define GRAVITY_EARTH (9.80665f) + +/*****************************************************************************/ +/*! Structure declaration */ + +/* Sensor initialization configuration. */ +struct bmi2_dev bmi2_dev; + +/******************************************************************************/ +/*! Functions */ + +/** + * user_aux_read - Reads data from auxiliary sensor in manual mode. + * + * @param[in] reg_addr : Register address. + * @param[out] aux_data : Aux data pointer to store the read data. + * @param[in] length : No of bytes to read. + * @param[in] intf_ptr : Interface pointer + * + * @return Status of execution + * @retval 0 -> Success + * @retval < 0 -> Failure Info + */ +static int8_t user_aux_read(uint8_t reg_addr, uint8_t *aux_data, uint32_t len, void *intf_ptr); + +/** + * user_aux_write - Writes data to the auxiliary sensor in manual mode. + * + * @param[in] reg_addr : Register address. + * @param[out] aux_data : Aux data pointer to store the data being written. + * @param[in] length : No of bytes to read. + * @param[in] intf_ptr : Interface pointer + * + * @return Status of execution + * @retval 0 -> Success + * @retval < 0 -> Failure Info + */ +static int8_t user_aux_write(uint8_t reg_addr, const uint8_t *aux_data, uint32_t len, void *intf_ptr); + +/*! + * @brief This function provides the delay for required time (Microsecond) as per the input provided in some of the + * APIs. + * + * @param[in] period_us : The required wait time in microsecond. + * @param[in] intf_ptr : Interface pointer + * + * @return void. + */ +static void user_delay_us(uint32_t period, void *intf_ptr); + +/*! + * @brief This function converts lsb to meter per second squared for 16 bit accelerometer at + * range 2G, 4G, 8G or 16G. + * + * @param[in] val : LSB from each axis. + * @param[in] g_range : Gravity range. + * @param[in] bit_width : Resolution for accel. + * + * @return Gravity. + */ +static float lsb_to_mps2(int16_t val, float g_range, uint8_t bit_width); + +/*! + * @brief This function converts lsb to degree per second for 16 bit gyro at + * range 125, 250, 500, 1000 or 2000dps. + * + * @param[in] val : LSB from each axis. + * @param[in] dps : Degree per second. + * @param[in] bit_width : Resolution for gyro. + * + * @return Degree per second. + */ +static float lsb_to_dps(int16_t val, float dps, uint8_t bit_width); + +/* This function starts the execution of program. */ +int main(void) +{ + /* Status of api are returned to this variable. */ + int8_t rslt; + + /* Variable to select the pull-up resistor which is set to trim register */ + uint8_t regdata; + + /* Variable to define limit to print aux data. */ + uint8_t limit = 20; + + /* Accel, Gyro and Aux sensors are listed in array. */ + uint8_t sensor_list[3] = { BMI2_ACCEL, BMI2_GYRO, BMI2_AUX }; + + /* Sensor initialization configuration. */ + struct bmm150_dev bmm150_dev; + + /* bmm150 settings configuration */ + struct bmm150_settings settings; + + /* bmm150 magnetometer data */ + struct bmm150_mag_data mag_data; + + /* Structure to define the type of the sensor and its configurations. */ + struct bmi2_sens_config config[3]; + + /* Structure to define type of sensor and their respective data. */ + struct bmi2_sensor_data sensor_data[2]; + + /* Variables to define read the accel and gyro data in float */ + float x = 0, y = 0, z = 0; + + config[ACCEL].type = BMI2_ACCEL; + config[GYRO].type = BMI2_GYRO; + config[AUX].type = BMI2_AUX; + + sensor_data[ACCEL].type = BMI2_ACCEL; + sensor_data[GYRO].type = BMI2_GYRO; + + /* Array of eight bytes to store x, y, z and r axis aux data. */ + uint8_t aux_data[8] = { 0 }; + + /* To enable the i2c interface settings for bmm150. */ + uint8_t bmm150_dev_addr = BMM150_DEFAULT_I2C_ADDRESS; + bmm150_dev.intf_ptr = &bmm150_dev_addr; + bmm150_dev.read = user_aux_read; + bmm150_dev.write = user_aux_write; + bmm150_dev.delay_us = user_delay_us; + + /* As per datasheet, aux interface with bmi270 will support only for I2C */ + bmm150_dev.intf = BMM150_I2C_INTF; + + /* Interface reference is given as a parameter + * For I2C : BMI2_I2C_INTF + * For SPI : BMI2_SPI_INTF + */ + rslt = bmi2_interface_init(&bmi2_dev, BMI2_I2C_INTF); + bmi2_error_codes_print_result(rslt); + + /* Initialize bmi270. */ + rslt = bmi270_init(&bmi2_dev); + bmi2_error_codes_print_result(rslt); + + /* Pull-up resistor 2k is set to the trim register */ + regdata = BMI2_ASDA_PUPSEL_2K; + rslt = bmi2_set_regs(BMI2_AUX_IF_TRIM, ®data, 1, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + /* Enable the accel, gyro and aux sensor. */ + rslt = bmi270_sensor_enable(sensor_list, 3, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + /* Get default configurations for the type of feature selected. */ + rslt = bmi270_get_sensor_config(config, 3, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + /* Configurations for accel. */ + config[ACCEL].cfg.acc.filter_perf = BMI2_PERF_OPT_MODE; + config[ACCEL].cfg.acc.bwp = BMI2_ACC_OSR2_AVG2; + config[ACCEL].cfg.acc.odr = BMI2_ACC_ODR_100HZ; + config[ACCEL].cfg.acc.range = BMI2_ACC_RANGE_2G; + + /* Configurations for gyro. */ + config[GYRO].cfg.gyr.filter_perf = BMI2_PERF_OPT_MODE; + config[GYRO].cfg.gyr.noise_perf = BMI2_GYR_RANGE_2000; + config[GYRO].cfg.gyr.bwp = BMI2_GYR_OSR2_MODE; + config[GYRO].cfg.gyr.odr = BMI2_GYR_ODR_100HZ; + config[GYRO].cfg.gyr.range = BMI2_GYR_RANGE_2000; + config[GYRO].cfg.gyr.ois_range = BMI2_GYR_OIS_2000; + + /* Configurations for aux. */ + config[AUX].cfg.aux.odr = BMI2_AUX_ODR_100HZ; + config[AUX].cfg.aux.aux_en = BMI2_ENABLE; + config[AUX].cfg.aux.i2c_device_addr = BMM150_DEFAULT_I2C_ADDRESS; + config[AUX].cfg.aux.manual_en = BMI2_ENABLE; + config[AUX].cfg.aux.fcu_write_en = BMI2_ENABLE; + config[AUX].cfg.aux.man_rd_burst = BMI2_AUX_READ_LEN_3; + + /* Set new configurations for accel, gyro and aux. */ + rslt = bmi270_set_sensor_config(config, 3, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + /* Initialize bmm150. */ + rslt = bmm150_init(&bmm150_dev); + bmi2_error_codes_print_result(rslt); + + /* Set the power mode to normal mode. */ + settings.pwr_mode = BMM150_POWERMODE_NORMAL; + rslt = bmm150_set_op_mode(&settings, &bmm150_dev); + bmi2_error_codes_print_result(rslt); + + printf("MAGNETOMETER, ACCEL AND GYRO DATA IN MANUAL MODE\n"); + + if (bmm150_dev.chip_id == BMM150_CHIP_ID) + { + while (limit--) + { + /* Delay has been added to get aux, accel and gyro data at the interval of every 0.05 second. */ + bmi2_dev.delay_us(50000, bmi2_dev.intf_ptr); + + rslt = bmi270_get_sensor_data(sensor_data, 2, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + if (rslt == BMI2_OK) + { + printf("\nAcc_x = %d\t", sensor_data[ACCEL].sens_data.acc.x); + printf("Acc_y = %d\t", sensor_data[ACCEL].sens_data.acc.y); + printf("Acc_z = %d", sensor_data[ACCEL].sens_data.acc.z); + + /* Converting lsb to meter per second squared for 16 bit accelerometer at 2G range. */ + x = lsb_to_mps2(sensor_data[ACCEL].sens_data.acc.x, 2, bmi2_dev.resolution); + y = lsb_to_mps2(sensor_data[ACCEL].sens_data.acc.y, 2, bmi2_dev.resolution); + z = lsb_to_mps2(sensor_data[ACCEL].sens_data.acc.z, 2, bmi2_dev.resolution); + + /* Print the data in m/s2. */ + printf("\nAcc_ms2_X = %4.2f, Acc_ms2_Y = %4.2f, Acc_ms2_Z = %4.2f\n", x, y, z); + + printf("\nGyr_X = %d\t", sensor_data[GYRO].sens_data.gyr.x); + printf("Gyr_Y = %d\t", sensor_data[GYRO].sens_data.gyr.y); + printf("Gyr_Z = %d", sensor_data[GYRO].sens_data.gyr.z); + + /* Converting lsb to degree per second for 16 bit gyro at 2000dps range. */ + x = lsb_to_dps(sensor_data[GYRO].sens_data.gyr.x, 2000, bmi2_dev.resolution); + y = lsb_to_dps(sensor_data[GYRO].sens_data.gyr.y, 2000, bmi2_dev.resolution); + z = lsb_to_dps(sensor_data[GYRO].sens_data.gyr.z, 2000, bmi2_dev.resolution); + + /* Print the data in dps. */ + printf("\nGyro_DPS_X = %4.2f, Gyro_DPS_Y = %4.2f, Gyro_DPS_Z = %4.2f\n", x, y, z); + } + + /* Read aux data from the bmm150 data registers. */ + rslt = bmi2_read_aux_man_mode(BMM150_REG_DATA_X_LSB, aux_data, 8, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + if (rslt == BMI2_OK) + { + /* Compensating the raw auxiliary data available from the BMM150 API. */ + rslt = bmm150_aux_mag_data(aux_data, &mag_data, &bmm150_dev); + bmi2_error_codes_print_result(rslt); + printf("Mag_x_axis = %d \t Mag_y_axis = %d \t Mag_z_axis = %d \t\n", mag_data.x, mag_data.y, + mag_data.z); + } + } + } + + bmi2_coines_deinit(); + + return rslt; +} + +/*! + * @brief This function reads the data from auxiliary sensor in manual mode. + */ +int8_t user_aux_read(uint8_t reg_addr, uint8_t *aux_data, uint32_t len, void *intf_ptr) +{ + int8_t rslt; + + /* Discarding the parameter id as it is redundant */ + rslt = bmi2_read_aux_man_mode(reg_addr, aux_data, len, &bmi2_dev); + + return rslt; +} + +/*! + * @brief This function writes the data to auxiliary sensor in manual mode. + */ +int8_t user_aux_write(uint8_t reg_addr, const uint8_t *aux_data, uint32_t len, void *intf_ptr) +{ + int8_t rslt; + + /* Discarding the parameter id as it is redundant */ + rslt = bmi2_write_aux_man_mode(reg_addr, aux_data, len, &bmi2_dev); + + return rslt; +} + +/*! + * Delay function map to COINES platform + */ +static void user_delay_us(uint32_t period, void *intf_ptr) +{ + coines_delay_usec(period); +} + +/*! + * @brief This function converts lsb to meter per second squared for 16 bit accelerometer at + * range 2G, 4G, 8G or 16G. + */ +static float lsb_to_mps2(int16_t val, float g_range, uint8_t bit_width) +{ + float half_scale = ((float)(1 << bit_width) / 2.0f); + + return (GRAVITY_EARTH * val * g_range) / half_scale; +} + +/*! + * @brief This function converts lsb to degree per second for 16 bit gyro at + * range 125, 250, 500, 1000 or 2000dps. + */ +static float lsb_to_dps(int16_t val, float dps, uint8_t bit_width) +{ + float half_scale = ((float)(1 << bit_width) / 2.0f); + + return (dps / ((half_scale) + BMI2_GYR_RANGE_2000)) * (val); +} diff --git a/examples/bmi270/sig_motion/Makefile b/examples/bmi270/sig_motion/Makefile new file mode 100644 index 0000000..97edcc2 --- /dev/null +++ b/examples/bmi270/sig_motion/Makefile @@ -0,0 +1,18 @@ +COINES_INSTALL_PATH ?= ../../../.. + +EXAMPLE_FILE ?= sig_motion.c + +API_LOCATION ?= ../.. + +COMMON_LOCATION ?= .. + +C_SRCS += \ +$(API_LOCATION)/bmi2.c \ +$(API_LOCATION)/bmi270.c \ +$(COMMON_LOCATION)/common/common.c + +INCLUDEPATHS += \ +$(API_LOCATION) \ +$(COMMON_LOCATION)/common + +include $(COINES_INSTALL_PATH)/coines.mk \ No newline at end of file diff --git a/examples/bmi270/generic/sig_motion.c b/examples/bmi270/sig_motion/sig_motion.c similarity index 85% rename from examples/bmi270/generic/sig_motion.c rename to examples/bmi270/sig_motion/sig_motion.c index e90e08a..47e1c28 100644 --- a/examples/bmi270/generic/sig_motion.c +++ b/examples/bmi270/sig_motion/sig_motion.c @@ -1,94 +1,93 @@ -/**\ - * Copyright (c) 2020 Bosch Sensortec GmbH. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - **/ - -/******************************************************************************/ -/*! Header Files */ -#include -#include "bmi2.h" -#include "bmi270.h" -#include "bmi2_common.h" - -/******************************************************************************/ -/*! Functions */ - -/* This function starts the execution of program. */ -int main(void) -{ - - /* Status of api are returned to this variable. */ - int8_t rslt; - - /* Structure to define the type of sensor and its configurations. */ - struct bmi2_sens_config config; - - /* Accel sensor and significant-motion feature are listed in array. */ - uint8_t sens_list[2] = { BMI2_ACCEL, BMI2_SIG_MOTION }; - - /* Variable to get significant-motion interrupt status. */ - uint16_t int_status = 0; - - /*! Sensor initialization configuration. */ - struct bmi2_dev bmi2_dev; - - /* Select features and their pins to be mapped to. */ - struct bmi2_sens_int_config sens_int = { .type = BMI2_SIG_MOTION, .hw_int_pin = BMI2_INT1 }; - - /* Initialize the dev structure */ - rslt = bmi2_interface_selection(&bmi2_dev); - bmi2_error_codes_print_result(rslt); - - /* Initialize bmi270. */ - rslt = bmi270_init(&bmi2_dev); - bmi2_error_codes_print_result(rslt); - - if (rslt == BMI2_OK) - { - - /* Enable the selected sensors. */ - rslt = bmi2_sensor_enable(sens_list, 2, &bmi2_dev); - bmi2_error_codes_print_result(rslt); - - /* Configure the type of feature. */ - config.type = BMI2_SIG_MOTION; - - if (rslt == BMI2_OK) - { - - /* Get default configurations for the type of feature selected. */ - rslt = bmi2_get_sensor_config(&config, 1, &bmi2_dev); - bmi2_error_codes_print_result(rslt); - - if (rslt == BMI2_OK) - { - - /* Map the feature interrupt for significant-motion. */ - rslt = bmi2_map_feat_int(&sens_int, 1, &bmi2_dev); - bmi2_error_codes_print_result(rslt); - - /* By default the significant-motion interrupt occurs when the sensor is in motion for about 5 seconds. - * */ - printf("Move the board for 5 secs in any direction\n"); - - do - { - - /* To get the interrupt status of significant-motion. */ - rslt = bmi2_get_int_status(&int_status, &bmi2_dev); - bmi2_error_codes_print_result(rslt); - - /* To check the interrupt status of significant-motion. */ - if (int_status & BMI270_SIG_MOT_STATUS_MASK) - { - printf("Significant motion interrupt is generated\n"); - break; - } - } while (rslt == BMI2_OK); - } - } - } - - return rslt; -} +/**\ + * Copyright (c) 2020 Bosch Sensortec GmbH. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + **/ + +/******************************************************************************/ +/*! Header Files */ +#include +#include "bmi270.h" +#include "common.h" + +/******************************************************************************/ +/*! Functions */ + +/* This function starts the execution of program. */ +int main(void) +{ + /* Status of api are returned to this variable. */ + int8_t rslt; + + /* Structure to define the type of sensor and its configurations. */ + struct bmi2_sens_config config; + + /* Accel sensor and significant-motion feature are listed in array. */ + uint8_t sens_list[2] = { BMI2_ACCEL, BMI2_SIG_MOTION }; + + /* Variable to get significant-motion interrupt status. */ + uint16_t int_status = 0; + + /* Sensor initialization configuration. */ + struct bmi2_dev bmi2_dev; + + /* Select features and their pins to be mapped to. */ + struct bmi2_sens_int_config sens_int = { .type = BMI2_SIG_MOTION, .hw_int_pin = BMI2_INT1 }; + + /* Interface reference is given as a parameter + * For I2C : BMI2_I2C_INTF + * For SPI : BMI2_SPI_INTF + */ + rslt = bmi2_interface_init(&bmi2_dev, BMI2_I2C_INTF); + bmi2_error_codes_print_result(rslt); + + /* Initialize bmi270. */ + rslt = bmi270_init(&bmi2_dev); + bmi2_error_codes_print_result(rslt); + + if (rslt == BMI2_OK) + { + /* Enable the selected sensors. */ + rslt = bmi270_sensor_enable(sens_list, 2, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + /* Configure the type of feature. */ + config.type = BMI2_SIG_MOTION; + + if (rslt == BMI2_OK) + { + /* Get default configurations for the type of feature selected. */ + rslt = bmi270_get_sensor_config(&config, 1, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + if (rslt == BMI2_OK) + { + /* Map the feature interrupt for significant-motion. */ + rslt = bmi270_map_feat_int(&sens_int, 1, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + /* By default the significant-motion interrupt occurs when the sensor is in motion for about 5 seconds. + * */ + printf("Move the board for 5 secs in any direction\n"); + + do + { + /* To get the interrupt status of significant-motion. */ + rslt = bmi2_get_int_status(&int_status, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + /* To check the interrupt status of significant-motion. */ + if (int_status & BMI270_SIG_MOT_STATUS_MASK) + { + printf("Significant motion interrupt is generated\n"); + break; + } + } while (rslt == BMI2_OK); + } + } + } + + bmi2_coines_deinit(); + + return rslt; +} diff --git a/examples/bmi270/step_activity/Makefile b/examples/bmi270/step_activity/Makefile new file mode 100644 index 0000000..91962d5 --- /dev/null +++ b/examples/bmi270/step_activity/Makefile @@ -0,0 +1,18 @@ +COINES_INSTALL_PATH ?= ../../../.. + +EXAMPLE_FILE ?= step_activity.c + +API_LOCATION ?= ../.. + +COMMON_LOCATION ?= .. + +C_SRCS += \ +$(API_LOCATION)/bmi2.c \ +$(API_LOCATION)/bmi270.c \ +$(COMMON_LOCATION)/common/common.c + +INCLUDEPATHS += \ +$(API_LOCATION) \ +$(COMMON_LOCATION)/common + +include $(COINES_INSTALL_PATH)/coines.mk \ No newline at end of file diff --git a/examples/bmi270/generic/step_activity.c b/examples/bmi270/step_activity/step_activity.c similarity index 83% rename from examples/bmi270/generic/step_activity.c rename to examples/bmi270/step_activity/step_activity.c index 93e22cb..87775b7 100644 --- a/examples/bmi270/generic/step_activity.c +++ b/examples/bmi270/step_activity/step_activity.c @@ -1,111 +1,110 @@ -/**\ - * Copyright (c) 2020 Bosch Sensortec GmbH. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - **/ - -/******************************************************************************/ -/*! Header Files */ -#include -#include "bmi2.h" -#include "bmi270.h" -#include "bmi2_common.h" - -/******************************************************************************/ -/*! Functions */ -/* This function starts the execution of program. */ -int main(void) -{ - - /*! Sensor initialization configuration. */ - struct bmi2_dev bmi2_dev; - - /* Structure to define the type of sensor and their respective data. */ - struct bmi2_sensor_data sensor_data; - - /* Structure to define the type of sensor and its configurations. */ - struct bmi2_sens_config config; - - /* Status of api are returned to this variable. */ - int8_t rslt; - - /* Accel sensor and step activity feature are listed in array. */ - uint8_t sensor_sel[2] = { BMI2_ACCEL, BMI2_STEP_ACTIVITY }; - - /* Type of sensor to get step activity data. */ - sensor_data.type = BMI2_STEP_ACTIVITY; - - /* Variable to get step activity interrupt status. */ - uint16_t int_status = 0; - - uint16_t loop = 100; - - /* Select features and their pins to be mapped to. */ - struct bmi2_sens_int_config sens_int = { .type = BMI2_STEP_ACTIVITY, .hw_int_pin = BMI2_INT2 }; - - /* Initialize the dev structure */ - rslt = bmi2_interface_selection(&bmi2_dev); - bmi2_error_codes_print_result(rslt); - - /* The step activities are listed in array. */ - const char *activity_output[4] = { "BMI2_STILL", "BMI2_WALK", "BMI2_RUN", "BMI2_UNKNOWN" }; - - /* Initialize bmi270. */ - rslt = bmi270_init(&bmi2_dev); - bmi2_error_codes_print_result(rslt); - - if (rslt == BMI2_OK) - { - - /* Enable the selected sensor. */ - rslt = bmi2_sensor_enable(sensor_sel, 2, &bmi2_dev); - bmi2_error_codes_print_result(rslt); - - /* Configure the type of sensor. */ - config.type = BMI2_STEP_ACTIVITY; - - if (rslt == BMI2_OK) - { - - /* Get default configurations for the type of feature selected. */ - rslt = bmi2_get_sensor_config(&config, 1, &bmi2_dev); - bmi2_error_codes_print_result(rslt); - - if (rslt == BMI2_OK) - { - - /* Map the feature interrupt for step activity. */ - rslt = bmi2_map_feat_int(&sens_int, 1, &bmi2_dev); - bmi2_error_codes_print_result(rslt); - - printf("\nMove the board in steps to perform step activity:\n"); - - /* Loop to get step activity. */ - while (loop) - { - - /* To get the interrupt status of step detector. */ - rslt = bmi2_get_int_status(&int_status, &bmi2_dev); - bmi2_error_codes_print_result(rslt); - - /* To check the interrupt status of step detector. */ - if (int_status & BMI270_STEP_ACT_STATUS_MASK) - { - printf("Step detected\n"); - - /* Get step activity output. */ - rslt = bmi2_get_sensor_data(&sensor_data, 1, &bmi2_dev); - bmi2_error_codes_print_result(rslt); - - /* Print the step activity output. */ - printf("Step activity = %s\n", activity_output[sensor_data.sens_data.activity_output]); - } - - loop--; - } - } - } - } - - return rslt; -} +/**\ + * Copyright (c) 2020 Bosch Sensortec GmbH. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + **/ + +/******************************************************************************/ +/*! Header Files */ +#include +#include "bmi270.h" +#include "common.h" + +/******************************************************************************/ +/*! Functions */ +/* This function starts the execution of program. */ +int main(void) +{ + /* Sensor initialization configuration. */ + struct bmi2_dev bmi2_dev; + + /* Structure to define the type of sensor and their respective data. */ + struct bmi2_sensor_data sensor_data; + + /* Structure to define the type of sensor and its configurations. */ + struct bmi2_sens_config config; + + /* Status of api are returned to this variable. */ + int8_t rslt; + + /* Accel sensor and step activity feature are listed in array. */ + uint8_t sensor_sel[2] = { BMI2_ACCEL, BMI2_STEP_ACTIVITY }; + + /* Type of sensor to get step activity data. */ + sensor_data.type = BMI2_STEP_ACTIVITY; + + /* Variable to get step activity interrupt status. */ + uint16_t int_status = 0; + + uint16_t loop = 10; + + /* Select features and their pins to be mapped to. */ + struct bmi2_sens_int_config sens_int = { .type = BMI2_STEP_ACTIVITY, .hw_int_pin = BMI2_INT2 }; + + /* The step activities are listed in array. */ + const char *activity_output[4] = { "BMI2_STILL", "BMI2_WALK", "BMI2_RUN", "BMI2_UNKNOWN" }; + + /* Interface reference is given as a parameter + * For I2C : BMI2_I2C_INTF + * For SPI : BMI2_SPI_INTF + */ + rslt = bmi2_interface_init(&bmi2_dev, BMI2_I2C_INTF); + bmi2_error_codes_print_result(rslt); + + /* Initialize bmi270. */ + rslt = bmi270_init(&bmi2_dev); + bmi2_error_codes_print_result(rslt); + + if (rslt == BMI2_OK) + { + /* Enable the selected sensor. */ + rslt = bmi270_sensor_enable(sensor_sel, 2, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + /* Configure the type of sensor. */ + config.type = BMI2_STEP_ACTIVITY; + + if (rslt == BMI2_OK) + { + /* Get default configurations for the type of feature selected. */ + rslt = bmi270_get_sensor_config(&config, 1, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + if (rslt == BMI2_OK) + { + /* Map the feature interrupt for step activity. */ + rslt = bmi270_map_feat_int(&sens_int, 1, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + printf("\nMove the board in steps to perform step activity:\n"); + + /* Loop to get step activity. */ + while (loop) + { + /* To get the interrupt status of step detector. */ + rslt = bmi2_get_int_status(&int_status, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + /* To check the interrupt status of step detector. */ + if (int_status & BMI270_STEP_ACT_STATUS_MASK) + { + printf("Step detected\n"); + + /* Get step activity output. */ + rslt = bmi270_get_sensor_data(&sensor_data, 1, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + /* Print the step activity output. */ + printf("Step activity = %s\n", activity_output[sensor_data.sens_data.activity_output]); + + loop--; + } + } + } + } + } + + bmi2_coines_deinit(); + + return rslt; +} diff --git a/examples/bmi270/step_counter/Makefile b/examples/bmi270/step_counter/Makefile new file mode 100644 index 0000000..b47fb0e --- /dev/null +++ b/examples/bmi270/step_counter/Makefile @@ -0,0 +1,18 @@ +COINES_INSTALL_PATH ?= ../../../.. + +EXAMPLE_FILE ?= step_counter.c + +API_LOCATION ?= ../.. + +COMMON_LOCATION ?= .. + +C_SRCS += \ +$(API_LOCATION)/bmi2.c \ +$(API_LOCATION)/bmi270.c \ +$(COMMON_LOCATION)/common/common.c + +INCLUDEPATHS += \ +$(API_LOCATION) \ +$(COMMON_LOCATION)/common + +include $(COINES_INSTALL_PATH)/coines.mk \ No newline at end of file diff --git a/examples/bmi270/generic/step_counter.c b/examples/bmi270/step_counter/step_counter.c similarity index 84% rename from examples/bmi270/generic/step_counter.c rename to examples/bmi270/step_counter/step_counter.c index 1a01608..b08f958 100644 --- a/examples/bmi270/generic/step_counter.c +++ b/examples/bmi270/step_counter/step_counter.c @@ -1,147 +1,146 @@ -/**\ - * Copyright (c) 2020 Bosch Sensortec GmbH. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - **/ - -/******************************************************************************/ -/*! Header Files */ -#include -#include "bmi2.h" -#include "bmi270.h" -#include "bmi2_common.h" - -/******************************************************************************/ -/*! Static function declaration */ - -/*! - * @brief This internal API is used to set configurations for step counter. - * - * @param[in] bmi2_dev : Structure instance of bmi2_dev. - * - * @return Status of execution. - */ -static int8_t set_feature_config(struct bmi2_dev *bmi2_dev); - -/******************************************************************************/ -/*! Functions */ - -/* This function starts the execution of program. */ -int main(void) -{ - - /*! Sensor initialization configuration. */ - struct bmi2_dev bmi2_dev; - - /* Structure to define type of sensor and their respective data. */ - struct bmi2_sensor_data sensor_data; - - /* Status of api are returned to this variable. */ - int8_t rslt; - - /* Accel sensor and step counter feature are listed in array. */ - uint8_t sensor_sel[2] = { BMI2_ACCEL, BMI2_STEP_COUNTER }; - - /* Variable to get step counter interrupt status. */ - uint16_t int_status = 0; - - /* Select features and their pins to be mapped to. */ - struct bmi2_sens_int_config sens_int = { .type = BMI2_STEP_COUNTER, .hw_int_pin = BMI2_INT2 }; - - /* Type of sensor to get step counter data. */ - sensor_data.type = BMI2_STEP_COUNTER; - - /* Initialize the dev structure */ - rslt = bmi2_interface_selection(&bmi2_dev); - bmi2_error_codes_print_result(rslt); - - /* Initialize bmi270. */ - rslt = bmi270_init(&bmi2_dev); - bmi2_error_codes_print_result(rslt); - - if (rslt == BMI2_OK) - { - - /* Enable the selected sensor. */ - rslt = bmi2_sensor_enable(sensor_sel, 2, &bmi2_dev); - bmi2_error_codes_print_result(rslt); - - if (rslt == BMI2_OK) - { - - /* Set the feature configuration for step counter. */ - rslt = set_feature_config(&bmi2_dev); - bmi2_error_codes_print_result(rslt); - - if (rslt == BMI2_OK) - { - - /* Map the step counter feature interrupt. */ - rslt = bmi2_map_feat_int(&sens_int, 1, &bmi2_dev); - bmi2_error_codes_print_result(rslt); - - /* Move the board in steps for 20 times to get step counter interrupt. */ - printf("Move the board in steps\n"); - - /* Loop to get number of steps counted. */ - do - { - - /* To get the interrupt status of the step counter. */ - rslt = bmi2_get_int_status(&int_status, &bmi2_dev); - bmi2_error_codes_print_result(rslt); - - /* To check the interrupt status of the step counter. */ - if (int_status & BMI270_STEP_CNT_STATUS_MASK) - { - printf("Step detected\n"); - - /* Get step counter output. */ - rslt = bmi2_get_sensor_data(&sensor_data, 1, &bmi2_dev); - bmi2_error_codes_print_result(rslt); - - /* Print the step counter output. */ - printf("No of steps counted = %ld", sensor_data.sens_data.step_counter_output); - break; - } - } while (rslt == BMI2_OK); - } - } - } - - return rslt; -} - -/*! - * @brief This internal API is used to set configurations for step counter. - */ -static int8_t set_feature_config(struct bmi2_dev *bmi2_dev) -{ - - /* Status of api are returned to this variable. */ - int8_t rslt; - - /* Structure to define the type of sensor and its configurations. */ - struct bmi2_sens_config config; - - /* Configure the type of sensor. */ - config.type = BMI2_STEP_COUNTER; - - /* Get default configurations for the type of feature selected. */ - rslt = bmi2_get_sensor_config(&config, 1, bmi2_dev); - bmi2_error_codes_print_result(rslt); - - if (rslt == BMI2_OK) - { - - /* Setting water-mark level to 1 for step counter to get interrupt after 20 step counts. Every 20 steps once - * output triggers. */ - config.cfg.step_counter.watermark_level = 1; - - /* Set new configuration. */ - rslt = bmi2_set_sensor_config(&config, 1, bmi2_dev); - bmi2_error_codes_print_result(rslt); - } - - return rslt; -} +/**\ + * Copyright (c) 2020 Bosch Sensortec GmbH. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + **/ + +/******************************************************************************/ +/*! Header Files */ +#include +#include "bmi270.h" +#include "common.h" + +/******************************************************************************/ +/*! Static function declaration */ + +/*! + * @brief This internal API is used to set configurations for step counter. + * + * @param[in] bmi2_dev : Structure instance of bmi2_dev. + * + * @return Status of execution. + */ +static int8_t set_feature_config(struct bmi2_dev *bmi2_dev); + +/******************************************************************************/ +/*! Functions */ + +/* This function starts the execution of program. */ +int main(void) +{ + /* Sensor initialization configuration. */ + struct bmi2_dev bmi2_dev; + + /* Structure to define type of sensor and their respective data. */ + struct bmi2_sensor_data sensor_data; + + /* Status of api are returned to this variable. */ + int8_t rslt; + + /* Accel sensor and step counter feature are listed in array. */ + uint8_t sensor_sel[2] = { BMI2_ACCEL, BMI2_STEP_COUNTER }; + + /* Variable to get step counter interrupt status. */ + uint16_t int_status = 0; + + /* Select features and their pins to be mapped to. */ + struct bmi2_sens_int_config sens_int = { .type = BMI2_STEP_COUNTER, .hw_int_pin = BMI2_INT2 }; + + /* Type of sensor to get step counter data. */ + sensor_data.type = BMI2_STEP_COUNTER; + + /* Interface reference is given as a parameter + * For I2C : BMI2_I2C_INTF + * For SPI : BMI2_SPI_INTF + */ + rslt = bmi2_interface_init(&bmi2_dev, BMI2_I2C_INTF); + bmi2_error_codes_print_result(rslt); + + /* Initialize bmi270. */ + rslt = bmi270_init(&bmi2_dev); + bmi2_error_codes_print_result(rslt); + + if (rslt == BMI2_OK) + { + /* Enable the selected sensor. */ + rslt = bmi270_sensor_enable(sensor_sel, 2, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + if (rslt == BMI2_OK) + { + /* Set the feature configuration for step counter. */ + rslt = set_feature_config(&bmi2_dev); + bmi2_error_codes_print_result(rslt); + + printf("Step counter watermark level set to 1 (20 steps)\n"); + + if (rslt == BMI2_OK) + { + /* Map the step counter feature interrupt. */ + rslt = bmi270_map_feat_int(&sens_int, 1, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + /* Move the board in steps for 20 times to get step counter interrupt. */ + printf("Move the board in steps\n"); + + /* Loop to get number of steps counted. */ + do + { + /* To get the interrupt status of the step counter. */ + rslt = bmi2_get_int_status(&int_status, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + /* To check the interrupt status of the step counter. */ + if (int_status & BMI270_STEP_CNT_STATUS_MASK) + { + printf("Step counter interrupt occurred when watermark level (20 steps) is reached\n"); + + /* Get step counter output. */ + rslt = bmi270_get_sensor_data(&sensor_data, 1, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + /* Print the step counter output. */ + printf("No of steps counted = %ld", sensor_data.sens_data.step_counter_output); + break; + } + } while (rslt == BMI2_OK); + } + } + } + + bmi2_coines_deinit(); + + return rslt; +} + +/*! + * @brief This internal API is used to set configurations for step counter. + */ +static int8_t set_feature_config(struct bmi2_dev *bmi2_dev) +{ + /* Status of api are returned to this variable. */ + int8_t rslt; + + /* Structure to define the type of sensor and its configurations. */ + struct bmi2_sens_config config; + + /* Configure the type of sensor. */ + config.type = BMI2_STEP_COUNTER; + + /* Get default configurations for the type of feature selected. */ + rslt = bmi270_get_sensor_config(&config, 1, bmi2_dev); + bmi2_error_codes_print_result(rslt); + + if (rslt == BMI2_OK) + { + /* Setting water-mark level to 1 for step counter to get interrupt after 20 step counts. Every 20 steps once + * output triggers. */ + config.cfg.step_counter.watermark_level = 1; + + /* Set new configuration. */ + rslt = bmi270_set_sensor_config(&config, 1, bmi2_dev); + bmi2_error_codes_print_result(rslt); + } + + return rslt; +} diff --git a/examples/bmi270/wrist_gesture/Makefile b/examples/bmi270/wrist_gesture/Makefile new file mode 100644 index 0000000..0f95990 --- /dev/null +++ b/examples/bmi270/wrist_gesture/Makefile @@ -0,0 +1,18 @@ +COINES_INSTALL_PATH ?= ../../../.. + +EXAMPLE_FILE ?= wrist_gesture.c + +API_LOCATION ?= ../.. + +COMMON_LOCATION ?= .. + +C_SRCS += \ +$(API_LOCATION)/bmi2.c \ +$(API_LOCATION)/bmi270.c \ +$(COMMON_LOCATION)/common/common.c + +INCLUDEPATHS += \ +$(API_LOCATION) \ +$(COMMON_LOCATION)/common + +include $(COINES_INSTALL_PATH)/coines.mk \ No newline at end of file diff --git a/examples/bmi270/generic/wrist_gesture.c b/examples/bmi270/wrist_gesture/wrist_gesture.c similarity index 86% rename from examples/bmi270/generic/wrist_gesture.c rename to examples/bmi270/wrist_gesture/wrist_gesture.c index 98a1cae..be494b8 100644 --- a/examples/bmi270/generic/wrist_gesture.c +++ b/examples/bmi270/wrist_gesture/wrist_gesture.c @@ -1,148 +1,147 @@ -/**\ - * Copyright (c) 2020 Bosch Sensortec GmbH. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - **/ - -/******************************************************************************/ -/*! Header Files */ -#include -#include "bmi2.h" -#include "bmi270.h" -#include "bmi2_common.h" - -/******************************************************************************/ -/*! Static function declaration */ - -/*! - * @brief This internal API is used to set the sensor configuration. - * - * @param[in] bmi2_dev : Structure instance of bmi2_dev. - * - * @return Status of execution. - */ -static int8_t bmi2_set_config(struct bmi2_dev *bmi2_dev); - -/******************************************************************************/ -/*! Functions */ - -/* This function starts the execution of program */ -int main(void) -{ - - /* Variable to define result */ - int8_t rslt; - - /* Initialize status of wrist gesture interrupt */ - uint16_t int_status = 0; - - /*! Sensor initialization configuration. */ - struct bmi2_dev bmi2_dev; - - /* Select features and their pins to be mapped to */ - struct bmi2_sens_int_config sens_int = { .type = BMI2_WRIST_GESTURE, .hw_int_pin = BMI2_INT1 }; - - /* Sensor data structure */ - struct bmi2_sensor_data sens_data = { 0 }; - - /* Initialize the dev structure */ - rslt = bmi2_interface_selection(&bmi2_dev); - bmi2_error_codes_print_result(rslt); - - /* The gesture movements are listed in array */ - const char *gesture_output[6] = - { "unknown_gesture", "push_arm_down", "pivot_up", "wrist_shake_jiggle", "flick_in", "flick_out" }; - - /* Initialize bmi270. */ - rslt = bmi270_init(&bmi2_dev); - bmi2_error_codes_print_result(rslt); - - if (rslt == BMI2_OK) - { - sens_data.type = BMI2_WRIST_GESTURE; - - /* Set the sensor configuration */ - rslt = bmi2_set_config(&bmi2_dev); - bmi2_error_codes_print_result(rslt); - - if (rslt == BMI2_OK) - { - - /* Map the feature interrupt */ - rslt = bmi2_map_feat_int(&sens_int, 1, &bmi2_dev); - bmi2_error_codes_print_result(rslt); - - if (rslt == BMI2_OK) - { - printf("Flip the board in portrait/landscape mode:\n"); - - /* Loop to print the wrist gesture data when interrupt occurs */ - while (1) - { - - /* Get the interrupt status of the wrist gesture */ - rslt = bmi2_get_int_status(&int_status, &bmi2_dev); - bmi2_error_codes_print_result(rslt); - - if ((rslt == BMI2_OK) && (int_status & BMI270_WRIST_GEST_STATUS_MASK)) - { - printf("Wrist gesture detected\n"); - - /* Get wrist gesture output */ - rslt = bmi2_get_sensor_data(&sens_data, 1, &bmi2_dev); - bmi2_error_codes_print_result(rslt); - - printf("Wrist gesture = %d\r\n", sens_data.sens_data.wrist_gesture_output); - - printf("Gesture output = %s\n", gesture_output[sens_data.sens_data.wrist_gesture_output]); - break; - } - } - } - } - } - - return rslt; -} - -/*! - * @brief This internal API sets the sensor configuration - */ -static int8_t bmi2_set_config(struct bmi2_dev *bmi2_dev) -{ - - /* Variable to define result */ - int8_t rslt; - - /* List the sensors which are required to enable */ - uint8_t sens_list[2] = { BMI2_ACCEL, BMI2_WRIST_GESTURE }; - - /* Structure to define the type of the sensor and its configurations */ - struct bmi2_sens_config config; - - /* Configure type of feature */ - config.type = BMI2_WRIST_GESTURE; - - /* Enable the selected sensors */ - rslt = bmi2_sensor_enable(sens_list, 2, bmi2_dev); - bmi2_error_codes_print_result(rslt); - - if (rslt == BMI2_OK) - { - - /* Get default configurations for the type of feature selected */ - rslt = bmi2_get_sensor_config(&config, 1, bmi2_dev); - bmi2_error_codes_print_result(rslt); - - if (rslt == BMI2_OK) - { - config.cfg.wrist_gest.wearable_arm = BMI2_ARM_LEFT; - - /* Set the new configuration along with interrupt mapping */ - rslt = bmi2_set_sensor_config(&config, 1, bmi2_dev); - bmi2_error_codes_print_result(rslt); - } - } - - return rslt; -} +/**\ + * Copyright (c) 2020 Bosch Sensortec GmbH. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + **/ + +/******************************************************************************/ +/*! Header Files */ +#include +#include "bmi270.h" +#include "common.h" + +/******************************************************************************/ +/*! Static function declaration */ + +/*! + * @brief This internal API is used to set the sensor configuration. + * + * @param[in] bmi2_dev : Structure instance of bmi2_dev. + * + * @return Status of execution. + */ +static int8_t bmi2_set_config(struct bmi2_dev *bmi2_dev); + +/******************************************************************************/ +/*! Functions */ + +/* This function starts the execution of program */ +int main(void) +{ + /* Variable to define result */ + int8_t rslt; + + /* Initialize status of wrist gesture interrupt */ + uint16_t int_status = 0; + + /* Sensor initialization configuration. */ + struct bmi2_dev bmi2_dev; + + /* Select features and their pins to be mapped to */ + struct bmi2_sens_int_config sens_int = { .type = BMI2_WRIST_GESTURE, .hw_int_pin = BMI2_INT1 }; + + /* Sensor data structure */ + struct bmi2_sensor_data sens_data = { 0 }; + + /* The gesture movements are listed in array */ + const char *gesture_output[6] = + { "unknown_gesture", "push_arm_down", "pivot_up", "wrist_shake_jiggle", "flick_in", "flick_out" }; + + /* Interface reference is given as a parameter + * For I2C : BMI2_I2C_INTF + * For SPI : BMI2_SPI_INTF + */ + rslt = bmi2_interface_init(&bmi2_dev, BMI2_I2C_INTF); + bmi2_error_codes_print_result(rslt); + + /* Initialize bmi270. */ + rslt = bmi270_init(&bmi2_dev); + bmi2_error_codes_print_result(rslt); + + if (rslt == BMI2_OK) + { + sens_data.type = BMI2_WRIST_GESTURE; + + /* Set the sensor configuration */ + rslt = bmi2_set_config(&bmi2_dev); + bmi2_error_codes_print_result(rslt); + + if (rslt == BMI2_OK) + { + /* Map the feature interrupt */ + rslt = bmi270_map_feat_int(&sens_int, 1, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + if (rslt == BMI2_OK) + { + printf("Flip the board in portrait/landscape mode:\n"); + + /* Loop to print the wrist gesture data when interrupt occurs */ + while (1) + { + /* Get the interrupt status of the wrist gesture */ + rslt = bmi2_get_int_status(&int_status, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + if ((rslt == BMI2_OK) && (int_status & BMI270_WRIST_GEST_STATUS_MASK)) + { + printf("Wrist gesture detected\n"); + + /* Get wrist gesture output */ + rslt = bmi270_get_sensor_data(&sens_data, 1, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + printf("Wrist gesture = %d\r\n", sens_data.sens_data.wrist_gesture_output); + + printf("Gesture output = %s\n", gesture_output[sens_data.sens_data.wrist_gesture_output]); + break; + } + } + } + } + } + + bmi2_coines_deinit(); + + return rslt; +} + +/*! + * @brief This internal API sets the sensor configuration + */ +static int8_t bmi2_set_config(struct bmi2_dev *bmi2_dev) +{ + /* Variable to define result */ + int8_t rslt; + + /* List the sensors which are required to enable */ + uint8_t sens_list[2] = { BMI2_ACCEL, BMI2_WRIST_GESTURE }; + + /* Structure to define the type of the sensor and its configurations */ + struct bmi2_sens_config config; + + /* Configure type of feature */ + config.type = BMI2_WRIST_GESTURE; + + /* Enable the selected sensors */ + rslt = bmi270_sensor_enable(sens_list, 2, bmi2_dev); + bmi2_error_codes_print_result(rslt); + + if (rslt == BMI2_OK) + { + /* Get default configurations for the type of feature selected */ + rslt = bmi270_get_sensor_config(&config, 1, bmi2_dev); + bmi2_error_codes_print_result(rslt); + + if (rslt == BMI2_OK) + { + config.cfg.wrist_gest.wearable_arm = BMI2_ARM_LEFT; + + /* Set the new configuration along with interrupt mapping */ + rslt = bmi270_set_sensor_config(&config, 1, bmi2_dev); + bmi2_error_codes_print_result(rslt); + } + } + + return rslt; +} diff --git a/examples/bmi270/wrist_wear_wakeup/Makefile b/examples/bmi270/wrist_wear_wakeup/Makefile new file mode 100644 index 0000000..1e20da2 --- /dev/null +++ b/examples/bmi270/wrist_wear_wakeup/Makefile @@ -0,0 +1,18 @@ +COINES_INSTALL_PATH ?= ../../../.. + +EXAMPLE_FILE ?= wrist_wear_wakeup.c + +API_LOCATION ?= ../.. + +COMMON_LOCATION ?= .. + +C_SRCS += \ +$(API_LOCATION)/bmi2.c \ +$(API_LOCATION)/bmi270.c \ +$(COMMON_LOCATION)/common/common.c + +INCLUDEPATHS += \ +$(API_LOCATION) \ +$(COMMON_LOCATION)/common + +include $(COINES_INSTALL_PATH)/coines.mk \ No newline at end of file diff --git a/examples/bmi270/generic/wrist_wear_wakeup.c b/examples/bmi270/wrist_wear_wakeup/wrist_wear_wakeup.c similarity index 86% rename from examples/bmi270/generic/wrist_wear_wakeup.c rename to examples/bmi270/wrist_wear_wakeup/wrist_wear_wakeup.c index e621eab..3547b2d 100644 --- a/examples/bmi270/generic/wrist_wear_wakeup.c +++ b/examples/bmi270/wrist_wear_wakeup/wrist_wear_wakeup.c @@ -1,133 +1,131 @@ -/**\ - * Copyright (c) 2020 Bosch Sensortec GmbH. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - **/ - -/******************************************************************************/ -/*! Header Files */ -#include -#include "bmi2.h" -#include "bmi270.h" -#include "bmi2_common.h" - -/******************************************************************************/ -/*! Static function declaration */ - -/*! - * @brief This internal API is used to set the sensor configuration. - * - * @param[in] bmi2_dev : Structure instance of bmi2_dev. - * - * @return Status of execution. - */ -static int8_t bmi2_set_config(struct bmi2_dev *bmi2_dev); - -/******************************************************************************/ -/*! Functions */ - -/* This function starts the execution of program */ -int main(void) -{ - - /* Variable to define result */ - int8_t rslt; - - /* Initialize status of wrist wear wakeup interrupt */ - uint16_t int_status = 0; - - /*! Sensor initialization configuration. */ - struct bmi2_dev bmi2_dev; - - /* Select features and their pins to be mapped to */ - struct bmi2_sens_int_config sens_int = { .type = BMI2_WRIST_WEAR_WAKE_UP, .hw_int_pin = BMI2_INT1 }; - - /* Initialize the dev structure */ - rslt = bmi2_interface_selection(&bmi2_dev); - bmi2_error_codes_print_result(rslt); - - /* Initialize bmi270. */ - rslt = bmi270_init(&bmi2_dev); - bmi2_error_codes_print_result(rslt); - - if (rslt == BMI2_OK) - { - - /* Set the sensor configuration */ - rslt = bmi2_set_config(&bmi2_dev); - bmi2_error_codes_print_result(rslt); - - if (rslt == BMI2_OK) - { - - /* Map the feature interrupt */ - rslt = bmi2_map_feat_int(&sens_int, 1, &bmi2_dev); - bmi2_error_codes_print_result(rslt); - - if (rslt == BMI2_OK) - { - printf("Tilt the board in landscape position to trigger wrist wear wakeup\n"); - - /* Loop to print the wrist wear wakeup data when interrupt occurs */ - while (1) - { - int_status = 0; - - /* To get the interrupt status of the wrist wear wakeup */ - rslt = bmi2_get_int_status(&int_status, &bmi2_dev); - bmi2_error_codes_print_result(rslt); - - /* To check the interrupt status of the wrist gesture */ - if ((rslt == BMI2_OK) && (int_status & BMI270_WRIST_WAKE_UP_STATUS_MASK)) - { - printf("Wrist wear wakeup detected\n"); - break; - } - } - } - } - } - - return rslt; -} - -/*! - * @brief This internal API sets the sensor configuration - */ -static int8_t bmi2_set_config(struct bmi2_dev *bmi2_dev) -{ - - /* Variable to define result */ - int8_t rslt; - - /* List the sensors which are required to enable */ - uint8_t sens_list[2] = { BMI2_ACCEL, BMI2_WRIST_WEAR_WAKE_UP }; - - /* Structure to define the type of the sensor and its configurations */ - struct bmi2_sens_config config; - - /* Configure type of feature */ - config.type = BMI2_WRIST_WEAR_WAKE_UP; - - /* Enable the selected sensors */ - rslt = bmi2_sensor_enable(sens_list, 2, bmi2_dev); - bmi2_error_codes_print_result(rslt); - - if (rslt == BMI2_OK) - { - - /* Get default configurations for the type of feature selected */ - rslt = bmi2_get_sensor_config(&config, 1, bmi2_dev); - bmi2_error_codes_print_result(rslt); - - if (rslt == BMI2_OK) - { - - /* Set the new configuration */ - rslt = bmi2_set_sensor_config(&config, 1, bmi2_dev); - bmi2_error_codes_print_result(rslt); - } - } - - return rslt; -} +/**\ + * Copyright (c) 2020 Bosch Sensortec GmbH. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + **/ + +/******************************************************************************/ +/*! Header Files */ +#include +#include "bmi270.h" +#include "common.h" + +/******************************************************************************/ +/*! Static function declaration */ + +/*! + * @brief This internal API is used to set the sensor configuration. + * + * @param[in] bmi2_dev : Structure instance of bmi2_dev. + * + * @return Status of execution. + */ +static int8_t bmi2_set_config(struct bmi2_dev *bmi2_dev); + +/******************************************************************************/ +/*! Functions */ + +/* This function starts the execution of program */ +int main(void) +{ + /* Variable to define result */ + int8_t rslt; + + /* Initialize status of wrist wear wakeup interrupt */ + uint16_t int_status = 0; + + /* Sensor initialization configuration. */ + struct bmi2_dev bmi2_dev; + + /* Select features and their pins to be mapped to */ + struct bmi2_sens_int_config sens_int = { .type = BMI2_WRIST_WEAR_WAKE_UP, .hw_int_pin = BMI2_INT1 }; + + /* Interface reference is given as a parameter + * For I2C : BMI2_I2C_INTF + * For SPI : BMI2_SPI_INTF + */ + rslt = bmi2_interface_init(&bmi2_dev, BMI2_I2C_INTF); + bmi2_error_codes_print_result(rslt); + + /* Initialize bmi270. */ + rslt = bmi270_init(&bmi2_dev); + bmi2_error_codes_print_result(rslt); + + if (rslt == BMI2_OK) + { + /* Set the sensor configuration */ + rslt = bmi2_set_config(&bmi2_dev); + bmi2_error_codes_print_result(rslt); + + if (rslt == BMI2_OK) + { + /* Map the feature interrupt */ + rslt = bmi270_map_feat_int(&sens_int, 1, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + if (rslt == BMI2_OK) + { + printf("Tilt the board in landscape position to trigger wrist wear wakeup\n"); + + /* Loop to print the wrist wear wakeup data when interrupt occurs */ + while (1) + { + int_status = 0; + + /* To get the interrupt status of the wrist wear wakeup */ + rslt = bmi2_get_int_status(&int_status, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + /* To check the interrupt status of the wrist gesture */ + if ((rslt == BMI2_OK) && (int_status & BMI270_WRIST_WAKE_UP_STATUS_MASK)) + { + printf("Wrist wear wakeup detected\n"); + break; + } + } + } + } + } + + bmi2_coines_deinit(); + + return rslt; +} + +/*! + * @brief This internal API sets the sensor configuration + */ +static int8_t bmi2_set_config(struct bmi2_dev *bmi2_dev) +{ + /* Variable to define result */ + int8_t rslt; + + /* List the sensors which are required to enable */ + uint8_t sens_list[2] = { BMI2_ACCEL, BMI2_WRIST_WEAR_WAKE_UP }; + + /* Structure to define the type of the sensor and its configurations */ + struct bmi2_sens_config config; + + /* Configure type of feature */ + config.type = BMI2_WRIST_WEAR_WAKE_UP; + + /* Enable the selected sensors */ + rslt = bmi270_sensor_enable(sens_list, 2, bmi2_dev); + bmi2_error_codes_print_result(rslt); + + if (rslt == BMI2_OK) + { + /* Get default configurations for the type of feature selected */ + rslt = bmi270_get_sensor_config(&config, 1, bmi2_dev); + bmi2_error_codes_print_result(rslt); + + if (rslt == BMI2_OK) + { + /* Set the new configuration */ + rslt = bmi270_set_sensor_config(&config, 1, bmi2_dev); + bmi2_error_codes_print_result(rslt); + } + } + + return rslt; +} diff --git a/examples/bmi270_context/accel/Makefile b/examples/bmi270_context/accel/Makefile new file mode 100644 index 0000000..d215172 --- /dev/null +++ b/examples/bmi270_context/accel/Makefile @@ -0,0 +1,18 @@ +COINES_INSTALL_PATH ?= ../../../.. + +EXAMPLE_FILE ?= accel.c + +API_LOCATION ?= ../.. + +COMMON_LOCATION ?= .. + +C_SRCS += \ +$(API_LOCATION)/bmi2.c \ +$(API_LOCATION)/bmi270_context.c \ +$(COMMON_LOCATION)/common/common.c + +INCLUDEPATHS += \ +$(API_LOCATION) \ +$(COMMON_LOCATION)/common + +include $(COINES_INSTALL_PATH)/coines.mk \ No newline at end of file diff --git a/examples/bmi270_context/accel/accel.c b/examples/bmi270_context/accel/accel.c new file mode 100644 index 0000000..5b36fff --- /dev/null +++ b/examples/bmi270_context/accel/accel.c @@ -0,0 +1,200 @@ +/**\ + * Copyright (c) 2020 Bosch Sensortec GmbH. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + **/ + +/******************************************************************************/ +/*! Header Files */ +#include +#include "bmi270_context.h" +#include "common.h" + +/******************************************************************************/ +/*! Macro definition */ + +/*! Earth's gravity in m/s^2 */ +#define GRAVITY_EARTH (9.80665f) + +/******************************************************************************/ +/*! Static Function Declaration */ + +/*! + * @brief This internal API is used to set configurations for accel. + * + * @param[in] dev : Structure instance of bmi2_dev. + * + * @return Status of execution. + */ +static int8_t set_accel_config(struct bmi2_dev *bmi2_dev); + +/*! + * @brief This function converts lsb to meter per second squared for 16 bit accelerometer at + * range 2G, 4G, 8G or 16G. + * + * @param[in] val : LSB from each axis. + * @param[in] g_range : Gravity range. + * @param[in] bit_width : Resolution for accel. + * + * @return Gravity. + */ +static float lsb_to_mps2(int16_t val, float g_range, uint8_t bit_width); + +/******************************************************************************/ +/*! Functions */ + +/* This function starts the execution of program. */ +int main(void) +{ + /* Status of api are returned to this variable. */ + int8_t rslt; + + /* Variable to define limit to print accel data. */ + uint8_t limit = 20; + + /* Assign accel sensor to variable. */ + uint8_t sensor_list = BMI2_ACCEL; + + /* Sensor initialization configuration. */ + struct bmi2_dev bmi2_dev; + + /* Create an instance of sensor data structure. */ + struct bmi2_sensor_data sensor_data = { 0 }; + + /* Initialize the interrupt status of accel. */ + uint16_t int_status = 0; + + uint8_t indx = 0; + float x = 0, y = 0, z = 0; + + /* Interface reference is given as a parameter + * For I2C : BMI2_I2C_INTF + * For SPI : BMI2_SPI_INTF + */ + rslt = bmi2_interface_init(&bmi2_dev, BMI2_I2C_INTF); + bmi2_error_codes_print_result(rslt); + + /* Initialize bmi270_context. */ + rslt = bmi270_context_init(&bmi2_dev); + bmi2_error_codes_print_result(rslt); + + if (rslt == BMI2_OK) + { + /* Enable the accel sensor. */ + rslt = bmi270_context_sensor_enable(&sensor_list, 1, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + if (rslt == BMI2_OK) + { + /* Accel configuration settings. */ + rslt = set_accel_config(&bmi2_dev); + bmi2_error_codes_print_result(rslt); + + /* Assign accel sensor. */ + sensor_data.type = BMI2_ACCEL; + printf("Accel and m/s2 data \n"); + printf("Accel data collected at 2G Range with 16-bit resolution\n"); + + /* Loop to print the accel data when interrupt occurs. */ + while (indx <= limit) + { + /* To get the status of accel data ready interrupt. */ + rslt = bmi2_get_int_status(&int_status, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + /* To check the accel data ready interrupt status and print the status for 10 samples. */ + if (int_status & BMI2_ACC_DRDY_INT_MASK) + { + /* Get accelerometer data for x, y and z axis. */ + rslt = bmi270_context_get_sensor_data(&sensor_data, 1, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + printf("\nAcc_X = %d\t", sensor_data.sens_data.acc.x); + printf("Acc_Y = %d\t", sensor_data.sens_data.acc.y); + printf("Acc_Z = %d\r\n", sensor_data.sens_data.acc.z); + + /* Converting lsb to meter per second squared for 16 bit accelerometer at 2G range. */ + x = lsb_to_mps2(sensor_data.sens_data.acc.x, 2, bmi2_dev.resolution); + y = lsb_to_mps2(sensor_data.sens_data.acc.y, 2, bmi2_dev.resolution); + z = lsb_to_mps2(sensor_data.sens_data.acc.z, 2, bmi2_dev.resolution); + + /* Print the data in m/s2. */ + printf("\nAcc_ms2_X = %4.2f, Acc_ms2_Y = %4.2f, Acc_ms2_Z = %4.2f\n", x, y, z); + + indx++; + } + } + } + } + + bmi2_coines_deinit(); + + return rslt; +} + +/*! + * @brief This internal API is used to set configurations for accel. + */ +static int8_t set_accel_config(struct bmi2_dev *bmi2_dev) +{ + /* Status of api are returned to this variable. */ + int8_t rslt; + + /* Structure to define accelerometer configuration. */ + struct bmi2_sens_config config; + + /* Configure the type of feature. */ + config.type = BMI2_ACCEL; + + /* Get default configurations for the type of feature selected. */ + rslt = bmi270_context_get_sensor_config(&config, 1, bmi2_dev); + bmi2_error_codes_print_result(rslt); + + if (rslt == BMI2_OK) + { + /* NOTE: The user can change the following configuration parameters according to their requirement. */ + /* Set Output Data Rate */ + config.cfg.acc.odr = BMI2_ACC_ODR_200HZ; + + /* Gravity range of the sensor (+/- 2G, 4G, 8G, 16G). */ + config.cfg.acc.range = BMI2_ACC_RANGE_2G; + + /* The bandwidth parameter is used to configure the number of sensor samples that are averaged + * if it is set to 2, then 2^(bandwidth parameter) samples + * are averaged, resulting in 4 averaged samples. + * Note1 : For more information, refer the datasheet. + * Note2 : A higher number of averaged samples will result in a lower noise level of the signal, but + * this has an adverse effect on the power consumed. + */ + config.cfg.acc.bwp = BMI2_ACC_NORMAL_AVG4; + + /* Enable the filter performance mode where averaging of samples + * will be done based on above set bandwidth and ODR. + * There are two modes + * 0 -> Ultra low power mode + * 1 -> High performance mode(Default) + * For more info refer datasheet. + */ + config.cfg.acc.filter_perf = BMI2_PERF_OPT_MODE; + + /* Set the accel configurations. */ + rslt = bmi270_context_set_sensor_config(&config, 1, bmi2_dev); + bmi2_error_codes_print_result(rslt); + + /* Map data ready interrupt to interrupt pin. */ + rslt = bmi2_map_data_int(BMI2_DRDY_INT, BMI2_INT1, bmi2_dev); + bmi2_error_codes_print_result(rslt); + } + + return rslt; +} + +/*! + * @brief This function converts lsb to meter per second squared for 16 bit accelerometer at + * range 2G, 4G, 8G or 16G. + */ +static float lsb_to_mps2(int16_t val, float g_range, uint8_t bit_width) +{ + float half_scale = ((float)(1 << bit_width) / 2.0f); + + return (GRAVITY_EARTH * val * g_range) / half_scale; +} diff --git a/examples/bmi270_context/accel_gyro/Makefile b/examples/bmi270_context/accel_gyro/Makefile new file mode 100644 index 0000000..2eed195 --- /dev/null +++ b/examples/bmi270_context/accel_gyro/Makefile @@ -0,0 +1,18 @@ +COINES_INSTALL_PATH ?= ../../../.. + +EXAMPLE_FILE ?= accel_gyro.c + +API_LOCATION ?= ../.. + +COMMON_LOCATION ?= .. + +C_SRCS += \ +$(API_LOCATION)/bmi2.c \ +$(API_LOCATION)/bmi270_context.c \ +$(COMMON_LOCATION)/common/common.c + +INCLUDEPATHS += \ +$(API_LOCATION) \ +$(COMMON_LOCATION)/common + +include $(COINES_INSTALL_PATH)/coines.mk \ No newline at end of file diff --git a/examples/bmi270_context/accel_gyro/accel_gyro.c b/examples/bmi270_context/accel_gyro/accel_gyro.c new file mode 100644 index 0000000..7458969 --- /dev/null +++ b/examples/bmi270_context/accel_gyro/accel_gyro.c @@ -0,0 +1,268 @@ +/**\ + * Copyright (c) 2020 Bosch Sensortec GmbH. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + **/ + +/******************************************************************************/ +/*! Header Files */ +#include +#include "bmi270_context.h" +#include "common.h" + +/******************************************************************************/ +/*! Macro definition */ + +/*! Earth's gravity in m/s^2 */ +#define GRAVITY_EARTH (9.80665f) + +/*! Macros to select the sensors */ +#define ACCEL UINT8_C(0x00) +#define GYRO UINT8_C(0x01) + +/******************************************************************************/ +/*! Static Function Declaration */ + +/*! + * @brief This internal API is used to set configurations for accel. + * + * @param[in] dev : Structure instance of bmi2_dev. + * + * @return Status of execution. + */ +static int8_t set_accel_gyro_config(struct bmi2_dev *bmi2_dev); + +/*! + * @brief This function converts lsb to meter per second squared for 16 bit accelerometer at + * range 2G, 4G, 8G or 16G. + * + * @param[in] val : LSB from each axis. + * @param[in] g_range : Gravity range. + * @param[in] bit_width : Resolution for accel. + * + * @return Gravity. + */ +static float lsb_to_mps2(int16_t val, float g_range, uint8_t bit_width); + +/*! + * @brief This function converts lsb to degree per second for 16 bit gyro at + * range 125, 250, 500, 1000 or 2000dps. + * + * @param[in] val : LSB from each axis. + * @param[in] dps : Degree per second. + * @param[in] bit_width : Resolution for gyro. + * + * @return Degree per second. + */ +static float lsb_to_dps(int16_t val, float dps, uint8_t bit_width); + +/******************************************************************************/ +/*! Functions */ + +/* This function starts the execution of program. */ +int main(void) +{ + /* Status of api are returned to this variable. */ + int8_t rslt; + + /* Variable to define limit to print accel data. */ + uint8_t limit = 10; + + /* Assign accel and gyro sensor to variable. */ + uint8_t sensor_list[2] = { BMI2_ACCEL, BMI2_GYRO }; + + /* Sensor initialization configuration. */ + struct bmi2_dev bmi2_dev; + + /* Create an instance of sensor data structure. */ + struct bmi2_sensor_data sensor_data[2] = { { 0 } }; + + /* Initialize the interrupt status of accel and gyro. */ + uint16_t int_status = 0; + + uint8_t indx = 1; + + float x = 0, y = 0, z = 0; + + /* Interface reference is given as a parameter + * For I2C : BMI2_I2C_INTF + * For SPI : BMI2_SPI_INTF + */ + rslt = bmi2_interface_init(&bmi2_dev, BMI2_I2C_INTF); + bmi2_error_codes_print_result(rslt); + + /* Initialize bmi270_context. */ + rslt = bmi270_context_init(&bmi2_dev); + bmi2_error_codes_print_result(rslt); + + if (rslt == BMI2_OK) + { + /* Enable the accel and gyro sensor. */ + rslt = bmi270_context_sensor_enable(sensor_list, 2, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + if (rslt == BMI2_OK) + { + /* Accel and gyro configuration settings. */ + rslt = set_accel_gyro_config(&bmi2_dev); + bmi2_error_codes_print_result(rslt); + + /* Assign accel and gyro sensor. */ + sensor_data[ACCEL].type = BMI2_ACCEL; + sensor_data[GYRO].type = BMI2_GYRO; + + /* Loop to print accel and gyro data when interrupt occurs. */ + while (indx <= limit) + { + /* To get the data ready interrupt status of accel and gyro. */ + rslt = bmi2_get_int_status(&int_status, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + /* To check the data ready interrupt status and print the status for 10 samples. */ + if ((int_status & BMI2_ACC_DRDY_INT_MASK) && (int_status & BMI2_GYR_DRDY_INT_MASK)) + { + /* Get accel and gyro data for x, y and z axis. */ + rslt = bmi270_context_get_sensor_data(sensor_data, 2, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + printf("\n******* Accel(Raw and m/s2) Gyro(Raw and dps) data : %d *******\n", indx); + + printf("\nAcc_x = %d\t", sensor_data[ACCEL].sens_data.acc.x); + printf("Acc_y = %d\t", sensor_data[ACCEL].sens_data.acc.y); + printf("Acc_z = %d", sensor_data[ACCEL].sens_data.acc.z); + + /* Converting lsb to meter per second squared for 16 bit accelerometer at 2G range. */ + x = lsb_to_mps2(sensor_data[ACCEL].sens_data.acc.x, 2, bmi2_dev.resolution); + y = lsb_to_mps2(sensor_data[ACCEL].sens_data.acc.y, 2, bmi2_dev.resolution); + z = lsb_to_mps2(sensor_data[ACCEL].sens_data.acc.z, 2, bmi2_dev.resolution); + + /* Print the data in m/s2. */ + printf("\nAcc_ms2_X = %4.2f, Acc_ms2_Y = %4.2f, Acc_ms2_Z = %4.2f\n", x, y, z); + + printf("\nGyr_X = %d\t", sensor_data[GYRO].sens_data.gyr.x); + printf("Gyr_Y = %d\t", sensor_data[GYRO].sens_data.gyr.y); + printf("Gyr_Z = %d\n", sensor_data[GYRO].sens_data.gyr.z); + + /* Converting lsb to degree per second for 16 bit gyro at 2000dps range. */ + x = lsb_to_dps(sensor_data[GYRO].sens_data.gyr.x, 2000, bmi2_dev.resolution); + y = lsb_to_dps(sensor_data[GYRO].sens_data.gyr.y, 2000, bmi2_dev.resolution); + z = lsb_to_dps(sensor_data[GYRO].sens_data.gyr.z, 2000, bmi2_dev.resolution); + + /* Print the data in dps. */ + printf("Gyro_DPS_X = %4.2f, Gyro_DPS_Y = %4.2f, Gyro_DPS_Z = %4.2f\n", x, y, z); + + indx++; + } + } + } + } + + bmi2_coines_deinit(); + + return rslt; +} + +/*! + * @brief This internal API is used to set configurations for accel and gyro. + */ +static int8_t set_accel_gyro_config(struct bmi2_dev *bmi2_dev) +{ + /* Status of api are returned to this variable. */ + int8_t rslt; + + /* Structure to define accelerometer and gyro configuration. */ + struct bmi2_sens_config config[2]; + + /* Configure the type of feature. */ + config[ACCEL].type = BMI2_ACCEL; + config[GYRO].type = BMI2_GYRO; + + /* Get default configurations for the type of feature selected. */ + rslt = bmi270_context_get_sensor_config(config, 2, bmi2_dev); + bmi2_error_codes_print_result(rslt); + + /* Map data ready interrupt to interrupt pin. */ + rslt = bmi2_map_data_int(BMI2_DRDY_INT, BMI2_INT1, bmi2_dev); + bmi2_error_codes_print_result(rslt); + + if (rslt == BMI2_OK) + { + /* NOTE: The user can change the following configuration parameters according to their requirement. */ + /* Set Output Data Rate */ + config[ACCEL].cfg.acc.odr = BMI2_ACC_ODR_200HZ; + + /* Gravity range of the sensor (+/- 2G, 4G, 8G, 16G). */ + config[ACCEL].cfg.acc.range = BMI2_ACC_RANGE_2G; + + /* The bandwidth parameter is used to configure the number of sensor samples that are averaged + * if it is set to 2, then 2^(bandwidth parameter) samples + * are averaged, resulting in 4 averaged samples. + * Note1 : For more information, refer the datasheet. + * Note2 : A higher number of averaged samples will result in a lower noise level of the signal, but + * this has an adverse effect on the power consumed. + */ + config[ACCEL].cfg.acc.bwp = BMI2_ACC_NORMAL_AVG4; + + /* Enable the filter performance mode where averaging of samples + * will be done based on above set bandwidth and ODR. + * There are two modes + * 0 -> Ultra low power mode + * 1 -> High performance mode(Default) + * For more info refer datasheet. + */ + config[ACCEL].cfg.acc.filter_perf = BMI2_PERF_OPT_MODE; + + /* The user can change the following configuration parameters according to their requirement. */ + /* Set Output Data Rate */ + config[GYRO].cfg.gyr.odr = BMI2_GYR_ODR_200HZ; + + /* Gyroscope Angular Rate Measurement Range.By default the range is 2000dps. */ + config[GYRO].cfg.gyr.range = BMI2_GYR_RANGE_2000; + + /* Gyroscope bandwidth parameters. By default the gyro bandwidth is in normal mode. */ + config[GYRO].cfg.gyr.bwp = BMI2_GYR_NORMAL_MODE; + + /* Enable/Disable the noise performance mode for precision yaw rate sensing + * There are two modes + * 0 -> Ultra low power mode(Default) + * 1 -> High performance mode + */ + config[GYRO].cfg.gyr.noise_perf = BMI2_POWER_OPT_MODE; + + /* Enable/Disable the filter performance mode where averaging of samples + * will be done based on above set bandwidth and ODR. + * There are two modes + * 0 -> Ultra low power mode + * 1 -> High performance mode(Default) + */ + config[GYRO].cfg.gyr.filter_perf = BMI2_PERF_OPT_MODE; + + /* Set the accel and gyro configurations. */ + rslt = bmi270_context_set_sensor_config(config, 2, bmi2_dev); + bmi2_error_codes_print_result(rslt); + } + + return rslt; +} + +/*! + * @brief This function converts lsb to meter per second squared for 16 bit accelerometer at + * range 2G, 4G, 8G or 16G. + */ +static float lsb_to_mps2(int16_t val, float g_range, uint8_t bit_width) +{ + float half_scale = ((float)(1 << bit_width) / 2.0f); + + return (GRAVITY_EARTH * val * g_range) / half_scale; +} + +/*! + * @brief This function converts lsb to degree per second for 16 bit gyro at + * range 125, 250, 500, 1000 or 2000dps. + */ +static float lsb_to_dps(int16_t val, float dps, uint8_t bit_width) +{ + float half_scale = ((float)(1 << bit_width) / 2.0f); + + return (dps / ((half_scale) + BMI2_GYR_RANGE_2000)) * (val); +} diff --git a/examples/bmi270_context/activity_recognition/Makefile b/examples/bmi270_context/activity_recognition/Makefile new file mode 100644 index 0000000..28ed939 --- /dev/null +++ b/examples/bmi270_context/activity_recognition/Makefile @@ -0,0 +1,18 @@ +COINES_INSTALL_PATH ?= ../../../.. + +EXAMPLE_FILE ?= activity_recognition.c + +API_LOCATION ?= ../.. + +COMMON_LOCATION ?= .. + +C_SRCS += \ +$(API_LOCATION)/bmi2.c \ +$(API_LOCATION)/bmi270_context.c \ +$(COMMON_LOCATION)/common/common.c + +INCLUDEPATHS += \ +$(API_LOCATION) \ +$(COMMON_LOCATION)/common + +include $(COINES_INSTALL_PATH)/coines.mk \ No newline at end of file diff --git a/examples/bmi270_context/activity_recognition/activity_recognition.c b/examples/bmi270_context/activity_recognition/activity_recognition.c new file mode 100644 index 0000000..9f0714d --- /dev/null +++ b/examples/bmi270_context/activity_recognition/activity_recognition.c @@ -0,0 +1,154 @@ +/**\ + * Copyright (c) 2020 Bosch Sensortec GmbH. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + **/ + +/******************************************************************************/ +/*! Header Files */ +#include +#include "bmi270_context.h" +#include "common.h" + +/******************************************************************************/ +/*! Static function declaration */ + +/*! + * @brief This internal API is used to set configurations for step counter. + * + * @param[in] bmi2_dev : Structure instance of bmi2_dev. + * + * @return Status of execution. + */ +static int8_t set_config(struct bmi2_dev *bmi2_dev); + +/******************************************************************************/ +/*! Functions */ +/* This function starts the execution of program. */ +int main(void) +{ + /* Sensor initialization configuration. */ + struct bmi2_dev bmi2_dev; + + /* Status of api are returned to this variable. */ + int8_t rslt; + + /* Variable to define index for FIFO data */ + uint8_t count; + + /* Various Activity recognitions are listed in array. */ + const char *activity_reg_output[6] = { "OTHERS", "STILL", "WALKING", "RUNNING", "ON_BICYCLE", "IN_VEHICLE" }; + + /* Accel sensor and step activity feature are listed in array. */ + uint8_t sensor_sel[2] = { BMI2_ACCEL, BMI2_ACTIVITY_RECOGNITION }; + + /* Array to define FIFO data */ + uint8_t fifo_data[516] = { 0 }; + + /* Variable to store number of activity frames */ + uint16_t act_frames; + + /* Structure to define a FIFO */ + struct bmi2_fifo_frame fifoframe = { 0 }; + + /* Structure to define output for activity recognition */ + struct bmi2_act_recog_output act_recog_data[5] = { { 0 } }; + + uint16_t fifo_length; + + /* Interface reference is given as a parameter + * For I2C : BMI2_I2C_INTF + * For SPI : BMI2_SPI_INTF + */ + rslt = bmi2_interface_init(&bmi2_dev, BMI2_I2C_INTF); + bmi2_error_codes_print_result(rslt); + + /* Initialize bmi270_context. */ + rslt = bmi270_context_init(&bmi2_dev); + bmi2_error_codes_print_result(rslt); + + if (rslt == BMI2_OK) + { + /* Enable the selected sensor. */ + rslt = bmi270_context_sensor_enable(sensor_sel, 2, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + if (rslt == BMI2_OK) + { + rslt = set_config(&bmi2_dev); + bmi2_error_codes_print_result(rslt); + + if (rslt == BMI2_OK) + { + /* Update FIFO structure */ + fifoframe.data = fifo_data; + fifoframe.length = 516; + + rslt = bmi2_get_fifo_length(&fifo_length, &bmi2_dev); + printf("Fifo length = %d \n", fifo_length); + + /* Read FIFO data */ + rslt = bmi2_read_fifo_data(&fifoframe, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + while (rslt != BMI2_W_FIFO_EMPTY) + { + /* Provide the number of frames to be read */ + act_frames = 5; + + printf("Requested FIFO data frames : %d\n", act_frames); + + /* Get the activity output */ + rslt = bmi270_context_get_act_recog_output(act_recog_data, &act_frames, &fifoframe, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + printf("Parsed FIFO data frames : %d\r\n", act_frames); + + for (count = 0; count < act_frames; count++) + { + printf( + "Activity Recognition output[%d]:Sensor time: %lu\t Previous activity: %s\t current: %s\n", + count, + act_recog_data[count].time_stamp, + activity_reg_output[act_recog_data[count].prev_act], + activity_reg_output[act_recog_data[count].curr_act]); + } + } + } + } + } + + bmi2_coines_deinit(); + + return rslt; +} + +static int8_t set_config(struct bmi2_dev *bmi2_dev) +{ + /* Status of api are returned to this variable. */ + int8_t rslt; + + uint8_t temp_data[2]; + + /* Disable advanced power save */ + rslt = bmi2_set_adv_power_save(BMI2_DISABLE, bmi2_dev); + bmi2_error_codes_print_result(rslt); + + if (rslt == BMI2_OK) + { + /* Reset FIFO */ + rslt = bmi2_set_command_register(BMI2_FIFO_FLUSH_CMD, bmi2_dev); + bmi2_error_codes_print_result(rslt); + + printf("Move the board for activity recognition for 30 sec :\n"); + bmi2_dev->delay_us(30000000, bmi2_dev->intf_ptr); + + if (rslt == BMI2_OK) + { + rslt = bmi2_get_regs(BMI2_FIFO_CONFIG_0_ADDR, temp_data, 2, bmi2_dev); + bmi2_error_codes_print_result(rslt); + } + } + + return rslt; +} diff --git a/examples/bmi270_context/common/common.c b/examples/bmi270_context/common/common.c new file mode 100644 index 0000000..afff37b --- /dev/null +++ b/examples/bmi270_context/common/common.c @@ -0,0 +1,372 @@ +/** + * Copyright (C) 2020 Bosch Sensortec GmbH. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include + +#include "coines.h" +#include "bmi2_defs.h" + +/******************************************************************************/ +/*! Macro definitions */ +#define BMI2XY_SHUTTLE_ID UINT16_C(0x1B8) + +/*! Macro that defines read write length */ +#define READ_WRITE_LEN UINT8_C(46) + +/******************************************************************************/ +/*! Static variable definition */ + +/*! Variable that holds the I2C device address or SPI chip selection */ +static uint8_t dev_addr; + +/******************************************************************************/ +/*! User interface functions */ + +/*! + * I2C read function map to COINES platform + */ +BMI2_INTF_RETURN_TYPE bmi2_i2c_read(uint8_t reg_addr, uint8_t *reg_data, uint32_t len, void *intf_ptr) +{ + uint8_t dev_addr = *(uint8_t*)intf_ptr; + + return coines_read_i2c(dev_addr, reg_addr, reg_data, (uint16_t)len); +} + +/*! + * I2C write function map to COINES platform + */ +BMI2_INTF_RETURN_TYPE bmi2_i2c_write(uint8_t reg_addr, const uint8_t *reg_data, uint32_t len, void *intf_ptr) +{ + uint8_t dev_addr = *(uint8_t*)intf_ptr; + + return coines_write_i2c(dev_addr, reg_addr, (uint8_t *)reg_data, (uint16_t)len); +} + +/*! + * SPI read function map to COINES platform + */ +BMI2_INTF_RETURN_TYPE bmi2_spi_read(uint8_t reg_addr, uint8_t *reg_data, uint32_t len, void *intf_ptr) +{ + uint8_t dev_addr = *(uint8_t*)intf_ptr; + + return coines_read_spi(dev_addr, reg_addr, reg_data, (uint16_t)len); +} + +/*! + * SPI write function map to COINES platform + */ +BMI2_INTF_RETURN_TYPE bmi2_spi_write(uint8_t reg_addr, const uint8_t *reg_data, uint32_t len, void *intf_ptr) +{ + uint8_t dev_addr = *(uint8_t*)intf_ptr; + + return coines_write_spi(dev_addr, reg_addr, (uint8_t *)reg_data, (uint16_t)len); +} + +/*! + * Delay function map to COINES platform + */ +void bmi2_delay_us(uint32_t period, void *intf_ptr) +{ + coines_delay_usec(period); +} + +/*! + * @brief Function to select the interface between SPI and I2C. + * Also to initialize coines platform + */ +int8_t bmi2_interface_init(struct bmi2_dev *bmi, uint8_t intf) +{ + int8_t rslt = BMI2_OK; + struct coines_board_info board_info; + + if (bmi != NULL) + { + int16_t result = coines_open_comm_intf(COINES_COMM_INTF_USB); + if (result < COINES_SUCCESS) + { + printf( + "\n Unable to connect with Application Board ! \n" " 1. Check if the board is connected and powered on. \n" " 2. Check if Application Board USB driver is installed. \n" + " 3. Check if board is in use by another application. (Insufficient permissions to access USB) \n"); + exit(result); + } + + result = coines_get_board_info(&board_info); + +#if defined(PC) + setbuf(stdout, NULL); +#endif + + if (result == COINES_SUCCESS) + { + if ((board_info.shuttle_id != BMI2XY_SHUTTLE_ID)) + { + printf("! Warning invalid sensor shuttle \n ," "This application will not support this sensor \n"); + exit(COINES_E_FAILURE); + } + } + + coines_set_shuttleboard_vdd_vddio_config(0, 0); + coines_delay_msec(100); + + /* Bus configuration : I2C */ + if (intf == BMI2_I2C_INTF) + { + printf("I2C Interface \n"); + + /* To initialize the user I2C function */ + dev_addr = BMI2_I2C_PRIM_ADDR; + bmi->intf = BMI2_I2C_INTF; + bmi->read = bmi2_i2c_read; + bmi->write = bmi2_i2c_write; + coines_config_i2c_bus(COINES_I2C_BUS_0, COINES_I2C_FAST_MODE); + } + /* Bus configuration : SPI */ + else if (intf == BMI2_SPI_INTF) + { + printf("SPI Interface \n"); + + /* To initialize the user SPI function */ + dev_addr = COINES_SHUTTLE_PIN_7; + bmi->intf = BMI2_SPI_INTF; + bmi->read = bmi2_spi_read; + bmi->write = bmi2_spi_write; + coines_config_spi_bus(COINES_SPI_BUS_0, COINES_SPI_SPEED_5_MHZ, COINES_SPI_MODE3); + coines_set_pin_config(COINES_SHUTTLE_PIN_7, COINES_PIN_DIRECTION_OUT, COINES_PIN_VALUE_HIGH); + } + + /* Assign device address to interface pointer */ + bmi->intf_ptr = &dev_addr; + + /* Configure delay in microseconds */ + bmi->delay_us = bmi2_delay_us; + + /* Configure max read/write length (in bytes) ( Supported length depends on target machine) */ + bmi->read_write_len = READ_WRITE_LEN; + + /* Assign to NULL to load the default config file. */ + bmi->config_file_ptr = NULL; + + coines_delay_usec(10000); + + coines_set_shuttleboard_vdd_vddio_config(3300, 3300); + + coines_delay_usec(10000); + } + else + { + rslt = BMI2_E_NULL_PTR; + } + + return rslt; + +} + +/*! + * @brief Prints the execution status of the APIs. + */ +void bmi2_error_codes_print_result(int8_t rslt) +{ + switch (rslt) + { + case BMI2_OK: + + /* Do nothing */ + break; + + case BMI2_W_FIFO_EMPTY: + printf("Warning [%d] : FIFO empty\r\n", rslt); + break; + case BMI2_W_PARTIAL_READ: + printf("Warning [%d] : FIFO partial read\r\n", rslt); + break; + case BMI2_E_NULL_PTR: + printf( + "Error [%d] : Null pointer error. It occurs when the user tries to assign value (not address) to a pointer," " which has been initialized to NULL.\r\n", + rslt); + break; + + case BMI2_E_COM_FAIL: + printf( + "Error [%d] : Communication failure error. It occurs due to read/write operation failure and also due " "to power failure during communication\r\n", + rslt); + break; + + case BMI2_E_DEV_NOT_FOUND: + printf("Error [%d] : Device not found error. It occurs when the device chip id is incorrectly read\r\n", + rslt); + break; + + case BMI2_E_INVALID_SENSOR: + printf( + "Error [%d] : Invalid sensor error. It occurs when there is a mismatch in the requested feature with the " "available one\r\n", + rslt); + break; + + case BMI2_E_SELF_TEST_FAIL: + printf( + "Error [%d] : Self-test failed error. It occurs when the validation of accel self-test data is " "not satisfied\r\n", + rslt); + break; + + case BMI2_E_INVALID_INT_PIN: + printf( + "Error [%d] : Invalid interrupt pin error. It occurs when the user tries to configure interrupt pins " "apart from INT1 and INT2\r\n", + rslt); + break; + + case BMI2_E_OUT_OF_RANGE: + printf( + "Error [%d] : Out of range error. It occurs when the data exceeds from filtered or unfiltered data from " "fifo and also when the range exceeds the maximum range for accel and gyro while performing FOC\r\n", + rslt); + break; + + case BMI2_E_ACC_INVALID_CFG: + printf( + "Error [%d] : Invalid Accel configuration error. It occurs when there is an error in accel configuration" " register which could be one among range, BW or filter performance in reg address 0x40\r\n", + rslt); + break; + + case BMI2_E_GYRO_INVALID_CFG: + printf( + "Error [%d] : Invalid Gyro configuration error. It occurs when there is a error in gyro configuration" "register which could be one among range, BW or filter performance in reg address 0x42\r\n", + rslt); + break; + + case BMI2_E_ACC_GYR_INVALID_CFG: + printf( + "Error [%d] : Invalid Accel-Gyro configuration error. It occurs when there is a error in accel and gyro" " configuration registers which could be one among range, BW or filter performance in reg address 0x40 " "and 0x42\r\n", + rslt); + break; + + case BMI2_E_CONFIG_LOAD: + printf( + "Error [%d] : Configuration load error. It occurs when failure observed while loading the configuration " "into the sensor\r\n", + rslt); + break; + + case BMI2_E_INVALID_PAGE: + printf( + "Error [%d] : Invalid page error. It occurs due to failure in writing the correct feature configuration " "from selected page\r\n", + rslt); + break; + + case BMI2_E_SET_APS_FAIL: + printf( + "Error [%d] : APS failure error. It occurs due to failure in write of advance power mode configuration " "register\r\n", + rslt); + break; + + case BMI2_E_AUX_INVALID_CFG: + printf( + "Error [%d] : Invalid AUX configuration error. It occurs when the auxiliary interface settings are not " "enabled properly\r\n", + rslt); + break; + + case BMI2_E_AUX_BUSY: + printf( + "Error [%d] : AUX busy error. It occurs when the auxiliary interface buses are engaged while configuring" " the AUX\r\n", + rslt); + break; + + case BMI2_E_REMAP_ERROR: + printf( + "Error [%d] : Remap error. It occurs due to failure in assigning the remap axes data for all the axes " "after change in axis position\r\n", + rslt); + break; + + case BMI2_E_GYR_USER_GAIN_UPD_FAIL: + printf( + "Error [%d] : Gyro user gain update fail error. It occurs when the reading of user gain update status " "fails\r\n", + rslt); + break; + + case BMI2_E_SELF_TEST_NOT_DONE: + printf( + "Error [%d] : Self-test not done error. It occurs when the self-test process is ongoing or not " "completed\r\n", + rslt); + break; + + case BMI2_E_INVALID_INPUT: + printf("Error [%d] : Invalid input error. It occurs when the sensor input validity fails\r\n", rslt); + break; + + case BMI2_E_INVALID_STATUS: + printf("Error [%d] : Invalid status error. It occurs when the feature/sensor validity fails\r\n", rslt); + break; + + case BMI2_E_CRT_ERROR: + printf("Error [%d] : CRT error. It occurs when the CRT test has failed\r\n", rslt); + break; + + case BMI2_E_ST_ALREADY_RUNNING: + printf( + "Error [%d] : Self-test already running error. It occurs when the self-test is already running and " "another has been initiated\r\n", + rslt); + break; + + case BMI2_E_CRT_READY_FOR_DL_FAIL_ABORT: + printf( + "Error [%d] : CRT ready for download fail abort error. It occurs when download in CRT fails due to wrong " "address location\r\n", + rslt); + break; + + case BMI2_E_DL_ERROR: + printf( + "Error [%d] : Download error. It occurs when write length exceeds that of the maximum burst length\r\n", + rslt); + break; + + case BMI2_E_PRECON_ERROR: + printf( + "Error [%d] : Pre-conditional error. It occurs when precondition to start the feature was not " "completed\r\n", + rslt); + break; + + case BMI2_E_ABORT_ERROR: + printf("Error [%d] : Abort error. It occurs when the device was shaken during CRT test\r\n", rslt); + break; + + case BMI2_E_WRITE_CYCLE_ONGOING: + printf( + "Error [%d] : Write cycle ongoing error. It occurs when the write cycle is already running and another " "has been initiated\r\n", + rslt); + break; + + case BMI2_E_ST_NOT_RUNING: + printf( + "Error [%d] : Self-test is not running error. It occurs when self-test running is disabled while it's " "running\r\n", + rslt); + break; + + case BMI2_E_DATA_RDY_INT_FAILED: + printf( + "Error [%d] : Data ready interrupt error. It occurs when the sample count exceeds the FOC sample limit " "and data ready status is not updated\r\n", + rslt); + break; + + case BMI2_E_INVALID_FOC_POSITION: + printf( + "Error [%d] : Invalid FOC position error. It occurs when average FOC data is obtained for the wrong" " axes\r\n", + rslt); + break; + + default: + printf("Error [%d] : Unknown error code\r\n", rslt); + break; + } +} + +/*! + * @brief Deinitializes coines platform + * + * @return void. + */ +void bmi2_coines_deinit(void) +{ + coines_close_comm_intf(COINES_COMM_INTF_USB); +} diff --git a/examples/bmi270_context/common/common.h b/examples/bmi270_context/common/common.h new file mode 100644 index 0000000..763983d --- /dev/null +++ b/examples/bmi270_context/common/common.h @@ -0,0 +1,122 @@ +/**\ + * Copyright (c) 2020 Bosch Sensortec GmbH. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + **/ + +#ifndef _COMMON_H +#define _COMMON_H + +/*! CPP guard */ +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include "bmi2.h" + +/*! + * @brief Function for reading the sensor's registers through I2C bus. + * + * @param[in] reg_addr : Register address. + * @param[out] reg_data : Pointer to the data buffer to store the read data. + * @param[in] length : No of bytes to read. + * @param[in] intf_ptr : Interface pointer + * + * @return Status of execution + * @retval = BMI2_INTF_RET_SUCCESS -> Success + * @retval != BMI2_INTF_RET_SUCCESS -> Failure Info + * + */ +BMI2_INTF_RETURN_TYPE bmi2_i2c_read(uint8_t reg_addr, uint8_t *reg_data, uint32_t len, void *intf_ptr); + +/*! + * @brief Function for writing the sensor's registers through I2C bus. + * + * @param[in] reg_addr : Register address. + * @param[in] reg_data : Pointer to the data buffer whose value is to be written. + * @param[in] length : No of bytes to write. + * @param[in] intf_ptr : Interface pointer + * + * @return Status of execution + * @retval = BMI2_INTF_RET_SUCCESS -> Success + * @retval != BMI2_INTF_RET_SUCCESS -> Failure Info + * + */ +BMI2_INTF_RETURN_TYPE bmi2_i2c_write(uint8_t reg_addr, const uint8_t *reg_data, uint32_t len, void *intf_ptr); + +/*! + * @brief Function for reading the sensor's registers through SPI bus. + * + * @param[in] reg_addr : Register address. + * @param[out] reg_data : Pointer to the data buffer to store the read data. + * @param[in] length : No of bytes to read. + * @param[in] intf_ptr : Interface pointer + * + * @return Status of execution + * @retval = BMI2_INTF_RET_SUCCESS -> Success + * @retval != BMI2_INTF_RET_SUCCESS -> Failure Info + * + */ +BMI2_INTF_RETURN_TYPE bmi2_spi_read(uint8_t reg_addr, uint8_t *reg_data, uint32_t len, void *intf_ptr); + +/*! + * @brief Function for writing the sensor's registers through SPI bus. + * + * @param[in] reg_addr : Register address. + * @param[in] reg_data : Pointer to the data buffer whose data has to be written. + * @param[in] length : No of bytes to write. + * @param[in] intf_ptr : Interface pointer + * + * @return Status of execution + * @retval = BMI2_INTF_RET_SUCCESS -> Success + * @retval != BMI2_INTF_RET_SUCCESS -> Failure Info + * + */ +BMI2_INTF_RETURN_TYPE bmi2_spi_write(uint8_t reg_addr, const uint8_t *reg_data, uint32_t len, void *intf_ptr); + +/*! + * @brief This function provides the delay for required time (Microsecond) as per the input provided in some of the + * APIs. + * + * @param[in] period_us : The required wait time in microsecond. + * @param[in] intf_ptr : Interface pointer + * + * @return void. + * + */ +void bmi2_delay_us(uint32_t period, void *intf_ptr); + +/*! + * @brief Function to select the interface between SPI and I2C. + * + * @param[in] bma : Structure instance of bmi2_dev + * @param[in] intf : Interface selection parameter + * + * @return Status of execution + * @retval 0 -> Success + * @retval < 0 -> Failure Info + */ +int8_t bmi2_interface_init(struct bmi2_dev *bma, uint8_t intf); + +/*! + * @brief Prints the execution status of the APIs. + * + * @param[in] rslt : Error code returned by the API whose execution status has to be printed. + * + * @return void. + */ +void bmi2_error_codes_print_result(int8_t rslt); + +/*! + * @brief Deinitializes coines platform + * + * @return void. + */ +void bmi2_coines_deinit(void); + +#ifdef __cplusplus +} +#endif /* End of CPP guard */ + +#endif /* _COMMON_H */ diff --git a/examples/bmi270_context/component_retrim/Makefile b/examples/bmi270_context/component_retrim/Makefile new file mode 100644 index 0000000..61db2e1 --- /dev/null +++ b/examples/bmi270_context/component_retrim/Makefile @@ -0,0 +1,18 @@ +COINES_INSTALL_PATH ?= ../../../.. + +EXAMPLE_FILE ?= component_retrim.c + +API_LOCATION ?= ../.. + +COMMON_LOCATION ?= .. + +C_SRCS += \ +$(API_LOCATION)/bmi2.c \ +$(API_LOCATION)/bmi270_context.c \ +$(COMMON_LOCATION)/common/common.c + +INCLUDEPATHS += \ +$(API_LOCATION) \ +$(COMMON_LOCATION)/common + +include $(COINES_INSTALL_PATH)/coines.mk \ No newline at end of file diff --git a/examples/bmi270_context/component_retrim/component_retrim.c b/examples/bmi270_context/component_retrim/component_retrim.c new file mode 100644 index 0000000..94ed043 --- /dev/null +++ b/examples/bmi270_context/component_retrim/component_retrim.c @@ -0,0 +1,52 @@ +/**\ + * Copyright (c) 2020 Bosch Sensortec GmbH. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + **/ + +/******************************************************************************/ +/*! Header Files */ +#include +#include "bmi270_context.h" +#include "common.h" + +/******************************************************************************/ +/*! Functions */ + +/* This function starts the execution of program. */ +int main(void) +{ + /* Sensor initialization configuration. */ + struct bmi2_dev bmi2_dev; + + /* Status of api are returned to this variable. */ + int8_t rslt; + + /* Interface reference is given as a parameter + * For I2C : BMI2_I2C_INTF + * For SPI : BMI2_SPI_INTF + */ + rslt = bmi2_interface_init(&bmi2_dev, BMI2_I2C_INTF); + bmi2_error_codes_print_result(rslt); + + /* Initialize bmi270_context. */ + rslt = bmi270_context_init(&bmi2_dev); + bmi2_error_codes_print_result(rslt); + + if (rslt == BMI2_OK) + { + /* This API runs the CRT process. */ + rslt = bmi2_do_crt(&bmi2_dev); + bmi2_error_codes_print_result(rslt); + + /* Do not move the board while doing CRT. If so, it will throw an abort error. */ + if (rslt == BMI2_OK) + { + printf("CRT successfully completed."); + } + } + + bmi2_coines_deinit(); + + return rslt; +} diff --git a/examples/bmi270_context/fifo_full_header_mode/Makefile b/examples/bmi270_context/fifo_full_header_mode/Makefile new file mode 100644 index 0000000..2d328d5 --- /dev/null +++ b/examples/bmi270_context/fifo_full_header_mode/Makefile @@ -0,0 +1,18 @@ +COINES_INSTALL_PATH ?= ../../../.. + +EXAMPLE_FILE ?= fifo_full_header_mode.c + +API_LOCATION ?= ../.. + +COMMON_LOCATION ?= .. + +C_SRCS += \ +$(API_LOCATION)/bmi2.c \ +$(API_LOCATION)/bmi270_context.c \ +$(COMMON_LOCATION)/common/common.c + +INCLUDEPATHS += \ +$(API_LOCATION) \ +$(COMMON_LOCATION)/common + +include $(COINES_INSTALL_PATH)/coines.mk \ No newline at end of file diff --git a/examples/bmi270_context/fifo_full_header_mode/fifo_full_header_mode.c b/examples/bmi270_context/fifo_full_header_mode/fifo_full_header_mode.c new file mode 100644 index 0000000..3a5a810 --- /dev/null +++ b/examples/bmi270_context/fifo_full_header_mode/fifo_full_header_mode.c @@ -0,0 +1,315 @@ +/**\ + * Copyright (c) 2020 Bosch Sensortec GmbH. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + **/ + +/******************************************************************************/ +/*! Header Files */ +#include +#include "bmi270_context.h" +#include "common.h" + +/******************************************************************************/ +/*! Macros */ + +/*! Buffer size allocated to store raw FIFO data. */ +#define BMI2_FIFO_RAW_DATA_BUFFER_SIZE UINT16_C(2048) + +/*! Length of data to be read from FIFO. */ +#define BMI2_FIFO_RAW_DATA_USER_LENGTH UINT16_C(2048) + +/*! Number of accel frames to be extracted from FIFO. */ + +/*! Calculation for frame count: Total frame count = Fifo buffer size(2048)/ Total frames(6 Accel, 6 Gyro and 1 header, + * totaling to 13) which equals to 157. + */ +#define BMI2_FIFO_ACCEL_FRAME_COUNT UINT8_C(157) + +/*! Number of gyro frames to be extracted from FIFO. */ +#define BMI2_FIFO_GYRO_FRAME_COUNT UINT8_C(157) + +/*! Macro to read sensortime byte in FIFO. */ +#define SENSORTIME_OVERHEAD_BYTE UINT8_C(3) + +/******************************************************************************/ +/*! Static Function Declaration */ + +/*! + * @brief This internal API is used to set configurations for accel and gyro. + * @param[in] dev : Structure instance of bmi2_dev. + * @return Status of execution. + */ +static int8_t set_accel_gyro_config(struct bmi2_dev *dev); + +/******************************************************************************/ + +/* This function starts the execution of program. */ +int main(void) +{ + /* Status of api are returned to this variable. */ + int8_t rslt; + + uint16_t index = 0; + uint16_t fifo_length = 0; + uint16_t config = 0; + + /* To read sensortime, extra 3 bytes are added to fifo buffer. */ + uint16_t fifo_buffer_size = BMI2_FIFO_RAW_DATA_BUFFER_SIZE + SENSORTIME_OVERHEAD_BYTE; + + /* Variable to get fifo full interrupt status. */ + uint16_t int_status = 0; + + uint16_t accel_frame_length = BMI2_FIFO_ACCEL_FRAME_COUNT; + + uint16_t gyro_frame_length = BMI2_FIFO_GYRO_FRAME_COUNT; + + /* Variable to store the available frame length count in FIFO */ + uint8_t frame_count; + + int8_t try = 1; + + /* Number of bytes of FIFO data. */ + uint8_t fifo_data[fifo_buffer_size]; + + /* Sensor initialization configuration. */ + struct bmi2_dev bmi2_dev; + + /* Array of accelerometer frames -> Total bytes = + * 157 * (6 axes + 1 header bytes) = 1099 bytes */ + struct bmi2_sens_axes_data fifo_accel_data[BMI2_FIFO_ACCEL_FRAME_COUNT] = { { 0 } }; + + /* Array of gyro frames -> Total bytes = + * 157 * (6 axes + 1 header bytes) = 1099 bytes */ + struct bmi2_sens_axes_data fifo_gyro_data[BMI2_FIFO_GYRO_FRAME_COUNT] = { { 0 } }; + + /* Initialize FIFO frame structure. */ + struct bmi2_fifo_frame fifoframe = { 0 }; + + /* Accel and gyro sensor are listed in array. */ + uint8_t sensor_sel[2] = { BMI2_ACCEL, BMI2_GYRO }; + + /* Interface reference is given as a parameter + * For I2C : BMI2_I2C_INTF + * For SPI : BMI2_SPI_INTF + */ + rslt = bmi2_interface_init(&bmi2_dev, BMI2_I2C_INTF); + bmi2_error_codes_print_result(rslt); + + /* Initialize bmi270_context. */ + rslt = bmi270_context_init(&bmi2_dev); + bmi2_error_codes_print_result(rslt); + + /* Enable accel and gyro sensor. */ + rslt = bmi270_context_sensor_enable(sensor_sel, 2, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + /* Configuration settings for accel and gyro. */ + rslt = set_accel_gyro_config(&bmi2_dev); + bmi2_error_codes_print_result(rslt); + + /* Before setting FIFO, disable the advance power save mode. */ + rslt = bmi2_set_adv_power_save(BMI2_DISABLE, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + /* Initially disable all configurations in fifo. */ + rslt = bmi2_get_fifo_config(&config, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + /* Initially disable all configurations in fifo. */ + rslt = bmi2_set_fifo_config(BMI2_FIFO_ALL_EN, BMI2_DISABLE, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + /* Update FIFO structure. */ + /* Mapping the buffer to store the fifo data. */ + fifoframe.data = fifo_data; + + /* Length of FIFO frame. */ + /* To read sensortime, extra 3 bytes are added to fifo user length. */ + fifoframe.length = BMI2_FIFO_RAW_DATA_USER_LENGTH + SENSORTIME_OVERHEAD_BYTE; + + /* Set FIFO configuration by enabling accel, gyro and timestamp. + * NOTE 1: The header mode is enabled by default. + * NOTE 2: By default the FIFO operating mode is in FIFO mode. + * NOTE 3: Sensortime is enabled by default */ + printf("FIFO is configured in header mode\n"); + rslt = bmi2_set_fifo_config(BMI2_FIFO_ACC_EN | BMI2_FIFO_GYR_EN, BMI2_ENABLE, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + /* Map FIFO full interrupt. */ + fifoframe.data_int_map = BMI2_FFULL_INT; + rslt = bmi2_map_data_int(fifoframe.data_int_map, BMI2_INT1, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + while (try <= 10) + { + /* Read FIFO data on interrupt. */ + rslt = bmi2_get_int_status(&int_status, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + if ((rslt == BMI2_OK) && (int_status & BMI2_FFULL_INT_STATUS_MASK)) + { + printf("\nIteration : %d\n", try); + + accel_frame_length = BMI2_FIFO_ACCEL_FRAME_COUNT; + + gyro_frame_length = BMI2_FIFO_GYRO_FRAME_COUNT; + + rslt = bmi2_get_fifo_length(&fifo_length, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + printf("\nFIFO data bytes available : %d \n", fifo_length); + printf("\nFIFO data bytes requested : %d \n", fifoframe.length); + + /* Read FIFO data. */ + rslt = bmi2_read_fifo_data(&fifoframe, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + /* Read FIFO data on interrupt. */ + rslt = bmi2_get_int_status(&int_status, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + if (rslt == BMI2_OK) + { + printf("\nFIFO accel frames requested : %d \n", accel_frame_length); + + /* Parse the FIFO data to extract accelerometer data from the FIFO buffer. */ + rslt = bmi2_extract_accel(fifo_accel_data, &accel_frame_length, &fifoframe, &bmi2_dev); + printf("\nFIFO accel frames extracted : %d \n", accel_frame_length); + + printf("\nFIFO gyro frames requested : %d \n", gyro_frame_length); + + /* Parse the FIFO data to extract gyro data from the FIFO buffer. */ + rslt = bmi2_extract_gyro(fifo_gyro_data, &gyro_frame_length, &fifoframe, &bmi2_dev); + printf("\nFIFO gyro frames extracted : %d \n", gyro_frame_length); + + /* Calculating the frame count from the available bytes in FIFO + * frame_length = (available_fifo_bytes / (acc_frame_len + gyro_frame_len + header_byte)) */ + frame_count = (fifo_length / (BMI2_FIFO_ACC_GYR_LENGTH + 1)); + printf("\nAvailable frame count from available bytes: %d\n", frame_count); + + printf("\nExtracted accel frames\n"); + + if (accel_frame_length > frame_count) + { + accel_frame_length = frame_count; + } + + /* Print the parsed accelerometer data from the FIFO buffer. */ + for (index = 0; index < accel_frame_length; index++) + { + printf("ACCEL[%d] X : %d\t Y : %d\t Z : %d\n", index, fifo_accel_data[index].x, + fifo_accel_data[index].y, fifo_accel_data[index].z); + } + + printf("\nExtracted gyro frames\n"); + + if (gyro_frame_length > frame_count) + { + gyro_frame_length = frame_count; + } + + /* Print the parsed gyro data from the FIFO buffer. */ + for (index = 0; index < gyro_frame_length; index++) + { + printf("GYRO[%d] X : %d\t Y : %d\t Z : %d\n", + index, + fifo_gyro_data[index].x, + fifo_gyro_data[index].y, + fifo_gyro_data[index].z); + } + + /* Print control frames like sensor time and skipped frame count. */ + printf("\nSkipped frame count = %d\n", fifoframe.skipped_frame_count); + + printf("Sensor time = %lu\r\n", fifoframe.sensor_time); + + try++; + } + } + } + + bmi2_coines_deinit(); + + return rslt; +} + +/*! + * @brief This internal API is used to set configurations for accel and gyro. + */ +static int8_t set_accel_gyro_config(struct bmi2_dev *bmi2_dev) +{ + /* Status of api are returned to this variable. */ + int8_t rslt; + + /* Structure to define accel and gyro configurations. */ + struct bmi2_sens_config config[2]; + + /* Configure the type of feature. */ + config[0].type = BMI2_ACCEL; + config[1].type = BMI2_GYRO; + + /* Get default configurations for the type of feature selected. */ + rslt = bmi270_context_get_sensor_config(config, 2, bmi2_dev); + bmi2_error_codes_print_result(rslt); + + if (rslt == BMI2_OK) + { + /* NOTE: The user can change the following configuration parameters according to their requirement. */ + /* Accel configuration settings. */ + /* Set Output Data Rate */ + config[0].cfg.acc.odr = BMI2_ACC_ODR_25HZ; + + /* Gravity range of the sensor (+/- 2G, 4G, 8G, 16G). */ + config[0].cfg.acc.range = BMI2_ACC_RANGE_2G; + + /* The bandwidth parameter is used to configure the number of sensor samples that are averaged + * if it is set to 2, then 2^(bandwidth parameter) samples + * are averaged, resulting in 4 averaged samples + * Note1 : For more information, refer the datasheet. + * Note2 : A higher number of averaged samples will result in a lower noise level of the signal, but + * this has an adverse effect on the power consumed. + */ + config[0].cfg.acc.bwp = BMI2_ACC_NORMAL_AVG4; + + /* Enable the filter performance mode where averaging of samples + * will be done based on above set bandwidth and ODR. + * There are two modes + * 0 -> Ultra low power mode + * 1 -> High performance mode(Default) + * For more info refer datasheet. + */ + config[0].cfg.acc.filter_perf = BMI2_PERF_OPT_MODE; + + /* Gyro configuration settings. */ + /* Set Output Data Rate */ + config[1].cfg.gyr.odr = BMI2_GYR_ODR_50HZ; + + /* Gyroscope Angular Rate Measurement Range.By default the range is 2000dps. */ + config[1].cfg.gyr.range = BMI2_GYR_RANGE_2000; + + /* Gyroscope Bandwidth parameters. By default the gyro bandwidth is in normal mode. */ + config[1].cfg.gyr.bwp = BMI2_GYR_NORMAL_MODE; + + /* Enable/Disable the noise performance mode for precision yaw rate sensing + * There are two modes + * 0 -> Ultra low power mode(Default) + * 1 -> High performance mode + */ + config[1].cfg.gyr.noise_perf = BMI2_POWER_OPT_MODE; + + /* Enable/Disable the filter performance mode where averaging of samples + * will be done based on above set bandwidth and ODR. + * There are two modes + * 0 -> Ultra low power mode + * 1 -> High performance mode(Default) + */ + config[1].cfg.gyr.filter_perf = BMI2_PERF_OPT_MODE; + + /* Set new configurations. */ + rslt = bmi270_context_set_sensor_config(config, 2, bmi2_dev); + bmi2_error_codes_print_result(rslt); + } + + return rslt; +} diff --git a/examples/bmi270_context/fifo_full_headerless_mode/Makefile b/examples/bmi270_context/fifo_full_headerless_mode/Makefile new file mode 100644 index 0000000..8f1f960 --- /dev/null +++ b/examples/bmi270_context/fifo_full_headerless_mode/Makefile @@ -0,0 +1,18 @@ +COINES_INSTALL_PATH ?= ../../../.. + +EXAMPLE_FILE ?= fifo_full_headerless_mode.c + +API_LOCATION ?= ../.. + +COMMON_LOCATION ?= .. + +C_SRCS += \ +$(API_LOCATION)/bmi2.c \ +$(API_LOCATION)/bmi270_context.c \ +$(COMMON_LOCATION)/common/common.c + +INCLUDEPATHS += \ +$(API_LOCATION) \ +$(COMMON_LOCATION)/common + +include $(COINES_INSTALL_PATH)/coines.mk \ No newline at end of file diff --git a/examples/bmi270_context/fifo_full_headerless_mode/fifo_full_headerless_mode.c b/examples/bmi270_context/fifo_full_headerless_mode/fifo_full_headerless_mode.c new file mode 100644 index 0000000..bfc1145 --- /dev/null +++ b/examples/bmi270_context/fifo_full_headerless_mode/fifo_full_headerless_mode.c @@ -0,0 +1,304 @@ +/**\ + * Copyright (c) 2020 Bosch Sensortec GmbH. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + **/ + +/******************************************************************************/ +/*! Header Files */ +#include +#include "bmi270_context.h" +#include "common.h" + +/******************************************************************************/ +/*! Macros */ + +/*! Buffer size allocated to store raw FIFO data */ +#define BMI2_FIFO_RAW_DATA_BUFFER_SIZE UINT16_C(2048) + +/*! Length of data to be read from FIFO */ +#define BMI2_FIFO_RAW_DATA_USER_LENGTH UINT16_C(2048) + +/*! Number of accel frames to be extracted from FIFO */ + +/*! Calculation for frame count: Total frame count = Fifo buffer size(2048)/ Total frames(6 Accel, 6 Gyro totaling to + * 12) which equals to 170. + */ +#define BMI2_FIFO_ACCEL_FRAME_COUNT UINT8_C(169) + +/*! Number of gyro frames to be extracted from FIFO */ +#define BMI2_FIFO_GYRO_FRAME_COUNT UINT8_C(169) + +/******************************************************************************/ +/*! Static Function Declaration */ + +/*! + * @brief This internal API is used to set configurations for accel and gyro. + * @param[in] dev : Structure instance of bmi2_dev. + * @return Status of execution. + */ +static int8_t set_accel_gyro_config(struct bmi2_dev *dev); + +/******************************************************************************/ + +/* This function starts the execution of program. */ +int main(void) +{ + /* Status of api are returned to this variable. */ + int8_t rslt; + + uint16_t index = 0; + + uint16_t fifo_length = 0; + + uint8_t try = 1; + + /* Variable to get fifo full interrupt status. */ + uint16_t int_status = 0; + + uint16_t accel_frame_length; + + uint16_t gyro_frame_length; + + /* Variable to store the available frame length count in FIFO */ + uint8_t frame_count; + + /* Number of bytes of FIFO data. */ + uint8_t fifo_data[BMI2_FIFO_RAW_DATA_BUFFER_SIZE] = { 0 }; + + /* Sensor initialization configuration. */ + struct bmi2_dev bmi2_dev; + + /* Array of accelerometer frames -> Total bytes = + * 170 * (6 axes bytes) = 1020 bytes */ + struct bmi2_sens_axes_data fifo_accel_data[BMI2_FIFO_ACCEL_FRAME_COUNT] = { { 0 } }; + + /* Array of gyro frames -> Total bytes = + * 170 * (6 axes bytes) = 1020 bytes */ + struct bmi2_sens_axes_data fifo_gyro_data[BMI2_FIFO_GYRO_FRAME_COUNT] = { { 0 } }; + + /* Initialize FIFO frame structure. */ + struct bmi2_fifo_frame fifoframe = { 0 }; + + /* Accel and gyro sensor are listed in array. */ + uint8_t sensor_sel[2] = { BMI2_ACCEL, BMI2_GYRO }; + + /* Interface reference is given as a parameter + * For I2C : BMI2_I2C_INTF + * For SPI : BMI2_SPI_INTF + */ + rslt = bmi2_interface_init(&bmi2_dev, BMI2_I2C_INTF); + bmi2_error_codes_print_result(rslt); + + /* Initialize bmi270_context. */ + rslt = bmi270_context_init(&bmi2_dev); + bmi2_error_codes_print_result(rslt); + + /* Enable accel and gyro sensor. */ + rslt = bmi270_context_sensor_enable(sensor_sel, 2, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + /* Configuration settings for accel and gyro. */ + rslt = set_accel_gyro_config(&bmi2_dev); + bmi2_error_codes_print_result(rslt); + + /* Before setting FIFO, disable the advance power save mode. */ + rslt = bmi2_set_adv_power_save(BMI2_DISABLE, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + /* Initially disable all configurations in fifo. */ + rslt = bmi2_set_fifo_config(BMI2_FIFO_ALL_EN, BMI2_DISABLE, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + /* Update FIFO structure. */ + /* Mapping the buffer to store the fifo data. */ + fifoframe.data = fifo_data; + + /* Length of FIFO frame. */ + fifoframe.length = BMI2_FIFO_RAW_DATA_USER_LENGTH; + + /* Set FIFO configuration by enabling accel, gyro. + * NOTE 1: The header mode is enabled by default. + * NOTE 2: By default the FIFO operating mode is FIFO mode. */ + rslt = bmi2_set_fifo_config(BMI2_FIFO_ACC_EN | BMI2_FIFO_GYR_EN, BMI2_ENABLE, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + printf("FIFO is configured in headerless mode\n"); + + /* To enable headerless mode, disable the header. */ + if (rslt == BMI2_OK) + { + rslt = bmi2_set_fifo_config(BMI2_FIFO_HEADER_EN, BMI2_DISABLE, &bmi2_dev); + } + + /* Map FIFO full interrupt. */ + fifoframe.data_int_map = BMI2_FFULL_INT; + rslt = bmi2_map_data_int(fifoframe.data_int_map, BMI2_INT1, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + while (try <= 10) + { + /* Read FIFO data on interrupt. */ + rslt = bmi2_get_int_status(&int_status, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + if ((rslt == BMI2_OK) && (int_status & BMI2_FFULL_INT_STATUS_MASK)) + { + printf("\nIteration : %d\n", try); + + rslt = bmi2_get_fifo_length(&fifo_length, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + accel_frame_length = BMI2_FIFO_ACCEL_FRAME_COUNT; + gyro_frame_length = BMI2_FIFO_GYRO_FRAME_COUNT; + + printf("\nFIFO data bytes available : %d \n", fifo_length); + printf("\nFIFO data bytes requested : %d \n", fifoframe.length); + + /* Read FIFO data. */ + rslt = bmi2_read_fifo_data(&fifoframe, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + /* Read FIFO data on interrupt. */ + rslt = bmi2_get_int_status(&int_status, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + if (rslt == BMI2_OK) + { + printf("\nFIFO accel frames requested : %d \n", accel_frame_length); + + /* Parse the FIFO data to extract accelerometer data from the FIFO buffer. */ + rslt = bmi2_extract_accel(fifo_accel_data, &accel_frame_length, &fifoframe, &bmi2_dev); + printf("\nFIFO accel frames extracted : %d \n", accel_frame_length); + + printf("\nFIFO gyro frames requested : %d \n", gyro_frame_length); + + /* Parse the FIFO data to extract gyro data from the FIFO buffer. */ + rslt = bmi2_extract_gyro(fifo_gyro_data, &gyro_frame_length, &fifoframe, &bmi2_dev); + printf("\nFIFO gyro frames extracted : %d \n", gyro_frame_length); + + /* Calculating the frame count from the available bytes in FIFO + * frame_length = (available_fifo_bytes / (acc_frame_len + gyro_frame_len)) */ + frame_count = (fifo_length / (BMI2_FIFO_ACC_GYR_LENGTH)); + printf("\nAvailable frame count from available bytes: %d\n", frame_count); + + printf("\nExtracted accel frames\n"); + + if (accel_frame_length > frame_count) + { + accel_frame_length = frame_count; + } + + /* Print the parsed accelerometer data from the FIFO buffer. */ + for (index = 0; index < accel_frame_length; index++) + { + printf("ACCEL[%d] X : %d\t Y : %d\t Z : %d\n", index, fifo_accel_data[index].x, + fifo_accel_data[index].y, fifo_accel_data[index].z); + } + + printf("\nExtracted gyro frames\n"); + + if (gyro_frame_length > frame_count) + { + gyro_frame_length = frame_count; + } + + /* Print the parsed gyro data from the FIFO buffer. */ + for (index = 0; index < gyro_frame_length; index++) + { + printf("GYRO[%d] X : %d\t Y : %d\t Z : %d\n", + index, + fifo_gyro_data[index].x, + fifo_gyro_data[index].y, + fifo_gyro_data[index].z); + } + } + + try++; + } + } + + bmi2_coines_deinit(); + + return rslt; +} + +/*! + * @brief This internal API is used to set configurations for accel and gyro. + */ +static int8_t set_accel_gyro_config(struct bmi2_dev *bmi2_dev) +{ + /* Status of api are returned to this variable. */ + int8_t rslt; + + /* Structure to define accel and gyro configurations. */ + struct bmi2_sens_config config[2]; + + /* Configure the type of feature. */ + config[0].type = BMI2_ACCEL; + config[1].type = BMI2_GYRO; + + /* Get default configurations for the type of feature selected. */ + rslt = bmi270_context_get_sensor_config(config, 2, bmi2_dev); + bmi2_error_codes_print_result(rslt); + + if (rslt == BMI2_OK) + { + /* NOTE: The user can change the following configuration parameters according to their requirement. */ + /* Accel configuration settings. */ + /* Set Output Data Rate */ + config[0].cfg.acc.odr = BMI2_ACC_ODR_100HZ; + + /* Gravity range of the sensor (+/- 2G, 4G, 8G, 16G). */ + config[0].cfg.acc.range = BMI2_ACC_RANGE_2G; + + /* The bandwidth parameter is used to configure the number of sensor samples that are averaged + * if it is set to 2, then 2^(bandwidth parameter) samples + * are averaged, resulting in 4 averaged samples + * Note1 : For more information, refer the datasheet. + * Note2 : A higher number of averaged samples will result in a lower noise level of the signal, but + * this has an adverse effect on the power consumed. + */ + config[0].cfg.acc.bwp = BMI2_ACC_NORMAL_AVG4; + + /* Enable the filter performance mode where averaging of samples + * will be done based on above set bandwidth and ODR. + * There are two modes + * 0 -> Ultra low power mode + * 1 -> High performance mode(Default) + * For more info refer datasheet. + */ + config[0].cfg.acc.filter_perf = BMI2_PERF_OPT_MODE; + + /* Gyro configuration settings. */ + /* Set Output Data Rate */ + config[1].cfg.gyr.odr = BMI2_GYR_ODR_100HZ; + + /* Gyroscope Angular Rate Measurement Range.By default the range is 2000dps. */ + config[1].cfg.gyr.range = BMI2_GYR_RANGE_2000; + + /* Gyroscope Bandwidth parameters. By default the gyro bandwidth is in normal mode. */ + config[1].cfg.gyr.bwp = BMI2_GYR_NORMAL_MODE; + + /* Enable/Disable the noise performance mode for precision yaw rate sensing + * There are two modes + * 0 -> Ultra low power mode(Default) + * 1 -> High performance mode + */ + config[1].cfg.gyr.noise_perf = BMI2_POWER_OPT_MODE; + + /* Enable/Disable the filter performance mode where averaging of samples + * will be done based on above set bandwidth and ODR. + * There are two modes + * 0 -> Ultra low power mode + * 1 -> High performance mode(Default) + */ + config[1].cfg.gyr.filter_perf = BMI2_PERF_OPT_MODE; + + /* Set new configurations. */ + rslt = bmi270_context_set_sensor_config(config, 2, bmi2_dev); + bmi2_error_codes_print_result(rslt); + } + + return rslt; +} diff --git a/examples/bmi270_context/fifo_watermark_header_mode/Makefile b/examples/bmi270_context/fifo_watermark_header_mode/Makefile new file mode 100644 index 0000000..38c5ce6 --- /dev/null +++ b/examples/bmi270_context/fifo_watermark_header_mode/Makefile @@ -0,0 +1,18 @@ +COINES_INSTALL_PATH ?= ../../../.. + +EXAMPLE_FILE ?= fifo_watermark_header_mode.c + +API_LOCATION ?= ../.. + +COMMON_LOCATION ?= .. + +C_SRCS += \ +$(API_LOCATION)/bmi2.c \ +$(API_LOCATION)/bmi270_context.c \ +$(COMMON_LOCATION)/common/common.c + +INCLUDEPATHS += \ +$(API_LOCATION) \ +$(COMMON_LOCATION)/common + +include $(COINES_INSTALL_PATH)/coines.mk \ No newline at end of file diff --git a/examples/bmi270_context/fifo_watermark_header_mode/fifo_watermark_header_mode.c b/examples/bmi270_context/fifo_watermark_header_mode/fifo_watermark_header_mode.c new file mode 100644 index 0000000..59ff8f7 --- /dev/null +++ b/examples/bmi270_context/fifo_watermark_header_mode/fifo_watermark_header_mode.c @@ -0,0 +1,335 @@ +/**\ + * Copyright (c) 2020 Bosch Sensortec GmbH. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + **/ + +/******************************************************************************/ +/*! Header Files */ +#include +#include "bmi270_context.h" +#include "common.h" + +/******************************************************************************/ +/*! Macros */ + +/*! Buffer size allocated to store raw FIFO data */ +#define BMI2_FIFO_RAW_DATA_BUFFER_SIZE UINT16_C(2048) + +/*! Length of data to be read from FIFO */ +#define BMI2_FIFO_RAW_DATA_USER_LENGTH UINT16_C(2048) + +/*! Number of accel frames to be extracted from FIFO */ + +/*! + * Calculation: + * fifo_watermark_level = 650, accel_frame_len = 6, gyro_frame_len = 6 header_byte = 1. + * fifo_accel_frame_count = (650 / (6 + 6 + 1 )) = 50 frames + * NOTE: Extra frames are read in order to get sensor time + */ +#define BMI2_FIFO_ACCEL_FRAME_COUNT UINT8_C(55) + +/*! Number of gyro frames to be extracted from FIFO */ +#define BMI2_FIFO_GYRO_FRAME_COUNT UINT8_C(55) + +/*! Setting a watermark level in FIFO */ +#define BMI270_FIFO_WATERMARK_LEVEL UINT16_C(650) + +/*! Macro to read sensortime byte in FIFO */ +#define SENSORTIME_OVERHEAD_BYTE UINT8_C(3) + +/******************************************************************************/ +/*! Static Function Declaration */ + +/*! + * @brief This internal API is used to set configurations for accel and gyro. + * @param[in] dev : Structure instance of bmi2_dev. + * @return Status of execution. + */ +static int8_t set_accel_gyro_config(struct bmi2_dev *dev); + +/******************************************************************************/ +/*! Functions */ + +/* This function starts the execution of program. */ +int main(void) +{ + /* Status of api are returned to this variable. */ + int8_t rslt; + + /* Variable to store the available frame length count in FIFO */ + uint8_t frame_count; + + /* Variable to index bytes. */ + uint16_t index = 0; + + uint16_t fifo_length = 0; + + uint16_t accel_frame_length; + + uint16_t gyro_frame_length; + + uint8_t try = 1; + + /* To read sensortime, extra 3 bytes are added to fifo buffer */ + uint16_t fifo_buffer_size = BMI2_FIFO_RAW_DATA_BUFFER_SIZE + SENSORTIME_OVERHEAD_BYTE; + + /* Number of bytes of FIFO data. */ + uint8_t fifo_data[fifo_buffer_size]; + + /* Sensor initialization configuration. */ + struct bmi2_dev bmi2_dev; + + /* Array of accelerometer frames -> Total bytes = + * 55 * (6 axes bytes) = 330 bytes */ + struct bmi2_sens_axes_data fifo_accel_data[BMI2_FIFO_ACCEL_FRAME_COUNT] = { { 0 } }; + + /* Array of gyro frames -> Total bytes = + * 55 * (6 axes bytes) = 330 bytes */ + struct bmi2_sens_axes_data fifo_gyro_data[BMI2_FIFO_GYRO_FRAME_COUNT] = { { 0 } }; + + /* Initialize FIFO frame structure. */ + struct bmi2_fifo_frame fifoframe = { 0 }; + + /* Accel and gyro sensor are listed in array. */ + uint8_t sensor_sel[2] = { BMI2_ACCEL, BMI2_GYRO }; + + /* Variable to get fifo water-mark interrupt status. */ + uint16_t int_status = 0; + + uint16_t watermark = 0; + + /* Interface reference is given as a parameter + * For I2C : BMI2_I2C_INTF + * For SPI : BMI2_SPI_INTF + */ + rslt = bmi2_interface_init(&bmi2_dev, BMI2_I2C_INTF); + bmi2_error_codes_print_result(rslt); + + /* Initialize bmi270_context. */ + rslt = bmi270_context_init(&bmi2_dev); + bmi2_error_codes_print_result(rslt); + + /* Enable accel and gyro sensor. */ + rslt = bmi270_context_sensor_enable(sensor_sel, 2, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + /* Configuration settings for accel and gyro. */ + rslt = set_accel_gyro_config(&bmi2_dev); + bmi2_error_codes_print_result(rslt); + + /* Before setting FIFO, disable the advance power save mode. */ + rslt = bmi2_set_adv_power_save(BMI2_DISABLE, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + /* Initially disable all configurations in fifo. */ + rslt = bmi2_set_fifo_config(BMI2_FIFO_ALL_EN, BMI2_DISABLE, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + /* Update FIFO structure. */ + /* Mapping the buffer to store the fifo data. */ + fifoframe.data = fifo_data; + + /* Length of FIFO frame. */ + /* To read sensortime, extra 3 bytes are added to fifo user length. */ + fifoframe.length = BMI2_FIFO_RAW_DATA_USER_LENGTH + SENSORTIME_OVERHEAD_BYTE; + + /* Set FIFO configuration by enabling accel, gyro and timestamp. + * NOTE 1: The header mode is enabled by default. + * NOTE 2: By default the FIFO operating mode is FIFO mode. + * NOTE 3: Sensortime is enabled by default */ + printf("FIFO is configured in header mode\n"); + rslt = bmi2_set_fifo_config(BMI2_FIFO_ACC_EN | BMI2_FIFO_GYR_EN, BMI2_ENABLE, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + /* FIFO water-mark interrupt is enabled. */ + fifoframe.data_int_map = BMI2_FWM_INT; + + /* Map water-mark interrupt to the required interrupt pin. */ + rslt = bmi2_map_data_int(fifoframe.data_int_map, BMI2_INT1, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + /* Set water-mark level. */ + fifoframe.wm_lvl = BMI270_FIFO_WATERMARK_LEVEL; + + /* Set the water-mark level if water-mark interrupt is mapped. */ + rslt = bmi2_set_fifo_wm(fifoframe.wm_lvl, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + rslt = bmi2_get_fifo_wm(&watermark, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + printf("\nFIFO watermark level is %d\n", watermark); + + while (try <= 10) + { + /* Read FIFO data on interrupt. */ + rslt = bmi2_get_int_status(&int_status, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + /* To check the status of FIFO watermark interrupt. */ + if ((rslt == BMI2_OK) && (int_status & BMI2_FWM_INT_STATUS_MASK)) + { + printf("\nIteration : %d\n", try); + + printf("\nWatermark interrupt occurred\n"); + + rslt = bmi2_get_fifo_length(&fifo_length, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + accel_frame_length = BMI2_FIFO_ACCEL_FRAME_COUNT; + gyro_frame_length = BMI2_FIFO_GYRO_FRAME_COUNT; + + printf("\nFIFO data bytes available : %d \n", fifo_length); + printf("\nFIFO data bytes requested : %d \n", fifoframe.length); + + /* Read FIFO data. */ + rslt = bmi2_read_fifo_data(&fifoframe, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + /* Read FIFO data on interrupt. */ + rslt = bmi2_get_int_status(&int_status, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + if (rslt == BMI2_OK) + { + printf("\nFIFO accel frames requested : %d \n", accel_frame_length); + + /* Parse the FIFO data to extract accelerometer data from the FIFO buffer. */ + rslt = bmi2_extract_accel(fifo_accel_data, &accel_frame_length, &fifoframe, &bmi2_dev); + printf("\nFIFO accel frames extracted : %d \n", accel_frame_length); + + printf("\nFIFO gyro frames requested : %d \n", gyro_frame_length); + + /* Parse the FIFO data to extract gyro data from the FIFO buffer. */ + rslt = bmi2_extract_gyro(fifo_gyro_data, &gyro_frame_length, &fifoframe, &bmi2_dev); + printf("\nFIFO gyro frames extracted : %d \n", gyro_frame_length); + + /* Calculating the frame count from the available bytes in FIFO + * frame_length = (available_fifo_bytes / (acc_frame_len + gyro_frame_len + header_byte)) */ + frame_count = (fifo_length / (BMI2_FIFO_ACC_GYR_LENGTH + 1)); + printf("\nAvailable frame count from available bytes: %d\n", frame_count); + + printf("\nExracted accel frames\n"); + + if (accel_frame_length > frame_count) + { + accel_frame_length = frame_count; + } + + /* Print the parsed accelerometer data from the FIFO buffer. */ + for (index = 0; index < accel_frame_length; index++) + { + printf("ACCEL[%d] X : %d\t Y : %d\t Z : %d\n", index, fifo_accel_data[index].x, + fifo_accel_data[index].y, fifo_accel_data[index].z); + } + + printf("\nExtracted gyro frames\n"); + + if (gyro_frame_length > frame_count) + { + gyro_frame_length = frame_count; + } + + /* Print the parsed gyro data from the FIFO buffer. */ + for (index = 0; index < gyro_frame_length; index++) + { + printf("GYRO[%d] X : %d\t Y : %d\t Z : %d\n", + index, + fifo_gyro_data[index].x, + fifo_gyro_data[index].y, + fifo_gyro_data[index].z); + } + + /* Print control frames like sensor time and skipped frame count. */ + printf("Skipped frame count = %d\n", fifoframe.skipped_frame_count); + printf("Sensor time = %lu\r\n", fifoframe.sensor_time); + + try++; + } + } + } + + bmi2_coines_deinit(); + + return rslt; +} + +/*! + * @brief This internal API is used to set configurations for accel and gyro. + */ +static int8_t set_accel_gyro_config(struct bmi2_dev *dev) +{ + /* Status of api are returned to this variable. */ + int8_t rslt; + + /* Structure to define accel and gyro configurations. */ + struct bmi2_sens_config config[2]; + + /* Configure the type of feature. */ + config[0].type = BMI2_ACCEL; + config[1].type = BMI2_GYRO; + + /* Get default configurations for the type of feature selected. */ + rslt = bmi270_context_get_sensor_config(config, 2, dev); + bmi2_error_codes_print_result(rslt); + + if (rslt == BMI2_OK) + { + /* NOTE: The user can change the following configuration parameters according to their requirement. */ + /* Accel configuration settings. */ + /* Set Output Data Rate */ + config[0].cfg.acc.odr = BMI2_ACC_ODR_25HZ; + + /* Gravity range of the sensor (+/- 2G, 4G, 8G, 16G). */ + config[0].cfg.acc.range = BMI2_ACC_RANGE_2G; + + /* The bandwidth parameter is used to configure the number of sensor samples that are averaged + * if it is set to 2, then 2^(bandwidth parameter) samples + * are averaged, resulting in 4 averaged samples + * Note1 : For more information, refer the datasheet. + * Note2 : A higher number of averaged samples will result in a lower noise level of the signal, but + * this has an adverse effect on the power consumed. + */ + config[0].cfg.acc.bwp = BMI2_ACC_NORMAL_AVG4; + + /* Enable the filter performance mode where averaging of samples + * will be done based on above set bandwidth and ODR. + * There are two modes + * 0 -> Ultra low power mode + * 1 -> High performance mode(Default) + * For more info refer datasheet. + */ + config[0].cfg.acc.filter_perf = BMI2_PERF_OPT_MODE; + + /* Gyro configuration settings. */ + /* Set Output Data Rate */ + config[1].cfg.gyr.odr = BMI2_GYR_ODR_25HZ; + + /* Gyroscope Angular Rate Measurement Range.By default the range is 2000dps. */ + config[1].cfg.gyr.range = BMI2_GYR_RANGE_2000; + + /* Gyroscope Bandwidth parameters. By default the gyro bandwidth is in normal mode. */ + config[1].cfg.gyr.bwp = BMI2_GYR_NORMAL_MODE; + + /* Enable/Disable the noise performance mode for precision yaw rate sensing + * There are two modes + * 0 -> Ultra low power mode(Default) + * 1 -> High performance mode + */ + config[1].cfg.gyr.noise_perf = BMI2_POWER_OPT_MODE; + + /* Enable/Disable the filter performance mode where averaging of samples + * will be done based on above set bandwidth and ODR. + * There are two modes + * 0 -> Ultra low power mode + * 1 -> High performance mode(Default) + */ + config[1].cfg.gyr.filter_perf = BMI2_PERF_OPT_MODE; + + /* Set new configurations. */ + rslt = bmi270_context_set_sensor_config(config, 2, dev); + bmi2_error_codes_print_result(rslt); + } + + return rslt; +} diff --git a/examples/bmi270_context/fifo_watermark_headerless_mode/Makefile b/examples/bmi270_context/fifo_watermark_headerless_mode/Makefile new file mode 100644 index 0000000..9d5e86e --- /dev/null +++ b/examples/bmi270_context/fifo_watermark_headerless_mode/Makefile @@ -0,0 +1,18 @@ +COINES_INSTALL_PATH ?= ../../../.. + +EXAMPLE_FILE ?= fifo_watermark_headerless_mode.c + +API_LOCATION ?= ../.. + +COMMON_LOCATION ?= .. + +C_SRCS += \ +$(API_LOCATION)/bmi2.c \ +$(API_LOCATION)/bmi270_context.c \ +$(COMMON_LOCATION)/common/common.c + +INCLUDEPATHS += \ +$(API_LOCATION) \ +$(COMMON_LOCATION)/common + +include $(COINES_INSTALL_PATH)/coines.mk \ No newline at end of file diff --git a/examples/bmi270_context/fifo_watermark_headerless_mode/fifo_watermark_headerless_mode.c b/examples/bmi270_context/fifo_watermark_headerless_mode/fifo_watermark_headerless_mode.c new file mode 100644 index 0000000..878fe43 --- /dev/null +++ b/examples/bmi270_context/fifo_watermark_headerless_mode/fifo_watermark_headerless_mode.c @@ -0,0 +1,331 @@ +/**\ + * Copyright (c) 2020 Bosch Sensortec GmbH. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + **/ + +/******************************************************************************/ +/*! Header Files */ +#include +#include "bmi270_context.h" +#include "common.h" + +/******************************************************************************/ +/*! Macros */ + +/*! Buffer size allocated to store raw FIFO data */ +#define BMI2_FIFO_RAW_DATA_BUFFER_SIZE UINT16_C(2048) + +/*! Length of data to be read from FIFO */ +#define BMI2_FIFO_RAW_DATA_USER_LENGTH UINT16_C(2048) + +/*! Number of accel frames to be extracted from FIFO */ + +/*! + * Calculation: + * fifo_watermark_level = 650, accel_frame_len = 6, gyro_frame_len = 6. + * fifo_accel_frame_count = (650 / (6 + 6 )) = 54 frames + */ +#define BMI2_FIFO_ACCEL_FRAME_COUNT UINT8_C(55) + +/*! Number of gyro frames to be extracted from FIFO */ +#define BMI2_FIFO_GYRO_FRAME_COUNT UINT8_C(55) + +/*! Setting a watermark level in FIFO */ +#define BMI270_FIFO_WATERMARK_LEVEL UINT16_C(650) + +/******************************************************************************/ +/*! Static Function Declaration */ + +/*! + * @brief This internal API is used to set configurations for accel and gyro. + * @param[in] dev : Structure instance of bmi2_dev. + * @return Status of execution. + */ +static int8_t set_accel_gyro_config(struct bmi2_dev *dev); + +/******************************************************************************/ +/*! Functions */ + +/* This function starts the execution of program. */ +int main(void) +{ + /* Status of api are returned to this variable. */ + int8_t rslt; + + /* Variable to index bytes. */ + uint16_t index = 0; + + /* Variable to store the available frame length count in FIFO */ + uint8_t frame_count; + + uint16_t fifo_length = 0; + + uint16_t accel_frame_length; + + uint16_t gyro_frame_length; + + uint8_t try = 1; + + /* Number of bytes of FIFO data. */ + uint8_t fifo_data[BMI2_FIFO_RAW_DATA_BUFFER_SIZE] = { 0 }; + + /* Sensor initialization configuration. */ + struct bmi2_dev bmi2_dev; + + /* Array of accelerometer frames -> Total bytes = + * 50 * (6 axes bytes) = 300 bytes */ + struct bmi2_sens_axes_data fifo_accel_data[BMI2_FIFO_ACCEL_FRAME_COUNT] = { { 0 } }; + + /* Array of gyro frames -> Total bytes = + * 50 * (6 axes bytes) = 300 bytes */ + struct bmi2_sens_axes_data fifo_gyro_data[BMI2_FIFO_GYRO_FRAME_COUNT] = { { 0 } }; + + /* Initialize FIFO frame structure. */ + struct bmi2_fifo_frame fifoframe = { 0 }; + + /* Accel and gyro sensor are listed in array. */ + uint8_t sensor_sel[2] = { BMI2_ACCEL, BMI2_GYRO }; + + /* Variable to get fifo water-mark interrupt status. */ + uint16_t int_status = 0; + + uint16_t watermark = 0; + + /* Interface reference is given as a parameter + * For I2C : BMI2_I2C_INTF + * For SPI : BMI2_SPI_INTF + */ + rslt = bmi2_interface_init(&bmi2_dev, BMI2_I2C_INTF); + bmi2_error_codes_print_result(rslt); + + /* Initialize bmi270_context. */ + rslt = bmi270_context_init(&bmi2_dev); + bmi2_error_codes_print_result(rslt); + + /* Enable accel and gyro sensor. */ + rslt = bmi270_context_sensor_enable(sensor_sel, 2, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + /* Configuration settings for accel and gyro. */ + rslt = set_accel_gyro_config(&bmi2_dev); + bmi2_error_codes_print_result(rslt); + + /* Before setting FIFO, disable the advance power save mode. */ + rslt = bmi2_set_adv_power_save(BMI2_DISABLE, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + /* Initially disable all configurations in fifo. */ + rslt = bmi2_set_fifo_config(BMI2_FIFO_ALL_EN, BMI2_DISABLE, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + /* Update FIFO structure. */ + /* Mapping the buffer to store the fifo data. */ + fifoframe.data = fifo_data; + + /* Length of FIFO frame. */ + fifoframe.length = BMI2_FIFO_RAW_DATA_USER_LENGTH; + + /* Set FIFO configuration by enabling accel, gyro. + * NOTE 1: The header mode is enabled by default. + * NOTE 2: By default the FIFO operating mode is FIFO mode. */ + rslt = bmi2_set_fifo_config(BMI2_FIFO_ACC_EN | BMI2_FIFO_GYR_EN, BMI2_ENABLE, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + printf("FIFO is configured in headerless mode\n"); + + /* To enable headerless mode, disable the header. */ + if (rslt == BMI2_OK) + { + rslt = bmi2_set_fifo_config(BMI2_FIFO_HEADER_EN, BMI2_DISABLE, &bmi2_dev); + } + + /* FIFO water-mark interrupt is enabled. */ + fifoframe.data_int_map = BMI2_FWM_INT; + + /* Map water-mark interrupt to the required interrupt pin. */ + rslt = bmi2_map_data_int(fifoframe.data_int_map, BMI2_INT1, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + /* Set water-mark level. */ + fifoframe.wm_lvl = BMI270_FIFO_WATERMARK_LEVEL; + + fifoframe.length = BMI2_FIFO_RAW_DATA_USER_LENGTH; + + /* Set the water-mark level if water-mark interrupt is mapped. */ + rslt = bmi2_set_fifo_wm(fifoframe.wm_lvl, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + rslt = bmi2_get_fifo_wm(&watermark, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + printf("\nFIFO watermark level is %d\n", watermark); + + while (try <= 10) + { + /* Read FIFO data on interrupt. */ + rslt = bmi2_get_int_status(&int_status, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + /* To check the status of FIFO watermark interrupt. */ + if ((rslt == BMI2_OK) && (int_status & BMI2_FWM_INT_STATUS_MASK)) + { + printf("\nIteration : %d\n", try); + + printf("\nWatermark interrupt occurred\n"); + + rslt = bmi2_get_fifo_length(&fifo_length, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + accel_frame_length = BMI2_FIFO_ACCEL_FRAME_COUNT; + gyro_frame_length = BMI2_FIFO_GYRO_FRAME_COUNT; + + printf("\nFIFO data bytes available : %d \n", fifo_length); + printf("\nFIFO data bytes requested : %d \n", fifoframe.length); + + /* Read FIFO data. */ + rslt = bmi2_read_fifo_data(&fifoframe, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + /* Read FIFO data on interrupt. */ + rslt = bmi2_get_int_status(&int_status, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + if (rslt == BMI2_OK) + { + printf("\nFIFO accel frames requested : %d \n", accel_frame_length); + + /* Parse the FIFO data to extract accelerometer data from the FIFO buffer. */ + rslt = bmi2_extract_accel(fifo_accel_data, &accel_frame_length, &fifoframe, &bmi2_dev); + printf("\nFIFO accel frames extracted : %d \n", accel_frame_length); + + printf("\nFIFO gyro frames requested : %d \n", gyro_frame_length); + + /* Parse the FIFO data to extract gyro data from the FIFO buffer. */ + rslt = bmi2_extract_gyro(fifo_gyro_data, &gyro_frame_length, &fifoframe, &bmi2_dev); + printf("\nFIFO gyro frames extracted : %d \n", gyro_frame_length); + + /* Calculating the frame count from the available bytes in FIFO + * frame_length = (available_fifo_bytes / (acc_frame_len + gyro_frame_len)) */ + frame_count = (fifo_length / (BMI2_FIFO_ACC_GYR_LENGTH)); + printf("\nAvailable frame count from available bytes: %d\n", frame_count); + + printf("\nExracted accel frames\n"); + + if (accel_frame_length > frame_count) + { + accel_frame_length = frame_count; + } + + /* Print the parsed accelerometer data from the FIFO buffer. */ + for (index = 0; index < accel_frame_length; index++) + { + printf("ACCEL[%d] X : %d\t Y : %d\t Z : %d\n", index, fifo_accel_data[index].x, + fifo_accel_data[index].y, fifo_accel_data[index].z); + } + + printf("\nExtracted gyro frames\n"); + + if (gyro_frame_length > frame_count) + { + gyro_frame_length = frame_count; + } + + /* Print the parsed gyro data from the FIFO buffer. */ + for (index = 0; index < gyro_frame_length; index++) + { + printf("GYRO[%d] X : %d\t Y : %d\t Z : %d\n", + index, + fifo_gyro_data[index].x, + fifo_gyro_data[index].y, + fifo_gyro_data[index].z); + } + } + + try++; + } + } + + bmi2_coines_deinit(); + + return rslt; +} + +/*! + * @brief This internal API is used to set configurations for accel. + */ +static int8_t set_accel_gyro_config(struct bmi2_dev *dev) +{ + /* Status of api are returned to this variable. */ + int8_t rslt; + + /* Structure to define accel and gyro configurations. */ + struct bmi2_sens_config config[2]; + + /* Configure the type of feature. */ + config[0].type = BMI2_ACCEL; + config[1].type = BMI2_GYRO; + + /* Get default configurations for the type of feature selected. */ + rslt = bmi270_context_get_sensor_config(config, 2, dev); + bmi2_error_codes_print_result(rslt); + + if (rslt == BMI2_OK) + { + /* NOTE: The user can change the following configuration parameter according to their requirement. */ + /* Accel configuration settings. */ + /* Set Output Data Rate */ + config[0].cfg.acc.odr = BMI2_ACC_ODR_100HZ; + + /* Gravity range of the sensor (+/- 2G, 4G, 8G, 16G). */ + config[0].cfg.acc.range = BMI2_ACC_RANGE_2G; + + /* The bandwidth parameter is used to configure the number of sensor samples that are averaged + * if it is set to 2, then 2^(bandwidth parameter) samples + * are averaged, resulting in 4 averaged samples + * Note1 : For more information, refer the datasheet. + * Note2 : A higher number of averaged samples will result in a lower noise level of the signal, but + * this has an adverse effect on the power consumed. + */ + config[0].cfg.acc.bwp = BMI2_ACC_NORMAL_AVG4; + + /* Enable the filter performance mode where averaging of samples + * will be done based on above set bandwidth and ODR. + * There are two modes + * 0 -> Ultra low power mode + * 1 -> High performance mode(Default) + * For more info refer datasheet. + */ + config[0].cfg.acc.filter_perf = BMI2_PERF_OPT_MODE; + + /* Gyro configuration settings. */ + /* Set Output Data Rate */ + config[1].cfg.gyr.odr = BMI2_GYR_ODR_100HZ; + + /* Gyroscope Angular Rate Measurement Range.By default the range is 2000dps. */ + config[1].cfg.gyr.range = BMI2_GYR_RANGE_2000; + + /* Gyroscope Bandwidth parameters. By default the gyro bandwidth is in normal mode. */ + config[1].cfg.gyr.bwp = BMI2_GYR_NORMAL_MODE; + + /* Enable/Disable the noise performance mode for precision yaw rate sensing + * There are two modes + * 0 -> Ultra low power mode(Default) + * 1 -> High performance mode + */ + config[1].cfg.gyr.noise_perf = BMI2_POWER_OPT_MODE; + + /* Enable/Disable the filter performance mode where averaging of samples + * will be done based on above set bandwidth and ODR. + * There are two modes + * 0 -> Ultra low power mode + * 1 -> High performance mode(Default) + */ + config[1].cfg.gyr.filter_perf = BMI2_PERF_OPT_MODE; + + /* Set new configurations. */ + rslt = bmi270_context_set_sensor_config(config, 2, dev); + bmi2_error_codes_print_result(rslt); + } + + return rslt; +} diff --git a/examples/bmi270_context/gyro/Makefile b/examples/bmi270_context/gyro/Makefile new file mode 100644 index 0000000..135fe5b --- /dev/null +++ b/examples/bmi270_context/gyro/Makefile @@ -0,0 +1,18 @@ +COINES_INSTALL_PATH ?= ../../../.. + +EXAMPLE_FILE ?= gyro.c + +API_LOCATION ?= ../.. + +COMMON_LOCATION ?= .. + +C_SRCS += \ +$(API_LOCATION)/bmi2.c \ +$(API_LOCATION)/bmi270_context.c \ +$(COMMON_LOCATION)/common/common.c + +INCLUDEPATHS += \ +$(API_LOCATION) \ +$(COMMON_LOCATION)/common + +include $(COINES_INSTALL_PATH)/coines.mk \ No newline at end of file diff --git a/examples/bmi270_context/gyro/gyro.c b/examples/bmi270_context/gyro/gyro.c new file mode 100644 index 0000000..0a057e4 --- /dev/null +++ b/examples/bmi270_context/gyro/gyro.c @@ -0,0 +1,195 @@ +/**\ + * Copyright (c) 2020 Bosch Sensortec GmbH. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + **/ + +/******************************************************************************/ +/*! Header Files */ +#include +#include "bmi270_context.h" +#include "common.h" + +/******************************************************************************/ +/*! Static Function Declaration */ + +/*! + * @brief This internal API is used to set configurations for gyro. + * + * @param[in] dev : Structure instance of bmi2_dev. + * + * @return Status of execution. + */ +static int8_t set_gyro_config(struct bmi2_dev *dev); + +/*! + * @brief This function converts lsb to degree per second for 16 bit gyro at + * range 125, 250, 500, 1000 or 2000dps. + * + * @param[in] val : LSB from each axis. + * @param[in] dps : Degree per second. + * @param[in] bit_width : Resolution for gyro. + * + * @return Degree per second. + */ +static float lsb_to_dps(int16_t val, float dps, uint8_t bit_width); + +/******************************************************************************/ +/*! Functions */ + +/* This function starts the execution of program. */ +int main(void) +{ + /* Status of api are returned to this variable. */ + int8_t rslt; + + /* Variable to define limit to print gyro data. */ + uint8_t limit = 10; + + uint8_t indx = 0; + + float x = 0, y = 0, z = 0; + + /* Sensor initialization configuration. */ + struct bmi2_dev bmi2_dev; + + /* Create an instance of sensor data structure. */ + struct bmi2_sensor_data sensor_data = { 0 }; + + /* Assign gyro sensor to variable. */ + uint8_t sens_list = BMI2_GYRO; + + /* Initialize the interrupt status of gyro. */ + uint16_t int_status = 0; + + /* Interface reference is given as a parameter + * For I2C : BMI2_I2C_INTF + * For SPI : BMI2_SPI_INTF + */ + rslt = bmi2_interface_init(&bmi2_dev, BMI2_I2C_INTF); + bmi2_error_codes_print_result(rslt); + + /* Initialize bmi270_context. */ + rslt = bmi270_context_init(&bmi2_dev); + bmi2_error_codes_print_result(rslt); + + if (rslt == BMI2_OK) + { + /* Enable the selected sensors. */ + rslt = bmi270_context_sensor_enable(&sens_list, 1, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + if (rslt == BMI2_OK) + { + /* Gyro configuration settings. */ + rslt = set_gyro_config(&bmi2_dev); + bmi2_error_codes_print_result(rslt); + + /* Select gyro sensor. */ + sensor_data.type = BMI2_GYRO; + printf("Gyro and DPS data\n"); + printf("Gyro data collected at Range 2000 dps with 16-bit resolution\n"); + + /* Loop to print gyro data when interrupt occurs. */ + while (indx <= limit) + { + /* To get the data ready interrupt status of gyro. */ + rslt = bmi2_get_int_status(&int_status, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + /* To check the data ready interrupt status and print the status for 10 samples. */ + if (int_status & BMI2_GYR_DRDY_INT_MASK) + { + /* Get gyro data for x, y and z axis. */ + rslt = bmi270_context_get_sensor_data(&sensor_data, 1, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + printf("\nGyr_X = %d\t", sensor_data.sens_data.gyr.x); + printf("Gyr_Y = %d\t", sensor_data.sens_data.gyr.y); + printf("Gyr_Z = %d\r\n", sensor_data.sens_data.gyr.z); + + /* Converting lsb to degree per second for 16 bit gyro at 2000dps range. */ + x = lsb_to_dps(sensor_data.sens_data.gyr.x, 2000, bmi2_dev.resolution); + y = lsb_to_dps(sensor_data.sens_data.gyr.y, 2000, bmi2_dev.resolution); + z = lsb_to_dps(sensor_data.sens_data.gyr.z, 2000, bmi2_dev.resolution); + + /* Print the data in dps. */ + printf("Gyr_DPS_X = %4.2f, Gyr_DPS_Y = %4.2f, Gyr_DPS_Z = %4.2f\n", x, y, z); + + indx++; + } + } + } + } + + bmi2_coines_deinit(); + + return rslt; +} + +/*! + * @brief This internal API is used to set configurations for gyro. + */ +static int8_t set_gyro_config(struct bmi2_dev *dev) +{ + /* Status of api are returned to this variable. */ + int8_t rslt; + + /* Structure to define the type of sensor and its configurations. */ + struct bmi2_sens_config config; + + /* Configure the type of feature. */ + config.type = BMI2_GYRO; + + /* Get default configurations for the type of feature selected. */ + rslt = bmi270_context_get_sensor_config(&config, 1, dev); + bmi2_error_codes_print_result(rslt); + + /* Map data ready interrupt to interrupt pin. */ + rslt = bmi2_map_data_int(BMI2_DRDY_INT, BMI2_INT2, dev); + bmi2_error_codes_print_result(rslt); + + if (rslt == BMI2_OK) + { + /* The user can change the following configuration parameters according to their requirement. */ + /* Set Output Data Rate */ + config.cfg.gyr.odr = BMI2_GYR_ODR_200HZ; + + /* Gyroscope Angular Rate Measurement Range.By default the range is 2000dps. */ + config.cfg.gyr.range = BMI2_GYR_RANGE_2000; + + /* Gyroscope bandwidth parameters. By default the gyro bandwidth is in normal mode. */ + config.cfg.gyr.bwp = BMI2_GYR_NORMAL_MODE; + + /* Enable/Disable the noise performance mode for precision yaw rate sensing + * There are two modes + * 0 -> Ultra low power mode(Default) + * 1 -> High performance mode + */ + config.cfg.gyr.noise_perf = BMI2_POWER_OPT_MODE; + + /* Enable/Disable the filter performance mode where averaging of samples + * will be done based on above set bandwidth and ODR. + * There are two modes + * 0 -> Ultra low power mode + * 1 -> High performance mode(Default) + */ + config.cfg.gyr.filter_perf = BMI2_PERF_OPT_MODE; + + /* Set the gyro configurations. */ + rslt = bmi270_context_set_sensor_config(&config, 1, dev); + } + + return rslt; +} + +/*! + * @brief This function converts lsb to degree per second for 16 bit gyro at + * range 125, 250, 500, 1000 or 2000dps. + */ +static float lsb_to_dps(int16_t val, float dps, uint8_t bit_width) +{ + float half_scale = ((float)(1 << bit_width) / 2.0f); + + return (dps / ((half_scale) + BMI2_GYR_RANGE_2000)) * (val); +} diff --git a/examples/bmi270_context/step_counter/Makefile b/examples/bmi270_context/step_counter/Makefile new file mode 100644 index 0000000..1e8be48 --- /dev/null +++ b/examples/bmi270_context/step_counter/Makefile @@ -0,0 +1,18 @@ +COINES_INSTALL_PATH ?= ../../../.. + +EXAMPLE_FILE ?= step_counter.c + +API_LOCATION ?= ../.. + +COMMON_LOCATION ?= .. + +C_SRCS += \ +$(API_LOCATION)/bmi2.c \ +$(API_LOCATION)/bmi270_context.c \ +$(COMMON_LOCATION)/common/common.c + +INCLUDEPATHS += \ +$(API_LOCATION) \ +$(COMMON_LOCATION)/common + +include $(COINES_INSTALL_PATH)/coines.mk \ No newline at end of file diff --git a/examples/bmi270_context/step_counter/step_counter.c b/examples/bmi270_context/step_counter/step_counter.c new file mode 100644 index 0000000..2513b02 --- /dev/null +++ b/examples/bmi270_context/step_counter/step_counter.c @@ -0,0 +1,146 @@ +/**\ + * Copyright (c) 2020 Bosch Sensortec GmbH. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + **/ + +/******************************************************************************/ +/*! Header Files */ +#include +#include "bmi270_context.h" +#include "common.h" + +/******************************************************************************/ +/*! Static function declaration */ + +/*! + * @brief This internal API is used to set configurations for step counter. + * + * @param[in] bmi2_dev : Structure instance of bmi2_dev. + * + * @return Status of execution. + */ +static int8_t set_feature_config(struct bmi2_dev *bmi2_dev); + +/******************************************************************************/ +/*! Functions */ + +/* This function starts the execution of program. */ +int main(void) +{ + /* Sensor initialization configuration. */ + struct bmi2_dev bmi2_dev; + + /* Structure to define type of sensor and their respective data. */ + struct bmi2_sensor_data sensor_data; + + /* Status of api are returned to this variable. */ + int8_t rslt; + + /* Accel sensor and step counter feature are listed in array. */ + uint8_t sensor_sel[2] = { BMI2_ACCEL, BMI2_STEP_COUNTER }; + + /* Variable to get step counter interrupt status. */ + uint16_t int_status = 0; + + /* Select features and their pins to be mapped to. */ + struct bmi2_sens_int_config sens_int = { .type = BMI2_STEP_COUNTER, .hw_int_pin = BMI2_INT2 }; + + /* Type of sensor to get step counter data. */ + sensor_data.type = BMI2_STEP_COUNTER; + + /* Interface reference is given as a parameter + * For I2C : BMI2_I2C_INTF + * For SPI : BMI2_SPI_INTF + */ + rslt = bmi2_interface_init(&bmi2_dev, BMI2_I2C_INTF); + bmi2_error_codes_print_result(rslt); + + /* Initialize bmi270_context. */ + rslt = bmi270_context_init(&bmi2_dev); + bmi2_error_codes_print_result(rslt); + + if (rslt == BMI2_OK) + { + /* Enable the selected sensor. */ + rslt = bmi270_context_sensor_enable(sensor_sel, 2, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + if (rslt == BMI2_OK) + { + /* Set the feature configuration for step counter. */ + rslt = set_feature_config(&bmi2_dev); + bmi2_error_codes_print_result(rslt); + + printf("Step counter watermark level set to 1 (20 steps)\n"); + + if (rslt == BMI2_OK) + { + /* Map the step counter feature interrupt. */ + rslt = bmi270_context_map_feat_int(&sens_int, 1, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + /* Move the board in steps for 20 times to get step counter interrupt. */ + printf("Move the board in steps\n"); + + /* Loop to get number of steps counted. */ + do + { + /* To get the interrupt status of the step counter. */ + rslt = bmi2_get_int_status(&int_status, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + /* To check the interrupt status of the step counter. */ + if (int_status & BMI270_CONTEXT_STEP_CNT_STATUS_MASK) + { + printf("Step counter interrupt occurred when watermark level (20 steps) is reached\n"); + + /* Get step counter output. */ + rslt = bmi270_context_get_sensor_data(&sensor_data, 1, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + /* Print the step counter output. */ + printf("No of steps counted = %ld", sensor_data.sens_data.step_counter_output); + break; + } + } while (rslt == BMI2_OK); + } + } + } + + bmi2_coines_deinit(); + + return rslt; +} + +/*! + * @brief This internal API is used to set configurations for step counter. + */ +static int8_t set_feature_config(struct bmi2_dev *bmi2_dev) +{ + /* Status of api are returned to this variable. */ + int8_t rslt; + + /* Structure to define the type of sensor and its configurations. */ + struct bmi2_sens_config config; + + /* Configure the type of sensor. */ + config.type = BMI2_STEP_COUNTER; + + /* Get default configurations for the type of feature selected. */ + rslt = bmi270_context_get_sensor_config(&config, 1, bmi2_dev); + bmi2_error_codes_print_result(rslt); + + if (rslt == BMI2_OK) + { + /* Setting water-mark level to 1 for step counter to get interrupt after 20 step counts. Every 20 steps once + * output triggers. */ + config.cfg.step_counter.watermark_level = 1; + + /* Set new configuration. */ + rslt = bmi270_context_set_sensor_config(&config, 1, bmi2_dev); + bmi2_error_codes_print_result(rslt); + } + + return rslt; +} diff --git a/examples/bmi270_hc/accel/Makefile b/examples/bmi270_hc/accel/Makefile new file mode 100644 index 0000000..d4cc64c --- /dev/null +++ b/examples/bmi270_hc/accel/Makefile @@ -0,0 +1,18 @@ +COINES_INSTALL_PATH ?= ../../../.. + +EXAMPLE_FILE ?= accel.c + +API_LOCATION ?= ../.. + +COMMON_LOCATION ?= .. + +C_SRCS += \ +$(API_LOCATION)/bmi2.c \ +$(API_LOCATION)/bmi270_hc.c \ +$(COMMON_LOCATION)/common/common.c + +INCLUDEPATHS += \ +$(API_LOCATION) \ +$(COMMON_LOCATION)/common + +include $(COINES_INSTALL_PATH)/coines.mk \ No newline at end of file diff --git a/examples/bmi270_hc/accel/accel.c b/examples/bmi270_hc/accel/accel.c new file mode 100644 index 0000000..553db37 --- /dev/null +++ b/examples/bmi270_hc/accel/accel.c @@ -0,0 +1,201 @@ +/**\ + * Copyright (c) 2020 Bosch Sensortec GmbH. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + **/ + +/******************************************************************************/ +/*! Header Files */ +#include +#include "bmi270_hc.h" +#include "common.h" + +/******************************************************************************/ +/*! Macro definition */ + +/*! Earth's gravity in m/s^2 */ +#define GRAVITY_EARTH (9.80665f) + +/******************************************************************************/ +/*! Static Function Declaration */ + +/*! + * @brief This internal API is used to set configurations for accel. + * + * @param[in] dev : Structure instance of bmi2_dev. + * + * @return Status of execution. + */ +static int8_t set_accel_config(struct bmi2_dev *bmi2_dev); + +/*! + * @brief This function converts lsb to meter per second squared for 16 bit accelerometer at + * range 2G, 4G, 8G or 16G. + * + * @param[in] val : LSB from each axis. + * @param[in] g_range : Gravity range. + * @param[in] bit_width : Resolution for accel. + * + * @return Gravity. + */ +static float lsb_to_mps2(int16_t val, float g_range, uint8_t bit_width); + +/******************************************************************************/ +/*! Functions */ + +/* This function starts the execution of program. */ +int main(void) +{ + /* Status of api are returned to this variable. */ + int8_t rslt; + + /* Variable to define limit to print accel data. */ + uint8_t limit = 20; + + /* Assign accel sensor to variable. */ + uint8_t sensor_list = BMI2_ACCEL; + + /* Sensor initialization configuration. */ + struct bmi2_dev bmi2_dev; + + /* Create an instance of sensor data structure. */ + struct bmi2_sensor_data sensor_data = { 0 }; + + /* Initialize the interrupt status of accel. */ + uint16_t int_status = 0; + + uint8_t indx = 0; + float x = 0, y = 0, z = 0; + + /* Interface reference is given as a parameter + * For I2C : BMI2_I2C_INTF + * For SPI : BMI2_SPI_INTF + */ + rslt = bmi2_interface_init(&bmi2_dev, BMI2_I2C_INTF); + bmi2_error_codes_print_result(rslt); + + /* Initialize bmi270_hc. */ + rslt = bmi270_hc_init(&bmi2_dev); + bmi2_error_codes_print_result(rslt); + + if (rslt == BMI2_OK) + { + /* Enable the accel sensor. */ + rslt = bmi270_hc_sensor_enable(&sensor_list, 1, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + if (rslt == BMI2_OK) + { + /* Accel configuration settings. */ + rslt = set_accel_config(&bmi2_dev); + bmi2_error_codes_print_result(rslt); + + /* Assign accel sensor. */ + sensor_data.type = BMI2_ACCEL; + printf("Accel and m/s2 data \n"); + printf("Accel data collected at 2G Range with 16-bit resolution\n"); + + /* Loop to print the accel data when interrupt occurs. */ + while (indx <= limit) + { + /* To get the status of accel data ready interrupt. */ + rslt = bmi2_get_int_status(&int_status, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + /* To check the accel data ready interrupt status and print the status for 10 samples. */ + if (int_status & BMI2_ACC_DRDY_INT_MASK) + { + /* Get accelerometer data for x, y and z axis. */ + rslt = bmi270_hc_get_sensor_data(&sensor_data, 1, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + printf("\nAcc_X = %d\t", sensor_data.sens_data.acc.x); + printf("Acc_Y = %d\t", sensor_data.sens_data.acc.y); + printf("Acc_Z = %d\r\n", sensor_data.sens_data.acc.z); + + /* Converting lsb to meter per second squared for 16 bit accelerometer at 2G range. */ + x = lsb_to_mps2(sensor_data.sens_data.acc.x, 2, bmi2_dev.resolution); + y = lsb_to_mps2(sensor_data.sens_data.acc.y, 2, bmi2_dev.resolution); + z = lsb_to_mps2(sensor_data.sens_data.acc.z, 2, bmi2_dev.resolution); + + /* Print the data in m/s2. */ + printf("\nAcc_ms2_X = %4.2f, Acc_ms2_Y = %4.2f, Acc_ms2_Z = %4.2f\n", x, y, z); + + indx++; + } + } + } + } + + bmi2_coines_deinit(); + + return rslt; +} + +/*! + * @brief This internal API is used to set configurations for accel. + */ +static int8_t set_accel_config(struct bmi2_dev *bmi2_dev) +{ + + /* Status of api are returned to this variable. */ + int8_t rslt; + + /* Structure to define accelerometer configuration. */ + struct bmi2_sens_config config; + + /* Configure the type of feature. */ + config.type = BMI2_ACCEL; + + /* Get default configurations for the type of feature selected. */ + rslt = bmi270_hc_get_sensor_config(&config, 1, bmi2_dev); + bmi2_error_codes_print_result(rslt); + + if (rslt == BMI2_OK) + { + /* NOTE: The user can change the following configuration parameters according to their requirement. */ + /* Set Output Data Rate */ + config.cfg.acc.odr = BMI2_ACC_ODR_200HZ; + + /* Gravity range of the sensor (+/- 2G, 4G, 8G, 16G). */ + config.cfg.acc.range = BMI2_ACC_RANGE_2G; + + /* The bandwidth parameter is used to configure the number of sensor samples that are averaged + * if it is set to 2, then 2^(bandwidth parameter) samples + * are averaged, resulting in 4 averaged samples. + * Note1 : For more information, refer the datasheet. + * Note2 : A higher number of averaged samples will result in a lower noise level of the signal, but + * this has an adverse effect on the power consumed. + */ + config.cfg.acc.bwp = BMI2_ACC_NORMAL_AVG4; + + /* Enable the filter performance mode where averaging of samples + * will be done based on above set bandwidth and ODR. + * There are two modes + * 0 -> Ultra low power mode + * 1 -> High performance mode(Default) + * For more info refer datasheet. + */ + config.cfg.acc.filter_perf = BMI2_PERF_OPT_MODE; + + /* Set the accel configurations. */ + rslt = bmi270_hc_set_sensor_config(&config, 1, bmi2_dev); + bmi2_error_codes_print_result(rslt); + + /* Map data ready interrupt to interrupt pin. */ + rslt = bmi2_map_data_int(BMI2_DRDY_INT, BMI2_INT1, bmi2_dev); + bmi2_error_codes_print_result(rslt); + } + + return rslt; +} + +/*! + * @brief This function converts lsb to meter per second squared for 16 bit accelerometer at + * range 2G, 4G, 8G or 16G. + */ +static float lsb_to_mps2(int16_t val, float g_range, uint8_t bit_width) +{ + float half_scale = ((float)(1 << bit_width) / 2.0f); + + return (GRAVITY_EARTH * val * g_range) / half_scale; +} diff --git a/examples/bmi270_hc/accel_gyro/Makefile b/examples/bmi270_hc/accel_gyro/Makefile new file mode 100644 index 0000000..19eb609 --- /dev/null +++ b/examples/bmi270_hc/accel_gyro/Makefile @@ -0,0 +1,18 @@ +COINES_INSTALL_PATH ?= ../../../.. + +EXAMPLE_FILE ?= accel_gyro.c + +API_LOCATION ?= ../.. + +COMMON_LOCATION ?= .. + +C_SRCS += \ +$(API_LOCATION)/bmi2.c \ +$(API_LOCATION)/bmi270_hc.c \ +$(COMMON_LOCATION)/common/common.c + +INCLUDEPATHS += \ +$(API_LOCATION) \ +$(COMMON_LOCATION)/common + +include $(COINES_INSTALL_PATH)/coines.mk \ No newline at end of file diff --git a/examples/bmi270_hc/accel_gyro/accel_gyro.c b/examples/bmi270_hc/accel_gyro/accel_gyro.c new file mode 100644 index 0000000..c92a1b8 --- /dev/null +++ b/examples/bmi270_hc/accel_gyro/accel_gyro.c @@ -0,0 +1,268 @@ +/**\ + * Copyright (c) 2020 Bosch Sensortec GmbH. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + **/ + +/******************************************************************************/ +/*! Header Files */ +#include +#include "bmi270_hc.h" +#include "common.h" + +/******************************************************************************/ +/*! Macro definition */ + +/*! Earth's gravity in m/s^2 */ +#define GRAVITY_EARTH (9.80665f) + +/*! Macros to select the sensors */ +#define ACCEL UINT8_C(0x00) +#define GYRO UINT8_C(0x01) + +/******************************************************************************/ +/*! Static Function Declaration */ + +/*! + * @brief This internal API is used to set configurations for accel. + * + * @param[in] dev : Structure instance of bmi2_dev. + * + * @return Status of execution. + */ +static int8_t set_accel_gyro_config(struct bmi2_dev *bmi2_dev); + +/*! + * @brief This function converts lsb to meter per second squared for 16 bit accelerometer at + * range 2G, 4G, 8G or 16G. + * + * @param[in] val : LSB from each axis. + * @param[in] g_range : Gravity range. + * @param[in] bit_width : Resolution for accel. + * + * @return Gravity. + */ +static float lsb_to_mps2(int16_t val, float g_range, uint8_t bit_width); + +/*! + * @brief This function converts lsb to degree per second for 16 bit gyro at + * range 125, 250, 500, 1000 or 2000dps. + * + * @param[in] val : LSB from each axis. + * @param[in] dps : Degree per second. + * @param[in] bit_width : Resolution for gyro. + * + * @return Degree per second. + */ +static float lsb_to_dps(int16_t val, float dps, uint8_t bit_width); + +/******************************************************************************/ +/*! Functions */ + +/* This function starts the execution of program. */ +int main(void) +{ + /* Status of api are returned to this variable. */ + int8_t rslt; + + /* Variable to define limit to print accel data. */ + uint8_t limit = 10; + + /* Assign accel and gyro sensor to variable. */ + uint8_t sensor_list[2] = { BMI2_ACCEL, BMI2_GYRO }; + + /* Sensor initialization configuration. */ + struct bmi2_dev bmi2_dev; + + /* Create an instance of sensor data structure. */ + struct bmi2_sensor_data sensor_data[2] = { { 0 } }; + + /* Initialize the interrupt status of accel and gyro. */ + uint16_t int_status = 0; + + uint8_t indx = 1; + + float x = 0, y = 0, z = 0; + + /* Interface reference is given as a parameter + * For I2C : BMI2_I2C_INTF + * For SPI : BMI2_SPI_INTF + */ + rslt = bmi2_interface_init(&bmi2_dev, BMI2_I2C_INTF); + bmi2_error_codes_print_result(rslt); + + /* Initialize bmi270_hc. */ + rslt = bmi270_hc_init(&bmi2_dev); + bmi2_error_codes_print_result(rslt); + + if (rslt == BMI2_OK) + { + /* Enable the accel and gyro sensor. */ + rslt = bmi270_hc_sensor_enable(sensor_list, 2, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + if (rslt == BMI2_OK) + { + /* Accel and gyro configuration settings. */ + rslt = set_accel_gyro_config(&bmi2_dev); + bmi2_error_codes_print_result(rslt); + + /* Assign accel and gyro sensor. */ + sensor_data[ACCEL].type = BMI2_ACCEL; + sensor_data[GYRO].type = BMI2_GYRO; + + /* Loop to print accel and gyro data when interrupt occurs. */ + while (indx <= limit) + { + /* To get the data ready interrupt status of accel and gyro. */ + rslt = bmi2_get_int_status(&int_status, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + /* To check the data ready interrupt status and print the status for 10 samples. */ + if ((int_status & BMI2_ACC_DRDY_INT_MASK) && (int_status & BMI2_GYR_DRDY_INT_MASK)) + { + /* Get accel and gyro data for x, y and z axis. */ + rslt = bmi270_hc_get_sensor_data(sensor_data, 2, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + printf("\n******* Accel(Raw and m/s2) Gyro(Raw and dps) data : %d *******\n", indx); + + printf("\nAcc_x = %d\t", sensor_data[ACCEL].sens_data.acc.x); + printf("Acc_y = %d\t", sensor_data[ACCEL].sens_data.acc.y); + printf("Acc_z = %d", sensor_data[ACCEL].sens_data.acc.z); + + /* Converting lsb to meter per second squared for 16 bit accelerometer at 2G range. */ + x = lsb_to_mps2(sensor_data[ACCEL].sens_data.acc.x, 2, bmi2_dev.resolution); + y = lsb_to_mps2(sensor_data[ACCEL].sens_data.acc.y, 2, bmi2_dev.resolution); + z = lsb_to_mps2(sensor_data[ACCEL].sens_data.acc.z, 2, bmi2_dev.resolution); + + /* Print the data in m/s2. */ + printf("\nAcc_ms2_X = %4.2f, Acc_ms2_Y = %4.2f, Acc_ms2_Z = %4.2f\n", x, y, z); + + printf("\nGyr_X = %d\t", sensor_data[GYRO].sens_data.gyr.x); + printf("Gyr_Y = %d\t", sensor_data[GYRO].sens_data.gyr.y); + printf("Gyr_Z = %d\n", sensor_data[GYRO].sens_data.gyr.z); + + /* Converting lsb to degree per second for 16 bit gyro at 2000dps range. */ + x = lsb_to_dps(sensor_data[GYRO].sens_data.gyr.x, 2000, bmi2_dev.resolution); + y = lsb_to_dps(sensor_data[GYRO].sens_data.gyr.y, 2000, bmi2_dev.resolution); + z = lsb_to_dps(sensor_data[GYRO].sens_data.gyr.z, 2000, bmi2_dev.resolution); + + /* Print the data in dps. */ + printf("Gyro_DPS_X = %4.2f, Gyro_DPS_Y = %4.2f, Gyro_DPS_Z = %4.2f\n", x, y, z); + + indx++; + } + } + } + } + + bmi2_coines_deinit(); + + return rslt; +} + +/*! + * @brief This internal API is used to set configurations for accel and gyro. + */ +static int8_t set_accel_gyro_config(struct bmi2_dev *bmi2_dev) +{ + /* Status of api are returned to this variable. */ + int8_t rslt; + + /* Structure to define accelerometer and gyro configuration. */ + struct bmi2_sens_config config[2]; + + /* Configure the type of feature. */ + config[ACCEL].type = BMI2_ACCEL; + config[GYRO].type = BMI2_GYRO; + + /* Get default configurations for the type of feature selected. */ + rslt = bmi270_hc_get_sensor_config(config, 2, bmi2_dev); + bmi2_error_codes_print_result(rslt); + + /* Map data ready interrupt to interrupt pin. */ + rslt = bmi2_map_data_int(BMI2_DRDY_INT, BMI2_INT1, bmi2_dev); + bmi2_error_codes_print_result(rslt); + + if (rslt == BMI2_OK) + { + /* NOTE: The user can change the following configuration parameters according to their requirement. */ + /* Set Output Data Rate */ + config[ACCEL].cfg.acc.odr = BMI2_ACC_ODR_200HZ; + + /* Gravity range of the sensor (+/- 2G, 4G, 8G, 16G). */ + config[ACCEL].cfg.acc.range = BMI2_ACC_RANGE_2G; + + /* The bandwidth parameter is used to configure the number of sensor samples that are averaged + * if it is set to 2, then 2^(bandwidth parameter) samples + * are averaged, resulting in 4 averaged samples. + * Note1 : For more information, refer the datasheet. + * Note2 : A higher number of averaged samples will result in a lower noise level of the signal, but + * this has an adverse effect on the power consumed. + */ + config[ACCEL].cfg.acc.bwp = BMI2_ACC_NORMAL_AVG4; + + /* Enable the filter performance mode where averaging of samples + * will be done based on above set bandwidth and ODR. + * There are two modes + * 0 -> Ultra low power mode + * 1 -> High performance mode(Default) + * For more info refer datasheet. + */ + config[ACCEL].cfg.acc.filter_perf = BMI2_PERF_OPT_MODE; + + /* The user can change the following configuration parameters according to their requirement. */ + /* Set Output Data Rate */ + config[GYRO].cfg.gyr.odr = BMI2_GYR_ODR_200HZ; + + /* Gyroscope Angular Rate Measurement Range.By default the range is 2000dps. */ + config[GYRO].cfg.gyr.range = BMI2_GYR_RANGE_2000; + + /* Gyroscope bandwidth parameters. By default the gyro bandwidth is in normal mode. */ + config[GYRO].cfg.gyr.bwp = BMI2_GYR_NORMAL_MODE; + + /* Enable/Disable the noise performance mode for precision yaw rate sensing + * There are two modes + * 0 -> Ultra low power mode(Default) + * 1 -> High performance mode + */ + config[GYRO].cfg.gyr.noise_perf = BMI2_POWER_OPT_MODE; + + /* Enable/Disable the filter performance mode where averaging of samples + * will be done based on above set bandwidth and ODR. + * There are two modes + * 0 -> Ultra low power mode + * 1 -> High performance mode(Default) + */ + config[GYRO].cfg.gyr.filter_perf = BMI2_PERF_OPT_MODE; + + /* Set the accel and gyro configurations. */ + rslt = bmi270_hc_set_sensor_config(config, 2, bmi2_dev); + bmi2_error_codes_print_result(rslt); + } + + return rslt; +} + +/*! + * @brief This function converts lsb to meter per second squared for 16 bit accelerometer at + * range 2G, 4G, 8G or 16G. + */ +static float lsb_to_mps2(int16_t val, float g_range, uint8_t bit_width) +{ + float half_scale = ((float)(1 << bit_width) / 2.0f); + + return (GRAVITY_EARTH * val * g_range) / half_scale; +} + +/*! + * @brief This function converts lsb to degree per second for 16 bit gyro at + * range 125, 250, 500, 1000 or 2000dps. + */ +static float lsb_to_dps(int16_t val, float dps, uint8_t bit_width) +{ + float half_scale = ((float)(1 << bit_width) / 2.0f); + + return (dps / ((half_scale) + BMI2_GYR_RANGE_2000)) * (val); +} diff --git a/examples/bmi270_hc/activity_recognition/Makefile b/examples/bmi270_hc/activity_recognition/Makefile new file mode 100644 index 0000000..ae036b4 --- /dev/null +++ b/examples/bmi270_hc/activity_recognition/Makefile @@ -0,0 +1,18 @@ +COINES_INSTALL_PATH ?= ../../../.. + +EXAMPLE_FILE ?= activity_recognition.c + +API_LOCATION ?= ../.. + +COMMON_LOCATION ?= .. + +C_SRCS += \ +$(API_LOCATION)/bmi2.c \ +$(API_LOCATION)/bmi270_hc.c \ +$(COMMON_LOCATION)/common/common.c + +INCLUDEPATHS += \ +$(API_LOCATION) \ +$(COMMON_LOCATION)/common + +include $(COINES_INSTALL_PATH)/coines.mk \ No newline at end of file diff --git a/examples/bmi270_hc/activity_recognition/activity_recognition.c b/examples/bmi270_hc/activity_recognition/activity_recognition.c new file mode 100644 index 0000000..11750ca --- /dev/null +++ b/examples/bmi270_hc/activity_recognition/activity_recognition.c @@ -0,0 +1,154 @@ +/**\ + * Copyright (c) 2020 Bosch Sensortec GmbH. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + **/ + +/******************************************************************************/ +/*! Header Files */ +#include +#include "bmi270_hc.h" +#include "common.h" + +/******************************************************************************/ +/*! Static function declaration */ + +/*! + * @brief This internal API is used to set configurations for step counter. + * + * @param[in] bmi2_dev : Structure instance of bmi2_dev. + * + * @return Status of execution. + */ +static int8_t set_config(struct bmi2_dev *bmi2_dev); + +/******************************************************************************/ +/*! Functions */ +/* This function starts the execution of program. */ +int main(void) +{ + /* Sensor initialization configuration. */ + struct bmi2_dev bmi2_dev; + + /* Status of api are returned to this variable. */ + int8_t rslt; + + /* Variable to define index for FIFO data */ + uint8_t count; + + /* Various Activity recognitions are listed in array. */ + const char *activity_reg_output[6] = { "OTHERS", "STILL", "WALKING", "RUNNING", "ON_BICYCLE", "IN_VEHICLE" }; + + /* Accel sensor and step activity feature are listed in array. */ + uint8_t sensor_sel[2] = { BMI2_ACCEL, BMI2_ACTIVITY_RECOGNITION }; + + /* Array to define FIFO data */ + uint8_t fifo_data[516] = { 0 }; + + /* Variable to store number of activity frames */ + uint16_t act_frames; + + /* Structure to define a FIFO */ + struct bmi2_fifo_frame fifoframe = { 0 }; + + /* Structure to define output for activity recognition */ + struct bmi2_act_recog_output act_recog_data[5] = { { 0 } }; + + uint16_t fifo_length; + + /* Interface reference is given as a parameter + * For I2C : BMI2_I2C_INTF + * For SPI : BMI2_SPI_INTF + */ + rslt = bmi2_interface_init(&bmi2_dev, BMI2_I2C_INTF); + bmi2_error_codes_print_result(rslt); + + /* Initialize bmi270_hc. */ + rslt = bmi270_hc_init(&bmi2_dev); + bmi2_error_codes_print_result(rslt); + + if (rslt == BMI2_OK) + { + /* Enable the selected sensor. */ + rslt = bmi270_hc_sensor_enable(sensor_sel, 2, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + if (rslt == BMI2_OK) + { + rslt = set_config(&bmi2_dev); + bmi2_error_codes_print_result(rslt); + + if (rslt == BMI2_OK) + { + /* Update FIFO structure */ + fifoframe.data = fifo_data; + fifoframe.length = 516; + + rslt = bmi2_get_fifo_length(&fifo_length, &bmi2_dev); + printf("Fifo length = %d \n", fifo_length); + + /* Read FIFO data */ + rslt = bmi2_read_fifo_data(&fifoframe, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + while (rslt != BMI2_W_FIFO_EMPTY) + { + /* Provide the number of frames to be read */ + act_frames = 5; + + printf("Requested FIFO data frames : %d\n", act_frames); + + /* Get the activity output */ + rslt = bmi270_hc_get_act_recog_output(act_recog_data, &act_frames, &fifoframe, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + printf("Parsed FIFO data frames : %d\r\n", act_frames); + + for (count = 0; count < act_frames; count++) + { + printf( + "Activity Recognition output[%d]:Sensor time: %lu\t Previous activity: %s\t current: %s\n", + count, + act_recog_data[count].time_stamp, + activity_reg_output[act_recog_data[count].prev_act], + activity_reg_output[act_recog_data[count].curr_act]); + } + } + } + } + } + + bmi2_coines_deinit(); + + return rslt; +} + +static int8_t set_config(struct bmi2_dev *bmi2_dev) +{ + /* Status of api are returned to this variable. */ + int8_t rslt; + + uint8_t temp_data[2]; + + /* Disable advanced power save */ + rslt = bmi2_set_adv_power_save(BMI2_DISABLE, bmi2_dev); + bmi2_error_codes_print_result(rslt); + + if (rslt == BMI2_OK) + { + /* Reset FIFO */ + rslt = bmi2_set_command_register(BMI2_FIFO_FLUSH_CMD, bmi2_dev); + bmi2_error_codes_print_result(rslt); + + printf("Move the board for activity recognition for 30 sec :\n"); + bmi2_dev->delay_us(30000000, bmi2_dev->intf_ptr); + + if (rslt == BMI2_OK) + { + rslt = bmi2_get_regs(BMI2_FIFO_CONFIG_0_ADDR, temp_data, 2, bmi2_dev); + bmi2_error_codes_print_result(rslt); + } + } + + return rslt; +} diff --git a/examples/bmi270_hc/common/common.c b/examples/bmi270_hc/common/common.c new file mode 100644 index 0000000..afff37b --- /dev/null +++ b/examples/bmi270_hc/common/common.c @@ -0,0 +1,372 @@ +/** + * Copyright (C) 2020 Bosch Sensortec GmbH. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include + +#include "coines.h" +#include "bmi2_defs.h" + +/******************************************************************************/ +/*! Macro definitions */ +#define BMI2XY_SHUTTLE_ID UINT16_C(0x1B8) + +/*! Macro that defines read write length */ +#define READ_WRITE_LEN UINT8_C(46) + +/******************************************************************************/ +/*! Static variable definition */ + +/*! Variable that holds the I2C device address or SPI chip selection */ +static uint8_t dev_addr; + +/******************************************************************************/ +/*! User interface functions */ + +/*! + * I2C read function map to COINES platform + */ +BMI2_INTF_RETURN_TYPE bmi2_i2c_read(uint8_t reg_addr, uint8_t *reg_data, uint32_t len, void *intf_ptr) +{ + uint8_t dev_addr = *(uint8_t*)intf_ptr; + + return coines_read_i2c(dev_addr, reg_addr, reg_data, (uint16_t)len); +} + +/*! + * I2C write function map to COINES platform + */ +BMI2_INTF_RETURN_TYPE bmi2_i2c_write(uint8_t reg_addr, const uint8_t *reg_data, uint32_t len, void *intf_ptr) +{ + uint8_t dev_addr = *(uint8_t*)intf_ptr; + + return coines_write_i2c(dev_addr, reg_addr, (uint8_t *)reg_data, (uint16_t)len); +} + +/*! + * SPI read function map to COINES platform + */ +BMI2_INTF_RETURN_TYPE bmi2_spi_read(uint8_t reg_addr, uint8_t *reg_data, uint32_t len, void *intf_ptr) +{ + uint8_t dev_addr = *(uint8_t*)intf_ptr; + + return coines_read_spi(dev_addr, reg_addr, reg_data, (uint16_t)len); +} + +/*! + * SPI write function map to COINES platform + */ +BMI2_INTF_RETURN_TYPE bmi2_spi_write(uint8_t reg_addr, const uint8_t *reg_data, uint32_t len, void *intf_ptr) +{ + uint8_t dev_addr = *(uint8_t*)intf_ptr; + + return coines_write_spi(dev_addr, reg_addr, (uint8_t *)reg_data, (uint16_t)len); +} + +/*! + * Delay function map to COINES platform + */ +void bmi2_delay_us(uint32_t period, void *intf_ptr) +{ + coines_delay_usec(period); +} + +/*! + * @brief Function to select the interface between SPI and I2C. + * Also to initialize coines platform + */ +int8_t bmi2_interface_init(struct bmi2_dev *bmi, uint8_t intf) +{ + int8_t rslt = BMI2_OK; + struct coines_board_info board_info; + + if (bmi != NULL) + { + int16_t result = coines_open_comm_intf(COINES_COMM_INTF_USB); + if (result < COINES_SUCCESS) + { + printf( + "\n Unable to connect with Application Board ! \n" " 1. Check if the board is connected and powered on. \n" " 2. Check if Application Board USB driver is installed. \n" + " 3. Check if board is in use by another application. (Insufficient permissions to access USB) \n"); + exit(result); + } + + result = coines_get_board_info(&board_info); + +#if defined(PC) + setbuf(stdout, NULL); +#endif + + if (result == COINES_SUCCESS) + { + if ((board_info.shuttle_id != BMI2XY_SHUTTLE_ID)) + { + printf("! Warning invalid sensor shuttle \n ," "This application will not support this sensor \n"); + exit(COINES_E_FAILURE); + } + } + + coines_set_shuttleboard_vdd_vddio_config(0, 0); + coines_delay_msec(100); + + /* Bus configuration : I2C */ + if (intf == BMI2_I2C_INTF) + { + printf("I2C Interface \n"); + + /* To initialize the user I2C function */ + dev_addr = BMI2_I2C_PRIM_ADDR; + bmi->intf = BMI2_I2C_INTF; + bmi->read = bmi2_i2c_read; + bmi->write = bmi2_i2c_write; + coines_config_i2c_bus(COINES_I2C_BUS_0, COINES_I2C_FAST_MODE); + } + /* Bus configuration : SPI */ + else if (intf == BMI2_SPI_INTF) + { + printf("SPI Interface \n"); + + /* To initialize the user SPI function */ + dev_addr = COINES_SHUTTLE_PIN_7; + bmi->intf = BMI2_SPI_INTF; + bmi->read = bmi2_spi_read; + bmi->write = bmi2_spi_write; + coines_config_spi_bus(COINES_SPI_BUS_0, COINES_SPI_SPEED_5_MHZ, COINES_SPI_MODE3); + coines_set_pin_config(COINES_SHUTTLE_PIN_7, COINES_PIN_DIRECTION_OUT, COINES_PIN_VALUE_HIGH); + } + + /* Assign device address to interface pointer */ + bmi->intf_ptr = &dev_addr; + + /* Configure delay in microseconds */ + bmi->delay_us = bmi2_delay_us; + + /* Configure max read/write length (in bytes) ( Supported length depends on target machine) */ + bmi->read_write_len = READ_WRITE_LEN; + + /* Assign to NULL to load the default config file. */ + bmi->config_file_ptr = NULL; + + coines_delay_usec(10000); + + coines_set_shuttleboard_vdd_vddio_config(3300, 3300); + + coines_delay_usec(10000); + } + else + { + rslt = BMI2_E_NULL_PTR; + } + + return rslt; + +} + +/*! + * @brief Prints the execution status of the APIs. + */ +void bmi2_error_codes_print_result(int8_t rslt) +{ + switch (rslt) + { + case BMI2_OK: + + /* Do nothing */ + break; + + case BMI2_W_FIFO_EMPTY: + printf("Warning [%d] : FIFO empty\r\n", rslt); + break; + case BMI2_W_PARTIAL_READ: + printf("Warning [%d] : FIFO partial read\r\n", rslt); + break; + case BMI2_E_NULL_PTR: + printf( + "Error [%d] : Null pointer error. It occurs when the user tries to assign value (not address) to a pointer," " which has been initialized to NULL.\r\n", + rslt); + break; + + case BMI2_E_COM_FAIL: + printf( + "Error [%d] : Communication failure error. It occurs due to read/write operation failure and also due " "to power failure during communication\r\n", + rslt); + break; + + case BMI2_E_DEV_NOT_FOUND: + printf("Error [%d] : Device not found error. It occurs when the device chip id is incorrectly read\r\n", + rslt); + break; + + case BMI2_E_INVALID_SENSOR: + printf( + "Error [%d] : Invalid sensor error. It occurs when there is a mismatch in the requested feature with the " "available one\r\n", + rslt); + break; + + case BMI2_E_SELF_TEST_FAIL: + printf( + "Error [%d] : Self-test failed error. It occurs when the validation of accel self-test data is " "not satisfied\r\n", + rslt); + break; + + case BMI2_E_INVALID_INT_PIN: + printf( + "Error [%d] : Invalid interrupt pin error. It occurs when the user tries to configure interrupt pins " "apart from INT1 and INT2\r\n", + rslt); + break; + + case BMI2_E_OUT_OF_RANGE: + printf( + "Error [%d] : Out of range error. It occurs when the data exceeds from filtered or unfiltered data from " "fifo and also when the range exceeds the maximum range for accel and gyro while performing FOC\r\n", + rslt); + break; + + case BMI2_E_ACC_INVALID_CFG: + printf( + "Error [%d] : Invalid Accel configuration error. It occurs when there is an error in accel configuration" " register which could be one among range, BW or filter performance in reg address 0x40\r\n", + rslt); + break; + + case BMI2_E_GYRO_INVALID_CFG: + printf( + "Error [%d] : Invalid Gyro configuration error. It occurs when there is a error in gyro configuration" "register which could be one among range, BW or filter performance in reg address 0x42\r\n", + rslt); + break; + + case BMI2_E_ACC_GYR_INVALID_CFG: + printf( + "Error [%d] : Invalid Accel-Gyro configuration error. It occurs when there is a error in accel and gyro" " configuration registers which could be one among range, BW or filter performance in reg address 0x40 " "and 0x42\r\n", + rslt); + break; + + case BMI2_E_CONFIG_LOAD: + printf( + "Error [%d] : Configuration load error. It occurs when failure observed while loading the configuration " "into the sensor\r\n", + rslt); + break; + + case BMI2_E_INVALID_PAGE: + printf( + "Error [%d] : Invalid page error. It occurs due to failure in writing the correct feature configuration " "from selected page\r\n", + rslt); + break; + + case BMI2_E_SET_APS_FAIL: + printf( + "Error [%d] : APS failure error. It occurs due to failure in write of advance power mode configuration " "register\r\n", + rslt); + break; + + case BMI2_E_AUX_INVALID_CFG: + printf( + "Error [%d] : Invalid AUX configuration error. It occurs when the auxiliary interface settings are not " "enabled properly\r\n", + rslt); + break; + + case BMI2_E_AUX_BUSY: + printf( + "Error [%d] : AUX busy error. It occurs when the auxiliary interface buses are engaged while configuring" " the AUX\r\n", + rslt); + break; + + case BMI2_E_REMAP_ERROR: + printf( + "Error [%d] : Remap error. It occurs due to failure in assigning the remap axes data for all the axes " "after change in axis position\r\n", + rslt); + break; + + case BMI2_E_GYR_USER_GAIN_UPD_FAIL: + printf( + "Error [%d] : Gyro user gain update fail error. It occurs when the reading of user gain update status " "fails\r\n", + rslt); + break; + + case BMI2_E_SELF_TEST_NOT_DONE: + printf( + "Error [%d] : Self-test not done error. It occurs when the self-test process is ongoing or not " "completed\r\n", + rslt); + break; + + case BMI2_E_INVALID_INPUT: + printf("Error [%d] : Invalid input error. It occurs when the sensor input validity fails\r\n", rslt); + break; + + case BMI2_E_INVALID_STATUS: + printf("Error [%d] : Invalid status error. It occurs when the feature/sensor validity fails\r\n", rslt); + break; + + case BMI2_E_CRT_ERROR: + printf("Error [%d] : CRT error. It occurs when the CRT test has failed\r\n", rslt); + break; + + case BMI2_E_ST_ALREADY_RUNNING: + printf( + "Error [%d] : Self-test already running error. It occurs when the self-test is already running and " "another has been initiated\r\n", + rslt); + break; + + case BMI2_E_CRT_READY_FOR_DL_FAIL_ABORT: + printf( + "Error [%d] : CRT ready for download fail abort error. It occurs when download in CRT fails due to wrong " "address location\r\n", + rslt); + break; + + case BMI2_E_DL_ERROR: + printf( + "Error [%d] : Download error. It occurs when write length exceeds that of the maximum burst length\r\n", + rslt); + break; + + case BMI2_E_PRECON_ERROR: + printf( + "Error [%d] : Pre-conditional error. It occurs when precondition to start the feature was not " "completed\r\n", + rslt); + break; + + case BMI2_E_ABORT_ERROR: + printf("Error [%d] : Abort error. It occurs when the device was shaken during CRT test\r\n", rslt); + break; + + case BMI2_E_WRITE_CYCLE_ONGOING: + printf( + "Error [%d] : Write cycle ongoing error. It occurs when the write cycle is already running and another " "has been initiated\r\n", + rslt); + break; + + case BMI2_E_ST_NOT_RUNING: + printf( + "Error [%d] : Self-test is not running error. It occurs when self-test running is disabled while it's " "running\r\n", + rslt); + break; + + case BMI2_E_DATA_RDY_INT_FAILED: + printf( + "Error [%d] : Data ready interrupt error. It occurs when the sample count exceeds the FOC sample limit " "and data ready status is not updated\r\n", + rslt); + break; + + case BMI2_E_INVALID_FOC_POSITION: + printf( + "Error [%d] : Invalid FOC position error. It occurs when average FOC data is obtained for the wrong" " axes\r\n", + rslt); + break; + + default: + printf("Error [%d] : Unknown error code\r\n", rslt); + break; + } +} + +/*! + * @brief Deinitializes coines platform + * + * @return void. + */ +void bmi2_coines_deinit(void) +{ + coines_close_comm_intf(COINES_COMM_INTF_USB); +} diff --git a/examples/bmi270_hc/common/common.h b/examples/bmi270_hc/common/common.h new file mode 100644 index 0000000..763983d --- /dev/null +++ b/examples/bmi270_hc/common/common.h @@ -0,0 +1,122 @@ +/**\ + * Copyright (c) 2020 Bosch Sensortec GmbH. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + **/ + +#ifndef _COMMON_H +#define _COMMON_H + +/*! CPP guard */ +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include "bmi2.h" + +/*! + * @brief Function for reading the sensor's registers through I2C bus. + * + * @param[in] reg_addr : Register address. + * @param[out] reg_data : Pointer to the data buffer to store the read data. + * @param[in] length : No of bytes to read. + * @param[in] intf_ptr : Interface pointer + * + * @return Status of execution + * @retval = BMI2_INTF_RET_SUCCESS -> Success + * @retval != BMI2_INTF_RET_SUCCESS -> Failure Info + * + */ +BMI2_INTF_RETURN_TYPE bmi2_i2c_read(uint8_t reg_addr, uint8_t *reg_data, uint32_t len, void *intf_ptr); + +/*! + * @brief Function for writing the sensor's registers through I2C bus. + * + * @param[in] reg_addr : Register address. + * @param[in] reg_data : Pointer to the data buffer whose value is to be written. + * @param[in] length : No of bytes to write. + * @param[in] intf_ptr : Interface pointer + * + * @return Status of execution + * @retval = BMI2_INTF_RET_SUCCESS -> Success + * @retval != BMI2_INTF_RET_SUCCESS -> Failure Info + * + */ +BMI2_INTF_RETURN_TYPE bmi2_i2c_write(uint8_t reg_addr, const uint8_t *reg_data, uint32_t len, void *intf_ptr); + +/*! + * @brief Function for reading the sensor's registers through SPI bus. + * + * @param[in] reg_addr : Register address. + * @param[out] reg_data : Pointer to the data buffer to store the read data. + * @param[in] length : No of bytes to read. + * @param[in] intf_ptr : Interface pointer + * + * @return Status of execution + * @retval = BMI2_INTF_RET_SUCCESS -> Success + * @retval != BMI2_INTF_RET_SUCCESS -> Failure Info + * + */ +BMI2_INTF_RETURN_TYPE bmi2_spi_read(uint8_t reg_addr, uint8_t *reg_data, uint32_t len, void *intf_ptr); + +/*! + * @brief Function for writing the sensor's registers through SPI bus. + * + * @param[in] reg_addr : Register address. + * @param[in] reg_data : Pointer to the data buffer whose data has to be written. + * @param[in] length : No of bytes to write. + * @param[in] intf_ptr : Interface pointer + * + * @return Status of execution + * @retval = BMI2_INTF_RET_SUCCESS -> Success + * @retval != BMI2_INTF_RET_SUCCESS -> Failure Info + * + */ +BMI2_INTF_RETURN_TYPE bmi2_spi_write(uint8_t reg_addr, const uint8_t *reg_data, uint32_t len, void *intf_ptr); + +/*! + * @brief This function provides the delay for required time (Microsecond) as per the input provided in some of the + * APIs. + * + * @param[in] period_us : The required wait time in microsecond. + * @param[in] intf_ptr : Interface pointer + * + * @return void. + * + */ +void bmi2_delay_us(uint32_t period, void *intf_ptr); + +/*! + * @brief Function to select the interface between SPI and I2C. + * + * @param[in] bma : Structure instance of bmi2_dev + * @param[in] intf : Interface selection parameter + * + * @return Status of execution + * @retval 0 -> Success + * @retval < 0 -> Failure Info + */ +int8_t bmi2_interface_init(struct bmi2_dev *bma, uint8_t intf); + +/*! + * @brief Prints the execution status of the APIs. + * + * @param[in] rslt : Error code returned by the API whose execution status has to be printed. + * + * @return void. + */ +void bmi2_error_codes_print_result(int8_t rslt); + +/*! + * @brief Deinitializes coines platform + * + * @return void. + */ +void bmi2_coines_deinit(void); + +#ifdef __cplusplus +} +#endif /* End of CPP guard */ + +#endif /* _COMMON_H */ diff --git a/examples/bmi270_hc/component_retrim/Makefile b/examples/bmi270_hc/component_retrim/Makefile new file mode 100644 index 0000000..633a817 --- /dev/null +++ b/examples/bmi270_hc/component_retrim/Makefile @@ -0,0 +1,18 @@ +COINES_INSTALL_PATH ?= ../../../.. + +EXAMPLE_FILE ?= component_retrim.c + +API_LOCATION ?= ../.. + +COMMON_LOCATION ?= .. + +C_SRCS += \ +$(API_LOCATION)/bmi2.c \ +$(API_LOCATION)/bmi270_hc.c \ +$(COMMON_LOCATION)/common/common.c + +INCLUDEPATHS += \ +$(API_LOCATION) \ +$(COMMON_LOCATION)/common + +include $(COINES_INSTALL_PATH)/coines.mk \ No newline at end of file diff --git a/examples/bmi270_hc/component_retrim/component_retrim.c b/examples/bmi270_hc/component_retrim/component_retrim.c new file mode 100644 index 0000000..6084574 --- /dev/null +++ b/examples/bmi270_hc/component_retrim/component_retrim.c @@ -0,0 +1,52 @@ +/**\ + * Copyright (c) 2020 Bosch Sensortec GmbH. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + **/ + +/******************************************************************************/ +/*! Header Files */ +#include +#include "bmi270_hc.h" +#include "common.h" + +/******************************************************************************/ +/*! Functions */ + +/* This function starts the execution of program. */ +int main(void) +{ + /* Sensor initialization configuration. */ + struct bmi2_dev bmi2_dev; + + /* Status of api are returned to this variable. */ + int8_t rslt; + + /* Interface reference is given as a parameter + * For I2C : BMI2_I2C_INTF + * For SPI : BMI2_SPI_INTF + */ + rslt = bmi2_interface_init(&bmi2_dev, BMI2_I2C_INTF); + bmi2_error_codes_print_result(rslt); + + /* Initialize bmi270_hc. */ + rslt = bmi270_hc_init(&bmi2_dev); + bmi2_error_codes_print_result(rslt); + + if (rslt == BMI2_OK) + { + /* This API runs the CRT process. */ + rslt = bmi2_do_crt(&bmi2_dev); + bmi2_error_codes_print_result(rslt); + + /* Do not move the board while doing CRT. If so, it will throw an abort error. */ + if (rslt == BMI2_OK) + { + printf("CRT successfully completed."); + } + } + + bmi2_coines_deinit(); + + return rslt; +} diff --git a/examples/bmi270_hc/fifo_full_header_mode/Makefile b/examples/bmi270_hc/fifo_full_header_mode/Makefile new file mode 100644 index 0000000..00794a3 --- /dev/null +++ b/examples/bmi270_hc/fifo_full_header_mode/Makefile @@ -0,0 +1,18 @@ +COINES_INSTALL_PATH ?= ../../../.. + +EXAMPLE_FILE ?= fifo_full_header_mode.c + +API_LOCATION ?= ../.. + +COMMON_LOCATION ?= .. + +C_SRCS += \ +$(API_LOCATION)/bmi2.c \ +$(API_LOCATION)/bmi270_hc.c \ +$(COMMON_LOCATION)/common/common.c + +INCLUDEPATHS += \ +$(API_LOCATION) \ +$(COMMON_LOCATION)/common + +include $(COINES_INSTALL_PATH)/coines.mk \ No newline at end of file diff --git a/examples/bmi270_hc/fifo_full_header_mode/fifo_full_header_mode.c b/examples/bmi270_hc/fifo_full_header_mode/fifo_full_header_mode.c new file mode 100644 index 0000000..6f11642 --- /dev/null +++ b/examples/bmi270_hc/fifo_full_header_mode/fifo_full_header_mode.c @@ -0,0 +1,316 @@ +/**\ + * Copyright (c) 2020 Bosch Sensortec GmbH. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + **/ + +/******************************************************************************/ +/*! Header Files */ +#include +#include "bmi270_hc.h" +#include "common.h" + +/******************************************************************************/ +/*! Macros */ + +/*! Buffer size allocated to store raw FIFO data. */ +#define BMI2_FIFO_RAW_DATA_BUFFER_SIZE UINT16_C(2048) + +/*! Length of data to be read from FIFO. */ +#define BMI2_FIFO_RAW_DATA_USER_LENGTH UINT16_C(2048) + +/*! Number of accel frames to be extracted from FIFO. */ + +/*! Calculation for frame count: Total frame count = Fifo buffer size(2048)/ Total frames(6 Accel, 6 Gyro and 1 header, + * totaling to 13) which equals to 157. + */ +#define BMI2_FIFO_ACCEL_FRAME_COUNT UINT8_C(157) + +/*! Number of gyro frames to be extracted from FIFO. */ +#define BMI2_FIFO_GYRO_FRAME_COUNT UINT8_C(157) + +/*! Macro to read sensortime byte in FIFO. */ +#define SENSORTIME_OVERHEAD_BYTE UINT8_C(3) + +/******************************************************************************/ +/*! Static Function Declaration */ + +/*! + * @brief This internal API is used to set configurations for accel and gyro. + * @param[in] dev : Structure instance of bmi2_dev. + * @return Status of execution. + */ +static int8_t set_accel_gyro_config(struct bmi2_dev *dev); + +/******************************************************************************/ + +/* This function starts the execution of program. */ +int main(void) +{ + /* Status of api are returned to this variable. */ + int8_t rslt; + + uint16_t index = 0; + uint16_t fifo_length = 0; + uint16_t config = 0; + + /* To read sensortime, extra 3 bytes are added to fifo buffer. */ + uint16_t fifo_buffer_size = BMI2_FIFO_RAW_DATA_BUFFER_SIZE + SENSORTIME_OVERHEAD_BYTE; + + /* Variable to get fifo full interrupt status. */ + uint16_t int_status = 0; + + uint16_t accel_frame_length = BMI2_FIFO_ACCEL_FRAME_COUNT; + + uint16_t gyro_frame_length = BMI2_FIFO_GYRO_FRAME_COUNT; + + /* Variable to store the available frame length count in FIFO */ + uint8_t frame_count; + + int8_t try = 1; + + /* Number of bytes of FIFO data. */ + uint8_t fifo_data[fifo_buffer_size]; + + /* Sensor initialization configuration. */ + struct bmi2_dev bmi2_dev; + + /* Array of accelerometer frames -> Total bytes = + * 157 * (6 axes + 1 header bytes) = 1099 bytes */ + struct bmi2_sens_axes_data fifo_accel_data[BMI2_FIFO_ACCEL_FRAME_COUNT] = { { 0 } }; + + /* Array of gyro frames -> Total bytes = + * 157 * (6 axes + 1 header bytes) = 1099 bytes */ + struct bmi2_sens_axes_data fifo_gyro_data[BMI2_FIFO_GYRO_FRAME_COUNT] = { { 0 } }; + + /* Initialize FIFO frame structure. */ + struct bmi2_fifo_frame fifoframe = { 0 }; + + /* Accel and gyro sensor are listed in array. */ + uint8_t sensor_sel[2] = { BMI2_ACCEL, BMI2_GYRO }; + + /* Interface reference is given as a parameter + * For I2C : BMI2_I2C_INTF + * For SPI : BMI2_SPI_INTF + */ + rslt = bmi2_interface_init(&bmi2_dev, BMI2_I2C_INTF); + bmi2_error_codes_print_result(rslt); + + /* Initialize bmi270_hc. */ + rslt = bmi270_hc_init(&bmi2_dev); + bmi2_error_codes_print_result(rslt); + + /* Enable accel and gyro sensor. */ + rslt = bmi270_hc_sensor_enable(sensor_sel, 2, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + /* Configuration settings for accel and gyro. */ + rslt = set_accel_gyro_config(&bmi2_dev); + bmi2_error_codes_print_result(rslt); + + /* Before setting FIFO, disable the advance power save mode. */ + rslt = bmi2_set_adv_power_save(BMI2_DISABLE, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + /* Initially disable all configurations in fifo. */ + rslt = bmi2_get_fifo_config(&config, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + /* Initially disable all configurations in fifo. */ + rslt = bmi2_set_fifo_config(BMI2_FIFO_ALL_EN, BMI2_DISABLE, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + /* Update FIFO structure. */ + /* Mapping the buffer to store the fifo data. */ + fifoframe.data = fifo_data; + + /* Length of FIFO frame. */ + /* To read sensortime, extra 3 bytes are added to fifo user length. */ + fifoframe.length = BMI2_FIFO_RAW_DATA_USER_LENGTH + SENSORTIME_OVERHEAD_BYTE; + + /* Set FIFO configuration by enabling accel, gyro and timestamp. + * NOTE 1: The header mode is enabled by default. + * NOTE 2: By default the FIFO operating mode is in FIFO mode. + * NOTE 3: Sensortime is enabled by default */ + printf("FIFO is configured in header mode\n"); + rslt = bmi2_set_fifo_config(BMI2_FIFO_ACC_EN | BMI2_FIFO_GYR_EN, BMI2_ENABLE, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + /* Map FIFO full interrupt. */ + fifoframe.data_int_map = BMI2_FFULL_INT; + rslt = bmi2_map_data_int(fifoframe.data_int_map, BMI2_INT1, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + while (try <= 10) + { + /* Read FIFO data on interrupt. */ + rslt = bmi2_get_int_status(&int_status, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + if ((rslt == BMI2_OK) && (int_status & BMI2_FFULL_INT_STATUS_MASK)) + { + printf("\nIteration : %d\n", try); + + accel_frame_length = BMI2_FIFO_ACCEL_FRAME_COUNT; + + gyro_frame_length = BMI2_FIFO_GYRO_FRAME_COUNT; + + rslt = bmi2_get_fifo_length(&fifo_length, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + printf("\nFIFO data bytes available : %d \n", fifo_length); + printf("\nFIFO data bytes requested : %d \n", fifoframe.length); + + /* Read FIFO data. */ + rslt = bmi2_read_fifo_data(&fifoframe, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + /* Read FIFO data on interrupt. */ + rslt = bmi2_get_int_status(&int_status, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + if (rslt == BMI2_OK) + { + printf("\nFIFO accel frames requested : %d \n", accel_frame_length); + + /* Parse the FIFO data to extract accelerometer data from the FIFO buffer. */ + rslt = bmi2_extract_accel(fifo_accel_data, &accel_frame_length, &fifoframe, &bmi2_dev); + printf("\nFIFO accel frames extracted : %d \n", accel_frame_length); + + printf("\nFIFO gyro frames requested : %d \n", gyro_frame_length); + + /* Parse the FIFO data to extract gyro data from the FIFO buffer. */ + rslt = bmi2_extract_gyro(fifo_gyro_data, &gyro_frame_length, &fifoframe, &bmi2_dev); + printf("\nFIFO gyro frames extracted : %d \n", gyro_frame_length); + + /* Calculating the frame count from the available bytes in FIFO + * frame_length = (available_fifo_bytes / (acc_frame_len + gyro_frame_len + header_byte)) */ + frame_count = (fifo_length / (BMI2_FIFO_ACC_GYR_LENGTH + 1)); + printf("\nAvailable frame count from available bytes: %d\n", frame_count); + + printf("\nExtracted accel frames\n"); + + if (accel_frame_length > frame_count) + { + accel_frame_length = frame_count; + } + + /* Print the parsed accelerometer data from the FIFO buffer. */ + for (index = 0; index < accel_frame_length; index++) + { + printf("ACCEL[%d] X : %d\t Y : %d\t Z : %d\n", index, fifo_accel_data[index].x, + fifo_accel_data[index].y, fifo_accel_data[index].z); + } + + printf("\nExtracted gyro frames\n"); + + if (gyro_frame_length > frame_count) + { + gyro_frame_length = frame_count; + } + + /* Print the parsed gyro data from the FIFO buffer. */ + for (index = 0; index < gyro_frame_length; index++) + { + printf("GYRO[%d] X : %d\t Y : %d\t Z : %d\n", + index, + fifo_gyro_data[index].x, + fifo_gyro_data[index].y, + fifo_gyro_data[index].z); + } + + /* Print control frames like sensor time and skipped frame count. */ + printf("\nSkipped frame count = %d\n", fifoframe.skipped_frame_count); + + printf("Sensor time = %lu\r\n", fifoframe.sensor_time); + + try++; + } + } + } + + bmi2_coines_deinit(); + + return rslt; +} + +/*! + * @brief This internal API is used to set configurations for accel and gyro. + */ +static int8_t set_accel_gyro_config(struct bmi2_dev *bmi2_dev) +{ + /* Status of api are returned to this variable. */ + int8_t rslt; + + /* Structure to define accel and gyro configurations. */ + struct bmi2_sens_config config[2]; + + /* Configure the type of feature. */ + config[0].type = BMI2_ACCEL; + config[1].type = BMI2_GYRO; + + /* Get default configurations for the type of feature selected. */ + rslt = bmi270_hc_get_sensor_config(config, 2, bmi2_dev); + bmi2_error_codes_print_result(rslt); + + if (rslt == BMI2_OK) + { + + /* NOTE: The user can change the following configuration parameters according to their requirement. */ + /* Accel configuration settings. */ + /* Set Output Data Rate */ + config[0].cfg.acc.odr = BMI2_ACC_ODR_25HZ; + + /* Gravity range of the sensor (+/- 2G, 4G, 8G, 16G). */ + config[0].cfg.acc.range = BMI2_ACC_RANGE_2G; + + /* The bandwidth parameter is used to configure the number of sensor samples that are averaged + * if it is set to 2, then 2^(bandwidth parameter) samples + * are averaged, resulting in 4 averaged samples + * Note1 : For more information, refer the datasheet. + * Note2 : A higher number of averaged samples will result in a lower noise level of the signal, but + * this has an adverse effect on the power consumed. + */ + config[0].cfg.acc.bwp = BMI2_ACC_NORMAL_AVG4; + + /* Enable the filter performance mode where averaging of samples + * will be done based on above set bandwidth and ODR. + * There are two modes + * 0 -> Ultra low power mode + * 1 -> High performance mode(Default) + * For more info refer datasheet. + */ + config[0].cfg.acc.filter_perf = BMI2_PERF_OPT_MODE; + + /* Gyro configuration settings. */ + /* Set Output Data Rate */ + config[1].cfg.gyr.odr = BMI2_GYR_ODR_25HZ; + + /* Gyroscope Angular Rate Measurement Range.By default the range is 2000dps. */ + config[1].cfg.gyr.range = BMI2_GYR_RANGE_2000; + + /* Gyroscope Bandwidth parameters. By default the gyro bandwidth is in normal mode. */ + config[1].cfg.gyr.bwp = BMI2_GYR_NORMAL_MODE; + + /* Enable/Disable the noise performance mode for precision yaw rate sensing + * There are two modes + * 0 -> Ultra low power mode(Default) + * 1 -> High performance mode + */ + config[1].cfg.gyr.noise_perf = BMI2_POWER_OPT_MODE; + + /* Enable/Disable the filter performance mode where averaging of samples + * will be done based on above set bandwidth and ODR. + * There are two modes + * 0 -> Ultra low power mode + * 1 -> High performance mode(Default) + */ + config[1].cfg.gyr.filter_perf = BMI2_PERF_OPT_MODE; + + /* Set new configurations. */ + rslt = bmi270_hc_set_sensor_config(config, 2, bmi2_dev); + bmi2_error_codes_print_result(rslt); + } + + return rslt; +} diff --git a/examples/bmi270_hc/fifo_full_headerless_mode/Makefile b/examples/bmi270_hc/fifo_full_headerless_mode/Makefile new file mode 100644 index 0000000..5eefc71 --- /dev/null +++ b/examples/bmi270_hc/fifo_full_headerless_mode/Makefile @@ -0,0 +1,18 @@ +COINES_INSTALL_PATH ?= ../../../.. + +EXAMPLE_FILE ?= fifo_full_headerless_mode.c + +API_LOCATION ?= ../.. + +COMMON_LOCATION ?= .. + +C_SRCS += \ +$(API_LOCATION)/bmi2.c \ +$(API_LOCATION)/bmi270_hc.c \ +$(COMMON_LOCATION)/common/common.c + +INCLUDEPATHS += \ +$(API_LOCATION) \ +$(COMMON_LOCATION)/common + +include $(COINES_INSTALL_PATH)/coines.mk \ No newline at end of file diff --git a/examples/bmi270_hc/fifo_full_headerless_mode/fifo_full_headerless_mode.c b/examples/bmi270_hc/fifo_full_headerless_mode/fifo_full_headerless_mode.c new file mode 100644 index 0000000..1bce488 --- /dev/null +++ b/examples/bmi270_hc/fifo_full_headerless_mode/fifo_full_headerless_mode.c @@ -0,0 +1,304 @@ +/**\ + * Copyright (c) 2020 Bosch Sensortec GmbH. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + **/ + +/******************************************************************************/ +/*! Header Files */ +#include +#include "bmi270_hc.h" +#include "common.h" + +/******************************************************************************/ +/*! Macros */ + +/*! Buffer size allocated to store raw FIFO data */ +#define BMI2_FIFO_RAW_DATA_BUFFER_SIZE UINT16_C(2048) + +/*! Length of data to be read from FIFO */ +#define BMI2_FIFO_RAW_DATA_USER_LENGTH UINT16_C(2048) + +/*! Number of accel frames to be extracted from FIFO */ + +/*! Calculation for frame count: Total frame count = Fifo buffer size(2048)/ Total frames(6 Accel, 6 Gyro totaling to + * 12) which equals to 170. + */ +#define BMI2_FIFO_ACCEL_FRAME_COUNT UINT8_C(169) + +/*! Number of gyro frames to be extracted from FIFO */ +#define BMI2_FIFO_GYRO_FRAME_COUNT UINT8_C(169) + +/******************************************************************************/ +/*! Static Function Declaration */ + +/*! + * @brief This internal API is used to set configurations for accel and gyro. + * @param[in] dev : Structure instance of bmi2_dev. + * @return Status of execution. + */ +static int8_t set_accel_gyro_config(struct bmi2_dev *dev); + +/******************************************************************************/ + +/* This function starts the execution of program. */ +int main(void) +{ + /* Status of api are returned to this variable. */ + int8_t rslt; + + uint16_t index = 0; + + uint16_t fifo_length = 0; + + uint8_t try = 1; + + /* Variable to get fifo full interrupt status. */ + uint16_t int_status = 0; + + uint16_t accel_frame_length; + + uint16_t gyro_frame_length; + + /* Variable to store the available frame length count in FIFO */ + uint8_t frame_count; + + /* Number of bytes of FIFO data. */ + uint8_t fifo_data[BMI2_FIFO_RAW_DATA_BUFFER_SIZE] = { 0 }; + + /* Sensor initialization configuration. */ + struct bmi2_dev bmi2_dev; + + /* Array of accelerometer frames -> Total bytes = + * 170 * (6 axes bytes) = 1020 bytes */ + struct bmi2_sens_axes_data fifo_accel_data[BMI2_FIFO_ACCEL_FRAME_COUNT] = { { 0 } }; + + /* Array of gyro frames -> Total bytes = + * 170 * (6 axes bytes) = 1020 bytes */ + struct bmi2_sens_axes_data fifo_gyro_data[BMI2_FIFO_GYRO_FRAME_COUNT] = { { 0 } }; + + /* Initialize FIFO frame structure. */ + struct bmi2_fifo_frame fifoframe = { 0 }; + + /* Accel and gyro sensor are listed in array. */ + uint8_t sensor_sel[2] = { BMI2_ACCEL, BMI2_GYRO }; + + /* Interface reference is given as a parameter + * For I2C : BMI2_I2C_INTF + * For SPI : BMI2_SPI_INTF + */ + rslt = bmi2_interface_init(&bmi2_dev, BMI2_I2C_INTF); + bmi2_error_codes_print_result(rslt); + + /* Initialize bmi270_hc. */ + rslt = bmi270_hc_init(&bmi2_dev); + bmi2_error_codes_print_result(rslt); + + /* Enable accel and gyro sensor. */ + rslt = bmi270_hc_sensor_enable(sensor_sel, 2, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + /* Configuration settings for accel and gyro. */ + rslt = set_accel_gyro_config(&bmi2_dev); + bmi2_error_codes_print_result(rslt); + + /* Before setting FIFO, disable the advance power save mode. */ + rslt = bmi2_set_adv_power_save(BMI2_DISABLE, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + /* Initially disable all configurations in fifo. */ + rslt = bmi2_set_fifo_config(BMI2_FIFO_ALL_EN, BMI2_DISABLE, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + /* Update FIFO structure. */ + /* Mapping the buffer to store the fifo data. */ + fifoframe.data = fifo_data; + + /* Length of FIFO frame. */ + fifoframe.length = BMI2_FIFO_RAW_DATA_USER_LENGTH; + + /* Set FIFO configuration by enabling accel, gyro. + * NOTE 1: The header mode is enabled by default. + * NOTE 2: By default the FIFO operating mode is FIFO mode. */ + rslt = bmi2_set_fifo_config(BMI2_FIFO_ACC_EN | BMI2_FIFO_GYR_EN, BMI2_ENABLE, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + printf("FIFO is configured in headerless mode\n"); + + /* To enable headerless mode, disable the header. */ + if (rslt == BMI2_OK) + { + rslt = bmi2_set_fifo_config(BMI2_FIFO_HEADER_EN, BMI2_DISABLE, &bmi2_dev); + } + + /* Map FIFO full interrupt. */ + fifoframe.data_int_map = BMI2_FFULL_INT; + rslt = bmi2_map_data_int(fifoframe.data_int_map, BMI2_INT1, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + while (try <= 10) + { + /* Read FIFO data on interrupt. */ + rslt = bmi2_get_int_status(&int_status, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + if ((rslt == BMI2_OK) && (int_status & BMI2_FFULL_INT_STATUS_MASK)) + { + printf("\nIteration : %d\n", try); + + rslt = bmi2_get_fifo_length(&fifo_length, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + accel_frame_length = BMI2_FIFO_ACCEL_FRAME_COUNT; + gyro_frame_length = BMI2_FIFO_GYRO_FRAME_COUNT; + + printf("\nFIFO data bytes available : %d \n", fifo_length); + printf("\nFIFO data bytes requested : %d \n", fifoframe.length); + + /* Read FIFO data. */ + rslt = bmi2_read_fifo_data(&fifoframe, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + /* Read FIFO data on interrupt. */ + rslt = bmi2_get_int_status(&int_status, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + if (rslt == BMI2_OK) + { + printf("\nFIFO accel frames requested : %d \n", accel_frame_length); + + /* Parse the FIFO data to extract accelerometer data from the FIFO buffer. */ + rslt = bmi2_extract_accel(fifo_accel_data, &accel_frame_length, &fifoframe, &bmi2_dev); + printf("\nFIFO accel frames extracted : %d \n", accel_frame_length); + + printf("\nFIFO gyro frames requested : %d \n", gyro_frame_length); + + /* Parse the FIFO data to extract gyro data from the FIFO buffer. */ + rslt = bmi2_extract_gyro(fifo_gyro_data, &gyro_frame_length, &fifoframe, &bmi2_dev); + printf("\nFIFO gyro frames extracted : %d \n", gyro_frame_length); + + /* Calculating the frame count from the available bytes in FIFO + * frame_length = (available_fifo_bytes / (acc_frame_len + gyro_frame_len)) */ + frame_count = (fifo_length / (BMI2_FIFO_ACC_GYR_LENGTH)); + printf("\nAvailable frame count from available bytes: %d\n", frame_count); + + printf("\nExtracted accel frames\n"); + + if (accel_frame_length > frame_count) + { + accel_frame_length = frame_count; + } + + /* Print the parsed accelerometer data from the FIFO buffer. */ + for (index = 0; index < accel_frame_length; index++) + { + printf("ACCEL[%d] X : %d\t Y : %d\t Z : %d\n", index, fifo_accel_data[index].x, + fifo_accel_data[index].y, fifo_accel_data[index].z); + } + + printf("\nExtracted gyro frames\n"); + + if (gyro_frame_length > frame_count) + { + gyro_frame_length = frame_count; + } + + /* Print the parsed gyro data from the FIFO buffer. */ + for (index = 0; index < gyro_frame_length; index++) + { + printf("GYRO[%d] X : %d\t Y : %d\t Z : %d\n", + index, + fifo_gyro_data[index].x, + fifo_gyro_data[index].y, + fifo_gyro_data[index].z); + } + } + + try++; + } + } + + bmi2_coines_deinit(); + + return rslt; +} + +/*! + * @brief This internal API is used to set configurations for accel and gyro. + */ +static int8_t set_accel_gyro_config(struct bmi2_dev *bmi2_dev) +{ + /* Status of api are returned to this variable. */ + int8_t rslt; + + /* Structure to define accel and gyro configurations. */ + struct bmi2_sens_config config[2]; + + /* Configure the type of feature. */ + config[0].type = BMI2_ACCEL; + config[1].type = BMI2_GYRO; + + /* Get default configurations for the type of feature selected. */ + rslt = bmi270_hc_get_sensor_config(config, 2, bmi2_dev); + bmi2_error_codes_print_result(rslt); + + if (rslt == BMI2_OK) + { + /* NOTE: The user can change the following configuration parameters according to their requirement. */ + /* Accel configuration settings. */ + /* Set Output Data Rate */ + config[0].cfg.acc.odr = BMI2_ACC_ODR_100HZ; + + /* Gravity range of the sensor (+/- 2G, 4G, 8G, 16G). */ + config[0].cfg.acc.range = BMI2_ACC_RANGE_2G; + + /* The bandwidth parameter is used to configure the number of sensor samples that are averaged + * if it is set to 2, then 2^(bandwidth parameter) samples + * are averaged, resulting in 4 averaged samples + * Note1 : For more information, refer the datasheet. + * Note2 : A higher number of averaged samples will result in a lower noise level of the signal, but + * this has an adverse effect on the power consumed. + */ + config[0].cfg.acc.bwp = BMI2_ACC_NORMAL_AVG4; + + /* Enable the filter performance mode where averaging of samples + * will be done based on above set bandwidth and ODR. + * There are two modes + * 0 -> Ultra low power mode + * 1 -> High performance mode(Default) + * For more info refer datasheet. + */ + config[0].cfg.acc.filter_perf = BMI2_PERF_OPT_MODE; + + /* Gyro configuration settings. */ + /* Set Output Data Rate */ + config[1].cfg.gyr.odr = BMI2_GYR_ODR_100HZ; + + /* Gyroscope Angular Rate Measurement Range.By default the range is 2000dps. */ + config[1].cfg.gyr.range = BMI2_GYR_RANGE_2000; + + /* Gyroscope Bandwidth parameters. By default the gyro bandwidth is in normal mode. */ + config[1].cfg.gyr.bwp = BMI2_GYR_NORMAL_MODE; + + /* Enable/Disable the noise performance mode for precision yaw rate sensing + * There are two modes + * 0 -> Ultra low power mode(Default) + * 1 -> High performance mode + */ + config[1].cfg.gyr.noise_perf = BMI2_POWER_OPT_MODE; + + /* Enable/Disable the filter performance mode where averaging of samples + * will be done based on above set bandwidth and ODR. + * There are two modes + * 0 -> Ultra low power mode + * 1 -> High performance mode(Default) + */ + config[1].cfg.gyr.filter_perf = BMI2_PERF_OPT_MODE; + + /* Set new configurations. */ + rslt = bmi270_hc_set_sensor_config(config, 2, bmi2_dev); + bmi2_error_codes_print_result(rslt); + } + + return rslt; +} diff --git a/examples/bmi270_hc/fifo_watermark_header_mode/Makefile b/examples/bmi270_hc/fifo_watermark_header_mode/Makefile new file mode 100644 index 0000000..8dea084 --- /dev/null +++ b/examples/bmi270_hc/fifo_watermark_header_mode/Makefile @@ -0,0 +1,18 @@ +COINES_INSTALL_PATH ?= ../../../.. + +EXAMPLE_FILE ?= fifo_watermark_header_mode.c + +API_LOCATION ?= ../.. + +COMMON_LOCATION ?= .. + +C_SRCS += \ +$(API_LOCATION)/bmi2.c \ +$(API_LOCATION)/bmi270_hc.c \ +$(COMMON_LOCATION)/common/common.c + +INCLUDEPATHS += \ +$(API_LOCATION) \ +$(COMMON_LOCATION)/common + +include $(COINES_INSTALL_PATH)/coines.mk \ No newline at end of file diff --git a/examples/bmi270_hc/fifo_watermark_header_mode/fifo_watermark_header_mode.c b/examples/bmi270_hc/fifo_watermark_header_mode/fifo_watermark_header_mode.c new file mode 100644 index 0000000..46599f2 --- /dev/null +++ b/examples/bmi270_hc/fifo_watermark_header_mode/fifo_watermark_header_mode.c @@ -0,0 +1,335 @@ +/**\ + * Copyright (c) 2020 Bosch Sensortec GmbH. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + **/ + +/******************************************************************************/ +/*! Header Files */ +#include +#include "bmi270_hc.h" +#include "common.h" + +/******************************************************************************/ +/*! Macros */ + +/*! Buffer size allocated to store raw FIFO data */ +#define BMI2_FIFO_RAW_DATA_BUFFER_SIZE UINT16_C(2048) + +/*! Length of data to be read from FIFO */ +#define BMI2_FIFO_RAW_DATA_USER_LENGTH UINT16_C(2048) + +/*! Number of accel frames to be extracted from FIFO */ + +/*! + * Calculation: + * fifo_watermark_level = 650, accel_frame_len = 6, gyro_frame_len = 6 header_byte = 1. + * fifo_accel_frame_count = (650 / (6 + 6 + 1 )) = 50 frames + * NOTE: Extra frames are read in order to get sensor time + */ +#define BMI2_FIFO_ACCEL_FRAME_COUNT UINT8_C(55) + +/*! Number of gyro frames to be extracted from FIFO */ +#define BMI2_FIFO_GYRO_FRAME_COUNT UINT8_C(55) + +/*! Setting a watermark level in FIFO */ +#define BMI270_FIFO_WATERMARK_LEVEL UINT16_C(650) + +/*! Macro to read sensortime byte in FIFO */ +#define SENSORTIME_OVERHEAD_BYTE UINT8_C(3) + +/******************************************************************************/ +/*! Static Function Declaration */ + +/*! + * @brief This internal API is used to set configurations for accel and gyro. + * @param[in] dev : Structure instance of bmi2_dev. + * @return Status of execution. + */ +static int8_t set_accel_gyro_config(struct bmi2_dev *dev); + +/******************************************************************************/ +/*! Functions */ + +/* This function starts the execution of program. */ +int main(void) +{ + /* Status of api are returned to this variable. */ + int8_t rslt; + + /* Variable to store the available frame length count in FIFO */ + uint8_t frame_count; + + /* Variable to index bytes. */ + uint16_t index = 0; + + uint16_t fifo_length = 0; + + uint16_t accel_frame_length; + + uint16_t gyro_frame_length; + + uint8_t try = 1; + + /* To read sensortime, extra 3 bytes are added to fifo buffer */ + uint16_t fifo_buffer_size = BMI2_FIFO_RAW_DATA_BUFFER_SIZE + SENSORTIME_OVERHEAD_BYTE; + + /* Number of bytes of FIFO data. */ + uint8_t fifo_data[fifo_buffer_size]; + + /* Sensor initialization configuration. */ + struct bmi2_dev bmi2_dev; + + /* Array of accelerometer frames -> Total bytes = + * 55 * (6 axes bytes) = 330 bytes */ + struct bmi2_sens_axes_data fifo_accel_data[BMI2_FIFO_ACCEL_FRAME_COUNT] = { { 0 } }; + + /* Array of gyro frames -> Total bytes = + * 55 * (6 axes bytes) = 330 bytes */ + struct bmi2_sens_axes_data fifo_gyro_data[BMI2_FIFO_GYRO_FRAME_COUNT] = { { 0 } }; + + /* Initialize FIFO frame structure. */ + struct bmi2_fifo_frame fifoframe = { 0 }; + + /* Accel and gyro sensor are listed in array. */ + uint8_t sensor_sel[2] = { BMI2_ACCEL, BMI2_GYRO }; + + /* Variable to get fifo water-mark interrupt status. */ + uint16_t int_status = 0; + + uint16_t watermark = 0; + + /* Interface reference is given as a parameter + * For I2C : BMI2_I2C_INTF + * For SPI : BMI2_SPI_INTF + */ + rslt = bmi2_interface_init(&bmi2_dev, BMI2_I2C_INTF); + bmi2_error_codes_print_result(rslt); + + /* Initialize bmi270_hc. */ + rslt = bmi270_hc_init(&bmi2_dev); + bmi2_error_codes_print_result(rslt); + + /* Enable accel and gyro sensor. */ + rslt = bmi270_hc_sensor_enable(sensor_sel, 2, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + /* Configuration settings for accel and gyro. */ + rslt = set_accel_gyro_config(&bmi2_dev); + bmi2_error_codes_print_result(rslt); + + /* Before setting FIFO, disable the advance power save mode. */ + rslt = bmi2_set_adv_power_save(BMI2_DISABLE, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + /* Initially disable all configurations in fifo. */ + rslt = bmi2_set_fifo_config(BMI2_FIFO_ALL_EN, BMI2_DISABLE, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + /* Update FIFO structure. */ + /* Mapping the buffer to store the fifo data. */ + fifoframe.data = fifo_data; + + /* Length of FIFO frame. */ + /* To read sensortime, extra 3 bytes are added to fifo user length. */ + fifoframe.length = BMI2_FIFO_RAW_DATA_USER_LENGTH + SENSORTIME_OVERHEAD_BYTE; + + /* Set FIFO configuration by enabling accel, gyro and timestamp. + * NOTE 1: The header mode is enabled by default. + * NOTE 2: By default the FIFO operating mode is FIFO mode. + * NOTE 3: Sensortime is enabled by default */ + printf("FIFO is configured in header mode\n"); + rslt = bmi2_set_fifo_config(BMI2_FIFO_ACC_EN | BMI2_FIFO_GYR_EN, BMI2_ENABLE, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + /* FIFO water-mark interrupt is enabled. */ + fifoframe.data_int_map = BMI2_FWM_INT; + + /* Map water-mark interrupt to the required interrupt pin. */ + rslt = bmi2_map_data_int(fifoframe.data_int_map, BMI2_INT1, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + /* Set water-mark level. */ + fifoframe.wm_lvl = BMI270_FIFO_WATERMARK_LEVEL; + + /* Set the water-mark level if water-mark interrupt is mapped. */ + rslt = bmi2_set_fifo_wm(fifoframe.wm_lvl, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + rslt = bmi2_get_fifo_wm(&watermark, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + printf("\nFIFO watermark level is %d\n", watermark); + + while (try <= 10) + { + /* Read FIFO data on interrupt. */ + rslt = bmi2_get_int_status(&int_status, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + /* To check the status of FIFO watermark interrupt. */ + if ((rslt == BMI2_OK) && (int_status & BMI2_FWM_INT_STATUS_MASK)) + { + printf("\nIteration : %d\n", try); + + printf("\nWatermark interrupt occurred\n"); + + rslt = bmi2_get_fifo_length(&fifo_length, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + accel_frame_length = BMI2_FIFO_ACCEL_FRAME_COUNT; + gyro_frame_length = BMI2_FIFO_GYRO_FRAME_COUNT; + + printf("\nFIFO data bytes available : %d \n", fifo_length); + printf("\nFIFO data bytes requested : %d \n", fifoframe.length); + + /* Read FIFO data. */ + rslt = bmi2_read_fifo_data(&fifoframe, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + /* Read FIFO data on interrupt. */ + rslt = bmi2_get_int_status(&int_status, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + if (rslt == BMI2_OK) + { + printf("\nFIFO accel frames requested : %d \n", accel_frame_length); + + /* Parse the FIFO data to extract accelerometer data from the FIFO buffer. */ + rslt = bmi2_extract_accel(fifo_accel_data, &accel_frame_length, &fifoframe, &bmi2_dev); + printf("\nFIFO accel frames extracted : %d \n", accel_frame_length); + + printf("\nFIFO gyro frames requested : %d \n", gyro_frame_length); + + /* Parse the FIFO data to extract gyro data from the FIFO buffer. */ + rslt = bmi2_extract_gyro(fifo_gyro_data, &gyro_frame_length, &fifoframe, &bmi2_dev); + printf("\nFIFO gyro frames extracted : %d \n", gyro_frame_length); + + /* Calculating the frame count from the available bytes in FIFO + * frame_length = (available_fifo_bytes / (acc_frame_len + gyro_frame_len + header_byte)) */ + frame_count = (fifo_length / (BMI2_FIFO_ACC_GYR_LENGTH + 1)); + printf("\nAvailable frame count from available bytes: %d\n", frame_count); + + printf("\nExracted accel frames\n"); + + if (accel_frame_length > frame_count) + { + accel_frame_length = frame_count; + } + + /* Print the parsed accelerometer data from the FIFO buffer. */ + for (index = 0; index < accel_frame_length; index++) + { + printf("ACCEL[%d] X : %d\t Y : %d\t Z : %d\n", index, fifo_accel_data[index].x, + fifo_accel_data[index].y, fifo_accel_data[index].z); + } + + printf("\nExtracted gyro frames\n"); + + if (gyro_frame_length > frame_count) + { + gyro_frame_length = frame_count; + } + + /* Print the parsed gyro data from the FIFO buffer. */ + for (index = 0; index < gyro_frame_length; index++) + { + printf("GYRO[%d] X : %d\t Y : %d\t Z : %d\n", + index, + fifo_gyro_data[index].x, + fifo_gyro_data[index].y, + fifo_gyro_data[index].z); + } + + /* Print control frames like sensor time and skipped frame count. */ + printf("Skipped frame count = %d\n", fifoframe.skipped_frame_count); + printf("Sensor time = %lu\r\n", fifoframe.sensor_time); + + try++; + } + } + } + + bmi2_coines_deinit(); + + return rslt; +} + +/*! + * @brief This internal API is used to set configurations for accel and gyro. + */ +static int8_t set_accel_gyro_config(struct bmi2_dev *dev) +{ + /* Status of api are returned to this variable. */ + int8_t rslt; + + /* Structure to define accel and gyro configurations. */ + struct bmi2_sens_config config[2]; + + /* Configure the type of feature. */ + config[0].type = BMI2_ACCEL; + config[1].type = BMI2_GYRO; + + /* Get default configurations for the type of feature selected. */ + rslt = bmi270_hc_get_sensor_config(config, 2, dev); + bmi2_error_codes_print_result(rslt); + + if (rslt == BMI2_OK) + { + /* NOTE: The user can change the following configuration parameters according to their requirement. */ + /* Accel configuration settings. */ + /* Set Output Data Rate */ + config[0].cfg.acc.odr = BMI2_ACC_ODR_25HZ; + + /* Gravity range of the sensor (+/- 2G, 4G, 8G, 16G). */ + config[0].cfg.acc.range = BMI2_ACC_RANGE_2G; + + /* The bandwidth parameter is used to configure the number of sensor samples that are averaged + * if it is set to 2, then 2^(bandwidth parameter) samples + * are averaged, resulting in 4 averaged samples + * Note1 : For more information, refer the datasheet. + * Note2 : A higher number of averaged samples will result in a lower noise level of the signal, but + * this has an adverse effect on the power consumed. + */ + config[0].cfg.acc.bwp = BMI2_ACC_NORMAL_AVG4; + + /* Enable the filter performance mode where averaging of samples + * will be done based on above set bandwidth and ODR. + * There are two modes + * 0 -> Ultra low power mode + * 1 -> High performance mode(Default) + * For more info refer datasheet. + */ + config[0].cfg.acc.filter_perf = BMI2_PERF_OPT_MODE; + + /* Gyro configuration settings. */ + /* Set Output Data Rate */ + config[1].cfg.gyr.odr = BMI2_GYR_ODR_25HZ; + + /* Gyroscope Angular Rate Measurement Range.By default the range is 2000dps. */ + config[1].cfg.gyr.range = BMI2_GYR_RANGE_2000; + + /* Gyroscope Bandwidth parameters. By default the gyro bandwidth is in normal mode. */ + config[1].cfg.gyr.bwp = BMI2_GYR_NORMAL_MODE; + + /* Enable/Disable the noise performance mode for precision yaw rate sensing + * There are two modes + * 0 -> Ultra low power mode(Default) + * 1 -> High performance mode + */ + config[1].cfg.gyr.noise_perf = BMI2_POWER_OPT_MODE; + + /* Enable/Disable the filter performance mode where averaging of samples + * will be done based on above set bandwidth and ODR. + * There are two modes + * 0 -> Ultra low power mode + * 1 -> High performance mode(Default) + */ + config[1].cfg.gyr.filter_perf = BMI2_PERF_OPT_MODE; + + /* Set new configurations. */ + rslt = bmi270_hc_set_sensor_config(config, 2, dev); + bmi2_error_codes_print_result(rslt); + } + + return rslt; +} diff --git a/examples/bmi270_hc/fifo_watermark_headerless_mode/Makefile b/examples/bmi270_hc/fifo_watermark_headerless_mode/Makefile new file mode 100644 index 0000000..bd842a8 --- /dev/null +++ b/examples/bmi270_hc/fifo_watermark_headerless_mode/Makefile @@ -0,0 +1,18 @@ +COINES_INSTALL_PATH ?= ../../../.. + +EXAMPLE_FILE ?= fifo_watermark_headerless_mode.c + +API_LOCATION ?= ../.. + +COMMON_LOCATION ?= .. + +C_SRCS += \ +$(API_LOCATION)/bmi2.c \ +$(API_LOCATION)/bmi270_hc.c \ +$(COMMON_LOCATION)/common/common.c + +INCLUDEPATHS += \ +$(API_LOCATION) \ +$(COMMON_LOCATION)/common + +include $(COINES_INSTALL_PATH)/coines.mk \ No newline at end of file diff --git a/examples/bmi270_hc/fifo_watermark_headerless_mode/fifo_watermark_headerless_mode.c b/examples/bmi270_hc/fifo_watermark_headerless_mode/fifo_watermark_headerless_mode.c new file mode 100644 index 0000000..bb0bfd1 --- /dev/null +++ b/examples/bmi270_hc/fifo_watermark_headerless_mode/fifo_watermark_headerless_mode.c @@ -0,0 +1,331 @@ +/**\ + * Copyright (c) 2020 Bosch Sensortec GmbH. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + **/ + +/******************************************************************************/ +/*! Header Files */ +#include +#include "bmi270_hc.h" +#include "common.h" + +/******************************************************************************/ +/*! Macros */ + +/*! Buffer size allocated to store raw FIFO data */ +#define BMI2_FIFO_RAW_DATA_BUFFER_SIZE UINT16_C(2048) + +/*! Length of data to be read from FIFO */ +#define BMI2_FIFO_RAW_DATA_USER_LENGTH UINT16_C(2048) + +/*! Number of accel frames to be extracted from FIFO */ + +/*! + * Calculation: + * fifo_watermark_level = 650, accel_frame_len = 6, gyro_frame_len = 6. + * fifo_accel_frame_count = (650 / (6 + 6 )) = 54 frames + */ +#define BMI2_FIFO_ACCEL_FRAME_COUNT UINT8_C(55) + +/*! Number of gyro frames to be extracted from FIFO */ +#define BMI2_FIFO_GYRO_FRAME_COUNT UINT8_C(55) + +/*! Setting a watermark level in FIFO */ +#define BMI270_FIFO_WATERMARK_LEVEL UINT16_C(650) + +/******************************************************************************/ +/*! Static Function Declaration */ + +/*! + * @brief This internal API is used to set configurations for accel and gyro. + * @param[in] dev : Structure instance of bmi2_dev. + * @return Status of execution. + */ +static int8_t set_accel_gyro_config(struct bmi2_dev *dev); + +/******************************************************************************/ +/*! Functions */ + +/* This function starts the execution of program. */ +int main(void) +{ + /* Status of api are returned to this variable. */ + int8_t rslt; + + /* Variable to index bytes. */ + uint16_t index = 0; + + /* Variable to store the available frame length count in FIFO */ + uint8_t frame_count; + + uint16_t fifo_length = 0; + + uint16_t accel_frame_length; + + uint16_t gyro_frame_length; + + uint8_t try = 1; + + /* Number of bytes of FIFO data. */ + uint8_t fifo_data[BMI2_FIFO_RAW_DATA_BUFFER_SIZE] = { 0 }; + + /* Sensor initialization configuration. */ + struct bmi2_dev bmi2_dev; + + /* Array of accelerometer frames -> Total bytes = + * 50 * (6 axes bytes) = 300 bytes */ + struct bmi2_sens_axes_data fifo_accel_data[BMI2_FIFO_ACCEL_FRAME_COUNT] = { { 0 } }; + + /* Array of gyro frames -> Total bytes = + * 50 * (6 axes bytes) = 300 bytes */ + struct bmi2_sens_axes_data fifo_gyro_data[BMI2_FIFO_GYRO_FRAME_COUNT] = { { 0 } }; + + /* Initialize FIFO frame structure. */ + struct bmi2_fifo_frame fifoframe = { 0 }; + + /* Accel and gyro sensor are listed in array. */ + uint8_t sensor_sel[2] = { BMI2_ACCEL, BMI2_GYRO }; + + /* Variable to get fifo water-mark interrupt status. */ + uint16_t int_status = 0; + + uint16_t watermark = 0; + + /* Interface reference is given as a parameter + * For I2C : BMI2_I2C_INTF + * For SPI : BMI2_SPI_INTF + */ + rslt = bmi2_interface_init(&bmi2_dev, BMI2_I2C_INTF); + bmi2_error_codes_print_result(rslt); + + /* Initialize bmi270_hc. */ + rslt = bmi270_hc_init(&bmi2_dev); + bmi2_error_codes_print_result(rslt); + + /* Enable accel and gyro sensor. */ + rslt = bmi270_hc_sensor_enable(sensor_sel, 2, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + /* Configuration settings for accel and gyro. */ + rslt = set_accel_gyro_config(&bmi2_dev); + bmi2_error_codes_print_result(rslt); + + /* Before setting FIFO, disable the advance power save mode. */ + rslt = bmi2_set_adv_power_save(BMI2_DISABLE, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + /* Initially disable all configurations in fifo. */ + rslt = bmi2_set_fifo_config(BMI2_FIFO_ALL_EN, BMI2_DISABLE, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + /* Update FIFO structure. */ + /* Mapping the buffer to store the fifo data. */ + fifoframe.data = fifo_data; + + /* Length of FIFO frame. */ + fifoframe.length = BMI2_FIFO_RAW_DATA_USER_LENGTH; + + /* Set FIFO configuration by enabling accel, gyro. + * NOTE 1: The header mode is enabled by default. + * NOTE 2: By default the FIFO operating mode is FIFO mode. */ + rslt = bmi2_set_fifo_config(BMI2_FIFO_ACC_EN | BMI2_FIFO_GYR_EN, BMI2_ENABLE, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + printf("FIFO is configured in headerless mode\n"); + + /* To enable headerless mode, disable the header. */ + if (rslt == BMI2_OK) + { + rslt = bmi2_set_fifo_config(BMI2_FIFO_HEADER_EN, BMI2_DISABLE, &bmi2_dev); + } + + /* FIFO water-mark interrupt is enabled. */ + fifoframe.data_int_map = BMI2_FWM_INT; + + /* Map water-mark interrupt to the required interrupt pin. */ + rslt = bmi2_map_data_int(fifoframe.data_int_map, BMI2_INT1, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + /* Set water-mark level. */ + fifoframe.wm_lvl = BMI270_FIFO_WATERMARK_LEVEL; + + fifoframe.length = BMI2_FIFO_RAW_DATA_USER_LENGTH; + + /* Set the water-mark level if water-mark interrupt is mapped. */ + rslt = bmi2_set_fifo_wm(fifoframe.wm_lvl, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + rslt = bmi2_get_fifo_wm(&watermark, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + printf("\nFIFO watermark level is %d\n", watermark); + + while (try <= 10) + { + /* Read FIFO data on interrupt. */ + rslt = bmi2_get_int_status(&int_status, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + /* To check the status of FIFO watermark interrupt. */ + if ((rslt == BMI2_OK) && (int_status & BMI2_FWM_INT_STATUS_MASK)) + { + printf("\nIteration : %d\n", try); + + printf("\nWatermark interrupt occurred\n"); + + rslt = bmi2_get_fifo_length(&fifo_length, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + accel_frame_length = BMI2_FIFO_ACCEL_FRAME_COUNT; + gyro_frame_length = BMI2_FIFO_GYRO_FRAME_COUNT; + + printf("\nFIFO data bytes available : %d \n", fifo_length); + printf("\nFIFO data bytes requested : %d \n", fifoframe.length); + + /* Read FIFO data. */ + rslt = bmi2_read_fifo_data(&fifoframe, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + /* Read FIFO data on interrupt. */ + rslt = bmi2_get_int_status(&int_status, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + if (rslt == BMI2_OK) + { + printf("\nFIFO accel frames requested : %d \n", accel_frame_length); + + /* Parse the FIFO data to extract accelerometer data from the FIFO buffer. */ + rslt = bmi2_extract_accel(fifo_accel_data, &accel_frame_length, &fifoframe, &bmi2_dev); + printf("\nFIFO accel frames extracted : %d \n", accel_frame_length); + + printf("\nFIFO gyro frames requested : %d \n", gyro_frame_length); + + /* Parse the FIFO data to extract gyro data from the FIFO buffer. */ + rslt = bmi2_extract_gyro(fifo_gyro_data, &gyro_frame_length, &fifoframe, &bmi2_dev); + printf("\nFIFO gyro frames extracted : %d \n", gyro_frame_length); + + /* Calculating the frame count from the available bytes in FIFO + * frame_length = (available_fifo_bytes / (acc_frame_len + gyro_frame_len)) */ + frame_count = (fifo_length / (BMI2_FIFO_ACC_GYR_LENGTH)); + printf("\nAvailable frame count from available bytes: %d\n", frame_count); + + printf("\nExracted accel frames\n"); + + if (accel_frame_length > frame_count) + { + accel_frame_length = frame_count; + } + + /* Print the parsed accelerometer data from the FIFO buffer. */ + for (index = 0; index < accel_frame_length; index++) + { + printf("ACCEL[%d] X : %d\t Y : %d\t Z : %d\n", index, fifo_accel_data[index].x, + fifo_accel_data[index].y, fifo_accel_data[index].z); + } + + printf("\nExtracted gyro frames\n"); + + if (gyro_frame_length > frame_count) + { + gyro_frame_length = frame_count; + } + + /* Print the parsed gyro data from the FIFO buffer. */ + for (index = 0; index < gyro_frame_length; index++) + { + printf("GYRO[%d] X : %d\t Y : %d\t Z : %d\n", + index, + fifo_gyro_data[index].x, + fifo_gyro_data[index].y, + fifo_gyro_data[index].z); + } + } + + try++; + } + } + + bmi2_coines_deinit(); + + return rslt; +} + +/*! + * @brief This internal API is used to set configurations for accel. + */ +static int8_t set_accel_gyro_config(struct bmi2_dev *dev) +{ + /* Status of api are returned to this variable. */ + int8_t rslt; + + /* Structure to define accel and gyro configurations. */ + struct bmi2_sens_config config[2]; + + /* Configure the type of feature. */ + config[0].type = BMI2_ACCEL; + config[1].type = BMI2_GYRO; + + /* Get default configurations for the type of feature selected. */ + rslt = bmi270_hc_get_sensor_config(config, 2, dev); + bmi2_error_codes_print_result(rslt); + + if (rslt == BMI2_OK) + { + /* NOTE: The user can change the following configuration parameter according to their requirement. */ + /* Accel configuration settings. */ + /* Set Output Data Rate */ + config[0].cfg.acc.odr = BMI2_ACC_ODR_100HZ; + + /* Gravity range of the sensor (+/- 2G, 4G, 8G, 16G). */ + config[0].cfg.acc.range = BMI2_ACC_RANGE_2G; + + /* The bandwidth parameter is used to configure the number of sensor samples that are averaged + * if it is set to 2, then 2^(bandwidth parameter) samples + * are averaged, resulting in 4 averaged samples + * Note1 : For more information, refer the datasheet. + * Note2 : A higher number of averaged samples will result in a lower noise level of the signal, but + * this has an adverse effect on the power consumed. + */ + config[0].cfg.acc.bwp = BMI2_ACC_NORMAL_AVG4; + + /* Enable the filter performance mode where averaging of samples + * will be done based on above set bandwidth and ODR. + * There are two modes + * 0 -> Ultra low power mode + * 1 -> High performance mode(Default) + * For more info refer datasheet. + */ + config[0].cfg.acc.filter_perf = BMI2_PERF_OPT_MODE; + + /* Gyro configuration settings. */ + /* Set Output Data Rate */ + config[1].cfg.gyr.odr = BMI2_GYR_ODR_100HZ; + + /* Gyroscope Angular Rate Measurement Range.By default the range is 2000dps. */ + config[1].cfg.gyr.range = BMI2_GYR_RANGE_2000; + + /* Gyroscope Bandwidth parameters. By default the gyro bandwidth is in normal mode. */ + config[1].cfg.gyr.bwp = BMI2_GYR_NORMAL_MODE; + + /* Enable/Disable the noise performance mode for precision yaw rate sensing + * There are two modes + * 0 -> Ultra low power mode(Default) + * 1 -> High performance mode + */ + config[1].cfg.gyr.noise_perf = BMI2_POWER_OPT_MODE; + + /* Enable/Disable the filter performance mode where averaging of samples + * will be done based on above set bandwidth and ODR. + * There are two modes + * 0 -> Ultra low power mode + * 1 -> High performance mode(Default) + */ + config[1].cfg.gyr.filter_perf = BMI2_PERF_OPT_MODE; + + /* Set new configurations. */ + rslt = bmi270_hc_set_sensor_config(config, 2, dev); + bmi2_error_codes_print_result(rslt); + } + + return rslt; +} diff --git a/examples/bmi270_hc/gyro/Makefile b/examples/bmi270_hc/gyro/Makefile new file mode 100644 index 0000000..cb6bfaa --- /dev/null +++ b/examples/bmi270_hc/gyro/Makefile @@ -0,0 +1,18 @@ +COINES_INSTALL_PATH ?= ../../../.. + +EXAMPLE_FILE ?= gyro.c + +API_LOCATION ?= ../.. + +COMMON_LOCATION ?= .. + +C_SRCS += \ +$(API_LOCATION)/bmi2.c \ +$(API_LOCATION)/bmi270_hc.c \ +$(COMMON_LOCATION)/common/common.c + +INCLUDEPATHS += \ +$(API_LOCATION) \ +$(COMMON_LOCATION)/common + +include $(COINES_INSTALL_PATH)/coines.mk \ No newline at end of file diff --git a/examples/bmi270_hc/gyro/gyro.c b/examples/bmi270_hc/gyro/gyro.c new file mode 100644 index 0000000..c7c5027 --- /dev/null +++ b/examples/bmi270_hc/gyro/gyro.c @@ -0,0 +1,195 @@ +/**\ + * Copyright (c) 2020 Bosch Sensortec GmbH. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + **/ + +/******************************************************************************/ +/*! Header Files */ +#include +#include "bmi270_hc.h" +#include "common.h" + +/******************************************************************************/ +/*! Static Function Declaration */ + +/*! + * @brief This internal API is used to set configurations for gyro. + * + * @param[in] dev : Structure instance of bmi2_dev. + * + * @return Status of execution. + */ +static int8_t set_gyro_config(struct bmi2_dev *dev); + +/*! + * @brief This function converts lsb to degree per second for 16 bit gyro at + * range 125, 250, 500, 1000 or 2000dps. + * + * @param[in] val : LSB from each axis. + * @param[in] dps : Degree per second. + * @param[in] bit_width : Resolution for gyro. + * + * @return Degree per second. + */ +static float lsb_to_dps(int16_t val, float dps, uint8_t bit_width); + +/******************************************************************************/ +/*! Functions */ + +/* This function starts the execution of program. */ +int main(void) +{ + /* Status of api are returned to this variable. */ + int8_t rslt; + + /* Variable to define limit to print gyro data. */ + uint8_t limit = 10; + + uint8_t indx = 0; + + float x = 0, y = 0, z = 0; + + /* Sensor initialization configuration. */ + struct bmi2_dev bmi2_dev; + + /* Create an instance of sensor data structure. */ + struct bmi2_sensor_data sensor_data = { 0 }; + + /* Assign gyro sensor to variable. */ + uint8_t sens_list = BMI2_GYRO; + + /* Initialize the interrupt status of gyro. */ + uint16_t int_status = 0; + + /* Interface reference is given as a parameter + * For I2C : BMI2_I2C_INTF + * For SPI : BMI2_SPI_INTF + */ + rslt = bmi2_interface_init(&bmi2_dev, BMI2_I2C_INTF); + bmi2_error_codes_print_result(rslt); + + /* Initialize bmi270_hc. */ + rslt = bmi270_hc_init(&bmi2_dev); + bmi2_error_codes_print_result(rslt); + + if (rslt == BMI2_OK) + { + /* Enable the selected sensors. */ + rslt = bmi270_hc_sensor_enable(&sens_list, 1, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + if (rslt == BMI2_OK) + { + /* Gyro configuration settings. */ + rslt = set_gyro_config(&bmi2_dev); + bmi2_error_codes_print_result(rslt); + + /* Select gyro sensor. */ + sensor_data.type = BMI2_GYRO; + printf("Gyro and DPS data\n"); + printf("Gyro data collected at Range 2000 dps with 16-bit resolution\n"); + + /* Loop to print gyro data when interrupt occurs. */ + while (indx <= limit) + { + /* To get the data ready interrupt status of gyro. */ + rslt = bmi2_get_int_status(&int_status, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + /* To check the data ready interrupt status and print the status for 10 samples. */ + if (int_status & BMI2_GYR_DRDY_INT_MASK) + { + /* Get gyro data for x, y and z axis. */ + rslt = bmi270_hc_get_sensor_data(&sensor_data, 1, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + printf("\nGyr_X = %d\t", sensor_data.sens_data.gyr.x); + printf("Gyr_Y = %d\t", sensor_data.sens_data.gyr.y); + printf("Gyr_Z = %d\r\n", sensor_data.sens_data.gyr.z); + + /* Converting lsb to degree per second for 16 bit gyro at 2000dps range. */ + x = lsb_to_dps(sensor_data.sens_data.gyr.x, 2000, bmi2_dev.resolution); + y = lsb_to_dps(sensor_data.sens_data.gyr.y, 2000, bmi2_dev.resolution); + z = lsb_to_dps(sensor_data.sens_data.gyr.z, 2000, bmi2_dev.resolution); + + /* Print the data in dps. */ + printf("Gyr_DPS_X = %4.2f, Gyr_DPS_Y = %4.2f, Gyr_DPS_Z = %4.2f\n", x, y, z); + + indx++; + } + } + } + } + + bmi2_coines_deinit(); + + return rslt; +} + +/*! + * @brief This internal API is used to set configurations for gyro. + */ +static int8_t set_gyro_config(struct bmi2_dev *dev) +{ + /* Status of api are returned to this variable. */ + int8_t rslt; + + /* Structure to define the type of sensor and its configurations. */ + struct bmi2_sens_config config; + + /* Configure the type of feature. */ + config.type = BMI2_GYRO; + + /* Get default configurations for the type of feature selected. */ + rslt = bmi270_hc_get_sensor_config(&config, 1, dev); + bmi2_error_codes_print_result(rslt); + + /* Map data ready interrupt to interrupt pin. */ + rslt = bmi2_map_data_int(BMI2_DRDY_INT, BMI2_INT2, dev); + bmi2_error_codes_print_result(rslt); + + if (rslt == BMI2_OK) + { + /* The user can change the following configuration parameters according to their requirement. */ + /* Set Output Data Rate */ + config.cfg.gyr.odr = BMI2_GYR_ODR_200HZ; + + /* Gyroscope Angular Rate Measurement Range.By default the range is 2000dps. */ + config.cfg.gyr.range = BMI2_GYR_RANGE_2000; + + /* Gyroscope bandwidth parameters. By default the gyro bandwidth is in normal mode. */ + config.cfg.gyr.bwp = BMI2_GYR_NORMAL_MODE; + + /* Enable/Disable the noise performance mode for precision yaw rate sensing + * There are two modes + * 0 -> Ultra low power mode(Default) + * 1 -> High performance mode + */ + config.cfg.gyr.noise_perf = BMI2_POWER_OPT_MODE; + + /* Enable/Disable the filter performance mode where averaging of samples + * will be done based on above set bandwidth and ODR. + * There are two modes + * 0 -> Ultra low power mode + * 1 -> High performance mode(Default) + */ + config.cfg.gyr.filter_perf = BMI2_PERF_OPT_MODE; + + /* Set the gyro configurations. */ + rslt = bmi270_hc_set_sensor_config(&config, 1, dev); + } + + return rslt; +} + +/*! + * @brief This function converts lsb to degree per second for 16 bit gyro at + * range 125, 250, 500, 1000 or 2000dps. + */ +static float lsb_to_dps(int16_t val, float dps, uint8_t bit_width) +{ + float half_scale = ((float)(1 << bit_width) / 2.0f); + + return (dps / ((half_scale) + BMI2_GYR_RANGE_2000)) * (val); +} diff --git a/examples/bmi270_hc/step_counter/Makefile b/examples/bmi270_hc/step_counter/Makefile new file mode 100644 index 0000000..fc47b9b --- /dev/null +++ b/examples/bmi270_hc/step_counter/Makefile @@ -0,0 +1,18 @@ +COINES_INSTALL_PATH ?= ../../../.. + +EXAMPLE_FILE ?= step_counter.c + +API_LOCATION ?= ../.. + +COMMON_LOCATION ?= .. + +C_SRCS += \ +$(API_LOCATION)/bmi2.c \ +$(API_LOCATION)/bmi270_hc.c \ +$(COMMON_LOCATION)/common/common.c + +INCLUDEPATHS += \ +$(API_LOCATION) \ +$(COMMON_LOCATION)/common + +include $(COINES_INSTALL_PATH)/coines.mk \ No newline at end of file diff --git a/examples/bmi270_hc/step_counter/step_counter.c b/examples/bmi270_hc/step_counter/step_counter.c new file mode 100644 index 0000000..785dc28 --- /dev/null +++ b/examples/bmi270_hc/step_counter/step_counter.c @@ -0,0 +1,146 @@ +/**\ + * Copyright (c) 2020 Bosch Sensortec GmbH. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + **/ + +/******************************************************************************/ +/*! Header Files */ +#include +#include "bmi270_hc.h" +#include "common.h" + +/******************************************************************************/ +/*! Static function declaration */ + +/*! + * @brief This internal API is used to set configurations for step counter. + * + * @param[in] bmi2_dev : Structure instance of bmi2_dev. + * + * @return Status of execution. + */ +static int8_t set_feature_config(struct bmi2_dev *bmi2_dev); + +/******************************************************************************/ +/*! Functions */ + +/* This function starts the execution of program. */ +int main(void) +{ + /* Sensor initialization configuration. */ + struct bmi2_dev bmi2_dev; + + /* Structure to define type of sensor and their respective data. */ + struct bmi2_sensor_data sensor_data; + + /* Status of api are returned to this variable. */ + int8_t rslt; + + /* Accel sensor and step counter feature are listed in array. */ + uint8_t sensor_sel[2] = { BMI2_ACCEL, BMI2_STEP_COUNTER }; + + /* Variable to get step counter interrupt status. */ + uint16_t int_status = 0; + + /* Select features and their pins to be mapped to. */ + struct bmi2_sens_int_config sens_int = { .type = BMI2_STEP_COUNTER, .hw_int_pin = BMI2_INT2 }; + + /* Type of sensor to get step counter data. */ + sensor_data.type = BMI2_STEP_COUNTER; + + /* Interface reference is given as a parameter + * For I2C : BMI2_I2C_INTF + * For SPI : BMI2_SPI_INTF + */ + rslt = bmi2_interface_init(&bmi2_dev, BMI2_I2C_INTF); + bmi2_error_codes_print_result(rslt); + + /* Initialize bmi270_hc. */ + rslt = bmi270_hc_init(&bmi2_dev); + bmi2_error_codes_print_result(rslt); + + if (rslt == BMI2_OK) + { + /* Enable the selected sensor. */ + rslt = bmi270_hc_sensor_enable(sensor_sel, 2, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + if (rslt == BMI2_OK) + { + /* Set the feature configuration for step counter. */ + rslt = set_feature_config(&bmi2_dev); + bmi2_error_codes_print_result(rslt); + + printf("Step counter watermark level set to 1 (20 steps)\n"); + + if (rslt == BMI2_OK) + { + /* Map the step counter feature interrupt. */ + rslt = bmi270_hc_map_feat_int(&sens_int, 1, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + /* Move the board in steps for 20 times to get step counter interrupt. */ + printf("Move the board in steps\n"); + + /* Loop to get number of steps counted. */ + do + { + /* To get the interrupt status of the step counter. */ + rslt = bmi2_get_int_status(&int_status, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + /* To check the interrupt status of the step counter. */ + if (int_status & BMI270_HC_STEP_CNT_STATUS_MASK) + { + printf("Step counter interrupt occurred when watermark level (20 steps) is reached\n"); + + /* Get step counter output. */ + rslt = bmi270_hc_get_sensor_data(&sensor_data, 1, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + /* Print the step counter output. */ + printf("No of steps counted = %ld", sensor_data.sens_data.step_counter_output); + break; + } + } while (rslt == BMI2_OK); + } + } + } + + bmi2_coines_deinit(); + + return rslt; +} + +/*! + * @brief This internal API is used to set configurations for step counter. + */ +static int8_t set_feature_config(struct bmi2_dev *bmi2_dev) +{ + /* Status of api are returned to this variable. */ + int8_t rslt; + + /* Structure to define the type of sensor and its configurations. */ + struct bmi2_sens_config config; + + /* Configure the type of sensor. */ + config.type = BMI2_STEP_COUNTER; + + /* Get default configurations for the type of feature selected. */ + rslt = bmi270_hc_get_sensor_config(&config, 1, bmi2_dev); + bmi2_error_codes_print_result(rslt); + + if (rslt == BMI2_OK) + { + /* Setting water-mark level to 1 for step counter to get interrupt after 20 step counts. Every 20 steps once + * output triggers. */ + config.cfg.step_counter.watermark_level = 1; + + /* Set new configuration. */ + rslt = bmi270_hc_set_sensor_config(&config, 1, bmi2_dev); + bmi2_error_codes_print_result(rslt); + } + + return rslt; +} diff --git a/examples/bmi270_maximum_fifo/accel/Makefile b/examples/bmi270_maximum_fifo/accel/Makefile new file mode 100644 index 0000000..e4400a4 --- /dev/null +++ b/examples/bmi270_maximum_fifo/accel/Makefile @@ -0,0 +1,18 @@ +COINES_INSTALL_PATH ?= ../../../.. + +EXAMPLE_FILE ?= accel.c + +API_LOCATION ?= ../.. + +COMMON_LOCATION ?= .. + +C_SRCS += \ +$(API_LOCATION)/bmi2.c \ +$(API_LOCATION)/bmi270_maximum_fifo.c \ +$(COMMON_LOCATION)/common/common.c + +INCLUDEPATHS += \ +$(API_LOCATION) \ +$(COMMON_LOCATION)/common + +include $(COINES_INSTALL_PATH)/coines.mk \ No newline at end of file diff --git a/examples/bmi270/generic/accel.c b/examples/bmi270_maximum_fifo/accel/accel.c similarity index 81% rename from examples/bmi270/generic/accel.c rename to examples/bmi270_maximum_fifo/accel/accel.c index c8f1289..c32a43a 100644 --- a/examples/bmi270/generic/accel.c +++ b/examples/bmi270_maximum_fifo/accel/accel.c @@ -1,196 +1,200 @@ -/**\ - * Copyright (c) 2020 Bosch Sensortec GmbH. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - **/ - -/******************************************************************************/ -/*! Header Files */ -#include -#include "bmi2.h" -#include "bmi270.h" -#include "bmi2_common.h" - -/******************************************************************************/ -/*! Macro definition */ - -/*! Earth's gravity in m/s^2 */ -#define GRAVITY_EARTH (9.80665f) - -/******************************************************************************/ -/*! Static Function Declaration */ - -/*! - * @brief This internal API is used to set configurations for accel. - * - * @param[in] dev : Structure instance of bmi2_dev. - * - * @return Status of execution. - */ -static int8_t set_accel_config(struct bmi2_dev *bmi2_dev); - -/*! - * @brief This function converts lsb to meter per second squared for 16 bit accelerometer at - * range 2G, 4G, 8G or 16G. - * - * @param[in] val : LSB from each axis. - * @param[in] g_range : Gravity range. - * @param[in] bit_width : Resolution for accel. - * - * @return Gravity. - */ -static float lsb_to_mps2(int16_t val, float g_range, uint8_t bit_width); - -/******************************************************************************/ -/*! Functions */ - -/* This function starts the execution of program. */ -int main(void) -{ - - /* Status of api are returned to this variable. */ - int8_t rslt; - - /* Variable to define limit to print accel data. */ - uint8_t limit = 20; - - /* Assign accel sensor to variable. */ - uint8_t sensor_list = BMI2_ACCEL; - - /*! Sensor initialization configuration. */ - struct bmi2_dev bmi2_dev; - - /* Create an instance of sensor data structure. */ - struct bmi2_sensor_data sensor_data = { 0 }; - - /* Initialize the interrupt status of accel. */ - uint16_t int_status = 0; - - uint8_t indx = 0; - float x = 0, y = 0, z = 0; - - /* Initialize the dev structure */ - rslt = bmi2_interface_selection(&bmi2_dev); - bmi2_error_codes_print_result(rslt); - - /* Initialize bmi270. */ - rslt = bmi270_init(&bmi2_dev); - bmi2_error_codes_print_result(rslt); - - if (rslt == BMI2_OK) - { - - /* Enable the accel sensor. */ - rslt = bmi2_sensor_enable(&sensor_list, 1, &bmi2_dev); - bmi2_error_codes_print_result(rslt); - - if (rslt == BMI2_OK) - { - /* Accel configuration settings. */ - rslt = set_accel_config(&bmi2_dev); - bmi2_error_codes_print_result(rslt); - - /* Assign accel sensor. */ - sensor_data.type = BMI2_ACCEL; - printf("Accel and gravity data \n\r"); - - /* Loop to print the accel data when interrupt occurs. */ - do - { - /* To get the status of accel data ready interrupt. */ - rslt = bmi2_get_int_status(&int_status, &bmi2_dev); - bmi2_error_codes_print_result(rslt); - - /* To check the accel data ready interrupt status and print the status for 10 samples. */ - for (indx = 0; (indx < limit && (int_status & BMI2_ACC_DRDY_INT_MASK)); indx++) - { - - /* Get accelerometer data for x, y and z axis. */ - rslt = bmi2_get_sensor_data(&sensor_data, 1, &bmi2_dev); - bmi2_error_codes_print_result(rslt); - printf("\nAx = %d\t", sensor_data.sens_data.acc.x); - printf("Ay = %d\t", sensor_data.sens_data.acc.y); - printf("Az = %d\r\n", sensor_data.sens_data.acc.z); - - /* Converting lsb to meter per second squared for 16 bit accelerometer at 2G range. */ - x = lsb_to_mps2(sensor_data.sens_data.acc.x, 2, bmi2_dev.resolution); - y = lsb_to_mps2(sensor_data.sens_data.acc.y, 2, bmi2_dev.resolution); - z = lsb_to_mps2(sensor_data.sens_data.acc.z, 2, bmi2_dev.resolution); - - /* Print the data in m/s2. */ - printf("\nGx = %4.2f, Gy = %4.2f, Gz = %4.2f\n", x, y, z); - } - } while (int_status != BMI2_ACC_DRDY_INT_MASK); - } - } - - return rslt; -} - -/*! - * @brief This internal API is used to set configurations for accel. - */ -static int8_t set_accel_config(struct bmi2_dev *bmi2_dev) -{ - - /* Status of api are returned to this variable. */ - int8_t rslt; - - /* Structure to define accelerometer configuration. */ - struct bmi2_sens_config config; - - /* Configure the type of feature. */ - config.type = BMI2_ACCEL; - - /* Get default configurations for the type of feature selected. */ - rslt = bmi2_get_sensor_config(&config, 1, bmi2_dev); - bmi2_error_codes_print_result(rslt); - - /* Map data ready interrupt to interrupt pin. */ - rslt = bmi2_map_data_int(BMI2_DRDY_INT, BMI2_INT1, bmi2_dev); - bmi2_error_codes_print_result(rslt); - - if (rslt == BMI2_OK) - { - /* NOTE: The user can change the following configuration parameters according to their requirement. */ - /* Output Data Rate. By default ODR is set as 100Hz for accel. */ - config.cfg.acc.odr = BMI2_ACC_ODR_100HZ; - - /* Gravity range of the sensor (+/- 2G, 4G, 8G, 16G). */ - config.cfg.acc.range = BMI2_ACC_RANGE_2G; - - /* The bandwidth parameter is used to configure the number of sensor samples that are averaged - * if it is set to 2, then 2^(bandwidth parameter) samples - * are averaged, resulting in 4 averaged samples. - * Note1 : For more information, refer the datasheet. - * Note2 : A higher number of averaged samples will result in a lower noise level of the signal, but - * this has an adverse effect on the power consumed. - */ - config.cfg.acc.bwp = BMI2_ACC_NORMAL_AVG4; - - /* Enable the filter performance mode where averaging of samples - * will be done based on above set bandwidth and ODR. - * There are two modes - * 0 -> Ultra low power mode - * 1 -> High performance mode(Default) - * For more info refer datasheet. - */ - config.cfg.acc.filter_perf = BMI2_PERF_OPT_MODE; - - /* Set the accel configurations. */ - rslt = bmi2_set_sensor_config(&config, 1, bmi2_dev); - } - - return rslt; -} - -/*! - * @brief This function converts lsb to meter per second squared for 16 bit accelerometer at - * range 2G, 4G, 8G or 16G. - */ -static float lsb_to_mps2(int16_t val, float g_range, uint8_t bit_width) -{ - float half_scale = ((float)(1 << bit_width) / 2.0f); - - return (GRAVITY_EARTH * val * g_range) / half_scale; -} +/**\ + * Copyright (c) 2020 Bosch Sensortec GmbH. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + **/ + +/******************************************************************************/ +/*! Header Files */ +#include +#include "bmi270_maximum_fifo.h" +#include "common.h" + +/******************************************************************************/ +/*! Macro definition */ + +/*! Earth's gravity in m/s^2 */ +#define GRAVITY_EARTH (9.80665f) + +/******************************************************************************/ +/*! Static Function Declaration */ + +/*! + * @brief This internal API is used to set configurations for accel. + * + * @param[in] dev : Structure instance of bmi2_dev. + * + * @return Status of execution. + */ +static int8_t set_accel_config(struct bmi2_dev *bmi2_dev); + +/*! + * @brief This function converts lsb to meter per second squared for 16 bit accelerometer at + * range 2G, 4G, 8G or 16G. + * + * @param[in] val : LSB from each axis. + * @param[in] g_range : Gravity range. + * @param[in] bit_width : Resolution for accel. + * + * @return Gravity. + */ +static float lsb_to_mps2(int16_t val, float g_range, uint8_t bit_width); + +/******************************************************************************/ +/*! Functions */ + +/* This function starts the execution of program. */ +int main(void) +{ + /* Status of api are returned to this variable. */ + int8_t rslt; + + /* Variable to define limit to print accel data. */ + uint8_t limit = 20; + + /* Assign accel sensor to variable. */ + uint8_t sensor_list = BMI2_ACCEL; + + /* Sensor initialization configuration. */ + struct bmi2_dev bmi2_dev; + + /* Create an instance of sensor data structure. */ + struct bmi2_sensor_data sensor_data = { 0 }; + + /* Initialize the interrupt status of accel. */ + uint16_t int_status = 0; + + uint8_t indx = 0; + float x = 0, y = 0, z = 0; + + /* Interface reference is given as a parameter + * For I2C : BMI2_I2C_INTF + * For SPI : BMI2_SPI_INTF + */ + rslt = bmi2_interface_init(&bmi2_dev, BMI2_I2C_INTF); + bmi2_error_codes_print_result(rslt); + + /* Initialize bmi270_maximum_fifo. */ + rslt = bmi270_maximum_fifo_init(&bmi2_dev); + bmi2_error_codes_print_result(rslt); + + if (rslt == BMI2_OK) + { + /* Enable the accel sensor. */ + rslt = bmi2_sensor_enable(&sensor_list, 1, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + if (rslt == BMI2_OK) + { + /* Accel configuration settings. */ + rslt = set_accel_config(&bmi2_dev); + bmi2_error_codes_print_result(rslt); + + /* Assign accel sensor. */ + sensor_data.type = BMI2_ACCEL; + printf("Accel and m/s2 data \n"); + printf("Accel data collected at 2G Range with 16-bit resolution\n"); + + /* Loop to print the accel data when interrupt occurs. */ + while (indx <= limit) + { + /* To get the status of accel data ready interrupt. */ + rslt = bmi2_get_int_status(&int_status, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + /* To check the accel data ready interrupt status and print the status for 10 samples. */ + if (int_status & BMI2_ACC_DRDY_INT_MASK) + { + /* Get accelerometer data for x, y and z axis. */ + rslt = bmi2_get_sensor_data(&sensor_data, 1, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + printf("\nAcc_X = %d\t", sensor_data.sens_data.acc.x); + printf("Acc_Y = %d\t", sensor_data.sens_data.acc.y); + printf("Acc_Z = %d\r\n", sensor_data.sens_data.acc.z); + + /* Converting lsb to meter per second squared for 16 bit accelerometer at 2G range. */ + x = lsb_to_mps2(sensor_data.sens_data.acc.x, 2, bmi2_dev.resolution); + y = lsb_to_mps2(sensor_data.sens_data.acc.y, 2, bmi2_dev.resolution); + z = lsb_to_mps2(sensor_data.sens_data.acc.z, 2, bmi2_dev.resolution); + + /* Print the data in m/s2. */ + printf("\nAcc_ms2_X = %4.2f, Acc_ms2_Y = %4.2f, Acc_ms2_Z = %4.2f\n", x, y, z); + + indx++; + } + } + } + } + + bmi2_coines_deinit(); + + return rslt; +} + +/*! + * @brief This internal API is used to set configurations for accel. + */ +static int8_t set_accel_config(struct bmi2_dev *bmi2_dev) +{ + /* Status of api are returned to this variable. */ + int8_t rslt; + + /* Structure to define accelerometer configuration. */ + struct bmi2_sens_config config; + + /* Configure the type of feature. */ + config.type = BMI2_ACCEL; + + /* Get default configurations for the type of feature selected. */ + rslt = bmi2_get_sensor_config(&config, 1, bmi2_dev); + bmi2_error_codes_print_result(rslt); + + if (rslt == BMI2_OK) + { + /* NOTE: The user can change the following configuration parameters according to their requirement. */ + /* Set Output Data Rate */ + config.cfg.acc.odr = BMI2_ACC_ODR_200HZ; + + /* Gravity range of the sensor (+/- 2G, 4G, 8G, 16G). */ + config.cfg.acc.range = BMI2_ACC_RANGE_2G; + + /* The bandwidth parameter is used to configure the number of sensor samples that are averaged + * if it is set to 2, then 2^(bandwidth parameter) samples + * are averaged, resulting in 4 averaged samples. + * Note1 : For more information, refer the datasheet. + * Note2 : A higher number of averaged samples will result in a lower noise level of the signal, but + * this has an adverse effect on the power consumed. + */ + config.cfg.acc.bwp = BMI2_ACC_NORMAL_AVG4; + + /* Enable the filter performance mode where averaging of samples + * will be done based on above set bandwidth and ODR. + * There are two modes + * 0 -> Ultra low power mode + * 1 -> High performance mode(Default) + * For more info refer datasheet. + */ + config.cfg.acc.filter_perf = BMI2_PERF_OPT_MODE; + + /* Set the accel configurations. */ + rslt = bmi2_set_sensor_config(&config, 1, bmi2_dev); + bmi2_error_codes_print_result(rslt); + + /* Map data ready interrupt to interrupt pin. */ + rslt = bmi2_map_data_int(BMI2_DRDY_INT, BMI2_INT1, bmi2_dev); + bmi2_error_codes_print_result(rslt); + } + + return rslt; +} + +/*! + * @brief This function converts lsb to meter per second squared for 16 bit accelerometer at + * range 2G, 4G, 8G or 16G. + */ +static float lsb_to_mps2(int16_t val, float g_range, uint8_t bit_width) +{ + float half_scale = ((float)(1 << bit_width) / 2.0f); + + return (GRAVITY_EARTH * val * g_range) / half_scale; +} diff --git a/examples/bmi270_maximum_fifo/accel_gyro/Makefile b/examples/bmi270_maximum_fifo/accel_gyro/Makefile new file mode 100644 index 0000000..a33f366 --- /dev/null +++ b/examples/bmi270_maximum_fifo/accel_gyro/Makefile @@ -0,0 +1,18 @@ +COINES_INSTALL_PATH ?= ../../../.. + +EXAMPLE_FILE ?= accel_gyro.c + +API_LOCATION ?= ../.. + +COMMON_LOCATION ?= .. + +C_SRCS += \ +$(API_LOCATION)/bmi2.c \ +$(API_LOCATION)/bmi270_maximum_fifo.c \ +$(COMMON_LOCATION)/common/common.c + +INCLUDEPATHS += \ +$(API_LOCATION) \ +$(COMMON_LOCATION)/common + +include $(COINES_INSTALL_PATH)/coines.mk \ No newline at end of file diff --git a/examples/bmi270_maximum_fifo/accel_gyro/accel_gyro.c b/examples/bmi270_maximum_fifo/accel_gyro/accel_gyro.c new file mode 100644 index 0000000..b77ea1d --- /dev/null +++ b/examples/bmi270_maximum_fifo/accel_gyro/accel_gyro.c @@ -0,0 +1,268 @@ +/**\ + * Copyright (c) 2020 Bosch Sensortec GmbH. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + **/ + +/******************************************************************************/ +/*! Header Files */ +#include +#include "bmi270_maximum_fifo.h" +#include "common.h" + +/******************************************************************************/ +/*! Macro definition */ + +/*! Earth's gravity in m/s^2 */ +#define GRAVITY_EARTH (9.80665f) + +/*! Macros to select the sensors */ +#define ACCEL UINT8_C(0x00) +#define GYRO UINT8_C(0x01) + +/******************************************************************************/ +/*! Static Function Declaration */ + +/*! + * @brief This internal API is used to set configurations for accel. + * + * @param[in] dev : Structure instance of bmi2_dev. + * + * @return Status of execution. + */ +static int8_t set_accel_gyro_config(struct bmi2_dev *bmi2_dev); + +/*! + * @brief This function converts lsb to meter per second squared for 16 bit accelerometer at + * range 2G, 4G, 8G or 16G. + * + * @param[in] val : LSB from each axis. + * @param[in] g_range : Gravity range. + * @param[in] bit_width : Resolution for accel. + * + * @return Gravity. + */ +static float lsb_to_mps2(int16_t val, float g_range, uint8_t bit_width); + +/*! + * @brief This function converts lsb to degree per second for 16 bit gyro at + * range 125, 250, 500, 1000 or 2000dps. + * + * @param[in] val : LSB from each axis. + * @param[in] dps : Degree per second. + * @param[in] bit_width : Resolution for gyro. + * + * @return Degree per second. + */ +static float lsb_to_dps(int16_t val, float dps, uint8_t bit_width); + +/******************************************************************************/ +/*! Functions */ + +/* This function starts the execution of program. */ +int main(void) +{ + /* Status of api are returned to this variable. */ + int8_t rslt; + + /* Variable to define limit to print accel data. */ + uint8_t limit = 10; + + /* Assign accel and gyro sensor to variable. */ + uint8_t sensor_list[2] = { BMI2_ACCEL, BMI2_GYRO }; + + /* Sensor initialization configuration. */ + struct bmi2_dev bmi2_dev; + + /* Create an instance of sensor data structure. */ + struct bmi2_sensor_data sensor_data[2] = { { 0 } }; + + /* Initialize the interrupt status of accel and gyro. */ + uint16_t int_status = 0; + + uint8_t indx = 1; + + float x = 0, y = 0, z = 0; + + /* Interface reference is given as a parameter + * For I2C : BMI2_I2C_INTF + * For SPI : BMI2_SPI_INTF + */ + rslt = bmi2_interface_init(&bmi2_dev, BMI2_I2C_INTF); + bmi2_error_codes_print_result(rslt); + + /* Initialize bmi270_maximum_fifo. */ + rslt = bmi270_maximum_fifo_init(&bmi2_dev); + bmi2_error_codes_print_result(rslt); + + if (rslt == BMI2_OK) + { + /* Enable the accel and gyro sensor. */ + rslt = bmi2_sensor_enable(sensor_list, 2, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + if (rslt == BMI2_OK) + { + /* Accel and gyro configuration settings. */ + rslt = set_accel_gyro_config(&bmi2_dev); + bmi2_error_codes_print_result(rslt); + + /* Assign accel and gyro sensor. */ + sensor_data[ACCEL].type = BMI2_ACCEL; + sensor_data[GYRO].type = BMI2_GYRO; + + /* Loop to print accel and gyro data when interrupt occurs. */ + while (indx <= limit) + { + /* To get the data ready interrupt status of accel and gyro. */ + rslt = bmi2_get_int_status(&int_status, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + /* To check the data ready interrupt status and print the status for 10 samples. */ + if ((int_status & BMI2_ACC_DRDY_INT_MASK) && (int_status & BMI2_GYR_DRDY_INT_MASK)) + { + /* Get accel and gyro data for x, y and z axis. */ + rslt = bmi2_get_sensor_data(sensor_data, 2, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + printf("\n******* Accel(Raw and m/s2) Gyro(Raw and dps) data : %d *******\n", indx); + + printf("\nAcc_x = %d\t", sensor_data[ACCEL].sens_data.acc.x); + printf("Acc_y = %d\t", sensor_data[ACCEL].sens_data.acc.y); + printf("Acc_z = %d", sensor_data[ACCEL].sens_data.acc.z); + + /* Converting lsb to meter per second squared for 16 bit accelerometer at 2G range. */ + x = lsb_to_mps2(sensor_data[ACCEL].sens_data.acc.x, 2, bmi2_dev.resolution); + y = lsb_to_mps2(sensor_data[ACCEL].sens_data.acc.y, 2, bmi2_dev.resolution); + z = lsb_to_mps2(sensor_data[ACCEL].sens_data.acc.z, 2, bmi2_dev.resolution); + + /* Print the data in m/s2. */ + printf("\nAcc_ms2_X = %4.2f, Acc_ms2_Y = %4.2f, Acc_ms2_Z = %4.2f\n", x, y, z); + + printf("\nGyr_X = %d\t", sensor_data[GYRO].sens_data.gyr.x); + printf("Gyr_Y = %d\t", sensor_data[GYRO].sens_data.gyr.y); + printf("Gyr_Z= %d\n", sensor_data[GYRO].sens_data.gyr.z); + + /* Converting lsb to degree per second for 16 bit gyro at 2000dps range. */ + x = lsb_to_dps(sensor_data[GYRO].sens_data.gyr.x, 2000, bmi2_dev.resolution); + y = lsb_to_dps(sensor_data[GYRO].sens_data.gyr.y, 2000, bmi2_dev.resolution); + z = lsb_to_dps(sensor_data[GYRO].sens_data.gyr.z, 2000, bmi2_dev.resolution); + + /* Print the data in dps. */ + printf("Gyro_DPS_X = %4.2f, Gyro_DPS_Y = %4.2f, Gyro_DPS_Z = %4.2f\n", x, y, z); + + indx++; + } + } + } + } + + bmi2_coines_deinit(); + + return rslt; +} + +/*! + * @brief This internal API is used to set configurations for accel and gyro. + */ +static int8_t set_accel_gyro_config(struct bmi2_dev *bmi2_dev) +{ + /* Status of api are returned to this variable. */ + int8_t rslt; + + /* Structure to define accelerometer and gyro configuration. */ + struct bmi2_sens_config config[2]; + + /* Configure the type of feature. */ + config[ACCEL].type = BMI2_ACCEL; + config[GYRO].type = BMI2_GYRO; + + /* Get default configurations for the type of feature selected. */ + rslt = bmi2_get_sensor_config(config, 2, bmi2_dev); + bmi2_error_codes_print_result(rslt); + + /* Map data ready interrupt to interrupt pin. */ + rslt = bmi2_map_data_int(BMI2_DRDY_INT, BMI2_INT1, bmi2_dev); + bmi2_error_codes_print_result(rslt); + + if (rslt == BMI2_OK) + { + /* NOTE: The user can change the following configuration parameters according to their requirement. */ + /* Set Output Data Rate */ + config[ACCEL].cfg.acc.odr = BMI2_ACC_ODR_200HZ; + + /* Gravity range of the sensor (+/- 2G, 4G, 8G, 16G). */ + config[ACCEL].cfg.acc.range = BMI2_ACC_RANGE_2G; + + /* The bandwidth parameter is used to configure the number of sensor samples that are averaged + * if it is set to 2, then 2^(bandwidth parameter) samples + * are averaged, resulting in 4 averaged samples. + * Note1 : For more information, refer the datasheet. + * Note2 : A higher number of averaged samples will result in a lower noise level of the signal, but + * this has an adverse effect on the power consumed. + */ + config[ACCEL].cfg.acc.bwp = BMI2_ACC_NORMAL_AVG4; + + /* Enable the filter performance mode where averaging of samples + * will be done based on above set bandwidth and ODR. + * There are two modes + * 0 -> Ultra low power mode + * 1 -> High performance mode(Default) + * For more info refer datasheet. + */ + config[ACCEL].cfg.acc.filter_perf = BMI2_PERF_OPT_MODE; + + /* The user can change the following configuration parameters according to their requirement. */ + /* Set Output Data Rate */ + config[GYRO].cfg.gyr.odr = BMI2_GYR_ODR_200HZ; + + /* Gyroscope Angular Rate Measurement Range.By default the range is 2000dps. */ + config[GYRO].cfg.gyr.range = BMI2_GYR_RANGE_2000; + + /* Gyroscope bandwidth parameters. By default the gyro bandwidth is in normal mode. */ + config[GYRO].cfg.gyr.bwp = BMI2_GYR_NORMAL_MODE; + + /* Enable/Disable the noise performance mode for precision yaw rate sensing + * There are two modes + * 0 -> Ultra low power mode(Default) + * 1 -> High performance mode + */ + config[GYRO].cfg.gyr.noise_perf = BMI2_POWER_OPT_MODE; + + /* Enable/Disable the filter performance mode where averaging of samples + * will be done based on above set bandwidth and ODR. + * There are two modes + * 0 -> Ultra low power mode + * 1 -> High performance mode(Default) + */ + config[GYRO].cfg.gyr.filter_perf = BMI2_PERF_OPT_MODE; + + /* Set the accel and gyro configurations. */ + rslt = bmi2_set_sensor_config(config, 2, bmi2_dev); + bmi2_error_codes_print_result(rslt); + } + + return rslt; +} + +/*! + * @brief This function converts lsb to meter per second squared for 16 bit accelerometer at + * range 2G, 4G, 8G or 16G. + */ +static float lsb_to_mps2(int16_t val, float g_range, uint8_t bit_width) +{ + float half_scale = ((float)(1 << bit_width) / 2.0f); + + return (GRAVITY_EARTH * val * g_range) / half_scale; +} + +/*! + * @brief This function converts lsb to degree per second for 16 bit gyro at + * range 125, 250, 500, 1000 or 2000dps. + */ +static float lsb_to_dps(int16_t val, float dps, uint8_t bit_width) +{ + float half_scale = ((float)(1 << bit_width) / 2.0f); + + return (dps / ((half_scale) + BMI2_GYR_RANGE_2000)) * (val); +} diff --git a/examples/bmi270_maximum_fifo/common/common.c b/examples/bmi270_maximum_fifo/common/common.c new file mode 100644 index 0000000..afff37b --- /dev/null +++ b/examples/bmi270_maximum_fifo/common/common.c @@ -0,0 +1,372 @@ +/** + * Copyright (C) 2020 Bosch Sensortec GmbH. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include + +#include "coines.h" +#include "bmi2_defs.h" + +/******************************************************************************/ +/*! Macro definitions */ +#define BMI2XY_SHUTTLE_ID UINT16_C(0x1B8) + +/*! Macro that defines read write length */ +#define READ_WRITE_LEN UINT8_C(46) + +/******************************************************************************/ +/*! Static variable definition */ + +/*! Variable that holds the I2C device address or SPI chip selection */ +static uint8_t dev_addr; + +/******************************************************************************/ +/*! User interface functions */ + +/*! + * I2C read function map to COINES platform + */ +BMI2_INTF_RETURN_TYPE bmi2_i2c_read(uint8_t reg_addr, uint8_t *reg_data, uint32_t len, void *intf_ptr) +{ + uint8_t dev_addr = *(uint8_t*)intf_ptr; + + return coines_read_i2c(dev_addr, reg_addr, reg_data, (uint16_t)len); +} + +/*! + * I2C write function map to COINES platform + */ +BMI2_INTF_RETURN_TYPE bmi2_i2c_write(uint8_t reg_addr, const uint8_t *reg_data, uint32_t len, void *intf_ptr) +{ + uint8_t dev_addr = *(uint8_t*)intf_ptr; + + return coines_write_i2c(dev_addr, reg_addr, (uint8_t *)reg_data, (uint16_t)len); +} + +/*! + * SPI read function map to COINES platform + */ +BMI2_INTF_RETURN_TYPE bmi2_spi_read(uint8_t reg_addr, uint8_t *reg_data, uint32_t len, void *intf_ptr) +{ + uint8_t dev_addr = *(uint8_t*)intf_ptr; + + return coines_read_spi(dev_addr, reg_addr, reg_data, (uint16_t)len); +} + +/*! + * SPI write function map to COINES platform + */ +BMI2_INTF_RETURN_TYPE bmi2_spi_write(uint8_t reg_addr, const uint8_t *reg_data, uint32_t len, void *intf_ptr) +{ + uint8_t dev_addr = *(uint8_t*)intf_ptr; + + return coines_write_spi(dev_addr, reg_addr, (uint8_t *)reg_data, (uint16_t)len); +} + +/*! + * Delay function map to COINES platform + */ +void bmi2_delay_us(uint32_t period, void *intf_ptr) +{ + coines_delay_usec(period); +} + +/*! + * @brief Function to select the interface between SPI and I2C. + * Also to initialize coines platform + */ +int8_t bmi2_interface_init(struct bmi2_dev *bmi, uint8_t intf) +{ + int8_t rslt = BMI2_OK; + struct coines_board_info board_info; + + if (bmi != NULL) + { + int16_t result = coines_open_comm_intf(COINES_COMM_INTF_USB); + if (result < COINES_SUCCESS) + { + printf( + "\n Unable to connect with Application Board ! \n" " 1. Check if the board is connected and powered on. \n" " 2. Check if Application Board USB driver is installed. \n" + " 3. Check if board is in use by another application. (Insufficient permissions to access USB) \n"); + exit(result); + } + + result = coines_get_board_info(&board_info); + +#if defined(PC) + setbuf(stdout, NULL); +#endif + + if (result == COINES_SUCCESS) + { + if ((board_info.shuttle_id != BMI2XY_SHUTTLE_ID)) + { + printf("! Warning invalid sensor shuttle \n ," "This application will not support this sensor \n"); + exit(COINES_E_FAILURE); + } + } + + coines_set_shuttleboard_vdd_vddio_config(0, 0); + coines_delay_msec(100); + + /* Bus configuration : I2C */ + if (intf == BMI2_I2C_INTF) + { + printf("I2C Interface \n"); + + /* To initialize the user I2C function */ + dev_addr = BMI2_I2C_PRIM_ADDR; + bmi->intf = BMI2_I2C_INTF; + bmi->read = bmi2_i2c_read; + bmi->write = bmi2_i2c_write; + coines_config_i2c_bus(COINES_I2C_BUS_0, COINES_I2C_FAST_MODE); + } + /* Bus configuration : SPI */ + else if (intf == BMI2_SPI_INTF) + { + printf("SPI Interface \n"); + + /* To initialize the user SPI function */ + dev_addr = COINES_SHUTTLE_PIN_7; + bmi->intf = BMI2_SPI_INTF; + bmi->read = bmi2_spi_read; + bmi->write = bmi2_spi_write; + coines_config_spi_bus(COINES_SPI_BUS_0, COINES_SPI_SPEED_5_MHZ, COINES_SPI_MODE3); + coines_set_pin_config(COINES_SHUTTLE_PIN_7, COINES_PIN_DIRECTION_OUT, COINES_PIN_VALUE_HIGH); + } + + /* Assign device address to interface pointer */ + bmi->intf_ptr = &dev_addr; + + /* Configure delay in microseconds */ + bmi->delay_us = bmi2_delay_us; + + /* Configure max read/write length (in bytes) ( Supported length depends on target machine) */ + bmi->read_write_len = READ_WRITE_LEN; + + /* Assign to NULL to load the default config file. */ + bmi->config_file_ptr = NULL; + + coines_delay_usec(10000); + + coines_set_shuttleboard_vdd_vddio_config(3300, 3300); + + coines_delay_usec(10000); + } + else + { + rslt = BMI2_E_NULL_PTR; + } + + return rslt; + +} + +/*! + * @brief Prints the execution status of the APIs. + */ +void bmi2_error_codes_print_result(int8_t rslt) +{ + switch (rslt) + { + case BMI2_OK: + + /* Do nothing */ + break; + + case BMI2_W_FIFO_EMPTY: + printf("Warning [%d] : FIFO empty\r\n", rslt); + break; + case BMI2_W_PARTIAL_READ: + printf("Warning [%d] : FIFO partial read\r\n", rslt); + break; + case BMI2_E_NULL_PTR: + printf( + "Error [%d] : Null pointer error. It occurs when the user tries to assign value (not address) to a pointer," " which has been initialized to NULL.\r\n", + rslt); + break; + + case BMI2_E_COM_FAIL: + printf( + "Error [%d] : Communication failure error. It occurs due to read/write operation failure and also due " "to power failure during communication\r\n", + rslt); + break; + + case BMI2_E_DEV_NOT_FOUND: + printf("Error [%d] : Device not found error. It occurs when the device chip id is incorrectly read\r\n", + rslt); + break; + + case BMI2_E_INVALID_SENSOR: + printf( + "Error [%d] : Invalid sensor error. It occurs when there is a mismatch in the requested feature with the " "available one\r\n", + rslt); + break; + + case BMI2_E_SELF_TEST_FAIL: + printf( + "Error [%d] : Self-test failed error. It occurs when the validation of accel self-test data is " "not satisfied\r\n", + rslt); + break; + + case BMI2_E_INVALID_INT_PIN: + printf( + "Error [%d] : Invalid interrupt pin error. It occurs when the user tries to configure interrupt pins " "apart from INT1 and INT2\r\n", + rslt); + break; + + case BMI2_E_OUT_OF_RANGE: + printf( + "Error [%d] : Out of range error. It occurs when the data exceeds from filtered or unfiltered data from " "fifo and also when the range exceeds the maximum range for accel and gyro while performing FOC\r\n", + rslt); + break; + + case BMI2_E_ACC_INVALID_CFG: + printf( + "Error [%d] : Invalid Accel configuration error. It occurs when there is an error in accel configuration" " register which could be one among range, BW or filter performance in reg address 0x40\r\n", + rslt); + break; + + case BMI2_E_GYRO_INVALID_CFG: + printf( + "Error [%d] : Invalid Gyro configuration error. It occurs when there is a error in gyro configuration" "register which could be one among range, BW or filter performance in reg address 0x42\r\n", + rslt); + break; + + case BMI2_E_ACC_GYR_INVALID_CFG: + printf( + "Error [%d] : Invalid Accel-Gyro configuration error. It occurs when there is a error in accel and gyro" " configuration registers which could be one among range, BW or filter performance in reg address 0x40 " "and 0x42\r\n", + rslt); + break; + + case BMI2_E_CONFIG_LOAD: + printf( + "Error [%d] : Configuration load error. It occurs when failure observed while loading the configuration " "into the sensor\r\n", + rslt); + break; + + case BMI2_E_INVALID_PAGE: + printf( + "Error [%d] : Invalid page error. It occurs due to failure in writing the correct feature configuration " "from selected page\r\n", + rslt); + break; + + case BMI2_E_SET_APS_FAIL: + printf( + "Error [%d] : APS failure error. It occurs due to failure in write of advance power mode configuration " "register\r\n", + rslt); + break; + + case BMI2_E_AUX_INVALID_CFG: + printf( + "Error [%d] : Invalid AUX configuration error. It occurs when the auxiliary interface settings are not " "enabled properly\r\n", + rslt); + break; + + case BMI2_E_AUX_BUSY: + printf( + "Error [%d] : AUX busy error. It occurs when the auxiliary interface buses are engaged while configuring" " the AUX\r\n", + rslt); + break; + + case BMI2_E_REMAP_ERROR: + printf( + "Error [%d] : Remap error. It occurs due to failure in assigning the remap axes data for all the axes " "after change in axis position\r\n", + rslt); + break; + + case BMI2_E_GYR_USER_GAIN_UPD_FAIL: + printf( + "Error [%d] : Gyro user gain update fail error. It occurs when the reading of user gain update status " "fails\r\n", + rslt); + break; + + case BMI2_E_SELF_TEST_NOT_DONE: + printf( + "Error [%d] : Self-test not done error. It occurs when the self-test process is ongoing or not " "completed\r\n", + rslt); + break; + + case BMI2_E_INVALID_INPUT: + printf("Error [%d] : Invalid input error. It occurs when the sensor input validity fails\r\n", rslt); + break; + + case BMI2_E_INVALID_STATUS: + printf("Error [%d] : Invalid status error. It occurs when the feature/sensor validity fails\r\n", rslt); + break; + + case BMI2_E_CRT_ERROR: + printf("Error [%d] : CRT error. It occurs when the CRT test has failed\r\n", rslt); + break; + + case BMI2_E_ST_ALREADY_RUNNING: + printf( + "Error [%d] : Self-test already running error. It occurs when the self-test is already running and " "another has been initiated\r\n", + rslt); + break; + + case BMI2_E_CRT_READY_FOR_DL_FAIL_ABORT: + printf( + "Error [%d] : CRT ready for download fail abort error. It occurs when download in CRT fails due to wrong " "address location\r\n", + rslt); + break; + + case BMI2_E_DL_ERROR: + printf( + "Error [%d] : Download error. It occurs when write length exceeds that of the maximum burst length\r\n", + rslt); + break; + + case BMI2_E_PRECON_ERROR: + printf( + "Error [%d] : Pre-conditional error. It occurs when precondition to start the feature was not " "completed\r\n", + rslt); + break; + + case BMI2_E_ABORT_ERROR: + printf("Error [%d] : Abort error. It occurs when the device was shaken during CRT test\r\n", rslt); + break; + + case BMI2_E_WRITE_CYCLE_ONGOING: + printf( + "Error [%d] : Write cycle ongoing error. It occurs when the write cycle is already running and another " "has been initiated\r\n", + rslt); + break; + + case BMI2_E_ST_NOT_RUNING: + printf( + "Error [%d] : Self-test is not running error. It occurs when self-test running is disabled while it's " "running\r\n", + rslt); + break; + + case BMI2_E_DATA_RDY_INT_FAILED: + printf( + "Error [%d] : Data ready interrupt error. It occurs when the sample count exceeds the FOC sample limit " "and data ready status is not updated\r\n", + rslt); + break; + + case BMI2_E_INVALID_FOC_POSITION: + printf( + "Error [%d] : Invalid FOC position error. It occurs when average FOC data is obtained for the wrong" " axes\r\n", + rslt); + break; + + default: + printf("Error [%d] : Unknown error code\r\n", rslt); + break; + } +} + +/*! + * @brief Deinitializes coines platform + * + * @return void. + */ +void bmi2_coines_deinit(void) +{ + coines_close_comm_intf(COINES_COMM_INTF_USB); +} diff --git a/examples/bmi270_maximum_fifo/common/common.h b/examples/bmi270_maximum_fifo/common/common.h new file mode 100644 index 0000000..763983d --- /dev/null +++ b/examples/bmi270_maximum_fifo/common/common.h @@ -0,0 +1,122 @@ +/**\ + * Copyright (c) 2020 Bosch Sensortec GmbH. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + **/ + +#ifndef _COMMON_H +#define _COMMON_H + +/*! CPP guard */ +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include "bmi2.h" + +/*! + * @brief Function for reading the sensor's registers through I2C bus. + * + * @param[in] reg_addr : Register address. + * @param[out] reg_data : Pointer to the data buffer to store the read data. + * @param[in] length : No of bytes to read. + * @param[in] intf_ptr : Interface pointer + * + * @return Status of execution + * @retval = BMI2_INTF_RET_SUCCESS -> Success + * @retval != BMI2_INTF_RET_SUCCESS -> Failure Info + * + */ +BMI2_INTF_RETURN_TYPE bmi2_i2c_read(uint8_t reg_addr, uint8_t *reg_data, uint32_t len, void *intf_ptr); + +/*! + * @brief Function for writing the sensor's registers through I2C bus. + * + * @param[in] reg_addr : Register address. + * @param[in] reg_data : Pointer to the data buffer whose value is to be written. + * @param[in] length : No of bytes to write. + * @param[in] intf_ptr : Interface pointer + * + * @return Status of execution + * @retval = BMI2_INTF_RET_SUCCESS -> Success + * @retval != BMI2_INTF_RET_SUCCESS -> Failure Info + * + */ +BMI2_INTF_RETURN_TYPE bmi2_i2c_write(uint8_t reg_addr, const uint8_t *reg_data, uint32_t len, void *intf_ptr); + +/*! + * @brief Function for reading the sensor's registers through SPI bus. + * + * @param[in] reg_addr : Register address. + * @param[out] reg_data : Pointer to the data buffer to store the read data. + * @param[in] length : No of bytes to read. + * @param[in] intf_ptr : Interface pointer + * + * @return Status of execution + * @retval = BMI2_INTF_RET_SUCCESS -> Success + * @retval != BMI2_INTF_RET_SUCCESS -> Failure Info + * + */ +BMI2_INTF_RETURN_TYPE bmi2_spi_read(uint8_t reg_addr, uint8_t *reg_data, uint32_t len, void *intf_ptr); + +/*! + * @brief Function for writing the sensor's registers through SPI bus. + * + * @param[in] reg_addr : Register address. + * @param[in] reg_data : Pointer to the data buffer whose data has to be written. + * @param[in] length : No of bytes to write. + * @param[in] intf_ptr : Interface pointer + * + * @return Status of execution + * @retval = BMI2_INTF_RET_SUCCESS -> Success + * @retval != BMI2_INTF_RET_SUCCESS -> Failure Info + * + */ +BMI2_INTF_RETURN_TYPE bmi2_spi_write(uint8_t reg_addr, const uint8_t *reg_data, uint32_t len, void *intf_ptr); + +/*! + * @brief This function provides the delay for required time (Microsecond) as per the input provided in some of the + * APIs. + * + * @param[in] period_us : The required wait time in microsecond. + * @param[in] intf_ptr : Interface pointer + * + * @return void. + * + */ +void bmi2_delay_us(uint32_t period, void *intf_ptr); + +/*! + * @brief Function to select the interface between SPI and I2C. + * + * @param[in] bma : Structure instance of bmi2_dev + * @param[in] intf : Interface selection parameter + * + * @return Status of execution + * @retval 0 -> Success + * @retval < 0 -> Failure Info + */ +int8_t bmi2_interface_init(struct bmi2_dev *bma, uint8_t intf); + +/*! + * @brief Prints the execution status of the APIs. + * + * @param[in] rslt : Error code returned by the API whose execution status has to be printed. + * + * @return void. + */ +void bmi2_error_codes_print_result(int8_t rslt); + +/*! + * @brief Deinitializes coines platform + * + * @return void. + */ +void bmi2_coines_deinit(void); + +#ifdef __cplusplus +} +#endif /* End of CPP guard */ + +#endif /* _COMMON_H */ diff --git a/examples/bmi270_maximum_fifo/component_retrim/Makefile b/examples/bmi270_maximum_fifo/component_retrim/Makefile new file mode 100644 index 0000000..0729972 --- /dev/null +++ b/examples/bmi270_maximum_fifo/component_retrim/Makefile @@ -0,0 +1,18 @@ +COINES_INSTALL_PATH ?= ../../../.. + +EXAMPLE_FILE ?= component_retrim.c + +API_LOCATION ?= ../.. + +COMMON_LOCATION ?= .. + +C_SRCS += \ +$(API_LOCATION)/bmi2.c \ +$(API_LOCATION)/bmi270_maximum_fifo.c \ +$(COMMON_LOCATION)/common/common.c + +INCLUDEPATHS += \ +$(API_LOCATION) \ +$(COMMON_LOCATION)/common + +include $(COINES_INSTALL_PATH)/coines.mk \ No newline at end of file diff --git a/examples/bmi270_maximum_fifo/component_retrim/component_retrim.c b/examples/bmi270_maximum_fifo/component_retrim/component_retrim.c new file mode 100644 index 0000000..ea24ab2 --- /dev/null +++ b/examples/bmi270_maximum_fifo/component_retrim/component_retrim.c @@ -0,0 +1,52 @@ +/**\ + * Copyright (c) 2020 Bosch Sensortec GmbH. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + **/ + +/******************************************************************************/ +/*! Header Files */ +#include +#include "bmi270_maximum_fifo.h" +#include "common.h" + +/******************************************************************************/ +/*! Functions */ + +/* This function starts the execution of program. */ +int main(void) +{ + /* Sensor initialization configuration. */ + struct bmi2_dev bmi2_dev; + + /* Status of api are returned to this variable. */ + int8_t rslt; + + /* Interface reference is given as a parameter + * For I2C : BMI2_I2C_INTF + * For SPI : BMI2_SPI_INTF + */ + rslt = bmi2_interface_init(&bmi2_dev, BMI2_I2C_INTF); + bmi2_error_codes_print_result(rslt); + + /* Initialize bmi270_maximum_fifo. */ + rslt = bmi270_maximum_fifo_init(&bmi2_dev); + bmi2_error_codes_print_result(rslt); + + if (rslt == BMI2_OK) + { + /* This API runs the CRT process. */ + rslt = bmi2_do_crt(&bmi2_dev); + bmi2_error_codes_print_result(rslt); + + /* Do not move the board while doing CRT. If so, it will throw an abort error. */ + if (rslt == BMI2_OK) + { + printf("CRT successfully completed."); + } + } + + bmi2_coines_deinit(); + + return rslt; +} diff --git a/examples/bmi270_maximum_fifo/fifo_watermark_header_mode/Makefile b/examples/bmi270_maximum_fifo/fifo_watermark_header_mode/Makefile new file mode 100644 index 0000000..131538f --- /dev/null +++ b/examples/bmi270_maximum_fifo/fifo_watermark_header_mode/Makefile @@ -0,0 +1,18 @@ +COINES_INSTALL_PATH ?= ../../../.. + +EXAMPLE_FILE ?= fifo_watermark_header_mode.c + +API_LOCATION ?= ../.. + +COMMON_LOCATION ?= .. + +C_SRCS += \ +$(API_LOCATION)/bmi2.c \ +$(API_LOCATION)/bmi270_maximum_fifo.c \ +$(COMMON_LOCATION)/common/common.c + +INCLUDEPATHS += \ +$(API_LOCATION) \ +$(COMMON_LOCATION)/common + +include $(COINES_INSTALL_PATH)/coines.mk \ No newline at end of file diff --git a/examples/bmi270/generic/fifo_watermark_header_mode.c b/examples/bmi270_maximum_fifo/fifo_watermark_header_mode/fifo_watermark_header_mode.c similarity index 83% rename from examples/bmi270/generic/fifo_watermark_header_mode.c rename to examples/bmi270_maximum_fifo/fifo_watermark_header_mode/fifo_watermark_header_mode.c index a5d7668..f031379 100644 --- a/examples/bmi270/generic/fifo_watermark_header_mode.c +++ b/examples/bmi270_maximum_fifo/fifo_watermark_header_mode/fifo_watermark_header_mode.c @@ -1,317 +1,335 @@ -/**\ - * Copyright (c) 2020 Bosch Sensortec GmbH. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - **/ - -/******************************************************************************/ -/*! Header Files */ -#include -#include "bmi2.h" -#include "bmi270.h" -#include "bmi2_common.h" - -/******************************************************************************/ -/*! Macros */ - -/*! Buffer size allocated to store raw FIFO data */ -#define BMI270_FIFO_RAW_DATA_BUFFER_SIZE UINT16_C(2048) - -/*! Length of data to be read from FIFO */ -#define BMI270_FIFO_RAW_DATA_USER_LENGTH UINT16_C(2048) - -/*! Number of accel frames to be extracted from FIFO */ - -/*! - * Calculation: - * fifo_watermark_level = 650, accel_frame_len = 6, gyro_frame_len = 6 header_byte = 1. - * fifo_accel_frame_count = (650 / (6 + 6 + 1 )) = 50 frames - * NOTE: Extra frames are read in order to get sensor time - */ -#define BMI270_FIFO_ACCEL_FRAME_COUNT UINT8_C(55) - -/*! Number of gyro frames to be extracted from FIFO */ -#define BMI270_FIFO_GYRO_FRAME_COUNT UINT8_C(55) - -/*! Setting a watermark level in FIFO */ -#define BMI270_FIFO_WATERMARK_LEVEL UINT16_C(650) - -/*! Macro to read sensortime byte in FIFO */ -#define SENSORTIME_OVERHEAD_BYTE UINT8_C(3) - -/******************************************************************************/ -/*! Static Function Declaration */ - -/*! - * @brief This internal API is used to set configurations for accel and gyro. - * @param[in] dev : Structure instance of bmi2_dev. - * @return Status of execution. - */ -static int8_t set_accel_gyro_config(struct bmi2_dev *dev); - -/******************************************************************************/ - -/* This function starts the execution of program. */ -int main(void) -{ - - /* Status of api are returned to this variable. */ - int8_t rslt; - - /* Variable to define device address. */ - uint8_t dev_addr; - - /* Variable to store the available frame length count in FIFO */ - uint8_t frame_count; - - /* Variable to index bytes. */ - uint16_t index = 0; - - uint16_t fifo_length = 0; - - uint16_t accel_frame_length; - - uint16_t gyro_frame_length; - - /* To read sensortime, extra 3 bytes are added to fifo buffer */ - uint16_t fifo_buffer_size = BMI270_FIFO_RAW_DATA_BUFFER_SIZE + SENSORTIME_OVERHEAD_BYTE; - - /* Number of bytes of FIFO data. */ - uint8_t fifo_data[fifo_buffer_size]; - - /* Sensor initialization configuration. */ - struct bmi2_dev bmi2_dev; - - /* Array of accelerometer frames -> Total bytes = - * 55 * (6 axes bytes) = 330 bytes */ - struct bmi2_sens_axes_data fifo_accel_data[BMI270_FIFO_ACCEL_FRAME_COUNT] = { 0 }; - - /* Array of gyro frames -> Total bytes = - * 55 * (6 axes bytes) = 330 bytes */ - struct bmi2_sens_axes_data fifo_gyro_data[BMI270_FIFO_GYRO_FRAME_COUNT] = { 0 }; - - /* Initialize FIFO frame structure. */ - struct bmi2_fifo_frame fifoframe = { 0 }; - - /* Accel and gyro sensor are listed in array. */ - uint8_t sensor_sel[2] = { BMI2_ACCEL, BMI2_GYRO }; - - /* Variable to get fifo water-mark interrupt status. */ - uint16_t int_status = 0; - - uint16_t watermark = 0; - - /* Initialize the dev structure */ - rslt = bmi2_interface_selection(&bmi2_dev); - bmi2_error_codes_print_result(rslt); - - /* Initialize bmi270. */ - rslt = bmi270_init(&bmi2_dev); - bmi2_error_codes_print_result(rslt); - - /* Enable accel and gyro sensor. */ - rslt = bmi2_sensor_enable(sensor_sel, 2, &bmi2_dev); - bmi2_error_codes_print_result(rslt); - - /* Configuration settings for accel and gyro. */ - rslt = set_accel_gyro_config(&bmi2_dev); - bmi2_error_codes_print_result(rslt); - - /* Before setting FIFO, disable the advance power save mode. */ - rslt = bmi2_set_adv_power_save(BMI2_DISABLE, &bmi2_dev); - bmi2_error_codes_print_result(rslt); - - /* Initially disable all configurations in fifo. */ - rslt = bmi2_set_fifo_config(BMI2_FIFO_ALL_EN, BMI2_DISABLE, &bmi2_dev); - bmi2_error_codes_print_result(rslt); - - /* Update FIFO structure. */ - /* Mapping the buffer to store the fifo data. */ - fifoframe.data = fifo_data; - - /* Length of FIFO frame. */ - /* To read sensortime, extra 3 bytes are added to fifo user length. */ - fifoframe.length = BMI270_FIFO_RAW_DATA_USER_LENGTH + SENSORTIME_OVERHEAD_BYTE; - - /* Set FIFO configuration by enabling accel, gyro and timestamp. - * NOTE 1: The header mode is enabled by default. - * NOTE 2: By default the FIFO operating mode is FIFO mode. - * NOTE 3: Sensortime is enabled by default */ - printf("FIFO is configured in header mode\n"); - rslt = bmi2_set_fifo_config(BMI2_FIFO_ACC_EN | BMI2_FIFO_GYR_EN, BMI2_ENABLE, &bmi2_dev); - bmi2_error_codes_print_result(rslt); - - /* FIFO water-mark interrupt is enabled. */ - fifoframe.data_int_map = BMI2_FWM_INT; - - /* Map water-mark interrupt to the required interrupt pin. */ - rslt = bmi2_map_data_int(fifoframe.data_int_map, BMI2_INT1, &bmi2_dev); - bmi2_error_codes_print_result(rslt); - - /* Set water-mark level. */ - fifoframe.wm_lvl = BMI270_FIFO_WATERMARK_LEVEL; - - /* Set the water-mark level if water-mark interrupt is mapped. */ - rslt = bmi2_set_fifo_wm(fifoframe.wm_lvl, &bmi2_dev); - bmi2_error_codes_print_result(rslt); - - rslt = bmi2_get_fifo_wm(&watermark, &bmi2_dev); - bmi2_error_codes_print_result(rslt); - printf("\nFIFO watermark level is %d\n", watermark); - while (1) - { - - /* Read FIFO data on interrupt. */ - rslt = bmi2_get_int_status(&int_status, &bmi2_dev); - bmi2_error_codes_print_result(rslt); - - /* To check the status of FIFO watermark interrupt. */ - if ((rslt == BMI2_OK) && (int_status & BMI2_FWM_INT_STATUS_MASK)) - { - printf("\nWatermark interrupt occurred\n"); - - rslt = bmi2_get_fifo_length(&fifo_length, &bmi2_dev); - bmi2_error_codes_print_result(rslt); - - accel_frame_length = BMI270_FIFO_ACCEL_FRAME_COUNT; - gyro_frame_length = BMI270_FIFO_GYRO_FRAME_COUNT; - - printf("\nFIFO data bytes available : %d \n", fifo_length); - printf("\nFIFO data bytes requested : %d \n", fifoframe.length); - - /* Read FIFO data. */ - rslt = bmi2_read_fifo_data(&fifoframe, &bmi2_dev); - bmi2_error_codes_print_result(rslt); - - if (rslt == BMI2_OK) - { - printf("\nFIFO accel frames requested : %d \n", accel_frame_length); - - /* Parse the FIFO data to extract accelerometer data from the FIFO buffer. */ - rslt = bmi2_extract_accel(fifo_accel_data, &accel_frame_length, &fifoframe, &bmi2_dev); - printf("\nFIFO accel frames extracted : %d \n", accel_frame_length); - - printf("\nFIFO gyro frames requested : %d \n", gyro_frame_length); - - /* Parse the FIFO data to extract gyro data from the FIFO buffer. */ - rslt = bmi2_extract_gyro(fifo_gyro_data, &gyro_frame_length, &fifoframe, &bmi2_dev); - printf("\nFIFO gyro frames extracted : %d \n", gyro_frame_length); - - /* Calculating the frame count from the available bytes in FIFO - * frame_length = (available_fifo_bytes / (acc_frame_len + gyro_frame_len + header_byte)) */ - frame_count = (fifo_length / (BMI2_FIFO_ACC_GYR_LENGTH + 1)); - printf("\nAvailable frame count from available bytes: %d\n", frame_count); - - printf("\nExracted accel frames\n"); - - /* Print the parsed accelerometer data from the FIFO buffer. */ - for (index = 0; index < frame_count; index++) - { - printf("ACCEL[%d] X : %d\t Y : %d\t Z : %d\n", index, fifo_accel_data[index].x, - fifo_accel_data[index].y, fifo_accel_data[index].z); - } - - printf("\nExtracted gyro frames\n"); - - /* Print the parsed gyro data from the FIFO buffer. */ - for (index = 0; index < frame_count; index++) - { - printf("GYRO[%d] X : %d\t Y : %d\t Z : %d\n", - index, - fifo_gyro_data[index].x, - fifo_gyro_data[index].y, - fifo_gyro_data[index].z); - } - - /* Print control frames like sensor time and skipped frame count. */ - printf("Skipped frame count = %d\n", fifoframe.skipped_frame_count); - printf("Sensor time = %lu\r\n", fifoframe.sensor_time); - } - - break; - } - } - - return rslt; -} - -/*! - * @brief This internal API is used to set configurations for accel and gyro. - */ -static int8_t set_accel_gyro_config(struct bmi2_dev *dev) -{ - - /* Status of api are returned to this variable. */ - int8_t rslt; - - /* Structure to define accel and gyro configurations. */ - struct bmi2_sens_config config[2]; - - /* Configure the type of feature. */ - config[0].type = BMI2_ACCEL; - config[1].type = BMI2_GYRO; - - /* Get default configurations for the type of feature selected. */ - rslt = bmi2_get_sensor_config(config, 2, dev); - bmi2_error_codes_print_result(rslt); - - if (rslt == BMI2_OK) - { - /* NOTE: The user can change the following configuration parameters according to their requirement. */ - /* Accel configuration settings. */ - /* Output Data Rate. By default ODR is set as 100Hz for accel. */ - config[0].cfg.acc.odr = BMI2_ACC_ODR_100HZ; - - /* Gravity range of the sensor (+/- 2G, 4G, 8G, 16G). */ - config[0].cfg.acc.range = BMI2_ACC_RANGE_2G; - - /* The bandwidth parameter is used to configure the number of sensor samples that are averaged - * if it is set to 2, then 2^(bandwidth parameter) samples - * are averaged, resulting in 4 averaged samples - * Note1 : For more information, refer the datasheet. - * Note2 : A higher number of averaged samples will result in a lower noise level of the signal, but - * this has an adverse effect on the power consumed. - */ - config[0].cfg.acc.bwp = BMI2_ACC_NORMAL_AVG4; - - /* Enable the filter performance mode where averaging of samples - * will be done based on above set bandwidth and ODR. - * There are two modes - * 0 -> Ultra low power mode - * 1 -> High performance mode(Default) - * For more info refer datasheet. - */ - config[0].cfg.acc.filter_perf = BMI2_PERF_OPT_MODE; - - /* Gyro configuration settings. */ - /* Output data Rate. Default ODR is 200Hz, setting to 100Hz. */ - config[1].cfg.gyr.odr = BMI2_GYR_ODR_100HZ; - - /* Gyroscope Angular Rate Measurement Range.By default the range is 2000dps. */ - config[1].cfg.gyr.range = BMI2_GYR_RANGE_2000; - - /* Gyroscope Bandwidth parameters. By default the gyro bandwidth is in normal mode. */ - config[1].cfg.gyr.bwp = BMI2_GYR_NORMAL_MODE; - - /* Enable/Disable the noise performance mode for precision yaw rate sensing - * There are two modes - * 0 -> Ultra low power mode(Default) - * 1 -> High performance mode - */ - config[1].cfg.gyr.noise_perf = BMI2_POWER_OPT_MODE; - - /* Enable/Disable the filter performance mode where averaging of samples - * will be done based on above set bandwidth and ODR. - * There are two modes - * 0 -> Ultra low power mode - * 1 -> High performance mode(Default) - */ - config[1].cfg.gyr.filter_perf = BMI2_PERF_OPT_MODE; - - /* Set new configurations. */ - rslt = bmi2_set_sensor_config(config, 2, dev); - bmi2_error_codes_print_result(rslt); - } - - return rslt; -} +/**\ + * Copyright (c) 2020 Bosch Sensortec GmbH. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + **/ + +/******************************************************************************/ +/*! Header Files */ +#include +#include "bmi270_maximum_fifo.h" +#include "common.h" + +/******************************************************************************/ +/*! Macros */ + +/*! Buffer size allocated to store raw FIFO data */ +#define BMI2_FIFO_RAW_DATA_BUFFER_SIZE UINT16_C(2048) + +/*! Length of data to be read from FIFO */ +#define BMI2_FIFO_RAW_DATA_USER_LENGTH UINT16_C(2048) + +/*! Number of accel frames to be extracted from FIFO */ + +/*! + * Calculation: + * fifo_watermark_level = 650, accel_frame_len = 6, gyro_frame_len = 6 header_byte = 1. + * fifo_accel_frame_count = (650 / (6 + 6 + 1 )) = 50 frames + * NOTE: Extra frames are read in order to get sensor time + */ +#define BMI2_FIFO_ACCEL_FRAME_COUNT UINT8_C(55) + +/*! Number of gyro frames to be extracted from FIFO */ +#define BMI2_FIFO_GYRO_FRAME_COUNT UINT8_C(55) + +/*! Setting a watermark level in FIFO */ +#define BMI270_FIFO_WATERMARK_LEVEL UINT16_C(650) + +/*! Macro to read sensortime byte in FIFO */ +#define SENSORTIME_OVERHEAD_BYTE UINT8_C(3) + +/******************************************************************************/ +/*! Static Function Declaration */ + +/*! + * @brief This internal API is used to set configurations for accel and gyro. + * @param[in] dev : Structure instance of bmi2_dev. + * @return Status of execution. + */ +static int8_t set_accel_gyro_config(struct bmi2_dev *dev); + +/******************************************************************************/ +/*! Functions */ + +/* This function starts the execution of program. */ +int main(void) +{ + /* Status of api are returned to this variable. */ + int8_t rslt; + + /* Variable to store the available frame length count in FIFO */ + uint8_t frame_count; + + /* Variable to index bytes. */ + uint16_t index = 0; + + uint16_t fifo_length = 0; + + uint16_t accel_frame_length; + + uint16_t gyro_frame_length; + + uint8_t try = 1; + + /* To read sensortime, extra 3 bytes are added to fifo buffer */ + uint16_t fifo_buffer_size = BMI2_FIFO_RAW_DATA_BUFFER_SIZE + SENSORTIME_OVERHEAD_BYTE; + + /* Number of bytes of FIFO data. */ + uint8_t fifo_data[fifo_buffer_size]; + + /* Sensor initialization configuration. */ + struct bmi2_dev bmi2_dev; + + /* Array of accelerometer frames -> Total bytes = + * 55 * (6 axes bytes) = 330 bytes */ + struct bmi2_sens_axes_data fifo_accel_data[BMI2_FIFO_ACCEL_FRAME_COUNT] = { { 0 } }; + + /* Array of gyro frames -> Total bytes = + * 55 * (6 axes bytes) = 330 bytes */ + struct bmi2_sens_axes_data fifo_gyro_data[BMI2_FIFO_GYRO_FRAME_COUNT] = { { 0 } }; + + /* Initialize FIFO frame structure. */ + struct bmi2_fifo_frame fifoframe = { 0 }; + + /* Accel and gyro sensor are listed in array. */ + uint8_t sensor_sel[2] = { BMI2_ACCEL, BMI2_GYRO }; + + /* Variable to get fifo water-mark interrupt status. */ + uint16_t int_status = 0; + + uint16_t watermark = 0; + + /* Interface reference is given as a parameter + * For I2C : BMI2_I2C_INTF + * For SPI : BMI2_SPI_INTF + */ + rslt = bmi2_interface_init(&bmi2_dev, BMI2_I2C_INTF); + bmi2_error_codes_print_result(rslt); + + /* Initialize bmi270_maximum_fifo. */ + rslt = bmi270_maximum_fifo_init(&bmi2_dev); + bmi2_error_codes_print_result(rslt); + + /* Enable accel and gyro sensor. */ + rslt = bmi2_sensor_enable(sensor_sel, 2, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + /* Configuration settings for accel and gyro. */ + rslt = set_accel_gyro_config(&bmi2_dev); + bmi2_error_codes_print_result(rslt); + + /* Before setting FIFO, disable the advance power save mode. */ + rslt = bmi2_set_adv_power_save(BMI2_DISABLE, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + /* Initially disable all configurations in fifo. */ + rslt = bmi2_set_fifo_config(BMI2_FIFO_ALL_EN, BMI2_DISABLE, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + /* Update FIFO structure. */ + /* Mapping the buffer to store the fifo data. */ + fifoframe.data = fifo_data; + + /* Length of FIFO frame. */ + /* To read sensortime, extra 3 bytes are added to fifo user length. */ + fifoframe.length = BMI2_FIFO_RAW_DATA_USER_LENGTH + SENSORTIME_OVERHEAD_BYTE; + + /* Set FIFO configuration by enabling accel, gyro and timestamp. + * NOTE 1: The header mode is enabled by default. + * NOTE 2: By default the FIFO operating mode is FIFO mode. + * NOTE 3: Sensortime is enabled by default */ + printf("FIFO is configured in header mode\n"); + rslt = bmi2_set_fifo_config(BMI2_FIFO_ACC_EN | BMI2_FIFO_GYR_EN, BMI2_ENABLE, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + /* FIFO water-mark interrupt is enabled. */ + fifoframe.data_int_map = BMI2_FWM_INT; + + /* Map water-mark interrupt to the required interrupt pin. */ + rslt = bmi2_map_data_int(fifoframe.data_int_map, BMI2_INT1, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + /* Set water-mark level. */ + fifoframe.wm_lvl = BMI270_FIFO_WATERMARK_LEVEL; + + /* Set the water-mark level if water-mark interrupt is mapped. */ + rslt = bmi2_set_fifo_wm(fifoframe.wm_lvl, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + rslt = bmi2_get_fifo_wm(&watermark, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + printf("\nFIFO watermark level is %d\n", watermark); + + while (try <= 10) + { + /* Read FIFO data on interrupt. */ + rslt = bmi2_get_int_status(&int_status, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + /* To check the status of FIFO watermark interrupt. */ + if ((rslt == BMI2_OK) && (int_status & BMI2_FWM_INT_STATUS_MASK)) + { + printf("\nIteration : %d\n", try); + + printf("\nWatermark interrupt occurred\n"); + + rslt = bmi2_get_fifo_length(&fifo_length, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + accel_frame_length = BMI2_FIFO_ACCEL_FRAME_COUNT; + gyro_frame_length = BMI2_FIFO_GYRO_FRAME_COUNT; + + printf("\nFIFO data bytes available : %d \n", fifo_length); + printf("\nFIFO data bytes requested : %d \n", fifoframe.length); + + /* Read FIFO data. */ + rslt = bmi2_read_fifo_data(&fifoframe, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + /* Read FIFO data on interrupt. */ + rslt = bmi2_get_int_status(&int_status, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + if (rslt == BMI2_OK) + { + printf("\nFIFO accel frames requested : %d \n", accel_frame_length); + + /* Parse the FIFO data to extract accelerometer data from the FIFO buffer. */ + rslt = bmi2_extract_accel(fifo_accel_data, &accel_frame_length, &fifoframe, &bmi2_dev); + printf("\nFIFO accel frames extracted : %d \n", accel_frame_length); + + printf("\nFIFO gyro frames requested : %d \n", gyro_frame_length); + + /* Parse the FIFO data to extract gyro data from the FIFO buffer. */ + rslt = bmi2_extract_gyro(fifo_gyro_data, &gyro_frame_length, &fifoframe, &bmi2_dev); + printf("\nFIFO gyro frames extracted : %d \n", gyro_frame_length); + + /* Calculating the frame count from the available bytes in FIFO + * frame_length = (available_fifo_bytes / (acc_frame_len + gyro_frame_len + header_byte)) */ + frame_count = (fifo_length / (BMI2_FIFO_ACC_GYR_LENGTH + 1)); + printf("\nAvailable frame count from available bytes: %d\n", frame_count); + + printf("\nExracted accel frames\n"); + + if (accel_frame_length > frame_count) + { + accel_frame_length = frame_count; + } + + /* Print the parsed accelerometer data from the FIFO buffer. */ + for (index = 0; index < accel_frame_length; index++) + { + printf("ACCEL[%d] X : %d\t Y : %d\t Z : %d\n", index, fifo_accel_data[index].x, + fifo_accel_data[index].y, fifo_accel_data[index].z); + } + + printf("\nExtracted gyro frames\n"); + + if (gyro_frame_length > frame_count) + { + gyro_frame_length = frame_count; + } + + /* Print the parsed gyro data from the FIFO buffer. */ + for (index = 0; index < gyro_frame_length; index++) + { + printf("GYRO[%d] X : %d\t Y : %d\t Z : %d\n", + index, + fifo_gyro_data[index].x, + fifo_gyro_data[index].y, + fifo_gyro_data[index].z); + } + + /* Print control frames like sensor time and skipped frame count. */ + printf("Skipped frame count = %d\n", fifoframe.skipped_frame_count); + printf("Sensor time = %lu\r\n", fifoframe.sensor_time); + + try++; + } + } + } + + bmi2_coines_deinit(); + + return rslt; +} + +/*! + * @brief This internal API is used to set configurations for accel and gyro. + */ +static int8_t set_accel_gyro_config(struct bmi2_dev *dev) +{ + /* Status of api are returned to this variable. */ + int8_t rslt; + + /* Structure to define accel and gyro configurations. */ + struct bmi2_sens_config config[2]; + + /* Configure the type of feature. */ + config[0].type = BMI2_ACCEL; + config[1].type = BMI2_GYRO; + + /* Get default configurations for the type of feature selected. */ + rslt = bmi2_get_sensor_config(config, 2, dev); + bmi2_error_codes_print_result(rslt); + + if (rslt == BMI2_OK) + { + /* NOTE: The user can change the following configuration parameters according to their requirement. */ + /* Accel configuration settings. */ + /* Set Output Data Rate */ + config[0].cfg.acc.odr = BMI2_ACC_ODR_25HZ; + + /* Gravity range of the sensor (+/- 2G, 4G, 8G, 16G). */ + config[0].cfg.acc.range = BMI2_ACC_RANGE_2G; + + /* The bandwidth parameter is used to configure the number of sensor samples that are averaged + * if it is set to 2, then 2^(bandwidth parameter) samples + * are averaged, resulting in 4 averaged samples + * Note1 : For more information, refer the datasheet. + * Note2 : A higher number of averaged samples will result in a lower noise level of the signal, but + * this has an adverse effect on the power consumed. + */ + config[0].cfg.acc.bwp = BMI2_ACC_NORMAL_AVG4; + + /* Enable the filter performance mode where averaging of samples + * will be done based on above set bandwidth and ODR. + * There are two modes + * 0 -> Ultra low power mode + * 1 -> High performance mode(Default) + * For more info refer datasheet. + */ + config[0].cfg.acc.filter_perf = BMI2_PERF_OPT_MODE; + + /* Gyro configuration settings. */ + /* Set Output Data Rate */ + config[1].cfg.gyr.odr = BMI2_GYR_ODR_25HZ; + + /* Gyroscope Angular Rate Measurement Range.By default the range is 2000dps. */ + config[1].cfg.gyr.range = BMI2_GYR_RANGE_2000; + + /* Gyroscope Bandwidth parameters. By default the gyro bandwidth is in normal mode. */ + config[1].cfg.gyr.bwp = BMI2_GYR_NORMAL_MODE; + + /* Enable/Disable the noise performance mode for precision yaw rate sensing + * There are two modes + * 0 -> Ultra low power mode(Default) + * 1 -> High performance mode + */ + config[1].cfg.gyr.noise_perf = BMI2_POWER_OPT_MODE; + + /* Enable/Disable the filter performance mode where averaging of samples + * will be done based on above set bandwidth and ODR. + * There are two modes + * 0 -> Ultra low power mode + * 1 -> High performance mode(Default) + */ + config[1].cfg.gyr.filter_perf = BMI2_PERF_OPT_MODE; + + /* Set new configurations. */ + rslt = bmi2_set_sensor_config(config, 2, dev); + bmi2_error_codes_print_result(rslt); + } + + return rslt; +} diff --git a/examples/bmi270_maximum_fifo/fifo_watermark_headerless_mode/Makefile b/examples/bmi270_maximum_fifo/fifo_watermark_headerless_mode/Makefile new file mode 100644 index 0000000..9790a92 --- /dev/null +++ b/examples/bmi270_maximum_fifo/fifo_watermark_headerless_mode/Makefile @@ -0,0 +1,18 @@ +COINES_INSTALL_PATH ?= ../../../.. + +EXAMPLE_FILE ?= fifo_watermark_headerless_mode.c + +API_LOCATION ?= ../.. + +COMMON_LOCATION ?= .. + +C_SRCS += \ +$(API_LOCATION)/bmi2.c \ +$(API_LOCATION)/bmi270_maximum_fifo.c \ +$(COMMON_LOCATION)/common/common.c + +INCLUDEPATHS += \ +$(API_LOCATION) \ +$(COMMON_LOCATION)/common + +include $(COINES_INSTALL_PATH)/coines.mk \ No newline at end of file diff --git a/examples/bmi270/generic/fifo_watermark_headerless_mode.c b/examples/bmi270_maximum_fifo/fifo_watermark_headerless_mode/fifo_watermark_headerless_mode.c similarity index 83% rename from examples/bmi270/generic/fifo_watermark_headerless_mode.c rename to examples/bmi270_maximum_fifo/fifo_watermark_headerless_mode/fifo_watermark_headerless_mode.c index b29ac49..541ff11 100644 --- a/examples/bmi270/generic/fifo_watermark_headerless_mode.c +++ b/examples/bmi270_maximum_fifo/fifo_watermark_headerless_mode/fifo_watermark_headerless_mode.c @@ -1,309 +1,331 @@ -/**\ - * Copyright (c) 2020 Bosch Sensortec GmbH. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - **/ - -/******************************************************************************/ -/*! Header Files */ -#include -#include "bmi2.h" -#include "bmi270.h" -#include "bmi2_common.h" - -/******************************************************************************/ -/*! Macros */ - -/*! Buffer size allocated to store raw FIFO data */ -#define BMI270_FIFO_RAW_DATA_BUFFER_SIZE UINT16_C(2048) - -/*! Length of data to be read from FIFO */ -#define BMI270_FIFO_RAW_DATA_USER_LENGTH UINT16_C(2048) - -/*! Number of accel frames to be extracted from FIFO */ - -/*! - * Calculation: - * fifo_watermark_level = 650, accel_frame_len = 6, gyro_frame_len = 6. - * fifo_accel_frame_count = (650 / (6 + 6 )) = 50 frames - */ -#define BMI270_FIFO_ACCEL_FRAME_COUNT UINT8_C(50) - -/*! Number of gyro frames to be extracted from FIFO */ -#define BMI270_FIFO_GYRO_FRAME_COUNT UINT8_C(50) - -/*! Setting a watermark level in FIFO */ -#define BMI270_FIFO_WATERMARK_LEVEL UINT16_C(650) - -/******************************************************************************/ -/*! Static Function Declaration */ - -/*! - * @brief This internal API is used to set configurations for accel and gyro. - * @param[in] dev : Structure instance of bmi2_dev. - * @return Status of execution. - */ -static int8_t set_accel_gyro_config(struct bmi2_dev *dev); - -/******************************************************************************/ - -/* This function starts the execution of program. */ -int main(void) -{ - - /* Status of api are returned to this variable. */ - int8_t rslt; - - /* Variable to index bytes. */ - uint16_t index = 0; - - /* Variable to store the available frame length count in FIFO */ - uint8_t frame_count; - - uint16_t fifo_length = 0; - - uint16_t accel_frame_length; - - uint16_t gyro_frame_length; - - /* Number of bytes of FIFO data. */ - uint8_t fifo_data[BMI270_FIFO_RAW_DATA_BUFFER_SIZE] = { 0 }; - - /* Sensor initialization configuration. */ - struct bmi2_dev bmi2_dev; - - /* Array of accelerometer frames -> Total bytes = - * 50 * (6 axes bytes) = 300 bytes */ - struct bmi2_sens_axes_data fifo_accel_data[BMI270_FIFO_ACCEL_FRAME_COUNT] = { 0 }; - - /* Array of gyro frames -> Total bytes = - * 50 * (6 axes bytes) = 300 bytes */ - struct bmi2_sens_axes_data fifo_gyro_data[BMI270_FIFO_GYRO_FRAME_COUNT] = { 0 }; - - /* Initialize FIFO frame structure. */ - struct bmi2_fifo_frame fifoframe = { 0 }; - - /* Accel and gyro sensor are listed in array. */ - uint8_t sensor_sel[2] = { BMI2_ACCEL, BMI2_GYRO }; - - /* Variable to get fifo water-mark interrupt status. */ - uint16_t int_status = 0; - - uint16_t watermark = 0; - - /* Initialize the dev structure */ - rslt = bmi2_interface_selection(&bmi2_dev); - bmi2_error_codes_print_result(rslt); - - /* Initialize bmi270. */ - rslt = bmi270_init(&bmi2_dev); - bmi2_error_codes_print_result(rslt); - - /* Enable accel and gyro sensor. */ - rslt = bmi2_sensor_enable(sensor_sel, 2, &bmi2_dev); - bmi2_error_codes_print_result(rslt); - - /* Configuration settings for accel and gyro. */ - rslt = set_accel_gyro_config(&bmi2_dev); - bmi2_error_codes_print_result(rslt); - - /* Before setting FIFO, disable the advance power save mode. */ - rslt = bmi2_set_adv_power_save(BMI2_DISABLE, &bmi2_dev); - bmi2_error_codes_print_result(rslt); - - /* Initially disable all configurations in fifo. */ - rslt = bmi2_set_fifo_config(BMI2_FIFO_ALL_EN, BMI2_DISABLE, &bmi2_dev); - bmi2_error_codes_print_result(rslt); - - /* Update FIFO structure. */ - /* Mapping the buffer to store the fifo data. */ - fifoframe.data = fifo_data; - - /* Length of FIFO frame. */ - fifoframe.length = BMI270_FIFO_RAW_DATA_USER_LENGTH; - - /* Set FIFO configuration by enabling accel, gyro. - * NOTE 1: The header mode is enabled by default. - * NOTE 2: By default the FIFO operating mode is FIFO mode. */ - rslt = bmi2_set_fifo_config(BMI2_FIFO_ACC_EN | BMI2_FIFO_GYR_EN, BMI2_ENABLE, &bmi2_dev); - bmi2_error_codes_print_result(rslt); - - printf("FIFO is configured in headerless mode\n"); - - /* To enable headerless mode, disable the header. */ - if (rslt == BMI2_OK) - { - rslt = bmi2_set_fifo_config(BMI2_FIFO_HEADER_EN, BMI2_DISABLE, &bmi2_dev); - } - - /* FIFO water-mark interrupt is enabled. */ - fifoframe.data_int_map = BMI2_FWM_INT; - - /* Map water-mark interrupt to the required interrupt pin. */ - rslt = bmi2_map_data_int(fifoframe.data_int_map, BMI2_INT1, &bmi2_dev); - bmi2_error_codes_print_result(rslt); - - /* Set water-mark level. */ - fifoframe.wm_lvl = BMI270_FIFO_WATERMARK_LEVEL; - - fifoframe.length = BMI270_FIFO_RAW_DATA_USER_LENGTH; - - /* Set the water-mark level if water-mark interrupt is mapped. */ - rslt = bmi2_set_fifo_wm(fifoframe.wm_lvl, &bmi2_dev); - bmi2_error_codes_print_result(rslt); - - rslt = bmi2_get_fifo_wm(&watermark, &bmi2_dev); - bmi2_error_codes_print_result(rslt); - printf("\nFIFO watermark level is %d\n", watermark); - while (1) - { - - /* Read FIFO data on interrupt. */ - rslt = bmi2_get_int_status(&int_status, &bmi2_dev); - - /* To check the status of FIFO watermark interrupt. */ - if ((rslt == BMI2_OK) && (int_status & BMI2_FWM_INT_STATUS_MASK)) - { - printf("\nWatermark interrupt occurred\n"); - - rslt = bmi2_get_fifo_length(&fifo_length, &bmi2_dev); - bmi2_error_codes_print_result(rslt); - - accel_frame_length = BMI270_FIFO_ACCEL_FRAME_COUNT; - gyro_frame_length = BMI270_FIFO_GYRO_FRAME_COUNT; - - printf("\nFIFO data bytes available : %d \n", fifo_length); - printf("\nFIFO data bytes requested : %d \n", fifoframe.length); - - /* Read FIFO data. */ - rslt = bmi2_read_fifo_data(&fifoframe, &bmi2_dev); - bmi2_error_codes_print_result(rslt); - - if (rslt == BMI2_OK) - { - printf("\nFIFO accel frames requested : %d \n", accel_frame_length); - - /* Parse the FIFO data to extract accelerometer data from the FIFO buffer. */ - rslt = bmi2_extract_accel(fifo_accel_data, &accel_frame_length, &fifoframe, &bmi2_dev); - printf("\nFIFO accel frames extracted : %d \n", accel_frame_length); - - printf("\nFIFO gyro frames requested : %d \n", gyro_frame_length); - - /* Parse the FIFO data to extract gyro data from the FIFO buffer. */ - rslt = bmi2_extract_gyro(fifo_gyro_data, &gyro_frame_length, &fifoframe, &bmi2_dev); - printf("\nFIFO gyro frames extracted : %d \n", gyro_frame_length); - - /* Calculating the frame count from the available bytes in FIFO - * frame_length = (available_fifo_bytes / (acc_frame_len + gyro_frame_len + header_byte)) */ - frame_count = (fifo_length / (BMI2_FIFO_ACC_GYR_LENGTH + 1)); - printf("\nAvailable frame count from available bytes: %d\n", frame_count); - - printf("\nExracted accel frames\n"); - - /* Print the parsed accelerometer data from the FIFO buffer. */ - for (index = 0; index < frame_count; index++) - { - printf("ACCEL[%d] X : %d\t Y : %d\t Z : %d\n", index, fifo_accel_data[index].x, - fifo_accel_data[index].y, fifo_accel_data[index].z); - } - - printf("\nExtracted gyro frames\n"); - - /* Print the parsed gyro data from the FIFO buffer. */ - for (index = 0; index < frame_count; index++) - { - printf("GYRO[%d] X : %d\t Y : %d\t Z : %d\n", - index, - fifo_gyro_data[index].x, - fifo_gyro_data[index].y, - fifo_gyro_data[index].z); - } - } - - break; - } - } - - return rslt; -} - -/*! - * @brief This internal API is used to set configurations for accel. - */ -static int8_t set_accel_gyro_config(struct bmi2_dev *dev) -{ - - /* Status of api are returned to this variable. */ - int8_t rslt; - - /* Structure to define accel and gyro configurations. */ - struct bmi2_sens_config config[2]; - - /* Configure the type of feature. */ - config[0].type = BMI2_ACCEL; - config[1].type = BMI2_GYRO; - - /* Get default configurations for the type of feature selected. */ - rslt = bmi2_get_sensor_config(config, 2, dev); - bmi2_error_codes_print_result(rslt); - - if (rslt == BMI2_OK) - { - /* NOTE: The user can change the following configuration parameter according to their requirement. */ - /* Accel configuration settings. */ - /* Output Data Rate. By default ODR is set as 100Hz for accel. */ - config[0].cfg.acc.odr = BMI2_ACC_ODR_100HZ; - - /* Gravity range of the sensor (+/- 2G, 4G, 8G, 16G). */ - config[0].cfg.acc.range = BMI2_ACC_RANGE_2G; - - /* The bandwidth parameter is used to configure the number of sensor samples that are averaged - * if it is set to 2, then 2^(bandwidth parameter) samples - * are averaged, resulting in 4 averaged samples - * Note1 : For more information, refer the datasheet. - * Note2 : A higher number of averaged samples will result in a lower noise level of the signal, but - * this has an adverse effect on the power consumed. - */ - config[0].cfg.acc.bwp = BMI2_ACC_NORMAL_AVG4; - - /* Enable the filter performance mode where averaging of samples - * will be done based on above set bandwidth and ODR. - * There are two modes - * 0 -> Ultra low power mode - * 1 -> High performance mode(Default) - * For more info refer datasheet. - */ - config[0].cfg.acc.filter_perf = BMI2_PERF_OPT_MODE; - - /* Gyro configuration settings. */ - /* Output Data Rate. Default ODR is 200Hz, setting to 100Hz. */ - config[1].cfg.gyr.odr = BMI2_GYR_ODR_100HZ; - - /* Gyroscope Angular Rate Measurement Range.By default the range is 2000dps. */ - config[1].cfg.gyr.range = BMI2_GYR_RANGE_2000; - - /* Gyroscope Bandwidth parameters. By default the gyro bandwidth is in normal mode. */ - config[1].cfg.gyr.bwp = BMI2_GYR_NORMAL_MODE; - - /* Enable/Disable the noise performance mode for precision yaw rate sensing - * There are two modes - * 0 -> Ultra low power mode(Default) - * 1 -> High performance mode - */ - config[1].cfg.gyr.noise_perf = BMI2_POWER_OPT_MODE; - - /* Enable/Disable the filter performance mode where averaging of samples - * will be done based on above set bandwidth and ODR. - * There are two modes - * 0 -> Ultra low power mode - * 1 -> High performance mode(Default) - */ - config[1].cfg.gyr.filter_perf = BMI2_PERF_OPT_MODE; - - /* Set new configurations. */ - rslt = bmi2_set_sensor_config(config, 2, dev); - bmi2_error_codes_print_result(rslt); - } - - return rslt; -} +/**\ + * Copyright (c) 2020 Bosch Sensortec GmbH. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + **/ + +/******************************************************************************/ +/*! Header Files */ +#include +#include "bmi270_maximum_fifo.h" +#include "common.h" + +/******************************************************************************/ +/*! Macros */ + +/*! Buffer size allocated to store raw FIFO data */ +#define BMI2_FIFO_RAW_DATA_BUFFER_SIZE UINT16_C(2048) + +/*! Length of data to be read from FIFO */ +#define BMI2_FIFO_RAW_DATA_USER_LENGTH UINT16_C(2048) + +/*! Number of accel frames to be extracted from FIFO */ + +/*! + * Calculation: + * fifo_watermark_level = 650, accel_frame_len = 6, gyro_frame_len = 6. + * fifo_accel_frame_count = (650 / (6 + 6 )) = 54 frames + */ +#define BMI2_FIFO_ACCEL_FRAME_COUNT UINT8_C(55) + +/*! Number of gyro frames to be extracted from FIFO */ +#define BMI2_FIFO_GYRO_FRAME_COUNT UINT8_C(55) + +/*! Setting a watermark level in FIFO */ +#define BMI270_FIFO_WATERMARK_LEVEL UINT16_C(650) + +/******************************************************************************/ +/*! Static Function Declaration */ + +/*! + * @brief This internal API is used to set configurations for accel and gyro. + * @param[in] dev : Structure instance of bmi2_dev. + * @return Status of execution. + */ +static int8_t set_accel_gyro_config(struct bmi2_dev *dev); + +/******************************************************************************/ +/*! Functions */ + +/* This function starts the execution of program. */ +int main(void) +{ + /* Status of api are returned to this variable. */ + int8_t rslt; + + /* Variable to index bytes. */ + uint16_t index = 0; + + /* Variable to store the available frame length count in FIFO */ + uint8_t frame_count; + + uint16_t fifo_length = 0; + + uint16_t accel_frame_length; + + uint16_t gyro_frame_length; + + uint8_t try = 1; + + /* Number of bytes of FIFO data. */ + uint8_t fifo_data[BMI2_FIFO_RAW_DATA_BUFFER_SIZE] = { 0 }; + + /* Sensor initialization configuration. */ + struct bmi2_dev bmi2_dev; + + /* Array of accelerometer frames -> Total bytes = + * 50 * (6 axes bytes) = 300 bytes */ + struct bmi2_sens_axes_data fifo_accel_data[BMI2_FIFO_ACCEL_FRAME_COUNT] = { { 0 } }; + + /* Array of gyro frames -> Total bytes = + * 50 * (6 axes bytes) = 300 bytes */ + struct bmi2_sens_axes_data fifo_gyro_data[BMI2_FIFO_GYRO_FRAME_COUNT] = { { 0 } }; + + /* Initialize FIFO frame structure. */ + struct bmi2_fifo_frame fifoframe = { 0 }; + + /* Accel and gyro sensor are listed in array. */ + uint8_t sensor_sel[2] = { BMI2_ACCEL, BMI2_GYRO }; + + /* Variable to get fifo water-mark interrupt status. */ + uint16_t int_status = 0; + + uint16_t watermark = 0; + + /* Interface reference is given as a parameter + * For I2C : BMI2_I2C_INTF + * For SPI : BMI2_SPI_INTF + */ + rslt = bmi2_interface_init(&bmi2_dev, BMI2_I2C_INTF); + bmi2_error_codes_print_result(rslt); + + /* Initialize bmi270. */ + rslt = bmi270_maximum_fifo_init(&bmi2_dev); + bmi2_error_codes_print_result(rslt); + + /* Enable accel and gyro sensor. */ + rslt = bmi2_sensor_enable(sensor_sel, 2, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + /* Configuration settings for accel and gyro. */ + rslt = set_accel_gyro_config(&bmi2_dev); + bmi2_error_codes_print_result(rslt); + + /* Before setting FIFO, disable the advance power save mode. */ + rslt = bmi2_set_adv_power_save(BMI2_DISABLE, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + /* Initially disable all configurations in fifo. */ + rslt = bmi2_set_fifo_config(BMI2_FIFO_ALL_EN, BMI2_DISABLE, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + /* Update FIFO structure. */ + /* Mapping the buffer to store the fifo data. */ + fifoframe.data = fifo_data; + + /* Length of FIFO frame. */ + fifoframe.length = BMI2_FIFO_RAW_DATA_USER_LENGTH; + + /* Set FIFO configuration by enabling accel, gyro. + * NOTE 1: The header mode is enabled by default. + * NOTE 2: By default the FIFO operating mode is FIFO mode. */ + rslt = bmi2_set_fifo_config(BMI2_FIFO_ACC_EN | BMI2_FIFO_GYR_EN, BMI2_ENABLE, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + printf("FIFO is configured in headerless mode\n"); + + /* To enable headerless mode, disable the header. */ + if (rslt == BMI2_OK) + { + rslt = bmi2_set_fifo_config(BMI2_FIFO_HEADER_EN, BMI2_DISABLE, &bmi2_dev); + } + + /* FIFO water-mark interrupt is enabled. */ + fifoframe.data_int_map = BMI2_FWM_INT; + + /* Map water-mark interrupt to the required interrupt pin. */ + rslt = bmi2_map_data_int(fifoframe.data_int_map, BMI2_INT1, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + /* Set water-mark level. */ + fifoframe.wm_lvl = BMI270_FIFO_WATERMARK_LEVEL; + + fifoframe.length = BMI2_FIFO_RAW_DATA_USER_LENGTH; + + /* Set the water-mark level if water-mark interrupt is mapped. */ + rslt = bmi2_set_fifo_wm(fifoframe.wm_lvl, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + rslt = bmi2_get_fifo_wm(&watermark, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + printf("\nFIFO watermark level is %d\n", watermark); + + while (try <= 10) + { + /* Read FIFO data on interrupt. */ + rslt = bmi2_get_int_status(&int_status, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + /* To check the status of FIFO watermark interrupt. */ + if ((rslt == BMI2_OK) && (int_status & BMI2_FWM_INT_STATUS_MASK)) + { + printf("\nIteration : %d\n", try); + + printf("\nWatermark interrupt occurred\n"); + + rslt = bmi2_get_fifo_length(&fifo_length, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + accel_frame_length = BMI2_FIFO_ACCEL_FRAME_COUNT; + gyro_frame_length = BMI2_FIFO_GYRO_FRAME_COUNT; + + printf("\nFIFO data bytes available : %d \n", fifo_length); + printf("\nFIFO data bytes requested : %d \n", fifoframe.length); + + /* Read FIFO data. */ + rslt = bmi2_read_fifo_data(&fifoframe, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + /* Read FIFO data on interrupt. */ + rslt = bmi2_get_int_status(&int_status, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + if (rslt == BMI2_OK) + { + printf("\nFIFO accel frames requested : %d \n", accel_frame_length); + + /* Parse the FIFO data to extract accelerometer data from the FIFO buffer. */ + rslt = bmi2_extract_accel(fifo_accel_data, &accel_frame_length, &fifoframe, &bmi2_dev); + printf("\nFIFO accel frames extracted : %d \n", accel_frame_length); + + printf("\nFIFO gyro frames requested : %d \n", gyro_frame_length); + + /* Parse the FIFO data to extract gyro data from the FIFO buffer. */ + rslt = bmi2_extract_gyro(fifo_gyro_data, &gyro_frame_length, &fifoframe, &bmi2_dev); + printf("\nFIFO gyro frames extracted : %d \n", gyro_frame_length); + + /* Calculating the frame count from the available bytes in FIFO + * frame_length = (available_fifo_bytes / (acc_frame_len + gyro_frame_len)) */ + frame_count = (fifo_length / (BMI2_FIFO_ACC_GYR_LENGTH)); + printf("\nAvailable frame count from available bytes: %d\n", frame_count); + + printf("\nExracted accel frames\n"); + + if (accel_frame_length > frame_count) + { + accel_frame_length = frame_count; + } + + /* Print the parsed accelerometer data from the FIFO buffer. */ + for (index = 0; index < accel_frame_length; index++) + { + printf("ACCEL[%d] X : %d\t Y : %d\t Z : %d\n", index, fifo_accel_data[index].x, + fifo_accel_data[index].y, fifo_accel_data[index].z); + } + + printf("\nExtracted gyro frames\n"); + + if (gyro_frame_length > frame_count) + { + gyro_frame_length = frame_count; + } + + /* Print the parsed gyro data from the FIFO buffer. */ + for (index = 0; index < gyro_frame_length; index++) + { + printf("GYRO[%d] X : %d\t Y : %d\t Z : %d\n", + index, + fifo_gyro_data[index].x, + fifo_gyro_data[index].y, + fifo_gyro_data[index].z); + } + } + + try++; + } + } + + bmi2_coines_deinit(); + + return rslt; +} + +/*! + * @brief This internal API is used to set configurations for accel. + */ +static int8_t set_accel_gyro_config(struct bmi2_dev *dev) +{ + /* Status of api are returned to this variable. */ + int8_t rslt; + + /* Structure to define accel and gyro configurations. */ + struct bmi2_sens_config config[2]; + + /* Configure the type of feature. */ + config[0].type = BMI2_ACCEL; + config[1].type = BMI2_GYRO; + + /* Get default configurations for the type of feature selected. */ + rslt = bmi2_get_sensor_config(config, 2, dev); + bmi2_error_codes_print_result(rslt); + + if (rslt == BMI2_OK) + { + /* NOTE: The user can change the following configuration parameter according to their requirement. */ + /* Accel configuration settings. */ + /* Set Output Data Rate */ + config[0].cfg.acc.odr = BMI2_ACC_ODR_100HZ; + + /* Gravity range of the sensor (+/- 2G, 4G, 8G, 16G). */ + config[0].cfg.acc.range = BMI2_ACC_RANGE_2G; + + /* The bandwidth parameter is used to configure the number of sensor samples that are averaged + * if it is set to 2, then 2^(bandwidth parameter) samples + * are averaged, resulting in 4 averaged samples + * Note1 : For more information, refer the datasheet. + * Note2 : A higher number of averaged samples will result in a lower noise level of the signal, but + * this has an adverse effect on the power consumed. + */ + config[0].cfg.acc.bwp = BMI2_ACC_NORMAL_AVG4; + + /* Enable the filter performance mode where averaging of samples + * will be done based on above set bandwidth and ODR. + * There are two modes + * 0 -> Ultra low power mode + * 1 -> High performance mode(Default) + * For more info refer datasheet. + */ + config[0].cfg.acc.filter_perf = BMI2_PERF_OPT_MODE; + + /* Gyro configuration settings. */ + /* Set Output Data Rate */ + config[1].cfg.gyr.odr = BMI2_GYR_ODR_100HZ; + + /* Gyroscope Angular Rate Measurement Range.By default the range is 2000dps. */ + config[1].cfg.gyr.range = BMI2_GYR_RANGE_2000; + + /* Gyroscope Bandwidth parameters. By default the gyro bandwidth is in normal mode. */ + config[1].cfg.gyr.bwp = BMI2_GYR_NORMAL_MODE; + + /* Enable/Disable the noise performance mode for precision yaw rate sensing + * There are two modes + * 0 -> Ultra low power mode(Default) + * 1 -> High performance mode + */ + config[1].cfg.gyr.noise_perf = BMI2_POWER_OPT_MODE; + + /* Enable/Disable the filter performance mode where averaging of samples + * will be done based on above set bandwidth and ODR. + * There are two modes + * 0 -> Ultra low power mode + * 1 -> High performance mode(Default) + */ + config[1].cfg.gyr.filter_perf = BMI2_PERF_OPT_MODE; + + /* Set new configurations. */ + rslt = bmi2_set_sensor_config(config, 2, dev); + bmi2_error_codes_print_result(rslt); + } + + return rslt; +} diff --git a/examples/bmi270_maximum_fifo/gyro/Makefile b/examples/bmi270_maximum_fifo/gyro/Makefile new file mode 100644 index 0000000..5ab6e7f --- /dev/null +++ b/examples/bmi270_maximum_fifo/gyro/Makefile @@ -0,0 +1,18 @@ +COINES_INSTALL_PATH ?= ../../../.. + +EXAMPLE_FILE ?= gyro.c + +API_LOCATION ?= ../.. + +COMMON_LOCATION ?= .. + +C_SRCS += \ +$(API_LOCATION)/bmi2.c \ +$(API_LOCATION)/bmi270_maximum_fifo.c \ +$(COMMON_LOCATION)/common/common.c + +INCLUDEPATHS += \ +$(API_LOCATION) \ +$(COMMON_LOCATION)/common + +include $(COINES_INSTALL_PATH)/coines.mk \ No newline at end of file diff --git a/examples/bmi270/generic/gyro.c b/examples/bmi270_maximum_fifo/gyro/gyro.c similarity index 82% rename from examples/bmi270/generic/gyro.c rename to examples/bmi270_maximum_fifo/gyro/gyro.c index a32adb8..8b56f08 100644 --- a/examples/bmi270/generic/gyro.c +++ b/examples/bmi270_maximum_fifo/gyro/gyro.c @@ -1,191 +1,195 @@ -/**\ - * Copyright (c) 2020 Bosch Sensortec GmbH. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - **/ - -/******************************************************************************/ -/*! Header Files */ -#include -#include "bmi2.h" -#include "bmi270.h" -#include "bmi2_common.h" - -/******************************************************************************/ -/*! Static Function Declaration */ - -/*! - * @brief This internal API is used to set configurations for gyro. - * - * @param[in] dev : Structure instance of bmi2_dev. - * - * @return Status of execution. - */ -static int8_t set_gyro_config(struct bmi2_dev *dev); - -/*! - * @brief This function converts lsb to degree per second for 16 bit gyro at - * range 125, 250, 500, 1000 or 2000dps. - * - * @param[in] val : LSB from each axis. - * @param[in] dps : Degree per second. - * @param[in] bit_width : Resolution for gyro. - * - * @return Gravity. - */ -static float lsb_to_dps(int16_t val, float dps, uint8_t bit_width); - -/******************************************************************************/ -/*! Functions */ - -/* This function starts the execution of program. */ -int main(void) -{ - - /* Status of api are returned to this variable. */ - int8_t rslt; - - /* Variable to define limit to print gyro data. */ - uint8_t limit = 10; - - uint8_t indx; - float x = 0, y = 0, z = 0; - - /*! Sensor initialization configuration. */ - struct bmi2_dev bmi2_dev; - - /* Create an instance of sensor data structure. */ - struct bmi2_sensor_data sensor_data = { 0 }; - - /* Assign gyro sensor to variable. */ - uint8_t sens_list = BMI2_GYRO; - - /* Initialize the interrupt status of gyro. */ - uint16_t int_status = 0; - - /* Initialize the dev structure */ - rslt = bmi2_interface_selection(&bmi2_dev); - bmi2_error_codes_print_result(rslt); - - /* Initialize bmi270. */ - rslt = bmi270_init(&bmi2_dev); - bmi2_error_codes_print_result(rslt); - - if (rslt == BMI2_OK) - { - - /* Enable the selected sensors. */ - rslt = bmi2_sensor_enable(&sens_list, 1, &bmi2_dev); - bmi2_error_codes_print_result(rslt); - - if (rslt == BMI2_OK) - { - - /* Gyro configuration settings. */ - rslt = set_gyro_config(&bmi2_dev); - bmi2_error_codes_print_result(rslt); - - /* Select gyro sensor. */ - sensor_data.type = BMI2_GYRO; - printf("Gyro and DPS data"); - - /* Loop to print gyro data when interrupt occurs. */ - do - { - - /* To get the data ready interrupt status of gyro. */ - rslt = bmi2_get_int_status(&int_status, &bmi2_dev); - - /* To check the data ready interrupt status and print the status for 10 samples. */ - for (indx = 0; (indx < limit && (int_status & BMI2_GYR_DRDY_INT_MASK)); indx++) - { - - /* Get gyro data for x, y and z axis. */ - rslt = bmi2_get_sensor_data(&sensor_data, 1, &bmi2_dev); - printf("\nGyrx= %d\t", sensor_data.sens_data.gyr.x); - printf("Gyry= %d\t", sensor_data.sens_data.gyr.y); - printf("Gyrz= %d\r\n", sensor_data.sens_data.gyr.z); - - /* Converting lsb to degree per second for 16 bit gyro at 2000dps range. */ - x = lsb_to_dps(sensor_data.sens_data.gyr.x, 2000, bmi2_dev.resolution); - y = lsb_to_dps(sensor_data.sens_data.gyr.y, 2000, bmi2_dev.resolution); - z = lsb_to_dps(sensor_data.sens_data.gyr.z, 2000, bmi2_dev.resolution); - - /* Print the data in dps. */ - printf("Dx = %4.2f, Dy = %4.2f, Dz = %4.2f\n", x, y, z); - } - } while (int_status != BMI2_GYR_DRDY_INT_MASK); - } - } - - return rslt; -} - -/*! - * @brief This internal API is used to set configurations for gyro. - */ -static int8_t set_gyro_config(struct bmi2_dev *dev) -{ - - /* Status of api are returned to this variable. */ - int8_t rslt; - - /* Structure to define the type of sensor and its configurations. */ - struct bmi2_sens_config config; - - /* Configure the type of feature. */ - config.type = BMI2_GYRO; - - /* Get default configurations for the type of feature selected. */ - rslt = bmi2_get_sensor_config(&config, 1, dev); - bmi2_error_codes_print_result(rslt); - - /* Map data ready interrupt to interrupt pin. */ - rslt = bmi2_map_data_int(BMI2_DRDY_INT, BMI2_INT2, dev); - bmi2_error_codes_print_result(rslt); - - if (rslt == BMI2_OK) - { - - /* The user can change the following configuration parameters according to their requirement. */ - /* Output Data Rate. By default ODR is set as 200Hz for gyro. */ - config.cfg.gyr.odr = BMI2_GYR_ODR_200HZ; - - /* Gyroscope Angular Rate Measurement Range.By default the range is 2000dps. */ - config.cfg.gyr.range = BMI2_GYR_RANGE_2000; - - /* Gyroscope bandwidth parameters. By default the gyro bandwidth is in normal mode. */ - config.cfg.gyr.bwp = BMI2_GYR_NORMAL_MODE; - - /* Enable/Disable the noise performance mode for precision yaw rate sensing - * There are two modes - * 0 -> Ultra low power mode(Default) - * 1 -> High performance mode - */ - config.cfg.gyr.noise_perf = BMI2_POWER_OPT_MODE; - - /* Enable/Disable the filter performance mode where averaging of samples - * will be done based on above set bandwidth and ODR. - * There are two modes - * 0 -> Ultra low power mode - * 1 -> High performance mode(Default) - */ - config.cfg.gyr.filter_perf = BMI2_PERF_OPT_MODE; - - /* Set the gyro configurations. */ - rslt = bmi2_set_sensor_config(&config, 1, dev); - } - - return rslt; -} - -/*! - * @brief This function converts lsb to degree per second for 16 bit gyro at - * range 125, 250, 500, 1000 or 2000dps. - */ -static float lsb_to_dps(int16_t val, float dps, uint8_t bit_width) -{ - float half_scale = ((float)(1 << bit_width) / 2.0f); - - return (dps / ((half_scale) + BMI2_GYR_RANGE_2000)) * (val); -} +/**\ + * Copyright (c) 2020 Bosch Sensortec GmbH. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + **/ + +/******************************************************************************/ +/*! Header Files */ +#include +#include "bmi270_maximum_fifo.h" +#include "common.h" + +/******************************************************************************/ +/*! Static Function Declaration */ + +/*! + * @brief This internal API is used to set configurations for gyro. + * + * @param[in] dev : Structure instance of bmi2_dev. + * + * @return Status of execution. + */ +static int8_t set_gyro_config(struct bmi2_dev *dev); + +/*! + * @brief This function converts lsb to degree per second for 16 bit gyro at + * range 125, 250, 500, 1000 or 2000dps. + * + * @param[in] val : LSB from each axis. + * @param[in] dps : Degree per second. + * @param[in] bit_width : Resolution for gyro. + * + * @return Degree per second. + */ +static float lsb_to_dps(int16_t val, float dps, uint8_t bit_width); + +/******************************************************************************/ +/*! Functions */ + +/* This function starts the execution of program. */ +int main(void) +{ + /* Status of api are returned to this variable. */ + int8_t rslt; + + /* Variable to define limit to print gyro data. */ + uint8_t limit = 10; + + uint8_t indx = 0; + + float x = 0, y = 0, z = 0; + + /* Sensor initialization configuration. */ + struct bmi2_dev bmi2_dev; + + /* Create an instance of sensor data structure. */ + struct bmi2_sensor_data sensor_data = { 0 }; + + /* Assign gyro sensor to variable. */ + uint8_t sens_list = BMI2_GYRO; + + /* Initialize the interrupt status of gyro. */ + uint16_t int_status = 0; + + /* Interface reference is given as a parameter + * For I2C : BMI2_I2C_INTF + * For SPI : BMI2_SPI_INTF + */ + rslt = bmi2_interface_init(&bmi2_dev, BMI2_I2C_INTF); + bmi2_error_codes_print_result(rslt); + + /* Initialize bmi270_maximum_fifo_init */ + rslt = bmi270_maximum_fifo_init(&bmi2_dev); + bmi2_error_codes_print_result(rslt); + + if (rslt == BMI2_OK) + { + /* Enable the selected sensors. */ + rslt = bmi2_sensor_enable(&sens_list, 1, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + if (rslt == BMI2_OK) + { + /* Gyro configuration settings. */ + rslt = set_gyro_config(&bmi2_dev); + bmi2_error_codes_print_result(rslt); + + /* Select gyro sensor. */ + sensor_data.type = BMI2_GYRO; + printf("Gyro and DPS data\n"); + printf("Gyro data collected at Range 2000 dps with 16-bit resolution\n"); + + /* Loop to print gyro data when interrupt occurs. */ + while (indx <= limit) + { + /* To get the data ready interrupt status of gyro. */ + rslt = bmi2_get_int_status(&int_status, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + /* To check the data ready interrupt status and print the status for 10 samples. */ + if (int_status & BMI2_GYR_DRDY_INT_MASK) + { + /* Get gyro data for x, y and z axis. */ + rslt = bmi2_get_sensor_data(&sensor_data, 1, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + printf("\nGyr_X = %d\t", sensor_data.sens_data.gyr.x); + printf("Gyr_Y = %d\t", sensor_data.sens_data.gyr.y); + printf("Gyr_Z = %d\r\n", sensor_data.sens_data.gyr.z); + + /* Converting lsb to degree per second for 16 bit gyro at 2000dps range. */ + x = lsb_to_dps(sensor_data.sens_data.gyr.x, 2000, bmi2_dev.resolution); + y = lsb_to_dps(sensor_data.sens_data.gyr.y, 2000, bmi2_dev.resolution); + z = lsb_to_dps(sensor_data.sens_data.gyr.z, 2000, bmi2_dev.resolution); + + /* Print the data in dps. */ + printf("Gyr_DPS_X = %4.2f, Gyr_DPS_Y = %4.2f, Gyr_DPS_Z = %4.2f\n", x, y, z); + + indx++; + } + } + } + } + + bmi2_coines_deinit(); + + return rslt; +} + +/*! + * @brief This internal API is used to set configurations for gyro. + */ +static int8_t set_gyro_config(struct bmi2_dev *dev) +{ + /* Status of api are returned to this variable. */ + int8_t rslt; + + /* Structure to define the type of sensor and its configurations. */ + struct bmi2_sens_config config; + + /* Configure the type of feature. */ + config.type = BMI2_GYRO; + + /* Get default configurations for the type of feature selected. */ + rslt = bmi2_get_sensor_config(&config, 1, dev); + bmi2_error_codes_print_result(rslt); + + /* Map data ready interrupt to interrupt pin. */ + rslt = bmi2_map_data_int(BMI2_DRDY_INT, BMI2_INT2, dev); + bmi2_error_codes_print_result(rslt); + + if (rslt == BMI2_OK) + { + /* The user can change the following configuration parameters according to their requirement. */ + /* Set Output Data Rate */ + config.cfg.gyr.odr = BMI2_GYR_ODR_200HZ; + + /* Gyroscope Angular Rate Measurement Range.By default the range is 2000dps. */ + config.cfg.gyr.range = BMI2_GYR_RANGE_2000; + + /* Gyroscope bandwidth parameters. By default the gyro bandwidth is in normal mode. */ + config.cfg.gyr.bwp = BMI2_GYR_NORMAL_MODE; + + /* Enable/Disable the noise performance mode for precision yaw rate sensing + * There are two modes + * 0 -> Ultra low power mode(Default) + * 1 -> High performance mode + */ + config.cfg.gyr.noise_perf = BMI2_POWER_OPT_MODE; + + /* Enable/Disable the filter performance mode where averaging of samples + * will be done based on above set bandwidth and ODR. + * There are two modes + * 0 -> Ultra low power mode + * 1 -> High performance mode(Default) + */ + config.cfg.gyr.filter_perf = BMI2_PERF_OPT_MODE; + + /* Set the gyro configurations. */ + rslt = bmi2_set_sensor_config(&config, 1, dev); + } + + return rslt; +} + +/*! + * @brief This function converts lsb to degree per second for 16 bit gyro at + * range 125, 250, 500, 1000 or 2000dps. + */ +static float lsb_to_dps(int16_t val, float dps, uint8_t bit_width) +{ + float half_scale = ((float)(1 << bit_width) / 2.0f); + + return (dps / ((half_scale) + BMI2_GYR_RANGE_2000)) * (val); +} diff --git a/examples/bmi270_wh/accel/Makefile b/examples/bmi270_wh/accel/Makefile new file mode 100644 index 0000000..3ab55f0 --- /dev/null +++ b/examples/bmi270_wh/accel/Makefile @@ -0,0 +1,18 @@ +COINES_INSTALL_PATH ?= ../../../.. + +EXAMPLE_FILE ?= accel.c + +API_LOCATION ?= ../.. + +COMMON_LOCATION ?= .. + +C_SRCS += \ +$(API_LOCATION)/bmi2.c \ +$(API_LOCATION)/bmi270_wh.c \ +$(COMMON_LOCATION)/common/common.c + +INCLUDEPATHS += \ +$(API_LOCATION) \ +$(COMMON_LOCATION)/common + +include $(COINES_INSTALL_PATH)/coines.mk \ No newline at end of file diff --git a/examples/bmi270_wh/accel/accel.c b/examples/bmi270_wh/accel/accel.c new file mode 100644 index 0000000..cf68252 --- /dev/null +++ b/examples/bmi270_wh/accel/accel.c @@ -0,0 +1,201 @@ +/**\ + * Copyright (c) 2020 Bosch Sensortec GmbH. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + **/ + +/******************************************************************************/ +/*! Header Files */ +#include +#include "bmi270_wh.h" +#include "common.h" + +/******************************************************************************/ +/*! Macro definition */ + +/*! Earth's gravity in m/s^2 */ +#define GRAVITY_EARTH (9.80665f) + +/******************************************************************************/ +/*! Static Function Declaration */ + +/*! + * @brief This internal API is used to set configurations for accel. + * + * @param[in] dev : Structure instance of bmi2_dev. + * + * @return Status of execution. + */ +static int8_t set_accel_config(struct bmi2_dev *bmi2_dev); + +/*! + * @brief This function converts lsb to meter per second squared for 16 bit accelerometer at + * range 2G, 4G, 8G or 16G. + * + * @param[in] val : LSB from each axis. + * @param[in] g_range : Gravity range. + * @param[in] bit_width : Resolution for accel. + * + * @return Gravity. + */ +static float lsb_to_mps2(int16_t val, float g_range, uint8_t bit_width); + +/******************************************************************************/ +/*! Functions */ + +/* This function starts the execution of program. */ +int main(void) +{ + /* Status of api are returned to this variable. */ + int8_t rslt; + + /* Variable to define limit to print accel data. */ + uint8_t limit = 20; + + /* Assign accel sensor to variable. */ + uint8_t sensor_list = BMI2_ACCEL; + + /* Sensor initialization configuration. */ + struct bmi2_dev bmi2_dev; + + /* Create an instance of sensor data structure. */ + struct bmi2_sensor_data sensor_data = { 0 }; + + /* Initialize the interrupt status of accel. */ + uint16_t int_status = 0; + + uint8_t indx = 0; + float x = 0, y = 0, z = 0; + + /* Interface reference is given as a parameter + * For I2C : BMI2_I2C_INTF + * For SPI : BMI2_SPI_INTF + */ + rslt = bmi2_interface_init(&bmi2_dev, BMI2_I2C_INTF); + bmi2_error_codes_print_result(rslt); + + /* Initialize bmi270_wh. */ + rslt = bmi270_wh_init(&bmi2_dev); + bmi2_error_codes_print_result(rslt); + + if (rslt == BMI2_OK) + { + /* Enable the accel sensor. */ + rslt = bmi270_wh_sensor_enable(&sensor_list, 1, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + if (rslt == BMI2_OK) + { + /* Accel configuration settings. */ + rslt = set_accel_config(&bmi2_dev); + bmi2_error_codes_print_result(rslt); + + /* Assign accel sensor. */ + sensor_data.type = BMI2_ACCEL; + printf("Accel and m/s2 data \n"); + printf("Accel data collected at 2G Range with 16-bit resolution\n"); + + /* Loop to print the accel data when interrupt occurs. */ + while (indx <= limit) + { + /* To get the status of accel data ready interrupt. */ + rslt = bmi2_get_int_status(&int_status, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + /* To check the accel data ready interrupt status and print the status for 10 samples. */ + if (int_status & BMI2_ACC_DRDY_INT_MASK) + { + /* Get accelerometer data for x, y and z axis. */ + rslt = bmi270_wh_get_sensor_data(&sensor_data, 1, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + printf("\nAcc_X = %d\t", sensor_data.sens_data.acc.x); + printf("Acc_Y = %d\t", sensor_data.sens_data.acc.y); + printf("Acc_Z = %d\r\n", sensor_data.sens_data.acc.z); + + /* Converting lsb to meter per second squared for 16 bit accelerometer at 2G range. */ + x = lsb_to_mps2(sensor_data.sens_data.acc.x, 2, bmi2_dev.resolution); + y = lsb_to_mps2(sensor_data.sens_data.acc.y, 2, bmi2_dev.resolution); + z = lsb_to_mps2(sensor_data.sens_data.acc.z, 2, bmi2_dev.resolution); + + /* Print the data in m/s2. */ + printf("\nAcc_ms2_X = %4.2f, Acc_ms2_Y = %4.2f, Acc_ms2_Z = %4.2f\n", x, y, z); + + indx++; + } + } + } + } + + bmi2_coines_deinit(); + + return rslt; +} + +/*! + * @brief This internal API is used to set configurations for accel. + */ +static int8_t set_accel_config(struct bmi2_dev *bmi2_dev) +{ + + /* Status of api are returned to this variable. */ + int8_t rslt; + + /* Structure to define accelerometer configuration. */ + struct bmi2_sens_config config; + + /* Configure the type of feature. */ + config.type = BMI2_ACCEL; + + /* Get default configurations for the type of feature selected. */ + rslt = bmi270_wh_get_sensor_config(&config, 1, bmi2_dev); + bmi2_error_codes_print_result(rslt); + + if (rslt == BMI2_OK) + { + /* NOTE: The user can change the following configuration parameters according to their requirement. */ + /* Set Output Data Rate */ + config.cfg.acc.odr = BMI2_ACC_ODR_200HZ; + + /* Gravity range of the sensor (+/- 2G, 4G, 8G, 16G). */ + config.cfg.acc.range = BMI2_ACC_RANGE_2G; + + /* The bandwidth parameter is used to configure the number of sensor samples that are averaged + * if it is set to 2, then 2^(bandwidth parameter) samples + * are averaged, resulting in 4 averaged samples. + * Note1 : For more information, refer the datasheet. + * Note2 : A higher number of averaged samples will result in a lower noise level of the signal, but + * this has an adverse effect on the power consumed. + */ + config.cfg.acc.bwp = BMI2_ACC_NORMAL_AVG4; + + /* Enable the filter performance mode where averaging of samples + * will be done based on above set bandwidth and ODR. + * There are two modes + * 0 -> Ultra low power mode + * 1 -> High performance mode(Default) + * For more info refer datasheet. + */ + config.cfg.acc.filter_perf = BMI2_PERF_OPT_MODE; + + /* Set the accel configurations. */ + rslt = bmi270_wh_set_sensor_config(&config, 1, bmi2_dev); + bmi2_error_codes_print_result(rslt); + + /* Map data ready interrupt to interrupt pin. */ + rslt = bmi2_map_data_int(BMI2_DRDY_INT, BMI2_INT1, bmi2_dev); + bmi2_error_codes_print_result(rslt); + } + + return rslt; +} + +/*! + * @brief This function converts lsb to meter per second squared for 16 bit accelerometer at + * range 2G, 4G, 8G or 16G. + */ +static float lsb_to_mps2(int16_t val, float g_range, uint8_t bit_width) +{ + float half_scale = ((float)(1 << bit_width) / 2.0f); + + return (GRAVITY_EARTH * val * g_range) / half_scale; +} diff --git a/examples/bmi270_wh/accel_gyro/Makefile b/examples/bmi270_wh/accel_gyro/Makefile new file mode 100644 index 0000000..1d3ea28 --- /dev/null +++ b/examples/bmi270_wh/accel_gyro/Makefile @@ -0,0 +1,18 @@ +COINES_INSTALL_PATH ?= ../../../.. + +EXAMPLE_FILE ?= accel_gyro.c + +API_LOCATION ?= ../.. + +COMMON_LOCATION ?= .. + +C_SRCS += \ +$(API_LOCATION)/bmi2.c \ +$(API_LOCATION)/bmi270_wh.c \ +$(COMMON_LOCATION)/common/common.c + +INCLUDEPATHS += \ +$(API_LOCATION) \ +$(COMMON_LOCATION)/common + +include $(COINES_INSTALL_PATH)/coines.mk \ No newline at end of file diff --git a/examples/bmi270_wh/accel_gyro/accel_gyro.c b/examples/bmi270_wh/accel_gyro/accel_gyro.c new file mode 100644 index 0000000..e543cca --- /dev/null +++ b/examples/bmi270_wh/accel_gyro/accel_gyro.c @@ -0,0 +1,268 @@ +/**\ + * Copyright (c) 2020 Bosch Sensortec GmbH. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + **/ + +/******************************************************************************/ +/*! Header Files */ +#include +#include "bmi270_wh.h" +#include "common.h" + +/******************************************************************************/ +/*! Macro definition */ + +/*! Earth's gravity in m/s^2 */ +#define GRAVITY_EARTH (9.80665f) + +/*! Macros to select the sensors */ +#define ACCEL UINT8_C(0x00) +#define GYRO UINT8_C(0x01) + +/******************************************************************************/ +/*! Static Function Declaration */ + +/*! + * @brief This internal API is used to set configurations for accel. + * + * @param[in] dev : Structure instance of bmi2_dev. + * + * @return Status of execution. + */ +static int8_t set_accel_gyro_config(struct bmi2_dev *bmi2_dev); + +/*! + * @brief This function converts lsb to meter per second squared for 16 bit accelerometer at + * range 2G, 4G, 8G or 16G. + * + * @param[in] val : LSB from each axis. + * @param[in] g_range : Gravity range. + * @param[in] bit_width : Resolution for accel. + * + * @return Gravity. + */ +static float lsb_to_mps2(int16_t val, float g_range, uint8_t bit_width); + +/*! + * @brief This function converts lsb to degree per second for 16 bit gyro at + * range 125, 250, 500, 1000 or 2000dps. + * + * @param[in] val : LSB from each axis. + * @param[in] dps : Degree per second. + * @param[in] bit_width : Resolution for gyro. + * + * @return Degree per second. + */ +static float lsb_to_dps(int16_t val, float dps, uint8_t bit_width); + +/******************************************************************************/ +/*! Functions */ + +/* This function starts the execution of program. */ +int main(void) +{ + /* Status of api are returned to this variable. */ + int8_t rslt; + + /* Variable to define limit to print accel data. */ + uint8_t limit = 10; + + /* Assign accel and gyro sensor to variable. */ + uint8_t sensor_list[2] = { BMI2_ACCEL, BMI2_GYRO }; + + /* Sensor initialization configuration. */ + struct bmi2_dev bmi2_dev; + + /* Create an instance of sensor data structure. */ + struct bmi2_sensor_data sensor_data[2] = { { 0 } }; + + /* Initialize the interrupt status of accel and gyro. */ + uint16_t int_status = 0; + + uint8_t indx = 1; + + float x = 0, y = 0, z = 0; + + /* Interface reference is given as a parameter + * For I2C : BMI2_I2C_INTF + * For SPI : BMI2_SPI_INTF + */ + rslt = bmi2_interface_init(&bmi2_dev, BMI2_I2C_INTF); + bmi2_error_codes_print_result(rslt); + + /* Initialize bmi270. */ + rslt = bmi270_wh_init(&bmi2_dev); + bmi2_error_codes_print_result(rslt); + + if (rslt == BMI2_OK) + { + /* Enable the accel and gyro sensor. */ + rslt = bmi270_wh_sensor_enable(sensor_list, 2, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + if (rslt == BMI2_OK) + { + /* Accel and gyro configuration settings. */ + rslt = set_accel_gyro_config(&bmi2_dev); + bmi2_error_codes_print_result(rslt); + + /* Assign accel and gyro sensor. */ + sensor_data[ACCEL].type = BMI2_ACCEL; + sensor_data[GYRO].type = BMI2_GYRO; + + /* Loop to print accel and gyro data when interrupt occurs. */ + while (indx <= limit) + { + /* To get the data ready interrupt status of accel and gyro. */ + rslt = bmi2_get_int_status(&int_status, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + /* To check the data ready interrupt status and print the status for 10 samples. */ + if ((int_status & BMI2_ACC_DRDY_INT_MASK) && (int_status & BMI2_GYR_DRDY_INT_MASK)) + { + /* Get accel and gyro data for x, y and z axis. */ + rslt = bmi270_wh_get_sensor_data(sensor_data, 2, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + printf("\n******* Accel(Raw and m/s2) Gyro(Raw and dps) data : %d *******\n", indx); + + printf("\nAcc_x = %d\t", sensor_data[ACCEL].sens_data.acc.x); + printf("Acc_y = %d\t", sensor_data[ACCEL].sens_data.acc.y); + printf("Acc_z = %d", sensor_data[ACCEL].sens_data.acc.z); + + /* Converting lsb to meter per second squared for 16 bit accelerometer at 2G range. */ + x = lsb_to_mps2(sensor_data[ACCEL].sens_data.acc.x, 2, bmi2_dev.resolution); + y = lsb_to_mps2(sensor_data[ACCEL].sens_data.acc.y, 2, bmi2_dev.resolution); + z = lsb_to_mps2(sensor_data[ACCEL].sens_data.acc.z, 2, bmi2_dev.resolution); + + /* Print the data in m/s2. */ + printf("\nAcc_ms2_X = %4.2f, Acc_ms2_Y = %4.2f, Acc_ms2_Z = %4.2f\n", x, y, z); + + printf("\nGyr_X = %d\t", sensor_data[GYRO].sens_data.gyr.x); + printf("Gyr_Y = %d\t", sensor_data[GYRO].sens_data.gyr.y); + printf("Gyr_Z= %d\n", sensor_data[GYRO].sens_data.gyr.z); + + /* Converting lsb to degree per second for 16 bit gyro at 2000dps range. */ + x = lsb_to_dps(sensor_data[GYRO].sens_data.gyr.x, 2000, bmi2_dev.resolution); + y = lsb_to_dps(sensor_data[GYRO].sens_data.gyr.y, 2000, bmi2_dev.resolution); + z = lsb_to_dps(sensor_data[GYRO].sens_data.gyr.z, 2000, bmi2_dev.resolution); + + /* Print the data in dps. */ + printf("Gyro_DPS_X = %4.2f, Gyro_DPS_Y = %4.2f, Gyro_DPS_Z = %4.2f\n", x, y, z); + + indx++; + } + } + } + } + + bmi2_coines_deinit(); + + return rslt; +} + +/*! + * @brief This internal API is used to set configurations for accel and gyro. + */ +static int8_t set_accel_gyro_config(struct bmi2_dev *bmi2_dev) +{ + /* Status of api are returned to this variable. */ + int8_t rslt; + + /* Structure to define accelerometer and gyro configuration. */ + struct bmi2_sens_config config[2]; + + /* Configure the type of feature. */ + config[ACCEL].type = BMI2_ACCEL; + config[GYRO].type = BMI2_GYRO; + + /* Get default configurations for the type of feature selected. */ + rslt = bmi270_wh_get_sensor_config(config, 2, bmi2_dev); + bmi2_error_codes_print_result(rslt); + + /* Map data ready interrupt to interrupt pin. */ + rslt = bmi2_map_data_int(BMI2_DRDY_INT, BMI2_INT1, bmi2_dev); + bmi2_error_codes_print_result(rslt); + + if (rslt == BMI2_OK) + { + /* NOTE: The user can change the following configuration parameters according to their requirement. */ + /* Set Output Data Rate */ + config[ACCEL].cfg.acc.odr = BMI2_ACC_ODR_200HZ; + + /* Gravity range of the sensor (+/- 2G, 4G, 8G, 16G). */ + config[ACCEL].cfg.acc.range = BMI2_ACC_RANGE_2G; + + /* The bandwidth parameter is used to configure the number of sensor samples that are averaged + * if it is set to 2, then 2^(bandwidth parameter) samples + * are averaged, resulting in 4 averaged samples. + * Note1 : For more information, refer the datasheet. + * Note2 : A higher number of averaged samples will result in a lower noise level of the signal, but + * this has an adverse effect on the power consumed. + */ + config[ACCEL].cfg.acc.bwp = BMI2_ACC_NORMAL_AVG4; + + /* Enable the filter performance mode where averaging of samples + * will be done based on above set bandwidth and ODR. + * There are two modes + * 0 -> Ultra low power mode + * 1 -> High performance mode(Default) + * For more info refer datasheet. + */ + config[ACCEL].cfg.acc.filter_perf = BMI2_PERF_OPT_MODE; + + /* The user can change the following configuration parameters according to their requirement. */ + /* Set Output Data Rate */ + config[GYRO].cfg.gyr.odr = BMI2_GYR_ODR_200HZ; + + /* Gyroscope Angular Rate Measurement Range.By default the range is 2000dps. */ + config[GYRO].cfg.gyr.range = BMI2_GYR_RANGE_2000; + + /* Gyroscope bandwidth parameters. By default the gyro bandwidth is in normal mode. */ + config[GYRO].cfg.gyr.bwp = BMI2_GYR_NORMAL_MODE; + + /* Enable/Disable the noise performance mode for precision yaw rate sensing + * There are two modes + * 0 -> Ultra low power mode(Default) + * 1 -> High performance mode + */ + config[GYRO].cfg.gyr.noise_perf = BMI2_POWER_OPT_MODE; + + /* Enable/Disable the filter performance mode where averaging of samples + * will be done based on above set bandwidth and ODR. + * There are two modes + * 0 -> Ultra low power mode + * 1 -> High performance mode(Default) + */ + config[GYRO].cfg.gyr.filter_perf = BMI2_PERF_OPT_MODE; + + /* Set the accel and gyro configurations. */ + rslt = bmi270_wh_set_sensor_config(config, 2, bmi2_dev); + bmi2_error_codes_print_result(rslt); + } + + return rslt; +} + +/*! + * @brief This function converts lsb to meter per second squared for 16 bit accelerometer at + * range 2G, 4G, 8G or 16G. + */ +static float lsb_to_mps2(int16_t val, float g_range, uint8_t bit_width) +{ + float half_scale = ((float)(1 << bit_width) / 2.0f); + + return (GRAVITY_EARTH * val * g_range) / half_scale; +} + +/*! + * @brief This function converts lsb to degree per second for 16 bit gyro at + * range 125, 250, 500, 1000 or 2000dps. + */ +static float lsb_to_dps(int16_t val, float dps, uint8_t bit_width) +{ + float half_scale = ((float)(1 << bit_width) / 2.0f); + + return (dps / ((half_scale) + BMI2_GYR_RANGE_2000)) * (val); +} diff --git a/examples/bmi270_wh/any_motion_interrupt/Makefile b/examples/bmi270_wh/any_motion_interrupt/Makefile new file mode 100644 index 0000000..1598c62 --- /dev/null +++ b/examples/bmi270_wh/any_motion_interrupt/Makefile @@ -0,0 +1,18 @@ +COINES_INSTALL_PATH ?= ../../../.. + +EXAMPLE_FILE ?= any_motion_interrupt.c + +API_LOCATION ?= ../.. + +COMMON_LOCATION ?= .. + +C_SRCS += \ +$(API_LOCATION)/bmi2.c \ +$(API_LOCATION)/bmi270_wh.c \ +$(COMMON_LOCATION)/common/common.c + +INCLUDEPATHS += \ +$(API_LOCATION) \ +$(COMMON_LOCATION)/common + +include $(COINES_INSTALL_PATH)/coines.mk \ No newline at end of file diff --git a/examples/bmi270_wh/any_motion_interrupt/any_motion_interrupt.c b/examples/bmi270_wh/any_motion_interrupt/any_motion_interrupt.c new file mode 100644 index 0000000..d1953e3 --- /dev/null +++ b/examples/bmi270_wh/any_motion_interrupt/any_motion_interrupt.c @@ -0,0 +1,134 @@ +/**\ + * Copyright (c) 2020 Bosch Sensortec GmbH. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + **/ + +/******************************************************************************/ +/*! Header Files */ +#include +#include "bmi270_wh.h" +#include "common.h" + +/******************************************************************************/ +/*! Static Function Declaration */ + +/*! + * @brief This internal API is used to set configurations for any-motion. + * + * @param[in] bmi2_dev : Structure instance of bmi2_dev. + * + * @return Status of execution. + */ +static int8_t set_feature_config(struct bmi2_dev *bmi2_dev); + +/******************************************************************************/ +/*! Functions */ + +/* This function starts the execution of program. */ +int main(void) +{ + /* Status of api are returned to this variable. */ + int8_t rslt; + + /* Accel sensor and any-motion feature are listed in array. */ + uint8_t sens_list[2] = { BMI2_ACCEL, BMI2_ANY_MOTION }; + + /* Variable to get any-motion interrupt status. */ + uint16_t int_status = 0; + + /* Sensor initialization configuration. */ + struct bmi2_dev bmi2_dev; + + /* Select features and their pins to be mapped to. */ + struct bmi2_sens_int_config sens_int = { .type = BMI2_ANY_MOTION, .hw_int_pin = BMI2_INT1 }; + + /* Interface reference is given as a parameter + * For I2C : BMI2_I2C_INTF + * For SPI : BMI2_SPI_INTF + */ + rslt = bmi2_interface_init(&bmi2_dev, BMI2_I2C_INTF); + bmi2_error_codes_print_result(rslt); + + /* Initialize bmi270_wh. */ + rslt = bmi270_wh_init(&bmi2_dev); + bmi2_error_codes_print_result(rslt); + + if (rslt == BMI2_OK) + { + /* Enable the selected sensors. */ + rslt = bmi270_wh_sensor_enable(sens_list, 2, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + if (rslt == BMI2_OK) + { + /* Set feature configurations for any-motion. */ + rslt = set_feature_config(&bmi2_dev); + bmi2_error_codes_print_result(rslt); + + if (rslt == BMI2_OK) + { + /* Map the feature interrupt for any-motion. */ + rslt = bmi270_wh_map_feat_int(&sens_int, 1, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + printf("Move the board\n"); + + /* Loop to get any-motion interrupt. */ + do + { + /* Clear buffer. */ + int_status = 0; + + /* To get the interrupt status of any-motion. */ + rslt = bmi2_get_int_status(&int_status, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + /* To check the interrupt status of any-motion. */ + if (int_status & BMI270_WH_ANY_MOT_STATUS_MASK) + { + printf("Any-motion interrupt is generated\n"); + break; + } + } while (rslt == BMI2_OK); + } + } + } + + bmi2_coines_deinit(); + + return rslt; +} + +/*! + * @brief This internal API is used to set configurations for any-motion. + */ +static int8_t set_feature_config(struct bmi2_dev *bmi2_dev) +{ + /* Status of api are returned to this variable. */ + int8_t rslt; + + /* Structure to define the type of sensor and its configurations. */ + struct bmi2_sens_config config; + + /* Configure the type of feature. */ + config.type = BMI2_ANY_MOTION; + + /* Get default configurations for the type of feature selected. */ + rslt = bmi270_wh_get_sensor_config(&config, 1, bmi2_dev); + bmi2_error_codes_print_result(rslt); + if (rslt == BMI2_OK) + { + /* NOTE: The user can change the following configuration parameters according to their requirement. */ + /* 1LSB equals 20ms. Default is 100ms, setting to 80ms. */ + config.cfg.any_motion.duration = 0x04; + + /* 1LSB equals to 0.48mg. Default is 83mg, setting to 50mg. */ + config.cfg.any_motion.threshold = 0x68; + + /* Set new configurations. */ + rslt = bmi270_wh_set_sensor_config(&config, 1, bmi2_dev); + bmi2_error_codes_print_result(rslt); + } + + return rslt; +} diff --git a/examples/bmi270_wh/common/common.c b/examples/bmi270_wh/common/common.c new file mode 100644 index 0000000..afff37b --- /dev/null +++ b/examples/bmi270_wh/common/common.c @@ -0,0 +1,372 @@ +/** + * Copyright (C) 2020 Bosch Sensortec GmbH. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include + +#include "coines.h" +#include "bmi2_defs.h" + +/******************************************************************************/ +/*! Macro definitions */ +#define BMI2XY_SHUTTLE_ID UINT16_C(0x1B8) + +/*! Macro that defines read write length */ +#define READ_WRITE_LEN UINT8_C(46) + +/******************************************************************************/ +/*! Static variable definition */ + +/*! Variable that holds the I2C device address or SPI chip selection */ +static uint8_t dev_addr; + +/******************************************************************************/ +/*! User interface functions */ + +/*! + * I2C read function map to COINES platform + */ +BMI2_INTF_RETURN_TYPE bmi2_i2c_read(uint8_t reg_addr, uint8_t *reg_data, uint32_t len, void *intf_ptr) +{ + uint8_t dev_addr = *(uint8_t*)intf_ptr; + + return coines_read_i2c(dev_addr, reg_addr, reg_data, (uint16_t)len); +} + +/*! + * I2C write function map to COINES platform + */ +BMI2_INTF_RETURN_TYPE bmi2_i2c_write(uint8_t reg_addr, const uint8_t *reg_data, uint32_t len, void *intf_ptr) +{ + uint8_t dev_addr = *(uint8_t*)intf_ptr; + + return coines_write_i2c(dev_addr, reg_addr, (uint8_t *)reg_data, (uint16_t)len); +} + +/*! + * SPI read function map to COINES platform + */ +BMI2_INTF_RETURN_TYPE bmi2_spi_read(uint8_t reg_addr, uint8_t *reg_data, uint32_t len, void *intf_ptr) +{ + uint8_t dev_addr = *(uint8_t*)intf_ptr; + + return coines_read_spi(dev_addr, reg_addr, reg_data, (uint16_t)len); +} + +/*! + * SPI write function map to COINES platform + */ +BMI2_INTF_RETURN_TYPE bmi2_spi_write(uint8_t reg_addr, const uint8_t *reg_data, uint32_t len, void *intf_ptr) +{ + uint8_t dev_addr = *(uint8_t*)intf_ptr; + + return coines_write_spi(dev_addr, reg_addr, (uint8_t *)reg_data, (uint16_t)len); +} + +/*! + * Delay function map to COINES platform + */ +void bmi2_delay_us(uint32_t period, void *intf_ptr) +{ + coines_delay_usec(period); +} + +/*! + * @brief Function to select the interface between SPI and I2C. + * Also to initialize coines platform + */ +int8_t bmi2_interface_init(struct bmi2_dev *bmi, uint8_t intf) +{ + int8_t rslt = BMI2_OK; + struct coines_board_info board_info; + + if (bmi != NULL) + { + int16_t result = coines_open_comm_intf(COINES_COMM_INTF_USB); + if (result < COINES_SUCCESS) + { + printf( + "\n Unable to connect with Application Board ! \n" " 1. Check if the board is connected and powered on. \n" " 2. Check if Application Board USB driver is installed. \n" + " 3. Check if board is in use by another application. (Insufficient permissions to access USB) \n"); + exit(result); + } + + result = coines_get_board_info(&board_info); + +#if defined(PC) + setbuf(stdout, NULL); +#endif + + if (result == COINES_SUCCESS) + { + if ((board_info.shuttle_id != BMI2XY_SHUTTLE_ID)) + { + printf("! Warning invalid sensor shuttle \n ," "This application will not support this sensor \n"); + exit(COINES_E_FAILURE); + } + } + + coines_set_shuttleboard_vdd_vddio_config(0, 0); + coines_delay_msec(100); + + /* Bus configuration : I2C */ + if (intf == BMI2_I2C_INTF) + { + printf("I2C Interface \n"); + + /* To initialize the user I2C function */ + dev_addr = BMI2_I2C_PRIM_ADDR; + bmi->intf = BMI2_I2C_INTF; + bmi->read = bmi2_i2c_read; + bmi->write = bmi2_i2c_write; + coines_config_i2c_bus(COINES_I2C_BUS_0, COINES_I2C_FAST_MODE); + } + /* Bus configuration : SPI */ + else if (intf == BMI2_SPI_INTF) + { + printf("SPI Interface \n"); + + /* To initialize the user SPI function */ + dev_addr = COINES_SHUTTLE_PIN_7; + bmi->intf = BMI2_SPI_INTF; + bmi->read = bmi2_spi_read; + bmi->write = bmi2_spi_write; + coines_config_spi_bus(COINES_SPI_BUS_0, COINES_SPI_SPEED_5_MHZ, COINES_SPI_MODE3); + coines_set_pin_config(COINES_SHUTTLE_PIN_7, COINES_PIN_DIRECTION_OUT, COINES_PIN_VALUE_HIGH); + } + + /* Assign device address to interface pointer */ + bmi->intf_ptr = &dev_addr; + + /* Configure delay in microseconds */ + bmi->delay_us = bmi2_delay_us; + + /* Configure max read/write length (in bytes) ( Supported length depends on target machine) */ + bmi->read_write_len = READ_WRITE_LEN; + + /* Assign to NULL to load the default config file. */ + bmi->config_file_ptr = NULL; + + coines_delay_usec(10000); + + coines_set_shuttleboard_vdd_vddio_config(3300, 3300); + + coines_delay_usec(10000); + } + else + { + rslt = BMI2_E_NULL_PTR; + } + + return rslt; + +} + +/*! + * @brief Prints the execution status of the APIs. + */ +void bmi2_error_codes_print_result(int8_t rslt) +{ + switch (rslt) + { + case BMI2_OK: + + /* Do nothing */ + break; + + case BMI2_W_FIFO_EMPTY: + printf("Warning [%d] : FIFO empty\r\n", rslt); + break; + case BMI2_W_PARTIAL_READ: + printf("Warning [%d] : FIFO partial read\r\n", rslt); + break; + case BMI2_E_NULL_PTR: + printf( + "Error [%d] : Null pointer error. It occurs when the user tries to assign value (not address) to a pointer," " which has been initialized to NULL.\r\n", + rslt); + break; + + case BMI2_E_COM_FAIL: + printf( + "Error [%d] : Communication failure error. It occurs due to read/write operation failure and also due " "to power failure during communication\r\n", + rslt); + break; + + case BMI2_E_DEV_NOT_FOUND: + printf("Error [%d] : Device not found error. It occurs when the device chip id is incorrectly read\r\n", + rslt); + break; + + case BMI2_E_INVALID_SENSOR: + printf( + "Error [%d] : Invalid sensor error. It occurs when there is a mismatch in the requested feature with the " "available one\r\n", + rslt); + break; + + case BMI2_E_SELF_TEST_FAIL: + printf( + "Error [%d] : Self-test failed error. It occurs when the validation of accel self-test data is " "not satisfied\r\n", + rslt); + break; + + case BMI2_E_INVALID_INT_PIN: + printf( + "Error [%d] : Invalid interrupt pin error. It occurs when the user tries to configure interrupt pins " "apart from INT1 and INT2\r\n", + rslt); + break; + + case BMI2_E_OUT_OF_RANGE: + printf( + "Error [%d] : Out of range error. It occurs when the data exceeds from filtered or unfiltered data from " "fifo and also when the range exceeds the maximum range for accel and gyro while performing FOC\r\n", + rslt); + break; + + case BMI2_E_ACC_INVALID_CFG: + printf( + "Error [%d] : Invalid Accel configuration error. It occurs when there is an error in accel configuration" " register which could be one among range, BW or filter performance in reg address 0x40\r\n", + rslt); + break; + + case BMI2_E_GYRO_INVALID_CFG: + printf( + "Error [%d] : Invalid Gyro configuration error. It occurs when there is a error in gyro configuration" "register which could be one among range, BW or filter performance in reg address 0x42\r\n", + rslt); + break; + + case BMI2_E_ACC_GYR_INVALID_CFG: + printf( + "Error [%d] : Invalid Accel-Gyro configuration error. It occurs when there is a error in accel and gyro" " configuration registers which could be one among range, BW or filter performance in reg address 0x40 " "and 0x42\r\n", + rslt); + break; + + case BMI2_E_CONFIG_LOAD: + printf( + "Error [%d] : Configuration load error. It occurs when failure observed while loading the configuration " "into the sensor\r\n", + rslt); + break; + + case BMI2_E_INVALID_PAGE: + printf( + "Error [%d] : Invalid page error. It occurs due to failure in writing the correct feature configuration " "from selected page\r\n", + rslt); + break; + + case BMI2_E_SET_APS_FAIL: + printf( + "Error [%d] : APS failure error. It occurs due to failure in write of advance power mode configuration " "register\r\n", + rslt); + break; + + case BMI2_E_AUX_INVALID_CFG: + printf( + "Error [%d] : Invalid AUX configuration error. It occurs when the auxiliary interface settings are not " "enabled properly\r\n", + rslt); + break; + + case BMI2_E_AUX_BUSY: + printf( + "Error [%d] : AUX busy error. It occurs when the auxiliary interface buses are engaged while configuring" " the AUX\r\n", + rslt); + break; + + case BMI2_E_REMAP_ERROR: + printf( + "Error [%d] : Remap error. It occurs due to failure in assigning the remap axes data for all the axes " "after change in axis position\r\n", + rslt); + break; + + case BMI2_E_GYR_USER_GAIN_UPD_FAIL: + printf( + "Error [%d] : Gyro user gain update fail error. It occurs when the reading of user gain update status " "fails\r\n", + rslt); + break; + + case BMI2_E_SELF_TEST_NOT_DONE: + printf( + "Error [%d] : Self-test not done error. It occurs when the self-test process is ongoing or not " "completed\r\n", + rslt); + break; + + case BMI2_E_INVALID_INPUT: + printf("Error [%d] : Invalid input error. It occurs when the sensor input validity fails\r\n", rslt); + break; + + case BMI2_E_INVALID_STATUS: + printf("Error [%d] : Invalid status error. It occurs when the feature/sensor validity fails\r\n", rslt); + break; + + case BMI2_E_CRT_ERROR: + printf("Error [%d] : CRT error. It occurs when the CRT test has failed\r\n", rslt); + break; + + case BMI2_E_ST_ALREADY_RUNNING: + printf( + "Error [%d] : Self-test already running error. It occurs when the self-test is already running and " "another has been initiated\r\n", + rslt); + break; + + case BMI2_E_CRT_READY_FOR_DL_FAIL_ABORT: + printf( + "Error [%d] : CRT ready for download fail abort error. It occurs when download in CRT fails due to wrong " "address location\r\n", + rslt); + break; + + case BMI2_E_DL_ERROR: + printf( + "Error [%d] : Download error. It occurs when write length exceeds that of the maximum burst length\r\n", + rslt); + break; + + case BMI2_E_PRECON_ERROR: + printf( + "Error [%d] : Pre-conditional error. It occurs when precondition to start the feature was not " "completed\r\n", + rslt); + break; + + case BMI2_E_ABORT_ERROR: + printf("Error [%d] : Abort error. It occurs when the device was shaken during CRT test\r\n", rslt); + break; + + case BMI2_E_WRITE_CYCLE_ONGOING: + printf( + "Error [%d] : Write cycle ongoing error. It occurs when the write cycle is already running and another " "has been initiated\r\n", + rslt); + break; + + case BMI2_E_ST_NOT_RUNING: + printf( + "Error [%d] : Self-test is not running error. It occurs when self-test running is disabled while it's " "running\r\n", + rslt); + break; + + case BMI2_E_DATA_RDY_INT_FAILED: + printf( + "Error [%d] : Data ready interrupt error. It occurs when the sample count exceeds the FOC sample limit " "and data ready status is not updated\r\n", + rslt); + break; + + case BMI2_E_INVALID_FOC_POSITION: + printf( + "Error [%d] : Invalid FOC position error. It occurs when average FOC data is obtained for the wrong" " axes\r\n", + rslt); + break; + + default: + printf("Error [%d] : Unknown error code\r\n", rslt); + break; + } +} + +/*! + * @brief Deinitializes coines platform + * + * @return void. + */ +void bmi2_coines_deinit(void) +{ + coines_close_comm_intf(COINES_COMM_INTF_USB); +} diff --git a/examples/bmi270_wh/common/common.h b/examples/bmi270_wh/common/common.h new file mode 100644 index 0000000..763983d --- /dev/null +++ b/examples/bmi270_wh/common/common.h @@ -0,0 +1,122 @@ +/**\ + * Copyright (c) 2020 Bosch Sensortec GmbH. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + **/ + +#ifndef _COMMON_H +#define _COMMON_H + +/*! CPP guard */ +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include "bmi2.h" + +/*! + * @brief Function for reading the sensor's registers through I2C bus. + * + * @param[in] reg_addr : Register address. + * @param[out] reg_data : Pointer to the data buffer to store the read data. + * @param[in] length : No of bytes to read. + * @param[in] intf_ptr : Interface pointer + * + * @return Status of execution + * @retval = BMI2_INTF_RET_SUCCESS -> Success + * @retval != BMI2_INTF_RET_SUCCESS -> Failure Info + * + */ +BMI2_INTF_RETURN_TYPE bmi2_i2c_read(uint8_t reg_addr, uint8_t *reg_data, uint32_t len, void *intf_ptr); + +/*! + * @brief Function for writing the sensor's registers through I2C bus. + * + * @param[in] reg_addr : Register address. + * @param[in] reg_data : Pointer to the data buffer whose value is to be written. + * @param[in] length : No of bytes to write. + * @param[in] intf_ptr : Interface pointer + * + * @return Status of execution + * @retval = BMI2_INTF_RET_SUCCESS -> Success + * @retval != BMI2_INTF_RET_SUCCESS -> Failure Info + * + */ +BMI2_INTF_RETURN_TYPE bmi2_i2c_write(uint8_t reg_addr, const uint8_t *reg_data, uint32_t len, void *intf_ptr); + +/*! + * @brief Function for reading the sensor's registers through SPI bus. + * + * @param[in] reg_addr : Register address. + * @param[out] reg_data : Pointer to the data buffer to store the read data. + * @param[in] length : No of bytes to read. + * @param[in] intf_ptr : Interface pointer + * + * @return Status of execution + * @retval = BMI2_INTF_RET_SUCCESS -> Success + * @retval != BMI2_INTF_RET_SUCCESS -> Failure Info + * + */ +BMI2_INTF_RETURN_TYPE bmi2_spi_read(uint8_t reg_addr, uint8_t *reg_data, uint32_t len, void *intf_ptr); + +/*! + * @brief Function for writing the sensor's registers through SPI bus. + * + * @param[in] reg_addr : Register address. + * @param[in] reg_data : Pointer to the data buffer whose data has to be written. + * @param[in] length : No of bytes to write. + * @param[in] intf_ptr : Interface pointer + * + * @return Status of execution + * @retval = BMI2_INTF_RET_SUCCESS -> Success + * @retval != BMI2_INTF_RET_SUCCESS -> Failure Info + * + */ +BMI2_INTF_RETURN_TYPE bmi2_spi_write(uint8_t reg_addr, const uint8_t *reg_data, uint32_t len, void *intf_ptr); + +/*! + * @brief This function provides the delay for required time (Microsecond) as per the input provided in some of the + * APIs. + * + * @param[in] period_us : The required wait time in microsecond. + * @param[in] intf_ptr : Interface pointer + * + * @return void. + * + */ +void bmi2_delay_us(uint32_t period, void *intf_ptr); + +/*! + * @brief Function to select the interface between SPI and I2C. + * + * @param[in] bma : Structure instance of bmi2_dev + * @param[in] intf : Interface selection parameter + * + * @return Status of execution + * @retval 0 -> Success + * @retval < 0 -> Failure Info + */ +int8_t bmi2_interface_init(struct bmi2_dev *bma, uint8_t intf); + +/*! + * @brief Prints the execution status of the APIs. + * + * @param[in] rslt : Error code returned by the API whose execution status has to be printed. + * + * @return void. + */ +void bmi2_error_codes_print_result(int8_t rslt); + +/*! + * @brief Deinitializes coines platform + * + * @return void. + */ +void bmi2_coines_deinit(void); + +#ifdef __cplusplus +} +#endif /* End of CPP guard */ + +#endif /* _COMMON_H */ diff --git a/examples/bmi270_wh/fifo_full_header_mode/Makefile b/examples/bmi270_wh/fifo_full_header_mode/Makefile new file mode 100644 index 0000000..bde7c19 --- /dev/null +++ b/examples/bmi270_wh/fifo_full_header_mode/Makefile @@ -0,0 +1,18 @@ +COINES_INSTALL_PATH ?= ../../../.. + +EXAMPLE_FILE ?= fifo_full_header_mode.c + +API_LOCATION ?= ../.. + +COMMON_LOCATION ?= .. + +C_SRCS += \ +$(API_LOCATION)/bmi2.c \ +$(API_LOCATION)/bmi270_wh.c \ +$(COMMON_LOCATION)/common/common.c + +INCLUDEPATHS += \ +$(API_LOCATION) \ +$(COMMON_LOCATION)/common + +include $(COINES_INSTALL_PATH)/coines.mk \ No newline at end of file diff --git a/examples/bmi270_wh/fifo_full_header_mode/fifo_full_header_mode.c b/examples/bmi270_wh/fifo_full_header_mode/fifo_full_header_mode.c new file mode 100644 index 0000000..ab331ea --- /dev/null +++ b/examples/bmi270_wh/fifo_full_header_mode/fifo_full_header_mode.c @@ -0,0 +1,316 @@ +/**\ + * Copyright (c) 2020 Bosch Sensortec GmbH. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + **/ + +/******************************************************************************/ +/*! Header Files */ +#include +#include "bmi270_wh.h" +#include "common.h" + +/******************************************************************************/ +/*! Macros */ + +/*! Buffer size allocated to store raw FIFO data. */ +#define BMI2_FIFO_RAW_DATA_BUFFER_SIZE UINT16_C(2048) + +/*! Length of data to be read from FIFO. */ +#define BMI2_FIFO_RAW_DATA_USER_LENGTH UINT16_C(2048) + +/*! Number of accel frames to be extracted from FIFO. */ + +/*! Calculation for frame count: Total frame count = Fifo buffer size(2048)/ Total frames(6 Accel, 6 Gyro and 1 header, + * totaling to 13) which equals to 157. + */ +#define BMI2_FIFO_ACCEL_FRAME_COUNT UINT8_C(157) + +/*! Number of gyro frames to be extracted from FIFO. */ +#define BMI2_FIFO_GYRO_FRAME_COUNT UINT8_C(157) + +/*! Macro to read sensortime byte in FIFO. */ +#define SENSORTIME_OVERHEAD_BYTE UINT8_C(3) + +/******************************************************************************/ +/*! Static Function Declaration */ + +/*! + * @brief This internal API is used to set configurations for accel and gyro. + * @param[in] dev : Structure instance of bmi2_dev. + * @return Status of execution. + */ +static int8_t set_accel_gyro_config(struct bmi2_dev *dev); + +/******************************************************************************/ + +/* This function starts the execution of program. */ +int main(void) +{ + /* Status of api are returned to this variable. */ + int8_t rslt; + + uint16_t index = 0; + uint16_t fifo_length = 0; + uint16_t config = 0; + + /* To read sensortime, extra 3 bytes are added to fifo buffer. */ + uint16_t fifo_buffer_size = BMI2_FIFO_RAW_DATA_BUFFER_SIZE + SENSORTIME_OVERHEAD_BYTE; + + /* Variable to get fifo full interrupt status. */ + uint16_t int_status = 0; + + uint16_t accel_frame_length = BMI2_FIFO_ACCEL_FRAME_COUNT; + + uint16_t gyro_frame_length = BMI2_FIFO_GYRO_FRAME_COUNT; + + /* Variable to store the available frame length count in FIFO */ + uint8_t frame_count; + + int8_t try = 1; + + /* Number of bytes of FIFO data. */ + uint8_t fifo_data[fifo_buffer_size]; + + /* Sensor initialization configuration. */ + struct bmi2_dev bmi2_dev; + + /* Array of accelerometer frames -> Total bytes = + * 157 * (6 axes + 1 header bytes) = 1099 bytes */ + struct bmi2_sens_axes_data fifo_accel_data[BMI2_FIFO_ACCEL_FRAME_COUNT] = { { 0 } }; + + /* Array of gyro frames -> Total bytes = + * 157 * (6 axes + 1 header bytes) = 1099 bytes */ + struct bmi2_sens_axes_data fifo_gyro_data[BMI2_FIFO_GYRO_FRAME_COUNT] = { { 0 } }; + + /* Initialize FIFO frame structure. */ + struct bmi2_fifo_frame fifoframe = { 0 }; + + /* Accel and gyro sensor are listed in array. */ + uint8_t sensor_sel[2] = { BMI2_ACCEL, BMI2_GYRO }; + + /* Interface reference is given as a parameter + * For I2C : BMI2_I2C_INTF + * For SPI : BMI2_SPI_INTF + */ + rslt = bmi2_interface_init(&bmi2_dev, BMI2_I2C_INTF); + bmi2_error_codes_print_result(rslt); + + /* Initialize bmi270_wh. */ + rslt = bmi270_wh_init(&bmi2_dev); + bmi2_error_codes_print_result(rslt); + + /* Enable accel and gyro sensor. */ + rslt = bmi270_wh_sensor_enable(sensor_sel, 2, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + /* Configuration settings for accel and gyro. */ + rslt = set_accel_gyro_config(&bmi2_dev); + bmi2_error_codes_print_result(rslt); + + /* Before setting FIFO, disable the advance power save mode. */ + rslt = bmi2_set_adv_power_save(BMI2_DISABLE, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + /* Initially disable all configurations in fifo. */ + rslt = bmi2_get_fifo_config(&config, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + /* Initially disable all configurations in fifo. */ + rslt = bmi2_set_fifo_config(BMI2_FIFO_ALL_EN, BMI2_DISABLE, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + /* Update FIFO structure. */ + /* Mapping the buffer to store the fifo data. */ + fifoframe.data = fifo_data; + + /* Length of FIFO frame. */ + /* To read sensortime, extra 3 bytes are added to fifo user length. */ + fifoframe.length = BMI2_FIFO_RAW_DATA_USER_LENGTH + SENSORTIME_OVERHEAD_BYTE; + + /* Set FIFO configuration by enabling accel, gyro and timestamp. + * NOTE 1: The header mode is enabled by default. + * NOTE 2: By default the FIFO operating mode is in FIFO mode. + * NOTE 3: Sensortime is enabled by default */ + printf("FIFO is configured in header mode\n"); + rslt = bmi2_set_fifo_config(BMI2_FIFO_ACC_EN | BMI2_FIFO_GYR_EN, BMI2_ENABLE, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + /* Map FIFO full interrupt. */ + fifoframe.data_int_map = BMI2_FFULL_INT; + rslt = bmi2_map_data_int(fifoframe.data_int_map, BMI2_INT1, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + while (try <= 10) + { + /* Read FIFO data on interrupt. */ + rslt = bmi2_get_int_status(&int_status, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + if ((rslt == BMI2_OK) && (int_status & BMI2_FFULL_INT_STATUS_MASK)) + { + printf("\nIteration : %d\n", try); + + accel_frame_length = BMI2_FIFO_ACCEL_FRAME_COUNT; + + gyro_frame_length = BMI2_FIFO_GYRO_FRAME_COUNT; + + rslt = bmi2_get_fifo_length(&fifo_length, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + printf("\nFIFO data bytes available : %d \n", fifo_length); + printf("\nFIFO data bytes requested : %d \n", fifoframe.length); + + /* Read FIFO data. */ + rslt = bmi2_read_fifo_data(&fifoframe, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + /* Read FIFO data on interrupt. */ + rslt = bmi2_get_int_status(&int_status, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + if (rslt == BMI2_OK) + { + printf("\nFIFO accel frames requested : %d \n", accel_frame_length); + + /* Parse the FIFO data to extract accelerometer data from the FIFO buffer. */ + rslt = bmi2_extract_accel(fifo_accel_data, &accel_frame_length, &fifoframe, &bmi2_dev); + printf("\nFIFO accel frames extracted : %d \n", accel_frame_length); + + printf("\nFIFO gyro frames requested : %d \n", gyro_frame_length); + + /* Parse the FIFO data to extract gyro data from the FIFO buffer. */ + rslt = bmi2_extract_gyro(fifo_gyro_data, &gyro_frame_length, &fifoframe, &bmi2_dev); + printf("\nFIFO gyro frames extracted : %d \n", gyro_frame_length); + + /* Calculating the frame count from the available bytes in FIFO + * frame_length = (available_fifo_bytes / (acc_frame_len + gyro_frame_len + header_byte)) */ + frame_count = (fifo_length / (BMI2_FIFO_ACC_GYR_LENGTH + 1)); + printf("\nAvailable frame count from available bytes: %d\n", frame_count); + + printf("\nExtracted accel frames\n"); + + if (accel_frame_length > frame_count) + { + accel_frame_length = frame_count; + } + + /* Print the parsed accelerometer data from the FIFO buffer. */ + for (index = 0; index < accel_frame_length; index++) + { + printf("ACCEL[%d] X : %d\t Y : %d\t Z : %d\n", index, fifo_accel_data[index].x, + fifo_accel_data[index].y, fifo_accel_data[index].z); + } + + printf("\nExtracted gyro frames\n"); + + if (gyro_frame_length > frame_count) + { + gyro_frame_length = frame_count; + } + + /* Print the parsed gyro data from the FIFO buffer. */ + for (index = 0; index < gyro_frame_length; index++) + { + printf("GYRO[%d] X : %d\t Y : %d\t Z : %d\n", + index, + fifo_gyro_data[index].x, + fifo_gyro_data[index].y, + fifo_gyro_data[index].z); + } + + /* Print control frames like sensor time and skipped frame count. */ + printf("\nSkipped frame count = %d\n", fifoframe.skipped_frame_count); + + printf("Sensor time = %lu\r\n", fifoframe.sensor_time); + + try++; + } + } + } + + bmi2_coines_deinit(); + + return rslt; +} + +/*! + * @brief This internal API is used to set configurations for accel and gyro. + */ +static int8_t set_accel_gyro_config(struct bmi2_dev *bmi2_dev) +{ + /* Status of api are returned to this variable. */ + int8_t rslt; + + /* Structure to define accel and gyro configurations. */ + struct bmi2_sens_config config[2]; + + /* Configure the type of feature. */ + config[0].type = BMI2_ACCEL; + config[1].type = BMI2_GYRO; + + /* Get default configurations for the type of feature selected. */ + rslt = bmi270_wh_get_sensor_config(config, 2, bmi2_dev); + bmi2_error_codes_print_result(rslt); + + if (rslt == BMI2_OK) + { + + /* NOTE: The user can change the following configuration parameters according to their requirement. */ + /* Accel configuration settings. */ + /* Set Output Data Rate */ + config[0].cfg.acc.odr = BMI2_ACC_ODR_25HZ; + + /* Gravity range of the sensor (+/- 2G, 4G, 8G, 16G). */ + config[0].cfg.acc.range = BMI2_ACC_RANGE_2G; + + /* The bandwidth parameter is used to configure the number of sensor samples that are averaged + * if it is set to 2, then 2^(bandwidth parameter) samples + * are averaged, resulting in 4 averaged samples + * Note1 : For more information, refer the datasheet. + * Note2 : A higher number of averaged samples will result in a lower noise level of the signal, but + * this has an adverse effect on the power consumed. + */ + config[0].cfg.acc.bwp = BMI2_ACC_NORMAL_AVG4; + + /* Enable the filter performance mode where averaging of samples + * will be done based on above set bandwidth and ODR. + * There are two modes + * 0 -> Ultra low power mode + * 1 -> High performance mode(Default) + * For more info refer datasheet. + */ + config[0].cfg.acc.filter_perf = BMI2_PERF_OPT_MODE; + + /* Gyro configuration settings. */ + /* Set Output Data Rate */ + config[1].cfg.gyr.odr = BMI2_GYR_ODR_25HZ; + + /* Gyroscope Angular Rate Measurement Range.By default the range is 2000dps. */ + config[1].cfg.gyr.range = BMI2_GYR_RANGE_2000; + + /* Gyroscope Bandwidth parameters. By default the gyro bandwidth is in normal mode. */ + config[1].cfg.gyr.bwp = BMI2_GYR_NORMAL_MODE; + + /* Enable/Disable the noise performance mode for precision yaw rate sensing + * There are two modes + * 0 -> Ultra low power mode(Default) + * 1 -> High performance mode + */ + config[1].cfg.gyr.noise_perf = BMI2_POWER_OPT_MODE; + + /* Enable/Disable the filter performance mode where averaging of samples + * will be done based on above set bandwidth and ODR. + * There are two modes + * 0 -> Ultra low power mode + * 1 -> High performance mode(Default) + */ + config[1].cfg.gyr.filter_perf = BMI2_PERF_OPT_MODE; + + /* Set new configurations. */ + rslt = bmi270_wh_set_sensor_config(config, 2, bmi2_dev); + bmi2_error_codes_print_result(rslt); + } + + return rslt; +} diff --git a/examples/bmi270_wh/fifo_full_headerless_mode/Makefile b/examples/bmi270_wh/fifo_full_headerless_mode/Makefile new file mode 100644 index 0000000..5c407e9 --- /dev/null +++ b/examples/bmi270_wh/fifo_full_headerless_mode/Makefile @@ -0,0 +1,18 @@ +COINES_INSTALL_PATH ?= ../../../.. + +EXAMPLE_FILE ?= fifo_full_headerless_mode.c + +API_LOCATION ?= ../.. + +COMMON_LOCATION ?= .. + +C_SRCS += \ +$(API_LOCATION)/bmi2.c \ +$(API_LOCATION)/bmi270_wh.c \ +$(COMMON_LOCATION)/common/common.c + +INCLUDEPATHS += \ +$(API_LOCATION) \ +$(COMMON_LOCATION)/common + +include $(COINES_INSTALL_PATH)/coines.mk \ No newline at end of file diff --git a/examples/bmi270_wh/fifo_full_headerless_mode/fifo_full_headerless_mode.c b/examples/bmi270_wh/fifo_full_headerless_mode/fifo_full_headerless_mode.c new file mode 100644 index 0000000..14b0b22 --- /dev/null +++ b/examples/bmi270_wh/fifo_full_headerless_mode/fifo_full_headerless_mode.c @@ -0,0 +1,304 @@ +/**\ + * Copyright (c) 2020 Bosch Sensortec GmbH. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + **/ + +/******************************************************************************/ +/*! Header Files */ +#include +#include "bmi270_wh.h" +#include "common.h" + +/******************************************************************************/ +/*! Macros */ + +/*! Buffer size allocated to store raw FIFO data */ +#define BMI2_FIFO_RAW_DATA_BUFFER_SIZE UINT16_C(2048) + +/*! Length of data to be read from FIFO */ +#define BMI2_FIFO_RAW_DATA_USER_LENGTH UINT16_C(2048) + +/*! Number of accel frames to be extracted from FIFO */ + +/*! Calculation for frame count: Total frame count = Fifo buffer size(2048)/ Total frames(6 Accel, 6 Gyro totaling to + * 12) which equals to 170. + */ +#define BMI2_FIFO_ACCEL_FRAME_COUNT UINT8_C(169) + +/*! Number of gyro frames to be extracted from FIFO */ +#define BMI2_FIFO_GYRO_FRAME_COUNT UINT8_C(169) + +/******************************************************************************/ +/*! Static Function Declaration */ + +/*! + * @brief This internal API is used to set configurations for accel and gyro. + * @param[in] dev : Structure instance of bmi2_dev. + * @return Status of execution. + */ +static int8_t set_accel_gyro_config(struct bmi2_dev *dev); + +/******************************************************************************/ + +/* This function starts the execution of program. */ +int main(void) +{ + /* Status of api are returned to this variable. */ + int8_t rslt; + + uint16_t index = 0; + + uint16_t fifo_length = 0; + + uint8_t try = 1; + + /* Variable to get fifo full interrupt status. */ + uint16_t int_status = 0; + + uint16_t accel_frame_length; + + uint16_t gyro_frame_length; + + /* Variable to store the available frame length count in FIFO */ + uint8_t frame_count; + + /* Number of bytes of FIFO data. */ + uint8_t fifo_data[BMI2_FIFO_RAW_DATA_BUFFER_SIZE] = { 0 }; + + /* Sensor initialization configuration. */ + struct bmi2_dev bmi2_dev; + + /* Array of accelerometer frames -> Total bytes = + * 170 * (6 axes bytes) = 1020 bytes */ + struct bmi2_sens_axes_data fifo_accel_data[BMI2_FIFO_ACCEL_FRAME_COUNT] = { { 0 } }; + + /* Array of gyro frames -> Total bytes = + * 170 * (6 axes bytes) = 1020 bytes */ + struct bmi2_sens_axes_data fifo_gyro_data[BMI2_FIFO_GYRO_FRAME_COUNT] = { { 0 } }; + + /* Initialize FIFO frame structure. */ + struct bmi2_fifo_frame fifoframe = { 0 }; + + /* Accel and gyro sensor are listed in array. */ + uint8_t sensor_sel[2] = { BMI2_ACCEL, BMI2_GYRO }; + + /* Interface reference is given as a parameter + * For I2C : BMI2_I2C_INTF + * For SPI : BMI2_SPI_INTF + */ + rslt = bmi2_interface_init(&bmi2_dev, BMI2_I2C_INTF); + bmi2_error_codes_print_result(rslt); + + /* Initialize bmi270_wh. */ + rslt = bmi270_wh_init(&bmi2_dev); + bmi2_error_codes_print_result(rslt); + + /* Enable accel and gyro sensor. */ + rslt = bmi270_wh_sensor_enable(sensor_sel, 2, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + /* Configuration settings for accel and gyro. */ + rslt = set_accel_gyro_config(&bmi2_dev); + bmi2_error_codes_print_result(rslt); + + /* Before setting FIFO, disable the advance power save mode. */ + rslt = bmi2_set_adv_power_save(BMI2_DISABLE, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + /* Initially disable all configurations in fifo. */ + rslt = bmi2_set_fifo_config(BMI2_FIFO_ALL_EN, BMI2_DISABLE, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + /* Update FIFO structure. */ + /* Mapping the buffer to store the fifo data. */ + fifoframe.data = fifo_data; + + /* Length of FIFO frame. */ + fifoframe.length = BMI2_FIFO_RAW_DATA_USER_LENGTH; + + /* Set FIFO configuration by enabling accel, gyro. + * NOTE 1: The header mode is enabled by default. + * NOTE 2: By default the FIFO operating mode is FIFO mode. */ + rslt = bmi2_set_fifo_config(BMI2_FIFO_ACC_EN | BMI2_FIFO_GYR_EN, BMI2_ENABLE, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + printf("FIFO is configured in headerless mode\n"); + + /* To enable headerless mode, disable the header. */ + if (rslt == BMI2_OK) + { + rslt = bmi2_set_fifo_config(BMI2_FIFO_HEADER_EN, BMI2_DISABLE, &bmi2_dev); + } + + /* Map FIFO full interrupt. */ + fifoframe.data_int_map = BMI2_FFULL_INT; + rslt = bmi2_map_data_int(fifoframe.data_int_map, BMI2_INT1, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + while (try <= 10) + { + /* Read FIFO data on interrupt. */ + rslt = bmi2_get_int_status(&int_status, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + if ((rslt == BMI2_OK) && (int_status & BMI2_FFULL_INT_STATUS_MASK)) + { + printf("\nIteration : %d\n", try); + + rslt = bmi2_get_fifo_length(&fifo_length, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + accel_frame_length = BMI2_FIFO_ACCEL_FRAME_COUNT; + gyro_frame_length = BMI2_FIFO_GYRO_FRAME_COUNT; + + printf("\nFIFO data bytes available : %d \n", fifo_length); + printf("\nFIFO data bytes requested : %d \n", fifoframe.length); + + /* Read FIFO data. */ + rslt = bmi2_read_fifo_data(&fifoframe, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + /* Read FIFO data on interrupt. */ + rslt = bmi2_get_int_status(&int_status, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + if (rslt == BMI2_OK) + { + printf("\nFIFO accel frames requested : %d \n", accel_frame_length); + + /* Parse the FIFO data to extract accelerometer data from the FIFO buffer. */ + rslt = bmi2_extract_accel(fifo_accel_data, &accel_frame_length, &fifoframe, &bmi2_dev); + printf("\nFIFO accel frames extracted : %d \n", accel_frame_length); + + printf("\nFIFO gyro frames requested : %d \n", gyro_frame_length); + + /* Parse the FIFO data to extract gyro data from the FIFO buffer. */ + rslt = bmi2_extract_gyro(fifo_gyro_data, &gyro_frame_length, &fifoframe, &bmi2_dev); + printf("\nFIFO gyro frames extracted : %d \n", gyro_frame_length); + + /* Calculating the frame count from the available bytes in FIFO + * frame_length = (available_fifo_bytes / (acc_frame_len + gyro_frame_len)) */ + frame_count = (fifo_length / (BMI2_FIFO_ACC_GYR_LENGTH)); + printf("\nAvailable frame count from available bytes: %d\n", frame_count); + + printf("\nExtracted accel frames\n"); + + if (accel_frame_length > frame_count) + { + accel_frame_length = frame_count; + } + + /* Print the parsed accelerometer data from the FIFO buffer. */ + for (index = 0; index < accel_frame_length; index++) + { + printf("ACCEL[%d] X : %d\t Y : %d\t Z : %d\n", index, fifo_accel_data[index].x, + fifo_accel_data[index].y, fifo_accel_data[index].z); + } + + printf("\nExtracted gyro frames\n"); + + if (gyro_frame_length > frame_count) + { + gyro_frame_length = frame_count; + } + + /* Print the parsed gyro data from the FIFO buffer. */ + for (index = 0; index < gyro_frame_length; index++) + { + printf("GYRO[%d] X : %d\t Y : %d\t Z : %d\n", + index, + fifo_gyro_data[index].x, + fifo_gyro_data[index].y, + fifo_gyro_data[index].z); + } + } + + try++; + } + } + + bmi2_coines_deinit(); + + return rslt; +} + +/*! + * @brief This internal API is used to set configurations for accel and gyro. + */ +static int8_t set_accel_gyro_config(struct bmi2_dev *bmi2_dev) +{ + /* Status of api are returned to this variable. */ + int8_t rslt; + + /* Structure to define accel and gyro configurations. */ + struct bmi2_sens_config config[2]; + + /* Configure the type of feature. */ + config[0].type = BMI2_ACCEL; + config[1].type = BMI2_GYRO; + + /* Get default configurations for the type of feature selected. */ + rslt = bmi270_wh_get_sensor_config(config, 2, bmi2_dev); + bmi2_error_codes_print_result(rslt); + + if (rslt == BMI2_OK) + { + /* NOTE: The user can change the following configuration parameters according to their requirement. */ + /* Accel configuration settings. */ + /* Set Output Data Rate */ + config[0].cfg.acc.odr = BMI2_ACC_ODR_100HZ; + + /* Gravity range of the sensor (+/- 2G, 4G, 8G, 16G). */ + config[0].cfg.acc.range = BMI2_ACC_RANGE_2G; + + /* The bandwidth parameter is used to configure the number of sensor samples that are averaged + * if it is set to 2, then 2^(bandwidth parameter) samples + * are averaged, resulting in 4 averaged samples + * Note1 : For more information, refer the datasheet. + * Note2 : A higher number of averaged samples will result in a lower noise level of the signal, but + * this has an adverse effect on the power consumed. + */ + config[0].cfg.acc.bwp = BMI2_ACC_NORMAL_AVG4; + + /* Enable the filter performance mode where averaging of samples + * will be done based on above set bandwidth and ODR. + * There are two modes + * 0 -> Ultra low power mode + * 1 -> High performance mode(Default) + * For more info refer datasheet. + */ + config[0].cfg.acc.filter_perf = BMI2_PERF_OPT_MODE; + + /* Gyro configuration settings. */ + /* Set Output Data Rate */ + config[1].cfg.gyr.odr = BMI2_GYR_ODR_100HZ; + + /* Gyroscope Angular Rate Measurement Range.By default the range is 2000dps. */ + config[1].cfg.gyr.range = BMI2_GYR_RANGE_2000; + + /* Gyroscope Bandwidth parameters. By default the gyro bandwidth is in normal mode. */ + config[1].cfg.gyr.bwp = BMI2_GYR_NORMAL_MODE; + + /* Enable/Disable the noise performance mode for precision yaw rate sensing + * There are two modes + * 0 -> Ultra low power mode(Default) + * 1 -> High performance mode + */ + config[1].cfg.gyr.noise_perf = BMI2_POWER_OPT_MODE; + + /* Enable/Disable the filter performance mode where averaging of samples + * will be done based on above set bandwidth and ODR. + * There are two modes + * 0 -> Ultra low power mode + * 1 -> High performance mode(Default) + */ + config[1].cfg.gyr.filter_perf = BMI2_PERF_OPT_MODE; + + /* Set new configurations. */ + rslt = bmi270_wh_set_sensor_config(config, 2, bmi2_dev); + bmi2_error_codes_print_result(rslt); + } + + return rslt; +} diff --git a/examples/bmi270_wh/fifo_watermark_header_mode/Makefile b/examples/bmi270_wh/fifo_watermark_header_mode/Makefile new file mode 100644 index 0000000..e0a42e3 --- /dev/null +++ b/examples/bmi270_wh/fifo_watermark_header_mode/Makefile @@ -0,0 +1,18 @@ +COINES_INSTALL_PATH ?= ../../../.. + +EXAMPLE_FILE ?= fifo_watermark_header_mode.c + +API_LOCATION ?= ../.. + +COMMON_LOCATION ?= .. + +C_SRCS += \ +$(API_LOCATION)/bmi2.c \ +$(API_LOCATION)/bmi270_wh.c \ +$(COMMON_LOCATION)/common/common.c + +INCLUDEPATHS += \ +$(API_LOCATION) \ +$(COMMON_LOCATION)/common + +include $(COINES_INSTALL_PATH)/coines.mk \ No newline at end of file diff --git a/examples/bmi270_wh/fifo_watermark_header_mode/fifo_watermark_header_mode.c b/examples/bmi270_wh/fifo_watermark_header_mode/fifo_watermark_header_mode.c new file mode 100644 index 0000000..f33bb5e --- /dev/null +++ b/examples/bmi270_wh/fifo_watermark_header_mode/fifo_watermark_header_mode.c @@ -0,0 +1,335 @@ +/**\ + * Copyright (c) 2020 Bosch Sensortec GmbH. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + **/ + +/******************************************************************************/ +/*! Header Files */ +#include +#include "bmi270_wh.h" +#include "common.h" + +/******************************************************************************/ +/*! Macros */ + +/*! Buffer size allocated to store raw FIFO data */ +#define BMI2_FIFO_RAW_DATA_BUFFER_SIZE UINT16_C(2048) + +/*! Length of data to be read from FIFO */ +#define BMI2_FIFO_RAW_DATA_USER_LENGTH UINT16_C(2048) + +/*! Number of accel frames to be extracted from FIFO */ + +/*! + * Calculation: + * fifo_watermark_level = 650, accel_frame_len = 6, gyro_frame_len = 6 header_byte = 1. + * fifo_accel_frame_count = (650 / (6 + 6 + 1 )) = 50 frames + * NOTE: Extra frames are read in order to get sensor time + */ +#define BMI2_FIFO_ACCEL_FRAME_COUNT UINT8_C(55) + +/*! Number of gyro frames to be extracted from FIFO */ +#define BMI2_FIFO_GYRO_FRAME_COUNT UINT8_C(55) + +/*! Setting a watermark level in FIFO */ +#define BMI270_FIFO_WATERMARK_LEVEL UINT16_C(650) + +/*! Macro to read sensortime byte in FIFO */ +#define SENSORTIME_OVERHEAD_BYTE UINT8_C(3) + +/******************************************************************************/ +/*! Static Function Declaration */ + +/*! + * @brief This internal API is used to set configurations for accel and gyro. + * @param[in] dev : Structure instance of bmi2_dev. + * @return Status of execution. + */ +static int8_t set_accel_gyro_config(struct bmi2_dev *dev); + +/******************************************************************************/ +/*! Functions */ + +/* This function starts the execution of program. */ +int main(void) +{ + /* Status of api are returned to this variable. */ + int8_t rslt; + + /* Variable to store the available frame length count in FIFO */ + uint8_t frame_count; + + /* Variable to index bytes. */ + uint16_t index = 0; + + uint16_t fifo_length = 0; + + uint16_t accel_frame_length; + + uint16_t gyro_frame_length; + + uint8_t try = 1; + + /* To read sensortime, extra 3 bytes are added to fifo buffer */ + uint16_t fifo_buffer_size = BMI2_FIFO_RAW_DATA_BUFFER_SIZE + SENSORTIME_OVERHEAD_BYTE; + + /* Number of bytes of FIFO data. */ + uint8_t fifo_data[fifo_buffer_size]; + + /* Sensor initialization configuration. */ + struct bmi2_dev bmi2_dev; + + /* Array of accelerometer frames -> Total bytes = + * 55 * (6 axes bytes) = 330 bytes */ + struct bmi2_sens_axes_data fifo_accel_data[BMI2_FIFO_ACCEL_FRAME_COUNT] = { { 0 } }; + + /* Array of gyro frames -> Total bytes = + * 55 * (6 axes bytes) = 330 bytes */ + struct bmi2_sens_axes_data fifo_gyro_data[BMI2_FIFO_GYRO_FRAME_COUNT] = { { 0 } }; + + /* Initialize FIFO frame structure. */ + struct bmi2_fifo_frame fifoframe = { 0 }; + + /* Accel and gyro sensor are listed in array. */ + uint8_t sensor_sel[2] = { BMI2_ACCEL, BMI2_GYRO }; + + /* Variable to get fifo water-mark interrupt status. */ + uint16_t int_status = 0; + + uint16_t watermark = 0; + + /* Interface reference is given as a parameter + * For I2C : BMI2_I2C_INTF + * For SPI : BMI2_SPI_INTF + */ + rslt = bmi2_interface_init(&bmi2_dev, BMI2_I2C_INTF); + bmi2_error_codes_print_result(rslt); + + /* Initialize bmi270_wh. */ + rslt = bmi270_wh_init(&bmi2_dev); + bmi2_error_codes_print_result(rslt); + + /* Enable accel and gyro sensor. */ + rslt = bmi270_wh_sensor_enable(sensor_sel, 2, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + /* Configuration settings for accel and gyro. */ + rslt = set_accel_gyro_config(&bmi2_dev); + bmi2_error_codes_print_result(rslt); + + /* Before setting FIFO, disable the advance power save mode. */ + rslt = bmi2_set_adv_power_save(BMI2_DISABLE, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + /* Initially disable all configurations in fifo. */ + rslt = bmi2_set_fifo_config(BMI2_FIFO_ALL_EN, BMI2_DISABLE, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + /* Update FIFO structure. */ + /* Mapping the buffer to store the fifo data. */ + fifoframe.data = fifo_data; + + /* Length of FIFO frame. */ + /* To read sensortime, extra 3 bytes are added to fifo user length. */ + fifoframe.length = BMI2_FIFO_RAW_DATA_USER_LENGTH + SENSORTIME_OVERHEAD_BYTE; + + /* Set FIFO configuration by enabling accel, gyro and timestamp. + * NOTE 1: The header mode is enabled by default. + * NOTE 2: By default the FIFO operating mode is FIFO mode. + * NOTE 3: Sensortime is enabled by default */ + printf("FIFO is configured in header mode\n"); + rslt = bmi2_set_fifo_config(BMI2_FIFO_ACC_EN | BMI2_FIFO_GYR_EN, BMI2_ENABLE, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + /* FIFO water-mark interrupt is enabled. */ + fifoframe.data_int_map = BMI2_FWM_INT; + + /* Map water-mark interrupt to the required interrupt pin. */ + rslt = bmi2_map_data_int(fifoframe.data_int_map, BMI2_INT1, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + /* Set water-mark level. */ + fifoframe.wm_lvl = BMI270_FIFO_WATERMARK_LEVEL; + + /* Set the water-mark level if water-mark interrupt is mapped. */ + rslt = bmi2_set_fifo_wm(fifoframe.wm_lvl, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + rslt = bmi2_get_fifo_wm(&watermark, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + printf("\nFIFO watermark level is %d\n", watermark); + + while (try <= 10) + { + /* Read FIFO data on interrupt. */ + rslt = bmi2_get_int_status(&int_status, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + /* To check the status of FIFO watermark interrupt. */ + if ((rslt == BMI2_OK) && (int_status & BMI2_FWM_INT_STATUS_MASK)) + { + printf("\nIteration : %d\n", try); + + printf("\nWatermark interrupt occurred\n"); + + rslt = bmi2_get_fifo_length(&fifo_length, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + accel_frame_length = BMI2_FIFO_ACCEL_FRAME_COUNT; + gyro_frame_length = BMI2_FIFO_GYRO_FRAME_COUNT; + + printf("\nFIFO data bytes available : %d \n", fifo_length); + printf("\nFIFO data bytes requested : %d \n", fifoframe.length); + + /* Read FIFO data. */ + rslt = bmi2_read_fifo_data(&fifoframe, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + /* Read FIFO data on interrupt. */ + rslt = bmi2_get_int_status(&int_status, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + if (rslt == BMI2_OK) + { + printf("\nFIFO accel frames requested : %d \n", accel_frame_length); + + /* Parse the FIFO data to extract accelerometer data from the FIFO buffer. */ + rslt = bmi2_extract_accel(fifo_accel_data, &accel_frame_length, &fifoframe, &bmi2_dev); + printf("\nFIFO accel frames extracted : %d \n", accel_frame_length); + + printf("\nFIFO gyro frames requested : %d \n", gyro_frame_length); + + /* Parse the FIFO data to extract gyro data from the FIFO buffer. */ + rslt = bmi2_extract_gyro(fifo_gyro_data, &gyro_frame_length, &fifoframe, &bmi2_dev); + printf("\nFIFO gyro frames extracted : %d \n", gyro_frame_length); + + /* Calculating the frame count from the available bytes in FIFO + * frame_length = (available_fifo_bytes / (acc_frame_len + gyro_frame_len + header_byte)) */ + frame_count = (fifo_length / (BMI2_FIFO_ACC_GYR_LENGTH + 1)); + printf("\nAvailable frame count from available bytes: %d\n", frame_count); + + printf("\nExracted accel frames\n"); + + if (accel_frame_length > frame_count) + { + accel_frame_length = frame_count; + } + + /* Print the parsed accelerometer data from the FIFO buffer. */ + for (index = 0; index < accel_frame_length; index++) + { + printf("ACCEL[%d] X : %d\t Y : %d\t Z : %d\n", index, fifo_accel_data[index].x, + fifo_accel_data[index].y, fifo_accel_data[index].z); + } + + printf("\nExtracted gyro frames\n"); + + if (gyro_frame_length > frame_count) + { + gyro_frame_length = frame_count; + } + + /* Print the parsed gyro data from the FIFO buffer. */ + for (index = 0; index < gyro_frame_length; index++) + { + printf("GYRO[%d] X : %d\t Y : %d\t Z : %d\n", + index, + fifo_gyro_data[index].x, + fifo_gyro_data[index].y, + fifo_gyro_data[index].z); + } + + /* Print control frames like sensor time and skipped frame count. */ + printf("Skipped frame count = %d\n", fifoframe.skipped_frame_count); + printf("Sensor time = %lu\r\n", fifoframe.sensor_time); + + try++; + } + } + } + + bmi2_coines_deinit(); + + return rslt; +} + +/*! + * @brief This internal API is used to set configurations for accel and gyro. + */ +static int8_t set_accel_gyro_config(struct bmi2_dev *dev) +{ + /* Status of api are returned to this variable. */ + int8_t rslt; + + /* Structure to define accel and gyro configurations. */ + struct bmi2_sens_config config[2]; + + /* Configure the type of feature. */ + config[0].type = BMI2_ACCEL; + config[1].type = BMI2_GYRO; + + /* Get default configurations for the type of feature selected. */ + rslt = bmi270_wh_get_sensor_config(config, 2, dev); + bmi2_error_codes_print_result(rslt); + + if (rslt == BMI2_OK) + { + /* NOTE: The user can change the following configuration parameters according to their requirement. */ + /* Accel configuration settings. */ + /* Set Output Data Rate */ + config[0].cfg.acc.odr = BMI2_ACC_ODR_25HZ; + + /* Gravity range of the sensor (+/- 2G, 4G, 8G, 16G). */ + config[0].cfg.acc.range = BMI2_ACC_RANGE_2G; + + /* The bandwidth parameter is used to configure the number of sensor samples that are averaged + * if it is set to 2, then 2^(bandwidth parameter) samples + * are averaged, resulting in 4 averaged samples + * Note1 : For more information, refer the datasheet. + * Note2 : A higher number of averaged samples will result in a lower noise level of the signal, but + * this has an adverse effect on the power consumed. + */ + config[0].cfg.acc.bwp = BMI2_ACC_NORMAL_AVG4; + + /* Enable the filter performance mode where averaging of samples + * will be done based on above set bandwidth and ODR. + * There are two modes + * 0 -> Ultra low power mode + * 1 -> High performance mode(Default) + * For more info refer datasheet. + */ + config[0].cfg.acc.filter_perf = BMI2_PERF_OPT_MODE; + + /* Gyro configuration settings. */ + /* Set Output Data Rate */ + config[1].cfg.gyr.odr = BMI2_GYR_ODR_25HZ; + + /* Gyroscope Angular Rate Measurement Range.By default the range is 2000dps. */ + config[1].cfg.gyr.range = BMI2_GYR_RANGE_2000; + + /* Gyroscope Bandwidth parameters. By default the gyro bandwidth is in normal mode. */ + config[1].cfg.gyr.bwp = BMI2_GYR_NORMAL_MODE; + + /* Enable/Disable the noise performance mode for precision yaw rate sensing + * There are two modes + * 0 -> Ultra low power mode(Default) + * 1 -> High performance mode + */ + config[1].cfg.gyr.noise_perf = BMI2_POWER_OPT_MODE; + + /* Enable/Disable the filter performance mode where averaging of samples + * will be done based on above set bandwidth and ODR. + * There are two modes + * 0 -> Ultra low power mode + * 1 -> High performance mode(Default) + */ + config[1].cfg.gyr.filter_perf = BMI2_PERF_OPT_MODE; + + /* Set new configurations. */ + rslt = bmi270_wh_set_sensor_config(config, 2, dev); + bmi2_error_codes_print_result(rslt); + } + + return rslt; +} diff --git a/examples/bmi270_wh/fifo_watermark_headerless_mode/Makefile b/examples/bmi270_wh/fifo_watermark_headerless_mode/Makefile new file mode 100644 index 0000000..ce97737 --- /dev/null +++ b/examples/bmi270_wh/fifo_watermark_headerless_mode/Makefile @@ -0,0 +1,18 @@ +COINES_INSTALL_PATH ?= ../../../.. + +EXAMPLE_FILE ?= fifo_watermark_headerless_mode.c + +API_LOCATION ?= ../.. + +COMMON_LOCATION ?= .. + +C_SRCS += \ +$(API_LOCATION)/bmi2.c \ +$(API_LOCATION)/bmi270_wh.c \ +$(COMMON_LOCATION)/common/common.c + +INCLUDEPATHS += \ +$(API_LOCATION) \ +$(COMMON_LOCATION)/common + +include $(COINES_INSTALL_PATH)/coines.mk \ No newline at end of file diff --git a/examples/bmi270_wh/fifo_watermark_headerless_mode/fifo_watermark_headerless_mode.c b/examples/bmi270_wh/fifo_watermark_headerless_mode/fifo_watermark_headerless_mode.c new file mode 100644 index 0000000..160c01d --- /dev/null +++ b/examples/bmi270_wh/fifo_watermark_headerless_mode/fifo_watermark_headerless_mode.c @@ -0,0 +1,331 @@ +/**\ + * Copyright (c) 2020 Bosch Sensortec GmbH. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + **/ + +/******************************************************************************/ +/*! Header Files */ +#include +#include "bmi270_wh.h" +#include "common.h" + +/******************************************************************************/ +/*! Macros */ + +/*! Buffer size allocated to store raw FIFO data */ +#define BMI2_FIFO_RAW_DATA_BUFFER_SIZE UINT16_C(2048) + +/*! Length of data to be read from FIFO */ +#define BMI2_FIFO_RAW_DATA_USER_LENGTH UINT16_C(2048) + +/*! Number of accel frames to be extracted from FIFO */ + +/*! + * Calculation: + * fifo_watermark_level = 650, accel_frame_len = 6, gyro_frame_len = 6. + * fifo_accel_frame_count = (650 / (6 + 6 )) = 54 frames + */ +#define BMI2_FIFO_ACCEL_FRAME_COUNT UINT8_C(55) + +/*! Number of gyro frames to be extracted from FIFO */ +#define BMI2_FIFO_GYRO_FRAME_COUNT UINT8_C(55) + +/*! Setting a watermark level in FIFO */ +#define BMI270_FIFO_WATERMARK_LEVEL UINT16_C(650) + +/******************************************************************************/ +/*! Static Function Declaration */ + +/*! + * @brief This internal API is used to set configurations for accel and gyro. + * @param[in] dev : Structure instance of bmi2_dev. + * @return Status of execution. + */ +static int8_t set_accel_gyro_config(struct bmi2_dev *dev); + +/******************************************************************************/ +/*! Functions */ + +/* This function starts the execution of program. */ +int main(void) +{ + /* Status of api are returned to this variable. */ + int8_t rslt; + + /* Variable to index bytes. */ + uint16_t index = 0; + + /* Variable to store the available frame length count in FIFO */ + uint8_t frame_count; + + uint16_t fifo_length = 0; + + uint16_t accel_frame_length; + + uint16_t gyro_frame_length; + + uint8_t try = 1; + + /* Number of bytes of FIFO data. */ + uint8_t fifo_data[BMI2_FIFO_RAW_DATA_BUFFER_SIZE] = { 0 }; + + /* Sensor initialization configuration. */ + struct bmi2_dev bmi2_dev; + + /* Array of accelerometer frames -> Total bytes = + * 50 * (6 axes bytes) = 300 bytes */ + struct bmi2_sens_axes_data fifo_accel_data[BMI2_FIFO_ACCEL_FRAME_COUNT] = { { 0 } }; + + /* Array of gyro frames -> Total bytes = + * 50 * (6 axes bytes) = 300 bytes */ + struct bmi2_sens_axes_data fifo_gyro_data[BMI2_FIFO_GYRO_FRAME_COUNT] = { { 0 } }; + + /* Initialize FIFO frame structure. */ + struct bmi2_fifo_frame fifoframe = { 0 }; + + /* Accel and gyro sensor are listed in array. */ + uint8_t sensor_sel[2] = { BMI2_ACCEL, BMI2_GYRO }; + + /* Variable to get fifo water-mark interrupt status. */ + uint16_t int_status = 0; + + uint16_t watermark = 0; + + /* Interface reference is given as a parameter + * For I2C : BMI2_I2C_INTF + * For SPI : BMI2_SPI_INTF + */ + rslt = bmi2_interface_init(&bmi2_dev, BMI2_I2C_INTF); + bmi2_error_codes_print_result(rslt); + + /* Initialize bmi270_wh. */ + rslt = bmi270_wh_init(&bmi2_dev); + bmi2_error_codes_print_result(rslt); + + /* Enable accel and gyro sensor. */ + rslt = bmi270_wh_sensor_enable(sensor_sel, 2, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + /* Configuration settings for accel and gyro. */ + rslt = set_accel_gyro_config(&bmi2_dev); + bmi2_error_codes_print_result(rslt); + + /* Before setting FIFO, disable the advance power save mode. */ + rslt = bmi2_set_adv_power_save(BMI2_DISABLE, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + /* Initially disable all configurations in fifo. */ + rslt = bmi2_set_fifo_config(BMI2_FIFO_ALL_EN, BMI2_DISABLE, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + /* Update FIFO structure. */ + /* Mapping the buffer to store the fifo data. */ + fifoframe.data = fifo_data; + + /* Length of FIFO frame. */ + fifoframe.length = BMI2_FIFO_RAW_DATA_USER_LENGTH; + + /* Set FIFO configuration by enabling accel, gyro. + * NOTE 1: The header mode is enabled by default. + * NOTE 2: By default the FIFO operating mode is FIFO mode. */ + rslt = bmi2_set_fifo_config(BMI2_FIFO_ACC_EN | BMI2_FIFO_GYR_EN, BMI2_ENABLE, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + printf("FIFO is configured in headerless mode\n"); + + /* To enable headerless mode, disable the header. */ + if (rslt == BMI2_OK) + { + rslt = bmi2_set_fifo_config(BMI2_FIFO_HEADER_EN, BMI2_DISABLE, &bmi2_dev); + } + + /* FIFO water-mark interrupt is enabled. */ + fifoframe.data_int_map = BMI2_FWM_INT; + + /* Map water-mark interrupt to the required interrupt pin. */ + rslt = bmi2_map_data_int(fifoframe.data_int_map, BMI2_INT1, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + /* Set water-mark level. */ + fifoframe.wm_lvl = BMI270_FIFO_WATERMARK_LEVEL; + + fifoframe.length = BMI2_FIFO_RAW_DATA_USER_LENGTH; + + /* Set the water-mark level if water-mark interrupt is mapped. */ + rslt = bmi2_set_fifo_wm(fifoframe.wm_lvl, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + rslt = bmi2_get_fifo_wm(&watermark, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + printf("\nFIFO watermark level is %d\n", watermark); + + while (try <= 10) + { + /* Read FIFO data on interrupt. */ + rslt = bmi2_get_int_status(&int_status, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + /* To check the status of FIFO watermark interrupt. */ + if ((rslt == BMI2_OK) && (int_status & BMI2_FWM_INT_STATUS_MASK)) + { + printf("\nIteration : %d\n", try); + + printf("\nWatermark interrupt occurred\n"); + + rslt = bmi2_get_fifo_length(&fifo_length, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + accel_frame_length = BMI2_FIFO_ACCEL_FRAME_COUNT; + gyro_frame_length = BMI2_FIFO_GYRO_FRAME_COUNT; + + printf("\nFIFO data bytes available : %d \n", fifo_length); + printf("\nFIFO data bytes requested : %d \n", fifoframe.length); + + /* Read FIFO data. */ + rslt = bmi2_read_fifo_data(&fifoframe, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + /* Read FIFO data on interrupt. */ + rslt = bmi2_get_int_status(&int_status, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + if (rslt == BMI2_OK) + { + printf("\nFIFO accel frames requested : %d \n", accel_frame_length); + + /* Parse the FIFO data to extract accelerometer data from the FIFO buffer. */ + rslt = bmi2_extract_accel(fifo_accel_data, &accel_frame_length, &fifoframe, &bmi2_dev); + printf("\nFIFO accel frames extracted : %d \n", accel_frame_length); + + printf("\nFIFO gyro frames requested : %d \n", gyro_frame_length); + + /* Parse the FIFO data to extract gyro data from the FIFO buffer. */ + rslt = bmi2_extract_gyro(fifo_gyro_data, &gyro_frame_length, &fifoframe, &bmi2_dev); + printf("\nFIFO gyro frames extracted : %d \n", gyro_frame_length); + + /* Calculating the frame count from the available bytes in FIFO + * frame_length = (available_fifo_bytes / (acc_frame_len + gyro_frame_len)) */ + frame_count = (fifo_length / (BMI2_FIFO_ACC_GYR_LENGTH)); + printf("\nAvailable frame count from available bytes: %d\n", frame_count); + + printf("\nExracted accel frames\n"); + + if (accel_frame_length > frame_count) + { + accel_frame_length = frame_count; + } + + /* Print the parsed accelerometer data from the FIFO buffer. */ + for (index = 0; index < accel_frame_length; index++) + { + printf("ACCEL[%d] X : %d\t Y : %d\t Z : %d\n", index, fifo_accel_data[index].x, + fifo_accel_data[index].y, fifo_accel_data[index].z); + } + + printf("\nExtracted gyro frames\n"); + + if (gyro_frame_length > frame_count) + { + gyro_frame_length = frame_count; + } + + /* Print the parsed gyro data from the FIFO buffer. */ + for (index = 0; index < gyro_frame_length; index++) + { + printf("GYRO[%d] X : %d\t Y : %d\t Z : %d\n", + index, + fifo_gyro_data[index].x, + fifo_gyro_data[index].y, + fifo_gyro_data[index].z); + } + } + + try++; + } + } + + bmi2_coines_deinit(); + + return rslt; +} + +/*! + * @brief This internal API is used to set configurations for accel. + */ +static int8_t set_accel_gyro_config(struct bmi2_dev *dev) +{ + /* Status of api are returned to this variable. */ + int8_t rslt; + + /* Structure to define accel and gyro configurations. */ + struct bmi2_sens_config config[2]; + + /* Configure the type of feature. */ + config[0].type = BMI2_ACCEL; + config[1].type = BMI2_GYRO; + + /* Get default configurations for the type of feature selected. */ + rslt = bmi270_wh_get_sensor_config(config, 2, dev); + bmi2_error_codes_print_result(rslt); + + if (rslt == BMI2_OK) + { + /* NOTE: The user can change the following configuration parameter according to their requirement. */ + /* Accel configuration settings. */ + /* Set Output Data Rate */ + config[0].cfg.acc.odr = BMI2_ACC_ODR_100HZ; + + /* Gravity range of the sensor (+/- 2G, 4G, 8G, 16G). */ + config[0].cfg.acc.range = BMI2_ACC_RANGE_2G; + + /* The bandwidth parameter is used to configure the number of sensor samples that are averaged + * if it is set to 2, then 2^(bandwidth parameter) samples + * are averaged, resulting in 4 averaged samples + * Note1 : For more information, refer the datasheet. + * Note2 : A higher number of averaged samples will result in a lower noise level of the signal, but + * this has an adverse effect on the power consumed. + */ + config[0].cfg.acc.bwp = BMI2_ACC_NORMAL_AVG4; + + /* Enable the filter performance mode where averaging of samples + * will be done based on above set bandwidth and ODR. + * There are two modes + * 0 -> Ultra low power mode + * 1 -> High performance mode(Default) + * For more info refer datasheet. + */ + config[0].cfg.acc.filter_perf = BMI2_PERF_OPT_MODE; + + /* Gyro configuration settings. */ + /* Set Output Data Rate */ + config[1].cfg.gyr.odr = BMI2_GYR_ODR_100HZ; + + /* Gyroscope Angular Rate Measurement Range.By default the range is 2000dps. */ + config[1].cfg.gyr.range = BMI2_GYR_RANGE_2000; + + /* Gyroscope Bandwidth parameters. By default the gyro bandwidth is in normal mode. */ + config[1].cfg.gyr.bwp = BMI2_GYR_NORMAL_MODE; + + /* Enable/Disable the noise performance mode for precision yaw rate sensing + * There are two modes + * 0 -> Ultra low power mode(Default) + * 1 -> High performance mode + */ + config[1].cfg.gyr.noise_perf = BMI2_POWER_OPT_MODE; + + /* Enable/Disable the filter performance mode where averaging of samples + * will be done based on above set bandwidth and ODR. + * There are two modes + * 0 -> Ultra low power mode + * 1 -> High performance mode(Default) + */ + config[1].cfg.gyr.filter_perf = BMI2_PERF_OPT_MODE; + + /* Set new configurations. */ + rslt = bmi270_wh_set_sensor_config(config, 2, dev); + bmi2_error_codes_print_result(rslt); + } + + return rslt; +} diff --git a/examples/bmi270_wh/gyro/Makefile b/examples/bmi270_wh/gyro/Makefile new file mode 100644 index 0000000..9192877 --- /dev/null +++ b/examples/bmi270_wh/gyro/Makefile @@ -0,0 +1,18 @@ +COINES_INSTALL_PATH ?= ../../../.. + +EXAMPLE_FILE ?= gyro.c + +API_LOCATION ?= ../.. + +COMMON_LOCATION ?= .. + +C_SRCS += \ +$(API_LOCATION)/bmi2.c \ +$(API_LOCATION)/bmi270_wh.c \ +$(COMMON_LOCATION)/common/common.c + +INCLUDEPATHS += \ +$(API_LOCATION) \ +$(COMMON_LOCATION)/common + +include $(COINES_INSTALL_PATH)/coines.mk \ No newline at end of file diff --git a/examples/bmi270_wh/gyro/gyro.c b/examples/bmi270_wh/gyro/gyro.c new file mode 100644 index 0000000..d1ce9fe --- /dev/null +++ b/examples/bmi270_wh/gyro/gyro.c @@ -0,0 +1,195 @@ +/**\ + * Copyright (c) 2020 Bosch Sensortec GmbH. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + **/ + +/******************************************************************************/ +/*! Header Files */ +#include +#include "bmi270_wh.h" +#include "common.h" + +/******************************************************************************/ +/*! Static Function Declaration */ + +/*! + * @brief This internal API is used to set configurations for gyro. + * + * @param[in] dev : Structure instance of bmi2_dev. + * + * @return Status of execution. + */ +static int8_t set_gyro_config(struct bmi2_dev *dev); + +/*! + * @brief This function converts lsb to degree per second for 16 bit gyro at + * range 125, 250, 500, 1000 or 2000dps. + * + * @param[in] val : LSB from each axis. + * @param[in] dps : Degree per second. + * @param[in] bit_width : Resolution for gyro. + * + * @return Degree per second. + */ +static float lsb_to_dps(int16_t val, float dps, uint8_t bit_width); + +/******************************************************************************/ +/*! Functions */ + +/* This function starts the execution of program. */ +int main(void) +{ + /* Status of api are returned to this variable. */ + int8_t rslt; + + /* Variable to define limit to print gyro data. */ + uint8_t limit = 10; + + uint8_t indx = 0; + + float x = 0, y = 0, z = 0; + + /* Sensor initialization configuration. */ + struct bmi2_dev bmi2_dev; + + /* Create an instance of sensor data structure. */ + struct bmi2_sensor_data sensor_data = { 0 }; + + /* Assign gyro sensor to variable. */ + uint8_t sens_list = BMI2_GYRO; + + /* Initialize the interrupt status of gyro. */ + uint16_t int_status = 0; + + /* Interface reference is given as a parameter + * For I2C : BMI2_I2C_INTF + * For SPI : BMI2_SPI_INTF + */ + rslt = bmi2_interface_init(&bmi2_dev, BMI2_I2C_INTF); + bmi2_error_codes_print_result(rslt); + + /* Initialize bmi270_wh. */ + rslt = bmi270_wh_init(&bmi2_dev); + bmi2_error_codes_print_result(rslt); + + if (rslt == BMI2_OK) + { + /* Enable the selected sensors. */ + rslt = bmi270_wh_sensor_enable(&sens_list, 1, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + if (rslt == BMI2_OK) + { + /* Gyro configuration settings. */ + rslt = set_gyro_config(&bmi2_dev); + bmi2_error_codes_print_result(rslt); + + /* Select gyro sensor. */ + sensor_data.type = BMI2_GYRO; + printf("Gyro and DPS data\n"); + printf("Gyro data collected at Range 2000 dps with 16-bit resolution\n"); + + /* Loop to print gyro data when interrupt occurs. */ + while (indx <= limit) + { + /* To get the data ready interrupt status of gyro. */ + rslt = bmi2_get_int_status(&int_status, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + /* To check the data ready interrupt status and print the status for 10 samples. */ + if (int_status & BMI2_GYR_DRDY_INT_MASK) + { + /* Get gyro data for x, y and z axis. */ + rslt = bmi270_wh_get_sensor_data(&sensor_data, 1, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + printf("\nGyr_X = %d\t", sensor_data.sens_data.gyr.x); + printf("Gyr_Y = %d\t", sensor_data.sens_data.gyr.y); + printf("Gyr_Z = %d\r\n", sensor_data.sens_data.gyr.z); + + /* Converting lsb to degree per second for 16 bit gyro at 2000dps range. */ + x = lsb_to_dps(sensor_data.sens_data.gyr.x, 2000, bmi2_dev.resolution); + y = lsb_to_dps(sensor_data.sens_data.gyr.y, 2000, bmi2_dev.resolution); + z = lsb_to_dps(sensor_data.sens_data.gyr.z, 2000, bmi2_dev.resolution); + + /* Print the data in dps. */ + printf("Gyr_DPS_X = %4.2f, Gyr_DPS_Y = %4.2f, Gyr_DPS_Z = %4.2f\n", x, y, z); + + indx++; + } + } + } + } + + bmi2_coines_deinit(); + + return rslt; +} + +/*! + * @brief This internal API is used to set configurations for gyro. + */ +static int8_t set_gyro_config(struct bmi2_dev *dev) +{ + /* Status of api are returned to this variable. */ + int8_t rslt; + + /* Structure to define the type of sensor and its configurations. */ + struct bmi2_sens_config config; + + /* Configure the type of feature. */ + config.type = BMI2_GYRO; + + /* Get default configurations for the type of feature selected. */ + rslt = bmi270_wh_get_sensor_config(&config, 1, dev); + bmi2_error_codes_print_result(rslt); + + /* Map data ready interrupt to interrupt pin. */ + rslt = bmi2_map_data_int(BMI2_DRDY_INT, BMI2_INT2, dev); + bmi2_error_codes_print_result(rslt); + + if (rslt == BMI2_OK) + { + /* The user can change the following configuration parameters according to their requirement. */ + /* Set Output Data Rate */ + config.cfg.gyr.odr = BMI2_GYR_ODR_200HZ; + + /* Gyroscope Angular Rate Measurement Range.By default the range is 2000dps. */ + config.cfg.gyr.range = BMI2_GYR_RANGE_2000; + + /* Gyroscope bandwidth parameters. By default the gyro bandwidth is in normal mode. */ + config.cfg.gyr.bwp = BMI2_GYR_NORMAL_MODE; + + /* Enable/Disable the noise performance mode for precision yaw rate sensing + * There are two modes + * 0 -> Ultra low power mode(Default) + * 1 -> High performance mode + */ + config.cfg.gyr.noise_perf = BMI2_POWER_OPT_MODE; + + /* Enable/Disable the filter performance mode where averaging of samples + * will be done based on above set bandwidth and ODR. + * There are two modes + * 0 -> Ultra low power mode + * 1 -> High performance mode(Default) + */ + config.cfg.gyr.filter_perf = BMI2_PERF_OPT_MODE; + + /* Set the gyro configurations. */ + rslt = bmi270_wh_set_sensor_config(&config, 1, dev); + } + + return rslt; +} + +/*! + * @brief This function converts lsb to degree per second for 16 bit gyro at + * range 125, 250, 500, 1000 or 2000dps. + */ +static float lsb_to_dps(int16_t val, float dps, uint8_t bit_width) +{ + float half_scale = ((float)(1 << bit_width) / 2.0f); + + return (dps / ((half_scale) + BMI2_GYR_RANGE_2000)) * (val); +} diff --git a/examples/bmi270_wh/no_motion_interrupt/Makefile b/examples/bmi270_wh/no_motion_interrupt/Makefile new file mode 100644 index 0000000..61b7016 --- /dev/null +++ b/examples/bmi270_wh/no_motion_interrupt/Makefile @@ -0,0 +1,18 @@ +COINES_INSTALL_PATH ?= ../../../.. + +EXAMPLE_FILE ?= no_motion_interrupt.c + +API_LOCATION ?= ../.. + +COMMON_LOCATION ?= .. + +C_SRCS += \ +$(API_LOCATION)/bmi2.c \ +$(API_LOCATION)/bmi270_wh.c \ +$(COMMON_LOCATION)/common/common.c + +INCLUDEPATHS += \ +$(API_LOCATION) \ +$(COMMON_LOCATION)/common + +include $(COINES_INSTALL_PATH)/coines.mk \ No newline at end of file diff --git a/examples/bmi270_wh/no_motion_interrupt/no_motion_interrupt.c b/examples/bmi270_wh/no_motion_interrupt/no_motion_interrupt.c new file mode 100644 index 0000000..5f584de --- /dev/null +++ b/examples/bmi270_wh/no_motion_interrupt/no_motion_interrupt.c @@ -0,0 +1,135 @@ +/**\ + * Copyright (c) 2020 Bosch Sensortec GmbH. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + **/ + +/******************************************************************************/ +/*! Header Files */ +#include +#include "bmi270_wh.h" +#include "common.h" + +/******************************************************************************/ +/*! Static Function Declaration */ + +/*! + * @brief This internal API is used to set configurations for no-motion. + * + * @param[in] bmi2_dev : Structure instance of bmi2_dev. + * + * @return Status of execution. + */ +static int8_t set_feature_config(struct bmi2_dev *bmi2_dev); + +/******************************************************************************/ +/*! Functions */ + +/* This function starts the execution of program. */ +int main(void) +{ + /* Status of api are returned to this variable. */ + int8_t rslt; + + /* Accel sensor and no-motion feature are listed in array. */ + uint8_t sens_list[2] = { BMI2_ACCEL, BMI2_NO_MOTION }; + + /* Variable to get no-motion interrupt status. */ + uint16_t int_status = 0; + + /* Sensor initialization configuration. */ + struct bmi2_dev bmi2_dev; + + /* Select features and their pins to be mapped to. */ + struct bmi2_sens_int_config sens_int = { .type = BMI2_NO_MOTION, .hw_int_pin = BMI2_INT1 }; + + /* Interface reference is given as a parameter + * For I2C : BMI2_I2C_INTF + * For SPI : BMI2_SPI_INTF + */ + rslt = bmi2_interface_init(&bmi2_dev, BMI2_I2C_INTF); + bmi2_error_codes_print_result(rslt); + + /* Initialize bmi270_wh. */ + rslt = bmi270_wh_init(&bmi2_dev); + bmi2_error_codes_print_result(rslt); + + if (rslt == BMI2_OK) + { + /* Enable the selected sensors. */ + rslt = bmi270_wh_sensor_enable(sens_list, 2, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + if (rslt == BMI2_OK) + { + /* Set feature configurations for no-motion. */ + rslt = set_feature_config(&bmi2_dev); + bmi2_error_codes_print_result(rslt); + + if (rslt == BMI2_OK) + { + /* Map the feature interrupt for no-motion. */ + rslt = bmi270_wh_map_feat_int(&sens_int, 1, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + printf("Do not move the board\n"); + + /* Loop to get no-motion interrupt. */ + do + { + /* Clear buffer. */ + int_status = 0; + + /* To get the interrupt status of no-motion. */ + rslt = bmi2_get_int_status(&int_status, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + /* To check the interrupt status of no-motion. */ + if (int_status & BMI270_WH_NO_MOT_STATUS_MASK) + { + printf("No-motion interrupt is generated\n"); + break; + } + } while (rslt == BMI2_OK); + } + } + } + + bmi2_coines_deinit(); + + return rslt; +} + +/*! + * @brief This internal API is used to set configurations for no-motion. + */ +static int8_t set_feature_config(struct bmi2_dev *bmi2_dev) +{ + /* Status of api are returned to this variable. */ + int8_t rslt; + + /* Structure to define the type of sensor and its configurations. */ + struct bmi2_sens_config config; + + /* Configure the type of feature. */ + config.type = BMI2_NO_MOTION; + + /* Get default configurations for the type of feature selected. */ + rslt = bmi270_wh_get_sensor_config(&config, 1, bmi2_dev); + bmi2_error_codes_print_result(rslt); + if (rslt == BMI2_OK) + { + + /* NOTE: The user can change the following configuration parameters according to their requirement. */ + /* 1LSB equals 20ms. Default is 100ms, setting to 80ms. */ + config.cfg.no_motion.duration = 0x04; + + /* 1LSB equals to 0.48mg. Default is 83mg, setting to 50mg. */ + config.cfg.no_motion.threshold = 0x68; + + /* Set new configurations. */ + rslt = bmi270_wh_set_sensor_config(&config, 1, bmi2_dev); + bmi2_error_codes_print_result(rslt); + } + + return rslt; +} diff --git a/examples/bmi270_wh/read_aux_data_mode/Makefile b/examples/bmi270_wh/read_aux_data_mode/Makefile new file mode 100644 index 0000000..b995b42 --- /dev/null +++ b/examples/bmi270_wh/read_aux_data_mode/Makefile @@ -0,0 +1,23 @@ +COINES_INSTALL_PATH ?= ../../../.. + +EXAMPLE_FILE ?= read_aux_data_mode.c + +API_LOCATION ?= ../.. + +COMMON_LOCATION ?= .. + +BMM150_SOURCE ?= ../../../bmm150 + +C_SRCS += \ +$(API_LOCATION)/bmi2.c \ +$(API_LOCATION)/bmi270_wh.c \ +$(BMM150_SOURCE)/bmm150.c \ +$(COMMON_LOCATION)/common/common.c + +INCLUDEPATHS += \ +$(API_LOCATION) \ +$(BMM150_SOURCE) \ +$(COMMON_LOCATION)/common + + +include $(COINES_INSTALL_PATH)/coines.mk \ No newline at end of file diff --git a/examples/bmi270_wh/read_aux_data_mode/read_aux_data_mode.c b/examples/bmi270_wh/read_aux_data_mode/read_aux_data_mode.c new file mode 100644 index 0000000..6d8cd67 --- /dev/null +++ b/examples/bmi270_wh/read_aux_data_mode/read_aux_data_mode.c @@ -0,0 +1,327 @@ +/**\ + * Copyright (c) 2020 Bosch Sensortec GmbH. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + **/ + +/******************************************************************************/ +/*! Header Files */ +#include +#include "bmi270_wh.h" +#include "bmm150.h" +#include "coines.h" +#include "common.h" + +/******************************************************************************/ +/*! Macro definition */ + +/*! Macros to select the sensors */ +#define ACCEL UINT8_C(0x00) +#define GYRO UINT8_C(0x01) +#define AUX UINT8_C(0x02) + +/*! Earth's gravity in m/s^2 */ +#define GRAVITY_EARTH (9.80665f) + +/*****************************************************************************/ +/*! Structure declaration */ + +/* Sensor initialization configuration. */ +struct bmi2_dev bmi2_dev; + +/*******************************************************************************/ +/*! Functions */ + +/** + * user_aux_read - Reads data from auxiliary sensor in manual mode. + * + * @param[in] reg_addr : Register address. + * @param[out] aux_data : Aux data pointer to store the read data. + * @param[in] length : No of bytes to read. + * @param[in] intf_ptr : Interface pointer + * + * @return Status of execution + * @retval 0 -> Success + * @retval < 0 -> Failure Info + */ +static int8_t user_aux_read(uint8_t reg_addr, uint8_t *aux_data, uint32_t len, void *intf_ptr); + +/** + * user_aux_write - Writes data to the auxiliary sensor in manual mode. + * + * @param[in] reg_addr : Register address. + * @param[out] aux_data : Aux data pointer to store the data being written. + * @param[in] length : No of bytes to read. + * @param[in] intf_ptr : Interface pointer + * + * @return Status of execution + * @retval 0 -> Success + * @retval < 0 -> Failure Info + */ +static int8_t user_aux_write(uint8_t reg_addr, const uint8_t *aux_data, uint32_t len, void *intf_ptr); + +/*! + * @brief This function provides the delay for required time (Microsecond) as per the input provided in some of the + * APIs. + * + * @param[in] period_us : The required wait time in microsecond. + * @param[in] intf_ptr : Interface pointer + * + * @return void. + */ +static void user_delay_us(uint32_t period, void *intf_ptr); + +/*! + * @brief This function converts lsb to meter per second squared for 16 bit accelerometer at + * range 2G, 4G, 8G or 16G. + * + * @param[in] val : LSB from each axis. + * @param[in] g_range : Gravity range. + * @param[in] bit_width : Resolution for accel. + * + * @return Gravity. + */ +static float lsb_to_mps2(int16_t val, float g_range, uint8_t bit_width); + +/*! + * @brief This function converts lsb to degree per second for 16 bit gyro at + * range 125, 250, 500, 1000 or 2000dps. + * + * @param[in] val : LSB from each axis. + * @param[in] dps : Degree per second. + * @param[in] bit_width : Resolution for gyro. + * + * @return Degree per second. + */ +static float lsb_to_dps(int16_t val, float dps, uint8_t bit_width); + +/* This function starts the execution of program. */ +int main(void) +{ + /* Status of api are returned to this variable. */ + int8_t rslt; + + /* Variable to select the pull-up resistor which is set to trim register */ + uint8_t regdata; + + /* Variable to define limit to print aux data. */ + uint8_t limit = 20; + + /* Accel, Gyro and Aux sensors are listed in array. */ + uint8_t sensor_list[3] = { BMI2_ACCEL, BMI2_GYRO, BMI2_AUX }; + + /* Structure to define the type of the sensor and its configurations. */ + struct bmi2_sens_config config[3]; + + /* Sensor initialization configuration. */ + struct bmm150_dev bmm150_dev; + + /* bmm150 settings configuration */ + struct bmm150_settings settings; + + /* bmm150 magnetometer data */ + struct bmm150_mag_data mag_data; + + /* Structure to define type of sensor and their respective data. */ + struct bmi2_sensor_data sensor_data[3]; + + /* Variables to define read the accel and gyro data in float */ + float x = 0, y = 0, z = 0; + + config[ACCEL].type = BMI2_ACCEL; + config[GYRO].type = BMI2_GYRO; + config[AUX].type = BMI2_AUX; + + /* To enable the i2c interface settings for bmm150. */ + uint8_t bmm150_dev_addr = BMM150_DEFAULT_I2C_ADDRESS; + bmm150_dev.intf_ptr = &bmm150_dev_addr; + bmm150_dev.read = user_aux_read; + bmm150_dev.write = user_aux_write; + bmm150_dev.delay_us = user_delay_us; + + /* As per datasheet, aux interface with bmi270_wh will support only for I2C */ + bmm150_dev.intf = BMM150_I2C_INTF; + + sensor_data[ACCEL].type = BMI2_ACCEL; + sensor_data[GYRO].type = BMI2_GYRO; + sensor_data[AUX].type = BMI2_AUX; + + /* Interface reference is given as a parameter + * For I2C : BMI2_I2C_INTF + * For SPI : BMI2_SPI_INTF + */ + rslt = bmi2_interface_init(&bmi2_dev, BMI2_I2C_INTF); + bmi2_error_codes_print_result(rslt); + + /* Initialize bmi270_wh. */ + rslt = bmi270_wh_init(&bmi2_dev); + bmi2_error_codes_print_result(rslt); + + /* Pull-up resistor 2k is set to the trim regiter */ + regdata = BMI2_ASDA_PUPSEL_2K; + rslt = bmi2_set_regs(BMI2_AUX_IF_TRIM, ®data, 1, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + /* Enable the accel, gyro and aux sensor. */ + rslt = bmi270_wh_sensor_enable(sensor_list, 3, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + /* Get default configurations for the type of feature selected. */ + rslt = bmi270_wh_get_sensor_config(config, 3, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + /* Configurations for accel. */ + config[ACCEL].cfg.acc.filter_perf = BMI2_PERF_OPT_MODE; + config[ACCEL].cfg.acc.bwp = BMI2_ACC_OSR2_AVG2; + config[ACCEL].cfg.acc.odr = BMI2_ACC_ODR_100HZ; + config[ACCEL].cfg.acc.range = BMI2_ACC_RANGE_2G; + + /* Configurations for gyro. */ + config[GYRO].cfg.gyr.filter_perf = BMI2_PERF_OPT_MODE; + config[GYRO].cfg.gyr.noise_perf = BMI2_GYR_RANGE_2000; + config[GYRO].cfg.gyr.bwp = BMI2_GYR_OSR2_MODE; + config[GYRO].cfg.gyr.odr = BMI2_GYR_ODR_100HZ; + config[GYRO].cfg.gyr.range = BMI2_GYR_RANGE_2000; + config[GYRO].cfg.gyr.ois_range = BMI2_GYR_OIS_2000; + + /* Configurations for aux. */ + config[AUX].cfg.aux.odr = BMI2_AUX_ODR_100HZ; + config[AUX].cfg.aux.aux_en = BMI2_ENABLE; + config[AUX].cfg.aux.i2c_device_addr = BMM150_DEFAULT_I2C_ADDRESS; + config[AUX].cfg.aux.manual_en = BMI2_ENABLE; + config[AUX].cfg.aux.fcu_write_en = BMI2_ENABLE; + config[AUX].cfg.aux.man_rd_burst = BMI2_AUX_READ_LEN_3; + config[AUX].cfg.aux.read_addr = BMM150_REG_DATA_X_LSB; + + /* Set new configurations for accel, gyro and aux. */ + rslt = bmi270_wh_set_sensor_config(config, 3, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + /* Initialize bmm150. */ + rslt = bmm150_init(&bmm150_dev); + bmi2_error_codes_print_result(rslt); + + /* Set the power mode to normal mode. */ + settings.pwr_mode = BMM150_POWERMODE_NORMAL; + rslt = bmm150_set_op_mode(&settings, &bmm150_dev); + bmi2_error_codes_print_result(rslt); + + rslt = bmi270_wh_get_sensor_config(config, 3, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + /* Disable manual mode so that the data mode is enabled. */ + config[AUX].cfg.aux.manual_en = BMI2_DISABLE; + + /* Set the aux configurations. */ + rslt = bmi270_wh_set_sensor_config(config, 3, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + printf("MAGNETOMETER, ACCEL, AND GYRO DATA IN DATA MODE\n"); + + if (bmm150_dev.chip_id == BMM150_CHIP_ID) + { + while (limit--) + { + /* Delay has been added to get aux, accel and gyro data at the interval of every 0.05 second. */ + bmi2_dev.delay_us(50000, bmi2_dev.intf_ptr); + + rslt = bmi270_wh_get_sensor_data(sensor_data, 3, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + if (rslt == BMI2_OK) + { + printf("\nAcc_x = %d\t", sensor_data[ACCEL].sens_data.acc.x); + printf("Acc_y = %d\t", sensor_data[ACCEL].sens_data.acc.y); + printf("Acc_z = %d", sensor_data[ACCEL].sens_data.acc.z); + + /* Converting lsb to meter per second squared for 16 bit accelerometer at 2G range. */ + x = lsb_to_mps2(sensor_data[ACCEL].sens_data.acc.x, 2, bmi2_dev.resolution); + y = lsb_to_mps2(sensor_data[ACCEL].sens_data.acc.y, 2, bmi2_dev.resolution); + z = lsb_to_mps2(sensor_data[ACCEL].sens_data.acc.z, 2, bmi2_dev.resolution); + + /* Print the data in m/s2. */ + printf("\nAcc_ms2_X = %4.2f, Acc_ms2_Y = %4.2f, Acc_ms2_Z = %4.2f\n", x, y, z); + + printf("\nGyr_X = %d\t", sensor_data[GYRO].sens_data.gyr.x); + printf("Gyr_Y = %d\t", sensor_data[GYRO].sens_data.gyr.y); + printf("Gyr_Z= %d", sensor_data[GYRO].sens_data.gyr.z); + + /* Converting lsb to degree per second for 16 bit gyro at 2000dps range. */ + x = lsb_to_dps(sensor_data[GYRO].sens_data.gyr.x, 2000, bmi2_dev.resolution); + y = lsb_to_dps(sensor_data[GYRO].sens_data.gyr.y, 2000, bmi2_dev.resolution); + z = lsb_to_dps(sensor_data[GYRO].sens_data.gyr.z, 2000, bmi2_dev.resolution); + + /* Print the data in dps. */ + printf("\nGyro_DPS_X = %4.2f, Gyro_DPS_Y = %4.2f, Gyro_DPS_Z = %4.2f\n", x, y, z); + + /* Compensating the raw auxiliary data available from the BMM150 API. */ + rslt = bmm150_aux_mag_data(sensor_data[AUX].sens_data.aux_data, &mag_data, &bmm150_dev); + bmi2_error_codes_print_result(rslt); + printf("\nMag_x_axis = %d \t Mag_y_axis = %d \t Mag_z_axis = %d \t\n", + mag_data.x, + mag_data.y, + mag_data.z); + } + } + } + + bmi2_coines_deinit(); + + return rslt; +} + +/*! + * @brief This function reads the data from auxiliary sensor in manual mode. + */ +static int8_t user_aux_read(uint8_t reg_addr, uint8_t *aux_data, uint32_t len, void *intf_ptr) +{ + int8_t rslt; + + /* Discarding the parameter id as it is redundant */ + rslt = bmi2_read_aux_man_mode(reg_addr, aux_data, len, &bmi2_dev); + + return rslt; +} + +/*! + * @brief This function writes the data to auxiliary sensor in manual mode. + */ +static int8_t user_aux_write(uint8_t reg_addr, const uint8_t *aux_data, uint32_t len, void *intf_ptr) +{ + int8_t rslt; + + /* Discarding the parameter id as it is redundant */ + rslt = bmi2_write_aux_man_mode(reg_addr, aux_data, len, &bmi2_dev); + + return rslt; +} + +/*! + * Delay function map to COINES platform + */ +static void user_delay_us(uint32_t period, void *intf_ptr) +{ + coines_delay_usec(period); +} + +/*! + * @brief This function converts lsb to meter per second squared for 16 bit accelerometer at + * range 2G, 4G, 8G or 16G. + */ +static float lsb_to_mps2(int16_t val, float g_range, uint8_t bit_width) +{ + float half_scale = ((float)(1 << bit_width) / 2.0f); + + return (GRAVITY_EARTH * val * g_range) / half_scale; +} + +/*! + * @brief This function converts lsb to degree per second for 16 bit gyro at + * range 125, 250, 500, 1000 or 2000dps. + */ +static float lsb_to_dps(int16_t val, float dps, uint8_t bit_width) +{ + float half_scale = ((float)(1 << bit_width) / 2.0f); + + return (dps / ((half_scale) + BMI2_GYR_RANGE_2000)) * (val); +} diff --git a/examples/bmi270_wh/read_aux_manual_mode/Makefile b/examples/bmi270_wh/read_aux_manual_mode/Makefile new file mode 100644 index 0000000..843a2ce --- /dev/null +++ b/examples/bmi270_wh/read_aux_manual_mode/Makefile @@ -0,0 +1,23 @@ +COINES_INSTALL_PATH ?= ../../../.. + +EXAMPLE_FILE ?= read_aux_manual_mode.c + +API_LOCATION ?= ../.. + +COMMON_LOCATION ?= .. + +BMM150_SOURCE ?= ../../../bmm150 + +C_SRCS += \ +$(API_LOCATION)/bmi2.c \ +$(API_LOCATION)/bmi270_wh.c \ +$(BMM150_SOURCE)/bmm150.c \ +$(COMMON_LOCATION)/common/common.c + +INCLUDEPATHS += \ +$(API_LOCATION) \ +$(BMM150_SOURCE) \ +$(COMMON_LOCATION)/common + + +include $(COINES_INSTALL_PATH)/coines.mk \ No newline at end of file diff --git a/examples/bmi270_wh/read_aux_manual_mode/read_aux_manual_mode.c b/examples/bmi270_wh/read_aux_manual_mode/read_aux_manual_mode.c new file mode 100644 index 0000000..524eb8d --- /dev/null +++ b/examples/bmi270_wh/read_aux_manual_mode/read_aux_manual_mode.c @@ -0,0 +1,322 @@ +/**\ + * Copyright (c) 2020 Bosch Sensortec GmbH. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + **/ + +/******************************************************************************/ +/*! Header Files */ +#include +#include "bmi270_wh.h" +#include "bmm150.h" +#include "coines.h" +#include "common.h" + +/******************************************************************************/ +/*! Macro definition */ + +/*! Macros to select the sensors */ +#define ACCEL UINT8_C(0x00) +#define GYRO UINT8_C(0x01) +#define AUX UINT8_C(0x02) + +/*! Earth's gravity in m/s^2 */ +#define GRAVITY_EARTH (9.80665f) + +/*****************************************************************************/ +/*! Structure declaration */ + +/* Sensor initialization configuration. */ +struct bmi2_dev bmi2_dev; + +/******************************************************************************/ +/*! Functions */ + +/** + * user_aux_read - Reads data from auxiliary sensor in manual mode. + * + * @param[in] reg_addr : Register address. + * @param[out] aux_data : Aux data pointer to store the read data. + * @param[in] length : No of bytes to read. + * @param[in] intf_ptr : Interface pointer + * + * @return Status of execution + * @retval 0 -> Success + * @retval < 0 -> Failure Info + */ +static int8_t user_aux_read(uint8_t reg_addr, uint8_t *aux_data, uint32_t len, void *intf_ptr); + +/** + * user_aux_write - Writes data to the auxiliary sensor in manual mode. + * + * @param[in] reg_addr : Register address. + * @param[out] aux_data : Aux data pointer to store the data being written. + * @param[in] length : No of bytes to read. + * @param[in] intf_ptr : Interface pointer + * + * @return Status of execution + * @retval 0 -> Success + * @retval < 0 -> Failure Info + */ +static int8_t user_aux_write(uint8_t reg_addr, const uint8_t *aux_data, uint32_t len, void *intf_ptr); + +/*! + * @brief This function provides the delay for required time (Microsecond) as per the input provided in some of the + * APIs. + * + * @param[in] period_us : The required wait time in microsecond. + * @param[in] intf_ptr : Interface pointer + * + * @return void. + */ +static void user_delay_us(uint32_t period, void *intf_ptr); + +/*! + * @brief This function converts lsb to meter per second squared for 16 bit accelerometer at + * range 2G, 4G, 8G or 16G. + * + * @param[in] val : LSB from each axis. + * @param[in] g_range : Gravity range. + * @param[in] bit_width : Resolution for accel. + * + * @return Gravity. + */ +static float lsb_to_mps2(int16_t val, float g_range, uint8_t bit_width); + +/*! + * @brief This function converts lsb to degree per second for 16 bit gyro at + * range 125, 250, 500, 1000 or 2000dps. + * + * @param[in] val : LSB from each axis. + * @param[in] dps : Degree per second. + * @param[in] bit_width : Resolution for gyro. + * + * @return Degree per second. + */ +static float lsb_to_dps(int16_t val, float dps, uint8_t bit_width); + +/* This function starts the execution of program. */ +int main(void) +{ + /* Status of api are returned to this variable. */ + int8_t rslt; + + /* Variable to select the pull-up resistor which is set to trim register */ + uint8_t regdata; + + /* Variable to define limit to print aux data. */ + uint8_t limit = 20; + + /* Accel, Gyro and Aux sensors are listed in array. */ + uint8_t sensor_list[3] = { BMI2_ACCEL, BMI2_GYRO, BMI2_AUX }; + + /* Sensor initialization configuration. */ + struct bmm150_dev bmm150_dev; + + /* bmm150 settings configuration */ + struct bmm150_settings settings; + + /* bmm150 magnetometer data */ + struct bmm150_mag_data mag_data; + + /* Structure to define the type of the sensor and its configurations. */ + struct bmi2_sens_config config[3]; + + /* Structure to define type of sensor and their respective data. */ + struct bmi2_sensor_data sensor_data[2]; + + /* Variables to define read the accel and gyro data in float */ + float x = 0, y = 0, z = 0; + + config[ACCEL].type = BMI2_ACCEL; + config[GYRO].type = BMI2_GYRO; + config[AUX].type = BMI2_AUX; + + sensor_data[ACCEL].type = BMI2_ACCEL; + sensor_data[GYRO].type = BMI2_GYRO; + + /* Array of eight bytes to store x, y, z and r axis aux data. */ + uint8_t aux_data[8] = { 0 }; + + /* To enable the i2c interface settings for bmm150. */ + uint8_t bmm150_dev_addr = BMM150_DEFAULT_I2C_ADDRESS; + bmm150_dev.intf_ptr = &bmm150_dev_addr; + bmm150_dev.read = user_aux_read; + bmm150_dev.write = user_aux_write; + bmm150_dev.delay_us = user_delay_us; + + /* As per datasheet, aux interface with bmi270_wh will support only for I2C */ + bmm150_dev.intf = BMM150_I2C_INTF; + + /* Interface reference is given as a parameter + * For I2C : BMI2_I2C_INTF + * For SPI : BMI2_SPI_INTF + */ + rslt = bmi2_interface_init(&bmi2_dev, BMI2_SPI_INTF); + bmi2_error_codes_print_result(rslt); + + /* Initialize bmi270_wh. */ + rslt = bmi270_wh_init(&bmi2_dev); + bmi2_error_codes_print_result(rslt); + + /* Pull-up resistor 2k is set to the trim register */ + regdata = BMI2_ASDA_PUPSEL_2K; + rslt = bmi2_set_regs(BMI2_AUX_IF_TRIM, ®data, 1, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + /* Enable the accel, gyro and aux sensor. */ + rslt = bmi270_wh_sensor_enable(sensor_list, 3, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + /* Get default configurations for the type of feature selected. */ + rslt = bmi270_wh_get_sensor_config(config, 3, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + /* Configurations for accel. */ + config[ACCEL].cfg.acc.filter_perf = BMI2_PERF_OPT_MODE; + config[ACCEL].cfg.acc.bwp = BMI2_ACC_OSR2_AVG2; + config[ACCEL].cfg.acc.odr = BMI2_ACC_ODR_100HZ; + config[ACCEL].cfg.acc.range = BMI2_ACC_RANGE_2G; + + /* Configurations for gyro. */ + config[GYRO].cfg.gyr.filter_perf = BMI2_PERF_OPT_MODE; + config[GYRO].cfg.gyr.noise_perf = BMI2_GYR_RANGE_2000; + config[GYRO].cfg.gyr.bwp = BMI2_GYR_OSR2_MODE; + config[GYRO].cfg.gyr.odr = BMI2_GYR_ODR_100HZ; + config[GYRO].cfg.gyr.range = BMI2_GYR_RANGE_2000; + config[GYRO].cfg.gyr.ois_range = BMI2_GYR_OIS_2000; + + /* Configurations for aux. */ + config[AUX].cfg.aux.odr = BMI2_AUX_ODR_100HZ; + config[AUX].cfg.aux.aux_en = BMI2_ENABLE; + config[AUX].cfg.aux.i2c_device_addr = BMM150_DEFAULT_I2C_ADDRESS; + config[AUX].cfg.aux.manual_en = BMI2_ENABLE; + config[AUX].cfg.aux.fcu_write_en = BMI2_ENABLE; + config[AUX].cfg.aux.man_rd_burst = BMI2_AUX_READ_LEN_3; + + /* Set new configurations for accel, gyro and aux. */ + rslt = bmi270_wh_set_sensor_config(config, 3, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + /* Initialize bmm150. */ + rslt = bmm150_init(&bmm150_dev); + bmi2_error_codes_print_result(rslt); + + /* Set the power mode to normal mode. */ + settings.pwr_mode = BMM150_POWERMODE_NORMAL; + rslt = bmm150_set_op_mode(&settings, &bmm150_dev); + bmi2_error_codes_print_result(rslt); + + printf("MAGNETOMETER, ACCEL AND GYRO DATA IN MANUAL MODE\n"); + + if (bmm150_dev.chip_id == BMM150_CHIP_ID) + { + while (limit--) + { + /* Delay has been added to get aux, accel and gyro data at the interval of every 0.05 second. */ + bmi2_dev.delay_us(50000, bmi2_dev.intf_ptr); + + rslt = bmi270_wh_get_sensor_data(sensor_data, 2, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + if (rslt == BMI2_OK) + { + printf("\nAcc_x = %d\t", sensor_data[ACCEL].sens_data.acc.x); + printf("Acc_y = %d\t", sensor_data[ACCEL].sens_data.acc.y); + printf("Acc_z = %d", sensor_data[ACCEL].sens_data.acc.z); + + /* Converting lsb to meter per second squared for 16 bit accelerometer at 2G range. */ + x = lsb_to_mps2(sensor_data[ACCEL].sens_data.acc.x, 2, bmi2_dev.resolution); + y = lsb_to_mps2(sensor_data[ACCEL].sens_data.acc.y, 2, bmi2_dev.resolution); + z = lsb_to_mps2(sensor_data[ACCEL].sens_data.acc.z, 2, bmi2_dev.resolution); + + /* Print the data in m/s2. */ + printf("\nAcc_ms2_X = %4.2f, Acc_ms2_Y = %4.2f, Acc_ms2_Z = %4.2f\n", x, y, z); + + printf("\nGyr_X = %d\t", sensor_data[GYRO].sens_data.gyr.x); + printf("Gyr_Y = %d\t", sensor_data[GYRO].sens_data.gyr.y); + printf("Gyr_Z = %d", sensor_data[GYRO].sens_data.gyr.z); + + /* Converting lsb to degree per second for 16 bit gyro at 2000dps range. */ + x = lsb_to_dps(sensor_data[GYRO].sens_data.gyr.x, 2000, bmi2_dev.resolution); + y = lsb_to_dps(sensor_data[GYRO].sens_data.gyr.y, 2000, bmi2_dev.resolution); + z = lsb_to_dps(sensor_data[GYRO].sens_data.gyr.z, 2000, bmi2_dev.resolution); + + /* Print the data in dps. */ + printf("\nGyro_DPS_X = %4.2f, Gyro_DPS_Y = %4.2f, Gyro_DPS_Z = %4.2f\n", x, y, z); + } + + /* Read aux data from the bmm150 data registers. */ + rslt = bmi2_read_aux_man_mode(BMM150_REG_DATA_X_LSB, aux_data, 8, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + if (rslt == BMI2_OK) + { + /* Compensating the raw auxiliary data available from the BMM150 API. */ + rslt = bmm150_aux_mag_data(aux_data, &mag_data, &bmm150_dev); + bmi2_error_codes_print_result(rslt); + printf("Mag_x_axis = %d \t Mag_y_axis = %d \t Mag_z_axis = %d \t\n", mag_data.x, mag_data.y, + mag_data.z); + } + } + } + + bmi2_coines_deinit(); + + return rslt; +} + +/*! + * @brief This function reads the data from auxiliary sensor in manual mode. + */ +int8_t user_aux_read(uint8_t reg_addr, uint8_t *aux_data, uint32_t len, void *intf_ptr) +{ + int8_t rslt; + + /* Discarding the parameter id as it is redundant */ + rslt = bmi2_read_aux_man_mode(reg_addr, aux_data, len, &bmi2_dev); + + return rslt; +} + +/*! + * @brief This function writes the data to auxiliary sensor in manual mode. + */ +int8_t user_aux_write(uint8_t reg_addr, const uint8_t *aux_data, uint32_t len, void *intf_ptr) +{ + int8_t rslt; + + /* Discarding the parameter id as it is redundant */ + rslt = bmi2_write_aux_man_mode(reg_addr, aux_data, len, &bmi2_dev); + + return rslt; +} + +/*! + * Delay function map to COINES platform + */ +static void user_delay_us(uint32_t period, void *intf_ptr) +{ + coines_delay_usec(period); +} + +/*! + * @brief This function converts lsb to meter per second squared for 16 bit accelerometer at + * range 2G, 4G, 8G or 16G. + */ +static float lsb_to_mps2(int16_t val, float g_range, uint8_t bit_width) +{ + float half_scale = ((float)(1 << bit_width) / 2.0f); + + return (GRAVITY_EARTH * val * g_range) / half_scale; +} + +/*! + * @brief This function converts lsb to degree per second for 16 bit gyro at + * range 125, 250, 500, 1000 or 2000dps. + */ +static float lsb_to_dps(int16_t val, float dps, uint8_t bit_width) +{ + float half_scale = ((float)(1 << bit_width) / 2.0f); + + return (dps / ((half_scale) + BMI2_GYR_RANGE_2000)) * (val); +} diff --git a/examples/bmi270_wh/step_activity/Makefile b/examples/bmi270_wh/step_activity/Makefile new file mode 100644 index 0000000..a4fcf10 --- /dev/null +++ b/examples/bmi270_wh/step_activity/Makefile @@ -0,0 +1,18 @@ +COINES_INSTALL_PATH ?= ../../../.. + +EXAMPLE_FILE ?= step_activity.c + +API_LOCATION ?= ../.. + +COMMON_LOCATION ?= .. + +C_SRCS += \ +$(API_LOCATION)/bmi2.c \ +$(API_LOCATION)/bmi270_wh.c \ +$(COMMON_LOCATION)/common/common.c + +INCLUDEPATHS += \ +$(API_LOCATION) \ +$(COMMON_LOCATION)/common + +include $(COINES_INSTALL_PATH)/coines.mk \ No newline at end of file diff --git a/examples/bmi270_wh/step_activity/step_activity.c b/examples/bmi270_wh/step_activity/step_activity.c new file mode 100644 index 0000000..0c3e9c7 --- /dev/null +++ b/examples/bmi270_wh/step_activity/step_activity.c @@ -0,0 +1,110 @@ +/**\ + * Copyright (c) 2020 Bosch Sensortec GmbH. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + **/ + +/******************************************************************************/ +/*! Header Files */ +#include +#include "bmi270_wh.h" +#include "common.h" + +/******************************************************************************/ +/*! Functions */ +/* This function starts the execution of program. */ +int main(void) +{ + /* Sensor initialization configuration. */ + struct bmi2_dev bmi2_dev; + + /* Structure to define the type of sensor and their respective data. */ + struct bmi2_sensor_data sensor_data; + + /* Structure to define the type of sensor and its configurations. */ + struct bmi2_sens_config config; + + /* Status of api are returned to this variable. */ + int8_t rslt; + + /* Accel sensor and step activity feature are listed in array. */ + uint8_t sensor_sel[2] = { BMI2_ACCEL, BMI2_STEP_ACTIVITY }; + + /* Type of sensor to get step activity data. */ + sensor_data.type = BMI2_STEP_ACTIVITY; + + /* Variable to get step activity interrupt status. */ + uint16_t int_status = 0; + + uint16_t loop = 10; + + /* Select features and their pins to be mapped to. */ + struct bmi2_sens_int_config sens_int = { .type = BMI2_STEP_ACTIVITY, .hw_int_pin = BMI2_INT2 }; + + /* The step activities are listed in array. */ + const char *activity_output[4] = { "BMI2_STILL", "BMI2_WALK", "BMI2_RUN", "BMI2_UNKNOWN" }; + + /* Interface reference is given as a parameter + * For I2C : BMI2_I2C_INTF + * For SPI : BMI2_SPI_INTF + */ + rslt = bmi2_interface_init(&bmi2_dev, BMI2_I2C_INTF); + bmi2_error_codes_print_result(rslt); + + /* Initialize bmi270. */ + rslt = bmi270_wh_init(&bmi2_dev); + bmi2_error_codes_print_result(rslt); + + if (rslt == BMI2_OK) + { + /* Enable the selected sensor. */ + rslt = bmi270_wh_sensor_enable(sensor_sel, 2, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + /* Configure the type of sensor. */ + config.type = BMI2_STEP_ACTIVITY; + + if (rslt == BMI2_OK) + { + /* Get default configurations for the type of feature selected. */ + rslt = bmi270_wh_get_sensor_config(&config, 1, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + if (rslt == BMI2_OK) + { + /* Map the feature interrupt for step activity. */ + rslt = bmi270_wh_map_feat_int(&sens_int, 1, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + printf("\nMove the board in steps to perform step activity:\n"); + + /* Loop to get step activity. */ + while (loop) + { + /* To get the interrupt status of step detector. */ + rslt = bmi2_get_int_status(&int_status, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + /* To check the interrupt status of step detector. */ + if (int_status & BMI270_WH_STEP_ACT_STATUS_MASK) + { + printf("Step detected\n"); + + /* Get step activity output. */ + rslt = bmi270_wh_get_sensor_data(&sensor_data, 1, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + /* Print the step activity output. */ + printf("Step activity = %s\n", activity_output[sensor_data.sens_data.activity_output]); + + loop--; + } + } + } + } + } + + bmi2_coines_deinit(); + + return rslt; +} diff --git a/examples/bmi270_wh/step_counter/Makefile b/examples/bmi270_wh/step_counter/Makefile new file mode 100644 index 0000000..1c16cc6 --- /dev/null +++ b/examples/bmi270_wh/step_counter/Makefile @@ -0,0 +1,18 @@ +COINES_INSTALL_PATH ?= ../../../.. + +EXAMPLE_FILE ?= step_counter.c + +API_LOCATION ?= ../.. + +COMMON_LOCATION ?= .. + +C_SRCS += \ +$(API_LOCATION)/bmi2.c \ +$(API_LOCATION)/bmi270_wh.c \ +$(COMMON_LOCATION)/common/common.c + +INCLUDEPATHS += \ +$(API_LOCATION) \ +$(COMMON_LOCATION)/common + +include $(COINES_INSTALL_PATH)/coines.mk \ No newline at end of file diff --git a/examples/bmi270_wh/step_counter/step_counter.c b/examples/bmi270_wh/step_counter/step_counter.c new file mode 100644 index 0000000..8d5f968 --- /dev/null +++ b/examples/bmi270_wh/step_counter/step_counter.c @@ -0,0 +1,146 @@ +/**\ + * Copyright (c) 2020 Bosch Sensortec GmbH. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + **/ + +/******************************************************************************/ +/*! Header Files */ +#include +#include "bmi270_wh.h" +#include "common.h" + +/******************************************************************************/ +/*! Static function declaration */ + +/*! + * @brief This internal API is used to set configurations for step counter. + * + * @param[in] bmi2_dev : Structure instance of bmi2_dev. + * + * @return Status of execution. + */ +static int8_t set_feature_config(struct bmi2_dev *bmi2_dev); + +/******************************************************************************/ +/*! Functions */ + +/* This function starts the execution of program. */ +int main(void) +{ + /* Sensor initialization configuration. */ + struct bmi2_dev bmi2_dev; + + /* Structure to define type of sensor and their respective data. */ + struct bmi2_sensor_data sensor_data; + + /* Status of api are returned to this variable. */ + int8_t rslt; + + /* Accel sensor and step counter feature are listed in array. */ + uint8_t sensor_sel[2] = { BMI2_ACCEL, BMI2_STEP_COUNTER }; + + /* Variable to get step counter interrupt status. */ + uint16_t int_status = 0; + + /* Select features and their pins to be mapped to. */ + struct bmi2_sens_int_config sens_int = { .type = BMI2_STEP_COUNTER, .hw_int_pin = BMI2_INT2 }; + + /* Type of sensor to get step counter data. */ + sensor_data.type = BMI2_STEP_COUNTER; + + /* Interface reference is given as a parameter + * For I2C : BMI2_I2C_INTF + * For SPI : BMI2_SPI_INTF + */ + rslt = bmi2_interface_init(&bmi2_dev, BMI2_I2C_INTF); + bmi2_error_codes_print_result(rslt); + + /* Initialize bmi270_wh. */ + rslt = bmi270_wh_init(&bmi2_dev); + bmi2_error_codes_print_result(rslt); + + if (rslt == BMI2_OK) + { + /* Enable the selected sensor. */ + rslt = bmi270_wh_sensor_enable(sensor_sel, 2, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + if (rslt == BMI2_OK) + { + /* Set the feature configuration for step counter. */ + rslt = set_feature_config(&bmi2_dev); + bmi2_error_codes_print_result(rslt); + + printf("Step counter watermark level set to 1 (20 steps)\n"); + + if (rslt == BMI2_OK) + { + /* Map the step counter feature interrupt. */ + rslt = bmi270_wh_map_feat_int(&sens_int, 1, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + /* Move the board in steps for 20 times to get step counter interrupt. */ + printf("Move the board in steps\n"); + + /* Loop to get number of steps counted. */ + do + { + /* To get the interrupt status of the step counter. */ + rslt = bmi2_get_int_status(&int_status, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + /* To check the interrupt status of the step counter. */ + if (int_status & BMI270_WH_STEP_CNT_STATUS_MASK) + { + printf("Step counter interrupt occurred when watermark level (20 steps) is reached\n"); + + /* Get step counter output. */ + rslt = bmi270_wh_get_sensor_data(&sensor_data, 1, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + /* Print the step counter output. */ + printf("No of steps counted = %ld", sensor_data.sens_data.step_counter_output); + break; + } + } while (rslt == BMI2_OK); + } + } + } + + bmi2_coines_deinit(); + + return rslt; +} + +/*! + * @brief This internal API is used to set configurations for step counter. + */ +static int8_t set_feature_config(struct bmi2_dev *bmi2_dev) +{ + /* Status of api are returned to this variable. */ + int8_t rslt; + + /* Structure to define the type of sensor and its configurations. */ + struct bmi2_sens_config config; + + /* Configure the type of sensor. */ + config.type = BMI2_STEP_COUNTER; + + /* Get default configurations for the type of feature selected. */ + rslt = bmi270_wh_get_sensor_config(&config, 1, bmi2_dev); + bmi2_error_codes_print_result(rslt); + + if (rslt == BMI2_OK) + { + /* Setting water-mark level to 1 for step counter to get interrupt after 20 step counts. Every 20 steps once + * output triggers. */ + config.cfg.step_counter.watermark_level = 1; + + /* Set new configuration. */ + rslt = bmi270_wh_set_sensor_config(&config, 1, bmi2_dev); + bmi2_error_codes_print_result(rslt); + } + + return rslt; +} diff --git a/examples/bmi270_wh/wrist_wear_wakeup/Makefile b/examples/bmi270_wh/wrist_wear_wakeup/Makefile new file mode 100644 index 0000000..65d3561 --- /dev/null +++ b/examples/bmi270_wh/wrist_wear_wakeup/Makefile @@ -0,0 +1,18 @@ +COINES_INSTALL_PATH ?= ../../../.. + +EXAMPLE_FILE ?= wrist_wear_wakeup.c + +API_LOCATION ?= ../.. + +COMMON_LOCATION ?= .. + +C_SRCS += \ +$(API_LOCATION)/bmi2.c \ +$(API_LOCATION)/bmi270_wh.c \ +$(COMMON_LOCATION)/common/common.c + +INCLUDEPATHS += \ +$(API_LOCATION) \ +$(COMMON_LOCATION)/common + +include $(COINES_INSTALL_PATH)/coines.mk \ No newline at end of file diff --git a/examples/bmi270_wh/wrist_wear_wakeup/wrist_wear_wakeup.c b/examples/bmi270_wh/wrist_wear_wakeup/wrist_wear_wakeup.c new file mode 100644 index 0000000..bee1191 --- /dev/null +++ b/examples/bmi270_wh/wrist_wear_wakeup/wrist_wear_wakeup.c @@ -0,0 +1,131 @@ +/**\ + * Copyright (c) 2020 Bosch Sensortec GmbH. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + **/ + +/******************************************************************************/ +/*! Header Files */ +#include +#include "bmi270_wh.h" +#include "common.h" + +/******************************************************************************/ +/*! Static function declaration */ + +/*! + * @brief This internal API is used to set the sensor configuration. + * + * @param[in] bmi2_dev : Structure instance of bmi2_dev. + * + * @return Status of execution. + */ +static int8_t bmi2_set_config(struct bmi2_dev *bmi2_dev); + +/******************************************************************************/ +/*! Functions */ + +/* This function starts the execution of program */ +int main(void) +{ + /* Variable to define result */ + int8_t rslt; + + /* Initialize status of wrist wear wakeup interrupt */ + uint16_t int_status = 0; + + /* Sensor initialization configuration. */ + struct bmi2_dev bmi2_dev; + + /* Select features and their pins to be mapped to */ + struct bmi2_sens_int_config sens_int = { .type = BMI2_WRIST_WEAR_WAKE_UP_WH, .hw_int_pin = BMI2_INT1 }; + + /* Interface reference is given as a parameter + * For I2C : BMI2_I2C_INTF + * For SPI : BMI2_SPI_INTF + */ + rslt = bmi2_interface_init(&bmi2_dev, BMI2_I2C_INTF); + bmi2_error_codes_print_result(rslt); + + /* Initialize bmi270_wh. */ + rslt = bmi270_wh_init(&bmi2_dev); + bmi2_error_codes_print_result(rslt); + + if (rslt == BMI2_OK) + { + /* Set the sensor configuration */ + rslt = bmi2_set_config(&bmi2_dev); + bmi2_error_codes_print_result(rslt); + + if (rslt == BMI2_OK) + { + /* Map the feature interrupt */ + rslt = bmi270_wh_map_feat_int(&sens_int, 1, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + if (rslt == BMI2_OK) + { + printf("Tilt the board in landscape position to trigger wrist wear wakeup\n"); + + /* Loop to print the wrist wear wakeup data when interrupt occurs */ + while (1) + { + int_status = 0; + + /* To get the interrupt status of the wrist wear wakeup */ + rslt = bmi2_get_int_status(&int_status, &bmi2_dev); + bmi2_error_codes_print_result(rslt); + + /* To check the interrupt status of the wrist gesture */ + if ((rslt == BMI2_OK) && (int_status & BMI270_WH_WRIST_WEAR_WAKEUP_WH_STATUS_MASK)) + { + printf("Wrist wear wakeup detected\n"); + break; + } + } + } + } + } + + bmi2_coines_deinit(); + + return rslt; +} + +/*! + * @brief This internal API sets the sensor configuration + */ +static int8_t bmi2_set_config(struct bmi2_dev *bmi2_dev) +{ + /* Variable to define result */ + int8_t rslt; + + /* List the sensors which are required to enable */ + uint8_t sens_list[2] = { BMI2_ACCEL, BMI2_WRIST_WEAR_WAKE_UP_WH }; + + /* Structure to define the type of the sensor and its configurations */ + struct bmi2_sens_config config; + + /* Configure type of feature */ + config.type = BMI2_WRIST_WEAR_WAKE_UP_WH; + + /* Enable the selected sensors */ + rslt = bmi270_wh_sensor_enable(sens_list, 2, bmi2_dev); + bmi2_error_codes_print_result(rslt); + + if (rslt == BMI2_OK) + { + /* Get default configurations for the type of feature selected */ + rslt = bmi270_wh_get_sensor_config(&config, 1, bmi2_dev); + bmi2_error_codes_print_result(rslt); + + if (rslt == BMI2_OK) + { + /* Set the new configuration */ + rslt = bmi270_wh_set_sensor_config(&config, 1, bmi2_dev); + bmi2_error_codes_print_result(rslt); + } + } + + return rslt; +} diff --git a/examples/bmi2_ois/common/common.c b/examples/bmi2_ois/common/common.c new file mode 100644 index 0000000..1a43947 --- /dev/null +++ b/examples/bmi2_ois/common/common.c @@ -0,0 +1,153 @@ +/**\ + * Copyright (c) 2020 Bosch Sensortec GmbH. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + **/ + +/******************************************************************************/ +#include +#include +#include + +#include "coines.h" +#include "common.h" + +/******************************************************************************/ +/*! Global declaration */ + +/*! Device address for primary and secondary interface */ +static uint8_t ois_dev_addr; + +/******************************************************************************/ +/*! Functions */ + +/*! + * SPI read function map to COINES platform + */ +int8_t bmi2_ois_spi_read(uint8_t reg_addr, uint8_t *reg_data, uint32_t len, void *intf_ptr) +{ + uint8_t dev_addr = *(uint8_t*)intf_ptr; + + return coines_read_spi(dev_addr, reg_addr, reg_data, (uint16_t)len); +} + +/*! + * SPI write function map to COINES platform + */ +int8_t bmi2_ois_spi_write(uint8_t reg_addr, const uint8_t *reg_data, uint32_t len, void *intf_ptr) +{ + uint8_t dev_addr = *(uint8_t*)intf_ptr; + + return coines_write_spi(dev_addr, reg_addr, (uint8_t *)reg_data, (uint16_t)len); +} + +/*! + * Delay function map to COINES platform + */ +void bmi2_ois_delay_us(uint32_t period, void *intf_ptr) +{ + coines_delay_usec(period); +} + +/******************************************************************************/ +int8_t bmi2_ois_init(struct bmi2_ois_dev *ois_dev) +{ + int8_t rslt; + + if (ois_dev != NULL) + { + int16_t result = coines_open_comm_intf(COINES_COMM_INTF_USB); + if (result < COINES_SUCCESS) + { + printf( + "\n Unable to connect with Application Board ! \n" " 1. Check if the board is connected and powered on. \n" " 2. Check if Application Board USB driver is installed. \n" + " 3. Check if board is in use by another application. (Insufficient permissions to access USB) \n"); + exit(result); + } + + coines_set_shuttleboard_vdd_vddio_config(0, 0); + coines_delay_msec(100); + + printf("SPI Interface \n"); + + /* To initialize the user SPI function */ + ois_dev_addr = COINES_SHUTTLE_PIN_8; /*COINES_SHUTTLE_PIN_7 */ + ois_dev->ois_read = bmi2_ois_spi_read; + ois_dev->ois_write = bmi2_ois_spi_write; + + /* Assign device address to interface pointer */ + ois_dev->intf_ptr = &ois_dev_addr; + + /* Configure delay in microseconds */ + ois_dev->ois_delay_us = bmi2_ois_delay_us; + + /* SDO pin is made low for selecting I2C address 0x76*/ + coines_set_pin_config(COINES_SHUTTLE_PIN_8, COINES_PIN_DIRECTION_OUT, COINES_PIN_VALUE_LOW); + + /* coines_config_spi_bus(COINES_SPI_BUS_0, COINES_SPI_SPEED_5_MHZ, COINES_SPI_MODE3); */ + coines_config_spi_bus(COINES_SPI_BUS_0, COINES_SPI_SPEED_7_5_MHZ, COINES_SPI_MODE0); + coines_delay_msec(10); + + /* PS pin is made high for selecting I2C protocol (gyroscope)*/ + coines_set_pin_config(COINES_SHUTTLE_PIN_9, COINES_PIN_DIRECTION_OUT, COINES_PIN_VALUE_HIGH); + + coines_delay_usec(10000); + + coines_set_shuttleboard_vdd_vddio_config(3300, 3300); + + coines_delay_usec(10000); + + } + else + { + rslt = BMI2_OIS_E_NULL_PTR; + } + + return rslt; +} + +/******************************************************************************/ + +/*! + * @brief This internal API prints the execution status + */ +void bmi2_ois_error_codes_print_result(const char api_name[], int8_t rslt) +{ + if (rslt != BMI2_OIS_OK) + { + printf("%s\t", api_name); + + if (rslt == BMI2_OIS_E_NULL_PTR) + { + printf("Error [%d] : Null pointer error.\r\n", rslt); + printf( + "It occurs when the user tries to assign value (not address) to a pointer, which has been initialized to NULL.\r\n"); + } + else if (rslt == BMI2_OIS_E_COM_FAIL) + { + printf("Error [%d] : Communication failure error.\r\n", rslt); + printf( + "It occurs due to read/write operation failure and also due to power failure during communication\r\n"); + } + else if (rslt == BMI2_OIS_E_INVALID_SENSOR) + { + printf( + "Error [%d] : Invalid sensor error. It occurs when there is a mismatch in the requested feature with the available one\r\n", + rslt); + } + else + { + printf("Error [%d] : Unknown error code\r\n", rslt); + } + } +} + +/*! + * @brief Deinitializes coines platform + * + * @return void. + */ +void bmi2_ois_coines_deinit(void) +{ + coines_close_comm_intf(COINES_COMM_INTF_USB); +} diff --git a/examples/bmi2_ois/common/common.h b/examples/bmi2_ois/common/common.h new file mode 100644 index 0000000..82a843b --- /dev/null +++ b/examples/bmi2_ois/common/common.h @@ -0,0 +1,92 @@ +/**\ + * Copyright (c) 2020 Bosch Sensortec GmbH. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + **/ + +#ifndef _COMMON_H +#define _COMMON_H + +/*! CPP guard */ +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include "bmi2_ois.h" + +/*! + * @brief Function for reading the sensor's registers through SPI bus. + * + * @param[in] reg_addr : Register address. + * @param[out] reg_data : Pointer to the data buffer to store the read data. + * @param[in] length : No of bytes to read. + * @param[in] intf_ptr : Interface pointer + * + * @return Status of execution + * @retval = BMI2_INTF_RET_SUCCESS -> Success + * @retval != BMI2_INTF_RET_SUCCESS -> Failure Info + * + */ +int8_t bmi2_ois_spi_read(uint8_t reg_addr, uint8_t *reg_data, uint32_t len, void *intf_ptr); + +/*! + * @brief Function for writing the sensor's registers through SPI bus. + * + * @param[in] reg_addr : Register address. + * @param[in] reg_data : Pointer to the data buffer whose data has to be written. + * @param[in] length : No of bytes to write. + * @param[in] intf_ptr : Interface pointer + * + * @return Status of execution + * @retval = BMI2_INTF_RET_SUCCESS -> Success + * @retval != BMI2_INTF_RET_SUCCESS -> Failure Info + * + */ +int8_t bmi2_ois_spi_write(uint8_t reg_addr, const uint8_t *reg_data, uint32_t len, void *intf_ptr); + +/*! + * @brief This function provides the delay for required time (Microsecond) as per the input provided in some of the + * APIs. + * + * @param[in] period_us : The required wait time in microsecond. + * @param[in] intf_ptr : Interface pointer + * + * @return void. + * + */ +void bmi2_ois_delay_us(uint32_t period, void *intf_ptr); + +/*! + * @brief Function to initialize device structure and coines platform + * + * @param[in] bma : Structure instance of bmi2_dev + * + * @return Status of execution + * @retval 0 -> Success + * @retval < 0 -> Failure Info + */ +int8_t bmi2_ois_init(struct bmi2_ois_dev *ois_dev); + +/*! + * @brief Prints the execution status of the APIs. + * + * @param[in] api_name : API name with return status + * @param[in] rslt : Error code returned by the API whose execution status has to be printed. + * + * @return void. + */ +void bmi2_ois_error_codes_print_result(const char api_name[], int8_t rslt); + +/*! + * @brief Deinitializes coines platform + * + * @return void. + */ +void bmi2_ois_coines_deinit(void); + +#ifdef __cplusplus +} +#endif /* End of CPP guard */ + +#endif /* End _COMMON_H */ diff --git a/examples/bmi2_ois/ois_accel_gyro/Makefile b/examples/bmi2_ois/ois_accel_gyro/Makefile new file mode 100644 index 0000000..65cd946 --- /dev/null +++ b/examples/bmi2_ois/ois_accel_gyro/Makefile @@ -0,0 +1,18 @@ +COINES_INSTALL_PATH ?= ../../../.. + +EXAMPLE_FILE ?= ois_accel_gyro.c + +API_LOCATION ?= ../.. + +COMMON_LOCATION ?= .. + +C_SRCS += \ +$(API_LOCATION)/bmi2.c \ +$(API_LOCATION)/bmi2_ois.c \ +$(COMMON_LOCATION)/common.c + +INCLUDEPATHS += \ +$(API_LOCATION) \ +$(COMMON_LOCATION)/common + +include $(COINES_INSTALL_PATH)/coines.mk \ No newline at end of file diff --git a/examples/ois/generic/ois_accel_gyro.c b/examples/bmi2_ois/ois_accel_gyro/ois_accel_gyro.c similarity index 82% rename from examples/ois/generic/ois_accel_gyro.c rename to examples/bmi2_ois/ois_accel_gyro/ois_accel_gyro.c index ef05b60..bdb9d8f 100644 --- a/examples/ois/generic/ois_accel_gyro.c +++ b/examples/bmi2_ois/ois_accel_gyro/ois_accel_gyro.c @@ -1,115 +1,118 @@ -/**\ - * Copyright (c) 2020 Bosch Sensortec GmbH. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - **/ - -/******************************************************************************/ -#include "bmi2_ois_common.h" -#include "bmi2_ois.h" -#include "stdio.h" - -/******************************************************************************/ -/*! Macro definition */ - -/*! Macro that holds the total number of accel x,y and z axes sample counts to be printed */ -#define ACCEL_GYRO_SAMPLE_COUNT UINT8_C(50) - -/******************************************************************************/ -/*! Functions */ - -int main(void) -{ - int8_t rslt; - - struct bmi2_ois_dev ois_dev; - - int8_t idx; - - /* To store the gyroscope cross sensitivity value */ - int16_t ois_gyr_cross_sens_zx; - - /* Array to enable sensor through OIS interface */ - uint8_t sens_sel[2] = { BMI2_OIS_ACCEL, BMI2_OIS_GYRO }; - - /* Variable that holds the accel and gyro sample count */ - uint8_t n_data = ACCEL_GYRO_SAMPLE_COUNT; - - /* Initialize the device structure */ - rslt = bmi2_ois_dev_init(&ois_dev); - bmi2_error_codes_print_result(rslt); - - /* Get configurations for OIS */ - rslt = bmi2_ois_get_config(&ois_dev); - bmi2_error_codes_print_result(rslt); - - /* OIS configurations */ - ois_dev.acc_en = BMI2_ENABLE; - ois_dev.gyr_en = BMI2_ENABLE; - ois_dev.lp_filter_en = BMI2_ENABLE; - - /* Set configurations for OIS */ - rslt = bmi2_ois_set_config(&ois_dev); - bmi2_error_codes_print_result(rslt); - - /* Get configurations for OIS */ - rslt = bmi2_ois_get_config(&ois_dev); - bmi2_error_codes_print_result(rslt); - - if (rslt == BMI2_OK) - { - for (idx = 0; idx < n_data; idx++) - { - ois_dev.ois_delay_us(156, ois_dev.intf_ptr); - - /* Accel ODR is 1600hz and gyro ODR is 6400hz.Delay required for - * accel 156us and 625us for gyro. - * taken modules from accel and gyro ODR which results every 4th sample accel and gyro - * read happens, rest of three samples gyro data alone will be read */ - if (idx % 4 == 0) - { - /* Get OIS accelerometer and gyro data through OIS interface - * @note for sensor which support gyro cross axes sensitivity pass the - * gyr_cross_sens_zx from the bmi2_dev structure */ - rslt = bmi2_ois_read_data(sens_sel, 2, &ois_dev, ois_gyr_cross_sens_zx); - bmi2_error_codes_print_result(rslt); - - if (rslt == BMI2_OK) - { - printf("\n"); - - /* Print accelerometer data */ - printf("OIS Accel x-axis = %d ", ois_dev.acc_data.x); - printf("OIS Accel y-axis = %d ", ois_dev.acc_data.y); - printf("OIS Accel z-axis = %d \n", ois_dev.acc_data.z); - - /* Print gyro data */ - printf("OIS Gyro x-axis = %d ", ois_dev.gyr_data.x); - printf("OIS Gyro y-axis = %d ", ois_dev.gyr_data.y); - printf("OIS Gyro z-axis = %d \n", ois_dev.gyr_data.z); - - printf("\n"); - } - } - else - { - /* Get OIS gyro data through OIS interface - * @note for sensor which support gyro cross axes sensitivity pass the - * gyr_cross_sens_zx from the bmi2_dev structure */ - rslt = bmi2_ois_read_data(&sens_sel[1], 1, &ois_dev, ois_gyr_cross_sens_zx); - bmi2_error_codes_print_result(rslt); - if (rslt == BMI2_OK) - { - /* Print gyro data */ - printf("OIS Gyro x-axis = %d ", ois_dev.gyr_data.x); - printf("OIS Gyro y-axis = %d ", ois_dev.gyr_data.y); - printf("OIS Gyro z-axis = %d ", ois_dev.gyr_data.z); - - printf("\n"); - } - } - } - } - - return rslt; -} +/**\ + * Copyright (c) 2020 Bosch Sensortec GmbH. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + **/ + +/******************************************************************************/ +#include + +#include "bmi2_ois.h" +#include "bmi2_ois_common.h" + +/******************************************************************************/ +/*! Macro definition */ + +/*! Macro that holds the total number of accel x,y and z axes sample counts to be printed */ +#define ACCEL_GYRO_SAMPLE_COUNT UINT8_C(50) + +/******************************************************************************/ +/*! Functions */ + +int main(void) +{ + int8_t rslt; + + struct bmi2_ois_dev ois_dev; + + int8_t idx; + + /* To store the gyroscope cross sensitivity value */ + int16_t ois_gyr_cross_sens_zx = 0; + + /* Array to enable sensor through OIS interface */ + uint8_t sens_sel[2] = { BMI2_OIS_ACCEL, BMI2_OIS_GYRO }; + + /* Variable that holds the accel and gyro sample count */ + uint8_t n_data = ACCEL_GYRO_SAMPLE_COUNT; + + /* Initialize the device structure */ + rslt = bmi2_ois_init(&ois_dev); + bmi2_ois_error_codes_print_result("bmi2_ois_init", rslt); + + /* Get configurations for OIS */ + rslt = bmi2_ois_get_config(&ois_dev); + bmi2_ois_error_codes_print_result("bmi2_ois_get_config", rslt); + + /* OIS configurations */ + ois_dev.acc_en = BMI2_OIS_ENABLE; + ois_dev.gyr_en = BMI2_OIS_ENABLE; + ois_dev.lp_filter_en = BMI2_OIS_ENABLE; + + /* Set configurations for OIS */ + rslt = bmi2_ois_set_config(&ois_dev); + bmi2_ois_error_codes_print_result("bmi2_ois_set_config", rslt); + + /* Get configurations for OIS */ + rslt = bmi2_ois_get_config(&ois_dev); + bmi2_ois_error_codes_print_result("bmi2_ois_get_config", rslt); + + if (rslt == BMI2_OIS_OK) + { + for (idx = 0; idx < n_data; idx++) + { + ois_dev.ois_delay_us(156, ois_dev.intf_ptr); + + /* Accel ODR is 1600hz and gyro ODR is 6400hz.Delay required for + * accel 156us and 625us for gyro. + * taken modules from accel and gyro ODR which results every 4th sample accel and gyro + * read happens, rest of three samples gyro data alone will be read */ + if (idx % 4 == 0) + { + /* Get OIS accelerometer and gyro data through OIS interface + * @note for sensor which support gyro cross axes sensitivity pass the + * gyr_cross_sens_zx from the bmi2_dev structure */ + rslt = bmi2_ois_read_data(sens_sel, 2, &ois_dev, ois_gyr_cross_sens_zx); + bmi2_ois_error_codes_print_result("bmi2_ois_read_data", rslt); + + if (rslt == BMI2_OIS_OK) + { + printf("\n"); + + /* Print accelerometer data */ + printf("OIS Accel x-axis = %d ", ois_dev.acc_data.x); + printf("OIS Accel y-axis = %d ", ois_dev.acc_data.y); + printf("OIS Accel z-axis = %d \n", ois_dev.acc_data.z); + + /* Print gyro data */ + printf("OIS Gyro x-axis = %d ", ois_dev.gyr_data.x); + printf("OIS Gyro y-axis = %d ", ois_dev.gyr_data.y); + printf("OIS Gyro z-axis = %d \n", ois_dev.gyr_data.z); + + printf("\n"); + } + } + else + { + /* Get OIS gyro data through OIS interface + * @note for sensor which support gyro cross axes sensitivity pass the + * gyr_cross_sens_zx from the bmi2_dev structure */ + rslt = bmi2_ois_read_data(&sens_sel[1], 1, &ois_dev, ois_gyr_cross_sens_zx); + bmi2_ois_error_codes_print_result("bmi2_ois_read_data", rslt); + if (rslt == BMI2_OIS_OK) + { + /* Print gyro data */ + printf("OIS Gyro x-axis = %d ", ois_dev.gyr_data.x); + printf("OIS Gyro y-axis = %d ", ois_dev.gyr_data.y); + printf("OIS Gyro z-axis = %d ", ois_dev.gyr_data.z); + + printf("\n"); + } + } + } + } + + bmi2_ois_coines_deinit(); + + return rslt; +} diff --git a/examples/ois/generic/bmi2_ois_common.c b/examples/ois/generic/bmi2_ois_common.c deleted file mode 100644 index 24bb61c..0000000 --- a/examples/ois/generic/bmi2_ois_common.c +++ /dev/null @@ -1,119 +0,0 @@ -/**\ - * Copyright (c) 2020 Bosch Sensortec GmbH. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - **/ - -/******************************************************************************/ -#include -#include "bmi2_ois_common.h" - -/******************************************************************************/ -/*! Global declaration */ - -/*! Device address for primary and secondary interface */ -static uint8_t ois_dev_addr; - -/******************************************************************************/ -/*! Functions */ - -/*! - * @brief Function for initialization of SPI bus. - */ -int8_t bmi2_user_spi_init(void) -{ - - /* Implement SPI bus initialization according to the target machine. */ - return 0; -} - -/*! - * @brief This function provides the delay for required time (Microseconds) as per the input provided in some of the - * APIs. - */ -void user_delay_us(uint32_t period_us, void *intf_ptr) -{ - /* Wait for a period amount of microseconds. */ -} - -/*! - * @brief This function is for writing the sensor's registers through SPI bus. - */ -int8_t user_spi_reg_write(uint8_t reg_addr, const uint8_t *reg_data, uint32_t length, void *intf_ptr) -{ - - /* Write to registers using SPI. Return 0 for a successful execution. */ - return 0; -} - -/*! - * @brief This function is for reading the sensor's registers through SPI bus. - */ -int8_t user_spi_reg_read(uint8_t reg_addr, uint8_t *reg_data, uint32_t length, void *intf_ptr) -{ - - /* Read from registers using SPI. Return 0 for a successful execution. */ - return 0; -} - -/******************************************************************************/ -int8_t bmi2_ois_dev_init(struct bmi2_ois_dev *ois_dev) -{ - int8_t rslt; - - if (ois_dev != NULL) - { - /* To initialize the user SPI function */ - bmi2_user_spi_init(); - - /* SPI interface for OIS */ - /* Chip select IO pin */ - ois_dev_addr = 0; - ois_dev->ois_read = user_spi_reg_read; - ois_dev->ois_write = user_spi_reg_write; - ois_dev->ois_delay_us = user_delay_us; - ois_dev->intf_ptr = &ois_dev_addr; - } - else - { - rslt = BMI2_OIS_E_NULL_PTR; - } - - return rslt; -} - -/******************************************************************************/ - -/*! - * @brief This internal API prints the execution status - */ -void bmi2_error_codes_print_result(int8_t rslt) -{ - switch (rslt) - { - case BMI2_OK: - - /*! Do nothing */ - break; - case BMI2_OIS_E_NULL_PTR: - printf("Error [%d] : Null pointer error.\r\n", rslt); - printf( - "It occurs when the user tries to assign value (not address) to a pointer, which has been initialized to NULL.\r\n"); - break; - case BMI2_OIS_E_COM_FAIL: - printf("Error [%d] : Communication failure error.\r\n", rslt); - printf( - "It occurs due to read/write operation failure and also due to power failure during communication\r\n"); - break; - - case BMI2_OIS_E_INVALID_SENSOR: - printf( - "Error [%d] : Invalid sensor error. It occurs when there is a mismatch in the requested feature with the available one\r\n", - rslt); - break; - - default: - printf("Error [%d] : Unknown error code\r\n", rslt); - break; - } -} diff --git a/examples/ois/generic/bmi2_ois_common.h b/examples/ois/generic/bmi2_ois_common.h deleted file mode 100644 index 45058f3..0000000 --- a/examples/ois/generic/bmi2_ois_common.h +++ /dev/null @@ -1,90 +0,0 @@ -/**\ - * Copyright (c) 2020 Bosch Sensortec GmbH. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - **/ - -#ifndef _BMI2_COMMON_H -#define _BMI2_COMMON_H - -/*! CPP guard */ -#ifdef __cplusplus -extern "C" { -#endif - -#include -#include "bmi2_ois.h" - -/*! - * @brief Function for initialization of SPI bus - * - * @retval 0 -> Success - * @retval < 0 -> Failure Info - */ -int8_t bmi2_user_spi_init(void); - -/*! - * @brief This function provides the delay for required time (Microseconds) as per the input provided in some of the - * APIs. - * @param[in] period_us : The required wait time in microseconds. - * @param[in] intf_ptr : Pointer to interface. - * @return void. - * - */ -void user_delay_us(uint32_t period_us, void *intf_ptr); - -/*! - * @brief This function is for reading the sensor's registers through SPI bus. - * - * @param[in] reg_addr : Register address. - * @param[out] reg_data : Pointer to the data buffer to store the read data. - * @param[in] length : No of bytes to read. - * @param[in] intf_ptr : Pointer to interface. - * @return Status of execution - * @retval = BMI2_INTF_RET_SUCCESS -> Success - * @retval != BMI2_INTF_RET_SUCCESS -> Failure - * - */ -int8_t user_spi_reg_read(uint8_t reg_addr, uint8_t *reg_data, uint32_t length, void *intf_ptr); - -/*! - * @brief This function is for writing the sensor's registers through SPI bus. - * - * @param[in] reg_addr : Register address. - * @param[in] reg_data : Pointer to the data buffer whose data has to be written. - * @param[in] length : No of bytes to write. - * @param[in] intf_ptr : Pointer to interface. - * - * @return Status of execution - * @retval = BMI2_INTF_RET_SUCCESS -> Success - * @retval != BMI2_INTF_RET_SUCCESS -> Failure - * - */ -int8_t user_spi_reg_write(uint8_t reg_addr, const uint8_t *reg_data, uint32_t length, void *intf_ptr); - -/*! - * @brief This internal API is used to print the execution status. - * - * @param[in] rslt : Error code returned by the API whose execution status has to be printed. - * - * @return void. - */ -void bmi2_error_codes_print_result(int8_t rslt); - -/*! - * @brief This internal API is used to initialize the dev structures. - * - * @param[in] dev : Structure instance of bmi2_dev. - * @param[in] ois_dev : Structure instance of bmi2_ois_dev. - * - * @return Status of execution. - * @retval 0 -> Success - * @retval < 0 -> Failure Info - */ -int8_t bmi2_ois_dev_init(struct bmi2_ois_dev *ois_dev); - -#ifdef __cplusplus -} -#endif /* End of CPP guard */ - -#endif /* End of _BMI2_COMMON_H */