/******************************************************************************
文 件 名：DoCAN_ISO15765.h
功能描述：ISO 15765 规范规定的诊断服务函数头文件
作    者：张暄
版    本：V1.0
日    期：2016.7.18
******************************************************************************/

/******************************************************************************
                         诊断服务的OSI模型映射
===============================================================================
  *     NO.     OSI Layer        Diagnostics services
-------------------------------------------------------------------------------
         7      Application      ISO 14229-1 ISO 14229-3
         6      Presentation     -
         5      Session          ISO 14229-2
  *      4      Transport        ISO 15765-2
  *      3      Network          ISO 15765-2
         2      Data Link        ISO 11898
         1      Physical         ISO 11898
===============================================================================
******************************************************************************/

#ifndef _DOCAN_ISO15765_H_
#define _DOCAN_ISO15765_H_

#include "TYW_stdint.h"

#include "DoCAN_ISO15765_Config.h"
#include "RTE_CAN.h"
/*-----------------------------------------------------------------------------
Transfer_Status
-----------------------------------------------------------------------------*/
#ifndef   DIAG_COMPLETE
#define DIAG_COMPLETE                 0x01u
#endif

#ifndef   DIAG_NOT_COMPLETE
#define   DIAG_NOT_COMPLETE           (!DIAG_COMPLETE)
#endif

/*-----------------------------------------------------------------------------
N_PDU 名称
-----------------------------------------------------------------------------*/
#define SINGLE_FRAME               0x00u
#define FIRST_FRAME                0x01u
#define CONSECUTIVE_FRAME          0x02u
#define FLOW_CONTROL               0x03u

/*-----------------------------------------------------------------------------
流控帧类型
-----------------------------------------------------------------------------*/
#define FC_FS_CTS                  0x00u
#define FC_FS_WAIT                 0x01u
#define FC_FS_OVFL                 0x02u

/*-----------------------------------------------------------------------------
时序参数名称
-----------------------------------------------------------------------------*/
#define TIMING_PARA_NONE           0X00u
#define TIMING_PARA_N_As           0X01u
#define TIMING_PARA_N_Ar           0X02u
#define TIMING_PARA_N_Bs           0X03u
#define TIMING_PARA_N_Br           0X04u
#define TIMING_PARA_N_Cs           0X05u
#define TIMING_PARA_N_Cr           0X06u

/*-----------------------------------------------------------------------------
STmin计时状态
-----------------------------------------------------------------------------*/
#define STmin_TIMER_IDLE           0X00u         /*STmin定时器空闲*/
#define STmin_TIME_UP              0X01u         /*STmin定时时间到*/
#define STmin_TIMING               0X02u         /*STmin定时器计时中*/

/*-----------------------------------------------------------------------------
传输层收发控制
-----------------------------------------------------------------------------*/
#define TP_DIR_MASK                0x80u         /*收发标志位*/
#define TP_RX                      0x00u         /*传输层接收状态*/
#define TP_TX                      0x80u         /*传输层发送状态*/

#define TP_IDLE                    0x00u         /*Rx：空闲状态*/
/*Tx：空闲状态*/
#define TP_ERR                     0x01u         /*Rx：接收系统错误*/
/*Tx：发送系统错误*/

#define TP_RX_INIT                 0x10u         /*Rx：已接收到首帧,初始化多帧接收*/
#define TP_TX_INIT                 0x90u         /*Tx：发送初始化完成,正在发送首帧或单帧(注意单帧也使用此标志)*/
#define TP_RX_CTS                  0x11u         /*Rx：接收机允许发送机发送连续帧(Clear To Send)*/
#define TP_TX_CTS                  0x91u         /*Tx：发送机被许可发送连续帧(Clear To Send)*/

#define TP_RX_RTS                  0x20u         /*Rx：请求继续发送多帧(Request To Send)*/
#define TP_TX_RTS                  0xA0u         /*Tx：等待接收机许可多帧发送(Request To Send)*/
#define TP_RX_WAIT                 0x21u         /*Rx：请求发送机暂停发送*/
#define TP_TX_WAIT                 0xA1u         /*Tx：接收机请求等待*/
#define TP_RX_OVFL                 0x22u         /*Rx：接收机接收溢出*/
#define TP_TX_OVFL                 0xA2u         /*Tx：接收机接收溢出*/

/******************************************************************************
结构体声明
******************************************************************************/

/*** 链路层数据帧结构 ***/
typedef struct
{
    uint32_t            Identifier;          /*帧ID*/
    uint8_t             Data[8];             /*帧数据*/
    uint8_t             DLC;                 /*帧长度*/
} LinkDataStruct;

/*** 链路层接收FIFO结构 ***/
typedef struct
{
    LinkDataStruct      LinkData[LINK_RX_FIFO_MAX_DEPTH];
    uint8_t             Depth;        /*FIFO深度*/
    uint8_t             IPtr;         /*输入指针*/
    uint8_t             OPtr;         /*输出指针*/
} LinkRxFIFOStruct;

/*** 链路层发送控制结构 ***/
typedef struct
{
    uint32_t            Identifier; /*帧ID*/
    uint8_t             Data[8];    /*帧数据*/
    uint8_t             Busy;       /*发送器忙标志*/
} LinkTxCtrlStruct;

/*---------------------------------------------------------------------------*/

/*** 传输层数据帧结构 ***/
typedef struct
{
    uint32_t            Identifier;
    uint8_t             Data[8];
    uint8_t             DLC;
    uint8_t             New;
} TP_Data_Struct;


/*** 通用N_PCI解析结构 ***/
typedef struct
{
    uint8_t  Rsvd      :  4;
    uint8_t  Type      :  4;
} TP_N_PCI_Struct;

/*** 通用N_PDU解析结构 ***/
typedef struct
{
    uint32_t            N_TAtype;
    TP_N_PCI_Struct     N_PCI;
    uint8_t             N_Data[7];
    uint8_t             DLC;
    uint8_t             New;
} TP_N_PDU_Struct;


/*** 单帧N_PCI解析结构 ***/
typedef struct
{
    uint8_t  SF_DL     :  4;
    uint8_t  Type      :  4;
} TP_SF_N_PCI_Struct;

/*** 单帧N_PDU解析结构 ***/
typedef struct
{
    uint32_t            N_TAtype;
    TP_SF_N_PCI_Struct  N_PCI;
    uint8_t             N_Data[7];
    uint8_t             DLC;
    uint8_t             New;
} TP_N_PDU_SF_Struct;


/*** 首帧N_PCI解析结构 ***/
typedef struct
{
    uint8_t  FF_DL_H   :  4;
    uint8_t  Type      :  4;
    uint16_t FF_DL_L   :  8;
} TP_FF_N_PCI_Struct;

/*** 首帧N_PDU解析结构 ***/
typedef struct
{
    uint32_t            N_TAtype;
    TP_FF_N_PCI_Struct  N_PCI;
    uint8_t             N_Data[6];
    uint8_t             DLC;
    uint8_t             New;
} TP_N_PDU_FF_Struct;


/*** 连续帧N_PCI解析结构 ***/
typedef struct
{
    uint8_t  SN        :  4;
    uint8_t  Type      :  4;
} TP_CF_N_PCI_Struct;

/*** 连续帧N_PDU解析结构 ***/
typedef struct
{
    uint32_t            N_TAtype;
    TP_CF_N_PCI_Struct  N_PCI;
    uint8_t             N_Data[7];
    uint8_t             DLC;
    uint8_t             New;
} TP_N_PDU_CF_Struct;


/*** 流控帧N_PCI解析结构 ***/
typedef struct
{
    uint8_t  FS        :  4;
    uint8_t  Type      :  4;
    uint8_t  BS        :  8;
    uint8_t  STmin     :  8;
} TP_FC_N_PCI_Struct;

/*** 流控帧N_PDU解析结构 ***/
typedef struct
{
    uint32_t            N_TAtype;
    TP_FC_N_PCI_Struct  N_PCI;
    uint8_t             N_Data[5];
    uint8_t             DLC;
    uint8_t             New;
} TP_N_PDU_FC_Struct;


/*** 传输层数据解析联合体 ***/
typedef union
{
    TP_Data_Struct      Frame;
    TP_N_PDU_Struct     N_PDU;
    TP_N_PDU_SF_Struct  N_PDU_SF;
    TP_N_PDU_FF_Struct  N_PDU_FF;
    TP_N_PDU_CF_Struct  N_PDU_CF;
    TP_N_PDU_FC_Struct  N_PDU_FC;
} TransportDataUnion;


/*** 传输层收发控制结构 ***/
typedef struct
{
    uint8_t             Process;      /*当前收发进程*/
    uint8_t             NonStopMode;  /*不间断收发模式(不再理会后续的FC帧)*/
    uint16_t            Len;          /*已接收到或已发送出的数据长度*/
    uint16_t            TotalLen;     /*数据总长*/
    uint16_t            BlockSize;    /*Block总数*/
    uint16_t            BlockCnt;     /*已接收到或已发送出的Block数*/
    uint8_t             BSMax;        /*当前接收机剩余的最大Block数*/
    uint8_t             WFTCnt;       /*[仅接收用]等待次数计数*/
    uint8_t             STmin;        /*[仅发送用]当前接收机要求的最小间隔时间*/
    uint8_t             TxReq;        /*[仅发送用]发送请求*/
} TransportControlStruct;

/*** 时序控制结构 ***/
typedef struct
{
    uint16_t            Cnt;          /*滚动计数器*/
    uint16_t            LastCnt;      /*上次更新时的滚动计数器*/
    uint32_t            NTimer;       /*时序定时器,单位：us*/
    uint32_t            STimer;       /*最小间隔时间(STmin)定时器,单位：us*/
    uint8_t             Type;         /*当前定时器计时参数名称*/
    uint8_t             STminStatus;  /*STmin计时状态*/
} TransportTimingControlStruct;

/*---------------------------------------------------------------------------*/

/*** 数据收发结果N_Result枚举 ***/
typedef enum
{
    N_OK = 0,
    N_TIMEOUT_A,
    N_TIMEOUT_Bs,
    N_TIMEOUT_Cr,
    N_WRONG_SN,
    N_INVALID_FS,
    N_UNEXP_PDU,
    N_WFT_OVRN,
    N_BUFFER_OVFLW,
    N_ERROR,
} N_ResultEnum;

/*** 接收用N_USData数据结构 ***/
typedef struct
{
    uint32_t            N_TAtype;
    uint16_t            Length;
    uint8_t             MsgData[N_USDATA_RX_BUFFER_SIZE];
} N_USDataRxStruct;

/*** 发送用N_USData数据结构 ***/
typedef struct
{
    uint32_t            N_TAtype;
    uint16_t            Length;
    uint8_t             MsgData[N_USDATA_TX_BUFFER_SIZE];
} N_USDataTxStruct;

extern TransportTimingControlStruct  TpTimingCtrl;

/******************************************************************************
函数声明
******************************************************************************/

/*-- 外部接口函数 -----------------------------------------------------------*/

/*** 后台服务函数 ***/
void DoCAN_Communication_Service ( void );
extern void DoCAN_Timer_Update ( uint16_t Interval );

/*** 网络层上层接口函数 ***/
void DoCAN_N_USData_Request( uint32_t N_TAtype, uint8_t MessageData[], uint16_t Length );
void DoCAN_N_USData_Confirm ( uint32_t N_TAtype, N_ResultEnum N_Result );
void DoCAN_N_USData_FF_Indication( uint32_t N_TAtype, uint16_t Length );
void DoCAN_N_USData_Indication( uint32_t N_TAtype, uint8_t *MessageData, uint16_t Length, N_ResultEnum N_Result );

/*** 链路层下层接口函数 ***/
void DoCAN_L_Data_Request ( uint32_t Identifier, uint8_t dlc, uint8_t Data[] );
void DoCAN_L_Data_Confirm ( uint32_t Identifier, uint8_t TransferStatus );
extern void DoCAN_L_Data_Indication ( uint32_t Identifier, uint8_t dlc, uint8_t pData[] );

extern void CAN_LLC_Ch5_Data_Request ( uint32_t Identifier, uint8_t DLC, uint8_t *Data );

/*-- 内部函数 ---------------------------------------------------------------*/

/*** 传输层协议解析 ***/
void DoCAN_Receive_And_Assemble_N_USData ( void );      /*接收主函数*/
void DoCAN_Get_N_PDU ( void );
void DoCAN_Receive_Single_Frame_N_Data ( void );
void DoCAN_Receive_First_Frame_N_Data ( void );
void DoCAN_Receive_Consecutive_Frame_N_Data ( void );
void DoCAN_Receive_Flow_Control ( void );
void DoCAN_Transmit_Flow_Control ( void );
void DoCAN_Handle_Unknown_N_PDU ( void );
void DoCAN_Disassemble_And_Transmit_N_USData ( void );  /*发送主函数*/

/*** 时序管理 ***/
void DoCAN_Update_Timer ( void );
void DoCAN_Handle_Time_Out ( void );
void DoCAN_Start_Timer ( uint8_t TimingParameter );
void DoCAN_Stop_Timer ( void );
void DoCAN_Start_STmin_Timer ( uint8_t STminTime );
uint8_t DoCAN_Get_STmin_Timer_Status ( void );

void UDS_TP_ArTimeOutHandle(void);

#endif