/******************************************************************************
文 件 名：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 "stdint.h"
#include "MSCAN0.h"
#include "DoCAN_ISO15765_Config.h"
#include "mc9s12xhy256.h"
/*-----------------------------------------------------------------------------
Transfer_Status
-----------------------------------------------------------------------------*/
#ifndef   COMPLETE
#define COMPLETE                 0x00
#endif

#ifndef   NOT_COMPLETE
#define   NOT_COMPLETE           (!COMPLETE)
#endif

/*-----------------------------------------------------------------------------
N_PDU 名称
-----------------------------------------------------------------------------*/
#define SINGLE_FRAME               0x00
#define FIRST_FRAME                0x01
#define CONSECUTIVE_FRAME          0x02
#define FLOW_CONTROL               0x03

/*-----------------------------------------------------------------------------
流控帧类型
-----------------------------------------------------------------------------*/
#define FC_FS_CTS                  0x00
#define FC_FS_WAIT                 0x01
#define FC_FS_OVFL                 0x02

/*-----------------------------------------------------------------------------
时序参数名称
-----------------------------------------------------------------------------*/
#define TIMING_PARA_NONE           0X00
#define TIMING_PARA_N_As           0X01
#define TIMING_PARA_N_Ar           0X02
#define TIMING_PARA_N_Bs           0X03
#define TIMING_PARA_N_Br           0X04
#define TIMING_PARA_N_Cs           0X05
#define TIMING_PARA_N_Cr           0X06

/*-----------------------------------------------------------------------------
STmin计时状态
-----------------------------------------------------------------------------*/
#define STmin_TIMER_IDLE           0X00         //STmin定时器空闲
#define STmin_TIME_UP              0X01         //STmin定时时间到
#define STmin_TIMING               0X02         //STmin定时器计时中

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

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

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

#define TP_RX_RTS                  0x20         //Rx：请求继续发送多帧(Request To Send)
#define TP_TX_RTS                  0xA0         //Tx：等待接收机许可多帧发送(Request To Send)
#define TP_RX_WAIT                 0x21         //Rx：请求发送机暂停发送
#define TP_TX_WAIT                 0xA1         //Tx：接收机请求等待
#define TP_RX_OVFL                 0x22         //Rx：接收机接收溢出
#define TP_TX_OVFL                 0xA2         //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;        //[仅发送用]当前接收机要求的最小间隔时间
} 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 );
void DoCAN_L_Data_Indication ( uint32_t Identifier, uint8_t dlc, uint8_t *pData );

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

/*** 传输层协议解析 ***/
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 );

#endif