/**
  *****************************************************************************
  * @file    ufcs_pe.h
  * @author  Solution Team
  * @version V1.00
  * @date    28-February-2023
  * @brief   UFCS Policy Control Engine management
  *****************************************************************************
  * @attention 
  *  Copyright (c) 2017 - 2023 Unicmicro Co., Ltd. 
  *  All Rights Reserved. 
  *****************************************************************************
  */
 
#ifndef __UFCS_PE_H_
#define __UFCS_PE_H_


#include "libc.h"
#include "drivers.h"
#include "ufcs_defs.h"

/** 策略控制供电设备指示 */
#define ufcs_source_port(dev) \
    ((((UFCS_DEV_t *)(dev))->pe.state >= UFCS_PE_SRC_DCP_DET1) && (((UFCS_DEV_t *)(dev))->pe.state <= UFCS_PE_SRC_GET_ERR_INFO))

/** 策略控制充电设备指示 */
#define ufcs_sink_port(dev) \
    ((((UFCS_DEV_t *)(dev))->pe.state >= UFCS_PE_SNK_VBUS_DET) && (((UFCS_DEV_t *)(dev))->pe.state <= UFCS_PE_SNK_CFG_WDT))

/** 策略控制电源已准备好 */
#define ufcs_pe_state_is_ps_rdy(dev) \
    ((((UFCS_DEV_t *)(dev))->pe.state == UFCS_PE_SNK_PS_READY) || (((UFCS_DEV_t *)(dev))->pe.state == UFCS_PE_SRC_PS_READY))

/** 策略控制供电设备电源已准备好 */
#define ufcs_pe_state_is_src_rdy(dev) \
    (((UFCS_DEV_t *)(dev))->pe.state == UFCS_PE_SRC_PS_READY)

/** 策略控制充电设备电源已准备好 */
#define ufcs_pe_state_is_snk_rdy(dev) \
    (((UFCS_DEV_t *)(dev))->pe.state == UFCS_PE_SNK_PS_READY)

/** 获取当前策略控制状态 */
#define ufcs_pe_state_get(dev) \
    (((UFCS_DEV_t *)(dev))->pe.state)

/** 获取上一个策略控制状态 */
#define ufcs_pe_state_prev_get(dev) \
    (((UFCS_DEV_t *)(dev))->pe.state_prev)

#if UFCS_DEBUG_ENABLED
/** 设置当前策略控制状态 */
void ufcs_pe_state_set(UFCS_DEV_t *dev, u32_t sta);
#else
/** 设置当前策略控制状态 */
#define ufcs_pe_state_set(dev, val) \
    do { \
        if (!ufcs_pe_state_is_ps_rdy(dev)) \
            ((UFCS_DEV_t *)(dev))->pe.ps_ready_time = 0; \
        if ((val) != ((UFCS_DEV_t *)(dev))->pe.state) { \
            ((UFCS_DEV_t *)(dev))->pe.state_prev = ((UFCS_DEV_t *)(dev))->pe.state; \
            ((UFCS_DEV_t *)(dev))->pe.state = val; \
        } \
    } while(0)
#endif /* UFCS_DEBUG_ENABLED */


/** 设置VBUS存在标志，需要外部设置，也是启动PE的标志 */
void ufcs_pe_vbus_present_set(UFCS_DEV_t *dev, u32_t flg);

/** 获取VBUS存在标志 */
#define ufcs_pe_vbus_present_get(dev) \
    (((UFCS_DEV_t *)(dev))->pe.vbus_present)

/** 设置VBUS充电中标志 */
#define ufcs_pe_sinking_vbus_set(dev,flg) \
    do { \
        ((UFCS_DEV_t *)(dev))->pe.sinking_vbus = flg; \
    } while(0)

/** 获取VBUS充电中标志 */
#define ufcs_pe_sinking_vbus_get(dev) \
    (((UFCS_DEV_t *)(dev))->pe.sinking_vbus)

/** 设置VBUS供电中标志 */
#define ufcs_pe_sourcing_vbus_set(dev,flg) \
    do { \
        ((UFCS_DEV_t *)(dev))->pe.sourcing_vbus = flg; \
    } while(0)

/** 获取VBUS供电中标志 */
#define ufcs_pe_sourcing_vbus_get(dev) \
    (((UFCS_DEV_t *)(dev))->pe.sourcing_vbus)

/** 设置检测到线缆电子标签标志 */
#define ufcs_pe_cableplug_detected_set(dev,flg) \
    do { \
        ((UFCS_DEV_t *)(dev))->pe.cableplug_detected = flg; \
    } while(0)

/** 获取检测到线缆电子标签标志 */
#define ufcs_pe_cableplug_detected_get(dev) \
    (((UFCS_DEV_t *)(dev))->pe.cableplug_detected)

/** 设置供电设备输出过压保护标志 */
#define ufcs_pe_err_info_ovp_set(dev,flg) \
    do { \
        ((UFCS_DEV_t *)(dev))->pe.err_info.ovp = flg; \
    } while(0)

/** 获取供电设备输出过压保护标志 */
#define ufcs_pe_err_info_ovp_get(dev) \
    (((UFCS_DEV_t *)(dev))->pe.err_info.ovp)

/** 设置供电设备输出欠压保护标志 */
#define ufcs_pe_err_info_uvp_set(dev,flg) \
    do { \
        ((UFCS_DEV_t *)(dev))->pe.err_info.uvp = flg; \
    } while(0)

/** 获取供电设备输出欠压保护标志 */
#define ufcs_pe_err_info_uvp_get(dev) \
    (((UFCS_DEV_t *)(dev))->pe.err_info.uvp)

/** 设置供电设备输出过流保护标志 */
#define ufcs_pe_err_info_ocp_set(dev,flg) \
    do { \
        ((UFCS_DEV_t *)(dev))->pe.err_info.ocp = flg; \
    } while(0)

/** 获取供电设备输出过流保护标志 */
#define ufcs_pe_err_info_ocp_get(dev) \
    (((UFCS_DEV_t *)(dev))->pe.err_info.ocp)

/** 设置供电设备输出短路保护标志 */
#define ufcs_pe_err_info_scp_set(dev,flg) \
    do { \
        ((UFCS_DEV_t *)(dev))->pe.err_info.scp = flg; \
    } while(0)

/** 获取供电设备输出短路保护标志 */
#define ufcs_pe_err_info_scp_get(dev) \
    (((UFCS_DEV_t *)(dev))->pe.err_info.scp)

/** 设置供电设备USB接口过温保护标志 */
#define ufcs_pe_err_info_usb_otp_set(dev,flg) \
    do { \
        ((UFCS_DEV_t *)(dev))->pe.err_info.usb_otp = flg; \
    } while(0)

/** 获取供电设备USB接口过温保护标志 */
#define ufcs_pe_err_info_usb_otp_get(dev) \
    (((UFCS_DEV_t *)(dev))->pe.err_info.usb_otp)

/** 设置供电设备内部或电池过温保护标志 */
#define ufcs_pe_err_info_dev_bat_otp_set(dev,flg) \
    do { \
        ((UFCS_DEV_t *)(dev))->pe.err_info.dev_bat_otp = flg; \
    } while(0)

/** 获取供电设备内部或电池过温保护标志 */
#define ufcs_pe_err_info_dev_bat_otp_get(dev) \
    (((UFCS_DEV_t *)(dev))->pe.err_info.dev_bat_otp)

/** 设置供电设备 CC 过压保护标志 */
#define ufcs_pe_err_info_cc_ovp_set(dev,flg) \
    do { \
        ((UFCS_DEV_t *)(dev))->pe.err_info.cc_ovp = flg; \
    } while(0)

/** 获取供电设备 CC 过压保护标志 */
#define ufcs_pe_err_info_cc_ovp_get(dev) \
    (((UFCS_DEV_t *)(dev))->pe.err_info.cc_ovp)

/** 设置供电设备 D-过压保护标志 */
#define ufcs_pe_err_info_dm_ovp_set(dev,flg) \
    do { \
        ((UFCS_DEV_t *)(dev))->pe.err_info.dm_ovp = flg; \
    } while(0)

/** 获取供电设备 D-过压保护标志 */
#define ufcs_pe_err_info_dm_ovp_get(dev) \
    (((UFCS_DEV_t *)(dev))->pe.err_info.dm_ovp)

/** 设置供电设备 D+过压保护标志 */
#define ufcs_pe_err_info_dp_ovp_set(dev,flg) \
    do { \
        ((UFCS_DEV_t *)(dev))->pe.err_info.dp_ovp = flg; \
    } while(0)

/** 获取供电设备 D+过压保护标志 */
#define ufcs_pe_err_info_dp_ovp_get(dev) \
    (((UFCS_DEV_t *)(dev))->pe.err_info.dp_ovp)

/** 设置供电设备输入过压保护标志 */
#define ufcs_pe_err_info_in_ovp_set(dev,flg) \
    do { \
        ((UFCS_DEV_t *)(dev))->pe.err_info.in_ovp = flg; \
    } while(0)

/** 获取供电设备输入过压保护标志 */
#define ufcs_pe_err_info_in_ovp_get(dev) \
    (((UFCS_DEV_t *)(dev))->pe.err_info.in_ovp)

/** 设置供电设备输入欠压保护标志 */
#define ufcs_pe_err_info_in_uvp_set(dev,flg) \
    do { \
        ((UFCS_DEV_t *)(dev))->pe.err_info.in_uvp = flg; \
    } while(0)

/** 获取供电设备输入欠压保护标志 */
#define ufcs_pe_err_info_in_uvp_get(dev) \
    (((UFCS_DEV_t *)(dev))->pe.err_info.in_uvp)

/** 设置供电设备漏电流状态标志 */
#define ufcs_pe_err_info_over_leakage_set(dev,flg) \
    do { \
        ((UFCS_DEV_t *)(dev))->pe.err_info.over_leakage = flg; \
    } while(0)

/** 获取供电设备漏电流状态标志 */
#define ufcs_pe_err_info_over_leakage_get(dev) \
    (((UFCS_DEV_t *)(dev))->pe.err_info.over_leakage)

/** 设置供电设备检测到输入掉电标志 */
#define ufcs_pe_err_info_vbus_lost_set(dev,flg) \
    do { \
        ((UFCS_DEV_t *)(dev))->pe.err_info.vbus_lost = flg; \
    } while(0)

/** 获取供电设备检测到输入掉电标志 */
#define ufcs_pe_err_info_vbus_lost_get(dev) \
    (((UFCS_DEV_t *)(dev))->pe.err_info.vbus_lost)

/** 设置供电设备 CRC 校验错误标志 */
#define ufcs_pe_err_info_crc_set(dev,flg) \
    do { \
        ((UFCS_DEV_t *)(dev))->pe.err_info.crc = flg; \
    } while(0)

/** 获取供电设备 CRC 校验错误标志 */
#define ufcs_pe_err_info_crc_get(dev) \
    (((UFCS_DEV_t *)(dev))->pe.err_info.crc)

/** 设置供电设备通信超时标志 */
#define ufcs_pe_err_info_wdt_set(dev,flg) \
    do { \
        ((UFCS_DEV_t *)(dev))->pe.err_info.wdt = flg; \
    } while(0)

/** 获取供电设备通信超时标志 */
#define ufcs_pe_err_info_wdt_get(dev) \
    (((UFCS_DEV_t *)(dev))->pe.err_info.wdt)

/** 设置供电设备处于恒流模式标志 */
#define ufcs_pe_charger_cc_set(dev,flg) \
    do { \
        ((UFCS_DEV_t *)(dev))->pe.charger_cc = flg; \
    } while(0)

/** 获取供电设备处于恒流模式标志 */
#define ufcs_pe_charger_cc_get(dev) \
    (((UFCS_DEV_t *)(dev))->pe.charger_cc)

/** 设置供电设备处于恒压模式标志 */
#define ufcs_pe_charger_cv_set(dev,flg) \
    do { \
        ((UFCS_DEV_t *)(dev))->pe.charger_cv = flg; \
    } while(0)

/** 获取供电设备处于恒压模式标志 */
#define ufcs_pe_charger_cv_get(dev) \
    (((UFCS_DEV_t *)(dev))->pe.charger_cv)

/** 设置已识别标志标志 */
#define ufcs_pe_identified_set(dev,flg) \
    do { \
        ((UFCS_DEV_t *)(dev))->pe.identified = flg; \
    } while(0)

/** 获取已识别标志标志 */
#define ufcs_pe_identified_get(dev) \
    (((UFCS_DEV_t *)(dev))->pe.identified)

/** 设置请求软件复位标志，设置为1后，系统自动产生软件复位事件 */
#define ufcs_pe_soft_reset_req_set(dev,flg) \
    do { \
        ((UFCS_DEV_t *)(dev))->pe.soft_reset_req = flg; \
    } while(0)

/** 获取请求软件复位标志 */
#define ufcs_pe_soft_reset_req_get(dev) \
    (((UFCS_DEV_t *)(dev))->pe.soft_reset_req)

/** 设置请求硬件复位标志，设置为1后，系统自动产生硬件复位事件 */
#define ufcs_pe_hard_reset_req_set(dev,flg) \
    do { \
        ((UFCS_DEV_t *)(dev))->pe.hard_reset_req = flg; \
    } while(0)

/** 获取请求硬件复位标志 */
#define ufcs_pe_hard_reset_req_get(dev) \
    (((UFCS_DEV_t *)(dev))->pe.hard_reset_req)

/** 设置请求线缆硬件复位标志，设置为1后，系统自动产生硬件复位事件 */
#define ufcs_pe_cable_reset_req_set(dev,flg) \
    do { \
        ((UFCS_DEV_t *)(dev))->pe.cable_reset_req = flg; \
    } while(0)

/** 获取请求线缆硬件复位标志 */
#define ufcs_pe_cable_reset_req_get(dev) \
    (((UFCS_DEV_t *)(dev))->pe.cable_reset_req)

/** 设置请求获取输出模式标志，设置为1后，系统自动发送获取输出模式消息 */
#define ufcs_pe_get_output_cap_req_set(dev,flg) \
    do { \
        ((UFCS_DEV_t *)(dev))->pe.get_output_cap_req = flg; \
    } while(0)

/** 获取请求获取输出模式标志 */
#define ufcs_pe_get_output_cap_req_get(dev) \
    (((UFCS_DEV_t *)(dev))->pe.get_output_cap_req)

/** 设置请求获取供电信息标志，设置为1后，系统自动发送获取供电信息消息 */
#define ufcs_pe_get_src_info_req_set(dev,flg) \
    do { \
        ((UFCS_DEV_t *)(dev))->pe.get_src_info_req = flg; \
    } while(0)

/** 获取请求获取供电信息标志 */
#define ufcs_pe_get_src_info_req_get(dev) \
    (((UFCS_DEV_t *)(dev))->pe.get_src_info_req)

/** 设置请求获取充电信息标志，设置为1后，系统自动发送获取充电信息消息 */
#define ufcs_pe_get_snk_info_req_set(dev,flg) \
    do { \
        ((UFCS_DEV_t *)(dev))->pe.get_snk_info_req = flg; \
    } while(0)

/** 获取请求获取充电信息标志 */
#define ufcs_pe_get_snk_info_req_get(dev) \
    (((UFCS_DEV_t *)(dev))->pe.get_snk_info_req)

/** 设置请求获取线缆信息标志，设置为1后，系统发送获取线缆信息消息 */
#define ufcs_pe_get_cbl_info_req_set(dev,flg) \
    do { \
        ((UFCS_DEV_t *)(dev))->pe.get_cbl_info_req = flg; \
    } while(0)

/** 获取请求获取线缆信息标志 */
#define ufcs_pe_get_cbl_info_req_get(dev) \
    (((UFCS_DEV_t *)(dev))->pe.get_cbl_info_req)

/** 设置请求获取设备信息标志，设置为1后，系统发送获取设备信息消息 */
#define ufcs_pe_get_dev_info_req_set(dev,flg) \
    do { \
        ((UFCS_DEV_t *)(dev))->pe.get_dev_info_req = flg; \
    } while(0)

/** 获取请求获取设备信息标志 */
#define ufcs_pe_get_dev_info_req_get(dev) \
    (((UFCS_DEV_t *)(dev))->pe.get_dev_info_req)

/** 设置请求获取错误信息标志，设置为1后，系统发送获取错误信息消息 */
#define ufcs_pe_get_err_info_req_set(dev,flg) \
    do { \
        ((UFCS_DEV_t *)(dev))->pe.get_err_info_req = flg; \
    } while(0)

/** 获取请求获取错误信息标志 */
#define ufcs_pe_get_err_info_req_get(dev) \
    (((UFCS_DEV_t *)(dev))->pe.get_err_info_req)

/** 设置请求检测线缆信息标志，设置为1后，系统发送请求检测线缆信息消息 */
#define ufcs_pe_det_cbl_info_req_set(dev,flg) \
    do { \
        ((UFCS_DEV_t *)(dev))->pe.det_cbl_info_req = flg; \
    } while(0)

/** 获取请求检测线缆信息标志 */
#define ufcs_pe_det_cbl_info_req_get(dev) \
    (((UFCS_DEV_t *)(dev))->pe.det_cbl_info_req)

/** 设置请求开启线缆检测标志，设置为1后，系统开启线缆检测 */
#define ufcs_pe_start_cbl_det_req_set(dev,flg) \
    do { \
        ((UFCS_DEV_t *)(dev))->pe.start_cbl_det_req = flg; \
    } while(0)

/** 获取请求开启线缆检测标志 */
#define ufcs_pe_start_cbl_det_req_get(dev) \
    (((UFCS_DEV_t *)(dev))->pe.start_cbl_det_req)

/** 设置请求结束线缆检测标志，设置为1后，系统结束线缆检测 */
#define ufcs_pe_end_cbl_det_req_set(dev,flg) \
    do { \
        ((UFCS_DEV_t *)(dev))->pe.end_cbl_det_req = flg; \
    } while(0)

/** 获取请求结束线缆检测标志 */
#define ufcs_pe_end_cbl_det_req_get(dev) \
    (((UFCS_DEV_t *)(dev))->pe.end_cbl_det_req)

/** 设置请求退出UFCS模式标志，设置为1后，系统退出UFCS模式 */
#define ufcs_pe_exit_ufcs_mode_req_set(dev,flg) \
    do { \
        ((UFCS_DEV_t *)(dev))->pe.exit_ufcs_mode_req = flg; \
    } while(0)

/** 获取请求退出UFCS模式标志 */
#define ufcs_pe_exit_ufcs_mode_req_get(dev) \
    (((UFCS_DEV_t *)(dev))->pe.exit_ufcs_mode_req)

/** 设置请求鉴权标志，设置为1后，系统请求鉴权 */
#define ufcs_pe_verify_req_set(dev,flg) \
    do { \
        ((UFCS_DEV_t *)(dev))->pe.verify_req = flg; \
    } while(0)

/** 获取请求鉴权标志 */
#define ufcs_pe_verify_req_get(dev) \
    (((UFCS_DEV_t *)(dev))->pe.verify_req)

/** 设置请求电源调整标志，设置为1后，系统请求电源调整 */
#define ufcs_pe_power_change_req_set(dev,flg) \
    do { \
        ((UFCS_DEV_t *)(dev))->pe.power_change_req = flg; \
    } while(0)

/** 获取请求电源调整标志 */
#define ufcs_pe_power_change_req_get(dev) \
    (((UFCS_DEV_t *)(dev))->pe.power_change_req)

/** 设置请求配置watchdog标志，上层软件设置为1后，系统请求配置watchdog */
#define ufcs_pe_cfg_wdt_req_set(dev,flg) \
    do { \
        ((UFCS_DEV_t *)(dev))->pe.cfg_wdt_req = flg; \
    } while(0)

/** 获取请求配置watchdog标志 */
#define ufcs_pe_cfg_wdt_req_get(dev) \
    (((UFCS_DEV_t *)(dev))->pe.cfg_wdt_req)

/** 设置请求发送ping消息标志，设置为1后，系统请求发送ping消息 */
#define ufcs_pe_ping_req_set(dev,flg) \
    do { \
        ((UFCS_DEV_t *)(dev))->pe.ping_req = flg; \
    } while(0)

/** 获取请求发送ping消息标志 */
#define ufcs_pe_ping_req_get(dev) \
    (((UFCS_DEV_t *)(dev))->pe.ping_req)

/** 设置请求启动测试标志，设置为1后，系统请求启动测试 */
#define ufcs_pe_test_req_set(dev,flg) \
    do { \
        ((UFCS_DEV_t *)(dev))->pe.test_req = flg; \
    } while(0)

/** 获取请求启动测试标志 */
#define ufcs_pe_test_req_get(dev) \
    (((UFCS_DEV_t *)(dev))->pe.test_req)

/** 设置当前工作输出模式位置，1~7 */
#define ufcs_pe_obj_pos_set(dev,flg) \
    do { \
        ((UFCS_DEV_t *)(dev))->pe.obj_pos = flg; \
    } while(0)

/** 获取当前工作输出模式位置标志 */
#define ufcs_pe_obj_pos_get(dev) \
    (((UFCS_DEV_t *)(dev))->pe.obj_pos)

/** 设置输出模式不匹配标志 */
#define ufcs_pe_output_cap_mismatch_set(dev,flg) \
    do { \
        ((UFCS_DEV_t *)(dev))->pe.output_cap_mismatch = flg; \
    } while(0)

/** 获取输出模式不匹配标志 */
#define ufcs_pe_output_cap_mismatch_get(dev) \
    (((UFCS_DEV_t *)(dev))->pe.output_cap_mismatch)

/** 设置请求的输出模式能接受标志 */
#define ufcs_pe_request_can_be_met_set(dev,flg) \
    do { \
        ((UFCS_DEV_t *)(dev))->pe.request_can_be_met = flg; \
    } while(0)

/** 获取请求的输出模式能接受标志 */
#define ufcs_pe_request_can_be_met_get(dev) \
    (((UFCS_DEV_t *)(dev))->pe.request_can_be_met)

/** 设置请求的输出模式不能接受标志 */
#define ufcs_pe_request_cant_be_met_set(dev,flg) \
    do { \
        ((UFCS_DEV_t *)(dev))->pe.request_cant_be_met = flg; \
    } while(0)

/** 获取请求的输出模式不能接受标志 */
#define ufcs_pe_request_cant_be_met_get(dev) \
    (((UFCS_DEV_t *)(dev))->pe.request_cant_be_met)

/** 设置电源供电准备好了标志 */
#define ufcs_pe_power_supply_ready_set(dev,flg) \
    do { \
        ((UFCS_DEV_t *)(dev))->pe.power_supply_ready = flg; \
    } while(0)

/** 获取电源供电准备好了标志 */
#define ufcs_pe_power_supply_ready_get(dev) \
    (((UFCS_DEV_t *)(dev))->pe.power_supply_ready)

/** 设置当前工作电流值，单位 mA */
#define ufcs_pe_opr_curr_set(dev,flg) \
    do { \
        ((UFCS_DEV_t *)(dev))->pe.opr_curr = flg; \
    } while(0)

/** 获取当前工作电流值，单位 mA */
#define ufcs_pe_opr_curr_get(dev) \
    (((UFCS_DEV_t *)(dev))->pe.opr_curr)

/** 设置当前工作电压，单位 mA */
#define ufcs_pe_opr_volt_set(dev,flg) \
    do { \
        ((UFCS_DEV_t *)(dev))->pe.opr_volt = flg; \
    } while(0)

/** 获取当前工作电压，单位 mA */
#define ufcs_pe_opr_volt_get(dev) \
    (((UFCS_DEV_t *)(dev))->pe.opr_volt)


/** 获取接收到的请求数据输出电流，单位 10mA */
#define ufcs_pe_req_curr_get(dev) \
    (((UFCS_DEV_t *)(dev))->pe.req_curr)

/** 获取接收到的请求数据输出电压，单位 10mV */
#define ufcs_pe_req_volt_get(dev) \
    (((UFCS_DEV_t *)(dev))->pe.req_volt)

/** 设置当前设备温度，单位 摄氏度 */
#define ufcs_pe_dev_temperature_set(dev,flg) \
    do { \
        ((UFCS_DEV_t *)(dev))->pe.dev_temperature = flg; \
    } while(0)

/** 获取当前设备温度，单位 摄氏度 */
#define ufcs_pe_dev_temperature_get(dev) \
    (((UFCS_DEV_t *)(dev))->pe.dev_temperature)

/** 设置当前USB接口温度，单位 摄氏度 */
#define ufcs_pe_usb_temperature_set(dev,flg) \
    do { \
        ((UFCS_DEV_t *)(dev))->pe.usb_temperature = flg; \
    } while(0)

/** 获取当前USB接口温度，单位 摄氏度 */
#define ufcs_pe_usb_temperature_get(dev) \
    (((UFCS_DEV_t *)(dev))->pe.usb_temperature)


/** 设置对端设备的当前设备温度，单位 摄氏度 */
#define ufcs_pe_partner_dev_temperature_set(dev,flg) \
    do { \
        ((UFCS_DEV_t *)(dev))->pe.partner_dev_temperature = flg; \
    } while(0)

/** 获取对端设备的当前设备温度，单位 摄氏度 */
#define ufcs_pe_partner_dev_temperature_get(dev) \
    (((UFCS_DEV_t *)(dev))->pe.partner_dev_temperature)

/** 设置对端设备的当前USB接口温度，单位 摄氏度 */
#define ufcs_pe_partner_usb_temperature_set(dev,flg) \
    do { \
        ((UFCS_DEV_t *)(dev))->pe.partner_usb_temperature = flg; \
    } while(0)

/** 获取对端设备的当前USB接口温度，单位 摄氏度 */
#define ufcs_pe_partner_usb_temperature_get(dev) \
    (((UFCS_DEV_t *)(dev))->pe.partner_usb_temperature)


/** 设置接收到的输出模式数量 */
#define ufcs_pe_rx_output_num_set(dev,val) \
    do { \
        ((UFCS_DEV_t *)(dev))->pe.rx_output_num = val; \
    } while(0)

/** 获取接收到的输出模式数量 */
#define ufcs_pe_rx_output_num_get(dev) \
    (((UFCS_DEV_t *)(dev))->pe.rx_output_num)

/** 设置接收到的输出模式数据对象 */
#define ufcs_pe_rx_output_set(dev,idx,obj) \
    do { \
        ((UFCS_DEV_t *)(dev))->pe.rx_pwr.rx_output.caps[idx] = (UFCS_DATA_MSG_OUTPUT_CAP_t)(obj); \
    } while(0)

/** 获取接收到的输出模式数据对象 */
#define ufcs_pe_rx_output_get(dev,idx) \
    (((UFCS_DEV_t *)(dev))->pe.rx_pwr.rx_output.caps[idx])

/** 获取接收到的输出模式的最小输出电流，单位 10mA */
#define ufcs_pe_rx_output_min_curr_get(dev,idx) \
    (((UFCS_DEV_t *)(dev))->pe.rx_pwr.rx_output.caps[idx].min_curr)

/** 获取接收到的输出模式的最大输出电流，单位 10mA */
#define ufcs_pe_rx_output_max_curr_get(dev,idx) \
    (((UFCS_DEV_t *)(dev))->pe.rx_pwr.rx_output.caps[idx].max_curr)

/** 获取接收到的输出模式的最小输出电压，单位 10mV */
#define ufcs_pe_rx_output_min_volt_get(dev,idx) \
    ((((UFCS_DEV_t *)(dev))->pe.rx_pwr.rx_output.caps[idx].min_volt_l) + ((((UFCS_DEV_t *)(dev))->pe.rx_pwr.rx_output.caps[idx].min_volt_h) << 8))

/** 获取接收到的输出模式的最小输出电压低字节，单位 10mV */
#define ufcs_pe_rx_output_min_volt_l_get(dev,idx) \
    (((UFCS_DEV_t *)(dev))->pe.rx_pwr.rx_output.caps[idx].min_volt_l)

/** 获取接收到的输出模式的最小输出电压高字节，单位 10mV */
#define ufcs_pe_rx_output_min_volt_h_get(dev,idx) \
    (((UFCS_DEV_t *)(dev))->pe.rx_pwr.rx_output.caps[idx].min_volt_h)

/** 获取接收到的输出模式的最大输出电压，单位 10mV */
#define ufcs_pe_rx_output_max_volt_get(dev,idx) \
    (((UFCS_DEV_t *)(dev))->pe.rx_pwr.rx_output.caps[idx].max_volt)

/** 获取接收到的输出模式的电压调节最小步进: 0b：10mV, 1b：20mV */
#define ufcs_pe_rx_output_volt_step_type_get(dev,idx) \
    (((UFCS_DEV_t *)(dev))->pe.rx_pwr.rx_output.caps[idx].volt_step_type)

/** 获取接收到的输出模式的电流调节最小步进：000b：10mA，001b：20mA，010b：30mA，011b：40mA，100b：50mA，其它：保留 */
#define ufcs_pe_rx_output_curr_step_type_get(dev,idx) \
    (((UFCS_DEV_t *)(dev))->pe.rx_pwr.rx_output.caps[idx].curr_step_type)

/** 获取接收到的输出模式编号 */
#define ufcs_pe_rx_output_index_get(dev,idx) \
    (((UFCS_DEV_t *)(dev))->pe.rx_pwr.rx_output.caps[idx].index)


/** 设置接收到的请求输出模式数据对象 */
#define ufcs_pe_rx_request_set(dev,obj) \
    do { \
        ((UFCS_DEV_t *)(dev))->pe.rx_pwr.rx_request = (UFCS_DATA_MSG_REQUEST_t)(obj); \
    } while(0)

/** 获取接收到的请求输出模式数据对象 */
#define ufcs_pe_rx_request_get(dev) \
    (((UFCS_DEV_t *)(dev))->pe.rx_pwr.rx_request)

/** 获取接收到的请求数据输出电流，单位 10mA */
#define ufcs_pe_rx_request_req_curr_get(dev) \
    (((UFCS_DEV_t *)(dev))->pe.rx_pwr.rx_request.req_curr)

/** 获取接收到的请求数据输出电压，单位 10mV */
#define ufcs_pe_rx_request_req_volt_get(dev) \
    (((UFCS_DEV_t *)(dev))->pe.rx_pwr.rx_request.req_volt)

/** 获取接收到的请求数据的输出模式编号 */
#define ufcs_pe_rx_request_index_get(dev) \
    (((UFCS_DEV_t *)(dev))->pe.rx_pwr.rx_request.index)


/** 获取接收到的线缆消息最大承载电流，单位 1A */
#define ufcs_pe_rx_cbl_max_curr_get(dev) \
    (((UFCS_DEV_t *)(dev))->pe.cbl_max_curr)

/** 获取接收到的线缆消息最大承载电压，单位 1V */
#define ufcs_pe_rx_cbl_max_volt_get(dev) \
    (((UFCS_DEV_t *)(dev))->pe.cbl_max_volt)

/** 获取接收到的线缆消息的线缆阻抗，单位 mOh */
#define ufcs_pe_rx_cbl_impedance_get(dev) \
    (((UFCS_DEV_t *)(dev))->pe.cbl_impedance)

/** 设置已识别开始时间 */
#define ufcs_pe_identified_time_set(dev,val) \
    do { \
        ((UFCS_DEV_t *)(dev))->pe.identified_time = val; \
    } while(0)

/** 获取已识别开始时间 */
#define ufcs_pe_identified_time_get(dev) \
    (((UFCS_DEV_t *)(dev))->pe.identified_time)

/** 设置无信号识别开始时间 */
#define ufcs_pe_no_identified_time_set(dev,val) \
    do { \
        ((UFCS_DEV_t *)(dev))->pe.no_identified_time = val; \
    } while(0)

/** 获取无信号识别开始时间 */
#define ufcs_pe_no_identified_time_get(dev) \
    (((UFCS_DEV_t *)(dev))->pe.no_identified_time)

/** 设置电源供电准备好开始时间 */
#define ufcs_pe_ps_ready_time_set(dev,val) \
    do { \
        ((UFCS_DEV_t *)(dev))->pe.ps_ready_time = val; \
    } while(0)

/** 获取电源供电准备好开始时间 */
#define ufcs_pe_ps_ready_time_get(dev) \
    (((UFCS_DEV_t *)(dev))->pe.ps_ready_time)

/** 获取接收到不期望的消息标志 */
#define ufcs_pe_unexpected_msg_received(dev) \
    (((UFCS_DEV_t *)(dev))->pe.unexpected_msg_received)

/** 设置接收到不期望的消息标志 */
#define ufcs_pe_unexpected_msg_received_set(dev,flg) \
    do { \
        ((UFCS_DEV_t *)(dev))->pe.unexpected_msg_received = flg; \
    } while(0)

/** 获取接收到不支持的消息标志 */
#define ufcs_pe_unsupported_msg_received(dev) \
    (((UFCS_DEV_t *)(dev))->pe.unsupported_msg_received)

/** 设置接收到不支持的消息标志 */
#define ufcs_pe_unsupported_msg_received_set(dev,flg) \
    do { \
        ((UFCS_DEV_t *)(dev))->pe.unsupported_msg_received = flg; \
    } while(0)

/** 获取接收到不认识的消息标志 */
#define ufcs_pe_unrecognized_msg_received(dev) \
    (((UFCS_DEV_t *)(dev))->pe.unrecognized_msg_received)

/** 设置接收到不认识的消息标志 */
#define ufcs_pe_unrecognized_msg_received_set(dev,flg) \
    do { \
        ((UFCS_DEV_t *)(dev))->pe.unrecognized_msg_received = flg; \
    } while(0)

/** 获取进入可打断的AMS操作标志 */
#define ufcs_pe_interruptible_AMS_entered_get(dev) \
    (((UFCS_DEV_t *)(dev))->pe.interruptible_AMS_entered)
/** 设置进入可打断的AMS操作标志 */
void ufcs_pe_interruptible_AMS_entered_set(UFCS_DEV_t *dev, bool_t st);

/** 获取进入不可打断的AMS操作标志 */
#define ufcs_pe_non_interruptible_AMS_entered_get(dev) \
    (((UFCS_DEV_t *)(dev))->pe.non_interruptible_AMS_entered)
/** 设置进入不可打断的AMS操作标志 */
void ufcs_pe_non_interruptible_AMS_entered_set(UFCS_DEV_t *dev, bool_t st);

/** 获取硬件复位正在操作中 */
#define ufcs_pe_hard_reset_in_prog_get(dev) \
    (((UFCS_DEV_t *)(dev))->pe.hrst_in_prog)
/** 设置硬件复位正在操作中标志 */
#define ufcs_pe_hard_reset_in_prog_set(dev,flg) \
    do { \
        ((UFCS_DEV_t *)(dev))->pe.hrst_in_prog = flg; \
    } while(0)

/** 设置接收到从PHY来的线缆复位信号标志 */
#define ufcs_pe_cable_rst_in_prog_set(dev,flg) \
    do { \
        ((UFCS_DEV_t *)(dev))->pe.cable_rst_in_prog = flg; \
    } while(0)

/** 获取接收到从PHY来的线缆复位信号标志 */
#define ufcs_pe_cable_rst_in_prog_get(dev) \
    (((UFCS_DEV_t *)(dev))->pe.cable_rst_in_prog)

/** 获取看门狗使能接口，返回值为0时看门狗关闭，非零则看门狗使能并且为看门狗的超时时间，单位为毫秒 */
#define ufcs_pe_wdt_get(dev) \
    (((UFCS_DEV_t *)(dev))->pe.wdt.wdt_timeout)

/** 设置看门狗接口，value为0时关闭看门狗，非零则使能并且值为看门狗超时时间，单位为毫秒 */
#define ufcs_pe_wdt_set(dev,value) \
    do { \
        ((UFCS_DEV_t *)(dev))->pe.wdt.wdt_timeout = value; \
    } while(0)

void ufcs_pe_state_init(UFCS_DEV_t *dev);
void ufcs_pe_timer_release(UFCS_DEV_t *dev);
void ufcs_pe_txmsg_req(UFCS_DEV_t *dev, u32_t msg_type);
void ufcs_pe_txmsg_req_ex(UFCS_DEV_t *dev, u32_t msg_type, u32_t sop_type);
u32_t ufcs_pe_vbus_volt_get(UFCS_DEV_t *dev);
bool_t ufcs_pe_vbus_detected(UFCS_DEV_t *dev);
bool_t ufcs_pe_vbus_volt_check(UFCS_DEV_t *dev, u32_t ref_volt);
u32_t ufcs_pe_cbl_impedance_calc(UFCS_DEV_t *dev);
u32_t ufcs_pe_cbl_max_curr_get(UFCS_DEV_t *dev);
void ufcs_pe_src_startup(UFCS_DEV_t *dev);
void ufcs_pe_snk_startup(UFCS_DEV_t *dev);
void ufcs_pe_src_ready(UFCS_DEV_t *dev);
void ufcs_pe_snk_ready(UFCS_DEV_t *dev);
void ufcs_pe_state_machine(UFCS_DEV_t *dev);
void ufcs_pe_cbl_state_machine(UFCS_DEV_t *dev);
void ufcs_rx_high_handler(u32_t arg);
void ufcs_rx_low_handler(u32_t arg);
void ufcs_rx_int_init(UFCS_DEV_t *dev, bool_t type);

#endif /* #ifndef __UFCS_PE_H_ */

