/*
 * __________________________________________________________________
 *
 * Copyright (C) [2023] by InvenSense, Inc.
 * 
 * Permission to use, copy, modify, and/or distribute this software
 * for any purpose with or without fee is hereby granted.
 * 
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
 * WARRANTIES  WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
 * WARRANTIES OF MERCHANTABILITY  AND FITNESS. IN NO EVENT SHALL
 * THE AUTHOR BE LIABLE  FOR ANY SPECIAL, DIRECT, INDIRECT, OR
 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
 * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
 * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 * __________________________________________________________________
 */

/** @defgroup DriverOIS OIS driver
 *  @brief High-level API to drive OIS interface of the device.
 *  @{
 */

/** @file Ixm42xxxDriver_HL_ois.h */

#ifndef _INV_IXM42XXX_DRIVER_HL_OIS_H_
#define _INV_IXM42XXX_DRIVER_HL_OIS_H_

#ifdef __cplusplus
extern "C" {
#endif

#include "Invn/Drivers/Ixm42xxx/Ixm42xxxDriver_HL.h"

/** @brief Initializes driver for OIS.
 *  @param[in] s      Pointer to device.
 *  @param[in] serif  Pointer on serial interface structure to be used to access ixm42xxx.
 *  @return 0 on success, negative value on error.
 */
int inv_ixm42xxx_init_ois(struct inv_ixm42xxx *s, struct inv_ixm42xxx_serif *serif);

/** @brief return WHOAMI value
 *  @param[in] s          Pointer to device.
 *  @param[out] who_am_i  WHOAMI for device
 *  @return               0 on success, negative value on error
 */
int inv_ixm42xxx_get_who_am_i_ois(struct inv_ixm42xxx *s, uint8_t *who_am_i);

/** @brief return OIS_MODE value
 *  @param[in] s          Pointer to device.
 *  @param[out] ois_mode  Current mode.
 *  @return               0 on success, negative value on error
 */
int inv_ixm42xxx_get_ois_mode_ois(struct inv_ixm42xxx *               s,
                                  IXM42XXX_SENSOR_CONFIG2_OIS_MODE_t *ois_mode);

/** @brief Set gyro full scale range on auxiliary path 1
 *  @param[in] s             Pointer to device.
 *  @param[in] gyro_fsr_dps  Requested full scale range.
 *  @return                  0 on success, negative value on error.
 */
int inv_ixm42xxx_set_gyro_fsr_ois1(struct inv_ixm42xxx *               s,
                                   IXM42XXX_OIS1_CONFIG2_GYRO_FS_SEL_t gyro_fsr_dps);

/** @brief Set gyro full scale range on auxiliary path 2
 *  @param[in] s             Pointer to device.
 *  @param[in] gyro_fsr_dps  Requested full scale range.
 *  @return                  0 on success, negative value on error.
 */
int inv_ixm42xxx_set_gyro_fsr_ois2(struct inv_ixm42xxx *               s,
                                   IXM42XXX_OIS2_CONFIG2_GYRO_FS_SEL_t gyro_fsr_dps);

/** @brief Set accel full scale range on auxiliary path 1
 *  @param[in] s            Pointer to device.
 *  @param[in] accel_fsr_g  Requested full scale range.
 *  @return                 0 on success, negative value on error.
 */
int inv_ixm42xxx_set_accel_fsr_ois1(struct inv_ixm42xxx *                s,
                                    IXM42XXX_OIS1_CONFIG2_ACCEL_FS_SEL_t accel_fsr_g);

/** @brief Set accel full scale range on auxiliary path 2
 *  @param[in] s            Pointer to device.
 *  @param[in] accel_fsr_g  Requested full scale range.
 *  @return                 0 on success, negative value on error.
 */
int inv_ixm42xxx_set_accel_fsr_ois2(struct inv_ixm42xxx *                s,
                                    IXM42XXX_OIS2_CONFIG2_ACCEL_FS_SEL_t accel_fsr_g);

/** @brief Configure OIS Output Data Rate on auxiliary path 1.
 *  @param[in] s          Pointer to device.
 *  @param[in] decimator  The requested decimation factor based on maximum OIS frequency 
 *                        allowed for current chip.
 *  @return               0 on success, negative value on error.
 */
int inv_ixm42xxx_set_ois1_decimator(struct inv_ixm42xxx *             s,
                                    const IXM42XXX_OIS1_CONFIG1_DEC_t decimator);

/** @brief Configure OIS Output Data Rate on auxiliary path 2.
 *  @param[in] s          Pointer to device.
 *  @param[in] decimator  The requested decimation factor based on maximum OIS frequency
 *                        allowed for current chip.
 *  @return               0 on success, negative value on error.
 */
int inv_ixm42xxx_set_ois2_decimator(struct inv_ixm42xxx *             s,
                                    const IXM42XXX_OIS2_CONFIG1_DEC_t decimator);

/** @brief Enable gyroscope on auxiliary path 1.
 *  Note this API fits with main OIS scenario meaning OIS with gyro data only. It does 
 *  not allow to enable accelerometer data on auxiliary pathes. To do so refer to
 *  low-level API in Ixm42xxxDriver.c.
 *  @param[in] s  Pointer to device.
 *  @return       0 on success, negative value on error.
 */
int inv_ixm42xxx_enable_gyro_ois1(struct inv_ixm42xxx *s);

/** @brief Enable gyrometer on auxiliary path 2.
 *  Note this API fits with main OIS scenario meaning OIS with gyro data only. It does 
 *  not allow to enable accelerometer data on auxiliary pathes. To do so refer to
 *  low-level API in Ixm42xxxDriver.c.
 *  @param[in] s  Pointer to device.
 *  @return       0 on success, negative value on error.
 */
int inv_ixm42xxx_enable_gyro_ois2(struct inv_ixm42xxx *s);

/** @brief Disable gyrometer on auxiliary path 1.
 *  @param[in] s  Pointer to device.
 *  @return       0 on success, negative value on error.
 */
int inv_ixm42xxx_disable_gyro_ois1(struct inv_ixm42xxx *s);

/** @brief Disable gyrometer on auxiliary path 2.
 *  @param[in] s  Pointer to device.
 *  @return       0 on success, negative value on error.
 */
int inv_ixm42xxx_disable_gyro_ois2(struct inv_ixm42xxx *s);

/** @brief Enable accelerometer on auxiliary path 1.
 *  @param[in] s  Pointer to device.
 *  @return       0 on success, negative value on error.
 */
int inv_ixm42xxx_enable_accel_ois1(struct inv_ixm42xxx *s);

/** @brief Enable accelerometer on auxiliary path 2.
 *  @param[in] s  Pointer to device.
 *  @return       0 on success, negative value on error.
 */
int inv_ixm42xxx_enable_accel_ois2(struct inv_ixm42xxx *s);

/** @brief Disable accelerometer on auxiliary path 1.
 *  @param[in] s  Pointer to device.
 *  @return       0 on success, negative value on error.
 */
int inv_ixm42xxx_disable_accel_ois1(struct inv_ixm42xxx *s);

/** @brief Disable accelerometer on auxiliary path 1.
 *  @param[in] s  Pointer to device.
 *  @return       0 on success, negative value on error.
 */
int inv_ixm42xxx_disable_accel_ois2(struct inv_ixm42xxx *s);

/** @brief Get gyrometer data from auxiliary path 1.
 *  @param[in] s           Pointer to device.
 *  @param[out] gyro_data  Gyro data.
 *  @return                0 on success, negative value on error or on invalid data.
 */
int inv_ixm42xxx_get_gyro_data_ois1(struct inv_ixm42xxx *s, int16_t gyro_data[3]);

/** @brief Get gyrometer data from auxiliary path 2.
 *  @param[in] s           Pointer to device.
 *  @param[out] gyro_data  Gyro data.
 *  @return                0 on success, negative value on error or on invalid data.
 */
int inv_ixm42xxx_get_gyro_data_ois2(struct inv_ixm42xxx *s, int16_t gyro_data[3]);

/** @brief Get accelerometer data from auxiliary path 1.
 *  @param[in] s            Pointer to device.
 *  @param[out] accel_data  Accel data.
 *  @return                 0 on success, negative value on error or on invalid data.
 */
int inv_ixm42xxx_get_accel_data_ois1(struct inv_ixm42xxx *s, int16_t accel_data[3]);

/** @brief Get accelerometer data from auxiliary path 2.
 *  @param[in] s            Pointer to device.
 *  @param[out] accel_data  Accel data.
 *  @return                 0 on success, negative value on error or on invalid data.
 */
int inv_ixm42xxx_get_accel_data_ois2(struct inv_ixm42xxx *s, int16_t accel_data[3]);

/** @brief Get accelerometer and gyroscope data from auxiliary path 1.
 *  @param[in] s            Pointer to device.
 *  @param[out] accel_data  Accel data.
 *  @param[out] gyro_data   Gyro data.
 *  @return                 0 on success, negative value on error or on invalid data.
 */
int inv_ixm42xxx_get_accel_and_gyro_data_ois1(struct inv_ixm42xxx *s, int16_t accel_data[3],
                                              int16_t gyro_data[3]);

/** @brief Get accelerometer and gyroscope data from auxiliary path 2.
 *  @param[in] s            Pointer to device.
 *  @param[out] accel_data  Accel data.
 *  @param[out] gyro_data   Gyro data.
 *  @return                 0 on success, negative value on error or on invalid data.
 */
int inv_ixm42xxx_get_accel_and_gyro_data_ois2(struct inv_ixm42xxx *s, int16_t accel_data[3],
                                              int16_t gyro_data[3]);

#ifdef __cplusplus
}
#endif

#endif /* _INV_IXM42XXX_DRIVER_HL_OIS_H_ */

/** @} */
