/**
 * \file    dpm_cc.h
 * \brief   DPM configuration channel
 *
 * \par     Copyright (c) 2018 UWE Technologies Corp., Ltd. All Rights Reserved.
 * \author  James
 * \date    2018-03-16
 * \version 
 * 
 * \history 
 *  Date        Note
 *  2018-03-16  Original Creation
 * 
 */
 
#ifndef __DPM_CC_H_
#define __DPM_CC_H_


#include "libc.h"
#include "drivers.h"
#include "reg_def_pd.h"
#include "usbpd_timer_defs.h"
#include "usbpd_hook.h"

#pragma pack(1)

/** \name Type-C Connection State definitions
 * \{ 
 */

#define DPM_CC_DISABLED         0x00
#define DPM_CC_ERR_RECOVERY     0x01
#define DPM_CC_UNATTACHED_SNK   0x02
#define DPM_CC_ATTACHWAIT_SNK   0x03
#define DPM_CC_ATTACHED_SNK     0x04
#define DPM_CC_UNATTACHED_SRC   0x05
#define DPM_CC_ATTACHWAIT_SRC   0x06
#define DPM_CC_ATTACHED_SRC     0x07
#define DPM_CC_TRY_SRC          0x08
#define DPM_CC_TRYWAIT_SNK      0x09
#define DPM_CC_UNATTACHED_ACCY  0x0A
#define DPM_CC_ATTACHWAIT_ACCY  0x0B
#define DPM_CC_AUDIO_ACCY       0x0C
#define DPM_CC_DEBUG_ACCY       0x0D
#define DPM_CC_POWERED_ACCY     0x0E
#define DPM_CC_UNSP_ACCY        0x0F
#define DPM_CC_PWR_DEF_SNK      0x10
#define DPM_CC_PWR_1_5_SNK      0x11
#define DPM_CC_PWR_3_0_SNK      0x12
#define DPM_CC_TRY_SNK          0x13

/** \}*/

/** \name Type-C Connection Sub State definitions
 * \{ 
 */
#define DPM_CC_SUB_PWR_DEF_SNK  0x01
#define DPM_CC_SUB_PWR_1_5_SNK  0x02
#define DPM_CC_SUB_PWR_3_0_SNK  0x03

/** \}*/

#if SYS_CC_READ_ADC_WITH_MASK
#define DPM_CC_READING_THRESHOLD_1      1
#define DPM_CC_READING_THRESHOLD_2      2
#define DPM_CC_READING_THRESHOLD_3      3
#endif /* SYS_CC_READ_ADC_WITH_MASK */

#define DPM_CC_READING_COUNT            6
#define DPM_CC_IDLE_READING_COUNT       3


typedef struct dpm_cc_state_info_s
{
    u32_t state:4; ///< CC state
    u32_t state_prev:4; ///< CC previous state
    u32_t presently_vconn_source:1;
    u32_t sub_state:2;
#if SYS_CC_READ_ADC_WITH_MASK  /* modified by James Gan - 2018-08-02 */
    u32_t resv:1;
    u32_t cc1_adc_rslt_curr:12;
    u32_t cc2_adc_rslt_curr:12;

    u32_t cc_adc_reading_cnt:8;
    u32_t cc1_adc_rslt_last1:12;
    u32_t cc1_adc_rslt_last2:12;

    u32_t cc2_adc_rslt_last1:12;
    u32_t cc2_adc_rslt_last2:12;
    u32_t resv2:4;
#else
    u32_t resv:21;
#endif /* #if SYS_CC_READ_ADC_WITH_MASK */

    sys_tick_t connection_changed_time;

    drv_timer_t cc_debounce_timer;
    drv_timer_t drp_timer;
    drv_timer_t drp_try_timer;
    drv_timer_t error_recovery_timer;
    drv_timer_t pd_debounce_timer;
    drv_timer_t try_timeout_timer;
    drv_timer_t sink_disconnect_timer;

} dpm_cc_state_info_t;

#pragma pack()

/** DPM CC state information */
extern volatile dpm_cc_state_info_t g_dpm_cc_state_info;


#define dpm_cc_attached() \
    ((DPM_CC_ATTACHED_SRC == g_dpm_cc_state_info.state) || (DPM_CC_ATTACHED_SNK == g_dpm_cc_state_info.state))

#define dpm_cc_unattached() \
    ((DPM_CC_ATTACHED_SRC != g_dpm_cc_state_info.state) && (DPM_CC_ATTACHED_SNK != g_dpm_cc_state_info.state))

#define dpm_cc_state_get() \
    (g_dpm_cc_state_info.state)

#define dpm_cc_state_set(v) \
    do { \
        g_dpm_cc_state_info.state_prev = g_dpm_cc_state_info.state; \
        g_dpm_cc_state_info.state = v; \
    } while(0)

#define dpm_cc_state_prev_get() \
    (g_dpm_cc_state_info.state_prev)

#define dpm_cc_state_prev_set(v) \
    do { \
        g_dpm_cc_state_info.state_prev = v; \
    } while(0)

#define dpm_presently_vconn_source_set(en) \
    do { \
        g_dpm_cc_state_info.presently_vconn_source = en; \
    } while(0)

#define dpm_presently_vconn_source_get() \
    (g_dpm_cc_state_info.presently_vconn_source)

#define dpm_cc_sub_state_get() \
    (g_dpm_cc_state_info.sub_state)

#define dpm_cc_sub_state_set(v) \
    do { \
        g_dpm_cc_state_info.sub_state = v; \
    } while(0)


#if SYS_CC_READ_ADC_WITH_MASK

#define dpm_cc1_adc_rslt_curr_set(v) \
    do { \
        g_dpm_cc_state_info.cc1_adc_rslt_curr = v; \
    } while(0)

#define dpm_cc1_adc_rslt_curr_get() \
    (g_dpm_cc_state_info.cc1_adc_rslt_curr)


#define dpm_cc2_adc_rslt_curr_set(v) \
    do { \
        g_dpm_cc_state_info.cc2_adc_rslt_curr = v; \
    } while(0)

#define dpm_cc2_adc_rslt_curr_get() \
    (g_dpm_cc_state_info.cc2_adc_rslt_curr)


#define dpm_cc_adc_reading_cnt_set(v) \
    do { \
        g_dpm_cc_state_info.cc_adc_reading_cnt = v; \
    } while(0)

#define dpm_cc_adc_reading_cnt_inc() \
    do { \
        g_dpm_cc_state_info.cc_adc_reading_cnt++; \
    } while(0)

#define dpm_cc_adc_reading_cnt_get() \
    (g_dpm_cc_state_info.cc_adc_reading_cnt)


#define dpm_cc1_adc_rslt_last1_set(v) \
    do { \
        g_dpm_cc_state_info.cc1_adc_rslt_last1 = v; \
    } while(0)

#define dpm_cc1_adc_rslt_last1_get() \
    (g_dpm_cc_state_info.cc1_adc_rslt_last1)


#define dpm_cc1_adc_rslt_last2_set(v) \
    do { \
        g_dpm_cc_state_info.cc1_adc_rslt_last2 = v; \
    } while(0)

#define dpm_cc1_adc_rslt_last2_get() \
    (g_dpm_cc_state_info.cc1_adc_rslt_last2)


#define dpm_cc2_adc_rslt_last1_set(v) \
    do { \
        g_dpm_cc_state_info.cc2_adc_rslt_last1 = v; \
    } while(0)

#define dpm_cc2_adc_rslt_last1_get() \
    (g_dpm_cc_state_info.cc2_adc_rslt_last1)


#define dpm_cc2_adc_rslt_last2_set(v) \
    do { \
        g_dpm_cc_state_info.cc2_adc_rslt_last2 = v; \
    } while(0)

#define dpm_cc2_adc_rslt_last2_get() \
    (g_dpm_cc_state_info.cc2_adc_rslt_last2)

#endif /* SYS_CC_READ_ADC_WITH_MASK */


#define dpm_cc_connection_changed_time_get() \
    (g_dpm_cc_state_info.connection_changed_time)

#define dpm_cc_connection_changed_time_set(v) \
    do { \
        g_dpm_cc_state_info.connection_changed_time = v; \
    } while(0)


#define dpm_vconn_en_cc1_set(flg) \
    do { \
        usbpd_hook(cc1_vconn_en,flg); \
    } while(0)

#define dpm_vconn_en_cc2_set(flg) \
    do { \
        usbpd_hook(cc2_vconn_en,flg); \
    } while(0)

#define dpm_vconn_en_cc1_get() \
    (usbpd_hook_with_return(cc1_vconn_en))

#define dpm_vconn_en_cc2_get() \
    (usbpd_hook_with_return(cc2_vconn_en))


void dpm_cc_update_adc();
bool_t dpm_cc_source_detected();
bool_t dpm_cc_connection_detected();
void dpm_cc_state_to_attached_snk();
void dpm_cc_state_cable_plug_detect();
void dpm_cc_state_to_attached_src();
void dpm_cc_state_init();
void dpm_cc_state_release();
void dpm_cc_state_machine();


#endif /* #ifndef __DPM_CC_H_ */

