#ifndef __xh_ina228_H__
#define __xh_ina228_H__

#include "stdint.h"
#include "xh_core.h"

typedef void        (*xh_ina228_set_shunt_mohm_obj)(void *var, float value);
typedef void        (*xh_ina228_set_max_curr_ma_obj)(void *var, float value);
typedef void        (*xh_ina228_set_chg_ocp_thresh_obj)(void *var, float value);
typedef void        (*xh_ina228_set_dsg_ocp_thresh_obj)(void *var, float value);
typedef void        (*xh_ina228_set_bus_ovp_thresh_obj)(void *var, float value);
typedef void        (*xh_ina228_set_bus_uvp_thresh_obj)(void *var, float value);
typedef void        (*xh_ina228_set_dev_otp_thresh_obj)(void *var, float value);
typedef void        (*xh_ina228_set_over_pwr_thresh_obj)(void *var, float value);

typedef uint8_t     (*xh_ina228_get_vshunt_mv_obj)(void *var, float *p_data);
typedef uint8_t     (*xh_ina228_get_vbus_mv_obj)(void *var, float *p_data);
typedef uint8_t     (*xh_ina228_get_dietemp_c_obj)(void *var, float *p_data);
typedef uint8_t     (*xh_ina228_get_current_ma_obj)(void *var, float *p_data);
typedef uint8_t     (*xh_ina228_get_power_w_obj)(void *var, float *p_data);
typedef uint8_t     (*xh_ina228_get_energy_j_obj)(void *var, float *p_data);
typedef uint8_t     (*xh_ina228_get_charge_c_obj)(void *var, float *p_data);
typedef uint8_t     (*xh_ina228_get_diag_alrt_obj)(void *var, uint16_t *p_data);
typedef uint8_t     (*xh_ina228_get_manu_id_obj)(void *var, uint16_t *p_data);
typedef uint8_t     (*xh_ina228_get_device_id_obj)(void *var, uint16_t *p_data);

typedef struct _xh_ina228_t
{
    xh_comm_t core;

    xh_ina228_set_shunt_mohm_obj            set_shunt_mohm;
    xh_ina228_set_max_curr_ma_obj           set_max_curr_ma;
    xh_ina228_set_chg_ocp_thresh_obj        set_chg_ocp_thresh;
    xh_ina228_set_dsg_ocp_thresh_obj        set_dsg_ocp_thresh;
    xh_ina228_set_bus_ovp_thresh_obj        set_bus_ovp_thresh;
    xh_ina228_set_bus_uvp_thresh_obj        set_bus_uvp_thresh;
    xh_ina228_set_dev_otp_thresh_obj        set_dev_otp_thresh;
    xh_ina228_set_over_pwr_thresh_obj       set_over_pwr_thresh;

    xh_ina228_get_vshunt_mv_obj             get_vshunt_mv;
    xh_ina228_get_vbus_mv_obj               get_vbus_mv;
    xh_ina228_get_dietemp_c_obj             get_dietemp_c;
    xh_ina228_get_current_ma_obj            get_current_ma;
    xh_ina228_get_power_w_obj               get_power_w;
    xh_ina228_get_energy_j_obj              get_energy_j;
    xh_ina228_get_charge_c_obj              get_charge_c;
    xh_ina228_get_diag_alrt_obj             get_diag_alrt;
    xh_ina228_get_manu_id_obj               get_manu_id;
    xh_ina228_get_device_id_obj             get_device_id;
}xh_ina228_t, *p_xh_ina228_t;

#define XH_INA228_WEAK_FUNC_DEF(drv_prefix, obj_type)                                                       \
    X_FRAME_WEAK void drv_prefix##_##set_shunt_mohm(obj_type ina228, float value) { return; }   \
    X_FRAME_WEAK void drv_prefix##_##set_max_curr_ma(obj_type ina228, float value) { return; }      \
    X_FRAME_WEAK void drv_prefix##_##set_chg_ocp_thresh(obj_type ina228, float value) { return; }       \
    X_FRAME_WEAK void drv_prefix##_##set_dsg_ocp_thresh(obj_type ina228, float value) { return; }       \
    X_FRAME_WEAK void drv_prefix##_##set_bus_ovp_thresh(obj_type ina228, float value) { return; }        \
    X_FRAME_WEAK void drv_prefix##_##set_bus_uvp_thresh(obj_type ina228, float value) { return; }        \
    X_FRAME_WEAK void drv_prefix##_##set_dev_otp_thresh(obj_type ina228, float value) { return; }       \
    X_FRAME_WEAK void drv_prefix##_##set_over_pwr_thresh(obj_type ina228, float value) { return; }       \
    X_FRAME_WEAK uint8_t drv_prefix##_##get_vshunt_mv(obj_type ina228, float *p_data) { return 0; }                    \
    X_FRAME_WEAK uint8_t drv_prefix##_##get_vbus_mv(obj_type ina228, float *p_data) { return 0; }                      \
    X_FRAME_WEAK uint8_t drv_prefix##_##get_dietemp_c(obj_type ina228, float *p_data) { return 0; }                    \
    X_FRAME_WEAK uint8_t drv_prefix##_##get_current_ma(obj_type ina228, float *p_data) { return 0; }                  \
    X_FRAME_WEAK uint8_t drv_prefix##_##get_power_w(obj_type ina228, float *p_data) { return 0; }                     \
    X_FRAME_WEAK uint8_t drv_prefix##_##get_energy_j(obj_type ina228, float *p_data) { return 0; }                    \
    X_FRAME_WEAK uint8_t drv_prefix##_##get_charge_c(obj_type ina228, float *p_data) { return 0; }                    \
    X_FRAME_WEAK uint8_t drv_prefix##_##get_diag_alrt(obj_type ina228, uint16_t *p_data) { return 0; }                   \
    X_FRAME_WEAK uint8_t drv_prefix##_##get_manu_id(obj_type ina228, uint16_t *p_data) { return 0; }                     \
    X_FRAME_WEAK uint8_t drv_prefix##_##get_device_id(obj_type ina228, uint16_t *p_data) { return 0; }

/* 驱动宏定义实现 */
#define XH_REG_INA228_DRV_NEW(id, var, prio, auto_init, init, deinit, drv_prefix)                  \
    XH_REG_DEV(xh_ina228_t, id, var, prio, auto_init, init, deinit,                                        \
                (xh_ina228_set_shunt_mohm_obj     )drv_prefix##_##set_shunt_mohm       ,                 \
                (xh_ina228_set_max_curr_ma_obj    )drv_prefix##_##set_max_curr_ma      ,                 \
                (xh_ina228_set_chg_ocp_thresh_obj )drv_prefix##_##set_chg_ocp_thresh   ,                \
                (xh_ina228_set_dsg_ocp_thresh_obj )drv_prefix##_##set_dsg_ocp_thresh   ,                \
                (xh_ina228_set_bus_ovp_thresh_obj )drv_prefix##_##set_bus_ovp_thresh   ,                 \
                (xh_ina228_set_bus_uvp_thresh_obj )drv_prefix##_##set_bus_uvp_thresh   ,                \
                (xh_ina228_set_dev_otp_thresh_obj )drv_prefix##_##set_dev_otp_thresh   ,                \
                (xh_ina228_set_over_pwr_thresh_obj)drv_prefix##_##set_over_pwr_thresh  ,                 \
                (xh_ina228_get_vshunt_mv_obj      )drv_prefix##_##get_vshunt_mv        ,                 \
                (xh_ina228_get_vbus_mv_obj        )drv_prefix##_##get_vbus_mv          ,                 \
                (xh_ina228_get_dietemp_c_obj      )drv_prefix##_##get_dietemp_c        ,                 \
                (xh_ina228_get_current_ma_obj     )drv_prefix##_##get_current_ma       ,                 \
                (xh_ina228_get_power_w_obj        )drv_prefix##_##get_power_w          ,                 \
                (xh_ina228_get_energy_j_obj       )drv_prefix##_##get_energy_j         ,                 \
                (xh_ina228_get_charge_c_obj       )drv_prefix##_##get_charge_c         ,                 \
                (xh_ina228_get_diag_alrt_obj      )drv_prefix##_##get_diag_alrt        ,                 \
                (xh_ina228_get_manu_id_obj        )drv_prefix##_##get_manu_id          ,                 \
                (xh_ina228_get_device_id_obj      )drv_prefix##_##get_device_id)

/* Legacy macro for backward compatibility */
#define XH_REG_INA228_DRV(id, var, prio, auto_init, init, deinit,                                   \
                set_shunt_mohm, set_max_curr_ma, set_chg_ocp_thresh, set_dsg_ocp_thresh,            \
                set_bus_ovp_thresh, set_bus_uvp_thresh, set_dev_otp_thresh, set_over_pwr_thresh,    \
                get_vshunt_mv, get_vbus_mv, get_dietemp_c, get_current_ma, get_power_w,             \
                get_energy_j, get_charge_c, get_diag_alrt, get_manu_id, get_device_id)              \
        XH_REG_DEV(xh_ina228_t, id, var, prio, auto_init, init, deinit,                             \
                (xh_ina228_set_shunt_mohm_obj     )set_shunt_mohm       ,                           \
                (xh_ina228_set_max_curr_ma_obj    )set_max_curr_ma      ,                           \
                (xh_ina228_set_chg_ocp_thresh_obj )set_chg_ocp_thresh   ,                           \
                (xh_ina228_set_dsg_ocp_thresh_obj )set_dsg_ocp_thresh   ,                           \
                (xh_ina228_set_bus_ovp_thresh_obj )set_bus_ovp_thresh   ,                           \
                (xh_ina228_set_bus_uvp_thresh_obj )set_bus_uvp_thresh   ,                           \
                (xh_ina228_set_dev_otp_thresh_obj )set_dev_otp_thresh   ,                           \
                (xh_ina228_set_over_pwr_thresh_obj)set_over_pwr_thresh  ,                           \
                (xh_ina228_get_vshunt_mv_obj      )get_vshunt_mv        ,                           \
                (xh_ina228_get_vbus_mv_obj        )get_vbus_mv          ,                           \
                (xh_ina228_get_dietemp_c_obj      )get_dietemp_c        ,                           \
                (xh_ina228_get_current_ma_obj     )get_current_ma       ,                           \
                (xh_ina228_get_power_w_obj        )get_power_w          ,                           \
                (xh_ina228_get_energy_j_obj       )get_energy_j         ,                           \
                (xh_ina228_get_charge_c_obj       )get_charge_c         ,                           \
                (xh_ina228_get_diag_alrt_obj      )get_diag_alrt        ,                           \
                (xh_ina228_get_manu_id_obj        )get_manu_id          ,                           \
                (xh_ina228_get_device_id_obj      )get_device_id                                    \
        )

#define XH_EXT_INA228_DRV(id)        XH_EXT_DEV(xh_ina228_t, id)

/**
 * @brief       INA228设置分流器阻值
 * @param [in]  id          	INA228的驱动ID
 * @param [in]  value       	分流器阻值, 单位: mΩ
 * @param [out] none    
 * @retval      none
 */
static inline void xh_ina228_set_shunt_mohm(void *const id, float value)
{
    xh_ina228_t *p = (xh_ina228_t *)id;
    p->set_shunt_mohm(p->core.var, value);
}

/**
 * @brief       INA228设置最大期望电流值
 * @param [in]  id          	INA228的驱动ID
 * @param [in]  value       	最大期望电流值, 单位: mA
 * @param [out] none    
 * @retval      none
 */
static inline void xh_ina228_set_max_curr_ma(void *const id, float value)
{
    xh_ina228_t *p = (xh_ina228_t *)id;
    p->set_max_curr_ma(p->core.var, value);
}

/**
 * @brief       INA228设置充电过流阈值
 * @param [in]  id          	INA228的驱动ID
 * @param [in]  value       	充电过流阈值, 单位: mA
 * @param [out] none    
 * @retval      none
 */
static inline void xh_ina228_set_chg_ocp_thresh(void *const id, float value)
{
    xh_ina228_t *p = (xh_ina228_t *)id;
    p->set_chg_ocp_thresh(p->core.var, value);
}

/**
 * @brief       INA228设置放电过流阈值
 * @param [in]  id          	INA228的驱动ID
 * @param [in]  value       	放电过流阈值, 单位: mA
 * @param [out] none    
 * @retval      none
 */
static inline void xh_ina228_set_dsg_ocp_thresh(void *const id, float value)
{
    xh_ina228_t *p = (xh_ina228_t *)id;
    p->set_dsg_ocp_thresh(p->core.var, value);
}

/**
 * @brief       INA228设置总线过压阈值
 * @param [in]  id          	INA228的驱动ID
 * @param [in]  value       	总线过压阈值, 单位: mV
 * @param [out] none    
 * @retval      none
 */
static inline void xh_ina228_set_bus_ovp_thresh(void *const id, float value)
{
    xh_ina228_t *p = (xh_ina228_t *)id;
    p->set_bus_ovp_thresh(p->core.var, value);
}

/**
 * @brief       INA228设置总线欠压阈值
 * @param [in]  id          	INA228的驱动ID
 * @param [in]  value       	总线欠压阈值, 单位: mV
 * @param [out] none    
 * @retval      none
 */
static inline void xh_ina228_set_bus_uvp_thresh(void *const id, float value)
{
    xh_ina228_t *p = (xh_ina228_t *)id;
    p->set_bus_uvp_thresh(p->core.var, value);
}

/**
 * @brief       INA228设置设备过温阈值
 * @param [in]  id          	INA228的驱动ID
 * @param [in]  value       	设备过温阈值, 单位: C
 * @param [out] none    
 * @retval      none
 */
static inline void xh_ina228_set_dev_otp_thresh(void *const id, float value)
{
    xh_ina228_t *p = (xh_ina228_t *)id;
    p->set_dev_otp_thresh(p->core.var, value);
}

/**
 * @brief       INA228设置过功率阈值
 * @param [in]  id          	INA228的驱动ID
 * @param [in]  value       	过功率阈值, 单位: W
 * @param [out] none    
 * @retval      none
 */
static inline void xh_ina228_set_over_pwr_thresh(void *const id, float value)
{
    xh_ina228_t *p = (xh_ina228_t *)id;
    p->set_over_pwr_thresh(p->core.var, value);
}

/**
 * @brief       INA228读取分流器电压
 * @param [in]  id          	INA228的驱动ID
 * @param [out] p_data			分流器电压值, 单位: mV
 * @retval      返回结果		1-失败，0-成功
 */
static inline uint8_t xh_ina228_get_vshunt_mv(void *const id, float *p_data)
{
    xh_ina228_t *p = (xh_ina228_t *)id;
    return p->get_vshunt_mv(p->core.var, p_data);
}

/**
 * @brief       INA228读取总线电压
 * @param [in]  id          	INA228的驱动ID
 * @param [out] p_data			总线电压值, 单位: mV
 * @retval      返回结果		1-失败，0-成功
 */
static inline uint8_t xh_ina228_get_vbus_mv(void *const id, float *p_data)
{
    xh_ina228_t *p = (xh_ina228_t *)id;
    return p->get_vbus_mv(p->core.var, p_data);
}

/**
 * @brief       INA228读取温度
 * @param [in]  id          	INA228的驱动ID
 * @param [out] p_data			温度值, 单位: C
 * @retval      返回结果		1-失败，0-成功   
 */
static inline uint8_t xh_ina228_get_dietemp_c(void *const id, float *p_data)
{
    xh_ina228_t *p = (xh_ina228_t *)id;
    return p->get_dietemp_c(p->core.var, p_data);
}

/**
 * @brief       INA228读取电流
 * @param [in]  id          	INA228的驱动ID
 * @param [out] p_data			电流值, 单位: mA
 * @retval      返回结果		1-失败，0-成功  
 */
static inline uint8_t xh_ina228_get_current_ma(void *const id, float *p_data)
{
    xh_ina228_t *p = (xh_ina228_t *)id;
    return p->get_current_ma(p->core.var, p_data);
}

/**
 * @brief       INA228读取功率
 * @param [in]  id          	INA228的驱动ID
 * @param [out] p_data			功率值, 单位: W
 * @retval      返回结果		1-失败，0-成功  
 */
static inline uint8_t xh_ina228_get_power_w(void *const id, float *p_data)
{
    xh_ina228_t *p = (xh_ina228_t *)id;
    return p->get_power_w(p->core.var, p_data);
}

/**
 * @brief       INA228读取电能
 * @param [in]  id          	INA228的驱动ID
 * @param [out] p_data			电能值, 单位: J
 * @retval      返回结果		1-失败，0-成功  
 */
static inline uint8_t xh_ina228_get_energy_j(void *const id, float *p_data)
{
    xh_ina228_t *p = (xh_ina228_t *)id;
    return p->get_energy_j(p->core.var, p_data);
}

/**
 * @brief       INA228读取电荷
 * @param [in]  id          	INA228的驱动ID
 * @param [out] p_data			电荷值, 单位: C
 * @retval      返回结果		1-失败，0-成功
 */
static inline uint8_t xh_ina228_get_charge_c(void *const id, float *p_data)
{
    xh_ina228_t *p = (xh_ina228_t *)id;
    return p->get_charge_c(p->core.var, p_data);
}

/**
 * @brief       INA228读取诊断标志和警报
 * @param [in]  id          	INA228的驱动ID
 * @param [out] p_data			诊断标志值
 * @retval      返回结果		1-失败，0-成功
 */
static inline uint8_t xh_ina228_get_diag_alrt(void *const id, uint16_t *p_data)
{
    xh_ina228_t *p = (xh_ina228_t *)id;
    return p->get_diag_alrt(p->core.var, p_data);
}

/**
 * @brief       INA228读取制造商ID
 * @param [in]  id          	INA228的驱动ID
 * @param [out] p_data			制造商ID值
 * @retval      返回结果		1-失败，0-成功
 */
static inline uint8_t xh_ina228_get_manu_id(void *const id, uint16_t *p_data)
{
    xh_ina228_t *p = (xh_ina228_t *)id;
    return p->get_manu_id(p->core.var, p_data);
}

/**
 * @brief       INA228读取器件ID
 * @param [in]  id          	INA228的驱动ID
 * @param [out] p_data			器件ID值
 * @retval      返回结果		1-失败，0-成功 
 */
static inline uint8_t xh_ina228_get_device_id(void *const id, uint16_t *p_data)
{
    xh_ina228_t *p = (xh_ina228_t *)id;
    return p->get_device_id(p->core.var, p_data);
}

#endif //__xh_ina228_H__
