diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..bf1bd66 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "BMA423-Sensor-API"] + path = BMA423-Sensor-API + url = https://github.com/BoschSensortec/BMA423-Sensor-API diff --git a/BMA421-Sensor-API/bma421.c b/BMA421-Sensor-API/bma421.c new file mode 100644 index 0000000..9d131b6 --- /dev/null +++ b/BMA421-Sensor-API/bma421.c @@ -0,0 +1,1362 @@ +/** + * Copyright (c) 2020 Bosch Sensortec GmbH. All rights reserved. + * + * BSD-3-Clause + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @file bma421.c + * @date 2020-05-08 + * @version V2.14.13 + * + */ + +/*! \file bma421.c + * \brief Sensor Driver for BMA421 sensor + */ + +#include "bma421.h" + +#include "bma421_config.h" + +/***************************************************************************/ + +/*! 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 bma421_stepcounter_settings *setting, + uint8_t index, + uint8_t *feature_config); + +/*! + * @brief This API copy the settings of step counter into the + * structure of bma421_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 bma421_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 bma421_init(struct bma4_dev *dev) +{ + int8_t rslt; + + rslt = bma4_init(dev); + if (rslt == BMA4_OK) + { + if (dev->chip_id == BMA421_CHIP_ID) + { + /* Resolution of BMA421 sensor is 12 bit */ + dev->resolution = 12; + + dev->feature_len = BMA421_FEATURE_SIZE; + + dev->config_size = sizeof(bma421_config_file); + } + 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 bma421_write_config_file(struct bma4_dev *dev) +{ + int8_t rslt = BMA4_OK; + + if (dev != NULL) + { + if (dev->chip_id == BMA421_CHIP_ID) + { + /* Configuration stream read/write length boundary + * check + */ + if ((dev->read_write_len >= BMA421_RD_WR_MIN_LEN) && (dev->read_write_len <= BMA421_FEATURE_SIZE)) + { + /* 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 = bma421_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 bma421_get_config_id(uint16_t *config_id, struct bma4_dev *dev) +{ + uint8_t feature_config[BMA421_FEATURE_SIZE] = { 0 }; + uint8_t index = BMA421_CONFIG_ID_OFFSET; + int8_t rslt = BMA4_OK; + uint16_t config_id_lsb = 0; + uint16_t config_id_msb = 0; + + if (dev != NULL) + { + if (dev->chip_id == BMA421_CHIP_ID) + { + rslt = bma4_read_regs(BMA4_FEATURE_CONFIG_ADDR, feature_config, BMA421_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 bma421_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 == BMA421_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 bma421 interrupt status from the sensor. + */ +int8_t bma421_read_int_status(uint16_t *int_status, struct bma4_dev *dev) +{ + int8_t rslt = BMA4_OK; + + if (dev != NULL) + { + if (dev->chip_id == BMA421_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 bma421_feature_enable(uint8_t feature, uint8_t enable, struct bma4_dev *dev) +{ + uint8_t feature_config[BMA421_FEATURE_SIZE] = { 0 }; + int8_t rslt = BMA4_OK; + uint8_t len = BMA421_FEATURE_SIZE; + + if (dev != NULL) + { + if (dev->chip_id == BMA421_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 bma421_set_remap_axes(const struct bma421_axes_remap *remap_data, struct bma4_dev *dev) +{ + uint8_t feature_config[BMA421_FEATURE_SIZE] = { 0 }; + uint8_t index = BMA421_AXES_REMAP_OFFSET; + int8_t rslt = BMA4_OK; + uint8_t x_axis = 0; + uint8_t x_axis_sign = 0; + uint8_t y_axis = 0; + uint8_t y_axis_sign = 0; + uint8_t z_axis = 0; + + if (dev != NULL) + { + if (dev->chip_id == BMA421_CHIP_ID) + { + rslt = bma4_read_regs(BMA4_FEATURE_CONFIG_ADDR, feature_config, BMA421_FEATURE_SIZE, dev); + if (rslt == BMA4_OK) + { + x_axis = remap_data->x_axis & BMA421_X_AXIS_MASK; + x_axis_sign = (remap_data->x_axis_sign << 2) & BMA421_X_AXIS_SIGN_MASK; + y_axis = (remap_data->y_axis << 3) & BMA421_Y_AXIS_MASK; + y_axis_sign = (remap_data->y_axis_sign << 5) & BMA421_Y_AXIS_SIGN_MASK; + z_axis = (remap_data->z_axis << 6) & BMA421_Z_AXIS_MASK; + feature_config[index] = x_axis | x_axis_sign | y_axis | y_axis_sign | z_axis; + feature_config[index + 1] = remap_data->z_axis_sign & BMA421_Z_AXIS_SIGN_MASK; + rslt = bma4_write_regs(BMA4_FEATURE_CONFIG_ADDR, feature_config, BMA421_FEATURE_SIZE, dev); + } + } + else + { + rslt = BMA4_E_INVALID_SENSOR; + } + } + 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 bma421_get_remap_axes(struct bma421_axes_remap *remap_data, struct bma4_dev *dev) +{ + uint8_t feature_config[BMA421_FEATURE_SIZE] = { 0 }; + uint8_t index = BMA421_AXES_REMAP_OFFSET; + int8_t rslt = BMA4_OK; + + if (dev != NULL) + { + if (dev->chip_id == BMA421_CHIP_ID) + { + rslt = bma4_read_regs(BMA4_FEATURE_CONFIG_ADDR, feature_config, BMA421_FEATURE_SIZE, dev); + if (rslt == BMA4_OK) + { + remap_data->x_axis = feature_config[index] & BMA421_X_AXIS_MASK; + remap_data->x_axis_sign = (feature_config[index] & BMA421_X_AXIS_SIGN_MASK) >> 2; + remap_data->y_axis = (feature_config[index] & BMA421_Y_AXIS_MASK) >> 3; + remap_data->y_axis_sign = (feature_config[index] & BMA421_Y_AXIS_SIGN_MASK) >> 5; + remap_data->z_axis = (feature_config[index] & BMA421_Z_AXIS_MASK) >> 6; + remap_data->z_axis_sign = (feature_config[index + 1] & BMA421_Z_AXIS_SIGN_MASK); + } + } + else + { + rslt = BMA4_E_INVALID_SENSOR; + } + } + 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 bma421_set_any_mot_config(const struct bma421_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[BMA421_FEATURE_SIZE] = { 0 }; + + /* Update index to configure any-motion axes */ + uint8_t index = BMA421_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, BMA421_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, BMA421_ANY_NO_MOT_DUR, any_mot->duration); + + /* Set the axes in the same word */ + lsb_msb = BMA4_SET_BITSLICE(lsb_msb, BMA421_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, BMA421_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 bma421_get_any_mot_config(struct bma421_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[BMA421_FEATURE_SIZE] = { 0 }; + + /* Update index to configure any-motion axes */ + uint8_t index = BMA421_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, BMA421_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 & BMA421_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 & BMA421_ANY_NO_MOT_DUR_MSK; + + /* Extract axes enable value */ + any_mot->axes_en = (uint8_t)((lsb_msb & BMA421_ANY_NO_MOT_AXIS_EN_MSK) >> BMA421_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 bma421_set_no_mot_config(const struct bma421_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[BMA421_FEATURE_SIZE] = { 0 }; + + /* Update index to configure no-motion axes */ + uint8_t index = BMA421_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, BMA421_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, BMA421_ANY_NO_MOT_DUR, no_mot->duration); + + /* Set the axes in the same word */ + lsb_msb = BMA4_SET_BITSLICE(lsb_msb, BMA421_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, BMA421_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 bma421_get_no_mot_config(struct bma421_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[BMA421_FEATURE_SIZE] = { 0 }; + + /* Update index to configure no-motion axes */ + uint8_t index = BMA421_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, BMA421_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 & BMA421_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 & BMA421_ANY_NO_MOT_DUR_MSK; + + /* Extract axes enable value */ + no_mot->axes_en = (uint8_t)((lsb_msb & BMA421_ANY_NO_MOT_AXIS_EN_MSK) >> BMA421_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 bma421_step_detector_enable(uint8_t enable, struct bma4_dev *dev) +{ + uint8_t feature_config[BMA421_FEATURE_SIZE] = { 0 }; + int8_t rslt = BMA4_OK; + + /* Step detector enable bit position is 1 byte ahead of the base address */ + uint8_t index = BMA421_STEP_CNTR_OFFSET + 1; + + if (dev != NULL) + { + if (dev->chip_id == BMA421_CHIP_ID) + { + rslt = bma4_read_regs(BMA4_FEATURE_CONFIG_ADDR, feature_config, BMA421_FEATURE_SIZE, dev); + if (rslt == BMA4_OK) + { + feature_config[index] = BMA4_SET_BITSLICE(feature_config[index], BMA421_STEP_DETECTOR_EN, enable); + rslt = bma4_write_regs(BMA4_FEATURE_CONFIG_ADDR, feature_config, BMA421_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 bma421_step_counter_set_watermark(uint16_t step_counter_wm, struct bma4_dev *dev) +{ + uint8_t feature_config[BMA421_FEATURE_SIZE] = { 0 }; + uint8_t index = BMA421_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 == BMA421_CHIP_ID) + { + rslt = bma4_read_regs(BMA4_FEATURE_CONFIG_ADDR, feature_config, BMA421_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 watermark bits in the complete + * 16 bits of data + */ + data = BMA4_SET_BITS_POS_0(data, BMA421_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 stepcounter watermark settings + * in the sensor + */ + rslt = bma4_write_regs(BMA4_FEATURE_CONFIG_ADDR, feature_config, BMA421_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 bma421_step_counter_get_watermark(uint16_t *step_counter_wm, struct bma4_dev *dev) +{ + uint8_t feature_config[BMA421_FEATURE_SIZE] = { 0 }; + uint8_t index = BMA421_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 == BMA421_CHIP_ID) + { + rslt = bma4_read_regs(BMA4_FEATURE_CONFIG_ADDR, feature_config, BMA421_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, BMA421_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 bma421_reset_step_counter(struct bma4_dev *dev) +{ + uint8_t feature_config[BMA421_FEATURE_SIZE] = { 0 }; + + /* Reset bit is 1 byte ahead of base address */ + uint8_t index = BMA421_STEP_CNTR_OFFSET + 1; + int8_t rslt = BMA4_OK; + + if (dev != NULL) + { + if (dev->chip_id == BMA421_CHIP_ID) + { + rslt = bma4_read_regs(BMA4_FEATURE_CONFIG_ADDR, feature_config, BMA421_FEATURE_SIZE, dev); + if (rslt == BMA4_OK) + { + feature_config[index] = BMA4_SET_BITSLICE(feature_config[index], BMA421_STEP_CNTR_RST, 1); + rslt = bma4_write_regs(BMA4_FEATURE_CONFIG_ADDR, feature_config, BMA421_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 bma421_step_counter_output(uint32_t *step_count, struct bma4_dev *dev) +{ + uint8_t data[BMA421_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 (dev != NULL) + { + if (dev->chip_id == BMA421_CHIP_ID) + { + /* Reads the step counter output data from the + * gpio register + */ + rslt = bma4_read_regs(BMA4_STEP_CNT_OUT_0_ADDR, data, BMA421_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_INVALID_SENSOR; + } + } + else + { + rslt = BMA4_E_NULL_PTR; + } + + return rslt; +} + +/*! + * @brief This API gets the output for activity feature. + */ +int8_t bma421_activity_output(uint8_t *activity, struct bma4_dev *dev) +{ + uint8_t data = 0; + int8_t rslt = BMA4_OK; + + if (dev != NULL) + { + if (dev->chip_id == BMA421_CHIP_ID) + { + /* 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_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 bma421_stepcounter_get_parameter(struct bma421_stepcounter_settings *setting, struct bma4_dev *dev) +{ + uint8_t feature_config[BMA421_FEATURE_SIZE] = { 0 }; + uint16_t *data_p = (uint16_t *)(void *)feature_config; + int8_t rslt = BMA4_OK; + + if (dev != NULL) + { + if (dev->chip_id == BMA421_CHIP_ID) + { + rslt = bma4_read_regs(BMA4_FEATURE_CONFIG_ADDR, feature_config, BMA421_FEATURE_SIZE, dev); + if (rslt == BMA4_OK) + { + /* To convert 8bit to 16 bit address */ + data_p = data_p + BMA421_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 bma421_stepcounter_set_parameter(const struct bma421_stepcounter_settings *setting, struct bma4_dev *dev) +{ + uint8_t feature_config[BMA421_FEATURE_SIZE] = { 0 }; + uint8_t index = BMA421_STEP_CNTR_PARAM_OFFSET; + int8_t rslt = BMA4_OK; + + if (dev != NULL) + { + if (dev->chip_id == BMA421_CHIP_ID) + { + rslt = bma4_read_regs(BMA4_FEATURE_CONFIG_ADDR, feature_config, BMA421_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, BMA421_FEATURE_SIZE, dev); + } + } + else + { + rslt = BMA4_E_INVALID_SENSOR; + } + } + else + { + rslt = BMA4_E_NULL_PTR; + } + + return rslt; +} + +/*! + * @brief This API sets the sensitivity of single tap feature in the sensor. + */ +int8_t bma421_single_tap_set_sensitivity(uint8_t sensitivity, struct bma4_dev *dev) +{ + uint8_t feature_config[BMA421_FEATURE_SIZE] = { 0 }; + uint8_t index = BMA421_SINGLE_TAP_OFFSET; + int8_t rslt = BMA4_OK; + + if (dev != NULL) + { + if (dev->chip_id == BMA421_CHIP_ID) + { + rslt = bma4_read_regs(BMA4_FEATURE_CONFIG_ADDR, feature_config, BMA421_FEATURE_SIZE, dev); + if (rslt == BMA4_OK) + { + feature_config[index] = BMA4_SET_BITSLICE(feature_config[index], BMA421_TAP_SENS, sensitivity); + + /* Writes sensitivity settings in the sensor */ + rslt = bma4_write_regs(BMA4_FEATURE_CONFIG_ADDR, feature_config, BMA421_FEATURE_SIZE, dev); + } + } + else + { + rslt = BMA4_E_INVALID_SENSOR; + } + } + else + { + rslt = BMA4_E_NULL_PTR; + } + + return rslt; +} + +/*! + * @brief This API sets the sensitivity of double tap feature in the sensor. + */ +int8_t bma421_double_tap_set_sensitivity(uint8_t sensitivity, struct bma4_dev *dev) +{ + uint8_t feature_config[BMA421_FEATURE_SIZE] = { 0 }; + uint8_t index = BMA421_DOUBLE_TAP_OFFSET; + int8_t rslt = BMA4_OK; + + if (dev != NULL) + { + if (dev->chip_id == BMA421_CHIP_ID) + { + rslt = bma4_read_regs(BMA4_FEATURE_CONFIG_ADDR, feature_config, BMA421_FEATURE_SIZE, dev); + if (rslt == BMA4_OK) + { + feature_config[index] = BMA4_SET_BITSLICE(feature_config[index], BMA421_TAP_SENS, sensitivity); + + /* Writes sensitivity settings in the sensor */ + rslt = bma4_write_regs(BMA4_FEATURE_CONFIG_ADDR, feature_config, BMA421_FEATURE_SIZE, dev); + } + } + else + { + rslt = BMA4_E_INVALID_SENSOR; + } + } + else + { + rslt = BMA4_E_NULL_PTR; + } + + return rslt; +} + +/*! + * @brief This API gets the sensitivity of single tap feature in the sensor + */ +int8_t bma421_single_tap_get_sensitivity(uint8_t *sensitivity, struct bma4_dev *dev) +{ + uint8_t feature_config[BMA421_FEATURE_SIZE] = { 0 }; + uint8_t index = BMA421_SINGLE_TAP_OFFSET; + int8_t rslt = BMA4_OK; + + if (dev != NULL) + { + if (dev->chip_id == BMA421_CHIP_ID) + { + rslt = bma4_read_regs(BMA4_FEATURE_CONFIG_ADDR, feature_config, BMA421_FEATURE_SIZE, dev); + if (rslt == BMA4_OK) + { + /* Extracts sensitivity data */ + *sensitivity = BMA4_GET_BITSLICE(feature_config[index], BMA421_TAP_SENS); + } + } + else + { + rslt = BMA4_E_INVALID_SENSOR; + } + } + else + { + rslt = BMA4_E_NULL_PTR; + } + + return rslt; +} + +/*! + * @brief This API gets the sensitivity of double tap feature in the sensor + */ +int8_t bma421_double_tap_get_sensitivity(uint8_t *sensitivity, struct bma4_dev *dev) +{ + uint8_t feature_config[BMA421_FEATURE_SIZE] = { 0 }; + uint8_t index = BMA421_DOUBLE_TAP_OFFSET; + int8_t rslt = BMA4_OK; + + if (dev != NULL) + { + if (dev->chip_id == BMA421_CHIP_ID) + { + rslt = bma4_read_regs(BMA4_FEATURE_CONFIG_ADDR, feature_config, BMA421_FEATURE_SIZE, dev); + if (rslt == BMA4_OK) + { + /* Extracts sensitivity data */ + *sensitivity = BMA4_GET_BITSLICE(feature_config[index], BMA421_TAP_SENS); + } + } + 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(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 & BMA421_STEP_CNTR) > 0) + { + index = BMA421_STEP_CNTR_OFFSET + 1; + feature_config[index] = feature_config[index] | BMA421_STEP_CNTR_EN_MSK; + } + + /* Enable step activity */ + if ((feature & BMA421_STEP_ACT) > 0) + { + index = BMA421_STEP_CNTR_OFFSET + 1; + feature_config[index] = feature_config[index] | BMA421_STEP_ACT_EN_MSK; + } + + /* Enable wrist wear wakeup */ + if ((feature & BMA421_WRIST_WEAR) > 0) + { + index = BMA421_WRIST_WEAR_OFFSET; + feature_config[index] = feature_config[index] | BMA421_WRIST_WEAR_EN_MSK; + } + + /* Enable single - tap */ + if ((feature & BMA421_SINGLE_TAP) > 0) + { + index = BMA421_SINGLE_TAP_OFFSET; + feature_config[index] = feature_config[index] | BMA421_SINGLE_TAP_EN_MSK; + } + + /* Enable double- tap */ + if ((feature & BMA421_DOUBLE_TAP) > 0) + { + index = BMA421_DOUBLE_TAP_OFFSET; + feature_config[index] = feature_config[index] | BMA421_DOUBLE_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; + + /* Disable step counter */ + if ((feature & BMA421_STEP_CNTR) > 0) + { + index = BMA421_STEP_CNTR_OFFSET + 1; + feature_config[index] = feature_config[index] & (~BMA421_STEP_CNTR_EN_MSK); + } + + /* Disable step activity */ + if ((feature & BMA421_STEP_ACT) > 0) + { + index = BMA421_STEP_CNTR_OFFSET + 1; + feature_config[index] = feature_config[index] & (~BMA421_STEP_ACT_EN_MSK); + } + + /* Disable wrist wear wakeup */ + if ((feature & BMA421_WRIST_WEAR) > 0) + { + index = BMA421_WRIST_WEAR_OFFSET; + feature_config[index] = feature_config[index] & (~BMA421_WRIST_WEAR_EN_MSK); + } + + /* Disable single-tap */ + if ((feature & BMA421_SINGLE_TAP) > 0) + { + index = BMA421_SINGLE_TAP_OFFSET; + feature_config[index] = feature_config[index] & (~BMA421_SINGLE_TAP_EN_MSK); + } + + /* Disable double-tap */ + if ((feature & BMA421_DOUBLE_TAP) > 0) + { + index = BMA421_DOUBLE_TAP_OFFSET; + feature_config[index] = feature_config[index] & (~BMA421_DOUBLE_TAP_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 bma421_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 + * bma421_stepcounter_settings, which is read from sensor. + */ +static void extract_stepcounter_parameter(struct bma421_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 bma421_get_version_config(uint16_t *config_major, uint16_t *config_minor, struct bma4_dev *dev) +{ + /* Initialize configuration file */ + uint8_t feature_config[BMA421_FEATURE_SIZE] = { 0 }; + + /* Update index to config file version */ + uint8_t index = BMA421_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 ((dev != NULL) && (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, BMA421_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, BMA421_CONFIG_MAJOR); + *config_minor = BMA4_GET_BITS_POS_0(lsb, BMA421_CONFIG_MINOR); + } + } + } + else + { + rslt = BMA4_E_NULL_PTR; + } + + return rslt; +} + +/*! @endcond */ diff --git a/BMA421-Sensor-API/bma421.h b/BMA421-Sensor-API/bma421.h new file mode 100644 index 0000000..b4c51cf --- /dev/null +++ b/BMA421-Sensor-API/bma421.h @@ -0,0 +1,1115 @@ +/** + * Copyright (c) 2020 Bosch Sensortec GmbH. All rights reserved. + * + * BSD-3-Clause + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @file bma421.h + * @date 2020-05-08 + * @version V2.14.13 + * + */ + +/** + * \ingroup bma4xy + * \defgroup bma421 BMA421 + * @brief Sensor driver for BMA421 sensor + */ + +#ifndef BMA421_H +#define BMA421_H + +#ifdef __cplusplus +extern "C" { +#endif +#include "bma4.h" + +/**\name Chip ID of BMA421 sensor */ +#define BMA421_CHIP_ID UINT8_C(0x11) + +/**\ Configuration ID start position of BMA421 sensor */ +#define BMA421_CONFIG_ID_START_ADDR UINT8_C(66) + +/**\name Sensor feature size */ +#define BMA421_FEATURE_SIZE UINT8_C(70) +#define BMA421_ANY_MOT_LEN UINT8_C(4) + +/**\name Feature offset address */ +#define BMA421_ANY_MOT_OFFSET UINT8_C(0x00) +#define BMA421_NO_MOT_OFFSET UINT8_C(0x04) +#define BMA421_STEP_CNTR_PARAM_OFFSET UINT8_C(0x08) +#define BMA421_STEP_CNTR_OFFSET UINT8_C(0x3A) +#define BMA421_SINGLE_TAP_OFFSET UINT8_C(0x3C) +#define BMA421_DOUBLE_TAP_OFFSET UINT8_C(0x3E) +#define BMA421_WRIST_WEAR_OFFSET UINT8_C(0x40) +#define BMA421_CONFIG_ID_OFFSET UINT8_C(0x42) +#define BMA421_AXES_REMAP_OFFSET UINT8_C(0x44) + +/**\name Read/Write Lengths */ +#define BMA421_RD_WR_MIN_LEN UINT8_C(2) +#define BMA421_NO_MOT_RD_WR_LEN (BMA421_ANY_MOT_LEN + BMA421_NO_MOT_OFFSET) + +/*! @name Mask definitions for major and minor config */ +#define BMA421_CONFIG_MAJOR_MSK UINT16_C(0X3C0) +#define BMA421_CONFIG_MINOR_MSK UINT8_C(0X1F) + +/*! @name Bit position for major config */ +#define BMA421_CONFIG_MAJOR_POS UINT8_C(0X06) + +/**************************************************************/ +/**\name Re-map Axes */ +/**************************************************************/ +#define BMA421_X_AXIS_MASK UINT8_C(0x03) +#define BMA421_X_AXIS_SIGN_MASK UINT8_C(0x04) +#define BMA421_Y_AXIS_MASK UINT8_C(0x18) +#define BMA421_Y_AXIS_SIGN_MASK UINT8_C(0x20) +#define BMA421_Z_AXIS_MASK UINT8_C(0xC0) +#define BMA421_Z_AXIS_SIGN_MASK UINT8_C(0x01) + +/**************************************************************/ +/**\name Step Counter/Detector/Activity */ +/**************************************************************/ +/**\name Step counter/activity enable macros */ +#define BMA421_STEP_CNTR_EN_MSK UINT8_C(0x10) +#define BMA421_STEP_ACT_EN_MSK UINT8_C(0x20) + +/**\name Step counter water-mark macros */ +#define BMA421_STEP_CNTR_WM_MSK UINT16_C(0x03FF) + +/**\name Step counter reset macros */ +#define BMA421_STEP_CNTR_RST_POS UINT8_C(2) +#define BMA421_STEP_CNTR_RST_MSK UINT8_C(0x04) + +/**\name Step detector enable macros */ +#define BMA421_STEP_DETECTOR_EN_POS UINT8_C(3) +#define BMA421_STEP_DETECTOR_EN_MSK UINT8_C(0x08) + +/**\name Wrist-wear enable macros */ +#define BMA421_WRIST_WEAR_EN_MSK UINT8_C(0x01) + +/**\name Step count output length*/ +#define BMA421_STEP_CNTR_DATA_SIZE UINT16_C(4) + +/**\name single tap enable macros */ +#define BMA421_SINGLE_TAP_EN_MSK UINT8_C(0x01) + +/**\name double tap enable macros */ +#define BMA421_DOUBLE_TAP_EN_MSK UINT8_C(0x01) + +/**\name tap sensitivity macros */ +#define BMA421_TAP_SENS_POS UINT8_C(1) +#define BMA421_TAP_SENS_MSK UINT8_C(0x0E) + +/**\name Tap selection macro */ +#define BMA421_TAP_SEL_POS UINT8_C(4) +#define BMA421_TAP_SEL_MSK UINT8_C(0x10) + +/**************************************************************/ +/**\name Any/no Motion */ +/**************************************************************/ +/**\name Any/No motion threshold macros */ +#define BMA421_ANY_NO_MOT_THRES_MSK UINT16_C(0x07FF) + +/**\name Any/No motion duration macros */ +#define BMA421_ANY_NO_MOT_DUR_MSK UINT16_C(0x1FFF) + +/**\name Any/No motion enable macros */ +#define BMA421_ANY_NO_MOT_AXIS_EN_POS UINT8_C(0x0D) +#define BMA421_ANY_NO_MOT_AXIS_EN_MSK UINT16_C(0xE000) + +/**************************************************************/ +/**\name User macros */ +/**************************************************************/ +/**\name Any-motion/No-motion axis enable macros */ +#define BMA421_X_AXIS_EN UINT8_C(0x01) +#define BMA421_Y_AXIS_EN UINT8_C(0x02) +#define BMA421_Z_AXIS_EN UINT8_C(0x04) +#define BMA421_EN_ALL_AXIS UINT8_C(0x07) +#define BMA421_DIS_ALL_AXIS UINT8_C(0x00) + +/**\name Feature enable macros for the sensor */ +#define BMA421_STEP_CNTR UINT8_C(0x01) +#define BMA421_STEP_ACT UINT8_C(0x02) +#define BMA421_WRIST_WEAR UINT8_C(0x04) +#define BMA421_SINGLE_TAP UINT8_C(0x08) +#define BMA421_DOUBLE_TAP UINT8_C(0x10) + +/**\name Interrupt status macros */ +#define BMA421_SINGLE_TAP_INT UINT8_C(0x01) +#define BMA421_STEP_CNTR_INT UINT8_C(0x02) +#define BMA421_ACTIVITY_INT UINT8_C(0x04) +#define BMA421_WRIST_WEAR_INT UINT8_C(0x08) +#define BMA421_DOUBLE_TAP_INT UINT8_C(0x10) +#define BMA421_ANY_MOT_INT UINT8_C(0x20) +#define BMA421_NO_MOT_INT UINT8_C(0x40) +#define BMA421_ERROR_INT UINT8_C(0x80) + +/**\name Activity recognition macros */ +#define BMA421_USER_STATIONARY UINT8_C(0x00) +#define BMA421_USER_WALKING UINT8_C(0x01) +#define BMA421_USER_RUNNING UINT8_C(0x02) +#define BMA421_STATE_INVALID UINT8_C(0x03) + +/******************************************************************************/ +/*! @name Structure Declarations */ +/******************************************************************************/ + +/*! + * @brief Any/No motion configuration + */ +struct bma421_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 Axes re-mapping configuration + */ +struct bma421_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 Step counter param settings + */ +struct bma421_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; +}; + +/***************************************************************************/ + +/*! BMA421 User Interface function prototypes + ****************************************************************************/ + +/** + * \ingroup bma421 + * \defgroup bma421ApiInit Initialization + * @brief Initialize the sensor and device structure + */ + +/*! + * \ingroup bma421ApiInit + * \page bma421_api_bma421_init bma421_init + * \code + * int8_t bma421_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 bma421_init(struct bma4_dev *dev); + +/** + * \ingroup bma421 + * \defgroup bma421ApiConfig ConfigFile + * @brief Write binary configuration in the sensor + */ + +/*! + * \ingroup bma421ApiConfig + * \page bma421_api_bma421_write_config_file bma421_write_config_file + * \code + * int8_t bma421_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 bma421_write_config_file(struct bma4_dev *dev); + +/** + * \ingroup bma421 + * \defgroup bma421ApiConfigId ConfigId + * @brief Get Configuration ID of the sensor + */ + +/*! + * \ingroup bma421ApiConfig + * \page bma421_api_bma421_get_config_id bma421_get_config_id + * \code + * int8_t bma421_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 bma421_get_config_id(uint16_t *config_id, struct bma4_dev *dev); + +/** + * \ingroup bma421 + * \defgroup bma421ApiMapInt Map / Unmap Interrupt + * @brief Map / Unmap user provided interrupt to interrupt pin1 or pin2 of the sensor + */ + +/*! + * \ingroup bma421ApiMapInt + * \page bma421_api_bma421_map_interrupt bma421_map_interrupt + * \code + * int8_t bma421_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 + * - BMA421_STEP_CNTR_INT + * - BMA421_ACTIVITY_INT + * - BMA421_WRIST_WEAR_INT + * - BMA421_WAKEUP_INT + * - BMA421_ANY_MOT_INT + * - BMA421_NO_MOT_INT + * - BMA421_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 bma421_map_interrupt(uint8_t int_line, uint16_t int_map, uint8_t enable, struct bma4_dev *dev); + +/** + * \ingroup bma421 + * \defgroup bma421ApiIntS Interrupt Status + * @brief Read interrupt status of the sensor + */ + +/*! + * \ingroup bma421ApiIntS + * \page bma421_api_bma421_read_int_status bma421_read_int_status + * \code + * int8_t bma421_read_int_status(uint16_t *int_status, struct bma4_dev *dev); + * \endcode + * @details This API reads the bma421 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 + * - BMA421_STEP_CNTR_INT + * - BMA421_ACTIVITY_INT + * - BMA421_WRIST_WEAR_INT + * - BMA421_WAKEUP_INT + * - BMA421_ANY_MOT_INT + * - BMA421_NO_MOT_INT + * - BMA421_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 bma421_read_int_status(uint16_t *int_status, struct bma4_dev *dev); + +/** + * \ingroup bma421 + * \defgroup bma421ApiFeat Sensor Feature + * @brief Enables / Disables features of the sensor + */ + +/*! + * \ingroup bma421ApiFeat + * \page bma421_api_bma421_feature_enable bma421_feature_enable + * \code + * int8_t bma421_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 + * bma421 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 bma421 sensor + * + * - BMA421_STEP_CNTR + * - BMA421_ACTIVITY + * - BMA421_WAKEUP + * - BMA421_WRIST_WEAR + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +int8_t bma421_feature_enable(uint8_t feature, uint8_t enable, struct bma4_dev *dev); + +/** + * \ingroup bma421 + * \defgroup bma421ApiRemap Remap Axes + * @brief Set / Get x, y and z axis re-mapping in the sensor + */ + +/*! + * \ingroup bma421ApiRemap + * \page bma421_api_bma421_set_remap_axes bma421_set_remap_axes + * \code + * int8_t bma421_set_remap_axes(const struct bma421_axes_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 bma421_set_remap_axes(const struct bma421_axes_remap *remap_data, struct bma4_dev *dev); + +/*! + * \ingroup bma421ApiRemap + * \page bma421_api_bma421_get_remap_axes bma421_get_remap_axes + * \code + * int8_t bma421_get_remap_axes(struct bma421_axes_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 bma421 sensor. + * @param[in] dev : Structure instance of bma4_dev + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +int8_t bma421_get_remap_axes(struct bma421_axes_remap *remap_data, struct bma4_dev *dev); + +/** + * \ingroup bma421 + * \defgroup bma421ApiStepC Step counter + * @brief Operations of step counter feature of the sensor + */ + +/*! + * \ingroup bma421ApiStepC + * \page bma421_api_bma421_step_counter_set_watermark bma421_step_counter_set_watermark + * \code + * int8_t bma421_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 bma421_step_counter_set_watermark(uint16_t step_counter_wm, struct bma4_dev *dev); + +/*! + * \ingroup bma421ApiStepC + * \page bma421_api_bma421_step_counter_get_watermark bma421_step_counter_get_watermark + * \code + * int8_t bma421_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 bma421_step_counter_get_watermark(uint16_t *step_counter_wm, struct bma4_dev *dev); + +/*! + * \ingroup bma421ApiStepC + * \page bma421_api_bma421_reset_step_counter bma421_reset_step_counter + * \code + * int8_t bma421_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 bma421_reset_step_counter(struct bma4_dev *dev); + +/*! + * \ingroup bma421ApiStepC + * \page bma421_api_bma421_step_counter_output bma421_step_counter_output + * \code + * int8_t bma421_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 bma421_step_counter_output(uint32_t *step_count, struct bma4_dev *dev); + +/** + * \ingroup bma421 + * \defgroup bma421ApiAct Activity Feature + * @brief Get output for activity feature of the sensor + */ + +/*! + * \ingroup bma421ApiAct + * \page bma421_api_bma421_activity_output bma421_activity_output + * \code + * int8_t bma421_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 | BMA421_USER_STATIONARY + * 0x01 | BMA421_USER_WALKING + * 0x02 | BMA421_USER_RUNNING + * 0x03 | BMA421_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 bma421_activity_output(uint8_t *activity, struct bma4_dev *dev); + +/*! + * \ingroup bma421ApiStepC + * \page bma421_api_bma421_stepcounter_get_parameter bma421_stepcounter_get_parameter + * \code + * int8_t bma421_stepcounter_get_parameter(struct bma421_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 bma421_stepcounter_get_parameter(struct bma421_stepcounter_settings *setting, struct bma4_dev *dev); + +/*! + * \ingroup bma421ApiStepC + * \page bma421_api_bma421_stepcounter_set_parameter bma421_stepcounter_set_parameter + * \code + * int8_t bma421_stepcounter_set_parameter(const struct bma421_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 bma421_stepcounter_set_parameter(const struct bma421_stepcounter_settings *setting, struct bma4_dev *dev); + +/** + * \ingroup bma421 + * \defgroup bma421ApiStepD Step detector + * @brief Operations of step detector feature of the sensor + */ + +/*! + * \ingroup bma421ApiStepD + * \page bma421_api_bma421_step_detector_enable bma421_step_detector_enable + * \code + * int8_t bma421_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 bma421_step_detector_enable(uint8_t enable, struct bma4_dev *dev); + +/** + * \ingroup bma421 + * \defgroup bma421ApiAnyMot Any motion Feature + * @brief Functions of Any motion feature of the sensor + */ + +/*! + * \ingroup bma421ApiAnyMot + * \page bma421_api_bma421_set_any_motion_config bma421_set_any_motion_config + * \code + * int8_t bma421_set_any_motion_config(const struct bma421_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 | BMA421_DIS_ALL_AXIS + * 0x01 | BMA421_X_AXIS_EN + * 0x02 | BMA421_Y_AXIS_EN + * 0x04 | BMA421_Z_AXIS_EN + * 0x07 | BMA421_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 bma421_set_any_mot_config(const struct bma421_any_no_mot_config *any_mot, struct bma4_dev *dev); + +/*! + * \ingroup bma421ApiAnyMot + * \page bma421_api_bma421_get_any_motion_config bma421_get_any_motion_config + * \code + * int8_t bma421_get_any_motion_config(struct bma421_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 | BMA421_DIS_ALL_AXIS + * 0x01 | BMA421_X_AXIS_EN + * 0x02 | BMA421_Y_AXIS_EN + * 0x04 | BMA421_Z_AXIS_EN + * 0x07 | BMA421_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 bma421_get_any_mot_config(struct bma421_any_no_mot_config *any_mot, struct bma4_dev *dev); + +/** + * \ingroup bma421 + * \defgroup bma421ApiNomot No-Motion Feature + * @brief Operations of no-motion feature of the sensor + */ + +/*! + * \ingroup bma421ApiNomot + * \page bma421_api_bma421_set_no_motion_config bma421_set_no_motion_config + * \code + * int8_t bma421_set_no_motion_config(const struct bma421_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 | BMA421_DIS_ALL_AXIS + * 0x01 | BMA421_X_AXIS_EN + * 0x02 | BMA421_Y_AXIS_EN + * 0x04 | BMA421_Z_AXIS_EN + * 0x07 | BMA421_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 bma421_set_no_mot_config(const struct bma421_any_no_mot_config *no_mot, struct bma4_dev *dev); + +/*! + * \ingroup bma421ApiNomot + * \page bma421_api_bma421_get_no_motion_config bma421_get_no_motion_config + * \code + * int8_t bma421_get_no_motion_config(struct bma421_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 | BMA421_DIS_ALL_AXIS + * 0x01 | BMA421_X_AXIS_EN + * 0x02 | BMA421_Y_AXIS_EN + * 0x04 | BMA421_Z_AXIS_EN + * 0x07 | BMA421_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 bma421_get_no_mot_config(struct bma421_any_no_mot_config *no_mot, struct bma4_dev *dev); + +/** + * \ingroup bma421 + * \defgroup bma421ApiTap Single Tap and Double tap + * @brief Single and Double tap feature operations + */ + +/*! + * \ingroup bma421ApiTap + * \page bma421_api_bma421_single_tap_set_sensitivity bma421_single_tap_set_sensitivity + * \code + * int8_t bma421_single_tap_set_sensitivity(uint8_t sensitivity, struct bma4_dev *dev); + * \endcode + * @details This API sets the sensitivity of single tap wake-up feature in the sensor + * + * @param[in] sensitivity : Variable used to specify the sensitivity of the + * Wake up feature. + * + *@verbatim + * Value | Sensitivity + * --------|------------------------- + * 0x00 | MOST SENSITIVE + * 0x07 | LEAST SENSITIVE + *@endverbatim + * + * @param[in] dev : Structure instance of bma4_dev + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +int8_t bma421_single_tap_set_sensitivity(uint8_t sensitivity, struct bma4_dev *dev); + +/*! + * \ingroup bma421ApiTap + * \page bma421_api_bma421_double_tap_set_sensitivity bma421_double_tap_set_sensitivity + * \code + * int8_t bma421_double_tap_set_sensitivity(uint8_t sensitivity, struct bma4_dev *dev); + * \endcode + * @details This API sets the sensitivity of double tap wake-up feature in the sensor + * + * @param[in] sensitivity : Variable used to specify the sensitivity of the + * Wake up feature. + * + *@verbatim + * Value | Sensitivity + * --------|------------------------- + * 0x00 | MOST SENSITIVE + * 0x07 | LEAST SENSITIVE + *@endverbatim + * + * @param[in] dev : Structure instance of bma4_dev + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +int8_t bma421_double_tap_set_sensitivity(uint8_t sensitivity, struct bma4_dev *dev); + +/*! + * \ingroup bma421ApiTap + * \page bma421_api_bma421_single_tap_get_sensitivity bma421_single_tap_get_sensitivity + * \code + * int8_t bma421_single_tap_get_sensitivity(uint8_t *sensitivity, struct bma4_dev *dev); + * \endcode + * @details This API gets the sensitivity of single tap wake up feature in the sensor + * + * @param[out] sensitivity : Pointer variable which stores the sensitivity + * value read from the sensor. + * + * @verbatim + * Value | Sensitivity + * --------|------------------------- + * 0x00 | MOST SENSITIVE + * 0x07 | LEAST SENSITIVE + *@endverbatim + * + * @param[in] dev : Structure instance of bma4_dev + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +int8_t bma421_single_tap_get_sensitivity(uint8_t *sensitivity, struct bma4_dev *dev); + +/*! + * \ingroup bma421ApiTap + * \page bma421_api_bma421_double_tap_get_sensitivity bma421_double_tap_get_sensitivity + * \code + * int8_t bma421_double_tap_get_sensitivity(uint8_t *sensitivity, struct bma4_dev *dev); + * \endcode + * @details This API gets the sensitivity of double tap wake up feature in the sensor + * + * @param[out] sensitivity : Pointer variable which stores the sensitivity + * value read from the sensor. + * + *@verbatim + * Value | Sensitivity + * --------|------------------------- + * 0x00 | MOST SENSITIVE + * 0x07 | LEAST SENSITIVE + *@endverbatim + * + * @param[in] dev : Structure instance of bma4_dev + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +int8_t bma421_double_tap_get_sensitivity(uint8_t *sensitivity, struct bma4_dev *dev); + +/** + * \ingroup bma421 + * \defgroup bma421ApiVersionConfig Version Config + * @brief Get version configuration of the sensor + */ + +/*! + * \ingroup bma421ApiVersionConfig + * \page bma421_api_bma422_huawei_get_version_config bma421_get_version_config + * \code + * int8_t bma421_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. + * + * @retval BMA4_OK - Success. + * @retval BMA4_E_NULL_PTR - Error: Null pointer error + */ +int8_t bma421_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/BMA421-Sensor-API/bma421_config.h b/BMA421-Sensor-API/bma421_config.h new file mode 100644 index 0000000..6542ecd --- /dev/null +++ b/BMA421-Sensor-API/bma421_config.h @@ -0,0 +1,333 @@ +/** + * @file bma421_config.h + * @date Unknown + * @version Unknown + */ + +/**\name Feature configuration file */ +const uint8_t bma421_config_file[] = { + 0x80, 0x2e, 0xfe, 0x00, 0x80, 0x2e, 0xf1, 0x01, 0xc8, 0x2e, 0x00, 0x2e, 0x80, 0x2e, 0xfc, 0x00, 0x80, 0x2e, 0xfb, + 0x00, 0x80, 0x2e, 0xff, 0x00, 0x80, 0x2e, 0xfd, 0x00, 0x80, 0x2e, 0x42, 0xb0, 0x50, 0x39, 0x21, 0x2e, 0xb0, 0xf0, + 0x10, 0x30, 0x21, 0x2e, 0x16, 0xf0, 0x80, 0x2e, 0xf2, 0x01, 0x5d, 0x50, 0x5b, 0x52, 0x01, 0x42, 0x3b, 0x80, 0x41, + 0x30, 0x01, 0x42, 0x3c, 0x80, 0x00, 0x2e, 0x01, 0x40, 0x01, 0x42, 0x21, 0x2e, 0xff, 0xaf, 0xb8, 0x2e, 0x03, 0xb7, + 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, + 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, + 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, + 0x2e, 0x18, 0x00, 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, 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, 0x98, 0x2e, 0x84, 0x01, + 0x20, 0x26, 0x98, 0x2e, 0xf7, 0x00, 0x10, 0x30, 0x21, 0x2e, 0x59, 0xf0, 0x98, 0x2e, 0xae, 0x00, 0x98, 0x2e, 0xab, + 0xb3, 0x98, 0x2e, 0xba, 0xb3, 0x00, 0x2e, 0x00, 0x2e, 0xd0, 0x2e, 0x98, 0x2e, 0xd4, 0x01, 0x01, 0x2e, 0x5a, 0x00, + 0x00, 0xb2, 0x10, 0x2f, 0x00, 0x30, 0x21, 0x2e, 0x5a, 0x00, 0x41, 0x50, 0x98, 0x2e, 0x00, 0xb0, 0x41, 0x50, 0x98, + 0x2e, 0xf2, 0xb0, 0x41, 0x50, 0x43, 0x52, 0x98, 0x2e, 0xd5, 0xb3, 0x41, 0x50, 0x45, 0x52, 0x98, 0x2e, 0xd5, 0xb3, + 0x98, 0x2e, 0xae, 0x00, 0xe3, 0x2d, 0x01, 0x2e, 0x55, 0xf0, 0xc0, 0x2e, 0x21, 0x2e, 0x55, 0xf0, 0x30, 0x50, 0x00, + 0x30, 0x47, 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, 0x65, 0x01, 0xfb, 0x6f, 0x21, 0x25, 0xf0, 0x5f, 0x10, 0x25, 0x80, 0x2e, 0xb3, 0x00, + 0x00, 0x31, 0xc0, 0x2e, 0x21, 0x2e, 0xba, 0xf0, 0xc8, 0x2e, 0xc8, 0x2e, 0xc8, 0x2e, 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, 0x4e, 0x14, 0x88, 0x00, 0x57, 0x00, 0x71, 0x00, 0x7a, 0x00, 0x00, 0x40, 0xff, 0x7f, 0x00, 0x80, 0xaf, + 0x00, 0xff, 0x00, 0xff, 0xb7, 0x00, 0x02, 0x00, 0xb0, 0x05, 0x80, 0xb1, 0xf0, 0x80, 0x00, 0x5e, 0xf0, 0xc0, 0x00, + 0x59, 0xf0, 0x89, 0xf0, 0x5a, 0x00, 0x00, 0x20, 0x5c, 0x00, 0x50, 0x00, 0x54, 0x00, 0x5b, 0x00, 0xff, 0xfb, 0x52, + 0xf0, 0x56, 0xf0, 0x33, 0x09, 0x33, 0x07, 0x00, 0x08, 0x90, 0x01, 0x00, 0xf8, 0x00, 0x01, 0x02, 0x01, 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, 0x4b, 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, 0x49, 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, 0x59, 0x50, 0x41, + 0x30, 0x02, 0x40, 0x51, 0x0a, 0x01, 0x42, 0x18, 0x82, 0x4d, 0x50, 0x60, 0x42, 0x70, 0x3c, 0x4f, 0x54, 0x42, 0x42, + 0x69, 0x82, 0x82, 0x32, 0x43, 0x40, 0x18, 0x08, 0x02, 0x0a, 0x40, 0x42, 0x42, 0x80, 0x02, 0x3f, 0x01, 0x40, 0x10, + 0x50, 0x4a, 0x08, 0xfb, 0x7f, 0x11, 0x42, 0x0b, 0x31, 0x0b, 0x42, 0x3e, 0x80, 0x01, 0x32, 0x01, 0x42, 0x00, 0x2e, + 0x01, 0x2e, 0x40, 0xf0, 0x11, 0x90, 0x20, 0x2f, 0x03, 0x30, 0x53, 0x50, 0x51, 0x54, 0x04, 0x35, 0x06, 0x30, 0x57, + 0x52, 0x55, 0x32, 0x1d, 0x1a, 0xe3, 0x22, 0x18, 0x1a, 0x55, 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, 0x02, 0x2c, 0x08, 0x22, 0x30, 0x30, + 0x00, 0xb2, 0x06, 0x2f, 0x21, 0x2e, 0x59, 0xf0, 0x98, 0x2e, 0xae, 0x00, 0x00, 0x2e, 0x00, 0x2e, 0xd0, 0x2e, 0xfb, + 0x6f, 0xf0, 0x5f, 0xb8, 0x2e, 0x61, 0x50, 0x05, 0x2e, 0x00, 0xf0, 0x5b, 0x56, 0xd3, 0x0f, 0x01, 0x40, 0xf4, 0x33, + 0xcc, 0x08, 0x0d, 0x2f, 0xf4, 0x30, 0x94, 0x08, 0xb9, 0x88, 0x02, 0xa3, 0x04, 0x2f, 0x5f, 0x58, 0x4c, 0x0a, 0x87, + 0xa2, 0x05, 0x2c, 0xcb, 0x22, 0x5b, 0x54, 0x4a, 0x0a, 0xf2, 0x3b, 0xca, 0x08, 0x3c, 0x80, 0x27, 0x2e, 0x59, 0xf0, + 0x01, 0x40, 0x01, 0x42, 0xb8, 0x2e, 0xc8, 0x2e, 0x1a, 0x24, 0x26, 0x00, 0x80, 0x2e, 0x83, 0x00, 0x80, 0x2e, 0x18, + 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x70, 0x50, + 0x03, 0x2e, 0x1f, 0x01, 0xf1, 0x7f, 0x2a, 0x25, 0xb9, 0x82, 0xe0, 0x7f, 0xdb, 0x7f, 0x00, 0x30, 0x45, 0x30, 0x32, + 0x30, 0x03, 0x30, 0x04, 0x30, 0xf6, 0x6f, 0xf2, 0x09, 0xfc, 0x13, 0xc2, 0xab, 0xb5, 0x09, 0xc7, 0x23, 0x80, 0xb3, + 0xe6, 0x6f, 0xb7, 0x01, 0x00, 0x2e, 0x8b, 0x41, 0x4b, 0x42, 0x05, 0x2f, 0xc5, 0x7f, 0x05, 0x30, 0x46, 0x40, 0xae, + 0x05, 0xc5, 0x6f, 0x46, 0x42, 0x01, 0x80, 0x23, 0xbd, 0xd3, 0xbe, 0x03, 0x89, 0x41, 0x82, 0xdf, 0x0c, 0x03, 0xa2, + 0xe4, 0x2f, 0xe0, 0x6f, 0x91, 0x6f, 0x11, 0x42, 0xc3, 0xb2, 0xa1, 0x6f, 0x11, 0x42, 0x00, 0x2e, 0xb1, 0x6f, 0x01, + 0x42, 0x06, 0x2f, 0x00, 0x32, 0x03, 0x2e, 0x59, 0xf0, 0x08, 0x0a, 0x21, 0x2e, 0x59, 0xf0, 0x06, 0x2d, 0xf1, 0x3d, + 0x01, 0x2e, 0x59, 0xf0, 0x01, 0x08, 0x21, 0x2e, 0x59, 0xf0, 0xdb, 0x6f, 0x90, 0x5f, 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, 0x63, 0x58, 0x77, 0x05, 0x41, 0x56, 0x65, 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, 0x67, 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, 0x42, 0x01, 0xd5, 0x6f, 0xe2, 0x6f, 0x2a, 0x18, 0x67, 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, 0x42, 0x01, 0xf2, 0x6f, 0xd5, 0x6f, 0xca, 0x16, + 0x55, 0x18, 0xdd, 0x18, 0x95, 0x6f, 0xea, 0x18, 0x67, 0x5a, 0x31, 0x25, 0x75, 0x01, 0x01, 0x30, 0x20, 0x25, 0x39, + 0x02, 0x5e, 0xba, 0x82, 0xbc, 0x8e, 0xb6, 0x21, 0x0b, 0x98, 0x2e, 0x42, 0x01, 0xe2, 0x6f, 0xb5, 0x6f, 0x2a, 0x18, + 0xe0, 0x7f, 0xf1, 0x7f, 0x04, 0x30, 0x67, 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, 0x42, 0x01, 0xf5, 0x6f, 0x31, 0x25, 0xd1, 0x6f, 0x92, 0x6f, 0xab, 0x6f, + 0x50, 0x43, 0x43, 0x43, 0x90, 0x5f, 0x49, 0x56, 0x80, 0x2e, 0x6f, 0x01, 0x10, 0x50, 0x03, 0x40, 0x19, 0x18, 0x4b, + 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, 0x47, 0x58, 0xdc, 0x00, 0x91, 0x02, 0xbf, 0xb8, 0x21, 0xbd, 0x8a, + 0x0a, 0xc0, 0x2e, 0x02, 0x42, 0xf0, 0x5f, 0x09, 0x2e, 0x1d, 0x01, 0x05, 0x2e, 0x1d, 0x01, 0xa3, 0xbc, 0x44, 0xbe, + 0x90, 0x50, 0x4f, 0xb9, 0x07, 0x2e, 0x1d, 0x01, 0x4a, 0x25, 0x9f, 0xb8, 0x39, 0x8f, 0xb2, 0xbd, 0xf2, 0x7f, 0xbf, + 0xb9, 0xeb, 0x7f, 0x8a, 0x0a, 0x37, 0x89, 0x0b, 0x30, 0x93, 0x0a, 0x8b, 0x7f, 0xcb, 0x43, 0x0b, 0x43, 0x80, 0xb2, + 0xd3, 0x7f, 0xc1, 0x7f, 0x90, 0x2e, 0x9d, 0xb1, 0x20, 0x25, 0x01, 0x2e, 0x56, 0x00, 0x01, 0x90, 0x0e, 0x2f, 0x69, + 0x52, 0x01, 0x2e, 0x53, 0x00, 0xb4, 0x7f, 0xa2, 0x7f, 0x98, 0x2e, 0xa3, 0xb1, 0x00, 0x30, 0x21, 0x2e, 0x56, 0x00, + 0xc1, 0x6f, 0xd3, 0x6f, 0xa2, 0x6f, 0xb4, 0x6f, 0x0b, 0x30, 0x01, 0x2e, 0x1d, 0x01, 0x06, 0xbc, 0x06, 0xbb, 0x57, + 0x25, 0x01, 0x2e, 0x1d, 0x01, 0x94, 0xb1, 0x05, 0xbc, 0xb6, 0x7f, 0x0f, 0xbb, 0x6d, 0x50, 0x80, 0xb3, 0x0f, 0x2f, + 0x0d, 0x2e, 0x1d, 0x01, 0x71, 0x5e, 0xb7, 0x09, 0x2d, 0x2e, 0x1d, 0x01, 0x73, 0x5c, 0x6b, 0x5e, 0x9b, 0x43, 0x9b, + 0x43, 0xdb, 0x43, 0x9b, 0x43, 0x1b, 0x42, 0xcb, 0x43, 0x0b, 0x42, 0x8b, 0x43, 0x40, 0xb2, 0x05, 0x2f, 0x6b, 0x50, + 0x00, 0x2e, 0x16, 0x40, 0x0b, 0x40, 0x76, 0x7f, 0x8b, 0x7f, 0xcb, 0x0a, 0x01, 0x2e, 0x53, 0x00, 0x69, 0x52, 0x6f, + 0x5c, 0x98, 0x2e, 0xef, 0xb1, 0x90, 0x6f, 0x00, 0xb2, 0x0b, 0x2f, 0xf0, 0x6f, 0x00, 0xb2, 0x08, 0x2f, 0x6b, 0x58, + 0x6d, 0x50, 0x12, 0x41, 0x12, 0x42, 0x21, 0x30, 0x04, 0x41, 0x04, 0x42, 0x23, 0x2e, 0x5e, 0xf0, 0xc0, 0x6f, 0x00, + 0xb2, 0x26, 0x2f, 0x74, 0x6f, 0x80, 0x6f, 0x73, 0x54, 0x88, 0xbd, 0xc8, 0xb8, 0x4b, 0x0a, 0x94, 0x42, 0x91, 0x42, + 0x90, 0x42, 0x88, 0xba, 0x6b, 0x52, 0xf3, 0x6f, 0x54, 0x42, 0x85, 0x42, 0xc0, 0x90, 0x40, 0x42, 0x15, 0x2f, 0x6d, + 0x52, 0x00, 0x2e, 0x52, 0x40, 0x41, 0x40, 0xa2, 0x04, 0x41, 0x06, 0x40, 0xaa, 0x04, 0x2f, 0x40, 0x90, 0x0b, 0x2f, + 0xb1, 0x6f, 0x4a, 0x0f, 0x08, 0x2f, 0xb2, 0x6f, 0x80, 0xb2, 0x05, 0x2f, 0x6d, 0x54, 0x21, 0x30, 0x94, 0x42, 0x80, + 0x42, 0x23, 0x2e, 0x5e, 0xf0, 0xd0, 0x6f, 0x00, 0xb2, 0x13, 0x2f, 0x01, 0x2e, 0x52, 0x00, 0x09, 0x2e, 0x5b, 0x00, + 0x04, 0x1a, 0x0d, 0x2f, 0x75, 0x50, 0x29, 0x2e, 0x52, 0x00, 0x24, 0x42, 0x44, 0x30, 0x02, 0x40, 0x02, 0x42, 0x09, + 0x80, 0x00, 0x2e, 0x04, 0x42, 0x03, 0x2d, 0x10, 0x30, 0x21, 0x2e, 0x56, 0x00, 0xeb, 0x6f, 0x70, 0x5f, 0xb8, 0x2e, + 0x09, 0x86, 0x47, 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, 0x77, 0x54, 0x52, 0x42, 0x10, 0x50, 0x79, 0x54, 0x52, 0x42, 0xfb, 0x7f, 0x22, 0x30, 0x7b, 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, 0xe2, 0xb1, + 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, 0x7d, 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, 0xec, 0x00, 0xc0, 0x7e, 0x00, 0xac, 0x01, 0x2f, 0x49, 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, 0x69, 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, 0x69, 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, 0xd8, 0xb0, 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, 0x7f, 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, + 0xd8, 0xb0, 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, 0xd8, 0xb0, 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, + 0xd8, 0xb0, 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, 0x93, 0xb3, 0x04, 0x40, 0x25, + 0x29, 0x04, 0x42, 0x83, 0x42, 0x45, 0x82, 0x94, 0x6f, 0x04, 0x85, 0xc0, 0xb2, 0x90, 0x2e, 0x7f, 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, 0xe2, 0xb1, 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, 0xd8, 0xb0, 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, 0x4f, 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, 0xe2, 0xb1, 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, 0x10, 0x50, 0x81, 0x52, 0x43, + 0x50, 0xfb, 0x7f, 0x98, 0x2e, 0xc9, 0xb3, 0x43, 0x52, 0x45, 0x82, 0x10, 0x30, 0x50, 0x42, 0x60, 0x30, 0xfb, 0x6f, + 0xc0, 0x2e, 0x40, 0x42, 0xf0, 0x5f, 0x10, 0x50, 0x83, 0x52, 0x45, 0x50, 0xfb, 0x7f, 0x98, 0x2e, 0xc9, 0xb3, 0x45, + 0x52, 0x45, 0x82, 0x00, 0x30, 0x50, 0x42, 0x70, 0x30, 0xfb, 0x6f, 0xc0, 0x2e, 0x40, 0x42, 0xf0, 0x5f, 0x12, 0x30, + 0x12, 0x42, 0x02, 0x30, 0x12, 0x42, 0x12, 0x42, 0x12, 0x42, 0x02, 0x42, 0x03, 0x80, 0x41, 0x84, 0x11, 0x42, 0x02, + 0x42, 0xb8, 0x2e, 0x48, 0x84, 0xbe, 0x8a, 0x84, 0x40, 0x70, 0x50, 0x02, 0x41, 0x2d, 0xbb, 0x63, 0x41, 0x42, 0x84, + 0x45, 0x41, 0xc2, 0x7f, 0xb5, 0x7f, 0x80, 0xb3, 0xe6, 0x7f, 0xd0, 0x7f, 0xf3, 0x7f, 0x12, 0x30, 0x5e, 0x2f, 0x31, + 0x25, 0x55, 0x40, 0x41, 0x91, 0xa1, 0x7f, 0x0f, 0x2f, 0x01, 0x30, 0xc1, 0x42, 0x00, 0x2e, 0xc2, 0x6f, 0x13, 0x40, + 0x93, 0x42, 0x00, 0x2e, 0x13, 0x40, 0x93, 0x42, 0x00, 0x2e, 0x00, 0x40, 0x80, 0x42, 0xbd, 0x80, 0xc0, 0x2e, 0x01, + 0x42, 0x90, 0x5f, 0xc7, 0x86, 0x01, 0x30, 0xc5, 0x40, 0xfb, 0x86, 0x45, 0x41, 0x04, 0x41, 0x43, 0xbe, 0xc3, 0xbb, + 0xd5, 0xbe, 0x55, 0xba, 0x97, 0x7f, 0x05, 0x30, 0xd1, 0x15, 0xf7, 0x09, 0xc0, 0xb3, 0x09, 0x2f, 0x06, 0x40, 0xc7, + 0x40, 0xb7, 0x05, 0x07, 0x30, 0x80, 0xa9, 0xfe, 0x05, 0xb7, 0x23, 0x74, 0x0f, 0x55, 0x23, 0xe6, 0x6f, 0x41, 0x82, + 0x01, 0x80, 0xc1, 0x86, 0x43, 0xa2, 0xec, 0x2f, 0xb0, 0x6f, 0xa4, 0x6f, 0x28, 0x1a, 0xd1, 0x6f, 0xc3, 0x6f, 0x02, + 0x2f, 0x02, 0x30, 0x18, 0x2c, 0x02, 0x43, 0x05, 0x41, 0x6a, 0x29, 0x96, 0x6f, 0x05, 0x43, 0x6e, 0x0e, 0x10, 0x2f, + 0xf4, 0x6f, 0x00, 0xb3, 0x03, 0x2f, 0x3f, 0x89, 0x94, 0x14, 0x25, 0x2e, 0x5e, 0xf0, 0x41, 0x25, 0x23, 0x25, 0x15, + 0x41, 0x95, 0x42, 0x00, 0x2e, 0x15, 0x41, 0x95, 0x42, 0x00, 0x2e, 0x04, 0x41, 0x84, 0x42, 0x00, 0x90, 0x09, 0x2f, + 0x50, 0x40, 0xd0, 0x42, 0x00, 0x2e, 0x50, 0x40, 0xd0, 0x42, 0x00, 0x2e, 0x40, 0x40, 0x02, 0x2c, 0xc0, 0x42, 0x42, + 0x42, 0x90, 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, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, + 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, + 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, + 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, + 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, + 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, + 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, + 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, + 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, + 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, + 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, + 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, + 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, + 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, + 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, + 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, + 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, + 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, + 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, + 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, + 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, + 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, + 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, + 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, + 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, + 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, + 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, + 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, + 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, + 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, + 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, + 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, + 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, + 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, + 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, + 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, + 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, + 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, + 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, + 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, + 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, + 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, + 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, + 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, + 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, + 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, + 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, + 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, + 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, + 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, + 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, + 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, + 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, + 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, + 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, + 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, + 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, + 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, + 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, + 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, + 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, + 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, + 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, + 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, + 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, + 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, + 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, + 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, + 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, + 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, + 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, + 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, + 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, + 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, + 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, + 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, + 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, + 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, + 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, + 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, + 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, + 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, + 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, + 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, + 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, + 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, + 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, + 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, + 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, + 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, + 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, + 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, + 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, + 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, + 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, + 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, + 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, + 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00 +}; diff --git a/BMA423-Sensor-API b/BMA423-Sensor-API new file mode 160000 index 0000000..e65f826 --- /dev/null +++ b/BMA423-Sensor-API @@ -0,0 +1 @@ +Subproject commit e65f82683cc2e0d2d4bd8dcfa14089c54bf8787d diff --git a/README.md b/README.md new file mode 100644 index 0000000..fac9217 --- /dev/null +++ b/README.md @@ -0,0 +1,15 @@ +# BMA42x Sensor API for MicroPython + +## Quickstart + +In the directory containing your [MicroPython external C +modules](https://docs.micropython.org/en/latest/develop/cmodules.html) try: + +~~~ sh +git clone https://github.com/daniel-thompson/bma42x-upy +cd bma42x-upy +git submodule update --init +~~~ + +After updating the submodules see `BMA423-Sensor-API/README.md` for more +information about the driver. diff --git a/bma42x.c b/bma42x.c new file mode 100644 index 0000000..62ab740 --- /dev/null +++ b/bma42x.c @@ -0,0 +1,413 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2020 Daniel Thompson + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include +#include + +#include "py/obj.h" +#include "py/objmodule.h" +#include "py/runtime.h" +#include "py/builtin.h" +#include "py/mphal.h" +#include "extmod/machine_i2c.h" +#include "bma421.h" + +STATIC const mp_obj_type_t bma42x_BMA42X_type; + +// this is the actual C-structure for our new object +typedef struct _bma42x_BMA42X_obj_t { + mp_obj_base_t base; + + mp_obj_base_t *i2c_obj; + uint16_t i2c_addr; + bool debug; + + struct bma4_dev dev; +} bma42x_BMA42X_obj_t; + +STATIC void check_result(int res) +{ + switch (res) { + case BMA4_OK: + return; + case BMA4_E_NULL_PTR: + mp_raise_ValueError("null pointer"); + // noreturn + case BMA4_E_OUT_OF_RANGE: + mp_raise_ValueError("out of range"); + // noreturn + case BMA4_E_INVALID_SENSOR: + mp_raise_ValueError("invalid sensor"); + // noreturn + case BMA4_E_CONFIG_STREAM_ERROR: + mp_raise_ValueError("config stream error"); + // noreturn + case BMA4_E_SELF_TEST_FAIL: + mp_raise_ValueError("self test fail"); + // noreturn + case BMA4_E_COM_FAIL: + mp_raise_ValueError("comms failure"); + // noreturn + default: + mp_raise_ValueError("unknown error"); + } +} + +STATIC int i2c_transfer(mp_obj_base_t *i2c_obj, uint16_t addr, size_t n, + mp_machine_i2c_buf_t *bufs, unsigned int flags) +{ + mp_machine_i2c_p_t *i2c_p = (mp_machine_i2c_p_t*)i2c_obj->type->protocol; + + int mp_res = i2c_p->transfer(i2c_obj, addr, n, bufs, flags); + + return mp_res < 0 ? BMA4_E_COM_FAIL : BMA4_OK; +} + +STATIC void hexdump(const uint8_t *buf, unsigned int len) +{ + for (unsigned int i=0; idebug) { + printf("BMA42x write: %u %02x [", self->i2c_addr, reg_addr); + hexdump(reg_data, length); + printf("]\n"); + } + return i2c_transfer(self->i2c_obj, self->i2c_addr, + 2, bufs, MP_MACHINE_I2C_FLAG_STOP); +} + +STATIC int8_t i2c_reg_read(uint8_t reg_addr, uint8_t *reg_data, + uint32_t length, void *intf_ptr) +{ + bma42x_BMA42X_obj_t *self = intf_ptr; + mp_machine_i2c_buf_t buf; + int res; + + if (self->debug) + printf("BMA42x read: %u %02x [", self->i2c_addr, reg_addr); + + /* send register address */ + buf.buf = ®_addr; + buf.len = 1; + res = i2c_transfer(self->i2c_obj, self->i2c_addr, 1, &buf, 0); + if (0 != res) + return res; + + /* STOP */ + buf.buf = NULL; + buf.len = 0; + res = i2c_transfer(self->i2c_obj, self->i2c_addr, + 1, &buf, MP_MACHINE_I2C_FLAG_STOP); + if (0 != res) + return res; + + /* read the data */ + buf.buf = reg_data; + buf.len = length; + res = i2c_transfer(self->i2c_obj, self->i2c_addr, 1, &buf, + MP_MACHINE_I2C_FLAG_READ | MP_MACHINE_I2C_FLAG_STOP); + if (self->debug) { + if (0 == res) + hexdump(reg_data, length); + printf("]\n"); + } + + return res; +} + +STATIC void delay_us(uint32_t period, void *intf_ptr) +{ + mp_hal_delay_us(period); +} + +#define define_bma42x_BMA42X_get(arg_t, prefix, getter) \ +STATIC mp_obj_t bma42x_BMA42X_##getter(mp_obj_t self_in) \ +{ \ + bma42x_BMA42X_obj_t *self = MP_OBJ_TO_PTR(self_in); \ + arg_t arg; \ + check_result(prefix##_##getter(&arg, &self->dev)); \ + return MP_OBJ_NEW_SMALL_INT(arg); \ +} \ +STATIC MP_DEFINE_CONST_FUN_OBJ_1(bma42x_BMA42X_##getter##_obj, \ + bma42x_BMA42X_##getter) + +#define define_bma42x_BMA42X_set(arg_t, prefix, setter) \ +STATIC mp_obj_t bma42x_BMA42X_##setter(mp_obj_t self_in, mp_obj_t arg_in) \ +{ \ + bma42x_BMA42X_obj_t *self = MP_OBJ_TO_PTR(self_in); \ + arg_t arg = mp_obj_get_int(arg_in); \ + check_result(prefix##_##setter(arg, &self->dev)); \ + return mp_const_none; \ +} \ +STATIC MP_DEFINE_CONST_FUN_OBJ_2(bma42x_BMA42X_##setter##_obj, \ + bma42x_BMA42X_##setter) + +mp_obj_t bma42x_BMA42X_make_new(const mp_obj_type_t *type, size_t n_args, + size_t n_kw, const mp_obj_t *all_args ) +{ + enum { ARG_i2c, }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_i2c, MP_ARG_OBJ | MP_ARG_REQUIRED }, + }; + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all_kw_array(n_args, n_kw, all_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + + // create new object + bma42x_BMA42X_obj_t *self = m_new_obj(bma42x_BMA42X_obj_t); + self->base.type = &bma42x_BMA42X_type; + + // set parameters + mp_obj_base_t *i2c_obj = (mp_obj_base_t*)MP_OBJ_TO_PTR(args[ARG_i2c].u_obj); + self->i2c_obj = i2c_obj; + self->i2c_addr = BMA4_I2C_ADDR_PRIMARY; + self->debug = false; + + memset(&self->dev, 0, sizeof(struct bma4_dev)); + self->dev.intf = BMA4_I2C_INTF; + self->dev.intf_ptr = self; + self->dev.bus_read = i2c_reg_read; + self->dev.bus_write = i2c_reg_write; + self->dev.delay_us = delay_us; + self->dev.read_write_len = 8; + + return MP_OBJ_FROM_PTR(self); +} + +STATIC void bma42x_BMA42X_print(const mp_print_t *print, mp_obj_t self_in, + mp_print_kind_t kind ) +{ + (void)kind; + bma42x_BMA42X_obj_t *self = MP_OBJ_TO_PTR(self_in); + mp_printf(print, "", self->i2c_obj); +} + +STATIC mp_obj_t bma42x_BMA42X_debug(mp_obj_t self_in, mp_obj_t enable_in) +{ + bma42x_BMA42X_obj_t *self = MP_OBJ_TO_PTR(self_in); + mp_int_t enable = mp_obj_get_int(enable_in); + + self->debug = enable; + + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_2(bma42x_BMA42X_debug_obj, + bma42x_BMA42X_debug); + +STATIC mp_obj_t bma42x_BMA42X_feature_enable( + mp_obj_t self_in, mp_obj_t feature_in, mp_obj_t enable_in) +{ + bma42x_BMA42X_obj_t *self = MP_OBJ_TO_PTR(self_in); + uint8_t feature = mp_obj_get_int(feature_in); + bool enable = mp_obj_get_int(enable_in); + + check_result(bma421_feature_enable(feature, enable, &self->dev)); + + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_3(bma42x_BMA42X_feature_enable_obj, + bma42x_BMA42X_feature_enable); + +define_bma42x_BMA42X_get(uint8_t, bma4, get_offset_comp); + +STATIC mp_obj_t bma42x_BMA42X_get_reg(mp_obj_t self_in, mp_obj_t reg_in) +{ + bma42x_BMA42X_obj_t *self = MP_OBJ_TO_PTR(self_in); + uint8_t reg = mp_obj_get_int(reg_in); + uint8_t val; + + check_result(bma4_read_regs(reg, &val, 1u, &self->dev)); + + return MP_OBJ_NEW_SMALL_INT(val); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_2(bma42x_BMA42X_get_reg_obj, + bma42x_BMA42X_get_reg); + +STATIC mp_obj_t bma42x_BMA42X_init(mp_obj_t self_in) +{ + bma42x_BMA42X_obj_t *self = MP_OBJ_TO_PTR(self_in); + + check_result(bma421_init(&self->dev)); + + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(bma42x_BMA42X_init_obj, bma42x_BMA42X_init); + +STATIC mp_obj_t bma42x_BMA42X_read_accel_xyz(mp_obj_t self_in) +{ + bma42x_BMA42X_obj_t *self = MP_OBJ_TO_PTR(self_in); + struct bma4_accel data; + + check_result(bma4_read_accel_xyz(&data, &self->dev)); + + mp_obj_t tuple[3] = { + MP_OBJ_NEW_SMALL_INT(data.x), + MP_OBJ_NEW_SMALL_INT(data.y), + MP_OBJ_NEW_SMALL_INT(data.z), + }; + return mp_obj_new_tuple(3, tuple); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(bma42x_BMA42X_read_accel_xyz_obj, + bma42x_BMA42X_read_accel_xyz); + +STATIC mp_obj_t bma42x_BMA42X_set_accel_config(size_t n_args, const mp_obj_t *args, + mp_map_t *kw_args) +{ + bma42x_BMA42X_obj_t *self = MP_OBJ_TO_PTR(args[0]); + + enum { ARG_odr, ARG_range, ARG_bandwidth, ARG_perf_mode, }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_odr, MP_ARG_INT, {.u_int = BMA4_OUTPUT_DATA_RATE_100HZ } }, + { MP_QSTR_range, MP_ARG_INT, {.u_int = BMA4_ACCEL_RANGE_2G } }, + { MP_QSTR_bandwidth, MP_ARG_INT, {.u_int = BMA4_ACCEL_NORMAL_AVG4 } }, + { MP_QSTR_perf_mode, MP_ARG_INT, {.u_int = BMA4_CIC_AVG_MODE } }, + }; + mp_arg_val_t vals[ARG_perf_mode+1]; + mp_arg_parse_all(n_args-1, args+1, kw_args, ARG_perf_mode+1, allowed_args, vals); + + struct bma4_accel_config conf = { + .odr = vals[ARG_odr].u_int, + .range = vals[ARG_range].u_int, + .bandwidth = vals[ARG_bandwidth].u_int, + .perf_mode = vals[ARG_perf_mode].u_int, + }; + check_result(bma4_set_accel_config(&conf, &self->dev)); + + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_KW(bma42x_BMA42X_set_accel_config_obj, 1, + bma42x_BMA42X_set_accel_config); + +define_bma42x_BMA42X_set(bool, bma4, set_accel_enable); +define_bma42x_BMA42X_set(uint8_t, bma4, set_command_register); +define_bma42x_BMA42X_set(uint8_t, bma4, set_offset_comp); + +STATIC mp_obj_t bma42x_BMA42X_set_reg(mp_obj_t self_in, mp_obj_t reg_in, + mp_obj_t val_in) +{ + bma42x_BMA42X_obj_t *self = MP_OBJ_TO_PTR(self_in); + uint8_t reg = mp_obj_get_int(reg_in); + uint8_t val = mp_obj_get_int(val_in); + + check_result(bma4_write_regs(reg, &val, 1u, &self->dev)); + + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_3(bma42x_BMA42X_set_reg_obj, + bma42x_BMA42X_set_reg); + +define_bma42x_BMA42X_get(uint32_t, bma421, step_counter_output); +define_bma42x_BMA42X_set(bool, bma421, step_detector_enable); + +STATIC mp_obj_t bma42x_BMA42X_write_config_file(mp_obj_t self_in) +{ + bma42x_BMA42X_obj_t *self = MP_OBJ_TO_PTR(self_in); + + check_result(bma421_write_config_file(&self->dev)); + + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(bma42x_BMA42X_write_config_file_obj, + bma42x_BMA42X_write_config_file); + +#define BMA4_EXPORT_OBJ(x) \ + { MP_ROM_QSTR(MP_QSTR_##x), MP_ROM_PTR(&bma42x_BMA42X_##x##_obj) } + +STATIC const mp_rom_map_elem_t bma42x_BMA42X_locals_dict_table[] = { + BMA4_EXPORT_OBJ(debug), + BMA4_EXPORT_OBJ(feature_enable), + BMA4_EXPORT_OBJ(get_offset_comp), + BMA4_EXPORT_OBJ(get_reg), + BMA4_EXPORT_OBJ(init), + BMA4_EXPORT_OBJ(read_accel_xyz), + BMA4_EXPORT_OBJ(set_accel_config), + BMA4_EXPORT_OBJ(set_accel_enable), + BMA4_EXPORT_OBJ(set_command_register), + BMA4_EXPORT_OBJ(set_offset_comp), + BMA4_EXPORT_OBJ(set_reg), + BMA4_EXPORT_OBJ(step_counter_output), + BMA4_EXPORT_OBJ(step_detector_enable), + BMA4_EXPORT_OBJ(write_config_file), +}; +STATIC MP_DEFINE_CONST_DICT(bma42x_BMA42X_locals_dict, bma42x_BMA42X_locals_dict_table); + +STATIC const mp_obj_type_t bma42x_BMA42X_type = { + { &mp_type_type }, + .name = MP_QSTR_BMA42X, + .print = bma42x_BMA42X_print, + .make_new = bma42x_BMA42X_make_new, + .locals_dict = (mp_obj_dict_t*)&bma42x_BMA42X_locals_dict, +}; + +#define BMA4_EXPORT_CONST(x) \ + { MP_ROM_QSTR(MP_QSTR_##x), MP_ROM_INT(BMA4_##x) } +#define BMA421_EXPORT_CONST(x) \ + { MP_ROM_QSTR(MP_QSTR_##x), MP_ROM_INT(BMA421_##x) } + +STATIC const mp_map_elem_t bma42x_module_globals_table[] = { + { MP_ROM_QSTR(MP_QSTR___name__), MP_OBJ_NEW_QSTR(MP_QSTR_bma42x) }, + { MP_ROM_QSTR(MP_QSTR_BMA42X), (mp_obj_t)&bma42x_BMA42X_type }, + + // Registers + BMA4_EXPORT_CONST(ACCEL_CONFIG_ADDR), + BMA4_EXPORT_CONST(POWER_CONF_ADDR), + BMA4_EXPORT_CONST(POWER_CTRL_ADDR), + BMA4_EXPORT_CONST(NV_CONFIG_ADDR), + + // Conf values + BMA4_EXPORT_CONST(ACCEL_RANGE_2G), + BMA4_EXPORT_CONST(ACCEL_RANGE_4G), + BMA4_EXPORT_CONST(ACCEL_RANGE_8G), + BMA4_EXPORT_CONST(ACCEL_RANGE_16G), + BMA4_EXPORT_CONST(ACCEL_NORMAL_AVG4), + BMA4_EXPORT_CONST(OUTPUT_DATA_RATE_50HZ), + BMA4_EXPORT_CONST(OUTPUT_DATA_RATE_100HZ), + BMA4_EXPORT_CONST(CIC_AVG_MODE), + BMA4_EXPORT_CONST(CONTINUOUS_MODE), + + BMA421_EXPORT_CONST(STEP_CNTR), + BMA421_EXPORT_CONST(STEP_ACT), + BMA421_EXPORT_CONST(WRIST_WEAR), + BMA421_EXPORT_CONST(SINGLE_TAP), + BMA421_EXPORT_CONST(DOUBLE_TAP), +}; + +STATIC MP_DEFINE_CONST_DICT (mp_module_bma42x_globals, bma42x_module_globals_table ); + +const mp_obj_module_t mp_module_bma42x = { + .base = { &mp_type_module }, + .globals = (mp_obj_dict_t*)&mp_module_bma42x_globals, +}; + +MP_REGISTER_MODULE(MP_QSTR_bma42x, mp_module_bma42x, MODULE_BMA42X_ENABLED); diff --git a/examples/step_counter.py b/examples/step_counter.py new file mode 100644 index 0000000..1ea317b --- /dev/null +++ b/examples/step_counter.py @@ -0,0 +1,73 @@ +# +# Copyright (c) 2020 Bosch Sensortec GmbH. All rights reserved. +# Copyright (c) 2020 Daniel Thompson. +# +# SPDX-License-Identifier: BSD-3-Clause +# + +"""Step counter + +Example shows basic setup application of step counter feature. + +This example is a translation of the equivalent code in C +(although the loop at the end is slightly different): +../BMA423-Sensor-API/examples/generic/step_counter.c . +""" + +import bma42x +import time +import watch + +bma = bma42x.BMA42X(watch.i2c) +accel_conf = {} + +bma.init() + +# There is no hardware reset capability so issue a software reset +# instead. +bma.set_command_register(0xb6) +time.sleep(0.20) + +# Upload the configuration file to enable the features of the sensor. +bma.write_config_file() + +# Enable the accelerometer +bma.set_accel_enable(True) + +# Accelerometer Configuration Setting +# Output data Rate +accel_conf['odr'] = bma42x.OUTPUT_DATA_RATE_100HZ + +# Gravity range of the sensor (+/- 2G, 4G, 8G, 16G) +accel_conf['range'] = bma42x.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'] = bma42x.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'] = bma42x.CIC_AVG_MODE + +# Set the accel configurations +bma.set_accel_config(**accel_conf) + +# Enable step counter +bma.feature_enable(bma42x.STEP_CNTR, True) + +print("Move/perform the walk/step action with the sensor") +while True: + # Get step counter output + step_out = bma.step_counter_output() + print("The step counter output is {}\r".format(step_out), end='') + + time.sleep(2) diff --git a/micropython.mk b/micropython.mk new file mode 100644 index 0000000..7e708e8 --- /dev/null +++ b/micropython.mk @@ -0,0 +1,11 @@ +BMA42X_MOD_DIR := $(USERMOD_DIR) +SRC_USERMOD += $(addprefix $(BMA42X_MOD_DIR)/, \ + bma42x.c \ + BMA421-Sensor-API/bma421.c \ + BMA423-Sensor-API/bma4.c \ + BMA423-Sensor-API/bma423.c \ +) +CFLAGS_USERMOD += \ + -I$(BMA42X_MOD_DIR)/BMA421-Sensor-API \ + -I$(BMA42X_MOD_DIR)/BMA423-Sensor-API \ + -DMODULE_BMA42X_ENABLED=1