From 2620831255614d47481abf929f7870099d8c5017 Mon Sep 17 00:00:00 2001 From: bstaistudiocx Date: Mon, 20 May 2024 14:59:29 +0550 Subject: [PATCH] BMA530 Sensor API v4.1.0 Github release. --- LICENSE | 30 + README.md | 29 + bma5.c | 2032 ++++++++++++++ bma5.h | 1079 +++++++ bma530.c | 609 ++++ bma530.h | 958 +++++++ bma530_context.h | 176 ++ bma530_features.c | 2496 +++++++++++++++++ bma530_features.h | 1336 +++++++++ bma5_defs.h | 1438 ++++++++++ examples/accel_foc/Makefile | 18 + examples/accel_foc/accel_foc.c | 352 +++ examples/accelerometer/Makefile | 18 + examples/accelerometer/accelerometer.c | 207 ++ examples/android_generic_interrupt_1/Makefile | 18 + .../android_generic_interrupt_1.c | 173 ++ examples/android_generic_interrupt_2/Makefile | 18 + .../android_generic_interrupt_2.c | 173 ++ examples/android_sig_motion/Makefile | 18 + .../android_sig_motion/android_sig_motion.c | 157 ++ examples/android_tilt/Makefile | 18 + examples/android_tilt/android_tilt.c | 153 + examples/common/common.c | 200 ++ examples/common/common.h | 167 ++ examples/feature_axis_exchange/Makefile | 18 + .../feature_axis_exchange.c | 269 ++ .../Makefile | 18 + ...ifo_full_16_bit_dedicated_frame_comp_dis.c | 377 +++ .../Makefile | 18 + .../fifo_full_16_bit_each_frame_comp_dis.c | 380 +++ .../Makefile | 18 + .../fifo_full_8_bit_dedicated_frame_comp_en.c | 374 +++ .../Makefile | 18 + .../fifo_full_8_bit_each_frame_comp_en.c | 377 +++ .../Makefile | 18 + .../fifo_wm_16_bit_dedicated_frame_comp_dis.c | 386 +++ .../Makefile | 18 + .../fifo_wm_16_bit_each_frame_comp_dis.c | 389 +++ .../Makefile | 18 + .../fifo_wm_8_bit_dedicated_frame_comp_en.c | 383 +++ .../fifo_wm_8_bit_each_frame_comp_en/Makefile | 18 + .../fifo_wm_8_bit_each_frame_comp_en.c | 386 +++ examples/flat/Makefile | 18 + examples/flat/flat.c | 189 ++ examples/generic_interrupt_1/Makefile | 18 + .../generic_interrupt_1/generic_interrupt_1.c | 158 ++ examples/generic_interrupt_2/Makefile | 18 + .../generic_interrupt_2/generic_interrupt_2.c | 158 ++ examples/generic_interrupt_3/Makefile | 18 + .../generic_interrupt_3/generic_interrupt_3.c | 158 ++ examples/orientation/Makefile | 18 + examples/orientation/orientation.c | 213 ++ examples/self_test/Makefile | 18 + examples/self_test/self_test.c | 413 +++ examples/sig_motion/Makefile | 18 + examples/sig_motion/sig_motion.c | 141 + examples/step_activity/Makefile | 18 + examples/step_activity/step_activity.c | 185 ++ examples/step_counter/Makefile | 18 + examples/step_counter/step_counter.c | 210 ++ examples/step_detector/Makefile | 18 + examples/step_detector/step_detector.c | 193 ++ examples/temperature/Makefile | 18 + examples/temperature/temperature.c | 109 + examples/tilt/Makefile | 18 + examples/tilt/tilt.c | 138 + 66 files changed, 17837 insertions(+) create mode 100644 LICENSE create mode 100644 README.md create mode 100644 bma5.c create mode 100644 bma5.h create mode 100644 bma530.c create mode 100644 bma530.h create mode 100644 bma530_context.h create mode 100644 bma530_features.c create mode 100644 bma530_features.h create mode 100644 bma5_defs.h create mode 100644 examples/accel_foc/Makefile create mode 100644 examples/accel_foc/accel_foc.c create mode 100644 examples/accelerometer/Makefile create mode 100644 examples/accelerometer/accelerometer.c create mode 100644 examples/android_generic_interrupt_1/Makefile create mode 100644 examples/android_generic_interrupt_1/android_generic_interrupt_1.c create mode 100644 examples/android_generic_interrupt_2/Makefile create mode 100644 examples/android_generic_interrupt_2/android_generic_interrupt_2.c create mode 100644 examples/android_sig_motion/Makefile create mode 100644 examples/android_sig_motion/android_sig_motion.c create mode 100644 examples/android_tilt/Makefile create mode 100644 examples/android_tilt/android_tilt.c create mode 100644 examples/common/common.c create mode 100644 examples/common/common.h create mode 100644 examples/feature_axis_exchange/Makefile create mode 100644 examples/feature_axis_exchange/feature_axis_exchange.c create mode 100644 examples/fifo_full_16_bit_dedicated_frame_comp_dis/Makefile create mode 100644 examples/fifo_full_16_bit_dedicated_frame_comp_dis/fifo_full_16_bit_dedicated_frame_comp_dis.c create mode 100644 examples/fifo_full_16_bit_each_frame_comp_dis/Makefile create mode 100644 examples/fifo_full_16_bit_each_frame_comp_dis/fifo_full_16_bit_each_frame_comp_dis.c create mode 100644 examples/fifo_full_8_bit_dedicated_frame_comp_en/Makefile create mode 100644 examples/fifo_full_8_bit_dedicated_frame_comp_en/fifo_full_8_bit_dedicated_frame_comp_en.c create mode 100644 examples/fifo_full_8_bit_each_frame_comp_en/Makefile create mode 100644 examples/fifo_full_8_bit_each_frame_comp_en/fifo_full_8_bit_each_frame_comp_en.c create mode 100644 examples/fifo_wm_16_bit_dedicated_frame_comp_dis/Makefile create mode 100644 examples/fifo_wm_16_bit_dedicated_frame_comp_dis/fifo_wm_16_bit_dedicated_frame_comp_dis.c create mode 100644 examples/fifo_wm_16_bit_each_frame_comp_dis/Makefile create mode 100644 examples/fifo_wm_16_bit_each_frame_comp_dis/fifo_wm_16_bit_each_frame_comp_dis.c create mode 100644 examples/fifo_wm_8_bit_dedicated_frame_comp_en/Makefile create mode 100644 examples/fifo_wm_8_bit_dedicated_frame_comp_en/fifo_wm_8_bit_dedicated_frame_comp_en.c create mode 100644 examples/fifo_wm_8_bit_each_frame_comp_en/Makefile create mode 100644 examples/fifo_wm_8_bit_each_frame_comp_en/fifo_wm_8_bit_each_frame_comp_en.c create mode 100644 examples/flat/Makefile create mode 100644 examples/flat/flat.c create mode 100644 examples/generic_interrupt_1/Makefile create mode 100644 examples/generic_interrupt_1/generic_interrupt_1.c create mode 100644 examples/generic_interrupt_2/Makefile create mode 100644 examples/generic_interrupt_2/generic_interrupt_2.c create mode 100644 examples/generic_interrupt_3/Makefile create mode 100644 examples/generic_interrupt_3/generic_interrupt_3.c create mode 100644 examples/orientation/Makefile create mode 100644 examples/orientation/orientation.c create mode 100644 examples/self_test/Makefile create mode 100644 examples/self_test/self_test.c create mode 100644 examples/sig_motion/Makefile create mode 100644 examples/sig_motion/sig_motion.c create mode 100644 examples/step_activity/Makefile create mode 100644 examples/step_activity/step_activity.c create mode 100644 examples/step_counter/Makefile create mode 100644 examples/step_counter/step_counter.c create mode 100644 examples/step_detector/Makefile create mode 100644 examples/step_detector/step_detector.c create mode 100644 examples/temperature/Makefile create mode 100644 examples/temperature/temperature.c create mode 100644 examples/tilt/Makefile create mode 100644 examples/tilt/tilt.c diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..3fe3a6b --- /dev/null +++ b/LICENSE @@ -0,0 +1,30 @@ +Copyright (c) 2023 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. \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..281feae --- /dev/null +++ b/README.md @@ -0,0 +1,29 @@ +BMA530 SensorAPI + +> This package contains the SensorAPIs for the BMA530 sensor + +## Sensor Overview +The BMA530 is an ultra-small, triaxial, low-g high performance acceleration sensor with digital interfaces. The sensor is +suitable for low-power and demanding consumer electronics applications. + +## Applications + +### BMA530 + +- Generic Interrupt 1 +- Generic Interrupt 2 +- Generic Interrupt 3 +- Android Generic Interrupt 1 +- Android Generic Interrupt 2 +- FIFO +- Feature Axis Exchange +- Orientation +- Significant motion +- Step activity +- Step counter +- Step detector +- Tilt +- Android Significant motion +- Android Tilt + +--- \ No newline at end of file diff --git a/bma5.c b/bma5.c new file mode 100644 index 0000000..6b34238 --- /dev/null +++ b/bma5.c @@ -0,0 +1,2032 @@ +/** +* Copyright (c) 2024 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 bma5.c +* @date 2024-04-15 +* @version v4.1.0 +* +*/ + +/******************************************************************************/ +/****************************** Header files **********************************/ +/******************************************************************************/ +#include "bma5.h" + +/******************************************************************************/ +/*********************** Static function declarations *************************/ +/******************************************************************************/ + +/*! + * @brief Internal API to verify the validity of the primary device handle which + * is passed as argument. + * + * @param[in] dev : Structure instance of bma5_dev. + * + * @return Result of API execution status + * @retval BMA5_OK -> device handle is valid + * @retval BMA5_E_NULL_PTR -> Null pointer error + */ +static int8_t verify_handle(const struct bma5_dev *dev); + +/*! + * @brief This internal API is used to reset the FIFO related configurations + * in the fifo_frame structure. + * + * @param[in] fifo : Structure instance of bma5_fifo_frame. + * + * @return Void + */ +static void reset_fifo_data_structure(struct bma5_fifo_frame *fifo); + +/*! + * @brief This internal API is used to unpack the accelerometer and sensor time data from the + * FIFO 8 bit data. + * It updates the idx value which is used to store the index of + * the current data byte which is parsed. + * + * @param[in] frame_header : Stores header byte. + * @param[in, out] acc : Structure instance of bma5_sens_fifo_axes_data_8_bit. + * @param[in, out] idx : Index value of number of bytes parsed. + * @param[in, out] acc_idx : Index value of accel data (x,y,z axes) + * frame to be parsed. + * @param[in] fifo : Structure instance of bma5_fifo_frame. + * @param[in] fifo_conf : Structure instance of bma5_fifo_conf. + * + * @return Result of API execution status + * @retval BMA5_OK -> Success + * @retval BMA5_E_NULL_PTR -> Null pointer Error + */ +static int8_t unpack_accel_sensor_time_frm_8_bit(uint8_t frame_header, + struct bma5_sens_fifo_axes_data_8_bit *acc, + uint16_t *idx, + uint16_t *acc_idx, + const struct bma5_fifo_frame *fifo, + const struct bma5_fifo_conf *fifo_conf); + +/*! + * @brief This internal API is used to unpack the accelerometer and sensor time data from the + * FIFO 16 bit data. + * It updates the idx value which is used to store the index of + * the current data byte which is parsed. + * + * @param[in] frame_header : Stores header byte. + * @param[in, out] acc : Structure instance of bma5_sens_fifo_axes_data_16_bit. + * @param[in, out] idx : Index value of number of bytes parsed. + * @param[in, out] acc_idx : Index value of accel data (x,y,z axes) + * frame to be parsed. + * @param[in] fifo : Structure instance of bma5_fifo_frame. + * @param[in] fifo_conf : Structure instance of bma5_fifo_conf. + * + * @return Result of API execution status + * @retval BMA5_OK -> Success + * @retval BMA5_E_NULL_PTR -> Null pointer Error + */ +static int8_t unpack_accel_sensor_time_frm_16_bit(uint8_t frame_header, + struct bma5_sens_fifo_axes_data_16_bit *acc, + uint16_t *idx, + uint16_t *acc_idx, + const struct bma5_fifo_frame *fifo, + const struct bma5_fifo_conf *fifo_conf); + +/*! + * @brief This internal API is used to unpack the accelerometer and sensor time data from the + * FIFO 8 bit data and store it in the instance of the structure bma5_sens_fifo_axes_data_8_bit. + * + * @param[in] frame_header : Stores header byte. + * @param[in, out] accel_data : Structure instance of bma5_sens_fifo_axes_data_8_bit. + * @param[in, out] data_start_index : Index value of number of bytes parsed. + * @param[in] per_frame_data : Variable to hold total number of bytes in one frame. + * @param[in] fifo : Structure instance of bma5_fifo_frame. + * + * @return Result of API execution status + * @retval BMA5_OK -> Success + * @retval BMA5_E_NULL_PTR -> Null pointer Error + */ +static int8_t unpack_accel_sensor_time_8_bit_data(uint8_t frame_header, + struct bma5_sens_fifo_axes_data_8_bit *accel_data, + uint16_t *data_start_index, + uint16_t per_frame_data, + const struct bma5_fifo_frame *fifo); + +/*! + * @brief This internal API is used to unpack the accelerometer and sensor time data from the + * FIFO 16 bit data and store it in the instance of the structure bma5_sens_fifo_axes_data_16_bit. + * + * @param[in] frame_header : Stores header byte. + * @param[in, out] accel_data : Structure instance of bma5_sens_fifo_axes_data_16_bit. + * @param[in, out] data_start_index : Index value of number of bytes parsed. + * @param[in] fifo : Structure instance of bma5_fifo_frame. + * + * @return Result of API execution status + * @retval BMA5_OK -> Success + * @retval BMA5_E_NULL_PTR -> Null pointer Error + */ +static int8_t unpack_accel_sensor_time_16_bit_data(uint8_t frame_header, + struct bma5_sens_fifo_axes_data_16_bit *accel_data, + uint16_t *data_start_index, + const struct bma5_fifo_frame *fifo); + +/*! + * @brief This internal API reads the FIFO fill level which is set + * in the sensor. + * + * @param[out] fifo_fill_lvl : Get FIFO fill level. + * @param[in,out] dev : Structure instance of bma5_dev. + * + * @return Result of API execution status + * + * @retval = 0 -> Success + * @retval > 0 -> Warning + * @retval < 0 -> Error + */ +static int8_t get_fifo_fill_level(uint16_t *fifo_fill_lvl, struct bma5_dev *dev); + +/******************************************************************************/ +/*********************** User function definitions ****************************/ +/******************************************************************************/ +int8_t bma5_get_health_status(uint8_t *sensor_health_status, struct bma5_dev *dev) +{ + /* Function execution status */ + int8_t result; + + /* Temporary variable to carry the register value */ + uint8_t reg_value; + + if (NULL == sensor_health_status) + { + result = BMA5_E_NULL_PTR; + } + else + { + result = bma5_get_regs(BMA5_REG_HEALTH_STATUS, ®_value, sizeof(reg_value), dev); + if (BMA5_OK == result) + { + /* Parse needed details from received serial data */ + *sensor_health_status = BMA5_GET_BITS_POS_0(reg_value, BMA5_SENSOR_HEALTH_STATUS); + } + } + + return result; +} + +int8_t bma5_get_cmd_suspend(uint8_t *suspend, struct bma5_dev *dev) +{ + /* Function execution status */ + int8_t result; + + /* Temporary variable to carry the register value */ + uint8_t reg_value; + + if (NULL == suspend) + { + result = BMA5_E_NULL_PTR; + } + else + { + result = bma5_get_regs(BMA5_REG_CMD_SUSPEND, ®_value, sizeof(reg_value), dev); + if (BMA5_OK == result) + { + /* Parse needed details from received serial data */ + *suspend = BMA5_GET_BITS_POS_0(reg_value, BMA5_SUSPEND); + } + } + + return result; +} + +int8_t bma5_set_cmd_suspend(const uint8_t suspend, struct bma5_dev *dev) +{ + /* Function execution status */ + int8_t result; + + /* Temporary variable to store the register value to be set */ + uint8_t reg_value = 0; + + /* Bring up the register value to be set, as per the input details */ + reg_value = BMA5_SET_BITS_POS_0(reg_value, BMA5_SUSPEND, suspend); + + result = bma5_set_regs(BMA5_REG_CMD_SUSPEND, (const uint8_t *)®_value, sizeof(reg_value), dev); + + return result; +} + +int8_t bma5_get_config_status(struct bma5_config_status *config, struct bma5_dev *dev) +{ + /* Function execution status */ + int8_t result; + + /* Temporary variable to carry the register value */ + uint8_t reg_value; + + if (NULL == config) + { + result = BMA5_E_NULL_PTR; + } + else + { + result = bma5_get_regs(BMA5_REG_CONFIG_STATUS, ®_value, sizeof(reg_value), dev); + if (BMA5_OK == result) + { + /* Parse needed details from received serial data */ + config->feat_eng_err = BMA5_GET_BITS_POS_0(reg_value, BMA5_FEAT_ENG_ERR); + config->acc_conf_err = BMA5_GET_BITS(reg_value, BMA5_ACC_CONF_ERR); + } + } + + return result; +} + +int8_t bma5_set_config_status(const struct bma5_config_status *config, struct bma5_dev *dev) +{ + /* Function execution status */ + int8_t result; + + /* Temporary variable to store the register value to be set */ + uint8_t reg_value = 0; + + if (NULL == config) + { + result = BMA5_E_NULL_PTR; + } + else + { + /* Bring up the register value to be set, as per the input details */ + reg_value = BMA5_SET_BITS_POS_0(reg_value, BMA5_FEAT_ENG_ERR, config->feat_eng_err); + + result = bma5_set_regs(BMA5_REG_CONFIG_STATUS, (const uint8_t *)®_value, sizeof(reg_value), dev); + } + + return result; +} + +int8_t bma5_get_sensor_status(struct bma5_sensor_status *config, struct bma5_dev *dev) +{ + /* Function execution status */ + int8_t result; + + /* Temporary variable to carry the register value */ + uint8_t reg_value; + + if (NULL == config) + { + result = BMA5_E_NULL_PTR; + } + else + { + result = bma5_get_regs(BMA5_REG_SENSOR_STATUS, ®_value, sizeof(reg_value), dev); + if (BMA5_OK == result) + { + /* Parse needed details from received serial data */ + config->acc_data_rdy = BMA5_GET_BITS_POS_0(reg_value, BMA5_ACC_DATA_RDY); + config->temperature_rdy = BMA5_GET_BITS(reg_value, BMA5_TEMPERATURE_RDY); + config->sensor_rdy = BMA5_GET_BITS(reg_value, BMA5_SENSOR_RDY); + } + } + + return result; +} + +int8_t bma5_set_sensor_status(const struct bma5_sensor_status *config, struct bma5_dev *dev) +{ + /* Function execution status */ + int8_t result; + + /* Temporary variable to store the register value to be set */ + uint8_t reg_value = 0; + + if (NULL == config) + { + result = BMA5_E_NULL_PTR; + } + else + { + /* Bring up the register value to be set, as per the input details */ + reg_value = BMA5_SET_BITS_POS_0(reg_value, BMA5_ACC_DATA_RDY, config->acc_data_rdy); + reg_value = BMA5_SET_BITS(reg_value, BMA5_TEMPERATURE_RDY, config->temperature_rdy); + + result = bma5_set_regs(BMA5_REG_SENSOR_STATUS, (const uint8_t *)®_value, sizeof(reg_value), dev); + } + + return result; +} + +int8_t bma5_get_temp_data(uint8_t *temp_data, struct bma5_dev *dev) +{ + /* Function execution status */ + int8_t result; + + /* Temporary variable to carry the register value */ + uint8_t reg_value; + + if (NULL == temp_data) + { + result = BMA5_E_NULL_PTR; + } + else + { + result = bma5_get_regs(BMA5_REG_TEMP_DATA, ®_value, sizeof(reg_value), dev); + if (BMA5_OK == result) + { + /* Parse needed details from received serial data */ + *temp_data = BMA5_GET_BITS_POS_0(reg_value, BMA5_TEMP_DATA); + } + } + + return result; +} + +int8_t bma5_get_fifo_data_out(uint8_t *fifo_data_out, struct bma5_dev *dev) +{ + /* Function execution status */ + int8_t result; + + /* Temporary variable to carry the register value */ + uint8_t reg_value; + + if (NULL == fifo_data_out) + { + result = BMA5_E_NULL_PTR; + } + else + { + result = bma5_get_regs(BMA5_REG_FIFO_DATA_OUT, ®_value, sizeof(reg_value), dev); + if (BMA5_OK == result) + { + /* Parse needed details from received serial data */ + *fifo_data_out = BMA5_GET_BITS_POS_0(reg_value, BMA5_FIFO_DATA_OUT); + } + } + + return result; +} + +int8_t bma5_get_acc_conf_0(uint8_t *sensor_ctrl, struct bma5_dev *dev) +{ + /* Function execution status */ + int8_t result; + + /* Temporary variable to carry the register value */ + uint8_t reg_value; + + if (NULL == sensor_ctrl) + { + result = BMA5_E_NULL_PTR; + } + else + { + result = bma5_get_regs(BMA5_REG_ACC_CONF_0, ®_value, sizeof(reg_value), dev); + if (BMA5_OK == result) + { + /* Parse needed details from received serial data */ + *sensor_ctrl = BMA5_GET_BITS_POS_0(reg_value, BMA5_SENSOR_CTRL); + } + } + + return result; +} + +int8_t bma5_set_acc_conf_0(const uint8_t sensor_ctrl, struct bma5_dev *dev) +{ + /* Function execution status */ + int8_t result; + + /* Temporary variable to store the register value to be set */ + uint8_t reg_value = 0; + + /* Bring up the register value to be set, as per the input details */ + reg_value = BMA5_SET_BITS_POS_0(reg_value, BMA5_SENSOR_CTRL, sensor_ctrl); + + result = bma5_set_regs(BMA5_REG_ACC_CONF_0, (const uint8_t *)®_value, sizeof(reg_value), dev); + + return result; +} + +int8_t bma5_get_acc_conf(struct bma5_acc_conf *config, struct bma5_dev *dev) +{ + /* Function execution status */ + int8_t result; + + /* Temporary variable to carry the register value */ + uint8_t reg_value[2] = { 0 }; + + if (NULL == config) + { + result = BMA5_E_NULL_PTR; + } + else + { + result = bma5_get_regs(BMA5_REG_ACC_CONF_1, reg_value, 2, dev); + if (BMA5_OK == result) + { + /* Parse needed details from received serial data */ + config->acc_odr = BMA5_GET_BITS_POS_0(reg_value[0], BMA5_ACC_ODR); + config->acc_bwp = BMA5_GET_BITS(reg_value[0], BMA5_ACC_BWP); + config->power_mode = BMA5_GET_BITS(reg_value[0], BMA5_POWER_MODE); + + config->acc_range = BMA5_GET_BITS_POS_0(reg_value[1], BMA5_ACC_RANGE); + config->acc_iir_ro = BMA5_GET_BITS(reg_value[1], BMA5_ACC_IIR_RO); + config->noise_mode = BMA5_GET_BITS(reg_value[1], BMA5_NOISE_MODE); + config->acc_drdy_int_auto_clear = BMA5_GET_BITS(reg_value[1], BMA5_ACC_DRDY_INT_AUTO_CLEAR); + } + } + + return result; +} + +int8_t bma5_set_acc_conf(const struct bma5_acc_conf *config, struct bma5_dev *dev) +{ + /* Function execution status */ + int8_t result; + + /* Temporary variable to store the register value to be set */ + uint8_t reg_value[2] = { 0 }; + + if (NULL == config) + { + result = BMA5_E_NULL_PTR; + } + else + { + /* Bring up the register value to be set, as per the input details */ + reg_value[0] = BMA5_SET_BITS_POS_0(reg_value[0], BMA5_ACC_ODR, config->acc_odr); + reg_value[0] = BMA5_SET_BITS(reg_value[0], BMA5_ACC_BWP, config->acc_bwp); + reg_value[0] = BMA5_SET_BITS(reg_value[0], BMA5_POWER_MODE, config->power_mode); + + reg_value[1] = BMA5_SET_BITS_POS_0(reg_value[1], BMA5_ACC_RANGE, config->acc_range); + reg_value[1] = BMA5_SET_BITS(reg_value[1], BMA5_ACC_IIR_RO, config->acc_iir_ro); + reg_value[1] = BMA5_SET_BITS(reg_value[1], BMA5_NOISE_MODE, config->noise_mode); + reg_value[1] = BMA5_SET_BITS(reg_value[1], BMA5_ACC_DRDY_INT_AUTO_CLEAR, config->acc_drdy_int_auto_clear); + + result = bma5_set_regs(BMA5_REG_ACC_CONF_1, (const uint8_t *)reg_value, 2, dev); + } + + return result; +} + +int8_t bma5_get_temp_conf(struct bma5_temp_conf *config, struct bma5_dev *dev) +{ + /* Function execution status */ + int8_t result; + + /* Temporary variable to carry the register value */ + uint8_t reg_value; + + if (NULL == config) + { + result = BMA5_E_NULL_PTR; + } + else + { + result = bma5_get_regs(BMA5_REG_TEMP_CONF, ®_value, sizeof(reg_value), dev); + if (BMA5_OK == result) + { + /* Parse needed details from received serial data */ + config->temp_rate = BMA5_GET_BITS_POS_0(reg_value, BMA5_TEMP_RATE); + config->temp_meas_src = BMA5_GET_BITS(reg_value, BMA5_TEMP_MEAS_SRC); + config->temp_ext_sel = BMA5_GET_BITS(reg_value, BMA5_TEMP_EXT_SEL); + config->temp_tcs = BMA5_GET_BITS(reg_value, BMA5_TEMP_TCS); + config->temp_tco = BMA5_GET_BITS(reg_value, BMA5_TEMP_TCO); + } + } + + return result; +} + +int8_t bma5_set_temp_conf(const struct bma5_temp_conf *config, struct bma5_dev *dev) +{ + /* Function execution status */ + int8_t result; + + /* Temporary variable to store the register value to be set */ + uint8_t reg_value = 0; + + if (NULL == config) + { + result = BMA5_E_NULL_PTR; + } + else + { + /* Bring up the register value to be set, as per the input details */ + reg_value = BMA5_SET_BITS_POS_0(reg_value, BMA5_TEMP_RATE, config->temp_rate); + reg_value = BMA5_SET_BITS(reg_value, BMA5_TEMP_MEAS_SRC, config->temp_meas_src); + reg_value = BMA5_SET_BITS(reg_value, BMA5_TEMP_EXT_SEL, config->temp_ext_sel); + reg_value = BMA5_SET_BITS(reg_value, BMA5_TEMP_TCS, config->temp_tcs); + reg_value = BMA5_SET_BITS(reg_value, BMA5_TEMP_TCO, config->temp_tco); + + result = bma5_set_regs(BMA5_REG_TEMP_CONF, (const uint8_t *)®_value, sizeof(reg_value), dev); + } + + return result; +} + +int8_t bma5_get_int_conf(struct bma5_int_conf_types *config, uint8_t int_configs, struct bma5_dev *dev) +{ + /* Function execution status */ + int8_t result = BMA5_OK; + uint8_t loop; + + /* Temporary variable to carry the register value */ + uint8_t reg_value; + + if (NULL == config) + { + result = BMA5_E_NULL_PTR; + } + else + { + for (loop = 0; loop < int_configs; loop++) + { + if (config[loop].int_src == BMA5_INT_1) + { + result = bma5_get_regs(BMA5_REG_INT1_CONF, ®_value, sizeof(reg_value), dev); + } + else if (config[loop].int_src == BMA5_INT_2) + { + result = bma5_get_regs(BMA5_REG_INT2_CONF, ®_value, sizeof(reg_value), dev); + } + else + { + result = BMA5_E_INVALID_INTERRUPT; + } + + /* Update the config values. */ + if (BMA5_OK != result) + { + break; + } + + /* Parse needed details from received serial data */ + config[loop].int_conf.int_mode = BMA5_GET_BITS_POS_0(reg_value, BMA5_INT_MODE); + config[loop].int_conf.int_od = BMA5_GET_BITS(reg_value, BMA5_INT_OD); + config[loop].int_conf.int_lvl = BMA5_GET_BITS(reg_value, BMA5_INT_LVL); + } + } + + return result; +} + +int8_t bma5_set_int_conf(const struct bma5_int_conf_types *config, uint8_t int_configs, struct bma5_dev *dev) +{ + /* Function execution status */ + int8_t result = BMA5_OK; + uint8_t loop; + + /* Temporary variable to store the register value to be set */ + uint8_t reg_value = 0; + + if (NULL == config) + { + result = BMA5_E_NULL_PTR; + } + else + { + for (loop = 0; loop < int_configs; loop++) + { + /* Bring up the register value to be set, as per the input details */ + reg_value = BMA5_SET_BITS_POS_0(reg_value, BMA5_INT_MODE, config[loop].int_conf.int_mode); + reg_value = BMA5_SET_BITS(reg_value, BMA5_INT_OD, config[loop].int_conf.int_od); + reg_value = BMA5_SET_BITS(reg_value, BMA5_INT_LVL, config[loop].int_conf.int_lvl); + + if (config[loop].int_src == BMA5_INT_1) + { + result = bma5_set_regs(BMA5_REG_INT1_CONF, (const uint8_t *)®_value, sizeof(reg_value), dev); + } + else if (config[loop].int_src == BMA5_INT_2) + { + result = bma5_set_regs(BMA5_REG_INT2_CONF, (const uint8_t *)®_value, sizeof(reg_value), dev); + } + else + { + result = BMA5_E_INVALID_INTERRUPT; + } + + if (result != BMA5_OK) + { + break; + } + } + } + + return result; +} + +int8_t bma5_get_if_conf_0(uint8_t *if_i2c_slv_addr, struct bma5_dev *dev) +{ + /* Function execution status */ + int8_t result; + + /* Temporary variable to carry the register value */ + uint8_t reg_value; + + if (NULL == if_i2c_slv_addr) + { + result = BMA5_E_NULL_PTR; + } + else + { + result = bma5_get_regs(BMA5_REG_IF_CONF_0, ®_value, sizeof(reg_value), dev); + if (BMA5_OK == result) + { + /* Parse needed details from received serial data */ + *if_i2c_slv_addr = BMA5_GET_BITS_POS_0(reg_value, BMA5_IF_I2C_SLV_ADDR); + } + } + + return result; +} + +int8_t bma5_get_if_conf(struct bma5_if_conf *config, struct bma5_dev *dev) +{ + /* Function execution status */ + int8_t result; + + /* Temporary variable to carry the register value */ + uint8_t reg_value; + + if (NULL == config) + { + result = BMA5_E_NULL_PTR; + } + else + { + result = bma5_get_regs(BMA5_REG_IF_CONF_1, ®_value, sizeof(reg_value), dev); + if (BMA5_OK == result) + { + /* Parse needed details from received serial data */ + config->if_i3c_cfg = BMA5_GET_BITS_POS_0(reg_value, BMA5_IF_I3C_CFG); + config->if_spi3_cfg = BMA5_GET_BITS(reg_value, BMA5_IF_SPI3_CFG); + config->if_csb_pullup = BMA5_GET_BITS(reg_value, BMA5_IF_CSB_PULLUP); + config->if_pad_drv = BMA5_GET_BITS(reg_value, BMA5_IF_PAD_DRV); + config->if_i2c_drv_sel = BMA5_GET_BITS(reg_value, BMA5_IF_I2C_DRV_SEL); + } + } + + return result; +} + +int8_t bma5_set_if_conf(const struct bma5_if_conf *config, struct bma5_dev *dev) +{ + /* Function execution status */ + int8_t result; + + /* Temporary variable to store the register value to be set */ + uint8_t reg_value = 0; + + if (NULL == config) + { + result = BMA5_E_NULL_PTR; + } + else + { + /* Bring up the register value to be set, as per the input details */ + reg_value = BMA5_SET_BITS_POS_0(reg_value, BMA5_IF_I3C_CFG, config->if_i3c_cfg); + reg_value = BMA5_SET_BITS(reg_value, BMA5_IF_SPI3_CFG, config->if_spi3_cfg); + reg_value = BMA5_SET_BITS(reg_value, BMA5_IF_CSB_PULLUP, config->if_csb_pullup); + reg_value = BMA5_SET_BITS(reg_value, BMA5_IF_PAD_DRV, config->if_pad_drv); + reg_value = BMA5_SET_BITS(reg_value, BMA5_IF_I2C_DRV_SEL, config->if_i2c_drv_sel); + + result = bma5_set_regs(BMA5_REG_IF_CONF_1, (const uint8_t *)®_value, sizeof(reg_value), dev); + } + + return result; +} + +int8_t bma5_set_fifo_ctrl(const struct bma5_fifo_ctrl *config, struct bma5_dev *dev) +{ + /* Function execution status */ + int8_t result; + + /* Temporary variable to store the register value to be set */ + uint8_t reg_value = 0; + + if (NULL == config) + { + result = BMA5_E_NULL_PTR; + } + else + { + /* Bring up the register value to be set, as per the input details */ + reg_value = BMA5_SET_BITS_POS_0(reg_value, BMA5_FIFO_RST, config->fifo_rst); + reg_value = BMA5_SET_BITS(reg_value, BMA5_FIFO_FRAME_SYNC, config->fifo_frame_sync); + + result = bma5_set_regs(BMA5_REG_FIFO_CTRL, (const uint8_t *)®_value, sizeof(reg_value), dev); + } + + return result; +} + +int8_t bma5_get_fifo_conf(struct bma5_fifo_conf *config, struct bma5_dev *dev) +{ + /* Function execution status */ + int8_t result; + + /* Temporary variable to carry the register value */ + uint8_t reg_value[2] = { 0 }; + + if (NULL == config) + { + result = BMA5_E_NULL_PTR; + } + else + { + result = bma5_get_regs(BMA5_REG_FIFO_CONF_0, reg_value, 2, dev); + if (BMA5_OK == result) + { + /* Parse needed details from received serial data */ + config->fifo_cfg = BMA5_GET_BITS_POS_0(reg_value[0], BMA5_FIFO_CFG); + config->fifo_acc_x = BMA5_GET_BITS(reg_value[0], BMA5_FIFO_ACC_X); + config->fifo_acc_y = BMA5_GET_BITS(reg_value[0], BMA5_FIFO_ACC_Y); + config->fifo_acc_z = BMA5_GET_BITS(reg_value[0], BMA5_FIFO_ACC_Z); + config->fifo_compression = BMA5_GET_BITS(reg_value[0], BMA5_FIFO_COMPRESSION); + + config->fifo_size = BMA5_GET_BITS_POS_0(reg_value[1], BMA5_FIFO_SIZE); + config->fifo_sensor_time = BMA5_GET_BITS(reg_value[1], BMA5_FIFO_SENSOR_TIME); + config->fifo_stop_on_full = BMA5_GET_BITS(reg_value[1], BMA5_FIFO_STOP_ON_FULL); + } + } + + return result; +} + +int8_t bma5_set_fifo_conf(const struct bma5_fifo_conf *config, struct bma5_dev *dev) +{ + /* Function execution status */ + int8_t result; + + /* Temporary variable to store the register value to be set */ + uint8_t reg_value[2] = { 0 }; + + if (NULL == config) + { + result = BMA5_E_NULL_PTR; + } + else + { + reg_value[0] = BMA5_SET_BITS_POS_0(reg_value[0], BMA5_FIFO_CFG, config->fifo_cfg); + reg_value[0] = BMA5_SET_BITS(reg_value[0], BMA5_FIFO_ACC_X, config->fifo_acc_x); + reg_value[0] = BMA5_SET_BITS(reg_value[0], BMA5_FIFO_ACC_Y, config->fifo_acc_y); + reg_value[0] = BMA5_SET_BITS(reg_value[0], BMA5_FIFO_ACC_Z, config->fifo_acc_z); + reg_value[0] = BMA5_SET_BITS(reg_value[0], BMA5_FIFO_COMPRESSION, config->fifo_compression); + + reg_value[1] = BMA5_SET_BITS_POS_0(reg_value[1], BMA5_FIFO_SIZE, config->fifo_size); + reg_value[1] = BMA5_SET_BITS(reg_value[1], BMA5_FIFO_SENSOR_TIME, config->fifo_sensor_time); + reg_value[1] = BMA5_SET_BITS(reg_value[1], BMA5_FIFO_STOP_ON_FULL, config->fifo_stop_on_full); + + result = bma5_set_regs(BMA5_REG_FIFO_CONF_0, (const uint8_t *)reg_value, 2, dev); + } + + return result; +} + +int8_t bma5_get_feat_eng_conf(uint8_t *feat_eng_ctrl, struct bma5_dev *dev) +{ + /* Function execution status */ + int8_t result; + + /* Temporary variable to carry the register value */ + uint8_t reg_value; + + if (NULL == feat_eng_ctrl) + { + result = BMA5_E_NULL_PTR; + } + else + { + result = bma5_get_regs(BMA5_REG_FEAT_ENG_CONF, ®_value, sizeof(reg_value), dev); + if (BMA5_OK == result) + { + /* Parse needed details from received serial data */ + *feat_eng_ctrl = BMA5_GET_BITS_POS_0(reg_value, BMA5_FEAT_ENG_CTRL); + } + } + + return result; +} + +int8_t bma5_set_feat_eng_conf(const uint8_t feat_eng_ctrl, struct bma5_dev *dev) +{ + /* Function execution status */ + int8_t result; + + /* Temporary variable to store the register value to be set */ + uint8_t reg_value = 0; + + /* Bring up the register value to be set, as per the input details */ + reg_value = BMA5_SET_BITS_POS_0(reg_value, BMA5_FEAT_ENG_CTRL, feat_eng_ctrl); + + result = bma5_set_regs(BMA5_REG_FEAT_ENG_CONF, (const uint8_t *)®_value, sizeof(reg_value), dev); + + return result; +} + +int8_t bma5_get_feat_eng_status(struct bma5_feat_eng_status *config, struct bma5_dev *dev) +{ + /* Function execution status */ + int8_t result; + + /* Temporary variable to carry the register value */ + uint8_t reg_value; + + if (NULL == config) + { + result = BMA5_E_NULL_PTR; + } + else + { + result = bma5_get_regs(BMA5_REG_FEAT_ENG_STATUS, ®_value, sizeof(reg_value), dev); + if (BMA5_OK == result) + { + /* Parse needed details from received serial data */ + config->feat_eng_halted = BMA5_GET_BITS_POS_0(reg_value, BMA5_FEAT_ENG_HALTED); + config->feat_eng_running = BMA5_GET_BITS(reg_value, BMA5_FEAT_ENG_RUNNING); + config->host_gpr_update_pending = BMA5_GET_BITS(reg_value, BMA5_HOST_GPR_UPDATE_PENDING); + config->feat_eng_gpr_update_pending = BMA5_GET_BITS(reg_value, BMA5_FEAT_ENG_GPR_UPDATE_PENDING); + } + } + + return result; +} + +int8_t bma5_get_feat_eng_gpr_conf(struct bma5_feat_eng_gpr_conf *config, struct bma5_dev *dev) +{ + /* Function execution status */ + int8_t result; + + /* Temporary variable to carry the register value */ + uint8_t reg_value; + + if (NULL == config) + { + result = BMA5_E_NULL_PTR; + } + else + { + result = bma5_get_regs(BMA5_REG_FEAT_ENG_GPR_CONF, ®_value, sizeof(reg_value), dev); + if (BMA5_OK == result) + { + /* Parse needed details from received serial data */ + config->feat_eng_gpr_0_dir = BMA5_GET_BITS_POS_0(reg_value, BMA5_FEAT_ENG_GPR_0_DIR); + config->feat_eng_gpr_1_dir = BMA5_GET_BITS(reg_value, BMA5_FEAT_ENG_GPR_1_DIR); + config->feat_eng_gpr_2_dir = BMA5_GET_BITS(reg_value, BMA5_FEAT_ENG_GPR_2_DIR); + config->feat_eng_gpr_3_dir = BMA5_GET_BITS(reg_value, BMA5_FEAT_ENG_GPR_3_DIR); + config->feat_eng_gpr_4_dir = BMA5_GET_BITS(reg_value, BMA5_FEAT_ENG_GPR_4_DIR); + config->feat_eng_gpr_5_dir = BMA5_GET_BITS(reg_value, BMA5_FEAT_ENG_GPR_5_DIR); + config->feat_eng_gpr_6_dir = BMA5_GET_BITS(reg_value, BMA5_FEAT_ENG_GPR_6_DIR); + } + } + + return result; +} + +int8_t bma5_set_feat_eng_gpr_conf(const struct bma5_feat_eng_gpr_conf *config, struct bma5_dev *dev) +{ + /* Function execution status */ + int8_t result; + + /* Temporary variable to store the register value to be set */ + uint8_t reg_value = 0; + + if (NULL == config) + { + result = BMA5_E_NULL_PTR; + } + else + { + /* Bring up the register value to be set, as per the input details */ + reg_value = BMA5_SET_BITS_POS_0(reg_value, BMA5_FEAT_ENG_GPR_0_DIR, config->feat_eng_gpr_0_dir); + reg_value = BMA5_SET_BITS(reg_value, BMA5_FEAT_ENG_GPR_1_DIR, config->feat_eng_gpr_1_dir); + reg_value = BMA5_SET_BITS(reg_value, BMA5_FEAT_ENG_GPR_2_DIR, config->feat_eng_gpr_2_dir); + reg_value = BMA5_SET_BITS(reg_value, BMA5_FEAT_ENG_GPR_3_DIR, config->feat_eng_gpr_3_dir); + reg_value = BMA5_SET_BITS(reg_value, BMA5_FEAT_ENG_GPR_4_DIR, config->feat_eng_gpr_4_dir); + reg_value = BMA5_SET_BITS(reg_value, BMA5_FEAT_ENG_GPR_5_DIR, config->feat_eng_gpr_5_dir); + reg_value = BMA5_SET_BITS(reg_value, BMA5_FEAT_ENG_GPR_6_DIR, config->feat_eng_gpr_6_dir); + + result = bma5_set_regs(BMA5_REG_FEAT_ENG_GPR_CONF, (const uint8_t *)®_value, sizeof(reg_value), dev); + } + + return result; +} + +int8_t bma5_set_feat_eng_gpr_ctrl(const struct bma5_feat_eng_gpr_ctrl *config, struct bma5_dev *dev) +{ + /* Function execution status */ + int8_t result; + + /* Temporary variable to store the register value to be set */ + uint8_t reg_value = 0; + + if (NULL == config) + { + result = BMA5_E_NULL_PTR; + } + else + { + /* Bring up the register value to be set, as per the input details */ + reg_value = BMA5_SET_BITS_POS_0(reg_value, BMA5_UPDATE_GPRS, config->update_gprs); + reg_value = BMA5_SET_BITS(reg_value, BMA5_UNLOCK_GPRS, config->unlock_gprs); + + result = bma5_set_regs(BMA5_REG_FEAT_ENG_GPR_CTRL, (const uint8_t *)®_value, sizeof(reg_value), dev); + } + + return result; +} + +int8_t bma5_get_feature_data_addr(uint8_t *feature_data_addr, struct bma5_dev *dev) +{ + /* Function execution status */ + int8_t result; + + /* Temporary variable to carry the register value */ + uint8_t reg_value; + + if (NULL == feature_data_addr) + { + result = BMA5_E_NULL_PTR; + } + else + { + result = bma5_get_regs(BMA5_REG_FEATURE_DATA_ADDR, ®_value, sizeof(reg_value), dev); + if (BMA5_OK == result) + { + /* Parse needed details from received serial data */ + *feature_data_addr = BMA5_GET_BITS_POS_0(reg_value, BMA5_FEATURE_DATA_ADDR); + } + } + + return result; +} + +int8_t bma5_set_feature_data_addr(const uint8_t feature_data_addr, struct bma5_dev *dev) +{ + /* Function execution status */ + int8_t result; + + /* Temporary variable to store the register value to be set */ + uint8_t reg_value = 0; + + /* Bring up the register value to be set, as per the input details */ + reg_value = BMA5_SET_BITS_POS_0(reg_value, BMA5_FEATURE_DATA_ADDR, feature_data_addr); + + result = bma5_set_regs(BMA5_REG_FEATURE_DATA_ADDR, (const uint8_t *)®_value, sizeof(reg_value), dev); + + return result; +} + +int8_t bma5_get_feature_data_tx(uint8_t *feature_data, struct bma5_dev *dev) +{ + /* Function execution status */ + int8_t result; + + /* Temporary variable to carry the register value */ + uint8_t reg_value; + + if (NULL == feature_data) + { + result = BMA5_E_NULL_PTR; + } + else + { + result = bma5_get_regs(BMA5_REG_FEATURE_DATA_TX, ®_value, sizeof(reg_value), dev); + if (BMA5_OK == result) + { + /* Parse needed details from received serial data */ + *feature_data = BMA5_GET_BITS_POS_0(reg_value, BMA5_FEATURE_DATA); + } + } + + return result; +} + +int8_t bma5_set_feature_data_tx(const uint8_t feature_data, struct bma5_dev *dev) +{ + /* Function execution status */ + int8_t result; + + /* Temporary variable to store the register value to be set */ + uint8_t reg_value = 0; + + /* Bring up the register value to be set, as per the input details */ + reg_value = BMA5_SET_BITS_POS_0(reg_value, BMA5_FEATURE_DATA, feature_data); + + result = bma5_set_regs(BMA5_REG_FEATURE_DATA_TX, (const uint8_t *)®_value, sizeof(reg_value), dev); + + return result; +} + +int8_t bma5_get_acc_self_test(struct bma5_acc_self_test *config, struct bma5_dev *dev) +{ + /* Function execution status */ + int8_t result; + + /* Temporary variable to carry the register value */ + uint8_t reg_value; + + if (NULL == config) + { + result = BMA5_E_NULL_PTR; + } + else + { + result = bma5_get_regs(BMA5_REG_ACC_SELF_TEST, ®_value, sizeof(reg_value), dev); + if (BMA5_OK == result) + { + /* Parse needed details from received serial data */ + config->self_test = BMA5_GET_BITS_POS_0(reg_value, BMA5_SELF_TEST); + config->self_test_sign = BMA5_GET_BITS(reg_value, BMA5_SELF_TEST_SIGN); + } + } + + return result; +} + +int8_t bma5_set_acc_self_test(const struct bma5_acc_self_test *config, struct bma5_dev *dev) +{ + /* Function execution status */ + int8_t result; + + /* Temporary variable to store the register value to be set */ + uint8_t reg_value = 0; + + if (NULL == config) + { + result = BMA5_E_NULL_PTR; + } + else + { + /* Bring up the register value to be set, as per the input details */ + reg_value = BMA5_SET_BITS_POS_0(reg_value, BMA5_SELF_TEST, config->self_test); + reg_value = BMA5_SET_BITS(reg_value, BMA5_SELF_TEST_SIGN, config->self_test_sign); + + result = bma5_set_regs(BMA5_REG_ACC_SELF_TEST, (const uint8_t *)®_value, sizeof(reg_value), dev); + } + + return result; +} + +int8_t bma5_set_cmd(const uint8_t cmd, struct bma5_dev *dev) +{ + /* Function execution status */ + int8_t result; + + /* Temporary variable to store the register value to be set */ + uint8_t reg_value = 0; + + /* Bring up the register value to be set, as per the input details */ + reg_value = BMA5_SET_BITS_POS_0(reg_value, BMA5_CMD, cmd); + + result = bma5_set_regs(BMA5_REG_CMD, (const uint8_t *)®_value, sizeof(reg_value), dev); + + return result; +} + +int8_t bma5_get_acc(struct bma5_accel *accel, struct bma5_dev *dev) +{ + /* Function execution status */ + int8_t result; + + /* Temporary buffer to receive the serial data from sensor */ + uint8_t data[6] = { 0 }; + + if (NULL == accel) + { + result = BMA5_E_NULL_PTR; + } + else + { + result = bma5_get_regs(BMA5_REG_ACC_DATA_0, data, 6, dev); + if (BMA5_OK == result) + { + /* Group the serial data to get needed detail */ + accel->x = (int16_t)(((uint16_t)data[1] << 8) | ((uint16_t)data[0])); + accel->y = (int16_t)(((uint16_t)data[3] << 8) | ((uint16_t)data[2])); + accel->z = (int16_t)(((uint16_t)data[5] << 8) | ((uint16_t)data[4])); + } + } + + return result; +} + +int8_t bma5_get_sensor_time(uint32_t *sensor_time, struct bma5_dev *dev) +{ + /* Function execution status */ + int8_t result; + + /* Temporary buffer to receive the serial data from sensor */ + uint8_t data[3] = { 0 }; + + if (NULL == sensor_time) + { + result = BMA5_E_NULL_PTR; + } + else + { + result = bma5_get_regs(BMA5_REG_SENSOR_TIME_0, (uint8_t *)data, sizeof(data), dev); + if (BMA5_OK == result) + { + /* Group the serial data to get needed detail */ + *sensor_time = (uint32_t)(((uint32_t)data[2] << 16) | ((uint32_t)data[1] << 8) | ((uint32_t)data[0])); + } + } + + return result; +} + +int8_t bma5_get_fifo_fill_level(uint16_t *fifo_fill_level, struct bma5_dev *dev) +{ + /* Function execution status */ + int8_t result; + + /* Temporary variable to receive the serial data from sensor */ + uint8_t reg_value; + + /* Temporary variables to carry values of components */ + uint8_t fifo_fill_level_7_0; + uint8_t fifo_fill_level_10_8; + + if (NULL == fifo_fill_level) + { + result = BMA5_E_NULL_PTR; + } + else + { + result = bma5_get_regs(BMA5_REG_FIFO_LEVEL_0, ®_value, sizeof(reg_value), dev); + if (BMA5_OK == result) + { + /* Parse fifo_fill_level_7_0 from received serial data */ + fifo_fill_level_7_0 = BMA5_GET_BITS_POS_0(reg_value, BMA5_FIFO_FILL_LEVEL_7_0); + + result = bma5_get_regs(BMA5_REG_FIFO_LEVEL_1, ®_value, sizeof(reg_value), dev); + } + + if (BMA5_OK == result) + { + /* Parse fifo_fill_level_10_8 from received serial data */ + fifo_fill_level_10_8 = BMA5_GET_BITS_POS_0(reg_value, BMA5_FIFO_FILL_LEVEL_10_8); + + /* Group the components to get needed detail */ + *fifo_fill_level = (uint16_t)(((uint16_t)fifo_fill_level_10_8 << 8) | ((uint16_t)fifo_fill_level_7_0)); + } + } + + return result; +} + +int8_t bma5_get_fifo_wm(uint16_t *fifo_wm, struct bma5_dev *dev) +{ + /* Function execution status */ + int8_t result; + + /* Temporary variable to receive the serial data from sensor */ + uint8_t reg_value; + + /* Temporary variables to carry values of components */ + uint8_t fifo_watermark_level_7_0; + uint8_t fifo_watermark_level_10_8; + + if (NULL == fifo_wm) + { + result = BMA5_E_NULL_PTR; + } + else + { + result = bma5_get_regs(BMA5_REG_FIFO_WM_0, ®_value, sizeof(reg_value), dev); + if (BMA5_OK == result) + { + /* Parse fifo_watermark_level_7_0 from received serial data */ + fifo_watermark_level_7_0 = BMA5_GET_BITS_POS_0(reg_value, BMA5_FIFO_WATERMARK_LEVEL_7_0); + + result = bma5_get_regs(BMA5_REG_FIFO_WM_1, ®_value, sizeof(reg_value), dev); + } + + if (BMA5_OK == result) + { + /* Parse fifo_watermark_level_10_8 from received serial data */ + fifo_watermark_level_10_8 = BMA5_GET_BITS_POS_0(reg_value, BMA5_FIFO_WATERMARK_LEVEL_10_8); + + /* Group the components to get needed detail */ + *fifo_wm = (uint16_t)(((uint16_t)fifo_watermark_level_10_8 << 8) | ((uint16_t)fifo_watermark_level_7_0)); + } + } + + return result; +} + +/*! + * @brief This API sets the FIFO watermark level in the sensor. + */ +int8_t bma5_set_fifo_wm(uint16_t fifo_wm, struct bma5_dev *dev) +{ + /* Variable to define error */ + int8_t result; + + /* Array to store FIFO watermark level */ + uint8_t data[2] = { 0 }; + + data[0] = (uint8_t)(fifo_wm & UINT16_C(0x00FF)); + data[1] = (uint8_t)((fifo_wm & UINT16_C(0xFF00)) >> 8); + + /* Set FIFO watermark level */ + result = bma5_set_regs(BMA5_REG_FIFO_WM_0, data, 2, dev); + + return result; +} + +int8_t bma5_get_acc_doff(struct bma5_accel_doff *accel_doff, struct bma5_dev *dev) +{ + /* Function execution status */ + int8_t result; + + /* Temporary variable to receive the serial data from sensor */ + uint8_t reg_value[6] = { 0 }; + + /* Temporary variables to carry values of components */ + uint8_t acc_doff_7_0; + uint8_t acc_doff_8; + + if (NULL == accel_doff) + { + result = BMA5_E_NULL_PTR; + } + else + { + result = bma5_get_regs(BMA5_REG_ACC_OFFSET_0, reg_value, 6, dev); + if (BMA5_OK == result) + { + acc_doff_7_0 = BMA5_GET_BITS_POS_0(reg_value[0], BMA5_ACC_DOFF_7_0); + acc_doff_8 = BMA5_GET_BITS_POS_0(reg_value[1], BMA5_ACC_DOFF_8); + + accel_doff->x_doff = (int16_t)(((uint16_t)acc_doff_8 << 8) | ((uint16_t)acc_doff_7_0)); + + acc_doff_7_0 = BMA5_GET_BITS_POS_0(reg_value[2], BMA5_ACC_DOFF_7_0); + acc_doff_8 = BMA5_GET_BITS_POS_0(reg_value[3], BMA5_ACC_DOFF_8); + + accel_doff->y_doff = (int16_t)(((uint16_t)acc_doff_8 << 8) | ((uint16_t)acc_doff_7_0)); + + acc_doff_7_0 = BMA5_GET_BITS_POS_0(reg_value[4], BMA5_ACC_DOFF_7_0); + acc_doff_8 = BMA5_GET_BITS_POS_0(reg_value[5], BMA5_ACC_DOFF_8); + + accel_doff->z_doff = (int16_t)(((uint16_t)acc_doff_8 << 8) | ((uint16_t)acc_doff_7_0)); + } + } + + return result; +} + +/*! + * @brief This API sets accel user offset for x, y and z-axis. + */ +int8_t bma5_set_acc_doff(const struct bma5_accel_doff *accel_doff, struct bma5_dev *dev) +{ + /* Variable to define error */ + int8_t result = BMA5_OK; + + /* Array to store accel foc user offset data */ + uint8_t accel_doff_data[6] = { 0 }; + + if (accel_doff == NULL) + { + result = BMA5_E_NULL_PTR; + } + else + { + accel_doff_data[0] = BMA5_SET_BITS_POS_0(accel_doff_data[0], BMA5_ACC_DOFF_X_7_0, accel_doff->x_doff); + accel_doff_data[1] = BMA5_SET_BITS_POS_0(accel_doff_data[1], BMA5_ACC_DOFF_X_8, accel_doff->x_doff); + accel_doff_data[2] = BMA5_SET_BITS_POS_0(accel_doff_data[2], BMA5_ACC_DOFF_Y_7_0, accel_doff->y_doff); + accel_doff_data[3] = BMA5_SET_BITS_POS_0(accel_doff_data[3], BMA5_ACC_DOFF_Y_8, accel_doff->y_doff); + accel_doff_data[4] = BMA5_SET_BITS_POS_0(accel_doff_data[4], BMA5_ACC_DOFF_Z_7_0, accel_doff->z_doff); + accel_doff_data[5] = BMA5_SET_BITS_POS_0(accel_doff_data[5], BMA5_ACC_DOFF_Z_8, accel_doff->z_doff); + + /* Set accel user offset */ + result = bma5_set_regs(BMA5_REG_ACC_OFFSET_0, accel_doff_data, 6, dev); + } + + return result; +} + +/*! + * @brief This API reads the data from the given register address of bma5 + * sensor. + */ +int8_t bma5_get_regs(uint8_t addr, uint8_t *data, uint32_t len, struct bma5_dev *dev) +{ + /* Function execution status */ + int8_t result; + + /* Temporary buffer to receive the serial data from sensor */ + uint8_t temp_buf[BMA5_MAX_BUFFER_SIZE] = { 0 }; + + /* Number of bytes to be copied from temp_buf to data */ + uint32_t bytes_to_copy = len; + + result = verify_handle(dev); + if ((BMA5_OK == result) && (NULL == data)) + { + result = BMA5_E_NULL_PTR; + } + + if (BMA5_OK == result) + { + /* Configuring register address for SPI Interface */ + if (BMA5_SPI_INTF == dev->intf) + { + addr = addr | BMA5_SPI_RD_MSK; + } + + dev->intf_rslt = dev->bus_read(addr, temp_buf, (len + dev->dummy_byte), dev->intf_ptr); + + if (BMA5_INTF_RET_SUCCESS != dev->intf_rslt) + { + result = BMA5_E_COM_FAIL; + } + } + + if (BMA5_OK == result) + { + while (bytes_to_copy--) + { + data[bytes_to_copy] = temp_buf[bytes_to_copy + dev->dummy_byte]; + } + } + + return result; +} + +/*! + * @brief This API writes data to the given register address of bma5 sensor. + */ +int8_t bma5_set_regs(uint8_t addr, const uint8_t *data, uint32_t len, struct bma5_dev *dev) +{ + /* Function execution status */ + int8_t result; + + result = verify_handle(dev); + if ((BMA5_OK == result) && (NULL == data)) + { + result = BMA5_E_NULL_PTR; + } + + if (BMA5_OK == result) + { + /* Configuring register address for SPI Interface */ + if (BMA5_SPI_INTF == dev->intf) + { + addr = (addr & BMA5_SPI_WR_MSK); + } + + dev->intf_rslt = dev->bus_write(addr, data, len, dev->intf_ptr); + + if (BMA5_INTF_RET_SUCCESS != dev->intf_rslt) + { + result = BMA5_E_COM_FAIL; + } + } + + return result; +} + +/*! + * @brief This API is to activate self-test procedure + */ +int8_t bma5_activate_self_test(struct bma5_dev *dev) +{ + /* Variable to store the function result */ + int8_t result; + + /* Variables to set the accel configuration for self test */ + /* Setting ODR = 1.6 Khz, ACC_BWP = Normal Mode, Power Mode = High Performance Mode (Continuous Mode */ + uint8_t acc_conf1 = 0xAA; + + /* Setting Acc Range = 8G, ACC IIR RO = db_20 -20dB roll-off */ + uint8_t acc_conf2 = 0x06; + uint8_t acc_conf0; + + /* Disable accelerometer */ + acc_conf0 = BMA5_SENSOR_CTRL_DISABLE; + result = bma5_set_regs(BMA5_REG_ACC_CONF_0, &acc_conf0, 1, dev); + + if (result == BMA5_OK) + { + /* Set acc_odr as 1.6 kHZ, acc_bwp as normal mode and acc_perf_mode as continuous mode */ + result = bma5_set_regs(BMA5_REG_ACC_CONF_1, &acc_conf1, 1, dev); + + if (result == BMA5_OK) + { + /* Set acc_range as 8g, acc_iir_ro as -20dB roll-off */ + result = bma5_set_regs(BMA5_REG_ACC_CONF_2, &acc_conf2, 1, dev); + + if (result == BMA5_OK) + { + /* Enable accelerometer */ + acc_conf0 = BMA5_SENSOR_CTRL_ENABLE; + result = bma5_set_regs(BMA5_REG_ACC_CONF_0, &acc_conf0, 1, dev); + + if (result == BMA5_OK) + { + /* Delay of 10ms required after write of above configurations */ + dev->delay_us(BMA5_SELF_TEST_DELAY, dev->intf_ptr); + } + } + } + } + + return result; +} + +/*! + * @brief This API is to perform self-test procedure + * with positive excitation + */ +int8_t bma5_self_test_pos_excitation(struct bma5_dev *dev) +{ + /* Variable to store the function result */ + int8_t result; + + /* Variables to set the accel configuration for self test */ + uint8_t acc_self_test = 0x03; + + /* Enable self-test with positive excitation */ + result = bma5_set_regs(BMA5_REG_ACC_SELF_TEST, &acc_self_test, 1, dev); + + if (result == BMA5_OK) + { + /* Delay of 10ms required after write of above configurations */ + dev->delay_us(BMA5_SELF_TEST_DELAY, dev->intf_ptr); + } + + return result; +} + +/*! + * @brief This API is to perform self-test procedure + * with negative excitation + */ +int8_t bma5_self_test_neg_excitation(struct bma5_dev *dev) +{ + /* Variable to store the function result */ + int8_t result; + + /* Variables to set the accel configuration for self test */ + uint8_t acc_self_test = 0x01; + + /* Enable self-test with negative excitation */ + result = bma5_set_regs(BMA5_REG_ACC_SELF_TEST, &acc_self_test, 1, dev); + + if (result == BMA5_OK) + { + /* Delay of 10ms required after write of above configurations */ + dev->delay_us(BMA5_SELF_TEST_DELAY, dev->intf_ptr); + } + + return result; +} + +/*! + * @brief This API reads the FIFO data from the sensor + */ +int8_t bma5_read_fifo_data(struct bma5_fifo_frame *fifo, const struct bma5_fifo_conf *fifo_conf, struct bma5_dev *dev) +{ + /* Variable to store the function result */ + int8_t result; + + /* Variable to store FIFO data register address */ + uint8_t reg_addr = BMA5_REG_FIFO_DATA_OUT; + + /* Number of bytes to be copied */ + uint32_t bytes_to_copy = 0; + + /* Null-pointer check */ + result = verify_handle(dev); + + if ((result == BMA5_OK) && (fifo != NULL) && (fifo->data != NULL) && (fifo_conf != NULL)) + { + /* Reset the FIFO data structure */ + reset_fifo_data_structure(fifo); + + /* Get fifo available length in bytes */ + result = get_fifo_fill_level(&fifo->fifo_avail_len, dev); + + if ((fifo->fifo_avail_len != 0) && (result == BMA5_OK)) + { + /* Configuring reg_addr for SPI Interface */ + if (dev->intf == BMA5_SPI_INTF) + { + reg_addr = (reg_addr | BMA5_SPI_RD_MSK); + } + + if (fifo_conf->fifo_sensor_time == BMA5_FIFO_SENSOR_TIME_DEDICATED_FRAME) + { + /* Overhead bytes added to read FIFO for higher ODRs */ + fifo->fifo_avail_len += BMA5_SENSORTIME_OVERHEAD_BYTE; + } + + dev->intf_rslt = + dev->bus_read(reg_addr, fifo->data, (fifo->fifo_avail_len + dev->dummy_byte), dev->intf_ptr); + + dev->delay_us(2, dev->intf_ptr); + + if (dev->intf_rslt != BMA5_INTF_RET_SUCCESS) + { + result = BMA5_E_COM_FAIL; + } + else + { + while (bytes_to_copy < fifo->fifo_avail_len) + { + fifo->data[bytes_to_copy] = fifo->data[bytes_to_copy + dev->dummy_byte]; + + bytes_to_copy++; + } + } + } + } + else + { + result = BMA5_E_NULL_PTR; + } + + return result; +} + +/*! + * @brief This API parses and extracts the accelerometer and sensortime frames from + * FIFO 8 bit data read by the "bma5_read_fifo_data" API and stores it in the + * "bma5_sens_fifo_axes_data_8_bit" structure instance. + */ +int8_t bma5_extract_acc_sens_time_8_bit(struct bma5_sens_fifo_axes_data_8_bit *accel_data, + struct bma5_fifo_frame *fifo, + const struct bma5_fifo_conf *fifo_conf, + const struct bma5_dev *dev) +{ + /* Variable to store the function result */ + int8_t result; + + /* Variable to store frame header byte */ + uint8_t frame_header = 0; + + /* Variable to store index value of number of bytes parsed */ + uint16_t data_index = 0; + + /* Variable to store index value of accel data (x,y,z axes) frame to be parsed. */ + uint16_t accel_index = 0; + + /* Null-pointer check */ + result = verify_handle(dev); + + if ((result == BMA5_OK) && (accel_data != NULL) && (fifo != NULL) && (fifo_conf != NULL)) + { + for (data_index = fifo->acc_byte_start_idx; + ((data_index < fifo->fifo_avail_len) && (fifo->data[data_index] != 128)); + ) + { + /* Header byte is stored in the variable frame_header */ + frame_header = fifo->data[data_index]; + + /* Index is moved to next byte where the data is starting */ + data_index++; + + result = unpack_accel_sensor_time_frm_8_bit(frame_header, + accel_data, + &data_index, + &accel_index, + fifo, + fifo_conf); + } + + /* Update number of accel data read */ + fifo->fifo_avail_frames = accel_index; + + /* Update the accelerometer byte index */ + fifo->acc_byte_start_idx = data_index; + } + else + { + result = BMA5_E_NULL_PTR; + } + + return result; +} + +/*! + * @brief This API parses and extracts the accelerometer and sensortime frames from + * FIFO 16 bit data read by the "bma5_read_fifo_data" API and stores it in the + * "bma5_sens_fifo_axes_data_16_bit" structure instance. + */ +int8_t bma5_extract_acc_sens_time_16_bit(struct bma5_sens_fifo_axes_data_16_bit *accel_data, + struct bma5_fifo_frame *fifo, + const struct bma5_fifo_conf *fifo_conf, + const struct bma5_dev *dev) +{ + /* Variable to store the function result */ + int8_t result; + + /* Variable to store frame header byte */ + uint8_t frame_header = 0; + + /* Variable to store index value of number of bytes parsed */ + uint16_t data_index = 0; + + /* Variable to store index value of accel data (x,y,z axes) frame to be parsed. */ + uint16_t accel_index = 0; + + /* Null-pointer check */ + result = verify_handle(dev); + + if ((result == BMA5_OK) && (accel_data != NULL) && (fifo != NULL) && (fifo_conf != NULL)) + { + for (data_index = fifo->acc_byte_start_idx; + ((data_index < fifo->fifo_avail_len) && (fifo->data[data_index] != 128)); + ) + { + /* Header byte is stored in the variable frame_header */ + frame_header = fifo->data[data_index]; + + /* Get the frame details from header */ + frame_header = frame_header & BMA5_FIFO_FRAME_HDR_MSK; + + /* Index is moved to next byte where the data is starting */ + data_index++; + + result = unpack_accel_sensor_time_frm_16_bit(frame_header, + accel_data, + &data_index, + &accel_index, + fifo, + fifo_conf); + } + + /* Update number of accel data read */ + fifo->fifo_avail_frames = accel_index; + + /* Update the accelerometer byte index */ + fifo->acc_byte_start_idx = data_index; + } + else + { + result = BMA5_E_NULL_PTR; + } + + return result; +} + +/******************************************************************************/ +/*********************** Static function definitions **************************/ +/******************************************************************************/ +static int8_t verify_handle(const struct bma5_dev *dev) +{ + /* Function execution status */ + int8_t result = BMA5_E_NULL_PTR; + + if (NULL != dev) + { + if ((NULL != dev->bus_read) && (NULL != dev->bus_write) && (NULL != dev->delay_us)) + { + result = BMA5_OK; + } + } + + return result; +} + +/*! + * @brief This internal API is used to reset the FIFO related configurations + * in the fifo_frame structure. + */ +static void reset_fifo_data_structure(struct bma5_fifo_frame *fifo) +{ + /* Prepare for next FIFO read by resetting FIFO's + * internal data structures + */ + fifo->fifo_avail_len = 0; + fifo->acc_byte_start_idx = 0; + fifo->fifo_avail_frames = 0; +} + +/*! + * @brief This internal API is used to unpack the accelerometer and sensortime data from the + * FIFO 8 bit data. + * It updates the idx value which is used to store the index of + * the current data byte which is parsed. + */ +static int8_t unpack_accel_sensor_time_frm_8_bit(uint8_t frame_header, + struct bma5_sens_fifo_axes_data_8_bit *acc, + uint16_t *idx, + uint16_t *acc_idx, + const struct bma5_fifo_frame *fifo, + const struct bma5_fifo_conf *fifo_conf) +{ + /* Variable to store the function result */ + int8_t result; + + /* Variable to hold total number of bytes in one frame */ + uint16_t per_frame_data = 0; + + if (fifo_conf->fifo_sensor_time & BMA5_FIFO_SENSOR_TIME_EACH_FRAME) + { + per_frame_data = BMA5_FIFO_8_BIT_ACCEL_XYZ_SENS_TIME_DATA; + } + else if (fifo_conf->fifo_sensor_time & BMA5_FIFO_SENSOR_TIME_DEDICATED_FRAME) + { + per_frame_data = BMA5_FIFO_8_BIT_ACCEL_XYZ_DATA; + } + + /* Partial read, then skip the data */ + if ((*idx + per_frame_data) > fifo->fifo_avail_len) + { + /* Update the data index as complete */ + *idx = fifo->fifo_avail_len; + } + + /* Unpack the data array into the structure instance "acc" */ + result = unpack_accel_sensor_time_8_bit_data(frame_header, &acc[*acc_idx], idx, per_frame_data, fifo); + + if (result == BMA5_OK) + { + (*acc_idx)++; + } + else if (result == BMA5_W_FIFO_PARTIAL_READ) + { + *idx = fifo->fifo_avail_len; + } + + return result; +} + +/*! + * @brief This internal API is used to unpack the accelerometer and sensortime data from the + * FIFO 16 bit data. + * It updates the idx value which is used to store the index of + * the current data byte which is parsed. + */ +static int8_t unpack_accel_sensor_time_frm_16_bit(uint8_t frame_header, + struct bma5_sens_fifo_axes_data_16_bit *acc, + uint16_t *idx, + uint16_t *acc_idx, + const struct bma5_fifo_frame *fifo, + const struct bma5_fifo_conf *fifo_conf) +{ + /* Variable to store the function result */ + int8_t result; + + /* Variable to hold total number of bytes in one frame */ + uint16_t per_frame_data = 0; + + if (fifo_conf->fifo_sensor_time & BMA5_FIFO_SENSOR_TIME_EACH_FRAME) + { + per_frame_data = BMA5_FIFO_16_BIT_ACCEL_XYZ_SENS_TIME_DATA; + } + else if (fifo_conf->fifo_sensor_time & BMA5_FIFO_SENSOR_TIME_DEDICATED_FRAME) + { + per_frame_data = BMA5_FIFO_16_BIT_ACCEL_XYZ_DATA; + } + + /* Partial read, then skip the data */ + if ((*idx + per_frame_data) > fifo->fifo_avail_len) + { + /* Update the data index as complete */ + *idx = fifo->fifo_avail_len; + } + + /* Unpack the data array into the structure instance "acc" */ + result = unpack_accel_sensor_time_16_bit_data(frame_header, &acc[*acc_idx], idx, fifo); + + if (result == BMA5_OK) + { + (*acc_idx)++; + } + else if (result == BMA5_W_FIFO_PARTIAL_READ) + { + *idx = fifo->fifo_avail_len; + } + + return result; +} + +/*! + * @brief This internal API is used to unpack the accelerometer data from the + * FIFO 8 bit data and store it in the instance of the structure bma5_sens_fifo_axes_data_8_bit. + */ +static int8_t unpack_accel_sensor_time_8_bit_data(uint8_t frame_header, + struct bma5_sens_fifo_axes_data_8_bit *accel_data, + uint16_t *data_start_index, + uint16_t per_frame_data, + const struct bma5_fifo_frame *fifo) +{ + /* Variable to store the function result */ + int8_t result = BMA5_OK; + + /* Variable to store sensor time */ + uint32_t sens_time_data_xlsb, sens_time_data_lsb, sens_time_data_msb; + + if ((((*data_start_index) + per_frame_data) <= fifo->fifo_avail_len) && + (frame_header != BMA5_FIFO_SENS_TIME_EN_DEDI_FRM)) + { + if (frame_header & BMA5_FIFO_ACC_X_MSK) + { + /* Accel raw x data */ + accel_data->x = (int8_t)(fifo->data[(*data_start_index)++]); + } + else + { + accel_data->x = 0; + } + + if (frame_header & BMA5_FIFO_ACC_Y_MSK) + { + /* Accel raw y data */ + accel_data->y = (int8_t)(fifo->data[(*data_start_index)++]); + } + else + { + accel_data->y = 0; + } + + if (frame_header & BMA5_FIFO_ACC_Z_MSK) + { + /* Accel raw z data */ + accel_data->z = (int8_t)(fifo->data[(*data_start_index)++]); + } + else + { + accel_data->z = 0; + } + + if (frame_header & BMA5_FIFO_SENS_TIME_EN_HDR_BYTE_MSK) + { + sens_time_data_xlsb = fifo->data[(*data_start_index)++]; + sens_time_data_lsb = fifo->data[(*data_start_index)++]; + sens_time_data_msb = fifo->data[(*data_start_index)++]; + + accel_data->sensor_time = (sens_time_data_xlsb | (sens_time_data_lsb << 8) | (sens_time_data_msb << 16)); + } + else + { + accel_data->sensor_time = 0; + } + } + else + { + result = BMA5_W_FIFO_PARTIAL_READ; + } + + if (frame_header == BMA5_FIFO_SENS_TIME_EN_DEDI_FRM) + { + sens_time_data_xlsb = fifo->data[(*data_start_index)++]; + sens_time_data_lsb = fifo->data[(*data_start_index)++]; + sens_time_data_msb = fifo->data[(*data_start_index)++]; + + accel_data->sensor_time = (sens_time_data_xlsb | (sens_time_data_lsb << 8) | (sens_time_data_msb << 16)); + } + + return result; +} + +/*! + * @brief This internal API is used to unpack the accelerometer data from the + * FIFO 16 bit data and store it in the instance of the structure bma5_sens_fifo_axes_data_16_bit. + */ +static int8_t unpack_accel_sensor_time_16_bit_data(uint8_t frame_header, + struct bma5_sens_fifo_axes_data_16_bit *accel_data, + uint16_t *data_start_index, + const struct bma5_fifo_frame *fifo) +{ + /* Variable to store the function result */ + int8_t result = BMA5_OK; + + /* Variable to store accel data LSB and MSB values */ + uint16_t data_lsb, data_msb; + + /* Variable to store sensor time */ + uint32_t sens_time_data_xlsb, sens_time_data_lsb, sens_time_data_msb; + + if ((((*data_start_index) + BMA5_FIFO_16_BIT_ACCEL_XYZ_DATA) <= fifo->fifo_avail_len) && + (frame_header != BMA5_FIFO_SENS_TIME_EN_DEDI_FRM)) + { + if (frame_header & BMA5_FIFO_ACC_X_MSK) + { + /* Accel raw x data */ + data_lsb = fifo->data[(*data_start_index)++]; + data_msb = fifo->data[(*data_start_index)++]; + accel_data->x = (int16_t)((data_msb << 8) | data_lsb); + } + else + { + accel_data->x = 0; + } + + if (frame_header & BMA5_FIFO_ACC_Y_MSK) + { + /* Accel raw y data */ + data_lsb = fifo->data[(*data_start_index)++]; + data_msb = fifo->data[(*data_start_index)++]; + accel_data->y = (int16_t)((data_msb << 8) | data_lsb); + } + else + { + accel_data->y = 0; + } + + if (frame_header & BMA5_FIFO_ACC_Z_MSK) + { + /* Accel raw z data */ + data_lsb = fifo->data[(*data_start_index)++]; + data_msb = fifo->data[(*data_start_index)++]; + accel_data->z = (int16_t)((data_msb << 8) | data_lsb); + } + else + { + accel_data->z = 0; + } + + if (frame_header & BMA5_FIFO_SENS_TIME_EN_HDR_BYTE_MSK) + { + sens_time_data_xlsb = fifo->data[(*data_start_index)++]; + sens_time_data_lsb = fifo->data[(*data_start_index)++]; + sens_time_data_msb = fifo->data[(*data_start_index)++]; + + accel_data->sensor_time = (sens_time_data_xlsb | (sens_time_data_lsb << 8) | (sens_time_data_msb << 16)); + } + else + { + accel_data->sensor_time = 0; + } + } + else + { + result = BMA5_W_FIFO_PARTIAL_READ; + } + + if (frame_header == BMA5_FIFO_SENS_TIME_EN_DEDI_FRM) + { + sens_time_data_xlsb = fifo->data[(*data_start_index)++]; + sens_time_data_lsb = fifo->data[(*data_start_index)++]; + sens_time_data_msb = fifo->data[(*data_start_index)++]; + + accel_data->sensor_time = (sens_time_data_xlsb | (sens_time_data_lsb << 8) | (sens_time_data_msb << 16)); + } + + return result; +} + +/*! + * @brief This API reads the FIFO fill level which is set + * in the sensor. + */ +static int8_t get_fifo_fill_level(uint16_t *fifo_fill_lvl, struct bma5_dev *dev) +{ + /* Variable to define error */ + int8_t result = BMA5_OK; + + /* Array to store FIFO fill level */ + uint8_t data[2] = { 0, 0 }; + + if (fifo_fill_lvl == NULL) + { + result = BMA5_E_NULL_PTR; + } + else + { + /* Read the FIFO fill level */ + result = bma5_get_regs(BMA5_REG_FIFO_LEVEL_0, data, 2, dev); + + if (result == BMA5_OK) + { + *fifo_fill_lvl = ((uint16_t)(data[1] << 8)) | (data[0]); + + if (*fifo_fill_lvl == 0) + { + result = BMA5_W_FIFO_EMPTY; + } + } + } + + return result; +} diff --git a/bma5.h b/bma5.h new file mode 100644 index 0000000..d87dfe3 --- /dev/null +++ b/bma5.h @@ -0,0 +1,1079 @@ +/** +* Copyright (c) 2024 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 bma5.h +* @date 2024-04-15 +* @version v4.1.0 +* +*/ + +#ifndef _BMA5_H +#define _BMA5_H + +/*! CPP guard */ +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************/ +/****************************** Header files **********************************/ +/******************************************************************************/ +#include "bma5_defs.h" + +/******************************************************************************/ +/********************** Function prototype declarations ***********************/ +/******************************************************************************/ + +/** + * \ingroup bma5 + * \defgroup bma5ApiRegs BMA5 Registers + * @brief Set / Get data from the given register address of the sensor + */ + +/*! + * \ingroup bma5ApiRegs + * \page bma5_api_bma5_set_regs bma5_set_regs + * \code + * int8_t bma5_set_regs(uint8_t addr, const uint8_t *data, uint32_t len, struct bma5_dev *dev); + * \endcode + * @details This API writes data to the given register address of bma5 + * sensor. + * + * @param[in] addr : Register address to which the data is written. + * @param[in] data : Pointer to data buffer in which data to be written is stored. + * @param[in] len : No. of bytes of data to be written. + * @param[in] dev : Structure instance of bma5_dev. + * + * @return Result of API execution status + * + * @retval = 0 -> Success + * @retval > 0 -> Warning + * @retval < 0 -> Error + */ +int8_t bma5_set_regs(uint8_t addr, const uint8_t *data, uint32_t len, struct bma5_dev *dev); + +/*! + * \ingroup bma5ApiRegs + * \page bma5_api_bma5_get_regs bma5_get_regs + * \code + * int8_t bma5_get_regs(uint8_t addr, uint8_t *data, uint32_t len, struct bma5_dev *dev); + * \endcode + * @details This API reads the data from the given register address of bma5 + * sensor. + * + * @param[in] addr : Register address from which data is read. + * @param[out] data : Pointer to data buffer where read data is stored. + * @param[in] len : No. of bytes of data to be read. + * @param[in] dev : Structure instance of bma5_dev. + * + * @return Result of API execution status + * + * @retval = 0 -> Success + * @retval > 0 -> Warning + * @retval < 0 -> Error + */ +int8_t bma5_get_regs(uint8_t addr, uint8_t *data, uint32_t len, struct bma5_dev *dev); + +/*! + * \ingroup bma5ApiRegs + * \page bma5_api_bma5_get_health_status bma5_get_health_status + * \code + * int8_t bma5_get_health_status(uint8_t *sensor_health_status, struct bma5_dev *dev); + * \endcode + * @details This API carries the provision to get the This register contains internal health status information + * + * @param[out] sensor_health_status : The value 0xF indicate a good internal health state. + * @param[in] dev : Structure instance of bma5_dev. + * + * @return Result of API execution status + * + * @retval = 0 -> Success + * @retval > 0 -> Warning + * @retval < 0 -> Error + */ +int8_t bma5_get_health_status(uint8_t *sensor_health_status, struct bma5_dev *dev); + +/*! + * \ingroup bma5ApiRegs + * \page bma5_api_bma5_get_cmd_suspend bma5_get_cmd_suspend + * \code + * int8_t bma5_get_cmd_suspend(uint8_t *suspend, struct bma5_dev *dev); + * \endcode + * @details This API carries the provision to get the Command register to activate suspend mode. + * + * @param[out] suspend : Write '1' to activate suspend mode. The register content prior to entering this power mode will NOT be lost. + * @param[in] dev : Structure instance of bma5_dev. + * + * @return Result of API execution status + * + * @retval = 0 -> Success + * @retval > 0 -> Warning + * @retval < 0 -> Error + */ +int8_t bma5_get_cmd_suspend(uint8_t *suspend, struct bma5_dev *dev); + +/*! + * \ingroup bma5ApiRegs + * \page bma5_api_bma5_get_cmd_suspend bma5_get_cmd_suspend + * \code + * int8_t bma5_set_cmd_suspend(const uint8_t suspend, struct bma5_dev *dev); + * \endcode + * @details This API carries the provision to set the Command register to activate suspend mode. + * + * @param[in] suspend : Write '1' to activate suspend mode. The register content prior to entering this power mode will NOT be lost. + * @param[in] dev : Structure instance of bma5_dev. + * + * @return Result of API execution status + * + * @retval = 0 -> Success + * @retval > 0 -> Warning + * @retval < 0 -> Error + */ +int8_t bma5_set_cmd_suspend(const uint8_t suspend, struct bma5_dev *dev); + +/*! + * \ingroup bma5ApiRegs + * \page bma5_api_bma5_get_config_status bma5_get_config_status + * \code + * int8_t bma5_get_config_status(struct bma5_config_status *config, struct bma5_dev *dev); + * \endcode + * @details This API carries the provision to get the Global error flags + * + * @param[out] config : Structure instance of bma5_config_status + * @param[in] dev : Structure instance of bma5_dev. + * + * @return Result of API execution status + * + * @retval = 0 -> Success + * @retval > 0 -> Warning + * @retval < 0 -> Error + */ +int8_t bma5_get_config_status(struct bma5_config_status *config, struct bma5_dev *dev); + +/*! + * \ingroup bma5ApiRegs + * \page bma5_api_bma5_get_config_status bma5_get_config_status + * \code + * int8_t bma5_set_config_status(const struct bma5_config_status *config, struct bma5_dev *dev); + * \endcode + * @details This API carries the provision to set the Global error flags + * + * @param[in] config : Structure instance of bma5_config_status + * @param[in] dev : Structure instance of bma5_dev. + * + * @return Result of API execution status + * + * @retval = 0 -> Success + * @retval > 0 -> Warning + * @retval < 0 -> Error + */ +int8_t bma5_set_config_status(const struct bma5_config_status *config, struct bma5_dev *dev); + +/*! + * \ingroup bma5ApiRegs + * \page bma5_api_bma5_get_sensor_status bma5_get_sensor_status + * \code + * int8_t bma5_get_sensor_status(struct bma5_sensor_status *config, struct bma5_dev *dev); + * \endcode + * @details This API carries the provision to get the Global status flags + * + * @param[out] config : Structure instance of bma5_sensor_status + * @param[in] dev : Structure instance of bma5_dev. + * + * @return Result of API execution status + * + * @retval = 0 -> Success + * @retval > 0 -> Warning + * @retval < 0 -> Error + */ +int8_t bma5_get_sensor_status(struct bma5_sensor_status *config, struct bma5_dev *dev); + +/*! + * \ingroup bma5ApiRegs + * \page bma5_api_bma5_get_sensor_status bma5_get_sensor_status + * \code + * int8_t bma5_set_sensor_status(const struct bma5_sensor_status *config, struct bma5_dev *dev); + * \endcode + * @details This API carries the provision to set the Global status flags + * + * @param[in] config : Structure instance of bma5_sensor_status + * @param[in] dev : Structure instance of bma5_dev. + * + * @return Result of API execution status + * + * @retval = 0 -> Success + * @retval > 0 -> Warning + * @retval < 0 -> Error + */ +int8_t bma5_set_sensor_status(const struct bma5_sensor_status *config, struct bma5_dev *dev); + +/*! + * \ingroup bma5ApiRegs + * \page bma5_api_bma5_get_temp_data bma5_get_temp_data + * \code + * int8_t bma5_get_temp_data(uint8_t *temp_data, struct bma5_dev *dev); + * \endcode + * @details This API carries the provision to get the Temperature data register + * + * @param[out] temp_data : Calculated temperature. Resolution: 1 K/LSB. The value 0 represents 23°C. + * @param[in] dev : Structure instance of bma5_dev. + * + * @return Result of API execution status + * + * @retval = 0 -> Success + * @retval > 0 -> Warning + * @retval < 0 -> Error + */ +int8_t bma5_get_temp_data(uint8_t *temp_data, struct bma5_dev *dev); + +/*! + * \ingroup bma5ApiRegs + * \page bma5_api_bma5_get_fifo_data_out bma5_get_fifo_data_out + * \code + * int8_t bma5_get_fifo_data_out(uint8_t *fifo_data_out, struct bma5_dev *dev); + * \endcode + * @details This API carries the provision to get the FIFO data register + * + * @param[out] fifo_data_out : Output of the FIFO. During burst reads on this address + * the address increment stops and the FIFO can be read out with help of the burst read. + * The type of data stored in the FIFO depends on configuration stored in FIFO_CONF_* registers. + * @param[in] dev : Structure instance of bma5_dev. + * + * @return Result of API execution status + * + * @retval = 0 -> Success + * @retval > 0 -> Warning + * @retval < 0 -> Error + */ +int8_t bma5_get_fifo_data_out(uint8_t *fifo_data_out, struct bma5_dev *dev); + +/*! + * \ingroup bma5ApiRegs + * \page bma5_api_bma5_get_acc_conf_0 bma5_get_acc_conf_0 + * \code + * int8_t bma5_get_acc_conf_0(uint8_t *sensor_ctrl, struct bma5_dev *dev); + * \endcode + * @details This API carries the provision to get the Accelerometer configuration register 0 + * + * @param[out] sensor_ctrl : This bit enables/disables the accelerometer and the temperature sensor. + * @param[in] dev : Structure instance of bma5_dev. + * + * @return Result of API execution status + * + * @retval = 0 -> Success + * @retval > 0 -> Warning + * @retval < 0 -> Error + */ +int8_t bma5_get_acc_conf_0(uint8_t *sensor_ctrl, struct bma5_dev *dev); + +/*! + * \ingroup bma5ApiRegs + * \page bma5_api_bma5_get_acc_conf_0 bma5_get_acc_conf_0 + * \code + * int8_t bma5_set_acc_conf_0(const uint8_t sensor_ctrl, struct bma5_dev *dev); + * \endcode + * @details This API carries the provision to set the Accelerometer configuration register 0 + * + * @param[in] sensor_ctrl : This bit enables/disables the accelerometer and the temperature sensor. + * @param[in] dev : Structure instance of bma5_dev. + * + * @return Result of API execution status + * + * @retval = 0 -> Success + * @retval > 0 -> Warning + * @retval < 0 -> Error + */ +int8_t bma5_set_acc_conf_0(const uint8_t sensor_ctrl, struct bma5_dev *dev); + +/*! + * \ingroup bma5ApiRegs + * \page bma5_api_bma5_get_acc_conf bma5_get_acc_conf + * \code + * int8_t bma5_get_acc_conf(struct bma5_acc_conf *config, struct bma5_dev *dev); + * \endcode + * @details This API carries the provision to get the Accelerometer configuration register + * + * @param[out] config : Structure instance of bma5_acc_conf + * @param[in] dev : Structure instance of bma5_dev. + * + * @return Result of API execution status + * + * @retval = 0 -> Success + * @retval > 0 -> Warning + * @retval < 0 -> Error + */ +int8_t bma5_get_acc_conf(struct bma5_acc_conf *config, struct bma5_dev *dev); + +/*! + * \ingroup bma5ApiRegs + * \page bma5_api_bma5_set_acc_conf bma5_get_acc_conf + * \code + * int8_t bma5_set_acc_conf(const struct bma5_acc_conf *config, struct bma5_dev *dev); + * \endcode + * @details This API carries the provision to set the Accelerometer configuration register + * + * @param[in] config : Structure instance of bma5_acc_conf + * @param[in] dev : Structure instance of bma5_dev. + * + * @return Result of API execution status + * + * @retval = 0 -> Success + * @retval > 0 -> Warning + * @retval < 0 -> Error + */ +int8_t bma5_set_acc_conf(const struct bma5_acc_conf *config, struct bma5_dev *dev); + +/*! + * \ingroup bma5ApiRegs + * \page bma5_api_bma5_get_temp_conf bma5_get_temp_conf + * \code + * int8_t bma5_get_temp_conf(struct bma5_temp_conf *config, struct bma5_dev *dev); + * \endcode + * @details This API carries the provision to get the Temperature Sensor configuration register + * + * @param[out] config : Structure instance of bma5_temp_conf + * @param[in] dev : Structure instance of bma5_dev. + * + * @return Result of API execution status + * + * @retval = 0 -> Success + * @retval > 0 -> Warning + * @retval < 0 -> Error + */ +int8_t bma5_get_temp_conf(struct bma5_temp_conf *config, struct bma5_dev *dev); + +/*! + * \ingroup bma5ApiRegs + * \page bma5_api_bma5_get_temp_conf bma5_get_temp_conf + * \code + * int8_t bma5_set_temp_conf(const struct bma5_temp_conf *config, struct bma5_dev *dev); + * \endcode + * @details This API carries the provision to set the Temperature Sensor configuration register + * + * @param[in] config : Structure instance of bma5_temp_conf + * @param[in] dev : Structure instance of bma5_dev. + * + * @return Result of API execution status + * + * @retval = 0 -> Success + * @retval > 0 -> Warning + * @retval < 0 -> Error + */ +int8_t bma5_set_temp_conf(const struct bma5_temp_conf *config, struct bma5_dev *dev); + +/*! + * \ingroup bma5ApiRegs + * \page bma5_api_bma5_get_int_conf bma5_get_int_conf + * \code + * int8_t bma5_get_int_conf(struct bma5_int_conf_types *config, uint8_t int_configs, struct bma5_dev *dev); + * \endcode + * @details This API carries the provision to get the Configuration register for INT2 + * + * @param[out] config : Structure instance of bma5_int_conf + * @param[in] int_configs : Number of interrupts configurations to get. + * @param[in] dev : Structure instance of bma5_dev. + * + * @return Result of API execution status + * + * @retval = 0 -> Success + * @retval > 0 -> Warning + * @retval < 0 -> Error + */ +int8_t bma5_get_int_conf(struct bma5_int_conf_types *config, uint8_t int_configs, struct bma5_dev *dev); + +/*! + * \ingroup bma5ApiRegs + * \page bma5_api_bma5_get_int_conf bma5_get_int_conf + * \code + * int8_t bma5_set_int_conf(const struct bma5_int_conf_types *config, uint8_t int_configs, struct bma5_dev *dev); + * \endcode + * @details This API carries the provision to set the Configuration register for INT2 + * + * @param[in] config : Structure instance of bma5_int_conf + * @param[in] int_configs : Number of interrupts configurations to set. + * @param[in] dev : Structure instance of bma5_dev. + * + * @return Result of API execution status + * + * @retval = 0 -> Success + * @retval > 0 -> Warning + * @retval < 0 -> Error + */ +int8_t bma5_set_int_conf(const struct bma5_int_conf_types *config, uint8_t int_configs, struct bma5_dev *dev); + +/*! + * \ingroup bma5ApiRegs + * \page bma5_api_bma5_get_if_conf_0 bma5_get_if_conf_0 + * \code + * int8_t bma5_get_if_conf_0(uint8_t *if_i2c_slv_addr, struct bma5_dev *dev); + * \endcode + * @details This API carries the provision to get the Serial interface settings + * + * @param[out] if_i2c_slv_addr : I2C slave address of this device. + * @param[in] dev : Structure instance of bma5_dev. + * + * @return Result of API execution status + * + * @retval = 0 -> Success + * @retval > 0 -> Warning + * @retval < 0 -> Error + */ +int8_t bma5_get_if_conf_0(uint8_t *if_i2c_slv_addr, struct bma5_dev *dev); + +/*! + * \ingroup bma5ApiRegs + * \page bma5_api_bma5_get_if_conf bma5_get_if_conf + * \code + * int8_t bma5_get_if_conf(struct bma5_if_conf *config, struct bma5_dev *dev); + * \endcode + * @details This API carries the provision to get the Serial interface settings + * + * @param[out] config : Structure instance of bma5_if_conf + * @param[in] dev : Structure instance of bma5_dev. + * + * @return Result of API execution status + * + * @retval = 0 -> Success + * @retval > 0 -> Warning + * @retval < 0 -> Error + */ +int8_t bma5_get_if_conf(struct bma5_if_conf *config, struct bma5_dev *dev); + +/*! + * \ingroup bma5ApiRegs + * \page bma5_api_bma5_get_if_conf bma5_get_if_conf + * \code + * int8_t bma5_set_if_conf(const struct bma5_if_conf *config, struct bma5_dev *dev); + * \endcode + * @details This API carries the provision to set the Serial interface settings + * + * @param[in] config : Structure instance of bma5_if_conf + * @param[in] dev : Structure instance of bma5_dev. + * + * @return Result of API execution status + * + * @retval = 0 -> Success + * @retval > 0 -> Warning + * @retval < 0 -> Error + */ +int8_t bma5_set_if_conf(const struct bma5_if_conf *config, struct bma5_dev *dev); + +/*! + * \ingroup bma5ApiRegs + * \page bma5_api_bma5_get_fifo_ctrl bma5_get_fifo_ctrl + * \code + * int8_t bma5_set_fifo_ctrl(const struct bma5_fifo_ctrl *config, struct bma5_dev *dev); + * \endcode + * @details This API carries the provision to set the FIFO control register + * + * @param[in] config : Structure instance of bma5_fifo_ctrl + * @param[in] dev : Structure instance of bma5_dev. + * + * @return Result of API execution status + * + * @retval = 0 -> Success + * @retval > 0 -> Warning + * @retval < 0 -> Error + */ +int8_t bma5_set_fifo_ctrl(const struct bma5_fifo_ctrl *config, struct bma5_dev *dev); + +/*! + * \ingroup bma5ApiRegs + * \page bma5_api_bma5_get_fifo_conf bma5_get_fifo_conf + * \code + * int8_t bma5_get_fifo_conf(struct bma5_fifo_conf *config, struct bma5_dev *dev); + * \endcode + * @details This API carries the provision to get the FIFO configuration register + * + * @param[out] config : Structure instance of bma5_fifo_conf + * @param[in] dev : Structure instance of bma5_dev. + * + * @return Result of API execution status + * + * @retval = 0 -> Success + * @retval > 0 -> Warning + * @retval < 0 -> Error + */ +int8_t bma5_get_fifo_conf(struct bma5_fifo_conf *config, struct bma5_dev *dev); + +/*! + * \ingroup bma5ApiRegs + * \page bma5_api_bma5_get_fifo_conf bma5_get_fifo_conf + * \code + * int8_t bma5_set_fifo_conf(const struct bma5_fifo_conf *config, struct bma5_dev *dev); + * \endcode + * @details This API carries the provision to set the FIFO configuration register + * + * @param[in] config : Structure instance of bma5_fifo_conf + * @param[in] dev : Structure instance of bma5_dev. + * + * @return Result of API execution status + * + * @retval = 0 -> Success + * @retval > 0 -> Warning + * @retval < 0 -> Error + */ +int8_t bma5_set_fifo_conf(const struct bma5_fifo_conf *config, struct bma5_dev *dev); + +/*! + * \ingroup bma5ApiRegs + * \page bma5_api_bma5_get_feat_eng_conf bma5_get_feat_eng_conf + * \code + * int8_t bma5_get_feat_eng_conf(uint8_t *feat_eng_ctrl, struct bma5_dev *dev); + * \endcode + * @details This API carries the provision to get the feature engine ('feat_eng') configuration register + * + * @param[out] feat_eng_ctrl : An enable/disable switch for the feature engine. The feature engine is internally reseted, once the engine is disabled and the enabled again. + * @param[in] dev : Structure instance of bma5_dev. + * + * @return Result of API execution status + * + * @retval = 0 -> Success + * @retval > 0 -> Warning + * @retval < 0 -> Error + */ +int8_t bma5_get_feat_eng_conf(uint8_t *feat_eng_ctrl, struct bma5_dev *dev); + +/*! + * \ingroup bma5ApiRegs + * \page bma5_api_bma5_get_feat_eng_conf bma5_get_feat_eng_conf + * \code + * int8_t bma5_set_feat_eng_conf(const uint8_t feat_eng_ctrl, struct bma5_dev *dev); + * \endcode + * @details This API carries the provision to set the feature engine ('feat_eng') configuration register + * + * @param[in] feat_eng_ctrl : An enable/disable switch for the feature engine. The feature engine is internally reseted, once the engine is disabled and the enabled again. + * @param[in] dev : Structure instance of bma5_dev. + * + * @return Result of API execution status + * + * @retval = 0 -> Success + * @retval > 0 -> Warning + * @retval < 0 -> Error + */ +int8_t bma5_set_feat_eng_conf(const uint8_t feat_eng_ctrl, struct bma5_dev *dev); + +/*! + * \ingroup bma5ApiRegs + * \page bma5_api_bma5_get_feat_eng_status bma5_get_feat_eng_status + * \code + * int8_t bma5_get_feat_eng_status(struct bma5_feat_eng_status *config, struct bma5_dev *dev); + * \endcode + * @details This API carries the provision to get the feature engine ('feat_eng') status register + * + * @param[out] config : Structure instance of bma5_feat_eng_status + * @param[in] dev : Structure instance of bma5_dev. + * + * @return Result of API execution status + * + * @retval = 0 -> Success + * @retval > 0 -> Warning + * @retval < 0 -> Error + */ +int8_t bma5_get_feat_eng_status(struct bma5_feat_eng_status *config, struct bma5_dev *dev); + +/*! + * \ingroup bma5ApiRegs + * \page bma5_api_bma5_get_feat_eng_gpr_conf bma5_get_feat_eng_gpr_conf + * \code + * int8_t bma5_get_feat_eng_gpr_conf(struct bma5_feat_eng_gpr_conf *config, struct bma5_dev *dev); + * \endcode + * @details This API carries the provision to get the feature engine ('feat_eng') general purpose register configuration register + * + * @param[out] config : Structure instance of bma5_feat_eng_gpr_conf + * @param[in] dev : Structure instance of bma5_dev. + * + * @return Result of API execution status + * + * @retval = 0 -> Success + * @retval > 0 -> Warning + * @retval < 0 -> Error + */ +int8_t bma5_get_feat_eng_gpr_conf(struct bma5_feat_eng_gpr_conf *config, struct bma5_dev *dev); + +/*! + * \ingroup bma5ApiRegs + * \page bma5_api_bma5_get_feat_eng_gpr_conf bma5_get_feat_eng_gpr_conf + * \code + * int8_t bma5_set_feat_eng_gpr_conf(const struct bma5_feat_eng_gpr_conf *config, struct bma5_dev *dev); + * \endcode + * @details This API carries the provision to set the feature engine ('feat_eng') general purpose register configuration register + * + * @param[in] config : Structure instance of bma5_feat_eng_gpr_conf + * @param[in] dev : Structure instance of bma5_dev. + * + * @return Result of API execution status + * + * @retval = 0 -> Success + * @retval > 0 -> Warning + * @retval < 0 -> Error + */ +int8_t bma5_set_feat_eng_gpr_conf(const struct bma5_feat_eng_gpr_conf *config, struct bma5_dev *dev); + +/*! + * \ingroup bma5ApiRegs + * \page bma5_api_bma5_get_feat_eng_gpr_ctrl bma5_get_feat_eng_gpr_ctrl + * \code + * int8_t bma5_set_feat_eng_gpr_ctrl(const struct bma5_feat_eng_gpr_ctrl *config, struct bma5_dev *dev); + * \endcode + * @details This API carries the provision to set the feature engine ('feat_eng') general purpose register control register + * + * @param[in] config : Structure instance of bma5_feat_eng_gpr_ctrl + * @param[in] dev : Structure instance of bma5_dev. + * + * @return Result of API execution status + * + * @retval = 0 -> Success + * @retval > 0 -> Warning + * @retval < 0 -> Error + */ +int8_t bma5_set_feat_eng_gpr_ctrl(const struct bma5_feat_eng_gpr_ctrl *config, struct bma5_dev *dev); + +/*! + * \ingroup bma5ApiRegs + * \page bma5_api_bma5_get_feature_data_addr bma5_get_feature_data_addr + * \code + * int8_t bma5_get_feature_data_addr(uint8_t *feature_data_addr, struct bma5_dev *dev); + * \endcode + * @details This API carries the provision to get the feature engine ('feat_eng') feature data start address + * + * @param[out] feature_data_addr : Feature data address. For the address values see the extended memory map. + * @param[in] dev : Structure instance of bma5_dev. + * + * @return Result of API execution status + * + * @retval = 0 -> Success + * @retval > 0 -> Warning + * @retval < 0 -> Error + */ +int8_t bma5_get_feature_data_addr(uint8_t *feature_data_addr, struct bma5_dev *dev); + +/*! + * \ingroup bma5ApiRegs + * \page bma5_api_bma5_get_feature_data_addr bma5_get_feature_data_addr + * \code + * int8_t bma5_set_feature_data_addr(const uint8_t feature_data_addr, struct bma5_dev *dev); + * \endcode + * @details This API carries the provision to set the feature engine ('feat_eng') feature data start address + * + * @param[in] feature_data_addr : Feature data address. For the address values see the extended memory map. + * @param[in] dev : Structure instance of bma5_dev. + * + * @return Result of API execution status + * + * @retval = 0 -> Success + * @retval > 0 -> Warning + * @retval < 0 -> Error + */ +int8_t bma5_set_feature_data_addr(const uint8_t feature_data_addr, struct bma5_dev *dev); + +/*! + * \ingroup bma5ApiRegs + * \page bma5_api_bma5_get_feature_data_tx bma5_get_feature_data_tx + * \code + * int8_t bma5_get_feature_data_tx(uint8_t *feature_data, struct bma5_dev *dev); + * \endcode + * @details This API carries the provision to get the feature engine ('feat_eng') feature data + * + * @param[out] feature_data : The data port associated with feature_data_addr. + * During burst read/write operations on this address + * the address increment stops and the burst operation can be used to + * read/write multiple feature_data words. See the extendend memory map for details. + * @param[in] dev : Structure instance of bma5_dev. + * + * @return Result of API execution status + * + * @retval = 0 -> Success + * @retval > 0 -> Warning + * @retval < 0 -> Error + */ +int8_t bma5_get_feature_data_tx(uint8_t *feature_data, struct bma5_dev *dev); + +/*! + * \ingroup bma5ApiRegs + * \page bma5_api_bma5_get_feature_data_tx bma5_get_feature_data_tx + * \code + * int8_t bma5_set_feature_data_tx(const uint8_t feature_data, struct bma5_dev *dev); + * \endcode + * @details This API carries the provision to set the feature engine ('feat_eng') feature data + * + * @param[in] feature_data : The data port associated with feature_data_addr. + * During burst read/write operations on this address + * the address increment stops and the burst operation can be used to + * read/write multiple feature_data words. See the extendend memory map for details. + * @param[in] dev : Structure instance of bma5_dev. + * + * @return Result of API execution status + * + * @retval = 0 -> Success + * @retval > 0 -> Warning + * @retval < 0 -> Error + */ +int8_t bma5_set_feature_data_tx(const uint8_t feature_data, struct bma5_dev *dev); + +/*! + * \ingroup bma5ApiRegs + * \page bma5_api_bma5_get_acc_self_test bma5_get_acc_self_test + * \code + * int8_t bma5_get_acc_self_test(struct bma5_acc_self_test *config, struct bma5_dev *dev); + * \endcode + * @details This API carries the provision to get the Select NORMAL/SELF_TEST mode and test data. If you write to this register, the ACC data path is reset. + * + * @param[out] config : Structure instance of bma5_acc_self_test + * @param[in] dev : Structure instance of bma5_dev. + * + * @return Result of API execution status + * + * @retval = 0 -> Success + * @retval > 0 -> Warning + * @retval < 0 -> Error + */ +int8_t bma5_get_acc_self_test(struct bma5_acc_self_test *config, struct bma5_dev *dev); + +/*! + * \ingroup bma5ApiRegs + * \page bma5_api_bma5_get_acc_self_test bma5_get_acc_self_test + * \code + * int8_t bma5_set_acc_self_test(const struct bma5_acc_self_test *config, struct bma5_dev *dev); + * \endcode + * @details This API carries the provision to set the Select NORMAL/SELF_TEST mode and test data. If you write to this register, the ACC data path is reset. + * + * @param[in] config : Structure instance of bma5_acc_self_test + * @param[in] dev : Structure instance of bma5_dev. + * + * @return Result of API execution status + * + * @retval = 0 -> Success + * @retval > 0 -> Warning + * @retval < 0 -> Error + */ +int8_t bma5_set_acc_self_test(const struct bma5_acc_self_test *config, struct bma5_dev *dev); + +/*! + * \ingroup bma5ApiRegs + * \page bma5_api_bma5_get_cmd bma5_get_cmd + * \code + * int8_t bma5_set_cmd(const uint8_t cmd, struct bma5_dev *dev); + * \endcode + * @details This API carries the provision to set the Command Register + * + * @param[in] cmd : Available commands (Note: Register will always read as 0x00): + * @param[in] dev : Structure instance of bma5_dev. + * + * @return Result of API execution status + * + * @retval = 0 -> Success + * @retval > 0 -> Warning + * @retval < 0 -> Error + */ +int8_t bma5_set_cmd(const uint8_t cmd, struct bma5_dev *dev); + +/*! + * \ingroup bma5ApiRegs + * \page bma5_api_bma5_get_acc bma5_get_acc + * \code + * int8_t bma5_get_acc(struct bma5_accel *accel, struct bma5_dev *dev); + * \endcode + * @details This API carries the provision to get the acceleration data + * + * @param[out] acc : acceleration data. + * @param[in] dev : Structure instance of bma5_dev. + * + * @return Result of API execution status + * + * @retval = 0 -> Success + * @retval > 0 -> Warning + * @retval < 0 -> Error + */ +int8_t bma5_get_acc(struct bma5_accel *accel, struct bma5_dev *dev); + +/*! + * \ingroup bma5ApiRegs + * \page bma5_api_bma5_get_sensor_time bma5_get_sensor_time + * \code + * int8_t bma5_get_sensor_time(uint32_t *sensor_time, struct bma5_dev *dev); + * \endcode + * @details This API carries the provision to get the the sensor time + * + * @param[out] sensor_time : the sensor time + * @param[in] dev : Structure instance of bma5_dev. + * + * @return Result of API execution status + * + * @retval = 0 -> Success + * @retval > 0 -> Warning + * @retval < 0 -> Error + */ +int8_t bma5_get_sensor_time(uint32_t *sensor_time, struct bma5_dev *dev); + +/*! + * \ingroup bma5ApiRegs + * \page bma5_api_bma5_get_fifo_fill_level bma5_get_fifo_fill_level + * \code + * int8_t bma5_get_fifo_fill_level(uint16_t *fifo_fill_level, struct bma5_dev *dev); + * \endcode + * @details This API carries the provision to get the FIFO fill level + * + * @param[out] fifo_fill_level : FIFO fill level + * @param[in] dev : Structure instance of bma5_dev. + * + * @return Result of API execution status + * + * @retval = 0 -> Success + * @retval > 0 -> Warning + * @retval < 0 -> Error + */ +int8_t bma5_get_fifo_fill_level(uint16_t *fifo_fill_level, struct bma5_dev *dev); + +/*! + * \ingroup bma5ApiRegs + * \page bma5_api_bma5_get_fifo_wm bma5_get_fifo_wm + * \code + * int8_t bma5_get_fifo_wm(uint16_t *fifo_wm, struct bma5_dev *dev); + * \endcode + * @details This API carries the provision to get the FIFO watermark level + * + * @param[out] fifo_wm : FIFO watermark level + * @param[in] dev : Structure instance of bma5_dev. + * + * @return Result of API execution status + * + * @retval = 0 -> Success + * @retval > 0 -> Warning + * @retval < 0 -> Error + */ +int8_t bma5_get_fifo_wm(uint16_t *fifo_wm, struct bma5_dev *dev); + +/*! + * \ingroup bma5ApiRegs + * \page bma5_api_bma5_set_fifo_wm bma5_set_fifo_wm + * \code + * int8_t bma5_set_fifo_wm(uint16_t fifo_wm, struct bma5_dev *dev); + * \endcode + * @details This API carries the provision to set the FIFO watermark level + * + * @param[in] fifo_wm : FIFO watermark level + * @param[in] dev : Structure instance of bma5_dev. + * + * @return Result of API execution status + * + * @retval = 0 -> Success + * @retval > 0 -> Warning + * @retval < 0 -> Error + */ +int8_t bma5_set_fifo_wm(uint16_t fifo_wm, struct bma5_dev *dev); + +/*! + * \ingroup bma5ApiRegs + * \page bma5_api_bma5_set_acc_doff bma5_set_acc_doff + * \code + * int8_t bma5_set_acc_doff(struct bma5_accel_doff *accel_doff, struct bma5_dev *dev); + * \endcode + * @details This API carries the provision to get the acceleration doff data + * + * @param[out] accel_doff : acceleration doff data. + * @param[in] dev : Structure instance of bma5_dev. + * + * @return Result of API execution status + * + * @retval = 0 -> Success + * @retval > 0 -> Warning + * @retval < 0 -> Error + */ +int8_t bma5_set_acc_doff(const struct bma5_accel_doff *accel_doff, struct bma5_dev *dev); + +/*! + * \ingroup bma5ApiRegs + * \page bma5_api_bma5_get_acc_doff bma5_get_acc_doff + * \code + * int8_t bma5_get_acc_doff(struct bma5_accel_doff *accel_doff, struct bma5_dev *dev); + * \endcode + * @details This API carries the provision to get the acceleration doff data + * + * @param[out] accel_doff : acceleration doff data. + * @param[in] dev : Structure instance of bma5_dev. + * + * @return Result of API execution status + * + * @retval = 0 -> Success + * @retval > 0 -> Warning + * @retval < 0 -> Error + */ +int8_t bma5_get_acc_doff(struct bma5_accel_doff *accel_doff, struct bma5_dev *dev); + +/** + * \ingroup bma5 + * \defgroup bma5Apist BMA5 Self-Test + * @brief Self-Test APIs + */ + +/*! + * \ingroup bma5Apist + * \page bma5_api_bma5_activate_self_test bma5_activate_self_test + * \code + * int8_t bma5_activate_self_test(struct bma5_dev *dev); + * \endcode + * @details This API is to activate self-test procedure + * + * @param[in,out] dev : Structure instance of bma5_dev + * + * @return Result of API execution status. + * @retval = 0 -> Success + * @retval > 0 -> Warning + * @retval < 0 -> Error + */ +int8_t bma5_activate_self_test(struct bma5_dev *dev); + +/*! + * \ingroup bma5Apist + * \page bma5_api_bma5_self_test_pos_excitation bma5_self_test_pos_excitation + * \code + * int8_t bma5_self_test_pos_excitation(struct bma5_dev *dev); + * \endcode + * @details This API is to perform self-test procedure with positive excitation + * + * @param[in,out] dev : Structure instance of bma5_dev + * + * @return Result of API execution status. + * @retval = 0 -> Success + * @retval > 0 -> Warning + * @retval < 0 -> Error + */ +int8_t bma5_self_test_pos_excitation(struct bma5_dev *dev); + +/*! + * \ingroup bma5Apist + * \page bma5_api_bma5_self_test_neg_excitation bma5_self_test_neg_excitation + * \code + * int8_t bma5_self_test_neg_excitation(struct bma5_dev *dev); + * \endcode + * @details This API is to perform self-test procedure with negative excitation + * + * @param[in,out] dev : Structure instance of bma5_dev + * + * @return Result of API execution status. + * @retval = 0 -> Success + * @retval > 0 -> Warning + * @retval < 0 -> Error + */ +int8_t bma5_self_test_neg_excitation(struct bma5_dev *dev); + +/** + * \ingroup bma5 + * \defgroup bma5FIFOApiRegs BMA5 FIFO + * @brief APIs for FIFO + */ + +/*! + * \ingroup bma5FIFOApiRegs + * \page bma5_api_bma5_read_fifo_data bma5_read_fifo_data + * \code + * int8_t bma5_read_fifo_data(struct bma5_fifo_frame *fifo, const struct bma5_fifo_conf *fifo_conf, + * struct bma5_dev *dev); + * \endcode + * @details This API reads the FIFO data from the sensor + * + * @param[in, out] fifo : Structure instance of bma5_fifo_frame. + * @param[in, out] fifo_conf : Structure instance of bma5_fifo_conf. + * @param[in,out] dev : Structure instance of bma5_dev. + * + * @return Result of API execution status + * + * @retval = 0 -> Success + * @retval > 0 -> Warning + * @retval < 0 -> Error + */ +int8_t bma5_read_fifo_data(struct bma5_fifo_frame *fifo, const struct bma5_fifo_conf *fifo_conf, struct bma5_dev *dev); + +/*! + * \ingroup bma5FIFOApiRegs + * \page bma5_api_bma5_extract_acc_sens_time_8_bit bma5_extract_acc_sens_time_8_bit + * \code + * int8_t bma5_extract_acc_sens_time_8_bit(struct bma5_sens_fifo_axes_data_8_bit *accel_data, + struct bma5_fifo_frame *fifo, + const struct bma5_fifo_conf *fifo_conf, + const struct bma5_dev *dev); + * \endcode + * @details This API parses and extracts the accelerometer and sensortime frames from + * FIFO 8 bit data read by the "bma5_read_fifo_data" API and stores it in the + * "bma5_sens_fifo_axes_data_8_bit" structure instance. + * + * @param[in] accel_data : Structure instance of bma5_sens_fifo_axes_data_8_bit. + * @param[in] fifo : Structure instance of bma5_fifo_frame. + * @param[in] fifo_conf : Structure instance of bma5_fifo_conf. + * @param[in] dev : Structure instance of bma5_dev. + * + * @return Result of API execution status + * + * @retval = 0 -> Success + * @retval > 0 -> Warning + * @retval < 0 -> Error + */ +int8_t bma5_extract_acc_sens_time_8_bit(struct bma5_sens_fifo_axes_data_8_bit *accel_data, + struct bma5_fifo_frame *fifo, + const struct bma5_fifo_conf *fifo_conf, + const struct bma5_dev *dev); + +/*! + * \ingroup bma5FIFOApiRegs + * \page bma5_api_bma5_extract_acc_sens_time_16_bit bma5_extract_acc_sens_time_16_bit + * \code + * int8_t bma5_extract_acc_sens_time_16_bit(struct bma5_sens_fifo_axes_data_16_bit *accel_data, + struct bma5_fifo_frame *fifo, + const struct bma5_fifo_conf *fifo_conf, + const struct bma5_dev *dev); + * \endcode + * @details This API parses and extracts the accelerometer and sensortime frames from + * FIFO 16 bit data read by the "bma5_read_fifo_data" API and stores it in the + * "bma5_sens_fifo_axes_data_16_bit" structure instance. + * + * @param[in] accel_data : Structure instance of bma5_sens_fifo_axes_data_16_bit. + * @param[in] fifo : Structure instance of bma5_fifo_frame. + * @param[in] fifo_conf : Structure instance of bma5_fifo_conf. + * @param[in] dev : Structure instance of bma5_dev. + * + * @return Result of API execution status + * + * @retval = 0 -> Success + * @retval > 0 -> Warning + * @retval < 0 -> Error + */ +int8_t bma5_extract_acc_sens_time_16_bit(struct bma5_sens_fifo_axes_data_16_bit *accel_data, + struct bma5_fifo_frame *fifo, + const struct bma5_fifo_conf *fifo_conf, + const struct bma5_dev *dev); + +#ifdef __cplusplus +} +#endif /* End of CPP guard */ + +#endif /*_BMA5_H */ diff --git a/bma530.c b/bma530.c new file mode 100644 index 0000000..73c575f --- /dev/null +++ b/bma530.c @@ -0,0 +1,609 @@ +/** +* Copyright (c) 2024 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 bma530.c +* @date 2024-04-15 +* @version v4.1.0 +* +*/ + +/******************************************************************************/ +/****************************** Header files **********************************/ +/******************************************************************************/ +#include "bma530.h" + +/******************************************************************************/ +/*********************** User function definitions ****************************/ +/******************************************************************************/ +int8_t bma530_get_chip_id(uint8_t *chip_id, struct bma5_dev *dev) +{ + /* Function execution status */ + int8_t result; + + /* Temporary variable to carry the register value */ + uint8_t reg_value; + + if (NULL == chip_id) + { + result = BMA5_E_NULL_PTR; + } + else + { + result = bma5_get_regs(BMA530_REG_CHIP_ID, ®_value, sizeof(reg_value), dev); + if (BMA5_OK == result) + { + /* Parse needed details from received serial data */ + *chip_id = BMA5_GET_BITS_POS_0(reg_value, BMA530_CHIP_ID); + } + } + + return result; +} + +int8_t bma530_get_int_status(struct bma530_int_status_types *config, uint8_t n_status, struct bma5_dev *dev) +{ + /* Function execution status */ + int8_t result = BMA5_OK; + uint8_t loop; + + /* Temporary variable to carry the register value */ + uint8_t reg_value[2] = { 0 }; + + if (NULL == config) + { + result = BMA5_E_NULL_PTR; + } + else + { + for (loop = 0; loop < n_status; loop++) + { + switch (config[loop].int_src) + { + case BMA530_INT_STATUS_INT1: + result = bma5_get_regs(BMA530_REG_INT_STATUS_INT1_0, reg_value, 2, dev); + break; + + case BMA530_INT_STATUS_INT2: + result = bma5_get_regs(BMA530_REG_INT_STATUS_INT2_0, reg_value, 2, dev); + break; + + case BMA530_INT_STATUS_I3C: + result = bma5_get_regs(BMA530_REG_INT_STATUS_I3C_0, reg_value, 2, dev); + break; + + default: + result = BMA5_E_INVALID_INT_STATUS; + break; + } + + if (BMA5_OK != result) + { + break; + } + + /* Parse needed details from received serial data */ + config[loop].int_status.acc_drdy_int_status = BMA5_GET_BITS_POS_0(reg_value[0], BMA530_ACC_DRDY_INT_STATUS); + config[loop].int_status.fifo_wm_int_status = BMA5_GET_BITS(reg_value[0], BMA530_FIFO_WM_INT_STATUS); + config[loop].int_status.fifo_full_int_status = BMA5_GET_BITS(reg_value[0], BMA530_FIFO_FULL_INT_STATUS); + config[loop].int_status.gen_int1_int_status = BMA5_GET_BITS(reg_value[0], BMA530_GEN_INT1_INT_STATUS); + config[loop].int_status.gen_int2_int_status = BMA5_GET_BITS(reg_value[0], BMA530_GEN_INT2_INT_STATUS); + config[loop].int_status.gen_int3_int_status = BMA5_GET_BITS(reg_value[0], BMA530_GEN_INT3_INT_STATUS); + config[loop].int_status.step_det_int_status = BMA5_GET_BITS(reg_value[0], BMA530_STEP_DET_INT_STATUS); + config[loop].int_status.step_cnt_int_status = BMA5_GET_BITS(reg_value[0], BMA530_STEP_CNT_INT_STATUS); + + config[loop].int_status.sig_mo_int_status = BMA5_GET_BITS_POS_0(reg_value[1], BMA530_SIG_MO_INT_STATUS); + config[loop].int_status.tilt_int_status = BMA5_GET_BITS(reg_value[1], BMA530_TILT_INT_STATUS); + config[loop].int_status.orient_int_status = BMA5_GET_BITS(reg_value[1], BMA530_ORIENT_INT_STATUS); + config[loop].int_status.acc_foc_int_status = BMA5_GET_BITS(reg_value[1], BMA530_ACC_FOC_INT_STATUS); + config[loop].int_status.feat_eng_err_int_status = + BMA5_GET_BITS(reg_value[1], BMA530_FEAT_ENG_ERR_INT_STATUS); + } + } + + return result; +} + +int8_t bma530_set_int_status(const struct bma530_int_status_types *config, uint8_t n_status, struct bma5_dev *dev) +{ + /* Function execution status */ + int8_t result = BMA5_OK; + uint8_t loop; + + /* Temporary variable to store the register value to be set */ + uint8_t reg_value[2] = { 0 }; + + if (NULL == config) + { + result = BMA5_E_NULL_PTR; + } + else + { + for (loop = 0; loop < n_status; loop++) + { + /* Bring up the register value to be set, as per the input details */ + reg_value[0] = BMA5_SET_BITS_POS_0(reg_value[0], + BMA530_ACC_DRDY_INT_STATUS, + config[loop].int_status.acc_drdy_int_status); + reg_value[0] = BMA5_SET_BITS(reg_value[0], + BMA530_FIFO_WM_INT_STATUS, + config[loop].int_status.fifo_wm_int_status); + reg_value[0] = BMA5_SET_BITS(reg_value[0], + BMA530_FIFO_FULL_INT_STATUS, + config[loop].int_status.fifo_full_int_status); + reg_value[0] = BMA5_SET_BITS(reg_value[0], + BMA530_GEN_INT1_INT_STATUS, + config[loop].int_status.gen_int1_int_status); + reg_value[0] = BMA5_SET_BITS(reg_value[0], + BMA530_GEN_INT2_INT_STATUS, + config[loop].int_status.gen_int2_int_status); + reg_value[0] = BMA5_SET_BITS(reg_value[0], + BMA530_GEN_INT3_INT_STATUS, + config[loop].int_status.gen_int3_int_status); + reg_value[0] = BMA5_SET_BITS(reg_value[0], + BMA530_STEP_DET_INT_STATUS, + config[loop].int_status.step_det_int_status); + reg_value[0] = BMA5_SET_BITS(reg_value[0], + BMA530_STEP_CNT_INT_STATUS, + config[loop].int_status.step_cnt_int_status); + + /* Bring up the register value to be set, as per the input details */ + reg_value[1] = BMA5_SET_BITS_POS_0(reg_value[1], + BMA530_SIG_MO_INT_STATUS, + config[loop].int_status.sig_mo_int_status); + reg_value[1] = BMA5_SET_BITS(reg_value[1], BMA530_TILT_INT_STATUS, config[loop].int_status.tilt_int_status); + reg_value[1] = BMA5_SET_BITS(reg_value[1], + BMA530_ORIENT_INT_STATUS, + config[loop].int_status.orient_int_status); + reg_value[1] = BMA5_SET_BITS(reg_value[1], + BMA530_ACC_FOC_INT_STATUS, + config[loop].int_status.acc_foc_int_status); + reg_value[1] = BMA5_SET_BITS(reg_value[1], + BMA530_FEAT_ENG_ERR_INT_STATUS, + config[loop].int_status.feat_eng_err_int_status); + + switch (config[loop].int_src) + { + case BMA530_INT_STATUS_INT1: + result = bma5_set_regs(BMA530_REG_INT_STATUS_INT1_0, reg_value, 2, dev); + break; + + case BMA530_INT_STATUS_INT2: + result = bma5_set_regs(BMA530_REG_INT_STATUS_INT2_0, reg_value, 2, dev); + break; + + case BMA530_INT_STATUS_I3C: + result = bma5_set_regs(BMA530_REG_INT_STATUS_I3C_0, reg_value, 2, dev); + break; + default: + result = BMA5_E_INVALID_INT_STATUS; + } + + if (BMA5_OK != result) + { + break; + } + } + } + + return result; +} + +int8_t bma530_get_int_map(struct bma530_int_map *config, struct bma5_dev *dev) +{ + /* Function execution status */ + int8_t result = BMA5_OK; + + /* Temporary variable to carry the register value */ + uint8_t reg_value[4] = { 0 }; + + if (NULL == config) + { + result = BMA5_E_NULL_PTR; + } + else + { + result = bma5_get_regs(BMA530_REG_INT_MAP_0, reg_value, 4, dev); + + if (BMA5_OK == result) + { + /* Parse needed details from received serial data */ + config->acc_drdy_int_map = BMA5_GET_BITS_POS_0(reg_value[0], BMA530_ACC_DRDY_INT_MAP); + config->fifo_wm_int_map = BMA5_GET_BITS(reg_value[0], BMA530_FIFO_WM_INT_MAP); + config->fifo_full_int_map = BMA5_GET_BITS(reg_value[0], BMA530_FIFO_FULL_INT_MAP); + config->gen_int1_int_map = BMA5_GET_BITS(reg_value[0], BMA530_GEN_INT1_INT_MAP); + + config->gen_int2_int_map = BMA5_GET_BITS_POS_0(reg_value[1], BMA530_GEN_INT2_INT_MAP); + config->gen_int3_int_map = BMA5_GET_BITS(reg_value[1], BMA530_GEN_INT3_INT_MAP); + config->step_det_int_map = BMA5_GET_BITS(reg_value[1], BMA530_STEP_DET_INT_MAP); + config->step_cnt_int_map = BMA5_GET_BITS(reg_value[1], BMA530_STEP_CNT_INT_MAP); + + config->sig_mo_int_map = BMA5_GET_BITS_POS_0(reg_value[2], BMA530_SIG_MO_INT_MAP); + config->tilt_int_map = BMA5_GET_BITS(reg_value[2], BMA530_TILT_INT_MAP); + config->orient_int_map = BMA5_GET_BITS(reg_value[2], BMA530_ORIENT_INT_MAP); + config->acc_foc_int_map = BMA5_GET_BITS(reg_value[2], BMA530_ACC_FOC_INT_MAP); + + config->feat_eng_err_int_map = BMA5_GET_BITS_POS_0(reg_value[3], BMA530_FEAT_ENG_ERR_INT_MAP); + } + } + + return result; +} + +int8_t bma530_set_int_map(const struct bma530_int_map *config, struct bma5_dev *dev) +{ + /* Function execution status */ + int8_t result; + + /* Temporary variable to store the register value to be set */ + uint8_t reg_value[4] = { 0 }; + + uint8_t acc_drdy_int_map, fifo_wm_int_map, fifo_full_int_map, gen_int1_int_map; + uint8_t gen_int2_int_map, gen_int3_int_map, step_det_int_map, step_cnt_int_map; + uint8_t sig_mo_int_map, tilt_int_map, orient_int_map, acc_foc_int_map; + + if (NULL == config) + { + result = BMA5_E_NULL_PTR; + } + else + { + result = bma5_get_regs(BMA530_REG_INT_MAP_0, reg_value, 4, dev); + + if (BMA5_OK == result) + { + /* Bring up the register value to be set, as per the input details */ + acc_drdy_int_map = + (BMA5_SET_BITS_POS_0(reg_value[0], BMA530_ACC_DRDY_INT_MAP, + config->acc_drdy_int_map) & BMA530_ACC_DRDY_INT_MAP_MSK); + fifo_wm_int_map = + (BMA5_SET_BITS(reg_value[0], BMA530_FIFO_WM_INT_MAP, + config->fifo_wm_int_map) & BMA530_FIFO_WM_INT_MAP_MSK); + fifo_full_int_map = + (BMA5_SET_BITS(reg_value[0], BMA530_FIFO_FULL_INT_MAP, + config->fifo_full_int_map) & BMA530_FIFO_FULL_INT_MAP_MSK); + gen_int1_int_map = + (BMA5_SET_BITS(reg_value[0], BMA530_GEN_INT1_INT_MAP, + config->gen_int1_int_map) & BMA530_GEN_INT1_INT_MAP_MSK); + + reg_value[0] = (uint8_t)(acc_drdy_int_map | fifo_wm_int_map | fifo_full_int_map | gen_int1_int_map); + + gen_int2_int_map = + (BMA5_SET_BITS_POS_0(reg_value[1], BMA530_GEN_INT2_INT_MAP, + config->gen_int2_int_map) & BMA530_GEN_INT2_INT_MAP_MSK); + gen_int3_int_map = + (BMA5_SET_BITS(reg_value[1], BMA530_GEN_INT3_INT_MAP, + config->gen_int3_int_map) & BMA530_GEN_INT3_INT_MAP_MSK); + step_det_int_map = + (BMA5_SET_BITS(reg_value[1], BMA530_STEP_DET_INT_MAP, + config->step_det_int_map) & BMA530_STEP_DET_INT_MAP_MSK); + step_cnt_int_map = + (BMA5_SET_BITS(reg_value[1], BMA530_STEP_CNT_INT_MAP, + config->step_cnt_int_map) & BMA530_STEP_CNT_INT_MAP_MSK); + + reg_value[1] = (uint8_t)(gen_int2_int_map | gen_int3_int_map | step_det_int_map | step_cnt_int_map); + + sig_mo_int_map = + (BMA5_SET_BITS_POS_0(reg_value[2], BMA530_SIG_MO_INT_MAP, + config->sig_mo_int_map) & BMA530_SIG_MO_INT_MAP_MSK); + tilt_int_map = + (BMA5_SET_BITS(reg_value[2], BMA530_TILT_INT_MAP, config->tilt_int_map) & BMA530_TILT_INT_MAP_MSK); + orient_int_map = + (BMA5_SET_BITS(reg_value[2], BMA530_ORIENT_INT_MAP, + config->orient_int_map) & BMA530_ORIENT_INT_MAP_MSK); + acc_foc_int_map = + (BMA5_SET_BITS(reg_value[2], BMA530_ACC_FOC_INT_MAP, + config->acc_foc_int_map) & BMA530_ACC_FOC_INT_MAP_MSK); + + reg_value[2] = (uint8_t)(sig_mo_int_map | tilt_int_map | orient_int_map | acc_foc_int_map); + + reg_value[3] = BMA5_SET_BITS_POS_0(reg_value[3], BMA530_FEAT_ENG_ERR_INT_MAP, config->feat_eng_err_int_map); + + result = bma5_set_regs(BMA530_REG_INT_MAP_0, reg_value, 4, dev); + } + } + + return result; +} + +int8_t bma530_get_feat_eng_gp_flags(struct bma530_feat_eng_gp_flags *config, struct bma5_dev *dev) +{ + /* Function execution status */ + int8_t result; + + /* Temporary variable to carry the register value */ + uint8_t reg_value; + + if (NULL == config) + { + result = BMA5_E_NULL_PTR; + } + else + { + result = bma5_get_regs(BMA530_REG_FEAT_ENG_GP_FLAGS, ®_value, sizeof(reg_value), dev); + if (BMA5_OK == result) + { + /* Parse needed details from received serial data */ + config->feat_init_stat = BMA5_GET_BITS_POS_0(reg_value, BMA530_FEAT_INIT_STAT); + config->foc_running = BMA5_GET_BITS(reg_value, BMA530_FOC_RUNNING); + config->fifo_size_changed = BMA5_GET_BITS(reg_value, BMA530_FIFO_SIZE_CHANGED); + } + } + + return result; +} + +int8_t bma530_get_feat_eng_gpr_0(struct bma530_feat_eng_gpr_0 *config, struct bma5_dev *dev) +{ + /* Function execution status */ + int8_t result; + + /* Temporary variable to carry the register value */ + uint8_t reg_value; + + if (NULL == config) + { + result = BMA5_E_NULL_PTR; + } + else + { + result = bma5_get_regs(BMA530_REG_FEAT_ENG_GPR_0, ®_value, sizeof(reg_value), dev); + if (BMA5_OK == result) + { + /* Parse needed details from received serial data */ + config->gen_int1_en = BMA5_GET_BITS_POS_0(reg_value, BMA530_GEN_INT1_EN); + config->gen_int2_en = BMA5_GET_BITS(reg_value, BMA530_GEN_INT2_EN); + config->gen_int3_en = BMA5_GET_BITS(reg_value, BMA530_GEN_INT3_EN); + config->step_en = BMA5_GET_BITS(reg_value, BMA530_STEP_EN); + config->sig_mo_en = BMA5_GET_BITS(reg_value, BMA530_SIG_MO_EN); + config->tilt_en = BMA5_GET_BITS(reg_value, BMA530_TILT_EN); + config->orient_en = BMA5_GET_BITS(reg_value, BMA530_ORIENT_EN); + config->acc_foc_en = BMA5_GET_BITS(reg_value, BMA530_ACC_FOC_EN); + } + } + + return result; +} + +int8_t bma530_set_feat_eng_gpr_0(const struct bma530_feat_eng_gpr_0 *config, struct bma5_dev *dev) +{ + /* Function execution status */ + int8_t result; + + /* Temporary variable to store the register value to be set */ + uint8_t reg_value = 0; + + uint8_t gen_int1_en, gen_int2_en, gen_int3_en, step_en, sig_mo_en, tilt_en, orient_en, acc_foc_en; + + if (NULL == config) + { + result = BMA5_E_NULL_PTR; + } + else + { + result = bma5_get_regs(BMA530_REG_FEAT_ENG_GPR_0, ®_value, sizeof(reg_value), dev); + + if (BMA5_OK == result) + { + /* Bring up the register value to be set, as per the input details */ + gen_int1_en = + (BMA5_SET_BITS_POS_0(reg_value, BMA530_GEN_INT1_EN, config->gen_int1_en) & BMA530_GEN_INT1_EN_MSK); + gen_int2_en = (BMA5_SET_BITS(reg_value, BMA530_GEN_INT2_EN, config->gen_int2_en) & BMA530_GEN_INT2_EN_MSK); + gen_int3_en = (BMA5_SET_BITS(reg_value, BMA530_GEN_INT3_EN, config->gen_int3_en) & BMA530_GEN_INT3_EN_MSK); + step_en = (BMA5_SET_BITS(reg_value, BMA530_STEP_EN, config->step_en) & BMA530_STEP_EN_MSK); + sig_mo_en = (BMA5_SET_BITS(reg_value, BMA530_SIG_MO_EN, config->sig_mo_en) & BMA530_SIG_MO_EN_MSK); + tilt_en = (BMA5_SET_BITS(reg_value, BMA530_TILT_EN, config->tilt_en) & BMA530_TILT_EN_MSK); + orient_en = (BMA5_SET_BITS(reg_value, BMA530_ORIENT_EN, config->orient_en) & BMA530_ORIENT_EN_MSK); + acc_foc_en = (BMA5_SET_BITS(reg_value, BMA530_ACC_FOC_EN, config->acc_foc_en) & BMA530_ACC_FOC_EN_MSK); + + reg_value = + (uint8_t)(gen_int1_en | gen_int2_en | gen_int3_en | step_en | sig_mo_en | tilt_en | orient_en | + acc_foc_en); + + result = bma5_set_regs(BMA530_REG_FEAT_ENG_GPR_0, (const uint8_t *)®_value, sizeof(reg_value), dev); + } + } + + return result; +} + +int8_t bma530_get_feat_eng_gpr_1(struct bma530_feat_eng_gpr_1 *config, struct bma5_dev *dev) +{ + /* Function execution status */ + int8_t result; + + /* Temporary variable to carry the register value */ + uint8_t reg_value; + + if (NULL == config) + { + result = BMA5_E_NULL_PTR; + } + else + { + result = bma5_get_regs(BMA530_REG_FEAT_ENG_GPR_1, ®_value, sizeof(reg_value), dev); + if (BMA5_OK == result) + { + /* Parse needed details from received serial data */ + config->gen_int1_data_src = BMA5_GET_BITS_POS_0(reg_value, BMA530_GEN_INT1_DATA_SRC); + config->gen_int2_data_src = BMA5_GET_BITS(reg_value, BMA530_GEN_INT2_DATA_SRC); + config->gen_int3_data_src = BMA5_GET_BITS(reg_value, BMA530_GEN_INT3_DATA_SRC); + } + } + + return result; +} + +int8_t bma530_set_feat_eng_gpr_1(const struct bma530_feat_eng_gpr_1 *config, struct bma5_dev *dev) +{ + /* Function execution status */ + int8_t result; + + /* Temporary variable to store the register value to be set */ + uint8_t reg_value = 0; + + uint8_t gen_int1_data_src, gen_int2_data_src, gen_int3_data_src; + + if (NULL == config) + { + result = BMA5_E_NULL_PTR; + } + else + { + result = bma5_get_regs(BMA530_REG_FEAT_ENG_GPR_1, ®_value, sizeof(reg_value), dev); + + if (BMA5_OK == result) + { + /* Bring up the register value to be set, as per the input details */ + gen_int1_data_src = + (BMA5_SET_BITS_POS_0(reg_value, BMA530_GEN_INT1_DATA_SRC, + config->gen_int1_data_src) & BMA530_GEN_INT1_DATA_SRC_MSK); + gen_int2_data_src = + (BMA5_SET_BITS(reg_value, BMA530_GEN_INT2_DATA_SRC, + config->gen_int2_data_src) & BMA530_GEN_INT2_DATA_SRC_MSK); + gen_int3_data_src = + (BMA5_SET_BITS(reg_value, BMA530_GEN_INT3_DATA_SRC, + config->gen_int3_data_src) & BMA530_GEN_INT3_DATA_SRC_MSK); + + reg_value = (uint8_t)(gen_int1_data_src | gen_int2_data_src | gen_int3_data_src); + + result = bma5_set_regs(BMA530_REG_FEAT_ENG_GPR_1, (const uint8_t *)®_value, sizeof(reg_value), dev); + } + } + + return result; +} + +int8_t bma530_get_feat_eng_gpr_2(uint8_t *step_cnt_out_0, struct bma5_dev *dev) +{ + /* Function execution status */ + int8_t result; + + /* Temporary variable to carry the register value */ + uint8_t reg_value; + + if (NULL == step_cnt_out_0) + { + result = BMA5_E_NULL_PTR; + } + else + { + result = bma5_get_regs(BMA530_REG_FEAT_ENG_GPR_2, ®_value, sizeof(reg_value), dev); + if (BMA5_OK == result) + { + /* Parse needed details from received serial data */ + *step_cnt_out_0 = BMA5_GET_BITS_POS_0(reg_value, BMA530_STEP_CNT_OUT_0); + } + } + + return result; +} + +int8_t bma530_get_feat_eng_gpr_3(uint8_t *step_cnt_out_1, struct bma5_dev *dev) +{ + /* Function execution status */ + int8_t result; + + /* Temporary variable to carry the register value */ + uint8_t reg_value; + + if (NULL == step_cnt_out_1) + { + result = BMA5_E_NULL_PTR; + } + else + { + result = bma5_get_regs(BMA530_REG_FEAT_ENG_GPR_3, ®_value, sizeof(reg_value), dev); + if (BMA5_OK == result) + { + /* Parse needed details from received serial data */ + *step_cnt_out_1 = BMA5_GET_BITS_POS_0(reg_value, BMA530_STEP_CNT_OUT_1); + } + } + + return result; +} + +int8_t bma530_get_feat_eng_gpr_4(uint8_t *step_cnt_out_2, struct bma5_dev *dev) +{ + /* Function execution status */ + int8_t result; + + /* Temporary variable to carry the register value */ + uint8_t reg_value; + + if (NULL == step_cnt_out_2) + { + result = BMA5_E_NULL_PTR; + } + else + { + result = bma5_get_regs(BMA530_REG_FEAT_ENG_GPR_4, ®_value, sizeof(reg_value), dev); + if (BMA5_OK == result) + { + /* Parse needed details from received serial data */ + *step_cnt_out_2 = BMA5_GET_BITS_POS_0(reg_value, BMA530_STEP_CNT_OUT_2); + } + } + + return result; +} + +int8_t bma530_get_feat_eng_gpr_5(struct bma530_feat_eng_gpr_5 *config, struct bma5_dev *dev) +{ + /* Function execution status */ + int8_t result; + + /* Temporary variable to carry the register value */ + uint8_t reg_value; + + if (NULL == config) + { + result = BMA5_E_NULL_PTR; + } + else + { + result = bma5_get_regs(BMA530_REG_FEAT_ENG_GPR_5, ®_value, sizeof(reg_value), dev); + if (BMA5_OK == result) + { + /* Parse needed details from received serial data */ + config->orientation_portrait_landscape = BMA5_GET_BITS_POS_0(reg_value, + BMA530_ORIENTATION_PORTRAIT_LANDSCAPE); + config->orientation_face_up_down = BMA5_GET_BITS(reg_value, BMA530_ORIENTATION_FACE_UP_DOWN); + config->activ_stat = BMA5_GET_BITS(reg_value, BMA530_ACTIV_STAT); + config->gen_int1_stat = BMA5_GET_BITS(reg_value, BMA530_GEN_INT1_STAT); + config->gen_int2_stat = BMA5_GET_BITS(reg_value, BMA530_GEN_INT2_STAT); + config->gen_int3_stat = BMA5_GET_BITS(reg_value, BMA530_GEN_INT3_STAT); + } + } + + return result; +} diff --git a/bma530.h b/bma530.h new file mode 100644 index 0000000..c1be7a1 --- /dev/null +++ b/bma530.h @@ -0,0 +1,958 @@ +/** +* Copyright (c) 2024 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 bma530.h +* @date 2024-04-15 +* @version v4.1.0 +* +*/ + +#ifndef _BMA530_H +#define _BMA530_H + +/*! CPP guard */ +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************/ +/****************************** Header files **********************************/ +/******************************************************************************/ +#include "bma5.h" + +/******************************************************************************/ +/************************* General macro definitions **************************/ +/******************************************************************************/ +/*! Chip ID of BMA530 */ +#define BMA530_CHIP_ID UINT8_C(0xC2) + +/******************************************************************************/ +/***************************** Register addresses *****************************/ +/******************************************************************************/ +/*! The product chip_id. Upper four bits are fix and lower four bits are boot loaded from OTP. */ +#define BMA530_REG_CHIP_ID UINT8_C(0x00) + +/*! INT1 interrupt status register 0 */ +#define BMA530_REG_INT_STATUS_INT1_0 UINT8_C(0x12) + +/*! INT1 interrupt status register 1 */ +#define BMA530_REG_INT_STATUS_INT1_1 UINT8_C(0x13) + +/*! INT2 interrupt status register 0 */ +#define BMA530_REG_INT_STATUS_INT2_0 UINT8_C(0x14) + +/*! INT2 interrupt status register 1 */ +#define BMA530_REG_INT_STATUS_INT2_1 UINT8_C(0x15) + +/*! I3C interrupt status register 0 */ +#define BMA530_REG_INT_STATUS_I3C_0 UINT8_C(0x16) + +/*! I3C interrupt status register 1 */ +#define BMA530_REG_INT_STATUS_I3C_1 UINT8_C(0x17) + +/*! Interrupt mapping register 0 */ +#define BMA530_REG_INT_MAP_0 UINT8_C(0x36) + +/*! Interrupt mapping register 1 */ +#define BMA530_REG_INT_MAP_1 UINT8_C(0x37) + +/*! Interrupt mapping register 2 */ +#define BMA530_REG_INT_MAP_2 UINT8_C(0x38) + +/*! Interrupt mapping register 3 */ +#define BMA530_REG_INT_MAP_3 UINT8_C(0x39) + +/*! feature engine ('feat_eng') general purpose flags */ +#define BMA530_REG_FEAT_ENG_GP_FLAGS UINT8_C(0x52) + +/*! feature engine ('feat_eng') general purpose register 0 */ +#define BMA530_REG_FEAT_ENG_GPR_0 UINT8_C(0x55) + +/*! feature engine ('feat_eng') general purpose register 1 */ +#define BMA530_REG_FEAT_ENG_GPR_1 UINT8_C(0x56) + +/*! feature engine ('feat_eng') general purpose register 2 */ +#define BMA530_REG_FEAT_ENG_GPR_2 UINT8_C(0x57) + +/*! feature engine ('feat_eng') general purpose register 3 */ +#define BMA530_REG_FEAT_ENG_GPR_3 UINT8_C(0x58) + +/*! feature engine ('feat_eng') general purpose register 4 */ +#define BMA530_REG_FEAT_ENG_GPR_4 UINT8_C(0x59) + +/*! feature engine ('feat_eng') general purpose register 5 */ +#define BMA530_REG_FEAT_ENG_GPR_5 UINT8_C(0x5A) + +/******************************************************************************/ +/********************** Register macros for bit masking ***********************/ +/******************************************************************************/ +/*! Chip id */ +#define BMA530_CHIP_ID_MSK UINT8_C(0xFF) +#define BMA530_CHIP_ID_POS UINT8_C(0x00) + +/*| + * @brief Mask and Position values for Interrupt Status for INT1, INT2, I3C Interrupts + */ + +/*! Accelerometer data ready interrupt status */ +#define BMA530_ACC_DRDY_INT_STATUS_MSK UINT8_C(0x01) +#define BMA530_ACC_DRDY_INT_STATUS_POS UINT8_C(0x00) + +/*! FIFO watermark interrupt status */ +#define BMA530_FIFO_WM_INT_STATUS_MSK UINT8_C(0x02) +#define BMA530_FIFO_WM_INT_STATUS_POS UINT8_C(0x01) + +/*! FIFO full interrupt status */ +#define BMA530_FIFO_FULL_INT_STATUS_MSK UINT8_C(0x04) +#define BMA530_FIFO_FULL_INT_STATUS_POS UINT8_C(0x02) + +/*! Generic interrupt 1 interrupt status */ +#define BMA530_GEN_INT1_INT_STATUS_MSK UINT8_C(0x08) +#define BMA530_GEN_INT1_INT_STATUS_POS UINT8_C(0x03) + +/*! Generic interrupt 2 interrupt status */ +#define BMA530_GEN_INT2_INT_STATUS_MSK UINT8_C(0x10) +#define BMA530_GEN_INT2_INT_STATUS_POS UINT8_C(0x04) + +/*! Generic interrupt 3 interrupt status */ +#define BMA530_GEN_INT3_INT_STATUS_MSK UINT8_C(0x20) +#define BMA530_GEN_INT3_INT_STATUS_POS UINT8_C(0x05) + +/*! Step detection interrupt status */ +#define BMA530_STEP_DET_INT_STATUS_MSK UINT8_C(0x40) +#define BMA530_STEP_DET_INT_STATUS_POS UINT8_C(0x06) + +/*! Step counter watermark interrupt status */ +#define BMA530_STEP_CNT_INT_STATUS_MSK UINT8_C(0x80) +#define BMA530_STEP_CNT_INT_STATUS_POS UINT8_C(0x07) + +/*! Significant motion detection interrupt status */ +#define BMA530_SIG_MO_INT_STATUS_MSK UINT8_C(0x01) +#define BMA530_SIG_MO_INT_STATUS_POS UINT8_C(0x00) + +/*! Tilt detection interrupt status */ +#define BMA530_TILT_INT_STATUS_MSK UINT8_C(0x02) +#define BMA530_TILT_INT_STATUS_POS UINT8_C(0x01) + +/*! Orientation detection status */ +#define BMA530_ORIENT_INT_STATUS_MSK UINT8_C(0x04) +#define BMA530_ORIENT_INT_STATUS_POS UINT8_C(0x02) + +/*! Accelerometer FOC completion status */ +#define BMA530_ACC_FOC_INT_STATUS_MSK UINT8_C(0x08) +#define BMA530_ACC_FOC_INT_STATUS_POS UINT8_C(0x03) + +/*! MCU error interrupt status */ +#define BMA530_FEAT_ENG_ERR_INT_STATUS_MSK UINT8_C(0x10) +#define BMA530_FEAT_ENG_ERR_INT_STATUS_POS UINT8_C(0x04) + +/*! Data ready interrupt mapping */ +#define BMA530_ACC_DRDY_INT_MAP_MSK UINT8_C(0x03) +#define BMA530_ACC_DRDY_INT_MAP_POS UINT8_C(0x00) + +/*! FIFO watermark interrupt mapping */ +#define BMA530_FIFO_WM_INT_MAP_MSK UINT8_C(0x0C) +#define BMA530_FIFO_WM_INT_MAP_POS UINT8_C(0x02) + +/*! FIFO full interrupt mapping */ +#define BMA530_FIFO_FULL_INT_MAP_MSK UINT8_C(0x30) +#define BMA530_FIFO_FULL_INT_MAP_POS UINT8_C(0x04) + +/*! Generic interrupt 1 interrupt mapping */ +#define BMA530_GEN_INT1_INT_MAP_MSK UINT8_C(0xC0) +#define BMA530_GEN_INT1_INT_MAP_POS UINT8_C(0x06) + +/*! Generic interrupt 2 interrupt mapping */ +#define BMA530_GEN_INT2_INT_MAP_MSK UINT8_C(0x03) +#define BMA530_GEN_INT2_INT_MAP_POS UINT8_C(0x00) + +/*! Generic interrupt 3 interrupt mapping */ +#define BMA530_GEN_INT3_INT_MAP_MSK UINT8_C(0x0C) +#define BMA530_GEN_INT3_INT_MAP_POS UINT8_C(0x02) + +/*! Step detection interrupt mapping */ +#define BMA530_STEP_DET_INT_MAP_MSK UINT8_C(0x30) +#define BMA530_STEP_DET_INT_MAP_POS UINT8_C(0x04) + +/*! Step counter watermark interrupt mapping */ +#define BMA530_STEP_CNT_INT_MAP_MSK UINT8_C(0xC0) +#define BMA530_STEP_CNT_INT_MAP_POS UINT8_C(0x06) + +/*! Significant motion detection interrupt mapping */ +#define BMA530_SIG_MO_INT_MAP_MSK UINT8_C(0x03) +#define BMA530_SIG_MO_INT_MAP_POS UINT8_C(0x00) + +/*! Tilt detection interrupt mapping */ +#define BMA530_TILT_INT_MAP_MSK UINT8_C(0x0C) +#define BMA530_TILT_INT_MAP_POS UINT8_C(0x02) + +/*! Orientation detection interrupt mapping */ +#define BMA530_ORIENT_INT_MAP_MSK UINT8_C(0x30) +#define BMA530_ORIENT_INT_MAP_POS UINT8_C(0x04) + +/*! Accelerometer FOC completion interrupt mapping */ +#define BMA530_ACC_FOC_INT_MAP_MSK UINT8_C(0xC0) +#define BMA530_ACC_FOC_INT_MAP_POS UINT8_C(0x06) + +/*! MCU error interrupt mapping */ +#define BMA530_FEAT_ENG_ERR_INT_MAP_MSK UINT8_C(0x03) +#define BMA530_FEAT_ENG_ERR_INT_MAP_POS UINT8_C(0x00) + +/*! Feature engine initialization status */ +#define BMA530_FEAT_INIT_STAT_MSK UINT8_C(0x03) +#define BMA530_FEAT_INIT_STAT_POS UINT8_C(0x00) + +/*! Bit is set to '1' if fast-offset compensation feature is being executed. Bit is cleared to '0' at the end of + * feature compensation. User should not change the accelerometer configuration while the feature is running. */ +#define BMA530_FOC_RUNNING_MSK UINT8_C(0x04) +#define BMA530_FOC_RUNNING_POS UINT8_C(0x02) + +/*! Bit is set when FIFO size is changed by feature engine. Bit is cleared, when default FIFO size (512bytes) is set + * */ +#define BMA530_FIFO_SIZE_CHANGED_MSK UINT8_C(0x08) +#define BMA530_FIFO_SIZE_CHANGED_POS UINT8_C(0x03) + +/*! Enables generic interrupt 1 feature */ +#define BMA530_GEN_INT1_EN_MSK UINT8_C(0x01) +#define BMA530_GEN_INT1_EN_POS UINT8_C(0x00) + +/*! Enables generic interrupt 2 feature */ +#define BMA530_GEN_INT2_EN_MSK UINT8_C(0x02) +#define BMA530_GEN_INT2_EN_POS UINT8_C(0x01) + +/*! Enables generic interrupt 3 feature */ +#define BMA530_GEN_INT3_EN_MSK UINT8_C(0x04) +#define BMA530_GEN_INT3_EN_POS UINT8_C(0x02) + +/*! Enables step counter and/or step detection features */ +#define BMA530_STEP_EN_MSK UINT8_C(0x08) +#define BMA530_STEP_EN_POS UINT8_C(0x03) + +/*! Enables significant motion detection feature */ +#define BMA530_SIG_MO_EN_MSK UINT8_C(0x10) +#define BMA530_SIG_MO_EN_POS UINT8_C(0x04) + +/*! Enables tilt detection feature */ +#define BMA530_TILT_EN_MSK UINT8_C(0x20) +#define BMA530_TILT_EN_POS UINT8_C(0x05) + +/*! Enables orientation detection feature */ +#define BMA530_ORIENT_EN_MSK UINT8_C(0x40) +#define BMA530_ORIENT_EN_POS UINT8_C(0x06) + +/*! Enables accelerometer fast-offset compensation */ +#define BMA530_ACC_FOC_EN_MSK UINT8_C(0x80) +#define BMA530_ACC_FOC_EN_POS UINT8_C(0x07) + +/*! Data source selection for gen_int1 feature */ +#define BMA530_GEN_INT1_DATA_SRC_MSK UINT8_C(0x03) +#define BMA530_GEN_INT1_DATA_SRC_POS UINT8_C(0x00) + +/*! Data source selection for gen_int2 feature */ +#define BMA530_GEN_INT2_DATA_SRC_MSK UINT8_C(0x0C) +#define BMA530_GEN_INT2_DATA_SRC_POS UINT8_C(0x02) + +/*! Data source selection for gen_int3 feature */ +#define BMA530_GEN_INT3_DATA_SRC_MSK UINT8_C(0x30) +#define BMA530_GEN_INT3_DATA_SRC_POS UINT8_C(0x04) + +/*! Step counter value byte-0 */ +#define BMA530_STEP_CNT_OUT_0_MSK UINT8_C(0xFF) +#define BMA530_STEP_CNT_OUT_0_POS UINT8_C(0x00) + +/*! Step counter value byte-1 */ +#define BMA530_STEP_CNT_OUT_1_MSK UINT8_C(0xFF) +#define BMA530_STEP_CNT_OUT_1_POS UINT8_C(0x00) + +/*! Step counter value byte-2 */ +#define BMA530_STEP_CNT_OUT_2_MSK UINT8_C(0xFF) +#define BMA530_STEP_CNT_OUT_2_POS UINT8_C(0x00) + +/*! Output of orientation detection feature. Device orientation can be either portrait or landscape. Value after device + * initialization is 0b00 i.e. portrait up. */ +#define BMA530_ORIENTATION_PORTRAIT_LANDSCAPE_MSK UINT8_C(0x03) +#define BMA530_ORIENTATION_PORTRAIT_LANDSCAPE_POS UINT8_C(0x00) + +/*! Output of orientation detection feature. Output is only valid if "ud_en" is enabled. Device orientation can be + * either face up or face down. Value after device initialization is 0b0 i.e. face up. */ +#define BMA530_ORIENTATION_FACE_UP_DOWN_MSK UINT8_C(0x04) +#define BMA530_ORIENTATION_FACE_UP_DOWN_POS UINT8_C(0x02) + +/*! Status of user activity reported by step counter */ +#define BMA530_ACTIV_STAT_MSK UINT8_C(0x18) +#define BMA530_ACTIV_STAT_POS UINT8_C(0x03) + +/*! Status of generic interrupt 1 motion detection */ +#define BMA530_GEN_INT1_STAT_MSK UINT8_C(0x20) +#define BMA530_GEN_INT1_STAT_POS UINT8_C(0x05) + +/*! Status of generic interrupt 2 motion detection */ +#define BMA530_GEN_INT2_STAT_MSK UINT8_C(0x40) +#define BMA530_GEN_INT2_STAT_POS UINT8_C(0x06) + +/*! Status of generic interrupt 3 motion detection */ +#define BMA530_GEN_INT3_STAT_MSK UINT8_C(0x80) +#define BMA530_GEN_INT3_STAT_POS UINT8_C(0x07) + +/******************************************************************************/ +/********************* Macros for supported field values **********************/ +/******************************************************************************/ +/* Macros to define the supported chip_id values */ +#define BMA530_CHIP_ID_BMA530 UINT8_C(0xC2) /*! product identifier for BMA530 */ + +/* Macros to define the supported acc_drdy_int_map values */ +#define BMA530_ACC_DRDY_INT_MAP_UNMAPPED UINT8_C(0x00) /*! Interrupt is not mapped to any + * destination. */ +#define BMA530_ACC_DRDY_INT_MAP_INT1 UINT8_C(0x01) /*! Interrupt is mapped to INT1 pin. */ +#define BMA530_ACC_DRDY_INT_MAP_INT2 UINT8_C(0x02) /*! Interrupt is mapped to INT2 pin. */ +#define BMA530_ACC_DRDY_INT_MAP_I3C UINT8_C(0x03) /*! Interrupt is mapped to I3C in-band + * interrupts. */ + +/* Macros to define the supported fifo_wm_int_map values */ +#define BMA530_FIFO_WM_INT_MAP_UNMAPPED UINT8_C(0x00) /*! Interrupt is not mapped to any + * destination. */ +#define BMA530_FIFO_WM_INT_MAP_INT1 UINT8_C(0x01) /*! Interrupt is mapped to INT1 pin. */ +#define BMA530_FIFO_WM_INT_MAP_INT2 UINT8_C(0x02) /*! Interrupt is mapped to INT2 pin. */ +#define BMA530_FIFO_WM_INT_MAP_I3C UINT8_C(0x03) /*! Interrupt is mapped to I3C in-band + * interrupts. */ + +/* Macros to define the supported fifo_full_int_map values */ +#define BMA530_FIFO_FULL_INT_MAP_UNMAPPED UINT8_C(0x00) /*! Interrupt is not mapped to any + * destination. */ +#define BMA530_FIFO_FULL_INT_MAP_INT1 UINT8_C(0x01) /*! Interrupt is mapped to INT1 pin. */ +#define BMA530_FIFO_FULL_INT_MAP_INT2 UINT8_C(0x02) /*! Interrupt is mapped to INT2 pin. */ +#define BMA530_FIFO_FULL_INT_MAP_I3C UINT8_C(0x03) /*! Interrupt is mapped to I3C in-band + * interrupts. */ + +/* Macros to define the supported gen_int1_int_map values */ +#define BMA530_GEN_INT1_INT_MAP_UNMAPPED UINT8_C(0x00) /*! Interrupt is not mapped to any + * destination. */ +#define BMA530_GEN_INT1_INT_MAP_INT1 UINT8_C(0x01) /*! Interrupt is mapped to INT1 pin. */ +#define BMA530_GEN_INT1_INT_MAP_INT2 UINT8_C(0x02) /*! Interrupt is mapped to INT2 pin. */ +#define BMA530_GEN_INT1_INT_MAP_I3C UINT8_C(0x03) /*! Interrupt is mapped to I3C in-band + * interrupts. */ + +/* Macros to define the supported gen_int2_int_map values */ +#define BMA530_GEN_INT2_INT_MAP_UNMAPPED UINT8_C(0x00) /*! Interrupt is not mapped to any + * destination. */ +#define BMA530_GEN_INT2_INT_MAP_INT1 UINT8_C(0x01) /*! Interrupt is mapped to INT1 pin. */ +#define BMA530_GEN_INT2_INT_MAP_INT2 UINT8_C(0x02) /*! Interrupt is mapped to INT2 pin. */ +#define BMA530_GEN_INT2_INT_MAP_I3C UINT8_C(0x03) /*! Interrupt is mapped to I3C in-band + * interrupts. */ + +/* Macros to define the supported gen_int3_int_map values */ +#define BMA530_GEN_INT3_INT_MAP_UNMAPPED UINT8_C(0x00) /*! Interrupt is not mapped to any + * destination. */ +#define BMA530_GEN_INT3_INT_MAP_INT1 UINT8_C(0x01) /*! Interrupt is mapped to INT1 pin. */ +#define BMA530_GEN_INT3_INT_MAP_INT2 UINT8_C(0x02) /*! Interrupt is mapped to INT2 pin. */ +#define BMA530_GEN_INT3_INT_MAP_I3C UINT8_C(0x03) /*! Interrupt is mapped to I3C in-band + * interrupts. */ + +/* Macros to define the supported step_det_int_map values */ +#define BMA530_STEP_DET_INT_MAP_UNMAPPED UINT8_C(0x00) /*! Interrupt is not mapped to any + * destination. */ +#define BMA530_STEP_DET_INT_MAP_INT1 UINT8_C(0x01) /*! Interrupt is mapped to INT1 pin. */ +#define BMA530_STEP_DET_INT_MAP_INT2 UINT8_C(0x02) /*! Interrupt is mapped to INT2 pin. */ +#define BMA530_STEP_DET_INT_MAP_I3C UINT8_C(0x03) /*! Interrupt is mapped to I3C in-band + * interrupts. */ + +/* Macros to define the supported step_cnt_int_map values */ +#define BMA530_STEP_CNT_INT_MAP_UNMAPPED UINT8_C(0x00) /*! Interrupt is not mapped to any + * destination. */ +#define BMA530_STEP_CNT_INT_MAP_INT1 UINT8_C(0x01) /*! Interrupt is mapped to INT1 pin. */ +#define BMA530_STEP_CNT_INT_MAP_INT2 UINT8_C(0x02) /*! Interrupt is mapped to INT2 pin. */ +#define BMA530_STEP_CNT_INT_MAP_I3C UINT8_C(0x03) /*! Interrupt is mapped to I3C in-band + * interrupts. */ + +/* Macros to define the supported sig_mo_int_map values */ +#define BMA530_SIG_MO_INT_MAP_UNMAPPED UINT8_C(0x00) /*! Interrupt is not mapped to any + * destination. */ +#define BMA530_SIG_MO_INT_MAP_INT1 UINT8_C(0x01) /*! Interrupt is mapped to INT1 pin. */ +#define BMA530_SIG_MO_INT_MAP_INT2 UINT8_C(0x02) /*! Interrupt is mapped to INT2 pin. */ +#define BMA530_SIG_MO_INT_MAP_I3C UINT8_C(0x03) /*! Interrupt is mapped to I3C in-band + * interrupts. */ + +/* Macros to define the supported tilt_int_map values */ +#define BMA530_TILT_INT_MAP_UNMAPPED UINT8_C(0x00) /*! Interrupt is not mapped to any + * destination. */ +#define BMA530_TILT_INT_MAP_INT1 UINT8_C(0x01) /*! Interrupt is mapped to INT1 pin. */ +#define BMA530_TILT_INT_MAP_INT2 UINT8_C(0x02) /*! Interrupt is mapped to INT2 pin. */ +#define BMA530_TILT_INT_MAP_I3C UINT8_C(0x03) /*! Interrupt is mapped to I3C in-band + * interrupts. */ + +/* Macros to define the supported orient_int_map values */ +#define BMA530_ORIENT_INT_MAP_UNMAPPED UINT8_C(0x00) /*! Interrupt is not mapped to any + * destination. */ +#define BMA530_ORIENT_INT_MAP_INT1 UINT8_C(0x01) /*! Interrupt is mapped to INT1 pin. */ +#define BMA530_ORIENT_INT_MAP_INT2 UINT8_C(0x02) /*! Interrupt is mapped to INT2 pin. */ +#define BMA530_ORIENT_INT_MAP_I3C UINT8_C(0x03) /*! Interrupt is mapped to I3C in-band + * interrupts. */ + +/* Macros to define the supported acc_foc_int_map values */ +#define BMA530_ACC_FOC_INT_MAP_UNMAPPED UINT8_C(0x00) /*! Interrupt is not mapped to any + * destination. */ +#define BMA530_ACC_FOC_INT_MAP_INT1 UINT8_C(0x01) /*! Interrupt is mapped to INT1 pin. */ +#define BMA530_ACC_FOC_INT_MAP_INT2 UINT8_C(0x02) /*! Interrupt is mapped to INT2 pin. */ +#define BMA530_ACC_FOC_INT_MAP_I3C UINT8_C(0x03) /*! Interrupt is mapped to I3C in-band + * interrupts. */ + +/* Macros to define the supported feat_eng_err_int_map values */ +#define BMA530_FEAT_ENG_ERR_INT_MAP_UNMAPPED UINT8_C(0x00) /*! Interrupt is not mapped to any + * destination. */ +#define BMA530_FEAT_ENG_ERR_INT_MAP_INT1 UINT8_C(0x01) /*! Interrupt is mapped to INT1 pin. */ +#define BMA530_FEAT_ENG_ERR_INT_MAP_INT2 UINT8_C(0x02) /*! Interrupt is mapped to INT2 pin. */ +#define BMA530_FEAT_ENG_ERR_INT_MAP_I3C UINT8_C(0x03) /*! Interrupt is mapped to I3C in-band + * interrupts. */ + +/* Macros to define the supported feat_init_stat values */ +#define BMA530_FEAT_INIT_STAT_INIT_NOT_OK UINT8_C(0x00) /*! Feature engine is not initialized */ +#define BMA530_FEAT_INIT_STAT_INIT_OK UINT8_C(0x01) /*! Feature engine is initialized */ +#define BMA530_FEAT_INIT_STAT_UN_DEF_1 UINT8_C(0x02) /*! Reserved */ +#define BMA530_FEAT_INIT_STAT_UN_DEF_2 UINT8_C(0x03) /*! Reserved */ + +/* Macros to define the supported gen_int1_data_src values */ +#define BMA530_GEN_INT1_DATA_SRC_DATA_SRC_1 UINT8_C(0x00) /*! Uses 50Hz filter data */ +#define BMA530_GEN_INT1_DATA_SRC_DATA_SRC_2 UINT8_C(0x01) /*! Uses 200Hz filter data */ +#define BMA530_GEN_INT1_DATA_SRC_DATA_SRC_3 UINT8_C(0x02) /*! Uses user filter data */ +#define BMA530_GEN_INT1_DATA_SRC_DATA_SRC_4 UINT8_C(0x03) /*! Uses 50Hz filter data. Same as + * data_src_1 */ + +/* Macros to define the supported gen_int2_data_src values */ +#define BMA530_GEN_INT2_DATA_SRC_DATA_SRC_1 UINT8_C(0x00) /*! Uses 50Hz filter data */ +#define BMA530_GEN_INT2_DATA_SRC_DATA_SRC_2 UINT8_C(0x01) /*! Uses 200Hz filter data */ +#define BMA530_GEN_INT2_DATA_SRC_DATA_SRC_3 UINT8_C(0x02) /*! Uses user filter data */ +#define BMA530_GEN_INT2_DATA_SRC_DATA_SRC_4 UINT8_C(0x03) /*! Uses 50Hz filter data. Same as + * data_src_1 */ + +/* Macros to define the supported gen_int3_data_src values */ +#define BMA530_GEN_INT3_DATA_SRC_DATA_SRC_1 UINT8_C(0x00) /*! Uses 50Hz filter data */ +#define BMA530_GEN_INT3_DATA_SRC_DATA_SRC_2 UINT8_C(0x01) /*! Uses 200Hz filter data */ +#define BMA530_GEN_INT3_DATA_SRC_DATA_SRC_3 UINT8_C(0x02) /*! Uses user filter data */ +#define BMA530_GEN_INT3_DATA_SRC_DATA_SRC_4 UINT8_C(0x03) /*! Uses 50Hz filter data. Same as + * data_src_1 */ + +/* Macros to define the supported orientation_portrait_landscape values */ +#define BMA530_ORIENTATION_PORTRAIT_LANDSCAPE_PORTRAIT_UP UINT8_C(0x00) /*! Portrait up orientation */ +#define BMA530_ORIENTATION_PORTRAIT_LANDSCAPE_LANDSCAPE_LEFT UINT8_C(0x01) /*! Landscape left orientation */ +#define BMA530_ORIENTATION_PORTRAIT_LANDSCAPE_PORTRAIT_DOWN UINT8_C(0x02) /*! Portrait down orientation */ +#define BMA530_ORIENTATION_PORTRAIT_LANDSCAPE_LANDSCAPE_RIGHT UINT8_C(0x03) /*! Landscape right orientation */ + +/* Macros to define the supported orientation_face_up_down values */ +#define BMA530_ORIENTATION_FACE_UP_DOWN_FACE_UP UINT8_C(0x00) /*! Face up orientation */ +#define BMA530_ORIENTATION_FACE_UP_DOWN_FACE_DOWN UINT8_C(0x01) /*! Face down orientation */ + +/* Macros to define the supported activ_stat values */ +#define BMA530_ACTIV_STAT_UNKNOWN UINT8_C(0x00) /*! After device reset or while step + * counter is disabled */ +#define BMA530_ACTIV_STAT_STILL UINT8_C(0x01) /*! User is stationary */ +#define BMA530_ACTIV_STAT_WALKING UINT8_C(0x02) /*! User is walking */ +#define BMA530_ACTIV_STAT_RUNNING UINT8_C(0x03) /*! User is running */ + +#define BMA530_INT_STATUS_INT1 UINT8_C(1) +#define BMA530_INT_STATUS_INT2 UINT8_C(2) +#define BMA530_INT_STATUS_I3C UINT8_C(3) + +/******************************************************************************/ +/***************** Structures for handling register content *******************/ +/******************************************************************************/ + +/*! + * @brief Structure holding interrupt status register + */ +struct bma530_int_status +{ + /*! Accelerometer data ready interrupt status */ + uint8_t acc_drdy_int_status; + + /*! FIFO watermark interrupt status */ + uint8_t fifo_wm_int_status; + + /*! FIFO full interrupt status */ + uint8_t fifo_full_int_status; + + /*! Generic interrupt 1 interrupt status */ + uint8_t gen_int1_int_status; + + /*! Generic interrupt 2 interrupt status */ + uint8_t gen_int2_int_status; + + /*! Generic interrupt 3 interrupt status */ + uint8_t gen_int3_int_status; + + /*! Step detection interrupt status */ + uint8_t step_det_int_status; + + /*! Step counter watermark interrupt status */ + uint8_t step_cnt_int_status; + + /*! Significant motion detection interrupt status */ + uint8_t sig_mo_int_status; + + /*! Tilt detection interrupt status */ + uint8_t tilt_int_status; + + /*! Orientation detection status */ + uint8_t orient_int_status; + + /*! Accelerometer FOC completion status */ + uint8_t acc_foc_int_status; + + /*! MCU error interrupt status */ + uint8_t feat_eng_err_int_status; +}; + +/*! + * @brief Structure holding Interrupt source and its configuration + */ +struct bma530_int_status_types +{ + /*! Interrupt soruce */ + uint8_t int_src; + + /*! Interrupt status configuration */ + struct bma530_int_status int_status; +}; + +/*! + * @brief Structure holding Interrupt mapping register + */ +struct bma530_int_map +{ + /*! Data ready interrupt mapping */ + uint8_t acc_drdy_int_map; + + /*! FIFO watermark interrupt mapping */ + uint8_t fifo_wm_int_map; + + /*! FIFO full interrupt mapping */ + uint8_t fifo_full_int_map; + + /*! Generic interrupt 1 interrupt mapping */ + uint8_t gen_int1_int_map; + + /*! Generic interrupt 2 interrupt mapping */ + uint8_t gen_int2_int_map; + + /*! Generic interrupt 3 interrupt mapping */ + uint8_t gen_int3_int_map; + + /*! Step detection interrupt mapping */ + uint8_t step_det_int_map; + + /*! Step counter watermark interrupt mapping */ + uint8_t step_cnt_int_map; + + /*! Significant motion detection interrupt mapping */ + uint8_t sig_mo_int_map; + + /*! Tilt detection interrupt mapping */ + uint8_t tilt_int_map; + + /*! Orientation detection interrupt mapping */ + uint8_t orient_int_map; + + /*! Accelerometer FOC completion interrupt mapping */ + uint8_t acc_foc_int_map; + + /*! MCU error interrupt mapping */ + uint8_t feat_eng_err_int_map; +}; + +/*! + * @brief Structure holding feature engine ('feat_eng') general purpose flags + */ +struct bma530_feat_eng_gp_flags +{ + /*! Feature engine initialization status */ + uint8_t feat_init_stat; + + /*! Bit is set to '1' if fast-offset compensation feature is being executed. Bit is cleared to '0' at the end of + * feature compensation. User should not change the accelerometer configuration while the feature is running. */ + uint8_t foc_running; + + /*! Bit is set when FIFO size is changed by feature engine. Bit is cleared, when default FIFO size (512bytes) is + * set */ + uint8_t fifo_size_changed; +}; + +/*! + * @brief Structure holding feature engine ('feat_eng') general purpose register 0 + */ +struct bma530_feat_eng_gpr_0 +{ + /*! Enables generic interrupt 1 feature */ + uint8_t gen_int1_en; + + /*! Enables generic interrupt 2 feature */ + uint8_t gen_int2_en; + + /*! Enables generic interrupt 3 feature */ + uint8_t gen_int3_en; + + /*! Enables step counter and/or step detection features */ + uint8_t step_en; + + /*! Enables significant motion detection feature */ + uint8_t sig_mo_en; + + /*! Enables tilt detection feature */ + uint8_t tilt_en; + + /*! Enables orientation detection feature */ + uint8_t orient_en; + + /*! Enables accelerometer fast-offset compensation */ + uint8_t acc_foc_en; +}; + +/*! + * @brief Structure holding feature engine ('feat_eng') general purpose register 1 + */ +struct bma530_feat_eng_gpr_1 +{ + /*! Data source selection for gen_int1 feature */ + uint8_t gen_int1_data_src; + + /*! Data source selection for gen_int2 feature */ + uint8_t gen_int2_data_src; + + /*! Data source selection for gen_int3 feature */ + uint8_t gen_int3_data_src; +}; + +/*! + * @brief Structure holding feature engine ('feat_eng') general purpose register 5 + */ +struct bma530_feat_eng_gpr_5 +{ + /*! Output of orientation detection feature. Device orientation can be either portrait or landscape. Value after + * device initialization is 0b00 i.e. portrait up. */ + uint8_t orientation_portrait_landscape; + + /*! Output of orientation detection feature. Output is only valid if "ud_en" is enabled. Device orientation can be + * either face up or face down. Value after device initialization is 0b0 i.e. face up. */ + uint8_t orientation_face_up_down; + + /*! Status of user activity reported by step counter */ + uint8_t activ_stat; + + /*! Status of generic interrupt 1 motion detection */ + uint8_t gen_int1_stat; + + /*! Status of generic interrupt 2 motion detection */ + uint8_t gen_int2_stat; + + /*! Status of generic interrupt 3 motion detection */ + uint8_t gen_int3_stat; +}; + +/******************************************************************************/ +/********************** Function prototype declarations ***********************/ +/******************************************************************************/ + +/** + * \ingroup bma530 + * \defgroup bma530ApiRegs BMA530 Registers + * @brief Set / Get data from the given register address of the sensor + */ + +/*! + * \ingroup bma530ApiRegs + * \page bma530_api_bma530_get_chip_id bma530_get_chip_id + * \code + * int8_t bma530_get_chip_id(uint8_t *chip_id, struct bma5_dev *dev); + * \endcode + * @details This API carries the provision to get the The product chip_id. Upper four bits are fix and lower four bits are boot loaded from OTP. + * + * @param[out] chip_id : Chip id + * @param[in] dev : Structure instance of bma5_dev. + * + * @return Result of API execution status + * + * @retval = 0 -> Success + * @retval > 0 -> Warning + * @retval < 0 -> Error + */ +int8_t bma530_get_chip_id(uint8_t *chip_id, struct bma5_dev *dev); + +/*! + * \ingroup bma530ApiRegs + * \page bma530_api_bma530_get_int_status_int1_0 bma530_get_int_status_int1_0 + * \code + * int8_t bma530_get_int_status(struct bma530_int_status_types *config, uint8_t n_status, struct bma5_dev *dev); + * \endcode + * @details This API carries the provision to get the INT1 interrupt status register 0 + * + * @param[out] config : Structure instance of bma530_int_status_int1_0 + * @param[in] dev : Structure instance of bma5_dev. + * + * @return Result of API execution status + * + * @retval = 0 -> Success + * @retval > 0 -> Warning + * @retval < 0 -> Error + */ +int8_t bma530_get_int_status(struct bma530_int_status_types *config, uint8_t n_status, struct bma5_dev *dev); + +/*! + * \ingroup bma530ApiRegs + * \page bma530_api_bma530_get_int_status_int1_0 bma530_get_int_status_int1_0 + * \code + * int8_t bma530_set_int_status(const struct bma530_int_status_types *config, uint8_t n_status, struct bma5_dev *dev); + * \endcode + * @details This API carries the provision to set the INT1 interrupt status register 0 + * + * @param[in] config : Structure instance of bma530_int_status_int1_0 + * @param[in] dev : Structure instance of bma5_dev. + * + * @return Result of API execution status + * + * @retval = 0 -> Success + * @retval > 0 -> Warning + * @retval < 0 -> Error + */ +int8_t bma530_set_int_status(const struct bma530_int_status_types *config, uint8_t n_status, struct bma5_dev *dev); + +/*! + * \ingroup bma530ApiRegs + * \page bma530_api_bma530_get_int_map_0 bma530_get_int_map_0 + * \code + * int8_t bma530_get_int_map_0(struct bma530_int_map *config, struct bma5_dev *dev); + * \endcode + * @details This API carries the provision to get the Interrupt mapping register 0 + * + * @param[out] config : Structure instance of bma530_int_map_0 + * @param[in] dev : Structure instance of bma5_dev. + * + * @return Result of API execution status + * + * @retval = 0 -> Success + * @retval > 0 -> Warning + * @retval < 0 -> Error + */ +int8_t bma530_get_int_map(struct bma530_int_map *config, struct bma5_dev *dev); + +/*! + * \ingroup bma530ApiRegs + * \page bma530_api_bma530_get_int_map_0 bma530_get_int_map_0 + * \code + * int8_t bma530_set_int_map(const struct bma530_int_map *config, struct bma5_dev *dev); + * \endcode + * @details This API carries the provision to set the Interrupt mapping register 0 + * + * @param[in] config : Structure instance of bma530_int_map_0 + * @param[in] dev : Structure instance of bma5_dev. + * + * @return Result of API execution status + * + * @retval = 0 -> Success + * @retval > 0 -> Warning + * @retval < 0 -> Error + */ +int8_t bma530_set_int_map(const struct bma530_int_map *config, struct bma5_dev *dev); + +/*! + * \ingroup bma530ApiRegs + * \page bma530_api_bma530_get_feat_eng_gp_flags bma530_get_feat_eng_gp_flags + * \code + * int8_t bma530_get_feat_eng_gp_flags(struct bma530_feat_eng_gp_flags *config, struct bma5_dev *dev); + * \endcode + * @details This API carries the provision to get the feature engine ('feat_eng') general purpose flags + * + * @param[out] config : Structure instance of bma530_feat_eng_gp_flags + * @param[in] dev : Structure instance of bma5_dev. + * + * @return Result of API execution status + * + * @retval = 0 -> Success + * @retval > 0 -> Warning + * @retval < 0 -> Error + */ +int8_t bma530_get_feat_eng_gp_flags(struct bma530_feat_eng_gp_flags *config, struct bma5_dev *dev); + +/*! + * \ingroup bma530ApiRegs + * \page bma530_api_bma530_get_feat_eng_gpr_0 bma530_get_feat_eng_gpr_0 + * \code + * int8_t bma530_get_feat_eng_gpr_0(struct bma530_feat_eng_gpr_0 *config, struct bma5_dev *dev); + * \endcode + * @details This API carries the provision to get the feature engine ('feat_eng') general purpose register 0 + * + * @param[out] config : Structure instance of bma530_feat_eng_gpr_0 + * @param[in] dev : Structure instance of bma5_dev. + * + * @return Result of API execution status + * + * @retval = 0 -> Success + * @retval > 0 -> Warning + * @retval < 0 -> Error + */ +int8_t bma530_get_feat_eng_gpr_0(struct bma530_feat_eng_gpr_0 *config, struct bma5_dev *dev); + +/*! + * \ingroup bma530ApiRegs + * \page bma530_api_bma530_get_feat_eng_gpr_0 bma530_get_feat_eng_gpr_0 + * \code + * int8_t bma530_set_feat_eng_gpr_0(const struct bma530_feat_eng_gpr_0 *config, struct bma5_dev *dev); + * \endcode + * @details This API carries the provision to set the feature engine ('feat_eng') general purpose register 0 + * + * @param[in] config : Structure instance of bma530_feat_eng_gpr_0 + * @param[in] dev : Structure instance of bma5_dev. + * + * @return Result of API execution status + * + * @retval = 0 -> Success + * @retval > 0 -> Warning + * @retval < 0 -> Error + */ +int8_t bma530_set_feat_eng_gpr_0(const struct bma530_feat_eng_gpr_0 *config, struct bma5_dev *dev); + +/*! + * \ingroup bma530ApiRegs + * \page bma530_api_bma530_get_feat_eng_gpr_1 bma530_get_feat_eng_gpr_1 + * \code + * int8_t bma530_get_feat_eng_gpr_1(struct bma530_feat_eng_gpr_1 *config, struct bma5_dev *dev); + * \endcode + * @details This API carries the provision to get the feature engine ('feat_eng') general purpose register 1 + * + * @param[out] config : Structure instance of bma530_feat_eng_gpr_1 + * @param[in] dev : Structure instance of bma5_dev. + * + * @return Result of API execution status + * + * @retval = 0 -> Success + * @retval > 0 -> Warning + * @retval < 0 -> Error + */ +int8_t bma530_get_feat_eng_gpr_1(struct bma530_feat_eng_gpr_1 *config, struct bma5_dev *dev); + +/*! + * \ingroup bma530ApiRegs + * \page bma530_api_bma530_get_feat_eng_gpr_1 bma530_get_feat_eng_gpr_1 + * \code + * int8_t bma530_set_feat_eng_gpr_1(const struct bma530_feat_eng_gpr_1 *config, struct bma5_dev *dev); + * \endcode + * @details This API carries the provision to set the feature engine ('feat_eng') general purpose register 1 + * + * @param[in] config : Structure instance of bma530_feat_eng_gpr_1 + * @param[in] dev : Structure instance of bma5_dev. + * + * @return Result of API execution status + * + * @retval = 0 -> Success + * @retval > 0 -> Warning + * @retval < 0 -> Error + */ +int8_t bma530_set_feat_eng_gpr_1(const struct bma530_feat_eng_gpr_1 *config, struct bma5_dev *dev); + +/*! + * \ingroup bma530ApiRegs + * \page bma530_api_bma530_get_feat_eng_gpr_2 bma530_get_feat_eng_gpr_2 + * \code + * int8_t bma530_get_feat_eng_gpr_2(uint8_t *step_cnt_out_0, struct bma5_dev *dev); + * \endcode + * @details This API carries the provision to get the feature engine ('feat_eng') general purpose register 2 + * + * @param[out] step_cnt_out_0 : Step counter value byte-0 + * @param[in] dev : Structure instance of bma5_dev. + * + * @return Result of API execution status + * + * @retval = 0 -> Success + * @retval > 0 -> Warning + * @retval < 0 -> Error + */ +int8_t bma530_get_feat_eng_gpr_2(uint8_t *step_cnt_out_0, struct bma5_dev *dev); + +/*! + * \ingroup bma530ApiRegs + * \page bma530_api_bma530_get_feat_eng_gpr_3 bma530_get_feat_eng_gpr_3 + * \code + * int8_t bma530_get_feat_eng_gpr_3(uint8_t *step_cnt_out_1, struct bma5_dev *dev); + * \endcode + * @details This API carries the provision to get the feature engine ('feat_eng') general purpose register 3 + * + * @param[out] step_cnt_out_1 : Step counter value byte-1 + * @param[in] dev : Structure instance of bma5_dev. + * + * @return Result of API execution status + * + * @retval = 0 -> Success + * @retval > 0 -> Warning + * @retval < 0 -> Error + */ +int8_t bma530_get_feat_eng_gpr_3(uint8_t *step_cnt_out_1, struct bma5_dev *dev); + +/*! + * \ingroup bma530ApiRegs + * \page bma530_api_bma530_get_feat_eng_gpr_4 bma530_get_feat_eng_gpr_4 + * \code + * int8_t bma530_get_feat_eng_gpr_4(uint8_t *step_cnt_out_2, struct bma5_dev *dev); + * \endcode + * @details This API carries the provision to get the feature engine ('feat_eng') general purpose register 4 + * + * @param[out] step_cnt_out_2 : Step counter value byte-2 + * @param[in] dev : Structure instance of bma5_dev. + * + * @return Result of API execution status + * + * @retval = 0 -> Success + * @retval > 0 -> Warning + * @retval < 0 -> Error + */ +int8_t bma530_get_feat_eng_gpr_4(uint8_t *step_cnt_out_2, struct bma5_dev *dev); + +/*! + * \ingroup bma530ApiRegs + * \page bma530_api_bma530_get_feat_eng_gpr_5 bma530_get_feat_eng_gpr_5 + * \code + * int8_t bma530_get_feat_eng_gpr_5(struct bma530_feat_eng_gpr_5 *config, struct bma5_dev *dev); + * \endcode + * @details This API carries the provision to get the feature engine ('feat_eng') general purpose register 5 + * + * @param[out] config : Structure instance of bma530_feat_eng_gpr_5 + * @param[in] dev : Structure instance of bma5_dev. + * + * @return Result of API execution status + * + * @retval = 0 -> Success + * @retval > 0 -> Warning + * @retval < 0 -> Error + */ +int8_t bma530_get_feat_eng_gpr_5(struct bma530_feat_eng_gpr_5 *config, struct bma5_dev *dev); + +#ifdef __cplusplus +} +#endif /* End of CPP guard */ + +#endif /*_BMA530_H */ diff --git a/bma530_context.h b/bma530_context.h new file mode 100644 index 0000000..0cd7344 --- /dev/null +++ b/bma530_context.h @@ -0,0 +1,176 @@ +/** +* Copyright (c) 2024 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 bma530_context.h +* @date 2024-04-15 +* @version v4.1.0 +* +*/ + +#ifndef _BMA530_CONTEXT_H +#define _BMA530_CONTEXT_H + +/*! CPP guard */ +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************/ +/****************************** Header files **********************************/ +/******************************************************************************/ + +#include "bma530.h" + +/******************************************************************************/ +/********************* Macros for context parameters **************************/ +/******************************************************************************/ +#define BMA530_GENERIC_INTERRUPT1_1_GI1_SLOPE_THRES_S UINT16_C(15) +#define BMA530_GENERIC_INTERRUPT1_1_GI1_SLOPE_THRES_W UINT16_C(13) +#define BMA530_GENERIC_INTERRUPT1_1_GI1_SLOPE_THRES_H UINT16_C(12) + +#define BMA530_GENERIC_INTERRUPT1_2_GI1_HYSTERESIS_S UINT16_C(3) +#define BMA530_GENERIC_INTERRUPT1_2_GI1_HYSTERESIS_W UINT16_C(2) +#define BMA530_GENERIC_INTERRUPT1_2_GI1_HYSTERESIS_H UINT16_C(4) + +#define BMA530_GENERIC_INTERRUPT2_1_GI2_SLOPE_THRES_S UINT16_C(15) +#define BMA530_GENERIC_INTERRUPT2_1_GI2_SLOPE_THRES_W UINT16_C(12) +#define BMA530_GENERIC_INTERRUPT2_1_GI2_SLOPE_THRES_H UINT16_C(8) + +#define BMA530_GENERIC_INTERRUPT2_2_GI2_HYSTERESIS_S UINT16_C(3) +#define BMA530_GENERIC_INTERRUPT2_2_GI2_HYSTERESIS_W UINT16_C(2) +#define BMA530_GENERIC_INTERRUPT2_2_GI2_HYSTERESIS_H UINT16_C(1) + +#define BMA530_STEP_COUNTER_2_ENVELOPE_UP_THRES_S UINT16_C(306) +#define BMA530_STEP_COUNTER_2_ENVELOPE_UP_THRES_W UINT16_C(301) +#define BMA530_STEP_COUNTER_2_ENVELOPE_UP_THRES_H UINT16_C(307) + +#define BMA530_STEP_COUNTER_3_ENVELOPE_UP_DECAY_COEFF_S UINT16_C(61900) +#define BMA530_STEP_COUNTER_3_ENVELOPE_UP_DECAY_COEFF_W UINT16_C(63400) +#define BMA530_STEP_COUNTER_3_ENVELOPE_UP_DECAY_COEFF_H UINT16_C(61932) + +#define BMA530_STEP_COUNTER_4_ENVELOPE_DOWN_THRES_S UINT16_C(132) +#define BMA530_STEP_COUNTER_4_ENVELOPE_DOWN_THRES_W UINT16_C(315) +#define BMA530_STEP_COUNTER_4_ENVELOPE_DOWN_THRES_H UINT16_C(133) + +#define BMA530_STEP_COUNTER_5_ENVELOPE_DOWN_DECAY_COEFF_S UINT16_C(55608) +#define BMA530_STEP_COUNTER_5_ENVELOPE_DOWN_DECAY_COEFF_W UINT16_C(62902) +#define BMA530_STEP_COUNTER_5_ENVELOPE_DOWN_DECAY_COEFF_H UINT16_C(55706) + +#define BMA530_STEP_COUNTER_6_ACC_MEAN_DECAY_COEFF_S UINT16_C(60104) +#define BMA530_STEP_COUNTER_6_ACC_MEAN_DECAY_COEFF_W UINT16_C(63102) +#define BMA530_STEP_COUNTER_6_ACC_MEAN_DECAY_COEFF_H UINT16_C(62260) + +#define BMA530_STEP_COUNTER_7_STEP_DUR_MEAN_DECAY_COEFF_S UINT16_C(64852) +#define BMA530_STEP_COUNTER_7_STEP_DUR_MEAN_DECAY_COEFF_W UINT16_C(55706) +#define BMA530_STEP_COUNTER_7_STEP_DUR_MEAN_DECAY_COEFF_H UINT16_C(58982) + +#define BMA530_STEP_COUNTER_8_STEP_BUFFER_SIZE_S UINT16_C(7) +#define BMA530_STEP_COUNTER_8_STEP_BUFFER_SIZE_W UINT16_C(4) +#define BMA530_STEP_COUNTER_8_STEP_BUFFER_SIZE_H UINT16_C(7) + +#define BMA530_STEP_COUNTER_8_FILTER_CASCADE_ENABLED_S UINT16_C(1) +#define BMA530_STEP_COUNTER_8_FILTER_CASCADE_ENABLED_W UINT16_C(1) +#define BMA530_STEP_COUNTER_8_FILTER_CASCADE_ENABLED_H UINT16_C(1) + +#define BMA530_STEP_COUNTER_8_STEP_COUNTER_INCREMENT_S UINT16_C(256) +#define BMA530_STEP_COUNTER_8_STEP_COUNTER_INCREMENT_W UINT16_C(256) +#define BMA530_STEP_COUNTER_8_STEP_COUNTER_INCREMENT_H UINT16_C(256) + +#define BMA530_STEP_COUNTER_8_EN_HALF_STEP_S UINT16_C(0) +#define BMA530_STEP_COUNTER_8_EN_HALF_STEP_W UINT16_C(1) +#define BMA530_STEP_COUNTER_8_EN_HALF_STEP_H UINT16_C(0) + +#define BMA530_STEP_COUNTER_9_PEAK_DURATION_MIN_WALKING_S UINT16_C(12) +#define BMA530_STEP_COUNTER_9_PEAK_DURATION_MIN_WALKING_W UINT16_C(39) +#define BMA530_STEP_COUNTER_9_PEAK_DURATION_MIN_WALKING_H UINT16_C(13) + +#define BMA530_STEP_COUNTER_9_PEAK_DURATION_MIN_RUNNING_S UINT16_C(12) +#define BMA530_STEP_COUNTER_9_PEAK_DURATION_MIN_RUNNING_W UINT16_C(25) +#define BMA530_STEP_COUNTER_9_PEAK_DURATION_MIN_RUNNING_H UINT16_C(12) + +#define BMA530_STEP_COUNTER_10_ACTIVITY_DETECTION_FACTOR_S UINT16_C(3) +#define BMA530_STEP_COUNTER_10_ACTIVITY_DETECTION_FACTOR_W UINT16_C(3) +#define BMA530_STEP_COUNTER_10_ACTIVITY_DETECTION_FACTOR_H UINT16_C(3) + +#define BMA530_STEP_COUNTER_10_ACTIVITY_DETECTION_THRES_S UINT16_C(3900) +#define BMA530_STEP_COUNTER_10_ACTIVITY_DETECTION_THRES_W UINT16_C(3900) +#define BMA530_STEP_COUNTER_10_ACTIVITY_DETECTION_THRES_H UINT16_C(3900) + +#define BMA530_STEP_COUNTER_11_STEP_DURATION_MAX_S UINT16_C(74) +#define BMA530_STEP_COUNTER_11_STEP_DURATION_MAX_W UINT16_C(150) +#define BMA530_STEP_COUNTER_11_STEP_DURATION_MAX_H UINT16_C(74) + +#define BMA530_STEP_COUNTER_11_STEP_DURATION_WINDOW_S UINT16_C(160) +#define BMA530_STEP_COUNTER_11_STEP_DURATION_WINDOW_W UINT16_C(160) +#define BMA530_STEP_COUNTER_11_STEP_DURATION_WINDOW_H UINT16_C(160) + +#define BMA530_STEP_COUNTER_12_EN_STEP_DUR_PP_S UINT16_C(0) +#define BMA530_STEP_COUNTER_12_EN_STEP_DUR_PP_W UINT16_C(1) +#define BMA530_STEP_COUNTER_12_EN_STEP_DUR_PP_H UINT16_C(1) + +#define BMA530_STEP_COUNTER_12_STEP_DUR_THRES_S UINT16_C(0) +#define BMA530_STEP_COUNTER_12_STEP_DUR_THRES_W UINT16_C(3) +#define BMA530_STEP_COUNTER_12_STEP_DUR_THRES_H UINT16_C(3) + +#define BMA530_STEP_COUNTER_12_EN_MCR_PP_S UINT16_C(0) +#define BMA530_STEP_COUNTER_12_EN_MCR_PP_W UINT16_C(1) +#define BMA530_STEP_COUNTER_12_EN_MCR_PP_H UINT16_C(1) + +#define BMA530_STEP_COUNTER_12_MCR_THRES_S UINT16_C(0) +#define BMA530_STEP_COUNTER_12_MCR_THRES_W UINT16_C(14) +#define BMA530_STEP_COUNTER_12_MCR_THRES_H UINT16_C(8) + +#define BMA530_SIG_MOTION_1_BLOCK_SIZE_S UINT16_C(250) +#define BMA530_SIG_MOTION_1_BLOCK_SIZE_W UINT16_C(250) +#define BMA530_SIG_MOTION_1_BLOCK_SIZE_H UINT16_C(250) + +#define BMA530_SIG_MOTION_2_P2P_MIN_S UINT16_C(60) +#define BMA530_SIG_MOTION_2_P2P_MIN_W UINT16_C(150) +#define BMA530_SIG_MOTION_2_P2P_MIN_H UINT16_C(38) + +#define BMA530_SIG_MOTION_2_MCR_MIN_S UINT16_C(11) +#define BMA530_SIG_MOTION_2_MCR_MIN_W UINT16_C(8) +#define BMA530_SIG_MOTION_2_MCR_MIN_H UINT16_C(8) + +#define BMA530_SIG_MOTION_3_P2P_MAX_S UINT16_C(595) +#define BMA530_SIG_MOTION_3_P2P_MAX_W UINT16_C(595) +#define BMA530_SIG_MOTION_3_P2P_MAX_H UINT16_C(400) + +#define BMA530_SIG_MOTION_3_MCR_MAX_S UINT16_C(17) +#define BMA530_SIG_MOTION_3_MCR_MAX_W UINT16_C(17) +#define BMA530_SIG_MOTION_3_MCR_MAX_H UINT16_C(17) + +#ifdef __cplusplus +} +#endif /* End of CPP guard */ + +#endif /* _BMA530_CONTEXT_H */ diff --git a/bma530_features.c b/bma530_features.c new file mode 100644 index 0000000..ca5d821 --- /dev/null +++ b/bma530_features.c @@ -0,0 +1,2496 @@ +/** +* Copyright (c) 2024 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 bma530_features.c +* @date 2024-04-15 +* @version v4.1.0 +* +*/ + +/******************************************************************************/ +/****************************** Header files **********************************/ +/******************************************************************************/ + +#include "bma530_features.h" + +/******************************************************************************/ +/*********************** Static function declarations *************************/ +/******************************************************************************/ + +/*! + * @brief Internal API to verify the validity of the primary device handle which + * is passed as argument. + * + * @param[in] dev : Structure instance of bma5_dev. + * + * @return Result of API execution status + * @retval BMA5_OK -> device handle is valid + * @retval BMA5_E_NULL_PTR -> Null pointer error + */ +static int8_t verify_handle(const struct bma5_dev *dev); + +/******************************************************************************/ +/*********************** User function definitions ****************************/ +/******************************************************************************/ + +/*! + * @brief This API is the entry point. + * Call this API before using all other APIs. + * This API reads the chip-id of the sensor which is the first step to + * verify the sensor and also it configures the read mechanism of SPI and + * I2C interface. + */ +int8_t bma530_init(struct bma5_dev *dev) +{ + /* Variable to store the function result */ + int8_t result; + + /* Variable to get chip id */ + uint8_t data = 0; + + /* Null-pointer check */ + result = verify_handle(dev); + + if (result == BMA5_OK) + { + dev->chip_id = 0; + + if (dev->intf == BMA5_SPI_INTF) + { + dev->dummy_byte = 1; + } + else + { + dev->dummy_byte = 0; + } + + /* Dummy read results in NACK. Hence result is not checked */ + (void) bma5_get_regs(BMA530_REG_CHIP_ID, &data, 1, dev); + + result = bma5_get_regs(BMA530_REG_CHIP_ID, &data, 1, dev); + + if (result == BMA5_OK) + { + /* Assign Chip Id */ + dev->chip_id = data; + } + + if (dev->chip_id != BMA530_CHIP_ID) + { + result = BMA5_E_DEV_NOT_FOUND; + } + } + else + { + result = BMA5_E_NULL_PTR; + } + + return result; +} + +/*! + * @brief This API gets feature output status from the register. + */ +int8_t bma530_get_feat_eng_feature_out(struct bma530_feat_eng_feat_out *feat_out, struct bma5_dev *dev) +{ + /* Variable to store the function result */ + int8_t result; + + /* Array to store feature engine GPR feature outputs */ + uint8_t reg_data[5]; + + /* Array to store step counter data */ + uint8_t step_cntr[3]; + + if (feat_out == NULL) + { + result = BMA5_E_NULL_PTR; + } + else + { + /* Get the feature engine GPR feature output data */ + result = bma5_get_regs(BMA530_REG_FEAT_ENG_GPR_1, reg_data, 5, dev); + + if (result == BMA5_OK) + { + step_cntr[0] = BMA5_GET_BITS_POS_0(reg_data[1], BMA530_STEP_CNT_OUT_0); + step_cntr[1] = BMA5_GET_BITS_POS_0(reg_data[2], BMA530_STEP_CNT_OUT_1); + step_cntr[2] = BMA5_GET_BITS_POS_0(reg_data[3], BMA530_STEP_CNT_OUT_2); + + feat_out->step_cntr_out = + (uint32_t)(step_cntr[0] | ((uint16_t)step_cntr[1] << 8) | ((uint32_t)step_cntr[2] << 16)); + + feat_out->orientation_portrait_landscape = BMA5_GET_BITS_POS_0(reg_data[4], + BMA530_ORIENTATION_PORTRAIT_LANDSCAPE); + feat_out->activ_stat = BMA5_GET_BITS(reg_data[4], BMA530_ACTIV_STAT); + + feat_out->orientation_face_up_down = BMA5_GET_BITS(reg_data[4], BMA530_ORIENTATION_FACE_UP_DOWN); + + feat_out->gen_int1_stat = BMA5_GET_BITS(reg_data[4], BMA530_GEN_INT1_STAT); + + feat_out->gen_int2_stat = BMA5_GET_BITS(reg_data[4], BMA530_GEN_INT2_STAT); + + feat_out->gen_int3_stat = BMA5_GET_BITS(reg_data[4], BMA530_GEN_INT3_STAT); + } + } + + return result; +} + +/*! + * @brief This API sets feature configuration error status + */ +int8_t bma530_set_feat_conf_err(const struct bma530_feat_conf_err *feat_conf_err, struct bma5_dev *dev) +{ + /* Variable to define error */ + int8_t result = BMA5_OK; + + /* Variable to store base address of feature config error */ + uint8_t data = BMA530_BASE_ADDR_FEAT_CONF_ERR; + + /* Array to store feature config error data */ + uint8_t feat_conf_err_data[4] = { 0 }; + + if (feat_conf_err == NULL) + { + result = BMA5_E_NULL_PTR; + } + else + { + /* Set the feature config error base address to feature engine transmission address to start DMA transaction */ + result = bma5_set_regs(BMA5_REG_FEATURE_DATA_ADDR, &data, 1, dev); + + if (result == BMA5_OK) + { + /* Get the configuration from the feature engine register */ + result = bma5_get_regs(BMA5_REG_FEATURE_DATA_TX, feat_conf_err_data, 4, dev); + + if (result == BMA5_OK) + { + feat_conf_err_data[2] = BMA5_SET_BITS(feat_conf_err_data[2], + BMA530_GEN_INT1_CONF_ERR, + feat_conf_err->gen_int1_conf_err); + + feat_conf_err_data[2] = BMA5_SET_BITS(feat_conf_err_data[2], + BMA530_GEN_INT2_CONF_ERR, + feat_conf_err->gen_int2_conf_err); + + feat_conf_err_data[2] = BMA5_SET_BITS(feat_conf_err_data[2], + BMA530_GEN_INT3_CONF_ERR, + feat_conf_err->gen_int3_conf_err); + + feat_conf_err_data[2] = BMA5_SET_BITS(feat_conf_err_data[2], + BMA530_STEP_CONF_ERR, + feat_conf_err->step_conf_err); + + feat_conf_err_data[2] = BMA5_SET_BITS(feat_conf_err_data[2], + BMA530_SIG_MO_CONF_ERR, + feat_conf_err->sig_mo_conf_err); + + feat_conf_err_data[2] = BMA5_SET_BITS(feat_conf_err_data[2], + BMA530_TILT_CONF_ERR, + feat_conf_err->tilt_conf_err); + + feat_conf_err_data[2] = BMA5_SET_BITS(feat_conf_err_data[2], + BMA530_ORIENT_CONF_ERR, + feat_conf_err->orient_conf_err); + + feat_conf_err_data[2] = BMA5_SET_BITS(feat_conf_err_data[2], + BMA530_ACC_FOC_CONF_ERR, + feat_conf_err->acc_foc_conf_err); + + feat_conf_err_data[0] = feat_conf_err_data[2]; + feat_conf_err_data[1] = feat_conf_err_data[3]; + + /* Set the configuration from the feature engine register */ + result = bma5_set_regs(BMA5_REG_FEATURE_DATA_TX, feat_conf_err_data, 2, dev); + } + } + } + + return result; +} + +/*! + * @brief This API gets feature configuration error status + */ +int8_t bma530_get_feat_conf_err(struct bma530_feat_conf_err *feat_conf_err, struct bma5_dev *dev) +{ + /* Variable to define error */ + int8_t result = BMA5_OK; + + /* Variable to store base address of feature config error */ + uint8_t data = BMA530_BASE_ADDR_FEAT_CONF_ERR; + + /* Array to store feature config error data */ + uint8_t feat_conf_err_data[4] = { 0 }; + + if (feat_conf_err == NULL) + { + result = BMA5_E_NULL_PTR; + } + else + { + /* Set the feature config error base address to feature engine transmission address to start DMA transaction */ + result = bma5_set_regs(BMA5_REG_FEATURE_DATA_ADDR, &data, 1, dev); + + if (result == BMA5_OK) + { + /* Get the configuration from the feature engine register */ + result = bma5_get_regs(BMA5_REG_FEATURE_DATA_TX, feat_conf_err_data, 4, dev); + + if (result == BMA5_OK) + { + feat_conf_err->gen_int1_conf_err = BMA5_GET_BITS(feat_conf_err_data[2], BMA530_GEN_INT1_CONF_ERR); + feat_conf_err->gen_int2_conf_err = BMA5_GET_BITS(feat_conf_err_data[2], BMA530_GEN_INT2_CONF_ERR); + feat_conf_err->gen_int3_conf_err = BMA5_GET_BITS(feat_conf_err_data[2], BMA530_GEN_INT3_CONF_ERR); + feat_conf_err->step_conf_err = BMA5_GET_BITS(feat_conf_err_data[2], BMA530_STEP_CONF_ERR); + feat_conf_err->sig_mo_conf_err = BMA5_GET_BITS(feat_conf_err_data[2], BMA530_SIG_MO_CONF_ERR); + feat_conf_err->tilt_conf_err = BMA5_GET_BITS(feat_conf_err_data[2], BMA530_TILT_CONF_ERR); + feat_conf_err->orient_conf_err = BMA5_GET_BITS(feat_conf_err_data[2], BMA530_ORIENT_CONF_ERR); + feat_conf_err->acc_foc_conf_err = BMA5_GET_BITS(feat_conf_err_data[2], BMA530_ACC_FOC_CONF_ERR); + + } + } + } + + return result; +} + +/*! + * @brief This API sets android compatibility mode + */ +int8_t bma530_set_android_comp_mode(const uint8_t *android_comp, struct bma5_dev *dev) +{ + /* Variable to define error */ + int8_t result = BMA5_OK; + + /* Variable to store base address of android compatibility mode */ + uint8_t data = BMA530_BASE_ADDR_GENERAL_SETTINGS; + + /* Array to store android compatibility mode data */ + uint8_t android_comp_data[4] = { 0 }; + + if (android_comp == NULL) + { + result = BMA5_E_NULL_PTR; + } + else + { + /* Set the feature axis base address to feature engine transmission address to start DMA transaction */ + result = bma5_set_regs(BMA5_REG_FEATURE_DATA_ADDR, &data, 1, dev); + + if (result == BMA5_OK) + { + /* Get the configuration from the feature engine register */ + result = bma5_get_regs(BMA5_REG_FEATURE_DATA_TX, android_comp_data, 4, dev); + + if (result == BMA5_OK) + { + android_comp_data[2] = BMA5_SET_BITS_POS_0(android_comp_data[2], BMA530_ANDROID_COMP, (*android_comp)); + + android_comp_data[0] = android_comp_data[2]; + android_comp_data[1] = android_comp_data[3]; + + /* Set the configuration from the feature engine register */ + result = bma5_set_regs(BMA5_REG_FEATURE_DATA_TX, android_comp_data, 2, dev); + } + } + } + + return result; +} + +/*! + * @brief This API gets android compatibility mode + */ +int8_t bma530_get_android_comp_mode(uint8_t *android_comp, struct bma5_dev *dev) +{ + /* Variable to define error */ + int8_t result = BMA5_OK; + + /* Variable to store base address of android compatibility mode */ + uint8_t data = BMA530_BASE_ADDR_GENERAL_SETTINGS; + + /* Array to store android compatibility mode data */ + uint8_t android_comp_data[4] = { 0 }; + + if (android_comp == NULL) + { + result = BMA5_E_NULL_PTR; + } + else + { + /* Set the feature axis base address to feature engine transmission address to start DMA transaction */ + result = bma5_set_regs(BMA5_REG_FEATURE_DATA_ADDR, &data, 1, dev); + + if (result == BMA5_OK) + { + /* Get the configuration from the feature engine register */ + result = bma5_get_regs(BMA5_REG_FEATURE_DATA_TX, android_comp_data, 4, dev); + + if (result == BMA5_OK) + { + (*android_comp) = BMA5_GET_BITS_POS_0(android_comp_data[2], BMA530_ANDROID_COMP); + } + } + } + + return result; +} + +/*! + * @brief This API sets step counter configuration + */ +int8_t bma530_set_step_counter_config(const struct bma530_step_cntr *step_cntr, struct bma5_dev *dev) +{ + /* Variable to define error */ + int8_t result = BMA5_OK; + + /* Variable to store base address of step counter */ + uint8_t data = BMA530_BASE_ADDR_STEP_COUNTER; + + /* Array to store step counter data */ + uint8_t sc_data[38] = { 0 }; + + /* Variable to store the data to be written in register */ + uint16_t watermark_level_1, watermark_level_2, reset_counter, sd_en, sc_en; + uint16_t envelope_up_thres_1, envelope_up_thres_2, envelope_up_decay_coeff_1, envelope_up_decay_coeff_2; + uint16_t envelope_down_thres_1, envelope_down_thres_2, envelope_down_decay_coeff_1, envelope_down_decay_coeff_2; + uint16_t acc_mean_decay_coeff_1, acc_mean_decay_coeff_2, step_dur_mean_decay_coeff_1, step_dur_mean_decay_coeff_2; + uint16_t step_buffer_size, filter_cascade_enabled, step_counter_increment_1, step_counter_increment_2; + uint16_t en_half_step, peak_duration_min_walking, peak_duration_min_running, activity_detection_factor; + uint16_t activity_detection_thres_1, activity_detection_thres_2, step_duration_max, step_duration_window, + en_step_dur_pp, step_dur_thres; + uint16_t en_mcr_pp, mcr_thres_1, mcr_thres_2, filter_coeff_b_2_1, filter_coeff_b_2_2, filter_coeff_b_1_1, + filter_coeff_b_1_2; + uint16_t filter_coeff_b_0_1, filter_coeff_b_0_2, filter_coeff_a_2_1, filter_coeff_a_2_2; + uint16_t filter_coeff_a_1_1, filter_coeff_a_1_2, filter_coeff_scale_a, filter_coeff_scale_b; + + if (step_cntr == NULL) + { + result = BMA5_E_NULL_PTR; + } + else + { + /* Set the step counter base address to feature engine transmission address to start DMA transaction */ + result = bma5_set_regs(BMA5_REG_FEATURE_DATA_ADDR, &data, 1, dev); + + if (result == BMA5_OK) + { + /* Get the configuration from the feature engine register */ + result = bma5_get_regs(BMA5_REG_FEATURE_DATA_TX, sc_data, 38, dev); + + if (result == BMA5_OK) + { + /* Settings 1 */ + watermark_level_1 = + (BMA5_SET_BITS_POS_0(sc_data[2], BMA530_SC_WATERMARK_LVL, + step_cntr->watermark_level) & BMA530_SC_WATERMARK_LVL_MSK); + + watermark_level_2 = (uint16_t)(sc_data[3] << 8); + + watermark_level_2 = + (BMA5_SET_BITS_POS_0(watermark_level_2, BMA530_SC_WATERMARK_LVL, + step_cntr->watermark_level) & BMA530_SC_WATERMARK_LVL_MSK); + + reset_counter = + (BMA5_SET_BITS(sc_data[3], BMA530_SC_RESET_COUNTER, + step_cntr->reset_counter) & BMA530_SC_RESET_COUNTER_MSK); + + sd_en = (BMA5_SET_BITS(sc_data[3], BMA530_SC_SD_EN, step_cntr->sd_en) & BMA530_SC_SD_EN_MSK); + + sc_en = (BMA5_SET_BITS(sc_data[3], BMA530_SC_SC_EN, step_cntr->sc_en) & BMA530_SC_SC_EN_MSK); + + /* Settings 2 */ + envelope_up_thres_1 = + (BMA5_SET_BITS_POS_0(sc_data[4], BMA530_SC_ENVELOPE_UP_THRES, + step_cntr->envelope_up_thres) & BMA530_SC_ENVELOPE_UP_THRES_MSK); + + envelope_up_thres_2 = (uint16_t)(sc_data[5] << 8); + + envelope_up_thres_2 = + (BMA5_SET_BITS_POS_0(envelope_up_thres_2, BMA530_SC_ENVELOPE_UP_THRES, + step_cntr->envelope_up_thres) & BMA530_SC_ENVELOPE_UP_THRES_MSK); + + /* Settings 3 */ + envelope_up_decay_coeff_1 = + (BMA5_SET_BITS_POS_0(sc_data[6], BMA530_SC_ENVELOPE_UP_DECAY_COEFF, + step_cntr->envelope_up_decay_coeff) & BMA530_SC_ENVELOPE_UP_DECAY_COEFF_MSK); + + envelope_up_decay_coeff_2 = (uint16_t)(sc_data[7] << 8); + + envelope_up_decay_coeff_2 = + (BMA5_SET_BITS_POS_0(envelope_up_decay_coeff_2, BMA530_SC_ENVELOPE_UP_DECAY_COEFF, + step_cntr->envelope_up_decay_coeff) & BMA530_SC_ENVELOPE_UP_DECAY_COEFF_MSK); + + /* Settings 4 */ + envelope_down_thres_1 = + (BMA5_SET_BITS_POS_0(sc_data[8], BMA530_SC_ENVELOPE_DOWN_THRES, + step_cntr->envelope_down_thres) & BMA530_SC_ENVELOPE_DOWN_THRES_MSK); + + envelope_down_thres_2 = (uint16_t)(sc_data[9] << 8); + + envelope_down_thres_2 = + (BMA5_SET_BITS_POS_0(envelope_down_thres_2, BMA530_SC_ENVELOPE_DOWN_THRES, + step_cntr->envelope_down_thres) & BMA530_SC_ENVELOPE_DOWN_THRES_MSK); + + /* Settings 5 */ + envelope_down_decay_coeff_1 = + (BMA5_SET_BITS_POS_0(sc_data[10], BMA530_SC_ENVELOPE_DOWN_DECAY_COEFF, + step_cntr->envelope_down_decay_coeff) & + BMA530_SC_ENVELOPE_DOWN_DECAY_COEFF_MSK); + + envelope_down_decay_coeff_2 = (uint16_t)(sc_data[11] << 8); + + envelope_down_decay_coeff_2 = + (BMA5_SET_BITS_POS_0(envelope_down_decay_coeff_2, BMA530_SC_ENVELOPE_DOWN_DECAY_COEFF, + step_cntr->envelope_down_decay_coeff) & + BMA530_SC_ENVELOPE_DOWN_DECAY_COEFF_MSK); + + /* Settings 6 */ + acc_mean_decay_coeff_1 = + (BMA5_SET_BITS_POS_0(sc_data[12], BMA530_SC_ACC_MEAN_DECAY_COEFF, + step_cntr->acc_mean_decay_coeff) & BMA530_SC_ACC_MEAN_DECAY_COEFF_MSK); + + acc_mean_decay_coeff_2 = (uint16_t)(sc_data[13] << 8); + + acc_mean_decay_coeff_2 = + (BMA5_SET_BITS_POS_0(acc_mean_decay_coeff_2, BMA530_SC_ACC_MEAN_DECAY_COEFF, + step_cntr->acc_mean_decay_coeff) & BMA530_SC_ACC_MEAN_DECAY_COEFF_MSK); + + /* Settings 7 */ + step_dur_mean_decay_coeff_1 = + (BMA5_SET_BITS_POS_0(sc_data[14], BMA530_SC_STEP_DUR_MEAN_DECAY_COEFF, + step_cntr->step_dur_mean_decay_coeff) & + BMA530_SC_STEP_DUR_MEAN_DECAY_COEFF_MSK); + + step_dur_mean_decay_coeff_2 = (uint16_t)(sc_data[15] << 8); + + step_dur_mean_decay_coeff_2 = + (BMA5_SET_BITS_POS_0(step_dur_mean_decay_coeff_2, BMA530_SC_STEP_DUR_MEAN_DECAY_COEFF, + step_cntr->step_dur_mean_decay_coeff) & + BMA530_SC_STEP_DUR_MEAN_DECAY_COEFF_MSK); + + /* Settings 8 */ + step_buffer_size = + (BMA5_SET_BITS_POS_0(sc_data[16], BMA530_SC_STEP_BUFFER_SIZE, + step_cntr->step_buffer_size) & BMA530_SC_STEP_BUFFER_SIZE_MSK); + + filter_cascade_enabled = + (BMA5_SET_BITS(sc_data[16], BMA530_SC_FILTER_CASCADE_ENABLED, + step_cntr->filter_cascade_enabled) & BMA530_SC_FILTER_CASCADE_ENABLED_MSK); + + step_counter_increment_1 = + (BMA5_SET_BITS(sc_data[16], BMA530_SC_STEP_COUNTER_INCREAMENT, + step_cntr->step_counter_increment) & BMA530_SC_STEP_COUNTER_INCREAMENT_MSK); + + step_counter_increment_2 = (uint16_t)(sc_data[17] << 8); + + step_counter_increment_2 = + (BMA5_SET_BITS(step_counter_increment_2, BMA530_SC_STEP_COUNTER_INCREAMENT, + step_cntr->step_counter_increment) & BMA530_SC_STEP_COUNTER_INCREAMENT_MSK); + + en_half_step = + (BMA5_SET_BITS(sc_data[17], BMA530_SC_EN_HALF_STEP, + step_cntr->en_half_step) & BMA530_SC_EN_HALF_STEP_MSK); + + /* Settings 9 */ + peak_duration_min_walking = + (BMA5_SET_BITS_POS_0(sc_data[18], BMA530_SC_PEAK_DUR_MIN_WALKING, + step_cntr->peak_duration_min_walking) & BMA530_SC_PEAK_DUR_MIN_WALKING_MSK); + + peak_duration_min_running = + (BMA5_SET_BITS(sc_data[19], BMA530_SC_PEAK_DUR_MIN_RUNNING, + step_cntr->peak_duration_min_running) & BMA530_SC_PEAK_DUR_MIN_RUNNING_MSK); + + /* Settings 10 */ + activity_detection_factor = + (BMA5_SET_BITS_POS_0(sc_data[20], BMA530_SC_ACTIVITY_DET_FACT, + step_cntr->activity_detection_factor) & BMA530_SC_ACTIVITY_DET_FACT_MSK); + + activity_detection_thres_1 = + (BMA5_SET_BITS(sc_data[20], BMA530_SC_ACTIVITY_DET_THRES, + step_cntr->activity_detection_thres) & BMA530_SC_ACTIVITY_DET_THRES_MSK); + + activity_detection_thres_2 = (uint16_t)(sc_data[21] << 8); + + activity_detection_thres_2 = + (BMA5_SET_BITS(activity_detection_thres_2, BMA530_SC_ACTIVITY_DET_THRES, + step_cntr->activity_detection_thres) & BMA530_SC_ACTIVITY_DET_THRES_MSK); + + /* Settings 11 */ + step_duration_max = + (BMA5_SET_BITS_POS_0(sc_data[22], BMA530_SC_STEP_DUR_MAX, + step_cntr->step_duration_max) & BMA530_SC_STEP_DUR_MAX_MSK); + + step_duration_window = + (BMA5_SET_BITS(sc_data[21], BMA530_SC_STEP_DUR_WINDOW, + step_cntr->step_duration_window) & BMA530_SC_STEP_DUR_WINDOW_MSK); + + /* Settings 12 */ + en_step_dur_pp = + (BMA5_SET_BITS_POS_0(sc_data[23], BMA530_SC_EN_STEP_DUR_PP, + step_cntr->en_step_dur_pp) & BMA530_SC_EN_STEP_DUR_PP_MSK); + + step_dur_thres = + (BMA5_SET_BITS(sc_data[24], BMA530_SC_STEP_DUR_THRES, + step_cntr->step_dur_thres) & BMA530_SC_STEP_DUR_THRES_MSK); + + en_mcr_pp = + (BMA5_SET_BITS(sc_data[24], BMA530_SC_EN_MCR_PP, step_cntr->en_mcr_pp) & BMA530_SC_EN_MCR_PP_MSK); + + mcr_thres_1 = + (BMA5_SET_BITS(sc_data[24], BMA530_SC_MCR_THRES, step_cntr->mcr_thres) & BMA530_SC_MCR_THRES_MSK); + + mcr_thres_2 = (uint16_t)(sc_data[25] << 8); + + mcr_thres_2 = + (BMA5_SET_BITS(mcr_thres_2, BMA530_SC_MCR_THRES, step_cntr->mcr_thres) & BMA530_SC_MCR_THRES_MSK); + + /* Settings 13 */ + filter_coeff_b_2_1 = + (BMA5_SET_BITS_POS_0(sc_data[26], BMA530_SC_FILTER_COEFF_B_2, + step_cntr->filter_coeff_b_2) & BMA530_SC_FILTER_COEFF_B_2_MSK); + + filter_coeff_b_2_2 = (uint16_t)(sc_data[27] << 8); + + filter_coeff_b_2_2 = + (BMA5_SET_BITS_POS_0(filter_coeff_b_2_2, BMA530_SC_FILTER_COEFF_B_2, + step_cntr->filter_coeff_b_2) & BMA530_SC_FILTER_COEFF_B_2_MSK); + + /* Settings 14 */ + filter_coeff_b_1_1 = + (BMA5_SET_BITS_POS_0(sc_data[28], BMA530_SC_FILTER_COEFF_B_1, + step_cntr->filter_coeff_b_1) & BMA530_SC_FILTER_COEFF_B_1_MSK); + + filter_coeff_b_1_2 = (uint16_t)(sc_data[29] << 8); + + filter_coeff_b_1_2 = + (BMA5_SET_BITS_POS_0(filter_coeff_b_1_2, BMA530_SC_FILTER_COEFF_B_1, + step_cntr->filter_coeff_b_1) & BMA530_SC_FILTER_COEFF_B_1_MSK); + + /* Settings 15 */ + filter_coeff_b_0_1 = + (BMA5_SET_BITS_POS_0(sc_data[30], BMA530_SC_FILTER_COEFF_B_0, + step_cntr->filter_coeff_b_0) & BMA530_SC_FILTER_COEFF_B_0_MSK); + + filter_coeff_b_0_2 = (uint16_t)(sc_data[31] << 8); + + filter_coeff_b_0_2 = + (BMA5_SET_BITS_POS_0(filter_coeff_b_0_2, BMA530_SC_FILTER_COEFF_B_0, + step_cntr->filter_coeff_b_0) & BMA530_SC_FILTER_COEFF_B_0_MSK); + + /* Settings 16 */ + filter_coeff_a_2_1 = + (BMA5_SET_BITS_POS_0(sc_data[32], BMA530_SC_FILTER_COEFF_A_2, + step_cntr->filter_coeff_a_2) & BMA530_SC_FILTER_COEFF_A_2_MSK); + + filter_coeff_a_2_2 = (uint16_t)(sc_data[33] << 8); + + filter_coeff_a_2_2 = + (BMA5_SET_BITS_POS_0(filter_coeff_a_2_2, BMA530_SC_FILTER_COEFF_A_2, + step_cntr->filter_coeff_a_2) & BMA530_SC_FILTER_COEFF_A_2_MSK); + + /* Settings 17 */ + filter_coeff_a_1_1 = + (BMA5_SET_BITS_POS_0(sc_data[34], BMA530_SC_FILTER_COEFF_A_1, + step_cntr->filter_coeff_a_1) & BMA530_SC_FILTER_COEFF_A_1_MSK); + + filter_coeff_a_1_2 = (uint16_t)(sc_data[35] << 8); + + filter_coeff_a_1_2 = + (BMA5_SET_BITS_POS_0(filter_coeff_a_1_2, BMA530_SC_FILTER_COEFF_A_1, + step_cntr->filter_coeff_a_1) & BMA530_SC_FILTER_COEFF_A_1_MSK); + + /* Settings 18 */ + filter_coeff_scale_a = + (BMA5_SET_BITS_POS_0(sc_data[36], BMA530_SC_FILTER_COEFF_SCALE_A, + step_cntr->filter_coeff_scale_a) & BMA530_SC_FILTER_COEFF_SCALE_A_MSK); + + filter_coeff_scale_b = + (BMA5_SET_BITS(sc_data[37], BMA530_SC_FILTER_COEFF_SCALE_B, + step_cntr->filter_coeff_scale_b) & BMA530_SC_FILTER_COEFF_SCALE_B_MSK); + + sc_data[0] = (uint8_t)watermark_level_1; + sc_data[1] = (uint8_t)((watermark_level_2 | reset_counter | sd_en | sc_en) >> 8); + sc_data[2] = (uint8_t)envelope_up_thres_1; + sc_data[3] = (uint8_t)(envelope_up_thres_2 >> 8); + sc_data[4] = (uint8_t)envelope_up_decay_coeff_1; + sc_data[5] = (uint8_t)(envelope_up_decay_coeff_2 >> 8); + sc_data[6] = (uint8_t)envelope_down_thres_1; + sc_data[7] = (uint8_t)(envelope_down_thres_2 >> 8); + sc_data[8] = (uint8_t)envelope_down_decay_coeff_1; + sc_data[9] = (uint8_t)(envelope_down_decay_coeff_2 >> 8); + sc_data[10] = (uint8_t)acc_mean_decay_coeff_1; + sc_data[11] = (uint8_t)(acc_mean_decay_coeff_2 >> 8); + sc_data[12] = (uint8_t)step_dur_mean_decay_coeff_1; + sc_data[13] = (uint8_t)(step_dur_mean_decay_coeff_2 >> 8); + sc_data[14] = (uint8_t)(step_buffer_size | filter_cascade_enabled | step_counter_increment_1); + sc_data[15] = (uint8_t)((step_counter_increment_2 | en_half_step) >> 8); + sc_data[16] = (uint8_t)peak_duration_min_walking; + sc_data[17] = (uint8_t)(peak_duration_min_running >> 8); + sc_data[18] = (uint8_t)(activity_detection_factor | activity_detection_thres_1); + sc_data[19] = (uint8_t)(activity_detection_thres_2 >> 8); + sc_data[20] = (uint8_t)step_duration_max; + sc_data[21] = (uint8_t)(step_duration_window >> 8); + sc_data[22] = (uint8_t)(en_step_dur_pp | step_dur_thres | en_mcr_pp | mcr_thres_1); + sc_data[23] = (uint8_t)(mcr_thres_2 >> 8); + sc_data[24] = (uint8_t)filter_coeff_b_2_1; + sc_data[25] = (uint8_t)(filter_coeff_b_2_2 >> 8); + sc_data[26] = (uint8_t)filter_coeff_b_1_1; + sc_data[27] = (uint8_t)(filter_coeff_b_1_2 >> 8); + sc_data[28] = (uint8_t)filter_coeff_b_0_1; + sc_data[29] = (uint8_t)(filter_coeff_b_0_2 >> 8); + sc_data[30] = (uint8_t)filter_coeff_a_2_1; + sc_data[31] = (uint8_t)(filter_coeff_a_2_2 >> 8); + sc_data[32] = (uint8_t)filter_coeff_a_1_1; + sc_data[33] = (uint8_t)(filter_coeff_a_1_2 >> 8); + sc_data[34] = (uint8_t)filter_coeff_scale_a; + sc_data[35] = (uint8_t)(filter_coeff_scale_b >> 8); + + /* Set the configuration from the feature engine register */ + result = bma5_set_regs(BMA5_REG_FEATURE_DATA_TX, sc_data, 36, dev); + } + } + } + + return result; +} + +/*! + * @brief This API gets step counter configuration + */ +int8_t bma530_get_step_counter_config(struct bma530_step_cntr *step_cntr, struct bma5_dev *dev) +{ + /* Variable to define error */ + int8_t result = BMA5_OK; + + /* Variable to store base address of step counter */ + uint8_t data = BMA530_BASE_ADDR_STEP_COUNTER; + + /* Array to store step counter data */ + uint8_t sc_data[38] = { 0 }; + + /* Variable to define array offset */ + uint8_t idx; + + /* Variable to define LSB */ + uint16_t lsb; + + /* Variable to define MSB */ + uint16_t msb; + + /* Variable to define a word */ + uint16_t lsb_msb; + + if (step_cntr == NULL) + { + result = BMA5_E_NULL_PTR; + } + else + { + /* Set the step counter base address to feature engine transmission address to start DMA transaction */ + result = bma5_set_regs(BMA5_REG_FEATURE_DATA_ADDR, &data, 1, dev); + + if (result == BMA5_OK) + { + /* Get the configuration from the feature engine register */ + result = bma5_get_regs(BMA5_REG_FEATURE_DATA_TX, sc_data, 38, dev); + + if (result == BMA5_OK) + { + /* First two bytes are dummy bytes */ + idx = 2; + + /* Settings 1 */ + /* Get word to calculate watermark_level, reset_counter, sd_en, and sc_en select from same word */ + lsb = (uint16_t) sc_data[idx++]; + msb = ((uint16_t) sc_data[idx++] << 8); + lsb_msb = (uint16_t)(lsb | msb); + + step_cntr->watermark_level = lsb_msb & BMA530_SC_WATERMARK_LVL_MSK; + + step_cntr->reset_counter = (lsb_msb & BMA530_SC_RESET_COUNTER_MSK) >> BMA530_SC_RESET_COUNTER_POS; + + step_cntr->sd_en = (lsb_msb & BMA530_SC_SD_EN_MSK) >> BMA530_SC_SD_EN_POS; + + step_cntr->sc_en = (lsb_msb & BMA530_SC_SC_EN_MSK) >> BMA530_SC_SC_EN_POS; + + /* Settings 2 */ + /* Get word to calculate envelope_up_thres */ + lsb = (uint16_t) sc_data[idx++]; + msb = ((uint16_t) sc_data[idx++] << 8); + lsb_msb = (uint16_t)(lsb | msb); + + step_cntr->envelope_up_thres = lsb_msb & BMA530_SC_ENVELOPE_UP_THRES_MSK; + + /* Settings 3 */ + /* Get word to calculate envelope_up_decay_coeff */ + lsb = (uint16_t) sc_data[idx++]; + msb = ((uint16_t) sc_data[idx++] << 8); + lsb_msb = (uint16_t)(lsb | msb); + + step_cntr->envelope_up_decay_coeff = lsb_msb & BMA530_SC_ENVELOPE_UP_DECAY_COEFF_MSK; + + /* Settings 4 */ + /* Get word to calculate envelope_down_thres */ + lsb = (uint16_t) sc_data[idx++]; + msb = ((uint16_t) sc_data[idx++] << 8); + lsb_msb = (uint16_t)(lsb | msb); + + step_cntr->envelope_down_thres = lsb_msb & BMA530_SC_ENVELOPE_DOWN_THRES_MSK; + + /* Settings 5 */ + /* Get word to calculate envelope_down_decay_coeff */ + lsb = (uint16_t) sc_data[idx++]; + msb = ((uint16_t) sc_data[idx++] << 8); + lsb_msb = (uint16_t)(lsb | msb); + + step_cntr->envelope_down_decay_coeff = lsb_msb & BMA530_SC_ENVELOPE_DOWN_DECAY_COEFF_MSK; + + /* Settings 6 */ + /* Get word to calculate acc_mean_decay_coeff */ + lsb = (uint16_t) sc_data[idx++]; + msb = ((uint16_t) sc_data[idx++] << 8); + lsb_msb = (uint16_t)(lsb | msb); + + step_cntr->acc_mean_decay_coeff = lsb_msb & BMA530_SC_ACC_MEAN_DECAY_COEFF_MSK; + + /* Settings 7 */ + /* Get word to calculate step_dur_mean_decay_coeff */ + lsb = (uint16_t) sc_data[idx++]; + msb = ((uint16_t) sc_data[idx++] << 8); + lsb_msb = (uint16_t)(lsb | msb); + + step_cntr->step_dur_mean_decay_coeff = lsb_msb & BMA530_SC_STEP_DUR_MEAN_DECAY_COEFF_MSK; + + /* Settings 8 */ + + /* Get word to calculate step_buffer_size, filter_cascade_enabled, step_counter_increment and + * en_half_step from same word */ + lsb = (uint16_t) sc_data[idx++]; + msb = ((uint16_t) sc_data[idx++] << 8); + lsb_msb = (uint16_t)(lsb | msb); + + step_cntr->step_buffer_size = lsb_msb & BMA530_SC_STEP_BUFFER_SIZE_MSK; + + step_cntr->filter_cascade_enabled = (lsb_msb & BMA530_SC_FILTER_CASCADE_ENABLED_MSK) >> + BMA530_SC_FILTER_CASCADE_ENABLED_POS; + + step_cntr->step_counter_increment = (lsb_msb & BMA530_SC_STEP_COUNTER_INCREAMENT_MSK) >> + BMA530_SC_STEP_COUNTER_INCREAMENT_POS; + + step_cntr->en_half_step = (lsb_msb & BMA530_SC_EN_HALF_STEP_MSK) >> BMA530_SC_EN_HALF_STEP_POS; + + /* Settings 9 */ + /* Get word to calculate peak_duration_min_walking and peak_duration_min_running from same word */ + lsb = (uint16_t) sc_data[idx++]; + msb = ((uint16_t) sc_data[idx++] << 8); + lsb_msb = (uint16_t)(lsb | msb); + + step_cntr->peak_duration_min_walking = lsb_msb & BMA530_SC_PEAK_DUR_MIN_WALKING_MSK; + + step_cntr->peak_duration_min_running = (lsb_msb & BMA530_SC_PEAK_DUR_MIN_RUNNING_MSK) >> + BMA530_SC_PEAK_DUR_MIN_RUNNING_POS; + + /* Settings 10 */ + /* Get word to calculate activity_detection_factor and activity_detection_thres from same word */ + lsb = (uint16_t) sc_data[idx++]; + msb = ((uint16_t) sc_data[idx++] << 8); + lsb_msb = (uint16_t)(lsb | msb); + + step_cntr->activity_detection_factor = lsb_msb & BMA530_SC_ACTIVITY_DET_FACT_MSK; + + step_cntr->activity_detection_thres = (lsb_msb & BMA530_SC_ACTIVITY_DET_THRES_MSK) >> + BMA530_SC_ACTIVITY_DET_THRES_POS; + + /* Settings 11 */ + /* Get word to calculate step_duration_max and step_duration_window from same word */ + lsb = (uint16_t) sc_data[idx++]; + msb = ((uint16_t) sc_data[idx++] << 8); + lsb_msb = (uint16_t)(lsb | msb); + + step_cntr->step_duration_max = lsb_msb & BMA530_SC_STEP_DUR_MAX_MSK; + + step_cntr->step_duration_window = (lsb_msb & BMA530_SC_STEP_DUR_WINDOW_MSK) >> + BMA530_SC_STEP_DUR_WINDOW_POS; + + /* Settings 12 */ + /* Get word to calculate en_step_dur_pp, step_dur_thres, en_mcr_pp and mcr_thres from same word */ + lsb = (uint16_t) sc_data[idx++]; + msb = ((uint16_t) sc_data[idx++] << 8); + lsb_msb = (uint16_t)(lsb | msb); + + step_cntr->en_step_dur_pp = lsb_msb & BMA530_SC_EN_STEP_DUR_PP_MSK; + + step_cntr->step_dur_thres = (lsb_msb & BMA530_SC_STEP_DUR_THRES_MSK) >> BMA530_SC_STEP_DUR_THRES_POS; + + step_cntr->en_mcr_pp = (lsb_msb & BMA530_SC_EN_MCR_PP_MSK) >> BMA530_SC_EN_MCR_PP_POS; + + step_cntr->mcr_thres = (lsb_msb & BMA530_SC_MCR_THRES_MSK) >> BMA530_SC_MCR_THRES_POS; + + /* Settings 13 */ + /* Get word to calculate filter_coeff_b_2 */ + lsb = (uint16_t) sc_data[idx++]; + msb = ((uint16_t) sc_data[idx++] << 8); + lsb_msb = (uint16_t)(lsb | msb); + + step_cntr->filter_coeff_b_2 = lsb_msb & BMA530_SC_FILTER_COEFF_B_2_MSK; + + /* Settings 14 */ + /* Get word to calculate filter_coeff_b_1 */ + lsb = (uint16_t) sc_data[idx++]; + msb = ((uint16_t) sc_data[idx++] << 8); + lsb_msb = (uint16_t)(lsb | msb); + + step_cntr->filter_coeff_b_1 = lsb_msb & BMA530_SC_FILTER_COEFF_B_1_MSK; + + /* Settings 15 */ + /* Get word to calculate filter_coeff_b_0 */ + lsb = (uint16_t) sc_data[idx++]; + msb = ((uint16_t) sc_data[idx++] << 8); + lsb_msb = (uint16_t)(lsb | msb); + + step_cntr->filter_coeff_b_0 = lsb_msb & BMA530_SC_FILTER_COEFF_B_0_MSK; + + /* Settings 16 */ + /* Get word to calculate filter_coeff_a_2 */ + lsb = (uint16_t) sc_data[idx++]; + msb = ((uint16_t) sc_data[idx++] << 8); + lsb_msb = (uint16_t)(lsb | msb); + + step_cntr->filter_coeff_a_2 = lsb_msb & BMA530_SC_FILTER_COEFF_A_2_MSK; + + /* Settings 17 */ + /* Get word to calculate filter_coeff_a_1 */ + lsb = (uint16_t) sc_data[idx++]; + msb = ((uint16_t) sc_data[idx++] << 8); + lsb_msb = (uint16_t)(lsb | msb); + + step_cntr->filter_coeff_a_1 = lsb_msb & BMA530_SC_FILTER_COEFF_A_1_MSK; + + /* Settings 18 */ + /* Get word to calculate filter_coeff_scale_a and filter_coeff_scale_b from same word */ + lsb = (uint16_t) sc_data[idx++]; + msb = ((uint16_t) sc_data[idx++] << 8); + lsb_msb = (uint16_t)(lsb | msb); + + step_cntr->filter_coeff_scale_a = lsb_msb & BMA530_SC_FILTER_COEFF_SCALE_A_MSK; + + step_cntr->filter_coeff_scale_b = (lsb_msb & BMA530_SC_FILTER_COEFF_SCALE_B_MSK) >> + BMA530_SC_FILTER_COEFF_SCALE_B_POS; + } + } + } + + return result; +} + +/*! + * @brief This API gets default step counter configuration + */ +int8_t bma530_get_default_step_counter_config(struct bma530_step_cntr *step_cntr, struct bma5_dev *dev) +{ + /* Variable to define error */ + int8_t result = BMA5_OK; + + /* Variable to store base address of step counter */ + uint8_t data = BMA530_BASE_ADDR_STEP_COUNTER; + + if (step_cntr == NULL) + { + result = BMA5_E_NULL_PTR; + } + else + { + /* Set the step counter base address to feature engine transmission address to start DMA transaction */ + result = bma5_set_regs(BMA5_REG_FEATURE_DATA_ADDR, &data, 1, dev); + + if (result == BMA5_OK) + { + /* Settings 1 */ + step_cntr->watermark_level = BMA530_SC_DEFAULT_WATERMARK_LEVEL; + + step_cntr->reset_counter = BMA530_SC_DEFAULT_RESET_COUNTER; + + step_cntr->sd_en = BMA530_SC_DEFAULT_SD_EN; + + step_cntr->sc_en = BMA530_SC_DEFAULT_SC_EN; + + if (dev->context == BMA5_HEARABLE) + { + /* Settings 2 */ + + step_cntr->envelope_up_thres = BMA530_STEP_COUNTER_2_ENVELOPE_UP_THRES_H; + + /* Settings 3 */ + + step_cntr->envelope_up_decay_coeff = BMA530_STEP_COUNTER_3_ENVELOPE_UP_DECAY_COEFF_H; + + /* Settings 4 */ + + step_cntr->envelope_down_thres = BMA530_STEP_COUNTER_4_ENVELOPE_DOWN_THRES_H; + + /* Settings 5 */ + + step_cntr->envelope_down_decay_coeff = BMA530_STEP_COUNTER_5_ENVELOPE_DOWN_DECAY_COEFF_H; + + /* Settings 6 */ + + step_cntr->acc_mean_decay_coeff = BMA530_STEP_COUNTER_6_ACC_MEAN_DECAY_COEFF_H; + + /* Settings 7 */ + + step_cntr->step_dur_mean_decay_coeff = BMA530_STEP_COUNTER_7_STEP_DUR_MEAN_DECAY_COEFF_H; + + /* Settings 8 */ + + step_cntr->step_buffer_size = BMA530_STEP_COUNTER_8_STEP_BUFFER_SIZE_H; + + step_cntr->filter_cascade_enabled = BMA530_STEP_COUNTER_8_FILTER_CASCADE_ENABLED_H; + + step_cntr->step_counter_increment = BMA530_STEP_COUNTER_8_STEP_COUNTER_INCREMENT_H; + + step_cntr->en_half_step = BMA530_STEP_COUNTER_8_EN_HALF_STEP_H; + + /* Settings 9 */ + + step_cntr->peak_duration_min_walking = BMA530_STEP_COUNTER_9_PEAK_DURATION_MIN_WALKING_H; + + step_cntr->peak_duration_min_running = BMA530_STEP_COUNTER_9_PEAK_DURATION_MIN_RUNNING_H; + + /* Settings 10 */ + + step_cntr->activity_detection_factor = BMA530_STEP_COUNTER_10_ACTIVITY_DETECTION_FACTOR_H; + + step_cntr->activity_detection_thres = BMA530_STEP_COUNTER_10_ACTIVITY_DETECTION_THRES_H; + + /* Settings 11 */ + + step_cntr->step_duration_max = BMA530_STEP_COUNTER_11_STEP_DURATION_MAX_H; + + step_cntr->step_duration_window = BMA530_STEP_COUNTER_11_STEP_DURATION_WINDOW_H; + + /* Settings 12 */ + + step_cntr->en_step_dur_pp = BMA530_STEP_COUNTER_12_EN_STEP_DUR_PP_H; + + step_cntr->step_dur_thres = BMA530_STEP_COUNTER_12_STEP_DUR_THRES_H; + + step_cntr->en_mcr_pp = BMA530_STEP_COUNTER_12_EN_MCR_PP_H; + + step_cntr->mcr_thres = BMA530_STEP_COUNTER_12_MCR_THRES_H; + } + else if (dev->context == BMA5_WEARABLE) + { + /* Settings 2 */ + + step_cntr->envelope_up_thres = BMA530_STEP_COUNTER_2_ENVELOPE_UP_THRES_W; + + /* Settings 3 */ + + step_cntr->envelope_up_decay_coeff = BMA530_STEP_COUNTER_3_ENVELOPE_UP_DECAY_COEFF_W; + + /* Settings 4 */ + + step_cntr->envelope_down_thres = BMA530_STEP_COUNTER_4_ENVELOPE_DOWN_THRES_W; + + /* Settings 5 */ + + step_cntr->envelope_down_decay_coeff = BMA530_STEP_COUNTER_5_ENVELOPE_DOWN_DECAY_COEFF_W; + + /* Settings 6 */ + + step_cntr->acc_mean_decay_coeff = BMA530_STEP_COUNTER_6_ACC_MEAN_DECAY_COEFF_W; + + /* Settings 7 */ + + step_cntr->step_dur_mean_decay_coeff = BMA530_STEP_COUNTER_7_STEP_DUR_MEAN_DECAY_COEFF_W; + + /* Settings 8 */ + + step_cntr->step_buffer_size = BMA530_STEP_COUNTER_8_STEP_BUFFER_SIZE_W; + + step_cntr->filter_cascade_enabled = BMA530_STEP_COUNTER_8_FILTER_CASCADE_ENABLED_W; + + step_cntr->step_counter_increment = BMA530_STEP_COUNTER_8_STEP_COUNTER_INCREMENT_W; + + step_cntr->en_half_step = BMA530_STEP_COUNTER_8_EN_HALF_STEP_W; + + /* Settings 9 */ + + step_cntr->peak_duration_min_walking = BMA530_STEP_COUNTER_9_PEAK_DURATION_MIN_WALKING_W; + + step_cntr->peak_duration_min_running = BMA530_STEP_COUNTER_9_PEAK_DURATION_MIN_RUNNING_W; + + /* Settings 10 */ + + step_cntr->activity_detection_factor = BMA530_STEP_COUNTER_10_ACTIVITY_DETECTION_FACTOR_W; + + step_cntr->activity_detection_thres = BMA530_STEP_COUNTER_10_ACTIVITY_DETECTION_THRES_W; + + /* Settings 11 */ + + step_cntr->step_duration_max = BMA530_STEP_COUNTER_11_STEP_DURATION_MAX_W; + + step_cntr->step_duration_window = BMA530_STEP_COUNTER_11_STEP_DURATION_WINDOW_W; + + /* Settings 12 */ + + step_cntr->en_step_dur_pp = BMA530_STEP_COUNTER_12_EN_STEP_DUR_PP_W; + + step_cntr->step_dur_thres = BMA530_STEP_COUNTER_12_STEP_DUR_THRES_W; + + step_cntr->en_mcr_pp = BMA530_STEP_COUNTER_12_EN_MCR_PP_W; + + step_cntr->mcr_thres = BMA530_STEP_COUNTER_12_MCR_THRES_W; + } + else if (dev->context == BMA5_SMARTPHONE) + { + /* Settings 2 */ + + step_cntr->envelope_up_thres = BMA530_STEP_COUNTER_2_ENVELOPE_UP_THRES_S; + + /* Settings 3 */ + + step_cntr->envelope_up_decay_coeff = BMA530_STEP_COUNTER_3_ENVELOPE_UP_DECAY_COEFF_S; + + /* Settings 4 */ + + step_cntr->envelope_down_thres = BMA530_STEP_COUNTER_4_ENVELOPE_DOWN_THRES_S; + + /* Settings 5 */ + + step_cntr->envelope_down_decay_coeff = BMA530_STEP_COUNTER_5_ENVELOPE_DOWN_DECAY_COEFF_S; + + /* Settings 6 */ + + step_cntr->acc_mean_decay_coeff = BMA530_STEP_COUNTER_6_ACC_MEAN_DECAY_COEFF_S; + + /* Settings 7 */ + + step_cntr->step_dur_mean_decay_coeff = BMA530_STEP_COUNTER_7_STEP_DUR_MEAN_DECAY_COEFF_S; + + /* Settings 8 */ + + step_cntr->step_buffer_size = BMA530_STEP_COUNTER_8_STEP_BUFFER_SIZE_S; + + step_cntr->filter_cascade_enabled = BMA530_STEP_COUNTER_8_FILTER_CASCADE_ENABLED_S; + + step_cntr->step_counter_increment = BMA530_STEP_COUNTER_8_STEP_COUNTER_INCREMENT_S; + + step_cntr->en_half_step = BMA530_STEP_COUNTER_8_EN_HALF_STEP_S; + + /* Settings 9 */ + + step_cntr->peak_duration_min_walking = BMA530_STEP_COUNTER_9_PEAK_DURATION_MIN_WALKING_S; + + step_cntr->peak_duration_min_running = BMA530_STEP_COUNTER_9_PEAK_DURATION_MIN_RUNNING_S; + + /* Settings 10 */ + + step_cntr->activity_detection_factor = BMA530_STEP_COUNTER_10_ACTIVITY_DETECTION_FACTOR_S; + + step_cntr->activity_detection_thres = BMA530_STEP_COUNTER_10_ACTIVITY_DETECTION_THRES_S; + + /* Settings 11 */ + + step_cntr->step_duration_max = BMA530_STEP_COUNTER_11_STEP_DURATION_MAX_S; + + step_cntr->step_duration_window = BMA530_STEP_COUNTER_11_STEP_DURATION_WINDOW_S; + + /* Settings 12 */ + + step_cntr->en_step_dur_pp = BMA530_STEP_COUNTER_12_EN_STEP_DUR_PP_S; + + step_cntr->step_dur_thres = BMA530_STEP_COUNTER_12_STEP_DUR_THRES_S; + + step_cntr->en_mcr_pp = BMA530_STEP_COUNTER_12_EN_MCR_PP_S; + + step_cntr->mcr_thres = BMA530_STEP_COUNTER_12_MCR_THRES_S; + } + else + { + result = BMA5_E_INVALID_CONTEXT_PARAM; + } + + /* Settings 13 */ + + step_cntr->filter_coeff_b_2 = BMA530_SC_DEFAULT_FILTER_COEFF_B_2; + + /* Settings 14 */ + + step_cntr->filter_coeff_b_1 = BMA530_SC_DEFAULT_FILTER_COEFF_B_1; + + /* Settings 15 */ + + step_cntr->filter_coeff_b_0 = BMA530_SC_DEFAULT_FILTER_COEFF_B_0; + + /* Settings 16 */ + + step_cntr->filter_coeff_a_2 = BMA530_SC_DEFAULT_FILTER_COEFF_A_2; + + /* Settings 17 */ + + step_cntr->filter_coeff_a_1 = BMA530_SC_DEFAULT_FILTER_COEFF_A_1; + + /* Settings 18 */ + + step_cntr->filter_coeff_scale_a = BMA530_SC_DEFAULT_FILTER_COEFF_SCALE_A; + + step_cntr->filter_coeff_scale_b = BMA530_SC_DEFAULT_FILTER_COEFF_SCALE_B; + } + } + + return result; +} + +/*! + * @brief This API sets sig-motion configuration + */ +int8_t bma530_set_sig_motion_config(const struct bma530_sig_motion *sig_mot, struct bma5_dev *dev) +{ + /* Variable to define error */ + int8_t result = BMA5_OK; + + /* Variable to store base address of sig-motion */ + uint8_t data = BMA530_BASE_ADDR_SIG_MOTION; + + /* Array to store sig-motion data */ + uint8_t sig_data[8] = { 0 }; + + /* Variables to store the data to be written in register */ + uint16_t block_size_1, block_size_2, p2p_min_1, p2p_min_2, mcr_min, p2p_max_1, p2p_max_2, mcr_max; + + if (sig_mot == NULL) + { + result = BMA5_E_NULL_PTR; + } + else + { + /* Set the sig-motion base address to feature engine transmission address to start DMA transaction */ + result = bma5_set_regs(BMA5_REG_FEATURE_DATA_ADDR, &data, 1, dev); + + if (result == BMA5_OK) + { + /* Get the configuration from the feature engine register */ + result = bma5_get_regs(BMA5_REG_FEATURE_DATA_TX, sig_data, 8, dev); + + if (result == BMA5_OK) + { + /* Settings 1 */ + block_size_1 = + (BMA5_SET_BITS_POS_0(sig_data[2], BMA530_SIG_MOT_BLOCK_SIZE, + sig_mot->block_size) & BMA530_SIG_MOT_BLOCK_SIZE_MSK); + + block_size_2 = (uint16_t)(sig_data[3] << 8); + + block_size_2 = + (BMA5_SET_BITS_POS_0(block_size_2, BMA530_SIG_MOT_BLOCK_SIZE, + sig_mot->block_size) & BMA530_SIG_MOT_BLOCK_SIZE_MSK); + + /* Settings 2 */ + p2p_min_1 = + (BMA5_SET_BITS_POS_0(sig_data[4], BMA530_SIG_MOT_P2P_MIN, + sig_mot->p2p_min) & BMA530_SIG_MOT_P2P_MIN_MSK); + + p2p_min_2 = (uint16_t)(sig_data[5] << 8); + + p2p_min_2 = + (BMA5_SET_BITS_POS_0(p2p_min_2, BMA530_SIG_MOT_P2P_MIN, + sig_mot->p2p_min) & BMA530_SIG_MOT_P2P_MIN_MSK); + + mcr_min = + (BMA5_SET_BITS(sig_data[5], BMA530_SIG_MOT_MCR_MIN, sig_mot->mcr_min) & BMA530_SIG_MOT_MCR_MIN_MSK); + + /* Settings 3 */ + p2p_max_1 = + (BMA5_SET_BITS_POS_0(sig_data[6], BMA530_SIG_MOT_P2P_MAX, + sig_mot->p2p_max) & BMA530_SIG_MOT_P2P_MAX_MSK); + + p2p_max_2 = (uint16_t)(sig_data[7] << 8); + + p2p_max_2 = + (BMA5_SET_BITS_POS_0(p2p_max_2, BMA530_SIG_MOT_P2P_MAX, + sig_mot->p2p_max) & BMA530_SIG_MOT_P2P_MAX_MSK); + + mcr_max = + (BMA5_SET_BITS(sig_data[7], BMA530_SIG_MOT_MCR_MAX, sig_mot->mcr_max) & BMA530_SIG_MOT_MCR_MAX_MSK); + + sig_data[0] = (uint8_t)block_size_1; + sig_data[1] = (uint8_t)(block_size_2 >> 8); + sig_data[2] = (uint8_t)p2p_min_1; + sig_data[3] = (uint8_t)((p2p_min_2 | mcr_min) >> 8); + sig_data[4] = (uint8_t)p2p_max_1; + sig_data[5] = (uint8_t)((p2p_max_2 | mcr_max) >> 8); + + /* Set the configuration from the feature engine register */ + result = bma5_set_regs(BMA5_REG_FEATURE_DATA_TX, sig_data, 6, dev); + } + } + } + + return result; +} + +/*! + * @brief This API gets sig-motion configuration + */ +int8_t bma530_get_sig_motion_config(struct bma530_sig_motion *sig_mot, struct bma5_dev *dev) +{ + /* Variable to define error */ + int8_t result = BMA5_OK; + + /* Variable to store base address of sig-motion */ + uint8_t data = BMA530_BASE_ADDR_SIG_MOTION; + + /* Array to store sig-motion data */ + uint8_t sig_data[8] = { 0 }; + + /* Variable to define array offset */ + uint8_t idx; + + /* Variable to define LSB */ + uint16_t lsb; + + /* Variable to define MSB */ + uint16_t msb; + + /* Variable to define a word */ + uint16_t lsb_msb; + + if (sig_mot == NULL) + { + result = BMA5_E_NULL_PTR; + } + else + { + /* Set the sig-motion base address to feature engine transmission address to start DMA transaction */ + result = bma5_set_regs(BMA5_REG_FEATURE_DATA_ADDR, &data, 1, dev); + + if (result == BMA5_OK) + { + /* Get the configuration from the feature engine register */ + result = bma5_get_regs(BMA5_REG_FEATURE_DATA_TX, sig_data, 8, dev); + + if (result == BMA5_OK) + { + /* First two bytes are dummy bytes */ + idx = 2; + + /* Settings 1 */ + /* Get word to calculate block_size */ + lsb = (uint16_t) sig_data[idx++]; + msb = ((uint16_t) sig_data[idx++] << 8); + lsb_msb = (uint16_t)(lsb | msb); + + sig_mot->block_size = lsb_msb & BMA530_SIG_MOT_BLOCK_SIZE_MSK; + + /* Settings 2 */ + /* Get word to calculate p2p_min and mcr_min from same word */ + lsb = (uint16_t) sig_data[idx++]; + msb = ((uint16_t) sig_data[idx++] << 8); + lsb_msb = (uint16_t)(lsb | msb); + + sig_mot->p2p_min = lsb_msb & BMA530_SIG_MOT_P2P_MIN_MSK; + + sig_mot->mcr_min = (lsb_msb & BMA530_SIG_MOT_MCR_MIN_MSK) >> BMA530_SIG_MOT_MCR_MIN_POS; + + /* Settings 3 */ + /* Get word to calculate p2p_max and mcr_max from same word */ + lsb = (uint16_t) sig_data[idx++]; + msb = ((uint16_t) sig_data[idx++] << 8); + lsb_msb = (uint16_t)(lsb | msb); + + sig_mot->p2p_max = lsb_msb & BMA530_SIG_MOT_P2P_MAX_MSK; + + sig_mot->mcr_max = (lsb_msb & BMA530_SIG_MOT_MCR_MAX_MSK) >> BMA530_SIG_MOT_MCR_MAX_POS; + } + } + } + + return result; +} + +/*! + * @brief This API gets default sig-motion configuration + */ +int8_t bma530_get_default_sig_motion_config(struct bma530_sig_motion *sig_mot, struct bma5_dev *dev) +{ + /* Variable to define error */ + int8_t result = BMA5_OK; + + /* Variable to store base address of sig-motion */ + uint8_t data = BMA530_BASE_ADDR_SIG_MOTION; + + if (sig_mot == NULL) + { + result = BMA5_E_NULL_PTR; + } + else + { + /* Set the sig-motion base address to feature engine transmission address to start DMA transaction */ + result = bma5_set_regs(BMA5_REG_FEATURE_DATA_ADDR, &data, 1, dev); + + if (result == BMA5_OK) + { + if (dev->context == BMA5_HEARABLE) + { + /* Settings 1 */ + + sig_mot->block_size = BMA530_SIG_MOTION_1_BLOCK_SIZE_H; + + /* Settings 2 */ + + sig_mot->p2p_min = BMA530_SIG_MOTION_2_P2P_MIN_H; + + sig_mot->mcr_min = BMA530_SIG_MOTION_2_MCR_MIN_H; + + /* Settings 3 */ + + sig_mot->p2p_max = BMA530_SIG_MOTION_3_P2P_MAX_H; + + sig_mot->mcr_max = BMA530_SIG_MOTION_3_MCR_MAX_H; + } + else if (dev->context == BMA5_WEARABLE) + { + /* Settings 1 */ + + sig_mot->block_size = BMA530_SIG_MOTION_1_BLOCK_SIZE_W; + + /* Settings 2 */ + + sig_mot->p2p_min = BMA530_SIG_MOTION_2_P2P_MIN_W; + + sig_mot->mcr_min = BMA530_SIG_MOTION_2_MCR_MIN_W; + + /* Settings 3 */ + + sig_mot->p2p_max = BMA530_SIG_MOTION_3_P2P_MAX_W; + + sig_mot->mcr_max = BMA530_SIG_MOTION_3_MCR_MAX_W; + } + else if (dev->context == BMA5_SMARTPHONE) + { + /* Settings 1 */ + + sig_mot->block_size = BMA530_SIG_MOTION_1_BLOCK_SIZE_S; + + /* Settings 2 */ + + sig_mot->p2p_min = BMA530_SIG_MOTION_2_P2P_MIN_S; + + sig_mot->mcr_min = BMA530_SIG_MOTION_2_MCR_MIN_S; + + /* Settings 3 */ + + sig_mot->p2p_max = BMA530_SIG_MOTION_3_P2P_MAX_S; + + sig_mot->mcr_max = BMA530_SIG_MOTION_3_MCR_MAX_S; + } + else + { + result = BMA5_E_INVALID_CONTEXT_PARAM; + } + } + } + + return result; +} + +/*! + * @brief This API sets tilt configuration + */ +int8_t bma530_set_tilt_config(const struct bma530_tilt *tilt, struct bma5_dev *dev) +{ + /* Variable to define error */ + int8_t result = BMA5_OK; + + /* Variable to store base address of tilt */ + uint8_t data = BMA530_BASE_ADDR_TILT; + + /* Array to store tilt config data */ + uint8_t tilt_data[6] = { 0 }; + + /* Variables to store the data to be written in register */ + uint16_t segment_size, min_tilt_angle, beta_acc_mean_1, beta_acc_mean_2; + + if (tilt == NULL) + { + result = BMA5_E_NULL_PTR; + } + else + { + /* Set the tilt base address to feature engine transmission address to start DMA transaction */ + result = bma5_set_regs(BMA5_REG_FEATURE_DATA_ADDR, &data, 1, dev); + + if (result == BMA5_OK) + { + /* Get the configuration from the feature engine register */ + result = bma5_get_regs(BMA5_REG_FEATURE_DATA_TX, tilt_data, 6, dev); + + if (result == BMA5_OK) + { + /* Settings 1 */ + segment_size = + (BMA5_SET_BITS_POS_0(tilt_data[2], BMA530_TILT_SEGMENT_SIZE, + tilt->segment_size) & BMA530_TILT_SEGMENT_SIZE_MSK); + + min_tilt_angle = + (BMA5_SET_BITS(tilt_data[3], BMA530_TILT_MIN_TILT_ANGLE, + tilt->min_tilt_angle) & BMA530_TILT_MIN_TILT_ANGLE_MSK); + + /* Settings 2 */ + beta_acc_mean_1 = + (BMA5_SET_BITS_POS_0(tilt_data[4], BMA530_TILT_BETA_ACC_MEAN, + tilt->beta_acc_mean) & BMA530_TILT_BETA_ACC_MEAN_MSK); + + beta_acc_mean_2 = (uint16_t)(tilt_data[5] << 8); + + beta_acc_mean_2 = + (BMA5_SET_BITS_POS_0(beta_acc_mean_2, BMA530_TILT_BETA_ACC_MEAN, + tilt->beta_acc_mean) & BMA530_TILT_BETA_ACC_MEAN_MSK); + + tilt_data[0] = (uint8_t)segment_size; + tilt_data[1] = (uint8_t)(min_tilt_angle >> 8); + tilt_data[2] = (uint8_t)beta_acc_mean_1; + tilt_data[3] = (uint8_t)(beta_acc_mean_2 >> 8); + + /* Set the configuration from the feature engine register */ + result = bma5_set_regs(BMA5_REG_FEATURE_DATA_TX, tilt_data, 4, dev); + } + } + } + + return result; +} + +/*! + * @brief This API gets tilt configuration + */ +int8_t bma530_get_tilt_config(struct bma530_tilt *tilt, struct bma5_dev *dev) +{ + /* Variable to define error */ + int8_t result = BMA5_OK; + + /* Variable to store base address of tilt */ + uint8_t data = BMA530_BASE_ADDR_TILT; + + /* Array to store tilt config data */ + uint8_t tilt_data[6] = { 0 }; + + /* Variable to define array offset */ + uint8_t idx; + + /* Variable to define LSB */ + uint16_t lsb; + + /* Variable to define MSB */ + uint16_t msb; + + /* Variable to define a word */ + uint16_t lsb_msb; + + if (tilt == NULL) + { + result = BMA5_E_NULL_PTR; + } + else + { + /* Set the tilt base address to feature engine transmission address to start DMA transaction */ + result = bma5_set_regs(BMA5_REG_FEATURE_DATA_ADDR, &data, 1, dev); + + if (result == BMA5_OK) + { + /* Get the configuration from the feature engine register */ + result = bma5_get_regs(BMA5_REG_FEATURE_DATA_TX, tilt_data, 6, dev); + + if (result == BMA5_OK) + { + /* First two bytes are dummy bytes */ + idx = 2; + + /* Settings 1 */ + /* Get word to calculate segment_size and min_tilt_angle from same word */ + lsb = (uint16_t) tilt_data[idx++]; + msb = ((uint16_t) tilt_data[idx++] << 8); + lsb_msb = (uint16_t)(lsb | msb); + + tilt->segment_size = lsb_msb & BMA530_TILT_SEGMENT_SIZE_MSK; + + tilt->min_tilt_angle = (lsb_msb & BMA530_TILT_MIN_TILT_ANGLE_MSK) >> BMA530_TILT_MIN_TILT_ANGLE_POS; + + /* Settings 2 */ + /* Get word to calculate beta_acc_mean */ + lsb = (uint16_t) tilt_data[idx++]; + msb = ((uint16_t) tilt_data[idx++] << 8); + lsb_msb = (uint16_t)(lsb | msb); + + tilt->beta_acc_mean = lsb_msb & BMA530_TILT_BETA_ACC_MEAN_MSK; + } + } + } + + return result; +} + +/*! + * @brief This API sets orientation configuration + */ +int8_t bma530_set_orient_config(const struct bma530_orient *orient, struct bma5_dev *dev) +{ + /* Variable to define error */ + int8_t result = BMA5_OK; + + /* Variable to store base address of orientation */ + uint8_t data = BMA530_BASE_ADDR_ORIENTATION; + + /* Array to store orientation config data */ + uint8_t orient_data[6] = { 0 }; + + /* Variables to store the data to be written in register */ + uint16_t ud_en, mode, blocking, slope_thres, hysteresis; + uint16_t theta_1, theta_2, hold_time; + + if (orient == NULL) + { + result = BMA5_E_NULL_PTR; + } + else + { + /* Set the orientation base address to feature engine transmission address to start DMA transaction */ + result = bma5_set_regs(BMA5_REG_FEATURE_DATA_ADDR, &data, 1, dev); + + if (result == BMA5_OK) + { + /* Get the configuration from the feature engine register */ + result = bma5_get_regs(BMA5_REG_FEATURE_DATA_TX, orient_data, 6, dev); + + if (result == BMA5_OK) + { + /* Settings 1 */ + ud_en = + (BMA5_SET_BITS_POS_0(orient_data[0], BMA530_ORIENT_UD_EN, orient->ud_en) & BMA530_ORIENT_UD_EN_MSK); + + mode = (BMA5_SET_BITS(orient_data[0], BMA530_ORIENT_MODE, orient->mode) & BMA530_ORIENT_MODE_MSK); + + blocking = + (BMA5_SET_BITS(orient_data[0], BMA530_ORIENT_BLOCKING, + orient->blocking) & BMA530_ORIENT_BLOCKING_MSK); + + theta_1 = (BMA5_SET_BITS(orient_data[0], BMA530_ORIENT_THETA, orient->theta) & BMA530_ORIENT_THETA_MSK); + + theta_2 = (uint16_t)(orient_data[1] << 8); + + theta_2 = (BMA5_SET_BITS(theta_2, BMA530_ORIENT_THETA, orient->theta) & BMA530_ORIENT_THETA_MSK); + + hold_time = + (BMA5_SET_BITS(orient_data[1], BMA530_ORIENT_HOLD_TIME, + orient->hold_time) & BMA530_ORIENT_HOLD_TIME_MSK); + + /* Settings 2 */ + slope_thres = + (BMA5_SET_BITS_POS_0(orient_data[2], BMA530_ORIENT_SLOPE_THRES, + orient->slope_thres) & BMA530_ORIENT_SLOPE_THRES_MSK); + + hysteresis = + (BMA5_SET_BITS(orient_data[3], BMA530_ORIENT_HYSTERESIS, + orient->hysteresis) & BMA530_ORIENT_HYSTERESIS_MSK); + + orient_data[0] = (uint8_t)(ud_en | mode | blocking | theta_1); + orient_data[1] = (uint8_t)((theta_2 | hold_time) >> 8); + orient_data[2] = (uint8_t)slope_thres; + orient_data[3] = (uint8_t)(hysteresis >> 8); + + /* Set the configuration from the feature engine register */ + result = bma5_set_regs(BMA5_REG_FEATURE_DATA_TX, orient_data, 4, dev); + } + } + } + + return result; +} + +/*! + * @brief This API gets orientation configuration + */ +int8_t bma530_get_orient_config(struct bma530_orient *orient, struct bma5_dev *dev) +{ + /* Variable to define error */ + int8_t result = BMA5_OK; + + /* Variable to store base address of orientation */ + uint8_t data = BMA530_BASE_ADDR_ORIENTATION; + + /* Array to store orientation config data */ + uint8_t orient_data[6] = { 0 }; + + /* Variable to define 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; + + if (orient == NULL) + { + result = BMA5_E_NULL_PTR; + } + else + { + /* Set the orientation base address to feature engine transmission address to start DMA transaction */ + result = bma5_set_regs(BMA5_REG_FEATURE_DATA_ADDR, &data, 1, dev); + + if (result == BMA5_OK) + { + /* Get the configuration from the feature engine register */ + result = bma5_get_regs(BMA5_REG_FEATURE_DATA_TX, orient_data, 6, dev); + + if (result == BMA5_OK) + { + /* First two bytes are dummy bytes */ + idx = 2; + + /* Settings 1 */ + /* Get word to calculate ud en, mode, blocking, theta and hold time from same word */ + lsb = (uint16_t) orient_data[idx++]; + msb = ((uint16_t) orient_data[idx++] << 8); + lsb_msb = (uint16_t)(lsb | msb); + + orient->ud_en = lsb_msb & BMA530_ORIENT_UD_EN_MSK; + + orient->mode = (lsb_msb & BMA530_ORIENT_MODE_MSK) >> BMA530_ORIENT_MODE_POS; + + orient->blocking = (lsb_msb & BMA530_ORIENT_BLOCKING_MSK) >> BMA530_ORIENT_BLOCKING_POS; + + orient->theta = (lsb_msb & BMA530_ORIENT_THETA_MSK) >> BMA530_ORIENT_THETA_POS; + + orient->hold_time = (lsb_msb & BMA530_ORIENT_HOLD_TIME_MSK) >> BMA530_ORIENT_HOLD_TIME_POS; + + /* Settings 2 */ + /* Get word to calculate slope threshold and hysteresis from same word */ + lsb = (uint16_t) orient_data[idx++]; + msb = ((uint16_t) orient_data[idx++] << 8); + lsb_msb = (uint16_t)(lsb | msb); + + orient->slope_thres = lsb_msb & BMA530_ORIENT_SLOPE_THRES_MSK; + + orient->hysteresis = (lsb_msb & BMA530_ORIENT_HYSTERESIS_MSK) >> BMA530_ORIENT_HYSTERESIS_POS; + } + } + } + + return result; +} + +/*! + * @brief This API sets generic interrupt configurations + */ +int8_t bma530_set_generic_int_config(const struct bma530_generic_interrupt_types *gen_int, + uint8_t n_ints, + struct bma5_dev *dev) +{ + /* Variable to define error */ + int8_t result = BMA5_OK; + uint8_t loop; + + /* Variable to store base address of generic interrupt 1 */ + uint8_t data; + + /* Array to store generic interrupt 1 data */ + uint8_t int_1_data[16] = { 0 }; + + uint16_t slope_thres_1, slope_thres_2, comb_sel, axis_sel, hysteresis_1, hysteresis_2, criterion_sel; + uint16_t acc_ref_up, duration_1, duration_2, wait_time, quiet_time_1, quiet_time_2; + uint16_t ref_acc_x_1, ref_acc_x_2, ref_acc_y_1, ref_acc_y_2, ref_acc_z_1, ref_acc_z_2; + + if (gen_int == NULL) + { + result = BMA5_E_NULL_PTR; + } + else + { + for (loop = 0; loop < n_ints; loop++) + { + switch (gen_int[loop].generic_interrupt) + { + case BMA530_GEN_INT_1: + data = BMA530_BASE_ADDR_GENERIC_INT1; + break; + + case BMA530_GEN_INT_2: + data = BMA530_BASE_ADDR_GENERIC_INT2; + break; + + case BMA530_GEN_INT_3: + data = BMA530_BASE_ADDR_GENERIC_INT3; + break; + + default: + result = BMA5_E_INVALID_GEN_INT; + + return result; + } + + if (result == BMA5_OK) + { + /* Set the generic interrupt base address to feature engine transmission address to start DMA + * transaction */ + result = bma5_set_regs(BMA5_REG_FEATURE_DATA_ADDR, &data, 1, dev); + } + + if (result == BMA5_OK) + { + /* Get the configuration from the feature engine register */ + result = bma5_get_regs(BMA5_REG_FEATURE_DATA_TX, int_1_data, 16, dev); + + if (result == BMA5_OK) + { + /* Settings 1 */ + slope_thres_1 = + (BMA5_SET_BITS_POS_0(int_1_data[2], BMA530_GEN_INT_SLOPE_THRES, + gen_int[loop].gen_int.slope_thres) & BMA530_GEN_INT_SLOPE_THRES_MSK); + + slope_thres_2 = (uint16_t)(int_1_data[3] << 8); + + slope_thres_2 = + (BMA5_SET_BITS_POS_0(slope_thres_2, BMA530_GEN_INT_SLOPE_THRES, + gen_int[loop].gen_int.slope_thres) & BMA530_GEN_INT_SLOPE_THRES_MSK); + + comb_sel = + (BMA5_SET_BITS(int_1_data[3], BMA530_GEN_INT_COMB_SEL, + gen_int[loop].gen_int.comb_sel) & BMA530_GEN_INT_COMB_SEL_MSK); + + axis_sel = + (BMA5_SET_BITS(int_1_data[3], BMA530_GEN_INT_AXIS_SEL, + gen_int[loop].gen_int.axis_sel) & BMA530_GEN_INT_AXIS_SEL_MSK); + + /* Settings 2 */ + hysteresis_1 = + (BMA5_SET_BITS_POS_0(int_1_data[4], BMA530_GEN_INT_HYST, + gen_int[loop].gen_int.hysteresis) & BMA530_GEN_INT_HYST_MSK); + + hysteresis_2 = (uint16_t)(int_1_data[5] << 8); + + hysteresis_2 = + (BMA5_SET_BITS_POS_0(hysteresis_2, BMA530_GEN_INT_HYST, + gen_int[loop].gen_int.hysteresis) & BMA530_GEN_INT_HYST_MSK); + + criterion_sel = + (BMA5_SET_BITS(int_1_data[5], BMA530_GEN_INT_CRIT_SEL, + gen_int[loop].gen_int.criterion_sel) & BMA530_GEN_INT_CRIT_SEL_MSK); + + acc_ref_up = + (BMA5_SET_BITS(int_1_data[5], BMA530_GEN_INT_ACC_REF_UP, + gen_int[loop].gen_int.acc_ref_up) & BMA530_GEN_INT_ACC_REF_UP_MSK); + + /* Settings 3 */ + duration_1 = + (BMA5_SET_BITS_POS_0(int_1_data[6], BMA530_GEN_INT_DURATION, + gen_int[loop].gen_int.duration) & BMA530_GEN_INT_DURATION_MSK); + + duration_2 = (uint16_t)(int_1_data[7] << 8); + + duration_2 = + (BMA5_SET_BITS_POS_0(duration_2, BMA530_GEN_INT_DURATION, + gen_int[loop].gen_int.duration) & BMA530_GEN_INT_DURATION_MSK); + + wait_time = + (BMA5_SET_BITS(int_1_data[7], BMA530_GEN_INT_WAIT_TIME, + gen_int[loop].gen_int.wait_time) & BMA530_GEN_INT_WAIT_TIME_MSK); + + /* Settings 4 */ + quiet_time_1 = + (BMA5_SET_BITS_POS_0(int_1_data[8], BMA530_GEN_INT_QUIET_TIME, + gen_int[loop].gen_int.quiet_time) & BMA530_GEN_INT_QUIET_TIME_MSK); + + quiet_time_2 = (uint16_t)(int_1_data[9] << 8); + + quiet_time_2 = + (BMA5_SET_BITS_POS_0(quiet_time_2, BMA530_GEN_INT_QUIET_TIME, + gen_int[loop].gen_int.quiet_time) & BMA530_GEN_INT_QUIET_TIME_MSK); + + /* Settings 5 */ + ref_acc_x_1 = + BMA5_SET_BITS_POS_0(int_1_data[10], BMA530_GEN_INT_REF_ACC_X, + (uint16_t)(gen_int[loop].gen_int.ref_acc_x & BMA530_GEN_INT_REF_ACC_X_MSK)); + + ref_acc_x_2 = (uint16_t)(int_1_data[11] << 8); + + ref_acc_x_2 = + BMA5_SET_BITS_POS_0(ref_acc_x_2, BMA530_GEN_INT_REF_ACC_X, + (uint16_t)(gen_int[loop].gen_int.ref_acc_x & BMA530_GEN_INT_REF_ACC_X_MSK)); + + /* Settings 6 */ + ref_acc_y_1 = + BMA5_SET_BITS_POS_0(int_1_data[12], BMA530_GEN_INT_REF_ACC_Y, + (uint16_t)(gen_int[loop].gen_int.ref_acc_y & BMA530_GEN_INT_REF_ACC_Y_MSK)); + + ref_acc_y_2 = (uint16_t)(int_1_data[13] << 8); + + ref_acc_y_2 = + BMA5_SET_BITS_POS_0(ref_acc_y_2, BMA530_GEN_INT_REF_ACC_Y, + (uint16_t)(gen_int[loop].gen_int.ref_acc_y & BMA530_GEN_INT_REF_ACC_Y_MSK)); + + /* Settings 7 */ + ref_acc_z_1 = + BMA5_SET_BITS_POS_0(int_1_data[14], BMA530_GEN_INT_REF_ACC_Z, + (uint16_t)(gen_int[loop].gen_int.ref_acc_z & BMA530_GEN_INT_REF_ACC_Z_MSK)); + + ref_acc_z_2 = (uint16_t)(int_1_data[15] << 8); + + ref_acc_z_2 = + BMA5_SET_BITS_POS_0(ref_acc_z_2, BMA530_GEN_INT_REF_ACC_Z, + (uint16_t)(gen_int[loop].gen_int.ref_acc_z & BMA530_GEN_INT_REF_ACC_Z_MSK)); + + int_1_data[0] = (uint8_t)slope_thres_1; + int_1_data[1] = (uint8_t)((slope_thres_2 | comb_sel | axis_sel) >> 8); + int_1_data[2] = (uint8_t)hysteresis_1; + int_1_data[3] = (uint8_t)((hysteresis_2 | criterion_sel | acc_ref_up) >> 8); + int_1_data[4] = (uint8_t)duration_1; + int_1_data[5] = (uint8_t)((duration_2 | wait_time) >> 8); + int_1_data[6] = (uint8_t)quiet_time_1; + int_1_data[7] = (uint8_t)(quiet_time_2 >> 8); + int_1_data[8] = (uint8_t)ref_acc_x_1; + int_1_data[9] = (uint8_t)(ref_acc_x_2 >> 8); + int_1_data[10] = (uint8_t)ref_acc_y_1; + int_1_data[11] = (uint8_t)(ref_acc_y_2 >> 8); + int_1_data[12] = (uint8_t)ref_acc_z_1; + int_1_data[13] = (uint8_t)(ref_acc_z_2 >> 8); + + /* Set the configuration from the feature engine register */ + result = bma5_set_regs(BMA5_REG_FEATURE_DATA_TX, int_1_data, 14, dev); + } + } + } + } + + return result; +} + +/*! + * @brief This API gets default generic interrupt 1 configurations + */ +int8_t bma530_get_default_generic_int_config(struct bma530_generic_interrupt_types *gen_int, + uint8_t n_ints, + struct bma5_dev *dev) +{ + /* Variable to define error */ + int8_t result = BMA5_OK; + uint8_t loop; + + /* Variable to store base address of generic interrupt 1 */ + uint8_t data; + + if (gen_int == NULL) + { + result = BMA5_E_NULL_PTR; + } + else + { + for (loop = 0; loop < n_ints; loop++) + { + switch (gen_int[loop].generic_interrupt) + { + case BMA530_GEN_INT_1: + data = BMA530_BASE_ADDR_GENERIC_INT1; + break; + + case BMA530_GEN_INT_2: + data = BMA530_BASE_ADDR_GENERIC_INT2; + break; + + default: + result = BMA5_E_INVALID_GEN_INT; + + return result; + } + + if (result == BMA5_OK) + { + /* Set the generic interrupt base address to feature engine transmission address to start DMA + * transaction */ + result = bma5_set_regs(BMA5_REG_FEATURE_DATA_ADDR, &data, 1, dev); + } + + if (result == BMA5_OK) + { + gen_int[loop].gen_int.comb_sel = BMA530_GEN_INT_COMB_SEL_LOGICAL_OR; + + gen_int[loop].gen_int.axis_sel = BMA530_AXIS_SEL_DEFAULT; + + gen_int[loop].gen_int.criterion_sel = BMA530_GEN_INT_CRI_SEL_ACT; + + gen_int[loop].gen_int.acc_ref_up = BMA530_GEN_INT_ACC_REF_UP_ON_ALWAYS; + + gen_int[loop].gen_int.duration = BMA530_DURATION_DEFAULT; + + gen_int[loop].gen_int.wait_time = BMA530_WAIT_TIME_DEFAULT; + + gen_int[loop].gen_int.quiet_time = BMA530_QUIET_TIME_DEFAULT; + + gen_int[loop].gen_int.ref_acc_x = BMA530_ACC_REF_X_DEFAULT; + + gen_int[loop].gen_int.ref_acc_y = BMA530_ACC_REF_Y_DEFAULT; + + gen_int[loop].gen_int.ref_acc_z = BMA530_ACC_REF_Z_DEFAULT; + + if (dev->context == BMA5_HEARABLE && gen_int[loop].generic_interrupt == BMA530_GEN_INT_1) + { + gen_int[loop].gen_int.slope_thres = BMA530_GENERIC_INTERRUPT1_1_GI1_SLOPE_THRES_H; + gen_int[loop].gen_int.hysteresis = BMA530_GENERIC_INTERRUPT1_2_GI1_HYSTERESIS_H; + } + else if (dev->context == BMA5_WEARABLE && gen_int[loop].generic_interrupt == BMA530_GEN_INT_1) + { + gen_int[loop].gen_int.slope_thres = BMA530_GENERIC_INTERRUPT1_1_GI1_SLOPE_THRES_W; + gen_int[loop].gen_int.hysteresis = BMA530_GENERIC_INTERRUPT1_2_GI1_HYSTERESIS_W; + } + else if (dev->context == BMA5_SMARTPHONE && gen_int[loop].generic_interrupt == BMA530_GEN_INT_1) + { + gen_int[loop].gen_int.slope_thres = BMA530_GENERIC_INTERRUPT1_1_GI1_SLOPE_THRES_S; + gen_int[loop].gen_int.hysteresis = BMA530_GENERIC_INTERRUPT1_2_GI1_HYSTERESIS_S; + } + else if (dev->context == BMA5_HEARABLE && gen_int[loop].generic_interrupt == BMA530_GEN_INT_2) + { + gen_int[loop].gen_int.slope_thres = BMA530_GENERIC_INTERRUPT2_1_GI2_SLOPE_THRES_H; + gen_int[loop].gen_int.hysteresis = BMA530_GENERIC_INTERRUPT2_2_GI2_HYSTERESIS_H; + } + else if (dev->context == BMA5_WEARABLE && gen_int[loop].generic_interrupt == BMA530_GEN_INT_2) + { + gen_int[loop].gen_int.slope_thres = BMA530_GENERIC_INTERRUPT2_1_GI2_SLOPE_THRES_W; + gen_int[loop].gen_int.hysteresis = BMA530_GENERIC_INTERRUPT2_2_GI2_HYSTERESIS_W; + } + else if (dev->context == BMA5_SMARTPHONE && gen_int[loop].generic_interrupt == BMA530_GEN_INT_2) + { + gen_int[loop].gen_int.slope_thres = BMA530_GENERIC_INTERRUPT2_1_GI2_SLOPE_THRES_S; + gen_int[loop].gen_int.hysteresis = BMA530_GENERIC_INTERRUPT2_2_GI2_HYSTERESIS_S; + } + else + { + result = BMA5_E_INVALID_CONTEXT_PARAM; + } + } + } + } + + return result; +} + +/*! + * @brief This API gets generic interrupt 1 configurations + */ +int8_t bma530_get_generic_int_config(struct bma530_generic_interrupt_types *gen_int, + uint8_t n_ints, + struct bma5_dev *dev) +{ + /* Variable to define error */ + int8_t result = BMA5_OK; + uint8_t loop; + + /* Variable to store base address of generic interrupt 1 */ + uint8_t data; + + /* Array to store generic interrupt 1 data */ + uint8_t int_1_data[16] = { 0 }; + + /* Variable to define 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; + + if (gen_int == NULL) + { + result = BMA5_E_NULL_PTR; + } + else + { + for (loop = 0; loop < n_ints; loop++) + { + switch (gen_int[loop].generic_interrupt) + { + case BMA530_GEN_INT_1: + data = BMA530_BASE_ADDR_GENERIC_INT1; + break; + + case BMA530_GEN_INT_2: + data = BMA530_BASE_ADDR_GENERIC_INT2; + break; + + case BMA530_GEN_INT_3: + data = BMA530_BASE_ADDR_GENERIC_INT3; + break; + + default: + result = BMA5_E_INVALID_GEN_INT; + + return result; + } + + if (result == BMA5_OK) + { + /* Set the generic interrupt base address to feature engine transmission address to start DMA + * transaction */ + result = bma5_set_regs(BMA5_REG_FEATURE_DATA_ADDR, &data, 1, dev); + } + + if (result == BMA5_OK) + { + /* Get the configuration from the feature engine register */ + result = bma5_get_regs(BMA5_REG_FEATURE_DATA_TX, int_1_data, 16, dev); + + if (result == BMA5_OK) + { + /* First two bytes are dummy bytes */ + idx = 2; + + /* Settings 1 */ + /* Get word to calculate slope threshold, comb_sel and axis select from same word */ + lsb = (uint16_t) int_1_data[idx++]; + msb = ((uint16_t) int_1_data[idx++] << 8); + lsb_msb = (uint16_t)(lsb | msb); + + gen_int[loop].gen_int.slope_thres = lsb_msb & BMA530_GEN_INT_SLOPE_THRES_MSK; + + gen_int[loop].gen_int.comb_sel = (lsb_msb & BMA530_GEN_INT_COMB_SEL_MSK) >> + BMA530_GEN_INT_COMB_SEL_POS; + + gen_int[loop].gen_int.axis_sel = (lsb_msb & BMA530_GEN_INT_AXIS_SEL_MSK) >> + BMA530_GEN_INT_AXIS_SEL_POS; + + /* Settings 2 */ + /* Get word to calculate hysteresis, criterion_sel and acc_ref_up from same word */ + lsb = (uint16_t) int_1_data[idx++]; + msb = ((uint16_t) int_1_data[idx++] << 8); + lsb_msb = (uint16_t)(lsb | msb); + + gen_int[loop].gen_int.hysteresis = lsb_msb & BMA530_GEN_INT_HYST_MSK; + + gen_int[loop].gen_int.criterion_sel = (lsb_msb & BMA530_GEN_INT_CRIT_SEL_MSK) >> + BMA530_GEN_INT_CRIT_SEL_POS; + + gen_int[loop].gen_int.acc_ref_up = (lsb_msb & BMA530_GEN_INT_ACC_REF_UP_MSK) >> + BMA530_GEN_INT_ACC_REF_UP_POS; + + /* Settings 3 */ + /* Get word to calculate duration and wait time from same word */ + lsb = (uint16_t) int_1_data[idx++]; + msb = ((uint16_t) int_1_data[idx++] << 8); + lsb_msb = (uint16_t)(lsb | msb); + + gen_int[loop].gen_int.duration = lsb_msb & BMA530_GEN_INT_DURATION_MSK; + + gen_int[loop].gen_int.wait_time = (lsb_msb & BMA530_GEN_INT_WAIT_TIME_MSK) >> + BMA530_GEN_INT_WAIT_TIME_POS; + + /* Settings 4 */ + /* Get word to calculate quiet time */ + lsb = (uint16_t) int_1_data[idx++]; + msb = ((uint16_t) int_1_data[idx++] << 8); + lsb_msb = (uint16_t)(lsb | msb); + + gen_int[loop].gen_int.quiet_time = lsb_msb & BMA530_GEN_INT_QUIET_TIME_MSK; + + /* Settings 5 */ + /* Get word to calculate ref_acc_x */ + lsb = (uint16_t) int_1_data[idx++]; + msb = ((uint16_t) int_1_data[idx++] << 8); + lsb_msb = (uint16_t)(lsb | msb); + + gen_int[loop].gen_int.ref_acc_x = (int16_t)(lsb_msb & BMA530_GEN_INT_REF_ACC_X_MSK); + + /* Settings 6 */ + /* Get word to calculate ref_acc_y */ + lsb = (uint16_t) int_1_data[idx++]; + msb = ((uint16_t) int_1_data[idx++] << 8); + lsb_msb = (uint16_t)(lsb | msb); + + gen_int[loop].gen_int.ref_acc_y = (int16_t)(lsb_msb & BMA530_GEN_INT_REF_ACC_Y_MSK); + + /* Settings 7 */ + /* Get word to calculate ref_acc_z */ + lsb = (uint16_t) int_1_data[idx++]; + msb = ((uint16_t) int_1_data[idx++] << 8); + lsb_msb = (uint16_t)(lsb | msb); + + gen_int[loop].gen_int.ref_acc_z = (int16_t)(lsb_msb & BMA530_GEN_INT_REF_ACC_Z_MSK); + } + } + } + } + + return result; +} + +/*! + * @brief This API sets accel foc configuration + */ +int8_t bma530_set_accel_foc_config(const struct bma530_accel_foc_config *acc_foc, struct bma5_dev *dev) +{ + /* Variable to define error */ + int8_t result = BMA5_OK; + + /* Variable to store base address of accel foc */ + uint8_t data = BMA530_BASE_ADDR_ACC_FOC; + + /* Array to store accel foc config data */ + uint8_t acc_foc_data[10] = { 0 }; + + uint16_t reg_data; + + uint16_t foc_off_x, foc_off_y, foc_off_z; + uint8_t foc_apply_corr, foc_filter_coeff, foc_axis_1g; + + if (acc_foc == NULL) + { + result = BMA5_E_NULL_PTR; + + } + else + { + /* Set the accel foc base address to feature engine transmission address to start DMA transaction */ + result = bma5_set_regs(BMA5_REG_FEATURE_DATA_ADDR, &data, 1, dev); + + if (result == BMA5_OK) + { + /* Get the configuration from the feature engine register */ + result = bma5_get_regs(BMA5_REG_FEATURE_DATA_TX, acc_foc_data, 10, dev); + + if (result == BMA5_OK) + { + /* Settings 1 */ + + reg_data = (uint16_t)(((uint16_t)acc_foc_data[2] | ((uint16_t)acc_foc_data[3] << 8))); + foc_off_x = BMA5_SET_BITS_POS_0(reg_data, BMA530_ACC_FOC_OFF_X, acc_foc->foc_off_x); + + /* Settings 2 */ + + reg_data = (uint16_t)(((uint16_t)acc_foc_data[4] | ((uint16_t)acc_foc_data[5] << 8))); + foc_off_y = BMA5_SET_BITS_POS_0(reg_data, BMA530_ACC_FOC_OFF_Y, acc_foc->foc_off_y); + + /* Settings 3 */ + + reg_data = (uint16_t)(((uint16_t)acc_foc_data[6] | ((uint16_t)acc_foc_data[7] << 8))); + foc_off_z = BMA5_SET_BITS_POS_0(reg_data, BMA530_ACC_FOC_OFF_Z, acc_foc->foc_off_z); + + /* Settings 4 */ + + reg_data = (uint16_t)(((uint16_t)acc_foc_data[8] | ((uint16_t)acc_foc_data[9] << 8))); + foc_apply_corr = (uint8_t)BMA5_SET_BITS_POS_0(reg_data, + BMA530_ACC_FOC_APPLY_CORR, + acc_foc->foc_apply_corr); + + foc_filter_coeff = (uint8_t)BMA5_SET_BITS(reg_data, + BMA530_ACC_FOC_FILTER_COEFF, + acc_foc->foc_filter_coeff); + + foc_axis_1g = (uint8_t)BMA5_SET_BITS(reg_data, BMA530_ACC_FOC_AXIS_1G, acc_foc->foc_axis_1g); + + acc_foc_data[0] = (uint8_t)(foc_off_x & 0x00FF); + acc_foc_data[1] = (uint8_t)((foc_off_x & 0xFF00) >> 8); + acc_foc_data[2] = (uint8_t)(foc_off_y & 0x00FF); + acc_foc_data[3] = (uint8_t)((foc_off_y & 0xFF00) >> 8); + acc_foc_data[4] = (uint8_t)(foc_off_z & 0x00FF); + acc_foc_data[5] = (uint8_t)((foc_off_z & 0xFF00) >> 8); + acc_foc_data[6] = (uint8_t)(foc_apply_corr | foc_filter_coeff | foc_axis_1g); + + /* Set the configuration from the feature engine register */ + result = bma5_set_regs(BMA5_REG_FEATURE_DATA_TX, acc_foc_data, 8, dev); + } + } + } + + return result; +} + +/*! + * @brief This API gets accel foc configuration + */ +int8_t bma530_get_accel_foc_config(struct bma530_accel_foc_config *acc_foc, struct bma5_dev *dev) +{ + /* Variable to define error */ + int8_t result = BMA5_OK; + + /* Variable to store base address of accel foc */ + uint8_t data = BMA530_BASE_ADDR_ACC_FOC; + + /* Array to store accel foc config data */ + uint8_t acc_foc_data[10] = { 0 }; + + /* Variable to define 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; + + if (acc_foc == NULL) + { + result = BMA5_E_NULL_PTR; + } + else + { + /* Set the accel foc base address to feature engine transmission address to start DMA transaction */ + result = bma5_set_regs(BMA5_REG_FEATURE_DATA_ADDR, &data, 1, dev); + + if (result == BMA5_OK) + { + /* Get the configuration from the feature engine register */ + result = bma5_get_regs(BMA5_REG_FEATURE_DATA_TX, acc_foc_data, 10, dev); + + if (result == BMA5_OK) + { + /* First two bytes are dummy bytes */ + idx = 2; + + /* Settings 1 */ + /* Get word to calculate foc_off_x */ + lsb = (uint16_t) acc_foc_data[idx++]; + msb = ((uint16_t) acc_foc_data[idx++] << 8); + lsb_msb = (uint16_t)(lsb | msb); + + acc_foc->foc_off_x = lsb_msb & BMA530_ACC_FOC_OFF_X_MSK; + + /* Settings 2 */ + /* Get word to calculate foc_off_y */ + lsb = (uint16_t) acc_foc_data[idx++]; + msb = ((uint16_t) acc_foc_data[idx++] << 8); + lsb_msb = (uint16_t)(lsb | msb); + + acc_foc->foc_off_y = lsb_msb & BMA530_ACC_FOC_OFF_Y_MSK; + + /* Settings 3 */ + /* Get word to calculate foc_off_z */ + lsb = (uint16_t) acc_foc_data[idx++]; + msb = ((uint16_t) acc_foc_data[idx++] << 8); + lsb_msb = (uint16_t)(lsb | msb); + + acc_foc->foc_off_z = lsb_msb & BMA530_ACC_FOC_OFF_Z_MSK; + + /* Settings 4 */ + /* Get word to calculate foc_apply_corr, foc_filter_coeff and foc_axis_1g from same word */ + lsb = (uint16_t) acc_foc_data[idx++]; + msb = ((uint16_t) acc_foc_data[idx++] << 8); + lsb_msb = (uint16_t)(lsb | msb); + + acc_foc->foc_apply_corr = lsb_msb & BMA530_ACC_FOC_APPLY_CORR_MSK; + + acc_foc->foc_filter_coeff = (lsb_msb & BMA530_ACC_FOC_FILTER_COEFF_MSK) >> + BMA530_ACC_FOC_FILTER_COEFF_POS; + + acc_foc->foc_axis_1g = (lsb_msb & BMA530_ACC_FOC_AXIS_1G_MSK) >> BMA530_ACC_FOC_AXIS_1G_POS; + } + } + } + + return result; +} + +/*! + * @brief This API sets feature axis configurations + */ +int8_t bma530_set_feature_axis_config(const struct bma530_feat_axis *feat_axis, struct bma5_dev *dev) +{ + /* Variable to define error */ + int8_t result = BMA5_OK; + + /* Variable to store base address of feature axis */ + uint8_t data = BMA530_BASE_ADDR_GENERAL_SETTINGS; + + /* Array to store feature axis data */ + uint8_t feat_axis_data[4] = { 0 }; + + if (feat_axis == NULL) + { + result = BMA5_E_NULL_PTR; + } + else + { + /* Set the feature axis base address to feature engine transmission address to start DMA transaction */ + result = bma5_set_regs(BMA5_REG_FEATURE_DATA_ADDR, &data, 1, dev); + + if (result == BMA5_OK) + { + /* Get the configuration from the feature engine register */ + result = bma5_get_regs(BMA5_REG_FEATURE_DATA_TX, feat_axis_data, 4, dev); + + if (result == BMA5_OK) + { + feat_axis_data[2] = BMA5_SET_BITS(feat_axis_data[2], BMA530_FEAT_AXIS_EX, feat_axis->feat_axis_ex); + + feat_axis_data[2] = BMA5_SET_BITS(feat_axis_data[2], BMA530_FEAT_X_INV, feat_axis->feat_x_inv); + + feat_axis_data[2] = BMA5_SET_BITS(feat_axis_data[2], BMA530_FEAT_Y_INV, feat_axis->feat_y_inv); + + feat_axis_data[2] = BMA5_SET_BITS(feat_axis_data[2], BMA530_FEAT_Z_INV, feat_axis->feat_z_inv); + + feat_axis_data[0] = feat_axis_data[2]; + feat_axis_data[1] = feat_axis_data[3]; + + /* Set the configuration from the feature engine register */ + result = bma5_set_regs(BMA5_REG_FEATURE_DATA_TX, feat_axis_data, 2, dev); + } + } + } + + return result; +} + +/*! + * @brief This API gets feature axis configurations + */ +int8_t bma530_get_feature_axis_config(struct bma530_feat_axis *feat_axis, struct bma5_dev *dev) +{ + /* Variable to define error */ + int8_t result = BMA5_OK; + + /* Variable to store base address of feature axis */ + uint8_t data = BMA530_BASE_ADDR_GENERAL_SETTINGS; + + /* Array to store feature axis data */ + uint8_t feat_axis_data[4] = { 0 }; + + if (feat_axis == NULL) + { + result = BMA5_E_NULL_PTR; + } + else + { + /* Set the feature axis base address to feature engine transmission address to start DMA transaction */ + result = bma5_set_regs(BMA5_REG_FEATURE_DATA_ADDR, &data, 1, dev); + + if (result == BMA5_OK) + { + /* Get the configuration from the feature engine register */ + result = bma5_get_regs(BMA5_REG_FEATURE_DATA_TX, feat_axis_data, 4, dev); + + if (result == BMA5_OK) + { + feat_axis->feat_axis_ex = BMA5_GET_BITS(feat_axis_data[2], BMA530_FEAT_AXIS_EX); + + feat_axis->feat_x_inv = BMA5_GET_BITS(feat_axis_data[2], BMA530_FEAT_X_INV); + + feat_axis->feat_y_inv = BMA5_GET_BITS(feat_axis_data[2], BMA530_FEAT_Y_INV); + + feat_axis->feat_z_inv = BMA5_GET_BITS(feat_axis_data[2], BMA530_FEAT_Z_INV); + } + } + } + + return result; +} + +/*! + * @brief This API resets sensor. All registers are overwritten with + * their default values. + */ +int8_t bma530_soft_reset(struct bma5_dev *dev) +{ + /* Variable to store the function result */ + int8_t result; + + /* Variable to perform dummy read */ + uint8_t dummy_read; + + /* Assign soft-reset command */ + uint8_t cmd = BMA5_CMD_SOFTRESET; + + /* Null-pointer check */ + result = verify_handle(dev); + + if (result != BMA5_OK) + { + result = BMA5_E_NULL_PTR; + } + else + { + if (dev->intf == BMA5_SPI_INTF) + { + dev->dummy_byte = 1; + } + else + { + dev->dummy_byte = 0; + } + + /* Set soft-reset command */ + result = bma5_set_regs(BMA5_REG_CMD, &cmd, 1, dev); + + if (result == BMA5_OK) + { + /* Provide 2ms delay after soft-reset */ + dev->delay_us(BMA530_SOFT_RESET_DELAY, dev->intf_ptr); + + /* Dummy read is performed after soft-reset */ + result = bma5_get_regs(BMA530_REG_CHIP_ID, &dummy_read, 1, dev); + } + } + + return result; +} + +/******************************************************************************/ +/*********************** Static function definitions **************************/ +/******************************************************************************/ + +static int8_t verify_handle(const struct bma5_dev *dev) +{ + /* Function execution status */ + int8_t result = BMA5_E_NULL_PTR; + + if (NULL != dev) + { + if ((NULL != dev->bus_read) && (NULL != dev->bus_write) && (NULL != dev->delay_us)) + { + result = BMA5_OK; + } + } + + return result; +} diff --git a/bma530_features.h b/bma530_features.h new file mode 100644 index 0000000..6023b74 --- /dev/null +++ b/bma530_features.h @@ -0,0 +1,1336 @@ +/** +* Copyright (c) 2024 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 bma530_features.h +* @date 2024-04-15 +* @version v4.1.0 +* +*/ + +#ifndef _BMA530_FEATURES_H +#define _BMA530_FEATURES_H + +/*! CPP guard */ +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************/ +/****************************** Header files **********************************/ +/******************************************************************************/ + +#include "bma530.h" +#include "bma530_context.h" + +/******************************************************************************/ +/********************** Register macros for bit masking ***********************/ +/******************************************************************************/ + +/*! Feature conf error macros */ +#define BMA530_GEN_INT1_CONF_ERR_MSK UINT8_C(0x01) +#define BMA530_GEN_INT1_CONF_ERR_POS UINT8_C(0) + +#define BMA530_GEN_INT2_CONF_ERR_MSK UINT8_C(0x02) +#define BMA530_GEN_INT2_CONF_ERR_POS UINT8_C(1) + +#define BMA530_GEN_INT3_CONF_ERR_MSK UINT8_C(0x04) +#define BMA530_GEN_INT3_CONF_ERR_POS UINT8_C(2) + +#define BMA530_STEP_CONF_ERR_MSK UINT8_C(0x08) +#define BMA530_STEP_CONF_ERR_POS UINT8_C(3) + +#define BMA530_SIG_MO_CONF_ERR_MSK UINT8_C(0x10) +#define BMA530_SIG_MO_CONF_ERR_POS UINT8_C(4) + +#define BMA530_TILT_CONF_ERR_MSK UINT8_C(0x20) +#define BMA530_TILT_CONF_ERR_POS UINT8_C(5) + +#define BMA530_ORIENT_CONF_ERR_MSK UINT8_C(0x40) +#define BMA530_ORIENT_CONF_ERR_POS UINT8_C(6) + +#define BMA530_ACC_FOC_CONF_ERR_MSK UINT8_C(0x80) +#define BMA530_ACC_FOC_CONF_ERR_POS UINT8_C(7) + +/*! Step counter feature macros */ + +#define BMA530_SC_DEFAULT_WATERMARK_LEVEL UINT16_C(0x0) +#define BMA530_SC_DEFAULT_RESET_COUNTER UINT8_C(0x0) +#define BMA530_SC_DEFAULT_SD_EN UINT8_C(0x1) +#define BMA530_SC_DEFAULT_SC_EN UINT8_C(0x1) +#define BMA530_SC_DEFAULT_FILTER_COEFF_B_2 UINT16_C(0x55F) +#define BMA530_SC_DEFAULT_FILTER_COEFF_B_1 UINT16_C(0xABE) +#define BMA530_SC_DEFAULT_FILTER_COEFF_B_0 UINT16_C(0x55F) +#define BMA530_SC_DEFAULT_FILTER_COEFF_A_2 UINT16_C(0xE897) +#define BMA530_SC_DEFAULT_FILTER_COEFF_A_1 UINT16_C(0x41EF) +#define BMA530_SC_DEFAULT_FILTER_COEFF_SCALE_A UINT8_C(0xE) +#define BMA530_SC_DEFAULT_FILTER_COEFF_SCALE_B UINT8_C(0xE) + +/*! An interrupt will be triggered every time the difference in number of + * steps counted from last event is equal to (set value * 20). If 0, the interrupt is disabled */ +#define BMA530_SC_WATERMARK_LVL_MSK UINT16_C(0x03FF) +#define BMA530_SC_WATERMARK_LVL_POS UINT8_C(0) + +/*! Reset the accumulated step count value */ +#define BMA530_SC_RESET_COUNTER_MSK UINT16_C(0x0400) +#define BMA530_SC_RESET_COUNTER_POS UINT8_C(10) + +/*! Enable step detector */ +#define BMA530_SC_SD_EN_MSK UINT16_C(0x0800) +#define BMA530_SC_SD_EN_POS UINT8_C(11) + +/*! Enable step counter */ +#define BMA530_SC_SC_EN_MSK UINT16_C(0x1000) +#define BMA530_SC_SC_EN_POS UINT8_C(12) + +/*! Threshold for upper peak of acceleration magnitude for step detection */ +#define BMA530_SC_ENVELOPE_UP_THRES_MSK UINT16_C(0xFFFF) +#define BMA530_SC_ENVELOPE_UP_THRES_POS UINT8_C(0) + +/*! Adaptive upper peak threshold decay coefficient */ +#define BMA530_SC_ENVELOPE_UP_DECAY_COEFF_MSK UINT16_C(0xFFFF) +#define BMA530_SC_ENVELOPE_UP_DECAY_COEFF_POS UINT8_C(0) + +/*! Threshold for lower peak of acceleration magnitude for step detection */ +#define BMA530_SC_ENVELOPE_DOWN_THRES_MSK UINT16_C(0xFFFF) +#define BMA530_SC_ENVELOPE_DOWN_THRES_POS UINT8_C(0) + +/*! Adaptive lower peak threshold decay coefficient */ +#define BMA530_SC_ENVELOPE_DOWN_DECAY_COEFF_MSK UINT16_C(0xFFFF) +#define BMA530_SC_ENVELOPE_DOWN_DECAY_COEFF_POS UINT8_C(0) + +/*! Exponential smoothing filter coefficient for computing mean of acceleration magnitude */ +#define BMA530_SC_ACC_MEAN_DECAY_COEFF_MSK UINT16_C(0xFFFF) +#define BMA530_SC_ACC_MEAN_DECAY_COEFF_POS UINT8_C(0) + +/*! Exponential smoothing filter coefficient for computing mean duration between steps */ +#define BMA530_SC_STEP_DUR_MEAN_DECAY_COEFF_MSK UINT16_C(0xFFFF) +#define BMA530_SC_STEP_DUR_MEAN_DECAY_COEFF_POS UINT8_C(0) + +/*! Minimum number of consecutive steps to be detected for updating step count */ +#define BMA530_SC_STEP_BUFFER_SIZE_MSK UINT16_C(0x000F) +#define BMA530_SC_STEP_BUFFER_SIZE_POS UINT8_C(0) + +/*! Enable or disable cascading of filters */ +#define BMA530_SC_FILTER_CASCADE_ENABLED_MSK UINT16_C(0x0010) +#define BMA530_SC_FILTER_CASCADE_ENABLED_POS UINT8_C(4) + +/*! Scale factor for the step count to handle overcounting to undercounting */ +#define BMA530_SC_STEP_COUNTER_INCREAMENT_MSK UINT16_C(0x3FE0) +#define BMA530_SC_STEP_COUNTER_INCREAMENT_POS UINT8_C(5) + +/*! Enable or disable detection of half step */ +#define BMA530_SC_EN_HALF_STEP_MSK UINT16_C(0x4000) +#define BMA530_SC_EN_HALF_STEP_POS UINT8_C(14) + +/*! Minimum duration between two consecutive steps while walking */ +#define BMA530_SC_PEAK_DUR_MIN_WALKING_MSK UINT16_C(0x00FF) +#define BMA530_SC_PEAK_DUR_MIN_WALKING_POS UINT8_C(0) + +/*! Minimum duration between two consecutive steps while running */ +#define BMA530_SC_PEAK_DUR_MIN_RUNNING_MSK UINT16_C(0xFF00) +#define BMA530_SC_PEAK_DUR_MIN_RUNNING_POS UINT8_C(8) + +/* Ratio of acceleration magnitude variance during running to walking */ +#define BMA530_SC_ACTIVITY_DET_FACT_MSK UINT16_C(0x000F) +#define BMA530_SC_ACTIVITY_DET_FACT_POS UINT8_C(0) + +/*! Acceleration magnitude variance threshold for activity classification */ +#define BMA530_SC_ACTIVITY_DET_THRES_MSK UINT16_C(0xFFF0) +#define BMA530_SC_ACTIVITY_DET_THRES_POS UINT8_C(4) + +/*! Maximum duration between two consecutive step occurance */ +#define BMA530_SC_STEP_DUR_MAX_MSK UINT16_C(0x00FF) +#define BMA530_SC_STEP_DUR_MAX_POS UINT8_C(0) + +/*! Maximum duration since last step where next step shall be detected to add missed step, if any */ +#define BMA530_SC_STEP_DUR_WINDOW_MSK UINT16_C(0xFF00) +#define BMA530_SC_STEP_DUR_WINDOW_POS UINT8_C(8) + +/*! Enable or disable post-processing for duration between steps */ +#define BMA530_SC_EN_STEP_DUR_PP_MSK UINT16_C(0x0001) +#define BMA530_SC_EN_STEP_DUR_PP_POS UINT8_C(0) + +/*! Scale factor for mean step duration for step processing */ +#define BMA530_SC_STEP_DUR_THRES_MSK UINT16_C(0x000E) +#define BMA530_SC_STEP_DUR_THRES_POS UINT8_C(1) + +/*! Enable or disable post-processing of step based on mean crossing */ +#define BMA530_SC_EN_MCR_PP_MSK UINT16_C(0x0010) +#define BMA530_SC_EN_MCR_PP_POS UINT8_C(4) + +/*! Threshold for number of mean crossings between two consecutive steps */ +#define BMA530_SC_MCR_THRES_MSK UINT16_C(0x03E0) +#define BMA530_SC_MCR_THRES_POS UINT8_C(5) + +/*! Filter coefficient B2 of 2nd order IIR filter */ +#define BMA530_SC_FILTER_COEFF_B_2_MSK UINT16_C(0xFFFF) +#define BMA530_SC_FILTER_COEFF_B_2_POS UINT8_C(0) + +/*! Filter coefficient B1 of 2nd order IIR filter */ +#define BMA530_SC_FILTER_COEFF_B_1_MSK UINT16_C(0xFFFF) +#define BMA530_SC_FILTER_COEFF_B_1_POS UINT8_C(0) + +/*! Filter coefficient B0 of 2nd order IIR filter */ +#define BMA530_SC_FILTER_COEFF_B_0_MSK UINT16_C(0xFFFF) +#define BMA530_SC_FILTER_COEFF_B_0_POS UINT8_C(0) + +/*! Filter coefficient A2 of 2nd order IIR filter */ +#define BMA530_SC_FILTER_COEFF_A_2_MSK UINT16_C(0xFFFF) +#define BMA530_SC_FILTER_COEFF_A_2_POS UINT8_C(0) + +/*! Filter coefficient A1 of 2nd order IIR filter */ +#define BMA530_SC_FILTER_COEFF_A_1_MSK UINT16_C(0xFFFF) +#define BMA530_SC_FILTER_COEFF_A_1_POS UINT8_C(0) + +/*! Scaling of filter coefficients A of 2nd order IIR filter */ +#define BMA530_SC_FILTER_COEFF_SCALE_A_MSK UINT16_C(0x00FF) +#define BMA530_SC_FILTER_COEFF_SCALE_A_POS UINT8_C(0) + +/*! Scaling of filter coefficients B of 2nd order IIR filter */ +#define BMA530_SC_FILTER_COEFF_SCALE_B_MSK UINT16_C(0xFF00) +#define BMA530_SC_FILTER_COEFF_SCALE_B_POS UINT8_C(8) + +/*! Size of the segment for detection of significant motion of the device */ +#define BMA530_SIG_MOT_BLOCK_SIZE_MSK UINT16_C(0xFFFF) +#define BMA530_SIG_MOT_BLOCK_SIZE_POS UINT8_C(0) + +/*! Minimum value of the peak to peak acceleration magnitude */ +#define BMA530_SIG_MOT_P2P_MIN_MSK UINT16_C(0x03FF) +#define BMA530_SIG_MOT_P2P_MIN_POS UINT8_C(0) + +/*! Minimum number of mean crossing per second in acceleration magnitude */ +#define BMA530_SIG_MOT_MCR_MIN_MSK UINT16_C(0xFC00) +#define BMA530_SIG_MOT_MCR_MIN_POS UINT8_C(10) + +/*! Maximum value of the peak to peak acceleration magnitude */ +#define BMA530_SIG_MOT_P2P_MAX_MSK UINT16_C(0x03FF) +#define BMA530_SIG_MOT_P2P_MAX_POS UINT8_C(0) + +/*! Maximum number of mean crossing per second in acceleration magnitude */ +#define BMA530_SIG_MOT_MCR_MAX_MSK UINT16_C(0xFC00) +#define BMA530_SIG_MOT_MCR_MAX_POS UINT8_C(10) + +/*! Duration for which the acceleration vector is averaged to be reference vector */ +#define BMA530_TILT_SEGMENT_SIZE_MSK UINT16_C(0x00FF) +#define BMA530_TILT_SEGMENT_SIZE_POS UINT8_C(0) + +/*! Minimum angle by which the device shall be tilted for event detection */ +#define BMA530_TILT_MIN_TILT_ANGLE_MSK UINT16_C(0xFF00) +#define BMA530_TILT_MIN_TILT_ANGLE_POS UINT8_C(8) + +/*! Exponential smoothing coefficient for computing low-pass mean of acceleration vector */ +#define BMA530_TILT_BETA_ACC_MEAN_MSK UINT16_C(0xFFFF) +#define BMA530_TILT_BETA_ACC_MEAN_POS UINT8_C(0) + +/*! Selection of upside down orientation detection */ +#define BMA530_ORIENT_UD_EN_MSK UINT16_C(0x0001) +#define BMA530_ORIENT_UD_EN_POS UINT8_C(0) + +/*! Selection of mode for orientation spread in the detection plane */ +#define BMA530_ORIENT_MODE_MSK UINT16_C(0x0006) +#define BMA530_ORIENT_MODE_POS UINT8_C(1) + +/*! Blocking allows to prevent change of orientation during large movement of device */ +#define BMA530_ORIENT_BLOCKING_MSK UINT16_C(0x0018) +#define BMA530_ORIENT_BLOCKING_POS UINT8_C(3) + +/*! Maximum allowed tilt angle for device to be in flat state */ +#define BMA530_ORIENT_THETA_MSK UINT16_C(0x07E0) +#define BMA530_ORIENT_THETA_POS UINT8_C(5) + +/*! Minimum duration the device shall be in new orientation for change detection */ +#define BMA530_ORIENT_HOLD_TIME_MSK UINT16_C(0xF800) +#define BMA530_ORIENT_HOLD_TIME_POS UINT8_C(11) + +/*! Minimum slope between consecutive acceleration samples to pervent the change of orientation during large movement */ +#define BMA530_ORIENT_SLOPE_THRES_MSK UINT16_C(0x00FF) +#define BMA530_ORIENT_SLOPE_THRES_POS UINT8_C(0) + +/*! Hysteresis of acceleration for orientation change detection */ +#define BMA530_ORIENT_HYSTERESIS_MSK UINT16_C(0xFF00) +#define BMA530_ORIENT_HYSTERESIS_POS UINT8_C(8) + +/*! Android compatibility mode macros */ +#define BMA530_ANDROID_COMP_MSK UINT8_C(0x01) + +/*! Feature axis macros */ +#define BMA530_FEAT_AXIS_EX_MSK UINT8_C(0x0E) +#define BMA530_FEAT_AXIS_EX_POS UINT8_C(1) + +#define BMA530_FEAT_X_INV_MSK UINT8_C(0x10) +#define BMA530_FEAT_X_INV_POS UINT8_C(4) + +#define BMA530_FEAT_Y_INV_MSK UINT8_C(0x20) +#define BMA530_FEAT_Y_INV_POS UINT8_C(5) + +#define BMA530_FEAT_Z_INV_MSK UINT8_C(0x40) +#define BMA530_FEAT_Z_INV_POS UINT8_C(6) + +/*! Generic interrupt macors */ +/*! Minimum/maximum slope of acceleration signal for interrupt detection based on selected motion criterion. */ +#define BMA530_GEN_INT_SLOPE_THRES_MSK UINT16_C(0x0FFF) +#define BMA530_GEN_INT_SLOPE_THRES_POS UINT8_C(0) + +/*! Logical evaluation condition between enabled axis status */ +#define BMA530_GEN_INT_COMB_SEL_MSK UINT16_C(0x1000) +#define BMA530_GEN_INT_COMB_SEL_POS UINT8_C(12) + +/*! Enabling of axis for generic interrupt detection */ +#define BMA530_GEN_INT_AXIS_SEL_MSK UINT16_C(0xE000) +#define BMA530_GEN_INT_AXIS_SEL_POS UINT8_C(13) + +/*! Hysteresis for the slope of the acceleration signal */ +#define BMA530_GEN_INT_HYST_MSK UINT16_C(0x03FF) +#define BMA530_GEN_INT_HYST_POS UINT8_C(0) + +/*! Logical evaluation condition between enabled axis status */ +#define BMA530_GEN_INT_CRIT_SEL_MSK UINT16_C(0x0400) +#define BMA530_GEN_INT_CRIT_SEL_POS UINT8_C(10) + +/*! Mode of the acceleration reference update */ +#define BMA530_GEN_INT_ACC_REF_UP_MSK UINT16_C(0x1800) +#define BMA530_GEN_INT_ACC_REF_UP_POS UINT8_C(11) + +/*! Minimum duration for which the selected criterion is true for interrupt detection. */ +#define BMA530_GEN_INT_DURATION_MSK UINT16_C(0x1FFF) +#define BMA530_GEN_INT_DURATION_POS UINT8_C(0) + +/*! Wait time for clearing the event after condition evaluates false */ +#define BMA530_GEN_INT_WAIT_TIME_MSK UINT16_C(0xE000) +#define BMA530_GEN_INT_WAIT_TIME_POS UINT8_C(13) + +/*! Quiet time after an interrupt where no additional interrupts are detected */ +#define BMA530_GEN_INT_QUIET_TIME_MSK UINT16_C(0x1FFF) +#define BMA530_GEN_INT_QUIET_TIME_POS UINT8_C(0) + +/*! Reference acceleration signal for x-axis */ +#define BMA530_GEN_INT_REF_ACC_X_MSK UINT16_C(0xFFFF) +#define BMA530_GEN_INT_REF_ACC_X_POS UINT8_C(0) + +/*! Reference acceleration signal for y-axis */ +#define BMA530_GEN_INT_REF_ACC_Y_MSK UINT16_C(0xFFFF) +#define BMA530_GEN_INT_REF_ACC_Y_POS UINT8_C(0) + +/*! Reference acceleration signal for z-axis */ +#define BMA530_GEN_INT_REF_ACC_Z_MSK UINT16_C(0xFFFF) +#define BMA530_GEN_INT_REF_ACC_Z_POS UINT8_C(0) + +/*! Accel foc configuration macros */ +#define BMA530_ACC_FOC_OFF_X_MSK UINT16_C(0x01FF) +#define BMA530_ACC_FOC_OFF_X_POS UINT8_C(0) + +#define BMA530_ACC_FOC_OFF_Y_MSK UINT16_C(0x01FF) +#define BMA530_ACC_FOC_OFF_Y_POS UINT8_C(0) + +#define BMA530_ACC_FOC_OFF_Z_MSK UINT16_C(0x01FF) +#define BMA530_ACC_FOC_OFF_Z_POS UINT8_C(0) + +#define BMA530_ACC_FOC_APPLY_CORR_MSK UINT16_C(0x0001) +#define BMA530_ACC_FOC_APPLY_CORR_POS UINT8_C(0) + +#define BMA530_ACC_FOC_FILTER_COEFF_MSK UINT16_C(0x000E) +#define BMA530_ACC_FOC_FILTER_COEFF_POS UINT8_C(1) + +#define BMA530_ACC_FOC_AXIS_1G_MSK UINT16_C(0x0070) +#define BMA530_ACC_FOC_AXIS_1G_POS UINT8_C(4) + +/******************************************************************************/ +/********************* Macros for supported field values **********************/ +/******************************************************************************/ + +#define BMA530_ORIENT_MODE_SYMM UINT8_C(0x00) +#define BMA530_ORIENT_MODE_HIGH_ASYMM UINT8_C(0x01) +#define BMA530_ORIENT_MODE_LOW_ASYMM UINT8_C(0x02) + +#define BMA530_ORIENT_BLOCKING_MODE_0 UINT8_C(0x00) +#define BMA530_ORIENT_BLOCKING_MODE_1 UINT8_C(0x01) +#define BMA530_ORIENT_BLOCKING_MODE_2 UINT8_C(0x02) +#define BMA530_ORIENT_BLOCKING_MODE_3 UINT8_C(0x03) + +#define BMA530_GEN_INT_COMB_SEL_LOGICAL_OR UINT8_C(0x00) +#define BMA530_GEN_INT_COMB_SEL_LOGICAL_AND UINT8_C(0x01) + +#define BMA530_GEN_INT_CRI_SEL_INACT UINT8_C(0x00) +#define BMA530_GEN_INT_CRI_SEL_ACT UINT8_C(0x01) + +#define BMA530_GEN_INT_ACC_REF_UP_ON_EVENT UINT8_C(0x00) +#define BMA530_GEN_INT_ACC_REF_UP_ON_ALWAYS UINT8_C(0x01) +#define BMA530_GEN_INT_ACC_REF_UP_ON_MANUAL UINT8_C(0x02) + +#define BMA530_FEAT_AXIS_EX_DEFAULT_0 UINT8_C(0x00) +#define BMA530_FEAT_AXIS_EX_YXZ UINT8_C(0x01) +#define BMA530_FEAT_AXIS_EX_XZY UINT8_C(0x02) +#define BMA530_FEAT_AXIS_EX_ZXY UINT8_C(0x03) +#define BMA530_FEAT_AXIS_EX_YZX UINT8_C(0x04) +#define BMA530_FEAT_AXIS_EX_ZYX UINT8_C(0x05) +#define BMA530_FEAT_AXIS_EX_DEFAULT_6 UINT8_C(0x06) +#define BMA530_FEAT_AXIS_EX_DEFAULT_7 UINT8_C(0x07) + +#define BMA530_FEAT_X_INV_DEFAULT UINT8_C(0) +#define BMA530_FEAT_X_INV_INVERT UINT8_C(1) + +#define BMA530_FEAT_Y_INV_DEFAULT UINT8_C(0) +#define BMA530_FEAT_Y_INV_INVERT UINT8_C(1) + +#define BMA530_FEAT_Z_INV_DEFAULT UINT8_C(0) +#define BMA530_FEAT_Z_INV_INVERT UINT8_C(1) + +/*! Feature interrupts base address definitions */ +#define BMA530_BASE_ADDR_FEAT_CONF_ERR UINT8_C(0x02) +#define BMA530_BASE_ADDR_GENERAL_SETTINGS UINT8_C(0x03) +#define BMA530_BASE_ADDR_GENERIC_INT1 UINT8_C(0x04) +#define BMA530_BASE_ADDR_GENERIC_INT2 UINT8_C(0x0B) +#define BMA530_BASE_ADDR_GENERIC_INT3 UINT8_C(0x12) +#define BMA530_BASE_ADDR_STEP_COUNTER UINT8_C(0x19) +#define BMA530_BASE_ADDR_SIG_MOTION UINT8_C(0x2B) +#define BMA530_BASE_ADDR_TILT UINT8_C(0x2E) +#define BMA530_BASE_ADDR_ORIENTATION UINT8_C(0x30) +#define BMA530_BASE_ADDR_ACC_FOC UINT8_C(0x32) + +#define BMA530_AXIS_SEL_DEFAULT UINT8_C(0x07) +#define BMA530_DURATION_DEFAULT UINT8_C(0x0A) +#define BMA530_WAIT_TIME_DEFAULT UINT8_C(0x03) +#define BMA530_QUIET_TIME_DEFAULT UINT8_C(0x40) +#define BMA530_ACC_REF_X_DEFAULT UINT8_C(0x00) +#define BMA530_ACC_REF_Y_DEFAULT UINT8_C(0x00) +#define BMA530_ACC_REF_Z_DEFAULT UINT8_C(0x800) + +/*! Error status of accel config for features */ +#define BMA530_GEN_INT1_CONF_ERR_OKAY UINT8_C(0) +#define BMA530_GEN_INT1_CONF_ERR_ERR UINT8_C(1) +#define BMA530_GEN_INT2_CONF_ERR_OKAY UINT8_C(0) +#define BMA530_GEN_INT2_CONF_ERR_ERR UINT8_C(1) +#define BMA530_GEN_INT3_CONF_ERR_OKAY UINT8_C(0) +#define BMA530_GEN_INT3_CONF_ERR_ERR UINT8_C(1) +#define BMA530_STEP_CONF_ERR_OKAY UINT8_C(0) +#define BMA530_STEP_CONF_ERR_ERR UINT8_C(1) +#define BMA530_SIG_MO_CONF_ERR_OKAY UINT8_C(0) +#define BMA530_SIG_MO_CONF_ERR_ERR UINT8_C(1) +#define BMA530_TILT_CONF_ERR_OKAY UINT8_C(0) +#define BMA530_TILT_CONF_ERR_ERR UINT8_C(1) +#define BMA530_ORIENT_CONF_ERR_OKAY UINT8_C(0) +#define BMA530_ORIENT_CONF_ERR_ERR UINT8_C(1) +#define BMA530_ACC_FOC_CONF_ERR_OKAY UINT8_C(0) +#define BMA530_ACC_FOC_CONF_ERR_ERR UINT8_C(1) + +/*! Accel foc axis 1G macros */ +#define BMA530_ACC_FOC_AXIS_Z_PLUS_1G UINT8_C(0) +#define BMA530_ACC_FOC_AXIS_Z_MINUS_1G UINT8_C(1) +#define BMA530_ACC_FOC_AXIS_Y_PLUS_1G UINT8_C(2) +#define BMA530_ACC_FOC_AXIS_Y_MINUS_1G UINT8_C(3) +#define BMA530_ACC_FOC_AXIS_X_PLUS_1G UINT8_C(4) +#define BMA530_ACC_FOC_AXIS_X_MINUS_1G UINT8_C(5) +#define BMA530_AXIS_SEL_X UINT8_C(0x01) +#define BMA530_AXIS_SEL_Y UINT8_C(0x02) +#define BMA530_AXIS_SEL_Z UINT8_C(0x04) +#define BMA530_AXIS_SEL_XYZ UINT8_C(0x07) + +/*! Feature axis Exchange macros */ +#define BMA530_FEAT_AXIS_EX_SEL_X UINT8_C(0x01) +#define BMA530_FEAT_AXIS_EX_SEL_Y UINT8_C(0x02) +#define BMA530_FEAT_AXIS_EX_SEL_Z UINT8_C(0x04) +#define BMA530_FEAT_AXIS_EX_SEL_XYZ UINT8_C(0x07) + +/*! Soft-reset delay is 2ms */ +#define BMA530_SOFT_RESET_DELAY UINT16_C(2000) + +#define BMA530_GEN_INT_1 UINT8_C(0) +#define BMA530_GEN_INT_2 UINT8_C(1) +#define BMA530_GEN_INT_3 UINT8_C(2) + +/******************************************************************************/ +/***************** Structures for handling register content *******************/ +/******************************************************************************/ + +struct bma530_feat_conf_err +{ + /*! Internal filter cannot produce enough samples for generic interrupt 1 feature */ + uint8_t gen_int1_conf_err; + + /*! Internal filter cannot produce enough samples for generic interrupt 2 feature */ + uint8_t gen_int2_conf_err; + + /*! Internal filter cannot produce enough samples for generic interrupt 3 feature */ + uint8_t gen_int3_conf_err; + + /*!Internal filter cannot produce enough samples for step counter and/or step detection features*/ + uint8_t step_conf_err; + + /*! Internal filter cannot produce enough samples for significant motion detection feature.*/ + uint8_t sig_mo_conf_err; + + /*!Internal filter cannot produce enough samples for tilt detection feature.*/ + uint8_t tilt_conf_err; + + /*! Internal filter cannot produce enough samples for orientation detection feature*/ + uint8_t orient_conf_err; + + /*! Internal filter cannot produce enough samples for accelerometer fast-offset compensation feature */ + uint8_t acc_foc_conf_err; +}; + +/*! + * @brief Structure to store feature axis config + */ +struct bma530_feat_axis +{ + /*! Axes exchange scheme that is applied in host software */ + uint8_t feat_axis_ex; + + /*! Invert polarity of X-axis data after axis exchange */ + uint8_t feat_x_inv; + + /*! Invert polarity of Y-axis data after axis exchange */ + uint8_t feat_y_inv; + + /*! Invert polarity of Z-axis data after axis exchange */ + uint8_t feat_z_inv; +}; + +/*! + * @brief Structure to store generic interrupt config + */ +struct bma530_generic_interrupt +{ + /*! Minimum/maximum slope of acceleration signal for interrupt detection based on selected motion criterion. */ + uint16_t slope_thres; + + /*! Logical evaluation condition between enabled axis status + * BMA530_GEN_INT_COMB_SEL_LOGICAL_OR - 0x00 + * BMA530_GEN_INT_COMB_SEL_LOGICAL_AND - 0x01 + */ + uint8_t comb_sel; + + /*! Enabling of axis for generic interrupt detection */ + uint8_t axis_sel; + + /*! Hysteresis for the slope of the acceleration signal */ + uint16_t hysteresis; + + /*! Logical evaluation condition between enabled axis status + * BMA530_GEN_INT_CRI_SEL_INACT - 0x00 + * BMA530_GEN_INT_CRI_SEL_ACT - 0x01 + */ + uint8_t criterion_sel; + + /*! Mode of the acceleration reference update + * BMA530_GEN_INT_ACC_REF_UP_ON_EVENT - 0x00 + * BMA530_GEN_INT_ACC_REF_UP_ON_ALWAYS - 0x01 + * BMA530_GEN_INT_ACC_REF_UP_ON_MANUAL - 0x02 + */ + uint8_t acc_ref_up; + + /*! Minimum duration for which the selected criterion is true for interrupt detection. */ + uint16_t duration; + + /*! Wait time for clearing the event after condition evaluates false */ + uint8_t wait_time; + + /*! Quiet time after an interrupt where no additional interrupts are detected */ + uint16_t quiet_time; + + /*! Reference acceleration signal for x-axis */ + int16_t ref_acc_x; + + /*! Reference acceleration signal for y-axis */ + int16_t ref_acc_y; + + /*! Reference acceleration signal for z-axis */ + int16_t ref_acc_z; +}; + +/*! + * @brief Structure to holding generic interrupt configuration. + */ +struct bma530_generic_interrupt_types +{ + /*! Specify generic interrupt 1, 2, or 3 */ + uint8_t generic_interrupt; + + /*! Generic Interrupt Configuration */ + struct bma530_generic_interrupt gen_int; +}; + +/*! + * @brief Structure to store accel FOC config + */ +struct bma530_accel_foc_config +{ + /*! Accel foc offset x-axis */ + uint16_t foc_off_x; + + /*! Accel foc offset y-axis */ + uint16_t foc_off_y; + + /*! Accel foc offset z-axis */ + uint16_t foc_off_z; + + /*! Accel foc correlation */ + uint8_t foc_apply_corr; + + /*! Accel foc filter coefficient */ + uint8_t foc_filter_coeff; + + /*! Accel foc axis for 1G + * BMA530_ACC_FOC_AXIS_Z_PLUS_1G - 0x00 + * BMA530_ACC_FOC_AXIS_Z_MINUS_1G - 0x01 + * BMA530_ACC_FOC_AXIS_Y_PLUS_1G - 0x02 + * BMA530_ACC_FOC_AXIS_Y_MINUS_1G - 0x03 + * BMA530_ACC_FOC_AXIS_X_PLUS_1G - 0x04 + * BMA530_ACC_FOC_AXIS_X_MINUS_1G - 0x05 + */ + uint8_t foc_axis_1g; +}; + +/*! + * @brief Structure to store step counter config + */ +struct bma530_step_cntr +{ + /*! An interrupt will be triggered every time the difference in number of + * steps counted from last event is equal to (set value * 20). If 0, the interrupt is disabled */ + uint16_t watermark_level; + + /*! Reset the accumulated step count value */ + uint8_t reset_counter; + + /*! Enable step detector */ + uint8_t sd_en; + + /*! Enable step counter */ + uint8_t sc_en; + + /*! Threshold for upper peak of acceleration magnitude for step detection */ + uint16_t envelope_up_thres; + + /*! Adaptive upper peak threshold decay coefficient */ + uint16_t envelope_up_decay_coeff; + + /*! Threshold for lower peak of acceleration magnitude for step detection */ + uint16_t envelope_down_thres; + + /*! Adaptive lower peak threshold decay coefficient */ + uint16_t envelope_down_decay_coeff; + + /*! Exponential smoothing filter coefficient for computing mean of acceleration magnitude */ + uint16_t acc_mean_decay_coeff; + + /*! Exponential smoothing filter coefficient for computing mean duration between steps */ + uint16_t step_dur_mean_decay_coeff; + + /*! Minimum number of consecutive steps to be detected for updating step count */ + uint8_t step_buffer_size; + + /*! Enable or disable cascading of filters */ + uint8_t filter_cascade_enabled; + + /*! Scale factor for the step count to handle overcounting to undercounting */ + uint16_t step_counter_increment; + + /*! Enable or disable detection of half step */ + uint8_t en_half_step; + + /*! Minimum duration between two consecutive steps while walking */ + uint8_t peak_duration_min_walking; + + /*! Minimum duration between two consecutive steps while running */ + uint8_t peak_duration_min_running; + + /*! Ratio of acceleration magnitude variance during running to walking */ + uint8_t activity_detection_factor; + + /*! Acceleration magnitude variance threshold for activity classification */ + uint16_t activity_detection_thres; + + /*! Maximum duration between two consecutive step occurance */ + uint8_t step_duration_max; + + /*! Maximum duration since last step where next step shall be detected to add missed step, if any */ + uint8_t step_duration_window; + + /*! Enable or disable post-processing for duration between steps */ + uint8_t en_step_dur_pp; + + /*! Scale factor for mean step duration for step processing */ + uint8_t step_dur_thres; + + /*! Enable or disable post-processing of step based on mean crossing */ + uint8_t en_mcr_pp; + + /*! Threshold for number of mean crossings between two consecutive steps */ + uint16_t mcr_thres; + + /*! Filter coefficient B2 of 2nd order IIR filter */ + uint16_t filter_coeff_b_2; + + /*! Filter coefficient B1 of 2nd order IIR filter */ + uint16_t filter_coeff_b_1; + + /*! Filter coefficient B0 of 2nd order IIR filter */ + uint16_t filter_coeff_b_0; + + /*! Filter coefficient A2 of 2nd order IIR filter */ + uint16_t filter_coeff_a_2; + + /*! Filter coefficient A1 of 2nd order IIR filter */ + uint16_t filter_coeff_a_1; + + /*! Scaling of filter coefficients A of 2nd order IIR filter */ + uint8_t filter_coeff_scale_a; + + /*! Scaling of filter coefficients B of 2nd order IIR filter */ + uint8_t filter_coeff_scale_b; +}; + +/*! + * @brief Structure to store sig motion config + */ +struct bma530_sig_motion +{ + /*! Size of the segment for detection of significant motion of the device */ + uint16_t block_size; + + /*! Minimum value of the peak to peak acceleration magnitude */ + uint16_t p2p_min; + + /*! Minimum number of mean crossing per second in acceleration magnitude */ + uint8_t mcr_min; + + /*! Maximum value of the peak to peak acceleration magnitude */ + uint16_t p2p_max; + + /*! Maximum number of mean crossing per second in acceleration magnitude */ + uint8_t mcr_max; +}; + +/*! + * @brief Structure to store tilt config + */ +struct bma530_tilt +{ + /*! Duration for which the acceleration vector is averaged to be reference vector */ + uint8_t segment_size; + + /*! Minimum angle by which the device shall be tilted for event detection */ + uint8_t min_tilt_angle; + + /*! Exponential smoothing coefficient for computing low-pass mean of acceleration vector */ + uint16_t beta_acc_mean; +}; + +/*! + * @brief Structure to store orientation config + */ +struct bma530_orient +{ + /*! Selection of upside down orientation detection + * BMA530_ENABLE - 0x01 + * BMA530_DISABLE - 0x00 + */ + uint8_t ud_en; + + /*! Selection of mode for orientation spread in the detection plane + * BMA530_ORIENT_MODE_SYMM - 0x00 + * BMA530_ORIENT_MODE_HIGH_ASYMM - 0x01 + * BMA530_ORIENT_MODE_LOW_ASYMM - 0x02 + */ + uint8_t mode; + + /*! Blocking allows to prevent change of orientation during large movement of device + * BMA530_ORIENT_BLOCKING_MODE_0 - 0x00 + * BMA530_ORIENT_BLOCKING_MODE_1 - 0x01 + * BMA530_ORIENT_BLOCKING_MODE_2 - 0x02 + * BMA530_ORIENT_BLOCKING_MODE_3 - 0x03 + */ + uint8_t blocking; + + /*! Maximum allowed tilt angle for device to be in flat state */ + uint8_t theta; + + /*! Minimum duration the device shall be in new orientation for change detection */ + uint8_t hold_time; + + /*! Minimum slope between consecutive acceleration samples to pervent the change of orientation during large + * movement */ + uint8_t slope_thres; + + /*! Hysteresis of acceleration for orientation change detection */ + uint8_t hysteresis; +}; + +/*! + * @brief Structure holds: feature engine general purpose register feature output + */ +struct bma530_feat_eng_feat_out +{ + /*! Stores step counter output */ + uint32_t step_cntr_out; + + /*! Output of orientation detection feature. Device orientation can be either portrait or landscape. Value after + * device initialization is 0b00 i.e. portrait up. + */ + uint8_t orientation_portrait_landscape; + + /*! Output of orientation detection feature. Output is only valid if "ud_en" is enabled. Device orientation can be + * either face up or face down. Value after device initialization is 0b0 i.e. face up. + */ + uint8_t orientation_face_up_down; + + /*! Status of user activity reported by step counter */ + uint8_t activ_stat; + + /*! Status of generic interrupt 1 motion detection */ + uint8_t gen_int1_stat; + + /*! Status of generic interrupt 2 motion detection */ + uint8_t gen_int2_stat; + + /*! Status of generic interrupt 3 motion detection */ + uint8_t gen_int3_stat; + + /*! Feature engine initialization status + Value Name Description + 00 init_not_ok Feature engine is not initialized + 01 init_ok Feature engine is initialized + */ + uint8_t feat_init_stat; + + /*! Feature engine error related to accelerometer configuration. + Bit is set to 1 when acc_perf_mode=0 and acc_odr is less than sample rate required by features. + Bit is cleared to 0 when acc_perf_mode=1 or acc_odr is set to minimum sample rate required by features. */ + uint8_t feat_conf_err; + + /*! Bit is set to '1' if fast-offset compensation feature is being executed. Bit is cleared to '0' at the end of + * feature compensation. User should not change the accelerometer configuration while the feature is running */ + uint8_t foc_running; +}; + +/******************************************************************************/ +/********************** Function prototype declarations ***********************/ +/******************************************************************************/ + +/** + * \ingroup bma530 + * \defgroup bma530ApiInit BMA530 Initialization + * @brief Initialize the sensor and device structure + */ + +/*! + * \ingroup bma530ApiInit + * \page bma530_api_bma530_init bma530_init + * \code + * int8_t bma530_init(struct bma5_dev *dev); + * \endcode + * @details This API reads the chip-id of the sensor which is the first step to + * verify the sensor and also it configures the read mechanism of SPI and + * I2C interface. As this API is the entry point, call this API before using other APIs. + * + * @param[in,out] dev : Structure instance of bma5_dev + * + * @return Result of API execution status + * + * @retval Zero -> Success + * @retval Positive -> Warning + * @retval Negative -> Error/Failure + */ +int8_t bma530_init(struct bma5_dev *dev); + +/** + * \ingroup bma530 + * \defgroup bma530FeatureEngineApiRegs BMA530 Feature Engine APIs + * @brief Feature Engine APIs + */ + +/*! + * \ingroup bma530FeatureEngineApiRegs + * \page bma530_api_bma530_get_feat_eng_feature_out bma530_get_feat_eng_feature_out + * \code + * int8_t bma530_get_feat_eng_feature_out(struct bma530_feat_eng_feat_out *feat_out, struct bma5_dev *dev); + * \endcode + * @details This API gets feature output status from the register. + * + * @param[out] feat_out : Structure instance of bma530_feat_eng_feat_out. + * @param[in,out] dev : Structure instance of bma5_dev. + * + * @return Result of API execution status + * + * @retval = 0 -> Success + * @retval > 0 -> Warning + * @retval < 0 -> Error + */ +int8_t bma530_get_feat_eng_feature_out(struct bma530_feat_eng_feat_out *feat_out, struct bma5_dev *dev); + +/** + * \ingroup bma530 + * \defgroup bma530FeatApiRegs BMA530 Feature configuration registers + * @brief Set / Get data from the given Feature configuration register address of the sensor + */ + +/*! + * \ingroup bma530FeatApiRegs + * \page bma530_api_bma530_set_android_comp_mode bma530_set_android_comp_mode + * \code + * int8_t bma530_set_android_comp_mode(const uint8_t *android_comp, struct bma5_dev *dev); + * \endcode + * @details This API sets android compatibility mode + * + * @param[in] comp_data : Variable holds android compatibility mode data + * @param[in] dev : Structure instance of bma5_dev. + * + * @return Result of API execution status + * + * @retval = 0 -> Success + * @retval > 0 -> Warning + * @retval < 0 -> Error + */ + +int8_t bma530_set_android_comp_mode(const uint8_t *android_comp, struct bma5_dev *dev); + +/*! + * \ingroup bma530FeatApiRegs + * \page bma530_api_bma530_set_feat_conf_err bma530_set_feat_conf_err + * \code + * int8_t bma530_set_feat_conf_err(const struct bma530_feat_conf_err *feat_conf_err, struct bma5_dev *dev) + * \endcode + * @details This API sets Bits which reflects the error status of accel config for features. + * + * @param[in] feat_conf_err : Structure instance of bma530_feat_conf_err. + * @param[in] dev : Structure instance of bma5_dev. + * + * @return Result of API execution status + * + * @retval = 0 -> Success + * @retval > 0 -> Warning + * @retval < 0 -> Error + */ +int8_t bma530_set_feat_conf_err(const struct bma530_feat_conf_err *feat_conf_err, struct bma5_dev *dev); + +/*! + * \ingroup bma530FeatApiRegs + * \page bma530_api_bma530_get_feat_conf_err bma530_get_feat_conf_err + * \code + * int8_t bma530_get_feat_conf_err(const struct bma530_feat_conf_err *feat_conf_err, struct bma5_dev *dev) + * \endcode + * @details This API gets Bits which reflects the error status of accel config for features. + * + * @param[in] feat_conf_err : Structure instance of bma530_feat_conf_err. + * @param[in] dev : Structure instance of bma5_dev. + * + * @return Result of API execution status + * + * @retval = 0 -> Success + * @retval > 0 -> Warning + * @retval < 0 -> Error + */ +int8_t bma530_get_feat_conf_err(struct bma530_feat_conf_err *feat_conf_err, struct bma5_dev *dev); + +/*! + * \ingroup bma530FeatApiRegs + * \page bma530_api_bma530_get_android_comp_mode bma530_get_android_comp_mode + * \code + * int8_t bma530_get_android_comp_mode(uint8_t *android_comp, struct bma5_dev *dev); + * \endcode + * @details This API gets android compatibility mode data + * + * @param[out] android_comp : Variable holds android compatibility mode data + * @param[in,out] dev : Structure instance of bma5_dev. + * + * @return Result of API execution status + * + * @retval = 0 -> Success + * @retval > 0 -> Warning + * @retval < 0 -> Error + */ +int8_t bma530_get_android_comp_mode(uint8_t *android_comp, struct bma5_dev *dev); + +/*! + * \ingroup bma530FeatApiRegs + * \page bma530_api_bma530_set_step_counter_config bma530_set_step_counter_config + * \code + * int8_t bma530_set_step_counter_config(const struct bma530_step_cntr *step_cntr, struct bma5_dev *dev); + * \endcode + * @details This API sets step counter configuration + * + * @param[in] step_cntr : Structure instance of bma530_step_cntr. + * @param[in] dev : Structure instance of bma5_dev. + * + * @return Result of API execution status + * + * @retval = 0 -> Success + * @retval > 0 -> Warning + * @retval < 0 -> Error + */ +int8_t bma530_set_step_counter_config(const struct bma530_step_cntr *step_cntr, struct bma5_dev *dev); + +/*! + * \ingroup bma530FeatApiRegs + * \page bma530_api_bma530_get_step_counter_config bma530_get_step_counter_config + * \code + * int8_t bma530_get_step_counter_config(struct bma530_step_cntr *step_cntr, struct bma5_dev *dev); + * \endcode + * @details This API gets step counter configuration + * + * @param[out] step_cntr : Structure instance of bma530_step_cntr. + * @param[in,out] dev : Structure instance of bma5_dev. + * + * @return Result of API execution status + * + * @retval = 0 -> Success + * @retval > 0 -> Warning + * @retval < 0 -> Error + */ +int8_t bma530_get_step_counter_config(struct bma530_step_cntr *step_cntr, struct bma5_dev *dev); + +/*! + * \ingroup bma530FeatApiRegs + * \page bma530_api_bma530_get_default_step_counter_config bma530_get_step_counter_config + * \code + * int8_t bma530_get_default_step_counter_config(struct bma530_step_cntr *step_cntr, struct bma5_dev *dev); + * \endcode + * @details This API gets step counter configuration + * + * @param[out] step_cntr : Structure instance of bma530_step_cntr. + * @param[in,out] dev : Structure instance of bma5_dev. + * + * @return Result of API execution status + * + * @retval = 0 -> Success + * @retval > 0 -> Warning + * @retval < 0 -> Error + */ +int8_t bma530_get_default_step_counter_config(struct bma530_step_cntr *step_cntr, struct bma5_dev *dev); + +/*! + * \ingroup bma530FeatApiRegs + * \page bma530_api_bma530_set_sig_motion_config bma530_set_sig_motion_config + * \code + * int8_t bma530_set_sig_motion_config(const struct bma530_sig_motion *sig_mot, struct bma5_dev *dev); + * \endcode + * @details This API sets sig-motion configuration + * + * @param[in] sig_mot : Structure instance of bma530_sig_motion. + * @param[in] dev : Structure instance of bma5_dev. + * + * @return Result of API execution status + * + * @retval = 0 -> Success + * @retval > 0 -> Warning + * @retval < 0 -> Error + */ +int8_t bma530_set_sig_motion_config(const struct bma530_sig_motion *sig_mot, struct bma5_dev *dev); + +/*! + * \ingroup bma530FeatApiRegs + * \page bma530_api_bma530_get_sig_motion_config bma530_get_sig_motion_config + * \code + * int8_t bma530_get_sig_motion_config(struct bma530_sig_motion *sig_mot, struct bma5_dev *dev); + * \endcode + * @details This API gets sig-motion configuration + * + * @param[out] sig_mot : Structure instance of bma530_sig_motion. + * @param[in,out] dev : Structure instance of bma5_dev. + * + * @return Result of API execution status + * + * @retval = 0 -> Success + * @retval > 0 -> Warning + * @retval < 0 -> Error + */ +int8_t bma530_get_sig_motion_config(struct bma530_sig_motion *sig_mot, struct bma5_dev *dev); + +/*! + * \ingroup bma530FeatApiRegs + * \page bma530_api_bma530_get_default_sig_motion_config bma530_get_sig_motion_config + * \code + * int8_t bma530_get_default_sig_motion_config(struct bma530_sig_motion *sig_mot, struct bma5_dev *dev); + * \endcode + * @details This API gets sig-motion configuration + * + * @param[out] sig_mot : Structure instance of bma530_sig_motion. + * @param[in,out] dev : Structure instance of bma5_dev. + * + * @return Result of API execution status + * + * @retval = 0 -> Success + * @retval > 0 -> Warning + * @retval < 0 -> Error + */ +int8_t bma530_get_default_sig_motion_config(struct bma530_sig_motion *sig_mot, struct bma5_dev *dev); + +/*! + * \ingroup bma530FeatApiRegs + * \page bma530_api_bma530_set_tilt_config bma530_set_tilt_config + * \code + * int8_t bma530_set_tilt_config(const struct bma530_tilt *tilt, struct bma5_dev *dev); + * \endcode + * @details This API sets tilt configuration + * + * @param[in] tilt : Structure instance of bma530_tilt. + * @param[in] dev : Structure instance of bma5_dev. + * + * @return Result of API execution status + * + * @retval = 0 -> Success + * @retval > 0 -> Warning + * @retval < 0 -> Error + */ +int8_t bma530_set_tilt_config(const struct bma530_tilt *tilt, struct bma5_dev *dev); + +/*! + * \ingroup bma530FeatApiRegs + * \page bma530_api_bma530_get_tilt_config bma530_get_tilt_config + * \code + * int8_t bma530_get_tilt_config(struct bma530_tilt *tilt, struct bma5_dev *dev); + * \endcode + * @details This API gets tilt configuration + * + * @param[out] tilt : Structure instance of bma530_tilt. + * @param[in,out] dev : Structure instance of bma5_dev. + * + * @return Result of API execution status + * + * @retval = 0 -> Success + * @retval > 0 -> Warning + * @retval < 0 -> Error + */ +int8_t bma530_get_tilt_config(struct bma530_tilt *tilt, struct bma5_dev *dev); + +/*! + * \ingroup bma530FeatApiRegs + * \page bma530_api_bma530_set_orient_config bma530_set_orient_config + * \code + * int8_t bma530_set_orient_config(const struct bma530_orient *orient, struct bma5_dev *dev); + * \endcode + * @details This API sets orientation configuration + * + * @param[in] orient : Structure instance of bma530_orient. + * @param[in] dev : Structure instance of bma5_dev. + * + * @return Result of API execution status + * + * @retval = 0 -> Success + * @retval > 0 -> Warning + * @retval < 0 -> Error + */ +int8_t bma530_set_orient_config(const struct bma530_orient *orient, struct bma5_dev *dev); + +/*! + * \ingroup bma530FeatApiRegs + * \page bma530_api_bma530_get_orient_config bma530_get_orient_config + * \code + * int8_t bma530_get_orient_config(struct bma530_orient *orient, struct bma5_dev *dev); + * \endcode + * @details This API gets orientation configuration + * + * @param[out] orient : Structure instance of bma530_orient + * @param[in,out] dev : Structure instance of bma5_dev. + * + * @return Result of API execution status + * + * @retval = 0 -> Success + * @retval > 0 -> Warning + * @retval < 0 -> Error + */ +int8_t bma530_get_orient_config(struct bma530_orient *orient, struct bma5_dev *dev); + +/*! + * \ingroup bma530FeatApiRegs + * \page bma530_api_bma530_get_default_generic_int_config bma530_get_default_generic_int_config + * \code + * int8_t bma530_get_default_generic_int_config(struct bma530_generic_interrupt_types *gen_int, uint8_t n_ints, struct bma5_dev *dev); + * \endcode + * @details This API gets default values generic interrupt configurations. + * + * @param[out] gen_int : Structure instance of bma530_generic_interrupt. + * @param[in] n_ints : Number of default generic interrupt configurations to get. + * @param[in,out] dev : Structure instance of bma5_dev. + * + * @return Result of API execution status + * + * @retval = 0 -> Success + * @retval > 0 -> Warning + * @retval < 0 -> Error + */ +int8_t bma530_get_default_generic_int_config(struct bma530_generic_interrupt_types *gen_int, + uint8_t n_ints, + struct bma5_dev *dev); + +/*! + * \ingroup bma530FeatApiRegs + * \page bma530_api_bma530_set_generic_int_config bma530_set_generic_int_config + * \code + * int8_t bma530_set_generic_int_config(const struct bma530_generic_interrupt *gen_int, uint8_t n_ints, struct bma5_dev *dev); + * \endcode + * @details This API sets generic interrupt configurations. + * + * @param[in] gen_int : Structure instance of bma530_generic_interrupt. + * @param[in] n_ints : Number of default generic interrupt configurations to set. + * @param[in] dev : Structure instance of bma5_dev. + * + * @return Result of API execution status + * + * @retval = 0 -> Success + * @retval > 0 -> Warning + * @retval < 0 -> Error + */ +int8_t bma530_set_generic_int_config(const struct bma530_generic_interrupt_types *gen_int, + uint8_t n_ints, + struct bma5_dev *dev); + +/*! + * \ingroup bma530FeatApiRegs + * \page bma530_api_bma530_get_generic_int_config bma530_get_generic_int_config + * \code + * int8_t bma530_get_generic_int_config(struct bma530_generic_interrupt_types *gen_int, uint8_t n_ints, struct bma5_dev *dev); + * \endcode + * @details This API gets generic interrupt configurations. + * + * @param[out] gen_int : Structure instance of bma530_generic_interrupt. + * @param[in] n_ints : Number of default generic interrupt configurations to get. + * @param[in,out] dev : Structure instance of bma5_dev. + * + * @return Result of API execution status + * + * @retval = 0 -> Success + * @retval > 0 -> Warning + * @retval < 0 -> Error + */ +int8_t bma530_get_generic_int_config(struct bma530_generic_interrupt_types *gen_int, + uint8_t n_ints, + struct bma5_dev *dev); + +/*! + * \ingroup bma530FeatApiRegs + * \page bma530_api_bma530_set_accel_foc_config bma530_set_accel_foc_config + * \code + * int8_t bma530_set_accel_foc_config(const struct bma530_accel_foc_config *acc_foc, struct bma5_dev *dev); + * \endcode + * @details This API sets accel foc configuration + * + * @param[in] acc_foc : Structure instance of bma530_accel_foc_config. + * @param[in] dev : Structure instance of bma5_dev. + * + * @return Result of API execution status + * + * @retval = 0 -> Success + * @retval > 0 -> Warning + * @retval < 0 -> Error + */ +int8_t bma530_set_accel_foc_config(const struct bma530_accel_foc_config *acc_foc, struct bma5_dev *dev); + +/*! + * \ingroup bma530FeatApiRegs + * \page bma530_api_bma530_get_accel_foc_config bma530_get_accel_foc_config + * \code + * int8_t bma530_get_accel_foc_config(struct bma530_accel_foc_config *acc_foc, struct bma5_dev *dev); + * \endcode + * @details This API gets accel foc configuration + * + * @param[out] acc_foc : Structure instance of bma530_accel_foc_config. + * @param[in,out] dev : Structure instance of bma5_dev. + * + * @return Result of API execution status + * + * @retval = 0 -> Success + * @retval > 0 -> Warning + * @retval < 0 -> Error + */ +int8_t bma530_get_accel_foc_config(struct bma530_accel_foc_config *acc_foc, struct bma5_dev *dev); + +/*! + * \ingroup bma530FeatApiRegs + * \page bma530_api_bma530_set_feature_axis_config bma530_set_feature_axis_config + * \code + * int8_t bma530_set_feature_axis_config(const struct bma530_feat_axis *feat_axis, struct bma5_dev *dev); + * \endcode + * @details This API sets feature axis configurations. + * + * @param[in] feat_axis : Structure instance of bma530_feat_axis. + * @param[in] dev : Structure instance of bma5_dev. + * + * @return Result of API execution status + * + * @retval = 0 -> Success + * @retval > 0 -> Warning + * @retval < 0 -> Error + */ +int8_t bma530_set_feature_axis_config(const struct bma530_feat_axis *feat_axis, struct bma5_dev *dev); + +/*! + * \ingroup bma530FeatApiRegs + * \page bma530_api_bma530_get_feature_axis_config bma530_get_feature_axis_config + * \code + * int8_t bma530_get_feature_axis_config(struct bma530_feat_axis *feat_axis, struct bma5_dev *dev); + * \endcode + * @details This API gets feature axis configurations. + * + * @param[out] feat_axis : Structure instance of bma530_feat_axis. + * @param[in,out] dev : Structure instance of bma5_dev. + * + * @return Result of API execution status + * + * @retval = 0 -> Success + * @retval > 0 -> Warning + * @retval < 0 -> Error + */ +int8_t bma530_get_feature_axis_config(struct bma530_feat_axis *feat_axis, struct bma5_dev *dev); + +/** + * \ingroup bma530 + * \defgroup bma530ApiSR BMA530 Soft-reset + * @brief Set / Get data from the given register address of the sensor + */ + +/*! + * \ingroup bma530ApiSR + * \page bma530_api_bma530_soft_reset bma530_soft_reset + * \code + * int8_t bma530_soft_reset(struct bma5_dev *dev); + * \endcode + * @details This API resets sensor. All registers are overwritten with + * their default values. + * + * @param[in] dev : Structure instance of bma5_dev. + * + * @return Result of API execution status + * + * @retval = 0 -> Success + * @retval > 0 -> Warning + * @retval < 0 -> Error + */ +int8_t bma530_soft_reset(struct bma5_dev *dev); + +#ifdef __cplusplus +} +#endif /* End of CPP guard */ + +#endif /* _BMA530_FEATURES_H */ diff --git a/bma5_defs.h b/bma5_defs.h new file mode 100644 index 0000000..a23f91d --- /dev/null +++ b/bma5_defs.h @@ -0,0 +1,1438 @@ +/** +* Copyright (c) 2024 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 bma5_defs.h +* @date 2024-04-15 +* @version v4.1.0 +* +*/ + +#ifndef _BMA5_DEFS_H +#define _BMA5_DEFS_H + +/******************************************************************************/ +/****************************** Header files **********************************/ +/******************************************************************************/ +#ifdef __KERNEL__ +#include +#include +#else +#include +#include +#endif + +/******************************************************************************/ +/****************************** Common macros *********************************/ +/******************************************************************************/ +#ifdef __KERNEL__ +#if !defined(UINT8_C) && !defined(INT8_C) +#define INT8_C(x) S8_C(x) +#define UINT8_C(x) U8_C(x) +#endif + +#if !defined(UINT16_C) && !defined(INT16_C) +#define INT16_C(x) S16_C(x) +#define UINT16_C(x) U16_C(x) +#endif + +#if !defined(INT32_C) && !defined(UINT32_C) +#define INT32_C(x) S32_C(x) +#define UINT32_C(x) U32_C(x) +#endif + +#if !defined(INT64_C) && !defined(UINT64_C) +#define INT64_C(x) S64_C(x) +#define UINT64_C(x) U64_C(x) +#endif +#endif + +/*! C standard macros */ +#ifndef NULL +#ifdef __cplusplus +#define NULL 0 +#else +#define NULL ((void *) 0) +#endif +#endif + +/******************************************************************************/ +/************************* General macro definitions **************************/ +/******************************************************************************/ +/*! Macro to get bits from register data */ +#define BMA5_GET_BITS(reg_data, bitname) \ + ((reg_data & (bitname##_MSK)) >> (bitname##_POS)) + +/*! Macro to get bit value at position zero of register data */ +#define BMA5_GET_BITS_POS_0(reg_data, bitname) \ + (reg_data & (bitname##_MSK)) + +/*! Macro to set bits from register data */ +#define BMA5_SET_BITS(reg_data, bitname, data) \ + ((reg_data & ~(bitname##_MSK)) | ((data << bitname##_POS) & bitname##_MSK)) + +/*! Macro to set bit value at position zero of register data */ +#define BMA5_SET_BITS_POS_0(reg_data, bitname, data) \ + ((reg_data & ~(bitname##_MSK)) | (data & bitname##_MSK)) + +/*! Maximum buffer size of temporary buffer used for serial communication, + in bytes */ +#define BMA5_MAX_BUFFER_SIZE UINT8_C(128) + +/*! Mask definitions for SPI read/write address */ +#define BMA5_SPI_RD_MSK UINT8_C(0x80) +#define BMA5_SPI_WR_MSK UINT8_C(0x7F) + +/*! I2C address */ +#define BMA5_I2C_ADDRESS UINT8_C(0x18) + +/******************************************************************************/ +/*********************** Interface specific definitions ***********************/ +/******************************************************************************/ +/*! Serial communication interface return type */ +#ifndef BMA5_INTF_RET_TYPE +#define BMA5_INTF_RET_TYPE int8_t +#endif + +/*! Serial communication interface success code */ +#define BMA5_INTF_RET_SUCCESS INT8_C(0) + +/******************************************************************************/ +/***************************** API status codes *******************************/ +/******************************************************************************/ +/*! API success code */ +#define BMA5_OK INT8_C(0) + +/*! API error status codes */ +#define BMA5_E_NULL_PTR INT8_C(-1) +#define BMA5_E_COM_FAIL INT8_C(-2) +#define BMA5_E_DEV_NOT_FOUND INT8_C(-3) +#define BMA5_E_INVALID_CONTEXT_PARAM INT8_C(-4) +#define BMA5_E_INVALID_INTERRUPT INT8_C(-5) +#define BMA5_E_INVALID_GEN_INT INT8_C(-6) +#define BMA5_E_INVALID_INT_STATUS INT8_C(-7) + +/******************************************************************************/ +/***************************** Register addresses *****************************/ +/******************************************************************************/ +/*! This register contains internal health status information */ +#define BMA5_REG_HEALTH_STATUS UINT8_C(0x02) + +/*! Command register to activate suspend mode. */ +#define BMA5_REG_CMD_SUSPEND UINT8_C(0x04) + +/*! Global error flags */ +#define BMA5_REG_CONFIG_STATUS UINT8_C(0x10) + +/*! Global status flags */ +#define BMA5_REG_SENSOR_STATUS UINT8_C(0x11) + +/*! ACC data register 0 */ +#define BMA5_REG_ACC_DATA_0 UINT8_C(0x18) + +/*! ACC data register 1 */ +#define BMA5_REG_ACC_DATA_1 UINT8_C(0x19) + +/*! ACC data register 2 */ +#define BMA5_REG_ACC_DATA_2 UINT8_C(0x1A) + +/*! ACC data register 3 */ +#define BMA5_REG_ACC_DATA_3 UINT8_C(0x1B) + +/*! ACC data register 4 */ +#define BMA5_REG_ACC_DATA_4 UINT8_C(0x1C) + +/*! ACC data register 5 */ +#define BMA5_REG_ACC_DATA_5 UINT8_C(0x1D) + +/*! Temperature data register */ +#define BMA5_REG_TEMP_DATA UINT8_C(0x1E) + +/*! Sensor time register 0 */ +#define BMA5_REG_SENSOR_TIME_0 UINT8_C(0x1F) + +/*! Sensor time register 1 */ +#define BMA5_REG_SENSOR_TIME_1 UINT8_C(0x20) + +/*! Sensor time register 2 */ +#define BMA5_REG_SENSOR_TIME_2 UINT8_C(0x21) + +/*! FIFO fill level register (LSB) */ +#define BMA5_REG_FIFO_LEVEL_0 UINT8_C(0x22) + +/*! FIFO fill level register (MSB) */ +#define BMA5_REG_FIFO_LEVEL_1 UINT8_C(0x23) + +/*! FIFO data register */ +#define BMA5_REG_FIFO_DATA_OUT UINT8_C(0x24) + +/*! Accelerometer configuration register 0 */ +#define BMA5_REG_ACC_CONF_0 UINT8_C(0x30) + +/*! Accelerometer configuration register 1 */ +#define BMA5_REG_ACC_CONF_1 UINT8_C(0x31) + +/*! Accelerometer configuration register 2 */ +#define BMA5_REG_ACC_CONF_2 UINT8_C(0x32) + +/*! Temperature Sensor configuration register */ +#define BMA5_REG_TEMP_CONF UINT8_C(0x33) + +/*! Configuration register for INT1 */ +#define BMA5_REG_INT1_CONF UINT8_C(0x34) + +/*! Configuration register for INT2 */ +#define BMA5_REG_INT2_CONF UINT8_C(0x35) + +/*! Serial interface settings */ +#define BMA5_REG_IF_CONF_0 UINT8_C(0x3A) + +/*! Serial interface settings */ +#define BMA5_REG_IF_CONF_1 UINT8_C(0x3B) + +/*! FIFO control register */ +#define BMA5_REG_FIFO_CTRL UINT8_C(0x40) + +/*! FIFO configuration register 0 */ +#define BMA5_REG_FIFO_CONF_0 UINT8_C(0x41) + +/*! FIFO configuration register 1 */ +#define BMA5_REG_FIFO_CONF_1 UINT8_C(0x42) + +/*! FIFO watermark level register (LSB) */ +#define BMA5_REG_FIFO_WM_0 UINT8_C(0x43) + +/*! FIFO watermark level register (MSB) */ +#define BMA5_REG_FIFO_WM_1 UINT8_C(0x44) + +/*! feature engine ('feat_eng') configuration register */ +#define BMA5_REG_FEAT_ENG_CONF UINT8_C(0x50) + +/*! feature engine ('feat_eng') status register */ +#define BMA5_REG_FEAT_ENG_STATUS UINT8_C(0x51) + +/*! feature engine ('feat_eng') general purpose register configuration register */ +#define BMA5_REG_FEAT_ENG_GPR_CONF UINT8_C(0x53) + +/*! feature engine ('feat_eng') general purpose register control register */ +#define BMA5_REG_FEAT_ENG_GPR_CTRL UINT8_C(0x54) + +/*! feature engine ('feat_eng') feature data start address */ +#define BMA5_REG_FEATURE_DATA_ADDR UINT8_C(0x5E) + +/*! feature engine ('feat_eng') feature data */ +#define BMA5_REG_FEATURE_DATA_TX UINT8_C(0x5F) + +/*! user offset (x-axis) */ +#define BMA5_REG_ACC_OFFSET_0 UINT8_C(0x70) + +/*! user offset (x-axis) */ +#define BMA5_REG_ACC_OFFSET_1 UINT8_C(0x71) + +/*! user offset (y-axis) */ +#define BMA5_REG_ACC_OFFSET_2 UINT8_C(0x72) + +/*! user offset (y-axis) */ +#define BMA5_REG_ACC_OFFSET_3 UINT8_C(0x73) + +/*! user offset (z-axis) */ +#define BMA5_REG_ACC_OFFSET_4 UINT8_C(0x74) + +/*! user offset (z-axis) */ +#define BMA5_REG_ACC_OFFSET_5 UINT8_C(0x75) + +/*! Select NORMAL/SELF_TEST mode and test data. If you write to this register, the ACC data path is reset. */ +#define BMA5_REG_ACC_SELF_TEST UINT8_C(0x76) + +/*! Command Register */ +#define BMA5_REG_CMD UINT8_C(0x7E) + +/******************************************************************************/ +/********************** Register macros for bit masking ***********************/ +/******************************************************************************/ +/*! The value 0xF indicate a good internal health state. */ +#define BMA5_SENSOR_HEALTH_STATUS_MSK UINT8_C(0x0F) +#define BMA5_SENSOR_HEALTH_STATUS_POS UINT8_C(0x00) + +/*! Write '1' to activate suspend mode. The register content prior to entering this power mode will NOT be lost. */ +#define BMA5_SUSPEND_MSK UINT8_C(0x01) +#define BMA5_SUSPEND_POS UINT8_C(0x00) + +/*! Set by feature engine in case of feature engine error condition. Needs to be reseted by the host. For more details + * there are further status register in the feature engine section and inside the DMA region. */ +#define BMA5_FEAT_ENG_ERR_MSK UINT8_C(0x01) +#define BMA5_FEAT_ENG_ERR_POS UINT8_C(0x00) + +/*! This flag is set if the ACC configuration in ACC_CONF_0, ACC_CONF_1, and ACC_CONF_2 is an invalid combination. */ +#define BMA5_ACC_CONF_ERR_MSK UINT8_C(0x02) +#define BMA5_ACC_CONF_ERR_POS UINT8_C(0x01) + +/*! Set when new ACC data is available. This flag can be cleared by writing '1' to it. */ +#define BMA5_ACC_DATA_RDY_MSK UINT8_C(0x01) +#define BMA5_ACC_DATA_RDY_POS UINT8_C(0x00) + +/*! Set when new temperature data is available. This flag can be cleared by writing '1' to it. */ +#define BMA5_TEMPERATURE_RDY_MSK UINT8_C(0x02) +#define BMA5_TEMPERATURE_RDY_POS UINT8_C(0x01) + +/*! Sensor is ready for operation. */ +#define BMA5_SENSOR_RDY_MSK UINT8_C(0x04) +#define BMA5_SENSOR_RDY_POS UINT8_C(0x02) + +/*! Accelerometer data for x-axis. (LSB). The full 16bit range cover the selected g-range. (e.g. 8G-range: 1LSB = + * 16/65536=0.244 mg) */ +#define BMA5_ACC_X_7_0_MSK UINT8_C(0xFF) +#define BMA5_ACC_X_7_0_POS UINT8_C(0x00) + +/*! Accelerometer data for x-axis. (MSB). The full 16bit range cover the selected g-range. (e.g. 8G-range: 1LSB = + * 16/65536=0.244 mg) */ +#define BMA5_ACC_X_15_8_MSK UINT8_C(0xFF) +#define BMA5_ACC_X_15_8_POS UINT8_C(0x00) + +/*! Accelerometer data for y-axis. (LSB). The full 16bit range cover the selected g-range. (e.g. 8G-range: 1LSB = + * 16/65536=0.244 mg) */ +#define BMA5_ACC_Y_7_0_MSK UINT8_C(0xFF) +#define BMA5_ACC_Y_7_0_POS UINT8_C(0x00) + +/*! Accelerometer data for y-axis. (MSB). The full 16bit range cover the selected g-range. (e.g. 8G-range: 1LSB = + * 16/65536=0.244 mg) */ +#define BMA5_ACC_Y_15_8_MSK UINT8_C(0xFF) +#define BMA5_ACC_Y_15_8_POS UINT8_C(0x00) + +/*! Accelerometer data for z-axis. (LSB). The full 16bit range cover the selected g-range. (e.g. 8G-range: 1LSB = + * 16/65536=0.244 mg) */ +#define BMA5_ACC_Z_7_0_MSK UINT8_C(0xFF) +#define BMA5_ACC_Z_7_0_POS UINT8_C(0x00) + +/*! Accelerometer data for z-axis. (MSB). The full 16bit range cover the selected g-range. (e.g. 8G-range: 1LSB = + * 16/65536=0.244 mg) */ +#define BMA5_ACC_Z_15_8_MSK UINT8_C(0xFF) +#define BMA5_ACC_Z_15_8_POS UINT8_C(0x00) + +/*! Calculated temperature. Resolution: 1 K/LSB. The value 0 represents 23°C. */ +#define BMA5_TEMP_DATA_MSK UINT8_C(0xFF) +#define BMA5_TEMP_DATA_POS UINT8_C(0x00) + +/*! Sensor time in units 1 LSB = 312.5us */ +#define BMA5_SENSOR_TIME_7_0_MSK UINT8_C(0xFF) +#define BMA5_SENSOR_TIME_7_0_POS UINT8_C(0x00) + +/*! Sensor time in units 1 LSB = 312.5us */ +#define BMA5_SENSOR_TIME_15_8_MSK UINT8_C(0xFF) +#define BMA5_SENSOR_TIME_15_8_POS UINT8_C(0x00) + +/*! Sensor time in units 1 LSB = 312.5us */ +#define BMA5_SENSOR_TIME_23_16_MSK UINT8_C(0xFF) +#define BMA5_SENSOR_TIME_23_16_POS UINT8_C(0x00) + +/*! The fill level of the fifo only reflects the stored data. The frame header are not stored and not part of the FIFO + * fill level. To read out complete FIFO, the best way is to read as long as valid frames are read. LSB of the FIFO fill + * level. Should be read before the MSB register. */ +#define BMA5_FIFO_FILL_LEVEL_7_0_MSK UINT8_C(0xFF) +#define BMA5_FIFO_FILL_LEVEL_7_0_POS UINT8_C(0x00) + +/*! MSB of the FIFO fill level. Should be read after the LSB register. */ +#define BMA5_FIFO_FILL_LEVEL_10_8_MSK UINT8_C(0x07) +#define BMA5_FIFO_FILL_LEVEL_10_8_POS UINT8_C(0x00) + +/*! Output of the FIFO. During burst reads on this address the address increment stops and the FIFO can be read out with + * help of the burst read. The type of data stored in the FIFO depends on configuration stored in FIFO_CONF_* registers. + * */ +#define BMA5_FIFO_DATA_OUT_MSK UINT8_C(0xFF) +#define BMA5_FIFO_DATA_OUT_POS UINT8_C(0x00) + +/*! This bit enables/disables the accelerometer and the temperature sensor. */ +#define BMA5_SENSOR_CTRL_MSK UINT8_C(0x0F) +#define BMA5_SENSOR_CTRL_POS UINT8_C(0x00) + +/*! The ODR (Output Data Rate) in Hz. Not all settings are available in all power modes */ +#define BMA5_ACC_ODR_MSK UINT8_C(0x0F) +#define BMA5_ACC_ODR_POS UINT8_C(0x00) + +/*! Accelerometer bandwith parameter. This parameter determines the filter configuration. The different settings have a + * different impact depending on the setting of the power_mode bit. The name of the settings are therefore + * (HPM-setting)_(LPM-setting). (e.g. norm_avg4 means norm mode for HPM and avg4 for LPM) */ +#define BMA5_ACC_BWP_MSK UINT8_C(0x70) +#define BMA5_ACC_BWP_POS UINT8_C(0x04) + +/*! With this config bit, it is possible to set the basic measurement power mode. There are two possible settings:LPM + * (Low Power Mode) with duty cycling or HPM (High Performance Mode) with continous measurement. This setting has an + * influence on the signal path and the filter settings, too. */ +#define BMA5_POWER_MODE_MSK UINT8_C(0x80) +#define BMA5_POWER_MODE_POS UINT8_C(0x07) + +/*! The measurement range of the accelerometer. This setting has influence on the scaling of the ACC_DATA registers. */ +#define BMA5_ACC_RANGE_MSK UINT8_C(0x03) +#define BMA5_ACC_RANGE_POS UINT8_C(0x00) + +/*! Select roll-off of IIR filter in continuous mode. */ +#define BMA5_ACC_IIR_RO_MSK UINT8_C(0x0C) +#define BMA5_ACC_IIR_RO_POS UINT8_C(0x02) + +/*! Select the performance mode of the sensor. The choice is between high performance with lower noise or reduce the + * power consumption but with an increased noise level. The default is the high performance (lower noise). Changing this + * setting from default migh also influence the sensor behaviour like offset. This configuration should only be used in + * HPM. */ +#define BMA5_NOISE_MODE_MSK UINT8_C(0x10) +#define BMA5_NOISE_MODE_POS UINT8_C(0x04) + +/*! Configuration bit to enable/disable the auto clear mechanism of the data ready interrupt. If enabled, a clock like + * with freq=odr can be enabled on the external interrupt pin. */ +#define BMA5_ACC_DRDY_INT_AUTO_CLEAR_MSK UINT8_C(0x80) +#define BMA5_ACC_DRDY_INT_AUTO_CLEAR_POS UINT8_C(0x07) + +/*! Select rate in Hz at which the temperature is sampled. */ +#define BMA5_TEMP_RATE_MSK UINT8_C(0x07) +#define BMA5_TEMP_RATE_POS UINT8_C(0x00) + +/*! Select the input source for the temperature ADC. */ +#define BMA5_TEMP_MEAS_SRC_MSK UINT8_C(0x08) +#define BMA5_TEMP_MEAS_SRC_POS UINT8_C(0x03) + +/*! Select the external pin as source for temperature ADC. */ +#define BMA5_TEMP_EXT_SEL_MSK UINT8_C(0x10) +#define BMA5_TEMP_EXT_SEL_POS UINT8_C(0x04) + +/*! Enable temperature dependent sensitivity correction. */ +#define BMA5_TEMP_TCS_MSK UINT8_C(0x20) +#define BMA5_TEMP_TCS_POS UINT8_C(0x05) + +/*! Enable temperature dependent offset correction. */ +#define BMA5_TEMP_TCO_MSK UINT8_C(0x40) +#define BMA5_TEMP_TCO_POS UINT8_C(0x06) + +/*! Output enable for INT pin */ +#define BMA5_INT_MODE_MSK UINT8_C(0x03) +#define BMA5_INT_MODE_POS UINT8_C(0x00) + +/*! Configure behaviour of INT pin to open drain. */ +#define BMA5_INT_OD_MSK UINT8_C(0x04) +#define BMA5_INT_OD_POS UINT8_C(0x02) + +/*! Configure level of INT pin */ +#define BMA5_INT_LVL_MSK UINT8_C(0x08) +#define BMA5_INT_LVL_POS UINT8_C(0x03) + +/*! I2C slave address of this device. */ +#define BMA5_IF_I2C_SLV_ADDR_MSK UINT8_C(0x7F) +#define BMA5_IF_I2C_SLV_ADDR_POS UINT8_C(0x00) + +/*! Configuration of I3C mode */ +#define BMA5_IF_I3C_CFG_MSK UINT8_C(0x01) +#define BMA5_IF_I3C_CFG_POS UINT8_C(0x00) + +/*! Configuration of SPI3 mode(SPI 3 wire protocol). */ +#define BMA5_IF_SPI3_CFG_MSK UINT8_C(0x02) +#define BMA5_IF_SPI3_CFG_POS UINT8_C(0x01) + +/*! Configuration of CSB pullup in SPI mode */ +#define BMA5_IF_CSB_PULLUP_MSK UINT8_C(0x04) +#define BMA5_IF_CSB_PULLUP_POS UINT8_C(0x02) + +/*! Pad drive strength in I2C mode. */ +#define BMA5_IF_PAD_DRV_MSK UINT8_C(0x38) +#define BMA5_IF_PAD_DRV_POS UINT8_C(0x03) + +/*! select drive strength in I2C mode */ +#define BMA5_IF_I2C_DRV_SEL_MSK UINT8_C(0x40) +#define BMA5_IF_I2C_DRV_SEL_POS UINT8_C(0x06) + +/*! FIFO reset trigger. Writing '1' to this field synchronously resets the FIFO. */ +#define BMA5_FIFO_RST_MSK UINT8_C(0x01) +#define BMA5_FIFO_RST_POS UINT8_C(0x00) + +/*! FIFO frame synchronization trigger. Writing '1' to this field tells the FIFO that another frame is about to be + * written to FIFO_DATA_IN. */ +#define BMA5_FIFO_FRAME_SYNC_MSK UINT8_C(0x02) +#define BMA5_FIFO_FRAME_SYNC_POS UINT8_C(0x01) + +/*! Enable bit for the FIFO. Cannot be set to 1 if fifo_size equals 0. */ +#define BMA5_FIFO_CFG_MSK UINT8_C(0x01) +#define BMA5_FIFO_CFG_POS UINT8_C(0x00) + +/*! Configuration bit to enable the storage of the x-axis acceleration data in the FIFO. */ +#define BMA5_FIFO_ACC_X_MSK UINT8_C(0x02) +#define BMA5_FIFO_ACC_X_POS UINT8_C(0x01) + +/*! Configuration bit to enable the storage of the y-axis acceleration data in the FIFO. */ +#define BMA5_FIFO_ACC_Y_MSK UINT8_C(0x04) +#define BMA5_FIFO_ACC_Y_POS UINT8_C(0x02) + +/*! Configuration bit to enable the storage of the z-axis acceleration data in the FIFO. */ +#define BMA5_FIFO_ACC_Z_MSK UINT8_C(0x08) +#define BMA5_FIFO_ACC_Z_POS UINT8_C(0x03) + +/*! Enable bit for FIFO data compression. */ +#define BMA5_FIFO_COMPRESSION_MSK UINT8_C(0x10) +#define BMA5_FIFO_COMPRESSION_POS UINT8_C(0x04) + +/*! FIFO size. Since FIFO and feature engine share a common RAM, the size for the FIFO share has to be adjusted. Cannot + * be changed if locked by the feature engine. In Order to change this value, first disable the feature engine. If the + * feature engine is turned on again, a minimum share migh be needed and this setting might be changed by the feature + * engine. */ +#define BMA5_FIFO_SIZE_MSK UINT8_C(0x03) +#define BMA5_FIFO_SIZE_POS UINT8_C(0x00) + +/*! FIFO sensor time configuration. */ +#define BMA5_FIFO_SENSOR_TIME_MSK UINT8_C(0x0C) +#define BMA5_FIFO_SENSOR_TIME_POS UINT8_C(0x02) + +/*! If set, the FIFO stops storing new data if it is full. Otherwise the oldest frame is dropped in order to make room + * for a new frame. */ +#define BMA5_FIFO_STOP_ON_FULL_MSK UINT8_C(0x10) +#define BMA5_FIFO_STOP_ON_FULL_POS UINT8_C(0x04) + +/*! LSB of the FIFO watermark level. */ +#define BMA5_FIFO_WATERMARK_LEVEL_7_0_MSK UINT8_C(0xFF) +#define BMA5_FIFO_WATERMARK_LEVEL_7_0_POS UINT8_C(0x00) + +/*! LSB of the FIFO watermark level. */ +#define BMA5_FIFO_WATERMARK_LEVEL_10_8_MSK UINT8_C(0x07) +#define BMA5_FIFO_WATERMARK_LEVEL_10_8_POS UINT8_C(0x00) + +/*! An enable/disable switch for the feature engine. The feature engine is internally reseted, once the engine is + * disabled and the enabled again. */ +#define BMA5_FEAT_ENG_CTRL_MSK UINT8_C(0x01) +#define BMA5_FEAT_ENG_CTRL_POS UINT8_C(0x00) + +/*! When this field equals 1, the feature engine is currently halted. This means that the "halt" instruction has been + * executed and that the processor waits for a wakeup trigger. */ +#define BMA5_FEAT_ENG_HALTED_MSK UINT8_C(0x01) +#define BMA5_FEAT_ENG_HALTED_POS UINT8_C(0x00) + +/*! When this field equals 1, the feature engine is currently executing code. */ +#define BMA5_FEAT_ENG_RUNNING_MSK UINT8_C(0x02) +#define BMA5_FEAT_ENG_RUNNING_POS UINT8_C(0x01) + +/*! + This field reads 1’b1 as long as an update of the host-owned GPRs is pending. + */ +#define BMA5_HOST_GPR_UPDATE_PENDING_MSK UINT8_C(0x04) +#define BMA5_HOST_GPR_UPDATE_PENDING_POS UINT8_C(0x02) + +/*! + This field reads 1’b1 as long as an update of the feature engine-owned GPRs is pending. + */ +#define BMA5_FEAT_ENG_GPR_UPDATE_PENDING_MSK UINT8_C(0x08) +#define BMA5_FEAT_ENG_GPR_UPDATE_PENDING_POS UINT8_C(0x03) + +/*! host Direction for GP register 0 ('0': feature engine has write access, '1': host has write access). This field is + * only writeable by the feature engine. */ +#define BMA5_FEAT_ENG_GPR_0_DIR_MSK UINT8_C(0x01) +#define BMA5_FEAT_ENG_GPR_0_DIR_POS UINT8_C(0x00) + +/*! host Direction for GP register 1 ('0': feature engine has write access, '1': host has write access). This field is + * only writeable by the feature engine. */ +#define BMA5_FEAT_ENG_GPR_1_DIR_MSK UINT8_C(0x02) +#define BMA5_FEAT_ENG_GPR_1_DIR_POS UINT8_C(0x01) + +/*! host Direction for GP register 2 ('0': feature engine has write access, '1': host has write access). This field is + * only writeable by the feature engine. */ +#define BMA5_FEAT_ENG_GPR_2_DIR_MSK UINT8_C(0x04) +#define BMA5_FEAT_ENG_GPR_2_DIR_POS UINT8_C(0x02) + +/*! host direction for GP register 3 ('0': feature engine has write access, '1': host has write access). This field is + * only writeable by the feature engine. */ +#define BMA5_FEAT_ENG_GPR_3_DIR_MSK UINT8_C(0x08) +#define BMA5_FEAT_ENG_GPR_3_DIR_POS UINT8_C(0x03) + +/*! host direction for GP register 4 ('0': feature engine has write access, '1': host has write access). This field is + * only writeable by the feature engine. */ +#define BMA5_FEAT_ENG_GPR_4_DIR_MSK UINT8_C(0x10) +#define BMA5_FEAT_ENG_GPR_4_DIR_POS UINT8_C(0x04) + +/*! host direction for GP register 5 ('0': feature engine has write access, '1': host has write access). This field is + * only writeable by the feature engine. */ +#define BMA5_FEAT_ENG_GPR_5_DIR_MSK UINT8_C(0x20) +#define BMA5_FEAT_ENG_GPR_5_DIR_POS UINT8_C(0x05) + +/*! host direction for GP register 6 ('0': feature engine has write access, '1': host has write access). This field is + * only writeable by the feature engine. */ +#define BMA5_FEAT_ENG_GPR_6_DIR_MSK UINT8_C(0x40) +#define BMA5_FEAT_ENG_GPR_6_DIR_POS UINT8_C(0x06) + +/*! If the host writes 1’b1 to this field, it requests that the host-owned first stage registers + * are copied to the host-owned second stage registers. If the feature engine writes 1’b1 to this field, + * it requests that the feature engine-owned first stage registers are copied to the feature engine-owned + * second stage registers. */ +#define BMA5_UPDATE_GPRS_MSK UINT8_C(0x01) +#define BMA5_UPDATE_GPRS_POS UINT8_C(0x00) + +/*! If the host writes 1’b1 to this field, it releases the lock of the feature engine-owned GPRs + * and thus allows for an update of the feature engine-owned second stage registers. + * If the feature engine writes 1’b1 to this field, it releases the lock of the host-owned GPRs + * and thus allows for an update of the host-owned second stage registers. */ +#define BMA5_UNLOCK_GPRS_MSK UINT8_C(0x02) +#define BMA5_UNLOCK_GPRS_POS UINT8_C(0x01) + +/*! Feature data address. For the address values see the extended memory map. */ +#define BMA5_FEATURE_DATA_ADDR_MSK UINT8_C(0x7F) +#define BMA5_FEATURE_DATA_ADDR_POS UINT8_C(0x00) + +/*! The data port associated with feature_data_addr. During burst read/write operations on this address the address + * increment stops and the burst operation can be used to read/write multiple feature_data words. See the extendend + * memory map for details. */ +#define BMA5_FEATURE_DATA_MSK UINT8_C(0xFF) +#define BMA5_FEATURE_DATA_POS UINT8_C(0x00) + +/*! Accelerometer offset correction values */ +#define BMA5_ACC_DOFF_7_0_MSK UINT8_C(0xFF) +#define BMA5_ACC_DOFF_8_MSK UINT8_C(0x01) + +/*! Accelerometer offset correction value for x-axis */ +#define BMA5_ACC_DOFF_X_7_0_MSK UINT8_C(0xFF) +#define BMA5_ACC_DOFF_X_7_0_POS UINT8_C(0x00) + +/*! Accelerometer offset correction value for x-axis */ +#define BMA5_ACC_DOFF_X_8_MSK UINT8_C(0x01) +#define BMA5_ACC_DOFF_X_8_POS UINT8_C(0x00) + +/*! Accelerometer offset correction value for y-axis */ +#define BMA5_ACC_DOFF_Y_7_0_MSK UINT8_C(0xFF) +#define BMA5_ACC_DOFF_Y_7_0_POS UINT8_C(0x00) + +/*! Accelerometer offset correction value for y-axis */ +#define BMA5_ACC_DOFF_Y_8_MSK UINT8_C(0x01) +#define BMA5_ACC_DOFF_Y_8_POS UINT8_C(0x00) + +/*! Accelerometer offset correction value for z-axis */ +#define BMA5_ACC_DOFF_Z_7_0_MSK UINT8_C(0xFF) +#define BMA5_ACC_DOFF_Z_7_0_POS UINT8_C(0x00) + +/*! Accelerometer offset correction value for z-axis */ +#define BMA5_ACC_DOFF_Z_8_MSK UINT8_C(0x01) +#define BMA5_ACC_DOFF_Z_8_POS UINT8_C(0x00) + +/*! Enable flag for the self test mode. */ +#define BMA5_SELF_TEST_MSK UINT8_C(0x01) +#define BMA5_SELF_TEST_POS UINT8_C(0x00) + +/*! Select sign of self test excitation */ +#define BMA5_SELF_TEST_SIGN_MSK UINT8_C(0x02) +#define BMA5_SELF_TEST_SIGN_POS UINT8_C(0x01) + +/*! Available commands (Note: Register will always read as 0x00): */ +#define BMA5_CMD_MSK UINT8_C(0xFF) +#define BMA5_CMD_POS UINT8_C(0x00) + +/******************************************************************************/ +/********************* Macros for supported field values **********************/ +/******************************************************************************/ +/* Macros to define the supported suspend values */ +#define BMA5_SUSPEND_DISABLE UINT8_C(0x00) /*! Suspend mode is disabled. Sensor in normal operation + * mode. */ +#define BMA5_SUSPEND_ENABLE UINT8_C(0x01) /*! Suspend mode is enabled. Only Register CHIP_ID and + * this register are accessible. */ + +/* Macros to define the supported feat_eng_err values */ +#define BMA5_FEAT_ENG_ERR_OKAY UINT8_C(0x00) /*! feature engine is okay */ +#define BMA5_FEAT_ENG_ERR_ERR UINT8_C(0x01) /*! feature engine indicates error */ + +/* Macros to define the supported acc_conf_err values */ +#define BMA5_ACC_CONF_ERR_OKAY UINT8_C(0x00) /*! sensor configuration okay */ +#define BMA5_ACC_CONF_ERR_ERR UINT8_C(0x01) /*! sensor configuration invalid */ + +/* Macros to define the supported sensor_ctrl values */ +#define BMA5_SENSOR_CTRL_DISABLE UINT8_C(0x00) /*! The accelerometer and the temperature sensor + * are disabled. */ +#define BMA5_SENSOR_CTRL_ENABLE UINT8_C(0x0F) /*! The accelerometer and the temperature sensor + * are enabled. */ +#define BMA5_SENSOR_CTRL_DIS_ERR UINT8_C(0x0E) /*! A wrong configuration was found: The + * accelerometer and the temperature sensor are + * disabled. */ + +/* Macros to define the supported acc_odr values */ +#define BMA5_ACC_ODR_HZ_1P5625 UINT8_C(0x00) /*! 1.5625 Hz. Only available in duty cycling + * mode (LPM). */ +#define BMA5_ACC_ODR_HZ_3P125 UINT8_C(0x01) /*! 3.125 Hz. Only available in duty cycling + * mode (LPM). */ +#define BMA5_ACC_ODR_HZ_6P25 UINT8_C(0x02) /*! 6.25 Hz.Only available in duty cycling mode + * (LPM). */ +#define BMA5_ACC_ODR_HZ_12P5 UINT8_C(0x03) /*! 12.5 Hz. */ +#define BMA5_ACC_ODR_HZ_25 UINT8_C(0x04) /*! 25 Hz. */ +#define BMA5_ACC_ODR_HZ_50 UINT8_C(0x05) /*! 50 Hz. */ +#define BMA5_ACC_ODR_HZ_100 UINT8_C(0x06) /*! 100 Hz. */ +#define BMA5_ACC_ODR_HZ_200 UINT8_C(0x07) /*! 200 Hz. */ +#define BMA5_ACC_ODR_HZ_400 UINT8_C(0x08) /*! 400 Hz. */ +#define BMA5_ACC_ODR_HZ_800 UINT8_C(0x09) /*! 800 Hz. Only available in continuous mode + * (HPM). */ +#define BMA5_ACC_ODR_HZ_1K6 UINT8_C(0x0A) /*! 1.6 kHz. Only available in continuous mode + * (HPM). */ +#define BMA5_ACC_ODR_HZ_3K2 UINT8_C(0x0B) /*! 3.2 kHz. Only available in continuous mode + * (HPM). */ +#define BMA5_ACC_ODR_HZ_6K4 UINT8_C(0x0C) /*! 6.4 kHz. Only available in continuous mode + * (HPM). */ + +/* Macros to define the supported acc_bwp values */ +#define BMA5_ACC_BWP_OSR4_AVG1 UINT8_C(0x00) /*! HPM --> OSR4 mode; LPM --> no averaging. */ +#define BMA5_ACC_BWP_OSR2_AVG2 UINT8_C(0x01) /*! HPM --> OSR2 mode; LPM --> average 2 + * samples. */ +#define BMA5_ACC_BWP_NORM_AVG4 UINT8_C(0x02) /*! HPM --> normal mode; LPM --> average 4 + * samples. */ +#define BMA5_ACC_BWP_CIC_AVG8 UINT8_C(0x03) /*! HPM --> CIC mode; LPM --> average 8 samples. + * */ + +/* Macros to define the supported power_mode values */ +#define BMA5_POWER_MODE_LPM UINT8_C(0x00) /*! LPM: Low power mode (Duty Cycling mode) */ +#define BMA5_POWER_MODE_HPM UINT8_C(0x01) /*! HPM: High Performance Mode (Continuous mode) + * */ + +/* Macros to define the supported acc_range values */ +#define BMA5_ACC_RANGE_MAX_2G UINT8_C(0x00) /*! measurement range: +/-2g. */ +#define BMA5_ACC_RANGE_MAX_4G UINT8_C(0x01) /*! measurement range: +/-4g. */ +#define BMA5_ACC_RANGE_MAX_8G UINT8_C(0x02) /*! measurement range: +/-8g. */ +#define BMA5_ACC_RANGE_MAX_16G UINT8_C(0x03) /*! measurement range: +/-16g. */ + +/* Macros to define the supported acc_iir_ro values */ +#define BMA5_ACC_IIR_RO_DB_20 UINT8_C(0x01) /*! -20dB roll-off */ +#define BMA5_ACC_IIR_RO_DB_40 UINT8_C(0x02) /*! -40dB roll-off */ +#define BMA5_ACC_IIR_RO_DB_60 UINT8_C(0x03) /*! -60dB roll-off */ + +/* Macros to define the supported noise_mode values */ +#define BMA5_NOISE_MODE_LOWER_NOISE UINT8_C(0x00) /*! Default config. Lower noise level. */ +#define BMA5_NOISE_MODE_LOWER_POWER UINT8_C(0x01) /*! Lower power consumption. Higher noise level. + * This setting should only be used in HPM mode! + * */ + +/* Macros to define the supported acc_drdy_int_auto_clear values */ +#define BMA5_ACC_DRDY_INT_AUTO_CLEAR_DISABLED UINT8_C(0x00) /*! The status flag of acc_drdy_int is not + * cleared automatically. */ +#define BMA5_ACC_DRDY_INT_AUTO_CLEAR_ENABLED UINT8_C(0x01) /*! The status flag of acc_drdy_int is cleared + * automatically after approximately 1/(2*ODR). + * */ + +/* Macros to define the supported temp_rate values */ +#define BMA5_TEMP_RATE_HZ_1P5625 UINT8_C(0x00) /*! Sample temperature at 1.5625 Hz. */ +#define BMA5_TEMP_RATE_HZ_3P125 UINT8_C(0x01) /*! Sample temperature at 3.125 Hz. */ +#define BMA5_TEMP_RATE_HZ_6P25 UINT8_C(0x02) /*! Sample temperature at 6.25 Hz. */ +#define BMA5_TEMP_RATE_HZ_12P5 UINT8_C(0x03) /*! Sample temperature at 12.5 Hz. */ +#define BMA5_TEMP_RATE_HZ_25 UINT8_C(0x04) /*! Sample temperature at 25 Hz. */ +#define BMA5_TEMP_RATE_HZ_50 UINT8_C(0x05) /*! Sample temperature at 50 Hz. */ +#define BMA5_TEMP_RATE_HZ_100 UINT8_C(0x06) /*! Sample temperature at 100 Hz. */ +#define BMA5_TEMP_RATE_HZ_200 UINT8_C(0x07) /*! Sample temperature at 200 Hz. */ + +/* Macros to define the supported temp_meas_src values */ +#define BMA5_TEMP_MEAS_SRC_TMP_INT UINT8_C(0x00) /*! internal temperature diode */ +#define BMA5_TEMP_MEAS_SRC_TMP_EXT UINT8_C(0x01) /*! external input as configured by tmp_pin_sel + * */ + +/* Macros to define the supported temp_ext_sel values */ +#define BMA5_TEMP_EXT_SEL_INT1 UINT8_C(0x00) /*! interrupt pin INT1 */ +#define BMA5_TEMP_EXT_SEL_INT2 UINT8_C(0x01) /*! interrupt pin INT2 */ + +/* Macros to define the supported temp_tcs values */ +#define BMA5_TEMP_TCS_DISABLE UINT8_C(0x00) /*! TCS correction disabled */ +#define BMA5_TEMP_TCS_ENABLE UINT8_C(0x01) /*! TCS correction enabled */ + +/* Macros to define the supported temp_tco values */ +#define BMA5_TEMP_TCO_DISABLE UINT8_C(0x00) /*! TCO correction disabled */ +#define BMA5_TEMP_TCO_ENABLE UINT8_C(0x01) /*! TCO correction enabled */ + +/* Macros to define the supported int1_mode values */ +#define BMA5_INT1_MODE_OFF UINT8_C(0x00) /*! Output disabled. */ +#define BMA5_INT1_MODE_LATCHED UINT8_C(0x01) /*! Latched (level triggered) interrupts. */ +#define BMA5_INT1_MODE_PULSED_SHORT UINT8_C(0x02) /*! Pulsed (edge triggered) interrupts with + * + * + * + * + * + * + * * + * short pulses. */ +#define BMA5_INT1_MODE_PULSED_LONG UINT8_C(0x03) /*! Pulsed (edge triggered) interrupts with long + * pulses. */ + +/* Macros to define the supported int1_od values */ +#define BMA5_INT1_OD_PUSH_PULL UINT8_C(0x00) /*! push-pull */ +#define BMA5_INT1_OD_OPEN_DRAIN UINT8_C(0x01) /*! open drain */ + +/* Macros to define the supported int1_lvl values */ +#define BMA5_INT1_LVL_ACTIVE_LOW UINT8_C(0x00) /*! active low */ +#define BMA5_INT1_LVL_ACTIVE_HIGH UINT8_C(0x01) /*! active high */ + +/* Macros to define the supported int2_mode values */ +#define BMA5_INT2_MODE_OFF UINT8_C(0x00) /*! Output disabled. */ +#define BMA5_INT2_MODE_LATCHED UINT8_C(0x01) /*! Latched (level triggered) interrupts. */ +#define BMA5_INT2_MODE_PULSED_SHORT UINT8_C(0x02) /*! Pulsed (edge triggered) interrupts with + * short pulses. */ +#define BMA5_INT2_MODE_PULSED_LONG UINT8_C(0x03) /*! Pulsed (edge triggered) interrupts with long + * pulses. */ + +/* Macros to define the supported int2_od values */ +#define BMA5_INT2_OD_PUSH_PULL UINT8_C(0x00) /*! push-pull */ +#define BMA5_INT2_OD_OPEN_DRAIN UINT8_C(0x01) /*! open drain */ + +/* Macros to define the supported int2_lvl values */ +#define BMA5_INT2_LVL_ACTIVE_LOW UINT8_C(0x00) /*! active low */ +#define BMA5_INT2_LVL_ACTIVE_HIGH UINT8_C(0x01) /*! active high */ + +/* Macros to define the supported if_i2c_slv_addr values */ +#define BMA5_IF_I2C_SLV_ADDR_I2C_DEFAULT_ADDR UINT8_C(0x18) /*! the default i2c slave address of this device + * */ + +/* Macros to define the supported if_i3c_cfg values */ +#define BMA5_IF_I3C_CFG_DISABLE UINT8_C(0x00) /*! The I3C mode is disabled. */ +#define BMA5_IF_I3C_CFG_ENABLE UINT8_C(0x01) /*! The I3C mode is enabled. */ + +/* Macros to define the supported if_spi3_cfg values */ +#define BMA5_IF_SPI3_CFG_DISABLE UINT8_C(0x00) /*! The SPI3 mode is disabled. */ +#define BMA5_IF_SPI3_CFG_ENABLE UINT8_C(0x01) /*! The SPI3 mode is enabled. */ + +/* Macros to define the supported if_csb_pullup values */ +#define BMA5_IF_CSB_PULLUP_DISABLE UINT8_C(0x00) /*! The pullup is disabled. */ +#define BMA5_IF_CSB_PULLUP_ENABLE UINT8_C(0x01) /*! The pullup is enabled. */ + +/* Macros to define the supported if_i2c_drv_sel values */ +#define BMA5_IF_I2C_DRV_SEL_I2C_MAX_PAD_DRV UINT8_C(0x00) /*! use maximum pad drive strength */ +#define BMA5_IF_I2C_DRV_SEL_I2C_CFG_PAD_DRV UINT8_C(0x01) /*! use drive strength settings of if_pad_drv */ + +/* Macros to define the supported fifo_cfg values */ +#define BMA5_FIFO_CFG_DISABLE UINT8_C(0x00) /*! The FIFO is disabled. */ +#define BMA5_FIFO_CFG_ENABLE UINT8_C(0x01) /*! The FIFO is enabled. */ + +/* Macros to define the supported fifo_acc_x values */ +#define BMA5_FIFO_ACC_X_DISABLE UINT8_C(0x00) /*! The FIFO x-axis acceleration channel is + * disabled. */ +#define BMA5_FIFO_ACC_X_ENABLE UINT8_C(0x01) /*! The FIFO x-axis acceleration channel is + * disabled. */ + +/* Macros to define the supported fifo_acc_y values */ +#define BMA5_FIFO_ACC_Y_DISABLE UINT8_C(0x00) /*! The FIFO y-axis acceleration channel is + * disabled. */ +#define BMA5_FIFO_ACC_Y_ENABLE UINT8_C(0x01) /*! The FIFO y-axis acceleration channel is + * disabled. */ + +/* Macros to define the supported fifo_acc_z values */ +#define BMA5_FIFO_ACC_Z_DISABLE UINT8_C(0x00) /*! The FIFO z-axis acceleration channel is + * disabled. */ +#define BMA5_FIFO_ACC_Z_ENABLE UINT8_C(0x01) /*! The FIFO z-axis acceleration channel is + * disabled. */ + +/* Macros to define the supported fifo_compression values */ +#define BMA5_FIFO_COMPRESSION_ACC_16BIT UINT8_C(0x00) /*! compression disbaled. full 16bit + * acceleration data. */ +#define BMA5_FIFO_COMPRESSION_ACC_8BIT UINT8_C(0x01) /*! compression enabled. 8bit compressed + * acceleration data. */ + +/* Macros to define the supported fifo_size values */ +#define BMA5_FIFO_SIZE_MAX_0_BYTES UINT8_C(0x00) /*! The FIFO has a size of 0 bytes. The feature + * engine ('feat_eng') has a RAM size of 1024 + * bytes. This setting forces fifo_en to 0. */ +#define BMA5_FIFO_SIZE_MAX_256_BYTES UINT8_C(0x01) /*! The FIFO has a size of 256 bytes. The + * feature engine ('feat_eng') has a RAM size of + * 768 bytes. */ +#define BMA5_FIFO_SIZE_MAX_512_BYTES UINT8_C(0x02) /*! The FIFO has a size of 512 bytes. The + * feature engine ('feat_eng') has a RAM size of + * 512 bytes. */ +#define BMA5_FIFO_SIZE_MAX_1024_BYTES UINT8_C(0x03) /*! The FIFO has a size of 1024 bytes. The + * feature engine ('feat_eng') has a RAM size of + * 0 bytes. This setting forces feature engine + * ('feat_eng')_en to 0. */ + +/* Macros to define the supported fifo_sensor_time values */ +#define BMA5_FIFO_SENSOR_TIME_OFF UINT8_C(0x00) /*! The FIFO does not transmit the sensor time. + * */ +#define BMA5_FIFO_SENSOR_TIME_DEDICATED_FRAME UINT8_C(0x01) /*! The FIFO sends a dedicated sensor time frame + * when the FIFO runs empty during a read burst. + * */ +#define BMA5_FIFO_SENSOR_TIME_EACH_FRAME UINT8_C(0x02) /*! The FIFO has appends the sensor time to each + * frame. */ + +/* Macros to define the supported fifo_stop_on_full values */ +#define BMA5_FIFO_STOP_ON_FULL_DISABLED UINT8_C(0x00) /*! feature disbaled.The FIFO will be filled + * continously with new data, old data will be + * dropped. */ +#define BMA5_FIFO_STOP_ON_FULL_ENABLED UINT8_C(0x01) /*! feature enabled. The FIFO will stop, when it + * is full. */ + +/* Macros to define the supported feat_eng_ctrl values */ +#define BMA5_FEAT_ENG_CTRL_DISABLE UINT8_C(0x00) /*! the feature engine is disabled (and reset) + * */ +#define BMA5_FEAT_ENG_CTRL_ENABLE UINT8_C(0x01) /*! the feature engine is enabled. */ + +/* Macros to define the supported self_test values */ +#define BMA5_SELF_TEST_DISABLE UINT8_C(0x00) /*! normal operation mode */ +#define BMA5_SELF_TEST_ENABLE UINT8_C(0x01) /*! built-in test excitation mode */ + +/* Macros to define the supported self_test_sign values */ +#define BMA5_SELF_TEST_SIGN_NEGATIVE UINT8_C(0x00) /*! negative */ +#define BMA5_SELF_TEST_SIGN_POSITIVE UINT8_C(0x01) /*! positive */ + +/* Macros to define the supported cmd values */ +#define BMA5_CMD_SOFTRESET UINT8_C(0xB6) /*! Triggers a reset, all user configuration + * settings are overwritten with their default + * state. If this register is set using I2C, an + * ACK will NOT be transmitted to the host */ + +/* Macros to define different interrupts */ +#define BMA5_INT_1 UINT8_C(0) +#define BMA5_INT_2 UINT8_C(1) + +#define BMA5_16_BIT_RESOLUTION UINT8_C(16) +#define BMA5_8_BIT_RESOLUTION UINT8_C(8) + +#define BMA5_FIFO_8_BIT_ACCEL_XYZ_DATA UINT8_C(3) +#define BMA5_FIFO_8_BIT_ACCEL_XYZ_SENS_TIME_DATA UINT8_C(6) +#define BMA5_FIFO_16_BIT_ACCEL_XYZ_DATA UINT8_C(6) +#define BMA5_FIFO_16_BIT_ACCEL_XYZ_SENS_TIME_DATA UINT8_C(9) + +/*! FIFO header byte mask */ +#define BMA5_FIFO_SENS_TIME_EN_HDR_BYTE_MSK UINT8_C(0x01) + +/*! FIFO sensor time length definitions */ +#define BMA5_SENSOR_TIME_LENGTH UINT8_C(3) + +/*! FIFO warning macros */ +#define BMA5_W_FIFO_EMPTY UINT8_C(1) +#define BMA5_W_FIFO_PARTIAL_READ UINT8_C(2) + +#define BMA5_FIFO_SENS_TIME_EN_DEDI_FRM UINT8_C(0xA1) +#define BMA5_FIFO_SENS_TIME_EN_EACH_FRM UINT8_C(0xC1) + +#define BMA5_FIFO_FRAME_HDR_MSK UINT8_C(0xFF) + +/*! FIFO sensortime overhead byte macros + * NOTE : Only payload is stored in the FIFO memory. + * The header is always generated on demand when the FIFO is read. + * Overhead byte is added to accommodate various FIFO combinations. + */ +#define BMA5_SENSORTIME_OVERHEAD_BYTE UINT16_C(1024) + +/*! Enable/Disable macros */ +#define BMA5_ENABLE UINT8_C(1) +#define BMA5_DISABLE UINT8_C(0) + +/*! Self-test macros */ +#define BMA5_SELF_TEST_DELAY UINT16_C(10000) +#define BMA5_SELF_TEST_ACCEL_DISABLE_DELAY UINT16_C(50000) +#define BMA5_SELF_TEST_MIN_THRESHOLD_X UINT16_C(17500) +#define BMA5_SELF_TEST_MIN_THRESHOLD_Y UINT16_C(17500) +#define BMA5_SELF_TEST_MIN_THRESHOLD_Z UINT16_C(8000) + +/*! Accel foc axis 1G macros */ +#define BMA5_ACC_FOC_AXIS_Z_PLUS_1G UINT8_C(0) +#define BMA5_ACC_FOC_AXIS_Z_MINUS_1G UINT8_C(1) +#define BMA5_ACC_FOC_AXIS_Y_PLUS_1G UINT8_C(2) +#define BMA5_ACC_FOC_AXIS_Y_MINUS_1G UINT8_C(3) +#define BMA5_ACC_FOC_AXIS_X_PLUS_1G UINT8_C(4) +#define BMA5_ACC_FOC_AXIS_X_MINUS_1G UINT8_C(5) +#define BMA5_AXIS_SEL_X UINT8_C(0x01) +#define BMA5_AXIS_SEL_Y UINT8_C(0x02) +#define BMA5_AXIS_SEL_Z UINT8_C(0x04) +#define BMA5_AXIS_SEL_XYZ UINT8_C(0x07) + +#define BMA5_FIFO_RST_TRIGGER_ENABLE UINT8_C(0x01) +#define BMA5_FIFO_RST_TRIGGER_DISABLE UINT8_C(0x00) + +/*! @name For defining absolute values */ +#define BMA5_ABS(a) ((a) > 0 ? (a) : -(a)) + +/******************************************************************************/ +/***************************** Function pointers ******************************/ +/******************************************************************************/ + +/*! + * @brief Pointer to be mapped to the platform specific bus read function of the + * user + * + * @param[in] reg_addr : Address of the register which needs to be read + * @param[out] reg_data : Buffer to carry the data from the specified address + * @param[in] length : Length of the data to be read in bytes + * @param[in,out] intf_ptr : Pointer that can enable the linking of descriptors + * for interface related callbacks + * + * @retval Zero for success + * @retval Non-zero for failure + */ +typedef BMA5_INTF_RET_TYPE (*bma5_read_fptr_t)(uint8_t reg_addr, uint8_t *reg_data, uint32_t length, void *intf_ptr); + +/*! + * @brief Pointer to be mapped to the platform specific bus write function of + * the user + * + * @param[in] reg_addr : Address of the register which needs to be written + * @param[in] reg_data : Data to be written to the specified address + * @param[in] length : Number of bytes to be written to the address + * @param[in,out] intf_ptr : Pointer that can enable the linking of descriptors + * for interface related callbacks + * + * @retval Zero for success + * @retval Non-zero for failure + */ +typedef BMA5_INTF_RET_TYPE (*bma5_write_fptr_t)(uint8_t reg_addr, const uint8_t *reg_data, uint32_t length, + void *intf_ptr); + +/*! + * @brief Pointer to be mapped to the platform specific delay function of user + * + * @param[in] period : Time period in microseconds + * @param[in,out] intf_ptr : Pointer that can enable the linking of descriptors + * for interface related callbacks + */ +typedef void (*bma5_delay_us_fptr_t)(uint32_t period, void *intf_ptr); + +/******************************************************************************/ +/******************************** Enumerators *********************************/ +/******************************************************************************/ + +/*! + * Enumerator to describe the interfaces + */ +enum bma5_intf { + /*! SPI interface */ + BMA5_SPI_INTF = 0, + /*! I2C interface */ + BMA5_I2C_INTF +}; + +/*! + * Enumerator to describe the interfaces + */ +enum bma5_context { + /*! Hearable */ + BMA5_HEARABLE = 0, + /*! Wearable */ + BMA5_WEARABLE, + /*! Smartphone */ + BMA5_SMARTPHONE +}; + +/******************************************************************************/ +/************************** Primary device structure **************************/ +/******************************************************************************/ + +/* + * @brief Primary device handle + */ +struct bma5_dev +{ + /*! Chip identification code for BMA5 */ + uint8_t chip_id; + + /*! SPI/I2C interface selection */ + enum bma5_intf intf; + + /*! Platform specific function to perform platform specific read operation + * corresponding to the selected interface */ + bma5_read_fptr_t bus_read; + + /*! Platform specific function to perform platform specific write operation + * corresponding to the selected interface */ + bma5_write_fptr_t bus_write; + + /*! Platform specific function to perform platform specific delay operation + * in microseconds */ + bma5_delay_us_fptr_t delay_us; + + /*! Pointer to enable the user to link their interface descriptors for + * reference during the implementation of the read and write interfaces to + * the hardware. + */ + void *intf_ptr; + + /*! The underlying interface operation results */ + BMA5_INTF_RET_TYPE intf_rslt; + + /*! The number of dummy bytes expected over serial communication interface. + * This field can further be used for specifying the dummy bytes expected + * over the serial communication with the auxillary as well. + */ + uint8_t dummy_byte; + + /*! Context parameter selection */ + enum bma5_context context; +}; + +/******************************************************************************/ +/***************** Structures for handling register content *******************/ +/******************************************************************************/ + +/*! + * @brief Structure holding Global error flags + */ +struct bma5_config_status +{ + /*! Set by feature engine in case of feature engine error condition. Needs to be reseted by the host. For more + * details there are further status register in the feature engine section and inside the DMA region. */ + uint8_t feat_eng_err; + + /*! This flag is set if the ACC configuration in ACC_CONF_0, ACC_CONF_1, and ACC_CONF_2 is an invalid combination. + * */ + uint8_t acc_conf_err; + +}; + +/*! + * @brief Structure holding Global status flags + */ +struct bma5_sensor_status +{ + /*! Set when new ACC data is available. This flag can be cleared by writing '1' to it. */ + uint8_t acc_data_rdy; + + /*! Set when new temperature data is available. This flag can be cleared by writing '1' to it. */ + uint8_t temperature_rdy; + + /*! Sensor is ready for operation. */ + uint8_t sensor_rdy; + +}; + +/*! + * @brief Structure holding Accelerometer configuration register + */ +struct bma5_acc_conf +{ + /*! The ODR (Output Data Rate) in Hz. Not all settings are available in all power modes */ + uint8_t acc_odr; + + /*! Accelerometer bandwith parameter. This parameter determines the filter configuration. The different settings + * have a different impact depending on the setting of the power_mode bit. The name of the settings are therefore + * (HPM-setting)_(LPM-setting). (e.g. norm_avg4 means norm mode for HPM and avg4 for LPM) */ + uint8_t acc_bwp; + + /*! With this config bit, it is possible to set the basic measurement power mode. There are two possible + * settings:LPM (Low Power Mode) with duty cycling or HPM (High Performance Mode) with continous measurement. This + * setting has an influence on the signal path and the filter settings, too. */ + uint8_t power_mode; + + /*! The measurement range of the accelerometer. This setting has influence on the scaling of the ACC_DATA registers. + * */ + uint8_t acc_range; + + /*! Select roll-off of IIR filter in continuous mode. */ + uint8_t acc_iir_ro; + + /*! Select the performance mode of the sensor. The choice is between high performance with lower noise or reduce the + * power consumption but with an increased noise level. The default is the high performance (lower noise). Changing + * this setting from default migh also influence the sensor behaviour like offset. This configuration should only be + * used in HPM. */ + uint8_t noise_mode; + + /*! Configuration bit to enable/disable the auto clear mechanism of the data ready interrupt. If enabled, a clock + * like with freq=odr can be enabled on the external interrupt pin. */ + uint8_t acc_drdy_int_auto_clear; +}; + +/*! + * @brief Structure holding Temperature Sensor configuration register + */ +struct bma5_temp_conf +{ + /*! Select rate in Hz at which the temperature is sampled. */ + uint8_t temp_rate; + + /*! Select the input source for the temperature ADC. */ + uint8_t temp_meas_src; + + /*! Select the external pin as source for temperature ADC. */ + uint8_t temp_ext_sel; + + /*! Enable temperature dependent sensitivity correction. */ + uint8_t temp_tcs; + + /*! Enable temperature dependent offset correction. */ + uint8_t temp_tco; + +}; + +/*! + * @brief Structure holding Configuration register for INT + */ +struct bma5_int_conf +{ + /*! Output enable for INT1 pin */ + uint8_t int_mode; + + /*! Configure behaviour of INT1 pin to open drain. */ + uint8_t int_od; + + /*! Configure level of INT1 pin */ + uint8_t int_lvl; +}; + +/*! + * @brief Structure to define interrupt source and its configuration + */ +struct bma5_int_conf_types +{ + /*! Interrupt source */ + uint8_t int_src; + + /*! Interrupt configuration */ + struct bma5_int_conf int_conf; +}; + +/*! + * @brief Structure holding Serial interface settings + */ +struct bma5_if_conf +{ + /*! Configuration of I3C mode */ + uint8_t if_i3c_cfg; + + /*! Configuration of SPI3 mode(SPI 3 wire protocol). */ + uint8_t if_spi3_cfg; + + /*! Configuration of CSB pullup in SPI mode */ + uint8_t if_csb_pullup; + + /*! Pad drive strength in I2C mode. */ + uint8_t if_pad_drv; + + /*! select drive strength in I2C mode */ + uint8_t if_i2c_drv_sel; + +}; + +/*! + * @brief Structure holding FIFO control register + */ +struct bma5_fifo_ctrl +{ + /*! FIFO reset trigger. Writing '1' to this field synchronously resets the FIFO. */ + uint8_t fifo_rst; + + /*! FIFO frame synchronization trigger. Writing '1' to this field tells the FIFO that another frame is about to be + * written to FIFO_DATA_IN. */ + uint8_t fifo_frame_sync; + +}; + +/*! + * @brief Structure holding FIFO configuration register 0 + */ +struct bma5_fifo_conf +{ + /*! Enable bit for the FIFO. Cannot be set to 1 if fifo_size equals 0. */ + uint8_t fifo_cfg; + + /*! Configuration bit to enable the storage of the x-axis acceleration data in the FIFO. */ + uint8_t fifo_acc_x; + + /*! Configuration bit to enable the storage of the y-axis acceleration data in the FIFO. */ + uint8_t fifo_acc_y; + + /*! Configuration bit to enable the storage of the z-axis acceleration data in the FIFO. */ + uint8_t fifo_acc_z; + + /*! Enable bit for FIFO data compression. */ + uint8_t fifo_compression; + + /*! FIFO size. Since FIFO and feature engine share a common RAM, the size for the FIFO share has to be adjusted. + * Cannot be changed if locked by the feature engine. In Order to change this value, first disable the feature + * engine. If the feature engine is turned on again, a minimum share migh be needed and this setting might be + * changed by the feature engine. */ + uint8_t fifo_size; + + /*! FIFO sensor time configuration. */ + uint8_t fifo_sensor_time; + + /*! If set, the FIFO stops storing new data if it is full. Otherwise the oldest frame is dropped in order to make + * room for a new frame. */ + uint8_t fifo_stop_on_full; +}; + +/*! @brief Structure to define accelerometer sensor axes data in 16 bit + */ +struct bma5_sens_fifo_axes_data_16_bit +{ + /*! Data in x-axis */ + int16_t x; + + /*! Data in y-axis */ + int16_t y; + + /*! Data in z-axis */ + int16_t z; + + /*! Sensortime */ + uint32_t sensor_time; +}; + +/*! @brief Structure to define accelerometer sensor axes data in 8 bit + */ +struct bma5_sens_fifo_axes_data_8_bit +{ + /*! Data in x-axis */ + int8_t x; + + /*! Data in y-axis */ + int8_t y; + + /*! Data in z-axis */ + int8_t z; + + /*! Sensortime */ + uint32_t sensor_time; +}; + +/*! + * @brief This structure holds the information for usage of + * FIFO by the user. + */ +struct bma5_fifo_frame +{ + /*! Data buffer of user defined length is to be mapped here */ + uint8_t *data; + + /*! Stores available FIFO length */ + uint16_t fifo_avail_len; + + /*! Stores available FIFO frames */ + uint16_t fifo_avail_frames; + + /*! To index accelerometer bytes */ + uint16_t acc_byte_start_idx; +}; + +/*! + * @brief Structure holding feature engine ('feat_eng') status register + */ +struct bma5_feat_eng_status +{ + /*! When this field equals 1, the feature engine is currently halted. This means that the "halt" instruction has + * been executed and that the processor waits for a wakeup trigger. */ + uint8_t feat_eng_halted; + + /*! When this field equals 1, the feature engine is currently executing code. */ + uint8_t feat_eng_running; + + /*! + This field reads 1’b1 as long as an update of the host-owned GPRs is pending. + */ + uint8_t host_gpr_update_pending; + + /*! + This field reads 1’b1 as long as an update of the feature engine-owned GPRs is pending. + */ + uint8_t feat_eng_gpr_update_pending; + +}; + +/*! + * @brief Structure holding feature engine ('feat_eng') general purpose register configuration register + */ +struct bma5_feat_eng_gpr_conf +{ + /*! host Direction for GP register 0 ('0': feature engine has write access, '1': host has write access). This field + * is only writeable by the feature engine. */ + uint8_t feat_eng_gpr_0_dir; + + /*! host Direction for GP register 1 ('0': feature engine has write access, '1': host has write access). This field + * is only writeable by the feature engine. */ + uint8_t feat_eng_gpr_1_dir; + + /*! host Direction for GP register 2 ('0': feature engine has write access, '1': host has write access). This field + * is only writeable by the feature engine. */ + uint8_t feat_eng_gpr_2_dir; + + /*! host direction for GP register 3 ('0': feature engine has write access, '1': host has write access). This field + * is only writeable by the feature engine. */ + uint8_t feat_eng_gpr_3_dir; + + /*! host direction for GP register 4 ('0': feature engine has write access, '1': host has write access). This field + * is only writeable by the feature engine. */ + uint8_t feat_eng_gpr_4_dir; + + /*! host direction for GP register 5 ('0': feature engine has write access, '1': host has write access). This field + * is only writeable by the feature engine. */ + uint8_t feat_eng_gpr_5_dir; + + /*! host direction for GP register 6 ('0': feature engine has write access, '1': host has write access). This field + * is only writeable by the feature engine. */ + uint8_t feat_eng_gpr_6_dir; + +}; + +/*! + * @brief Structure holding feature engine ('feat_eng') general purpose register control register + */ +struct bma5_feat_eng_gpr_ctrl +{ + /*! If the host writes 1’b1 to this field, it requests that the host-owned first stage registers + * are copied to the host-owned second stage registers. + * If the feature engine writes 1’b1 to this field, it requests that the feature engine-owned + * first stage registers are copied to the feature engine-owned second stage registers. */ + uint8_t update_gprs; + + /*! If the host writes 1’b1 to this field, it releases the lock of the feature engine-owned GPRs + * and thus allows for an update of the feature engine-owned second stage registers. + * If the feature engine writes 1’b1 to this field, it releases the lock of the host-owned GPRs + * and thus allows for an update of the host-owned second stage registers. */ + uint8_t unlock_gprs; +}; + +/*! + * @brief Structure holding Select NORMAL/SELF_TEST mode and test data. If you write to this register, the ACC data path is reset. + */ +struct bma5_acc_self_test +{ + /*! Enable flag for the self test mode. */ + uint8_t self_test; + + /*! Select sign of self test excitation */ + uint8_t self_test_sign; + +}; + +/*! + * @brief Structures holding accelerometer values + */ +struct bma5_accel +{ + /*! Accel X value. */ + int16_t x; + + /*! Accel Y value. */ + int16_t y; + + /*! Accel Z value. */ + int16_t z; +}; + +/*! + * @brief Structures holding accelerometer doff values + */ +struct bma5_accel_doff +{ + /*! Accel X value. */ + int16_t x_doff; + + /*! Accel Y value. */ + int16_t y_doff; + + /*! Accel Z value. */ + int16_t z_doff; +}; + +#endif /* _BMA5_DEFS_H */ diff --git a/examples/accel_foc/Makefile b/examples/accel_foc/Makefile new file mode 100644 index 0000000..5e0eb04 --- /dev/null +++ b/examples/accel_foc/Makefile @@ -0,0 +1,18 @@ +COINES_INSTALL_PATH ?= ../../../.. + +EXAMPLE_FILE ?= accel_foc.c + +API_LOCATION ?= ../.. +COMMON_LOCATION ?= .. + +C_SRCS += \ +$(API_LOCATION)/bma5.c \ +$(API_LOCATION)/bma530.c \ +$(API_LOCATION)/bma530_features.c \ +$(COMMON_LOCATION)/common/common.c + +INCLUDEPATHS += \ +$(API_LOCATION) \ +$(COMMON_LOCATION)/common + +include $(COINES_INSTALL_PATH)/coines.mk diff --git a/examples/accel_foc/accel_foc.c b/examples/accel_foc/accel_foc.c new file mode 100644 index 0000000..75d2b2a --- /dev/null +++ b/examples/accel_foc/accel_foc.c @@ -0,0 +1,352 @@ +/** + * Copyright (c) 2024 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. + * + */ + +#include +#include +#include "common.h" +#include "bma530_features.h" + +/******************************************************************************/ +/*! Macro definition */ + +/*! Earth's gravity in m/s^2 */ +#define GRAVITY_EARTH (9.80665f) + +/******************************************************************************/ +/*! Static Function Declaration */ + +/*! + * @brief This internal API converts raw sensor values(LSB) to mg. + * + * @param[in] val : Raw sensor value. + * @param[in] g_range : Accel Range selected (2G, 4G, 8G, 16G). + * @param[in] bit_width : Resolution of the sensor. + * + * @return Accel values in mg + * + */ +static float lsb_to_ms2(int16_t val, float g_range, uint8_t bit_width); + +/******************************************************************************/ +int main(void) +{ + int8_t rslt; + uint8_t n_ints = 2; + uint8_t n_status = 2; + uint8_t loop; + uint8_t gpr_ctrl_host = BMA5_ENABLE; + uint8_t sensor_ctrl; + + float x, y, z; + + struct bma5_dev dev; + struct bma530_int_map int_map = { 0 }; + struct bma530_int_status_types int_status[2]; + struct bma5_int_conf_types int_config[2]; + struct bma530_accel_foc_config conf; + struct bma530_feat_eng_gpr_0 gpr_0; + struct bma530_feat_eng_gp_flags gp_flags; + struct bma5_accel_doff user_off; + struct bma5_sensor_status status; + struct bma5_accel sens_data = { 0 }; + + /* Assign context parameter selection */ + enum bma5_context context; + + context = BMA5_SMARTPHONE; + + int_config[0].int_src = BMA5_INT_1; + int_config[1].int_src = BMA5_INT_2; + + int_status[0].int_src = BMA530_INT_STATUS_INT1; + int_status[1].int_src = BMA530_INT_STATUS_INT2; + + /* Interface reference is given as a parameter + * For I2C : BMA5_I2C_INTF + * For SPI : BMA5_SPI_INTF + */ + rslt = bma5_interface_init(&dev, BMA5_SPI_INTF, context); + bma5_check_rslt("bma5_interface_init", rslt); + + rslt = bma530_init(&dev); + bma5_check_rslt("bma530_init", rslt); + printf("BMA530 Chip ID is 0x%X\n", dev.chip_id); + + /* Get accel configurations */ + rslt = bma5_get_acc_conf_0(&sensor_ctrl, &dev); + bma5_check_rslt("bma5_get_acc_conf_0", rslt); + + sensor_ctrl = BMA5_SENSOR_CTRL_DISABLE; + + /* disable accel */ + rslt = bma5_set_acc_conf_0(sensor_ctrl, &dev); + bma5_check_rslt("bma5_get_acc_conf_0", rslt); + + rslt = bma530_get_int_map(&int_map, &dev); + bma5_check_rslt("bma530_get_int_map", rslt); + + /* Map accel drdy interrupt */ + int_map.acc_drdy_int_map = BMA530_ACC_DRDY_INT_MAP_INT1; + + /* Map accel foc interrupt */ + int_map.acc_foc_int_map = BMA530_ACC_FOC_INT_MAP_INT2; + + rslt = bma530_set_int_map(&int_map, &dev); + bma5_check_rslt("bma530_set_int_map_0", rslt); + + /* Get accel configurations */ + rslt = bma5_get_acc_conf_0(&sensor_ctrl, &dev); + bma5_check_rslt("bma5_get_acc_conf_0", rslt); + + sensor_ctrl = BMA5_SENSOR_CTRL_ENABLE; + + /* enable accel */ + rslt = bma5_set_acc_conf_0(sensor_ctrl, &dev); + bma5_check_rslt("bma5_set_acc_conf_0", rslt); + + /* Map hardware interrupt pin configurations */ + rslt = bma5_get_int_conf(int_config, n_ints, &dev); + bma5_check_rslt("bma5_get_int_conf", rslt); + + int_config[0].int_conf.int_mode = BMA5_INT1_MODE_PULSED_LONG; + int_config[0].int_conf.int_od = BMA5_INT1_OD_PUSH_PULL; + int_config[0].int_conf.int_lvl = BMA5_INT1_LVL_ACTIVE_HIGH; + + int_config[1].int_conf.int_mode = BMA5_INT2_MODE_PULSED_LONG; + int_config[1].int_conf.int_od = BMA5_INT2_OD_PUSH_PULL; + int_config[1].int_conf.int_lvl = BMA5_INT2_LVL_ACTIVE_LOW; + + rslt = bma5_set_int_conf(int_config, n_ints, &dev); + bma5_check_rslt("bma5_set_int_conf", rslt); + + printf("Reading Accel values before FOC compensation\n"); + printf("\n# Count, Accel_LSB_X, Accel_LSB_Y, Accel_LSB_Z, Acc_ms2_X, Acc_ms2_Y, Acc_ms2_Z\n"); + + loop = 0; + while (loop < 10) + { + for (;;) + { + /* Get accel data ready status */ + rslt = bma5_get_sensor_status(&status, &dev); + bma5_check_rslt("bma5_get_sensor_status", rslt); + + if (status.acc_data_rdy) + { + /* Get accel data ready interrupt status */ + rslt = bma530_get_int_status(int_status, n_status, &dev); + bma5_check_rslt("bma530_get_int_status", rslt); + + if (int_status[0].int_status.acc_drdy_int_status & BMA530_ACC_DRDY_INT_STATUS_MSK) + { + rslt = bma5_set_sensor_status(&status, &dev); + bma5_check_rslt("bma5_set_sensor_status", rslt); + + rslt = bma530_set_int_status(int_status, n_status, &dev); + bma5_check_rslt("bma530_set_int_status_int1_0", rslt); + + /* Get accel data */ + rslt = bma5_get_acc(&sens_data, &dev); + bma5_check_rslt("bma5_get_acc", rslt); + + /* Converting lsb to mg for 16 bit resolution at 8G range */ + x = lsb_to_ms2(sens_data.x, (float)8, BMA5_16_BIT_RESOLUTION); + y = lsb_to_ms2(sens_data.y, (float)8, BMA5_16_BIT_RESOLUTION); + z = lsb_to_ms2(sens_data.z, (float)8, BMA5_16_BIT_RESOLUTION); + + /* Print the data in mg */ + printf("%d, %d, %d, %d, %4.2f, %4.2f, %4.2f\n", + loop + 1, + sens_data.x, + sens_data.y, + sens_data.z, + x, + y, + z); + break; + } + } + } + + loop++; + } + + printf("Reading the offset values before FOC compensation\n"); + + rslt = bma5_get_acc_doff(&user_off, &dev); + bma5_check_rslt("bma5_get_acc_doff", rslt); + + printf("USER_OFFSET_X %d\t USER_OFFSET_Y %d\t USER_OFFSET_Z %d\n", user_off.x_doff, user_off.y_doff, + user_off.z_doff); + + rslt = bma530_get_accel_foc_config(&conf, &dev); + bma5_check_rslt("bma530_get_accel_foc_config", rslt); + + printf("foc_off_x:0x%x\n", conf.foc_off_x); + printf("foc_off_y:0x%x\n", conf.foc_off_y); + printf("foc_off_z:0x%x\n", conf.foc_off_z); + + conf.foc_apply_corr = BMA5_ENABLE; + conf.foc_filter_coeff = 4; + conf.foc_axis_1g = BMA5_ACC_FOC_AXIS_Z_MINUS_1G; + + rslt = bma530_set_accel_foc_config(&conf, &dev); + bma5_check_rslt("bma530_set_accel_foc_config", rslt); + + rslt = bma530_get_accel_foc_config(&conf, &dev); + bma5_check_rslt("bma530_get_accel_foc_config", rslt); + + printf("foc_apply_corr:0x%x\n", conf.foc_apply_corr); + printf("foc_filter_coeff:0x%x\n", conf.foc_filter_coeff); + printf("foc_axis_1g:0x%x\n", conf.foc_axis_1g); + + rslt = bma530_get_feat_eng_gpr_0(&gpr_0, &dev); + bma5_check_rslt("bma530_get_feat_eng_gpr_0", rslt); + + gpr_0.acc_foc_en = BMA5_ENABLE; + + rslt = bma530_set_feat_eng_gpr_0(&gpr_0, &dev); + bma5_check_rslt("bma530_set_feat_eng_gpr_0", rslt); + + rslt = bma5_set_regs(BMA5_REG_FEAT_ENG_GPR_CTRL, &gpr_ctrl_host, 1, &dev); + bma5_check_rslt("bma5_set_regs", rslt); + + rslt = bma530_get_feat_eng_gpr_0(&gpr_0, &dev); + bma5_check_rslt("bma530_get_feat_eng_gpr_0", rslt); + + printf("foc en : %d\n", gpr_0.acc_foc_en); + + rslt = bma530_get_feat_eng_gp_flags(&gp_flags, &dev); + bma5_check_rslt("bma530_get_feat_eng_gp_flags", rslt); + + printf("gp_flags.feat_init_stat : %d\n", gp_flags.feat_init_stat); + printf("gp_flags.foc_running : %d\n", gp_flags.foc_running); + + printf("\nDo not move the board to perform ACCEL FOC\n"); + for (;;) + { + rslt = bma530_get_int_status(int_status, n_status, &dev); + bma5_check_rslt("bma530_get_int_status", rslt); + + if (int_status[0].int_status.acc_drdy_int_status & int_status[1].int_status.acc_foc_int_status & BMA5_ENABLE) + { + rslt = bma530_set_int_status(int_status, n_status, &dev); + bma5_check_rslt("bma530_set_int_status", rslt); + + printf("\nAccel FOC interrupt occurred\n"); + + break; + } + } + + printf("\n# Count, Accel_LSB_X, Accel_LSB_Y, Accel_LSB_Z, Acc_ms2_X, Acc_ms2_Y, Acc_ms2_Z\n"); + printf("Reading Accel values after FOC compensation\n"); + + loop = 0; + while (loop < 10) + { + for (;;) + { + /* Get accel data ready status */ + rslt = bma5_get_sensor_status(&status, &dev); + bma5_check_rslt("bma5_get_sensor_status", rslt); + + if (status.acc_data_rdy) + { + /* Get accel data ready interrupt status */ + rslt = bma530_get_int_status(int_status, n_status, &dev); + bma5_check_rslt("bma530_get_int_status", rslt); + + if (int_status[0].int_status.acc_drdy_int_status & BMA530_ACC_DRDY_INT_STATUS_MSK) + { + rslt = bma5_set_sensor_status(&status, &dev); + bma5_check_rslt("bma5_set_sensor_status", rslt); + + rslt = bma530_set_int_status(int_status, n_status, &dev); + bma5_check_rslt("bma530_set_int_status_int1_0", rslt); + + /* Get accel data */ + rslt = bma5_get_acc(&sens_data, &dev); + bma5_check_rslt("bma5_get_acc", rslt); + + /* Converting lsb to mg for 16 bit resolution at 8G range */ + x = lsb_to_ms2(sens_data.x, (float)8, BMA5_16_BIT_RESOLUTION); + y = lsb_to_ms2(sens_data.y, (float)8, BMA5_16_BIT_RESOLUTION); + z = lsb_to_ms2(sens_data.z, (float)8, BMA5_16_BIT_RESOLUTION); + + /* Print the data in mg */ + printf("%d, %d, %d, %d, %4.2f, %4.2f, %4.2f\n", + loop + 1, + sens_data.x, + sens_data.y, + sens_data.z, + x, + y, + z); + break; + } + } + } + + loop++; + } + + printf("Reading the offset values after FOC compensation\n"); + + rslt = bma5_get_acc_doff(&user_off, &dev); + bma5_check_rslt("bma5_get_acc_doff", rslt); + + printf("USER_OFFSET_X %d\t USER_OFFSET_Y %d\t USER_OFFSET_Z %d\n", user_off.x_doff, user_off.y_doff, + user_off.z_doff); + + bma5_coines_deinit(); + + return rslt; +} + +/*******************************************************************/ +/* Static Function Definitions */ +/*******************************************************************/ + +/*! + * @brief This internal API converts raw sensor values(LSB) to mg. + */ +static float lsb_to_ms2(int16_t val, float g_range, uint8_t bit_width) +{ + double power = 2; + + float half_scale = (float)((pow((double)power, (double)bit_width) / 2.0f)); + + return (GRAVITY_EARTH * val * g_range) / half_scale; +} diff --git a/examples/accelerometer/Makefile b/examples/accelerometer/Makefile new file mode 100644 index 0000000..612875f --- /dev/null +++ b/examples/accelerometer/Makefile @@ -0,0 +1,18 @@ +COINES_INSTALL_PATH ?= ../../../.. + +EXAMPLE_FILE ?= accelerometer.c + +API_LOCATION ?= ../.. +COMMON_LOCATION ?= .. + +C_SRCS += \ +$(API_LOCATION)/bma5.c \ +$(API_LOCATION)/bma530.c \ +$(API_LOCATION)/bma530_features.c \ +$(COMMON_LOCATION)/common/common.c + +INCLUDEPATHS += \ +$(API_LOCATION) \ +$(COMMON_LOCATION)/common + +include $(COINES_INSTALL_PATH)/coines.mk diff --git a/examples/accelerometer/accelerometer.c b/examples/accelerometer/accelerometer.c new file mode 100644 index 0000000..df696c5 --- /dev/null +++ b/examples/accelerometer/accelerometer.c @@ -0,0 +1,207 @@ +/** + * Copyright (c) 2024 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. + * + */ + +#include +#include +#include "common.h" +#include "bma530_features.h" + +/******************************************************************************/ +/*! Macro definition */ + +/*! Earth's gravity in m/s^2 */ +#define GRAVITY_EARTH (9.80665f) + +/******************************************************************************/ +/*! Static Function Declaration */ + +/*! + * @brief This internal API converts raw sensor values(LSB) to meters per seconds square. + * + * @param[in] val : Raw sensor value. + * @param[in] g_range : Accel Range selected (2G, 4G, 8G, 16G). + * @param[in] bit_width : Resolution of the sensor. + * + * @return Accel values in meters per second square. + * + */ +static float lsb_to_ms2(int16_t val, float g_range, uint8_t bit_width); + +/******************************************************************************/ +int main(void) +{ + int8_t rslt; + uint8_t sensor_ctrl; + uint8_t n_conf = 1; + uint8_t n_status = 1; + uint8_t loop = 0; + float x = 0, y = 0, z = 0; + + struct bma5_acc_conf acc_cfg; + struct bma530_int_map int_map; + struct bma5_accel sens_data; + struct bma5_sensor_status status; + struct bma5_int_conf_types int_config; + struct bma530_int_status_types int_status; + struct bma5_dev dev; + + /* Assign context parameter selection */ + enum bma5_context context; + + context = BMA5_SMARTPHONE; + + int_config.int_src = BMA5_INT_1; + int_status.int_src = BMA530_INT_STATUS_INT1; + + /* Interface reference is given as a parameter + * For I2C : BMA5_I2C_INTF + * For SPI : BMA5_SPI_INTF + */ + rslt = bma5_interface_init(&dev, BMA5_I2C_INTF, context); + bma5_check_rslt("bma5_interface_init", rslt); + + rslt = bma530_init(&dev); + bma5_check_rslt("bma530_init", rslt); + printf("BMA530 Chip ID is 0x%X\n", dev.chip_id); + + rslt = bma530_get_int_map(&int_map, &dev); + bma5_check_rslt("bma530_get_int_map", rslt); + + /* Map accel data ready interrupt */ + int_map.acc_drdy_int_map = BMA530_ACC_DRDY_INT_MAP_INT1; + rslt = bma530_set_int_map(&int_map, &dev); + bma5_check_rslt("bma530_set_int_map", rslt); + + /* Get accel configurations */ + rslt = bma5_get_acc_conf_0(&sensor_ctrl, &dev); + bma5_check_rslt("bma5_get_acc_conf_0", rslt); + + rslt = bma5_get_acc_conf(&acc_cfg, &dev); + bma5_check_rslt("bma5_get_acc_conf", rslt); + + /* Set accel configurations */ + acc_cfg.acc_odr = BMA5_ACC_ODR_HZ_25; + acc_cfg.acc_bwp = BMA5_ACC_BWP_NORM_AVG4; + acc_cfg.power_mode = BMA5_POWER_MODE_HPM; + + acc_cfg.acc_range = BMA5_ACC_RANGE_MAX_2G; + acc_cfg.acc_iir_ro = BMA5_ACC_IIR_RO_DB_40; + acc_cfg.noise_mode = BMA5_NOISE_MODE_LOWER_POWER; + acc_cfg.acc_drdy_int_auto_clear = BMA5_ACC_DRDY_INT_AUTO_CLEAR_ENABLED; + + rslt = bma5_set_acc_conf(&acc_cfg, &dev); + bma5_check_rslt("bma5_set_acc_conf", rslt); + + /* Enable accel */ + sensor_ctrl = BMA5_SENSOR_CTRL_ENABLE; + + rslt = bma5_set_acc_conf_0(sensor_ctrl, &dev); + bma5_check_rslt("bma5_set_acc_conf_0", rslt); + + /* Map hardware interrupt pin configurations */ + rslt = bma5_get_int_conf(&int_config, n_conf, &dev); + bma5_check_rslt("bma5_get_int_conf", rslt); + + int_config.int_conf.int_mode = BMA5_INT1_MODE_LATCHED; + int_config.int_conf.int_od = BMA5_INT1_OD_PUSH_PULL; + int_config.int_conf.int_lvl = BMA5_INT1_LVL_ACTIVE_HIGH; + + rslt = bma5_set_int_conf(&int_config, n_conf, &dev); + bma5_check_rslt("bma5_set_int_conf", rslt); + + printf("Accelerometer data in 2G range\n"); + + printf("\nCount, Accel_LSB_X, Accel_LSB_Y, Accel_LSB_Z, Acc_ms2_X, Acc_ms2_Y, Acc_ms2_Z\n"); + + while (loop < 50) + { + /* Get accel data ready status */ + rslt = bma5_get_sensor_status(&status, &dev); + bma5_check_rslt("bma5_get_sensor_status", rslt); + + if (status.acc_data_rdy) + { + /* Get accel data ready interrupt status */ + rslt = bma530_get_int_status(&int_status, n_status, &dev); + bma5_check_rslt("bma530_get_int_status", rslt); + + if (int_status.int_status.acc_drdy_int_status & BMA530_ACC_DRDY_INT_STATUS_MSK) + { + rslt = bma5_set_sensor_status(&status, &dev); + bma5_check_rslt("bma5_set_sensor_status", rslt); + + rslt = bma530_set_int_status(&int_status, n_status, &dev); + bma5_check_rslt("bma530_set_int_status_int1_0", rslt); + + /* Get accel data and sensortime */ + /* Get accel data */ + rslt = bma5_get_acc(&sens_data, &dev); + bma5_check_rslt("bma5_get_acc", rslt); + + /* Converting lsb to meter per second squared for 16 bit resolution at 2G range */ + x = lsb_to_ms2(sens_data.x, (float)2, BMA5_16_BIT_RESOLUTION); + y = lsb_to_ms2(sens_data.y, (float)2, BMA5_16_BIT_RESOLUTION); + z = lsb_to_ms2(sens_data.z, (float)2, BMA5_16_BIT_RESOLUTION); + + /* Print the data in m/s2 */ + printf("%d, %d, %d, %d, %4.2f, %4.2f, %4.2f\n", + loop, + sens_data.x, + sens_data.y, + sens_data.z, + x, + y, + z); + + loop++; + } + } + } + + bma5_coines_deinit(); + + return rslt; +} + +/*! + * @brief This internal API converts raw sensor values(LSB) to meters per seconds square. + */ +static float lsb_to_ms2(int16_t val, float g_range, uint8_t bit_width) +{ + double power = 2; + + float half_scale = (float)((pow((double)power, (double)bit_width) / 2.0f)); + + return (GRAVITY_EARTH * val * g_range) / half_scale; +} diff --git a/examples/android_generic_interrupt_1/Makefile b/examples/android_generic_interrupt_1/Makefile new file mode 100644 index 0000000..4a0d344 --- /dev/null +++ b/examples/android_generic_interrupt_1/Makefile @@ -0,0 +1,18 @@ +COINES_INSTALL_PATH ?= ../../../.. + +EXAMPLE_FILE ?= android_generic_interrupt_1.c + +API_LOCATION ?= ../.. +COMMON_LOCATION ?= .. + +C_SRCS += \ +$(API_LOCATION)/bma5.c \ +$(API_LOCATION)/bma530.c \ +$(API_LOCATION)/bma530_features.c \ +$(COMMON_LOCATION)/common/common.c + +INCLUDEPATHS += \ +$(API_LOCATION) \ +$(COMMON_LOCATION)/common + +include $(COINES_INSTALL_PATH)/coines.mk diff --git a/examples/android_generic_interrupt_1/android_generic_interrupt_1.c b/examples/android_generic_interrupt_1/android_generic_interrupt_1.c new file mode 100644 index 0000000..d544887 --- /dev/null +++ b/examples/android_generic_interrupt_1/android_generic_interrupt_1.c @@ -0,0 +1,173 @@ +/** + * Copyright (c) 2024 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. + * + */ + +#include +#include "common.h" +#include "bma530_features.h" + +/******************************************************************************/ +int main(void) +{ + int8_t rslt; + uint8_t n_ints = 1; + uint8_t n_status = 1; + uint8_t android_comp, get_android_comp; + uint8_t gpr_ctrl_host = BMA5_ENABLE; + struct bma530_int_map int_map; + struct bma5_int_conf_types int_config; + struct bma530_int_status_types int_status; + struct bma530_generic_interrupt_types conf; + struct bma530_feat_eng_gpr_0 gpr_0; + struct bma5_dev dev; + + int_config.int_src = BMA5_INT_1; + + int_status.int_src = BMA530_INT_STATUS_INT1; + + conf.generic_interrupt = BMA530_GEN_INT_1; + + /* Assign context parameter selection */ + enum bma5_context context; + context = BMA5_SMARTPHONE; + + /* Interface reference is given as a parameter + * For I2C : BMA5_I2C_INTF + * For SPI : BMA5_SPI_INTF + */ + rslt = bma5_interface_init(&dev, BMA5_SPI_INTF, context); + bma5_check_rslt("bma5_interface_init", rslt); + + rslt = bma530_init(&dev); + bma5_check_rslt("bma530_init", rslt); + printf("BMA530 Chip ID is 0x%X\n", dev.chip_id); + + printf("Default configurations\n"); + rslt = bma530_get_default_generic_int_config(&conf, n_ints, &dev); + bma5_check_rslt("bma530_get_default_generic_int_config", rslt); + + printf("slope_thres 0x%x\n", conf.gen_int.slope_thres); + printf("comb_sel 0x%x\n", conf.gen_int.comb_sel); + printf("axis_sel 0x%x\n", conf.gen_int.axis_sel); + printf("hysteresis 0x%x\n", conf.gen_int.hysteresis); + printf("criterion_sel 0x%x\n", conf.gen_int.criterion_sel); + printf("acc_ref_up 0x%x\n", conf.gen_int.acc_ref_up); + printf("duration 0x%x\n", conf.gen_int.duration); + printf("wait_time 0x%x\n", conf.gen_int.wait_time); + printf("quiet_time 0x%x\n", conf.gen_int.quiet_time); + printf("ref_acc_x 0x%x\n", conf.gen_int.ref_acc_x); + printf("ref_acc_y 0x%x\n", conf.gen_int.ref_acc_y); + printf("ref_acc_z 0x%x\n", conf.gen_int.ref_acc_z); + + conf.gen_int.slope_thres = 0xA; + conf.gen_int.comb_sel = 0x0; + conf.gen_int.axis_sel = 0x7; + conf.gen_int.hysteresis = 0x2; + conf.gen_int.criterion_sel = 0x1; + conf.gen_int.acc_ref_up = 0x1; + conf.gen_int.duration = 0xA; + conf.gen_int.wait_time = 0x3; + conf.gen_int.quiet_time = 0x40; + conf.gen_int.ref_acc_x = 0x0; + conf.gen_int.ref_acc_y = 0x0; + conf.gen_int.ref_acc_z = 0x800; + + rslt = bma530_set_generic_int_config(&conf, n_ints, &dev); + bma5_check_rslt("bma530_set_generic_int_config", rslt); + + rslt = bma530_get_android_comp_mode(&android_comp, &dev); + bma5_check_rslt("bma530_get_android_comp_mode", rslt); + + android_comp = 1; + + rslt = bma530_set_android_comp_mode(&android_comp, &dev); + bma5_check_rslt("bma530_set_android_comp_mode", rslt); + + printf("Get Android compatibility mode\n\n"); + rslt = bma530_get_android_comp_mode(&get_android_comp, &dev); + bma5_check_rslt("bma530_get_android_comp_mode", rslt); + + printf("Android compatibility mode : %d\n", get_android_comp); + + rslt = bma530_get_feat_eng_gpr_0(&gpr_0, &dev); + bma5_check_rslt("bma530_get_feat_eng_gpr_0", rslt); + + gpr_0.gen_int1_en = BMA5_ENABLE; + + rslt = bma530_set_feat_eng_gpr_0(&gpr_0, &dev); + bma5_check_rslt("bma530_set_feat_eng_gpr_0", rslt); + + rslt = bma5_set_regs(BMA5_REG_FEAT_ENG_GPR_CTRL, &gpr_ctrl_host, 1, &dev); + bma5_check_rslt("bma5_set_regs", rslt); + + rslt = bma530_get_int_map(&int_map, &dev); + bma5_check_rslt("bma530_get_int_map", rslt); + + /* Map generic interrupt 1 */ + int_map.gen_int1_int_map = BMA530_GEN_INT1_INT_MAP_INT1; + rslt = bma530_set_int_map(&int_map, &dev); + bma5_check_rslt("bma530_set_int_map", rslt); + + /* Map hardware interrupt pin configurations */ + rslt = bma5_get_int_conf(&int_config, n_ints, &dev); + bma5_check_rslt("bma5_get_int_conf", rslt); + + int_config.int_conf.int_mode = BMA5_INT1_MODE_PULSED_SHORT; + int_config.int_conf.int_od = BMA5_INT1_OD_PUSH_PULL; + int_config.int_conf.int_lvl = BMA5_INT1_LVL_ACTIVE_LOW; + + rslt = bma5_set_int_conf(&int_config, n_ints, &dev); + bma5_check_rslt("bma5_set_int_conf", rslt); + + printf("Shake the board to get generic interrupt 1 interrupt\n"); + + for (;;) + { + rslt = bma530_get_int_status(&int_status, n_status, &dev); + bma5_check_rslt("bma530_get_int_status", rslt); + + if (int_status.int_status.gen_int1_int_status & BMA5_ENABLE) + { + rslt = bma530_set_int_status(&int_status, n_status, &dev); + bma5_check_rslt("bma530_set_int_status", rslt); + + printf("Generic interrupt 1 interrupt occurred\n"); + + break; + } + } + + bma5_coines_deinit(); + + return rslt; +} diff --git a/examples/android_generic_interrupt_2/Makefile b/examples/android_generic_interrupt_2/Makefile new file mode 100644 index 0000000..0899683 --- /dev/null +++ b/examples/android_generic_interrupt_2/Makefile @@ -0,0 +1,18 @@ +COINES_INSTALL_PATH ?= ../../../.. + +EXAMPLE_FILE ?= android_generic_interrupt_2.c + +API_LOCATION ?= ../.. +COMMON_LOCATION ?= .. + +C_SRCS += \ +$(API_LOCATION)/bma5.c \ +$(API_LOCATION)/bma530.c \ +$(API_LOCATION)/bma530_features.c \ +$(COMMON_LOCATION)/common/common.c + +INCLUDEPATHS += \ +$(API_LOCATION) \ +$(COMMON_LOCATION)/common + +include $(COINES_INSTALL_PATH)/coines.mk diff --git a/examples/android_generic_interrupt_2/android_generic_interrupt_2.c b/examples/android_generic_interrupt_2/android_generic_interrupt_2.c new file mode 100644 index 0000000..0ceb903 --- /dev/null +++ b/examples/android_generic_interrupt_2/android_generic_interrupt_2.c @@ -0,0 +1,173 @@ +/** + * Copyright (c) 2024 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. + * + */ + +#include +#include "common.h" +#include "bma530_features.h" + +/******************************************************************************/ +int main(void) +{ + int8_t rslt; + uint8_t n_ints = 1; + uint8_t n_status = 1; + uint8_t android_comp, get_android_comp; + uint8_t gpr_ctrl_host = BMA5_ENABLE; + struct bma530_int_map int_map; + struct bma5_int_conf_types int_config; + struct bma530_int_status_types int_status; + struct bma530_generic_interrupt_types conf; + struct bma530_feat_eng_gpr_0 gpr_0; + struct bma5_dev dev; + + int_config.int_src = BMA5_INT_2; + + int_status.int_src = BMA530_INT_STATUS_INT2; + + conf.generic_interrupt = BMA530_GEN_INT_2; + + /* Assign context parameter selection */ + enum bma5_context context; + context = BMA5_SMARTPHONE; + + /* Interface reference is given as a parameter + * For I2C : BMA5_I2C_INTF + * For SPI : BMA5_SPI_INTF + */ + rslt = bma5_interface_init(&dev, BMA5_SPI_INTF, context); + bma5_check_rslt("bma5_interface_init", rslt); + + rslt = bma530_init(&dev); + bma5_check_rslt("bma530_init", rslt); + printf("BMA530 Chip ID is 0x%X\n", dev.chip_id); + + printf("Default configurations\n"); + rslt = bma530_get_default_generic_int_config(&conf, n_ints, &dev); + bma5_check_rslt("bma530_get_default_generic_int_config", rslt); + + printf("slope_thres 0x%x\n", conf.gen_int.slope_thres); + printf("comb_sel 0x%x\n", conf.gen_int.comb_sel); + printf("axis_sel 0x%x\n", conf.gen_int.axis_sel); + printf("hysteresis 0x%x\n", conf.gen_int.hysteresis); + printf("criterion_sel 0x%x\n", conf.gen_int.criterion_sel); + printf("acc_ref_up 0x%x\n", conf.gen_int.acc_ref_up); + printf("duration 0x%x\n", conf.gen_int.duration); + printf("wait_time 0x%x\n", conf.gen_int.wait_time); + printf("quiet_time 0x%x\n", conf.gen_int.quiet_time); + printf("ref_acc_x 0x%x\n", conf.gen_int.ref_acc_x); + printf("ref_acc_y 0x%x\n", conf.gen_int.ref_acc_y); + printf("ref_acc_z 0x%x\n", conf.gen_int.ref_acc_z); + + conf.gen_int.slope_thres = 0xA; + conf.gen_int.comb_sel = 0x0; + conf.gen_int.axis_sel = 0x7; + conf.gen_int.hysteresis = 0x2; + conf.gen_int.criterion_sel = 0x1; + conf.gen_int.acc_ref_up = 0x1; + conf.gen_int.duration = 0xA; + conf.gen_int.wait_time = 0x3; + conf.gen_int.quiet_time = 0x40; + conf.gen_int.ref_acc_x = 0x0; + conf.gen_int.ref_acc_y = 0x0; + conf.gen_int.ref_acc_z = 0x800; + + rslt = bma530_set_generic_int_config(&conf, n_ints, &dev); + bma5_check_rslt("bma530_set_generic_int_config", rslt); + + rslt = bma530_get_android_comp_mode(&android_comp, &dev); + bma5_check_rslt("bma530_get_android_comp_mode", rslt); + + android_comp = 1; + + rslt = bma530_set_android_comp_mode(&android_comp, &dev); + bma5_check_rslt("bma530_set_android_comp_mode", rslt); + + printf("Get Android compatibility mode\n\n"); + rslt = bma530_get_android_comp_mode(&get_android_comp, &dev); + bma5_check_rslt("bma530_get_android_comp_mode", rslt); + + printf("Android compatibility mode : %d\n", get_android_comp); + + rslt = bma530_get_feat_eng_gpr_0(&gpr_0, &dev); + bma5_check_rslt("bma530_get_feat_eng_gpr_0", rslt); + + gpr_0.gen_int2_en = BMA5_ENABLE; + + rslt = bma530_set_feat_eng_gpr_0(&gpr_0, &dev); + bma5_check_rslt("bma530_set_feat_eng_gpr_0", rslt); + + rslt = bma5_set_regs(BMA5_REG_FEAT_ENG_GPR_CTRL, &gpr_ctrl_host, 1, &dev); + bma5_check_rslt("bma5_set_regs", rslt); + + rslt = bma530_get_int_map(&int_map, &dev); + bma5_check_rslt("bma530_get_int_map", rslt); + + /* Map generic interrupt 1 */ + int_map.gen_int2_int_map = BMA530_GEN_INT2_INT_MAP_INT2; + rslt = bma530_set_int_map(&int_map, &dev); + bma5_check_rslt("bma530_set_int_map", rslt); + + /* Map hardware interrupt pin configurations */ + rslt = bma5_get_int_conf(&int_config, n_ints, &dev); + bma5_check_rslt("bma5_get_int_conf", rslt); + + int_config.int_conf.int_mode = BMA5_INT2_MODE_PULSED_SHORT; + int_config.int_conf.int_od = BMA5_INT2_OD_PUSH_PULL; + int_config.int_conf.int_lvl = BMA5_INT2_LVL_ACTIVE_LOW; + + rslt = bma5_set_int_conf(&int_config, n_ints, &dev); + bma5_check_rslt("bma5_set_int_conf", rslt); + + printf("Shake the board to get generic interrupt 2 interrupt\n"); + + for (;;) + { + rslt = bma530_get_int_status(&int_status, n_status, &dev); + bma5_check_rslt("bma530_get_int_status", rslt); + + if (int_status.int_status.gen_int2_int_status & BMA5_ENABLE) + { + rslt = bma530_set_int_status(&int_status, n_status, &dev); + bma5_check_rslt("bma530_set_int_status", rslt); + + printf("Generic interrupt 2 interrupt occurred\n"); + + break; + } + } + + bma5_coines_deinit(); + + return rslt; +} diff --git a/examples/android_sig_motion/Makefile b/examples/android_sig_motion/Makefile new file mode 100644 index 0000000..1aa08fc --- /dev/null +++ b/examples/android_sig_motion/Makefile @@ -0,0 +1,18 @@ +COINES_INSTALL_PATH ?= ../../../.. + +EXAMPLE_FILE ?= android_sig_motion.c + +API_LOCATION ?= ../.. +COMMON_LOCATION ?= .. + +C_SRCS += \ +$(API_LOCATION)/bma5.c \ +$(API_LOCATION)/bma530.c \ +$(API_LOCATION)/bma530_features.c \ +$(COMMON_LOCATION)/common/common.c + +INCLUDEPATHS += \ +$(API_LOCATION) \ +$(COMMON_LOCATION)/common + +include $(COINES_INSTALL_PATH)/coines.mk diff --git a/examples/android_sig_motion/android_sig_motion.c b/examples/android_sig_motion/android_sig_motion.c new file mode 100644 index 0000000..521c85c --- /dev/null +++ b/examples/android_sig_motion/android_sig_motion.c @@ -0,0 +1,157 @@ +/** + * Copyright (c) 2024 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. + * + */ + +#include +#include "common.h" +#include "bma530_features.h" + +/******************************************************************************/ +int main(void) +{ + struct bma5_dev dev; + int8_t rslt; + uint8_t android_comp = 0; + uint8_t n_ints = 1; + uint8_t n_status = 1; + uint8_t get_android_comp = 0; + uint8_t gpr_ctrl_host = BMA5_ENABLE; + struct bma530_int_map int_map = { 0 }; + struct bma5_int_conf_types int_config = { 0 }; + struct bma530_sig_motion conf = { 0 }; + struct bma530_feat_eng_gpr_0 gpr_0 = { 0 }; + struct bma530_int_status_types int_status = { 0 }; + + int_config.int_src = BMA5_INT_2; + int_status.int_src = BMA530_INT_STATUS_INT2; + + /* Assign context parameter selection */ + enum bma5_context context; + context = BMA5_SMARTPHONE; + + /* Interface reference is given as a parameter + * For I2C : BMA5_I2C_INTF + * For SPI : BMA5_SPI_INTF + */ + rslt = bma5_interface_init(&dev, BMA5_SPI_INTF, context); + bma5_check_rslt("bma5_interface_init", rslt); + + rslt = bma530_init(&dev); + bma5_check_rslt("bma530_init", rslt); + printf("BMA530 Chip ID is 0x%X\n", dev.chip_id); + + rslt = bma530_get_android_comp_mode(&android_comp, &dev); + bma5_check_rslt("bma530_get_android_comp_mode", rslt); + + android_comp = 1; + + rslt = bma530_set_android_comp_mode(&android_comp, &dev); + bma5_check_rslt("bma530_set_android_comp_mode", rslt); + + printf("Get Android compatibility mode\n\n"); + rslt = bma530_get_android_comp_mode(&get_android_comp, &dev); + bma5_check_rslt("bma530_get_android_comp_mode", rslt); + + printf("Android compatibility mode : %d\n", get_android_comp); + + printf("\nDefault configurations\n\n"); + rslt = bma530_get_default_sig_motion_config(&conf, &dev); + bma5_check_rslt("bma530_get_default_sig_motion_config", rslt); + + printf("block_size :: 0x%x\n", conf.block_size); + printf("mcr_max :: 0x%x\n", conf.mcr_max); + printf("mcr_min :: 0x%x\n", conf.mcr_min); + printf("p2p_max :: 0x%x\n", conf.p2p_max); + printf("p2p_min :: 0x%x\n", conf.p2p_min); + + conf.block_size = 0xFA; + conf.mcr_max = 0x11; + conf.mcr_min = 0x11; + conf.p2p_max = 0x253; + conf.p2p_min = 0x26; + + rslt = bma530_set_sig_motion_config(&conf, &dev); + bma5_check_rslt("bma530_set_sig_motion_config", rslt); + + rslt = bma530_get_feat_eng_gpr_0(&gpr_0, &dev); + bma5_check_rslt("bma530_get_feat_eng_gpr_0", rslt); + + gpr_0.sig_mo_en = BMA5_ENABLE; + + rslt = bma530_set_feat_eng_gpr_0(&gpr_0, &dev); + bma5_check_rslt("bma530_set_feat_eng_gpr_0", rslt); + + rslt = bma5_set_regs(BMA5_REG_FEAT_ENG_GPR_CTRL, &gpr_ctrl_host, 1, &dev); + bma5_check_rslt("bma5_set_regs", rslt); + + rslt = bma530_get_int_map(&int_map, &dev); + bma5_check_rslt("bma530_get_int_map", rslt); + + /* Map sig motion */ + int_map.sig_mo_int_map = BMA530_SIG_MO_INT_MAP_INT2; + rslt = bma530_set_int_map(&int_map, &dev); + bma5_check_rslt("bma530_set_int_map", rslt); + + /* Map hardware interrupt pin configurations */ + rslt = bma5_get_int_conf(&int_config, n_ints, &dev); + bma5_check_rslt("bma5_get_int_conf", rslt); + + int_config.int_conf.int_mode = BMA5_INT2_MODE_PULSED_SHORT; + int_config.int_conf.int_od = BMA5_INT2_OD_PUSH_PULL; + int_config.int_conf.int_lvl = BMA5_INT2_LVL_ACTIVE_LOW; + + rslt = bma5_set_int_conf(&int_config, n_ints, &dev); + bma5_check_rslt("bma5_set_int_conf", rslt); + + printf("\nMove the board to get significant motion interrupt\n"); + + for (;;) + { + rslt = bma530_get_int_status(&int_status, n_status, &dev); + bma5_check_rslt("bma530_get_int_status", rslt); + + if (int_status.int_status.sig_mo_int_status & BMA5_ENABLE) + { + rslt = bma530_set_int_status(&int_status, n_status, &dev); + bma5_check_rslt("bma530_set_int_status", rslt); + + printf("Significant motion interrupt occurred\n"); + + break; + } + } + + bma5_coines_deinit(); + + return rslt; +} diff --git a/examples/android_tilt/Makefile b/examples/android_tilt/Makefile new file mode 100644 index 0000000..1d29b05 --- /dev/null +++ b/examples/android_tilt/Makefile @@ -0,0 +1,18 @@ +COINES_INSTALL_PATH ?= ../../../.. + +EXAMPLE_FILE ?= android_tilt.c + +API_LOCATION ?= ../.. +COMMON_LOCATION ?= .. + +C_SRCS += \ +$(API_LOCATION)/bma5.c \ +$(API_LOCATION)/bma530.c \ +$(API_LOCATION)/bma530_features.c \ +$(COMMON_LOCATION)/common/common.c + +INCLUDEPATHS += \ +$(API_LOCATION) \ +$(COMMON_LOCATION)/common + +include $(COINES_INSTALL_PATH)/coines.mk diff --git a/examples/android_tilt/android_tilt.c b/examples/android_tilt/android_tilt.c new file mode 100644 index 0000000..2cac7a0 --- /dev/null +++ b/examples/android_tilt/android_tilt.c @@ -0,0 +1,153 @@ +/** + * Copyright (c) 2024 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. + * + */ + +#include +#include "common.h" +#include "bma530_features.h" + +/******************************************************************************/ +int main(void) +{ + struct bma5_dev dev; + int8_t rslt; + uint8_t android_comp = 0; + uint8_t get_android_comp = 0; + uint8_t n_status = 1; + uint8_t n_ints = 1; + uint8_t gpr_ctrl_host = BMA5_ENABLE; + struct bma530_int_map int_map = { 0 }; + struct bma5_int_conf_types int_config = { 0 }; + struct bma530_tilt conf = { 0 }; + struct bma530_feat_eng_gpr_0 gpr_0 = { 0 }; + struct bma530_int_status_types int_status = { 0 }; + + int_config.int_src = BMA5_INT_2; + int_status.int_src = BMA530_INT_STATUS_INT2; + + /* Assign context parameter selection */ + enum bma5_context context; + context = BMA5_SMARTPHONE; + + /* Interface reference is given as a parameter + * For I2C : BMA5_I2C_INTF + * For SPI : BMA5_SPI_INTF + */ + rslt = bma5_interface_init(&dev, BMA5_SPI_INTF, context); + bma5_check_rslt("bma5_interface_init", rslt); + + rslt = bma530_init(&dev); + bma5_check_rslt("bma530_init", rslt); + printf("BMA530 Chip ID is 0x%X\n", dev.chip_id); + + rslt = bma530_get_android_comp_mode(&android_comp, &dev); + bma5_check_rslt("bma530_get_android_comp_mode", rslt); + + android_comp = 1; + + rslt = bma530_set_android_comp_mode(&android_comp, &dev); + bma5_check_rslt("bma530_set_android_comp_mode", rslt); + + printf("Get Android compatibility mode\n\n"); + rslt = bma530_get_android_comp_mode(&get_android_comp, &dev); + bma5_check_rslt("bma530_get_android_comp_mode", rslt); + + printf("Android compatibility mode : %d\n", get_android_comp); + + printf("\nDefault configurations\n\n"); + rslt = bma530_get_tilt_config(&conf, &dev); + bma5_check_rslt("bma530_get_tilt_config", rslt); + + printf("beta_acc_mean :: 0x%x\n", conf.beta_acc_mean); + printf("min_tilt_angle :: 0x%x\n", conf.min_tilt_angle); + printf("segment_size :: 0x%x\n", conf.segment_size); + + conf.beta_acc_mean = 0xf069; + conf.min_tilt_angle = 0xd2; + conf.segment_size = 0x64; + + rslt = bma530_set_tilt_config(&conf, &dev); + bma5_check_rslt("bma530_set_tilt_config", rslt); + + rslt = bma530_get_feat_eng_gpr_0(&gpr_0, &dev); + bma5_check_rslt("bma530_get_feat_eng_gpr_0", rslt); + + gpr_0.tilt_en = BMA5_ENABLE; + + rslt = bma530_set_feat_eng_gpr_0(&gpr_0, &dev); + bma5_check_rslt("bma530_set_feat_eng_gpr_0", rslt); + + rslt = bma5_set_regs(BMA5_REG_FEAT_ENG_GPR_CTRL, &gpr_ctrl_host, 1, &dev); + bma5_check_rslt("bma5_set_regs", rslt); + + rslt = bma530_get_int_map(&int_map, &dev); + bma5_check_rslt("bma530_get_int_map", rslt); + + /* Map tilt */ + int_map.tilt_int_map = BMA530_TILT_INT_MAP_INT2; + rslt = bma530_set_int_map(&int_map, &dev); + bma5_check_rslt("bma530_set_int_map", rslt); + + /* Map hardware interrupt pin configurations */ + rslt = bma5_get_int_conf(&int_config, n_ints, &dev); + bma5_check_rslt("bma5_get_int_conf", rslt); + + int_config.int_conf.int_mode = BMA5_INT2_MODE_PULSED_SHORT; + int_config.int_conf.int_od = BMA5_INT2_OD_PUSH_PULL; + int_config.int_conf.int_lvl = BMA5_INT2_LVL_ACTIVE_LOW; + + rslt = bma5_set_int_conf(&int_config, n_ints, &dev); + bma5_check_rslt("bma5_set_int_conf", rslt); + + printf("\nTilt the board to get tilt interrupt\n"); + + for (;;) + { + rslt = bma530_get_int_status(&int_status, n_status, &dev); + bma5_check_rslt("bma530_get_int_status", rslt); + + if (int_status.int_status.tilt_int_status & BMA5_ENABLE) + { + rslt = bma530_set_int_status(&int_status, n_status, &dev); + bma5_check_rslt("bma530_set_int_status", rslt); + + printf("Tilt interrupt occurred\n"); + + break; + } + } + + bma5_coines_deinit(); + + return rslt; +} diff --git a/examples/common/common.c b/examples/common/common.c new file mode 100644 index 0000000..6ec079e --- /dev/null +++ b/examples/common/common.c @@ -0,0 +1,200 @@ +/** + * Copyright (c) 2024 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. + * + */ +#include +#include +#include + +#include "bma5.h" +#include "coines.h" +#include "common.h" + +/* Variable to store the device address */ +static uint8_t dev_addr; + +/*! + * @brief I2C read function map to COINES platform + */ +BMA5_INTF_RET_TYPE bma5_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(COINES_I2C_BUS_0, dev_addr, reg_addr, reg_data, (uint16_t)len); +} + +/*! + * @brief I2C write function map to COINES platform + */ +BMA5_INTF_RET_TYPE bma5_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(COINES_I2C_BUS_0, dev_addr, reg_addr, (uint8_t *)reg_data, (uint16_t)len); +} + +/*! + * @brief SPI read function map to COINES platform + */ +BMA5_INTF_RET_TYPE bma5_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(COINES_SPI_BUS_0, dev_addr, reg_addr, reg_data, (uint16_t)len); +} + +/*! + * @brief SPI write function map to COINES platform + */ +BMA5_INTF_RET_TYPE bma5_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(COINES_SPI_BUS_0, dev_addr, reg_addr, (uint8_t *)reg_data, (uint16_t)len); +} + +/*! + * @brief Delay function map to COINES platform + */ +void bma5_delay_us(uint32_t period, void *intf_ptr) +{ + coines_delay_usec(period); +} + +void bma5_check_rslt(const char api_name[], int8_t rslt) +{ + switch (rslt) + { + case BMA5_OK: + + /* Do nothing */ + break; + case BMA5_E_NULL_PTR: + printf("API name %s\t", api_name); + printf("Error [%d] : Null pointer\r\n", rslt); + break; + case BMA5_E_COM_FAIL: + printf("API name %s\t", api_name); + printf("Error [%d] : Communication failure\r\n", rslt); + break; + case BMA5_E_DEV_NOT_FOUND: + printf("API name %s\t", api_name); + printf("Error [%d] : Device not found\r\n", rslt); + break; + default: + printf("API name %s\t", api_name); + printf("Error [%d] : Unknown error code\r\n", rslt); + break; + } +} + +int8_t bma5_interface_init(struct bma5_dev *bma5, uint8_t intf, enum bma5_context context) +{ + int8_t rslt = BMA5_OK; + + if (bma5 != NULL) + { + int16_t result = coines_open_comm_intf(COINES_COMM_INTF_USB, NULL); + + 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); + + /* Bus configuration : I2C */ + if (intf == BMA5_I2C_INTF) + { + printf("I2C Interface \n"); + + dev_addr = BMA5_I2C_ADDRESS; + bma5->bus_read = bma5_i2c_read; + bma5->bus_write = bma5_i2c_write; + bma5->intf = BMA5_I2C_INTF; + + coines_config_i2c_bus(COINES_I2C_BUS_0, COINES_I2C_STANDARD_MODE); + } + /* Bus configuration : SPI */ + else if (intf == BMA5_SPI_INTF) + { + printf("SPI Interface \n"); + + dev_addr = COINES_MINI_SHUTTLE_PIN_2_1; + bma5->bus_read = bma5_spi_read; + bma5->bus_write = bma5_spi_write; + bma5->intf = BMA5_SPI_INTF; + + coines_config_spi_bus(COINES_SPI_BUS_0, COINES_SPI_SPEED_7_5_MHZ, COINES_SPI_MODE0); + } + + coines_delay_msec(100); + + coines_set_shuttleboard_vdd_vddio_config(1800, 1800); + + coines_delay_msec(100); + + /* Holds the I2C device addr or SPI chip selection */ + bma5->intf_ptr = &dev_addr; + + /* Configure delay in microseconds */ + bma5->delay_us = bma5_delay_us; + + /* Assign context parameter */ + bma5->context = context; + } + else + { + rslt = BMA5_E_NULL_PTR; + } + + return rslt; +} + +void bma5_coines_deinit(void) +{ + fflush(stdout); + + coines_set_shuttleboard_vdd_vddio_config(0, 0); + + coines_delay_msec(2000); + + coines_soft_reset(); + + coines_delay_msec(100); + + coines_close_comm_intf(COINES_COMM_INTF_USB, NULL); +} diff --git a/examples/common/common.h b/examples/common/common.h new file mode 100644 index 0000000..c3ce0e9 --- /dev/null +++ b/examples/common/common.h @@ -0,0 +1,167 @@ +/** + * Copyright (c) 2024 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. + * + */ + +#ifndef _COMMON_H +#define _COMMON_H + +/*! CPP guard */ +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include "bma5.h" + +/***************************************************************************/ + +/*! User function prototypes + ****************************************************************************/ + +/*! + * @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, out] intf_ptr : Void pointer that can enable the linking of descriptors + * for interface related call backs. + * + * @return Status of execution + * + * @retval BMA5_INTF_RET_SUCCESS -> Success. + * @retval != BMA5_INTF_RET_SUCCESS -> Fail. + * + */ +BMA5_INTF_RET_TYPE bma5_spi_read(uint8_t reg_addr, uint8_t *reg_data, uint32_t length, void *intf_ptr); + +/*! + * @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, out] intf_ptr : Void pointer that can enable the linking of descriptors + * for interface related call backs. + * + * @return Status of execution + * + * @retval BMA5_INTF_RET_SUCCESS -> Success. + * @retval != BMA5_INTF_RET_SUCCESS -> Fail. + * + */ +BMA5_INTF_RET_TYPE bma5_i2c_read(uint8_t reg_addr, uint8_t *reg_data, uint32_t length, 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, out] intf_ptr : Void pointer that can enable the linking of descriptors + * for interface related call backs. + * + * @return Status of execution + * + * @retval BMA5_INTF_RET_SUCCESS -> Success. + * @retval != BMA5_INTF_RET_SUCCESS -> Fail. + * + */ +BMA5_INTF_RET_TYPE bma5_spi_write(uint8_t reg_addr, const uint8_t *reg_data, uint32_t length, 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, out] intf_ptr : Void pointer that can enable the linking of descriptors + * for interface related call backs. + * + * @return Status of execution + * + * @retval BMA5_INTF_RET_SUCCESS -> Success. + * @retval != BMA5_INTF_RET_SUCCESS -> Failure. + * + */ +BMA5_INTF_RET_TYPE bma5_i2c_write(uint8_t reg_addr, const uint8_t *reg_data, uint32_t length, 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, out] intf_ptr : Void pointer that can enable the linking of descriptors + * for interface related call backs. + * @return void. + * + */ +void bma5_delay_us(uint32_t period_us, void *intf_ptr); + +/*! + * @brief Function to select the interface between SPI and I2C. + * Also to initialize coines platform. + * + * @param[in] bma5 : Structure instance of bma5_dev + * @param[in] intf : Interface selection parameter + * @param[in] context : Context parameter selection + * + * @return Status of execution + * @retval 0 -> Success + * @retval < 0 -> Failure Info + */ +int8_t bma5_interface_init(struct bma5_dev *bma5, uint8_t intf, enum bma5_context context); + +/*! + * @brief Prints the execution status of the APIs. + * + * @param[in] api_name : Name of the API whose execution status has to be printed. + * @param[in] rslt : Error code returned by the API whose execution status has to be printed. + * + * @return void. + */ +void bma5_check_rslt(const char api_name[], int8_t rslt); + +/*! + * @brief This function deinitializes coines platform + * + * @return void. + * + */ +void bma5_coines_deinit(void); + +#ifdef __cplusplus +} +#endif /* End of CPP guard */ + +#endif /* _COMMON_H */ diff --git a/examples/feature_axis_exchange/Makefile b/examples/feature_axis_exchange/Makefile new file mode 100644 index 0000000..51bf32b --- /dev/null +++ b/examples/feature_axis_exchange/Makefile @@ -0,0 +1,18 @@ +COINES_INSTALL_PATH ?= ../../../.. + +EXAMPLE_FILE ?= feature_axis_exchange.c + +API_LOCATION ?= ../.. +COMMON_LOCATION ?= .. + +C_SRCS += \ +$(API_LOCATION)/bma5.c \ +$(API_LOCATION)/bma530.c \ +$(API_LOCATION)/bma530_features.c \ +$(COMMON_LOCATION)/common/common.c + +INCLUDEPATHS += \ +$(API_LOCATION) \ +$(COMMON_LOCATION)/common + +include $(COINES_INSTALL_PATH)/coines.mk diff --git a/examples/feature_axis_exchange/feature_axis_exchange.c b/examples/feature_axis_exchange/feature_axis_exchange.c new file mode 100644 index 0000000..5dead21 --- /dev/null +++ b/examples/feature_axis_exchange/feature_axis_exchange.c @@ -0,0 +1,269 @@ +/** + * Copyright (c) 2024 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. + * + */ + +#include +#include "common.h" +#include "bma530_features.h" + +/******************************************************************************/ +/*! Static Function Declaration */ + +/*! + * @brief This internal API prints the selected XYZ axis. + * + * @param[in] conf : Structure instance of bma530_feat_axis. + * + * @return void. + * + */ +static void feature_axis_selection(const struct bma530_feat_axis *conf); + +/******************************************************************************/ +int main(void) +{ + int8_t rslt; + uint8_t n_ints = 1; + uint8_t n_status = 1; + uint8_t gpr_ctrl_host = BMA5_ENABLE; + + struct bma5_dev dev; + struct bma530_feat_axis conf, get_conf; + struct bma530_int_map int_map = { 0 }; + struct bma5_int_conf_types int_config; + struct bma530_generic_interrupt_types gen_conf, set_gen_conf; + struct bma530_int_status_types int_status; + struct bma530_feat_eng_gpr_0 gpr_0; + struct bma5_feat_eng_status feat_eng_status; + + gen_conf.generic_interrupt = BMA530_GEN_INT_1; + set_gen_conf.generic_interrupt = BMA530_GEN_INT_1; + int_status.int_src = BMA530_INT_STATUS_INT1; + int_config.int_src = BMA5_INT_1; + + /* Assign context parameter selection */ + enum bma5_context context; + context = BMA5_SMARTPHONE; + + /* Interface reference is given as a parameter + * For I2C : BMA5_I2C_INTF + * For SPI : BMA5_SPI_INTF + */ + rslt = bma5_interface_init(&dev, BMA5_I2C_INTF, context); + bma5_check_rslt("bma5_interface_init", rslt); + + rslt = bma530_init(&dev); + bma5_check_rslt("bma530_init", rslt); + printf("BMA530 Chip ID is 0x%X\n", dev.chip_id); + + rslt = bma5_get_feat_eng_status(&feat_eng_status, &dev); + bma5_check_rslt("bma5_get_feat_eng_status", rslt); + + printf("feat_eng_status.feat_eng_gpr_update_pending : %d\n", feat_eng_status.feat_eng_gpr_update_pending); + printf("feat_eng_status.feat_eng_halted : %d\n", feat_eng_status.feat_eng_halted); + printf("feat_eng_status.feat_eng_running : %d\n", feat_eng_status.feat_eng_running); + printf("feat_eng_status.host_gpr_update_pending : %d\n\n", feat_eng_status.host_gpr_update_pending); + + rslt = bma530_get_feature_axis_config(&conf, &dev); + bma5_check_rslt("bma530_get_feature_axis_config", rslt); + + conf.feat_axis_ex = BMA530_FEAT_AXIS_EX_ZXY; + conf.feat_x_inv = BMA530_FEAT_X_INV_INVERT; + conf.feat_y_inv = BMA530_FEAT_Y_INV_INVERT; + conf.feat_z_inv = BMA530_FEAT_Z_INV_INVERT; + + rslt = bma530_set_feature_axis_config(&conf, &dev); + bma5_check_rslt("bma530_set_feature_axis_config", rslt); + + rslt = bma530_get_feature_axis_config(&get_conf, &dev); + bma5_check_rslt("bma530_get_feature_axis_config", rslt); + + feature_axis_selection(&get_conf); + + rslt = bma530_get_generic_int_config(&gen_conf, n_ints, &dev); + bma5_check_rslt("bma530_get_generic_int_config", rslt); + + set_gen_conf.gen_int.slope_thres = 0xA; + set_gen_conf.gen_int.comb_sel = 0x0; + set_gen_conf.gen_int.axis_sel = BMA530_FEAT_AXIS_EX_SEL_Z; + set_gen_conf.gen_int.hysteresis = 0x2; + set_gen_conf.gen_int.criterion_sel = 0x1; + set_gen_conf.gen_int.acc_ref_up = 0x1; + set_gen_conf.gen_int.duration = 0xA; + set_gen_conf.gen_int.wait_time = 0x3; + set_gen_conf.gen_int.quiet_time = 0x40; + set_gen_conf.gen_int.ref_acc_x = 0x0; + set_gen_conf.gen_int.ref_acc_y = 0x0; + set_gen_conf.gen_int.ref_acc_z = 0x800; + + rslt = bma530_set_generic_int_config(&set_gen_conf, n_ints, &dev); + bma5_check_rslt("bma530_set_generic_int_config", rslt); + + rslt = bma530_get_generic_int_config(&gen_conf, n_ints, &dev); + bma5_check_rslt("bma530_get_generic_int_config", rslt); + + printf("\nGeneric Interrupt 1 configurations\n"); + printf("slope_thres 0x%x\n", gen_conf.gen_int.slope_thres); + printf("comb_sel 0x%x\n", gen_conf.gen_int.comb_sel); + printf("axis_sel 0x%x\n", gen_conf.gen_int.axis_sel); + printf("hysteresis 0x%x\n", gen_conf.gen_int.hysteresis); + printf("criterion_sel 0x%x\n", gen_conf.gen_int.criterion_sel); + printf("acc_ref_up 0x%x\n", gen_conf.gen_int.acc_ref_up); + printf("duration 0x%x\n", gen_conf.gen_int.duration); + printf("wait_time 0x%x\n", gen_conf.gen_int.wait_time); + printf("quiet_time 0x%x\n", gen_conf.gen_int.quiet_time); + printf("ref_acc_x 0x%x\n", gen_conf.gen_int.ref_acc_x); + printf("ref_acc_y 0x%x\n", gen_conf.gen_int.ref_acc_y); + printf("ref_acc_z 0x%x\n", gen_conf.gen_int.ref_acc_z); + + rslt = bma530_get_feat_eng_gpr_0(&gpr_0, &dev); + bma5_check_rslt("bma530_get_feat_eng_gpr_0", rslt); + + gpr_0.gen_int1_en = BMA5_ENABLE; + + rslt = bma530_set_feat_eng_gpr_0(&gpr_0, &dev); + bma5_check_rslt("bma530_set_feat_eng_gpr_0", rslt); + + rslt = bma5_set_regs(BMA5_REG_FEAT_ENG_GPR_CTRL, &gpr_ctrl_host, 1, &dev); + bma5_check_rslt("bma5_set_regs", rslt); + + rslt = bma530_get_feat_eng_gpr_0(&gpr_0, &dev); + bma5_check_rslt("bma530_get_feat_eng_gpr_0", rslt); + + printf("\ngpr_0.gen_int1_en : %d\n", gpr_0.gen_int1_en); + + rslt = bma530_get_int_map(&int_map, &dev); + bma5_check_rslt("bma530_get_int_map", rslt); + + /* Map generic interrupt 1 */ + int_map.gen_int1_int_map = BMA530_GEN_INT1_INT_MAP_INT1; + rslt = bma530_set_int_map(&int_map, &dev); + bma5_check_rslt("bma530_set_int_map", rslt); + + /* Map hardware interrupt pin configurations */ + rslt = bma5_get_int_conf(&int_config, n_ints, &dev); + bma5_check_rslt("bma5_get_int_conf", rslt); + + int_config.int_conf.int_mode = BMA5_INT1_MODE_LATCHED; + int_config.int_conf.int_od = BMA5_INT1_OD_PUSH_PULL; + int_config.int_conf.int_lvl = BMA5_INT1_LVL_ACTIVE_HIGH; + + rslt = bma5_set_int_conf(&int_config, n_ints, &dev); + bma5_check_rslt("bma5_set_int_conf", rslt); + + printf("\nShake the board to get generic interrupt 1 interrupt\n"); + + for (;;) + { + rslt = bma530_get_int_status(&int_status, n_status, &dev); + bma5_check_rslt("bma530_get_int_status", rslt); + + if (int_status.int_status.gen_int1_int_status & BMA5_ENABLE) + { + rslt = bma530_set_int_status(&int_status, n_ints, &dev); + bma5_check_rslt("bma530_set_int_status", rslt); + + printf("Generic interrupt 1 interrupt occurred\n"); + + break; + } + } + + bma5_coines_deinit(); + + return rslt; +} + +/*! + * @brief This internal API prints the selected XYZ axis. + */ +static void feature_axis_selection(const struct bma530_feat_axis *conf) +{ + if ((conf->feat_axis_ex == BMA530_FEAT_AXIS_EX_DEFAULT_0) || + (conf->feat_axis_ex == BMA530_FEAT_AXIS_EX_DEFAULT_6) || (conf->feat_axis_ex == BMA530_FEAT_AXIS_EX_DEFAULT_7)) + { + printf("Selected axis is XYZ\n"); + } + + if (conf->feat_axis_ex == BMA530_FEAT_AXIS_EX_YXZ) + { + printf("Selected axis is YXZ\n"); + } + + if (conf->feat_axis_ex == BMA530_FEAT_AXIS_EX_XZY) + { + printf("Selected axis is XZY\n"); + } + + if (conf->feat_axis_ex == BMA530_FEAT_AXIS_EX_ZXY) + { + printf("Selected axis is ZXY\n"); + } + + if (conf->feat_axis_ex == BMA530_FEAT_AXIS_EX_YZX) + { + printf("Selected axis is YZX\n"); + } + + if (conf->feat_axis_ex == BMA530_FEAT_AXIS_EX_ZYX) + { + printf("Selected axis is ZYX\n"); + } + + if (conf->feat_x_inv == BMA530_FEAT_X_INV_DEFAULT) + { + printf("feat_x_inv : remains unchanged\n"); + } + else + { + printf("feat_x_inv : -X\n"); + } + + if (conf->feat_y_inv == BMA530_FEAT_Y_INV_DEFAULT) + { + printf("feat_y_inv : remains unchanged\n"); + } + else + { + printf("feat_y_inv : -Y\n"); + } + + if (conf->feat_z_inv == BMA530_FEAT_Z_INV_DEFAULT) + { + printf("feat_z_inv : remains unchanged\n"); + } + else + { + printf("feat_z_inv : -Z\n"); + } +} diff --git a/examples/fifo_full_16_bit_dedicated_frame_comp_dis/Makefile b/examples/fifo_full_16_bit_dedicated_frame_comp_dis/Makefile new file mode 100644 index 0000000..70fd6b4 --- /dev/null +++ b/examples/fifo_full_16_bit_dedicated_frame_comp_dis/Makefile @@ -0,0 +1,18 @@ +COINES_INSTALL_PATH ?= ../../../.. + +EXAMPLE_FILE ?= fifo_full_16_bit_dedicated_frame_comp_dis.c + +API_LOCATION ?= ../.. +COMMON_LOCATION ?= .. + +C_SRCS += \ +$(API_LOCATION)/bma5.c \ +$(API_LOCATION)/bma530.c \ +$(API_LOCATION)/bma530_features.c \ +$(COMMON_LOCATION)/common/common.c + +INCLUDEPATHS += \ +$(API_LOCATION) \ +$(COMMON_LOCATION)/common + +include $(COINES_INSTALL_PATH)/coines.mk diff --git a/examples/fifo_full_16_bit_dedicated_frame_comp_dis/fifo_full_16_bit_dedicated_frame_comp_dis.c b/examples/fifo_full_16_bit_dedicated_frame_comp_dis/fifo_full_16_bit_dedicated_frame_comp_dis.c new file mode 100644 index 0000000..e01004d --- /dev/null +++ b/examples/fifo_full_16_bit_dedicated_frame_comp_dis/fifo_full_16_bit_dedicated_frame_comp_dis.c @@ -0,0 +1,377 @@ +/** + * Copyright (c) 2024 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. + * + */ + +#include +#include +#include "common.h" +#include "bma530_features.h" + +/******************************************************************************/ +/*! Macro definition */ + +/*! FIFO raw data buffer size */ +#define BMA530_FIFO_RAW_DATA_BUFFER_SIZE UINT16_C(520) + +/*! Number of accel frames to be extracted from FIFO + * + * Calculation: + * fifo_buffer = 520, accel_frame_len = 6 + * fifo_accel_frame_count = (520 / (6)) = 86 frames + * + * Note : + * Dedicated frame generates header on demand. + * Additional frames given to read sensortime frame + */ +#define ACCEL_FRAME_LEN UINT8_C(255) + +/*! Sensortime resolution in seconds */ +#define SENSORTIME_RESOLUTION (0.0003125f) + +/*! Earth's gravity in m/s^2 */ +#define GRAVITY_EARTH (9.80665f) + +/******************************************************************************/ +/*! Global Variables */ + +/*! Number of accel frames to be extracted from FIFO */ +uint8_t fifo_accel_frame_length = ACCEL_FRAME_LEN; + +/*! Number of bytes of FIFO data */ +uint8_t fifo_data[BMA530_FIFO_RAW_DATA_BUFFER_SIZE + BMA5_SENSORTIME_OVERHEAD_BYTE] = { 0 }; + +/*! Array of accelerometer and sensortime frames + * Array size same as fifo_accel_frame_length */ +struct bma5_sens_fifo_axes_data_16_bit fifo_acc_data[ACCEL_FRAME_LEN]; + +/******************************************************************************/ +/*! Static Function Declaration */ + +/*! + * @brief This internal API is used to enable accel and interrupt configuration settings. + * + * @param[in] dev : Structure instance of bma5_dev. + * + * return Status of API + */ +static int8_t get_accel_and_int_settings(struct bma5_dev *dev); + +/*! + * @brief This internal API gets FIFO configurations. + * + * @param[in, out] fifo_conf : Structure instance of bma5_fifo_conf. + * @param[in] dev : Structure instance of bma5_dev. + * + * return Status of API + */ +static int8_t get_fifo_conf(const struct bma5_fifo_conf *fifo_conf, struct bma5_dev *dev); + +/*! + * @brief This internal API gets FIFO 16 bit data with FIFO full interrupt. + * + * @param[in] accel_length : Store accel frame length. + * @param[in] fifo_accel_data : Structure instance of bma5_sens_fifo_axes_data_8_bit. + * @param[in] fifoframe : Structure instance of bma5_fifo_frame. + * @param[in] fifo_conf : Structure instance of bma5_fifo_conf. + * @param[in] dev : Structure instance of bma5_dev. + * + * return Status of API + */ +static int8_t get_fifo_full_16_bit_data(struct bma5_sens_fifo_axes_data_16_bit *fifo_accel_data, + struct bma5_fifo_frame fifoframe, + const struct bma5_fifo_conf *fifo_conf, + struct bma5_dev *dev); + +/*! + * @brief This internal API converts raw sensor values(LSB) to meters per seconds square. + * + * @param[in] val : Raw sensor value. + * @param[in] g_range : Accel Range selected (2G, 4G, 8G, 16G). + * @param[in] bit_width : Resolution of the sensor. + * + * @return Accel values in meters per second square. + * + */ +static float lsb_to_ms2(int16_t val, float g_range, uint8_t bit_width); + +/******************************************************************************/ +int main(void) +{ + struct bma5_dev dev; + int8_t rslt; + struct bma530_int_map int_map, get_int_map; + struct bma5_fifo_conf fifo_conf; + + /* Initialize FIFO frame structure */ + struct bma5_fifo_frame fifoframe = { 0 }; + enum bma5_context context; + + /* Assign context parameter selection */ + context = BMA5_SMARTPHONE; + + /* Interface reference is given as a parameter + * For I2C : BMA5_I2C_INTF + * For SPI : BMA5_SPI_INTF + */ + rslt = bma5_interface_init(&dev, BMA5_SPI_INTF, context); + bma5_check_rslt("bma5_interface_init", rslt); + + rslt = bma530_init(&dev); + bma5_check_rslt("bma530_init", rslt); + printf("BMA530 Chip ID is 0x%X\n", dev.chip_id); + + rslt = bma530_get_int_map(&int_map, &dev); + bma5_check_rslt("bma530_get_int_map", rslt); + + int_map.fifo_full_int_map = BMA530_FIFO_FULL_INT_MAP_INT2; + rslt = bma530_set_int_map(&int_map, &dev); + bma5_check_rslt("bma530_set_int_map", rslt); + + rslt = bma530_get_int_map(&get_int_map, &dev); + bma5_check_rslt("bma530_get_int_map", rslt); + + rslt = get_accel_and_int_settings(&dev); + bma5_check_rslt("get_accel_and_int_settings", rslt); + + /* Get FIFO configuration register */ + rslt = bma5_get_fifo_conf(&fifo_conf, &dev); + bma5_check_rslt("bma5_get_fifo_conf", rslt); + + rslt = bma5_get_fifo_conf(&fifo_conf, &dev); + bma5_check_rslt("bma5_get_fifo_conf", rslt); + + fifo_conf.fifo_cfg = BMA5_FIFO_CFG_ENABLE; + fifo_conf.fifo_acc_x = BMA5_FIFO_ACC_X_ENABLE; + fifo_conf.fifo_acc_y = BMA5_FIFO_ACC_Y_ENABLE; + fifo_conf.fifo_acc_z = BMA5_FIFO_ACC_Z_ENABLE; + fifo_conf.fifo_compression = BMA5_FIFO_COMPRESSION_ACC_16BIT; + fifo_conf.fifo_sensor_time = BMA5_FIFO_SENSOR_TIME_DEDICATED_FRAME; + fifo_conf.fifo_size = BMA5_FIFO_SIZE_MAX_512_BYTES; + fifo_conf.fifo_stop_on_full = BMA5_ENABLE; + + rslt = get_fifo_conf(&fifo_conf, &dev); + bma5_check_rslt("get_fifo_conf", rslt); + + /* Update FIFO structure */ + fifoframe.data = fifo_data; + + rslt = get_fifo_full_16_bit_data(fifo_acc_data, fifoframe, &fifo_conf, &dev); + + bma5_coines_deinit(); + + return rslt; +} + +/*! + * @brief This internal API is used to enable accel and interrupt configuration settings. + */ +static int8_t get_accel_and_int_settings(struct bma5_dev *dev) +{ + int8_t rslt; + uint8_t n_ints = 1; + uint8_t sensor_ctrl; + struct bma5_acc_conf acc_cfg, get_acc_cfg; + struct bma5_int_conf_types int_config; + + int_config.int_src = BMA5_INT_2; + + /* Get accel configurations */ + rslt = bma5_get_acc_conf_0(&sensor_ctrl, dev); + bma5_check_rslt("bma5_get_acc_conf_0", rslt); + + rslt = bma5_get_acc_conf(&acc_cfg, dev); + bma5_check_rslt("bma5_get_acc_conf", rslt); + + /* Set accel configurations */ + acc_cfg.acc_odr = BMA5_ACC_ODR_HZ_6K4; + acc_cfg.acc_bwp = BMA5_ACC_BWP_NORM_AVG4; + acc_cfg.power_mode = BMA5_POWER_MODE_HPM; + + acc_cfg.acc_range = BMA5_ACC_RANGE_MAX_2G; + acc_cfg.acc_iir_ro = BMA5_ACC_IIR_RO_DB_60; + acc_cfg.noise_mode = BMA5_NOISE_MODE_LOWER_POWER; + acc_cfg.acc_drdy_int_auto_clear = BMA5_ACC_DRDY_INT_AUTO_CLEAR_DISABLED; + + rslt = bma5_set_acc_conf(&acc_cfg, dev); + bma5_check_rslt("bma5_get_acc_conf", rslt); + + /* Enable accel */ + sensor_ctrl = BMA5_SENSOR_CTRL_ENABLE; + + rslt = bma5_set_acc_conf_0(sensor_ctrl, dev); + bma5_check_rslt("bma5_set_acc_conf_0", rslt); + + rslt = bma5_get_acc_conf_0(&sensor_ctrl, dev); + bma5_check_rslt("bma5_set_acc_conf_0", rslt); + + rslt = bma5_get_acc_conf(&get_acc_cfg, dev); + bma5_check_rslt("bma5_get_acc_conf", rslt); + + printf("Sensor CTRL : %d\n", sensor_ctrl); + printf("ODR : %d\n", get_acc_cfg.acc_odr); + printf("BW : %d\n", get_acc_cfg.acc_bwp); + printf("Power mode : %d\n", get_acc_cfg.power_mode); + printf("Range : %d\n", get_acc_cfg.acc_range); + printf("IIR RO : %d\n", get_acc_cfg.acc_iir_ro); + printf("Noise mode : %d\n", get_acc_cfg.noise_mode); + printf("Auto Int clear : %d\n", get_acc_cfg.acc_drdy_int_auto_clear); + + rslt = bma5_get_int_conf(&int_config, n_ints, dev); + bma5_check_rslt("bma5_get_int_conf", rslt); + + int_config.int_conf.int_mode = BMA5_INT2_MODE_LATCHED; + int_config.int_conf.int_od = BMA5_INT2_OD_PUSH_PULL; + int_config.int_conf.int_lvl = BMA5_INT2_LVL_ACTIVE_HIGH; + + rslt = bma5_set_int_conf(&int_config, n_ints, dev); + bma5_check_rslt("bma5_set_int_conf", rslt); + + return rslt; +} + +/*! + * @brief This internal API gets FIFO configurations. + */ +static int8_t get_fifo_conf(const struct bma5_fifo_conf *fifo_conf, struct bma5_dev *dev) +{ + int8_t rslt; + struct bma5_fifo_conf read_fifo_conf = { 0 }; + + /* Set FIFO configuration. + * NOTE 1: FIFO works only on header mode */ + rslt = bma5_set_fifo_conf(fifo_conf, dev); + bma5_check_rslt("bma5_set_fifo_conf", rslt); + + printf("\nSet FIFO conf\n"); + printf("fifo en %d\n", fifo_conf->fifo_cfg); + printf("fifo_x_en %d\n", fifo_conf->fifo_acc_x); + printf("fifo_y_en %d\n", fifo_conf->fifo_acc_y); + printf("fifo_z_en %d\n", fifo_conf->fifo_acc_z); + printf("fifo_compression_en %d\n", fifo_conf->fifo_compression); + printf("fifo_sensor_time %d\n", fifo_conf->fifo_sensor_time); + printf("fifo_size %d\n", fifo_conf->fifo_size); + + /* Get FIFO configuration register */ + rslt = bma5_get_fifo_conf(&read_fifo_conf, dev); + bma5_check_rslt("bma5_get_fifo_conf", rslt); + + printf("\nGet FIFO conf\n"); + printf("fifo en %d\n", read_fifo_conf.fifo_cfg); + printf("fifo_x_en %d\n", read_fifo_conf.fifo_acc_x); + printf("fifo_y_en %d\n", read_fifo_conf.fifo_acc_y); + printf("fifo_z_en %d\n", read_fifo_conf.fifo_acc_z); + printf("fifo_compression_en %d\n", read_fifo_conf.fifo_compression); + printf("fifo_sensor_time %d\n", read_fifo_conf.fifo_sensor_time); + printf("fifo_size %d\n", read_fifo_conf.fifo_size); + + return rslt; +} + +/*! + * @brief This internal API gets FIFO 16 bit data with FIFO full interrupt. + */ +static int8_t get_fifo_full_16_bit_data(struct bma5_sens_fifo_axes_data_16_bit *fifo_accel_data, + struct bma5_fifo_frame fifoframe, + const struct bma5_fifo_conf *fifo_conf, + struct bma5_dev *dev) +{ + int8_t rslt = BMA5_OK; + uint8_t n_status = 1; + struct bma530_int_status_types int_status = { 0 }; + uint8_t loop = 0; + uint16_t idx = 0; + float x = 0, y = 0, z = 0; + + int_status.int_src = BMA530_INT_STATUS_INT2; + + printf("Get FIFO data"); + + while (loop < 3) + { + /* Get fifo full interrupt 2 status */ + rslt = bma530_get_int_status(&int_status, n_status, dev); + bma5_check_rslt("bma530_get_int_status", rslt); + + if (int_status.int_status.fifo_full_int_status & BMA5_ENABLE) + { + printf("\n\nIteration %d\n\n", loop); + + /* Read FIFO data */ + rslt = bma5_read_fifo_data(&fifoframe, fifo_conf, dev); + bma5_check_rslt("bma5_read_fifo_data", rslt); + + /* Set fifo full interrupt 2 status */ + rslt = bma530_set_int_status(&int_status, n_status, dev); + bma5_check_rslt("bma530_get_int_status\n", rslt); + + if (rslt == BMA5_OK) + { + /* Parse the FIFO data to extract accelerometer and sensortime data from the FIFO buffer */ + (void)bma5_extract_acc_sens_time_16_bit(fifo_accel_data, &fifoframe, fifo_conf, dev); + + printf("\nCount, Accel_LSB_X, Accel_LSB_Y, Accel_LSB_Z, Acc_ms2_X, Acc_ms2_Y, Acc_ms2_Z\n"); + + /* Print the parsed accelerometer and sensortime data from the FIFO buffer */ + for (idx = 0; idx < fifoframe.fifo_avail_frames; idx++) + { + /* Converting lsb to meter per second squared for 16 bit resolution at 2G range */ + x = lsb_to_ms2(fifo_accel_data[idx].x, (float)2, BMA5_16_BIT_RESOLUTION); + y = lsb_to_ms2(fifo_accel_data[idx].y, (float)2, BMA5_16_BIT_RESOLUTION); + z = lsb_to_ms2(fifo_accel_data[idx].z, (float)2, BMA5_16_BIT_RESOLUTION); + + /* Print the data in m/s2 */ + printf("%d, %d, %d, %d, %4.2f, %4.2f, %4.2f\n", idx, fifo_accel_data[idx].x, + fifo_accel_data[idx].y, fifo_accel_data[idx].z, x, y, z); + } + + printf("Sensor time(in seconds) = %.4lf s", fifo_accel_data[idx].sensor_time * SENSORTIME_RESOLUTION); + + loop++; + } + } + } + + return rslt; +} + +/*! + * @brief This internal API converts raw sensor values(LSB) to meters per seconds square. + */ +static float lsb_to_ms2(int16_t val, float g_range, uint8_t bit_width) +{ + double power = 2; + + float half_scale = (float)((pow((double)power, (double)bit_width) / 2.0f)); + + return (GRAVITY_EARTH * val * g_range) / half_scale; +} diff --git a/examples/fifo_full_16_bit_each_frame_comp_dis/Makefile b/examples/fifo_full_16_bit_each_frame_comp_dis/Makefile new file mode 100644 index 0000000..2c9d4d7 --- /dev/null +++ b/examples/fifo_full_16_bit_each_frame_comp_dis/Makefile @@ -0,0 +1,18 @@ +COINES_INSTALL_PATH ?= ../../../.. + +EXAMPLE_FILE ?= fifo_full_16_bit_each_frame_comp_dis.c + +API_LOCATION ?= ../.. +COMMON_LOCATION ?= .. + +C_SRCS += \ +$(API_LOCATION)/bma5.c \ +$(API_LOCATION)/bma530.c \ +$(API_LOCATION)/bma530_features.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/fifo_full_16_bit_each_frame_comp_dis/fifo_full_16_bit_each_frame_comp_dis.c b/examples/fifo_full_16_bit_each_frame_comp_dis/fifo_full_16_bit_each_frame_comp_dis.c new file mode 100644 index 0000000..d585ea7 --- /dev/null +++ b/examples/fifo_full_16_bit_each_frame_comp_dis/fifo_full_16_bit_each_frame_comp_dis.c @@ -0,0 +1,380 @@ +/** + * Copyright (c) 2024 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. + * + */ + +#include +#include +#include "common.h" +#include "bma530_features.h" + +/******************************************************************************/ +/*! Macro definition */ + +/*! FIFO raw data buffer size */ +#define BMA530_FIFO_RAW_DATA_BUFFER_SIZE UINT16_C(520) + +/*! Number of accel frames to be extracted from FIFO + * Calculation: + * fifo_buffer = 520, accel_frame_len = 6, header_byte = 1, sensortime = 3. + * fifo_accel_frame_count = (520 / (6 + 1 + 3)) = 52 frames + * + * Additional frames given to test FIFO on higher ODRs. + */ +#define ACCEL_FRAME_LEN UINT8_C(255) + +/*! Sensortime resolution in seconds */ +#define SENSORTIME_RESOLUTION (0.0003125f) + +/*! Earth's gravity in m/s^2 */ +#define GRAVITY_EARTH (9.80665f) + +/******************************************************************************/ +/*! Global Variables */ + +/*! Number of accel frames to be extracted from FIFO */ +uint8_t fifo_accel_frame_length = ACCEL_FRAME_LEN; + +/*! Number of bytes of FIFO data */ +uint8_t fifo_data[BMA530_FIFO_RAW_DATA_BUFFER_SIZE] = { 0 }; + +/*! Array of accelerometer and sensortime frames + * Array size same as fifo_accel_frame_length */ +struct bma5_sens_fifo_axes_data_16_bit fifo_acc_data[ACCEL_FRAME_LEN]; + +/******************************************************************************/ +/*! Static Function Declaration */ + +/*! + * @brief This internal API is used to enable accel and interrupt configuration settings. + * + * @param[in] dev : Structure instance of bma5_dev. + * + * return Status of API + */ +static int8_t get_accel_and_int_settings(struct bma5_dev *dev); + +/*! + * @brief This internal API gets FIFO configurations. + * + * @param[in, out] fifo_conf : Structure instance of bma5_fifo_conf. + * @param[in] dev : Structure instance of bma5_dev. + * + * return Status of API + */ +static int8_t get_fifo_conf(const struct bma5_fifo_conf *fifo_conf, struct bma5_dev *dev); + +/*! + * @brief This internal API gets FIFO 16 bit data with FIFO full interrupt. + * + * @param[in] accel_length : Store accel frame length. + * @param[in] fifo_accel_data : Structure instance of bma5_sens_fifo_axes_data_8_bit. + * @param[in] fifoframe : Structure instance of bma5_fifo_frame. + * @param[in] fifo_conf : Structure instance of bma5_fifo_conf. + * @param[in] dev : Structure instance of bma5_dev. + * + * return Status of API + */ +static int8_t get_fifo_full_16_bit_data(struct bma5_sens_fifo_axes_data_16_bit *fifo_accel_data, + struct bma5_fifo_frame fifoframe, + const struct bma5_fifo_conf *fifo_conf, + struct bma5_dev *dev); + +/*! + * @brief This internal API converts raw sensor values(LSB) to meters per seconds square. + * + * @param[in] val : Raw sensor value. + * @param[in] g_range : Accel Range selected (2G, 4G, 8G, 16G). + * @param[in] bit_width : Resolution of the sensor. + * + * @return Accel values in meters per second square. + * + */ +static float lsb_to_ms2(int16_t val, float g_range, uint8_t bit_width); + +/******************************************************************************/ +int main(void) +{ + struct bma5_dev dev; + int8_t rslt; + struct bma530_int_map int_map, get_int_map; + struct bma5_fifo_conf fifo_conf; + + /* Initialize FIFO frame structure */ + struct bma5_fifo_frame fifoframe = { 0 }; + enum bma5_context context; + + /* Assign context parameter selection */ + context = BMA5_SMARTPHONE; + + /* Interface reference is given as a parameter + * For I2C : BMA5_I2C_INTF + * For SPI : BMA5_SPI_INTF + */ + rslt = bma5_interface_init(&dev, BMA5_I2C_INTF, context); + bma5_check_rslt("bma5_interface_init", rslt); + + rslt = bma530_init(&dev); + bma5_check_rslt("bma530_init", rslt); + printf("BMA530 Chip ID is 0x%X\n", dev.chip_id); + + rslt = bma530_get_int_map(&int_map, &dev); + bma5_check_rslt("bma530_get_int_map", rslt); + + int_map.fifo_full_int_map = BMA530_FIFO_FULL_INT_MAP_INT2; + rslt = bma530_set_int_map(&int_map, &dev); + bma5_check_rslt("bma530_set_int_map", rslt); + + rslt = bma530_get_int_map(&get_int_map, &dev); + bma5_check_rslt("bma530_get_int_map", rslt); + + rslt = get_accel_and_int_settings(&dev); + bma5_check_rslt("get_accel_and_int_settings", rslt); + + /* Get FIFO configuration register */ + rslt = bma5_get_fifo_conf(&fifo_conf, &dev); + bma5_check_rslt("bma5_get_fifo_conf", rslt); + + rslt = bma5_get_fifo_conf(&fifo_conf, &dev); + bma5_check_rslt("bma5_get_fifo_conf", rslt); + + fifo_conf.fifo_cfg = BMA5_FIFO_CFG_ENABLE; + fifo_conf.fifo_acc_x = BMA5_FIFO_ACC_X_ENABLE; + fifo_conf.fifo_acc_y = BMA5_FIFO_ACC_Y_ENABLE; + fifo_conf.fifo_acc_z = BMA5_FIFO_ACC_Z_ENABLE; + fifo_conf.fifo_compression = BMA5_FIFO_COMPRESSION_ACC_16BIT; + fifo_conf.fifo_sensor_time = BMA5_FIFO_SENSOR_TIME_EACH_FRAME; + fifo_conf.fifo_size = BMA5_FIFO_SIZE_MAX_512_BYTES; + fifo_conf.fifo_stop_on_full = BMA5_ENABLE; + + rslt = get_fifo_conf(&fifo_conf, &dev); + bma5_check_rslt("get_fifo_conf", rslt); + + /* Update FIFO structure */ + fifoframe.data = fifo_data; + + rslt = get_fifo_full_16_bit_data(fifo_acc_data, fifoframe, &fifo_conf, &dev); + + bma5_coines_deinit(); + + return rslt; +} + +/*! + * @brief This internal API is used to enable accel and interrupt configuration settings. + */ +static int8_t get_accel_and_int_settings(struct bma5_dev *dev) +{ + int8_t rslt; + uint8_t n_ints = 1; + uint8_t sensor_ctrl; + struct bma5_acc_conf acc_cfg, get_acc_cfg; + struct bma5_int_conf_types int_config; + + int_config.int_src = BMA5_INT_2; + + /* Get accel configurations */ + rslt = bma5_get_acc_conf_0(&sensor_ctrl, dev); + bma5_check_rslt("bma5_get_acc_conf_0", rslt); + + rslt = bma5_get_acc_conf(&acc_cfg, dev); + bma5_check_rslt("bma5_get_acc_conf", rslt); + + /* Set accel configurations */ + acc_cfg.acc_odr = BMA5_ACC_ODR_HZ_6K4; + acc_cfg.acc_bwp = BMA5_ACC_BWP_NORM_AVG4; + acc_cfg.power_mode = BMA5_POWER_MODE_HPM; + + acc_cfg.acc_range = BMA5_ACC_RANGE_MAX_2G; + acc_cfg.acc_iir_ro = BMA5_ACC_IIR_RO_DB_60; + acc_cfg.noise_mode = BMA5_NOISE_MODE_LOWER_POWER; + acc_cfg.acc_drdy_int_auto_clear = BMA5_ACC_DRDY_INT_AUTO_CLEAR_DISABLED; + + rslt = bma5_set_acc_conf(&acc_cfg, dev); + bma5_check_rslt("bma5_get_acc_conf", rslt); + + /* Enable accel */ + sensor_ctrl = BMA5_SENSOR_CTRL_ENABLE; + + rslt = bma5_set_acc_conf_0(sensor_ctrl, dev); + bma5_check_rslt("bma5_set_acc_conf_0", rslt); + + rslt = bma5_get_acc_conf_0(&sensor_ctrl, dev); + bma5_check_rslt("bma5_set_acc_conf_0", rslt); + + rslt = bma5_get_acc_conf(&get_acc_cfg, dev); + bma5_check_rslt("bma5_get_acc_conf", rslt); + + printf("Sensor CTRL : %d\n", sensor_ctrl); + printf("ODR : %d\n", get_acc_cfg.acc_odr); + printf("BW : %d\n", get_acc_cfg.acc_bwp); + printf("Power mode : %d\n", get_acc_cfg.power_mode); + printf("Range : %d\n", get_acc_cfg.acc_range); + printf("IIR RO : %d\n", get_acc_cfg.acc_iir_ro); + printf("Noise mode : %d\n", get_acc_cfg.noise_mode); + printf("Auto Int clear : %d\n", get_acc_cfg.acc_drdy_int_auto_clear); + + rslt = bma5_get_int_conf(&int_config, n_ints, dev); + bma5_check_rslt("bma5_get_int_conf", rslt); + + int_config.int_conf.int_mode = BMA5_INT2_MODE_LATCHED; + int_config.int_conf.int_od = BMA5_INT2_OD_PUSH_PULL; + int_config.int_conf.int_lvl = BMA5_INT2_LVL_ACTIVE_HIGH; + + rslt = bma5_set_int_conf(&int_config, n_ints, dev); + bma5_check_rslt("bma5_set_int_conf", rslt); + + return rslt; +} + +/*! + * @brief This internal API gets FIFO configurations. + */ +static int8_t get_fifo_conf(const struct bma5_fifo_conf *fifo_conf, struct bma5_dev *dev) +{ + int8_t rslt; + struct bma5_fifo_conf read_fifo_conf = { 0 }; + + /* Set FIFO configuration. + * NOTE 1: FIFO works only on header mode */ + rslt = bma5_set_fifo_conf(fifo_conf, dev); + bma5_check_rslt("bma5_set_fifo_conf", rslt); + + printf("\nSet FIFO conf\n"); + printf("fifo en %d\n", fifo_conf->fifo_cfg); + printf("fifo_x_en %d\n", fifo_conf->fifo_acc_x); + printf("fifo_y_en %d\n", fifo_conf->fifo_acc_y); + printf("fifo_z_en %d\n", fifo_conf->fifo_acc_z); + printf("fifo_compression_en %d\n", fifo_conf->fifo_compression); + printf("fifo_sensor_time %d\n", fifo_conf->fifo_sensor_time); + printf("fifo_size %d\n", fifo_conf->fifo_size); + + /* Get FIFO configuration register */ + rslt = bma5_get_fifo_conf(&read_fifo_conf, dev); + bma5_check_rslt("bma5_get_fifo_conf", rslt); + + printf("\nGet FIFO conf\n"); + printf("fifo en %d\n", read_fifo_conf.fifo_cfg); + printf("fifo_x_en %d\n", read_fifo_conf.fifo_acc_x); + printf("fifo_y_en %d\n", read_fifo_conf.fifo_acc_y); + printf("fifo_z_en %d\n", read_fifo_conf.fifo_acc_z); + printf("fifo_compression_en %d\n", read_fifo_conf.fifo_compression); + printf("fifo_sensor_time %d\n", read_fifo_conf.fifo_sensor_time); + printf("fifo_size %d\n", read_fifo_conf.fifo_size); + + return rslt; +} + +/*! + * @brief This internal API gets FIFO 16 bit data with FIFO full interrupt. + */ +static int8_t get_fifo_full_16_bit_data(struct bma5_sens_fifo_axes_data_16_bit *fifo_accel_data, + struct bma5_fifo_frame fifoframe, + const struct bma5_fifo_conf *fifo_conf, + struct bma5_dev *dev) +{ + int8_t rslt = BMA5_OK; + uint8_t n_status = 1; + struct bma530_int_status_types int_status = { 0 }; + uint8_t loop = 0; + uint16_t idx = 0; + float x = 0, y = 0, z = 0; + + int_status.int_src = BMA530_INT_STATUS_INT2; + + printf("Get FIFO data"); + + while (loop < 3) + { + /* Get fifo full interrupt 2 status */ + rslt = bma530_get_int_status(&int_status, n_status, dev); + bma5_check_rslt("bma530_get_int_status", rslt); + + if (int_status.int_status.fifo_full_int_status & BMA5_ENABLE) + { + printf("\n\nIteration %d\n\n", loop); + + /* Read FIFO data */ + rslt = bma5_read_fifo_data(&fifoframe, fifo_conf, dev); + bma5_check_rslt("bma5_read_fifo_data", rslt); + + /* Set fifo full interrupt 2 status */ + rslt = bma530_set_int_status(&int_status, n_status, dev); + bma5_check_rslt("bma530_get_int_status\n", rslt); + + if (rslt == BMA5_OK) + { + /* Parse the FIFO data to extract accelerometer and sensortime data from the FIFO buffer */ + (void)bma5_extract_acc_sens_time_16_bit(fifo_accel_data, &fifoframe, fifo_conf, dev); + + printf( + "\nCount, Accel_LSB_X, Accel_LSB_Y, Accel_LSB_Z, Acc_ms2_X, Acc_ms2_Y, Acc_ms2_Z, Sensortime(S)\n"); + + /* Print the parsed accelerometer and sensortime data from the FIFO buffer */ + for (idx = 0; idx < fifoframe.fifo_avail_frames; idx++) + { + /* Converting lsb to meter per second squared for 16 bit resolution at 2G range */ + x = lsb_to_ms2(fifo_accel_data[idx].x, (float)2, BMA5_16_BIT_RESOLUTION); + y = lsb_to_ms2(fifo_accel_data[idx].y, (float)2, BMA5_16_BIT_RESOLUTION); + z = lsb_to_ms2(fifo_accel_data[idx].z, (float)2, BMA5_16_BIT_RESOLUTION); + + /* Print the data in m/s2 */ + printf("%d, %d, %d, %d, %4.2f, %4.2f, %4.2f, %.4lf s\n", + idx, + fifo_accel_data[idx].x, + fifo_accel_data[idx].y, + fifo_accel_data[idx].z, + x, + y, + z, + (fifo_accel_data[idx].sensor_time * SENSORTIME_RESOLUTION)); + } + + loop++; + } + } + } + + return rslt; +} + +/*! + * @brief This internal API converts raw sensor values(LSB) to meters per seconds square. + */ +static float lsb_to_ms2(int16_t val, float g_range, uint8_t bit_width) +{ + double power = 2; + + float half_scale = (float)((pow((double)power, (double)bit_width) / 2.0f)); + + return (GRAVITY_EARTH * val * g_range) / half_scale; +} diff --git a/examples/fifo_full_8_bit_dedicated_frame_comp_en/Makefile b/examples/fifo_full_8_bit_dedicated_frame_comp_en/Makefile new file mode 100644 index 0000000..8f7527b --- /dev/null +++ b/examples/fifo_full_8_bit_dedicated_frame_comp_en/Makefile @@ -0,0 +1,18 @@ +COINES_INSTALL_PATH ?= ../../../.. + +EXAMPLE_FILE ?= fifo_full_8_bit_dedicated_frame_comp_en.c + +API_LOCATION ?= ../.. +COMMON_LOCATION ?= .. + +C_SRCS += \ +$(API_LOCATION)/bma5.c \ +$(API_LOCATION)/bma530.c \ +$(API_LOCATION)/bma530_features.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/fifo_full_8_bit_dedicated_frame_comp_en/fifo_full_8_bit_dedicated_frame_comp_en.c b/examples/fifo_full_8_bit_dedicated_frame_comp_en/fifo_full_8_bit_dedicated_frame_comp_en.c new file mode 100644 index 0000000..aabf9b9 --- /dev/null +++ b/examples/fifo_full_8_bit_dedicated_frame_comp_en/fifo_full_8_bit_dedicated_frame_comp_en.c @@ -0,0 +1,374 @@ +/** + * Copyright (c) 2024 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. + * + */ + +#include +#include +#include "common.h" +#include "bma530_features.h" + +/******************************************************************************/ +/*! Macro definition */ + +/*! FIFO raw data buffer size */ +#define BMA530_FIFO_RAW_DATA_BUFFER_SIZE UINT16_C(660) + +/*! Number of accel frames to be extracted from FIFO + * + * Calculation: + * fifo_buffer = 660, accel_frame_len = 3 + * fifo_accel_frame_count = (660 / (3)) = 220 frames + * + * Note : + * Dedicated frame generates header on demand. + * Additional frames given to read sensortime frame + */ +#define ACCEL_FRAME_LEN UINT16_C(380) + +/*! Sensortime resolution in seconds */ +#define SENSORTIME_RESOLUTION (0.0003125f) + +/*! Earth's gravity in m/s^2 */ +#define GRAVITY_EARTH (9.80665f) + +/******************************************************************************/ +/*! Global Variables */ + +/*! Number of accel frames to be extracted from FIFO */ +uint16_t fifo_accel_frame_length = ACCEL_FRAME_LEN; + +/*! Number of bytes of FIFO data */ +uint8_t fifo_data[BMA530_FIFO_RAW_DATA_BUFFER_SIZE + BMA5_SENSORTIME_OVERHEAD_BYTE] = { 0 }; + +/*! Array of accelerometer and sensortime frames + * Array size same as fifo_accel_frame_length */ +struct bma5_sens_fifo_axes_data_8_bit fifo_acc_data[ACCEL_FRAME_LEN]; + +/******************************************************************************/ +/*! Static Function Declaration */ + +/*! + * @brief This internal API is used to enable accel and interrupt configuration settings. + * + * @param[in] dev : Structure instance of bma5_dev. + * + * return Status of API + */ +static int8_t get_accel_and_int_settings(struct bma5_dev *dev); + +/*! + * @brief This internal API gets FIFO configurations. + * + * @param[in, out] fifo_conf : Structure instance of bma5_fifo_conf. + * @param[in] dev : Structure instance of bma5_dev. + * + * return Status of API + */ +static int8_t get_fifo_conf(const struct bma5_fifo_conf *fifo_conf, struct bma5_dev *dev); + +/*! + * @brief This internal API gets FIFO 8 bit data with FIFO full interrupt. + * + * @param[in] accel_length : Store accel frame length. + * @param[in] fifo_accel_data : Structure instance of bma5_sens_fifo_axes_data_8_bit. + * @param[in] fifoframe : Structure instance of bma5_fifo_frame. + * @param[in] fifo_conf : Structure instance of bma5_fifo_conf. + * @param[in] dev : Structure instance of bma5_dev. + * + * return Status of API + */ +static int8_t get_fifo_full_8_bit_data(struct bma5_sens_fifo_axes_data_8_bit *fifo_accel_data, + struct bma5_fifo_frame fifoframe, + const struct bma5_fifo_conf *fifo_conf, + struct bma5_dev *dev); + +/*! + * @brief This internal API converts raw sensor values(LSB) to meters per seconds square. + * + * @param[in] val : Raw sensor value. + * @param[in] g_range : Accel Range selected (2G, 4G, 8G, 16G). + * @param[in] bit_width : Resolution of the sensor. + * + * @return Accel values in meters per second square. + * + */ +static float lsb_to_ms2(int16_t val, float g_range, uint8_t bit_width); + +/******************************************************************************/ +int main(void) +{ + struct bma5_dev dev; + int8_t rslt; + struct bma530_int_map int_map, get_int_map; + struct bma5_fifo_conf fifo_conf; + + /* Initialize FIFO frame structure */ + struct bma5_fifo_frame fifoframe = { 0 }; + + enum bma5_context context; + + /* Assign context parameter selection */ + context = BMA5_SMARTPHONE; + + /* Interface reference is given as a parameter + * For I2C : BMA5_I2C_INTF + * For SPI : BMA5_SPI_INTF + */ + rslt = bma5_interface_init(&dev, BMA5_I2C_INTF, context); + bma5_check_rslt("bma5_interface_init", rslt); + + rslt = bma530_init(&dev); + bma5_check_rslt("bma530_init", rslt); + printf("BMA530 Chip ID is 0x%X\n", dev.chip_id); + + rslt = bma530_get_int_map(&int_map, &dev); + bma5_check_rslt("bma530_get_int_map", rslt); + + int_map.fifo_full_int_map = BMA530_FIFO_FULL_INT_MAP_INT2; + rslt = bma530_set_int_map(&int_map, &dev); + bma5_check_rslt("bma530_set_int_map", rslt); + + rslt = bma530_get_int_map(&get_int_map, &dev); + bma5_check_rslt("bma530_get_int_map", rslt); + + rslt = get_accel_and_int_settings(&dev); + bma5_check_rslt("get_accel_and_int_settings", rslt); + + /* Get FIFO configuration register */ + rslt = bma5_get_fifo_conf(&fifo_conf, &dev); + bma5_check_rslt("bma5_get_fifo_conf", rslt); + + fifo_conf.fifo_cfg = BMA5_FIFO_CFG_ENABLE; + fifo_conf.fifo_acc_x = BMA5_FIFO_ACC_X_ENABLE; + fifo_conf.fifo_acc_y = BMA5_FIFO_ACC_Y_ENABLE; + fifo_conf.fifo_acc_z = BMA5_FIFO_ACC_Z_ENABLE; + fifo_conf.fifo_compression = BMA5_FIFO_COMPRESSION_ACC_8BIT; + fifo_conf.fifo_sensor_time = BMA5_FIFO_SENSOR_TIME_DEDICATED_FRAME; + fifo_conf.fifo_size = BMA5_FIFO_SIZE_MAX_512_BYTES; + fifo_conf.fifo_stop_on_full = BMA5_ENABLE; + + rslt = get_fifo_conf(&fifo_conf, &dev); + bma5_check_rslt("get_fifo_conf", rslt); + + /* Update FIFO structure */ + fifoframe.data = fifo_data; + + rslt = get_fifo_full_8_bit_data(fifo_acc_data, fifoframe, &fifo_conf, &dev); + + bma5_coines_deinit(); + + return rslt; +} + +/*! + * @brief This internal API is used to enable accel and interrupt configuration settings. + */ +static int8_t get_accel_and_int_settings(struct bma5_dev *dev) +{ + int8_t rslt; + uint8_t n_ints = 1; + uint8_t sensor_ctrl; + struct bma5_acc_conf acc_cfg, get_acc_cfg; + struct bma5_int_conf_types int_config; + + int_config.int_src = BMA5_INT_2; + + /* Get accel configurations */ + rslt = bma5_get_acc_conf_0(&sensor_ctrl, dev); + bma5_check_rslt("bma5_get_acc_conf_0", rslt); + + rslt = bma5_get_acc_conf(&acc_cfg, dev); + bma5_check_rslt("bma5_get_acc_conf", rslt); + + /* Set accel configurations */ + acc_cfg.acc_odr = BMA5_ACC_ODR_HZ_6K4; + acc_cfg.acc_bwp = BMA5_ACC_BWP_NORM_AVG4; + acc_cfg.power_mode = BMA5_POWER_MODE_HPM; + + acc_cfg.acc_range = BMA5_ACC_RANGE_MAX_2G; + acc_cfg.acc_iir_ro = BMA5_ACC_IIR_RO_DB_60; + acc_cfg.noise_mode = BMA5_NOISE_MODE_LOWER_POWER; + acc_cfg.acc_drdy_int_auto_clear = BMA5_ACC_DRDY_INT_AUTO_CLEAR_DISABLED; + + rslt = bma5_set_acc_conf(&acc_cfg, dev); + bma5_check_rslt("bma5_get_acc_conf", rslt); + + /* Enable accel */ + sensor_ctrl = BMA5_SENSOR_CTRL_ENABLE; + + rslt = bma5_set_acc_conf_0(sensor_ctrl, dev); + bma5_check_rslt("bma5_set_acc_conf_0", rslt); + + rslt = bma5_get_acc_conf_0(&sensor_ctrl, dev); + bma5_check_rslt("bma5_set_acc_conf_0", rslt); + + rslt = bma5_get_acc_conf(&get_acc_cfg, dev); + bma5_check_rslt("bma5_get_acc_conf", rslt); + + printf("Sensor CTRL : %d\n", sensor_ctrl); + printf("ODR : %d\n", get_acc_cfg.acc_odr); + printf("BW : %d\n", get_acc_cfg.acc_bwp); + printf("Power mode : %d\n", get_acc_cfg.power_mode); + printf("Range : %d\n", get_acc_cfg.acc_range); + printf("IIR RO : %d\n", get_acc_cfg.acc_iir_ro); + printf("Noise mode : %d\n", get_acc_cfg.noise_mode); + printf("Auto Int clear : %d\n", get_acc_cfg.acc_drdy_int_auto_clear); + + rslt = bma5_get_int_conf(&int_config, n_ints, dev); + bma5_check_rslt("bma5_get_int_conf", rslt); + + int_config.int_conf.int_mode = BMA5_INT2_MODE_LATCHED; + int_config.int_conf.int_od = BMA5_INT2_OD_PUSH_PULL; + int_config.int_conf.int_lvl = BMA5_INT2_LVL_ACTIVE_HIGH; + + rslt = bma5_set_int_conf(&int_config, n_ints, dev); + bma5_check_rslt("bma5_set_int_conf", rslt); + + return rslt; +} + +/*! + * @brief This internal API gets FIFO configurations. + */ +static int8_t get_fifo_conf(const struct bma5_fifo_conf *fifo_conf, struct bma5_dev *dev) +{ + int8_t rslt; + struct bma5_fifo_conf read_fifo_conf = { 0 }; + + /* Set FIFO configuration. + * NOTE 1: FIFO works only on header mode */ + rslt = bma5_set_fifo_conf(fifo_conf, dev); + bma5_check_rslt("bma5_set_fifo_conf", rslt); + + printf("\nSet FIFO conf\n"); + printf("fifo en %d\n", fifo_conf->fifo_cfg); + printf("fifo_x_en %d\n", fifo_conf->fifo_acc_x); + printf("fifo_y_en %d\n", fifo_conf->fifo_acc_y); + printf("fifo_z_en %d\n", fifo_conf->fifo_acc_z); + printf("fifo_compression_en %d\n", fifo_conf->fifo_compression); + printf("fifo_sensor_time %d\n", fifo_conf->fifo_sensor_time); + printf("fifo_size %d\n", fifo_conf->fifo_size); + + /* Get FIFO configuration register */ + rslt = bma5_get_fifo_conf(&read_fifo_conf, dev); + bma5_check_rslt("bma5_get_fifo_conf", rslt); + + printf("\nGet FIFO conf\n"); + printf("fifo en %d\n", read_fifo_conf.fifo_cfg); + printf("fifo_x_en %d\n", read_fifo_conf.fifo_acc_x); + printf("fifo_y_en %d\n", read_fifo_conf.fifo_acc_y); + printf("fifo_z_en %d\n", read_fifo_conf.fifo_acc_z); + printf("fifo_compression_en %d\n", read_fifo_conf.fifo_compression); + printf("fifo_sensor_time %d\n", read_fifo_conf.fifo_sensor_time); + printf("fifo_size %d\n", read_fifo_conf.fifo_size); + + return rslt; +} + +/*! + * @brief This internal API gets FIFO 8 bit data with FIFO full interrupt. + */ +static int8_t get_fifo_full_8_bit_data(struct bma5_sens_fifo_axes_data_8_bit *fifo_accel_data, + struct bma5_fifo_frame fifoframe, + const struct bma5_fifo_conf *fifo_conf, + struct bma5_dev *dev) +{ + int8_t rslt = BMA5_OK; + uint8_t n_status = 1; + struct bma530_int_status_types int_status = { 0 }; + uint8_t loop = 0; + uint16_t idx = 0; + float x = 0, y = 0, z = 0; + + int_status.int_src = BMA530_INT_STATUS_INT2; + + printf("Get FIFO data"); + + while (loop < 3) + { + /* Get fifo full interrupt 2 status */ + rslt = bma530_get_int_status(&int_status, n_status, dev); + bma5_check_rslt("bma530_get_int_status", rslt); + + if (int_status.int_status.fifo_full_int_status & BMA5_ENABLE) + { + printf("\n\nIteration %d\n\n", loop); + + /* Read FIFO data */ + rslt = bma5_read_fifo_data(&fifoframe, fifo_conf, dev); + bma5_check_rslt("bma5_read_fifo_data", rslt); + + rslt = bma530_set_int_status(&int_status, n_status, dev); + bma5_check_rslt("bma530_set_int_status", rslt); + + if (rslt == BMA5_OK) + { + /* Parse the FIFO data to extract accelerometer and sensortime data from the FIFO buffer */ + (void)bma5_extract_acc_sens_time_8_bit(fifo_accel_data, &fifoframe, fifo_conf, dev); + + printf("\nCount, Accel_LSB_X, Accel_LSB_Y, Accel_LSB_Z, Acc_ms2_X, Acc_ms2_Y, Acc_ms2_Z\n"); + + /* Print the parsed accelerometer and sensortime data from the FIFO buffer */ + for (idx = 0; idx < fifoframe.fifo_avail_frames; idx++) + { + /* Converting lsb to meter per second squared for 8 bit resolution at 2G range */ + x = lsb_to_ms2(fifo_accel_data[idx].x, (float)2, BMA5_8_BIT_RESOLUTION); + y = lsb_to_ms2(fifo_accel_data[idx].y, (float)2, BMA5_8_BIT_RESOLUTION); + z = lsb_to_ms2(fifo_accel_data[idx].z, (float)2, BMA5_8_BIT_RESOLUTION); + + /* Print the data in m/s2 */ + printf("%d, %d, %d, %d, %4.2f, %4.2f, %4.2f\n", idx, fifo_accel_data[idx].x, + fifo_accel_data[idx].y, fifo_accel_data[idx].z, x, y, z); + } + + printf("Sensor time(in seconds) = %.4lf s", fifo_accel_data[idx].sensor_time * SENSORTIME_RESOLUTION); + + loop++; + } + } + } + + return rslt; +} + +/*! + * @brief This internal API converts raw sensor values(LSB) to meters per seconds square. + */ +static float lsb_to_ms2(int16_t val, float g_range, uint8_t bit_width) +{ + double power = 2; + + float half_scale = (float)((pow((double)power, (double)bit_width) / 2.0f)); + + return (GRAVITY_EARTH * val * g_range) / half_scale; +} diff --git a/examples/fifo_full_8_bit_each_frame_comp_en/Makefile b/examples/fifo_full_8_bit_each_frame_comp_en/Makefile new file mode 100644 index 0000000..6fa974a --- /dev/null +++ b/examples/fifo_full_8_bit_each_frame_comp_en/Makefile @@ -0,0 +1,18 @@ +COINES_INSTALL_PATH ?= ../../../.. + +EXAMPLE_FILE ?= fifo_full_8_bit_each_frame_comp_en.c + +API_LOCATION ?= ../.. +COMMON_LOCATION ?= .. + +C_SRCS += \ +$(API_LOCATION)/bma5.c \ +$(API_LOCATION)/bma530.c \ +$(API_LOCATION)/bma530_features.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/fifo_full_8_bit_each_frame_comp_en/fifo_full_8_bit_each_frame_comp_en.c b/examples/fifo_full_8_bit_each_frame_comp_en/fifo_full_8_bit_each_frame_comp_en.c new file mode 100644 index 0000000..2f742f8 --- /dev/null +++ b/examples/fifo_full_8_bit_each_frame_comp_en/fifo_full_8_bit_each_frame_comp_en.c @@ -0,0 +1,377 @@ +/** + * Copyright (c) 2024 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. + * + */ + +#include +#include +#include "common.h" +#include "bma530_features.h" + +/******************************************************************************/ +/*! Macro definition */ + +/*! FIFO raw data buffer size */ +#define BMA530_FIFO_RAW_DATA_BUFFER_SIZE UINT16_C(520) + +/* Number of accel frames to be extracted from FIFO + * Calculation: + * fifo_buffer = 520, accel_frame_len = 3, header_byte = 1, sensortime = 3. + * fifo_accel_frame_count = (520 / (3 + 1 + 3)) = 74 frames + * + * Additional frames given to test FIFO on higher ODRs. + */ +#define ACCEL_FRAME_LEN UINT16_C(380) + +/*! Sensortime resolution in seconds */ +#define SENSORTIME_RESOLUTION (0.0003125f) + +/*! Earth's gravity in m/s^2 */ +#define GRAVITY_EARTH (9.80665f) + +/******************************************************************************/ +/*! Global Variables */ + +/*! Number of accel frames to be extracted from FIFO */ +uint16_t fifo_accel_frame_length = ACCEL_FRAME_LEN; + +/*! Number of bytes of FIFO data */ +uint8_t fifo_data[BMA530_FIFO_RAW_DATA_BUFFER_SIZE] = { 0 }; + +/*! Array of accelerometer and sensortime frames + * Array size same as fifo_accel_frame_length */ +struct bma5_sens_fifo_axes_data_8_bit fifo_acc_data[ACCEL_FRAME_LEN]; + +/******************************************************************************/ +/*! Static Function Declaration */ + +/*! + * @brief This internal API is used to enable accel and interrupt configuration settings. + * + * @param[in] dev : Structure instance of bma5_dev. + * + * return Status of API + */ +static int8_t get_accel_and_int_settings(struct bma5_dev *dev); + +/*! + * @brief This internal API gets FIFO configurations. + * + * @param[in, out] fifo_conf : Structure instance of bma5_fifo_conf. + * @param[in] dev : Structure instance of bma5_dev. + * + * return Status of API + */ +static int8_t get_fifo_conf(const struct bma5_fifo_conf *fifo_conf, struct bma5_dev *dev); + +/*! + * @brief This internal API gets FIFO 8 bit data with FIFO full interrupt. + * + * @param[in] accel_length : Store accel frame length. + * @param[in] fifo_accel_data : Structure instance of bma5_sens_fifo_axes_data_8_bit. + * @param[in] fifoframe : Structure instance of bma5_fifo_frame. + * @param[in] fifo_conf : Structure instance of bma5_fifo_conf. + * @param[in] dev : Structure instance of bma5_dev. + * + * return Status of API + */ +static int8_t get_fifo_full_8_bit_data(struct bma5_sens_fifo_axes_data_8_bit *fifo_accel_data, + struct bma5_fifo_frame fifoframe, + const struct bma5_fifo_conf *fifo_conf, + struct bma5_dev *dev); + +/*! + * @brief This internal API converts raw sensor values(LSB) to meters per seconds square. + * + * @param[in] val : Raw sensor value. + * @param[in] g_range : Accel Range selected (2G, 4G, 8G, 16G). + * @param[in] bit_width : Resolution of the sensor. + * + * @return Accel values in meters per second square. + * + */ +static float lsb_to_ms2(int16_t val, float g_range, uint8_t bit_width); + +/******************************************************************************/ +int main(void) +{ + struct bma5_dev dev; + int8_t rslt; + struct bma530_int_map int_map, get_int_map; + struct bma5_fifo_conf fifo_conf; + + /* Initialize FIFO frame structure */ + struct bma5_fifo_frame fifoframe = { 0 }; + + enum bma5_context context; + + /* Assign context parameter selection */ + context = BMA5_SMARTPHONE; + + /* Interface reference is given as a parameter + * For I2C : BMA5_I2C_INTF + * For SPI : BMA5_SPI_INTF + */ + rslt = bma5_interface_init(&dev, BMA5_SPI_INTF, context); + bma5_check_rslt("bma5_interface_init", rslt); + + rslt = bma530_init(&dev); + bma5_check_rslt("bma530_init", rslt); + printf("BMA530 Chip ID is 0x%X\n", dev.chip_id); + + rslt = bma530_get_int_map(&int_map, &dev); + bma5_check_rslt("bma530_get_int_map", rslt); + + int_map.fifo_full_int_map = BMA530_FIFO_FULL_INT_MAP_INT1; + rslt = bma530_set_int_map(&int_map, &dev); + bma5_check_rslt("bma530_set_int_map", rslt); + + rslt = bma530_get_int_map(&get_int_map, &dev); + bma5_check_rslt("bma530_get_int_map", rslt); + + rslt = get_accel_and_int_settings(&dev); + bma5_check_rslt("get_accel_and_int_settings", rslt); + + /* Get FIFO configuration register */ + rslt = bma5_get_fifo_conf(&fifo_conf, &dev); + bma5_check_rslt("bma5_get_fifo_conf", rslt); + + fifo_conf.fifo_cfg = BMA5_FIFO_CFG_ENABLE; + fifo_conf.fifo_acc_x = BMA5_FIFO_ACC_X_ENABLE; + fifo_conf.fifo_acc_y = BMA5_FIFO_ACC_Y_ENABLE; + fifo_conf.fifo_acc_z = BMA5_FIFO_ACC_Z_ENABLE; + fifo_conf.fifo_compression = BMA5_FIFO_COMPRESSION_ACC_8BIT; + fifo_conf.fifo_sensor_time = BMA5_FIFO_SENSOR_TIME_EACH_FRAME; + fifo_conf.fifo_size = BMA5_FIFO_SIZE_MAX_512_BYTES; + fifo_conf.fifo_stop_on_full = BMA5_ENABLE; + + rslt = get_fifo_conf(&fifo_conf, &dev); + bma5_check_rslt("get_fifo_conf", rslt); + + /* Update FIFO structure */ + fifoframe.data = fifo_data; + + rslt = get_fifo_full_8_bit_data(fifo_acc_data, fifoframe, &fifo_conf, &dev); + + bma5_coines_deinit(); + + return rslt; +} + +/*! + * @brief This internal API is used to enable accel and interrupt configuration settings. + */ +static int8_t get_accel_and_int_settings(struct bma5_dev *dev) +{ + int8_t rslt; + uint8_t n_ints = 1; + uint8_t sensor_ctrl; + struct bma5_acc_conf acc_cfg, get_acc_cfg; + struct bma5_int_conf_types int_config; + + int_config.int_src = BMA5_INT_1; + + /* Get accel configurations */ + rslt = bma5_get_acc_conf_0(&sensor_ctrl, dev); + bma5_check_rslt("bma5_get_acc_conf_0", rslt); + + rslt = bma5_get_acc_conf(&acc_cfg, dev); + bma5_check_rslt("bma5_get_acc_conf", rslt); + + /* Set accel configurations */ + acc_cfg.acc_odr = BMA5_ACC_ODR_HZ_6K4; + acc_cfg.acc_bwp = BMA5_ACC_BWP_NORM_AVG4; + acc_cfg.power_mode = BMA5_POWER_MODE_HPM; + + acc_cfg.acc_range = BMA5_ACC_RANGE_MAX_2G; + acc_cfg.acc_iir_ro = BMA5_ACC_IIR_RO_DB_60; + acc_cfg.noise_mode = BMA5_NOISE_MODE_LOWER_POWER; + acc_cfg.acc_drdy_int_auto_clear = BMA5_ACC_DRDY_INT_AUTO_CLEAR_DISABLED; + + rslt = bma5_set_acc_conf(&acc_cfg, dev); + bma5_check_rslt("bma5_get_acc_conf", rslt); + + /* Enable accel */ + sensor_ctrl = BMA5_SENSOR_CTRL_ENABLE; + + rslt = bma5_set_acc_conf_0(sensor_ctrl, dev); + bma5_check_rslt("bma5_set_acc_conf_0", rslt); + + rslt = bma5_get_acc_conf_0(&sensor_ctrl, dev); + bma5_check_rslt("bma5_set_acc_conf_0", rslt); + + rslt = bma5_get_acc_conf(&get_acc_cfg, dev); + bma5_check_rslt("bma5_get_acc_conf", rslt); + + printf("Sensor CTRL : %d\n", sensor_ctrl); + printf("ODR : %d\n", get_acc_cfg.acc_odr); + printf("BW : %d\n", get_acc_cfg.acc_bwp); + printf("Power mode : %d\n", get_acc_cfg.power_mode); + printf("Range : %d\n", get_acc_cfg.acc_range); + printf("IIR RO : %d\n", get_acc_cfg.acc_iir_ro); + printf("Noise mode : %d\n", get_acc_cfg.noise_mode); + printf("Auto Int clear : %d\n", get_acc_cfg.acc_drdy_int_auto_clear); + + rslt = bma5_get_int_conf(&int_config, n_ints, dev); + bma5_check_rslt("bma5_get_int_conf", rslt); + + int_config.int_conf.int_mode = BMA5_INT1_MODE_LATCHED; + int_config.int_conf.int_od = BMA5_INT1_OD_PUSH_PULL; + int_config.int_conf.int_lvl = BMA5_INT1_LVL_ACTIVE_HIGH; + + rslt = bma5_set_int_conf(&int_config, n_ints, dev); + bma5_check_rslt("bma5_set_int_conf", rslt); + + return rslt; +} + +/*! + * @brief This internal API gets FIFO configurations. + */ +static int8_t get_fifo_conf(const struct bma5_fifo_conf *fifo_conf, struct bma5_dev *dev) +{ + int8_t rslt; + struct bma5_fifo_conf read_fifo_conf = { 0 }; + + /* Set FIFO configuration. + * NOTE 1: FIFO works only on header mode */ + rslt = bma5_set_fifo_conf(fifo_conf, dev); + bma5_check_rslt("bma5_set_fifo_conf", rslt); + + printf("\nSet FIFO conf\n"); + printf("fifo en %d\n", fifo_conf->fifo_cfg); + printf("fifo_x_en %d\n", fifo_conf->fifo_acc_x); + printf("fifo_y_en %d\n", fifo_conf->fifo_acc_y); + printf("fifo_z_en %d\n", fifo_conf->fifo_acc_z); + printf("fifo_compression_en %d\n", fifo_conf->fifo_compression); + printf("fifo_sensor_time %d\n", fifo_conf->fifo_sensor_time); + printf("fifo_size %d\n", fifo_conf->fifo_size); + + /* Get FIFO configuration register */ + rslt = bma5_get_fifo_conf(&read_fifo_conf, dev); + bma5_check_rslt("bma5_get_fifo_conf", rslt); + + printf("\nGet FIFO conf\n"); + printf("fifo en %d\n", read_fifo_conf.fifo_cfg); + printf("fifo_x_en %d\n", read_fifo_conf.fifo_acc_x); + printf("fifo_y_en %d\n", read_fifo_conf.fifo_acc_y); + printf("fifo_z_en %d\n", read_fifo_conf.fifo_acc_z); + printf("fifo_compression_en %d\n", read_fifo_conf.fifo_compression); + printf("fifo_sensor_time %d\n", read_fifo_conf.fifo_sensor_time); + printf("fifo_size %d\n", read_fifo_conf.fifo_size); + + return rslt; +} + +/*! + * @brief This internal API gets FIFO 8 bit data with FIFO full interrupt. + */ +static int8_t get_fifo_full_8_bit_data(struct bma5_sens_fifo_axes_data_8_bit *fifo_accel_data, + struct bma5_fifo_frame fifoframe, + const struct bma5_fifo_conf *fifo_conf, + struct bma5_dev *dev) +{ + int8_t rslt = BMA5_OK; + uint8_t n_status = 1; + struct bma530_int_status_types int_status = { 0 }; + uint8_t loop = 0; + uint16_t idx = 0; + float x = 0, y = 0, z = 0; + + int_status.int_src = BMA530_INT_STATUS_INT1; + + printf("Get FIFO data"); + + while (loop < 3) + { + /* Get fifo full interrupt 2 status */ + rslt = bma530_get_int_status(&int_status, n_status, dev); + bma5_check_rslt("bma530_get_int_status", rslt); + + if (int_status.int_status.fifo_full_int_status & BMA5_ENABLE) + { + printf("\n\nIteration %d\n\n", loop); + + /* Read FIFO data */ + rslt = bma5_read_fifo_data(&fifoframe, fifo_conf, dev); + bma5_check_rslt("bma5_read_fifo_data", rslt); + + rslt = bma530_set_int_status(&int_status, n_status, dev); + bma5_check_rslt("bma530_set_int_status", rslt); + + if (rslt == BMA5_OK) + { + /* Parse the FIFO data to extract accelerometer and sensortime data from the FIFO buffer */ + (void)bma5_extract_acc_sens_time_8_bit(fifo_accel_data, &fifoframe, fifo_conf, dev); + + printf( + "\nCount, Accel_LSB_X, Accel_LSB_Y, Accel_LSB_Z, Acc_ms2_X, Acc_ms2_Y, Acc_ms2_Z, Sensortime(s)\n"); + + /* Print the parsed accelerometer and sensortime data from the FIFO buffer */ + for (idx = 0; idx < fifoframe.fifo_avail_frames; idx++) + { + /* Converting lsb to meter per second squared for 8 bit resolution at 2G range */ + x = lsb_to_ms2(fifo_accel_data[idx].x, (float)2, BMA5_8_BIT_RESOLUTION); + y = lsb_to_ms2(fifo_accel_data[idx].y, (float)2, BMA5_8_BIT_RESOLUTION); + z = lsb_to_ms2(fifo_accel_data[idx].z, (float)2, BMA5_8_BIT_RESOLUTION); + + /* Print the data in m/s2 */ + printf("%d, %d, %d, %d, %4.2f, %4.2f, %4.2f, %.4lf s\n", + idx, + fifo_accel_data[idx].x, + fifo_accel_data[idx].y, + fifo_accel_data[idx].z, + x, + y, + z, + (fifo_accel_data[idx].sensor_time * SENSORTIME_RESOLUTION)); + } + + loop++; + } + } + } + + return rslt; +} + +/*! + * @brief This internal API converts raw sensor values(LSB) to meters per seconds square. + */ +static float lsb_to_ms2(int16_t val, float g_range, uint8_t bit_width) +{ + double power = 2; + + float half_scale = (float)((pow((double)power, (double)bit_width) / 2.0f)); + + return (GRAVITY_EARTH * val * g_range) / half_scale; +} diff --git a/examples/fifo_wm_16_bit_dedicated_frame_comp_dis/Makefile b/examples/fifo_wm_16_bit_dedicated_frame_comp_dis/Makefile new file mode 100644 index 0000000..3ebef23 --- /dev/null +++ b/examples/fifo_wm_16_bit_dedicated_frame_comp_dis/Makefile @@ -0,0 +1,18 @@ +COINES_INSTALL_PATH ?= ../../../.. + +EXAMPLE_FILE ?= fifo_wm_16_bit_dedicated_frame_comp_dis.c + +API_LOCATION ?= ../.. +COMMON_LOCATION ?= .. + +C_SRCS += \ +$(API_LOCATION)/bma5.c \ +$(API_LOCATION)/bma530.c \ +$(API_LOCATION)/bma530_features.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/fifo_wm_16_bit_dedicated_frame_comp_dis/fifo_wm_16_bit_dedicated_frame_comp_dis.c b/examples/fifo_wm_16_bit_dedicated_frame_comp_dis/fifo_wm_16_bit_dedicated_frame_comp_dis.c new file mode 100644 index 0000000..975c8c1 --- /dev/null +++ b/examples/fifo_wm_16_bit_dedicated_frame_comp_dis/fifo_wm_16_bit_dedicated_frame_comp_dis.c @@ -0,0 +1,386 @@ +/** + * Copyright (c) 2024 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. + * + */ + +#include +#include +#include "common.h" +#include "bma530_features.h" + +/******************************************************************************/ +/*! Macro definition */ + +/*! FIFO raw data buffer size */ +#define BMA530_FIFO_RAW_DATA_BUFFER_SIZE UINT16_C(520) + +/*! Number of accel frames to be extracted from FIFO + * + * Calculation: + * fifo_watermark_level = 300, accel_frame_len = 6 + * fifo_accel_frame_count = (300 / (6)) = 50 frames + * + * Note : + * Dedicated frame generates header on demand. + * Additional frames given to read sensortime frame + */ +#define ACCEL_FRAME_LEN UINT8_C(255) + +/*! FIFO watermark level */ +#define WATERMARK_LEVEL UINT16_C(300) + +/*! Sensortime resolution in seconds */ +#define SENSORTIME_RESOLUTION (0.0003125f) + +/*! Earth's gravity in m/s^2 */ +#define GRAVITY_EARTH (9.80665f) + +/******************************************************************************/ +/*! Global Variables */ + +/*! Number of accel frames to be extracted from FIFO */ +uint8_t fifo_accel_frame_length = ACCEL_FRAME_LEN; + +/*! Number of bytes of FIFO data */ +uint8_t fifo_data[BMA530_FIFO_RAW_DATA_BUFFER_SIZE + BMA5_SENSORTIME_OVERHEAD_BYTE] = { 0 }; + +/*! Array of accelerometer and sensortime frames + * Array size same as fifo_accel_frame_length */ +struct bma5_sens_fifo_axes_data_16_bit fifo_acc_data[ACCEL_FRAME_LEN]; + +/******************************************************************************/ +/*! Static Function Declaration */ + +/*! + * @brief This internal API is used to enable accel and interrupt configuration settings. + * + * @param[in] dev : Structure instance of bma5_dev. + * + * return Status of API + */ +static int8_t get_accel_and_int_settings(struct bma5_dev *dev); + +/*! + * @brief This internal API gets FIFO configurations. + * + * @param[in, out] fifo_conf : Structure instance of bma5_fifo_conf. + * @param[in] dev : Structure instance of bma5_dev. + * + * return Status of API + */ +static int8_t get_fifo_conf(const struct bma5_fifo_conf *fifo_conf, struct bma5_dev *dev); + +/*! + * @brief This internal API gets FIFO 16 bit data with FIFO full interrupt. + * + * @param[in] accel_length : Store accel frame length. + * @param[in] fifo_accel_data : Structure instance of bma5_sens_fifo_axes_data_8_bit. + * @param[in] fifoframe : Structure instance of bma5_fifo_frame. + * @param[in] fifo_conf : Structure instance of bma5_fifo_conf. + * @param[in] dev : Structure instance of bma5_dev. + * + * return Status of API + */ +static int8_t get_fifo_full_16_bit_data(struct bma5_sens_fifo_axes_data_16_bit *fifo_accel_data, + struct bma5_fifo_frame fifoframe, + const struct bma5_fifo_conf *fifo_conf, + struct bma5_dev *dev); + +/*! + * @brief This internal API converts raw sensor values(LSB) to meters per seconds square. + * + * @param[in] val : Raw sensor value. + * @param[in] g_range : Accel Range selected (2G, 4G, 8G, 16G). + * @param[in] bit_width : Resolution of the sensor. + * + * @return Accel values in meters per second square. + * + */ +static float lsb_to_ms2(int16_t val, float g_range, uint8_t bit_width); + +/******************************************************************************/ +int main(void) +{ + struct bma5_dev dev; + int8_t rslt; + struct bma530_int_map int_map, get_int_map; + struct bma5_fifo_conf fifo_conf; + + /* Initialize FIFO frame structure */ + struct bma5_fifo_frame fifoframe = { 0 }; + enum bma5_context context; + + /* Set FIFO water-mark level */ + uint16_t fifo_watermark_level = WATERMARK_LEVEL; + + /* Assign context parameter selection */ + context = BMA5_SMARTPHONE; + + /* Interface reference is given as a parameter + * For I2C : BMA5_I2C_INTF + * For SPI : BMA5_SPI_INTF + */ + rslt = bma5_interface_init(&dev, BMA5_SPI_INTF, context); + bma5_check_rslt("bma5_interface_init", rslt); + + rslt = bma530_init(&dev); + bma5_check_rslt("bma530_init", rslt); + printf("BMA530 Chip ID is 0x%X\n", dev.chip_id); + + rslt = bma530_get_int_map(&int_map, &dev); + bma5_check_rslt("bma530_get_int_map", rslt); + + int_map.fifo_full_int_map = BMA530_FIFO_FULL_INT_MAP_INT2; + rslt = bma530_set_int_map(&int_map, &dev); + bma5_check_rslt("bma530_set_int_map", rslt); + + rslt = bma530_get_int_map(&get_int_map, &dev); + bma5_check_rslt("bma530_get_int_map", rslt); + + rslt = get_accel_and_int_settings(&dev); + bma5_check_rslt("get_accel_and_int_settings", rslt); + + /* Get FIFO configuration register */ + rslt = bma5_get_fifo_conf(&fifo_conf, &dev); + bma5_check_rslt("bma5_get_fifo_conf", rslt); + + rslt = bma5_get_fifo_conf(&fifo_conf, &dev); + bma5_check_rslt("bma5_get_fifo_conf", rslt); + + fifo_conf.fifo_cfg = BMA5_FIFO_CFG_ENABLE; + fifo_conf.fifo_acc_x = BMA5_FIFO_ACC_X_ENABLE; + fifo_conf.fifo_acc_y = BMA5_FIFO_ACC_Y_ENABLE; + fifo_conf.fifo_acc_z = BMA5_FIFO_ACC_Z_ENABLE; + fifo_conf.fifo_compression = BMA5_FIFO_COMPRESSION_ACC_16BIT; + fifo_conf.fifo_sensor_time = BMA5_FIFO_SENSOR_TIME_DEDICATED_FRAME; + fifo_conf.fifo_size = BMA5_FIFO_SIZE_MAX_512_BYTES; + fifo_conf.fifo_stop_on_full = BMA5_ENABLE; + + rslt = get_fifo_conf(&fifo_conf, &dev); + bma5_check_rslt("get_fifo_conf", rslt); + + /* Update FIFO structure */ + fifoframe.data = fifo_data; + + rslt = bma5_set_fifo_wm(fifo_watermark_level, &dev); + bma5_check_rslt("bma5_set_fifo_wm", rslt); + + rslt = get_fifo_full_16_bit_data(fifo_acc_data, fifoframe, &fifo_conf, &dev); + + bma5_coines_deinit(); + + return rslt; +} + +/*! + * @brief This internal API is used to enable accel and interrupt configuration settings. + */ +static int8_t get_accel_and_int_settings(struct bma5_dev *dev) +{ + int8_t rslt; + uint8_t n_ints = 1; + uint8_t sensor_ctrl; + struct bma5_acc_conf acc_cfg, get_acc_cfg; + struct bma5_int_conf_types int_config; + + int_config.int_src = BMA5_INT_2; + + /* Get accel configurations */ + rslt = bma5_get_acc_conf_0(&sensor_ctrl, dev); + bma5_check_rslt("bma5_get_acc_conf_0", rslt); + + rslt = bma5_get_acc_conf(&acc_cfg, dev); + bma5_check_rslt("bma5_get_acc_conf", rslt); + + /* Set accel configurations */ + acc_cfg.acc_odr = BMA5_ACC_ODR_HZ_6K4; + acc_cfg.acc_bwp = BMA5_ACC_BWP_NORM_AVG4; + acc_cfg.power_mode = BMA5_POWER_MODE_HPM; + + acc_cfg.acc_range = BMA5_ACC_RANGE_MAX_2G; + acc_cfg.acc_iir_ro = BMA5_ACC_IIR_RO_DB_60; + acc_cfg.noise_mode = BMA5_NOISE_MODE_LOWER_POWER; + acc_cfg.acc_drdy_int_auto_clear = BMA5_ACC_DRDY_INT_AUTO_CLEAR_DISABLED; + + rslt = bma5_set_acc_conf(&acc_cfg, dev); + bma5_check_rslt("bma5_get_acc_conf", rslt); + + /* Enable accel */ + sensor_ctrl = BMA5_SENSOR_CTRL_ENABLE; + + rslt = bma5_set_acc_conf_0(sensor_ctrl, dev); + bma5_check_rslt("bma5_set_acc_conf_0", rslt); + + rslt = bma5_get_acc_conf_0(&sensor_ctrl, dev); + bma5_check_rslt("bma5_set_acc_conf_0", rslt); + + rslt = bma5_get_acc_conf(&get_acc_cfg, dev); + bma5_check_rslt("bma5_get_acc_conf", rslt); + + printf("Sensor CTRL : %d\n", sensor_ctrl); + printf("ODR : %d\n", get_acc_cfg.acc_odr); + printf("BW : %d\n", get_acc_cfg.acc_bwp); + printf("Power mode : %d\n", get_acc_cfg.power_mode); + printf("Range : %d\n", get_acc_cfg.acc_range); + printf("IIR RO : %d\n", get_acc_cfg.acc_iir_ro); + printf("Noise mode : %d\n", get_acc_cfg.noise_mode); + printf("Auto Int clear : %d\n", get_acc_cfg.acc_drdy_int_auto_clear); + + rslt = bma5_get_int_conf(&int_config, n_ints, dev); + bma5_check_rslt("bma5_get_int_conf", rslt); + + int_config.int_conf.int_mode = BMA5_INT2_MODE_LATCHED; + int_config.int_conf.int_od = BMA5_INT2_OD_PUSH_PULL; + int_config.int_conf.int_lvl = BMA5_INT2_LVL_ACTIVE_HIGH; + + rslt = bma5_set_int_conf(&int_config, n_ints, dev); + bma5_check_rslt("bma5_set_int_conf", rslt); + + return rslt; +} + +/*! + * @brief This internal API gets FIFO configurations. + */ +static int8_t get_fifo_conf(const struct bma5_fifo_conf *fifo_conf, struct bma5_dev *dev) +{ + int8_t rslt; + struct bma5_fifo_conf read_fifo_conf = { 0 }; + + /* Set FIFO configuration. + * NOTE 1: FIFO works only on header mode */ + rslt = bma5_set_fifo_conf(fifo_conf, dev); + bma5_check_rslt("bma5_set_fifo_conf", rslt); + + printf("\nSet FIFO conf\n"); + printf("fifo en %d\n", fifo_conf->fifo_cfg); + printf("fifo_x_en %d\n", fifo_conf->fifo_acc_x); + printf("fifo_y_en %d\n", fifo_conf->fifo_acc_y); + printf("fifo_z_en %d\n", fifo_conf->fifo_acc_z); + printf("fifo_compression_en %d\n", fifo_conf->fifo_compression); + printf("fifo_sensor_time %d\n", fifo_conf->fifo_sensor_time); + printf("fifo_size %d\n", fifo_conf->fifo_size); + + /* Get FIFO configuration register */ + rslt = bma5_get_fifo_conf(&read_fifo_conf, dev); + bma5_check_rslt("bma5_get_fifo_conf", rslt); + + printf("\nGet FIFO conf\n"); + printf("fifo en %d\n", read_fifo_conf.fifo_cfg); + printf("fifo_x_en %d\n", read_fifo_conf.fifo_acc_x); + printf("fifo_y_en %d\n", read_fifo_conf.fifo_acc_y); + printf("fifo_z_en %d\n", read_fifo_conf.fifo_acc_z); + printf("fifo_compression_en %d\n", read_fifo_conf.fifo_compression); + printf("fifo_sensor_time %d\n", read_fifo_conf.fifo_sensor_time); + printf("fifo_size %d\n", read_fifo_conf.fifo_size); + + return rslt; +} + +/*! + * @brief This internal API gets FIFO 16 bit data with FIFO watermark interrupt. + */ +static int8_t get_fifo_full_16_bit_data(struct bma5_sens_fifo_axes_data_16_bit *fifo_accel_data, + struct bma5_fifo_frame fifoframe, + const struct bma5_fifo_conf *fifo_conf, + struct bma5_dev *dev) +{ + int8_t rslt = BMA5_OK; + uint8_t n_status = 1; + struct bma530_int_status_types int_status = { 0 }; + uint8_t loop = 0; + uint16_t idx = 0; + float x = 0, y = 0, z = 0; + + int_status.int_src = BMA530_INT_STATUS_INT2; + + printf("Get FIFO data"); + + while (loop < 3) + { + /* Get fifo full interrupt 2 status */ + rslt = bma530_get_int_status(&int_status, n_status, dev); + bma5_check_rslt("bma530_get_int_status", rslt); + + if (int_status.int_status.fifo_full_int_status & BMA5_ENABLE) + { + printf("\n\nIteration %d\n\n", loop); + + /* Read FIFO data */ + rslt = bma5_read_fifo_data(&fifoframe, fifo_conf, dev); + bma5_check_rslt("bma5_read_fifo_data", rslt); + + /* Set fifo full interrupt 2 status */ + rslt = bma530_set_int_status(&int_status, n_status, dev); + bma5_check_rslt("bma530_get_int_status\n", rslt); + + if (rslt == BMA5_OK) + { + /* Parse the FIFO data to extract accelerometer and sensortime data from the FIFO buffer */ + (void)bma5_extract_acc_sens_time_16_bit(fifo_accel_data, &fifoframe, fifo_conf, dev); + + printf("\nCount, Accel_LSB_X, Accel_LSB_Y, Accel_LSB_Z, Acc_ms2_X, Acc_ms2_Y, Acc_ms2_Z\n"); + + /* Print the parsed accelerometer and sensortime data from the FIFO buffer */ + for (idx = 0; idx < fifoframe.fifo_avail_frames; idx++) + { + /* Converting lsb to meter per second squared for 16 bit resolution at 2G range */ + x = lsb_to_ms2(fifo_accel_data[idx].x, (float)2, BMA5_16_BIT_RESOLUTION); + y = lsb_to_ms2(fifo_accel_data[idx].y, (float)2, BMA5_16_BIT_RESOLUTION); + z = lsb_to_ms2(fifo_accel_data[idx].z, (float)2, BMA5_16_BIT_RESOLUTION); + + /* Print the data in m/s2 */ + printf("%d, %d, %d, %d, %4.2f, %4.2f, %4.2f\n", idx, fifo_accel_data[idx].x, + fifo_accel_data[idx].y, fifo_accel_data[idx].z, x, y, z); + } + + printf("Sensor time(in seconds) = %.4lf s", fifo_accel_data[idx].sensor_time * SENSORTIME_RESOLUTION); + + loop++; + } + } + } + + return rslt; +} + +/*! + * @brief This internal API converts raw sensor values(LSB) to meters per seconds square. + */ +static float lsb_to_ms2(int16_t val, float g_range, uint8_t bit_width) +{ + double power = 2; + + float half_scale = (float)((pow((double)power, (double)bit_width) / 2.0f)); + + return (GRAVITY_EARTH * val * g_range) / half_scale; +} diff --git a/examples/fifo_wm_16_bit_each_frame_comp_dis/Makefile b/examples/fifo_wm_16_bit_each_frame_comp_dis/Makefile new file mode 100644 index 0000000..7f2cbab --- /dev/null +++ b/examples/fifo_wm_16_bit_each_frame_comp_dis/Makefile @@ -0,0 +1,18 @@ +COINES_INSTALL_PATH ?= ../../../.. + +EXAMPLE_FILE ?= fifo_wm_16_bit_each_frame_comp_dis.c + +API_LOCATION ?= ../.. +COMMON_LOCATION ?= .. + +C_SRCS += \ +$(API_LOCATION)/bma5.c \ +$(API_LOCATION)/bma530.c \ +$(API_LOCATION)/bma530_features.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/fifo_wm_16_bit_each_frame_comp_dis/fifo_wm_16_bit_each_frame_comp_dis.c b/examples/fifo_wm_16_bit_each_frame_comp_dis/fifo_wm_16_bit_each_frame_comp_dis.c new file mode 100644 index 0000000..c78dec7 --- /dev/null +++ b/examples/fifo_wm_16_bit_each_frame_comp_dis/fifo_wm_16_bit_each_frame_comp_dis.c @@ -0,0 +1,389 @@ +/** + * Copyright (c) 2024 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. + * + */ + +#include +#include +#include "common.h" +#include "bma530_features.h" + +/******************************************************************************/ +/*! Macro definition */ + +/*! FIFO raw data buffer size */ +#define BMA530_FIFO_RAW_DATA_BUFFER_SIZE UINT16_C(520) + +/*! Number of accel frames to be extracted from FIFO + * Calculation: + * fifo_watermark_level = 300, accel_frame_len = 6, header_byte = 1, sensortime = 3. + * fifo_accel_frame_count = (300 / (6 + 1 + 3)) = 30 frames + * + * Additional frames given if received FIFO frames is more than WATERMARK_LEVEL set. + */ +#define ACCEL_FRAME_LEN UINT8_C(255) + +/*! FIFO watermark level */ +#define WATERMARK_LEVEL UINT16_C(300) + +/*! Sensortime resolution in seconds */ +#define SENSORTIME_RESOLUTION (0.0003125f) + +/*! Earth's gravity in m/s^2 */ +#define GRAVITY_EARTH (9.80665f) + +/******************************************************************************/ +/*! Global Variables */ + +/*! Number of accel frames to be extracted from FIFO */ +uint8_t fifo_accel_frame_length = ACCEL_FRAME_LEN; + +/*! Number of bytes of FIFO data */ +uint8_t fifo_data[BMA530_FIFO_RAW_DATA_BUFFER_SIZE] = { 0 }; + +/*! Array of accelerometer and sensortime frames + * Array size same as fifo_accel_frame_length */ +struct bma5_sens_fifo_axes_data_16_bit fifo_acc_data[ACCEL_FRAME_LEN]; + +/******************************************************************************/ +/*! Static Function Declaration */ + +/*! + * @brief This internal API is used to enable accel and interrupt configuration settings. + * + * @param[in] dev : Structure instance of bma5_dev. + * + * return Status of API + */ +static int8_t get_accel_and_int_settings(struct bma5_dev *dev); + +/*! + * @brief This internal API gets FIFO configurations. + * + * @param[in, out] fifo_conf : Structure instance of bma5_fifo_conf. + * @param[in] dev : Structure instance of bma5_dev. + * + * return Status of API + */ +static int8_t get_fifo_conf(const struct bma5_fifo_conf *fifo_conf, struct bma5_dev *dev); + +/*! + * @brief This internal API gets FIFO 16 bit data with FIFO WM interrupt. + * + * @param[in] accel_length : Store accel frame length. + * @param[in] fifo_accel_data : Structure instance of bma5_sens_fifo_axes_data_8_bit. + * @param[in] fifoframe : Structure instance of bma5_fifo_frame. + * @param[in] fifo_conf : Structure instance of bma5_fifo_conf. + * @param[in] dev : Structure instance of bma5_dev. + * + * return Status of API + */ +static int8_t get_fifo_full_16_bit_data(struct bma5_sens_fifo_axes_data_16_bit *fifo_accel_data, + struct bma5_fifo_frame fifoframe, + const struct bma5_fifo_conf *fifo_conf, + struct bma5_dev *dev); + +/*! + * @brief This internal API converts raw sensor values(LSB) to meters per seconds square. + * + * @param[in] val : Raw sensor value. + * @param[in] g_range : Accel Range selected (2G, 4G, 8G, 16G). + * @param[in] bit_width : Resolution of the sensor. + * + * @return Accel values in meters per second square. + * + */ +static float lsb_to_ms2(int16_t val, float g_range, uint8_t bit_width); + +/* Set FIFO water-mark level */ +uint16_t fifo_watermark_level = WATERMARK_LEVEL; + +/******************************************************************************/ +int main(void) +{ + struct bma5_dev dev; + int8_t rslt; + struct bma530_int_map int_map, get_int_map; + struct bma5_fifo_conf fifo_conf; + + /* Initialize FIFO frame structure */ + struct bma5_fifo_frame fifoframe = { 0 }; + enum bma5_context context; + + /* Assign context parameter selection */ + context = BMA5_SMARTPHONE; + + /* Interface reference is given as a parameter + * For I2C : BMA5_I2C_INTF + * For SPI : BMA5_SPI_INTF + */ + rslt = bma5_interface_init(&dev, BMA5_SPI_INTF, context); + bma5_check_rslt("bma5_interface_init", rslt); + + rslt = bma530_init(&dev); + bma5_check_rslt("bma530_init", rslt); + printf("BMA530 Chip ID is 0x%X\n", dev.chip_id); + + rslt = bma530_get_int_map(&int_map, &dev); + bma5_check_rslt("bma530_get_int_map", rslt); + + int_map.fifo_full_int_map = BMA530_FIFO_FULL_INT_MAP_INT2; + rslt = bma530_set_int_map(&int_map, &dev); + bma5_check_rslt("bma530_set_int_map", rslt); + + rslt = bma530_get_int_map(&get_int_map, &dev); + bma5_check_rslt("bma530_get_int_map", rslt); + + rslt = get_accel_and_int_settings(&dev); + bma5_check_rslt("get_accel_and_int_settings", rslt); + + /* Get FIFO configuration register */ + rslt = bma5_get_fifo_conf(&fifo_conf, &dev); + bma5_check_rslt("bma5_get_fifo_conf", rslt); + + rslt = bma5_get_fifo_conf(&fifo_conf, &dev); + bma5_check_rslt("bma5_get_fifo_conf", rslt); + + fifo_conf.fifo_cfg = BMA5_FIFO_CFG_ENABLE; + fifo_conf.fifo_acc_x = BMA5_FIFO_ACC_X_ENABLE; + fifo_conf.fifo_acc_y = BMA5_FIFO_ACC_Y_ENABLE; + fifo_conf.fifo_acc_z = BMA5_FIFO_ACC_Z_ENABLE; + fifo_conf.fifo_compression = BMA5_FIFO_COMPRESSION_ACC_16BIT; + fifo_conf.fifo_sensor_time = BMA5_FIFO_SENSOR_TIME_EACH_FRAME; + fifo_conf.fifo_size = BMA5_FIFO_SIZE_MAX_512_BYTES; + fifo_conf.fifo_stop_on_full = BMA5_ENABLE; + + rslt = get_fifo_conf(&fifo_conf, &dev); + bma5_check_rslt("get_fifo_conf", rslt); + + /* Update FIFO structure */ + fifoframe.data = fifo_data; + + rslt = bma5_set_fifo_wm(fifo_watermark_level, &dev); + bma5_check_rslt("bma5_set_fifo_wm", rslt); + + rslt = get_fifo_full_16_bit_data(fifo_acc_data, fifoframe, &fifo_conf, &dev); + + bma5_coines_deinit(); + + return rslt; +} + +/*! + * @brief This internal API is used to enable accel and interrupt configuration settings. + */ +static int8_t get_accel_and_int_settings(struct bma5_dev *dev) +{ + int8_t rslt; + uint8_t n_ints = 1; + uint8_t sensor_ctrl; + struct bma5_acc_conf acc_cfg, get_acc_cfg; + struct bma5_int_conf_types int_config; + + int_config.int_src = BMA5_INT_2; + + /* Get accel configurations */ + rslt = bma5_get_acc_conf_0(&sensor_ctrl, dev); + bma5_check_rslt("bma5_get_acc_conf_0", rslt); + + rslt = bma5_get_acc_conf(&acc_cfg, dev); + bma5_check_rslt("bma5_get_acc_conf", rslt); + + /* Set accel configurations */ + acc_cfg.acc_odr = BMA5_ACC_ODR_HZ_6K4; + acc_cfg.acc_bwp = BMA5_ACC_BWP_NORM_AVG4; + acc_cfg.power_mode = BMA5_POWER_MODE_HPM; + + acc_cfg.acc_range = BMA5_ACC_RANGE_MAX_2G; + acc_cfg.acc_iir_ro = BMA5_ACC_IIR_RO_DB_60; + acc_cfg.noise_mode = BMA5_NOISE_MODE_LOWER_POWER; + acc_cfg.acc_drdy_int_auto_clear = BMA5_ACC_DRDY_INT_AUTO_CLEAR_DISABLED; + + rslt = bma5_set_acc_conf(&acc_cfg, dev); + bma5_check_rslt("bma5_get_acc_conf", rslt); + + /* Enable accel */ + sensor_ctrl = BMA5_SENSOR_CTRL_ENABLE; + + rslt = bma5_set_acc_conf_0(sensor_ctrl, dev); + bma5_check_rslt("bma5_set_acc_conf_0", rslt); + + rslt = bma5_get_acc_conf_0(&sensor_ctrl, dev); + bma5_check_rslt("bma5_set_acc_conf_0", rslt); + + rslt = bma5_get_acc_conf(&get_acc_cfg, dev); + bma5_check_rslt("bma5_get_acc_conf", rslt); + + printf("Sensor CTRL : %d\n", sensor_ctrl); + printf("ODR : %d\n", get_acc_cfg.acc_odr); + printf("BW : %d\n", get_acc_cfg.acc_bwp); + printf("Power mode : %d\n", get_acc_cfg.power_mode); + printf("Range : %d\n", get_acc_cfg.acc_range); + printf("IIR RO : %d\n", get_acc_cfg.acc_iir_ro); + printf("Noise mode : %d\n", get_acc_cfg.noise_mode); + printf("Auto Int clear : %d\n", get_acc_cfg.acc_drdy_int_auto_clear); + + rslt = bma5_get_int_conf(&int_config, n_ints, dev); + bma5_check_rslt("bma5_get_int_conf", rslt); + + int_config.int_conf.int_mode = BMA5_INT2_MODE_LATCHED; + int_config.int_conf.int_od = BMA5_INT2_OD_PUSH_PULL; + int_config.int_conf.int_lvl = BMA5_INT2_LVL_ACTIVE_HIGH; + + rslt = bma5_set_int_conf(&int_config, n_ints, dev); + bma5_check_rslt("bma5_set_int_conf", rslt); + + return rslt; +} + +/*! + * @brief This internal API gets FIFO configurations. + */ +static int8_t get_fifo_conf(const struct bma5_fifo_conf *fifo_conf, struct bma5_dev *dev) +{ + int8_t rslt; + struct bma5_fifo_conf read_fifo_conf = { 0 }; + + /* Set FIFO configuration. + * NOTE 1: FIFO works only on header mode */ + rslt = bma5_set_fifo_conf(fifo_conf, dev); + bma5_check_rslt("bma5_set_fifo_conf", rslt); + + printf("\nSet FIFO conf\n"); + printf("fifo en %d\n", fifo_conf->fifo_cfg); + printf("fifo_x_en %d\n", fifo_conf->fifo_acc_x); + printf("fifo_y_en %d\n", fifo_conf->fifo_acc_y); + printf("fifo_z_en %d\n", fifo_conf->fifo_acc_z); + printf("fifo_compression_en %d\n", fifo_conf->fifo_compression); + printf("fifo_sensor_time %d\n", fifo_conf->fifo_sensor_time); + printf("fifo_size %d\n", fifo_conf->fifo_size); + + /* Get FIFO configuration register */ + rslt = bma5_get_fifo_conf(&read_fifo_conf, dev); + bma5_check_rslt("bma5_get_fifo_conf", rslt); + + printf("\nGet FIFO conf\n"); + printf("fifo en %d\n", read_fifo_conf.fifo_cfg); + printf("fifo_x_en %d\n", read_fifo_conf.fifo_acc_x); + printf("fifo_y_en %d\n", read_fifo_conf.fifo_acc_y); + printf("fifo_z_en %d\n", read_fifo_conf.fifo_acc_z); + printf("fifo_compression_en %d\n", read_fifo_conf.fifo_compression); + printf("fifo_sensor_time %d\n", read_fifo_conf.fifo_sensor_time); + printf("fifo_size %d\n", read_fifo_conf.fifo_size); + + return rslt; +} + +/*! + * @brief This internal API gets FIFO 16 bit data with FIFO full interrupt. + */ +static int8_t get_fifo_full_16_bit_data(struct bma5_sens_fifo_axes_data_16_bit *fifo_accel_data, + struct bma5_fifo_frame fifoframe, + const struct bma5_fifo_conf *fifo_conf, + struct bma5_dev *dev) +{ + int8_t rslt = BMA5_OK; + uint8_t n_status = 1; + struct bma530_int_status_types int_status = { 0 }; + uint8_t loop = 0; + uint16_t idx = 0; + float x = 0, y = 0, z = 0; + + int_status.int_src = BMA530_INT_STATUS_INT2; + + printf("Get FIFO data"); + + while (loop < 3) + { + /* Get fifo full interrupt 2 status */ + rslt = bma530_get_int_status(&int_status, n_status, dev); + bma5_check_rslt("bma530_get_int_status", rslt); + + if (int_status.int_status.fifo_full_int_status & BMA5_ENABLE) + { + printf("\n\nIteration %d\n\n", loop); + + /* Read FIFO data */ + rslt = bma5_read_fifo_data(&fifoframe, fifo_conf, dev); + bma5_check_rslt("bma5_read_fifo_data", rslt); + + /* Set fifo full interrupt 2 status */ + rslt = bma530_set_int_status(&int_status, n_status, dev); + bma5_check_rslt("bma530_get_int_status\n", rslt); + + if (rslt == BMA5_OK) + { + /* Parse the FIFO data to extract accelerometer and sensortime data from the FIFO buffer */ + (void)bma5_extract_acc_sens_time_16_bit(fifo_accel_data, &fifoframe, fifo_conf, dev); + + printf( + "\nCount, Accel_LSB_X, Accel_LSB_Y, Accel_LSB_Z, Acc_ms2_X, Acc_ms2_Y, Acc_ms2_Z, Sensortime(S)\n"); + + /* Print the parsed accelerometer and sensortime data from the FIFO buffer */ + for (idx = 0; idx < fifoframe.fifo_avail_frames; idx++) + { + /* Converting lsb to meter per second squared for 16 bit resolution at 2G range */ + x = lsb_to_ms2(fifo_accel_data[idx].x, (float)2, BMA5_16_BIT_RESOLUTION); + y = lsb_to_ms2(fifo_accel_data[idx].y, (float)2, BMA5_16_BIT_RESOLUTION); + z = lsb_to_ms2(fifo_accel_data[idx].z, (float)2, BMA5_16_BIT_RESOLUTION); + + /* Print the data in m/s2 */ + printf("%d, %d, %d, %d, %4.2f, %4.2f, %4.2f, %.4lf s\n", + idx, + fifo_accel_data[idx].x, + fifo_accel_data[idx].y, + fifo_accel_data[idx].z, + x, + y, + z, + (fifo_accel_data[idx].sensor_time * SENSORTIME_RESOLUTION)); + } + + loop++; + } + } + } + + return rslt; +} + +/*! + * @brief This internal API converts raw sensor values(LSB) to meters per seconds square. + */ +static float lsb_to_ms2(int16_t val, float g_range, uint8_t bit_width) +{ + double power = 2; + + float half_scale = (float)((pow((double)power, (double)bit_width) / 2.0f)); + + return (GRAVITY_EARTH * val * g_range) / half_scale; +} diff --git a/examples/fifo_wm_8_bit_dedicated_frame_comp_en/Makefile b/examples/fifo_wm_8_bit_dedicated_frame_comp_en/Makefile new file mode 100644 index 0000000..65e3291 --- /dev/null +++ b/examples/fifo_wm_8_bit_dedicated_frame_comp_en/Makefile @@ -0,0 +1,18 @@ +COINES_INSTALL_PATH ?= ../../../.. + +EXAMPLE_FILE ?= fifo_wm_8_bit_dedicated_frame_comp_en.c + +API_LOCATION ?= ../.. +COMMON_LOCATION ?= .. + +C_SRCS += \ +$(API_LOCATION)/bma5.c \ +$(API_LOCATION)/bma530.c \ +$(API_LOCATION)/bma530_features.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/fifo_wm_8_bit_dedicated_frame_comp_en/fifo_wm_8_bit_dedicated_frame_comp_en.c b/examples/fifo_wm_8_bit_dedicated_frame_comp_en/fifo_wm_8_bit_dedicated_frame_comp_en.c new file mode 100644 index 0000000..dc9fbea --- /dev/null +++ b/examples/fifo_wm_8_bit_dedicated_frame_comp_en/fifo_wm_8_bit_dedicated_frame_comp_en.c @@ -0,0 +1,383 @@ +/** + * Copyright (c) 2024 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. + * + */ + +#include +#include +#include "common.h" +#include "bma530_features.h" + +/******************************************************************************/ +/*! Macro definition */ + +/*! FIFO raw data buffer size */ +#define BMA530_FIFO_RAW_DATA_BUFFER_SIZE UINT16_C(520) + +/*! Number of accel frames to be extracted from FIFO + * + * Calculation: + * fifo_watermark_level = 400, accel_frame_len = 3 + * fifo_accel_frame_count = (400 / (3)) = 133 frames + * + * Note : + * Dedicated frame generates header on demand. + * Additional frames given to read sensortime frame + */ +#define ACCEL_FRAME_LEN UINT16_C(380) + +/*! FIFO watermark level */ +#define WATERMARK_LEVEL UINT16_C(400) + +/*! Sensortime resolution in seconds */ +#define SENSORTIME_RESOLUTION (0.0003125f) + +/*! Earth's gravity in m/s^2 */ +#define GRAVITY_EARTH (9.80665f) + +/******************************************************************************/ +/*! Global Variables */ + +/*! Number of accel frames to be extracted from FIFO */ +uint16_t fifo_accel_frame_length = ACCEL_FRAME_LEN; + +/*! Number of bytes of FIFO data */ +uint8_t fifo_data[BMA530_FIFO_RAW_DATA_BUFFER_SIZE + BMA5_SENSORTIME_OVERHEAD_BYTE] = { 0 }; + +/*! Array of accelerometer and sensortime frames + * Array size same as fifo_accel_frame_length */ +struct bma5_sens_fifo_axes_data_8_bit fifo_acc_data[ACCEL_FRAME_LEN]; + +/******************************************************************************/ +/*! Static Function Declaration */ + +/*! + * @brief This internal API is used to enable accel and interrupt configuration settings. + * + * @param[in] dev : Structure instance of bma5_dev. + * + * return Status of API + */ +static int8_t get_accel_and_int_settings(struct bma5_dev *dev); + +/*! + * @brief This internal API gets FIFO configurations. + * + * @param[in, out] fifo_conf : Structure instance of bma5_fifo_conf. + * @param[in] dev : Structure instance of bma5_dev. + * + * return Status of API + */ +static int8_t get_fifo_conf(const struct bma5_fifo_conf *fifo_conf, struct bma5_dev *dev); + +/*! + * @brief This internal API gets FIFO 8 bit data with FIFO WM interrupt. + * + * @param[in] accel_length : Store accel frame length. + * @param[in] fifo_accel_data : Structure instance of bma5_sens_fifo_axes_data_8_bit. + * @param[in] fifoframe : Structure instance of bma5_fifo_frame. + * @param[in] fifo_conf : Structure instance of bma5_fifo_conf. + * @param[in] dev : Structure instance of bma5_dev. + * + * return Status of API + */ +static int8_t get_fifo_full_8_bit_data(struct bma5_sens_fifo_axes_data_8_bit *fifo_accel_data, + struct bma5_fifo_frame fifoframe, + const struct bma5_fifo_conf *fifo_conf, + struct bma5_dev *dev); + +/*! + * @brief This internal API converts raw sensor values(LSB) to meters per seconds square. + * + * @param[in] val : Raw sensor value. + * @param[in] g_range : Accel Range selected (2G, 4G, 8G, 16G). + * @param[in] bit_width : Resolution of the sensor. + * + * @return Accel values in meters per second square. + * + */ +static float lsb_to_ms2(int16_t val, float g_range, uint8_t bit_width); + +/******************************************************************************/ +int main(void) +{ + struct bma5_dev dev; + int8_t rslt; + struct bma530_int_map int_map, get_int_map; + struct bma5_fifo_conf fifo_conf; + + /* Initialize FIFO frame structure */ + struct bma5_fifo_frame fifoframe = { 0 }; + + /* Set FIFO water-mark level */ + uint16_t fifo_watermark_level = WATERMARK_LEVEL; + + enum bma5_context context; + + /* Assign context parameter selection */ + context = BMA5_SMARTPHONE; + + /* Interface reference is given as a parameter + * For I2C : BMA5_I2C_INTF + * For SPI : BMA5_SPI_INTF + */ + rslt = bma5_interface_init(&dev, BMA5_I2C_INTF, context); + bma5_check_rslt("bma5_interface_init", rslt); + + rslt = bma530_init(&dev); + bma5_check_rslt("bma530_init", rslt); + printf("BMA530 Chip ID is 0x%X\n", dev.chip_id); + + rslt = bma530_get_int_map(&int_map, &dev); + bma5_check_rslt("bma530_get_int_map", rslt); + + int_map.fifo_full_int_map = BMA530_FIFO_FULL_INT_MAP_INT2; + rslt = bma530_set_int_map(&int_map, &dev); + bma5_check_rslt("bma530_set_int_map", rslt); + + rslt = bma530_get_int_map(&get_int_map, &dev); + bma5_check_rslt("bma530_get_int_map", rslt); + + rslt = get_accel_and_int_settings(&dev); + bma5_check_rslt("get_accel_and_int_settings", rslt); + + /* Get FIFO configuration register */ + rslt = bma5_get_fifo_conf(&fifo_conf, &dev); + bma5_check_rslt("bma5_get_fifo_conf", rslt); + + fifo_conf.fifo_cfg = BMA5_FIFO_CFG_ENABLE; + fifo_conf.fifo_acc_x = BMA5_FIFO_ACC_X_ENABLE; + fifo_conf.fifo_acc_y = BMA5_FIFO_ACC_Y_ENABLE; + fifo_conf.fifo_acc_z = BMA5_FIFO_ACC_Z_ENABLE; + fifo_conf.fifo_compression = BMA5_FIFO_COMPRESSION_ACC_8BIT; + fifo_conf.fifo_sensor_time = BMA5_FIFO_SENSOR_TIME_DEDICATED_FRAME; + fifo_conf.fifo_size = BMA5_FIFO_SIZE_MAX_512_BYTES; + fifo_conf.fifo_stop_on_full = BMA5_ENABLE; + + rslt = get_fifo_conf(&fifo_conf, &dev); + bma5_check_rslt("get_fifo_conf", rslt); + + /* Update FIFO structure */ + fifoframe.data = fifo_data; + + rslt = bma5_set_fifo_wm(fifo_watermark_level, &dev); + bma5_check_rslt("bma5_set_fifo_wm", rslt); + + rslt = get_fifo_full_8_bit_data(fifo_acc_data, fifoframe, &fifo_conf, &dev); + + bma5_coines_deinit(); + + return rslt; +} + +/*! + * @brief This internal API is used to enable accel and interrupt configuration settings. + */ +static int8_t get_accel_and_int_settings(struct bma5_dev *dev) +{ + int8_t rslt; + uint8_t n_ints = 1; + uint8_t sensor_ctrl; + struct bma5_acc_conf acc_cfg, get_acc_cfg; + struct bma5_int_conf_types int_config; + + int_config.int_src = BMA5_INT_2; + + /* Get accel configurations */ + rslt = bma5_get_acc_conf_0(&sensor_ctrl, dev); + bma5_check_rslt("bma5_get_acc_conf_0", rslt); + + rslt = bma5_get_acc_conf(&acc_cfg, dev); + bma5_check_rslt("bma5_get_acc_conf", rslt); + + /* Set accel configurations */ + acc_cfg.acc_odr = BMA5_ACC_ODR_HZ_6K4; + acc_cfg.acc_bwp = BMA5_ACC_BWP_NORM_AVG4; + acc_cfg.power_mode = BMA5_POWER_MODE_HPM; + + acc_cfg.acc_range = BMA5_ACC_RANGE_MAX_2G; + acc_cfg.acc_iir_ro = BMA5_ACC_IIR_RO_DB_60; + acc_cfg.noise_mode = BMA5_NOISE_MODE_LOWER_POWER; + acc_cfg.acc_drdy_int_auto_clear = BMA5_ACC_DRDY_INT_AUTO_CLEAR_DISABLED; + + rslt = bma5_set_acc_conf(&acc_cfg, dev); + bma5_check_rslt("bma5_get_acc_conf", rslt); + + /* Enable accel */ + sensor_ctrl = BMA5_SENSOR_CTRL_ENABLE; + + rslt = bma5_set_acc_conf_0(sensor_ctrl, dev); + bma5_check_rslt("bma5_set_acc_conf_0", rslt); + + rslt = bma5_get_acc_conf_0(&sensor_ctrl, dev); + bma5_check_rslt("bma5_set_acc_conf_0", rslt); + + rslt = bma5_get_acc_conf(&get_acc_cfg, dev); + bma5_check_rslt("bma5_get_acc_conf", rslt); + + printf("Sensor CTRL : %d\n", sensor_ctrl); + printf("ODR : %d\n", get_acc_cfg.acc_odr); + printf("BW : %d\n", get_acc_cfg.acc_bwp); + printf("Power mode : %d\n", get_acc_cfg.power_mode); + printf("Range : %d\n", get_acc_cfg.acc_range); + printf("IIR RO : %d\n", get_acc_cfg.acc_iir_ro); + printf("Noise mode : %d\n", get_acc_cfg.noise_mode); + printf("Auto Int clear : %d\n", get_acc_cfg.acc_drdy_int_auto_clear); + + rslt = bma5_get_int_conf(&int_config, n_ints, dev); + bma5_check_rslt("bma5_get_int_conf", rslt); + + int_config.int_conf.int_mode = BMA5_INT2_MODE_LATCHED; + int_config.int_conf.int_od = BMA5_INT2_OD_PUSH_PULL; + int_config.int_conf.int_lvl = BMA5_INT2_LVL_ACTIVE_HIGH; + + rslt = bma5_set_int_conf(&int_config, n_ints, dev); + bma5_check_rslt("bma5_set_int_conf", rslt); + + return rslt; +} + +/*! + * @brief This internal API gets FIFO configurations. + */ +static int8_t get_fifo_conf(const struct bma5_fifo_conf *fifo_conf, struct bma5_dev *dev) +{ + int8_t rslt; + struct bma5_fifo_conf read_fifo_conf = { 0 }; + + /* Set FIFO configuration. + * NOTE 1: FIFO works only on header mode */ + rslt = bma5_set_fifo_conf(fifo_conf, dev); + bma5_check_rslt("bma5_set_fifo_conf", rslt); + + printf("\nSet FIFO conf\n"); + printf("fifo en %d\n", fifo_conf->fifo_cfg); + printf("fifo_x_en %d\n", fifo_conf->fifo_acc_x); + printf("fifo_y_en %d\n", fifo_conf->fifo_acc_y); + printf("fifo_z_en %d\n", fifo_conf->fifo_acc_z); + printf("fifo_compression_en %d\n", fifo_conf->fifo_compression); + printf("fifo_sensor_time %d\n", fifo_conf->fifo_sensor_time); + printf("fifo_size %d\n", fifo_conf->fifo_size); + + /* Get FIFO configuration register */ + rslt = bma5_get_fifo_conf(&read_fifo_conf, dev); + bma5_check_rslt("bma5_get_fifo_conf", rslt); + + printf("\nGet FIFO conf\n"); + printf("fifo en %d\n", read_fifo_conf.fifo_cfg); + printf("fifo_x_en %d\n", read_fifo_conf.fifo_acc_x); + printf("fifo_y_en %d\n", read_fifo_conf.fifo_acc_y); + printf("fifo_z_en %d\n", read_fifo_conf.fifo_acc_z); + printf("fifo_compression_en %d\n", read_fifo_conf.fifo_compression); + printf("fifo_sensor_time %d\n", read_fifo_conf.fifo_sensor_time); + printf("fifo_size %d\n", read_fifo_conf.fifo_size); + + return rslt; +} + +/*! + * @brief This internal API gets FIFO 8 bit data with FIFO full interrupt. + */ +static int8_t get_fifo_full_8_bit_data(struct bma5_sens_fifo_axes_data_8_bit *fifo_accel_data, + struct bma5_fifo_frame fifoframe, + const struct bma5_fifo_conf *fifo_conf, + struct bma5_dev *dev) +{ + int8_t rslt = BMA5_OK; + uint8_t n_status = 1; + struct bma530_int_status_types int_status = { 0 }; + uint8_t loop = 0; + uint16_t idx = 0; + float x = 0, y = 0, z = 0; + + int_status.int_src = BMA530_INT_STATUS_INT2; + + printf("Get FIFO data"); + + while (loop < 3) + { + /* Get fifo full interrupt 2 status */ + rslt = bma530_get_int_status(&int_status, n_status, dev); + bma5_check_rslt("bma530_get_int_status", rslt); + + if (int_status.int_status.fifo_full_int_status & BMA5_ENABLE) + { + printf("\n\nIteration %d\n\n", loop); + + /* Read FIFO data */ + rslt = bma5_read_fifo_data(&fifoframe, fifo_conf, dev); + bma5_check_rslt("bma5_read_fifo_data", rslt); + + rslt = bma530_set_int_status(&int_status, n_status, dev); + bma5_check_rslt("bma530_set_int_status", rslt); + + if (rslt == BMA5_OK) + { + /* Parse the FIFO data to extract accelerometer and sensortime data from the FIFO buffer */ + (void)bma5_extract_acc_sens_time_8_bit(fifo_accel_data, &fifoframe, fifo_conf, dev); + + printf("\nCount, Accel_LSB_X, Accel_LSB_Y, Accel_LSB_Z, Acc_ms2_X, Acc_ms2_Y, Acc_ms2_Z\n"); + + /* Print the parsed accelerometer and sensortime data from the FIFO buffer */ + for (idx = 0; idx < fifoframe.fifo_avail_frames; idx++) + { + /* Converting lsb to meter per second squared for 8 bit resolution at 2G range */ + x = lsb_to_ms2(fifo_accel_data[idx].x, (float)2, BMA5_8_BIT_RESOLUTION); + y = lsb_to_ms2(fifo_accel_data[idx].y, (float)2, BMA5_8_BIT_RESOLUTION); + z = lsb_to_ms2(fifo_accel_data[idx].z, (float)2, BMA5_8_BIT_RESOLUTION); + + /* Print the data in m/s2 */ + printf("%d, %d, %d, %d, %4.2f, %4.2f, %4.2f\n", idx, fifo_accel_data[idx].x, + fifo_accel_data[idx].y, fifo_accel_data[idx].z, x, y, z); + } + + printf("Sensor time(in seconds) = %.4lf s", fifo_accel_data[idx].sensor_time * SENSORTIME_RESOLUTION); + + loop++; + } + } + } + + return rslt; +} + +/*! + * @brief This internal API converts raw sensor values(LSB) to meters per seconds square. + */ +static float lsb_to_ms2(int16_t val, float g_range, uint8_t bit_width) +{ + double power = 2; + + float half_scale = (float)((pow((double)power, (double)bit_width) / 2.0f)); + + return (GRAVITY_EARTH * val * g_range) / half_scale; +} diff --git a/examples/fifo_wm_8_bit_each_frame_comp_en/Makefile b/examples/fifo_wm_8_bit_each_frame_comp_en/Makefile new file mode 100644 index 0000000..dd14676 --- /dev/null +++ b/examples/fifo_wm_8_bit_each_frame_comp_en/Makefile @@ -0,0 +1,18 @@ +COINES_INSTALL_PATH ?= ../../../.. + +EXAMPLE_FILE ?= fifo_wm_8_bit_each_frame_comp_en.c + +API_LOCATION ?= ../.. +COMMON_LOCATION ?= .. + +C_SRCS += \ +$(API_LOCATION)/bma5.c \ +$(API_LOCATION)/bma530.c \ +$(API_LOCATION)/bma530_features.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/fifo_wm_8_bit_each_frame_comp_en/fifo_wm_8_bit_each_frame_comp_en.c b/examples/fifo_wm_8_bit_each_frame_comp_en/fifo_wm_8_bit_each_frame_comp_en.c new file mode 100644 index 0000000..78f3510 --- /dev/null +++ b/examples/fifo_wm_8_bit_each_frame_comp_en/fifo_wm_8_bit_each_frame_comp_en.c @@ -0,0 +1,386 @@ +/** + * Copyright (c) 2024 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. + * + */ + +#include +#include +#include "common.h" +#include "bma530_features.h" + +/******************************************************************************/ +/*! Macro definition */ + +/*! FIFO raw data buffer size */ +#define BMA530_FIFO_RAW_DATA_BUFFER_SIZE UINT16_C(520) + +/*! Number of accel frames to be extracted from FIFO + * Calculation: + * fifo_watermark_level = 300, accel_frame_len = 3, header_byte = 1, sensortime = 3. + * fifo_accel_frame_count = (300 / (3 + 1 + 3)) = 43 frames + * + * Additional frames given if received FIFO frames is more than WATERMARK_LEVEL set. + */ +#define ACCEL_FRAME_LEN UINT16_C(380) + +/*! FIFO watermark level */ +#define WATERMARK_LEVEL UINT16_C(300) + +/*! Sensortime resolution in seconds */ +#define SENSORTIME_RESOLUTION (0.0003125f) + +/*! Earth's gravity in m/s^2 */ +#define GRAVITY_EARTH (9.80665f) + +/******************************************************************************/ +/*! Global Variables */ + +/*! Number of accel frames to be extracted from FIFO */ +uint16_t fifo_accel_frame_length = ACCEL_FRAME_LEN; + +/*! Number of bytes of FIFO data */ +uint8_t fifo_data[BMA530_FIFO_RAW_DATA_BUFFER_SIZE] = { 0 }; + +/*! Array of accelerometer and sensortime frames + * Array size same as fifo_accel_frame_length */ +struct bma5_sens_fifo_axes_data_8_bit fifo_acc_data[ACCEL_FRAME_LEN]; + +/******************************************************************************/ +/*! Static Function Declaration */ + +/*! + * @brief This internal API is used to enable accel and interrupt configuration settings. + * + * @param[in] dev : Structure instance of bma5_dev. + * + * return Status of API + */ +static int8_t get_accel_and_int_settings(struct bma5_dev *dev); + +/*! + * @brief This internal API gets FIFO configurations. + * + * @param[in, out] fifo_conf : Structure instance of bma5_fifo_conf. + * @param[in] dev : Structure instance of bma5_dev. + * + * return Status of API + */ +static int8_t get_fifo_conf(const struct bma5_fifo_conf *fifo_conf, struct bma5_dev *dev); + +/*! + * @brief This internal API gets FIFO 8 bit data with FIFO full interrupt. + * + * @param[in] accel_length : Store accel frame length. + * @param[in] fifo_accel_data : Structure instance of bma5_sens_fifo_axes_data_8_bit. + * @param[in] fifoframe : Structure instance of bma5_fifo_frame. + * @param[in] fifo_conf : Structure instance of bma5_fifo_conf. + * @param[in] dev : Structure instance of bma5_dev. + * + * return Status of API + */ +static int8_t get_fifo_full_8_bit_data(struct bma5_sens_fifo_axes_data_8_bit *fifo_accel_data, + struct bma5_fifo_frame fifoframe, + const struct bma5_fifo_conf *fifo_conf, + struct bma5_dev *dev); + +/*! + * @brief This internal API converts raw sensor values(LSB) to meters per seconds square. + * + * @param[in] val : Raw sensor value. + * @param[in] g_range : Accel Range selected (2G, 4G, 8G, 16G). + * @param[in] bit_width : Resolution of the sensor. + * + * @return Accel values in meters per second square. + * + */ +static float lsb_to_ms2(int16_t val, float g_range, uint8_t bit_width); + +/* Set FIFO water-mark level */ +uint16_t fifo_watermark_level = WATERMARK_LEVEL; + +/******************************************************************************/ +int main(void) +{ + struct bma5_dev dev; + int8_t rslt; + struct bma530_int_map int_map, get_int_map; + struct bma5_fifo_conf fifo_conf; + + /* Initialize FIFO frame structure */ + struct bma5_fifo_frame fifoframe = { 0 }; + + enum bma5_context context; + + /* Assign context parameter selection */ + context = BMA5_SMARTPHONE; + + /* Interface reference is given as a parameter + * For I2C : BMA5_I2C_INTF + * For SPI : BMA5_SPI_INTF + */ + rslt = bma5_interface_init(&dev, BMA5_I2C_INTF, context); + bma5_check_rslt("bma5_interface_init", rslt); + + rslt = bma530_init(&dev); + bma5_check_rslt("bma530_init", rslt); + printf("BMA530 Chip ID is 0x%X\n", dev.chip_id); + + rslt = bma530_get_int_map(&int_map, &dev); + bma5_check_rslt("bma530_get_int_map", rslt); + + int_map.fifo_full_int_map = BMA530_FIFO_FULL_INT_MAP_INT1; + rslt = bma530_set_int_map(&int_map, &dev); + bma5_check_rslt("bma530_set_int_map", rslt); + + rslt = bma530_get_int_map(&get_int_map, &dev); + bma5_check_rslt("bma530_get_int_map", rslt); + + rslt = get_accel_and_int_settings(&dev); + bma5_check_rslt("get_accel_and_int_settings", rslt); + + /* Get FIFO configuration register */ + rslt = bma5_get_fifo_conf(&fifo_conf, &dev); + bma5_check_rslt("bma5_get_fifo_conf", rslt); + + fifo_conf.fifo_cfg = BMA5_FIFO_CFG_ENABLE; + fifo_conf.fifo_acc_x = BMA5_FIFO_ACC_X_ENABLE; + fifo_conf.fifo_acc_y = BMA5_FIFO_ACC_Y_ENABLE; + fifo_conf.fifo_acc_z = BMA5_FIFO_ACC_Z_ENABLE; + fifo_conf.fifo_compression = BMA5_FIFO_COMPRESSION_ACC_8BIT; + fifo_conf.fifo_sensor_time = BMA5_FIFO_SENSOR_TIME_EACH_FRAME; + fifo_conf.fifo_size = BMA5_FIFO_SIZE_MAX_512_BYTES; + fifo_conf.fifo_stop_on_full = BMA5_ENABLE; + + rslt = get_fifo_conf(&fifo_conf, &dev); + bma5_check_rslt("get_fifo_conf", rslt); + + /* Update FIFO structure */ + fifoframe.data = fifo_data; + + rslt = bma5_set_fifo_wm(fifo_watermark_level, &dev); + bma5_check_rslt("bma5_set_fifo_wm", rslt); + + rslt = get_fifo_full_8_bit_data(fifo_acc_data, fifoframe, &fifo_conf, &dev); + + bma5_coines_deinit(); + + return rslt; +} + +/*! + * @brief This internal API is used to enable accel and interrupt configuration settings. + */ +static int8_t get_accel_and_int_settings(struct bma5_dev *dev) +{ + int8_t rslt; + uint8_t n_ints = 1; + uint8_t sensor_ctrl; + struct bma5_acc_conf acc_cfg, get_acc_cfg; + struct bma5_int_conf_types int_config; + + int_config.int_src = BMA5_INT_1; + + /* Get accel configurations */ + rslt = bma5_get_acc_conf_0(&sensor_ctrl, dev); + bma5_check_rslt("bma5_get_acc_conf_0", rslt); + + rslt = bma5_get_acc_conf(&acc_cfg, dev); + bma5_check_rslt("bma5_get_acc_conf", rslt); + + /* Set accel configurations */ + acc_cfg.acc_odr = BMA5_ACC_ODR_HZ_6K4; + acc_cfg.acc_bwp = BMA5_ACC_BWP_NORM_AVG4; + acc_cfg.power_mode = BMA5_POWER_MODE_HPM; + + acc_cfg.acc_range = BMA5_ACC_RANGE_MAX_2G; + acc_cfg.acc_iir_ro = BMA5_ACC_IIR_RO_DB_60; + acc_cfg.noise_mode = BMA5_NOISE_MODE_LOWER_POWER; + acc_cfg.acc_drdy_int_auto_clear = BMA5_ACC_DRDY_INT_AUTO_CLEAR_DISABLED; + + rslt = bma5_set_acc_conf(&acc_cfg, dev); + bma5_check_rslt("bma5_get_acc_conf", rslt); + + /* Enable accel */ + sensor_ctrl = BMA5_SENSOR_CTRL_ENABLE; + + rslt = bma5_set_acc_conf_0(sensor_ctrl, dev); + bma5_check_rslt("bma5_set_acc_conf_0", rslt); + + rslt = bma5_get_acc_conf_0(&sensor_ctrl, dev); + bma5_check_rslt("bma5_set_acc_conf_0", rslt); + + rslt = bma5_get_acc_conf(&get_acc_cfg, dev); + bma5_check_rslt("bma5_get_acc_conf", rslt); + + printf("Sensor CTRL : %d\n", sensor_ctrl); + printf("ODR : %d\n", get_acc_cfg.acc_odr); + printf("BW : %d\n", get_acc_cfg.acc_bwp); + printf("Power mode : %d\n", get_acc_cfg.power_mode); + printf("Range : %d\n", get_acc_cfg.acc_range); + printf("IIR RO : %d\n", get_acc_cfg.acc_iir_ro); + printf("Noise mode : %d\n", get_acc_cfg.noise_mode); + printf("Auto Int clear : %d\n", get_acc_cfg.acc_drdy_int_auto_clear); + + rslt = bma5_get_int_conf(&int_config, n_ints, dev); + bma5_check_rslt("bma5_get_int_conf", rslt); + + int_config.int_conf.int_mode = BMA5_INT1_MODE_LATCHED; + int_config.int_conf.int_od = BMA5_INT1_OD_PUSH_PULL; + int_config.int_conf.int_lvl = BMA5_INT1_LVL_ACTIVE_HIGH; + + rslt = bma5_set_int_conf(&int_config, n_ints, dev); + bma5_check_rslt("bma5_set_int_conf", rslt); + + return rslt; +} + +/*! + * @brief This internal API gets FIFO configurations. + */ +static int8_t get_fifo_conf(const struct bma5_fifo_conf *fifo_conf, struct bma5_dev *dev) +{ + int8_t rslt; + struct bma5_fifo_conf read_fifo_conf = { 0 }; + + /* Set FIFO configuration. + * NOTE 1: FIFO works only on header mode */ + rslt = bma5_set_fifo_conf(fifo_conf, dev); + bma5_check_rslt("bma5_set_fifo_conf", rslt); + + printf("\nSet FIFO conf\n"); + printf("fifo en %d\n", fifo_conf->fifo_cfg); + printf("fifo_x_en %d\n", fifo_conf->fifo_acc_x); + printf("fifo_y_en %d\n", fifo_conf->fifo_acc_y); + printf("fifo_z_en %d\n", fifo_conf->fifo_acc_z); + printf("fifo_compression_en %d\n", fifo_conf->fifo_compression); + printf("fifo_sensor_time %d\n", fifo_conf->fifo_sensor_time); + printf("fifo_size %d\n", fifo_conf->fifo_size); + + /* Get FIFO configuration register */ + rslt = bma5_get_fifo_conf(&read_fifo_conf, dev); + bma5_check_rslt("bma5_get_fifo_conf", rslt); + + printf("\nGet FIFO conf\n"); + printf("fifo en %d\n", read_fifo_conf.fifo_cfg); + printf("fifo_x_en %d\n", read_fifo_conf.fifo_acc_x); + printf("fifo_y_en %d\n", read_fifo_conf.fifo_acc_y); + printf("fifo_z_en %d\n", read_fifo_conf.fifo_acc_z); + printf("fifo_compression_en %d\n", read_fifo_conf.fifo_compression); + printf("fifo_sensor_time %d\n", read_fifo_conf.fifo_sensor_time); + printf("fifo_size %d\n", read_fifo_conf.fifo_size); + + return rslt; +} + +/*! + * @brief This internal API gets FIFO 8 bit data with FIFO full interrupt. + */ +static int8_t get_fifo_full_8_bit_data(struct bma5_sens_fifo_axes_data_8_bit *fifo_accel_data, + struct bma5_fifo_frame fifoframe, + const struct bma5_fifo_conf *fifo_conf, + struct bma5_dev *dev) +{ + int8_t rslt = BMA5_OK; + uint8_t n_status = 1; + struct bma530_int_status_types int_status = { 0 }; + uint8_t loop = 0; + uint16_t idx = 0; + float x = 0, y = 0, z = 0; + + int_status.int_src = BMA530_INT_STATUS_INT1; + + printf("Get FIFO data"); + + while (loop < 3) + { + /* Get fifo full interrupt 2 status */ + rslt = bma530_get_int_status(&int_status, n_status, dev); + bma5_check_rslt("bma530_get_int_status", rslt); + + if (int_status.int_status.fifo_full_int_status & BMA5_ENABLE) + { + printf("\n\nIteration %d\n\n", loop); + + /* Read FIFO data */ + rslt = bma5_read_fifo_data(&fifoframe, fifo_conf, dev); + bma5_check_rslt("bma5_read_fifo_data", rslt); + + rslt = bma530_set_int_status(&int_status, n_status, dev); + bma5_check_rslt("bma530_set_int_status", rslt); + + if (rslt == BMA5_OK) + { + /* Parse the FIFO data to extract accelerometer and sensortime data from the FIFO buffer */ + (void)bma5_extract_acc_sens_time_8_bit(fifo_accel_data, &fifoframe, fifo_conf, dev); + + printf( + "\nCount, Accel_LSB_X, Accel_LSB_Y, Accel_LSB_Z, Acc_ms2_X, Acc_ms2_Y, Acc_ms2_Z, Sensortime(s)\n"); + + /* Print the parsed accelerometer and sensortime data from the FIFO buffer */ + for (idx = 0; idx < fifoframe.fifo_avail_frames; idx++) + { + /* Converting lsb to meter per second squared for 8 bit resolution at 2G range */ + x = lsb_to_ms2(fifo_accel_data[idx].x, (float)2, BMA5_8_BIT_RESOLUTION); + y = lsb_to_ms2(fifo_accel_data[idx].y, (float)2, BMA5_8_BIT_RESOLUTION); + z = lsb_to_ms2(fifo_accel_data[idx].z, (float)2, BMA5_8_BIT_RESOLUTION); + + /* Print the data in m/s2 */ + printf("%d, %d, %d, %d, %4.2f, %4.2f, %4.2f, %.4lf s\n", + idx, + fifo_accel_data[idx].x, + fifo_accel_data[idx].y, + fifo_accel_data[idx].z, + x, + y, + z, + (fifo_accel_data[idx].sensor_time * SENSORTIME_RESOLUTION)); + } + + loop++; + } + } + } + + return rslt; +} + +/*! + * @brief This internal API converts raw sensor values(LSB) to meters per seconds square. + */ +static float lsb_to_ms2(int16_t val, float g_range, uint8_t bit_width) +{ + double power = 2; + + float half_scale = (float)((pow((double)power, (double)bit_width) / 2.0f)); + + return (GRAVITY_EARTH * val * g_range) / half_scale; +} diff --git a/examples/flat/Makefile b/examples/flat/Makefile new file mode 100644 index 0000000..d06a40d --- /dev/null +++ b/examples/flat/Makefile @@ -0,0 +1,18 @@ +COINES_INSTALL_PATH ?= ../../../.. + +EXAMPLE_FILE ?= flat.c + +API_LOCATION ?= ../.. +COMMON_LOCATION ?= .. + +C_SRCS += \ +$(API_LOCATION)/bma5.c \ +$(API_LOCATION)/bma530.c \ +$(API_LOCATION)/bma530_features.c \ +$(COMMON_LOCATION)/common/common.c + +INCLUDEPATHS += \ +$(API_LOCATION) \ +$(COMMON_LOCATION)/common + +include $(COINES_INSTALL_PATH)/coines.mk diff --git a/examples/flat/flat.c b/examples/flat/flat.c new file mode 100644 index 0000000..55f8572 --- /dev/null +++ b/examples/flat/flat.c @@ -0,0 +1,189 @@ +/**\ + * Copyright (c) 2024 Bosch Sensortec GmbH. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + **/ + +#include +#include "common.h" +#include "bma530_features.h" + +/******************************************************************************/ +/* Global Definitions */ + +/* Macros for setting various generic interrupt configuration */ + +/* + * Configuration parameters of generic interrupt which influence the sensitivity of the + * flat detection algorithm. + * User can modify below parameters according to system requirements. + */ +#define SLOPE_THRES UINT16_C(160) +#define HYSTERESIS UINT16_C(8) +#define QUIET_TIME UINT16_C(64) +#define DURATION UINT16_C(10) +#define WAIT_TIME UINT8_C(3) + +/* + * Fixed configuration parameters of generic interrupt for flat detection algorithm. + * Not to be changed. + */ +#define CRITERION_SEL UINT8_C(0) /* Check for in-activity */ +#define COMB_SEL UINT8_C(1) /* AND combination of axes */ +#define AXIS_SEL UINT8_C(7) /* Select all axes (X, Y, Z) */ +#define ACC_REF_UP UINT8_C(2) /* Manual reference update */ +#define REF_ACC_X INT16_C(0) /* 0G on X axis */ +#define REF_ACC_Y INT16_C(0) /* 0G on Y axis */ +#define REF_ACC_Z_POS INT16_C(2048) /* 1G on positive Z axis for face down detection */ +#define REF_ACC_Z_NEG INT16_C(-2048) /* 1G negative Z axis for face up detection */ + +/******************************************************************************/ +int main(void) +{ + struct bma5_dev dev; + int8_t rslt; + uint8_t gpr_ctrl_host = BMA5_ENABLE; + uint8_t n_ints = 2; + uint8_t n_status = 1; + uint8_t n_ints_conf = 1; + + /* Variable to hold interrupt mapping */ + struct bma530_int_map int_map; + struct bma5_int_conf_types int_config; + + /* Variable to hold generic interrupt 1 and 2 configuration*/ + struct bma530_generic_interrupt_types conf[2]; + + conf[0].generic_interrupt = BMA530_GEN_INT_1; + conf[1].generic_interrupt = BMA530_GEN_INT_2; + + /* Variable to store interrupt status */ + struct bma530_int_status_types int_status; + struct bma530_feat_eng_gpr_0 gpr_0; + + /* Mapping to hardware interrupt pin 1 on sensor */ + int_config.int_src = BMA5_INT_1; + + /* Variable to hold configurations related to interrupt pin 1 */ + int_status.int_src = BMA530_INT_STATUS_INT1; + + /* Assign context parameter selection */ + enum bma5_context context; + context = BMA5_SMARTPHONE; + + /* Interface reference is given as a parameter + * For I2C : BMA5_I2C_INTF + * For SPI : BMA5_SPI_INTF + */ + rslt = bma5_interface_init(&dev, BMA5_I2C_INTF, context); + bma5_check_rslt("bma5_interface_init", rslt); + + /* Initialize the BMA5 device instance */ + rslt = bma530_init(&dev); + bma5_check_rslt("bma530_init", rslt); + printf("BMA530 Chip ID is 0x%X\n", dev.chip_id); + + /* Updating the generic interrupt 1 and 2 configuration for face up and face down detection */ + printf("Gen Int configurations\n"); + rslt = bma530_get_generic_int_config(conf, n_ints, &dev); + bma5_check_rslt("bma530_get_default_generic_int_config", rslt); + + /* Set Generic Interrupt 1 Configuration as Face Up detection */ + conf[0].gen_int.slope_thres = SLOPE_THRES; + conf[0].gen_int.comb_sel = COMB_SEL; + conf[0].gen_int.axis_sel = AXIS_SEL; + conf[0].gen_int.hysteresis = HYSTERESIS; + conf[0].gen_int.criterion_sel = CRITERION_SEL; + conf[0].gen_int.quiet_time = QUIET_TIME; + conf[0].gen_int.duration = DURATION; + conf[0].gen_int.wait_time = WAIT_TIME; + conf[0].gen_int.acc_ref_up = ACC_REF_UP; + conf[0].gen_int.ref_acc_x = REF_ACC_X; + conf[0].gen_int.ref_acc_y = REF_ACC_Y; + conf[0].gen_int.ref_acc_z = REF_ACC_Z_POS; + + /* Set Generic Interrupt 2 Configuration as Face Down detection */ + conf[1].gen_int.slope_thres = SLOPE_THRES; + conf[1].gen_int.comb_sel = COMB_SEL; + conf[1].gen_int.axis_sel = AXIS_SEL; + conf[1].gen_int.hysteresis = HYSTERESIS; + conf[1].gen_int.criterion_sel = CRITERION_SEL; + conf[1].gen_int.quiet_time = QUIET_TIME; + conf[1].gen_int.duration = DURATION; + conf[1].gen_int.wait_time = WAIT_TIME; + conf[1].gen_int.acc_ref_up = ACC_REF_UP; + conf[1].gen_int.ref_acc_x = REF_ACC_X; + conf[1].gen_int.ref_acc_y = REF_ACC_Y; + conf[1].gen_int.ref_acc_z = REF_ACC_Z_NEG; + + rslt = bma530_set_generic_int_config(conf, n_ints, &dev); + bma5_check_rslt("bma530_set_generic_int_config", rslt); + + if (rslt == BMA5_OK) + { + printf("Generic Interrupt configurations done\n"); + } + + /* Enabling the generic interrupt 1 and 2 using the feature engine general purpose register 0 */ + rslt = bma530_get_feat_eng_gpr_0(&gpr_0, &dev); + bma5_check_rslt("bma530_get_feat_eng_gpr_0", rslt); + + gpr_0.gen_int1_en = BMA5_ENABLE; + gpr_0.gen_int2_en = BMA5_ENABLE; + + rslt = bma530_set_feat_eng_gpr_0(&gpr_0, &dev); + bma5_check_rslt("bma530_set_feat_eng_gpr_0", rslt); + + rslt = bma5_set_regs(BMA5_REG_FEAT_ENG_GPR_CTRL, &gpr_ctrl_host, 1, &dev); + bma5_check_rslt("bma5_set_regs", rslt); + + /* Map generic interrupt 1 and 2 interrupts to hardware interrupt pin 1 of the sensor */ + rslt = bma530_get_int_map(&int_map, &dev); + bma5_check_rslt("bma530_get_int_map", rslt); + + /* Map generic interrupt 1 */ + /* Mapping interrupt for Flat up detection */ + int_map.gen_int1_int_map = BMA530_GEN_INT1_INT_MAP_INT1; + + /* Mapping interrupt for Flat down detection */ + int_map.gen_int2_int_map = BMA530_GEN_INT2_INT_MAP_INT1; + rslt = bma530_set_int_map(&int_map, &dev); + bma5_check_rslt("bma530_set_int_map", rslt); + + /* Map hardware interrupt pin configurations */ + rslt = bma5_get_int_conf(&int_config, n_ints_conf, &dev); + bma5_check_rslt("bma5_get_int_conf", rslt); + + /* Set the hardware interrupt pin configuration */ + int_config.int_conf.int_mode = BMA5_INT1_MODE_LATCHED; + int_config.int_conf.int_od = BMA5_INT1_OD_PUSH_PULL; + int_config.int_conf.int_lvl = BMA5_INT1_LVL_ACTIVE_HIGH; + + rslt = bma5_set_int_conf(&int_config, n_ints_conf, &dev); + bma5_check_rslt("bma5_set_int_conf", rslt); + + printf("Keep the board in Flat postion to genereate interrupt\n"); + + for (;;) + { + /* Read the hardware interrupt pin 1 status */ + rslt = bma530_get_int_status(&int_status, n_status, &dev); + bma5_check_rslt("bma530_get_int_status", rslt); + + /* Checking interrupt status to check Flat orientation */ + if ((int_status.int_status.gen_int1_int_status & BMA5_ENABLE) | + (int_status.int_status.gen_int2_int_status & BMA5_ENABLE)) + { + rslt = bma530_set_int_status(&int_status, n_status, &dev); + bma5_check_rslt("bma530_set_int_status", rslt); + + printf("Flat orientation detected\n"); + break; + + } + } + + bma5_coines_deinit(); + + return rslt; +} diff --git a/examples/generic_interrupt_1/Makefile b/examples/generic_interrupt_1/Makefile new file mode 100644 index 0000000..0712942 --- /dev/null +++ b/examples/generic_interrupt_1/Makefile @@ -0,0 +1,18 @@ +COINES_INSTALL_PATH ?= ../../../.. + +EXAMPLE_FILE ?= generic_interrupt_1.c + +API_LOCATION ?= ../.. +COMMON_LOCATION ?= .. + +C_SRCS += \ +$(API_LOCATION)/bma5.c \ +$(API_LOCATION)/bma530.c \ +$(API_LOCATION)/bma530_features.c \ +$(COMMON_LOCATION)/common/common.c + +INCLUDEPATHS += \ +$(API_LOCATION) \ +$(COMMON_LOCATION)/common + +include $(COINES_INSTALL_PATH)/coines.mk diff --git a/examples/generic_interrupt_1/generic_interrupt_1.c b/examples/generic_interrupt_1/generic_interrupt_1.c new file mode 100644 index 0000000..78504f8 --- /dev/null +++ b/examples/generic_interrupt_1/generic_interrupt_1.c @@ -0,0 +1,158 @@ +/** + * Copyright (c) 2024 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. + * + */ + +#include +#include "common.h" +#include "bma530_features.h" + +/******************************************************************************/ +int main(void) +{ + struct bma5_dev dev; + int8_t rslt; + uint8_t gpr_ctrl_host = BMA5_ENABLE; + uint8_t n_ints = 1; + uint8_t n_status = 1; + + struct bma530_int_map int_map; + struct bma5_int_conf_types int_config; + struct bma530_generic_interrupt_types conf, set_conf; + struct bma530_int_status_types int_status; + struct bma530_feat_eng_gpr_0 gpr_0; + + int_config.int_src = BMA5_INT_1; + int_status.int_src = BMA530_INT_STATUS_INT1; + conf.generic_interrupt = BMA530_GEN_INT_1; + set_conf.generic_interrupt = BMA530_GEN_INT_1; + + /* Assign context parameter selection */ + enum bma5_context context; + context = BMA5_SMARTPHONE; + + /* Interface reference is given as a parameter + * For I2C : BMA5_I2C_INTF + * For SPI : BMA5_SPI_INTF + */ + rslt = bma5_interface_init(&dev, BMA5_I2C_INTF, context); + bma5_check_rslt("bma5_interface_init", rslt); + + rslt = bma530_init(&dev); + bma5_check_rslt("bma530_init", rslt); + printf("BMA530 Chip ID is 0x%X\n", dev.chip_id); + + printf("Default configurations\n"); + rslt = bma530_get_default_generic_int_config(&conf, n_ints, &dev); + bma5_check_rslt("bma530_get_default_generic_int_config", rslt); + + printf("slope_thres 0x%x\n", conf.gen_int.slope_thres); + printf("comb_sel 0x%x\n", conf.gen_int.comb_sel); + printf("axis_sel 0x%x\n", conf.gen_int.axis_sel); + printf("hysteresis 0x%x\n", conf.gen_int.hysteresis); + printf("criterion_sel 0x%x\n", conf.gen_int.criterion_sel); + printf("acc_ref_up 0x%x\n", conf.gen_int.acc_ref_up); + printf("duration 0x%x\n", conf.gen_int.duration); + printf("wait_time 0x%x\n", conf.gen_int.wait_time); + printf("quiet_time 0x%x\n", conf.gen_int.quiet_time); + printf("ref_acc_x 0x%x\n", conf.gen_int.ref_acc_x); + printf("ref_acc_y 0x%x\n", conf.gen_int.ref_acc_y); + printf("ref_acc_z 0x%x\n", conf.gen_int.ref_acc_z); + + set_conf.gen_int.slope_thres = 0xA; + set_conf.gen_int.comb_sel = 0x0; + set_conf.gen_int.axis_sel = 0x7; + set_conf.gen_int.hysteresis = 0x2; + set_conf.gen_int.criterion_sel = 0x1; + set_conf.gen_int.acc_ref_up = 0x1; + set_conf.gen_int.duration = 0xA; + set_conf.gen_int.wait_time = 0x3; + set_conf.gen_int.quiet_time = 0x40; + set_conf.gen_int.ref_acc_x = 0x0; + set_conf.gen_int.ref_acc_y = 0x0; + set_conf.gen_int.ref_acc_z = 0x800; + + rslt = bma530_set_generic_int_config(&set_conf, n_ints, &dev); + bma5_check_rslt("bma530_set_generic_int_config", rslt); + + rslt = bma530_get_feat_eng_gpr_0(&gpr_0, &dev); + bma5_check_rslt("bma530_get_feat_eng_gpr_0", rslt); + + gpr_0.gen_int1_en = BMA5_ENABLE; + + rslt = bma530_set_feat_eng_gpr_0(&gpr_0, &dev); + bma5_check_rslt("bma530_set_feat_eng_gpr_0", rslt); + + rslt = bma5_set_regs(BMA5_REG_FEAT_ENG_GPR_CTRL, &gpr_ctrl_host, 1, &dev); + bma5_check_rslt("bma5_set_regs", rslt); + + rslt = bma530_get_int_map(&int_map, &dev); + bma5_check_rslt("bma530_get_int_map", rslt); + + /* Map generic interrupt 1 */ + int_map.gen_int1_int_map = BMA530_GEN_INT1_INT_MAP_INT1; + rslt = bma530_set_int_map(&int_map, &dev); + bma5_check_rslt("bma530_set_int_map", rslt); + + /* Map hardware interrupt pin configurations */ + rslt = bma5_get_int_conf(&int_config, n_ints, &dev); + bma5_check_rslt("bma5_get_int_conf", rslt); + + int_config.int_conf.int_mode = BMA5_INT1_MODE_LATCHED; + int_config.int_conf.int_od = BMA5_INT1_OD_PUSH_PULL; + int_config.int_conf.int_lvl = BMA5_INT1_LVL_ACTIVE_HIGH; + + rslt = bma5_set_int_conf(&int_config, n_ints, &dev); + bma5_check_rslt("bma5_set_int_conf", rslt); + + printf("Shake the board to get generic interrupt 1 interrupt\n"); + + for (;;) + { + rslt = bma530_get_int_status(&int_status, n_status, &dev); + bma5_check_rslt("bma530_get_int_status", rslt); + + if (int_status.int_status.gen_int1_int_status & BMA5_ENABLE) + { + rslt = bma530_set_int_status(&int_status, n_status, &dev); + bma5_check_rslt("bma530_set_int_status", rslt); + + printf("Generic interrupt 1 interrupt occurred\n"); + + break; + } + } + + bma5_coines_deinit(); + + return rslt; +} diff --git a/examples/generic_interrupt_2/Makefile b/examples/generic_interrupt_2/Makefile new file mode 100644 index 0000000..76b2b29 --- /dev/null +++ b/examples/generic_interrupt_2/Makefile @@ -0,0 +1,18 @@ +COINES_INSTALL_PATH ?= ../../../.. + +EXAMPLE_FILE ?= generic_interrupt_2.c + +API_LOCATION ?= ../.. +COMMON_LOCATION ?= .. + +C_SRCS += \ +$(API_LOCATION)/bma5.c \ +$(API_LOCATION)/bma530.c \ +$(API_LOCATION)/bma530_features.c \ +$(COMMON_LOCATION)/common/common.c + +INCLUDEPATHS += \ +$(API_LOCATION) \ +$(COMMON_LOCATION)/common + +include $(COINES_INSTALL_PATH)/coines.mk diff --git a/examples/generic_interrupt_2/generic_interrupt_2.c b/examples/generic_interrupt_2/generic_interrupt_2.c new file mode 100644 index 0000000..106f97c --- /dev/null +++ b/examples/generic_interrupt_2/generic_interrupt_2.c @@ -0,0 +1,158 @@ +/** + * Copyright (c) 2024 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. + * + */ + +#include +#include "common.h" +#include "bma530_features.h" + +/******************************************************************************/ +int main(void) +{ + struct bma5_dev dev; + int8_t rslt; + uint8_t gpr_ctrl_host = BMA5_ENABLE; + uint8_t n_ints = 1; + uint8_t n_status = 1; + + struct bma530_int_map int_map; + struct bma5_int_conf_types int_config; + struct bma530_generic_interrupt_types conf, set_conf; + struct bma530_int_status_types int_status; + struct bma530_feat_eng_gpr_0 gpr_0; + + int_config.int_src = BMA5_INT_2; + int_status.int_src = BMA530_INT_STATUS_INT2; + conf.generic_interrupt = BMA530_GEN_INT_2; + set_conf.generic_interrupt = BMA530_GEN_INT_2; + + /* Assign context parameter selection */ + enum bma5_context context; + context = BMA5_SMARTPHONE; + + /* Interface reference is given as a parameter + * For I2C : BMA5_I2C_INTF + * For SPI : BMA5_SPI_INTF + */ + rslt = bma5_interface_init(&dev, BMA5_I2C_INTF, context); + bma5_check_rslt("bma5_interface_init", rslt); + + rslt = bma530_init(&dev); + bma5_check_rslt("bma530_init", rslt); + printf("BMA530 Chip ID is 0x%X\n", dev.chip_id); + + printf("Default configurations\n"); + rslt = bma530_get_default_generic_int_config(&conf, n_ints, &dev); + bma5_check_rslt("bma530_get_default_generic_int_config", rslt); + + printf("slope_thres 0x%x\n", conf.gen_int.slope_thres); + printf("comb_sel 0x%x\n", conf.gen_int.comb_sel); + printf("axis_sel 0x%x\n", conf.gen_int.axis_sel); + printf("hysteresis 0x%x\n", conf.gen_int.hysteresis); + printf("criterion_sel 0x%x\n", conf.gen_int.criterion_sel); + printf("acc_ref_up 0x%x\n", conf.gen_int.acc_ref_up); + printf("duration 0x%x\n", conf.gen_int.duration); + printf("wait_time 0x%x\n", conf.gen_int.wait_time); + printf("quiet_time 0x%x\n", conf.gen_int.quiet_time); + printf("ref_acc_x 0x%x\n", conf.gen_int.ref_acc_x); + printf("ref_acc_y 0x%x\n", conf.gen_int.ref_acc_y); + printf("ref_acc_z 0x%x\n", conf.gen_int.ref_acc_z); + + set_conf.gen_int.slope_thres = 0xA; + set_conf.gen_int.comb_sel = 0x1; + set_conf.gen_int.axis_sel = 0x7; + set_conf.gen_int.hysteresis = 0x2; + set_conf.gen_int.criterion_sel = 0x0; + set_conf.gen_int.acc_ref_up = 0x1; + set_conf.gen_int.duration = 0xA; + set_conf.gen_int.wait_time = 0x3; + set_conf.gen_int.quiet_time = 0x40; + set_conf.gen_int.ref_acc_x = 0x0; + set_conf.gen_int.ref_acc_y = 0x0; + set_conf.gen_int.ref_acc_z = 0x800; + + rslt = bma530_set_generic_int_config(&set_conf, n_ints, &dev); + bma5_check_rslt("bma530_set_generic_int_config", rslt); + + rslt = bma530_get_feat_eng_gpr_0(&gpr_0, &dev); + bma5_check_rslt("bma530_get_feat_eng_gpr_0", rslt); + + gpr_0.gen_int2_en = BMA5_ENABLE; + + rslt = bma530_set_feat_eng_gpr_0(&gpr_0, &dev); + bma5_check_rslt("bma530_set_feat_eng_gpr_0", rslt); + + rslt = bma5_set_regs(BMA5_REG_FEAT_ENG_GPR_CTRL, &gpr_ctrl_host, 1, &dev); + bma5_check_rslt("bma5_set_regs", rslt); + + rslt = bma530_get_int_map(&int_map, &dev); + bma5_check_rslt("bma530_get_int_map", rslt); + + /* Map generic interrupt 2 */ + int_map.gen_int2_int_map = BMA530_GEN_INT2_INT_MAP_INT2; + rslt = bma530_set_int_map(&int_map, &dev); + bma5_check_rslt("bma530_set_int_map", rslt); + + /* Map hardware interrupt pin configurations */ + rslt = bma5_get_int_conf(&int_config, n_ints, &dev); + bma5_check_rslt("bma5_get_int_conf", rslt); + + int_config.int_conf.int_mode = BMA5_INT1_MODE_LATCHED; + int_config.int_conf.int_od = BMA5_INT1_OD_PUSH_PULL; + int_config.int_conf.int_lvl = BMA5_INT1_LVL_ACTIVE_HIGH; + + rslt = bma5_set_int_conf(&int_config, n_ints, &dev); + bma5_check_rslt("bma5_set_int_conf", rslt); + + printf("Do not shake the board to get interrupt for generic interrupt 2\n"); + + for (;;) + { + rslt = bma530_get_int_status(&int_status, n_status, &dev); + bma5_check_rslt("bma530_get_int_status_int", rslt); + + if (int_status.int_status.gen_int2_int_status & BMA5_ENABLE) + { + rslt = bma530_set_int_status(&int_status, n_status, &dev); + bma5_check_rslt("bma530_set_int_status_int", rslt); + + printf("Generic interrupt 2 interrupt occurred\n"); + + break; + } + } + + bma5_coines_deinit(); + + return rslt; +} diff --git a/examples/generic_interrupt_3/Makefile b/examples/generic_interrupt_3/Makefile new file mode 100644 index 0000000..15ff58e --- /dev/null +++ b/examples/generic_interrupt_3/Makefile @@ -0,0 +1,18 @@ +COINES_INSTALL_PATH ?= ../../../.. + +EXAMPLE_FILE ?= generic_interrupt_3.c + +API_LOCATION ?= ../.. +COMMON_LOCATION ?= .. + +C_SRCS += \ +$(API_LOCATION)/bma5.c \ +$(API_LOCATION)/bma530.c \ +$(API_LOCATION)/bma530_features.c \ +$(COMMON_LOCATION)/common/common.c + +INCLUDEPATHS += \ +$(API_LOCATION) \ +$(COMMON_LOCATION)/common + +include $(COINES_INSTALL_PATH)/coines.mk diff --git a/examples/generic_interrupt_3/generic_interrupt_3.c b/examples/generic_interrupt_3/generic_interrupt_3.c new file mode 100644 index 0000000..3172cf0 --- /dev/null +++ b/examples/generic_interrupt_3/generic_interrupt_3.c @@ -0,0 +1,158 @@ +/** + * Copyright (c) 2024 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. + * + */ + +#include +#include "common.h" +#include "bma530_features.h" + +/******************************************************************************/ +int main(void) +{ + struct bma5_dev dev; + int8_t rslt; + uint8_t gpr_ctrl_host = BMA5_ENABLE; + uint8_t n_ints = 1; + uint8_t n_status = 1; + + struct bma530_int_map int_map; + struct bma5_int_conf_types int_config; + struct bma530_generic_interrupt_types conf, set_conf; + struct bma530_int_status_types int_status; + struct bma530_feat_eng_gpr_0 gpr_0; + + int_config.int_src = BMA5_INT_1; + int_status.int_src = BMA530_INT_STATUS_INT1; + conf.generic_interrupt = BMA530_GEN_INT_3; + set_conf.generic_interrupt = BMA530_GEN_INT_3; + + /* Assign context parameter selection */ + enum bma5_context context; + context = BMA5_SMARTPHONE; + + /* Interface reference is given as a parameter + * For I2C : BMA5_I2C_INTF + * For SPI : BMA5_SPI_INTF + */ + rslt = bma5_interface_init(&dev, BMA5_I2C_INTF, context); + bma5_check_rslt("bma5_interface_init", rslt); + + rslt = bma530_init(&dev); + bma5_check_rslt("bma530_init", rslt); + printf("BMA530 Chip ID is 0x%X\n", dev.chip_id); + + printf("Default configurations\n"); + rslt = bma530_get_generic_int_config(&conf, n_ints, &dev); + bma5_check_rslt("bma530_get_generic_int_config", rslt); + + printf("slope_thres 0x%x\n", conf.gen_int.slope_thres); + printf("comb_sel 0x%x\n", conf.gen_int.comb_sel); + printf("axis_sel 0x%x\n", conf.gen_int.axis_sel); + printf("hysteresis 0x%x\n", conf.gen_int.hysteresis); + printf("criterion_sel 0x%x\n", conf.gen_int.criterion_sel); + printf("acc_ref_up 0x%x\n", conf.gen_int.acc_ref_up); + printf("duration 0x%x\n", conf.gen_int.duration); + printf("wait_time 0x%x\n", conf.gen_int.wait_time); + printf("quiet_time 0x%x\n", conf.gen_int.quiet_time); + printf("ref_acc_x 0x%x\n", conf.gen_int.ref_acc_x); + printf("ref_acc_y 0x%x\n", conf.gen_int.ref_acc_y); + printf("ref_acc_z 0x%x\n", conf.gen_int.ref_acc_z); + + set_conf.gen_int.slope_thres = 0x82; + set_conf.gen_int.comb_sel = 0x1; + set_conf.gen_int.axis_sel = 0x7; + set_conf.gen_int.hysteresis = 0x8; + set_conf.gen_int.criterion_sel = 0x0; + set_conf.gen_int.acc_ref_up = 0x2; + set_conf.gen_int.duration = 0x3; + set_conf.gen_int.wait_time = 0x2; + set_conf.gen_int.quiet_time = 0x40; + set_conf.gen_int.ref_acc_x = 0x0; + set_conf.gen_int.ref_acc_y = 0x0; + set_conf.gen_int.ref_acc_z = 0x0; + + rslt = bma530_set_generic_int_config(&set_conf, n_ints, &dev); + bma5_check_rslt("bma530_set_generic_int_config", rslt); + + rslt = bma530_get_feat_eng_gpr_0(&gpr_0, &dev); + bma5_check_rslt("bma530_get_feat_eng_gpr_0", rslt); + + gpr_0.gen_int3_en = BMA5_ENABLE; + + rslt = bma530_set_feat_eng_gpr_0(&gpr_0, &dev); + bma5_check_rslt("bma530_set_feat_eng_gpr_0", rslt); + + rslt = bma5_set_regs(BMA5_REG_FEAT_ENG_GPR_CTRL, &gpr_ctrl_host, 1, &dev); + bma5_check_rslt("bma5_set_regs", rslt); + + rslt = bma530_get_int_map(&int_map, &dev); + bma5_check_rslt("bma530_get_int_map", rslt); + + /* Map generic interrupt 3 */ + int_map.gen_int3_int_map = BMA530_GEN_INT3_INT_MAP_INT1; + rslt = bma530_set_int_map(&int_map, &dev); + bma5_check_rslt("bma530_set_int_map", rslt); + + /* Map hardware interrupt pin configurations */ + rslt = bma5_get_int_conf(&int_config, n_ints, &dev); + bma5_check_rslt("bma5_get_int_conf", rslt); + + int_config.int_conf.int_mode = BMA5_INT1_MODE_LATCHED; + int_config.int_conf.int_od = BMA5_INT1_OD_PUSH_PULL; + int_config.int_conf.int_lvl = BMA5_INT1_LVL_ACTIVE_HIGH; + + rslt = bma5_set_int_conf(&int_config, n_ints, &dev); + bma5_check_rslt("bma5_set_int_conf", rslt); + + printf("Drop the board to get generic interrupt 3 interrupt\n"); + + for (;;) + { + rslt = bma530_get_int_status(&int_status, n_status, &dev); + bma5_check_rslt("bma530_get_int_status", rslt); + + if (int_status.int_status.gen_int3_int_status & BMA5_ENABLE) + { + rslt = bma530_set_int_status(&int_status, n_status, &dev); + bma5_check_rslt("bma530_set_int_status", rslt); + + printf("Generic interrupt 3 interrupt occurred\n"); + + break; + } + } + + bma5_coines_deinit(); + + return rslt; +} diff --git a/examples/orientation/Makefile b/examples/orientation/Makefile new file mode 100644 index 0000000..b04172a --- /dev/null +++ b/examples/orientation/Makefile @@ -0,0 +1,18 @@ +COINES_INSTALL_PATH ?= ../../../.. + +EXAMPLE_FILE ?= orientation.c + +API_LOCATION ?= ../.. +COMMON_LOCATION ?= .. + +C_SRCS += \ +$(API_LOCATION)/bma5.c \ +$(API_LOCATION)/bma530.c \ +$(API_LOCATION)/bma530_features.c \ +$(COMMON_LOCATION)/common/common.c + +INCLUDEPATHS += \ +$(API_LOCATION) \ +$(COMMON_LOCATION)/common + +include $(COINES_INSTALL_PATH)/coines.mk diff --git a/examples/orientation/orientation.c b/examples/orientation/orientation.c new file mode 100644 index 0000000..74ffc1d --- /dev/null +++ b/examples/orientation/orientation.c @@ -0,0 +1,213 @@ +/** + * Copyright (c) 2024 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. + * + */ + +#include +#include "common.h" +#include "bma530_features.h" + +/******************************************************************************/ +/*! Macro definition */ + +/* Name Orientation output macros */ +#define FACE_UP UINT8_C(0x00) +#define FACE_DOWN UINT8_C(0x01) + +#define PORTRAIT_UP_RIGHT UINT8_C(0x00) +#define LANDSCAPE_LEFT UINT8_C(0x01) +#define PORTRAIT_UP_DOWN UINT8_C(0x02) +#define LANDSCAPE_RIGHT UINT8_C(0x03) + +/******************************************************************************/ +int main(void) +{ + struct bma5_dev dev; + int8_t rslt; + uint8_t n_ints = 1; + uint8_t n_status = 1; + uint8_t gpr_ctrl_host = BMA5_ENABLE; + struct bma530_int_map int_map = { 0 }; + struct bma5_int_conf_types int_config = { 0 }; + struct bma530_orient conf = { 0 }; + struct bma530_orient get_conf = { 0 }; + struct bma530_feat_eng_gpr_0 gpr_0 = { 0 }; + struct bma530_int_status_types int_status = { 0 }; + struct bma530_feat_eng_feat_out feat_out = { 0 }; + + /* Variables to store the output of orientation. */ + uint8_t orientation_out = 0; + uint8_t orientation_faceup_down = 0; + + int_config.int_src = BMA5_INT_2; + int_status.int_src = BMA530_INT_STATUS_INT2; + + /* Assign context parameter selection */ + enum bma5_context context; + context = BMA5_SMARTPHONE; + + /* Interface reference is given as a parameter + * For I2C : BMA5_I2C_INTF + * For SPI : BMA5_SPI_INTF + */ + rslt = bma5_interface_init(&dev, BMA5_SPI_INTF, context); + bma5_check_rslt("bma5_interface_init", rslt); + + rslt = bma530_init(&dev); + bma5_check_rslt("bma530_init", rslt); + printf("BMA530 Chip ID is 0x%X\n", dev.chip_id); + + printf("\nDefault configurations\n\n"); + rslt = bma530_get_orient_config(&conf, &dev); + bma5_check_rslt("bma530_get_orient_config", rslt); + + printf("blocking :: 0x%x\n", conf.blocking); + printf("hold_time :: 0x%x\n", conf.hold_time); + printf("hysteresis :: 0x%x\n", conf.hysteresis); + printf("mode :: 0x%x\n", conf.mode); + printf("slope_thres :: 0x%x\n", conf.slope_thres); + printf("theta :: 0x%x\n", conf.theta); + printf("ud_en :: 0x%x\n", conf.ud_en); + + conf.hold_time = 0x5; + conf.hysteresis = 0x20; + conf.slope_thres = 0xCD; + conf.theta = 0x27; + + conf.ud_en = 1; + conf.blocking = 0; + conf.mode = 0; + rslt = bma530_set_orient_config(&conf, &dev); + bma5_check_rslt("bma530_set_orient_config", rslt); + + printf("\n\nSet Upside down orientation detection : %d\n", conf.ud_en); + printf("Set Blocking : %d\n", conf.blocking); + printf("Set Mode : %d\n", conf.mode); + + rslt = bma530_get_orient_config(&get_conf, &dev); + bma5_check_rslt("bma530_get_orient_config", rslt); + + printf("\n\nGet Upside down orientation detection : %d\n", get_conf.ud_en); + printf("Get Blocking : %d\n", get_conf.blocking); + printf("Get Mode : %d\n", get_conf.mode); + + rslt = bma530_get_feat_eng_gpr_0(&gpr_0, &dev); + bma5_check_rslt("bma530_get_feat_eng_gpr_0", rslt); + + gpr_0.orient_en = 0x01; + + rslt = bma530_set_feat_eng_gpr_0(&gpr_0, &dev); + bma5_check_rslt("bma530_set_feat_eng_gpr_0", rslt); + + rslt = bma5_set_regs(BMA5_REG_FEAT_ENG_GPR_CTRL, &gpr_ctrl_host, 1, &dev); + bma5_check_rslt("bma5_set_regs", rslt); + + rslt = bma530_get_int_map(&int_map, &dev); + bma5_check_rslt("bma530_get_int_map", rslt); + + /* Map orientation */ + int_map.orient_int_map = BMA530_ORIENT_INT_MAP_INT2; + rslt = bma530_set_int_map(&int_map, &dev); + bma5_check_rslt("bma530_set_int_map", rslt); + + /* Map hardware interrupt pin configurations */ + rslt = bma5_get_int_conf(&int_config, n_ints, &dev); + bma5_check_rslt("bma5_get_int_conf", rslt); + + int_config.int_conf.int_mode = BMA5_INT2_MODE_PULSED_SHORT; + int_config.int_conf.int_od = BMA5_INT2_OD_PUSH_PULL; + int_config.int_conf.int_lvl = BMA5_INT2_LVL_ACTIVE_LOW; + + rslt = bma5_set_int_conf(&int_config, n_ints, &dev); + bma5_check_rslt("bma5_set_int_conf", rslt); + + printf("\nMove the board to get orientation interrupt\n"); + + for (;;) + { + rslt = bma530_get_int_status(&int_status, n_status, &dev); + bma5_check_rslt("bma530_get_int_status", rslt); + + if (int_status.int_status.orient_int_status & BMA5_ENABLE) + { + printf("\nOrientation interrupt occurred\n"); + + rslt = bma530_get_feat_eng_feature_out(&feat_out, &dev); + bma5_check_rslt("bma530_get_feat_eng_feature_out", rslt); + + orientation_out = feat_out.orientation_portrait_landscape; + orientation_faceup_down = feat_out.orientation_face_up_down; + + printf("Orientation output : %d \n", orientation_out); + printf("Orientation face-up/down output : %d\n", orientation_faceup_down); + + rslt = bma530_set_int_status(&int_status, n_status, &dev); + bma5_check_rslt("bma530_set_int_status", rslt); + + switch (orientation_out) + { + case LANDSCAPE_LEFT: + printf("\nOrientation state is landscape left\n"); + break; + case LANDSCAPE_RIGHT: + printf("\nOrientation state is landscape right\n"); + break; + case PORTRAIT_UP_DOWN: + printf("\nOrientation state is portrait upside down\n"); + break; + case PORTRAIT_UP_RIGHT: + printf("\nOrientation state is portrait upright\n"); + break; + default: + printf("\nInvalid"); + } + + switch (orientation_faceup_down) + { + case FACE_UP: + printf("\nOrientation state is face up\n"); + break; + case FACE_DOWN: + printf("\nOrientation state is face down\n"); + break; + default: + printf("\nInvalid"); + } + + break; + } + } + + bma5_coines_deinit(); + + return rslt; +} diff --git a/examples/self_test/Makefile b/examples/self_test/Makefile new file mode 100644 index 0000000..d7eb5db --- /dev/null +++ b/examples/self_test/Makefile @@ -0,0 +1,18 @@ +COINES_INSTALL_PATH ?= ../../../.. + +EXAMPLE_FILE ?= self_test.c + +API_LOCATION ?= ../.. +COMMON_LOCATION ?= .. + +C_SRCS += \ +$(API_LOCATION)/bma5.c \ +$(API_LOCATION)/bma530.c \ +$(API_LOCATION)/bma530_features.c \ +$(COMMON_LOCATION)/common/common.c + +INCLUDEPATHS += \ +$(API_LOCATION) \ +$(COMMON_LOCATION)/common + +include $(COINES_INSTALL_PATH)/coines.mk diff --git a/examples/self_test/self_test.c b/examples/self_test/self_test.c new file mode 100644 index 0000000..1109a8f --- /dev/null +++ b/examples/self_test/self_test.c @@ -0,0 +1,413 @@ +/** + * Copyright (c) 2024 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. + * + */ + +#include +#include + +#include "common.h" +#include "bma530_features.h" + +/******************************************************************************/ +/*! Static Function Declaration */ + +/*! + * @brief This internal API converts raw sensor values(LSB) to mg. + * + * @param[in] val : Raw sensor value. + * @param[in] g_range : Accel Range selected (2G, 4G, 8G, 16G). + * @param[in] bit_width : Resolution of the sensor. + * + * @return Accel values in mg + * + */ +static float lsb_to_mg(int16_t val, float g_range, uint8_t bit_width); + +/*! + * @brief This internal API reads accel samples based on data ready interrupt + * + * @param[in] count : Stores count of accel samples to be read. + * @param[in] sens_data_x : Stores average value of accel x axis data. + * @param[in] sens_data_y : Stores average value of accel y axis data. + * @param[in] sens_data_z : Stores average value of accel z axis data. + * @param[in] dev : Structure instance of bma5_dev. + * + * return Status of API + */ +static int8_t read_accel_samples(uint8_t count, + int32_t *sens_data_x, + int32_t *sens_data_y, + int32_t *sens_data_z, + struct bma5_dev *dev); + +/******************************************************************************/ +int main(void) +{ + int8_t rslt; + struct bma5_dev dev; + uint8_t count; + uint8_t int_conf, get_int_conf; + uint8_t int_map, get_int_map; + uint8_t gpr_ctrl_host = BMA5_ENABLE; + uint8_t sensor_ctrl, get_sensor_ctrl; + int32_t pos_exc_x, pos_exc_y, pos_exc_z; + int32_t neg_exc_x, neg_exc_y, neg_exc_z; + int32_t diff_x, diff_y, diff_z; + int32_t sens_data_pos_exc_x = 0, sens_data_pos_exc_y = 0, sens_data_pos_exc_z = 0; + int32_t sens_data_neg_exc_x = 0, sens_data_neg_exc_y = 0, sens_data_neg_exc_z = 0; + + uint8_t acc_self_test, get_acc_self_test; + struct bma530_feat_eng_gpr_0 config = { 0 }; + struct bma530_int_map map_config = { 0 }; + + enum bma5_context context; + + /* Assign context parameter selection */ + context = BMA5_SMARTPHONE; + + /* Interface reference is given as a parameter + * For I2C : BMA5_I2C_INTF + * For SPI : BMA5_SPI_INTF + */ + rslt = bma5_interface_init(&dev, BMA5_I2C_INTF, context); + bma5_check_rslt("bma5_interface_init", rslt); + + rslt = bma530_init(&dev); + bma5_check_rslt("bma530_init", rslt); + + /********************************************************************************/ + + printf("# *******************************************************************************\n"); + printf("Disable features and interrupts\n"); + printf("***********************************************************************************\n"); + + rslt = bma530_set_feat_eng_gpr_0(&config, &dev); + bma5_check_rslt("bma530_set_feat_eng_gpr_0", rslt); + + rslt = bma5_set_regs(BMA5_REG_FEAT_ENG_GPR_CTRL, &gpr_ctrl_host, 1, &dev); + bma5_check_rslt("bma5_set_regs", rslt); + + rslt = bma530_get_feat_eng_gpr_0(&config, &dev); + bma5_check_rslt("bma530_get_feat_eng_gpr_0", rslt); + + printf("acc_foc_en : 0x%X\n", config.acc_foc_en); + printf("gen_int1_en : 0x%X\n", config.gen_int1_en); + printf("gen_int2_en : 0x%X\n", config.gen_int2_en); + printf("gen_int3_en : 0x%X\n", config.gen_int3_en); + + rslt = bma530_set_int_map(&map_config, &dev); + bma5_check_rslt("bma530_set_int_map", rslt); + + rslt = bma530_get_int_map(&map_config, &dev); + bma5_check_rslt("bma530_get_int_map", rslt); + + printf("acc_drdy_int_map : 0x%X\n", map_config.acc_drdy_int_map); + printf("fifo_full_int_map : 0x%X\n", map_config.fifo_full_int_map); + printf("fifo_wm_int_map : 0x%X\n", map_config.fifo_wm_int_map); + printf("gen_int1_int_map : 0x%X\n", map_config.gen_int1_int_map); + printf("gen_int2_int_map : 0x%X\n", map_config.gen_int2_int_map); + printf("gen_int3_int_map : 0x%X\n", map_config.gen_int3_int_map); + printf("feat_eng_err_int_map : 0x%X\n", map_config.feat_eng_err_int_map); + + printf("\n# *******************************************************************************\n"); + printf("Activate Self-test\n"); + printf("***********************************************************************************\n"); + + rslt = bma5_activate_self_test(&dev); + bma5_check_rslt("bma5_activate_self_test", rslt); + + /********************************************************************************/ + + printf("\n# Write Reg INT1_CONF(0x34) with 0x01 (latch)\n"); + + int_conf = 0x01; + rslt = bma5_set_regs(BMA5_REG_INT1_CONF, &int_conf, 1, &dev); + bma5_check_rslt("bma5_set_regs", rslt); + + rslt = bma5_get_regs(BMA5_REG_INT1_CONF, &get_int_conf, 1, &dev); + bma5_check_rslt("bma5_get_regs", rslt); + + printf("Value read from Reg INT1_CONF(0x34) : 0x%x\n", get_int_conf); + + /********************************************************************************/ + + printf("*******************************************************************************\n"); + printf("\n# Write Reg INT_MAP0(0x36) with 0x01 (Acc data ready mapped to INT1)\n"); + + int_map = 0x01; + rslt = bma5_set_regs(BMA530_REG_INT_MAP_0, &int_map, 1, &dev); + bma5_check_rslt("bma5_set_regs", rslt); + + rslt = bma5_get_regs(BMA530_REG_INT_MAP_0, &get_int_map, 1, &dev); + bma5_check_rslt("bma5_set_regs", rslt); + + printf("Value read from Reg INT_MAP0(0x36) : 0x%x\n", get_int_map); + + /********************************************************************************/ + + printf("\n# *******************************************************************************\n"); + printf("Self-Test with negative excitation\n"); + printf("***********************************************************************************\n"); + + rslt = bma5_self_test_neg_excitation(&dev); + bma5_check_rslt("bma5_self_test_neg_excitation", rslt); + + /********************************************************************************/ + + printf("\n# Read accel data based on data ready interrupt\n"); + + count = 4; + + rslt = read_accel_samples(count, &sens_data_neg_exc_x, &sens_data_neg_exc_y, &sens_data_neg_exc_z, &dev); + bma5_check_rslt("read_accel_samples", rslt); + + printf("*******************************************************************************\n"); + printf("Mean LSB values for self-test with negative excitation (4 samples)\n"); + printf("*******************************************************************************\n"); + + /* Negative excitation self-test values in LSB */ + neg_exc_x = (long int)(sens_data_neg_exc_x / 4); + neg_exc_y = (long int)(sens_data_neg_exc_y / 4); + neg_exc_z = (long int)(sens_data_neg_exc_z / 4); + + /* Print the data in LSB */ + printf("Acc_LSB_X : %ld, Acc_LSB_Y : %ld, Acc_LSB_Z : %ld\n", + (long int)neg_exc_x, + (long int)neg_exc_y, + (long int)neg_exc_z); + + printf("*******************************************************************************\n"); + + /********************************************************************************/ + + printf("\n# *******************************************************************************\n"); + printf("Self-Test with positive excitation\n"); + printf("***********************************************************************************\n"); + + rslt = bma5_self_test_pos_excitation(&dev); + bma5_check_rslt("bma5_self_test_pos_excitation\n", rslt); + + /********************************************************************************/ + + printf("\n# Read accel data based on data ready interrupt\n"); + + count = 4; + + rslt = read_accel_samples(count, &sens_data_pos_exc_x, &sens_data_pos_exc_y, &sens_data_pos_exc_z, &dev); + bma5_check_rslt("read_accel_samples", rslt); + + printf("*******************************************************************************\n"); + printf("Mean LSB values for self-test with positive excitation (4 samples)\n"); + printf("*******************************************************************************\n"); + + /* Positive excitation self-test values in LSB */ + pos_exc_x = (long int)(sens_data_pos_exc_x / 4); + pos_exc_y = (long int)(sens_data_pos_exc_y / 4); + pos_exc_z = (long int)(sens_data_pos_exc_z / 4); + + /* Print the data in LSB */ + printf("Acc_LSB_X : %ld, Acc_LSB_Y : %ld, Acc_LSB_Z : %ld\n", + (long int)pos_exc_x, + (long int)pos_exc_y, + (long int)pos_exc_z); + + /********************************************************************************/ + + printf("\n# *******************************************************************************\n"); + printf("Disable self-test and reset signal path\n"); + + acc_self_test = 0x00; + rslt = bma5_set_regs(BMA5_REG_ACC_SELF_TEST, &acc_self_test, 1, &dev); + bma5_check_rslt("bma5_set_regs", rslt); + + rslt = bma5_get_regs(BMA5_REG_ACC_SELF_TEST, &get_acc_self_test, 1, &dev); + bma5_check_rslt("bma5_get_regs", rslt); + + printf("(Disable Self-test) Value read from Reg ACC_SELF_TEST(0x76) : 0x%x\n", get_acc_self_test); + + /* Disable accelerometer */ + sensor_ctrl = BMA5_SENSOR_CTRL_DISABLE; + + rslt = bma5_set_acc_conf_0(sensor_ctrl, &dev); + bma5_check_rslt("bma5_set_acc_conf_0", rslt); + + rslt = bma5_get_acc_conf_0(&get_sensor_ctrl, &dev); + bma5_check_rslt("bma5_get_acc_conf_0", rslt); + + printf("(Disable accelerometer) ACC_CONF_0.sensor_ctrl : 0x%x\n", get_sensor_ctrl); + + /* Delay of 50ms */ + dev.delay_us(BMA5_SELF_TEST_ACCEL_DISABLE_DELAY, dev.intf_ptr); + + /* Enable accelerometer */ + sensor_ctrl = BMA5_SENSOR_CTRL_ENABLE; + + rslt = bma5_set_acc_conf_0(sensor_ctrl, &dev); + bma5_check_rslt("bma5_set_acc_conf_0", rslt); + + rslt = bma5_get_acc_conf_0(&get_sensor_ctrl, &dev); + bma5_check_rslt("bma5_get_acc_conf_0", rslt); + + printf("(Enable accelerometer) ACC_CONF_0.sensor_ctrl : 0x%x\n", get_sensor_ctrl); + + /********************************************************************************/ + + printf("*******************************************************************************\n"); + printf("\n# Calculate difference of self-test results\n"); + + diff_x = (long int)(pos_exc_x - neg_exc_x); + diff_y = (long int)(pos_exc_y - neg_exc_y); + diff_z = (long int)(pos_exc_z - neg_exc_z); + + printf("Diff_LSB_X : %ld Diff_LSB_Y : %ld Diff_LSB_Z : %ld\n# ", + (long int)diff_x, + (long int)diff_y, + (long int)diff_z); + + if (diff_x >= BMA5_SELF_TEST_MIN_THRESHOLD_X) + { + printf("\n# Self-test pass for X-axis"); + } + else + { + printf("\n# Self-test fail for X-axis"); + } + + if (diff_y >= BMA5_SELF_TEST_MIN_THRESHOLD_Y) + { + printf("\n# Self-test pass for Y-axis"); + } + else + { + printf("\n# Self-test fail for Y-axis"); + } + + if (diff_z >= BMA5_SELF_TEST_MIN_THRESHOLD_Z) + { + printf("\n# Self-test pass for Z-axis"); + } + else + { + printf("\n# Self-test fail for Z-axis\n# "); + } + + bma5_coines_deinit(); + + return rslt; +} + +/******************************************************************************/ +/*! Static Function Definitions */ + +/*! + * @brief This internal API converts raw sensor values(LSB) to mg. + */ +static float lsb_to_mg(int16_t val, float g_range, uint8_t bit_width) +{ + double power = 2; + + float half_scale = (float)((pow((double)power, (double)bit_width) / 2.0f)); + + return (val * g_range * 1000) / half_scale; +} + +/*! + * @brief This internal API reads accel samples based on data ready interrupt + */ +static int8_t read_accel_samples(uint8_t count, + int32_t *sens_data_x, + int32_t *sens_data_y, + int32_t *sens_data_z, + struct bma5_dev *dev) +{ + int8_t rslt = BMA5_E_COM_FAIL; + struct bma5_sensor_status status; + struct bma530_int_status_types int_status = { 0 }; + struct bma5_accel sens_data = { 0 }; + uint8_t n_status = 1; + float x = 0, y = 0, z = 0; + + int_status.int_src = BMA530_INT_STATUS_INT1; + + printf("\nCount, Accel_LSB_X, Accel_LSB_Y, Accel_LSB_Z, Acc_mg_X, Acc_mg_Y, Acc_mg_Z\n"); + + while (count >= 1) + { + /* Get accel data ready status */ + rslt = bma5_get_sensor_status(&status, dev); + bma5_check_rslt("bma5_get_sensor_status", rslt); + + if (status.acc_data_rdy & BMA5_ENABLE) + { + /* Get accel data ready interrupt status */ + rslt = bma530_get_int_status(&int_status, n_status, dev); + bma5_check_rslt("bma530_get_int_status", rslt); + + if (int_status.int_status.acc_drdy_int_status & BMA530_ACC_DRDY_INT_STATUS_MSK) + { + rslt = bma5_set_sensor_status(&status, dev); + bma5_check_rslt("bma5_set_sensor_status", rslt); + + rslt = bma530_set_int_status(&int_status, n_status, dev); + bma5_check_rslt("bma530_set_int_status", rslt); + + /* Get accel data and sensortime */ + rslt = bma5_get_acc(&sens_data, dev); + bma5_check_rslt("bma5_get_acc", rslt); + + (*sens_data_x) += sens_data.x; + (*sens_data_y) += sens_data.y; + (*sens_data_z) += sens_data.z; + + /* Converting lsb to mg for 16 bit resolution at 8G range */ + x = lsb_to_mg(sens_data.x, (float)8, BMA5_16_BIT_RESOLUTION); + y = lsb_to_mg(sens_data.y, (float)8, BMA5_16_BIT_RESOLUTION); + z = lsb_to_mg(sens_data.z, (float)8, BMA5_16_BIT_RESOLUTION); + + /* Print the data in mg */ + printf("%d, %d, %d, %d, %4.2f, %4.2f, %4.2f\n", + count, + sens_data.x, + sens_data.y, + sens_data.z, + x, + y, + z); + + count--; + } + } + } + + return rslt; +} diff --git a/examples/sig_motion/Makefile b/examples/sig_motion/Makefile new file mode 100644 index 0000000..c4ae7d7 --- /dev/null +++ b/examples/sig_motion/Makefile @@ -0,0 +1,18 @@ +COINES_INSTALL_PATH ?= ../../../.. + +EXAMPLE_FILE ?= sig_motion.c + +API_LOCATION ?= ../.. +COMMON_LOCATION ?= .. + +C_SRCS += \ +$(API_LOCATION)/bma5.c \ +$(API_LOCATION)/bma530.c \ +$(API_LOCATION)/bma530_features.c \ +$(COMMON_LOCATION)/common/common.c + +INCLUDEPATHS += \ +$(API_LOCATION) \ +$(COMMON_LOCATION)/common + +include $(COINES_INSTALL_PATH)/coines.mk diff --git a/examples/sig_motion/sig_motion.c b/examples/sig_motion/sig_motion.c new file mode 100644 index 0000000..2ea3d56 --- /dev/null +++ b/examples/sig_motion/sig_motion.c @@ -0,0 +1,141 @@ +/** + * Copyright (c) 2024 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. + * + */ + +#include +#include "common.h" +#include "bma530_features.h" + +/******************************************************************************/ +int main(void) +{ + struct bma5_dev dev; + int8_t rslt; + uint8_t gpr_ctrl_host = BMA5_ENABLE; + uint8_t n_ints = 1; + uint8_t n_status = 1; + struct bma530_int_map int_map = { 0 }; + struct bma5_int_conf_types int_config = { 0 }; + struct bma530_sig_motion conf = { 0 }; + struct bma530_feat_eng_gpr_0 gpr_0 = { 0 }; + struct bma530_int_status_types int_status = { 0 }; + + int_config.int_src = BMA5_INT_1; + int_status.int_src = BMA530_INT_STATUS_INT1; + + /* Assign context parameter selection */ + enum bma5_context context; + context = BMA5_SMARTPHONE; + + /* Interface reference is given as a parameter + * For I2C : BMA5_I2C_INTF + * For SPI : BMA5_SPI_INTF + */ + rslt = bma5_interface_init(&dev, BMA5_SPI_INTF, context); + bma5_check_rslt("bma5_interface_init", rslt); + + rslt = bma530_init(&dev); + bma5_check_rslt("bma530_init", rslt); + printf("BMA530 Chip ID is 0x%X\n", dev.chip_id); + + printf("\nDefault configurations\n\n"); + rslt = bma530_get_default_sig_motion_config(&conf, &dev); + bma5_check_rslt("bma530_get_default_sig_motion_config", rslt); + + printf("block_size :: 0x%x\n", conf.block_size); + printf("mcr_max :: 0x%x\n", conf.mcr_max); + printf("mcr_min :: 0x%x\n", conf.mcr_min); + printf("p2p_max :: 0x%x\n", conf.p2p_max); + printf("p2p_min :: 0x%x\n", conf.p2p_min); + + conf.block_size = 0xFA; + conf.mcr_max = 0x11; + conf.mcr_min = 0x11; + conf.p2p_max = 0x253; + conf.p2p_min = 0x26; + + rslt = bma530_set_sig_motion_config(&conf, &dev); + bma5_check_rslt("bma530_set_sig_motion_config", rslt); + + rslt = bma530_get_feat_eng_gpr_0(&gpr_0, &dev); + bma5_check_rslt("bma530_get_feat_eng_gpr_0", rslt); + + gpr_0.sig_mo_en = BMA5_ENABLE; + + rslt = bma530_set_feat_eng_gpr_0(&gpr_0, &dev); + bma5_check_rslt("bma530_set_feat_eng_gpr_0", rslt); + + rslt = bma5_set_regs(BMA5_REG_FEAT_ENG_GPR_CTRL, &gpr_ctrl_host, 1, &dev); + bma5_check_rslt("bma5_set_regs", rslt); + + rslt = bma530_get_int_map(&int_map, &dev); + bma5_check_rslt("bma530_get_int_map", rslt); + + /* Map sig motion */ + int_map.sig_mo_int_map = BMA530_SIG_MO_INT_MAP_INT1; + rslt = bma530_set_int_map(&int_map, &dev); + bma5_check_rslt("bma530_set_int_map", rslt); + + /* Map hardware interrupt pin configurations */ + rslt = bma5_get_int_conf(&int_config, n_ints, &dev); + bma5_check_rslt("bma5_get_int_conf", rslt); + + int_config.int_conf.int_mode = BMA5_INT1_MODE_PULSED_SHORT; + int_config.int_conf.int_od = BMA5_INT1_OD_PUSH_PULL; + int_config.int_conf.int_lvl = BMA5_INT1_LVL_ACTIVE_LOW; + + rslt = bma5_set_int_conf(&int_config, n_ints, &dev); + bma5_check_rslt("bma5_set_int_conf", rslt); + + printf("\nMove the board to get significant motion interrupt\n"); + + for (;;) + { + rslt = bma530_get_int_status(&int_status, n_status, &dev); + bma5_check_rslt("bma530_get_int_status", rslt); + + if (int_status.int_status.sig_mo_int_status & BMA5_ENABLE) + { + rslt = bma530_set_int_status(&int_status, n_status, &dev); + bma5_check_rslt("bma530_set_int_status", rslt); + + printf("Significant motion interrupt occurred\n"); + + break; + } + } + + bma5_coines_deinit(); + + return rslt; +} diff --git a/examples/step_activity/Makefile b/examples/step_activity/Makefile new file mode 100644 index 0000000..e1d4612 --- /dev/null +++ b/examples/step_activity/Makefile @@ -0,0 +1,18 @@ +COINES_INSTALL_PATH ?= ../../../.. + +EXAMPLE_FILE ?= step_activity.c + +API_LOCATION ?= ../.. +COMMON_LOCATION ?= .. + +C_SRCS += \ +$(API_LOCATION)/bma5.c \ +$(API_LOCATION)/bma530.c \ +$(API_LOCATION)/bma530_features.c \ +$(COMMON_LOCATION)/common/common.c + +INCLUDEPATHS += \ +$(API_LOCATION) \ +$(COMMON_LOCATION)/common + +include $(COINES_INSTALL_PATH)/coines.mk diff --git a/examples/step_activity/step_activity.c b/examples/step_activity/step_activity.c new file mode 100644 index 0000000..41ed5ec --- /dev/null +++ b/examples/step_activity/step_activity.c @@ -0,0 +1,185 @@ +/** + * Copyright (c) 2024 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. + * + */ + +#include +#include "common.h" +#include "bma530_features.h" + +/******************************************************************************/ +int main(void) +{ + struct bma5_dev dev; + int8_t rslt; + uint16_t loop = 10; + uint8_t n_ints = 1; + uint8_t gpr_ctrl_host = BMA5_ENABLE; + struct bma5_int_conf_types int_config = { 0 }; + struct bma530_step_cntr conf = { 0 }; + struct bma530_feat_eng_gpr_0 gpr_0 = { 0 }; + struct bma530_feat_eng_feat_out feat_out = { 0 }; + + /* The step activities are listed in array. */ + const char *activity_output[4] = { "UNKNOWN", "STILL", "WALKING", "RUNNING" }; + + int_config.int_src = BMA5_INT_1; + + /* Assign context parameter selection */ + enum bma5_context context; + context = BMA5_SMARTPHONE; + + /* Interface reference is given as a parameter + * For I2C : BMA5_I2C_INTF + * For SPI : BMA5_SPI_INTF + */ + rslt = bma5_interface_init(&dev, BMA5_SPI_INTF, context); + bma5_check_rslt("bma5_interface_init", rslt); + + rslt = bma530_init(&dev); + bma5_check_rslt("bma530_init", rslt); + printf("BMA530 Chip ID is 0x%X\n", dev.chip_id); + + /* Map hardware interrupt pin configurations */ + rslt = bma5_get_int_conf(&int_config, n_ints, &dev); + bma5_check_rslt("bma5_get_int_conf", rslt); + + int_config.int_conf.int_mode = BMA5_INT1_MODE_LATCHED; + int_config.int_conf.int_od = BMA5_INT1_OD_PUSH_PULL; + int_config.int_conf.int_lvl = BMA5_INT1_LVL_ACTIVE_HIGH; + + rslt = bma5_set_int_conf(&int_config, n_ints, &dev); + bma5_check_rslt("bma5_set_int_conf", rslt); + + rslt = bma530_get_feat_eng_gpr_0(&gpr_0, &dev); + bma5_check_rslt("bma530_get_feat_eng_gpr_0", rslt); + + gpr_0.step_en = BMA5_ENABLE; + + rslt = bma530_set_feat_eng_gpr_0(&gpr_0, &dev); + bma5_check_rslt("bma530_set_feat_eng_gpr_0", rslt); + + rslt = bma5_set_regs(BMA5_REG_FEAT_ENG_GPR_CTRL, &gpr_ctrl_host, 1, &dev); + bma5_check_rslt("bma5_set_regs", rslt); + + printf("\nDefault configurations\n\n"); + rslt = bma530_get_default_step_counter_config(&conf, &dev); + bma5_check_rslt("bma530_get_default_step_counter_config", rslt); + + printf("acc_mean_decay_coeff :: 0x%x\n", conf.acc_mean_decay_coeff); + printf("activity_detection_factor :: 0x%x\n", conf.activity_detection_factor); + printf("activity_detection_thres :: 0x%x\n", conf.activity_detection_thres); + printf("en_half_step :: 0x%x\n", conf.en_half_step); + printf("en_mcr_pp :: 0x%x\n", conf.en_mcr_pp); + printf("en_step_dur_pp :: 0x%x\n", conf.en_step_dur_pp); + printf("envelope_down_decay_coeff :: 0x%x\n", conf.envelope_down_decay_coeff); + printf("envelope_down_thres :: 0x%x\n", conf.envelope_down_thres); + printf("envelope_up_decay_coeff :: 0x%x\n", conf.envelope_up_decay_coeff); + printf("envelope_up_thres :: 0x%x\n", conf.envelope_up_thres); + printf("filter_cascade_enabled :: 0x%x\n", conf.filter_cascade_enabled); + printf("filter_coeff_a_1 :: 0x%x\n", conf.filter_coeff_a_1); + printf("filter_coeff_a_2 :: 0x%x\n", conf.filter_coeff_a_2); + printf("filter_coeff_b_0 :: 0x%x\n", conf.filter_coeff_b_0); + printf("filter_coeff_b_1 :: 0x%x\n", conf.filter_coeff_b_1); + printf("filter_coeff_b_2 :: 0x%x\n", conf.filter_coeff_b_2); + printf("filter_coeff_scale_a :: 0x%x\n", conf.filter_coeff_scale_a); + printf("filter_coeff_scale_b :: 0x%x\n", conf.filter_coeff_scale_b); + printf("mcr_thres :: 0x%x\n", conf.mcr_thres); + printf("peak_duration_min_running :: 0x%x\n", conf.peak_duration_min_running); + printf("peak_duration_min_walking :: 0x%x\n", conf.peak_duration_min_walking); + printf("reset_counter :: 0x%x\n", conf.reset_counter); + printf("sc_en :: 0x%x\n", conf.sc_en); + printf("sd_en :: 0x%x\n", conf.sd_en); + printf("step_buffer_size :: 0x%x\n", conf.step_buffer_size); + printf("step_counter_increment :: 0x%x\n", conf.step_counter_increment); + printf("step_dur_mean_decay_coeff :: 0x%x\n", conf.step_dur_mean_decay_coeff); + printf("step_dur_thres :: 0x%x\n", conf.step_dur_thres); + printf("step_duration_max :: 0x%x\n", conf.step_duration_max); + printf("step_duration_window :: 0x%x\n", conf.step_duration_window); + printf("watermark_level :: 0x%x\n", conf.watermark_level); + + conf.acc_mean_decay_coeff = 0xEAC8; + conf.activity_detection_factor = 0x3; + conf.activity_detection_thres = 0xF3C; + conf.en_half_step = 0x0; + conf.en_mcr_pp = 0x0; + conf.en_step_dur_pp = 0x0; + conf.envelope_down_decay_coeff = 0xD938; + conf.envelope_down_thres = 0x84; + conf.envelope_up_decay_coeff = 0xF1CC; + conf.envelope_up_thres = 0x132; + conf.filter_cascade_enabled = 0x1; + conf.filter_coeff_a_1 = 0x41EF; + conf.filter_coeff_a_2 = 0xE897; + conf.filter_coeff_b_0 = 0x55F; + conf.filter_coeff_b_1 = 0xABE; + conf.filter_coeff_b_2 = 0x55F; + conf.filter_coeff_scale_a = 0xE; + conf.filter_coeff_scale_b = 0xE; + conf.mcr_thres = 0x0; + conf.peak_duration_min_running = 0xC; + conf.peak_duration_min_walking = 0xC; + conf.reset_counter = 0x0; + conf.sc_en = 0x1; + conf.sd_en = 0x1; + conf.step_buffer_size = 0x7; + conf.step_counter_increment = 0x100; + conf.step_dur_mean_decay_coeff = 0xFD54; + conf.step_dur_thres = 0x0; + conf.step_duration_max = 0x4A; + conf.step_duration_window = 0xA0; + conf.watermark_level = 0x0; + + rslt = bma530_set_step_counter_config(&conf, &dev); + bma5_check_rslt("bma530_set_step_counter_config", rslt); + + printf("\nMove the board in steps to perform step activity\n"); + + /* Loop to get step activity. */ + while (loop) + { + /* Give delay to perform activity */ + dev.delay_us(1000000, dev.intf_ptr); + + rslt = bma530_get_feat_eng_feature_out(&feat_out, &dev); + bma5_check_rslt("bma530_get_feat_eng_feature_out", rslt); + + /* Print the step activity output. */ + printf("Step activity = %s\n", activity_output[feat_out.activ_stat]); + + loop--; + } + + bma5_coines_deinit(); + + return rslt; +} diff --git a/examples/step_counter/Makefile b/examples/step_counter/Makefile new file mode 100644 index 0000000..a6804c6 --- /dev/null +++ b/examples/step_counter/Makefile @@ -0,0 +1,18 @@ +COINES_INSTALL_PATH ?= ../../../.. + +EXAMPLE_FILE ?= step_counter.c + +API_LOCATION ?= ../.. +COMMON_LOCATION ?= .. + +C_SRCS += \ +$(API_LOCATION)/bma5.c \ +$(API_LOCATION)/bma530.c \ +$(API_LOCATION)/bma530_features.c \ +$(COMMON_LOCATION)/common/common.c + +INCLUDEPATHS += \ +$(API_LOCATION) \ +$(COMMON_LOCATION)/common + +include $(COINES_INSTALL_PATH)/coines.mk diff --git a/examples/step_counter/step_counter.c b/examples/step_counter/step_counter.c new file mode 100644 index 0000000..bfe0b73 --- /dev/null +++ b/examples/step_counter/step_counter.c @@ -0,0 +1,210 @@ +/** + * Copyright (c) 2024 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. + * + */ + +#include +#include "common.h" +#include "bma530_features.h" + +/******************************************************************************/ +int main(void) +{ + struct bma5_dev dev; + int8_t rslt; + uint8_t n_ints = 1; + uint8_t n_status = 1; + uint8_t gpr_ctrl_host = BMA5_ENABLE; + struct bma530_int_map int_map = { 0 }; + struct bma5_int_conf_types int_config = { 0 }; + struct bma530_step_cntr conf = { 0 }; + struct bma530_feat_eng_gpr_0 gpr_0 = { 0 }; + struct bma530_int_status_types int_status = { 0 }; + struct bma530_feat_eng_feat_out feat_out = { 0 }; + enum bma5_context context; + + int_config.int_src = BMA5_INT_2; + int_status.int_src = BMA530_INT_STATUS_INT2; + + /* Assign context parameter selection */ + context = BMA5_SMARTPHONE; + + /* Interface reference is given as a parameter + * For I2C : BMA5_I2C_INTF + * For SPI : BMA5_SPI_INTF + */ + rslt = bma5_interface_init(&dev, BMA5_SPI_INTF, context); + bma5_check_rslt("bma5_interface_init", rslt); + + rslt = bma530_init(&dev); + bma5_check_rslt("bma530_init", rslt); + printf("BMA530 Chip ID is 0x%X\n", dev.chip_id); + + /* Map hardware interrupt pin configurations */ + rslt = bma5_get_int_conf(&int_config, n_ints, &dev); + bma5_check_rslt("bma5_get_int_conf", rslt); + + int_config.int_conf.int_mode = BMA5_INT2_MODE_LATCHED; + int_config.int_conf.int_od = BMA5_INT2_OD_PUSH_PULL; + int_config.int_conf.int_lvl = BMA5_INT2_LVL_ACTIVE_HIGH; + + rslt = bma5_set_int_conf(&int_config, n_ints, &dev); + bma5_check_rslt("bma5_set_int1_conf", rslt); + + rslt = bma530_get_feat_eng_gpr_0(&gpr_0, &dev); + bma5_check_rslt("bma530_get_feat_eng_gpr_0", rslt); + + gpr_0.step_en = BMA5_ENABLE; + + rslt = bma530_set_feat_eng_gpr_0(&gpr_0, &dev); + bma5_check_rslt("bma530_set_feat_eng_gpr_0", rslt); + + rslt = bma5_set_regs(BMA5_REG_FEAT_ENG_GPR_CTRL, &gpr_ctrl_host, 1, &dev); + bma5_check_rslt("bma5_set_regs", rslt); + + printf("\nDefault configurations\n\n"); + rslt = bma530_get_default_step_counter_config(&conf, &dev); + bma5_check_rslt("bma530_get_default_step_counter_config", rslt); + + printf("acc_mean_decay_coeff :: 0x%x\n", conf.acc_mean_decay_coeff); + printf("activity_detection_factor :: 0x%x\n", conf.activity_detection_factor); + printf("activity_detection_thres :: 0x%x\n", conf.activity_detection_thres); + printf("en_half_step :: 0x%x\n", conf.en_half_step); + printf("en_mcr_pp :: 0x%x\n", conf.en_mcr_pp); + printf("en_step_dur_pp :: 0x%x\n", conf.en_step_dur_pp); + printf("envelope_down_decay_coeff :: 0x%x\n", conf.envelope_down_decay_coeff); + printf("envelope_down_thres :: 0x%x\n", conf.envelope_down_thres); + printf("envelope_up_decay_coeff :: 0x%x\n", conf.envelope_up_decay_coeff); + printf("envelope_up_thres :: 0x%x\n", conf.envelope_up_thres); + printf("filter_cascade_enabled :: 0x%x\n", conf.filter_cascade_enabled); + printf("filter_coeff_a_1 :: 0x%x\n", conf.filter_coeff_a_1); + printf("filter_coeff_a_2 :: 0x%x\n", conf.filter_coeff_a_2); + printf("filter_coeff_b_0 :: 0x%x\n", conf.filter_coeff_b_0); + printf("filter_coeff_b_1 :: 0x%x\n", conf.filter_coeff_b_1); + printf("filter_coeff_b_2 :: 0x%x\n", conf.filter_coeff_b_2); + printf("filter_coeff_scale_a :: 0x%x\n", conf.filter_coeff_scale_a); + printf("filter_coeff_scale_b :: 0x%x\n", conf.filter_coeff_scale_b); + printf("mcr_thres :: 0x%x\n", conf.mcr_thres); + printf("peak_duration_min_running :: 0x%x\n", conf.peak_duration_min_running); + printf("peak_duration_min_walking :: 0x%x\n", conf.peak_duration_min_walking); + printf("reset_counter :: 0x%x\n", conf.reset_counter); + printf("sc_en :: 0x%x\n", conf.sc_en); + printf("sd_en :: 0x%x\n", conf.sd_en); + printf("step_buffer_size :: 0x%x\n", conf.step_buffer_size); + printf("step_counter_increment :: 0x%x\n", conf.step_counter_increment); + printf("step_dur_mean_decay_coeff :: 0x%x\n", conf.step_dur_mean_decay_coeff); + printf("step_dur_thres :: 0x%x\n", conf.step_dur_thres); + printf("step_duration_max :: 0x%x\n", conf.step_duration_max); + printf("step_duration_window :: 0x%x\n", conf.step_duration_window); + printf("watermark_level :: 0x%x\n", conf.watermark_level); + + conf.acc_mean_decay_coeff = 0xEAC8; + conf.activity_detection_factor = 0x3; + conf.activity_detection_thres = 0xF3C; + conf.en_half_step = 0x0; + conf.en_mcr_pp = 0x0; + conf.en_step_dur_pp = 0x0; + conf.envelope_down_decay_coeff = 0xD938; + conf.envelope_down_thres = 0x84; + conf.envelope_up_decay_coeff = 0xF1CC; + conf.envelope_up_thres = 0x132; + conf.filter_cascade_enabled = 0x1; + conf.filter_coeff_a_1 = 0x41EF; + conf.filter_coeff_a_2 = 0xE897; + conf.filter_coeff_b_0 = 0x55F; + conf.filter_coeff_b_1 = 0xABE; + conf.filter_coeff_b_2 = 0x55F; + conf.filter_coeff_scale_a = 0xE; + conf.filter_coeff_scale_b = 0xE; + conf.mcr_thres = 0x0; + conf.peak_duration_min_running = 0xC; + conf.peak_duration_min_walking = 0xC; + conf.reset_counter = 0x0; + conf.sc_en = 0x1; + conf.sd_en = 0x1; + conf.step_buffer_size = 0x7; + conf.step_counter_increment = 0x100; + conf.step_dur_mean_decay_coeff = 0xFD54; + conf.step_dur_thres = 0x0; + conf.step_duration_max = 0x4A; + conf.step_duration_window = 0xA0; + + conf.watermark_level = 1; + + printf("\n\nSet Watermark level : %d\n", conf.watermark_level); + + rslt = bma530_set_step_counter_config(&conf, &dev); + bma5_check_rslt("bma530_set_step_counter_config", rslt); + + rslt = bma530_get_int_map(&int_map, &dev); + bma5_check_rslt("bma530_get_int_map", rslt); + + /* Map step counter */ + int_map.step_cnt_int_map = BMA530_STEP_CNT_INT_MAP_INT2; + rslt = bma530_set_int_map(&int_map, &dev); + bma5_check_rslt("bma530_set_int_map", rslt); + + rslt = bma530_get_step_counter_config(&conf, &dev); + bma5_check_rslt("bma530_get_step_counter_config", rslt); + + printf("\nGet Watermark level : %d\n", conf.watermark_level); + printf( + "Interrupt triggers when difference in number of steps counted from last event is equal to (%d * 20) steps\n\n", + conf.watermark_level); + + printf("Move the board in steps to get step counter interrupt\n"); + + for (;;) + { + rslt = bma530_get_int_status(&int_status, n_status, &dev); + bma5_check_rslt("bma530_get_int_status", rslt); + + if (int_status.int_status.step_cnt_int_status & BMA5_ENABLE) + { + printf("Step counter interrupt occurred\n"); + + rslt = bma530_get_feat_eng_feature_out(&feat_out, &dev); + bma5_check_rslt("bma530_get_feat_eng_feature_out", rslt); + + printf("Steps counted : %lu\n", (long unsigned int)feat_out.step_cntr_out); + + rslt = bma530_set_int_status(&int_status, n_status, &dev); + bma5_check_rslt("bma530_set_int_status_int1_0", rslt); + + break; + } + } + + bma5_coines_deinit(); + + return rslt; +} diff --git a/examples/step_detector/Makefile b/examples/step_detector/Makefile new file mode 100644 index 0000000..381dca1 --- /dev/null +++ b/examples/step_detector/Makefile @@ -0,0 +1,18 @@ +COINES_INSTALL_PATH ?= ../../../.. + +EXAMPLE_FILE ?= step_detector.c + +API_LOCATION ?= ../.. +COMMON_LOCATION ?= .. + +C_SRCS += \ +$(API_LOCATION)/bma5.c \ +$(API_LOCATION)/bma530.c \ +$(API_LOCATION)/bma530_features.c \ +$(COMMON_LOCATION)/common/common.c + +INCLUDEPATHS += \ +$(API_LOCATION) \ +$(COMMON_LOCATION)/common + +include $(COINES_INSTALL_PATH)/coines.mk diff --git a/examples/step_detector/step_detector.c b/examples/step_detector/step_detector.c new file mode 100644 index 0000000..2419d4a --- /dev/null +++ b/examples/step_detector/step_detector.c @@ -0,0 +1,193 @@ +/** + * Copyright (c) 2024 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. + * + */ + +#include +#include "common.h" +#include "bma530_features.h" + +/******************************************************************************/ +int main(void) +{ + struct bma5_dev dev; + int8_t rslt; + uint8_t n_ints = 1; + uint8_t n_status = 1; + uint8_t gpr_ctrl_host = BMA5_ENABLE; + struct bma530_int_map int_map = { 0 }; + struct bma5_int_conf_types int_config = { 0 }; + struct bma530_step_cntr conf = { 0 }; + struct bma530_feat_eng_gpr_0 gpr_0 = { 0 }; + struct bma530_int_status_types int_status = { 0 }; + enum bma5_context context; + + int_config.int_src = BMA5_INT_1; + int_status.int_src = BMA530_INT_STATUS_INT1; + + /* Assign context parameter selection */ + context = BMA5_SMARTPHONE; + + /* Interface reference is given as a parameter + * For I2C : BMA5_I2C_INTF + * For SPI : BMA5_SPI_INTF + */ + rslt = bma5_interface_init(&dev, BMA5_SPI_INTF, context); + bma5_check_rslt("bma5_interface_init", rslt); + + rslt = bma530_init(&dev); + bma5_check_rslt("bma530_init", rslt); + printf("BMA530 Chip ID is 0x%X\n", dev.chip_id); + + /* Map hardware interrupt pin configurations */ + rslt = bma5_get_int_conf(&int_config, n_ints, &dev); + bma5_check_rslt("bma5_get_int_conf", rslt); + + int_config.int_conf.int_mode = BMA5_INT1_MODE_PULSED_SHORT; + int_config.int_conf.int_od = BMA5_INT1_OD_OPEN_DRAIN; + int_config.int_conf.int_lvl = BMA5_INT1_LVL_ACTIVE_LOW; + + rslt = bma5_set_int_conf(&int_config, n_ints, &dev); + bma5_check_rslt("bma5_set_int_conf", rslt); + + rslt = bma530_get_feat_eng_gpr_0(&gpr_0, &dev); + bma5_check_rslt("bma530_get_feat_eng_gpr_0", rslt); + + gpr_0.step_en = 0x01; + + rslt = bma530_set_feat_eng_gpr_0(&gpr_0, &dev); + bma5_check_rslt("bma530_set_feat_eng_gpr_0", rslt); + + rslt = bma5_set_regs(BMA5_REG_FEAT_ENG_GPR_CTRL, &gpr_ctrl_host, 1, &dev); + bma5_check_rslt("bma5_set_regs", rslt); + + printf("\nDefault configurations\n\n"); + rslt = bma530_get_default_step_counter_config(&conf, &dev); + bma5_check_rslt("bma530_get_default_step_counter_config", rslt); + + printf("acc_mean_decay_coeff :: 0x%x\n", conf.acc_mean_decay_coeff); + printf("activity_detection_factor :: 0x%x\n", conf.activity_detection_factor); + printf("activity_detection_thres :: 0x%x\n", conf.activity_detection_thres); + printf("en_half_step :: 0x%x\n", conf.en_half_step); + printf("en_mcr_pp :: 0x%x\n", conf.en_mcr_pp); + printf("en_step_dur_pp :: 0x%x\n", conf.en_step_dur_pp); + printf("envelope_down_decay_coeff :: 0x%x\n", conf.envelope_down_decay_coeff); + printf("envelope_down_thres :: 0x%x\n", conf.envelope_down_thres); + printf("envelope_up_decay_coeff :: 0x%x\n", conf.envelope_up_decay_coeff); + printf("envelope_up_thres :: 0x%x\n", conf.envelope_up_thres); + printf("filter_cascade_enabled :: 0x%x\n", conf.filter_cascade_enabled); + printf("filter_coeff_a_1 :: 0x%x\n", conf.filter_coeff_a_1); + printf("filter_coeff_a_2 :: 0x%x\n", conf.filter_coeff_a_2); + printf("filter_coeff_b_0 :: 0x%x\n", conf.filter_coeff_b_0); + printf("filter_coeff_b_1 :: 0x%x\n", conf.filter_coeff_b_1); + printf("filter_coeff_b_2 :: 0x%x\n", conf.filter_coeff_b_2); + printf("filter_coeff_scale_a :: 0x%x\n", conf.filter_coeff_scale_a); + printf("filter_coeff_scale_b :: 0x%x\n", conf.filter_coeff_scale_b); + printf("mcr_thres :: 0x%x\n", conf.mcr_thres); + printf("peak_duration_min_running :: 0x%x\n", conf.peak_duration_min_running); + printf("peak_duration_min_walking :: 0x%x\n", conf.peak_duration_min_walking); + printf("reset_counter :: 0x%x\n", conf.reset_counter); + printf("sc_en :: 0x%x\n", conf.sc_en); + printf("sd_en :: 0x%x\n", conf.sd_en); + printf("step_buffer_size :: 0x%x\n", conf.step_buffer_size); + printf("step_counter_increment :: 0x%x\n", conf.step_counter_increment); + printf("step_dur_mean_decay_coeff :: 0x%x\n", conf.step_dur_mean_decay_coeff); + printf("step_dur_thres :: 0x%x\n", conf.step_dur_thres); + printf("step_duration_max :: 0x%x\n", conf.step_duration_max); + printf("step_duration_window :: 0x%x\n", conf.step_duration_window); + printf("watermark_level :: 0x%x\n", conf.watermark_level); + + conf.acc_mean_decay_coeff = 0xEAC8; + conf.activity_detection_factor = 0x3; + conf.activity_detection_thres = 0xF3C; + conf.en_half_step = 0x0; + conf.en_mcr_pp = 0x0; + conf.en_step_dur_pp = 0x0; + conf.envelope_down_decay_coeff = 0xD938; + conf.envelope_down_thres = 0x84; + conf.envelope_up_decay_coeff = 0xF1CC; + conf.envelope_up_thres = 0x132; + conf.filter_cascade_enabled = 0x1; + conf.filter_coeff_a_1 = 0x41EF; + conf.filter_coeff_a_2 = 0xE897; + conf.filter_coeff_b_0 = 0x55F; + conf.filter_coeff_b_1 = 0xABE; + conf.filter_coeff_b_2 = 0x55F; + conf.filter_coeff_scale_a = 0xE; + conf.filter_coeff_scale_b = 0xE; + conf.mcr_thres = 0x0; + conf.peak_duration_min_running = 0xC; + conf.peak_duration_min_walking = 0xC; + conf.reset_counter = 0x0; + conf.sc_en = 0x1; + conf.sd_en = 0x1; + conf.step_buffer_size = 0x7; + conf.step_counter_increment = 0x100; + conf.step_dur_mean_decay_coeff = 0xFD54; + conf.step_dur_thres = 0x0; + conf.step_duration_max = 0x4A; + conf.step_duration_window = 0xA0; + conf.watermark_level = 0; + + rslt = bma530_set_step_counter_config(&conf, &dev); + bma5_check_rslt("bma530_set_step_counter_config", rslt); + + rslt = bma530_get_int_map(&int_map, &dev); + bma5_check_rslt("bma530_get_int_map", rslt); + + /* Map step detector */ + int_map.step_det_int_map = BMA530_STEP_DET_INT_MAP_INT1; + rslt = bma530_set_int_map(&int_map, &dev); + bma5_check_rslt("bma530_set_int_map", rslt); + + printf("\nMove the board to get step detector interrupt\n"); + + for (;;) + { + rslt = bma530_get_int_status(&int_status, n_status, &dev); + bma5_check_rslt("bma530_get_int_status", rslt); + + if (int_status.int_status.step_det_int_status & BMA5_ENABLE) + { + rslt = bma530_set_int_status(&int_status, n_status, &dev); + bma5_check_rslt("bma530_set_int_status", rslt); + + printf("Step detector interrupt occurred\n"); + + break; + } + } + + bma5_coines_deinit(); + + return rslt; +} diff --git a/examples/temperature/Makefile b/examples/temperature/Makefile new file mode 100644 index 0000000..6e7190d --- /dev/null +++ b/examples/temperature/Makefile @@ -0,0 +1,18 @@ +COINES_INSTALL_PATH ?= ../../../.. + +EXAMPLE_FILE ?= temperature.c + +API_LOCATION ?= ../.. +COMMON_LOCATION ?= .. + +C_SRCS += \ +$(API_LOCATION)/bma5.c \ +$(API_LOCATION)/bma530.c \ +$(API_LOCATION)/bma530_features.c \ +$(COMMON_LOCATION)/common/common.c + +INCLUDEPATHS += \ +$(API_LOCATION) \ +$(COMMON_LOCATION)/common + +include $(COINES_INSTALL_PATH)/coines.mk diff --git a/examples/temperature/temperature.c b/examples/temperature/temperature.c new file mode 100644 index 0000000..cdee376 --- /dev/null +++ b/examples/temperature/temperature.c @@ -0,0 +1,109 @@ +/** + * Copyright (c) 2024 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. + * + */ + +#include +#include "common.h" +#include "bma530_features.h" + +/******************************************************************************/ +int main(void) +{ + struct bma5_dev dev; + int8_t rslt; + uint8_t loop = 0; + struct bma5_temp_conf config; + struct bma5_sensor_status status; + uint8_t temperature = 0; + int8_t temp_celsius = 0; + + enum bma5_context context; + + /* Assign context parameter selection */ + context = BMA5_SMARTPHONE; + + /* Interface reference is given as a parameter + * For I2C : BMA5_I2C_INTF + * For SPI : BMA5_SPI_INTF + */ + rslt = bma5_interface_init(&dev, BMA5_SPI_INTF, context); + bma5_check_rslt("bma5_interface_init", rslt); + + rslt = bma530_init(&dev); + bma5_check_rslt("bma530_init", rslt); + printf("BMA530 Chip ID is 0x%X\n", dev.chip_id); + + /* Get temperature config */ + rslt = bma5_get_temp_conf(&config, &dev); + bma5_check_rslt("bma5_get_temp_conf", rslt); + + config.temp_rate = BMA5_TEMP_RATE_HZ_25; + config.temp_meas_src = BMA5_TEMP_MEAS_SRC_TMP_INT; + config.temp_ext_sel = BMA5_TEMP_EXT_SEL_INT2; + + /* Set temperature config */ + rslt = bma5_set_temp_conf(&config, &dev); + bma5_check_rslt("bma5_set_temp_conf", rslt); + + printf("\nCount, Temparature data\n"); + + while (loop < 50) + { + /* Get temperature data ready status */ + rslt = bma5_get_sensor_status(&status, &dev); + bma5_check_rslt("bma5_get_sensor_status", rslt); + + if (status.temperature_rdy & BMA5_ENABLE) + { + rslt = bma5_set_sensor_status(&status, &dev); + bma5_check_rslt("bma5_set_sensor_status", rslt); + + /* Get temperature data */ + rslt = bma5_get_temp_data(&temperature, &dev); + bma5_check_rslt("bma5_get_temp_data", rslt); + + if (rslt == BMA5_OK) + { + temp_celsius = (int8_t)(temperature + 23); + } + + printf("%d, \t%d(Deg C)\n", loop, temp_celsius); + + loop++; + } + } + + bma5_coines_deinit(); + + return rslt; +} diff --git a/examples/tilt/Makefile b/examples/tilt/Makefile new file mode 100644 index 0000000..24b5bdb --- /dev/null +++ b/examples/tilt/Makefile @@ -0,0 +1,18 @@ +COINES_INSTALL_PATH ?= ../../../.. + +EXAMPLE_FILE ?= tilt.c + +API_LOCATION ?= ../.. +COMMON_LOCATION ?= .. + +C_SRCS += \ +$(API_LOCATION)/bma5.c \ +$(API_LOCATION)/bma530.c \ +$(API_LOCATION)/bma530_features.c \ +$(COMMON_LOCATION)/common/common.c + +INCLUDEPATHS += \ +$(API_LOCATION) \ +$(COMMON_LOCATION)/common + +include $(COINES_INSTALL_PATH)/coines.mk diff --git a/examples/tilt/tilt.c b/examples/tilt/tilt.c new file mode 100644 index 0000000..3a0a849 --- /dev/null +++ b/examples/tilt/tilt.c @@ -0,0 +1,138 @@ +/** + * Copyright (c) 2024 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. + * + */ + +#include +#include "common.h" +#include "bma530_features.h" + +/******************************************************************************/ +int main(void) +{ + struct bma5_dev dev; + int8_t rslt; + uint8_t gpr_ctrl_host = BMA5_ENABLE; + uint8_t n_ints = 1; + uint8_t n_status = 1; + + struct bma530_int_map int_map = { 0 }; + struct bma5_int_conf_types int_config = { 0 }; + struct bma530_tilt conf = { 0 }; + struct bma530_feat_eng_gpr_0 gpr_0 = { 0 }; + struct bma530_int_status_types int_status = { 0 }; + enum bma5_context context; + + int_config.int_src = BMA5_INT_2; + int_status.int_src = BMA530_INT_STATUS_INT2; + + /* Assign context parameter selection */ + context = BMA5_SMARTPHONE; + + /* Interface reference is given as a parameter + * For I2C : BMA5_I2C_INTF + * For SPI : BMA5_SPI_INTF + */ + rslt = bma5_interface_init(&dev, BMA5_SPI_INTF, context); + bma5_check_rslt("bma5_interface_init", rslt); + + rslt = bma530_init(&dev); + bma5_check_rslt("bma530_init", rslt); + printf("BMA530 Chip ID is 0x%X\n", dev.chip_id); + + printf("\nDefault configurations\n\n"); + rslt = bma530_get_tilt_config(&conf, &dev); + bma5_check_rslt("bma530_get_tilt_config", rslt); + + printf("beta_acc_mean :: 0x%x\n", conf.beta_acc_mean); + printf("min_tilt_angle :: 0x%x\n", conf.min_tilt_angle); + printf("segment_size :: 0x%x\n", conf.segment_size); + + conf.beta_acc_mean = 0xf069; + conf.min_tilt_angle = 0xd2; + conf.segment_size = 0x64; + + rslt = bma530_set_tilt_config(&conf, &dev); + bma5_check_rslt("bma530_set_tilt_config", rslt); + + rslt = bma530_get_feat_eng_gpr_0(&gpr_0, &dev); + bma5_check_rslt("bma530_get_feat_eng_gpr_0", rslt); + + gpr_0.tilt_en = BMA5_ENABLE; + + rslt = bma530_set_feat_eng_gpr_0(&gpr_0, &dev); + bma5_check_rslt("bma530_set_feat_eng_gpr_0", rslt); + + rslt = bma5_set_regs(BMA5_REG_FEAT_ENG_GPR_CTRL, &gpr_ctrl_host, 1, &dev); + bma5_check_rslt("bma5_set_regs", rslt); + + rslt = bma530_get_int_map(&int_map, &dev); + bma5_check_rslt("bma530_get_int_map", rslt); + + /* Map tilt */ + int_map.tilt_int_map = BMA530_TILT_INT_MAP_INT2; + rslt = bma530_set_int_map(&int_map, &dev); + bma5_check_rslt("bma530_set_int_map", rslt); + + /* Map hardware interrupt pin configurations */ + rslt = bma5_get_int_conf(&int_config, n_ints, &dev); + bma5_check_rslt("bma5_get_int_conf", rslt); + + int_config.int_conf.int_mode = BMA5_INT2_MODE_PULSED_SHORT; + int_config.int_conf.int_od = BMA5_INT2_OD_PUSH_PULL; + int_config.int_conf.int_lvl = BMA5_INT2_LVL_ACTIVE_LOW; + + rslt = bma5_set_int_conf(&int_config, n_ints, &dev); + bma5_check_rslt("bma5_set_int_conf", rslt); + + printf("\nTilt the board to get tilt interrupt\n"); + + for (;;) + { + rslt = bma530_get_int_status(&int_status, n_status, &dev); + bma5_check_rslt("bma530_get_int_status", rslt); + + if (int_status.int_status.tilt_int_status & BMA5_ENABLE) + { + rslt = bma530_set_int_status(&int_status, n_status, &dev); + bma5_check_rslt("bma530_set_int_status", rslt); + + printf("Tilt interrupt occurred\n"); + + break; + } + } + + bma5_coines_deinit(); + + return rslt; +}