diff --git a/components/bma456/CMakeLists.txt b/components/bma456/CMakeLists.txt new file mode 100644 index 0000000..8ef26a8 --- /dev/null +++ b/components/bma456/CMakeLists.txt @@ -0,0 +1,7 @@ +idf_component_register( + SRCS + "bma456h.c" + "bma4.c" + INCLUDE_DIRS "." + REQUIRES driver +) diff --git a/components/bma456/LICENSE b/components/bma456/LICENSE new file mode 100644 index 0000000..dca3eee --- /dev/null +++ b/components/bma456/LICENSE @@ -0,0 +1,30 @@ +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. \ No newline at end of file diff --git a/components/bma456/README.md b/components/bma456/README.md new file mode 100644 index 0000000..22843ec --- /dev/null +++ b/components/bma456/README.md @@ -0,0 +1,58 @@ +# BMA456 Sensor API + +> This package contains SensorAPIs for BMA456 Sensor + +## Sensor Overview + +The BMA456 is an ultra-small, triaxial, low-g acceleration sensor with digital interfaces, aiming for low-power consumer electronics applications. Featuring 16 bit digital resolution and embedded intelligence, the device is optimized to fulfill low power accelerometer requirements. + +## Applications + +### BMA456W +- Any motion +- No motion +- Step detector +- Step counter +- Step activity +- Tap + - Single tap + - Double tap + +### BMA456H + +- Any motion +- No motion +- Step detector +- Step counter +- Step activity +- Auto low power +- Tap + - Single tap + - Double tap + - Triple tap + +### BMA456MM + +- Any motion +- No motion +- Orientation +- High-g +- Low-g +- Significant motion +- Auto low power +- Tap + - Single tap + - Double tap + - Triple tap + +### BMA456AN + +- Any motion +- No motion + +### BMA456 tablet + +- Any/no motion +- Low-g +- Single, double and triple tap +- Orientation \ No newline at end of file diff --git a/components/bma456/bma4.c b/components/bma456/bma4.c new file mode 100644 index 0000000..a3e8a52 --- /dev/null +++ b/components/bma456/bma4.c @@ -0,0 +1,5859 @@ +/** +* 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. +* +* @file bma4.c +* @date 2023-07-05 +* @version V2.29.0 +* +*/ + +/* + * @file bma4.c + * @brief Source file for the BMA4 Sensor API + */ + +/***************************************************************************/ + +/*! + * @defgroup bma4 BMA4 + */ + +/**\name Header files + ****************************************************************************/ +#include "bma4.h" + +/***************************************************************************/ + +/**\name Local structures + ****************************************************************************/ + +/*! + * @brief Accel data deviation from ideal value + */ +struct bma4_offset_delta +{ + /*! X axis */ + int16_t x; + + /*! Y axis */ + int16_t y; + + /*! Z axis */ + int16_t z; +}; + +/*! + * @brief Accel offset xyz structure + */ +struct bma4_accel_offset +{ + /*! Accel offset X data */ + uint8_t x; + + /*! Accel offset Y data */ + uint8_t y; + + /*! Accel offset Z data */ + uint8_t z; +}; + +/***************************************************************************/ + +/*! Static Function Declarations + ****************************************************************************/ + +/*! + * @brief This API validates the bandwidth, odr and perf_mode + * combinations set by the user. + * + * param bandwidth[in] : bandwidth value set by the user. + * param perf_mode[in] : perf_mode value set by the user. + * param odr[in] : odr value set by the user. + */ +static int8_t validate_odr_bandwidth_perfmode(uint8_t odr, uint8_t bandwidth, uint8_t perf_mode); + +/*! + * @brief This API validates the bandwidth and perfmode + * value set by the user. + * + * param bandwidth[in] : bandwidth value set by the user. + * param perf_mode[in] : perf_mode value set by the user. + */ +static int8_t validate_bandwidth_perfmode(uint8_t bandwidth, uint8_t perf_mode); + +/*! + * @brief @brief This API validates the ODR value set by the user. + * + * param odr[in] : odr value set by the user. + */ +static int8_t validate_odr(uint8_t odr); + +/*! + * @brief This API validates the bandwidth and odr when perf_mode = BMA4_CIC_AVG_MODE + * + * param bandwidth[in] : bandwidth value set by the user. + * param odr[in] : odr value set by the user. + */ +static int8_t validate_bandwidth_odr(uint8_t bandwidth, uint8_t odr); + +/*! + * @brief This API is used to reset the FIFO related configurations + * in the fifo_frame structure. + * + * @param fifo[in,out] : Structure instance of bma4_fifo_frame + * + */ +static void reset_fifo_data_structure(struct bma4_fifo_frame *fifo); + +/*! + * @brief This API computes the number of bytes of accel FIFO data + * which is to be parsed in header-less mode + * + * @param[out] start_idx : The start index for parsing data + * @param[out] len : Number of bytes to be parsed + * @param[in] acc_count : Number of accelerometer frames to be read + * @param[in] fifo : Structure instance of bma4_fifo_frame. + * + */ +static void get_accel_len_to_parse(uint16_t *start_idx, + uint16_t *len, + const uint16_t *acc_count, + const struct bma4_fifo_frame *fifo); + +/*! + * @brief This API checks the fifo read data as empty frame, if it + * is empty frame then moves the index to last byte. + * + * @param[in,out] data_index : The index of the current data to + * be parsed from fifo data + * @param[in] fifo : Structure instance of bma4_fifo_frame. + */ +static void check_empty_fifo(uint16_t *data_index, const struct bma4_fifo_frame *fifo); + +/*! + * @brief This API is used to parse the accelerometer data from the + * FIFO data in header mode. + * + * @param[in,out] accel_data : Structure instance of bma4_accel where + * the accelerometer data in FIFO is stored. + * @param[in,out] accel_length : Number of accelerometer frames + * (x,y,z axes data) + * @param[in,out] fifo : Structure instance of bma4_fifo_frame + * @param[in,out] dev : Structure instance of bma4_dev. + * + */ +static void extract_accel_header_mode(struct bma4_accel *accel_data, + uint16_t *accel_length, + struct bma4_fifo_frame *fifo, + const struct bma4_dev *dev); + +/*! + * @brief This API is used to parse the accelerometer data from the + * FIFO data in both header mode and header-less mode. + * It update the idx value which is used to store the index of + * the current data byte which is parsed. + * + * @param[in,out] acc : Structure instance of bma4_accel. + * @param[in,out] idx : Index value of number of bytes parsed + * @param[in,out] acc_idx : Index value of accelerometer data + * (x,y,z axes) frame to be parsed + * @param[in] frm : It consists of either fifo_data_enable + * parameter (Accel and/or mag data enabled in FIFO) + * in header-less mode or frame header data + * in header mode + * @param[in] fifo : Structure instance of bma4_fifo_frame. + * @param[in] dev : Structure instance of bma4_dev. + * + */ +static void unpack_acc_frm(struct bma4_accel *acc, + uint16_t *idx, + uint16_t *acc_idx, + uint8_t frm, + const struct bma4_fifo_frame *fifo, + const struct bma4_dev *dev); + +/*! + * @brief This API is used to parse the accelerometer data from the + * FIFO data and store it in the instance of the structure bma4_accel. + * + * @param[out] accel_data : Structure instance of bma4_accel where + * the parsed accel data bytes are stored. + * @param[in] data_start_index : Index value of the accel data bytes + * which is to be parsed from the fifo data. + * @param[in] fifo : Structure instance of bma4_fifo_frame. + * @param[in] dev : Structure instance of bma4_dev. + * + */ +static void unpack_accel_data(struct bma4_accel *accel_data, + uint16_t data_start_index, + const struct bma4_fifo_frame *fifo, + const struct bma4_dev *dev); + +/*! + * @brief This API computes the number of bytes of Mag FIFO data which is + * to be parsed in header-less mode + * + * @param[out] start_idx : The start index for parsing data + * @param[out] len : Number of bytes to be parsed + * @param[in] mag_count : Number of magnetometer frames to be read + * @param[in] fifo : Structure instance of bma4_fifo_frame. + * + */ +static void get_mag_len_to_parse(uint16_t *start_idx, + uint16_t *len, + const uint16_t *mag_count, + const struct bma4_fifo_frame *fifo); + +/*! + * @brief This API is used to parse the magnetometer data from the + * FIFO data in header mode. + * + * @param[in,out] data : Structure instance of bma4_mag_xyzr where + * the magnetometer data in FIFO is extracted + * and stored. + * @param[in,out] len : Number of magnetometer frames + * (x,y,z,r data) + * @param[in,out] fifo : Structure instance of bma4_fifo_frame. + * @param[in] dev : Structure instance of bma4_dev. + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + * + */ +static int8_t extract_mag_header_mode(const struct bma4_mag *data, + uint16_t *len, + struct bma4_fifo_frame *fifo, + const struct bma4_dev *dev); + +/*! + * @brief This API is used to parse the magnetometer data from the + * FIFO data in both header mode and header-less mode and update the + * idx value which is used to store the index of the current + * data byte which is parsed. + * + * @param data : Structure instance of bma4_mag_xyzr. + * @param idx : Index value of number of bytes parsed + * @param mag_idx : Index value magnetometer data frame (x,y,z,r) + * to be parsed + * @param frm : It consists of either the fifo_data_enable parameter + * (Accel and/or mag data enabled in FIFO) in + * header-less mode and frame header data in header mode + * @param fifo : Structure instance of bma4_fifo_frame. + * @param dev : Structure instance of bma4_dev. + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + * + */ +static int8_t unpack_mag_frm(const struct bma4_mag *data, + uint16_t *idx, + uint16_t *mag_idx, + uint8_t frm, + const struct bma4_fifo_frame *fifo, + const struct bma4_dev *dev); + +/*! + * @brief This API is used to parse the auxiliary magnetometer data from + * the FIFO data and store it in the instance of the structure mag_data. + * + * @param mag_data : Structure instance of bma4_mag_xyzr where the + * parsed magnetometer data bytes are stored. + * @param start_idx : Index value of the magnetometer data bytes + * which is to be parsed from the FIFO data + * @param fifo : Structure instance of bma4_fifo_frame. + * @param dev : Structure instance of bma4_dev. + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + * + */ +static int8_t unpack_mag_data(const struct bma4_mag *mag_data, + uint16_t start_idx, + const struct bma4_fifo_frame *fifo, + const struct bma4_dev *dev); + +/*! + * @brief This API is used to parse and store the sensor time from the + * FIFO data in the structure instance dev. + * + * @param[in,out] data_index : Index of the FIFO data which + * has the sensor time. + * @param[in,out] fifo : Structure instance of bma4_fifo_frame. + * + */ +static void unpack_sensortime_frame(uint16_t *data_index, struct bma4_fifo_frame *fifo); + +/*! + * @brief This API is used to parse and store the skipped_frame_count from + * the FIFO data in the structure instance dev. + * + * @param[in,out] data_index : Index of the FIFO data which + * has the skipped frame count. + * @param[in,out] fifo : Structure instance of bma4_fifo_frame. + * + */ +static void unpack_skipped_frame(uint16_t *data_index, struct bma4_fifo_frame *fifo); + +/*! + * @brief This API is used to parse and store the dropped_frame_count from + * the FIFO data in the structure instance dev. + * + * @param[in,out] data_index : Index of the FIFO data which + * has the dropped frame data. + * @param[in,out] fifo : Structure instance of bma4_fifo_frame. + * + */ +static void unpack_dropped_frame(uint16_t *data_index, struct bma4_fifo_frame *fifo); + +/*! + * @brief This API is used to move the data index ahead of the + * current_frame_length parameter when unnecessary FIFO data appears while + * extracting the user specified data. + * + * @param[in,out] data_index : Index of the FIFO data which + * is to be moved ahead of the + * current_frame_length + * @param[in] current_frame_length : Number of bytes in a particular frame + * @param[in] fifo : Structure instance of bma4_fifo_frame. + * + */ +static void move_next_frame(uint16_t *data_index, uint8_t current_frame_length, const struct bma4_fifo_frame *fifo); + +/*! + * @brief This API writes the config stream data in memory using burst mode + * + * @param[in] stream_data : Pointer to store data of 32 bytes + * @param[in] index : Represents value in multiple of 32 bytes + * @param[in] dev : Structure instance of bma4_dev. + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +static int8_t stream_transfer_write(const uint8_t *stream_data, uint16_t index, struct bma4_dev *dev); + +/*! + * @brief This API enables or disables the Accel self-test feature in the + * sensor. + * + * @param[in] accel_self-test_enable : Variable used to enable or disable + * the Accel self-test feature + * Value | Description + * --------|--------------- + * 0x00 | BMA4_DISABLE + * 0x01 | BMA4_ENABLE + * + * @param[in] dev : Structure instance of bma4_dev + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + * + */ +static int8_t set_accel_selftest_enable(uint8_t accel_selftest_axis, struct bma4_dev *dev); + +/*! + * @brief This API selects the sign of Accel self-test excitation + * + * @param[in] accel_selftest_sign: Variable used to select the Accel + * self-test sign + * Value | Description + * --------|-------------------------- + * 0x00 | BMA4_DISABLE (negative) + * 0x01 | BMA4_ENABLE (positive) + * + * @param[in] dev : Structure instance of bma4_dev + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + * + */ +static int8_t set_accel_selftest_sign(uint8_t accel_selftest_sign, struct bma4_dev *dev); + +/*! + * @brief This API sets the Accel self-test amplitude in the sensor. + * + * @param[in] accel_selftest_amp : Variable used to specify the Accel self + * test amplitude + * Value | Description + * --------|------------------------------------ + * 0x00 | BMA4_SELFTEST_AMP_LOW + * 0x01 | BMA4_SELFTEST_AMP_HIGH + * + * @param[in] dev : structure instance of bma4_dev + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + * + */ +static int8_t set_accel_selftest_amp(uint8_t accel_selftest_amp, struct bma4_dev *dev); + +/*! + * @brief This function enables and configures the Accel which is needed + * for self-test operation. + * + * @param[in] dev : Structure instance of bma4_dev + * + * @return results of self-test + * @retval 0 -> Success + * @retval < 0 -> Fail + * + */ +static int8_t set_accel_selftest_config(struct bma4_dev *dev); + +/*! + * @brief This function validates the Accel self-test data and decides the + * result of self-test operation. + * + * @param[in] accel_data_diff : Pointer to structure variable which holds + * the Accel data difference of self-test operation + * @param[in] dev : Structure instance of bma4_dev + * + * @return results of self-test operation + * @retval 0 -> Success + * @retval Any non zero value -> Fail + * + */ +static int8_t validate_selftest(const struct bma4_selftest_delta_limit *accel_data_diff, const struct bma4_dev *dev); + +/*! + * @brief This API converts lsb value of axes to mg for self-test + * + * @param[in] accel_data_diff : Pointer variable used to pass accel difference + * values in g + * @param[out] accel_data_diff_mg : Pointer variable used to store accel + * difference values in mg + * @param[out] dev : Structure instance of bma4_dev + * + */ +static void convert_lsb_g(const struct bma4_selftest_delta_limit *accel_data_diff, + struct bma4_selftest_delta_limit *accel_data_diff_mg, + const struct bma4_dev *dev); + +/*! + * @brief This API sets the feature config. data start address in the sensor. + * + * @param[in] dev : Structure instance of bma4_dev. + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +static int8_t set_feature_config_start_addr(struct bma4_dev *dev); + +/*! + * @brief This API increments the feature config. data address according to the user + * provided read/write length in the dev structure. + * + * @param[in] dev : Structure instance of bma4_dev. + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +static int8_t increment_feature_config_addr(struct bma4_dev *dev); + +/*! + * @brief This API reads the 8-bit data from the given register + * in the sensor. + * + * @param[in] addr : Register address. + * @param[in] data : Read data buffer. + * @param[in] len : No of bytes to read. + * @param[in] dev : Structure instance of bma4_dev + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +static int8_t read_regs(uint8_t addr, uint8_t *data, uint32_t len, struct bma4_dev *dev); + +/*! + * @brief This API reads the 8-bit data from the given register + * when length is less than read write length + * + * @param[in] data : Read data buffer. + * @param[in] len : No of bytes to read. + * @param[in] dev : Structure instance of bma4_dev + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +static int8_t read_within_len_regs(uint8_t *data, uint32_t len, struct bma4_dev *dev); + +/*! + * @brief This API writes the 8-bit data to the given register + * in the sensor. + * + * @param[in] addr : Register address. + * @param[in] data : Write data buffer + * @param[in] len : No of bytes to write + * @param[in] dev : Structure instance of bma4_dev. + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +static int8_t write_regs(uint8_t addr, const uint8_t *data, uint32_t len, struct bma4_dev *dev); + +/*! + * @brief This API writes the 8-bit data to the given register + * in the sensor for length less than read write length + * + * @param[in] data : Write data buffer + * @param[in] len : No of bytes to write + * @param[in] dev : Structure instance of bma4_dev. + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +static int8_t write_within_len_regs(const uint8_t *data, uint32_t len, struct bma4_dev *dev); + +/*! + * @brief This API sets the feature config. data start address in the sensor. + * + * @param[in] dev : Structure instance of bma4_dev. + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +static int8_t get_feature_config_start_addr(struct bma4_dev *dev); + +/*! + * @brief This API is used to calculate the power of given + * base value. + * + * @param[in] base : value of base + * @param[in] resolution : resolution of the sensor + * + * @return : Return the value of base^resolution + */ +static int32_t power(int16_t base, uint8_t resolution); + +/*! + * @brief This API finds the the null error of the device pointer structure + * + * @param[in] dev : Structure instance of bma4_dev. + * + * @return Result of API execution status + * @retval BMA4_OK -> Success + * @retval BMA4_E_NULL_PTR -> Null pointer Error + */ +static int8_t null_pointer_check(const struct bma4_dev *dev); + +/*! + * @brief This internal API gets the re-mapped x, y and z axes from the sensor. + * + * @param[out] remap_data : Structure instance of bma4_axes_remap + * @param[in] feature_config : Array data containing feature configurations + * @param[in] index : Index to which mapping has to be applied + * @param[in] feature_len : Length of feature configurations + * @param[in, out] dev : Structure instance of bma4_dev + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +static int8_t get_remap_axes(struct bma4_axes_remap *remap_data, + uint8_t *feature_config, + uint8_t index, + uint8_t feature_len, + struct bma4_dev *dev); + +/*! + * @brief This internal API sets the re-mapped x, y and z axes in the sensor. + * + * @param[in] remap_data : Structure instance of bma4_axes_remap + * @param[in] feature_config : Array data containing feature configurations + * @param[in] index : Index to which mapping has to be applied + * @param[in] feature_len : Length of feature configurations + * @param[in, out] dev : Structure instance of bma4_dev + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +static int8_t set_remap_axes(const struct bma4_axes_remap *remap_data, + uint8_t *feature_config, + uint8_t index, + uint8_t feature_len, + struct bma4_dev *dev); + +/*! + * @brief This internal API is to store re-mapped axis and sign values + * in device structure + * + * @param[in] remap_axis : Value of re-mapped axis + * @param[out] axis : Re-mapped axis value stored in device structure + * @param[out] sign : Re-mapped axis sign stored in device structure + * + * @return None + * + * @retval None + */ +static void assign_remap_axis(uint8_t remap_axis, uint8_t *axis, uint8_t *sign); + +/*! + * @brief This internal API is to receive re-mapped axis and sign values + * in device structure + * + * @param[in] remap_axis : Re-mapped axis value + * @param[in] remap_sign : Re-mapped axis sign value + * @param[out] axis : Re-mapped axis stored in local structure + * + * @return None + * + * @retval None + */ +static void receive_remap_axis(uint8_t remap_axis, uint8_t remap_sign, uint8_t *axis); + +/*! + * @brief This internal API gets the re-mapped accelerometer/gyroscope data. + * + * @param[out] data : Structure instance of bma4_accel. + * @param[in] dev : Structure instance of bma4_dev. + * + * @return None + * + * @retval None + */ +static void get_remapped_data(struct bma4_accel *data, const struct bma4_dev *dev); + +/*! + * @brief This API performs the steps needed for Self test operation + * before reading the Accel Self test data. + * + * @param[in] sign: Variable used to specify the self test sign + * @param[in] dev : Structure instance of bma4_dev + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +static int8_t selftest_config(uint8_t sign, struct bma4_dev *dev); + +/*! + * @brief This internal API brings up the secondary interface to access + * auxiliary sensor + * + * @param[in] dev : Structure instance of bma4_dev. + * + * @return Result of API execution status + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +static int8_t set_aux_interface_config(struct bma4_dev *dev); + +/*! + * @brief This internal API reads the data from the auxiliary sensor + * depending on burst length configured + * + * @param[in] dev : Structure instance of bma4_dev. + * @param[out] aux_data : Pointer variable to store data read + * @param[in] aux_reg_addr : Variable to pass address from where + * data is to be read + * + * @return Result of API execution status + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +static int8_t extract_aux_data(uint8_t aux_reg_addr, uint8_t *aux_data, uint16_t len, struct bma4_dev *dev); + +/*! + * @brief This internal API maps the actual burst read length with user length set. + * + * @param[in] dev : Structure instance of bma4_dev. + * @param[out] len : Pointer variable to store mapped length + * + * @return Result of API execution status + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +static int8_t map_read_len(uint8_t *len, const struct bma4_dev *dev); + +/*! + * @brief This internal API validates accel self-test status from positive and negative axes input + * + * @param[in] positive : Positive accel data. + * @param[in] negative : Negative accel data. + * @param[in/out] accel_data_diff_mg : accel data difference data between positive and negative in mg. + * @param[in] dev : Structure instance of bma4_dev. + * + * @return Result of API execution status + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +static int8_t get_accel_data_difference_and_validate(struct bma4_accel positive, + struct bma4_accel negative, + struct bma4_selftest_delta_limit *accel_data_diff_mg, + const struct bma4_dev *dev); + +/*! + * @brief This internal API saves the configurations before performing FOC. + * + * @param[out] acc_cfg : Accelerometer configuration value + * @param[out] aps : Advance power mode value + * @param[out] acc_en : Accelerometer enable value + * @param[in] dev : Structure instance of bma4_dev + * + * @return Result of API execution status + * @retval BMA4_OK - Success. + * @retval BMA4_E_COM_FAIL - Error: Communication fail + * @retval BMA4_E_INVALID_SENSOR - Error: Invalid sensor + */ +static int8_t save_accel_foc_config(struct bma4_accel_config *acc_cfg, + uint8_t *aps, + uint8_t *acc_en, + struct bma4_dev *dev); + +/*! + * @brief This internal API sets configurations for performing accelerometer FOC. + * + * @param[in] dev : Structure instance of bma4_dev + * + * @return Result of API execution status + * @retval BMA4_OK - Success. + * @retval BMA4_E_COM_FAIL - Error: Communication fail + * @retval BMA4_E_INVALID_SENSOR - Error: Invalid sensor + */ +static int8_t set_accel_foc_config(struct bma4_dev *dev); + +/*! + * @brief This internal API enables/disables the offset compensation for + * filtered and un-filtered accelerometer data. + * + * @param[in] offset_en : Enables/Disables offset compensation. + * @param[in] dev : Structure instance of bma4_dev + * + * @return Result of API execution status + * @retval BMA4_OK - Success. + * @retval BMA4_E_COM_FAIL - Error: Communication fail + */ +static int8_t set_bma4_accel_offset_comp(uint8_t offset_en, struct bma4_dev *dev); + +/*! + * @brief This internal API performs Fast Offset Compensation for accelerometer. + * + * @param[in] accel_g_value : This parameter selects the accel FOC + * axis to be performed + * + * Input format is {x, y, z, sign}. '1' to enable. '0' to disable + * + * Eg:- To choose x axis {1, 0, 0, 0} + * Eg:- To choose -x axis {1, 0, 0, 1} + * + * @param[in] acc_cfg : Accelerometer configuration value + * @param[in] dev : Structure instance of bma4_dev. + * + * @return Result of API execution status + * + * @retval BMA4_OK - Success. + * @retval BMA4_E_NULL_PTR - Error: Null pointer error + * @retval BMA4_E_COM_FAIL - Error: Communication fail + */ +static int8_t perform_accel_foc(const struct bma4_accel_foc_g_value *accel_g_value, + const struct bma4_accel_config *acc_cfg, + struct bma4_dev *dev); + +/*! + * @brief This internal API converts the range value into accelerometer + * corresponding integer value. + * + * @param[in] range_in : Input range value. + * @param[out] range_out : Stores the integer value of range. + * + * @return None + * @retval None + */ +static void map_accel_range(uint8_t range_in, uint8_t *range_out); + +/*! + * @brief This internal API compensate the accelerometer data against gravity. + * + * @param[in] lsb_per_g : LSB value per 1g. + * @param[in] g_val : Gravity reference value of all axes. + * @param[in] data : Accelerometer data + * @param[out] comp_data : Stores the data that is compensated by taking the + * difference in accelerometer data and lsb_per_g + * value. + * + * @return None + * @retval None + */ +static void comp_for_gravity(uint16_t lsb_per_g, + const struct bma4_accel_foc_g_value *g_val, + const struct bma4_accel *data, + struct bma4_offset_delta *comp_data); + +/*! + * @brief This internal API scales the compensated accelerometer data according + * to the offset register resolution. + * + * @param[in] range : Gravity range of the accelerometer. + * @param[out] comp_data : Data that is compensated by taking the + * difference in accelerometer data and lsb_per_g + * value. + * @param[out] data : Stores offset data + * @param[in] resolution : Resolution of bma4 sensor + * + * @return None + * @retval None + */ +static void scale_bma4_accel_offset(uint8_t range, + const struct bma4_offset_delta *comp_data, + struct bma4_accel_offset *data, + uint8_t resolution); + +/*! + * @brief This internal API inverts the accelerometer offset data. + * + * @param[out] offset_data : Stores the inverted offset data + * + * @return None + * @retval None + */ +static void invert_bma4_accel_offset(struct bma4_accel_offset *offset_data); + +/*! + * @brief This internal API writes the offset data in the offset compensation + * register. + * + * @param[in] offset : Offset data + * @param[in] dev : Structure instance of bma4_dev + * + * @return Result of API execution status + * @retval BMA4_OK - Success. + * @retval BMA4_E_COM_FAIL - Error: Communication fail + */ +static int8_t write_bma4_accel_offset(const struct bma4_accel_offset *offset, struct bma4_dev *dev); + +/*! + * @brief This internal API finds the bit position of 3.9mg according to given + * range and resolution. + * + * @param[in] range : Gravity range of the accelerometer. + * @param[in] resolution : Resolution of sensor + * + * @return Result of API execution status + * @retval Bit position of 3.9mg + */ +static int8_t get_bit_pos_3_9mg(uint8_t range, uint8_t resolution); + +/*! + * @brief This internal API restores the configurations saved before performing + * accelerometer FOC. + * + * @param[in] acc_cfg : Accelerometer configuration value + * @param[in] aps : Advance power mode value + * @param[in] acc_en : Accelerometer enable value + * @param[in] dev : Structure instance of bma4_dev + * + * @return Result of API execution status + * @retval BMA4_OK - Success. + * @retval BMA4_E_COM_FAIL - Error: Communication fail + * @retval BMA4_E_INVALID_SENSOR - Error: Invalid sensor + * @retval BMA4_E_SET_APS_FAIL - Error: Set Advance Power Save Fail + */ +static int8_t restore_accel_foc_config(const struct bma4_accel_config *acc_cfg, + uint8_t aps, + uint8_t acc_en, + struct bma4_dev *dev); + +/***************************************************************************/ + +/**\name Extern Declarations + ****************************************************************************/ + +/***************************************************************************/ + +/**\name Globals + ****************************************************************************/ + +/***************************************************************************/ + +/**\name 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 bma4_init(struct bma4_dev *dev) +{ + int8_t rslt; + uint8_t data = 0; + uint8_t dummy_read = 0; + + /* NULL pointer check */ + rslt = null_pointer_check(dev); + + if (rslt == BMA4_OK) + { + if (dev->intf == BMA4_SPI_INTF) + { + dev->dummy_byte = 1; + rslt = bma4_read_regs(BMA4_CHIP_ID_ADDR, &dummy_read, 1, dev); + } + else + { + dev->dummy_byte = 0; + } + + if (rslt == BMA4_OK) + { + rslt = bma4_read_regs(BMA4_CHIP_ID_ADDR, &data, 1, dev); + if (rslt == BMA4_OK) + { + /* Assign Chip Id */ + dev->chip_id = data; + } + } + } + + return rslt; +} + +/*! + * @brief This API is used to write the binary configuration in the sensor + */ +int8_t bma4_write_config_file(struct bma4_dev *dev) +{ + int8_t rslt; + + /* Config loading disable*/ + uint8_t config_load = 0; + uint16_t index = 0; + uint8_t config_stream_status = 0; + + /* Disable advanced power save */ + rslt = bma4_set_advance_power_save(BMA4_DISABLE, dev); + + if (rslt == BMA4_OK) + { + /* Disable config loading*/ + rslt = bma4_write_regs(BMA4_INIT_CTRL_ADDR, &config_load, 1, dev); + + if (rslt == BMA4_OK) + { + /* Write the config stream */ + for (index = 0; index < dev->config_size; index += dev->read_write_len) + { + rslt = stream_transfer_write((dev->config_file_ptr + index), index, dev); + } + + if (rslt == BMA4_OK) + { + /* Enable config loading and FIFO mode */ + config_load = 0x01; + rslt = bma4_write_regs(BMA4_INIT_CTRL_ADDR, &config_load, 1, dev); + + if (rslt == BMA4_OK) + { + /* Wait till ASIC is initialized. Refer the data-sheet for + * more information + */ + dev->delay_us(BMA4_MS_TO_US(150), dev->intf_ptr); + + /* Read the status of config stream operation */ + rslt = bma4_read_regs(BMA4_INTERNAL_STAT, &config_stream_status, 1, dev); + config_stream_status = config_stream_status & BMA4_CONFIG_STREAM_MESSAGE_MSK; + + if (rslt == BMA4_OK) + { + if (config_stream_status != BMA4_ASIC_INITIALIZED) + { + rslt = BMA4_E_CONFIG_STREAM_ERROR; + } + else + { + /* Enable advanced power save */ + rslt = bma4_set_advance_power_save(BMA4_ENABLE, dev); + if (rslt == BMA4_OK) + { + rslt = get_feature_config_start_addr(dev); + } + } + } + } + } + } + } + + return rslt; +} + +/*! + * @brief This API checks whether the write operation requested is for feature + * config or register write and accordingly writes the data in the sensor. + */ +int8_t bma4_write_regs(uint8_t addr, const uint8_t *data, uint32_t len, struct bma4_dev *dev) +{ + int8_t rslt; + uint8_t adv_pwr_save = 0; + + /* Check the dev structure as NULL */ + rslt = null_pointer_check(dev); + + if ((rslt == BMA4_OK) && (data != NULL)) + { + if (addr == BMA4_FEATURE_CONFIG_ADDR) + { + /* Disable APS if enabled before writing the feature + * config register + */ + rslt = bma4_get_advance_power_save(&adv_pwr_save, dev); + if ((adv_pwr_save == BMA4_ENABLE) && (rslt == BMA4_OK)) + { + rslt = bma4_set_advance_power_save(BMA4_DISABLE, dev); + } + + if (((len % 2) == 0) && (len <= dev->feature_len) && (rslt == BMA4_OK)) + { + if (dev->read_write_len < len) + { + rslt = write_within_len_regs(data, len, dev); + } + else + { + rslt = write_regs(BMA4_FEATURE_CONFIG_ADDR, data, len, dev); + } + } + else + { + rslt = BMA4_E_RD_WR_LENGTH_INVALID; + } + + if (rslt == BMA4_OK) + { + /* Enable APS if previously enabled */ + if (adv_pwr_save == BMA4_ENABLE) + { + rslt = bma4_set_advance_power_save(BMA4_ENABLE, dev); + } + } + } + else + { + rslt = write_regs(addr, data, len, dev); + } + } + else + { + rslt = BMA4_E_NULL_PTR; + } + + return rslt; +} + +/*! @cond DOXYGEN_SUPRESS */ + +/* Suppressing doxygen warnings triggered for same static function names present across various sensor variant + * directories */ + +/*! + * @brief This API writes the 8-bit data to the given register + * in the sensor. + */ +static int8_t write_regs(uint8_t addr, const uint8_t *data, uint32_t len, struct bma4_dev *dev) +{ + int8_t rslt; + + /* NULL pointer check */ + rslt = null_pointer_check(dev); + + if ((rslt == BMA4_OK) && (data != NULL)) + { + if (dev->intf == BMA4_SPI_INTF) + { + addr = addr & BMA4_SPI_WR_MASK; + } + + /* write data in the register*/ + dev->intf_rslt = dev->bus_write(addr, data, len, dev->intf_ptr); + + if (dev->intf_rslt == BMA4_INTF_RET_SUCCESS) + { + /* After write operation 2us delay is required when + * device operates in performance mode whereas + * 450us is required when the device operates in suspend and low power mode. + * NOTE: For more information refer datasheet */ + if (dev->perf_mode_status == BMA4_ENABLE) + { + dev->delay_us(2, dev->intf_ptr); + } + else + { + dev->delay_us(450, dev->intf_ptr); + } + } + else + { + rslt = BMA4_E_COM_FAIL; + } + } + else + { + rslt = BMA4_E_NULL_PTR; + } + + return rslt; +} + +/*! + * @brief This API writes the 8-bit data to the given register + * in the sensor for length less than read write length + */ +static int8_t write_within_len_regs(const uint8_t *data, uint32_t len, struct bma4_dev *dev) +{ + int8_t rslt; + uint32_t loop_count; + uint16_t overflow; + uint16_t index; + uint32_t i; + + /* Calculate the no of writes to be + * performed according to the read/write + * length + */ + loop_count = len / dev->read_write_len; + overflow = len % dev->read_write_len; + index = 0; + rslt = set_feature_config_start_addr(dev); + + if (rslt == BMA4_OK) + { + for (i = 0; i < loop_count; i++) + { + rslt = write_regs(BMA4_FEATURE_CONFIG_ADDR, data + index, dev->read_write_len, dev); + if (rslt == BMA4_OK) + { + rslt = increment_feature_config_addr(dev); + if (rslt == BMA4_OK) + { + index = index + dev->read_write_len; + } + } + } + + if ((overflow) && (rslt == BMA4_OK)) + { + rslt = write_regs(BMA4_FEATURE_CONFIG_ADDR, data + index, overflow, dev); + } + + if (rslt == BMA4_OK) + { + rslt = set_feature_config_start_addr(dev); + } + } + + return rslt; +} + +/*! + * @brief This API sets the feature config. data start address in the sensor. + */ +static int8_t get_feature_config_start_addr(struct bma4_dev *dev) +{ + int8_t rslt; + uint8_t asic_lsb = 0; + uint8_t asic_msb = 0; + + /* NULL pointer check */ + rslt = null_pointer_check(dev); + + if (rslt == BMA4_OK) + { + rslt = read_regs(BMA4_RESERVED_REG_5B_ADDR, &asic_lsb, 1, dev); + if (rslt == BMA4_OK) + { + rslt = read_regs(BMA4_RESERVED_REG_5C_ADDR, &asic_msb, 1, dev); + } + + if (rslt == BMA4_OK) + { + /* Store asic info in dev structure */ + dev->asic_data.asic_lsb = asic_lsb & 0x0F; + dev->asic_data.asic_msb = asic_msb; + } + } + + return rslt; +} + +/*! + * @brief This API sets the feature config. data start address in the sensor. + */ +static int8_t set_feature_config_start_addr(struct bma4_dev *dev) +{ + int8_t rslt; + + /* NULL pointer check */ + rslt = null_pointer_check(dev); + + if (rslt == BMA4_OK) + { + rslt = write_regs(BMA4_RESERVED_REG_5B_ADDR, &dev->asic_data.asic_lsb, 1, dev); + if (rslt == BMA4_OK) + { + rslt = write_regs(BMA4_RESERVED_REG_5C_ADDR, &dev->asic_data.asic_msb, 1, dev); + } + } + + return rslt; +} + +/*! + * @brief This API increments the feature config. data address according to the user + * provided read/write length in the dev structure. + */ +static int8_t increment_feature_config_addr(struct bma4_dev *dev) +{ + int8_t rslt; + uint16_t asic_addr; + uint8_t asic_lsb = 0; + uint8_t asic_msb = 0; + + /* NULL pointer check */ + rslt = null_pointer_check(dev); + + if (rslt == BMA4_OK) + { + /* Read the asic address from the sensor */ + rslt = read_regs(BMA4_RESERVED_REG_5B_ADDR, &asic_lsb, 1, dev); + if (rslt == BMA4_OK) + { + rslt = read_regs(BMA4_RESERVED_REG_5C_ADDR, &asic_msb, 1, dev); + } + else + { + rslt = BMA4_E_COM_FAIL; + } + + if (rslt == BMA4_OK) + { + /* Get the asic address */ + asic_addr = (asic_msb << 4) | (asic_lsb & 0x0F); + + /* Sum the asic address with read/write length after converting from + * byte to word + */ + asic_addr = asic_addr + (dev->read_write_len / 2); + + /* Split the asic address */ + asic_lsb = asic_addr & 0x0F; + asic_msb = (uint8_t)(asic_addr >> 4); + + /* Write the asic address in the sensor */ + rslt = write_regs(BMA4_RESERVED_REG_5B_ADDR, &asic_lsb, 1, dev); + if (rslt == BMA4_OK) + { + rslt = write_regs(BMA4_RESERVED_REG_5C_ADDR, &asic_msb, 1, dev); + } + } + else + { + rslt = BMA4_E_COM_FAIL; + } + } + + return rslt; +} + +/*! @endcond */ + +/*! + * @brief This API checks whether the read operation requested is for feature + * or register read and accordingly reads the data from the sensor. + */ +int8_t bma4_read_regs(uint8_t addr, uint8_t *data, uint32_t len, struct bma4_dev *dev) +{ + int8_t rslt; + uint8_t adv_pwr_save = 0; + + /* Check the dev structure as NULL */ + rslt = null_pointer_check(dev); + + if ((rslt == BMA4_OK) && (data != NULL)) + { + if (addr == BMA4_FEATURE_CONFIG_ADDR) + { + /* Disable APS if enabled before reading the feature + * config register + */ + rslt = bma4_get_advance_power_save(&adv_pwr_save, dev); + if (adv_pwr_save == BMA4_ENABLE) + { + rslt = bma4_set_advance_power_save(BMA4_DISABLE, dev); + } + + if (((len % 2) == 0) && (len <= dev->feature_len) && (rslt == BMA4_OK)) + { + if (dev->read_write_len < len) + { + rslt = read_within_len_regs(data, len, dev); + } + else + { + rslt = read_regs(BMA4_FEATURE_CONFIG_ADDR, data, len, dev); + } + } + else + { + rslt = BMA4_E_RD_WR_LENGTH_INVALID; + } + + if (rslt == BMA4_OK) + { + /* Enable APS if previously enabled */ + if (adv_pwr_save == BMA4_ENABLE) + { + rslt = bma4_set_advance_power_save(BMA4_ENABLE, dev); + } + } + } + else + { + rslt = read_regs(addr, data, len, dev); + } + } + else + { + rslt = BMA4_E_NULL_PTR; + } + + return rslt; +} + +/*! @cond DOXYGEN_SUPRESS */ + +/* Suppressing doxygen warnings triggered for same static function names present across various sensor variant + * directories */ + +/*! + * @brief This API reads the 8-bit data from the given register + * in the sensor. + */ +static int8_t read_regs(uint8_t addr, uint8_t *data, uint32_t len, struct bma4_dev *dev) +{ + int8_t rslt; + uint16_t indx; + uint8_t temp_buff[BMA4_MAX_LEN]; + + /* Check the dev structure as NULL */ + rslt = null_pointer_check(dev); + + if ((rslt == BMA4_OK) && (data != NULL)) + { + if (dev->intf == BMA4_SPI_INTF) + { + /* SPI mask added */ + addr = addr | BMA4_SPI_RD_MASK; + } + + /* Read the data from the register */ + dev->intf_rslt = dev->bus_read(addr, temp_buff, (len + dev->dummy_byte), dev->intf_ptr); + + if (dev->intf_rslt == BMA4_INTF_RET_SUCCESS) + { + for (indx = 0; indx < len; indx++) + { + /* Parsing and storing the valid data */ + data[indx] = temp_buff[indx + dev->dummy_byte]; + } + } + else + { + rslt = BMA4_E_COM_FAIL; + } + } + else + { + rslt = BMA4_E_NULL_PTR; + } + + return rslt; +} + +/*! + * @brief This API reads the 8-bit data when length is less than read write length + */ +static int8_t read_within_len_regs(uint8_t *data, uint32_t len, struct bma4_dev *dev) +{ + uint32_t idx; + int8_t rslt; + uint32_t loop_count; + uint16_t overflow; + uint16_t index; + + /* Calculate the no of writes to be + * performed according to the read/write + * length + */ + loop_count = len / dev->read_write_len; + overflow = len % dev->read_write_len; + index = 0; + rslt = set_feature_config_start_addr(dev); + + if (rslt == BMA4_OK) + { + for (idx = 0; idx < loop_count; idx++) + { + rslt = read_regs(BMA4_FEATURE_CONFIG_ADDR, data + index, dev->read_write_len, dev); + + if (rslt == BMA4_OK) + { + rslt = increment_feature_config_addr(dev); + + if (rslt == BMA4_OK) + { + index = index + dev->read_write_len; + } + } + } + + if ((overflow) && (rslt == BMA4_OK)) + { + rslt = read_regs(BMA4_FEATURE_CONFIG_ADDR, data + index, overflow, dev); + } + + if (rslt == BMA4_OK) + { + rslt = set_feature_config_start_addr(dev); + } + } + + return rslt; +} + +/*! @endcond */ + +/*! + * @brief This API reads the error status from the sensor. + */ +int8_t bma4_get_error_status(struct bma4_err_reg *err_reg, struct bma4_dev *dev) +{ + int8_t rslt; + uint8_t data = 0; + + /* Check the dev structure as NULL */ + rslt = null_pointer_check(dev); + + if ((rslt == BMA4_OK) && (err_reg != NULL)) + { + /* Read the error codes*/ + rslt = bma4_read_regs(BMA4_ERROR_ADDR, &data, 1, dev); + if (rslt == BMA4_OK) + { + /* Fatal error*/ + err_reg->fatal_err = BMA4_GET_BITS_POS_0(data, BMA4_FATAL_ERR); + + /* Cmd error*/ + err_reg->cmd_err = BMA4_GET_BITSLICE(data, BMA4_CMD_ERR); + + /* User error*/ + err_reg->err_code = BMA4_GET_BITSLICE(data, BMA4_ERR_CODE); + + /* FIFO error*/ + err_reg->fifo_err = BMA4_GET_BITSLICE(data, BMA4_FIFO_ERR); + + /* Mag data ready error*/ + err_reg->aux_err = BMA4_GET_BITSLICE(data, BMA4_AUX_ERR); + } + } + else + { + rslt = BMA4_E_NULL_PTR; + } + + return rslt; +} + +/*! + * @brief This API reads the Accel data for x,y and z axis from the sensor. + * The data units is in LSB format. + */ +int8_t bma4_read_accel_xyz(struct bma4_accel *accel, struct bma4_dev *dev) +{ + int8_t rslt; + uint16_t lsb = 0; + uint16_t msb = 0; + uint8_t data[BMA4_ACCEL_DATA_LENGTH] = { 0 }; + + /* Check the dev structure as NULL */ + rslt = null_pointer_check(dev); + + if ((rslt == BMA4_OK) && (accel != NULL)) + { + rslt = bma4_read_regs(BMA4_DATA_8_ADDR, data, BMA4_ACCEL_DATA_LENGTH, dev); + if (rslt == BMA4_OK) + { + msb = data[1]; + lsb = data[0]; + + /* Accel data x axis */ + accel->x = (int16_t)((msb << 8) | lsb); + msb = data[3]; + lsb = data[2]; + + /* Accel data y axis */ + accel->y = (int16_t)((msb << 8) | lsb); + msb = data[5]; + lsb = data[4]; + + /* Accel data z axis */ + accel->z = (int16_t)((msb << 8) | lsb); + if (dev->resolution == BMA4_12_BIT_RESOLUTION) + { + accel->x = (accel->x / 0x10); + accel->y = (accel->y / 0x10); + accel->z = (accel->z / 0x10); + } + else if (dev->resolution == BMA4_14_BIT_RESOLUTION) + { + accel->x = (accel->x / 0x04); + accel->y = (accel->y / 0x04); + accel->z = (accel->z / 0x04); + } + + /* Get the re-mapped accelerometer data */ + get_remapped_data(accel, dev); + } + } + else + { + rslt = BMA4_E_NULL_PTR; + } + + return rslt; +} + +/*! + * @brief This API reads the sensor time of Sensor time gets updated + * with every update of data register or FIFO. + */ +int8_t bma4_get_sensor_time(uint32_t *sensor_time, struct bma4_dev *dev) +{ + int8_t rslt; + uint8_t data[BMA4_SENSOR_TIME_LENGTH] = { 0 }; + uint8_t msb = 0; + uint8_t xlsb = 0; + uint8_t lsb = 0; + + /* Check the dev structure as NULL */ + rslt = null_pointer_check(dev); + + if ((rslt == BMA4_OK) && (sensor_time != NULL)) + { + rslt = bma4_read_regs(BMA4_SENSORTIME_0_ADDR, data, BMA4_SENSOR_TIME_LENGTH, dev); + if (rslt == BMA4_OK) + { + msb = data[BMA4_SENSOR_TIME_MSB_BYTE]; + xlsb = data[BMA4_SENSOR_TIME_XLSB_BYTE]; + lsb = data[BMA4_SENSOR_TIME_LSB_BYTE]; + *sensor_time = (uint32_t)((msb << 16) | (xlsb << 8) | lsb); + } + } + else + { + rslt = BMA4_E_NULL_PTR; + } + + return rslt; +} + +/*! + * @brief This API reads the chip temperature of sensor. + * + * @note Using a scaling factor of 1000, to obtain integer values, which + * at the user end, are used to get accurate temperature value . + * BMA4_FAHREN_SCALED = 1.8 * 1000, BMA4_KELVIN_SCALED = 273.15 * 1000 + */ +int8_t bma4_get_temperature(int32_t *temp, uint8_t temp_unit, struct bma4_dev *dev) +{ + int8_t rslt; + uint8_t data[BMA4_TEMP_DATA_SIZE] = { 0 }; + int32_t temp_raw_scaled = 0; + + /* Check the dev structure as NULL */ + rslt = null_pointer_check(dev); + + if ((rslt == BMA4_OK) && (temp != NULL)) + { + /* Read temperature value from the register */ + rslt = bma4_read_regs(BMA4_TEMPERATURE_ADDR, data, BMA4_TEMP_DATA_SIZE, dev); + if (rslt == BMA4_OK) + { + temp_raw_scaled = (int32_t)data[BMA4_TEMP_BYTE] * BMA4_SCALE_TEMP; + } + + /* '0' value read from the register corresponds to 23 degree C */ + (*temp) = temp_raw_scaled + (BMA4_OFFSET_TEMP * BMA4_SCALE_TEMP); + switch (temp_unit) + { + case BMA4_DEG: + break; + case BMA4_FAHREN: + + /* Temperature in degree Fahrenheit */ + (*temp) = (((*temp) / BMA4_SCALE_TEMP) * BMA4_FAHREN_SCALED) + (32 * BMA4_SCALE_TEMP); + break; + case BMA4_KELVIN: + + /* Temperature in degree Kelvin */ + (*temp) = (*temp) + BMA4_KELVIN_SCALED; + break; + default: + break; + } + } + else + { + rslt = BMA4_E_NULL_PTR; + } + + return rslt; +} + +/*! + * @brief This API reads the Output data rate, Bandwidth, perf_mode + * and Range of accel. + */ +int8_t bma4_get_accel_config(struct bma4_accel_config *accel, struct bma4_dev *dev) +{ + int8_t rslt; + uint8_t data[2] = { 0 }; + + /* Check the dev structure as NULL */ + rslt = null_pointer_check(dev); + + if ((rslt == BMA4_OK) && (accel != NULL)) + { + rslt = bma4_read_regs(BMA4_ACCEL_CONFIG_ADDR, data, BMA4_ACCEL_CONFIG_LENGTH, dev); + if (rslt == BMA4_OK) + { + /* To get the ODR */ + accel->odr = BMA4_GET_BITS_POS_0(data[0], BMA4_ACCEL_ODR); + + /* To get the bandwidth */ + accel->bandwidth = BMA4_GET_BITSLICE(data[0], BMA4_ACCEL_BW); + + /* To get the under sampling mode */ + accel->perf_mode = BMA4_GET_BITSLICE(data[0], BMA4_ACCEL_PERFMODE); + + /* Read the Accel range */ + accel->range = BMA4_GET_BITS_POS_0(data[1], BMA4_ACCEL_RANGE); + + /* Flag bit to store the performance mode status */ + dev->perf_mode_status = accel->perf_mode; + } + } + else + { + rslt = BMA4_E_NULL_PTR; + } + + return rslt; +} + +/*! + * @brief This API sets the output_data_rate, bandwidth, perf_mode + * and range of Accel. + */ +int8_t bma4_set_accel_config(const struct bma4_accel_config *accel, struct bma4_dev *dev) +{ + int8_t rslt; + uint8_t accel_config_data[2] = { 0, 0 }; + + /* Check the dev structure as NULL */ + rslt = null_pointer_check(dev); + + if ((rslt == BMA4_OK) && (accel != NULL)) + { + /* Check whether the bandwidth , odr and perf_mode combinations are valid */ + rslt = validate_odr_bandwidth_perfmode(accel->odr, accel->bandwidth, accel->perf_mode); + + if (rslt == BMA4_OK) + { + accel_config_data[0] = accel->odr & BMA4_ACCEL_ODR_MSK; + accel_config_data[0] |= (uint8_t)(accel->bandwidth << BMA4_ACCEL_BW_POS); + accel_config_data[0] |= (uint8_t)(accel->perf_mode << BMA4_ACCEL_PERFMODE_POS); + accel_config_data[1] = accel->range & BMA4_ACCEL_RANGE_MSK; + + rslt = bma4_write_regs(BMA4_ACCEL_RANGE_ADDR, &accel_config_data[1], 1, dev); + + if (rslt == BMA4_OK) + { + rslt = bma4_write_regs(BMA4_ACCEL_CONFIG_ADDR, &accel_config_data[0], 1, dev); + + /* Flag bit to store the performance mode status */ + dev->perf_mode_status = ((accel_config_data[0] & BMA4_ACCEL_PERFMODE_MSK) >> BMA4_ACCEL_PERFMODE_POS); + } + } + } + else + { + rslt = BMA4_E_NULL_PTR; + } + + return rslt; +} + +/*! @cond DOXYGEN_SUPRESS */ + +/* Suppressing doxygen warnings triggered for same static function names present across various sensor variant + * directories */ + +/*! + * @brief This API validates the bandwidth, odr and perf_mode + * combinations set by the user. + */ +static int8_t validate_odr_bandwidth_perfmode(uint8_t odr, uint8_t bandwidth, uint8_t perf_mode) +{ + int8_t rslt; + + /* Check bandwidth and perf_mode combinations */ + rslt = validate_bandwidth_perfmode(bandwidth, perf_mode); + + if (rslt == BMA4_OK) + { + /* Check ODR validity */ + rslt = validate_odr(odr); + } + + if (rslt == BMA4_OK) + { + /* Validate ODR and bandwidth combinations when perf_mode = BMA4_CIC_AVG_MODE */ + if (perf_mode == BMA4_CIC_AVG_MODE) + { + rslt = validate_bandwidth_odr(bandwidth, odr); + } + } + + return rslt; + +} + +/*! + * @brief This API validates the bandwidth and perf_mode + * value set by the user. + */ +static int8_t validate_bandwidth_perfmode(uint8_t bandwidth, uint8_t perf_mode) +{ + int8_t rslt = BMA4_OK; + + if (perf_mode == BMA4_CONTINUOUS_MODE) + { + if (bandwidth > BMA4_ACCEL_NORMAL_AVG4) + { + /* Invalid bandwidth error for continuous mode */ + rslt = BMA4_E_OUT_OF_RANGE; + } + } + else if (perf_mode == BMA4_CIC_AVG_MODE) + { + if (bandwidth > BMA4_ACCEL_RES_AVG128) + { + /* Invalid bandwidth error for CIC avg. mode */ + rslt = BMA4_E_OUT_OF_RANGE; + } + } + else + { + rslt = BMA4_E_OUT_OF_RANGE; + } + + return rslt; +} + +/*! + * @brief This API validates the ODR value set by the user. + */ +static int8_t validate_odr(uint8_t odr) +{ + int8_t rslt = BMA4_OK; + + if ((odr < BMA4_OUTPUT_DATA_RATE_0_78HZ) || (odr > BMA4_OUTPUT_DATA_RATE_1600HZ)) + { + /* If odr is not valid return error */ + rslt = BMA4_E_OUT_OF_RANGE; + } + + return rslt; +} + +/*! + * @brief This API validates the bandwidth and odr when perf_mode = BMA4_CIC_AVG_MODE + */ +static int8_t validate_bandwidth_odr(uint8_t bandwidth, uint8_t odr) +{ + int8_t rslt = BMA4_OK; + uint8_t index; + + /* + * Array contains ODR values + * From BMA4_OUTPUT_DATA_RATE_0_78HZ (value = 1) + * To BMA4_OUTPUT_DATA_RATE_400HZ (value = 10) + */ + uint8_t accel_odr[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; + + /* + * Array contains valid bandwidth values for each ODR + */ + uint8_t valid_bw[10] = { 7, 7, 7, 7, 6, 5, 4, 3, 2, 1 }; + + /* + * For ODR - 800Hz and 1600Hz, none of the bandwidth is applicable + */ + if ((odr == BMA4_OUTPUT_DATA_RATE_800HZ) || (odr == BMA4_OUTPUT_DATA_RATE_1600HZ)) + { + rslt = BMA4_E_AVG_MODE_INVALID_CONF; + } + + /* + * Maximum valid bandwidth value for accel_odr[index] is the + * corresponding value in valid_bw[index] + */ + for (index = 0; index < 10; index++) + { + if (odr == accel_odr[index]) + { + if (bandwidth > valid_bw[index]) + { + rslt = BMA4_E_AVG_MODE_INVALID_CONF; + } + } + } + + return rslt; +} + +/*! @endcond */ + +/*! + * @brief This API sets the advance power save mode in the sensor. + */ +int8_t bma4_set_advance_power_save(uint8_t adv_pwr_save, struct bma4_dev *dev) +{ + int8_t rslt; + uint8_t data = 0; + + /* Check the dev structure as NULL */ + rslt = null_pointer_check(dev); + + if (rslt == BMA4_OK) + { + rslt = bma4_read_regs(BMA4_POWER_CONF_ADDR, &data, 1, dev); + if (rslt == BMA4_OK) + { + data = BMA4_SET_BITS_POS_0(data, BMA4_ADVANCE_POWER_SAVE, adv_pwr_save); + rslt = bma4_write_regs(BMA4_POWER_CONF_ADDR, &data, 1, dev); + } + } + + return rslt; +} + +/*! + * @brief This API reads the status of advance power save mode + * from the sensor. + */ +int8_t bma4_get_advance_power_save(uint8_t *adv_pwr_save, struct bma4_dev *dev) +{ + int8_t rslt; + uint8_t data = 0; + + /* Check the dev structure as NULL */ + rslt = null_pointer_check(dev); + + if ((rslt == BMA4_OK) && (adv_pwr_save != NULL)) + { + rslt = bma4_read_regs(BMA4_POWER_CONF_ADDR, &data, 1, dev); + if (rslt == BMA4_OK) + { + *adv_pwr_save = BMA4_GET_BITS_POS_0(data, BMA4_ADVANCE_POWER_SAVE); + } + } + else + { + rslt = BMA4_E_NULL_PTR; + } + + return rslt; +} + +/*! + * @brief This API sets the FIFO self wake up functionality in the sensor. + */ +int8_t bma4_set_fifo_self_wakeup(uint8_t fifo_self_wakeup, struct bma4_dev *dev) +{ + int8_t rslt; + uint8_t data = 0; + + /* Check the dev structure as NULL */ + rslt = null_pointer_check(dev); + + if (rslt == BMA4_OK) + { + rslt = bma4_read_regs(BMA4_POWER_CONF_ADDR, &data, 1, dev); + if (rslt == BMA4_OK) + { + data = BMA4_SET_BITSLICE(data, BMA4_FIFO_SELF_WAKE_UP, fifo_self_wakeup); + rslt = bma4_write_regs(BMA4_POWER_CONF_ADDR, &data, 1, dev); + } + } + + return rslt; +} + +/*! + * @brief This API gets the status of FIFO self wake up functionality from + * the sensor. + */ +int8_t bma4_get_fifo_self_wakeup(uint8_t *fifo_self_wake_up, struct bma4_dev *dev) +{ + int8_t rslt; + uint8_t data = 0; + + /* Check the dev structure as NULL */ + rslt = null_pointer_check(dev); + + if ((rslt == BMA4_OK) && (fifo_self_wake_up != NULL)) + { + rslt = bma4_read_regs(BMA4_POWER_CONF_ADDR, &data, 1, dev); + if (rslt == BMA4_OK) + { + *fifo_self_wake_up = BMA4_GET_BITSLICE(data, BMA4_FIFO_SELF_WAKE_UP); + } + } + else + { + rslt = BMA4_E_NULL_PTR; + } + + return rslt; +} + +/*! + * @brief This API enables or disables the Accel in the sensor. + */ +int8_t bma4_set_accel_enable(uint8_t accel_en, struct bma4_dev *dev) +{ + int8_t rslt; + uint8_t data = 0; + + /* Check the dev structure as NULL */ + rslt = null_pointer_check(dev); + + if (rslt == BMA4_OK) + { + rslt = bma4_read_regs(BMA4_POWER_CTRL_ADDR, &data, 1, dev); + if (rslt == BMA4_OK) + { + data = BMA4_SET_BITSLICE(data, BMA4_ACCEL_ENABLE, accel_en); + + rslt = bma4_write_regs(BMA4_POWER_CTRL_ADDR, &data, 1, dev); + dev->delay_us(25000, dev->intf_ptr); + } + } + + return rslt; +} + +/*! + * @brief This API checks whether Accel is enabled or not in the sensor. + */ +int8_t bma4_get_accel_enable(uint8_t *accel_en, struct bma4_dev *dev) +{ + int8_t rslt; + uint8_t data = 0; + + /* Check the dev structure as NULL */ + rslt = null_pointer_check(dev); + + if ((rslt == BMA4_OK) && (accel_en != NULL)) + { + rslt = bma4_read_regs(BMA4_POWER_CTRL_ADDR, &data, 1, dev); + if (rslt == BMA4_OK) + { + *accel_en = BMA4_GET_BITSLICE(data, BMA4_ACCEL_ENABLE); + } + } + else + { + rslt = BMA4_E_NULL_PTR; + } + + return rslt; +} + +/*! + * @brief This API is used to enable or disable auxiliary Mag + * in the sensor. + */ +int8_t bma4_set_mag_enable(uint8_t mag_en, struct bma4_dev *dev) +{ + int8_t rslt; + uint8_t data = 0; + + /* Check the dev structure as NULL */ + rslt = null_pointer_check(dev); + + if (rslt == BMA4_OK) + { + rslt = bma4_read_regs(BMA4_POWER_CTRL_ADDR, &data, 1, dev); + if (rslt == BMA4_OK) + { + data = BMA4_SET_BITS_POS_0(data, BMA4_MAG_ENABLE, mag_en); + rslt = bma4_write_regs(BMA4_POWER_CTRL_ADDR, &data, 1, dev); + } + } + + return rslt; +} + +/*! + * @brief This API is used to check whether the auxiliary Mag is enabled + * or not in the sensor. + */ +int8_t bma4_get_mag_enable(uint8_t *mag_en, struct bma4_dev *dev) +{ + int8_t rslt; + uint8_t data = 0; + + /* Check the dev structure as NULL */ + rslt = null_pointer_check(dev); + + if ((rslt == BMA4_OK) && (mag_en != NULL)) + { + rslt = bma4_read_regs(BMA4_POWER_CTRL_ADDR, &data, 1, dev); + if (rslt == BMA4_OK) + { + *mag_en = BMA4_GET_BITS_POS_0(data, BMA4_MAG_ENABLE); + } + } + else + { + rslt = BMA4_E_NULL_PTR; + } + + return rslt; +} + +/*! + * @brief This API reads the SPI interface mode which is set for primary + * interface. + */ +int8_t bma4_get_spi_interface(uint8_t *spi, struct bma4_dev *dev) +{ + int8_t rslt; + uint8_t data = 0; + + /* Check the dev structure as NULL */ + rslt = null_pointer_check(dev); + + if ((rslt == BMA4_OK) && (spi != NULL)) + { + /* Read SPI mode */ + rslt = bma4_read_regs(BMA4_IF_CONFIG_ADDR, &data, 1, dev); + if (rslt == BMA4_OK) + { + *spi = BMA4_GET_BITS_POS_0(data, BMA4_CONFIG_SPI3); + } + } + else + { + rslt = BMA4_E_NULL_PTR; + } + + return rslt; +} + +/*! + * @brief This API configures the SPI interface Mode for primary interface + */ +int8_t bma4_set_spi_interface(uint8_t spi, struct bma4_dev *dev) +{ + int8_t rslt; + uint8_t data = 0; + + /* Check the dev structure as NULL */ + rslt = null_pointer_check(dev); + + if (rslt == BMA4_OK) + { + if (spi <= BMA4_MAX_VALUE_SPI3) + { + /* Write SPI mode */ + rslt = bma4_read_regs(BMA4_IF_CONFIG_ADDR, &data, 1, dev); + if (rslt == BMA4_OK) + { + data = BMA4_SET_BITS_POS_0(data, BMA4_CONFIG_SPI3, spi); + rslt = bma4_write_regs(BMA4_IF_CONFIG_ADDR, &data, 1, dev); + } + } + else + { + rslt = BMA4_E_OUT_OF_RANGE; + } + } + + return rslt; +} + +/*! + * @brief This API writes the available sensor specific commands + * to the sensor. + */ +int8_t bma4_set_command_register(uint8_t command_reg, struct bma4_dev *dev) +{ + int8_t rslt; + + /* Check the dev structure as NULL */ + rslt = null_pointer_check(dev); + + if (rslt == BMA4_OK) + { + /* Write command register */ + rslt = bma4_write_regs(BMA4_CMD_ADDR, &command_reg, 1, dev); + } + + return rslt; +} + +/*! + * @brief This API sets the I2C device address of auxiliary sensor + */ +int8_t bma4_set_i2c_device_addr(struct bma4_dev *dev) +{ + int8_t rslt; + uint8_t data = 0, dev_id = 0; + + /* Check the dev structure as NULL */ + rslt = null_pointer_check(dev); + + if (rslt == BMA4_OK) + { + /* Write the auxiliary I2C device address */ + rslt = bma4_read_regs(BMA4_AUX_DEV_ID_ADDR, &data, 1, dev); + if (rslt == BMA4_OK) + { + dev_id = BMA4_SET_BITSLICE(data, BMA4_I2C_DEVICE_ADDR, dev->aux_config.aux_dev_addr); + rslt = bma4_write_regs(BMA4_AUX_DEV_ID_ADDR, &dev_id, 1, dev); + } + } + + return rslt; +} + +/*! + * @brief This API sets the register access on MAG_IF[2], MAG_IF[3], + * MAG_IF[4] in the sensor. This implies that the DATA registers are + * not updated with Mag values automatically. + */ +int8_t bma4_set_mag_manual_enable(uint8_t mag_manual, struct bma4_dev *dev) +{ + int8_t rslt; + uint8_t data = 0; + + /* Check the dev structure as NULL */ + rslt = null_pointer_check(dev); + + if (rslt == BMA4_OK) + { + /* Write the Mag manual*/ + rslt = bma4_read_regs(BMA4_AUX_IF_CONF_ADDR, &data, 1, dev); + dev->delay_us(BMA4_GEN_READ_WRITE_DELAY, dev->intf_ptr); + + if (rslt == BMA4_OK) + { + /* Set the bit of Mag manual enable */ + data = BMA4_SET_BITSLICE(data, BMA4_MAG_MANUAL_ENABLE, mag_manual); + rslt = bma4_write_regs(BMA4_AUX_IF_CONF_ADDR, &data, 1, dev); + if (rslt == BMA4_OK) + { + dev->aux_config.manual_enable = (uint8_t)mag_manual; + } + } + else + { + /*dev->mag_manual_enable = 0;*/ + dev->aux_config.manual_enable = 0; + } + } + + return rslt; +} + +/*! + * @brief This API checks whether the Mag access is done manually or + * automatically in the sensor. + * If the Mag access is done through manual mode then Mag data registers + * in sensor are not updated automatically. + */ +int8_t bma4_get_mag_manual_enable(uint8_t *mag_manual, struct bma4_dev *dev) +{ + int8_t rslt; + uint8_t data = 0; + + /* Check the dev structure as NULL */ + rslt = null_pointer_check(dev); + + if ((rslt == BMA4_OK) && (mag_manual != NULL)) + { + /* Read Mag manual */ + rslt = bma4_read_regs(BMA4_AUX_IF_CONF_ADDR, &data, 1, dev); + if (rslt == BMA4_OK) + { + *mag_manual = BMA4_GET_BITSLICE(data, BMA4_MAG_MANUAL_ENABLE); + } + } + else + { + rslt = BMA4_E_NULL_PTR; + } + + return rslt; +} + +/*! + * @brief This API sets the I2C interface configuration(if) mode + * for auxiliary Mag. + */ +int8_t bma4_set_aux_if_mode(uint8_t if_mode, struct bma4_dev *dev) +{ + int8_t rslt; + uint8_t data = 0; + + /* Check the dev structure as NULL */ + rslt = null_pointer_check(dev); + + if (rslt == BMA4_OK) + { + rslt = bma4_read_regs(BMA4_IF_CONFIG_ADDR, &data, 1, dev); + if (rslt == BMA4_OK) + { + data = BMA4_SET_BITSLICE(data, BMA4_IF_CONFIG_IF_MODE, if_mode); + rslt = bma4_write_regs(BMA4_IF_CONFIG_ADDR, &data, 1, dev); + } + } + + return rslt; +} + +/*! + * @brief This API gets the address of the register of Aux Mag sensor + * where the data to be read. + */ +int8_t bma4_get_mag_read_addr(uint8_t *mag_read_addr, struct bma4_dev *dev) +{ + int8_t rslt; + uint8_t data = 0; + + /* Check the dev structure as NULL */ + rslt = null_pointer_check(dev); + + if ((rslt == BMA4_OK) && (mag_read_addr != NULL)) + { + rslt = bma4_read_regs(BMA4_AUX_RD_ADDR, &data, 1, dev); + if (rslt == BMA4_OK) + { + *mag_read_addr = BMA4_GET_BITS_POS_0(data, BMA4_READ_ADDR); + } + } + else + { + rslt = BMA4_E_NULL_PTR; + } + + return rslt; +} + +/*! + * @brief This API sets the address of the register of Aux Mag sensor + * where the data to be read. + */ +int8_t bma4_set_mag_read_addr(uint8_t mag_read_addr, struct bma4_dev *dev) +{ + int8_t rslt; + + /* Check the dev structure as NULL */ + rslt = null_pointer_check(dev); + + if (rslt == BMA4_OK) + { + /* Write the Mag read address*/ + rslt = bma4_write_regs(BMA4_AUX_RD_ADDR, &mag_read_addr, 1, dev); + } + + return rslt; +} + +/*! + * @brief This API gets the Aux Mag write address from the sensor. + * Mag write address is where the Mag data will be written. + */ +int8_t bma4_get_mag_write_addr(uint8_t *mag_write_addr, struct bma4_dev *dev) +{ + int8_t rslt; + uint8_t data = 0; + + /* Check the dev structure as NULL */ + rslt = null_pointer_check(dev); + + if ((rslt == BMA4_OK) && (mag_write_addr != NULL)) + { + rslt = bma4_read_regs(BMA4_AUX_WR_ADDR, &data, 1, dev); + if (rslt == BMA4_OK) + { + *mag_write_addr = BMA4_GET_BITS_POS_0(data, BMA4_WRITE_ADDR); + } + } + else + { + rslt = BMA4_E_NULL_PTR; + } + + return rslt; +} + +/*! + * @brief This API sets the Aux Mag write address in the sensor. + * Mag write address is where the Mag data will be written. + */ +int8_t bma4_set_mag_write_addr(uint8_t mag_write_addr, struct bma4_dev *dev) +{ + int8_t rslt; + + /* Check the dev structure as NULL */ + rslt = null_pointer_check(dev); + + if (rslt == BMA4_OK) + { + rslt = bma4_write_regs(BMA4_AUX_WR_ADDR, &mag_write_addr, 1, dev); + } + + return rslt; +} + +/*! + * @brief This API reads the data from the sensor which is written to the + * Mag. + */ +int8_t bma4_get_mag_write_data(uint8_t *mag_write_data, struct bma4_dev *dev) +{ + int8_t rslt; + uint8_t data = 0; + + /* Check the dev structure as NULL */ + rslt = null_pointer_check(dev); + + if ((rslt == BMA4_OK) && (mag_write_data != NULL)) + { + rslt = bma4_read_regs(BMA4_AUX_WR_DATA_ADDR, &data, 1, dev); + if (rslt == BMA4_OK) + { + *mag_write_data = BMA4_GET_BITS_POS_0(data, BMA4_WRITE_DATA); + } + } + else + { + rslt = BMA4_E_NULL_PTR; + } + + return rslt; +} + +/*! + * @brief This API sets the data in the sensor which in turn will + * be written to Mag. + */ +int8_t bma4_set_mag_write_data(uint8_t mag_write_data, struct bma4_dev *dev) +{ + int8_t rslt; + + /* Check the dev structure as NULL */ + rslt = null_pointer_check(dev); + + if (rslt == BMA4_OK) + { + rslt = bma4_write_regs(BMA4_AUX_WR_DATA_ADDR, &mag_write_data, 1, dev); + } + + return rslt; +} + +/*! + * @brief This API reads the x,y,z and r axis data from the auxiliary + * Mag BMM150/AKM9916 sensor. + */ +int8_t bma4_read_mag_xyzr(struct bma4_mag_xyzr *mag, struct bma4_dev *dev) +{ + int8_t rslt; + uint16_t msb = 0; + uint16_t lsb = 0; + uint8_t data[BMA4_MAG_XYZR_DATA_LENGTH] = { 0 }; + + /* Check the dev structure as NULL */ + rslt = null_pointer_check(dev); + + if ((rslt == BMA4_OK) && (mag != NULL)) + { + rslt = bma4_read_regs(BMA4_DATA_0_ADDR, data, BMA4_MAG_XYZR_DATA_LENGTH, dev); + if (rslt == BMA4_OK) + { + /* Data X */ + /* X-axis LSB value shifting */ + lsb = BMA4_GET_BITSLICE(data[BMA4_MAG_X_LSB_BYTE], BMA4_DATA_MAG_X_LSB); + msb = data[BMA4_MAG_X_MSB_BYTE]; + mag->x = (int16_t)((msb << 8) | lsb); + mag->x = (mag->x / 0x08); + + /* Data Y */ + /* Y-axis LSB value shifting */ + lsb = BMA4_GET_BITSLICE(data[BMA4_MAG_Y_LSB_BYTE], BMA4_DATA_MAG_Y_LSB); + msb = data[BMA4_MAG_Y_MSB_BYTE]; + mag->y = (int16_t)((msb << 8) | lsb); + mag->y = (mag->y / 0x08); + + /* Data Z */ + /* Z-axis LSB value shifting */ + lsb = BMA4_GET_BITSLICE(data[BMA4_MAG_Z_LSB_BYTE], BMA4_DATA_MAG_Z_LSB); + msb = data[BMA4_MAG_Z_MSB_BYTE]; + mag->z = (int16_t)((msb << 8) | lsb); + mag->z = (mag->z / 0x02); + + /* RHall */ + /* R-axis LSB value shifting */ + lsb = BMA4_GET_BITSLICE(data[BMA4_MAG_R_LSB_BYTE], BMA4_DATA_MAG_R_LSB); + msb = data[BMA4_MAG_R_MSB_BYTE]; + mag->r = (int16_t)((msb << 8) | lsb); + mag->r = (mag->r / 0x04); + } + } + else + { + rslt = BMA4_E_NULL_PTR; + } + + return rslt; +} + +/*! + * @brief This API sets the burst data length (1,2,6,8 byte) of auxiliary + * Mag sensor. + */ +int8_t bma4_set_mag_burst(uint8_t mag_burst, struct bma4_dev *dev) +{ + int8_t rslt; + uint8_t data = 0; + + /* Check the dev structure as NULL */ + rslt = null_pointer_check(dev); + + if (rslt == BMA4_OK) + { + /* Write auxiliary burst mode length*/ + rslt = bma4_read_regs(BMA4_AUX_IF_CONF_ADDR, &data, 1, dev); + if (rslt == BMA4_OK) + { + data = BMA4_SET_BITS_POS_0(data, BMA4_MAG_BURST, mag_burst); + rslt = bma4_write_regs(BMA4_AUX_IF_CONF_ADDR, &data, 1, dev); + } + } + + return rslt; +} + +/*! + * @brief This API reads the burst data length of Mag set in the sensor. + */ +int8_t bma4_get_mag_burst(uint8_t *mag_burst, struct bma4_dev *dev) +{ + int8_t rslt; + uint8_t data = 0; + + /* Check the dev structure as NULL */ + rslt = null_pointer_check(dev); + + if ((rslt == BMA4_OK) && (mag_burst != NULL)) + { + /* Write Mag burst mode length*/ + rslt = bma4_read_regs(BMA4_AUX_IF_CONF_ADDR, &data, 1, dev); + if (rslt == BMA4_OK) + { + *mag_burst = BMA4_GET_BITS_POS_0(data, BMA4_MAG_BURST); + } + } + else + { + rslt = BMA4_E_NULL_PTR; + } + + return rslt; +} + +/*! + * @brief This API reads the FIFO data of Accel and/or Mag sensor + * NOTE : Dummy byte (for SPI Interface) required for FIFO data read + * must be given as part of data pointer in struct bma4_fifo_frame + */ +int8_t bma4_read_fifo_data(struct bma4_fifo_frame *fifo, struct bma4_dev *dev) +{ + int8_t rslt; + uint8_t data = 0; + uint8_t fifo_config_1 = 0; + uint16_t fifo_length = 0; + uint8_t addr = BMA4_FIFO_DATA_ADDR; + + /* Check the dev structure as NULL */ + rslt = null_pointer_check(dev); + + if ((rslt == BMA4_OK) && (fifo != NULL)) + { + /* reset the fifo data structure */ + reset_fifo_data_structure(fifo); + + if (dev->intf == BMA4_SPI_INTF) + { + /* SPI mask added */ + addr = addr | BMA4_SPI_RD_MASK; + } + + /* Read available fifo length */ + rslt = bma4_get_fifo_length(&fifo_length, dev); + + if (rslt == BMA4_OK) + { + /* Read FIFO header enable configuration */ + rslt = bma4_read_regs(BMA4_FIFO_CONFIG_1_ADDR, &fifo_config_1, 1, dev); + + if (rslt == BMA4_OK) + { + /* If fifo header is enabled, add sensortime overhead byte to total FIFO length */ + if ((fifo_config_1 & BMA4_FIFO_HEADER)) + { + /* This update will take care of dummy byte necessity based on interface selection */ + fifo->length = (fifo_length + BMA4_SENSORTIME_OVERHEAD_BYTE + dev->dummy_byte); + } + /* If fifo header is enabled, exclude addition of sensortime overhead byte to total FIFO length */ + else + { + /* This update will take care of dummy byte necessity based on interface selection */ + fifo->length = (fifo_length + dev->dummy_byte); + } + } + + /* Read FIFO data */ + dev->intf_rslt = dev->bus_read(addr, fifo->data, (uint32_t)fifo->length, dev->intf_ptr); + + /* If interface read fails, update rslt variable with communication failure */ + if (dev->intf_rslt != BMA4_INTF_RET_SUCCESS) + { + rslt = BMA4_E_COM_FAIL; + } + } + + if (rslt == BMA4_OK) + { + /* read fifo frame content configuration*/ + rslt = bma4_read_regs(BMA4_FIFO_CONFIG_1_ADDR, &data, 1, dev); + + if (rslt == BMA4_OK) + { + /* filter fifo header enabled status */ + fifo->fifo_header_enable = data & BMA4_FIFO_HEADER; + + /* filter accel/mag data enabled status */ + fifo->fifo_data_enable = data & BMA4_FIFO_M_A_ENABLE; + } + } + } + else + { + rslt = BMA4_E_NULL_PTR; + } + + return rslt; +} + +/*! + * @brief This API parses and extracts the accelerometer frames from + * FIFO data read by the "bma4_read_fifo_data" API and stores it in the + * "accel_data" structure instance. + */ +int8_t bma4_extract_accel(struct bma4_accel *accel_data, + uint16_t *accel_length, + struct bma4_fifo_frame *fifo, + const struct bma4_dev *dev) +{ + int8_t rslt; + uint16_t data_index = 0; + uint16_t accel_index = 0; + uint16_t data_read_length = 0; + + /* Check the dev structure as NULL */ + rslt = null_pointer_check(dev); + + if ((rslt == BMA4_OK) && (accel_data != NULL) && (accel_length != NULL) && (fifo != NULL)) + { + /* Check if this is the first iteration of data unpacking + * if yes, then consider dummy byte on SPI + */ + if (fifo->accel_byte_start_idx == 0) + { + /* Dummy byte included */ + fifo->accel_byte_start_idx = dev->dummy_byte; + } + + /* Parsing the FIFO data in header-less mode */ + if (fifo->fifo_header_enable == 0) + { + get_accel_len_to_parse(&data_index, &data_read_length, accel_length, fifo); + + for (; data_index < data_read_length;) + { + unpack_acc_frm(accel_data, &data_index, &accel_index, fifo->fifo_data_enable, fifo, dev); + + /* Checks for the availability of set of FIFO data */ + check_empty_fifo(&data_index, fifo); + } + + /* update number of accel data read*/ + *accel_length = accel_index; + + /*update the accel byte index*/ + fifo->accel_byte_start_idx = data_index; + } + else + { + /* Parsing the FIFO data in header mode */ + extract_accel_header_mode(accel_data, accel_length, fifo, dev); + } + } + else + { + rslt = BMA4_E_NULL_PTR; + } + + return rslt; +} + +/*! + * @brief This API parses and extracts the magnetometer frames from + * FIFO data read by the "bma4_read_fifo_data" API and stores it in the + * "mag_data" structure instance parameter of this API + */ +int8_t bma4_extract_mag(const struct bma4_mag *mag_data, + uint16_t *mag_length, + struct bma4_fifo_frame *fifo, + const struct bma4_dev *dev) +{ + int8_t rslt; + uint16_t data_index = 0; + uint16_t mag_index = 0; + uint16_t data_read_length = 0; + + /* Check the dev structure as NULL */ + rslt = null_pointer_check(dev); + + if ((rslt == BMA4_OK) && (mag_data != NULL) && (mag_length != NULL) && (fifo != NULL)) + { + /* Check if this is the first iteration of data unpacking + * if yes, then consider dummy byte on SPI + */ + if (fifo->mag_byte_start_idx == 0) + { + /* Dummy byte included */ + fifo->mag_byte_start_idx = dev->dummy_byte; + } + + /* Parsing the FIFO data in header-less mode */ + if (fifo->fifo_header_enable == 0) + { + get_mag_len_to_parse(&data_index, &data_read_length, mag_length, fifo); + for (; data_index < data_read_length;) + { + rslt = unpack_mag_frm(mag_data, &data_index, &mag_index, fifo->fifo_data_enable, fifo, dev); + + /*Check for the availability of next + * two bytes of FIFO data + */ + check_empty_fifo(&data_index, fifo); + } + + /* update number of Aux. sensor data read*/ + *mag_length = mag_index; + + /*update the Aux. sensor frame index*/ + fifo->mag_byte_start_idx = data_index; + } + else + { + /* Parsing the FIFO data in header mode */ + rslt = extract_mag_header_mode(mag_data, mag_length, fifo, dev); + } + } + else + { + rslt = BMA4_E_NULL_PTR; + } + + return rslt; +} + +/*! + * @brief This API reads the FIFO water mark level which is set + * in the sensor. + */ +int8_t bma4_get_fifo_wm(uint16_t *fifo_wm, struct bma4_dev *dev) +{ + int8_t rslt; + uint8_t data[2] = { 0, 0 }; + + /* Check the dev structure as NULL */ + rslt = null_pointer_check(dev); + + if ((rslt == BMA4_OK) && (fifo_wm != NULL)) + { + /* Read the FIFO water mark level*/ + rslt = bma4_read_regs(BMA4_FIFO_WTM_0_ADDR, data, BMA4_FIFO_WM_LENGTH, dev); + if (rslt == BMA4_OK) + { + *fifo_wm = (data[1] << 8) | (data[0]); + } + } + else + { + rslt = BMA4_E_NULL_PTR; + } + + return rslt; +} + +/*! + * @brief This API sets the FIFO watermark level in the sensor. + */ +int8_t bma4_set_fifo_wm(uint16_t fifo_wm, struct bma4_dev *dev) +{ + int8_t rslt; + uint8_t data[2] = { 0, 0 }; + + /* Check the dev structure as NULL */ + rslt = null_pointer_check(dev); + + if (rslt == BMA4_OK) + { + data[0] = BMA4_GET_LSB(fifo_wm); + data[1] = BMA4_GET_MSB(fifo_wm); + + /* consecutive write is not possible in suspend mode hence + * separate write is used with delay of 1 ms + */ + + /* Write the fifo watermark level*/ + rslt = bma4_write_regs(BMA4_FIFO_WTM_0_ADDR, &data[0], 1, dev); + + if (rslt == BMA4_OK) + { + dev->delay_us(BMA4_GEN_READ_WRITE_DELAY, dev->intf_ptr); + rslt = bma4_write_regs((BMA4_FIFO_WTM_0_ADDR + 1), &data[1], 1, dev); + } + } + + return rslt; +} + +/*! + * @brief This API checks whether the Accel FIFO data is set for filtered + * or unfiltered mode. + */ +int8_t bma4_get_accel_fifo_filter_data(uint8_t *accel_fifo_filter, struct bma4_dev *dev) +{ + int8_t rslt; + uint8_t data = 0; + + /* Check the dev structure as NULL */ + rslt = null_pointer_check(dev); + + if ((rslt == BMA4_OK) && (accel_fifo_filter != NULL)) + { + /* Read the Accel FIFO filter data */ + rslt = bma4_read_regs(BMA4_FIFO_DOWN_ADDR, &data, 1, dev); + if (rslt == BMA4_OK) + { + *accel_fifo_filter = BMA4_GET_BITSLICE(data, BMA4_FIFO_FILTER_ACCEL); + } + } + else + { + rslt = BMA4_E_NULL_PTR; + } + + return rslt; +} + +/*! + * @brief This API sets the condition of Accel FIFO data either to + * filtered or unfiltered mode. + */ +int8_t bma4_set_accel_fifo_filter_data(uint8_t accel_fifo_filter, struct bma4_dev *dev) +{ + int8_t rslt; + uint8_t data = 0; + + /* Check the dev structure as NULL */ + rslt = null_pointer_check(dev); + + if (rslt == BMA4_OK) + { + if (accel_fifo_filter <= BMA4_MAX_VALUE_FIFO_FILTER) + { + rslt = bma4_read_regs(BMA4_FIFO_DOWN_ADDR, &data, 1, dev); + if (rslt == BMA4_OK) + { + /* Write Accel FIFO filter data */ + data = BMA4_SET_BITSLICE(data, BMA4_FIFO_FILTER_ACCEL, accel_fifo_filter); + rslt = bma4_write_regs(BMA4_FIFO_DOWN_ADDR, &data, 1, dev); + } + } + else + { + rslt = BMA4_E_OUT_OF_RANGE; + } + } + + return rslt; +} + +/*! + * @brief This API reads the down sampling rates which is configured + * for Accel FIFO data. + */ +int8_t bma4_get_fifo_down_accel(uint8_t *fifo_down, struct bma4_dev *dev) +{ + int8_t rslt; + uint8_t data = 0; + + /* Check the dev structure as NULL */ + rslt = null_pointer_check(dev); + + if ((rslt == BMA4_OK) && (fifo_down != NULL)) + { + /* Read the Accel FIFO down data */ + rslt = bma4_read_regs(BMA4_FIFO_DOWN_ADDR, &data, 1, dev); + if (rslt == BMA4_OK) + { + *fifo_down = BMA4_GET_BITSLICE(data, BMA4_FIFO_DOWN_ACCEL); + } + } + else + { + rslt = BMA4_E_NULL_PTR; + } + + return rslt; +} + +/*! + * @brief This API sets the down-sampling rates for Accel FIFO. + */ +int8_t bma4_set_fifo_down_accel(uint8_t fifo_down, struct bma4_dev *dev) +{ + int8_t rslt; + uint8_t data = 0; + + /* Check the dev structure as NULL */ + rslt = null_pointer_check(dev); + + if (rslt == BMA4_OK) + { + /* Write the Accel FIFO down data */ + rslt = bma4_read_regs(BMA4_FIFO_DOWN_ADDR, &data, 1, dev); + if (rslt == BMA4_OK) + { + data = BMA4_SET_BITSLICE(data, BMA4_FIFO_DOWN_ACCEL, fifo_down); + rslt = bma4_write_regs(BMA4_FIFO_DOWN_ADDR, &data, 1, dev); + } + } + + return rslt; +} + +/*! + * @brief This API reads the length of FIFO data available in the sensor + * in the units of bytes. + */ +int8_t bma4_get_fifo_length(uint16_t *fifo_length, struct bma4_dev *dev) +{ + int8_t rslt; + uint8_t index = 0; + uint8_t data[BMA4_FIFO_DATA_LENGTH] = { 0, 0 }; + + /* Check the dev structure as NULL */ + rslt = null_pointer_check(dev); + + if ((rslt == BMA4_OK) && (fifo_length != NULL)) + { + /* Read FIFO length*/ + rslt = bma4_read_regs(BMA4_FIFO_LENGTH_0_ADDR, data, BMA4_FIFO_DATA_LENGTH, dev); + if (rslt == BMA4_OK) + { + index = BMA4_FIFO_LENGTH_MSB_BYTE; + data[index] = BMA4_GET_BITS_POS_0(data[index], BMA4_FIFO_BYTE_COUNTER_MSB); + *fifo_length = ((data[index] << 8) | data[index - 1]); + } + } + else + { + rslt = BMA4_E_NULL_PTR; + } + + return rslt; +} + +/*! + * @brief This API aligns and compensates the Mag data of BMM150/AKM9916 + * sensor. + */ +int8_t bma4_second_if_mag_compensate_xyz(struct bma4_mag_fifo_data mag_fifo_data, + uint8_t mag_second_if, + const struct bma4_mag *compensated_mag_data) +{ + int8_t rslt = BMA4_OK; + +#ifdef BMM150 + int16_t mag_x = 0; + int16_t mag_y = 0; + int16_t mag_z = 0; + uint16_t mag_r = 0; +#else + + /* Suppress Warnings */ + (void)(mag_second_if); + (void)(mag_fifo_data); +#endif + + if (compensated_mag_data == NULL) + { + rslt = BMA4_E_NULL_PTR; + } + +#if defined(BMM150) || defined(AKM9916) + switch (mag_second_if) + { +#ifdef BMM150 + case BMA4_SEC_IF_BMM150: + + /* X data*/ + mag_x = (int16_t)((mag_fifo_data.mag_x_msb << 8) | (mag_fifo_data.mag_x_lsb)); + mag_x = (int16_t) (mag_x / 0x08); + + /* Y data*/ + mag_y = (int16_t)((mag_fifo_data.mag_y_msb << 8) | (mag_fifo_data.mag_y_lsb)); + mag_y = (int16_t) (mag_y / 0x08); + + /* Z data*/ + mag_z = (int16_t)((mag_fifo_data.mag_z_msb << 8) | (mag_fifo_data.mag_z_lsb)); + mag_z = (int16_t) (mag_z / 0x02); + + /* R data*/ + mag_r = (uint16_t)((mag_fifo_data.mag_r_y2_msb << 8) | (mag_fifo_data.mag_r_y2_lsb)); + mag_r = (uint16_t) (mag_r >> 2); + + /* Compensated Mag x data */ + compensated_mag_data->x = bma4_bmm150_mag_compensate_x(mag_x, mag_r); + + /* Compensated Mag y data */ + compensated_mag_data->y = bma4_bmm150_mag_compensate_y(mag_y, mag_r); + + /* Compensated Mag z data */ + compensated_mag_data->z = bma4_bmm150_mag_compensate_z(mag_z, mag_r); + break; +#endif + +#ifdef AKM9916 + case BMA4_SEC_IF_AKM09916: + + /* Compensated X data */ + compensated_mag_data->x = (int16_t)((mag_fifo_data.mag_x_msb << 8) | (mag_fifo_data.mag_x_lsb)); + + /* Compensated Y data*/ + compensated_mag_data->y = (int16_t)((mag_fifo_data.mag_y_msb << 8) | (mag_fifo_data.mag_y_lsb)); + + /* Compensated Z data*/ + compensated_mag_data->z = (int16_t)((mag_fifo_data.mag_z_msb << 8) | (mag_fifo_data.mag_z_lsb)); + break; +#endif + } +#endif + + return rslt; +} + +/*! + * @brief This API reads Mag. x,y and z axis data from either BMM150 or + * AKM9916 sensor + */ +int8_t bma4_read_mag_xyz(const struct bma4_mag *mag, uint8_t sensor_select, const struct bma4_dev *dev) +{ + int8_t rslt; + +#if defined(AKM9916) || defined(BMM150) + uint8_t index; + uint16_t msb = 0; + uint16_t lsb = 0; + uint8_t data[BMA4_MAG_XYZ_DATA_LENGTH] = { 0 }; +#else + + /* Suppress Warnings */ + (void)(sensor_select); +#endif + + /* Check the dev structure as NULL */ + rslt = null_pointer_check(dev); + + if ((BMA4_OK != rslt) || (mag == NULL)) + { + rslt = BMA4_E_NULL_PTR; + } + else + { +#if defined(BMM150) || defined(AKM9916) + switch (sensor_select) + { + +#ifdef BMM150 + case BMA4_SEC_IF_BMM150: + rslt = bma4_read_regs(BMA4_DATA_0_ADDR, data, BMA4_MAG_XYZ_DATA_LENGTH, dev); + if (rslt == BMA4_OK) + { + index = BMA4_MAG_X_LSB_BYTE; + + /*X-axis LSB value shifting*/ + data[index] = BMA4_GET_BITSLICE(data[index], BMA4_DATA_MAG_X_LSB); + + /* Data X */ + msb = data[index + 1]; + lsb = data[index]; + mag->x = (int16_t)((msb << 8) | lsb); + mag->x = (mag->x / 0x08); + + /* Data Y */ + /*Y-axis LSB value shifting*/ + data[index + 2] = BMA4_GET_BITSLICE(data[index + 2], BMA4_DATA_MAG_Y_LSB); + msb = data[index + 3]; + lsb = data[index + 2]; + mag->y = (int16_t)((msb << 8) | lsb); + mag->y = (mag->y / 0x08); + + /* Data Z */ + /*Z-axis LSB value shifting*/ + data[index + 4] = BMA4_GET_BITSLICE(data[index + 4], BMA4_DATA_MAG_Z_LSB); + msb = data[index + 5]; + lsb = data[index + 4]; + mag->z = (int16_t)((msb << 8) | lsb); + mag->z = (mag->z / 0x02); + } + + break; +#endif + +#ifdef AKM9916 + case BMA4_SEC_IF_AKM09916: + if (dev->aux_sensor == AKM9916_SENSOR) + { + rslt = bma4_read_regs(BMA4_DATA_0_ADDR, data, BMA4_MAG_XYZ_DATA_LENGTH, dev); + if (rslt == BMA4_OK) + { + index = BMA4_MAG_X_LSB_BYTE; + + /* Data X */ + msb = data[index + 1]; + lsb = data[index]; + mag->x = (int16_t)((msb << 8) | lsb); + + /* Data Y */ + msb = data[index + 3]; + lsb = data[index + 2]; + mag->y = (int32_t)((msb << 8) | lsb); + + /* Data Z */ + msb = data[index + 5]; + lsb = data[index + 4]; + mag->z = (int16_t)((msb << 8) | lsb); + } + } + + break; +#endif + } +#else + rslt = BMA4_E_OUT_OF_RANGE; +#endif + } + + return rslt; +} + +/*! + * @brief This API reads the auxiliary I2C interface configuration which + * is set in the sensor. + */ +int8_t bma4_get_if_mode(uint8_t *if_mode, struct bma4_dev *dev) +{ + int8_t rslt; + uint8_t data = 0; + + /* Check the dev structure as NULL */ + rslt = null_pointer_check(dev); + + if ((rslt == BMA4_OK) && (if_mode != NULL)) + { + /* Read auxiliary interface configuration */ + rslt = bma4_read_regs(BMA4_IF_CONFIG_ADDR, &data, 1, dev); + if (rslt == BMA4_OK) + { + *if_mode = BMA4_GET_BITSLICE(data, BMA4_IF_CONFIG_IF_MODE); + } + } + else + { + rslt = BMA4_E_NULL_PTR; + } + + return rslt; +} + +/*! + * @brief This API sets the auxiliary interface configuration in the + * sensor. + */ +int8_t bma4_set_if_mode(uint8_t if_mode, struct bma4_dev *dev) +{ + int8_t rslt; + uint8_t data = 0; + + /* Check the dev structure as NULL */ + rslt = null_pointer_check(dev); + + if (rslt == BMA4_OK) + { + if (if_mode <= BMA4_MAX_IF_MODE) + { + /* Write the interface configuration mode */ + rslt = bma4_read_regs(BMA4_IF_CONFIG_ADDR, &data, 1, dev); + if (rslt == BMA4_OK) + { + data = BMA4_SET_BITSLICE(data, BMA4_IF_CONFIG_IF_MODE, if_mode); + rslt = bma4_write_regs(BMA4_IF_CONFIG_ADDR, &data, 1, dev); + } + } + else + { + rslt = BMA4_E_OUT_OF_RANGE; + } + } + + return rslt; +} + +/*! + * @brief This API reads the ASIC status from the sensor. + * The status information is mentioned in the below table. + */ +int8_t bma4_get_asic_status(struct bma4_asic_status *asic_status, struct bma4_dev *dev) +{ + int8_t rslt; + uint8_t data = 0; + + /* Check the dev structure as NULL */ + rslt = null_pointer_check(dev); + + if ((rslt == BMA4_OK) && (asic_status != NULL)) + { + /* Read the Mag I2C device address*/ + rslt = bma4_read_regs(BMA4_INTERNAL_ERROR, &data, 1, dev); + if (rslt == BMA4_OK) + { + asic_status->sleep = (data & 0x01); + asic_status->irq_ovrn = ((data & 0x02) >> 0x01); + asic_status->wc_event = ((data & 0x04) >> 0x02); + asic_status->stream_transfer_active = ((data & 0x08) >> 0x03); + } + } + else + { + rslt = BMA4_E_NULL_PTR; + } + + return rslt; +} + +/*! + * @brief This API enables the offset compensation for filtered and + * unfiltered Accel data. + */ +int8_t bma4_set_offset_comp(uint8_t offset_en, struct bma4_dev *dev) +{ + int8_t rslt; + uint8_t data = 0; + + /* Check the dev structure as NULL */ + rslt = null_pointer_check(dev); + + if (rslt == BMA4_OK) + { + rslt = bma4_read_regs(BMA4_NV_CONFIG_ADDR, &data, 1, dev); + if (rslt == BMA4_OK) + { + /* Write Accel FIFO filter data */ + data = BMA4_SET_BITSLICE(data, BMA4_NV_ACCEL_OFFSET, offset_en); + rslt = bma4_write_regs(BMA4_NV_CONFIG_ADDR, &data, 1, dev); + } + } + + return rslt; +} + +/*! + * @brief This API gets the status of Accel offset compensation + */ +int8_t bma4_get_offset_comp(uint8_t *offset_en, struct bma4_dev *dev) +{ + int8_t rslt; + uint8_t data = 0; + + /* Check the dev structure as NULL */ + rslt = null_pointer_check(dev); + + if ((rslt == BMA4_OK) && (offset_en != NULL)) + { + rslt = bma4_read_regs(BMA4_NV_CONFIG_ADDR, &data, 1, dev); + if (rslt == BMA4_OK) + { + /* Write Accel FIFO filter data */ + *offset_en = BMA4_GET_BITSLICE(data, BMA4_NV_ACCEL_OFFSET); + } + } + else + { + rslt = BMA4_E_NULL_PTR; + } + + return rslt; +} + +/*! + * @brief This API checks whether the self-test functionality of the sensor + * is working or not. + * The following parameter of struct bma4_dev, should have the valid value + * before performing the self-test, + * 1. Variant and 2. Resolution + */ +int8_t bma4_perform_accel_selftest(int8_t *result, struct bma4_dev *dev) +{ + int8_t rslt; + struct bma4_accel positive = { 0, 0, 0 }; + struct bma4_accel negative = { 0, 0, 0 }; + + /*! Structure for difference of accel values in mg */ + struct bma4_selftest_delta_limit accel_data_diff_mg = { 0, 0, 0 }; + + /* Check the dev structure as NULL */ + rslt = null_pointer_check(dev); + + if ((rslt == BMA4_OK) && (result != NULL)) + { + *result = BMA4_SELFTEST_FAIL; + + rslt = set_accel_selftest_config(dev); + + if (rslt == BMA4_OK) + { + /* Wait for 2ms after accel self-test config please refer data sheet data sheet 4.9. sensor self-test */ + dev->delay_us(BMA4_MS_TO_US(2), dev->intf_ptr); + + rslt = selftest_config(BMA4_ENABLE, dev); + + if (rslt == BMA4_OK) + { + /* Taking positive data */ + + /* User should wait 50ms before interpreting the acceleration data. + * please refer data sheet 4.9. sensor self-test + */ + dev->delay_us(BMA4_MS_TO_US(50), dev->intf_ptr); + rslt = bma4_read_accel_xyz(&positive, dev); + + if (rslt == BMA4_OK) + { + rslt = selftest_config(BMA4_DISABLE, dev); + + if (rslt == BMA4_OK) + { + /* User should wait 50ms before interpreting the acceleration data. + * please refer data sheet 4.9. sensor self-test + */ + dev->delay_us(BMA4_MS_TO_US(50), dev->intf_ptr); + rslt = bma4_read_accel_xyz(&negative, dev); + if (rslt == BMA4_OK) + { + rslt = *result = get_accel_data_difference_and_validate(positive, + negative, + &accel_data_diff_mg, + dev); + + if (rslt == BMA4_OK) + { + /* Triggers a soft reset */ + rslt = bma4_soft_reset(dev); + dev->delay_us(BMA4_MS_TO_US(200), dev->intf_ptr); + } + } + } + } + } + } + } + else + { + rslt = BMA4_E_NULL_PTR; + } + + return rslt; +} + +/*! @cond DOXYGEN_SUPRESS */ + +/* Suppressing doxygen warnings triggered for same static function names present across various sensor variant + * directories */ + +/*! + * @brief This Internal API validates accel self-test status from positive and negative axes input + */ +static int8_t get_accel_data_difference_and_validate(struct bma4_accel positive, + struct bma4_accel negative, + struct bma4_selftest_delta_limit *accel_data_diff_mg, + const struct bma4_dev *dev) +{ + int8_t rslt; + + /*! Structure for difference of accel values in g */ + struct bma4_selftest_delta_limit accel_data_diff = { 0, 0, 0 }; + + accel_data_diff.x = ABS(positive.x - negative.x); + accel_data_diff.y = ABS(positive.y - negative.y); + accel_data_diff.z = ABS(positive.z - negative.z); + + /*! Converting LSB of the differences of accel values to mg */ + convert_lsb_g(&accel_data_diff, accel_data_diff_mg, dev); + + /*! Validating self-test for accel values in mg */ + rslt = validate_selftest(accel_data_diff_mg, dev); + + return rslt; +} + +/*! @endcond */ + +/*! + * @brief API sets the interrupt to either interrupt1 or + * interrupt2 pin in the sensor. + */ +int8_t bma4_map_interrupt(uint8_t int_line, uint16_t int_map, uint8_t enable, struct bma4_dev *dev) +{ + int8_t rslt; + uint8_t data[3] = { 0, 0, 0 }; + uint8_t index[2] = { BMA4_INT_MAP_1_ADDR, BMA4_INT_MAP_2_ADDR }; + + /* Check the dev structure as NULL */ + rslt = null_pointer_check(dev); + + if (rslt == BMA4_OK) + { + rslt = bma4_read_regs(BMA4_INT_MAP_1_ADDR, data, 3, dev); + if (rslt == BMA4_OK) + { + if (enable == TRUE) + { + /* Feature interrupt mapping */ + data[int_line] |= (uint8_t)(int_map & (0x00FF)); + + /* Hardware interrupt mapping */ + data[2] |= (uint8_t)((int_map & (0xFF00)) >> (8 - (4 * int_line))); + } + else + { + /* Feature interrupt un-mapping */ + data[int_line] &= (~(uint8_t)(int_map & (0x00FF))); + + /* Hardware interrupt un-mapping */ + data[2] &= (~(uint8_t)((int_map & (0xFF00)) >> (8 - (4 * int_line)))); + } + + rslt = bma4_write_regs(index[int_line], &data[int_line], 1, dev); + if (rslt == BMA4_OK) + { + rslt = bma4_write_regs(BMA4_INT_MAP_DATA_ADDR, &data[2], 1, dev); + } + } + } + + return rslt; +} + +/*! + * @brief This API sets the interrupt mode in the sensor. + */ +int8_t bma4_set_interrupt_mode(uint8_t mode, struct bma4_dev *dev) +{ + int8_t rslt; + + /* Check the dev structure as NULL */ + rslt = null_pointer_check(dev); + + if (rslt == BMA4_OK) + { + if ((mode == BMA4_NON_LATCH_MODE) || (mode == BMA4_LATCH_MODE)) + { + rslt = bma4_write_regs(BMA4_INTR_LATCH_ADDR, &mode, 1, dev); + } + else + { + rslt = BMA4_E_OUT_OF_RANGE; + } + } + + return rslt; +} + +/*! + * @brief This API gets the interrupt mode which is set in the sensor. + */ +int8_t bma4_get_interrupt_mode(uint8_t *mode, struct bma4_dev *dev) +{ + int8_t rslt; + uint8_t data = 0; + + /* Check the dev structure as NULL */ + rslt = null_pointer_check(dev); + + if ((rslt == BMA4_OK) && (mode != NULL)) + { + rslt = bma4_read_regs(BMA4_INTR_LATCH_ADDR, &data, 1, dev); + *mode = data; + } + else + { + rslt = BMA4_E_NULL_PTR; + } + + return rslt; +} + +/*! + * @brief This API sets the auxiliary Mag(BMM150 or AKM9916) output data + * rate and offset. + */ +int8_t bma4_set_aux_mag_config(const struct bma4_aux_mag_config *aux_mag, struct bma4_dev *dev) +{ + int8_t rslt; + uint8_t data = 0; + + /* Check the dev structure as NULL */ + rslt = null_pointer_check(dev); + + if ((rslt == BMA4_OK) && (aux_mag != NULL)) + { + if ((aux_mag->odr >= BMA4_OUTPUT_DATA_RATE_0_78HZ) && (aux_mag->odr <= BMA4_OUTPUT_DATA_RATE_1600HZ) && + ((aux_mag->offset & BMA4_MAG_CONFIG_OFFSET_MSK) == 0x00)) + { + data = (uint8_t)(aux_mag->odr | ((aux_mag->offset << BMA4_MAG_CONFIG_OFFSET_POS))); + rslt = bma4_write_regs(BMA4_AUX_CONFIG_ADDR, &data, 1, dev); + } + else + { + rslt = BMA4_E_OUT_OF_RANGE; + } + } + else + { + rslt = BMA4_E_NULL_PTR; + } + + return rslt; +} + +/*! + * @brief This API reads the auxiliary Mag(BMM150 or AKM9916) output data + * rate and offset. + */ +int8_t bma4_get_aux_mag_config(struct bma4_aux_mag_config *aux_mag, struct bma4_dev *dev) +{ + int8_t rslt; + uint8_t data = 0; + + /* Check the dev structure as NULL */ + rslt = null_pointer_check(dev); + + if ((rslt == BMA4_OK) && (aux_mag != NULL)) + { + rslt = bma4_read_regs(BMA4_AUX_CONFIG_ADDR, &data, 1, dev); + if (rslt == BMA4_OK) + { + aux_mag->odr = (data & 0x0F); + aux_mag->offset = (data & BMA4_MAG_CONFIG_OFFSET_MSK) >> 4; + } + } + else + { + rslt = BMA4_E_NULL_PTR; + } + + return rslt; +} + +/*! @brief This API sets the FIFO configuration in the sensor. */ +int8_t bma4_set_fifo_config(uint8_t config, uint8_t enable, struct bma4_dev *dev) +{ + int8_t rslt; + uint8_t data[2] = { 0, 0 }; + uint8_t fifo_config_0 = config & BMA4_FIFO_CONFIG_0_MASK; + + /* Check the dev structure as NULL */ + rslt = null_pointer_check(dev); + + if (rslt == BMA4_OK) + { + rslt = bma4_read_regs(BMA4_FIFO_CONFIG_0_ADDR, data, BMA4_FIFO_CONFIG_LENGTH, dev); + if (rslt == BMA4_OK) + { + if (fifo_config_0 > 0) + { + if (enable == TRUE) + { + data[0] = data[0] | fifo_config_0; + } + else + { + data[0] = data[0] & (~fifo_config_0); + } + } + + if (enable == TRUE) + { + data[1] = data[1] | (config & BMA4_FIFO_CONFIG_1_MASK); + } + else + { + data[1] = data[1] & (~(config & BMA4_FIFO_CONFIG_1_MASK)); + } + + /* Burst write is not possible in suspend mode hence + * separate write is used with delay of 1 ms + */ + rslt = bma4_write_regs(BMA4_FIFO_CONFIG_0_ADDR, &data[0], 1, dev); + + if (rslt == BMA4_OK) + { + dev->delay_us(BMA4_GEN_READ_WRITE_DELAY, dev->intf_ptr); + rslt = bma4_write_regs(BMA4_FIFO_CONFIG_1_ADDR, &data[1], 1, dev); + } + } + } + + return rslt; +} + +/*! @brief This API reads the FIFO configuration from the sensor. + */ +int8_t bma4_get_fifo_config(uint8_t *fifo_config, struct bma4_dev *dev) +{ + int8_t rslt; + uint8_t data[2] = { 0, 0 }; + + /* Check the dev structure as NULL */ + rslt = null_pointer_check(dev); + + if ((rslt == BMA4_OK) && (fifo_config != NULL)) + { + rslt = bma4_read_regs(BMA4_FIFO_CONFIG_0_ADDR, data, BMA4_FIFO_CONFIG_LENGTH, dev); + if (rslt == BMA4_OK) + { + *fifo_config = ((uint8_t)((data[0] & BMA4_FIFO_CONFIG_0_MASK) | (data[1]))); + } + } + else + { + rslt = BMA4_E_NULL_PTR; + } + + return rslt; +} + +/*! @brief This function sets the electrical behaviour of interrupt pin1 or + * pin2 in the sensor. + */ +int8_t bma4_set_int_pin_config(const struct bma4_int_pin_config *int_pin_config, uint8_t int_line, struct bma4_dev *dev) +{ + int8_t rslt; + uint8_t interrupt_address_array[2] = { BMA4_INT1_IO_CTRL_ADDR, BMA4_INT2_IO_CTRL_ADDR }; + uint8_t data = 0; + + /* Check the dev structure as NULL */ + rslt = null_pointer_check(dev); + + if ((rslt == BMA4_OK) && (int_pin_config != NULL)) + { + if (int_line <= 1) + { + data = + ((uint8_t)((int_pin_config->edge_ctrl & BMA4_INT_EDGE_CTRL_MASK) | + ((int_pin_config->lvl << 1) & BMA4_INT_LEVEL_MASK) | + ((int_pin_config->od << 2) & BMA4_INT_OPEN_DRAIN_MASK) | + ((int_pin_config->output_en << 3) & BMA4_INT_OUTPUT_EN_MASK) | + ((int_pin_config->input_en << 4) & BMA4_INT_INPUT_EN_MASK))); + rslt = bma4_write_regs(interrupt_address_array[int_line], &data, 1, dev); + } + else + { + rslt = BMA4_E_INT_LINE_INVALID; + } + } + else + { + rslt = BMA4_E_NULL_PTR; + } + + return rslt; +} + +/*! @brief This API reads the electrical behavior of interrupt pin1 or pin2 + * from the sensor. + */ +int8_t bma4_get_int_pin_config(struct bma4_int_pin_config *int_pin_config, uint8_t int_line, struct bma4_dev *dev) +{ + int8_t rslt; + uint8_t interrupt_address_array[2] = { BMA4_INT1_IO_CTRL_ADDR, BMA4_INT2_IO_CTRL_ADDR }; + uint8_t data = 0; + + /* Check the dev structure as NULL */ + rslt = null_pointer_check(dev); + + if ((rslt == BMA4_OK) && (int_pin_config != NULL)) + { + if (int_line <= 1) + { + rslt = bma4_read_regs(interrupt_address_array[int_line], &data, 1, dev); + + /* Assign interrupt configurations to the + * structure members + */ + if (rslt == BMA4_OK) + { + int_pin_config->edge_ctrl = data & BMA4_INT_EDGE_CTRL_MASK; + int_pin_config->lvl = ((data & BMA4_INT_LEVEL_MASK) >> BMA4_INT_LEVEL_POS); + int_pin_config->od = ((data & BMA4_INT_OPEN_DRAIN_MASK) >> BMA4_INT_OPEN_DRAIN_POS); + int_pin_config->output_en = ((data & BMA4_INT_OUTPUT_EN_MASK) >> BMA4_INT_OUTPUT_EN_POS); + int_pin_config->input_en = ((data & BMA4_INT_INPUT_EN_MASK) >> BMA4_INT_INPUT_EN_POS); + } + } + else + { + rslt = BMA4_E_INT_LINE_INVALID; + } + } + else + { + rslt = BMA4_E_NULL_PTR; + } + + return rslt; +} + +/*! + * @brief This API reads the Feature and Hardware interrupt status from the sensor. + */ +int8_t bma4_read_int_status(uint16_t *int_status, struct bma4_dev *dev) +{ + int8_t rslt; + uint8_t data[2] = { 0 }; + + /* Check the dev structure as NULL */ + rslt = null_pointer_check(dev); + + if ((rslt == BMA4_OK) && (int_status != NULL)) + { + rslt = bma4_read_regs(BMA4_INT_STAT_0_ADDR, data, 2, dev); + if (rslt == BMA4_OK) + { + *int_status = data[0]; + *((uint8_t *)int_status + 1) = data[1]; + } + } + else + { + rslt = BMA4_E_NULL_PTR; + } + + return rslt; +} + +/*! + * @brief This API initializes the auxiliary interface to access + * auxiliary sensor + */ +int8_t bma4_aux_interface_init(struct bma4_dev *dev) +{ + /* Variable to return error codes */ + int8_t rslt; + + /* Check for Null pointer error */ + rslt = null_pointer_check(dev); + + if (rslt == BMA4_OK) + { + /* Set the auxiliary sensor configuration */ + rslt = set_aux_interface_config(dev); + if (rslt != BMA4_OK) + { + rslt = BMA4_E_AUX_CONFIG_FAIL; + } + } + + return rslt; +} + +/*! + * @brief This API reads the data from the auxiliary sensor + */ +int8_t bma4_aux_read(uint8_t aux_reg_addr, uint8_t *aux_data, uint16_t len, struct bma4_dev *dev) +{ + /* Variable to return error codes */ + int8_t rslt; + + /* Check for Null pointer error */ + rslt = null_pointer_check(dev); + + if ((rslt == BMA4_OK) && (aux_data != NULL)) + { + /* Read the data from the data register in terms of + * user defined length + */ + rslt = extract_aux_data(aux_reg_addr, aux_data, len, dev); + } + else + { + rslt = BMA4_E_NULL_PTR; + } + + return rslt; +} + +/*! + * @brief This API writes the data into the auxiliary sensor + */ +int8_t bma4_aux_write(uint8_t aux_reg_addr, const uint8_t *aux_data, uint16_t len, struct bma4_dev *dev) +{ + int8_t rslt; + + /* Check for Null pointer error */ + rslt = null_pointer_check(dev); + + if ((rslt == BMA4_OK) && (aux_data != NULL)) + { + /* Write data in terms of user defined length */ + if (len > 0) + { + while (len--) + { + /* First set data to write */ + rslt = bma4_write_regs(BMA4_AUX_WR_DATA_ADDR, aux_data, 1, dev); + dev->delay_us(BMA4_AUX_COM_DELAY, dev->intf_ptr); + if (rslt == BMA4_OK) + { + /* Then set address to write */ + rslt = bma4_write_regs(BMA4_AUX_WR_ADDR, &aux_reg_addr, 1, dev); + dev->delay_us(BMA4_AUX_COM_DELAY, dev->intf_ptr); + + /* Increment data array and register + * address until user-defined length is + * greater than 0 + */ + if ((rslt == BMA4_OK) && (len > 0)) + { + aux_data++; + aux_reg_addr++; + } + } + else + { + rslt = BMA4_E_COM_FAIL; + } + } + } + else + { + rslt = BMA4_E_RD_WR_LENGTH_INVALID; + } + } + else + { + rslt = BMA4_E_NULL_PTR; + } + + return rslt; +} + +/*! + * @brief This API gets the re-mapped x, y and z axes from the sensor and + * updates the values in the device structure. + */ +int8_t bma4_get_remap_axes(struct bma4_remap *remap_data, + uint8_t *feature_config, + uint8_t index, + uint8_t feature_len, + struct bma4_dev *dev) +{ + /* Variable to define error */ + int8_t rslt; + + /* Null-pointer check */ + rslt = null_pointer_check(dev); + + if (rslt == BMA4_OK) + { + /* Get the re-mapped axes from the sensor */ + rslt = get_remap_axes(&dev->remap, feature_config, index, feature_len, dev); + if (rslt == BMA4_OK) + { + /* Store the receive re-mapped axis and sign from device structure */ + receive_remap_axis(dev->remap.x_axis, dev->remap.x_axis_sign, &remap_data->x); + receive_remap_axis(dev->remap.y_axis, dev->remap.y_axis_sign, &remap_data->y); + receive_remap_axis(dev->remap.z_axis, dev->remap.z_axis_sign, &remap_data->z); + } + } + + return rslt; +} + +/*! + * @brief This API sets the re-mapped x, y and z axes to the sensor and + * updates the them in the device structure. + */ +int8_t bma4_set_remap_axes(const struct bma4_remap *remapped_axis, + uint8_t *feature_config, + uint8_t index, + uint8_t feature_len, + struct bma4_dev *dev) +{ + /* Variable to define error */ + int8_t rslt; + + /* Variable to store all the re-mapped axes */ + uint8_t remap_axes = 0; + + /* Null-pointer check */ + rslt = null_pointer_check(dev); + + if (rslt == BMA4_OK) + { + /* Check whether all the axes are re-mapped */ + remap_axes = remapped_axis->x | remapped_axis->y | remapped_axis->z; + + /* If all the axes are re-mapped */ + if ((remap_axes & BMA4_AXIS_MASK) == BMA4_AXIS_MASK) + { + /* Store the value of re-mapped in device structure */ + assign_remap_axis(remapped_axis->x, &dev->remap.x_axis, &dev->remap.x_axis_sign); + assign_remap_axis(remapped_axis->y, &dev->remap.y_axis, &dev->remap.y_axis_sign); + assign_remap_axis(remapped_axis->z, &dev->remap.z_axis, &dev->remap.z_axis_sign); + + /* Set the re-mapped axes in the sensor */ + rslt = set_remap_axes(&dev->remap, feature_config, index, feature_len, dev); + } + else + { + rslt = BMA4_E_REMAP_ERROR; + } + } + + return rslt; +} + +/*****************************************************************************/ +/*! @cond DOXYGEN_SUPRESS */ + +/* Suppressing doxygen warnings triggered for same static function names present across various sensor variant + * directories */ + +/* Static function definition */ + +/*! + * @brief This API converts lsb value of axes to mg for self-test * + */ +static void convert_lsb_g(const struct bma4_selftest_delta_limit *accel_data_diff, + struct bma4_selftest_delta_limit *accel_data_diff_mg, + const struct bma4_dev *dev) +{ + uint32_t lsb_per_g; + + /*! Range considered for self-test is 8g */ + uint8_t range = 8; + + /*! lsb_per_g for the respective resolution and 8g range*/ + lsb_per_g = (uint32_t)(power(2, dev->resolution) / (2 * range)); + + /*! accel x value in mg */ + accel_data_diff_mg->x = (accel_data_diff->x / (int32_t)lsb_per_g) * 1000; + + /*! accel y value in mg */ + accel_data_diff_mg->y = (accel_data_diff->y / (int32_t)lsb_per_g) * 1000; + + /*! accel z value in mg */ + accel_data_diff_mg->z = (accel_data_diff->z / (int32_t)lsb_per_g) * 1000; +} + +/*! + * @brief This API writes the config stream data in memory using burst mode + * @note index value should be even number. + */ +static int8_t stream_transfer_write(const uint8_t *stream_data, uint16_t index, struct bma4_dev *dev) +{ + int8_t rslt; + uint8_t asic_msb = (uint8_t)((index / 2) >> 4); + uint8_t asic_lsb = ((index / 2) & 0x0F); + + /* Check the dev structure as NULL */ + rslt = null_pointer_check(dev); + + if ((rslt == BMA4_OK) && (stream_data != NULL)) + { + rslt = bma4_write_regs(BMA4_RESERVED_REG_5B_ADDR, &asic_lsb, 1, dev); + if (rslt == BMA4_OK) + { + rslt = bma4_write_regs(BMA4_RESERVED_REG_5C_ADDR, &asic_msb, 1, dev); + if (rslt == BMA4_OK) + { + rslt = write_regs(BMA4_FEATURE_CONFIG_ADDR, (uint8_t *)stream_data, dev->read_write_len, dev); + } + } + } + else + { + rslt = BMA4_E_NULL_PTR; + } + + return rslt; +} + +/*! + * @brief This API enables or disables the Accel self-test feature in the + * sensor. + */ +static int8_t set_accel_selftest_enable(uint8_t accel_selftest_enable, struct bma4_dev *dev) +{ + int8_t rslt; + uint8_t data = 0; + + /* Check the dev structure as NULL */ + rslt = null_pointer_check(dev); + + if (rslt == BMA4_OK) + { + /* Read the self-test register */ + rslt = bma4_read_regs(BMA4_ACC_SELF_TEST_ADDR, &data, 1, dev); + if (rslt == BMA4_OK) + { + data = BMA4_SET_BITS_POS_0(data, BMA4_ACCEL_SELFTEST_ENABLE, accel_selftest_enable); + rslt = bma4_write_regs(BMA4_ACC_SELF_TEST_ADDR, &data, 1, dev); + } + } + + return rslt; +} + +/*! + * @brief This API selects the sign of Accel self-test excitation. + */ +static int8_t set_accel_selftest_sign(uint8_t accel_selftest_sign, struct bma4_dev *dev) +{ + int8_t rslt; + uint8_t data = 0; + + /* Check the dev structure as NULL */ + rslt = null_pointer_check(dev); + + if (rslt == BMA4_OK) + { + if (accel_selftest_sign <= BMA4_MAX_VALUE_SELFTEST_SIGN) + { + /* Read the Accel self-test sign*/ + rslt = bma4_read_regs(BMA4_ACC_SELF_TEST_ADDR, &data, 1, dev); + if (rslt == BMA4_OK) + { + data = BMA4_SET_BITSLICE(data, BMA4_ACCEL_SELFTEST_SIGN, accel_selftest_sign); + rslt = bma4_write_regs(BMA4_ACC_SELF_TEST_ADDR, &data, 1, dev); + } + } + else + { + rslt = BMA4_E_OUT_OF_RANGE; + } + } + + return rslt; +} + +/*! + * @brief This API sets the Accel self-test amplitude in the sensor. + */ +static int8_t set_accel_selftest_amp(uint8_t accel_selftest_amp, struct bma4_dev *dev) +{ + int8_t rslt; + uint8_t data = 0; + + /* Check the dev structure as NULL */ + rslt = null_pointer_check(dev); + + if (rslt == BMA4_OK) + { + if (accel_selftest_amp <= BMA4_MAX_VALUE_SELFTEST_AMP) + { + /* Write self-test amplitude*/ + rslt = bma4_read_regs(BMA4_ACC_SELF_TEST_ADDR, &data, 1, dev); + if (rslt == BMA4_OK) + { + data = BMA4_SET_BITSLICE(data, BMA4_SELFTEST_AMP, accel_selftest_amp); + rslt = bma4_write_regs(BMA4_ACC_SELF_TEST_ADDR, &data, 1, dev); + } + } + else + { + rslt = BMA4_E_OUT_OF_RANGE; + } + } + + return rslt; +} + +/*! + * @brief This function enables and configures the Accel which is needed + * for self-test operation. + */ +static int8_t set_accel_selftest_config(struct bma4_dev *dev) +{ + int8_t rslt; + struct bma4_accel_config accel = { 0, 0, 0, 0 }; + + accel.odr = BMA4_OUTPUT_DATA_RATE_1600HZ; + accel.bandwidth = BMA4_ACCEL_NORMAL_AVG4; + accel.perf_mode = BMA4_ENABLE; + accel.range = BMA4_ACCEL_RANGE_8G; + + rslt = bma4_set_accel_enable(BMA4_ENABLE, dev); + dev->delay_us(BMA4_MS_TO_US(5), dev->intf_ptr); + + if (rslt == BMA4_OK) + { + rslt = bma4_set_accel_config(&accel, dev); + } + + return rslt; +} + +/*! + * @brief This API is used to reset the FIFO related configurations + * in the fifo_frame structure. + * + */ +static void reset_fifo_data_structure(struct bma4_fifo_frame *fifo) +{ + /*Prepare for next FIFO read by resetting FIFO's + * internal data structures + */ + fifo->accel_byte_start_idx = 0; + fifo->mag_byte_start_idx = 0; + fifo->sc_frame_byte_start_idx = 0; + fifo->sensor_time = 0; + fifo->skipped_frame_count = 0; + fifo->accel_dropped_frame_count = 0; + fifo->mag_dropped_frame_count = 0; +} + +/*! + * @brief This API computes the number of bytes of accel FIFO data + * which is to be parsed in header-less mode + */ +static void get_accel_len_to_parse(uint16_t *start_idx, + uint16_t *len, + const uint16_t *acc_count, + const struct bma4_fifo_frame *fifo) +{ + /*Data start index*/ + *start_idx = fifo->accel_byte_start_idx; + if (fifo->fifo_data_enable == BMA4_FIFO_A_ENABLE) + { + /*Len has the number of bytes to loop for */ + *len = (uint16_t)(((*acc_count) * BMA4_FIFO_A_LENGTH)); + } + else if (fifo->fifo_data_enable == BMA4_FIFO_M_A_ENABLE) + { + /*Len has the number of bytes to loop for */ + *len = (uint16_t)(((*acc_count) * BMA4_FIFO_MA_LENGTH)); + } + else + { + /*Only aux. sensor or no sensor is enabled in FIFO, + * so there will be no accel data. + * Update the data index as complete + */ + *start_idx = fifo->length; + } + + if ((*len) > fifo->length) + { + /*Handling the case where more data is requested + * than available + */ + *len = fifo->length; + } +} + +/*! + * @brief This API checks the fifo read data as empty frame, if it + * is empty frame then moves the index to last byte. + */ +static void check_empty_fifo(uint16_t *data_index, const struct bma4_fifo_frame *fifo) +{ + if ((*data_index + 6) < fifo->length) + { + /* Check if FIFO is empty (For X, Y and Z)*/ + if (((fifo->data[(*data_index)] == BMA4_FIFO_LSB_CONFIG_CHECK) && + (fifo->data[(*data_index) + 1] == BMA4_FIFO_MSB_CONFIG_CHECK)) && + ((fifo->data[(*data_index) + 2] == BMA4_FIFO_LSB_CONFIG_CHECK) && + (fifo->data[(*data_index) + 3] == BMA4_FIFO_MSB_CONFIG_CHECK)) && + ((fifo->data[(*data_index) + 4] == BMA4_FIFO_LSB_CONFIG_CHECK) && + (fifo->data[(*data_index) + 5] == BMA4_FIFO_MSB_CONFIG_CHECK))) + { + /*Update the data index as complete*/ + *data_index = fifo->length; + } + } +} + +/*! + * @brief This API is used to parse the accelerometer data from the + * FIFO data in header mode. + * + */ +static void extract_accel_header_mode(struct bma4_accel *accel_data, + uint16_t *accel_length, + struct bma4_fifo_frame *fifo, + const struct bma4_dev *dev) +{ + uint8_t frame_header = 0; + uint16_t data_index; + uint16_t accel_index = 0; + uint16_t frame_to_read = *accel_length; + + for (data_index = fifo->accel_byte_start_idx; data_index < fifo->length;) + { + /*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 & BMA4_FIFO_TAG_INTR_MASK; + + /*Index is moved to next byte where the data is starting*/ + data_index++; + switch (frame_header) + { + /* Accel frame */ + case BMA4_FIFO_HEAD_A: + case BMA4_FIFO_HEAD_M_A: + unpack_acc_frm(accel_data, &data_index, &accel_index, frame_header, fifo, dev); + break; + + /* Aux. sensor frame */ + case BMA4_FIFO_HEAD_M: + move_next_frame(&data_index, BMA4_FIFO_M_LENGTH, fifo); + break; + + /* Sensor time frame */ + case BMA4_FIFO_HEAD_SENSOR_TIME: + unpack_sensortime_frame(&data_index, fifo); + break; + + /* Skip frame */ + case BMA4_FIFO_HEAD_SKIP_FRAME: + unpack_skipped_frame(&data_index, fifo); + break; + + /* Input config frame */ + case BMA4_FIFO_HEAD_INPUT_CONFIG: + move_next_frame(&data_index, 1, fifo); + break; + + /* Sample drop frame */ + case BMA4_FIFO_HEAD_SAMPLE_DROP: + unpack_dropped_frame(&data_index, fifo); + break; + + /* Over read FIFO data */ + case BMA4_FIFO_HEAD_OVER_READ_MSB: + + /* Update the data index as complete*/ + data_index = fifo->length; + break; + default: + break; + } + if (frame_to_read == accel_index) + { + /*Number of frames to read completed*/ + break; + } + } + + /*Update number of accel data read*/ + *accel_length = accel_index; + + /*Update the accel frame index*/ + fifo->accel_byte_start_idx = data_index; +} + +/*! + * @brief This API is used to parse the accelerometer data from the + * FIFO data in both header mode and header-less mode. + * It update the idx value which is used to store the index of + * the current data byte which is parsed. + */ +static void unpack_acc_frm(struct bma4_accel *acc, + uint16_t *idx, + uint16_t *acc_idx, + uint8_t frm, + const struct bma4_fifo_frame *fifo, + const struct bma4_dev *dev) +{ + + switch (frm) + { + case BMA4_FIFO_HEAD_A: + case BMA4_FIFO_A_ENABLE: + + /*Partial read, then skip the data*/ + if ((*idx + BMA4_FIFO_A_LENGTH) > fifo->length) + { + /*Update the data index as complete*/ + *idx = fifo->length; + break; + } + + /*Unpack the data array into the structure instance "acc" */ + unpack_accel_data(&acc[*acc_idx], *idx, fifo, dev); + + /*Move the data index*/ + *idx = *idx + BMA4_FIFO_A_LENGTH; + (*acc_idx)++; + break; + case BMA4_FIFO_HEAD_M_A: + case BMA4_FIFO_M_A_ENABLE: + + /*Partial read, then skip the data*/ + if ((*idx + BMA4_FIFO_MA_LENGTH) > fifo->length) + { + /*Update the data index as complete*/ + *idx = fifo->length; + break; + } + + /*Unpack the data array into structure instance "acc"*/ + unpack_accel_data(&acc[*acc_idx], *idx + BMA4_MA_FIFO_A_X_LSB, fifo, dev); + + /*Move the data index*/ + *idx = *idx + BMA4_FIFO_MA_LENGTH; + (*acc_idx)++; + break; + + /* Aux. sensor frame */ + case BMA4_FIFO_HEAD_M: + case BMA4_FIFO_M_ENABLE: + (*idx) = (*idx) + BMA4_FIFO_M_LENGTH; + break; + default: + break; + } +} + +/*! + * @brief This API is used to parse the accelerometer data from the + * FIFO data and store it in the instance of the structure bma4_accel. + */ +static void unpack_accel_data(struct bma4_accel *accel_data, + uint16_t data_start_index, + const struct bma4_fifo_frame *fifo, + const struct bma4_dev *dev) +{ + uint16_t data_lsb; + uint16_t data_msb; + + /* 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); + + /* 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); + + /* 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); + if (dev->resolution == BMA4_12_BIT_RESOLUTION) + { + accel_data->x = (accel_data->x / 0x10); + accel_data->y = (accel_data->y / 0x10); + accel_data->z = (accel_data->z / 0x10); + } + else if (dev->resolution == BMA4_14_BIT_RESOLUTION) + { + accel_data->x = (accel_data->x / 0x04); + accel_data->y = (accel_data->y / 0x04); + accel_data->z = (accel_data->z / 0x04); + } +} + +/*! + * @brief This API computes the number of bytes of Mag FIFO data which is + * to be parsed in header-less mode + * + */ +static void get_mag_len_to_parse(uint16_t *start_idx, + uint16_t *len, + const uint16_t *mag_count, + const struct bma4_fifo_frame *fifo) +{ + /*Data start index*/ + *start_idx = fifo->mag_byte_start_idx; + if (fifo->fifo_data_enable == BMA4_FIFO_M_ENABLE) + { + /*Len has the number of bytes to loop for */ + *len = (uint16_t)(((*mag_count) * BMA4_FIFO_M_LENGTH)); + } + else if (fifo->fifo_data_enable == BMA4_FIFO_M_A_ENABLE) + { + /*Len has the number of bytes to loop for */ + *len = (uint16_t)(((*mag_count) * BMA4_FIFO_MA_LENGTH)); + } + else + { + /*Only accel sensor or no sensor is enabled in FIFO, + * so there will be no mag data. + * Update the data index as complete + */ + *start_idx = fifo->length; + } + + /*Handling the case where more data is requested than available*/ + if ((*len) > fifo->length) + { + /*Len is equal to the FIFO length*/ + *len = fifo->length; + } +} + +/*! + * @brief This API is used to parse the magnetometer data from the + * FIFO data in header mode. + * + */ +static int8_t extract_mag_header_mode(const struct bma4_mag *data, + uint16_t *len, + struct bma4_fifo_frame *fifo, + const struct bma4_dev *dev) +{ + int8_t rslt = BMA4_OK; + uint8_t frame_header = 0; + uint16_t data_index; + uint16_t mag_index = 0; + uint16_t frame_to_read = *len; + + for (data_index = fifo->mag_byte_start_idx; data_index < fifo->length;) + { + /*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 & BMA4_FIFO_TAG_INTR_MASK; + + /*Index is moved to next byte where the data is starting*/ + data_index++; + switch (frame_header) + { + /* Aux. sensor frame */ + case BMA4_FIFO_HEAD_M: + case BMA4_FIFO_HEAD_M_A: + rslt = unpack_mag_frm(data, &data_index, &mag_index, frame_header, fifo, dev); + break; + + /* Aux. sensor frame */ + case BMA4_FIFO_HEAD_A: + move_next_frame(&data_index, BMA4_FIFO_A_LENGTH, fifo); + break; + + /* Sensor time frame */ + case BMA4_FIFO_HEAD_SENSOR_TIME: + unpack_sensortime_frame(&data_index, fifo); + break; + + /* Skip frame */ + case BMA4_FIFO_HEAD_SKIP_FRAME: + unpack_skipped_frame(&data_index, fifo); + break; + + /* Input config frame */ + case BMA4_FIFO_HEAD_INPUT_CONFIG: + move_next_frame(&data_index, 1, fifo); + break; + + /* Sample drop frame */ + case BMA4_FIFO_HEAD_SAMPLE_DROP: + unpack_dropped_frame(&data_index, fifo); + break; + case BMA4_FIFO_HEAD_OVER_READ_MSB: + + /*Update the data index as complete*/ + data_index = fifo->length; + break; + default: + break; + } + if (frame_to_read == mag_index) + { + /*Number of frames to read completed*/ + break; + } + } + + /*update number of Aux. sensor data read*/ + *len = mag_index; + + /*update the Aux. sensor frame index*/ + fifo->mag_byte_start_idx = data_index; + + return rslt; +} + +/*! + * @brief This API is used to parse the magnetometer data from the + * FIFO data in both header mode and header-less mode and update the + * data_index value which is used to store the index of the current + * data byte which is parsed. + * + */ +static int8_t unpack_mag_frm(const struct bma4_mag *data, + uint16_t *idx, + uint16_t *mag_idx, + uint8_t frm, + const struct bma4_fifo_frame *fifo, + const struct bma4_dev *dev) +{ + int8_t rslt = BMA4_OK; + + switch (frm) + { + case BMA4_FIFO_HEAD_M: + case BMA4_FIFO_M_ENABLE: + + /*partial read, then skip the data*/ + if ((*idx + BMA4_FIFO_M_LENGTH) > fifo->length) + { + /*update the data index as complete*/ + *idx = fifo->length; + break; + } + + /*unpack the data array into Aux. sensor data structure*/ + rslt = unpack_mag_data(&data[*mag_idx], *idx, fifo, dev); + + /*move the data index*/ + *idx = *idx + BMA4_FIFO_M_LENGTH; + (*mag_idx)++; + break; + case BMA4_FIFO_HEAD_M_A: + case BMA4_FIFO_M_A_ENABLE: + + /*partial read, then skip the data*/ + if ((*idx + BMA4_FIFO_MA_LENGTH) > fifo->length) + { + /*update the data index as complete*/ + *idx = fifo->length; + break; + } + + /*unpack the data array into Aux. sensor data structure*/ + rslt = unpack_mag_data(&data[*mag_idx], *idx, fifo, dev); + + /*move the data index to next frame*/ + *idx = *idx + BMA4_FIFO_MA_LENGTH; + (*mag_idx)++; + break; + + /* aux. sensor frame */ + case BMA4_FIFO_HEAD_A: + case BMA4_FIFO_A_ENABLE: + (*idx) = (*idx) + BMA4_FIFO_A_LENGTH; + break; + default: + break; + } + + return rslt; +} + +/*! + * @brief This API is used to parse the auxiliary magnetometer data from + * the FIFO data and store it in the instance of the structure mag_data. + * + */ +static int8_t unpack_mag_data(const struct bma4_mag *mag_data, + uint16_t start_idx, + const struct bma4_fifo_frame *fifo, + const struct bma4_dev *dev) +{ + int8_t rslt; + struct bma4_mag_fifo_data mag_fifo_data; + + /* Aux. mag sensor raw x data */ + mag_fifo_data.mag_x_lsb = fifo->data[start_idx++]; + mag_fifo_data.mag_x_msb = fifo->data[start_idx++]; + + /* Aux. mag sensor raw y data */ + mag_fifo_data.mag_y_lsb = fifo->data[start_idx++]; + mag_fifo_data.mag_y_msb = fifo->data[start_idx++]; + + /* Aux. mag sensor raw z data */ + mag_fifo_data.mag_z_lsb = fifo->data[start_idx++]; + mag_fifo_data.mag_z_msb = fifo->data[start_idx++]; + + /* Aux. mag sensor raw r data */ + mag_fifo_data.mag_r_y2_lsb = fifo->data[start_idx++]; + mag_fifo_data.mag_r_y2_msb = fifo->data[start_idx++]; + + /*Compensated FIFO data output*/ + rslt = bma4_second_if_mag_compensate_xyz(mag_fifo_data, dev->aux_sensor, mag_data); + + return rslt; +} + +/*! + * @brief This API is used to parse and store the sensor time from the + * FIFO data in the structure instance dev. + * + */ +static void unpack_sensortime_frame(uint16_t *data_index, struct bma4_fifo_frame *fifo) +{ + uint32_t sensor_time_byte3 = 0; + uint16_t sensor_time_byte2 = 0; + uint8_t sensor_time_byte1 = 0; + + /*Partial read, then move the data index to last data*/ + if ((*data_index + BMA4_SENSOR_TIME_LENGTH) > fifo->length) + { + /*Update the data index as complete*/ + *data_index = fifo->length; + } + else + { + sensor_time_byte3 = fifo->data[(*data_index) + BMA4_SENSOR_TIME_MSB_BYTE] << 16; + sensor_time_byte2 = fifo->data[(*data_index) + BMA4_SENSOR_TIME_XLSB_BYTE] << 8; + sensor_time_byte1 = fifo->data[(*data_index)]; + + /* Sensor time */ + fifo->sensor_time = (uint32_t)(sensor_time_byte3 | sensor_time_byte2 | sensor_time_byte1); + *data_index = (*data_index) + BMA4_SENSOR_TIME_LENGTH; + } +} + +/*! + * @brief This API is used to parse and store the skipped_frame_count from + * the FIFO data in the structure instance dev. + */ +static void unpack_skipped_frame(uint16_t *data_index, struct bma4_fifo_frame *fifo) +{ + /*Partial read, then move the data index to last data*/ + if (*data_index >= fifo->length) + { + /*Update the data index as complete*/ + *data_index = fifo->length; + } + else + { + fifo->skipped_frame_count = fifo->data[*data_index]; + + /*Move the data index*/ + *data_index = (*data_index) + 1; + } +} + +/*! + * @brief This API is used to parse and store the dropped_frame_count from + * the FIFO data in the structure instance dev. + */ +static void unpack_dropped_frame(uint16_t *data_index, struct bma4_fifo_frame *fifo) +{ + uint8_t dropped_frame = 0; + + /*Partial read, then move the data index to last data*/ + if (*data_index >= fifo->length) + { + /*Update the data index as complete*/ + *data_index = fifo->length; + } + else + { + /*Extract accel and mag dropped frame count*/ + dropped_frame = fifo->data[*data_index] & BMA4_ACCEL_AUX_FIFO_DROP; + + /*Move the data index and update the dropped frame count*/ + switch (dropped_frame) + { + case BMA4_ACCEL_FIFO_DROP: + *data_index = (*data_index) + BMA4_FIFO_A_LENGTH; + fifo->accel_dropped_frame_count = fifo->accel_dropped_frame_count + 1; + break; + case BMA4_AUX_FIFO_DROP: + *data_index = (*data_index) + BMA4_FIFO_M_LENGTH; + fifo->mag_dropped_frame_count = fifo->mag_dropped_frame_count + 1; + break; + case BMA4_ACCEL_AUX_FIFO_DROP: + *data_index = (*data_index) + BMA4_FIFO_MA_LENGTH; + fifo->accel_dropped_frame_count = fifo->accel_dropped_frame_count + 1; + fifo->mag_dropped_frame_count = fifo->mag_dropped_frame_count + 1; + break; + default: + break; + } + } +} + +/*! + * @brief This API is used to move the data index ahead of the + * current_frame_length parameter when unnecessary FIFO data appears while + * extracting the user specified data. + */ +static void move_next_frame(uint16_t *data_index, uint8_t current_frame_length, const struct bma4_fifo_frame *fifo) +{ + /*Partial read, then move the data index to last data*/ + if ((*data_index + current_frame_length) > fifo->length) + { + /*Update the data index as complete*/ + *data_index = fifo->length; + } + else + { + /*Move the data index to next frame*/ + *data_index = *data_index + current_frame_length; + } +} + +/*! + * @brief This function validates the Accel self-test data and decides the + * result of self-test operation. + */ +static int8_t validate_selftest(const struct bma4_selftest_delta_limit *accel_data_diff, const struct bma4_dev *dev) +{ + int8_t rslt = 0; + uint16_t x_axis_signal_diff = 0; + uint16_t y_axis_signal_diff = 0; + uint16_t z_axis_signal_diff = 0; + + /* Set self-test amplitude based on variant */ + switch (dev->variant) + { + case BMA42X_VARIANT: + x_axis_signal_diff = BMA42X_ST_ACC_X_AXIS_SIGNAL_DIFF; + y_axis_signal_diff = BMA42X_ST_ACC_Y_AXIS_SIGNAL_DIFF; + z_axis_signal_diff = BMA42X_ST_ACC_Z_AXIS_SIGNAL_DIFF; + break; + + case BMA42X_B_VARIANT: + x_axis_signal_diff = BMA42X_B_ST_ACC_X_AXIS_SIGNAL_DIFF; + y_axis_signal_diff = BMA42X_B_ST_ACC_Y_AXIS_SIGNAL_DIFF; + z_axis_signal_diff = BMA42X_B_ST_ACC_Z_AXIS_SIGNAL_DIFF; + break; + + case BMA45X_VARIANT: + x_axis_signal_diff = BMA45X_ST_ACC_X_AXIS_SIGNAL_DIFF; + y_axis_signal_diff = BMA45X_ST_ACC_Y_AXIS_SIGNAL_DIFF; + z_axis_signal_diff = BMA45X_ST_ACC_Z_AXIS_SIGNAL_DIFF; + break; + + default: + rslt = BMA4_E_INVALID_SENSOR; + break; + } + + if (rslt != BMA4_E_INVALID_SENSOR) + { + if ((accel_data_diff->x <= x_axis_signal_diff) && (accel_data_diff->y <= y_axis_signal_diff) && + (accel_data_diff->z <= z_axis_signal_diff)) + { + rslt = BMA4_SELFTEST_DIFF_X_Y_AND_Z_AXIS_FAILED; + } + else if ((accel_data_diff->x <= x_axis_signal_diff) && (accel_data_diff->y <= y_axis_signal_diff)) + { + rslt = BMA4_SELFTEST_DIFF_X_AND_Y_AXIS_FAILED; + } + else if ((accel_data_diff->x <= x_axis_signal_diff) && (accel_data_diff->z <= z_axis_signal_diff)) + { + rslt = BMA4_SELFTEST_DIFF_X_AND_Z_AXIS_FAILED; + } + else if ((accel_data_diff->y <= y_axis_signal_diff) && (accel_data_diff->z <= z_axis_signal_diff)) + { + rslt = BMA4_SELFTEST_DIFF_Y_AND_Z_AXIS_FAILED; + } + else if (accel_data_diff->x <= x_axis_signal_diff) + { + rslt = BMA4_SELFTEST_DIFF_X_AXIS_FAILED; + } + else if (accel_data_diff->y <= y_axis_signal_diff) + { + rslt = BMA4_SELFTEST_DIFF_Y_AXIS_FAILED; + } + else if (accel_data_diff->z <= z_axis_signal_diff) + { + rslt = BMA4_SELFTEST_DIFF_Z_AXIS_FAILED; + } + else + { + rslt = BMA4_SELFTEST_PASS; + } + } + + return rslt; +} + +/*! + * @brief This API is used to calculate the power of 2 + */ +static int32_t power(int16_t base, uint8_t resolution) +{ + uint8_t i = 1; + + /* Initialize variable to store the power of 2 value */ + int32_t value = 1; + + for (; i <= resolution; i++) + { + value = (int32_t)(value * base); + } + + return value; +} + +/*! + * @brief This internal API brings up the secondary interface to access + * auxiliary sensor * + */ +static int8_t set_aux_interface_config(struct bma4_dev *dev) +{ + /* Variable to return error codes */ + int8_t rslt; + + /* Check for null pointer error */ + rslt = null_pointer_check(dev); + if (rslt == BMA4_OK) + { + /* Enable the auxiliary sensor */ + rslt = bma4_set_mag_enable(0x01, dev); + dev->delay_us(BMA4_AUX_COM_DELAY, dev->intf_ptr); + + if (rslt == BMA4_OK) + { + /* Disable advance power save */ + rslt = bma4_set_advance_power_save(0x00, dev); + dev->delay_us(BMA4_AUX_COM_DELAY, dev->intf_ptr); + + if (rslt == BMA4_OK) + { + /* Set the I2C device address of auxiliary device */ + rslt = bma4_set_i2c_device_addr(dev); + dev->delay_us(BMA4_AUX_COM_DELAY, dev->intf_ptr); + + if (rslt == BMA4_OK) + { + /* Set auxiliary interface to manual mode */ + rslt = bma4_set_mag_manual_enable(dev->aux_config.manual_enable, dev); + dev->delay_us(BMA4_AUX_COM_DELAY, dev->intf_ptr); + + if (rslt == BMA4_OK) + { + /* Set the number of bytes for burst read */ + rslt = bma4_set_mag_burst(dev->aux_config.burst_read_length, dev); + dev->delay_us(BMA4_AUX_COM_DELAY, dev->intf_ptr); + + if (rslt == BMA4_OK) + { + /* Switch on the the auxiliary interface mode */ + rslt = bma4_set_if_mode(dev->aux_config.if_mode, dev); + dev->delay_us(BMA4_AUX_COM_DELAY, dev->intf_ptr); + } + } + } + } + } + } + + return rslt; +} + +/*! + * @brief This internal API reads the data from the auxiliary sensor + * depending on burst length configured + */ +static int8_t extract_aux_data(uint8_t aux_reg_addr, uint8_t *aux_data, uint16_t len, struct bma4_dev *dev) +{ + /* Variable to return error codes */ + int8_t rslt; + + /* Pointer variable to read data from the register */ + uint8_t data[15] = { 0 }; + + /* Variable to define length counts */ + uint8_t len_count = 0; + + /* Variable to define burst read length */ + uint8_t burst_len = 0; + + /* Variable to define read length */ + uint8_t read_length = 0; + + /* Variable to define the number of burst reads */ + uint8_t burst_count; + + /* Variable to define address of the data register*/ + uint8_t aux_read_addr = BMA4_DATA_0_ADDR; + + /* Extract burst read length in a variable */ + rslt = map_read_len(&burst_len, dev); + if ((rslt == BMA4_OK) && (aux_data != NULL)) + { + for (burst_count = 0; burst_count < len; burst_count += burst_len) + { + /* Set the address whose data is to be read */ + rslt = bma4_set_mag_read_addr(aux_reg_addr, dev); + dev->delay_us(BMA4_AUX_COM_DELAY, dev->intf_ptr); + if (rslt == BMA4_OK) + { + /* If user defined length is valid */ + if (len > 0) + { + /* Read the data from the data register */ + rslt = bma4_read_regs(aux_read_addr, data, (uint8_t)burst_len, dev); + dev->delay_us(BMA4_AUX_COM_DELAY, dev->intf_ptr); + if (rslt == BMA4_OK) + { + /* If defined user length or remaining + * length after a burst read is less than + * burst length + */ + if ((len - burst_count) < burst_len) + { + /* Read length is equal to burst + * length or remaining length + */ + read_length = (uint8_t)(len - burst_count); + } + else + { + /* Read length is equal to burst + * length + */ + read_length = burst_len; + } + + /* Copy the read data in terms of given + * read length + */ + for (len_count = 0; len_count < read_length; len_count++) + { + aux_data[burst_count + len_count] = data[len_count]; + } + + /* Increment the register address by + * burst read length + */ + aux_reg_addr += burst_len; + } + else + { + rslt = BMA4_E_RD_WR_LENGTH_INVALID; + } + } + else + { + rslt = BMA4_E_COM_FAIL; + } + } + else + { + rslt = BMA4_E_COM_FAIL; + } + } + } + else + { + rslt = BMA4_E_NULL_PTR; + } + + return rslt; +} + +/*! + * @brief This internal API maps the actual burst read length with user + * length set. + */ +static int8_t map_read_len(uint8_t *len, const struct bma4_dev *dev) +{ + /* Variable to return error codes */ + int8_t rslt = BMA4_OK; + + switch (dev->aux_config.burst_read_length) + { + case BMA4_AUX_READ_LEN_0: + *len = 1; + break; + case BMA4_AUX_READ_LEN_1: + *len = 2; + break; + case BMA4_AUX_READ_LEN_2: + *len = 6; + break; + case BMA4_AUX_READ_LEN_3: + *len = 8; + break; + default: + rslt = BMA4_E_OUT_OF_RANGE; + break; + } + + return rslt; +} + +/*! + * @brief This internal API checks null pointer error + */ +static int8_t null_pointer_check(const struct bma4_dev *dev) +{ + int8_t rslt = BMA4_OK; + + if ((dev == NULL) || (dev->bus_read == NULL) || (dev->bus_write == NULL) || (dev->delay_us == NULL)) + { + rslt = BMA4_E_NULL_PTR; + } + else + { + rslt = BMA4_OK; + } + + return rslt; +} + +/*! @endcond */ + +/*! + * @brief This API does soft reset + */ +int8_t bma4_soft_reset(struct bma4_dev *dev) +{ + int8_t rslt; + + /* Variable to read the dummy byte */ + uint8_t dummy_read = 0; + + /* Variable contains soft reset command */ + uint8_t command_reg = BMA4_SOFT_RESET; + + /* Check the dev structure as NULL */ + rslt = null_pointer_check(dev); + + /* Check the bma4 structure as NULL */ + if (rslt == BMA4_OK) + { + /* Write command register */ + rslt = bma4_write_regs(BMA4_CMD_ADDR, &command_reg, 1, dev); + + if (rslt == BMA4_OK) + { + if (dev->intf == BMA4_SPI_INTF) + { + /* Dummy read to bring interface to SPI */ + rslt = bma4_read_regs(BMA4_CHIP_ID_ADDR, &dummy_read, 1, dev); + } + } + } + + return rslt; +} + +/*! + * @brief This API performs Fast Offset Compensation for accelerometer. + */ +int8_t bma4_perform_accel_foc(const struct bma4_accel_foc_g_value *accel_g_value, struct bma4_dev *dev) +{ + /* Variable to define error */ + int8_t rslt; + + /* Structure to define the accelerometer configurations */ + struct bma4_accel_config acc_cfg = { 0, 0, 0, 0 }; + + /* Variable to store status of advance power save */ + uint8_t aps = 0; + + /* Variable to store status of accelerometer enable */ + uint8_t acc_en = 0; + + /* NULL pointer check */ + rslt = null_pointer_check(dev); + + if ((rslt == BMA4_OK) && (accel_g_value != NULL)) + { + /* Check for input validity */ + if (((ABS(accel_g_value->x) + ABS(accel_g_value->y) + ABS(accel_g_value->z)) == 1) && + ((accel_g_value->sign == 1) || (accel_g_value->sign == 0))) + { + /* Save accelerometer configurations, accelerometer + * enable status and advance power save status + */ + rslt = save_accel_foc_config(&acc_cfg, &aps, &acc_en, dev); + + /* Set configurations for FOC */ + if (rslt == BMA4_OK) + { + rslt = set_accel_foc_config(dev); + } + + /* Perform accelerometer FOC */ + if (rslt == BMA4_OK) + { + rslt = perform_accel_foc(accel_g_value, &acc_cfg, dev); + } + + /* Restore the saved configurations */ + if (rslt == BMA4_OK) + { + rslt = restore_accel_foc_config(&acc_cfg, aps, acc_en, dev); + } + } + else + { + rslt = BMA4_E_OUT_OF_RANGE; + } + } + else + { + rslt = BMA4_E_NULL_PTR; + } + + return rslt; +} + +/*! + * @brief This internal API saves the configurations before performing FOC. + */ +static int8_t save_accel_foc_config(struct bma4_accel_config *acc_cfg, + uint8_t *aps, + uint8_t *acc_en, + struct bma4_dev *dev) +{ + /* Variable to define error */ + int8_t rslt; + + /* Variable to get the status from PWR_CTRL register */ + uint8_t pwr_ctrl_data = 0; + + /* NULL pointer check */ + rslt = null_pointer_check(dev); + + if ((rslt == BMA4_OK) && (acc_cfg != NULL) && (aps != NULL) && (acc_en != NULL)) + { + /* Get accelerometer configurations to be saved */ + rslt = bma4_get_accel_config(acc_cfg, dev); + if (rslt == BMA4_OK) + { + /* Get accelerometer enable status to be saved */ + rslt = bma4_read_regs(BMA4_POWER_CTRL_ADDR, &pwr_ctrl_data, 1, dev); + if (rslt == BMA4_OK) + { + *acc_en = BMA4_GET_BITSLICE(pwr_ctrl_data, BMA4_ACCEL_ENABLE); + } + + /* Get advance power save mode to be saved */ + if (rslt == BMA4_OK) + { + rslt = bma4_get_advance_power_save(aps, dev); + } + } + } + else + { + rslt = BMA4_E_NULL_PTR; + } + + return rslt; +} + +/*! + * @brief This internal API sets configurations for performing accelerometer FOC. + */ +static int8_t set_accel_foc_config(struct bma4_dev *dev) +{ + /* Variable to define error */ + int8_t rslt; + + /* Variable to set the accelerometer configuration value */ + uint8_t acc_conf_data = BMA4_FOC_ACC_CONF_VAL; + + /* NULL pointer check */ + rslt = null_pointer_check(dev); + + if (rslt == BMA4_OK) + { + /* Disabling offset compensation */ + rslt = set_bma4_accel_offset_comp(BMA4_DISABLE, dev); + if (rslt == BMA4_OK) + { + /* Set accelerometer configurations to 50Hz, continuous mode, CIC mode */ + rslt = bma4_write_regs(BMA4_ACCEL_CONFIG_ADDR, &acc_conf_data, 1, dev); + if (rslt == BMA4_OK) + { + /* Set accelerometer to normal mode by enabling it */ + rslt = bma4_set_accel_enable(BMA4_ENABLE, dev); + if (rslt == BMA4_OK) + { + /* Disable advance power save mode */ + rslt = bma4_set_advance_power_save(BMA4_DISABLE, dev); + } + } + } + } + else + { + rslt = BMA4_E_NULL_PTR; + } + + return rslt; +} + +/*! + * @brief This internal API enables/disables the offset compensation for + * filtered and un-filtered accelerometer data. + */ +static int8_t set_bma4_accel_offset_comp(uint8_t offset_en, struct bma4_dev *dev) +{ + /* Variable to define error */ + int8_t rslt; + + /* Variable to store data */ + uint8_t data = 0; + + /* NULL pointer check */ + rslt = null_pointer_check(dev); + + if (rslt == BMA4_OK) + { + /* Enable/Disable offset compensation */ + rslt = bma4_read_regs(BMA4_NV_CONFIG_ADDR, &data, 1, dev); + if (rslt == BMA4_OK) + { + data = BMA4_SET_BITSLICE(data, BMA4_NV_ACCEL_OFFSET, offset_en); + rslt = bma4_write_regs(BMA4_NV_CONFIG_ADDR, &data, 1, dev); + } + } + + return rslt; +} + +/*! + * @brief This internal API performs Fast Offset Compensation for accelerometer. + */ +static int8_t perform_accel_foc(const struct bma4_accel_foc_g_value *accel_g_value, + const struct bma4_accel_config *acc_cfg, + struct bma4_dev *dev) +{ + /* Variable to define error */ + int8_t rslt; + + /* Variable to define count */ + uint8_t loop; + + /* Variable to store status read from the status register */ + uint8_t reg_status = 0; + + /* Array of structure to store accelerometer data */ + struct bma4_accel accel_value[128] = { { 0 } }; + + /* Structure to store accelerometer data temporarily */ + struct bma4_foc_temp_value temp = { 0, 0, 0 }; + + /* Structure to store the average of accelerometer data */ + struct bma4_accel accel_avg = { 0, 0, 0 }; + + /* Variable to define LSB per g value */ + uint16_t lsb_per_g = 0; + + /* Variable to define range */ + uint8_t range = 0; + + /* Variable to set limit for FOC sample */ + uint8_t limit = 128; + + /* Structure to store accelerometer data deviation from ideal value */ + struct bma4_offset_delta delta = { 0, 0, 0 }; + + /* Structure to store accelerometer offset values */ + struct bma4_accel_offset offset = { 0, 0, 0 }; + + /* Variable tries max 5 times for interrupt then generates timeout */ + uint8_t try_cnt; + + /* NULL pointer check */ + rslt = null_pointer_check(dev); + + if ((rslt == BMA4_OK) && (accel_g_value != NULL) && (acc_cfg != NULL)) + { + for (loop = 0; loop < limit; loop++) + { + try_cnt = 5; + while (try_cnt && (!(reg_status & BMA4_STAT_DATA_RDY_ACCEL_MSK))) + { + /* 20ms delay for 50Hz ODR */ + dev->delay_us(BMA4_MS_TO_US(20), dev->intf_ptr); + rslt = bma4_read_regs(BMA4_STATUS_ADDR, ®_status, 1, dev); + try_cnt--; + } + + if ((rslt == BMA4_OK) && (reg_status & BMA4_STAT_DATA_RDY_ACCEL_MSK)) + { + rslt = bma4_read_accel_xyz(&accel_value[loop], dev); + } + + if (rslt == BMA4_OK) + { + rslt = bma4_read_accel_xyz(&accel_value[loop], dev); + } + + if (rslt == BMA4_OK) + { + /* Store the data in a temporary structure */ + temp.x = temp.x + (int32_t)accel_value[loop].x; + temp.y = temp.y + (int32_t)accel_value[loop].y; + temp.z = temp.z + (int32_t)accel_value[loop].z; + } + else + { + break; + } + } + + if (rslt == BMA4_OK) + { + /* Take average of x, y and z data for lesser noise */ + accel_avg.x = (int16_t)(temp.x / 128); + accel_avg.y = (int16_t)(temp.y / 128); + accel_avg.z = (int16_t)(temp.z / 128); + + /* Get the exact range value */ + map_accel_range(acc_cfg->range, &range); + + /* Get the smallest possible measurable acceleration level given the range and + * resolution */ + lsb_per_g = (uint16_t)(power(2, dev->resolution) / (2 * range)); + + /* Compensate acceleration data against gravity */ + comp_for_gravity(lsb_per_g, accel_g_value, &accel_avg, &delta); + + /* Scale according to offset register resolution */ + scale_bma4_accel_offset(range, &delta, &offset, dev->resolution); + + /* Invert the accelerometer offset data */ + invert_bma4_accel_offset(&offset); + + /* Write offset data in the offset compensation register */ + rslt = write_bma4_accel_offset(&offset, dev); + + /* Enable offset compensation */ + if (rslt == BMA4_OK) + { + rslt = set_bma4_accel_offset_comp(BMA4_ENABLE, dev); + } + } + } + else + { + rslt = BMA4_E_NULL_PTR; + } + + return rslt; +} + +/*! + * @brief This internal API converts the accelerometer range value into + * corresponding integer value. + */ +static void map_accel_range(uint8_t range_in, uint8_t *range_out) +{ + switch (range_in) + { + case BMA4_ACCEL_RANGE_2G: + *range_out = 2; + break; + case BMA4_ACCEL_RANGE_4G: + *range_out = 4; + break; + case BMA4_ACCEL_RANGE_8G: + *range_out = 8; + break; + case BMA4_ACCEL_RANGE_16G: + *range_out = 16; + break; + default: + + /* By default RANGE 4G is set */ + *range_out = 4; + break; + } +} + +/*! + * @brief This internal API compensate the accelerometer data against gravity. + */ +static void comp_for_gravity(uint16_t lsb_per_g, + const struct bma4_accel_foc_g_value *g_val, + const struct bma4_accel *data, + struct bma4_offset_delta *comp_data) +{ + /* Array to store the accelerometer values in LSB */ + int16_t accel_value_lsb[3] = { 0 }; + + /* Convert g-value to LSB */ + accel_value_lsb[BMA4_X_AXIS] = (int16_t)(lsb_per_g * g_val->x); + accel_value_lsb[BMA4_Y_AXIS] = (int16_t)(lsb_per_g * g_val->y); + accel_value_lsb[BMA4_Z_AXIS] = (int16_t)(lsb_per_g * g_val->z); + + /* Get the compensated values for X, Y and Z axis */ + comp_data->x = (data->x - accel_value_lsb[BMA4_X_AXIS]); + comp_data->y = (data->y - accel_value_lsb[BMA4_Y_AXIS]); + comp_data->z = (data->z - accel_value_lsb[BMA4_Z_AXIS]); +} + +/*! + * @brief This internal API scales the compensated accelerometer data according + * to the offset register resolution. + */ +static void scale_bma4_accel_offset(uint8_t range, + const struct bma4_offset_delta *comp_data, + struct bma4_accel_offset *data, + uint8_t resolution) +{ + /* Variable to store the position of bit having 3.9mg resolution */ + int8_t bit_pos_3_9mg; + + /* Variable to store the position previous of bit having 3.9mg resolution */ + int8_t bit_pos_3_9mg_prev_bit = 0; + + /* Variable to store the round-off value */ + uint8_t round_off = 0; + + /* Find the bit position of 3.9mg */ + bit_pos_3_9mg = get_bit_pos_3_9mg(range, resolution); + + if (bit_pos_3_9mg < 0) + { + bit_pos_3_9mg = 0; + } + + /* Round off, consider if the next bit is high */ + if (bit_pos_3_9mg > 0) + { + bit_pos_3_9mg_prev_bit = bit_pos_3_9mg - 1; + round_off = (uint8_t)(power(2, ((uint8_t) bit_pos_3_9mg_prev_bit))); + } + + /* Scale according to offset register resolution */ + data->x = (uint8_t)((comp_data->x + round_off) / power(2, ((uint8_t) bit_pos_3_9mg))); + data->y = (uint8_t)((comp_data->y + round_off) / power(2, ((uint8_t) bit_pos_3_9mg))); + data->z = (uint8_t)((comp_data->z + round_off) / power(2, ((uint8_t) bit_pos_3_9mg))); +} + +/*! + * @brief This internal API inverts the accelerometer offset data. + */ +static void invert_bma4_accel_offset(struct bma4_accel_offset *offset_data) +{ + /* Get the offset data */ + offset_data->x = (uint8_t)((offset_data->x) * (-1)); + offset_data->y = (uint8_t)((offset_data->y) * (-1)); + offset_data->z = (uint8_t)((offset_data->z) * (-1)); +} + +/*! + * @brief This internal API writes the offset data in the offset compensation + * register. + */ +static int8_t write_bma4_accel_offset(const struct bma4_accel_offset *offset, struct bma4_dev *dev) +{ + /* Variable to define error */ + int8_t rslt; + + /* Array to store the offset data */ + uint8_t data_array[3] = { 0 }; + + data_array[0] = offset->x; + data_array[1] = offset->y; + data_array[2] = offset->z; + + /* NULL pointer check */ + rslt = null_pointer_check(dev); + + if (rslt == BMA4_OK) + { + /* Offset values are written in the offset register */ + rslt = bma4_write_regs(BMA4_OFFSET_0_ADDR, data_array, 3, dev); + } + + return rslt; +} + +/*! + * @brief This internal API finds the bit position of 3.9mg according to given + * range and resolution. + */ +static int8_t get_bit_pos_3_9mg(uint8_t range, uint8_t resolution) +{ + /* Variable to store the bit position of 3.9mg resolution */ + int8_t bit_pos_3_9mg; + + /* Variable to shift the bits according to the resolution */ + uint32_t divisor = 1; + + /* Scaling factor to get the bit position of 3.9 mg resolution */ + int16_t scale_factor = -1; + + /* Variable to store temporary value */ + uint16_t temp; + + /* Shift left by the times of resolution */ + divisor = divisor << (resolution - 1); + + /* Get the bit position to be shifted */ + temp = (uint16_t)(divisor / (range * 128)); + + /* Get the scaling factor until bit position is shifted to last bit */ + while (temp != 1) + { + scale_factor++; + temp = temp >> 1; + } + + /* Scaling factor is the bit position of 3.9 mg resolution */ + bit_pos_3_9mg = (int8_t) scale_factor; + + return bit_pos_3_9mg; +} + +/*! + * @brief This internal API restores the configurations saved before performing + * accelerometer FOC. + */ +static int8_t restore_accel_foc_config(const struct bma4_accel_config *acc_cfg, + uint8_t aps, + uint8_t acc_en, + struct bma4_dev *dev) +{ + /* Variable to define error */ + int8_t rslt; + + /* Variable to get the status from PWR_CTRL register */ + uint8_t pwr_ctrl_data = 0; + + /* NULL pointer check */ + rslt = null_pointer_check(dev); + + if ((rslt == BMA4_OK) && (acc_cfg != NULL)) + { + /* Restore the saved accelerometer configurations */ + rslt = bma4_set_accel_config(acc_cfg, dev); + if (rslt == BMA4_OK) + { + /* Restore the saved accelerometer enable status */ + rslt = bma4_read_regs(BMA4_POWER_CTRL_ADDR, &pwr_ctrl_data, 1, dev); + if (rslt == BMA4_OK) + { + pwr_ctrl_data = BMA4_SET_BITSLICE(pwr_ctrl_data, BMA4_ACCEL_ENABLE, acc_en); + rslt = bma4_write_regs(BMA4_POWER_CTRL_ADDR, &pwr_ctrl_data, 1, dev); + + /* Restore the saved advance power save */ + if (rslt == BMA4_OK) + { + rslt = bma4_set_advance_power_save(aps, dev); + } + } + } + } + else + { + rslt = BMA4_E_NULL_PTR; + } + + return rslt; +} + +/*! + * @brief This internal API is to store remapped axis and sign values + * in device structure + */ +static void assign_remap_axis(uint8_t remap_axis, uint8_t *axis, uint8_t *sign) +{ + /* Variable to store the re-mapped axis value */ + uint8_t axis_val = remap_axis & BMA4_AXIS_MASK; + + switch (axis_val) + { + case BMA4_X: + + /* If mapped to x-axis */ + (*axis) = BMA4_MAP_X_AXIS; + break; + case BMA4_Y: + + /* If mapped to y-axis */ + (*axis) = BMA4_MAP_Y_AXIS; + break; + case BMA4_Z: + + /* If mapped to z-axis */ + (*axis) = BMA4_MAP_Z_AXIS; + break; + default: + break; + } + + /* Store the re-mapped axis sign in the device structure */ + if (remap_axis & BMA4_AXIS_SIGN) + { + /* If axis mapped to negative sign */ + (*sign) = BMA4_MAP_NEGATIVE; + } + else + { + /* If axis mapped to positive sign */ + (*sign) = BMA4_MAP_POSITIVE; + } +} + +/*! + * @brief This internal API is to receive remapped axis and sign values + * in device structure and to local structure + */ +static void receive_remap_axis(uint8_t remap_axis, uint8_t remap_sign, uint8_t *axis) +{ + /* Get the re-mapped axis value from device structure */ + switch (remap_axis) + { + case BMA4_MAP_X_AXIS: + + /* If mapped to x-axis */ + (*axis) = BMA4_X; + break; + case BMA4_MAP_Y_AXIS: + + /* If mapped to y-axis */ + (*axis) = BMA4_Y; + break; + case BMA4_MAP_Z_AXIS: + + /* If mapped to z-axis */ + (*axis) = BMA4_Z; + break; + default: + break; + } + + /* Get the re-mapped axis sign from device structure */ + if (remap_sign) + { + /* If axis is mapped to negative sign */ + (*axis) |= BMA4_AXIS_SIGN; + } +} + +/*! + * @brief This API performs x, y and z-axis re-mapping in the sensor. + */ +static int8_t set_remap_axes(const struct bma4_axes_remap *remap_data, + uint8_t *feature_config, + uint8_t index, + uint8_t feature_len, + struct bma4_dev *dev) +{ + /* Variable to hold execution status */ + int8_t rslt; + + /* Variable to define x-axis to be re-mapped */ + uint8_t x_axis; + + /* Variable to define y-axis to be re-mapped */ + uint8_t y_axis; + + /* Variable to define z-axis to be re-mapped */ + uint8_t z_axis; + + /* Variable to define x-axis sign to be re-mapped */ + uint8_t x_axis_sign; + + /* Variable to define y-axis sign to be re-mapped */ + uint8_t y_axis_sign; + + /* Variable to define z-axis sign to be re-mapped */ + uint8_t z_axis_sign; + + if (remap_data != NULL) + { + /* Read the configuration file */ + rslt = bma4_read_regs(BMA4_FEATURE_CONFIG_ADDR, feature_config, feature_len, dev); + + if (rslt == BMA4_OK) + { + /* Get x-axis to be re-mapped */ + x_axis = remap_data->x_axis & BMA4_X_AXIS_MSK; + + /* Get x-axis sign to be re-mapped */ + x_axis_sign = (remap_data->x_axis_sign << BMA4_X_AXIS_SIGN_POS) & BMA4_X_AXIS_SIGN_MSK; + + /* Get y-axis to be re-mapped */ + y_axis = (remap_data->y_axis << BMA4_Y_AXIS_POS) & BMA4_Y_AXIS_MSK; + + /* Get y-axis sign to be re-mapped */ + y_axis_sign = (remap_data->y_axis_sign << BMA4_Y_AXIS_SIGN_POS) & BMA4_Y_AXIS_SIGN_MSK; + + /* Get z-axis to be re-mapped */ + z_axis = (remap_data->z_axis << BMA4_Z_AXIS_POS) & BMA4_Z_AXIS_MSK; + + /* Get z-axis sign to be re-mapped */ + z_axis_sign = remap_data->z_axis_sign & BMA4_Z_AXIS_SIGN_MSK; + + /* Set the first byte for axis re-mapping */ + feature_config[index] = x_axis | x_axis_sign | y_axis | y_axis_sign | z_axis; + + /* Set the second byte for axis re-mapping */ + feature_config[index + 1] = z_axis_sign; + + /* Set the re-mapped axes */ + rslt = bma4_write_regs(BMA4_FEATURE_CONFIG_ADDR, feature_config, feature_len, dev); + } + } + else + { + rslt = BMA4_E_NULL_PTR; + } + + return rslt; +} + +/*! + * @brief This API reads the x, y and z axis re-mapped data from the sensor. + */ +static int8_t get_remap_axes(struct bma4_axes_remap *remap_data, + uint8_t *feature_config, + uint8_t index, + uint8_t feature_len, + struct bma4_dev *dev) +{ + /* Variable to hold execution status */ + int8_t rslt; + + if (remap_data != NULL) + { + /* Read the configuration file */ + rslt = bma4_read_regs(BMA4_FEATURE_CONFIG_ADDR, feature_config, feature_len, dev); + + if (rslt == BMA4_OK) + { + /* Get re-mapped x-axis */ + remap_data->x_axis = BMA4_GET_BITS_POS_0(feature_config[index], BMA4_X_AXIS); + + /* Get re-mapped x-axis sign */ + remap_data->x_axis_sign = BMA4_GET_BITSLICE(feature_config[index], BMA4_X_AXIS_SIGN); + + /* Get re-mapped y-axis */ + remap_data->y_axis = BMA4_GET_BITSLICE(feature_config[index], BMA4_Y_AXIS); + + /* Get re-mapped y-axis sign */ + remap_data->y_axis_sign = BMA4_GET_BITSLICE(feature_config[index], BMA4_Y_AXIS_SIGN); + + /* Get re-mapped z-axis */ + remap_data->z_axis = BMA4_GET_BITSLICE(feature_config[index], BMA4_Z_AXIS); + + /* Get re-mapped z-axis sign */ + remap_data->z_axis_sign = BMA4_GET_BITS_POS_0(feature_config[index + 1], BMA4_Z_AXIS_SIGN); + } + } + else + { + rslt = BMA4_E_NULL_PTR; + } + + return rslt; +} + +/*! + * @brief This internal API gets the re-mapped accelerometer/gyroscope data. + */ +static void get_remapped_data(struct bma4_accel *data, const struct bma4_dev *dev) +{ + /* Array to defined the re-mapped sensor data */ + int16_t remap_data[3] = { 0 }; + int16_t pos_multiplier = INT16_C(1); + int16_t neg_multiplier = INT16_C(-1); + + /* Fill the array with the un-mapped sensor data */ + remap_data[0] = data->x; + remap_data[1] = data->y; + remap_data[2] = data->z; + + /* Get the re-mapped x axis data */ + if (dev->remap.x_axis_sign == BMA4_MAP_POSITIVE) + { + data->x = (int16_t)(remap_data[dev->remap.x_axis] * pos_multiplier); + } + else + { + data->x = (int16_t)(remap_data[dev->remap.x_axis] * neg_multiplier); + } + + /* Get the re-mapped y axis data */ + if (dev->remap.y_axis_sign == BMA4_MAP_POSITIVE) + { + data->y = (int16_t)(remap_data[dev->remap.y_axis] * pos_multiplier); + } + else + { + data->y = (int16_t)(remap_data[dev->remap.y_axis] * neg_multiplier); + } + + /* Get the re-mapped z axis data */ + if (dev->remap.z_axis_sign == BMA4_MAP_POSITIVE) + { + data->z = (int16_t)(remap_data[dev->remap.z_axis] * pos_multiplier); + } + else + { + data->z = (int16_t)(remap_data[dev->remap.z_axis] * neg_multiplier); + } +} + +/*! + * @brief This API performs the steps needed for self-test operation + * before reading the Accel self-test data. + */ +static int8_t selftest_config(uint8_t sign, struct bma4_dev *dev) +{ + int8_t rslt; + + /* NULL pointer check */ + rslt = null_pointer_check(dev); + + if (rslt == BMA4_OK) + { + rslt = set_accel_selftest_enable(BMA4_ENABLE, dev); + + if (rslt == BMA4_OK) + { + rslt = set_accel_selftest_sign(sign, dev); + + if (rslt == BMA4_OK) + { + /* Set self-test amplitude based on variant */ + switch (dev->variant) + { + case BMA42X_VARIANT: + + /* Set self-test amplitude to high for BMA42x */ + rslt = set_accel_selftest_amp(BMA4_ENABLE, dev); + break; + + case BMA42X_B_VARIANT: + + /* Set self-test amplitude to low for BMA42x_B */ + rslt = set_accel_selftest_amp(BMA4_DISABLE, dev); + break; + + case BMA45X_VARIANT: + + /* Set self-test amplitude to low for BMA45x */ + rslt = set_accel_selftest_amp(BMA4_DISABLE, dev); + break; + + default: + rslt = BMA4_E_INVALID_SENSOR; + break; + } + } + } + } + + return rslt; +} diff --git a/components/bma456/bma4.h b/components/bma456/bma4.h new file mode 100644 index 0000000..66106bc --- /dev/null +++ b/components/bma456/bma4.h @@ -0,0 +1,2209 @@ +/** +* 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. +* +* @file bma4.h +* @date 2023-07-05 +* @version V2.29.0 +* +*/ + +/* + * @file bma4.h + * @brief Source file for the BMA4 Sensor API + */ + +/*! + * @defgroup bma4xy BMA4XY + */ + +/** + * \ingroup bma4xy + * \defgroup bma4 BMA4 + * @brief Sensor driver for BMA4 sensor + */ + +#ifndef BMA4_H__ +#define BMA4_H__ + +/*********************************************************************/ +/* header files */ + +#include "bma4_defs.h" +#ifdef AKM9916 +#include "aux_akm9916.h" +#endif + +#ifdef BMM150 +#include "aux_bmm150.h" +#endif + +/*********************************************************************/ +/* (extern) variable declarations */ +/*********************************************************************/ +/* function prototype declarations */ + +/** + * \ingroup bma4 + * \defgroup bma4ApiInit Initialization + * @brief Initialize the sensor and device structure + */ + +/*! + * \ingroup bma4ApiInit + * \page bma4_api_bma4_init bma4_init + * \code + * int8_t bma4_init(struct bma4_dev *dev); + * \endcode + * @details 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. + * + * @param[in,out] dev : Structure instance of bma4_dev + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + * + * @note + * While changing the parameter of the bma4 + * consider the following point: + * Changing the reference value of the parameter + * will changes the local copy or local reference + * make sure your changes will not + * affect the reference value of the parameter + * (Better case don't change the reference value of the parameter) + */ +int8_t bma4_init(struct bma4_dev *dev); + +/** + * \ingroup bma4 + * \defgroup bma4ApiConfig ConfigFile + * @brief Write binary configuration in the sensor + */ + +/*! + * \ingroup bma4ApiConfig + * \page bma4_api_bma4_write_config_file bma4_write_config_file + * \code + * int8_t bma4_write_config_file(struct bma4_dev *dev); + * \endcode + * @details This API is used to write the binary configuration in the sensor + * + * @param[in] dev : Structure instance of bma4_dev. + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +int8_t bma4_write_config_file(struct bma4_dev *dev); + +/** + * \ingroup bma4 + * \defgroup bma4ApiRegisters Registers + * @brief Perform read / write operation to registers of the sensor + */ + +/*! + * \ingroup bma4ApiRegisters + * \page bma4_api_bma4_write_regs bma4_write_regs + * \code + * int8_t bma4_write_regs(uint8_t addr, uint8_t *data, uint8_t len, struct bma4_dev *dev); + * \endcode + * @details This API checks whether the write operation requested is for + * feature config or register write and accordingly writes the data in the + * sensor. + * + * @note user has to disable the advance power save mode in the sensor when + * using this API in burst write mode. + * bma4_set_advance_power_save(BMA4_DISABLE, dev); + * + * @param[in] addr : Register address. + * @param[in] data : Write data buffer + * @param[in] len : No of bytes to write + * @param[in] dev : Structure instance of bma4_dev. + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +int8_t bma4_write_regs(uint8_t addr, const uint8_t *data, uint32_t len, struct bma4_dev *dev); + +/*! + * \ingroup bma4ApiRegisters + * \page bma4_api_bma4_read_regs bma4_read_regs + * \code + * int8_t bma4_write_regs(uint8_t addr, uint8_t *data, uint8_t len, struct bma4_dev *dev); + * \endcode + * @details This API checks whether the read operation requested is for + * feature or register read and accordingly reads the data from the sensor. + * + * @param[in] addr : Register address. + * @param[in] data : Read data buffer. + * @param[in] len : No of bytes to read. + * @param[in] dev : Structure instance of bma4_dev + * + * @note For most of the registers auto address increment applies, with the + * exception of a few special registers, which trap the address. For e.g., + * Register address - 0x26, 0x5E. + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +int8_t bma4_read_regs(uint8_t addr, uint8_t *data, uint32_t len, struct bma4_dev *dev); + +/** + * \ingroup bma4 + * \defgroup bma4ApiErrorStatus Error Status + * @brief Read error status of the sensor + */ + +/*! + * \ingroup bma4ApiErrorStatus + * \page bma4_api_bma4_get_error_status bma4_get_error_status + * \code + * int8_t bma4_get_error_status(struct bma4_err_reg *err_reg, struct bma4_dev *dev);; + * \endcode + * @details This API reads the error status from the sensor. + * + * Below table mention the types of error which can occur in the sensor + * + *@verbatim + ************************************************************************* + * Error | Description + *************************|*********************************************** + * | Fatal Error, chip is not in operational + * fatal | state (Boot-, power-system). + * | This flag will be reset only by + * | power-on-reset or soft reset. + *************************|*********************************************** + * cmd | Command execution failed. + *************************|*********************************************** + * | Value Name Description + * error_code | 000 no_error no error + * | 001 acc_err error in + * | ACC_CONF + *************************|*********************************************** + * | Error in FIFO detected: Input data was + * fifo | discarded in stream mode. This flag + * | will be reset when read. + *************************|*********************************************** + * mag | Error in I2C-Master detected. + * | This flag will be reset when read. + ************************************************************************* + *@endverbatim + * + * @param[in,out] err_reg : Pointer to structure variable which stores the + * error status read from the sensor. + * @param[in] dev : Structure instance of bma4_dev. + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +int8_t bma4_get_error_status(struct bma4_err_reg *err_reg, struct bma4_dev *dev); + +/** + * \ingroup bma4 + * \defgroup bma4ApiAccelxyz Accel XYZ Data + * @brief Read accel xyz data from the sensor + */ + +/*! + * \ingroup bma4ApiAccelxyz + * \page bma4_api_bma4_read_accel_xyz bma4_read_accel_xyz + * \code + * int8_t bma4_read_accel_xyz(struct bma4_accel *accel, struct bma4_dev *dev); + * \endcode + * @details This API reads the Accel data for x,y and z axis from the sensor. + * The data units is in LSB format. + * + * @param[in] accel : Variable used to store the Accel data which is read + * from the sensor. + * @param[in] dev : Structure instance of bma4_dev. + * + * @note For setting the Accel configuration use the below function + * bma4_set_accel_config + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +int8_t bma4_read_accel_xyz(struct bma4_accel *accel, struct bma4_dev *dev); + +/** + * \ingroup bma4 + * \defgroup bma4ApiSensorTime Sensor Time + * @brief Read sensor time of the sensor + */ + +/*! + * \ingroup bma4ApiSensorTime + * \page bma4_api_bma4_get_sensor_time bma4_get_sensor_time + * \code + * int8_t bma4_get_sensor_time(uint32_t *sensor_time, struct bma4_dev *dev); + * \endcode + * @details This API reads the sensor time of Sensor time gets updated + * with every update of data register or FIFO. + * + * @param[in] sensor_time : Pointer variable which stores sensor time + * @param[in] dev : Structure instance of bma4_dev. + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +int8_t bma4_get_sensor_time(uint32_t *sensor_time, struct bma4_dev *dev); + +/** + * \ingroup bma4 + * \defgroup bma4ApiTemperature Temperature + * @brief Read chip temperature of the sensor + */ + +/*! + * \ingroup bma4ApiTemperature + * \page bma4_api_bma4_get_temperature bma4_get_temperature + * \code + * int8_t bma4_get_temperature(int32_t *temp, uint8_t temp_unit, struct bma4_dev *dev); + * \endcode + * @details This API reads the chip temperature of sensor. + * @note If Accel and Mag are disabled, the temperature value will be set + * to invalid. + * + * @param[out] temp : Pointer variable which stores the temperature value. + * @param[in] temp_unit : indicates the unit of temperature + * + * @verbatim + * temp_unit | description + * ------------|------------------- + * BMA4_DEG | degrees Celsius + * BMA4_FAHREN | degrees fahrenheit + * BMA4_KELVIN | degrees kelvin + *@endverbatim + * + * @param[in] dev : Structure instance of bma4_dev. + * + * @note Using a scaling factor of 1000, to obtain integer values, which + * at the user end, are used to get accurate temperature value. + * BMA4_SCALE_FARHAN = 1.8 * 1000, BMA4_SCALE_KELVIN = 273.15 * 1000 + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +int8_t bma4_get_temperature(int32_t *temp, uint8_t temp_unit, struct bma4_dev *dev); + +/** + * \ingroup bma4 + * \defgroup bma4ApiAccel Accel Configuration + * @brief Read / Write configurations of accel sensor + */ + +/*! + * \ingroup bma4ApiAccel + * \page bma4_api_bma4_get_accel_config bma4_get_accel_config + * \code + * int8_t bma4_get_accel_config(struct bma4_accel_config *accel, struct bma4_dev *dev); + * \endcode + * @details This API reads the Output data rate, Bandwidth, perf_mode + * and Range of accel. + * + * @param[in,out] accel : Address of user passed structure which is used + * to store the Accel configurations read from the sensor. + * + * @note Enums and corresponding values for structure parameters like + * Odr, Bandwidth and Range are mentioned in the below tables. + * + *@verbatim + * Value | Odr + * -----------|------------------------------------ + * 1 | BMA4_OUTPUT_DATA_RATE_0_78HZ + * 2 | BMA4_OUTPUT_DATA_RATE_1_56HZ + * 3 | BMA4_OUTPUT_DATA_RATE_3_12HZ + * 4 | BMA4_OUTPUT_DATA_RATE_6_25HZ + * 5 | BMA4_OUTPUT_DATA_RATE_12_5HZ + * 6 | BMA4_OUTPUT_DATA_RATE_25HZ + * 7 | BMA4_OUTPUT_DATA_RATE_50HZ + * 8 | BMA4_OUTPUT_DATA_RATE_100HZ + * 9 | BMA4_OUTPUT_DATA_RATE_200HZ + * 10 | BMA4_OUTPUT_DATA_RATE_400HZ + * 11 | BMA4_OUTPUT_DATA_RATE_800HZ + * 12 | BMA4_OUTPUT_DATA_RATE_1600HZ + *@endverbatim + * + *@verbatim + * Value | accel_bw + * ------|-------------------------- + * 0 | BMA4_ACCEL_OSR4_AVG1 + * 1 | BMA4_ACCEL_OSR2_AVG2 + * 2 | BMA4_ACCEL_NORMAL_AVG4 + * 3 | BMA4_ACCEL_CIC_AVG8 + * 4 | BMA4_ACCEL_RES_AVG16 + * 5 | BMA4_ACCEL_RES_AVG32 + * 6 | BMA4_ACCEL_RES_AVG64 + * 7 | BMA4_ACCEL_RES_AVG128 + *@endverbatim + * + *@verbatim + * Value | g_range + * --------|--------------------- + * 0x00 | BMA4_ACCEL_RANGE_2G + * 0x01 | BMA4_ACCEL_RANGE_4G + * 0x02 | BMA4_ACCEL_RANGE_8G + * 0x03 | BMA4_ACCEL_RANGE_16G + *@endverbatim + * + * @param[in] dev : Structure instance of bma4_dev + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +int8_t bma4_get_accel_config(struct bma4_accel_config *accel, struct bma4_dev *dev); + +/*! + * \ingroup bma4ApiAccel + * \page bma4_api_bma4_set_accel_config bma4_set_accel_config + * \code + * int8_t bma4_set_accel_config(struct bma4_accel_config *accel, struct bma4_dev *dev); + * \endcode + * @details This API sets the output_data_rate, bandwidth, perf_mode + * and range of Accel. + * + * @param[in] accel : Pointer to structure variable which specifies the + * Accel configurations. + * + * @note Enums and corresponding values for structure parameters like + * Odr, Bandwidth and Range are mentioned in the below tables. + * + * @verbatim + * Value | ODR + * --------|----------------------------------------- + * 1 | BMA4_OUTPUT_DATA_RATE_0_78HZ + * 2 | BMA4_OUTPUT_DATA_RATE_1_56HZ + * 3 | BMA4_OUTPUT_DATA_RATE_3_12HZ + * 4 | BMA4_OUTPUT_DATA_RATE_6_25HZ + * 5 | BMA4_OUTPUT_DATA_RATE_12_5HZ + * 6 | BMA4_OUTPUT_DATA_RATE_25HZ + * 7 | BMA4_OUTPUT_DATA_RATE_50HZ + * 8 | BMA4_OUTPUT_DATA_RATE_100HZ + * 9 | BMA4_OUTPUT_DATA_RATE_200HZ + * 10 | BMA4_OUTPUT_DATA_RATE_400HZ + * 11 | BMA4_OUTPUT_DATA_RATE_800HZ + * 12 | BMA4_OUTPUT_DATA_RATE_1600HZ + * + *@endverbatim + * + *@verbatim + * Value | accel_bw + * ------|-------------------------- + * 0 | BMA4_ACCEL_OSR4_AVG1 + * 1 | BMA4_ACCEL_OSR2_AVG2 + * 2 | BMA4_ACCEL_NORMAL_AVG4 + * 3 | BMA4_ACCEL_CIC_AVG8 + * 4 | BMA4_ACCEL_RES_AVG16 + * 5 | BMA4_ACCEL_RES_AVG32 + * 6 | BMA4_ACCEL_RES_AVG64 + * 7 | BMA4_ACCEL_RES_AVG128 + *@endverbatim + * + *@verbatim + * Value | g_range + * --------|--------------------- + * 0x00 | BMA4_ACCEL_RANGE_2G + * 0x01 | BMA4_ACCEL_RANGE_4G + * 0x02 | BMA4_ACCEL_RANGE_8G + * 0x03 | BMA4_ACCEL_RANGE_16G + *@endverbatim + * + * @param[in] dev : Structure instance of bma4_dev + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + * + */ +int8_t bma4_set_accel_config(const struct bma4_accel_config *accel, struct bma4_dev *dev); + +/** + * \ingroup bma4 + * \defgroup bma4ApiAdvancedPowerMode Advanced Power Mode + * @brief Read / Write advance power mode of accel sensor + */ + +/*! + * \ingroup bma4ApiAdvancedPowerMode + * \page bma4_api_bma4_set_advance_power_save bma4_set_advance_power_save + * \code + * int8_t bma4_set_advance_power_save(uint8_t adv_pwr_save, struct bma4_dev *dev); + * \endcode + * @details This API sets the advance power save mode in the sensor. + * + * @note If advanced power save is enabled and the Accel and/or + * magnetometer operate in duty cycling mode, the length of the unlatched + * DRDY interrupt pulse is longer than 1/3.2 kHz (312.5 us). + * + * @param[in] adv_pwr_save : The value of advance power save mode + * @param[in] dev : Structure instance of bma4_dev. + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +int8_t bma4_set_advance_power_save(uint8_t adv_pwr_save, struct bma4_dev *dev); + +/*! + * \ingroup bma4ApiAdvancedPowerMode + * \page bma4_api_bma4_get_advance_power_save bma4_get_advance_power_save + * \code + * int8_t bma4_get_advance_power_save(uint8_t adv_pwr_save, struct bma4_dev *dev); + * \endcode + * @details This API reads the status of advance power save mode + * from the sensor. + * + * @note If the advanced power save is enabled and the Accel and/or + * magnetometer operate in duty cycling mode, the length of the unlatched + * DRDY interrupt pulse is longer than 1/3.2 kHz (312.5 us). + * + * @param[out] adv_pwr_save : The value of advance power save mode + * @param[in] dev : Structure instance of bma4_dev. + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +int8_t bma4_get_advance_power_save(uint8_t *adv_pwr_save, struct bma4_dev *dev); + +/** + * \ingroup bma4 + * \defgroup bma4ApiFIFOSelfWakeUp FIFO Self Wake up + * @brief Read / Write FIFO self wake up functionality in the sensor + */ + +/*! + * \ingroup bma4ApiFIFOSelfWakeUp + * \page bma4_api_bma4_set_fifo_self_wakeup bma4_set_fifo_self_wakeup + * \code + * int8_t bma4_set_fifo_self_wakeup(uint8_t fifo_self_wakeup, struct bma4_dev *dev); + * \endcode + * @details This API sets the FIFO self wake up functionality in the sensor. + * + * @note Functionality related to FIFO self wake up depends upon the + * advance power save mode. for more info. refer data sheet. + * + * @param[in] fifo_self_wakeup : Variable used to enable or disable + * FIFO self wake up functionality. + * @param[in] dev : Structure instance of bma4_dev. + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +int8_t bma4_set_fifo_self_wakeup(uint8_t fifo_self_wakeup, struct bma4_dev *dev); + +/*! + * \ingroup bma4ApiFIFOSelfWakeUp + * \page bma4_api_bma4_get_fifo_self_wakeup bma4_get_fifo_self_wakeup + * \code + * int8_t bma4_get_fifo_self_wakeup(uint8_t *fifo_self_wakeup, struct bma4_dev *dev); + * \endcode + * @details This API gets the status of FIFO self wake up functionality from + * the sensor. + * + * @note Functionality related to FIFO self wake up depends upon the + * advance power save mode. for more info. refer data sheet. + * + * @param[out] fifo_self_wake_up : Pointer variable used to store the + * fifo self wake up status. + * @param[in] dev : Structure instance of bma4_dev. + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +int8_t bma4_get_fifo_self_wakeup(uint8_t *fifo_self_wake_up, struct bma4_dev *dev); + +/** + * \ingroup bma4 + * \defgroup bma4ApiAccelEnable Accel Enable + * @brief Enables / Disables accelerometer in the sensor + */ + +/*! + * \ingroup bma4ApiAccelEnable + * \page bma4_api_bma4_set_accel_enable bma4_set_accel_enable + * \code + * int8_t bma4_set_accel_enable(uint8_t accel_en, struct bma4_dev *dev); + * \endcode + * @details This API enables or disables the Accel in the sensor. + * + * @note Before reading Accel data, user should call this API. + * + * @param[in] accel_en : Variable used to enable or disable the Accel. + * @param[in] dev : Structure instance of bma4_dev. + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +int8_t bma4_set_accel_enable(uint8_t accel_en, struct bma4_dev *dev); + +/*! + * \ingroup bma4ApiAccelEnable + * \page bma4_api_bma4_get_accel_enable bma4_get_accel_enable + * \code + * int8_t bma4_get_accel_enable(uint8_t *accel_en, struct bma4_dev *dev); + * \endcode + * @details This API checks whether Accel is enabled or not in the sensor. + * + * @param[out] accel_en : Pointer variable used to store the Accel enable + * status + * @param[in] dev : Structure instance of bma4_dev. + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +int8_t bma4_get_accel_enable(uint8_t *accel_en, struct bma4_dev *dev); + +/** + * \ingroup bma4 + * \defgroup bma4ApiMagEnable Magnetometer Enable + * @brief Enables / Disables Auxiliary Magnetometer in the sensor + */ + +/*! + * \ingroup bma4ApiMagEnable + * \page bma4_api_bma4_set_mag_enable bma4_set_mag_enable + * \code + * int8_t bma4_set_mag_enable(uint8_t mag_en, struct bma4_dev *dev); + * \endcode + * @details This API is used to enable or disable auxiliary Mag + * in the sensor. + * + * @note Before reading Mag data, user should call this API. + * + * @param[in] mag_en : Variable used to enable or disable the Mag. + * @param[in] dev : Structure instance of bma4_dev. + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +int8_t bma4_set_mag_enable(uint8_t mag_en, struct bma4_dev *dev); + +/*! + * \ingroup bma4ApiMagEnable + * \page bma4_api_bma4_get_mag_enable bma4_get_mag_enable + * \code + * int8_t bma4_get_mag_enable(uint8_t *mag_en, struct bma4_dev *dev); + * \endcode + * @details This API is used to check whether the auxiliary Mag is enabled + * or not in the sensor. + * + * @param[out] mag_en : Pointer variable used to store the enable status of + * Mag in the sensor. + * @param[in] dev : Structure instance of bma4_dev. + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +int8_t bma4_get_mag_enable(uint8_t *mag_en, struct bma4_dev *dev); + +/** + * \ingroup bma4 + * \defgroup bma4ApiSpiInterface SPI interface + * @brief Read / Write SPI interface mode set for primary interface + */ + +/*! + * \ingroup bma4AiSpiInterface + * \page bma4_api_bma4_set_spi_interface bma4_set_spi_interface + * \code + * int8_t bma4_set_spi_interface(uint8_t *spi, struct bma4_dev *dev); + * \endcode + * @details This API reads the SPI interface mode which is set for primary + * interface. + * + * @param[out] spi : Pointer variable which stores the SPI mode selection + * + * @verbatim + * Value | Description + * --------|------------------ + * 0 | SPI 4-wire mode + * 1 | SPI 3-wire mode + * + *@endverbatim + * + * @param[in] dev : Structure instance of bma4_dev. + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +int8_t bma4_get_spi_interface(uint8_t *spi, struct bma4_dev *dev); + +/*! + * \ingroup bma4ApiSpiInterface + * \page bma4_api_bma4_get_spi_interface bma4_get_spi_interface + * \code + * int8_t bma4_get_spi_interface(uint8_t spi, struct bma4_dev *dev); + * \endcode + * @details This API configures the SPI interface Mode for primary interface + * + * @param[in] spi : The value of SPI mode selection + * + *@verbatim + * Value | Description + * --------|------------------ + * 0 | SPI 4-wire mode + * 1 | SPI 3-wire mode + * + *@endverbatim + * + * @param[in] dev : Structure instance of bma4_dev. + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +int8_t bma4_set_spi_interface(uint8_t spi, struct bma4_dev *dev); + +/** + * \ingroup bma4 + * \defgroup bma4ApiCommandReg Command Register + * @brief Write available sensor specific commands to the sensor + */ + +/*! + * \ingroup bma4ApiCommandReg + * \page bma4_api_bma4_set_command_register bma4_set_command_register + * \code + * int8_t bma4_set_command_register(uint8_t command_reg, struct bma4_dev *dev); + * \endcode + * @details This API writes the available sensor specific commands + * to the sensor. + * + * @param[in] command_reg : The command to write to the command register + * + *@verbatim + * value | Description + * --------|------------------------------------------------------ + * 0xB6 | Triggers a soft reset + * 0xB0 | Clears all data in the FIFO, does not change + * | FIFO_CONFIG and FIFO_DOWNS registers + * 0xF0 | Reset acceleration data path + *@endverbatim + * + * + * @param[in] dev : Structure instance of bma4_dev. + * + * @note Register will always read as 0x00 + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +int8_t bma4_set_command_register(uint8_t command_reg, struct bma4_dev *dev); + +/** + * \ingroup bma4 + * \defgroup bma4ApiI2CAddr i2C Device Address + * @brief Write I2C device address of auxiliary sensor + */ + +/*! + * \ingroup bma4ApiI2CAddr + * \page bma4_api_bma4_set_i2c_device_addr bma4_set_i2c_device_addr + * \code + * int8_t bma4_set_i2c_device_addr(struct bma4_dev *dev); + * \endcode + * @details This API sets the I2C device address of auxiliary sensor + * + * @param[in] dev : Structure instance of bma4_dev. + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +int8_t bma4_set_i2c_device_addr(struct bma4_dev *dev); + +/** + * \ingroup bma4 + * \defgroup bma4ApiMagManualEnable Mag Manual Enable + * @brief Read / Write register access on magnetometer manually + */ + +/*! + * \ingroup bma4ApiMagManualEnable + * \page bma4_api_bma4_set_mag_manual_enable bma4_set_mag_manual_enable + * \code + * int8_t bma4_set_mag_manual_enable(uint8_t mag_manual, struct bma4_dev *dev); + * \endcode + * @details This API sets the register access on MAG_IF[2], MAG_IF[3], + * MAG_IF[4] in the sensor. This implies that the DATA registers are + * not updated with Mag values automatically. + * + * @param[in] mag_manual : Variable used to specify the Mag manual + * enable status. + * + *@verbatim + * value | mag manual + * ---------|-------------------- + * 0x01 | BMA4_ENABLE + * 0x00 | BMA4_DISABLE + *@endverbatim + * + * @param[out] dev : Structure instance of bma4_dev. + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +int8_t bma4_set_mag_manual_enable(uint8_t mag_manual, struct bma4_dev *dev); + +/*! + * \ingroup bma4ApiMagManualEnable + * \page bma4_api_bma4_get_mag_manual_enable bma4_get_mag_manual_enable + * \code + * int8_t bma4_get_mag_manual_enable(uint8_t *mag_manual, struct bma4_dev *dev); + * \endcode + * @details This API checks whether the Mag access is done manually or + * automatically in the sensor. + * If the Mag access is done through manual mode then Mag data registers + * in sensor are not updated automatically. + * + * @param[out] mag_manual : Mag manual enable value + * + *@verbatim + * value | mag_manual + * --------|------------------- + * 0x01 | BMA4_ENABLE + * 0x00 | BMA4_DISABLE + *@endverbatim + * + * @param[in] dev : Structure instance of bma4_dev + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +int8_t bma4_get_mag_manual_enable(uint8_t *mag_manual, struct bma4_dev *dev); + +/** + * \ingroup bma4 + * \defgroup bma4ApiMagIFMode Mag Interface Mode + * @brief Set I2C interface configuration mode for auxiliary magnetometer + */ + +/*! + * \ingroup bma4ApiMagIFMode + * \page bma4_api_bma4_set_aux_if_mode bma4_set_aux_if_mode + * \code + * int8_t bma4_set_aux_if_mode(uint8_t if_mode, struct bma4_dev *dev); + * \endcode + * @details This API sets the I2C interface configuration(if) mode + * for auxiliary Mag. + * + * @param[in] if_mode : The value of interface configuration mode + * + *@verbatim + * Value | Description + * ------------|------------------------------------------- + * 0 | p_auto_s_off Auxiliary interface:off + * 1 | p_auto_s_mag Auxiliary interface:on + *@endverbatim + * + * @param[in] dev : Structure instance of bma4_dev. + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +int8_t bma4_set_aux_if_mode(uint8_t if_mode, struct bma4_dev *dev); + +/** + * \ingroup bma4 + * \defgroup bma4ApiMagRead Mag Read + * @brief Set / Get address of register of Aux Mag sensor to read data + */ + +/*! + * \ingroup bma4ApiMagRead + * \page bma4_api_bma4_get_mag_read_addr bma4_get_mag_read_addr + * \code + * int8_t bma4_get_mag_read_addr(uint8_t *mag_read_addr, struct bma4_dev *dev); + * \endcode + * @details This API gets the address of the register of Aux Mag sensor + * where the data to be read. + * + * @param[out] mag_read_addr : Pointer variable used to store the + * mag read address. + * @param[in] dev : Structure instance of bma4_dev. + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +int8_t bma4_get_mag_read_addr(uint8_t *mag_read_addr, struct bma4_dev *dev); + +/*! + * \ingroup bma4ApiMagRead + * \page bma4_api_bma4_set_mag_read_addr bma4_set_mag_read_addr + * \code + * int8_t bma4_set_mag_read_addr(uint8_t mag_read_addr, struct bma4_dev *dev); + * \endcode + * @details This API sets the address of the register of Aux Mag sensor + * where the data to be read. + * + * @param[in] mag_read_addr: Value of Mag. read address in order to read + * the data from the auxiliary Mag. + * @param[in] dev : Structure instance of bma4_dev. + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +int8_t bma4_set_mag_read_addr(uint8_t mag_read_addr, struct bma4_dev *dev); + +/** + * \ingroup bma4 + * \defgroup bma4ApiMagWrite Mag Write + * @brief Set / Get address of register of Aux Mag sensor to write data + */ + +/*! + * \ingroup bma4ApiMagWrite + * \page bma4_api_bma4_get_mag_write_addr bma4_get_mag_write_addr + * \code + * int8_t bma4_get_mag_write_addr(uint8_t *mag_write_addr, struct bma4_dev *dev); + * \endcode + * @details This API gets the Aux Mag write address from the sensor. + * Mag write address is where the Mag data will be written. + * + * @param[out] mag_write_addr: Pointer used to store the Mag write address + * which is read from the sensor. + * @param[in] dev : Structure instance of bma4_dev + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +int8_t bma4_get_mag_write_addr(uint8_t *mag_write_addr, struct bma4_dev *dev); + +/*! + * \ingroup bma4ApiMagWrite + * \page bma4_api_bma4_set_mag_write_addr bma4_set_mag_write_addr + * \code + * int8_t bma4_set_mag_write_addr(uint8_t mag_write_addr, struct bma4_dev *dev); + * \endcode + * @details This API sets the Aux Mag write address in the sensor. + * Mag write address is where the Mag data will be written. + * + * @param[in] mag_write_addr: Write address of Mag where the data will + * be written. + * @param[out] dev : Structure instance of bma4_dev + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +int8_t bma4_set_mag_write_addr(uint8_t mag_write_addr, struct bma4_dev *dev); + +/** + * \ingroup bma4 + * \defgroup bma4ApiMagData Mag Data + * @brief Read / Write data from the Mag sensor + */ + +/*! + * \ingroup bma4ApiMagData + * \page bma4_api_bma4_get_mag_write_data bma4_get_mag_write_data + * \code + * int8_t bma4_get_mag_write_data(uint8_t *mag_write_data, struct bma4_dev *dev); + * \endcode + * @details This API reads the data from the sensor which is written to the + * Mag. + * + * @param[out] mag_write_data: Pointer variable which stores the + * data which is written in Mag through sensor. + * @param[in] dev : Structure instance of bma4_dev + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +int8_t bma4_get_mag_write_data(uint8_t *mag_write_data, struct bma4_dev *dev); + +/*! + * \ingroup bma4ApiMagData + * \page bma4_api_bma4_set_mag_write_data bma4_set_mag_write_data + * \code + * int8_t bma4_set_mag_write_data(uint8_t mag_write_data, struct bma4_dev *dev); + * \endcode + * @details This API sets the data in the sensor which in turn will + * be written to Mag. + * + * @param[in] mag_write_data: variable which specify the data which is to + * be written in Mag. + * @param[out] dev : Structure instance of bma4_dev + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +int8_t bma4_set_mag_write_data(uint8_t mag_write_data, struct bma4_dev *dev); + +/** + * \ingroup bma4 + * \defgroup bma4ApiReadMagXYZR Mag xyzr Data + * @brief Read xyzr axes data from auxiliary Mag sensor + */ + +/*! + * \ingroup bma4ApiReadMagXYZR + * \page bma4_api_bma4_read_mag_xyzr bma4_read_mag_xyzr + * \code + * int8_t bma4_read_mag_xyzr(struct bma4_mag_xyzr *mag, struct bma4_dev *dev); + * \endcode + * @details This API reads the x,y,z and r axis data from the auxiliary + * Mag BMM150/AKM9916 sensor. + * + * @param[out] mag : Pointer variable to store the auxiliary Mag x,y,z + * and r axis data read from the sensor. + * @param[in] dev : Structure instance of bma4_dev + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +int8_t bma4_read_mag_xyzr(struct bma4_mag_xyzr *mag, struct bma4_dev *dev); + +/** + * \ingroup bma4 + * \defgroup bma4ApiMagBurst Mag Burst + * @brief Set / Get burst data length of auxiliary Mag Sensor + */ + +/*! + * \ingroup bma4ApiMagBurst + * \page bma4_api_bma4_set_mag_burst bma4_set_mag_burst + * \code + * int8_t bma4_set_mag_burst(uint8_t mag_burst, struct bma4_dev *dev); + * \endcode + * @details This API sets the burst data length (1,2,6,8 byte) of auxiliary + * Mag sensor. + * + * @param[in] mag_burst : Variable used to specify the Mag burst read length + * @param[in] dev : Structure instance of bma4_dev + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +int8_t bma4_set_mag_burst(uint8_t mag_burst, struct bma4_dev *dev); + +/*! + * \ingroup bma4ApiMagBurst + * \page bma4_api_bma4_get_mag_burst bma4_get_mag_burst + * \code + * int8_t bma4_get_mag_burst(uint8_t *mag_burst, struct bma4_dev *dev); + * \endcode + * @details This API reads the burst data length of Mag set in the sensor. + * + * @param[out] mag_burst : Pointer variable used to store the burst length + * @param[in] dev : Structure instance of bma4_dev + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +int8_t bma4_get_mag_burst(uint8_t *mag_burst, struct bma4_dev *dev); + +/** + * \ingroup bma4 + * \defgroup bma4ApiReadFIFO Read FIFO Data + * @brief Read FIFO data of accel and/or Mag sensor + */ + +/*! + * \ingroup bma4ApiReadFIFO + * \page bma4_api_bma4_read_fifo_data bma4_read_fifo_data + * \code + * int8_t bma4_read_fifo_data(struct bma4_fifo_frame *fifo, struct bma4_dev *dev); + * \endcode + * @details This API reads the FIFO data of Accel and/or Mag sensor + * + * @param[in] fifo : Structure instance of bma4_fifo_frame + * @param[in] dev : Structure instance of bma4_dev + * + * @note : Dummy byte (for SPI Interface) required for FIFO data read + * must be given as part of data pointer in struct bma4_fifo_frame + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +int8_t bma4_read_fifo_data(struct bma4_fifo_frame *fifo, struct bma4_dev *dev); + +/** + * \ingroup bma4 + * \defgroup bma4ApiFIFOWM FIFO Watermark level + * @brief Read / Write FIFO watermark level in the sensor + */ + +/*! + * \ingroup bma4ApiFIFOWM + * \page bma4_api_bma4_get_fifo_wm bma4_get_fifo_wm + * \code + * int8_t bma4_get_fifo_wm(uint16_t *fifo_wm, struct bma4_dev *dev); + * \endcode + * @details This API reads the FIFO water mark level which is set + * in the sensor. + * + * @note The FIFO watermark is issued when the FIFO fill level is + * equal or above the watermark level. + * + * @param[out] fifo_wm : Pointer variable to store FIFO water mark level + * @param[in] dev : Structure instance of bma4_dev + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +int8_t bma4_get_fifo_wm(uint16_t *fifo_wm, struct bma4_dev *dev); + +/*! + * \ingroup bma4ApiFIFOWM + * \page bma4_api_bma4_set_fifo_wm bma4_set_fifo_wm + * \code + * int8_t bma4_set_fifo_wm(uint16_t fifo_wm, struct bma4_dev *dev); + * \endcode + * @details This API sets the FIFO watermark level in the sensor. + * + * @note The FIFO watermark is issued when the FIFO fill level is + * equal or above the watermark level. + * + * @param[in] fifo_wm : Variable used to set the FIFO water mark level + * @param[out] dev : Structure instance of bma4_dev + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +int8_t bma4_set_fifo_wm(uint16_t fifo_wm, struct bma4_dev *dev); + +/** + * \ingroup bma4 + * \defgroup bma4ApiAccelFIFOFilterData Accel FIFO Filter data + * @brief Set / Get Filtered or unfiltered mode of Accel FIFO data + */ + +/*! + * \ingroup bma4ApiAccelFIFOFilterData + * \page bma4_api_bma4_get_accel_fifo_filter_data bma4_get_accel_fifo_filter_data + * \code + * int8_t bma4_get_accel_fifo_filter_data(uint8_t *accel_fifo_filter, struct bma4_dev *dev); + * \endcode + * @details This API checks whether the Accel FIFO data is set for filtered + * or unfiltered mode. + * + * @param[out] accel_fifo_filter : Variable used to check whether the Accel + * data is filtered or unfiltered. + * + *@verbatim + * Value | accel_fifo_filter + * ---------|------------------------- + * 0x00 | Unfiltered data + * 0x01 | Filtered data + *@endverbatim + * + * @param[in] dev : structure instance of bma4_dev + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +int8_t bma4_get_accel_fifo_filter_data(uint8_t *accel_fifo_filter, struct bma4_dev *dev); + +/*! + * \ingroup bma4ApiAccelFIFOFilterData + * \page bma4_api_bma4_set_accel_fifo_filter_data bma4_set_accel_fifo_filter_data + * \code + * int8_t bma4_set_accel_fifo_filter_data(uint8_t accel_fifo_filter, struct bma4_dev *dev); + * \endcode + * @details This API sets the condition of Accel FIFO data either to + * filtered or unfiltered mode. + * + * @param[in] accel_fifo_filter : Variable used to set the filtered or + * unfiltered condition of Accel FIFO data. + * + *@verbatim + * value | accel_fifo_filter_data + * -----------|------------------------- + * 0x00 | Unfiltered data + * 0x01 | Filtered data + *@endverbatim + * + * @param[out] dev : Structure instance of bma4_dev + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +int8_t bma4_set_accel_fifo_filter_data(uint8_t accel_fifo_filter, struct bma4_dev *dev); + +/** + * \ingroup bma4 + * \defgroup bma4ApiAccelFIFODown Accel FIFO Down Sampling + * @brief Read / Write Down sampling rates configured for Accel FIFO Data + */ + +/*! + * \ingroup bma4ApiAccelFIFOFilterData + * \page bma4_api_bma4_get_fifo_down_accel bma4_get_fifo_down_accel + * \code + * int8_t bma4_get_fifo_down_accel(uint8_t *fifo_down, struct bma4_dev *dev); + * \endcode + * @details This API reads the down sampling rates which is configured + * for Accel FIFO data. + * + * @param[out] fifo_down : Variable used to specify the Accel FIFO + * down-sampling rates + * @param[in] dev : Structure instance of bma4_dev + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +int8_t bma4_get_fifo_down_accel(uint8_t *fifo_down, struct bma4_dev *dev); + +/*! + * \ingroup bma4ApiAccelFIFOFilterData + * \page bma4_api_bma4_set_fifo_down_accel bma4_set_fifo_down_accel + * \code + * int8_t bma4_set_fifo_down_accel(uint8_t fifo_down, struct bma4_dev *dev); + * \endcode + * @details This API sets the down-sampling rates for Accel FIFO. + * + * @param[in] fifo_down : Variable used to specify the Accel FIFO + * down-sampling rates. + * @param[in] dev : structure instance of bma4_dev + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +int8_t bma4_set_fifo_down_accel(uint8_t fifo_down, struct bma4_dev *dev); + +/** + * \ingroup bma4 + * \defgroup bma4ApiFIFOLength FIFO Length + * @brief Read length of FIFO data available in the sensor (unit of bytes) + */ + +/*! + * \ingroup bma4ApiAccelFIFOFilterData + * \page bma4_api_bma4_get_fifo_length bma4_get_fifo_length + * \code + * int8_t bma4_get_fifo_length(uint16_t *fifo_length, struct bma4_dev *dev); + * \endcode + * @details This API reads the length of FIFO data available in the sensor + * in the units of bytes. + * + * @note This byte counter is updated each time a complete frame was read + * or written + * + * @param[in] fifo_length : Pointer variable used to store the value of + * fifo byte counter + * @param[in] dev : Structure instance of bma4_dev + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + * + */ +int8_t bma4_get_fifo_length(uint16_t *fifo_length, struct bma4_dev *dev); + +/** + * \ingroup bma4 + * \defgroup bma4ApiMagCompensate Compensate Mag data + * @brief Aligns and Compensates Mag Data of BMM150 / AKM9916 + */ + +/*! + * \ingroup bma4ApiAccelFIFOFilterData + * \page bma4_api_bma4_second_if_mag_compensate_xyz bma4_second_if_mag_compensate_xyz + * \code + * int8_t bma4_second_if_mag_compensate_xyz(struct bma4_mag_fifo_data mag_fifo_data, + * uint8_t mag_second_if, + * const struct bma4_mag *compensated_mag_data); + * + * \endcode + * @details This API aligns and compensates the Mag data of BMM150/AKM9916 + * sensor. + * + * @param[in] mag_fifo_data: Structure object which stores the Mag x,yand z + * axis FIFO data which is to be aligned and/or compensated. + * @param[in] mag_second_if: Variable used to select the Mag sensor. + * + *@verbatim + * Value | mag_second_if + * --------|---------------------- + * 1 | BMA4_SEC_IF_BMM150 + * 2 | BMA4_SEC_IF_AKM09916 + *@endverbatim + * + * @param[out] compensated_mag_data: Pointer variable used to store the + * compensated Mag xyz axis data + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +int8_t bma4_second_if_mag_compensate_xyz(struct bma4_mag_fifo_data mag_fifo_data, + uint8_t mag_second_if, + const struct bma4_mag *compensated_mag_data); + +/** + * \ingroup bma4 + * \defgroup bma4ApiMagXYZ Mag XYZ + * @brief Read x, y and z axes data from either BMM150 or AKM9916 sensor + */ + +/*! + * \ingroup bma4ApiMagXYZ + * \page bma4_api_bma4_read_mag_xyz bma4_read_mag_xyz + * \code + * int8_t bma4_read_mag_xyz(const struct bma4_mag *mag, uint8_t sensor_select, const struct bma4_dev *dev); + * \endcode + * @details This API reads Mag. x,y and z axis data from either BMM150 or + * AKM9916 sensor + * + * @param[out] mag : Structure pointer used to store the Mag x,y, and z axis + * data read from the sensor. + * + * @param[in] sensor_select : Variable used to select the Mag sensor + * + *@verbatim + * Value | Sensor + * ---------|---------------------- + * 0 | BMA4_SEC_IF_NULL + * 1 | BMA4_SEC_IF_BMM150 + * 2 | BMA4_SEC_IF_AKM09916 + *@endverbatim + * + * @param[in] dev : Structure instance of bma4_dev + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +int8_t bma4_read_mag_xyz(const struct bma4_mag *mag, uint8_t sensor_select, const struct bma4_dev *dev); + +/** + * \ingroup bma4 + * \defgroup bma4ApiIFMode I2C interface configuration + * @brief Set / Get auxiliary I2C interface configuration set in the sensor + */ + +/*! + * \ingroup bma4ApiIFMode + * \page bma4_api_bma4_get_if_mode bma4_get_if_mode + * \code + * int8_t bma4_get_if_mode(uint8_t *if_mode, struct bma4_dev *dev); + * \endcode + * @details This API reads the auxiliary I2C interface configuration which + * is set in the sensor. + * + * @param[out] if_mode : Pointer variable used to store the auxiliary + * interface configuration. + * + *@verbatim + * Value | Description + * ----- |---------------------------------- + * 0x00 | auxiliary interface:off + * 0x01 | auxiliary interface:on + *@endverbatim + * + * @param[in] dev : Structure instance of bma4_dev + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +int8_t bma4_get_if_mode(uint8_t *if_mode, struct bma4_dev *dev); + +/*! + * \ingroup bma4ApiIFMode + * \page bma4_api_bma4_set_if_mode bma4_set_if_mode + * \code + * int8_t bma4_set_if_mode(uint8_t if_mode, struct bma4_dev *dev); + * \endcode + * @details This API sets the auxiliary interface configuration in the sensor. + * + * @param[in] if_mode : Variable used to select the auxiliary interface + * configuration. + * + *@verbatim + * Value | Description + * ----- |-------------------------- + * 0x00 | auxiliary interface:off + * 0x01 | auxiliary interface:on + *@endverbatim + * + * @param[in] dev : Structure instance of bma4_dev + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +int8_t bma4_set_if_mode(uint8_t if_mode, struct bma4_dev *dev); + +/** + * \ingroup bma4 + * \defgroup bma4ApiASICStatus ASIC status + * @brief Read ASIC status from the sensor + */ + +/*! + * \ingroup bma4ApiASICStatus + * \page bma4_api_bma4_get_asic_status bma4_get_asic_status + * \code + * int8_t bma4_get_asic_status(struct bma4_asic_status *asic_status, struct bma4_dev *dev); + * \endcode + * @details This API reads the ASIC status from the sensor. + * The status information is mentioned in the below table. + * + *@verbatim + ******************************************************************************* + * Status | Description + **************************|**************************************************** + * sleep | ASIC is in sleep/halt state. + * irq_ovrn | Dedicated interrupt is set again before previous + * | interrupt was acknowledged. + * wc_event | Watchcell event detected (ASIC stopped). + * stream_transfer_active | stream transfer has started. + ******************************************************************************* + *@endverbatim + * + * @param[out] asic_status : Structure pointer used to store the ASIC + * status read from the sensor. + * @param[in] dev : Structure instance of bma4_dev + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +int8_t bma4_get_asic_status(struct bma4_asic_status *asic_status, struct bma4_dev *dev); + +/** + * \ingroup bma4 + * \defgroup bma4ApiOffsetComp Accel Offset Compensation + * @brief Set / Get Accel Offset Compensation + */ + +/*! + * \ingroup bma4ApiOffsetComp + * \page bma4_api_bma4_set_offset_comp bma4_set_offset_comp + * \code + * int8_t bma4_set_offset_comp(uint8_t offset_en, struct bma4_dev *dev); + * \endcode + * @details This API enables the offset compensation for filtered and + * unfiltered Accel data. + * + * @param[in] offset_en : Variable used to enable or disable offset + * compensation + * + *@verbatim + * offset_en | Description + * ------------|---------------------- + * 0 | BMA4_DISABLE + * 1 | BMA4_ENABLE + *@endverbatim + * + * @param[in] dev : Structure instance of bma4_dev + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +int8_t bma4_set_offset_comp(uint8_t offset_en, struct bma4_dev *dev); + +/*! + * \ingroup bma4ApiOffsetComp + * \page bma4_api_bma4_get_offset_comp bma4_get_offset_comp + * \code + * int8_t bma4_get_offset_comp(uint8_t *offset_en, struct bma4_dev *dev); + * \endcode + * @details This API gets the status of Accel offset compensation + * + * @param[out] offset_en : Pointer variable used to store the Accel offset + * enable or disable status. + * + *@verbatim + * offset_en | Description + * ----------|-------------- + * 0 | BMA4_DISABLE + * 1 | BMA4_ENABLE + *@endverbatim + * + * @param[in] dev : Structure instance of bma4_dev + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +int8_t bma4_get_offset_comp(uint8_t *offset_en, struct bma4_dev *dev); + +/** + * \ingroup bma4 + * \defgroup bma4ApiExtractAccel Accel Extract and Parse Frames + * @brief Parse and Extract Accel frames from FIFO data read + */ + +/*! + * \ingroup bma4ApiExtractAccel + * \page bma4_api_bma4_extract_accel bma4_extract_accel + * \code + * int8_t bma4_extract_accel(struct bma4_accel *accel_data, + * uint16_t *accel_length, + * struct bma4_fifo_frame *fifo, + * const struct bma4_dev *dev); + * \endcode + * @details This API parses and extracts the accelerometer frames from + * FIFO data read by the "bma4_read_fifo_data" API and stores it in the + * "accel_data" structure instance. + * + * @note The bma4_extract_accel API should be called only after reading + * the FIFO data by calling the bma4_read_fifo_data() API + * + * @param[in,out] accel_data : Structure instance of bma4_accel where + * the accelerometer data in FIFO is stored. + * @param[in,out] accel_length : Number of accelerometer frames + * (x,y,z axes data) + * @param[in,out] dev : Structure instance of bma4_dev. + * + * @note accel_length has the number of accelerometer frames + * (1 accel frame = 6 bytes) which the user needs to extract and store is + * provided as input parameter by the user and the Number of valid + * accelerometer frames extracted and stored is updated in + * "accel_length" at the end of execution of this API. + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + * + */ +int8_t bma4_extract_accel(struct bma4_accel *accel_data, + uint16_t *accel_length, + struct bma4_fifo_frame *fifo, + const struct bma4_dev *dev); + +/** + * \ingroup bma4 + * \defgroup bma4ApiExtractMag Mag Extract and Parse Frames + * @brief Parse and Extract Accel frames from FIFO data read + */ + +/*! + * \ingroup bma4ApiExtractMag + * \page bma4_api_bma4_extract_mag bma4_extract_mag + * \code + * int8_t bma4_extract_mag(const struct bma4_mag *mag_data, + * uint16_t *mag_length, + * struct bma4_fifo_frame *fifo, + * const struct bma4_dev *dev); + * \endcode + * @details This API parses and extracts the magnetometer frames from + * FIFO data read by the "bma4_read_fifo_data" API and stores it in the + * "mag_data" structure instance parameter of this API + * + * @note The bma4_extract_mag API should be called only after reading + * the FIFO data by calling the bma4_read_fifo_data() API + * + * @param[in,out] mag_data : Structure instance of bma4_mag_xyzr where + * the magnetometer data in FIFO is stored. + * @param[in,out] mag_length : Number of magnetometer frames (x,y,z,r data) + * @param[in,out] dev : Structure instance of bma4_dev. + * + * @note mag_length has the number of magnetometer frames(x,y,z,r data) + * (1 mag frame = 8 bytes) which the user needs to extract and store,It is + * provided as input parameter by the user and the number of valid + * magnetometer frames extracted and stored is updated in + * "mag_length" at the end of execution of this API. + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + * + */ +int8_t bma4_extract_mag(const struct bma4_mag *mag_data, + uint16_t *mag_length, + struct bma4_fifo_frame *fifo, + const struct bma4_dev *dev); + +/** + * \ingroup bma4 + * \defgroup bma4ApiAccelSelftest Accel Self test + * @brief Self test for accel + */ + +/*! + * \ingroup bma4ApiAccelSelftest + * \page bma4_api_bma4_perform_accel_selftest bma4_perform_accel_selftest + * \code + * int8_t bma4_perform_accel_selftest(int8_t *result, struct bma4_dev *dev); + * \endcode + * @details This API checks whether the self test functionality of the sensor + * is working or not + * + * @param[in] result : Pointer variable used to store the result of self test + * operation + * + *@verbatim + * result | Description + * ---------|-------------------- + * 0x00 | BMA4_SELFTEST_PASS + * 0x01 | BMA4_SELFTEST_FAIL + *@endverbatim + * + * @param[in] dev : Structure instance of bma4_dev + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +int8_t bma4_perform_accel_selftest(int8_t *result, struct bma4_dev *dev); + +/** + * \ingroup bma4 + * \defgroup bma4ApiInterrupt Interrupt Functions + * @brief Interrupt mapping and set/get interrupt mode + */ + +/*! + * \ingroup bma4ApiInterrupt + * \page bma4_api_bma4_map_interrupt bma4_map_interrupt + * \code + * int8_t bma4_map_interrupt(uint8_t int_line, uint16_t int_map, uint8_t enable, struct bma4_dev *dev); + * \endcode + * @details API sets the interrupt to either interrupt1 or + * interrupt2 pin in the sensor. + * + * @param[in] int_line: Variable used to select interrupt pin1 or pin2 + * + *@verbatim + * int_line | interrupt selection + * ---------|------------------- + * 0 | BMA4_INTR1_MAP + * 1 | BMA4_INTR2_MAP + *@endverbatim + * + * @param[in] int_map: Variable used to select a particular interrupt + * in the sensor + * + * @param[in] enable : Variable used to enable or disable the interrupt + * + *@verbatim + * Value | Behaviour + * ---------|------------------- + * 0x01 | BMA4_ENABLE + * 0x00 | BMA4_DISABLE + *@endverbatim + * + * @param[in] dev : Structure instance of bma4_dev + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + * + */ +int8_t bma4_map_interrupt(uint8_t int_line, uint16_t int_map, uint8_t enable, struct bma4_dev *dev); + +/*! + * \ingroup bma4ApiInterrupt + * \page bma4_api_bma4_set_interrupt_mode bma4_set_interrupt_mode + * \code + * int8_t bma4_set_interrupt_mode(uint8_t mode, struct bma4_dev *dev); + * \endcode + * @details This API sets the interrupt mode in the sensor. + * + * @param[in] mode: Variable used to specify the interrupt mode which + * is to be set in the sensor. + * + *@verbatim + * Mode | Value + * ----------------------- |--------- + * BMA4_NON_LATCH_MODE | 0 + * BMA4_LATCH_MODE | 1 + *@endverbatim + * + * @param[in] dev : Structure instance of bma4_dev + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + * + */ +int8_t bma4_set_interrupt_mode(uint8_t mode, struct bma4_dev *dev); + +/*! + * \ingroup bma4ApiInterrupt + * \page bma4_api_bma4_get_interrupt_mode bma4_get_interrupt_mode + * \code + * int8_t bma4_get_interrupt_mode(uint8_t *mode, struct bma4_dev *dev); + * \endcode + * @details This API gets the interrupt mode which is set in the sensor. + * + * @param[out] mode: Pointer variable used to store the interrupt mode set in + * in the sensor. + * + *@verbatim + * Mode | Value + * ---------------------|--------------- + * BMA4_NON_LATCH_MODE | 0 + * BMA4_LATCH_MODE | 1 + *@endverbatim + * + * @param[in] dev : Structure instance of bma4_dev + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + * + */ +int8_t bma4_get_interrupt_mode(uint8_t *mode, struct bma4_dev *dev); + +/** + * \ingroup bma4 + * \defgroup bma4ApiAuxMagConfig Auxiliary Mag Config + * @brief Set / Get Auxiliary Mag(BMM150 or AKM9916) output data rate and offset + */ + +/*! + * \ingroup bma4ApiAuxMagConfig + * \page bma4_api_bma4_set_aux_mag_config bma4_set_aux_mag_config + * \code + * int8_t bma4_set_aux_mag_config(const struct bma4_aux_mag_config *aux_mag, struct bma4_dev *dev); + * \endcode + * @details This API sets the auxiliary Mag(BMM150 or AKM9916) output data + * rate and offset. + * + * @param[in] aux_mag : Pointer to structure variable used to specify + * the auxiliary Mag configuration. + * + *@verbatim + *------------------------------------------------------------------------------ + * Odr | Value + *----------------------------------------|--------------------------------- + * BMA4_OUTPUT_DATA_RATE_0_78HZ | 0x01 + * BMA4_OUTPUT_DATA_RATE_1_56HZ | 0x02 + * BMA4_OUTPUT_DATA_RATE_3_12HZ | 0x03 + * BMA4_OUTPUT_DATA_RATE_6_25HZ | 0x04 + * BMA4_OUTPUT_DATA_RATE_12_5HZ | 0x05 + * BMA4_OUTPUT_DATA_RATE_25HZ | 0x06 + * BMA4_OUTPUT_DATA_RATE_50HZ | 0x07 + * BMA4_OUTPUT_DATA_RATE_100HZ | 0x08 + * BMA4_OUTPUT_DATA_RATE_200HZ | 0x09 + * BMA4_OUTPUT_DATA_RATE_400HZ | 0x0A + * BMA4_OUTPUT_DATA_RATE_800HZ | 0x0B + * BMA4_OUTPUT_DATA_RATE_1600HZ | 0x0C + *------------------------------------------------------------------------------ + * Offset | Value + *--------------------------------------------|--------------------------------- + * BMA4_MAG_OFFSET_MAX | 0x00 + *--------------------------------------------|--------------------------------- + *@endverbatim + * + * @param[in] dev : Structure instance of bma4_dev + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + * + */ +int8_t bma4_set_aux_mag_config(const struct bma4_aux_mag_config *aux_mag, struct bma4_dev *dev); + +/*! + * \ingroup bma4ApiAuxMagConfig + * \page bma4_api_bma4_get_aux_mag_config bma4_get_aux_mag_config + * \code + * int8_t bma4_get_aux_mag_config(struct bma4_aux_mag_config *aux_mag, struct bma4_dev *dev); + * \endcode + * @details This API reads the auxiliary Mag(BMM150 or AKM9916) output data + * rate and offset. + * @note : Valid output data rates are mentioned in the below table + * + * @param[out] aux_mag : Pointer to structure variable used to store the + * auxiliary Mag configuration read from the sensor + * + *@verbatim + *------------------------------------------------------------------------ + * Odr | Value + *----------------------------------------|------------------------------- + * BMA4_OUTPUT_DATA_RATE_0_78HZ | 0x01 + * BMA4_OUTPUT_DATA_RATE_1_56HZ | 0x02 + * BMA4_OUTPUT_DATA_RATE_3_12HZ | 0x03 + * BMA4_OUTPUT_DATA_RATE_6_25HZ | 0x04 + * BMA4_OUTPUT_DATA_RATE_12_5HZ | 0x05 + * BMA4_OUTPUT_DATA_RATE_25HZ | 0x06 + * BMA4_OUTPUT_DATA_RATE_50HZ | 0x07 + * BMA4_OUTPUT_DATA_RATE_100HZ | 0x08 + * BMA4_OUTPUT_DATA_RATE_200HZ | 0x09 + * BMA4_OUTPUT_DATA_RATE_400HZ | 0x0A + * BMA4_OUTPUT_DATA_RATE_800HZ | 0x0B + * BMA4_OUTPUT_DATA_RATE_1600HZ | 0x0C + *------------------------------------------------------------------------- + * Offset | Value + *----------------------------------------|-------------------------------- + * BMA4_MAG_OFFSET_MAX | 0x00 + *------------------------------------------------------------------------- + *@endverbatim + * + * @param[in] dev : Structure instance of bma4_dev + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + * + */ +int8_t bma4_get_aux_mag_config(struct bma4_aux_mag_config *aux_mag, struct bma4_dev *dev); + +/** + * \ingroup bma4 + * \defgroup bma4ApiFIFOConfig FIFO Configuration + * @brief Set / Get FIFO Configuration in the sensor + */ + +/*! + * \ingroup bma4ApiFIFOConfig + * \page bma4_api_bma4_set_fifo_config bma4_set_fifo_config + * \code + * int8_t bma4_set_fifo_config(uint8_t config, uint8_t enable, struct bma4_dev *dev); + * \endcode + * @details This API sets the FIFO configuration in the sensor. + * + * @param[in] config : Enum variable used to specify the FIFO + * configurations which are to be enabled or disabled in the sensor. + * + * @note : User can set either one or more or all FIFO configurations + * by ORing the below mentioned enums. + * + *@verbatim + * config | Value + * ------------------------|--------------------------- + * BMA4_FIFO_STOP_ON_FULL | 0x01 + * BMA4_FIFO_TIME | 0x02 + * BMA4_FIFO_TAG_INTR2 | 0x04 + * BMA4_FIFO_TAG_INTR1 | 0x08 + * BMA4_FIFO_HEADER | 0x10 + * BMA4_FIFO_MAG | 0x20 + * BMA4_FIFO_ACCEL | 0x40 + * BMA4_FIFO_ALL | 0x7F + *@endverbatim + * + * @param[in] enable : Parameter used to enable or disable the above + * FIFO configuration + * @param[in] dev : Structure instance of bma4_dev. + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + * + */ +int8_t bma4_set_fifo_config(uint8_t config, uint8_t enable, struct bma4_dev *dev); + +/*! + * \ingroup bma4ApiFIFOConfig + * \page bma4_api_bma4_get_fifo_config bma4_get_fifo_config + * \code + * int8_t bma4_get_fifo_config(uint8_t *fifo_config, struct bma4_dev *dev); + * \endcode + * @details This API reads the FIFO configuration from the sensor. + * + * @param[in] fifo_config : Enum variable used to get the below fifo + * configuration from the sensor. + * + * @note After calling this function user should do the AND operation with + * the enum value populated by this function to know which FIFO + * configuration is enabled. + * + *@verbatim + * fifo_config | Value + * -------------------------|-------------------------- + * BMA4_FIFO_STOP_ON_FULL | 0x01 + * BMA4_FIFO_TIME | 0x02 + * BMA4_FIFO_TAG_INTR2 | 0x04 + * BMA4_FIFO_TAG_INTR1 | 0x08 + * BMA4_FIFO_HEADER | 0x10 + * BMA4_FIFO_MAG | 0x20 + * BMA4_FIFO_ACCEL | 0x40 + * BMA4_FIFO_ALL | 0x7F + *@endverbatim + * + * @param[in] dev : Structure instance of bma4_dev + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + * + */ +int8_t bma4_get_fifo_config(uint8_t *fifo_config, struct bma4_dev *dev); + +/** + * \ingroup bma4 + * \defgroup bma4ApiIntConfig Interrupt Pin Config + * @brief Set / Get Electrical behavior of interrupt pin1 or pin2 of the sensor + */ + +/*! + * \ingroup bma4ApiIntConfig + * \page bma4_api_bma4_set_int_pin_config bma4_set_int_pin_config + * \code + * int8_t bma4_set_int_pin_config(const struct bma4_int_pin_config *int_pin_config, + * uint8_t int_line, + * struct bma4_dev *dev); + * + * \endcode + * @details This function sets the electrical behaviour of interrupt pin1 or + * pin2 in the sensor. + * + * @param[in] int_pin_config : Pointer to structure variable which specifies + * the configuration data of either interrupt pin1 or 2. + * + *@verbatim + * ************************************************************************ + * Structure field members | Macros + * ********************************|*************************************** + * edge_ctrl | BMA4_LEVEL_TRIGGER(0) + * | BMA4_EDGE_TRIGGER(1) + * ********************************|*************************************** + * lvl | BMA4_ACTIVE_LOW(0) + * | BMA4_ACTIVE_HIGH(1) + * ********************************|*************************************** + * od | BMA4_PUSH_PULL(0) + * | BMA4_OPEN_DRAIN(1) + * ********************************|*************************************** + * output_en | BMA4_OUTPUT_DISABLE(0) + * | BMA4_OUTPUT_ENABLE(1) + * ********************************|*************************************** + * input_en | BMA4_INPUT_DISABLE(0) + * | BMA4_INPUT_ENABLE(1) + * ************************************************************************ + *@endverbatim + * + * @param[in] int_line : Variable used to select the interrupt pin1 or + * pin2 for interrupt configuration. + * + *@verbatim + * int_line | Value + * ----------------|---------------------- + * BMA4_INTR1_MAP | 0 + * BMA4_INTR2_MAP | 1 + *@endverbatim + * + * @param[in] dev : Structure instance of bma4_dev + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +int8_t bma4_set_int_pin_config(const struct bma4_int_pin_config *int_pin_config, uint8_t int_line, + struct bma4_dev *dev); + +/*! + * \ingroup bma4ApiIntConfig + * \page bma4_api_bma4_get_int_pin_config bma4_get_int_pin_config + * \code + * int8_t bma4_get_int_pin_config(struct bma4_int_pin_config *int_pin_config, uint8_t int_line, struct bma4_dev *dev); + * \endcode + * @details This API reads the electrical behavior of interrupt pin1 or pin2 + * from the sensor. + * + * @param[out] int_pin_config : Pointer to structure variable which stores the + * configuration data of either interrupt pin1 or pin2 read from the sensor + * + *@verbatim + * ************************************************************************ + * Structure field members | Macros + * ************************|*********************************************** + * edge_ctrl | BMA4_LEVEL_TRIGGER(0) + * | BMA4_EDGE_TRIGGER(1) + * ************************|*********************************************** + * lvl | BMA4_ACTIVE_LOW(0) + * | BMA4_ACTIVE_HIGH(1) + * ************************|*********************************************** + * od | BMA4_PUSH_PULL(0) + * | BMA4_OPEN_DRAIN(1) + * ************************|*********************************************** + * output_en | BMA4_OUTPUT_DISABLE(0) + * | BMA4_OUTPUT_ENABLE(1) + * ************************|*********************************************** + * input_en | BMA4_INPUT_DISABLE(0) + * | BMA4_INPUT_ENABLE(1) + * ************************************************************************ + *@endverbatim + * + * @param[in] int_line : Variable used to select the interrupt pin1 or + * pin2 for interrupt configuration. + * + *@verbatim + * int_line | Value + * -------------------|--------------- + * BMA4_INTR1_MAP | 0 + * BMA4_INTR2_MAP | 1 + *@endverbatim + * + * @param[in] dev : Structure instance of bma4_dev + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + * + */ +int8_t bma4_get_int_pin_config(struct bma4_int_pin_config *int_pin_config, uint8_t int_line, struct bma4_dev *dev); + +/** + * \ingroup bma4 + * \defgroup bma4ApiIntStatus Interrupt Status + * @brief Read Feature interrupt and/or Hardware interrupt status from the sensor + */ + +/*! + * \ingroup bma4ApiIntStatus + * \page bma4_api_bma4_read_int_status bma4_read_int_status + * \code + * int8_t bma4_read_int_status(uint16_t *int_status, struct bma4_dev *dev); + * \endcode + * @details This API reads the Feature and Hardware interrupt status from the sensor. + * + * @param[out] int_status : Variable used to get the interrupt status. + * @param[in] dev : Structure instance of bma4_dev. + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + * + */ +int8_t bma4_read_int_status(uint16_t *int_status, struct bma4_dev *dev); + +/** + * \ingroup bma4 + * \defgroup bma4ApiAux Auxiliary interface + * @brief Initialize and read/write data to auxiliary interface + */ + +/*! + * \ingroup bma4ApiAux + * \page bma4_api_bma4_aux_interface_init bma4_aux_interface_init + * \code + * int8_t bma4_aux_interface_init(struct bma4_dev *dev); + * \endcode + * @details This API initializes the auxiliary interface to access + * auxiliary sensor + * + * @param[in] dev : Structure instance of bma4_dev. + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + * + */ +int8_t bma4_aux_interface_init(struct bma4_dev *dev); + +/*! + * \ingroup bma4ApiAux + * \page bma4_api_bma4_aux_read bma4_aux_read + * \code + * int8_t bma4_aux_read(uint8_t aux_reg_addr, uint8_t *aux_data, uint16_t len, struct bma4_dev *dev); + * \endcode + * @details This API reads the data from the auxiliary sensor + * + * @param[in] dev : Structure instance of bma4_dev. + * @param[in] len : User specified data length + * @param[out] aux_data : Pointer variable to store data read + * @param[in] aux_reg_addr : Variable to pass address from where + * data is to be read + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + * + */ +int8_t bma4_aux_read(uint8_t aux_reg_addr, uint8_t *aux_data, uint16_t len, struct bma4_dev *dev); + +/*! + * \ingroup bma4ApiAux + * \page bma4_api_bma4_aux_write bma4_aux_write + * \code + * int8_t bma4_aux_write(uint8_t aux_reg_addr, uint8_t *aux_data, uint16_t len, struct bma4_dev *dev); + * \endcode + * @details This API writes the data into the auxiliary sensor + * + * @param[in] dev : Structure instance of bma4_dev. + * @param[in] len : User specified data length + * @param[out] aux_data : Pointer variable to store data read + * @param[in] aux_reg_addr : Variable to pass address from where + * data is to be written + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + * + */ +int8_t bma4_aux_write(uint8_t aux_reg_addr, const uint8_t *aux_data, uint16_t len, struct bma4_dev *dev); + +/** + * \ingroup bma4 + * \defgroup bma4ApiSoftReset Soft Reset + * @brief Perform Soft Reset of the sensor + */ + +/*! + * \ingroup bma4ApiSoftReset + * \page bma4_api_bma4_soft_reset bma4_soft_reset + * \code + * int8_t bma4_soft_reset(struct bma4_dev *dev); + * \endcode + * @details This API commands to do soft reset + * + * @param[in] dev : Structure instance of bma4_dev. + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + * + */ +int8_t bma4_soft_reset(struct bma4_dev *dev); + +/** + * \ingroup bma4 + * \defgroup bma4ApiAccelFoc Accel FOC + * @brief Performs Fast Offset Compensation for accel + */ + +/*! + * \ingroup bma4ApiAccelFoc + * \page bma4_api_bma4_perform_accel_foc bma4_perform_accel_foc + * \code + * int8_t bma4_perform_accel_foc(const struct bma4_accel_foc_g_value *accel_g_value, struct bma4_dev *dev); + * \endcode + * @details This API performs Fast Offset Compensation for Accel. + * @param[in] accel_g_value : Array which stores the Accel g units + * for x,y and z-axis. + * + *@verbatim + * accel_g_value | Description + * --------------------------|--------------------------------------- + * accel_g_value[0] | x-axis g units + * accel_g_value[1] | y-axis g units + * accel_g_value[2] | z-axis g units + *@endverbatim + * + * @param[in] dev : Structure instance of dev. + * + * @return Result of API execution status. + * @retval 0 -> Success + * @retval Any non zero value -> Fail + * + */ +int8_t bma4_perform_accel_foc(const struct bma4_accel_foc_g_value *accel_g_value, struct bma4_dev *dev); + +/** + * \ingroup bma4 + * \defgroup bma4ApiAxisRemap Axis Remap + * @brief Functions of axis re-mapping of bma4 sensors + */ + +/*! + * \ingroup bma4ApiAxisRemap + * @brief Set / Get x, y and z axis re-mapping in the sensor + * \page bma4_api_bma4_set_remap_axes bma4_set_remap_axes + * \code + * int8_t bma4_set_remap_axes(const struct bma4_remap *remapped_axis, uint8_t *feature_config, uint8_t index, uint8_t feature_len, struct bma4_dev *dev); + * \endcode + * @details This API sets the re-mapped x, y and z axes to the sensor and + * updates them in the device structure. + * + * @param[in] remap_data : Structure instance of bma4_remap + * @param[in] feature_config : Array data containing feature configurations + * @param[in] index : Index to which mapping has to be applied + * @param[in] feature_len : Length of feature configurations + * @param[in, out] dev : Structure instance of bma4_dev + * + * @return Result of API execution status. + * + * @return 0 -> Success + * @return < 0 -> Fail + * + */ +int8_t bma4_set_remap_axes(const struct bma4_remap *remapped_axis, + uint8_t *feature_config, + uint8_t index, + uint8_t feature_len, + struct bma4_dev *dev); + +/*! + * \ingroup bma4ApiAxisRemap + * \page bma4_api_bma4_get_remap_axes bma4_get_remap_axes + * \code + * int8_t bma4_get_remap_axes(struct bma4_remap *remapped_axis, uint8_t *feature_config, uint8_t index, uint8_t feature_len, struct bma4_dev *dev); + * \endcode + * @details This API gets the re-mapped x, y and z axes from the sensor and + * updates the values in the device structure. + * + * @param[out] remap_data : Structure instance of bma4_remap + * @param[in] feature_config : Array data containing feature configurations + * @param[in] index : Index to which mapping has to be applied + * @param[in] feature_len : Length of feature configurations + * @param[in, out] dev : Structure instance of bma4_dev + * + * @return Result of API execution status. + * + * @return 0 -> Success + * @return < 0 -> Fail + * + */ +int8_t bma4_get_remap_axes(struct bma4_remap *remap_data, + uint8_t *feature_config, + uint8_t index, + uint8_t feature_len, + struct bma4_dev *dev); + +#endif + +/* End of __BMA4_H__ */ diff --git a/components/bma456/bma456_an.c b/components/bma456/bma456_an.c new file mode 100644 index 0000000..e93da06 --- /dev/null +++ b/components/bma456/bma456_an.c @@ -0,0 +1,619 @@ +/** +* 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. +* +* @file bma456_an.c +* @date 2023-07-05 +* @version V2.29.0 +* +*/ + +/*! \file bma456_an.c + * \brief Sensor Driver for BMA456_AN sensor + */ + +#include "bma456_an.h" + +/**\name Feature configuration file */ +const uint8_t bma456_an_config_file[] = { + 0xc8, 0x2e, 0x00, 0x2e, 0xc8, 0x2e, 0x00, 0x2e, 0xc8, 0x2e, 0x00, 0x2e, 0xc8, 0x2e, 0x00, 0x2e, 0xc8, 0x2e, 0x00, + 0x2e, 0xc8, 0x2e, 0x00, 0x2e, 0xc8, 0x2e, 0x00, 0x2e, 0x80, 0x2e, 0x58, 0x01, 0x80, 0x2e, 0x42, 0x02, 0xb0, 0xf0, + 0x10, 0x30, 0x21, 0x2e, 0x16, 0xf0, 0x80, 0x2e, 0xf0, 0x00, 0x1f, 0x50, 0x1d, 0x52, 0x01, 0x42, 0x3b, 0x80, 0x41, + 0x30, 0x01, 0x42, 0x3c, 0x80, 0x00, 0x2e, 0x01, 0x40, 0x01, 0x42, 0x21, 0x2e, 0xff, 0xaf, 0xb8, 0x2e, 0x2c, 0x82, + 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, + 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0xfd, 0x2d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x01, 0x2e, 0x55, 0xf0, 0xc0, 0x2e, 0x21, 0x2e, 0x55, 0xf0, 0x44, 0x47, 0xaa, 0x00, 0x05, 0x00, 0xaa, + 0x00, 0x05, 0x00, 0x42, 0x58, 0x88, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0x52, 0x0b, 0x50, 0x60, 0x42, 0x00, 0x3f, 0x0d, 0x54, 0x42, 0x42, 0x69, 0x82, + 0x0f, 0x54, 0x42, 0x42, 0x42, 0x82, 0x4b, 0x30, 0x42, 0x40, 0x10, 0x08, 0x50, 0x42, 0x7e, 0x80, 0x4b, 0x42, 0x61, + 0x30, 0x01, 0x42, 0x10, 0x50, 0x03, 0x2e, 0x40, 0xf0, 0x56, 0xb2, 0x08, 0x80, 0x31, 0x30, 0xf0, 0x7f, 0x03, 0x2f, + 0x01, 0x2e, 0x40, 0xf0, 0x1a, 0x90, 0x21, 0x2f, 0x98, 0x2e, 0x1e, 0xb0, 0x03, 0x30, 0x13, 0x50, 0x17, 0x52, 0x11, + 0x54, 0x54, 0x33, 0x06, 0x30, 0x55, 0x32, 0x1d, 0x1a, 0xe3, 0x22, 0x18, 0x1a, 0x15, 0x58, 0xe3, 0x22, 0x04, 0x30, + 0xd5, 0x40, 0xb5, 0x0d, 0xe1, 0xbe, 0x6f, 0xbb, 0x80, 0x91, 0xa9, 0x0d, 0x01, 0x89, 0xb5, 0x23, 0x10, 0xa1, 0xf7, + 0x2f, 0xda, 0x0e, 0x54, 0x33, 0xeb, 0x2f, 0x01, 0x2e, 0x25, 0x00, 0x70, 0x1a, 0x00, 0x30, 0x21, 0x30, 0x48, 0x22, + 0x40, 0xb2, 0x06, 0x2f, 0x23, 0x2e, 0x59, 0xf0, 0x98, 0x2e, 0x3a, 0x00, 0x00, 0x2e, 0x00, 0x2e, 0xd0, 0x2e, 0xf0, + 0x6f, 0x01, 0x31, 0x20, 0x26, 0x01, 0x42, 0x10, 0x30, 0x21, 0x2e, 0x59, 0xf0, 0x98, 0x2e, 0x3a, 0x00, 0x01, 0x50, + 0x03, 0x52, 0x98, 0x2e, 0x7f, 0x01, 0x01, 0x50, 0x05, 0x84, 0x13, 0x30, 0x05, 0x50, 0x64, 0x30, 0x07, 0x52, 0x93, + 0x42, 0x84, 0x42, 0x98, 0x2e, 0x7f, 0x01, 0x05, 0x50, 0x06, 0x80, 0x71, 0x30, 0x01, 0x42, 0x00, 0x2e, 0x00, 0x2e, + 0xd0, 0x2e, 0x98, 0x2e, 0xd6, 0x00, 0x01, 0x2e, 0x36, 0x00, 0x00, 0xb2, 0x0d, 0x2f, 0x00, 0x30, 0x21, 0x2e, 0x36, + 0x00, 0x09, 0x50, 0x98, 0x2e, 0x18, 0x01, 0x09, 0x50, 0x01, 0x52, 0x98, 0x2e, 0x90, 0x01, 0x09, 0x50, 0x05, 0x52, + 0x98, 0x2e, 0x90, 0x01, 0x98, 0x2e, 0x3a, 0x00, 0xe6, 0x2d, 0x07, 0x2e, 0x00, 0xf0, 0x03, 0x2e, 0x00, 0xf0, 0x21, + 0x50, 0x9c, 0xbe, 0x02, 0x40, 0x1d, 0x52, 0xf4, 0x33, 0xdc, 0xba, 0xd9, 0x0f, 0x94, 0x08, 0x06, 0x2f, 0x49, 0xaf, + 0x04, 0x2f, 0x51, 0x0a, 0x02, 0x34, 0x47, 0xa3, 0x8a, 0x0a, 0x91, 0x22, 0x3c, 0x80, 0x25, 0x2e, 0x59, 0xf0, 0x01, + 0x40, 0x01, 0x42, 0xb8, 0x2e, 0x1a, 0x24, 0x26, 0x00, 0x80, 0x2e, 0x58, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, + 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x46, + 0x00, 0x40, 0x00, 0x4f, 0x00, 0x42, 0x00, 0x37, 0x00, 0xaf, 0x00, 0xff, 0x00, 0xec, 0x00, 0xff, 0xb7, 0x00, 0x02, + 0x00, 0xb0, 0x05, 0x80, 0xc9, 0xf0, 0x88, 0x00, 0x80, 0x00, 0x5e, 0xf0, 0x59, 0xf0, 0x89, 0xf0, 0x3a, 0x00, 0x80, + 0x2e, 0x00, 0xae, 0x44, 0x47, 0xfd, 0x2d, 0x00, 0x0c, 0x60, 0x50, 0x03, 0x2e, 0x45, 0x00, 0xe0, 0x7f, 0xf1, 0x7f, + 0xdb, 0x7f, 0x30, 0x30, 0x1b, 0x54, 0x0a, 0x1a, 0x28, 0x2f, 0x1a, 0x25, 0x7a, 0x82, 0x00, 0x30, 0x43, 0x30, 0x32, + 0x30, 0x05, 0x30, 0x04, 0x30, 0xf6, 0x6f, 0xf2, 0x09, 0xfc, 0x13, 0xc2, 0xab, 0xb3, 0x09, 0xef, 0x23, 0x80, 0xb3, + 0xe6, 0x6f, 0xb7, 0x01, 0x00, 0x2e, 0x8b, 0x41, 0x4b, 0x42, 0x03, 0x2f, 0x46, 0x40, 0x86, 0x17, 0x81, 0x8d, 0x46, + 0x42, 0x41, 0x8b, 0x23, 0xbd, 0xb3, 0xbd, 0x03, 0x89, 0x41, 0x82, 0x07, 0x0c, 0x43, 0xa3, 0xe6, 0x2f, 0xe1, 0x6f, + 0xa2, 0x6f, 0x52, 0x42, 0x00, 0x2e, 0xb2, 0x6f, 0x52, 0x42, 0x00, 0x2e, 0xc2, 0x6f, 0x42, 0x42, 0x03, 0xb2, 0x03, + 0x2e, 0x59, 0xf0, 0xf3, 0x3d, 0x02, 0x32, 0x0b, 0x08, 0x8a, 0x0a, 0xdb, 0x6f, 0x02, 0x22, 0xa0, 0x5f, 0x21, 0x2e, + 0x59, 0xf0, 0xb8, 0x2e, 0x60, 0x50, 0xc3, 0x7f, 0xd4, 0x7f, 0xe7, 0x7f, 0xf6, 0x7f, 0xb2, 0x7f, 0xa5, 0x7f, 0x36, + 0x30, 0x07, 0x2e, 0x01, 0xf0, 0xbe, 0xbd, 0xbe, 0xbb, 0x23, 0x58, 0x77, 0x05, 0x09, 0x56, 0x25, 0x54, 0x27, 0x41, + 0x06, 0x41, 0xf8, 0xbf, 0xbe, 0x0b, 0xb5, 0x11, 0xd6, 0x42, 0x03, 0x89, 0x5a, 0x0e, 0xf6, 0x2f, 0x12, 0x30, 0x25, + 0x2e, 0x36, 0x00, 0x02, 0x31, 0x25, 0x2e, 0xb8, 0xf0, 0xd4, 0x6f, 0xc3, 0x6f, 0xe7, 0x6f, 0xb2, 0x6f, 0xa5, 0x6f, + 0xf6, 0x6f, 0xa0, 0x5f, 0xc8, 0x2e, 0x09, 0x86, 0x02, 0x30, 0x12, 0x42, 0x43, 0x0e, 0xfc, 0x2f, 0x37, 0x80, 0x13, + 0x30, 0x13, 0x42, 0x12, 0x42, 0x12, 0x42, 0x12, 0x42, 0x02, 0x42, 0x03, 0x80, 0x41, 0x84, 0x11, 0x42, 0x02, 0x42, + 0xb8, 0x2e, 0x46, 0x84, 0x80, 0x50, 0xa3, 0x40, 0x83, 0x88, 0x82, 0x40, 0x04, 0x41, 0xc3, 0x7f, 0x42, 0x8a, 0x06, + 0x41, 0x6d, 0xbb, 0xf6, 0x7f, 0x80, 0xb3, 0xd5, 0x7f, 0xe0, 0x7f, 0x59, 0x2f, 0x31, 0x25, 0x55, 0x40, 0x41, 0x91, + 0xb1, 0x7f, 0x0f, 0x2f, 0x01, 0x30, 0xc1, 0x42, 0x00, 0x2e, 0xd2, 0x6f, 0x13, 0x40, 0x93, 0x42, 0x00, 0x2e, 0x13, + 0x40, 0x93, 0x42, 0x00, 0x2e, 0x00, 0x40, 0x80, 0x42, 0xbd, 0x80, 0xc0, 0x2e, 0x01, 0x42, 0x80, 0x5f, 0xc7, 0x86, + 0x01, 0x30, 0xc5, 0x40, 0xfb, 0x86, 0x45, 0x41, 0x04, 0x41, 0x43, 0xbe, 0xd5, 0xbe, 0x43, 0xba, 0xd5, 0xba, 0x84, + 0x7f, 0x95, 0x7f, 0xa1, 0x7f, 0x14, 0x30, 0x61, 0x15, 0xf5, 0x09, 0x15, 0x40, 0xc0, 0xb3, 0x0b, 0x2f, 0xc6, 0x40, + 0xae, 0x05, 0x07, 0x30, 0xfe, 0x05, 0x80, 0xa9, 0xb7, 0x23, 0x97, 0x6f, 0x77, 0x0f, 0xa6, 0x6f, 0xe6, 0x23, 0xf6, + 0x6f, 0xa7, 0x7f, 0x80, 0x90, 0x00, 0x2f, 0xc5, 0x42, 0x41, 0x82, 0xc1, 0x86, 0x43, 0xa2, 0xe7, 0x2f, 0xa1, 0x6f, + 0xb0, 0x6f, 0x0a, 0x1a, 0x02, 0x2f, 0x01, 0x30, 0x1b, 0x2c, 0x01, 0x42, 0x01, 0x40, 0x4c, 0x28, 0x82, 0x6f, 0x01, + 0x42, 0x4a, 0x0e, 0x13, 0x2f, 0xc0, 0x6f, 0x00, 0xb2, 0x03, 0x2f, 0x3f, 0x80, 0x20, 0x14, 0x21, 0x2e, 0x5e, 0xf0, + 0xe1, 0x6f, 0xd0, 0x6f, 0x52, 0x40, 0x12, 0x42, 0x00, 0x2e, 0x52, 0x40, 0x12, 0x42, 0x00, 0x2e, 0x41, 0x40, 0x03, + 0x2c, 0x01, 0x42, 0x10, 0x30, 0x40, 0x42, 0x80, 0x5f, 0xb8, 0x2e, 0x80, 0x2e, 0x18, 0x00, 0xfd, 0x2d, 0x30, 0x50, + 0x2a, 0x25, 0xbd, 0x84, 0xfb, 0x7f, 0x8b, 0x31, 0x27, 0x56, 0x83, 0x42, 0xeb, 0x7f, 0x06, 0x30, 0x14, 0x30, 0x05, + 0x30, 0x0d, 0x2c, 0x13, 0x56, 0x43, 0x1a, 0x02, 0x2f, 0x4e, 0x04, 0x06, 0x30, 0x15, 0x50, 0xec, 0x09, 0xd7, 0x01, + 0x41, 0x8b, 0xcb, 0x41, 0xc6, 0x01, 0x81, 0x8d, 0xcb, 0x43, 0x31, 0x0e, 0xf1, 0x2f, 0xfb, 0x6f, 0xd0, 0x5f, 0xb8, + 0x2e, 0x10, 0x50, 0x01, 0x2e, 0x35, 0x00, 0x00, 0xb2, 0xfb, 0x7f, 0x19, 0x2f, 0x29, 0x56, 0x2f, 0x52, 0x13, 0x54, + 0xc3, 0x00, 0x48, 0x04, 0xc2, 0x0f, 0x18, 0x22, 0x41, 0xb2, 0x0e, 0x2f, 0x12, 0x30, 0x8a, 0x08, 0x80, 0xb2, 0x06, + 0x2f, 0x7f, 0x82, 0x98, 0x2e, 0x00, 0xb0, 0x2d, 0x52, 0x23, 0x2e, 0xff, 0xb9, 0x06, 0x2d, 0xfb, 0x6f, 0xf0, 0x5f, + 0x80, 0x2e, 0x00, 0xb0, 0x2b, 0x52, 0x01, 0x42, 0x00, 0x2e, 0xfb, 0x6f, 0xf0, 0x5f, 0xb8, 0x2e, 0x10, 0x24, 0x58, + 0x02, 0x11, 0x24, 0x00, 0x0c, 0x12, 0x24, 0x80, 0x2e, 0x13, 0x24, 0x18, 0x00, 0x12, 0x42, 0x13, 0x42, 0x41, 0x1a, + 0xfb, 0x2f, 0x10, 0x24, 0x50, 0x39, 0x11, 0x24, 0x21, 0x2e, 0x21, 0x2e, 0x10, 0x00, 0x23, 0x2e, 0x11, 0x00, 0x80, + 0x2e, 0x10, 0x00 +}; + +/***************************************************************************/ + +/**\name 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 and sets the resolution. + */ +int8_t bma456_an_init(struct bma4_dev *dev) +{ + int8_t rslt; + + /* Structure to define the default values for axes re-mapping */ + struct bma4_axes_remap axes_remap = { + .x_axis = BMA4_MAP_X_AXIS, .x_axis_sign = BMA4_MAP_POSITIVE, .y_axis = BMA4_MAP_Y_AXIS, + .y_axis_sign = BMA4_MAP_POSITIVE, .z_axis = BMA4_MAP_Z_AXIS, .z_axis_sign = BMA4_MAP_POSITIVE + }; + + rslt = bma4_init(dev); + if (rslt == BMA4_OK) + { + if ((dev->chip_id == BMA456_AN_CHIP_ID_PRIM) || (dev->chip_id == BMA456_AN_CHIP_ID_SEC)) + { + /* Resolution of BMA456_AN sensor is 16 bit */ + dev->resolution = BMA4_16_BIT_RESOLUTION; + + dev->feature_len = BMA456_AN_FEATURE_SIZE; + + dev->config_size = sizeof(bma456_an_config_file); + + /* Set the default values for axis + * re-mapping in the device structure + */ + dev->remap = axes_remap; + } + else + { + rslt = BMA4_E_INVALID_SENSOR; + } + } + + return rslt; +} + +/*! + * @brief This API is used to upload the configuration file to enable the + * features of the sensor. + */ +int8_t bma456_an_write_config_file(struct bma4_dev *dev) +{ + int8_t rslt = BMA4_OK; + + if (dev != NULL) + { + if ((dev->chip_id == BMA456_AN_CHIP_ID_PRIM) || (dev->chip_id == BMA456_AN_CHIP_ID_SEC)) + { + /* Configuration stream read/write length boundary + * check + */ + if ((dev->read_write_len >= BMA456_AN_RD_WR_MIN_LEN) && (dev->read_write_len <= BMA456_AN_RD_WR_MAX_LEN)) + { + /* Even or odd check */ + if ((dev->read_write_len % 2) != 0) + { + dev->read_write_len = dev->read_write_len - 1; + } + + /* Assign stream data */ + dev->config_file_ptr = bma456_an_config_file; + rslt = bma4_write_config_file(dev); + } + else + { + rslt = BMA4_E_RD_WR_LENGTH_INVALID; + } + } + else + { + rslt = BMA4_E_INVALID_SENSOR; + } + } + else + { + rslt = BMA4_E_NULL_PTR; + } + + return rslt; +} + +/*! + * @brief This API is used to get the config file major and minor information. + */ +int8_t bma456_an_get_version_config(uint16_t *config_major, uint16_t *config_minor, struct bma4_dev *dev) +{ + /* Initialize configuration file */ + uint8_t feature_config[BMA456_AN_FEATURE_SIZE] = { 0 }; + + /* Update index to config file version */ + uint8_t index = BMA456_AN_CONFIG_ID_OFFSET; + + /* Variable to define LSB */ + uint8_t lsb = 0; + + /* Variable to define MSB */ + uint8_t msb = 0; + + /* Variable to define LSB and MSB */ + uint16_t lsb_msb = 0; + + /* Result of api are returned to this variable */ + int8_t rslt = BMA4_OK; + + if ((config_major != NULL) && (config_minor != NULL)) + { + rslt = bma4_set_advance_power_save(BMA4_DISABLE, dev); + + if (rslt == BMA4_OK) + { + /* Wait for sensor time synchronization. Refer the data-sheet for + * more information + */ + dev->delay_us(450, dev->intf_ptr); + + /* Get config file identification from the sensor */ + rslt = bma4_read_regs(BMA4_FEATURE_CONFIG_ADDR, feature_config, BMA456_AN_FEATURE_SIZE, dev); + + if (rslt == BMA4_OK) + { + /* Get word to calculate config file identification */ + lsb = feature_config[index++]; + msb = feature_config[index++]; + + lsb_msb = (uint16_t)(msb << 8 | lsb); + + /* Get major and minor version */ + *config_major = BMA4_GET_BITSLICE(lsb_msb, BMA4_CONFIG_MAJOR); + *config_minor = BMA4_GET_BITS_POS_0(lsb, BMA4_CONFIG_MINOR); + } + } + } + else + { + rslt = BMA4_E_NULL_PTR; + } + + return rslt; +} + +/*! + * @brief This API sets/un-sets the user provided interrupt to either interrupt + * pin1 or pin2 in the sensor. + */ +int8_t bma456_an_map_interrupt(uint8_t int_line, uint16_t int_map, uint8_t enable, struct bma4_dev *dev) +{ + int8_t rslt = BMA4_OK; + + if (dev != NULL) + { + if ((dev->chip_id == BMA456_AN_CHIP_ID_PRIM) || (dev->chip_id == BMA456_AN_CHIP_ID_SEC)) + { + if (int_line <= 1) + { + /* Map/Unmap the interrupt */ + rslt = bma4_map_interrupt(int_line, int_map, enable, dev); + } + else + { + rslt = BMA4_E_INT_LINE_INVALID; + } + } + else + { + rslt = BMA4_E_INVALID_SENSOR; + } + } + else + { + rslt = BMA4_E_NULL_PTR; + } + + return rslt; +} + +/*! + * @brief This API reads the bma456_an interrupt status from the sensor. + */ +int8_t bma456_an_read_int_status(uint16_t *int_status, struct bma4_dev *dev) +{ + int8_t rslt = BMA4_OK; + + if ((dev != NULL) && (int_status != NULL)) + { + if ((dev->chip_id == BMA456_AN_CHIP_ID_PRIM) || (dev->chip_id == BMA456_AN_CHIP_ID_SEC)) + { + /* Read the interrupt status */ + rslt = bma4_read_int_status(int_status, dev); + } + else + { + rslt = BMA4_E_INVALID_SENSOR; + } + } + else + { + rslt = BMA4_E_NULL_PTR; + } + + return rslt; +} + +/*! + * @brief This API performs x, y and z axis remapping in the sensor. + */ +int8_t bma456_an_set_remap_axes(const struct bma4_remap *remap_axes, struct bma4_dev *dev) +{ + uint8_t feature_config[BMA456_AN_FEATURE_SIZE] = { 0 }; + uint8_t index = BMA456_AN_AXES_REMAP_OFFSET; + int8_t rslt = BMA4_OK; + + if (remap_axes != NULL) + { + rslt = bma4_set_remap_axes(remap_axes, feature_config, index, BMA456_AN_FEATURE_SIZE, dev); + } + else + { + rslt = BMA4_E_NULL_PTR; + } + + return rslt; +} + +/*! + * @brief This API reads the x, y and z axis remap data from the sensor. + */ +int8_t bma456_an_get_remap_axes(struct bma4_remap *remap_axes, struct bma4_dev *dev) +{ + uint8_t feature_config[BMA456_AN_FEATURE_SIZE] = { 0 }; + uint8_t index = BMA456_AN_AXES_REMAP_OFFSET; + int8_t rslt = BMA4_OK; + + if (remap_axes != NULL) + { + rslt = bma4_get_remap_axes(remap_axes, feature_config, index, BMA456_AN_FEATURE_SIZE, dev); + } + else + { + rslt = BMA4_E_NULL_PTR; + } + + return rslt; +} + +/*! + * @brief This API sets the configuration of any-motion feature in the sensor. + * This API enables/disables the any-motion feature according to the axis set. + */ +int8_t bma456_an_set_any_mot_config(const struct bma456_an_any_no_mot_config *any_motion, struct bma4_dev *dev) +{ + /* Variable to define error */ + int8_t rslt = BMA4_OK; + + /* Initialize configuration file */ + uint8_t feature_config[BMA456_AN_FEATURE_SIZE] = { 0 }; + + /* Update index to configure any-motion axes */ + uint8_t index = BMA456_AN_ANY_MOT_OFFSET; + + /* Variable to define LSB */ + uint16_t lsb = 0; + + /* Variable to define MSB */ + uint16_t msb = 0; + + /* Variable to define LSB and MSB */ + uint16_t lsb_msb = 0; + + if ((dev != NULL) && (any_motion != NULL)) + { + /* Get any-motion configuration from the sensor */ + rslt = bma4_read_regs(BMA4_FEATURE_CONFIG_ADDR, feature_config, BMA456_AN_ANY_MOT_LEN, dev); + if (rslt == BMA4_OK) + { + /* Set threshold value in feature configuration array */ + feature_config[index++] = BMA4_GET_LSB(any_motion->threshold); + feature_config[index++] = BMA4_GET_MSB(any_motion->threshold); + + /* Extract the word where duration and axes enable + * resides + */ + lsb = feature_config[index]; + msb = feature_config[index + 1] << 8; + lsb_msb = lsb | msb; + + /* Set the duration in the same word */ + lsb_msb = BMA4_SET_BITS_POS_0(lsb_msb, BMA456_AN_ANY_NO_MOT_DUR, any_motion->duration); + + /* Set the axes in the same word */ + lsb_msb = BMA4_SET_BITSLICE(lsb_msb, BMA456_AN_ANY_NO_MOT_AXIS_EN, any_motion->axes_en); + + /* Assign the word with set duration and axes enable + * value back to feature configuration array + */ + feature_config[index++] = BMA4_GET_LSB(lsb_msb); + feature_config[index] = BMA4_GET_MSB(lsb_msb); + + /* Set any-motion configuration to the sensor */ + rslt = bma4_write_regs(BMA4_FEATURE_CONFIG_ADDR, feature_config, BMA456_AN_ANY_MOT_LEN, dev); + } + } + else + { + rslt = BMA4_E_NULL_PTR; + } + + return rslt; +} + +/*! + * @brief This API gets the configuration of any-motion feature from the + * sensor. + */ +int8_t bma456_an_get_any_mot_config(struct bma456_an_any_no_mot_config *any_motion, struct bma4_dev *dev) +{ + /* Variable to define error */ + int8_t rslt = BMA4_OK; + + /* Initialize configuration file */ + uint8_t feature_config[BMA456_AN_FEATURE_SIZE] = { 0 }; + + /* Update index to configure any-motion axes */ + uint8_t index = BMA456_AN_ANY_MOT_OFFSET; + + /* Variable to define LSB */ + uint16_t lsb = 0; + + /* Variable to define MSB */ + uint16_t msb = 0; + + /* Variable to define LSB and MSB */ + uint16_t lsb_msb = 0; + + if ((dev != NULL) && (any_motion != NULL)) + { + /* Get any-motion configuration from the sensor */ + rslt = bma4_read_regs(BMA4_FEATURE_CONFIG_ADDR, feature_config, BMA456_AN_ANY_MOT_LEN, dev); + if (rslt == BMA4_OK) + { + /* Get word to calculate threshold and any-motion + * select + */ + lsb = (uint16_t)feature_config[index++]; + msb = ((uint16_t)feature_config[index++] << 8); + lsb_msb = lsb | msb; + + /* Extract threshold value */ + any_motion->threshold = lsb_msb & BMA456_AN_ANY_NO_MOT_THRES_MSK; + + /* Get word to calculate duration and axes enable */ + lsb = (uint16_t)feature_config[index++]; + msb = ((uint16_t)feature_config[index] << 8); + lsb_msb = lsb | msb; + + /* Extract duration value */ + any_motion->duration = lsb_msb & BMA456_AN_ANY_NO_MOT_DUR_MSK; + + /* Extract axes enable value */ + any_motion->axes_en = + (uint8_t)((lsb_msb & BMA456_AN_ANY_NO_MOT_AXIS_EN_MSK) >> BMA456_AN_ANY_NO_MOT_AXIS_EN_POS); + } + } + else + { + rslt = BMA4_E_NULL_PTR; + } + + return rslt; +} + +/*! + * @brief This API sets the configuration of no-motion feature in the sensor. + * This API enables/disables the no-motion feature according to the axis set. + */ +int8_t bma456_an_set_no_mot_config(const struct bma456_an_any_no_mot_config *no_motion, struct bma4_dev *dev) +{ + /* Variable to define error */ + int8_t rslt = BMA4_OK; + + /* Initialize configuration file */ + uint8_t feature_config[BMA456_AN_FEATURE_SIZE] = { 0 }; + + /* Update index to configure no-motion axes */ + uint8_t index = BMA456_AN_NO_MOT_OFFSET; + + /* Variable to define LSB */ + uint16_t lsb = 0; + + /* Variable to define MSB */ + uint16_t msb = 0; + + /* Variable to define LSB and MSB */ + uint16_t lsb_msb = 0; + + if ((dev != NULL) && (no_motion != NULL)) + { + /* Get no-motion configuration from the sensor */ + rslt = bma4_read_regs(BMA4_FEATURE_CONFIG_ADDR, feature_config, BMA456_AN_NO_MOT_RD_WR_LEN, dev); + if (rslt == BMA4_OK) + { + /* Set threshold value in feature configuration array */ + feature_config[index++] = BMA4_GET_LSB(no_motion->threshold); + feature_config[index++] = BMA4_GET_MSB(no_motion->threshold); + + /* Extract the word where duration and axes enable + * resides + */ + lsb = feature_config[index]; + msb = feature_config[index + 1] << 8; + lsb_msb = lsb | msb; + + /* Set the duration in the same word */ + lsb_msb = BMA4_SET_BITS_POS_0(lsb_msb, BMA456_AN_ANY_NO_MOT_DUR, no_motion->duration); + + /* Set the axes in the same word */ + lsb_msb = BMA4_SET_BITSLICE(lsb_msb, BMA456_AN_ANY_NO_MOT_AXIS_EN, no_motion->axes_en); + + /* Assign the word with set duration and axes enable + * value back to feature configuration array + */ + feature_config[index++] = BMA4_GET_LSB(lsb_msb); + feature_config[index] = BMA4_GET_MSB(lsb_msb); + + /* Set no-motion configuration to the sensor */ + rslt = bma4_write_regs(BMA4_FEATURE_CONFIG_ADDR, feature_config, BMA456_AN_NO_MOT_RD_WR_LEN, dev); + } + } + else + { + rslt = BMA4_E_NULL_PTR; + } + + return rslt; +} + +/*! + * @brief This API gets the configuration of no-motion feature from the + * sensor. + */ +int8_t bma456_an_get_no_mot_config(struct bma456_an_any_no_mot_config *no_motion, struct bma4_dev *dev) +{ + /* Variable to define error */ + int8_t rslt = BMA4_OK; + + /* Initialize configuration file */ + uint8_t feature_config[BMA456_AN_FEATURE_SIZE] = { 0 }; + + /* Update index to configure no-motion axes */ + uint8_t index = BMA456_AN_NO_MOT_OFFSET; + + /* Variable to define LSB */ + uint16_t lsb = 0; + + /* Variable to define MSB */ + uint16_t msb = 0; + + /* Variable to define LSB and MSB */ + uint16_t lsb_msb = 0; + + if ((dev != NULL) && (no_motion != NULL)) + { + /* Get no-motion configuration from the sensor */ + rslt = bma4_read_regs(BMA4_FEATURE_CONFIG_ADDR, feature_config, BMA456_AN_NO_MOT_RD_WR_LEN, dev); + if (rslt == BMA4_OK) + { + /* Get word to calculate threshold and no-motion + * select + */ + lsb = (uint16_t)feature_config[index++]; + msb = ((uint16_t)feature_config[index++] << 8); + lsb_msb = lsb | msb; + + /* Extract threshold value */ + no_motion->threshold = lsb_msb & BMA456_AN_ANY_NO_MOT_THRES_MSK; + + /* Get word to calculate duration and axes enable */ + lsb = (uint16_t)feature_config[index++]; + msb = ((uint16_t)feature_config[index] << 8); + lsb_msb = lsb | msb; + + /* Extract duration value */ + no_motion->duration = lsb_msb & BMA456_AN_ANY_NO_MOT_DUR_MSK; + + /* Extract axes enable value */ + no_motion->axes_en = + (uint8_t)((lsb_msb & BMA456_AN_ANY_NO_MOT_AXIS_EN_MSK) >> BMA456_AN_ANY_NO_MOT_AXIS_EN_POS); + } + } + else + { + rslt = BMA4_E_NULL_PTR; + } + + return rslt; +} + +/*! @endcond */ diff --git a/components/bma456/bma456_an.h b/components/bma456/bma456_an.h new file mode 100644 index 0000000..38a9f02 --- /dev/null +++ b/components/bma456/bma456_an.h @@ -0,0 +1,566 @@ +/** +* 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. +* +* @file bma456_an.h +* @date 2023-07-05 +* @version V2.29.0 +* +*/ + +/** + * \ingroup bma4xy + * \defgroup bma456_an BMA456_AN + * @brief Sensor driver for BMA456_AN sensor + */ + +#ifndef BMA456_AN_H +#define BMA456_AN_H + +#ifdef __cplusplus +extern "C" { +#endif +#include "bma4.h" + +/**\name Chip ID of BMA456_AN sensor */ +#define BMA456_AN_CHIP_ID_PRIM UINT8_C(0x16) +#define BMA456_AN_CHIP_ID_SEC UINT8_C(0x1A) + +/**\name Sensor feature size */ +#define BMA456_AN_FEATURE_SIZE UINT8_C(12) +#define BMA456_AN_ANY_MOT_LEN UINT8_C(4) + +/**\name Feature offset address */ +#define BMA456_AN_ANY_MOT_OFFSET UINT8_C(0x00) +#define BMA456_AN_NO_MOT_OFFSET UINT8_C(0x04) +#define BMA456_AN_CONFIG_ID_OFFSET UINT8_C(0x08) +#define BMA456_AN_AXES_REMAP_OFFSET UINT8_C(0x0A) + +/**\name Read/Write Lengths */ +#define BMA456_AN_RD_WR_MIN_LEN UINT8_C(2) + +/*! @name Maximum valid read write length is size of config file array */ +#define BMA456_AN_RD_WR_MAX_LEN ((uint16_t)sizeof(bma456_an_config_file)) + +#define BMA456_AN_NO_MOT_RD_WR_LEN (BMA456_AN_ANY_MOT_LEN + BMA456_AN_NO_MOT_OFFSET) + +/**************************************************************/ +/**\name Re-map Axes */ +/**************************************************************/ +#define BMA456_AN_X_AXIS_MASK UINT8_C(0x03) +#define BMA456_AN_X_AXIS_SIGN_MASK UINT8_C(0x04) +#define BMA456_AN_Y_AXIS_MASK UINT8_C(0x18) +#define BMA456_AN_Y_AXIS_SIGN_MASK UINT8_C(0x20) +#define BMA456_AN_Z_AXIS_MASK UINT8_C(0xC0) +#define BMA456_AN_Z_AXIS_SIGN_MASK UINT8_C(0x01) + +/**************************************************************/ +/**\name Any/no Motion */ +/**************************************************************/ +/**\name Any/No motion threshold macros */ +#define BMA456_AN_ANY_NO_MOT_THRES_MSK UINT16_C(0x07FF) + +/**\name Any/No motion duration macros */ +#define BMA456_AN_ANY_NO_MOT_DUR_MSK UINT16_C(0x1FFF) + +/**\name Any/No motion enable macros */ +#define BMA456_AN_ANY_NO_MOT_AXIS_EN_POS UINT8_C(0x0D) +#define BMA456_AN_ANY_NO_MOT_AXIS_EN_MSK UINT16_C(0xE000) + +/**************************************************************/ +/**\name User macros */ +/**************************************************************/ +/**\name Any-motion/No-motion axis enable macros */ +#define BMA456_AN_X_AXIS_EN UINT8_C(0x01) +#define BMA456_AN_Y_AXIS_EN UINT8_C(0x02) +#define BMA456_AN_Z_AXIS_EN UINT8_C(0x04) +#define BMA456_AN_EN_ALL_AXIS UINT8_C(0x07) +#define BMA456_AN_DIS_ALL_AXIS UINT8_C(0x00) + +/**\name Interrupt status macros */ +#define BMA456_AN_ANY_MOT_INT UINT8_C(0x20) +#define BMA456_AN_NO_MOT_INT UINT8_C(0x40) +#define BMA456_AN_ERROR_INT UINT8_C(0x80) + +/******************************************************************************/ +/*! @name Structure Declarations */ +/******************************************************************************/ + +/*! + * @brief Any/No motion configuration + */ +struct bma456_an_any_no_mot_config +{ + /*! Expressed in 50 Hz samples (20 ms) */ + uint16_t duration; + + /*! Threshold value for Any-motion/No-motion detection in + * 5.11g format + */ + uint16_t threshold; + + /*! To enable selected axes */ + uint8_t axes_en; +}; + +/***************************************************************************/ + +/*! BMA456_AN User Interface function prototypes + ****************************************************************************/ + +/** + * \ingroup bma456_an + * \defgroup bma456_anApiInit Initialization + * @brief Initialize the sensor and device structure + */ + +/*! + * \ingroup bma456_anApiInit + * \page bma456_an_api_bma456_an_init bma456_an_init + * \code + * int8_t bma456_an_init(struct bma4_dev *dev); + * \endcode + * @details This API is the entry point. + * Call this API before using all other APIs. + * This API reads the chip-id of the sensor and sets the resolution. + * + * @param[in,out] dev : Structure instance of bma4_dev + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +int8_t bma456_an_init(struct bma4_dev *dev); + +/** + * \ingroup bma456_an + * \defgroup bma456_anApiConfig ConfigFile + * @brief Write binary configuration in the sensor + */ + +/*! + * \ingroup bma456_anApiConfig + * \page bma456_an_api_bma456_an_write_config_file bma456_an_write_config_file + * \code + * int8_t bma456_an_write_config_file(struct bma4_dev *dev); + * \endcode + * @details This API is used to upload the config file to enable the features of + * the sensor. + * + * @param[in] dev : Structure instance of bma4_dev. + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +int8_t bma456_an_write_config_file(struct bma4_dev *dev); + +/*! + * \ingroup bma456_anApiConfig + * \page bma456_an_api_bma456_an_get_version_config bma456_an_get_version_config + * \code + *int8_t bma456_an_get_version_config(uint16_t *config_major, uint16_t *config_minor, struct bma4_dev *dev); + * \endcode + * @details This API is used to get the config file major and minor information. + * + * @param[in] dev : Structure instance of bma4_dev. + * @param[out] config_major : Pointer to data buffer to store the config major. + * @param[out] config_minor : Pointer to data buffer to store the config minor. + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +int8_t bma456_an_get_version_config(uint16_t *config_major, uint16_t *config_minor, struct bma4_dev *dev); + +/** + * \ingroup bma456_an + * \defgroup bma456_anApiMapInt Map / Unmap Interrupt + * @brief Map / Unmap user provided interrupt to interrupt pin1 or pin2 of the sensor + */ + +/*! + * \ingroup bma456_anApiMapInt + * \page bma456_an_api_bma456_an_map_interrupt bma456_an_map_interrupt + * \code + * int8_t bma456_an_map_interrupt(uint8_t int_line, uint16_t int_map, uint8_t enable, struct bma4_dev *dev); + * \endcode + * @details This API sets/unsets the user provided interrupt to either + * interrupt pin1 or pin2 in the sensor. + * + * @param[in] int_line: Variable to select either interrupt pin1 or pin2. + * + *@verbatim + * int_line | Macros + * ------------|------------------- + * 0x00 | BMA4_INTR1_MAP + * 0x01 | BMA4_INTR2_MAP + *@endverbatim + * + * @param[in] int_map : Variable to specify the interrupts. + * @param[in] enable : Variable to specify mapping or unmapping of interrupts. + * + *@verbatim + * enable | Macros + * --------|------------------- + * 0x00 | BMA4_DISABLE + * 0x01 | BMA4_ENABLE + *@endverbatim + * + * @param[in] dev : Structure instance of bma4_dev. + * + * @note Below macros specify the interrupts. + * + * Feature Interrupts + * - BMA456_AN_ANY_MOT_INT + * - BMA456_AN_NO_MOT_INT + * - BMA456_AN_ERROR_INT + * + * Hardware Interrupts + * - BMA4_FIFO_FULL_INT + * - BMA4_FIFO_WM_INT + * - BMA4_ACCEL_DATA_RDY_INT + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +int8_t bma456_an_map_interrupt(uint8_t int_line, uint16_t int_map, uint8_t enable, struct bma4_dev *dev); + +/** + * \ingroup bma456_an + * \defgroup bma456_anApiIntS Interrupt Status + * @brief Read interrupt status of the sensor + */ + +/*! + * \ingroup bma456_anApiIntS + * \page bma456_an_api_bma456_an_read_int_status bma456_an_read_int_status + * \code + * int8_t bma456_an_read_int_status(uint16_t *int_status, struct bma4_dev *dev); + * \endcode + * @details This API reads the bma456_an interrupt status from the sensor. + * + * @param[out] int_status : Variable to store the interrupt status read from + * the sensor. + * @param[in] dev : Structure instance of bma4_dev. + * + * @note Below macros are used to check the interrupt status. + * + * Feature Interrupts + * - BMA456_AN_ANY_MOT_INT + * - BMA456_AN_NO_MOT_INT + * - BMA456_AN_ERROR_INT + * + * Hardware Interrupts + * - BMA4_FIFO_FULL_INT + * - BMA4_FIFO_WM_INT + * - BMA4_ACCEL_DATA_RDY_INT + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +int8_t bma456_an_read_int_status(uint16_t *int_status, struct bma4_dev *dev); + +/** + * \ingroup bma456_an + * \defgroup bma456_anApiRemap Remap Axes + * @brief Set / Get x, y and z axis re-mapping in the sensor + */ + +/*! + * \ingroup bma456_anApiRemap + * \page bma456_an_api_bma456_an_set_remap_axes bma456_an_set_remap_axes + * \code + * int8_t bma456_an_set_remap_axes(const struct bma4_remap *remap_data, struct bma4_dev *dev); + * \endcode + * @details This API performs x, y and z axis remapping in the sensor. + * + * @param[in] remap_data : Pointer to store axes remapping data. + * @param[in] dev : Structure instance of bma4_dev + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +int8_t bma456_an_set_remap_axes(const struct bma4_remap *remap_data, struct bma4_dev *dev); + +/*! + * \ingroup bma456_anApiRemap + * \page bma456_an_api_bma456_an_get_remap_axes bma456_an_get_remap_axes + * \code + * int8_t bma456_an_get_remap_axes(struct bma4_remap *remap_data, struct bma4_dev *dev); + * \endcode + * @details This API reads the x, y and z axis remap data from the sensor. + * + * @param[out] remap_data : Pointer to store axis remap data which is read + * from the bma456_an sensor. + * @param[in] dev : Structure instance of bma4_dev + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +int8_t bma456_an_get_remap_axes(struct bma4_remap *remap_data, struct bma4_dev *dev); + +/** + * \ingroup bma456_an + * \defgroup bma456_anApiAnyMot Any motion Feature + * @brief Functions of Any motion feature of the sensor + */ + +/*! + * \ingroup bma456_anApiAnyMot + * \page bma456_an_api_bma456_an_set_any_mot_config bma456_an_set_any_mot_config + * \code + * int8_t bma456_an_set_any_mot_config(const struct bma456_an_any_no_mot_config *any_motion, struct bma4_dev *dev); + * \endcode + * @details This API sets the configuration of any-motion feature in the sensor + * This API enables/disables the any-motion feature according to the axis set. + * + * @param[in] any_motion : Pointer to structure variable to configure + * any-motion. + * + * @verbatim + * ------------------------------------------------------------------------- + * Structure parameters | Description + * --------------------------------|---------------------------------------- + * | Defines the number of + * | consecutive data points for + * | which the threshold condition + * duration | must be respected, for interrupt + * | assertion. It is expressed in + * | 50 Hz samples (20 ms). + * | Range is 0 to 163sec. + * | Default value is 5 = 100ms. + * --------------------------------|---------------------------------------- + * | Slope threshold value for + * | Any-motion detection + * threshold | in 5.11g format. + * | Range is 0 to 1g. + * | Default value is 0xAA = 83mg. + * --------------------------------|---------------------------------------- + * | Enables the feature on a per-axis + * axis_en | basis. + * --------------------------------------------------------------------------- + * @endverbatim + * + *@verbatim + * Value | axis_en + * ---------|------------------------- + * 0x00 | BMA456_AN_DIS_ALL_AXIS + * 0x01 | BMA456_AN_X_AXIS_EN + * 0x02 | BMA456_AN_Y_AXIS_EN + * 0x04 | BMA456_AN_Z_AXIS_EN + * 0x07 | BMA456_AN_EN_ALL_AXIS + *@endverbatim + * + * @param[in] dev : Structure instance of bma4_dev + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +int8_t bma456_an_set_any_mot_config(const struct bma456_an_any_no_mot_config *any_motion, struct bma4_dev *dev); + +/*! + * \ingroup bma456_anApiNomot + * \page bma456_an_api_bma456_an_get_any_motion_config bma456_an_get_any_motion_config + * \code + * int8_t bma456_an_get_any_motion_config(struct bma456_an_anymotion_config *any_motion, struct bma4_dev *dev); + * \endcode + * @details This API gets the configuration of any-motion feature from the + * sensor. + * + * @param[out] any_motion : Pointer to structure variable to configure + * any-motion. + * + * @verbatim + * ------------------------------------------------------------------------- + * Structure parameters | Description + * --------------------------------|---------------------------------------- + * | Defines the number of + * | consecutive data points for + * | which the threshold condition + * duration | must be respected, for interrupt + * | assertion. It is expressed in + * | 50 Hz samples (20 ms). + * | Range is 0 to 163sec. + * | Default value is 5 = 100ms. + * --------------------------------|---------------------------------------- + * | Slope threshold value for + * | Any-motion detection + * threshold | in 5.11g format. + * | Range is 0 to 1g. + * | Default value is 0xAA = 83mg. + * --------------------------------|----------------------------------------- + * | Enables the feature on a per-axis + * axis_en | basis. + * --------------------------------------------------------------------------- + * @endverbatim + * + *@verbatim + * Value | axis_en + * ---------|------------------------- + * 0x00 | BMA456_AN_DIS_ALL_AXIS + * 0x01 | BMA456_AN_X_AXIS_EN + * 0x02 | BMA456_AN_Y_AXIS_EN + * 0x04 | BMA456_AN_Z_AXIS_EN + * 0x07 | BMA456_AN_EN_ALL_AXIS + *@endverbatim + * + * @param[in] dev : Structure instance of bma4_dev + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +int8_t bma456_an_get_any_mot_config(struct bma456_an_any_no_mot_config *any_motion, struct bma4_dev *dev); + +/** + * \ingroup bma456_an + * \defgroup bma456_anApiNomot No-Motion Feature + * @brief Operations of no-motion feature of the sensor + */ + +/*! + * \ingroup bma456_anApiNomot + * \page bma456_an_api_bma456_an_set_no_motion_config bma456_an_set_no_motion_config + * \code + * int8_t bma456_an_set_no_motion_config(const struct bma456_an_nomotion_config *no_motion, struct bma4_dev *dev); + * \endcode + * @details This API sets the configuration of no-motion feature in the sensor + * This API enables/disables the no-motion feature according to the axis set. + * + * @param[in] no_motion : Pointer to structure variable to configure + * no-motion. + * @verbatim + * ------------------------------------------------------------------------- + * Structure parameters | Description + * --------------------------------|---------------------------------------- + * | Defines the number of + * | consecutive data points for + * | which the threshold condition + * duration | must be respected, for interrupt + * | assertion. It is expressed in + * | 50 Hz samples (20 ms). + * | Range is 0 to 163sec. + * | Default value is 5 = 100ms. + * --------------------------------|---------------------------------------- + * | Slope threshold value for + * | No-motion detection + * threshold | in 5.11g format. + * | Range is 0 to 1g. + * | Default value is 0xAA = 83mg. + * --------------------------------|---------------------------------------- + * | Enables the feature on a per-axis + * axis_en | basis. + * --------------------------------------------------------------------------- + * @endverbatim + * + *@verbatim + * Value | axis_en + * ---------|------------------------- + * 0x00 | BMA456_AN_DIS_ALL_AXIS + * 0x01 | BMA456_AN_X_AXIS_EN + * 0x02 | BMA456_AN_Y_AXIS_EN + * 0x04 | BMA456_AN_Z_AXIS_EN + * 0x07 | BMA456_AN_EN_ALL_AXIS + *@endverbatim + * + * @param[in] dev : Structure instance of bma4_dev + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +int8_t bma456_an_set_no_mot_config(const struct bma456_an_any_no_mot_config *no_motion, struct bma4_dev *dev); + +/*! + * \ingroup bma456_anApiAnyMot + * \page bma456_an_api_bma456_an_get_no_motion_config bma456_an_get_no_motion_config + * \code + * int8_t bma456_an_get_no_motion_config(struct bma456_an_nomotion_config *no_motion, struct bma4_dev *dev); + * \endcode + * @details This API gets the configuration of no-motion feature from the + * sensor. + * + * @param[out] no_motion : Pointer to structure variable to configure + * no-motion. + * + * @verbatim + * ------------------------------------------------------------------------- + * Structure parameters | Description + * --------------------------------|---------------------------------------- + * | Defines the number of + * | consecutive data points for + * | which the threshold condition + * duration | must be respected, for interrupt + * | assertion. It is expressed in + * | 50 Hz samples (20 ms). + * | Range is 0 to 163sec. + * | Default value is 5 = 100ms. + * --------------------------------|---------------------------------------- + * | Slope threshold value for + * | No-motion detection + * threshold | in 5.11g format. + * | Range is 0 to 1g. + * | Default value is 0xAA = 83mg. + * --------------------------------|----------------------------------------- + * | Enables the feature on a per-axis + * axis_en | basis. + * --------------------------------------------------------------------------- + * @endverbatim + * + *@verbatim + * Value | axis_en + * ---------|------------------------- + * 0x00 | BMA456_AN_DIS_ALL_AXIS + * 0x01 | BMA456_AN_X_AXIS_EN + * 0x02 | BMA456_AN_Y_AXIS_EN + * 0x04 | BMA456_AN_Z_AXIS_EN + * 0x07 | BMA456_AN_EN_ALL_AXIS + *@endverbatim + * + * @param[in] dev : Structure instance of bma4_dev + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +int8_t bma456_an_get_no_mot_config(struct bma456_an_any_no_mot_config *no_motion, struct bma4_dev *dev); + +#ifdef __cplusplus +} +#endif /*End of CPP guard */ + +#endif /*End of header guard macro */ diff --git a/components/bma456/bma456_tablet.c b/components/bma456/bma456_tablet.c new file mode 100644 index 0000000..561a859 --- /dev/null +++ b/components/bma456/bma456_tablet.c @@ -0,0 +1,1514 @@ +/** +* 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. +* +* @file bma456_tablet.c +* @date 2023-07-05 +* @version V2.29.0 +* +*/ + +/*! \file bma456_tablet.c + * \brief Sensor Driver for BMA456_TABLET sensor + */ + +#include "bma456_tablet.h" + +/**\name Feature configuration file */ +const uint8_t bma456_tablet_config_file[] = { + 0xc8, 0x2e, 0x00, 0x2e, 0xc8, 0x2e, 0x00, 0x2e, 0xc8, 0x2e, 0x00, 0x2e, 0xc8, 0x2e, 0x00, 0x2e, 0x80, 0x2e, 0x9c, + 0xb0, 0xc8, 0x2e, 0x00, 0x2e, 0xc8, 0x2e, 0x00, 0x2e, 0x80, 0x2e, 0xcc, 0xb0, 0x80, 0x2e, 0x7a, 0x07, 0xb0, 0xf0, + 0x10, 0x30, 0x21, 0x2e, 0x16, 0xf0, 0x80, 0x2e, 0xf7, 0x01, 0x5b, 0x50, 0x4f, 0x52, 0x01, 0x42, 0x3b, 0x80, 0x41, + 0x30, 0x01, 0x42, 0x3c, 0x80, 0x00, 0x2e, 0x01, 0x40, 0x01, 0x42, 0x21, 0x2e, 0xff, 0xaf, 0xb8, 0x2e, 0x86, 0x52, + 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, + 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, + 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, + 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, + 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x02, 0x00, 0x04, 0x00, 0x01, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x01, 0x01, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x07, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x2e, 0x55, 0xf0, 0xc0, 0x2e, + 0x21, 0x2e, 0x55, 0xf0, 0x30, 0x50, 0x00, 0x30, 0x53, 0x56, 0x05, 0x30, 0x05, 0x2c, 0xfb, 0x7f, 0x3e, 0xbe, 0xd2, + 0xba, 0xb2, 0xb9, 0x6c, 0x0b, 0x53, 0x0e, 0xf9, 0x2f, 0x53, 0x1a, 0x01, 0x2f, 0x4d, 0x0e, 0xf5, 0x2f, 0xd2, 0x7f, + 0x04, 0x30, 0x1f, 0x2c, 0xe1, 0x7f, 0xc5, 0x01, 0xa3, 0x03, 0x72, 0x0e, 0x03, 0x2f, 0x72, 0x1a, 0x0f, 0x2f, 0x79, + 0x0f, 0x0d, 0x2f, 0xe1, 0x6f, 0x4f, 0x04, 0x5f, 0xb9, 0xb1, 0xbf, 0xfa, 0x0b, 0xd2, 0x6f, 0x96, 0x06, 0xb1, 0x25, + 0x51, 0xbf, 0xeb, 0x7f, 0x06, 0x00, 0xb2, 0x25, 0x27, 0x03, 0xdb, 0x7f, 0xcf, 0xbf, 0x3e, 0xbf, 0x01, 0xb8, 0xd2, + 0xba, 0x41, 0xba, 0xb2, 0xb9, 0x07, 0x0a, 0x6e, 0x0b, 0xc0, 0x90, 0xdf, 0x2f, 0x40, 0x91, 0xdd, 0x2f, 0xfb, 0x6f, + 0xd0, 0x5f, 0xb8, 0x2e, 0x10, 0x50, 0xfb, 0x7f, 0x21, 0x25, 0x98, 0x2e, 0xde, 0x00, 0xfb, 0x6f, 0x21, 0x25, 0xf0, + 0x5f, 0x10, 0x25, 0x80, 0x2e, 0x9a, 0x00, 0x83, 0x86, 0x01, 0x30, 0x00, 0x30, 0x94, 0x40, 0x24, 0x18, 0x06, 0x00, + 0x53, 0x0e, 0x4f, 0x02, 0xf9, 0x2f, 0xb8, 0x2e, 0x80, 0xa8, 0x03, 0x25, 0x10, 0x2f, 0x80, 0x90, 0x01, 0x2f, 0x41, + 0x0e, 0x0c, 0x2f, 0xf3, 0x3f, 0x18, 0x05, 0x05, 0x30, 0x5d, 0x07, 0x15, 0x0e, 0x03, 0x2f, 0x55, 0x1a, 0x02, 0x2f, + 0xcc, 0x0f, 0x00, 0x2f, 0x58, 0x04, 0x01, 0x25, 0xb8, 0x2e, 0xb8, 0x2e, 0x80, 0x2e, 0x18, 0x00, 0xfd, 0x2d, 0xaa, + 0x00, 0x05, 0x00, 0xaa, 0x00, 0x05, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00, 0x20, 0x00, 0x00, 0x06, 0x00, 0x09, 0x00, + 0x82, 0x00, 0x06, 0x00, 0x06, 0x00, 0x08, 0x00, 0x50, 0x00, 0x00, 0x00, 0x4c, 0x04, 0x02, 0x00, 0x03, 0x00, 0x00, + 0x00, 0x70, 0x01, 0xcd, 0x20, 0x27, 0x00, 0x40, 0x74, 0x88, 0x00, 0x63, 0x00, 0x00, 0x01, 0x6c, 0x00, 0x02, 0x01, + 0x04, 0x01, 0x57, 0x00, 0x54, 0x00, 0xaf, 0x00, 0xff, 0x00, 0xec, 0x00, 0xff, 0xb7, 0x00, 0x02, 0x00, 0xb0, 0x05, + 0x80, 0x80, 0x00, 0xc9, 0xf0, 0x00, 0x40, 0xff, 0x7f, 0x00, 0x80, 0x88, 0x00, 0x5e, 0xf0, 0x59, 0xf0, 0xc0, 0x00, + 0x39, 0xf0, 0x5a, 0x00, 0x89, 0xf0, 0x57, 0x00, 0x00, 0x20, 0x75, 0x00, 0x7a, 0x00, 0x85, 0x00, 0x52, 0xf0, 0x50, + 0x00, 0x9a, 0x01, 0x00, 0x0c, 0x89, 0x00, 0x00, 0x08, 0x00, 0xf8, 0xa0, 0x00, 0xe8, 0x03, 0x01, 0x80, 0xb8, 0x7e, + 0xe1, 0x7a, 0x51, 0x52, 0x41, 0x50, 0x60, 0x42, 0x00, 0x3f, 0x43, 0x54, 0x42, 0x42, 0x69, 0x82, 0x45, 0x54, 0x42, + 0x42, 0x42, 0x82, 0x0b, 0x31, 0x42, 0x40, 0x10, 0x08, 0x50, 0x42, 0x7e, 0x80, 0x4b, 0x42, 0x91, 0x31, 0x01, 0x42, + 0x10, 0x50, 0x03, 0x2e, 0x40, 0xf0, 0x56, 0x90, 0x08, 0x80, 0xf0, 0x7f, 0x31, 0x30, 0x1f, 0x2f, 0x03, 0x30, 0x4d, + 0x52, 0x47, 0x54, 0x04, 0x35, 0x06, 0x30, 0x49, 0x50, 0x55, 0x32, 0x1d, 0x1a, 0xe3, 0x22, 0x18, 0x1a, 0x4b, 0x58, + 0xe3, 0x22, 0x04, 0x30, 0xd5, 0x40, 0xb5, 0x0d, 0xe1, 0xbe, 0x6f, 0xbb, 0x80, 0x91, 0xa9, 0x0d, 0x01, 0x89, 0xb5, + 0x23, 0x10, 0xa1, 0xf7, 0x2f, 0xda, 0x0e, 0x04, 0x35, 0xeb, 0x2f, 0x01, 0x2e, 0x25, 0x00, 0x70, 0x1a, 0x00, 0x30, + 0x21, 0x30, 0x48, 0x22, 0x40, 0xb2, 0x06, 0x2f, 0x23, 0x2e, 0x59, 0xf0, 0x98, 0x2e, 0x95, 0x00, 0x00, 0x2e, 0x00, + 0x2e, 0xd0, 0x2e, 0xf0, 0x6f, 0x01, 0x31, 0x20, 0x26, 0x01, 0x42, 0x98, 0x2e, 0x7d, 0xb0, 0x10, 0x30, 0x21, 0x2e, + 0x59, 0xf0, 0x98, 0x2e, 0x95, 0x00, 0x33, 0x50, 0x35, 0x52, 0x98, 0x2e, 0x7c, 0xb1, 0x33, 0x50, 0x05, 0x84, 0x14, + 0x30, 0x37, 0x50, 0x63, 0x30, 0x39, 0x52, 0x94, 0x42, 0x83, 0x42, 0x98, 0x2e, 0x7c, 0xb1, 0x37, 0x50, 0x06, 0x80, + 0x71, 0x30, 0x3b, 0x54, 0x01, 0x42, 0x25, 0x2e, 0x88, 0x00, 0x00, 0x2e, 0x00, 0x2e, 0xd0, 0x2e, 0x98, 0x2e, 0x63, + 0xb0, 0x01, 0x2e, 0x5b, 0x00, 0x00, 0xb2, 0x17, 0x2f, 0x00, 0x30, 0x21, 0x2e, 0x5b, 0x00, 0x3d, 0x50, 0x98, 0x2e, + 0x23, 0xb0, 0x3d, 0x50, 0x98, 0x2e, 0x24, 0xb4, 0x01, 0x2e, 0x03, 0xf0, 0x0d, 0xbc, 0x0f, 0xb8, 0x00, 0x90, 0x08, + 0x2f, 0x4f, 0x50, 0x21, 0x2e, 0xbc, 0xf0, 0x00, 0x30, 0x11, 0x30, 0x21, 0x2e, 0x54, 0xf0, 0x23, 0x2e, 0x62, 0x00, + 0x01, 0x2e, 0x5a, 0x00, 0x00, 0xb2, 0x27, 0x2f, 0x00, 0x30, 0x21, 0x2e, 0x5a, 0x00, 0x3f, 0x50, 0x98, 0x2e, 0x23, + 0xb0, 0x3f, 0x50, 0x33, 0x52, 0x98, 0x2e, 0x8d, 0xb1, 0x3f, 0x50, 0x37, 0x52, 0x98, 0x2e, 0x8d, 0xb1, 0x3f, 0x50, + 0x98, 0x2e, 0xdd, 0xb3, 0x3f, 0x50, 0x98, 0x2e, 0x49, 0xb2, 0x01, 0x2e, 0x07, 0x01, 0x8f, 0xbc, 0x9f, 0xb8, 0x40, + 0x90, 0x4f, 0x52, 0x0a, 0x2f, 0x0e, 0xbd, 0x2f, 0xb9, 0x80, 0x90, 0x06, 0x2f, 0x0d, 0xbc, 0x0f, 0xb8, 0x00, 0x90, + 0x02, 0x2f, 0x23, 0x2e, 0xbc, 0xf0, 0x02, 0x2d, 0x23, 0x2e, 0xba, 0xf0, 0x98, 0x2e, 0x95, 0x00, 0xb0, 0x2d, 0x1a, + 0x24, 0x26, 0x00, 0x80, 0x2e, 0x44, 0x01, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0xfd, 0x2d, 0x94, 0x01, + 0xdd, 0x03, 0xc0, 0xad, 0x0b, 0x2f, 0xc0, 0xa8, 0x03, 0x2f, 0xc0, 0x90, 0x07, 0x2f, 0x80, 0xa6, 0x05, 0x2f, 0x40, + 0xa9, 0x12, 0x2f, 0x40, 0x91, 0x01, 0x2f, 0x00, 0xab, 0x0e, 0x2f, 0xc0, 0xac, 0x00, 0x30, 0x57, 0x52, 0x07, 0x2f, + 0xc0, 0xa9, 0x03, 0x2f, 0xc0, 0x91, 0x03, 0x2f, 0x80, 0xa7, 0x01, 0x2f, 0x40, 0xa1, 0x05, 0x2f, 0xc0, 0x2e, 0x17, + 0x25, 0x06, 0x25, 0xc0, 0x2e, 0xf0, 0x3f, 0x55, 0x52, 0xb8, 0x2e, 0x60, 0x50, 0x03, 0x2e, 0x18, 0x01, 0xe0, 0x7f, + 0xf1, 0x7f, 0xdb, 0x7f, 0x30, 0x30, 0x59, 0x54, 0x0a, 0x1a, 0x28, 0x2f, 0x1a, 0x25, 0x7a, 0x82, 0x00, 0x30, 0x43, + 0x30, 0x32, 0x30, 0x05, 0x30, 0x04, 0x30, 0xf6, 0x6f, 0xf2, 0x09, 0xfc, 0x13, 0xc2, 0xab, 0xb3, 0x09, 0xef, 0x23, + 0x80, 0xb3, 0xe6, 0x6f, 0xb7, 0x01, 0x00, 0x2e, 0x8b, 0x41, 0x4b, 0x42, 0x03, 0x2f, 0x46, 0x40, 0x86, 0x17, 0x81, + 0x8d, 0x46, 0x42, 0x41, 0x8b, 0x23, 0xbd, 0xb3, 0xbd, 0x03, 0x89, 0x41, 0x82, 0x07, 0x0c, 0x43, 0xa3, 0xe6, 0x2f, + 0xe1, 0x6f, 0xa2, 0x6f, 0x52, 0x42, 0x00, 0x2e, 0xb2, 0x6f, 0x52, 0x42, 0x00, 0x2e, 0xc2, 0x6f, 0x42, 0x42, 0x03, + 0xb2, 0x03, 0x2e, 0x59, 0xf0, 0xf3, 0x3d, 0x02, 0x32, 0x0b, 0x08, 0x8a, 0x0a, 0xdb, 0x6f, 0x02, 0x22, 0xa0, 0x5f, + 0x21, 0x2e, 0x59, 0xf0, 0xb8, 0x2e, 0x07, 0x2e, 0x00, 0xf0, 0x03, 0x2e, 0x00, 0xf0, 0x5d, 0x50, 0x9c, 0xbe, 0x02, + 0x40, 0x4f, 0x52, 0xf4, 0x33, 0xdc, 0xba, 0xd9, 0x0f, 0x94, 0x08, 0x06, 0x2f, 0x49, 0xaf, 0x04, 0x2f, 0x51, 0x0a, + 0x02, 0x34, 0x47, 0xa3, 0x8a, 0x0a, 0x91, 0x22, 0x3c, 0x80, 0x25, 0x2e, 0x59, 0xf0, 0x01, 0x40, 0x01, 0x42, 0xb8, + 0x2e, 0x01, 0x2e, 0xb1, 0xf0, 0x5f, 0x52, 0x01, 0x0a, 0x05, 0x2e, 0x07, 0x01, 0x2f, 0xbd, 0x21, 0x2e, 0xb1, 0xf0, + 0xaf, 0xb8, 0x40, 0x90, 0x4f, 0x50, 0x0e, 0x2f, 0x03, 0x2e, 0x07, 0x01, 0x9e, 0xbc, 0x9f, 0xb8, 0x40, 0x90, 0x08, + 0x2f, 0x03, 0x2e, 0x07, 0x01, 0x9d, 0xbc, 0x9f, 0xb8, 0x40, 0x90, 0x02, 0x2f, 0xc0, 0x2e, 0x21, 0x2e, 0xbc, 0xf0, + 0xc0, 0x2e, 0x21, 0x2e, 0xba, 0xf0, 0x70, 0x50, 0xf7, 0x7f, 0x00, 0x2e, 0x0f, 0x2e, 0xb8, 0xf0, 0xf8, 0xbf, 0xff, + 0xbb, 0xc0, 0xb3, 0x23, 0x2f, 0xb2, 0x7f, 0x94, 0x7f, 0xc6, 0x7f, 0xe5, 0x7f, 0xd3, 0x7f, 0xa1, 0x7f, 0x35, 0x30, + 0x05, 0x2e, 0x01, 0xf0, 0x2e, 0xbd, 0x2e, 0xbb, 0x61, 0x58, 0x6e, 0x05, 0x3d, 0x56, 0x63, 0x54, 0x11, 0x30, 0x27, + 0x41, 0x06, 0x41, 0xf8, 0xbf, 0xbe, 0x0b, 0xb5, 0x11, 0xd6, 0x42, 0x03, 0x89, 0x5a, 0x0e, 0xf6, 0x2f, 0x23, 0x2e, + 0x5b, 0x00, 0x4f, 0x52, 0x23, 0x2e, 0xb8, 0xf0, 0xb2, 0x6f, 0xe5, 0x6f, 0xd3, 0x6f, 0xa1, 0x6f, 0x94, 0x6f, 0xc6, + 0x6f, 0xf7, 0x6f, 0x90, 0x5f, 0xc8, 0x2e, 0x60, 0x50, 0xc3, 0x7f, 0xd4, 0x7f, 0xe7, 0x7f, 0xf6, 0x7f, 0xb2, 0x7f, + 0xa5, 0x7f, 0x36, 0x30, 0x07, 0x2e, 0x01, 0xf0, 0xbe, 0xbd, 0xbe, 0xbb, 0x65, 0x58, 0x77, 0x05, 0x3f, 0x56, 0x67, + 0x54, 0x27, 0x41, 0x06, 0x41, 0xf8, 0xbf, 0xbe, 0x0b, 0xb5, 0x11, 0xd6, 0x42, 0x03, 0x89, 0x5a, 0x0e, 0xf6, 0x2f, + 0x12, 0x30, 0x25, 0x2e, 0x5a, 0x00, 0x02, 0x31, 0x25, 0x2e, 0xb8, 0xf0, 0xd4, 0x6f, 0xc3, 0x6f, 0xe7, 0x6f, 0xb2, + 0x6f, 0xa5, 0x6f, 0xf6, 0x6f, 0xa0, 0x5f, 0xc8, 0x2e, 0x70, 0x50, 0x42, 0x8e, 0xd4, 0x7f, 0xf6, 0x7f, 0x47, 0x25, + 0x1a, 0x18, 0x69, 0x52, 0xf1, 0x00, 0x64, 0x25, 0x01, 0x30, 0x39, 0x02, 0x94, 0x41, 0x81, 0x41, 0xe2, 0x7f, 0xbe, + 0xbb, 0xbd, 0x8d, 0x02, 0xbd, 0xb5, 0x7f, 0x8e, 0xb5, 0xba, 0x0a, 0xc6, 0x7f, 0xab, 0x7f, 0x51, 0x25, 0x98, 0x2e, + 0x00, 0xb0, 0xd5, 0x6f, 0xe2, 0x6f, 0x2a, 0x18, 0x69, 0x54, 0xb2, 0x01, 0x02, 0x30, 0xc4, 0x6f, 0x7a, 0x03, 0x12, + 0x41, 0x74, 0x25, 0xd0, 0x7f, 0x52, 0xbc, 0xd3, 0x41, 0x6e, 0xba, 0xde, 0xb6, 0x20, 0x0b, 0xc7, 0x7f, 0x91, 0x7f, + 0x98, 0x2e, 0x00, 0xb0, 0xf2, 0x6f, 0xd5, 0x6f, 0xca, 0x16, 0x55, 0x18, 0xdd, 0x18, 0x95, 0x6f, 0xea, 0x18, 0x69, + 0x5a, 0x31, 0x25, 0x75, 0x01, 0x01, 0x30, 0x20, 0x25, 0x39, 0x02, 0x5e, 0xba, 0x82, 0xbc, 0x8e, 0xb6, 0x21, 0x0b, + 0x98, 0x2e, 0x00, 0xb0, 0xe2, 0x6f, 0xb5, 0x6f, 0x2a, 0x18, 0xe0, 0x7f, 0xf1, 0x7f, 0x04, 0x30, 0x69, 0x54, 0xf2, + 0x00, 0x7c, 0x02, 0x85, 0x6f, 0xd0, 0x6f, 0x0d, 0x17, 0x68, 0x18, 0xe0, 0x18, 0x90, 0x6f, 0xc4, 0x6f, 0xc5, 0x18, + 0xeb, 0x6f, 0xb2, 0x01, 0x1b, 0x43, 0x02, 0x30, 0x7a, 0x03, 0xfb, 0x6f, 0x3d, 0x8f, 0x0b, 0x43, 0x3e, 0xba, 0x12, + 0xbd, 0x52, 0xbc, 0x6e, 0xbb, 0xa2, 0x0a, 0x9e, 0xb5, 0xde, 0xb6, 0x30, 0x0b, 0xf7, 0x7f, 0x98, 0x2e, 0x00, 0xb0, + 0xf5, 0x6f, 0x31, 0x25, 0xd1, 0x6f, 0x92, 0x6f, 0xab, 0x6f, 0x50, 0x43, 0x43, 0x43, 0x90, 0x5f, 0x55, 0x56, 0x80, + 0x2e, 0xe8, 0x00, 0x10, 0x50, 0x03, 0x40, 0x19, 0x18, 0x57, 0x56, 0x19, 0x05, 0x36, 0x25, 0xf7, 0x7f, 0x4a, 0x17, + 0x54, 0x18, 0xec, 0x18, 0x09, 0x17, 0x01, 0x30, 0x0c, 0x07, 0xe2, 0x18, 0xde, 0x00, 0xf2, 0x6f, 0x97, 0x02, 0x53, + 0x58, 0xdc, 0x00, 0x91, 0x02, 0xbf, 0xb8, 0x21, 0xbd, 0x8a, 0x0a, 0xc0, 0x2e, 0x02, 0x42, 0xf0, 0x5f, 0x09, 0x86, + 0x02, 0x30, 0x12, 0x42, 0x43, 0x0e, 0xfc, 0x2f, 0x37, 0x80, 0x13, 0x30, 0x13, 0x42, 0x12, 0x42, 0x12, 0x42, 0x12, + 0x42, 0x02, 0x42, 0x03, 0x80, 0x41, 0x84, 0x11, 0x42, 0x02, 0x42, 0xb8, 0x2e, 0x46, 0x84, 0x80, 0x50, 0xa3, 0x40, + 0x83, 0x88, 0x82, 0x40, 0x04, 0x41, 0xc3, 0x7f, 0x42, 0x8a, 0x06, 0x41, 0x6d, 0xbb, 0xf6, 0x7f, 0x80, 0xb3, 0xd5, + 0x7f, 0xe0, 0x7f, 0x59, 0x2f, 0x31, 0x25, 0x55, 0x40, 0x41, 0x91, 0xb1, 0x7f, 0x0f, 0x2f, 0x01, 0x30, 0xc1, 0x42, + 0x00, 0x2e, 0xd2, 0x6f, 0x13, 0x40, 0x93, 0x42, 0x00, 0x2e, 0x13, 0x40, 0x93, 0x42, 0x00, 0x2e, 0x00, 0x40, 0x80, + 0x42, 0xbd, 0x80, 0xc0, 0x2e, 0x01, 0x42, 0x80, 0x5f, 0xc7, 0x86, 0x01, 0x30, 0xc5, 0x40, 0xfb, 0x86, 0x45, 0x41, + 0x04, 0x41, 0x43, 0xbe, 0xd5, 0xbe, 0x43, 0xba, 0xd5, 0xba, 0x84, 0x7f, 0x95, 0x7f, 0xa1, 0x7f, 0x14, 0x30, 0x61, + 0x15, 0xf5, 0x09, 0x15, 0x40, 0xc0, 0xb3, 0x0b, 0x2f, 0xc6, 0x40, 0xae, 0x05, 0x07, 0x30, 0xfe, 0x05, 0x80, 0xa9, + 0xb7, 0x23, 0x97, 0x6f, 0x77, 0x0f, 0xa6, 0x6f, 0xe6, 0x23, 0xf6, 0x6f, 0xa7, 0x7f, 0x80, 0x90, 0x00, 0x2f, 0xc5, + 0x42, 0x41, 0x82, 0xc1, 0x86, 0x43, 0xa2, 0xe7, 0x2f, 0xa1, 0x6f, 0xb0, 0x6f, 0x0a, 0x1a, 0x02, 0x2f, 0x01, 0x30, + 0x1b, 0x2c, 0x01, 0x42, 0x01, 0x40, 0x4c, 0x28, 0x82, 0x6f, 0x01, 0x42, 0x4a, 0x0e, 0x13, 0x2f, 0xc0, 0x6f, 0x00, + 0xb2, 0x03, 0x2f, 0x3f, 0x80, 0x20, 0x14, 0x21, 0x2e, 0x5e, 0xf0, 0xe1, 0x6f, 0xd0, 0x6f, 0x52, 0x40, 0x12, 0x42, + 0x00, 0x2e, 0x52, 0x40, 0x12, 0x42, 0x00, 0x2e, 0x41, 0x40, 0x03, 0x2c, 0x01, 0x42, 0x10, 0x30, 0x40, 0x42, 0x80, + 0x5f, 0xb8, 0x2e, 0x57, 0x50, 0x50, 0x1a, 0x04, 0x2f, 0x55, 0x56, 0x41, 0x80, 0x4b, 0x1a, 0x81, 0x84, 0x41, 0x22, + 0x00, 0x30, 0xc0, 0x2e, 0x82, 0x04, 0x0a, 0x28, 0xff, 0x80, 0x14, 0x30, 0x20, 0x14, 0x0a, 0x18, 0x08, 0x17, 0x30, + 0x00, 0xc0, 0xb2, 0x3c, 0x03, 0x0b, 0x2f, 0xd0, 0xa0, 0x03, 0x2f, 0xf0, 0x80, 0x20, 0x10, 0x07, 0x2c, 0x08, 0x17, + 0x05, 0x31, 0x6b, 0x05, 0x65, 0x15, 0x03, 0x12, 0x23, 0x11, 0x05, 0x0a, 0xc8, 0x16, 0x23, 0x1a, 0x04, 0x2f, 0x4a, + 0x0c, 0x55, 0x54, 0xc0, 0x2e, 0x9f, 0xb8, 0x0a, 0x00, 0xb8, 0x2e, 0x40, 0x50, 0x03, 0x40, 0xc3, 0x82, 0x05, 0x84, + 0xf1, 0x7f, 0xeb, 0x7f, 0x00, 0x30, 0xd1, 0x40, 0x40, 0xa8, 0x01, 0x04, 0x08, 0x22, 0x80, 0x42, 0xbc, 0x84, 0x87, + 0x80, 0x82, 0x40, 0xd0, 0x7f, 0xc3, 0x7f, 0x98, 0x2e, 0xfa, 0xb1, 0xd1, 0x6f, 0x7e, 0x84, 0x40, 0x42, 0x00, 0x30, + 0xc3, 0x6f, 0xf1, 0x6f, 0x59, 0x0e, 0xeb, 0x2f, 0xfd, 0x82, 0xf2, 0x7f, 0x98, 0x2e, 0xd3, 0x00, 0xf1, 0x6f, 0x7c, + 0x82, 0xeb, 0x6f, 0xc0, 0x2e, 0x40, 0x42, 0xc0, 0x5f, 0x05, 0x2e, 0x14, 0x01, 0x2f, 0xbd, 0x30, 0x50, 0x2f, 0xb9, + 0x80, 0xb2, 0xf0, 0x7f, 0xeb, 0x7f, 0x3e, 0x2f, 0x01, 0x2e, 0x5d, 0x00, 0x00, 0xb2, 0x6b, 0x50, 0x04, 0x2f, 0x98, + 0x2e, 0x61, 0xb3, 0x00, 0x30, 0x21, 0x2e, 0x5d, 0x00, 0xf0, 0x6f, 0x6d, 0x54, 0x14, 0x40, 0x11, 0x40, 0x03, 0x40, + 0x6f, 0x5a, 0x95, 0x42, 0x54, 0x43, 0x51, 0x43, 0x7e, 0x83, 0x6d, 0x50, 0xd2, 0x7f, 0xf1, 0x7f, 0x43, 0x43, 0x98, + 0x2e, 0x24, 0xb2, 0x05, 0x2e, 0x5c, 0x00, 0x6b, 0x52, 0x6d, 0x56, 0x98, 0x2e, 0x9c, 0xb2, 0xf1, 0x6f, 0xd2, 0x6f, + 0x53, 0x40, 0x93, 0x42, 0x73, 0x30, 0x54, 0x40, 0x94, 0x42, 0x03, 0x08, 0x41, 0x40, 0x81, 0x42, 0xf0, 0x7f, 0x00, + 0x2e, 0x05, 0x2e, 0x5e, 0x00, 0x10, 0x1a, 0x09, 0x2f, 0x71, 0x54, 0x8c, 0x84, 0x21, 0x2e, 0x52, 0xf0, 0xd2, 0x7f, + 0x98, 0x2e, 0x95, 0x00, 0xd0, 0x6f, 0x22, 0x30, 0x02, 0x42, 0x00, 0x2e, 0xf0, 0x6f, 0x21, 0x2e, 0x5e, 0x00, 0x08, + 0x2d, 0x00, 0x30, 0x21, 0x2e, 0x52, 0xf0, 0x98, 0x2e, 0x95, 0x00, 0x10, 0x30, 0x21, 0x2e, 0x5d, 0x00, 0xeb, 0x6f, + 0xd0, 0x5f, 0xb8, 0x2e, 0x90, 0x51, 0x94, 0x40, 0xc6, 0x80, 0x95, 0x40, 0xe0, 0x7f, 0xfb, 0x7f, 0xc1, 0x7f, 0x42, + 0x82, 0x2b, 0x40, 0x9b, 0x7f, 0xb1, 0x7f, 0xa3, 0x7f, 0xce, 0xbf, 0xcb, 0x40, 0x63, 0x40, 0x82, 0x40, 0x71, 0x7f, + 0x28, 0xbd, 0x31, 0x30, 0xd9, 0x08, 0xff, 0xbb, 0x28, 0xb9, 0xd7, 0x7f, 0x62, 0x7f, 0xcc, 0xbf, 0x45, 0xbd, 0x58, + 0xbb, 0xfe, 0xbb, 0x73, 0x52, 0x2b, 0xb9, 0x53, 0x7f, 0x4f, 0x00, 0xd8, 0xbe, 0x80, 0xb2, 0x13, 0x30, 0x62, 0xbf, + 0x80, 0x7f, 0x4a, 0xbe, 0xd8, 0xba, 0x9a, 0x22, 0x41, 0x40, 0x4e, 0xba, 0x00, 0x40, 0xd2, 0xbe, 0x91, 0xbc, 0xf2, + 0x7e, 0x86, 0x04, 0x01, 0x7f, 0x15, 0x7f, 0x46, 0x7f, 0x24, 0x7f, 0x3b, 0x7f, 0x98, 0x2e, 0x06, 0xb2, 0x48, 0x16, + 0x13, 0x30, 0x4b, 0x08, 0x01, 0x00, 0x01, 0xb4, 0x91, 0x6f, 0x08, 0x0e, 0x1a, 0x2f, 0x81, 0x6f, 0xe0, 0x6f, 0x42, + 0x40, 0x00, 0x40, 0x01, 0x6f, 0xe0, 0x7f, 0x98, 0x2e, 0x06, 0xb2, 0x48, 0x16, 0x13, 0x30, 0x4b, 0x08, 0x01, 0x00, + 0x01, 0xb4, 0x41, 0x6f, 0x01, 0x28, 0xe1, 0x6f, 0x88, 0x0e, 0x0e, 0x2f, 0x30, 0x6f, 0x01, 0x82, 0x20, 0x30, 0x41, + 0x40, 0x40, 0xa0, 0x01, 0x30, 0x01, 0x22, 0x07, 0x2c, 0x50, 0x7f, 0x31, 0x6f, 0x30, 0x30, 0x41, 0x40, 0x40, 0xac, + 0x18, 0x22, 0x50, 0x7f, 0x00, 0x30, 0xd4, 0x6f, 0x71, 0x6f, 0x00, 0xb3, 0x42, 0x40, 0x04, 0x30, 0x0e, 0x2f, 0xa4, + 0x6f, 0x07, 0x8b, 0x75, 0x58, 0x45, 0x41, 0x6c, 0x0f, 0x34, 0x6f, 0x02, 0x2f, 0x00, 0x2e, 0x06, 0x2c, 0x22, 0xba, + 0x02, 0x89, 0x00, 0x2e, 0x04, 0x41, 0x00, 0xad, 0x03, 0x23, 0x42, 0xbe, 0x55, 0x6f, 0x2c, 0x0b, 0x54, 0x1a, 0xd8, + 0x22, 0x14, 0x1a, 0x3a, 0x2f, 0x20, 0x6f, 0x00, 0xa4, 0x00, 0x30, 0x36, 0x2f, 0x21, 0x6f, 0xd3, 0x7f, 0xe4, 0x7f, + 0x43, 0x90, 0x00, 0x30, 0x12, 0x2f, 0xc3, 0x6f, 0xc4, 0x86, 0xfe, 0x80, 0xc2, 0x40, 0x00, 0x40, 0x81, 0x84, 0xe4, + 0x6f, 0xc2, 0x42, 0x04, 0x1a, 0x01, 0x2f, 0x00, 0x30, 0xc0, 0x42, 0x00, 0x2e, 0xf0, 0x6e, 0xc3, 0x40, 0x58, 0x0e, + 0x13, 0x30, 0x00, 0x30, 0x18, 0x22, 0x00, 0x90, 0xa2, 0x6f, 0x02, 0x2f, 0x13, 0x6f, 0x98, 0x2e, 0xa5, 0xb3, 0x00, + 0x90, 0xc1, 0x6f, 0x03, 0x30, 0x0f, 0x2f, 0x43, 0x80, 0x90, 0x7f, 0x1a, 0x25, 0x00, 0x40, 0xa2, 0x6f, 0xb2, 0x7e, + 0x6b, 0x82, 0x62, 0x6f, 0xc2, 0x7e, 0xd3, 0x7e, 0xe0, 0x7e, 0x98, 0x2e, 0x6c, 0xb3, 0x93, 0x6f, 0x00, 0x2e, 0xc0, + 0x42, 0x00, 0x2e, 0x71, 0x6f, 0xe4, 0x6f, 0xd3, 0x6f, 0xb2, 0x6f, 0x01, 0x90, 0x84, 0x42, 0x03, 0x2f, 0xc3, 0x6f, + 0xc1, 0x80, 0x03, 0x30, 0x04, 0x40, 0xfb, 0x6f, 0x44, 0x42, 0xbf, 0xbd, 0xc0, 0x2e, 0x23, 0x0a, 0x70, 0x5e, 0x01, + 0x80, 0x01, 0x30, 0x11, 0x42, 0x11, 0x42, 0x11, 0x42, 0x01, 0x42, 0x3c, 0x80, 0x31, 0x30, 0xc0, 0x2e, 0x01, 0x42, + 0x00, 0x2e, 0x50, 0x50, 0x40, 0x40, 0x42, 0x84, 0x00, 0x40, 0xe0, 0x7f, 0x02, 0x86, 0xdb, 0x7f, 0xf1, 0x7f, 0x00, + 0x2e, 0xa0, 0x40, 0x8b, 0x40, 0xc2, 0x40, 0xcb, 0x7f, 0xb0, 0x7f, 0xb3, 0x30, 0x12, 0x25, 0x98, 0x2e, 0x06, 0xb2, + 0xc1, 0x6f, 0x63, 0x30, 0x20, 0x25, 0x98, 0x2e, 0x06, 0xb2, 0xe1, 0x6f, 0xe0, 0x7f, 0xb3, 0x30, 0x52, 0x40, 0xc1, + 0x7f, 0x12, 0x25, 0x98, 0x2e, 0x06, 0xb2, 0xc2, 0x6f, 0xc0, 0x7f, 0xb3, 0x30, 0x82, 0x40, 0x12, 0x25, 0x98, 0x2e, + 0x06, 0xb2, 0xc2, 0x6f, 0x90, 0x28, 0xb0, 0x6f, 0x50, 0x28, 0xe3, 0x6f, 0x99, 0x0f, 0x07, 0x2f, 0xf1, 0x6f, 0x18, + 0x28, 0x43, 0x82, 0x82, 0x0f, 0x42, 0x40, 0x00, 0x30, 0x02, 0x2c, 0x10, 0x22, 0x10, 0x30, 0xdb, 0x6f, 0xb0, 0x5f, + 0xb8, 0x2e, 0x41, 0xb2, 0x01, 0x2f, 0x00, 0x2e, 0x02, 0x2d, 0x20, 0x2c, 0x00, 0x30, 0x43, 0xb2, 0x00, 0x30, 0x01, + 0x2f, 0x42, 0x90, 0x2b, 0x2f, 0x88, 0x8a, 0x34, 0x30, 0x61, 0x04, 0x45, 0x41, 0xd9, 0x12, 0x40, 0xa9, 0x05, 0x05, + 0x6c, 0x22, 0x4b, 0x0f, 0x20, 0x2f, 0x89, 0x82, 0x00, 0x2e, 0x41, 0x40, 0x40, 0xa8, 0x01, 0x05, 0x4c, 0x22, 0x4b, + 0x0f, 0x18, 0x2f, 0x8a, 0x82, 0x00, 0x2e, 0x41, 0x40, 0x40, 0xa8, 0x01, 0x05, 0x4c, 0x22, 0x4b, 0x0f, 0x10, 0x2f, + 0x85, 0x82, 0x77, 0x56, 0x41, 0x40, 0x4b, 0x0f, 0x09, 0x2f, 0x86, 0x82, 0x77, 0x56, 0x41, 0x40, 0x4b, 0x0f, 0x04, + 0x2f, 0x87, 0x86, 0x77, 0x54, 0xc3, 0x40, 0xda, 0x0e, 0x02, 0x2f, 0x10, 0x30, 0xb8, 0x2e, 0x10, 0x30, 0xb8, 0x2e, + 0x05, 0x2e, 0x88, 0x00, 0x81, 0x82, 0x40, 0x50, 0x41, 0x40, 0x93, 0xbd, 0xbf, 0xb9, 0xfb, 0x7f, 0xc0, 0xb2, 0x0b, + 0x30, 0x36, 0x2f, 0x07, 0x2e, 0x5f, 0x00, 0xc0, 0x90, 0x04, 0x2f, 0xc1, 0x86, 0x27, 0x2e, 0x5f, 0x00, 0x37, 0x2e, + 0x60, 0x00, 0x82, 0x86, 0x82, 0x40, 0x94, 0xbc, 0xc3, 0x40, 0x94, 0xb8, 0x21, 0xbd, 0xb4, 0xbd, 0x21, 0xb9, 0xb4, + 0xb9, 0xc1, 0x7f, 0xe3, 0x7f, 0xd2, 0x7f, 0x10, 0x25, 0x98, 0x2e, 0xd3, 0x00, 0xc2, 0x6f, 0xd1, 0x6f, 0x8a, 0x28, + 0x42, 0x0f, 0x0d, 0x2f, 0xc1, 0x0e, 0x05, 0x2e, 0x60, 0x00, 0x13, 0x30, 0x13, 0x28, 0x04, 0x2f, 0x80, 0xa6, 0x08, + 0x2f, 0x21, 0x2e, 0x60, 0x00, 0x06, 0x2d, 0x21, 0x2e, 0x60, 0x00, 0x03, 0x2d, 0x00, 0x30, 0x21, 0x2e, 0x60, 0x00, + 0x03, 0x2e, 0x60, 0x00, 0xe0, 0x6f, 0xc8, 0x0e, 0x40, 0x30, 0x04, 0x2f, 0x21, 0x2e, 0x5e, 0xf0, 0x02, 0x2d, 0x37, + 0x2e, 0x5f, 0x00, 0xfb, 0x6f, 0xc0, 0x5f, 0xb8, 0x2e, 0x03, 0x2e, 0x07, 0x01, 0x72, 0x30, 0x30, 0x50, 0xca, 0x08, + 0xc0, 0x90, 0xfb, 0x7f, 0x0b, 0x2f, 0x01, 0x30, 0x23, 0x2e, 0x54, 0xf0, 0xe0, 0x7f, 0xd3, 0x7f, 0x98, 0x2e, 0x95, + 0x00, 0x10, 0x30, 0x21, 0x2e, 0x62, 0x00, 0xe0, 0x6f, 0xd3, 0x6f, 0x03, 0x2e, 0x62, 0x00, 0x40, 0x90, 0x79, 0x52, + 0x15, 0x2f, 0x05, 0x2e, 0x61, 0x00, 0x8c, 0x88, 0x00, 0x2e, 0x03, 0x43, 0x30, 0x25, 0x98, 0x2e, 0x97, 0xb4, 0x00, + 0xb2, 0x05, 0x2f, 0x21, 0x2e, 0x54, 0xf0, 0xe0, 0x7f, 0x98, 0x2e, 0x95, 0x00, 0xe0, 0x6f, 0x00, 0xa6, 0x10, 0x30, + 0x08, 0x2f, 0x21, 0x2e, 0x5e, 0xf0, 0x06, 0x2d, 0x03, 0x30, 0x79, 0x50, 0x98, 0x2e, 0x5c, 0xb4, 0x27, 0x2e, 0x62, + 0x00, 0xfb, 0x6f, 0xd0, 0x5f, 0xb8, 0x2e, 0x0c, 0x82, 0x02, 0x30, 0x12, 0x42, 0x41, 0x0e, 0xfc, 0x2f, 0x35, 0x80, + 0x7b, 0x52, 0x11, 0x42, 0x00, 0x2e, 0x7d, 0x52, 0x01, 0x42, 0xb8, 0x2e, 0x07, 0x88, 0x47, 0x8e, 0x06, 0x41, 0x3c, + 0x8b, 0x32, 0x1a, 0x42, 0x41, 0xc7, 0x41, 0x16, 0x2f, 0x80, 0x91, 0x23, 0x2f, 0x57, 0x0f, 0x16, 0x30, 0x0c, 0x2f, + 0x06, 0x80, 0x00, 0x2e, 0x00, 0x40, 0x00, 0xb2, 0x04, 0x2f, 0x46, 0x82, 0x00, 0x2e, 0x41, 0x40, 0xd1, 0x0f, 0x02, + 0x2f, 0x06, 0x30, 0x06, 0x43, 0x46, 0x43, 0x80, 0xb3, 0x11, 0x2f, 0x03, 0x43, 0x47, 0x43, 0xb8, 0x2e, 0xd7, 0x0e, + 0x0c, 0x2f, 0x44, 0x82, 0x17, 0x04, 0x41, 0x40, 0x41, 0x0f, 0x07, 0x2f, 0x03, 0x43, 0x42, 0x83, 0x47, 0x43, 0x00, + 0x2e, 0x43, 0x40, 0xc1, 0x86, 0x43, 0x42, 0xb8, 0x2e, 0xb8, 0x2e, 0x89, 0x88, 0xc0, 0x50, 0x39, 0x8d, 0x88, 0x81, + 0xe2, 0x7f, 0x02, 0x30, 0x05, 0x40, 0xf2, 0x7f, 0x41, 0xab, 0x22, 0x30, 0x95, 0x22, 0x86, 0x41, 0x7f, 0x5e, 0x9a, + 0x00, 0x04, 0x41, 0x37, 0x18, 0x66, 0x01, 0x81, 0x56, 0xeb, 0x00, 0xc1, 0x7f, 0xb3, 0x7f, 0xd5, 0x7f, 0x48, 0x82, + 0x39, 0x80, 0x82, 0x40, 0xa0, 0x7f, 0x91, 0x7f, 0x8b, 0x7f, 0x06, 0x30, 0x53, 0x5a, 0x83, 0x58, 0x53, 0x56, 0x98, + 0x2e, 0xf3, 0xb0, 0x91, 0x6f, 0x7b, 0x82, 0xc6, 0x6f, 0x42, 0x40, 0x81, 0x84, 0x42, 0x42, 0x43, 0x82, 0x83, 0x8b, + 0x42, 0x40, 0x86, 0x89, 0x7b, 0x82, 0x84, 0x87, 0x71, 0x7f, 0x80, 0xb2, 0x95, 0x7f, 0x64, 0x7f, 0x50, 0x7f, 0x02, + 0x2f, 0xc5, 0x40, 0x41, 0x8b, 0xc5, 0x42, 0x87, 0x89, 0x67, 0x40, 0x07, 0x0f, 0x85, 0x8b, 0x41, 0x7f, 0x82, 0x8d, + 0x47, 0x40, 0x3d, 0x2f, 0x81, 0x41, 0x01, 0x0e, 0xe1, 0x6f, 0x2e, 0x2f, 0x47, 0x8c, 0x90, 0x6f, 0x86, 0x41, 0x07, + 0x40, 0xfe, 0x0e, 0x02, 0x2f, 0x04, 0x41, 0x00, 0xb3, 0x22, 0x2f, 0x45, 0x82, 0x04, 0x30, 0x41, 0x40, 0x71, 0x00, + 0xf9, 0x0e, 0x37, 0x2f, 0x46, 0x41, 0x80, 0xa7, 0x01, 0x30, 0x04, 0x30, 0x0e, 0x2f, 0xe4, 0x6f, 0x01, 0x89, 0x00, + 0x2e, 0x04, 0x41, 0x74, 0x0f, 0x04, 0x30, 0x07, 0x2f, 0x80, 0x90, 0x00, 0x2f, 0xc1, 0x42, 0x03, 0x86, 0x81, 0x84, + 0xc2, 0x42, 0x01, 0x42, 0x14, 0x30, 0x42, 0x85, 0x41, 0x43, 0xa1, 0x42, 0x00, 0x2e, 0x82, 0x40, 0x80, 0x90, 0x1c, + 0x2f, 0x01, 0x42, 0x1b, 0x2d, 0x06, 0x42, 0x19, 0x2c, 0x04, 0x30, 0xb2, 0x6f, 0xba, 0x04, 0x02, 0x1e, 0x80, 0x43, + 0x12, 0x30, 0xc0, 0x6f, 0x23, 0x30, 0x98, 0x2e, 0x68, 0xb4, 0x0e, 0x2c, 0x04, 0x30, 0xb2, 0x6f, 0xc0, 0x6f, 0xba, + 0x00, 0x51, 0x6f, 0x01, 0x86, 0x4a, 0x1c, 0xc1, 0x42, 0x22, 0x30, 0xe1, 0x6f, 0x13, 0x30, 0x98, 0x2e, 0x68, 0xb4, + 0x04, 0x30, 0x52, 0x6f, 0x85, 0x52, 0x40, 0x6f, 0xc4, 0x7f, 0x98, 0x2e, 0x62, 0xb1, 0x41, 0x6f, 0x70, 0x6f, 0x42, + 0x40, 0x87, 0x52, 0x98, 0x2e, 0x62, 0xb1, 0x41, 0x6f, 0x70, 0x6f, 0x42, 0x40, 0x01, 0x40, 0xd3, 0x6f, 0xd3, 0x00, + 0xcb, 0x1e, 0x87, 0x52, 0x13, 0x42, 0xb0, 0x7f, 0x98, 0x2e, 0x62, 0xb1, 0xb0, 0x6f, 0x3e, 0x84, 0xd1, 0x6f, 0x82, + 0x40, 0x03, 0x40, 0x51, 0x04, 0x59, 0x1c, 0x01, 0x42, 0x02, 0x82, 0xa0, 0x6f, 0x42, 0x40, 0x03, 0x40, 0xd3, 0x0f, + 0x00, 0x30, 0x14, 0x30, 0x60, 0x22, 0xc5, 0x6f, 0x40, 0x91, 0x01, 0x2f, 0x53, 0x0e, 0x26, 0x2f, 0xe5, 0x6f, 0x48, + 0x85, 0x00, 0x2e, 0x83, 0x40, 0x59, 0x0f, 0x20, 0x2f, 0x62, 0x6f, 0x4b, 0x8f, 0x85, 0x40, 0xc7, 0x41, 0x7f, 0x8d, + 0x6f, 0x0f, 0xa6, 0x15, 0x17, 0x30, 0x04, 0x30, 0x0f, 0x2f, 0xe0, 0x6f, 0x0c, 0x80, 0x00, 0x2e, 0x07, 0x40, 0x3e, + 0x08, 0x00, 0xb2, 0x00, 0x30, 0x06, 0x2f, 0x59, 0x1a, 0x04, 0x2f, 0xfd, 0x12, 0xc0, 0x90, 0x13, 0x30, 0x4b, 0x22, + 0x06, 0x25, 0x71, 0x25, 0xc0, 0xb3, 0x04, 0x2f, 0xa4, 0x42, 0xa4, 0x42, 0x83, 0x82, 0x84, 0x42, 0x44, 0x42, 0x00, + 0x2e, 0x8b, 0x6f, 0x40, 0x5f, 0xb8, 0x2e, 0x00, 0x2e, 0x10, 0x24, 0x90, 0x07, 0x11, 0x24, 0x00, 0x0c, 0x12, 0x24, + 0x80, 0x2e, 0x13, 0x24, 0x18, 0x00, 0x12, 0x42, 0x13, 0x42, 0x41, 0x1a, 0xfb, 0x2f, 0x10, 0x24, 0x50, 0x39, 0x11, + 0x24, 0x21, 0x2e, 0x21, 0x2e, 0x10, 0x00, 0x23, 0x2e, 0x11, 0x00, 0x80, 0x2e, 0x10, 0x00 +}; + +/***************************************************************************/ +/*! Static Function Declarations */ +/***************************************************************************/ + +/*! + * @brief This API update the settings of tap into write array. + * + * @param[in] setting : Pointer to structure variable which stores the + * settings parameter1 to parameter12. + * @param[in] index : Value for array traversing. + * @param[out] feature_config : Pointer to store the settings + * + * @return none + */ +static void update_tap_parameter(const struct bma456_tablet_tap_settings *setting, + uint16_t index, + uint8_t *feature_config); + +/*! + * @brief This API copy the settings of tap into the + * structure of bma456_tablet_tap_settings, which is read from sensor. + * + * @param[out] setting : Pointer to structure variable which stores the + * settings parameter1 to parameter12 read from sensor. + * @param[in] data_p : Pointer of array which stores the parameters. + * + * @return none + */ +static void extract_tap_parameter(struct bma456_tablet_tap_settings *setting, const uint16_t *data_p); + +/*! + * @brief This API enables the features of sensor. + * + * @param[in] feature : Variable to specify the features which are to be set in + * the sensor. + * @param[in] len : Length to read and write + * @param[in] feature_config : Array address which stores the feature + * configuration data + * @param[in] dev : Structure instance of bma4_dev. + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +static int8_t feature_enable(uint8_t feature, uint8_t len, uint8_t *feature_config, struct bma4_dev *dev); + +/*! + * @brief This API disables the features of sensor. + * + * @param[in] feature : Variable to specify the features which are to be unset + * in the sensor. + * @param[in] len : Length to read and write + * @param[in] feature_config : Array address which stores the feature + * configuration data + * @param[in] dev : Structure instance of bma4_dev. + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +static int8_t feature_disable(uint8_t feature, uint8_t len, uint8_t *feature_config, struct bma4_dev *dev); + +/***************************************************************************/ +/*! Global 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 and sets the resolution. + */ +int8_t bma456_tablet_init(struct bma4_dev *dev) +{ + int8_t rslt; + + /* Structure to define the default values for axes re-mapping */ + struct bma4_axes_remap axes_remap = { + .x_axis = BMA4_MAP_X_AXIS, .x_axis_sign = BMA4_MAP_POSITIVE, .y_axis = BMA4_MAP_Y_AXIS, + .y_axis_sign = BMA4_MAP_POSITIVE, .z_axis = BMA4_MAP_Z_AXIS, .z_axis_sign = BMA4_MAP_POSITIVE + }; + + if (dev != NULL) + { + rslt = bma4_init(dev); + + if (rslt == BMA4_OK) + { + if (dev->chip_id == BMA456_TABLET_CHIP_ID) + { + /* Resolution of BMA456_TABLET sensor is 12 bit */ + dev->resolution = BMA4_12_BIT_RESOLUTION; + + dev->feature_len = BMA456_TABLET_FEATURE_SIZE; + + dev->config_size = sizeof(bma456_tablet_config_file); + + /* Set the default values for axis + * re-mapping in the device structure + */ + dev->remap = axes_remap; + } + else + { + rslt = BMA4_E_INVALID_SENSOR; + } + } + } + else + { + rslt = BMA4_E_NULL_PTR; + } + + return rslt; +} + +/*! + * @brief This API is used to upload the configuration file to enable the + * features of the sensor. + */ +int8_t bma456_tablet_write_config_file(struct bma4_dev *dev) +{ + int8_t rslt = BMA4_OK; + + if (dev != NULL) + { + if (dev->chip_id == BMA456_TABLET_CHIP_ID) + { + /* Configuration stream read/write length boundary + * check + */ + if ((dev->read_write_len >= BMA456_TABLET_RD_WR_MIN_LEN) && + (dev->read_write_len <= BMA456_TABLET_RD_WR_MAX_LEN)) + { + /* Even or odd check */ + if ((dev->read_write_len % 2) != 0) + { + dev->read_write_len = dev->read_write_len - 1; + } + + /* Assign stream data */ + dev->config_file_ptr = bma456_tablet_config_file; + rslt = bma4_write_config_file(dev); + } + else + { + rslt = BMA4_E_RD_WR_LENGTH_INVALID; + } + } + else + { + rslt = BMA4_E_INVALID_SENSOR; + } + } + else + { + rslt = BMA4_E_NULL_PTR; + } + + return rslt; +} + +/*! + * @brief This API is used to get the config file major and minor information. + */ +int8_t bma456_tablet_get_version_config(uint16_t *config_major, uint16_t *config_minor, struct bma4_dev *dev) +{ + /* Initialize configuration file */ + uint8_t feature_config[BMA456_TABLET_FEATURE_SIZE] = { 0 }; + + /* Update index to config file version */ + uint8_t index = BMA456_TABLET_CONFIG_ID_OFFSET; + + /* Variable to define LSB */ + uint8_t lsb = 0; + + /* Variable to define MSB */ + uint8_t msb = 0; + + /* Variable to define LSB and MSB */ + uint16_t lsb_msb = 0; + + /* Result of api are returned to this variable */ + int8_t rslt = BMA4_OK; + + if ((config_major != NULL) && (config_minor != NULL)) + { + rslt = bma4_set_advance_power_save(BMA4_DISABLE, dev); + + if (rslt == BMA4_OK) + { + /* Wait for sensor time synchronization. Refer the data-sheet for + * more information + */ + dev->delay_us(450, dev->intf_ptr); + + /* Get config file identification from the sensor */ + rslt = bma4_read_regs(BMA4_FEATURE_CONFIG_ADDR, feature_config, BMA456_TABLET_FEATURE_SIZE, dev); + + if (rslt == BMA4_OK) + { + /* Get word to calculate config file identification */ + lsb = feature_config[index++]; + msb = feature_config[index++]; + + lsb_msb = (uint16_t)(msb << 8 | lsb); + + /* Get major and minor version */ + *config_major = BMA4_GET_BITSLICE(lsb_msb, BMA4_CONFIG_MAJOR); + *config_minor = BMA4_GET_BITS_POS_0(lsb, BMA4_CONFIG_MINOR); + } + } + } + else + { + rslt = BMA4_E_NULL_PTR; + } + + return rslt; +} + +/*! + * @brief This API is used to get the configuration id of the sensor. + */ +int8_t bma456_tablet_get_config_id(uint16_t *config_id, struct bma4_dev *dev) +{ + uint8_t feature_config[BMA456_TABLET_FEATURE_SIZE] = { 0 }; + uint16_t index = BMA456_TABLET_CONFIG_ID_OFFSET; + int8_t rslt = BMA4_OK; + uint16_t config_id_lsb = 0; + uint16_t config_id_msb = 0; + + if ((dev != NULL) && (config_id != NULL)) + { + if (dev->chip_id == BMA456_TABLET_CHIP_ID) + { + rslt = bma4_read_regs(BMA4_FEATURE_CONFIG_ADDR, feature_config, BMA456_TABLET_FEATURE_SIZE, dev); + if (rslt == BMA4_OK) + { + config_id_lsb = (uint16_t)feature_config[index]; + config_id_msb = ((uint16_t)feature_config[index + 1]) << 8; + *config_id = config_id_lsb | config_id_msb; + } + } + else + { + rslt = BMA4_E_INVALID_SENSOR; + } + } + else + { + rslt = BMA4_E_NULL_PTR; + } + + return rslt; +} + +/*! + * @brief This API sets/un-sets the user provided interrupt to either interrupt + * pin1 or pin2 in the sensor. + */ +int8_t bma456_tablet_map_interrupt(uint8_t int_line, uint16_t int_map, uint8_t enable, struct bma4_dev *dev) +{ + int8_t rslt = BMA4_OK; + + if (dev != NULL) + { + if (dev->chip_id == BMA456_TABLET_CHIP_ID) + { + if (int_line <= 1) + { + /* Map/Unmap the interrupt */ + rslt = bma4_map_interrupt(int_line, int_map, enable, dev); + } + else + { + rslt = BMA4_E_INT_LINE_INVALID; + } + } + else + { + rslt = BMA4_E_INVALID_SENSOR; + } + } + else + { + rslt = BMA4_E_NULL_PTR; + } + + return rslt; +} + +/*! + * @brief This API reads the interrupt status from the sensor. + */ +int8_t bma456_tablet_read_int_status(uint16_t *int_status, struct bma4_dev *dev) +{ + int8_t rslt = BMA4_OK; + + if ((dev != NULL) && (int_status != NULL)) + { + if (dev->chip_id == BMA456_TABLET_CHIP_ID) + { + /* Read the interrupt status */ + rslt = bma4_read_int_status(int_status, dev); + } + else + { + rslt = BMA4_E_INVALID_SENSOR; + } + } + else + { + rslt = BMA4_E_NULL_PTR; + } + + return rslt; +} + +/*! + * @brief This API enables/disables the features of the sensor. + */ +int8_t bma456_tablet_feature_enable(uint8_t feature, uint8_t enable, struct bma4_dev *dev) +{ + uint8_t feature_config[BMA456_TABLET_FEATURE_SIZE] = { 0 }; + int8_t rslt = BMA4_OK; + uint8_t len = BMA456_TABLET_FEATURE_SIZE; + + if (dev != NULL) + { + if (dev->chip_id == BMA456_TABLET_CHIP_ID) + { + /* Read feature configuration data */ + rslt = bma4_read_regs(BMA4_FEATURE_CONFIG_ADDR, feature_config, len, dev); + if (rslt == BMA4_OK) + { + if (enable == TRUE) + { + /* Enables the feature */ + rslt = feature_enable(feature, len, feature_config, dev); + } + else + { + /* Disables the feature */ + rslt = feature_disable(feature, len, feature_config, dev); + } + } + } + else + { + rslt = BMA4_E_INVALID_SENSOR; + } + } + else + { + rslt = BMA4_E_NULL_PTR; + } + + return rslt; +} + +/*! + * @brief This API performs x, y and z axis remapping in the sensor. + */ +int8_t bma456_tablet_set_remap_axes(const struct bma4_remap *remap_axes, struct bma4_dev *dev) +{ + uint8_t feature_config[BMA456_TABLET_FEATURE_SIZE] = { 0 }; + uint8_t index = BMA456_TABLET_AXES_REMAP_OFFSET; + int8_t rslt = BMA4_OK; + + if (remap_axes != NULL) + { + rslt = bma4_set_remap_axes(remap_axes, feature_config, index, BMA456_TABLET_FEATURE_SIZE, dev); + } + else + { + rslt = BMA4_E_NULL_PTR; + } + + return rslt; +} + +/*! + * @brief This API reads the x, y and z axis remap data from the sensor. + */ +int8_t bma456_tablet_get_remap_axes(struct bma4_remap *remap_axes, struct bma4_dev *dev) +{ + uint8_t feature_config[BMA456_TABLET_FEATURE_SIZE] = { 0 }; + uint8_t index = BMA456_TABLET_AXES_REMAP_OFFSET; + int8_t rslt = BMA4_OK; + + if (remap_axes != NULL) + { + rslt = bma4_get_remap_axes(remap_axes, feature_config, index, BMA456_TABLET_FEATURE_SIZE, dev); + } + else + { + rslt = BMA4_E_NULL_PTR; + } + + return rslt; +} + +/*! + * @brief This API sets the configuration of any-motion feature in the sensor. + * This API enables/disables the any-motion feature according to the axis set. + */ +int8_t bma456_tablet_set_any_mot_config(const struct bma456_tablet_any_no_mot_config *any_mot, struct bma4_dev *dev) +{ + /* Variable to define error */ + int8_t rslt = BMA4_OK; + + /* Initialize configuration file */ + uint8_t feature_config[BMA456_TABLET_FEATURE_SIZE] = { 0 }; + + /* Update index to configure any-motion axes */ + uint8_t index = BMA456_TABLET_ANY_MOT_OFFSET; + + /* Variable to define LSB */ + uint16_t lsb = 0; + + /* Variable to define MSB */ + uint16_t msb = 0; + + /* Variable to define LSB and MSB */ + uint16_t lsb_msb = 0; + + if (any_mot != NULL) + { + /* Get any-motion configuration from the sensor */ + rslt = bma4_read_regs(BMA4_FEATURE_CONFIG_ADDR, feature_config, BMA456_TABLET_ANY_MOT_LEN, dev); + if (rslt == BMA4_OK) + { + /* Set threshold value in feature configuration array */ + feature_config[index] = BMA4_GET_LSB(any_mot->threshold); + feature_config[index + 1] = BMA4_GET_MSB(any_mot->threshold); + + /* Extract the word where duration and axes enable + * resides + */ + lsb = feature_config[index + 2]; + msb = feature_config[index + 3] << 8; + lsb_msb = lsb | msb; + + /* Set the duration in the same word */ + lsb_msb = BMA4_SET_BITS_POS_0(lsb_msb, BMA456_TABLET_ANY_NO_MOT_DUR, any_mot->duration); + + /* Set the axes in the same word */ + lsb_msb = BMA4_SET_BITSLICE(lsb_msb, BMA456_TABLET_ANY_NO_MOT_AXIS_EN, any_mot->axes_en); + + /* Assign the word with set duration and axes enable + * value back to feature configuration array + */ + feature_config[index + 2] = BMA4_GET_LSB(lsb_msb); + feature_config[index + 3] = BMA4_GET_MSB(lsb_msb); + + /* Set any-motion configuration to the sensor */ + rslt = bma4_write_regs(BMA4_FEATURE_CONFIG_ADDR, feature_config, BMA456_TABLET_ANY_MOT_LEN, dev); + } + } + else + { + rslt = BMA4_E_NULL_PTR; + } + + return rslt; +} + +/*! + * @brief This API gets the configuration of any-motion feature from the + * sensor. + */ +int8_t bma456_tablet_get_any_mot_config(struct bma456_tablet_any_no_mot_config *any_mot, struct bma4_dev *dev) +{ + /* Variable to define error */ + int8_t rslt = BMA4_OK; + + /* Initialize configuration file */ + uint8_t feature_config[BMA456_TABLET_FEATURE_SIZE] = { 0 }; + + /* Update index to configure any-motion axes */ + uint8_t index = BMA456_TABLET_ANY_MOT_OFFSET; + + /* Variable to define LSB */ + uint16_t lsb = 0; + + /* Variable to define MSB */ + uint16_t msb = 0; + + /* Variable to define LSB and MSB */ + uint16_t lsb_msb = 0; + + if (any_mot != NULL) + { + /* Get any-motion configuration from the sensor */ + rslt = bma4_read_regs(BMA4_FEATURE_CONFIG_ADDR, feature_config, BMA456_TABLET_ANY_MOT_LEN, dev); + if (rslt == BMA4_OK) + { + /* Get word to calculate threshold and any-motion + * select + */ + lsb = (uint16_t)feature_config[index]; + msb = (uint16_t)((feature_config[index + 1] << 8)); + lsb_msb = lsb | msb; + + /* Extract threshold value */ + any_mot->threshold = lsb_msb & BMA456_TABLET_ANY_NO_MOT_THRES_MSK; + + /* Get word to calculate duration and axes enable */ + lsb = (uint16_t)feature_config[index + 2]; + msb = (uint16_t)((feature_config[index + 3] << 8)); + lsb_msb = lsb | msb; + + /* Extract duration value */ + any_mot->duration = lsb_msb & BMA456_TABLET_ANY_NO_MOT_DUR_MSK; + + /* Extract axes enable value */ + any_mot->axes_en = BMA4_GET_BITSLICE(lsb_msb, BMA456_TABLET_ANY_NO_MOT_AXIS_EN); + } + } + else + { + rslt = BMA4_E_NULL_PTR; + } + + return rslt; +} + +/*! + * @brief This API sets the configuration of no-motion feature in the sensor. + * This API enables/disables the no-motion feature according to the axis set. + */ +int8_t bma456_tablet_set_no_mot_config(const struct bma456_tablet_any_no_mot_config *no_mot, struct bma4_dev *dev) +{ + /* Variable to define error */ + int8_t rslt = BMA4_OK; + + /* Initialize configuration file */ + uint8_t feature_config[BMA456_TABLET_FEATURE_SIZE] = { 0 }; + + /* Update index to configure no-motion axes */ + uint8_t index = BMA456_TABLET_NO_MOT_OFFSET; + + /* Variable to define LSB */ + uint16_t lsb = 0; + + /* Variable to define MSB */ + uint16_t msb = 0; + + /* Variable to define LSB and MSB */ + uint16_t lsb_msb = 0; + + if (no_mot != NULL) + { + /* Get no-motion configuration from the sensor */ + rslt = bma4_read_regs(BMA4_FEATURE_CONFIG_ADDR, feature_config, BMA456_TABLET_NO_MOT_RD_WR_LEN, dev); + if (rslt == BMA4_OK) + { + /* Set threshold value in feature configuration array */ + feature_config[index] = BMA4_GET_LSB(no_mot->threshold); + feature_config[index + 1] = BMA4_GET_MSB(no_mot->threshold); + + /* Extract the word where duration and axes enable + * resides + */ + lsb = feature_config[index + 2]; + msb = feature_config[index + 3] << 8; + lsb_msb = lsb | msb; + + /* Set the duration in the same word */ + lsb_msb = BMA4_SET_BITS_POS_0(lsb_msb, BMA456_TABLET_ANY_NO_MOT_DUR, no_mot->duration); + + /* Set the axes in the same word */ + lsb_msb = BMA4_SET_BITSLICE(lsb_msb, BMA456_TABLET_ANY_NO_MOT_AXIS_EN, no_mot->axes_en); + + /* Assign the word with set duration and axes enable + * value back to feature configuration array + */ + feature_config[index + 2] = BMA4_GET_LSB(lsb_msb); + feature_config[index + 3] = BMA4_GET_MSB(lsb_msb); + + /* Set no-motion configuration to the sensor */ + rslt = bma4_write_regs(BMA4_FEATURE_CONFIG_ADDR, feature_config, BMA456_TABLET_NO_MOT_RD_WR_LEN, dev); + } + } + else + { + rslt = BMA4_E_NULL_PTR; + } + + return rslt; +} + +/*! + * @brief This API gets the configuration of no-motion feature from the + * sensor. + */ +int8_t bma456_tablet_get_no_mot_config(struct bma456_tablet_any_no_mot_config *no_mot, struct bma4_dev *dev) +{ + /* Variable to define error */ + int8_t rslt = BMA4_OK; + + /* Initialize configuration file */ + uint8_t feature_config[BMA456_TABLET_FEATURE_SIZE] = { 0 }; + + /* Update index to configure no-motion axes */ + uint8_t index = BMA456_TABLET_NO_MOT_OFFSET; + + /* Variable to define LSB */ + uint16_t lsb = 0; + + /* Variable to define MSB */ + uint16_t msb = 0; + + /* Variable to define LSB and MSB */ + uint16_t lsb_msb = 0; + + if (no_mot != NULL) + { + /* Get no-motion configuration from the sensor */ + rslt = bma4_read_regs(BMA4_FEATURE_CONFIG_ADDR, feature_config, BMA456_TABLET_NO_MOT_RD_WR_LEN, dev); + if (rslt == BMA4_OK) + { + /* Get word to calculate threshold and no-motion + * select + */ + lsb = (uint16_t)feature_config[index]; + msb = ((uint16_t)feature_config[index + 1] << 8); + lsb_msb = lsb | msb; + + /* Extract threshold value */ + no_mot->threshold = lsb_msb & BMA456_TABLET_ANY_NO_MOT_THRES_MSK; + + /* Get word to calculate duration and axes enable */ + lsb = (uint16_t)feature_config[index + 2]; + msb = (uint16_t)((feature_config[index + 3] << 8)); + lsb_msb = lsb | msb; + + /* Extract duration value */ + no_mot->duration = lsb_msb & BMA456_TABLET_ANY_NO_MOT_DUR_MSK; + + /* Extract axes enable value */ + no_mot->axes_en = BMA4_GET_BITSLICE(lsb_msb, BMA456_TABLET_ANY_NO_MOT_AXIS_EN); + } + } + else + { + rslt = BMA4_E_NULL_PTR; + } + + return rslt; +} + +/*! + * @brief This API gets the parameter1 to parameter12 settings of the + * tap feature. + */ +int8_t bma456_tablet_tap_get_parameter(struct bma456_tablet_tap_settings *setting, struct bma4_dev *dev) +{ + uint8_t feature_config[BMA456_TABLET_FEATURE_SIZE] = { 0 }; + uint16_t *data_p = (uint16_t *)(void *)feature_config; + int8_t rslt = BMA4_OK; + + if ((dev != NULL) && (setting != NULL)) + { + if (dev->chip_id == BMA456_TABLET_CHIP_ID) + { + rslt = bma4_read_regs(BMA4_FEATURE_CONFIG_ADDR, feature_config, BMA456_TABLET_FEATURE_SIZE, dev); + if (rslt == BMA4_OK) + { + /* To convert 8bit to 16 bit address */ + data_p = data_p + ((BMA456_TABLET_TAP_DETECTOR_OFFSET + 2) / 2); + extract_tap_parameter(setting, data_p); + } + } + else + { + rslt = BMA4_E_INVALID_SENSOR; + } + } + else + { + rslt = BMA4_E_NULL_PTR; + } + + return rslt; +} + +/*! + * @brief This API sets the parameter1 to parameter12 settings of the + * tap feature in the sensor. + */ +int8_t bma456_tablet_tap_set_parameter(const struct bma456_tablet_tap_settings *setting, struct bma4_dev *dev) +{ + uint8_t feature_config[BMA456_TABLET_FEATURE_SIZE] = { 0 }; + uint16_t index = BMA456_TABLET_TAP_DETECTOR_OFFSET + 4; + int8_t rslt = BMA4_OK; + + if ((dev != NULL) && (setting != NULL)) + { + if (dev->chip_id == BMA456_TABLET_CHIP_ID) + { + rslt = bma4_read_regs(BMA4_FEATURE_CONFIG_ADDR, feature_config, BMA456_TABLET_FEATURE_SIZE, dev); + if (rslt == BMA4_OK) + { + update_tap_parameter(setting, index, feature_config); + + /* Writes tap parameter settings + * in the sensor + */ + rslt = bma4_write_regs(BMA4_FEATURE_CONFIG_ADDR, feature_config, BMA456_TABLET_FEATURE_SIZE, dev); + } + } + else + { + rslt = BMA4_E_INVALID_SENSOR; + } + } + else + { + rslt = BMA4_E_NULL_PTR; + } + + return rslt; +} + +/*! + * @brief This API gets the output for tap feature. + */ +int8_t bma456_tablet_tap_output(struct bma456_tablet_tap_output *out_state, struct bma4_dev *dev) +{ + uint8_t data = { 0 }; + int8_t rslt = BMA4_OK; + + if ((dev != NULL) && (out_state != NULL)) + { + if (dev->chip_id == BMA456_TABLET_CHIP_ID) + { + /* Reads the tap output from the gpio register */ + rslt = bma4_read_regs(BMA456_TABLET_TAP_FEAT_OUT_ADDR, &data, 1, dev); + if (rslt == BMA4_OK) + { + out_state->s_tap = BMA4_GET_BITS_POS_0(data, BMA456_TABLET_SINGLE_TAP_OUT); + out_state->d_tap = BMA4_GET_BITSLICE(data, BMA456_TABLET_DOUBLE_TAP_OUT); + out_state->t_tap = BMA4_GET_BITSLICE(data, BMA456_TABLET_TRIPLE_TAP_OUT); + } + } + else + { + rslt = BMA4_E_INVALID_SENSOR; + } + } + else + { + rslt = BMA4_E_NULL_PTR; + } + + return rslt; +} + +/*! + * @brief This API sets the configuration for low-g feature of the sensor. + */ +int8_t bma456_tablet_set_low_g_config(const struct bma456_tablet_low_g_config *low_g, struct bma4_dev *dev) +{ + /* variable used to return the status of communication result*/ + int8_t rslt = BMA4_OK; + uint8_t feature_config[BMA456_TABLET_FEATURE_SIZE] = { 0, }; + uint8_t index = BMA456_TABLET_LOW_G_OFFSET; + + /* Variable to define LSB */ + uint16_t lsb = 0; + + /* Variable to define MSB */ + uint16_t msb = 0; + + /* Variable to define LSB and MSB */ + uint16_t lsb_msb = 0; + + if ((dev != NULL) && (low_g != NULL)) + { + if (dev->chip_id == BMA456_TABLET_CHIP_ID) + { + rslt = bma4_read_regs(BMA4_FEATURE_CONFIG_ADDR, feature_config, BMA456_TABLET_FEATURE_SIZE, dev); + if (rslt == BMA4_OK) + { + /* Threshold */ + + lsb = feature_config[index]; + msb = feature_config[index + 1] << 8; + lsb_msb = lsb | msb; + + /* Set the threshold in the same word */ + lsb_msb = BMA4_SET_BITS_POS_0(lsb_msb, BMA456_TABLET_LOW_G_THRES, low_g->threshold); + + /* Set threshold value in feature configuration array */ + feature_config[index++] = BMA4_GET_LSB(lsb_msb); + feature_config[index++] = BMA4_GET_MSB(lsb_msb); + + /* Hysteresis */ + + lsb = feature_config[index]; + msb = feature_config[index + 1] << 8; + lsb_msb = lsb | msb; + + /* Set the hysteresis in the same word */ + lsb_msb = BMA4_SET_BITS_POS_0(lsb_msb, BMA456_TABLET_LOW_G_HYST, low_g->hysteresis); + + /* Set hysteresis value in feature configuration array */ + feature_config[index++] = BMA4_GET_LSB(lsb_msb); + feature_config[index++] = BMA4_GET_MSB(lsb_msb); + + /* Duration */ + + lsb = feature_config[index]; + msb = feature_config[index + 1] << 8; + lsb_msb = lsb | msb; + + /* Set the duration in the same word */ + lsb_msb = BMA4_SET_BITS_POS_0(lsb_msb, BMA456_TABLET_LOW_G_HYST, low_g->duration); + + /* Set duration value in feature configuration array */ + feature_config[index++] = BMA4_GET_LSB(lsb_msb); + feature_config[index++] = BMA4_GET_MSB(lsb_msb); + + /* Writes orientation settings value in the sensor */ + rslt = bma4_write_regs(BMA4_FEATURE_CONFIG_ADDR, feature_config, BMA456_TABLET_FEATURE_SIZE, dev); + } + } + else + { + rslt = BMA4_E_INVALID_SENSOR; + } + } + else + { + rslt = BMA4_E_NULL_PTR; + } + + return rslt; +} + +/*! + * @brief This API gets the configuration of low-g feature from the sensor + */ +int8_t bma456_tablet_get_low_g_config(struct bma456_tablet_low_g_config *low_g, struct bma4_dev *dev) +{ + /* variable used to return the status of communication result*/ + int8_t rslt = BMA4_OK; + uint8_t feature_config[BMA456_TABLET_FEATURE_SIZE] = { 0 }; + uint8_t index = BMA456_TABLET_LOW_G_OFFSET; + + /* Variable to define LSB */ + uint16_t lsb = 0; + + /* Variable to define MSB */ + uint16_t msb = 0; + + /* Variable to define LSB and MSB */ + uint16_t lsb_msb = 0; + + if ((dev != NULL) && (low_g != NULL)) + { + if (dev->chip_id == BMA456_TABLET_CHIP_ID) + { + rslt = bma4_read_regs(BMA4_FEATURE_CONFIG_ADDR, feature_config, BMA456_TABLET_FEATURE_SIZE, dev); + if (rslt == BMA4_OK) + { + /* Get threshold */ + + lsb = (uint16_t)feature_config[index++]; + msb = ((uint16_t)feature_config[index++] << 8); + lsb_msb = lsb | msb; + + /* Extract threshold value */ + low_g->threshold = lsb_msb & BMA456_TABLET_LOW_G_THRES_MSK; + + /* Get hysteresis */ + + lsb = (uint16_t)feature_config[index++]; + msb = ((uint16_t)feature_config[index++] << 8); + lsb_msb = lsb | msb; + + /* Extract hysteresis value */ + low_g->hysteresis = lsb_msb & BMA456_TABLET_LOW_G_HYST_MSK; + + /* Get duration */ + + lsb = (uint16_t)feature_config[index++]; + msb = ((uint16_t)feature_config[index++] << 8); + lsb_msb = lsb | msb; + + /* Extract duration value */ + low_g->duration = lsb_msb & BMA456_TABLET_LOW_G_DUR_MSK; + } + } + else + { + rslt = BMA4_E_INVALID_SENSOR; + } + } + else + { + rslt = BMA4_E_NULL_PTR; + } + + return rslt; +} + +/*! + * @brief This API sets the configuration for orientation feature of the sensor. + */ +int8_t bma456_tablet_set_orientation_config(const struct bma456_tablet_orientation_config *orientation, + struct bma4_dev *dev) +{ + /* variable used to return the status of communication result*/ + int8_t rslt = BMA4_OK; + uint8_t feature_config[BMA456_TABLET_FEATURE_SIZE] = { 0, }; + uint8_t index = BMA456_TABLET_ORIENTATION_OFFSET; + uint16_t orient_settings_1_lsb = 0; + uint16_t orient_settings_1_msb = 0; + uint16_t orient_settings_1 = 0; + + if ((dev != NULL) && (orientation != NULL)) + { + if (dev->chip_id == BMA456_TABLET_CHIP_ID) + { + rslt = bma4_read_regs(BMA4_FEATURE_CONFIG_ADDR, feature_config, BMA456_TABLET_FEATURE_SIZE, dev); + if (rslt == BMA4_OK) + { + /* Extract upside/down, mode, blocking and hold_time */ + orient_settings_1_lsb = feature_config[index]; + orient_settings_1_msb = feature_config[index + 1] << 8; + orient_settings_1 = orient_settings_1_lsb | orient_settings_1_msb; + orient_settings_1 = BMA4_SET_BITSLICE(orient_settings_1, + BMA456_TABLET_ORIENT_UD, + orientation->upside_down); + orient_settings_1 = BMA4_SET_BITSLICE(orient_settings_1, BMA456_TABLET_ORIENT_MODE, orientation->mode); + orient_settings_1 = BMA4_SET_BITSLICE(orient_settings_1, + BMA456_TABLET_ORIENT_BLOCKING, + orientation->blocking); + orient_settings_1 = BMA4_SET_BITSLICE(orient_settings_1, + BMA456_TABLET_ORIENT_HOLD_TIME, + orientation->hold_time); + + /* Assign slope_thres and hysteresis value in feature config array*/ + feature_config[index++] = BMA4_GET_LSB(orient_settings_1); + feature_config[index++] = BMA4_GET_MSB(orient_settings_1); + + /* Extract slope_thres and hysteresis */ + orient_settings_1_lsb = feature_config[index]; + orient_settings_1_msb = feature_config[index + 1] << 8; + orient_settings_1 = orient_settings_1_lsb | orient_settings_1_msb; + orient_settings_1 = BMA4_SET_BITS_POS_0(orient_settings_1, + BMA456_TABLET_ORIENT_SLOPE_THRES, + orientation->slope_thres); + orient_settings_1 = BMA4_SET_BITSLICE(orient_settings_1, + BMA456_TABLET_ORIENT_HYST, + orientation->hysteresis); + + /* Assign theta value in feature config array*/ + feature_config[index++] = BMA4_GET_LSB(orient_settings_1); + feature_config[index++] = BMA4_GET_MSB(orient_settings_1); + + /* Extract theta */ + orient_settings_1_lsb = feature_config[index]; + orient_settings_1_msb = feature_config[index + 1] << 8; + orient_settings_1 = orient_settings_1_lsb | orient_settings_1_msb; + orient_settings_1 = BMA4_SET_BITS_POS_0(orient_settings_1, + BMA456_TABLET_ORIENT_THETA, + orientation->theta); + + /* Assign fall threshold value in feature config array*/ + feature_config[index++] = BMA4_GET_LSB(orient_settings_1); + feature_config[index++] = BMA4_GET_MSB(orient_settings_1); + + /* Writes orientation settings value in the sensor */ + rslt = bma4_write_regs(BMA4_FEATURE_CONFIG_ADDR, feature_config, BMA456_TABLET_FEATURE_SIZE, dev); + } + } + else + { + rslt = BMA4_E_INVALID_SENSOR; + } + } + else + { + rslt = BMA4_E_NULL_PTR; + } + + return rslt; +} + +/*! + * @brief This API gets the configuration of orientation feature from the sensor + */ +int8_t bma456_tablet_get_orientation_config(struct bma456_tablet_orientation_config *orientation, struct bma4_dev *dev) +{ + /* variable used to return the status of communication result*/ + int8_t rslt = BMA4_OK; + uint8_t feature_config[BMA456_TABLET_FEATURE_SIZE] = { 0 }; + uint8_t index = BMA456_TABLET_ORIENTATION_OFFSET; + uint16_t orient_settings_lsb = 0; + uint16_t orient_settings_msb = 0; + uint16_t orient_settings = 0; + + if ((dev != NULL) && (orientation != NULL)) + { + if (dev->chip_id == BMA456_TABLET_CHIP_ID) + { + rslt = bma4_read_regs(BMA4_FEATURE_CONFIG_ADDR, feature_config, BMA456_TABLET_FEATURE_SIZE, dev); + if (rslt == BMA4_OK) + { + /* Extract upside/down, mode, blocking and hold_time */ + orient_settings_lsb = feature_config[index]; + orient_settings_msb = feature_config[index + 1] << 8; + orient_settings = orient_settings_lsb | orient_settings_msb; + orientation->upside_down = BMA4_GET_BITSLICE(orient_settings, BMA456_TABLET_ORIENT_UD); + orientation->mode = BMA4_GET_BITSLICE(orient_settings, BMA456_TABLET_ORIENT_MODE); + orientation->blocking = BMA4_GET_BITSLICE(orient_settings, BMA456_TABLET_ORIENT_BLOCKING); + orientation->hold_time = BMA4_GET_BITSLICE(orient_settings, BMA456_TABLET_ORIENT_HOLD_TIME); + + /* Extract slope_thres and hysteresis */ + orient_settings_lsb = feature_config[index + 2]; + orient_settings_msb = feature_config[index + 3] << 8; + orient_settings = orient_settings_lsb | orient_settings_msb; + orientation->slope_thres = BMA4_GET_BITS_POS_0(orient_settings, BMA456_TABLET_ORIENT_SLOPE_THRES); + orientation->hysteresis = BMA4_GET_BITSLICE(orient_settings, BMA456_TABLET_ORIENT_HYST); + + /* Extract theta */ + orient_settings_lsb = feature_config[index + 4]; + orient_settings_msb = feature_config[index + 5] << 8; + orient_settings = orient_settings_lsb | orient_settings_msb; + orientation->theta = BMA4_GET_BITS_POS_0(orient_settings, BMA456_TABLET_ORIENT_THETA); + } + } + else + { + rslt = BMA4_E_INVALID_SENSOR; + } + } + else + { + rslt = BMA4_E_NULL_PTR; + } + + return rslt; +} + +/*! + * @brief This API gets the output of orientation feature from the sensor. + */ +int8_t bma456_tablet_orientation_output(uint8_t *orientation_output, + uint8_t *orientation_faceup_down, + struct bma4_dev *dev) +{ + /* variable used to return the status of communication result*/ + int8_t rslt = BMA4_OK; + uint8_t data = 0; + + if (dev != NULL) + { + if (dev->chip_id == BMA456_TABLET_CHIP_ID) + { + /* Reads the orientation output from the gpio register */ + rslt = bma4_read_regs(BMA456_TABLET_ORIENTATION_OUT_ADDR, &data, 1, dev); + if (rslt == BMA4_OK) + { + *orientation_output = BMA4_GET_BITS_POS_0(data, BMA456_TABLET_ORIENT_OUT); + *orientation_faceup_down = BMA4_GET_BITSLICE(data, BMA456_TABLET_ORIENT_FACEUP_DOWN); + } + } + else + { + rslt = BMA4_E_INVALID_SENSOR; + } + } + else + { + rslt = BMA4_E_NULL_PTR; + } + + return rslt; +} + +/*! @cond DOXYGEN_SUPRESS */ + +/* Suppressing doxygen warnings triggered for same static function names present across various sensor variant + * directories */ + +/***************************************************************************/ +/*! Static Function Definitions */ +/***************************************************************************/ + +/*! + * @brief This API update the settings of tap. + */ +static void update_tap_parameter(const struct bma456_tablet_tap_settings *setting, + uint16_t index, + uint8_t *feature_config) +{ + /* Update tap_sens_thres */ + feature_config[index++] = BMA4_GET_LSB(setting->tap_sens_thres); + feature_config[index++] = BMA4_GET_MSB(setting->tap_sens_thres); + + /* Update max_gest_dur */ + feature_config[index++] = BMA4_GET_LSB(setting->max_gest_dur); + feature_config[index++] = BMA4_GET_MSB(setting->max_gest_dur); + + /* Update tap_shock_dur */ + index = index + 2; + feature_config[index++] = BMA4_GET_LSB(setting->tap_shock_dur); + feature_config[index++] = BMA4_GET_MSB(setting->tap_shock_dur); + + /* Update quite_time_after_gest */ + index = index + 2; + feature_config[index++] = BMA4_GET_LSB(setting->quite_time_after_gest); + feature_config[index++] = BMA4_GET_MSB(setting->quite_time_after_gest); + + /* Update wait_for_timeout */ + feature_config[index++] = BMA4_GET_LSB(setting->wait_for_timeout); + feature_config[index++] = BMA4_GET_MSB(setting->wait_for_timeout); + + /* Update axis_sel */ + index = index + 2; + feature_config[index++] = BMA4_GET_LSB(setting->axis_sel); + feature_config[index++] = BMA4_GET_MSB(setting->axis_sel); +} + +/*! + * @brief This API copy the settings of tap into the structure of + * bma456_tablet_tap_settings, which is read from sensor. + */ +static void extract_tap_parameter(struct bma456_tablet_tap_settings *setting, const uint16_t *data_p) +{ + /* Extract tap_sens_thres */ + data_p++; + setting->tap_sens_thres = *(data_p++); + + /* Extract max_gest_dur */ + setting->max_gest_dur = *(data_p++); + + /* Extract tap_shock_dur */ + data_p++; + setting->tap_shock_dur = *(data_p++); + + /* Extract quite_time_after_gest */ + data_p++; + setting->quite_time_after_gest = *(data_p++); + + /* Extract wait_for_timeout */ + setting->wait_for_timeout = *(data_p++); + + /* Extract axis_sel */ + data_p++; + setting->axis_sel = *(data_p++); +} + +/*! + * @brief This API enables the features of the sensor. + */ +static int8_t feature_enable(uint8_t feature, uint8_t len, uint8_t *feature_config, struct bma4_dev *dev) +{ + uint8_t index = 0; + int8_t rslt = BMA4_OK; + + if ((dev != NULL) && (feature_config != NULL)) + { + /* Enable Low-G */ + if ((feature & BMA456_TABLET_LOW_G) > 0) + { + index = BMA456_TABLET_LOW_G_OFFSET + BMA456_TABLET_LOW_G_FEAT_EN_OFFSET; + feature_config[index] = feature_config[index] | BMA456_TABLET_LOW_G_EN_MSK; + } + + /* Enable orientation */ + if ((feature & BMA456_TABLET_ORIENTATION) > 0) + { + index = BMA456_TABLET_ORIENTATION_OFFSET; + feature_config[index] = feature_config[index] | BMA456_TABLET_ORIENT_EN_MSK; + } + + /* Enable single - tap */ + if ((feature & BMA456_TABLET_SINGLE_TAP) > 0) + { + index = BMA456_TABLET_TAP_DETECTOR_OFFSET; + feature_config[index] = feature_config[index] | BMA456_TABLET_SINGLE_TAP_EN_MSK; + } + + /* Enable double - tap */ + if ((feature & BMA456_TABLET_DOUBLE_TAP) > 0) + { + index = BMA456_TABLET_TAP_DETECTOR_OFFSET; + feature_config[index] = feature_config[index] | BMA456_TABLET_DOUBLE_TAP_EN_MSK; + } + + /* Enable triple - tap */ + if ((feature & BMA456_TABLET_TRIPLE_TAP) > 0) + { + index = BMA456_TABLET_TAP_DETECTOR_OFFSET; + feature_config[index] = feature_config[index] | BMA456_TABLET_TRIPLE_TAP_EN_MSK; + } + + /* Write the feature enable settings in the sensor */ + rslt = bma4_write_regs(BMA4_FEATURE_CONFIG_ADDR, feature_config, len, dev); + } + + return rslt; +} + +/*! + * @brief This API disables the features of the sensor. + */ +static int8_t feature_disable(uint8_t feature, uint8_t len, uint8_t *feature_config, struct bma4_dev *dev) +{ + uint8_t index = 0; + int8_t rslt = BMA4_OK; + + if ((dev != NULL) && (feature_config != NULL)) + { + /* Disable Low-G */ + if ((feature & BMA456_TABLET_LOW_G) > 0) + { + index = BMA456_TABLET_LOW_G_OFFSET + BMA456_TABLET_LOW_G_FEAT_EN_OFFSET; + feature_config[index] = feature_config[index] & (~BMA456_TABLET_LOW_G_EN_MSK); + } + + /* Disable orientation */ + if ((feature & BMA456_TABLET_ORIENTATION) > 0) + { + index = BMA456_TABLET_ORIENTATION_OFFSET; + feature_config[index] = feature_config[index] & (~BMA456_TABLET_ORIENT_EN_MSK); + } + + /* Disable single-tap */ + if ((feature & BMA456_TABLET_SINGLE_TAP) > 0) + { + index = BMA456_TABLET_TAP_DETECTOR_OFFSET; + feature_config[index] = feature_config[index] & (~BMA456_TABLET_SINGLE_TAP_EN_MSK); + } + + /* Disable double-tap */ + if ((feature & BMA456_TABLET_DOUBLE_TAP) > 0) + { + index = BMA456_TABLET_TAP_DETECTOR_OFFSET; + feature_config[index] = feature_config[index] & (~BMA456_TABLET_DOUBLE_TAP_EN_MSK); + } + + /* Disable triple-tap */ + if ((feature & BMA456_TABLET_TRIPLE_TAP) > 0) + { + index = BMA456_TABLET_TAP_DETECTOR_OFFSET; + feature_config[index] = feature_config[index] & (~BMA456_TABLET_TRIPLE_TAP_EN_MSK); + } + + /* Write the configured settings in the sensor */ + rslt = bma4_write_regs(BMA4_FEATURE_CONFIG_ADDR, feature_config, len, dev); + } + + return rslt; +} + +/*! @endcond */ diff --git a/components/bma456/bma456_tablet.h b/components/bma456/bma456_tablet.h new file mode 100644 index 0000000..85cd890 --- /dev/null +++ b/components/bma456/bma456_tablet.h @@ -0,0 +1,1166 @@ +/** +* 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. +* +* @file bma456_tablet.h +* @date 2023-07-05 +* @version V2.29.0 +* +*/ + +/** + * \ingroup bma4xy + * \defgroup bma456_tablet BMA456_TABLET + * @brief Sensor driver for BMA456_TABLET sensor + */ + +#ifndef BMA456_TABLET_H +#define BMA456_TABLET_H + +#ifdef __cplusplus +extern "C" { +#endif +#include "bma4.h" + +/**\name Chip ID */ +#define BMA456_TABLET_CHIP_ID UINT8_C(0x16) + +/**\name Sensor feature size */ +#define BMA456_TABLET_FEATURE_SIZE UINT8_C(50) + +/**\name Feature offset address */ +#define BMA456_TABLET_ANY_MOT_OFFSET UINT8_C(0x00) +#define BMA456_TABLET_NO_MOT_OFFSET UINT8_C(0x04) +#define BMA456_TABLET_LOW_G_OFFSET UINT8_C(0x08) +#define BMA456_TABLET_TAP_DETECTOR_OFFSET UINT8_C(0x0E) +#define BMA456_TABLET_ORIENTATION_OFFSET UINT8_C(0x28) +#define BMA456_TABLET_CONFIG_ID_OFFSET UINT8_C(0x2E) +#define BMA456_TABLET_AXES_REMAP_OFFSET UINT8_C(0x30) + +/**\name Read/Write Lengths */ +#define BMA456_TABLET_RD_WR_MIN_LEN UINT8_C(2) + +/*! @name Maximum valid read write length is size of config file array */ +#define BMA456_TABLET_RD_WR_MAX_LEN ((uint16_t)sizeof(bma456_tablet_config_file)) + +/**************************************************************/ +/**\name Re-map Axes */ +/**************************************************************/ +#define BMA456_TABLET_X_AXIS_MASK UINT8_C(0x03) +#define BMA456_TABLET_X_AXIS_SIGN_MASK UINT8_C(0x04) +#define BMA456_TABLET_Y_AXIS_MASK UINT8_C(0x18) +#define BMA456_TABLET_Y_AXIS_SIGN_MASK UINT8_C(0x20) +#define BMA456_TABLET_Z_AXIS_MASK UINT8_C(0xC0) +#define BMA456_TABLET_Z_AXIS_SIGN_MASK UINT8_C(0x01) + +/**************************************************************/ +/**\name Any/no Motion */ +/**************************************************************/ +#define BMA456_TABLET_ANY_MOT_LEN UINT8_C(4) +#define BMA456_TABLET_NO_MOT_RD_WR_LEN (BMA456_TABLET_ANY_MOT_LEN + BMA456_TABLET_NO_MOT_OFFSET) + +/**\name Any/No motion threshold macros */ +#define BMA456_TABLET_ANY_NO_MOT_THRES_MSK UINT16_C(0x07FF) + +/**\name Position and mask of interrupt behavior and slope */ +#define BMA456_TABLET_ANY_NO_MOTION_INTR_BHVR_EN_POS UINT8_C(0x03) +#define BMA456_TABLET_ANY_NO_MOTION_INTR_BHVR_EN_MSK UINT8_C(0x08) + +#define BMA456_TABLET_ANY_MOTION_SLOPE_EN_POS UINT8_C(0x04) +#define BMA456_TABLET_ANY_MOTION_SLOPE_EN_MSK UINT8_C(0x10) + +/**\name Any/No motion duration macros */ +#define BMA456_TABLET_ANY_NO_MOT_DUR_MSK UINT16_C(0x1FFF) + +/**\name Any/No motion enable macros */ +#define BMA456_TABLET_ANY_NO_MOT_AXIS_EN_POS UINT8_C(0x0D) +#define BMA456_TABLET_ANY_NO_MOT_AXIS_EN_MSK UINT16_C(0xE000) + +/**************************************************************/ +/**\name Single/Double/Triple Tap */ +/**************************************************************/ +/**\name Single tap enable macros */ +#define BMA456_TABLET_SINGLE_TAP_EN_MSK UINT8_C(0x01) + +/**\name Double tap enable macros */ +#define BMA456_TABLET_DOUBLE_TAP_EN_MSK UINT8_C(0x02) + +/**\name Triple tap enable macros */ +#define BMA456_TABLET_TRIPLE_TAP_EN_MSK UINT8_C(0x04) + +/**\name Tap averaging enable macros */ +#define BMA456_TABLET_TAP_AVG_EN_MSK UINT8_C(0x08) + +/**\name Tap output macros */ +#define BMA456_TABLET_SINGLE_TAP_OUT_MSK UINT8_C(0x01) + +#define BMA456_TABLET_DOUBLE_TAP_OUT_MSK UINT8_C(0x02) +#define BMA456_TABLET_DOUBLE_TAP_OUT_POS UINT8_C(0x01) + +#define BMA456_TABLET_TRIPLE_TAP_OUT_MSK UINT8_C(0x04) +#define BMA456_TABLET_TRIPLE_TAP_OUT_POS UINT8_C(0x02) + +/**************************************************************/ +/**\name Low-G */ +/**************************************************************/ +/**\name Low-G enable macros */ +#define BMA456_TABLET_LOW_G_FEAT_EN_OFFSET UINT8_C(0x03) +#define BMA456_TABLET_LOW_G_EN_POS UINT8_C(0x04) +#define BMA456_TABLET_LOW_G_EN_MSK UINT8_C(0x10) + +/**\name Low-g threshold macro */ +#define BMA456_TABLET_LOW_G_THRES_MSK UINT16_C(0x7FFF) + +/**\name Low-g hysteresis macro */ +#define BMA456_TABLET_LOW_G_HYST_MSK UINT16_C(0x0FFF) + +/**\name Low-g duration macro */ +#define BMA456_TABLET_LOW_G_DUR_MSK UINT16_C(0x0FFF) + +/**************************************************************/ +/**\name Orientation */ +/**************************************************************/ +#define BMA456_TABLET_ORIENTATION_OUT_ADDR UINT8_C(0x1E) + +/**\name Orientation enable macros */ +#define BMA456_TABLET_ORIENT_EN_MSK UINT8_C(0x01) + +/**\name Orientation upside/down detection macros */ +#define BMA456_TABLET_ORIENT_UD_POS UINT8_C(1) +#define BMA456_TABLET_ORIENT_UD_MSK UINT8_C(0x02) + +/**\name Orientation mode macros */ +#define BMA456_TABLET_ORIENT_MODE_POS UINT8_C(2) +#define BMA456_TABLET_ORIENT_MODE_MSK UINT8_C(0x0C) + +/**\name Orientation blocking macros */ +#define BMA456_TABLET_ORIENT_BLOCKING_POS UINT8_C(4) +#define BMA456_TABLET_ORIENT_BLOCKING_MSK UINT8_C(0x30) + +/**\name Orientation hold time macros */ +#define BMA456_TABLET_ORIENT_HOLD_TIME_POS UINT8_C(6) +#define BMA456_TABLET_ORIENT_HOLD_TIME_MSK UINT16_C(0x7C0) + +/**\name Orientation slope threshold macros */ +#define BMA456_TABLET_ORIENT_SLOPE_THRES_MSK UINT16_C(0x00FF) + +/**\name Orientation hysteresis macros */ +#define BMA456_TABLET_ORIENT_HYST_POS UINT8_C(8) +#define BMA456_TABLET_ORIENT_HYST_MSK UINT16_C(0xFF00) + +/**\name Orientation theta macros */ +#define BMA456_TABLET_ORIENT_THETA_MSK UINT16_C(0x00FF) + +/* Orientation output macros */ +#define BMA456_TABLET_ORIENT_OUT_POS UINT8_C(0) +#define BMA456_TABLET_ORIENT_OUT_MSK UINT8_C(0x03) +#define BMA456_TABLET_ORIENT_FACEUP_DOWN_POS UINT8_C(2) +#define BMA456_TABLET_ORIENT_FACEUP_DOWN_MSK UINT8_C(0x04) + +/**\name Orientation output macros */ +/* Bit pos 2 reflects the face-up (0) face-down(1) only if ud_en is enabled */ +#define BMA456_TABLET_FACE_UP UINT8_C(0x00) +#define BMA456_TABLET_FACE_DOWN UINT8_C(0x01) + +/* Bit pos 0-1 reflects the have the following value */ +#define BMA456_TABLET_PORTRAIT_UP_RIGHT UINT8_C(0x00) +#define BMA456_TABLET_LANDSCAPE_LEFT UINT8_C(0x01) +#define BMA456_TABLET_PORTRAIT_UP_DOWN UINT8_C(0x02) +#define BMA456_TABLET_LANDSCAPE_RIGHT UINT8_C(0x03) + +/**************************************************************/ +/**\name User macros */ +/**************************************************************/ +#define BMA456_TABLET_TAP_FEAT_OUT_ADDR UINT8_C(0x20) + +/**\name Any-motion/No-motion axis enable macros */ +#define BMA456_TABLET_X_AXIS_EN UINT8_C(0x01) +#define BMA456_TABLET_Y_AXIS_EN UINT8_C(0x02) +#define BMA456_TABLET_Z_AXIS_EN UINT8_C(0x04) +#define BMA456_TABLET_EN_ALL_AXIS UINT8_C(0x07) +#define BMA456_TABLET_DIS_ALL_AXIS UINT8_C(0x00) + +/**\name Feature enable macros for the sensor */ +#define BMA456_TABLET_LOW_G UINT8_C(0x01) +#define BMA456_TABLET_ORIENTATION UINT8_C(0x02) +#define BMA456_TABLET_SINGLE_TAP UINT8_C(0x04) +#define BMA456_TABLET_DOUBLE_TAP UINT8_C(0x08) +#define BMA456_TABLET_TRIPLE_TAP UINT8_C(0x10) + +/**\name Interrupt status macros */ +#define BMA456_TABLET_TAP_OUT_INT UINT8_C(0x01) +#define BMA456_TABLET_ORIENTATION_INT UINT8_C(0x02) +#define BMA456_TABLET_LOW_G_INT UINT8_C(0x04) +#define BMA456_TABLET_ANY_MOT_INT UINT8_C(0x20) +#define BMA456_TABLET_NO_MOT_INT UINT8_C(0x40) +#define BMA456_TABLET_ERROR_INT UINT8_C(0x80) + +/******************************************************************************/ +/*! @name Structure Declarations */ +/******************************************************************************/ + +/*! + * @brief Any/No motion configuration + */ +struct bma456_tablet_any_no_mot_config +{ + /*! Expressed in 50 Hz samples (20 ms) */ + uint16_t duration; + + /*! Threshold value for Any-motion/No-motion detection in + * 5.11g format + */ + uint16_t threshold; + + /*! To enable selected axes */ + uint8_t axes_en; +}; + +/*! + * @brief Tap param settings + */ +struct bma456_tablet_tap_settings +{ + /*! Scaling factor for threshold */ + uint16_t tap_sens_thres; + + /*! Maximum duration after the first tap */ + uint16_t max_gest_dur; + + /*! Settling time for high frequency acceleration signal */ + uint16_t tap_shock_dur; + + /*! Minimum quite time between the two gesture detection */ + uint16_t quite_time_after_gest; + + /*! Wait for the duration set by max_gest_dur after the first tap */ + uint16_t wait_for_timeout; + + /*! Selection of axis from 3D-acceleration signal vector */ + uint16_t axis_sel; +}; + +/*! + * @brief Tap output state + */ +struct bma456_tablet_tap_output +{ + /*! Single tap detected */ + uint8_t s_tap; + + /*! Double tap detected */ + uint8_t d_tap; + + /*! Triple tap detected */ + uint8_t t_tap; +}; + +/*! + * @brief Low-G configuration + */ +struct bma456_tablet_low_g_config +{ + /*! Threshold value for Low-G feature */ + uint16_t threshold; + + /*! Hysteresis value for Low-G feature */ + uint16_t hysteresis; + + /*! Duration in 50Hz samples(20msec) for + * which threshold has to be exceeded + */ + uint16_t duration; +}; + +/*! + * @brief Orientation configuration structure + */ +struct bma456_tablet_orientation_config +{ + /*! Upside/Downside detection */ + uint8_t upside_down; + + /*! Mode + * Symmetrical (values 0 or 3), High asymmetrical + * (value 1) or Low asymmetrical (value 2) + */ + uint8_t mode; + + /*! Blocking mode + * Sets the blocking mode. + * If blocking is set, no Orientation interrupt will be triggered. + * Default value is 3 – the most restrictive blocking mode. + */ + uint8_t blocking; + + /*! Hold Time + * The number of samples for which the orientation + * should be stable in 50Hz. Resolution: 5 = 100msecs + */ + uint8_t hold_time; + + /*! Slope Threshold + * The slope threshold for blocking mode. + * Resolution: 0.4g = 205 lsbs + */ + uint8_t slope_thres; + + /*! Hysteresis + * Hysteresis of acceleration for orientation change detection. + * Resolution: 62.5mg = 32 lsbs + */ + uint8_t hysteresis; + + /*! Theta + * Coded value of the threshold angle with horizontal + * used in Blocking modes; + * theta = 64 * (tan(angle)^2); + */ + uint8_t theta; +}; + +/***************************************************************************/ + +/*! BMA456_TABLET User Interface function prototypes + ****************************************************************************/ + +/** + * \ingroup bma456_tablet + * \defgroup bma456_tabletApiInit Initialization + * @brief Initialize the sensor and device structure + */ + +/*! + * \ingroup bma456_tabletApiInit + * \page bma456_tablet_api_bma456_tablet_init bma456_tablet_init + * \code + * int8_t bma456_tablet_init(struct bma4_dev *dev); + * \endcode + * @details This API is the entry point. + * Call this API before using all other APIs. + * This API reads the chip-id of the sensor and sets the resolution. + * + * @param[in,out] dev : Structure instance of bma4_dev + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +int8_t bma456_tablet_init(struct bma4_dev *dev); + +/** + * \ingroup bma456_tablet + * \defgroup bma456_tabletApiConfig Config + * @brief Configuration APIs + */ + +/*! + * \ingroup bma456_tabletApiConfig + * \page bma456_tablet_api_bma456_tablet_write_config_file bma456_tablet_write_config_file + * \code + * int8_t bma456_tablet_write_config_file(struct bma4_dev *dev); + * \endcode + * @details This API is used to upload the config file to enable the features of + * the sensor. + * + * @param[in] dev : Structure instance of bma4_dev. + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +int8_t bma456_tablet_write_config_file(struct bma4_dev *dev); + +/*! + * \ingroup bma456_tabletApiConfig + * \page bma456_tablet_api_bma456_tablet_get_version_config bma456_tablet_get_version_config + * \code + *int8_t bma456_tablet_get_version_config(uint16_t *config_major, uint16_t *config_minor, struct bma4_dev *dev); + * \endcode + * @details This API is used to get the config file major and minor information. + * + * @param[in] dev : Structure instance of bma4_dev. + * @param[out] config_major : Pointer to data buffer to store the config major. + * @param[out] config_minor : Pointer to data buffer to store the config minor. + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +int8_t bma456_tablet_get_version_config(uint16_t *config_major, uint16_t *config_minor, struct bma4_dev *dev); + +/*! + * \ingroup bma456_tabletApiConfig + * \page bma456_tablet_api_bma456_tablet_get_config_id bma456_tablet_get_config_id + * \code + * int8_t bma456_tablet_get_config_id(uint16_t *config_id, struct bma4_dev *dev); + * \endcode + * @details This API is used to get the configuration id of the sensor. + * + * @param[out] config_id : Pointer variable used to store the configuration id. + * @param[in] dev : Structure instance of bma4_dev. + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +int8_t bma456_tablet_get_config_id(uint16_t *config_id, struct bma4_dev *dev); + +/** + * \ingroup bma456_tablet + * \defgroup bma456_tabletApiMapInt Map / Unmap Interrupt + * @brief Map / Unmap user provided interrupt to interrupt pin1 or pin2 of the sensor + */ + +/*! + * \ingroup bma456_tabletApiMapInt + * \page bma456_tablet_api_bma456_tablet_map_interrupt bma456_tablet_map_interrupt + * \code + * int8_t bma456_tablet_map_interrupt(uint8_t int_line, uint16_t int_map, uint8_t enable, struct bma4_dev *dev); + * \endcode + * @details This API sets/unsets the user provided interrupt to either + * interrupt pin1 or pin2 in the sensor. + * + * @param[in] int_line: Variable to select either interrupt pin1 or pin2. + * + *@verbatim + * int_line | Macros + * ------------|------------------- + * 0x00 | BMA4_INTR1_MAP + * 0x01 | BMA4_INTR2_MAP + *@endverbatim + * + * @param[in] int_map : Variable to specify the interrupts. + * @param[in] enable : Variable to specify mapping or unmapping of interrupts. + * + *@verbatim + * enable | Macros + * --------|------------------- + * 0x00 | BMA4_DISABLE + * 0x01 | BMA4_ENABLE + *@endverbatim + * + * @param[in] dev : Structure instance of bma4_dev. + * + * @note Below macros specify the interrupts. + * + * Feature Interrupts + * - BMA456_TABLET_TAP_OUT_INT + * - BMA456_TABLET_ORIENTATION_INT + * - BMA456_TABLET_LOW_G_INT + * - BMA456_TABLET_ANY_MOT_INT + * - BMA456_TABLET_NO_MOT_INT + * - BMA456_TABLET_ERROR_INT + * + * Hardware Interrupts + * - BMA4_FIFO_FULL_INT + * - BMA4_FIFO_WM_INT + * - BMA4_MAG_DATA_RDY_INT + * - BMA4_ACCEL_DATA_RDY_INT + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +int8_t bma456_tablet_map_interrupt(uint8_t int_line, uint16_t int_map, uint8_t enable, struct bma4_dev *dev); + +/** + * \ingroup bma456_tablet + * \defgroup bma456_tabletApiIntS Interrupt Status + * @brief Read interrupt status of the sensor + */ + +/*! + * \ingroup bma456_tabletApiIntS + * \page bma456_tablet_api_bma456_tablet_read_int_status bma456_tablet_read_int_status + * \code + * int8_t bma456_tablet_read_int_status(uint16_t *int_status, struct bma4_dev *dev); + * \endcode + * @details This API reads the bma456 interrupt status from the sensor. + * + * @param[out] int_status : Variable to store the interrupt status read from + * the sensor. + * @param[in] dev : Structure instance of bma4_dev. + * + * @note Below macros are used to check the interrupt status. + * + * Feature Interrupts + * - BMA456_TABLET_TAP_OUT_INT + * - BMA456_TABLET_ORIENTATION_INT + * - BMA456_TABLET_LOW_G_INT + * - BMA456_TABLET_ANY_MOT_INT + * - BMA456_TABLET_NO_MOT_INT + * - BMA456_TABLET_ERROR_INT + * + * Hardware Interrupts + * - BMA4_FIFO_FULL_INT + * - BMA4_FIFO_WM_INT + * - BMA4_MAG_DATA_RDY_INT + * - BMA4_ACCEL_DATA_RDY_INT + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +int8_t bma456_tablet_read_int_status(uint16_t *int_status, struct bma4_dev *dev); + +/** + * \ingroup bma456_tablet + * \defgroup bma456_tabletApiFeat Sensor Feature + * @brief Enables / Disables features of the sensor + */ + +/*! + * \ingroup bma456_tabletApiFeat + * \page bma456_tablet_api_bma456_tablet_feature_enable bma456_tablet_feature_enable + * \code + * int8_t bma456_tablet_feature_enable(uint8_t feature, uint8_t enable, struct bma4_dev *dev); + * \endcode + * @details This API enables/disables the features of the sensor. + * + * @param[in] feature : Variable to specify the features which are to be set in + * bma456 sensor. + * @param[in] enable : Variable which specifies whether to enable or disable the + * features in the bma456 sensor. + * + *@verbatim + * enable | Macros + * --------|------------------- + * 0x00 | BMA4_DISABLE + * 0x01 | BMA4_ENABLE + *@endverbatim + * + * @param[in] dev : Structure instance of bma4_dev. + * + * @note User should use the below macros to enable or disable the + * features of bma456_tablet sensor + * + * - BMA456_TABLET_SINGLE_TAP + * - BMA456_TABLET_DOUBLE_TAP + * - BMA456_TABLET_TRIPLE_TAP + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +int8_t bma456_tablet_feature_enable(uint8_t feature, uint8_t enable, struct bma4_dev *dev); + +/** + * \ingroup bma456_tablet + * \defgroup bma456_tabletApiRemap Remap Axes + * @brief Set / Get x, y and z axis re-mapping in the sensor + */ + +/*! + * \ingroup bma456_tabletApiRemap + * \page bma456_tablet_api_bma456_tablet_set_remap_axes bma456_tablet_set_remap_axes + * \code + * int8_t bma456_tablet_set_remap_axes(const struct bma4_remap *remap_data, struct bma4_dev *dev); + * \endcode + * @details This API performs x, y and z axis remapping in the sensor. + * + * @param[in] remap_data : Pointer to store axes remapping data. + * @param[in] dev : Structure instance of bma4_dev + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +int8_t bma456_tablet_set_remap_axes(const struct bma4_remap *remap_data, struct bma4_dev *dev); + +/*! + * \ingroup bma456_tabletApiRemap + * \page bma456_tablet_api_bma456_tablet_get_remap_axes bma456_tablet_get_remap_axes + * \code + * int8_t bma456_tablet_get_remap_axes(struct bma4_remap *remap_data, struct bma4_dev *dev); + * \endcode + * @details This API reads the x, y and z axis remap data from the sensor. + * + * @param[out] remap_data : Pointer to store axis remap data which is read + * from the bma456 sensor. + * @param[in] dev : Structure instance of bma4_dev + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +int8_t bma456_tablet_get_remap_axes(struct bma4_remap *remap_data, struct bma4_dev *dev); + +/** + * \ingroup bma456_tablet + * \defgroup bma456_tabletApiAnyMot Any motion Feature + * @brief Functions of Any motion feature of the sensor + */ + +/*! + * \ingroup bma456_tabletApiAnyMot + * \page bma456_tablet_api_bma456_tablet_set_any_mot_config bma456_tablet_set_any_mot_config + * \code + * int8_t bma456_tablet_set_any_mot_config(const struct bma456_tablet_any_no_mot_config *any_mot, struct bma4_dev *dev); + * \endcode + * @details This API sets the configuration of any-motion feature in the sensor + * This API enables/disables the any-motion feature according to the axis set. + * + * @param[in] any_mot : Pointer to structure variable to configure + * any-motion. + * + * @verbatim + * ------------------------------------------------------------------------- + * Structure parameters | Description + * --------------------------------|---------------------------------------- + * | Defines the number of + * | consecutive data points for + * | which the threshold condition + * duration | must be respected, for interrupt + * | assertion. It is expressed in + * | 50 Hz samples (20 ms). + * | Range is 0 to 163sec. + * | Default value is 5 = 100ms. + * --------------------------------|---------------------------------------- + * | Slope threshold value for + * | Any-motion detection + * threshold | in 5.11g format. + * | Range is 0 to 1g. + * | Default value is 0xAA = 83mg. + * --------------------------------|---------------------------------------- + * | Enables the feature on a per-axis + * axis_en | basis. + * --------------------------------------------------------------------------- + * | Configuration for acceleration + * slope | scope computation. + * --------------------------------------------------------------------------- + * @endverbatim + * + *@verbatim + * Value | axis_en + * ---------|------------------------- + * 0x00 | BMA456_TABLET_DIS_ALL_AXIS + * 0x01 | BMA456_TABLET_X_AXIS_EN + * 0x02 | BMA456_TABLET_Y_AXIS_EN + * 0x04 | BMA456_TABLET_Z_AXIS_EN + * 0x07 | BMA456_TABLET_EN_ALL_AXIS + *@endverbatim + * + * @param[in] dev : Structure instance of bma4_dev + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +int8_t bma456_tablet_set_any_mot_config(const struct bma456_tablet_any_no_mot_config *any_mot, struct bma4_dev *dev); + +/*! + * \ingroup bma456_tabletApiAnyMot + * \page bma456_tablet_api_bma456_tablet_get_any_motion_config bma456_tablet_get_any_motion_config + * \code + * int8_t bma456_tablet_get_any_motion_config(struct bma456_tablet_anymotion_config *any_motion, struct bma4_dev *dev); + * \endcode + * @details This API gets the configuration of any-motion feature from the + * sensor. + * + * @param[out] any_mot : Pointer to structure variable to configure + * any-motion. + * + * @verbatim + * ------------------------------------------------------------------------- + * Structure parameters | Description + * --------------------------------|---------------------------------------- + * | Defines the number of + * | consecutive data points for + * | which the threshold condition + * duration | must be respected, for interrupt + * | assertion. It is expressed in + * | 50 Hz samples (20 ms). + * | Range is 0 to 163sec. + * | Default value is 5 = 100ms. + * --------------------------------|---------------------------------------- + * | Slope threshold value for + * | Any-motion detection + * threshold | in 5.11g format. + * | Range is 0 to 1g. + * | Default value is 0xAA = 83mg. + * --------------------------------|----------------------------------------- + * | Enables the feature on a per-axis + * axis_en | basis. + * --------------------------------------------------------------------------- + * | Configuration for acceleration + * slope | scope computation. + * --------------------------------------------------------------------------- + * @endverbatim + * + *@verbatim + * Value | axis_en + * ---------|------------------------- + * 0x00 | BMA456_TABLET_DIS_ALL_AXIS + * 0x01 | BMA456_TABLET_X_AXIS_EN + * 0x02 | BMA456_TABLET_Y_AXIS_EN + * 0x04 | BMA456_TABLET_Z_AXIS_EN + * 0x07 | BMA456_TABLET_EN_ALL_AXIS + *@endverbatim + * + * @param[in] dev : Structure instance of bma4_dev + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +int8_t bma456_tablet_get_any_mot_config(struct bma456_tablet_any_no_mot_config *any_mot, struct bma4_dev *dev); + +/** + * \ingroup bma456_tablet + * \defgroup bma456_tabletApiNomot No-Motion Feature + * @brief Operations of no-motion feature of the sensor + */ + +/*! + * \ingroup bma456_tabletApiNomot + * \page bma456_tablet_api_bma456_tablet_set_no_motion_config bma456_tablet_set_no_motion_config + * \code + * int8_t bma456_tablet_set_no_motion_config(const struct bma456_tablet_nomotion_config *no_motion, struct bma4_dev *dev); + * \endcode + * @details This API sets the configuration of no-motion feature in the sensor + * This API enables/disables the no-motion feature according to the axis set. + * + * @param[in] no_mot : Pointer to structure variable to configure + * no-motion. + * @verbatim + * ------------------------------------------------------------------------- + * Structure parameters | Description + * --------------------------------|---------------------------------------- + * | Defines the number of + * | consecutive data points for + * | which the threshold condition + * duration | must be respected, for interrupt + * | assertion. It is expressed in + * | 50 Hz samples (20 ms). + * | Range is 0 to 163sec. + * | Default value is 5 = 100ms. + * --------------------------------|---------------------------------------- + * | Slope threshold value for + * | No-motion detection + * threshold | in 5.11g format. + * | Range is 0 to 1g. + * | Default value is 0xAA = 83mg. + * --------------------------------|---------------------------------------- + * | Enables the feature on a per-axis + * axis_en | basis. + * --------------------------------------------------------------------------- + * @endverbatim + * + *@verbatim + * Value | axis_en + * ---------|------------------------- + * 0x00 | BMA456_TABLET_DIS_ALL_AXIS + * 0x01 | BMA456_TABLET_X_AXIS_EN + * 0x02 | BMA456_TABLET_Y_AXIS_EN + * 0x04 | BMA456_TABLET_Z_AXIS_EN + * 0x07 | BMA456_TABLET_EN_ALL_AXIS + *@endverbatim + * + * @param[in] dev : Structure instance of bma4_dev + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +int8_t bma456_tablet_set_no_mot_config(const struct bma456_tablet_any_no_mot_config *no_mot, struct bma4_dev *dev); + +/*! + * \ingroup bma456_tabletApiNomot + * \page bma456_tablet_api_bma456_tablet_get_no_motion_config bma456_tablet_get_no_motion_config + * \code + * int8_t bma456_tablet_get_no_motion_config(struct bma456_tablet_nomotion_config *no_motion, struct bma4_dev *dev); + * \endcode + * @details This API gets the configuration of no-motion feature from the + * sensor. + * + * @param[out] no_mot : Pointer to structure variable to configure + * no-motion. + * + * @verbatim + * ------------------------------------------------------------------------- + * Structure parameters | Description + * --------------------------------|---------------------------------------- + * | Defines the number of + * | consecutive data points for + * | which the threshold condition + * duration | must be respected, for interrupt + * | assertion. It is expressed in + * | 50 Hz samples (20 ms). + * | Range is 0 to 163sec. + * | Default value is 5 = 100ms. + * --------------------------------|---------------------------------------- + * | Slope threshold value for + * | No-motion detection + * threshold | in 5.11g format. + * | Range is 0 to 1g. + * | Default value is 0xAA = 83mg. + * --------------------------------|----------------------------------------- + * | Enables the feature on a per-axis + * axis_en | basis. + * --------------------------------------------------------------------------- + * @endverbatim + * + *@verbatim + * Value | axis_en + * ---------|------------------------- + * 0x00 | BMA456_TABLET_DIS_ALL_AXIS + * 0x01 | BMA456_TABLET_X_AXIS_EN + * 0x02 | BMA456_TABLET_Y_AXIS_EN + * 0x04 | BMA456_TABLET_Z_AXIS_EN + * 0x07 | BMA456_TABLET_EN_ALL_AXIS + *@endverbatim + * + * @param[in] dev : Structure instance of bma4_dev + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +int8_t bma456_tablet_get_no_mot_config(struct bma456_tablet_any_no_mot_config *no_mot, struct bma4_dev *dev); + +/** + * \ingroup bma456_tablet + * \defgroup bma456_tabletApOP Tap Output + * @brief Functions to provide tap feature output status + */ + +/*! + * \ingroup bma456_tabletApOP + * \page bma456_tablet_api_bma456_tablet_tap_output bma456_tablet_tap_output + * \code + * int8_t bma456_tablet_tap_output(struct bma456_tablet_tap_output *out_state, struct bma4_dev *dev); + * \endcode + * @details This API gets the output for tap(single, double, triple) feature. + * + * @param[out] out_state : Pointer variable which stores feature output values. + * @param[in] dev : Structure instance of bma4_dev + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +int8_t bma456_tablet_tap_output(struct bma456_tablet_tap_output *out_state, struct bma4_dev *dev); + +/** + * \ingroup bma456_tablet + * \defgroup bma456_tabletApiTap Tap Feature + * @brief Tap feature operations + */ + +/*! + * \ingroup bma456_tabletApiTap + * \page bma456_tablet_api_bma456_tablet_tap_get_parameter bma456_tablet_tap_get_parameter + * \code + * int8_t bma456_tablet_tap_get_parameter(struct bma456_tablet_tap_settings *setting, struct bma4_dev *dev); + * \endcode + * @details This API gets the tap parameter settings. + * + * @param[out] setting : Pointer to structure variable which stores the + * tap parameters read from the sensor + * @param[in] dev : Structure instance of bma4_dev + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +int8_t bma456_tablet_tap_get_parameter(struct bma456_tablet_tap_settings *setting, struct bma4_dev *dev); + +/*! + * \ingroup bma456_tabletApiTap + * \page bma456_tablet_api_bma456_tablet_tap_set_parameter bma456_tablet_tap_set_parameter + * \code + * int8_t bma456_tablet_tap_set_parameter(const struct bma456_tablet_tap_settings *setting, struct bma4_dev *dev); + * \endcode + * @details This API sets the tap parameter settings in the sensor. + * + * @param[in] setting : Pointer to structure variable which stores the + * tap parameter settings read from the sensor. + * @param[in] dev : Structure instance of bma4_dev + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +int8_t bma456_tablet_tap_set_parameter(const struct bma456_tablet_tap_settings *setting, struct bma4_dev *dev); + +/** + * \ingroup bma456_tablet + * \defgroup bma456_tabletApLowG Low-G Feature + * @brief Functions of Low-G feature of the sensor + */ + +/*! + * \ingroup bma456_tabletApLowG + * \page bma456_tablet_api_bma456_tablet_set_low_g_config bma456_tablet_set_low_g_config + * \code + * int8_t bma456_tablet_set_low_g_config(const struct bma456_tablet_low_g_config *low_g, struct bma4_dev *dev); + * \endcode + * @details This API sets the configuration of low-g feature of the sensor. + * + * @param[in] low_g : Pointer to structure variable used to + * store the low-g feature settings to be written to the sensor. + * + * Structure members are provided in the table below + * + *@verbatim + * ------------------------------------------------------------------------- + * Structure parameters | Description + * --------------------------------|---------------------------------------- + * | Threshold value for low-g feature. + * threshold | Range is 0 to 1g. + * | Default value is 512 = 0.25g. + * --------------------------------|---------------------------------------- + * | Hysteresis value for low_g feature. + * hysteresis | Range is 0 to 0.5g. + * | Default value is 256 = 0.125g. + * --------------------------------|---------------------------------------- + * | Duration in 50 Hz samples (20 msec) for + * duration | which the threshold has to be exceeded. + * | Range is 0 to 82 sec. + * | Default value is 0 = 0 ms. + * --------------------------------|---------------------------------------- + *@endverbatim + * + * @param[in] dev : Structure instance of bma4_dev + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +int8_t bma456_tablet_set_low_g_config(const struct bma456_tablet_low_g_config *low_g, struct bma4_dev *dev); + +/*! + * \ingroup bma456_tabletApLowG + * \page bma456_tablet_api_bma456_tablet_get_low_g_config bma456_tablet_get_low_g_config + * \code + * int8_t bma456_tablet_get_low_g_config(struct bma456_tablet_low_g_config *low_g, struct bma4_dev *dev); + * \endcode + * @details This API gets the configuration of significant motion feature + * from the sensor. + * + * @param[out] low_g : Pointer to structure variable used to + * store the low-g feature settings read from the sensor. + * + * Structure members are provided in the table below + * + *@verbatim + * ------------------------------------------------------------------------- + * Structure parameters | Description + * --------------------------------|---------------------------------------- + * | Threshold value for low-g feature. + * threshold | Range is 0 to 1g. + * | Default value is 512 = 0.25g. + * --------------------------------|---------------------------------------- + * | Hysteresis value for low_g feature. + * hysteresis | Range is 0 to 0.5g. + * | Default value is 256 = 0.125g. + * --------------------------------|---------------------------------------- + * | Duration in 50 Hz samples (20 msec) for + * duration | which the threshold has to be exceeded. + * | Range is 0 to 82 sec. + * | Default value is 0 = 0 ms. + * --------------------------------|---------------------------------------- + *@endverbatim + * + * @param[in] dev : Structure instance of bma4_dev + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +int8_t bma456_tablet_get_low_g_config(struct bma456_tablet_low_g_config *low_g, struct bma4_dev *dev); + +/** + * \ingroup bma456_tablet + * \defgroup bma456_tabletApiOrientation Orientation Feature + * @brief Functions of Orientation feature of the sensor + */ + +/*! + * \ingroup bma456_tabletApiOrientation + * \page bma456_tablet_api_bma456_tablet_set_orientation_config bma456_tablet_set_orientation_config + * \code + * int8_t bma456_tablet_set_orientation_config(struct bma456_tablet_orientation_config *orientation, struct bma4_dev *dev); + * \endcode + * @details This API sets the configuration of orientation feature of the sensor. + * + * @param[in] orientation : Pointer to structure variable used to + * store the orientation feature settings to be written to sensor. + * + * Structure members are provided in the table below + * + *@verbatim + * ------------------------------------------------------------------------- + * Structure parameters | Description + * --------------------------------|---------------------------------------- + * ud_en | Enables face upside/downside + * | detection if set to 1 + * --------------------------------|---------------------------------------- + * | symmetrical (values 0 or 3), + * mode | high asymmetrical (value 1) + * | or low asymmetrical (value 2). + * --------------------------------|---------------------------------------- + * | Sets the blocking mode. + * blocking | Default value is 4, the most + * | restrictive blocking mode. + * ------------------------------------------------------------------------- + * | The number of samples for which + * hold_time | the orientation should be stable + * | in 50Hz. Reolution: 5 = 100msecs + * ------------------------------------------------------------------------- + * slope_thres | The slope threshold for blocking + * | mode. Resolution: 0.4g = 205 lsbs + * ------------------------------------------------------------------------- + * | Hysteresis of acceleration for + * hysteresis | orientation change detection. + * | Resolution: 62.5mg = 32 lsbs + * ------------------------------------------------------------------------- + * | Coded value of the threshold angle + * | with horizontal used in blocking + * theta | modes, theta = 64 * (tan(angle)^2). + * | Default value is 40 which is + * | equivalent to 38 degrees angle. + * ------------------------------------------------------------------------- + *@endverbatim + * + * @param[in] dev : Structure instance of bma4_dev + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +int8_t bma456_tablet_set_orientation_config(const struct bma456_tablet_orientation_config *orientation, + struct bma4_dev *dev); + +/*! + * \ingroup bma456_tabletApiOrientation + * \page bma456_tablet_api_bma456_tablet_get_orientation_config bma456_tablet_get_orientation_config + * \code + * int8_t bma456_tablet_get_orientation_config(struct bma456_tablet_orientation_config *orientation, struct bma4_dev *dev); + * \endcode + * @details This API gets the configuration of orientation feature from the sensor. + * + * @param[out] orientation : Pointer to structure variable used to + * store the orientation feature settings read from the sensor. + * + * Structure members are provided in the table below + * + *@verbatim + * ------------------------------------------------------------------------- + * Structure parameters | Description + * --------------------------------|---------------------------------------- + * ud_en | Enables face upside/downside + * | detection if set to 1 + * --------------------------------|---------------------------------------- + * | symmetrical (values 0 or 3), + * mode | high asymmetrical (value 1) + * | or low asymmetrical (value 2). + * --------------------------------|---------------------------------------- + * | Sets the blocking mode. + * blocking | Default value is 4, the most + * | restrictive blocking mode. + * ------------------------------------------------------------------------- + * | The number of samples for which + * hold_time | the orientation should be stable + * | in 50Hz. Reolution: 5 = 100msecs + * ------------------------------------------------------------------------- + * slope_thres | The slope threshold for blocking + * | mode. Resolution: 0.4g = 205 lsbs + * ------------------------------------------------------------------------- + * | Hysteresis of acceleration for + * hysteresis | orientation change detection. + * | Resolution: 62.5mg = 32 lsbs + * ------------------------------------------------------------------------- + * | Coded value of the threshold angle + * | with horizontal used in blocking + * theta | modes, theta = 64 * (tan(angle)^2). + * | Default value is 40 which is + * | equivalent to 38 degrees angle. + * ------------------------------------------------------------------------- + *@endverbatim + * + * @param[in] dev : Structure instance of bma4_dev + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +int8_t bma456_tablet_get_orientation_config(struct bma456_tablet_orientation_config *orientation, struct bma4_dev *dev); + +/*! + * \ingroup bma422nApiOrient + * \page bma456_tablet_api_bma456_tablet_orientation_output bma456_tablet_orientation_output + * \code + * int8_t bma456_tablet_orientation_output(uint8_t *orientation_output, uint8_t *orientation_faceup_down, + * struct bma4_dev *dev); + * + * \endcode + * @details This API gets the output of orientation feature from the sensor. + * + * @param orientation_output : pointer used to store the orientation output. + * + *@verbatim + * orientation_output | Values + *-------------------------------|----------------------------- + * Bit pos 0-1 reflects | BMA456_TABLET_PORTRAIT_UP_RIGHT + * orientation output value | BMA456_TABLET_LANDSCAPE_LEFT + * only if ud_en is enabled | BMA456_TABLET_PORTRAIT_UP_DOWN + * | BMA456_TABLET_LANDSCAPE_RIGHT + *-------------------------------|----------------------------- + *@endverbatim + * + * @param orientation_faceup_down : Output value of face down face up orientation + * + *@verbatim + * orientation_faceup_down | Values + *-------------------------------|----------------------------- + * Bit pos 2 reflects | BMA456_TABLET_FACE_UP + * face-up (0) or face-down(1) | BMA456_TABLET_FACE_DOWN + * only if ud_en is enabled | + *-------------------------------|----------------------------- + *@endverbatim + * + * @param dev : Structure instance of bma4_dev + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +int8_t bma456_tablet_orientation_output(uint8_t *orientation_output, + uint8_t *orientation_faceup_down, + struct bma4_dev *dev); + +#ifdef __cplusplus +} +#endif /* End of CPP guard */ + +#endif /* End of header guard macro */ diff --git a/components/bma456/bma456_tablet_examples/accel_foc/Makefile b/components/bma456/bma456_tablet_examples/accel_foc/Makefile new file mode 100644 index 0000000..0e116f2 --- /dev/null +++ b/components/bma456/bma456_tablet_examples/accel_foc/Makefile @@ -0,0 +1,18 @@ +COINES_INSTALL_PATH ?= ../../../.. + +EXAMPLE_FILE ?= accel_foc.c + +API_LOCATION ?= ../.. + +COMMON_LOCATION ?= .. + +C_SRCS += \ +$(API_LOCATION)/bma4.c \ +$(API_LOCATION)/bma456_tablet.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/components/bma456/bma456_tablet_examples/accel_foc/accel_foc.c b/components/bma456/bma456_tablet_examples/accel_foc/accel_foc.c new file mode 100644 index 0000000..335e9e2 --- /dev/null +++ b/components/bma456/bma456_tablet_examples/accel_foc/accel_foc.c @@ -0,0 +1,735 @@ +/**\ + * Copyright (c) 2023 Bosch Sensortec GmbH. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + **/ + +/******************************************************************************/ +/*! Header Files */ +#include +#include +#include +#include +#include + +#include "bma456_tablet.h" +#include "common.h" +#include "coines.h" + +/******************************************************************************/ +/*! Macro Definitions */ + +#define ACCEL_SAMPLE_COUNT UINT8_C(100) + +/******************************************************************************/ +/*! Global Variable Declaration */ + +/* Structure to store temporary axes data values */ +struct temp_axes_val +{ + /* X data */ + int32_t x; + + /* Y data */ + int32_t y; + + /* Z data */ + int32_t z; +}; + +/******************************************************************************/ +/*! Static Function Declaration */ + +/*! + * @brief This internal API is used perform accel foc and determine limits based on range + * + * @param[in] range : Range of Accel + * @param[in] input_axis : Axis selected for Accel FOC + * @param[in,out] dev : Structure instance of bma4_dev. + * + * @return Status of execution. + */ +static int8_t perform_foc_range_test(uint8_t range, uint8_t input_axis, struct bma4_dev *dev); + +/*! + * @brief This internal API is to determine if average accel FOC data is within limits + * + * @param[in] avg_accel_foc_data : Average Accel FOC value + * @param[in] reference : Reference LSB based on Accel Range + * @param[in] foc_sign : Input sign of performed Accel FOC + * @param[in] min_val : Minimum acceptable LSB limit + * @param[in] max_val : Maximum acceptable LSB limit + * + * @return Status of execution. + */ +static int8_t accel_foc_report(int16_t avg_accel_foc_data, + int16_t reference, + uint8_t foc_sign, + int16_t min_val, + int16_t max_val); + +/*! + * @brief This internal API is to collect and verify accel sensor data + * + * @param[in] range : Value of Accel range + * @param[in] reference : Reference LSB based on Accel Range + * @param[in] matched_axis : Input Axis to perform Accel FOC + * @param[in] foc_sign : Input sign to perform Accel FOC + * @param[in,out] dev : Structure instance of bma4_dev. + * + * @return Status of execution. + */ +static int8_t verify_accel_foc_data(uint8_t range, + int16_t reference, + int8_t matched_axis, + uint8_t foc_sign, + struct bma4_dev *dev); + +/*! + * @brief This internal API is to calculate noise level for Accel FOC data + * + * @param[in] matched_axis : Input Axis to perform accel FOC + * @param[in] accel_foc_data : Array of Accel FOC data + * @param[in] avg_accel_foc_data : Average Accel FOC data + * + * @return Status of execution. + */ +static void calculate_noise(int8_t matched_axis, + const struct bma4_accel *accel_foc_data, + const struct bma4_accel avg_accel_foc_data); + +/******************************************************************************/ +/*! Functions */ + +/* This function starts the execution of program. */ +int main(void) +{ + /* Sensor initialization configuration. */ + struct bma4_dev dev; + + uint8_t try = 0, j; + int8_t rslt; + struct bma4_accel_config accel_conf = { 0 }; + uint8_t data = 0, range, input_axis = 0; + + /* Interface reference is given as a parameter + * For I2C : BMA4_I2C_INTF + * For SPI : BMA4_SPI_INTF + * Variant information given as parameter - BMA45X_VARIANT + */ + rslt = bma4_interface_init(&dev, BMA4_I2C_INTF, BMA45X_VARIANT); + bma4_error_codes_print_result("bma4_interface_init", rslt); + + printf("Functional test for accel foc start..\n\n"); + + printf("Choose the axis for accel FOC to be done\n"); + printf("Press '1' to choose X axis\n"); + printf("Press '2' to choose Y axis\n"); + printf("Press '3' to choose Z axis\n"); + + printf("Press '4' to choose -X axis\n"); + printf("Press '5' to choose -Y axis\n"); + printf("Press '6' to choose -Z axis\n"); + + for (;;) + { + scanf("%u", (unsigned int *)&input_axis); + if (input_axis > 0 && input_axis < 7) + { + break; + } + } + + if (input_axis == 1) + { + printf("The choosen input axis for FOC is : X\n"); + } + else if (input_axis == 2) + { + printf("The choosen input axis for FOC is : Y\n"); + } + else if (input_axis == 3) + { + printf("The choosen input axis for FOC is : Z\n"); + } + else if (input_axis == 4) + { + printf("The choosen input axis for FOC is : -X\n"); + } + else if (input_axis == 5) + { + printf("The choosen input axis for FOC is : -Y\n"); + } + else if (input_axis == 6) + { + printf("The choosen input axis for FOC is : -Z\n"); + } + + printf("Confirm your chosen axis and the sensor keeping position are same before doing FOC\n"); + + for (j = 0; j < 2; j++) + { + try = 0; + + if (j == 1) + { + printf("Keep sensor in wrong position and press 5\n"); + } + else if (j == 0) + { + printf("Keep sensor in right position and press 5\n"); + } + + for (;;) + { + scanf("%hu", (short unsigned int *)&try); + if (try == 5) + { + break; + } + } + + for (range = BMA4_ACCEL_RANGE_2G; range <= BMA4_ACCEL_RANGE_16G; range++) + { + /****************************************************************/ + /* Initialize by enabling configuration load */ + printf("#########################################################\n\n"); + + rslt = bma456_tablet_init(&dev); + bma4_error_codes_print_result("bma456_tablet_init", rslt); + + /* Upload the configuration file to enable the features of the sensor. */ + rslt = bma456_tablet_write_config_file(&dev); + bma4_error_codes_print_result("bma456_tablet_write_config_file", rslt); + + /* Enable the accelerometer */ + rslt = bma4_set_accel_enable(BMA4_ENABLE, &dev); + bma4_error_codes_print_result("bma4_set_accel_enable status", rslt); + + /* Accelerometer Configuration Settings */ + /* Output Data Rate */ + accel_conf.odr = BMA4_OUTPUT_DATA_RATE_50HZ; + + /* Gravity range of the sensor (+/- 2G, 4G, 8G, 16G) */ + accel_conf.range = range; + + /* The bandwidth parameter is used to configure the number of sensor samples that are averaged + * if it is set to 2, then 2^(bandwidth parameter) samples + * are averaged, resulting in 4 averaged samples + * Note1 : For more information, refer the datasheet. + * Note2 : A higher number of averaged samples will result in a less noisier signal, but + * this has an adverse effect on the power consumed. + */ + accel_conf.bandwidth = BMA4_ACCEL_NORMAL_AVG4; + + /* Enable the filter performance mode where averaging of samples + * will be done based on above set bandwidth and ODR. + * There are two modes + * 0 -> Averaging samples (Default) + * 1 -> No averaging + * For more info on No Averaging mode refer datasheet. + */ + accel_conf.perf_mode = BMA4_CIC_AVG_MODE; + + /* Set the accel configurations */ + rslt = bma4_set_accel_config(&accel_conf, &dev); + bma4_error_codes_print_result("bma4_set_accel_config status", rslt); + + /* Mapping data ready interrupt with interrupt1 to get interrupt status once getting new accel data */ + rslt = bma456_tablet_map_interrupt(BMA4_INTR1_MAP, BMA4_DATA_RDY_INT, BMA4_ENABLE, &dev); + bma4_error_codes_print_result("bma456_tablet_map_interrupt status", rslt); + + printf("ODR = %d, RANGE = %d, BANDWIDTH = %d\n", accel_conf.odr, accel_conf.range, accel_conf.bandwidth); + + /* Perform FOC for different ranges */ + rslt = perform_foc_range_test(range, input_axis, &dev); + + if ((j == 1) && (rslt == BMA4_E_OUT_OF_RANGE)) + { + printf("\n######### Valid input - Wrong position #########\n\n"); + bma4_error_codes_print_result("perform_foc_range_test", rslt); + } + else if ((j == 0) && (rslt == BMA4_OK)) + { + printf("\n######### Valid input - Right position #########\n\n"); + bma4_error_codes_print_result("perform_foc_range_test", rslt); + } + else if ((j == 1) && (rslt == BMA4_OK)) + { + printf("\n######### Invalid input - Right position #########\n\n"); + bma4_error_codes_print_result("perform_foc_range_test", rslt); + } + else if ((j == 0) && (rslt == BMA4_E_OUT_OF_RANGE)) + { + printf("\n######### Invalid input - Wrong position #########\n\n"); + bma4_error_codes_print_result("perform_foc_range_test", rslt); + } + else if ((j == 0) && (rslt == BMA4_E_OUT_OF_RANGE)) + { + printf("\n######### Valid input - Right position #########\n\n"); + printf("\n######### Before FOC is better than after FOC #########\n\n"); + bma4_error_codes_print_result("perform_foc_range_test", rslt); + } + else if ((j == 1) && (rslt == BMA4_E_OUT_OF_RANGE)) + { + printf("\n######### Invalid input - Right position #########\n\n"); + printf("\n######### Before FOC is better than after FOC #########\n\n"); + bma4_error_codes_print_result("perform_foc_range_test", rslt); + } + } + + /* Disable offset compensation */ + rslt = bma4_read_regs(BMA4_NV_CONFIG_ADDR, &data, 1, &dev); + bma4_error_codes_print_result("bma4_read_regs", rslt); + + data = BMA4_SET_BIT_VAL_0(data, BMA4_NV_ACCEL_OFFSET); + + rslt = bma4_write_regs(BMA4_NV_CONFIG_ADDR, &data, 1, &dev); + bma4_error_codes_print_result("bma4_write_regs", rslt); + } + + bma4_coines_deinit(); + + return rslt; +} + +static int8_t accel_foc_report(int16_t avg_accel_foc_data, + int16_t reference, + uint8_t foc_sign, + int16_t min_val, + int16_t max_val) +{ + int8_t rslt = BMA4_OK; + int16_t diff_after = 0; + + if (foc_sign == 0) + { + if ((avg_accel_foc_data >= (min_val)) && (avg_accel_foc_data <= (max_val))) + { + if (avg_accel_foc_data >= reference) + { + diff_after = avg_accel_foc_data - reference; + } + else + { + diff_after = reference - avg_accel_foc_data; + } + + printf("\n# ********** PASS | Difference = %d **********\n", diff_after); + printf("\n# Avg_FOC %d in range\n", avg_accel_foc_data); + rslt = BMA4_OK; + } + else + { + if (avg_accel_foc_data >= reference) + { + diff_after = avg_accel_foc_data - reference; + } + else + { + diff_after = reference - avg_accel_foc_data; + } + + printf("\n# ********** FAIL | Difference = %d **********\n", diff_after); + printf("\n# Avg_FOC %d not in range\n", avg_accel_foc_data); + rslt = BMA4_E_OUT_OF_RANGE; + } + } + + if (foc_sign == 1) + { + if ((avg_accel_foc_data <= (min_val)) && (avg_accel_foc_data >= (max_val))) + { + if (avg_accel_foc_data <= reference) + { + diff_after = avg_accel_foc_data - reference; + } + else + { + diff_after = reference - avg_accel_foc_data; + } + + printf("\n# ********** PASS | Difference = %d **********\n", diff_after); + printf("\n# Avg_FOC %d in range\n", avg_accel_foc_data); + rslt = BMA4_OK; + } + else + { + if (avg_accel_foc_data <= reference) + { + diff_after = avg_accel_foc_data - reference; + } + else + { + diff_after = reference - avg_accel_foc_data; + } + + printf("\n# ********** FAIL | Difference = %d **********\n", diff_after); + printf("\n# Avg_FOC %d not in range\n", avg_accel_foc_data); + rslt = BMA4_E_OUT_OF_RANGE; + } + } + + return rslt; +} + +static void calculate_noise(int8_t matched_axis, + const struct bma4_accel *accel_foc_data, + const struct bma4_accel avg_accel_foc_data) +{ + int32_t variance = 0; + double noise_level; + uint16_t idx = 0; + + if (matched_axis == 'X') + { + for (idx = 0; idx < ACCEL_SAMPLE_COUNT; idx++) + { + variance += + ((accel_foc_data[idx].x - avg_accel_foc_data.x) * (accel_foc_data[idx].x - avg_accel_foc_data.x)); + } + } + else if (matched_axis == 'Y') + { + for (idx = 0; idx < ACCEL_SAMPLE_COUNT; idx++) + { + variance += + ((accel_foc_data[idx].y - avg_accel_foc_data.y) * (accel_foc_data[idx].y - avg_accel_foc_data.y)); + } + } + else if (matched_axis == 'Z') + { + for (idx = 0; idx < ACCEL_SAMPLE_COUNT; idx++) + { + variance += + ((accel_foc_data[idx].z - avg_accel_foc_data.z) * (accel_foc_data[idx].z - avg_accel_foc_data.z)); + } + } + + noise_level = sqrt((double)variance); + + printf("\n# ********** NOISE LEVEL = %lf **********\n", noise_level); +} + +static int8_t verify_accel_foc_data(uint8_t range, + int16_t reference, + int8_t matched_axis, + uint8_t foc_sign, + struct bma4_dev *dev) +{ + int8_t rslt = BMA4_E_INVALID_STATUS; + uint8_t i; + uint16_t reg_status = 0; + int16_t xl, yl, zl; + int16_t xh, yh, zh; + int16_t min_val = 0; + int16_t max_val = 0; + struct bma4_accel accel_foc_data[ACCEL_SAMPLE_COUNT] = { { 0 } }; + struct temp_axes_val temp_foc_data = { 0 }; + struct bma4_accel avg_accel_foc_data = { 0 }; + struct bma4_accel sensor_data = { 0 }; + + /* Setting initial values */ + xl = yl = zl = 32767; + xh = yh = zh = -32768; + + /* Read accelerometer values before/after FOC */ + for (i = 0; i < ACCEL_SAMPLE_COUNT; i++) + { + for (;;) + { + /* To get the data ready interrupt status */ + rslt = bma4_read_int_status(®_status, dev); + bma4_error_codes_print_result("bma4_read_int_status", rslt); + + /* Read accelerometer data based on data ready interrupt */ + if ((rslt == BMA4_OK) && (reg_status & BMA4_ACCEL_DATA_RDY_INT)) + { + rslt = bma4_read_accel_xyz(&sensor_data, dev); + bma4_error_codes_print_result("bma4_read_accel_xyz", rslt); + + memcpy(&accel_foc_data[i], &sensor_data, sizeof(struct bma4_accel)); + + printf("X[%d] = %5d Y[%d] = %5d Z[%d] = %5d\n", + i, + accel_foc_data[i].x, + i, + accel_foc_data[i].y, + i, + accel_foc_data[i].z); + + if (xl > accel_foc_data[i].x) + { + xl = accel_foc_data[i].x; + } + + if (xh < accel_foc_data[i].x) + { + xh = accel_foc_data[i].x; + } + + if (yl > accel_foc_data[i].y) + { + yl = accel_foc_data[i].y; + } + + if (yh < accel_foc_data[i].y) + { + yh = accel_foc_data[i].y; + } + + if (zl > accel_foc_data[i].z) + { + zl = accel_foc_data[i].z; + } + + if (zh < accel_foc_data[i].z) + { + zh = accel_foc_data[i].z; + } + + temp_foc_data.x += accel_foc_data[i].x; + temp_foc_data.y += accel_foc_data[i].y; + temp_foc_data.z += accel_foc_data[i].z; + break; + + } + } + } + + /* Taking average values to calculate percentage deviation */ + avg_accel_foc_data.x = (int16_t)(temp_foc_data.x / ACCEL_SAMPLE_COUNT); + avg_accel_foc_data.y = (int16_t)(temp_foc_data.y / ACCEL_SAMPLE_COUNT); + avg_accel_foc_data.z = (int16_t)(temp_foc_data.z / ACCEL_SAMPLE_COUNT); + + printf("********* MIN & MAX VALUES ********\n"); + + printf("XL = %5d YL = %5d ZL = %5d\n", xl, yl, zl); + printf("XH = %5d YH = %5d ZH = %5d\n", xh, yh, zh); + + printf("***** AVERAGE AFTER FOC *****\n"); + printf("Avg-X = %d Avg-Y = %d Avg-Z = %d\n", + avg_accel_foc_data.x, + avg_accel_foc_data.y, + avg_accel_foc_data.z); + + /* Calculate noise level */ + calculate_noise(matched_axis, accel_foc_data, avg_accel_foc_data); + + /* "zero-g offset" of accel is +/- 20 mg for all ranges as per datasheet (for 12-bit resolution) */ + if (range == 0) + { + /* Min and Max limits for Range 2G */ + min_val = BMA4_12BIT_ACC_2G_MIN_NOISE_LIMIT; + max_val = BMA4_12BIT_ACC_2G_MAX_NOISE_LIMIT; + } + else if (range == 1) + { + /* Min and Max limits for Range 4G */ + min_val = BMA4_12BIT_ACC_4G_MIN_NOISE_LIMIT; + max_val = BMA4_12BIT_ACC_4G_MAX_NOISE_LIMIT; + } + else if (range == 2) + { + /* Min and Max limits for Range 8G */ + min_val = BMA4_12BIT_ACC_8G_MIN_NOISE_LIMIT; + max_val = BMA4_12BIT_ACC_8G_MAX_NOISE_LIMIT; + } + else if (range == 3) + { + /* Min and Max limits for Range 16G */ + min_val = BMA4_12BIT_ACC_16G_MIN_NOISE_LIMIT; + max_val = BMA4_12BIT_ACC_16G_MAX_NOISE_LIMIT; + } + + if ((matched_axis == 'X') && (foc_sign == 0)) + { + rslt = accel_foc_report(avg_accel_foc_data.x, reference, foc_sign, min_val, max_val); + printf("Range : %u Avg_FOC-X : %d Reference : %d Min_Value : %d Max_Value : %d\n", + range, + avg_accel_foc_data.x, + reference, + min_val, + max_val); + } + else if ((matched_axis == 'Y') && (foc_sign == 0)) + { + rslt = accel_foc_report(avg_accel_foc_data.y, reference, foc_sign, min_val, max_val); + printf("Range : %u Avg_FOC-X : %d Reference : %d Min_Value : %d Max_Value : %d\n", + range, + avg_accel_foc_data.y, + reference, + min_val, + max_val); + } + else if ((matched_axis == 'Z') && (foc_sign == 0)) + { + rslt = accel_foc_report(avg_accel_foc_data.z, reference, foc_sign, min_val, max_val); + printf("Range : %u Avg_FOC-X : %d Reference : %d Min_Value : %d Max_Value : %d\n", + range, + avg_accel_foc_data.z, + reference, + min_val, + max_val); + } + else if ((matched_axis == 'X') && (foc_sign == 1)) + { + rslt = accel_foc_report(avg_accel_foc_data.x, + (int16_t)(reference * (-1)), + foc_sign, + (int16_t)(min_val * (-1)), + (int16_t)(max_val * (-1))); + printf("Range : %u Avg_FOC-X : %d Reference : %d Min_Value : %d Max_Value : %d\n", + range, + avg_accel_foc_data.x, + (reference * (-1)), + (min_val * (-1)), + (max_val * (-1))); + } + else if ((matched_axis == 'Y') && (foc_sign == 1)) + { + rslt = accel_foc_report(avg_accel_foc_data.y, + (int16_t)(reference * (-1)), + foc_sign, + (int16_t)(min_val * (-1)), + (int16_t)(max_val * (-1))); + printf("Range : %u Avg_FOC-X : %d Reference : %d Min_Value : %d Max_Value : %d\n", + range, + avg_accel_foc_data.y, + (reference * (-1)), + (min_val * (-1)), + (max_val * (-1))); + } + else if ((matched_axis == 'Z') && (foc_sign == 1)) + { + rslt = accel_foc_report(avg_accel_foc_data.z, + (int16_t)(reference * (-1)), + foc_sign, + (int16_t)(min_val * (-1)), + (int16_t)(max_val * (-1))); + printf("Range : %u Avg_FOC-X : %d Reference : %d Min_Value : %d Max_Value : %d\n", + range, + avg_accel_foc_data.z, + (reference * (-1)), + (min_val * (-1)), + (max_val * (-1))); + } + + return rslt; +} + +/* Perform FOC for different range and resolutions */ +static int8_t perform_foc_range_test(uint8_t range, uint8_t input_axis, struct bma4_dev *dev) +{ + int8_t rslt; + int8_t matched_axis = 0; + int16_t reference = 0; + + /* Set accel foc axis and it's sign (x, y, z, sign)*/ + struct bma4_accel_foc_g_value g_value_foc = { 0, 0, 0, 0 }; + + if (input_axis == 1) + { + g_value_foc.x = 1; + g_value_foc.y = 0; + g_value_foc.z = 0; + g_value_foc.sign = 0; + } + else if (input_axis == 2) + { + g_value_foc.x = 0; + g_value_foc.y = 1; + g_value_foc.z = 0; + g_value_foc.sign = 0; + } + else if (input_axis == 3) + { + g_value_foc.x = 0; + g_value_foc.y = 0; + g_value_foc.z = 1; + g_value_foc.sign = 0; + } + else if (input_axis == 4) + { + g_value_foc.x = 1; + g_value_foc.y = 0; + g_value_foc.z = 0; + g_value_foc.sign = 1; + } + else if (input_axis == 5) + { + g_value_foc.x = 0; + g_value_foc.y = 1; + g_value_foc.z = 0; + g_value_foc.sign = 1; + } + else if (input_axis == 6) + { + g_value_foc.x = 0; + g_value_foc.y = 0; + g_value_foc.z = 1; + g_value_foc.sign = 1; + } + + switch (range) + { + /* Reference LSB value of 2G */ + case 0: + reference = BMA4_12BIT_ACC_FOC_2G_REF; + break; + + /* Reference LSB value of 4G */ + case 1: + reference = BMA4_12BIT_ACC_FOC_4G_REF; + break; + + /* Reference LSB value of 8G */ + case 2: + reference = BMA4_12BIT_ACC_FOC_8G_REF; + break; + + /* Reference LSB value of 16G */ + case 3: + reference = BMA4_12BIT_ACC_FOC_16G_REF; + break; + default: + break; + } + + if (g_value_foc.x == 1) + { + matched_axis = 'X'; + } + else if (g_value_foc.y == 1) + { + matched_axis = 'Y'; + } + else if (g_value_foc.z == 1) + { + matched_axis = 'Z'; + } + + if (g_value_foc.sign == 1) + { + printf("MATCHED AXIS is = -%c\n", matched_axis); + } + else + { + printf("MATCHED AXIS is = %c\n", matched_axis); + } + + printf("\n\n# Before FOC\n"); + rslt = verify_accel_foc_data(range, reference, matched_axis, g_value_foc.sign, dev); + bma4_error_codes_print_result("bma4_perform_accel_foc", rslt); + + printf("\n\n######### Perform Accel FOC #########\n\n"); + + /* Perform accelerometer FOC */ + rslt = bma4_perform_accel_foc(&g_value_foc, dev); + bma4_error_codes_print_result("bma4_perform_accel_foc", rslt); + + printf("\n\n# After FOC\n"); + rslt = verify_accel_foc_data(range, reference, matched_axis, g_value_foc.sign, dev); + + return rslt; +} diff --git a/components/bma456/bma456_tablet_examples/accelerometer/Makefile b/components/bma456/bma456_tablet_examples/accelerometer/Makefile new file mode 100644 index 0000000..ee18302 --- /dev/null +++ b/components/bma456/bma456_tablet_examples/accelerometer/Makefile @@ -0,0 +1,18 @@ +COINES_INSTALL_PATH ?= ../../../.. + +EXAMPLE_FILE ?= accelerometer.c + +API_LOCATION ?= ../.. + +COMMON_LOCATION ?= .. + +C_SRCS += \ +$(API_LOCATION)/bma4.c \ +$(API_LOCATION)/bma456_tablet.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/components/bma456/bma456_tablet_examples/accelerometer/accelerometer.c b/components/bma456/bma456_tablet_examples/accelerometer/accelerometer.c new file mode 100644 index 0000000..77c0a3c --- /dev/null +++ b/components/bma456/bma456_tablet_examples/accelerometer/accelerometer.c @@ -0,0 +1,163 @@ +/**\ + * Copyright (c) 2023 Bosch Sensortec GmbH. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + **/ + +#include +#include "bma456_tablet.h" +#include "common.h" + +/******************************************************************************/ +/*! Macro definition */ + +/*! Earth's gravity in m/s^2 */ +#define GRAVITY_EARTH (9.80665f) + +/*! Macro that holds the total number of accel x,y and z axes sample counts to be printed */ +#define ACCEL_SAMPLE_COUNT UINT8_C(100) + +/******************************************************************************/ +/*! 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); + +/******************************************************************************/ +/*! Functions */ + +/* This function starts the execution of program. */ +int main(void) +{ + /* Variable to store the status of API */ + int8_t rslt; + + /* Sensor initialization configuration */ + struct bma4_dev bma = { 0 }; + + /* Variable to store accel data ready interrupt status */ + uint16_t int_status = 0; + + /* Variable that holds the accelerometer sample count */ + uint8_t n_data = 1; + + struct bma4_accel sens_data = { 0 }; + float x = 0, y = 0, z = 0; + struct bma4_accel_config accel_conf = { 0 }; + + /* Interface reference is given as a parameter + * For I2C : BMA4_I2C_INTF + * For SPI : BMA4_SPI_INTF + * Variant information given as parameter - BMA45X_VARIANT + */ + rslt = bma4_interface_init(&bma, BMA4_I2C_INTF, BMA45X_VARIANT); + bma4_error_codes_print_result("bma4_interface_init", rslt); + + /* Sensor initialization */ + rslt = bma456_tablet_init(&bma); + bma4_error_codes_print_result("bma456_tablet_init status", rslt); + + /* Upload the configuration file to enable the features of the sensor. */ + rslt = bma456_tablet_write_config_file(&bma); + bma4_error_codes_print_result("bma456_tablet_write_config status", rslt); + + /* Accelerometer configuration settings */ + /* Output data Rate */ + accel_conf.odr = BMA4_OUTPUT_DATA_RATE_50HZ; + + /* Gravity range of the sensor (+/- 2G, 4G, 8G, 16G) */ + accel_conf.range = BMA4_ACCEL_RANGE_2G; + + /* The bandwidth parameter is used to configure the number of sensor samples that are averaged + * if it is set to 2, then 2^(bandwidth parameter) samples + * are averaged, resulting in 4 averaged samples + * Note1 : For more information, refer the datasheet. + * Note2 : A higher number of averaged samples will result in a less noisier signal, but + * this has an adverse effect on the power consumed. + */ + accel_conf.bandwidth = BMA4_ACCEL_NORMAL_AVG4; + + /* Enable the filter performance mode where averaging of samples + * will be done based on above set bandwidth and ODR. + * There are two modes + * 0 -> Averaging samples (Default) + * 1 -> No averaging + * For more info on No Averaging mode refer datasheet. + */ + accel_conf.perf_mode = BMA4_CIC_AVG_MODE; + + /* Set the accel configurations */ + rslt = bma4_set_accel_config(&accel_conf, &bma); + bma4_error_codes_print_result("bma4_set_accel_config status", rslt); + + /* NOTE : Enable accel after set of configurations */ + rslt = bma4_set_accel_enable(BMA4_ENABLE, &bma); + bma4_error_codes_print_result("bma4_set_accel_enable status", rslt); + + /* Mapping data ready interrupt with interrupt pin 1 to get interrupt status once getting new accel data */ + rslt = bma456_tablet_map_interrupt(BMA4_INTR1_MAP, BMA4_DATA_RDY_INT, BMA4_ENABLE, &bma); + bma4_error_codes_print_result("bma456_tablet_map_interrupt status", rslt); + + printf("Data, Acc_Raw_X, Acc_Raw_Y, Acc_Raw_Z, Acc_ms2_X, Acc_ms2_Y, Acc_ms2_Z\n"); + + for (;;) + { + /* Read interrupt status */ + rslt = bma456_tablet_read_int_status(&int_status, &bma); + bma4_error_codes_print_result("bma456_tablet_read_int_status", rslt); + + /* Filtering only the accel data ready interrupt */ + if ((rslt == BMA4_OK) && (int_status & BMA4_ACCEL_DATA_RDY_INT)) + { + /* Read the accel x, y, z data */ + rslt = bma4_read_accel_xyz(&sens_data, &bma); + bma4_error_codes_print_result("bma4_read_accel_xyz status", rslt); + + if (rslt == BMA4_OK) + { + + /* Converting lsb to meter per second squared for 12 bit resolution at 2G range */ + x = lsb_to_ms2(sens_data.x, (float)2, bma.resolution); + y = lsb_to_ms2(sens_data.y, (float)2, bma.resolution); + z = lsb_to_ms2(sens_data.z, (float)2, bma.resolution); + + /* Print the data in m/s2 */ + printf("%d, %d, %d, %d, %4.2f, %4.2f, %4.2f\n", n_data, sens_data.x, sens_data.y, sens_data.z, x, y, z); + } + + /* Increment the count that determines the number of samples to be printed */ + n_data++; + + /* When the count reaches more than ACCEL_SAMPLE_COUNT, break and exit the loop */ + if (n_data > ACCEL_SAMPLE_COUNT) + { + break; + } + } + } + + bma4_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/components/bma456/bma456_tablet_examples/axis_remap/Makefile b/components/bma456/bma456_tablet_examples/axis_remap/Makefile new file mode 100644 index 0000000..5c938dc --- /dev/null +++ b/components/bma456/bma456_tablet_examples/axis_remap/Makefile @@ -0,0 +1,18 @@ +COINES_INSTALL_PATH ?= ../../../.. + +EXAMPLE_FILE = axis_remap.c + +API_LOCATION ?= ../.. + +COMMON_LOCATION ?= .. + +C_SRCS += \ +$(API_LOCATION)/bma4.c \ +$(API_LOCATION)/bma456_tablet.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/components/bma456/bma456_tablet_examples/axis_remap/axis_remap.c b/components/bma456/bma456_tablet_examples/axis_remap/axis_remap.c new file mode 100644 index 0000000..a2df2f8 --- /dev/null +++ b/components/bma456/bma456_tablet_examples/axis_remap/axis_remap.c @@ -0,0 +1,356 @@ +/**\ + * Copyright (c) 2023 Bosch Sensortec GmbH. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + **/ + +#include +#include + +#include "coines.h" +#include "bma456_tablet.h" +#include "common.h" + +/*********************************************************************/ +/* functions */ +/*********************************************************************/ + +/*! + * @brief Main Function where the execution getting started to test the code. + */ +int main(void) +{ + int8_t rslt; + struct bma4_dev bma4; + struct bma4_remap remap_data = { 0 }; + struct bma4_accel accel = { 0 }; + struct bma4_accel_config accel_conf = { 0 }; + uint16_t int_status = 0; + + char data_array[13][11] = + { { 0 }, { "BMA4_X" }, { "BMA4_Y" }, { 0 }, { "BMA4_Z" }, { 0 }, { 0 }, { 0 }, { 0 }, { "BMA4_NEG_X" }, + { "BMA4_NEG_Y" }, { 0 }, { "BMA4_NEG_Z" } }; + + /* Interface reference is given as a parameter + * For I2C : BMA4_I2C_INTF + * For SPI : BMA4_SPI_INTF + * Variant information given as parameter - BMA45X_VARIANT + */ + rslt = bma4_interface_init(&bma4, BMA4_I2C_INTF, BMA45X_VARIANT); + bma4_error_codes_print_result("bma4_interface_init", rslt); + + /* Sensor initialization */ + rslt = bma456_tablet_init(&bma4); + bma4_error_codes_print_result("bma456_tablet_init", rslt); + + /* Upload the configuration file to enable the features of the sensor. */ + rslt = bma456_tablet_write_config_file(&bma4); + bma4_error_codes_print_result("bma456_tablet_write_config", rslt); + + /* Accelerometer configuration Setting */ + /* Output data Rate */ + accel_conf.odr = BMA4_OUTPUT_DATA_RATE_50HZ; + + /* Gravity range of the sensor (+/- 2G, 4G, 8G, 16G) */ + accel_conf.range = BMA4_ACCEL_RANGE_2G; + + /* The bandwidth parameter is used to configure the number of sensor samples that are averaged + * if it is set to 2, then 2^(bandwidth parameter) samples + * are averaged, resulting in 4 averaged samples + * Note1 : For more information, refer the datasheet. + * Note2 : A higher number of averaged samples will result in a less noisier signal, but + * this has an adverse effect on the power consumed. + */ + accel_conf.bandwidth = BMA4_ACCEL_NORMAL_AVG4; + + /* Enable the filter performance mode where averaging of samples + * will be done based on above set bandwidth and ODR. + * There are two modes + * 0 -> Averaging samples (Default) + * 1 -> No averaging + * For more info on No Averaging mode refer datasheet. + */ + accel_conf.perf_mode = BMA4_CIC_AVG_MODE; + + /* Set the accel configurations */ + rslt = bma4_set_accel_config(&accel_conf, &bma4); + bma4_error_codes_print_result("bma4_set_accel_config status", rslt); + + /* NOTE : Enable accel after set of configurations */ + rslt = bma4_set_accel_enable(BMA4_ENABLE, &bma4); + bma4_error_codes_print_result("bma4_set_accel_enable status", rslt); + + /* Mapping data ready interrupt with interrupt pin 1 to get interrupt status once getting new accel data */ + rslt = bma456_tablet_map_interrupt(BMA4_INTR1_MAP, BMA4_DATA_RDY_INT, BMA4_ENABLE, &bma4); + bma4_error_codes_print_result("bma456_tablet_map_interrupt status", rslt); + + printf("\nAXIS_REMAP_FUNC_TEST 1\n"); + printf("Get sensor data of re-mapped axes\n"); + + rslt = bma456_tablet_get_remap_axes(&remap_data, &bma4); + bma4_error_codes_print_result("bma456_tablet_get_remap_axes", rslt); + + printf("Re-mapped x value = %s\n", data_array[remap_data.x]); + printf("Re-mapped y value = %s\n", data_array[remap_data.y]); + printf("Re-mapped z value = %s\n", data_array[remap_data.z]); + + printf("Expected Re-mapped x value = BMA4_X\n"); + printf("Expected Re-mapped y value = BMA4_Y\n"); + printf("Expected Re-mapped z value = BMA4_Z\n"); + + if ((remap_data.x == BMA4_X) && (remap_data.y == BMA4_Y) && (remap_data.z == BMA4_Z)) + { + printf(">> PASS\n"); + } + else + { + printf(">> FAIL\n"); + } + + printf("Print mapped data\n"); + + for (;;) + { + /* Read interrupt status */ + rslt = bma456_tablet_read_int_status(&int_status, &bma4); + bma4_error_codes_print_result("bma456_tablet_read_int_status", rslt); + + /* Filtering only the accel data ready interrupt */ + if ((rslt == BMA4_OK) && (int_status & BMA4_ACCEL_DATA_RDY_INT)) + { + rslt = bma4_read_accel_xyz(&accel, &bma4); + bma4_error_codes_print_result("bma4_read_accel_xyz", rslt); + + printf("Accel :: X = %d Y = %d Z = %d\n", accel.x, accel.y, accel.z); + + break; + } + } + + printf("\nAXIS_REMAP_FUNC_TEST 2\n"); + printf("Get sensor data of re-mapped axes\n"); + + remap_data.x = BMA4_NEG_Y; + remap_data.y = BMA4_Z; + remap_data.z = BMA4_NEG_X; + + rslt = bma456_tablet_set_remap_axes(&remap_data, &bma4); + bma4_error_codes_print_result("bma456_tablet_set_remap_axes", rslt); + + if (rslt == BMA4_OK) + { + rslt = bma456_tablet_get_remap_axes(&remap_data, &bma4); + bma4_error_codes_print_result("bma456_tablet_get_remap_axes", rslt); + + if (rslt == BMA4_OK) + { + printf("Re-mapped x value = %s\n", data_array[remap_data.x]); + printf("Re-mapped y value = %s\n", data_array[remap_data.y]); + printf("Re-mapped z value = %s\n", data_array[remap_data.z]); + } + + printf("Expected Re-mapped x value = BMA4_NEG_Y\n"); + printf("Expected Re-mapped y value = BMA4_Z\n"); + printf("Expected Re-mapped z value = BMA4_NEG_X\n"); + + if ((remap_data.x == BMA4_NEG_Y) && (remap_data.y == BMA4_Z) && (remap_data.z == BMA4_NEG_X)) + { + printf(">> PASS\n"); + } + else + { + printf(">> FAIL\n"); + } + } + + printf("Print mapped data\n"); + + for (;;) + { + /* Read interrupt status */ + rslt = bma456_tablet_read_int_status(&int_status, &bma4); + bma4_error_codes_print_result("bma456_tablet_read_int_status", rslt); + + /* Filtering only the accel data ready interrupt */ + if ((rslt == BMA4_OK) && (int_status & BMA4_ACCEL_DATA_RDY_INT)) + { + rslt = bma4_read_accel_xyz(&accel, &bma4); + bma4_error_codes_print_result("bma4_read_accel_xyz", rslt); + + printf("Accel :: X = %d Y = %d Z = %d\n", accel.x, accel.y, accel.z); + + break; + } + } + + printf("\nAXIS_REMAP_FUNC_TEST 3\n"); + printf("Get sensor data of re-mapped axes - 2nd combination\n"); + + remap_data.x = BMA4_NEG_Z; + remap_data.y = BMA4_NEG_X; + remap_data.z = BMA4_Y; + + rslt = bma456_tablet_set_remap_axes(&remap_data, &bma4); + bma4_error_codes_print_result("bma456_tablet_set_remap_axes", rslt); + + if (rslt == BMA4_OK) + { + rslt = bma456_tablet_get_remap_axes(&remap_data, &bma4); + bma4_error_codes_print_result("bma456_tablet_get_remap_axes", rslt); + + if (rslt == BMA4_OK) + { + printf("Re-mapped x value = %s\n", data_array[remap_data.x]); + printf("Re-mapped y value = %s\n", data_array[remap_data.y]); + printf("Re-mapped z value = %s\n", data_array[remap_data.z]); + } + + printf("Expected Re-mapped x value = BMA4_NEG_Z\n"); + printf("Expected Re-mapped y value = BMA4_NEG_X\n"); + printf("Expected Re-mapped z value = BMA4_Y\n"); + + if ((remap_data.x == BMA4_NEG_Z) && (remap_data.y == BMA4_NEG_X) && (remap_data.z == BMA4_Y)) + { + printf(">> PASS\n"); + } + else + { + printf(">> FAIL\n"); + } + } + + printf("Print mapped data\n"); + + for (;;) + { + /* Read interrupt status */ + rslt = bma456_tablet_read_int_status(&int_status, &bma4); + bma4_error_codes_print_result("bma456_tablet_read_int_status", rslt); + + /* Filtering only the accel data ready interrupt */ + if ((rslt == BMA4_OK) && (int_status & BMA4_ACCEL_DATA_RDY_INT)) + { + rslt = bma4_read_accel_xyz(&accel, &bma4); + bma4_error_codes_print_result("bma4_read_accel_xyz", rslt); + + printf("Accel :: X = %d Y = %d Z = %d\n", accel.x, accel.y, accel.z); + + break; + } + } + + printf("\nAXIS_REMAP_FUNC_TEST 4\n"); + printf("Get sensor data of re-mapped axes - 3rd combination\n"); + + remap_data.x = BMA4_Y; + remap_data.y = BMA4_Z; + remap_data.z = BMA4_X; + + rslt = bma456_tablet_set_remap_axes(&remap_data, &bma4); + bma4_error_codes_print_result("bma456_tablet_set_remap_axes", rslt); + if (rslt == BMA4_OK) + { + rslt = bma456_tablet_get_remap_axes(&remap_data, &bma4); + bma4_error_codes_print_result("bma456_tablet_get_remap_axes", rslt); + + if (rslt == BMA4_OK) + { + printf("Re-mapped x value = %s\n", data_array[remap_data.x]); + printf("Re-mapped y value = %s\n", data_array[remap_data.y]); + printf("Re-mapped z value = %s\n", data_array[remap_data.z]); + } + + printf("Expected Re-mapped x value = BMA4_Y\n"); + printf("Expected Re-mapped y value = BMA4_Z\n"); + printf("Expected Re-mapped z value = BMA4_X\n"); + + if ((remap_data.x == BMA4_Y) && (remap_data.y == BMA4_Z) && (remap_data.z == BMA4_X)) + { + printf(">> PASS\n"); + } + else + { + printf(">> FAIL\n"); + } + } + + printf("Print mapped data\n"); + + for (;;) + { + /* Read interrupt status */ + rslt = bma456_tablet_read_int_status(&int_status, &bma4); + bma4_error_codes_print_result("bma456_tablet_read_int_status", rslt); + + /* Filtering only the accel data ready interrupt */ + if ((rslt == BMA4_OK) && (int_status & BMA4_ACCEL_DATA_RDY_INT)) + { + rslt = bma4_read_accel_xyz(&accel, &bma4); + bma4_error_codes_print_result("bma4_read_accel_xyz", rslt); + + printf("Accel :: X = %d Y = %d Z = %d\n", accel.x, accel.y, accel.z); + + break; + } + } + + printf("\nAXIS_REMAP_FUNC_TEST 5\n"); + printf("Get sensor data of re-mapped axes - 4th combination\n"); + + remap_data.x = BMA4_NEG_X; + remap_data.y = BMA4_NEG_Y; + remap_data.z = BMA4_NEG_Z; + + rslt = bma456_tablet_set_remap_axes(&remap_data, &bma4); + bma4_error_codes_print_result("bma456_tablet_set_remap_axes", rslt); + + if (rslt == BMA4_OK) + { + rslt = bma456_tablet_get_remap_axes(&remap_data, &bma4); + bma4_error_codes_print_result("bma456_tablet_get_remap_axes", rslt); + + if (rslt == BMA4_OK) + { + printf("Re-mapped x value = %s\n", data_array[remap_data.x]); + printf("Re-mapped y value = %s\n", data_array[remap_data.y]); + printf("Re-mapped z value = %s\n", data_array[remap_data.z]); + } + + printf("Expected Re-mapped x value = BMA4_NEG_X\n"); + printf("Expected Re-mapped y value = BMA4_NEG_Y\n"); + printf("Expected Re-mapped z value = BMA4_NEG_Z\n"); + + if ((remap_data.x == BMA4_NEG_X) && (remap_data.y == BMA4_NEG_Y) && (remap_data.z == BMA4_NEG_Z)) + { + printf(">> PASS\n"); + } + else + { + printf(">> FAIL\n"); + } + } + + printf("Print mapped data\n"); + + for (;;) + { + /* Read interrupt status */ + rslt = bma456_tablet_read_int_status(&int_status, &bma4); + bma4_error_codes_print_result("bma456_tablet_read_int_status", rslt); + + /* Filtering only the accel data ready interrupt */ + if ((rslt == BMA4_OK) && (int_status & BMA4_ACCEL_DATA_RDY_INT)) + { + rslt = bma4_read_accel_xyz(&accel, &bma4); + bma4_error_codes_print_result("bma4_read_accel_xyz", rslt); + + printf("Accel :: X = %d Y = %d Z = %d\n", accel.x, accel.y, accel.z); + + break; + } + } + + bma4_coines_deinit(); + + return rslt; +} diff --git a/components/bma456/bma456_tablet_examples/common/common.c b/components/bma456/bma456_tablet_examples/common/common.c new file mode 100644 index 0000000..ca1e7c9 --- /dev/null +++ b/components/bma456/bma456_tablet_examples/common/common.c @@ -0,0 +1,242 @@ +/** + * Copyright (C) 2023 Bosch Sensortec GmbH. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include + +#include "bma4_defs.h" +#include "common.h" + +/******************************************************************************/ +/*! Macro definitions */ + +/*! Read write length varies based on user requirement */ +#define BMA4_READ_WRITE_LEN UINT8_C(46) + +/******************************************************************************/ +/*! Static variable definition */ + +/*! Variable that holds the I2C device address or SPI chip selection */ +static uint8_t dev_addr; + +/******************************************************************************/ +/*! User interface functions */ + +/*! + * I2C read function map to COINES platform + */ +BMA4_INTF_RET_TYPE bma4_i2c_read(uint8_t reg_addr, uint8_t *reg_data, uint32_t len, void *intf_ptr) +{ + uint8_t dev_address = *(uint8_t*)intf_ptr; + + (void)intf_ptr; + + return coines_read_i2c(COINES_I2C_BUS_0, dev_address, reg_addr, reg_data, (uint16_t)len); +} + +/*! + * I2C write function map to COINES platform + */ +BMA4_INTF_RET_TYPE bma4_i2c_write(uint8_t reg_addr, const uint8_t *reg_data, uint32_t len, void *intf_ptr) +{ + uint8_t dev_address = *(uint8_t*)intf_ptr; + + (void)intf_ptr; + + return coines_write_i2c(COINES_I2C_BUS_0, dev_address, reg_addr, (uint8_t *)reg_data, (uint16_t)len); +} + +/*! + * SPI read function map to COINES platform + */ +BMA4_INTF_RET_TYPE bma4_spi_read(uint8_t reg_addr, uint8_t *reg_data, uint32_t len, void *intf_ptr) +{ + uint8_t dev_address = *(uint8_t*)intf_ptr; + + (void)intf_ptr; + + return coines_read_spi(COINES_SPI_BUS_0, dev_address, reg_addr, reg_data, (uint16_t)len); +} + +/*! + * SPI write function map to COINES platform + */ +BMA4_INTF_RET_TYPE bma4_spi_write(uint8_t reg_addr, const uint8_t *reg_data, uint32_t len, void *intf_ptr) +{ + uint8_t dev_address = *(uint8_t*)intf_ptr; + + (void)intf_ptr; + + return coines_write_spi(COINES_SPI_BUS_0, dev_address, reg_addr, (uint8_t *)reg_data, (uint16_t)len); +} + +/*! + * Delay function map to COINES platform + */ +void bma4_delay_us(uint32_t period, void *intf_ptr) +{ + (void) intf_ptr; + coines_delay_usec(period); +} + +/*! + * @brief Function to select the interface between SPI and I2C. + * Also to initialize coines platform + */ +int8_t bma4_interface_init(struct bma4_dev *bma, uint8_t intf, enum bma4_variant variant) +{ + int8_t rslt = BMA4_OK; + + if (bma != NULL) + { + int16_t result = coines_open_comm_intf(COINES_COMM_INTF_USB, NULL); + struct coines_board_info board_info; + if (result < COINES_SUCCESS) + { + printf( + "\n Unable to connect with Application Board ! \n" " 1. Check if the board is connected and powered on. \n" " 2. Check if Application Board USB driver is installed. \n" + " 3. Check if board is in use by another application. (Insufficient permissions to access USB) \n"); + exit(result); + } + + result = coines_get_board_info(&board_info); + + #if defined(PC) + setbuf(stdout, NULL); + #endif + + (void)coines_set_shuttleboard_vdd_vddio_config(0, 0); + coines_delay_usec(10000); + + /* Bus configuration : I2C */ + if (intf == BMA4_I2C_INTF) + { + printf("I2C Interface \n"); + + /* To initialize the user I2C function */ + dev_addr = BMA4_I2C_ADDR_PRIMARY; + bma->intf = BMA4_I2C_INTF; + bma->bus_read = bma4_i2c_read; + bma->bus_write = bma4_i2c_write; + + /* SDO to Ground */ + (void)coines_set_pin_config(COINES_SHUTTLE_PIN_22, COINES_PIN_DIRECTION_OUT, COINES_PIN_VALUE_LOW); + + /* Make CSB pin HIGH */ + (void)coines_set_pin_config(COINES_SHUTTLE_PIN_21, COINES_PIN_DIRECTION_OUT, COINES_PIN_VALUE_HIGH); + coines_delay_msec(100); + + /* SDO pin is made low */ + (void)coines_set_pin_config(COINES_SHUTTLE_PIN_SDO, COINES_PIN_DIRECTION_OUT, COINES_PIN_VALUE_LOW); + + (void)coines_config_i2c_bus(COINES_I2C_BUS_0, COINES_I2C_STANDARD_MODE); + } + /* Bus configuration : SPI */ + else if (intf == BMA4_SPI_INTF) + { + printf("SPI Interface \n"); + + /* To initialize the user SPI function */ + dev_addr = COINES_SHUTTLE_PIN_7; + bma->intf = BMA4_SPI_INTF; + bma->bus_read = bma4_spi_read; + bma->bus_write = bma4_spi_write; + (void)coines_config_spi_bus(COINES_SPI_BUS_0, COINES_SPI_SPEED_7_5_MHZ, COINES_SPI_MODE0); + } + + /* Assign variant information */ + bma->variant = variant; + + /* Assign device address to interface pointer */ + bma->intf_ptr = &dev_addr; + + /* Configure delay in microseconds */ + bma->delay_us = bma4_delay_us; + + /* Configure max read/write length (in bytes) ( Supported length depends on target machine) */ + bma->read_write_len = BMA4_READ_WRITE_LEN; + + /* Set Performance mode status */ + bma->perf_mode_status = BMA4_DISABLE; + + coines_delay_msec(100); + + (void)coines_set_shuttleboard_vdd_vddio_config(3300, 3300); + + coines_delay_msec(200); + } + else + { + rslt = BMA4_E_NULL_PTR; + } + + return rslt; + +} + +/*! + * @brief Prints the execution status of the APIs. + */ +void bma4_error_codes_print_result(const char api_name[], int8_t rslt) +{ + if (rslt != BMA4_OK) + { + printf("%s\t", api_name); + if (rslt == BMA4_E_NULL_PTR) + { + printf("Error [%d] : Null pointer\r\n", rslt); + } + else if (rslt == BMA4_E_COM_FAIL) + { + printf("Error [%d] : Communication failure\r\n", rslt); + } + else if (rslt == BMA4_E_CONFIG_STREAM_ERROR) + { + printf("Error [%d] : Invalid configuration stream\r\n", rslt); + } + else if (rslt == BMA4_E_SELF_TEST_FAIL) + { + printf("Error [%d] : Self test failed\r\n", rslt); + } + else if (rslt == BMA4_E_INVALID_SENSOR) + { + printf("Error [%d] : Device not found\r\n", rslt); + } + else if (rslt == BMA4_E_OUT_OF_RANGE) + { + printf("Error [%d] : Out of Range\r\n", rslt); + } + else if (rslt == BMA4_E_AVG_MODE_INVALID_CONF) + { + printf("Error [%d] : Invalid bandwidth and ODR combination in Accel Averaging mode\r\n", rslt); + } + else + { + /* For more error codes refer "*_defs.h" */ + printf("Error [%d] : Unknown error code\r\n", rslt); + } + } +} + +/*! + * @brief Deinitializes coines platform + * + * @return void. + */ +void bma4_coines_deinit(void) +{ + (void)fflush(stdout); + coines_delay_msec(200); + + (void)coines_set_shuttleboard_vdd_vddio_config(0, 0); + coines_delay_msec(1000); + + /* Coines interface reset */ + coines_soft_reset(); + coines_delay_msec(1000); + (void)coines_close_comm_intf(COINES_COMM_INTF_USB, NULL); +} diff --git a/components/bma456/bma456_tablet_examples/common/common.h b/components/bma456/bma456_tablet_examples/common/common.h new file mode 100644 index 0000000..75c53f4 --- /dev/null +++ b/components/bma456/bma456_tablet_examples/common/common.h @@ -0,0 +1,127 @@ +/**\ + * Copyright (c) 2023 Bosch Sensortec GmbH. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + **/ + +#ifndef COMMON_H +#define COMMON_H + +/*! CPP guard */ +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include "bma4.h" +#include "coines.h" + +/*! + * @brief Function for reading the sensor's registers through I2C bus. + * + * @param[in] reg_addr : Register address. + * @param[out] reg_data : Pointer to the data buffer to store the read data. + * @param[in] length : No of bytes to read. + * @param[in] intf_ptr : Interface pointer + * + * @return Status of execution + * @retval = BMA4_INTF_RET_SUCCESS -> Success + * @retval != BMA4_INTF_RET_SUCCESS -> Failure Info + * + */ +BMA4_INTF_RET_TYPE bma4_i2c_read(uint8_t reg_addr, uint8_t *reg_data, uint32_t len, void *intf_ptr); + +/*! + * @brief Function for writing the sensor's registers through I2C bus. + * + * @param[in] reg_addr : Register address. + * @param[in] reg_data : Pointer to the data buffer whose value is to be written. + * @param[in] length : No of bytes to write. + * @param[in] intf_ptr : Interface pointer + * + * @return Status of execution + * @retval = BMA4_INTF_RET_SUCCESS -> Success + * @retval != BMA4_INTF_RET_SUCCESS -> Failure Info + * + */ +BMA4_INTF_RET_TYPE bma4_i2c_write(uint8_t reg_addr, const uint8_t *reg_data, uint32_t len, void *intf_ptr); + +/*! + * @brief Function for reading the sensor's registers through SPI bus. + * + * @param[in] reg_addr : Register address. + * @param[out] reg_data : Pointer to the data buffer to store the read data. + * @param[in] length : No of bytes to read. + * @param[in] intf_ptr : Interface pointer + * + * @return Status of execution + * @retval = BMA4_INTF_RET_SUCCESS -> Success + * @retval != BMA4_INTF_RET_SUCCESS -> Failure Info + * + */ +BMA4_INTF_RET_TYPE bma4_spi_read(uint8_t reg_addr, uint8_t *reg_data, uint32_t len, void *intf_ptr); + +/*! + * @brief Function for writing the sensor's registers through SPI bus. + * + * @param[in] reg_addr : Register address. + * @param[in] reg_data : Pointer to the data buffer whose data has to be written. + * @param[in] length : No of bytes to write. + * @param[in] intf_ptr : Interface pointer + * + * @return Status of execution + * @retval = BMA4_INTF_RET_SUCCESS -> Success + * @retval != BMA4_INTF_RET_SUCCESS -> Failure Info + * + */ +BMA4_INTF_RET_TYPE bma4_spi_write(uint8_t reg_addr, const uint8_t *reg_data, uint32_t len, void *intf_ptr); + +/*! + * @brief This function provides the delay for required time (Microsecond) as per the input provided in some of the + * APIs. + * + * @param[in] period_us : The required wait time in microsecond. + * @param[in] intf_ptr : Interface pointer + * + * @return void. + * + */ +void bma4_delay_us(uint32_t period, void *intf_ptr); + +/*! + * @brief Function to select the interface between SPI and I2C. + * + * @param[in] bma : Structure instance of bma4_dev + * @param[in] intf : Interface selection parameter + * @param[in] variant : Variant information of the sensor + * ( BMA42x variants values - BMA42X_VARIANT / BMA42X_B_VARIANT ) + * ( BMA45x variants values - BMA45X_VARIANT ) + * + * @return Status of execution + * @retval 0 -> Success + * @retval < 0 -> Failure Info + */ +int8_t bma4_interface_init(struct bma4_dev *bma, uint8_t intf, enum bma4_variant variant); + +/*! + * @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 bma4_error_codes_print_result(const char api_name[], int8_t rslt); + +/*! + * @brief Deinitializes coines platform + * + * @return void. + */ +void bma4_coines_deinit(void); + +#ifdef __cplusplus +} +#endif /* End of CPP guard */ + +#endif /* COMMON_H */ diff --git a/components/bma456/bma456_tablet_examples/fifo_full_header_mode/Makefile b/components/bma456/bma456_tablet_examples/fifo_full_header_mode/Makefile new file mode 100644 index 0000000..58deead --- /dev/null +++ b/components/bma456/bma456_tablet_examples/fifo_full_header_mode/Makefile @@ -0,0 +1,20 @@ +COINES_INSTALL_PATH ?= ../../../.. + +EXAMPLE_FILE ?= fifo_full_header_mode.c + +API_LOCATION ?= ../.. + +COMMON_LOCATION ?= .. + +C_SRCS += \ +$(API_LOCATION)/bma4.c \ +$(API_LOCATION)/bma456_tablet.c \ +$(COMMON_LOCATION)/common/common.c + +INCLUDEPATHS += \ +$(API_LOCATION) \ +$(COMMON_LOCATION)/common + +TARGET=MCU_APP30 + +include $(COINES_INSTALL_PATH)/coines.mk \ No newline at end of file diff --git a/components/bma456/bma456_tablet_examples/fifo_full_header_mode/fifo_full_header_mode.c b/components/bma456/bma456_tablet_examples/fifo_full_header_mode/fifo_full_header_mode.c new file mode 100644 index 0000000..72a77e6 --- /dev/null +++ b/components/bma456/bma456_tablet_examples/fifo_full_header_mode/fifo_full_header_mode.c @@ -0,0 +1,173 @@ +/**\ + * Copyright (c) 2023 Bosch Sensortec GmbH. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + **/ + +#include +#include "bma456_tablet.h" +#include "common.h" + +/******************************************************************************/ +/*! Macro definition */ + +/*! Buffer size allocated to store raw FIFO data */ +#define BMA456_TABLET_FIFO_RAW_DATA_BUFFER_SIZE UINT16_C(1024) + +/*! Length of data to be read from FIFO */ +#define BMA456_TABLET_FIFO_RAW_DATA_USER_LENGTH UINT16_C(1024) + +/*! Number of accel frames to be extracted from FIFO + * Calculation: + * fifo_buffer = 1024, accel_frame_len = 6, header_byte = 1. + * fifo_accel_frame_count = (1024 / (6 + 1)) = 147 frames + * + * Extra frames to parse sensortime data + */ +#define BMA456_TABLET_FIFO_ACCEL_FRAME_COUNT UINT8_C(170) + +/******************************************************************************/ +/*! Function */ + +/* This function starts the execution of program */ +int main(void) +{ + /* Status of API are returned to this variable */ + int8_t rslt; + + /* Accelerometer configuration structure */ + struct bma4_accel_config acc_conf = { 0 }; + + /* Sensor initialization configuration */ + struct bma4_dev dev = { 0 }; + + /* Number of accelerometer frames */ + uint16_t accel_length; + + /* Variable to idx bytes */ + uint16_t idx = 0; + + /* Variable to maintain count of loop to run FIFO read */ + uint8_t loop = 1; + + /* Number of bytes of FIFO data + * NOTE : Dummy byte (for SPI Interface) required for FIFO data read must be given as part of array size + */ + uint8_t fifo_data[BMA456_TABLET_FIFO_RAW_DATA_BUFFER_SIZE + BMA4_SENSORTIME_OVERHEAD_BYTE] = { 0 }; + + /* Array of accelerometer frames -> Total bytes = + * 147 * (6 axes bytes(+/- x,y,z) + 1 header byte) = 1029 bytes */ + struct bma4_accel fifo_accel_data[BMA456_TABLET_FIFO_ACCEL_FRAME_COUNT] = { { 0 } }; + + /* Initialize FIFO frame structure */ + struct bma4_fifo_frame fifoframe = { 0 }; + + /* Variable that contains interrupt status value */ + uint16_t int_status = 0; + + /* Variable to hold the length of FIFO data */ + uint16_t fifo_length = 0; + + /* Interface reference is given as a parameter + * For I2C : BMA4_I2C_INTF + * For SPI : BMA4_SPI_INTF + * Variant information given as parameter - BMA45X_VARIANT + */ + rslt = bma4_interface_init(&dev, BMA4_I2C_INTF, BMA45X_VARIANT); + bma4_error_codes_print_result("bma4_interface_init", rslt); + + /* Initialize BMA456_TABLET */ + rslt = bma456_tablet_init(&dev); + bma4_error_codes_print_result("bma456_tablet_init status", rslt); + + /* Accelerometer configuration settings */ + acc_conf.odr = BMA4_OUTPUT_DATA_RATE_100HZ; + acc_conf.bandwidth = BMA4_ACCEL_NORMAL_AVG4; + acc_conf.range = BMA4_ACCEL_RANGE_2G; + acc_conf.perf_mode = BMA4_CIC_AVG_MODE; + + /* Set the accel configurations */ + rslt = bma4_set_accel_config(&acc_conf, &dev); + bma4_error_codes_print_result("bma4_set_accel_config status", rslt); + + /* NOTE : Enable accel after set of configurations */ + rslt = bma4_set_accel_enable(BMA4_ENABLE, &dev); + bma4_error_codes_print_result("bma4_set_accel_enable status", rslt); + + /* Disabling advance power save mode as FIFO data is not accessible in advance low power mode */ + rslt = bma4_set_advance_power_save(BMA4_DISABLE, &dev); + bma4_error_codes_print_result("bma4_set_advance_power_save status", rslt); + + /* Clear FIFO configuration register */ + rslt = bma4_set_fifo_config(BMA4_FIFO_ALL, BMA4_DISABLE, &dev); + bma4_error_codes_print_result("bma4_set_fifo_config disable status", rslt); + + /* Set FIFO configuration by enabling accel. + * NOTE 1: The header mode is enabled by default. + * NOTE 2: By default the FIFO operating mode is FIFO mode. */ + rslt = bma4_set_fifo_config(BMA4_FIFO_ACCEL | BMA4_FIFO_HEADER | BMA4_FIFO_TIME, BMA4_ENABLE, &dev); + bma4_error_codes_print_result("bma4_set_fifo_config enable status", rslt); + + /* Update FIFO structure */ + fifoframe.data = fifo_data; + fifoframe.length = BMA456_TABLET_FIFO_RAW_DATA_USER_LENGTH + BMA4_SENSORTIME_OVERHEAD_BYTE; + + printf("FIFO is configured in header mode\n"); + + rslt = bma456_tablet_map_interrupt(BMA4_INTR1_MAP, BMA4_FIFO_FULL_INT, BMA4_ENABLE, &dev); + bma4_error_codes_print_result("bma456_tablet_map_interrupt status", rslt); + + while (loop <= 10) + { + rslt = bma456_tablet_read_int_status(&int_status, &dev); + bma4_error_codes_print_result("bma456_tablet_read_int_status", rslt); + + if ((rslt == BMA4_OK) && (int_status & BMA4_FIFO_FULL_INT)) + { + printf("\nIteration : %d\n", loop); + + rslt = bma4_get_fifo_length(&fifo_length, &dev); + bma4_error_codes_print_result("bma4_get_fifo_length status", rslt); + + printf("FIFO data bytes available : %d\n", fifo_length); + printf("FIFO data bytes requested : %d\n", fifoframe.length); + + /* Read FIFO data */ + rslt = bma4_read_fifo_data(&fifoframe, &dev); + bma4_error_codes_print_result("bma4_read_fifo_data status", rslt); + + accel_length = BMA456_TABLET_FIFO_ACCEL_FRAME_COUNT; + + if (rslt == BMA4_OK) + { + printf("Requested data frames before parsing: %d\n", accel_length); + + /* Parse the FIFO data to extract accelerometer data from the FIFO buffer */ + rslt = bma4_extract_accel(fifo_accel_data, &accel_length, &fifoframe, &dev); + printf("Parsed accelerometer data frames: %d\n", accel_length); + + printf("ACCEL, X, Y, Z\n"); + + /* Print the parsed accelerometer data from the FIFO buffer */ + for (idx = 0; idx < accel_length; idx++) + { + printf("%d, %d, %d, %d\n", + idx, + fifo_accel_data[idx].x, + fifo_accel_data[idx].y, + fifo_accel_data[idx].z); + } + + /* Print control frames like sensor time and skipped frame count */ + printf("Skipped frame count = %d\n", fifoframe.skipped_frame_count); + printf("Sensor time(in seconds) = %.4lf s\r\n", (fifoframe.sensor_time * BMA4_SENSORTIME_RESOLUTION)); + } + + loop++; + } + } + + bma4_coines_deinit(); + + return rslt; +} diff --git a/components/bma456/bma456_tablet_examples/fifo_full_headerless_mode/Makefile b/components/bma456/bma456_tablet_examples/fifo_full_headerless_mode/Makefile new file mode 100644 index 0000000..c1bf89e --- /dev/null +++ b/components/bma456/bma456_tablet_examples/fifo_full_headerless_mode/Makefile @@ -0,0 +1,18 @@ +COINES_INSTALL_PATH ?= ../../../.. + +EXAMPLE_FILE ?= fifo_full_headerless_mode.c + +API_LOCATION ?= ../.. + +COMMON_LOCATION ?= .. + +C_SRCS += \ +$(API_LOCATION)/bma4.c \ +$(API_LOCATION)/bma456_tablet.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/components/bma456/bma456_tablet_examples/fifo_full_headerless_mode/fifo_full_headerless_mode.c b/components/bma456/bma456_tablet_examples/fifo_full_headerless_mode/fifo_full_headerless_mode.c new file mode 100644 index 0000000..abadc20 --- /dev/null +++ b/components/bma456/bma456_tablet_examples/fifo_full_headerless_mode/fifo_full_headerless_mode.c @@ -0,0 +1,171 @@ +/**\ + * Copyright (c) 2023 Bosch Sensortec GmbH. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + **/ + +#include +#include "bma456_tablet.h" +#include "common.h" + +/******************************************************************************/ +/*! Macro definition */ + +/*! Buffer size allocated to store raw FIFO data */ +#define BMA456_TABLET_FIFO_RAW_DATA_BUFFER_SIZE UINT16_C(1024) + +/*! Length of data to be read from FIFO */ +#define BMA456_TABLET_FIFO_RAW_DATA_USER_LENGTH UINT16_C(1024) + +/*! Number of accel frames to be extracted from FIFO + * Calculation: + * fifo_buffer = 1024, accel_frame_len = 6. + * fifo_accel_frame_count = (1024 / 6) = 170 frames + */ +#define BMA456_TABLET_FIFO_ACCEL_FRAME_COUNT UINT8_C(170) + +/******************************************************************************/ +/*! Function */ + +/* This function starts the execution of program */ +int main(void) +{ + /* Status of API are returned to this variable */ + int8_t rslt; + + /* Accelerometer configuration structure */ + struct bma4_accel_config acc_conf = { 0 }; + + /* Sensor initialization configuration */ + struct bma4_dev dev = { 0 }; + + /* Number of accelerometer frames */ + uint16_t accel_length; + + /* Variable to idx bytes */ + uint16_t idx = 0; + + /* Variable to maintain count of loop to run FIFO read */ + uint8_t loop = 1; + + /* Number of bytes of FIFO data + * NOTE : Dummy byte (for SPI Interface) required for FIFO data read must be given as part of array size + */ + uint8_t fifo_data[BMA456_TABLET_FIFO_RAW_DATA_BUFFER_SIZE] = { 0 }; + + /* Array of accelerometer frames -> Total bytes = + * 170 * (6 axes bytes(+/- x,y,z)) = 1020 bytes */ + struct bma4_accel fifo_accel_data[BMA456_TABLET_FIFO_ACCEL_FRAME_COUNT] = { { 0 } }; + + /* Initialize FIFO frame structure */ + struct bma4_fifo_frame fifoframe = { 0 }; + + /* Variable that contains interrupt status value */ + uint16_t int_status = 0; + + /* Variable to hold the length of FIFO data */ + uint16_t fifo_length = 0; + + /* Interface reference is given as a parameter + * For I2C : BMA4_I2C_INTF + * For SPI : BMA4_SPI_INTF + * Variant information given as parameter - BMA45X_VARIANT + */ + rslt = bma4_interface_init(&dev, BMA4_I2C_INTF, BMA45X_VARIANT); + bma4_error_codes_print_result("bma4_interface_init", rslt); + + /* Initialize BMA456_TABLET */ + rslt = bma456_tablet_init(&dev); + bma4_error_codes_print_result("bma456_tablet_init status", rslt); + + /* Accelerometer configuration settings */ + acc_conf.odr = BMA4_OUTPUT_DATA_RATE_100HZ; + acc_conf.bandwidth = BMA4_ACCEL_NORMAL_AVG4; + acc_conf.range = BMA4_ACCEL_RANGE_2G; + acc_conf.perf_mode = BMA4_CIC_AVG_MODE; + + /* Set the accel configurations */ + rslt = bma4_set_accel_config(&acc_conf, &dev); + bma4_error_codes_print_result("bma4_set_accel_config status", rslt); + + /* NOTE : Enable accel after set of configurations */ + rslt = bma4_set_accel_enable(BMA4_ENABLE, &dev); + bma4_error_codes_print_result("bma4_set_accel_enable status", rslt); + + /* Disabling advance power save mode as FIFO data is not accessible in advance low power mode */ + rslt = bma4_set_advance_power_save(BMA4_DISABLE, &dev); + bma4_error_codes_print_result("bma4_set_advance_power_save status", rslt); + + /* Clear FIFO configuration register */ + rslt = bma4_set_fifo_config(BMA4_FIFO_ALL, BMA4_DISABLE, &dev); + bma4_error_codes_print_result("bma4_set_fifo_config disable status", rslt); + + /* Set FIFO configuration by enabling accel. + * NOTE 1: The header mode is enabled by default. + * NOTE 2: By default the FIFO operating mode is FIFO mode. */ + rslt = bma4_set_fifo_config(BMA4_FIFO_ACCEL, BMA4_ENABLE, &dev); + bma4_error_codes_print_result("bma4_set_fifo_config enable status", rslt); + + /* Update FIFO structure */ + fifoframe.data = fifo_data; + fifoframe.length = BMA456_TABLET_FIFO_RAW_DATA_USER_LENGTH; + + /* To enable headerless mode, disable the header. */ + rslt = bma4_set_fifo_config(BMA4_FIFO_HEADER, BMA4_DISABLE, &dev); + bma4_error_codes_print_result("bma4_set_fifo_config status", rslt); + + printf("FIFO is configured in headerless mode\n"); + + rslt = bma456_tablet_map_interrupt(BMA4_INTR1_MAP, BMA4_FIFO_FULL_INT, BMA4_ENABLE, &dev); + bma4_error_codes_print_result("bma456_tablet_map_interrupt status", rslt); + + while (loop <= 10) + { + rslt = bma456_tablet_read_int_status(&int_status, &dev); + bma4_error_codes_print_result("bma456_tablet_read_int_status", rslt); + + if ((rslt == BMA4_OK) && (int_status & BMA4_FIFO_FULL_INT)) + { + printf("\nIteration : %d\n", loop); + + rslt = bma4_get_fifo_length(&fifo_length, &dev); + bma4_error_codes_print_result("bma4_get_fifo_length status", rslt); + + printf("FIFO data bytes available : %d\n", fifo_length); + printf("FIFO data bytes requested : %d\n", fifoframe.length); + + /* Read FIFO data */ + rslt = bma4_read_fifo_data(&fifoframe, &dev); + bma4_error_codes_print_result("bma4_read_fifo_data status", rslt); + + accel_length = BMA456_TABLET_FIFO_ACCEL_FRAME_COUNT; + + if (rslt == BMA4_OK) + { + printf("Requested data frames before parsing: %d\n", accel_length); + + /* Parse the FIFO data to extract accelerometer data from the FIFO buffer */ + rslt = bma4_extract_accel(fifo_accel_data, &accel_length, &fifoframe, &dev); + printf("Parsed accelerometer data frames: %d\n", accel_length); + + printf("ACCEL, X, Y, Z\n"); + + /* Print the parsed accelerometer data from the FIFO buffer */ + for (idx = 0; idx < accel_length; idx++) + { + printf("%d, %d, %d, %d\n", + idx, + fifo_accel_data[idx].x, + fifo_accel_data[idx].y, + fifo_accel_data[idx].z); + } + + loop++; + } + } + } + + bma4_coines_deinit(); + + return rslt; +} diff --git a/components/bma456/bma456_tablet_examples/fifo_watermark_header_mode/Makefile b/components/bma456/bma456_tablet_examples/fifo_watermark_header_mode/Makefile new file mode 100644 index 0000000..ec8a1b2 --- /dev/null +++ b/components/bma456/bma456_tablet_examples/fifo_watermark_header_mode/Makefile @@ -0,0 +1,20 @@ +COINES_INSTALL_PATH ?= ../../../.. + +EXAMPLE_FILE ?= fifo_watermark_header_mode.c + +API_LOCATION ?= ../.. + +COMMON_LOCATION ?= .. + +C_SRCS += \ +$(API_LOCATION)/bma4.c \ +$(API_LOCATION)/bma456_tablet.c \ +$(COMMON_LOCATION)/common/common.c + +INCLUDEPATHS += \ +$(API_LOCATION) \ +$(COMMON_LOCATION)/common + +TARGET=MCU_APP30 + +include $(COINES_INSTALL_PATH)/coines.mk \ No newline at end of file diff --git a/components/bma456/bma456_tablet_examples/fifo_watermark_header_mode/fifo_watermark_header_mode.c b/components/bma456/bma456_tablet_examples/fifo_watermark_header_mode/fifo_watermark_header_mode.c new file mode 100644 index 0000000..4e46b01 --- /dev/null +++ b/components/bma456/bma456_tablet_examples/fifo_watermark_header_mode/fifo_watermark_header_mode.c @@ -0,0 +1,188 @@ +/**\ + * Copyright (c) 2023 Bosch Sensortec GmbH. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + **/ + +#include +#include "bma456_tablet.h" +#include "common.h" + +/******************************************************************************/ +/*! Macro definition */ + +/*! Buffer size allocated to store raw FIFO data */ +#define BMA456_TABLET_FIFO_RAW_DATA_BUFFER_SIZE UINT16_C(1024) + +/*! Length of data to be read from FIFO */ +#define BMA456_TABLET_FIFO_RAW_DATA_USER_LENGTH UINT16_C(1024) + +/*! Setting a watermark level in FIFO */ +#define BMA456_TABLET_FIFO_WATERMARK_LEVEL UINT16_C(650) + +/*! Number of accel frames to be extracted from FIFO + * Calculation: + * fifo_watermark_level = 650, accel_frame_len = 6, header_byte = 1. + * fifo_accel_frame_count = (650 / (6 + 1)) = 93 frames + * NOTE: Extra frames are read in order to get sensor time + */ +#define BMA456_TABLET_FIFO_ACCEL_FRAME_COUNT UINT8_C(120) + +/******************************************************************************/ +/*! Function */ + +/* This function starts the execution of program */ +int main(void) +{ + /* Status of API are returned to this variable */ + int8_t rslt; + + /* Accelerometer configuration structure */ + struct bma4_accel_config acc_conf = { 0 }; + + /* Sensor initialization configuration */ + struct bma4_dev dev = { 0 }; + + /* Number of accelerometer frames */ + uint16_t accel_length; + + /* Variable to idx bytes */ + uint16_t idx = 0; + + /* Variable to maintain count of loop to run FIFO read */ + uint8_t loop = 1; + + /* Number of bytes of FIFO data + * NOTE : Dummy byte (for SPI Interface) required for FIFO data read must be given as part of array size + */ + uint8_t fifo_data[BMA456_TABLET_FIFO_RAW_DATA_BUFFER_SIZE + BMA4_SENSORTIME_OVERHEAD_BYTE] = { 0 }; + + /* Array of accelerometer frames -> Total bytes = + * 100 * (6 axes bytes(+/- x,y,z) + 1 header byte) = 700 bytes */ + struct bma4_accel fifo_accel_data[BMA456_TABLET_FIFO_ACCEL_FRAME_COUNT] = { { 0 } }; + + /* Initialize FIFO frame structure */ + struct bma4_fifo_frame fifoframe = { 0 }; + + /* Variable that contains interrupt status value */ + uint16_t int_status = 0; + + /* Variable to hold the length of FIFO data */ + uint16_t fifo_length = 0; + + uint16_t watermark = 0; + + /* To set the watermark level in FIFO */ + uint16_t wm_lvl; + + /* Interface reference is given as a parameter + * For I2C : BMA4_I2C_INTF + * For SPI : BMA4_SPI_INTF + * Variant information given as parameter - BMA45X_VARIANT + */ + rslt = bma4_interface_init(&dev, BMA4_I2C_INTF, BMA45X_VARIANT); + bma4_error_codes_print_result("bma4_interface_init", rslt); + + /* Initialize BMA456_TABLET */ + rslt = bma456_tablet_init(&dev); + bma4_error_codes_print_result("bma456_tablet_init status", rslt); + + /* Accelerometer configuration settings */ + acc_conf.odr = BMA4_OUTPUT_DATA_RATE_100HZ; + acc_conf.bandwidth = BMA4_ACCEL_NORMAL_AVG4; + acc_conf.range = BMA4_ACCEL_RANGE_2G; + acc_conf.perf_mode = BMA4_CIC_AVG_MODE; + + /* Set the accel configurations */ + rslt = bma4_set_accel_config(&acc_conf, &dev); + bma4_error_codes_print_result("bma4_set_accel_config status", rslt); + + /* NOTE : Enable accel after set of configurations */ + rslt = bma4_set_accel_enable(BMA4_ENABLE, &dev); + bma4_error_codes_print_result("bma4_set_accel_enable status", rslt); + + /* Disabling advance power save mode as FIFO data is not accessible in advance low power mode */ + rslt = bma4_set_advance_power_save(BMA4_DISABLE, &dev); + bma4_error_codes_print_result("bma4_set_advance_power_save status", rslt); + + /* Clear FIFO configuration register */ + rslt = bma4_set_fifo_config(BMA4_FIFO_ALL, BMA4_DISABLE, &dev); + bma4_error_codes_print_result("bma4_set_fifo_config disable status", rslt); + + /* Set FIFO configuration by enabling accel. + * NOTE 1: The header mode is enabled by default. + * NOTE 2: By default the FIFO operating mode is FIFO mode. */ + rslt = bma4_set_fifo_config(BMA4_FIFO_ACCEL | BMA4_FIFO_HEADER | BMA4_FIFO_TIME, BMA4_ENABLE, &dev); + bma4_error_codes_print_result("bma4_set_fifo_config enable status", rslt); + + /* Update FIFO structure */ + fifoframe.data = fifo_data; + fifoframe.length = BMA456_TABLET_FIFO_RAW_DATA_USER_LENGTH + BMA4_SENSORTIME_OVERHEAD_BYTE; + + printf("FIFO is configured in header mode\n"); + + rslt = bma456_tablet_map_interrupt(BMA4_INTR1_MAP, BMA4_FIFO_WM_INT, BMA4_ENABLE, &dev); + bma4_error_codes_print_result("bma456_tablet_map_interrupt status", rslt); + + wm_lvl = BMA456_TABLET_FIFO_WATERMARK_LEVEL; + rslt = bma4_set_fifo_wm(wm_lvl, &dev); + bma4_error_codes_print_result("bma4_set_fifo_wm status", rslt); + + while (loop <= 10) + { + rslt = bma456_tablet_read_int_status(&int_status, &dev); + bma4_error_codes_print_result("bma456_tablet_read_int_status", rslt); + + if ((rslt == BMA4_OK) && (int_status & BMA4_FIFO_WM_INT)) + { + printf("\nIteration : %d\n", loop); + + rslt = bma4_get_fifo_wm(&watermark, &dev); + bma4_error_codes_print_result("bma4_get_fifo_wm status", rslt); + printf("FIFO watermark level : %d\n", watermark); + + rslt = bma4_get_fifo_length(&fifo_length, &dev); + bma4_error_codes_print_result("bma4_get_fifo_length status", rslt); + + printf("FIFO data bytes available : %d\n", fifo_length); + printf("FIFO data bytes requested : %d\n", fifoframe.length); + + /* Read FIFO data */ + rslt = bma4_read_fifo_data(&fifoframe, &dev); + bma4_error_codes_print_result("bma4_read_fifo_data status", rslt); + + accel_length = BMA456_TABLET_FIFO_ACCEL_FRAME_COUNT; + + if (rslt == BMA4_OK) + { + printf("Requested data frames before parsing: %d\n", accel_length); + + /* Parse the FIFO data to extract accelerometer data from the FIFO buffer */ + rslt = bma4_extract_accel(fifo_accel_data, &accel_length, &fifoframe, &dev); + printf("Parsed accelerometer data frames: %d\n", accel_length); + + printf("ACCEL, X, Y, Z\n"); + + /* Print the parsed accelerometer data from the FIFO buffer */ + for (idx = 0; idx < accel_length; idx++) + { + printf("%d, %d, %d, %d\n", + idx, + fifo_accel_data[idx].x, + fifo_accel_data[idx].y, + fifo_accel_data[idx].z); + } + + /* Print control frames like sensor time and skipped frame count */ + printf("Skipped frame count = %d\n", fifoframe.skipped_frame_count); + printf("Sensor time(in seconds) = %.4lf s\r\n", (fifoframe.sensor_time * BMA4_SENSORTIME_RESOLUTION)); + } + + loop++; + } + } + + bma4_coines_deinit(); + + return rslt; +} diff --git a/components/bma456/bma456_tablet_examples/fifo_watermark_headerless_mode/Makefile b/components/bma456/bma456_tablet_examples/fifo_watermark_headerless_mode/Makefile new file mode 100644 index 0000000..df138f5 --- /dev/null +++ b/components/bma456/bma456_tablet_examples/fifo_watermark_headerless_mode/Makefile @@ -0,0 +1,18 @@ +COINES_INSTALL_PATH ?= ../../../.. + +EXAMPLE_FILE ?= fifo_watermark_headerless_mode.c + +API_LOCATION ?= ../.. + +COMMON_LOCATION ?= .. + +C_SRCS += \ +$(API_LOCATION)/bma4.c \ +$(API_LOCATION)/bma456_tablet.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/components/bma456/bma456_tablet_examples/fifo_watermark_headerless_mode/fifo_watermark_headerless_mode.c b/components/bma456/bma456_tablet_examples/fifo_watermark_headerless_mode/fifo_watermark_headerless_mode.c new file mode 100644 index 0000000..81b9ab0 --- /dev/null +++ b/components/bma456/bma456_tablet_examples/fifo_watermark_headerless_mode/fifo_watermark_headerless_mode.c @@ -0,0 +1,188 @@ +/**\ + * Copyright (c) 2023 Bosch Sensortec GmbH. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + **/ + +#include +#include "bma456_tablet.h" +#include "common.h" + +/******************************************************************************/ +/*! Macro definition */ + +/*! Buffer size allocated to store raw FIFO data */ +#define BMA456_TABLET_FIFO_RAW_DATA_BUFFER_SIZE UINT16_C(1024) + +/*! Length of data to be read from FIFO */ +#define BMA456_TABLET_FIFO_RAW_DATA_USER_LENGTH UINT16_C(1024) + +/*! Setting a watermark level in FIFO */ +#define BMA456_TABLET_FIFO_WATERMARK_LEVEL UINT16_C(600) + +/*! Number of accel frames to be extracted from FIFO + * Calculation: + * fifo_watermark_level = 600, accel_frame_len = 6. + * fifo_accel_frame_count = (600 / 6) = 100 frames + */ +#define BMA456_TABLET_FIFO_ACCEL_FRAME_COUNT UINT8_C(100) + +/******************************************************************************/ +/*! Function */ + +/* This function starts the execution of program */ +int main(void) +{ + /* Status of API are returned to this variable */ + int8_t rslt; + + /* Accelerometer configuration structure */ + struct bma4_accel_config acc_conf = { 0 }; + + /* Sensor initialization configuration */ + struct bma4_dev dev = { 0 }; + + /* Number of accelerometer frames */ + uint16_t accel_length; + + /* Variable to idx bytes */ + uint16_t idx = 0; + + /* Variable to maintain count of loop to run FIFO read */ + uint8_t loop = 1; + + /* Number of bytes of FIFO data + * NOTE : Dummy byte (for SPI Interface) required for FIFO data read must be given as part of array size + */ + uint8_t fifo_data[BMA456_TABLET_FIFO_RAW_DATA_BUFFER_SIZE] = { 0 }; + + /* Array of accelerometer frames -> Total bytes = + * 100 * (6 axes bytes(+/- x,y,z)) = 600 bytes */ + struct bma4_accel fifo_accel_data[BMA456_TABLET_FIFO_ACCEL_FRAME_COUNT] = { { 0 } }; + + /* Initialize FIFO frame structure */ + struct bma4_fifo_frame fifoframe = { 0 }; + + /* Variable that contains interrupt status value */ + uint16_t int_status = 0; + + /* Variable to hold the length of FIFO data */ + uint16_t fifo_length = 0; + + uint16_t watermark = 0; + + /* To set the watermark level in FIFO */ + uint16_t wm_lvl; + + /* Interface reference is given as a parameter + * For I2C : BMA4_I2C_INTF + * For SPI : BMA4_SPI_INTF + * Variant information given as parameter - BMA45X_VARIANT + */ + rslt = bma4_interface_init(&dev, BMA4_I2C_INTF, BMA45X_VARIANT); + bma4_error_codes_print_result("bma4_interface_init", rslt); + + /* Initialize BMA456_TABLET */ + rslt = bma456_tablet_init(&dev); + bma4_error_codes_print_result("bma456_tablet_init status", rslt); + + /* Accelerometer configuration settings */ + acc_conf.odr = BMA4_OUTPUT_DATA_RATE_100HZ; + acc_conf.bandwidth = BMA4_ACCEL_NORMAL_AVG4; + acc_conf.range = BMA4_ACCEL_RANGE_2G; + acc_conf.perf_mode = BMA4_CIC_AVG_MODE; + + /* Set the accel configurations */ + rslt = bma4_set_accel_config(&acc_conf, &dev); + bma4_error_codes_print_result("bma4_set_accel_config status", rslt); + + /* NOTE : Enable accel after set of configurations */ + rslt = bma4_set_accel_enable(BMA4_ENABLE, &dev); + bma4_error_codes_print_result("bma4_set_accel_enable status", rslt); + + /* Disabling advance power save mode as FIFO data is not accessible in advance low power mode */ + rslt = bma4_set_advance_power_save(BMA4_DISABLE, &dev); + bma4_error_codes_print_result("bma4_set_advance_power_save status", rslt); + + /* Clear FIFO configuration register */ + rslt = bma4_set_fifo_config(BMA4_FIFO_ALL, BMA4_DISABLE, &dev); + bma4_error_codes_print_result("bma4_set_fifo_config disable status", rslt); + + /* Set FIFO configuration by enabling accel. + * NOTE 1: The header mode is enabled by default. + * NOTE 2: By default the FIFO operating mode is FIFO mode. */ + rslt = bma4_set_fifo_config(BMA4_FIFO_ACCEL, BMA4_ENABLE, &dev); + bma4_error_codes_print_result("bma4_set_fifo_config enable status", rslt); + + /* Update FIFO structure */ + fifoframe.data = fifo_data; + fifoframe.length = BMA456_TABLET_FIFO_RAW_DATA_USER_LENGTH; + + /* To enable headerless mode, disable the header. */ + rslt = bma4_set_fifo_config(BMA4_FIFO_HEADER, BMA4_DISABLE, &dev); + bma4_error_codes_print_result("bma4_set_fifo_config status", rslt); + + printf("FIFO is configured in headerless mode\n"); + + rslt = bma456_tablet_map_interrupt(BMA4_INTR1_MAP, BMA4_FIFO_WM_INT, BMA4_ENABLE, &dev); + bma4_error_codes_print_result("bma456_tablet_map_interrupt status", rslt); + + wm_lvl = BMA456_TABLET_FIFO_WATERMARK_LEVEL; + rslt = bma4_set_fifo_wm(wm_lvl, &dev); + bma4_error_codes_print_result("bma4_set_fifo_wm status", rslt); + + while (loop <= 10) + { + rslt = bma456_tablet_read_int_status(&int_status, &dev); + bma4_error_codes_print_result("bma456_tablet_read_int_status", rslt); + + if ((rslt == BMA4_OK) && (int_status & BMA4_FIFO_WM_INT)) + { + printf("\nIteration : %d\n", loop); + + rslt = bma4_get_fifo_wm(&watermark, &dev); + bma4_error_codes_print_result("bma4_get_fifo_wm status", rslt); + + printf("FIFO watermark level : %d\n", watermark); + + rslt = bma4_get_fifo_length(&fifo_length, &dev); + bma4_error_codes_print_result("bma4_get_fifo_length status", rslt); + + printf("FIFO data bytes available : %d\n", fifo_length); + printf("FIFO data bytes requested : %d\n", fifoframe.length); + + /* Read FIFO data */ + rslt = bma4_read_fifo_data(&fifoframe, &dev); + bma4_error_codes_print_result("bma4_read_fifo_data status", rslt); + + accel_length = BMA456_TABLET_FIFO_ACCEL_FRAME_COUNT; + + if (rslt == BMA4_OK) + { + printf("Requested data frames before parsing: %d\n", accel_length); + + /* Parse the FIFO data to extract accelerometer data from the FIFO buffer */ + rslt = bma4_extract_accel(fifo_accel_data, &accel_length, &fifoframe, &dev); + printf("Parsed accelerometer data frames: %d\n", accel_length); + + printf("ACCEL, X, Y, Z\n"); + + /* Print the parsed accelerometer data from the FIFO buffer */ + for (idx = 0; idx < accel_length; idx++) + { + printf("%d, %d, %d, %d\n", + idx, + fifo_accel_data[idx].x, + fifo_accel_data[idx].y, + fifo_accel_data[idx].z); + } + } + + loop++; + } + } + + bma4_coines_deinit(); + + return rslt; +} diff --git a/components/bma456/bma456_tablet_examples/low_g/Makefile b/components/bma456/bma456_tablet_examples/low_g/Makefile new file mode 100644 index 0000000..2f0bcbb --- /dev/null +++ b/components/bma456/bma456_tablet_examples/low_g/Makefile @@ -0,0 +1,18 @@ +COINES_INSTALL_PATH ?= ../../../.. + +EXAMPLE_FILE ?= low_g.c + +API_LOCATION ?= ../.. + +COMMON_LOCATION ?= .. + +C_SRCS += \ +$(API_LOCATION)/bma4.c \ +$(API_LOCATION)/bma456_tablet.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/components/bma456/bma456_tablet_examples/low_g/low_g.c b/components/bma456/bma456_tablet_examples/low_g/low_g.c new file mode 100644 index 0000000..59a390c --- /dev/null +++ b/components/bma456/bma456_tablet_examples/low_g/low_g.c @@ -0,0 +1,96 @@ +/**\ + * Copyright (c) 2023 Bosch Sensortec GmbH. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + **/ + +#include +#include "bma456_tablet.h" +#include "common.h" + +/******************************************************************************/ +/*! Function */ + +/* This function starts the execution of program. */ +int main(void) +{ + /* Variable to store the status of API */ + int8_t rslt; + + /* Sensor initialization configuration */ + struct bma4_dev bma = { 0 }; + + /* Variable to store step activity interrupt status */ + uint16_t int_status = 0; + + struct bma456_tablet_low_g_config low_g = { 0 }; + struct bma456_tablet_low_g_config get_low_g = { 0 }; + + /* Interface reference is given as a parameter + * For I2C : BMA4_I2C_INTF + * For SPI : BMA4_SPI_INTF + * Variant information given as parameter - BMA45X_VARIANT + */ + rslt = bma4_interface_init(&bma, BMA4_I2C_INTF, BMA45X_VARIANT); + bma4_error_codes_print_result("bma4_interface_init", rslt); + + /* Sensor initialization */ + rslt = bma456_tablet_init(&bma); + bma4_error_codes_print_result("bma456_tablet_init status", rslt); + + /* Upload the configuration file to enable the features of the sensor. */ + rslt = bma456_tablet_write_config_file(&bma); + bma4_error_codes_print_result("bma456_tablet_write_config status", rslt); + + /* Enable the accelerometer */ + rslt = bma4_set_accel_enable(BMA4_ENABLE, &bma); + bma4_error_codes_print_result("bma4_set_accel_enable status", rslt); + + low_g.threshold = 0x133; + low_g.duration = 0x0; + low_g.hysteresis = 0x100; + + rslt = bma456_tablet_set_low_g_config(&low_g, &bma); + bma4_error_codes_print_result("bma456_tablet_feature_enable status", rslt); + + rslt = bma456_tablet_get_low_g_config(&get_low_g, &bma); + bma4_error_codes_print_result("bma456_tablet_feature_enable status", rslt); + + printf("Low-g Threshold : 0x%x\n\n", get_low_g.threshold); + + /* Enable low-g feature */ + rslt = bma456_tablet_feature_enable(BMA456_TABLET_LOW_G, 1, &bma); + bma4_error_codes_print_result("bma456_tablet_feature_enable status", rslt); + + if (rslt == BMA4_OK) + { + /* Map the interrupt 1 for low-g detection */ + rslt = bma456_tablet_map_interrupt(BMA4_INTR1_MAP, BMA456_TABLET_LOW_G_INT, BMA4_ENABLE, &bma); + bma4_error_codes_print_result("bma456_tablet_map_interrupt status", rslt); + + if (rslt == BMA4_OK) + { + printf("Drop the board for low-g\n"); + + for (;;) + { + /* Read interrupt status */ + rslt = bma456_tablet_read_int_status(&int_status, &bma); + bma4_error_codes_print_result("bma456_tablet_read_int_status", rslt); + + /* Filtering only the low-g interrupt */ + if ((rslt == BMA4_OK) && (int_status & BMA456_TABLET_LOW_G_INT)) + { + printf("\nLow-g interrupt occurred\n"); + break; + } + + int_status = 0; + } + } + } + + bma4_coines_deinit(); + + return rslt; +} diff --git a/components/bma456/bma456_tablet_examples/motion/Makefile b/components/bma456/bma456_tablet_examples/motion/Makefile new file mode 100644 index 0000000..7fa500c --- /dev/null +++ b/components/bma456/bma456_tablet_examples/motion/Makefile @@ -0,0 +1,18 @@ +COINES_INSTALL_PATH ?= ../../../.. + +EXAMPLE_FILE ?= motion.c + +API_LOCATION ?= ../.. + +COMMON_LOCATION ?= .. + +C_SRCS += \ +$(API_LOCATION)/bma4.c \ +$(API_LOCATION)/bma456_tablet.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/components/bma456/bma456_tablet_examples/motion/motion.c b/components/bma456/bma456_tablet_examples/motion/motion.c new file mode 100644 index 0000000..521b937 --- /dev/null +++ b/components/bma456/bma456_tablet_examples/motion/motion.c @@ -0,0 +1,190 @@ +/**\ + * Copyright (c) 2023 Bosch Sensortec GmbH. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + **/ + +#include +#include "bma456_tablet.h" +#include "common.h" + +/*****************************************************************************/ +/*! Global variable */ + +/*! Structure to define any/no-motion configurations */ +struct bma456_tablet_any_no_mot_config any_no_mot = { 0 }; + +/******************************************************************************/ +/*! Static Function Declaration */ + +/*! + * @brief This internal API is used to get any/no-motion configurations. + * + * @param[in] bma : Structure instance of bma4_dev. + * + * @return Status of execution. + */ +static int8_t get_any_no_mot_config(struct bma4_dev *bma); + +/******************************************************************************/ +/*! Functions */ + +/* This function starts the execution of program. */ +int main(void) +{ + /* Variable to store the status of API */ + int8_t rslt; + + /* Sensor initialization configuration */ + struct bma4_dev bma = { 0 }; + + /* Variable to store any/no-motion interrupt status */ + uint16_t int_status = 0; + + uint8_t iteration = 20; + + /* Interface reference is given as a parameter + * For I2C : BMA4_I2C_INTF + * For SPI : BMA4_SPI_INTF + * Variant information given as parameter - BMA45X_VARIANT + */ + rslt = bma4_interface_init(&bma, BMA4_I2C_INTF, BMA45X_VARIANT); + bma4_error_codes_print_result("bma4_interface_init", rslt); + + /* Sensor initialization */ + rslt = bma456_tablet_init(&bma); + bma4_error_codes_print_result("bma456_tablet_init status", rslt); + + /* Upload the configuration file to enable the features of the sensor. */ + rslt = bma456_tablet_write_config_file(&bma); + bma4_error_codes_print_result("bma456_tablet_write_config status", rslt); + + /* Enable the accelerometer */ + rslt = bma4_set_accel_enable(BMA4_ENABLE, &bma); + bma4_error_codes_print_result("bma4_set_accel_enable status", rslt); + + /* Map the interrupt pin 1 for any/no-motion */ + rslt = bma456_tablet_map_interrupt(BMA4_INTR1_MAP, + (BMA456_TABLET_ANY_MOT_INT | BMA456_TABLET_NO_MOT_INT), + BMA4_ENABLE, + &bma); + bma4_error_codes_print_result("bma456_tablet_map_interrupt status", rslt); + + /* Get any-motion and no-motion configurations */ + rslt = get_any_no_mot_config(&bma); + bma4_error_codes_print_result("get_any_no_mot_config status", rslt); + + printf("Shake the board for any-motion interrupt whereas do not shake the board for no-motion interrupt\n"); + + if (rslt == BMA4_OK) + { + for (;;) + { + /* Read interrupt status */ + rslt = bma456_tablet_read_int_status(&int_status, &bma); + bma4_error_codes_print_result("bma456_tablet_read_int_status", rslt); + + if (rslt == BMA4_OK) + { + /* Enters only if the obtained interrupt is any-motion */ + if (int_status & BMA456_TABLET_ANY_MOT_INT) + { + printf("Any-motion interrupt occurred\n"); + iteration--; + } + /* Enters only if the obtained interrupt is no-motion */ + else if (int_status & BMA456_TABLET_NO_MOT_INT) + { + printf("No-motion interrupt occurred\n"); + iteration--; + } + + int_status = 0; + + /* Break out of the loop when iteration has reached zero */ + if (iteration == 0) + { + printf("Iterations are done. Exiting !\n\n"); + break; + } + } + } + } + + bma4_coines_deinit(); + + return rslt; +} + +/*! + * @brief This internal API is used to get any/no-motion configurations. + */ +static int8_t get_any_no_mot_config(struct bma4_dev *bma) +{ + /* Variable to store the status of API */ + int8_t rslt; + + /* Getting any-motion configuration to get default configuration */ + rslt = bma456_tablet_get_any_mot_config(&any_no_mot, bma); + bma4_error_codes_print_result("bma456_tablet_get_any_mot_config status", rslt); + + if (rslt == BMA4_OK) + { + /* Select the axis for which any/no motion interrupt should be generated */ + any_no_mot.axes_en = BMA456_TABLET_EN_ALL_AXIS; + + /* + * Set the slope threshold: + * Interrupt will be generated if the slope of all the axis exceeds the threshold (1 bit = 0.48mG) + */ + any_no_mot.threshold = 10; + + /* + * Set the duration for any-motion interrupt: + * Duration defines the number of consecutive data points for which threshold condition must be true(1 + * bit = + * 20ms) + */ + any_no_mot.duration = 4; + + /* Like threshold and duration, we can also change the config of int_bhvr and slope */ + + /* Set the threshold and duration configuration */ + rslt = bma456_tablet_set_any_mot_config(&any_no_mot, bma); + bma4_error_codes_print_result("bma456_tablet_set_any_mot_config status", rslt); + + if (rslt == BMA4_OK) + { + /* Getting no-motion configuration to get default configuration */ + rslt = bma456_tablet_get_no_mot_config(&any_no_mot, bma); + bma4_error_codes_print_result("bma456_tablet_get_no_mot_config status", rslt); + + if (rslt == BMA4_OK) + { + /* Select the axis for which any/no motion interrupt should be generated */ + any_no_mot.axes_en = BMA456_TABLET_EN_ALL_AXIS; + + /* + * Set the slope threshold: + * Interrupt will be generated if the slope of all the axis exceeds the threshold (1 bit = 0.48mG) + */ + any_no_mot.threshold = 10; + + /* + * Set the duration for no-motion interrupt: + * Duration defines the number of consecutive data points for which threshold condition must be + * true(1 bit = 20ms) + */ + any_no_mot.duration = 4; + + /* Like threshold and duration, we can also change the config of int_bhvr */ + + /* Set the threshold and duration configuration */ + rslt = bma456_tablet_set_no_mot_config(&any_no_mot, bma); + bma4_error_codes_print_result("bma456_tablet_set_no_mot_config status", rslt); + } + } + } + + return rslt; +} diff --git a/components/bma456/bma456_tablet_examples/orientation/Makefile b/components/bma456/bma456_tablet_examples/orientation/Makefile new file mode 100644 index 0000000..2e2b559 --- /dev/null +++ b/components/bma456/bma456_tablet_examples/orientation/Makefile @@ -0,0 +1,18 @@ +COINES_INSTALL_PATH ?= ../../../.. + +EXAMPLE_FILE ?= orientation.c + +API_LOCATION ?= ../.. + +COMMON_LOCATION ?= .. + +C_SRCS += \ +$(API_LOCATION)/bma4.c \ +$(API_LOCATION)/bma456_tablet.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/components/bma456/bma456_tablet_examples/orientation/orientation.c b/components/bma456/bma456_tablet_examples/orientation/orientation.c new file mode 100644 index 0000000..eb49efd --- /dev/null +++ b/components/bma456/bma456_tablet_examples/orientation/orientation.c @@ -0,0 +1,147 @@ +/**\ + * Copyright (c) 2023 Bosch Sensortec GmbH. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + **/ + +#include +#include "bma456_tablet.h" +#include "common.h" + +/******************************************************************************/ +/*! Macros */ + +#define COUNT UINT8_C(5) + +/******************************************************************************/ +/*! Function */ + +/* This function starts the execution of program. */ +int main(void) +{ + /* Variable to store the status of API */ + int8_t rslt; + + /* Sensor initialization configuration */ + struct bma4_dev bma = { 0 }; + + /* Variable to store step activity interrupt status */ + uint16_t int_status = 0; + + /* Variable to hold iteration value */ + uint8_t loop = 1; + + /* Structure to hold orientation configuration */ + struct bma456_tablet_orientation_config orient; + uint8_t orientation_out = 0; + uint8_t orientation_faceup_down = 0; + + /* Interface reference is given as a parameter + * For I2C : BMA4_I2C_INTF + * For SPI : BMA4_SPI_INTF + * Variant information given as parameter - BMA45X_VARIANT + */ + rslt = bma4_interface_init(&bma, BMA4_I2C_INTF, BMA45X_VARIANT); + bma4_error_codes_print_result("bma4_interface_init", rslt); + + /* Sensor initialization */ + rslt = bma456_tablet_init(&bma); + bma4_error_codes_print_result("bma456_tablet_init status", rslt); + + /* Upload the configuration file to enable the features of the sensor. */ + rslt = bma456_tablet_write_config_file(&bma); + bma4_error_codes_print_result("bma456_tablet_write_config status", rslt); + + /* Enable the accelerometer */ + rslt = bma4_set_accel_enable(BMA4_ENABLE, &bma); + bma4_error_codes_print_result("bma4_set_accel_enable status", rslt); + + /* Enable orientation feature */ + rslt = bma456_tablet_feature_enable(BMA456_TABLET_ORIENTATION, 1, &bma); + bma4_error_codes_print_result("bma456_tablet_feature_enable status", rslt); + + orient.upside_down = 0x01; + orient.mode = 0x02; + orient.blocking = 0x01; + orient.hold_time = 0x14; + orient.slope_thres = 0xA4; + orient.hysteresis = 0x80; + orient.theta = 0x33; + + rslt = bma456_tablet_set_orientation_config(&orient, &bma); + bma4_error_codes_print_result("bma456_tablet_set_orientation_config status", rslt); + + if (rslt == BMA4_OK) + { + /* Map the interrupt 1 for orientation detection */ + rslt = bma456_tablet_map_interrupt(BMA4_INTR1_MAP, BMA456_TABLET_ORIENTATION_INT, BMA4_ENABLE, &bma); + bma4_error_codes_print_result("bma456_tablet_map_interrupt status", rslt); + + if (rslt == BMA4_OK) + { + printf("Move the board to detect orientation\n"); + + while (loop <= COUNT) + { + int_status = 0; + + /* Read interrupt status */ + rslt = bma456_tablet_read_int_status(&int_status, &bma); + bma4_error_codes_print_result("bma456_tablet_read_int_status", rslt); + + /* Filtering only the orientation interrupt */ + if ((rslt == BMA4_OK) && (int_status & BMA456_TABLET_ORIENTATION_INT)) + { + printf("\nIteration : %d\n", loop); + + rslt = bma456_tablet_orientation_output(&orientation_out, &orientation_faceup_down, &bma); + bma4_error_codes_print_result("bma456_tablet_orientation_output", rslt); + + printf("The Orientation output is %d\n", orientation_out); + printf("The Orientation faceup/down output is %d\n", orientation_faceup_down); + + switch (orientation_faceup_down) + { + case BMA456_TABLET_FACE_UP: + printf("\nOrientation state is face up\n"); + break; + case BMA456_TABLET_FACE_DOWN: + printf("\nOrientation state is face down\n"); + break; + default: + break; + } + + switch (orientation_out) + { + case BMA456_TABLET_LANDSCAPE_LEFT: + printf("\nOrientation state is landscape left\n\n"); + break; + case BMA456_TABLET_LANDSCAPE_RIGHT: + printf("\nOrientation state is landscape right\n\n"); + break; + case BMA456_TABLET_PORTRAIT_UP_DOWN: + printf("\nOrientation state is portrait upside down\n\n"); + break; + case BMA456_TABLET_PORTRAIT_UP_RIGHT: + printf("\nOrientation state is portrait upright\n\n"); + break; + default: + break; + } + + loop++; + + if (loop > COUNT) + { + break; + } + } + } + } + } + + bma4_coines_deinit(); + + return rslt; +} diff --git a/components/bma456/bma456_tablet_examples/tap/Makefile b/components/bma456/bma456_tablet_examples/tap/Makefile new file mode 100644 index 0000000..7fa5019 --- /dev/null +++ b/components/bma456/bma456_tablet_examples/tap/Makefile @@ -0,0 +1,18 @@ +COINES_INSTALL_PATH ?= ../../../.. + +EXAMPLE_FILE ?= tap.c + +API_LOCATION ?= ../.. + +COMMON_LOCATION ?= .. + +C_SRCS += \ +$(API_LOCATION)/bma4.c \ +$(API_LOCATION)/bma456_tablet.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/components/bma456/bma456_tablet_examples/tap/tap.c b/components/bma456/bma456_tablet_examples/tap/tap.c new file mode 100644 index 0000000..8e0509a --- /dev/null +++ b/components/bma456/bma456_tablet_examples/tap/tap.c @@ -0,0 +1,127 @@ +/**\ + * Copyright (c) 2023 Bosch Sensortec GmbH. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + **/ + +#include +#include "bma456_tablet.h" +#include "common.h" + +/******************************************************************************/ +/*! Function */ + +/* This function starts the execution of program. */ +int main(void) +{ + /* Variable to store the status of API */ + int8_t rslt; + + /* Sensor initialization configuration */ + struct bma4_dev bma = { 0 }; + + /* Variable to store tap interrupt status */ + uint16_t int_status = 0; + + /* Loop variable */ + uint8_t loop = 10; + + struct bma456_tablet_tap_output tap_out = { 0 }; + struct bma456_tablet_tap_settings settings = { 0 }; + + /* Interface reference is given as a parameter + * For I2C : BMA4_I2C_INTF + * For SPI : BMA4_SPI_INTF + * Variant information given as parameter - BMA45X_VARIANT + */ + rslt = bma4_interface_init(&bma, BMA4_SPI_INTF, BMA45X_VARIANT); + bma4_error_codes_print_result("bma4_interface_init", rslt); + + /* Sensor initialization */ + rslt = bma456_tablet_init(&bma); + bma4_error_codes_print_result("bma456_tablet_init status", rslt); + + /* Upload the configuration file to enable the features of the sensor. */ + rslt = bma456_tablet_write_config_file(&bma); + bma4_error_codes_print_result("bma456_tablet_write_config status", rslt); + + /* Enable the accelerometer */ + rslt = bma4_set_accel_enable(BMA4_ENABLE, &bma); + bma4_error_codes_print_result("bma4_set_accel_enable status", rslt); + + if (rslt == BMA4_OK) + { + /* Map the interrupt pin 1 for tap detection */ + rslt = bma456_tablet_map_interrupt(BMA4_INTR1_MAP, BMA456_TABLET_TAP_OUT_INT, BMA4_ENABLE, &bma); + bma4_error_codes_print_result("bma456_tablet_map_interrupt status", rslt); + + if (rslt == BMA4_OK) + { + /* Enabling the single, double and triple tap features */ + rslt = + bma456_tablet_feature_enable( + (BMA456_TABLET_SINGLE_TAP | BMA456_TABLET_DOUBLE_TAP | BMA456_TABLET_TRIPLE_TAP), + BMA4_ENABLE, + &bma); + bma4_error_codes_print_result("bma456_tablet_feature_enable status", rslt); + + if (rslt == BMA4_OK) + { + /* Getting tap parameters settings */ + rslt = bma456_tablet_tap_get_parameter(&settings, &bma); + bma4_error_codes_print_result("bma456_tablet_tap_get_parameter status", rslt); + } + } + + if (rslt == BMA4_OK) + { + printf("Tap the board either single, double or triple tap\n"); + + while (loop > 0) + { + /* Read interrupt status */ + rslt = bma456_tablet_read_int_status(&int_status, &bma); + bma4_error_codes_print_result("bma456_tablet_read_int_status", rslt); + + /* Filtering only the tap interrupt */ + if ((rslt == BMA4_OK) && (int_status & BMA456_TABLET_TAP_OUT_INT)) + { + rslt = bma456_tablet_tap_output(&tap_out, &bma); + + if (BMA4_OK == rslt) + { + /* Enters only if the obtained interrupt is single-tap */ + if (tap_out.s_tap) + { + printf("Single Tap interrupt occurred\n"); + } + /* Enters only if the obtained interrupt is double-tap */ + else if (tap_out.d_tap) + { + printf("Double Tap interrupt occurred\n"); + } + /* Enters only if the obtained interrupt is triple-tap */ + else if (tap_out.t_tap) + { + printf("Triple Tap interrupt occurred\n"); + } + + loop--; + } + + int_status = 0; + } + } + + /* Break out of the loop when iteration has reached zero */ + if (loop == 0) + { + printf("Iterations are done. Exiting !\n\n"); + } + } + } + + bma4_coines_deinit(); + + return rslt; +} diff --git a/components/bma456/bma456an_examples/accel_foc/Makefile b/components/bma456/bma456an_examples/accel_foc/Makefile new file mode 100644 index 0000000..4169ddd --- /dev/null +++ b/components/bma456/bma456an_examples/accel_foc/Makefile @@ -0,0 +1,18 @@ +COINES_INSTALL_PATH ?= ../../../.. + +EXAMPLE_FILE ?= accel_foc.c + +API_LOCATION ?= ../.. + +COMMON_LOCATION ?= .. + +C_SRCS += \ +$(API_LOCATION)/bma4.c \ +$(API_LOCATION)/bma456_an.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/components/bma456/bma456an_examples/accel_foc/accel_foc.c b/components/bma456/bma456an_examples/accel_foc/accel_foc.c new file mode 100644 index 0000000..00c37e6 --- /dev/null +++ b/components/bma456/bma456an_examples/accel_foc/accel_foc.c @@ -0,0 +1,741 @@ +/**\ + * Copyright (c) 2022 Bosch Sensortec GmbH. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + **/ + +/******************************************************************************/ +/*! Header Files */ +#include +#include +#include +#include +#include + +#include "bma456_an.h" +#include "common.h" +#include "coines.h" + +/******************************************************************************/ +/*! Macro Definitions */ + +#define ACCEL_SAMPLE_COUNT UINT8_C(100) + +/******************************************************************************/ +/*! Global Variable Declaration */ + +/* Structure to store temporary axes data values */ +struct temp_axes_val +{ + /* X data */ + int32_t x; + + /* Y data */ + int32_t y; + + /* Z data */ + int32_t z; +}; + +/******************************************************************************/ +/*! Static Function Declaration */ + +/*! + * @brief This internal API is used perform accel foc and determine limits based on range + * + * @param[in] range : Range of Accel + * @param[in] input_axis : Axis selected for Accel FOC + * @param[in,out] dev : Structure instance of bma4_dev. + * + * @return Status of execution. + */ +static int8_t perform_foc_range_test(uint8_t range, uint8_t input_axis, struct bma4_dev *dev); + +/*! + * @brief This internal API is to determine if average accel FOC data is within limits + * + * @param[in] avg_accel_foc_data : Average Accel FOC value + * @param[in] reference : Reference LSB based on Accel Range + * @param[in] foc_sign : Input sign of performed Accel FOC + * @param[in] min_val : Minimum acceptable LSB limit + * @param[in] max_val : Maximum acceptable LSB limit + * + * @return Status of execution. + */ +static int8_t accel_foc_report(int16_t avg_accel_foc_data, + int16_t reference, + uint8_t foc_sign, + int16_t min_val, + int16_t max_val); + +/*! + * @brief This internal API is to collect and verify accel sensor data + * + * @param[in] range : Value of Accel range + * @param[in] reference : Reference LSB based on Accel Range + * @param[in] matched_axis : Input Axis to perform Accel FOC + * @param[in] foc_sign : Input sign to perform Accel FOC + * @param[in,out] dev : Structure instance of bma4_dev. + * + * @return Status of execution. + */ +static int8_t verify_accel_foc_data(uint8_t range, + int16_t reference, + int8_t matched_axis, + uint8_t foc_sign, + struct bma4_dev *dev); + +/*! + * @brief This internal API is to calculate noise level for Accel FOC data + * + * @param[in] matched_axis : Input Axis to perform accel FOC + * @param[in] accel_foc_data : Array of Accel FOC data + * @param[in] avg_accel_foc_data : Average Accel FOC data + * + * @return Status of execution. + */ +static void calculate_noise(int8_t matched_axis, + const struct bma4_accel *accel_foc_data, + const struct bma4_accel avg_accel_foc_data); + +/******************************************************************************/ +/*! Functions */ + +/* This function starts the execution of program. */ +int main(void) +{ + /* Sensor initialization configuration. */ + struct bma4_dev dev; + + uint8_t try = 0, j; + int8_t rslt; + struct bma4_accel_config accel_conf = { 0 }; + uint8_t data = 0, range, input_axis = 0; + + /* Interface reference is given as a parameter + * For I2C : BMA4_I2C_INTF + * For SPI : BMA4_SPI_INTF + * Variant information given as parameter - BMA45X_VARIANT + */ + rslt = bma4_interface_init(&dev, BMA4_I2C_INTF, BMA45X_VARIANT); + bma4_error_codes_print_result("bma4_interface_init", rslt); + + printf("Functional test for accel foc start..\n\n"); + + printf("Choose the axis for accel FOC to be done\n"); + printf("Press '1' to choose X axis\n"); + printf("Press '2' to choose Y axis\n"); + printf("Press '3' to choose Z axis\n"); + + printf("Press '4' to choose -X axis\n"); + printf("Press '5' to choose -Y axis\n"); + printf("Press '6' to choose -Z axis\n"); + + for (;;) + { + scanf("%u", (unsigned int *)&input_axis); + if (input_axis > 0 && input_axis < 7) + { + break; + } + } + + if (input_axis == 1) + { + printf("The choosen input axis for FOC is : X\n"); + } + else if (input_axis == 2) + { + printf("The choosen input axis for FOC is : Y\n"); + } + else if (input_axis == 3) + { + printf("The choosen input axis for FOC is : Z\n"); + } + else if (input_axis == 4) + { + printf("The choosen input axis for FOC is : -X\n"); + } + else if (input_axis == 5) + { + printf("The choosen input axis for FOC is : -Y\n"); + } + else if (input_axis == 6) + { + printf("The choosen input axis for FOC is : -Z\n"); + } + + printf("Confirm your chosen axis and the sensor keeping position are same before doing FOC\n"); + + for (j = 0; j < 2; j++) + { + try = 0; + + if (j == 1) + { + printf("Keep sensor in wrong position and press 5\n"); + } + else if (j == 0) + { + printf("Keep sensor in right position and press 5\n"); + } + + for (;;) + { + scanf("%hu", (short unsigned int *)&try); + if (try == 5) + { + break; + } + } + + for (range = BMA4_ACCEL_RANGE_2G; range <= BMA4_ACCEL_RANGE_16G; range++) + { + /****************************************************************/ + /* Initialize by enabling configuration load */ + printf("#########################################################\n\n"); + + rslt = bma456_an_init(&dev); + bma4_error_codes_print_result("bma4_init", rslt); + + /* Upload the configuration file to enable the features of the sensor. */ + rslt = bma456_an_write_config_file(&dev); + bma4_error_codes_print_result("bma4_write_config", rslt); + + /* Enable the accelerometer */ + rslt = bma4_set_accel_enable(BMA4_ENABLE, &dev); + bma4_error_codes_print_result("bma4_set_accel_enable status", rslt); + + /* Accelerometer Configuration Settings */ + /* Output Data Rate */ + accel_conf.odr = BMA4_OUTPUT_DATA_RATE_50HZ; + + /* Gravity range of the sensor (+/- 2G, 4G, 8G, 16G) */ + accel_conf.range = range; + + /* The bandwidth parameter is used to configure the number of sensor samples that are averaged + * if it is set to 2, then 2^(bandwidth parameter) samples + * are averaged, resulting in 4 averaged samples + * Note1 : For more information, refer the datasheet. + * Note2 : A higher number of averaged samples will result in a less noisier signal, but + * this has an adverse effect on the power consumed. + */ + accel_conf.bandwidth = BMA4_ACCEL_NORMAL_AVG4; + + /* Enable the filter performance mode where averaging of samples + * will be done based on above set bandwidth and ODR. + * There are two modes + * 0 -> Averaging samples (Default) + * 1 -> No averaging + * For more info on No Averaging mode refer datasheet. + */ + accel_conf.perf_mode = BMA4_CIC_AVG_MODE; + + /* Set the accel configurations */ + rslt = bma4_set_accel_config(&accel_conf, &dev); + bma4_error_codes_print_result("bma4_set_accel_config status", rslt); + + /* Delay to set accel sensor configurations (20ms for 50HZ) */ + dev.delay_us(20000, dev.intf_ptr); + + /* Mapping data ready interrupt with interrupt1 to get interrupt status once getting new accel data */ + rslt = bma456_an_map_interrupt(BMA4_INTR1_MAP, BMA4_DATA_RDY_INT, BMA4_ENABLE, &dev); + bma4_error_codes_print_result("bma4_map_interrupt status", rslt); + + printf("ODR = %d, RANGE = %d, BANDWIDTH = %d\n", accel_conf.odr, accel_conf.range, accel_conf.bandwidth); + + /* Perform FOC for different ranges */ + rslt = perform_foc_range_test(range, input_axis, &dev); + + if ((j == 1) && (rslt == BMA4_E_OUT_OF_RANGE)) + { + printf("\n######### Valid input - Wrong position #########\n\n"); + bma4_error_codes_print_result("perform_foc_range_test", rslt); + } + else if ((j == 0) && (rslt == BMA4_OK)) + { + printf("\n######### Valid input - Right position #########\n\n"); + bma4_error_codes_print_result("perform_foc_range_test", rslt); + } + else if ((j == 1) && (rslt == BMA4_OK)) + { + printf("\n######### Invalid input - Right position #########\n\n"); + bma4_error_codes_print_result("perform_foc_range_test", rslt); + } + else if ((j == 0) && (rslt == BMA4_E_OUT_OF_RANGE)) + { + printf("\n######### Invalid input - Wrong position #########\n\n"); + bma4_error_codes_print_result("perform_foc_range_test", rslt); + } + else if ((j == 0) && (rslt == BMA4_E_OUT_OF_RANGE)) + { + printf("\n######### Valid input - Right position #########\n\n"); + printf("\n######### Before FOC is better than after FOC #########\n\n"); + bma4_error_codes_print_result("perform_foc_range_test", rslt); + } + else if ((j == 1) && (rslt == BMA4_E_OUT_OF_RANGE)) + { + printf("\n######### Invalid input - Right position #########\n\n"); + printf("\n######### Before FOC is better than after FOC #########\n\n"); + bma4_error_codes_print_result("perform_foc_range_test", rslt); + } + } + + /* Disable offset compensation */ + rslt = bma4_read_regs(BMA4_NV_CONFIG_ADDR, &data, 1, &dev); + bma4_error_codes_print_result("bma4_read_regs", rslt); + + data = BMA4_SET_BIT_VAL_0(data, BMA4_NV_ACCEL_OFFSET); + + rslt = bma4_write_regs(BMA4_NV_CONFIG_ADDR, &data, 1, &dev); + bma4_error_codes_print_result("bma4_write_regs", rslt); + } + + bma4_coines_deinit(); + + return rslt; +} + +static int8_t accel_foc_report(int16_t avg_accel_foc_data, + int16_t reference, + uint8_t foc_sign, + int16_t min_val, + int16_t max_val) +{ + int8_t rslt = BMA4_OK; + int16_t diff_after = 0; + + if (foc_sign == 0) + { + if ((avg_accel_foc_data >= (min_val)) && (avg_accel_foc_data <= (max_val))) + { + if (avg_accel_foc_data >= reference) + { + diff_after = avg_accel_foc_data - reference; + } + else + { + diff_after = reference - avg_accel_foc_data; + } + + printf("\n# ********** PASS | Difference = %d **********\n", diff_after); + printf("\n# Avg_FOC %d in range\n", avg_accel_foc_data); + rslt = BMA4_OK; + } + else + { + if (avg_accel_foc_data >= reference) + { + diff_after = avg_accel_foc_data - reference; + } + else + { + diff_after = reference - avg_accel_foc_data; + } + + printf("\n# ********** FAIL | Difference = %d **********\n", diff_after); + printf("\n# Avg_FOC %d not in range\n", avg_accel_foc_data); + rslt = BMA4_E_OUT_OF_RANGE; + } + } + + if (foc_sign == 1) + { + if ((avg_accel_foc_data <= (min_val)) && (avg_accel_foc_data >= (max_val))) + { + if (avg_accel_foc_data <= reference) + { + diff_after = avg_accel_foc_data - reference; + } + else + { + diff_after = reference - avg_accel_foc_data; + } + + printf("\n# ********** PASS | Difference = %d **********\n", diff_after); + printf("\n# Avg_FOC %d in range\n", avg_accel_foc_data); + rslt = BMA4_OK; + } + else + { + if (avg_accel_foc_data <= reference) + { + diff_after = avg_accel_foc_data - reference; + } + else + { + diff_after = reference - avg_accel_foc_data; + } + + printf("\n# ********** FAIL | Difference = %d **********\n", diff_after); + printf("\n# Avg_FOC %d not in range\n", avg_accel_foc_data); + rslt = BMA4_E_OUT_OF_RANGE; + } + } + + return rslt; +} + +static void calculate_noise(int8_t matched_axis, + const struct bma4_accel *accel_foc_data, + const struct bma4_accel avg_accel_foc_data) +{ + int32_t variance = 0; + double noise_level; + uint16_t idx = 0; + + if (matched_axis == 'X') + { + for (idx = 0; idx < ACCEL_SAMPLE_COUNT; idx++) + { + variance += + ((accel_foc_data[idx].x - avg_accel_foc_data.x) * (accel_foc_data[idx].x - avg_accel_foc_data.x)); + } + } + else if (matched_axis == 'Y') + { + for (idx = 0; idx < ACCEL_SAMPLE_COUNT; idx++) + { + variance += + ((accel_foc_data[idx].y - avg_accel_foc_data.y) * (accel_foc_data[idx].y - avg_accel_foc_data.y)); + } + } + else if (matched_axis == 'Z') + { + for (idx = 0; idx < ACCEL_SAMPLE_COUNT; idx++) + { + variance += + ((accel_foc_data[idx].z - avg_accel_foc_data.z) * (accel_foc_data[idx].z - avg_accel_foc_data.z)); + } + } + + noise_level = sqrt((double)variance); + + printf("\n# ********** NOISE LEVEL = %lf **********\n", noise_level); +} + +static int8_t verify_accel_foc_data(uint8_t range, + int16_t reference, + int8_t matched_axis, + uint8_t foc_sign, + struct bma4_dev *dev) +{ + int8_t rslt = BMA4_E_INVALID_STATUS; + uint8_t i; + uint16_t reg_status = 0; + int16_t xl, yl, zl; + int16_t xh, yh, zh; + int16_t min_val = 0; + int16_t max_val = 0; + struct bma4_accel accel_foc_data[ACCEL_SAMPLE_COUNT] = { { 0 } }; + struct temp_axes_val temp_foc_data = { 0 }; + struct bma4_accel avg_accel_foc_data = { 0 }; + struct bma4_accel sensor_data = { 0 }; + + /* Setting initial values */ + xl = yl = zl = 32767; + xh = yh = zh = -32768; + + /* Read accelerometer values before/after FOC */ + for (i = 0; i < ACCEL_SAMPLE_COUNT; i++) + { + for (;;) + { + /* To get the data ready interrupt status */ + rslt = bma4_read_int_status(®_status, dev); + bma4_error_codes_print_result("bma4_read_int_status", rslt); + + /* Read accelerometer data based on data ready interrupt */ + if ((rslt == BMA4_OK) && (reg_status & BMA4_ACCEL_DATA_RDY_INT)) + { + rslt = bma4_read_accel_xyz(&sensor_data, dev); + bma4_error_codes_print_result("bma4_read_accel_xyz", rslt); + + memcpy(&accel_foc_data[i], &sensor_data, sizeof(struct bma4_accel)); + + printf("X[%d] = %5d Y[%d] = %5d Z[%d] = %5d\n", + i, + accel_foc_data[i].x, + i, + accel_foc_data[i].y, + i, + accel_foc_data[i].z); + + if (xl > accel_foc_data[i].x) + { + xl = accel_foc_data[i].x; + } + + if (xh < accel_foc_data[i].x) + { + xh = accel_foc_data[i].x; + } + + if (yl > accel_foc_data[i].y) + { + yl = accel_foc_data[i].y; + } + + if (yh < accel_foc_data[i].y) + { + yh = accel_foc_data[i].y; + } + + if (zl > accel_foc_data[i].z) + { + zl = accel_foc_data[i].z; + } + + if (zh < accel_foc_data[i].z) + { + zh = accel_foc_data[i].z; + } + + temp_foc_data.x += accel_foc_data[i].x; + temp_foc_data.y += accel_foc_data[i].y; + temp_foc_data.z += accel_foc_data[i].z; + break; + + } + } + } + + /* Taking average values to calculate percentage deviation */ + avg_accel_foc_data.x = (int16_t)(temp_foc_data.x / ACCEL_SAMPLE_COUNT); + avg_accel_foc_data.y = (int16_t)(temp_foc_data.y / ACCEL_SAMPLE_COUNT); + avg_accel_foc_data.z = (int16_t)(temp_foc_data.z / ACCEL_SAMPLE_COUNT); + + printf("********* MIN & MAX VALUES ********\n"); + + printf("XL = %5d YL = %5d ZL = %5d\n", xl, yl, zl); + printf("XH = %5d YH = %5d ZH = %5d\n", xh, yh, zh); + + printf("***** AVERAGE AFTER FOC *****\n"); + printf("Avg-X = %d Avg-Y = %d Avg-Z = %d\n", + avg_accel_foc_data.x, + avg_accel_foc_data.y, + avg_accel_foc_data.z); + + /* Calculate noise level */ + calculate_noise(matched_axis, accel_foc_data, avg_accel_foc_data); + + /* "zero-g offset" of accel is +/- 20 mg for all ranges as per datasheet (for 16-bit resolution) */ + if (range == 0) + { + /* Min and Max limits for Range 2G */ + min_val = BMA4_16BIT_ACC_2G_MIN_NOISE_LIMIT; + max_val = BMA4_16BIT_ACC_2G_MAX_NOISE_LIMIT; + } + else if (range == 1) + { + /* Min and Max limits for Range 4G */ + min_val = BMA4_16BIT_ACC_4G_MIN_NOISE_LIMIT; + max_val = BMA4_16BIT_ACC_4G_MAX_NOISE_LIMIT; + } + else if (range == 2) + { + /* Min and Max limits for Range 8G */ + min_val = BMA4_16BIT_ACC_8G_MIN_NOISE_LIMIT; + max_val = BMA4_16BIT_ACC_8G_MAX_NOISE_LIMIT; + } + else if (range == 3) + { + /* Min and Max limits for Range 16G */ + min_val = BMA4_16BIT_ACC_16G_MIN_NOISE_LIMIT; + max_val = BMA4_16BIT_ACC_16G_MAX_NOISE_LIMIT; + } + + if ((matched_axis == 'X') && (foc_sign == 0)) + { + rslt = accel_foc_report(avg_accel_foc_data.x, reference, foc_sign, min_val, max_val); + printf("Range : %u Avg_FOC-X : %d Reference : %d Min_Value : %d Max_Value : %d\n", + range, + avg_accel_foc_data.x, + reference, + min_val, + max_val); + } + else if ((matched_axis == 'Y') && (foc_sign == 0)) + { + rslt = accel_foc_report(avg_accel_foc_data.y, reference, foc_sign, min_val, max_val); + printf("Range : %u Avg_FOC-X : %d Reference : %d Min_Value : %d Max_Value : %d\n", + range, + avg_accel_foc_data.y, + reference, + min_val, + max_val); + } + else if ((matched_axis == 'Z') && (foc_sign == 0)) + { + rslt = accel_foc_report(avg_accel_foc_data.z, reference, foc_sign, min_val, max_val); + printf("Range : %u Avg_FOC-X : %d Reference : %d Min_Value : %d Max_Value : %d\n", + range, + avg_accel_foc_data.z, + reference, + min_val, + max_val); + } + else if ((matched_axis == 'X') && (foc_sign == 1)) + { + rslt = accel_foc_report(avg_accel_foc_data.x, + (int16_t)(reference * (-1)), + foc_sign, + (int16_t)(min_val * (-1)), + (int16_t)(max_val * (-1))); + printf("Range : %u Avg_FOC-X : %d Reference : %d Min_Value : %d Max_Value : %d\n", + range, + avg_accel_foc_data.x, + (reference * (-1)), + (min_val * (-1)), + (max_val * (-1))); + } + else if ((matched_axis == 'Y') && (foc_sign == 1)) + { + rslt = accel_foc_report(avg_accel_foc_data.y, + (int16_t)(reference * (-1)), + foc_sign, + (int16_t)(min_val * (-1)), + (int16_t)(max_val * (-1))); + printf("Range : %u Avg_FOC-X : %d Reference : %d Min_Value : %d Max_Value : %d\n", + range, + avg_accel_foc_data.y, + (reference * (-1)), + (min_val * (-1)), + (max_val * (-1))); + } + else if ((matched_axis == 'Z') && (foc_sign == 1)) + { + rslt = accel_foc_report(avg_accel_foc_data.z, + (int16_t)(reference * (-1)), + foc_sign, + (int16_t)(min_val * (-1)), + (int16_t)(max_val * (-1))); + printf("Range : %u Avg_FOC-X : %d Reference : %d Min_Value : %d Max_Value : %d\n", + range, + avg_accel_foc_data.z, + (reference * (-1)), + (min_val * (-1)), + (max_val * (-1))); + } + + return rslt; +} + +/* Perform FOC for different range and resolutions */ +static int8_t perform_foc_range_test(uint8_t range, uint8_t input_axis, struct bma4_dev *dev) +{ + int8_t rslt; + int8_t matched_axis = 0; + int16_t reference = 0; + + /* Set accel foc axis and it's sign (x, y, z, sign)*/ + struct bma4_accel_foc_g_value g_value_foc = { 0, 0, 0, 0 }; + + if (input_axis == 1) + { + g_value_foc.x = 1; + g_value_foc.y = 0; + g_value_foc.z = 0; + g_value_foc.sign = 0; + } + else if (input_axis == 2) + { + g_value_foc.x = 0; + g_value_foc.y = 1; + g_value_foc.z = 0; + g_value_foc.sign = 0; + } + else if (input_axis == 3) + { + g_value_foc.x = 0; + g_value_foc.y = 0; + g_value_foc.z = 1; + g_value_foc.sign = 0; + } + else if (input_axis == 4) + { + g_value_foc.x = 1; + g_value_foc.y = 0; + g_value_foc.z = 0; + g_value_foc.sign = 1; + } + else if (input_axis == 5) + { + g_value_foc.x = 0; + g_value_foc.y = 1; + g_value_foc.z = 0; + g_value_foc.sign = 1; + } + else if (input_axis == 6) + { + g_value_foc.x = 0; + g_value_foc.y = 0; + g_value_foc.z = 1; + g_value_foc.sign = 1; + } + + switch (range) + { + /* Reference LSB value of 2G */ + case 0: + reference = BMA4_16BIT_ACC_FOC_2G_REF; + break; + + /* Reference LSB value of 4G */ + case 1: + reference = BMA4_16BIT_ACC_FOC_4G_REF; + break; + + /* Reference LSB value of 8G */ + case 2: + reference = BMA4_16BIT_ACC_FOC_8G_REF; + break; + + /* Reference LSB value of 16G */ + case 3: + reference = BMA4_16BIT_ACC_FOC_16G_REF; + break; + default: + break; + } + + if (g_value_foc.x == 1) + { + matched_axis = 'X'; + } + else if (g_value_foc.y == 1) + { + matched_axis = 'Y'; + } + else if (g_value_foc.z == 1) + { + matched_axis = 'Z'; + } + + if (g_value_foc.sign == 1) + { + printf("MATCHED AXIS is = -%c\n", matched_axis); + } + else + { + printf("MATCHED AXIS is = %c\n", matched_axis); + } + + printf("\n\n# Before FOC\n"); + rslt = verify_accel_foc_data(range, reference, matched_axis, g_value_foc.sign, dev); + bma4_error_codes_print_result("bma4_perform_accel_foc", rslt); + + printf("\n\n######### Perform Accel FOC #########\n\n"); + + /* Perform accelerometer FOC */ + rslt = bma4_perform_accel_foc(&g_value_foc, dev); + bma4_error_codes_print_result("bma4_perform_accel_foc", rslt); + + /* Delay after performing Accel FOC */ + dev->delay_us(30000, dev->intf_ptr); + + printf("\n\n# After FOC\n"); + rslt = verify_accel_foc_data(range, reference, matched_axis, g_value_foc.sign, dev); + + return rslt; +} diff --git a/components/bma456/bma456an_examples/accelerometer/Makefile b/components/bma456/bma456an_examples/accelerometer/Makefile new file mode 100644 index 0000000..74bcdea --- /dev/null +++ b/components/bma456/bma456an_examples/accelerometer/Makefile @@ -0,0 +1,18 @@ +COINES_INSTALL_PATH ?= ../../../.. + +EXAMPLE_FILE ?= accelerometer.c + +API_LOCATION ?= ../.. + +COMMON_LOCATION ?= .. + +C_SRCS += \ +$(API_LOCATION)/bma4.c \ +$(API_LOCATION)/bma456_an.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/components/bma456/bma456an_examples/accelerometer/accelerometer.c b/components/bma456/bma456an_examples/accelerometer/accelerometer.c new file mode 100644 index 0000000..d8ba0a3 --- /dev/null +++ b/components/bma456/bma456an_examples/accelerometer/accelerometer.c @@ -0,0 +1,162 @@ +/**\ + * Copyright (c) 2022 Bosch Sensortec GmbH. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + **/ +#include +#include "bma456_an.h" +#include "common.h" + +/******************************************************************************/ +/*! Macro definition */ + +/*! Earth's gravity in m/s^2 */ +#define GRAVITY_EARTH (9.80665f) + +/*! Macro that holds the total number of accel x,y and z axes sample counts to be printed */ +#define ACCEL_SAMPLE_COUNT UINT8_C(100) + +/******************************************************************************/ +/*! 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); + +/******************************************************************************/ +/*! Functions */ + +/* This function starts the execution of program. */ +int main(void) +{ + /* Variable to store the status of API */ + int8_t rslt; + + /* Sensor initialization configuration */ + struct bma4_dev bma = { 0 }; + + /* Variable to store accel data ready interrupt status */ + uint16_t int_status = 0; + + /* Variable that holds the accelerometer sample count */ + uint8_t n_data = 1; + + struct bma4_accel sens_data = { 0 }; + float x = 0, y = 0, z = 0; + struct bma4_accel_config accel_conf = { 0 }; + + /* Interface reference is given as a parameter + * For I2C : BMA4_I2C_INTF + * For SPI : BMA4_SPI_INTF + * Variant information given as parameter - BMA45X_VARIANT + */ + rslt = bma4_interface_init(&bma, BMA4_I2C_INTF, BMA45X_VARIANT); + bma4_error_codes_print_result("bma4_interface_init", rslt); + + /* Sensor initialization */ + rslt = bma456_an_init(&bma); + bma4_error_codes_print_result("bma456_an_init status", rslt); + + /* Upload the configuration file to enable the features of the sensor. */ + rslt = bma456_an_write_config_file(&bma); + bma4_error_codes_print_result("bma456_an_write_config status", rslt); + + /* Accelerometer configuration settings */ + /* Output data Rate */ + accel_conf.odr = BMA4_OUTPUT_DATA_RATE_50HZ; + + /* Gravity range of the sensor (+/- 2G, 4G, 8G, 16G) */ + accel_conf.range = BMA4_ACCEL_RANGE_2G; + + /* The bandwidth parameter is used to configure the number of sensor samples that are averaged + * if it is set to 2, then 2^(bandwidth parameter) samples + * are averaged, resulting in 4 averaged samples + * Note1 : For more information, refer the datasheet. + * Note2 : A higher number of averaged samples will result in a less noisier signal, but + * this has an adverse effect on the power consumed. + */ + accel_conf.bandwidth = BMA4_ACCEL_NORMAL_AVG4; + + /* Enable the filter performance mode where averaging of samples + * will be done based on above set bandwidth and ODR. + * There are two modes + * 0 -> Averaging samples (Default) + * 1 -> No averaging + * For more info on No Averaging mode refer datasheet. + */ + accel_conf.perf_mode = BMA4_CIC_AVG_MODE; + + /* Set the accel configurations */ + rslt = bma4_set_accel_config(&accel_conf, &bma); + bma4_error_codes_print_result("bma4_set_accel_config status", rslt); + + /* NOTE : Enable accel after set of configurations */ + rslt = bma4_set_accel_enable(1, &bma); + bma4_error_codes_print_result("bma4_set_accel_enable status", rslt); + + /* Mapping data ready interrupt with interrupt pin 1 to get interrupt status once getting new accel data */ + rslt = bma456_an_map_interrupt(BMA4_INTR1_MAP, BMA4_DATA_RDY_INT, BMA4_ENABLE, &bma); + bma4_error_codes_print_result("bma456_an_map_interrupt status", rslt); + + printf("Data, Acc_Raw_X, Acc_Raw_Y, Acc_Raw_Z, Acc_ms2_X, Acc_ms2_Y, Acc_ms2_Z\n"); + + for (;;) + { + /* Read interrupt status */ + rslt = bma456_an_read_int_status(&int_status, &bma); + bma4_error_codes_print_result("bma456_an_read_int_status", rslt); + + /* Filtering only the accel data ready interrupt */ + if ((rslt == BMA4_OK) && (int_status & BMA4_ACCEL_DATA_RDY_INT)) + { + /* Read the accel x, y, z data */ + rslt = bma4_read_accel_xyz(&sens_data, &bma); + bma4_error_codes_print_result("bma4_read_accel_xyz status", rslt); + + if (rslt == BMA4_OK) + { + + /* Converting lsb to meter per second squared for 16 bit resolution at 2G range */ + x = lsb_to_ms2(sens_data.x, (float)2, bma.resolution); + y = lsb_to_ms2(sens_data.y, (float)2, bma.resolution); + z = lsb_to_ms2(sens_data.z, (float)2, bma.resolution); + + /* Print the data in m/s2 */ + printf("%d, %d, %d, %d, %4.2f, %4.2f, %4.2f\n", n_data, sens_data.x, sens_data.y, sens_data.z, x, y, z); + } + + /* Increment the count that determines the number of samples to be printed */ + n_data++; + + /* When the count reaches more than ACCEL_SAMPLE_COUNT, break and exit the loop */ + if (n_data > ACCEL_SAMPLE_COUNT) + { + break; + } + } + } + + bma4_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/components/bma456/bma456an_examples/any_motion/Makefile b/components/bma456/bma456an_examples/any_motion/Makefile new file mode 100644 index 0000000..3e8a422 --- /dev/null +++ b/components/bma456/bma456an_examples/any_motion/Makefile @@ -0,0 +1,18 @@ +COINES_INSTALL_PATH ?= ../../../.. + +EXAMPLE_FILE ?= any_motion.c + +API_LOCATION ?= ../.. + +COMMON_LOCATION ?= .. + +C_SRCS += \ +$(API_LOCATION)/bma4.c \ +$(API_LOCATION)/bma456_an.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/components/bma456/bma456an_examples/any_motion/any_motion.c b/components/bma456/bma456an_examples/any_motion/any_motion.c new file mode 100644 index 0000000..28f0116 --- /dev/null +++ b/components/bma456/bma456an_examples/any_motion/any_motion.c @@ -0,0 +1,133 @@ +/**\ + * Copyright (c) 2022 Bosch Sensortec GmbH. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + **/ + +#include +#include "bma456_an.h" +#include "common.h" +#include "coines.h" + +/******************************************************************************/ +/*! Static Function Declaration */ + +/*! + * @brief This internal API is used to get any-motion configurations. + * + * @param[in] bma : Structure instance of bma4_dev. + * + * @return Status of execution. + */ +static int8_t get_any_no_mot_config(struct bma4_dev *bma); + +/******************************************************************************/ +/*! Functions */ + +/* This function starts the execution of program. */ +int main(void) +{ + /* Variable to store the status of API */ + int8_t rslt; + + /* Sensor initialization configuration */ + struct bma4_dev bma = { 0 }; + + /* Variable to store any/no-motion interrupt status */ + uint16_t int_status = 0; + + /* Interface reference is given as a parameter + * For I2C : BMA4_I2C_INTF + * For SPI : BMA4_SPI_INTF + * Variant information given as parameter - BMA45X_VARIANT + */ + rslt = bma4_interface_init(&bma, BMA4_I2C_INTF, BMA45X_VARIANT); + bma4_error_codes_print_result("bma4_interface_init", rslt); + + /* Sensor initialization */ + rslt = bma456_an_init(&bma); + bma4_error_codes_print_result("bma456_an_init status", rslt); + + /* Upload the configuration file to enable the features of the sensor. */ + rslt = bma456_an_write_config_file(&bma); + bma4_error_codes_print_result("bma456_an_write_config status", rslt); + + /* Enable the accelerometer */ + rslt = bma4_set_accel_enable(BMA4_ENABLE, &bma); + bma4_error_codes_print_result("bma4_set_accel_enable status", rslt); + + /* Map the interrupt 1 for any-motion */ + rslt = bma456_an_map_interrupt(BMA4_INTR1_MAP, BMA456_AN_ANY_MOT_INT, BMA4_ENABLE, &bma); + bma4_error_codes_print_result("bma456_an_map_interrupt status", rslt); + + /* Get any-motion configurations */ + rslt = get_any_no_mot_config(&bma); + bma4_error_codes_print_result("get_any_no_mot_config status", rslt); + + printf("Shake the board for any-motion interrupt\n"); + + for (;;) + { + /* Read interrupt status */ + rslt = bma456_an_read_int_status(&int_status, &bma); + bma4_error_codes_print_result("bma456_an_read_int_status", rslt); + + if (rslt == BMA4_OK) + { + /* Enters only if the obtained interrupt is any-motion */ + if (int_status & BMA456_AN_ANY_MOT_INT) + { + printf("Any-motion interrupt occurred\n"); + break; + } + } + } + + bma4_coines_deinit(); + + return rslt; +} + +/*! + * @brief This internal API is used to get any-motion configurations. + */ +static int8_t get_any_no_mot_config(struct bma4_dev *bma) +{ + /* Variable to store the status of API */ + int8_t rslt; + + /*! Structure to define any/no-motion configurations */ + struct bma456_an_any_no_mot_config any_no_mot = { 0 }; + + /* Getting any-motion configuration to get default configuration */ + rslt = bma456_an_get_any_mot_config(&any_no_mot, bma); + bma4_error_codes_print_result("bma456_an_get_any_mot_config status", rslt); + + if (rslt == BMA4_OK) + { + /* + * Set the slope threshold: + * Interrupt will be generated if the slope of all the axis exceeds the threshold (1 bit = 0.48mG) + */ + any_no_mot.threshold = 10; + + /* + * Set the duration for any-motion interrupt: + * Duration defines the number of consecutive data points for which threshold condition must be true(1 + * bit = + * 20ms) + */ + any_no_mot.duration = 4; + + /* Enabling X, Y, and Z axis for Any-motion feature */ + any_no_mot.axes_en = BMA456_AN_EN_ALL_AXIS; + + /* Like threshold and duration, we can also change the config of int_bhvr and slope */ + + /* Set the threshold and duration configuration */ + rslt = bma456_an_set_any_mot_config(&any_no_mot, bma); + bma4_error_codes_print_result("bma456_an_set_any_mot_config status", rslt); + } + + return rslt; +} diff --git a/components/bma456/bma456an_examples/axis_remap/Makefile b/components/bma456/bma456an_examples/axis_remap/Makefile new file mode 100644 index 0000000..340aa79 --- /dev/null +++ b/components/bma456/bma456an_examples/axis_remap/Makefile @@ -0,0 +1,18 @@ +COINES_INSTALL_PATH ?= ../../../.. + +EXAMPLE_FILE = axis_remap.c + +API_LOCATION ?= ../.. + +COMMON_LOCATION ?= .. + +C_SRCS += \ +$(API_LOCATION)/bma4.c \ +$(API_LOCATION)/bma456_an.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/components/bma456/bma456an_examples/axis_remap/axis_remap.c b/components/bma456/bma456an_examples/axis_remap/axis_remap.c new file mode 100644 index 0000000..83e2dc3 --- /dev/null +++ b/components/bma456/bma456an_examples/axis_remap/axis_remap.c @@ -0,0 +1,362 @@ +/**\ + * Copyright (c) 2022 Bosch Sensortec GmbH. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + **/ + +#include +#include + +#include "coines.h" +#include "bma456_an.h" +#include "common.h" + +/*********************************************************************/ +/* functions */ +/*********************************************************************/ + +/*! + * @brief Main Function where the execution getting started to test the code. + * + * @param[in] argc + * @param[in] argv + * + * @return status + * + */ +int main(void) +{ + int8_t rslt; + struct bma4_dev bma4; + struct bma4_remap remap_data = { 0 }; + struct bma4_accel accel = { 0 }; + struct bma4_accel_config accel_conf = { 0 }; + uint16_t int_status = 0; + + char data_array[13][11] = + { { 0 }, { "BMA4_X" }, { "BMA4_Y" }, { 0 }, { "BMA4_Z" }, { 0 }, { 0 }, { 0 }, { 0 }, { "BMA4_NEG_X" }, + { "BMA4_NEG_Y" }, { 0 }, { "BMA4_NEG_Z" } }; + + /* Interface reference is given as a parameter + * For I2C : BMA4_I2C_INTF + * For SPI : BMA4_SPI_INTF + * Variant information given as parameter - BMA45X_VARIANT + */ + rslt = bma4_interface_init(&bma4, BMA4_SPI_INTF, BMA45X_VARIANT); + bma4_error_codes_print_result("bma4_interface_init", rslt); + + /* Sensor initialization */ + rslt = bma456_an_init(&bma4); + bma4_error_codes_print_result("bma456_an_init", rslt); + + /* Upload the configuration file to enable the features of the sensor. */ + rslt = bma456_an_write_config_file(&bma4); + bma4_error_codes_print_result("bma456_an_write_config", rslt); + + /* Accelerometer configuration Setting */ + /* Output data Rate */ + accel_conf.odr = BMA4_OUTPUT_DATA_RATE_50HZ; + + /* Gravity range of the sensor (+/- 2G, 4G, 8G, 16G) */ + accel_conf.range = BMA4_ACCEL_RANGE_2G; + + /* The bandwidth parameter is used to configure the number of sensor samples that are averaged + * if it is set to 2, then 2^(bandwidth parameter) samples + * are averaged, resulting in 4 averaged samples + * Note1 : For more information, refer the datasheet. + * Note2 : A higher number of averaged samples will result in a less noisier signal, but + * this has an adverse effect on the power consumed. + */ + accel_conf.bandwidth = BMA4_ACCEL_NORMAL_AVG4; + + /* Enable the filter performance mode where averaging of samples + * will be done based on above set bandwidth and ODR. + * There are two modes + * 0 -> Averaging samples (Default) + * 1 -> No averaging + * For more info on No Averaging mode refer datasheet. + */ + accel_conf.perf_mode = BMA4_CIC_AVG_MODE; + + /* Set the accel configurations */ + rslt = bma4_set_accel_config(&accel_conf, &bma4); + bma4_error_codes_print_result("bma4_set_accel_config status", rslt); + + /* NOTE : Enable accel after set of configurations */ + rslt = bma4_set_accel_enable(1, &bma4); + bma4_error_codes_print_result("bma4_set_accel_enable status", rslt); + + /* Mapping data ready interrupt with interrupt pin 1 to get interrupt status once getting new accel data */ + rslt = bma456_an_map_interrupt(BMA4_INTR1_MAP, BMA4_DATA_RDY_INT, BMA4_ENABLE, &bma4); + bma4_error_codes_print_result("bma456_an_map_interrupt status", rslt); + + printf("\nAXIS_REMAP_FUNC_TEST 1\n"); + printf("Get sensor data of re-mapped axes\n"); + + rslt = bma456_an_get_remap_axes(&remap_data, &bma4); + bma4_error_codes_print_result("bma456_an_get_remap_axes", rslt); + + printf("Re-mapped x value = %s\n", data_array[remap_data.x]); + printf("Re-mapped y value = %s\n", data_array[remap_data.y]); + printf("Re-mapped z value = %s\n", data_array[remap_data.z]); + + printf("Expected Re-mapped x value = BMA4_X\n"); + printf("Expected Re-mapped y value = BMA4_Y\n"); + printf("Expected Re-mapped z value = BMA4_Z\n"); + + if ((remap_data.x == BMA4_X) && (remap_data.y == BMA4_Y) && (remap_data.z == BMA4_Z)) + { + printf(">> PASS\n"); + } + else + { + printf(">> FAIL\n"); + } + + printf("Print mapped data\n"); + + for (;;) + { + /* Read interrupt status */ + rslt = bma456_an_read_int_status(&int_status, &bma4); + bma4_error_codes_print_result("bma456_an_read_int_status", rslt); + + /* Filtering only the accel data ready interrupt */ + if ((rslt == BMA4_OK) && (int_status & BMA4_ACCEL_DATA_RDY_INT)) + { + rslt = bma4_read_accel_xyz(&accel, &bma4); + bma4_error_codes_print_result("bma4_read_accel_xyz", rslt); + + printf("Accel :: X = %d Y = %d Z = %d\n", accel.x, accel.y, accel.z); + + break; + } + } + + printf("\nAXIS_REMAP_FUNC_TEST 2\n"); + printf("Get sensor data of re-mapped axes\n"); + + remap_data.x = BMA4_NEG_Y; + remap_data.y = BMA4_Z; + remap_data.z = BMA4_NEG_X; + + rslt = bma456_an_set_remap_axes(&remap_data, &bma4); + bma4_error_codes_print_result("bma456_an_set_remap_axes", rslt); + + if (rslt == BMA4_OK) + { + rslt = bma456_an_get_remap_axes(&remap_data, &bma4); + bma4_error_codes_print_result("bma456_an_get_remap_axes", rslt); + + if (rslt == BMA4_OK) + { + printf("Re-mapped x value = %s\n", data_array[remap_data.x]); + printf("Re-mapped y value = %s\n", data_array[remap_data.y]); + printf("Re-mapped z value = %s\n", data_array[remap_data.z]); + } + + printf("Expected Re-mapped x value = BMA4_NEG_Y\n"); + printf("Expected Re-mapped y value = BMA4_Z\n"); + printf("Expected Re-mapped z value = BMA4_NEG_X\n"); + + if ((remap_data.x == BMA4_NEG_Y) && (remap_data.y == BMA4_Z) && (remap_data.z == BMA4_NEG_X)) + { + printf(">> PASS\n"); + } + else + { + printf(">> FAIL\n"); + } + } + + printf("Print mapped data\n"); + + for (;;) + { + /* Read interrupt status */ + rslt = bma456_an_read_int_status(&int_status, &bma4); + bma4_error_codes_print_result("bma456_an_read_int_status", rslt); + + /* Filtering only the accel data ready interrupt */ + if ((rslt == BMA4_OK) && (int_status & BMA4_ACCEL_DATA_RDY_INT)) + { + rslt = bma4_read_accel_xyz(&accel, &bma4); + bma4_error_codes_print_result("bma4_read_accel_xyz", rslt); + + printf("Accel :: X = %d Y = %d Z = %d\n", accel.x, accel.y, accel.z); + + break; + } + } + + printf("\nAXIS_REMAP_FUNC_TEST 3\n"); + printf("Get sensor data of re-mapped axes - 2nd combination\n"); + + remap_data.x = BMA4_NEG_Z; + remap_data.y = BMA4_NEG_X; + remap_data.z = BMA4_Y; + + rslt = bma456_an_set_remap_axes(&remap_data, &bma4); + bma4_error_codes_print_result("bma456_an_set_remap_axes", rslt); + + if (rslt == BMA4_OK) + { + rslt = bma456_an_get_remap_axes(&remap_data, &bma4); + bma4_error_codes_print_result("bma456_an_get_remap_axes", rslt); + + if (rslt == BMA4_OK) + { + printf("Re-mapped x value = %s\n", data_array[remap_data.x]); + printf("Re-mapped y value = %s\n", data_array[remap_data.y]); + printf("Re-mapped z value = %s\n", data_array[remap_data.z]); + } + + printf("Expected Re-mapped x value = BMA4_NEG_Z\n"); + printf("Expected Re-mapped y value = BMA4_NEG_X\n"); + printf("Expected Re-mapped z value = BMA4_Y\n"); + + if ((remap_data.x == BMA4_NEG_Z) && (remap_data.y == BMA4_NEG_X) && (remap_data.z == BMA4_Y)) + { + printf(">> PASS\n"); + } + else + { + printf(">> FAIL\n"); + } + } + + printf("Print mapped data\n"); + + for (;;) + { + /* Read interrupt status */ + rslt = bma456_an_read_int_status(&int_status, &bma4); + bma4_error_codes_print_result("bma456_an_read_int_status", rslt); + + /* Filtering only the accel data ready interrupt */ + if ((rslt == BMA4_OK) && (int_status & BMA4_ACCEL_DATA_RDY_INT)) + { + rslt = bma4_read_accel_xyz(&accel, &bma4); + bma4_error_codes_print_result("bma4_read_accel_xyz", rslt); + + printf("Accel :: X = %d Y = %d Z = %d\n", accel.x, accel.y, accel.z); + + break; + } + } + + printf("\nAXIS_REMAP_FUNC_TEST 4\n"); + printf("Get sensor data of re-mapped axes - 3rd combination\n"); + + remap_data.x = BMA4_Y; + remap_data.y = BMA4_Z; + remap_data.z = BMA4_X; + + rslt = bma456_an_set_remap_axes(&remap_data, &bma4); + bma4_error_codes_print_result("bma456_an_set_remap_axes", rslt); + if (rslt == BMA4_OK) + { + rslt = bma456_an_get_remap_axes(&remap_data, &bma4); + bma4_error_codes_print_result("bma456_an_get_remap_axes", rslt); + + if (rslt == BMA4_OK) + { + printf("Re-mapped x value = %s\n", data_array[remap_data.x]); + printf("Re-mapped y value = %s\n", data_array[remap_data.y]); + printf("Re-mapped z value = %s\n", data_array[remap_data.z]); + } + + printf("Expected Re-mapped x value = BMA4_Y\n"); + printf("Expected Re-mapped y value = BMA4_Z\n"); + printf("Expected Re-mapped z value = BMA4_X\n"); + + if ((remap_data.x == BMA4_Y) && (remap_data.y == BMA4_Z) && (remap_data.z == BMA4_X)) + { + printf(">> PASS\n"); + } + else + { + printf(">> FAIL\n"); + } + } + + printf("Print mapped data\n"); + + for (;;) + { + /* Read interrupt status */ + rslt = bma456_an_read_int_status(&int_status, &bma4); + bma4_error_codes_print_result("bma456_an_read_int_status", rslt); + + /* Filtering only the accel data ready interrupt */ + if ((rslt == BMA4_OK) && (int_status & BMA4_ACCEL_DATA_RDY_INT)) + { + rslt = bma4_read_accel_xyz(&accel, &bma4); + bma4_error_codes_print_result("bma4_read_accel_xyz", rslt); + + printf("Accel :: X = %d Y = %d Z = %d\n", accel.x, accel.y, accel.z); + + break; + } + } + + printf("\nAXIS_REMAP_FUNC_TEST 5\n"); + printf("Get sensor data of re-mapped axes - 4th combination\n"); + + remap_data.x = BMA4_NEG_X; + remap_data.y = BMA4_NEG_Y; + remap_data.z = BMA4_NEG_Z; + + rslt = bma456_an_set_remap_axes(&remap_data, &bma4); + bma4_error_codes_print_result("bma456_an_set_remap_axes", rslt); + + if (rslt == BMA4_OK) + { + rslt = bma456_an_get_remap_axes(&remap_data, &bma4); + bma4_error_codes_print_result("bma456_an_get_remap_axes", rslt); + + if (rslt == BMA4_OK) + { + printf("Re-mapped x value = %s\n", data_array[remap_data.x]); + printf("Re-mapped y value = %s\n", data_array[remap_data.y]); + printf("Re-mapped z value = %s\n", data_array[remap_data.z]); + } + + printf("Expected Re-mapped x value = BMA4_NEG_X\n"); + printf("Expected Re-mapped y value = BMA4_NEG_Y\n"); + printf("Expected Re-mapped z value = BMA4_NEG_Z\n"); + + if ((remap_data.x == BMA4_NEG_X) && (remap_data.y == BMA4_NEG_Y) && (remap_data.z == BMA4_NEG_Z)) + { + printf(">> PASS\n"); + } + else + { + printf(">> FAIL\n"); + } + } + + printf("Print mapped data\n"); + + for (;;) + { + /* Read interrupt status */ + rslt = bma456_an_read_int_status(&int_status, &bma4); + bma4_error_codes_print_result("bma456_an_read_int_status", rslt); + + /* Filtering only the accel data ready interrupt */ + if ((rslt == BMA4_OK) && (int_status & BMA4_ACCEL_DATA_RDY_INT)) + { + rslt = bma4_read_accel_xyz(&accel, &bma4); + bma4_error_codes_print_result("bma4_read_accel_xyz", rslt); + + printf("Accel :: X = %d Y = %d Z = %d\n", accel.x, accel.y, accel.z); + + break; + } + } + + bma4_coines_deinit(); + + return rslt; +} diff --git a/components/bma456/bma456an_examples/common/common.c b/components/bma456/bma456an_examples/common/common.c new file mode 100644 index 0000000..ca1e7c9 --- /dev/null +++ b/components/bma456/bma456an_examples/common/common.c @@ -0,0 +1,242 @@ +/** + * Copyright (C) 2023 Bosch Sensortec GmbH. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include + +#include "bma4_defs.h" +#include "common.h" + +/******************************************************************************/ +/*! Macro definitions */ + +/*! Read write length varies based on user requirement */ +#define BMA4_READ_WRITE_LEN UINT8_C(46) + +/******************************************************************************/ +/*! Static variable definition */ + +/*! Variable that holds the I2C device address or SPI chip selection */ +static uint8_t dev_addr; + +/******************************************************************************/ +/*! User interface functions */ + +/*! + * I2C read function map to COINES platform + */ +BMA4_INTF_RET_TYPE bma4_i2c_read(uint8_t reg_addr, uint8_t *reg_data, uint32_t len, void *intf_ptr) +{ + uint8_t dev_address = *(uint8_t*)intf_ptr; + + (void)intf_ptr; + + return coines_read_i2c(COINES_I2C_BUS_0, dev_address, reg_addr, reg_data, (uint16_t)len); +} + +/*! + * I2C write function map to COINES platform + */ +BMA4_INTF_RET_TYPE bma4_i2c_write(uint8_t reg_addr, const uint8_t *reg_data, uint32_t len, void *intf_ptr) +{ + uint8_t dev_address = *(uint8_t*)intf_ptr; + + (void)intf_ptr; + + return coines_write_i2c(COINES_I2C_BUS_0, dev_address, reg_addr, (uint8_t *)reg_data, (uint16_t)len); +} + +/*! + * SPI read function map to COINES platform + */ +BMA4_INTF_RET_TYPE bma4_spi_read(uint8_t reg_addr, uint8_t *reg_data, uint32_t len, void *intf_ptr) +{ + uint8_t dev_address = *(uint8_t*)intf_ptr; + + (void)intf_ptr; + + return coines_read_spi(COINES_SPI_BUS_0, dev_address, reg_addr, reg_data, (uint16_t)len); +} + +/*! + * SPI write function map to COINES platform + */ +BMA4_INTF_RET_TYPE bma4_spi_write(uint8_t reg_addr, const uint8_t *reg_data, uint32_t len, void *intf_ptr) +{ + uint8_t dev_address = *(uint8_t*)intf_ptr; + + (void)intf_ptr; + + return coines_write_spi(COINES_SPI_BUS_0, dev_address, reg_addr, (uint8_t *)reg_data, (uint16_t)len); +} + +/*! + * Delay function map to COINES platform + */ +void bma4_delay_us(uint32_t period, void *intf_ptr) +{ + (void) intf_ptr; + coines_delay_usec(period); +} + +/*! + * @brief Function to select the interface between SPI and I2C. + * Also to initialize coines platform + */ +int8_t bma4_interface_init(struct bma4_dev *bma, uint8_t intf, enum bma4_variant variant) +{ + int8_t rslt = BMA4_OK; + + if (bma != NULL) + { + int16_t result = coines_open_comm_intf(COINES_COMM_INTF_USB, NULL); + struct coines_board_info board_info; + if (result < COINES_SUCCESS) + { + printf( + "\n Unable to connect with Application Board ! \n" " 1. Check if the board is connected and powered on. \n" " 2. Check if Application Board USB driver is installed. \n" + " 3. Check if board is in use by another application. (Insufficient permissions to access USB) \n"); + exit(result); + } + + result = coines_get_board_info(&board_info); + + #if defined(PC) + setbuf(stdout, NULL); + #endif + + (void)coines_set_shuttleboard_vdd_vddio_config(0, 0); + coines_delay_usec(10000); + + /* Bus configuration : I2C */ + if (intf == BMA4_I2C_INTF) + { + printf("I2C Interface \n"); + + /* To initialize the user I2C function */ + dev_addr = BMA4_I2C_ADDR_PRIMARY; + bma->intf = BMA4_I2C_INTF; + bma->bus_read = bma4_i2c_read; + bma->bus_write = bma4_i2c_write; + + /* SDO to Ground */ + (void)coines_set_pin_config(COINES_SHUTTLE_PIN_22, COINES_PIN_DIRECTION_OUT, COINES_PIN_VALUE_LOW); + + /* Make CSB pin HIGH */ + (void)coines_set_pin_config(COINES_SHUTTLE_PIN_21, COINES_PIN_DIRECTION_OUT, COINES_PIN_VALUE_HIGH); + coines_delay_msec(100); + + /* SDO pin is made low */ + (void)coines_set_pin_config(COINES_SHUTTLE_PIN_SDO, COINES_PIN_DIRECTION_OUT, COINES_PIN_VALUE_LOW); + + (void)coines_config_i2c_bus(COINES_I2C_BUS_0, COINES_I2C_STANDARD_MODE); + } + /* Bus configuration : SPI */ + else if (intf == BMA4_SPI_INTF) + { + printf("SPI Interface \n"); + + /* To initialize the user SPI function */ + dev_addr = COINES_SHUTTLE_PIN_7; + bma->intf = BMA4_SPI_INTF; + bma->bus_read = bma4_spi_read; + bma->bus_write = bma4_spi_write; + (void)coines_config_spi_bus(COINES_SPI_BUS_0, COINES_SPI_SPEED_7_5_MHZ, COINES_SPI_MODE0); + } + + /* Assign variant information */ + bma->variant = variant; + + /* Assign device address to interface pointer */ + bma->intf_ptr = &dev_addr; + + /* Configure delay in microseconds */ + bma->delay_us = bma4_delay_us; + + /* Configure max read/write length (in bytes) ( Supported length depends on target machine) */ + bma->read_write_len = BMA4_READ_WRITE_LEN; + + /* Set Performance mode status */ + bma->perf_mode_status = BMA4_DISABLE; + + coines_delay_msec(100); + + (void)coines_set_shuttleboard_vdd_vddio_config(3300, 3300); + + coines_delay_msec(200); + } + else + { + rslt = BMA4_E_NULL_PTR; + } + + return rslt; + +} + +/*! + * @brief Prints the execution status of the APIs. + */ +void bma4_error_codes_print_result(const char api_name[], int8_t rslt) +{ + if (rslt != BMA4_OK) + { + printf("%s\t", api_name); + if (rslt == BMA4_E_NULL_PTR) + { + printf("Error [%d] : Null pointer\r\n", rslt); + } + else if (rslt == BMA4_E_COM_FAIL) + { + printf("Error [%d] : Communication failure\r\n", rslt); + } + else if (rslt == BMA4_E_CONFIG_STREAM_ERROR) + { + printf("Error [%d] : Invalid configuration stream\r\n", rslt); + } + else if (rslt == BMA4_E_SELF_TEST_FAIL) + { + printf("Error [%d] : Self test failed\r\n", rslt); + } + else if (rslt == BMA4_E_INVALID_SENSOR) + { + printf("Error [%d] : Device not found\r\n", rslt); + } + else if (rslt == BMA4_E_OUT_OF_RANGE) + { + printf("Error [%d] : Out of Range\r\n", rslt); + } + else if (rslt == BMA4_E_AVG_MODE_INVALID_CONF) + { + printf("Error [%d] : Invalid bandwidth and ODR combination in Accel Averaging mode\r\n", rslt); + } + else + { + /* For more error codes refer "*_defs.h" */ + printf("Error [%d] : Unknown error code\r\n", rslt); + } + } +} + +/*! + * @brief Deinitializes coines platform + * + * @return void. + */ +void bma4_coines_deinit(void) +{ + (void)fflush(stdout); + coines_delay_msec(200); + + (void)coines_set_shuttleboard_vdd_vddio_config(0, 0); + coines_delay_msec(1000); + + /* Coines interface reset */ + coines_soft_reset(); + coines_delay_msec(1000); + (void)coines_close_comm_intf(COINES_COMM_INTF_USB, NULL); +} diff --git a/components/bma456/bma456an_examples/common/common.h b/components/bma456/bma456an_examples/common/common.h new file mode 100644 index 0000000..75c53f4 --- /dev/null +++ b/components/bma456/bma456an_examples/common/common.h @@ -0,0 +1,127 @@ +/**\ + * Copyright (c) 2023 Bosch Sensortec GmbH. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + **/ + +#ifndef COMMON_H +#define COMMON_H + +/*! CPP guard */ +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include "bma4.h" +#include "coines.h" + +/*! + * @brief Function for reading the sensor's registers through I2C bus. + * + * @param[in] reg_addr : Register address. + * @param[out] reg_data : Pointer to the data buffer to store the read data. + * @param[in] length : No of bytes to read. + * @param[in] intf_ptr : Interface pointer + * + * @return Status of execution + * @retval = BMA4_INTF_RET_SUCCESS -> Success + * @retval != BMA4_INTF_RET_SUCCESS -> Failure Info + * + */ +BMA4_INTF_RET_TYPE bma4_i2c_read(uint8_t reg_addr, uint8_t *reg_data, uint32_t len, void *intf_ptr); + +/*! + * @brief Function for writing the sensor's registers through I2C bus. + * + * @param[in] reg_addr : Register address. + * @param[in] reg_data : Pointer to the data buffer whose value is to be written. + * @param[in] length : No of bytes to write. + * @param[in] intf_ptr : Interface pointer + * + * @return Status of execution + * @retval = BMA4_INTF_RET_SUCCESS -> Success + * @retval != BMA4_INTF_RET_SUCCESS -> Failure Info + * + */ +BMA4_INTF_RET_TYPE bma4_i2c_write(uint8_t reg_addr, const uint8_t *reg_data, uint32_t len, void *intf_ptr); + +/*! + * @brief Function for reading the sensor's registers through SPI bus. + * + * @param[in] reg_addr : Register address. + * @param[out] reg_data : Pointer to the data buffer to store the read data. + * @param[in] length : No of bytes to read. + * @param[in] intf_ptr : Interface pointer + * + * @return Status of execution + * @retval = BMA4_INTF_RET_SUCCESS -> Success + * @retval != BMA4_INTF_RET_SUCCESS -> Failure Info + * + */ +BMA4_INTF_RET_TYPE bma4_spi_read(uint8_t reg_addr, uint8_t *reg_data, uint32_t len, void *intf_ptr); + +/*! + * @brief Function for writing the sensor's registers through SPI bus. + * + * @param[in] reg_addr : Register address. + * @param[in] reg_data : Pointer to the data buffer whose data has to be written. + * @param[in] length : No of bytes to write. + * @param[in] intf_ptr : Interface pointer + * + * @return Status of execution + * @retval = BMA4_INTF_RET_SUCCESS -> Success + * @retval != BMA4_INTF_RET_SUCCESS -> Failure Info + * + */ +BMA4_INTF_RET_TYPE bma4_spi_write(uint8_t reg_addr, const uint8_t *reg_data, uint32_t len, void *intf_ptr); + +/*! + * @brief This function provides the delay for required time (Microsecond) as per the input provided in some of the + * APIs. + * + * @param[in] period_us : The required wait time in microsecond. + * @param[in] intf_ptr : Interface pointer + * + * @return void. + * + */ +void bma4_delay_us(uint32_t period, void *intf_ptr); + +/*! + * @brief Function to select the interface between SPI and I2C. + * + * @param[in] bma : Structure instance of bma4_dev + * @param[in] intf : Interface selection parameter + * @param[in] variant : Variant information of the sensor + * ( BMA42x variants values - BMA42X_VARIANT / BMA42X_B_VARIANT ) + * ( BMA45x variants values - BMA45X_VARIANT ) + * + * @return Status of execution + * @retval 0 -> Success + * @retval < 0 -> Failure Info + */ +int8_t bma4_interface_init(struct bma4_dev *bma, uint8_t intf, enum bma4_variant variant); + +/*! + * @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 bma4_error_codes_print_result(const char api_name[], int8_t rslt); + +/*! + * @brief Deinitializes coines platform + * + * @return void. + */ +void bma4_coines_deinit(void); + +#ifdef __cplusplus +} +#endif /* End of CPP guard */ + +#endif /* COMMON_H */ diff --git a/components/bma456/bma456an_examples/fifo_full_header_mode/Makefile b/components/bma456/bma456an_examples/fifo_full_header_mode/Makefile new file mode 100644 index 0000000..da306f2 --- /dev/null +++ b/components/bma456/bma456an_examples/fifo_full_header_mode/Makefile @@ -0,0 +1,20 @@ +COINES_INSTALL_PATH ?= ../../../.. + +EXAMPLE_FILE ?= fifo_full_header_mode.c + +API_LOCATION ?= ../.. + +COMMON_LOCATION ?= .. + +C_SRCS += \ +$(API_LOCATION)/bma4.c \ +$(API_LOCATION)/bma456_an.c \ +$(COMMON_LOCATION)/common/common.c + +INCLUDEPATHS += \ +$(API_LOCATION) \ +$(COMMON_LOCATION)/common + +TARGET=MCU_APP30 + +include $(COINES_INSTALL_PATH)/coines.mk \ No newline at end of file diff --git a/components/bma456/bma456an_examples/fifo_full_header_mode/fifo_full_header_mode.c b/components/bma456/bma456an_examples/fifo_full_header_mode/fifo_full_header_mode.c new file mode 100644 index 0000000..a7fecd2 --- /dev/null +++ b/components/bma456/bma456an_examples/fifo_full_header_mode/fifo_full_header_mode.c @@ -0,0 +1,173 @@ +/**\ + * Copyright (c) 2022 Bosch Sensortec GmbH. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + **/ + +#include +#include "bma456_an.h" +#include "common.h" + +/******************************************************************************/ +/*! Macro definition */ + +/*! Buffer size allocated to store raw FIFO data */ +#define BMA456_AN_FIFO_RAW_DATA_BUFFER_SIZE UINT16_C(1024) + +/*! Length of data to be read from FIFO */ +#define BMA456_AN_FIFO_RAW_DATA_USER_LENGTH UINT16_C(1024) + +/*! Number of accel frames to be extracted from FIFO + * Calculation: + * fifo_buffer = 1024, accel_frame_len = 6, header_byte = 1. + * fifo_accel_frame_count = (1024 / (6 + 1)) = 147 frames + * + * Extra frames to parse sensortime data + */ +#define BMA456_AN_FIFO_ACCEL_FRAME_COUNT UINT8_C(170) + +/******************************************************************************/ +/*! Function */ + +/* This function starts the execution of program */ +int main(void) +{ + /* Status of API are returned to this variable */ + int8_t rslt; + + /* Accelerometer configuration structure */ + struct bma4_accel_config acc_conf = { 0 }; + + /* Sensor initialization configuration */ + struct bma4_dev dev = { 0 }; + + /* Number of accelerometer frames */ + uint16_t accel_length; + + /* Variable to idx bytes */ + uint16_t idx = 0; + + /* Variable to maintain count of loop to run FIFO read */ + uint8_t loop = 1; + + /* Number of bytes of FIFO data + * NOTE : Dummy byte (for SPI Interface) required for FIFO data read must be given as part of array size + */ + uint8_t fifo_data[BMA456_AN_FIFO_RAW_DATA_BUFFER_SIZE + BMA4_SENSORTIME_OVERHEAD_BYTE] = { 0 }; + + /* Array of accelerometer frames -> Total bytes = + * 147 * (6 axes bytes(+/- x,y,z) + 1 header byte) = 1029 bytes */ + struct bma4_accel fifo_accel_data[BMA456_AN_FIFO_ACCEL_FRAME_COUNT] = { { 0 } }; + + /* Initialize FIFO frame structure */ + struct bma4_fifo_frame fifoframe = { 0 }; + + /* Variable that contains interrupt status value */ + uint16_t int_status = 0; + + /* Variable to hold the length of FIFO data */ + uint16_t fifo_length = 0; + + /* Interface reference is given as a parameter + * For I2C : BMA4_I2C_INTF + * For SPI : BMA4_SPI_INTF + * Variant information given as parameter - BMA45X_VARIANT + */ + rslt = bma4_interface_init(&dev, BMA4_I2C_INTF, BMA45X_VARIANT); + bma4_error_codes_print_result("bma4_interface_init", rslt); + + /* Initialize BMA456_AN */ + rslt = bma456_an_init(&dev); + bma4_error_codes_print_result("bma456_an_init status", rslt); + + /* Accelerometer configuration settings */ + acc_conf.odr = BMA4_OUTPUT_DATA_RATE_100HZ; + acc_conf.bandwidth = BMA4_ACCEL_NORMAL_AVG4; + acc_conf.range = BMA4_ACCEL_RANGE_2G; + acc_conf.perf_mode = BMA4_CIC_AVG_MODE; + + /* Set the accel configurations */ + rslt = bma4_set_accel_config(&acc_conf, &dev); + bma4_error_codes_print_result("bma4_set_accel_config status", rslt); + + /* NOTE : Enable accel after set of configurations */ + rslt = bma4_set_accel_enable(1, &dev); + bma4_error_codes_print_result("bma4_set_accel_enable status", rslt); + + /* Disabling advance power save mode as FIFO data is not accessible in advance low power mode */ + rslt = bma4_set_advance_power_save(BMA4_DISABLE, &dev); + bma4_error_codes_print_result("bma4_set_advance_power_save status", rslt); + + /* Clear FIFO configuration register */ + rslt = bma4_set_fifo_config(BMA4_FIFO_ALL, BMA4_DISABLE, &dev); + bma4_error_codes_print_result("bma4_set_fifo_config disable status", rslt); + + /* Set FIFO configuration by enabling accel. + * NOTE 1: The header mode is enabled by default. + * NOTE 2: By default the FIFO operating mode is FIFO mode. */ + rslt = bma4_set_fifo_config(BMA4_FIFO_ACCEL | BMA4_FIFO_HEADER | BMA4_FIFO_TIME, BMA4_ENABLE, &dev); + bma4_error_codes_print_result("bma4_set_fifo_config enable status", rslt); + + /* Update FIFO structure */ + fifoframe.data = fifo_data; + fifoframe.length = BMA456_AN_FIFO_RAW_DATA_USER_LENGTH + BMA4_SENSORTIME_OVERHEAD_BYTE; + + printf("FIFO is configured in header mode\n"); + + rslt = bma456_an_map_interrupt(BMA4_INTR1_MAP, BMA4_FIFO_FULL_INT, BMA4_ENABLE, &dev); + bma4_error_codes_print_result("bma4_map_interrupt status", rslt); + + while (loop <= 10) + { + rslt = bma456_an_read_int_status(&int_status, &dev); + bma4_error_codes_print_result("bma4_read_int_status", rslt); + + if ((rslt == BMA4_OK) && (int_status & BMA4_FIFO_FULL_INT)) + { + printf("\nIteration : %d\n", loop); + + rslt = bma4_get_fifo_length(&fifo_length, &dev); + bma4_error_codes_print_result("bma4_get_fifo_length status", rslt); + + printf("FIFO data bytes available : %d\n", fifo_length); + printf("FIFO data bytes requested : %d\n", fifoframe.length); + + /* Read FIFO data */ + rslt = bma4_read_fifo_data(&fifoframe, &dev); + bma4_error_codes_print_result("bma4_read_fifo_data status", rslt); + + accel_length = BMA456_AN_FIFO_ACCEL_FRAME_COUNT; + + if (rslt == BMA4_OK) + { + printf("Requested data frames before parsing: %d\n", accel_length); + + /* Parse the FIFO data to extract accelerometer data from the FIFO buffer */ + rslt = bma4_extract_accel(fifo_accel_data, &accel_length, &fifoframe, &dev); + printf("Parsed accelerometer data frames: %d\n", accel_length); + + printf("ACCEL, X, Y, Z\n"); + + /* Print the parsed accelerometer data from the FIFO buffer */ + for (idx = 0; idx < accel_length; idx++) + { + printf("%d, %d, %d, %d\n", + idx, + fifo_accel_data[idx].x, + fifo_accel_data[idx].y, + fifo_accel_data[idx].z); + } + + /* Print control frames like sensor time and skipped frame count */ + printf("Skipped frame count = %d\n", fifoframe.skipped_frame_count); + printf("Sensor time(in seconds) = %.4lf s\r\n", (fifoframe.sensor_time * BMA4_SENSORTIME_RESOLUTION)); + } + + loop++; + } + } + + bma4_coines_deinit(); + + return rslt; +} diff --git a/components/bma456/bma456an_examples/fifo_full_headerless_mode/Makefile b/components/bma456/bma456an_examples/fifo_full_headerless_mode/Makefile new file mode 100644 index 0000000..b6f6993 --- /dev/null +++ b/components/bma456/bma456an_examples/fifo_full_headerless_mode/Makefile @@ -0,0 +1,18 @@ +COINES_INSTALL_PATH ?= ../../../.. + +EXAMPLE_FILE ?= fifo_full_headerless_mode.c + +API_LOCATION ?= ../.. + +COMMON_LOCATION ?= .. + +C_SRCS += \ +$(API_LOCATION)/bma4.c \ +$(API_LOCATION)/bma456_an.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/components/bma456/bma456an_examples/fifo_full_headerless_mode/fifo_full_headerless_mode.c b/components/bma456/bma456an_examples/fifo_full_headerless_mode/fifo_full_headerless_mode.c new file mode 100644 index 0000000..0baf05f --- /dev/null +++ b/components/bma456/bma456an_examples/fifo_full_headerless_mode/fifo_full_headerless_mode.c @@ -0,0 +1,171 @@ +/**\ + * Copyright (c) 2022 Bosch Sensortec GmbH. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + **/ + +#include +#include "bma456_an.h" +#include "common.h" + +/******************************************************************************/ +/*! Macro definition */ + +/*! Buffer size allocated to store raw FIFO data */ +#define BMA456_AN_FIFO_RAW_DATA_BUFFER_SIZE UINT16_C(1024) + +/*! Length of data to be read from FIFO */ +#define BMA456_AN_FIFO_RAW_DATA_USER_LENGTH UINT16_C(1024) + +/*! Number of accel frames to be extracted from FIFO + * Calculation: + * fifo_buffer = 1024, accel_frame_len = 6. + * fifo_accel_frame_count = (1024 / 6) = 170 frames + */ +#define BMA456_AN_FIFO_ACCEL_FRAME_COUNT UINT8_C(170) + +/******************************************************************************/ +/*! Function */ + +/* This function starts the execution of program */ +int main(void) +{ + /* Status of API are returned to this variable */ + int8_t rslt; + + /* Accelerometer configuration structure */ + struct bma4_accel_config acc_conf = { 0 }; + + /* Sensor initialization configuration */ + struct bma4_dev dev = { 0 }; + + /* Number of accelerometer frames */ + uint16_t accel_length; + + /* Variable to idx bytes */ + uint16_t idx = 0; + + /* Variable to maintain count of loop to run FIFO read */ + uint8_t loop = 1; + + /* Number of bytes of FIFO data + * NOTE : Dummy byte (for SPI Interface) required for FIFO data read must be given as part of array size + */ + uint8_t fifo_data[BMA456_AN_FIFO_RAW_DATA_BUFFER_SIZE] = { 0 }; + + /* Array of accelerometer frames -> Total bytes = + * 170 * (6 axes bytes(+/- x,y,z)) = 1020 bytes */ + struct bma4_accel fifo_accel_data[BMA456_AN_FIFO_ACCEL_FRAME_COUNT] = { { 0 } }; + + /* Initialize FIFO frame structure */ + struct bma4_fifo_frame fifoframe = { 0 }; + + /* Variable that contains interrupt status value */ + uint16_t int_status = 0; + + /* Variable to hold the length of FIFO data */ + uint16_t fifo_length = 0; + + /* Interface reference is given as a parameter + * For I2C : BMA4_I2C_INTF + * For SPI : BMA4_SPI_INTF + * Variant information given as parameter - BMA45X_VARIANT + */ + rslt = bma4_interface_init(&dev, BMA4_I2C_INTF, BMA45X_VARIANT); + bma4_error_codes_print_result("bma4_interface_init", rslt); + + /* Initialize BMA456_AN */ + rslt = bma456_an_init(&dev); + bma4_error_codes_print_result("bma456_an_init status", rslt); + + /* Accelerometer configuration settings */ + acc_conf.odr = BMA4_OUTPUT_DATA_RATE_100HZ; + acc_conf.bandwidth = BMA4_ACCEL_NORMAL_AVG4; + acc_conf.range = BMA4_ACCEL_RANGE_2G; + acc_conf.perf_mode = BMA4_CIC_AVG_MODE; + + /* Set the accel configurations */ + rslt = bma4_set_accel_config(&acc_conf, &dev); + bma4_error_codes_print_result("bma4_set_accel_config status", rslt); + + /* NOTE : Enable accel after set of configurations */ + rslt = bma4_set_accel_enable(1, &dev); + bma4_error_codes_print_result("bma4_set_accel_enable status", rslt); + + /* Disabling advance power save mode as FIFO data is not accessible in advance low power mode */ + rslt = bma4_set_advance_power_save(BMA4_DISABLE, &dev); + bma4_error_codes_print_result("bma4_set_advance_power_save status", rslt); + + /* Clear FIFO configuration register */ + rslt = bma4_set_fifo_config(BMA4_FIFO_ALL, BMA4_DISABLE, &dev); + bma4_error_codes_print_result("bma4_set_fifo_config disable status", rslt); + + /* Set FIFO configuration by enabling accel. + * NOTE 1: The header mode is enabled by default. + * NOTE 2: By default the FIFO operating mode is FIFO mode. */ + rslt = bma4_set_fifo_config(BMA4_FIFO_ACCEL, BMA4_ENABLE, &dev); + bma4_error_codes_print_result("bma4_set_fifo_config enable status", rslt); + + /* Update FIFO structure */ + fifoframe.data = fifo_data; + fifoframe.length = BMA456_AN_FIFO_RAW_DATA_USER_LENGTH; + + /* To enable headerless mode, disable the header. */ + rslt = bma4_set_fifo_config(BMA4_FIFO_HEADER, BMA4_DISABLE, &dev); + bma4_error_codes_print_result("bma4_set_fifo_config status", rslt); + + printf("FIFO is configured in headerless mode\n"); + + rslt = bma456_an_map_interrupt(BMA4_INTR1_MAP, BMA4_FIFO_FULL_INT, BMA4_ENABLE, &dev); + bma4_error_codes_print_result("bma4_map_interrupt status", rslt); + + while (loop <= 10) + { + rslt = bma456_an_read_int_status(&int_status, &dev); + bma4_error_codes_print_result("bma4_read_int_status", rslt); + + if ((rslt == BMA4_OK) && (int_status & BMA4_FIFO_FULL_INT)) + { + printf("\nIteration : %d\n", loop); + + rslt = bma4_get_fifo_length(&fifo_length, &dev); + bma4_error_codes_print_result("bma4_get_fifo_length status", rslt); + + printf("FIFO data bytes available : %d\n", fifo_length); + printf("FIFO data bytes requested : %d\n", fifoframe.length); + + /* Read FIFO data */ + rslt = bma4_read_fifo_data(&fifoframe, &dev); + bma4_error_codes_print_result("bma4_read_fifo_data status", rslt); + + accel_length = BMA456_AN_FIFO_ACCEL_FRAME_COUNT; + + if (rslt == BMA4_OK) + { + printf("Requested data frames before parsing: %d\n", accel_length); + + /* Parse the FIFO data to extract accelerometer data from the FIFO buffer */ + rslt = bma4_extract_accel(fifo_accel_data, &accel_length, &fifoframe, &dev); + printf("Parsed accelerometer data frames: %d\n", accel_length); + + printf("ACCEL, X, Y, Z\n"); + + /* Print the parsed accelerometer data from the FIFO buffer */ + for (idx = 0; idx < accel_length; idx++) + { + printf("%d, %d, %d, %d\n", + idx, + fifo_accel_data[idx].x, + fifo_accel_data[idx].y, + fifo_accel_data[idx].z); + } + } + + loop++; + } + } + + bma4_coines_deinit(); + + return rslt; +} diff --git a/components/bma456/bma456an_examples/fifo_watermark_header_mode/Makefile b/components/bma456/bma456an_examples/fifo_watermark_header_mode/Makefile new file mode 100644 index 0000000..291ab62 --- /dev/null +++ b/components/bma456/bma456an_examples/fifo_watermark_header_mode/Makefile @@ -0,0 +1,20 @@ +COINES_INSTALL_PATH ?= ../../../.. + +EXAMPLE_FILE ?= fifo_watermark_header_mode.c + +API_LOCATION ?= ../.. + +COMMON_LOCATION ?= .. + +C_SRCS += \ +$(API_LOCATION)/bma4.c \ +$(API_LOCATION)/bma456_an.c \ +$(COMMON_LOCATION)/common/common.c + +INCLUDEPATHS += \ +$(API_LOCATION) \ +$(COMMON_LOCATION)/common + +TARGET=MCU_APP30 + +include $(COINES_INSTALL_PATH)/coines.mk \ No newline at end of file diff --git a/components/bma456/bma456an_examples/fifo_watermark_header_mode/fifo_watermark_header_mode.c b/components/bma456/bma456an_examples/fifo_watermark_header_mode/fifo_watermark_header_mode.c new file mode 100644 index 0000000..2fe7e0a --- /dev/null +++ b/components/bma456/bma456an_examples/fifo_watermark_header_mode/fifo_watermark_header_mode.c @@ -0,0 +1,188 @@ +/**\ + * Copyright (c) 2022 Bosch Sensortec GmbH. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + **/ + +#include +#include "bma456_an.h" +#include "common.h" + +/******************************************************************************/ +/*! Macro definition */ + +/*! Buffer size allocated to store raw FIFO data */ +#define BMA456_AN_FIFO_RAW_DATA_BUFFER_SIZE UINT16_C(1024) + +/*! Length of data to be read from FIFO */ +#define BMA456_AN_FIFO_RAW_DATA_USER_LENGTH UINT16_C(1024) + +/*! Setting a watermark level in FIFO */ +#define BMA456_AN_FIFO_WATERMARK_LEVEL UINT16_C(650) + +/*! Number of accel frames to be extracted from FIFO + * Calculation: + * fifo_watermark_level = 650, accel_frame_len = 6, header_byte = 1. + * fifo_accel_frame_count = (650 / (6 + 1)) = 93 frames + * NOTE: Extra frames are read in order to get sensor time + */ +#define BMA456_AN_FIFO_ACCEL_FRAME_COUNT UINT8_C(100) + +/******************************************************************************/ +/*! Function */ + +/* This function starts the execution of program */ +int main(void) +{ + /* Status of API are returned to this variable */ + int8_t rslt; + + /* Accelerometer configuration structure */ + struct bma4_accel_config acc_conf = { 0 }; + + /* Sensor initialization configuration */ + struct bma4_dev dev = { 0 }; + + /* Number of accelerometer frames */ + uint16_t accel_length; + + /* Variable to idx bytes */ + uint16_t idx = 0; + + /* Variable to maintain count of loop to run FIFO read */ + uint8_t loop = 1; + + /* Number of bytes of FIFO data + * NOTE : Dummy byte (for SPI Interface) required for FIFO data read must be given as part of array size + */ + uint8_t fifo_data[BMA456_AN_FIFO_RAW_DATA_BUFFER_SIZE + BMA4_SENSORTIME_OVERHEAD_BYTE] = { 0 }; + + /* Array of accelerometer frames -> Total bytes = + * 100 * (6 axes bytes(+/- x,y,z) + 1 header byte) = 700 bytes */ + struct bma4_accel fifo_accel_data[BMA456_AN_FIFO_ACCEL_FRAME_COUNT] = { { 0 } }; + + /* Initialize FIFO frame structure */ + struct bma4_fifo_frame fifoframe = { 0 }; + + /* Variable that contains interrupt status value */ + uint16_t int_status = 0; + + /* Variable to hold the length of FIFO data */ + uint16_t fifo_length = 0; + + uint16_t watermark = 0; + + /* To set the watermark level in FIFO */ + uint16_t wm_lvl; + + /* Interface reference is given as a parameter + * For I2C : BMA4_I2C_INTF + * For SPI : BMA4_SPI_INTF + * Variant information given as parameter - BMA45X_VARIANT + */ + rslt = bma4_interface_init(&dev, BMA4_I2C_INTF, BMA45X_VARIANT); + bma4_error_codes_print_result("bma4_interface_init", rslt); + + /* Initialize BMA456_AN */ + rslt = bma456_an_init(&dev); + bma4_error_codes_print_result("bma456_an_init status", rslt); + + /* Accelerometer configuration settings */ + acc_conf.odr = BMA4_OUTPUT_DATA_RATE_100HZ; + acc_conf.bandwidth = BMA4_ACCEL_NORMAL_AVG4; + acc_conf.range = BMA4_ACCEL_RANGE_2G; + acc_conf.perf_mode = BMA4_CIC_AVG_MODE; + + /* Set the accel configurations */ + rslt = bma4_set_accel_config(&acc_conf, &dev); + bma4_error_codes_print_result("bma4_set_accel_config status", rslt); + + /* NOTE : Enable accel after set of configurations */ + rslt = bma4_set_accel_enable(1, &dev); + bma4_error_codes_print_result("bma4_set_accel_enable status", rslt); + + /* Disabling advance power save mode as FIFO data is not accessible in advance low power mode */ + rslt = bma4_set_advance_power_save(BMA4_DISABLE, &dev); + bma4_error_codes_print_result("bma4_set_advance_power_save status", rslt); + + /* Clear FIFO configuration register */ + rslt = bma4_set_fifo_config(BMA4_FIFO_ALL, BMA4_DISABLE, &dev); + bma4_error_codes_print_result("bma4_set_fifo_config disable status", rslt); + + /* Set FIFO configuration by enabling accel. + * NOTE 1: The header mode is enabled by default. + * NOTE 2: By default the FIFO operating mode is FIFO mode. */ + rslt = bma4_set_fifo_config(BMA4_FIFO_ACCEL | BMA4_FIFO_HEADER | BMA4_FIFO_TIME, BMA4_ENABLE, &dev); + bma4_error_codes_print_result("bma4_set_fifo_config enable status", rslt); + + /* Update FIFO structure */ + fifoframe.data = fifo_data; + fifoframe.length = BMA456_AN_FIFO_RAW_DATA_USER_LENGTH + BMA4_SENSORTIME_OVERHEAD_BYTE; + + printf("FIFO is configured in header mode\n"); + + rslt = bma456_an_map_interrupt(BMA4_INTR1_MAP, BMA4_FIFO_WM_INT, BMA4_ENABLE, &dev); + bma4_error_codes_print_result("bma4_map_interrupt status", rslt); + + wm_lvl = BMA456_AN_FIFO_WATERMARK_LEVEL; + rslt = bma4_set_fifo_wm(wm_lvl, &dev); + bma4_error_codes_print_result("bma4_set_fifo_wm status", rslt); + + while (loop <= 10) + { + rslt = bma456_an_read_int_status(&int_status, &dev); + bma4_error_codes_print_result("bma4_read_int_status", rslt); + + if ((rslt == BMA4_OK) && (int_status & BMA4_FIFO_WM_INT)) + { + printf("\nIteration : %d\n", loop); + + rslt = bma4_get_fifo_wm(&watermark, &dev); + bma4_error_codes_print_result("bma4_get_fifo_wm status", rslt); + printf("FIFO watermark level : %d\n", watermark); + + rslt = bma4_get_fifo_length(&fifo_length, &dev); + bma4_error_codes_print_result("bma4_get_fifo_length status", rslt); + + printf("FIFO data bytes available : %d\n", fifo_length); + printf("FIFO data bytes requested : %d\n", fifoframe.length); + + /* Read FIFO data */ + rslt = bma4_read_fifo_data(&fifoframe, &dev); + bma4_error_codes_print_result("bma4_read_fifo_data status", rslt); + + accel_length = BMA456_AN_FIFO_ACCEL_FRAME_COUNT; + + if (rslt == BMA4_OK) + { + printf("Requested data frames before parsing: %d\n", accel_length); + + /* Parse the FIFO data to extract accelerometer data from the FIFO buffer */ + rslt = bma4_extract_accel(fifo_accel_data, &accel_length, &fifoframe, &dev); + printf("Parsed accelerometer data frames: %d\n", accel_length); + + printf("ACCEL, X, Y, Z\n"); + + /* Print the parsed accelerometer data from the FIFO buffer */ + for (idx = 0; idx < accel_length; idx++) + { + printf("%d, %d, %d, %d\n", + idx, + fifo_accel_data[idx].x, + fifo_accel_data[idx].y, + fifo_accel_data[idx].z); + } + + /* Print control frames like sensor time and skipped frame count */ + printf("Skipped frame count = %d\n", fifoframe.skipped_frame_count); + printf("Sensor time(in seconds) = %.4lf s\r\n", (fifoframe.sensor_time * BMA4_SENSORTIME_RESOLUTION)); + } + + loop++; + } + } + + bma4_coines_deinit(); + + return rslt; +} diff --git a/components/bma456/bma456an_examples/fifo_watermark_headerless_mode/Makefile b/components/bma456/bma456an_examples/fifo_watermark_headerless_mode/Makefile new file mode 100644 index 0000000..763f7ed --- /dev/null +++ b/components/bma456/bma456an_examples/fifo_watermark_headerless_mode/Makefile @@ -0,0 +1,18 @@ +COINES_INSTALL_PATH ?= ../../../.. + +EXAMPLE_FILE ?= fifo_watermark_headerless_mode.c + +API_LOCATION ?= ../.. + +COMMON_LOCATION ?= .. + +C_SRCS += \ +$(API_LOCATION)/bma4.c \ +$(API_LOCATION)/bma456_an.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/components/bma456/bma456an_examples/fifo_watermark_headerless_mode/fifo_watermark_headerless_mode.c b/components/bma456/bma456an_examples/fifo_watermark_headerless_mode/fifo_watermark_headerless_mode.c new file mode 100644 index 0000000..a6bd960 --- /dev/null +++ b/components/bma456/bma456an_examples/fifo_watermark_headerless_mode/fifo_watermark_headerless_mode.c @@ -0,0 +1,188 @@ +/**\ + * Copyright (c) 2022 Bosch Sensortec GmbH. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + **/ + +#include +#include "bma456_an.h" +#include "common.h" + +/******************************************************************************/ +/*! Macro definition */ + +/*! Buffer size allocated to store raw FIFO data */ +#define BMA456_AN_FIFO_RAW_DATA_BUFFER_SIZE UINT16_C(1024) + +/*! Length of data to be read from FIFO */ +#define BMA456_AN_FIFO_RAW_DATA_USER_LENGTH UINT16_C(1024) + +/*! Setting a watermark level in FIFO */ +#define BMA456_AN_FIFO_WATERMARK_LEVEL UINT16_C(600) + +/*! Number of accel frames to be extracted from FIFO + * Calculation: + * fifo_watermark_level = 600, accel_frame_len = 6. + * fifo_accel_frame_count = (600 / 6) = 100 frames + */ +#define BMA456_AN_FIFO_ACCEL_FRAME_COUNT UINT8_C(100) + +/******************************************************************************/ +/*! Function */ + +/* This function starts the execution of program */ +int main(void) +{ + /* Status of API are returned to this variable */ + int8_t rslt; + + /* Accelerometer configuration structure */ + struct bma4_accel_config acc_conf = { 0 }; + + /* Sensor initialization configuration */ + struct bma4_dev dev = { 0 }; + + /* Number of accelerometer frames */ + uint16_t accel_length; + + /* Variable to idx bytes */ + uint16_t idx = 0; + + /* Variable to maintain count of loop to run FIFO read */ + uint8_t loop = 1; + + /* Number of bytes of FIFO data + * NOTE : Dummy byte (for SPI Interface) required for FIFO data read must be given as part of array size + */ + uint8_t fifo_data[BMA456_AN_FIFO_RAW_DATA_BUFFER_SIZE] = { 0 }; + + /* Array of accelerometer frames -> Total bytes = + * 100 * (6 axes bytes(+/- x,y,z)) = 600 bytes */ + struct bma4_accel fifo_accel_data[BMA456_AN_FIFO_ACCEL_FRAME_COUNT] = { { 0 } }; + + /* Initialize FIFO frame structure */ + struct bma4_fifo_frame fifoframe = { 0 }; + + /* Variable that contains interrupt status value */ + uint16_t int_status = 0; + + /* Variable to hold the length of FIFO data */ + uint16_t fifo_length = 0; + + uint16_t watermark = 0; + + /* To set the watermark level in FIFO */ + uint16_t wm_lvl; + + /* Interface reference is given as a parameter + * For I2C : BMA4_I2C_INTF + * For SPI : BMA4_SPI_INTF + * Variant information given as parameter - BMA45X_VARIANT + */ + rslt = bma4_interface_init(&dev, BMA4_I2C_INTF, BMA45X_VARIANT); + bma4_error_codes_print_result("bma4_interface_init", rslt); + + /* Initialize BMA456_AN */ + rslt = bma456_an_init(&dev); + bma4_error_codes_print_result("bma456_an_init status", rslt); + + /* Accelerometer configuration settings */ + acc_conf.odr = BMA4_OUTPUT_DATA_RATE_100HZ; + acc_conf.bandwidth = BMA4_ACCEL_NORMAL_AVG4; + acc_conf.range = BMA4_ACCEL_RANGE_2G; + acc_conf.perf_mode = BMA4_CIC_AVG_MODE; + + /* Set the accel configurations */ + rslt = bma4_set_accel_config(&acc_conf, &dev); + bma4_error_codes_print_result("bma4_set_accel_config status", rslt); + + /* NOTE : Enable accel after set of configurations */ + rslt = bma4_set_accel_enable(1, &dev); + bma4_error_codes_print_result("bma4_set_accel_enable status", rslt); + + /* Disabling advance power save mode as FIFO data is not accessible in advance low power mode */ + rslt = bma4_set_advance_power_save(BMA4_DISABLE, &dev); + bma4_error_codes_print_result("bma4_set_advance_power_save status", rslt); + + /* Clear FIFO configuration register */ + rslt = bma4_set_fifo_config(BMA4_FIFO_ALL, BMA4_DISABLE, &dev); + bma4_error_codes_print_result("bma4_set_fifo_config disable status", rslt); + + /* Set FIFO configuration by enabling accel. + * NOTE 1: The header mode is enabled by default. + * NOTE 2: By default the FIFO operating mode is FIFO mode. */ + rslt = bma4_set_fifo_config(BMA4_FIFO_ACCEL, BMA4_ENABLE, &dev); + bma4_error_codes_print_result("bma4_set_fifo_config enable status", rslt); + + /* Update FIFO structure */ + fifoframe.data = fifo_data; + fifoframe.length = BMA456_AN_FIFO_RAW_DATA_USER_LENGTH; + + /* To enable headerless mode, disable the header. */ + rslt = bma4_set_fifo_config(BMA4_FIFO_HEADER, BMA4_DISABLE, &dev); + bma4_error_codes_print_result("bma4_set_fifo_config status", rslt); + + printf("FIFO is configured in headerless mode\n"); + + rslt = bma456_an_map_interrupt(BMA4_INTR1_MAP, BMA4_FIFO_WM_INT, BMA4_ENABLE, &dev); + bma4_error_codes_print_result("bma4_map_interrupt status", rslt); + + wm_lvl = BMA456_AN_FIFO_WATERMARK_LEVEL; + rslt = bma4_set_fifo_wm(wm_lvl, &dev); + bma4_error_codes_print_result("bma4_set_fifo_wm status", rslt); + + while (loop <= 10) + { + rslt = bma456_an_read_int_status(&int_status, &dev); + bma4_error_codes_print_result("bma4_read_int_status", rslt); + + if ((rslt == BMA4_OK) && (int_status & BMA4_FIFO_WM_INT)) + { + printf("\nIteration : %d\n", loop); + + rslt = bma4_get_fifo_wm(&watermark, &dev); + bma4_error_codes_print_result("bma4_get_fifo_wm status", rslt); + + printf("FIFO watermark level : %d\n", watermark); + + rslt = bma4_get_fifo_length(&fifo_length, &dev); + bma4_error_codes_print_result("bma4_get_fifo_length status", rslt); + + printf("FIFO data bytes available : %d\n", fifo_length); + printf("FIFO data bytes requested : %d\n", fifoframe.length); + + /* Read FIFO data */ + rslt = bma4_read_fifo_data(&fifoframe, &dev); + bma4_error_codes_print_result("bma4_read_fifo_data status", rslt); + + accel_length = BMA456_AN_FIFO_ACCEL_FRAME_COUNT; + + if (rslt == BMA4_OK) + { + printf("Requested data frames before parsing: %d\n", accel_length); + + /* Parse the FIFO data to extract accelerometer data from the FIFO buffer */ + rslt = bma4_extract_accel(fifo_accel_data, &accel_length, &fifoframe, &dev); + printf("Parsed accelerometer data frames: %d\n", accel_length); + + printf("ACCEL, X, Y, Z\n"); + + /* Print the parsed accelerometer data from the FIFO buffer */ + for (idx = 0; idx < accel_length; idx++) + { + printf("%d, %d, %d, %d\n", + idx, + fifo_accel_data[idx].x, + fifo_accel_data[idx].y, + fifo_accel_data[idx].z); + } + } + + loop++; + } + } + + bma4_coines_deinit(); + + return rslt; +} diff --git a/components/bma456/bma456an_examples/no_motion/Makefile b/components/bma456/bma456an_examples/no_motion/Makefile new file mode 100644 index 0000000..4f5c41a --- /dev/null +++ b/components/bma456/bma456an_examples/no_motion/Makefile @@ -0,0 +1,18 @@ +COINES_INSTALL_PATH ?= ../../../.. + +EXAMPLE_FILE ?= no_motion.c + +API_LOCATION ?= ../.. + +COMMON_LOCATION ?= .. + +C_SRCS += \ +$(API_LOCATION)/bma4.c \ +$(API_LOCATION)/bma456_an.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/components/bma456/bma456an_examples/no_motion/no_motion.c b/components/bma456/bma456an_examples/no_motion/no_motion.c new file mode 100644 index 0000000..8d3dcaa --- /dev/null +++ b/components/bma456/bma456an_examples/no_motion/no_motion.c @@ -0,0 +1,131 @@ +/**\ + * Copyright (c) 2022 Bosch Sensortec GmbH. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + **/ + +#include +#include "bma456_an.h" +#include "common.h" + +/******************************************************************************/ +/*! Static Function Declaration */ + +/*! + * @brief This internal API is used to get no-motion configurations. + * + * @param[in] bma : Structure instance of bma4_dev. + * + * @return Status of execution. + */ +static int8_t get_any_no_mot_config(struct bma4_dev *bma); + +/******************************************************************************/ +/*! Functions */ + +/* This function starts the execution of program. */ +int main(void) +{ + /* Variable to store the status of API */ + int8_t rslt; + + /* Sensor initialization configuration */ + struct bma4_dev bma = { 0 }; + + /* Variable to store any/no-motion interrupt status */ + uint16_t int_status = 0; + + /* Interface reference is given as a parameter + * For I2C : BMA4_I2C_INTF + * For SPI : BMA4_SPI_INTF + * Variant information given as parameter - BMA45X_VARIANT + */ + rslt = bma4_interface_init(&bma, BMA4_I2C_INTF, BMA45X_VARIANT); + bma4_error_codes_print_result("bma4_interface_init", rslt); + + /* Sensor initialization */ + rslt = bma456_an_init(&bma); + bma4_error_codes_print_result("bma456_an_init status", rslt); + + /* Upload the configuration file to enable the features of the sensor. */ + rslt = bma456_an_write_config_file(&bma); + bma4_error_codes_print_result("bma456_an_write_config status", rslt); + + /* Enable the accelerometer */ + rslt = bma4_set_accel_enable(BMA4_ENABLE, &bma); + bma4_error_codes_print_result("bma4_set_accel_enable status", rslt); + + /* Map the interrupt 1 for no-motion */ + rslt = bma456_an_map_interrupt(BMA4_INTR1_MAP, BMA456_AN_NO_MOT_INT, BMA4_ENABLE, &bma); + bma4_error_codes_print_result("bma456_an_map_interrupt status", rslt); + + /* Get no-motion configurations */ + rslt = get_any_no_mot_config(&bma); + bma4_error_codes_print_result("get_any_no_mot_config status", rslt); + + printf("Do not shake the board for no-motion interrupt\n"); + + for (;;) + { + /* Read interrupt status */ + rslt = bma456_an_read_int_status(&int_status, &bma); + bma4_error_codes_print_result("bma456_an_read_int_status", rslt); + + if (rslt == BMA4_OK) + { + /* Enters only if the obtained interrupt is no-motion */ + if (int_status & BMA456_AN_NO_MOT_INT) + { + printf("No-motion interrupt occurred\n"); + break; + } + } + } + + bma4_coines_deinit(); + + return rslt; +} + +/*! + * @brief This internal API is used to get any/no-motion configurations. + */ +static int8_t get_any_no_mot_config(struct bma4_dev *bma) +{ + /* Variable to store the status of API */ + int8_t rslt; + + /* Structure to define any/no-motion configurations */ + struct bma456_an_any_no_mot_config any_no_mot = { 0 }; + + /* Getting no-motion configuration to get default configuration */ + rslt = bma456_an_get_no_mot_config(&any_no_mot, bma); + bma4_error_codes_print_result("bma456_an_get_no_mot_config status", rslt); + + if (rslt == BMA4_OK) + { + /* + * Set the slope threshold: + * Interrupt will be generated if the slope of all the axis exceeds the threshold (1 bit = 0.48mG) + */ + any_no_mot.threshold = 10; + + /* + * Set the duration for no-motion interrupt: + * Duration defines the number of consecutive data points for which threshold condition must be + * true(1 bit = 20ms) + */ + any_no_mot.duration = 4; + + /* Enabling X, Y, and Z axis for no-motion feature */ + any_no_mot.axes_en = BMA456_AN_EN_ALL_AXIS; + + /* Like threshold and duration, we can also change the config of int_bhvr */ + + /* Set the threshold and duration configuration */ + rslt = bma456_an_set_no_mot_config(&any_no_mot, bma); + bma4_error_codes_print_result("bma456_an_set_no_mot_config status", rslt); + } + + return rslt; +} diff --git a/components/bma456/bma456h.c b/components/bma456/bma456h.c new file mode 100644 index 0000000..af29e75 --- /dev/null +++ b/components/bma456/bma456h.c @@ -0,0 +1,1649 @@ +/** +* 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. +* +* @file bma456h.c +* @date 2023-07-05 +* @version V2.29.0 +* +*/ + +/*! \file bma456h.c + * \brief Sensor Driver for BMA456H sensor + */ + +#include "bma456h.h" + +/**\name Feature configuration file */ +const uint8_t bma456h_config_file[] = { + 0xc8, 0x2e, 0x00, 0x2e, 0xc8, 0x2e, 0x00, 0x2e, 0xc8, 0x2e, 0x00, 0x2e, 0x80, 0x2e, 0xae, 0x00, 0x80, 0x2e, 0x6e, + 0x01, 0xc8, 0x2e, 0x00, 0x2e, 0xc8, 0x2e, 0x00, 0x2e, 0x80, 0x2e, 0x9a, 0x01, 0x50, 0x35, 0x21, 0x2e, 0xb0, 0xf0, + 0x10, 0x30, 0x21, 0x2e, 0x16, 0xf0, 0x80, 0x2e, 0xe7, 0x01, 0x8b, 0x50, 0x79, 0x52, 0x01, 0x42, 0x3b, 0x80, 0x41, + 0x30, 0x01, 0x42, 0x3c, 0x80, 0x00, 0x2e, 0x01, 0x40, 0x01, 0x42, 0x21, 0x2e, 0xff, 0xaf, 0xb8, 0x2e, 0x6d, 0x00, + 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, + 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, + 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, + 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, + 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x1e, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x04, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x21, 0x2e, 0xb0, 0xf0, 0x10, 0x30, + 0xc0, 0x2e, 0x21, 0x2e, 0x16, 0xf0, 0x90, 0x50, 0xe5, 0x7f, 0xd7, 0x7f, 0xf6, 0x7f, 0x86, 0x30, 0x7b, 0x5a, 0x00, + 0x2e, 0x47, 0x41, 0x57, 0x43, 0x00, 0x2e, 0x47, 0x41, 0x47, 0x43, 0x00, 0x2e, 0x47, 0x41, 0xbe, 0x09, 0x2d, 0x2e, + 0x69, 0x00, 0x0d, 0x2e, 0x69, 0x00, 0x80, 0x91, 0x02, 0x2f, 0x46, 0x30, 0x2d, 0x2e, 0x5a, 0x00, 0x0d, 0x2e, 0x57, + 0xf0, 0x47, 0x30, 0x45, 0x41, 0x6f, 0x09, 0xd2, 0xba, 0x40, 0x91, 0x79, 0x5a, 0xb5, 0x09, 0x67, 0xbb, 0x2d, 0x2e, + 0x8c, 0x00, 0x0e, 0x2f, 0xc4, 0x7f, 0xb3, 0x7f, 0xa2, 0x7f, 0x91, 0x7f, 0x80, 0x7f, 0x7b, 0x7f, 0x98, 0x2e, 0x33, + 0xb5, 0x80, 0x6f, 0x91, 0x6f, 0xa2, 0x6f, 0xb3, 0x6f, 0xc4, 0x6f, 0x7b, 0x6f, 0x79, 0x5a, 0x2b, 0x2e, 0xb9, 0xf0, + 0xe5, 0x6f, 0xd7, 0x6f, 0xf6, 0x6f, 0x70, 0x5f, 0xc8, 0x2e, 0x01, 0x2e, 0x58, 0xf0, 0x01, 0x37, 0x01, 0x08, 0x00, + 0xb2, 0x10, 0x30, 0x03, 0x2f, 0x03, 0x2e, 0x5a, 0x00, 0x44, 0xb2, 0x01, 0x2f, 0x00, 0x30, 0xb8, 0x2e, 0xb8, 0x2e, + 0x01, 0x2e, 0x58, 0xf0, 0x79, 0x52, 0xc0, 0x2e, 0x01, 0x08, 0x07, 0xb8, 0x80, 0x2e, 0x18, 0x00, 0xfd, 0x2d, 0xcc, + 0x00, 0x05, 0x00, 0xcc, 0x00, 0x64, 0x00, 0x33, 0x01, 0xf6, 0x78, 0x85, 0x00, 0xcd, 0x6c, 0x07, 0x00, 0x9a, 0x79, + 0x33, 0x73, 0x5f, 0x05, 0xbe, 0x0a, 0x5f, 0x05, 0x96, 0xe8, 0xef, 0x41, 0x01, 0x00, 0x0d, 0x00, 0x0c, 0x00, 0x4a, + 0x00, 0xa0, 0x00, 0x00, 0x00, 0x03, 0x00, 0x3c, 0x0f, 0x00, 0x01, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x08, 0x00, + 0x00, 0x00, 0x06, 0x00, 0x09, 0x00, 0x82, 0x00, 0x06, 0x00, 0x06, 0x00, 0x08, 0x00, 0x50, 0x00, 0x00, 0x00, 0x4c, + 0x04, 0x02, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x91, 0x41, 0x48, 0x40, 0x88, 0x00, 0x6c, 0x00, + 0x5f, 0x00, 0x6a, 0x00, 0x82, 0x00, 0x57, 0x00, 0x54, 0x00, 0x95, 0x00, 0xfc, 0x1f, 0x00, 0xe0, 0xff, 0x1f, 0x03, + 0x01, 0x01, 0x01, 0x55, 0xf0, 0x80, 0x00, 0x57, 0xf0, 0x39, 0xf0, 0x58, 0xf0, 0x89, 0xf0, 0x00, 0x40, 0xff, 0x7f, + 0x00, 0x80, 0x88, 0x00, 0x5e, 0xf0, 0x59, 0xf0, 0x00, 0x10, 0x00, 0x08, 0x00, 0x20, 0x76, 0x00, 0x00, 0xf8, 0xa0, + 0x00, 0xe8, 0x03, 0x01, 0x80, 0xb8, 0x7e, 0xe1, 0x7a, 0x7f, 0xff, 0x26, 0xf0, 0x91, 0x04, 0xf0, 0x00, 0xff, 0x00, + 0x00, 0xff, 0x56, 0xf0, 0x8e, 0x00, 0x62, 0x00, 0x66, 0x00, 0xff, 0xfb, 0x52, 0xf0, 0x33, 0x09, 0x33, 0x07, 0x90, + 0x01, 0xc8, 0x3b, 0x39, 0xc4, 0x91, 0x37, 0x66, 0x02, 0x00, 0x01, 0x02, 0x01, 0x8c, 0x00, 0xaf, 0x00, 0xec, 0x00, + 0xff, 0xb9, 0x00, 0x02, 0x00, 0xb0, 0x05, 0x80, 0xc9, 0xf0, 0x70, 0x50, 0xf0, 0x7f, 0xe1, 0x7f, 0xdb, 0x7f, 0x98, + 0x2e, 0xe9, 0x00, 0x00, 0xb2, 0x79, 0x50, 0x1b, 0x30, 0x05, 0x2f, 0x03, 0x2e, 0x03, 0xf0, 0x9d, 0xbc, 0x9f, 0xb8, + 0x40, 0x90, 0x04, 0x2f, 0x37, 0x2e, 0x61, 0x00, 0x21, 0x2e, 0xbc, 0xf0, 0x10, 0x2d, 0x69, 0x52, 0x7d, 0x50, 0xc5, + 0x7f, 0xb4, 0x7f, 0xa3, 0x7f, 0x92, 0x7f, 0x98, 0x2e, 0xd6, 0x01, 0x10, 0x30, 0x21, 0x2e, 0x52, 0x00, 0x92, 0x6f, + 0xa3, 0x6f, 0xb4, 0x6f, 0xc5, 0x6f, 0x79, 0x50, 0x21, 0x2e, 0xb8, 0xf0, 0xe1, 0x6f, 0xf0, 0x6f, 0xdb, 0x6f, 0x90, + 0x5f, 0xc8, 0x2e, 0x80, 0x50, 0xe1, 0x7f, 0xf0, 0x7f, 0xdb, 0x7f, 0x00, 0x2e, 0x7f, 0x52, 0x00, 0x2e, 0x60, 0x40, + 0x41, 0x40, 0x08, 0xbc, 0x41, 0x0a, 0x40, 0xb2, 0x12, 0x2f, 0x87, 0x7f, 0x71, 0x25, 0x67, 0x52, 0x81, 0x50, 0x94, + 0x7f, 0xa2, 0x7f, 0xb3, 0x7f, 0xc5, 0x7f, 0x98, 0x2e, 0xd6, 0x01, 0x10, 0x30, 0x17, 0x25, 0x21, 0x2e, 0x6b, 0x00, + 0xc5, 0x6f, 0xb3, 0x6f, 0xa2, 0x6f, 0x94, 0x6f, 0x87, 0x6f, 0x01, 0x2e, 0x6b, 0x00, 0x01, 0x0a, 0x00, 0xb2, 0x07, + 0x2f, 0x1b, 0x30, 0x37, 0x2e, 0x53, 0x00, 0x40, 0x90, 0x0b, 0x30, 0x01, 0x2f, 0x37, 0x2e, 0x6b, 0x00, 0x98, 0x2e, + 0xe9, 0x00, 0x00, 0xb2, 0x02, 0x2f, 0x79, 0x50, 0x21, 0x2e, 0xba, 0xf0, 0x0b, 0x31, 0x37, 0x2e, 0xb8, 0xf0, 0xe1, + 0x6f, 0xdb, 0x6f, 0xf0, 0x6f, 0x80, 0x5f, 0xc8, 0x2e, 0x05, 0x2e, 0x01, 0xf0, 0x2e, 0xbd, 0xae, 0xb9, 0x34, 0x30, + 0x43, 0x84, 0xe3, 0x04, 0x25, 0x40, 0x04, 0x40, 0xd8, 0xbe, 0x2c, 0x0b, 0x23, 0x11, 0x54, 0x42, 0x03, 0x80, 0x4a, + 0x0e, 0xf6, 0x2f, 0xb8, 0x2e, 0x1a, 0x24, 0x26, 0x00, 0x80, 0x2e, 0x00, 0xb0, 0x01, 0x2e, 0x55, 0xf0, 0xc0, 0x2e, + 0x21, 0x2e, 0x55, 0xf0, 0x10, 0x50, 0xfb, 0x7f, 0x21, 0x25, 0x98, 0x2e, 0x7a, 0xb1, 0xfb, 0x6f, 0x21, 0x25, 0xf0, + 0x5f, 0x10, 0x25, 0x80, 0x2e, 0x1e, 0xb1, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0xfd, 0x2d, 0x10, 0x50, + 0x98, 0x2e, 0x00, 0xb8, 0x6b, 0x50, 0x98, 0x2e, 0xa8, 0x00, 0x77, 0x50, 0x04, 0x80, 0xf0, 0x7f, 0x00, 0x2e, 0x00, + 0x2e, 0xd0, 0x2e, 0x01, 0x2e, 0x2c, 0x01, 0x01, 0xbc, 0x0e, 0xb8, 0x21, 0x2e, 0x5b, 0x00, 0x98, 0x2e, 0xd9, 0xb1, + 0x98, 0x2e, 0xa0, 0xb4, 0x01, 0x2e, 0x53, 0x00, 0x00, 0xb2, 0x90, 0x2e, 0xb8, 0xb0, 0x01, 0x2e, 0x5a, 0x00, 0x03, + 0xa0, 0x35, 0x2f, 0x03, 0xb2, 0x06, 0x2f, 0x75, 0x52, 0x73, 0x50, 0x21, 0x2e, 0x8b, 0x00, 0x23, 0x2e, 0x75, 0x00, + 0x1b, 0x2d, 0x05, 0x2e, 0x03, 0x01, 0x01, 0x2e, 0x5b, 0x00, 0x51, 0x30, 0x08, 0x04, 0x23, 0xbd, 0xa3, 0xb8, 0x48, + 0x12, 0x40, 0xb2, 0x12, 0x30, 0x51, 0x22, 0x01, 0x2e, 0x6a, 0x00, 0x6f, 0x54, 0x71, 0x56, 0x02, 0x08, 0x4b, 0x08, + 0x01, 0x0a, 0x61, 0x54, 0x63, 0x52, 0x21, 0x2e, 0x6a, 0x00, 0x25, 0x2e, 0x75, 0x00, 0x23, 0x2e, 0x8b, 0x00, 0x67, + 0x50, 0x98, 0x2e, 0x99, 0xb1, 0x67, 0x50, 0x5f, 0x52, 0x98, 0x2e, 0x0e, 0xb2, 0x67, 0x50, 0x65, 0x52, 0x98, 0x2e, + 0x0e, 0xb2, 0x01, 0x2e, 0x5a, 0x00, 0x04, 0x90, 0x02, 0x2f, 0x67, 0x50, 0x98, 0x2e, 0x3e, 0xb5, 0x05, 0x2e, 0x5a, + 0x00, 0x82, 0xb2, 0x51, 0x2f, 0x80, 0xb2, 0x4f, 0x2f, 0x81, 0xb2, 0x6d, 0x50, 0x41, 0x2f, 0x83, 0xb2, 0x03, 0x2e, + 0x73, 0x00, 0x2f, 0x2f, 0x84, 0x90, 0x53, 0x2f, 0x05, 0x2e, 0x69, 0x00, 0x80, 0x90, 0x03, 0x2f, 0x00, 0x30, 0x21, + 0x2e, 0x5d, 0x00, 0x4c, 0x2d, 0x07, 0x2e, 0x89, 0x00, 0x05, 0x2e, 0x2c, 0x01, 0xc0, 0xb2, 0x06, 0x2f, 0x13, 0x30, + 0xd3, 0x08, 0xc0, 0xb2, 0x02, 0x2f, 0x03, 0x30, 0x27, 0x2e, 0x5a, 0x00, 0x07, 0x2e, 0x6d, 0x00, 0x59, 0x0a, 0x40, + 0xb2, 0x02, 0x2f, 0x01, 0x30, 0x23, 0x2e, 0x5d, 0x00, 0x21, 0x30, 0x51, 0x08, 0x40, 0xb2, 0x32, 0x2f, 0x03, 0x2e, + 0x5d, 0x00, 0x10, 0x08, 0x41, 0x82, 0x02, 0xb8, 0x23, 0x2e, 0x5d, 0x00, 0x48, 0x0e, 0x29, 0x2f, 0x00, 0x30, 0x21, + 0x2e, 0x5a, 0x00, 0x26, 0x2d, 0x40, 0xb2, 0x23, 0x2f, 0x11, 0x30, 0x40, 0x30, 0x02, 0x30, 0x23, 0x2e, 0x6c, 0x00, + 0x23, 0x2e, 0x82, 0x00, 0x21, 0x2e, 0x5a, 0x00, 0x25, 0x2e, 0x5d, 0x00, 0x18, 0x2d, 0x01, 0x2e, 0x5e, 0x00, 0x3f, + 0x80, 0x21, 0x2e, 0x5e, 0x00, 0x00, 0xaa, 0x10, 0x2f, 0x30, 0x30, 0x21, 0x2e, 0x5a, 0x00, 0x0d, 0x2d, 0x03, 0x2e, + 0x5b, 0x00, 0x02, 0x32, 0x10, 0x30, 0x51, 0x10, 0x21, 0x2e, 0x6c, 0x00, 0x21, 0x2e, 0x82, 0x00, 0x21, 0x2e, 0x5a, + 0x00, 0x23, 0x2e, 0x5e, 0x00, 0x02, 0x30, 0x25, 0x2e, 0x53, 0x00, 0x01, 0x2e, 0x00, 0xf0, 0x09, 0x2e, 0x2c, 0x01, + 0x07, 0x2e, 0x69, 0x00, 0x4f, 0xba, 0xc0, 0x90, 0x03, 0x2e, 0x5c, 0x00, 0x06, 0x2f, 0x40, 0xb2, 0x00, 0x30, 0x29, + 0x2f, 0x25, 0x2e, 0x5c, 0x00, 0x27, 0x2c, 0x01, 0x25, 0x40, 0x90, 0x01, 0x2f, 0x21, 0x2e, 0x5c, 0x00, 0x03, 0x2e, + 0x5a, 0x00, 0x40, 0xb2, 0x12, 0x2f, 0x44, 0x90, 0x00, 0x30, 0x1a, 0x2f, 0x00, 0xb3, 0x01, 0x2e, 0x5c, 0x00, 0x16, + 0x2f, 0x98, 0x2e, 0xe9, 0x00, 0x00, 0xb2, 0x70, 0x32, 0x11, 0x2f, 0x93, 0x31, 0x98, 0x2e, 0xf7, 0x00, 0x00, 0x90, + 0x90, 0x30, 0x0c, 0x2c, 0x18, 0x22, 0x00, 0x91, 0x01, 0x2f, 0x21, 0x2e, 0x5c, 0x00, 0x21, 0x33, 0x23, 0x30, 0x01, + 0x2e, 0x5b, 0x00, 0x01, 0x00, 0x27, 0x2e, 0x5a, 0x00, 0x00, 0xb2, 0x01, 0x2f, 0x21, 0x2e, 0x00, 0xf0, 0x01, 0x2e, + 0x52, 0x00, 0x00, 0x90, 0x03, 0x2f, 0x01, 0x2e, 0x61, 0x00, 0x00, 0xb2, 0x06, 0x2f, 0x69, 0x50, 0x98, 0x2e, 0x99, + 0xb1, 0x69, 0x50, 0x98, 0x2e, 0x19, 0xb3, 0x02, 0x30, 0x25, 0x2e, 0x52, 0x00, 0x01, 0x2e, 0x55, 0xf0, 0x21, 0x2e, + 0x55, 0xf0, 0xf0, 0x6f, 0x03, 0x31, 0x01, 0x40, 0x05, 0x2e, 0x5a, 0x00, 0xcb, 0x0a, 0xf4, 0x3e, 0x83, 0x90, 0x4c, + 0x08, 0x4b, 0x22, 0x01, 0x42, 0x00, 0x2e, 0x01, 0x2e, 0x55, 0xf0, 0x21, 0x2e, 0x55, 0xf0, 0x80, 0x2e, 0x09, 0xb0, + 0x30, 0x50, 0x00, 0x30, 0x83, 0x56, 0x05, 0x30, 0x05, 0x2c, 0xfb, 0x7f, 0x3e, 0xbe, 0xd2, 0xba, 0xb2, 0xb9, 0x6c, + 0x0b, 0x53, 0x0e, 0xf9, 0x2f, 0x53, 0x1a, 0x01, 0x2f, 0x4d, 0x0e, 0xf5, 0x2f, 0xd2, 0x7f, 0x04, 0x30, 0x1f, 0x2c, + 0xe1, 0x7f, 0xc5, 0x01, 0xa3, 0x03, 0x72, 0x0e, 0x03, 0x2f, 0x72, 0x1a, 0x0f, 0x2f, 0x79, 0x0f, 0x0d, 0x2f, 0xe1, + 0x6f, 0x4f, 0x04, 0x5f, 0xb9, 0xb1, 0xbf, 0xfa, 0x0b, 0xd2, 0x6f, 0x96, 0x06, 0xb1, 0x25, 0x51, 0xbf, 0xeb, 0x7f, + 0x06, 0x00, 0xb2, 0x25, 0x27, 0x03, 0xdb, 0x7f, 0xcf, 0xbf, 0x3e, 0xbf, 0x01, 0xb8, 0xd2, 0xba, 0x41, 0xba, 0xb2, + 0xb9, 0x07, 0x0a, 0x6e, 0x0b, 0xc0, 0x90, 0xdf, 0x2f, 0x40, 0x91, 0xdd, 0x2f, 0xfb, 0x6f, 0xd0, 0x5f, 0xb8, 0x2e, + 0x94, 0x01, 0xdd, 0x03, 0xc0, 0xad, 0x0b, 0x2f, 0xc0, 0xa8, 0x03, 0x2f, 0xc0, 0x90, 0x07, 0x2f, 0x80, 0xa6, 0x05, + 0x2f, 0x40, 0xa9, 0x12, 0x2f, 0x40, 0x91, 0x01, 0x2f, 0x00, 0xab, 0x0e, 0x2f, 0xc0, 0xac, 0x00, 0x30, 0x87, 0x52, + 0x07, 0x2f, 0xc0, 0xa9, 0x03, 0x2f, 0xc0, 0x91, 0x03, 0x2f, 0x80, 0xa7, 0x01, 0x2f, 0x40, 0xa1, 0x05, 0x2f, 0xc0, + 0x2e, 0x17, 0x25, 0x06, 0x25, 0xc0, 0x2e, 0xf0, 0x3f, 0x85, 0x52, 0xb8, 0x2e, 0x83, 0x86, 0x01, 0x30, 0x00, 0x30, + 0x94, 0x40, 0x24, 0x18, 0x06, 0x00, 0x53, 0x0e, 0x4f, 0x02, 0xf9, 0x2f, 0xb8, 0x2e, 0x80, 0xa8, 0x03, 0x25, 0x10, + 0x2f, 0x80, 0x90, 0x01, 0x2f, 0x41, 0x0e, 0x0c, 0x2f, 0xf3, 0x3f, 0x18, 0x05, 0x05, 0x30, 0x5d, 0x07, 0x15, 0x0e, + 0x03, 0x2f, 0x55, 0x1a, 0x02, 0x2f, 0xcc, 0x0f, 0x00, 0x2f, 0x58, 0x04, 0x01, 0x25, 0xb8, 0x2e, 0xb8, 0x2e, 0x60, + 0x50, 0x03, 0x2e, 0x2e, 0x01, 0xe0, 0x7f, 0xf1, 0x7f, 0xdb, 0x7f, 0x30, 0x30, 0x89, 0x54, 0x0a, 0x1a, 0x28, 0x2f, + 0x1a, 0x25, 0x7a, 0x82, 0x00, 0x30, 0x43, 0x30, 0x32, 0x30, 0x05, 0x30, 0x04, 0x30, 0xf6, 0x6f, 0xf2, 0x09, 0xfc, + 0x13, 0xc2, 0xab, 0xb3, 0x09, 0xef, 0x23, 0x80, 0xb3, 0xe6, 0x6f, 0xb7, 0x01, 0x00, 0x2e, 0x8b, 0x41, 0x4b, 0x42, + 0x03, 0x2f, 0x46, 0x40, 0x86, 0x17, 0x81, 0x8d, 0x46, 0x42, 0x41, 0x8b, 0x23, 0xbd, 0xb3, 0xbd, 0x03, 0x89, 0x41, + 0x82, 0x07, 0x0c, 0x43, 0xa3, 0xe6, 0x2f, 0xe1, 0x6f, 0xa2, 0x6f, 0x52, 0x42, 0x00, 0x2e, 0xb2, 0x6f, 0x52, 0x42, + 0x00, 0x2e, 0xc2, 0x6f, 0x42, 0x42, 0x03, 0xb2, 0x03, 0x2e, 0x59, 0xf0, 0xf3, 0x3d, 0x02, 0x32, 0x0b, 0x08, 0x8a, + 0x0a, 0xdb, 0x6f, 0x02, 0x22, 0xa0, 0x5f, 0x21, 0x2e, 0x59, 0xf0, 0xb8, 0x2e, 0x03, 0x2e, 0x00, 0xf0, 0x07, 0x2e, + 0x00, 0xf0, 0xbc, 0xbe, 0x05, 0x2e, 0x2c, 0x01, 0x8d, 0x50, 0xaf, 0xb9, 0x02, 0x40, 0xf4, 0x33, 0xdc, 0xba, 0xc1, + 0xb2, 0x94, 0x08, 0x0e, 0x2f, 0x07, 0x2e, 0x5a, 0x00, 0xc4, 0x90, 0x0a, 0x2f, 0x79, 0x56, 0xcb, 0x0f, 0x07, 0x2f, + 0x49, 0xaf, 0x05, 0x2f, 0x79, 0x52, 0x51, 0x0a, 0x02, 0x34, 0x47, 0xa3, 0x8a, 0x0a, 0x91, 0x22, 0x3c, 0x80, 0x25, + 0x2e, 0x59, 0xf0, 0x01, 0x40, 0x01, 0x42, 0xb8, 0x2e, 0x0a, 0x86, 0x02, 0x30, 0x12, 0x42, 0x43, 0x0e, 0xfc, 0x2f, + 0x36, 0x80, 0x13, 0x30, 0x13, 0x42, 0x12, 0x42, 0x12, 0x42, 0x12, 0x42, 0x02, 0x42, 0x04, 0x80, 0x41, 0x84, 0x11, + 0x42, 0x02, 0x42, 0xb8, 0x2e, 0x46, 0x86, 0x80, 0x50, 0xe4, 0x40, 0xc2, 0x40, 0xf4, 0x7f, 0x83, 0xb0, 0x0b, 0x2e, + 0x57, 0xf0, 0x42, 0x88, 0xee, 0x13, 0xe4, 0x7f, 0x74, 0x30, 0xc2, 0x8a, 0xfc, 0x09, 0x03, 0x30, 0x43, 0x43, 0xc0, + 0xb3, 0xc7, 0x7f, 0xd0, 0x7f, 0x69, 0x2f, 0x41, 0x25, 0x55, 0x40, 0xb1, 0x7f, 0x41, 0x91, 0x0e, 0x2f, 0x03, 0x43, + 0x00, 0x2e, 0xe1, 0x6f, 0x12, 0x40, 0x52, 0x42, 0x00, 0x2e, 0x12, 0x40, 0x52, 0x42, 0x00, 0x2e, 0x00, 0x40, 0x40, + 0x42, 0x7d, 0x80, 0xc0, 0x2e, 0x03, 0x42, 0x80, 0x5f, 0x08, 0x89, 0x11, 0x30, 0x16, 0x41, 0x05, 0x41, 0xa6, 0x7f, + 0x39, 0x89, 0x86, 0x41, 0x45, 0x41, 0xd3, 0xbe, 0xd3, 0xba, 0x65, 0xbf, 0x95, 0x7f, 0x65, 0xbb, 0x05, 0x30, 0x86, + 0x7f, 0x8b, 0x15, 0xbe, 0x09, 0x80, 0xb3, 0x0a, 0x2f, 0x07, 0x40, 0x06, 0x41, 0xfe, 0x05, 0x06, 0x30, 0xc0, 0xa9, + 0xb7, 0x05, 0xfe, 0x23, 0x86, 0x6f, 0x7e, 0x0f, 0x4d, 0x23, 0xc7, 0x6f, 0x80, 0xb2, 0x06, 0x2f, 0xa6, 0x6f, 0x8f, + 0x5e, 0x86, 0x41, 0xf7, 0x09, 0xc0, 0xb3, 0xc7, 0x6f, 0x01, 0x2f, 0x06, 0x40, 0x06, 0x43, 0xc1, 0x86, 0x01, 0x80, + 0x01, 0x89, 0xc3, 0xa2, 0xe0, 0x2f, 0xb0, 0x6f, 0x2a, 0x1a, 0x02, 0x2f, 0x01, 0x30, 0x25, 0x2c, 0x01, 0x42, 0x02, + 0x40, 0x91, 0x28, 0x93, 0x6f, 0x02, 0x42, 0x53, 0x0e, 0x1d, 0x2f, 0xf2, 0x6f, 0x80, 0xb2, 0x03, 0x2f, 0xbf, 0x84, + 0x8a, 0x14, 0x25, 0x2e, 0x5e, 0xf0, 0xd4, 0x6f, 0xe3, 0x6f, 0x12, 0x41, 0xd2, 0x42, 0x02, 0x30, 0x15, 0x41, 0xd5, + 0x42, 0x00, 0x2e, 0x04, 0x41, 0xc4, 0x42, 0xc3, 0x86, 0xa5, 0x6f, 0x91, 0x58, 0x45, 0x41, 0x2c, 0x09, 0xc1, 0x42, + 0x00, 0xb3, 0x04, 0x2f, 0x00, 0x2e, 0x03, 0x2c, 0x02, 0x42, 0x10, 0x30, 0x40, 0x42, 0x80, 0x5f, 0xb8, 0x2e, 0x70, + 0x50, 0x42, 0x8e, 0xd4, 0x7f, 0xf6, 0x7f, 0x47, 0x25, 0x1a, 0x18, 0x93, 0x52, 0xf1, 0x00, 0x64, 0x25, 0x01, 0x30, + 0x39, 0x02, 0x94, 0x41, 0x81, 0x41, 0xe2, 0x7f, 0xbe, 0xbb, 0xbd, 0x8d, 0x02, 0xbd, 0xb5, 0x7f, 0x8e, 0xb5, 0xba, + 0x0a, 0xc6, 0x7f, 0xab, 0x7f, 0x51, 0x25, 0x98, 0x2e, 0x57, 0xb1, 0xd5, 0x6f, 0xe2, 0x6f, 0x2a, 0x18, 0x93, 0x54, + 0xb2, 0x01, 0x02, 0x30, 0xc4, 0x6f, 0x7a, 0x03, 0x12, 0x41, 0x74, 0x25, 0xd0, 0x7f, 0x52, 0xbc, 0xd3, 0x41, 0x6e, + 0xba, 0xde, 0xb6, 0x20, 0x0b, 0xc7, 0x7f, 0x91, 0x7f, 0x98, 0x2e, 0x57, 0xb1, 0xf2, 0x6f, 0xd5, 0x6f, 0xca, 0x16, + 0x55, 0x18, 0xdd, 0x18, 0x95, 0x6f, 0xea, 0x18, 0x93, 0x5a, 0x31, 0x25, 0x75, 0x01, 0x01, 0x30, 0x20, 0x25, 0x39, + 0x02, 0x5e, 0xba, 0x82, 0xbc, 0x8e, 0xb6, 0x21, 0x0b, 0x98, 0x2e, 0x57, 0xb1, 0xe2, 0x6f, 0xb5, 0x6f, 0x2a, 0x18, + 0xe0, 0x7f, 0xf1, 0x7f, 0x04, 0x30, 0x93, 0x54, 0xf2, 0x00, 0x7c, 0x02, 0x85, 0x6f, 0xd0, 0x6f, 0x0d, 0x17, 0x68, + 0x18, 0xe0, 0x18, 0x90, 0x6f, 0xc4, 0x6f, 0xc5, 0x18, 0xeb, 0x6f, 0xb2, 0x01, 0x1b, 0x43, 0x02, 0x30, 0x7a, 0x03, + 0xfb, 0x6f, 0x3d, 0x8f, 0x0b, 0x43, 0x3e, 0xba, 0x12, 0xbd, 0x52, 0xbc, 0x6e, 0xbb, 0xa2, 0x0a, 0x9e, 0xb5, 0xde, + 0xb6, 0x30, 0x0b, 0xf7, 0x7f, 0x98, 0x2e, 0x57, 0xb1, 0xf5, 0x6f, 0x31, 0x25, 0xd1, 0x6f, 0x92, 0x6f, 0xab, 0x6f, + 0x50, 0x43, 0x43, 0x43, 0x90, 0x5f, 0x85, 0x56, 0x80, 0x2e, 0x84, 0xb1, 0x10, 0x50, 0x03, 0x40, 0x19, 0x18, 0x87, + 0x56, 0x19, 0x05, 0x36, 0x25, 0xf7, 0x7f, 0x4a, 0x17, 0x54, 0x18, 0xec, 0x18, 0x09, 0x17, 0x01, 0x30, 0x0c, 0x07, + 0xe2, 0x18, 0xde, 0x00, 0xf2, 0x6f, 0x97, 0x02, 0x83, 0x58, 0xdc, 0x00, 0x91, 0x02, 0xbf, 0xb8, 0x21, 0xbd, 0x8a, + 0x0a, 0xc0, 0x2e, 0x02, 0x42, 0xf0, 0x5f, 0x03, 0x2e, 0x58, 0xf0, 0x02, 0x37, 0x30, 0x50, 0xca, 0x08, 0xc0, 0x90, + 0xfb, 0x7f, 0x0e, 0x2f, 0x03, 0x2e, 0x56, 0xf0, 0x32, 0x3e, 0x4a, 0x08, 0x23, 0x2e, 0x56, 0xf0, 0xe0, 0x7f, 0xd3, + 0x7f, 0x98, 0x2e, 0xeb, 0x01, 0x10, 0x30, 0x21, 0x2e, 0x61, 0x00, 0xe0, 0x6f, 0xd3, 0x6f, 0x03, 0x2e, 0x61, 0x00, + 0x40, 0x90, 0x95, 0x52, 0x1b, 0x2f, 0x05, 0x2e, 0x60, 0x00, 0x8b, 0x88, 0xb4, 0xb9, 0x03, 0x43, 0x30, 0x25, 0x98, + 0x2e, 0x95, 0xb3, 0x00, 0xb2, 0xe0, 0x7f, 0x09, 0x2f, 0x03, 0x2e, 0x56, 0xf0, 0x32, 0x3e, 0x02, 0xbc, 0x4a, 0x08, + 0x01, 0x0a, 0x21, 0x2e, 0x56, 0xf0, 0x98, 0x2e, 0xeb, 0x01, 0xe0, 0x6f, 0x00, 0xa6, 0x10, 0x30, 0x08, 0x2f, 0x21, + 0x2e, 0x5e, 0xf0, 0x06, 0x2d, 0x03, 0x30, 0x95, 0x50, 0x98, 0x2e, 0x5a, 0xb3, 0x27, 0x2e, 0x61, 0x00, 0xfb, 0x6f, + 0xd0, 0x5f, 0xb8, 0x2e, 0x0c, 0x82, 0x02, 0x30, 0x12, 0x42, 0x41, 0x0e, 0xfc, 0x2f, 0x35, 0x80, 0x91, 0x52, 0x11, + 0x42, 0x00, 0x2e, 0x97, 0x52, 0x01, 0x42, 0xb8, 0x2e, 0x07, 0x88, 0x46, 0x8e, 0x06, 0x41, 0x3c, 0x8b, 0x32, 0x1a, + 0x42, 0x41, 0xc7, 0x41, 0x16, 0x2f, 0x80, 0x91, 0x23, 0x2f, 0x57, 0x0f, 0x16, 0x30, 0x0c, 0x2f, 0x06, 0x80, 0x00, + 0x2e, 0x00, 0x40, 0x00, 0xb2, 0x04, 0x2f, 0x45, 0x82, 0x00, 0x2e, 0x41, 0x40, 0xd1, 0x0f, 0x02, 0x2f, 0x06, 0x30, + 0x06, 0x43, 0x46, 0x43, 0x80, 0xb3, 0x11, 0x2f, 0x03, 0x43, 0x47, 0x43, 0xb8, 0x2e, 0xd7, 0x0e, 0x0c, 0x2f, 0x43, + 0x82, 0x17, 0x04, 0x41, 0x40, 0x41, 0x0f, 0x07, 0x2f, 0x03, 0x43, 0x42, 0x83, 0x47, 0x43, 0x00, 0x2e, 0x43, 0x40, + 0xc1, 0x86, 0x43, 0x42, 0xb8, 0x2e, 0xb8, 0x2e, 0x88, 0x88, 0xc0, 0x50, 0x39, 0x8d, 0x88, 0x81, 0xe2, 0x7f, 0x02, + 0x30, 0x05, 0x40, 0xf2, 0x7f, 0x41, 0xab, 0x22, 0x30, 0x95, 0x22, 0x86, 0x41, 0x99, 0x5e, 0x9a, 0x00, 0x04, 0x41, + 0x37, 0x18, 0x66, 0x01, 0x9b, 0x56, 0xeb, 0x00, 0xc1, 0x7f, 0xb3, 0x7f, 0xd5, 0x7f, 0x48, 0x82, 0x39, 0x80, 0x82, + 0x40, 0xa0, 0x7f, 0x91, 0x7f, 0x8b, 0x7f, 0x06, 0x30, 0x83, 0x5a, 0x9d, 0x58, 0x83, 0x56, 0x98, 0x2e, 0x90, 0xb2, + 0x91, 0x6f, 0x7b, 0x82, 0xc6, 0x6f, 0x42, 0x40, 0x81, 0x84, 0x42, 0x42, 0x43, 0x82, 0x83, 0x8b, 0x42, 0x40, 0x86, + 0x89, 0x7b, 0x82, 0x84, 0x87, 0x71, 0x7f, 0x80, 0xb2, 0x95, 0x7f, 0x64, 0x7f, 0x50, 0x7f, 0x02, 0x2f, 0xc5, 0x40, + 0x41, 0x8b, 0xc5, 0x42, 0x87, 0x89, 0x67, 0x40, 0x07, 0x0f, 0x85, 0x8b, 0x41, 0x7f, 0x82, 0x8d, 0x47, 0x40, 0x3c, + 0x2f, 0x81, 0x41, 0x01, 0x0e, 0xe1, 0x6f, 0x2d, 0x2f, 0x46, 0x8c, 0x90, 0x6f, 0x86, 0x41, 0x07, 0x40, 0xfe, 0x0e, + 0x02, 0x2f, 0x04, 0x41, 0x00, 0xb3, 0x21, 0x2f, 0x44, 0x82, 0x04, 0x30, 0x41, 0x40, 0x71, 0x00, 0xf9, 0x0e, 0x36, + 0x2f, 0x46, 0x41, 0x80, 0xa7, 0x01, 0x30, 0x04, 0x30, 0x0d, 0x2f, 0xe4, 0x6f, 0x00, 0x2e, 0x04, 0x41, 0x74, 0x0f, + 0x04, 0x30, 0x07, 0x2f, 0x80, 0x90, 0x00, 0x2f, 0xc1, 0x42, 0x03, 0x86, 0x81, 0x84, 0xc2, 0x42, 0x01, 0x42, 0x14, + 0x30, 0x42, 0x85, 0x41, 0x43, 0xa1, 0x42, 0x00, 0x2e, 0x82, 0x40, 0x80, 0x90, 0x1c, 0x2f, 0x01, 0x42, 0x1b, 0x2d, + 0x06, 0x42, 0x19, 0x2c, 0x04, 0x30, 0xb2, 0x6f, 0xba, 0x04, 0x02, 0x1e, 0x80, 0x43, 0x12, 0x30, 0xc0, 0x6f, 0x23, + 0x30, 0x98, 0x2e, 0x66, 0xb3, 0x0e, 0x2c, 0x04, 0x30, 0xb2, 0x6f, 0xc0, 0x6f, 0xba, 0x00, 0x51, 0x6f, 0x01, 0x86, + 0x4a, 0x1c, 0xc1, 0x42, 0x22, 0x30, 0xe1, 0x6f, 0x13, 0x30, 0x98, 0x2e, 0x66, 0xb3, 0x04, 0x30, 0x52, 0x6f, 0x9f, + 0x52, 0x40, 0x6f, 0xc4, 0x7f, 0x98, 0x2e, 0xff, 0xb2, 0x41, 0x6f, 0x70, 0x6f, 0x42, 0x40, 0xa1, 0x52, 0x98, 0x2e, + 0xff, 0xb2, 0x41, 0x6f, 0x70, 0x6f, 0x42, 0x40, 0x01, 0x40, 0xd3, 0x6f, 0xd3, 0x00, 0xcb, 0x1e, 0xa1, 0x52, 0x13, + 0x42, 0xb0, 0x7f, 0x98, 0x2e, 0xff, 0xb2, 0xb0, 0x6f, 0x3e, 0x84, 0xd1, 0x6f, 0x82, 0x40, 0x03, 0x40, 0x51, 0x04, + 0x59, 0x1c, 0x01, 0x42, 0x02, 0x82, 0xa0, 0x6f, 0x42, 0x40, 0x03, 0x40, 0xd3, 0x0f, 0x00, 0x30, 0x14, 0x30, 0x60, + 0x22, 0xc5, 0x6f, 0x40, 0x91, 0x01, 0x2f, 0x53, 0x0e, 0x26, 0x2f, 0xe5, 0x6f, 0x47, 0x85, 0x00, 0x2e, 0x83, 0x40, + 0x59, 0x0f, 0x20, 0x2f, 0x62, 0x6f, 0x4a, 0x8f, 0x85, 0x40, 0xc7, 0x41, 0x7f, 0x8d, 0x6f, 0x0f, 0xa6, 0x15, 0x17, + 0x30, 0x04, 0x30, 0x0f, 0x2f, 0xe0, 0x6f, 0x0b, 0x80, 0x00, 0x2e, 0x07, 0x40, 0x3e, 0x08, 0x00, 0xb2, 0x00, 0x30, + 0x06, 0x2f, 0x59, 0x1a, 0x04, 0x2f, 0xfd, 0x12, 0xc0, 0x90, 0x13, 0x30, 0x4b, 0x22, 0x06, 0x25, 0x71, 0x25, 0xc0, + 0xb3, 0x04, 0x2f, 0xa4, 0x42, 0xa4, 0x42, 0x83, 0x82, 0x84, 0x42, 0x44, 0x42, 0x00, 0x2e, 0x8b, 0x6f, 0x40, 0x5f, + 0xb8, 0x2e, 0x87, 0x50, 0x50, 0x1a, 0x04, 0x2f, 0x85, 0x56, 0x41, 0x80, 0x4b, 0x1a, 0x81, 0x84, 0x41, 0x22, 0x00, + 0x30, 0xc0, 0x2e, 0x82, 0x04, 0x0a, 0x28, 0xff, 0x80, 0x14, 0x30, 0x20, 0x14, 0x0a, 0x18, 0x08, 0x17, 0x30, 0x00, + 0xc0, 0xb2, 0x3c, 0x03, 0x0b, 0x2f, 0xd0, 0xa0, 0x03, 0x2f, 0xf0, 0x80, 0x20, 0x10, 0x07, 0x2c, 0x08, 0x17, 0x05, + 0x31, 0x6b, 0x05, 0x65, 0x15, 0x03, 0x12, 0x23, 0x11, 0x05, 0x0a, 0xc8, 0x16, 0x23, 0x1a, 0x04, 0x2f, 0x4a, 0x0c, + 0x85, 0x54, 0xc0, 0x2e, 0x9f, 0xb8, 0x0a, 0x00, 0xb8, 0x2e, 0x20, 0x50, 0x4a, 0x25, 0x3e, 0x89, 0x07, 0x2e, 0x8c, + 0x00, 0x02, 0x30, 0xc0, 0xb2, 0x02, 0x43, 0xfb, 0x7f, 0x30, 0x2f, 0x07, 0x2e, 0x8d, 0x00, 0xc0, 0xb2, 0x11, 0x2f, + 0xc1, 0x90, 0x0d, 0x2f, 0x05, 0x2e, 0x2a, 0x01, 0x07, 0x2e, 0x2b, 0x01, 0xa1, 0x32, 0x98, 0x2e, 0xff, 0xb4, 0xe3, + 0x6f, 0x04, 0x30, 0x27, 0x2e, 0x2b, 0x01, 0x29, 0x2e, 0x8d, 0x00, 0x13, 0x2d, 0x12, 0x2c, 0x04, 0x30, 0xa5, 0x50, + 0xa3, 0x32, 0x14, 0x40, 0x11, 0x40, 0x18, 0xb9, 0x00, 0x40, 0x98, 0xbc, 0x61, 0x0a, 0x90, 0x0a, 0x98, 0x2e, 0xf1, + 0xb4, 0x14, 0x30, 0x29, 0x2e, 0x8d, 0x00, 0x21, 0x2e, 0x2b, 0x01, 0x04, 0x30, 0x7b, 0x56, 0xa3, 0x54, 0xc1, 0x40, + 0x8a, 0x08, 0xc2, 0x42, 0xfe, 0x86, 0x29, 0x2e, 0x8c, 0x00, 0xc4, 0x40, 0xc4, 0x42, 0x00, 0x2e, 0xfb, 0x6f, 0xe0, + 0x5f, 0xb8, 0x2e, 0xa7, 0x58, 0x00, 0x30, 0x0c, 0x2c, 0x8a, 0x00, 0x55, 0x40, 0x05, 0x0c, 0x05, 0x30, 0x01, 0xbf, + 0x0f, 0xb8, 0x00, 0x90, 0x34, 0x0c, 0x41, 0x8b, 0x06, 0x22, 0x50, 0xa3, 0xf7, 0x2f, 0x4a, 0x0e, 0xf2, 0x2f, 0xb8, + 0x2e, 0x40, 0x50, 0x0a, 0x25, 0x3c, 0x80, 0xfb, 0x7f, 0x01, 0x42, 0xd2, 0x7f, 0xe3, 0x7f, 0x32, 0x30, 0x10, 0x25, + 0x98, 0x2e, 0xdf, 0xb4, 0xfb, 0x6f, 0xc0, 0x5f, 0xb8, 0x2e, 0x70, 0x50, 0x0a, 0x25, 0x39, 0x80, 0xf3, 0x7f, 0x03, + 0x42, 0xa1, 0x7f, 0xc2, 0x7f, 0xd1, 0x7f, 0x03, 0x30, 0x03, 0x43, 0xe4, 0x7f, 0xbb, 0x7f, 0x22, 0x30, 0x10, 0x25, + 0x98, 0x2e, 0xdf, 0xb4, 0xd2, 0x6f, 0x02, 0x17, 0x04, 0x08, 0xc1, 0x6f, 0x0c, 0x09, 0x04, 0x1a, 0x10, 0x30, 0x04, + 0x30, 0x20, 0x22, 0x01, 0xb2, 0x14, 0x2f, 0xa9, 0x58, 0x14, 0x09, 0xf3, 0x30, 0x93, 0x08, 0x24, 0xbd, 0x44, 0xba, + 0x94, 0x0a, 0x02, 0x17, 0xf3, 0x6f, 0x4c, 0x08, 0x9a, 0x08, 0x8a, 0x0a, 0xad, 0x52, 0x51, 0x08, 0xab, 0x58, 0x94, + 0x08, 0x28, 0xbd, 0x98, 0xb8, 0xe4, 0x6f, 0x51, 0x0a, 0x01, 0x43, 0x00, 0x2e, 0xbb, 0x6f, 0x90, 0x5f, 0xb8, 0x2e, + 0xaf, 0x50, 0x31, 0x30, 0x23, 0x2e, 0x64, 0x00, 0x02, 0x40, 0x51, 0x0a, 0x21, 0x42, 0x00, 0x2e, 0x01, 0x40, 0x01, + 0x42, 0xb8, 0x2e, 0x80, 0x50, 0x09, 0x2e, 0x58, 0xf0, 0xf0, 0x7f, 0x43, 0x30, 0x23, 0x08, 0x5a, 0x25, 0x11, 0x30, + 0x23, 0x30, 0x72, 0x30, 0x79, 0x8b, 0x61, 0x08, 0xe3, 0x08, 0xa2, 0x08, 0x07, 0x30, 0x80, 0xb2, 0x47, 0x43, 0xeb, + 0x7f, 0xd1, 0x7f, 0xc0, 0x7f, 0xb3, 0x7f, 0x90, 0x2e, 0xe0, 0xb5, 0x09, 0x2e, 0x68, 0x00, 0x00, 0xb3, 0x09, 0x2f, + 0xb1, 0x52, 0x01, 0x2e, 0x65, 0x00, 0xa5, 0x7f, 0x98, 0x2e, 0xe6, 0xb5, 0x2f, 0x2e, 0x68, 0x00, 0xb3, 0x6f, 0xa5, + 0x6f, 0x03, 0x2e, 0x1d, 0x01, 0x15, 0xbe, 0x4f, 0xba, 0x00, 0xb3, 0x16, 0xbe, 0x46, 0xba, 0x14, 0xb1, 0xa6, 0x7f, + 0x61, 0x25, 0xb3, 0x58, 0xb5, 0x50, 0xc1, 0x6f, 0x02, 0x30, 0x0e, 0x2f, 0xb7, 0x5e, 0xb7, 0x09, 0xb3, 0x5e, 0x2d, + 0x2e, 0x1d, 0x01, 0xd2, 0x43, 0xc2, 0x43, 0x06, 0x30, 0xb9, 0x54, 0xaf, 0x5e, 0x96, 0x42, 0x57, 0x0e, 0xfc, 0x2f, + 0x16, 0x42, 0x06, 0x42, 0x2a, 0x25, 0xd9, 0x0a, 0xb8, 0x8c, 0x01, 0x2e, 0x65, 0x00, 0xf2, 0x6f, 0xb1, 0x52, 0x98, + 0x2e, 0x2a, 0xb6, 0xb3, 0x5a, 0x90, 0x6f, 0x54, 0x41, 0x00, 0xb2, 0x45, 0x41, 0x08, 0x2f, 0xd0, 0x6f, 0x00, 0xb2, + 0x05, 0x2f, 0xb5, 0x50, 0x23, 0x30, 0x14, 0x42, 0x05, 0x42, 0x27, 0x2e, 0x5e, 0xf0, 0xb0, 0x6f, 0x00, 0xb2, 0xaf, + 0x50, 0x2b, 0x2f, 0x03, 0x30, 0xb9, 0x52, 0x02, 0x31, 0xc0, 0xb2, 0x64, 0x25, 0x08, 0x2f, 0xd0, 0xa0, 0x02, 0x2f, + 0xf0, 0x8c, 0x05, 0x2c, 0xae, 0x13, 0xd3, 0x05, 0xa3, 0x13, 0xef, 0x15, 0xb7, 0x0b, 0x56, 0x42, 0xc8, 0x86, 0x48, + 0x0e, 0xef, 0x2f, 0xd3, 0x6f, 0xc0, 0x90, 0x15, 0x2f, 0xb5, 0x52, 0x00, 0x2e, 0x53, 0x40, 0x41, 0x40, 0xe3, 0x04, + 0x69, 0x06, 0x40, 0xaa, 0x04, 0x2f, 0x40, 0x90, 0x0b, 0x2f, 0xa1, 0x6f, 0x4b, 0x0f, 0x08, 0x2f, 0xa3, 0x6f, 0xc0, + 0xb2, 0x05, 0x2f, 0xb5, 0x56, 0x21, 0x30, 0xd4, 0x42, 0xc5, 0x42, 0x23, 0x2e, 0x5e, 0xf0, 0xc5, 0x6f, 0x40, 0xb3, + 0x16, 0x2f, 0x85, 0x6f, 0x09, 0x2e, 0x64, 0x00, 0x2c, 0x1a, 0x11, 0x2f, 0x09, 0x2e, 0x56, 0xf0, 0xc3, 0x3f, 0x2b, + 0x2e, 0x64, 0x00, 0x23, 0x09, 0x6c, 0x0b, 0x25, 0x42, 0x45, 0x30, 0x04, 0x40, 0x04, 0x42, 0x09, 0x88, 0x00, 0x2e, + 0x05, 0x43, 0x03, 0x2d, 0x15, 0x30, 0x2b, 0x2e, 0x68, 0x00, 0xeb, 0x6f, 0x80, 0x5f, 0xb8, 0x2e, 0x10, 0x50, 0x5a, + 0x84, 0xfb, 0x7f, 0x03, 0x30, 0x53, 0x42, 0x4a, 0x0e, 0xfc, 0x2f, 0x09, 0x86, 0x83, 0x54, 0xe4, 0x40, 0xc3, 0x80, + 0x94, 0x04, 0xc3, 0x40, 0x13, 0x05, 0x06, 0x40, 0xa6, 0x05, 0x4a, 0x17, 0x73, 0x30, 0x2b, 0x09, 0x4e, 0x17, 0xeb, + 0x08, 0x73, 0x01, 0x72, 0x86, 0xd3, 0xb4, 0xd1, 0x42, 0x49, 0x17, 0xc5, 0x42, 0xc3, 0x86, 0x94, 0x00, 0xd1, 0x42, + 0x23, 0xb5, 0xc5, 0x42, 0xfd, 0x86, 0x4a, 0x16, 0xd2, 0x42, 0xc3, 0x88, 0xc1, 0x42, 0x12, 0x43, 0x2d, 0x85, 0xbb, + 0x56, 0x93, 0x42, 0x01, 0x43, 0x13, 0x30, 0xbd, 0x52, 0x91, 0x42, 0x35, 0x82, 0x91, 0x50, 0x80, 0x42, 0xbe, 0x80, + 0x40, 0x25, 0x98, 0x2e, 0x1f, 0xb6, 0x0b, 0x83, 0xfb, 0x6f, 0xc0, 0x2e, 0x43, 0x42, 0xf0, 0x5f, 0x05, 0x80, 0x02, + 0x30, 0x02, 0x42, 0x51, 0x82, 0xbf, 0x54, 0x41, 0x40, 0x3e, 0x80, 0x51, 0x14, 0xc0, 0x2e, 0x01, 0x42, 0x00, 0x2e, + 0x30, 0x51, 0xd1, 0x7f, 0x12, 0x25, 0x02, 0x30, 0x42, 0x43, 0x32, 0x30, 0x82, 0x43, 0xc6, 0x7f, 0xe5, 0x7f, 0xb4, + 0x7f, 0xa3, 0x7f, 0x90, 0x7f, 0x8b, 0x7f, 0x98, 0x2e, 0xf0, 0x01, 0xd0, 0x7e, 0x00, 0xac, 0x01, 0x2f, 0x85, 0x52, + 0xd1, 0x7e, 0x00, 0x2e, 0x91, 0x6f, 0x49, 0x8a, 0xd1, 0x6f, 0x75, 0x7f, 0x4c, 0x82, 0x63, 0x41, 0x65, 0x7f, 0x11, + 0x7f, 0x00, 0x2e, 0x64, 0x41, 0x44, 0x85, 0x52, 0x7f, 0x45, 0x7f, 0x00, 0x2e, 0xa6, 0x40, 0x32, 0x7f, 0x82, 0x8e, + 0x80, 0x40, 0xd2, 0x6e, 0x45, 0x41, 0xf0, 0x7f, 0x27, 0x7f, 0x02, 0x7f, 0x98, 0x2e, 0x90, 0xb2, 0x23, 0x6f, 0xd1, + 0x6f, 0xc2, 0x40, 0xf9, 0x86, 0x23, 0x7f, 0x80, 0xb2, 0xe0, 0x7e, 0x0f, 0x2f, 0x32, 0x6f, 0x64, 0x6f, 0x82, 0x40, + 0xf2, 0x7f, 0x50, 0x82, 0x42, 0x6f, 0x50, 0x6f, 0x73, 0x6f, 0x85, 0x40, 0xc3, 0x40, 0x04, 0x41, 0x06, 0x40, 0xe2, + 0x6e, 0x98, 0x2e, 0x90, 0xb2, 0xe0, 0x7e, 0x00, 0x2e, 0x11, 0x6f, 0x76, 0x82, 0x71, 0x7f, 0x42, 0x80, 0xe2, 0x6e, + 0x41, 0x40, 0x60, 0x7f, 0x52, 0x7f, 0x98, 0x2e, 0x76, 0xb4, 0x10, 0x25, 0xb3, 0x30, 0x21, 0x25, 0x98, 0x2e, 0x82, + 0xb4, 0x21, 0x6f, 0x4d, 0x86, 0x20, 0x25, 0x41, 0x40, 0x60, 0x6f, 0x43, 0x7f, 0x98, 0x2e, 0xff, 0xb2, 0x74, 0x6f, + 0x60, 0x6f, 0x12, 0x30, 0xc1, 0x6f, 0x45, 0x6f, 0x42, 0x42, 0x06, 0x83, 0x52, 0x41, 0x43, 0x41, 0x04, 0x41, 0x00, + 0x40, 0x7a, 0x8b, 0xdc, 0x04, 0x10, 0x18, 0x61, 0x7f, 0x75, 0x7f, 0xb3, 0x0e, 0x02, 0x2f, 0xc1, 0x6f, 0x20, 0x30, + 0x40, 0x42, 0x05, 0x30, 0xd1, 0x6f, 0x4a, 0x80, 0x93, 0x6f, 0xa2, 0x6f, 0x40, 0x7f, 0xd7, 0x86, 0x80, 0xb2, 0x1f, + 0x2f, 0xc0, 0x40, 0x00, 0xb2, 0x1c, 0x2f, 0x55, 0x82, 0xc5, 0x5c, 0xc3, 0x58, 0xc1, 0x56, 0x02, 0x6f, 0x31, 0x7f, + 0xf5, 0x7f, 0x98, 0x2e, 0x90, 0xb2, 0x31, 0x6f, 0x76, 0x82, 0x00, 0xa4, 0x42, 0x40, 0x01, 0x2f, 0x80, 0xa0, 0x03, + 0x2f, 0x00, 0xac, 0x09, 0x2f, 0x80, 0xa4, 0x07, 0x2f, 0x41, 0x6f, 0x05, 0x30, 0x40, 0x40, 0x01, 0x80, 0x50, 0x42, + 0xaa, 0x04, 0x02, 0x2c, 0x42, 0x42, 0x05, 0x30, 0x00, 0x2e, 0xc4, 0x6f, 0x90, 0x6f, 0x0e, 0x86, 0x71, 0x6f, 0x04, + 0x41, 0xe0, 0x6f, 0x42, 0x40, 0xc3, 0x40, 0x02, 0xb3, 0x05, 0x42, 0xda, 0x22, 0x64, 0x6f, 0x10, 0x30, 0x02, 0x41, + 0x90, 0x28, 0x02, 0x43, 0x0c, 0x85, 0x78, 0x82, 0x84, 0x40, 0x20, 0x28, 0x80, 0x42, 0x7c, 0x88, 0xae, 0x80, 0x41, + 0x40, 0x52, 0x6f, 0x73, 0x7f, 0x60, 0x7f, 0x34, 0x7f, 0x98, 0x2e, 0xff, 0xb2, 0x33, 0x6f, 0x62, 0x6f, 0xbe, 0x80, + 0xe1, 0x40, 0x82, 0x40, 0x30, 0x7f, 0x23, 0x7f, 0x98, 0x2e, 0xff, 0xb2, 0x21, 0x6f, 0x60, 0x6f, 0x34, 0x6f, 0x22, + 0x40, 0x05, 0x41, 0x43, 0x40, 0x13, 0x01, 0x43, 0x86, 0xac, 0x0f, 0xd1, 0x6f, 0x20, 0x7f, 0x00, 0x2f, 0x44, 0x42, + 0x48, 0x8a, 0x41, 0x88, 0xe1, 0x40, 0x13, 0x7f, 0x04, 0x7f, 0xf5, 0x7e, 0x98, 0x2e, 0xff, 0xb2, 0x11, 0x6f, 0x63, + 0x6f, 0x40, 0x40, 0xc3, 0x40, 0x22, 0x6f, 0x18, 0x04, 0x82, 0x40, 0x4d, 0x86, 0x90, 0x0e, 0x01, 0x6f, 0x00, 0x2f, + 0x40, 0x42, 0x00, 0x2e, 0x34, 0x6f, 0xd6, 0x6f, 0x15, 0x41, 0x51, 0x6f, 0x90, 0x6f, 0x11, 0x80, 0x86, 0x85, 0x8d, + 0x0e, 0x1f, 0x2f, 0xf5, 0x6e, 0x81, 0x43, 0x00, 0x2e, 0x46, 0x41, 0x77, 0x6f, 0x37, 0x0f, 0x06, 0x40, 0x04, 0x2f, + 0x80, 0x91, 0x06, 0x30, 0x15, 0x2f, 0x46, 0x43, 0x14, 0x2d, 0x85, 0x40, 0x42, 0xb3, 0x04, 0x2f, 0x80, 0x91, 0x0b, + 0x2f, 0x05, 0x30, 0x0a, 0x2c, 0x85, 0x42, 0xe6, 0x6f, 0x1b, 0x30, 0x8b, 0x43, 0x82, 0x8a, 0x06, 0x30, 0x46, 0x43, + 0x4c, 0x8b, 0x8b, 0x42, 0x46, 0x43, 0x02, 0x2c, 0x06, 0x30, 0x06, 0x30, 0x05, 0x41, 0x8d, 0x0f, 0x13, 0x89, 0x05, + 0x6f, 0x2b, 0x30, 0x04, 0x2f, 0x41, 0x43, 0x45, 0x83, 0x4e, 0x8a, 0x4b, 0x42, 0x46, 0x43, 0x00, 0x2e, 0x91, 0x6f, + 0x4f, 0x8a, 0x04, 0x41, 0xc3, 0x40, 0xa3, 0x0e, 0x75, 0x7f, 0x06, 0x2f, 0x00, 0x40, 0x00, 0x90, 0x03, 0x2f, 0x8e, + 0x80, 0x86, 0x42, 0x06, 0x42, 0x00, 0x2e, 0xa0, 0x6f, 0x00, 0x90, 0xd0, 0x6f, 0x03, 0x2f, 0x8b, 0x6f, 0xd0, 0x5e, + 0x80, 0x2e, 0x1f, 0xb6, 0x07, 0x84, 0x13, 0x30, 0x84, 0x40, 0x23, 0x29, 0x84, 0x42, 0x44, 0x88, 0xe5, 0x6f, 0xa2, + 0x7f, 0x05, 0x84, 0x41, 0x41, 0x62, 0x7f, 0x40, 0xb2, 0x6b, 0x2f, 0x81, 0x40, 0x40, 0xa6, 0x11, 0x30, 0x2d, 0x2f, + 0xa0, 0x6f, 0x91, 0x6f, 0x02, 0x40, 0x46, 0x82, 0x4f, 0x86, 0x3c, 0x80, 0x41, 0x40, 0x24, 0xbd, 0x53, 0x7f, 0x34, + 0x7f, 0x20, 0x7f, 0x98, 0x2e, 0xff, 0xb2, 0x50, 0x6f, 0x13, 0x30, 0x01, 0x40, 0x40, 0xb2, 0x02, 0x80, 0x11, 0x30, + 0x0b, 0x2f, 0x91, 0x6f, 0x56, 0x82, 0x24, 0x6f, 0xa2, 0x6f, 0x04, 0x41, 0x41, 0x40, 0x82, 0x40, 0x0c, 0x18, 0x24, + 0xbd, 0x96, 0x0e, 0x01, 0x30, 0x59, 0x22, 0x00, 0x40, 0x00, 0xb2, 0xd0, 0x6f, 0x62, 0x6f, 0x34, 0x6f, 0x06, 0x30, + 0x06, 0x2f, 0x91, 0x6f, 0x58, 0x8a, 0x41, 0x6f, 0x45, 0x41, 0x41, 0x40, 0xcd, 0x0e, 0x5e, 0x22, 0x40, 0x90, 0x03, + 0x2f, 0x91, 0x6f, 0x98, 0x2e, 0x1f, 0xb6, 0x2f, 0x2d, 0x81, 0x40, 0x02, 0x41, 0xca, 0x0f, 0x08, 0x2f, 0x60, 0x6f, + 0x41, 0x82, 0x01, 0x42, 0x4a, 0x0e, 0xd6, 0x7e, 0x19, 0x2f, 0x00, 0x2e, 0x18, 0x2c, 0xd1, 0x7e, 0x03, 0x80, 0x04, + 0x82, 0x02, 0x40, 0x40, 0x40, 0xa1, 0xbc, 0x04, 0xbc, 0x48, 0x04, 0x40, 0xa8, 0x31, 0x04, 0x48, 0x22, 0x51, 0x7f, + 0xd3, 0x7e, 0xb3, 0x30, 0xc7, 0x52, 0x98, 0x2e, 0x82, 0xb4, 0x51, 0x6f, 0xc8, 0x0f, 0x21, 0x30, 0x02, 0x2f, 0xe0, + 0x6f, 0xd1, 0x7e, 0x01, 0x42, 0x06, 0x30, 0xb1, 0x6f, 0xd0, 0x6e, 0x42, 0x40, 0x10, 0x00, 0x50, 0x42, 0x00, 0x2e, + 0x40, 0x40, 0x06, 0x02, 0x40, 0x42, 0x00, 0x2e, 0x61, 0x6f, 0x42, 0x82, 0x43, 0x80, 0x46, 0x42, 0x06, 0x42, 0x00, + 0x2e, 0xa1, 0x6f, 0x70, 0x6f, 0x43, 0x40, 0x02, 0x40, 0x9a, 0x0e, 0x35, 0x86, 0x7e, 0x88, 0x91, 0x6f, 0xd0, 0x6f, + 0x01, 0x2f, 0x98, 0x2e, 0x1f, 0xb6, 0x00, 0x2e, 0x01, 0x41, 0xc0, 0x40, 0xc8, 0x0f, 0xc1, 0x6f, 0x00, 0x2f, 0x46, + 0x42, 0x00, 0x2e, 0x8b, 0x6f, 0xd0, 0x5e, 0xb8, 0x2e, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, + 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, + 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0xfd, 0x2d, 0xdb, 0x50, 0xcf, 0x52, 0x21, 0x42, 0x20, 0x50, 0xab, 0x52, + 0x01, 0x42, 0x29, 0x80, 0xd1, 0x52, 0x01, 0x42, 0x02, 0x80, 0x01, 0x3f, 0x02, 0x40, 0x51, 0x08, 0xfb, 0x7f, 0x11, + 0x42, 0x0b, 0x31, 0x0b, 0x42, 0x3e, 0x80, 0xf1, 0x32, 0x01, 0x42, 0x09, 0x80, 0x03, 0x2e, 0x40, 0xf0, 0x56, 0x90, + 0xe0, 0x7f, 0x31, 0x30, 0x1f, 0x2f, 0x03, 0x30, 0xd9, 0x52, 0xd3, 0x54, 0x24, 0x35, 0x06, 0x30, 0xd5, 0x50, 0x55, + 0x32, 0x1d, 0x1a, 0xe3, 0x22, 0x18, 0x1a, 0xd7, 0x58, 0xe3, 0x22, 0x04, 0x30, 0xd5, 0x40, 0xb5, 0x0d, 0xe1, 0xbe, + 0x6f, 0xbb, 0x80, 0x91, 0xa9, 0x0d, 0x01, 0x89, 0xb5, 0x23, 0x10, 0xa1, 0xf7, 0x2f, 0xda, 0x0e, 0x24, 0x35, 0xeb, + 0x2f, 0x01, 0x2e, 0x25, 0x00, 0x70, 0x1a, 0x00, 0x30, 0x21, 0x30, 0x48, 0x22, 0x40, 0xb2, 0x06, 0x2f, 0x23, 0x2e, + 0x59, 0xf0, 0x98, 0x2e, 0xeb, 0x01, 0x00, 0x2e, 0x00, 0x2e, 0xd0, 0x2e, 0xe0, 0x6f, 0x01, 0x31, 0x20, 0x26, 0x02, + 0x40, 0x79, 0x56, 0x93, 0x0a, 0x22, 0x42, 0x01, 0x42, 0x10, 0x30, 0x21, 0x2e, 0x59, 0xf0, 0x98, 0x2e, 0xeb, 0x01, + 0x5f, 0x50, 0xc9, 0x52, 0x98, 0x2e, 0xfd, 0xb1, 0x5f, 0x50, 0x05, 0x84, 0x14, 0x30, 0x65, 0x50, 0x53, 0x30, 0xcb, + 0x52, 0x94, 0x42, 0x83, 0x42, 0x98, 0x2e, 0xfd, 0xb1, 0xcd, 0x50, 0x65, 0x54, 0x01, 0x30, 0x86, 0x84, 0x11, 0x42, + 0x63, 0x30, 0xfb, 0x6f, 0xe0, 0x5f, 0x83, 0x42, 0x01, 0x42, 0x80, 0x2e, 0x33, 0xb5, 0x80, 0x2e, 0x18, 0x00, 0x80, + 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, + 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, + 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, + 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, + 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, + 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, + 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, + 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, + 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, + 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, + 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, + 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, + 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, + 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, + 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, + 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, + 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, + 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, + 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, + 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, + 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, + 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, + 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, + 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, + 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, + 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, + 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, + 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, + 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, + 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, + 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, + 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, + 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, + 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, + 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, + 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, + 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, + 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, + 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, + 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, + 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, + 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, + 0x00, 0x80, 0x2e, 0x18, 0x00, 0xfd, 0x2d +}; + +/***************************************************************************/ + +/*! Static Function Declarations + ****************************************************************************/ + +/*! + * @brief This API enables the features of sensor. + * + * @param[in] feature : Variable to specify the features which are to be set in + * the sensor. + * @param[in] feature_config : Array address which stores the feature + * configuration data + * @param[in] dev : Structure instance of bma4_dev. + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +static int8_t feature_enable(uint16_t feature, uint8_t *feature_config, struct bma4_dev *dev); + +/*! + * @brief This API disables the features of sensor. + * + * @param[in] feature : Variable to specify the features which are to be unset + * in the sensor. + * @param[in] feature_config : Array address which stores the feature + * configuration data + * @param[in] dev : Structure instance of bma4_dev. + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +static int8_t feature_disable(uint16_t feature, uint8_t *feature_config, struct bma4_dev *dev); + +/*! + * @brief This API update the settings of step counter into write array. + * + * @param[in] setting : Pointer to structure variable which stores the + * settings parameter1 to parameter25. + * @param[in] index : Value for array traversing. + * @param[out] feature_config : Pointer to store the settings + * + * @return none + */ +static void update_stepcounter_parameter(const struct bma456h_stepcounter_settings *setting, + uint8_t index, + uint8_t *feature_config); + +/*! + * @brief This API copy the settings of step counter into the + * structure of bma456h_stepcounter_settings, which is read from sensor. + * + * @param[out] setting : Pointer to structure variable which stores the + * settings parameter1 to parameter25 read from sensor. + * @param[in] data_p : Pointer of array which stores the parameters. + * + * @return none + */ +static void extract_stepcounter_parameter(struct bma456h_stepcounter_settings *setting, const uint16_t *data_p); + +/*! + * @brief This API update the settings of tap into write array. + * + * @param[in] setting : Pointer to structure variable which stores the + * settings parameter1 to parameter12. + * @param[in] index : Value for array traversing. + * @param[out] feature_config : Pointer to store the settings + * + * @return none + */ +static void update_tap_parameter(const struct bma456h_multitap_settings *setting, uint8_t index, + uint8_t *feature_config); + +/*! + * @brief This API copy the settings of tap into the + * structure of bma456h_multitap_settings, which is read from sensor. + * + * @param[out] setting : Pointer to structure variable which stores the + * settings parameter1 to parameter12 read from sensor. + * @param[in] data_p : Pointer of array which stores the parameters. + * + * @return none + */ +static void extract_tap_parameter(struct bma456h_multitap_settings *setting, const uint16_t *data_p); + +/***************************************************************************/ + +/**\name 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 and sets the resolution. + */ +int8_t bma456h_init(struct bma4_dev *dev) +{ + int8_t rslt; + + /* Structure to define the default values for axes re-mapping */ + struct bma4_axes_remap axes_remap = { + .x_axis = BMA4_MAP_X_AXIS, .x_axis_sign = BMA4_MAP_POSITIVE, .y_axis = BMA4_MAP_Y_AXIS, + .y_axis_sign = BMA4_MAP_POSITIVE, .z_axis = BMA4_MAP_Z_AXIS, .z_axis_sign = BMA4_MAP_POSITIVE + }; + + rslt = bma4_init(dev); + if (rslt == BMA4_OK) + { + if (dev->chip_id == BMA456H_CHIP_ID) + { + /* Resolution of BMA456H sensor is 16 bit */ + dev->resolution = BMA4_16_BIT_RESOLUTION; + + dev->feature_len = BMA456H_FEATURE_SIZE; + + dev->config_size = sizeof(bma456h_config_file); + + /* Set the default values for axis + * re-mapping in the device structure + */ + dev->remap = axes_remap; + } + else + { + rslt = BMA4_E_INVALID_SENSOR; + } + } + + return rslt; +} + +/*! + * @brief This API is used to upload the configuration file to enable the + * features of the sensor. + */ +int8_t bma456h_write_config_file(struct bma4_dev *dev) +{ + int8_t rslt = BMA4_OK; + + if (dev != NULL) + { + if (dev->chip_id == BMA456H_CHIP_ID) + { + /* Configuration stream read/write length boundary + * check + */ + if ((dev->read_write_len >= BMA456H_RD_WR_MIN_LEN) && (dev->read_write_len <= BMA456H_RD_WR_MAX_LEN)) + { + /* Even or odd check */ + if (dev->read_write_len & 0x01) + { + dev->read_write_len = dev->read_write_len - 1; + } + + /* Assign stream data */ + dev->config_file_ptr = bma456h_config_file; + rslt = bma4_write_config_file(dev); + } + else + { + rslt = BMA4_E_RD_WR_LENGTH_INVALID; + } + } + else + { + rslt = BMA4_E_INVALID_SENSOR; + } + } + else + { + rslt = BMA4_E_NULL_PTR; + } + + return rslt; +} + +/*! + * @brief This API is used to get the configuration id of the sensor. + */ +int8_t bma456h_get_config_id(uint16_t *config_id, struct bma4_dev *dev) +{ + uint8_t feature_config[BMA456H_FEATURE_SIZE] = { 0 }; + uint8_t index = BMA456H_CONFIG_ID_OFFSET; + int8_t rslt = BMA4_OK; + uint16_t config_id_lsb = 0; + uint16_t config_id_msb = 0; + + if ((dev != NULL) && (config_id != NULL)) + { + if (dev->chip_id == BMA456H_CHIP_ID) + { + rslt = bma4_read_regs(BMA4_FEATURE_CONFIG_ADDR, feature_config, BMA456H_FEATURE_SIZE, dev); + if (rslt == BMA4_OK) + { + config_id_lsb = (uint16_t)feature_config[index]; + config_id_msb = ((uint16_t)feature_config[index + 1]) << 8; + *config_id = config_id_lsb | config_id_msb; + } + } + else + { + rslt = BMA4_E_INVALID_SENSOR; + } + } + else + { + rslt = BMA4_E_NULL_PTR; + } + + return rslt; +} + +/*! + * @brief This API sets/un-sets the user provided interrupt to either interrupt + * pin1 or pin2 in the sensor. + */ +int8_t bma456h_map_interrupt(uint8_t int_line, uint16_t int_map, uint8_t enable, struct bma4_dev *dev) +{ + int8_t rslt = BMA4_OK; + + if (dev != NULL) + { + if (dev->chip_id == BMA456H_CHIP_ID) + { + if (int_line <= 1) + { + /* Map/Unmap the interrupt */ + rslt = bma4_map_interrupt(int_line, int_map, enable, dev); + } + else + { + rslt = BMA4_E_INT_LINE_INVALID; + } + } + else + { + rslt = BMA4_E_INVALID_SENSOR; + } + } + else + { + rslt = BMA4_E_NULL_PTR; + } + + return rslt; +} + +/*! + * @brief This API reads the bma456h interrupt status from the sensor. + */ +int8_t bma456h_read_int_status(uint16_t *int_status, struct bma4_dev *dev) +{ + int8_t rslt = BMA4_OK; + + if ((dev != NULL) && (int_status != NULL)) + { + if (dev->chip_id == BMA456H_CHIP_ID) + { + /* Read the interrupt status */ + rslt = bma4_read_int_status(int_status, dev); + } + else + { + rslt = BMA4_E_INVALID_SENSOR; + } + } + else + { + rslt = BMA4_E_NULL_PTR; + } + + return rslt; +} + +/*! + * @brief This API enables/disables the features of the sensor. + */ +int8_t bma456h_feature_enable(uint16_t feature, uint8_t enable, struct bma4_dev *dev) +{ + uint8_t feature_config[BMA456H_FEAT_EN_SIZE] = { 0, 0 }; + int8_t rslt = BMA4_OK; + uint8_t len = BMA456H_FEAT_EN_SIZE; + + if (dev != NULL) + { + if (dev->chip_id == BMA456H_CHIP_ID) + { + /* Read feature configuration data */ + rslt = bma4_read_regs(BMA456H_FEAT_EN_ADDR1, feature_config, len, dev); + if (rslt == BMA4_OK) + { + if (enable == TRUE) + { + /* Enables the feature */ + rslt = feature_enable(feature, feature_config, dev); + } + else + { + /* Disables the feature */ + rslt = feature_disable(feature, feature_config, dev); + } + } + } + else + { + rslt = BMA4_E_INVALID_SENSOR; + } + } + else + { + rslt = BMA4_E_NULL_PTR; + } + + return rslt; +} + +/*! + * @brief This API performs x, y and z axis remapping in the sensor. + */ +int8_t bma456h_set_remap_axes(const struct bma4_remap *remap_axes, struct bma4_dev *dev) +{ + uint8_t feature_config[BMA456H_FEATURE_SIZE] = { 0 }; + uint8_t index = BMA456H_AXES_REMAP_OFFSET; + int8_t rslt = BMA4_OK; + + if (remap_axes != NULL) + { + rslt = bma4_set_remap_axes(remap_axes, feature_config, index, BMA456H_FEATURE_SIZE, dev); + } + else + { + rslt = BMA4_E_NULL_PTR; + } + + return rslt; +} + +/*! + * @brief This API reads the x, y and z axis remap data from the sensor. + */ +int8_t bma456h_get_remap_axes(struct bma4_remap *remap_axes, struct bma4_dev *dev) +{ + uint8_t feature_config[BMA456H_FEATURE_SIZE] = { 0 }; + uint8_t index = BMA456H_AXES_REMAP_OFFSET; + int8_t rslt = BMA4_OK; + + if (remap_axes != NULL) + { + rslt = bma4_get_remap_axes(remap_axes, feature_config, index, BMA456H_FEATURE_SIZE, dev); + } + else + { + rslt = BMA4_E_NULL_PTR; + } + + return rslt; +} + +/*! + * @brief This API sets the configuration of any-motion feature in the sensor. + * This API enables/disables the any-motion feature according to the axis set. + */ + +int8_t bma456h_set_any_mot_config(const struct bma456h_any_no_mot_config *any_mot, struct bma4_dev *dev) +{ + /* Variable to define error */ + int8_t rslt = BMA4_OK; + + /* Initialize configuration file */ + uint8_t feature_config[BMA456H_FEATURE_SIZE] = { 0 }; + + /* Update index to configure any-motion axes */ + uint8_t index = BMA456H_ANY_MOT_OFFSET; + + if ((dev != NULL) && (any_mot != NULL)) + { + /* Get any-motion configuration from the sensor */ + rslt = bma4_read_regs(BMA4_FEATURE_CONFIG_ADDR, feature_config, BMA456H_ANY_MOT_LEN, dev); + if (rslt == BMA4_OK) + { + /* Set threshold value in feature configuration array */ + feature_config[index] = BMA4_GET_LSB(any_mot->threshold); + feature_config[index + 1] = BMA4_GET_MSB(any_mot->threshold); + feature_config[index + 1] = BMA4_SET_BITSLICE(feature_config[index + 1], + BMA456H_ANY_NO_MOTION_INTR_BHVR_EN, + any_mot->intr_bhvr); + feature_config[index + 1] = BMA4_SET_BITSLICE(feature_config[index + 1], + BMA456H_ANY_MOTION_SLOPE_EN, + any_mot->slope); + + /* Extract the word where duration and axes enable + * resides + */ + feature_config[index + 2] = BMA4_GET_LSB(any_mot->duration); + feature_config[index + 3] = BMA4_GET_MSB(any_mot->duration); + + /* Set any-motion configuration to the sensor */ + rslt = bma4_write_regs(BMA4_FEATURE_CONFIG_ADDR, feature_config, BMA456H_ANY_MOT_LEN, dev); + } + } + else + { + rslt = BMA4_E_NULL_PTR; + } + + return rslt; +} + +/*! + * @brief This API gets the configuration of any-motion feature from the + * sensor. + */ +int8_t bma456h_get_any_mot_config(struct bma456h_any_no_mot_config *any_mot, struct bma4_dev *dev) +{ + /* Variable to define error */ + int8_t rslt = BMA4_OK; + + /* Initialize configuration file */ + uint8_t feature_config[BMA456H_FEATURE_SIZE] = { 0 }; + + /* Update index to configure any-motion axes */ + uint8_t index = BMA456H_ANY_MOT_OFFSET; + + /* Variable to define LSB */ + uint16_t lsb = 0; + + /* Variable to define MSB */ + uint16_t msb = 0; + + /* Variable to define LSB and MSB */ + uint16_t lsb_msb = 0; + + if ((dev != NULL) && (any_mot != NULL)) + { + /* Get any-motion configuration from the sensor */ + rslt = bma4_read_regs(BMA4_FEATURE_CONFIG_ADDR, feature_config, BMA456H_ANY_MOT_LEN, dev); + if (rslt == BMA4_OK) + { + /* Get word to calculate threshold and any-motion + * select + */ + lsb = (uint16_t)feature_config[index]; + msb = (uint16_t)((feature_config[index + 1] << 8) & (BMA456H_ANY_NO_MOT_THRES_MSK)); + lsb_msb = lsb | msb; + + /* Get word to calculate intr_bhvr */ + any_mot->intr_bhvr = BMA4_GET_BITSLICE(feature_config[index + 1], BMA456H_ANY_NO_MOTION_INTR_BHVR_EN); + + /* Get word to calculate slope */ + any_mot->slope = BMA4_GET_BITSLICE(feature_config[index + 1], BMA456H_ANY_MOTION_SLOPE_EN); + + /* Extract threshold value */ + any_mot->threshold = lsb_msb & BMA456H_ANY_NO_MOT_THRES_MSK; + + /* Get word to calculate duration */ + lsb = (uint16_t)feature_config[index + 2]; + msb = (uint16_t)((feature_config[index + 3] << 8) & (BMA456H_ANY_NO_MOT_DUR_MSK)); + lsb_msb = lsb | msb; + + /* Extract duration value */ + any_mot->duration = lsb_msb & BMA456H_ANY_NO_MOT_DUR_MSK; + } + } + else + { + rslt = BMA4_E_NULL_PTR; + } + + return rslt; +} + +/*! + * @brief This API sets the configuration of no-motion feature in the sensor. + * This API enables/disables the no-motion feature according to the axis set. + */ +int8_t bma456h_set_no_mot_config(const struct bma456h_any_no_mot_config *no_mot, struct bma4_dev *dev) +{ + /* Variable to define error */ + int8_t rslt = BMA4_OK; + + /* Initialize configuration file */ + uint8_t feature_config[BMA456H_FEATURE_SIZE] = { 0 }; + + /* Update index to configure no-motion axes */ + uint8_t index = BMA456H_NO_MOT_OFFSET; + + if ((dev != NULL) && (no_mot != NULL)) + { + /* Get no-motion configuration from the sensor */ + rslt = bma4_read_regs(BMA4_FEATURE_CONFIG_ADDR, feature_config, BMA456H_NO_MOT_RD_WR_LEN, dev); + if (rslt == BMA4_OK) + { + /* Set threshold value in feature configuration array */ + feature_config[index] = BMA4_GET_LSB(no_mot->threshold); + feature_config[index + 1] = BMA4_GET_MSB(no_mot->threshold); + + feature_config[index + 1] = BMA4_SET_BITSLICE(feature_config[index + 1], + BMA456H_ANY_NO_MOTION_INTR_BHVR_EN, + no_mot->intr_bhvr); + + /* Extract the word where duration and axes enable + * resides + */ + feature_config[index + 2] = BMA4_GET_LSB(no_mot->duration); + feature_config[index + 3] = BMA4_GET_MSB(no_mot->duration); + + /* Set no-motion configuration to the sensor */ + rslt = bma4_write_regs(BMA4_FEATURE_CONFIG_ADDR, feature_config, BMA456H_NO_MOT_RD_WR_LEN, dev); + } + } + else + { + rslt = BMA4_E_NULL_PTR; + } + + return rslt; +} + +/*! + * @brief This API gets the configuration of no-motion feature from the + * sensor. + */ +int8_t bma456h_get_no_mot_config(struct bma456h_any_no_mot_config *no_mot, struct bma4_dev *dev) +{ + /* Variable to define error */ + int8_t rslt = BMA4_OK; + + /* Initialize configuration file */ + uint8_t feature_config[BMA456H_FEATURE_SIZE] = { 0 }; + + /* Update index to configure no-motion axes */ + uint8_t index = BMA456H_NO_MOT_OFFSET; + + /* Variable to define LSB */ + uint16_t lsb = 0; + + /* Variable to define MSB */ + uint16_t msb = 0; + + /* Variable to define LSB and MSB */ + uint16_t lsb_msb = 0; + + if ((dev != NULL) && (no_mot != NULL)) + { + /* Get no-motion configuration from the sensor */ + rslt = bma4_read_regs(BMA4_FEATURE_CONFIG_ADDR, feature_config, BMA456H_NO_MOT_RD_WR_LEN, dev); + if (rslt == BMA4_OK) + { + /* Get word to calculate threshold and no-motion + * select + */ + lsb = (uint16_t)feature_config[index]; + msb = ((uint16_t)feature_config[index + 1] << 8); + lsb_msb = lsb | msb; + + /* Get word to calculate intr_bhvr */ + no_mot->intr_bhvr = BMA4_GET_BITSLICE(feature_config[index + 1], BMA456H_ANY_NO_MOTION_INTR_BHVR_EN); + + /* Extract threshold value */ + no_mot->threshold = lsb_msb & BMA456H_ANY_NO_MOT_THRES_MSK; + + /* Get word to calculate duration and axes enable */ + lsb = (uint16_t)feature_config[index + 2]; + msb = ((uint16_t)feature_config[index + 3] << 8); + lsb_msb = lsb | msb; + + /* Extract duration value */ + no_mot->duration = lsb_msb & BMA456H_ANY_NO_MOT_DUR_MSK; + } + } + else + { + rslt = BMA4_E_NULL_PTR; + } + + return rslt; +} + +/*! + * @brief This API enables or disables the step detector feature in the sensor. + */ +int8_t bma456h_step_detector_enable(uint8_t enable, struct bma4_dev *dev) +{ + uint8_t feature_config[BMA456H_FEATURE_SIZE] = { 0 }; + int8_t rslt = BMA4_OK; + + /* Step detector enable bit position is 1 + * byte ahead of the base address + */ + uint8_t index = BMA456H_STEP_CNTR_OFFSET + 1; + + if (dev != NULL) + { + if (dev->chip_id == BMA456H_CHIP_ID) + { + rslt = bma4_read_regs(BMA4_FEATURE_CONFIG_ADDR, feature_config, BMA456H_FEATURE_SIZE, dev); + if (rslt == BMA4_OK) + { + feature_config[index] = BMA4_SET_BITS_POS_0(feature_config[index], BMA456H_STEP_DETR_EN, enable); + rslt = bma4_write_regs(BMA4_FEATURE_CONFIG_ADDR, feature_config, BMA456H_FEATURE_SIZE, dev); + } + } + else + { + rslt = BMA4_E_INVALID_SENSOR; + } + } + else + { + rslt = BMA4_E_NULL_PTR; + } + + return rslt; +} + +/*! + * @brief This API sets the watermark level for step counter interrupt in the + * sensor. + */ +int8_t bma456h_step_counter_set_watermark(uint16_t step_counter_wm, struct bma4_dev *dev) +{ + uint8_t feature_config[BMA456H_FEATURE_SIZE] = { 0 }; + uint8_t index = BMA456H_STEP_CNTR_OFFSET; + uint16_t wm_lsb = 0; + uint16_t wm_msb = 0; + int8_t rslt = BMA4_OK; + uint16_t data = 0; + + if (dev != NULL) + { + if (dev->chip_id == BMA456H_CHIP_ID) + { + rslt = bma4_read_regs(BMA4_FEATURE_CONFIG_ADDR, feature_config, BMA456H_FEATURE_SIZE, dev); + if (rslt == BMA4_OK) + { + wm_lsb = feature_config[index]; + wm_msb = feature_config[index + 1] << 8; + data = wm_lsb | wm_msb; + + /* Sets only water-mark bits in the complete + * 16 bits of data + */ + data = BMA4_SET_BITS_POS_0(data, BMA456H_STEP_CNTR_WM, step_counter_wm); + + /* Splits 16 bits of data to individual + * 8 bits data + */ + feature_config[index] = BMA4_GET_LSB(data); + feature_config[index + 1] = BMA4_GET_MSB(data); + + /* Writes step counter water-mark settings + * in the sensor + */ + rslt = bma4_write_regs(BMA4_FEATURE_CONFIG_ADDR, feature_config, BMA456H_FEATURE_SIZE, dev); + } + } + else + { + rslt = BMA4_E_INVALID_SENSOR; + } + } + else + { + rslt = BMA4_E_NULL_PTR; + } + + return rslt; +} + +/*! + * @brief This API gets the water mark level set for step counter interrupt + * in the sensor. + */ +int8_t bma456h_step_counter_get_watermark(uint16_t *step_counter_wm, struct bma4_dev *dev) +{ + uint8_t feature_config[BMA456H_FEATURE_SIZE] = { 0 }; + uint8_t index = BMA456H_STEP_CNTR_OFFSET; + uint16_t wm_lsb = 0; + uint16_t wm_msb = 0; + int8_t rslt = BMA4_OK; + uint16_t data = 0; + + if ((dev != NULL) && (step_counter_wm != NULL)) + { + if (dev->chip_id == BMA456H_CHIP_ID) + { + rslt = bma4_read_regs(BMA4_FEATURE_CONFIG_ADDR, feature_config, BMA456H_FEATURE_SIZE, dev); + if (rslt == BMA4_OK) + { + wm_lsb = feature_config[index]; + wm_msb = feature_config[index + 1] << 8; + data = wm_lsb | wm_msb; + *step_counter_wm = BMA4_GET_BITS_POS_0(data, BMA456H_STEP_CNTR_WM); + } + } + else + { + rslt = BMA4_E_INVALID_SENSOR; + } + } + else + { + rslt = BMA4_E_NULL_PTR; + } + + return rslt; +} + +/*! + * @brief This API resets the counted steps of step counter. + */ +int8_t bma456h_reset_step_counter(struct bma4_dev *dev) +{ + uint8_t feature_config[BMA456H_FEATURE_SIZE] = { 0 }; + + /* Reset bit is 1 byte ahead of base address */ + uint8_t index = BMA456H_STEP_CNTR_OFFSET + 1; + int8_t rslt = BMA4_OK; + + if (dev != NULL) + { + if (dev->chip_id == BMA456H_CHIP_ID) + { + rslt = bma4_read_regs(BMA4_FEATURE_CONFIG_ADDR, feature_config, BMA456H_FEATURE_SIZE, dev); + if (rslt == BMA4_OK) + { + feature_config[index] = BMA4_SET_BITSLICE(feature_config[index], BMA456H_STEP_CNTR_RST, 1); + rslt = bma4_write_regs(BMA4_FEATURE_CONFIG_ADDR, feature_config, BMA456H_FEATURE_SIZE, dev); + } + } + else + { + rslt = BMA4_E_INVALID_SENSOR; + } + } + else + { + rslt = BMA4_E_NULL_PTR; + } + + return rslt; +} + +/*! + * @brief This API gets the number of counted steps of the step counter + * feature from the sensor. + */ +int8_t bma456h_step_counter_output(uint32_t *step_count, struct bma4_dev *dev) +{ + uint8_t data[BMA456H_STEP_CNTR_DATA_SIZE] = { 0 }; + int8_t rslt = BMA4_OK; + + if ((dev != NULL) && (step_count != NULL)) + { + if (dev->chip_id == BMA456H_CHIP_ID) + { + /* Reads the step counter output data from the + * gpio register + */ + rslt = bma4_read_regs(BMA4_STEP_CNT_OUT_0_ADDR, data, BMA456H_STEP_CNTR_DATA_SIZE, dev); + if (rslt == BMA4_OK) + { + *step_count = ((uint32_t)data[0]) | ((uint32_t)data[1] << 8) | ((uint32_t)data[2] << 16) | + ((uint32_t)data[3] << 24); + } + } + else + { + rslt = BMA4_E_INVALID_SENSOR; + } + } + else + { + rslt = BMA4_E_NULL_PTR; + } + + return rslt; +} + +/*! + * @brief This API gets the output for activity feature. + */ +int8_t bma456h_output_state(struct bma456h_out_state *out_state, struct bma4_dev *dev) +{ + uint8_t data = 0; + int8_t rslt = BMA4_OK; + + if ((dev != NULL) && (out_state != NULL)) + { + if (dev->chip_id == BMA456H_CHIP_ID) + { + /* Reads the activity output from the gpio register */ + rslt = bma4_read_regs(BMA456H_FEAT_OUT_ADDR, &data, 1, dev); + if (rslt == BMA4_OK) + { + out_state->activity_type = BMA4_GET_BITS_POS_0(data, BMA456H_ACTIVITY_OUT); + out_state->single_tap = BMA4_GET_BITSLICE(data, BMA456H_SINGLE_TAP_OUT); + out_state->double_tap = BMA4_GET_BITSLICE(data, BMA456H_DOUBLE_TAP_OUT); + out_state->triple_tap = BMA4_GET_BITSLICE(data, BMA456H_TRIPLE_TAP_OUT); + } + } + else + { + rslt = BMA4_E_INVALID_SENSOR; + } + } + else + { + rslt = BMA4_E_NULL_PTR; + } + + return rslt; +} + +/*! + * @brief This API gets the parameter1 to parameter7 settings of the step + * counter feature. + */ +int8_t bma456h_stepcounter_get_parameter(struct bma456h_stepcounter_settings *setting, struct bma4_dev *dev) +{ + uint8_t feature_config[BMA456H_FEATURE_SIZE] = { 0 }; + uint16_t *data_p = (uint16_t *)(void *)feature_config; + int8_t rslt = BMA4_OK; + + if ((dev != NULL) && (setting != NULL)) + { + if (dev->chip_id == BMA456H_CHIP_ID) + { + rslt = bma4_read_regs(BMA4_FEATURE_CONFIG_ADDR, feature_config, BMA456H_FEATURE_SIZE, dev); + if (rslt == BMA4_OK) + { + /* To convert 8bit to 16 bit address */ + data_p = data_p + BMA456H_STEP_CNTR_PARAM_OFFSET / 2; + extract_stepcounter_parameter(setting, data_p); + } + } + else + { + rslt = BMA4_E_INVALID_SENSOR; + } + } + else + { + rslt = BMA4_E_NULL_PTR; + } + + return rslt; +} + +/*! + * @brief This API sets the parameter1 to parameter7 settings of the step + * counter feature in the sensor. + */ +int8_t bma456h_stepcounter_set_parameter(const struct bma456h_stepcounter_settings *setting, struct bma4_dev *dev) +{ + uint8_t feature_config[BMA456H_FEATURE_SIZE] = { 0 }; + uint8_t index = BMA456H_STEP_CNTR_PARAM_OFFSET; + int8_t rslt = BMA4_OK; + + if ((dev != NULL) && (setting != NULL)) + { + if (dev->chip_id == BMA456H_CHIP_ID) + { + rslt = bma4_read_regs(BMA4_FEATURE_CONFIG_ADDR, feature_config, BMA456H_FEATURE_SIZE, dev); + if (rslt == BMA4_OK) + { + update_stepcounter_parameter(setting, index, feature_config); + + /* Writes step counter parameter settings + * in the sensor + */ + rslt = bma4_write_regs(BMA4_FEATURE_CONFIG_ADDR, feature_config, BMA456H_FEATURE_SIZE, dev); + } + } + else + { + rslt = BMA4_E_INVALID_SENSOR; + } + } + else + { + rslt = BMA4_E_NULL_PTR; + } + + return rslt; +} + +/*! @cond DOXYGEN_SUPRESS */ + +/* Suppressing doxygen warnings triggered for same static function names present across various sensor variant + * directories */ + +/*! + * @brief This API enables the features of the sensor. + */ +static int8_t feature_enable(uint16_t feature, uint8_t *feature_config, struct bma4_dev *dev) +{ + uint8_t index = 0; + int8_t rslt = BMA4_OK; + + if ((dev != NULL) && (feature_config != NULL)) + { + feature_config[index] |= BMA4_GET_LSB(feature); + feature_config[index + 1] |= BMA4_GET_MSB(feature); + + /* Write the feature enable settings in the sensor */ + rslt = bma4_write_regs(BMA456H_FEAT_EN_ADDR1, &feature_config[0], 1, dev); + + if (rslt == BMA4_OK) + { + /* Delay required for write register */ + dev->delay_us(450, dev->intf_ptr); + rslt = bma4_write_regs(BMA456H_FEAT_EN_ADDR2, &feature_config[1], 1, dev); + } + } + + return rslt; +} + +/*! + * @brief This API disables the features of the sensor. + */ +static int8_t feature_disable(uint16_t feature, uint8_t *feature_config, struct bma4_dev *dev) +{ + uint8_t index = 0; + int8_t rslt = BMA4_OK; + + if ((dev != NULL) && (feature_config != NULL)) + { + feature = ~feature; + feature_config[index] &= BMA4_GET_LSB(feature); + feature_config[index + 1] &= BMA4_GET_MSB(feature); + + /* Write the configured settings in the sensor */ + rslt = bma4_write_regs(BMA456H_FEAT_EN_ADDR1, &feature_config[0], 1, dev); + + if (rslt == BMA4_OK) + { + /* Delay required for write register */ + dev->delay_us(450, dev->intf_ptr); + rslt = bma4_write_regs(BMA456H_FEAT_EN_ADDR2, &feature_config[1], 1, dev); + } + } + + return rslt; +} + +/*! + * @brief This API update the settings of step counter. + */ +static void update_stepcounter_parameter(const struct bma456h_stepcounter_settings *setting, + uint8_t index, + uint8_t *feature_config) +{ + uint8_t param_num; + const uint16_t *step_counter_param = &setting->param1; + + /* Number of step-counter parameter is 25 */ + for (param_num = 1; param_num <= 25; param_num++) + { + feature_config[index++] = BMA4_GET_LSB(*step_counter_param); + feature_config[index++] = BMA4_GET_MSB(*step_counter_param); + step_counter_param++; + } +} + +/*! + * @brief This API copy the settings of step counter into the structure of + * bma456h_stepcounter_settings, which is read from sensor. + */ +static void extract_stepcounter_parameter(struct bma456h_stepcounter_settings *setting, const uint16_t *data_p) +{ + uint8_t param_num; + uint16_t *step_counter_param = &setting->param1; + + /* Number of step-counter parameter is 25 */ + for (param_num = 1; param_num <= 25; param_num++) + { + *step_counter_param = *(data_p++); + step_counter_param++; + } +} + +/*! @endcond */ + +/*! + * @brief This API gets the parameter1 to parameter12 settings of the + * tap feature. + */ +int8_t bma456h_tap_get_parameter(struct bma456h_multitap_settings *setting, struct bma4_dev *dev) +{ + uint8_t feature_config[BMA456H_FEATURE_SIZE] = { 0 }; + uint16_t *data_p = (uint16_t *)(void *)feature_config; + int8_t rslt = BMA4_OK; + + if ((dev != NULL) && (setting != NULL)) + { + if (dev->chip_id == BMA456H_CHIP_ID) + { + rslt = bma4_read_regs(BMA4_FEATURE_CONFIG_ADDR, feature_config, BMA456H_FEATURE_SIZE, dev); + if (rslt == BMA4_OK) + { + /* To convert 8bit to 16 bit address */ + data_p = data_p + BMA456H_TAP_PARAM_OFFSET / 2; + extract_tap_parameter(setting, data_p); + } + } + else + { + rslt = BMA4_E_INVALID_SENSOR; + } + } + else + { + rslt = BMA4_E_NULL_PTR; + } + + return rslt; +} + +/*! + * @brief This API sets the parameter1 to parameter12 settings of the + * tap feature in the sensor. + */ +int8_t bma456h_tap_set_parameter(const struct bma456h_multitap_settings *setting, struct bma4_dev *dev) +{ + uint8_t feature_config[BMA456H_FEATURE_SIZE] = { 0 }; + uint8_t index = BMA456H_TAP_PARAM_OFFSET; + int8_t rslt = BMA4_OK; + + if ((dev != NULL) && (setting != NULL)) + { + if (dev->chip_id == BMA456H_CHIP_ID) + { + rslt = bma4_read_regs(BMA4_FEATURE_CONFIG_ADDR, feature_config, BMA456H_FEATURE_SIZE, dev); + if (rslt == BMA4_OK) + { + update_tap_parameter(setting, index, feature_config); + + /* Writes tap parameter settings + * in the sensor + */ + rslt = bma4_write_regs(BMA4_FEATURE_CONFIG_ADDR, feature_config, BMA456H_FEATURE_SIZE, dev); + } + } + else + { + rslt = BMA4_E_INVALID_SENSOR; + } + } + else + { + rslt = BMA4_E_NULL_PTR; + } + + return rslt; +} + +/*! @cond DOXYGEN_SUPRESS */ + +/* Suppressing doxygen warnings triggered for same static function names present across various sensor variant + * directories */ + +/*! + * @brief This API update the settings of tap. + */ +static void update_tap_parameter(const struct bma456h_multitap_settings *setting, uint8_t index, + uint8_t *feature_config) +{ + uint8_t param_num; + uint8_t max_tap_param = 12; + const uint16_t *tap_param = &setting->reserved_1; + + /* Number of tap detection parameter is 12 */ + for (param_num = 1; param_num <= max_tap_param; param_num++) + { + feature_config[index++] = BMA4_GET_LSB(*tap_param); + feature_config[index++] = BMA4_GET_MSB(*tap_param); + tap_param++; + } +} + +/*! + * @brief This API copy the settings of tap into the structure of + * bma456h_multitap_settings, which is read from sensor. + */ +static void extract_tap_parameter(struct bma456h_multitap_settings *setting, const uint16_t *data_p) +{ + uint8_t param_num; + uint8_t max_tap_param = 12; + uint16_t *tap_param = &setting->reserved_1; + + /* Number of tap detection parameter is 12 */ + for (param_num = 1; param_num <= max_tap_param; param_num++) + { + *tap_param = *(data_p++); + tap_param++; + } +} + +/*! @endcond */ + +/*! + * @brief This API gets auto sleep configurations + */ +int8_t bma456h_get_auto_low_power_config(struct bma456h_auto_low_power *auto_low_power, struct bma4_dev *dev) +{ + uint8_t feature_config[BMA456H_FEATURE_SIZE] = { 0 }; + int8_t rslt = BMA4_OK; + uint16_t msb_lsb; + + if ((dev != NULL) && (auto_low_power != NULL)) + { + if (dev->chip_id == BMA456H_CHIP_ID) + { + rslt = bma4_read_regs(BMA4_FEATURE_CONFIG_ADDR, feature_config, BMA456H_FEATURE_SIZE, dev); + if (rslt == BMA4_OK) + { + + auto_low_power->no_motion = BMA4_GET_BITS_POS_0(feature_config[BMA456H_AUTO_LOW_POWER_OFFSET], + BMA456H_NO_MOT_AUTO_LOW_POWER); + auto_low_power->time_out = BMA4_GET_BITSLICE(feature_config[BMA456H_AUTO_LOW_POWER_OFFSET], + BMA456H_AUTO_LOW_POWER_TIME_OUT); + + msb_lsb = + (uint16_t)(feature_config[BMA456H_AUTO_LOW_POWER_OFFSET] | + (uint16_t)(feature_config[BMA456H_AUTO_LOW_POWER_OFFSET + 1] << 8)); + auto_low_power->time_out_dur = BMA4_GET_BITSLICE(msb_lsb, BMA456H_TIME_OUT_DUR); + + auto_low_power->lp_odr = BMA4_GET_BITSLICE(feature_config[BMA456H_AUTO_LOW_POWER_OFFSET + 1], + BMA456H_LOW_POW_ODR); + auto_low_power->pwr_mgt = BMA4_GET_BITSLICE(feature_config[BMA456H_AUTO_LOW_POWER_OFFSET + 1], + BMA456H_PWR_MGT_ENABLE); + } + } + else + { + rslt = BMA4_E_INVALID_SENSOR; + } + } + else + { + rslt = BMA4_E_NULL_PTR; + } + + return rslt; +} + +/*! + * @brief This API gets power mode management configuration. + */ +int8_t bma456h_set_auto_low_power_config(const struct bma456h_auto_low_power *auto_low_power, struct bma4_dev *dev) +{ + uint8_t feature_config[BMA456H_FEATURE_SIZE] = { 0 }; + uint8_t index = BMA456H_AUTO_LOW_POWER_OFFSET; + int8_t rslt = BMA4_OK; + uint16_t msb_lsb; + + if ((dev != NULL) && (auto_low_power != NULL)) + { + if (dev->chip_id == BMA456H_CHIP_ID) + { + rslt = bma4_read_regs(BMA4_FEATURE_CONFIG_ADDR, feature_config, BMA456H_FEATURE_SIZE, dev); + if (rslt == BMA4_OK) + { + + msb_lsb = (uint16_t)((feature_config[index]) | (uint16_t)(feature_config[index + 1] << 8)); + + msb_lsb = BMA4_SET_BITS_POS_0(msb_lsb, BMA456H_NO_MOT_AUTO_LOW_POWER_WORD, auto_low_power->no_motion); + msb_lsb = BMA4_SET_BITSLICE(msb_lsb, BMA456H_AUTO_LOW_POWER_TIME_OUT_WORD, auto_low_power->time_out); + + msb_lsb = BMA4_SET_BITSLICE(msb_lsb, BMA456H_TIME_OUT_DUR_WORD, auto_low_power->time_out_dur); + + msb_lsb = BMA4_SET_BITSLICE(msb_lsb, BMA456H_LOW_POW_ODR_WORD, auto_low_power->lp_odr); + msb_lsb = BMA4_SET_BITSLICE(msb_lsb, BMA456H_PWR_MGT_ENABLE_WORD, auto_low_power->pwr_mgt); + + feature_config[index] = BMA4_GET_LSB(msb_lsb); + feature_config[index + 1] = BMA4_GET_MSB(msb_lsb); + + rslt = bma4_write_regs(BMA4_FEATURE_CONFIG_ADDR, feature_config, BMA456H_FEATURE_SIZE, dev); + } + } + else + { + rslt = BMA4_E_INVALID_SENSOR; + } + } + else + { + rslt = BMA4_E_NULL_PTR; + } + + return rslt; +} + +/*! + * @brief This api reads the auto low power state output status + */ +int8_t bma456h_get_auto_low_power_state(uint8_t *auto_low_power_state, struct bma4_dev *dev) +{ + int8_t rslt = BMA4_OK; + uint8_t data; + + if ((dev != NULL) && (auto_low_power_state != NULL)) + { + rslt = bma4_read_regs(BMA4_INTERNAL_STAT, &data, 1, dev); + *auto_low_power_state = BMA4_GET_BITSLICE(data, BMA456H_AUTO_LOW_POWER_STATE); + } + else + { + rslt = BMA4_E_NULL_PTR; + } + + return rslt; +} + +/*! + * @brief This API is used to get the config file major and minor information. + */ +int8_t bma456h_get_version_config(uint16_t *config_major, uint16_t *config_minor, struct bma4_dev *dev) +{ + /* Initialize configuration file */ + uint8_t feature_config[BMA456H_FEATURE_SIZE] = { 0 }; + + /* Update index to config file version */ + uint8_t index = BMA456H_CONFIG_ID_START_ADDR; + + /* Variable to define LSB */ + uint8_t lsb = 0; + + /* Variable to define MSB */ + uint8_t msb = 0; + + /* Variable to define LSB and MSB */ + uint16_t lsb_msb = 0; + + /* Result of api are returned to this variable */ + int8_t rslt = BMA4_OK; + + if ((config_major != NULL) && (config_minor != NULL)) + { + rslt = bma4_set_advance_power_save(BMA4_DISABLE, dev); + + /* Wait for sensor time synchronization. Refer the data-sheet for + * more information + */ + dev->delay_us(450, dev->intf_ptr); + + if (rslt == BMA4_OK) + { + /* Get config file identification from the sensor */ + rslt = bma4_read_regs(BMA4_FEATURE_CONFIG_ADDR, feature_config, BMA456H_FEATURE_SIZE, dev); + + if (rslt == BMA4_OK) + { + /* Get word to calculate config file identification */ + lsb = feature_config[index++]; + msb = feature_config[index++]; + + lsb_msb = (uint16_t)(msb << 8 | lsb); + + /* Get major and minor version */ + *config_major = BMA4_GET_BITSLICE(lsb_msb, BMA4_CONFIG_MAJOR); + *config_minor = BMA4_GET_BITS_POS_0(lsb, BMA4_CONFIG_MINOR); + } + } + } + else + { + rslt = BMA4_E_NULL_PTR; + } + + return rslt; +} + +/*! @endcond */ diff --git a/components/bma456/bma456h.h b/components/bma456/bma456h.h new file mode 100644 index 0000000..9f472fe --- /dev/null +++ b/components/bma456/bma456h.h @@ -0,0 +1,1322 @@ +/** +* 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. +* +* @file bma456h.h +* @date 2023-07-05 +* @version V2.29.0 +* +*/ + +/** + * \ingroup bma4xy + * \defgroup bma456h BMA456H + * @brief Sensor driver for BMA456H sensor + */ + +#ifndef BMA456H_H +#define BMA456H_H + +#ifdef __cplusplus +extern "C" { +#endif +#include "bma4.h" + +/**\name Chip ID of BMA456H sensor */ +#define BMA456H_CHIP_ID UINT8_C(0x16) + +/**\ Configuration ID start position of BMA456H sensor */ +#define BMA456H_CONFIG_ID_START_ADDR UINT8_C(90) + +/**\name Sensor feature size */ +#define BMA456H_FEATURE_SIZE UINT8_C(94) +#define BMA456H_FEATURE_SIZE_WORDS UINT8_C(46) +#define BMA456H_ANY_MOT_LEN UINT8_C(4) + +/**************************************************************/ +/**\name Feature input offset: Features enable position */ +/**************************************************************/ +#define BMA456H_ANY_MOT_OFFSET UINT8_C(0x00) +#define BMA456H_NO_MOT_OFFSET UINT8_C(0x04) +#define BMA456H_STEP_CNTR_PARAM_OFFSET UINT8_C(0x08) +#define BMA456H_STEP_CNTR_OFFSET UINT8_C(0x3A) +#define BMA456H_TAP_PARAM_OFFSET UINT8_C(0x3C) +#define BMA456H_AUTO_LOW_POWER_OFFSET UINT8_C(0x58) +#define BMA456H_AUTO_LOW_POWER_OFFSET_WORDS UINT8_C(0x2C) + +/**\name Read/Write Lengths */ +#define BMA456H_RD_WR_MIN_LEN UINT8_C(2) +#define BMA456H_NO_MOT_RD_WR_LEN (BMA456H_ANY_MOT_LEN + BMA456H_NO_MOT_OFFSET) + +/*! @name Maximum valid read write length is size of config file array */ +#define BMA456H_RD_WR_MAX_LEN ((uint16_t)sizeof(bma456h_config_file)) + +/**************************************************************/ +/**\name General settings: Re-map Axes */ +/**************************************************************/ +#define BMA456H_CONFIG_ID_OFFSET UINT8_C(0x5A) +#define BMA456H_AXES_REMAP_OFFSET UINT8_C(0x5C) +#define BMA456H_X_AXIS_MASK UINT8_C(0x03) +#define BMA456H_X_AXIS_SIGN_MASK UINT8_C(0x04) +#define BMA456H_Y_AXIS_MASK UINT8_C(0x18) +#define BMA456H_Y_AXIS_SIGN_MASK UINT8_C(0x20) +#define BMA456H_Z_AXIS_MASK UINT8_C(0xC0) +#define BMA456H_Z_AXIS_SIGN_MASK UINT8_C(0x01) + +/**************************************************************/ +/**\name Output: Features enable position */ +/**************************************************************/ +#define BMA456H_NO_MOT_X_EN_POS UINT8_C(0) +#define BMA456H_NO_MOT_Y_EN_POS UINT8_C(1) +#define BMA456H_NO_MOT_Z_EN_POS UINT8_C(2) +#define BMA456H_ANY_MOT_X_EN_POS UINT8_C(3) +#define BMA456H_ANY_MOT_Y_EN_POS UINT8_C(4) +#define BMA456H_ANY_MOT_Z_EN_POS UINT8_C(5) + +#define BMA456H_STEP_DETR_EN_POS UINT8_C(0) +#define BMA456H_STEP_CNTR_EN_POS UINT8_C(1) +#define BMA456H_STEP_ACT_EN_POS UINT8_C(2) +#define BMA456H_AUTO_LOW_POWER_EN_POS UINT8_C(3) +#define BMA456H_SIN_TAP_EN_POS UINT8_C(4) +#define BMA456H_DBL_TAP_EN_POS UINT8_C(5) +#define BMA456H_TPL_TAP_EN_POS UINT8_C(6) +#define BMA456H_TAP_AVERAGE_EN_POS UINT8_C(7) + +/**************************************************************/ +/**\name Output: Features enable mask */ +/**************************************************************/ +#define BMA456H_NO_MOT_X_EN_MSK UINT8_C(0x01) +#define BMA456H_NO_MOT_Y_EN_MSK UINT8_C(0x02) +#define BMA456H_NO_MOT_Z_EN_MSK UINT8_C(0x04) +#define BMA456H_NO_MOT_ALL_EN_MSK UINT8_C(0x07) +#define BMA456H_NO_MOT_ALL_DIS_MSK UINT8_C(0x00) +#define BMA456H_ANY_MOT_X_EN_MSK UINT8_C(0x08) +#define BMA456H_ANY_MOT_Y_EN_MSK UINT8_C(0x10) +#define BMA456H_ANY_MOT_Z_EN_MSK UINT8_C(0x20) +#define BMA456H_ANY_MOT_ALL_EN_MSK UINT8_C(0x38) +#define BMA456H_ANY_MOT_ALL_DIS_MSK UINT8_C(0x00) + +#define BMA456H_STEP_DETR_EN_MSK UINT8_C(0x01) +#define BMA456H_STEP_CNTR_EN_MSK UINT8_C(0x02) +#define BMA456H_STEP_ACT_EN_MSK UINT8_C(0x04) +#define BMA456H_AUTO_LOW_POWER_EN_MSK UINT8_C(0x08) +#define BMA456H_SINGLE_TAP_EN_MSK UINT8_C(0x10) +#define BMA456H_DOUBLE_TAP_EN_MSK UINT8_C(0x20) +#define BMA456H_TRIPLE_TAP_EN_MSK UINT8_C(0x40) +#define BMA456H_TAP_AVERAGE_EN_MSK UINT8_C(0x80) + +/**\name Step counter water-mark macros */ +#define BMA456H_STEP_CNTR_WM_MSK UINT16_C(0x03FF) + +/**\name Step counter reset macros */ +#define BMA456H_STEP_CNTR_RST_POS UINT8_C(2) +#define BMA456H_STEP_CNTR_RST_MSK UINT8_C(0x04) + +/**\name Step counter output length */ +#define BMA456H_STEP_CNTR_DATA_SIZE UINT16_C(4) + +/**\name Step activity output macros */ +#define BMA456H_ACTIVITY_OUT_MSK UINT8_C(0x03) +#define BMA456H_ACTIVITY_OUT_POS UINT8_C(0x00) + +/**\name Tap output macros */ +#define BMA456H_SINGLE_TAP_OUT_MSK UINT8_C(0x04) +#define BMA456H_SINGLE_TAP_OUT_POS UINT8_C(0x02) + +#define BMA456H_DOUBLE_TAP_OUT_MSK UINT8_C(0x08) +#define BMA456H_DOUBLE_TAP_OUT_POS UINT8_C(0x03) + +#define BMA456H_TRIPLE_TAP_OUT_MSK UINT8_C(0x10) +#define BMA456H_TRIPLE_TAP_OUT_POS UINT8_C(0x04) + +#define BMA456H_TAP_OUT_MSK UINT8_C(0x1C) +#define BMA456H_TAP_OUT_POS UINT8_C(0x02) + +/**************************************************************/ +/**\name Any/no Motion */ +/**************************************************************/ +/**\name Any/No motion threshold macros */ +#define BMA456H_ANY_NO_MOT_THRES_MSK UINT16_C(0x07FF) + +/**\name Any/No motion duration macros */ +#define BMA456H_ANY_NO_MOT_DUR_MSK UINT16_C(0x1FFF) + +/**\name Any/No motion enable macros */ +#define BMA456H_ANY_NO_MOT_AXIS_EN_POS UINT8_C(0x03) +#define BMA456H_ANY_NO_MOT_AXIS_EN_MSK UINT16_C(0x78) + +#define BMA456H_NO_MOT_AUTO_LOW_POWER_MSK UINT8_C(0x01) + +#define BMA456H_AUTO_LOW_POWER_TIME_OUT_MSK UINT8_C(0x02) +#define BMA456H_AUTO_LOW_POWER_TIME_OUT_POS UINT8_C(0x1) +#define BMA456H_TIME_OUT_DUR_MSK UINT16_C(0x1FFC) +#define BMA456H_TIME_OUT_DUR_POS UINT16_C(0x02) +#define BMA456H_LOW_POW_ODR_MSK UINT8_C(0x60) +#define BMA456H_LOW_POW_ODR_POS UINT8_C(0x05) +#define BMA456H_PWR_MGT_ENABLE_MSK UINT8_C(0x80) +#define BMA456H_PWR_MGT_ENABLE_POS UINT8_C(0x07) +#define BMA456H_TIME_OUT_DUR_LSB_MSK UINT16_C(0X00FC) +#define BMA456H_TIME_OUT_DUR_LSB_POS UINT8_C(0x02) +#define BMA456H_TIME_OUT_DUR_MSB_MSK UINT16_C(0X07C0) +#define BMA456H_TIME_OUT_DUR_MSB_POS UINT8_C(0X06) + +#define BMA456H_NO_MOT_AUTO_LOW_POWER_WORD_MSK UINT16_C(0x01) + +#define BMA456H_AUTO_LOW_POWER_TIME_OUT_WORD_MSK UINT16_C(0x02) +#define BMA456H_AUTO_LOW_POWER_TIME_OUT_WORD_POS UINT8_C(0x1) + +#define BMA456H_TIME_OUT_DUR_WORD_MSK UINT16_C(0X1FFC) +#define BMA456H_TIME_OUT_DUR_WORD_POS UINT8_C(0x02) + +#define BMA456H_LOW_POW_ODR_WORD_MSK UINT16_C(0x6000) +#define BMA456H_LOW_POW_ODR_WORD_POS UINT8_C(0x0D) + +#define BMA456H_PWR_MGT_ENABLE_WORD_MSK UINT16_C(0x8000) +#define BMA456H_PWR_MGT_ENABLE_WORD_POS UINT8_C(0x0F) + +/**************************************************************/ +/**\name User macros */ +/**************************************************************/ +/**************************************************************/ +/**\name Output: Features for enable/disable */ +/**************************************************************/ +#define BMA456H_NO_MOTION_X_AXIS_EN UINT16_C(0x0001) +#define BMA456H_NO_MOTION_Y_AXIS_EN UINT16_C(0x0002) +#define BMA456H_NO_MOTION_Z_AXIS_EN UINT16_C(0x0004) +#define BMA456H_NO_MOTION_ALL_AXIS_EN UINT16_C(0x0007) +#define BMA456H_ANY_MOTION_X_AXIS_EN UINT16_C(0x0008) +#define BMA456H_ANY_MOTION_Y_AXIS_EN UINT16_C(0x0010) +#define BMA456H_ANY_MOTION_Z_AXIS_EN UINT16_C(0x0020) +#define BMA456H_ANY_MOTION_ALL_AXIS_EN UINT16_C(0x0038) + +#define BMA456H_STEP_DETECTOR_EN UINT16_C(0x0100) +#define BMA456H_STEP_COUNTER_EN UINT16_C(0x0200) +#define BMA456H_STEP_ACTIVITY_EN UINT16_C(0x0400) +#define BMA456H_AUTO_LOW_POWER_EN UINT16_C(0x0800) +#define BMA456H_SINGLE_TAP_EN UINT16_C(0x1000) +#define BMA456H_DOUBLE_TAP_EN UINT16_C(0x2000) +#define BMA456H_TRIPLE_TAP_EN UINT16_C(0x4000) +#define BMA456H_TAP_AVERAGE_EN UINT16_C(0x8000) + +/**\name Interrupt status macros */ +#define BMA456H_TAP_OUT_INT UINT8_C(0x01) +#define BMA456H_STEP_CNTR_INT UINT8_C(0x02) +#define BMA456H_ACTIVITY_INT UINT8_C(0x04) +#define BMA456H_ANY_MOT_INT UINT8_C(0x10) +#define BMA456H_NO_MOT_INT UINT8_C(0x20) +#define BMA456H_ERROR_INT UINT8_C(0x80) + +/**\name Activity recognition macros */ +#define BMA456H_USER_STATIONARY UINT8_C(0x00) +#define BMA456H_USER_WALKING UINT8_C(0x01) +#define BMA456H_USER_RUNNING UINT8_C(0x02) +#define BMA456H_UNKNOWN_ACTVTY UINT8_C(0x03) + +/**\name Address of features enable macros */ +#define BMA456H_FEAT_EN_ADDR1 UINT8_C(0x28) +#define BMA456H_FEAT_EN_ADDR2 UINT8_C(0x29) + +#define BMA456H_FEAT_OUT_ADDR UINT8_C(0x27) +#define BMA456H_FEAT_EN_SIZE UINT8_C(0x02) + +/**\name Position and mask of interrupt behavior and slope */ +#define BMA456H_ANY_NO_MOTION_INTR_BHVR_EN_POS UINT8_C(0x03) +#define BMA456H_ANY_NO_MOTION_INTR_BHVR_EN_MSK UINT8_C(0x08) + +#define BMA456H_ANY_MOTION_SLOPE_EN_POS UINT8_C(0x04) +#define BMA456H_ANY_MOTION_SLOPE_EN_MSK UINT8_C(0x10) + +#define BMA456H_MULTI_INTR UINT8_C(0x00) +#define BMA456H_SINGLE_SHOT UINT8_C(0x01) + +#define BMA456H_NON_CONSECUTIVE UINT8_C(0x00) +#define BMA456H_CONSECUTIVE UINT8_C(0x01) + +#define BMA456H_AUTO_LOW_POWER_STATE_POS UINT8_C(0x04) +#define BMA456H_AUTO_LOW_POWER_STATE_MSK UINT8_C(0x10) + +/******************************************************************************/ +/*! @name Structure Declarations */ +/******************************************************************************/ + +/*! + * @brief Any/No motion configuration + */ +struct bma456h_any_no_mot_config +{ + /*! Expressed in 50 Hz samples (20 ms) */ + uint16_t duration; + + /*! Threshold value for Any-motion/No-motion detection in + * 5.11g format + */ + uint16_t threshold; + + uint8_t intr_bhvr; + + uint8_t slope; +}; + +/*! + * @brief Step counter param settings + */ +struct bma456h_stepcounter_settings +{ + /*! Step Counter param 1 */ + uint16_t param1; + + /*! Step Counter param 2 */ + uint16_t param2; + + /*! Step Counter param 3 */ + uint16_t param3; + + /*! Step Counter param 4 */ + uint16_t param4; + + /*! Step Counter param 5 */ + uint16_t param5; + + /*! Step Counter param 6 */ + uint16_t param6; + + /*! Step Counter param 7 */ + uint16_t param7; + + /*! Step Counter param 8 */ + uint16_t param8; + + /*! Step Counter param 9 */ + uint16_t param9; + + /*! Step Counter param 10 */ + uint16_t param10; + + /*! Step Counter param 11 */ + uint16_t param11; + + /*! Step Counter param 12 */ + uint16_t param12; + + /*! Step Counter param 13 */ + uint16_t param13; + + /*! Step Counter param 14 */ + uint16_t param14; + + /*! Step Counter param 15 */ + uint16_t param15; + + /*! Step Counter param 16 */ + uint16_t param16; + + /*! Step Counter param 17 */ + uint16_t param17; + + /*! Step Counter param 18 */ + uint16_t param18; + + /*! Step Counter param 19 */ + uint16_t param19; + + /*! Step Counter param 20 */ + uint16_t param20; + + /*! Step Counter param 21 */ + uint16_t param21; + + /*! Step Counter param 22 */ + uint16_t param22; + + /*! Step Counter param 23 */ + uint16_t param23; + + /*! Step Counter param 24 */ + uint16_t param24; + + /*! Step Counter param 25 */ + uint16_t param25; +}; + +/*! + * @brief Auto sleep configuration + */ +struct bma456h_auto_low_power +{ + /*! Enters auto-sleep, when no-motion is detected */ + uint8_t no_motion; + + /*! Enters auto-sleep, when any-motion is not detected for time_out_dur period */ + uint8_t time_out; + + /*! Duration to enter to auto sleep, when any-motion event is not detected. + * Range : 0 ms to 40690 ms + * Resolution : 20 ms + * Default Value : 2000 ms + */ + uint16_t time_out_dur; + + /*! ODR for low power mode + * --------------------------------------- + * Value Name Description + * --------------------------------------- + * 0 odr_1p5 25/16 Hz + * 1 odr_3p1 25/8 Hz + * 2 odr_6p25 25/4 Hz + * 3 odr_12p5 25/2 Hz + */ + uint8_t lp_odr; + + /*! Power management + * -------------------------------------------- + * Value Name Description + * -------------------------------------------- + * 0 Disable Disable feature optimized + * acc conf. Uses host desired + * configuration + * 1 Enable Enable feature optimized + * acc conf + */ + uint8_t pwr_mgt; +}; + +/*! + * @brief Tap param settings + */ +struct bma456h_multitap_settings +{ + /*! Reserved parameter */ + uint16_t reserved_1; + + /*! Scaling factor for threshold */ + uint16_t tap_sens_thres; + + /*! Maximum duration after the first tap */ + uint16_t max_gest_dur; + + /*! Reserved parameter */ + uint16_t reserved_4; + + /*! Settling time for high frequency acceleration signal */ + uint16_t tap_shock_dur; + + /*! Reserved parameter */ + uint16_t reserved_6; + + /*! Minimum quite time between the two gesture detection */ + uint16_t quite_time_after_gest; + + /*! Wait for the duration set by max_gest_dur after the first tap */ + uint16_t wait_for_timeout; + + /*! Reserved parameter */ + uint16_t reserved_9; + + /*! Selection of axis from 3D-acceleration signal vector */ + uint16_t axis_sel; + + /*! Reserved parameter */ + uint16_t reserved_11; + + /*! Reserved parameter */ + uint16_t reserved_12; +}; + +/*! + * @brief activity, tap output state + */ +struct bma456h_out_state +{ + /*! Output value of activity detection feature. Value after device + * initialization is 0b0 i.e User Stationary + * ---------------------------------------------------------------- + * Value Name Description + * ---------------------------------------------------------------- + * 0 Still User Stationary + * 1 Walking User walking + * 2 Running User running + * 3 Unknown Unknown state + */ + uint8_t activity_type; + + /*! Single tap detected */ + uint8_t single_tap; + + /*! Double tap detected */ + uint8_t double_tap; + + /*! Triple tap detected */ + uint8_t triple_tap; +}; + +/***************************************************************************/ + +/*! BMA456H User Interface function prototypes + ****************************************************************************/ + +/** + * \ingroup bma456h + * \defgroup bma456hApiInit Initialization + * @brief Initialize the sensor and device structure + */ + +/*! + * \ingroup bma456hApiInit + * \page bma456h_api_bma456h_init bma456h_init + * \code + * int8_t bma456h_init(struct bma4_dev *dev); + * \endcode + * @details This API is the entry point. + * Call this API before using all other APIs. + * This API reads the chip-id of the sensor and sets the resolution. + * + * @param[in,out] dev : Structure instance of bma4_dev + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +int8_t bma456h_init(struct bma4_dev *dev); + +/** + * \ingroup bma456h + * \defgroup bma456hApiConfig ConfigFile + * @brief Write binary configuration in the sensor + */ + +/*! + * \ingroup bma456hApiConfig + * \page bma456h_api_bma456h_write_config_file bma456h_write_config_file + * \code + * int8_t bma456h_write_config_file(struct bma4_dev *dev); + * \endcode + * @details This API is used to upload the config file to enable the features of + * the sensor. + * + * @param[in] dev : Structure instance of bma4_dev. + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +int8_t bma456h_write_config_file(struct bma4_dev *dev); + +/** + * \ingroup bma456h + * \defgroup bma456hApiConfigId ConfigId + * @brief Get Configuration ID of the sensor + */ + +/*! + * \ingroup bma456hApiConfig + * \page bma456h_api_bma456h_get_config_id bma456h_get_config_id + * \code + * int8_t bma456h_get_config_id(uint16_t *config_id, struct bma4_dev *dev); + * \endcode + * @details This API is used to get the configuration id of the sensor. + * + * @param[out] config_id : Pointer variable used to store the configuration id. + * @param[in] dev : Structure instance of bma4_dev. + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +int8_t bma456h_get_config_id(uint16_t *config_id, struct bma4_dev *dev); + +/** + * \ingroup bma456h + * \defgroup bma456hApiMapInt Map / Unmap Interrupt + * @brief Map / Unmap user provided interrupt to interrupt pin1 or pin2 of the sensor + */ + +/*! + * \ingroup bma456hApiMapInt + * \page bma456h_api_bma456h_map_interrupt bma456h_map_interrupt + * \code + * int8_t bma456h_map_interrupt(uint8_t int_line, uint16_t int_map, uint8_t enable, struct bma4_dev *dev); + * \endcode + * @details This API sets/unsets the user provided interrupt to either + * interrupt pin1 or pin2 in the sensor. + * + * @param[in] int_line: Variable to select either interrupt pin1 or pin2. + * + *@verbatim + * int_line | Macros + * ------------|------------------- + * 0x00 | BMA4_INTR1_MAP + * 0x01 | BMA4_INTR2_MAP + *@endverbatim + * + * @param[in] int_map : Variable to specify the interrupts. + * @param[in] enable : Variable to specify mapping or unmapping of interrupts. + * + *@verbatim + * enable | Macros + * --------|------------------- + * 0x00 | BMA4_DISABLE + * 0x01 | BMA4_ENABLE + *@endverbatim + * + * @param[in] dev : Structure instance of bma4_dev. + * + * @note Below macros specify the interrupts. + * + * Feature Interrupts + * - BMA456H_TAP_OUT_INT + * - BMA456H_STEP_CNTR_INT + * - BMA456H_ACTIVITY_INT + * - BMA456H_ANY_MOT_INT + * - BMA456H_ERROR_INT + * + * Hardware Interrupts + * - BMA4_FIFO_FULL_INT + * - BMA4_FIFO_WM_INT + * - BMA4_MAG_DATA_RDY_INT + * - BMA4_ACCEL_DATA_RDY_INT + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +int8_t bma456h_map_interrupt(uint8_t int_line, uint16_t int_map, uint8_t enable, struct bma4_dev *dev); + +/** + * \ingroup bma456h + * \defgroup bma456hApiIntS Interrupt Status + * @brief Read interrupt status of the sensor + */ + +/*! + * \ingroup bma456hApiIntS + * \page bma456h_api_bma456h_read_int_status bma456h_read_int_status + * \code + * int8_t bma456h_read_int_status(uint16_t *int_status, struct bma4_dev *dev); + * \endcode + * @details This API reads the bma456h interrupt status from the sensor. + * + * @param[out] int_status : Variable to store the interrupt status read from + * the sensor. + * @param[in] dev : Structure instance of bma4_dev. + * + * @note Below macros are used to check the interrupt status. + * + * Feature Interrupts + * - BMA456H_STEP_CNTR_INT + * - BMA456H_ACTIVITY_INT + * - BMA456H_SINGLE_TAP_EN + * - BMA456H_DOUBLE_TAP_EN + * - BMA456H_TRIPLE_TAP_EN + * - BMA456H_ANY_MOT_INT + * - BMA456H_ERROR_INT + * + * Hardware Interrupts + * - BMA4_FIFO_FULL_INT + * - BMA4_FIFO_WM_INT + * - BMA4_MAG_DATA_RDY_INT + * - BMA4_ACCEL_DATA_RDY_INT + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +int8_t bma456h_read_int_status(uint16_t *int_status, struct bma4_dev *dev); + +/** + * \ingroup bma456h + * \defgroup bma456hApiFeat Sensor Feature + * @brief Enables / Disables features of the sensor + */ + +/*! + * \ingroup bma456hApiFeat + * \page bma456h_api_bma456h_feature_enable bma456h_feature_enable + * \code + * int8_t bma456h_feature_enable(uint8_t feature, uint8_t enable, struct bma4_dev *dev); + * \endcode + * @details This API enables/disables the features of the sensor. + * + * @param[in] feature : Variable to specify the features which are to be set in + * bma456h sensor. + * @param[in] enable : Variable which specifies whether to enable or disable the + * features in the bma456h sensor. + * + *@verbatim + * enable | Macros + * --------|------------------- + * 0x00 | BMA4_DISABLE + * 0x01 | BMA4_ENABLE + *@endverbatim + * + * @param[in] dev : Structure instance of bma4_dev. + * + * @note User should use the below macros to enable or disable the + * features of bma456h sensor + * + * - BMA456H_NO_MOTION_X_AXIS_EN + * - BMA456H_NO_MOTION_Y_AXIS_EN + * - BMA456H_NO_MOTION_Z_AXIS_EN + * - BMA456H_NO_MOTION_ALL_AXIS_EN + * - BMA456H_ANY_MOTION_X_AXIS_EN + * - BMA456H_ANY_MOTION_Y_AXIS_EN + * - BMA456H_ANY_MOTION_Z_AXIS_EN + * - BMA456H_ANY_MOTION_ALL_AXIS_EN + * - BMA456H_STEP_DETECTOR_EN + * - BMA456H_STEP_COUNTER_EN + * - BMA456H_STEP_ACTIVITY_EN + * - BMA456H_AUTO_LOW_POWER_EN + * - BMA456H_SINGLE_TAP_EN + * - BMA456H_DOUBLE_TAP_EN + * - BMA456H_TRIPLE_TAP_EN + * - BMA456H_TAP_AVERAGE_EN + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +int8_t bma456h_feature_enable(uint16_t feature, uint8_t enable, struct bma4_dev *dev); + +/** + * \ingroup bma456h + * \defgroup bma456hApiRemap Remap Axes + * @brief Set / Get x, y and z axis re-mapping in the sensor + */ + +/*! + * \ingroup bma456hApiRemap + * \page bma456h_api_bma456h_set_remap_axes bma456h_set_remap_axes + * \code + * int8_t bma456h_set_remap_axes(const struct bma4_remap *remap_data, struct bma4_dev *dev); + * \endcode + * @details This API performs x, y and z axis remapping in the sensor. + * + * @param[in] remap_data : Pointer to store axes remapping data. + * @param[in] dev : Structure instance of bma4_dev + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +int8_t bma456h_set_remap_axes(const struct bma4_remap *remap_data, struct bma4_dev *dev); + +/*! + * \ingroup bma456hApiRemap + * \page bma456h_api_bma456h_get_remap_axes bma456h_get_remap_axes + * \code + * int8_t bma456h_get_remap_axes(struct bma4_remap *remap_data, struct bma4_dev *dev); + * \endcode + * @details This API reads the x, y and z axis remap data from the sensor. + * + * @param[out] remap_data : Pointer to store axis remap data which is read + * from the bma456h sensor. + * @param[in] dev : Structure instance of bma4_dev + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +int8_t bma456h_get_remap_axes(struct bma4_remap *remap_data, struct bma4_dev *dev); + +/** + * \ingroup bma456h + * \defgroup bma456hApiStepC Step counter + * @brief Operations of step counter feature of the sensor + */ + +/*! + * \ingroup bma456hApiStepC + * \page bma456h_api_bma456h_step_counter_set_watermark bma456h_step_counter_set_watermark + * \code + * int8_t bma456h_step_counter_set_watermark(uint16_t step_counter_wm, struct bma4_dev *dev); + * \endcode + * @details This API sets the watermark level for step counter interrupt in + * the sensor. + * + * @param[in] step_counter_wm : Variable which specifies watermark level + * count + * @note Valid values are from 1 to 1023 + * @note Value 0 is used for step detector interrupt + * + * @param[in] dev : Structure instance of bma4_dev + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +int8_t bma456h_step_counter_set_watermark(uint16_t step_counter_wm, struct bma4_dev *dev); + +/*! + * \ingroup bma456hApiStepC + * \page bma456h_api_bma456h_step_counter_get_watermark bma456h_step_counter_get_watermark + * \code + * int8_t bma456h_step_counter_get_watermark(uint16_t *step_counter_wm, struct bma4_dev *dev); + * \endcode + * @details This API gets the water mark level set for step counter interrupt + * in the sensor + * + * @param[out] step_counter_wm : Pointer variable which stores the water mark + * level read from the sensor. + * @note valid values are from 1 to 1023 + * @note value 0 is used for step detector interrupt + * + * @param[in] dev : Structure instance of bma4_dev + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +int8_t bma456h_step_counter_get_watermark(uint16_t *step_counter_wm, struct bma4_dev *dev); + +/*! + * \ingroup bma456hApiStepC + * \page bma456h_api_bma456h_reset_step_counter bma456h_reset_step_counter + * \code + * int8_t bma456h_reset_step_counter(struct bma4_dev *dev); + * \endcode + * @details This API resets the counted steps of step counter. + * + * @param[in] dev : structure instance of bma4_dev + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +int8_t bma456h_reset_step_counter(struct bma4_dev *dev); + +/*! + * \ingroup bma456hApiStepC + * \page bma456h_api_bma456h_step_counter_output bma456h_step_counter_output + * \code + * int8_t bma456h_step_counter_output(uint32_t *step_count, struct bma4_dev *dev); + * \endcode + * @details This API gets the number of counted steps of the step counter + * feature from the sensor. + * + * @param[out] step_count : Pointer variable which stores counted steps + * read from the sensor. + * @param[in] dev : Structure instance of bma4_dev + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +int8_t bma456h_step_counter_output(uint32_t *step_count, struct bma4_dev *dev); + +/** + * \ingroup bma456h + * \defgroup bma456hApiAct Activity Feature + * @brief Get output for activity feature of the sensor + */ + +/*! + * \ingroup bma456hApiAct + * \page bma456h_api_bma456h_output_state bma456h_output_state + * \code + * int8_t bma456h_output_state(struct bma456h_out_state *out_state, struct bma4_dev *dev); + * \endcode + * @details This API gets the output for activity feature. + * + * @param[out] activity : Pointer variable which stores activity output read + * from the sensor. + * + *@verbatim + * activity | State + * --------------|------------------------ + * 0x00 | BMA456H_USER_STATIONARY + * 0x01 | BMA456H_USER_WALKING + * 0x02 | BMA456H_USER_RUNNING + * 0x03 | BMA456H_STATE_INVALID + *@endverbatim + * + * @param[in] dev : Structure instance of bma4_dev + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +int8_t bma456h_output_state(struct bma456h_out_state *out_state, struct bma4_dev *dev); + +/*! + * \ingroup bma456hApiStepC + * \page bma456h_api_bma456h_stepcounter_get_parameter bma456h_stepcounter_get_parameter + * \code + * int8_t bma456h_stepcounter_get_parameter(struct bma456h_stepcounter_settings *setting, struct bma4_dev *dev); + * \endcode + * @details This API gets the parameter1 to parameter7 settings of the step + * counter feature. + * + * @param[out] setting : Pointer to structure variable which stores the + * parameter1 to parameter7 read from the sensor. + * @param[in] dev : Structure instance of bma4_dev + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +int8_t bma456h_stepcounter_get_parameter(struct bma456h_stepcounter_settings *setting, struct bma4_dev *dev); + +/*! + * \ingroup bma456hApiStepC + * \page bma456h_api_bma456h_stepcounter_set_parameter bma456h_stepcounter_set_parameter + * \code + * int8_t bma456h_stepcounter_set_parameter(const struct bma456h_stepcounter_settings *setting, struct bma4_dev *dev); + * \endcode + * @details This API sets the parameter1 to parameter7 settings of the step + * counter feature in the sensor. + * + * @param[in] setting : Pointer to structure variable which stores the + * parameter1 to parameter7 settings read from the sensor. + * @param[in] dev : Structure instance of bma4_dev + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +int8_t bma456h_stepcounter_set_parameter(const struct bma456h_stepcounter_settings *setting, struct bma4_dev *dev); + +/** + * \ingroup bma456h + * \defgroup bma456hApiStepD Step detector + * @brief Operations of step detector feature of the sensor + */ + +/*! + * \ingroup bma456hApiStepD + * \page bma456h_api_bma456h_step_detector_enable bma456h_step_detector_enable + * \code + * int8_t bma456h_step_detector_enable(uint8_t enable, struct bma4_dev *dev); + * \endcode + * @details This API enables or disables the step detector feature in the + * sensor. + * + * @param[in] enable : Variable used to enable or disable step detector + * + *@verbatim + * enable | Macros + * --------|------------------- + * 0x00 | BMA4_DISABLE + * 0x01 | BMA4_ENABLE + *@endverbatim + * + * @param[in] dev : Structure instance of bma4_dev + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +int8_t bma456h_step_detector_enable(uint8_t enable, struct bma4_dev *dev); + +/** + * \ingroup bma456h + * \defgroup bma456hApiAnyMot Any motion Feature + * @brief Functions of Any motion feature of the sensor + */ + +/*! + * \ingroup bma456hApiAnyMot + * \page bma456h_api_bma456h_set_any_motion_config bma456h_set_any_motion_config + * \code + * int8_t bma456h_set_any_mot_config(const struct bma456h_any_no_mot_config *any_mot, struct bma4_dev *dev); + * \endcode + * @details This API sets the configuration of any-motion feature in the sensor + * This API enables/disables the any-motion feature according to the axis set. + * + * @param[in] any_mot : Pointer to structure variable to configure + * any-motion. + * + * @verbatim + * ------------------------------------------------------------------------- + * Structure parameters | Description + * --------------------------------|---------------------------------------- + * | Threshold for duration to + * | detect any-motion event. + * | Range 0 to 163 seconds. + * duration | Resolution is 20 ms. + * | Default value is 100 ms + * | + * | + * | + * --------------------------------|---------------------------------------- + * | Threshold for acceleration + * | signal slope to detect any- + * threshold | motion event. Range is 0 to 1g. + * | Resolution is 0.4883mg. Default + * | value is 100 mg. + * --------------------------------|----------------------------------------- + * | Defines any motion interrupt + * | behavior + * | Value Name Description + * | + * | 0 multi_int Generates + * interrupt behavior | interrupt + * | as long as + * | condition + * | is valid + * | 1 single_shot Generate one + * | interrupt for + * | every valid + * | condition + * --------------------------------|----------------------------------------- + * | Configuration for acceleration + * | slope computation + * | + * | Value Name Description + * | 0 non- slope between + * | consecutive acceleration + * | vector at last + * Slope | event detection + * | to current. + * | 1 consecutive Computes the + * | slope between + * | consecutive + * | acceleration + * | vector samples + * --------------------------------------------------------------------------- + *@endverbatim + * + * @param[in] dev : Structure instance of bma4_dev + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +int8_t bma456h_set_any_mot_config(const struct bma456h_any_no_mot_config *any_mot, struct bma4_dev *dev); + +/*! + * \ingroup bma456hApiAnyMot + * \page bma456h_api_bma456h_get_any_mot_config bma456h_get_any_mot_config + * \code + * int8_t bma456h_get_any_mot_config(struct bma456h_any_no_mot_config *any_mot, struct bma4_dev *dev); + * \endcode + * @details This API gets the configuration of any-motion feature from the + * sensor. + * + * @param[out] any_mot : Pointer to structure variable to configure + * any-motion. + * + * @verbatim + * ------------------------------------------------------------------------- + * Structure parameters | Description + * --------------------------------|---------------------------------------- + * | Threshold for duration to + * | detect any-motion event. + * | Range 0 to 163 seconds. + * duration | Resolution is 20 ms. + * | Default value is 100 ms + * | + * | + * | + * --------------------------------|---------------------------------------- + * | Threshold for acceleration + * | signal slope to detect any- + * threshold | motion event. Range is 0 to 1g. + * | Resolution is 0.4883mg. Default + * | value is 100 mg. + * --------------------------------|----------------------------------------- + * | Defines any motion interrupt + * | behavior + * | Value Name Description + * | + * | 0 multi_int Generates + * interrupt behavior | interrupt + * | as long as + * | condition + * | is valid + * | 1 single_shot Generate one + * | interrupt for + * | every valid + * | condition + * --------------------------------|----------------------------------------- + * | Configuration for acceleration + * | slope computation + * | + * | Value Name Description + * | 0 non- slope between + * | consecutive acceleration + * | vector at last + * Slope | event detection + * | to current. + * | 1 consecutive Computes the + * | slope between + * | consecutive + * | acceleration + * | vector samples + * --------------------------------------------------------------------------- + * @endverbatim + * + * @param[in] dev : Structure instance of bma4_dev + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +int8_t bma456h_get_any_mot_config(struct bma456h_any_no_mot_config *any_mot, struct bma4_dev *dev); + +/** + * \ingroup bma456h + * \defgroup bma456hApiNoMot No-motion Feature + * @brief Functions of no-motion feature of the sensor + */ + +/*! + * \ingroup bma456hApiNoMot + * \page bma456h_api_bma456h_set_no_mot_config bma456h_set_no_mot_config + * \code + * int8_t bma456h_set_no_mot_config(const struct bma456h_any_no_mot_config *no_mot, struct bma4_dev *dev); + * \endcode + * @details This API sets the configuration of no-motion feature in the sensor + * This API enables/disables the no-motion feature according to the axis set. + * + * @param[in] no_mot : Pointer to structure variable to configure + * no-motion. + * + * @verbatim + * ------------------------------------------------------------------------- + * Structure parameters | Description + * --------------------------------|---------------------------------------- + * | Threshold for acceleration + * | signal slope to detect no- + * threshold | motion event. Range is 0 to 1g. + * | Resolution is 0.4883mg. Default + * | value is 100 mg. + * --------------------------------|----------------------------------------- + * | Defines any motion interrupt + * | behavior + * | Value Name Description + * | + * | 0 multi_int Generates + * interrupt behavior | interrupt + * | as long as + * | condition + * | is valid + * | 1 single_shot Generate one + * | interrupt for + * | every valid + * | condition + * --------------------------------------------------------------------------- + * | Threshold for duration to + * | detect no-motion event. + * | Range 0 to 163 seconds. + * duration | Resolution is 20 ms. + * | Default value is 2000 ms + * | + * | + * | + * ------------------------------------------------------------------------- + * @endverbatim + * + * @param[in] dev : Structure instance of bma4_dev + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +int8_t bma456h_set_no_mot_config(const struct bma456h_any_no_mot_config *no_mot, struct bma4_dev *dev); + +/*! + * \ingroup bma456hApiNoMot + * \page bma456h_api_bma456h_get_no_mot_config bma456h_get_no_mot_config + * \code + * int8_t bma456h_get_no_mot_config(struct bma456h_any_no_mot_config *no_mot, struct bma4_dev *dev); + * \endcode + * @details This API gets the configuration of no-motion feature from the + * sensor. + * + * @param[out] no_mot : Pointer to structure variable to configure + * no-motion. + * + * @verbatim + * ------------------------------------------------------------------------- + * Structure parameters | Description + * --------------------------------|---------------------------------------- + * | Threshold for acceleration + * | signal slope to detect no- + * threshold | motion event. Range is 0 to 1g. + * | Resolution is 0.4883mg. Default + * | value is 100 mg. + * --------------------------------|----------------------------------------- + * | Defines any motion interrupt + * | behavior + * | Value Name Description + * | + * | 0 multi_int Generates + * interrupt behavior | interrupt + * | as long as + * | condition + * | is valid + * | 1 single_shot Generate one + * | interrupt for + * | every valid + * | condition + * --------------------------------------------------------------------------- + * | Threshold for duration to + * | detect no-motion event. + * | Range 0 to 163 seconds. + * duration | Resolution is 20 ms. + * | Default value is 2000 ms + * | + * | + * | + * ------------------------------------------------------------------------- + * @endverbatim + * + * @param[in] dev : Structure instance of bma4_dev + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +int8_t bma456h_get_no_mot_config(struct bma456h_any_no_mot_config *no_mot, struct bma4_dev *dev); + +/** + * \ingroup bma456h + * \defgroup bma456hApiTap Tap Feature + * @brief Tap feature operations + */ + +/*! + * \ingroup bma456hApiTap + * \page bma456h_api_bma456h_tap_get_parameter bma456h_tap_get_parameter + * \code + * int8_t bma456h_tap_get_parameter(struct bma456h_multitap_settings *setting, struct bma4_dev *dev); + * \endcode + * @details This API gets the parameter1 to parameter12 settings of the tap + * feature. + * + * @param[out] setting : Pointer to structure variable which stores the + * parameter1 to parameter12 read from the sensor. + * @param[in] dev : Structure instance of bma4_dev + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +int8_t bma456h_tap_get_parameter(struct bma456h_multitap_settings *setting, struct bma4_dev *dev); + +/*! + * \ingroup bma456hApiTap + * \page bma456h_api_bma456h_tap_set_parameter bma456h_tap_set_parameter + * \code + * int8_t bma456h_tap_set_parameter(const struct bma456h_multitap_settings *setting, struct bma4_dev *dev); + * \endcode + * @details This API sets the parameter1 to parameter12 settings of the tap + * feature in the sensor. + * + * @param[in] setting : Pointer to structure variable which stores the + * parameter1 to parameter12 settings read from the sensor. + * @param[in] dev : Structure instance of bma4_dev + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +int8_t bma456h_tap_set_parameter(const struct bma456h_multitap_settings *setting, struct bma4_dev *dev); + +/** + * \ingroup bma456h + * \defgroup bma456hApiAutoLP Auto Low power mode + * @brief Configurations and Status of auto low power mode of the sensor + */ + +/*! + * \ingroup bma456hApiAutoLP + * \page bma456h_api_bma456h_get_auto_low_power_config bma456h_get_auto_low_power_config + * \code + * int8_t bma456h_get_auto_low_power_config(struct bma456h_auto_low_power *auto_low_power, struct bma4_dev *dev); + * \endcode + * @details This api gets the auto low power configuration + * + * @param auto_low_power[out] : this pointer gets the auto low power configuration. + * @param dev[in] : Structure instance of bma4_dev + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +int8_t bma456h_get_auto_low_power_config(struct bma456h_auto_low_power *auto_low_power, struct bma4_dev *dev); + +/*! + * \ingroup bma456hApiAutoLP + * \page bma456h_api_bma456h_set_auto_low_power_config bma456h_set_auto_low_power_config + * \code + * int8_t bma456h_set_auto_low_power_config(const struct bma456h_auto_low_power *auto_low_power, struct bma4_dev *dev); + * \endcode + * @details This api sets the auto low power configuration + * + * @param auto_low_power[in] : this pointer sets the auto low power configuration. + * @param dev[in] : Structure instance of bma4_dev + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +int8_t bma456h_set_auto_low_power_config(const struct bma456h_auto_low_power *auto_low_power, struct bma4_dev *dev); + +/*! + * \ingroup bma456hApiAutoLP + * \page bma456h_api_bma456h_get_auto_low_power_state bma456h_get_auto_low_power_state + * \code + * int8_t bma456h_get_auto_low_power_state(uint8_t *auto_low_power_state, struct bma4_dev *dev); + * \endcode + * @details This api reads the auto low power state output status + * + * @param auto_low_power_state[out] : pointer reads auto low power state output bit status. + * @param dev[in] : Structure instance of bma4_dev + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +int8_t bma456h_get_auto_low_power_state(uint8_t *auto_low_power_state, struct bma4_dev *dev); + +/*! + * \ingroup bma456hApiVersionConfig + * \page bma456h_api_bma456h_get_version_config bma456h_get_version_config + * \code + *int8_t bma456h_get_version_config(uint16_t *config_major, uint16_t *config_minor, struct bma4_dev *dev); + * \endcode + * @details This API is used to get the config file major and minor information. + * + * @param[in] dev : Structure instance of bma4_dev. + * @param[out] config_major : Pointer to data buffer to store the config major. + * @param[out] config_minor : Pointer to data buffer to store the config minor. + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +int8_t bma456h_get_version_config(uint16_t *config_major, uint16_t *config_minor, struct bma4_dev *dev); + +#ifdef __cplusplus +} +#endif /*End of CPP guard */ + +#endif /*End of header guard macro */ diff --git a/components/bma456/bma456h_examples/accel_foc/Makefile b/components/bma456/bma456h_examples/accel_foc/Makefile new file mode 100644 index 0000000..824e337 --- /dev/null +++ b/components/bma456/bma456h_examples/accel_foc/Makefile @@ -0,0 +1,18 @@ +COINES_INSTALL_PATH ?= ../../../.. + +EXAMPLE_FILE ?= accel_foc.c + +API_LOCATION ?= ../.. + +COMMON_LOCATION ?= .. + +C_SRCS += \ +$(API_LOCATION)/bma4.c \ +$(API_LOCATION)/bma456h.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/components/bma456/bma456h_examples/accel_foc/accel_foc.c b/components/bma456/bma456h_examples/accel_foc/accel_foc.c new file mode 100644 index 0000000..2b2e071 --- /dev/null +++ b/components/bma456/bma456h_examples/accel_foc/accel_foc.c @@ -0,0 +1,741 @@ +/**\ + * Copyright (c) 2022 Bosch Sensortec GmbH. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + **/ + +/******************************************************************************/ +/*! Header Files */ +#include +#include +#include +#include +#include + +#include "bma456h.h" +#include "common.h" +#include "coines.h" + +/******************************************************************************/ +/*! Macro Definitions */ + +#define ACCEL_SAMPLE_COUNT UINT8_C(100) + +/******************************************************************************/ +/*! Global Variable Declaration */ + +/* Structure to store temporary axes data values */ +struct temp_axes_val +{ + /* X data */ + int32_t x; + + /* Y data */ + int32_t y; + + /* Z data */ + int32_t z; +}; + +/******************************************************************************/ +/*! Static Function Declaration */ + +/*! + * @brief This internal API is used perform accel foc and determine limits based on range + * + * @param[in] range : Range of Accel + * @param[in] input_axis : Axis selected for Accel FOC + * @param[in,out] dev : Structure instance of bma4_dev. + * + * @return Status of execution. + */ +static int8_t perform_foc_range_test(uint8_t range, uint8_t input_axis, struct bma4_dev *dev); + +/*! + * @brief This internal API is to determine if average accel FOC data is within limits + * + * @param[in] avg_accel_foc_data : Average Accel FOC value + * @param[in] reference : Reference LSB based on Accel Range + * @param[in] foc_sign : Input sign of performed Accel FOC + * @param[in] min_val : Minimum acceptable LSB limit + * @param[in] max_val : Maximum acceptable LSB limit + * + * @return Status of execution. + */ +static int8_t accel_foc_report(int16_t avg_accel_foc_data, + int16_t reference, + uint8_t foc_sign, + int16_t min_val, + int16_t max_val); + +/*! + * @brief This internal API is to collect and verify accel sensor data + * + * @param[in] range : Value of Accel range + * @param[in] reference : Reference LSB based on Accel Range + * @param[in] matched_axis : Input Axis to perform Accel FOC + * @param[in] foc_sign : Input sign to perform Accel FOC + * @param[in,out] dev : Structure instance of bma4_dev. + * + * @return Status of execution. + */ +static int8_t verify_accel_foc_data(uint8_t range, + int16_t reference, + int8_t matched_axis, + uint8_t foc_sign, + struct bma4_dev *dev); + +/*! + * @brief This internal API is to calculate noise level for Accel FOC data + * + * @param[in] matched_axis : Input Axis to perform accel FOC + * @param[in] accel_foc_data : Array of Accel FOC data + * @param[in] avg_accel_foc_data : Average Accel FOC data + * + * @return Status of execution. + */ +static void calculate_noise(int8_t matched_axis, + const struct bma4_accel *accel_foc_data, + const struct bma4_accel avg_accel_foc_data); + +/******************************************************************************/ +/*! Functions */ + +/* This function starts the execution of program. */ +int main(void) +{ + /* Sensor initialization configuration. */ + struct bma4_dev dev; + + uint8_t try = 0, j; + int8_t rslt; + struct bma4_accel_config accel_conf = { 0 }; + uint8_t data = 0, range, input_axis = 0; + + /* Interface reference is given as a parameter + * For I2C : BMA4_I2C_INTF + * For SPI : BMA4_SPI_INTF + * Variant information given as parameter - BMA45X_VARIANT + */ + rslt = bma4_interface_init(&dev, BMA4_I2C_INTF, BMA45X_VARIANT); + bma4_error_codes_print_result("bma4_interface_init", rslt); + + printf("Functional test for accel foc start..\n\n"); + + printf("Choose the axis for accel FOC to be done\n"); + printf("Press '1' to choose X axis\n"); + printf("Press '2' to choose Y axis\n"); + printf("Press '3' to choose Z axis\n"); + + printf("Press '4' to choose -X axis\n"); + printf("Press '5' to choose -Y axis\n"); + printf("Press '6' to choose -Z axis\n"); + + for (;;) + { + scanf("%u", (unsigned int *)&input_axis); + if (input_axis > 0 && input_axis < 7) + { + break; + } + } + + if (input_axis == 1) + { + printf("The choosen input axis for FOC is : X\n"); + } + else if (input_axis == 2) + { + printf("The choosen input axis for FOC is : Y\n"); + } + else if (input_axis == 3) + { + printf("The choosen input axis for FOC is : Z\n"); + } + else if (input_axis == 4) + { + printf("The choosen input axis for FOC is : -X\n"); + } + else if (input_axis == 5) + { + printf("The choosen input axis for FOC is : -Y\n"); + } + else if (input_axis == 6) + { + printf("The choosen input axis for FOC is : -Z\n"); + } + + printf("Confirm your chosen axis and the sensor keeping position are same before doing FOC\n"); + + for (j = 0; j < 2; j++) + { + try = 0; + + if (j == 1) + { + printf("Keep sensor in wrong position and press 5\n"); + } + else if (j == 0) + { + printf("Keep sensor in right position and press 5\n"); + } + + for (;;) + { + scanf("%hu", (short unsigned int *)&try); + if (try == 5) + { + break; + } + } + + for (range = BMA4_ACCEL_RANGE_2G; range <= BMA4_ACCEL_RANGE_16G; range++) + { + /****************************************************************/ + /* Initialize by enabling configuration load */ + printf("#########################################################\n\n"); + + rslt = bma456h_init(&dev); + bma4_error_codes_print_result("bma4_init", rslt); + + /* Upload the configuration file to enable the features of the sensor. */ + rslt = bma456h_write_config_file(&dev); + bma4_error_codes_print_result("bma4_write_config", rslt); + + /* Enable the accelerometer */ + rslt = bma4_set_accel_enable(BMA4_ENABLE, &dev); + bma4_error_codes_print_result("bma4_set_accel_enable status", rslt); + + /* Accelerometer Configuration Settings */ + /* Output Data Rate */ + accel_conf.odr = BMA4_OUTPUT_DATA_RATE_50HZ; + + /* Gravity range of the sensor (+/- 2G, 4G, 8G, 16G) */ + accel_conf.range = range; + + /* The bandwidth parameter is used to configure the number of sensor samples that are averaged + * if it is set to 2, then 2^(bandwidth parameter) samples + * are averaged, resulting in 4 averaged samples + * Note1 : For more information, refer the datasheet. + * Note2 : A higher number of averaged samples will result in a less noisier signal, but + * this has an adverse effect on the power consumed. + */ + accel_conf.bandwidth = BMA4_ACCEL_NORMAL_AVG4; + + /* Enable the filter performance mode where averaging of samples + * will be done based on above set bandwidth and ODR. + * There are two modes + * 0 -> Averaging samples (Default) + * 1 -> No averaging + * For more info on No Averaging mode refer datasheet. + */ + accel_conf.perf_mode = BMA4_CIC_AVG_MODE; + + /* Set the accel configurations */ + rslt = bma4_set_accel_config(&accel_conf, &dev); + bma4_error_codes_print_result("bma4_set_accel_config status", rslt); + + /* Delay to set accel sensor configurations (20ms for 50HZ) */ + dev.delay_us(20000, dev.intf_ptr); + + /* Mapping data ready interrupt with interrupt1 to get interrupt status once getting new accel data */ + rslt = bma456h_map_interrupt(BMA4_INTR1_MAP, BMA4_DATA_RDY_INT, BMA4_ENABLE, &dev); + bma4_error_codes_print_result("bma4_map_interrupt status", rslt); + + printf("ODR = %d, RANGE = %d, BANDWIDTH = %d\n", accel_conf.odr, accel_conf.range, accel_conf.bandwidth); + + /* Perform FOC for different ranges */ + rslt = perform_foc_range_test(range, input_axis, &dev); + + if ((j == 1) && (rslt == BMA4_E_OUT_OF_RANGE)) + { + printf("\n######### Valid input - Wrong position #########\n\n"); + bma4_error_codes_print_result("perform_foc_range_test", rslt); + } + else if ((j == 0) && (rslt == BMA4_OK)) + { + printf("\n######### Valid input - Right position #########\n\n"); + bma4_error_codes_print_result("perform_foc_range_test", rslt); + } + else if ((j == 1) && (rslt == BMA4_OK)) + { + printf("\n######### Invalid input - Right position #########\n\n"); + bma4_error_codes_print_result("perform_foc_range_test", rslt); + } + else if ((j == 0) && (rslt == BMA4_E_OUT_OF_RANGE)) + { + printf("\n######### Invalid input - Wrong position #########\n\n"); + bma4_error_codes_print_result("perform_foc_range_test", rslt); + } + else if ((j == 0) && (rslt == BMA4_E_OUT_OF_RANGE)) + { + printf("\n######### Valid input - Right position #########\n\n"); + printf("\n######### Before FOC is better than after FOC #########\n\n"); + bma4_error_codes_print_result("perform_foc_range_test", rslt); + } + else if ((j == 1) && (rslt == BMA4_E_OUT_OF_RANGE)) + { + printf("\n######### Invalid input - Right position #########\n\n"); + printf("\n######### Before FOC is better than after FOC #########\n\n"); + bma4_error_codes_print_result("perform_foc_range_test", rslt); + } + } + + /* Disable offset compensation */ + rslt = bma4_read_regs(BMA4_NV_CONFIG_ADDR, &data, 1, &dev); + bma4_error_codes_print_result("bma4_read_regs", rslt); + + data = BMA4_SET_BIT_VAL_0(data, BMA4_NV_ACCEL_OFFSET); + + rslt = bma4_write_regs(BMA4_NV_CONFIG_ADDR, &data, 1, &dev); + bma4_error_codes_print_result("bma4_write_regs", rslt); + } + + bma4_coines_deinit(); + + return rslt; +} + +static int8_t accel_foc_report(int16_t avg_accel_foc_data, + int16_t reference, + uint8_t foc_sign, + int16_t min_val, + int16_t max_val) +{ + int8_t rslt = BMA4_OK; + int16_t diff_after = 0; + + if (foc_sign == 0) + { + if ((avg_accel_foc_data >= (min_val)) && (avg_accel_foc_data <= (max_val))) + { + if (avg_accel_foc_data >= reference) + { + diff_after = avg_accel_foc_data - reference; + } + else + { + diff_after = reference - avg_accel_foc_data; + } + + printf("\n# ********** PASS | Difference = %d **********\n", diff_after); + printf("\n# Avg_FOC %d in range\n", avg_accel_foc_data); + rslt = BMA4_OK; + } + else + { + if (avg_accel_foc_data >= reference) + { + diff_after = avg_accel_foc_data - reference; + } + else + { + diff_after = reference - avg_accel_foc_data; + } + + printf("\n# ********** FAIL | Difference = %d **********\n", diff_after); + printf("\n# Avg_FOC %d not in range\n", avg_accel_foc_data); + rslt = BMA4_E_OUT_OF_RANGE; + } + } + + if (foc_sign == 1) + { + if ((avg_accel_foc_data <= (min_val)) && (avg_accel_foc_data >= (max_val))) + { + if (avg_accel_foc_data <= reference) + { + diff_after = avg_accel_foc_data - reference; + } + else + { + diff_after = reference - avg_accel_foc_data; + } + + printf("\n# ********** PASS | Difference = %d **********\n", diff_after); + printf("\n# Avg_FOC %d in range\n", avg_accel_foc_data); + rslt = BMA4_OK; + } + else + { + if (avg_accel_foc_data <= reference) + { + diff_after = avg_accel_foc_data - reference; + } + else + { + diff_after = reference - avg_accel_foc_data; + } + + printf("\n# ********** FAIL | Difference = %d **********\n", diff_after); + printf("\n# Avg_FOC %d not in range\n", avg_accel_foc_data); + rslt = BMA4_E_OUT_OF_RANGE; + } + } + + return rslt; +} + +static void calculate_noise(int8_t matched_axis, + const struct bma4_accel *accel_foc_data, + const struct bma4_accel avg_accel_foc_data) +{ + int32_t variance = 0; + double noise_level; + uint16_t idx = 0; + + if (matched_axis == 'X') + { + for (idx = 0; idx < ACCEL_SAMPLE_COUNT; idx++) + { + variance += + ((accel_foc_data[idx].x - avg_accel_foc_data.x) * (accel_foc_data[idx].x - avg_accel_foc_data.x)); + } + } + else if (matched_axis == 'Y') + { + for (idx = 0; idx < ACCEL_SAMPLE_COUNT; idx++) + { + variance += + ((accel_foc_data[idx].y - avg_accel_foc_data.y) * (accel_foc_data[idx].y - avg_accel_foc_data.y)); + } + } + else if (matched_axis == 'Z') + { + for (idx = 0; idx < ACCEL_SAMPLE_COUNT; idx++) + { + variance += + ((accel_foc_data[idx].z - avg_accel_foc_data.z) * (accel_foc_data[idx].z - avg_accel_foc_data.z)); + } + } + + noise_level = sqrt((double)variance); + + printf("\n# ********** NOISE LEVEL = %lf **********\n", noise_level); +} + +static int8_t verify_accel_foc_data(uint8_t range, + int16_t reference, + int8_t matched_axis, + uint8_t foc_sign, + struct bma4_dev *dev) +{ + int8_t rslt = BMA4_E_INVALID_STATUS; + uint8_t i; + uint16_t reg_status = 0; + int16_t xl, yl, zl; + int16_t xh, yh, zh; + int16_t min_val = 0; + int16_t max_val = 0; + struct bma4_accel accel_foc_data[ACCEL_SAMPLE_COUNT] = { { 0 } }; + struct temp_axes_val temp_foc_data = { 0 }; + struct bma4_accel avg_accel_foc_data = { 0 }; + struct bma4_accel sensor_data = { 0 }; + + /* Setting initial values */ + xl = yl = zl = 32767; + xh = yh = zh = -32768; + + /* Read accelerometer values before/after FOC */ + for (i = 0; i < ACCEL_SAMPLE_COUNT; i++) + { + for (;;) + { + /* To get the data ready interrupt status */ + rslt = bma4_read_int_status(®_status, dev); + bma4_error_codes_print_result("bma4_read_int_status", rslt); + + /* Read accelerometer data based on data ready interrupt */ + if ((rslt == BMA4_OK) && (reg_status & BMA4_ACCEL_DATA_RDY_INT)) + { + rslt = bma4_read_accel_xyz(&sensor_data, dev); + bma4_error_codes_print_result("bma4_read_accel_xyz", rslt); + + memcpy(&accel_foc_data[i], &sensor_data, sizeof(struct bma4_accel)); + + printf("X[%d] = %5d Y[%d] = %5d Z[%d] = %5d\n", + i, + accel_foc_data[i].x, + i, + accel_foc_data[i].y, + i, + accel_foc_data[i].z); + + if (xl > accel_foc_data[i].x) + { + xl = accel_foc_data[i].x; + } + + if (xh < accel_foc_data[i].x) + { + xh = accel_foc_data[i].x; + } + + if (yl > accel_foc_data[i].y) + { + yl = accel_foc_data[i].y; + } + + if (yh < accel_foc_data[i].y) + { + yh = accel_foc_data[i].y; + } + + if (zl > accel_foc_data[i].z) + { + zl = accel_foc_data[i].z; + } + + if (zh < accel_foc_data[i].z) + { + zh = accel_foc_data[i].z; + } + + temp_foc_data.x += accel_foc_data[i].x; + temp_foc_data.y += accel_foc_data[i].y; + temp_foc_data.z += accel_foc_data[i].z; + break; + + } + } + } + + /* Taking average values to calculate percentage deviation */ + avg_accel_foc_data.x = (int16_t)(temp_foc_data.x / ACCEL_SAMPLE_COUNT); + avg_accel_foc_data.y = (int16_t)(temp_foc_data.y / ACCEL_SAMPLE_COUNT); + avg_accel_foc_data.z = (int16_t)(temp_foc_data.z / ACCEL_SAMPLE_COUNT); + + printf("********* MIN & MAX VALUES ********\n"); + + printf("XL = %5d YL = %5d ZL = %5d\n", xl, yl, zl); + printf("XH = %5d YH = %5d ZH = %5d\n", xh, yh, zh); + + printf("***** AVERAGE AFTER FOC *****\n"); + printf("Avg-X = %d Avg-Y = %d Avg-Z = %d\n", + avg_accel_foc_data.x, + avg_accel_foc_data.y, + avg_accel_foc_data.z); + + /* Calculate noise level */ + calculate_noise(matched_axis, accel_foc_data, avg_accel_foc_data); + + /* "zero-g offset" of accel is +/- 20 mg for all ranges as per datasheet (for 16-bit resolution) */ + if (range == 0) + { + /* Min and Max limits for Range 2G */ + min_val = BMA4_16BIT_ACC_2G_MIN_NOISE_LIMIT; + max_val = BMA4_16BIT_ACC_2G_MAX_NOISE_LIMIT; + } + else if (range == 1) + { + /* Min and Max limits for Range 4G */ + min_val = BMA4_16BIT_ACC_4G_MIN_NOISE_LIMIT; + max_val = BMA4_16BIT_ACC_4G_MAX_NOISE_LIMIT; + } + else if (range == 2) + { + /* Min and Max limits for Range 8G */ + min_val = BMA4_16BIT_ACC_8G_MIN_NOISE_LIMIT; + max_val = BMA4_16BIT_ACC_8G_MAX_NOISE_LIMIT; + } + else if (range == 3) + { + /* Min and Max limits for Range 16G */ + min_val = BMA4_16BIT_ACC_16G_MIN_NOISE_LIMIT; + max_val = BMA4_16BIT_ACC_16G_MAX_NOISE_LIMIT; + } + + if ((matched_axis == 'X') && (foc_sign == 0)) + { + rslt = accel_foc_report(avg_accel_foc_data.x, reference, foc_sign, min_val, max_val); + printf("Range : %u Avg_FOC-X : %d Reference : %d Min_Value : %d Max_Value : %d\n", + range, + avg_accel_foc_data.x, + reference, + min_val, + max_val); + } + else if ((matched_axis == 'Y') && (foc_sign == 0)) + { + rslt = accel_foc_report(avg_accel_foc_data.y, reference, foc_sign, min_val, max_val); + printf("Range : %u Avg_FOC-X : %d Reference : %d Min_Value : %d Max_Value : %d\n", + range, + avg_accel_foc_data.y, + reference, + min_val, + max_val); + } + else if ((matched_axis == 'Z') && (foc_sign == 0)) + { + rslt = accel_foc_report(avg_accel_foc_data.z, reference, foc_sign, min_val, max_val); + printf("Range : %u Avg_FOC-X : %d Reference : %d Min_Value : %d Max_Value : %d\n", + range, + avg_accel_foc_data.z, + reference, + min_val, + max_val); + } + else if ((matched_axis == 'X') && (foc_sign == 1)) + { + rslt = accel_foc_report(avg_accel_foc_data.x, + (int16_t)(reference * (-1)), + foc_sign, + (int16_t)(min_val * (-1)), + (int16_t)(max_val * (-1))); + printf("Range : %u Avg_FOC-X : %d Reference : %d Min_Value : %d Max_Value : %d\n", + range, + avg_accel_foc_data.x, + (reference * (-1)), + (min_val * (-1)), + (max_val * (-1))); + } + else if ((matched_axis == 'Y') && (foc_sign == 1)) + { + rslt = accel_foc_report(avg_accel_foc_data.y, + (int16_t)(reference * (-1)), + foc_sign, + (int16_t)(min_val * (-1)), + (int16_t)(max_val * (-1))); + printf("Range : %u Avg_FOC-X : %d Reference : %d Min_Value : %d Max_Value : %d\n", + range, + avg_accel_foc_data.y, + (reference * (-1)), + (min_val * (-1)), + (max_val * (-1))); + } + else if ((matched_axis == 'Z') && (foc_sign == 1)) + { + rslt = accel_foc_report(avg_accel_foc_data.z, + (int16_t)(reference * (-1)), + foc_sign, + (int16_t)(min_val * (-1)), + (int16_t)(max_val * (-1))); + printf("Range : %u Avg_FOC-X : %d Reference : %d Min_Value : %d Max_Value : %d\n", + range, + avg_accel_foc_data.z, + (reference * (-1)), + (min_val * (-1)), + (max_val * (-1))); + } + + return rslt; +} + +/* Perform FOC for different range and resolutions */ +static int8_t perform_foc_range_test(uint8_t range, uint8_t input_axis, struct bma4_dev *dev) +{ + int8_t rslt; + int8_t matched_axis = 0; + int16_t reference = 0; + + /* Set accel foc axis and it's sign (x, y, z, sign)*/ + struct bma4_accel_foc_g_value g_value_foc = { 0, 0, 0, 0 }; + + if (input_axis == 1) + { + g_value_foc.x = 1; + g_value_foc.y = 0; + g_value_foc.z = 0; + g_value_foc.sign = 0; + } + else if (input_axis == 2) + { + g_value_foc.x = 0; + g_value_foc.y = 1; + g_value_foc.z = 0; + g_value_foc.sign = 0; + } + else if (input_axis == 3) + { + g_value_foc.x = 0; + g_value_foc.y = 0; + g_value_foc.z = 1; + g_value_foc.sign = 0; + } + else if (input_axis == 4) + { + g_value_foc.x = 1; + g_value_foc.y = 0; + g_value_foc.z = 0; + g_value_foc.sign = 1; + } + else if (input_axis == 5) + { + g_value_foc.x = 0; + g_value_foc.y = 1; + g_value_foc.z = 0; + g_value_foc.sign = 1; + } + else if (input_axis == 6) + { + g_value_foc.x = 0; + g_value_foc.y = 0; + g_value_foc.z = 1; + g_value_foc.sign = 1; + } + + switch (range) + { + /* Reference LSB value of 2G */ + case 0: + reference = BMA4_16BIT_ACC_FOC_2G_REF; + break; + + /* Reference LSB value of 4G */ + case 1: + reference = BMA4_16BIT_ACC_FOC_4G_REF; + break; + + /* Reference LSB value of 8G */ + case 2: + reference = BMA4_16BIT_ACC_FOC_8G_REF; + break; + + /* Reference LSB value of 16G */ + case 3: + reference = BMA4_16BIT_ACC_FOC_16G_REF; + break; + default: + break; + } + + if (g_value_foc.x == 1) + { + matched_axis = 'X'; + } + else if (g_value_foc.y == 1) + { + matched_axis = 'Y'; + } + else if (g_value_foc.z == 1) + { + matched_axis = 'Z'; + } + + if (g_value_foc.sign == 1) + { + printf("MATCHED AXIS is = -%c\n", matched_axis); + } + else + { + printf("MATCHED AXIS is = %c\n", matched_axis); + } + + printf("\n\n# Before FOC\n"); + rslt = verify_accel_foc_data(range, reference, matched_axis, g_value_foc.sign, dev); + bma4_error_codes_print_result("bma4_perform_accel_foc", rslt); + + printf("\n\n######### Perform Accel FOC #########\n\n"); + + /* Perform accelerometer FOC */ + rslt = bma4_perform_accel_foc(&g_value_foc, dev); + bma4_error_codes_print_result("bma4_perform_accel_foc", rslt); + + /* Delay after performing Accel FOC */ + dev->delay_us(30000, dev->intf_ptr); + + printf("\n\n# After FOC\n"); + rslt = verify_accel_foc_data(range, reference, matched_axis, g_value_foc.sign, dev); + + return rslt; +} diff --git a/components/bma456/bma456h_examples/accelerometer/Makefile b/components/bma456/bma456h_examples/accelerometer/Makefile new file mode 100644 index 0000000..dc1ba59 --- /dev/null +++ b/components/bma456/bma456h_examples/accelerometer/Makefile @@ -0,0 +1,18 @@ +COINES_INSTALL_PATH ?= ../../../.. + +EXAMPLE_FILE ?= accelerometer.c + +API_LOCATION ?= ../.. + +COMMON_LOCATION ?= .. + +C_SRCS += \ +$(API_LOCATION)/bma4.c \ +$(API_LOCATION)/bma456h.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/components/bma456/bma456h_examples/accelerometer/accelerometer.c b/components/bma456/bma456h_examples/accelerometer/accelerometer.c new file mode 100644 index 0000000..7d9ab86 --- /dev/null +++ b/components/bma456/bma456h_examples/accelerometer/accelerometer.c @@ -0,0 +1,162 @@ +/**\ + * Copyright (c) 2022 Bosch Sensortec GmbH. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + **/ + +#include +#include "bma456h.h" +#include "common.h" + +/******************************************************************************/ +/*! Macro definition */ + +/*! Earth's gravity in m/s^2 */ +#define GRAVITY_EARTH (9.80665f) + +/*! Macro that holds the total number of accel x,y and z axes sample counts to be printed */ +#define ACCEL_SAMPLE_COUNT UINT8_C(100) + +/******************************************************************************/ +/*! 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); + +/******************************************************************************/ +/*! Functions */ + +/* This function starts the execution of program. */ +int main(void) +{ + /* Variable to store the status of API */ + int8_t rslt; + + /* Sensor initialization configuration */ + struct bma4_dev bma = { 0 }; + + /* Variable to store accel data ready interrupt status */ + uint16_t int_status = 0; + + /* Variable that holds the accelerometer sample count */ + uint8_t n_data = 1; + + struct bma4_accel sens_data = { 0 }; + float x = 0, y = 0, z = 0; + struct bma4_accel_config accel_conf = { 0 }; + + /* Interface reference is given as a parameter + * For I2C : BMA4_I2C_INTF + * For SPI : BMA4_SPI_INTF + * Variant information given as parameter - BMA45X_VARIANT + */ + rslt = bma4_interface_init(&bma, BMA4_I2C_INTF, BMA45X_VARIANT); + bma4_error_codes_print_result("bma4_interface_init", rslt); + + /* Sensor initialization */ + rslt = bma456h_init(&bma); + bma4_error_codes_print_result("bma456h_init status", rslt); + + /* Upload the configuration file to enable the features of the sensor. */ + rslt = bma456h_write_config_file(&bma); + bma4_error_codes_print_result("bma456h_write_config status", rslt); + + /* Mapping data ready interrupt with interrupt pin 1 to get interrupt status once getting new accel data */ + rslt = bma456h_map_interrupt(BMA4_INTR1_MAP, BMA4_DATA_RDY_INT, BMA4_ENABLE, &bma); + bma4_error_codes_print_result("bma456h_map_interrupt status", rslt); + + /* Accelerometer configuration settings */ + /* Output data Rate */ + accel_conf.odr = BMA4_OUTPUT_DATA_RATE_50HZ; + + /* Gravity range of the sensor (+/- 2G, 4G, 8G, 16G) */ + accel_conf.range = BMA4_ACCEL_RANGE_2G; + + /* The bandwidth parameter is used to configure the number of sensor samples that are averaged + * if it is set to 2, then 2^(bandwidth parameter) samples + * are averaged, resulting in 4 averaged samples + * Note1 : For more information, refer the datasheet. + * Note2 : A higher number of averaged samples will result in a less noisier signal, but + * this has an adverse effect on the power consumed. + */ + accel_conf.bandwidth = BMA4_ACCEL_NORMAL_AVG4; + + /* Enable the filter performance mode where averaging of samples + * will be done based on above set bandwidth and ODR. + * There are two modes + * 0 -> Averaging samples (Default) + * 1 -> No averaging + * For more info on No Averaging mode refer datasheet. + */ + accel_conf.perf_mode = BMA4_CIC_AVG_MODE; + + /* Set the accel configurations */ + rslt = bma4_set_accel_config(&accel_conf, &bma); + bma4_error_codes_print_result("bma4_set_accel_config status", rslt); + + /* NOTE : Enable accel after set of configurations */ + rslt = bma4_set_accel_enable(BMA4_ENABLE, &bma); + bma4_error_codes_print_result("bma4_set_accel_enable status", rslt); + + printf("Data, Acc_Raw_X, Acc_Raw_Y, Acc_Raw_Z, Acc_ms2_X, Acc_ms2_Y, Acc_ms2_Z\n"); + + for (;;) + { + /* Read interrupt status */ + rslt = bma456h_read_int_status(&int_status, &bma); + bma4_error_codes_print_result("bma456h_read_int_status", rslt); + + /* Filtering only the accel data ready interrupt */ + if ((rslt == BMA4_OK) && (int_status & BMA4_ACCEL_DATA_RDY_INT)) + { + /* Read the accel x, y, z data */ + rslt = bma4_read_accel_xyz(&sens_data, &bma); + bma4_error_codes_print_result("bma4_read_accel_xyz status", rslt); + + if (rslt == BMA4_OK) + { + + /* Converting lsb to meter per second squared for 16 bit resolution at 2G range */ + x = lsb_to_ms2(sens_data.x, (float)2, bma.resolution); + y = lsb_to_ms2(sens_data.y, (float)2, bma.resolution); + z = lsb_to_ms2(sens_data.z, (float)2, bma.resolution); + + /* Print the data in m/s2 */ + printf("%d, %d, %d, %d, %4.2f, %4.2f, %4.2f\n", n_data, sens_data.x, sens_data.y, sens_data.z, x, y, z); + } + + /* Increment the count that determines the number of samples to be printed */ + n_data++; + + /* When the count reaches more than ACCEL_SAMPLE_COUNT, break and exit the loop */ + if (n_data > ACCEL_SAMPLE_COUNT) + { + break; + } + } + } + + bma4_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/components/bma456/bma456h_examples/auto_low_power/Makefile b/components/bma456/bma456h_examples/auto_low_power/Makefile new file mode 100644 index 0000000..e8a5f9d --- /dev/null +++ b/components/bma456/bma456h_examples/auto_low_power/Makefile @@ -0,0 +1,18 @@ +COINES_INSTALL_PATH ?= ../../../.. + +EXAMPLE_FILE ?= auto_low_power.c + +API_LOCATION ?= ../.. + +COMMON_LOCATION ?= .. + +C_SRCS += \ +$(API_LOCATION)/bma4.c \ +$(API_LOCATION)/bma456h.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/components/bma456/bma456h_examples/auto_low_power/auto_low_power.c b/components/bma456/bma456h_examples/auto_low_power/auto_low_power.c new file mode 100644 index 0000000..15a4d31 --- /dev/null +++ b/components/bma456/bma456h_examples/auto_low_power/auto_low_power.c @@ -0,0 +1,146 @@ +/**\ + * Copyright (c) 2022 Bosch Sensortec GmbH. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + **/ + +#include +#include "bma456h.h" +#include "common.h" + +/******************************************************************************/ +/*! Function */ + +/* This function starts the execution of program. */ +int main(void) +{ + /* Variable to store the status of API */ + int8_t rslt; + + /* Sensor initialization configuration */ + struct bma4_dev bma = { 0 }; + + /* Variable to store auto low power state */ + uint8_t auto_low_power_state = 0; + + struct bma4_accel_config accel_conf = { 0 }; + struct bma456h_auto_low_power auto_low_power = { 0 }; + + /* Interface reference is given as a parameter + * For I2C : BMA4_I2C_INTF + * For SPI : BMA4_SPI_INTF + * Variant information given as parameter - BMA45X_VARIANT + */ + rslt = bma4_interface_init(&bma, BMA4_SPI_INTF, BMA45X_VARIANT); + bma4_error_codes_print_result("bma4_interface_init", rslt); + + /* Sensor initialization */ + rslt = bma456h_init(&bma); + bma4_error_codes_print_result("bma456h_init status", rslt); + + /* Upload the configuration file to enable the features of the sensor. */ + rslt = bma456h_write_config_file(&bma); + bma4_error_codes_print_result("bma456h_write_config status", rslt); + + /* Get the accel configurations */ + rslt = bma4_get_accel_config(&accel_conf, &bma); + bma4_error_codes_print_result("bma4_get_accel_config status", rslt); + + if (rslt == BMA4_OK) + { + /* Accelerometer configuration settings */ + /* Output data Rate */ + accel_conf.odr = BMA4_OUTPUT_DATA_RATE_100HZ; + + /* Gravity range of the sensor (+/- 2G, 4G, 8G, 16G) */ + accel_conf.range = BMA4_ACCEL_RANGE_2G; + + /* The bandwidth parameter is used to configure the number of sensor samples that are averaged + * if it is set to 2, then 2^(bandwidth parameter) samples + * are averaged, resulting in 4 averaged samples + * Note1 : For more information, refer the datasheet. + * Note2 : A higher number of averaged samples will result in a less noisier signal, but + * this has an adverse effect on the power consumed. + */ + accel_conf.bandwidth = BMA4_ACCEL_NORMAL_AVG4; + + /* Enable the filter performance mode where averaging of samples + * will be done based on above set bandwidth and ODR. + * There are two modes + * 0 -> Averaging samples (Default) + * 1 -> No averaging + * For more info on No Averaging mode refer datasheet. + */ + accel_conf.perf_mode = BMA4_CIC_AVG_MODE; + + /* Set the accel configurations */ + rslt = bma4_set_accel_config(&accel_conf, &bma); + bma4_error_codes_print_result("bma4_set_accel_config status", rslt); + + /* NOTE : Enable accel after set of configurations */ + rslt = bma4_set_accel_enable(BMA4_ENABLE, &bma); + bma4_error_codes_print_result("bma4_set_accel_enable status", rslt); + + if (rslt == BMA4_OK) + { + /* Enable auto low power state through no-motion interrupt */ + auto_low_power.no_motion = 0; + + /* Enable auto low power state through time-out duration */ + auto_low_power.time_out = 1; + + /* Time-out duration is (value * resolution) eg: (10 * 20ms) */ + auto_low_power.time_out_dur = 10; + + /* These bits used to set odr at auto low power mode. default + * value is '0'(i.e) 25/16 HZ */ + auto_low_power.lp_odr = 0; + + /* Set this bit to set default odr of titan core in auto low power mode */ + auto_low_power.pwr_mgt = 1; + + /* Configure Auto low power settings */ + rslt = bma456h_set_auto_low_power_config(&auto_low_power, &bma); + bma4_error_codes_print_result("bma456h_set_auto_low_power_config status", rslt); + + if (rslt == BMA4_OK) + { + /* Get output of auto low power state */ + rslt = bma456h_get_auto_low_power_state(&auto_low_power_state, &bma); + bma4_error_codes_print_result("bma456h_get_auto_low_power_state status", rslt); + } + } + } + + if (rslt == BMA4_OK) + { + /* Enable auto low power feature */ + rslt = bma456h_feature_enable(BMA456H_AUTO_LOW_POWER_EN, BMA4_ENABLE, &bma); + bma4_error_codes_print_result("bma456h_feature_enable status", rslt); + } + + if (rslt == BMA4_OK) + { + /* Read and check the ODR change after changing the auto low power settings */ + rslt = bma4_get_accel_config(&accel_conf, &bma); + bma4_error_codes_print_result("bma4_get_accel_config status", rslt); + + if (rslt == BMA4_OK) + { + printf("ODR : %X\n", accel_conf.odr); + + if (auto_low_power_state) + { + printf("Auto low power state : Disabled(Auto wake state)"); + } + else + { + printf("Auto low power state : Enabled(Auto sleep state)"); + } + } + } + + bma4_coines_deinit(); + + return rslt; +} diff --git a/components/bma456/bma456h_examples/axis_remap/Makefile b/components/bma456/bma456h_examples/axis_remap/Makefile new file mode 100644 index 0000000..0fc5c88 --- /dev/null +++ b/components/bma456/bma456h_examples/axis_remap/Makefile @@ -0,0 +1,18 @@ +COINES_INSTALL_PATH ?= ../../../.. + +EXAMPLE_FILE = axis_remap.c + +API_LOCATION ?= ../.. + +COMMON_LOCATION ?= .. + +C_SRCS += \ +$(API_LOCATION)/bma4.c \ +$(API_LOCATION)/bma456h.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/components/bma456/bma456h_examples/axis_remap/axis_remap.c b/components/bma456/bma456h_examples/axis_remap/axis_remap.c new file mode 100644 index 0000000..048e191 --- /dev/null +++ b/components/bma456/bma456h_examples/axis_remap/axis_remap.c @@ -0,0 +1,362 @@ +/**\ + * Copyright (c) 2022 Bosch Sensortec GmbH. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + **/ + +#include +#include + +#include "coines.h" +#include "bma456h.h" +#include "common.h" + +/*********************************************************************/ +/* functions */ +/*********************************************************************/ + +/*! + * @brief Main Function where the execution getting started to test the code. + * + * @param[in] argc + * @param[in] argv + * + * @return status + * + */ +int main(void) +{ + int8_t rslt; + struct bma4_dev bma4; + uint16_t int_status = 0; + struct bma4_remap remap_data = { 0 }; + struct bma4_accel accel = { 0 }; + struct bma4_accel_config accel_conf = { 0 }; + + char data_array[13][11] = + { { 0 }, { "BMA4_X" }, { "BMA4_Y" }, { 0 }, { "BMA4_Z" }, { 0 }, { 0 }, { 0 }, { 0 }, { "BMA4_NEG_X" }, + { "BMA4_NEG_Y" }, { 0 }, { "BMA4_NEG_Z" } }; + + /* Interface reference is given as a parameter + * For I2C : BMA4_I2C_INTF + * For SPI : BMA4_SPI_INTF + * Variant information given as parameter - BMA45X_VARIANT + */ + rslt = bma4_interface_init(&bma4, BMA4_I2C_INTF, BMA45X_VARIANT); + bma4_error_codes_print_result("bma4_interface_init", rslt); + + /* Sensor initialization */ + rslt = bma456h_init(&bma4); + bma4_error_codes_print_result("bma456h_init", rslt); + + /* Upload the configuration file to enable the features of the sensor. */ + rslt = bma456h_write_config_file(&bma4); + bma4_error_codes_print_result("bma456h_write_config", rslt); + + /* Accelerometer configuration Setting */ + /* Output data Rate */ + accel_conf.odr = BMA4_OUTPUT_DATA_RATE_50HZ; + + /* Gravity range of the sensor (+/- 2G, 4G, 8G, 16G) */ + accel_conf.range = BMA4_ACCEL_RANGE_2G; + + /* The bandwidth parameter is used to configure the number of sensor samples that are averaged + * if it is set to 2, then 2^(bandwidth parameter) samples + * are averaged, resulting in 4 averaged samples + * Note1 : For more information, refer the datasheet. + * Note2 : A higher number of averaged samples will result in a less noisier signal, but + * this has an adverse effect on the power consumed. + */ + accel_conf.bandwidth = BMA4_ACCEL_NORMAL_AVG4; + + /* Enable the filter performance mode where averaging of samples + * will be done based on above set bandwidth and ODR. + * There are two modes + * 0 -> Averaging samples (Default) + * 1 -> No averaging + * For more info on No Averaging mode refer datasheet. + */ + accel_conf.perf_mode = BMA4_CIC_AVG_MODE; + + /* Set the accel configurations */ + rslt = bma4_set_accel_config(&accel_conf, &bma4); + bma4_error_codes_print_result("bma4_set_accel_config status", rslt); + + /* NOTE : Enable accel after set of configurations */ + rslt = bma4_set_accel_enable(BMA4_ENABLE, &bma4); + bma4_error_codes_print_result("bma4_set_accel_enable status", rslt); + + /* Mapping data ready interrupt with interrupt pin 1 to get interrupt status once getting new accel data */ + rslt = bma456h_map_interrupt(BMA4_INTR1_MAP, BMA4_DATA_RDY_INT, BMA4_ENABLE, &bma4); + bma4_error_codes_print_result("bma456h_map_interrupt status", rslt); + + printf("\nAXIS_REMAP_FUNC_TEST 1\n"); + printf("Get sensor data of re-mapped axes\n"); + + rslt = bma456h_get_remap_axes(&remap_data, &bma4); + bma4_error_codes_print_result("bma456h_get_remap_axes", rslt); + + printf("Re-mapped x value = %s\n", data_array[remap_data.x]); + printf("Re-mapped y value = %s\n", data_array[remap_data.y]); + printf("Re-mapped z value = %s\n", data_array[remap_data.z]); + + printf("Expected Re-mapped x value = BMA4_X\n"); + printf("Expected Re-mapped y value = BMA4_Y\n"); + printf("Expected Re-mapped z value = BMA4_Z\n"); + + if ((remap_data.x == BMA4_X) && (remap_data.y == BMA4_Y) && (remap_data.z == BMA4_Z)) + { + printf(">> PASS\n"); + } + else + { + printf(">> FAIL\n"); + } + + printf("Print mapped data\n"); + + for (;;) + { + /* Read interrupt status */ + rslt = bma456h_read_int_status(&int_status, &bma4); + bma4_error_codes_print_result("bma456_read_int_status", rslt); + + /* Filtering only the accel data ready interrupt */ + if ((rslt == BMA4_OK) && (int_status & BMA4_ACCEL_DATA_RDY_INT)) + { + rslt = bma4_read_accel_xyz(&accel, &bma4); + bma4_error_codes_print_result("bma4_read_accel_xyz", rslt); + + printf("Accel :: X = %d Y = %d Z = %d\n", accel.x, accel.y, accel.z); + + break; + } + } + + printf("\nAXIS_REMAP_FUNC_TEST 2\n"); + printf("Get sensor data of re-mapped axes\n"); + + remap_data.x = BMA4_NEG_Y; + remap_data.y = BMA4_Z; + remap_data.z = BMA4_NEG_X; + + rslt = bma456h_set_remap_axes(&remap_data, &bma4); + bma4_error_codes_print_result("bma456h_set_remap_axes", rslt); + + if (rslt == BMA4_OK) + { + rslt = bma456h_get_remap_axes(&remap_data, &bma4); + bma4_error_codes_print_result("bma456h_get_remap_axes", rslt); + + if (rslt == BMA4_OK) + { + printf("Re-mapped x value = %s\n", data_array[remap_data.x]); + printf("Re-mapped y value = %s\n", data_array[remap_data.y]); + printf("Re-mapped z value = %s\n", data_array[remap_data.z]); + } + + printf("Expected Re-mapped x value = BMA4_NEG_Y\n"); + printf("Expected Re-mapped y value = BMA4_Z\n"); + printf("Expected Re-mapped z value = BMA4_NEG_X\n"); + + if ((remap_data.x == BMA4_NEG_Y) && (remap_data.y == BMA4_Z) && (remap_data.z == BMA4_NEG_X)) + { + printf(">> PASS\n"); + } + else + { + printf(">> FAIL\n"); + } + } + + printf("Print mapped data\n"); + + for (;;) + { + /* Read interrupt status */ + rslt = bma456h_read_int_status(&int_status, &bma4); + bma4_error_codes_print_result("bma456_read_int_status", rslt); + + /* Filtering only the accel data ready interrupt */ + if ((rslt == BMA4_OK) && (int_status & BMA4_ACCEL_DATA_RDY_INT)) + { + rslt = bma4_read_accel_xyz(&accel, &bma4); + bma4_error_codes_print_result("bma4_read_accel_xyz", rslt); + + printf("Accel :: X = %d Y = %d Z = %d\n", accel.x, accel.y, accel.z); + + break; + } + } + + printf("\nAXIS_REMAP_FUNC_TEST 3\n"); + printf("Get sensor data of re-mapped axes - 2nd combination\n"); + + remap_data.x = BMA4_NEG_Z; + remap_data.y = BMA4_NEG_X; + remap_data.z = BMA4_Y; + + rslt = bma456h_set_remap_axes(&remap_data, &bma4); + bma4_error_codes_print_result("bma456h_set_remap_axes", rslt); + + if (rslt == BMA4_OK) + { + rslt = bma456h_get_remap_axes(&remap_data, &bma4); + bma4_error_codes_print_result("bma456h_get_remap_axes", rslt); + + if (rslt == BMA4_OK) + { + printf("Re-mapped x value = %s\n", data_array[remap_data.x]); + printf("Re-mapped y value = %s\n", data_array[remap_data.y]); + printf("Re-mapped z value = %s\n", data_array[remap_data.z]); + } + + printf("Expected Re-mapped x value = BMA4_NEG_Z\n"); + printf("Expected Re-mapped y value = BMA4_NEG_X\n"); + printf("Expected Re-mapped z value = BMA4_Y\n"); + + if ((remap_data.x == BMA4_NEG_Z) && (remap_data.y == BMA4_NEG_X) && (remap_data.z == BMA4_Y)) + { + printf(">> PASS\n"); + } + else + { + printf(">> FAIL\n"); + } + } + + printf("Print mapped data\n"); + + for (;;) + { + /* Read interrupt status */ + rslt = bma456h_read_int_status(&int_status, &bma4); + bma4_error_codes_print_result("bma456_read_int_status", rslt); + + /* Filtering only the accel data ready interrupt */ + if ((rslt == BMA4_OK) && (int_status & BMA4_ACCEL_DATA_RDY_INT)) + { + rslt = bma4_read_accel_xyz(&accel, &bma4); + bma4_error_codes_print_result("bma4_read_accel_xyz", rslt); + + printf("Accel :: X = %d Y = %d Z = %d\n", accel.x, accel.y, accel.z); + + break; + } + } + + printf("\nAXIS_REMAP_FUNC_TEST 4\n"); + printf("Get sensor data of re-mapped axes - 3rd combination\n"); + + remap_data.x = BMA4_Y; + remap_data.y = BMA4_Z; + remap_data.z = BMA4_X; + + rslt = bma456h_set_remap_axes(&remap_data, &bma4); + bma4_error_codes_print_result("bma456h_set_remap_axes", rslt); + if (rslt == BMA4_OK) + { + rslt = bma456h_get_remap_axes(&remap_data, &bma4); + bma4_error_codes_print_result("bma456h_get_remap_axes", rslt); + + if (rslt == BMA4_OK) + { + printf("Re-mapped x value = %s\n", data_array[remap_data.x]); + printf("Re-mapped y value = %s\n", data_array[remap_data.y]); + printf("Re-mapped z value = %s\n", data_array[remap_data.z]); + } + + printf("Expected Re-mapped x value = BMA4_Y\n"); + printf("Expected Re-mapped y value = BMA4_Z\n"); + printf("Expected Re-mapped z value = BMA4_X\n"); + + if ((remap_data.x == BMA4_Y) && (remap_data.y == BMA4_Z) && (remap_data.z == BMA4_X)) + { + printf(">> PASS\n"); + } + else + { + printf(">> FAIL\n"); + } + } + + printf("Print mapped data\n"); + + for (;;) + { + /* Read interrupt status */ + rslt = bma456h_read_int_status(&int_status, &bma4); + bma4_error_codes_print_result("bma456_read_int_status", rslt); + + /* Filtering only the accel data ready interrupt */ + if ((rslt == BMA4_OK) && (int_status & BMA4_ACCEL_DATA_RDY_INT)) + { + rslt = bma4_read_accel_xyz(&accel, &bma4); + bma4_error_codes_print_result("bma4_read_accel_xyz", rslt); + + printf("Accel :: X = %d Y = %d Z = %d\n", accel.x, accel.y, accel.z); + + break; + } + } + + printf("\nAXIS_REMAP_FUNC_TEST 5\n"); + printf("Get sensor data of re-mapped axes - 4th combination\n"); + + remap_data.x = BMA4_NEG_X; + remap_data.y = BMA4_NEG_Y; + remap_data.z = BMA4_NEG_Z; + + rslt = bma456h_set_remap_axes(&remap_data, &bma4); + bma4_error_codes_print_result("bma456h_set_remap_axes", rslt); + + if (rslt == BMA4_OK) + { + rslt = bma456h_get_remap_axes(&remap_data, &bma4); + bma4_error_codes_print_result("bma456h_get_remap_axes", rslt); + + if (rslt == BMA4_OK) + { + printf("Re-mapped x value = %s\n", data_array[remap_data.x]); + printf("Re-mapped y value = %s\n", data_array[remap_data.y]); + printf("Re-mapped z value = %s\n", data_array[remap_data.z]); + } + + printf("Expected Re-mapped x value = BMA4_NEG_X\n"); + printf("Expected Re-mapped y value = BMA4_NEG_Y\n"); + printf("Expected Re-mapped z value = BMA4_NEG_Z\n"); + + if ((remap_data.x == BMA4_NEG_X) && (remap_data.y == BMA4_NEG_Y) && (remap_data.z == BMA4_NEG_Z)) + { + printf(">> PASS\n"); + } + else + { + printf(">> FAIL\n"); + } + } + + printf("Print mapped data\n"); + + for (;;) + { + /* Read interrupt status */ + rslt = bma456h_read_int_status(&int_status, &bma4); + bma4_error_codes_print_result("bma456_read_int_status", rslt); + + /* Filtering only the accel data ready interrupt */ + if ((rslt == BMA4_OK) && (int_status & BMA4_ACCEL_DATA_RDY_INT)) + { + rslt = bma4_read_accel_xyz(&accel, &bma4); + bma4_error_codes_print_result("bma4_read_accel_xyz", rslt); + + printf("Accel :: X = %d Y = %d Z = %d\n", accel.x, accel.y, accel.z); + + break; + } + } + + bma4_coines_deinit(); + + return rslt; +} diff --git a/components/bma456/bma456h_examples/common/common.c b/components/bma456/bma456h_examples/common/common.c new file mode 100644 index 0000000..ca1e7c9 --- /dev/null +++ b/components/bma456/bma456h_examples/common/common.c @@ -0,0 +1,242 @@ +/** + * Copyright (C) 2023 Bosch Sensortec GmbH. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include + +#include "bma4_defs.h" +#include "common.h" + +/******************************************************************************/ +/*! Macro definitions */ + +/*! Read write length varies based on user requirement */ +#define BMA4_READ_WRITE_LEN UINT8_C(46) + +/******************************************************************************/ +/*! Static variable definition */ + +/*! Variable that holds the I2C device address or SPI chip selection */ +static uint8_t dev_addr; + +/******************************************************************************/ +/*! User interface functions */ + +/*! + * I2C read function map to COINES platform + */ +BMA4_INTF_RET_TYPE bma4_i2c_read(uint8_t reg_addr, uint8_t *reg_data, uint32_t len, void *intf_ptr) +{ + uint8_t dev_address = *(uint8_t*)intf_ptr; + + (void)intf_ptr; + + return coines_read_i2c(COINES_I2C_BUS_0, dev_address, reg_addr, reg_data, (uint16_t)len); +} + +/*! + * I2C write function map to COINES platform + */ +BMA4_INTF_RET_TYPE bma4_i2c_write(uint8_t reg_addr, const uint8_t *reg_data, uint32_t len, void *intf_ptr) +{ + uint8_t dev_address = *(uint8_t*)intf_ptr; + + (void)intf_ptr; + + return coines_write_i2c(COINES_I2C_BUS_0, dev_address, reg_addr, (uint8_t *)reg_data, (uint16_t)len); +} + +/*! + * SPI read function map to COINES platform + */ +BMA4_INTF_RET_TYPE bma4_spi_read(uint8_t reg_addr, uint8_t *reg_data, uint32_t len, void *intf_ptr) +{ + uint8_t dev_address = *(uint8_t*)intf_ptr; + + (void)intf_ptr; + + return coines_read_spi(COINES_SPI_BUS_0, dev_address, reg_addr, reg_data, (uint16_t)len); +} + +/*! + * SPI write function map to COINES platform + */ +BMA4_INTF_RET_TYPE bma4_spi_write(uint8_t reg_addr, const uint8_t *reg_data, uint32_t len, void *intf_ptr) +{ + uint8_t dev_address = *(uint8_t*)intf_ptr; + + (void)intf_ptr; + + return coines_write_spi(COINES_SPI_BUS_0, dev_address, reg_addr, (uint8_t *)reg_data, (uint16_t)len); +} + +/*! + * Delay function map to COINES platform + */ +void bma4_delay_us(uint32_t period, void *intf_ptr) +{ + (void) intf_ptr; + coines_delay_usec(period); +} + +/*! + * @brief Function to select the interface between SPI and I2C. + * Also to initialize coines platform + */ +int8_t bma4_interface_init(struct bma4_dev *bma, uint8_t intf, enum bma4_variant variant) +{ + int8_t rslt = BMA4_OK; + + if (bma != NULL) + { + int16_t result = coines_open_comm_intf(COINES_COMM_INTF_USB, NULL); + struct coines_board_info board_info; + if (result < COINES_SUCCESS) + { + printf( + "\n Unable to connect with Application Board ! \n" " 1. Check if the board is connected and powered on. \n" " 2. Check if Application Board USB driver is installed. \n" + " 3. Check if board is in use by another application. (Insufficient permissions to access USB) \n"); + exit(result); + } + + result = coines_get_board_info(&board_info); + + #if defined(PC) + setbuf(stdout, NULL); + #endif + + (void)coines_set_shuttleboard_vdd_vddio_config(0, 0); + coines_delay_usec(10000); + + /* Bus configuration : I2C */ + if (intf == BMA4_I2C_INTF) + { + printf("I2C Interface \n"); + + /* To initialize the user I2C function */ + dev_addr = BMA4_I2C_ADDR_PRIMARY; + bma->intf = BMA4_I2C_INTF; + bma->bus_read = bma4_i2c_read; + bma->bus_write = bma4_i2c_write; + + /* SDO to Ground */ + (void)coines_set_pin_config(COINES_SHUTTLE_PIN_22, COINES_PIN_DIRECTION_OUT, COINES_PIN_VALUE_LOW); + + /* Make CSB pin HIGH */ + (void)coines_set_pin_config(COINES_SHUTTLE_PIN_21, COINES_PIN_DIRECTION_OUT, COINES_PIN_VALUE_HIGH); + coines_delay_msec(100); + + /* SDO pin is made low */ + (void)coines_set_pin_config(COINES_SHUTTLE_PIN_SDO, COINES_PIN_DIRECTION_OUT, COINES_PIN_VALUE_LOW); + + (void)coines_config_i2c_bus(COINES_I2C_BUS_0, COINES_I2C_STANDARD_MODE); + } + /* Bus configuration : SPI */ + else if (intf == BMA4_SPI_INTF) + { + printf("SPI Interface \n"); + + /* To initialize the user SPI function */ + dev_addr = COINES_SHUTTLE_PIN_7; + bma->intf = BMA4_SPI_INTF; + bma->bus_read = bma4_spi_read; + bma->bus_write = bma4_spi_write; + (void)coines_config_spi_bus(COINES_SPI_BUS_0, COINES_SPI_SPEED_7_5_MHZ, COINES_SPI_MODE0); + } + + /* Assign variant information */ + bma->variant = variant; + + /* Assign device address to interface pointer */ + bma->intf_ptr = &dev_addr; + + /* Configure delay in microseconds */ + bma->delay_us = bma4_delay_us; + + /* Configure max read/write length (in bytes) ( Supported length depends on target machine) */ + bma->read_write_len = BMA4_READ_WRITE_LEN; + + /* Set Performance mode status */ + bma->perf_mode_status = BMA4_DISABLE; + + coines_delay_msec(100); + + (void)coines_set_shuttleboard_vdd_vddio_config(3300, 3300); + + coines_delay_msec(200); + } + else + { + rslt = BMA4_E_NULL_PTR; + } + + return rslt; + +} + +/*! + * @brief Prints the execution status of the APIs. + */ +void bma4_error_codes_print_result(const char api_name[], int8_t rslt) +{ + if (rslt != BMA4_OK) + { + printf("%s\t", api_name); + if (rslt == BMA4_E_NULL_PTR) + { + printf("Error [%d] : Null pointer\r\n", rslt); + } + else if (rslt == BMA4_E_COM_FAIL) + { + printf("Error [%d] : Communication failure\r\n", rslt); + } + else if (rslt == BMA4_E_CONFIG_STREAM_ERROR) + { + printf("Error [%d] : Invalid configuration stream\r\n", rslt); + } + else if (rslt == BMA4_E_SELF_TEST_FAIL) + { + printf("Error [%d] : Self test failed\r\n", rslt); + } + else if (rslt == BMA4_E_INVALID_SENSOR) + { + printf("Error [%d] : Device not found\r\n", rslt); + } + else if (rslt == BMA4_E_OUT_OF_RANGE) + { + printf("Error [%d] : Out of Range\r\n", rslt); + } + else if (rslt == BMA4_E_AVG_MODE_INVALID_CONF) + { + printf("Error [%d] : Invalid bandwidth and ODR combination in Accel Averaging mode\r\n", rslt); + } + else + { + /* For more error codes refer "*_defs.h" */ + printf("Error [%d] : Unknown error code\r\n", rslt); + } + } +} + +/*! + * @brief Deinitializes coines platform + * + * @return void. + */ +void bma4_coines_deinit(void) +{ + (void)fflush(stdout); + coines_delay_msec(200); + + (void)coines_set_shuttleboard_vdd_vddio_config(0, 0); + coines_delay_msec(1000); + + /* Coines interface reset */ + coines_soft_reset(); + coines_delay_msec(1000); + (void)coines_close_comm_intf(COINES_COMM_INTF_USB, NULL); +} diff --git a/components/bma456/bma456h_examples/common/common.h b/components/bma456/bma456h_examples/common/common.h new file mode 100644 index 0000000..75c53f4 --- /dev/null +++ b/components/bma456/bma456h_examples/common/common.h @@ -0,0 +1,127 @@ +/**\ + * Copyright (c) 2023 Bosch Sensortec GmbH. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + **/ + +#ifndef COMMON_H +#define COMMON_H + +/*! CPP guard */ +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include "bma4.h" +#include "coines.h" + +/*! + * @brief Function for reading the sensor's registers through I2C bus. + * + * @param[in] reg_addr : Register address. + * @param[out] reg_data : Pointer to the data buffer to store the read data. + * @param[in] length : No of bytes to read. + * @param[in] intf_ptr : Interface pointer + * + * @return Status of execution + * @retval = BMA4_INTF_RET_SUCCESS -> Success + * @retval != BMA4_INTF_RET_SUCCESS -> Failure Info + * + */ +BMA4_INTF_RET_TYPE bma4_i2c_read(uint8_t reg_addr, uint8_t *reg_data, uint32_t len, void *intf_ptr); + +/*! + * @brief Function for writing the sensor's registers through I2C bus. + * + * @param[in] reg_addr : Register address. + * @param[in] reg_data : Pointer to the data buffer whose value is to be written. + * @param[in] length : No of bytes to write. + * @param[in] intf_ptr : Interface pointer + * + * @return Status of execution + * @retval = BMA4_INTF_RET_SUCCESS -> Success + * @retval != BMA4_INTF_RET_SUCCESS -> Failure Info + * + */ +BMA4_INTF_RET_TYPE bma4_i2c_write(uint8_t reg_addr, const uint8_t *reg_data, uint32_t len, void *intf_ptr); + +/*! + * @brief Function for reading the sensor's registers through SPI bus. + * + * @param[in] reg_addr : Register address. + * @param[out] reg_data : Pointer to the data buffer to store the read data. + * @param[in] length : No of bytes to read. + * @param[in] intf_ptr : Interface pointer + * + * @return Status of execution + * @retval = BMA4_INTF_RET_SUCCESS -> Success + * @retval != BMA4_INTF_RET_SUCCESS -> Failure Info + * + */ +BMA4_INTF_RET_TYPE bma4_spi_read(uint8_t reg_addr, uint8_t *reg_data, uint32_t len, void *intf_ptr); + +/*! + * @brief Function for writing the sensor's registers through SPI bus. + * + * @param[in] reg_addr : Register address. + * @param[in] reg_data : Pointer to the data buffer whose data has to be written. + * @param[in] length : No of bytes to write. + * @param[in] intf_ptr : Interface pointer + * + * @return Status of execution + * @retval = BMA4_INTF_RET_SUCCESS -> Success + * @retval != BMA4_INTF_RET_SUCCESS -> Failure Info + * + */ +BMA4_INTF_RET_TYPE bma4_spi_write(uint8_t reg_addr, const uint8_t *reg_data, uint32_t len, void *intf_ptr); + +/*! + * @brief This function provides the delay for required time (Microsecond) as per the input provided in some of the + * APIs. + * + * @param[in] period_us : The required wait time in microsecond. + * @param[in] intf_ptr : Interface pointer + * + * @return void. + * + */ +void bma4_delay_us(uint32_t period, void *intf_ptr); + +/*! + * @brief Function to select the interface between SPI and I2C. + * + * @param[in] bma : Structure instance of bma4_dev + * @param[in] intf : Interface selection parameter + * @param[in] variant : Variant information of the sensor + * ( BMA42x variants values - BMA42X_VARIANT / BMA42X_B_VARIANT ) + * ( BMA45x variants values - BMA45X_VARIANT ) + * + * @return Status of execution + * @retval 0 -> Success + * @retval < 0 -> Failure Info + */ +int8_t bma4_interface_init(struct bma4_dev *bma, uint8_t intf, enum bma4_variant variant); + +/*! + * @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 bma4_error_codes_print_result(const char api_name[], int8_t rslt); + +/*! + * @brief Deinitializes coines platform + * + * @return void. + */ +void bma4_coines_deinit(void); + +#ifdef __cplusplus +} +#endif /* End of CPP guard */ + +#endif /* COMMON_H */ diff --git a/components/bma456/bma456h_examples/fifo_full_header_mode/Makefile b/components/bma456/bma456h_examples/fifo_full_header_mode/Makefile new file mode 100644 index 0000000..a7cfd67 --- /dev/null +++ b/components/bma456/bma456h_examples/fifo_full_header_mode/Makefile @@ -0,0 +1,20 @@ +COINES_INSTALL_PATH ?= ../../../.. + +EXAMPLE_FILE ?= fifo_full_header_mode.c + +API_LOCATION ?= ../.. + +COMMON_LOCATION ?= .. + +C_SRCS += \ +$(API_LOCATION)/bma4.c \ +$(API_LOCATION)/bma456h.c \ +$(COMMON_LOCATION)/common/common.c + +INCLUDEPATHS += \ +$(API_LOCATION) \ +$(COMMON_LOCATION)/common + +TARGET=MCU_APP30 + +include $(COINES_INSTALL_PATH)/coines.mk \ No newline at end of file diff --git a/components/bma456/bma456h_examples/fifo_full_header_mode/fifo_full_header_mode.c b/components/bma456/bma456h_examples/fifo_full_header_mode/fifo_full_header_mode.c new file mode 100644 index 0000000..4120f11 --- /dev/null +++ b/components/bma456/bma456h_examples/fifo_full_header_mode/fifo_full_header_mode.c @@ -0,0 +1,173 @@ +/**\ + * Copyright (c) 2022 Bosch Sensortec GmbH. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + **/ + +#include +#include "bma456h.h" +#include "common.h" + +/******************************************************************************/ +/*! Macro definition */ + +/*! Buffer size allocated to store raw FIFO data */ +#define BMA456H_FIFO_RAW_DATA_BUFFER_SIZE UINT16_C(1024) + +/*! Length of data to be read from FIFO */ +#define BMA456H_FIFO_RAW_DATA_USER_LENGTH UINT16_C(1024) + +/*! Number of accel frames to be extracted from FIFO + * Calculation: + * fifo_buffer = 1024, accel_frame_len = 6, header_byte = 1. + * fifo_accel_frame_count = (1024 / (6 + 1)) = 147 frames + * + * Extra frames to parse sensortime data + */ +#define BMA456H_FIFO_ACCEL_FRAME_COUNT UINT8_C(170) + +/******************************************************************************/ +/*! Function */ + +/* This function starts the execution of program */ +int main(void) +{ + /* Status of API are returned to this variable */ + int8_t rslt; + + /* Accelerometer configuration structure */ + struct bma4_accel_config acc_conf = { 0 }; + + /* Sensor initialization configuration */ + struct bma4_dev dev = { 0 }; + + /* Number of accelerometer frames */ + uint16_t accel_length; + + /* Variable to idx bytes */ + uint16_t idx = 0; + + /* Variable to maintain count of loop to run FIFO read */ + uint8_t loop = 1; + + /* Number of bytes of FIFO data + * NOTE : Dummy byte (for SPI Interface) required for FIFO data read must be given as part of array size + */ + uint8_t fifo_data[BMA456H_FIFO_RAW_DATA_BUFFER_SIZE + BMA4_SENSORTIME_OVERHEAD_BYTE] = { 0 }; + + /* Array of accelerometer frames -> Total bytes = + * 147 * (6 axes bytes(+/- x,y,z) + 1 header byte) = 1029 bytes */ + struct bma4_accel fifo_accel_data[BMA456H_FIFO_ACCEL_FRAME_COUNT] = { { 0 } }; + + /* Initialize FIFO frame structure */ + struct bma4_fifo_frame fifoframe = { 0 }; + + /* Variable that contains interrupt status value */ + uint16_t int_status = 0; + + /* Variable to hold the length of FIFO data */ + uint16_t fifo_length = 0; + + /* Interface reference is given as a parameter + * For I2C : BMA4_I2C_INTF + * For SPI : BMA4_SPI_INTF + * Variant information given as parameter - BMA45X_VARIANT + */ + rslt = bma4_interface_init(&dev, BMA4_I2C_INTF, BMA45X_VARIANT); + bma4_error_codes_print_result("bma4_interface_init", rslt); + + /* Initialize BMA456H */ + rslt = bma456h_init(&dev); + bma4_error_codes_print_result("bma456h_init status", rslt); + + /* Accelerometer configuration settings */ + acc_conf.odr = BMA4_OUTPUT_DATA_RATE_100HZ; + acc_conf.bandwidth = BMA4_ACCEL_NORMAL_AVG4; + acc_conf.range = BMA4_ACCEL_RANGE_2G; + acc_conf.perf_mode = BMA4_CIC_AVG_MODE; + + /* Set the accel configurations */ + rslt = bma4_set_accel_config(&acc_conf, &dev); + bma4_error_codes_print_result("bma4_set_accel_config status", rslt); + + /* NOTE : Enable accel after set of configurations */ + rslt = bma4_set_accel_enable(BMA4_ENABLE, &dev); + bma4_error_codes_print_result("bma4_set_accel_enable status", rslt); + + /* Disabling advance power save mode as FIFO data is not accessible in advance low power mode */ + rslt = bma4_set_advance_power_save(BMA4_DISABLE, &dev); + bma4_error_codes_print_result("bma4_set_advance_power_save status", rslt); + + /* Clear FIFO configuration register */ + rslt = bma4_set_fifo_config(BMA4_FIFO_ALL, BMA4_DISABLE, &dev); + bma4_error_codes_print_result("bma4_set_fifo_config disable status", rslt); + + /* Set FIFO configuration by enabling accel. + * NOTE 1: The header mode is enabled by default. + * NOTE 2: By default the FIFO operating mode is FIFO mode. */ + rslt = bma4_set_fifo_config(BMA4_FIFO_ACCEL | BMA4_FIFO_HEADER | BMA4_FIFO_TIME, BMA4_ENABLE, &dev); + bma4_error_codes_print_result("bma4_set_fifo_config enable status", rslt); + + /* Update FIFO structure */ + fifoframe.data = fifo_data; + fifoframe.length = BMA456H_FIFO_RAW_DATA_USER_LENGTH + BMA4_SENSORTIME_OVERHEAD_BYTE; + + printf("FIFO is configured in header mode\n"); + + rslt = bma456h_map_interrupt(BMA4_INTR1_MAP, BMA4_FIFO_FULL_INT, BMA4_ENABLE, &dev); + bma4_error_codes_print_result("bma4_map_interrupt status", rslt); + + while (loop <= 10) + { + rslt = bma456h_read_int_status(&int_status, &dev); + bma4_error_codes_print_result("bma4_read_int_status", rslt); + + if ((rslt == BMA4_OK) && (int_status & BMA4_FIFO_FULL_INT)) + { + printf("\nIteration : %d\n", loop); + + rslt = bma4_get_fifo_length(&fifo_length, &dev); + bma4_error_codes_print_result("bma4_get_fifo_length status", rslt); + + printf("FIFO data bytes available : %d\n", fifo_length); + printf("FIFO data bytes requested : %d\n", fifoframe.length); + + /* Read FIFO data */ + rslt = bma4_read_fifo_data(&fifoframe, &dev); + bma4_error_codes_print_result("bma4_read_fifo_data status", rslt); + + accel_length = BMA456H_FIFO_ACCEL_FRAME_COUNT; + + if (rslt == BMA4_OK) + { + printf("Requested data frames before parsing: %d\n", accel_length); + + /* Parse the FIFO data to extract accelerometer data from the FIFO buffer */ + rslt = bma4_extract_accel(fifo_accel_data, &accel_length, &fifoframe, &dev); + printf("Parsed accelerometer data frames: %d\n", accel_length); + + printf("ACCEL, X, Y, Z\n"); + + /* Print the parsed accelerometer data from the FIFO buffer */ + for (idx = 0; idx < accel_length; idx++) + { + printf("%d, %d, %d, %d\n", + idx, + fifo_accel_data[idx].x, + fifo_accel_data[idx].y, + fifo_accel_data[idx].z); + } + + /* Print control frames like sensor time and skipped frame count */ + printf("Skipped frame count = %d\n", fifoframe.skipped_frame_count); + printf("Sensor time(in seconds) = %.4lf s\r\n", (fifoframe.sensor_time * BMA4_SENSORTIME_RESOLUTION)); + } + + loop++; + } + } + + bma4_coines_deinit(); + + return rslt; +} diff --git a/components/bma456/bma456h_examples/fifo_full_headerless_mode/Makefile b/components/bma456/bma456h_examples/fifo_full_headerless_mode/Makefile new file mode 100644 index 0000000..f244e75 --- /dev/null +++ b/components/bma456/bma456h_examples/fifo_full_headerless_mode/Makefile @@ -0,0 +1,18 @@ +COINES_INSTALL_PATH ?= ../../../.. + +EXAMPLE_FILE ?= fifo_full_headerless_mode.c + +API_LOCATION ?= ../.. + +COMMON_LOCATION ?= .. + +C_SRCS += \ +$(API_LOCATION)/bma4.c \ +$(API_LOCATION)/bma456h.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/components/bma456/bma456h_examples/fifo_full_headerless_mode/fifo_full_headerless_mode.c b/components/bma456/bma456h_examples/fifo_full_headerless_mode/fifo_full_headerless_mode.c new file mode 100644 index 0000000..3d70bf2 --- /dev/null +++ b/components/bma456/bma456h_examples/fifo_full_headerless_mode/fifo_full_headerless_mode.c @@ -0,0 +1,171 @@ +/**\ + * Copyright (c) 2022 Bosch Sensortec GmbH. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + **/ + +#include +#include "bma456h.h" +#include "common.h" + +/******************************************************************************/ +/*! Macro definition */ + +/*! Buffer size allocated to store raw FIFO data */ +#define BMA456H_FIFO_RAW_DATA_BUFFER_SIZE UINT16_C(1024) + +/*! Length of data to be read from FIFO */ +#define BMA456H_FIFO_RAW_DATA_USER_LENGTH UINT16_C(1024) + +/*! Number of accel frames to be extracted from FIFO + * Calculation: + * fifo_buffer = 1024, accel_frame_len = 6. + * fifo_accel_frame_count = (1024 / 6) = 170 frames + */ +#define BMA456H_FIFO_ACCEL_FRAME_COUNT UINT8_C(170) + +/******************************************************************************/ +/*! Function */ + +/* This function starts the execution of program */ +int main(void) +{ + /* Status of API are returned to this variable */ + int8_t rslt; + + /* Accelerometer configuration structure */ + struct bma4_accel_config acc_conf = { 0 }; + + /* Sensor initialization configuration */ + struct bma4_dev dev = { 0 }; + + /* Number of accelerometer frames */ + uint16_t accel_length; + + /* Variable to idx bytes */ + uint16_t idx = 0; + + /* Variable to maintain count of loop to run FIFO read */ + uint8_t loop = 1; + + /* Number of bytes of FIFO data + * NOTE : Dummy byte (for SPI Interface) required for FIFO data read must be given as part of array size + */ + uint8_t fifo_data[BMA456H_FIFO_RAW_DATA_BUFFER_SIZE] = { 0 }; + + /* Array of accelerometer frames -> Total bytes = + * 170 * (6 axes bytes(+/- x,y,z)) = 1020 bytes */ + struct bma4_accel fifo_accel_data[BMA456H_FIFO_ACCEL_FRAME_COUNT] = { { 0 } }; + + /* Initialize FIFO frame structure */ + struct bma4_fifo_frame fifoframe = { 0 }; + + /* Variable that contains interrupt status value */ + uint16_t int_status = 0; + + /* Variable to hold the length of FIFO data */ + uint16_t fifo_length = 0; + + /* Interface reference is given as a parameter + * For I2C : BMA4_I2C_INTF + * For SPI : BMA4_SPI_INTF + * Variant information given as parameter - BMA45X_VARIANT + */ + rslt = bma4_interface_init(&dev, BMA4_I2C_INTF, BMA45X_VARIANT); + bma4_error_codes_print_result("bma4_interface_init", rslt); + + /* Initialize BMA456H */ + rslt = bma456h_init(&dev); + bma4_error_codes_print_result("bma456h_init status", rslt); + + /* Accelerometer configuration settings */ + acc_conf.odr = BMA4_OUTPUT_DATA_RATE_100HZ; + acc_conf.bandwidth = BMA4_ACCEL_NORMAL_AVG4; + acc_conf.range = BMA4_ACCEL_RANGE_2G; + acc_conf.perf_mode = BMA4_CIC_AVG_MODE; + + /* Set the accel configurations */ + rslt = bma4_set_accel_config(&acc_conf, &dev); + bma4_error_codes_print_result("bma4_set_accel_config status", rslt); + + /* NOTE : Enable accel after set of configurations */ + rslt = bma4_set_accel_enable(BMA4_ENABLE, &dev); + bma4_error_codes_print_result("bma4_set_accel_enable status", rslt); + + /* Disabling advance power save mode as FIFO data is not accessible in advance low power mode */ + rslt = bma4_set_advance_power_save(BMA4_DISABLE, &dev); + bma4_error_codes_print_result("bma4_set_advance_power_save status", rslt); + + /* Clear FIFO configuration register */ + rslt = bma4_set_fifo_config(BMA4_FIFO_ALL, BMA4_DISABLE, &dev); + bma4_error_codes_print_result("bma4_set_fifo_config disable status", rslt); + + /* Set FIFO configuration by enabling accel. + * NOTE 1: The header mode is enabled by default. + * NOTE 2: By default the FIFO operating mode is FIFO mode. */ + rslt = bma4_set_fifo_config(BMA4_FIFO_ACCEL, BMA4_ENABLE, &dev); + bma4_error_codes_print_result("bma4_set_fifo_config enable status", rslt); + + /* Update FIFO structure */ + fifoframe.data = fifo_data; + fifoframe.length = BMA456H_FIFO_RAW_DATA_USER_LENGTH; + + /* To enable headerless mode, disable the header. */ + rslt = bma4_set_fifo_config(BMA4_FIFO_HEADER, BMA4_DISABLE, &dev); + bma4_error_codes_print_result("bma4_set_fifo_config status", rslt); + + printf("FIFO is configured in headerless mode\n"); + + rslt = bma456h_map_interrupt(BMA4_INTR1_MAP, BMA4_FIFO_FULL_INT, BMA4_ENABLE, &dev); + bma4_error_codes_print_result("bma4_map_interrupt status", rslt); + + while (loop <= 10) + { + rslt = bma456h_read_int_status(&int_status, &dev); + bma4_error_codes_print_result("bma4_read_int_status", rslt); + + if ((rslt == BMA4_OK) && (int_status & BMA4_FIFO_FULL_INT)) + { + printf("\nIteration : %d\n", loop); + + rslt = bma4_get_fifo_length(&fifo_length, &dev); + bma4_error_codes_print_result("bma4_get_fifo_length status", rslt); + + printf("FIFO data bytes available : %d\n", fifo_length); + printf("FIFO data bytes requested : %d\n", fifoframe.length); + + /* Read FIFO data */ + rslt = bma4_read_fifo_data(&fifoframe, &dev); + bma4_error_codes_print_result("bma4_read_fifo_data status", rslt); + + accel_length = BMA456H_FIFO_ACCEL_FRAME_COUNT; + + if (rslt == BMA4_OK) + { + printf("Requested data frames before parsing: %d\n", accel_length); + + /* Parse the FIFO data to extract accelerometer data from the FIFO buffer */ + rslt = bma4_extract_accel(fifo_accel_data, &accel_length, &fifoframe, &dev); + printf("Parsed accelerometer data frames: %d\n", accel_length); + + printf("ACCEL, X, Y, Z\n"); + + /* Print the parsed accelerometer data from the FIFO buffer */ + for (idx = 0; idx < accel_length; idx++) + { + printf("%d, %d, %d, %d\n", + idx, + fifo_accel_data[idx].x, + fifo_accel_data[idx].y, + fifo_accel_data[idx].z); + } + } + + loop++; + } + } + + bma4_coines_deinit(); + + return rslt; +} diff --git a/components/bma456/bma456h_examples/fifo_watermark_header_mode/Makefile b/components/bma456/bma456h_examples/fifo_watermark_header_mode/Makefile new file mode 100644 index 0000000..274e5fe --- /dev/null +++ b/components/bma456/bma456h_examples/fifo_watermark_header_mode/Makefile @@ -0,0 +1,20 @@ +COINES_INSTALL_PATH ?= ../../../.. + +EXAMPLE_FILE ?= fifo_watermark_header_mode.c + +API_LOCATION ?= ../.. + +COMMON_LOCATION ?= .. + +C_SRCS += \ +$(API_LOCATION)/bma4.c \ +$(API_LOCATION)/bma456h.c \ +$(COMMON_LOCATION)/common/common.c + +INCLUDEPATHS += \ +$(API_LOCATION) \ +$(COMMON_LOCATION)/common + +TARGET=MCU_APP30 + +include $(COINES_INSTALL_PATH)/coines.mk \ No newline at end of file diff --git a/components/bma456/bma456h_examples/fifo_watermark_header_mode/fifo_watermark_header_mode.c b/components/bma456/bma456h_examples/fifo_watermark_header_mode/fifo_watermark_header_mode.c new file mode 100644 index 0000000..efd56f9 --- /dev/null +++ b/components/bma456/bma456h_examples/fifo_watermark_header_mode/fifo_watermark_header_mode.c @@ -0,0 +1,188 @@ +/**\ + * Copyright (c) 2022 Bosch Sensortec GmbH. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + **/ + +#include +#include "bma456h.h" +#include "common.h" + +/******************************************************************************/ +/*! Macro definition */ + +/*! Buffer size allocated to store raw FIFO data */ +#define BMA456H_FIFO_RAW_DATA_BUFFER_SIZE UINT16_C(1024) + +/*! Length of data to be read from FIFO */ +#define BMA456H_FIFO_RAW_DATA_USER_LENGTH UINT16_C(1024) + +/*! Setting a watermark level in FIFO */ +#define BMA456H_FIFO_WATERMARK_LEVEL UINT16_C(650) + +/*! Number of accel frames to be extracted from FIFO + * Calculation: + * fifo_watermark_level = 650, accel_frame_len = 6, header_byte = 1. + * fifo_accel_frame_count = (650 / (6 + 1)) = 93 frames + * NOTE: Extra frames are read in order to get sensor time + */ +#define BMA456H_FIFO_ACCEL_FRAME_COUNT UINT8_C(100) + +/******************************************************************************/ +/*! Function */ + +/* This function starts the execution of program */ +int main(void) +{ + /* Status of API are returned to this variable */ + int8_t rslt; + + /* Accelerometer configuration structure */ + struct bma4_accel_config acc_conf = { 0 }; + + /* Sensor initialization configuration */ + struct bma4_dev dev = { 0 }; + + /* Number of accelerometer frames */ + uint16_t accel_length; + + /* Variable to idx bytes */ + uint16_t idx = 0; + + /* Variable to maintain count of loop to run FIFO read */ + uint8_t loop = 1; + + /* Number of bytes of FIFO data + * NOTE : Dummy byte (for SPI Interface) required for FIFO data read must be given as part of array size + */ + uint8_t fifo_data[BMA456H_FIFO_RAW_DATA_BUFFER_SIZE + BMA4_SENSORTIME_OVERHEAD_BYTE] = { 0 }; + + /* Array of accelerometer frames -> Total bytes = + * 100 * (6 axes bytes(+/- x,y,z) + 1 header byte) = 700 bytes */ + struct bma4_accel fifo_accel_data[BMA456H_FIFO_ACCEL_FRAME_COUNT] = { { 0 } }; + + /* Initialize FIFO frame structure */ + struct bma4_fifo_frame fifoframe = { 0 }; + + /* Variable that contains interrupt status value */ + uint16_t int_status = 0; + + /* Variable to hold the length of FIFO data */ + uint16_t fifo_length = 0; + + uint16_t watermark = 0; + + /* To set the watermark level in FIFO */ + uint16_t wm_lvl; + + /* Interface reference is given as a parameter + * For I2C : BMA4_I2C_INTF + * For SPI : BMA4_SPI_INTF + * Variant information given as parameter - BMA45X_VARIANT + */ + rslt = bma4_interface_init(&dev, BMA4_I2C_INTF, BMA45X_VARIANT); + bma4_error_codes_print_result("bma4_interface_init", rslt); + + /* Initialize BMA456H */ + rslt = bma456h_init(&dev); + bma4_error_codes_print_result("bma456h_init status", rslt); + + /* Accelerometer configuration settings */ + acc_conf.odr = BMA4_OUTPUT_DATA_RATE_100HZ; + acc_conf.bandwidth = BMA4_ACCEL_NORMAL_AVG4; + acc_conf.range = BMA4_ACCEL_RANGE_2G; + acc_conf.perf_mode = BMA4_CIC_AVG_MODE; + + /* Set the accel configurations */ + rslt = bma4_set_accel_config(&acc_conf, &dev); + bma4_error_codes_print_result("bma4_set_accel_config status", rslt); + + /* NOTE : Enable accel after set of configurations */ + rslt = bma4_set_accel_enable(BMA4_ENABLE, &dev); + bma4_error_codes_print_result("bma4_set_accel_enable status", rslt); + + /* Disabling advance power save mode as FIFO data is not accessible in advance low power mode */ + rslt = bma4_set_advance_power_save(BMA4_DISABLE, &dev); + bma4_error_codes_print_result("bma4_set_advance_power_save status", rslt); + + /* Clear FIFO configuration register */ + rslt = bma4_set_fifo_config(BMA4_FIFO_ALL, BMA4_DISABLE, &dev); + bma4_error_codes_print_result("bma4_set_fifo_config disable status", rslt); + + /* Set FIFO configuration by enabling accel. + * NOTE 1: The header mode is enabled by default. + * NOTE 2: By default the FIFO operating mode is FIFO mode. */ + rslt = bma4_set_fifo_config(BMA4_FIFO_ACCEL | BMA4_FIFO_HEADER | BMA4_FIFO_TIME, BMA4_ENABLE, &dev); + bma4_error_codes_print_result("bma4_set_fifo_config enable status", rslt); + + /* Update FIFO structure */ + fifoframe.data = fifo_data; + fifoframe.length = BMA456H_FIFO_RAW_DATA_USER_LENGTH + BMA4_SENSORTIME_OVERHEAD_BYTE; + + printf("FIFO is configured in header mode\n"); + + rslt = bma456h_map_interrupt(BMA4_INTR1_MAP, BMA4_FIFO_WM_INT, BMA4_ENABLE, &dev); + bma4_error_codes_print_result("bma456h_map_interrupt status", rslt); + + wm_lvl = BMA456H_FIFO_WATERMARK_LEVEL; + rslt = bma4_set_fifo_wm(wm_lvl, &dev); + bma4_error_codes_print_result("bma4_set_fifo_wm status", rslt); + + while (loop <= 10) + { + rslt = bma456h_read_int_status(&int_status, &dev); + bma4_error_codes_print_result("bma4_read_int_status", rslt); + + if ((rslt == BMA4_OK) && (int_status & BMA4_FIFO_WM_INT)) + { + printf("\nIteration : %d\n", loop); + + rslt = bma4_get_fifo_wm(&watermark, &dev); + bma4_error_codes_print_result("bma4_get_fifo_wm status", rslt); + printf("FIFO watermark level : %d\n", watermark); + + rslt = bma4_get_fifo_length(&fifo_length, &dev); + bma4_error_codes_print_result("bma4_get_fifo_length status", rslt); + + printf("FIFO data bytes available : %d\n", fifo_length); + printf("FIFO data bytes requested : %d\n", fifoframe.length); + + /* Read FIFO data */ + rslt = bma4_read_fifo_data(&fifoframe, &dev); + bma4_error_codes_print_result("bma4_read_fifo_data status", rslt); + + accel_length = BMA456H_FIFO_ACCEL_FRAME_COUNT; + + if (rslt == BMA4_OK) + { + printf("Requested data frames before parsing: %d\n", accel_length); + + /* Parse the FIFO data to extract accelerometer data from the FIFO buffer */ + rslt = bma4_extract_accel(fifo_accel_data, &accel_length, &fifoframe, &dev); + printf("Parsed accelerometer data frames: %d\n", accel_length); + + printf("ACCEL, X, Y, Z\n"); + + /* Print the parsed accelerometer data from the FIFO buffer */ + for (idx = 0; idx < accel_length; idx++) + { + printf("%d, %d, %d, %d\n", + idx, + fifo_accel_data[idx].x, + fifo_accel_data[idx].y, + fifo_accel_data[idx].z); + } + + /* Print control frames like sensor time and skipped frame count */ + printf("Skipped frame count = %d\n", fifoframe.skipped_frame_count); + printf("Sensor time(in seconds) = %.4lf s\r\n", (fifoframe.sensor_time * BMA4_SENSORTIME_RESOLUTION)); + } + + loop++; + } + } + + bma4_coines_deinit(); + + return rslt; +} diff --git a/components/bma456/bma456h_examples/fifo_watermark_headerless_mode/Makefile b/components/bma456/bma456h_examples/fifo_watermark_headerless_mode/Makefile new file mode 100644 index 0000000..b444df6 --- /dev/null +++ b/components/bma456/bma456h_examples/fifo_watermark_headerless_mode/Makefile @@ -0,0 +1,18 @@ +COINES_INSTALL_PATH ?= ../../../.. + +EXAMPLE_FILE ?= fifo_watermark_headerless_mode.c + +API_LOCATION ?= ../.. + +COMMON_LOCATION ?= .. + +C_SRCS += \ +$(API_LOCATION)/bma4.c \ +$(API_LOCATION)/bma456h.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/components/bma456/bma456h_examples/fifo_watermark_headerless_mode/fifo_watermark_headerless_mode.c b/components/bma456/bma456h_examples/fifo_watermark_headerless_mode/fifo_watermark_headerless_mode.c new file mode 100644 index 0000000..678926a --- /dev/null +++ b/components/bma456/bma456h_examples/fifo_watermark_headerless_mode/fifo_watermark_headerless_mode.c @@ -0,0 +1,188 @@ +/**\ + * Copyright (c) 2022 Bosch Sensortec GmbH. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + **/ + +#include +#include "bma456h.h" +#include "common.h" + +/******************************************************************************/ +/*! Macro definition */ + +/*! Buffer size allocated to store raw FIFO data */ +#define BMA456H_FIFO_RAW_DATA_BUFFER_SIZE UINT16_C(1024) + +/*! Length of data to be read from FIFO */ +#define BMA456H_FIFO_RAW_DATA_USER_LENGTH UINT16_C(1024) + +/*! Setting a watermark level in FIFO */ +#define BMA456H_FIFO_WATERMARK_LEVEL UINT16_C(600) + +/*! Number of accel frames to be extracted from FIFO + * Calculation: + * fifo_watermark_level = 600, accel_frame_len = 6. + * fifo_accel_frame_count = (600 / 6) = 100 frames + */ +#define BMA456H_FIFO_ACCEL_FRAME_COUNT UINT8_C(100) + +/******************************************************************************/ +/*! Function */ + +/* This function starts the execution of program */ +int main(void) +{ + /* Status of API are returned to this variable */ + int8_t rslt; + + /* Accelerometer configuration structure */ + struct bma4_accel_config acc_conf = { 0 }; + + /* Sensor initialization configuration */ + struct bma4_dev dev = { 0 }; + + /* Number of accelerometer frames */ + uint16_t accel_length; + + /* Variable to idx bytes */ + uint16_t idx = 0; + + /* Variable to maintain count of loop to run FIFO read */ + uint8_t loop = 1; + + /* Number of bytes of FIFO data + * NOTE : Dummy byte (for SPI Interface) required for FIFO data read must be given as part of array size + */ + uint8_t fifo_data[BMA456H_FIFO_RAW_DATA_BUFFER_SIZE] = { 0 }; + + /* Array of accelerometer frames -> Total bytes = + * 100 * (6 axes bytes(+/- x,y,z)) = 600 bytes */ + struct bma4_accel fifo_accel_data[BMA456H_FIFO_ACCEL_FRAME_COUNT] = { { 0 } }; + + /* Initialize FIFO frame structure */ + struct bma4_fifo_frame fifoframe = { 0 }; + + /* Variable that contains interrupt status value */ + uint16_t int_status = 0; + + /* Variable to hold the length of FIFO data */ + uint16_t fifo_length = 0; + + uint16_t watermark = 0; + + /* To set the watermark level in FIFO */ + uint16_t wm_lvl; + + /* Interface reference is given as a parameter + * For I2C : BMA4_I2C_INTF + * For SPI : BMA4_SPI_INTF + * Variant information given as parameter - BMA45X_VARIANT + */ + rslt = bma4_interface_init(&dev, BMA4_I2C_INTF, BMA45X_VARIANT); + bma4_error_codes_print_result("bma4_interface_init", rslt); + + /* Initialize BMA456H */ + rslt = bma456h_init(&dev); + bma4_error_codes_print_result("bma456h_init status", rslt); + + /* Accelerometer configuration settings */ + acc_conf.odr = BMA4_OUTPUT_DATA_RATE_100HZ; + acc_conf.bandwidth = BMA4_ACCEL_NORMAL_AVG4; + acc_conf.range = BMA4_ACCEL_RANGE_2G; + acc_conf.perf_mode = BMA4_CIC_AVG_MODE; + + /* Set the accel configurations */ + rslt = bma4_set_accel_config(&acc_conf, &dev); + bma4_error_codes_print_result("bma4_set_accel_config status", rslt); + + /* NOTE : Enable accel after set of configurations */ + rslt = bma4_set_accel_enable(BMA4_ENABLE, &dev); + bma4_error_codes_print_result("bma4_set_accel_enable status", rslt); + + /* Disabling advance power save mode as FIFO data is not accessible in advance low power mode */ + rslt = bma4_set_advance_power_save(BMA4_DISABLE, &dev); + bma4_error_codes_print_result("bma4_set_advance_power_save status", rslt); + + /* Clear FIFO configuration register */ + rslt = bma4_set_fifo_config(BMA4_FIFO_ALL, BMA4_DISABLE, &dev); + bma4_error_codes_print_result("bma4_set_fifo_config disable status", rslt); + + /* Set FIFO configuration by enabling accel. + * NOTE 1: The header mode is enabled by default. + * NOTE 2: By default the FIFO operating mode is FIFO mode. */ + rslt = bma4_set_fifo_config(BMA4_FIFO_ACCEL, BMA4_ENABLE, &dev); + bma4_error_codes_print_result("bma4_set_fifo_config enable status", rslt); + + /* Update FIFO structure */ + fifoframe.data = fifo_data; + fifoframe.length = BMA456H_FIFO_RAW_DATA_USER_LENGTH; + + /* To enable headerless mode, disable the header. */ + rslt = bma4_set_fifo_config(BMA4_FIFO_HEADER, BMA4_DISABLE, &dev); + bma4_error_codes_print_result("bma4_set_fifo_config status", rslt); + + printf("FIFO is configured in headerless mode\n"); + + rslt = bma456h_map_interrupt(BMA4_INTR1_MAP, BMA4_FIFO_WM_INT, BMA4_ENABLE, &dev); + bma4_error_codes_print_result("bma456h_map_interrupt status", rslt); + + wm_lvl = BMA456H_FIFO_WATERMARK_LEVEL; + rslt = bma4_set_fifo_wm(wm_lvl, &dev); + bma4_error_codes_print_result("bma4_set_fifo_wm status", rslt); + + while (loop <= 10) + { + rslt = bma456h_read_int_status(&int_status, &dev); + bma4_error_codes_print_result("bma456h_read_int_status", rslt); + + if ((rslt == BMA4_OK) && (int_status & BMA4_FIFO_WM_INT)) + { + printf("\nIteration : %d\n", loop); + + rslt = bma4_get_fifo_wm(&watermark, &dev); + bma4_error_codes_print_result("bma4_get_fifo_wm status", rslt); + + printf("FIFO watermark level : %d\n", watermark); + + rslt = bma4_get_fifo_length(&fifo_length, &dev); + bma4_error_codes_print_result("bma4_get_fifo_length status", rslt); + + printf("FIFO data bytes available : %d\n", fifo_length); + printf("FIFO data bytes requested : %d\n", fifoframe.length); + + /* Read FIFO data */ + rslt = bma4_read_fifo_data(&fifoframe, &dev); + bma4_error_codes_print_result("bma4_read_fifo_data status", rslt); + + accel_length = BMA456H_FIFO_ACCEL_FRAME_COUNT; + + if (rslt == BMA4_OK) + { + printf("Requested data frames before parsing: %d\n", accel_length); + + /* Parse the FIFO data to extract accelerometer data from the FIFO buffer */ + rslt = bma4_extract_accel(fifo_accel_data, &accel_length, &fifoframe, &dev); + printf("Parsed accelerometer data frames: %d\n", accel_length); + + printf("ACCEL, X, Y, Z\n"); + + /* Print the parsed accelerometer data from the FIFO buffer */ + for (idx = 0; idx < accel_length; idx++) + { + printf("%d, %d, %d, %d\n", + idx, + fifo_accel_data[idx].x, + fifo_accel_data[idx].y, + fifo_accel_data[idx].z); + } + } + + loop++; + } + } + + bma4_coines_deinit(); + + return rslt; +} diff --git a/components/bma456/bma456h_examples/motion/Makefile b/components/bma456/bma456h_examples/motion/Makefile new file mode 100644 index 0000000..e390a4a --- /dev/null +++ b/components/bma456/bma456h_examples/motion/Makefile @@ -0,0 +1,18 @@ +COINES_INSTALL_PATH ?= ../../../.. + +EXAMPLE_FILE ?= motion.c + +API_LOCATION ?= ../.. + +COMMON_LOCATION ?= .. + +C_SRCS += \ +$(API_LOCATION)/bma4.c \ +$(API_LOCATION)/bma456h.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/components/bma456/bma456h_examples/motion/motion.c b/components/bma456/bma456h_examples/motion/motion.c new file mode 100644 index 0000000..fae79b5 --- /dev/null +++ b/components/bma456/bma456h_examples/motion/motion.c @@ -0,0 +1,186 @@ +/**\ + * Copyright (c) 2022 Bosch Sensortec GmbH. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + **/ + +#include +#include "bma456h.h" +#include "common.h" + +/*****************************************************************************/ +/*! Global variable */ + +/*! Structure to define any/no-motion configurations */ +struct bma456h_any_no_mot_config any_no_mot = { 0 }; + +/******************************************************************************/ +/*! Static Function Declaration */ + +/*! + * @brief This internal API is used to get any/no-motion configurations. + * + * @param[in] bma : Structure instance of bma4_dev. + * + * @return Status of execution. + */ +static int8_t get_any_no_mot_config(struct bma4_dev *bma); + +/******************************************************************************/ +/*! Functions */ + +/* This function starts the execution of program. */ +int main(void) +{ + /* Variable to store the status of API */ + int8_t rslt; + + /* Sensor initialization configuration */ + struct bma4_dev bma = { 0 }; + + /* Variable to store any/no-motion interrupt status */ + uint16_t int_status = 0; + + uint8_t iteration = 20; + + /* Interface reference is given as a parameter + * For I2C : BMA4_I2C_INTF + * For SPI : BMA4_SPI_INTF + * Variant information given as parameter - BMA45X_VARIANT + */ + rslt = bma4_interface_init(&bma, BMA4_I2C_INTF, BMA45X_VARIANT); + bma4_error_codes_print_result("bma4_interface_init", rslt); + + /* Sensor initialization */ + rslt = bma456h_init(&bma); + bma4_error_codes_print_result("bma456h_init status", rslt); + + /* Upload the configuration file to enable the features of the sensor. */ + rslt = bma456h_write_config_file(&bma); + bma4_error_codes_print_result("bma456h_write_config status", rslt); + + /* Enable the accelerometer */ + rslt = bma4_set_accel_enable(BMA4_ENABLE, &bma); + bma4_error_codes_print_result("bma4_set_accel_enable status", rslt); + + /* Map the interrupt pin 1 for any/no-motion */ + rslt = bma456h_map_interrupt(BMA4_INTR1_MAP, (BMA456H_ANY_MOT_INT | BMA456H_NO_MOT_INT), BMA4_ENABLE, &bma); + bma4_error_codes_print_result("bma456h_map_interrupt status", rslt); + + /* Enabling X, Y, and Z axis for Any and No-motion feature */ + rslt = bma456h_feature_enable((BMA456H_ANY_MOTION_ALL_AXIS_EN | BMA456H_NO_MOTION_ALL_AXIS_EN), BMA4_ENABLE, &bma); + bma4_error_codes_print_result("bma456h_feature_enable status", rslt); + + /* Get any-motion and no-motion configurations */ + rslt = get_any_no_mot_config(&bma); + bma4_error_codes_print_result("get_any_no_mot_config status", rslt); + + printf("Shake the board for any-motion interrupt whereas do not shake the board for no-motion interrupt\n"); + + if (rslt == BMA4_OK) + { + for (;;) + { + /* Read interrupt status */ + rslt = bma456h_read_int_status(&int_status, &bma); + bma4_error_codes_print_result("bma456h_read_int_status", rslt); + + if (rslt == BMA4_OK) + { + /* Enters only if the obtained interrupt is any-motion */ + if (int_status & BMA456H_ANY_MOT_INT) + { + printf("Any-motion interrupt occurred\n"); + iteration--; + } + + /* Enters only if the obtained interrupt is no-motion */ + else if (int_status & BMA456H_NO_MOT_INT) + { + printf("No-motion interrupt occurred\n"); + iteration--; + } + + int_status = 0; + + /* Break out of the loop when iteration has reached zero */ + if (iteration == 0) + { + printf("Iterations are done. Exiting !"); + break; + } + } + } + } + + bma4_coines_deinit(); + + return rslt; +} + +/*! + * @brief This internal API is used to get any/no-motion configurations. + */ +static int8_t get_any_no_mot_config(struct bma4_dev *bma) +{ + /* Variable to store the status of API */ + int8_t rslt; + + /* Getting any-motion configuration to get default configuration */ + rslt = bma456h_get_any_mot_config(&any_no_mot, bma); + bma4_error_codes_print_result("bma456h_get_any_mot_config status", rslt); + + if (rslt == BMA4_OK) + { + /* + * Set the slope threshold: + * Interrupt will be generated if the slope of all the axis exceeds the threshold (1 bit = 0.48mG) + */ + any_no_mot.threshold = 10; + + /* + * Set the duration for any-motion interrupt: + * Duration defines the number of consecutive data points for which threshold condition must be true(1 + * bit = + * 20ms) + */ + any_no_mot.duration = 4; + + /* Like threshold and duration, we can also change the config of int_bhvr and slope */ + + /* Set the threshold and duration configuration */ + rslt = bma456h_set_any_mot_config(&any_no_mot, bma); + bma4_error_codes_print_result("bma456h_set_any_mot_config status", rslt); + + if (rslt == BMA4_OK) + { + /* Getting no-motion configuration to get default configuration */ + rslt = bma456h_get_no_mot_config(&any_no_mot, bma); + bma4_error_codes_print_result("bma456h_get_no_mot_config status", rslt); + + if (rslt == BMA4_OK) + { + /* + * Set the slope threshold: + * Interrupt will be generated if the slope of all the axis exceeds the threshold (1 bit = 0.48mG) + */ + any_no_mot.threshold = 10; + + /* + * Set the duration for no-motion interrupt: + * Duration defines the number of consecutive data points for which threshold condition must be + * true(1 bit = 20ms) + */ + any_no_mot.duration = 4; + + /* Like threshold and duration, we can also change the config of int_bhvr */ + + /* Set the threshold and duration configuration */ + rslt = bma456h_set_no_mot_config(&any_no_mot, bma); + bma4_error_codes_print_result("bma456h_set_no_mot_config status", rslt); + } + } + } + + return rslt; +} diff --git a/components/bma456/bma456h_examples/selftest/Makefile b/components/bma456/bma456h_examples/selftest/Makefile new file mode 100644 index 0000000..861ef74 --- /dev/null +++ b/components/bma456/bma456h_examples/selftest/Makefile @@ -0,0 +1,18 @@ +COINES_INSTALL_PATH ?= ../../../.. + +EXAMPLE_FILE ?= selftest.c + +API_LOCATION ?= ../.. + +COMMON_LOCATION ?= .. + +C_SRCS += \ +$(API_LOCATION)/bma4.c \ +$(API_LOCATION)/bma456h.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/components/bma456/bma456h_examples/selftest/selftest.c b/components/bma456/bma456h_examples/selftest/selftest.c new file mode 100644 index 0000000..37de63f --- /dev/null +++ b/components/bma456/bma456h_examples/selftest/selftest.c @@ -0,0 +1,47 @@ +/**\ + * Copyright (c) 2022 Bosch Sensortec GmbH. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + **/ + +#include +#include "bma456h.h" +#include "common.h" + +/******************************************************************************/ +/*! Function */ + +/* This function starts the execution of program. */ +int main(void) +{ + /* Variable to store the status of API */ + int8_t rslt; + + /* Sensor initialization configuration */ + struct bma4_dev bma = { 0 }; + + /* Variable to store result of self-test */ + int8_t selftest_rslt = 0; + + /* Interface reference is given as a parameter + * For I2C : BMA4_I2C_INTF + * For SPI : BMA4_SPI_INTF + * Variant information given as parameter - BMA45X_VARIANT + */ + rslt = bma4_interface_init(&bma, BMA4_SPI_INTF, BMA45X_VARIANT); + bma4_error_codes_print_result("bma4_interface_init", rslt); + + /* Sensor initialization */ + rslt = bma456h_init(&bma); + bma4_error_codes_print_result("bma456h_init status", rslt); + + printf("Perform accel self-test\n"); + + rslt = bma4_perform_accel_selftest(&selftest_rslt, &bma); + bma4_error_codes_print_result("bma4_perform_accel_selftest", rslt); + printf("Self-test result is %d\n", selftest_rslt); + + bma4_coines_deinit(); + + return rslt; +} diff --git a/components/bma456/bma456h_examples/step_activity/Makefile b/components/bma456/bma456h_examples/step_activity/Makefile new file mode 100644 index 0000000..ac4fd7a --- /dev/null +++ b/components/bma456/bma456h_examples/step_activity/Makefile @@ -0,0 +1,18 @@ +COINES_INSTALL_PATH ?= ../../../.. + +EXAMPLE_FILE ?= step_activity.c + +API_LOCATION ?= ../.. + +COMMON_LOCATION ?= .. + +C_SRCS += \ +$(API_LOCATION)/bma4.c \ +$(API_LOCATION)/bma456h.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/components/bma456/bma456h_examples/step_activity/step_activity.c b/components/bma456/bma456h_examples/step_activity/step_activity.c new file mode 100644 index 0000000..32340fd --- /dev/null +++ b/components/bma456/bma456h_examples/step_activity/step_activity.c @@ -0,0 +1,116 @@ +/**\ + * Copyright (c) 2022 Bosch Sensortec GmbH. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + **/ + +#include +#include "bma456h.h" +#include "common.h" + +/******************************************************************************/ +/*! Function */ + +/* This function starts the execution of program. */ +int main(void) +{ + /* Variable to store the status of API */ + int8_t rslt; + + /* Sensor initialization configuration */ + struct bma4_dev bma = { 0 }; + + /* Variable to hold iteration value */ + uint8_t loop = 1; + + /* Variable to store step activity interrupt status */ + uint16_t int_status = 0; + + struct bma456h_out_state activity_output = { 0 }; + + /* Interface reference is given as a parameter + * For I2C : BMA4_I2C_INTF + * For SPI : BMA4_SPI_INTF + * Variant information given as parameter - BMA45X_VARIANT + */ + rslt = bma4_interface_init(&bma, BMA4_I2C_INTF, BMA45X_VARIANT); + bma4_error_codes_print_result("bma4_interface_init", rslt); + + /* Sensor initialization */ + rslt = bma456h_init(&bma); + bma4_error_codes_print_result("bma456h_init status", rslt); + + /* Upload the configuration file to enable the features of the sensor */ + rslt = bma456h_write_config_file(&bma); + bma4_error_codes_print_result("bma456h_write_config status", rslt); + + /* Enable the accelerometer */ + rslt = bma4_set_accel_enable(BMA4_ENABLE, &bma); + bma4_error_codes_print_result("bma4_set_accel_enable status", rslt); + + if (rslt == BMA4_OK) + { + /* Enabling step activity feature */ + rslt = bma456h_feature_enable(BMA456H_STEP_ACTIVITY_EN, BMA4_ENABLE, &bma); + bma4_error_codes_print_result("bma456h_feature_enable status", rslt); + + if (rslt == BMA4_OK) + { + /* Map the interrupt pin 1 for step counter */ + rslt = bma456h_map_interrupt(BMA4_INTR1_MAP, BMA456H_ACTIVITY_INT, BMA4_ENABLE, &bma); + bma4_error_codes_print_result("bma456h_map_interrupt status", rslt); + } + + if (rslt == BMA4_OK) + { + printf("Move the board in steps to perform step activity\n"); + + while (loop <= 5) + { + /* Read interrupt status */ + rslt = bma456h_read_int_status(&int_status, &bma); + bma4_error_codes_print_result("bma456h_read_int_status", rslt); + + /* Filtering only the activity interrupt */ + if ((rslt == BMA4_OK) && (int_status & BMA456H_ACTIVITY_INT)) + { + printf("\nIteration : %d\n", loop); + + /* Get step activity output */ + rslt = bma456h_output_state(&activity_output, &bma); + + if (rslt == BMA4_OK) + { + printf("The Activity output is %d\n", activity_output.activity_type); + + switch (activity_output.activity_type) + { + case BMA456H_USER_STATIONARY: + printf("User state is stationary\n"); + break; + case BMA456H_USER_WALKING: + printf("User state is walking\n"); + break; + case BMA456H_USER_RUNNING: + printf("User state is running\n"); + break; + case BMA456H_UNKNOWN_ACTVTY: + printf("User state is invalid state\n"); + break; + default: + break; + } + + loop++; + } + } + + int_status = 0; + } + } + } + + bma4_coines_deinit(); + + return rslt; +} diff --git a/components/bma456/bma456h_examples/step_counter/Makefile b/components/bma456/bma456h_examples/step_counter/Makefile new file mode 100644 index 0000000..18b473e --- /dev/null +++ b/components/bma456/bma456h_examples/step_counter/Makefile @@ -0,0 +1,18 @@ +COINES_INSTALL_PATH ?= ../../../.. + +EXAMPLE_FILE ?= step_counter.c + +API_LOCATION ?= ../.. + +COMMON_LOCATION ?= .. + +C_SRCS += \ +$(API_LOCATION)/bma4.c \ +$(API_LOCATION)/bma456h.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/components/bma456/bma456h_examples/step_counter/step_counter.c b/components/bma456/bma456h_examples/step_counter/step_counter.c new file mode 100644 index 0000000..75b27a2 --- /dev/null +++ b/components/bma456/bma456h_examples/step_counter/step_counter.c @@ -0,0 +1,103 @@ +/**\ + * Copyright (c) 2022 Bosch Sensortec GmbH. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + **/ + +#include +#include "bma456h.h" +#include "common.h" + +/******************************************************************************/ +/*! Function */ + +/* This function starts the execution of program. */ +int main(void) +{ + /* Variable to store the status of API */ + int8_t rslt; + + /* Sensor initialization configuration */ + struct bma4_dev bma = { 0 }; + + /* Variable to store step counter interrupt status */ + uint16_t int_status = 0; + + /* Variable to store step counter output */ + uint32_t step_out = 0; + + /* Interface reference is given as a parameter + * For I2C : BMA4_I2C_INTF + * For SPI : BMA4_SPI_INTF + * Variant information given as parameter - BMA45X_VARIANT + */ + rslt = bma4_interface_init(&bma, BMA4_SPI_INTF, BMA45X_VARIANT); + bma4_error_codes_print_result("bma4_interface_init", rslt); + + /* Sensor initialization */ + rslt = bma456h_init(&bma); + bma4_error_codes_print_result("bma456h_init status", rslt); + + /* Upload the configuration file to enable the features of the sensor. */ + rslt = bma456h_write_config_file(&bma); + bma4_error_codes_print_result("bma456h_write_config status", rslt); + + /* Enable the accelerometer */ + rslt = bma4_set_accel_enable(BMA4_ENABLE, &bma); + bma4_error_codes_print_result("bma4_set_accel_enable status", rslt); + + if (rslt == BMA4_OK) + { + /* Map the interrupt pin 1 for step counter */ + rslt = bma456h_map_interrupt(BMA4_INTR1_MAP, BMA456H_STEP_CNTR_INT, BMA4_ENABLE, &bma); + bma4_error_codes_print_result("bma456h_map_interrupt status", rslt); + + if (rslt == BMA4_OK) + { + /* Setting watermark level 1, the output step resolution is 20 steps. + * Eg: 1 means, 1 * 20 = 20. Every 20 steps once output triggers + */ + rslt = bma456h_step_counter_set_watermark(1, &bma); + bma4_error_codes_print_result("bma456h_step_counter_set_watermark status", rslt); + + if (rslt == BMA4_OK) + { + /* Enabling step counter feature */ + rslt = bma456h_feature_enable(BMA456H_STEP_COUNTER_EN, BMA4_ENABLE, &bma); + bma4_error_codes_print_result("bma456h_feature_enable status", rslt); + } + } + + if (rslt == BMA4_OK) + { + printf("Step counter feature is enabled\n"); + + printf("Step counter watermark level is 1 (Output resolution is 20 steps)\n"); + + printf("Move the board in steps to perform step counter\n"); + + for (;;) + { + /* Read interrupt status */ + rslt = bma456h_read_int_status(&int_status, &bma); + bma4_error_codes_print_result("bma456h_read_int_status", rslt); + + /* Enters only if the obtained interrupt is step counter */ + if ((rslt == BMA4_OK) && (int_status & BMA456H_STEP_CNTR_INT)) + { + printf("Step counter interrupt received when watermark level is reached (20 steps)\n"); + + rslt = bma456h_step_counter_output(&step_out, &bma); + printf("The step counter output is %lu\n", (long unsigned int)step_out); + break; + } + + int_status = 0; + } + } + } + + bma4_coines_deinit(); + + return rslt; +} diff --git a/components/bma456/bma456h_examples/step_detector/Makefile b/components/bma456/bma456h_examples/step_detector/Makefile new file mode 100644 index 0000000..561686b --- /dev/null +++ b/components/bma456/bma456h_examples/step_detector/Makefile @@ -0,0 +1,18 @@ +COINES_INSTALL_PATH ?= ../../../.. + +EXAMPLE_FILE ?= step_detector.c + +API_LOCATION ?= ../.. + +COMMON_LOCATION ?= .. + +C_SRCS += \ +$(API_LOCATION)/bma4.c \ +$(API_LOCATION)/bma456h.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/components/bma456/bma456h_examples/step_detector/step_detector.c b/components/bma456/bma456h_examples/step_detector/step_detector.c new file mode 100644 index 0000000..565dcbd --- /dev/null +++ b/components/bma456/bma456h_examples/step_detector/step_detector.c @@ -0,0 +1,93 @@ +/**\ + * Copyright (c) 2022 Bosch Sensortec GmbH. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + **/ + +#include +#include "bma456h.h" +#include "common.h" + +/******************************************************************************/ +/*! Function */ + +/* This function starts the execution of program. */ +int main(void) +{ + /* Variable to store the status of API */ + int8_t rslt; + + /* Sensor initialization configuration */ + struct bma4_dev bma = { 0 }; + + /* Variable to store step detector interrupt status */ + uint16_t int_status = 0; + + /* Interface reference is given as a parameter + * For I2C : BMA4_I2C_INTF + * For SPI : BMA4_SPI_INTF + * Variant information given as parameter - BMA45X_VARIANT + */ + rslt = bma4_interface_init(&bma, BMA4_I2C_INTF, BMA45X_VARIANT); + bma4_error_codes_print_result("bma4_interface_init", rslt); + + /* Sensor initialization */ + rslt = bma456h_init(&bma); + bma4_error_codes_print_result("bma456h_init status", rslt); + + /* Upload the configuration file to enable the features of the sensor. */ + rslt = bma456h_write_config_file(&bma); + bma4_error_codes_print_result("bma456h_write_config status", rslt); + + /* Enable the accelerometer */ + rslt = bma4_set_accel_enable(BMA4_ENABLE, &bma); + bma4_error_codes_print_result("bma4_set_accel_enable status", rslt); + + if (rslt == BMA4_OK) + { + /* Map the interrupt pin 1 for step detector */ + rslt = bma456h_map_interrupt(BMA4_INTR1_MAP, BMA456H_STEP_CNTR_INT, BMA4_ENABLE, &bma); + bma4_error_codes_print_result("bma456h_map_interrupt status", rslt); + + if (rslt == BMA4_OK) + { + /* Enabling step detector feature */ + rslt = bma456h_feature_enable(BMA456H_STEP_DETECTOR_EN, BMA4_ENABLE, &bma); + bma4_error_codes_print_result("bma456h_feature_enable status", rslt); + + if (rslt == BMA4_OK) + { + /* By setting watermark level 1, the output step resolution is 20 steps. + * By setting watermark level 0, it provides output for each steps for step detection. + */ + rslt = bma456h_step_counter_set_watermark(0, &bma); + bma4_error_codes_print_result("bma456h_step_counter_set_watermark status", rslt); + } + } + + if (rslt == BMA4_OK) + { + printf("Move the board in steps to get interrupt\n"); + + for (;;) + { + /* Read interrupt status */ + rslt = bma456h_read_int_status(&int_status, &bma); + bma4_error_codes_print_result("bma456h_read_int_status", rslt); + + /* Filtering only the step detector interrupt */ + if ((rslt == BMA4_OK) && (int_status & BMA456H_STEP_CNTR_INT)) + { + printf("The step detector interrupt is occurred\n"); + break; + } + + int_status = 0; + } + } + } + + bma4_coines_deinit(); + + return rslt; +} diff --git a/components/bma456/bma456h_examples/tap/Makefile b/components/bma456/bma456h_examples/tap/Makefile new file mode 100644 index 0000000..6458a3a --- /dev/null +++ b/components/bma456/bma456h_examples/tap/Makefile @@ -0,0 +1,18 @@ +COINES_INSTALL_PATH ?= ../../../.. + +EXAMPLE_FILE ?= tap.c + +API_LOCATION ?= ../.. + +COMMON_LOCATION ?= .. + +C_SRCS += \ +$(API_LOCATION)/bma4.c \ +$(API_LOCATION)/bma456h.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/components/bma456/bma456h_examples/tap/tap.c b/components/bma456/bma456h_examples/tap/tap.c new file mode 100644 index 0000000..86b10af --- /dev/null +++ b/components/bma456/bma456h_examples/tap/tap.c @@ -0,0 +1,125 @@ +/**\ + * Copyright (c) 2022 Bosch Sensortec GmbH. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + **/ + +#include +#include "bma456h.h" +#include "common.h" + +/******************************************************************************/ +/*! Function */ + +/* This function starts the execution of program. */ +int main(void) +{ + /* Variable to store the status of API */ + int8_t rslt; + + /* Sensor initialization configuration */ + struct bma4_dev bma = { 0 }; + + /* Variable to store tap interrupt status */ + uint16_t int_status = 0; + + /* Loop variable */ + uint8_t loop = 10; + + struct bma456h_out_state tap_out = { 0 }; + struct bma456h_multitap_settings settings = { 0 }; + + /* Interface reference is given as a parameter + * For I2C : BMA4_I2C_INTF + * For SPI : BMA4_SPI_INTF + * Variant information given as parameter - BMA45X_VARIANT + */ + rslt = bma4_interface_init(&bma, BMA4_I2C_INTF, BMA45X_VARIANT); + bma4_error_codes_print_result("bma4_interface_init", rslt); + + /* Sensor initialization */ + rslt = bma456h_init(&bma); + bma4_error_codes_print_result("bma456h_init status", rslt); + + /* Upload the configuration file to enable the features of the sensor. */ + rslt = bma456h_write_config_file(&bma); + bma4_error_codes_print_result("bma456h_write_config status", rslt); + + /* Enable the accelerometer */ + rslt = bma4_set_accel_enable(BMA4_ENABLE, &bma); + bma4_error_codes_print_result("bma4_set_accel_enable status", rslt); + + if (rslt == BMA4_OK) + { + /* Map the interrupt pin 1 for tap detection */ + rslt = bma456h_map_interrupt(BMA4_INTR1_MAP, BMA456H_TAP_OUT_INT, BMA4_ENABLE, &bma); + bma4_error_codes_print_result("bma456h_map_interrupt status", rslt); + + if (rslt == BMA4_OK) + { + /* Enabling the single, double and triple tap features */ + rslt = bma456h_feature_enable((BMA456H_SINGLE_TAP_EN | BMA456H_DOUBLE_TAP_EN | BMA456H_TRIPLE_TAP_EN), + BMA4_ENABLE, + &bma); + bma4_error_codes_print_result("bma456h_feature_enable status", rslt); + + if (rslt == BMA4_OK) + { + /* Getting tap parameters settings */ + rslt = bma456h_tap_get_parameter(&settings, &bma); + bma4_error_codes_print_result("bma456h_tap_get_parameter status", rslt); + } + } + + if (rslt == BMA4_OK) + { + printf("Tap the board either single, double or triple tap\n"); + + while (loop > 0) + { + /* Read interrupt status */ + rslt = bma456h_read_int_status(&int_status, &bma); + bma4_error_codes_print_result("bma456h_read_int_status", rslt); + + /* Filtering only the tap interrupt */ + if ((rslt == BMA4_OK) && (int_status & BMA456H_TAP_OUT_INT)) + { + rslt = bma456h_output_state(&tap_out, &bma); + + if (BMA4_OK == rslt) + { + /* Enters only if the obtained interrupt is single-tap */ + if (tap_out.single_tap) + { + printf("Single Tap interrupt occurred\n"); + } + /* Enters only if the obtained interrupt is double-tap */ + else if (tap_out.double_tap) + { + printf("Double Tap interrupt occurred\n"); + } + /* Enters only if the obtained interrupt is triple-tap */ + else if (tap_out.triple_tap) + { + printf("Triple Tap interrupt occurred\n"); + } + + loop--; + } + + int_status = 0; + } + } + + /* Break out of the loop when iteration has reached zero */ + if (loop == 0) + { + printf("Iterations are done. Exiting !"); + } + } + } + + bma4_coines_deinit(); + + return rslt; +} diff --git a/components/bma456/bma456mm.c b/components/bma456/bma456mm.c new file mode 100644 index 0000000..0056e7e --- /dev/null +++ b/components/bma456/bma456mm.c @@ -0,0 +1,1948 @@ +/** +* 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. +* +* @file bma456mm.c +* @date 2023-07-05 +* @version V2.29.0 +* +*/ + +/*! \file bma456mm.c + * \brief Sensor Driver for BMA456MM sensor + */ + +#include "bma456mm.h" + +/**\name Feature configuration file */ +const uint8_t bma456mm_config_file[] = { + 0xc8, 0x2e, 0x00, 0x2e, 0xc8, 0x2e, 0x00, 0x2e, 0xc8, 0x2e, 0x00, 0x2e, 0xc8, 0x2e, 0x00, 0x2e, 0x80, 0x2e, 0x99, + 0x00, 0xc8, 0x2e, 0x00, 0x2e, 0xc8, 0x2e, 0x00, 0x2e, 0x80, 0x2e, 0x56, 0x01, 0x50, 0x39, 0x21, 0x2e, 0xb0, 0xf0, + 0x10, 0x30, 0x21, 0x2e, 0x16, 0xf0, 0x80, 0x2e, 0xfb, 0x00, 0x81, 0x50, 0x75, 0x52, 0x01, 0x42, 0x3b, 0x80, 0x41, + 0x30, 0x01, 0x42, 0x3c, 0x80, 0x00, 0x2e, 0x01, 0x40, 0x01, 0x42, 0x21, 0x2e, 0xff, 0xaf, 0xb8, 0x2e, 0x9f, 0xab, + 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, + 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, + 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, + 0x2e, 0x18, 0x00, 0xfd, 0x2d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x00, 0x04, 0x00, 0x01, + 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x9a, 0x01, 0x34, 0x03, 0x00, 0x00, 0x00, 0x00, 0x09, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x70, 0x50, 0xf1, 0x7f, 0xe0, 0x7f, 0xd2, 0x7f, 0xcb, 0x7f, 0x98, 0x2e, 0xc8, 0x00, 0x00, 0xb2, 0x75, + 0x50, 0x1b, 0x30, 0x05, 0x2f, 0x03, 0x2e, 0x03, 0xf0, 0x9d, 0xbc, 0x9f, 0xb8, 0x40, 0x90, 0x07, 0x2f, 0x37, 0x2e, + 0x65, 0x00, 0x0b, 0x30, 0x37, 0x2e, 0x6d, 0x00, 0x21, 0x2e, 0xbc, 0xf0, 0x0e, 0x2d, 0x51, 0x52, 0x77, 0x50, 0xb5, + 0x7f, 0xa4, 0x7f, 0x93, 0x7f, 0x98, 0x2e, 0xe5, 0x00, 0x10, 0x30, 0x21, 0x2e, 0x4c, 0x00, 0x93, 0x6f, 0xa4, 0x6f, + 0xb5, 0x6f, 0x75, 0x50, 0x21, 0x2e, 0xb8, 0xf0, 0xf1, 0x6f, 0xd2, 0x6f, 0xe0, 0x6f, 0xcb, 0x6f, 0x90, 0x5f, 0xc8, + 0x2e, 0x01, 0x2e, 0x09, 0x01, 0x0f, 0xbd, 0x8e, 0xbc, 0x2f, 0xb9, 0x9f, 0xb8, 0x51, 0x0a, 0x0d, 0xbc, 0x0f, 0xb8, + 0x05, 0x2e, 0x18, 0x01, 0x2f, 0xb9, 0x08, 0x0a, 0x02, 0x0a, 0x00, 0xb2, 0x10, 0x30, 0x03, 0x2f, 0x03, 0x2e, 0x4d, + 0x00, 0x44, 0xb2, 0x01, 0x2f, 0x00, 0x30, 0xb8, 0x2e, 0xb8, 0x2e, 0x01, 0x2e, 0x09, 0x01, 0xc0, 0x2e, 0x0c, 0xbc, + 0x0f, 0xb8, 0x05, 0x2e, 0x01, 0xf0, 0x2e, 0xbd, 0xae, 0xb9, 0x34, 0x30, 0x43, 0x84, 0xe3, 0x04, 0x25, 0x40, 0x04, + 0x40, 0xd8, 0xbe, 0x2c, 0x0b, 0x23, 0x11, 0x54, 0x42, 0x03, 0x80, 0x4a, 0x0e, 0xf6, 0x2f, 0xb8, 0x2e, 0x01, 0x2e, + 0x55, 0xf0, 0xc0, 0x2e, 0x21, 0x2e, 0x55, 0xf0, 0x1a, 0x24, 0x26, 0x00, 0x80, 0x2e, 0x00, 0xb0, 0x44, 0x47, 0xcc, + 0x00, 0x05, 0x00, 0xcc, 0x00, 0x64, 0x00, 0x30, 0x0a, 0x80, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00, 0x30, 0x00, 0x00, + 0x06, 0x00, 0x09, 0x00, 0x82, 0x00, 0x06, 0x00, 0x06, 0x00, 0x08, 0x00, 0x50, 0x00, 0x00, 0x00, 0x4c, 0x04, 0x02, + 0x00, 0x03, 0x00, 0x00, 0x00, 0x91, 0x41, 0x00, 0x0c, 0x00, 0x71, 0x04, 0x00, 0x33, 0x01, 0x96, 0x00, 0x32, 0x00, + 0x40, 0x5c, 0x88, 0x00, 0x77, 0x00, 0x00, 0x01, 0x81, 0x00, 0x02, 0x01, 0x06, 0x01, 0x17, 0x01, 0x52, 0x00, 0x75, + 0x00, 0x45, 0x00, 0x48, 0x00, 0xaf, 0x00, 0xff, 0x00, 0xec, 0x00, 0xff, 0xb7, 0x00, 0x02, 0x00, 0xb0, 0x05, 0x80, + 0xfc, 0x0f, 0x00, 0xe0, 0xff, 0x1f, 0xff, 0xdf, 0xff, 0xbf, 0xff, 0x7f, 0xc9, 0xf0, 0x59, 0xf0, 0x01, 0x01, 0x03, + 0x01, 0x80, 0x00, 0x39, 0xf0, 0x89, 0xf0, 0x00, 0x40, 0x00, 0x80, 0x88, 0x00, 0x5e, 0xf0, 0x00, 0x20, 0x00, 0x10, + 0x00, 0x08, 0x53, 0x00, 0x5a, 0x00, 0x9a, 0x01, 0x60, 0x00, 0x00, 0x0c, 0x8c, 0x00, 0x00, 0xf8, 0xa0, 0x00, 0xe8, + 0x03, 0x01, 0x80, 0xb8, 0x7e, 0xe1, 0x7a, 0x1a, 0x01, 0x66, 0x00, 0xf0, 0x00, 0x6e, 0x00, 0x71, 0x00, 0x71, 0x00, + 0x80, 0x50, 0xf1, 0x7f, 0xd0, 0x7f, 0xe2, 0x7f, 0xcb, 0x7f, 0x00, 0x2e, 0x03, 0x2e, 0x01, 0x01, 0x01, 0x2e, 0x03, + 0x01, 0x05, 0x2e, 0x04, 0x01, 0x9d, 0xb8, 0x0d, 0xb8, 0x2f, 0xbd, 0x08, 0x0a, 0x2f, 0xb9, 0x02, 0x0a, 0x05, 0x2e, + 0x1b, 0x01, 0x03, 0x2e, 0x07, 0x01, 0x26, 0xbd, 0x2f, 0xb9, 0x93, 0xbc, 0x9f, 0xb8, 0x02, 0x0a, 0x81, 0x0a, 0x80, + 0xb2, 0x10, 0x2f, 0xb7, 0x7f, 0x83, 0x7f, 0x94, 0x7f, 0xa5, 0x7f, 0x72, 0x25, 0x79, 0x50, 0x4f, 0x52, 0x98, 0x2e, + 0xe5, 0x00, 0x10, 0x30, 0x27, 0x25, 0x21, 0x2e, 0x76, 0x00, 0x83, 0x6f, 0x94, 0x6f, 0xa5, 0x6f, 0xb7, 0x6f, 0x01, + 0x2e, 0x76, 0x00, 0x02, 0x0a, 0x00, 0xb2, 0x07, 0x2f, 0x1b, 0x30, 0x80, 0x90, 0x37, 0x2e, 0x4b, 0x00, 0x00, 0x30, + 0x01, 0x2f, 0x21, 0x2e, 0x76, 0x00, 0x98, 0x2e, 0xc8, 0x00, 0x00, 0xb2, 0x02, 0x2f, 0x75, 0x50, 0x21, 0x2e, 0xba, + 0xf0, 0x00, 0x31, 0x21, 0x2e, 0xb8, 0xf0, 0xf1, 0x6f, 0xd0, 0x6f, 0xe2, 0x6f, 0xcb, 0x6f, 0x80, 0x5f, 0xc8, 0x2e, + 0x30, 0x50, 0x00, 0x30, 0x7b, 0x56, 0x05, 0x30, 0x05, 0x2c, 0xfb, 0x7f, 0x3e, 0xbe, 0xd2, 0xba, 0xb2, 0xb9, 0x6c, + 0x0b, 0x53, 0x0e, 0xf9, 0x2f, 0x53, 0x1a, 0x01, 0x2f, 0x4d, 0x0e, 0xf5, 0x2f, 0xd2, 0x7f, 0x04, 0x30, 0x1f, 0x2c, + 0xe1, 0x7f, 0xc5, 0x01, 0xa3, 0x03, 0x72, 0x0e, 0x03, 0x2f, 0x72, 0x1a, 0x0f, 0x2f, 0x79, 0x0f, 0x0d, 0x2f, 0xe1, + 0x6f, 0x4f, 0x04, 0x5f, 0xb9, 0xb1, 0xbf, 0xfa, 0x0b, 0xd2, 0x6f, 0x96, 0x06, 0xb1, 0x25, 0x51, 0xbf, 0xeb, 0x7f, + 0x06, 0x00, 0xb2, 0x25, 0x27, 0x03, 0xdb, 0x7f, 0xcf, 0xbf, 0x3e, 0xbf, 0x01, 0xb8, 0xd2, 0xba, 0x41, 0xba, 0xb2, + 0xb9, 0x07, 0x0a, 0x6e, 0x0b, 0xc0, 0x90, 0xdf, 0x2f, 0x40, 0x91, 0xdd, 0x2f, 0xfb, 0x6f, 0xd0, 0x5f, 0xb8, 0x2e, + 0x10, 0x50, 0xfb, 0x7f, 0x21, 0x25, 0x98, 0x2e, 0xee, 0xb1, 0xfb, 0x6f, 0x21, 0x25, 0xf0, 0x5f, 0x10, 0x25, 0x80, + 0x2e, 0xa2, 0x01, 0x03, 0x30, 0x15, 0x40, 0xd9, 0x04, 0x2b, 0x0e, 0x1d, 0x23, 0x29, 0x0f, 0x15, 0x40, 0x0c, 0x23, + 0x2b, 0x0e, 0x9d, 0x23, 0x29, 0x0f, 0x4e, 0x23, 0x00, 0x40, 0x03, 0x0e, 0xd8, 0x22, 0x01, 0x0f, 0x94, 0x42, 0x4b, + 0x22, 0x95, 0x42, 0x81, 0x42, 0xb8, 0x2e, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0xfd, 0x2d, 0x6d, 0x52, + 0x53, 0x50, 0x60, 0x42, 0x00, 0x3f, 0x55, 0x54, 0x42, 0x42, 0x69, 0x82, 0x57, 0x54, 0x42, 0x42, 0x42, 0x82, 0x0b, + 0x31, 0x42, 0x40, 0x10, 0x08, 0x50, 0x42, 0x7e, 0x80, 0x4b, 0x42, 0xf1, 0x31, 0x01, 0x42, 0x10, 0x50, 0x08, 0x80, + 0xf0, 0x7f, 0x30, 0x30, 0x03, 0x2e, 0x40, 0xf0, 0x56, 0x90, 0x1f, 0x2f, 0x03, 0x30, 0x5f, 0x52, 0x59, 0x54, 0x54, + 0x34, 0x06, 0x30, 0x5b, 0x50, 0x55, 0x32, 0x1d, 0x1a, 0xe3, 0x22, 0x18, 0x1a, 0x5d, 0x58, 0xe3, 0x22, 0x04, 0x30, + 0xd5, 0x40, 0xb5, 0x0d, 0xe1, 0xbe, 0x6f, 0xbb, 0x80, 0x91, 0xa9, 0x0d, 0x01, 0x89, 0xb5, 0x23, 0x10, 0xa1, 0xf7, + 0x2f, 0xda, 0x0e, 0x54, 0x34, 0xeb, 0x2f, 0x01, 0x2e, 0x25, 0x00, 0x70, 0x1a, 0x00, 0x30, 0x21, 0x30, 0x08, 0x22, + 0x00, 0xb2, 0x06, 0x2f, 0x21, 0x2e, 0x59, 0xf0, 0x98, 0x2e, 0xf6, 0x00, 0x00, 0x2e, 0x00, 0x2e, 0xd0, 0x2e, 0xf0, + 0x6f, 0x01, 0x31, 0x20, 0x26, 0x01, 0x42, 0x10, 0x30, 0x21, 0x2e, 0x59, 0xf0, 0x98, 0x2e, 0xf6, 0x00, 0x3f, 0x50, + 0x41, 0x52, 0x98, 0x2e, 0xfa, 0xb2, 0x3f, 0x50, 0x05, 0x84, 0x14, 0x30, 0x43, 0x50, 0x63, 0x30, 0x45, 0x52, 0x94, + 0x42, 0x83, 0x42, 0x98, 0x2e, 0xfa, 0xb2, 0x43, 0x50, 0x73, 0x30, 0x06, 0x80, 0x49, 0x54, 0x47, 0x52, 0x03, 0x42, + 0x25, 0x2e, 0x98, 0x00, 0x6f, 0x50, 0x23, 0x2e, 0x8b, 0x00, 0xf0, 0x7f, 0x00, 0x2e, 0x00, 0x2e, 0xd0, 0x2e, 0x01, + 0x2e, 0x16, 0x01, 0x83, 0xbc, 0x9f, 0xb8, 0x01, 0xbc, 0x23, 0x2e, 0x74, 0x00, 0x8e, 0xb8, 0x01, 0x2e, 0x74, 0x00, + 0x23, 0x2e, 0x4e, 0x00, 0x00, 0x90, 0x02, 0x2f, 0x40, 0x30, 0x21, 0x2e, 0x4d, 0x00, 0x98, 0x2e, 0x4d, 0xb2, 0x01, + 0x2e, 0x4b, 0x00, 0x00, 0xb2, 0x90, 0x2e, 0x64, 0xb1, 0x01, 0x2e, 0x4d, 0x00, 0x03, 0xa0, 0x7b, 0x2f, 0x03, 0xb2, + 0x06, 0x2f, 0x71, 0x52, 0x73, 0x50, 0x21, 0x2e, 0x8a, 0x00, 0x23, 0x2e, 0x80, 0x00, 0x5b, 0x2d, 0x07, 0x2e, 0x01, + 0x01, 0xb2, 0xbc, 0x9f, 0xb8, 0x10, 0x30, 0x88, 0x08, 0x09, 0x2e, 0x52, 0x00, 0x67, 0x52, 0x21, 0x09, 0x2d, 0xbd, + 0x22, 0x0b, 0x31, 0xbd, 0x2f, 0xb9, 0x29, 0x2e, 0x52, 0x00, 0x50, 0x09, 0x09, 0x2e, 0x52, 0x00, 0x69, 0x54, 0xde, + 0xbe, 0x22, 0x09, 0x25, 0x0b, 0x29, 0x2e, 0x52, 0x00, 0xbf, 0xba, 0x07, 0x2e, 0x52, 0x00, 0x6b, 0x58, 0x68, 0x09, + 0x1c, 0x09, 0xdf, 0xbe, 0x25, 0x0b, 0x07, 0x2e, 0x03, 0x01, 0xb2, 0xbe, 0xdf, 0xba, 0x29, 0x2e, 0x52, 0x00, 0x28, + 0x09, 0x0b, 0x2e, 0x4e, 0x00, 0x56, 0x30, 0x75, 0x05, 0x33, 0xbf, 0x63, 0xbb, 0x75, 0x13, 0x40, 0xb3, 0x45, 0x23, + 0x65, 0x5c, 0x6e, 0x09, 0x0d, 0x2e, 0x75, 0x00, 0x63, 0x5e, 0xb7, 0x09, 0x75, 0x0b, 0x2b, 0x2e, 0x75, 0x00, 0x0b, + 0x2e, 0x75, 0x00, 0x4d, 0xbe, 0x69, 0x08, 0x0c, 0x0b, 0xb1, 0xbc, 0x9f, 0xb8, 0x29, 0x2e, 0x75, 0x00, 0x08, 0x09, + 0x03, 0x2e, 0x75, 0x00, 0x4e, 0xbe, 0x4a, 0x08, 0x4c, 0x0a, 0x23, 0x2e, 0x75, 0x00, 0xbf, 0xb8, 0x88, 0x08, 0x01, + 0x2e, 0x75, 0x00, 0x6b, 0x52, 0x01, 0x08, 0x2f, 0xbd, 0x02, 0x0a, 0x4b, 0x54, 0x4d, 0x52, 0x21, 0x2e, 0x75, 0x00, + 0x25, 0x2e, 0x80, 0x00, 0x23, 0x2e, 0x8a, 0x00, 0x4f, 0x50, 0x98, 0x2e, 0x0d, 0xb2, 0x4f, 0x50, 0x3f, 0x52, 0x98, + 0x2e, 0x0b, 0xb3, 0x4f, 0x50, 0x43, 0x52, 0x98, 0x2e, 0x0b, 0xb3, 0x01, 0x2e, 0x4d, 0x00, 0x04, 0x90, 0x08, 0x2f, + 0x4f, 0x50, 0x98, 0x2e, 0x85, 0xb6, 0x4f, 0x50, 0x98, 0x2e, 0xe9, 0xb4, 0x4f, 0x50, 0x98, 0x2e, 0x8a, 0xb3, 0x05, + 0x2e, 0x4d, 0x00, 0x82, 0xb2, 0x51, 0x2f, 0x80, 0xb2, 0x4f, 0x2f, 0x81, 0xb2, 0x61, 0x50, 0x41, 0x2f, 0x83, 0xb2, + 0x03, 0x2e, 0x7e, 0x00, 0x2f, 0x2f, 0x84, 0x90, 0x53, 0x2f, 0x05, 0x2e, 0x74, 0x00, 0x80, 0x90, 0x03, 0x2f, 0x00, + 0x30, 0x21, 0x2e, 0x50, 0x00, 0x4c, 0x2d, 0x07, 0x2e, 0x88, 0x00, 0x05, 0x2e, 0x16, 0x01, 0xc0, 0xb2, 0x06, 0x2f, + 0x13, 0x30, 0xd3, 0x08, 0xc0, 0xb2, 0x02, 0x2f, 0x03, 0x30, 0x27, 0x2e, 0x4d, 0x00, 0x07, 0x2e, 0x78, 0x00, 0x59, + 0x0a, 0x40, 0xb2, 0x02, 0x2f, 0x01, 0x30, 0x23, 0x2e, 0x50, 0x00, 0x21, 0x30, 0x51, 0x08, 0x40, 0xb2, 0x32, 0x2f, + 0x03, 0x2e, 0x50, 0x00, 0x10, 0x08, 0x41, 0x82, 0x02, 0xb8, 0x23, 0x2e, 0x50, 0x00, 0x48, 0x0e, 0x29, 0x2f, 0x00, + 0x30, 0x21, 0x2e, 0x4d, 0x00, 0x26, 0x2d, 0x40, 0xb2, 0x23, 0x2f, 0x11, 0x30, 0x40, 0x30, 0x02, 0x30, 0x23, 0x2e, + 0x77, 0x00, 0x23, 0x2e, 0x81, 0x00, 0x21, 0x2e, 0x4d, 0x00, 0x25, 0x2e, 0x50, 0x00, 0x18, 0x2d, 0x01, 0x2e, 0x51, + 0x00, 0x3f, 0x80, 0x21, 0x2e, 0x51, 0x00, 0x00, 0xaa, 0x10, 0x2f, 0x30, 0x30, 0x21, 0x2e, 0x4d, 0x00, 0x0d, 0x2d, + 0x03, 0x2e, 0x4e, 0x00, 0x02, 0x32, 0x10, 0x30, 0x51, 0x10, 0x21, 0x2e, 0x77, 0x00, 0x21, 0x2e, 0x81, 0x00, 0x21, + 0x2e, 0x4d, 0x00, 0x23, 0x2e, 0x51, 0x00, 0x03, 0x30, 0x27, 0x2e, 0x4b, 0x00, 0x01, 0x2e, 0x00, 0xf0, 0x09, 0x2e, + 0x16, 0x01, 0x05, 0x2e, 0x74, 0x00, 0x4f, 0xba, 0x80, 0x90, 0x03, 0x2e, 0x4f, 0x00, 0x06, 0x2f, 0x40, 0xb2, 0x00, + 0x30, 0x29, 0x2f, 0x27, 0x2e, 0x4f, 0x00, 0x27, 0x2c, 0x01, 0x25, 0x40, 0x90, 0x01, 0x2f, 0x21, 0x2e, 0x4f, 0x00, + 0x03, 0x2e, 0x4d, 0x00, 0x40, 0xb2, 0x12, 0x2f, 0x44, 0x90, 0x00, 0x30, 0x1a, 0x2f, 0x00, 0xb3, 0x01, 0x2e, 0x4f, + 0x00, 0x16, 0x2f, 0x98, 0x2e, 0xc8, 0x00, 0x00, 0xb2, 0x70, 0x32, 0x11, 0x2f, 0x91, 0x31, 0x98, 0x2e, 0xe0, 0x00, + 0x00, 0x90, 0x90, 0x30, 0x0c, 0x2c, 0x08, 0x22, 0x00, 0x91, 0x01, 0x2f, 0x21, 0x2e, 0x4f, 0x00, 0x21, 0x33, 0x22, + 0x30, 0x01, 0x2e, 0x4e, 0x00, 0x01, 0x00, 0x25, 0x2e, 0x4d, 0x00, 0x00, 0xb2, 0x01, 0x2f, 0x21, 0x2e, 0x00, 0xf0, + 0x01, 0x2e, 0x4c, 0x00, 0x00, 0x90, 0x03, 0x2f, 0x01, 0x2e, 0x65, 0x00, 0x00, 0xb2, 0x09, 0x2f, 0x51, 0x50, 0x98, + 0x2e, 0x0d, 0xb2, 0x51, 0x50, 0x98, 0x2e, 0x30, 0xb5, 0x51, 0x50, 0x98, 0x2e, 0x4b, 0xb7, 0x03, 0x30, 0x27, 0x2e, + 0x4c, 0x00, 0x98, 0x2e, 0xf6, 0x00, 0xf0, 0x6f, 0xf3, 0x3e, 0x02, 0x40, 0x03, 0x2e, 0x4d, 0x00, 0xd3, 0x08, 0x04, + 0x31, 0x94, 0x0a, 0x43, 0x90, 0x5a, 0x22, 0x01, 0x42, 0x3c, 0x80, 0x00, 0x2e, 0x01, 0x40, 0x01, 0x42, 0x04, 0x80, + 0x80, 0x2e, 0x65, 0xb0, 0x94, 0x01, 0xdd, 0x03, 0xc0, 0xad, 0x0b, 0x2f, 0xc0, 0xa8, 0x03, 0x2f, 0xc0, 0x90, 0x07, + 0x2f, 0x80, 0xa6, 0x05, 0x2f, 0x40, 0xa9, 0x12, 0x2f, 0x40, 0x91, 0x01, 0x2f, 0x00, 0xab, 0x0e, 0x2f, 0xc0, 0xac, + 0x00, 0x30, 0x7d, 0x52, 0x07, 0x2f, 0xc0, 0xa9, 0x03, 0x2f, 0xc0, 0x91, 0x03, 0x2f, 0x80, 0xa7, 0x01, 0x2f, 0x40, + 0xa1, 0x05, 0x2f, 0xc0, 0x2e, 0x17, 0x25, 0x06, 0x25, 0xc0, 0x2e, 0xf0, 0x3f, 0x6b, 0x52, 0xb8, 0x2e, 0x83, 0x86, + 0x01, 0x30, 0x00, 0x30, 0x94, 0x40, 0x24, 0x18, 0x06, 0x00, 0x53, 0x0e, 0x4f, 0x02, 0xf9, 0x2f, 0xb8, 0x2e, 0x80, + 0xa8, 0x03, 0x25, 0x10, 0x2f, 0x80, 0x90, 0x01, 0x2f, 0x41, 0x0e, 0x0c, 0x2f, 0xf3, 0x3f, 0x18, 0x05, 0x05, 0x30, + 0x5d, 0x07, 0x15, 0x0e, 0x03, 0x2f, 0x55, 0x1a, 0x02, 0x2f, 0xcc, 0x0f, 0x00, 0x2f, 0x58, 0x04, 0x01, 0x25, 0xb8, + 0x2e, 0xb8, 0x2e, 0x60, 0x50, 0x03, 0x2e, 0x1e, 0x01, 0xe0, 0x7f, 0xf1, 0x7f, 0xdb, 0x7f, 0x30, 0x30, 0x7f, 0x54, + 0x0a, 0x1a, 0x28, 0x2f, 0x1a, 0x25, 0x7a, 0x82, 0x00, 0x30, 0x43, 0x30, 0x32, 0x30, 0x05, 0x30, 0x04, 0x30, 0xf6, + 0x6f, 0xf2, 0x09, 0xfc, 0x13, 0xc2, 0xab, 0xb3, 0x09, 0xef, 0x23, 0x80, 0xb3, 0xe6, 0x6f, 0xb7, 0x01, 0x00, 0x2e, + 0x8b, 0x41, 0x4b, 0x42, 0x03, 0x2f, 0x46, 0x40, 0x86, 0x17, 0x81, 0x8d, 0x46, 0x42, 0x41, 0x8b, 0x23, 0xbd, 0xb3, + 0xbd, 0x03, 0x89, 0x41, 0x82, 0x07, 0x0c, 0x43, 0xa3, 0xe6, 0x2f, 0xe1, 0x6f, 0xa2, 0x6f, 0x52, 0x42, 0x00, 0x2e, + 0xb2, 0x6f, 0x52, 0x42, 0x00, 0x2e, 0xc2, 0x6f, 0x42, 0x42, 0x03, 0xb2, 0x03, 0x2e, 0x59, 0xf0, 0xf3, 0x3d, 0x02, + 0x32, 0x0b, 0x08, 0x8a, 0x0a, 0xdb, 0x6f, 0x02, 0x22, 0xa0, 0x5f, 0x21, 0x2e, 0x59, 0xf0, 0xb8, 0x2e, 0x03, 0x2e, + 0x00, 0xf0, 0x07, 0x2e, 0x00, 0xf0, 0xbc, 0xbe, 0x05, 0x2e, 0x16, 0x01, 0x6f, 0x50, 0xaf, 0xb9, 0x02, 0x40, 0xf4, + 0x33, 0xdc, 0xba, 0xc1, 0xb2, 0x94, 0x08, 0x0e, 0x2f, 0x07, 0x2e, 0x4d, 0x00, 0xc4, 0x90, 0x0a, 0x2f, 0x75, 0x56, + 0xcb, 0x0f, 0x07, 0x2f, 0x49, 0xaf, 0x05, 0x2f, 0x75, 0x52, 0x51, 0x0a, 0x02, 0x34, 0x47, 0xa3, 0x8a, 0x0a, 0x91, + 0x22, 0x3c, 0x80, 0x25, 0x2e, 0x59, 0xf0, 0x01, 0x40, 0x01, 0x42, 0xb8, 0x2e, 0x70, 0x50, 0x42, 0x8e, 0xd4, 0x7f, + 0xf6, 0x7f, 0x47, 0x25, 0x1a, 0x18, 0x83, 0x52, 0xf1, 0x00, 0x64, 0x25, 0x01, 0x30, 0x39, 0x02, 0x94, 0x41, 0x81, + 0x41, 0xe2, 0x7f, 0xbe, 0xbb, 0xbd, 0x8d, 0x02, 0xbd, 0xb5, 0x7f, 0x8e, 0xb5, 0xba, 0x0a, 0xc6, 0x7f, 0xab, 0x7f, + 0x51, 0x25, 0x98, 0x2e, 0xcb, 0xb1, 0xd5, 0x6f, 0xe2, 0x6f, 0x2a, 0x18, 0x83, 0x54, 0xb2, 0x01, 0x02, 0x30, 0xc4, + 0x6f, 0x7a, 0x03, 0x12, 0x41, 0x74, 0x25, 0xd0, 0x7f, 0x52, 0xbc, 0xd3, 0x41, 0x6e, 0xba, 0xde, 0xb6, 0x20, 0x0b, + 0xc7, 0x7f, 0x91, 0x7f, 0x98, 0x2e, 0xcb, 0xb1, 0xf2, 0x6f, 0xd5, 0x6f, 0xca, 0x16, 0x55, 0x18, 0xdd, 0x18, 0x95, + 0x6f, 0xea, 0x18, 0x83, 0x5a, 0x31, 0x25, 0x75, 0x01, 0x01, 0x30, 0x20, 0x25, 0x39, 0x02, 0x5e, 0xba, 0x82, 0xbc, + 0x8e, 0xb6, 0x21, 0x0b, 0x98, 0x2e, 0xcb, 0xb1, 0xe2, 0x6f, 0xb5, 0x6f, 0x2a, 0x18, 0xe0, 0x7f, 0xf1, 0x7f, 0x04, + 0x30, 0x83, 0x54, 0xf2, 0x00, 0x7c, 0x02, 0x85, 0x6f, 0xd0, 0x6f, 0x0d, 0x17, 0x68, 0x18, 0xe0, 0x18, 0x90, 0x6f, + 0xc4, 0x6f, 0xc5, 0x18, 0xeb, 0x6f, 0xb2, 0x01, 0x1b, 0x43, 0x02, 0x30, 0x7a, 0x03, 0xfb, 0x6f, 0x3d, 0x8f, 0x0b, + 0x43, 0x3e, 0xba, 0x12, 0xbd, 0x52, 0xbc, 0x6e, 0xbb, 0xa2, 0x0a, 0x9e, 0xb5, 0xde, 0xb6, 0x30, 0x0b, 0xf7, 0x7f, + 0x98, 0x2e, 0xcb, 0xb1, 0xf5, 0x6f, 0x31, 0x25, 0xd1, 0x6f, 0x92, 0x6f, 0xab, 0x6f, 0x50, 0x43, 0x43, 0x43, 0x90, + 0x5f, 0x6b, 0x56, 0x80, 0x2e, 0xf8, 0xb1, 0x10, 0x50, 0x03, 0x40, 0x19, 0x18, 0x7d, 0x56, 0x19, 0x05, 0x36, 0x25, + 0xf7, 0x7f, 0x4a, 0x17, 0x54, 0x18, 0xec, 0x18, 0x09, 0x17, 0x01, 0x30, 0x0c, 0x07, 0xe2, 0x18, 0xde, 0x00, 0xf2, + 0x6f, 0x97, 0x02, 0x7b, 0x58, 0xdc, 0x00, 0x91, 0x02, 0xbf, 0xb8, 0x21, 0xbd, 0x8a, 0x0a, 0xc0, 0x2e, 0x02, 0x42, + 0xf0, 0x5f, 0x0a, 0x86, 0x02, 0x30, 0x12, 0x42, 0x43, 0x0e, 0xfc, 0x2f, 0x36, 0x80, 0x13, 0x30, 0x13, 0x42, 0x12, + 0x42, 0x12, 0x42, 0x12, 0x42, 0x02, 0x42, 0x04, 0x80, 0x41, 0x84, 0x11, 0x42, 0x02, 0x42, 0xb8, 0x2e, 0x46, 0x86, + 0x80, 0x50, 0xe4, 0x40, 0xc4, 0x84, 0xbe, 0x8e, 0x85, 0x40, 0xf4, 0x7f, 0x42, 0x88, 0x42, 0x41, 0x2d, 0xbb, 0x02, + 0x30, 0xc2, 0x43, 0x80, 0xb3, 0xc3, 0x40, 0xe6, 0x7f, 0xd0, 0x7f, 0xc4, 0x7f, 0x68, 0x2f, 0x41, 0x25, 0x57, 0x40, + 0xb1, 0x7f, 0xc1, 0x91, 0x0e, 0x2f, 0x02, 0x43, 0x00, 0x2e, 0xc1, 0x6f, 0x13, 0x40, 0x53, 0x42, 0x00, 0x2e, 0x13, + 0x40, 0x53, 0x42, 0x00, 0x2e, 0x00, 0x40, 0x40, 0x42, 0x7d, 0x80, 0xc0, 0x2e, 0x02, 0x42, 0x80, 0x5f, 0x08, 0x89, + 0x11, 0x30, 0x07, 0x41, 0xa7, 0x7f, 0x3a, 0x89, 0xc7, 0x41, 0x45, 0x41, 0xd3, 0xbe, 0xf5, 0xbf, 0xd3, 0xba, 0xf5, + 0xbb, 0x85, 0x7f, 0x97, 0x7f, 0x05, 0x30, 0xca, 0x15, 0xf7, 0x09, 0xc0, 0xb3, 0x0a, 0x2f, 0x06, 0x40, 0x07, 0x41, + 0xb7, 0x05, 0x07, 0x30, 0x80, 0xa9, 0xfe, 0x05, 0xb7, 0x23, 0x97, 0x6f, 0x77, 0x0f, 0x4d, 0x23, 0xe6, 0x6f, 0xc0, + 0xb2, 0x06, 0x2f, 0xa7, 0x6f, 0x85, 0x5c, 0xc7, 0x41, 0xbe, 0x09, 0x80, 0xb3, 0xe6, 0x6f, 0x01, 0x2f, 0x07, 0x40, + 0x07, 0x43, 0x81, 0x84, 0x01, 0x80, 0x01, 0x89, 0x83, 0xa2, 0xe0, 0x2f, 0xb0, 0x6f, 0x2b, 0x1a, 0x02, 0x2f, 0x01, + 0x30, 0x25, 0x2c, 0x01, 0x42, 0x02, 0x40, 0x91, 0x28, 0x83, 0x6f, 0x02, 0x42, 0x53, 0x0e, 0x1d, 0x2f, 0xf2, 0x6f, + 0x80, 0xb2, 0x03, 0x2f, 0xbf, 0x84, 0x8a, 0x14, 0x25, 0x2e, 0x5e, 0xf0, 0xd4, 0x6f, 0xc3, 0x6f, 0x12, 0x41, 0xd2, + 0x42, 0x02, 0x30, 0x15, 0x41, 0xd5, 0x42, 0x00, 0x2e, 0x04, 0x41, 0xc4, 0x42, 0xc3, 0x86, 0xa5, 0x6f, 0x87, 0x58, + 0x45, 0x41, 0x2c, 0x09, 0xc1, 0x42, 0x00, 0xb3, 0x04, 0x2f, 0x00, 0x2e, 0x03, 0x2c, 0x02, 0x42, 0x10, 0x30, 0x40, + 0x42, 0x80, 0x5f, 0xb8, 0x2e, 0x03, 0x2e, 0x04, 0x01, 0x1f, 0xbd, 0xe0, 0x50, 0x2f, 0xb9, 0xf0, 0x7f, 0x80, 0xb2, + 0xeb, 0x7f, 0x90, 0x2e, 0x64, 0xb4, 0x13, 0x40, 0x14, 0xbd, 0xd0, 0x7f, 0x2a, 0xba, 0x05, 0x30, 0x12, 0x40, 0xc4, + 0x7f, 0xc0, 0xa8, 0xeb, 0x05, 0x3e, 0x88, 0xdf, 0x22, 0xb4, 0x7f, 0x80, 0xa8, 0x2a, 0x05, 0x94, 0x22, 0x9c, 0xbf, + 0x04, 0x40, 0xfe, 0xbb, 0x89, 0x5c, 0x00, 0xa9, 0x01, 0x2e, 0x05, 0x01, 0x6c, 0x05, 0xf7, 0x01, 0x05, 0xbc, 0x25, + 0x23, 0x05, 0xb8, 0xc5, 0x41, 0xd8, 0x05, 0x2f, 0x2a, 0x9a, 0xbf, 0xb7, 0x25, 0x9e, 0xbf, 0x61, 0xb7, 0x1b, 0x25, + 0xff, 0xbb, 0x9e, 0xb8, 0x96, 0x0f, 0x07, 0x2f, 0xa3, 0x7f, 0x00, 0x2e, 0xf3, 0x6f, 0x00, 0x2e, 0xc3, 0x40, 0xc0, + 0xac, 0xa3, 0x6f, 0x26, 0x2f, 0x96, 0x0f, 0x04, 0x2f, 0xf6, 0x6f, 0x00, 0x2e, 0x86, 0x41, 0x80, 0xa1, 0x1b, 0x2f, + 0xb7, 0x25, 0x2b, 0x2a, 0xe1, 0xb5, 0x18, 0x28, 0x90, 0x0e, 0x5b, 0x25, 0x04, 0x2f, 0xd3, 0x6f, 0x00, 0x2e, 0xc3, + 0x40, 0xc0, 0xa0, 0x0a, 0x2f, 0x90, 0x0e, 0x0b, 0x2f, 0xd0, 0x6f, 0x00, 0x2e, 0x00, 0x40, 0x00, 0xa0, 0x06, 0x2f, + 0x00, 0x30, 0x21, 0x2e, 0x58, 0x00, 0x03, 0x2d, 0x20, 0x30, 0x21, 0x2e, 0x58, 0x00, 0x08, 0x2c, 0x75, 0x25, 0x30, + 0x30, 0x21, 0x2e, 0x58, 0x00, 0x03, 0x2d, 0x10, 0x30, 0x21, 0x2e, 0x58, 0x00, 0xc0, 0x91, 0xf2, 0x6f, 0x01, 0x2e, + 0x57, 0x00, 0x03, 0x2f, 0x03, 0x30, 0x27, 0x2e, 0x59, 0x00, 0x12, 0x2d, 0x8d, 0x56, 0x63, 0x0f, 0x03, 0x2f, 0x82, + 0xb9, 0x27, 0x2e, 0x59, 0x00, 0x0b, 0x2d, 0x82, 0x88, 0x13, 0x30, 0x04, 0x41, 0x00, 0xad, 0x02, 0x2f, 0x27, 0x2e, + 0x59, 0x00, 0x03, 0x2d, 0x03, 0x30, 0x27, 0x2e, 0x59, 0x00, 0x35, 0x30, 0x07, 0x2e, 0x58, 0x00, 0x09, 0x2e, 0x59, + 0x00, 0xdd, 0x08, 0x42, 0xbe, 0xdc, 0x0a, 0x03, 0x1a, 0xd3, 0x7f, 0x00, 0x30, 0x2f, 0x2f, 0x40, 0xa4, 0x2d, 0x2f, + 0x43, 0x90, 0x03, 0x30, 0x10, 0x2f, 0x09, 0x2e, 0x5f, 0x00, 0x10, 0x30, 0x60, 0x29, 0x09, 0x2e, 0x5d, 0x00, 0xd7, + 0x6f, 0x27, 0x1a, 0x2b, 0x2e, 0x5f, 0x00, 0x01, 0x2f, 0x27, 0x2e, 0x5f, 0x00, 0x09, 0x2e, 0x5f, 0x00, 0x05, 0xa3, + 0x03, 0x22, 0x00, 0x90, 0x04, 0x2f, 0x8b, 0x56, 0x98, 0x2e, 0xa2, 0xb4, 0xf2, 0x6f, 0x03, 0x30, 0x00, 0x90, 0x10, + 0x2f, 0x01, 0x2e, 0x5e, 0x00, 0x62, 0x7f, 0x1a, 0x25, 0xc2, 0x6f, 0x72, 0x7f, 0x83, 0x7f, 0x76, 0x82, 0x90, 0x7f, + 0x98, 0x2e, 0x67, 0xb4, 0x01, 0xb2, 0x21, 0x2e, 0x5e, 0x00, 0x11, 0x30, 0x00, 0x30, 0x08, 0x22, 0x01, 0xb2, 0xd1, + 0x6f, 0x01, 0x2e, 0x57, 0x00, 0x23, 0x2e, 0x5d, 0x00, 0x41, 0x22, 0x23, 0x2e, 0x52, 0xf0, 0xf1, 0x7f, 0x98, 0x2e, + 0xf6, 0x00, 0x01, 0x2e, 0x57, 0x00, 0xf1, 0x6f, 0x08, 0x1a, 0x20, 0x30, 0x01, 0x2f, 0x21, 0x2e, 0x5e, 0xf0, 0xb2, + 0x6f, 0x8b, 0x50, 0x93, 0x40, 0x13, 0x42, 0x00, 0x2e, 0x93, 0x40, 0x13, 0x42, 0x00, 0x2e, 0x82, 0x40, 0x02, 0x42, + 0x23, 0x2e, 0x57, 0x00, 0xeb, 0x6f, 0x20, 0x5f, 0xb8, 0x2e, 0x60, 0x50, 0x2a, 0x25, 0xba, 0x84, 0x00, 0x30, 0x80, + 0x42, 0xb0, 0x7f, 0xc0, 0x7f, 0xf1, 0x7f, 0x42, 0x86, 0x40, 0x40, 0x85, 0x52, 0xe3, 0x7f, 0xdb, 0x7f, 0x98, 0x2e, + 0xe6, 0x01, 0xb1, 0x6f, 0x09, 0x18, 0xa1, 0x6f, 0x56, 0x25, 0x47, 0x25, 0x09, 0x18, 0x75, 0x00, 0xe0, 0x6f, 0xfc, + 0x02, 0xc2, 0x6f, 0x12, 0x18, 0x25, 0x40, 0x00, 0x40, 0x47, 0x25, 0x1a, 0xb9, 0x46, 0x18, 0xb6, 0xbd, 0xe0, 0x18, + 0xd4, 0xbe, 0x9a, 0x0a, 0x15, 0x00, 0x96, 0xbc, 0x47, 0x0e, 0x0f, 0x2f, 0x47, 0x1a, 0x01, 0x2f, 0x4e, 0x0e, 0x0b, + 0x2f, 0xfd, 0x00, 0x5a, 0x0e, 0x00, 0x30, 0x08, 0x2f, 0x5a, 0x1a, 0x01, 0x2f, 0x71, 0x0e, 0x04, 0x2f, 0xf1, 0x6f, + 0x43, 0x82, 0x02, 0x2c, 0x40, 0x40, 0x10, 0x30, 0xdb, 0x6f, 0xa0, 0x5f, 0xb8, 0x2e, 0x81, 0x8a, 0x82, 0x88, 0x41, + 0xb2, 0x01, 0x2f, 0x00, 0x2e, 0x02, 0x2d, 0x24, 0x2c, 0x00, 0x30, 0x42, 0xb2, 0x01, 0x2f, 0x43, 0x90, 0x37, 0x2f, + 0x80, 0x40, 0xc6, 0x40, 0x86, 0x05, 0x7e, 0x80, 0x8f, 0x52, 0xc8, 0x01, 0x00, 0x30, 0x80, 0xa9, 0x46, 0x04, 0xc7, + 0x41, 0x71, 0x22, 0x4f, 0x0f, 0x28, 0x2f, 0xc1, 0x8c, 0x41, 0x41, 0x86, 0x41, 0x4e, 0x04, 0x40, 0xa8, 0x81, 0x05, + 0x4e, 0x22, 0x4f, 0x0f, 0x1f, 0x2f, 0xc2, 0x82, 0x03, 0x41, 0x41, 0x40, 0xd9, 0x04, 0xc0, 0xa8, 0x43, 0x04, 0xd9, + 0x22, 0x5f, 0x0f, 0x16, 0x2f, 0x82, 0x40, 0x80, 0xa8, 0xc2, 0x04, 0x93, 0x22, 0x91, 0x56, 0x53, 0x0f, 0x0d, 0x2f, + 0x42, 0x41, 0x80, 0xa8, 0xc2, 0x04, 0x93, 0x22, 0x91, 0x56, 0x53, 0x0f, 0x06, 0x2f, 0x02, 0x41, 0x80, 0xa8, 0xc2, + 0x04, 0x93, 0x22, 0x91, 0x56, 0xd3, 0x0e, 0x05, 0x2f, 0x10, 0x30, 0xb8, 0x2e, 0x10, 0x30, 0xb8, 0x2e, 0x00, 0x30, + 0xb8, 0x2e, 0xb8, 0x2e, 0x05, 0x2e, 0x8b, 0x00, 0x81, 0x82, 0x40, 0x50, 0x41, 0x40, 0x93, 0xbd, 0xbf, 0xb9, 0xfb, + 0x7f, 0xc0, 0xb2, 0x0b, 0x30, 0x36, 0x2f, 0x07, 0x2e, 0x62, 0x00, 0xc0, 0x90, 0x04, 0x2f, 0xc1, 0x86, 0x27, 0x2e, + 0x62, 0x00, 0x37, 0x2e, 0x63, 0x00, 0x82, 0x86, 0x82, 0x40, 0x94, 0xbc, 0xc3, 0x40, 0x94, 0xb8, 0x21, 0xbd, 0xb4, + 0xbd, 0x21, 0xb9, 0xb4, 0xb9, 0xc1, 0x7f, 0xe3, 0x7f, 0xd2, 0x7f, 0x10, 0x25, 0x98, 0x2e, 0xdb, 0x01, 0xc2, 0x6f, + 0xd1, 0x6f, 0x8a, 0x28, 0x42, 0x0f, 0x0d, 0x2f, 0xc1, 0x0e, 0x05, 0x2e, 0x63, 0x00, 0x13, 0x30, 0x13, 0x28, 0x04, + 0x2f, 0x80, 0xa6, 0x08, 0x2f, 0x21, 0x2e, 0x63, 0x00, 0x06, 0x2d, 0x21, 0x2e, 0x63, 0x00, 0x03, 0x2d, 0x00, 0x30, + 0x21, 0x2e, 0x63, 0x00, 0x03, 0x2e, 0x63, 0x00, 0xe0, 0x6f, 0xc8, 0x0e, 0x40, 0x30, 0x04, 0x2f, 0x21, 0x2e, 0x5e, + 0xf0, 0x02, 0x2d, 0x37, 0x2e, 0x62, 0x00, 0xfb, 0x6f, 0xc0, 0x5f, 0xb8, 0x2e, 0x03, 0x2e, 0x09, 0x01, 0x72, 0x30, + 0x30, 0x50, 0xca, 0x08, 0xc0, 0x90, 0xfb, 0x7f, 0x0b, 0x2f, 0x01, 0x30, 0x23, 0x2e, 0x54, 0xf0, 0xe0, 0x7f, 0xd3, + 0x7f, 0x98, 0x2e, 0xf6, 0x00, 0x10, 0x30, 0x21, 0x2e, 0x65, 0x00, 0xe0, 0x6f, 0xd3, 0x6f, 0x03, 0x2e, 0x65, 0x00, + 0x40, 0x90, 0x93, 0x52, 0x15, 0x2f, 0x05, 0x2e, 0x64, 0x00, 0x8c, 0x88, 0x00, 0x2e, 0x03, 0x43, 0x30, 0x25, 0x98, + 0x2e, 0xa3, 0xb5, 0x00, 0xb2, 0x05, 0x2f, 0x21, 0x2e, 0x54, 0xf0, 0xe0, 0x7f, 0x98, 0x2e, 0xf6, 0x00, 0xe0, 0x6f, + 0x00, 0xa6, 0x10, 0x30, 0x08, 0x2f, 0x21, 0x2e, 0x5e, 0xf0, 0x06, 0x2d, 0x03, 0x30, 0x93, 0x50, 0x98, 0x2e, 0x68, + 0xb5, 0x27, 0x2e, 0x65, 0x00, 0xfb, 0x6f, 0xd0, 0x5f, 0xb8, 0x2e, 0x0c, 0x82, 0x02, 0x30, 0x12, 0x42, 0x41, 0x0e, + 0xfc, 0x2f, 0x35, 0x80, 0x87, 0x52, 0x11, 0x42, 0x00, 0x2e, 0x95, 0x52, 0x01, 0x42, 0xb8, 0x2e, 0x07, 0x88, 0x47, + 0x8e, 0x06, 0x41, 0x3c, 0x8b, 0x32, 0x1a, 0x42, 0x41, 0xc7, 0x41, 0x16, 0x2f, 0x80, 0x91, 0x23, 0x2f, 0x57, 0x0f, + 0x16, 0x30, 0x0c, 0x2f, 0x06, 0x80, 0x00, 0x2e, 0x00, 0x40, 0x00, 0xb2, 0x04, 0x2f, 0x46, 0x82, 0x00, 0x2e, 0x41, + 0x40, 0xd1, 0x0f, 0x02, 0x2f, 0x06, 0x30, 0x06, 0x43, 0x46, 0x43, 0x80, 0xb3, 0x11, 0x2f, 0x03, 0x43, 0x47, 0x43, + 0xb8, 0x2e, 0xd7, 0x0e, 0x0c, 0x2f, 0x44, 0x82, 0x17, 0x04, 0x41, 0x40, 0x41, 0x0f, 0x07, 0x2f, 0x03, 0x43, 0x42, + 0x83, 0x47, 0x43, 0x00, 0x2e, 0x43, 0x40, 0xc1, 0x86, 0x43, 0x42, 0xb8, 0x2e, 0xb8, 0x2e, 0x89, 0x88, 0xc0, 0x50, + 0x39, 0x8d, 0x88, 0x81, 0xe2, 0x7f, 0x02, 0x30, 0x05, 0x40, 0xf2, 0x7f, 0x41, 0xab, 0x22, 0x30, 0x95, 0x22, 0x86, + 0x41, 0x97, 0x5e, 0x9a, 0x00, 0x04, 0x41, 0x37, 0x18, 0x66, 0x01, 0x99, 0x56, 0xeb, 0x00, 0xc1, 0x7f, 0xb3, 0x7f, + 0xd5, 0x7f, 0x48, 0x82, 0x39, 0x80, 0x82, 0x40, 0xa0, 0x7f, 0x91, 0x7f, 0x8b, 0x7f, 0x06, 0x30, 0x7b, 0x5a, 0x9b, + 0x58, 0x7b, 0x56, 0x98, 0x2e, 0x71, 0xb2, 0x91, 0x6f, 0x7b, 0x82, 0xc6, 0x6f, 0x42, 0x40, 0x81, 0x84, 0x42, 0x42, + 0x43, 0x82, 0x83, 0x8b, 0x42, 0x40, 0x86, 0x89, 0x7b, 0x82, 0x84, 0x87, 0x71, 0x7f, 0x80, 0xb2, 0x95, 0x7f, 0x64, + 0x7f, 0x50, 0x7f, 0x02, 0x2f, 0xc5, 0x40, 0x41, 0x8b, 0xc5, 0x42, 0x87, 0x89, 0x67, 0x40, 0x07, 0x0f, 0x85, 0x8b, + 0x41, 0x7f, 0x82, 0x8d, 0x47, 0x40, 0x3d, 0x2f, 0x81, 0x41, 0x01, 0x0e, 0xe1, 0x6f, 0x2e, 0x2f, 0x47, 0x8c, 0x90, + 0x6f, 0x86, 0x41, 0x07, 0x40, 0xfe, 0x0e, 0x02, 0x2f, 0x04, 0x41, 0x00, 0xb3, 0x22, 0x2f, 0x45, 0x82, 0x04, 0x30, + 0x41, 0x40, 0x71, 0x00, 0xf9, 0x0e, 0x37, 0x2f, 0x46, 0x41, 0x80, 0xa7, 0x01, 0x30, 0x04, 0x30, 0x0e, 0x2f, 0xe4, + 0x6f, 0x01, 0x89, 0x00, 0x2e, 0x04, 0x41, 0x74, 0x0f, 0x04, 0x30, 0x07, 0x2f, 0x80, 0x90, 0x00, 0x2f, 0xc1, 0x42, + 0x03, 0x86, 0x81, 0x84, 0xc2, 0x42, 0x01, 0x42, 0x14, 0x30, 0x42, 0x85, 0x41, 0x43, 0xa1, 0x42, 0x00, 0x2e, 0x82, + 0x40, 0x80, 0x90, 0x1c, 0x2f, 0x01, 0x42, 0x1b, 0x2d, 0x06, 0x42, 0x19, 0x2c, 0x04, 0x30, 0xb2, 0x6f, 0xba, 0x04, + 0x02, 0x1e, 0x80, 0x43, 0x12, 0x30, 0xc0, 0x6f, 0x23, 0x30, 0x98, 0x2e, 0x74, 0xb5, 0x0e, 0x2c, 0x04, 0x30, 0xb2, + 0x6f, 0xc0, 0x6f, 0xba, 0x00, 0x51, 0x6f, 0x01, 0x86, 0x4a, 0x1c, 0xc1, 0x42, 0x22, 0x30, 0xe1, 0x6f, 0x13, 0x30, + 0x98, 0x2e, 0x74, 0xb5, 0x04, 0x30, 0x52, 0x6f, 0x9d, 0x52, 0x40, 0x6f, 0xc4, 0x7f, 0x98, 0x2e, 0xe0, 0xb2, 0x41, + 0x6f, 0x70, 0x6f, 0x42, 0x40, 0x9f, 0x52, 0x98, 0x2e, 0xe0, 0xb2, 0x41, 0x6f, 0x70, 0x6f, 0x42, 0x40, 0x01, 0x40, + 0xd3, 0x6f, 0xd3, 0x00, 0xcb, 0x1e, 0x9f, 0x52, 0x13, 0x42, 0xb0, 0x7f, 0x98, 0x2e, 0xe0, 0xb2, 0xb0, 0x6f, 0x3e, + 0x84, 0xd1, 0x6f, 0x82, 0x40, 0x03, 0x40, 0x51, 0x04, 0x59, 0x1c, 0x01, 0x42, 0x02, 0x82, 0xa0, 0x6f, 0x42, 0x40, + 0x03, 0x40, 0xd3, 0x0f, 0x00, 0x30, 0x14, 0x30, 0x60, 0x22, 0xc5, 0x6f, 0x40, 0x91, 0x01, 0x2f, 0x53, 0x0e, 0x26, + 0x2f, 0xe5, 0x6f, 0x48, 0x85, 0x00, 0x2e, 0x83, 0x40, 0x59, 0x0f, 0x20, 0x2f, 0x62, 0x6f, 0x4b, 0x8f, 0x85, 0x40, + 0xc7, 0x41, 0x7f, 0x8d, 0x6f, 0x0f, 0xa6, 0x15, 0x17, 0x30, 0x04, 0x30, 0x0f, 0x2f, 0xe0, 0x6f, 0x0c, 0x80, 0x00, + 0x2e, 0x07, 0x40, 0x3e, 0x08, 0x00, 0xb2, 0x00, 0x30, 0x06, 0x2f, 0x59, 0x1a, 0x04, 0x2f, 0xfd, 0x12, 0xc0, 0x90, + 0x13, 0x30, 0x4b, 0x22, 0x06, 0x25, 0x71, 0x25, 0xc0, 0xb3, 0x04, 0x2f, 0xa4, 0x42, 0xa4, 0x42, 0x83, 0x82, 0x84, + 0x42, 0x44, 0x42, 0x00, 0x2e, 0x8b, 0x6f, 0x40, 0x5f, 0xb8, 0x2e, 0x07, 0x2e, 0x1b, 0x01, 0x36, 0xbd, 0x30, 0x50, + 0x2f, 0xb9, 0x03, 0x2e, 0x6a, 0x00, 0x09, 0x2e, 0x69, 0x00, 0x80, 0xb2, 0xf0, 0x7f, 0x90, 0x2e, 0x19, 0xb7, 0xa1, + 0x54, 0x82, 0x80, 0xb7, 0xbe, 0x06, 0x40, 0xe9, 0xbf, 0x82, 0x40, 0x01, 0x2e, 0x6b, 0x00, 0x07, 0x2e, 0x00, 0xf0, + 0x21, 0xbd, 0xf6, 0x30, 0xd7, 0xba, 0x9e, 0x09, 0x00, 0xb2, 0x21, 0xb9, 0xf9, 0xbb, 0xeb, 0x7f, 0x51, 0x2f, 0x09, + 0x2e, 0x6c, 0x00, 0x01, 0xb2, 0x3f, 0x89, 0x21, 0x2f, 0x02, 0x90, 0x1d, 0x2f, 0x29, 0x2e, 0x6c, 0x00, 0xf1, 0x6f, + 0x98, 0x2e, 0x26, 0xb7, 0x00, 0x90, 0x00, 0x30, 0x06, 0x2f, 0x05, 0x2e, 0x6c, 0x00, 0x80, 0x90, 0x07, 0x2f, 0x21, + 0x2e, 0x6b, 0x00, 0x05, 0x2d, 0x02, 0x31, 0x25, 0x2e, 0x5e, 0xf0, 0x21, 0x2e, 0x6b, 0x00, 0xf2, 0x6f, 0xa3, 0x50, + 0x91, 0x40, 0x11, 0x42, 0x00, 0x2e, 0x91, 0x40, 0x11, 0x42, 0x00, 0x2e, 0x82, 0x40, 0x02, 0x42, 0x59, 0x2c, 0xeb, + 0x6f, 0x00, 0xb3, 0x29, 0x2e, 0x6c, 0x00, 0x16, 0x2f, 0x08, 0x91, 0x51, 0x2f, 0x75, 0x50, 0xd8, 0x0f, 0x4e, 0x2f, + 0x40, 0x90, 0x4c, 0x2f, 0x01, 0x2e, 0x00, 0xf0, 0x0c, 0xbc, 0x0c, 0xb8, 0x05, 0xa2, 0x46, 0x2f, 0x97, 0x50, 0x30, + 0x0a, 0x12, 0x30, 0x27, 0x2e, 0x69, 0x00, 0x21, 0x2e, 0x00, 0xf0, 0x25, 0x2e, 0x6a, 0x00, 0x3d, 0x2d, 0x20, 0x30, + 0x21, 0x2e, 0x6b, 0x00, 0x2f, 0x2e, 0x6c, 0x00, 0xf2, 0x6f, 0xa3, 0x50, 0x91, 0x40, 0x11, 0x42, 0x00, 0x2e, 0x91, + 0x40, 0x11, 0x42, 0x00, 0x2e, 0x82, 0x40, 0x2e, 0x2c, 0x02, 0x42, 0x41, 0x90, 0xd5, 0x7f, 0x07, 0x2f, 0xa5, 0x50, + 0x20, 0x08, 0x06, 0x0a, 0x0b, 0x30, 0x21, 0x2e, 0x00, 0xf0, 0x37, 0x2e, 0x6a, 0x00, 0xf1, 0x6f, 0x98, 0x2e, 0x26, + 0xb7, 0x00, 0xb2, 0x05, 0x2f, 0xd2, 0x6f, 0x10, 0x30, 0x25, 0x2e, 0x6c, 0x00, 0x21, 0x2e, 0x6b, 0x00, 0xf2, 0x6f, + 0xa3, 0x50, 0x91, 0x40, 0x11, 0x42, 0x00, 0x2e, 0x91, 0x40, 0x11, 0x42, 0x00, 0x2e, 0x82, 0x40, 0xeb, 0x6f, 0x0c, + 0x2c, 0x02, 0x42, 0x41, 0x90, 0x00, 0x30, 0x03, 0x2f, 0x29, 0x2e, 0x00, 0xf0, 0x21, 0x2e, 0x6a, 0x00, 0x21, 0x2e, + 0x6b, 0x00, 0x21, 0x2e, 0x6c, 0x00, 0xd0, 0x5f, 0xb8, 0x2e, 0xa3, 0x58, 0x00, 0x30, 0x15, 0x41, 0x56, 0x40, 0xc6, + 0x05, 0x13, 0x41, 0x56, 0x40, 0x04, 0x41, 0x6f, 0x29, 0x41, 0x40, 0xc6, 0x05, 0x41, 0x04, 0x61, 0x28, 0x85, 0x05, + 0x40, 0xa9, 0x30, 0x50, 0xdf, 0x28, 0x2e, 0x23, 0xe3, 0x7f, 0xf1, 0x7f, 0x62, 0x0f, 0x0b, 0x2f, 0xe1, 0x6f, 0x40, + 0xa8, 0xc1, 0x04, 0x4b, 0x22, 0x4a, 0x0f, 0x05, 0x2f, 0xf1, 0x6f, 0x40, 0xa8, 0xc1, 0x04, 0x4b, 0x22, 0xca, 0x0e, + 0x00, 0x2f, 0x10, 0x30, 0xd0, 0x5f, 0xb8, 0x2e, 0x05, 0x2e, 0x98, 0x00, 0x81, 0x82, 0xa0, 0x50, 0x41, 0x40, 0x3a, + 0x25, 0xf6, 0x86, 0x13, 0xbe, 0x4f, 0xba, 0x92, 0xbe, 0xc4, 0x42, 0xdf, 0xba, 0x11, 0xbf, 0xf3, 0x7f, 0xef, 0xb9, + 0x1f, 0xba, 0x75, 0x7f, 0x00, 0xb3, 0x83, 0x7f, 0xeb, 0x7f, 0x08, 0x2f, 0x63, 0x6f, 0xc0, 0x90, 0x08, 0x2f, 0x73, + 0x6f, 0xc0, 0x90, 0x05, 0x2f, 0x83, 0x6f, 0xc0, 0x90, 0x02, 0x2f, 0x03, 0x30, 0x27, 0x2e, 0x6d, 0x00, 0x09, 0x2e, + 0x6d, 0x00, 0x00, 0x91, 0x03, 0x30, 0xa7, 0x5a, 0xab, 0x5c, 0x07, 0x2f, 0xa7, 0x5e, 0x00, 0x2e, 0xd3, 0x43, 0x7e, + 0x0e, 0xfc, 0x2f, 0x01, 0x89, 0x29, 0x2e, 0x6d, 0x00, 0x84, 0x40, 0x82, 0x84, 0x41, 0xbf, 0x84, 0x40, 0x61, 0xb9, + 0x94, 0xbc, 0x14, 0xbb, 0xc4, 0xbc, 0xb2, 0x7f, 0xa3, 0x7f, 0xc3, 0x7f, 0xd3, 0x7f, 0x94, 0xb8, 0x96, 0x04, 0xa9, + 0x58, 0x13, 0x30, 0xf6, 0x6f, 0x90, 0x7f, 0x00, 0x2e, 0x97, 0x41, 0xc0, 0x91, 0x07, 0x30, 0xf6, 0x7f, 0x02, 0x2f, + 0x00, 0x2e, 0x3b, 0x2c, 0x47, 0x43, 0x06, 0x40, 0x80, 0xa9, 0xfe, 0x05, 0xf7, 0x23, 0x40, 0x41, 0x00, 0xb2, 0x28, + 0x2f, 0x0b, 0x41, 0xfa, 0x0e, 0x05, 0x2f, 0x80, 0xa1, 0x06, 0x30, 0x9e, 0x23, 0x7b, 0x25, 0x3e, 0x1a, 0x02, 0x2f, + 0x00, 0x30, 0x28, 0x2c, 0x40, 0x43, 0x03, 0x28, 0x40, 0x43, 0xc1, 0x0e, 0x22, 0x2f, 0xc0, 0x6f, 0x00, 0x90, 0x1f, + 0x2f, 0xa5, 0x7f, 0x5b, 0x25, 0xd6, 0x6f, 0x1e, 0x14, 0xd3, 0xbe, 0xc0, 0x7f, 0x28, 0x0a, 0xa7, 0x5a, 0xae, 0x01, + 0xab, 0x5e, 0x0b, 0x30, 0x2e, 0x1a, 0x00, 0x2f, 0x4b, 0x43, 0x41, 0x8b, 0x21, 0x2e, 0x53, 0xf0, 0x6f, 0x0e, 0xf7, + 0x2f, 0xa5, 0x6f, 0x0b, 0x2c, 0xa3, 0x7f, 0xb0, 0x6f, 0xf8, 0x0e, 0x06, 0x2f, 0x96, 0x6f, 0x43, 0x43, 0x00, 0x30, + 0x86, 0x41, 0x80, 0xa1, 0x18, 0x22, 0x00, 0x43, 0x41, 0x8b, 0xd0, 0x6f, 0x01, 0x8c, 0x90, 0x6f, 0x01, 0x80, 0x01, + 0x89, 0x83, 0xa3, 0xd6, 0x7f, 0xb1, 0x2f, 0xa0, 0x6f, 0x00, 0xb2, 0x02, 0x2f, 0x80, 0x30, 0x21, 0x2e, 0x5e, 0xf0, + 0xeb, 0x6f, 0x60, 0x5f, 0xb8, 0x2e, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, + 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, + 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, + 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, + 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, + 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, + 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, + 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, + 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, + 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, + 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, + 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, + 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, + 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, + 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, + 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, + 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, + 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, + 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, + 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, + 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, + 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, + 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, + 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, + 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, + 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, + 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, + 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, + 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, + 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, + 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, + 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, + 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, + 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, + 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, + 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, + 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, + 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, + 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, + 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, + 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, + 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, + 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, + 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, + 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, + 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, + 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, + 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, + 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, + 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, + 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, + 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, + 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, + 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, + 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, + 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, + 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, + 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00 +}; + +/***************************************************************************/ +/*! Static Function Declarations */ +/***************************************************************************/ + +/*! + * @brief This API update the settings of tap into write array. + * + * @param[in] setting : Pointer to structure variable which stores the + * settings parameter1 to parameter12. + * @param[in] index : Value for array traversing. + * @param[out] feature_config : Pointer to store the settings + * + * @return none + */ +static void update_tap_parameter(const struct bma456mm_multitap_settings *setting, + uint8_t index, + uint8_t *feature_config); + +/*! + * @brief This API copy the settings of tap into the + * structure of bma456mm_multitap_settings, which is read from sensor. + * + * @param[out] setting : Pointer to structure variable which stores the + * settings parameter1 to parameter12 read from sensor. + * @param[in] data_p : Pointer of array which stores the parameters. + * + * @return none + */ +static void extract_tap_parameter(struct bma456mm_multitap_settings *setting, const uint16_t *data_p); + +/*! + * @brief This API enables the features of sensor. + * + * @param[in] feature : Variable to specify the features which are to be set in + * the sensor. + * @param[in] len : Length to read and write + * @param[in] feature_config : Array address which stores the feature + * configuration data + * @param[in] dev : Structure instance of bma4_dev. + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +static int8_t feature_enable(uint8_t feature, uint8_t len, uint8_t *feature_config, struct bma4_dev *dev); + +/*! + * @brief This API disables the features of sensor. + * + * @param[in] feature : Variable to specify the features which are to be unset + * in the sensor. + * @param[in] len : Length to read and write + * @param[in] feature_config : Array address which stores the feature + * configuration data + * @param[in] dev : Structure instance of bma4_dev. + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +static int8_t feature_disable(uint8_t feature, uint8_t len, uint8_t *feature_config, struct bma4_dev *dev); + +/***************************************************************************/ +/*! Global 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 and sets the resolution. + */ +int8_t bma456mm_init(struct bma4_dev *dev) +{ + int8_t rslt; + + /* Structure to define the default values for axes re-mapping */ + struct bma4_axes_remap axes_remap = { + .x_axis = BMA4_MAP_X_AXIS, .x_axis_sign = BMA4_MAP_POSITIVE, .y_axis = BMA4_MAP_Y_AXIS, + .y_axis_sign = BMA4_MAP_POSITIVE, .z_axis = BMA4_MAP_Z_AXIS, .z_axis_sign = BMA4_MAP_POSITIVE + }; + + if (dev != NULL) + { + rslt = bma4_init(dev); + + if (rslt == BMA4_OK) + { + if (dev->chip_id == BMA456MM_CHIP_ID) + { + /* Resolution of BMA456MM sensor is 16 bit */ + dev->resolution = BMA4_16_BIT_RESOLUTION; + + dev->feature_len = BMA456MM_FEATURE_SIZE; + + dev->config_size = sizeof(bma456mm_config_file); + + /* Set the default values for axis + * re-mapping in the device structure + */ + dev->remap = axes_remap; + } + else + { + rslt = BMA4_E_INVALID_SENSOR; + } + } + } + else + { + rslt = BMA4_E_NULL_PTR; + } + + return rslt; +} + +/*! + * @brief This API is used to upload the configuration file to enable the + * features of the sensor. + */ +int8_t bma456mm_write_config_file(struct bma4_dev *dev) +{ + int8_t rslt = BMA4_OK; + + if (dev != NULL) + { + if (dev->chip_id == BMA456MM_CHIP_ID) + { + /* Configuration stream read/write length boundary + * check + */ + if ((dev->read_write_len >= BMA456MM_RD_WR_MIN_LEN) && (dev->read_write_len <= BMA456MM_RD_WR_MAX_LEN)) + { + /* Even or odd check */ + if ((dev->read_write_len % 2) != 0) + { + dev->read_write_len = dev->read_write_len - 1; + } + + /* Assign stream data */ + dev->config_file_ptr = bma456mm_config_file; + rslt = bma4_write_config_file(dev); + } + else + { + rslt = BMA4_E_RD_WR_LENGTH_INVALID; + } + } + else + { + rslt = BMA4_E_INVALID_SENSOR; + } + } + else + { + rslt = BMA4_E_NULL_PTR; + } + + return rslt; +} + +/*! + * @brief This API is used to get the config file major and minor information. + */ +int8_t bma456mm_get_version_config(uint16_t *config_major, uint16_t *config_minor, struct bma4_dev *dev) +{ + /* Initialize configuration file */ + uint8_t feature_config[BMA456MM_FEATURE_SIZE] = { 0 }; + + /* Update index to config file version */ + uint8_t index = BMA456MM_CONFIG_ID_OFFSET; + + /* Variable to define LSB */ + uint8_t lsb = 0; + + /* Variable to define MSB */ + uint8_t msb = 0; + + /* Variable to define LSB and MSB */ + uint16_t lsb_msb = 0; + + /* Result of api are returned to this variable */ + int8_t rslt = BMA4_OK; + + if ((config_major != NULL) && (config_minor != NULL)) + { + rslt = bma4_set_advance_power_save(BMA4_DISABLE, dev); + + if (rslt == BMA4_OK) + { + /* Wait for sensor time synchronization. Refer the data-sheet for + * more information + */ + dev->delay_us(450, dev->intf_ptr); + + /* Get config file identification from the sensor */ + rslt = bma4_read_regs(BMA4_FEATURE_CONFIG_ADDR, feature_config, BMA456MM_FEATURE_SIZE, dev); + + if (rslt == BMA4_OK) + { + /* Get word to calculate config file identification */ + lsb = feature_config[index++]; + msb = feature_config[index++]; + + lsb_msb = (uint16_t)(msb << 8 | lsb); + + /* Get major and minor version */ + *config_major = BMA4_GET_BITSLICE(lsb_msb, BMA4_CONFIG_MAJOR); + *config_minor = BMA4_GET_BITS_POS_0(lsb, BMA4_CONFIG_MINOR); + } + } + } + else + { + rslt = BMA4_E_NULL_PTR; + } + + return rslt; +} + +/*! + * @brief This API is used to get the configuration id of the sensor. + */ +int8_t bma456mm_get_config_id(uint16_t *config_id, struct bma4_dev *dev) +{ + uint8_t feature_config[BMA456MM_FEATURE_SIZE] = { 0 }; + uint8_t index = BMA456MM_CONFIG_ID_OFFSET; + int8_t rslt = BMA4_OK; + uint16_t config_id_lsb = 0; + uint16_t config_id_msb = 0; + + if ((dev != NULL) && (config_id != NULL)) + { + if (dev->chip_id == BMA456MM_CHIP_ID) + { + rslt = bma4_read_regs(BMA4_FEATURE_CONFIG_ADDR, feature_config, BMA456MM_FEATURE_SIZE, dev); + if (rslt == BMA4_OK) + { + config_id_lsb = (uint16_t)feature_config[index]; + config_id_msb = ((uint16_t)feature_config[index + 1]) << 8; + *config_id = config_id_lsb | config_id_msb; + } + } + else + { + rslt = BMA4_E_INVALID_SENSOR; + } + } + else + { + rslt = BMA4_E_NULL_PTR; + } + + return rslt; +} + +/*! + * @brief This API sets/un-sets the user provided interrupt to either interrupt + * pin1 or pin2 in the sensor. + */ +int8_t bma456mm_map_interrupt(uint8_t int_line, uint16_t int_map, uint8_t enable, struct bma4_dev *dev) +{ + int8_t rslt = BMA4_OK; + + if (dev != NULL) + { + if (dev->chip_id == BMA456MM_CHIP_ID) + { + if (int_line <= 1) + { + /* Map/Unmap the interrupt */ + rslt = bma4_map_interrupt(int_line, int_map, enable, dev); + } + else + { + rslt = BMA4_E_INT_LINE_INVALID; + } + } + else + { + rslt = BMA4_E_INVALID_SENSOR; + } + } + else + { + rslt = BMA4_E_NULL_PTR; + } + + return rslt; +} + +/*! + * @brief This API reads the interrupt status from the sensor. + */ +int8_t bma456mm_read_int_status(uint16_t *int_status, struct bma4_dev *dev) +{ + int8_t rslt = BMA4_OK; + + if ((dev != NULL) && (int_status != NULL)) + { + if (dev->chip_id == BMA456MM_CHIP_ID) + { + /* Read the interrupt status */ + rslt = bma4_read_int_status(int_status, dev); + } + else + { + rslt = BMA4_E_INVALID_SENSOR; + } + } + else + { + rslt = BMA4_E_NULL_PTR; + } + + return rslt; +} + +/*! + * @brief This API enables/disables the features of the sensor. + */ +int8_t bma456mm_feature_enable(uint8_t feature, uint8_t enable, struct bma4_dev *dev) +{ + uint8_t feature_config[BMA456MM_FEATURE_SIZE] = { 0 }; + int8_t rslt = BMA4_OK; + uint8_t len = BMA456MM_FEATURE_SIZE; + + if (dev != NULL) + { + if (dev->chip_id == BMA456MM_CHIP_ID) + { + /* Read feature configuration data */ + rslt = bma4_read_regs(BMA4_FEATURE_CONFIG_ADDR, feature_config, len, dev); + if (rslt == BMA4_OK) + { + if (enable == TRUE) + { + /* Enables the feature */ + rslt = feature_enable(feature, len, feature_config, dev); + } + else + { + /* Disables the feature */ + rslt = feature_disable(feature, len, feature_config, dev); + } + } + } + else + { + rslt = BMA4_E_INVALID_SENSOR; + } + } + else + { + rslt = BMA4_E_NULL_PTR; + } + + return rslt; +} + +/*! + * @brief This API performs x, y and z axis remapping in the sensor. + */ +int8_t bma456mm_set_remap_axes(const struct bma4_remap *remap_axes, struct bma4_dev *dev) +{ + uint8_t feature_config[BMA456MM_FEATURE_SIZE] = { 0 }; + uint8_t index = BMA456MM_AXES_REMAP_OFFSET; + int8_t rslt = BMA4_OK; + + if (remap_axes != NULL) + { + rslt = bma4_set_remap_axes(remap_axes, feature_config, index, BMA456MM_FEATURE_SIZE, dev); + } + else + { + rslt = BMA4_E_NULL_PTR; + } + + return rslt; +} + +/*! + * @brief This API reads the x, y and z axis remap data from the sensor. + */ +int8_t bma456mm_get_remap_axes(struct bma4_remap *remap_axes, struct bma4_dev *dev) +{ + uint8_t feature_config[BMA456MM_FEATURE_SIZE] = { 0 }; + uint8_t index = BMA456MM_AXES_REMAP_OFFSET; + int8_t rslt = BMA4_OK; + + if (remap_axes != NULL) + { + rslt = bma4_get_remap_axes(remap_axes, feature_config, index, BMA456MM_FEATURE_SIZE, dev); + } + else + { + rslt = BMA4_E_NULL_PTR; + } + + return rslt; +} + +/*! + * @brief This API sets the configuration of any-motion feature in the sensor. + * This API enables/disables the any-motion feature according to the axis set. + */ +int8_t bma456mm_set_any_mot_config(const struct bma456mm_any_no_mot_config *any_mot, struct bma4_dev *dev) +{ + /* Variable to define error */ + int8_t rslt = BMA4_OK; + + /* Initialize configuration file */ + uint8_t feature_config[BMA456MM_FEATURE_SIZE] = { 0 }; + + /* Update index to configure any-motion axes */ + uint8_t index = BMA456MM_ANY_MOT_OFFSET; + + /* Variable to define LSB */ + uint16_t lsb = 0; + + /* Variable to define MSB */ + uint16_t msb = 0; + + /* Variable to define LSB and MSB */ + uint16_t lsb_msb = 0; + + if (any_mot != NULL) + { + /* Get any-motion configuration from the sensor */ + rslt = bma4_read_regs(BMA4_FEATURE_CONFIG_ADDR, feature_config, BMA456MM_ANY_MOT_LEN, dev); + if (rslt == BMA4_OK) + { + /* Set threshold value in feature configuration array */ + feature_config[index] = BMA4_GET_LSB(any_mot->threshold); + feature_config[index + 1] = BMA4_GET_MSB(any_mot->threshold); + feature_config[index + 1] = BMA4_SET_BITSLICE(feature_config[index + 1], + BMA456MM_ANY_NO_MOTION_INTR_BHVR_EN, + any_mot->intr_bhvr); + feature_config[index + 1] = BMA4_SET_BITSLICE(feature_config[index + 1], + BMA456MM_ANY_MOTION_SLOPE_EN, + any_mot->slope); + + /* Extract the word where duration and axes enable + * resides + */ + lsb = feature_config[index + 2]; + msb = feature_config[index + 3] << 8; + lsb_msb = lsb | msb; + + /* Set the duration in the same word */ + lsb_msb = BMA4_SET_BITS_POS_0(lsb_msb, BMA456MM_ANY_NO_MOT_DUR, any_mot->duration); + + /* Set the axes in the same word */ + lsb_msb = BMA4_SET_BITSLICE(lsb_msb, BMA456MM_ANY_NO_MOT_AXIS_EN, any_mot->axes_en); + + /* Assign the word with set duration and axes enable + * value back to feature configuration array + */ + feature_config[index + 2] = BMA4_GET_LSB(lsb_msb); + feature_config[index + 3] = BMA4_GET_MSB(lsb_msb); + + /* Set any-motion configuration to the sensor */ + rslt = bma4_write_regs(BMA4_FEATURE_CONFIG_ADDR, feature_config, BMA456MM_ANY_MOT_LEN, dev); + } + } + else + { + rslt = BMA4_E_NULL_PTR; + } + + return rslt; +} + +/*! + * @brief This API gets the configuration of any-motion feature from the + * sensor. + */ +int8_t bma456mm_get_any_mot_config(struct bma456mm_any_no_mot_config *any_mot, struct bma4_dev *dev) +{ + /* Variable to define error */ + int8_t rslt = BMA4_OK; + + /* Initialize configuration file */ + uint8_t feature_config[BMA456MM_FEATURE_SIZE] = { 0 }; + + /* Update index to configure any-motion axes */ + uint8_t index = BMA456MM_ANY_MOT_OFFSET; + + /* Variable to define LSB */ + uint16_t lsb = 0; + + /* Variable to define MSB */ + uint16_t msb = 0; + + /* Variable to define LSB and MSB */ + uint16_t lsb_msb = 0; + + if (any_mot != NULL) + { + /* Get any-motion configuration from the sensor */ + rslt = bma4_read_regs(BMA4_FEATURE_CONFIG_ADDR, feature_config, BMA456MM_ANY_MOT_LEN, dev); + if (rslt == BMA4_OK) + { + /* Get word to calculate threshold and any-motion + * select + */ + lsb = (uint16_t)feature_config[index]; + msb = (uint16_t)((feature_config[index + 1] << 8)); + lsb_msb = lsb | msb; + + /* Get word to calculate intr_bhvr */ + any_mot->intr_bhvr = BMA4_GET_BITSLICE(feature_config[index + 1], BMA456MM_ANY_NO_MOTION_INTR_BHVR_EN); + + /* Get word to calculate slope */ + any_mot->slope = BMA4_GET_BITSLICE(feature_config[index + 1], BMA456MM_ANY_MOTION_SLOPE_EN); + + /* Extract threshold value */ + any_mot->threshold = lsb_msb & BMA456MM_ANY_NO_MOT_THRES_MSK; + + /* Get word to calculate duration and axes enable */ + lsb = (uint16_t)feature_config[index + 2]; + msb = (uint16_t)((feature_config[index + 3] << 8)); + lsb_msb = lsb | msb; + + /* Extract duration value */ + any_mot->duration = lsb_msb & BMA456MM_ANY_NO_MOT_DUR_MSK; + + /* Extract axes enable value */ + any_mot->axes_en = BMA4_GET_BITSLICE(lsb_msb, BMA456MM_ANY_NO_MOT_AXIS_EN); + } + } + else + { + rslt = BMA4_E_NULL_PTR; + } + + return rslt; +} + +/*! + * @brief This API sets the configuration of no-motion feature in the sensor. + * This API enables/disables the no-motion feature according to the axis set. + */ +int8_t bma456mm_set_no_mot_config(const struct bma456mm_any_no_mot_config *no_mot, struct bma4_dev *dev) +{ + /* Variable to define error */ + int8_t rslt = BMA4_OK; + + /* Initialize configuration file */ + uint8_t feature_config[BMA456MM_FEATURE_SIZE] = { 0 }; + + /* Update index to configure no-motion axes */ + uint8_t index = BMA456MM_NO_MOT_OFFSET; + + /* Variable to define LSB */ + uint16_t lsb = 0; + + /* Variable to define MSB */ + uint16_t msb = 0; + + /* Variable to define LSB and MSB */ + uint16_t lsb_msb = 0; + + if (no_mot != NULL) + { + /* Get no-motion configuration from the sensor */ + rslt = bma4_read_regs(BMA4_FEATURE_CONFIG_ADDR, feature_config, BMA456MM_NO_MOT_RD_WR_LEN, dev); + if (rslt == BMA4_OK) + { + /* Set threshold value in feature configuration array */ + feature_config[index] = BMA4_GET_LSB(no_mot->threshold); + feature_config[index + 1] = BMA4_GET_MSB(no_mot->threshold); + + feature_config[index + 1] = BMA4_SET_BITSLICE(feature_config[index + 1], + BMA456MM_ANY_NO_MOTION_INTR_BHVR_EN, + no_mot->intr_bhvr); + + /* Extract the word where duration and axes enable + * resides + */ + lsb = feature_config[index + 2]; + msb = feature_config[index + 3] << 8; + lsb_msb = lsb | msb; + + /* Set the duration in the same word */ + lsb_msb = BMA4_SET_BITS_POS_0(lsb_msb, BMA456MM_ANY_NO_MOT_DUR, no_mot->duration); + + /* Set the axes in the same word */ + lsb_msb = BMA4_SET_BITSLICE(lsb_msb, BMA456MM_ANY_NO_MOT_AXIS_EN, no_mot->axes_en); + + /* Assign the word with set duration and axes enable + * value back to feature configuration array + */ + feature_config[index + 2] = BMA4_GET_LSB(lsb_msb); + feature_config[index + 3] = BMA4_GET_MSB(lsb_msb); + + /* Set no-motion configuration to the sensor */ + rslt = bma4_write_regs(BMA4_FEATURE_CONFIG_ADDR, feature_config, BMA456MM_NO_MOT_RD_WR_LEN, dev); + } + } + else + { + rslt = BMA4_E_NULL_PTR; + } + + return rslt; +} + +/*! + * @brief This API gets the configuration of no-motion feature from the + * sensor. + */ +int8_t bma456mm_get_no_mot_config(struct bma456mm_any_no_mot_config *no_mot, struct bma4_dev *dev) +{ + /* Variable to define error */ + int8_t rslt = BMA4_OK; + + /* Initialize configuration file */ + uint8_t feature_config[BMA456MM_FEATURE_SIZE] = { 0 }; + + /* Update index to configure no-motion axes */ + uint8_t index = BMA456MM_NO_MOT_OFFSET; + + /* Variable to define LSB */ + uint16_t lsb = 0; + + /* Variable to define MSB */ + uint16_t msb = 0; + + /* Variable to define LSB and MSB */ + uint16_t lsb_msb = 0; + + if (no_mot != NULL) + { + /* Get no-motion configuration from the sensor */ + rslt = bma4_read_regs(BMA4_FEATURE_CONFIG_ADDR, feature_config, BMA456MM_NO_MOT_RD_WR_LEN, dev); + if (rslt == BMA4_OK) + { + /* Get word to calculate threshold and no-motion + * select + */ + lsb = (uint16_t)feature_config[index]; + msb = ((uint16_t)feature_config[index + 1] << 8); + lsb_msb = lsb | msb; + + /* Get word to calculate intr_bhvr */ + no_mot->intr_bhvr = BMA4_GET_BITSLICE(feature_config[index + 1], BMA456MM_ANY_NO_MOTION_INTR_BHVR_EN); + + /* Extract threshold value */ + no_mot->threshold = lsb_msb & BMA456MM_ANY_NO_MOT_THRES_MSK; + + /* Get word to calculate duration and axes enable */ + lsb = (uint16_t)feature_config[index + 2]; + msb = (uint16_t)((feature_config[index + 3] << 8)); + lsb_msb = lsb | msb; + + /* Extract duration value */ + no_mot->duration = lsb_msb & BMA456MM_ANY_NO_MOT_DUR_MSK; + + /* Extract axes enable value */ + no_mot->axes_en = BMA4_GET_BITSLICE(lsb_msb, BMA456MM_ANY_NO_MOT_AXIS_EN); + } + } + else + { + rslt = BMA4_E_NULL_PTR; + } + + return rslt; +} + +/*! + * @brief This API gets the parameter1 to parameter12 settings of the + * tap feature. + */ +int8_t bma456mm_tap_get_parameter(struct bma456mm_multitap_settings *setting, struct bma4_dev *dev) +{ + uint8_t feature_config[BMA456MM_FEATURE_SIZE] = { 0 }; + uint16_t *data_p = (uint16_t *)(void *)feature_config; + int8_t rslt = BMA4_OK; + + if ((dev != NULL) && (setting != NULL)) + { + if (dev->chip_id == BMA456MM_CHIP_ID) + { + rslt = bma4_read_regs(BMA4_FEATURE_CONFIG_ADDR, feature_config, BMA456MM_FEATURE_SIZE, dev); + if (rslt == BMA4_OK) + { + /* To convert 8bit to 16 bit address */ + data_p = data_p + ((BMA456MM_TAP_DETECTOR_OFFSET + 2) / 2); + extract_tap_parameter(setting, data_p); + } + } + else + { + rslt = BMA4_E_INVALID_SENSOR; + } + } + else + { + rslt = BMA4_E_NULL_PTR; + } + + return rslt; +} + +/*! + * @brief This API sets the parameter1 to parameter12 settings of the + * tap feature in the sensor. + */ +int8_t bma456mm_tap_set_parameter(const struct bma456mm_multitap_settings *setting, struct bma4_dev *dev) +{ + uint8_t feature_config[BMA456MM_FEATURE_SIZE] = { 0 }; + uint8_t index = BMA456MM_TAP_DETECTOR_OFFSET + 2; + int8_t rslt = BMA4_OK; + + if ((dev != NULL) && (setting != NULL)) + { + if (dev->chip_id == BMA456MM_CHIP_ID) + { + rslt = bma4_read_regs(BMA4_FEATURE_CONFIG_ADDR, feature_config, BMA456MM_FEATURE_SIZE, dev); + if (rslt == BMA4_OK) + { + update_tap_parameter(setting, index, feature_config); + + /* Writes tap parameter settings + * in the sensor + */ + rslt = bma4_write_regs(BMA4_FEATURE_CONFIG_ADDR, feature_config, BMA456MM_FEATURE_SIZE, dev); + } + } + else + { + rslt = BMA4_E_INVALID_SENSOR; + } + } + else + { + rslt = BMA4_E_NULL_PTR; + } + + return rslt; +} + +/*! + * @brief This API gets the output for activity feature. + */ +int8_t bma456mm_output_state(struct bma456mm_out_state *out_state, struct bma4_dev *dev) +{ + uint8_t data[3] = { 0 }; + int8_t rslt = BMA4_OK; + + if ((dev != NULL) && (out_state != NULL)) + { + if (dev->chip_id == BMA456MM_CHIP_ID) + { + /* Reads the activity output from the gpio register */ + rslt = bma4_read_regs(BMA456MM_FEAT_OUT_ADDR, data, 3, dev); + if (rslt == BMA4_OK) + { + out_state->orientation_out = BMA4_GET_BITS_POS_0(data[0], BMA456MM_ORIENT_OUT); + out_state->orientation_faceup_down = BMA4_GET_BITSLICE(data[0], BMA456MM_ORIENT_FACEUP_DOWN); + + out_state->high_g_detect_x = BMA4_GET_BITS_POS_0(data[1], BMA456MM_HIGH_G_DETECT_X); + out_state->high_g_detect_y = BMA4_GET_BITSLICE(data[1], BMA456MM_HIGH_G_DETECT_Y); + out_state->high_g_detect_z = BMA4_GET_BITSLICE(data[1], BMA456MM_HIGH_G_DETECT_Z); + out_state->high_g_detect_sign = BMA4_GET_BITSLICE(data[1], BMA456MM_HIGH_G_DETECT_SIGN); + + out_state->s_tap = BMA4_GET_BITS_POS_0(data[2], BMA456MM_SINGLE_TAP_OUT); + out_state->d_tap = BMA4_GET_BITSLICE(data[2], BMA456MM_DOUBLE_TAP_OUT); + out_state->t_tap = BMA4_GET_BITSLICE(data[2], BMA456MM_TRIPLE_TAP_OUT); + } + } + else + { + rslt = BMA4_E_INVALID_SENSOR; + } + } + else + { + rslt = BMA4_E_NULL_PTR; + } + + return rslt; +} + +/*! + * @brief This API sets the configuration for orientation feature of the sensor. + */ +int8_t bma456mm_set_orientation_config(const struct bma456mm_orientation_config *orientation, struct bma4_dev *dev) +{ + /* variable used to return the status of communication result*/ + int8_t rslt = BMA4_OK; + uint8_t feature_config[BMA456MM_FEATURE_SIZE] = { 0, }; + uint8_t index = BMA456MM_ORIENTATION_OFFSET; + uint16_t orient_settings_1_lsb = 0; + uint16_t orient_settings_1_msb = 0; + uint16_t orient_settings_1 = 0; + + if ((dev != NULL) && (orientation != NULL)) + { + if (dev->chip_id == BMA456MM_CHIP_ID) + { + rslt = bma4_read_regs(BMA4_FEATURE_CONFIG_ADDR, feature_config, BMA456MM_FEATURE_SIZE, dev); + if (rslt == BMA4_OK) + { + /* Extract upside/down, mode, block and theta */ + orient_settings_1_lsb = feature_config[index]; + orient_settings_1_msb = feature_config[index + 1] << 8; + orient_settings_1 = orient_settings_1_lsb | orient_settings_1_msb; + orient_settings_1 = BMA4_SET_BITSLICE(orient_settings_1, BMA456MM_ORIENT_UD, orientation->upside_down); + orient_settings_1 = BMA4_SET_BITSLICE(orient_settings_1, BMA456MM_ORIENT_MODE, orientation->mode); + orient_settings_1 = BMA4_SET_BITSLICE(orient_settings_1, BMA456MM_ORIENT_BLOCK, orientation->blocking); + orient_settings_1 = BMA4_SET_BITSLICE(orient_settings_1, BMA456MM_ORIENT_THETA, orientation->theta); + + /* Assign upside/down, mode, block and theta value in feature config array*/ + feature_config[index++] = BMA4_GET_LSB(orient_settings_1); + feature_config[index++] = BMA4_GET_MSB(orient_settings_1); + + /* Assign hysteresis value in feature config array */ + feature_config[index++] = BMA4_GET_LSB(orientation->hysteresis); + feature_config[index++] = BMA4_GET_MSB(orientation->hysteresis); + + /* Writes orientation settings value in the sensor */ + rslt = bma4_write_regs(BMA4_FEATURE_CONFIG_ADDR, feature_config, BMA456MM_FEATURE_SIZE, dev); + } + } + else + { + rslt = BMA4_E_INVALID_SENSOR; + } + } + else + { + rslt = BMA4_E_NULL_PTR; + } + + return rslt; +} + +/*! + * @brief This API gets the configuration of orientation feature from the sensor + */ +int8_t bma456mm_get_orientation_config(struct bma456mm_orientation_config *orientation, struct bma4_dev *dev) +{ + /* variable used to return the status of communication result*/ + int8_t rslt = BMA4_OK; + uint8_t feature_config[BMA456MM_FEATURE_SIZE] = { 0 }; + uint8_t index = BMA456MM_ORIENTATION_OFFSET; + uint16_t orient_settings_lsb = 0; + uint16_t orient_settings_msb = 0; + uint16_t orient_settings = 0; + + if ((dev != NULL) && (orientation != NULL)) + { + if (dev->chip_id == BMA456MM_CHIP_ID) + { + rslt = bma4_read_regs(BMA4_FEATURE_CONFIG_ADDR, feature_config, BMA456MM_FEATURE_SIZE, dev); + if (rslt == BMA4_OK) + { + /* Extract upside/down, mode, block and theta */ + orient_settings_lsb = feature_config[index]; + orient_settings_msb = feature_config[index + 1] << 8; + orient_settings = orient_settings_lsb | orient_settings_msb; + orientation->upside_down = BMA4_GET_BITSLICE(orient_settings, BMA456MM_ORIENT_UD); + orientation->mode = BMA4_GET_BITSLICE(orient_settings, BMA456MM_ORIENT_MODE); + orientation->blocking = BMA4_GET_BITSLICE(orient_settings, BMA456MM_ORIENT_BLOCK); + orientation->theta = BMA4_GET_BITSLICE(orient_settings, BMA456MM_ORIENT_THETA); + + /* Extract hysteresis */ + orient_settings_lsb = feature_config[index + 2]; + orient_settings_msb = feature_config[index + 3] << 8; + orient_settings = orient_settings_lsb | orient_settings_msb; + orientation->hysteresis = BMA4_GET_BITS_POS_0(orient_settings, BMA456MM_ORIENT_HYST); + } + } + else + { + rslt = BMA4_E_INVALID_SENSOR; + } + } + else + { + rslt = BMA4_E_NULL_PTR; + } + + return rslt; +} + +/*! + * @brief This API sets the configuration for low-g feature of the sensor. + */ +int8_t bma456mm_set_low_g_config(const struct bma456mm_low_g_config *low_g, struct bma4_dev *dev) +{ + /* variable used to return the status of communication result*/ + int8_t rslt = BMA4_OK; + uint8_t feature_config[BMA456MM_FEATURE_SIZE] = { 0, }; + uint8_t index = BMA456MM_LOW_G_OFFSET; + + /* Variable to define LSB */ + uint16_t lsb = 0; + + /* Variable to define MSB */ + uint16_t msb = 0; + + /* Variable to define LSB and MSB */ + uint16_t lsb_msb = 0; + + if ((dev != NULL) && (low_g != NULL)) + { + if (dev->chip_id == BMA456MM_CHIP_ID) + { + rslt = bma4_read_regs(BMA4_FEATURE_CONFIG_ADDR, feature_config, BMA456MM_FEATURE_SIZE, dev); + if (rslt == BMA4_OK) + { + /* Threshold */ + + lsb = feature_config[index]; + msb = feature_config[index + 1] << 8; + lsb_msb = lsb | msb; + + /* Set the threshold in the same word */ + lsb_msb = BMA4_SET_BITS_POS_0(lsb_msb, BMA456MM_LOW_G_THRES, low_g->threshold); + + /* Set threshold value in feature configuration array */ + feature_config[index++] = BMA4_GET_LSB(lsb_msb); + feature_config[index++] = BMA4_GET_MSB(lsb_msb); + + /* Hysteresis */ + + lsb = feature_config[index]; + msb = feature_config[index + 1] << 8; + lsb_msb = lsb | msb; + + /* Set the hysteresis in the same word */ + lsb_msb = BMA4_SET_BITS_POS_0(lsb_msb, BMA456MM_LOW_G_HYST, low_g->hysteresis); + + /* Set hysteresis value in feature configuration array */ + feature_config[index++] = BMA4_GET_LSB(lsb_msb); + feature_config[index++] = BMA4_GET_MSB(lsb_msb); + + /* Duration */ + + lsb = feature_config[index]; + msb = feature_config[index + 1] << 8; + lsb_msb = lsb | msb; + + /* Set the duration in the same word */ + lsb_msb = BMA4_SET_BITS_POS_0(lsb_msb, BMA456MM_LOW_G_HYST, low_g->duration); + + /* Set duration value in feature configuration array */ + feature_config[index++] = BMA4_GET_LSB(lsb_msb); + feature_config[index++] = BMA4_GET_MSB(lsb_msb); + + /* Writes orientation settings value in the sensor */ + rslt = bma4_write_regs(BMA4_FEATURE_CONFIG_ADDR, feature_config, BMA456MM_FEATURE_SIZE, dev); + } + } + else + { + rslt = BMA4_E_INVALID_SENSOR; + } + } + else + { + rslt = BMA4_E_NULL_PTR; + } + + return rslt; +} + +/*! + * @brief This API gets the configuration of low-g feature from the sensor + */ +int8_t bma456mm_get_low_g_config(struct bma456mm_low_g_config *low_g, struct bma4_dev *dev) +{ + /* variable used to return the status of communication result*/ + int8_t rslt = BMA4_OK; + uint8_t feature_config[BMA456MM_FEATURE_SIZE] = { 0 }; + uint8_t index = BMA456MM_LOW_G_OFFSET; + + /* Variable to define LSB */ + uint16_t lsb = 0; + + /* Variable to define MSB */ + uint16_t msb = 0; + + /* Variable to define LSB and MSB */ + uint16_t lsb_msb = 0; + + if ((dev != NULL) && (low_g != NULL)) + { + if (dev->chip_id == BMA456MM_CHIP_ID) + { + rslt = bma4_read_regs(BMA4_FEATURE_CONFIG_ADDR, feature_config, BMA456MM_FEATURE_SIZE, dev); + if (rslt == BMA4_OK) + { + /* Get threshold */ + + lsb = (uint16_t)feature_config[index++]; + msb = ((uint16_t)feature_config[index++] << 8); + lsb_msb = lsb | msb; + + /* Extract threshold value */ + low_g->threshold = lsb_msb & BMA456MM_LOW_G_THRES_MSK; + + /* Get hysteresis */ + + lsb = (uint16_t)feature_config[index++]; + msb = ((uint16_t)feature_config[index++] << 8); + lsb_msb = lsb | msb; + + /* Extract hysteresis value */ + low_g->hysteresis = lsb_msb & BMA456MM_LOW_G_HYST_MSK; + + /* Get duration */ + + lsb = (uint16_t)feature_config[index++]; + msb = ((uint16_t)feature_config[index++] << 8); + lsb_msb = lsb | msb; + + /* Extract duration value */ + low_g->duration = lsb_msb & BMA456MM_LOW_G_DUR_MSK; + } + } + else + { + rslt = BMA4_E_INVALID_SENSOR; + } + } + else + { + rslt = BMA4_E_NULL_PTR; + } + + return rslt; +} + +/*! + * @brief This API gets auto sleep configurations + */ +int8_t bma456mm_get_auto_low_power_config(struct bma456mm_auto_low_power *auto_low_power, struct bma4_dev *dev) +{ + uint8_t feature_config[BMA456MM_FEATURE_SIZE] = { 0 }; + int8_t rslt = BMA4_OK; + uint16_t msb_lsb; + + if ((dev != NULL) && (auto_low_power != NULL)) + { + if (dev->chip_id == BMA456MM_CHIP_ID) + { + rslt = bma4_read_regs(BMA4_FEATURE_CONFIG_ADDR, feature_config, BMA456MM_FEATURE_SIZE, dev); + if (rslt == BMA4_OK) + { + auto_low_power->no_motion = BMA4_GET_BITS_POS_0(feature_config[BMA456MM_AUTO_LOW_POWER_OFFSET], + BMA456MM_NO_MOT_AUTO_LOW_POWER); + auto_low_power->time_out = BMA4_GET_BITSLICE(feature_config[BMA456MM_AUTO_LOW_POWER_OFFSET], + BMA456MM_AUTO_LOW_POWER_TIME_OUT); + + msb_lsb = + (uint16_t)(feature_config[BMA456MM_AUTO_LOW_POWER_OFFSET] | + (uint16_t)(feature_config[BMA456MM_AUTO_LOW_POWER_OFFSET + 1] << 8)); + auto_low_power->time_out_dur = BMA4_GET_BITSLICE(msb_lsb, BMA456MM_TIME_OUT_DUR); + + auto_low_power->lp_odr = BMA4_GET_BITSLICE(feature_config[BMA456MM_AUTO_LOW_POWER_OFFSET + 1], + BMA456MM_LOW_POW_ODR); + auto_low_power->pwr_mgt = BMA4_GET_BITSLICE(feature_config[BMA456MM_AUTO_LOW_POWER_OFFSET + 1], + BMA456MM_PWR_MGT_ENABLE); + } + } + else + { + rslt = BMA4_E_INVALID_SENSOR; + } + } + else + { + rslt = BMA4_E_NULL_PTR; + } + + return rslt; +} + +/*! + * @brief This API gets power mode management configuration. + */ +int8_t bma456mm_set_auto_low_power_config(const struct bma456mm_auto_low_power *auto_low_power, struct bma4_dev *dev) +{ + uint8_t feature_config[BMA456MM_FEATURE_SIZE] = { 0 }; + uint8_t index = BMA456MM_AUTO_LOW_POWER_OFFSET; + int8_t rslt = BMA4_OK; + uint16_t msb_lsb; + + if ((dev != NULL) && (auto_low_power != NULL)) + { + if (dev->chip_id == BMA456MM_CHIP_ID) + { + rslt = bma4_read_regs(BMA4_FEATURE_CONFIG_ADDR, feature_config, BMA456MM_FEATURE_SIZE, dev); + if (rslt == BMA4_OK) + { + + msb_lsb = (uint16_t)((feature_config[index]) | (uint16_t)(feature_config[index + 1] << 8)); + + msb_lsb = BMA4_SET_BITS_POS_0(msb_lsb, BMA456MM_NO_MOT_AUTO_LOW_POWER_WORD, auto_low_power->no_motion); + msb_lsb = BMA4_SET_BITSLICE(msb_lsb, BMA456MM_AUTO_LOW_POWER_TIME_OUT_WORD, auto_low_power->time_out); + + msb_lsb = BMA4_SET_BITSLICE(msb_lsb, BMA456MM_TIME_OUT_DUR_WORD, auto_low_power->time_out_dur); + + msb_lsb = BMA4_SET_BITSLICE(msb_lsb, BMA456MM_LOW_POW_ODR_WORD, auto_low_power->lp_odr); + msb_lsb = BMA4_SET_BITSLICE(msb_lsb, BMA456MM_PWR_MGT_ENABLE_WORD, auto_low_power->pwr_mgt); + + feature_config[index] = BMA4_GET_LSB(msb_lsb); + feature_config[index + 1] = BMA4_GET_MSB(msb_lsb); + + rslt = bma4_write_regs(BMA4_FEATURE_CONFIG_ADDR, feature_config, BMA456MM_FEATURE_SIZE, dev); + } + } + else + { + rslt = BMA4_E_INVALID_SENSOR; + } + } + else + { + rslt = BMA4_E_NULL_PTR; + } + + return rslt; +} + +/*! + * @brief This api reads the auto low power state output status + */ +int8_t bma456mm_get_auto_low_power_state(uint8_t *auto_low_power_state, struct bma4_dev *dev) +{ + int8_t rslt = BMA4_OK; + uint8_t data; + + if ((dev != NULL) && (auto_low_power_state != NULL)) + { + rslt = bma4_read_regs(BMA4_INTERNAL_STAT, &data, 1, dev); + *auto_low_power_state = BMA4_GET_BITSLICE(data, BMA456MM_AUTO_LOW_POWER_STATE); + } + else + { + rslt = BMA4_E_NULL_PTR; + } + + return rslt; +} + +/*! + * @brief This API sets the configuration of high-g feature in the sensor. + * This API enables/disables the high-g feature according to the axis set. + */ +int8_t bma456mm_set_high_g_config(const struct bma456mm_high_g_config *high_g, struct bma4_dev *dev) +{ + /* Variable to define error */ + int8_t rslt; + + /* Initialize configuration file */ + uint8_t feature_config[BMA456MM_FEATURE_SIZE] = { 0 }; + + /* Update index to configure high-g feature */ + uint8_t index = BMA456MM_HIGH_G_OFFSET; + + /* Variable to define LSB */ + uint16_t lsb = 0; + + /* Variable to define MSB */ + uint16_t msb = 0; + + /* Variable to define LSB and MSB */ + uint16_t lsb_msb = 0; + + if (high_g != NULL) + { + /* Get high-g configuration from the sensor */ + rslt = bma4_read_regs(BMA4_FEATURE_CONFIG_ADDR, feature_config, BMA456MM_FEATURE_SIZE, dev); + + if (rslt == BMA4_OK) + { + /* Assign threshold value in feature config array */ + lsb = feature_config[index]; + msb = feature_config[index + 1] << 8; + lsb_msb = lsb | msb; + + /* Set the threshold in the same word */ + lsb_msb = BMA4_SET_BITS_POS_0(lsb_msb, BMA456MM_HIGH_G_THRES, high_g->threshold); + + /* Set threshold and motion selection value in feature configuration array */ + feature_config[index++] = BMA4_GET_LSB(lsb_msb); + feature_config[index++] = BMA4_GET_MSB(lsb_msb); + + lsb = (uint16_t)feature_config[index]; + msb = ((uint16_t)feature_config[index + 1] << 8); + lsb_msb = lsb | msb; + + /* Set the hysteresis in the same word */ + lsb_msb = BMA4_SET_BITS_POS_0(lsb_msb, BMA456MM_HIGH_G_HYST, high_g->hysteresis); + + /* Set the axes enable in the same word */ + lsb_msb = BMA4_SET_BITSLICE(lsb_msb, BMA456MM_HIGH_G_AXIS_EN, high_g->axes_en); + + /* Set hysteresis and and axes enable in the same word */ + feature_config[index++] = BMA4_GET_LSB(lsb_msb); + feature_config[index++] = BMA4_GET_MSB(lsb_msb); + + /* Assign duration value in feature config array */ + feature_config[index] = BMA4_GET_LSB(high_g->duration); + feature_config[index + 1] = BMA4_GET_MSB(high_g->duration); + + /* Set high-g configuration to the sensor */ + rslt = bma4_write_regs(BMA4_FEATURE_CONFIG_ADDR, feature_config, BMA456MM_FEATURE_SIZE, dev); + } + } + else + { + rslt = BMA4_E_NULL_PTR; + } + + return rslt; +} + +/*! + * @brief This API gets the configuration of high-g feature in the sensor. + * This API enables/disables the high-g feature according to the axis set. + */ +int8_t bma456mm_get_high_g_config(struct bma456mm_high_g_config *high_g, struct bma4_dev *dev) +{ + /* Variable to define error */ + int8_t rslt; + + /* Initialize configuration file */ + uint8_t feature_config[BMA456MM_FEATURE_SIZE] = { 0 }; + + /* Update index to configure high_g */ + uint8_t index = BMA456MM_HIGH_G_OFFSET; + + /* Variable to define LSB */ + uint16_t lsb = 0; + + /* Variable to define MSB */ + uint16_t msb = 0; + + /* Variable to define LSB and MSB */ + uint16_t lsb_msb = 0; + + if (high_g != NULL) + { + /* Get high-g configuration from the sensor */ + rslt = bma4_read_regs(BMA4_FEATURE_CONFIG_ADDR, feature_config, BMA456MM_FEATURE_SIZE, dev); + + if (rslt == BMA4_OK) + { + /* Get word to calculate threshold selection + * select + */ + lsb = (uint16_t)feature_config[index++]; + msb = ((uint16_t)feature_config[index++] << 8); + lsb_msb = lsb | msb; + + /* Extract threshold value */ + high_g->threshold = lsb_msb & BMA456MM_HIGH_G_THRES_MSK; + + /* Get word to calculate hysteresis and axis selection selection + * select + */ + lsb = (uint16_t)feature_config[index++]; + msb = ((uint16_t)feature_config[index++] << 8); + lsb_msb = lsb | msb; + + /* Extract select the hysteresis and axis enable value */ + high_g->hysteresis = lsb_msb & BMA456MM_HIGH_G_HYST_MSK; + + /* Extract axes enable value */ + high_g->axes_en = BMA4_GET_BITSLICE(lsb_msb, BMA456MM_HIGH_G_AXIS_EN); + + /* Get word to calculate duration */ + lsb = (uint16_t)feature_config[index++]; + msb = ((uint16_t)feature_config[index++] << 8); + lsb_msb = lsb | msb; + + /* Extract duration value */ + high_g->duration = lsb_msb & BMA456MM_HIGH_G_DUR_MSK; + } + } + else + { + rslt = BMA4_E_NULL_PTR; + } + + return rslt; +} + +/*! + * @brief This API sets the configuration of significant motion + * in the sensor. + */ +int8_t bma456mm_set_sig_motion_config(const struct bma456mm_sig_motion_config *sig_motion, struct bma4_dev *dev) +{ + uint8_t feature_config[BMA456MM_FEATURE_SIZE] = { 0 }; + uint8_t index = BMA456MM_SIG_MOTION_OFFSET; + uint16_t skiptime_msb = 0; + uint16_t skiptime_lsb = 0; + uint16_t skiptime = 0; + int8_t rslt = BMA4_OK; + + if (sig_motion != NULL) + { + rslt = bma4_read_regs(BMA4_FEATURE_CONFIG_ADDR, feature_config, BMA456MM_FEATURE_SIZE, dev); + + if (rslt == BMA4_OK) + { + /* Assigns threshold value */ + feature_config[index++] = BMA4_GET_LSB(sig_motion->threshold); + feature_config[index++] = BMA4_GET_MSB(sig_motion->threshold); + + /* Gets skip time data bytes and sets only + * skip time bits + */ + skiptime_lsb = feature_config[index]; + skiptime_msb = feature_config[index + 1] << 8; + skiptime = skiptime_lsb | skiptime_msb; + skiptime = BMA4_SET_BITS_POS_0(skiptime, BMA456MM_SIG_MOTION_SKIPTIME, sig_motion->skiptime); + + /* Assigns skip time value */ + feature_config[index++] = BMA4_GET_LSB(skiptime); + feature_config[index++] = BMA4_GET_MSB(skiptime); + + /* Assigns proof time value */ + feature_config[index] = sig_motion->prooftime & BMA456MM_SIG_MOTION_PROOFTIME_MSK; + + /* Writes significant motion settings + * in the sensor + */ + rslt = bma4_write_regs(BMA4_FEATURE_CONFIG_ADDR, feature_config, BMA456MM_FEATURE_SIZE, dev); + } + } + else + { + rslt = BMA4_E_NULL_PTR; + } + + return rslt; +} + +/*! @brief This API gets the configuration of significant motion feature + * from the sensor. + */ +int8_t bma456mm_get_sig_motion_config(struct bma456mm_sig_motion_config *sig_motion, struct bma4_dev *dev) +{ + uint8_t feature_config[BMA456MM_FEATURE_SIZE] = { 0 }; + uint16_t *data_p = (uint16_t *)(void *)feature_config; + int8_t rslt = BMA4_OK; + + if (sig_motion != NULL) + { + rslt = bma4_read_regs(BMA4_FEATURE_CONFIG_ADDR, feature_config, BMA456MM_FEATURE_SIZE, dev); + + if (rslt == BMA4_OK) + { + /* To convert 8bit to 16 bit address */ + data_p = data_p + BMA456MM_SIG_MOTION_OFFSET / 2; + + /* Extracts threshold value */ + sig_motion->threshold = (*(data_p++)) & BMA456MM_SIG_MOTION_THRES_MSK; + + /* Extracts skip time value */ + sig_motion->skiptime = (*(data_p++)) & BMA456MM_SIG_MOTION_SKIPTIME_MSK; + + /* Extracts proof time value */ + sig_motion->prooftime = (uint8_t)((*data_p) & BMA456MM_SIG_MOTION_PROOFTIME_MSK); + } + } + else + { + rslt = BMA4_E_NULL_PTR; + } + + return rslt; +} + +/*! @cond DOXYGEN_SUPRESS */ + +/* Suppressing doxygen warnings triggered for same static function names present across various sensor variant + * directories */ + +/***************************************************************************/ +/*! Static Function Definitions */ +/***************************************************************************/ + +/*! + * @brief This API update the settings of tap. + */ +static void update_tap_parameter(const struct bma456mm_multitap_settings *setting, + uint8_t index, + uint8_t *feature_config) +{ + uint8_t param_num; + uint8_t max_tap_param = 12; + const uint16_t *tap_param = &setting->reserved_1; + + /* Number of tap detection parameter is 12 */ + for (param_num = 1; param_num <= max_tap_param; param_num++) + { + feature_config[index++] = BMA4_GET_LSB(*tap_param); + feature_config[index++] = BMA4_GET_MSB(*tap_param); + tap_param++; + } +} + +/*! + * @brief This API copy the settings of tap into the structure of + * bma456mm_multitap_settings, which is read from sensor. + */ +static void extract_tap_parameter(struct bma456mm_multitap_settings *setting, const uint16_t *data_p) +{ + uint8_t param_num; + uint8_t max_tap_param = 12; + uint16_t *tap_param = &setting->reserved_1; + + /* Number of tap detection parameter is 12 */ + for (param_num = 1; param_num <= max_tap_param; param_num++) + { + *tap_param = *(data_p++); + tap_param++; + } +} + +/*! + * @brief This API enables the features of the sensor. + */ +static int8_t feature_enable(uint8_t feature, uint8_t len, uint8_t *feature_config, struct bma4_dev *dev) +{ + uint8_t index = 0; + int8_t rslt = BMA4_OK; + + if ((dev != NULL) && (feature_config != NULL)) + { + /* Enable Low-G */ + if ((feature & BMA456MM_LOW_G) > 0) + { + index = BMA456MM_LOW_G_OFFSET + BMA456MM_LOW_G_FEAT_EN_OFFSET; + feature_config[index] = feature_config[index] | BMA456MM_LOW_G_EN_MSK; + } + + /* Enable orientation */ + if ((feature & BMA456MM_ORIENT) > 0) + { + index = BMA456MM_ORIENTATION_OFFSET; + feature_config[index] = feature_config[index] | BMA456MM_ORIENT_EN_MSK; + } + + /* Enable single - tap */ + if ((feature & BMA456MM_SINGLE_TAP) > 0) + { + index = BMA456MM_TAP_DETECTOR_OFFSET; + feature_config[index] = feature_config[index] | BMA456MM_SINGLE_TAP_EN_MSK; + } + + /* Enable double - tap */ + if ((feature & BMA456MM_DOUBLE_TAP) > 0) + { + index = BMA456MM_TAP_DETECTOR_OFFSET; + feature_config[index] = feature_config[index] | BMA456MM_DOUBLE_TAP_EN_MSK; + } + + /* Enable triple - tap */ + if ((feature & BMA456MM_TRIPLE_TAP) > 0) + { + index = BMA456MM_TAP_DETECTOR_OFFSET; + feature_config[index] = feature_config[index] | BMA456MM_TRIPLE_TAP_EN_MSK; + } + + /* Enable auto-low-power */ + if ((feature & BMA456MM_AUTO_LOW_POWER) > 0) + { + index = BMA456MM_AUTO_LOW_POWER_EN_OFFSET; + feature_config[index] = feature_config[index] | BMA456MM_AUTO_LOW_POWER_ALP_EN_MSK; + } + + /* Enable high_g */ + if ((feature & BMA456MM_HIGH_G) > 0) + { + index = BMA456MM_HIGH_G_EN_OFFSET; + feature_config[index] = feature_config[index] | BMA456MM_HIGH_G_EN_MSK; + } + + /* Enable significant motion */ + if (feature & BMA456MM_SIG_MOTION) + { + index = BMA456MM_SIG_MOTION_EN_OFFSET; + feature_config[index] = feature_config[index] | BMA456MM_SIG_MOTION_EN_MSK; + } + + /* Write the feature enable settings in the sensor */ + rslt = bma4_write_regs(BMA4_FEATURE_CONFIG_ADDR, feature_config, len, dev); + } + + return rslt; +} + +/*! + * @brief This API disables the features of the sensor. + */ +static int8_t feature_disable(uint8_t feature, uint8_t len, uint8_t *feature_config, struct bma4_dev *dev) +{ + uint8_t index = 0; + int8_t rslt = BMA4_OK; + + if ((dev != NULL) && (feature_config != NULL)) + { + /* Disable Low-G */ + if ((feature & BMA456MM_LOW_G) > 0) + { + index = BMA456MM_LOW_G_OFFSET + BMA456MM_LOW_G_FEAT_EN_OFFSET; + feature_config[index] = feature_config[index] & (~BMA456MM_LOW_G_EN_MSK); + } + + /* Disable orientation */ + if ((feature & BMA456MM_ORIENT) > 0) + { + index = BMA456MM_ORIENTATION_OFFSET; + feature_config[index] = feature_config[index] & (~BMA456MM_ORIENT_EN_MSK); + } + + /* Disable single-tap */ + if ((feature & BMA456MM_SINGLE_TAP) > 0) + { + index = BMA456MM_TAP_DETECTOR_OFFSET; + feature_config[index] = feature_config[index] & (~BMA456MM_SINGLE_TAP_EN_MSK); + } + + /* Disable double-tap */ + if ((feature & BMA456MM_DOUBLE_TAP) > 0) + { + index = BMA456MM_TAP_DETECTOR_OFFSET; + feature_config[index] = feature_config[index] & (~BMA456MM_DOUBLE_TAP_EN_MSK); + } + + /* Disable triple-tap */ + if ((feature & BMA456MM_TRIPLE_TAP) > 0) + { + index = BMA456MM_TAP_DETECTOR_OFFSET; + feature_config[index] = feature_config[index] & (~BMA456MM_TRIPLE_TAP_EN_MSK); + } + + /* Disable auto-low-power */ + if ((feature & BMA456MM_AUTO_LOW_POWER) > 0) + { + index = BMA456MM_AUTO_LOW_POWER_EN_OFFSET; + feature_config[index] = feature_config[index] & (~BMA456MM_AUTO_LOW_POWER_ALP_EN_MSK); + } + + /* Disable high_g */ + if ((feature & BMA456MM_HIGH_G) > 0) + { + index = BMA456MM_HIGH_G_EN_OFFSET; + feature_config[index] = feature_config[index] & (~BMA456MM_HIGH_G_EN_MSK); + } + + /* Disable significant motion */ + if ((feature & BMA456MM_SIG_MOTION) > 0) + { + index = BMA456MM_SIG_MOTION_EN_OFFSET; + feature_config[index] = feature_config[index] & (~BMA456MM_SIG_MOTION_EN_MSK); + } + + /* Write the configured settings in the sensor */ + rslt = bma4_write_regs(BMA4_FEATURE_CONFIG_ADDR, feature_config, len, dev); + } + + return rslt; +} + +/*! @endcond */ diff --git a/components/bma456/bma456mm.h b/components/bma456/bma456mm.h new file mode 100644 index 0000000..1a1f204 --- /dev/null +++ b/components/bma456/bma456mm.h @@ -0,0 +1,1584 @@ +/** +* 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. +* +* @file bma456mm.h +* @date 2023-07-05 +* @version V2.29.0 +* +*/ + +/** + * \ingroup bma4xy + * \defgroup bma456mm BMA456MM + * @brief Sensor driver for BMA456MM sensor + */ + +#ifndef BMA456MM_H +#define BMA456MM_H + +#ifdef __cplusplus +extern "C" { +#endif +#include "bma4.h" + +/**\name Chip ID of BMA456 sensor */ +#define BMA456MM_CHIP_ID UINT8_C(0x16) + +/**\name Sensor feature size */ +#define BMA456MM_FEATURE_SIZE UINT8_C(62) + +/**\name Feature offset address */ +#define BMA456MM_ANY_MOT_OFFSET UINT8_C(0x00) +#define BMA456MM_NO_MOT_OFFSET UINT8_C(0x04) +#define BMA456MM_ORIENTATION_OFFSET UINT8_C(0x08) +#define BMA456MM_LOW_G_OFFSET UINT8_C(0x0C) +#define BMA456MM_TAP_DETECTOR_OFFSET UINT8_C(0x12) +#define BMA456MM_AUTO_LOW_POWER_OFFSET UINT8_C(0x2C) +#define BMA456MM_HIGH_G_OFFSET UINT8_C(0x2E) +#define BMA456MM_SIG_MOTION_OFFSET UINT8_C(0x34) +#define BMA456MM_CONFIG_ID_OFFSET UINT8_C(0x3A) +#define BMA456MM_AXES_REMAP_OFFSET UINT8_C(0x3C) + +/**\name Read/Write Lengths */ +#define BMA456MM_RD_WR_MIN_LEN UINT8_C(2) + +/*! @name Maximum valid read write length is size of config file array */ +#define BMA456MM_RD_WR_MAX_LEN ((uint16_t)sizeof(bma456mm_config_file)) + +/**************************************************************/ +/**\name Re-map Axes */ +/**************************************************************/ +#define BMA456MM_X_AXIS_MASK UINT8_C(0x03) +#define BMA456MM_X_AXIS_SIGN_MASK UINT8_C(0x04) +#define BMA456MM_Y_AXIS_MASK UINT8_C(0x18) +#define BMA456MM_Y_AXIS_SIGN_MASK UINT8_C(0x20) +#define BMA456MM_Z_AXIS_MASK UINT8_C(0xC0) +#define BMA456MM_Z_AXIS_SIGN_MASK UINT8_C(0x01) + +/**************************************************************/ +/**\name Any/no Motion */ +/**************************************************************/ +#define BMA456MM_ANY_MOT_LEN UINT8_C(4) +#define BMA456MM_NO_MOT_RD_WR_LEN (BMA456MM_ANY_MOT_LEN + BMA456MM_NO_MOT_OFFSET) + +/**\name Any/No motion threshold macros */ +#define BMA456MM_ANY_NO_MOT_THRES_MSK UINT16_C(0x07FF) + +/**\name Position and mask of interrupt behavior and slope */ +#define BMA456MM_ANY_NO_MOTION_INTR_BHVR_EN_POS UINT8_C(0x03) +#define BMA456MM_ANY_NO_MOTION_INTR_BHVR_EN_MSK UINT8_C(0x08) + +#define BMA456MM_ANY_MOTION_SLOPE_EN_POS UINT8_C(0x04) +#define BMA456MM_ANY_MOTION_SLOPE_EN_MSK UINT8_C(0x10) + +/**\name Any/No motion duration macros */ +#define BMA456MM_ANY_NO_MOT_DUR_MSK UINT16_C(0x1FFF) + +/**\name Any/No motion enable macros */ +#define BMA456MM_ANY_NO_MOT_AXIS_EN_POS UINT8_C(0x0D) +#define BMA456MM_ANY_NO_MOT_AXIS_EN_MSK UINT16_C(0xE000) + +/**************************************************************/ +/**\name Single/Double Tap */ +/**************************************************************/ +/**\name Single tap enable macros */ +#define BMA456MM_SINGLE_TAP_EN_MSK UINT8_C(0x01) + +/**\name Double tap enable macros */ +#define BMA456MM_DOUBLE_TAP_EN_MSK UINT8_C(0x02) + +/**\name Triple tap enable macros */ +#define BMA456MM_TRIPLE_TAP_EN_MSK UINT8_C(0x04) + +/**\name Tap averaging enable macros */ +#define BMA456MM_TAP_AVG_EN_MSK UINT8_C(0x08) + +/**\name Tap output macros */ +#define BMA456MM_SINGLE_TAP_OUT_MSK UINT8_C(0x01) + +#define BMA456MM_DOUBLE_TAP_OUT_MSK UINT8_C(0x02) +#define BMA456MM_DOUBLE_TAP_OUT_POS UINT8_C(0x01) + +#define BMA456MM_TRIPLE_TAP_OUT_MSK UINT8_C(0x04) +#define BMA456MM_TRIPLE_TAP_OUT_POS UINT8_C(0x02) + +/**************************************************************/ +/**\name Orientation */ +/**************************************************************/ +#define BMA456MM_FEAT_OUT_ADDR UINT8_C(0x1E) + +#define BMA456MM_ORIENTATION_OUTPUT_MASK UINT8_C(0x07) + +/**\name Orientation enable macros */ +#define BMA456MM_ORIENT_EN_POS UINT8_C(0) +#define BMA456MM_ORIENT_EN_MSK UINT8_C(0x01) + +/**\name Orientation upside/down detection macros */ +#define BMA456MM_ORIENT_UD_POS UINT8_C(1) +#define BMA456MM_ORIENT_UD_MSK UINT8_C(0x02) + +/**\name Orientation mode macros */ +#define BMA456MM_ORIENT_MODE_POS UINT8_C(2) +#define BMA456MM_ORIENT_MODE_MSK UINT8_C(0x0C) + +/**\name Orientation blocking macros */ +#define BMA456MM_ORIENT_BLOCK_POS UINT8_C(4) +#define BMA456MM_ORIENT_BLOCK_MSK UINT8_C(0x30) + +/**\name Orientation theta macros */ +#define BMA456MM_ORIENT_THETA_POS UINT8_C(6) +#define BMA456MM_ORIENT_THETA_MSK UINT16_C(0x0FC0) + +/**\name Orientation hysteresis macros */ +#define BMA456MM_ORIENT_HYST_POS UINT8_C(0) +#define BMA456MM_ORIENT_HYST_MSK UINT16_C(0x07FF) + +/* Orientation output macros */ +#define BMA456MM_ORIENT_OUT_POS UINT8_C(0) +#define BMA456MM_ORIENT_OUT_MSK UINT8_C(0x03) +#define BMA456MM_ORIENT_FACEUP_DOWN_POS UINT8_C(2) +#define BMA456MM_ORIENT_FACEUP_DOWN_MSK UINT8_C(0x04) + +/**\name Orientation output macros */ +/* Bit pos 2 reflects the face-up (0) face-down(1) only if ud_en is enabled */ +#define BMA456MM_FACE_UP UINT8_C(0x00) +#define BMA456MM_FACE_DOWN UINT8_C(0x01) + +/* Bit pos 0-1 reflects the have the following value */ +#define BMA456MM_PORTRAIT_UP_RIGHT UINT8_C(0x00) +#define BMA456MM_LANDSCAPE_LEFT UINT8_C(0x01) +#define BMA456MM_PORTRAIT_UP_DOWN UINT8_C(0x02) +#define BMA456MM_LANDSCAPE_RIGHT UINT8_C(0x03) + +/**************************************************************/ +/**\name Low-G */ +/**************************************************************/ +/**\name Low-G enable macros */ +#define BMA456MM_LOW_G_FEAT_EN_OFFSET UINT8_C(0x03) +#define BMA456MM_LOW_G_EN_POS UINT8_C(0x04) +#define BMA456MM_LOW_G_EN_MSK UINT8_C(0x10) + +/**\name Low-g threshold macro */ +#define BMA456MM_LOW_G_THRES_MSK UINT16_C(0x7FFF) + +/**\name Low-g hysteresis macro */ +#define BMA456MM_LOW_G_HYST_MSK UINT16_C(0x0FFF) + +/**\name Low-g duration macro */ +#define BMA456MM_LOW_G_DUR_MSK UINT16_C(0x0FFF) + +/**************************************************************/ +/**\name Auto Low power */ +/**************************************************************/ + +#define BMA456MM_AUTO_LOW_POWER_EN_OFFSET UINT8_C(0x2D) + +#define BMA456MM_NO_MOT_AUTO_LOW_POWER_MSK UINT8_C(0x01) + +#define BMA456MM_AUTO_LOW_POWER_TIME_OUT_MSK UINT8_C(0x02) +#define BMA456MM_AUTO_LOW_POWER_TIME_OUT_POS UINT8_C(0x1) +#define BMA456MM_TIME_OUT_DUR_MSK UINT16_C(0x0FFC) +#define BMA456MM_TIME_OUT_DUR_POS UINT16_C(0x02) +#define BMA456MM_AUTO_LOW_POWER_ALP_EN_MSK UINT16_C(0x10) +#define BMA456MM_AUTO_LOW_POWER_ALP_EN_POS UINT8_C(0x04) +#define BMA456MM_LOW_POW_ODR_MSK UINT8_C(0x60) +#define BMA456MM_LOW_POW_ODR_POS UINT8_C(0x05) +#define BMA456MM_PWR_MGT_ENABLE_MSK UINT8_C(0x80) +#define BMA456MM_PWR_MGT_ENABLE_POS UINT8_C(0x07) + +#define BMA456MM_NO_MOT_AUTO_LOW_POWER_WORD_MSK UINT16_C(0x01) + +#define BMA456MM_AUTO_LOW_POWER_TIME_OUT_WORD_MSK UINT16_C(0x02) +#define BMA456MM_AUTO_LOW_POWER_TIME_OUT_WORD_POS UINT8_C(0x1) + +#define BMA456MM_TIME_OUT_DUR_WORD_MSK UINT16_C(0X1FFC) +#define BMA456MM_TIME_OUT_DUR_WORD_POS UINT8_C(0x02) + +#define BMA456MM_LOW_POW_ODR_WORD_MSK UINT16_C(0x6000) +#define BMA456MM_LOW_POW_ODR_WORD_POS UINT8_C(0x0D) + +#define BMA456MM_PWR_MGT_ENABLE_WORD_MSK UINT16_C(0x8000) +#define BMA456MM_PWR_MGT_ENABLE_WORD_POS UINT8_C(0x0F) + +#define BMA456MM_AUTO_LOW_POWER_STATE_POS UINT8_C(0x04) +#define BMA456MM_AUTO_LOW_POWER_STATE_MSK UINT8_C(0x10) + +/**************************************************************/ +/**\name High-g */ +/**************************************************************/ + +/**\name High-g enable macros */ +#define BMA456MM_HIGH_G_EN_OFFSET UINT8_C(0x31) +#define BMA456MM_HIGH_G_EN_MSK UINT8_C(0x80) +#define BMA456MM_HIGH_G_EN_POS UINT8_C(15) + +/**\name High-g threshold macros */ +#define BMA456MM_HIGH_G_THRES_MSK UINT16_C(0x7FFF) + +/**\name High-g hysteresis macros */ +#define BMA456MM_HIGH_G_HYST_MSK UINT16_C(0x0FFF) + +/**\name High-g duration macros */ +#define BMA456MM_HIGH_G_DUR_MSK UINT16_C(0x0FFF) + +/**\name High-g axis enable macros */ +#define BMA456MM_HIGH_G_AXIS_EN_MSK UINT8_C(0x7000) +#define BMA456MM_HIGH_G_AXIS_EN_POS UINT8_C(0x0C) + +/**\name High-g axis selection macros */ +#define BMA456MM_HIGH_G_X_EN UINT8_C(0x01) +#define BMA456MM_HIGH_G_Y_EN UINT8_C(0x02) +#define BMA456MM_HIGH_G_Z_EN UINT8_C(0x04) +#define BMA456MM_HIGH_G_EN_ALL_AXIS UINT8_C(0x07) +#define BMA456MM_HIGH_G_DIS_ALL_AXIS UINT8_C(0x00) + +/**\name High-g output macros */ +#define BMA456MM_HIGH_G_DETECT_X_MSK UINT8_C(0x01) + +#define BMA456MM_HIGH_G_DETECT_Y_MSK UINT8_C(0x02) +#define BMA456MM_HIGH_G_DETECT_Y_POS UINT8_C(0x01) + +#define BMA456MM_HIGH_G_DETECT_Z_MSK UINT8_C(0x04) +#define BMA456MM_HIGH_G_DETECT_Z_POS UINT8_C(0x02) + +#define BMA456MM_HIGH_G_DETECT_SIGN_MSK UINT8_C(0x08) +#define BMA456MM_HIGH_G_DETECT_SIGN_POS UINT8_C(0x03) + +/**************************************************************/ +/**\name Significant motion */ +/**************************************************************/ +/**\name Significant motion enable macros */ +#define BMA456MM_SIG_MOTION_EN_OFFSET UINT8_C(0x37) +#define BMA456MM_SIG_MOTION_EN_POS UINT8_C(1) +#define BMA456MM_SIG_MOTION_EN_MSK UINT8_C(0x02) + +/**\name Significant motion threshold macros */ +#define BMA456MM_SIG_MOTION_THRES_POS UINT8_C(0) +#define BMA456MM_SIG_MOTION_THRES_MSK UINT16_C(0x7FFF) + +/**\name Significant motion skiptime macros */ +#define BMA456MM_SIG_MOTION_SKIPTIME_MSK UINT16_C(0x01FF) + +/**\name Significant motion prooftime macros */ +#define BMA456MM_SIG_MOTION_PROOFTIME_POS UINT8_C(0) +#define BMA456MM_SIG_MOTION_PROOFTIME_MSK UINT8_C(0x7F) + +/**************************************************************/ +/**\name User macros */ +/**************************************************************/ +/**\name Any-motion/No-motion axis enable macros */ +#define BMA456MM_X_AXIS_EN UINT8_C(0x01) +#define BMA456MM_Y_AXIS_EN UINT8_C(0x02) +#define BMA456MM_Z_AXIS_EN UINT8_C(0x04) +#define BMA456MM_EN_ALL_AXIS UINT8_C(0x07) +#define BMA456MM_DIS_ALL_AXIS UINT8_C(0x00) + +/**\name Feature enable macros for the sensor */ +#define BMA456MM_LOW_G UINT8_C(0x01) +#define BMA456MM_ORIENT UINT8_C(0x02) +#define BMA456MM_SINGLE_TAP UINT8_C(0x04) +#define BMA456MM_DOUBLE_TAP UINT8_C(0x08) +#define BMA456MM_TRIPLE_TAP UINT8_C(0x10) +#define BMA456MM_AUTO_LOW_POWER UINT8_C(0x20) +#define BMA456MM_HIGH_G UINT8_C(0x40) +#define BMA456MM_SIG_MOTION UINT8_C(0x80) + +/**\name Interrupt status macros */ +#define BMA456MM_TAP_OUT_INT UINT8_C(0x01) +#define BMA456MM_ORIENT_INT UINT8_C(0x02) +#define BMA456MM_LOW_G_INT UINT8_C(0x04) +#define BMA456MM_HIGH_G_INT UINT8_C(0x08) +#define BMA456MM_SIG_MOT_INT UINT8_C(0x10) +#define BMA456MM_ANY_MOT_INT UINT8_C(0x20) +#define BMA456MM_NO_MOT_INT UINT8_C(0x40) +#define BMA456MM_ERROR_INT UINT8_C(0x80) + +/******************************************************************************/ +/*! @name Structure Declarations */ +/******************************************************************************/ + +/*! + * @brief Any/No motion configuration + */ +struct bma456mm_any_no_mot_config +{ + /*! Expressed in 50 Hz samples (20 ms) */ + uint16_t duration; + + /*! Threshold value for Any-motion/No-motion detection in + * 5.11g format + */ + uint16_t threshold; + + uint8_t intr_bhvr; + + uint8_t slope; + + /*! To enable selected axes */ + uint8_t axes_en; +}; + +/*! + * @brief Orientation configuration structure + */ +struct bma456mm_orientation_config +{ + /*! Upside/Downside detection */ + uint8_t upside_down; + + /*! Mode + * Symmetrical (values 0 or 3), High asymmetrical + * (value 1) or Low asymmetrical (value 2) + */ + uint8_t mode; + + /*! Blocking mode */ + uint8_t blocking; + + /*! Coded value of the threshold angle with horizontal + * used in Blocking modes + */ + uint8_t theta; + + /*! Acceleration hysteresis for Orientation detection */ + uint16_t hysteresis; +}; + +/*! + * @brief Low-G configuration + */ +struct bma456mm_low_g_config +{ + /*! Threshold value for Low-G feature */ + uint16_t threshold; + + /*! Hysteresis value for Low-G feature */ + uint16_t hysteresis; + + /*! Duration in 50Hz samples(20msec) for + * which threshold has to be exceeded + */ + uint16_t duration; +}; + +/*! + * @brief Auto sleep configuration + */ +struct bma456mm_auto_low_power +{ + /*! Enters auto-sleep, when no-motion is detected */ + uint8_t no_motion; + + /*! Enters auto-sleep, when any-motion is not detected for time_out_dur period */ + uint8_t time_out; + + /*! Duration to enter to auto sleep, when any-motion event is not detected. + * Range : 0 ms to 40690 ms + * Resolution : 20 ms + * Default Value : 2000 ms + */ + uint16_t time_out_dur; + + /*! ODR for low power mode + * --------------------------------------- + * Value Name Description + * --------------------------------------- + * 0 odr_1p5 25/16 Hz + * 1 odr_3p1 25/8 Hz + * 2 odr_6p25 25/4 Hz + * 3 odr_12p5 25/2 Hz + */ + uint8_t lp_odr; + + /*! Power management + * -------------------------------------------- + * Value Name Description + * -------------------------------------------- + * 0 Disable Disable feature optimized + * acc conf. Uses host desired + * configuration + * 1 Enable Enable feature optimized + * acc conf + */ + uint8_t pwr_mgt; +}; + +/*! + * @brief Tap param settings + */ +struct bma456mm_multitap_settings +{ + /*! Reserved parameter */ + uint16_t reserved_1; + + /*! Scaling factor for threshold */ + uint16_t tap_sens_thres; + + /*! Maximum duration after the first tap */ + uint16_t max_gest_dur; + + /*! Reserved parameter */ + uint16_t reserved_4; + + /*! Settling time for high frequency acceleration signal */ + uint16_t tap_shock_dur; + + /*! Reserved parameter */ + uint16_t reserved_6; + + /*! Minimum quite time between the two gesture detection */ + uint16_t quite_time_after_gest; + + /*! Wait for the duration set by max_gest_dur after the first tap */ + uint16_t wait_for_timeout; + + /*! Reserved parameter */ + uint16_t reserved_9; + + /*! Selection of axis from 3D-acceleration signal vector */ + uint16_t axis_sel; + + /*! Reserved parameter */ + uint16_t reserved_11; + + /*! Reserved parameter */ + uint16_t reserved_12; +}; + +/*! + * @brief High-g configuration + */ +struct bma456mm_high_g_config +{ + /*! Expressed in 200 Hz samples (5 ms) */ + uint16_t duration; + + /*! Hysteresis value for high-g in 0.74g */ + uint16_t hysteresis; + + /*! Threshold value for Any motion detection in + * 5.11g format + */ + uint16_t threshold; + + /*! To enable selected axes */ + uint8_t axes_en; +}; + +/*! + * @brief Significant motion configuration + */ +struct bma456mm_sig_motion_config +{ + /*! Holds the threshold in 5.11 g format */ + uint16_t threshold; + + /*! Holds the duration for skip in 50Hz samples (20ms) */ + uint16_t skiptime; + + /*! Holds the duration for proof in 50Hz samples (20ms) */ + uint8_t prooftime; +}; + +/*! + * @brief activity, tap output state + */ +struct bma456mm_out_state +{ + /*! + *-------------------------------|----------------------------- + * orientation_output | Values + *-------------------------------|----------------------------- + * Bit pos 0-1 reflects | BMA456MM_PORTRAIT_UP_RIGHT + * orientation output value | BMA456MM_LANDSCAPE_LEFT + * only if ud_en is enabled | BMA456MM_PORTRAIT_UP_DOWN + * | BMA456MM_LANDSCAPE_RIGHT + *-------------------------------|----------------------------- + */ + uint8_t orientation_out; + + /*! + *-------------------------------|----------------------------- + * orientation_faceup_down | Values + *-------------------------------|----------------------------- + * Bit pos 2 reflects | BMA456MM_FACE_UP + * face-up (0) or face-down(1) | BMA456MM_FACE_DOWN + * only if ud_en is enabled | + *-------------------------------|----------------------------- + */ + uint8_t orientation_faceup_down; + + /*! High-g detected on X-axis */ + uint8_t high_g_detect_x; + + /*! High-g detected on Y-axis */ + uint8_t high_g_detect_y; + + /*! High-g detected on Z-axis */ + uint8_t high_g_detect_z; + + /*! Axis direction for which the high-g was detected. + * 1 for negative axis, 0 for positive axis. + */ + uint8_t high_g_detect_sign; + + /*! Single tap detected */ + uint8_t s_tap; + + /*! Double tap detected */ + uint8_t d_tap; + + /*! Triple tap detected */ + uint8_t t_tap; +}; + +/***************************************************************************/ + +/*! BMA456MM User Interface function prototypes + ****************************************************************************/ + +/** + * \ingroup bma456mm + * \defgroup bma456mmApiInit Initialization + * @brief Initialize the sensor and device structure + */ + +/*! + * \ingroup bma456mmApiInit + * \page bma456mm_api_bma456mm_init bma456mm_init + * \code + * int8_t bma456mm_init(struct bma4_dev *dev); + * \endcode + * @details This API is the entry point. + * Call this API before using all other APIs. + * This API reads the chip-id of the sensor and sets the resolution. + * + * @param[in,out] dev : Structure instance of bma4_dev + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +int8_t bma456mm_init(struct bma4_dev *dev); + +/** + * \ingroup bma456mm + * \defgroup bma456mmApiConfig Config + * @brief Configuration APIs + */ + +/*! + * \ingroup bma456mmApiConfig + * \page bma456mm_api_bma456mm_write_config_file bma456mm_write_config_file + * \code + * int8_t bma456mm_write_config_file(struct bma4_dev *dev); + * \endcode + * @details This API is used to upload the config file to enable the features of + * the sensor. + * + * @param[in] dev : Structure instance of bma4_dev. + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +int8_t bma456mm_write_config_file(struct bma4_dev *dev); + +/*! + * \ingroup bma456mmApiConfig + * \page bma456mm_api_bma456mm_get_version_config bma456mm_get_version_config + * \code + *int8_t bma456mm_get_version_config(uint16_t *config_major, uint16_t *config_minor, struct bma4_dev *dev); + * \endcode + * @details This API is used to get the config file major and minor information. + * + * @param[in] dev : Structure instance of bma4_dev. + * @param[out] config_major : Pointer to data buffer to store the config major. + * @param[out] config_minor : Pointer to data buffer to store the config minor. + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +int8_t bma456mm_get_version_config(uint16_t *config_major, uint16_t *config_minor, struct bma4_dev *dev); + +/*! + * \ingroup bma456mmApiConfig + * \page bma456mm_api_bma456mm_get_config_id bma456mm_get_config_id + * \code + * int8_t bma456mm_get_config_id(uint16_t *config_id, struct bma4_dev *dev); + * \endcode + * @details This API is used to get the configuration id of the sensor. + * + * @param[out] config_id : Pointer variable used to store the configuration id. + * @param[in] dev : Structure instance of bma4_dev. + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +int8_t bma456mm_get_config_id(uint16_t *config_id, struct bma4_dev *dev); + +/** + * \ingroup bma456mm + * \defgroup bma456mmApiMapInt Map / Unmap Interrupt + * @brief Map / Unmap user provided interrupt to interrupt pin1 or pin2 of the sensor + */ + +/*! + * \ingroup bma456mmApiMapInt + * \page bma456mm_api_bma456mm_map_interrupt bma456mm_map_interrupt + * \code + * int8_t bma456mm_map_interrupt(uint8_t int_line, uint16_t int_map, uint8_t enable, struct bma4_dev *dev); + * \endcode + * @details This API sets/unsets the user provided interrupt to either + * interrupt pin1 or pin2 in the sensor. + * + * @param[in] int_line: Variable to select either interrupt pin1 or pin2. + * + *@verbatim + * int_line | Macros + * ------------|------------------- + * 0x00 | BMA4_INTR1_MAP + * 0x01 | BMA4_INTR2_MAP + *@endverbatim + * + * @param[in] int_map : Variable to specify the interrupts. + * @param[in] enable : Variable to specify mapping or unmapping of interrupts. + * + *@verbatim + * enable | Macros + * --------|------------------- + * 0x00 | BMA4_DISABLE + * 0x01 | BMA4_ENABLE + *@endverbatim + * + * @param[in] dev : Structure instance of bma4_dev. + * + * @note Below macros specify the interrupts. + * + * Feature Interrupts + * - BMA456MM_SINGLE_TAP_INT + * - BMA456MM_ORIENT_INT + * - BMA456MM_LOW_G_INT + * - BMA456MM_DOUBLE_TAP_INT + * - BMA456MM_ANY_MOT_INT + * - BMA456MM_NO_MOT_INT + * - BMA456MM_ERROR_INT + * + * Hardware Interrupts + * - BMA4_FIFO_FULL_INT + * - BMA4_FIFO_WM_INT + * - BMA4_MAG_DATA_RDY_INT + * - BMA4_ACCEL_DATA_RDY_INT + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +int8_t bma456mm_map_interrupt(uint8_t int_line, uint16_t int_map, uint8_t enable, struct bma4_dev *dev); + +/** + * \ingroup bma456mm + * \defgroup bma456mmApiIntS Interrupt Status + * @brief Read interrupt status of the sensor + */ + +/*! + * \ingroup bma456mmApiIntS + * \page bma456mm_api_bma456mm_read_int_status bma456mm_read_int_status + * \code + * int8_t bma456mm_read_int_status(uint16_t *int_status, struct bma4_dev *dev); + * \endcode + * @details This API reads the bma456 interrupt status from the sensor. + * + * @param[out] int_status : Variable to store the interrupt status read from + * the sensor. + * @param[in] dev : Structure instance of bma4_dev. + * + * @note Below macros are used to check the interrupt status. + * + * Feature Interrupts + * - BMA456MM_SINGLE_TAP_INT + * - BMA456MM_ORIENT_INT + * - BMA456MM_LOW_G_INT + * - BMA456MM_DOUBLE_TAP_INT + * - BMA456MM_ANY_MOT_INT + * - BMA456MM_NO_MOT_INT + * - BMA456MM_ERROR_INT + * + * Hardware Interrupts + * - BMA4_FIFO_FULL_INT + * - BMA4_FIFO_WM_INT + * - BMA4_MAG_DATA_RDY_INT + * - BMA4_ACCEL_DATA_RDY_INT + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +int8_t bma456mm_read_int_status(uint16_t *int_status, struct bma4_dev *dev); + +/** + * \ingroup bma456mm + * \defgroup bma456mmApiFeat Sensor Feature + * @brief Enables / Disables features of the sensor + */ + +/*! + * \ingroup bma456mmApiFeat + * \page bma456mm_api_bma456mm_feature_enable bma456mm_feature_enable + * \code + * int8_t bma456mm_feature_enable(uint8_t feature, uint8_t enable, struct bma4_dev *dev); + * \endcode + * @details This API enables/disables the features of the sensor. + * + * @param[in] feature : Variable to specify the features which are to be set in + * bma456 sensor. + * @param[in] enable : Variable which specifies whether to enable or disable the + * features in the bma456 sensor. + * + *@verbatim + * enable | Macros + * --------|------------------- + * 0x00 | BMA4_DISABLE + * 0x01 | BMA4_ENABLE + *@endverbatim + * + * @param[in] dev : Structure instance of bma4_dev. + * + * @note User should use the below macros to enable or disable the + * features of bma456mm sensor + * + * - BMA456MM_LOW_G + * - BMA456MM_ORIENT + * - BMA456MM_SINGLE_TAP + * - BMA456MM_DOUBLE_TAP + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +int8_t bma456mm_feature_enable(uint8_t feature, uint8_t enable, struct bma4_dev *dev); + +/** + * \ingroup bma456mm + * \defgroup bma456mmApiRemap Remap Axes + * @brief Set / Get x, y and z axis re-mapping in the sensor + */ + +/*! + * \ingroup bma456mmApiRemap + * \page bma456mm_api_bma456mm_set_remap_axes bma456mm_set_remap_axes + * \code + * int8_t bma456mm_set_remap_axes(const struct bma4_remap *remap_data, struct bma4_dev *dev); + * \endcode + * @details This API performs x, y and z axis remapping in the sensor. + * + * @param[in] remap_data : Pointer to store axes remapping data. + * @param[in] dev : Structure instance of bma4_dev + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +int8_t bma456mm_set_remap_axes(const struct bma4_remap *remap_data, struct bma4_dev *dev); + +/*! + * \ingroup bma456mmApiRemap + * \page bma456mm_api_bma456mm_get_remap_axes bma456mm_get_remap_axes + * \code + * int8_t bma456mm_get_remap_axes(struct bma4_remap *remap_data, struct bma4_dev *dev); + * \endcode + * @details This API reads the x, y and z axis remap data from the sensor. + * + * @param[out] remap_data : Pointer to store axis remap data which is read + * from the bma456 sensor. + * @param[in] dev : Structure instance of bma4_dev + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +int8_t bma456mm_get_remap_axes(struct bma4_remap *remap_data, struct bma4_dev *dev); + +/** + * \ingroup bma456mm + * \defgroup bma456mmApiAnyMot Any motion Feature + * @brief Functions of Any motion feature of the sensor + */ + +/*! + * \ingroup bma456mmApiAnyMot + * \page bma456mm_api_bma456mm_set_any_mot_config bma456mm_set_any_mot_config + * \code + * int8_t bma456mm_set_any_mot_config(const struct bma456mm_any_no_mot_config *any_mot, struct bma4_dev *dev); + * \endcode + * @details This API sets the configuration of any-motion feature in the sensor + * This API enables/disables the any-motion feature according to the axis set. + * + * @param[in] any_mot : Pointer to structure variable to configure + * any-motion. + * + * @verbatim + * ------------------------------------------------------------------------- + * Structure parameters | Description + * --------------------------------|---------------------------------------- + * | Defines the number of + * | consecutive data points for + * | which the threshold condition + * duration | must be respected, for interrupt + * | assertion. It is expressed in + * | 50 Hz samples (20 ms). + * | Range is 0 to 163sec. + * | Default value is 5 = 100ms. + * --------------------------------|---------------------------------------- + * | Slope threshold value for + * | Any-motion detection + * threshold | in 5.11g format. + * | Range is 0 to 1g. + * | Default value is 0xAA = 83mg. + * --------------------------------|---------------------------------------- + * | Enables the feature on a per-axis + * axis_en | basis. + * --------------------------------------------------------------------------- + * | Configuration for acceleration + * slope | scope computation. + * --------------------------------------------------------------------------- + * @endverbatim + * + *@verbatim + * Value | axis_en + * ---------|------------------------- + * 0x00 | BMA456MM_DIS_ALL_AXIS + * 0x01 | BMA456MM_X_AXIS_EN + * 0x02 | BMA456MM_Y_AXIS_EN + * 0x04 | BMA456MM_Z_AXIS_EN + * 0x07 | BMA456MM_EN_ALL_AXIS + *@endverbatim + * + * @param[in] dev : Structure instance of bma4_dev + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +int8_t bma456mm_set_any_mot_config(const struct bma456mm_any_no_mot_config *any_mot, struct bma4_dev *dev); + +/*! + * \ingroup bma456mmApiAnyMot + * \page bma456mm_api_bma456mm_get_any_motion_config bma456mm_get_any_motion_config + * \code + * int8_t bma456mm_get_any_motion_config(struct bma456mm_anymotion_config *any_motion, struct bma4_dev *dev); + * \endcode + * @details This API gets the configuration of any-motion feature from the + * sensor. + * + * @param[out] any_mot : Pointer to structure variable to configure + * any-motion. + * + * @verbatim + * ------------------------------------------------------------------------- + * Structure parameters | Description + * --------------------------------|---------------------------------------- + * | Defines the number of + * | consecutive data points for + * | which the threshold condition + * duration | must be respected, for interrupt + * | assertion. It is expressed in + * | 50 Hz samples (20 ms). + * | Range is 0 to 163sec. + * | Default value is 5 = 100ms. + * --------------------------------|---------------------------------------- + * | Slope threshold value for + * | Any-motion detection + * threshold | in 5.11g format. + * | Range is 0 to 1g. + * | Default value is 0xAA = 83mg. + * --------------------------------|----------------------------------------- + * | Enables the feature on a per-axis + * axis_en | basis. + * --------------------------------------------------------------------------- + * | Configuration for acceleration + * slope | scope computation. + * --------------------------------------------------------------------------- + * @endverbatim + * + *@verbatim + * Value | axis_en + * ---------|------------------------- + * 0x00 | BMA456MM_DIS_ALL_AXIS + * 0x01 | BMA456MM_X_AXIS_EN + * 0x02 | BMA456MM_Y_AXIS_EN + * 0x04 | BMA456MM_Z_AXIS_EN + * 0x07 | BMA456MM_EN_ALL_AXIS + *@endverbatim + * + * @param[in] dev : Structure instance of bma4_dev + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +int8_t bma456mm_get_any_mot_config(struct bma456mm_any_no_mot_config *any_mot, struct bma4_dev *dev); + +/** + * \ingroup bma456mm + * \defgroup bma456mmApiNomot No-Motion Feature + * @brief Operations of no-motion feature of the sensor + */ + +/*! + * \ingroup bma456mmApiNomot + * \page bma456mm_api_bma456mm_set_no_motion_config bma456mm_set_no_motion_config + * \code + * int8_t bma456mm_set_no_motion_config(const struct bma456mm_nomotion_config *no_motion, struct bma4_dev *dev); + * \endcode + * @details This API sets the configuration of no-motion feature in the sensor + * This API enables/disables the no-motion feature according to the axis set. + * + * @param[in] no_mot : Pointer to structure variable to configure + * no-motion. + * @verbatim + * ------------------------------------------------------------------------- + * Structure parameters | Description + * --------------------------------|---------------------------------------- + * | Defines the number of + * | consecutive data points for + * | which the threshold condition + * duration | must be respected, for interrupt + * | assertion. It is expressed in + * | 50 Hz samples (20 ms). + * | Range is 0 to 163sec. + * | Default value is 5 = 100ms. + * --------------------------------|---------------------------------------- + * | Slope threshold value for + * | No-motion detection + * threshold | in 5.11g format. + * | Range is 0 to 1g. + * | Default value is 0xAA = 83mg. + * --------------------------------|---------------------------------------- + * | Enables the feature on a per-axis + * axis_en | basis. + * --------------------------------------------------------------------------- + * @endverbatim + * + *@verbatim + * Value | axis_en + * ---------|------------------------- + * 0x00 | BMA456MM_DIS_ALL_AXIS + * 0x01 | BMA456MM_X_AXIS_EN + * 0x02 | BMA456MM_Y_AXIS_EN + * 0x04 | BMA456MM_Z_AXIS_EN + * 0x07 | BMA456MM_EN_ALL_AXIS + *@endverbatim + * + * @param[in] dev : Structure instance of bma4_dev + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +int8_t bma456mm_set_no_mot_config(const struct bma456mm_any_no_mot_config *no_mot, struct bma4_dev *dev); + +/*! + * \ingroup bma456mmApiNomot + * \page bma456mm_api_bma456mm_get_no_motion_config bma456mm_get_no_motion_config + * \code + * int8_t bma456mm_get_no_motion_config(struct bma456mm_nomotion_config *no_motion, struct bma4_dev *dev); + * \endcode + * @details This API gets the configuration of no-motion feature from the + * sensor. + * + * @param[out] no_mot : Pointer to structure variable to configure + * no-motion. + * + * @verbatim + * ------------------------------------------------------------------------- + * Structure parameters | Description + * --------------------------------|---------------------------------------- + * | Defines the number of + * | consecutive data points for + * | which the threshold condition + * duration | must be respected, for interrupt + * | assertion. It is expressed in + * | 50 Hz samples (20 ms). + * | Range is 0 to 163sec. + * | Default value is 5 = 100ms. + * --------------------------------|---------------------------------------- + * | Slope threshold value for + * | No-motion detection + * threshold | in 5.11g format. + * | Range is 0 to 1g. + * | Default value is 0xAA = 83mg. + * --------------------------------|----------------------------------------- + * | Enables the feature on a per-axis + * axis_en | basis. + * --------------------------------------------------------------------------- + * @endverbatim + * + *@verbatim + * Value | axis_en + * ---------|------------------------- + * 0x00 | BMA456MM_DIS_ALL_AXIS + * 0x01 | BMA456MM_X_AXIS_EN + * 0x02 | BMA456MM_Y_AXIS_EN + * 0x04 | BMA456MM_Z_AXIS_EN + * 0x07 | BMA456MM_EN_ALL_AXIS + *@endverbatim + * + * @param[in] dev : Structure instance of bma4_dev + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +int8_t bma456mm_get_no_mot_config(struct bma456mm_any_no_mot_config *no_mot, struct bma4_dev *dev); + +/** + * \ingroup bma456mm + * \defgroup bma456mmApiOrientation Orientation Feature + * @brief Functions of Orientation feature of the sensor + */ + +/*! + * \ingroup bma456mmApiOrientation + * \page bma456mm_api_bma456mm_set_orientation_config bma456mm_set_orientation_config + * \code + * int8_t bma456mm_set_orientation_config(struct bma456mm_orientation_config *orientation, struct bma4_dev *dev); + * \endcode + * @details This API sets the configuration of orientation feature of the sensor. + * + * @param[in] orientation : Pointer to structure variable used to + * store the orientation feature settings to be written to sensor. + * + * Structure members are provided in the table below + * + *@verbatim + * ------------------------------------------------------------------------- + * Structure parameters | Description + * --------------------------------|---------------------------------------- + * ud_en | Enables face upside/downside + * | detection if set to 1 + * --------------------------------|---------------------------------------- + * | Symmetrical (values 0 or 3), + * mode | High asymmetrical (value 1) + * | or Low asymmetrical (value 2). + * --------------------------------|---------------------------------------- + * | Sets the blocking mode. + * blocking | Default value is 3, the most + * | restrictive blocking mode. + * ------------------------------------------------------------------------- + * | Coded value of the threshold angle + * | with horizontal used in blocking + * theta | modes, theta = 64 * (tan(angle)^2). + * | Default value is 40 which is + * | equivalent to 38 degrees angle. + * ------------------------------------------------------------------------- + * | Acceleration hysteresis for + * | orientation detection. + * hysteresis | Range is 0 to 1g. + * | Default value is 0x80 = 0.0625g. + * ------------------------------------------------------------------------- + *@endverbatim + * + * @param[in] dev : Structure instance of bma4_dev + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +int8_t bma456mm_set_orientation_config(const struct bma456mm_orientation_config *orientation, struct bma4_dev *dev); + +/*! + * \ingroup bma456mmApiOrientation + * \page bma456mm_api_bma456mm_get_orientation_config bma456mm_get_orientation_config + * \code + * int8_t bma456mm_get_orientation_config(struct bma456mm_orientation_config *orientation, struct bma4_dev *dev); + * \endcode + * @details This API gets the configuration of orientation feature from the sensor. + * + * @param[out] orientation : Pointer to structure variable used to + * store the orientation feature settings read from the sensor. + * + * Structure members are provided in the table below + * + *@verbatim + * ------------------------------------------------------------------------- + * Structure parameters | Description + * --------------------------------|---------------------------------------- + * ud_en | Enables face upside/downside + * | detection if set to 1 + * --------------------------------|---------------------------------------- + * | symmetrical (values 0 or 3), + * mode | high asymmetrical (value 1) + * | or low asymmetrical (value 2). + * --------------------------------|---------------------------------------- + * | Sets the blocking mode. + * blocking | Default value is 3, the most + * | restrictive blocking mode. + * ------------------------------------------------------------------------- + * | Coded value of the threshold angle + * | with horizontal used in blocking + * theta | modes, theta = 64 * (tan(angle)^2). + * | Default value is 40 which is + * | equivalent to 38 degrees angle. + * ------------------------------------------------------------------------- + * | Acceleration hysteresis for + * | orientation detection. + * hysteresis | Range is 0 to 1g. + * | Default value is 0x80 = 0.0625g. + * ------------------------------------------------------------------------- + *@endverbatim + * + * @param[in] dev : Structure instance of bma4_dev + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +int8_t bma456mm_get_orientation_config(struct bma456mm_orientation_config *orientation, struct bma4_dev *dev); + +/** + * \ingroup bma456mm + * \defgroup bma456mmApLowG Low-G Feature + * @brief Functions of Low-G feature of the sensor + */ + +/*! + * \ingroup bma456mmApLowG + * \page bma456mm_api_bma456mm_set_low_g_config bma456mm_set_low_g_config + * \code + * int8_t bma456mm_set_low_g_config(const struct bma456mm_low_g_config *low_g, struct bma4_dev *dev); + * \endcode + * @details This API sets the configuration of low-g feature of the sensor. + * + * @param[in] low_g : Pointer to structure variable used to + * store the low-g feature settings to be written to the sensor. + * + * Structure members are provided in the table below + * + *@verbatim + * ------------------------------------------------------------------------- + * Structure parameters | Description + * --------------------------------|---------------------------------------- + * | Threshold value for low-g feature. + * threshold | Range is 0 to 1g. + * | Default value is 512 = 0.25g. + * --------------------------------|---------------------------------------- + * | Hysteresis value for low_g feature. + * hysteresis | Range is 0 to 0.5g. + * | Default value is 256 = 0.125g. + * --------------------------------|---------------------------------------- + * | Duration in 50 Hz samples (20 msec) for + * duration | which the threshold has to be exceeded. + * | Range is 0 to 82 sec. + * | Default value is 0 = 0 ms. + * --------------------------------|---------------------------------------- + *@endverbatim + * + * @param[in] dev : Structure instance of bma4_dev + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +int8_t bma456mm_set_low_g_config(const struct bma456mm_low_g_config *low_g, struct bma4_dev *dev); + +/*! + * \ingroup bma456mmApLowG + * \page bma456mm_api_bma456mm_get_low_g_config bma456mm_get_low_g_config + * \code + * int8_t bma456mm_get_low_g_config(struct bma456mm_low_g_config *low_g, struct bma4_dev *dev); + * \endcode + * @details This API gets the configuration of significant motion feature + * from the sensor. + * + * @param[out] low_g : Pointer to structure variable used to + * store the low-g feature settings read from the sensor. + * + * Structure members are provided in the table below + * + *@verbatim + * ------------------------------------------------------------------------- + * Structure parameters | Description + * --------------------------------|---------------------------------------- + * | Threshold value for low-g feature. + * threshold | Range is 0 to 1g. + * | Default value is 512 = 0.25g. + * --------------------------------|---------------------------------------- + * | Hysteresis value for low_g feature. + * hysteresis | Range is 0 to 0.5g. + * | Default value is 256 = 0.125g. + * --------------------------------|---------------------------------------- + * | Duration in 50 Hz samples (20 msec) for + * duration | which the threshold has to be exceeded. + * | Range is 0 to 82 sec. + * | Default value is 0 = 0 ms. + * --------------------------------|---------------------------------------- + *@endverbatim + * + * @param[in] dev : Structure instance of bma4_dev + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +int8_t bma456mm_get_low_g_config(struct bma456mm_low_g_config *low_g, struct bma4_dev *dev); + +/** + * \ingroup bma456mm + * \defgroup bma456mmApOP Output state + * @brief Functions to provide feature output status + */ + +/*! + * \ingroup bma456mmApOP + * \page bma456mm_api_bma456mm_output_state bma456mm_output_state + * \code + * int8_t bma456mm_output_state(struct bma456mm_out_state *out_state, struct bma4_dev *dev); + * \endcode + * @details This API gets the output for orientation, tap(single, double, triple) and high-g features. + * + * @param[out] out_state : Pointer variable which stores feature output values. + * @param[in] dev : Structure instance of bma4_dev + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +int8_t bma456mm_output_state(struct bma456mm_out_state *out_state, struct bma4_dev *dev); + +/** + * \ingroup bma456mm + * \defgroup bma456mmApiTap Tap Feature + * @brief Tap feature operations + */ + +/*! + * \ingroup bma456mmApiTap + * \page bma456mm_api_bma456mm_tap_get_parameter bma456mm_tap_get_parameter + * \code + * int8_t bma456mm_tap_get_parameter(struct bma456mm_multitap_settings *setting, struct bma4_dev *dev); + * \endcode + * @details This API gets the parameter1 to parameter12 settings of the tap + * feature. + * + * @param[out] setting : Pointer to structure variable which stores the + * parameter1 to parameter12 read from the sensor. + * @param[in] dev : Structure instance of bma4_dev + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +int8_t bma456mm_tap_get_parameter(struct bma456mm_multitap_settings *setting, struct bma4_dev *dev); + +/*! + * \ingroup bma456mmApiTap + * \page bma456mm_api_bma456mm_tap_set_parameter bma456mm_tap_set_parameter + * \code + * int8_t bma456mm_tap_set_parameter(const struct bma456mm_multitap_settings *setting, struct bma4_dev *dev); + * \endcode + * @details This API sets the parameter1 to parameter12 settings of the tap + * feature in the sensor. + * + * @param[in] setting : Pointer to structure variable which stores the + * parameter1 to parameter12 settings read from the sensor. + * @param[in] dev : Structure instance of bma4_dev + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +int8_t bma456mm_tap_set_parameter(const struct bma456mm_multitap_settings *setting, struct bma4_dev *dev); + +/** + * \ingroup bma456mm + * \defgroup bma456mmApiAutoLP Auto Low power mode + * @brief Configurations and Status of auto low power mode of the sensor + */ + +/*! + * \ingroup bma456mmApiAutoLP + * \page bma456mm_api_bma456mm_get_auto_low_power_config bma456mm_get_auto_low_power_config + * \code + * int8_t bma456mm_get_auto_low_power_config(struct bma456mm_auto_low_power *auto_low_power, struct bma4_dev *dev); + * \endcode + * @details This api gets the auto low power configuration + * + * @param auto_low_power[out] : Pointer gets the auto low power configuration. + * @param dev[in] : Structure instance of bma4_dev + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +int8_t bma456mm_get_auto_low_power_config(struct bma456mm_auto_low_power *auto_low_power, struct bma4_dev *dev); + +/*! + * \ingroup bma456mmApiAutoLP + * \page bma456mm_api_bma456mm_set_auto_low_power_config bma456mm_set_auto_low_power_config + * \code + * int8_t bma456mm_set_auto_low_power_config(const struct bma456mm_auto_low_power *auto_low_power, struct bma4_dev *dev); + * \endcode + * @details This api sets the auto low power configuration + * + * @param auto_low_power[in] : Pointer sets the auto low power configuration. + * @param dev[in] : Structure instance of bma4_dev + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +int8_t bma456mm_set_auto_low_power_config(const struct bma456mm_auto_low_power *auto_low_power, struct bma4_dev *dev); + +/*! + * \ingroup bma456mmApiAutoLP + * \page bma456mm_api_bma456mm_get_auto_low_power_state bma456mm_get_auto_low_power_state + * \code + * int8_t bma456mm_get_auto_low_power_state(uint8_t *auto_low_power_state, struct bma4_dev *dev); + * \endcode + * @details This api reads the auto low power state output status + * + * @param auto_low_power_state[out] : Pointer reads auto low power state output bit status. + * @param dev[in] : Structure instance of bma4_dev + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +int8_t bma456mm_get_auto_low_power_state(uint8_t *auto_low_power_state, struct bma4_dev *dev); + +/** + * \ingroup bma456mm + * \defgroup bma456mmApihighg High-g + * @brief Set/Get Configurations of high-g feature + */ + +/*! + * \ingroup bma456mmApihighg + * \page bma456mm_api_bma456mm_set_high_g_config bma456mm_set_high_g_config + * \code + * int8_t bma456mm_set_high_g_config(struct bma456mm_high_g_config *high_g, struct bma4_dev *dev); + * \endcode + * @details This API set the configuration of high_g feature from + * the sensor. + * + * @param[in] high_g : Pointer to structure variable used to + * store the high_g feature settings read from the sensor. + * Structure members are provided in the table below + * + *@verbatim + * ------------------------------------------------------------------------- + * Structure parameters | Description + * --------------------------------|---------------------------------------- + * | The acceleration threshold + * | above which the high_g motion + * | is signed 15 bit, signed int + * threshold | holding the threshold in 5.11 g format. + * | Default is 3072 = 2.25 g. + * | Range is 0 to 24g. + * --------------------------------|---------------------------------------- + * | Hysteresis value for high_g feature. + * hysterisis | Range is 0 to 3g. + * | Default value is 1000 = 0.74g. + * --------------------------------|---------------------------------------- + * | 12 bit signed character + * | (valid values 0...4095) holding + * duration | the duration in 200 Hz samples (5 ms) + * | for which the threshold has to be + * | exceeded; default value 4 = 20 msec. + * | Range is 0 to 20sec. + * --------------------------------|---------------------------------------- + * | Enables the feature on a per-axis + * axis_en | basis. + * --------------------------------------------------------------------------- + *@endverbatim + * + * @param[in] dev : Structure instance of bma4_dev + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +int8_t bma456mm_set_high_g_config(const struct bma456mm_high_g_config *high_g, struct bma4_dev *dev); + +/*! + * \ingroup bma456mmApihighg + * \page bma456mm_api_bma456mm_get_high_g_config bma456mm_get_high_g_config + * \code + * int8_t bma456mm_get_high_g_config(struct bma456mm_high_g_config *high_g, struct bma4_dev *dev); + * \endcode + * @details This API gets the configuration of high_g feature from + * the sensor. + * + * @param[out] high_g : Pointer to structure variable used to + * store the high_g feature settings read from the sensor. + * Structure members are provided in the table below + * + *@verbatim + * ------------------------------------------------------------------------- + * Structure parameters | Description + * --------------------------------|---------------------------------------- + * | The acceleration threshold + * | above which the high_g motion + * | is signed 15 bit, signed int + * threshold | holding the threshold in 5.11 g format. + * | Default is 3072 = 2.25 g. + * | Range is 0 to 24g. + * --------------------------------|---------------------------------------- + * | Hysteresis value for high_g feature. + * hysterisis | Range is 0 to 3g. + * | Default value is 1000 = 0.74g. + * --------------------------------|---------------------------------------- + * | 12 bit signed character + * | (valid values 0...4095) holding + * duration | the duration in 200 Hz samples (5 ms) + * | for which the threshold has to be + * | exceeded; default value 4 = 20 msec. + * | Range is 0 to 20sec. + * --------------------------------|---------------------------------------- + * | Enables the feature on a per-axis + * axis_en | basis. + * --------------------------------------------------------------------------- + *@endverbatim + * + * @param[in] dev : Structure instance of bma4_dev + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +int8_t bma456mm_get_high_g_config(struct bma456mm_high_g_config *high_g, struct bma4_dev *dev); + +/** + * \ingroup bma456mm + * \defgroup bma456mmApiSigMot Significant motion Feature + * @brief Functions of Significant motion feature of the sensor + */ + +/*! + * \ingroup bma456mmApiSigMot + * \page bma456mm_api_bma456mm_set_sig_motion_config bma456mm_set_sig_motion_config + * \code + * int8_t bma456mm_set_sig_motion_config(const struct bma456mm_sig_motion_config *sig_motion, struct bma4_dev *dev); + * \endcode + * @details This API sets the configuration of significant motion + * in the sensor. + * + * @param[in] sig_motion : Pointer to structure variable used to + * specify the significant motion feature settings. + * structure members are provided in the table below + * + *@verbatim + * ------------------------------------------------------------------------------------- + * Structure parameters | Description + * ------------------------------------------------------------------------------------- + * | Slope threshold value for this feature + * threshold | above which the significant motion is detected. + * | Range is 0 to 16g. Default is 307 = 150mg. + * ------------------------------------------------------------------------------------- + * | Defines the number of consecutive data points + * | for which the feature remains in sleep mode + * | after the first significant motion detection. + * skip_time | The feature checks for significant motion detection + * | again after this sleep duration. + * | It is expressed in 50 Hz samples (20 ms). + * | Range is 0 to 10sec. Default is 150 = 3sec + * ------------------------------------------------------------------------------------- + * | Defines duration of certain number of consecutive + * | data points after sleep time. The second significant + * proof_time | motion must be detected within this duration for + * | the interrupt to get triggered. + * | Range is 0 to 2.5sec. Default value is 50 = 1sec. + * ------------------------------------------------------------------------------------- + *@endverbatim + * + * @param[in] dev : Structure instance of bma4_dev + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +int8_t bma456mm_set_sig_motion_config(const struct bma456mm_sig_motion_config *sig_motion, struct bma4_dev *dev); + +/*! + * \ingroup bma456mmApiSigMot + * \page bma456mm_api_bma456mm_get_sig_motion_config bma456mm_get_sig_motion_config + * \code + * int8_t bma456mm_get_sig_motion_config(struct bma456mm_sig_motion_config *sig_motion, struct bma4_dev *dev); + * \endcode + * @details This API gets the configuration of significant motion feature + * from the sensor. + * + * @param[out] sig_motion : Pointer to structure variable used to + * store the significant motion feature settings read from the sensor. + * structure members are provided in the table below + * + *@verbatim + * ------------------------------------------------------------------------------------- + * Structure parameters | Description + * ------------------------------------------------------------------------------------- + * | Slope threshold value for this feature + * threshold | above which the significant motion is detected. + * | Range is 0 to 16g. Default is 307 = 150mg. + * ------------------------------------------------------------------------------------- + * | Defines the number of consecutive data points + * | for which the feature remains in sleep mode + * | after the first significant motion detection. + * skip_time | The feature checks for significant motion detection + * | again after this sleep duration. + * | It is expressed in 50 Hz samples (20 ms). + * | Range is 0 to 10sec. Default is 150 = 3sec + * ------------------------------------------------------------------------------------- + * | Defines duration of certain number of consecutive + * | data points after sleep time. The second significant + * proof_time | motion must be detected within this duration for + * | the interrupt to get triggered. + * | Range is 0 to 2.5sec. Default value is 50 = 1sec. + * ------------------------------------------------------------------------------------- + *@endverbatim + * + * @param[in] dev : Structure instance of bma4_dev + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +int8_t bma456mm_get_sig_motion_config(struct bma456mm_sig_motion_config *sig_motion, struct bma4_dev *dev); + +#ifdef __cplusplus +} +#endif /*End of CPP guard */ + +#endif /*End of header guard macro */ diff --git a/components/bma456/bma456mm_examples/accel_foc/Makefile b/components/bma456/bma456mm_examples/accel_foc/Makefile new file mode 100644 index 0000000..bb795a5 --- /dev/null +++ b/components/bma456/bma456mm_examples/accel_foc/Makefile @@ -0,0 +1,18 @@ +COINES_INSTALL_PATH ?= ../../../.. + +EXAMPLE_FILE ?= accel_foc.c + +API_LOCATION ?= ../.. + +COMMON_LOCATION ?= .. + +C_SRCS += \ +$(API_LOCATION)/bma4.c \ +$(API_LOCATION)/bma456mm.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/components/bma456/bma456mm_examples/accel_foc/accel_foc.c b/components/bma456/bma456mm_examples/accel_foc/accel_foc.c new file mode 100644 index 0000000..cbafd84 --- /dev/null +++ b/components/bma456/bma456mm_examples/accel_foc/accel_foc.c @@ -0,0 +1,741 @@ +/**\ + * Copyright (c) 2022 Bosch Sensortec GmbH. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + **/ + +/******************************************************************************/ +/*! Header Files */ +#include +#include +#include +#include +#include + +#include "bma456mm.h" +#include "common.h" +#include "coines.h" + +/******************************************************************************/ +/*! Macro Definitions */ + +#define ACCEL_SAMPLE_COUNT UINT8_C(100) + +/******************************************************************************/ +/*! Global Variable Declaration */ + +/* Structure to store temporary axes data values */ +struct temp_axes_val +{ + /* X data */ + int32_t x; + + /* Y data */ + int32_t y; + + /* Z data */ + int32_t z; +}; + +/******************************************************************************/ +/*! Static Function Declaration */ + +/*! + * @brief This internal API is used perform accel foc and determine limits based on range + * + * @param[in] range : Range of Accel + * @param[in] input_axis : Axis selected for Accel FOC + * @param[in,out] dev : Structure instance of bma4_dev. + * + * @return Status of execution. + */ +static int8_t perform_foc_range_test(uint8_t range, uint8_t input_axis, struct bma4_dev *dev); + +/*! + * @brief This internal API is to determine if average accel FOC data is within limits + * + * @param[in] avg_accel_foc_data : Average Accel FOC value + * @param[in] reference : Reference LSB based on Accel Range + * @param[in] foc_sign : Input sign of performed Accel FOC + * @param[in] min_val : Minimum acceptable LSB limit + * @param[in] max_val : Maximum acceptable LSB limit + * + * @return Status of execution. + */ +static int8_t accel_foc_report(int16_t avg_accel_foc_data, + int16_t reference, + uint8_t foc_sign, + int16_t min_val, + int16_t max_val); + +/*! + * @brief This internal API is to collect and verify accel sensor data + * + * @param[in] range : Value of Accel range + * @param[in] reference : Reference LSB based on Accel Range + * @param[in] matched_axis : Input Axis to perform Accel FOC + * @param[in] foc_sign : Input sign to perform Accel FOC + * @param[in,out] dev : Structure instance of bma4_dev. + * + * @return Status of execution. + */ +static int8_t verify_accel_foc_data(uint8_t range, + int16_t reference, + int8_t matched_axis, + uint8_t foc_sign, + struct bma4_dev *dev); + +/*! + * @brief This internal API is to calculate noise level for Accel FOC data + * + * @param[in] matched_axis : Input Axis to perform accel FOC + * @param[in] accel_foc_data : Array of Accel FOC data + * @param[in] avg_accel_foc_data : Average Accel FOC data + * + * @return Status of execution. + */ +static void calculate_noise(int8_t matched_axis, + const struct bma4_accel *accel_foc_data, + const struct bma4_accel avg_accel_foc_data); + +/******************************************************************************/ +/*! Functions */ + +/* This function starts the execution of program. */ +int main(void) +{ + /* Sensor initialization configuration. */ + struct bma4_dev dev; + + uint8_t try = 0, j; + int8_t rslt; + struct bma4_accel_config accel_conf = { 0 }; + uint8_t data = 0, range, input_axis = 0; + + /* Interface reference is given as a parameter + * For I2C : BMA4_I2C_INTF + * For SPI : BMA4_SPI_INTF + * Variant information given as parameter - BMA45X_VARIANT + */ + rslt = bma4_interface_init(&dev, BMA4_I2C_INTF, BMA45X_VARIANT); + bma4_error_codes_print_result("bma4_interface_init", rslt); + + printf("Functional test for accel foc start..\n\n"); + + printf("Choose the axis for accel FOC to be done\n"); + printf("Press '1' to choose X axis\n"); + printf("Press '2' to choose Y axis\n"); + printf("Press '3' to choose Z axis\n"); + + printf("Press '4' to choose -X axis\n"); + printf("Press '5' to choose -Y axis\n"); + printf("Press '6' to choose -Z axis\n"); + + for (;;) + { + scanf("%u", (unsigned int *)&input_axis); + if (input_axis > 0 && input_axis < 7) + { + break; + } + } + + if (input_axis == 1) + { + printf("The choosen input axis for FOC is : X\n"); + } + else if (input_axis == 2) + { + printf("The choosen input axis for FOC is : Y\n"); + } + else if (input_axis == 3) + { + printf("The choosen input axis for FOC is : Z\n"); + } + else if (input_axis == 4) + { + printf("The choosen input axis for FOC is : -X\n"); + } + else if (input_axis == 5) + { + printf("The choosen input axis for FOC is : -Y\n"); + } + else if (input_axis == 6) + { + printf("The choosen input axis for FOC is : -Z\n"); + } + + printf("Confirm your chosen axis and the sensor keeping position are same before doing FOC\n"); + + for (j = 0; j < 2; j++) + { + try = 0; + + if (j == 1) + { + printf("Keep sensor in wrong position and press 5\n"); + } + else if (j == 0) + { + printf("Keep sensor in right position and press 5\n"); + } + + for (;;) + { + scanf("%hu", (short unsigned int *)&try); + if (try == 5) + { + break; + } + } + + for (range = BMA4_ACCEL_RANGE_2G; range <= BMA4_ACCEL_RANGE_16G; range++) + { + /****************************************************************/ + /* Initialize by enabling configuration load */ + printf("#########################################################\n\n"); + + rslt = bma456mm_init(&dev); + bma4_error_codes_print_result("bma4_init", rslt); + + /* Upload the configuration file to enable the features of the sensor. */ + rslt = bma456mm_write_config_file(&dev); + bma4_error_codes_print_result("bma4_write_config", rslt); + + /* Enable the accelerometer */ + rslt = bma4_set_accel_enable(BMA4_ENABLE, &dev); + bma4_error_codes_print_result("bma4_set_accel_enable status", rslt); + + /* Accelerometer Configuration Settings */ + /* Output Data Rate */ + accel_conf.odr = BMA4_OUTPUT_DATA_RATE_50HZ; + + /* Gravity range of the sensor (+/- 2G, 4G, 8G, 16G) */ + accel_conf.range = range; + + /* The bandwidth parameter is used to configure the number of sensor samples that are averaged + * if it is set to 2, then 2^(bandwidth parameter) samples + * are averaged, resulting in 4 averaged samples + * Note1 : For more information, refer the datasheet. + * Note2 : A higher number of averaged samples will result in a less noisier signal, but + * this has an adverse effect on the power consumed. + */ + accel_conf.bandwidth = BMA4_ACCEL_NORMAL_AVG4; + + /* Enable the filter performance mode where averaging of samples + * will be done based on above set bandwidth and ODR. + * There are two modes + * 0 -> Averaging samples (Default) + * 1 -> No averaging + * For more info on No Averaging mode refer datasheet. + */ + accel_conf.perf_mode = BMA4_CIC_AVG_MODE; + + /* Set the accel configurations */ + rslt = bma4_set_accel_config(&accel_conf, &dev); + bma4_error_codes_print_result("bma4_set_accel_config status", rslt); + + /* Delay to set accel sensor configurations (20ms for 50HZ) */ + dev.delay_us(20000, dev.intf_ptr); + + /* Mapping data ready interrupt with interrupt1 to get interrupt status once getting new accel data */ + rslt = bma456mm_map_interrupt(BMA4_INTR1_MAP, BMA4_DATA_RDY_INT, BMA4_ENABLE, &dev); + bma4_error_codes_print_result("bma4_map_interrupt status", rslt); + + printf("ODR = %d, RANGE = %d, BANDWIDTH = %d\n", accel_conf.odr, accel_conf.range, accel_conf.bandwidth); + + /* Perform FOC for different ranges */ + rslt = perform_foc_range_test(range, input_axis, &dev); + + if ((j == 1) && (rslt == BMA4_E_OUT_OF_RANGE)) + { + printf("\n######### Valid input - Wrong position #########\n\n"); + bma4_error_codes_print_result("perform_foc_range_test", rslt); + } + else if ((j == 0) && (rslt == BMA4_OK)) + { + printf("\n######### Valid input - Right position #########\n\n"); + bma4_error_codes_print_result("perform_foc_range_test", rslt); + } + else if ((j == 1) && (rslt == BMA4_OK)) + { + printf("\n######### Invalid input - Right position #########\n\n"); + bma4_error_codes_print_result("perform_foc_range_test", rslt); + } + else if ((j == 0) && (rslt == BMA4_E_OUT_OF_RANGE)) + { + printf("\n######### Invalid input - Wrong position #########\n\n"); + bma4_error_codes_print_result("perform_foc_range_test", rslt); + } + else if ((j == 0) && (rslt == BMA4_E_OUT_OF_RANGE)) + { + printf("\n######### Valid input - Right position #########\n\n"); + printf("\n######### Before FOC is better than after FOC #########\n\n"); + bma4_error_codes_print_result("perform_foc_range_test", rslt); + } + else if ((j == 1) && (rslt == BMA4_E_OUT_OF_RANGE)) + { + printf("\n######### Invalid input - Right position #########\n\n"); + printf("\n######### Before FOC is better than after FOC #########\n\n"); + bma4_error_codes_print_result("perform_foc_range_test", rslt); + } + } + + /* Disable offset compensation */ + rslt = bma4_read_regs(BMA4_NV_CONFIG_ADDR, &data, 1, &dev); + bma4_error_codes_print_result("bma4_read_regs", rslt); + + data = BMA4_SET_BIT_VAL_0(data, BMA4_NV_ACCEL_OFFSET); + + rslt = bma4_write_regs(BMA4_NV_CONFIG_ADDR, &data, 1, &dev); + bma4_error_codes_print_result("bma4_write_regs", rslt); + } + + bma4_coines_deinit(); + + return rslt; +} + +static int8_t accel_foc_report(int16_t avg_accel_foc_data, + int16_t reference, + uint8_t foc_sign, + int16_t min_val, + int16_t max_val) +{ + int8_t rslt = BMA4_OK; + int16_t diff_after = 0; + + if (foc_sign == 0) + { + if ((avg_accel_foc_data >= (min_val)) && (avg_accel_foc_data <= (max_val))) + { + if (avg_accel_foc_data >= reference) + { + diff_after = avg_accel_foc_data - reference; + } + else + { + diff_after = reference - avg_accel_foc_data; + } + + printf("\n# ********** PASS | Difference = %d **********\n", diff_after); + printf("\n# Avg_FOC %d in range\n", avg_accel_foc_data); + rslt = BMA4_OK; + } + else + { + if (avg_accel_foc_data >= reference) + { + diff_after = avg_accel_foc_data - reference; + } + else + { + diff_after = reference - avg_accel_foc_data; + } + + printf("\n# ********** FAIL | Difference = %d **********\n", diff_after); + printf("\n# Avg_FOC %d not in range\n", avg_accel_foc_data); + rslt = BMA4_E_OUT_OF_RANGE; + } + } + + if (foc_sign == 1) + { + if ((avg_accel_foc_data <= (min_val)) && (avg_accel_foc_data >= (max_val))) + { + if (avg_accel_foc_data <= reference) + { + diff_after = avg_accel_foc_data - reference; + } + else + { + diff_after = reference - avg_accel_foc_data; + } + + printf("\n# ********** PASS | Difference = %d **********\n", diff_after); + printf("\n# Avg_FOC %d in range\n", avg_accel_foc_data); + rslt = BMA4_OK; + } + else + { + if (avg_accel_foc_data <= reference) + { + diff_after = avg_accel_foc_data - reference; + } + else + { + diff_after = reference - avg_accel_foc_data; + } + + printf("\n# ********** FAIL | Difference = %d **********\n", diff_after); + printf("\n# Avg_FOC %d not in range\n", avg_accel_foc_data); + rslt = BMA4_E_OUT_OF_RANGE; + } + } + + return rslt; +} + +static void calculate_noise(int8_t matched_axis, + const struct bma4_accel *accel_foc_data, + const struct bma4_accel avg_accel_foc_data) +{ + int32_t variance = 0; + double noise_level; + uint16_t idx = 0; + + if (matched_axis == 'X') + { + for (idx = 0; idx < ACCEL_SAMPLE_COUNT; idx++) + { + variance += + ((accel_foc_data[idx].x - avg_accel_foc_data.x) * (accel_foc_data[idx].x - avg_accel_foc_data.x)); + } + } + else if (matched_axis == 'Y') + { + for (idx = 0; idx < ACCEL_SAMPLE_COUNT; idx++) + { + variance += + ((accel_foc_data[idx].y - avg_accel_foc_data.y) * (accel_foc_data[idx].y - avg_accel_foc_data.y)); + } + } + else if (matched_axis == 'Z') + { + for (idx = 0; idx < ACCEL_SAMPLE_COUNT; idx++) + { + variance += + ((accel_foc_data[idx].z - avg_accel_foc_data.z) * (accel_foc_data[idx].z - avg_accel_foc_data.z)); + } + } + + noise_level = sqrt((double)variance); + + printf("\n# ********** NOISE LEVEL = %lf **********\n", noise_level); +} + +static int8_t verify_accel_foc_data(uint8_t range, + int16_t reference, + int8_t matched_axis, + uint8_t foc_sign, + struct bma4_dev *dev) +{ + int8_t rslt = BMA4_E_INVALID_STATUS; + uint8_t i; + uint16_t reg_status = 0; + int16_t xl, yl, zl; + int16_t xh, yh, zh; + int16_t min_val = 0; + int16_t max_val = 0; + struct bma4_accel accel_foc_data[ACCEL_SAMPLE_COUNT] = { { 0 } }; + struct temp_axes_val temp_foc_data = { 0 }; + struct bma4_accel avg_accel_foc_data = { 0 }; + struct bma4_accel sensor_data = { 0 }; + + /* Setting initial values */ + xl = yl = zl = 32767; + xh = yh = zh = -32768; + + /* Read accelerometer values before/after FOC */ + for (i = 0; i < ACCEL_SAMPLE_COUNT; i++) + { + for (;;) + { + /* To get the data ready interrupt status */ + rslt = bma4_read_int_status(®_status, dev); + bma4_error_codes_print_result("bma4_read_int_status", rslt); + + /* Read accelerometer data based on data ready interrupt */ + if ((rslt == BMA4_OK) && (reg_status & BMA4_ACCEL_DATA_RDY_INT)) + { + rslt = bma4_read_accel_xyz(&sensor_data, dev); + bma4_error_codes_print_result("bma4_read_accel_xyz", rslt); + + memcpy(&accel_foc_data[i], &sensor_data, sizeof(struct bma4_accel)); + + printf("X[%d] = %5d Y[%d] = %5d Z[%d] = %5d\n", + i, + accel_foc_data[i].x, + i, + accel_foc_data[i].y, + i, + accel_foc_data[i].z); + + if (xl > accel_foc_data[i].x) + { + xl = accel_foc_data[i].x; + } + + if (xh < accel_foc_data[i].x) + { + xh = accel_foc_data[i].x; + } + + if (yl > accel_foc_data[i].y) + { + yl = accel_foc_data[i].y; + } + + if (yh < accel_foc_data[i].y) + { + yh = accel_foc_data[i].y; + } + + if (zl > accel_foc_data[i].z) + { + zl = accel_foc_data[i].z; + } + + if (zh < accel_foc_data[i].z) + { + zh = accel_foc_data[i].z; + } + + temp_foc_data.x += accel_foc_data[i].x; + temp_foc_data.y += accel_foc_data[i].y; + temp_foc_data.z += accel_foc_data[i].z; + break; + + } + } + } + + /* Taking average values to calculate percentage deviation */ + avg_accel_foc_data.x = (int16_t)(temp_foc_data.x / ACCEL_SAMPLE_COUNT); + avg_accel_foc_data.y = (int16_t)(temp_foc_data.y / ACCEL_SAMPLE_COUNT); + avg_accel_foc_data.z = (int16_t)(temp_foc_data.z / ACCEL_SAMPLE_COUNT); + + printf("********* MIN & MAX VALUES ********\n"); + + printf("XL = %5d YL = %5d ZL = %5d\n", xl, yl, zl); + printf("XH = %5d YH = %5d ZH = %5d\n", xh, yh, zh); + + printf("***** AVERAGE AFTER FOC *****\n"); + printf("Avg-X = %d Avg-Y = %d Avg-Z = %d\n", + avg_accel_foc_data.x, + avg_accel_foc_data.y, + avg_accel_foc_data.z); + + /* Calculate noise level */ + calculate_noise(matched_axis, accel_foc_data, avg_accel_foc_data); + + /* "zero-g offset" of accel is +/- 20 mg for all ranges as per datasheet (for 16-bit resolution) */ + if (range == 0) + { + /* Min and Max limits for Range 2G */ + min_val = BMA4_16BIT_ACC_2G_MIN_NOISE_LIMIT; + max_val = BMA4_16BIT_ACC_2G_MAX_NOISE_LIMIT; + } + else if (range == 1) + { + /* Min and Max limits for Range 4G */ + min_val = BMA4_16BIT_ACC_4G_MIN_NOISE_LIMIT; + max_val = BMA4_16BIT_ACC_4G_MAX_NOISE_LIMIT; + } + else if (range == 2) + { + /* Min and Max limits for Range 8G */ + min_val = BMA4_16BIT_ACC_8G_MIN_NOISE_LIMIT; + max_val = BMA4_16BIT_ACC_8G_MAX_NOISE_LIMIT; + } + else if (range == 3) + { + /* Min and Max limits for Range 16G */ + min_val = BMA4_16BIT_ACC_16G_MIN_NOISE_LIMIT; + max_val = BMA4_16BIT_ACC_16G_MAX_NOISE_LIMIT; + } + + if ((matched_axis == 'X') && (foc_sign == 0)) + { + rslt = accel_foc_report(avg_accel_foc_data.x, reference, foc_sign, min_val, max_val); + printf("Range : %u Avg_FOC-X : %d Reference : %d Min_Value : %d Max_Value : %d\n", + range, + avg_accel_foc_data.x, + reference, + min_val, + max_val); + } + else if ((matched_axis == 'Y') && (foc_sign == 0)) + { + rslt = accel_foc_report(avg_accel_foc_data.y, reference, foc_sign, min_val, max_val); + printf("Range : %u Avg_FOC-X : %d Reference : %d Min_Value : %d Max_Value : %d\n", + range, + avg_accel_foc_data.y, + reference, + min_val, + max_val); + } + else if ((matched_axis == 'Z') && (foc_sign == 0)) + { + rslt = accel_foc_report(avg_accel_foc_data.z, reference, foc_sign, min_val, max_val); + printf("Range : %u Avg_FOC-X : %d Reference : %d Min_Value : %d Max_Value : %d\n", + range, + avg_accel_foc_data.z, + reference, + min_val, + max_val); + } + else if ((matched_axis == 'X') && (foc_sign == 1)) + { + rslt = accel_foc_report(avg_accel_foc_data.x, + (int16_t)(reference * (-1)), + foc_sign, + (int16_t)(min_val * (-1)), + (int16_t)(max_val * (-1))); + printf("Range : %u Avg_FOC-X : %d Reference : %d Min_Value : %d Max_Value : %d\n", + range, + avg_accel_foc_data.x, + (reference * (-1)), + (min_val * (-1)), + (max_val * (-1))); + } + else if ((matched_axis == 'Y') && (foc_sign == 1)) + { + rslt = accel_foc_report(avg_accel_foc_data.y, + (int16_t)(reference * (-1)), + foc_sign, + (int16_t)(min_val * (-1)), + (int16_t)(max_val * (-1))); + printf("Range : %u Avg_FOC-X : %d Reference : %d Min_Value : %d Max_Value : %d\n", + range, + avg_accel_foc_data.y, + (reference * (-1)), + (min_val * (-1)), + (max_val * (-1))); + } + else if ((matched_axis == 'Z') && (foc_sign == 1)) + { + rslt = accel_foc_report(avg_accel_foc_data.z, + (int16_t)(reference * (-1)), + foc_sign, + (int16_t)(min_val * (-1)), + (int16_t)(max_val * (-1))); + printf("Range : %u Avg_FOC-X : %d Reference : %d Min_Value : %d Max_Value : %d\n", + range, + avg_accel_foc_data.z, + (reference * (-1)), + (min_val * (-1)), + (max_val * (-1))); + } + + return rslt; +} + +/* Perform FOC for different range and resolutions */ +static int8_t perform_foc_range_test(uint8_t range, uint8_t input_axis, struct bma4_dev *dev) +{ + int8_t rslt; + int8_t matched_axis = 0; + int16_t reference = 0; + + /* Set accel foc axis and it's sign (x, y, z, sign)*/ + struct bma4_accel_foc_g_value g_value_foc = { 0, 0, 0, 0 }; + + if (input_axis == 1) + { + g_value_foc.x = 1; + g_value_foc.y = 0; + g_value_foc.z = 0; + g_value_foc.sign = 0; + } + else if (input_axis == 2) + { + g_value_foc.x = 0; + g_value_foc.y = 1; + g_value_foc.z = 0; + g_value_foc.sign = 0; + } + else if (input_axis == 3) + { + g_value_foc.x = 0; + g_value_foc.y = 0; + g_value_foc.z = 1; + g_value_foc.sign = 0; + } + else if (input_axis == 4) + { + g_value_foc.x = 1; + g_value_foc.y = 0; + g_value_foc.z = 0; + g_value_foc.sign = 1; + } + else if (input_axis == 5) + { + g_value_foc.x = 0; + g_value_foc.y = 1; + g_value_foc.z = 0; + g_value_foc.sign = 1; + } + else if (input_axis == 6) + { + g_value_foc.x = 0; + g_value_foc.y = 0; + g_value_foc.z = 1; + g_value_foc.sign = 1; + } + + switch (range) + { + /* Reference LSB value of 2G */ + case 0: + reference = BMA4_16BIT_ACC_FOC_2G_REF; + break; + + /* Reference LSB value of 4G */ + case 1: + reference = BMA4_16BIT_ACC_FOC_4G_REF; + break; + + /* Reference LSB value of 8G */ + case 2: + reference = BMA4_16BIT_ACC_FOC_8G_REF; + break; + + /* Reference LSB value of 16G */ + case 3: + reference = BMA4_16BIT_ACC_FOC_16G_REF; + break; + default: + break; + } + + if (g_value_foc.x == 1) + { + matched_axis = 'X'; + } + else if (g_value_foc.y == 1) + { + matched_axis = 'Y'; + } + else if (g_value_foc.z == 1) + { + matched_axis = 'Z'; + } + + if (g_value_foc.sign == 1) + { + printf("MATCHED AXIS is = -%c\n", matched_axis); + } + else + { + printf("MATCHED AXIS is = %c\n", matched_axis); + } + + printf("\n\n# Before FOC\n"); + rslt = verify_accel_foc_data(range, reference, matched_axis, g_value_foc.sign, dev); + bma4_error_codes_print_result("bma4_perform_accel_foc", rslt); + + printf("\n\n######### Perform Accel FOC #########\n\n"); + + /* Perform accelerometer FOC */ + rslt = bma4_perform_accel_foc(&g_value_foc, dev); + bma4_error_codes_print_result("bma4_perform_accel_foc", rslt); + + /* Delay after performing Accel FOC */ + dev->delay_us(30000, dev->intf_ptr); + + printf("\n\n# After FOC\n"); + rslt = verify_accel_foc_data(range, reference, matched_axis, g_value_foc.sign, dev); + + return rslt; +} diff --git a/components/bma456/bma456mm_examples/accelerometer/Makefile b/components/bma456/bma456mm_examples/accelerometer/Makefile new file mode 100644 index 0000000..2b15731 --- /dev/null +++ b/components/bma456/bma456mm_examples/accelerometer/Makefile @@ -0,0 +1,18 @@ +COINES_INSTALL_PATH ?= ../../../.. + +EXAMPLE_FILE ?= accelerometer.c + +API_LOCATION ?= ../.. + +COMMON_LOCATION ?= .. + +C_SRCS += \ +$(API_LOCATION)/bma4.c \ +$(API_LOCATION)/bma456mm.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/components/bma456/bma456mm_examples/accelerometer/accelerometer.c b/components/bma456/bma456mm_examples/accelerometer/accelerometer.c new file mode 100644 index 0000000..5aff704 --- /dev/null +++ b/components/bma456/bma456mm_examples/accelerometer/accelerometer.c @@ -0,0 +1,163 @@ +/**\ + * Copyright (c) 2022 Bosch Sensortec GmbH. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + **/ + +#include +#include "bma456mm.h" +#include "common.h" + +/******************************************************************************/ +/*! Macro definition */ + +/*! Earth's gravity in m/s^2 */ +#define GRAVITY_EARTH (9.80665f) + +/*! Macro that holds the total number of accel x,y and z axes sample counts to be printed */ +#define ACCEL_SAMPLE_COUNT UINT8_C(100) + +/******************************************************************************/ +/*! 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); + +/******************************************************************************/ +/*! Functions */ + +/* This function starts the execution of program. */ +int main(void) +{ + /* Variable to store the status of API */ + int8_t rslt; + + /* Sensor initialization configuration */ + struct bma4_dev bma = { 0 }; + + /* Variable to store accel data ready interrupt status */ + uint16_t int_status = 0; + + /* Variable that holds the accelerometer sample count */ + uint8_t n_data = 1; + + struct bma4_accel sens_data = { 0 }; + float x = 0, y = 0, z = 0; + struct bma4_accel_config accel_conf = { 0 }; + + /* Interface reference is given as a parameter + * For I2C : BMA4_I2C_INTF + * For SPI : BMA4_SPI_INTF + * Variant information given as parameter - BMA45X_VARIANT + */ + rslt = bma4_interface_init(&bma, BMA4_I2C_INTF, BMA45X_VARIANT); + bma4_error_codes_print_result("bma4_interface_init", rslt); + + /* Sensor initialization */ + rslt = bma456mm_init(&bma); + bma4_error_codes_print_result("bma456mm_init status", rslt); + + /* Upload the configuration file to enable the features of the sensor. */ + rslt = bma456mm_write_config_file(&bma); + bma4_error_codes_print_result("bma456mm_write_config status", rslt); + + /* Accelerometer configuration settings */ + /* Output data Rate */ + accel_conf.odr = BMA4_OUTPUT_DATA_RATE_50HZ; + + /* Gravity range of the sensor (+/- 2G, 4G, 8G, 16G) */ + accel_conf.range = BMA4_ACCEL_RANGE_2G; + + /* The bandwidth parameter is used to configure the number of sensor samples that are averaged + * if it is set to 2, then 2^(bandwidth parameter) samples + * are averaged, resulting in 4 averaged samples + * Note1 : For more information, refer the datasheet. + * Note2 : A higher number of averaged samples will result in a less noisier signal, but + * this has an adverse effect on the power consumed. + */ + accel_conf.bandwidth = BMA4_ACCEL_NORMAL_AVG4; + + /* Enable the filter performance mode where averaging of samples + * will be done based on above set bandwidth and ODR. + * There are two modes + * 0 -> Averaging samples (Default) + * 1 -> No averaging + * For more info on No Averaging mode refer datasheet. + */ + accel_conf.perf_mode = BMA4_CIC_AVG_MODE; + + /* Set the accel configurations */ + rslt = bma4_set_accel_config(&accel_conf, &bma); + bma4_error_codes_print_result("bma4_set_accel_config status", rslt); + + /* NOTE : Enable accel after set of configurations */ + rslt = bma4_set_accel_enable(BMA4_ENABLE, &bma); + bma4_error_codes_print_result("bma4_set_accel_enable status", rslt); + + /* Mapping data ready interrupt with interrupt pin 1 to get interrupt status once getting new accel data */ + rslt = bma456mm_map_interrupt(BMA4_INTR1_MAP, BMA4_DATA_RDY_INT, BMA4_ENABLE, &bma); + bma4_error_codes_print_result("bma456mm_map_interrupt status", rslt); + + printf("Data, Acc_Raw_X, Acc_Raw_Y, Acc_Raw_Z, Acc_ms2_X, Acc_ms2_Y, Acc_ms2_Z\n"); + + for (;;) + { + /* Read interrupt status */ + rslt = bma456mm_read_int_status(&int_status, &bma); + bma4_error_codes_print_result("bma456mm_read_int_status", rslt); + + /* Filtering only the accel data ready interrupt */ + if ((rslt == BMA4_OK) && (int_status & BMA4_ACCEL_DATA_RDY_INT)) + { + /* Read the accel x, y, z data */ + rslt = bma4_read_accel_xyz(&sens_data, &bma); + bma4_error_codes_print_result("bma4_read_accel_xyz status", rslt); + + if (rslt == BMA4_OK) + { + + /* Converting lsb to meter per second squared for 16 bit resolution at 2G range */ + x = lsb_to_ms2(sens_data.x, (float)2, bma.resolution); + y = lsb_to_ms2(sens_data.y, (float)2, bma.resolution); + z = lsb_to_ms2(sens_data.z, (float)2, bma.resolution); + + /* Print the data in m/s2 */ + printf("%d, %d, %d, %d, %4.2f, %4.2f, %4.2f\n", n_data, sens_data.x, sens_data.y, sens_data.z, x, y, z); + } + + /* Increment the count that determines the number of samples to be printed */ + n_data++; + + /* When the count reaches more than ACCEL_SAMPLE_COUNT, break and exit the loop */ + if (n_data > ACCEL_SAMPLE_COUNT) + { + break; + } + } + } + + bma4_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/components/bma456/bma456mm_examples/auto_low_power/Makefile b/components/bma456/bma456mm_examples/auto_low_power/Makefile new file mode 100644 index 0000000..17b5e1f --- /dev/null +++ b/components/bma456/bma456mm_examples/auto_low_power/Makefile @@ -0,0 +1,18 @@ +COINES_INSTALL_PATH ?= ../../../.. + +EXAMPLE_FILE ?= auto_low_power.c + +API_LOCATION ?= ../.. + +COMMON_LOCATION ?= .. + +C_SRCS += \ +$(API_LOCATION)/bma4.c \ +$(API_LOCATION)/bma456mm.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/components/bma456/bma456mm_examples/auto_low_power/auto_low_power.c b/components/bma456/bma456mm_examples/auto_low_power/auto_low_power.c new file mode 100644 index 0000000..657d04c --- /dev/null +++ b/components/bma456/bma456mm_examples/auto_low_power/auto_low_power.c @@ -0,0 +1,146 @@ +/**\ + * Copyright (c) 2022 Bosch Sensortec GmbH. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + **/ + +#include +#include "bma456mm.h" +#include "common.h" + +/******************************************************************************/ +/*! Function */ + +/* This function starts the execution of program. */ +int main(void) +{ + /* Variable to store the status of API */ + int8_t rslt; + + /* Sensor initialization configuration */ + struct bma4_dev bma = { 0 }; + + /* Variable to store auto low power state */ + uint8_t auto_low_power_state = 0; + + struct bma4_accel_config accel_conf = { 0 }; + struct bma456mm_auto_low_power auto_low_power = { 0 }; + + /* Interface reference is given as a parameter + * For I2C : BMA4_I2C_INTF + * For SPI : BMA4_SPI_INTF + * Variant information given as parameter - BMA45X_VARIANT + */ + rslt = bma4_interface_init(&bma, BMA4_I2C_INTF, BMA45X_VARIANT); + bma4_error_codes_print_result("bma4_interface_init", rslt); + + /* Sensor initialization */ + rslt = bma456mm_init(&bma); + bma4_error_codes_print_result("bma456mm_init status", rslt); + + /* Upload the configuration file to enable the features of the sensor. */ + rslt = bma456mm_write_config_file(&bma); + bma4_error_codes_print_result("bma456mm_write_config status", rslt); + + /* Get the accel configurations */ + rslt = bma4_get_accel_config(&accel_conf, &bma); + bma4_error_codes_print_result("bma4_get_accel_config status", rslt); + + if (rslt == BMA4_OK) + { + /* Accelerometer configuration settings */ + /* Output data Rate */ + accel_conf.odr = BMA4_OUTPUT_DATA_RATE_100HZ; + + /* Gravity range of the sensor (+/- 2G, 4G, 8G, 16G) */ + accel_conf.range = BMA4_ACCEL_RANGE_2G; + + /* The bandwidth parameter is used to configure the number of sensor samples that are averaged + * if it is set to 2, then 2^(bandwidth parameter) samples + * are averaged, resulting in 4 averaged samples + * Note1 : For more information, refer the datasheet. + * Note2 : A higher number of averaged samples will result in a less noisier signal, but + * this has an adverse effect on the power consumed. + */ + accel_conf.bandwidth = BMA4_ACCEL_NORMAL_AVG4; + + /* Enable the filter performance mode where averaging of samples + * will be done based on above set bandwidth and ODR. + * There are two modes + * 0 -> Averaging samples (Default) + * 1 -> No averaging + * For more info on No Averaging mode refer datasheet. + */ + accel_conf.perf_mode = BMA4_CIC_AVG_MODE; + + /* Set the accel configurations */ + rslt = bma4_set_accel_config(&accel_conf, &bma); + bma4_error_codes_print_result("bma4_set_accel_config status", rslt); + + /* NOTE : Enable accel after set of configurations */ + rslt = bma4_set_accel_enable(BMA4_ENABLE, &bma); + bma4_error_codes_print_result("bma4_set_accel_enable status", rslt); + + if (rslt == BMA4_OK) + { + /* Enable auto low power state through no-motion interrupt */ + auto_low_power.no_motion = 0; + + /* Enable auto low power state through time-out duration */ + auto_low_power.time_out = 1; + + /* Time-out duration is (value * resolution) eg: (10 * 20ms) */ + auto_low_power.time_out_dur = 10; + + /* These bits used to set odr at auto low power mode. default + * value is '0'(i.e) 25/16 HZ */ + auto_low_power.lp_odr = 0; + + /* Set this bit to set default odr of titan core in auto low power mode */ + auto_low_power.pwr_mgt = 1; + + /* Configure Auto low power settings */ + rslt = bma456mm_set_auto_low_power_config(&auto_low_power, &bma); + bma4_error_codes_print_result("bma456mm_set_auto_low_power_config status", rslt); + + if (rslt == BMA4_OK) + { + /* Get output of auto low power state */ + rslt = bma456mm_get_auto_low_power_state(&auto_low_power_state, &bma); + bma4_error_codes_print_result("bma456mm_get_auto_low_power_state status", rslt); + } + } + } + + if (rslt == BMA4_OK) + { + /* Enable auto low power feature */ + rslt = bma456mm_feature_enable(BMA456MM_AUTO_LOW_POWER, BMA4_ENABLE, &bma); + bma4_error_codes_print_result("bma456mm_feature_enable status", rslt); + } + + if (rslt == BMA4_OK) + { + /* Read and check the ODR change after changing the auto low power settings */ + rslt = bma4_get_accel_config(&accel_conf, &bma); + bma4_error_codes_print_result("bma4_get_accel_config status", rslt); + + if (rslt == BMA4_OK) + { + printf("ODR : %X\n", accel_conf.odr); + + if (auto_low_power_state) + { + printf("Auto low power state : Disabled(Auto wake state)"); + } + else + { + printf("Auto low power state : Enabled(Auto sleep state)"); + } + } + } + + bma4_coines_deinit(); + + return rslt; +} diff --git a/components/bma456/bma456mm_examples/axis_remap/Makefile b/components/bma456/bma456mm_examples/axis_remap/Makefile new file mode 100644 index 0000000..9082938 --- /dev/null +++ b/components/bma456/bma456mm_examples/axis_remap/Makefile @@ -0,0 +1,18 @@ +COINES_INSTALL_PATH ?= ../../../.. + +EXAMPLE_FILE = axis_remap.c + +API_LOCATION ?= ../.. + +COMMON_LOCATION ?= .. + +C_SRCS += \ +$(API_LOCATION)/bma4.c \ +$(API_LOCATION)/bma456mm.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/components/bma456/bma456mm_examples/axis_remap/axis_remap.c b/components/bma456/bma456mm_examples/axis_remap/axis_remap.c new file mode 100644 index 0000000..54d1aaa --- /dev/null +++ b/components/bma456/bma456mm_examples/axis_remap/axis_remap.c @@ -0,0 +1,362 @@ +/**\ + * Copyright (c) 2022 Bosch Sensortec GmbH. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + **/ + +#include +#include + +#include "coines.h" +#include "bma456mm.h" +#include "common.h" + +/*********************************************************************/ +/* functions */ +/*********************************************************************/ + +/*! + * @brief Main Function where the execution getting started to test the code. + * + * @param[in] argc + * @param[in] argv + * + * @return status + * + */ +int main(void) +{ + int8_t rslt; + struct bma4_dev bma4; + struct bma4_remap remap_data = { 0 }; + struct bma4_accel accel = { 0 }; + struct bma4_accel_config accel_conf = { 0 }; + uint16_t int_status = 0; + + char data_array[13][11] = + { { 0 }, { "BMA4_X" }, { "BMA4_Y" }, { 0 }, { "BMA4_Z" }, { 0 }, { 0 }, { 0 }, { 0 }, { "BMA4_NEG_X" }, + { "BMA4_NEG_Y" }, { 0 }, { "BMA4_NEG_Z" } }; + + /* Interface reference is given as a parameter + * For I2C : BMA4_I2C_INTF + * For SPI : BMA4_SPI_INTF + * Variant information given as parameter - BMA45X_VARIANT + */ + rslt = bma4_interface_init(&bma4, BMA4_I2C_INTF, BMA45X_VARIANT); + bma4_error_codes_print_result("bma4_interface_init", rslt); + + /* Sensor initialization */ + rslt = bma456mm_init(&bma4); + bma4_error_codes_print_result("bma456mm_init", rslt); + + /* Upload the configuration file to enable the features of the sensor. */ + rslt = bma456mm_write_config_file(&bma4); + bma4_error_codes_print_result("bma456mm_write_config", rslt); + + /* Accelerometer configuration Setting */ + /* Output data Rate */ + accel_conf.odr = BMA4_OUTPUT_DATA_RATE_50HZ; + + /* Gravity range of the sensor (+/- 2G, 4G, 8G, 16G) */ + accel_conf.range = BMA4_ACCEL_RANGE_2G; + + /* The bandwidth parameter is used to configure the number of sensor samples that are averaged + * if it is set to 2, then 2^(bandwidth parameter) samples + * are averaged, resulting in 4 averaged samples + * Note1 : For more information, refer the datasheet. + * Note2 : A higher number of averaged samples will result in a less noisier signal, but + * this has an adverse effect on the power consumed. + */ + accel_conf.bandwidth = BMA4_ACCEL_NORMAL_AVG4; + + /* Enable the filter performance mode where averaging of samples + * will be done based on above set bandwidth and ODR. + * There are two modes + * 0 -> Averaging samples (Default) + * 1 -> No averaging + * For more info on No Averaging mode refer datasheet. + */ + accel_conf.perf_mode = BMA4_CIC_AVG_MODE; + + /* Set the accel configurations */ + rslt = bma4_set_accel_config(&accel_conf, &bma4); + bma4_error_codes_print_result("bma4_set_accel_config status", rslt); + + /* NOTE : Enable accel after set of configurations */ + rslt = bma4_set_accel_enable(BMA4_ENABLE, &bma4); + bma4_error_codes_print_result("bma4_set_accel_enable status", rslt); + + /* Mapping data ready interrupt with interrupt pin 1 to get interrupt status once getting new accel data */ + rslt = bma456mm_map_interrupt(BMA4_INTR1_MAP, BMA4_DATA_RDY_INT, BMA4_ENABLE, &bma4); + bma4_error_codes_print_result("bma456mm_map_interrupt status", rslt); + + printf("\nAXIS_REMAP_FUNC_TEST 1\n"); + printf("Get sensor data of re-mapped axes\n"); + + rslt = bma456mm_get_remap_axes(&remap_data, &bma4); + bma4_error_codes_print_result("bma456mm_get_remap_axes", rslt); + + printf("Re-mapped x value = %s\n", data_array[remap_data.x]); + printf("Re-mapped y value = %s\n", data_array[remap_data.y]); + printf("Re-mapped z value = %s\n", data_array[remap_data.z]); + + printf("Expected Re-mapped x value = BMA4_X\n"); + printf("Expected Re-mapped y value = BMA4_Y\n"); + printf("Expected Re-mapped z value = BMA4_Z\n"); + + if ((remap_data.x == BMA4_X) && (remap_data.y == BMA4_Y) && (remap_data.z == BMA4_Z)) + { + printf(">> PASS\n"); + } + else + { + printf(">> FAIL\n"); + } + + printf("Print mapped data\n"); + + for (;;) + { + /* Read interrupt status */ + rslt = bma456mm_read_int_status(&int_status, &bma4); + bma4_error_codes_print_result("bma456mm_read_int_status", rslt); + + /* Filtering only the accel data ready interrupt */ + if ((rslt == BMA4_OK) && (int_status & BMA4_ACCEL_DATA_RDY_INT)) + { + rslt = bma4_read_accel_xyz(&accel, &bma4); + bma4_error_codes_print_result("bma4_read_accel_xyz", rslt); + + printf("Accel :: X = %d Y = %d Z = %d\n", accel.x, accel.y, accel.z); + + break; + } + } + + printf("\nAXIS_REMAP_FUNC_TEST 2\n"); + printf("Get sensor data of re-mapped axes\n"); + + remap_data.x = BMA4_NEG_Y; + remap_data.y = BMA4_Z; + remap_data.z = BMA4_NEG_X; + + rslt = bma456mm_set_remap_axes(&remap_data, &bma4); + bma4_error_codes_print_result("bma456mm_set_remap_axes", rslt); + + if (rslt == BMA4_OK) + { + rslt = bma456mm_get_remap_axes(&remap_data, &bma4); + bma4_error_codes_print_result("bma456mm_get_remap_axes", rslt); + + if (rslt == BMA4_OK) + { + printf("Re-mapped x value = %s\n", data_array[remap_data.x]); + printf("Re-mapped y value = %s\n", data_array[remap_data.y]); + printf("Re-mapped z value = %s\n", data_array[remap_data.z]); + } + + printf("Expected Re-mapped x value = BMA4_NEG_Y\n"); + printf("Expected Re-mapped y value = BMA4_Z\n"); + printf("Expected Re-mapped z value = BMA4_NEG_X\n"); + + if ((remap_data.x == BMA4_NEG_Y) && (remap_data.y == BMA4_Z) && (remap_data.z == BMA4_NEG_X)) + { + printf(">> PASS\n"); + } + else + { + printf(">> FAIL\n"); + } + } + + printf("Print mapped data\n"); + + for (;;) + { + /* Read interrupt status */ + rslt = bma456mm_read_int_status(&int_status, &bma4); + bma4_error_codes_print_result("bma456mm_read_int_status", rslt); + + /* Filtering only the accel data ready interrupt */ + if ((rslt == BMA4_OK) && (int_status & BMA4_ACCEL_DATA_RDY_INT)) + { + rslt = bma4_read_accel_xyz(&accel, &bma4); + bma4_error_codes_print_result("bma4_read_accel_xyz", rslt); + + printf("Accel :: X = %d Y = %d Z = %d\n", accel.x, accel.y, accel.z); + + break; + } + } + + printf("\nAXIS_REMAP_FUNC_TEST 3\n"); + printf("Get sensor data of re-mapped axes - 2nd combination\n"); + + remap_data.x = BMA4_NEG_Z; + remap_data.y = BMA4_NEG_X; + remap_data.z = BMA4_Y; + + rslt = bma456mm_set_remap_axes(&remap_data, &bma4); + bma4_error_codes_print_result("bma456mm_set_remap_axes", rslt); + + if (rslt == BMA4_OK) + { + rslt = bma456mm_get_remap_axes(&remap_data, &bma4); + bma4_error_codes_print_result("bma456mm_get_remap_axes", rslt); + + if (rslt == BMA4_OK) + { + printf("Re-mapped x value = %s\n", data_array[remap_data.x]); + printf("Re-mapped y value = %s\n", data_array[remap_data.y]); + printf("Re-mapped z value = %s\n", data_array[remap_data.z]); + } + + printf("Expected Re-mapped x value = BMA4_NEG_Z\n"); + printf("Expected Re-mapped y value = BMA4_NEG_X\n"); + printf("Expected Re-mapped z value = BMA4_Y\n"); + + if ((remap_data.x == BMA4_NEG_Z) && (remap_data.y == BMA4_NEG_X) && (remap_data.z == BMA4_Y)) + { + printf(">> PASS\n"); + } + else + { + printf(">> FAIL\n"); + } + } + + printf("Print mapped data\n"); + + for (;;) + { + /* Read interrupt status */ + rslt = bma456mm_read_int_status(&int_status, &bma4); + bma4_error_codes_print_result("bma456mm_read_int_status", rslt); + + /* Filtering only the accel data ready interrupt */ + if ((rslt == BMA4_OK) && (int_status & BMA4_ACCEL_DATA_RDY_INT)) + { + rslt = bma4_read_accel_xyz(&accel, &bma4); + bma4_error_codes_print_result("bma4_read_accel_xyz", rslt); + + printf("Accel :: X = %d Y = %d Z = %d\n", accel.x, accel.y, accel.z); + + break; + } + } + + printf("\nAXIS_REMAP_FUNC_TEST 4\n"); + printf("Get sensor data of re-mapped axes - 3rd combination\n"); + + remap_data.x = BMA4_Y; + remap_data.y = BMA4_Z; + remap_data.z = BMA4_X; + + rslt = bma456mm_set_remap_axes(&remap_data, &bma4); + bma4_error_codes_print_result("bma456mm_set_remap_axes", rslt); + if (rslt == BMA4_OK) + { + rslt = bma456mm_get_remap_axes(&remap_data, &bma4); + bma4_error_codes_print_result("bma456mm_get_remap_axes", rslt); + + if (rslt == BMA4_OK) + { + printf("Re-mapped x value = %s\n", data_array[remap_data.x]); + printf("Re-mapped y value = %s\n", data_array[remap_data.y]); + printf("Re-mapped z value = %s\n", data_array[remap_data.z]); + } + + printf("Expected Re-mapped x value = BMA4_Y\n"); + printf("Expected Re-mapped y value = BMA4_Z\n"); + printf("Expected Re-mapped z value = BMA4_X\n"); + + if ((remap_data.x == BMA4_Y) && (remap_data.y == BMA4_Z) && (remap_data.z == BMA4_X)) + { + printf(">> PASS\n"); + } + else + { + printf(">> FAIL\n"); + } + } + + printf("Print mapped data\n"); + + for (;;) + { + /* Read interrupt status */ + rslt = bma456mm_read_int_status(&int_status, &bma4); + bma4_error_codes_print_result("bma456mm_read_int_status", rslt); + + /* Filtering only the accel data ready interrupt */ + if ((rslt == BMA4_OK) && (int_status & BMA4_ACCEL_DATA_RDY_INT)) + { + rslt = bma4_read_accel_xyz(&accel, &bma4); + bma4_error_codes_print_result("bma4_read_accel_xyz", rslt); + + printf("Accel :: X = %d Y = %d Z = %d\n", accel.x, accel.y, accel.z); + + break; + } + } + + printf("\nAXIS_REMAP_FUNC_TEST 5\n"); + printf("Get sensor data of re-mapped axes - 4th combination\n"); + + remap_data.x = BMA4_NEG_X; + remap_data.y = BMA4_NEG_Y; + remap_data.z = BMA4_NEG_Z; + + rslt = bma456mm_set_remap_axes(&remap_data, &bma4); + bma4_error_codes_print_result("bma456mm_set_remap_axes", rslt); + + if (rslt == BMA4_OK) + { + rslt = bma456mm_get_remap_axes(&remap_data, &bma4); + bma4_error_codes_print_result("bma456mm_get_remap_axes", rslt); + + if (rslt == BMA4_OK) + { + printf("Re-mapped x value = %s\n", data_array[remap_data.x]); + printf("Re-mapped y value = %s\n", data_array[remap_data.y]); + printf("Re-mapped z value = %s\n", data_array[remap_data.z]); + } + + printf("Expected Re-mapped x value = BMA4_NEG_X\n"); + printf("Expected Re-mapped y value = BMA4_NEG_Y\n"); + printf("Expected Re-mapped z value = BMA4_NEG_Z\n"); + + if ((remap_data.x == BMA4_NEG_X) && (remap_data.y == BMA4_NEG_Y) && (remap_data.z == BMA4_NEG_Z)) + { + printf(">> PASS\n"); + } + else + { + printf(">> FAIL\n"); + } + } + + printf("Print mapped data\n"); + + for (;;) + { + /* Read interrupt status */ + rslt = bma456mm_read_int_status(&int_status, &bma4); + bma4_error_codes_print_result("bma456mm_read_int_status", rslt); + + /* Filtering only the accel data ready interrupt */ + if ((rslt == BMA4_OK) && (int_status & BMA4_ACCEL_DATA_RDY_INT)) + { + rslt = bma4_read_accel_xyz(&accel, &bma4); + bma4_error_codes_print_result("bma4_read_accel_xyz", rslt); + + printf("Accel :: X = %d Y = %d Z = %d\n", accel.x, accel.y, accel.z); + + break; + } + } + + bma4_coines_deinit(); + + return rslt; +} diff --git a/components/bma456/bma456mm_examples/common/common.c b/components/bma456/bma456mm_examples/common/common.c new file mode 100644 index 0000000..ca1e7c9 --- /dev/null +++ b/components/bma456/bma456mm_examples/common/common.c @@ -0,0 +1,242 @@ +/** + * Copyright (C) 2023 Bosch Sensortec GmbH. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include + +#include "bma4_defs.h" +#include "common.h" + +/******************************************************************************/ +/*! Macro definitions */ + +/*! Read write length varies based on user requirement */ +#define BMA4_READ_WRITE_LEN UINT8_C(46) + +/******************************************************************************/ +/*! Static variable definition */ + +/*! Variable that holds the I2C device address or SPI chip selection */ +static uint8_t dev_addr; + +/******************************************************************************/ +/*! User interface functions */ + +/*! + * I2C read function map to COINES platform + */ +BMA4_INTF_RET_TYPE bma4_i2c_read(uint8_t reg_addr, uint8_t *reg_data, uint32_t len, void *intf_ptr) +{ + uint8_t dev_address = *(uint8_t*)intf_ptr; + + (void)intf_ptr; + + return coines_read_i2c(COINES_I2C_BUS_0, dev_address, reg_addr, reg_data, (uint16_t)len); +} + +/*! + * I2C write function map to COINES platform + */ +BMA4_INTF_RET_TYPE bma4_i2c_write(uint8_t reg_addr, const uint8_t *reg_data, uint32_t len, void *intf_ptr) +{ + uint8_t dev_address = *(uint8_t*)intf_ptr; + + (void)intf_ptr; + + return coines_write_i2c(COINES_I2C_BUS_0, dev_address, reg_addr, (uint8_t *)reg_data, (uint16_t)len); +} + +/*! + * SPI read function map to COINES platform + */ +BMA4_INTF_RET_TYPE bma4_spi_read(uint8_t reg_addr, uint8_t *reg_data, uint32_t len, void *intf_ptr) +{ + uint8_t dev_address = *(uint8_t*)intf_ptr; + + (void)intf_ptr; + + return coines_read_spi(COINES_SPI_BUS_0, dev_address, reg_addr, reg_data, (uint16_t)len); +} + +/*! + * SPI write function map to COINES platform + */ +BMA4_INTF_RET_TYPE bma4_spi_write(uint8_t reg_addr, const uint8_t *reg_data, uint32_t len, void *intf_ptr) +{ + uint8_t dev_address = *(uint8_t*)intf_ptr; + + (void)intf_ptr; + + return coines_write_spi(COINES_SPI_BUS_0, dev_address, reg_addr, (uint8_t *)reg_data, (uint16_t)len); +} + +/*! + * Delay function map to COINES platform + */ +void bma4_delay_us(uint32_t period, void *intf_ptr) +{ + (void) intf_ptr; + coines_delay_usec(period); +} + +/*! + * @brief Function to select the interface between SPI and I2C. + * Also to initialize coines platform + */ +int8_t bma4_interface_init(struct bma4_dev *bma, uint8_t intf, enum bma4_variant variant) +{ + int8_t rslt = BMA4_OK; + + if (bma != NULL) + { + int16_t result = coines_open_comm_intf(COINES_COMM_INTF_USB, NULL); + struct coines_board_info board_info; + if (result < COINES_SUCCESS) + { + printf( + "\n Unable to connect with Application Board ! \n" " 1. Check if the board is connected and powered on. \n" " 2. Check if Application Board USB driver is installed. \n" + " 3. Check if board is in use by another application. (Insufficient permissions to access USB) \n"); + exit(result); + } + + result = coines_get_board_info(&board_info); + + #if defined(PC) + setbuf(stdout, NULL); + #endif + + (void)coines_set_shuttleboard_vdd_vddio_config(0, 0); + coines_delay_usec(10000); + + /* Bus configuration : I2C */ + if (intf == BMA4_I2C_INTF) + { + printf("I2C Interface \n"); + + /* To initialize the user I2C function */ + dev_addr = BMA4_I2C_ADDR_PRIMARY; + bma->intf = BMA4_I2C_INTF; + bma->bus_read = bma4_i2c_read; + bma->bus_write = bma4_i2c_write; + + /* SDO to Ground */ + (void)coines_set_pin_config(COINES_SHUTTLE_PIN_22, COINES_PIN_DIRECTION_OUT, COINES_PIN_VALUE_LOW); + + /* Make CSB pin HIGH */ + (void)coines_set_pin_config(COINES_SHUTTLE_PIN_21, COINES_PIN_DIRECTION_OUT, COINES_PIN_VALUE_HIGH); + coines_delay_msec(100); + + /* SDO pin is made low */ + (void)coines_set_pin_config(COINES_SHUTTLE_PIN_SDO, COINES_PIN_DIRECTION_OUT, COINES_PIN_VALUE_LOW); + + (void)coines_config_i2c_bus(COINES_I2C_BUS_0, COINES_I2C_STANDARD_MODE); + } + /* Bus configuration : SPI */ + else if (intf == BMA4_SPI_INTF) + { + printf("SPI Interface \n"); + + /* To initialize the user SPI function */ + dev_addr = COINES_SHUTTLE_PIN_7; + bma->intf = BMA4_SPI_INTF; + bma->bus_read = bma4_spi_read; + bma->bus_write = bma4_spi_write; + (void)coines_config_spi_bus(COINES_SPI_BUS_0, COINES_SPI_SPEED_7_5_MHZ, COINES_SPI_MODE0); + } + + /* Assign variant information */ + bma->variant = variant; + + /* Assign device address to interface pointer */ + bma->intf_ptr = &dev_addr; + + /* Configure delay in microseconds */ + bma->delay_us = bma4_delay_us; + + /* Configure max read/write length (in bytes) ( Supported length depends on target machine) */ + bma->read_write_len = BMA4_READ_WRITE_LEN; + + /* Set Performance mode status */ + bma->perf_mode_status = BMA4_DISABLE; + + coines_delay_msec(100); + + (void)coines_set_shuttleboard_vdd_vddio_config(3300, 3300); + + coines_delay_msec(200); + } + else + { + rslt = BMA4_E_NULL_PTR; + } + + return rslt; + +} + +/*! + * @brief Prints the execution status of the APIs. + */ +void bma4_error_codes_print_result(const char api_name[], int8_t rslt) +{ + if (rslt != BMA4_OK) + { + printf("%s\t", api_name); + if (rslt == BMA4_E_NULL_PTR) + { + printf("Error [%d] : Null pointer\r\n", rslt); + } + else if (rslt == BMA4_E_COM_FAIL) + { + printf("Error [%d] : Communication failure\r\n", rslt); + } + else if (rslt == BMA4_E_CONFIG_STREAM_ERROR) + { + printf("Error [%d] : Invalid configuration stream\r\n", rslt); + } + else if (rslt == BMA4_E_SELF_TEST_FAIL) + { + printf("Error [%d] : Self test failed\r\n", rslt); + } + else if (rslt == BMA4_E_INVALID_SENSOR) + { + printf("Error [%d] : Device not found\r\n", rslt); + } + else if (rslt == BMA4_E_OUT_OF_RANGE) + { + printf("Error [%d] : Out of Range\r\n", rslt); + } + else if (rslt == BMA4_E_AVG_MODE_INVALID_CONF) + { + printf("Error [%d] : Invalid bandwidth and ODR combination in Accel Averaging mode\r\n", rslt); + } + else + { + /* For more error codes refer "*_defs.h" */ + printf("Error [%d] : Unknown error code\r\n", rslt); + } + } +} + +/*! + * @brief Deinitializes coines platform + * + * @return void. + */ +void bma4_coines_deinit(void) +{ + (void)fflush(stdout); + coines_delay_msec(200); + + (void)coines_set_shuttleboard_vdd_vddio_config(0, 0); + coines_delay_msec(1000); + + /* Coines interface reset */ + coines_soft_reset(); + coines_delay_msec(1000); + (void)coines_close_comm_intf(COINES_COMM_INTF_USB, NULL); +} diff --git a/components/bma456/bma456mm_examples/common/common.h b/components/bma456/bma456mm_examples/common/common.h new file mode 100644 index 0000000..75c53f4 --- /dev/null +++ b/components/bma456/bma456mm_examples/common/common.h @@ -0,0 +1,127 @@ +/**\ + * Copyright (c) 2023 Bosch Sensortec GmbH. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + **/ + +#ifndef COMMON_H +#define COMMON_H + +/*! CPP guard */ +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include "bma4.h" +#include "coines.h" + +/*! + * @brief Function for reading the sensor's registers through I2C bus. + * + * @param[in] reg_addr : Register address. + * @param[out] reg_data : Pointer to the data buffer to store the read data. + * @param[in] length : No of bytes to read. + * @param[in] intf_ptr : Interface pointer + * + * @return Status of execution + * @retval = BMA4_INTF_RET_SUCCESS -> Success + * @retval != BMA4_INTF_RET_SUCCESS -> Failure Info + * + */ +BMA4_INTF_RET_TYPE bma4_i2c_read(uint8_t reg_addr, uint8_t *reg_data, uint32_t len, void *intf_ptr); + +/*! + * @brief Function for writing the sensor's registers through I2C bus. + * + * @param[in] reg_addr : Register address. + * @param[in] reg_data : Pointer to the data buffer whose value is to be written. + * @param[in] length : No of bytes to write. + * @param[in] intf_ptr : Interface pointer + * + * @return Status of execution + * @retval = BMA4_INTF_RET_SUCCESS -> Success + * @retval != BMA4_INTF_RET_SUCCESS -> Failure Info + * + */ +BMA4_INTF_RET_TYPE bma4_i2c_write(uint8_t reg_addr, const uint8_t *reg_data, uint32_t len, void *intf_ptr); + +/*! + * @brief Function for reading the sensor's registers through SPI bus. + * + * @param[in] reg_addr : Register address. + * @param[out] reg_data : Pointer to the data buffer to store the read data. + * @param[in] length : No of bytes to read. + * @param[in] intf_ptr : Interface pointer + * + * @return Status of execution + * @retval = BMA4_INTF_RET_SUCCESS -> Success + * @retval != BMA4_INTF_RET_SUCCESS -> Failure Info + * + */ +BMA4_INTF_RET_TYPE bma4_spi_read(uint8_t reg_addr, uint8_t *reg_data, uint32_t len, void *intf_ptr); + +/*! + * @brief Function for writing the sensor's registers through SPI bus. + * + * @param[in] reg_addr : Register address. + * @param[in] reg_data : Pointer to the data buffer whose data has to be written. + * @param[in] length : No of bytes to write. + * @param[in] intf_ptr : Interface pointer + * + * @return Status of execution + * @retval = BMA4_INTF_RET_SUCCESS -> Success + * @retval != BMA4_INTF_RET_SUCCESS -> Failure Info + * + */ +BMA4_INTF_RET_TYPE bma4_spi_write(uint8_t reg_addr, const uint8_t *reg_data, uint32_t len, void *intf_ptr); + +/*! + * @brief This function provides the delay for required time (Microsecond) as per the input provided in some of the + * APIs. + * + * @param[in] period_us : The required wait time in microsecond. + * @param[in] intf_ptr : Interface pointer + * + * @return void. + * + */ +void bma4_delay_us(uint32_t period, void *intf_ptr); + +/*! + * @brief Function to select the interface between SPI and I2C. + * + * @param[in] bma : Structure instance of bma4_dev + * @param[in] intf : Interface selection parameter + * @param[in] variant : Variant information of the sensor + * ( BMA42x variants values - BMA42X_VARIANT / BMA42X_B_VARIANT ) + * ( BMA45x variants values - BMA45X_VARIANT ) + * + * @return Status of execution + * @retval 0 -> Success + * @retval < 0 -> Failure Info + */ +int8_t bma4_interface_init(struct bma4_dev *bma, uint8_t intf, enum bma4_variant variant); + +/*! + * @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 bma4_error_codes_print_result(const char api_name[], int8_t rslt); + +/*! + * @brief Deinitializes coines platform + * + * @return void. + */ +void bma4_coines_deinit(void); + +#ifdef __cplusplus +} +#endif /* End of CPP guard */ + +#endif /* COMMON_H */ diff --git a/components/bma456/bma456mm_examples/fifo_full_header_mode/Makefile b/components/bma456/bma456mm_examples/fifo_full_header_mode/Makefile new file mode 100644 index 0000000..f47ddf3 --- /dev/null +++ b/components/bma456/bma456mm_examples/fifo_full_header_mode/Makefile @@ -0,0 +1,20 @@ +COINES_INSTALL_PATH ?= ../../../.. + +EXAMPLE_FILE ?= fifo_full_header_mode.c + +API_LOCATION ?= ../.. + +COMMON_LOCATION ?= .. + +C_SRCS += \ +$(API_LOCATION)/bma4.c \ +$(API_LOCATION)/bma456mm.c \ +$(COMMON_LOCATION)/common/common.c + +INCLUDEPATHS += \ +$(API_LOCATION) \ +$(COMMON_LOCATION)/common + +TARGET=MCU_APP30 + +include $(COINES_INSTALL_PATH)/coines.mk \ No newline at end of file diff --git a/components/bma456/bma456mm_examples/fifo_full_header_mode/fifo_full_header_mode.c b/components/bma456/bma456mm_examples/fifo_full_header_mode/fifo_full_header_mode.c new file mode 100644 index 0000000..7a1db66 --- /dev/null +++ b/components/bma456/bma456mm_examples/fifo_full_header_mode/fifo_full_header_mode.c @@ -0,0 +1,173 @@ +/**\ + * Copyright (c) 2022 Bosch Sensortec GmbH. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + **/ + +#include +#include "bma456mm.h" +#include "common.h" + +/******************************************************************************/ +/*! Macro definition */ + +/*! Buffer size allocated to store raw FIFO data */ +#define BMA456MM_FIFO_RAW_DATA_BUFFER_SIZE UINT16_C(1024) + +/*! Length of data to be read from FIFO */ +#define BMA456MM_FIFO_RAW_DATA_USER_LENGTH UINT16_C(1024) + +/*! Number of accel frames to be extracted from FIFO + * Calculation: + * fifo_buffer = 1024, accel_frame_len = 6, header_byte = 1. + * fifo_accel_frame_count = (1024 / (6 + 1)) = 147 frames + * + * Extra frames to parse sensortime data + */ +#define BMA456MM_FIFO_ACCEL_FRAME_COUNT UINT8_C(170) + +/******************************************************************************/ +/*! Function */ + +/* This function starts the execution of program */ +int main(void) +{ + /* Status of API are returned to this variable */ + int8_t rslt; + + /* Accelerometer configuration structure */ + struct bma4_accel_config acc_conf = { 0 }; + + /* Sensor initialization configuration */ + struct bma4_dev dev = { 0 }; + + /* Number of accelerometer frames */ + uint16_t accel_length; + + /* Variable to idx bytes */ + uint16_t idx = 0; + + /* Variable to maintain count of loop to run FIFO read */ + uint8_t loop = 1; + + /* Number of bytes of FIFO data + * NOTE : Dummy byte (for SPI Interface) required for FIFO data read must be given as part of array size + */ + uint8_t fifo_data[BMA456MM_FIFO_RAW_DATA_BUFFER_SIZE + BMA4_SENSORTIME_OVERHEAD_BYTE] = { 0 }; + + /* Array of accelerometer frames -> Total bytes = + * 147 * (6 axes bytes(+/- x,y,z) + 1 header byte) = 1029 bytes */ + struct bma4_accel fifo_accel_data[BMA456MM_FIFO_ACCEL_FRAME_COUNT] = { { 0 } }; + + /* Initialize FIFO frame structure */ + struct bma4_fifo_frame fifoframe = { 0 }; + + /* Variable that contains interrupt status value */ + uint16_t int_status = 0; + + /* Variable to hold the length of FIFO data */ + uint16_t fifo_length = 0; + + /* Interface reference is given as a parameter + * For I2C : BMA4_I2C_INTF + * For SPI : BMA4_SPI_INTF + * Variant information given as parameter - BMA45X_VARIANT + */ + rslt = bma4_interface_init(&dev, BMA4_I2C_INTF, BMA45X_VARIANT); + bma4_error_codes_print_result("bma4_interface_init", rslt); + + /* Initialize BMA456MM */ + rslt = bma456mm_init(&dev); + bma4_error_codes_print_result("bma456mm_init status", rslt); + + /* Accelerometer configuration settings */ + acc_conf.odr = BMA4_OUTPUT_DATA_RATE_100HZ; + acc_conf.bandwidth = BMA4_ACCEL_NORMAL_AVG4; + acc_conf.range = BMA4_ACCEL_RANGE_2G; + acc_conf.perf_mode = BMA4_CIC_AVG_MODE; + + /* Set the accel configurations */ + rslt = bma4_set_accel_config(&acc_conf, &dev); + bma4_error_codes_print_result("bma4_set_accel_config status", rslt); + + /* NOTE : Enable accel after set of configurations */ + rslt = bma4_set_accel_enable(BMA4_ENABLE, &dev); + bma4_error_codes_print_result("bma4_set_accel_enable status", rslt); + + /* Disabling advance power save mode as FIFO data is not accessible in advance low power mode */ + rslt = bma4_set_advance_power_save(BMA4_DISABLE, &dev); + bma4_error_codes_print_result("bma4_set_advance_power_save status", rslt); + + /* Clear FIFO configuration register */ + rslt = bma4_set_fifo_config(BMA4_FIFO_ALL, BMA4_DISABLE, &dev); + bma4_error_codes_print_result("bma4_set_fifo_config disable status", rslt); + + /* Set FIFO configuration by enabling accel. + * NOTE 1: The header mode is enabled by default. + * NOTE 2: By default the FIFO operating mode is FIFO mode. */ + rslt = bma4_set_fifo_config(BMA4_FIFO_ACCEL | BMA4_FIFO_HEADER | BMA4_FIFO_TIME, BMA4_ENABLE, &dev); + bma4_error_codes_print_result("bma4_set_fifo_config enable status", rslt); + + /* Update FIFO structure */ + fifoframe.data = fifo_data; + fifoframe.length = BMA456MM_FIFO_RAW_DATA_USER_LENGTH + BMA4_SENSORTIME_OVERHEAD_BYTE; + + printf("FIFO is configured in header mode\n"); + + rslt = bma456mm_map_interrupt(BMA4_INTR1_MAP, BMA4_FIFO_FULL_INT, BMA4_ENABLE, &dev); + bma4_error_codes_print_result("bma4_map_interrupt status", rslt); + + while (loop <= 10) + { + rslt = bma456mm_read_int_status(&int_status, &dev); + bma4_error_codes_print_result("bma4_read_int_status", rslt); + + if ((rslt == BMA4_OK) && (int_status & BMA4_FIFO_FULL_INT)) + { + printf("\nIteration : %d\n", loop); + + rslt = bma4_get_fifo_length(&fifo_length, &dev); + bma4_error_codes_print_result("bma4_get_fifo_length status", rslt); + + printf("FIFO data bytes available : %d\n", fifo_length); + printf("FIFO data bytes requested : %d\n", fifoframe.length); + + /* Read FIFO data */ + rslt = bma4_read_fifo_data(&fifoframe, &dev); + bma4_error_codes_print_result("bma4_read_fifo_data status", rslt); + + accel_length = BMA456MM_FIFO_ACCEL_FRAME_COUNT; + + if (rslt == BMA4_OK) + { + printf("Requested data frames before parsing: %d\n", accel_length); + + /* Parse the FIFO data to extract accelerometer data from the FIFO buffer */ + rslt = bma4_extract_accel(fifo_accel_data, &accel_length, &fifoframe, &dev); + printf("Parsed accelerometer data frames: %d\n", accel_length); + + printf("ACCEL, X, Y, Z\n"); + + /* Print the parsed accelerometer data from the FIFO buffer */ + for (idx = 0; idx < accel_length; idx++) + { + printf("%d, %d, %d, %d\n", + idx, + fifo_accel_data[idx].x, + fifo_accel_data[idx].y, + fifo_accel_data[idx].z); + } + + /* Print control frames like sensor time and skipped frame count */ + printf("Skipped frame count = %d\n", fifoframe.skipped_frame_count); + printf("Sensor time(in seconds) = %.4lf s\r\n", (fifoframe.sensor_time * BMA4_SENSORTIME_RESOLUTION)); + } + + loop++; + } + } + + bma4_coines_deinit(); + + return rslt; +} diff --git a/components/bma456/bma456mm_examples/fifo_full_headerless_mode/Makefile b/components/bma456/bma456mm_examples/fifo_full_headerless_mode/Makefile new file mode 100644 index 0000000..0b713d0 --- /dev/null +++ b/components/bma456/bma456mm_examples/fifo_full_headerless_mode/Makefile @@ -0,0 +1,18 @@ +COINES_INSTALL_PATH ?= ../../../.. + +EXAMPLE_FILE ?= fifo_full_headerless_mode.c + +API_LOCATION ?= ../.. + +COMMON_LOCATION ?= .. + +C_SRCS += \ +$(API_LOCATION)/bma4.c \ +$(API_LOCATION)/bma456mm.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/components/bma456/bma456mm_examples/fifo_full_headerless_mode/fifo_full_headerless_mode.c b/components/bma456/bma456mm_examples/fifo_full_headerless_mode/fifo_full_headerless_mode.c new file mode 100644 index 0000000..9f5f05b --- /dev/null +++ b/components/bma456/bma456mm_examples/fifo_full_headerless_mode/fifo_full_headerless_mode.c @@ -0,0 +1,171 @@ +/**\ + * Copyright (c) 2022 Bosch Sensortec GmbH. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + **/ + +#include +#include "bma456mm.h" +#include "common.h" + +/******************************************************************************/ +/*! Macro definition */ + +/*! Buffer size allocated to store raw FIFO data */ +#define BMA456MM_FIFO_RAW_DATA_BUFFER_SIZE UINT16_C(1024) + +/*! Length of data to be read from FIFO */ +#define BMA456MM_FIFO_RAW_DATA_USER_LENGTH UINT16_C(1024) + +/*! Number of accel frames to be extracted from FIFO + * Calculation: + * fifo_buffer = 1024, accel_frame_len = 6. + * fifo_accel_frame_count = (1024 / 6) = 170 frames + */ +#define BMA456MM_FIFO_ACCEL_FRAME_COUNT UINT8_C(170) + +/******************************************************************************/ +/*! Function */ + +/* This function starts the execution of program */ +int main(void) +{ + /* Status of API are returned to this variable */ + int8_t rslt; + + /* Accelerometer configuration structure */ + struct bma4_accel_config acc_conf = { 0 }; + + /* Sensor initialization configuration */ + struct bma4_dev dev = { 0 }; + + /* Number of accelerometer frames */ + uint16_t accel_length; + + /* Variable to idx bytes */ + uint16_t idx = 0; + + /* Variable to maintain count of loop to run FIFO read */ + uint8_t loop = 1; + + /* Number of bytes of FIFO data + * NOTE : Dummy byte (for SPI Interface) required for FIFO data read must be given as part of array size + */ + uint8_t fifo_data[BMA456MM_FIFO_RAW_DATA_BUFFER_SIZE] = { 0 }; + + /* Array of accelerometer frames -> Total bytes = + * 170 * (6 axes bytes(+/- x,y,z)) = 1020 bytes */ + struct bma4_accel fifo_accel_data[BMA456MM_FIFO_ACCEL_FRAME_COUNT] = { { 0 } }; + + /* Initialize FIFO frame structure */ + struct bma4_fifo_frame fifoframe = { 0 }; + + /* Variable that contains interrupt status value */ + uint16_t int_status = 0; + + /* Variable to hold the length of FIFO data */ + uint16_t fifo_length = 0; + + /* Interface reference is given as a parameter + * For I2C : BMA4_I2C_INTF + * For SPI : BMA4_SPI_INTF + * Variant information given as parameter - BMA45X_VARIANT + */ + rslt = bma4_interface_init(&dev, BMA4_I2C_INTF, BMA45X_VARIANT); + bma4_error_codes_print_result("bma4_interface_init", rslt); + + /* Initialize BMA456MM */ + rslt = bma456mm_init(&dev); + bma4_error_codes_print_result("bma456mm_init status", rslt); + + /* Accelerometer configuration settings */ + acc_conf.odr = BMA4_OUTPUT_DATA_RATE_100HZ; + acc_conf.bandwidth = BMA4_ACCEL_NORMAL_AVG4; + acc_conf.range = BMA4_ACCEL_RANGE_2G; + acc_conf.perf_mode = BMA4_CIC_AVG_MODE; + + /* Set the accel configurations */ + rslt = bma4_set_accel_config(&acc_conf, &dev); + bma4_error_codes_print_result("bma4_set_accel_config status", rslt); + + /* NOTE : Enable accel after set of configurations */ + rslt = bma4_set_accel_enable(BMA4_ENABLE, &dev); + bma4_error_codes_print_result("bma4_set_accel_enable status", rslt); + + /* Disabling advance power save mode as FIFO data is not accessible in advance low power mode */ + rslt = bma4_set_advance_power_save(BMA4_DISABLE, &dev); + bma4_error_codes_print_result("bma4_set_advance_power_save status", rslt); + + /* Clear FIFO configuration register */ + rslt = bma4_set_fifo_config(BMA4_FIFO_ALL, BMA4_DISABLE, &dev); + bma4_error_codes_print_result("bma4_set_fifo_config disable status", rslt); + + /* Set FIFO configuration by enabling accel. + * NOTE 1: The header mode is enabled by default. + * NOTE 2: By default the FIFO operating mode is FIFO mode. */ + rslt = bma4_set_fifo_config(BMA4_FIFO_ACCEL, BMA4_ENABLE, &dev); + bma4_error_codes_print_result("bma4_set_fifo_config enable status", rslt); + + /* Update FIFO structure */ + fifoframe.data = fifo_data; + fifoframe.length = BMA456MM_FIFO_RAW_DATA_USER_LENGTH; + + /* To enable headerless mode, disable the header. */ + rslt = bma4_set_fifo_config(BMA4_FIFO_HEADER, BMA4_DISABLE, &dev); + bma4_error_codes_print_result("bma4_set_fifo_config status", rslt); + + printf("FIFO is configured in headerless mode\n"); + + rslt = bma456mm_map_interrupt(BMA4_INTR1_MAP, BMA4_FIFO_FULL_INT, BMA4_ENABLE, &dev); + bma4_error_codes_print_result("bma4_map_interrupt status", rslt); + + while (loop <= 10) + { + rslt = bma456mm_read_int_status(&int_status, &dev); + bma4_error_codes_print_result("bma4_read_int_status", rslt); + + if ((rslt == BMA4_OK) && (int_status & BMA4_FIFO_FULL_INT)) + { + printf("\nIteration : %d\n", loop); + + rslt = bma4_get_fifo_length(&fifo_length, &dev); + bma4_error_codes_print_result("bma4_get_fifo_length status", rslt); + + printf("FIFO data bytes available : %d\n", fifo_length); + printf("FIFO data bytes requested : %d\n", fifoframe.length); + + /* Read FIFO data */ + rslt = bma4_read_fifo_data(&fifoframe, &dev); + bma4_error_codes_print_result("bma4_read_fifo_data status", rslt); + + accel_length = BMA456MM_FIFO_ACCEL_FRAME_COUNT; + + if (rslt == BMA4_OK) + { + printf("Requested data frames before parsing: %d\n", accel_length); + + /* Parse the FIFO data to extract accelerometer data from the FIFO buffer */ + rslt = bma4_extract_accel(fifo_accel_data, &accel_length, &fifoframe, &dev); + printf("Parsed accelerometer data frames: %d\n", accel_length); + + printf("ACCEL, X, Y, Z\n"); + + /* Print the parsed accelerometer data from the FIFO buffer */ + for (idx = 0; idx < accel_length; idx++) + { + printf("%d, %d, %d, %d\n", + idx, + fifo_accel_data[idx].x, + fifo_accel_data[idx].y, + fifo_accel_data[idx].z); + } + + loop++; + } + } + } + + bma4_coines_deinit(); + + return rslt; +} diff --git a/components/bma456/bma456mm_examples/fifo_watermark_header_mode/Makefile b/components/bma456/bma456mm_examples/fifo_watermark_header_mode/Makefile new file mode 100644 index 0000000..4b833ea --- /dev/null +++ b/components/bma456/bma456mm_examples/fifo_watermark_header_mode/Makefile @@ -0,0 +1,20 @@ +COINES_INSTALL_PATH ?= ../../../.. + +EXAMPLE_FILE ?= fifo_watermark_header_mode.c + +API_LOCATION ?= ../.. + +COMMON_LOCATION ?= .. + +C_SRCS += \ +$(API_LOCATION)/bma4.c \ +$(API_LOCATION)/bma456mm.c \ +$(COMMON_LOCATION)/common/common.c + +INCLUDEPATHS += \ +$(API_LOCATION) \ +$(COMMON_LOCATION)/common + +TARGET=MCU_APP30 + +include $(COINES_INSTALL_PATH)/coines.mk \ No newline at end of file diff --git a/components/bma456/bma456mm_examples/fifo_watermark_header_mode/fifo_watermark_header_mode.c b/components/bma456/bma456mm_examples/fifo_watermark_header_mode/fifo_watermark_header_mode.c new file mode 100644 index 0000000..b8cdefa --- /dev/null +++ b/components/bma456/bma456mm_examples/fifo_watermark_header_mode/fifo_watermark_header_mode.c @@ -0,0 +1,188 @@ +/**\ + * Copyright (c) 2022 Bosch Sensortec GmbH. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + **/ + +#include +#include "bma456mm.h" +#include "common.h" + +/******************************************************************************/ +/*! Macro definition */ + +/*! Buffer size allocated to store raw FIFO data */ +#define BMA456MM_FIFO_RAW_DATA_BUFFER_SIZE UINT16_C(1024) + +/*! Length of data to be read from FIFO */ +#define BMA456MM_FIFO_RAW_DATA_USER_LENGTH UINT16_C(1024) + +/*! Setting a watermark level in FIFO */ +#define BMA456MM_FIFO_WATERMARK_LEVEL UINT16_C(650) + +/*! Number of accel frames to be extracted from FIFO + * Calculation: + * fifo_watermark_level = 650, accel_frame_len = 6, header_byte = 1. + * fifo_accel_frame_count = (650 / (6 + 1)) = 93 frames + * NOTE: Extra frames are read in order to get sensor time + */ +#define BMA456MM_FIFO_ACCEL_FRAME_COUNT UINT8_C(120) + +/******************************************************************************/ +/*! Function */ + +/* This function starts the execution of program */ +int main(void) +{ + /* Status of API are returned to this variable */ + int8_t rslt; + + /* Accelerometer configuration structure */ + struct bma4_accel_config acc_conf = { 0 }; + + /* Sensor initialization configuration */ + struct bma4_dev dev = { 0 }; + + /* Number of accelerometer frames */ + uint16_t accel_length; + + /* Variable to idx bytes */ + uint16_t idx = 0; + + /* Variable to maintain count of loop to run FIFO read */ + uint8_t loop = 1; + + /* Number of bytes of FIFO data + * NOTE : Dummy byte (for SPI Interface) required for FIFO data read must be given as part of array size + */ + uint8_t fifo_data[BMA456MM_FIFO_RAW_DATA_BUFFER_SIZE + BMA4_SENSORTIME_OVERHEAD_BYTE] = { 0 }; + + /* Array of accelerometer frames -> Total bytes = + * 100 * (6 axes bytes(+/- x,y,z) + 1 header byte) = 700 bytes */ + struct bma4_accel fifo_accel_data[BMA456MM_FIFO_ACCEL_FRAME_COUNT] = { { 0 } }; + + /* Initialize FIFO frame structure */ + struct bma4_fifo_frame fifoframe = { 0 }; + + /* Variable that contains interrupt status value */ + uint16_t int_status = 0; + + /* Variable to hold the length of FIFO data */ + uint16_t fifo_length = 0; + + uint16_t watermark = 0; + + /* To set the watermark level in FIFO */ + uint16_t wm_lvl; + + /* Interface reference is given as a parameter + * For I2C : BMA4_I2C_INTF + * For SPI : BMA4_SPI_INTF + * Variant information given as parameter - BMA45X_VARIANT + */ + rslt = bma4_interface_init(&dev, BMA4_I2C_INTF, BMA45X_VARIANT); + bma4_error_codes_print_result("bma4_interface_init", rslt); + + /* Initialize BMA456MM */ + rslt = bma456mm_init(&dev); + bma4_error_codes_print_result("bma456mm_init status", rslt); + + /* Accelerometer configuration settings */ + acc_conf.odr = BMA4_OUTPUT_DATA_RATE_100HZ; + acc_conf.bandwidth = BMA4_ACCEL_NORMAL_AVG4; + acc_conf.range = BMA4_ACCEL_RANGE_2G; + acc_conf.perf_mode = BMA4_CIC_AVG_MODE; + + /* Set the accel configurations */ + rslt = bma4_set_accel_config(&acc_conf, &dev); + bma4_error_codes_print_result("bma4_set_accel_config status", rslt); + + /* NOTE : Enable accel after set of configurations */ + rslt = bma4_set_accel_enable(BMA4_ENABLE, &dev); + bma4_error_codes_print_result("bma4_set_accel_enable status", rslt); + + /* Disabling advance power save mode as FIFO data is not accessible in advance low power mode */ + rslt = bma4_set_advance_power_save(BMA4_DISABLE, &dev); + bma4_error_codes_print_result("bma4_set_advance_power_save status", rslt); + + /* Clear FIFO configuration register */ + rslt = bma4_set_fifo_config(BMA4_FIFO_ALL, BMA4_DISABLE, &dev); + bma4_error_codes_print_result("bma4_set_fifo_config disable status", rslt); + + /* Set FIFO configuration by enabling accel. + * NOTE 1: The header mode is enabled by default. + * NOTE 2: By default the FIFO operating mode is FIFO mode. */ + rslt = bma4_set_fifo_config(BMA4_FIFO_ACCEL | BMA4_FIFO_HEADER | BMA4_FIFO_TIME, BMA4_ENABLE, &dev); + bma4_error_codes_print_result("bma4_set_fifo_config enable status", rslt); + + /* Update FIFO structure */ + fifoframe.data = fifo_data; + fifoframe.length = BMA456MM_FIFO_RAW_DATA_USER_LENGTH + BMA4_SENSORTIME_OVERHEAD_BYTE; + + printf("FIFO is configured in header mode\n"); + + rslt = bma456mm_map_interrupt(BMA4_INTR1_MAP, BMA4_FIFO_WM_INT, BMA4_ENABLE, &dev); + bma4_error_codes_print_result("bma4_map_interrupt status", rslt); + + wm_lvl = BMA456MM_FIFO_WATERMARK_LEVEL; + rslt = bma4_set_fifo_wm(wm_lvl, &dev); + bma4_error_codes_print_result("bma4_set_fifo_wm status", rslt); + + while (loop <= 10) + { + rslt = bma456mm_read_int_status(&int_status, &dev); + bma4_error_codes_print_result("bma4_read_int_status", rslt); + + if ((rslt == BMA4_OK) && (int_status & BMA4_FIFO_WM_INT)) + { + printf("\nIteration : %d\n", loop); + + rslt = bma4_get_fifo_wm(&watermark, &dev); + bma4_error_codes_print_result("bma4_get_fifo_wm status", rslt); + printf("FIFO watermark level : %d\n", watermark); + + rslt = bma4_get_fifo_length(&fifo_length, &dev); + bma4_error_codes_print_result("bma4_get_fifo_length status", rslt); + + printf("FIFO data bytes available : %d\n", fifo_length); + printf("FIFO data bytes requested : %d\n", fifoframe.length); + + /* Read FIFO data */ + rslt = bma4_read_fifo_data(&fifoframe, &dev); + bma4_error_codes_print_result("bma4_read_fifo_data status", rslt); + + accel_length = BMA456MM_FIFO_ACCEL_FRAME_COUNT; + + if (rslt == BMA4_OK) + { + printf("Requested data frames before parsing: %d\n", accel_length); + + /* Parse the FIFO data to extract accelerometer data from the FIFO buffer */ + rslt = bma4_extract_accel(fifo_accel_data, &accel_length, &fifoframe, &dev); + printf("Parsed accelerometer data frames: %d\n", accel_length); + + printf("ACCEL, X, Y, Z\n"); + + /* Print the parsed accelerometer data from the FIFO buffer */ + for (idx = 0; idx < accel_length; idx++) + { + printf("%d, %d, %d, %d\n", + idx, + fifo_accel_data[idx].x, + fifo_accel_data[idx].y, + fifo_accel_data[idx].z); + } + + /* Print control frames like sensor time and skipped frame count */ + printf("Skipped frame count = %d\n", fifoframe.skipped_frame_count); + printf("Sensor time(in seconds) = %.4lf s\r\n", (fifoframe.sensor_time * BMA4_SENSORTIME_RESOLUTION)); + } + + loop++; + } + } + + bma4_coines_deinit(); + + return rslt; +} diff --git a/components/bma456/bma456mm_examples/fifo_watermark_headerless_mode/Makefile b/components/bma456/bma456mm_examples/fifo_watermark_headerless_mode/Makefile new file mode 100644 index 0000000..a6c78f4 --- /dev/null +++ b/components/bma456/bma456mm_examples/fifo_watermark_headerless_mode/Makefile @@ -0,0 +1,18 @@ +COINES_INSTALL_PATH ?= ../../../.. + +EXAMPLE_FILE ?= fifo_watermark_headerless_mode.c + +API_LOCATION ?= ../.. + +COMMON_LOCATION ?= .. + +C_SRCS += \ +$(API_LOCATION)/bma4.c \ +$(API_LOCATION)/bma456mm.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/components/bma456/bma456mm_examples/fifo_watermark_headerless_mode/fifo_watermark_headerless_mode.c b/components/bma456/bma456mm_examples/fifo_watermark_headerless_mode/fifo_watermark_headerless_mode.c new file mode 100644 index 0000000..7c0f7a8 --- /dev/null +++ b/components/bma456/bma456mm_examples/fifo_watermark_headerless_mode/fifo_watermark_headerless_mode.c @@ -0,0 +1,188 @@ +/**\ + * Copyright (c) 2022 Bosch Sensortec GmbH. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + **/ + +#include +#include "bma456mm.h" +#include "common.h" + +/******************************************************************************/ +/*! Macro definition */ + +/*! Buffer size allocated to store raw FIFO data */ +#define BMA456MM_FIFO_RAW_DATA_BUFFER_SIZE UINT16_C(1024) + +/*! Length of data to be read from FIFO */ +#define BMA456MM_FIFO_RAW_DATA_USER_LENGTH UINT16_C(1024) + +/*! Setting a watermark level in FIFO */ +#define BMA456MM_FIFO_WATERMARK_LEVEL UINT16_C(600) + +/*! Number of accel frames to be extracted from FIFO + * Calculation: + * fifo_watermark_level = 600, accel_frame_len = 6. + * fifo_accel_frame_count = (600 / 6) = 100 frames + */ +#define BMA456MM_FIFO_ACCEL_FRAME_COUNT UINT8_C(100) + +/******************************************************************************/ +/*! Function */ + +/* This function starts the execution of program */ +int main(void) +{ + /* Status of API are returned to this variable */ + int8_t rslt; + + /* Accelerometer configuration structure */ + struct bma4_accel_config acc_conf = { 0 }; + + /* Sensor initialization configuration */ + struct bma4_dev dev = { 0 }; + + /* Number of accelerometer frames */ + uint16_t accel_length; + + /* Variable to idx bytes */ + uint16_t idx = 0; + + /* Variable to maintain count of loop to run FIFO read */ + uint8_t loop = 1; + + /* Number of bytes of FIFO data + * NOTE : Dummy byte (for SPI Interface) required for FIFO data read must be given as part of array size + */ + uint8_t fifo_data[BMA456MM_FIFO_RAW_DATA_BUFFER_SIZE] = { 0 }; + + /* Array of accelerometer frames -> Total bytes = + * 100 * (6 axes bytes(+/- x,y,z)) = 600 bytes */ + struct bma4_accel fifo_accel_data[BMA456MM_FIFO_ACCEL_FRAME_COUNT] = { { 0 } }; + + /* Initialize FIFO frame structure */ + struct bma4_fifo_frame fifoframe = { 0 }; + + /* Variable that contains interrupt status value */ + uint16_t int_status = 0; + + /* Variable to hold the length of FIFO data */ + uint16_t fifo_length = 0; + + uint16_t watermark = 0; + + /* To set the watermark level in FIFO */ + uint16_t wm_lvl; + + /* Interface reference is given as a parameter + * For I2C : BMA4_I2C_INTF + * For SPI : BMA4_SPI_INTF + * Variant information given as parameter - BMA45X_VARIANT + */ + rslt = bma4_interface_init(&dev, BMA4_I2C_INTF, BMA45X_VARIANT); + bma4_error_codes_print_result("bma4_interface_init", rslt); + + /* Initialize BMA456MM */ + rslt = bma456mm_init(&dev); + bma4_error_codes_print_result("bma456mm_init status", rslt); + + /* Accelerometer configuration settings */ + acc_conf.odr = BMA4_OUTPUT_DATA_RATE_100HZ; + acc_conf.bandwidth = BMA4_ACCEL_NORMAL_AVG4; + acc_conf.range = BMA4_ACCEL_RANGE_2G; + acc_conf.perf_mode = BMA4_CIC_AVG_MODE; + + /* Set the accel configurations */ + rslt = bma4_set_accel_config(&acc_conf, &dev); + bma4_error_codes_print_result("bma4_set_accel_config status", rslt); + + /* NOTE : Enable accel after set of configurations */ + rslt = bma4_set_accel_enable(BMA4_ENABLE, &dev); + bma4_error_codes_print_result("bma4_set_accel_enable status", rslt); + + /* Disabling advance power save mode as FIFO data is not accessible in advance low power mode */ + rslt = bma4_set_advance_power_save(BMA4_DISABLE, &dev); + bma4_error_codes_print_result("bma4_set_advance_power_save status", rslt); + + /* Clear FIFO configuration register */ + rslt = bma4_set_fifo_config(BMA4_FIFO_ALL, BMA4_DISABLE, &dev); + bma4_error_codes_print_result("bma4_set_fifo_config disable status", rslt); + + /* Set FIFO configuration by enabling accel. + * NOTE 1: The header mode is enabled by default. + * NOTE 2: By default the FIFO operating mode is FIFO mode. */ + rslt = bma4_set_fifo_config(BMA4_FIFO_ACCEL, BMA4_ENABLE, &dev); + bma4_error_codes_print_result("bma4_set_fifo_config enable status", rslt); + + /* Update FIFO structure */ + fifoframe.data = fifo_data; + fifoframe.length = BMA456MM_FIFO_RAW_DATA_USER_LENGTH; + + /* To enable headerless mode, disable the header. */ + rslt = bma4_set_fifo_config(BMA4_FIFO_HEADER, BMA4_DISABLE, &dev); + bma4_error_codes_print_result("bma4_set_fifo_config status", rslt); + + printf("FIFO is configured in headerless mode\n"); + + rslt = bma456mm_map_interrupt(BMA4_INTR1_MAP, BMA4_FIFO_WM_INT, BMA4_ENABLE, &dev); + bma4_error_codes_print_result("bma4_map_interrupt status", rslt); + + wm_lvl = BMA456MM_FIFO_WATERMARK_LEVEL; + rslt = bma4_set_fifo_wm(wm_lvl, &dev); + bma4_error_codes_print_result("bma4_set_fifo_wm status", rslt); + + while (loop <= 10) + { + rslt = bma456mm_read_int_status(&int_status, &dev); + bma4_error_codes_print_result("bma4_read_int_status", rslt); + + if ((rslt == BMA4_OK) && (int_status & BMA4_FIFO_WM_INT)) + { + printf("\nIteration : %d\n", loop); + + rslt = bma4_get_fifo_wm(&watermark, &dev); + bma4_error_codes_print_result("bma4_get_fifo_wm status", rslt); + + printf("FIFO watermark level : %d\n", watermark); + + rslt = bma4_get_fifo_length(&fifo_length, &dev); + bma4_error_codes_print_result("bma4_get_fifo_length status", rslt); + + printf("FIFO data bytes available : %d\n", fifo_length); + printf("FIFO data bytes requested : %d\n", fifoframe.length); + + /* Read FIFO data */ + rslt = bma4_read_fifo_data(&fifoframe, &dev); + bma4_error_codes_print_result("bma4_read_fifo_data status", rslt); + + accel_length = BMA456MM_FIFO_ACCEL_FRAME_COUNT; + + if (rslt == BMA4_OK) + { + printf("Requested data frames before parsing: %d\n", accel_length); + + /* Parse the FIFO data to extract accelerometer data from the FIFO buffer */ + rslt = bma4_extract_accel(fifo_accel_data, &accel_length, &fifoframe, &dev); + printf("Parsed accelerometer data frames: %d\n", accel_length); + + printf("ACCEL, X, Y, Z\n"); + + /* Print the parsed accelerometer data from the FIFO buffer */ + for (idx = 0; idx < accel_length; idx++) + { + printf("%d, %d, %d, %d\n", + idx, + fifo_accel_data[idx].x, + fifo_accel_data[idx].y, + fifo_accel_data[idx].z); + } + } + + loop++; + } + } + + bma4_coines_deinit(); + + return rslt; +} diff --git a/components/bma456/bma456mm_examples/high_g/Makefile b/components/bma456/bma456mm_examples/high_g/Makefile new file mode 100644 index 0000000..459e964 --- /dev/null +++ b/components/bma456/bma456mm_examples/high_g/Makefile @@ -0,0 +1,18 @@ +COINES_INSTALL_PATH ?= ../../../.. + +EXAMPLE_FILE ?= high_g.c + +API_LOCATION ?= ../.. + +COMMON_LOCATION ?= .. + +C_SRCS += \ +$(API_LOCATION)/bma4.c \ +$(API_LOCATION)/bma456mm.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/components/bma456/bma456mm_examples/high_g/high_g.c b/components/bma456/bma456mm_examples/high_g/high_g.c new file mode 100644 index 0000000..b6c05b3 --- /dev/null +++ b/components/bma456/bma456mm_examples/high_g/high_g.c @@ -0,0 +1,130 @@ +/**\ + * Copyright (c) 2022 Bosch Sensortec GmbH. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + **/ + +#include +#include "bma456mm.h" +#include "common.h" + +/******************************************************************************/ +/*! Function */ + +/* This function starts the execution of program. */ +int main(void) +{ + /* Variable to store the status of API */ + int8_t rslt; + + /* Sensor initialization configuration */ + struct bma4_dev bma = { 0 }; + + struct bma456mm_high_g_config high_g = { 0 }; + struct bma456mm_out_state out_state; + + /* Variable to store high-g interrupt status */ + uint16_t int_status = 0; + + /* Interface reference is given as a parameter + * For I2C : BMA4_I2C_INTF + * For SPI : BMA4_SPI_INTF + * Variant information given as parameter - BMA45X_VARIANT + */ + rslt = bma4_interface_init(&bma, BMA4_I2C_INTF, BMA45X_VARIANT); + bma4_error_codes_print_result("bma4_interface_init", rslt); + + /* Sensor initialization */ + rslt = bma456mm_init(&bma); + bma4_error_codes_print_result("bma456mm_init status", rslt); + + /* Upload the configuration file to enable the features of the sensor. */ + rslt = bma456mm_write_config_file(&bma); + bma4_error_codes_print_result("bma456mm_write_config status", rslt); + + /* Enable the accelerometer */ + rslt = bma4_set_accel_enable(BMA4_ENABLE, &bma); + bma4_error_codes_print_result("bma4_set_accel_enable status", rslt); + + printf("High-g functionality test\n\n"); + + if (rslt == BMA4_OK) + { + /* Map the interrupt pin 1 for high-g */ + rslt = bma456mm_map_interrupt(BMA4_INTR1_MAP, BMA456MM_HIGH_G_INT, BMA4_ENABLE, &bma); + bma4_error_codes_print_result("bma456mm_map_interrupt status", rslt); + + if (rslt == BMA4_OK) + { + /* Enabling high-g feature */ + rslt = bma456mm_feature_enable(BMA456MM_HIGH_G, BMA4_ENABLE, &bma); + bma4_error_codes_print_result("bma456mm_feature_enable status", rslt); + } + + if (rslt == BMA4_OK) + { + printf("High_g enabled for all axis\n"); + + rslt = bma456mm_get_high_g_config(&high_g, &bma); + bma4_error_codes_print_result("bma456mm_get_high_g_config status", rslt); + + high_g.axes_en = BMA456MM_HIGH_G_EN_ALL_AXIS; + rslt = bma456mm_set_high_g_config(&high_g, &bma); + bma4_error_codes_print_result("bma456mm_get_high_g_config status", rslt); + } + + if (rslt == BMA4_OK) + { + printf("\nMove the board upwards for high-g interrupt\n"); + + for (;;) + { + /* Read the interrupt status */ + rslt = bma456mm_read_int_status(&int_status, &bma); + bma4_error_codes_print_result("bma456mm_read_int_status", rslt); + + /* Check if high-g interrupt is received */ + if ((rslt == BMA4_OK) && (int_status & BMA456MM_HIGH_G_INT)) + { + printf("\nReceived high-g interrupt\n"); + + rslt = bma456mm_output_state(&out_state, &bma); + bma4_error_codes_print_result("bma456mm_orientation_output", rslt); + + if (out_state.high_g_detect_x) + { + printf("High-g detected in x-axis\n"); + } + + if (out_state.high_g_detect_y) + { + printf("High-g detected in y-axis\n"); + } + + if (out_state.high_g_detect_z) + { + printf("High-g detected in z-axis\n"); + } + + if (out_state.high_g_detect_sign == BMA4_ENABLE) + { + printf("High-g detected in negative axis\n"); + } + + if (out_state.high_g_detect_sign == BMA4_DISABLE) + { + printf("High-g detected in positive axis\n"); + } + + break; + } + + int_status = 0; + } + } + } + + bma4_coines_deinit(); + + return rslt; +} diff --git a/components/bma456/bma456mm_examples/low_g/Makefile b/components/bma456/bma456mm_examples/low_g/Makefile new file mode 100644 index 0000000..36770cd --- /dev/null +++ b/components/bma456/bma456mm_examples/low_g/Makefile @@ -0,0 +1,18 @@ +COINES_INSTALL_PATH ?= ../../../.. + +EXAMPLE_FILE ?= low_g.c + +API_LOCATION ?= ../.. + +COMMON_LOCATION ?= .. + +C_SRCS += \ +$(API_LOCATION)/bma4.c \ +$(API_LOCATION)/bma456mm.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/components/bma456/bma456mm_examples/low_g/low_g.c b/components/bma456/bma456mm_examples/low_g/low_g.c new file mode 100644 index 0000000..bbe4906 --- /dev/null +++ b/components/bma456/bma456mm_examples/low_g/low_g.c @@ -0,0 +1,94 @@ +/**\ + * Copyright (c) 2022 Bosch Sensortec GmbH. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + **/ + +#include +#include "bma456mm.h" +#include "common.h" + +/******************************************************************************/ +/*! Function */ + +/* This function starts the execution of program. */ +int main(void) +{ + /* Variable to store the status of API */ + int8_t rslt; + + /* Sensor initialization configuration */ + struct bma4_dev bma = { 0 }; + + /* Variable to store step activity interrupt status */ + uint16_t int_status = 0; + + struct bma456mm_low_g_config low_g = { 0 }; + struct bma456mm_low_g_config get_low_g = { 0 }; + + /* Interface reference is given as a parameter + * For I2C : BMA4_I2C_INTF + * For SPI : BMA4_SPI_INTF + * Variant information given as parameter - BMA45X_VARIANT + */ + rslt = bma4_interface_init(&bma, BMA4_I2C_INTF, BMA45X_VARIANT); + bma4_error_codes_print_result("bma4_interface_init", rslt); + + /* Sensor initialization */ + rslt = bma456mm_init(&bma); + bma4_error_codes_print_result("bma456mm_init status", rslt); + + /* Upload the configuration file to enable the features of the sensor. */ + rslt = bma456mm_write_config_file(&bma); + bma4_error_codes_print_result("bma456mm_write_config status", rslt); + + /* Enable the accelerometer */ + rslt = bma4_set_accel_enable(BMA4_ENABLE, &bma); + bma4_error_codes_print_result("bma4_set_accel_enable status", rslt); + + low_g.threshold = 0x133; + + rslt = bma456mm_set_low_g_config(&low_g, &bma); + bma4_error_codes_print_result("bma456mm_feature_enable status", rslt); + + rslt = bma456mm_get_low_g_config(&get_low_g, &bma); + bma4_error_codes_print_result("bma456mm_feature_enable status", rslt); + + printf("Low-g Threshold : 0x%x\n\n", get_low_g.threshold); + + /* Enable orientation feature */ + rslt = bma456mm_feature_enable(BMA456MM_LOW_G, 1, &bma); + bma4_error_codes_print_result("bma456mm_feature_enable status", rslt); + + if (rslt == BMA4_OK) + { + /* Map the interrupt 1 for tap detection */ + rslt = bma456mm_map_interrupt(BMA4_INTR1_MAP, BMA456MM_LOW_G_INT, BMA4_ENABLE, &bma); + bma4_error_codes_print_result("bma456mm_map_interrupt status", rslt); + + if (rslt == BMA4_OK) + { + printf("Drop the board for low-g\n"); + + for (;;) + { + /* Read interrupt status */ + rslt = bma456mm_read_int_status(&int_status, &bma); + bma4_error_codes_print_result("bma456mm_read_int_status", rslt); + + /* Filtering only the activity interrupt */ + if ((rslt == BMA4_OK) && (int_status & BMA456MM_LOW_G_INT)) + { + printf("\nLow-g interrupt occurred\n"); + break; + } + + int_status = 0; + } + } + } + + bma4_coines_deinit(); + + return rslt; +} diff --git a/components/bma456/bma456mm_examples/motion/Makefile b/components/bma456/bma456mm_examples/motion/Makefile new file mode 100644 index 0000000..3ce678c --- /dev/null +++ b/components/bma456/bma456mm_examples/motion/Makefile @@ -0,0 +1,18 @@ +COINES_INSTALL_PATH ?= ../../../.. + +EXAMPLE_FILE ?= motion.c + +API_LOCATION ?= ../.. + +COMMON_LOCATION ?= .. + +C_SRCS += \ +$(API_LOCATION)/bma4.c \ +$(API_LOCATION)/bma456mm.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/components/bma456/bma456mm_examples/motion/motion.c b/components/bma456/bma456mm_examples/motion/motion.c new file mode 100644 index 0000000..edddc41 --- /dev/null +++ b/components/bma456/bma456mm_examples/motion/motion.c @@ -0,0 +1,188 @@ +/**\ + * Copyright (c) 2022 Bosch Sensortec GmbH. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + **/ + +#include +#include "bma456mm.h" +#include "common.h" + +/*****************************************************************************/ +/*! Global variable */ + +/*! Structure to define any/no-motion configurations */ +struct bma456mm_any_no_mot_config any_no_mot = { 0 }; + +/******************************************************************************/ +/*! Static Function Declaration */ + +/*! + * @brief This internal API is used to get any/no-motion configurations. + * + * @param[in] bma : Structure instance of bma4_dev. + * + * @return Status of execution. + */ +static int8_t get_any_no_mot_config(struct bma4_dev *bma); + +/******************************************************************************/ +/*! Functions */ + +/* This function starts the execution of program. */ +int main(void) +{ + /* Variable to store the status of API */ + int8_t rslt; + + /* Sensor initialization configuration */ + struct bma4_dev bma = { 0 }; + + /* Variable to store any/no-motion interrupt status */ + uint16_t int_status = 0; + + uint8_t iteration = 20; + + /* Interface reference is given as a parameter + * For I2C : BMA4_I2C_INTF + * For SPI : BMA4_SPI_INTF + * Variant information given as parameter - BMA45X_VARIANT + */ + rslt = bma4_interface_init(&bma, BMA4_I2C_INTF, BMA45X_VARIANT); + bma4_error_codes_print_result("bma4_interface_init", rslt); + + /* Sensor initialization */ + rslt = bma456mm_init(&bma); + bma4_error_codes_print_result("bma456mm_init status", rslt); + + /* Upload the configuration file to enable the features of the sensor. */ + rslt = bma456mm_write_config_file(&bma); + bma4_error_codes_print_result("bma456mm_write_config status", rslt); + + /* Enable the accelerometer */ + rslt = bma4_set_accel_enable(BMA4_ENABLE, &bma); + bma4_error_codes_print_result("bma4_set_accel_enable status", rslt); + + /* Map the interrupt pin 1 for any/no-motion */ + rslt = bma456mm_map_interrupt(BMA4_INTR1_MAP, (BMA456MM_ANY_MOT_INT | BMA456MM_NO_MOT_INT), BMA4_ENABLE, &bma); + bma4_error_codes_print_result("bma456mm_map_interrupt status", rslt); + + /* Get any-motion and no-motion configurations */ + rslt = get_any_no_mot_config(&bma); + bma4_error_codes_print_result("get_any_no_mot_config status", rslt); + + printf("Shake the board for any-motion interrupt whereas do not shake the board for no-motion interrupt\n"); + + if (rslt == BMA4_OK) + { + for (;;) + { + /* Read interrupt status */ + rslt = bma456mm_read_int_status(&int_status, &bma); + bma4_error_codes_print_result("bma456mm_read_int_status", rslt); + + if (rslt == BMA4_OK) + { + /* Enters only if the obtained interrupt is any-motion */ + if (int_status & BMA456MM_ANY_MOT_INT) + { + printf("Any-motion interrupt occurred\n"); + iteration--; + } + + /* Enters only if the obtained interrupt is no-motion */ + else if (int_status & BMA456MM_NO_MOT_INT) + { + printf("No-motion interrupt occurred\n"); + iteration--; + } + + int_status = 0; + + /* Break out of the loop when iteration has reached zero */ + if (iteration == 0) + { + printf("Iterations are done. Exiting !\n\n"); + break; + } + } + } + } + + bma4_coines_deinit(); + + return rslt; +} + +/*! + * @brief This internal API is used to get any/no-motion configurations. + */ +static int8_t get_any_no_mot_config(struct bma4_dev *bma) +{ + /* Variable to store the status of API */ + int8_t rslt; + + /* Getting any-motion configuration to get default configuration */ + rslt = bma456mm_get_any_mot_config(&any_no_mot, bma); + bma4_error_codes_print_result("bma456mm_get_any_mot_config status", rslt); + + if (rslt == BMA4_OK) + { + /* Select the axis for which any/no motion interrupt should be generated */ + any_no_mot.axes_en = BMA456MM_EN_ALL_AXIS; + + /* + * Set the slope threshold: + * Interrupt will be generated if the slope of all the axis exceeds the threshold (1 bit = 0.48mG) + */ + any_no_mot.threshold = 10; + + /* + * Set the duration for any-motion interrupt: + * Duration defines the number of consecutive data points for which threshold condition must be true(1 + * bit = + * 20ms) + */ + any_no_mot.duration = 4; + + /* Like threshold and duration, we can also change the config of int_bhvr and slope */ + + /* Set the threshold and duration configuration */ + rslt = bma456mm_set_any_mot_config(&any_no_mot, bma); + bma4_error_codes_print_result("bma456mm_set_any_mot_config status", rslt); + + if (rslt == BMA4_OK) + { + /* Getting no-motion configuration to get default configuration */ + rslt = bma456mm_get_no_mot_config(&any_no_mot, bma); + bma4_error_codes_print_result("bma456mm_get_no_mot_config status", rslt); + + if (rslt == BMA4_OK) + { + /* Select the axis for which any/no motion interrupt should be generated */ + any_no_mot.axes_en = BMA456MM_EN_ALL_AXIS; + + /* + * Set the slope threshold: + * Interrupt will be generated if the slope of all the axis exceeds the threshold (1 bit = 0.48mG) + */ + any_no_mot.threshold = 10; + + /* + * Set the duration for no-motion interrupt: + * Duration defines the number of consecutive data points for which threshold condition must be + * true(1 bit = 20ms) + */ + any_no_mot.duration = 4; + + /* Like threshold and duration, we can also change the config of int_bhvr */ + + /* Set the threshold and duration configuration */ + rslt = bma456mm_set_no_mot_config(&any_no_mot, bma); + bma4_error_codes_print_result("bma456mm_set_no_mot_config status", rslt); + } + } + } + + return rslt; +} diff --git a/components/bma456/bma456mm_examples/orient/Makefile b/components/bma456/bma456mm_examples/orient/Makefile new file mode 100644 index 0000000..cc48c12 --- /dev/null +++ b/components/bma456/bma456mm_examples/orient/Makefile @@ -0,0 +1,18 @@ +COINES_INSTALL_PATH ?= ../../../.. + +EXAMPLE_FILE ?= orient.c + +API_LOCATION ?= ../.. + +COMMON_LOCATION ?= .. + +C_SRCS += \ +$(API_LOCATION)/bma4.c \ +$(API_LOCATION)/bma456mm.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/components/bma456/bma456mm_examples/orient/orient.c b/components/bma456/bma456mm_examples/orient/orient.c new file mode 100644 index 0000000..4dee862 --- /dev/null +++ b/components/bma456/bma456mm_examples/orient/orient.c @@ -0,0 +1,133 @@ +/**\ + * Copyright (c) 2022 Bosch Sensortec GmbH. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + **/ + +#include +#include "bma456mm.h" +#include "common.h" + +/******************************************************************************/ +/*! Function */ + +/* This function starts the execution of program. */ +int main(void) +{ + /* Variable to store the status of API */ + int8_t rslt; + + /* Sensor initialization configuration */ + struct bma4_dev bma = { 0 }; + + /* Variable to store step activity interrupt status */ + uint16_t int_status = 0; + + /* Structure to hold orientation configuration */ + struct bma456mm_orientation_config orient; + struct bma456mm_out_state out_state; + + /* Interface reference is given as a parameter + * For I2C : BMA4_I2C_INTF + * For SPI : BMA4_SPI_INTF + * Variant information given as parameter - BMA45X_VARIANT + */ + rslt = bma4_interface_init(&bma, BMA4_I2C_INTF, BMA45X_VARIANT); + bma4_error_codes_print_result("bma4_interface_init", rslt); + + /* Sensor initialization */ + rslt = bma456mm_init(&bma); + bma4_error_codes_print_result("bma456mm_init status", rslt); + + /* Upload the configuration file to enable the features of the sensor. */ + rslt = bma456mm_write_config_file(&bma); + bma4_error_codes_print_result("bma456mm_write_config status", rslt); + + /* Enable the accelerometer */ + rslt = bma4_set_accel_enable(BMA4_ENABLE, &bma); + bma4_error_codes_print_result("bma4_set_accel_enable status", rslt); + + /* Enable orientation feature */ + rslt = bma456mm_feature_enable(BMA456MM_ORIENT, 1, &bma); + bma4_error_codes_print_result("bma456mm_feature_enable status", rslt); + + orient.upside_down = 0x01; + orient.mode = 0x02; + orient.blocking = 0x01; + orient.theta = 0x33; + orient.hysteresis = 0x80; + + rslt = bma456mm_set_orientation_config(&orient, &bma); + bma4_error_codes_print_result("bma456mm_set_orientation_config status", rslt); + + if (rslt == BMA4_OK) + { + /* Map the interrupt 1 for tap detection */ + rslt = bma456mm_map_interrupt(BMA4_INTR1_MAP, BMA456MM_ORIENT_INT, BMA4_ENABLE, &bma); + bma4_error_codes_print_result("bma456mm_map_interrupt status", rslt); + + if (rslt == BMA4_OK) + { + printf("Move the board to detect orientation\n"); + + for (;;) + { + int_status = 0; + + /* Read interrupt status */ + rslt = bma456mm_read_int_status(&int_status, &bma); + bma4_error_codes_print_result("bma456mm_read_int_status", rslt); + + /* Filtering only the activity interrupt */ + if ((rslt == BMA4_OK) && (int_status & BMA456MM_ORIENT_INT)) + { + printf("\nOrientation interrupt occurred\n"); + + rslt = bma456mm_output_state(&out_state, &bma); + bma4_error_codes_print_result("bma456mm_orientation_output", rslt); + + printf("The Orientation output is %d\n", out_state.orientation_out); + printf("The Orientation faceup/down output is %d\n", out_state.orientation_faceup_down); + + switch (out_state.orientation_faceup_down) + { + case BMA456MM_FACE_UP: + printf("\nOrientation state is face up\n"); + break; + case BMA456MM_FACE_DOWN: + printf("\nOrientation state is face down\n"); + break; + + default: + break; + } + + switch (out_state.orientation_out) + { + case BMA456MM_LANDSCAPE_LEFT: + printf("\nOrientation state is landscape left\n\n"); + break; + case BMA456MM_LANDSCAPE_RIGHT: + printf("\nOrientation state is landscape right\n\n"); + break; + case BMA456MM_PORTRAIT_UP_DOWN: + printf("\nOrientation state is portrait upside down\n\n"); + break; + case BMA456MM_PORTRAIT_UP_RIGHT: + printf("\nOrientation state is portrait upright\n\n"); + break; + + default: + break; + } + + break; + } + } + } + } + + bma4_coines_deinit(); + + return rslt; +} diff --git a/components/bma456/bma456mm_examples/sig_motion/Makefile b/components/bma456/bma456mm_examples/sig_motion/Makefile new file mode 100644 index 0000000..844902c --- /dev/null +++ b/components/bma456/bma456mm_examples/sig_motion/Makefile @@ -0,0 +1,18 @@ +COINES_INSTALL_PATH ?= ../../../.. + +EXAMPLE_FILE ?= sig_motion.c + +API_LOCATION ?= ../.. + +COMMON_LOCATION ?= .. + +C_SRCS += \ +$(API_LOCATION)/bma4.c \ +$(API_LOCATION)/bma456mm.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/components/bma456/bma456mm_examples/sig_motion/sig_motion.c b/components/bma456/bma456mm_examples/sig_motion/sig_motion.c new file mode 100644 index 0000000..621a769 --- /dev/null +++ b/components/bma456/bma456mm_examples/sig_motion/sig_motion.c @@ -0,0 +1,84 @@ +/**\ + * Copyright (c) 2022 Bosch Sensortec GmbH. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + **/ + +#include +#include "bma456mm.h" +#include "common.h" + +/******************************************************************************/ +/*! Function */ + +/* This function starts the execution of program. */ +int main(void) +{ + /* Variable to store the status of API */ + int8_t rslt; + + /* Sensor initialization configuration */ + struct bma4_dev bma = { 0 }; + + /* Variable to store sig-motion interrupt status */ + uint16_t int_status = 0; + + /* Interface reference is given as a parameter + * For I2C : BMA4_I2C_INTF + * For SPI : BMA4_SPI_INTF + * Variant information given as parameter - BMA45X_VARIANT + */ + rslt = bma4_interface_init(&bma, BMA4_I2C_INTF, BMA45X_VARIANT); + bma4_error_codes_print_result("bma4_interface_init", rslt); + + /* Sensor initialization */ + rslt = bma456mm_init(&bma); + bma4_error_codes_print_result("bma456mm_init status", rslt); + + /* Upload the configuration file to enable the features of the sensor. */ + rslt = bma456mm_write_config_file(&bma); + bma4_error_codes_print_result("bma456mm_write_config status", rslt); + + /* Enable the accelerometer */ + rslt = bma4_set_accel_enable(BMA4_ENABLE, &bma); + bma4_error_codes_print_result("bma4_set_accel_enable status", rslt); + + if (rslt == BMA4_OK) + { + /* Map the interrupt pin 1 for sig-motion */ + rslt = bma456mm_map_interrupt(BMA4_INTR1_MAP, BMA456MM_SIG_MOT_INT, BMA4_ENABLE, &bma); + bma4_error_codes_print_result("bma456mm_map_interrupt status", rslt); + + if (rslt == BMA4_OK) + { + /* Enabling sig-motion feature */ + rslt = bma456mm_feature_enable(BMA456MM_SIG_MOTION, BMA4_ENABLE, &bma); + bma4_error_codes_print_result("bma456mm_feature_enable status", rslt); + } + + if (rslt == BMA4_OK) + { + printf("Shake the sensor for greater than 3 sec to detect sig-motion interrupt\n"); + + for (;;) + { + /* Read the interrupt status */ + rslt = bma456mm_read_int_status(&int_status, &bma); + bma4_error_codes_print_result("bma456mm_read_int_status", rslt); + + /* Check if sig-motion interrupt is received */ + if ((rslt == BMA4_OK) && (int_status & BMA456MM_SIG_MOT_INT)) + { + printf("\nReceived Sig-motion interrupt\n"); + break; + } + + int_status = 0; + } + } + } + + bma4_coines_deinit(); + + return rslt; +} diff --git a/components/bma456/bma456mm_examples/tap/Makefile b/components/bma456/bma456mm_examples/tap/Makefile new file mode 100644 index 0000000..e357d88 --- /dev/null +++ b/components/bma456/bma456mm_examples/tap/Makefile @@ -0,0 +1,18 @@ +COINES_INSTALL_PATH ?= ../../../.. + +EXAMPLE_FILE ?= tap.c + +API_LOCATION ?= ../.. + +COMMON_LOCATION ?= .. + +C_SRCS += \ +$(API_LOCATION)/bma4.c \ +$(API_LOCATION)/bma456mm.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/components/bma456/bma456mm_examples/tap/tap.c b/components/bma456/bma456mm_examples/tap/tap.c new file mode 100644 index 0000000..fafa525 --- /dev/null +++ b/components/bma456/bma456mm_examples/tap/tap.c @@ -0,0 +1,125 @@ +/**\ + * Copyright (c) 2022 Bosch Sensortec GmbH. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + **/ + +#include +#include "bma456mm.h" +#include "common.h" + +/******************************************************************************/ +/*! Function */ + +/* This function starts the execution of program. */ +int main(void) +{ + /* Variable to store the status of API */ + int8_t rslt; + + /* Sensor initialization configuration */ + struct bma4_dev bma = { 0 }; + + /* Variable to store tap interrupt status */ + uint16_t int_status = 0; + + /* Loop variable */ + uint8_t loop = 10; + + struct bma456mm_out_state tap_out = { 0 }; + struct bma456mm_multitap_settings settings = { 0 }; + + /* Interface reference is given as a parameter + * For I2C : BMA4_I2C_INTF + * For SPI : BMA4_SPI_INTF + * Variant information given as parameter - BMA45X_VARIANT + */ + rslt = bma4_interface_init(&bma, BMA4_I2C_INTF, BMA45X_VARIANT); + bma4_error_codes_print_result("bma4_interface_init", rslt); + + /* Sensor initialization */ + rslt = bma456mm_init(&bma); + bma4_error_codes_print_result("bma456mm_init status", rslt); + + /* Upload the configuration file to enable the features of the sensor. */ + rslt = bma456mm_write_config_file(&bma); + bma4_error_codes_print_result("bma456mm_write_config status", rslt); + + /* Enable the accelerometer */ + rslt = bma4_set_accel_enable(BMA4_ENABLE, &bma); + bma4_error_codes_print_result("bma4_set_accel_enable status", rslt); + + if (rslt == BMA4_OK) + { + /* Map the interrupt pin 1 for tap detection */ + rslt = bma456mm_map_interrupt(BMA4_INTR1_MAP, BMA456MM_TAP_OUT_INT, BMA4_ENABLE, &bma); + bma4_error_codes_print_result("bma456mm_map_interrupt status", rslt); + + if (rslt == BMA4_OK) + { + /* Enabling the single, double and triple tap features */ + rslt = bma456mm_feature_enable((BMA456MM_SINGLE_TAP | BMA456MM_DOUBLE_TAP | BMA456MM_TRIPLE_TAP), + BMA4_ENABLE, + &bma); + bma4_error_codes_print_result("bma456mm_feature_enable status", rslt); + + if (rslt == BMA4_OK) + { + /* Getting tap parameters settings */ + rslt = bma456mm_tap_get_parameter(&settings, &bma); + bma4_error_codes_print_result("bma456mm_tap_get_parameter status", rslt); + } + } + + if (rslt == BMA4_OK) + { + printf("Tap the board either single, double or triple tap\n"); + + while (loop > 0) + { + /* Read interrupt status */ + rslt = bma456mm_read_int_status(&int_status, &bma); + bma4_error_codes_print_result("bma456mm_read_int_status", rslt); + + /* Filtering only the tap interrupt */ + if ((rslt == BMA4_OK) && (int_status & BMA456MM_TAP_OUT_INT)) + { + rslt = bma456mm_output_state(&tap_out, &bma); + + if (BMA4_OK == rslt) + { + /* Enters only if the obtained interrupt is single-tap */ + if (tap_out.s_tap) + { + printf("Single Tap interrupt occurred\n"); + } + /* Enters only if the obtained interrupt is double-tap */ + else if (tap_out.d_tap) + { + printf("Double Tap interrupt occurred\n"); + } + /* Enters only if the obtained interrupt is triple-tap */ + else if (tap_out.t_tap) + { + printf("Triple Tap interrupt occurred\n"); + } + + loop--; + } + + int_status = 0; + } + } + + /* Break out of the loop when iteration has reached zero */ + if (loop == 0) + { + printf("Iterations are done. Exiting !\n\n"); + } + } + } + + bma4_coines_deinit(); + + return rslt; +} diff --git a/components/bma456/bma456w.c b/components/bma456/bma456w.c new file mode 100644 index 0000000..1fbfdbd --- /dev/null +++ b/components/bma456/bma456w.c @@ -0,0 +1,1545 @@ +/** +* 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. +* +* @file bma456w.c +* @date 2023-07-05 +* @version V2.29.0 +* +*/ + +/*! \file bma456w.c + * \brief Sensor Driver for BMA456W sensor + */ + +#include "bma456w.h" + +/**\name Feature configuration file */ +const uint8_t bma456w_config_file[] = { + 0x80, 0x2e, 0xf0, 0x01, 0x80, 0x2e, 0xf2, 0x01, 0xc8, 0x2e, 0x00, 0x2e, 0x80, 0x2e, 0xff, 0x00, 0x80, 0x2e, 0xfe, + 0x00, 0x80, 0x2e, 0xf1, 0x01, 0x80, 0x2e, 0xef, 0x01, 0x80, 0x2e, 0x92, 0xb0, 0x80, 0x2e, 0xb6, 0x09, 0xb0, 0xf0, + 0x10, 0x30, 0x21, 0x2e, 0x16, 0xf0, 0x80, 0x2e, 0xf3, 0x01, 0x71, 0x50, 0x6f, 0x52, 0x01, 0x42, 0x3b, 0x80, 0x41, + 0x30, 0x01, 0x42, 0x3c, 0x80, 0x00, 0x2e, 0x01, 0x40, 0x01, 0x42, 0x21, 0x2e, 0xff, 0xaf, 0xb8, 0x2e, 0x22, 0xeb, + 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, + 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, + 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, + 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, + 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0xfd, 0x2d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x03, 0x00, 0x03, 0x00, 0x04, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x1e, 0x01, 0x01, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x01, 0x2e, 0x55, 0xf0, 0xc0, 0x2e, 0x21, 0x2e, 0x55, 0xf0, 0x30, 0x50, 0x00, 0x30, 0x67, 0x56, 0x05, 0x30, + 0x05, 0x2c, 0xfb, 0x7f, 0x3e, 0xbe, 0xd2, 0xba, 0xb2, 0xb9, 0x6c, 0x0b, 0x53, 0x0e, 0xf9, 0x2f, 0x53, 0x1a, 0x01, + 0x2f, 0x4d, 0x0e, 0xf5, 0x2f, 0xd2, 0x7f, 0x04, 0x30, 0x1f, 0x2c, 0xe1, 0x7f, 0xc5, 0x01, 0xa3, 0x03, 0x72, 0x0e, + 0x03, 0x2f, 0x72, 0x1a, 0x0f, 0x2f, 0x79, 0x0f, 0x0d, 0x2f, 0xe1, 0x6f, 0x4f, 0x04, 0x5f, 0xb9, 0xb1, 0xbf, 0xfa, + 0x0b, 0xd2, 0x6f, 0x96, 0x06, 0xb1, 0x25, 0x51, 0xbf, 0xeb, 0x7f, 0x06, 0x00, 0xb2, 0x25, 0x27, 0x03, 0xdb, 0x7f, + 0xcf, 0xbf, 0x3e, 0xbf, 0x01, 0xb8, 0xd2, 0xba, 0x41, 0xba, 0xb2, 0xb9, 0x07, 0x0a, 0x6e, 0x0b, 0xc0, 0x90, 0xdf, + 0x2f, 0x40, 0x91, 0xdd, 0x2f, 0xfb, 0x6f, 0xd0, 0x5f, 0xb8, 0x2e, 0x10, 0x50, 0xfb, 0x7f, 0x21, 0x25, 0x98, 0x2e, + 0xe5, 0x01, 0xfb, 0x6f, 0x21, 0x25, 0xf0, 0x5f, 0x10, 0x25, 0x80, 0x2e, 0xba, 0x00, 0xc8, 0x2e, 0xc8, 0x2e, 0xaa, + 0x00, 0x05, 0x00, 0xaa, 0x00, 0x05, 0x00, 0x2d, 0x01, 0xd4, 0x7b, 0x3b, 0x01, 0xdb, 0x7a, 0x04, 0x00, 0x3f, 0x7b, + 0xcd, 0x6c, 0xc3, 0x04, 0x85, 0x09, 0xc3, 0x04, 0xec, 0xe6, 0x0c, 0x46, 0x01, 0x00, 0x27, 0x00, 0x19, 0x00, 0x96, + 0x00, 0xa0, 0x00, 0x01, 0x00, 0x0c, 0x00, 0xf0, 0x3c, 0x00, 0x01, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x0e, 0x00, + 0x00, 0x00, 0x04, 0x00, 0xee, 0x06, 0xf2, 0x05, 0x80, 0x80, 0x16, 0xf1, 0x02, 0x02, 0x48, 0x20, 0x88, 0x00, 0x74, + 0x00, 0x00, 0x01, 0x7d, 0x00, 0x02, 0x01, 0x51, 0x00, 0xaf, 0x00, 0xff, 0x00, 0xec, 0x00, 0xff, 0xb7, 0x00, 0x02, + 0x00, 0xb0, 0x05, 0x80, 0xc9, 0xf0, 0x00, 0x40, 0xff, 0x7f, 0x00, 0x80, 0x88, 0x00, 0x80, 0x00, 0x5e, 0xf0, 0x59, + 0xf0, 0x89, 0xf0, 0x54, 0x00, 0x00, 0x20, 0x56, 0xf0, 0x5f, 0x00, 0x55, 0x00, 0x5a, 0x00, 0x58, 0x00, 0xff, 0xfb, + 0x52, 0xf0, 0x33, 0x09, 0x33, 0x07, 0x00, 0x08, 0x90, 0x01, 0x00, 0xf8, 0x01, 0x80, 0x86, 0x00, 0xff, 0x1f, 0xa9, + 0x36, 0xab, 0x04, 0x1d, 0x6c, 0xad, 0x00, 0x59, 0x01, 0x31, 0xd1, 0x71, 0x7d, 0xe4, 0x0c, 0x12, 0x02, 0xb3, 0x00, + 0xb4, 0x04, 0x62, 0x03, 0xc0, 0x02, 0x1f, 0xf8, 0xe1, 0x07, 0xd3, 0x07, 0x01, 0xe0, 0x8d, 0x00, 0x97, 0x00, 0x99, + 0x00, 0x91, 0x00, 0x90, 0x00, 0x93, 0x00, 0x8c, 0x00, 0x96, 0x00, 0xb5, 0x00, 0x65, 0x52, 0x57, 0x50, 0x60, 0x42, + 0x00, 0x3f, 0x59, 0x54, 0x42, 0x42, 0x69, 0x82, 0x5b, 0x54, 0x42, 0x42, 0x42, 0x82, 0x0b, 0x31, 0x42, 0x40, 0x10, + 0x08, 0x50, 0x42, 0x7e, 0x80, 0x4b, 0x42, 0x61, 0x32, 0x01, 0x42, 0x10, 0x50, 0x03, 0x2e, 0x40, 0xf0, 0x56, 0x90, + 0x08, 0x80, 0xf0, 0x7f, 0x31, 0x30, 0x1f, 0x2f, 0x03, 0x30, 0x63, 0x52, 0x5d, 0x54, 0x14, 0x35, 0x06, 0x30, 0x5f, + 0x50, 0x55, 0x32, 0x1d, 0x1a, 0xe3, 0x22, 0x18, 0x1a, 0x61, 0x58, 0xe3, 0x22, 0x04, 0x30, 0xd5, 0x40, 0xb5, 0x0d, + 0xe1, 0xbe, 0x6f, 0xbb, 0x80, 0x91, 0xa9, 0x0d, 0x01, 0x89, 0xb5, 0x23, 0x10, 0xa1, 0xf7, 0x2f, 0xda, 0x0e, 0x14, + 0x35, 0xeb, 0x2f, 0x01, 0x2e, 0x25, 0x00, 0x70, 0x1a, 0x00, 0x30, 0x21, 0x30, 0x48, 0x22, 0x40, 0xb2, 0x06, 0x2f, + 0x23, 0x2e, 0x59, 0xf0, 0x98, 0x2e, 0xb5, 0x00, 0x00, 0x2e, 0x00, 0x2e, 0xd0, 0x2e, 0xf0, 0x6f, 0x01, 0x31, 0x20, + 0x26, 0x01, 0x42, 0x10, 0x30, 0x21, 0x2e, 0x59, 0xf0, 0x98, 0x2e, 0xb5, 0x00, 0x4d, 0x50, 0x4f, 0x52, 0x98, 0x2e, + 0x07, 0xb4, 0x4d, 0x50, 0x05, 0x84, 0x14, 0x30, 0x51, 0x50, 0x63, 0x30, 0x53, 0x52, 0x94, 0x42, 0x83, 0x42, 0x98, + 0x2e, 0x07, 0xb4, 0x51, 0x50, 0x06, 0x80, 0x71, 0x30, 0x01, 0x42, 0x98, 0x2e, 0x42, 0xb1, 0x00, 0x2e, 0x00, 0x2e, + 0xd0, 0x2e, 0x98, 0x2e, 0x78, 0xb0, 0x01, 0x2e, 0x54, 0x00, 0x00, 0xb2, 0x12, 0x2f, 0x00, 0x30, 0x21, 0x2e, 0x54, + 0x00, 0x55, 0x50, 0x98, 0x2e, 0x38, 0xb0, 0x55, 0x50, 0x98, 0x2e, 0x4d, 0xb1, 0x98, 0x2e, 0xff, 0xb4, 0x55, 0x50, + 0x4d, 0x52, 0x98, 0x2e, 0x18, 0xb4, 0x55, 0x50, 0x51, 0x52, 0x98, 0x2e, 0x18, 0xb4, 0x98, 0x2e, 0xb5, 0x00, 0xe1, + 0x2d, 0x83, 0x86, 0x01, 0x30, 0x00, 0x30, 0x94, 0x40, 0x24, 0x18, 0x06, 0x00, 0x53, 0x0e, 0x4f, 0x02, 0xf9, 0x2f, + 0xb8, 0x2e, 0xc8, 0x2e, 0xc8, 0x2e, 0xc8, 0x2e, 0xc8, 0x2e, 0x1a, 0x24, 0x26, 0x00, 0x80, 0x2e, 0x66, 0x01, 0x80, + 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0xfd, 0x2d, 0x94, 0x01, + 0xdd, 0x03, 0xc0, 0xad, 0x0b, 0x2f, 0xc0, 0xa8, 0x03, 0x2f, 0xc0, 0x90, 0x07, 0x2f, 0x80, 0xa6, 0x05, 0x2f, 0x40, + 0xa9, 0x12, 0x2f, 0x40, 0x91, 0x01, 0x2f, 0x00, 0xab, 0x0e, 0x2f, 0xc0, 0xac, 0x00, 0x30, 0x6b, 0x52, 0x07, 0x2f, + 0xc0, 0xa9, 0x03, 0x2f, 0xc0, 0x91, 0x03, 0x2f, 0x80, 0xa7, 0x01, 0x2f, 0x40, 0xa1, 0x05, 0x2f, 0xc0, 0x2e, 0x17, + 0x25, 0x06, 0x25, 0xc0, 0x2e, 0xf0, 0x3f, 0x69, 0x52, 0xb8, 0x2e, 0x80, 0xa8, 0x03, 0x25, 0x10, 0x2f, 0x80, 0x90, + 0x01, 0x2f, 0x41, 0x0e, 0x0c, 0x2f, 0xf3, 0x3f, 0x18, 0x05, 0x05, 0x30, 0x5d, 0x07, 0x15, 0x0e, 0x03, 0x2f, 0x55, + 0x1a, 0x02, 0x2f, 0xcc, 0x0f, 0x00, 0x2f, 0x58, 0x04, 0x01, 0x25, 0xb8, 0x2e, 0xb8, 0x2e, 0x60, 0x50, 0x03, 0x2e, + 0x25, 0x01, 0xe0, 0x7f, 0xf1, 0x7f, 0xdb, 0x7f, 0x30, 0x30, 0x6d, 0x54, 0x0a, 0x1a, 0x28, 0x2f, 0x1a, 0x25, 0x7a, + 0x82, 0x00, 0x30, 0x43, 0x30, 0x32, 0x30, 0x05, 0x30, 0x04, 0x30, 0xf6, 0x6f, 0xf2, 0x09, 0xfc, 0x13, 0xc2, 0xab, + 0xb3, 0x09, 0xef, 0x23, 0x80, 0xb3, 0xe6, 0x6f, 0xb7, 0x01, 0x00, 0x2e, 0x8b, 0x41, 0x4b, 0x42, 0x03, 0x2f, 0x46, + 0x40, 0x86, 0x17, 0x81, 0x8d, 0x46, 0x42, 0x41, 0x8b, 0x23, 0xbd, 0xb3, 0xbd, 0x03, 0x89, 0x41, 0x82, 0x07, 0x0c, + 0x43, 0xa3, 0xe6, 0x2f, 0xe1, 0x6f, 0xa2, 0x6f, 0x52, 0x42, 0x00, 0x2e, 0xb2, 0x6f, 0x52, 0x42, 0x00, 0x2e, 0xc2, + 0x6f, 0x42, 0x42, 0x03, 0xb2, 0x03, 0x2e, 0x59, 0xf0, 0xf3, 0x3d, 0x02, 0x32, 0x0b, 0x08, 0x8a, 0x0a, 0xdb, 0x6f, + 0x02, 0x22, 0xa0, 0x5f, 0x21, 0x2e, 0x59, 0xf0, 0xb8, 0x2e, 0x07, 0x2e, 0x00, 0xf0, 0x03, 0x2e, 0x00, 0xf0, 0x73, + 0x50, 0x9c, 0xbe, 0x02, 0x40, 0x6f, 0x52, 0xf4, 0x33, 0xdc, 0xba, 0xd9, 0x0f, 0x94, 0x08, 0x06, 0x2f, 0x49, 0xaf, + 0x04, 0x2f, 0x51, 0x0a, 0x02, 0x34, 0x47, 0xa3, 0x8a, 0x0a, 0x91, 0x22, 0x3c, 0x80, 0x25, 0x2e, 0x59, 0xf0, 0x01, + 0x40, 0x01, 0x42, 0xb8, 0x2e, 0x60, 0x50, 0xc3, 0x7f, 0xd4, 0x7f, 0xe7, 0x7f, 0xf6, 0x7f, 0xb2, 0x7f, 0xa5, 0x7f, + 0x36, 0x30, 0x07, 0x2e, 0x01, 0xf0, 0xbe, 0xbd, 0xbe, 0xbb, 0x75, 0x58, 0x77, 0x05, 0x55, 0x56, 0x77, 0x54, 0x27, + 0x41, 0x06, 0x41, 0xf8, 0xbf, 0xbe, 0x0b, 0xb5, 0x11, 0xd6, 0x42, 0x03, 0x89, 0x5a, 0x0e, 0xf6, 0x2f, 0x12, 0x30, + 0x25, 0x2e, 0x54, 0x00, 0x02, 0x31, 0x25, 0x2e, 0xb8, 0xf0, 0xd4, 0x6f, 0xc3, 0x6f, 0xe7, 0x6f, 0xb2, 0x6f, 0xa5, + 0x6f, 0xf6, 0x6f, 0xa0, 0x5f, 0xc8, 0x2e, 0x70, 0x50, 0x42, 0x8e, 0xd4, 0x7f, 0xf6, 0x7f, 0x47, 0x25, 0x1a, 0x18, + 0x79, 0x52, 0xf1, 0x00, 0x64, 0x25, 0x01, 0x30, 0x39, 0x02, 0x94, 0x41, 0x81, 0x41, 0xe2, 0x7f, 0xbe, 0xbb, 0xbd, + 0x8d, 0x02, 0xbd, 0xb5, 0x7f, 0x8e, 0xb5, 0xba, 0x0a, 0xc6, 0x7f, 0xab, 0x7f, 0x51, 0x25, 0x98, 0x2e, 0x00, 0xb0, + 0xd5, 0x6f, 0xe2, 0x6f, 0x2a, 0x18, 0x79, 0x54, 0xb2, 0x01, 0x02, 0x30, 0xc4, 0x6f, 0x7a, 0x03, 0x12, 0x41, 0x74, + 0x25, 0xd0, 0x7f, 0x52, 0xbc, 0xd3, 0x41, 0x6e, 0xba, 0xde, 0xb6, 0x20, 0x0b, 0xc7, 0x7f, 0x91, 0x7f, 0x98, 0x2e, + 0x00, 0xb0, 0xf2, 0x6f, 0xd5, 0x6f, 0xca, 0x16, 0x55, 0x18, 0xdd, 0x18, 0x95, 0x6f, 0xea, 0x18, 0x79, 0x5a, 0x31, + 0x25, 0x75, 0x01, 0x01, 0x30, 0x20, 0x25, 0x39, 0x02, 0x5e, 0xba, 0x82, 0xbc, 0x8e, 0xb6, 0x21, 0x0b, 0x98, 0x2e, + 0x00, 0xb0, 0xe2, 0x6f, 0xb5, 0x6f, 0x2a, 0x18, 0xe0, 0x7f, 0xf1, 0x7f, 0x04, 0x30, 0x79, 0x54, 0xf2, 0x00, 0x7c, + 0x02, 0x85, 0x6f, 0xd0, 0x6f, 0x0d, 0x17, 0x68, 0x18, 0xe0, 0x18, 0x90, 0x6f, 0xc4, 0x6f, 0xc5, 0x18, 0xeb, 0x6f, + 0xb2, 0x01, 0x1b, 0x43, 0x02, 0x30, 0x7a, 0x03, 0xfb, 0x6f, 0x3d, 0x8f, 0x0b, 0x43, 0x3e, 0xba, 0x12, 0xbd, 0x52, + 0xbc, 0x6e, 0xbb, 0xa2, 0x0a, 0x9e, 0xb5, 0xde, 0xb6, 0x30, 0x0b, 0xf7, 0x7f, 0x98, 0x2e, 0x00, 0xb0, 0xf5, 0x6f, + 0x31, 0x25, 0xd1, 0x6f, 0x92, 0x6f, 0xab, 0x6f, 0x50, 0x43, 0x43, 0x43, 0x90, 0x5f, 0x69, 0x56, 0x80, 0x2e, 0x23, + 0xb0, 0x10, 0x50, 0x03, 0x40, 0x19, 0x18, 0x6b, 0x56, 0x19, 0x05, 0x36, 0x25, 0xf7, 0x7f, 0x4a, 0x17, 0x54, 0x18, + 0xec, 0x18, 0x09, 0x17, 0x01, 0x30, 0x0c, 0x07, 0xe2, 0x18, 0xde, 0x00, 0xf2, 0x6f, 0x97, 0x02, 0x67, 0x58, 0xdc, + 0x00, 0x91, 0x02, 0xbf, 0xb8, 0x21, 0xbd, 0x8a, 0x0a, 0xc0, 0x2e, 0x02, 0x42, 0xf0, 0x5f, 0x7b, 0x50, 0x31, 0x30, + 0x23, 0x2e, 0x57, 0x00, 0x02, 0x40, 0x51, 0x0a, 0x21, 0x42, 0x00, 0x2e, 0x01, 0x40, 0x01, 0x42, 0xb8, 0x2e, 0x07, + 0x2e, 0x1d, 0x01, 0x50, 0x25, 0x90, 0x50, 0x32, 0xbc, 0x33, 0xbd, 0x1a, 0x25, 0xb4, 0xbd, 0x79, 0x8e, 0x77, 0x88, + 0x3f, 0xbb, 0xfb, 0x7f, 0x0b, 0x30, 0x8f, 0xb8, 0xaf, 0xb9, 0x8b, 0x7f, 0x40, 0x90, 0xcb, 0x43, 0x0b, 0x43, 0xe1, + 0x7f, 0xd3, 0x7f, 0xc6, 0x7f, 0x03, 0x2f, 0x98, 0x2e, 0x42, 0xb1, 0xe1, 0x6f, 0x0b, 0x30, 0x9e, 0x0a, 0x91, 0x0a, + 0x80, 0xb2, 0x90, 0x2e, 0xf9, 0xb1, 0x01, 0x2e, 0x5c, 0x00, 0x01, 0x90, 0x25, 0x25, 0x0e, 0x2f, 0x7d, 0x52, 0x01, + 0x2e, 0x59, 0x00, 0xb4, 0x7f, 0xa2, 0x7f, 0x98, 0x2e, 0xff, 0xb1, 0x04, 0x30, 0x29, 0x2e, 0x5c, 0x00, 0xe1, 0x6f, + 0xd3, 0x6f, 0xa2, 0x6f, 0xb4, 0x6f, 0x0b, 0x30, 0x01, 0x2e, 0x1d, 0x01, 0x57, 0x25, 0x85, 0xbf, 0x06, 0xbf, 0xff, + 0xbb, 0xc0, 0xb3, 0x66, 0xbb, 0x94, 0xb1, 0xb6, 0x7f, 0x00, 0x2e, 0x7f, 0x5e, 0x87, 0x5c, 0x0d, 0x2f, 0x9b, 0x43, + 0x9b, 0x43, 0x9b, 0x43, 0x8b, 0x43, 0xdb, 0x43, 0xcb, 0x43, 0x00, 0x2e, 0x85, 0x5c, 0x86, 0x09, 0x81, 0x50, 0x2d, + 0x2e, 0x1d, 0x01, 0x1b, 0x42, 0x0b, 0x42, 0xc0, 0xb2, 0x05, 0x2f, 0x7f, 0x50, 0x00, 0x2e, 0x16, 0x40, 0x0b, 0x40, + 0x76, 0x7f, 0x8b, 0x7f, 0xd9, 0x0a, 0x01, 0x2e, 0x59, 0x00, 0x7d, 0x52, 0x83, 0x5c, 0x98, 0x2e, 0x4b, 0xb2, 0x94, + 0x6f, 0x00, 0xb3, 0x0b, 0x2f, 0xc4, 0x6f, 0x00, 0xb3, 0x08, 0x2f, 0x7f, 0x54, 0x81, 0x58, 0x90, 0x40, 0x10, 0x43, + 0x21, 0x30, 0x82, 0x40, 0x02, 0x43, 0x23, 0x2e, 0x5e, 0xf0, 0xd4, 0x6f, 0x00, 0xb3, 0x26, 0x2f, 0x72, 0x6f, 0x84, + 0x6f, 0x87, 0x50, 0xc8, 0xbd, 0xa8, 0xb8, 0x4b, 0x0a, 0x12, 0x42, 0x11, 0x42, 0x14, 0x42, 0xc8, 0xba, 0x7f, 0x52, + 0xc3, 0x6f, 0x52, 0x42, 0x05, 0x42, 0xc0, 0x90, 0x44, 0x42, 0x15, 0x2f, 0x81, 0x52, 0x00, 0x2e, 0x50, 0x40, 0x41, + 0x40, 0x10, 0x04, 0x61, 0x06, 0x40, 0xaa, 0x04, 0x2f, 0x40, 0x90, 0x0b, 0x2f, 0xb1, 0x6f, 0x48, 0x0f, 0x08, 0x2f, + 0xb0, 0x6f, 0x00, 0xb2, 0x05, 0x2f, 0x81, 0x50, 0x21, 0x30, 0x12, 0x42, 0x04, 0x42, 0x23, 0x2e, 0x5e, 0xf0, 0xe4, + 0x6f, 0x00, 0xb3, 0x13, 0x2f, 0x09, 0x2e, 0x57, 0x00, 0x05, 0x2e, 0x58, 0x00, 0x22, 0x1a, 0x0d, 0x2f, 0x7b, 0x58, + 0x25, 0x2e, 0x57, 0x00, 0x22, 0x43, 0x42, 0x30, 0x00, 0x41, 0x00, 0x43, 0x09, 0x89, 0x00, 0x2e, 0x02, 0x43, 0x03, + 0x2d, 0x14, 0x30, 0x29, 0x2e, 0x5c, 0x00, 0xfb, 0x6f, 0x70, 0x5f, 0xb8, 0x2e, 0x09, 0x86, 0x67, 0x54, 0xe4, 0x40, + 0xc3, 0x80, 0x94, 0x04, 0xc3, 0x40, 0x13, 0x05, 0x05, 0x40, 0x25, 0x05, 0x8a, 0x17, 0x73, 0x30, 0x73, 0x09, 0x8c, + 0x17, 0xf3, 0x08, 0xe3, 0x00, 0x4c, 0x82, 0x15, 0x01, 0xb3, 0xb5, 0x53, 0x42, 0x8b, 0x16, 0x43, 0xb6, 0x52, 0x42, + 0x4c, 0x17, 0x54, 0x42, 0x55, 0x42, 0x53, 0x42, 0x52, 0x42, 0x54, 0x42, 0x45, 0x42, 0x6d, 0x82, 0x89, 0x54, 0x52, + 0x42, 0x10, 0x50, 0x8b, 0x54, 0x52, 0x42, 0xfb, 0x7f, 0x22, 0x30, 0x8d, 0x56, 0x43, 0x42, 0x44, 0x82, 0x0b, 0x30, + 0x52, 0x42, 0x5b, 0x42, 0x7c, 0x84, 0x4b, 0x42, 0x35, 0x82, 0x90, 0x80, 0x8b, 0x42, 0x0b, 0x42, 0x35, 0x80, 0x04, + 0x30, 0x0b, 0x42, 0x37, 0x80, 0x15, 0x30, 0x60, 0x25, 0x98, 0x2e, 0x3e, 0xb2, 0x8b, 0x83, 0xfb, 0x6f, 0x65, 0x42, + 0xc0, 0x2e, 0x44, 0x42, 0xf0, 0x5f, 0x05, 0x80, 0x02, 0x30, 0x51, 0x82, 0x02, 0x42, 0x13, 0x30, 0x41, 0x40, 0x4b, + 0x08, 0x8f, 0x54, 0x3e, 0x80, 0x51, 0x14, 0xc0, 0x2e, 0x01, 0x42, 0x00, 0x2e, 0x40, 0x51, 0xd1, 0x7f, 0x12, 0x25, + 0x02, 0x30, 0x42, 0x43, 0x32, 0x30, 0x82, 0x43, 0xc6, 0x7f, 0xe5, 0x7f, 0xb4, 0x7f, 0xa3, 0x7f, 0x90, 0x7f, 0x8b, + 0x7f, 0x98, 0x2e, 0xf3, 0x00, 0xc0, 0x7e, 0x00, 0xac, 0x01, 0x2f, 0x69, 0x50, 0xc0, 0x7e, 0x00, 0x2e, 0x90, 0x6f, + 0x09, 0x8a, 0xd1, 0x6f, 0x75, 0x7f, 0x4c, 0x82, 0x63, 0x41, 0x65, 0x7f, 0x11, 0x7f, 0x00, 0x2e, 0x64, 0x41, 0x44, + 0x85, 0x52, 0x7f, 0x45, 0x7f, 0x00, 0x2e, 0xa6, 0x40, 0x80, 0x40, 0x32, 0x7f, 0x82, 0x8e, 0xc2, 0x6e, 0x45, 0x41, + 0xf0, 0x7f, 0x27, 0x7f, 0x02, 0x7f, 0x98, 0x2e, 0xb9, 0xb0, 0x23, 0x6f, 0xd1, 0x6f, 0xc2, 0x40, 0xf9, 0x86, 0x23, + 0x7f, 0x80, 0xb2, 0xe0, 0x7e, 0x0f, 0x2f, 0x32, 0x6f, 0x64, 0x6f, 0x82, 0x40, 0xf2, 0x7f, 0x50, 0x82, 0x42, 0x6f, + 0x50, 0x6f, 0x73, 0x6f, 0x85, 0x40, 0xc3, 0x40, 0x04, 0x41, 0x06, 0x40, 0xe2, 0x6e, 0x98, 0x2e, 0xb9, 0xb0, 0xe0, + 0x7e, 0xf3, 0x31, 0x10, 0x6f, 0x36, 0x80, 0xe1, 0x6e, 0x02, 0x40, 0x71, 0x7f, 0x51, 0x04, 0x02, 0x30, 0x40, 0xa8, + 0x91, 0x04, 0x4a, 0x22, 0x89, 0x16, 0x93, 0x08, 0x4a, 0x00, 0x95, 0xb4, 0x09, 0x18, 0x8e, 0x16, 0x13, 0x30, 0x93, + 0x08, 0x21, 0x6f, 0x60, 0x7f, 0x4d, 0x86, 0x02, 0x80, 0xb2, 0x00, 0x41, 0x40, 0x21, 0xb5, 0x50, 0x7f, 0x43, 0x7f, + 0x98, 0x2e, 0x28, 0xb1, 0x40, 0x6f, 0x62, 0x6f, 0x55, 0x6f, 0x13, 0x40, 0x84, 0x40, 0x01, 0x40, 0x45, 0x41, 0x42, + 0xbe, 0x1d, 0x18, 0x4c, 0x04, 0x31, 0x0f, 0x04, 0x8a, 0xc0, 0x6f, 0x11, 0x30, 0x02, 0x2f, 0x00, 0x2e, 0x03, 0x2c, + 0x01, 0x42, 0x23, 0x30, 0x03, 0x42, 0x00, 0x2e, 0xd6, 0x6f, 0x44, 0x41, 0x8a, 0x87, 0x76, 0x8b, 0x00, 0xb3, 0x53, + 0x7f, 0x15, 0x2f, 0x04, 0x6f, 0x91, 0x5e, 0x8b, 0x8d, 0xe7, 0x01, 0xc0, 0xa5, 0x84, 0x41, 0x01, 0x2f, 0x00, 0xa1, + 0x03, 0x2f, 0xc0, 0xad, 0x08, 0x2f, 0x00, 0xa5, 0x06, 0x2f, 0xc6, 0x40, 0x81, 0x8d, 0x07, 0x30, 0x3c, 0x05, 0xd6, + 0x42, 0x04, 0x2c, 0xc4, 0x42, 0x02, 0x2c, 0x07, 0x30, 0x07, 0x30, 0x86, 0x86, 0x94, 0x6f, 0xd7, 0x7e, 0x0e, 0x8d, + 0x00, 0x40, 0x74, 0x89, 0xc7, 0x40, 0x02, 0xb2, 0xf9, 0x29, 0x45, 0x41, 0x86, 0x41, 0xbe, 0x80, 0x21, 0x41, 0x75, + 0x23, 0x82, 0x40, 0xc7, 0x42, 0x45, 0x7f, 0x34, 0x7f, 0x20, 0x7f, 0x98, 0x2e, 0x28, 0xb1, 0x31, 0x6f, 0x60, 0x6f, + 0x24, 0x6f, 0x22, 0x40, 0x05, 0x41, 0x43, 0x40, 0x13, 0x01, 0x43, 0x86, 0xac, 0x0f, 0xd1, 0x6f, 0x30, 0x7f, 0x00, + 0x2f, 0x44, 0x42, 0x48, 0x8a, 0x41, 0x88, 0xe1, 0x40, 0x13, 0x7f, 0x04, 0x7f, 0xf5, 0x7e, 0x98, 0x2e, 0x28, 0xb1, + 0x11, 0x6f, 0x60, 0x6f, 0x34, 0x6f, 0x42, 0x40, 0x03, 0x40, 0x9a, 0x04, 0x04, 0x41, 0x43, 0x82, 0xa2, 0x0e, 0x03, + 0x6f, 0x00, 0x2f, 0xc2, 0x42, 0x00, 0x2e, 0x41, 0x40, 0x72, 0x6f, 0x98, 0x2e, 0x28, 0xb1, 0x25, 0x6f, 0x72, 0x6f, + 0x53, 0x41, 0x93, 0x0e, 0xd1, 0x6f, 0x46, 0x80, 0x1b, 0x30, 0x03, 0x30, 0x0c, 0x2f, 0x04, 0x40, 0x00, 0x91, 0x42, + 0x42, 0x08, 0x2f, 0xf6, 0x6e, 0x44, 0x6f, 0x86, 0x41, 0xb4, 0x0e, 0x03, 0x2f, 0x02, 0x88, 0xdb, 0x7e, 0x03, 0x43, + 0x0b, 0x42, 0x46, 0x8d, 0x44, 0x41, 0x47, 0x80, 0x05, 0x6f, 0x94, 0x0f, 0x76, 0x7f, 0x60, 0x7f, 0x02, 0x2f, 0x45, + 0x89, 0x42, 0x43, 0x03, 0x43, 0x49, 0x88, 0xa5, 0x6f, 0x40, 0x91, 0xa4, 0x7f, 0x15, 0x30, 0xe2, 0x6f, 0xd3, 0x6e, + 0x03, 0x2f, 0x04, 0x30, 0x83, 0x42, 0x80, 0x2e, 0xef, 0xb3, 0x04, 0x40, 0x25, 0x29, 0x04, 0x42, 0x83, 0x42, 0x45, + 0x82, 0x94, 0x6f, 0x04, 0x85, 0xc0, 0xb2, 0x90, 0x2e, 0xdb, 0xb3, 0x15, 0x87, 0x3c, 0x8c, 0xc4, 0x40, 0x46, 0x7f, + 0xc2, 0x86, 0x07, 0x40, 0x86, 0x41, 0xf4, 0xbf, 0x00, 0xb3, 0x0c, 0x2f, 0x90, 0x6f, 0x16, 0x80, 0x46, 0x25, 0x00, + 0x40, 0x57, 0x25, 0x04, 0x18, 0xae, 0x0e, 0x10, 0x30, 0x06, 0x30, 0x75, 0x25, 0x46, 0x23, 0x60, 0x6f, 0x64, 0x25, + 0xc4, 0x40, 0xfa, 0x86, 0x00, 0xb3, 0x33, 0x7f, 0x09, 0x2f, 0x93, 0x6f, 0xd8, 0x88, 0x53, 0x6f, 0x04, 0x41, 0xc3, + 0x40, 0xdc, 0x0e, 0x13, 0x30, 0x04, 0x30, 0xdc, 0x22, 0xb3, 0x25, 0x40, 0xb3, 0x02, 0x2f, 0x3b, 0x25, 0xc0, 0x90, + 0x05, 0x2f, 0x91, 0x6f, 0xd0, 0x6f, 0x98, 0x2e, 0x3e, 0xb2, 0x4d, 0x2c, 0x04, 0x30, 0x8d, 0x88, 0x43, 0x40, 0x82, + 0x40, 0x54, 0x7f, 0xda, 0x0f, 0x04, 0x30, 0x08, 0x2f, 0xc1, 0x80, 0x40, 0x42, 0xc2, 0x0f, 0x02, 0x2f, 0x00, 0x30, + 0xc0, 0x7e, 0x1b, 0x2d, 0xc0, 0x7e, 0x19, 0x2d, 0xe1, 0xbc, 0x92, 0x6f, 0x4f, 0x04, 0x90, 0x84, 0x40, 0xa8, 0x21, + 0x05, 0x83, 0x40, 0x4c, 0x22, 0x4b, 0x0e, 0xb6, 0x84, 0x21, 0x30, 0x02, 0x2f, 0x11, 0x30, 0x04, 0x2c, 0xc1, 0x7e, + 0xe3, 0x6f, 0xc1, 0x7e, 0xc1, 0x42, 0x00, 0x2e, 0x00, 0x40, 0x81, 0x40, 0x04, 0xbd, 0x40, 0x6f, 0x98, 0x2e, 0x28, + 0xb1, 0x50, 0x6f, 0x11, 0x30, 0x02, 0x40, 0x51, 0x08, 0xc3, 0x6e, 0x03, 0x80, 0x99, 0x15, 0x0b, 0x40, 0xb1, 0x6f, + 0xd0, 0x6f, 0xb6, 0x7f, 0x5b, 0x7f, 0x04, 0x30, 0x59, 0x54, 0x03, 0x30, 0x11, 0x2c, 0x14, 0x80, 0x55, 0x6f, 0x06, + 0x40, 0x75, 0x01, 0x58, 0xbb, 0x6a, 0x09, 0x05, 0x42, 0xc1, 0x86, 0x47, 0x40, 0x51, 0x25, 0xbe, 0x01, 0x56, 0x43, + 0x00, 0x2e, 0x46, 0x41, 0xf4, 0x03, 0xb6, 0x6f, 0x47, 0x43, 0x5e, 0x0e, 0xed, 0x2f, 0x31, 0x6f, 0x60, 0x6f, 0x42, + 0x40, 0x15, 0x30, 0x02, 0x82, 0x95, 0x08, 0x04, 0x42, 0x52, 0x42, 0x02, 0x2c, 0x44, 0x42, 0x04, 0x30, 0x3e, 0x8e, + 0x91, 0x6f, 0x4f, 0x8c, 0x02, 0x40, 0x83, 0x41, 0xb5, 0x8d, 0x93, 0x0e, 0xd0, 0x6f, 0x01, 0x2f, 0x98, 0x2e, 0x3e, + 0xb2, 0x00, 0x2e, 0xc0, 0x41, 0x81, 0x41, 0xc1, 0x0f, 0xc0, 0x6f, 0x01, 0x2f, 0x04, 0x42, 0x00, 0x2e, 0x70, 0x6f, + 0x3c, 0x82, 0x00, 0x40, 0x41, 0x40, 0x89, 0x16, 0x95, 0x08, 0x4a, 0x00, 0x04, 0xbc, 0x91, 0xb4, 0x01, 0x0e, 0xe0, + 0x6f, 0x07, 0x2f, 0xa1, 0x6f, 0x00, 0x2e, 0x41, 0x40, 0x40, 0xb2, 0x02, 0x2f, 0xa1, 0x6f, 0x05, 0x42, 0x44, 0x42, + 0x00, 0x2e, 0x8b, 0x6f, 0xc0, 0x5e, 0xb8, 0x2e, 0x09, 0x86, 0x02, 0x30, 0x12, 0x42, 0x43, 0x0e, 0xfc, 0x2f, 0x37, + 0x80, 0x13, 0x30, 0x13, 0x42, 0x12, 0x42, 0x12, 0x42, 0x12, 0x42, 0x02, 0x42, 0x03, 0x80, 0x41, 0x84, 0x11, 0x42, + 0x02, 0x42, 0xb8, 0x2e, 0x46, 0x84, 0x80, 0x50, 0xa3, 0x40, 0x83, 0x88, 0x82, 0x40, 0x04, 0x41, 0xc3, 0x7f, 0x42, + 0x8a, 0x06, 0x41, 0x6d, 0xbb, 0xf6, 0x7f, 0x80, 0xb3, 0xd5, 0x7f, 0xe0, 0x7f, 0x59, 0x2f, 0x31, 0x25, 0x55, 0x40, + 0x41, 0x91, 0xb1, 0x7f, 0x0f, 0x2f, 0x01, 0x30, 0xc1, 0x42, 0x00, 0x2e, 0xd2, 0x6f, 0x13, 0x40, 0x93, 0x42, 0x00, + 0x2e, 0x13, 0x40, 0x93, 0x42, 0x00, 0x2e, 0x00, 0x40, 0x80, 0x42, 0xbd, 0x80, 0xc0, 0x2e, 0x01, 0x42, 0x80, 0x5f, + 0xc7, 0x86, 0x01, 0x30, 0xc5, 0x40, 0xfb, 0x86, 0x45, 0x41, 0x04, 0x41, 0x43, 0xbe, 0xd5, 0xbe, 0x43, 0xba, 0xd5, + 0xba, 0x84, 0x7f, 0x95, 0x7f, 0xa1, 0x7f, 0x14, 0x30, 0x61, 0x15, 0xf5, 0x09, 0x15, 0x40, 0xc0, 0xb3, 0x0b, 0x2f, + 0xc6, 0x40, 0xae, 0x05, 0x07, 0x30, 0xfe, 0x05, 0x80, 0xa9, 0xb7, 0x23, 0x97, 0x6f, 0x77, 0x0f, 0xa6, 0x6f, 0xe6, + 0x23, 0xf6, 0x6f, 0xa7, 0x7f, 0x80, 0x90, 0x00, 0x2f, 0xc5, 0x42, 0x41, 0x82, 0xc1, 0x86, 0x43, 0xa2, 0xe7, 0x2f, + 0xa1, 0x6f, 0xb0, 0x6f, 0x0a, 0x1a, 0x02, 0x2f, 0x01, 0x30, 0x1b, 0x2c, 0x01, 0x42, 0x01, 0x40, 0x4c, 0x28, 0x82, + 0x6f, 0x01, 0x42, 0x4a, 0x0e, 0x13, 0x2f, 0xc0, 0x6f, 0x00, 0xb2, 0x03, 0x2f, 0x3f, 0x80, 0x20, 0x14, 0x21, 0x2e, + 0x5e, 0xf0, 0xe1, 0x6f, 0xd0, 0x6f, 0x52, 0x40, 0x12, 0x42, 0x00, 0x2e, 0x52, 0x40, 0x12, 0x42, 0x00, 0x2e, 0x41, + 0x40, 0x03, 0x2c, 0x01, 0x42, 0x10, 0x30, 0x40, 0x42, 0x80, 0x5f, 0xb8, 0x2e, 0x6b, 0x50, 0x50, 0x1a, 0x04, 0x2f, + 0x69, 0x56, 0x41, 0x80, 0x4b, 0x1a, 0x81, 0x84, 0x41, 0x22, 0x00, 0x30, 0xc0, 0x2e, 0x82, 0x04, 0x0a, 0x28, 0xff, + 0x80, 0x14, 0x30, 0x20, 0x14, 0x0a, 0x18, 0x08, 0x17, 0x30, 0x00, 0xc0, 0xb2, 0x3c, 0x03, 0x0b, 0x2f, 0xd0, 0xa0, + 0x03, 0x2f, 0xf0, 0x80, 0x20, 0x10, 0x07, 0x2c, 0x08, 0x17, 0x05, 0x31, 0x6b, 0x05, 0x65, 0x15, 0x03, 0x12, 0x23, + 0x11, 0x05, 0x0a, 0xc8, 0x16, 0x23, 0x1a, 0x04, 0x2f, 0x4a, 0x0c, 0x69, 0x54, 0xc0, 0x2e, 0x9f, 0xb8, 0x0a, 0x00, + 0xb8, 0x2e, 0x80, 0xa0, 0x17, 0x30, 0x04, 0x30, 0x3c, 0x22, 0x40, 0xa0, 0xbc, 0x23, 0x06, 0x1a, 0x4a, 0x17, 0x2f, + 0x08, 0x10, 0x00, 0x30, 0x50, 0x01, 0xb4, 0x88, 0x17, 0xdb, 0x7f, 0x07, 0x2f, 0x80, 0xa8, 0x03, 0x2f, 0xf4, 0x3f, + 0x20, 0x04, 0x03, 0x2c, 0xa6, 0x07, 0x38, 0x04, 0xa6, 0x07, 0x80, 0xb2, 0x14, 0x2f, 0xc9, 0x17, 0xc0, 0xb2, 0x42, + 0x25, 0x0b, 0x2f, 0xd0, 0xa0, 0x03, 0x2f, 0xf0, 0x86, 0xcb, 0x15, 0x07, 0x2c, 0x01, 0x30, 0x02, 0x31, 0x93, 0x04, + 0x8a, 0x12, 0xfb, 0x15, 0x4b, 0x14, 0xfa, 0x0b, 0x88, 0x00, 0xfe, 0x02, 0x98, 0x2e, 0x5c, 0xb7, 0x04, 0x2d, 0x40, + 0xac, 0xf1, 0x3f, 0x03, 0x30, 0x0b, 0x22, 0xdb, 0x6f, 0xd0, 0x5f, 0x93, 0x52, 0xc0, 0x2e, 0x01, 0x0e, 0x08, 0x22, + 0x6b, 0x56, 0x05, 0x40, 0x69, 0x18, 0x0d, 0x17, 0xe1, 0x18, 0x19, 0x05, 0x16, 0x25, 0x37, 0x25, 0x4a, 0x17, 0x54, + 0x18, 0xec, 0x18, 0x04, 0x30, 0x64, 0x07, 0xea, 0x18, 0x8e, 0x00, 0x5f, 0x02, 0x67, 0x56, 0x93, 0x00, 0x4c, 0x02, + 0x2f, 0xb9, 0x91, 0xbc, 0x91, 0x0a, 0x02, 0x42, 0xb8, 0x2e, 0x01, 0x2e, 0x1e, 0x01, 0x01, 0x31, 0x10, 0x50, 0x01, + 0x08, 0x00, 0xb2, 0xfb, 0x7f, 0x10, 0x2f, 0x01, 0x2e, 0x5e, 0x00, 0x01, 0x90, 0x00, 0x30, 0x03, 0x2f, 0x21, 0x2e, + 0x5e, 0x00, 0x98, 0x2e, 0x52, 0xb7, 0x98, 0x2e, 0x1e, 0xb5, 0x00, 0xb2, 0x06, 0x2f, 0x80, 0x30, 0x21, 0x2e, 0x5e, + 0xf0, 0x03, 0x2d, 0x10, 0x30, 0x21, 0x2e, 0x5e, 0x00, 0xfb, 0x6f, 0xf0, 0x5f, 0xb8, 0x2e, 0x09, 0x2e, 0xb3, 0x00, + 0x00, 0x51, 0xb9, 0x50, 0x97, 0x54, 0x55, 0x5a, 0xa1, 0x52, 0x9f, 0x56, 0x9b, 0x5e, 0xbb, 0x5c, 0xeb, 0x7f, 0x00, + 0x91, 0x65, 0x2f, 0x59, 0x28, 0xff, 0x29, 0xb7, 0x7f, 0xc1, 0x7f, 0xd6, 0x7f, 0x9a, 0x89, 0x51, 0x41, 0x08, 0x0e, + 0x01, 0x22, 0x0a, 0x0f, 0x10, 0x22, 0x99, 0x54, 0x67, 0x52, 0xa4, 0x7f, 0x95, 0x7f, 0x80, 0x7f, 0x98, 0x2e, 0x85, + 0xb4, 0xb2, 0x6f, 0x10, 0x25, 0x98, 0x2e, 0x85, 0xb4, 0x82, 0x6f, 0xe3, 0x30, 0x10, 0x25, 0x98, 0x2e, 0x91, 0xb4, + 0xa5, 0x6f, 0xc8, 0x16, 0x9b, 0x54, 0x67, 0x52, 0x50, 0x43, 0x53, 0x43, 0xa5, 0x7f, 0x98, 0x2e, 0x85, 0xb4, 0x82, + 0x6f, 0xe3, 0x30, 0x10, 0x25, 0x98, 0x2e, 0x91, 0xb4, 0xa1, 0x6f, 0x48, 0x17, 0x50, 0x42, 0x45, 0x42, 0x71, 0x8a, + 0x9d, 0x54, 0x67, 0x52, 0xa5, 0x7f, 0x98, 0x2e, 0x85, 0xb4, 0xc2, 0x6f, 0x10, 0x25, 0x98, 0x2e, 0x85, 0xb4, 0x82, + 0x6f, 0xe3, 0x30, 0x10, 0x25, 0x98, 0x2e, 0x91, 0xb4, 0xa5, 0x6f, 0xc8, 0x16, 0x9f, 0x54, 0x67, 0x52, 0x50, 0x43, + 0x53, 0x43, 0xa5, 0x7f, 0x98, 0x2e, 0x85, 0xb4, 0x82, 0x6f, 0xe3, 0x30, 0x10, 0x25, 0x98, 0x2e, 0x91, 0xb4, 0xa1, + 0x6f, 0xc8, 0x17, 0xa3, 0x56, 0x50, 0x42, 0x47, 0x42, 0xf3, 0x7f, 0x7d, 0x82, 0x82, 0x6f, 0x9f, 0x5a, 0xa1, 0x58, + 0x9d, 0x5c, 0x9f, 0x56, 0xa1, 0x7f, 0x98, 0x2e, 0xb9, 0xb0, 0xd3, 0x6f, 0xa2, 0x6f, 0xd0, 0x42, 0x90, 0x88, 0x77, + 0x52, 0x95, 0x6f, 0xb9, 0x50, 0x97, 0x54, 0xd3, 0x7f, 0x69, 0x0e, 0xa1, 0x2f, 0x11, 0x30, 0x01, 0x43, 0x1a, 0x25, + 0x70, 0x8a, 0x55, 0x56, 0xc5, 0x7f, 0xd5, 0x7f, 0x11, 0x32, 0x95, 0x5c, 0xb3, 0x7f, 0x71, 0x00, 0x05, 0x30, 0xb3, + 0x6f, 0x87, 0x41, 0xc4, 0x40, 0xfc, 0x01, 0x97, 0x43, 0x0c, 0x17, 0x87, 0x41, 0x3c, 0x03, 0x94, 0x43, 0x96, 0x7f, + 0xf5, 0x7f, 0xa1, 0x7f, 0x00, 0x2e, 0xd6, 0x40, 0x30, 0x0e, 0x06, 0x22, 0xb3, 0x7f, 0x32, 0x0f, 0x90, 0x22, 0x9b, + 0x58, 0x99, 0x5c, 0x9b, 0x56, 0x98, 0x2e, 0xb9, 0xb0, 0xc5, 0x6f, 0xb2, 0x6f, 0x50, 0x43, 0xc5, 0x7f, 0x05, 0x30, + 0x77, 0x50, 0x50, 0x0e, 0xa1, 0x6f, 0x44, 0x82, 0x96, 0x6f, 0x97, 0x54, 0xb9, 0x50, 0xda, 0x2f, 0xc7, 0x52, 0x13, + 0x30, 0x46, 0x40, 0xf3, 0x28, 0x43, 0x42, 0xc4, 0xa0, 0xbb, 0x52, 0xc1, 0x7f, 0x33, 0x30, 0x95, 0x58, 0x2e, 0x2f, + 0x15, 0x83, 0xa3, 0x5c, 0xb1, 0x7f, 0xf6, 0x7f, 0x74, 0x25, 0x16, 0x41, 0xa4, 0x7f, 0x97, 0x7f, 0x00, 0x2e, 0x04, + 0x41, 0xcc, 0x17, 0xfb, 0x08, 0xf3, 0x00, 0x65, 0x03, 0xde, 0xbe, 0xb2, 0xb9, 0x5d, 0x0b, 0x28, 0x0e, 0x05, 0x22, + 0x2a, 0x0f, 0x90, 0x22, 0x9f, 0x5a, 0xa1, 0x58, 0x9d, 0x5c, 0x9f, 0x56, 0x98, 0x2e, 0xb9, 0xb0, 0x05, 0x30, 0xc1, + 0x6f, 0xc3, 0x56, 0x50, 0x42, 0x4b, 0x0e, 0xb0, 0x6f, 0xc1, 0x7f, 0x04, 0x82, 0x92, 0x6f, 0xa4, 0x6f, 0x85, 0x42, + 0x33, 0x30, 0xa3, 0x5c, 0xb9, 0x50, 0x97, 0x54, 0xb1, 0x7f, 0x15, 0x43, 0xd5, 0x2f, 0x2b, 0x2e, 0x8c, 0x00, 0xc7, + 0x52, 0x41, 0x82, 0xc1, 0x7f, 0x98, 0x2e, 0xf3, 0x00, 0xd1, 0x6f, 0xb0, 0x7f, 0x98, 0x2e, 0xf3, 0x00, 0x55, 0x52, + 0xa0, 0x7f, 0x98, 0x2e, 0xf3, 0x00, 0x00, 0xa0, 0x69, 0x52, 0x48, 0x23, 0xa2, 0x6f, 0xb1, 0x6f, 0x95, 0x7f, 0xb3, + 0x30, 0x98, 0x2e, 0x91, 0xb4, 0xa2, 0x6f, 0xa0, 0x7f, 0xb3, 0x30, 0x8d, 0x52, 0x98, 0x2e, 0xaf, 0xb4, 0xd1, 0x6f, + 0xc5, 0x6f, 0x02, 0x30, 0xd2, 0x7f, 0xc0, 0x7f, 0x81, 0x7f, 0xb3, 0x30, 0x42, 0x40, 0x51, 0x41, 0x75, 0x7f, 0x98, + 0x2e, 0x91, 0xb4, 0xd5, 0x6f, 0x81, 0x6f, 0x68, 0x29, 0x41, 0x40, 0xc2, 0x6f, 0xd5, 0x7f, 0xb3, 0x30, 0x98, 0x2e, + 0x91, 0xb4, 0x81, 0x6f, 0x75, 0x6f, 0xc3, 0x54, 0x50, 0x42, 0x6a, 0x0e, 0xe9, 0x2f, 0xb2, 0x6f, 0x91, 0x6f, 0x98, + 0x2e, 0x85, 0xb4, 0x10, 0x25, 0xb3, 0x30, 0x21, 0x25, 0x98, 0x2e, 0x91, 0xb4, 0x20, 0x25, 0xc9, 0x50, 0xa5, 0x52, + 0x98, 0x2e, 0xe7, 0xb4, 0xc9, 0x54, 0xb5, 0x6f, 0xa7, 0x50, 0x05, 0x04, 0x91, 0x40, 0x08, 0x0f, 0x9d, 0x8a, 0x82, + 0x40, 0xbd, 0x52, 0x08, 0x2f, 0xbf, 0x84, 0x80, 0xa8, 0x25, 0x2e, 0x97, 0x00, 0x02, 0x30, 0x0b, 0x2f, 0x52, 0x42, + 0x0a, 0x2c, 0x42, 0x42, 0x81, 0x84, 0x85, 0xa0, 0x25, 0x2e, 0x97, 0x00, 0x52, 0x30, 0x10, 0x30, 0x01, 0x2f, 0x52, + 0x42, 0x40, 0x42, 0x00, 0x2e, 0x22, 0x6f, 0xa9, 0x52, 0x91, 0x0f, 0x10, 0x6f, 0x01, 0x30, 0x02, 0x2f, 0xab, 0x56, + 0x03, 0x0f, 0x12, 0x2f, 0x03, 0x6f, 0xc0, 0xa8, 0x8b, 0x05, 0xde, 0x22, 0xad, 0x5c, 0xde, 0x0f, 0xc1, 0x7f, 0x06, + 0x30, 0x0b, 0x2f, 0xaf, 0x56, 0x83, 0x0e, 0x16, 0x30, 0x03, 0x2f, 0x80, 0xa4, 0x16, 0x30, 0x00, 0x2f, 0x26, 0x30, + 0x03, 0x2c, 0xc6, 0x7f, 0x36, 0x30, 0xc6, 0x7f, 0x00, 0x2e, 0x42, 0x41, 0x65, 0x8b, 0x80, 0x90, 0x08, 0x2f, 0xbf, + 0x54, 0xb8, 0x84, 0x30, 0x32, 0x86, 0x42, 0x90, 0x00, 0x1b, 0x30, 0x2d, 0x2e, 0x99, 0x00, 0x8b, 0x42, 0x78, 0x87, + 0x42, 0x41, 0xbf, 0x5a, 0x32, 0x1a, 0x02, 0x2f, 0x56, 0x43, 0x0f, 0x2c, 0x41, 0x43, 0x0b, 0x2e, 0x9a, 0x00, 0x12, + 0x30, 0x6a, 0x29, 0x02, 0x32, 0x2b, 0x2e, 0x9a, 0x00, 0x2a, 0x0e, 0x04, 0x2f, 0xc1, 0x54, 0x89, 0x8a, 0xc0, 0x6f, + 0x80, 0x42, 0x41, 0x43, 0x00, 0x2e, 0x05, 0x2e, 0x5d, 0x00, 0x84, 0x8c, 0xc7, 0x40, 0xa5, 0x41, 0x59, 0x50, 0xc0, + 0xb3, 0x28, 0x09, 0xcc, 0x05, 0xc4, 0x88, 0x83, 0x41, 0xf3, 0xbf, 0x82, 0x8d, 0xb7, 0x7f, 0x94, 0x7f, 0x0a, 0x2f, + 0x09, 0x2e, 0x98, 0x00, 0x00, 0x91, 0x06, 0x2f, 0xb3, 0x58, 0x84, 0x7f, 0x81, 0x82, 0xb5, 0x5a, 0xb5, 0x50, 0x0c, + 0x2c, 0x4b, 0x40, 0x18, 0x09, 0x82, 0x84, 0x58, 0xb8, 0xb8, 0xb9, 0x4c, 0x04, 0xb1, 0x5e, 0xb3, 0xbe, 0x03, 0xbc, + 0x8b, 0x40, 0x13, 0xbe, 0x87, 0x7f, 0xb3, 0x30, 0x86, 0x41, 0xb7, 0x52, 0xa2, 0x6f, 0x76, 0x7f, 0x65, 0x7f, 0x50, + 0x7f, 0x4b, 0x7f, 0x34, 0x7f, 0x98, 0x2e, 0x91, 0xb4, 0xd1, 0x6f, 0x88, 0x0e, 0x01, 0x30, 0x03, 0x2f, 0x0b, 0x2e, + 0x90, 0x00, 0x40, 0xb3, 0x02, 0x2f, 0x23, 0x2e, 0x92, 0x00, 0x0f, 0x2d, 0x05, 0x2e, 0x92, 0x00, 0x15, 0x30, 0x95, + 0x28, 0x70, 0x6f, 0x08, 0xb8, 0x25, 0x2e, 0x92, 0x00, 0x10, 0x0e, 0xc2, 0x6f, 0xc3, 0x50, 0x02, 0x2f, 0x15, 0x42, + 0x12, 0x42, 0x01, 0x42, 0xb3, 0x30, 0xa2, 0x6f, 0x41, 0x6f, 0x98, 0x2e, 0x91, 0xb4, 0xd1, 0x6f, 0x08, 0x0f, 0x03, + 0x2f, 0x03, 0x2e, 0x90, 0x00, 0x40, 0x90, 0x03, 0x2f, 0x01, 0x30, 0x23, 0x2e, 0x94, 0x00, 0x12, 0x2d, 0x03, 0x2e, + 0x94, 0x00, 0x75, 0x6f, 0x59, 0x54, 0x41, 0x82, 0x6a, 0x09, 0x23, 0x2e, 0x94, 0x00, 0x0d, 0x0e, 0x07, 0x2f, 0xc5, + 0x52, 0x42, 0x82, 0x05, 0x30, 0x65, 0x42, 0x12, 0x30, 0x45, 0x42, 0x25, 0x2e, 0x93, 0x00, 0x91, 0x6f, 0x7e, 0x8a, + 0x40, 0x40, 0x7c, 0x84, 0x45, 0x41, 0x05, 0x28, 0x83, 0x40, 0x40, 0x42, 0xc3, 0xb2, 0x02, 0x30, 0x00, 0x30, 0x2b, + 0x2f, 0xc0, 0x6f, 0x00, 0xb2, 0x00, 0x30, 0x27, 0x2f, 0x01, 0x2e, 0x98, 0x00, 0x00, 0x90, 0x00, 0x30, 0x05, 0x2f, + 0xc2, 0x90, 0x03, 0x2f, 0xc0, 0x6f, 0x03, 0x90, 0x00, 0x30, 0x1c, 0x2f, 0x20, 0x6f, 0x83, 0x6f, 0x83, 0x0e, 0x00, + 0x30, 0x17, 0x2f, 0x13, 0x6f, 0x50, 0x6f, 0x98, 0x0f, 0x00, 0x30, 0x12, 0x2f, 0xb0, 0x6f, 0x98, 0x0e, 0x00, 0x30, + 0x0e, 0x2f, 0x03, 0x6f, 0x60, 0x6f, 0x98, 0x0f, 0x00, 0x30, 0x09, 0x2f, 0x30, 0x6f, 0x98, 0x0e, 0x00, 0x30, 0x05, + 0x2f, 0x40, 0xb3, 0x00, 0x30, 0x02, 0x2f, 0x25, 0x2e, 0x90, 0x00, 0x10, 0x30, 0x41, 0x40, 0x45, 0xac, 0x01, 0x2f, + 0x00, 0xb2, 0x04, 0x2f, 0xc5, 0x52, 0x42, 0x82, 0x25, 0x2e, 0x93, 0x00, 0x42, 0x42, 0x00, 0x2e, 0xeb, 0x6f, 0x00, + 0x5f, 0xb8, 0x2e, 0x95, 0x50, 0x01, 0x30, 0xcb, 0x54, 0x11, 0x42, 0x42, 0x0e, 0xfc, 0x2f, 0x10, 0x30, 0xc0, 0x2e, + 0x21, 0x2e, 0x90, 0x00, 0x30, 0x50, 0xf3, 0x7f, 0xc0, 0xac, 0xe4, 0x7f, 0xd5, 0x7f, 0x03, 0x2f, 0x00, 0x30, 0x82, + 0x04, 0xf3, 0x6f, 0xc3, 0x06, 0x40, 0xad, 0x05, 0x2f, 0xe0, 0x6f, 0x05, 0x30, 0x28, 0x04, 0xd1, 0x6f, 0x69, 0x07, + 0xe0, 0x7f, 0x40, 0xa1, 0x01, 0x30, 0x20, 0x2f, 0x13, 0x25, 0x02, 0x25, 0x04, 0x32, 0x06, 0x30, 0x02, 0x30, 0x03, + 0x30, 0xaf, 0xbb, 0xb1, 0xbd, 0xdf, 0x0a, 0x9f, 0xbb, 0x21, 0xbd, 0x97, 0x0a, 0x8f, 0xbb, 0x91, 0xbc, 0x01, 0xbc, + 0x4f, 0x0a, 0x6b, 0x0e, 0x04, 0x2f, 0x6b, 0x1a, 0x07, 0x2f, 0xe7, 0x6f, 0x7a, 0x0f, 0x04, 0x2f, 0xe7, 0x6f, 0x97, + 0x04, 0x17, 0x30, 0x07, 0x0a, 0xdd, 0x06, 0x81, 0x8d, 0x34, 0x0e, 0xe6, 0x2f, 0x00, 0x2e, 0x0d, 0x2d, 0x6b, 0x0e, + 0x00, 0x30, 0x05, 0x2f, 0x6b, 0x1a, 0x07, 0x2f, 0xe0, 0x6f, 0x42, 0x0f, 0x00, 0x30, 0x03, 0x2f, 0xe0, 0x6f, 0x90, + 0x04, 0xdd, 0x06, 0x10, 0x30, 0xf5, 0x6f, 0xc3, 0x7f, 0xb2, 0x7f, 0x40, 0xad, 0x06, 0x2f, 0x03, 0x30, 0xb2, 0x6f, + 0x9a, 0x04, 0xc4, 0x6f, 0xdc, 0x06, 0xb2, 0x7f, 0xc3, 0x7f, 0x00, 0x2e, 0xd2, 0x6f, 0xaa, 0x0c, 0x80, 0xac, 0x02, + 0x30, 0x01, 0x2f, 0x10, 0x04, 0x51, 0x06, 0xd0, 0x5f, 0xb8, 0x2e, 0x00, 0x2e, 0x10, 0x24, 0xcc, 0x09, 0x11, 0x24, + 0x00, 0x0c, 0x12, 0x24, 0x80, 0x2e, 0x13, 0x24, 0x18, 0x00, 0x12, 0x42, 0x13, 0x42, 0x41, 0x1a, 0xfb, 0x2f, 0x10, + 0x24, 0x50, 0x39, 0x11, 0x24, 0x21, 0x2e, 0x21, 0x2e, 0x10, 0x00, 0x23, 0x2e, 0x11, 0x00, 0x80, 0x2e, 0x10, 0x00 +}; + +/***************************************************************************/ + +/*! Static Function Declarations + ****************************************************************************/ + +/*! + * @brief This API enables the features of sensor. + * + * @param[in] feature : Variable to specify the features which are to be set + * in the sensor. + * @param[in] len : Length for read and write + * @param[in] feature_config : Array address which stores the feature + * configuration data + * @param[in] dev : Structure instance of bma4_dev. + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +static int8_t feature_enable(uint8_t feature, uint8_t len, uint8_t *feature_config, struct bma4_dev *dev); + +/*! + * @brief This API disables the features of sensor. + * + * @param[in] feature : Variable to specify the features which are to be unset + * in the sensor. + * @param[in] len : Length for read and write + * @param[in] feature_config : Array address which stores the feature + * configuration data + * @param[in] dev : Structure instance of bma4_dev. + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +static int8_t feature_disable(uint8_t feature, uint8_t len, uint8_t *feature_config, struct bma4_dev *dev); + +/*! + * @brief This API update the settings of step counter into write array. + * + * @param[in] setting : Pointer to structure variable which stores the + * settings parameter1 to parameter25. + * @param[in] index : Value for array traversing. + * @param[out] feature_config : Pointer to store the settings + * + * @return none + */ +static void update_stepcounter_parameter(const struct bma456w_stepcounter_settings *setting, + uint8_t index, + uint8_t *feature_config); + +/*! + * @brief This API copy the settings of step counter into the + * structure of bma456w_stepcounter_settings, which is read from sensor. + * + * @param[out] setting : Pointer to structure variable which stores the + * settings parameter1 to parameter25 read from sensor. + * @param[in] data_p : Pointer of array which stores the parameters. + * + * @return none + */ +static void extract_stepcounter_parameter(struct bma456w_stepcounter_settings *setting, const uint16_t *data_p); + +/***************************************************************************/ + +/**\name 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 and sets the resolution. + */ +int8_t bma456w_init(struct bma4_dev *dev) +{ + int8_t rslt; + + /* Structure to define the default values for axes re-mapping */ + struct bma4_axes_remap axes_remap = { + .x_axis = BMA4_MAP_X_AXIS, .x_axis_sign = BMA4_MAP_POSITIVE, .y_axis = BMA4_MAP_Y_AXIS, + .y_axis_sign = BMA4_MAP_POSITIVE, .z_axis = BMA4_MAP_Z_AXIS, .z_axis_sign = BMA4_MAP_POSITIVE + }; + + rslt = bma4_init(dev); + + if (rslt == BMA4_OK) + { + if (dev->chip_id == BMA456W_CHIP_ID) + { + /* Resolution of BMA456 sensor is 16 bit */ + dev->resolution = BMA4_16_BIT_RESOLUTION; + + dev->feature_len = BMA456W_FEATURE_SIZE; + + dev->config_size = sizeof(bma456w_config_file); + + /* Set the default values for axis + * re-mapping in the device structure + */ + dev->remap = axes_remap; + } + else + { + rslt = BMA4_E_INVALID_SENSOR; + } + } + + return rslt; +} + +/*! + * @brief This API is used to upload the configuration file to enable the + * features of the sensor. + */ +int8_t bma456w_write_config_file(struct bma4_dev *dev) +{ + int8_t rslt = BMA4_OK; + + if (dev != NULL) + { + /* Configuration stream read/write length boundary + * check + */ + if ((dev->read_write_len >= BMA456W_RD_WR_MIN_LEN) && (dev->read_write_len <= BMA456W_RD_WR_MAX_LEN)) + { + /* Even or odd check */ + if ((dev->read_write_len % 2) != 0) + { + dev->read_write_len = dev->read_write_len - 1; + } + + /* Assign stream data */ + dev->config_file_ptr = bma456w_config_file; + rslt = bma4_write_config_file(dev); + } + else + { + rslt = BMA4_E_RD_WR_LENGTH_INVALID; + } + } + else + { + rslt = BMA4_E_NULL_PTR; + } + + return rslt; +} + +/*! + * @brief This API is used to get the configuration id of the sensor. + */ +int8_t bma456w_get_config_id(uint16_t *config_id, struct bma4_dev *dev) +{ + uint8_t feature_config[BMA456W_FEATURE_SIZE] = { 0 }; + uint8_t index = BMA456W_CONFIG_ID_OFFSET; + int8_t rslt = BMA4_OK; + uint16_t config_id_lsb = 0; + uint16_t config_id_msb = 0; + + if (config_id != NULL) + { + rslt = bma4_read_regs(BMA4_FEATURE_CONFIG_ADDR, feature_config, BMA456W_FEATURE_SIZE, dev); + + if (rslt == BMA4_OK) + { + config_id_lsb = (uint16_t)feature_config[index]; + config_id_msb = ((uint16_t)feature_config[index + 1]) << 8; + *config_id = config_id_lsb | config_id_msb; + } + } + else + { + rslt = BMA4_E_NULL_PTR; + } + + return rslt; +} + +/*! + * @brief This API sets/un-sets the user provided interrupt to either interrupt + * pin1 or pin2 in the sensor. + */ +int8_t bma456w_map_interrupt(uint8_t int_line, uint16_t int_map, uint8_t enable, struct bma4_dev *dev) +{ + int8_t rslt = BMA4_OK; + + if (dev != NULL) + { + if (dev->chip_id == BMA456W_CHIP_ID) + { + if (int_line <= 1) + { + /* Map/Unmap the interrupt */ + rslt = bma4_map_interrupt(int_line, int_map, enable, dev); + } + else + { + rslt = BMA4_E_INT_LINE_INVALID; + } + } + else + { + rslt = BMA4_E_INVALID_SENSOR; + } + } + else + { + rslt = BMA4_E_NULL_PTR; + } + + return rslt; +} + +/*! + * @brief This API reads the bma456w interrupt status from the sensor. + */ +int8_t bma456w_read_int_status(uint16_t *int_status, struct bma4_dev *dev) +{ + int8_t rslt = BMA4_OK; + + if (int_status != NULL) + { + /* Read the interrupt status */ + rslt = bma4_read_int_status(int_status, dev); + } + else + { + rslt = BMA4_E_NULL_PTR; + } + + return rslt; +} + +/*! + * @brief This API enables/disables the features of the sensor. + */ +int8_t bma456w_feature_enable(uint8_t feature, uint8_t enable, struct bma4_dev *dev) +{ + uint8_t feature_config[BMA456W_FEATURE_SIZE] = { 0 }; + int8_t rslt; + uint8_t len = BMA456W_FEATURE_SIZE; + + /* Read feature configuration data */ + rslt = bma4_read_regs(BMA4_FEATURE_CONFIG_ADDR, feature_config, len, dev); + + if (rslt == BMA4_OK) + { + if (enable == TRUE) + { + /* Enables the feature */ + rslt = feature_enable(feature, len, feature_config, dev); + } + else + { + /* Disables the feature */ + rslt = feature_disable(feature, len, feature_config, dev); + } + } + + return rslt; +} + +/*! + * @brief This API performs x, y and z axis remapping in the sensor. + */ +int8_t bma456w_set_remap_axes(const struct bma4_remap *remap_axes, struct bma4_dev *dev) +{ + uint8_t feature_config[BMA456W_FEATURE_SIZE] = { 0 }; + uint8_t index = BMA456W_AXES_REMAP_OFFSET; + int8_t rslt = BMA4_OK; + + if (remap_axes != NULL) + { + rslt = bma4_set_remap_axes(remap_axes, feature_config, index, BMA456W_FEATURE_SIZE, dev); + } + else + { + rslt = BMA4_E_NULL_PTR; + } + + return rslt; +} + +/*! + * @brief This API reads the x, y and z axis remap data from the sensor. + */ +int8_t bma456w_get_remap_axes(struct bma4_remap *remap_axes, struct bma4_dev *dev) +{ + uint8_t feature_config[BMA456W_FEATURE_SIZE] = { 0 }; + uint8_t index = BMA456W_AXES_REMAP_OFFSET; + int8_t rslt = BMA4_OK; + + if (remap_axes != NULL) + { + rslt = bma4_get_remap_axes(remap_axes, feature_config, index, BMA456W_FEATURE_SIZE, dev); + } + else + { + rslt = BMA4_E_NULL_PTR; + } + + return rslt; +} + +/*! + * @brief This API sets the configuration of any-motion feature in the sensor. + * This API enables/disables the any-motion feature according to the axis set. + */ +int8_t bma456w_set_any_mot_config(const struct bma456w_any_no_mot_config *any_mot, struct bma4_dev *dev) +{ + /* Variable to define error */ + int8_t rslt = BMA4_OK; + + /* Initialize configuration file */ + uint8_t feature_config[BMA456W_FEATURE_SIZE] = { 0 }; + + /* Update index to configure any-motion axes */ + uint8_t index = BMA456W_ANY_MOT_OFFSET; + + /* Variable to define LSB */ + uint16_t lsb = 0; + + /* Variable to define MSB */ + uint16_t msb = 0; + + /* Variable to define LSB and MSB */ + uint16_t lsb_msb = 0; + + if (any_mot != NULL) + { + /* Get any-motion configuration from the sensor */ + rslt = bma4_read_regs(BMA4_FEATURE_CONFIG_ADDR, feature_config, BMA456W_ANY_MOT_LEN, dev); + + if (rslt == BMA4_OK) + { + /* Set threshold value in feature configuration array */ + feature_config[index++] = BMA4_GET_LSB(any_mot->threshold); + feature_config[index++] = BMA4_GET_MSB(any_mot->threshold); + + /* Extract the word where duration and axes enable + * resides + */ + lsb = feature_config[index]; + msb = feature_config[index + 1] << 8; + lsb_msb = lsb | msb; + + /* Set the duration in the same word */ + lsb_msb = BMA4_SET_BITS_POS_0(lsb_msb, BMA456W_ANY_NO_MOT_DUR, any_mot->duration); + + /* Set the axes in the same word */ + lsb_msb = BMA4_SET_BITSLICE(lsb_msb, BMA456W_ANY_NO_MOT_AXIS_EN, any_mot->axes_en); + + /* Assign the word with set duration and axes enable + * value back to feature configuration array + */ + feature_config[index++] = BMA4_GET_LSB(lsb_msb); + feature_config[index] = BMA4_GET_MSB(lsb_msb); + + /* Set any-motion configuration to the sensor */ + rslt = bma4_write_regs(BMA4_FEATURE_CONFIG_ADDR, feature_config, BMA456W_ANY_MOT_LEN, dev); + } + } + else + { + rslt = BMA4_E_NULL_PTR; + } + + return rslt; +} + +/*! + * @brief This API gets the configuration of any-motion feature from the + * sensor. + */ +int8_t bma456w_get_any_mot_config(struct bma456w_any_no_mot_config *any_mot, struct bma4_dev *dev) +{ + /* Variable to define error */ + int8_t rslt = BMA4_OK; + + /* Initialize configuration file */ + uint8_t feature_config[BMA456W_FEATURE_SIZE] = { 0 }; + + /* Update index to configure any-motion axes */ + uint8_t index = BMA456W_ANY_MOT_OFFSET; + + /* Variable to define LSB */ + uint16_t lsb = 0; + + /* Variable to define MSB */ + uint16_t msb = 0; + + /* Variable to define LSB and MSB */ + uint16_t lsb_msb = 0; + + if (any_mot != NULL) + { + /* Get any-motion configuration from the sensor */ + rslt = bma4_read_regs(BMA4_FEATURE_CONFIG_ADDR, feature_config, BMA456W_ANY_MOT_LEN, dev); + + if (rslt == BMA4_OK) + { + /* Get word to calculate threshold and any-motion + * select + */ + lsb = (uint16_t)feature_config[index++]; + msb = ((uint16_t)feature_config[index++] << 8); + lsb_msb = lsb | msb; + + /* Extract threshold value */ + any_mot->threshold = lsb_msb & BMA456W_ANY_NO_MOT_THRES_MSK; + + /* Get word to calculate duration and axes enable */ + lsb = (uint16_t)feature_config[index++]; + msb = ((uint16_t)feature_config[index] << 8); + lsb_msb = lsb | msb; + + /* Extract duration value */ + any_mot->duration = lsb_msb & BMA456W_ANY_NO_MOT_DUR_MSK; + + /* Extract axes enable value */ + any_mot->axes_en = (uint8_t)((lsb_msb & BMA456W_ANY_NO_MOT_AXIS_EN_MSK) >> BMA456W_ANY_NO_MOT_AXIS_EN_POS); + } + } + else + { + rslt = BMA4_E_NULL_PTR; + } + + return rslt; +} + +/*! + * @brief This API sets the configuration of no-motion feature in the sensor. + * This API enables/disables the no-motion feature according to the axis set. + */ +int8_t bma456w_set_no_mot_config(const struct bma456w_any_no_mot_config *no_mot, struct bma4_dev *dev) +{ + /* Variable to define error */ + int8_t rslt = BMA4_OK; + + /* Initialize configuration file */ + uint8_t feature_config[BMA456W_FEATURE_SIZE] = { 0 }; + + /* Update index to configure no-motion axes */ + uint8_t index = BMA456W_NO_MOT_OFFSET; + + /* Variable to define LSB */ + uint16_t lsb = 0; + + /* Variable to define MSB */ + uint16_t msb = 0; + + /* Variable to define LSB and MSB */ + uint16_t lsb_msb = 0; + + if (no_mot != NULL) + { + /* Get no-motion configuration from the sensor */ + rslt = bma4_read_regs(BMA4_FEATURE_CONFIG_ADDR, feature_config, BMA456W_NO_MOT_RD_WR_LEN, dev); + + if (rslt == BMA4_OK) + { + /* Set threshold value in feature configuration array */ + feature_config[index++] = BMA4_GET_LSB(no_mot->threshold); + feature_config[index++] = BMA4_GET_MSB(no_mot->threshold); + + /* Extract the word where duration and axes enable + * resides + */ + lsb = feature_config[index]; + msb = feature_config[index + 1] << 8; + lsb_msb = lsb | msb; + + /* Set the duration in the same word */ + lsb_msb = BMA4_SET_BITS_POS_0(lsb_msb, BMA456W_ANY_NO_MOT_DUR, no_mot->duration); + + /* Set the axes in the same word */ + lsb_msb = BMA4_SET_BITSLICE(lsb_msb, BMA456W_ANY_NO_MOT_AXIS_EN, no_mot->axes_en); + + /* Assign the word with set duration and axes enable + * value back to feature configuration array + */ + feature_config[index++] = BMA4_GET_LSB(lsb_msb); + feature_config[index] = BMA4_GET_MSB(lsb_msb); + + /* Set no-motion configuration to the sensor */ + rslt = bma4_write_regs(BMA4_FEATURE_CONFIG_ADDR, feature_config, BMA456W_NO_MOT_RD_WR_LEN, dev); + } + } + else + { + rslt = BMA4_E_NULL_PTR; + } + + return rslt; +} + +/*! + * @brief This API gets the configuration of no-motion feature from the + * sensor. + */ +int8_t bma456w_get_no_mot_config(struct bma456w_any_no_mot_config *no_mot, struct bma4_dev *dev) +{ + /* Variable to define error */ + int8_t rslt = BMA4_OK; + + /* Initialize configuration file */ + uint8_t feature_config[BMA456W_FEATURE_SIZE] = { 0 }; + + /* Update index to configure no-motion axes */ + uint8_t index = BMA456W_NO_MOT_OFFSET; + + /* Variable to define LSB */ + uint16_t lsb = 0; + + /* Variable to define MSB */ + uint16_t msb = 0; + + /* Variable to define LSB and MSB */ + uint16_t lsb_msb = 0; + + if (no_mot != NULL) + { + /* Get no-motion configuration from the sensor */ + rslt = bma4_read_regs(BMA4_FEATURE_CONFIG_ADDR, feature_config, BMA456W_NO_MOT_RD_WR_LEN, dev); + + if (rslt == BMA4_OK) + { + /* Get word to calculate threshold and no-motion + * select + */ + lsb = (uint16_t)feature_config[index++]; + msb = ((uint16_t)feature_config[index++] << 8); + lsb_msb = lsb | msb; + + /* Extract threshold value */ + no_mot->threshold = lsb_msb & BMA456W_ANY_NO_MOT_THRES_MSK; + + /* Get word to calculate duration and axes enable */ + lsb = (uint16_t)feature_config[index++]; + msb = ((uint16_t)feature_config[index] << 8); + lsb_msb = lsb | msb; + + /* Extract duration value */ + no_mot->duration = lsb_msb & BMA456W_ANY_NO_MOT_DUR_MSK; + + /* Extract axes enable value */ + no_mot->axes_en = (uint8_t)((lsb_msb & BMA456W_ANY_NO_MOT_AXIS_EN_MSK) >> BMA456W_ANY_NO_MOT_AXIS_EN_POS); + } + } + else + { + rslt = BMA4_E_NULL_PTR; + } + + return rslt; +} + +/*! + * @brief This API enables or disables the step detector feature in the sensor. + */ +int8_t bma456w_step_detector_enable(uint8_t enable, struct bma4_dev *dev) +{ + uint8_t feature_config[BMA456W_FEATURE_SIZE] = { 0 }; + int8_t rslt; + + /* Step detector enable bit position is 1 byte ahead of the base address */ + uint8_t index = BMA456W_STEP_CNTR_OFFSET + 1; + + rslt = bma4_read_regs(BMA4_FEATURE_CONFIG_ADDR, feature_config, BMA456W_FEATURE_SIZE, dev); + + if (rslt == BMA4_OK) + { + feature_config[index] = BMA4_SET_BITSLICE(feature_config[index], BMA456W_STEP_DETECTOR_EN, enable); + rslt = bma4_write_regs(BMA4_FEATURE_CONFIG_ADDR, feature_config, BMA456W_FEATURE_SIZE, dev); + } + + return rslt; +} + +/*! + * @brief This API sets the water mark level for step counter interrupt in the + * sensor. + */ +int8_t bma456w_step_counter_set_watermark(uint16_t step_counter_wm, struct bma4_dev *dev) +{ + uint8_t feature_config[BMA456W_FEATURE_SIZE] = { 0 }; + uint8_t index = BMA456W_STEP_CNTR_OFFSET; + uint16_t wm_lsb = 0; + uint16_t wm_msb = 0; + int8_t rslt; + uint16_t data = 0; + + rslt = bma4_read_regs(BMA4_FEATURE_CONFIG_ADDR, feature_config, BMA456W_FEATURE_SIZE, dev); + + if (rslt == BMA4_OK) + { + wm_lsb = feature_config[index]; + wm_msb = feature_config[index + 1] << 8; + data = wm_lsb | wm_msb; + + /* Sets only water mark bits in the complete + * 16 bits of data + */ + data = BMA4_SET_BITS_POS_0(data, BMA456W_STEP_CNTR_WM, step_counter_wm); + + /* Splits 16 bits of data to individual + * 8 bits data + */ + feature_config[index] = BMA4_GET_LSB(data); + feature_config[index + 1] = BMA4_GET_MSB(data); + + /* Writes step counter water mark settings + * in the sensor + */ + rslt = bma4_write_regs(BMA4_FEATURE_CONFIG_ADDR, feature_config, BMA456W_FEATURE_SIZE, dev); + } + + return rslt; +} + +/*! + * @brief This API gets the water mark level set for step counter interrupt + * in the sensor. + */ +int8_t bma456w_step_counter_get_watermark(uint16_t *step_counter_wm, struct bma4_dev *dev) +{ + uint8_t feature_config[BMA456W_FEATURE_SIZE] = { 0 }; + uint8_t index = BMA456W_STEP_CNTR_OFFSET; + uint16_t wm_lsb = 0; + uint16_t wm_msb = 0; + int8_t rslt = BMA4_OK; + uint16_t data = 0; + + if (step_counter_wm != NULL) + { + rslt = bma4_read_regs(BMA4_FEATURE_CONFIG_ADDR, feature_config, BMA456W_FEATURE_SIZE, dev); + + if (rslt == BMA4_OK) + { + wm_lsb = feature_config[index]; + wm_msb = feature_config[index + 1] << 8; + data = wm_lsb | wm_msb; + *step_counter_wm = BMA4_GET_BITS_POS_0(data, BMA456W_STEP_CNTR_WM); + } + } + else + { + rslt = BMA4_E_NULL_PTR; + } + + return rslt; +} + +/*! + * @brief This API resets the counted steps of step counter. + */ +int8_t bma456w_reset_step_counter(struct bma4_dev *dev) +{ + uint8_t feature_config[BMA456W_FEATURE_SIZE] = { 0 }; + + /* Reset bit is 1 byte ahead of base address */ + uint8_t index = BMA456W_STEP_CNTR_OFFSET + 1; + int8_t rslt; + + rslt = bma4_read_regs(BMA4_FEATURE_CONFIG_ADDR, feature_config, BMA456W_FEATURE_SIZE, dev); + + if (rslt == BMA4_OK) + { + feature_config[index] = BMA4_SET_BITSLICE(feature_config[index], BMA456W_STEP_CNTR_RST, 1); + rslt = bma4_write_regs(BMA4_FEATURE_CONFIG_ADDR, feature_config, BMA456W_FEATURE_SIZE, dev); + } + + return rslt; +} + +/*! + * @brief This API gets the number of counted steps of the step counter + * feature from the sensor. + */ +int8_t bma456w_step_counter_output(uint32_t *step_count, struct bma4_dev *dev) +{ + uint8_t data[BMA456W_STEP_CNTR_DATA_SIZE] = { 0 }; + int8_t rslt = BMA4_OK; + uint32_t step_count_0 = 0; + uint32_t step_count_1 = 0; + uint32_t step_count_2 = 0; + uint32_t step_count_3 = 0; + + if (step_count != NULL) + { + /* Reads the step counter output data from the + * gpio register + */ + rslt = bma4_read_regs(BMA4_STEP_CNT_OUT_0_ADDR, data, BMA456W_STEP_CNTR_DATA_SIZE, dev); + + if (rslt == BMA4_OK) + { + step_count_0 = (uint32_t)data[0]; + step_count_1 = (uint32_t)data[1] << 8; + step_count_2 = (uint32_t)data[2] << 16; + step_count_3 = (uint32_t)data[3] << 24; + *step_count = step_count_0 | step_count_1 | step_count_2 | step_count_3; + } + } + else + { + rslt = BMA4_E_NULL_PTR; + } + + return rslt; +} + +/*! + * @brief This API gets the output for activity feature. + */ +int8_t bma456w_activity_output(uint8_t *activity, struct bma4_dev *dev) +{ + uint8_t data = 0; + int8_t rslt = BMA4_OK; + + if (activity != NULL) + { + /* Reads the activity output from the gpio register */ + rslt = bma4_read_regs(BMA4_ACTIVITY_OUT_ADDR, &data, 1, dev); + + if (rslt == BMA4_OK) + { + *activity = data; + } + } + else + { + rslt = BMA4_E_NULL_PTR; + } + + return rslt; +} + +/*! + * @brief This API gets the parameter1 to parameter7 settings of the step + * counter feature. + */ +int8_t bma456w_stepcounter_get_parameter(struct bma456w_stepcounter_settings *setting, struct bma4_dev *dev) +{ + uint8_t feature_config[BMA456W_FEATURE_SIZE] = { 0 }; + uint16_t *data_p = (uint16_t *)(void *)feature_config; + int8_t rslt = BMA4_OK; + + if (setting != NULL) + { + rslt = bma4_read_regs(BMA4_FEATURE_CONFIG_ADDR, feature_config, BMA456W_FEATURE_SIZE, dev); + + if (rslt == BMA4_OK) + { + /* To convert 8bit to 16 bit address */ + data_p = data_p + BMA456W_STEP_CNTR_PARAM_OFFSET / 2; + extract_stepcounter_parameter(setting, data_p); + } + } + else + { + rslt = BMA4_E_NULL_PTR; + } + + return rslt; +} + +/*! + * @brief This API sets the parameter1 to parameter7 settings of the step + * counter feature in the sensor. + */ +int8_t bma456w_stepcounter_set_parameter(const struct bma456w_stepcounter_settings *setting, struct bma4_dev *dev) +{ + uint8_t feature_config[BMA456W_FEATURE_SIZE] = { 0 }; + uint8_t index = BMA456W_STEP_CNTR_PARAM_OFFSET; + int8_t rslt = BMA4_OK; + + if (setting != NULL) + { + rslt = bma4_read_regs(BMA4_FEATURE_CONFIG_ADDR, feature_config, BMA456W_FEATURE_SIZE, dev); + + if (rslt == BMA4_OK) + { + update_stepcounter_parameter(setting, index, feature_config); + + /* Writes step counter parameter settings + * in the sensor + */ + rslt = bma4_write_regs(BMA4_FEATURE_CONFIG_ADDR, feature_config, BMA456W_FEATURE_SIZE, dev); + } + } + else + { + rslt = BMA4_E_NULL_PTR; + } + + return rslt; +} + +/*! + * @brief This API sets the wrist wear wakeup settings + */ +int8_t bma456w_set_wrist_wear_wakeup_param_config(const struct bma456w_wrist_wear_wakeup_params *setting, + struct bma4_dev *dev) +{ + /* Variable to define error */ + int8_t rslt = BMA4_OK; + + /* Initialize configuration file */ + uint8_t feature_config[BMA456W_FEATURE_SIZE] = { 0 }; + + /* Update index to configure wrist wear wakeup */ + uint8_t index = BMA456W_WRIST_WEAR_WAKEUP_PARAM_OFFSET; + + /* Variable to define LSB */ + uint16_t lsb = 0; + + /* Variable to define MSB */ + uint16_t msb = 0; + + /* Variable to define LSB and MSB */ + uint16_t lsb_msb = 0; + + if (setting != NULL) + { + /* Get wrist wear wake up configuration from the sensor */ + rslt = bma4_read_regs(BMA4_FEATURE_CONFIG_ADDR, feature_config, BMA456W_FEATURE_SIZE, dev); + + if (rslt == BMA4_OK) + { + /* Set minimum angle focus value in feature configuration array */ + feature_config[index++] = BMA4_GET_LSB(setting->min_angle_focus); + feature_config[index++] = BMA4_GET_MSB(setting->min_angle_focus); + + /* Set minimum angle non focus value in feature configuration array */ + feature_config[index++] = BMA4_GET_LSB(setting->min_angle_non_focus); + feature_config[index++] = BMA4_GET_MSB(setting->min_angle_non_focus); + + /* Extract the word where angle landscape right and angle landscape left + * resides + */ + lsb = feature_config[index]; + msb = feature_config[index + 1] << 8; + lsb_msb = lsb | msb; + + /* Set the angle landscape right in the same word */ + lsb_msb = BMA4_SET_BITS_POS_0(lsb_msb, + BMA456W_WRIST_WEAR_WAKEUP_ANG_LSCAPE_RHT, + setting->angle_landscape_right); + + /* Set the angle landscape left in the same word */ + lsb_msb = BMA4_SET_BITSLICE(lsb_msb, + BMA456W_WRIST_WEAR_WAKEUP_ANG_LSCAPE_LEFT, + setting->angle_landscape_left); + + /* Assign the word with set angle landscape right and left + * value back to feature configuration array + */ + feature_config[index++] = BMA4_GET_LSB(lsb_msb); + feature_config[index++] = BMA4_GET_MSB(lsb_msb); + + /* Extract the word where angle portrait down and angle portrait up + * resides + */ + lsb = feature_config[index]; + msb = feature_config[index + 1] << 8; + lsb_msb = lsb | msb; + + /* Set the portrait down in the same word */ + lsb_msb = BMA4_SET_BITS_POS_0(lsb_msb, + BMA456W_WRIST_WEAR_WAKEUP_ANG_PORTRAIT_DOWN, + setting->angle_portrait_down); + + /* Set the portrait up in the same word */ + lsb_msb = BMA4_SET_BITSLICE(lsb_msb, BMA456W_WRIST_WEAR_WAKEUP_ANG_PORTRAIT_UP, setting->angle_portrait_up); + + /* Assign the word with set portrait down and portrait up + * value back to feature configuration array + */ + feature_config[index++] = BMA4_GET_LSB(lsb_msb); + feature_config[index++] = BMA4_GET_MSB(lsb_msb); + + /* Extract the word where minimum duration moved and minimum duration quite + * resides + */ + lsb = feature_config[index]; + msb = feature_config[index + 1] << 8; + lsb_msb = lsb | msb; + + /* Set the minimum duration moved in the same word */ + lsb_msb = BMA4_SET_BITS_POS_0(lsb_msb, BMA456W_WRIST_WEAR_WAKEUP_MIN_DUR_MOVED, setting->min_dur_moved); + + /* Set the minimum duration quite in the same word */ + lsb_msb = BMA4_SET_BITSLICE(lsb_msb, BMA456W_WRIST_WEAR_WAKEUP_MIN_DUR_QUITE, setting->min_dur_quite); + + /* Assign the word with set minimum duration moved and minimum duration quite + * value back to feature configuration array + */ + feature_config[index++] = BMA4_GET_LSB(lsb_msb); + feature_config[index] = BMA4_GET_MSB(lsb_msb); + + /* Set wrist wear wakeup configuration to the sensor */ + rslt = bma4_write_regs(BMA4_FEATURE_CONFIG_ADDR, feature_config, BMA456W_FEATURE_SIZE, dev); + } + } + else + { + rslt = BMA4_E_NULL_PTR; + } + + return rslt; +} + +/*! + * @brief This API gets the wrist wear wakeup settings + */ +int8_t bma456w_get_wrist_wear_wakeup_param_config(struct bma456w_wrist_wear_wakeup_params *setting, + struct bma4_dev *dev) +{ + /* Variable to define error */ + int8_t rslt = BMA4_OK; + + /* Initialize configuration file */ + uint8_t feature_config[BMA456W_FEATURE_SIZE] = { 0 }; + + /* Update index to configure wrist wear wakeup */ + uint8_t index = BMA456W_WRIST_WEAR_WAKEUP_PARAM_OFFSET; + + /* Variable to define LSB */ + uint16_t lsb = 0; + + /* Variable to define MSB */ + uint16_t msb = 0; + + /* Variable to define LSB and MSB */ + uint16_t lsb_msb = 0; + + if (setting != NULL) + { + /* Get wrist wear wakeup configuration from the sensor */ + rslt = bma4_read_regs(BMA4_FEATURE_CONFIG_ADDR, feature_config, BMA456W_FEATURE_SIZE, dev); + + if (rslt == BMA4_OK) + { + /* Get minimum angle focus value in feature configuration array */ + lsb = (uint16_t)feature_config[index++]; + msb = ((uint16_t)feature_config[index++] << 8); + lsb_msb = lsb | msb; + + /* Extract minimum angle focus value */ + setting->min_angle_focus = lsb_msb & BMA456W_WRIST_WEAR_WAKEUP_MIN_ANG_FOCUS_MSK; + + /* Get minimum angle non focus value in feature configuration array */ + lsb = (uint16_t)feature_config[index++]; + msb = ((uint16_t)feature_config[index++] << 8); + lsb_msb = lsb | msb; + + /* Extract minimum angle non focus value */ + setting->min_angle_non_focus = lsb_msb & BMA456W_WRIST_WEAR_WAKEUP_MIN_ANG_NON_FOCUS_MSK; + + /* Get landscape right and landscape left in feature configuration array */ + lsb = (uint16_t)feature_config[index++]; + msb = ((uint16_t)feature_config[index++] << 8); + lsb_msb = lsb | msb; + + /* Extract landscape right value */ + setting->angle_landscape_right = lsb_msb & BMA456W_WRIST_WEAR_WAKEUP_ANG_LSCAPE_RHT_MSK; + + /* Extract landscape left value */ + setting->angle_landscape_left = (lsb_msb & BMA456W_WRIST_WEAR_WAKEUP_ANG_LSCAPE_LEFT_MSK) >> + BMA456W_WRIST_WEAR_WAKEUP_ANG_LSCAPE_LEFT_POS; + + /* Get portrait down and portrait up value in feature configuration array */ + lsb = (uint16_t)feature_config[index++]; + msb = ((uint16_t)feature_config[index++] << 8); + lsb_msb = lsb | msb; + + /* Extract portrait down value */ + setting->angle_portrait_down = lsb_msb & BMA456W_WRIST_WEAR_WAKEUP_ANG_PORTRAIT_DOWN_MSK; + + /* Extract portrait up value */ + setting->angle_portrait_up = (lsb_msb & BMA456W_WRIST_WEAR_WAKEUP_ANG_PORTRAIT_UP_MSK) >> + BMA456W_WRIST_WEAR_WAKEUP_ANG_PORTRAIT_UP_POS; + + /* Get min duration moved and min durtion quite value in feature configuration array */ + lsb = (uint16_t)feature_config[index++]; + msb = ((uint16_t)feature_config[index++] << 8); + lsb_msb = lsb | msb; + + /* Extract min duration moved value */ + setting->min_dur_moved = lsb_msb & BMA456W_WRIST_WEAR_WAKEUP_MIN_DUR_MOVED_MSK; + + /* Extract min duration quite value */ + setting->min_dur_quite = (lsb_msb & BMA456W_WRIST_WEAR_WAKEUP_MIN_DUR_QUITE_MSK) >> + BMA456W_WRIST_WEAR_WAKEUP_MIN_DUR_QUITE_POS; + } + } + else + { + rslt = BMA4_E_NULL_PTR; + } + + return rslt; +} + +/*! @cond DOXYGEN_SUPRESS */ + +/* Suppressing doxygen warnings triggered for same static function names present across various sensor variant + * directories */ + +/*! + * @brief This API enables the features of the sensor. + */ +static int8_t feature_enable(uint8_t feature, uint8_t len, uint8_t *feature_config, struct bma4_dev *dev) +{ + uint8_t index = 0; + int8_t rslt; + + /* Enable step counter */ + if ((feature & BMA456W_STEP_CNTR) > 0) + { + index = BMA456W_STEP_CNTR_OFFSET + 1; + feature_config[index] = feature_config[index] | BMA456W_STEP_CNTR_EN_MSK; + } + + /* Enable step activity */ + if ((feature & BMA456W_STEP_ACT) > 0) + { + index = BMA456W_STEP_CNTR_OFFSET + 1; + feature_config[index] = feature_config[index] | BMA456W_STEP_ACT_EN_MSK; + } + + /* Enable wrist wear wakeup */ + if ((feature & BMA456W_WRIST_WEAR_WAKEUP) > 0) + { + index = BMA456W_WRIST_WEAR_WAKEUP_OFFSET; + feature_config[index] = feature_config[index] | BMA456W_WRIST_WEAR_WAKEUP_EN_MSK; + } + + /* Write the feature enable settings in the sensor */ + rslt = bma4_write_regs(BMA4_FEATURE_CONFIG_ADDR, feature_config, len, dev); + + return rslt; +} + +/*! + * @brief This API disables the features of the sensor. + */ +static int8_t feature_disable(uint8_t feature, uint8_t len, uint8_t *feature_config, struct bma4_dev *dev) +{ + uint8_t index = 0; + int8_t rslt; + + /* Disable step counter */ + if ((feature & BMA456W_STEP_CNTR) > 0) + { + index = BMA456W_STEP_CNTR_OFFSET + 1; + feature_config[index] = feature_config[index] & (~BMA456W_STEP_CNTR_EN_MSK); + } + + /* Disable step activity */ + if ((feature & BMA456W_STEP_ACT) > 0) + { + index = BMA456W_STEP_CNTR_OFFSET + 1; + feature_config[index] = feature_config[index] & (~BMA456W_STEP_ACT_EN_MSK); + } + + /* Disable wrist wear wakeup */ + if ((feature & BMA456W_WRIST_WEAR_WAKEUP) > 0) + { + index = BMA456W_WRIST_WEAR_WAKEUP_OFFSET; + feature_config[index] = feature_config[index] & (~BMA456W_WRIST_WEAR_WAKEUP_EN_MSK); + } + + /* Write the configured settings in the sensor */ + rslt = bma4_write_regs(BMA4_FEATURE_CONFIG_ADDR, feature_config, len, dev); + + return rslt; +} + +/*! + * @brief This API update the settings of step counter. + */ +static void update_stepcounter_parameter(const struct bma456w_stepcounter_settings *setting, + uint8_t index, + uint8_t *feature_config) +{ + feature_config[index++] = BMA4_GET_LSB(setting->param1); + feature_config[index++] = BMA4_GET_MSB(setting->param1); + feature_config[index++] = BMA4_GET_LSB(setting->param2); + feature_config[index++] = BMA4_GET_MSB(setting->param2); + feature_config[index++] = BMA4_GET_LSB(setting->param3); + feature_config[index++] = BMA4_GET_MSB(setting->param3); + feature_config[index++] = BMA4_GET_LSB(setting->param4); + feature_config[index++] = BMA4_GET_MSB(setting->param4); + feature_config[index++] = BMA4_GET_LSB(setting->param5); + feature_config[index++] = BMA4_GET_MSB(setting->param5); + feature_config[index++] = BMA4_GET_LSB(setting->param6); + feature_config[index++] = BMA4_GET_MSB(setting->param6); + feature_config[index++] = BMA4_GET_LSB(setting->param7); + feature_config[index++] = BMA4_GET_MSB(setting->param7); + feature_config[index++] = BMA4_GET_LSB(setting->param8); + feature_config[index++] = BMA4_GET_MSB(setting->param8); + feature_config[index++] = BMA4_GET_LSB(setting->param9); + feature_config[index++] = BMA4_GET_MSB(setting->param9); + feature_config[index++] = BMA4_GET_LSB(setting->param10); + feature_config[index++] = BMA4_GET_MSB(setting->param10); + feature_config[index++] = BMA4_GET_LSB(setting->param11); + feature_config[index++] = BMA4_GET_MSB(setting->param11); + feature_config[index++] = BMA4_GET_LSB(setting->param12); + feature_config[index++] = BMA4_GET_MSB(setting->param12); + feature_config[index++] = BMA4_GET_LSB(setting->param13); + feature_config[index++] = BMA4_GET_MSB(setting->param13); + feature_config[index++] = BMA4_GET_LSB(setting->param14); + feature_config[index++] = BMA4_GET_MSB(setting->param14); + feature_config[index++] = BMA4_GET_LSB(setting->param15); + feature_config[index++] = BMA4_GET_MSB(setting->param15); + feature_config[index++] = BMA4_GET_LSB(setting->param16); + feature_config[index++] = BMA4_GET_MSB(setting->param16); + feature_config[index++] = BMA4_GET_LSB(setting->param17); + feature_config[index++] = BMA4_GET_MSB(setting->param17); + feature_config[index++] = BMA4_GET_LSB(setting->param18); + feature_config[index++] = BMA4_GET_MSB(setting->param18); + feature_config[index++] = BMA4_GET_LSB(setting->param19); + feature_config[index++] = BMA4_GET_MSB(setting->param19); + feature_config[index++] = BMA4_GET_LSB(setting->param20); + feature_config[index++] = BMA4_GET_MSB(setting->param20); + feature_config[index++] = BMA4_GET_LSB(setting->param21); + feature_config[index++] = BMA4_GET_MSB(setting->param21); + feature_config[index++] = BMA4_GET_LSB(setting->param22); + feature_config[index++] = BMA4_GET_MSB(setting->param22); + feature_config[index++] = BMA4_GET_LSB(setting->param23); + feature_config[index++] = BMA4_GET_MSB(setting->param23); + feature_config[index++] = BMA4_GET_LSB(setting->param24); + feature_config[index++] = BMA4_GET_MSB(setting->param24); + feature_config[index++] = BMA4_GET_LSB(setting->param25); + feature_config[index] = BMA4_GET_MSB(setting->param25); +} + +/*! + * @brief This API copy the settings of step counter into the structure of + * bma456w_stepcounter_settings, which is read from sensor. + */ +static void extract_stepcounter_parameter(struct bma456w_stepcounter_settings *setting, const uint16_t *data_p) +{ + setting->param1 = *(data_p++); + setting->param2 = *(data_p++); + setting->param3 = *(data_p++); + setting->param4 = *(data_p++); + setting->param5 = *(data_p++); + setting->param6 = *(data_p++); + setting->param7 = *(data_p++); + setting->param8 = *(data_p++); + setting->param9 = *(data_p++); + setting->param10 = *(data_p++); + setting->param11 = *(data_p++); + setting->param12 = *(data_p++); + setting->param13 = *(data_p++); + setting->param14 = *(data_p++); + setting->param15 = *(data_p++); + setting->param16 = *(data_p++); + setting->param17 = *(data_p++); + setting->param18 = *(data_p++); + setting->param19 = *(data_p++); + setting->param20 = *(data_p++); + setting->param21 = *(data_p++); + setting->param22 = *(data_p++); + setting->param23 = *(data_p++); + setting->param24 = *(data_p++); + setting->param25 = *data_p; +} + +/*! + * @brief This API is used to get the config file major and minor information. + */ +int8_t bma456w_get_version_config(uint16_t *config_major, uint16_t *config_minor, struct bma4_dev *dev) +{ + /* Initialize configuration file */ + uint8_t feature_config[BMA456W_FEATURE_SIZE] = { 0 }; + + /* Update index to config file version */ + uint8_t index = BMA456W_CONFIG_ID_START_ADDR; + + /* Variable to define LSB */ + uint8_t lsb = 0; + + /* Variable to define MSB */ + uint8_t msb = 0; + + /* Variable to define LSB and MSB */ + uint16_t lsb_msb = 0; + + /* Result of api are returned to this variable */ + int8_t rslt = BMA4_OK; + + if ((config_major != NULL) && (config_minor != NULL)) + { + rslt = bma4_set_advance_power_save(BMA4_DISABLE, dev); + + if (rslt == BMA4_OK) + { + /* Wait for sensor time synchronization. Refer the data-sheet for + * more information + */ + dev->delay_us(450, dev->intf_ptr); + + /* Get config file identification from the sensor */ + rslt = bma4_read_regs(BMA4_FEATURE_CONFIG_ADDR, feature_config, BMA456W_FEATURE_SIZE, dev); + + if (rslt == BMA4_OK) + { + /* Get word to calculate config file identification */ + lsb = feature_config[index++]; + msb = feature_config[index++]; + + lsb_msb = (uint16_t)(msb << 8 | lsb); + + /* Get major and minor version */ + *config_major = BMA4_GET_BITSLICE(lsb_msb, BMA4_CONFIG_MAJOR); + *config_minor = BMA4_GET_BITS_POS_0(lsb, BMA4_CONFIG_MINOR); + } + } + } + else + { + rslt = BMA4_E_NULL_PTR; + } + + return rslt; +} + +/*! @endcond */ diff --git a/components/bma456/bma456w.h b/components/bma456/bma456w.h new file mode 100644 index 0000000..fc9ab33 --- /dev/null +++ b/components/bma456/bma456w.h @@ -0,0 +1,1205 @@ +/** +* 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. +* +* @file bma456w.h +* @date 2023-07-05 +* @version V2.29.0 +* +*/ + +/** + * \ingroup bma4xy + * \defgroup bma456w BMA456W + * @brief Sensor driver for BMA456W sensor + */ + +#ifndef BMA456W_H +#define BMA456W_H + +#ifdef __cplusplus +extern "C" { +#endif +#include "bma4.h" + +/**\name Chip ID of BMA456W sensor */ +#define BMA456W_CHIP_ID UINT8_C(0x16) + +/**\ Configuration ID start position of BMA456W sensor */ +#define BMA456W_CONFIG_ID_START_ADDR UINT8_C(72) + +/**\name Sensor feature size */ +#define BMA456W_FEATURE_SIZE UINT8_C(76) +#define BMA456W_ANY_MOT_LEN UINT8_C(4) + +/**\name Feature offset address */ +#define BMA456W_ANY_MOT_OFFSET UINT8_C(0x00) +#define BMA456W_NO_MOT_OFFSET UINT8_C(0x04) +#define BMA456W_STEP_CNTR_PARAM_OFFSET UINT8_C(0x08) +#define BMA456W_STEP_CNTR_OFFSET UINT8_C(0x3A) +#define BMA456W_WRIST_WEAR_WAKEUP_OFFSET UINT8_C(0x3C) +#define BMA456W_WRIST_WEAR_WAKEUP_PARAM_OFFSET UINT8_C(0x3E) +#define BMA456W_CONFIG_ID_OFFSET UINT8_C(0x48) +#define BMA456W_AXES_REMAP_OFFSET UINT8_C(0x4A) + +/**\name Read/Write Lengths */ +#define BMA456W_RD_WR_MIN_LEN UINT8_C(2) +#define BMA456W_NO_MOT_RD_WR_LEN (BMA456W_ANY_MOT_LEN + BMA456W_NO_MOT_OFFSET) + +/*! @name Maximum valid read write length is size of config file array */ +#define BMA456W_RD_WR_MAX_LEN ((uint16_t)sizeof(bma456w_config_file)) + +/**************************************************************/ +/**\name Step Counter/Detector/Activity */ +/**************************************************************/ +/**\name Step counter/activity enable macros */ +#define BMA456W_STEP_CNTR_EN_MSK UINT8_C(0x10) +#define BMA456W_STEP_ACT_EN_MSK UINT8_C(0x20) + +/**\name Step counter water-mark macros */ +#define BMA456W_STEP_CNTR_WM_MSK UINT16_C(0x03FF) + +/**\name Step counter reset macros */ +#define BMA456W_STEP_CNTR_RST_POS UINT8_C(2) +#define BMA456W_STEP_CNTR_RST_MSK UINT8_C(0x04) + +/**\name Step detector enable macros */ +#define BMA456W_STEP_DETECTOR_EN_POS UINT8_C(3) +#define BMA456W_STEP_DETECTOR_EN_MSK UINT8_C(0x08) + +/**\name Wrist-wear enable macros */ +#define BMA456W_WRIST_WEAR_WAKEUP_EN_MSK UINT8_C(0x10) +#define BMA456W_WRIST_WEAR_WAKEUP_EN_POS UINT8_C(4) + +/**\name Step count output length */ +#define BMA456W_STEP_CNTR_DATA_SIZE UINT8_C(4) + +/**************************************************************/ +/**\name Any/No-Motion */ +/**************************************************************/ +/**\name Any/No-motion threshold macros */ +#define BMA456W_ANY_NO_MOT_THRES_MSK UINT16_C(0x07FF) + +/**\name Any/No-motion duration macros */ +#define BMA456W_ANY_NO_MOT_DUR_MSK UINT16_C(0x1FFF) + +/**\name Any/No-motion enable macros */ +#define BMA456W_ANY_NO_MOT_AXIS_EN_POS UINT8_C(0x0D) +#define BMA456W_ANY_NO_MOT_AXIS_EN_MSK UINT16_C(0xE000) + +/**************************************************************/ +/**\name Wrist wear wakeup */ +/**************************************************************/ +/**\name Mask definition for minimum angle focus */ +#define BMA456W_WRIST_WEAR_WAKEUP_MIN_ANG_FOCUS_MSK UINT16_C(0xFFFF) + +/**\name Mask definition for minimum angle non focus */ +#define BMA456W_WRIST_WEAR_WAKEUP_MIN_ANG_NON_FOCUS_MSK UINT16_C(0xFFFF) + +/**\name Mask definition for angle landscape right */ +#define BMA456W_WRIST_WEAR_WAKEUP_ANG_LSCAPE_RHT_MSK UINT8_C(0xFF) + +/**\name Mask definition for angle landscape left */ +#define BMA456W_WRIST_WEAR_WAKEUP_ANG_LSCAPE_LEFT_MSK UINT16_C(0XFF00) + +/**\name Position definition for angle landscape left */ +#define BMA456W_WRIST_WEAR_WAKEUP_ANG_LSCAPE_LEFT_POS UINT8_C(8) + +/**\name Mask definition for angle portrait down */ +#define BMA456W_WRIST_WEAR_WAKEUP_ANG_PORTRAIT_DOWN_MSK UINT8_C(0xFF) + +/**\name Mask definition for angle portrait up */ +#define BMA456W_WRIST_WEAR_WAKEUP_ANG_PORTRAIT_UP_MSK UINT16_C(0xFF00) + +/**\name Position definition for angle portrait up */ +#define BMA456W_WRIST_WEAR_WAKEUP_ANG_PORTRAIT_UP_POS UINT8_C(8) + +/**\name Mask definition for minimum duration moved */ +#define BMA456W_WRIST_WEAR_WAKEUP_MIN_DUR_MOVED_MSK UINT8_C(0xFF) + +/**\name Mask definition for minimum duration quite */ +#define BMA456W_WRIST_WEAR_WAKEUP_MIN_DUR_QUITE_MSK UINT16_C(0xFF00) + +/**\name Position definition for minimum duration quite */ +#define BMA456W_WRIST_WEAR_WAKEUP_MIN_DUR_QUITE_POS UINT8_C(8) + +/**************************************************************/ +/**\name User macros */ +/**************************************************************/ +/**\name Any-motion/No-motion axis enable macros */ +#define BMA456W_X_AXIS_EN UINT8_C(0x01) +#define BMA456W_Y_AXIS_EN UINT8_C(0x02) +#define BMA456W_Z_AXIS_EN UINT8_C(0x04) +#define BMA456W_EN_ALL_AXIS UINT8_C(0x07) +#define BMA456W_DIS_ALL_AXIS UINT8_C(0x00) + +/**\name Feature enable macros for the sensor */ +#define BMA456W_STEP_CNTR UINT8_C(0x01) +#define BMA456W_STEP_ACT UINT8_C(0x02) +#define BMA456W_WRIST_WEAR_WAKEUP UINT8_C(0x04) + +/**\name Interrupt status macros */ +#define BMA456W_STEP_CNTR_INT UINT8_C(0x02) +#define BMA456W_ACTIVITY_INT UINT8_C(0x04) +#define BMA456W_WRIST_WEAR_WAKEUP_INT UINT8_C(0x08) +#define BMA456W_ANY_MOT_INT UINT8_C(0x20) +#define BMA456W_NO_MOT_INT UINT8_C(0x40) +#define BMA456W_ERROR_INT UINT8_C(0x80) + +/**\name Activity recognition macros */ +#define BMA456W_USER_STATIONARY UINT8_C(0x00) +#define BMA456W_USER_WALKING UINT8_C(0x01) +#define BMA456W_USER_RUNNING UINT8_C(0x02) +#define BMA456W_STATE_INVALID UINT8_C(0x03) + +/******************************************************************************/ +/*! @name Structure Declarations */ +/******************************************************************************/ + +/*! + * @brief Any/No-motion configuration + */ +struct bma456w_any_no_mot_config +{ + /*! Expressed in 50 Hz samples (20 ms) */ + uint16_t duration; + + /*! Threshold value for Any-motion/No-motion detection in + * 5.11g format + */ + uint16_t threshold; + + /*! To enable selected axes */ + uint8_t axes_en; +}; + +/*! + * @brief Step counter param settings + */ +struct bma456w_stepcounter_settings +{ + /*! Step Counter param 1 */ + uint16_t param1; + + /*! Step Counter param 2 */ + uint16_t param2; + + /*! Step Counter param 3 */ + uint16_t param3; + + /*! Step Counter param 4 */ + uint16_t param4; + + /*! Step Counter param 5 */ + uint16_t param5; + + /*! Step Counter param 6 */ + uint16_t param6; + + /*! Step Counter param 7 */ + uint16_t param7; + + /*! Step Counter param 8 */ + uint16_t param8; + + /*! Step Counter param 9 */ + uint16_t param9; + + /*! Step Counter param 10 */ + uint16_t param10; + + /*! Step Counter param 11 */ + uint16_t param11; + + /*! Step Counter param 12 */ + uint16_t param12; + + /*! Step Counter param 13 */ + uint16_t param13; + + /*! Step Counter param 14 */ + uint16_t param14; + + /*! Step Counter param 15 */ + uint16_t param15; + + /*! Step Counter param 16 */ + uint16_t param16; + + /*! Step Counter param 17 */ + uint16_t param17; + + /*! Step Counter param 18 */ + uint16_t param18; + + /*! Step Counter param 19 */ + uint16_t param19; + + /*! Step Counter param 20 */ + uint16_t param20; + + /*! Step Counter param 21 */ + uint16_t param21; + + /*! Step Counter param 22 */ + uint16_t param22; + + /*! Step Counter param 23 */ + uint16_t param23; + + /*! Step Counter param 24 */ + uint16_t param24; + + /*! Step Counter param 25 */ + uint16_t param25; +}; + +/*! + * @brief Wrist wear wakeup param settings + */ +struct bma456w_wrist_wear_wakeup_params +{ + /*! Cosine of minimum expected attitude change of the + * device within 1 second time window + * when moving within focus position. */ + uint16_t min_angle_focus; + + /*!Cosine of minimum expected attitude change of the + * device within 1 second time window + * when moving from non-focus to focus position.*/ + uint16_t min_angle_non_focus; + + /*! Sine of the maximum allowed tilt angle in + * landscape right direction of the device, + * when it is in focus position */ + uint8_t angle_landscape_right; + + /*! Sine of the maximum allowed tilt angle in + * landscape left direction of the device, + * when it is in focus position */ + uint8_t angle_landscape_left; + + /*! Sine of the maximum allowed forward + * tilt angle in portrait up direction + * of the device, when it is in focus position */ + uint8_t angle_portrait_up; + + /*! Sine of the maximum allowed backward tilt + * angle in portrait down direction of + * the device, when it is in focus position */ + uint8_t angle_portrait_down; + + /*! Minimum duration the arm should + * be moved while performing gesture.*/ + uint8_t min_dur_moved; + + /*! Minimum duration the arm should be + * static between two consecutive gestures */ + uint8_t min_dur_quite; +}; + +/***************************************************************************/ + +/*! BMA456W User Interface function prototypes + ****************************************************************************/ + +/** + * \ingroup bma456w + * \defgroup bma456wApiInit Initialization + * @brief Initialize the sensor and device structure + */ + +/*! + * \ingroup bma456wApiInit + * \page bma456w_api_bma456w_init bma456w_init + * \code + * int8_t bma456w_init(struct bma4_dev *dev); + * \endcode + * @details This API is the entry point. + * Call this API before using all other APIs. + * This API reads the chip-id of the sensor and sets the resolution. + * + * @param[in,out] dev : Structure instance of bma4_dev + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +int8_t bma456w_init(struct bma4_dev *dev); + +/** + * \ingroup bma456w + * \defgroup bma456wApiConfig ConfigFile + * @brief Write binary configuration in the sensor + */ + +/*! + * \ingroup bma456wApiConfig + * \page bma456w_api_bma456w_write_config_file bma456w_write_config_file + * \code + * int8_t bma456w_write_config_file(struct bma4_dev *dev); + * \endcode + * @details This API is used to upload the config file to enable the features of + * the sensor. + * + * @param[in] dev : Structure instance of bma4_dev. + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +int8_t bma456w_write_config_file(struct bma4_dev *dev); + +/** + * \ingroup bma456w + * \defgroup bma456wApiConfigId ConfigId + * @brief Get Configuration ID of the sensor + */ + +/*! + * \ingroup bma456wApiConfig + * \page bma456w_api_bma456w_get_config_id bma456w_get_config_id + * \code + * int8_t bma456w_get_config_id(uint16_t *config_id, struct bma4_dev *dev); + * \endcode + * @details This API is used to get the configuration id of the sensor. + * + * @param[out] config_id : Pointer variable used to store the configuration id. + * @param[in] dev : Structure instance of bma4_dev. + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +int8_t bma456w_get_config_id(uint16_t *config_id, struct bma4_dev *dev); + +/** + * \ingroup bma456w + * \defgroup bma456wApiMapInt Map / Unmap Interrupt + * @brief Map / Unmap user provided interrupt to interrupt pin1 or pin2 of the sensor + */ + +/*! + * \ingroup bma456wApiMapInt + * \page bma456w_api_bma456w_map_interrupt bma456w_map_interrupt + * \code + * int8_t bma456w_map_interrupt(uint8_t int_line, uint16_t int_map, uint8_t enable, struct bma4_dev *dev); + * \endcode + * @details This API sets/unsets the user provided interrupt to either + * interrupt pin1 or pin2 in the sensor. + * + * @param[in] int_line: Variable to select either interrupt pin1 or pin2. + * + *@verbatim + * int_line | Macros + * ------------|------------------- + * 0x00 | BMA4_INTR1_MAP + * 0x01 | BMA4_INTR2_MAP + *@endverbatim + * + * @param[in] int_map : Variable to specify the interrupts. + * @param[in] enable : Variable to specify mapping or unmapping of interrupts. + * + *@verbatim + * enable | Macros + * --------|------------------- + * 0x00 | BMA4_DISABLE + * 0x01 | BMA4_ENABLE + *@endverbatim + * + * @param[in] dev : Structure instance of bma4_dev. + * + * @note Below macros specify the interrupts. + * + * Feature Interrupts + * - BMA456W_STEP_CNTR_INT + * - BMA456W_ACTIVITY_INT + * - BMA456W_WRIST_WEAR_INT + * - BMA456W_ANY_MOT_INT + * - BMA456W_NO_MOT_INT + * - BMA456W_ERROR_INT + * + * Hardware Interrupts + * - BMA4_FIFO_FULL_INT + * - BMA4_FIFO_WM_INT + * - BMA4_DATA_RDY_INT + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +int8_t bma456w_map_interrupt(uint8_t int_line, uint16_t int_map, uint8_t enable, struct bma4_dev *dev); + +/** + * \ingroup bma456w + * \defgroup bma456wApiIntS Interrupt Status + * @brief Read interrupt status of the sensor + */ + +/*! + * \ingroup bma456wApiIntS + * \page bma456w_api_bma456w_read_int_status bma456w_read_int_status + * \code + * int8_t bma456w_read_int_status(uint16_t *int_status, struct bma4_dev *dev); + * \endcode + * @details This API reads the bma456w interrupt status from the sensor. + * + * @param[out] int_status : Variable to store the interrupt status read from + * the sensor. + * @param[in] dev : Structure instance of bma4_dev. + * + * @note Below macros are used to check the interrupt status. + * + * Feature Interrupts + * - BMA456W_STEP_CNTR_INT + * - BMA456W_ACTIVITY_INT + * - BMA456W_WRIST_WEAR_INT + * - BMA456W_ANY_MOT_INT + * - BMA456W_NO_MOT_INT + * - BMA456W_ERROR_INT + * + * Hardware Interrupts + * - BMA4_FIFO_FULL_INT + * - BMA4_FIFO_WM_INT + * - BMA4_DATA_RDY_INT + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +int8_t bma456w_read_int_status(uint16_t *int_status, struct bma4_dev *dev); + +/** + * \ingroup bma456w + * \defgroup bma456wApiFeat Sensor Feature + * @brief Enables / Disables features of the sensor + */ + +/*! + * \ingroup bma456wApiFeat + * \page bma456w_api_bma456w_feature_enable bma456w_feature_enable + * \code + * int8_t bma456w_feature_enable(uint8_t feature, uint8_t enable, struct bma4_dev *dev); + * \endcode + * @details This API enables/disables the features of the sensor. + * + * @param[in] feature : Variable to specify the features which are to be set in + * bma456w sensor. + * @param[in] enable : Variable which specifies whether to enable or disable the + * features in the bma456w sensor. + * + *@verbatim + * enable | Macros + * --------|------------------- + * 0x00 | BMA4_DISABLE + * 0x01 | BMA4_ENABLE + *@endverbatim + * + * @param[in] dev : Structure instance of bma4_dev. + * + * @note User should use the below macros to enable or disable the + * features of bma456w sensor + * + * - BMA456W_STEP_CNTR + * - BMA456W_ACTIVITY + * - BMA456W_WAKEUP + * - BMA456W_WRIST_WEAR + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +int8_t bma456w_feature_enable(uint8_t feature, uint8_t enable, struct bma4_dev *dev); + +/** + * \ingroup bma456w + * \defgroup bma456wApiRemap Remap Axes + * @brief Set / Get x, y and z axis re-mapping in the sensor + */ + +/*! + * \ingroup bma456wApiRemap + * \page bma456w_api_bma456w_set_remap_axes bma456w_set_remap_axes + * \code + * int8_t bma456w_set_remap_axes(const struct bma4_remap *remap_data, struct bma4_dev *dev); + * \endcode + * @details This API performs x, y and z axis remapping in the sensor. + * + * @param[in] remap_axes : Structure instance of bma4_remap + * @param[in] dev : Structure instance of bma4_dev + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +int8_t bma456w_set_remap_axes(const struct bma4_remap *remap_axes, struct bma4_dev *dev); + +/*! + * \ingroup bma456wApiRemap + * \page bma456w_api_bma456w_get_remap_axes bma456w_get_remap_axes + * \code + * int8_t bma456w_get_remap_axes(struct bma4_remap *remap_data, struct bma4_dev *dev); + * \endcode + * @details This API reads the x, y and z axis remap data from the sensor. + * + * @param[out] remap_axes : Structure instance of bma4_remap + * @param[in] dev : Structure instance of bma4_dev + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +int8_t bma456w_get_remap_axes(struct bma4_remap *remap_axes, struct bma4_dev *dev); + +/** + * \ingroup bma456w + * \defgroup bma456wApiStepC Step counter + * @brief Operations of step counter feature of the sensor + */ + +/*! + * \ingroup bma456wApiStepC + * \page bma456w_api_bma456w_step_counter_set_watermark bma456w_step_counter_set_watermark + * \code + * int8_t bma456w_step_counter_set_watermark(uint16_t step_counter_wm, struct bma4_dev *dev); + * \endcode + * @details This API sets the watermark level for step counter interrupt in + * the sensor. + * + * @param[in] step_counter_wm : Variable which specifies watermark level + * count + * @note Valid values are from 1 to 1023 + * @note Value 0 is used for step detector interrupt + * + * @param[in] dev : Structure instance of bma4_dev + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +int8_t bma456w_step_counter_set_watermark(uint16_t step_counter_wm, struct bma4_dev *dev); + +/*! + * \ingroup bma456wApiStepC + * \page bma456w_api_bma456w_step_counter_get_watermark bma456w_step_counter_get_watermark + * \code + * int8_t bma456w_step_counter_get_watermark(uint16_t *step_counter_wm, struct bma4_dev *dev); + * \endcode + * @details This API gets the water mark level set for step counter interrupt + * in the sensor + * + * @param[out] step_counter_wm : Pointer variable which stores the water mark + * level read from the sensor. + * @note valid values are from 1 to 1023 + * @note value 0 is used for step detector interrupt + * + * @param[in] dev : Structure instance of bma4_dev + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +int8_t bma456w_step_counter_get_watermark(uint16_t *step_counter_wm, struct bma4_dev *dev); + +/*! + * \ingroup bma456wApiStepC + * \page bma456w_api_bma456w_reset_step_counter bma456w_reset_step_counter + * \code + * int8_t bma456w_reset_step_counter(struct bma4_dev *dev); + * \endcode + * @details This API resets the counted steps of step counter. + * + * @param[in] dev : structure instance of bma4_dev + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +int8_t bma456w_reset_step_counter(struct bma4_dev *dev); + +/*! + * \ingroup bma456wApiStepC + * \page bma456w_api_bma456w_step_counter_output bma456w_step_counter_output + * \code + * int8_t bma456w_step_counter_output(uint32_t *step_count, struct bma4_dev *dev); + * \endcode + * @details This API gets the number of counted steps of the step counter + * feature from the sensor. + * + * @param[out] step_count : Pointer variable which stores counted steps + * read from the sensor. + * @param[in] dev : Structure instance of bma4_dev + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +int8_t bma456w_step_counter_output(uint32_t *step_count, struct bma4_dev *dev); + +/** + * \ingroup bma456w + * \defgroup bma456wApiAct Activity Feature + * @brief Get output for activity feature of the sensor + */ + +/*! + * \ingroup bma456wApiAct + * \page bma456w_api_bma456w_activity_output bma456w_activity_output + * \code + * int8_t bma456w_activity_output(uint8_t *activity, struct bma4_dev *dev); + * \endcode + * @details This API gets the output for activity feature. + * + * @param[out] activity : Pointer variable which stores activity output read + * from the sensor. + * + *@verbatim + * activity | State + * --------------|------------------------ + * 0x00 | BMA456W_USER_STATIONARY + * 0x01 | BMA456W_USER_WALKING + * 0x02 | BMA456W_USER_RUNNING + * 0x03 | BMA456W_STATE_INVALID + *@endverbatim + * + * @param[in] dev : Structure instance of bma4_dev + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +int8_t bma456w_activity_output(uint8_t *activity, struct bma4_dev *dev); + +/*! + * \ingroup bma456wApiStepC + * \page bma456w_api_bma456w_stepcounter_get_parameter bma456w_stepcounter_get_parameter + * \code + * int8_t bma456w_stepcounter_get_parameter(struct bma456w_stepcounter_settings *setting, struct bma4_dev *dev); + * \endcode + * @details This API gets the parameter1 to parameter7 settings of the step + * counter feature. + * + * @param[out] setting : Pointer to structure variable which stores the + * parameter1 to parameter7 read from the sensor. + * @param[in] dev : Structure instance of bma4_dev + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +int8_t bma456w_stepcounter_get_parameter(struct bma456w_stepcounter_settings *setting, struct bma4_dev *dev); + +/*! + * \ingroup bma456wApiStepC + * \page bma456w_api_bma456w_stepcounter_set_parameter bma456w_stepcounter_set_parameter + * \code + * int8_t bma456w_stepcounter_set_parameter(const struct bma456w_stepcounter_settings *setting, struct bma4_dev *dev); + * \endcode + * @details This API sets the parameter1 to parameter7 settings of the step + * counter feature in the sensor. + * + * @param[in] setting : Pointer to structure variable which stores the + * parameter1 to parameter7 settings read from the sensor. + * @param[in] dev : Structure instance of bma4_dev + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +int8_t bma456w_stepcounter_set_parameter(const struct bma456w_stepcounter_settings *setting, struct bma4_dev *dev); + +/** + * \ingroup bma456w + * \defgroup bma456wApiStepD Step detector + * @brief Operations of step detector feature of the sensor + */ + +/*! + * \ingroup bma456wApiStepD + * \page bma456w_api_bma421_step_detector_enable bma456w_step_detector_enable + * \code + * int8_t bma456w_step_detector_enable(uint8_t enable, struct bma4_dev *dev); + * \endcode + * @details This API enables or disables the step detector feature in the + * sensor. + * + * @param[in] enable : Variable used to enable or disable step detector + * + *@verbatim + * enable | Macros + * --------|------------------- + * 0x00 | BMA4_DISABLE + * 0x01 | BMA4_ENABLE + *@endverbatim + * + * @param[in] dev : Structure instance of bma4_dev + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +int8_t bma456w_step_detector_enable(uint8_t enable, struct bma4_dev *dev); + +/** + * \ingroup bma456w + * \defgroup bma456wApiAnyMot Any motion Feature + * @brief Functions of Any motion feature of the sensor + */ + +/*! + * \ingroup bma456wApiAnyMot + * \page bma456w_api_bma456w_set_any_motion_config bma456w_set_any_motion_config + * \code + * int8_t bma456w_set_any_motion_config(const struct bma456w_anymotion_config *any_motion, struct bma4_dev *dev); + * \endcode + * @details This API sets the configuration of any-motion feature in the sensor + * This API enables/disables the any-motion feature according to the axis set. + * + * @param[in] any_mot : Pointer to structure variable to configure + * any-motion. + * + * @verbatim + * ------------------------------------------------------------------------- + * Structure parameters | Description + * --------------------------------|---------------------------------------- + * | Defines the number of + * | consecutive data points for + * | which the threshold condition + * duration | must be respected, for interrupt + * | assertion. It is expressed in + * | 50 Hz samples (20 ms). + * | Range is 0 to 163sec. + * | Default value is 5 = 100ms. + * --------------------------------|---------------------------------------- + * | Slope threshold value for + * | Any-motion detection + * threshold | in 5.11g format. + * | Range is 0 to 1g. + * | Default value is 0xAA = 83mg. + * --------------------------------|---------------------------------------- + * | Enables the feature on a per-axis + * axis_en | basis. + * --------------------------------------------------------------------------- + * @endverbatim + * + *@verbatim + * Value | axis_en + * ---------|------------------------- + * 0x00 | BMA456W_ANY_NO_MOT_ALL_AXIS_DIS + * 0x01 | BMA456W_ANY_NO_MOT_X_AXIS_EN + * 0x02 | BMA456W_ANY_NO_MOT_Y_AXIS_EN + * 0x04 | BMA456W_ANY_NO_MOT_Z_AXIS_EN + * 0x07 | BMA456W_ANY_NO_MOT_ALL_AXIS_EN + *@endverbatim + * + * @param[in] dev : Structure instance of bma4_dev + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +int8_t bma456w_set_any_mot_config(const struct bma456w_any_no_mot_config *any_mot, struct bma4_dev *dev); + +/*! + * \ingroup bma456wApiAnyMot + * \page bma456w_api_bma456w_get_any_motion_config bma456w_get_any_motion_config + * \code + * int8_t bma456w_get_any_motion_config(struct bma456w_anymotion_config *any_motion, struct bma4_dev *dev); + * \endcode + * @details This API gets the configuration of any-motion feature from the + * sensor. + * + * @param[out] any_mot : Pointer to structure variable to configure + * any-motion. + * + * @verbatim + * ------------------------------------------------------------------------- + * Structure parameters | Description + * --------------------------------|---------------------------------------- + * | Defines the number of + * | consecutive data points for + * | which the threshold condition + * duration | must be respected, for interrupt + * | assertion. It is expressed in + * | 50 Hz samples (20 ms). + * | Range is 0 to 163sec. + * | Default value is 5 = 100ms. + * --------------------------------|---------------------------------------- + * | Slope threshold value for + * | Any-motion detection + * threshold | in 5.11g format. + * | Range is 0 to 1g. + * | Default value is 0xAA = 83mg. + * --------------------------------|----------------------------------------- + * | Enables the feature on a per-axis + * axis_en | basis. + * --------------------------------------------------------------------------- + * @endverbatim + * + *@verbatim + * Value | axis_en + * ---------|------------------------- + * 0x00 | BMA456W_ANY_NO_MOT_ALL_AXIS_DIS + * 0x01 | BMA456W_ANY_NO_MOT_X_AXIS_EN + * 0x02 | BMA456W_ANY_NO_MOT_Y_AXIS_EN + * 0x04 | BMA456W_ANY_NO_MOT_Z_AXIS_EN + * 0x07 | BMA456W_ANY_NO_MOT_ALL_AXIS_EN + *@endverbatim + * + * @param[in] dev : Structure instance of bma4_dev + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +int8_t bma456w_get_any_mot_config(struct bma456w_any_no_mot_config *any_mot, struct bma4_dev *dev); + +/** + * \ingroup bma456w + * \defgroup bma456wApiNomot No-Motion Feature + * @brief Operations of no-motion feature of the sensor + */ + +/*! + * \ingroup bma456wApiNomot + * \page bma456w_api_bma456w_set_no_motion_config bma456w_set_no_motion_config + * \code + * int8_t bma456w_set_no_motion_config(const struct bma456w_nomotion_config *no_motion, struct bma4_dev *dev); + * \endcode + * @details This API sets the configuration of no-motion feature in the sensor + * This API enables/disables the no-motion feature according to the axis set. + * + * @param[in] no_mot : Pointer to structure variable to configure + * no-motion. + * + * @verbatim + * ------------------------------------------------------------------------- + * Structure parameters | Description + * --------------------------------|---------------------------------------- + * | Defines the number of + * | consecutive data points for + * | which the threshold condition + * duration | must be respected, for interrupt + * | assertion. It is expressed in + * | 50 Hz samples (20 ms). + * | Range is 0 to 163sec. + * | Default value is 5 = 100ms. + * --------------------------------|---------------------------------------- + * | Slope threshold value for + * | No-motion detection + * threshold | in 5.11g format. + * | Range is 0 to 1g. + * | Default value is 0xAA = 83mg. + * --------------------------------|---------------------------------------- + * | Enables the feature on a per-axis + * axis_en | basis. + * --------------------------------------------------------------------------- + * @endverbatim + * + *@verbatim + * Value | axis_en + * ---------|------------------------- + * 0x00 | BMA456W_ANY_NO_MOT_ALL_AXIS_DIS + * 0x01 | BMA456W_ANY_NO_MOT_X_AXIS_EN + * 0x02 | BMA456W_ANY_NO_MOT_Y_AXIS_EN + * 0x04 | BMA456W_ANY_NO_MOT_Z_AXIS_EN + * 0x07 | BMA456W_ANY_NO_MOT_ALL_AXIS_EN + *@endverbatim + * + * @param[in] dev : Structure instance of bma4_dev + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +int8_t bma456w_set_no_mot_config(const struct bma456w_any_no_mot_config *no_mot, struct bma4_dev *dev); + +/*! + * \ingroup bma456wApiNomot + * \page bma456w_api_bma456w_get_no_motion_config bma456w_get_no_motion_config + * \code + * int8_t bma456w_get_no_motion_config(struct bma456w_nomotion_config *no_motion, struct bma4_dev *dev); + * \endcode + * @details This API gets the configuration of no-motion feature from the + * sensor. + * + * @param[out] no_mot : Pointer to structure variable to configure + * no-motion. + * + * @verbatim + * ------------------------------------------------------------------------- + * Structure parameters | Description + * --------------------------------|---------------------------------------- + * | Defines the number of + * | consecutive data points for + * | which the threshold condition + * duration | must be respected, for interrupt + * | assertion. It is expressed in + * | 50 Hz samples (20 ms). + * | Range is 0 to 163sec. + * | Default value is 5 = 100ms. + * --------------------------------|---------------------------------------- + * | Slope threshold value for + * | No-motion detection + * threshold | in 5.11g format. + * | Range is 0 to 1g. + * | Default value is 0xAA = 83mg. + * --------------------------------|----------------------------------------- + * | Enables the feature on a per-axis + * axis_en | basis. + * --------------------------------------------------------------------------- + * @endverbatim + * + *@verbatim + * Value | axis_en + * ---------|------------------------- + * 0x00 | BMA456W_ANY_NO_MOT_ALL_AXIS_DIS + * 0x01 | BMA456W_ANY_NO_MOT_X_AXIS_EN + * 0x02 | BMA456W_ANY_NO_MOT_Y_AXIS_EN + * 0x04 | BMA456W_ANY_NO_MOT_Z_AXIS_EN + * 0x07 | BMA456W_ANY_NO_MOT_ALL_AXIS_EN + *@endverbatim + * + * @param[in] dev : Structure instance of bma4_dev + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +int8_t bma456w_get_no_mot_config(struct bma456w_any_no_mot_config *no_mot, struct bma4_dev *dev); + +/** + * \ingroup bma456w + * \defgroup bma456wApiVersionConfig Version Config + * @brief Get version configuration of the sensor + */ + +/*! + * \ingroup bma456wApiVersionConfig + * \page bma456w_api_bma456w_get_version_config bma456w_get_version_config + * \code + * int8_t bma456w_get_version_config(uint16_t *config_major, uint16_t *config_minor, struct bma4_dev *dev); + * \endcode + * @details This API is used to get the config file major and minor information. + * + * @param[out] config_major : Pointer to data buffer to store the config major. + * @param[out] config_minor : Pointer to data buffer to store the config minor. + * @param[in, out] dev : Structure instance of bma4_dev. + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +int8_t bma456w_get_version_config(uint16_t *config_major, uint16_t *config_minor, struct bma4_dev *dev); + +/** + * \ingroup bma456w + * \defgroup bma456wApiWristwearwakeup Wrist wear wakeup + * @brief Wrist wear wakeup configurations of the sensor + */ + +/*! + * \ingroup bma456wApiWristwearwakeup + * \page bma456w_api_bma456w_set_wrist_wear_wakeup_param_config bma456w_set_wrist_wear_wakeup_param_config + * \code + * int8_t bma456w_set_wrist_wear_wakeup_param_config(const struct bma456w_wrist_wear_wakeup_params *setting, struct bma4_dev *dev); + * \endcode + * @details This API sets the configuration of wrist wear wakeup feature from the + * sensor. + * + * @param[in] setting : Pointer to structure variable to configure + * wrist wear wakeup. + * + * @verbatim + * --------------------------------|----------------------------------------- + * Structure parameters | Description + * --------------------------------|---------------------------------------- + * | Cosine of minimum expected attitude change of the + * | device within 1 second time window + * Minimum angle focus | when moving within focus position. + * | The parameter is scaled by 2048 + * | i.e. 2048 * cos(angle). + * | Range is 1024 to 1774. Default is 1774. + * | + * --------------------------------|---------------------------------------- + * | Cosine of minimum expected attitude change of the + * | device within 1 second time window + * Minimum angle non focus | when moving from non-focus to focus position + * | The parameter is scaled by 2048 + * | i.e. 2048 * cos(angle). Range is 1448 to 1856. + * | Default value is 1522. + * --------------------------------|----------------------------------------- + * | Sine of the maximum allowed tilt angle + * | in landscape right direction of the device, + * Angle landscape right | when it is in focus position + * | (i.e. user is able to comfortably + * | look at the dial of wear device). + * | The configuration parameter is scaled + * | by 256 i.e. 256 * sin(angle). Range is + * | 88 to 128. Default value is 128. + * --------------------------------|------------------------------------------- + * | Sine of the maximum allowed tilt angle + * | in landscape left direction of the device, + * Angle landscape left | when it is in focus position + * | (i.e. user is able to comfortably look at + * | the dial of wear device). + * | The configuration parameter is scaled by 256 + * | i.e. 256 * sin(angle). Range is 88 to 128. + * | Default value is 128. + * --------------------------------|----------------------------------------- + * | Sine of the maximum allowed backward tilt + * | angle in portrait down direction of the device, + * Angle portrait down | when it is in focus position (i.e. user is + * | able to comfortably look at the dial of wear device). + * | The configuration parameter is scaled by 256 + * | i.e. 256 * sin(angle). + * | Range is 0 to179. Default value is 22. + * | basis. + * --------------------------------|------------------------------------------- + * | Sine of the maximum allowed forward tilt angle + * | in portrait up direction of the device, + * Angle portrait up | when it is in focus position + * | (i.e. user is able to comfortably look at + * | the dial of wear device). + * | The configuration parameter is scaled by 256 i.e. + * | 256 * sin(angle). + * | Range is 222 to 247. Default value is 241. + * --------------------------------|----------------------------------------- + * | Minimum duration the arm should be moved + * Minimum duration moved | while performing gesture. + * | Range: 1 to 10, resolution = 20 ms + * --------------------------------|------------------------------------------ + * | Minimum duration the arm should be + * Minimum duration quite | static between two consecutive gestures. + * | Range: 1 to 10, resolution = 20 ms + * --------------------------------|----------------------------------------- + * @endverbatim + * + * @param[in] dev : Structure instance of bma4_dev + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +int8_t bma456w_set_wrist_wear_wakeup_param_config(const struct bma456w_wrist_wear_wakeup_params *setting, + struct bma4_dev *dev); + +/*! + * \ingroup bma456wApiWristwearwakeup + * \page bma456w_api_bma456w_get_wrist_wear_wakeup_param_config bma456w_set_wrist_wear_wakeup_param_config + * \code + * int8_t bma456w_get_wrist_wear_wakeup_param_config(struct bma456w_wrist_wear_wakeup_params *setting, struct bma4_dev *dev); + * \endcode + * @details This API gets the configuration of wrist wear wakeup feature from the + * sensor. + * + * @param[in] setting : Pointer to structure variable to store + * wrist wear wakeup. + * + * @verbatim + * --------------------------------|----------------------------------------- + * Structure parameters | Description + * --------------------------------|---------------------------------------- + * | Cosine of minimum expected attitude change of the + * | device within 1 second time window + * Minimum angle focus | when moving within focus position. + * | The parameter is scaled by 2048 + * | i.e. 2048 * cos(angle). + * | Range is 1024 to 1774. Default is 1774. + * | + * --------------------------------|---------------------------------------- + * | Cosine of minimum expected attitude change of the + * | device within 1 second time window + * Minimum angle non focus | when moving from non-focus to focus position + * | The parameter is scaled by 2048 + * | i.e. 2048 * cos(angle). Range is 1448 to 1856. + * | Default value is 1522. + * --------------------------------|----------------------------------------- + * | Sine of the maximum allowed tilt angle + * | in landscape right direction of the device, + * Angle landscape right | when it is in focus position + * | (i.e. user is able to comfortably + * | look at the dial of wear device). + * | The configuration parameter is scaled + * | by 256 i.e. 256 * sin(angle). Range is + * | 88 to 128. Default value is 128. + * --------------------------------|------------------------------------------- + * | Sine of the maximum allowed tilt angle + * | in landscape left direction of the device, + * Angle landscape left | when it is in focus position + * | (i.e. user is able to comfortably look at + * | the dial of wear device). + * | The configuration parameter is scaled by 256 + * | i.e. 256 * sin(angle). Range is 88 to 128. + * | Default value is 128. + * --------------------------------|----------------------------------------- + * | Sine of the maximum allowed backward tilt + * | angle in portrait down direction of the device, + * Angle portrait down | when it is in focus position (i.e. user is + * | able to comfortably look at the dial of wear device). + * | The configuration parameter is scaled by 256 + * | i.e. 256 * sin(angle). + * | Range is 0 to179. Default value is 22. + * | basis. + * --------------------------------|------------------------------------------- + * | Sine of the maximum allowed forward tilt angle + * | in portrait up direction of the device, + * Angle portrait up | when it is in focus position + * | (i.e. user is able to comfortably look at + * | the dial of wear device). + * | The configuration parameter is scaled by 256 i.e. + * | 256 * sin(angle). + * | Range is 222 to 247. Default value is 241. + * --------------------------------|----------------------------------------- + * | Minimum duration the arm should be moved + * Minimum duration moved | while performing gesture. + * | Range: 1 to 10, resolution = 20 ms + * --------------------------------|------------------------------------------ + * | Minimum duration the arm should be + * Minimum duration quite | static between two consecutive gestures. + * | Range: 1 to 10, resolution = 20 ms + * --------------------------------|----------------------------------------- + * @endverbatim + * + * @param[in] dev : Structure instance of bma4_dev + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +int8_t bma456w_get_wrist_wear_wakeup_param_config(struct bma456w_wrist_wear_wakeup_params *setting, + struct bma4_dev *dev); + +#ifdef __cplusplus +} +#endif /*End of CPP guard */ + +#endif /*End of header guard macro */ diff --git a/components/bma456/bma456w_examples/accel_foc/Makefile b/components/bma456/bma456w_examples/accel_foc/Makefile new file mode 100644 index 0000000..29fa113 --- /dev/null +++ b/components/bma456/bma456w_examples/accel_foc/Makefile @@ -0,0 +1,18 @@ +COINES_INSTALL_PATH ?= ../../../.. + +EXAMPLE_FILE ?= accel_foc.c + +API_LOCATION ?= ../.. + +COMMON_LOCATION ?= .. + +C_SRCS += \ +$(API_LOCATION)/bma4.c \ +$(API_LOCATION)/bma456w.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/components/bma456/bma456w_examples/accel_foc/accel_foc.c b/components/bma456/bma456w_examples/accel_foc/accel_foc.c new file mode 100644 index 0000000..c229c4d --- /dev/null +++ b/components/bma456/bma456w_examples/accel_foc/accel_foc.c @@ -0,0 +1,741 @@ +/**\ + * Copyright (c) 2022 Bosch Sensortec GmbH. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + **/ + +/******************************************************************************/ +/*! Header Files */ +#include +#include +#include +#include +#include + +#include "bma456w.h" +#include "common.h" +#include "coines.h" + +/******************************************************************************/ +/*! Macro Definitions */ + +#define ACCEL_SAMPLE_COUNT UINT8_C(100) + +/******************************************************************************/ +/*! Global Variable Declaration */ + +/* Structure to store temporary axes data values */ +struct temp_axes_val +{ + /* X data */ + int32_t x; + + /* Y data */ + int32_t y; + + /* Z data */ + int32_t z; +}; + +/******************************************************************************/ +/*! Static Function Declaration */ + +/*! + * @brief This internal API is used perform accel foc and determine limits based on range + * + * @param[in] range : Range of Accel + * @param[in] input_axis : Axis selected for Accel FOC + * @param[in,out] dev : Structure instance of bma4_dev. + * + * @return Status of execution. + */ +static int8_t perform_foc_range_test(uint8_t range, uint8_t input_axis, struct bma4_dev *dev); + +/*! + * @brief This internal API is to determine if average accel FOC data is within limits + * + * @param[in] avg_accel_foc_data : Average Accel FOC value + * @param[in] reference : Reference LSB based on Accel Range + * @param[in] foc_sign : Input sign of performed Accel FOC + * @param[in] min_val : Minimum acceptable LSB limit + * @param[in] max_val : Maximum acceptable LSB limit + * + * @return Status of execution. + */ +static int8_t accel_foc_report(int16_t avg_accel_foc_data, + int16_t reference, + uint8_t foc_sign, + int16_t min_val, + int16_t max_val); + +/*! + * @brief This internal API is to collect and verify accel sensor data + * + * @param[in] range : Value of Accel range + * @param[in] reference : Reference LSB based on Accel Range + * @param[in] matched_axis : Input Axis to perform Accel FOC + * @param[in] foc_sign : Input sign to perform Accel FOC + * @param[in,out] dev : Structure instance of bma4_dev. + * + * @return Status of execution. + */ +static int8_t verify_accel_foc_data(uint8_t range, + int16_t reference, + int8_t matched_axis, + uint8_t foc_sign, + struct bma4_dev *dev); + +/*! + * @brief This internal API is to calculate noise level for Accel FOC data + * + * @param[in] matched_axis : Input Axis to perform accel FOC + * @param[in] accel_foc_data : Array of Accel FOC data + * @param[in] avg_accel_foc_data : Average Accel FOC data + * + * @return Status of execution. + */ +static void calculate_noise(int8_t matched_axis, + const struct bma4_accel *accel_foc_data, + const struct bma4_accel avg_accel_foc_data); + +/******************************************************************************/ +/*! Functions */ + +/* This function starts the execution of program. */ +int main(void) +{ + /* Sensor initialization configuration. */ + struct bma4_dev dev; + + uint8_t try = 0, j; + int8_t rslt; + struct bma4_accel_config accel_conf = { 0 }; + uint8_t data = 0, range, input_axis = 0; + + /* Interface reference is given as a parameter + * For I2C : BMA4_I2C_INTF + * For SPI : BMA4_SPI_INTF + * Variant information given as parameter - BMA45X_VARIANT + */ + rslt = bma4_interface_init(&dev, BMA4_I2C_INTF, BMA45X_VARIANT); + bma4_error_codes_print_result("bma4_interface_init", rslt); + + printf("Functional test for accel foc start..\n\n"); + + printf("Choose the axis for accel FOC to be done\n"); + printf("Press '1' to choose X axis\n"); + printf("Press '2' to choose Y axis\n"); + printf("Press '3' to choose Z axis\n"); + + printf("Press '4' to choose -X axis\n"); + printf("Press '5' to choose -Y axis\n"); + printf("Press '6' to choose -Z axis\n"); + + for (;;) + { + scanf("%u", (unsigned int *)&input_axis); + if (input_axis > 0 && input_axis < 7) + { + break; + } + } + + if (input_axis == 1) + { + printf("The choosen input axis for FOC is : X\n"); + } + else if (input_axis == 2) + { + printf("The choosen input axis for FOC is : Y\n"); + } + else if (input_axis == 3) + { + printf("The choosen input axis for FOC is : Z\n"); + } + else if (input_axis == 4) + { + printf("The choosen input axis for FOC is : -X\n"); + } + else if (input_axis == 5) + { + printf("The choosen input axis for FOC is : -Y\n"); + } + else if (input_axis == 6) + { + printf("The choosen input axis for FOC is : -Z\n"); + } + + printf("Confirm your chosen axis and the sensor keeping position are same before doing FOC\n"); + + for (j = 0; j < 2; j++) + { + try = 0; + + if (j == 1) + { + printf("Keep sensor in wrong position and press 5\n"); + } + else if (j == 0) + { + printf("Keep sensor in right position and press 5\n"); + } + + for (;;) + { + scanf("%hu", (short unsigned int *)&try); + if (try == 5) + { + break; + } + } + + for (range = BMA4_ACCEL_RANGE_2G; range <= BMA4_ACCEL_RANGE_16G; range++) + { + /****************************************************************/ + /* Initialize by enabling configuration load */ + printf("#########################################################\n\n"); + + rslt = bma456w_init(&dev); + bma4_error_codes_print_result("bma4_init", rslt); + + /* Upload the configuration file to enable the features of the sensor. */ + rslt = bma456w_write_config_file(&dev); + bma4_error_codes_print_result("bma4_write_config", rslt); + + /* Enable the accelerometer */ + rslt = bma4_set_accel_enable(BMA4_ENABLE, &dev); + bma4_error_codes_print_result("bma4_set_accel_enable status", rslt); + + /* Accelerometer Configuration Settings */ + /* Output Data Rate */ + accel_conf.odr = BMA4_OUTPUT_DATA_RATE_50HZ; + + /* Gravity range of the sensor (+/- 2G, 4G, 8G, 16G) */ + accel_conf.range = range; + + /* The bandwidth parameter is used to configure the number of sensor samples that are averaged + * if it is set to 2, then 2^(bandwidth parameter) samples + * are averaged, resulting in 4 averaged samples + * Note1 : For more information, refer the datasheet. + * Note2 : A higher number of averaged samples will result in a less noisier signal, but + * this has an adverse effect on the power consumed. + */ + accel_conf.bandwidth = BMA4_ACCEL_NORMAL_AVG4; + + /* Enable the filter performance mode where averaging of samples + * will be done based on above set bandwidth and ODR. + * There are two modes + * 0 -> Averaging samples (Default) + * 1 -> No averaging + * For more info on No Averaging mode refer datasheet. + */ + accel_conf.perf_mode = BMA4_CIC_AVG_MODE; + + /* Set the accel configurations */ + rslt = bma4_set_accel_config(&accel_conf, &dev); + bma4_error_codes_print_result("bma4_set_accel_config status", rslt); + + /* Delay to set accel sensor configurations (20ms for 50HZ) */ + dev.delay_us(20000, dev.intf_ptr); + + /* Mapping data ready interrupt with interrupt1 to get interrupt status once getting new accel data */ + rslt = bma456w_map_interrupt(BMA4_INTR1_MAP, BMA4_DATA_RDY_INT, BMA4_ENABLE, &dev); + bma4_error_codes_print_result("bma4_map_interrupt status", rslt); + + printf("ODR = %d, RANGE = %d, BANDWIDTH = %d\n", accel_conf.odr, accel_conf.range, accel_conf.bandwidth); + + /* Perform FOC for different ranges */ + rslt = perform_foc_range_test(range, input_axis, &dev); + + if ((j == 1) && (rslt == BMA4_E_OUT_OF_RANGE)) + { + printf("\n######### Valid input - Wrong position #########\n\n"); + bma4_error_codes_print_result("perform_foc_range_test", rslt); + } + else if ((j == 0) && (rslt == BMA4_OK)) + { + printf("\n######### Valid input - Right position #########\n\n"); + bma4_error_codes_print_result("perform_foc_range_test", rslt); + } + else if ((j == 1) && (rslt == BMA4_OK)) + { + printf("\n######### Invalid input - Right position #########\n\n"); + bma4_error_codes_print_result("perform_foc_range_test", rslt); + } + else if ((j == 0) && (rslt == BMA4_E_OUT_OF_RANGE)) + { + printf("\n######### Invalid input - Wrong position #########\n\n"); + bma4_error_codes_print_result("perform_foc_range_test", rslt); + } + else if ((j == 0) && (rslt == BMA4_E_OUT_OF_RANGE)) + { + printf("\n######### Valid input - Right position #########\n\n"); + printf("\n######### Before FOC is better than after FOC #########\n\n"); + bma4_error_codes_print_result("perform_foc_range_test", rslt); + } + else if ((j == 1) && (rslt == BMA4_E_OUT_OF_RANGE)) + { + printf("\n######### Invalid input - Right position #########\n\n"); + printf("\n######### Before FOC is better than after FOC #########\n\n"); + bma4_error_codes_print_result("perform_foc_range_test", rslt); + } + } + + /* Disable offset compensation */ + rslt = bma4_read_regs(BMA4_NV_CONFIG_ADDR, &data, 1, &dev); + bma4_error_codes_print_result("bma4_read_regs", rslt); + + data = BMA4_SET_BIT_VAL_0(data, BMA4_NV_ACCEL_OFFSET); + + rslt = bma4_write_regs(BMA4_NV_CONFIG_ADDR, &data, 1, &dev); + bma4_error_codes_print_result("bma4_write_regs", rslt); + } + + bma4_coines_deinit(); + + return rslt; +} + +static int8_t accel_foc_report(int16_t avg_accel_foc_data, + int16_t reference, + uint8_t foc_sign, + int16_t min_val, + int16_t max_val) +{ + int8_t rslt = BMA4_OK; + int16_t diff_after = 0; + + if (foc_sign == 0) + { + if ((avg_accel_foc_data >= (min_val)) && (avg_accel_foc_data <= (max_val))) + { + if (avg_accel_foc_data >= reference) + { + diff_after = avg_accel_foc_data - reference; + } + else + { + diff_after = reference - avg_accel_foc_data; + } + + printf("\n# ********** PASS | Difference = %d **********\n", diff_after); + printf("\n# Avg_FOC %d in range\n", avg_accel_foc_data); + rslt = BMA4_OK; + } + else + { + if (avg_accel_foc_data >= reference) + { + diff_after = avg_accel_foc_data - reference; + } + else + { + diff_after = reference - avg_accel_foc_data; + } + + printf("\n# ********** FAIL | Difference = %d **********\n", diff_after); + printf("\n# Avg_FOC %d not in range\n", avg_accel_foc_data); + rslt = BMA4_E_OUT_OF_RANGE; + } + } + + if (foc_sign == 1) + { + if ((avg_accel_foc_data <= (min_val)) && (avg_accel_foc_data >= (max_val))) + { + if (avg_accel_foc_data <= reference) + { + diff_after = avg_accel_foc_data - reference; + } + else + { + diff_after = reference - avg_accel_foc_data; + } + + printf("\n# ********** PASS | Difference = %d **********\n", diff_after); + printf("\n# Avg_FOC %d in range\n", avg_accel_foc_data); + rslt = BMA4_OK; + } + else + { + if (avg_accel_foc_data <= reference) + { + diff_after = avg_accel_foc_data - reference; + } + else + { + diff_after = reference - avg_accel_foc_data; + } + + printf("\n# ********** FAIL | Difference = %d **********\n", diff_after); + printf("\n# Avg_FOC %d not in range\n", avg_accel_foc_data); + rslt = BMA4_E_OUT_OF_RANGE; + } + } + + return rslt; +} + +static void calculate_noise(int8_t matched_axis, + const struct bma4_accel *accel_foc_data, + const struct bma4_accel avg_accel_foc_data) +{ + int32_t variance = 0; + double noise_level; + uint16_t idx = 0; + + if (matched_axis == 'X') + { + for (idx = 0; idx < ACCEL_SAMPLE_COUNT; idx++) + { + variance += + ((accel_foc_data[idx].x - avg_accel_foc_data.x) * (accel_foc_data[idx].x - avg_accel_foc_data.x)); + } + } + else if (matched_axis == 'Y') + { + for (idx = 0; idx < ACCEL_SAMPLE_COUNT; idx++) + { + variance += + ((accel_foc_data[idx].y - avg_accel_foc_data.y) * (accel_foc_data[idx].y - avg_accel_foc_data.y)); + } + } + else if (matched_axis == 'Z') + { + for (idx = 0; idx < ACCEL_SAMPLE_COUNT; idx++) + { + variance += + ((accel_foc_data[idx].z - avg_accel_foc_data.z) * (accel_foc_data[idx].z - avg_accel_foc_data.z)); + } + } + + noise_level = sqrt((double)variance); + + printf("\n# ********** NOISE LEVEL = %lf **********\n", noise_level); +} + +static int8_t verify_accel_foc_data(uint8_t range, + int16_t reference, + int8_t matched_axis, + uint8_t foc_sign, + struct bma4_dev *dev) +{ + int8_t rslt = BMA4_E_INVALID_STATUS; + uint8_t i; + uint16_t reg_status = 0; + int16_t xl, yl, zl; + int16_t xh, yh, zh; + int16_t min_val = 0; + int16_t max_val = 0; + struct bma4_accel accel_foc_data[ACCEL_SAMPLE_COUNT] = { { 0 } }; + struct temp_axes_val temp_foc_data = { 0 }; + struct bma4_accel avg_accel_foc_data = { 0 }; + struct bma4_accel sensor_data = { 0 }; + + /* Setting initial values */ + xl = yl = zl = 32767; + xh = yh = zh = -32768; + + /* Read accelerometer values before/after FOC */ + for (i = 0; i < ACCEL_SAMPLE_COUNT; i++) + { + for (;;) + { + /* To get the data ready interrupt status */ + rslt = bma4_read_int_status(®_status, dev); + bma4_error_codes_print_result("bma4_read_int_status", rslt); + + /* Read accelerometer data based on data ready interrupt */ + if ((rslt == BMA4_OK) && (reg_status & BMA4_ACCEL_DATA_RDY_INT)) + { + rslt = bma4_read_accel_xyz(&sensor_data, dev); + bma4_error_codes_print_result("bma4_read_accel_xyz", rslt); + + memcpy(&accel_foc_data[i], &sensor_data, sizeof(struct bma4_accel)); + + printf("X[%d] = %5d Y[%d] = %5d Z[%d] = %5d\n", + i, + accel_foc_data[i].x, + i, + accel_foc_data[i].y, + i, + accel_foc_data[i].z); + + if (xl > accel_foc_data[i].x) + { + xl = accel_foc_data[i].x; + } + + if (xh < accel_foc_data[i].x) + { + xh = accel_foc_data[i].x; + } + + if (yl > accel_foc_data[i].y) + { + yl = accel_foc_data[i].y; + } + + if (yh < accel_foc_data[i].y) + { + yh = accel_foc_data[i].y; + } + + if (zl > accel_foc_data[i].z) + { + zl = accel_foc_data[i].z; + } + + if (zh < accel_foc_data[i].z) + { + zh = accel_foc_data[i].z; + } + + temp_foc_data.x += accel_foc_data[i].x; + temp_foc_data.y += accel_foc_data[i].y; + temp_foc_data.z += accel_foc_data[i].z; + break; + + } + } + } + + /* Taking average values to calculate percentage deviation */ + avg_accel_foc_data.x = (int16_t)(temp_foc_data.x / ACCEL_SAMPLE_COUNT); + avg_accel_foc_data.y = (int16_t)(temp_foc_data.y / ACCEL_SAMPLE_COUNT); + avg_accel_foc_data.z = (int16_t)(temp_foc_data.z / ACCEL_SAMPLE_COUNT); + + printf("********* MIN & MAX VALUES ********\n"); + + printf("XL = %5d YL = %5d ZL = %5d\n", xl, yl, zl); + printf("XH = %5d YH = %5d ZH = %5d\n", xh, yh, zh); + + printf("***** AVERAGE AFTER FOC *****\n"); + printf("Avg-X = %d Avg-Y = %d Avg-Z = %d\n", + avg_accel_foc_data.x, + avg_accel_foc_data.y, + avg_accel_foc_data.z); + + /* Calculate noise level */ + calculate_noise(matched_axis, accel_foc_data, avg_accel_foc_data); + + /* "zero-g offset" of accel is +/- 20 mg for all ranges as per datasheet (for 16-bit resolution) */ + if (range == 0) + { + /* Min and Max limits for Range 2G */ + min_val = BMA4_16BIT_ACC_2G_MIN_NOISE_LIMIT; + max_val = BMA4_16BIT_ACC_2G_MAX_NOISE_LIMIT; + } + else if (range == 1) + { + /* Min and Max limits for Range 4G */ + min_val = BMA4_16BIT_ACC_4G_MIN_NOISE_LIMIT; + max_val = BMA4_16BIT_ACC_4G_MAX_NOISE_LIMIT; + } + else if (range == 2) + { + /* Min and Max limits for Range 8G */ + min_val = BMA4_16BIT_ACC_8G_MIN_NOISE_LIMIT; + max_val = BMA4_16BIT_ACC_8G_MAX_NOISE_LIMIT; + } + else if (range == 3) + { + /* Min and Max limits for Range 16G */ + min_val = BMA4_16BIT_ACC_16G_MIN_NOISE_LIMIT; + max_val = BMA4_16BIT_ACC_16G_MAX_NOISE_LIMIT; + } + + if ((matched_axis == 'X') && (foc_sign == 0)) + { + rslt = accel_foc_report(avg_accel_foc_data.x, reference, foc_sign, min_val, max_val); + printf("Range : %u Avg_FOC-X : %d Reference : %d Min_Value : %d Max_Value : %d\n", + range, + avg_accel_foc_data.x, + reference, + min_val, + max_val); + } + else if ((matched_axis == 'Y') && (foc_sign == 0)) + { + rslt = accel_foc_report(avg_accel_foc_data.y, reference, foc_sign, min_val, max_val); + printf("Range : %u Avg_FOC-X : %d Reference : %d Min_Value : %d Max_Value : %d\n", + range, + avg_accel_foc_data.y, + reference, + min_val, + max_val); + } + else if ((matched_axis == 'Z') && (foc_sign == 0)) + { + rslt = accel_foc_report(avg_accel_foc_data.z, reference, foc_sign, min_val, max_val); + printf("Range : %u Avg_FOC-X : %d Reference : %d Min_Value : %d Max_Value : %d\n", + range, + avg_accel_foc_data.z, + reference, + min_val, + max_val); + } + else if ((matched_axis == 'X') && (foc_sign == 1)) + { + rslt = accel_foc_report(avg_accel_foc_data.x, + (int16_t)(reference * (-1)), + foc_sign, + (int16_t)(min_val * (-1)), + (int16_t)(max_val * (-1))); + printf("Range : %u Avg_FOC-X : %d Reference : %d Min_Value : %d Max_Value : %d\n", + range, + avg_accel_foc_data.x, + (reference * (-1)), + (min_val * (-1)), + (max_val * (-1))); + } + else if ((matched_axis == 'Y') && (foc_sign == 1)) + { + rslt = accel_foc_report(avg_accel_foc_data.y, + (int16_t)(reference * (-1)), + foc_sign, + (int16_t)(min_val * (-1)), + (int16_t)(max_val * (-1))); + printf("Range : %u Avg_FOC-X : %d Reference : %d Min_Value : %d Max_Value : %d\n", + range, + avg_accel_foc_data.y, + (reference * (-1)), + (min_val * (-1)), + (max_val * (-1))); + } + else if ((matched_axis == 'Z') && (foc_sign == 1)) + { + rslt = accel_foc_report(avg_accel_foc_data.z, + (int16_t)(reference * (-1)), + foc_sign, + (int16_t)(min_val * (-1)), + (int16_t)(max_val * (-1))); + printf("Range : %u Avg_FOC-X : %d Reference : %d Min_Value : %d Max_Value : %d\n", + range, + avg_accel_foc_data.z, + (reference * (-1)), + (min_val * (-1)), + (max_val * (-1))); + } + + return rslt; +} + +/* Perform FOC for different range and resolutions */ +static int8_t perform_foc_range_test(uint8_t range, uint8_t input_axis, struct bma4_dev *dev) +{ + int8_t rslt; + int8_t matched_axis = 0; + int16_t reference = 0; + + /* Set accel foc axis and it's sign (x, y, z, sign)*/ + struct bma4_accel_foc_g_value g_value_foc = { 0, 0, 0, 0 }; + + if (input_axis == 1) + { + g_value_foc.x = 1; + g_value_foc.y = 0; + g_value_foc.z = 0; + g_value_foc.sign = 0; + } + else if (input_axis == 2) + { + g_value_foc.x = 0; + g_value_foc.y = 1; + g_value_foc.z = 0; + g_value_foc.sign = 0; + } + else if (input_axis == 3) + { + g_value_foc.x = 0; + g_value_foc.y = 0; + g_value_foc.z = 1; + g_value_foc.sign = 0; + } + else if (input_axis == 4) + { + g_value_foc.x = 1; + g_value_foc.y = 0; + g_value_foc.z = 0; + g_value_foc.sign = 1; + } + else if (input_axis == 5) + { + g_value_foc.x = 0; + g_value_foc.y = 1; + g_value_foc.z = 0; + g_value_foc.sign = 1; + } + else if (input_axis == 6) + { + g_value_foc.x = 0; + g_value_foc.y = 0; + g_value_foc.z = 1; + g_value_foc.sign = 1; + } + + switch (range) + { + /* Reference LSB value of 2G */ + case 0: + reference = BMA4_16BIT_ACC_FOC_2G_REF; + break; + + /* Reference LSB value of 4G */ + case 1: + reference = BMA4_16BIT_ACC_FOC_4G_REF; + break; + + /* Reference LSB value of 8G */ + case 2: + reference = BMA4_16BIT_ACC_FOC_8G_REF; + break; + + /* Reference LSB value of 16G */ + case 3: + reference = BMA4_16BIT_ACC_FOC_16G_REF; + break; + default: + break; + } + + if (g_value_foc.x == 1) + { + matched_axis = 'X'; + } + else if (g_value_foc.y == 1) + { + matched_axis = 'Y'; + } + else if (g_value_foc.z == 1) + { + matched_axis = 'Z'; + } + + if (g_value_foc.sign == 1) + { + printf("MATCHED AXIS is = -%c\n", matched_axis); + } + else + { + printf("MATCHED AXIS is = %c\n", matched_axis); + } + + printf("\n\n# Before FOC\n"); + rslt = verify_accel_foc_data(range, reference, matched_axis, g_value_foc.sign, dev); + bma4_error_codes_print_result("bma4_perform_accel_foc", rslt); + + printf("\n\n######### Perform Accel FOC #########\n\n"); + + /* Perform accelerometer FOC */ + rslt = bma4_perform_accel_foc(&g_value_foc, dev); + bma4_error_codes_print_result("bma4_perform_accel_foc", rslt); + + /* Delay after performing Accel FOC */ + dev->delay_us(30000, dev->intf_ptr); + + printf("\n\n# After FOC\n"); + rslt = verify_accel_foc_data(range, reference, matched_axis, g_value_foc.sign, dev); + + return rslt; +} diff --git a/components/bma456/bma456w_examples/accelerometer/Makefile b/components/bma456/bma456w_examples/accelerometer/Makefile new file mode 100644 index 0000000..9bf7065 --- /dev/null +++ b/components/bma456/bma456w_examples/accelerometer/Makefile @@ -0,0 +1,18 @@ +COINES_INSTALL_PATH ?= ../../../.. + +EXAMPLE_FILE ?= accelerometer.c + +API_LOCATION ?= ../.. + +COMMON_LOCATION ?= .. + +C_SRCS += \ +$(API_LOCATION)/bma4.c \ +$(API_LOCATION)/bma456w.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/components/bma456/bma456w_examples/accelerometer/accelerometer.c b/components/bma456/bma456w_examples/accelerometer/accelerometer.c new file mode 100644 index 0000000..f2cda0d --- /dev/null +++ b/components/bma456/bma456w_examples/accelerometer/accelerometer.c @@ -0,0 +1,163 @@ +/**\ + * Copyright (c) 2022 Bosch Sensortec GmbH. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + **/ + +#include +#include "bma456w.h" +#include "common.h" + +/******************************************************************************/ +/*! Macro definition */ + +/*! Earth's gravity in m/s^2 */ +#define GRAVITY_EARTH (9.80665f) + +/*! Macro that holds the total number of accel x,y and z axes sample counts to be printed */ +#define ACCEL_SAMPLE_COUNT UINT8_C(100) + +/******************************************************************************/ +/*! 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); + +/******************************************************************************/ +/*! Functions */ + +/* This function starts the execution of program. */ +int main(void) +{ + /* Variable to store the status of API */ + int8_t rslt; + + /* Sensor initialization configuration */ + struct bma4_dev bma = { 0 }; + + /* Variable to store accel data ready interrupt status */ + uint16_t int_status = 0; + + /* Variable that holds the accelerometer sample count */ + uint8_t n_data = 1; + + struct bma4_accel sens_data = { 0 }; + float x = 0, y = 0, z = 0; + struct bma4_accel_config accel_conf = { 0 }; + + /* Interface reference is given as a parameter + * For I2C : BMA4_I2C_INTF + * For SPI : BMA4_SPI_INTF + * Variant information given as parameter - BMA45X_VARIANT + */ + rslt = bma4_interface_init(&bma, BMA4_I2C_INTF, BMA45X_VARIANT); + bma4_error_codes_print_result("bma4_interface_init", rslt); + + /* Sensor initialization */ + rslt = bma456w_init(&bma); + bma4_error_codes_print_result("bma456w_init status", rslt); + + /* Upload the configuration file to enable the features of the sensor. */ + rslt = bma456w_write_config_file(&bma); + bma4_error_codes_print_result("bma456w_write_config status", rslt); + + /* Accelerometer configuration settings */ + /* Output data Rate */ + accel_conf.odr = BMA4_OUTPUT_DATA_RATE_50HZ; + + /* Gravity range of the sensor (+/- 2G, 4G, 8G, 16G) */ + accel_conf.range = BMA4_ACCEL_RANGE_2G; + + /* The bandwidth parameter is used to configure the number of sensor samples that are averaged + * if it is set to 2, then 2^(bandwidth parameter) samples + * are averaged, resulting in 4 averaged samples + * Note1 : For more information, refer the datasheet. + * Note2 : A higher number of averaged samples will result in a less noisier signal, but + * this has an adverse effect on the power consumed. + */ + accel_conf.bandwidth = BMA4_ACCEL_NORMAL_AVG4; + + /* Enable the filter performance mode where averaging of samples + * will be done based on above set bandwidth and ODR. + * There are two modes + * 0 -> Averaging samples (Default) + * 1 -> No averaging + * For more info on No Averaging mode refer datasheet. + */ + accel_conf.perf_mode = BMA4_CIC_AVG_MODE; + + /* Set the accel configurations */ + rslt = bma4_set_accel_config(&accel_conf, &bma); + bma4_error_codes_print_result("bma4_set_accel_config status", rslt); + + /* NOTE : Enable accel after set of configurations */ + rslt = bma4_set_accel_enable(1, &bma); + bma4_error_codes_print_result("bma4_set_accel_enable status", rslt); + + /* Mapping data ready interrupt with interrupt pin 1 to get interrupt status once getting new accel data */ + rslt = bma456w_map_interrupt(BMA4_INTR1_MAP, BMA4_DATA_RDY_INT, BMA4_ENABLE, &bma); + bma4_error_codes_print_result("bma456w_map_interrupt status", rslt); + + printf("Data, Acc_Raw_X, Acc_Raw_Y, Acc_Raw_Z, Acc_ms2_X, Acc_ms2_Y, Acc_ms2_Z\n"); + + for (;;) + { + /* Read interrupt status */ + rslt = bma456w_read_int_status(&int_status, &bma); + bma4_error_codes_print_result("bma456w_read_int_status", rslt); + + /* Filtering only the accel data ready interrupt */ + if ((rslt == BMA4_OK) && (int_status & BMA4_ACCEL_DATA_RDY_INT)) + { + /* Read the accel x, y, z data */ + rslt = bma4_read_accel_xyz(&sens_data, &bma); + bma4_error_codes_print_result("bma4_read_accel_xyz status", rslt); + + if (rslt == BMA4_OK) + { + + /* Converting lsb to meter per second squared for 16 bit resolution at 2G range */ + x = lsb_to_ms2(sens_data.x, (float)2, bma.resolution); + y = lsb_to_ms2(sens_data.y, (float)2, bma.resolution); + z = lsb_to_ms2(sens_data.z, (float)2, bma.resolution); + + /* Print the data in m/s2 */ + printf("%d, %d, %d, %d, %4.2f, %4.2f, %4.2f\n", n_data, sens_data.x, sens_data.y, sens_data.z, x, y, z); + } + + /* Increment the count that determines the number of samples to be printed */ + n_data++; + + /* When the count reaches more than ACCEL_SAMPLE_COUNT, break and exit the loop */ + if (n_data > ACCEL_SAMPLE_COUNT) + { + break; + } + } + } + + bma4_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/components/bma456/bma456w_examples/accelerometer_hw_int/Makefile b/components/bma456/bma456w_examples/accelerometer_hw_int/Makefile new file mode 100644 index 0000000..22c9ed0 --- /dev/null +++ b/components/bma456/bma456w_examples/accelerometer_hw_int/Makefile @@ -0,0 +1,20 @@ +COINES_INSTALL_PATH ?= ../../../.. + +EXAMPLE_FILE ?= accelerometer_hw_int.c + +API_LOCATION ?= ../.. + +COMMON_LOCATION ?= .. + +C_SRCS += \ +$(API_LOCATION)/bma4.c \ +$(API_LOCATION)/bma456w.c \ +$(COMMON_LOCATION)/common/common.c + +INCLUDEPATHS += \ +$(API_LOCATION) \ +$(COMMON_LOCATION)/common + +TARGET = MCU_APP30 + +include $(COINES_INSTALL_PATH)/coines.mk \ No newline at end of file diff --git a/components/bma456/bma456w_examples/accelerometer_hw_int/accelerometer_hw_int.c b/components/bma456/bma456w_examples/accelerometer_hw_int/accelerometer_hw_int.c new file mode 100644 index 0000000..29b2f43 --- /dev/null +++ b/components/bma456/bma456w_examples/accelerometer_hw_int/accelerometer_hw_int.c @@ -0,0 +1,297 @@ +/**\ + * Copyright (c) 2022 Bosch Sensortec GmbH. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + **/ +#include +#include +#include +#include "bma456w.h" +#include "common.h" +#include "coines.h" + +/******************************************************************************/ +/*! Global variable Declaration */ + +volatile uint8_t drdy_int_status = 0; + +/******************************************************************************/ +/*! Macro definition */ + +/*! Earth's gravity in m/s^2 */ +#define GRAVITY_EARTH (9.80665f) + +/*! Macro that holds the total number of accel x,y and z axes sample counts to be printed */ +#define ACCEL_SAMPLE_COUNT UINT8_C(100) + +/*! APP20 Board number */ +#define BOARD_MCU_APP20 UINT8_C(0x03) + +/*! APP30 Board number */ +#define BOARD_MCU_APP30 UINT8_C(0x05) + +/******************************************************************************/ +/*! 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); + +/*! + * @brief This function gets board information + * + * @param[out] board : Board value to determine as APP2.0 or APP3.0 + */ +static void get_board_info(uint8_t *board); + +/*! + * @brief This internal API is used to set the interrupt status + */ +static void interrupt_callback(uint32_t param1, uint32_t param2) +{ + (void)param1; + (void)param2; + drdy_int_status = 1; +} + +/******************************************************************************/ +/*! Functions */ + +/* This function starts the execution of program. */ +int main(void) +{ + /* Variable to store the status of API */ + int8_t rslt; + + /* Sensor initialization configuration */ + struct bma4_dev bma = { 0 }; + + /* Variable to store accel data ready interrupt status */ + uint16_t int_status = 0; + + /* Variable that holds the accelerometer sample count */ + uint8_t n_data = 1; + + struct bma4_accel sens_data = { 0 }; + float x = 0, y = 0, z = 0; + struct bma4_accel_config accel_conf = { 0 }; + + struct bma4_int_pin_config pin_config = { 0 }; + + /* Variable for interrupt line selection */ + uint8_t int_line; + + uint8_t intf; + uint8_t board = 0; + + /* intf: Interface reference is given as a parameter + * For I2C : BMA4_I2C_INTF + * For SPI : BMA4_SPI_INTF + * Variant information given as parameter - BMA45X_VARIANT + */ + + intf = BMA4_I2C_INTF; + rslt = bma4_interface_init(&bma, intf, BMA45X_VARIANT); + bma4_error_codes_print_result("bma4_interface_init", rslt); + + /* Sensor initialization */ + rslt = bma456w_init(&bma); + bma4_error_codes_print_result("bma456w_init status", rslt); + + /* Accelerometer configuration settings */ + /* Output data Rate */ + accel_conf.odr = BMA4_OUTPUT_DATA_RATE_50HZ; + + /* Gravity range of the sensor (+/- 2G, 4G, 8G, 16G) */ + accel_conf.range = BMA4_ACCEL_RANGE_2G; + + /* The bandwidth parameter is used to configure the number of sensor samples that are averaged + * if it is set to 2, then 2^(bandwidth parameter) samples + * are averaged, resulting in 4 averaged samples + * Note1 : For more information, refer the datasheet. + * Note2 : A higher number of averaged samples will result in a less noisier signal, but + * this has an adverse effect on the power consumed. + */ + accel_conf.bandwidth = BMA4_ACCEL_NORMAL_AVG4; + + /* Enable the filter performance mode where averaging of samples + * will be done based on above set bandwidth and ODR. + * There are two modes + * 0 -> Averaging samples (Default) + * 1 -> No averaging + * For more info on No Averaging mode refer datasheet. + */ + accel_conf.perf_mode = BMA4_CIC_AVG_MODE; + + /* Set the accel configurations */ + rslt = bma4_set_accel_config(&accel_conf, &bma); + bma4_error_codes_print_result("bma4_set_accel_config status", rslt); + + /* Hardware interrupt configuration */ + int_line = BMA4_INTR1_MAP; + + rslt = bma456w_map_interrupt(int_line, BMA4_DATA_RDY_INT, BMA4_ENABLE, &bma); + bma4_error_codes_print_result("bma456w_map_interrupt status", rslt); + + /* Get board information */ + get_board_info(&board); + + /* + * Attach interrupt based on board + */ + if (board == BOARD_MCU_APP20) + { + switch (int_line) + { + case BMA4_INTR1_MAP: + coines_attach_interrupt(COINES_SHUTTLE_PIN_20, interrupt_callback, COINES_PIN_INTERRUPT_RISING_EDGE); + break; + + case BMA4_INTR2_MAP: + coines_attach_interrupt(COINES_SHUTTLE_PIN_21, interrupt_callback, COINES_PIN_INTERRUPT_RISING_EDGE); + break; + default: + break; + } + } + +#if !defined(MCU_APP20) + else if (board == BOARD_MCU_APP30) + { + switch (int_line) + { + case BMA4_INTR1_MAP: + coines_attach_interrupt(COINES_MINI_SHUTTLE_PIN_1_6, + interrupt_callback, + COINES_PIN_INTERRUPT_RISING_EDGE); + break; + + case BMA4_INTR2_MAP: + coines_attach_interrupt(COINES_MINI_SHUTTLE_PIN_1_7, + interrupt_callback, + COINES_PIN_INTERRUPT_RISING_EDGE); + break; + + default: + break; + } + } +#endif + + /* Latch mode to be set for I2C to read Drdy interrupt with 100kHz Speed */ + switch (intf) + { + case BMA4_I2C_INTF: + rslt = bma4_set_interrupt_mode(BMA4_LATCH_MODE, &bma); + bma4_error_codes_print_result("bma4_set_interrupt_mode status", rslt); + break; + default: + break; + } + + rslt = bma4_get_int_pin_config(&pin_config, int_line, &bma); + bma4_error_codes_print_result("bma4_get_int_pin_config status", rslt); + + pin_config.edge_ctrl = BMA4_EDGE_TRIGGER; + pin_config.output_en = BMA4_OUTPUT_ENABLE; + pin_config.lvl = BMA4_ACTIVE_HIGH; + pin_config.od = BMA4_PUSH_PULL; + pin_config.input_en = BMA4_INPUT_DISABLE; + + rslt = bma4_set_int_pin_config(&pin_config, int_line, &bma); + bma4_error_codes_print_result("bma4_set_int_pin_config status", rslt); + + /* NOTE : Enable accel after set of configurations */ + rslt = bma4_set_accel_enable(1, &bma); + bma4_error_codes_print_result("bma4_set_accel_enable status", rslt); + + printf("Data, Acc_Raw_X, Acc_Raw_Y, Acc_Raw_Z, Acc_ms2_X, Acc_ms2_Y, Acc_ms2_Z\n"); + + for (;;) + { + if (drdy_int_status == 1) + { + drdy_int_status = 0; + + /* Read interrupt status */ + rslt = bma456w_read_int_status(&int_status, &bma); + bma4_error_codes_print_result("bma456w_read_int_status", rslt); + + /* Filtering only the accel data ready interrupt */ + if ((rslt == BMA4_OK) && (int_status & BMA4_ACCEL_DATA_RDY_INT)) + { + /* Read the accel x, y, z data */ + rslt = bma4_read_accel_xyz(&sens_data, &bma); + bma4_error_codes_print_result("bma4_read_accel_xyz status", rslt); + + if (rslt == BMA4_OK) + { + + /* Converting lsb to meter per second squared for 16 bit resolution at 2G range */ + x = lsb_to_ms2(sens_data.x, (float)2, bma.resolution); + y = lsb_to_ms2(sens_data.y, (float)2, bma.resolution); + z = lsb_to_ms2(sens_data.z, (float)2, bma.resolution); + + /* Print the data in m/s2 */ + printf("%d, %d, %d, %d, %4.2f, %4.2f, %4.2f\n", + n_data, + sens_data.x, + sens_data.y, + sens_data.z, + x, + y, + z); + } + + /* Increment the count that determines the number of samples to be printed */ + n_data++; + + /* When the count reaches more than ACCEL_SAMPLE_COUNT, break and exit the loop */ + if (n_data > ACCEL_SAMPLE_COUNT) + { + break; + } + } + } + } + + bma4_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; +} + +/*! + * @brief This function gets board information + */ +static void get_board_info(uint8_t *board) +{ + struct coines_board_info board_info; + int16_t result; + + result = coines_get_board_info(&board_info); + + if (result == COINES_SUCCESS) + { + (*board) = board_info.board; + } +} diff --git a/components/bma456/bma456w_examples/axis_remap/Makefile b/components/bma456/bma456w_examples/axis_remap/Makefile new file mode 100644 index 0000000..3c4ab33 --- /dev/null +++ b/components/bma456/bma456w_examples/axis_remap/Makefile @@ -0,0 +1,18 @@ +COINES_INSTALL_PATH ?= ../../../.. + +EXAMPLE_FILE = axis_remap.c + +API_LOCATION ?= ../.. + +COMMON_LOCATION ?= .. + +C_SRCS += \ +$(API_LOCATION)/bma4.c \ +$(API_LOCATION)/bma456w.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/components/bma456/bma456w_examples/axis_remap/axis_remap.c b/components/bma456/bma456w_examples/axis_remap/axis_remap.c new file mode 100644 index 0000000..2535dde --- /dev/null +++ b/components/bma456/bma456w_examples/axis_remap/axis_remap.c @@ -0,0 +1,362 @@ +/**\ + * Copyright (c) 2022 Bosch Sensortec GmbH. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + **/ + +#include +#include + +#include "coines.h" +#include "bma456w.h" +#include "common.h" + +/*********************************************************************/ +/* functions */ +/*********************************************************************/ + +/*! + * @brief Main Function where the execution getting started to test the code. + * + * @param[in] argc + * @param[in] argv + * + * @return status + * + */ +int main(void) +{ + int8_t rslt; + struct bma4_dev bma4; + struct bma4_remap remap_data = { 0 }; + struct bma4_accel accel = { 0 }; + struct bma4_accel_config accel_conf = { 0 }; + uint16_t int_status = 0; + + char data_array[13][11] = + { { 0 }, { "BMA4_X" }, { "BMA4_Y" }, { 0 }, { "BMA4_Z" }, { 0 }, { 0 }, { 0 }, { 0 }, { "BMA4_NEG_X" }, + { "BMA4_NEG_Y" }, { 0 }, { "BMA4_NEG_Z" } }; + + /* Interface reference is given as a parameter + * For I2C : BMA4_I2C_INTF + * For SPI : BMA4_SPI_INTF + * Variant information given as parameter - BMA45X_VARIANT + */ + rslt = bma4_interface_init(&bma4, BMA4_I2C_INTF, BMA45X_VARIANT); + bma4_error_codes_print_result("bma4_interface_init", rslt); + + /* Sensor initialization */ + rslt = bma456w_init(&bma4); + bma4_error_codes_print_result("bma456w_init", rslt); + + /* Upload the configuration file to enable the features of the sensor. */ + rslt = bma456w_write_config_file(&bma4); + bma4_error_codes_print_result("bma456w_write_config_file", rslt); + + /* Accelerometer configuration Setting */ + /* Output data Rate */ + accel_conf.odr = BMA4_OUTPUT_DATA_RATE_50HZ; + + /* Gravity range of the sensor (+/- 2G, 4G, 8G, 16G) */ + accel_conf.range = BMA4_ACCEL_RANGE_2G; + + /* The bandwidth parameter is used to configure the number of sensor samples that are averaged + * if it is set to 2, then 2^(bandwidth parameter) samples + * are averaged, resulting in 4 averaged samples + * Note1 : For more information, refer the datasheet. + * Note2 : A higher number of averaged samples will result in a less noisier signal, but + * this has an adverse effect on the power consumed. + */ + accel_conf.bandwidth = BMA4_ACCEL_NORMAL_AVG4; + + /* Enable the filter performance mode where averaging of samples + * will be done based on above set bandwidth and ODR. + * There are two modes + * 0 -> Averaging samples (Default) + * 1 -> No averaging + * For more info on No Averaging mode refer datasheet. + */ + accel_conf.perf_mode = BMA4_CIC_AVG_MODE; + + /* Set the accel configurations */ + rslt = bma4_set_accel_config(&accel_conf, &bma4); + bma4_error_codes_print_result("bma4_set_accel_config status", rslt); + + /* NOTE : Enable accel after set of configurations */ + rslt = bma4_set_accel_enable(1, &bma4); + bma4_error_codes_print_result("bma4_set_accel_enable status", rslt); + + /* Mapping data ready interrupt with interrupt pin 1 to get interrupt status once getting new accel data */ + rslt = bma456w_map_interrupt(BMA4_INTR1_MAP, BMA4_DATA_RDY_INT, BMA4_ENABLE, &bma4); + bma4_error_codes_print_result("bma456w_map_interrupt status", rslt); + + printf("\nAXIS_REMAP_FUNC_TEST 1\n"); + printf("Get sensor data of re-mapped axes\n"); + + rslt = bma456w_get_remap_axes(&remap_data, &bma4); + bma4_error_codes_print_result("bma456w_get_remap_axes", rslt); + + printf("Re-mapped x value = %s\n", data_array[remap_data.x]); + printf("Re-mapped y value = %s\n", data_array[remap_data.y]); + printf("Re-mapped z value = %s\n", data_array[remap_data.z]); + + printf("Expected Re-mapped x value = BMA4_X\n"); + printf("Expected Re-mapped y value = BMA4_Y\n"); + printf("Expected Re-mapped z value = BMA4_Z\n"); + + if ((remap_data.x == BMA4_X) && (remap_data.y == BMA4_Y) && (remap_data.z == BMA4_Z)) + { + printf(">> PASS\n"); + } + else + { + printf(">> FAIL\n"); + } + + printf("Print mapped data\n"); + + for (;;) + { + /* Read interrupt status */ + rslt = bma456w_read_int_status(&int_status, &bma4); + bma4_error_codes_print_result("bma456w_read_int_status", rslt); + + /* Filtering only the accel data ready interrupt */ + if ((rslt == BMA4_OK) && (int_status & BMA4_ACCEL_DATA_RDY_INT)) + { + rslt = bma4_read_accel_xyz(&accel, &bma4); + bma4_error_codes_print_result("bma4_read_accel_xyz", rslt); + + printf("Accel :: X = %d Y = %d Z = %d\n", accel.x, accel.y, accel.z); + + break; + } + } + + printf("\nAXIS_REMAP_FUNC_TEST 2\n"); + printf("Get sensor data of re-mapped axes\n"); + + remap_data.x = BMA4_NEG_Y; + remap_data.y = BMA4_Z; + remap_data.z = BMA4_NEG_X; + + rslt = bma456w_set_remap_axes(&remap_data, &bma4); + bma4_error_codes_print_result("bma456w_set_remap_axes", rslt); + + if (rslt == BMA4_OK) + { + rslt = bma456w_get_remap_axes(&remap_data, &bma4); + bma4_error_codes_print_result("bma456w_get_remap_axes", rslt); + + if (rslt == BMA4_OK) + { + printf("Re-mapped x value = %s\n", data_array[remap_data.x]); + printf("Re-mapped y value = %s\n", data_array[remap_data.y]); + printf("Re-mapped z value = %s\n", data_array[remap_data.z]); + } + + printf("Expected Re-mapped x value = BMA4_NEG_Y\n"); + printf("Expected Re-mapped y value = BMA4_Z\n"); + printf("Expected Re-mapped z value = BMA4_NEG_X\n"); + + if ((remap_data.x == BMA4_NEG_Y) && (remap_data.y == BMA4_Z) && (remap_data.z == BMA4_NEG_X)) + { + printf(">> PASS\n"); + } + else + { + printf(">> FAIL\n"); + } + } + + printf("Print mapped data\n"); + + for (;;) + { + /* Read interrupt status */ + rslt = bma456w_read_int_status(&int_status, &bma4); + bma4_error_codes_print_result("bma456w_read_int_status", rslt); + + /* Filtering only the accel data ready interrupt */ + if ((rslt == BMA4_OK) && (int_status & BMA4_ACCEL_DATA_RDY_INT)) + { + rslt = bma4_read_accel_xyz(&accel, &bma4); + bma4_error_codes_print_result("bma4_read_accel_xyz", rslt); + + printf("Accel :: X = %d Y = %d Z = %d\n", accel.x, accel.y, accel.z); + + break; + } + } + + printf("\nAXIS_REMAP_FUNC_TEST 3\n"); + printf("Get sensor data of re-mapped axes - 2nd combination\n"); + + remap_data.x = BMA4_NEG_Z; + remap_data.y = BMA4_NEG_X; + remap_data.z = BMA4_Y; + + rslt = bma456w_set_remap_axes(&remap_data, &bma4); + bma4_error_codes_print_result("bma456w_set_remap_axes", rslt); + + if (rslt == BMA4_OK) + { + rslt = bma456w_get_remap_axes(&remap_data, &bma4); + bma4_error_codes_print_result("bma456w_get_remap_axes", rslt); + + if (rslt == BMA4_OK) + { + printf("Re-mapped x value = %s\n", data_array[remap_data.x]); + printf("Re-mapped y value = %s\n", data_array[remap_data.y]); + printf("Re-mapped z value = %s\n", data_array[remap_data.z]); + } + + printf("Expected Re-mapped x value = BMA4_NEG_Z\n"); + printf("Expected Re-mapped y value = BMA4_NEG_X\n"); + printf("Expected Re-mapped z value = BMA4_Y\n"); + + if ((remap_data.x == BMA4_NEG_Z) && (remap_data.y == BMA4_NEG_X) && (remap_data.z == BMA4_Y)) + { + printf(">> PASS\n"); + } + else + { + printf(">> FAIL\n"); + } + } + + printf("Print mapped data\n"); + + for (;;) + { + /* Read interrupt status */ + rslt = bma456w_read_int_status(&int_status, &bma4); + bma4_error_codes_print_result("bma456w_read_int_status", rslt); + + /* Filtering only the accel data ready interrupt */ + if ((rslt == BMA4_OK) && (int_status & BMA4_ACCEL_DATA_RDY_INT)) + { + rslt = bma4_read_accel_xyz(&accel, &bma4); + bma4_error_codes_print_result("bma4_read_accel_xyz", rslt); + + printf("Accel :: X = %d Y = %d Z = %d\n", accel.x, accel.y, accel.z); + + break; + } + } + + printf("\nAXIS_REMAP_FUNC_TEST 4\n"); + printf("Get sensor data of re-mapped axes - 3rd combination\n"); + + remap_data.x = BMA4_Y; + remap_data.y = BMA4_Z; + remap_data.z = BMA4_X; + + rslt = bma456w_set_remap_axes(&remap_data, &bma4); + bma4_error_codes_print_result("bma456w_set_remap_axes", rslt); + if (rslt == BMA4_OK) + { + rslt = bma456w_get_remap_axes(&remap_data, &bma4); + bma4_error_codes_print_result("bma456w_get_remap_axes", rslt); + + if (rslt == BMA4_OK) + { + printf("Re-mapped x value = %s\n", data_array[remap_data.x]); + printf("Re-mapped y value = %s\n", data_array[remap_data.y]); + printf("Re-mapped z value = %s\n", data_array[remap_data.z]); + } + + printf("Expected Re-mapped x value = BMA4_Y\n"); + printf("Expected Re-mapped y value = BMA4_Z\n"); + printf("Expected Re-mapped z value = BMA4_X\n"); + + if ((remap_data.x == BMA4_Y) && (remap_data.y == BMA4_Z) && (remap_data.z == BMA4_X)) + { + printf(">> PASS\n"); + } + else + { + printf(">> FAIL\n"); + } + } + + printf("Print mapped data\n"); + + for (;;) + { + /* Read interrupt status */ + rslt = bma456w_read_int_status(&int_status, &bma4); + bma4_error_codes_print_result("bma456w_read_int_status", rslt); + + /* Filtering only the accel data ready interrupt */ + if ((rslt == BMA4_OK) && (int_status & BMA4_ACCEL_DATA_RDY_INT)) + { + rslt = bma4_read_accel_xyz(&accel, &bma4); + bma4_error_codes_print_result("bma4_read_accel_xyz", rslt); + + printf("Accel :: X = %d Y = %d Z = %d\n", accel.x, accel.y, accel.z); + + break; + } + } + + printf("\nAXIS_REMAP_FUNC_TEST 5\n"); + printf("Get sensor data of re-mapped axes - 4th combination\n"); + + remap_data.x = BMA4_NEG_X; + remap_data.y = BMA4_NEG_Y; + remap_data.z = BMA4_NEG_Z; + + rslt = bma456w_set_remap_axes(&remap_data, &bma4); + bma4_error_codes_print_result("bma456w_set_remap_axes", rslt); + + if (rslt == BMA4_OK) + { + rslt = bma456w_get_remap_axes(&remap_data, &bma4); + bma4_error_codes_print_result("bma456w_get_remap_axes", rslt); + + if (rslt == BMA4_OK) + { + printf("Re-mapped x value = %s\n", data_array[remap_data.x]); + printf("Re-mapped y value = %s\n", data_array[remap_data.y]); + printf("Re-mapped z value = %s\n", data_array[remap_data.z]); + } + + printf("Expected Re-mapped x value = BMA4_NEG_X\n"); + printf("Expected Re-mapped y value = BMA4_NEG_Y\n"); + printf("Expected Re-mapped z value = BMA4_NEG_Z\n"); + + if ((remap_data.x == BMA4_NEG_X) && (remap_data.y == BMA4_NEG_Y) && (remap_data.z == BMA4_NEG_Z)) + { + printf(">> PASS\n"); + } + else + { + printf(">> FAIL\n"); + } + } + + printf("Print mapped data\n"); + + for (;;) + { + /* Read interrupt status */ + rslt = bma456w_read_int_status(&int_status, &bma4); + bma4_error_codes_print_result("bma456w_read_int_status", rslt); + + /* Filtering only the accel data ready interrupt */ + if ((rslt == BMA4_OK) && (int_status & BMA4_ACCEL_DATA_RDY_INT)) + { + rslt = bma4_read_accel_xyz(&accel, &bma4); + bma4_error_codes_print_result("bma4_read_accel_xyz", rslt); + + printf("Accel :: X = %d Y = %d Z = %d\n", accel.x, accel.y, accel.z); + + break; + } + } + + bma4_coines_deinit(); + + return rslt; +} diff --git a/components/bma456/bma456w_examples/axis_remap_hw_int/Makefile b/components/bma456/bma456w_examples/axis_remap_hw_int/Makefile new file mode 100644 index 0000000..a92e943 --- /dev/null +++ b/components/bma456/bma456w_examples/axis_remap_hw_int/Makefile @@ -0,0 +1,20 @@ +COINES_INSTALL_PATH ?= ../../../.. + +EXAMPLE_FILE = axis_remap_hw_int.c + +API_LOCATION ?= ../.. + +COMMON_LOCATION ?= .. + +C_SRCS += \ +$(API_LOCATION)/bma4.c \ +$(API_LOCATION)/bma456w.c \ +$(COMMON_LOCATION)/common/common.c + +INCLUDEPATHS += \ +$(API_LOCATION) \ +$(COMMON_LOCATION)/common + +TARGET = MCU_APP30 + +include $(COINES_INSTALL_PATH)/coines.mk \ No newline at end of file diff --git a/components/bma456/bma456w_examples/axis_remap_hw_int/axis_remap_hw_int.c b/components/bma456/bma456w_examples/axis_remap_hw_int/axis_remap_hw_int.c new file mode 100644 index 0000000..06c2adc --- /dev/null +++ b/components/bma456/bma456w_examples/axis_remap_hw_int/axis_remap_hw_int.c @@ -0,0 +1,507 @@ +/**\ + * Copyright (c) 2022 Bosch Sensortec GmbH. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + **/ +#include +#include +#include +#include "coines.h" +#include "bma456w.h" +#include "common.h" + +/******************************************************************************/ +/*! Global variable Declaration */ + +volatile uint8_t drdy_int_status = 0; + +/******************************************************************************/ +/*! Macro definition */ + +/*! APP20 Board number */ +#define BOARD_MCU_APP20 UINT8_C(0x03) + +/*! APP30 Board number */ +#define BOARD_MCU_APP30 UINT8_C(0x05) + +/******************************************************************************/ +/*! Static Function Declaration */ + +/*! + * @brief This function gets board information + * + * @param[out] board : Board value to determine as APP2.0 or APP3.0 + */ +static void get_board_info(uint8_t *board); + +/*! + * @brief This internal API is used to set the interrupt status + */ +static void interrupt_callback(uint32_t param1, uint32_t param2) +{ + (void)param1; + (void)param2; + drdy_int_status = 1; +} + +/******************************************************************************/ +/*! Functions */ + +/* This function starts the execution of program. */ +int main(void) +{ + int8_t rslt; + struct bma4_dev bma4; + struct bma4_remap remap_data = { 0 }; + struct bma4_accel accel = { 0 }; + struct bma4_accel_config accel_conf = { 0 }; + uint16_t int_status = 0; + struct bma4_int_pin_config pin_config = { 0 }; + + /* Variable for interrupt line selection*/ + uint8_t int_line; + + uint8_t intf; + uint8_t board = 0; + + char data_array[13][11] = + { { 0 }, { "BMA4_X" }, { "BMA4_Y" }, { 0 }, { "BMA4_Z" }, { 0 }, { 0 }, { 0 }, { 0 }, { "BMA4_NEG_X" }, + { "BMA4_NEG_Y" }, { 0 }, { "BMA4_NEG_Z" } }; + + /* intf: Interface reference is given as a parameter + * For I2C : BMA4_I2C_INTF + * For SPI : BMA4_SPI_INTF + * Variant information given as parameter - BMA45X_VARIANT + */ + + intf = BMA4_I2C_INTF; + rslt = bma4_interface_init(&bma4, intf, BMA45X_VARIANT); + bma4_error_codes_print_result("bma4_interface_init", rslt); + + /* Sensor initialization */ + rslt = bma456w_init(&bma4); + bma4_error_codes_print_result("bma456w_init", rslt); + + /* Upload the configuration file to enable the features of the sensor. */ + rslt = bma456w_write_config_file(&bma4); + bma4_error_codes_print_result("bma456w_write_config_file", rslt); + + /* Accelerometer configuration Setting */ + /* Output data Rate */ + accel_conf.odr = BMA4_OUTPUT_DATA_RATE_50HZ; + + /* Gravity range of the sensor (+/- 2G, 4G, 8G, 16G) */ + accel_conf.range = BMA4_ACCEL_RANGE_2G; + + /* The bandwidth parameter is used to configure the number of sensor samples that are averaged + * if it is set to 2, then 2^(bandwidth parameter) samples + * are averaged, resulting in 4 averaged samples + * Note1 : For more information, refer the datasheet. + * Note2 : A higher number of averaged samples will result in a less noisier signal, but + * this has an adverse effect on the power consumed. + */ + accel_conf.bandwidth = BMA4_ACCEL_NORMAL_AVG4; + + /* Enable the filter performance mode where averaging of samples + * will be done based on above set bandwidth and ODR. + * There are two modes + * 0 -> Averaging samples (Default) + * 1 -> No averaging + * For more info on No Averaging mode refer datasheet. + */ + accel_conf.perf_mode = BMA4_CIC_AVG_MODE; + + /* Set the accel configurations */ + rslt = bma4_set_accel_config(&accel_conf, &bma4); + bma4_error_codes_print_result("bma4_set_accel_config status", rslt); + + /* Hardware interrupt configuration */ + int_line = BMA4_INTR2_MAP; + + rslt = bma456w_map_interrupt(int_line, BMA4_DATA_RDY_INT, BMA4_ENABLE, &bma4); + bma4_error_codes_print_result("bma456w_map_interrupt status", rslt); + + /* Get board information */ + get_board_info(&board); + + /* + * Attach interrupt based on board + */ + if (board == BOARD_MCU_APP20) + { + switch (int_line) + { + case BMA4_INTR1_MAP: + coines_attach_interrupt(COINES_SHUTTLE_PIN_20, interrupt_callback, COINES_PIN_INTERRUPT_RISING_EDGE); + break; + + case BMA4_INTR2_MAP: + coines_attach_interrupt(COINES_SHUTTLE_PIN_21, interrupt_callback, COINES_PIN_INTERRUPT_RISING_EDGE); + break; + default: + break; + } + } + +#if !defined(MCU_APP20) + else if (board == BOARD_MCU_APP30) + { + switch (int_line) + { + case BMA4_INTR1_MAP: + coines_attach_interrupt(COINES_MINI_SHUTTLE_PIN_1_6, + interrupt_callback, + COINES_PIN_INTERRUPT_RISING_EDGE); + break; + + case BMA4_INTR2_MAP: + coines_attach_interrupt(COINES_MINI_SHUTTLE_PIN_1_7, + interrupt_callback, + COINES_PIN_INTERRUPT_RISING_EDGE); + break; + + default: + break; + } + } +#endif + + /* Latch mode to be set for I2C to read Drdy interrupt with 100kHz Speed */ + switch (intf) + { + case BMA4_I2C_INTF: + rslt = bma4_set_interrupt_mode(BMA4_LATCH_MODE, &bma4); + bma4_error_codes_print_result("bma4_set_interrupt_mode status", rslt); + break; + default: + break; + } + + rslt = bma4_get_int_pin_config(&pin_config, int_line, &bma4); + bma4_error_codes_print_result("bma4_get_int_pin_config status", rslt); + + pin_config.edge_ctrl = BMA4_EDGE_TRIGGER; + pin_config.output_en = BMA4_OUTPUT_ENABLE; + pin_config.lvl = BMA4_ACTIVE_HIGH; + pin_config.od = BMA4_PUSH_PULL; + pin_config.input_en = BMA4_INPUT_DISABLE; + + rslt = bma4_set_int_pin_config(&pin_config, int_line, &bma4); + bma4_error_codes_print_result("bma4_set_int_pin_config status", rslt); + + /* NOTE : Enable accel after set of configurations */ + rslt = bma4_set_accel_enable(1, &bma4); + bma4_error_codes_print_result("bma4_set_accel_enable status", rslt); + + printf("\nAXIS_REMAP_FUNC_TEST 1\n"); + printf("Get sensor data of re-mapped axes\n"); + + rslt = bma456w_get_remap_axes(&remap_data, &bma4); + bma4_error_codes_print_result("bma456w_get_remap_axes", rslt); + + printf("Re-mapped x value = %s\n", data_array[remap_data.x]); + printf("Re-mapped y value = %s\n", data_array[remap_data.y]); + printf("Re-mapped z value = %s\n", data_array[remap_data.z]); + + printf("Expected Re-mapped x value = BMA4_X\n"); + printf("Expected Re-mapped y value = BMA4_Y\n"); + printf("Expected Re-mapped z value = BMA4_Z\n"); + + if ((remap_data.x == BMA4_X) && (remap_data.y == BMA4_Y) && (remap_data.z == BMA4_Z)) + { + printf(">> PASS\n"); + } + else + { + printf(">> FAIL\n"); + } + + printf("Print mapped data\n"); + + for (;;) + { + if (drdy_int_status == 1) + { + drdy_int_status = 0; + + /* Read interrupt status */ + rslt = bma456w_read_int_status(&int_status, &bma4); + bma4_error_codes_print_result("bma456w_read_int_status", rslt); + + /* Filtering only the accel data ready interrupt */ + if ((rslt == BMA4_OK) && (int_status & BMA4_ACCEL_DATA_RDY_INT)) + { + rslt = bma4_read_accel_xyz(&accel, &bma4); + bma4_error_codes_print_result("bma4_read_accel_xyz", rslt); + + printf("Accel :: X = %d Y = %d Z = %d\n", accel.x, accel.y, accel.z); + + break; + } + } + } + + printf("\nAXIS_REMAP_FUNC_TEST 2\n"); + printf("Get sensor data of re-mapped axes\n"); + + remap_data.x = BMA4_NEG_Y; + remap_data.y = BMA4_Z; + remap_data.z = BMA4_NEG_X; + + rslt = bma456w_set_remap_axes(&remap_data, &bma4); + bma4_error_codes_print_result("bma456w_set_remap_axes", rslt); + + if (rslt == BMA4_OK) + { + rslt = bma456w_get_remap_axes(&remap_data, &bma4); + bma4_error_codes_print_result("bma456w_get_remap_axes", rslt); + + if (rslt == BMA4_OK) + { + printf("Re-mapped x value = %s\n", data_array[remap_data.x]); + printf("Re-mapped y value = %s\n", data_array[remap_data.y]); + printf("Re-mapped z value = %s\n", data_array[remap_data.z]); + } + + printf("Expected Re-mapped x value = BMA4_NEG_Y\n"); + printf("Expected Re-mapped y value = BMA4_Z\n"); + printf("Expected Re-mapped z value = BMA4_NEG_X\n"); + + if ((remap_data.x == BMA4_NEG_Y) && (remap_data.y == BMA4_Z) && (remap_data.z == BMA4_NEG_X)) + { + printf(">> PASS\n"); + } + else + { + printf(">> FAIL\n"); + } + } + + printf("Print mapped data\n"); + + for (;;) + { + if (drdy_int_status == 1) + { + drdy_int_status = 0; + + /* Read interrupt status */ + rslt = bma456w_read_int_status(&int_status, &bma4); + bma4_error_codes_print_result("bma456w_read_int_status", rslt); + + /* Filtering only the accel data ready interrupt */ + if ((rslt == BMA4_OK) && (int_status & BMA4_ACCEL_DATA_RDY_INT)) + { + rslt = bma4_read_accel_xyz(&accel, &bma4); + bma4_error_codes_print_result("bma4_read_accel_xyz", rslt); + + printf("Accel :: X = %d Y = %d Z = %d\n", accel.x, accel.y, accel.z); + + break; + } + } + } + + printf("\nAXIS_REMAP_FUNC_TEST 3\n"); + printf("Get sensor data of re-mapped axes - 2nd combination\n"); + + remap_data.x = BMA4_NEG_Z; + remap_data.y = BMA4_NEG_X; + remap_data.z = BMA4_Y; + + rslt = bma456w_set_remap_axes(&remap_data, &bma4); + bma4_error_codes_print_result("bma456w_set_remap_axes", rslt); + + if (rslt == BMA4_OK) + { + rslt = bma456w_get_remap_axes(&remap_data, &bma4); + bma4_error_codes_print_result("bma456w_get_remap_axes", rslt); + + if (rslt == BMA4_OK) + { + printf("Re-mapped x value = %s\n", data_array[remap_data.x]); + printf("Re-mapped y value = %s\n", data_array[remap_data.y]); + printf("Re-mapped z value = %s\n", data_array[remap_data.z]); + } + + printf("Expected Re-mapped x value = BMA4_NEG_Z\n"); + printf("Expected Re-mapped y value = BMA4_NEG_X\n"); + printf("Expected Re-mapped z value = BMA4_Y\n"); + + if ((remap_data.x == BMA4_NEG_Z) && (remap_data.y == BMA4_NEG_X) && (remap_data.z == BMA4_Y)) + { + printf(">> PASS\n"); + } + else + { + printf(">> FAIL\n"); + } + } + + printf("Print mapped data\n"); + + for (;;) + { + if (drdy_int_status == 1) + { + drdy_int_status = 0; + + /* Read interrupt status */ + rslt = bma456w_read_int_status(&int_status, &bma4); + bma4_error_codes_print_result("bma456w_read_int_status", rslt); + + /* Filtering only the accel data ready interrupt */ + if ((rslt == BMA4_OK) && (int_status & BMA4_ACCEL_DATA_RDY_INT)) + { + rslt = bma4_read_accel_xyz(&accel, &bma4); + bma4_error_codes_print_result("bma4_read_accel_xyz", rslt); + + printf("Accel :: X = %d Y = %d Z = %d\n", accel.x, accel.y, accel.z); + + break; + } + } + } + + printf("\nAXIS_REMAP_FUNC_TEST 4\n"); + printf("Get sensor data of re-mapped axes - 3rd combination\n"); + + remap_data.x = BMA4_Y; + remap_data.y = BMA4_Z; + remap_data.z = BMA4_X; + + rslt = bma456w_set_remap_axes(&remap_data, &bma4); + bma4_error_codes_print_result("bma456w_set_remap_axes", rslt); + + if (rslt == BMA4_OK) + { + rslt = bma456w_get_remap_axes(&remap_data, &bma4); + bma4_error_codes_print_result("bma456w_get_remap_axes", rslt); + + if (rslt == BMA4_OK) + { + printf("Re-mapped x value = %s\n", data_array[remap_data.x]); + printf("Re-mapped y value = %s\n", data_array[remap_data.y]); + printf("Re-mapped z value = %s\n", data_array[remap_data.z]); + } + + printf("Expected Re-mapped x value = BMA4_Y\n"); + printf("Expected Re-mapped y value = BMA4_Z\n"); + printf("Expected Re-mapped z value = BMA4_X\n"); + + if ((remap_data.x == BMA4_Y) && (remap_data.y == BMA4_Z) && (remap_data.z == BMA4_X)) + { + printf(">> PASS\n"); + } + else + { + printf(">> FAIL\n"); + } + } + + printf("Print mapped data\n"); + + for (;;) + { + if (drdy_int_status == 1) + { + drdy_int_status = 0; + + /* Read interrupt status */ + rslt = bma456w_read_int_status(&int_status, &bma4); + bma4_error_codes_print_result("bma456w_read_int_status", rslt); + + /* Filtering only the accel data ready interrupt */ + if ((rslt == BMA4_OK) && (int_status & BMA4_ACCEL_DATA_RDY_INT)) + { + rslt = bma4_read_accel_xyz(&accel, &bma4); + bma4_error_codes_print_result("bma4_read_accel_xyz", rslt); + + printf("Accel :: X = %d Y = %d Z = %d\n", accel.x, accel.y, accel.z); + + break; + } + } + } + + printf("\nAXIS_REMAP_FUNC_TEST 5\n"); + printf("Get sensor data of re-mapped axes - 4th combination\n"); + + remap_data.x = BMA4_NEG_X; + remap_data.y = BMA4_NEG_Y; + remap_data.z = BMA4_NEG_Z; + + rslt = bma456w_set_remap_axes(&remap_data, &bma4); + bma4_error_codes_print_result("bma456w_set_remap_axes", rslt); + + if (rslt == BMA4_OK) + { + rslt = bma456w_get_remap_axes(&remap_data, &bma4); + bma4_error_codes_print_result("bma456w_get_remap_axes", rslt); + + if (rslt == BMA4_OK) + { + printf("Re-mapped x value = %s\n", data_array[remap_data.x]); + printf("Re-mapped y value = %s\n", data_array[remap_data.y]); + printf("Re-mapped z value = %s\n", data_array[remap_data.z]); + } + + printf("Expected Re-mapped x value = BMA4_NEG_X\n"); + printf("Expected Re-mapped y value = BMA4_NEG_Y\n"); + printf("Expected Re-mapped z value = BMA4_NEG_Z\n"); + + if ((remap_data.x == BMA4_NEG_X) && (remap_data.y == BMA4_NEG_Y) && (remap_data.z == BMA4_NEG_Z)) + { + printf(">> PASS\n"); + } + else + { + printf(">> FAIL\n"); + } + } + + printf("Print mapped data\n"); + + for (;;) + { + if (drdy_int_status == 1) + { + drdy_int_status = 0; + + /* Read interrupt status */ + rslt = bma456w_read_int_status(&int_status, &bma4); + bma4_error_codes_print_result("bma456w_read_int_status", rslt); + + /* Filtering only the accel data ready interrupt */ + if ((rslt == BMA4_OK) && (int_status & BMA4_ACCEL_DATA_RDY_INT)) + { + rslt = bma4_read_accel_xyz(&accel, &bma4); + bma4_error_codes_print_result("bma4_read_accel_xyz", rslt); + + printf("Accel :: X = %d Y = %d Z = %d\n", accel.x, accel.y, accel.z); + + break; + } + } + } + + bma4_coines_deinit(); + + return rslt; +} + +/*! + * @brief This function gets board information + */ +static void get_board_info(uint8_t *board) +{ + struct coines_board_info board_info; + int16_t result; + + result = coines_get_board_info(&board_info); + + if (result == COINES_SUCCESS) + { + (*board) = board_info.board; + } +} diff --git a/components/bma456/bma456w_examples/common/common.c b/components/bma456/bma456w_examples/common/common.c new file mode 100644 index 0000000..ca1e7c9 --- /dev/null +++ b/components/bma456/bma456w_examples/common/common.c @@ -0,0 +1,242 @@ +/** + * Copyright (C) 2023 Bosch Sensortec GmbH. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include + +#include "bma4_defs.h" +#include "common.h" + +/******************************************************************************/ +/*! Macro definitions */ + +/*! Read write length varies based on user requirement */ +#define BMA4_READ_WRITE_LEN UINT8_C(46) + +/******************************************************************************/ +/*! Static variable definition */ + +/*! Variable that holds the I2C device address or SPI chip selection */ +static uint8_t dev_addr; + +/******************************************************************************/ +/*! User interface functions */ + +/*! + * I2C read function map to COINES platform + */ +BMA4_INTF_RET_TYPE bma4_i2c_read(uint8_t reg_addr, uint8_t *reg_data, uint32_t len, void *intf_ptr) +{ + uint8_t dev_address = *(uint8_t*)intf_ptr; + + (void)intf_ptr; + + return coines_read_i2c(COINES_I2C_BUS_0, dev_address, reg_addr, reg_data, (uint16_t)len); +} + +/*! + * I2C write function map to COINES platform + */ +BMA4_INTF_RET_TYPE bma4_i2c_write(uint8_t reg_addr, const uint8_t *reg_data, uint32_t len, void *intf_ptr) +{ + uint8_t dev_address = *(uint8_t*)intf_ptr; + + (void)intf_ptr; + + return coines_write_i2c(COINES_I2C_BUS_0, dev_address, reg_addr, (uint8_t *)reg_data, (uint16_t)len); +} + +/*! + * SPI read function map to COINES platform + */ +BMA4_INTF_RET_TYPE bma4_spi_read(uint8_t reg_addr, uint8_t *reg_data, uint32_t len, void *intf_ptr) +{ + uint8_t dev_address = *(uint8_t*)intf_ptr; + + (void)intf_ptr; + + return coines_read_spi(COINES_SPI_BUS_0, dev_address, reg_addr, reg_data, (uint16_t)len); +} + +/*! + * SPI write function map to COINES platform + */ +BMA4_INTF_RET_TYPE bma4_spi_write(uint8_t reg_addr, const uint8_t *reg_data, uint32_t len, void *intf_ptr) +{ + uint8_t dev_address = *(uint8_t*)intf_ptr; + + (void)intf_ptr; + + return coines_write_spi(COINES_SPI_BUS_0, dev_address, reg_addr, (uint8_t *)reg_data, (uint16_t)len); +} + +/*! + * Delay function map to COINES platform + */ +void bma4_delay_us(uint32_t period, void *intf_ptr) +{ + (void) intf_ptr; + coines_delay_usec(period); +} + +/*! + * @brief Function to select the interface between SPI and I2C. + * Also to initialize coines platform + */ +int8_t bma4_interface_init(struct bma4_dev *bma, uint8_t intf, enum bma4_variant variant) +{ + int8_t rslt = BMA4_OK; + + if (bma != NULL) + { + int16_t result = coines_open_comm_intf(COINES_COMM_INTF_USB, NULL); + struct coines_board_info board_info; + if (result < COINES_SUCCESS) + { + printf( + "\n Unable to connect with Application Board ! \n" " 1. Check if the board is connected and powered on. \n" " 2. Check if Application Board USB driver is installed. \n" + " 3. Check if board is in use by another application. (Insufficient permissions to access USB) \n"); + exit(result); + } + + result = coines_get_board_info(&board_info); + + #if defined(PC) + setbuf(stdout, NULL); + #endif + + (void)coines_set_shuttleboard_vdd_vddio_config(0, 0); + coines_delay_usec(10000); + + /* Bus configuration : I2C */ + if (intf == BMA4_I2C_INTF) + { + printf("I2C Interface \n"); + + /* To initialize the user I2C function */ + dev_addr = BMA4_I2C_ADDR_PRIMARY; + bma->intf = BMA4_I2C_INTF; + bma->bus_read = bma4_i2c_read; + bma->bus_write = bma4_i2c_write; + + /* SDO to Ground */ + (void)coines_set_pin_config(COINES_SHUTTLE_PIN_22, COINES_PIN_DIRECTION_OUT, COINES_PIN_VALUE_LOW); + + /* Make CSB pin HIGH */ + (void)coines_set_pin_config(COINES_SHUTTLE_PIN_21, COINES_PIN_DIRECTION_OUT, COINES_PIN_VALUE_HIGH); + coines_delay_msec(100); + + /* SDO pin is made low */ + (void)coines_set_pin_config(COINES_SHUTTLE_PIN_SDO, COINES_PIN_DIRECTION_OUT, COINES_PIN_VALUE_LOW); + + (void)coines_config_i2c_bus(COINES_I2C_BUS_0, COINES_I2C_STANDARD_MODE); + } + /* Bus configuration : SPI */ + else if (intf == BMA4_SPI_INTF) + { + printf("SPI Interface \n"); + + /* To initialize the user SPI function */ + dev_addr = COINES_SHUTTLE_PIN_7; + bma->intf = BMA4_SPI_INTF; + bma->bus_read = bma4_spi_read; + bma->bus_write = bma4_spi_write; + (void)coines_config_spi_bus(COINES_SPI_BUS_0, COINES_SPI_SPEED_7_5_MHZ, COINES_SPI_MODE0); + } + + /* Assign variant information */ + bma->variant = variant; + + /* Assign device address to interface pointer */ + bma->intf_ptr = &dev_addr; + + /* Configure delay in microseconds */ + bma->delay_us = bma4_delay_us; + + /* Configure max read/write length (in bytes) ( Supported length depends on target machine) */ + bma->read_write_len = BMA4_READ_WRITE_LEN; + + /* Set Performance mode status */ + bma->perf_mode_status = BMA4_DISABLE; + + coines_delay_msec(100); + + (void)coines_set_shuttleboard_vdd_vddio_config(3300, 3300); + + coines_delay_msec(200); + } + else + { + rslt = BMA4_E_NULL_PTR; + } + + return rslt; + +} + +/*! + * @brief Prints the execution status of the APIs. + */ +void bma4_error_codes_print_result(const char api_name[], int8_t rslt) +{ + if (rslt != BMA4_OK) + { + printf("%s\t", api_name); + if (rslt == BMA4_E_NULL_PTR) + { + printf("Error [%d] : Null pointer\r\n", rslt); + } + else if (rslt == BMA4_E_COM_FAIL) + { + printf("Error [%d] : Communication failure\r\n", rslt); + } + else if (rslt == BMA4_E_CONFIG_STREAM_ERROR) + { + printf("Error [%d] : Invalid configuration stream\r\n", rslt); + } + else if (rslt == BMA4_E_SELF_TEST_FAIL) + { + printf("Error [%d] : Self test failed\r\n", rslt); + } + else if (rslt == BMA4_E_INVALID_SENSOR) + { + printf("Error [%d] : Device not found\r\n", rslt); + } + else if (rslt == BMA4_E_OUT_OF_RANGE) + { + printf("Error [%d] : Out of Range\r\n", rslt); + } + else if (rslt == BMA4_E_AVG_MODE_INVALID_CONF) + { + printf("Error [%d] : Invalid bandwidth and ODR combination in Accel Averaging mode\r\n", rslt); + } + else + { + /* For more error codes refer "*_defs.h" */ + printf("Error [%d] : Unknown error code\r\n", rslt); + } + } +} + +/*! + * @brief Deinitializes coines platform + * + * @return void. + */ +void bma4_coines_deinit(void) +{ + (void)fflush(stdout); + coines_delay_msec(200); + + (void)coines_set_shuttleboard_vdd_vddio_config(0, 0); + coines_delay_msec(1000); + + /* Coines interface reset */ + coines_soft_reset(); + coines_delay_msec(1000); + (void)coines_close_comm_intf(COINES_COMM_INTF_USB, NULL); +} diff --git a/components/bma456/bma456w_examples/common/common.h b/components/bma456/bma456w_examples/common/common.h new file mode 100644 index 0000000..75c53f4 --- /dev/null +++ b/components/bma456/bma456w_examples/common/common.h @@ -0,0 +1,127 @@ +/**\ + * Copyright (c) 2023 Bosch Sensortec GmbH. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + **/ + +#ifndef COMMON_H +#define COMMON_H + +/*! CPP guard */ +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include "bma4.h" +#include "coines.h" + +/*! + * @brief Function for reading the sensor's registers through I2C bus. + * + * @param[in] reg_addr : Register address. + * @param[out] reg_data : Pointer to the data buffer to store the read data. + * @param[in] length : No of bytes to read. + * @param[in] intf_ptr : Interface pointer + * + * @return Status of execution + * @retval = BMA4_INTF_RET_SUCCESS -> Success + * @retval != BMA4_INTF_RET_SUCCESS -> Failure Info + * + */ +BMA4_INTF_RET_TYPE bma4_i2c_read(uint8_t reg_addr, uint8_t *reg_data, uint32_t len, void *intf_ptr); + +/*! + * @brief Function for writing the sensor's registers through I2C bus. + * + * @param[in] reg_addr : Register address. + * @param[in] reg_data : Pointer to the data buffer whose value is to be written. + * @param[in] length : No of bytes to write. + * @param[in] intf_ptr : Interface pointer + * + * @return Status of execution + * @retval = BMA4_INTF_RET_SUCCESS -> Success + * @retval != BMA4_INTF_RET_SUCCESS -> Failure Info + * + */ +BMA4_INTF_RET_TYPE bma4_i2c_write(uint8_t reg_addr, const uint8_t *reg_data, uint32_t len, void *intf_ptr); + +/*! + * @brief Function for reading the sensor's registers through SPI bus. + * + * @param[in] reg_addr : Register address. + * @param[out] reg_data : Pointer to the data buffer to store the read data. + * @param[in] length : No of bytes to read. + * @param[in] intf_ptr : Interface pointer + * + * @return Status of execution + * @retval = BMA4_INTF_RET_SUCCESS -> Success + * @retval != BMA4_INTF_RET_SUCCESS -> Failure Info + * + */ +BMA4_INTF_RET_TYPE bma4_spi_read(uint8_t reg_addr, uint8_t *reg_data, uint32_t len, void *intf_ptr); + +/*! + * @brief Function for writing the sensor's registers through SPI bus. + * + * @param[in] reg_addr : Register address. + * @param[in] reg_data : Pointer to the data buffer whose data has to be written. + * @param[in] length : No of bytes to write. + * @param[in] intf_ptr : Interface pointer + * + * @return Status of execution + * @retval = BMA4_INTF_RET_SUCCESS -> Success + * @retval != BMA4_INTF_RET_SUCCESS -> Failure Info + * + */ +BMA4_INTF_RET_TYPE bma4_spi_write(uint8_t reg_addr, const uint8_t *reg_data, uint32_t len, void *intf_ptr); + +/*! + * @brief This function provides the delay for required time (Microsecond) as per the input provided in some of the + * APIs. + * + * @param[in] period_us : The required wait time in microsecond. + * @param[in] intf_ptr : Interface pointer + * + * @return void. + * + */ +void bma4_delay_us(uint32_t period, void *intf_ptr); + +/*! + * @brief Function to select the interface between SPI and I2C. + * + * @param[in] bma : Structure instance of bma4_dev + * @param[in] intf : Interface selection parameter + * @param[in] variant : Variant information of the sensor + * ( BMA42x variants values - BMA42X_VARIANT / BMA42X_B_VARIANT ) + * ( BMA45x variants values - BMA45X_VARIANT ) + * + * @return Status of execution + * @retval 0 -> Success + * @retval < 0 -> Failure Info + */ +int8_t bma4_interface_init(struct bma4_dev *bma, uint8_t intf, enum bma4_variant variant); + +/*! + * @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 bma4_error_codes_print_result(const char api_name[], int8_t rslt); + +/*! + * @brief Deinitializes coines platform + * + * @return void. + */ +void bma4_coines_deinit(void); + +#ifdef __cplusplus +} +#endif /* End of CPP guard */ + +#endif /* COMMON_H */ diff --git a/components/bma456/bma456w_examples/fifo_full_header_mode/Makefile b/components/bma456/bma456w_examples/fifo_full_header_mode/Makefile new file mode 100644 index 0000000..800928a --- /dev/null +++ b/components/bma456/bma456w_examples/fifo_full_header_mode/Makefile @@ -0,0 +1,20 @@ +COINES_INSTALL_PATH ?= ../../../.. + +EXAMPLE_FILE ?= fifo_full_header_mode.c + +API_LOCATION ?= ../.. + +COMMON_LOCATION ?= .. + +C_SRCS += \ +$(API_LOCATION)/bma4.c \ +$(API_LOCATION)/bma456w.c \ +$(COMMON_LOCATION)/common/common.c + +INCLUDEPATHS += \ +$(API_LOCATION) \ +$(COMMON_LOCATION)/common + +TARGET=MCU_APP30 + +include $(COINES_INSTALL_PATH)/coines.mk \ No newline at end of file diff --git a/components/bma456/bma456w_examples/fifo_full_header_mode/fifo_full_header_mode.c b/components/bma456/bma456w_examples/fifo_full_header_mode/fifo_full_header_mode.c new file mode 100644 index 0000000..615bcb6 --- /dev/null +++ b/components/bma456/bma456w_examples/fifo_full_header_mode/fifo_full_header_mode.c @@ -0,0 +1,173 @@ +/**\ + * Copyright (c) 2022 Bosch Sensortec GmbH. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + **/ + +#include +#include "bma456w.h" +#include "common.h" + +/******************************************************************************/ +/*! Macro definition */ + +/*! Buffer size allocated to store raw FIFO data */ +#define BMA456W_FIFO_RAW_DATA_BUFFER_SIZE UINT16_C(1024) + +/*! Length of data to be read from FIFO */ +#define BMA456W_FIFO_RAW_DATA_USER_LENGTH UINT16_C(1024) + +/*! Number of accel frames to be extracted from FIFO + * Calculation: + * fifo_buffer = 1024, accel_frame_len = 6, header_byte = 1. + * fifo_accel_frame_count = (1024 / (6 + 1)) = 147 frames + * + * Extra frames to parse sensortime data + */ +#define BMA456W_FIFO_ACCEL_FRAME_COUNT UINT8_C(170) + +/******************************************************************************/ +/*! Function */ + +/* This function starts the execution of program */ +int main(void) +{ + /* Status of API are returned to this variable */ + int8_t rslt; + + /* Accelerometer configuration structure */ + struct bma4_accel_config acc_conf = { 0 }; + + /* Sensor initialization configuration */ + struct bma4_dev dev = { 0 }; + + /* Number of accelerometer frames */ + uint16_t accel_length; + + /* Variable to idx bytes */ + uint16_t idx = 0; + + /* Variable to maintain count of loop to run FIFO read */ + uint8_t loop = 1; + + /* Number of bytes of FIFO data + * NOTE : Dummy byte (for SPI Interface) required for FIFO data read must be given as part of array size + */ + uint8_t fifo_data[BMA456W_FIFO_RAW_DATA_BUFFER_SIZE + BMA4_SENSORTIME_OVERHEAD_BYTE] = { 0 }; + + /* Array of accelerometer frames -> Total bytes = + * 147 * (6 axes bytes(+/- x,y,z) + 1 header byte) = 1029 bytes */ + struct bma4_accel fifo_accel_data[BMA456W_FIFO_ACCEL_FRAME_COUNT] = { { 0 } }; + + /* Initialize FIFO frame structure */ + struct bma4_fifo_frame fifoframe = { 0 }; + + /* Variable that contains interrupt status value */ + uint16_t int_status = 0; + + /* Variable to hold the length of FIFO data */ + uint16_t fifo_length = 0; + + /* Interface reference is given as a parameter + * For I2C : BMA4_I2C_INTF + * For SPI : BMA4_SPI_INTF + * Variant information given as parameter - BMA45X_VARIANT + */ + rslt = bma4_interface_init(&dev, BMA4_I2C_INTF, BMA45X_VARIANT); + bma4_error_codes_print_result("bma4_interface_init", rslt); + + /* Initialize BMA456W */ + rslt = bma456w_init(&dev); + bma4_error_codes_print_result("bma456w_init status", rslt); + + /* Accelerometer configuration settings */ + acc_conf.odr = BMA4_OUTPUT_DATA_RATE_100HZ; + acc_conf.bandwidth = BMA4_ACCEL_NORMAL_AVG4; + acc_conf.range = BMA4_ACCEL_RANGE_2G; + acc_conf.perf_mode = BMA4_CIC_AVG_MODE; + + /* Set the accel configurations */ + rslt = bma4_set_accel_config(&acc_conf, &dev); + bma4_error_codes_print_result("bma4_set_accel_config status", rslt); + + /* NOTE : Enable accel after set of configurations */ + rslt = bma4_set_accel_enable(1, &dev); + bma4_error_codes_print_result("bma4_set_accel_enable status", rslt); + + /* Disabling advance power save mode as FIFO data is not accessible in advance low power mode */ + rslt = bma4_set_advance_power_save(BMA4_DISABLE, &dev); + bma4_error_codes_print_result("bma4_set_advance_power_save status", rslt); + + /* Clear FIFO configuration register */ + rslt = bma4_set_fifo_config(BMA4_FIFO_ALL, BMA4_DISABLE, &dev); + bma4_error_codes_print_result("bma4_set_fifo_config disable status", rslt); + + /* Set FIFO configuration by enabling accel. + * NOTE 1: The header mode is enabled by default. + * NOTE 2: By default the FIFO operating mode is FIFO mode. */ + rslt = bma4_set_fifo_config(BMA4_FIFO_ACCEL | BMA4_FIFO_HEADER | BMA4_FIFO_TIME, BMA4_ENABLE, &dev); + bma4_error_codes_print_result("bma4_set_fifo_config enable status", rslt); + + /* Update FIFO structure */ + fifoframe.data = fifo_data; + fifoframe.length = BMA456W_FIFO_RAW_DATA_USER_LENGTH + BMA4_SENSORTIME_OVERHEAD_BYTE; + + printf("FIFO is configured in header mode\n"); + + rslt = bma456w_map_interrupt(BMA4_INTR1_MAP, BMA4_FIFO_FULL_INT, BMA4_ENABLE, &dev); + bma4_error_codes_print_result("bma4_map_interrupt status", rslt); + + while (loop <= 10) + { + rslt = bma456w_read_int_status(&int_status, &dev); + bma4_error_codes_print_result("bma4_read_int_status", rslt); + + if ((rslt == BMA4_OK) && (int_status & BMA4_FIFO_FULL_INT)) + { + printf("\nIteration : %d\n", loop); + + rslt = bma4_get_fifo_length(&fifo_length, &dev); + bma4_error_codes_print_result("bma4_get_fifo_length status", rslt); + + printf("FIFO data bytes available : %d\n", fifo_length); + printf("FIFO data bytes requested : %d\n", fifoframe.length); + + /* Read FIFO data */ + rslt = bma4_read_fifo_data(&fifoframe, &dev); + bma4_error_codes_print_result("bma4_read_fifo_data status", rslt); + + accel_length = BMA456W_FIFO_ACCEL_FRAME_COUNT; + + if (rslt == BMA4_OK) + { + printf("Requested data frames before parsing: %d\n", accel_length); + + /* Parse the FIFO data to extract accelerometer data from the FIFO buffer */ + rslt = bma4_extract_accel(fifo_accel_data, &accel_length, &fifoframe, &dev); + printf("Parsed accelerometer data frames: %d\n", accel_length); + + printf("ACCEL, X, Y, Z\n"); + + /* Print the parsed accelerometer data from the FIFO buffer */ + for (idx = 0; idx < accel_length; idx++) + { + printf("%d, %d, %d, %d\n", + idx, + fifo_accel_data[idx].x, + fifo_accel_data[idx].y, + fifo_accel_data[idx].z); + } + + /* Print control frames like sensor time and skipped frame count */ + printf("Skipped frame count = %d\n", fifoframe.skipped_frame_count); + printf("Sensor time(in seconds) = %.4lf s\r\n", (fifoframe.sensor_time * BMA4_SENSORTIME_RESOLUTION)); + } + + loop++; + } + } + + bma4_coines_deinit(); + + return rslt; +} diff --git a/components/bma456/bma456w_examples/fifo_full_header_mode_hw_int/Makefile b/components/bma456/bma456w_examples/fifo_full_header_mode_hw_int/Makefile new file mode 100644 index 0000000..b83bd9b --- /dev/null +++ b/components/bma456/bma456w_examples/fifo_full_header_mode_hw_int/Makefile @@ -0,0 +1,20 @@ +COINES_INSTALL_PATH ?= ../../../.. + +EXAMPLE_FILE ?= fifo_full_header_mode_hw_int.c + +API_LOCATION ?= ../.. + +COMMON_LOCATION ?= .. + +C_SRCS += \ +$(API_LOCATION)/bma4.c \ +$(API_LOCATION)/bma456w.c \ +$(COMMON_LOCATION)/common/common.c + +INCLUDEPATHS += \ +$(API_LOCATION) \ +$(COMMON_LOCATION)/common + +TARGET = MCU_APP30 + +include $(COINES_INSTALL_PATH)/coines.mk \ No newline at end of file diff --git a/components/bma456/bma456w_examples/fifo_full_header_mode_hw_int/fifo_full_header_mode_hw_int.c b/components/bma456/bma456w_examples/fifo_full_header_mode_hw_int/fifo_full_header_mode_hw_int.c new file mode 100644 index 0000000..2fbd066 --- /dev/null +++ b/components/bma456/bma456w_examples/fifo_full_header_mode_hw_int/fifo_full_header_mode_hw_int.c @@ -0,0 +1,290 @@ +/**\ + * Copyright (c) 2022 Bosch Sensortec GmbH. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + **/ + +#include +#include +#include +#include "bma456w.h" +#include "common.h" +#include "coines.h" + +/******************************************************************************/ +/*! Global variable Declaration */ + +volatile uint8_t interrupt_status = 0; + +/******************************************************************************/ +/*! Macro definition */ + +/*! Buffer size allocated to store raw FIFO data */ +#define BMA456W_FIFO_RAW_DATA_BUFFER_SIZE UINT16_C(1024) + +/*! Length of data to be read from FIFO */ +#define BMA456W_FIFO_RAW_DATA_USER_LENGTH UINT16_C(1024) + +/*! Number of accel frames to be extracted from FIFO + * Calculation: + * fifo_buffer = 1024, accel_frame_len = 6, header_byte = 1. + * fifo_accel_frame_count = (1024 / (6 + 1)) = 147 frames + * + * Extra frames to parse sensortime data + */ +#define BMA456W_FIFO_ACCEL_FRAME_COUNT UINT8_C(170) + +/*! APP20 Board number */ +#define BOARD_MCU_APP20 UINT8_C(0x03) + +/*! APP30 Board number */ +#define BOARD_MCU_APP30 UINT8_C(0x05) + +/******************************************************************************/ +/*! Static Function Declaration */ + +/*! + * @brief This function gets board information + * + * @param[out] board : Board value to determine as APP2.0 or APP3.0 + */ +static void get_board_info(uint8_t *board); + +/*! + * @brief This internal API is used to set the interrupt status + */ +static void interrupt_callback(uint32_t param1, uint32_t param2) +{ + (void)param1; + (void)param2; + interrupt_status = 1; +} + +/******************************************************************************/ +/*! Function */ + +/* This function starts the execution of program */ +int main(void) +{ + /* Status of API are returned to this variable */ + int8_t rslt; + + /* Accelerometer configuration structure */ + struct bma4_accel_config acc_conf = { 0 }; + + /* Sensor initialization configuration */ + struct bma4_dev dev = { 0 }; + + /* Number of accelerometer frames */ + uint16_t accel_length; + + /* Variable to idx bytes */ + uint16_t idx = 0; + + /* Variable to maintain count of loop to run FIFO read */ + uint8_t loop = 1; + + /* Number of bytes of FIFO data + * NOTE : Dummy byte (for SPI Interface) required for FIFO data read must be given as part of array size + */ + uint8_t fifo_data[BMA456W_FIFO_RAW_DATA_BUFFER_SIZE + BMA4_SENSORTIME_OVERHEAD_BYTE] = { 0 }; + + /* Array of accelerometer frames -> Total bytes = + * 147 * (6 axes bytes(+/- x,y,z) + 1 header byte) = 1029 bytes */ + struct bma4_accel fifo_accel_data[BMA456W_FIFO_ACCEL_FRAME_COUNT] = { { 0 } }; + + /* Initialize FIFO frame structure */ + struct bma4_fifo_frame fifoframe = { 0 }; + + /* Variable that contains interrupt status value */ + uint16_t int_status = 0; + + /* Variable to hold the length of FIFO data */ + uint16_t fifo_length = 0; + + struct bma4_int_pin_config pin_config = { 0 }; + uint8_t board = 0; + + /* Variable for interrupt line selection*/ + uint8_t int_line; + + /* Interface reference is given as a parameter + * For I2C : BMA4_I2C_INTF + * For SPI : BMA4_SPI_INTF + * Variant information given as parameter - BMA45X_VARIANT + */ + rslt = bma4_interface_init(&dev, BMA4_I2C_INTF, BMA45X_VARIANT); + bma4_error_codes_print_result("bma4_interface_init", rslt); + + /* Initialize BMA456W */ + rslt = bma456w_init(&dev); + bma4_error_codes_print_result("bma456w_init status", rslt); + + /* Accelerometer configuration settings */ + acc_conf.odr = BMA4_OUTPUT_DATA_RATE_100HZ; + acc_conf.bandwidth = BMA4_ACCEL_NORMAL_AVG4; + acc_conf.range = BMA4_ACCEL_RANGE_2G; + acc_conf.perf_mode = BMA4_CIC_AVG_MODE; + + /* Set the accel configurations */ + rslt = bma4_set_accel_config(&acc_conf, &dev); + bma4_error_codes_print_result("bma4_set_accel_config status", rslt); + + /* NOTE : Enable accel after set of configurations */ + rslt = bma4_set_accel_enable(1, &dev); + bma4_error_codes_print_result("bma4_set_accel_enable status", rslt); + + /* Disabling advance power save mode as FIFO data is not accessible in advance low power mode */ + rslt = bma4_set_advance_power_save(BMA4_DISABLE, &dev); + bma4_error_codes_print_result("bma4_set_advance_power_save status", rslt); + + /* Clear FIFO configuration register */ + rslt = bma4_set_fifo_config(BMA4_FIFO_ALL, BMA4_DISABLE, &dev); + bma4_error_codes_print_result("bma4_set_fifo_config disable status", rslt); + + /* Set FIFO configuration by enabling accel. + * NOTE 1: The header mode is enabled by default. + * NOTE 2: By default the FIFO operating mode is FIFO mode. */ + rslt = bma4_set_fifo_config(BMA4_FIFO_ACCEL | BMA4_FIFO_HEADER | BMA4_FIFO_TIME, BMA4_ENABLE, &dev); + bma4_error_codes_print_result("bma4_set_fifo_config enable status", rslt); + + /* Update FIFO structure */ + fifoframe.data = fifo_data; + fifoframe.length = BMA456W_FIFO_RAW_DATA_USER_LENGTH + BMA4_SENSORTIME_OVERHEAD_BYTE; + + printf("FIFO is configured in header mode\n"); + + /* Hardware interrupt configuration */ + int_line = BMA4_INTR1_MAP; + + rslt = bma456w_map_interrupt(int_line, BMA4_FIFO_FULL_INT, BMA4_ENABLE, &dev); + bma4_error_codes_print_result("bma456w_map_interrupt status", rslt); + + pin_config.edge_ctrl = BMA4_EDGE_TRIGGER; + pin_config.output_en = BMA4_OUTPUT_ENABLE; + pin_config.lvl = BMA4_ACTIVE_HIGH; + pin_config.od = BMA4_PUSH_PULL; + pin_config.input_en = BMA4_INPUT_DISABLE; + + rslt = bma4_set_int_pin_config(&pin_config, int_line, &dev); + bma4_error_codes_print_result("bma4_set_int_pin_config status", rslt); + + /* Get board information */ + get_board_info(&board); + + /* + * Attach interrupt based on board + */ + if (board == BOARD_MCU_APP20) + { + switch (int_line) + { + case BMA4_INTR1_MAP: + coines_attach_interrupt(COINES_SHUTTLE_PIN_20, interrupt_callback, COINES_PIN_INTERRUPT_RISING_EDGE); + break; + + case BMA4_INTR2_MAP: + coines_attach_interrupt(COINES_SHUTTLE_PIN_21, interrupt_callback, COINES_PIN_INTERRUPT_RISING_EDGE); + break; + + default: + break; + } + } + +#if !defined(MCU_APP20) + else if (board == BOARD_MCU_APP30) + { + switch (int_line) + { + case BMA4_INTR1_MAP: + coines_attach_interrupt(COINES_MINI_SHUTTLE_PIN_1_6, + interrupt_callback, + COINES_PIN_INTERRUPT_RISING_EDGE); + break; + + case BMA4_INTR2_MAP: + coines_attach_interrupt(COINES_MINI_SHUTTLE_PIN_1_7, + interrupt_callback, + COINES_PIN_INTERRUPT_RISING_EDGE); + break; + + default: + break; + } + } +#endif + + while (loop <= 10) + { + if (interrupt_status == 1) + { + interrupt_status = 0; + + rslt = bma456w_read_int_status(&int_status, &dev); + bma4_error_codes_print_result("bma4_read_int_status", rslt); + + if ((rslt == BMA4_OK) && (int_status & BMA4_FIFO_FULL_INT)) + { + printf("\nIteration : %d\n", loop); + + rslt = bma4_get_fifo_length(&fifo_length, &dev); + bma4_error_codes_print_result("bma4_get_fifo_length status", rslt); + + printf("FIFO data bytes available : %d\n", fifo_length); + printf("FIFO data bytes requested : %d\n", fifoframe.length); + + /* Read FIFO data */ + rslt = bma4_read_fifo_data(&fifoframe, &dev); + bma4_error_codes_print_result("bma4_read_fifo_data status", rslt); + + accel_length = BMA456W_FIFO_ACCEL_FRAME_COUNT; + + if (rslt == BMA4_OK) + { + printf("Requested data frames before parsing: %d\n", accel_length); + + /* Parse the FIFO data to extract accelerometer data from the FIFO buffer */ + rslt = bma4_extract_accel(fifo_accel_data, &accel_length, &fifoframe, &dev); + printf("Parsed accelerometer data frames: %d\n", accel_length); + + printf("ACCEL, X, Y, Z\n"); + + /* Print the parsed accelerometer data from the FIFO buffer */ + for (idx = 0; idx < accel_length; idx++) + { + printf("%d, %d, %d, %d\n", idx, fifo_accel_data[idx].x, fifo_accel_data[idx].y, + fifo_accel_data[idx].z); + } + + /* Print control frames like sensor time and skipped frame count */ + printf("Skipped frame count = %d\n", fifoframe.skipped_frame_count); + printf("Sensor time(in seconds) = %.4lf s\r\n", + (fifoframe.sensor_time * BMA4_SENSORTIME_RESOLUTION)); + } + + loop++; + } + } + } + + bma4_coines_deinit(); + + return rslt; +} + +/*! + * @brief This function gets board information + */ +static void get_board_info(uint8_t *board) +{ + struct coines_board_info board_info; + int16_t result; + + result = coines_get_board_info(&board_info); + + if (result == COINES_SUCCESS) + { + (*board) = board_info.board; + } +} diff --git a/components/bma456/bma456w_examples/fifo_full_headerless_mode/Makefile b/components/bma456/bma456w_examples/fifo_full_headerless_mode/Makefile new file mode 100644 index 0000000..bbfc638 --- /dev/null +++ b/components/bma456/bma456w_examples/fifo_full_headerless_mode/Makefile @@ -0,0 +1,18 @@ +COINES_INSTALL_PATH ?= ../../../.. + +EXAMPLE_FILE ?= fifo_full_headerless_mode.c + +API_LOCATION ?= ../.. + +COMMON_LOCATION ?= .. + +C_SRCS += \ +$(API_LOCATION)/bma4.c \ +$(API_LOCATION)/bma456w.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/components/bma456/bma456w_examples/fifo_full_headerless_mode/fifo_full_headerless_mode.c b/components/bma456/bma456w_examples/fifo_full_headerless_mode/fifo_full_headerless_mode.c new file mode 100644 index 0000000..d02d396 --- /dev/null +++ b/components/bma456/bma456w_examples/fifo_full_headerless_mode/fifo_full_headerless_mode.c @@ -0,0 +1,171 @@ +/**\ + * Copyright (c) 2022 Bosch Sensortec GmbH. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + **/ + +#include +#include "bma456w.h" +#include "common.h" + +/******************************************************************************/ +/*! Macro definition */ + +/*! Buffer size allocated to store raw FIFO data */ +#define BMA456W_FIFO_RAW_DATA_BUFFER_SIZE UINT16_C(1024) + +/*! Length of data to be read from FIFO */ +#define BMA456W_FIFO_RAW_DATA_USER_LENGTH UINT16_C(1024) + +/*! Number of accel frames to be extracted from FIFO + * Calculation: + * fifo_buffer = 1024, accel_frame_len = 6. + * fifo_accel_frame_count = (1024 / 6) = 170 frames + */ +#define BMA456W_FIFO_ACCEL_FRAME_COUNT UINT8_C(170) + +/******************************************************************************/ +/*! Function */ + +/* This function starts the execution of program */ +int main(void) +{ + /* Status of API are returned to this variable */ + int8_t rslt; + + /* Accelerometer configuration structure */ + struct bma4_accel_config acc_conf = { 0 }; + + /* Sensor initialization configuration */ + struct bma4_dev dev = { 0 }; + + /* Number of accelerometer frames */ + uint16_t accel_length; + + /* Variable to idx bytes */ + uint16_t idx = 0; + + /* Variable to maintain count of loop to run FIFO read */ + uint8_t loop = 1; + + /* Number of bytes of FIFO data + * NOTE : Dummy byte (for SPI Interface) required for FIFO data read must be given as part of array size + */ + uint8_t fifo_data[BMA456W_FIFO_RAW_DATA_BUFFER_SIZE] = { 0 }; + + /* Array of accelerometer frames -> Total bytes = + * 170 * (6 axes bytes(+/- x,y,z)) = 1020 bytes */ + struct bma4_accel fifo_accel_data[BMA456W_FIFO_ACCEL_FRAME_COUNT] = { { 0 } }; + + /* Initialize FIFO frame structure */ + struct bma4_fifo_frame fifoframe = { 0 }; + + /* Variable that contains interrupt status value */ + uint16_t int_status = 0; + + /* Variable to hold the length of FIFO data */ + uint16_t fifo_length = 0; + + /* Interface reference is given as a parameter + * For I2C : BMA4_I2C_INTF + * For SPI : BMA4_SPI_INTF + * Variant information given as parameter - BMA45X_VARIANT + */ + rslt = bma4_interface_init(&dev, BMA4_I2C_INTF, BMA45X_VARIANT); + bma4_error_codes_print_result("bma4_interface_init", rslt); + + /* Initialize BMA456W */ + rslt = bma456w_init(&dev); + bma4_error_codes_print_result("bma456w_init status", rslt); + + /* Accelerometer configuration settings */ + acc_conf.odr = BMA4_OUTPUT_DATA_RATE_100HZ; + acc_conf.bandwidth = BMA4_ACCEL_NORMAL_AVG4; + acc_conf.range = BMA4_ACCEL_RANGE_2G; + acc_conf.perf_mode = BMA4_CIC_AVG_MODE; + + /* Set the accel configurations */ + rslt = bma4_set_accel_config(&acc_conf, &dev); + bma4_error_codes_print_result("bma4_set_accel_config status", rslt); + + /* NOTE : Enable accel after set of configurations */ + rslt = bma4_set_accel_enable(1, &dev); + bma4_error_codes_print_result("bma4_set_accel_enable status", rslt); + + /* Disabling advance power save mode as FIFO data is not accessible in advance low power mode */ + rslt = bma4_set_advance_power_save(BMA4_DISABLE, &dev); + bma4_error_codes_print_result("bma4_set_advance_power_save status", rslt); + + /* Clear FIFO configuration register */ + rslt = bma4_set_fifo_config(BMA4_FIFO_ALL, BMA4_DISABLE, &dev); + bma4_error_codes_print_result("bma4_set_fifo_config disable status", rslt); + + /* Set FIFO configuration by enabling accel. + * NOTE 1: The header mode is enabled by default. + * NOTE 2: By default the FIFO operating mode is FIFO mode. */ + rslt = bma4_set_fifo_config(BMA4_FIFO_ACCEL, BMA4_ENABLE, &dev); + bma4_error_codes_print_result("bma4_set_fifo_config enable status", rslt); + + /* Update FIFO structure */ + fifoframe.data = fifo_data; + fifoframe.length = BMA456W_FIFO_RAW_DATA_USER_LENGTH; + + /* To enable headerless mode, disable the header. */ + rslt = bma4_set_fifo_config(BMA4_FIFO_HEADER, BMA4_DISABLE, &dev); + bma4_error_codes_print_result("bma4_set_fifo_config status", rslt); + + printf("FIFO is configured in headerless mode\n"); + + rslt = bma456w_map_interrupt(BMA4_INTR1_MAP, BMA4_FIFO_FULL_INT, BMA4_ENABLE, &dev); + bma4_error_codes_print_result("bma4_map_interrupt status", rslt); + + while (loop <= 10) + { + rslt = bma456w_read_int_status(&int_status, &dev); + bma4_error_codes_print_result("bma4_read_int_status", rslt); + + if ((rslt == BMA4_OK) && (int_status & BMA4_FIFO_FULL_INT)) + { + printf("\nIteration : %d\n", loop); + + rslt = bma4_get_fifo_length(&fifo_length, &dev); + bma4_error_codes_print_result("bma4_get_fifo_length status", rslt); + + printf("FIFO data bytes available : %d\n", fifo_length); + printf("FIFO data bytes requested : %d\n", fifoframe.length); + + /* Read FIFO data */ + rslt = bma4_read_fifo_data(&fifoframe, &dev); + bma4_error_codes_print_result("bma4_read_fifo_data status", rslt); + + accel_length = BMA456W_FIFO_ACCEL_FRAME_COUNT; + + if (rslt == BMA4_OK) + { + printf("Requested data frames before parsing: %d\n", accel_length); + + /* Parse the FIFO data to extract accelerometer data from the FIFO buffer */ + rslt = bma4_extract_accel(fifo_accel_data, &accel_length, &fifoframe, &dev); + printf("Parsed accelerometer data frames: %d\n", accel_length); + + printf("ACCEL, X, Y, Z\n"); + + /* Print the parsed accelerometer data from the FIFO buffer */ + for (idx = 0; idx < accel_length; idx++) + { + printf("%d, %d, %d, %d\n", + idx, + fifo_accel_data[idx].x, + fifo_accel_data[idx].y, + fifo_accel_data[idx].z); + } + } + + loop++; + } + } + + bma4_coines_deinit(); + + return rslt; +} diff --git a/components/bma456/bma456w_examples/fifo_full_headerless_mode_hw_int/Makefile b/components/bma456/bma456w_examples/fifo_full_headerless_mode_hw_int/Makefile new file mode 100644 index 0000000..07db9ba --- /dev/null +++ b/components/bma456/bma456w_examples/fifo_full_headerless_mode_hw_int/Makefile @@ -0,0 +1,20 @@ +COINES_INSTALL_PATH ?= ../../../.. + +EXAMPLE_FILE ?= fifo_full_headerless_mode_hw_int.c + +API_LOCATION ?= ../.. + +COMMON_LOCATION ?= .. + +C_SRCS += \ +$(API_LOCATION)/bma4.c \ +$(API_LOCATION)/bma456w.c \ +$(COMMON_LOCATION)/common/common.c + +INCLUDEPATHS += \ +$(API_LOCATION) \ +$(COMMON_LOCATION)/common + +TARGET = MCU_APP30 + +include $(COINES_INSTALL_PATH)/coines.mk \ No newline at end of file diff --git a/components/bma456/bma456w_examples/fifo_full_headerless_mode_hw_int/fifo_full_headerless_mode_hw_int.c b/components/bma456/bma456w_examples/fifo_full_headerless_mode_hw_int/fifo_full_headerless_mode_hw_int.c new file mode 100644 index 0000000..fe25ad1 --- /dev/null +++ b/components/bma456/bma456w_examples/fifo_full_headerless_mode_hw_int/fifo_full_headerless_mode_hw_int.c @@ -0,0 +1,286 @@ +/**\ + * Copyright (c) 2022 Bosch Sensortec GmbH. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + **/ + +#include +#include +#include "bma456w.h" +#include "common.h" +#include "coines.h" + +/******************************************************************************/ +/*! Global variable Declaration */ + +volatile uint8_t interrupt_status = 0; + +/******************************************************************************/ +/*! Macro definition */ + +/*! Buffer size allocated to store raw FIFO data */ +#define BMA456W_FIFO_RAW_DATA_BUFFER_SIZE UINT16_C(1024) + +/*! Length of data to be read from FIFO */ +#define BMA456W_FIFO_RAW_DATA_USER_LENGTH UINT16_C(1024) + +/*! Number of accel frames to be extracted from FIFO + * Calculation: + * fifo_buffer = 1024, accel_frame_len = 6. + * fifo_accel_frame_count = (1024 / 6) = 170 frames + */ +#define BMA456W_FIFO_ACCEL_FRAME_COUNT UINT8_C(170) + +/*! APP20 Board number */ +#define BOARD_MCU_APP20 UINT8_C(0x03) + +/*! APP30 Board number */ +#define BOARD_MCU_APP30 UINT8_C(0x05) + +/******************************************************************************/ +/*! Static Function Declaration */ + +/*! + * @brief This function gets board information + * + * @param[out] board : Board value to determine as APP2.0 or APP3.0 + */ +static void get_board_info(uint8_t *board); + +/*! + * @brief This internal API is used to set the interrupt status + */ +static void interrupt_callback(uint32_t param1, uint32_t param2) +{ + (void)param1; + (void)param2; + interrupt_status = 1; +} + +/******************************************************************************/ +/*! Function */ + +/* This function starts the execution of program */ +int main(void) +{ + /* Status of API are returned to this variable */ + int8_t rslt; + + /* Accelerometer configuration structure */ + struct bma4_accel_config acc_conf = { 0 }; + + /* Sensor initialization configuration */ + struct bma4_dev dev = { 0 }; + + /* Number of accelerometer frames */ + uint16_t accel_length; + + /* Variable to idx bytes */ + uint16_t idx = 0; + + /* Variable to maintain count of loop to run FIFO read */ + uint8_t loop = 1; + + /* Number of bytes of FIFO data + * NOTE : Dummy byte (for SPI Interface) required for FIFO data read must be given as part of array size + */ + uint8_t fifo_data[BMA456W_FIFO_RAW_DATA_BUFFER_SIZE] = { 0 }; + + /* Array of accelerometer frames -> Total bytes = + * 170 * (6 axes bytes(+/- x,y,z)) = 1020 bytes */ + struct bma4_accel fifo_accel_data[BMA456W_FIFO_ACCEL_FRAME_COUNT] = { { 0 } }; + + /* Initialize FIFO frame structure */ + struct bma4_fifo_frame fifoframe = { 0 }; + + /* Variable that contains interrupt status value */ + uint16_t int_status = 0; + + /* Variable to hold the length of FIFO data */ + uint16_t fifo_length = 0; + + struct bma4_int_pin_config pin_config = { 0 }; + uint8_t board = 0; + + /* Variable for interrupt line selection*/ + uint8_t int_line; + + /* Interface reference is given as a parameter + * For I2C : BMA4_I2C_INTF + * For SPI : BMA4_SPI_INTF + * Variant information given as parameter - BMA45X_VARIANT + */ + rslt = bma4_interface_init(&dev, BMA4_I2C_INTF, BMA45X_VARIANT); + bma4_error_codes_print_result("bma4_interface_init", rslt); + + /* Initialize BMA456W */ + rslt = bma456w_init(&dev); + bma4_error_codes_print_result("bma456w_init status", rslt); + + /* Accelerometer configuration settings */ + acc_conf.odr = BMA4_OUTPUT_DATA_RATE_100HZ; + acc_conf.bandwidth = BMA4_ACCEL_NORMAL_AVG4; + acc_conf.range = BMA4_ACCEL_RANGE_2G; + acc_conf.perf_mode = BMA4_CIC_AVG_MODE; + + /* Set the accel configurations */ + rslt = bma4_set_accel_config(&acc_conf, &dev); + bma4_error_codes_print_result("bma4_set_accel_config status", rslt); + + /* NOTE : Enable accel after set of configurations */ + rslt = bma4_set_accel_enable(1, &dev); + bma4_error_codes_print_result("bma4_set_accel_enable status", rslt); + + /* Disabling advance power save mode as FIFO data is not accessible in advance low power mode */ + rslt = bma4_set_advance_power_save(BMA4_DISABLE, &dev); + bma4_error_codes_print_result("bma4_set_advance_power_save status", rslt); + + /* Clear FIFO configuration register */ + rslt = bma4_set_fifo_config(BMA4_FIFO_ALL, BMA4_DISABLE, &dev); + bma4_error_codes_print_result("bma4_set_fifo_config disable status", rslt); + + /* Set FIFO configuration by enabling accel. + * NOTE 1: The header mode is enabled by default. + * NOTE 2: By default the FIFO operating mode is FIFO mode. */ + rslt = bma4_set_fifo_config(BMA4_FIFO_ACCEL, BMA4_ENABLE, &dev); + bma4_error_codes_print_result("bma4_set_fifo_config enable status", rslt); + + /* Update FIFO structure */ + fifoframe.data = fifo_data; + fifoframe.length = BMA456W_FIFO_RAW_DATA_USER_LENGTH; + + /* To enable headerless mode, disable the header. */ + rslt = bma4_set_fifo_config(BMA4_FIFO_HEADER, BMA4_DISABLE, &dev); + bma4_error_codes_print_result("bma4_set_fifo_config status", rslt); + + printf("FIFO is configured in headerless mode\n"); + + /* Hardware interrupt configuration */ + int_line = BMA4_INTR2_MAP; + + rslt = bma456w_map_interrupt(int_line, BMA4_FIFO_FULL_INT, BMA4_ENABLE, &dev); + bma4_error_codes_print_result("bma456w_map_interrupt status", rslt); + + pin_config.edge_ctrl = BMA4_EDGE_TRIGGER; + pin_config.output_en = BMA4_OUTPUT_ENABLE; + pin_config.lvl = BMA4_ACTIVE_HIGH; + pin_config.od = BMA4_PUSH_PULL; + pin_config.input_en = BMA4_INPUT_DISABLE; + + rslt = bma4_set_int_pin_config(&pin_config, int_line, &dev); + bma4_error_codes_print_result("bma4_set_int_pin_config status", rslt); + + /* Get board information */ + get_board_info(&board); + + /* + * Attach interrupt based on board + */ + if (board == BOARD_MCU_APP20) + { + switch (int_line) + { + case BMA4_INTR1_MAP: + coines_attach_interrupt(COINES_SHUTTLE_PIN_20, interrupt_callback, COINES_PIN_INTERRUPT_RISING_EDGE); + break; + + case BMA4_INTR2_MAP: + coines_attach_interrupt(COINES_SHUTTLE_PIN_21, interrupt_callback, COINES_PIN_INTERRUPT_RISING_EDGE); + break; + + default: + break; + } + } + +#if !defined(MCU_APP20) + else if (board == BOARD_MCU_APP30) + { + switch (int_line) + { + case BMA4_INTR1_MAP: + coines_attach_interrupt(COINES_MINI_SHUTTLE_PIN_1_6, + interrupt_callback, + COINES_PIN_INTERRUPT_RISING_EDGE); + break; + + case BMA4_INTR2_MAP: + coines_attach_interrupt(COINES_MINI_SHUTTLE_PIN_1_7, + interrupt_callback, + COINES_PIN_INTERRUPT_RISING_EDGE); + break; + + default: + break; + } + } +#endif + + while (loop <= 10) + { + if (interrupt_status == 1) + { + interrupt_status = 0; + + rslt = bma456w_read_int_status(&int_status, &dev); + bma4_error_codes_print_result("bma4_read_int_status", rslt); + + if ((rslt == BMA4_OK) && (int_status & BMA4_FIFO_FULL_INT)) + { + printf("\nIteration : %d\n", loop); + + rslt = bma4_get_fifo_length(&fifo_length, &dev); + bma4_error_codes_print_result("bma4_get_fifo_length status", rslt); + + printf("FIFO data bytes available : %d\n", fifo_length); + printf("FIFO data bytes requested : %d\n", fifoframe.length); + + /* Read FIFO data */ + rslt = bma4_read_fifo_data(&fifoframe, &dev); + bma4_error_codes_print_result("bma4_read_fifo_data status", rslt); + + accel_length = BMA456W_FIFO_ACCEL_FRAME_COUNT; + + if (rslt == BMA4_OK) + { + printf("Requested data frames before parsing: %d\n", accel_length); + + /* Parse the FIFO data to extract accelerometer data from the FIFO buffer */ + rslt = bma4_extract_accel(fifo_accel_data, &accel_length, &fifoframe, &dev); + printf("Parsed accelerometer data frames: %d\n", accel_length); + + printf("ACCEL, X, Y, Z\n"); + + /* Print the parsed accelerometer data from the FIFO buffer */ + for (idx = 0; idx < accel_length; idx++) + { + printf("%d, %d, %d, %d\n", idx, fifo_accel_data[idx].x, fifo_accel_data[idx].y, + fifo_accel_data[idx].z); + } + } + + loop++; + } + } + } + + bma4_coines_deinit(); + + return rslt; +} + +/*! + * @brief This function gets board information + */ +static void get_board_info(uint8_t *board) +{ + struct coines_board_info board_info; + int16_t result; + + result = coines_get_board_info(&board_info); + + if (result == COINES_SUCCESS) + { + (*board) = board_info.board; + } +} diff --git a/components/bma456/bma456w_examples/fifo_watermark_header_mode/Makefile b/components/bma456/bma456w_examples/fifo_watermark_header_mode/Makefile new file mode 100644 index 0000000..503d2d8 --- /dev/null +++ b/components/bma456/bma456w_examples/fifo_watermark_header_mode/Makefile @@ -0,0 +1,20 @@ +COINES_INSTALL_PATH ?= ../../../.. + +EXAMPLE_FILE ?= fifo_watermark_header_mode.c + +API_LOCATION ?= ../.. + +COMMON_LOCATION ?= .. + +C_SRCS += \ +$(API_LOCATION)/bma4.c \ +$(API_LOCATION)/bma456w.c \ +$(COMMON_LOCATION)/common/common.c + +INCLUDEPATHS += \ +$(API_LOCATION) \ +$(COMMON_LOCATION)/common + +TARGET=MCU_APP30 + +include $(COINES_INSTALL_PATH)/coines.mk \ No newline at end of file diff --git a/components/bma456/bma456w_examples/fifo_watermark_header_mode/fifo_watermark_header_mode.c b/components/bma456/bma456w_examples/fifo_watermark_header_mode/fifo_watermark_header_mode.c new file mode 100644 index 0000000..2c7c59c --- /dev/null +++ b/components/bma456/bma456w_examples/fifo_watermark_header_mode/fifo_watermark_header_mode.c @@ -0,0 +1,188 @@ +/**\ + * Copyright (c) 2022 Bosch Sensortec GmbH. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + **/ + +#include +#include "bma456w.h" +#include "common.h" + +/******************************************************************************/ +/*! Macro definition */ + +/*! Buffer size allocated to store raw FIFO data */ +#define BMA456W_FIFO_RAW_DATA_BUFFER_SIZE UINT16_C(1024) + +/*! Length of data to be read from FIFO */ +#define BMA456W_FIFO_RAW_DATA_USER_LENGTH UINT16_C(1024) + +/*! Setting a watermark level in FIFO */ +#define BMA456W_FIFO_WATERMARK_LEVEL UINT16_C(650) + +/*! Number of accel frames to be extracted from FIFO + * Calculation: + * fifo_watermark_level = 650, accel_frame_len = 6, header_byte = 1. + * fifo_accel_frame_count = (650 / (6 + 1)) = 93 frames + * NOTE: Extra frames are read in order to get sensor time + */ +#define BMA456W_FIFO_ACCEL_FRAME_COUNT UINT8_C(200) + +/******************************************************************************/ +/*! Function */ + +/* This function starts the execution of program */ +int main(void) +{ + /* Status of API are returned to this variable */ + int8_t rslt; + + /* Accelerometer configuration structure */ + struct bma4_accel_config acc_conf = { 0 }; + + /* Sensor initialization configuration */ + struct bma4_dev dev = { 0 }; + + /* Number of accelerometer frames */ + uint16_t accel_length; + + /* Variable to idx bytes */ + uint16_t idx = 0; + + /* Variable to maintain count of loop to run FIFO read */ + uint8_t loop = 1; + + /* Number of bytes of FIFO data + * NOTE : Dummy byte (for SPI Interface) required for FIFO data read must be given as part of array size + */ + uint8_t fifo_data[BMA456W_FIFO_RAW_DATA_BUFFER_SIZE + BMA4_SENSORTIME_OVERHEAD_BYTE] = { 0 }; + + /* Array of accelerometer frames -> Total bytes = + * 100 * (6 axes bytes(+/- x,y,z) + 1 header byte) = 700 bytes */ + struct bma4_accel fifo_accel_data[BMA456W_FIFO_ACCEL_FRAME_COUNT] = { { 0 } }; + + /* Initialize FIFO frame structure */ + struct bma4_fifo_frame fifoframe = { 0 }; + + /* Variable that contains interrupt status value */ + uint16_t int_status = 0; + + /* Variable to hold the length of FIFO data */ + uint16_t fifo_length = 0; + + uint16_t watermark = 0; + + /* To set the watermark level in FIFO */ + uint16_t wm_lvl; + + /* Interface reference is given as a parameter + * For I2C : BMA4_I2C_INTF + * For SPI : BMA4_SPI_INTF + * Variant information given as parameter - BMA45X_VARIANT + */ + rslt = bma4_interface_init(&dev, BMA4_I2C_INTF, BMA45X_VARIANT); + bma4_error_codes_print_result("bma4_interface_init", rslt); + + /* Initialize BMA456W */ + rslt = bma456w_init(&dev); + bma4_error_codes_print_result("bma456w_init status", rslt); + + /* Accelerometer configuration settings */ + acc_conf.odr = BMA4_OUTPUT_DATA_RATE_100HZ; + acc_conf.bandwidth = BMA4_ACCEL_NORMAL_AVG4; + acc_conf.range = BMA4_ACCEL_RANGE_2G; + acc_conf.perf_mode = BMA4_CIC_AVG_MODE; + + /* Set the accel configurations */ + rslt = bma4_set_accel_config(&acc_conf, &dev); + bma4_error_codes_print_result("bma4_set_accel_config status", rslt); + + /* NOTE : Enable accel after set of configurations */ + rslt = bma4_set_accel_enable(1, &dev); + bma4_error_codes_print_result("bma4_set_accel_enable status", rslt); + + /* Disabling advance power save mode as FIFO data is not accessible in advance low power mode */ + rslt = bma4_set_advance_power_save(BMA4_DISABLE, &dev); + bma4_error_codes_print_result("bma4_set_advance_power_save status", rslt); + + /* Clear FIFO configuration register */ + rslt = bma4_set_fifo_config(BMA4_FIFO_ALL, BMA4_DISABLE, &dev); + bma4_error_codes_print_result("bma4_set_fifo_config disable status", rslt); + + /* Set FIFO configuration by enabling accel. + * NOTE 1: The header mode is enabled by default. + * NOTE 2: By default the FIFO operating mode is FIFO mode. */ + rslt = bma4_set_fifo_config(BMA4_FIFO_ACCEL | BMA4_FIFO_HEADER | BMA4_FIFO_TIME, BMA4_ENABLE, &dev); + bma4_error_codes_print_result("bma4_set_fifo_config enable status", rslt); + + /* Update FIFO structure */ + fifoframe.data = fifo_data; + fifoframe.length = BMA456W_FIFO_RAW_DATA_USER_LENGTH + BMA4_SENSORTIME_OVERHEAD_BYTE; + + printf("FIFO is configured in header mode\n"); + + rslt = bma456w_map_interrupt(BMA4_INTR1_MAP, BMA4_FIFO_WM_INT, BMA4_ENABLE, &dev); + bma4_error_codes_print_result("bma4_map_interrupt status", rslt); + + wm_lvl = BMA456W_FIFO_WATERMARK_LEVEL; + rslt = bma4_set_fifo_wm(wm_lvl, &dev); + bma4_error_codes_print_result("bma4_set_fifo_wm status", rslt); + + while (loop <= 10) + { + rslt = bma456w_read_int_status(&int_status, &dev); + bma4_error_codes_print_result("bma4_read_int_status", rslt); + + if ((rslt == BMA4_OK) && (int_status & BMA4_FIFO_WM_INT)) + { + printf("\nIteration : %d\n", loop); + + rslt = bma4_get_fifo_wm(&watermark, &dev); + bma4_error_codes_print_result("bma4_get_fifo_wm status", rslt); + printf("FIFO watermark level : %d\n", watermark); + + rslt = bma4_get_fifo_length(&fifo_length, &dev); + bma4_error_codes_print_result("bma4_get_fifo_length status", rslt); + + printf("FIFO data bytes available : %d\n", fifo_length); + printf("FIFO data bytes requested : %d\n", fifoframe.length); + + /* Read FIFO data */ + rslt = bma4_read_fifo_data(&fifoframe, &dev); + bma4_error_codes_print_result("bma4_read_fifo_data status", rslt); + + accel_length = BMA456W_FIFO_ACCEL_FRAME_COUNT; + + if (rslt == BMA4_OK) + { + printf("Requested data frames before parsing: %d\n", accel_length); + + /* Parse the FIFO data to extract accelerometer data from the FIFO buffer */ + rslt = bma4_extract_accel(fifo_accel_data, &accel_length, &fifoframe, &dev); + printf("Parsed accelerometer data frames: %d\n", accel_length); + + printf("ACCEL, X, Y, Z\n"); + + /* Print the parsed accelerometer data from the FIFO buffer */ + for (idx = 0; idx < accel_length; idx++) + { + printf("%d, %d, %d, %d\n", + idx, + fifo_accel_data[idx].x, + fifo_accel_data[idx].y, + fifo_accel_data[idx].z); + } + + /* Print control frames like sensor time and skipped frame count */ + printf("Skipped frame count = %d\n", fifoframe.skipped_frame_count); + printf("Sensor time(in seconds) = %.4lf s\r\n", (fifoframe.sensor_time * BMA4_SENSORTIME_RESOLUTION)); + } + + loop++; + } + } + + bma4_coines_deinit(); + + return rslt; +} diff --git a/components/bma456/bma456w_examples/fifo_watermark_header_mode_hw_int/Makefile b/components/bma456/bma456w_examples/fifo_watermark_header_mode_hw_int/Makefile new file mode 100644 index 0000000..760a1fa --- /dev/null +++ b/components/bma456/bma456w_examples/fifo_watermark_header_mode_hw_int/Makefile @@ -0,0 +1,20 @@ +COINES_INSTALL_PATH ?= ../../../.. + +EXAMPLE_FILE ?= fifo_watermark_header_mode_hw_int.c + +API_LOCATION ?= ../.. + +COMMON_LOCATION ?= .. + +C_SRCS += \ +$(API_LOCATION)/bma4.c \ +$(API_LOCATION)/bma456w.c \ +$(COMMON_LOCATION)/common/common.c + +INCLUDEPATHS += \ +$(API_LOCATION) \ +$(COMMON_LOCATION)/common + +TARGET = MCU_APP30 + +include $(COINES_INSTALL_PATH)/coines.mk \ No newline at end of file diff --git a/components/bma456/bma456w_examples/fifo_watermark_header_mode_hw_int/fifo_watermark_header_mode_hw_int.c b/components/bma456/bma456w_examples/fifo_watermark_header_mode_hw_int/fifo_watermark_header_mode_hw_int.c new file mode 100644 index 0000000..be8c16e --- /dev/null +++ b/components/bma456/bma456w_examples/fifo_watermark_header_mode_hw_int/fifo_watermark_header_mode_hw_int.c @@ -0,0 +1,303 @@ +/**\ + * Copyright (c) 2022 Bosch Sensortec GmbH. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + **/ + +#include +#include "bma456w.h" +#include +#include "common.h" +#include "coines.h" + +/******************************************************************************/ +/*! Global variable Declaration */ + +volatile uint8_t interrupt_status = 0; + +/******************************************************************************/ +/*! Macro definition */ + +/*! Buffer size allocated to store raw FIFO data */ +#define BMA456W_FIFO_RAW_DATA_BUFFER_SIZE UINT16_C(1024) + +/*! Length of data to be read from FIFO */ +#define BMA456W_FIFO_RAW_DATA_USER_LENGTH UINT16_C(1024) + +/*! Setting a watermark level in FIFO */ +#define BMA456W_FIFO_WATERMARK_LEVEL UINT16_C(650) + +/*! Number of accel frames to be extracted from FIFO + * Calculation: + * fifo_watermark_level = 650, accel_frame_len = 6, header_byte = 1. + * fifo_accel_frame_count = (650 / (6 + 1)) = 93 frames + * NOTE: Extra frames are read in order to get sensor time + */ +#define BMA456W_FIFO_ACCEL_FRAME_COUNT UINT8_C(100) + +/*! APP20 Board number */ +#define BOARD_MCU_APP20 UINT8_C(0x03) + +/*! APP30 Board number */ +#define BOARD_MCU_APP30 UINT8_C(0x05) + +/******************************************************************************/ +/*! Static Function Declaration */ + +/*! + * @brief This function gets board information + * + * @param[out] board : Board value to determine as APP2.0 or APP3.0 + */ +static void get_board_info(uint8_t *board); + +/*! + * @brief This internal API is used to set the interrupt status + */ +static void interrupt_callback(uint32_t param1, uint32_t param2) +{ + (void)param1; + (void)param2; + interrupt_status = 1; +} + +/******************************************************************************/ +/*! Function */ + +/* This function starts the execution of program */ +int main(void) +{ + /* Status of API are returned to this variable */ + int8_t rslt; + + /* Accelerometer configuration structure */ + struct bma4_accel_config acc_conf = { 0 }; + + /* Sensor initialization configuration */ + struct bma4_dev dev = { 0 }; + + /* Number of accelerometer frames */ + uint16_t accel_length; + + /* Variable to idx bytes */ + uint16_t idx = 0; + + /* Variable to maintain count of loop to run FIFO read */ + uint8_t loop = 1; + + /* Number of bytes of FIFO data + * NOTE : Dummy byte (for SPI Interface) required for FIFO data read must be given as part of array size + */ + uint8_t fifo_data[BMA456W_FIFO_RAW_DATA_BUFFER_SIZE + BMA4_SENSORTIME_OVERHEAD_BYTE] = { 0 }; + + /* Array of accelerometer frames -> Total bytes = + * 100 * (6 axes bytes(+/- x,y,z) + 1 header byte) = 700 bytes */ + struct bma4_accel fifo_accel_data[BMA456W_FIFO_ACCEL_FRAME_COUNT] = { { 0 } }; + + /* Initialize FIFO frame structure */ + struct bma4_fifo_frame fifoframe = { 0 }; + + /* Variable that contains interrupt status value */ + uint16_t int_status = 0; + + /* Variable to hold the length of FIFO data */ + uint16_t fifo_length = 0; + + uint16_t watermark = 0; + + /* To set the watermark level in FIFO */ + uint16_t wm_lvl; + + struct bma4_int_pin_config pin_config = { 0 }; + uint8_t board = 0; + + /* Variable for interrupt line selection*/ + uint8_t int_line; + + /* Interface reference is given as a parameter + * For I2C : BMA4_I2C_INTF + * For SPI : BMA4_SPI_INTF + * Variant information given as parameter - BMA45X_VARIANT + */ + rslt = bma4_interface_init(&dev, BMA4_I2C_INTF, BMA45X_VARIANT); + bma4_error_codes_print_result("bma4_interface_init", rslt); + + /* Initialize BMA456W */ + rslt = bma456w_init(&dev); + bma4_error_codes_print_result("bma456w_init status", rslt); + + /* Accelerometer configuration settings */ + acc_conf.odr = BMA4_OUTPUT_DATA_RATE_100HZ; + acc_conf.bandwidth = BMA4_ACCEL_NORMAL_AVG4; + acc_conf.range = BMA4_ACCEL_RANGE_2G; + acc_conf.perf_mode = BMA4_CIC_AVG_MODE; + + /* Set the accel configurations */ + rslt = bma4_set_accel_config(&acc_conf, &dev); + bma4_error_codes_print_result("bma4_set_accel_config status", rslt); + + /* NOTE : Enable accel after set of configurations */ + rslt = bma4_set_accel_enable(1, &dev); + bma4_error_codes_print_result("bma4_set_accel_enable status", rslt); + + /* Disabling advance power save mode as FIFO data is not accessible in advance low power mode */ + rslt = bma4_set_advance_power_save(BMA4_DISABLE, &dev); + bma4_error_codes_print_result("bma4_set_advance_power_save status", rslt); + + /* Clear FIFO configuration register */ + rslt = bma4_set_fifo_config(BMA4_FIFO_ALL, BMA4_DISABLE, &dev); + bma4_error_codes_print_result("bma4_set_fifo_config disable status", rslt); + + /* Set FIFO configuration by enabling accel. + * NOTE 1: The header mode is enabled by default. + * NOTE 2: By default the FIFO operating mode is FIFO mode. */ + rslt = bma4_set_fifo_config(BMA4_FIFO_ACCEL | BMA4_FIFO_HEADER | BMA4_FIFO_TIME, BMA4_ENABLE, &dev); + bma4_error_codes_print_result("bma4_set_fifo_config enable status", rslt); + + /* Update FIFO structure */ + fifoframe.data = fifo_data; + fifoframe.length = BMA456W_FIFO_RAW_DATA_USER_LENGTH + BMA4_SENSORTIME_OVERHEAD_BYTE; + + printf("FIFO is configured in header mode\n"); + + /* Hardware interrupt configuration */ + int_line = BMA4_INTR1_MAP; + + rslt = bma456w_map_interrupt(int_line, BMA4_FIFO_WM_INT, BMA4_ENABLE, &dev); + bma4_error_codes_print_result("bma456w_map_interrupt status", rslt); + + wm_lvl = BMA456W_FIFO_WATERMARK_LEVEL; + rslt = bma4_set_fifo_wm(wm_lvl, &dev); + bma4_error_codes_print_result("bma4_set_fifo_wm status", rslt); + + pin_config.edge_ctrl = BMA4_EDGE_TRIGGER; + pin_config.output_en = BMA4_OUTPUT_ENABLE; + pin_config.lvl = BMA4_ACTIVE_HIGH; + pin_config.od = BMA4_PUSH_PULL; + pin_config.input_en = BMA4_INPUT_DISABLE; + + rslt = bma4_set_int_pin_config(&pin_config, int_line, &dev); + bma4_error_codes_print_result("bma4_set_int_pin_config status", rslt); + + /* Get board information */ + get_board_info(&board); + + /* + * Attach interrupt based on board + */ + if (board == BOARD_MCU_APP20) + { + switch (int_line) + { + case BMA4_INTR1_MAP: + coines_attach_interrupt(COINES_SHUTTLE_PIN_20, interrupt_callback, COINES_PIN_INTERRUPT_RISING_EDGE); + break; + + case BMA4_INTR2_MAP: + coines_attach_interrupt(COINES_SHUTTLE_PIN_21, interrupt_callback, COINES_PIN_INTERRUPT_RISING_EDGE); + break; + + default: + break; + } + } + +#if !defined(MCU_APP20) + else if (board == BOARD_MCU_APP30) + { + switch (int_line) + { + case BMA4_INTR1_MAP: + coines_attach_interrupt(COINES_MINI_SHUTTLE_PIN_1_6, + interrupt_callback, + COINES_PIN_INTERRUPT_RISING_EDGE); + break; + + case BMA4_INTR2_MAP: + coines_attach_interrupt(COINES_MINI_SHUTTLE_PIN_1_7, + interrupt_callback, + COINES_PIN_INTERRUPT_RISING_EDGE); + break; + + default: + break; + } + } +#endif + + while (loop <= 10) + { + if (interrupt_status == 1) + { + interrupt_status = 0; + rslt = bma456w_read_int_status(&int_status, &dev); + bma4_error_codes_print_result("bma4_read_int_status", rslt); + + if ((rslt == BMA4_OK) && (int_status & BMA4_FIFO_WM_INT)) + { + printf("\nIteration : %d\n", loop); + + rslt = bma4_get_fifo_wm(&watermark, &dev); + bma4_error_codes_print_result("bma4_get_fifo_wm status", rslt); + printf("FIFO watermark level : %d\n", watermark); + + rslt = bma4_get_fifo_length(&fifo_length, &dev); + bma4_error_codes_print_result("bma4_get_fifo_length status", rslt); + + printf("FIFO data bytes available : %d\n", fifo_length); + printf("FIFO data bytes requested : %d\n", fifoframe.length); + + /* Read FIFO data */ + rslt = bma4_read_fifo_data(&fifoframe, &dev); + bma4_error_codes_print_result("bma4_read_fifo_data status", rslt); + + accel_length = BMA456W_FIFO_ACCEL_FRAME_COUNT; + + if (rslt == BMA4_OK) + { + printf("Requested data frames before parsing: %d\n", accel_length); + + /* Parse the FIFO data to extract accelerometer data from the FIFO buffer */ + rslt = bma4_extract_accel(fifo_accel_data, &accel_length, &fifoframe, &dev); + printf("Parsed accelerometer data frames: %d\n", accel_length); + + printf("ACCEL, X, Y, Z\n"); + + /* Print the parsed accelerometer data from the FIFO buffer */ + for (idx = 0; idx < accel_length; idx++) + { + printf("%d, %d, %d, %d\n", idx, fifo_accel_data[idx].x, fifo_accel_data[idx].y, + fifo_accel_data[idx].z); + } + + /* Print control frames like sensor time and skipped frame count */ + printf("Skipped frame count = %d\n", fifoframe.skipped_frame_count); + printf("Sensor time(in seconds) = %.4lf s\r\n", + (fifoframe.sensor_time * BMA4_SENSORTIME_RESOLUTION)); + } + + loop++; + } + } + } + + bma4_coines_deinit(); + + return rslt; +} + +/*! + * @brief This function gets board information + */ +static void get_board_info(uint8_t *board) +{ + struct coines_board_info board_info; + int16_t result; + + result = coines_get_board_info(&board_info); + + if (result == COINES_SUCCESS) + { + (*board) = board_info.board; + } +} diff --git a/components/bma456/bma456w_examples/fifo_watermark_headerless_mode/Makefile b/components/bma456/bma456w_examples/fifo_watermark_headerless_mode/Makefile new file mode 100644 index 0000000..c8c4144 --- /dev/null +++ b/components/bma456/bma456w_examples/fifo_watermark_headerless_mode/Makefile @@ -0,0 +1,18 @@ +COINES_INSTALL_PATH ?= ../../../.. + +EXAMPLE_FILE ?= fifo_watermark_headerless_mode.c + +API_LOCATION ?= ../.. + +COMMON_LOCATION ?= .. + +C_SRCS += \ +$(API_LOCATION)/bma4.c \ +$(API_LOCATION)/bma456w.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/components/bma456/bma456w_examples/fifo_watermark_headerless_mode/fifo_watermark_headerless_mode.c b/components/bma456/bma456w_examples/fifo_watermark_headerless_mode/fifo_watermark_headerless_mode.c new file mode 100644 index 0000000..e24a6d3 --- /dev/null +++ b/components/bma456/bma456w_examples/fifo_watermark_headerless_mode/fifo_watermark_headerless_mode.c @@ -0,0 +1,188 @@ +/**\ + * Copyright (c) 2022 Bosch Sensortec GmbH. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + **/ + +#include +#include "bma456w.h" +#include "common.h" + +/******************************************************************************/ +/*! Macro definition */ + +/*! Buffer size allocated to store raw FIFO data */ +#define BMA456W_FIFO_RAW_DATA_BUFFER_SIZE UINT16_C(1024) + +/*! Length of data to be read from FIFO */ +#define BMA456W_FIFO_RAW_DATA_USER_LENGTH UINT16_C(1024) + +/*! Setting a watermark level in FIFO */ +#define BMA456W_FIFO_WATERMARK_LEVEL UINT16_C(600) + +/*! Number of accel frames to be extracted from FIFO + * Calculation: + * fifo_watermark_level = 600, accel_frame_len = 6. + * fifo_accel_frame_count = (600 / 6) = 100 frames + */ +#define BMA456W_FIFO_ACCEL_FRAME_COUNT UINT8_C(100) + +/******************************************************************************/ +/*! Function */ + +/* This function starts the execution of program */ +int main(void) +{ + /* Status of API are returned to this variable */ + int8_t rslt; + + /* Accelerometer configuration structure */ + struct bma4_accel_config acc_conf = { 0 }; + + /* Sensor initialization configuration */ + struct bma4_dev dev = { 0 }; + + /* Number of accelerometer frames */ + uint16_t accel_length; + + /* Variable to idx bytes */ + uint16_t idx = 0; + + /* Variable to maintain count of loop to run FIFO read */ + uint8_t loop = 1; + + /* Number of bytes of FIFO data + * NOTE : Dummy byte (for SPI Interface) required for FIFO data read must be given as part of array size + */ + uint8_t fifo_data[BMA456W_FIFO_RAW_DATA_BUFFER_SIZE] = { 0 }; + + /* Array of accelerometer frames -> Total bytes = + * 100 * (6 axes bytes(+/- x,y,z)) = 600 bytes */ + struct bma4_accel fifo_accel_data[BMA456W_FIFO_ACCEL_FRAME_COUNT] = { { 0 } }; + + /* Initialize FIFO frame structure */ + struct bma4_fifo_frame fifoframe = { 0 }; + + /* Variable that contains interrupt status value */ + uint16_t int_status = 0; + + /* Variable to hold the length of FIFO data */ + uint16_t fifo_length = 0; + + uint16_t watermark = 0; + + /* To set the watermark level in FIFO */ + uint16_t wm_lvl; + + /* Interface reference is given as a parameter + * For I2C : BMA4_I2C_INTF + * For SPI : BMA4_SPI_INTF + * Variant information given as parameter - BMA45X_VARIANT + */ + rslt = bma4_interface_init(&dev, BMA4_I2C_INTF, BMA45X_VARIANT); + bma4_error_codes_print_result("bma4_interface_init", rslt); + + /* Initialize BMA456W */ + rslt = bma456w_init(&dev); + bma4_error_codes_print_result("bma456w_init status", rslt); + + /* Accelerometer configuration settings */ + acc_conf.odr = BMA4_OUTPUT_DATA_RATE_100HZ; + acc_conf.bandwidth = BMA4_ACCEL_NORMAL_AVG4; + acc_conf.range = BMA4_ACCEL_RANGE_2G; + acc_conf.perf_mode = BMA4_CIC_AVG_MODE; + + /* Set the accel configurations */ + rslt = bma4_set_accel_config(&acc_conf, &dev); + bma4_error_codes_print_result("bma4_set_accel_config status", rslt); + + /* NOTE : Enable accel after set of configurations */ + rslt = bma4_set_accel_enable(1, &dev); + bma4_error_codes_print_result("bma4_set_accel_enable status", rslt); + + /* Disabling advance power save mode as FIFO data is not accessible in advance low power mode */ + rslt = bma4_set_advance_power_save(BMA4_DISABLE, &dev); + bma4_error_codes_print_result("bma4_set_advance_power_save status", rslt); + + /* Clear FIFO configuration register */ + rslt = bma4_set_fifo_config(BMA4_FIFO_ALL, BMA4_DISABLE, &dev); + bma4_error_codes_print_result("bma4_set_fifo_config disable status", rslt); + + /* Set FIFO configuration by enabling accel. + * NOTE 1: The header mode is enabled by default. + * NOTE 2: By default the FIFO operating mode is FIFO mode. */ + rslt = bma4_set_fifo_config(BMA4_FIFO_ACCEL, BMA4_ENABLE, &dev); + bma4_error_codes_print_result("bma4_set_fifo_config enable status", rslt); + + /* Update FIFO structure */ + fifoframe.data = fifo_data; + fifoframe.length = BMA456W_FIFO_RAW_DATA_USER_LENGTH; + + /* To enable headerless mode, disable the header. */ + rslt = bma4_set_fifo_config(BMA4_FIFO_HEADER, BMA4_DISABLE, &dev); + bma4_error_codes_print_result("bma4_set_fifo_config status", rslt); + + printf("FIFO is configured in headerless mode\n"); + + rslt = bma456w_map_interrupt(BMA4_INTR1_MAP, BMA4_FIFO_WM_INT, BMA4_ENABLE, &dev); + bma4_error_codes_print_result("bma4_map_interrupt status", rslt); + + wm_lvl = BMA456W_FIFO_WATERMARK_LEVEL; + rslt = bma4_set_fifo_wm(wm_lvl, &dev); + bma4_error_codes_print_result("bma4_set_fifo_wm status", rslt); + + while (loop <= 10) + { + rslt = bma456w_read_int_status(&int_status, &dev); + bma4_error_codes_print_result("bma4_read_int_status", rslt); + + if ((rslt == BMA4_OK) && (int_status & BMA4_FIFO_WM_INT)) + { + printf("\nIteration : %d\n", loop); + + rslt = bma4_get_fifo_wm(&watermark, &dev); + bma4_error_codes_print_result("bma4_get_fifo_wm status", rslt); + + printf("FIFO watermark level : %d\n", watermark); + + rslt = bma4_get_fifo_length(&fifo_length, &dev); + bma4_error_codes_print_result("bma4_get_fifo_length status", rslt); + + printf("FIFO data bytes available : %d\n", fifo_length); + printf("FIFO data bytes requested : %d\n", fifoframe.length); + + /* Read FIFO data */ + rslt = bma4_read_fifo_data(&fifoframe, &dev); + bma4_error_codes_print_result("bma4_read_fifo_data status", rslt); + + accel_length = BMA456W_FIFO_ACCEL_FRAME_COUNT; + + if (rslt == BMA4_OK) + { + printf("Requested data frames before parsing: %d\n", accel_length); + + /* Parse the FIFO data to extract accelerometer data from the FIFO buffer */ + rslt = bma4_extract_accel(fifo_accel_data, &accel_length, &fifoframe, &dev); + printf("Parsed accelerometer data frames: %d\n", accel_length); + + printf("ACCEL, X, Y, Z\n"); + + /* Print the parsed accelerometer data from the FIFO buffer */ + for (idx = 0; idx < accel_length; idx++) + { + printf("%d, %d, %d, %d\n", + idx, + fifo_accel_data[idx].x, + fifo_accel_data[idx].y, + fifo_accel_data[idx].z); + } + } + + loop++; + } + } + + bma4_coines_deinit(); + + return rslt; +} diff --git a/components/bma456/bma456w_examples/fifo_watermark_headerless_mode_hw_int/Makefile b/components/bma456/bma456w_examples/fifo_watermark_headerless_mode_hw_int/Makefile new file mode 100644 index 0000000..0fde913 --- /dev/null +++ b/components/bma456/bma456w_examples/fifo_watermark_headerless_mode_hw_int/Makefile @@ -0,0 +1,20 @@ +COINES_INSTALL_PATH ?= ../../../.. + +EXAMPLE_FILE ?= fifo_watermark_headerless_mode_hw_int.c + +API_LOCATION ?= ../.. + +COMMON_LOCATION ?= .. + +C_SRCS += \ +$(API_LOCATION)/bma4.c \ +$(API_LOCATION)/bma456w.c \ +$(COMMON_LOCATION)/common/common.c + +INCLUDEPATHS += \ +$(API_LOCATION) \ +$(COMMON_LOCATION)/common + +TARGET = MCU_APP30 + +include $(COINES_INSTALL_PATH)/coines.mk \ No newline at end of file diff --git a/components/bma456/bma456w_examples/fifo_watermark_headerless_mode_hw_int/fifo_watermark_headerless_mode_hw_int.c b/components/bma456/bma456w_examples/fifo_watermark_headerless_mode_hw_int/fifo_watermark_headerless_mode_hw_int.c new file mode 100644 index 0000000..be35646 --- /dev/null +++ b/components/bma456/bma456w_examples/fifo_watermark_headerless_mode_hw_int/fifo_watermark_headerless_mode_hw_int.c @@ -0,0 +1,302 @@ +/**\ + * Copyright (c) 2022 Bosch Sensortec GmbH. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + **/ + +#include +#include +#include "bma456w.h" +#include "common.h" +#include "coines.h" + +/******************************************************************************/ +/*! Global variable Declaration */ + +volatile uint8_t interrupt_status = 0; + +/******************************************************************************/ +/*! Macro definition */ + +/*! Buffer size allocated to store raw FIFO data */ +#define BMA456W_FIFO_RAW_DATA_BUFFER_SIZE UINT16_C(1024) + +/*! Length of data to be read from FIFO */ +#define BMA456W_FIFO_RAW_DATA_USER_LENGTH UINT16_C(1024) + +/*! Setting a watermark level in FIFO */ +#define BMA456W_FIFO_WATERMARK_LEVEL UINT16_C(600) + +/*! Number of accel frames to be extracted from FIFO + * Calculation: + * fifo_watermark_level = 600, accel_frame_len = 6. + * fifo_accel_frame_count = (600 / 6) = 100 frames + */ +#define BMA456W_FIFO_ACCEL_FRAME_COUNT UINT8_C(100) + +/*! APP20 Board number */ +#define BOARD_MCU_APP20 UINT8_C(0x03) + +/*! APP30 Board number */ +#define BOARD_MCU_APP30 UINT8_C(0x05) + +/******************************************************************************/ +/*! Static Function Declaration */ + +/*! + * @brief This function gets board information + * + * @param[out] board : Board value to determine as APP2.0 or APP3.0 + */ +static void get_board_info(uint8_t *board); + +/*! + * @brief This internal API is used to set the interrupt status + */ +static void interrupt_callback(uint32_t param1, uint32_t param2) +{ + (void)param1; + (void)param2; + interrupt_status = 1; +} + +/******************************************************************************/ +/*! Function */ + +/* This function starts the execution of program */ +int main(void) +{ + /* Status of API are returned to this variable */ + int8_t rslt; + + /* Accelerometer configuration structure */ + struct bma4_accel_config acc_conf = { 0 }; + + /* Sensor initialization configuration */ + struct bma4_dev dev = { 0 }; + + /* Number of accelerometer frames */ + uint16_t accel_length; + + /* Variable to idx bytes */ + uint16_t idx = 0; + + /* Variable to maintain count of loop to run FIFO read */ + uint8_t loop = 1; + + /* Number of bytes of FIFO data + * NOTE : Dummy byte (for SPI Interface) required for FIFO data read must be given as part of array size + */ + uint8_t fifo_data[BMA456W_FIFO_RAW_DATA_BUFFER_SIZE] = { 0 }; + + /* Array of accelerometer frames -> Total bytes = + * 100 * (6 axes bytes(+/- x,y,z)) = 600 bytes */ + struct bma4_accel fifo_accel_data[BMA456W_FIFO_ACCEL_FRAME_COUNT] = { { 0 } }; + + /* Initialize FIFO frame structure */ + struct bma4_fifo_frame fifoframe = { 0 }; + + /* Variable that contains interrupt status value */ + uint16_t int_status = 0; + + /* Variable to hold the length of FIFO data */ + uint16_t fifo_length = 0; + + uint16_t watermark = 0; + + /* To set the watermark level in FIFO */ + uint16_t wm_lvl; + + struct bma4_int_pin_config pin_config = { 0 }; + uint8_t board = 0; + + /* Variable for interrupt line selection*/ + uint8_t int_line; + + /* Interface reference is given as a parameter + * For I2C : BMA4_I2C_INTF + * For SPI : BMA4_SPI_INTF + * Variant information given as parameter - BMA45X_VARIANT + */ + rslt = bma4_interface_init(&dev, BMA4_I2C_INTF, BMA45X_VARIANT); + bma4_error_codes_print_result("bma4_interface_init", rslt); + + /* Initialize BMA456W */ + rslt = bma456w_init(&dev); + bma4_error_codes_print_result("bma456w_init status", rslt); + + /* Accelerometer configuration settings */ + acc_conf.odr = BMA4_OUTPUT_DATA_RATE_100HZ; + acc_conf.bandwidth = BMA4_ACCEL_NORMAL_AVG4; + acc_conf.range = BMA4_ACCEL_RANGE_2G; + acc_conf.perf_mode = BMA4_CIC_AVG_MODE; + + /* Set the accel configurations */ + rslt = bma4_set_accel_config(&acc_conf, &dev); + bma4_error_codes_print_result("bma4_set_accel_config status", rslt); + + /* NOTE : Enable accel after set of configurations */ + rslt = bma4_set_accel_enable(1, &dev); + bma4_error_codes_print_result("bma4_set_accel_enable status", rslt); + + /* Disabling advance power save mode as FIFO data is not accessible in advance low power mode */ + rslt = bma4_set_advance_power_save(BMA4_DISABLE, &dev); + bma4_error_codes_print_result("bma4_set_advance_power_save status", rslt); + + /* Clear FIFO configuration register */ + rslt = bma4_set_fifo_config(BMA4_FIFO_ALL, BMA4_DISABLE, &dev); + bma4_error_codes_print_result("bma4_set_fifo_config disable status", rslt); + + /* Set FIFO configuration by enabling accel. + * NOTE 1: The header mode is enabled by default. + * NOTE 2: By default the FIFO operating mode is FIFO mode. */ + rslt = bma4_set_fifo_config(BMA4_FIFO_ACCEL, BMA4_ENABLE, &dev); + bma4_error_codes_print_result("bma4_set_fifo_config enable status", rslt); + + /* Update FIFO structure */ + fifoframe.data = fifo_data; + fifoframe.length = BMA456W_FIFO_RAW_DATA_USER_LENGTH; + + /* To enable headerless mode, disable the header. */ + rslt = bma4_set_fifo_config(BMA4_FIFO_HEADER, BMA4_DISABLE, &dev); + bma4_error_codes_print_result("bma4_set_fifo_config status", rslt); + + printf("FIFO is configured in headerless mode\n"); + + /* Hardware interrupt configuration */ + int_line = BMA4_INTR1_MAP; + + rslt = bma456w_map_interrupt(int_line, BMA4_FIFO_WM_INT, BMA4_ENABLE, &dev); + bma4_error_codes_print_result("bma456w_map_interrupt status", rslt); + + wm_lvl = BMA456W_FIFO_WATERMARK_LEVEL; + rslt = bma4_set_fifo_wm(wm_lvl, &dev); + bma4_error_codes_print_result("bma4_set_fifo_wm status", rslt); + + pin_config.edge_ctrl = BMA4_EDGE_TRIGGER; + pin_config.output_en = BMA4_OUTPUT_ENABLE; + pin_config.lvl = BMA4_ACTIVE_HIGH; + pin_config.od = BMA4_PUSH_PULL; + pin_config.input_en = BMA4_INPUT_DISABLE; + + rslt = bma4_set_int_pin_config(&pin_config, int_line, &dev); + bma4_error_codes_print_result("bma4_set_int_pin_config status", rslt); + + /* Get board information */ + get_board_info(&board); + + /* + * Attach interrupt based on board + */ + if (board == BOARD_MCU_APP20) + { + switch (int_line) + { + case BMA4_INTR1_MAP: + coines_attach_interrupt(COINES_SHUTTLE_PIN_20, interrupt_callback, COINES_PIN_INTERRUPT_RISING_EDGE); + break; + + case BMA4_INTR2_MAP: + coines_attach_interrupt(COINES_SHUTTLE_PIN_21, interrupt_callback, COINES_PIN_INTERRUPT_RISING_EDGE); + break; + + default: + break; + } + } + +#if !defined(MCU_APP20) + else if (board == BOARD_MCU_APP30) + { + switch (int_line) + { + case BMA4_INTR1_MAP: + coines_attach_interrupt(COINES_MINI_SHUTTLE_PIN_1_6, + interrupt_callback, + COINES_PIN_INTERRUPT_RISING_EDGE); + break; + + case BMA4_INTR2_MAP: + coines_attach_interrupt(COINES_MINI_SHUTTLE_PIN_1_7, + interrupt_callback, + COINES_PIN_INTERRUPT_RISING_EDGE); + break; + + default: + break; + } + } +#endif + + while (loop <= 10) + { + if (interrupt_status == 1) + { + interrupt_status = 0; + rslt = bma456w_read_int_status(&int_status, &dev); + bma4_error_codes_print_result("bma4_read_int_status", rslt); + + if ((rslt == BMA4_OK) && (int_status & BMA4_FIFO_WM_INT)) + { + printf("\nIteration : %d\n", loop); + + rslt = bma4_get_fifo_wm(&watermark, &dev); + bma4_error_codes_print_result("bma4_get_fifo_wm status", rslt); + + printf("FIFO watermark level : %d\n", watermark); + + rslt = bma4_get_fifo_length(&fifo_length, &dev); + bma4_error_codes_print_result("bma4_get_fifo_length status", rslt); + + printf("FIFO data bytes available : %d\n", fifo_length); + printf("FIFO data bytes requested : %d\n", fifoframe.length); + + /* Read FIFO data */ + rslt = bma4_read_fifo_data(&fifoframe, &dev); + bma4_error_codes_print_result("bma4_read_fifo_data status", rslt); + + accel_length = BMA456W_FIFO_ACCEL_FRAME_COUNT; + + if (rslt == BMA4_OK) + { + printf("Requested data frames before parsing: %d\n", accel_length); + + /* Parse the FIFO data to extract accelerometer data from the FIFO buffer */ + rslt = bma4_extract_accel(fifo_accel_data, &accel_length, &fifoframe, &dev); + printf("Parsed accelerometer data frames: %d\n", accel_length); + + printf("ACCEL, X, Y, Z\n"); + + /* Print the parsed accelerometer data from the FIFO buffer */ + for (idx = 0; idx < accel_length; idx++) + { + printf("%d, %d, %d, %d\n", idx, fifo_accel_data[idx].x, fifo_accel_data[idx].y, + fifo_accel_data[idx].z); + } + } + + loop++; + } + } + } + + bma4_coines_deinit(); + + return rslt; +} + +/*! + * @brief This function gets board information + */ +static void get_board_info(uint8_t *board) +{ + struct coines_board_info board_info; + int16_t result; + + result = coines_get_board_info(&board_info); + + if (result == COINES_SUCCESS) + { + (*board) = board_info.board; + } +} diff --git a/components/bma456/bma456w_examples/motion/Makefile b/components/bma456/bma456w_examples/motion/Makefile new file mode 100644 index 0000000..c9e69bd --- /dev/null +++ b/components/bma456/bma456w_examples/motion/Makefile @@ -0,0 +1,18 @@ +COINES_INSTALL_PATH ?= ../../../.. + +EXAMPLE_FILE ?= motion.c + +API_LOCATION ?= ../.. + +COMMON_LOCATION ?= .. + +C_SRCS += \ +$(API_LOCATION)/bma4.c \ +$(API_LOCATION)/bma456w.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/components/bma456/bma456w_examples/motion/motion.c b/components/bma456/bma456w_examples/motion/motion.c new file mode 100644 index 0000000..a9951a7 --- /dev/null +++ b/components/bma456/bma456w_examples/motion/motion.c @@ -0,0 +1,186 @@ +/**\ + * Copyright (c) 2022 Bosch Sensortec GmbH. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + **/ + +#include +#include "bma456w.h" +#include "common.h" + +/*****************************************************************************/ +/*! Global variable */ + +/*! Structure to define any/no-motion configurations */ +struct bma456w_any_no_mot_config any_no_mot = { 0 }; + +/******************************************************************************/ +/*! Static Function Declaration */ + +/*! + * @brief This internal API is used to get any/no-motion configurations. + * + * @param[in] bma : Structure instance of bma4_dev. + * + * @return Status of execution. + */ +static int8_t get_any_no_mot_config(struct bma4_dev *bma); + +/******************************************************************************/ +/*! Functions */ + +/* This function starts the execution of program. */ +int main(void) +{ + /* Variable to store the status of API */ + int8_t rslt; + + /* Sensor initialization configuration */ + struct bma4_dev bma = { 0 }; + + /* Variable to store any/no-motion interrupt status */ + uint16_t int_status = 0; + + /* Loop variable */ + uint8_t iteration = 20; + + /* Interface reference is given as a parameter + * For I2C : BMA4_I2C_INTF + * For SPI : BMA4_SPI_INTF + * Variant information given as parameter - BMA45X_VARIANT + */ + rslt = bma4_interface_init(&bma, BMA4_I2C_INTF, BMA45X_VARIANT); + bma4_error_codes_print_result("bma4_interface_init", rslt); + + /* Sensor initialization */ + rslt = bma456w_init(&bma); + bma4_error_codes_print_result("bma456w_init status", rslt); + + /* Upload the configuration file to enable the features of the sensor. */ + rslt = bma456w_write_config_file(&bma); + bma4_error_codes_print_result("bma456w_write_config status", rslt); + + /* Enable the accelerometer */ + rslt = bma4_set_accel_enable(BMA4_ENABLE, &bma); + bma4_error_codes_print_result("bma4_set_accel_enable status", rslt); + + /* Map the interrupt 1 for any/no-motion */ + rslt = bma456w_map_interrupt(BMA4_INTR1_MAP, (BMA456W_ANY_MOT_INT | BMA456W_NO_MOT_INT), BMA4_ENABLE, &bma); + bma4_error_codes_print_result("bma456w_map_interrupt status", rslt); + + /* Get any-motion and no-motion configurations */ + rslt = get_any_no_mot_config(&bma); + bma4_error_codes_print_result("get_any_no_mot_config status", rslt); + + printf("Shake the board for any-motion interrupt whereas do not shake the board for no-motion interrupt\n"); + + for (;;) + { + /* Read interrupt status */ + rslt = bma456w_read_int_status(&int_status, &bma); + bma4_error_codes_print_result("bma456w_read_int_status", rslt); + + if (rslt == BMA4_OK) + { + /* Enters only if the obtained interrupt is any-motion */ + if (int_status & BMA456W_ANY_MOT_INT) + { + printf("Any-motion interrupt occurred\n"); + iteration--; + } + + /* Enters only if the obtained interrupt is no-motion */ + else if (int_status & BMA456W_NO_MOT_INT) + { + printf("No-motion interrupt occurred\n"); + iteration--; + } + + int_status = 0; + + /* Break out of the loop when iteration has reached zero */ + if (iteration == 0) + { + printf("Iterations are done. Exiting !"); + break; + } + } + } + + bma4_coines_deinit(); + + return rslt; +} + +/*! + * @brief This internal API is used to get any/no-motion configurations. + */ +static int8_t get_any_no_mot_config(struct bma4_dev *bma) +{ + /* Variable to store the status of API */ + int8_t rslt; + + /* Getting any-motion configuration to get default configuration */ + rslt = bma456w_get_any_mot_config(&any_no_mot, bma); + bma4_error_codes_print_result("bma456w_get_any_mot_config status", rslt); + + if (rslt == BMA4_OK) + { + /* + * Set the slope threshold: + * Interrupt will be generated if the slope of all the axis exceeds the threshold (1 bit = 0.48mG) + */ + any_no_mot.threshold = 10; + + /* + * Set the duration for any-motion interrupt: + * Duration defines the number of consecutive data points for which threshold condition must be true(1 + * bit = + * 20ms) + */ + any_no_mot.duration = 4; + + /* Enabling X, Y, and Z axis for Any-motion feature */ + any_no_mot.axes_en = BMA456W_EN_ALL_AXIS; + + /* Like threshold and duration, we can also change the config of int_bhvr and slope */ + + /* Set the threshold and duration configuration */ + rslt = bma456w_set_any_mot_config(&any_no_mot, bma); + bma4_error_codes_print_result("bma456w_set_any_mot_config status", rslt); + + if (rslt == BMA4_OK) + { + /* Getting no-motion configuration to get default configuration */ + rslt = bma456w_get_no_mot_config(&any_no_mot, bma); + bma4_error_codes_print_result("bma456w_get_no_mot_config status", rslt); + + if (rslt == BMA4_OK) + { + /* + * Set the slope threshold: + * Interrupt will be generated if the slope of all the axis exceeds the threshold (1 bit = 0.48mG) + */ + any_no_mot.threshold = 10; + + /* + * Set the duration for no-motion interrupt: + * Duration defines the number of consecutive data points for which threshold condition must be + * true(1 bit = 20ms) + */ + any_no_mot.duration = 4; + + /* Enabling X, Y, and Z axis for no-motion feature */ + any_no_mot.axes_en = BMA456W_EN_ALL_AXIS; + + /* Like threshold and duration, we can also change the config of int_bhvr */ + + /* Set the threshold and duration configuration */ + rslt = bma456w_set_no_mot_config(&any_no_mot, bma); + bma4_error_codes_print_result("bma456w_set_no_mot_config status", rslt); + } + } + } + + return rslt; +} diff --git a/components/bma456/bma456w_examples/motion_hw_int/Makefile b/components/bma456/bma456w_examples/motion_hw_int/Makefile new file mode 100644 index 0000000..bbfe3cb --- /dev/null +++ b/components/bma456/bma456w_examples/motion_hw_int/Makefile @@ -0,0 +1,20 @@ +COINES_INSTALL_PATH ?= ../../../.. + +EXAMPLE_FILE ?= motion_hw_int.c + +API_LOCATION ?= ../.. + +COMMON_LOCATION ?= .. + +C_SRCS += \ +$(API_LOCATION)/bma4.c \ +$(API_LOCATION)/bma456w.c \ +$(COMMON_LOCATION)/common/common.c + +INCLUDEPATHS += \ +$(API_LOCATION) \ +$(COMMON_LOCATION)/common + +TARGET = MCU_APP30 + +include $(COINES_INSTALL_PATH)/coines.mk \ No newline at end of file diff --git a/components/bma456/bma456w_examples/motion_hw_int/motion_hw_int.c b/components/bma456/bma456w_examples/motion_hw_int/motion_hw_int.c new file mode 100644 index 0000000..256a311 --- /dev/null +++ b/components/bma456/bma456w_examples/motion_hw_int/motion_hw_int.c @@ -0,0 +1,301 @@ +/**\ + * Copyright (c) 2022 Bosch Sensortec GmbH. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + **/ + +#include +#include +#include "bma456w.h" +#include "common.h" + +/*****************************************************************************/ +/*! Global variable */ + +/*! Structure to define any/no-motion configurations */ +struct bma456w_any_no_mot_config any_no_mot = { 0 }; + +volatile uint8_t interrupt_status = 0; + +/******************************************************************************/ +/*! Macro definition */ + +/*! APP20 Board number */ +#define BOARD_MCU_APP20 UINT8_C(0x03) + +/*! APP30 Board number */ +#define BOARD_MCU_APP30 UINT8_C(0x05) + +/******************************************************************************/ +/*! Static Function Declaration */ + +/*! + * @brief This internal API is used to get any/no-motion configurations. + * + * @param[in] bma : Structure instance of bma4_dev. + * + * @return Status of execution. + */ +static int8_t get_any_no_mot_config(struct bma4_dev *bma); + +/*! + * @brief This function gets board information + * + * @param[out] board : Board value to determine as APP2.0 or APP3.0 + */ +static void get_board_info(uint8_t *board); + +/*! + * @brief This internal API is used to set the interrupt status + */ +static void interrupt_callback(uint32_t param1, uint32_t param2) +{ + (void)param1; + (void)param2; + interrupt_status = 1; +} + +/******************************************************************************/ +/*! Functions */ + +/* This function starts the execution of program. */ +int main(void) +{ + /* Variable to store the status of API */ + int8_t rslt; + + /* Sensor initialization configuration */ + struct bma4_dev bma = { 0 }; + + /* Variable to store any/no-motion interrupt status */ + uint16_t int_status = 0; + + /* Loop variable */ + uint8_t iteration = 20; + + struct bma4_int_pin_config pin_config = { 0 }; + uint8_t board = 0; + + /* Variable for interrupt line selection*/ + uint8_t int_line; + + /* Interface reference is given as a parameter + * For I2C : BMA4_I2C_INTF + * For SPI : BMA4_SPI_INTF + * Variant information given as parameter - BMA45X_VARIANT + */ + rslt = bma4_interface_init(&bma, BMA4_I2C_INTF, BMA45X_VARIANT); + bma4_error_codes_print_result("bma4_interface_init", rslt); + + /* Sensor initialization */ + rslt = bma456w_init(&bma); + bma4_error_codes_print_result("bma456w_init status", rslt); + + /* Upload the configuration file to enable the features of the sensor. */ + rslt = bma456w_write_config_file(&bma); + bma4_error_codes_print_result("bma456w_write_config status", rslt); + + /* Enable the accelerometer */ + rslt = bma4_set_accel_enable(BMA4_ENABLE, &bma); + bma4_error_codes_print_result("bma4_set_accel_enable status", rslt); + + /* Get any-motion and no-motion configurations */ + rslt = get_any_no_mot_config(&bma); + bma4_error_codes_print_result("get_any_no_mot_config status", rslt); + + /* Hardware interrupt configuration */ + int_line = BMA4_INTR2_MAP; + + rslt = bma4_get_int_pin_config(&pin_config, int_line, &bma); + bma4_error_codes_print_result("bma4_get_int_pin_config status", rslt); + + rslt = bma456w_map_interrupt(int_line, (BMA456W_ANY_MOT_INT | BMA456W_NO_MOT_INT), BMA4_ENABLE, &bma); + bma4_error_codes_print_result("bma456w_map_interrupt status", rslt); + + pin_config.edge_ctrl = BMA4_EDGE_TRIGGER; + pin_config.output_en = BMA4_OUTPUT_ENABLE; + pin_config.lvl = BMA4_ACTIVE_HIGH; + pin_config.od = BMA4_PUSH_PULL; + pin_config.input_en = BMA4_INPUT_DISABLE; + + rslt = bma4_set_int_pin_config(&pin_config, int_line, &bma); + bma4_error_codes_print_result("bma4_set_int_pin_config status", rslt); + + /* Get board information */ + get_board_info(&board); + + /* + * Attach interrupt based on board + */ + if (board == BOARD_MCU_APP20) + { + switch (int_line) + { + case BMA4_INTR1_MAP: + coines_attach_interrupt(COINES_SHUTTLE_PIN_20, interrupt_callback, COINES_PIN_INTERRUPT_RISING_EDGE); + break; + + case BMA4_INTR2_MAP: + coines_attach_interrupt(COINES_SHUTTLE_PIN_21, interrupt_callback, COINES_PIN_INTERRUPT_RISING_EDGE); + break; + + default: + break; + } + } + +#if !defined(MCU_APP20) + else if (board == BOARD_MCU_APP30) + { + switch (int_line) + { + case BMA4_INTR1_MAP: + coines_attach_interrupt(COINES_MINI_SHUTTLE_PIN_1_6, + interrupt_callback, + COINES_PIN_INTERRUPT_RISING_EDGE); + break; + + case BMA4_INTR2_MAP: + coines_attach_interrupt(COINES_MINI_SHUTTLE_PIN_1_7, + interrupt_callback, + COINES_PIN_INTERRUPT_RISING_EDGE); + break; + + default: + break; + } + } +#endif + + printf("Shake the board for any-motion interrupt whereas do not shake the board for no-motion interrupt\n"); + + for (;;) + { + if (interrupt_status == 1) + { + interrupt_status = 0; + + /* Read interrupt status */ + rslt = bma456w_read_int_status(&int_status, &bma); + bma4_error_codes_print_result("bma456w_read_int_status", rslt); + + if (rslt == BMA4_OK) + { + /* Enters only if the obtained interrupt is any-motion */ + if (int_status & BMA456W_ANY_MOT_INT) + { + printf("Any-motion interrupt occurred\n"); + iteration--; + } + /* Enters only if the obtained interrupt is no-motion */ + else if (int_status & BMA456W_NO_MOT_INT) + { + printf("No-motion interrupt occurred\n"); + iteration--; + } + + int_status = 0; + + /* Break out of the loop when iteration has reached zero */ + if (iteration == 0) + { + printf("Iterations are done. Exiting !"); + break; + } + } + } + } + + bma4_coines_deinit(); + + return rslt; +} + +/*! + * @brief This internal API is used to get any/no-motion configurations. + */ +static int8_t get_any_no_mot_config(struct bma4_dev *bma) +{ + /* Variable to store the status of API */ + int8_t rslt; + + /* Getting any-motion configuration to get default configuration */ + rslt = bma456w_get_any_mot_config(&any_no_mot, bma); + bma4_error_codes_print_result("bma456w_get_any_mot_config status", rslt); + + if (rslt == BMA4_OK) + { + /* + * Set the slope threshold: + * Interrupt will be generated if the slope of all the axis exceeds the threshold (1 bit = 0.48mG) + */ + any_no_mot.threshold = 10; + + /* + * Set the duration for any-motion interrupt: + * Duration defines the number of consecutive data points for which threshold condition must be true(1 + * bit = + * 20ms) + */ + any_no_mot.duration = 4; + + /* Enabling X, Y, and Z axis for Any-motion feature */ + any_no_mot.axes_en = BMA456W_EN_ALL_AXIS; + + /* Like threshold and duration, we can also change the config of int_bhvr and slope */ + + /* Set the threshold and duration configuration */ + rslt = bma456w_set_any_mot_config(&any_no_mot, bma); + bma4_error_codes_print_result("bma456w_set_any_mot_config status", rslt); + + if (rslt == BMA4_OK) + { + /* Getting no-motion configuration to get default configuration */ + rslt = bma456w_get_no_mot_config(&any_no_mot, bma); + bma4_error_codes_print_result("bma456w_get_no_mot_config status", rslt); + + if (rslt == BMA4_OK) + { + /* + * Set the slope threshold: + * Interrupt will be generated if the slope of all the axis exceeds the threshold (1 bit = 0.48mG) + */ + any_no_mot.threshold = 10; + + /* + * Set the duration for no-motion interrupt: + * Duration defines the number of consecutive data points for which threshold condition must be + * true(1 bit = 20ms) + */ + any_no_mot.duration = 4; + + /* Enabling X, Y, and Z axis for no-motion feature */ + any_no_mot.axes_en = BMA456W_EN_ALL_AXIS; + + /* Like threshold and duration, we can also change the config of int_bhvr */ + + /* Set the threshold and duration configuration */ + rslt = bma456w_set_no_mot_config(&any_no_mot, bma); + bma4_error_codes_print_result("bma456w_set_no_mot_config status", rslt); + } + } + } + + return rslt; +} + +/*! + * @brief This function gets board information + */ +static void get_board_info(uint8_t *board) +{ + struct coines_board_info board_info; + int16_t result; + + result = coines_get_board_info(&board_info); + + if (result == COINES_SUCCESS) + { + (*board) = board_info.board; + } +} diff --git a/components/bma456/bma456w_examples/step_activity/Makefile b/components/bma456/bma456w_examples/step_activity/Makefile new file mode 100644 index 0000000..80d616f --- /dev/null +++ b/components/bma456/bma456w_examples/step_activity/Makefile @@ -0,0 +1,18 @@ +COINES_INSTALL_PATH ?= ../../../.. + +EXAMPLE_FILE ?= step_activity.c + +API_LOCATION ?= ../.. + +COMMON_LOCATION ?= .. + +C_SRCS += \ +$(API_LOCATION)/bma4.c \ +$(API_LOCATION)/bma456w.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/components/bma456/bma456w_examples/step_activity/step_activity.c b/components/bma456/bma456w_examples/step_activity/step_activity.c new file mode 100644 index 0000000..83cb837 --- /dev/null +++ b/components/bma456/bma456w_examples/step_activity/step_activity.c @@ -0,0 +1,127 @@ +/**\ + * Copyright (c) 2022 Bosch Sensortec GmbH. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + **/ + +#include +#include "bma456w.h" +#include "common.h" + +/******************************************************************************/ +/*! Function */ + +/* This function starts the execution of program. */ +int main(void) +{ + /* Variable to store the status of API */ + int8_t rslt; + + /* Sensor initialization configuration */ + struct bma4_dev bma = { 0 }; + + /* Variable to store step activity interrupt status */ + uint16_t int_status = 0; + + /* Variable to hold iteration value */ + uint8_t loop = 1; + + /* Variable to store activity status */ + uint8_t activity_output = 0; + + /* Interface reference is given as a parameter + * For I2C : BMA4_I2C_INTF + * For SPI : BMA4_SPI_INTF + * Variant information given as parameter - BMA45X_VARIANT + */ + rslt = bma4_interface_init(&bma, BMA4_I2C_INTF, BMA45X_VARIANT); + bma4_error_codes_print_result("bma4_interface_init", rslt); + + /* Sensor initialization */ + rslt = bma456w_init(&bma); + bma4_error_codes_print_result("bma456w_init status", rslt); + + /* Upload the configuration file to enable the features of the sensor. */ + rslt = bma456w_write_config_file(&bma); + bma4_error_codes_print_result("bma456w_write_config status", rslt); + + /* Enable the accelerometer */ + rslt = bma4_set_accel_enable(BMA4_ENABLE, &bma); + bma4_error_codes_print_result("bma4_set_accel_enable status", rslt); + + if (rslt == BMA4_OK) + { + /* Map the interrupt 1 for step activity */ + rslt = bma456w_map_interrupt(BMA4_INTR1_MAP, BMA456W_ACTIVITY_INT, BMA4_ENABLE, &bma); + bma4_error_codes_print_result("bma456w_map_interrupt status", rslt); + + if (rslt == BMA4_OK) + { + /* Setting watermark level 1, the output step resolution is 20 steps. + * Eg: 1 means, 1 * 20 = 20. Every 20 steps once output triggers + */ + rslt = bma456w_step_counter_set_watermark(1, &bma); + bma4_error_codes_print_result("bma456w_step_counter_set_watermark status", rslt); + + if (rslt == BMA4_OK) + { + /* Enabling step detector feature */ + rslt = bma456w_feature_enable(BMA456W_STEP_ACT, BMA4_ENABLE, &bma); + bma4_error_codes_print_result("bma456w_feature_enable status", rslt); + } + } + + if (rslt == BMA4_OK) + { + printf("Move the board in steps to perform step activity\n"); + + while (loop <= 5) + { + /* Read interrupt status */ + rslt = bma456w_read_int_status(&int_status, &bma); + bma4_error_codes_print_result("bma456w_read_int_status", rslt); + + /* Filtering only the activity interrupt */ + if ((rslt == BMA4_OK) && (int_status & BMA456W_ACTIVITY_INT)) + { + printf("\nIteration : %d\n", loop); + + /* Get step activity output */ + rslt = bma456w_activity_output(&activity_output, &bma); + bma4_error_codes_print_result("bma456w_activity_output status", rslt); + + if (rslt == BMA4_OK) + { + printf("The Activity output is %d\n", activity_output); + + switch (activity_output) + { + case BMA456W_USER_STATIONARY: + printf("User state is stationary\n"); + break; + case BMA456W_USER_WALKING: + printf("User state is walking\n"); + break; + case BMA456W_USER_RUNNING: + printf("User state is running\n"); + break; + case BMA456W_STATE_INVALID: + printf("User state is invalid state\n"); + break; + default: + break; + } + + loop++; + } + } + + int_status = 0; + } + } + } + + bma4_coines_deinit(); + + return rslt; +} diff --git a/components/bma456/bma456w_examples/step_activity_hw_int/Makefile b/components/bma456/bma456w_examples/step_activity_hw_int/Makefile new file mode 100644 index 0000000..af39ddb --- /dev/null +++ b/components/bma456/bma456w_examples/step_activity_hw_int/Makefile @@ -0,0 +1,20 @@ +COINES_INSTALL_PATH ?= ../../../.. + +EXAMPLE_FILE ?= step_activity_hw_int.c + +API_LOCATION ?= ../.. + +COMMON_LOCATION ?= .. + +C_SRCS += \ +$(API_LOCATION)/bma4.c \ +$(API_LOCATION)/bma456w.c \ +$(COMMON_LOCATION)/common/common.c + +INCLUDEPATHS += \ +$(API_LOCATION) \ +$(COMMON_LOCATION)/common + +TARGET = MCU_APP30 + +include $(COINES_INSTALL_PATH)/coines.mk \ No newline at end of file diff --git a/components/bma456/bma456w_examples/step_activity_hw_int/step_activity_hw_int.c b/components/bma456/bma456w_examples/step_activity_hw_int/step_activity_hw_int.c new file mode 100644 index 0000000..d0ffa0c --- /dev/null +++ b/components/bma456/bma456w_examples/step_activity_hw_int/step_activity_hw_int.c @@ -0,0 +1,251 @@ +/**\ + * Copyright (c) 2022 Bosch Sensortec GmbH. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + **/ + +#include +#include +#include "bma456w.h" +#include "common.h" + +/******************************************************************************/ +/*! Global variable Declaration */ + +volatile uint8_t interrupt_status = 0; + +/******************************************************************************/ +/*! Macro definition */ + +/*! APP20 Board number */ +#define BOARD_MCU_APP20 UINT8_C(0x03) + +/*! APP30 Board number */ +#define BOARD_MCU_APP30 UINT8_C(0x05) + +/******************************************************************************/ +/*! Static Function Declaration */ + +/*! + * @brief This function gets board information + * + * @param[out] board : Board value to determine as APP2.0 or APP3.0 + */ +static void get_board_info(uint8_t *board); + +/*! + * @brief This internal API is used to set the interrupt status + */ +static void interrupt_callback(uint32_t param1, uint32_t param2) +{ + (void)param1; + (void)param2; + interrupt_status = 1; +} + +/******************************************************************************/ +/*! Function */ + +/* This function starts the execution of program. */ +int main(void) +{ + /* Variable to store the status of API */ + int8_t rslt; + + /* Sensor initialization configuration */ + struct bma4_dev bma = { 0 }; + + /* Variable to store step activity interrupt status */ + uint16_t int_status = 0; + + /* Variable to hold iteration value */ + uint8_t loop = 1; + + /* Variable to store activity status */ + uint8_t activity_output = 0; + + struct bma4_int_pin_config pin_config = { 0 }; + uint8_t board = 0; + + /* Variable for interrupt line selection*/ + uint8_t int_line; + + /* Interface reference is given as a parameter + * For I2C : BMA4_I2C_INTF + * For SPI : BMA4_SPI_INTF + * Variant information given as parameter - BMA45X_VARIANT + */ + rslt = bma4_interface_init(&bma, BMA4_I2C_INTF, BMA45X_VARIANT); + bma4_error_codes_print_result("bma4_interface_init", rslt); + + /* Sensor initialization */ + rslt = bma456w_init(&bma); + bma4_error_codes_print_result("bma456w_init status", rslt); + + /* Upload the configuration file to enable the features of the sensor. */ + rslt = bma456w_write_config_file(&bma); + bma4_error_codes_print_result("bma456w_write_config status", rslt); + + /* Enable the accelerometer */ + rslt = bma4_set_accel_enable(BMA4_ENABLE, &bma); + bma4_error_codes_print_result("bma4_set_accel_enable status", rslt); + + if (rslt == BMA4_OK) + { + /* Setting watermark level 1, the output step resolution is 20 steps. + * Eg: 1 means, 1 * 20 = 20. Every 20 steps once output triggers + */ + rslt = bma456w_step_counter_set_watermark(1, &bma); + bma4_error_codes_print_result("bma456w_step_counter_set_watermark status", rslt); + + if (rslt == BMA4_OK) + { + /* Enabling step detector feature */ + rslt = bma456w_feature_enable(BMA456W_STEP_ACT, BMA4_ENABLE, &bma); + bma4_error_codes_print_result("bma456w_feature_enable status", rslt); + } + } + + if (rslt == BMA4_OK) + { + /* Hardware interrupt configuration */ + int_line = BMA4_INTR1_MAP; + + rslt = bma4_get_int_pin_config(&pin_config, int_line, &bma); + bma4_error_codes_print_result("bma4_get_int_pin_config status", rslt); + + rslt = bma456w_map_interrupt(int_line, BMA456W_ACTIVITY_INT, BMA4_ENABLE, &bma); + bma4_error_codes_print_result("bma456w_map_interrupt status", rslt); + + pin_config.edge_ctrl = BMA4_EDGE_TRIGGER; + pin_config.output_en = BMA4_OUTPUT_ENABLE; + pin_config.lvl = BMA4_ACTIVE_HIGH; + pin_config.od = BMA4_PUSH_PULL; + pin_config.input_en = BMA4_INPUT_DISABLE; + + rslt = bma4_set_int_pin_config(&pin_config, int_line, &bma); + bma4_error_codes_print_result("bma4_set_int_pin_config status", rslt); + + /* Get board information */ + get_board_info(&board); + + /* + * Attach interrupt based on board + */ + if (board == BOARD_MCU_APP20) + { + switch (int_line) + { + case BMA4_INTR1_MAP: + coines_attach_interrupt(COINES_SHUTTLE_PIN_20, interrupt_callback, + COINES_PIN_INTERRUPT_RISING_EDGE); + break; + + case BMA4_INTR2_MAP: + coines_attach_interrupt(COINES_SHUTTLE_PIN_21, interrupt_callback, + COINES_PIN_INTERRUPT_RISING_EDGE); + break; + + default: + break; + } + } + +#if !defined(MCU_APP20) + else if (board == BOARD_MCU_APP30) + { + switch (int_line) + { + case BMA4_INTR1_MAP: + coines_attach_interrupt(COINES_MINI_SHUTTLE_PIN_1_6, + interrupt_callback, + COINES_PIN_INTERRUPT_RISING_EDGE); + break; + + case BMA4_INTR2_MAP: + coines_attach_interrupt(COINES_MINI_SHUTTLE_PIN_1_7, + interrupt_callback, + COINES_PIN_INTERRUPT_RISING_EDGE); + break; + + default: + break; + } + } +#endif + } + + if (rslt == BMA4_OK) + { + printf("Move the board in steps to perform step activity\n"); + + while (loop <= 5) + { + if (interrupt_status == 1) + { + interrupt_status = 0; + + /* Read interrupt status */ + rslt = bma456w_read_int_status(&int_status, &bma); + bma4_error_codes_print_result("bma456w_read_int_status", rslt); + + /* Filtering only the activity interrupt */ + if ((rslt == BMA4_OK) && (int_status & BMA456W_ACTIVITY_INT)) + { + printf("\nIteration : %d\n", loop); + + /* Get step activity output */ + rslt = bma456w_activity_output(&activity_output, &bma); + bma4_error_codes_print_result("bma456w_activity_output status", rslt); + + if (rslt == BMA4_OK) + { + printf("The Activity output is %d\n", activity_output); + + switch (activity_output) + { + case BMA456W_USER_STATIONARY: + printf("User state is stationary\n"); + break; + case BMA456W_USER_WALKING: + printf("User state is walking\n"); + break; + case BMA456W_USER_RUNNING: + printf("User state is running\n"); + break; + case BMA456W_STATE_INVALID: + printf("User state is invalid state\n"); + break; + default: + break; + } + + loop++; + } + } + + int_status = 0; + } + } + } + + bma4_coines_deinit(); + + return rslt; +} + +/*! + * @brief This function gets board information + */ +static void get_board_info(uint8_t *board) +{ + struct coines_board_info board_info; + int16_t result; + + result = coines_get_board_info(&board_info); + + if (result == COINES_SUCCESS) + { + (*board) = board_info.board; + } +} diff --git a/components/bma456/bma456w_examples/step_counter/Makefile b/components/bma456/bma456w_examples/step_counter/Makefile new file mode 100644 index 0000000..601750b --- /dev/null +++ b/components/bma456/bma456w_examples/step_counter/Makefile @@ -0,0 +1,18 @@ +COINES_INSTALL_PATH ?= ../../../.. + +EXAMPLE_FILE ?= step_counter.c + +API_LOCATION ?= ../.. + +COMMON_LOCATION ?= .. + +C_SRCS += \ +$(API_LOCATION)/bma4.c \ +$(API_LOCATION)/bma456w.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/components/bma456/bma456w_examples/step_counter/step_counter.c b/components/bma456/bma456w_examples/step_counter/step_counter.c new file mode 100644 index 0000000..1dd29ff --- /dev/null +++ b/components/bma456/bma456w_examples/step_counter/step_counter.c @@ -0,0 +1,91 @@ +/**\ + * Copyright (c) 2022 Bosch Sensortec GmbH. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + **/ + +#include +#include "bma456w.h" +#include "common.h" + +/******************************************************************************/ +/*! Function */ + +/* This function starts the execution of program. */ +int main(void) +{ + /* Variable to store the status of API */ + int8_t rslt; + + /* Sensor initialization configuration */ + struct bma4_dev bma = { 0 }; + + /* Variable to store step counter interrupt status */ + uint16_t int_status = 0; + + /* Variable to store step counter status */ + uint32_t step_out = 0; + + /* Interface reference is given as a parameter + * For I2C : BMA4_I2C_INTF + * For SPI : BMA4_SPI_INTF + * Variant information given as parameter - BMA45X_VARIANT + */ + rslt = bma4_interface_init(&bma, BMA4_I2C_INTF, BMA45X_VARIANT); + bma4_error_codes_print_result("bma4_interface_init", rslt); + + /* Sensor initialization */ + rslt = bma456w_init(&bma); + bma4_error_codes_print_result("bma456w_init status", rslt); + + /* Upload the configuration file to enable the features of the sensor. */ + rslt = bma456w_write_config_file(&bma); + bma4_error_codes_print_result("bma456w_write_config status", rslt); + + /* Enable accelerometer to perform feature testing */ + rslt = bma4_set_accel_enable(BMA4_ENABLE, &bma); + bma4_error_codes_print_result("bma4_set_accel_enable status", rslt); + + rslt = bma456w_feature_enable(BMA456W_STEP_CNTR, BMA4_ENABLE, &bma); + bma4_error_codes_print_result("bma456w_feature_enable status", rslt); + + rslt = bma456w_map_interrupt(BMA4_INTR1_MAP, BMA456W_STEP_CNTR_INT, BMA4_ENABLE, &bma); + bma4_error_codes_print_result("bma456w_map_interrupt status", rslt); + + /* Setting watermark level 1, the output step resolution is 20 steps. + * Eg: 1 means, 1 * 20 = 20. Every 20 steps once output triggers + */ + rslt = bma456w_step_counter_set_watermark(1, &bma); + bma4_error_codes_print_result("bma456w_step_counter_set_watermark status", rslt); + + printf("Step counter feature is enabled\n"); + + printf("Step counter watermark level is 1 (Output resolution is 20 steps)\n"); + + printf("Move the board in steps for greater than 3 seconds\n"); + + /* Loop over until step counter interrupt occurs */ + for (;;) + { + /* Read the interrupt status (After 20 steps, generates interrupt) */ + rslt = bma456w_read_int_status(&int_status, &bma); + bma4_error_codes_print_result("bma456w_read_int_status", rslt); + + if ((BMA4_OK == rslt) && (int_status & BMA456W_STEP_CNTR_INT)) + { + printf("Step counter interrupt received when watermark level is reached (20 steps)\n"); + + /* Get the step counter output after reset */ + rslt = bma456w_step_counter_output(&step_out, &bma); + bma4_error_codes_print_result("bma456w_step_counter_output status", rslt); + + break; + } + } + + printf("The step counter output is %lu \n", (long unsigned int)step_out); + + bma4_coines_deinit(); + + return rslt; +} diff --git a/components/bma456/bma456w_examples/step_counter_hw_int/Makefile b/components/bma456/bma456w_examples/step_counter_hw_int/Makefile new file mode 100644 index 0000000..d1f63cf --- /dev/null +++ b/components/bma456/bma456w_examples/step_counter_hw_int/Makefile @@ -0,0 +1,20 @@ +COINES_INSTALL_PATH ?= ../../../.. + +EXAMPLE_FILE ?= step_counter_hw_int.c + +API_LOCATION ?= ../.. + +COMMON_LOCATION ?= .. + +C_SRCS += \ +$(API_LOCATION)/bma4.c \ +$(API_LOCATION)/bma456w.c \ +$(COMMON_LOCATION)/common/common.c + +INCLUDEPATHS += \ +$(API_LOCATION) \ +$(COMMON_LOCATION)/common + +TARGET = MCU_APP30 + +include $(COINES_INSTALL_PATH)/coines.mk \ No newline at end of file diff --git a/components/bma456/bma456w_examples/step_counter_hw_int/step_counter_hw_int.c b/components/bma456/bma456w_examples/step_counter_hw_int/step_counter_hw_int.c new file mode 100644 index 0000000..f64394f --- /dev/null +++ b/components/bma456/bma456w_examples/step_counter_hw_int/step_counter_hw_int.c @@ -0,0 +1,214 @@ +/**\ + * Copyright (c) 2022 Bosch Sensortec GmbH. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + **/ + +#include +#include +#include "bma456w.h" +#include "common.h" + +/******************************************************************************/ +/*! Global variable Declaration */ + +volatile uint8_t interrupt_status = 0; + +/******************************************************************************/ +/*! Macro definition */ + +/*! APP20 Board number */ +#define BOARD_MCU_APP20 UINT8_C(0x03) + +/*! APP30 Board number */ +#define BOARD_MCU_APP30 UINT8_C(0x05) + +/******************************************************************************/ +/*! Static Function Declaration */ + +/*! + * @brief This function gets board information + * + * @param[out] board : Board value to determine as APP2.0 or APP3.0 + */ +static void get_board_info(uint8_t *board); + +/*! + * @brief This internal API is used to set the interrupt status + */ +static void interrupt_callback(uint32_t param1, uint32_t param2) +{ + (void)param1; + (void)param2; + interrupt_status = 1; +} + +/******************************************************************************/ +/*! Function */ + +/* This function starts the execution of program. */ +int main(void) +{ + /* Variable to store the status of API */ + int8_t rslt; + + /* Sensor initialization configuration */ + struct bma4_dev bma = { 0 }; + + /* Variable to store step counter interrupt status */ + uint16_t int_status = 0; + + /* Variable to store step counter status */ + uint32_t step_out = 0; + + struct bma4_int_pin_config pin_config = { 0 }; + uint8_t board = 0; + + /* Variable for interrupt line selection*/ + uint8_t int_line; + + /* Interface reference is given as a parameter + * For I2C : BMA4_I2C_INTF + * For SPI : BMA4_SPI_INTF + * Variant information given as parameter - BMA45X_VARIANT + */ + rslt = bma4_interface_init(&bma, BMA4_SPI_INTF, BMA45X_VARIANT); + bma4_error_codes_print_result("bma4_interface_init", rslt); + + /* Sensor initialization */ + rslt = bma456w_init(&bma); + bma4_error_codes_print_result("bma456w_init status", rslt); + + /* Upload the configuration file to enable the features of the sensor. */ + rslt = bma456w_write_config_file(&bma); + bma4_error_codes_print_result("bma456w_write_config status", rslt); + + /* Enable accelerometer to perform feature testing */ + rslt = bma4_set_accel_enable(BMA4_ENABLE, &bma); + bma4_error_codes_print_result("bma4_set_accel_enable status", rslt); + + rslt = bma456w_feature_enable(BMA456W_STEP_CNTR, BMA4_ENABLE, &bma); + bma4_error_codes_print_result("bma456w_feature_enable status", rslt); + + /* Setting watermark level 1, the output step resolution is 20 steps. + * Eg: 1 means, 1 * 20 = 20. Every 20 steps once output triggers + */ + rslt = bma456w_step_counter_set_watermark(1, &bma); + bma4_error_codes_print_result("bma456w_step_counter_set_watermark status", rslt); + + /* Hardware interrupt configuration */ + int_line = BMA4_INTR2_MAP; + + rslt = bma4_get_int_pin_config(&pin_config, int_line, &bma); + bma4_error_codes_print_result("bma4_get_int_pin_config status", rslt); + + rslt = bma456w_map_interrupt(int_line, BMA456W_STEP_CNTR_INT, BMA4_ENABLE, &bma); + bma4_error_codes_print_result("bma456w_map_interrupt status", rslt); + + pin_config.edge_ctrl = BMA4_EDGE_TRIGGER; + pin_config.output_en = BMA4_OUTPUT_ENABLE; + pin_config.lvl = BMA4_ACTIVE_HIGH; + pin_config.od = BMA4_PUSH_PULL; + pin_config.input_en = BMA4_INPUT_DISABLE; + + rslt = bma4_set_int_pin_config(&pin_config, int_line, &bma); + bma4_error_codes_print_result("bma4_set_int_pin_config status", rslt); + + /* Get board information */ + get_board_info(&board); + + /* + * Attach interrupt based on board + */ + if (board == BOARD_MCU_APP20) + { + switch (int_line) + { + case BMA4_INTR1_MAP: + coines_attach_interrupt(COINES_SHUTTLE_PIN_20, interrupt_callback, COINES_PIN_INTERRUPT_RISING_EDGE); + break; + + case BMA4_INTR2_MAP: + coines_attach_interrupt(COINES_SHUTTLE_PIN_21, interrupt_callback, COINES_PIN_INTERRUPT_RISING_EDGE); + break; + + default: + break; + } + } + +#if !defined(MCU_APP20) + else if (board == BOARD_MCU_APP30) + { + switch (int_line) + { + case BMA4_INTR1_MAP: + coines_attach_interrupt(COINES_MINI_SHUTTLE_PIN_1_6, + interrupt_callback, + COINES_PIN_INTERRUPT_RISING_EDGE); + break; + + case BMA4_INTR2_MAP: + coines_attach_interrupt(COINES_MINI_SHUTTLE_PIN_1_7, + interrupt_callback, + COINES_PIN_INTERRUPT_RISING_EDGE); + break; + + default: + break; + } + } +#endif + + printf("Step counter feature is enabled\n"); + + printf("Step counter watermark level is 1 (Output resolution is 20 steps)\n"); + + printf("Move the board in steps for greater than 3 seconds\n"); + + /* Loop over until step counter interrupt occurs */ + for (;;) + { + if (interrupt_status == 1) + { + interrupt_status = 0; + + /* Read the interrupt status (After 20 steps, generates interrupt) */ + rslt = bma456w_read_int_status(&int_status, &bma); + bma4_error_codes_print_result("bma456w_read_int_status", rslt); + + if ((BMA4_OK == rslt) && (int_status & BMA456W_STEP_CNTR_INT)) + { + printf("Step counter interrupt received when watermark level is reached (20 steps)\n"); + + /* Get the step counter output after reset */ + rslt = bma456w_step_counter_output(&step_out, &bma); + bma4_error_codes_print_result("bma456w_step_counter_output status", rslt); + + break; + } + } + } + + printf("The step counter output is %lu \n", (long unsigned int)step_out); + + bma4_coines_deinit(); + + return rslt; +} + +/*! + * @brief This function gets board information + */ +static void get_board_info(uint8_t *board) +{ + struct coines_board_info board_info; + int16_t result; + + result = coines_get_board_info(&board_info); + + if (result == COINES_SUCCESS) + { + (*board) = board_info.board; + } +} diff --git a/components/bma456/bma456w_examples/wrist_wear_wakeup/Makefile b/components/bma456/bma456w_examples/wrist_wear_wakeup/Makefile new file mode 100644 index 0000000..57fb049 --- /dev/null +++ b/components/bma456/bma456w_examples/wrist_wear_wakeup/Makefile @@ -0,0 +1,18 @@ +COINES_INSTALL_PATH ?= ../../../.. + +EXAMPLE_FILE ?= wrist_wear_wakeup.c + +API_LOCATION ?= ../.. + +COMMON_LOCATION ?= .. + +C_SRCS += \ +$(API_LOCATION)/bma4.c \ +$(API_LOCATION)/bma456w.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/components/bma456/bma456w_examples/wrist_wear_wakeup/wrist_wear_wakeup.c b/components/bma456/bma456w_examples/wrist_wear_wakeup/wrist_wear_wakeup.c new file mode 100644 index 0000000..72a3b55 --- /dev/null +++ b/components/bma456/bma456w_examples/wrist_wear_wakeup/wrist_wear_wakeup.c @@ -0,0 +1,127 @@ +/**\ + * Copyright (c) 2022 Bosch Sensortec GmbH. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + **/ + +#include +#include "bma456w.h" +#include "common.h" + +int main(void) +{ + struct bma4_dev bma; + struct bma4_accel_config accel_conf; + struct bma456w_wrist_wear_wakeup_params setting; + uint8_t try = 10; + int8_t rslt; + + /* Variable to get the interrupt status */ + uint16_t int_status = 0; + + /* Interface reference is given as a parameter + * For I2C : BMA4_I2C_INTF + * For SPI : BMA4_SPI_INTF + * Variant information given as parameter - BMA45X_VARIANT + */ + rslt = bma4_interface_init(&bma, BMA4_I2C_INTF, BMA45X_VARIANT); + bma4_error_codes_print_result("bma4_interface_init", rslt); + + /* Sensor initialization */ + rslt = bma456w_init(&bma); + bma4_error_codes_print_result("bma456w_init", rslt); + + /* Upload the configuration file to enable the features of the sensor. */ + rslt = bma456w_write_config_file(&bma); + bma4_error_codes_print_result("bma456w_write_config", rslt); + + /* Accelerometer Configuration Setting */ + /* Output data Rate */ + accel_conf.odr = BMA4_OUTPUT_DATA_RATE_100HZ; + + /* Gravity range of the sensor (+/- 2G, 4G, 8G, 16G) */ + accel_conf.range = BMA4_ACCEL_RANGE_2G; + + /* Bandwidth configure number of sensor samples required to average + * if value = 2, then 4 samples are averaged + * averaged samples = 2^(val(accel bandwidth)) + * Note1 : More info refer datasheets + * Note2 : A higher number of averaged samples will result in a lower noise level of the signal, but since the + * performance power mode phase is increased, the power consumption will also rise. + */ + accel_conf.bandwidth = BMA4_ACCEL_NORMAL_AVG4; + + /* Enable the filter performance mode where averaging of samples + * will be done based on above set bandwidth and ODR. + * There are two modes + * 0 -> Averaging samples (Default) + * 1 -> No averaging + * For more info on No Averaging mode refer datasheets. + */ + accel_conf.perf_mode = BMA4_CIC_AVG_MODE; + + /* Set the accel configurations */ + rslt = bma4_set_accel_config(&accel_conf, &bma); + bma4_error_codes_print_result("bma4_set_accel_config status", rslt); + + /* NOTE : Enable accel after set of configurations */ + rslt = bma4_set_accel_enable(1, &bma); + bma4_error_codes_print_result("bma4_set_accel_enable status", rslt); + + printf("\nEnable wear feature\n"); + + rslt = bma456w_feature_enable(BMA456W_WRIST_WEAR_WAKEUP, 1, &bma); + bma4_error_codes_print_result("bma456w_feature_enable status", rslt); + + rslt = bma456w_get_wrist_wear_wakeup_param_config(&setting, &bma); + bma4_error_codes_print_result("bma456w_get_wrist_wear_wakeup_param_config status", rslt); + + rslt = bma456w_map_interrupt(BMA4_INTR1_MAP, BMA456W_WRIST_WEAR_WAKEUP_INT, BMA4_ENABLE, &bma); + bma4_error_codes_print_result("bma456w_map_interrupt status", rslt); + + printf("Do wear movement\n"); + + for (;;) + { + /* Read the interrupt register to check whether wrist wear interrupt is received. */ + rslt = bma456w_read_int_status(&int_status, &bma); + bma4_error_codes_print_result("bma456w_read_int_status status", rslt); + + /* Check if step counter interrupt is triggered */ + if ((BMA4_OK == rslt) && (int_status & BMA456W_WRIST_WEAR_WAKEUP_INT)) + { + printf("\nWear interrupt is received\n\n"); + + break; + } + } + + printf("\nDisable wear feature\n"); + rslt = bma456w_feature_enable(BMA456W_WRIST_WEAR_WAKEUP, BMA4_DISABLE, &bma); + bma4_error_codes_print_result("bma456w_feature_enable status", rslt); + + rslt = bma456w_map_interrupt(BMA4_INTR1_MAP, BMA456W_WRIST_WEAR_WAKEUP_INT, BMA4_ENABLE, &bma); + bma4_error_codes_print_result("bma456w_map_interrupt status", rslt); + + printf("Do wear movement\n\n"); + + while (try--) + { + rslt = bma456w_read_int_status(&int_status, &bma); + bma4_error_codes_print_result("bma456w_read_int_status status", rslt); + + if (int_status & BMA456W_WRIST_WEAR_WAKEUP_INT) + { + printf("Wear interrupt is received, Test is failed\n"); + break; + } + else + { + printf("Wear feature disable and wear interrupt not received\n"); + } + } + + bma4_coines_deinit(); + + return rslt; +} diff --git a/components/bma456/bma456w_examples/wrist_wear_wakeup_hw_int/Makefile b/components/bma456/bma456w_examples/wrist_wear_wakeup_hw_int/Makefile new file mode 100644 index 0000000..2e3d343 --- /dev/null +++ b/components/bma456/bma456w_examples/wrist_wear_wakeup_hw_int/Makefile @@ -0,0 +1,20 @@ +COINES_INSTALL_PATH ?= ../../../.. + +EXAMPLE_FILE ?= wrist_wear_wakeup_hw_int.c + +API_LOCATION ?= ../.. + +COMMON_LOCATION ?= .. + +C_SRCS += \ +$(API_LOCATION)/bma4.c \ +$(API_LOCATION)/bma456w.c \ +$(COMMON_LOCATION)/common/common.c + +INCLUDEPATHS += \ +$(API_LOCATION) \ +$(COMMON_LOCATION)/common + +TARGET = MCU_APP30 + +include $(COINES_INSTALL_PATH)/coines.mk \ No newline at end of file diff --git a/components/bma456/bma456w_examples/wrist_wear_wakeup_hw_int/wrist_wear_wakeup_hw_int.c b/components/bma456/bma456w_examples/wrist_wear_wakeup_hw_int/wrist_wear_wakeup_hw_int.c new file mode 100644 index 0000000..c470d01 --- /dev/null +++ b/components/bma456/bma456w_examples/wrist_wear_wakeup_hw_int/wrist_wear_wakeup_hw_int.c @@ -0,0 +1,251 @@ +/**\ + * Copyright (c) 2022 Bosch Sensortec GmbH. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + **/ + +#include +#include +#include "bma456w.h" +#include "common.h" + +/******************************************************************************/ +/*! Global variable Declaration */ + +volatile uint8_t interrupt_status = 0; + +/******************************************************************************/ +/*! Macro definition */ + +/*! APP20 Board number */ +#define BOARD_MCU_APP20 UINT8_C(0x03) + +/*! APP30 Board number */ +#define BOARD_MCU_APP30 UINT8_C(0x05) + +/******************************************************************************/ +/*! Static Function Declaration */ + +/*! + * @brief This function gets board information + * + * @param[out] board : Board value to determine as APP2.0 or APP3.0 + */ +static void get_board_info(uint8_t *board); + +/*! + * @brief This internal API is used to set the interrupt status + */ +static void interrupt_callback(uint32_t param1, uint32_t param2) +{ + (void)param1; + (void)param2; + interrupt_status = 1; +} + +/******************************************************************************/ +/*! Function */ + +int main(void) +{ + struct bma4_dev bma; + struct bma4_accel_config accel_conf; + struct bma456w_wrist_wear_wakeup_params setting; + uint8_t try = 10; + int8_t rslt; + + uint16_t int_status = 0; + uint8_t board = 0; + struct bma4_int_pin_config pin_config = { 0 }; + + /* Variable for interrupt line selection*/ + uint8_t int_line; + + /* Interface reference is given as a parameter + * For I2C : BMA4_I2C_INTF + * For SPI : BMA4_SPI_INTF + * Variant information given as parameter - BMA45X_VARIANT + */ + rslt = bma4_interface_init(&bma, BMA4_I2C_INTF, BMA45X_VARIANT); + bma4_error_codes_print_result("bma4_interface_init", rslt); + + /* Sensor initialization */ + rslt = bma456w_init(&bma); + bma4_error_codes_print_result("bma456w_init", rslt); + + /* Upload the configuration file to enable the features of the sensor. */ + rslt = bma456w_write_config_file(&bma); + bma4_error_codes_print_result("bma456w_write_config", rslt); + + /* Accelerometer Configuration Setting */ + /* Output data Rate */ + accel_conf.odr = BMA4_OUTPUT_DATA_RATE_100HZ; + + /* Gravity range of the sensor (+/- 2G, 4G, 8G, 16G) */ + accel_conf.range = BMA4_ACCEL_RANGE_2G; + + /* Bandwidth configure number of sensor samples required to average + * if value = 2, then 4 samples are averaged + * averaged samples = 2^(val(accel bandwidth)) + * Note1 : More info refer datasheets + * Note2 : A higher number of averaged samples will result in a lower noise level of the signal, but since the + * performance power mode phase is increased, the power consumption will also rise. + */ + accel_conf.bandwidth = BMA4_ACCEL_NORMAL_AVG4; + + /* Enable the filter performance mode where averaging of samples + * will be done based on above set bandwidth and ODR. + * There are two modes + * 0 -> Averaging samples (Default) + * 1 -> No averaging + * For more info on No Averaging mode refer datasheets. + */ + accel_conf.perf_mode = BMA4_CIC_AVG_MODE; + + /* Set the accel configurations */ + rslt = bma4_set_accel_config(&accel_conf, &bma); + bma4_error_codes_print_result("bma4_set_accel_config status", rslt); + + /* NOTE : Enable accel after set of configurations */ + rslt = bma4_set_accel_enable(1, &bma); + bma4_error_codes_print_result("bma4_set_accel_enable status", rslt); + + printf("\nEnable wear feature\n"); + + rslt = bma456w_feature_enable(BMA456W_WRIST_WEAR_WAKEUP, 1, &bma); + bma4_error_codes_print_result("bma456w_feature_enable status", rslt); + + rslt = bma456w_get_wrist_wear_wakeup_param_config(&setting, &bma); + bma4_error_codes_print_result("bma456w_get_wrist_wear_wakeup_param_config status", rslt); + + /* Hardware interrupt configuration */ + int_line = BMA4_INTR1_MAP; + + rslt = bma4_get_int_pin_config(&pin_config, int_line, &bma); + bma4_error_codes_print_result("bma4_get_int_pin_config status", rslt); + + rslt = bma456w_map_interrupt(int_line, BMA456W_WRIST_WEAR_WAKEUP_INT, BMA4_ENABLE, &bma); + bma4_error_codes_print_result("bma456w_map_interrupt status", rslt); + + pin_config.edge_ctrl = BMA4_EDGE_TRIGGER; + pin_config.output_en = BMA4_OUTPUT_ENABLE; + pin_config.lvl = BMA4_ACTIVE_HIGH; + pin_config.od = BMA4_PUSH_PULL; + pin_config.input_en = BMA4_INPUT_DISABLE; + + rslt = bma4_set_int_pin_config(&pin_config, int_line, &bma); + bma4_error_codes_print_result("bma4_set_int_pin_config status", rslt); + + /* Get board information */ + get_board_info(&board); + + /* + * Attach interrupt based on board + */ + if (board == BOARD_MCU_APP20) + { + switch (int_line) + { + case BMA4_INTR1_MAP: + coines_attach_interrupt(COINES_SHUTTLE_PIN_20, interrupt_callback, COINES_PIN_INTERRUPT_RISING_EDGE); + break; + + case BMA4_INTR2_MAP: + coines_attach_interrupt(COINES_SHUTTLE_PIN_21, interrupt_callback, COINES_PIN_INTERRUPT_RISING_EDGE); + break; + + default: + break; + } + } + +#if !defined(MCU_APP20) + else if (board == BOARD_MCU_APP30) + { + switch (int_line) + { + case BMA4_INTR1_MAP: + coines_attach_interrupt(COINES_MINI_SHUTTLE_PIN_1_6, + interrupt_callback, + COINES_PIN_INTERRUPT_RISING_EDGE); + break; + + case BMA4_INTR2_MAP: + coines_attach_interrupt(COINES_MINI_SHUTTLE_PIN_1_7, + interrupt_callback, + COINES_PIN_INTERRUPT_RISING_EDGE); + break; + + default: + break; + } + } +#endif + + printf("Do wear movement\n"); + + for (;;) + { + if (interrupt_status == 1) + { + interrupt_status = 0; + + /* Read the interrupt register to check whether wrist wear interrupt is received. */ + rslt = bma456w_read_int_status(&int_status, &bma); + bma4_error_codes_print_result("bma456w_read_int_status status", rslt); + + /* Check if step counter interrupt is triggered */ + if ((BMA4_OK == rslt) && (int_status & BMA456W_WRIST_WEAR_WAKEUP_INT)) + { + printf("\nWear interrupt is received\n\n"); + + break; + } + } + } + + printf("\nDisable wear feature\n"); + rslt = bma456w_feature_enable(BMA456W_WRIST_WEAR_WAKEUP, BMA4_DISABLE, &bma); + bma4_error_codes_print_result("bma456w_feature_enable status", rslt); + + rslt = bma456w_map_interrupt(BMA4_INTR1_MAP, BMA456W_WRIST_WEAR_WAKEUP_INT, BMA4_ENABLE, &bma); + bma4_error_codes_print_result("bma456w_map_interrupt status", rslt); + + printf("Do wear movement\n\n"); + + while (try--) + { + rslt = bma456w_read_int_status(&int_status, &bma); + bma4_error_codes_print_result("bma456w_read_int_status status", rslt); + + if (int_status & BMA456W_WRIST_WEAR_WAKEUP_INT) + { + printf("Wear interrupt is received, Test is failed\n"); + break; + } + else + { + printf("Wear feature disable and wear interrupt not received\n"); + } + } + + bma4_coines_deinit(); + + return rslt; +} + +/*! + * @brief This function gets board information + */ +static void get_board_info(uint8_t *board) +{ + struct coines_board_info board_info; + int16_t result; + + result = coines_get_board_info(&board_info); + + if (result == COINES_SUCCESS) + { + (*board) = board_info.board; + } +} diff --git a/components/bma456/bma4_defs.h b/components/bma456/bma4_defs.h new file mode 100644 index 0000000..bcfad55 --- /dev/null +++ b/components/bma456/bma4_defs.h @@ -0,0 +1,1299 @@ +/** +* 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. +* +* @file bma4_defs.h +* @date 2023-07-05 +* @version V2.29.0 +* +*/ + +/*! \file bma4_defs.h + * \brief Sensor Driver for BMA4 family of sensors + */ +#ifndef BMA4_DEFS_H__ +#define BMA4_DEFS_H__ + +/*********************************************************************/ +/**\ header files */ +#ifdef __KERNEL__ +#include +#else +#include +#include +#include +#endif + +/*********************************************************************/ +/* macro definitions */ + +#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 + +#else /* __KERNEL__ */ + +#if (!defined(UINT8_C) && !defined(INT8_C)) +#define INT8_C(x) (x) +#define UINT8_C(x) (x##U) +#endif + +#if (!defined(UINT16_C) && !defined(INT16_C)) +#define INT16_C(x) (x) +#define UINT16_C(x) (x##U) +#endif + +#if (!defined(INT32_C) && !defined(UINT32_C)) +#define INT32_C(x) (x) +#define UINT32_C(x) (x##U) +#endif + +#if (!defined(INT64_C) && !defined(UINT64_C)) +#define INT64_C(x) (x##LL) +#define UINT64_C(x) (x##ULL) +#endif + +#endif /* __KERNEL__ */ + +/**\name CHIP ID ADDRESS*/ +#define BMA4_CHIP_ID_ADDR UINT8_C(0x00) + +/**\name ERROR STATUS*/ +#define BMA4_ERROR_ADDR UINT8_C(0x02) + +/**\name STATUS REGISTER FOR SENSOR STATUS FLAG*/ +#define BMA4_STATUS_ADDR UINT8_C(0x03) + +/**\name AUX/ACCEL DATA BASE ADDRESS REGISTERS*/ +#define BMA4_DATA_0_ADDR UINT8_C(0x0A) +#define BMA4_DATA_8_ADDR UINT8_C(0x12) + +/**\name SENSOR TIME REGISTERS*/ +#define BMA4_SENSORTIME_0_ADDR UINT8_C(0x18) + +/**\name INTERRUPT/FEATURE STATUS REGISTERS*/ +#define BMA4_INT_STAT_0_ADDR UINT8_C(0x1C) + +/**\name INTERRUPT/FEATURE STATUS REGISTERS*/ +#define BMA4_INT_STAT_1_ADDR UINT8_C(0x1D) + +/**\name TEMPERATURE REGISTERS*/ +#define BMA4_TEMPERATURE_ADDR UINT8_C(0x22) + +/**\name FIFO REGISTERS*/ +#define BMA4_FIFO_LENGTH_0_ADDR UINT8_C(0x24) +#define BMA4_FIFO_DATA_ADDR UINT8_C(0x26) + +/**\name ACCEL CONFIG REGISTERS*/ +#define BMA4_ACCEL_CONFIG_ADDR UINT8_C(0x40) + +/**\name ACCEL RANGE ADDRESS*/ +#define BMA4_ACCEL_RANGE_ADDR UINT8_C(0x41) + +/**\name AUX CONFIG REGISTERS*/ +#define BMA4_AUX_CONFIG_ADDR UINT8_C(0x44) + +/**\name FIFO DOWN SAMPLING REGISTER ADDRESS FOR ACCEL*/ +#define BMA4_FIFO_DOWN_ADDR UINT8_C(0x45) + +/**\name FIFO WATERMARK REGISTER ADDRESS*/ +#define BMA4_FIFO_WTM_0_ADDR UINT8_C(0x46) + +/**\name FIFO CONFIG REGISTERS*/ +#define BMA4_FIFO_CONFIG_0_ADDR UINT8_C(0x48) +#define BMA4_FIFO_CONFIG_1_ADDR UINT8_C(0x49) + +/**\name MAG INTERFACE REGISTERS*/ +#define BMA4_AUX_DEV_ID_ADDR UINT8_C(0x4B) +#define BMA4_AUX_IF_CONF_ADDR UINT8_C(0x4C) +#define BMA4_AUX_RD_ADDR UINT8_C(0x4D) +#define BMA4_AUX_WR_ADDR UINT8_C(0x4E) +#define BMA4_AUX_WR_DATA_ADDR UINT8_C(0x4F) + +/**\name INTERRUPT ENABLE REGISTERS*/ +#define BMA4_INT1_IO_CTRL_ADDR UINT8_C(0x53) +#define BMA4_INT2_IO_CTRL_ADDR UINT8_C(0x54) + +/**\name LATCH DURATION REGISTERS*/ +#define BMA4_INTR_LATCH_ADDR UINT8_C(0x55) + +/**\name MAP INTERRUPT 1 and 2 REGISTERS*/ +#define BMA4_INT_MAP_1_ADDR UINT8_C(0x56) +#define BMA4_INT_MAP_2_ADDR UINT8_C(0x57) +#define BMA4_INT_MAP_DATA_ADDR UINT8_C(0x58) +#define BMA4_INIT_CTRL_ADDR UINT8_C(0x59) + +/**\name FEATURE CONFIG RELATED */ +#define BMA4_RESERVED_REG_5B_ADDR UINT8_C(0x5B) +#define BMA4_RESERVED_REG_5C_ADDR UINT8_C(0x5C) +#define BMA4_FEATURE_CONFIG_ADDR UINT8_C(0x5E) +#define BMA4_INTERNAL_ERROR UINT8_C(0x5F) + +/**\name SERIAL INTERFACE SETTINGS REGISTER*/ +#define BMA4_IF_CONFIG_ADDR UINT8_C(0x6B) + +/**\name SELF_TEST REGISTER*/ +#define BMA4_ACC_SELF_TEST_ADDR UINT8_C(0x6D) + +/**\name Macro to define accelerometer configuration value for FOC */ +#define BMA4_FOC_ACC_CONF_VAL UINT8_C(0xB7) + +/**\name SPI,I2C SELECTION REGISTER*/ +#define BMA4_NV_CONFIG_ADDR UINT8_C(0x70) + +/**\name ACCEL OFFSET REGISTERS*/ +#define BMA4_OFFSET_0_ADDR UINT8_C(0x71) +#define BMA4_OFFSET_1_ADDR UINT8_C(0x72) +#define BMA4_OFFSET_2_ADDR UINT8_C(0x73) + +/**\name POWER_CTRL REGISTER*/ +#define BMA4_POWER_CONF_ADDR UINT8_C(0x7C) +#define BMA4_POWER_CTRL_ADDR UINT8_C(0x7D) + +/**\name COMMAND REGISTER*/ +#define BMA4_CMD_ADDR UINT8_C(0x7E) + +/**\name GPIO REGISTERS*/ +#define BMA4_STEP_CNT_OUT_0_ADDR UINT8_C(0x1E) +#define BMA4_HIGH_G_OUT_ADDR UINT8_C(0x1F) +#define BMA4_ACTIVITY_OUT_ADDR UINT8_C(0x27) +#define BMA4_ORIENTATION_OUT_ADDR UINT8_C(0x28) +#define BMA4_MEMS_ID_ADDR UINT8_C(0x29) +#define BMA4_INTERNAL_STAT UINT8_C(0x2A) + +/* Maximum length to read */ +#define BMA4_MAX_LEN UINT8_C(128) + +/*! Macro to read sensortime byte in FIFO */ +#define BMA4_SENSORTIME_OVERHEAD_BYTE UINT8_C(150) + +/* Sensortime resolution in seconds */ +#define BMA4_SENSORTIME_RESOLUTION 0.0000390625f + +/*! + * @brief Block size for config write + */ +#define BMA4_BLOCK_SIZE UINT8_C(32) + +/**\name I2C slave address */ +#define BMA4_I2C_ADDR_PRIMARY UINT8_C(0x18) +#define BMA4_I2C_ADDR_SECONDARY UINT8_C(0x19) +#define BMA4_I2C_BMM150_ADDR UINT8_C(0x10) + +/**\name Interface selection macro */ +#define BMA4_SPI_WR_MASK UINT8_C(0x7F) +#define BMA4_SPI_RD_MASK UINT8_C(0x80) + +/**\name Chip ID macros */ +#define BMA4_CHIP_ID_MIN UINT8_C(0x10) +#define BMA4_CHIP_ID_MAX UINT8_C(0x15) + +/**\name Auxiliary sensor selection macro */ +#define BMM150_SENSOR UINT8_C(1) +#define AKM9916_SENSOR UINT8_C(2) +#define BMA4_ASIC_INITIALIZED UINT8_C(0x01) + +/**\name Auxiliary sensor chip id macros */ +#define BMM150_CHIP_ID UINT8_C(0x32) + +/**\name Auxiliary sensor other macros */ +#define BMM150_POWER_CONTROL_REG UINT8_C(0x4B) +#define BMM150_POWER_MODE_REG UINT8_C(0x4C) + +/**\name CONSTANTS */ +#define BMA4_FIFO_CONFIG_LENGTH UINT8_C(2) +#define BMA4_ACCEL_CONFIG_LENGTH UINT8_C(2) +#define BMA4_FIFO_WM_LENGTH UINT8_C(2) +#define BMA4_NON_LATCH_MODE UINT8_C(0) +#define BMA4_LATCH_MODE UINT8_C(1) +#define BMA4_OPEN_DRAIN UINT8_C(1) +#define BMA4_PUSH_PULL UINT8_C(0) +#define BMA4_ACTIVE_HIGH UINT8_C(1) +#define BMA4_ACTIVE_LOW UINT8_C(0) +#define BMA4_EDGE_TRIGGER UINT8_C(1) +#define BMA4_LEVEL_TRIGGER UINT8_C(0) +#define BMA4_OUTPUT_ENABLE UINT8_C(1) +#define BMA4_OUTPUT_DISABLE UINT8_C(0) +#define BMA4_INPUT_ENABLE UINT8_C(1) +#define BMA4_INPUT_DISABLE UINT8_C(0) + +/**\name ACCEL RANGE CHECK*/ +#define BMA4_ACCEL_RANGE_2G UINT8_C(0) +#define BMA4_ACCEL_RANGE_4G UINT8_C(1) +#define BMA4_ACCEL_RANGE_8G UINT8_C(2) +#define BMA4_ACCEL_RANGE_16G UINT8_C(3) + +/**\name CONDITION CHECK FOR READING AND WRTING DATA*/ +#define BMA4_MAX_VALUE_FIFO_FILTER UINT8_C(1) +#define BMA4_MAX_VALUE_SPI3 UINT8_C(1) +#define BMA4_MAX_VALUE_SELFTEST_AMP UINT8_C(1) +#define BMA4_MAX_IF_MODE UINT8_C(3) +#define BMA4_MAX_VALUE_SELFTEST_SIGN UINT8_C(1) + +/**\name BUS READ AND WRITE LENGTH FOR MAG & ACCEL*/ +#define BMA4_MAG_TRIM_DATA_SIZE UINT8_C(16) +#define BMA4_MAG_XYZ_DATA_LENGTH UINT8_C(6) +#define BMA4_MAG_XYZR_DATA_LENGTH UINT8_C(8) +#define BMA4_ACCEL_DATA_LENGTH UINT8_C(6) +#define BMA4_FIFO_DATA_LENGTH UINT8_C(2) +#define BMA4_TEMP_DATA_SIZE UINT8_C(1) + +/**\name TEMPERATURE CONSTANT */ +#define BMA4_OFFSET_TEMP UINT8_C(23) +#define BMA4_DEG UINT8_C(1) +#define BMA4_FAHREN UINT8_C(2) +#define BMA4_KELVIN UINT8_C(3) + +/**\name DELAY DEFINITION IN MSEC*/ +#define BMA4_AUX_IF_DELAY UINT8_C(5) +#define BMA4_BMM150_WAKEUP_DELAY1 UINT8_C(2) +#define BMA4_BMM150_WAKEUP_DELAY2 UINT8_C(3) +#define BMA4_BMM150_WAKEUP_DELAY3 UINT8_C(1) +#define BMA4_GEN_READ_WRITE_DELAY UINT16_C(1000) +#define BMA4_AUX_COM_DELAY UINT16_C(10000) + +/**\name ARRAY PARAMETER DEFINITIONS*/ +#define BMA4_SENSOR_TIME_MSB_BYTE UINT8_C(2) +#define BMA4_SENSOR_TIME_XLSB_BYTE UINT8_C(1) +#define BMA4_SENSOR_TIME_LSB_BYTE UINT8_C(0) +#define BMA4_MAG_X_LSB_BYTE UINT8_C(0) +#define BMA4_MAG_X_MSB_BYTE UINT8_C(1) +#define BMA4_MAG_Y_LSB_BYTE UINT8_C(2) +#define BMA4_MAG_Y_MSB_BYTE UINT8_C(3) +#define BMA4_MAG_Z_LSB_BYTE UINT8_C(4) +#define BMA4_MAG_Z_MSB_BYTE UINT8_C(5) +#define BMA4_MAG_R_LSB_BYTE UINT8_C(6) +#define BMA4_MAG_R_MSB_BYTE UINT8_C(7) +#define BMA4_TEMP_BYTE UINT8_C(0) +#define BMA4_FIFO_LENGTH_MSB_BYTE UINT8_C(1) + +/*! @name To define success code */ +#define BMA4_OK INT8_C(0) + +/*! @name To define error codes */ +#define BMA4_E_NULL_PTR INT8_C(-1) +#define BMA4_E_COM_FAIL INT8_C(-2) +#define BMA4_E_DEV_NOT_FOUND INT8_C(-3) +#define BMA4_E_INVALID_SENSOR INT8_C(-4) +#define BMA4_E_CONFIG_STREAM_ERROR INT8_C(-5) +#define BMA4_E_SELF_TEST_FAIL INT8_C(-6) +#define BMA4_E_INVALID_STATUS INT8_C(-7) +#define BMA4_E_OUT_OF_RANGE INT8_C(-8) +#define BMA4_E_INT_LINE_INVALID INT8_C(-9) +#define BMA4_E_RD_WR_LENGTH_INVALID INT8_C(-10) +#define BMA4_E_AUX_CONFIG_FAIL INT8_C(-11) +#define BMA4_E_SC_FIFO_HEADER_ERR INT8_C(-12) +#define BMA4_E_SC_FIFO_CONFIG_ERR INT8_C(-13) +#define BMA4_E_REMAP_ERROR INT8_C(-14) +#define BMA4_E_AVG_MODE_INVALID_CONF INT8_C(-15) +#define BMA4_E_INVALID_MEMS_ID INT8_C(-16) + +/**\name UTILITY MACROS */ +#define BMA4_SET_LOW_BYTE UINT16_C(0x00FF) +#define BMA4_SET_HIGH_BYTE UINT16_C(0xFF00) +#define BMA4_SET_LOW_NIBBLE UINT8_C(0x0F) + +/* Macros for variant information */ +#define BMA4_MEMS_SPN_281 UINT8_C(0x00) +#define BMA4_MEMS_SPN_013 UINT8_C(0x01) + +/* Macros used for Self test (BMA42X_VARIANT) */ +/* Self-test: Resulting minimum difference signal in mg for BMA42X */ +#define BMA42X_ST_ACC_X_AXIS_SIGNAL_DIFF UINT16_C(400) +#define BMA42X_ST_ACC_Y_AXIS_SIGNAL_DIFF UINT16_C(800) +#define BMA42X_ST_ACC_Z_AXIS_SIGNAL_DIFF UINT16_C(400) + +/* Macros used for Self test (BMA42X_B_VARIANT) */ +/* Self-test: Resulting minimum difference signal in mg for BMA42X_B */ +#define BMA42X_B_ST_ACC_X_AXIS_SIGNAL_DIFF UINT16_C(1800) +#define BMA42X_B_ST_ACC_Y_AXIS_SIGNAL_DIFF UINT16_C(1800) +#define BMA42X_B_ST_ACC_Z_AXIS_SIGNAL_DIFF UINT16_C(1800) + +/* Macros used for Self test (BMA45X_VARIANT) */ +/* Self-test: Resulting minimum difference signal in mg for BMA45X */ +#define BMA45X_ST_ACC_X_AXIS_SIGNAL_DIFF UINT16_C(1800) +#define BMA45X_ST_ACC_Y_AXIS_SIGNAL_DIFF UINT16_C(1800) +#define BMA45X_ST_ACC_Z_AXIS_SIGNAL_DIFF UINT16_C(1800) + +/**\name BOOLEAN TYPES*/ +#ifndef TRUE +#define TRUE UINT8_C(0x01) +#endif + +#ifndef FALSE +#define FALSE UINT8_C(0x00) +#endif + +#ifndef NULL +#define NULL UINT8_C(0x00) +#endif + +/**\name ERROR STATUS POSITION AND MASK*/ +#define BMA4_FATAL_ERR_MSK UINT8_C(0x01) +#define BMA4_CMD_ERR_POS UINT8_C(1) +#define BMA4_CMD_ERR_MSK UINT8_C(0x02) +#define BMA4_ERR_CODE_POS UINT8_C(2) +#define BMA4_ERR_CODE_MSK UINT8_C(0x1C) +#define BMA4_FIFO_ERR_POS UINT8_C(6) +#define BMA4_FIFO_ERR_MSK UINT8_C(0x40) +#define BMA4_AUX_ERR_POS UINT8_C(7) +#define BMA4_AUX_ERR_MSK UINT8_C(0x80) + +/**\name Mask definition for config version */ +#define BMA4_CONFIG_MAJOR_MSK UINT16_C(0x3C0) +#define BMA4_CONFIG_MINOR_MSK UINT8_C(0x3F) + +/**\name Bit position for major version from config */ +#define BMA4_CONFIG_MAJOR_POS UINT8_C(0x06) + +/**\name NV_CONFIG POSITION AND MASK*/ +/* NV_CONF Description - Reg Addr --> (0x70), Bit --> 3 */ +#define BMA4_NV_ACCEL_OFFSET_POS UINT8_C(3) +#define BMA4_NV_ACCEL_OFFSET_MSK UINT8_C(0x08) + +/**\name MAG DATA XYZ POSITION AND MASK*/ +#define BMA4_DATA_MAG_X_LSB_POS UINT8_C(3) +#define BMA4_DATA_MAG_X_LSB_MSK UINT8_C(0xF8) +#define BMA4_DATA_MAG_Y_LSB_POS UINT8_C(3) +#define BMA4_DATA_MAG_Y_LSB_MSK UINT8_C(0xF8) +#define BMA4_DATA_MAG_Z_LSB_POS UINT8_C(1) +#define BMA4_DATA_MAG_Z_LSB_MSK UINT8_C(0xFE) +#define BMA4_DATA_MAG_R_LSB_POS UINT8_C(2) +#define BMA4_DATA_MAG_R_LSB_MSK UINT8_C(0xFC) + +/**\name ACCEL DATA READY POSITION AND MASK*/ +#define BMA4_STAT_DATA_RDY_ACCEL_POS UINT8_C(7) +#define BMA4_STAT_DATA_RDY_ACCEL_MSK UINT8_C(0x80) + +/**\name MAG DATA READY POSITION AND MASK*/ +#define BMA4_STAT_DATA_RDY_MAG_POS UINT8_C(5) +#define BMA4_STAT_DATA_RDY_MAG_MSK UINT8_C(0x20) + +/**\name ADVANCE POWER SAVE POSITION AND MASK*/ +#define BMA4_ADVANCE_POWER_SAVE_MSK UINT8_C(0x01) + +/**\name ACCELEROMETER ENABLE POSITION AND MASK*/ +#define BMA4_ACCEL_ENABLE_POS UINT8_C(2) +#define BMA4_ACCEL_ENABLE_MSK UINT8_C(0x04) + +/**\name MAGNETOMETER ENABLE POSITION AND MASK*/ +#define BMA4_MAG_ENABLE_MSK UINT8_C(0x01) + +/**\name ACCEL CONFIGURATION POSITION AND MASK*/ +#define BMA4_ACCEL_ODR_MSK UINT8_C(0x0F) +#define BMA4_ACCEL_BW_POS UINT8_C(4) +#define BMA4_ACCEL_BW_MSK UINT8_C(0x70) +#define BMA4_ACCEL_RANGE_MSK UINT8_C(0x03) +#define BMA4_ACCEL_PERFMODE_POS UINT8_C(7) +#define BMA4_ACCEL_PERFMODE_MSK UINT8_C(0x80) + +/**\name MAG CONFIGURATION POSITION AND MASK*/ +#define BMA4_MAG_CONFIG_OFFSET_POS UINT8_C(4) +#define BMA4_MAG_CONFIG_OFFSET_LEN UINT8_C(4) +#define BMA4_MAG_CONFIG_OFFSET_MSK UINT8_C(0xF0) +#define BMA4_MAG_CONFIG_OFFSET_REG (BMA4_AUX_CONFIG_ADDR) + +/**\name FIFO SELF WAKE UP POSITION AND MASK*/ +#define BMA4_FIFO_SELF_WAKE_UP_POS UINT8_C(1) +#define BMA4_FIFO_SELF_WAKE_UP_MSK UINT8_C(0x02) + +/**\name FIFO BYTE COUNTER POSITION AND MASK*/ +#define BMA4_FIFO_BYTE_COUNTER_MSB_MSK UINT8_C(0x3F) + +/**\name FIFO DATA POSITION AND MASK*/ +#define BMA4_FIFO_DATA_POS UINT8_C(0) +#define BMA4_FIFO_DATA_MSK UINT8_C(0xFF) + +/**\name FIFO FILTER FOR ACCEL POSITION AND MASK*/ +#define BMA4_FIFO_DOWN_ACCEL_POS UINT8_C(4) +#define BMA4_FIFO_DOWN_ACCEL_MSK UINT8_C(0x70) +#define BMA4_FIFO_FILTER_ACCEL_POS UINT8_C(7) +#define BMA4_FIFO_FILTER_ACCEL_MSK UINT8_C(0x80) + +/**\name FIFO HEADER DATA DEFINITIONS */ +#define BMA4_FIFO_HEAD_A UINT8_C(0x84) +#define BMA4_FIFO_HEAD_M UINT8_C(0x90) +#define BMA4_FIFO_HEAD_M_A UINT8_C(0x94) +#define BMA4_FIFO_HEAD_SENSOR_TIME UINT8_C(0x44) +#define BMA4_FIFO_HEAD_INPUT_CONFIG UINT8_C(0x48) +#define BMA4_FIFO_HEAD_SKIP_FRAME UINT8_C(0x40) +#define BMA4_FIFO_HEAD_OVER_READ_MSB UINT8_C(0x80) +#define BMA4_FIFO_HEAD_SAMPLE_DROP UINT8_C(0x50) + +/**\name FIFO HEADERLESS MODE DATA ENABLE DEFINITIONS */ +#define BMA4_FIFO_M_A_ENABLE UINT8_C(0x60) +#define BMA4_FIFO_A_ENABLE UINT8_C(0x40) +#define BMA4_FIFO_M_ENABLE UINT8_C(0x20) + +/**\name FIFO CONFIGURATION SELECTION */ +#define BMA4_FIFO_STOP_ON_FULL UINT8_C(0x01) +#define BMA4_FIFO_TIME UINT8_C(0x02) +#define BMA4_FIFO_TAG_INTR2 UINT8_C(0x04) +#define BMA4_FIFO_TAG_INTR1 UINT8_C(0x08) +#define BMA4_FIFO_HEADER UINT8_C(0x10) +#define BMA4_FIFO_MAG UINT8_C(0x20) +#define BMA4_FIFO_ACCEL UINT8_C(0x40) +#define BMA4_FIFO_ALL UINT8_C(0x7F) +#define BMA4_FIFO_CONFIG_0_MASK UINT8_C(0x03) +#define BMA4_FIFO_CONFIG_1_MASK UINT8_C(0xFC) + +/**\name FIFO FRAME COUNT DEFINITION */ +#define BMA4_FIFO_LSB_CONFIG_CHECK UINT8_C(0x00) +#define BMA4_FIFO_MSB_CONFIG_CHECK UINT8_C(0x80) +#define BMA4_FIFO_TAG_INTR_MASK UINT8_C(0xFC) + +/**\name FIFO DROPPED FRAME DEFINITION */ +#define BMA4_AUX_FIFO_DROP UINT8_C(0x04) +#define BMA4_ACCEL_AUX_FIFO_DROP UINT8_C(0x05) +#define BMA4_ACCEL_FIFO_DROP UINT8_C(0x01) + +/**\name FIFO MAG DEFINITION*/ +#define BMA4_MA_FIFO_A_X_LSB UINT8_C(8) + +/**\name FIFO sensor time length definitions*/ +#define BMA4_SENSOR_TIME_LENGTH UINT8_C(3) + +/**\name FIFO LENGTH DEFINITION*/ +#define BMA4_FIFO_A_LENGTH UINT8_C(6) +#define BMA4_FIFO_M_LENGTH UINT8_C(8) +#define BMA4_FIFO_MA_LENGTH UINT8_C(14) + +/**\name MAG I2C ADDRESS SELECTION POSITION AND MASK*/ +#define BMA4_I2C_DEVICE_ADDR_POS UINT8_C(1) +#define BMA4_I2C_DEVICE_ADDR_MSK UINT8_C(0xFE) + +/**\name MAG CONFIGURATION FOR SECONDARY INTERFACE POSITION AND MASK*/ +#define BMA4_MAG_BURST_MSK UINT8_C(0x03) +#define BMA4_MAG_MANUAL_ENABLE_POS UINT8_C(7) +#define BMA4_MAG_MANUAL_ENABLE_MSK UINT8_C(0x80) +#define BMA4_READ_ADDR_MSK UINT8_C(0xFF) +#define BMA4_WRITE_ADDR_MSK UINT8_C(0xFF) +#define BMA4_WRITE_DATA_MSK UINT8_C(0xFF) + +/**\name OUTPUT TYPE ENABLE POSITION AND MASK*/ +#define BMA4_INT_EDGE_CTRL_MASK UINT8_C(0x01) +#define BMA4_INT_EDGE_CTRL_POS UINT8_C(0x00) +#define BMA4_INT_LEVEL_MASK UINT8_C(0x02) +#define BMA4_INT_LEVEL_POS UINT8_C(0x01) +#define BMA4_INT_OPEN_DRAIN_MASK UINT8_C(0x04) +#define BMA4_INT_OPEN_DRAIN_POS UINT8_C(0x02) +#define BMA4_INT_OUTPUT_EN_MASK UINT8_C(0x08) +#define BMA4_INT_OUTPUT_EN_POS UINT8_C(0x03) +#define BMA4_INT_INPUT_EN_MASK UINT8_C(0x10) +#define BMA4_INT_INPUT_EN_POS UINT8_C(0x04) + +/**\name IF CONFIG POSITION AND MASK*/ +#define BMA4_CONFIG_SPI3_MSK UINT8_C(0x01) +#define BMA4_IF_CONFIG_IF_MODE_POS UINT8_C(4) +#define BMA4_IF_CONFIG_IF_MODE_MSK UINT8_C(0x10) + +/**\name ACCEL SELF TEST POSITION AND MASK*/ +#define BMA4_ACCEL_SELFTEST_ENABLE_MSK UINT8_C(0x01) +#define BMA4_ACCEL_SELFTEST_SIGN_POS UINT8_C(2) +#define BMA4_ACCEL_SELFTEST_SIGN_MSK UINT8_C(0x04) +#define BMA4_SELFTEST_AMP_POS UINT8_C(3) +#define BMA4_SELFTEST_AMP_MSK UINT8_C(0x08) + +/**\name ACCEL ODR */ +#define BMA4_OUTPUT_DATA_RATE_0_78HZ UINT8_C(0x01) +#define BMA4_OUTPUT_DATA_RATE_1_56HZ UINT8_C(0x02) +#define BMA4_OUTPUT_DATA_RATE_3_12HZ UINT8_C(0x03) +#define BMA4_OUTPUT_DATA_RATE_6_25HZ UINT8_C(0x04) +#define BMA4_OUTPUT_DATA_RATE_12_5HZ UINT8_C(0x05) +#define BMA4_OUTPUT_DATA_RATE_25HZ UINT8_C(0x06) +#define BMA4_OUTPUT_DATA_RATE_50HZ UINT8_C(0x07) +#define BMA4_OUTPUT_DATA_RATE_100HZ UINT8_C(0x08) +#define BMA4_OUTPUT_DATA_RATE_200HZ UINT8_C(0x09) +#define BMA4_OUTPUT_DATA_RATE_400HZ UINT8_C(0x0A) +#define BMA4_OUTPUT_DATA_RATE_800HZ UINT8_C(0x0B) +#define BMA4_OUTPUT_DATA_RATE_1600HZ UINT8_C(0x0C) + +/**\name ACCEL BANDWIDTH PARAMETER */ +#define BMA4_ACCEL_OSR4_AVG1 UINT8_C(0) +#define BMA4_ACCEL_OSR2_AVG2 UINT8_C(1) +#define BMA4_ACCEL_NORMAL_AVG4 UINT8_C(2) +#define BMA4_ACCEL_CIC_AVG8 UINT8_C(3) +#define BMA4_ACCEL_RES_AVG16 UINT8_C(4) +#define BMA4_ACCEL_RES_AVG32 UINT8_C(5) +#define BMA4_ACCEL_RES_AVG64 UINT8_C(6) +#define BMA4_ACCEL_RES_AVG128 UINT8_C(7) + +/**\name ACCEL PERFMODE PARAMETER */ +#define BMA4_CIC_AVG_MODE UINT8_C(0) +#define BMA4_CONTINUOUS_MODE UINT8_C(1) + +/**\name MAG OFFSET */ +#define BMA4_MAG_OFFSET_MAX UINT8_C(0x00) + +/**\name ENABLE/DISABLE SELECTIONS */ +#define BMA4_X_AXIS UINT8_C(0) +#define BMA4_Y_AXIS UINT8_C(1) +#define BMA4_Z_AXIS UINT8_C(2) + +/**\name SELF TEST*/ +#define BMA4_SELFTEST_PASS INT8_C(0) +#define BMA4_SELFTEST_FAIL INT8_C(1) + +#define BMA4_SELFTEST_DIFF_X_AXIS_FAILED INT8_C(1) +#define BMA4_SELFTEST_DIFF_Y_AXIS_FAILED INT8_C(2) +#define BMA4_SELFTEST_DIFF_Z_AXIS_FAILED INT8_C(3) +#define BMA4_SELFTEST_DIFF_X_AND_Y_AXIS_FAILED INT8_C(4) +#define BMA4_SELFTEST_DIFF_X_AND_Z_AXIS_FAILED INT8_C(5) +#define BMA4_SELFTEST_DIFF_Y_AND_Z_AXIS_FAILED INT8_C(6) +#define BMA4_SELFTEST_DIFF_X_Y_AND_Z_AXIS_FAILED INT8_C(7) + +/**\name INTERRUPT MAPS */ +#define BMA4_INTR1_MAP UINT8_C(0) +#define BMA4_INTR2_MAP UINT8_C(1) + +/**\name INTERRUPT MASKS */ +#define BMA4_FIFO_FULL_INT UINT16_C(0x0100) +#define BMA4_FIFO_WM_INT UINT16_C(0x0200) +#define BMA4_DATA_RDY_INT UINT16_C(0x0400) +#define BMA4_MAG_DATA_RDY_INT UINT16_C(0x2000) +#define BMA4_ACCEL_DATA_RDY_INT UINT16_C(0x8000) + +/**\name AKM POWER MODE SELECTION */ +#define BMA4_AKM_POWER_DOWN_MODE UINT8_C(0) +#define BMA4_AKM_SINGLE_MEAS_MODE UINT8_C(1) + +/**\name SECONDARY_MAG POWER MODE SELECTION */ +#define BMA4_MAG_FORCE_MODE UINT8_C(0) +#define BMA4_MAG_SUSPEND_MODE UINT8_C(1) + +/**\name MAG POWER MODE SELECTION */ +#define BMA4_FORCE_MODE UINT8_C(0) +#define BMA4_SUSPEND_MODE UINT8_C(1) + +/**\name ACCEL POWER MODE */ +#define BMA4_ACCEL_MODE_NORMAL UINT8_C(0x11) + +/**\name MAG POWER MODE */ +#define BMA4_MAG_MODE_SUSPEND UINT8_C(0x18) + +/**\name ENABLE/DISABLE BIT VALUES */ +#define BMA4_ENABLE UINT8_C(0x01) +#define BMA4_DISABLE UINT8_C(0x00) + +/**\name DEFINITION USED FOR DIFFERENT WRITE */ +#define BMA4_MANUAL_DISABLE UINT8_C(0x00) +#define BMA4_MANUAL_ENABLE UINT8_C(0x01) +#define BMA4_ENABLE_MAG_IF_MODE UINT8_C(0x01) +#define BMA4_MAG_DATA_READ_REG UINT8_C(0x0A) +#define BMA4_BMM_POWER_MODE_REG UINT8_C(0x06) +#define BMA4_SEC_IF_NULL UINT8_C(0) +#define BMA4_SEC_IF_BMM150 UINT8_C(1) +#define BMA4_SEC_IF_AKM09916 UINT8_C(2) +#define BMA4_ENABLE_AUX_IF_MODE UINT8_C(0x01) + +/**\name SENSOR RESOLUTION */ +#define BMA4_12_BIT_RESOLUTION UINT8_C(12) +#define BMA4_14_BIT_RESOLUTION UINT8_C(14) +#define BMA4_16_BIT_RESOLUTION UINT8_C(16) + +/*************** FOC Macros ******************/ + +/* Reference value with positive and negative noise range in lsb */ + +/* Resolution : 16 bit */ + +/* + * As per datasheet, Zero-g offset : +/- 20mg + * + * In range 2G, 1G is 16384. so, 16384 x 20 x (10 ^ -3) = 328 + * In range 4G, 1G is 8192. so, 8192 x 20 x (10 ^ -3) = 164 + * In range 8G, 1G is 4096. so, 4096 x 20 x (10 ^ -3) = 82 + * In range 16G, 1G is 2048. so, 2048 x 20 x (10 ^ -3) = 41 + */ +#define BMA4_16BIT_ACC_FOC_2G_REF UINT16_C(16384) +#define BMA4_16BIT_ACC_FOC_4G_REF UINT16_C(8192) +#define BMA4_16BIT_ACC_FOC_8G_REF UINT16_C(4096) +#define BMA4_16BIT_ACC_FOC_16G_REF UINT16_C(2048) + +#define BMA4_16BIT_ACC_FOC_2G_OFFSET UINT16_C(328) +#define BMA4_16BIT_ACC_FOC_4G_OFFSET UINT16_C(164) +#define BMA4_16BIT_ACC_FOC_8G_OFFSET UINT16_C(82) +#define BMA4_16BIT_ACC_FOC_16G_OFFSET UINT16_C(41) + +#define BMA4_16BIT_ACC_2G_MAX_NOISE_LIMIT (BMA4_16BIT_ACC_FOC_2G_REF + BMA4_16BIT_ACC_FOC_2G_OFFSET) +#define BMA4_16BIT_ACC_2G_MIN_NOISE_LIMIT (BMA4_16BIT_ACC_FOC_2G_REF - BMA4_16BIT_ACC_FOC_2G_OFFSET) +#define BMA4_16BIT_ACC_4G_MAX_NOISE_LIMIT (BMA4_16BIT_ACC_FOC_4G_REF + BMA4_16BIT_ACC_FOC_4G_OFFSET) +#define BMA4_16BIT_ACC_4G_MIN_NOISE_LIMIT (BMA4_16BIT_ACC_FOC_4G_REF - BMA4_16BIT_ACC_FOC_4G_OFFSET) +#define BMA4_16BIT_ACC_8G_MAX_NOISE_LIMIT (BMA4_16BIT_ACC_FOC_8G_REF + BMA4_16BIT_ACC_FOC_8G_OFFSET) +#define BMA4_16BIT_ACC_8G_MIN_NOISE_LIMIT (BMA4_16BIT_ACC_FOC_8G_REF - BMA4_16BIT_ACC_FOC_8G_OFFSET) +#define BMA4_16BIT_ACC_16G_MAX_NOISE_LIMIT (BMA4_16BIT_ACC_FOC_16G_REF + BMA4_16BIT_ACC_FOC_16G_OFFSET) +#define BMA4_16BIT_ACC_16G_MIN_NOISE_LIMIT (BMA4_16BIT_ACC_FOC_16G_REF - BMA4_16BIT_ACC_FOC_16G_OFFSET) + +/* Resolution : 12 bit */ + +/* + * As per datasheet, Zero-g offset : +/- 80mg + * + * In range 2G, 1G is 1024. so, 1024 x 80 x (10 ^ -3) = 82 + * In range 4G, 1G is 512. so, 512 x 80 x (10 ^ -3) = 41 + * In range 8G, 1G is 256. so, 256 x 80 x (10 ^ -3) = 20 + * In range 16G, 1G is 128. so, 128 x 80 x (10 ^ -3) = 10 + */ +#define BMA4_12BIT_ACC_FOC_2G_REF UINT16_C(1024) +#define BMA4_12BIT_ACC_FOC_4G_REF UINT16_C(512) +#define BMA4_12BIT_ACC_FOC_8G_REF UINT16_C(256) +#define BMA4_12BIT_ACC_FOC_16G_REF UINT16_C(128) + +#define BMA4_12BIT_ACC_FOC_2G_OFFSET UINT8_C(82) +#define BMA4_12BIT_ACC_FOC_4G_OFFSET UINT8_C(41) +#define BMA4_12BIT_ACC_FOC_8G_OFFSET UINT8_C(20) +#define BMA4_12BIT_ACC_FOC_16G_OFFSET UINT8_C(10) + +#define BMA4_12BIT_ACC_2G_MAX_NOISE_LIMIT (BMA4_12BIT_ACC_FOC_2G_REF + BMA4_12BIT_ACC_FOC_2G_OFFSET) +#define BMA4_12BIT_ACC_2G_MIN_NOISE_LIMIT (BMA4_12BIT_ACC_FOC_2G_REF - BMA4_12BIT_ACC_FOC_2G_OFFSET) +#define BMA4_12BIT_ACC_4G_MAX_NOISE_LIMIT (BMA4_12BIT_ACC_FOC_4G_REF + BMA4_12BIT_ACC_FOC_4G_OFFSET) +#define BMA4_12BIT_ACC_4G_MIN_NOISE_LIMIT (BMA4_12BIT_ACC_FOC_4G_REF - BMA4_12BIT_ACC_FOC_4G_OFFSET) +#define BMA4_12BIT_ACC_8G_MAX_NOISE_LIMIT (BMA4_12BIT_ACC_FOC_8G_REF + BMA4_12BIT_ACC_FOC_8G_OFFSET) +#define BMA4_12BIT_ACC_8G_MIN_NOISE_LIMIT (BMA4_12BIT_ACC_FOC_8G_REF - BMA4_12BIT_ACC_FOC_8G_OFFSET) +#define BMA4_12BIT_ACC_16G_MAX_NOISE_LIMIT (BMA4_12BIT_ACC_FOC_16G_REF + BMA4_12BIT_ACC_FOC_16G_OFFSET) +#define BMA4_12BIT_ACC_16G_MIN_NOISE_LIMIT (BMA4_12BIT_ACC_FOC_16G_REF - BMA4_12BIT_ACC_FOC_16G_OFFSET) + +/*! for handling float temperature values */ +#define BMA4_SCALE_TEMP INT32_C(1000) + +/* BMA4_FAHREN_SCALED = 1.8 * 1000 */ +#define BMA4_FAHREN_SCALED INT32_C(1800) + +/* BMA4_KELVIN_SCALED = 273.15 * 1000 */ +#define BMA4_KELVIN_SCALED INT32_C(273150) + +/**\name MAP BURST READ LENGTHS */ +#define BMA4_AUX_READ_LEN_0 UINT8_C(0) +#define BMA4_AUX_READ_LEN_1 UINT8_C(1) +#define BMA4_AUX_READ_LEN_2 UINT8_C(2) +#define BMA4_AUX_READ_LEN_3 UINT8_C(3) + +#define BMA4_CONFIG_STREAM_MESSAGE_MSK UINT8_C(0x0F) + +#define BMA4_SOFT_RESET UINT8_C(0xB6) +#define BMA4_FIFO_FLUSH UINT8_C(0xB0) + +/*********************************************************************/ +/*! @name Macro Definitions for Axes re-mapping */ +/*********************************************************************/ + +/**\name Define values of axis and its sign for re-map settings */ +#define BMA4_MAP_X_AXIS UINT8_C(0x00) +#define BMA4_MAP_Y_AXIS UINT8_C(0x01) +#define BMA4_MAP_Z_AXIS UINT8_C(0x02) +#define BMA4_MAP_POSITIVE UINT8_C(0x00) +#define BMA4_MAP_NEGATIVE UINT8_C(0x01) + +/*! @name Macros for the user-defined values of axes and their polarities */ +#define BMA4_X UINT8_C(0x01) +#define BMA4_NEG_X UINT8_C(0x09) +#define BMA4_Y UINT8_C(0x02) +#define BMA4_NEG_Y UINT8_C(0x0A) +#define BMA4_Z UINT8_C(0x04) +#define BMA4_NEG_Z UINT8_C(0x0C) +#define BMA4_AXIS_MASK UINT8_C(0x07) +#define BMA4_AXIS_SIGN UINT8_C(0x08) + +/**\name Mask definitions for axes re-mapping */ +#define BMA4_X_AXIS_MSK UINT8_C(0x03) +#define BMA4_X_AXIS_SIGN_MSK UINT8_C(0x04) +#define BMA4_Y_AXIS_MSK UINT8_C(0x18) +#define BMA4_Y_AXIS_SIGN_MSK UINT8_C(0x20) +#define BMA4_Z_AXIS_MSK UINT8_C(0xC0) +#define BMA4_Z_AXIS_SIGN_MSK UINT8_C(0x01) + +/**\name Bit position for axes re-mapping */ +#define BMA4_X_AXIS_SIGN_POS UINT8_C(0x02) +#define BMA4_Y_AXIS_POS UINT8_C(0x03) +#define BMA4_Y_AXIS_SIGN_POS UINT8_C(0x05) +#define BMA4_Z_AXIS_POS UINT8_C(0x06) + +#define BMA4_MS_TO_US(X) (X * 1000) + +#ifndef ABS +#define ABS(a) ((a) > 0 ? (a) : -(a)) /*!< Absolute value */ +#endif + +/**\name BIT SLICE GET AND SET FUNCTIONS */ +#define BMA4_GET_BITSLICE(regvar, bitname) \ + ((regvar & bitname##_MSK) >> bitname##_POS) + +#define BMA4_SET_BITSLICE(regvar, bitname, val) \ + ((regvar & ~bitname##_MSK) | \ + ((val << bitname##_POS) & bitname##_MSK)) + +#define BMA4_GET_DIFF(x, y) ((x) - (y)) + +#define BMA4_GET_LSB(var) (uint8_t)(var & BMA4_SET_LOW_BYTE) +#define BMA4_GET_MSB(var) (uint8_t)((var & BMA4_SET_HIGH_BYTE) >> 8) + +#define BMA4_SET_BIT_VAL_0(reg_data, bitname) (reg_data & ~(bitname##_MSK)) + +#define BMA4_SET_BITS_POS_0(reg_data, bitname, data) \ + ((reg_data & ~(bitname##_MSK)) | \ + (data & bitname##_MSK)) + +#define BMA4_GET_BITS_POS_0(reg_data, bitname) (reg_data & (bitname##_MSK)) + +/** + * BMA4_INTF_RET_TYPE is the read/write interface return type which can be overwritten by the build system. + * The default is set to int8_t. + */ +#ifndef BMA4_INTF_RET_TYPE +#define BMA4_INTF_RET_TYPE int8_t +#endif + +/** + * BST_INTF_RET_SUCCESS is the success return value read/write interface return type which can be + * overwritten by the build system. The default is set to 0. It is used to check for a successful + * execution of the read/write functions + */ +#ifndef BMA4_INTF_RET_SUCCESS +#define BMA4_INTF_RET_SUCCESS INT8_C(0) +#endif + +/******************************************************************************/ +/*! @name TYPEDEF DEFINITIONS */ +/******************************************************************************/ + +/*! + * @brief Bus communication function pointer which should be mapped to + * the platform specific read functions of the user + * + * @param[in] reg_addr : Register address from which data is read. + * @param[out] read_data : Pointer to data buffer where read data is stored. + * @param[in] len : Number of bytes of data to be read. + * @param[in, out] intf_ptr : Void pointer that can enable the linking of descriptors + * for interface related call backs. + * + * @retval 0 for Success + * @retval Non-zero for Failure + */ +typedef BMA4_INTF_RET_TYPE (*bma4_read_fptr_t)(uint8_t reg_addr, uint8_t *read_data, uint32_t len, void *intf_ptr); + +/*! + * @brief Bus communication function pointer which should be mapped to + * the platform specific write functions of the user + * + * @param[in] reg_addr : Register address to which the data is written. + * @param[in] read_data : Pointer to data buffer in which data to be written + * is stored. + * @param[in] len : Number of bytes of data to be written. + * @param[in, out] intf_ptr : Void pointer that can enable the linking of descriptors + * for interface related call backs + * + * @retval 0 for Success + * @retval Non-zero for Failure + */ +typedef BMA4_INTF_RET_TYPE (*bma4_write_fptr_t)(uint8_t reg_addr, const uint8_t *read_data, uint32_t len, + void *intf_ptr); + +/*! + * @brief Delay function pointer which should be mapped to + * delay function of the user + * + * @param[in] period : Delay in microseconds. + * @param[in, out] intf_ptr : Void pointer that can enable the linking of descriptors + * for interface related call backs + * + */ +typedef void (*bma4_delay_us_fptr_t)(uint32_t period, void *intf_ptr); + +/******************************************************************************/ +/*! @name Enum Declarations */ +/******************************************************************************/ +/*! @name Enum to define BMA4 variants */ +enum bma4_variant { + BMA42X_VARIANT = UINT8_C(1), + BMA42X_B_VARIANT, + BMA45X_VARIANT +}; + +/* Enumerator describing interfaces */ +enum bma4_intf { + BMA4_SPI_INTF, + BMA4_I2C_INTF +}; + +/**\name STRUCTURE DEFINITIONS*/ + +/*! + * @brief + * This structure holds asic info. for feature configuration. + */ +struct bma4_asic_data +{ + /* Feature config start addr (0-3 bits)*/ + uint8_t asic_lsb; + + /* Feature config start addr (4-11 bits)*/ + uint8_t asic_msb; +}; + +/*! + * @brief Auxiliary configuration structure for user settings + */ +struct bma4_aux_config +{ + /*! Device address of auxiliary sensor */ + uint8_t aux_dev_addr; + + /*! To enable manual or auto mode */ + uint8_t manual_enable; + + /*! No of bytes to be read at a time */ + uint8_t burst_read_length; + + /*! Variable to set the auxiliary interface */ + uint8_t if_mode; +}; + +/*! @name Structure to store the re-mapped axis */ +struct bma4_remap +{ + /*! Re-mapped x-axis */ + uint8_t x; + + /*! Re-mapped y-axis */ + uint8_t y; + + /*! Re-mapped z-axis */ + uint8_t z; +}; + +/*! + * @brief Axes re-mapping configuration + */ +struct bma4_axes_remap +{ + /*! Re-mapped x-axis */ + uint8_t x_axis; + + /*! Re-mapped y-axis */ + uint8_t y_axis; + + /*! Re-mapped z-axis */ + uint8_t z_axis; + + /*! Re-mapped x-axis sign */ + uint8_t x_axis_sign; + + /*! Re-mapped y-axis sign */ + uint8_t y_axis_sign; + + /*! Re-mapped z-axis sign */ + uint8_t z_axis_sign; +}; + +/*! + * @brief + * This structure holds all relevant information about BMA4 + */ +struct bma4_dev +{ + /*! Chip id of BMA4 */ + uint8_t chip_id; + + /*! Chip id of auxiliary sensor */ + uint8_t aux_chip_id; + + /*! Interface pointer */ + void *intf_ptr; + + /*! Interface detail */ + enum bma4_intf intf; + + /*! Variable that holds error code */ + BMA4_INTF_RET_TYPE intf_rslt; + + /*! Auxiliary sensor information */ + uint8_t aux_sensor; + + /*! Decide SPI or I2C read mechanism */ + uint8_t dummy_byte; + + /*! Resolution for FOC */ + uint8_t resolution; + + /*! Define the BMA4 variant */ + enum bma4_variant variant; + + /*! Used to check mag manual/auto mode status + * int8_t mag_manual_enable; + */ + + /*! Config stream data buffer address will be assigned*/ + const uint8_t *config_file_ptr; + + /*! Read/write length */ + uint16_t read_write_len; + + /*! Feature len */ + uint8_t feature_len; + + /*! Contains asic information */ + struct bma4_asic_data asic_data; + + /*! Contains aux configuration settings */ + struct bma4_aux_config aux_config; + + /*! Structure to maintain a copy of the re-mapped axis */ + struct bma4_axes_remap remap; + + /*! Bus read function pointer */ + bma4_read_fptr_t bus_read; + + /*! Bus write function pointer */ + bma4_write_fptr_t bus_write; + + /*! Delay(in microsecond) function pointer */ + bma4_delay_us_fptr_t delay_us; + + /*! Variable to store the size of config file */ + uint16_t config_size; + + /*! Variable to store the status of performance mode */ + uint8_t perf_mode_status; +}; + +/*! + * @brief This structure holds the information for usage of + * FIFO by the user. + */ +struct bma4_fifo_frame +{ + /*! Data buffer of user defined length is to be mapped here */ + uint8_t *data; + + /*! Number of bytes of FIFO to be read as specified by the user */ + uint16_t length; + + /*! Enabling of the FIFO header to stream in header mode */ + uint8_t fifo_header_enable; + + /*! Streaming of the Accelerometer, Auxiliary + * sensor data or both in FIFO + */ + uint8_t fifo_data_enable; + + /*! Will be equal to length when no more frames are there to parse */ + uint16_t accel_byte_start_idx; + + /*! Will be equal to length when no more frames are there to parse */ + uint16_t mag_byte_start_idx; + + /*! Will be equal to length when no more frames are there to parse */ + uint16_t sc_frame_byte_start_idx; + + /*! Value of FIFO sensor time time */ + uint32_t sensor_time; + + /*! Value of Skipped frame counts */ + uint8_t skipped_frame_count; + + /*! Value of accel dropped frame count */ + uint8_t accel_dropped_frame_count; + + /*! Value of mag dropped frame count */ + uint8_t mag_dropped_frame_count; +}; + +/*! + * @brief Error Status structure + */ +struct bma4_err_reg +{ + /*! Indicates fatal error */ + uint8_t fatal_err; + + /*! Indicates command error */ + uint8_t cmd_err; + + /*! Indicates error code */ + uint8_t err_code; + + /*! Indicates fifo error */ + uint8_t fifo_err; + + /*! Indicates mag error */ + uint8_t aux_err; +}; + +/*! + * @brief Asic Status structure + */ +struct bma4_asic_status +{ + /*! Asic is in sleep/halt state */ + uint8_t sleep; + + /*! Dedicated interrupt is set again before previous interrupt + * was acknowledged + */ + uint8_t irq_ovrn; + + /*! Watchcell event detected (asic stopped) */ + uint8_t wc_event; + + /*! Stream transfer has started and transactions are ongoing */ + uint8_t stream_transfer_active; +}; + +/*! + * @brief Interrupt Pin Configuration structure + */ +struct bma4_int_pin_config +{ + /*! Trigger condition of interrupt pin */ + uint8_t edge_ctrl; + + /*! Level of interrupt pin */ + uint8_t lvl; + + /*! Behaviour of interrupt pin to open drain */ + uint8_t od; + + /*! Output enable for interrupt pin */ + uint8_t output_en; + + /*! Input enable for interrupt pin */ + uint8_t input_en; +}; + +/*! + * @brief Accelerometer configuration structure + */ +struct bma4_accel_config +{ + /*! Output data rate in Hz */ + uint8_t odr; + + /*! Bandwidth parameter, determines filter configuration */ + uint8_t bandwidth; + + /*! Filter performance mode */ + uint8_t perf_mode; + + /*! G-range */ + uint8_t range; +}; + +/*! + * @brief Auxiliary magnetometer configuration structure + */ +struct bma4_aux_mag_config +{ + /*! Poll rate for the sensor attached to the Magnetometer interface */ + uint8_t odr; + + /*! Trigger-readout offset in units of 2.5 ms. + * If set to zero, the offset is maximum, i.e. after readout a trigger + * is issued immediately + */ + uint8_t offset; +}; + +/*! + * @brief ASIC Config structure + */ +struct bma4_asic_config +{ + /*! Enable/Disable ASIC Wake Up */ + uint8_t asic_en; + + /*! Configure stream_transfer/FIFO mode */ + uint8_t fifo_mode_en; + + /*! Mapping of instance RAM1 */ + uint8_t mem_conf_ram1; + + /*! Mapping of instance RAM2 */ + uint8_t mem_conf_ram2; + + /*! Mapping of instance RAM3 */ + uint8_t mem_conf_ram3; +}; + +/*! + * @brief bmm150 or akm09916 + * magnetometer values structure + */ +struct bma4_mag +{ + /*! BMM150 and AKM09916 X raw data */ + int32_t x; + + /*! BMM150 and AKM09916 Y raw data */ + int32_t y; + + /*! BMM150 and AKM09916 Z raw data */ + int32_t z; +}; + +/*! + * @brief bmm150 xyz data structure + */ +struct bma4_mag_xyzr +{ + /*! BMM150 X raw data */ + int16_t x; + + /*! BMM150 Y raw data */ + int16_t y; + + /*! BMM150 Z raw data */ + int16_t z; + + /*! BMM150 R raw data */ + uint16_t r; +}; + +/*! + * @brief Accel xyz data structure + */ +struct bma4_accel +{ + /*! Accel X data */ + int16_t x; + + /*! Accel Y data */ + int16_t y; + + /*! Accel Z data */ + int16_t z; +}; + +/*! + * @brief FIFO mag data structure + */ +struct bma4_mag_fifo_data +{ + /*! The value of mag x LSB data */ + uint8_t mag_x_lsb; + + /*! The value of mag x MSB data */ + uint8_t mag_x_msb; + + /*! The value of mag y LSB data */ + uint8_t mag_y_lsb; + + /*! The value of mag y MSB data */ + uint8_t mag_y_msb; + + /*! The value of mag z LSB data */ + uint8_t mag_z_lsb; + + /*! The value of mag z MSB data */ + uint8_t mag_z_msb; + + /*! The value of mag r for BMM150 Y2 for YAMAHA LSB data */ + uint8_t mag_r_y2_lsb; + + /*! The value of mag r for BMM150 Y2 for YAMAHA MSB data */ + uint8_t mag_r_y2_msb; +}; + +/*! + * @brief Accel self test difference data structure + */ +struct bma4_selftest_delta_limit +{ + /*! Accel X data */ + int32_t x; + + /*! Accel Y data */ + int32_t y; + + /*! Accel Z data */ + int32_t z; +}; + +/*! @name Structure to enable an accel axis for FOC */ +struct bma4_accel_foc_g_value +{ + /* '0' to disable x-axis and '1' to enable x-axis */ + uint8_t x; + + /* '0' to disable y-axis and '1' to enable y-axis */ + uint8_t y; + + /* '0' to disable z-axis and '1' to enable z-axis */ + uint8_t z; + + /* '0' for positive input and '1' for negative input */ + uint8_t sign; +}; + +/*! @name Structure to store temporary accelerometer values */ +struct bma4_foc_temp_value +{ + /*! X data */ + int32_t x; + + /*! Y data */ + int32_t y; + + /*! Z data */ + int32_t z; +}; + +/* Structure to store temporary axes data values */ +struct bma4_temp_axes_val +{ + /* X data */ + int32_t x; + + /* Y data */ + int32_t y; + + /* Z data */ + int32_t z; +}; + +#endif /* End of BMA4_DEFS_H__ */ diff --git a/main/CMakeLists.txt b/main/CMakeLists.txt index 590f4f2..42bfedb 100644 --- a/main/CMakeLists.txt +++ b/main/CMakeLists.txt @@ -19,6 +19,7 @@ idf_component_register( "client_registry.c" "esp_now_comm.c" "esp_now_proto.c" + "bosch456.c" "proto/uart_messages.pb.c" "proto/esp_now_messages.pb.c" "proto/pb_encode.c" @@ -36,7 +37,8 @@ idf_component_register( esp_driver_gpio esp_driver_uart esp_driver_i2c - app_update) + app_update + bma456) target_compile_definitions(${COMPONENT_LIB} PRIVATE "POWERPOD_GIT_HASH=\"${POWERPOD_GIT_HASH}\"") diff --git a/main/bosch456.c b/main/bosch456.c new file mode 100644 index 0000000..da78aa2 --- /dev/null +++ b/main/bosch456.c @@ -0,0 +1,338 @@ +#include "bosch456.h" +#include "bma4.h" +#include "bma456h.h" +#include "bma4_defs.h" +#include "driver/gpio.h" +#include "driver/i2c_master.h" +#include "esp_err.h" +#include "esp_log.h" +#include "freertos/idf_additions.h" +#include "hal/gpio_types.h" +#include +#include +#include +#include + +static const char *TAG = "[BMA456]"; + +static i2c_master_dev_handle_t bma456_dev_handle; +static bool s_bma456_ready; +static struct bma4_dev bma456_struct; + +volatile uint8_t interrupt_status = 0; +uint8_t int_line; +struct bma4_int_pin_config pin_config = {0}; +uint16_t int_status = 0; + +#define BMA4_READ_WRITE_LEN UINT8_C(46) +#define BMA456W_INT_PIN 10 +#define BMA456W_INT_PIN2 9 + +static void interrupt_callback(void *) { + interrupt_status = 1; + // ESP_LOGI("INTERRUPT", "STEP DETECTED"); +} + +/******************************************************************************/ +/*! User interface functions */ + +/*! + * I2C read function map to ESP platform + */ +BMA4_INTF_RET_TYPE bma4_i2c_read(uint8_t reg_addr, uint8_t *reg_data, + uint32_t len, void *intf_ptr) { + if (bma456_dev_handle == NULL) { + return BMA4_E_COM_FAIL; + } + esp_err_t err = i2c_master_transmit_receive(bma456_dev_handle, ®_addr, 1, + reg_data, len, -1); + return (err == ESP_OK) ? BMA4_OK : BMA4_E_COM_FAIL; + // return BMA4_OK; +} + +/*! + * I2C write function map to ESP platform + */ +BMA4_INTF_RET_TYPE bma4_i2c_write(uint8_t reg_addr, const uint8_t *reg_data, + uint32_t len, void *intf_ptr) { + if (bma456_dev_handle == NULL) { + return BMA4_E_COM_FAIL; + } + uint8_t *buffer = malloc(len + 1); + if (!buffer) + return BMA4_E_NULL_PTR; + + buffer[0] = reg_addr; + + ESP_LOGI("I2CWrite", "Message Length: %d", len); + + memcpy(&buffer[1], reg_data, len); + + esp_err_t err = i2c_master_transmit(bma456_dev_handle, buffer, len + 1, -1); + free(buffer); + + return (err == ESP_OK) ? BMA4_OK : BMA4_E_COM_FAIL; + // return BMA4_OK; +} + +/*! + * Delay function map to ESP platform + */ +void bma4_delay_us(uint32_t period, void *intf_ptr) { + uint32_t wait_ms = period / 1000; + uint32_t wait_us = period % 1000; + if (wait_ms) { + vTaskDelay(pdMS_TO_TICKS(wait_ms)); + } + ets_delay_us(wait_us); +} + +/*! + * @brief Prints the execution status of the APIs. + */ +void bma4_error_codes_print_result(const char api_name[], int8_t rslt) { + if (rslt == BMA4_OK) { + return; + } + + ESP_LOGI("BMA4_I2C", "%s\t", api_name); + + switch (rslt) { + case BMA4_E_NULL_PTR: + ESP_LOGI("BMA4_I2C", "Error [%d] : Null pointer\r\n", rslt); + break; + case BMA4_E_COM_FAIL: + ESP_LOGI("BMA4_I2C", "Error [%d] : Communication failure\r\n", rslt); + break; + case BMA4_E_CONFIG_STREAM_ERROR: + ESP_LOGI("BMA4_I2C", "Error [%d] : Invalid configuration stream\r\n", rslt); + break; + case BMA4_E_SELF_TEST_FAIL: + ESP_LOGI("BMA4_I2C", "Error [%d] : Self test failed\r\n", rslt); + break; + case BMA4_E_INVALID_SENSOR: + ESP_LOGI("BMA4_I2C", "Error [%d] : Device not found\r\n", rslt); + break; + case BMA4_E_OUT_OF_RANGE: + ESP_LOGI("BMA4_I2C", "Error [%d] : Out of Range\r\n", rslt); + break; + case BMA4_E_AVG_MODE_INVALID_CONF: + ESP_LOGI("BMA4_I2C", "Error [%d] : Invalid bandwidth/ODR combination\r\n", + rslt); + break; + default: + ESP_LOGI("BMA4_I2C", "Error [%d] : Unknown error code\r\n", rslt); + break; + } +} + +static esp_err_t check_bma4(const char *api_name, int8_t rslt) { + if (rslt == BMA4_OK) { + return ESP_OK; + } + bma4_error_codes_print_result(api_name, rslt); + return ESP_FAIL; +} + +static void remove_bma456_device(void) { + if (bma456_dev_handle != NULL) { + i2c_master_bus_rm_device(bma456_dev_handle); + bma456_dev_handle = NULL; + } + s_bma456_ready = false; +} + +void read_sensor_task(void *params) { + int8_t ret; + struct bma4_accel sens_data = {0}; + + if (!s_bma456_ready) { + vTaskDelete(NULL); + return; + } + + while (1) { + ret = bma4_read_accel_xyz(&sens_data, &bma456_struct); + bma4_error_codes_print_result("bma4_read_accel_xyz", ret); + + ESP_LOGI("ACC", "X: %d, Y: %d, Z: %d", sens_data.x, sens_data.y, + sens_data.z); + + if (interrupt_status) { + ESP_LOGI("INTERRUPT", "Da war der Interrupt resetting"); + interrupt_status = 0; + ret = bma456h_read_int_status(&int_status, &bma456_struct); + bma4_error_codes_print_result("bma456w_step_counter_output status", ret); + + int8_t rslt; + struct bma456h_out_state tap_out = {0}; + + rslt = bma456h_output_state(&tap_out, &bma456_struct); + + if (BMA4_OK == rslt) { + /* Enters only if the obtained interrupt is single-tap */ + if (tap_out.single_tap) { + ESP_LOGI("INTERRUPT", "Single Tap interrupt occurred\n"); + } + /* Enters only if the obtained interrupt is double-tap */ + else if (tap_out.double_tap) { + ESP_LOGI("INTERRUPT", "Double Tap interrupt occurred\n"); + } + /* Enters only if the obtained interrupt is triple-tap */ + else if (tap_out.triple_tap) { + ESP_LOGI("INTERRUPT", "Triple Tap interrupt occurred\n"); + } + } + } + + // ESP_LOGI("i2c", "X:%d, Y%d, Z%d", sens_data.x, sens_data.y, sens_data.z); + vTaskDelay(pdMS_TO_TICKS(100)); + } +} + +esp_err_t init_bma456(i2c_master_bus_handle_t bus_handle) { + int8_t ret; + esp_err_t err; + + s_bma456_ready = false; + bma456_dev_handle = NULL; + + if (bus_handle == NULL) { + return ESP_ERR_INVALID_ARG; + } + + i2c_device_config_t dev_cfg_bma456 = { + .dev_addr_length = I2C_ADDR_BIT_LEN_7, + .device_address = BMA456_ADDRESS, + .scl_speed_hz = 100000, + }; + + err = i2c_master_bus_add_device(bus_handle, &dev_cfg_bma456, &bma456_dev_handle); + if (err != ESP_OK) { + return err; + } + + bma456_struct.intf = BMA4_I2C_INTF; + bma456_struct.bus_read = bma4_i2c_read; + bma456_struct.bus_write = bma4_i2c_write; + bma456_struct.delay_us = bma4_delay_us; + bma456_struct.read_write_len = BMA4_READ_WRITE_LEN; + bma456_struct.intf_ptr = &bma456_dev_handle; + bma456_struct.chip_id = 0; + + ret = bma456h_init(&bma456_struct); + if (check_bma4("bma456h_init", ret) != ESP_OK) { + remove_bma456_device(); + return ESP_ERR_NOT_FOUND; + } + + ESP_LOGI(TAG, "chip id 0x%02x", bma456_struct.chip_id); + + ret = bma4_soft_reset(&bma456_struct); + if (check_bma4("bma4_soft_reset", ret) != ESP_OK) { + goto fail; + } + vTaskDelay(pdMS_TO_TICKS(20)); + + ret = bma4_set_advance_power_save(BMA4_DISABLE, &bma456_struct); + if (check_bma4("bma4_set_advance_power_save", ret) != ESP_OK) { + goto fail; + } + vTaskDelay(pdMS_TO_TICKS(10)); + + ret = bma456h_write_config_file(&bma456_struct); + if (check_bma4("bma456h_write_config_file", ret) != ESP_OK) { + goto fail; + } + + struct bma4_accel_config accel_config; + bma4_get_accel_config(&accel_config, &bma456_struct); + accel_config.range = BMA4_ACCEL_RANGE_2G; + ret = bma4_set_accel_config(&accel_config, &bma456_struct); + if (check_bma4("bma4_set_accel_config", ret) != ESP_OK) { + goto fail; + } + + ret = bma4_set_accel_enable(BMA4_ENABLE, &bma456_struct); + if (check_bma4("bma4_set_accel_enable", ret) != ESP_OK) { + goto fail; + } + + struct bma456h_multitap_settings tap_settings = {0}; + ret = bma456h_tap_get_parameter(&tap_settings, &bma456_struct); + if (check_bma4("bma456h_tap_get_parameter", ret) != ESP_OK) { + goto fail; + } + tap_settings.tap_sens_thres = 0; + ret = bma456h_tap_set_parameter(&tap_settings, &bma456_struct); + if (check_bma4("bma456h_tap_set_parameter", ret) != ESP_OK) { + goto fail; + } + + ret = bma456h_feature_enable( + (BMA456H_SINGLE_TAP_EN | BMA456H_DOUBLE_TAP_EN | BMA456H_TRIPLE_TAP_EN), + BMA4_ENABLE, &bma456_struct); + if (check_bma4("bma456h_feature_enable", ret) != ESP_OK) { + goto fail; + } + + ret = bma456h_step_counter_set_watermark(1, &bma456_struct); + if (check_bma4("bma456h_step_counter_set_watermark", ret) != ESP_OK) { + goto fail; + } + + int_line = BMA4_INTR2_MAP; + + ret = bma4_get_int_pin_config(&pin_config, int_line, &bma456_struct); + if (check_bma4("bma4_get_int_pin_config", ret) != ESP_OK) { + goto fail; + } + + ret = bma456h_map_interrupt(int_line, BMA456H_TAP_OUT_INT, BMA4_ENABLE, + &bma456_struct); + if (check_bma4("bma456h_map_interrupt", ret) != ESP_OK) { + goto fail; + } + + pin_config.edge_ctrl = BMA4_EDGE_TRIGGER; + pin_config.output_en = BMA4_OUTPUT_ENABLE; + pin_config.lvl = BMA4_ACTIVE_HIGH; + pin_config.od = BMA4_PUSH_PULL; + pin_config.input_en = BMA4_INPUT_DISABLE; + + ret = bma4_set_int_pin_config(&pin_config, int_line, &bma456_struct); + if (check_bma4("bma4_set_int_pin_config", ret) != ESP_OK) { + goto fail; + } + + gpio_reset_pin(BMA456W_INT_PIN); + gpio_set_direction(BMA456W_INT_PIN, GPIO_MODE_INPUT); + gpio_set_pull_mode(BMA456W_INT_PIN, GPIO_PULLDOWN_ENABLE); + gpio_set_intr_type(BMA456W_INT_PIN, GPIO_INTR_POSEDGE); + gpio_intr_enable(BMA456W_INT_PIN); + + err = gpio_install_isr_service(0); + if (err != ESP_OK && err != ESP_ERR_INVALID_STATE) { + goto fail; + } + + err = gpio_isr_handler_add(BMA456W_INT_PIN, interrupt_callback, + (void *)BMA456W_INT_PIN); + if (err != ESP_OK) { + goto fail; + } + + if (xTaskCreate(read_sensor_task, "READ_SENSOR", 4096, NULL, 1, NULL) != + pdPASS) { + gpio_isr_handler_remove(BMA456W_INT_PIN); + goto fail; + } + + s_bma456_ready = true; + ESP_LOGI(TAG, "initialized"); + return ESP_OK; + +fail: + remove_bma456_device(); + return ESP_FAIL; +} diff --git a/main/bosch456.h b/main/bosch456.h new file mode 100644 index 0000000..17f6a4b --- /dev/null +++ b/main/bosch456.h @@ -0,0 +1,15 @@ +#ifndef BOSCH456_H +#define BOSCH456_H + +#include "driver/i2c_types.h" +#include "esp_err.h" + +#define TOUCH_1 9 +#define TOUCH_2 8 + +#define BMA456_ADDRESS 0x18 + +/** Initialize BMA456 on the shared I2C bus. Returns ESP_OK or logs and skips sensor use. */ +esp_err_t init_bma456(i2c_master_bus_handle_t bus_handle); + +#endif diff --git a/main/powerpod.c b/main/powerpod.c index 3886839..cdcdede 100644 --- a/main/powerpod.c +++ b/main/powerpod.c @@ -13,6 +13,7 @@ #include "esp_ota_ops.h" #include "freertos/FreeRTOS.h" #include "freertos/idf_additions.h" +#include "bosch456.h" #include "led_ring.h" #include "uart.h" #include @@ -76,7 +77,8 @@ void app_main(void) { err = i2c_new_master_bus(&i2c_mst_config, &bus_handle); if (err != ESP_OK) { - ESP_LOGI(TAG, "I2C Master Could not Init Bus"); + ESP_LOGI(TAG, "I2C master bus init failed: %s", esp_err_to_name(err)); + bus_handle = NULL; } i2c_device_config_t dev_cfg = { @@ -110,6 +112,13 @@ void app_main(void) { 1; // map network to 0-8, 0 is not a valid network } + if (bus_handle != NULL) { + esp_err_t bma_err = init_bma456(bus_handle); + if (bma_err != ESP_OK) { + ESP_LOGI(TAG, "BMA456 init skipped: %s", esp_err_to_name(bma_err)); + } + } + const esp_partition_t *running = esp_ota_get_running_partition(); app_config.master = (master != 0);