/**
 * @section LICENSE
 * Copyright (c) 2023 Bosch Sensortec GmbH All Rights Reserved.
 *
 * This software program is licensed subject to the GNU General
 * Public License (GPL).Version 2,June 1991,
 * available at http://www.fsf.org/copyleft/gpl.html
 *
 * @file       bma456o.h
 * @date       2023-02-24
 * @version    V2.27.1
 *
 */

/**
 * \ingroup bma4xy
 * \defgroup bma456o BMA456O
 * @brief Sensor driver for BMA456O sensor
 */

#ifndef BMA456O_H
#define BMA456O_H

#ifdef __cplusplus
extern "C" {
#endif
#include "bma4.h"

/**\name Chip ID of BMA456 sensor */
#define BMA456O_CHIP_ID                  UINT8_C(0x16)

/**\name Sensor feature size */
#define BMA456O_FEATURE_SIZE             UINT8_C(12)

/**\name Feature offset address */
#define BMA456O_ORIENTATION_OFFSET       UINT8_C(0x00)
#define BMA456O_CONFIG_ID_OFFSET         UINT8_C(0x08)
#define BMA456O_AXES_REMAP_OFFSET        UINT8_C(0x0A)

/**\name Read/Write Lengths */
#define BMA456O_RD_WR_MIN_LEN            UINT8_C(2)

/*! @name Maximum valid read write length is size of config file array */
#define BMA456O_RD_WR_MAX_LEN            ((uint16_t)sizeof(bma456o_config_file))

/**************************************************************/
/**\name    Re-map Axes */
/**************************************************************/
#define BMA456O_X_AXIS_MASK              UINT8_C(0x03)
#define BMA456O_X_AXIS_SIGN_MASK         UINT8_C(0x04)
#define BMA456O_Y_AXIS_MASK              UINT8_C(0x18)
#define BMA456O_Y_AXIS_SIGN_MASK         UINT8_C(0x20)
#define BMA456O_Z_AXIS_MASK              UINT8_C(0xC0)
#define BMA456O_Z_AXIS_SIGN_MASK         UINT8_C(0x01)

/**************************************************************/
/**\name                Orientation                           */
/**************************************************************/
#define BMA456O_ORIENTATION_OUT_ADDR     UINT8_C(0x1E)

#define BMA456O_ORIENTATION_OUTPUT_MASK  UINT8_C(0x07)

/**\name Orientation enable macros */
#define BMA456O_ORIENT_EN_POS            UINT8_C(0)
#define BMA456O_ORIENT_EN_MSK            UINT8_C(0x01)

/**\name Orientation upside/down detection macros */
#define BMA456O_ORIENT_UD_POS            UINT8_C(1)
#define BMA456O_ORIENT_UD_MSK            UINT8_C(0x02)

/**\name Orientation mode macros */
#define BMA456O_ORIENT_MODE_POS          UINT8_C(2)
#define BMA456O_ORIENT_MODE_MSK          UINT8_C(0x0C)

/**\name Orientation theta macros */
#define BMA456O_ORIENT_THETA_POS         UINT8_C(4)
#define BMA456O_ORIENT_THETA_MSK         UINT16_C(0x03F0)

/**\name Orientation hold time macros */
#define BMA456O_ORIENT_HOLD_TIME_POS     UINT8_C(10)
#define BMA456O_ORIENT_HOLD_TIME_MSK     UINT16_C(0x7C00)

/**\name Orientation slope threshold macros */
#define BMA456O_ORIENT_SLOPE_THRES_POS   UINT8_C(0)
#define BMA456O_ORIENT_SLOPE_THRES_MSK   UINT16_C(0x00FF)

/**\name Orientation hysteresis macros */
#define BMA456O_ORIENT_HYST_POS          UINT8_C(8)
#define BMA456O_ORIENT_HYST_MSK          UINT16_C(0xFF00)

/**\name Orientation fall threshold macros */
#define BMA456O_ORIENT_FALL_THRES_POS    UINT8_C(0)
#define BMA456O_ORIENT_FALL_THRES_MSK    UINT16_C(0x7FFF)

/**\name Orientation blocking macros */
#define BMA456O_ORIENT_BLOCKING_POS      UINT8_C(0)
#define BMA456O_ORIENT_BLOCKING_MSK      UINT16_C(0x0007)

/**\name Orientation fall hysteresis macros */
#define BMA456O_ORIENT_FALL_HYST_POS     UINT8_C(3)
#define BMA456O_ORIENT_FALL_HYST_MSK     UINT16_C(0x7FF8)

/*  Orientation output macros  */
#define BMA456O_ORIENT_OUT_POS           UINT8_C(0)
#define BMA456O_ORIENT_OUT_MSK           UINT8_C(0x03)
#define BMA456O_ORIENT_FACEUP_DOWN_POS   UINT8_C(2)
#define BMA456O_ORIENT_FACEUP_DOWN_MSK   UINT8_C(0x04)

/**\name Orientation output macros */
/* Bit pos 2 reflects the face-up (0) face-down(1) only if ud_en is enabled */
#define BMA456O_FACE_UP                  UINT8_C(0x00)
#define BMA456O_FACE_DOWN                UINT8_C(0x01)

/* Bit pos 0-1 reflects the have the following value */
#define BMA456O_PORTRAIT_UP_RIGHT        UINT8_C(0x00)
#define BMA456O_LANDSCAPE_LEFT           UINT8_C(0x01)
#define BMA456O_PORTRAIT_UP_DOWN         UINT8_C(0x02)
#define BMA456O_LANDSCAPE_RIGHT          UINT8_C(0x03)

/**************************************************************/
/**\name                 User macros                          */
/**************************************************************/
/**\name Feature enable macros for the sensor */
#define BMA456O_ORIENT                   UINT8_C(0x02)

/**\name Interrupt status macros */
#define BMA456O_ORIENT_INT               UINT8_C(0x02)
#define BMA456O_ERROR_INT                UINT8_C(0x80)

/******************************************************************************/
/*!  @name         Structure Declarations                             */
/******************************************************************************/

/*!
 * @brief Orientation configuration structure
 */
struct bma456o_orientation_config
{
    /*! Upside/Downside detection */
    uint8_t upside_down;

    /*! Mode
     * Symmetrical (values 0 or 3), High asymmetrical
     * (value 1) or Low asymmetrical (value 2)
     */
    uint8_t mode;

    /*! Theta
     * Coded value of the threshold angle with horizontal
     * used in Blocking modes;
     * theta = 64 * (tan(angle)^2);
     */
    uint8_t theta;

    /*! Hold Time
     * The number of samples for which the orientation
     * should be stable in 50Hz. Resolution: 5 = 100msecs
     */
    uint8_t hold_time;

    /*! Slope Threshold
     * The slope threshold for blocking mode.
     * Resolution: 0.4g = 205 lsbs
     */
    uint8_t slope_thres;

    /*! Hysteresis
     * Hysteresis of acceleration for orientation change detection.
     * Resolution: 62.5mg = 32 lsbs
     */
    uint8_t hysteresis;

    /*! Fall Threshold
     * Threshold for fall detection.
     * Fall detection is used to block the orientation change
     * in block mode 4. Resolution: 0.5g = 1024 lsbs
     */
    uint16_t fall_threshold;

    /*! Blocking mode
     * Sets the blocking mode.
     * If blocking is set, no Orientation interrupt will be triggered.
     * Default value is 4 – the most restrictive blocking mode.
     */
    uint8_t blocking;

    /*! Fall Hysteresis
     * Hysteresis threshold for fall detection.
     * Fall detection is used to block the orientation change in block mode 4.
     * Resolution: 0.25g = 512 lsbs
     */
    uint16_t fall_hysteresis;
};

/***************************************************************************/

/*!             BMA456O User Interface function prototypes
 ****************************************************************************/

/**
 * \ingroup bma456o
 * \defgroup bma456oApiInit Initialization
 * @brief Initialize the sensor and device structure
 */

/*!
 * \ingroup bma456oApiInit
 * \page bma456o_api_bma456o_init bma456o_init
 * \code
 * int8_t bma456o_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 bma456o_init(struct bma4_dev *dev);

/**
 * \ingroup bma456o
 * \defgroup bma456oApiConfig Config
 * @brief Configuration APIs
 */

/*!
 * \ingroup bma456oApiConfig
 * \page bma456o_api_bma456o_write_config_file bma456o_write_config_file
 * \code
 * int8_t bma456o_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 bma456o_write_config_file(struct bma4_dev *dev);

/*!
 * \ingroup bma456oApiConfig
 * \page bma456o_api_bma456o_get_version_config bma456o_get_version_config
 * \code
 *int8_t bma456o_get_version_config(uint16_t *config_major, uint16_t *config_minor, struct bma4_dev *dev);
 * \endcode
 * @details This API is used to get the config file major and minor information.
 *
 * @param[in] dev   : Structure instance of bma4_dev.
 * @param[out] config_major    : Pointer to data buffer to store the config major.
 * @param[out] config_minor    : Pointer to data buffer to store the config minor.
 *
 *  @return Result of API execution status
 *  @retval 0 -> Success
 *  @retval < 0 -> Fail
 */
int8_t bma456o_get_version_config(uint16_t *config_major, uint16_t *config_minor, struct bma4_dev *dev);

/*!
 * \ingroup bma456oApiConfig
 * \page bma456o_api_bma456o_get_config_id bma456o_get_config_id
 * \code
 * int8_t bma456o_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 bma456o_get_config_id(uint16_t *config_id, struct bma4_dev *dev);

/**
 * \ingroup bma456o
 * \defgroup bma456oApiMapInt Map / Unmap Interrupt
 * @brief Map / Unmap user provided interrupt to interrupt pin1 or pin2 of the sensor
 */

/*!
 * \ingroup bma456oApiMapInt
 * \page bma456o_api_bma456o_map_interrupt bma456o_map_interrupt
 * \code
 * int8_t bma456o_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
 *  - BMA456O_ORIENT_INT
 *  - BMA456O_ERROR_INT
 *
 * Hardware Interrupts
 *  - BMA4_FIFO_FULL_INT
 *  - BMA4_FIFO_WM_INT
 *  - BMA4_MAG_DATA_RDY_INT
 *  - BMA4_ACCEL_DATA_RDY_INT
 *
 * @return Result of API execution status
 * @retval 0 -> Success
 * @retval < 0 -> Fail
 */
int8_t bma456o_map_interrupt(uint8_t int_line, uint16_t int_map, uint8_t enable, struct bma4_dev *dev);

/**
 * \ingroup bma456o
 * \defgroup bma456oApiIntS Interrupt Status
 * @brief Read interrupt status of the sensor
 */

/*!
 * \ingroup bma456oApiIntS
 * \page bma456o_api_bma456o_read_int_status bma456o_read_int_status
 * \code
 * int8_t bma456o_read_int_status(uint16_t *int_status, struct bma4_dev *dev);
 * \endcode
 * @details This API reads the bma456 interrupt status from the sensor.
 *
 * @param[out] int_status : Variable to store the interrupt status read from
 * the sensor.
 * @param[in] dev : Structure instance of bma4_dev.
 *
 * @note Below macros are used to check the interrupt status.
 *
 * Feature Interrupts
 *  - BMA456O_ORIENT_INT
 *  - BMA456O_ERROR_INT
 *
 * Hardware Interrupts
 *  - BMA4_FIFO_FULL_INT
 *  - BMA4_FIFO_WM_INT
 *  - BMA4_MAG_DATA_RDY_INT
 *  - BMA4_ACCEL_DATA_RDY_INT
 *
 * @return Result of API execution status
 * @retval 0 -> Success
 * @retval < 0 -> Fail
 */
int8_t bma456o_read_int_status(uint16_t *int_status, struct bma4_dev *dev);

/**
 * \ingroup bma456o
 * \defgroup bma456oApiFeat Sensor Feature
 * @brief Enables / Disables features of the sensor
 */

/*!
 * \ingroup bma456oApiFeat
 * \page bma456o_api_bma456o_feature_enable bma456o_feature_enable
 * \code
 * int8_t bma456o_feature_enable(uint8_t feature, uint8_t enable, struct bma4_dev *dev);
 * \endcode
 * @details This API enables/disables the features of the sensor.
 *
 * @param[in] feature : Variable to specify the features which are to be set in
 * bma456 sensor.
 * @param[in] enable : Variable which specifies whether to enable or disable the
 * features in the bma456 sensor.
 *
 *@verbatim
 *  enable  |   Macros
 *  --------|-------------------
 *  0x00    |  BMA4_DISABLE
 *  0x01    |  BMA4_ENABLE
 *@endverbatim
 *
 * @param[in] dev : Structure instance of bma4_dev.
 *
 * @note User should use the below macros to enable or disable the
 * features of bma456o sensor
 *
 *   - BMA456O_ORIENT
 *
 * @return Result of API execution status
 * @retval 0 -> Success
 * @retval < 0 -> Fail
 */
int8_t bma456o_feature_enable(uint8_t feature, uint8_t enable, struct bma4_dev *dev);

/**
 * \ingroup bma456o
 * \defgroup bma456oApiRemap Remap Axes
 * @brief Set / Get x, y and z axis re-mapping in the sensor
 */

/*!
 * \ingroup bma456oApiRemap
 * \page bma456o_api_bma456o_set_remap_axes bma456o_set_remap_axes
 * \code
 * int8_t bma456o_set_remap_axes(const struct bma4_remap *remap_data, struct bma4_dev *dev);
 * \endcode
 * @details This API performs x, y and z axis remapping in the sensor.
 *
 * @param[in] remap_data : Pointer to store axes remapping data.
 * @param[in] dev : Structure instance of bma4_dev
 *
 * @return Result of API execution status
 * @retval 0 -> Success
 * @retval < 0 -> Fail
 */
int8_t bma456o_set_remap_axes(const struct bma4_remap *remap_data, struct bma4_dev *dev);

/*!
 * \ingroup bma456oApiRemap
 * \page bma456o_api_bma456o_get_remap_axes bma456o_get_remap_axes
 * \code
 * int8_t bma456o_get_remap_axes(struct bma4_remap *remap_data, struct bma4_dev *dev);
 * \endcode
 * @details This API reads the x, y and z axis remap data from the sensor.
 *
 * @param[out] remap_data : Pointer to store axis remap data which is read
 * from the bma456 sensor.
 * @param[in] dev : Structure instance of bma4_dev
 *
 * @return Result of API execution status
 * @retval 0 -> Success
 * @retval < 0 -> Fail
 */
int8_t bma456o_get_remap_axes(struct bma4_remap *remap_data, struct bma4_dev *dev);

/**
 * \ingroup bma456o
 * \defgroup bma456oApiOrientation Orientation Feature
 * @brief Functions of Orientation feature of the sensor
 */

/*!
 * \ingroup bma456oApiOrientation
 * \page bma456o_api_bma456o_set_orientation_config bma456o_set_orientation_config
 * \code
 * int8_t bma456o_set_orientation_config(struct bma456o_orientation_config *orientation, struct bma4_dev *dev);
 * \endcode
 * @details  This API sets the configuration of orientation feature of the sensor.
 *
 * @param[in] orientation : Pointer  to structure variable used to
 * store the orientation feature settings to be written to sensor.
 *
 * Structure members are provided in the table below
 *
 *@verbatim
 * -------------------------------------------------------------------------
 *         Structure parameters    |        Description
 * --------------------------------|----------------------------------------
 *         ud_en                   |        Enables face upside/downside
 *                                 |        detection if set to 1
 * --------------------------------|----------------------------------------
 *                                 |        symmetrical (values 0 or 3),
 *         mode                    |        high asymmetrical (value 1)
 *                                 |        or low asymmetrical (value 2).
 * --------------------------------|----------------------------------------
 *                                 |        Coded value of the threshold angle
 *                                 |        with horizontal used in blocking
 *        theta                    |        modes, theta = 64 * (tan(angle)^2).
 *                                 |        Default value is 40 which is
 *                                 |        equivalent to 38 degrees angle.
 * -------------------------------------------------------------------------
 *                                 |        The number of samples for which
 *        hold_time                |        the orientation should be stable
 *                                 |         in 50Hz. Reolution: 5 = 100msecs
 * -------------------------------------------------------------------------
 *        slope_thres              |        The slope threshold for blocking
 *                                 |        mode. Resolution: 0.4g = 205 lsbs
 * -------------------------------------------------------------------------
 *                                 |        Hysteresis of acceleration for
 *        hysteresis               |        orientation change detection.
 *                                 |        Resolution: 62.5mg = 32 lsbs
 * -------------------------------------------------------------------------
 *                                 |        Threshold for fall detection.
 *       fall_threshold            |        Fall detection is used to block
 *                                 |        the orientation change in block
 *                                 |        mode 4. Resolution: 0.5g = 1024 lsbs
 * -------------------------------------------------------------------------
 *                                 |        Sets the blocking mode.
 *         blocking                |        Default value is 4, the most
 *                                 |        restrictive blocking mode.
 * -------------------------------------------------------------------------
 *                                 |        Hysteresis threshold for fall detection.
 *       fall_hysteresis           |        Fall detection is used to block the
 *                                 |        orientation change in block mode 4.
 *                                 |        Resolution: 0.25g = 512 lsbs
 * -------------------------------------------------------------------------
 *@endverbatim
 *
 *  @param[in] dev : Structure instance of bma4_dev
 *
 *  @return Result of API execution status
 *  @retval 0 -> Success
 *  @retval < 0 -> Fail
 */
int8_t bma456o_set_orientation_config(const struct bma456o_orientation_config *orientation, struct bma4_dev *dev);

/*!
 * \ingroup bma456oApiOrientation
 * \page bma456o_api_bma456o_get_orientation_config bma456o_get_orientation_config
 * \code
 * int8_t bma456o_get_orientation_config(struct bma456o_orientation_config *orientation, struct bma4_dev *dev);
 * \endcode
 * @details  This API gets the configuration of orientation feature from the sensor.
 *
 * @param[out] orientation : Pointer  to structure variable used to
 * store the orientation feature settings read from the sensor.
 *
 * Structure members are provided in the table below
 *
 *@verbatim
 * -------------------------------------------------------------------------
 *         Structure parameters    |        Description
 * --------------------------------|----------------------------------------
 *         ud_en                   |        Enables face upside/downside
 *                                 |        detection if set to 1
 * --------------------------------|----------------------------------------
 *                                 |        symmetrical (values 0 or 3),
 *         mode                    |        high asymmetrical (value 1)
 *                                 |        or low asymmetrical (value 2).
 * --------------------------------|----------------------------------------
 *                                 |        Coded value of the threshold angle
 *                                 |        with horizontal used in blocking
 *        theta                    |        modes, theta = 64 * (tan(angle)^2).
 *                                 |        Default value is 40 which is
 *                                 |        equivalent to 38 degrees angle.
 * -------------------------------------------------------------------------
 *                                 |        The number of samples for which
 *        hold_time                |        the orientation should be stable
 *                                 |         in 50Hz. Reolution: 5 = 100msecs
 * -------------------------------------------------------------------------
 *        slope_thres              |        The slope threshold for blocking
 *                                 |        mode. Resolution: 0.4g = 205 lsbs
 * -------------------------------------------------------------------------
 *                                 |        Hysteresis of acceleration for
 *        hysteresis               |        orientation change detection.
 *                                 |        Resolution: 62.5mg = 32 lsbs
 * -------------------------------------------------------------------------
 *                                 |        Threshold for fall detection.
 *       fall_threshold            |        Fall detection is used to block
 *                                 |        the orientation change in block
 *                                 |        mode 4. Resolution: 0.5g = 1024 lsbs
 * -------------------------------------------------------------------------
 *                                 |        Sets the blocking mode.
 *         blocking                |        Default value is 4, the most
 *                                 |        restrictive blocking mode.
 * -------------------------------------------------------------------------
 *                                 |        Hysteresis threshold for fall detection.
 *       fall_hysteresis           |        Fall detection is used to block the
 *                                 |        orientation change in block mode 4.
 *                                 |        Resolution: 0.25g = 512 lsbs
 * -------------------------------------------------------------------------
 *@endverbatim
 *
 *  @param[in] dev : Structure instance of bma4_dev
 *
 *  @return Result of API execution status
 *  @retval 0 -> Success
 *  @retval < 0 -> Fail
 */
int8_t bma456o_get_orientation_config(struct bma456o_orientation_config *orientation, struct bma4_dev *dev);

/*!
 * \ingroup bma422nApiOrient
 * \page bma456o_api_bma456o_orientation_output bma456o_orientation_output
 * \code
 * int8_t bma456o_orientation_output(uint8_t *orientation_output, uint8_t *orientation_faceup_down,
 *                                   struct bma4_dev *dev);
 *
 * \endcode
 * @details This API gets the output of orientation feature from the sensor.
 *
 *  @param orientation_output : pointer used to store the orientation output.
 *
 *@verbatim
 *   orientation_output          |        Values
 *-------------------------------|-----------------------------
 *   Bit pos 0-1 reflects        |   BMA456O_PORTRAIT_UP_RIGHT
 *   orientation output value    |   BMA456O_LANDSCAPE_LEFT
 *   only if ud_en is enabled    |   BMA456O_PORTRAIT_UP_DOWN
 *                               |   BMA456O_LANDSCAPE_RIGHT
 *-------------------------------|-----------------------------
 *@endverbatim
 *
 * @param orientation_faceup_down : Output value of face down face up orientation
 *
 *@verbatim
 *   orientation_faceup_down     |        Values
 *-------------------------------|-----------------------------
 *   Bit pos 2 reflects          |   BMA456O_FACE_UP
 *   face-up (0) or face-down(1) |   BMA456O_FACE_DOWN
 *   only if ud_en is enabled    |
 *-------------------------------|-----------------------------
 *@endverbatim
 *
 *  @param dev : Structure instance of bma4_dev
 *
 *  @return Result of API execution status
 *  @retval 0 -> Success
 *  @retval < 0 -> Fail
 */
int8_t bma456o_orientation_output(uint8_t *orientation_output, uint8_t *orientation_faceup_down, struct bma4_dev *dev);

#ifdef __cplusplus
}
#endif /*End of CPP guard */

#endif /*End of header guard macro */
