1.5wuling_zhuanjietou/UDS/tp_cca.c

1782 lines
51 KiB
C
Raw Normal View History

2024-10-17 01:06:51 +00:00
/*!
* @file tp_cca.c
* @brief TP layer file according to the 15765-2.
*
*/
#include "uds_config.h"
/*!
* Macro. Minumum of the first frame data length
*/
#define MINIMUM_FIRST_FRAME_DATA_LENGTH 8
/*!
* Macro. Dynamic tp para update enable
*/
#define DYNAMIC_TP_PARA_UPDATE_ENABLE 0
static uint8_t TP_Tx_Message_Status; /*!< Transmit Message Status */
static uint8_t TP_Tx_Block_Size; /*!< Transmit Block Size */
static uint8_t TP_Tx_Block_Size_Constant; /*!< Transmit Block Size Constant */
static uint8_t TP_Tx_Separation_Time_Min_Constant; /*!< Min of Transmit Separation time constant */
static uint8_t TP_Tx_Separation_Time_min; /*!< Min of Transmit Separation time */
static uint8_t TP_Tx_Sequence_Number; /*!< Transmit sequence number */
static uint8_t TP_Transmit_Sub_State; /*!< Transmit sub state */
uint16_t TP_Tx_Message_DLC; /*!< Transmit Message DLC */
static uint8_t TP_Tx_Frame_Type; /*!< Transmit Frame Type */
static uint16_t TP_Tx_Index; /*!< Transmit Index */
static uint8_t TP_Tx_Frame_DLC; /*!< Transmit Frame DLC */
//static uint8_t TP_Transmit_Message_Number_Physical; /*!< Transmit transmit message physical number */
static uint8_t TP_Rx_Message_Status; /*!< Receive message Status */
static uint16_t TP_Rx_Block_Size; /*!< Receive Block Size */
//static uint16_t TP_Rx_Block_Size_Parameter; /*!< Receive Block size Parameter */
//static uint8_t TP_Rx_Seperation_Time_Parameter; /*!< Receive Seperation Time Parameter */
static uint8_t TP_Rx_Sequence_Number; /*!< Receive sequence number */
static uint8_t TP_Receive_Sub_State; /*!< Receive sub state */
static uint16_t TP_Rx_Message_DLC; /*!< Receive Message DLC */
static uint8_t TP_Rx_Frame_Type; /*!< Receive Frame type */
uint16_t TP_Rx_Index; /*!< Receive Index */
static uint16_t TP_Rx_Frame_DLC; /*!< Receive Frame DLC */
//static uint8_t TP_Receive_Message_Number_Physical; /*!< Receive Message Number Physical */
//static uint8_t TP_Receivet_Message_Number_Functional; /*!< Receive Message Number Functional */
uint16_t TP_Rx_Message_Length; /*!< Receive Message Length */
static uint16_t TPN_As_Timer; /*!< AS Timer */
static uint16_t TPN_Ar_Timer; /*!< Ar Timer */
static uint16_t TPN_Bs_Timer; /*!< Bs Timer */
static uint16_t TPN_Cr_Timer; /*!< Cr Timer */
static uint8_t TP_State; /*!< State of tp layer */
static uint16_t TP_Data_Count; /*!< Data Count */
static uint16_t TP_Next_Loop_Count; /*!< Next Loop Count */
static uint8_t Flow_Status; /*!< Flow Status */
static uint8_t TP_Result; /*!< Result */
static uint8_t TP_Change_Parameter_Result; /*!< Change parameter Result */
static uint8_t TP_Request_Type; /*!< Request type */
bool Frame_Tx_Complete; /*!< Frame transmit complete flag */
static bool Frame_Available; /*!< Frame available flag */
static bool Load_Consecutive_Frame; /*!< Load CF flag */
static uint8_t TP_Tx_Buffer_Status; /*!< Tx Buffer Status */
static uint8_t TP_Rx_Buffer_Status; /*!< Rx Buffer Status */
static uint8_t TP_N_As_Timer_Control; /*!< As Timer Control */
static uint8_t TP_N_Ar_Timer_Control; /*!< Ar Timer Control */
static uint8_t TP_N_Bs_Timer_Control; /*!< Bs Timer Control */
static uint8_t TP_N_Cr_Timer_Control; /*!< Cr Timer Control */
static bool Update_Tp_Parameter_Req = DYNAMIC_TP_PARA_UPDATE_ENABLE;
uint8_t TP_Buffer[TP_BUFFER_SIZE]; /*!< TP Buffer */
//uint8_t TP_Tx_Buffer[TP_BUFFER_SIZE];
static uint8_t TP_Frame_Array[FRAME_DATA_SIZE]; /*!< Frame Buffer */
/* functions local to TP Module */
static void TP_Transmit_Single_OR_First_Frame (void);
static void TP_Receive_Single_OR_First_Frame (void);
static void TP_Transmit_Consecutive_Frame (void);
static void TP_Receive_Consecutive_Frame (void);
static void TP_Check_Rx_Message_Length (void);
static void TP_Transmit_Flow_Control (void);
static void TP_Update_Timers (void);
static bool TP_Received_DLC_Check (void);
static uint8_t TP_STmin_Calculate (void);
static void TP_Idle_State_Process (void);
static void TP_Wait_For_SFORFF_TxConf_State_Process (void);
static void TP_Wait_For_FCFrame_Rx_State_Process (void);
static void TP_Transmit_CF_State_Process (void);
static void TP_Wait_For_CF_TxConf_State_Process (void);
static void TP_Wait_For_STmin_State_Process (void);
static void TP_Wait_For_FC_TXconf_State_Process (void);
static void TP_Rx_CF_State_Process (void);
static void TP_Wait_For_DataRead_State_Process (void);
static void TP_Tx_To_Idle_Init (uint8_t TP_Result);
static void TP_FC_Frame_Process (void);
static void TP_Rx_To_Idle_Init (uint8_t TP_Result);
static void TP_Transmit_Single_Frame (void);
static void TP_Transmit_First_Frame (void);
static void TP_Receive_Single_Frame (void);
static void TP_Receive_First_Frame (void);
static void TP_Tx_Load_CF_Data_Process (void);
static void TP_Tx_Load_Remaining_Bytes_OF_CF_Process (void);
static void TP_Tx_Load_Remaining_Bytes_OF_Last_CF_Process (void);
static void TP_Load_TL_Buffer_Start_NAs_Timer (void);
static void TP_Update_SN_and_BS (void);
static void TP_Tx_CF_Data_Process (void);
static void TP_Tx_Last_CF_Data_Process (void);
static void TP_Rx_Unload_CF_Data_Process (void);
static void TP_Rx_Unload_Remaining_Bytes_OF_CF_Process (void);
static void TP_Rx_Unload_Remaining_Bytes_OF_Last_CF_Process (void);
static void TP_Rx_CF_Data_Process (void);
static void TP_Rx_Last_CF_Data_Process (void);
/*!
* @brief TP_Init
* Read the message numbers from the TL config table, Initialize
* the state to idle, transmit and recieve status init, buffer status init,
* Timers disabling, loads the default value's of BS and STmin to
* variables.
*/
void TP_Init (void)
{
/* Reads the Message number/Index from the TL config table */
#ifdef TP_DIAG_PHYSICAL_MSG_SUPPORT
// TP_Transmit_Message_Number_Physical = 8;
// TP_Receive_Message_Number_Physical = 8;
#endif
#ifdef TP_DIAG_FUNCTIONAL_MSG_SUPPORT
// TP_Receivet_Message_Number_Functional = 8;
#endif
TP_State = TP_Idle_State;
TP_Tx_Message_Status = TP_TRANSMIT_IDLE;
TP_Rx_Message_Status = TP_RECEIVE_IDLE;
TP_Tx_Buffer_Status = EMPTY;
TP_Rx_Buffer_Status = EMPTY;
Frame_Tx_Complete = false;
// Frame_Tx_Complete_Flag_For_Reset = false;
Frame_Available = false;
TP_N_As_Timer_Control = TIMER_STOP;
TP_N_Ar_Timer_Control = TIMER_STOP;
TP_N_Bs_Timer_Control = TIMER_STOP;
TP_N_Cr_Timer_Control = TIMER_STOP;
Flow_Status = CLEAR_TO_SEND;
/* default block size for receive. */
// TP_Rx_Block_Size_Parameter = TP_RX_BLOCK_SIZE_MAX;
/* default STmin for receive. */
// TP_Rx_Seperation_Time_Parameter = TP_RX_SEPARATION_TIME_MIN;
Load_Consecutive_Frame = false;
}/* End of TP_Init*/
void TP_Task(void)
{
//U32 context = hwi_disable_interrupts_savestate();
switch (TP_State)
{
case TP_Idle_State:
TP_Idle_State_Process();
break;
case TP_Wait_For_SFORFF_TxConf_State:
TP_Wait_For_SFORFF_TxConf_State_Process();
break;
case TP_Wait_For_FCFrame_Rx_State:
TP_Wait_For_FCFrame_Rx_State_Process();
break;
case TP_Transmit_CF_State:
TP_Transmit_CF_State_Process();
break;
case TP_Wait_For_CF_TxConf_State:
TP_Wait_For_CF_TxConf_State_Process();
break;
case TP_Wait_For_STmin_State:
TP_Wait_For_STmin_State_Process();
break;
case TP_Wait_For_FC_TXconf_State:
TP_Wait_For_FC_TXconf_State_Process();
break;
case TP_Rx_CF_State:
TP_Rx_CF_State_Process();
break;
case TP_Wait_For_DataRead_State:
TP_Wait_For_DataRead_State_Process();
break;
default:
break;
}
//hwi_restore_interrupts( context );
}
/*!
* @brief TP_Periodic_Task
* Main task which handles both transmit and receive portion of
* Network Layer
*/
void TP_Periodic_Task (void)
{
TP_Update_Timers();
TP_Task();
}/* End of TP_Periodic_Task*/
/*!
* @brief TP_Idle_State_Process
* This function handles TP_Idle_State
*
*/
static void TP_Idle_State_Process (void)
{
if (Frame_Available == true)
{
Frame_Available = false;
TP_Receive_Single_OR_First_Frame();
}
}
/*!
* @brief TP_Wait_For_SFORFF_TxConf_State_Process
* This function handles TP_Wait_For_SFORFF_TxConf_State
*/
static void TP_Wait_For_SFORFF_TxConf_State_Process (void)
{
if (TPN_As_Timer == 0)
{
TP_Result = N_TIMEOUT_A;
TP_Tx_To_Idle_Init (TP_Result);
}
else if (Frame_Tx_Complete == true)
{
Frame_Tx_Complete = false;
TP_N_As_Timer_Control = TIMER_STOP;
if (TP_Tx_Frame_Type == SINGLE_FRAME)
{
TP_Result = N_OK;
TP_Tx_To_Idle_Init (TP_Result);
}
else if (TP_Tx_Frame_Type == FIRST_FRAME)
{
Update_Tp_Parameter_Req = TRUE;
TP_State = TP_Wait_For_FCFrame_Rx_State;
}
else
{
/* do nothing */
}
}
else
{
/* do nothing */
}
}
/*!
* @brief TP_Wait_For_FCFrame_Rx_State_Process
* This function handles TP_Wait_For_FCFrame_Rx_State
*/
static void TP_Wait_For_FCFrame_Rx_State_Process (void)
{
uint8_t FlowControlStatus;
if (TPN_Bs_Timer == 0)
{
TP_Result = N_TIMEOUTBs;
TP_Tx_To_Idle_Init (TP_Result);
}
else if (Frame_Available == true)
{
Frame_Available = false;
TP_Rx_Frame_Type = TP_Frame_Array[0] & FRAME_TYPE_MASK;
if (TP_Rx_Frame_Type == FLOW_CONTROL_FRAME)
{
TP_N_Bs_Timer_Control = TIMER_STOP;
FlowControlStatus = TP_Frame_Array[0] & FLOW_STATUS_MASK;
if (false == TP_Received_DLC_Check())
{
TP_Result = N_WRONG_DLC;
TP_Tx_To_Idle_Init (TP_Result);
}
else
{
if (FlowControlStatus >= RESERVED)
{
TP_Result = N_INVALID_FS;
TP_Tx_To_Idle_Init (TP_Result);
}
else if (FlowControlStatus == OVERFLOW)
{
TP_Result = N_BUFFER_OVFLW;
TP_Tx_To_Idle_Init (TP_Result);
}
else if (FlowControlStatus == WAIT)
{
if (N_WAIT_FRAME_TX_MAX == 0)
{
TP_Result = N_WFT_OVRN;
TP_Tx_To_Idle_Init (TP_Result);
}
/* A count of 1 less is loaded as Bs timeout was exceeding max set */
TPN_Bs_Timer = (N_Bs_TIMER_COUNT) - 1;
TP_N_Bs_Timer_Control = TIMER_RUN;
}
else if (FlowControlStatus == CLEAR_TO_SEND)
{
TP_FC_Frame_Process();
}
else
{
/* do nothing */
}
}
}
}
else
{
/* do nothing */
}
}
/*!
* @brief TP_Transmit_CF_State_Process
* This function handles TP_Transmit_CF_State
*/
static void TP_Transmit_CF_State_Process (void)
{
TP_Transmit_Consecutive_Frame();
if (TP_Transmit_Sub_State == TP_TX_LOAD_CF_DATA)
{
TP_State = TP_Wait_For_CF_TxConf_State;
}
}
/*!
* @brief TP_Wait_For_CF_TxConf_State_Process
* This function handles TP_Wait_For_CF_TxConf_State
*/
static void TP_Wait_For_CF_TxConf_State_Process (void)
{
if (TPN_As_Timer == 0)
{
TP_Result = N_TIMEOUT_A;
TP_Tx_To_Idle_Init (TP_Result);
}
else if ( (Frame_Tx_Complete == true) || (Load_Consecutive_Frame == true))
{
TP_N_As_Timer_Control = TIMER_STOP;
Frame_Tx_Complete = false;
if (TP_Tx_Message_DLC == 0)
{
TP_Result = N_OK;
TP_Tx_To_Idle_Init (TP_Result);
}
else if ( (TP_Tx_Block_Size_Constant != 0) && (TP_Tx_Block_Size == 0))
{
Update_Tp_Parameter_Req = DYNAMIC_TP_PARA_UPDATE_ENABLE;
TP_State = TP_Wait_For_FCFrame_Rx_State;
}
else if ( (TP_Tx_Separation_Time_Min_Constant == ZERO_LOOP_COUNT) ||
(TP_Tx_Separation_Time_Min_Constant == ONE_LOOP_COUNT))
{
TP_Transmit_Consecutive_Frame();
if (TP_Transmit_Sub_State == TP_TX_LOAD_CF_DATA)
{
Load_Consecutive_Frame = false;
}
else
{
Load_Consecutive_Frame = true;
}
}
else if (TP_Tx_Separation_Time_Min_Constant == TWO_LOOP_COUNT)
{
TP_State = TP_Transmit_CF_State;
}
else if (TP_Tx_Separation_Time_Min_Constant > TWO_LOOP_COUNT)
{
TP_Tx_Separation_Time_min--;
TP_State = TP_Wait_For_STmin_State;
}
else
{
/* do nothing */
}
}
else
{
/* do nothing */
}
}
/*!
* @brief TP_Wait_For_STmin_State_Process
* This function handles TP_Wait_For_STmin_State
*/
static void TP_Wait_For_STmin_State_Process (void)
{
TP_Tx_Separation_Time_min--;
if (TP_Tx_Separation_Time_min <= 1)
{
TP_State = TP_Transmit_CF_State;
TP_Tx_Separation_Time_min = TP_Tx_Separation_Time_Min_Constant;
}
}
/*!
* @brief TP_Wait_For_FC_TXconf_State_Process
* This function handles TP_Wait_For_FC_TXconf_State
*/
static void TP_Wait_For_FC_TXconf_State_Process (void)
{
if (Frame_Tx_Complete == true)
{
Frame_Tx_Complete = false;
TP_N_Ar_Timer_Control = TIMER_STOP;
TP_State = TP_Rx_CF_State;
TPN_Cr_Timer = N_Cr_TIMER_COUNT;
TP_N_Cr_Timer_Control = TIMER_RUN;
}
else if (TPN_Ar_Timer == 0)
{
TP_Result = N_TIMEOUT_A;
TP_Rx_To_Idle_Init (TP_Result);
}
else
{
/* do nothing */
}
}
/*!
* @brief TP_Rx_CF_State_Process
* This function handles TP_Rx_CF_State
*/
static void TP_Rx_CF_State_Process (void)
{
if (TPN_Cr_Timer == 0)
{
TP_Result = N_TIMEOUTCr;
TP_Rx_To_Idle_Init (TP_Result);
}
else if (Frame_Available == true)
{
Frame_Available = false;
TP_N_Cr_Timer_Control = TIMER_STOP;
TP_Rx_Frame_Type = TP_Frame_Array[0] & FRAME_TYPE_MASK;
if ( (TP_Rx_Frame_Type == SINGLE_FRAME) ||
(TP_Rx_Frame_Type == FIRST_FRAME))
{
TP_Result = N_UNEXP_PDU;
TP_Rx_To_Idle_Init (TP_Result);
TP_Receive_Single_OR_First_Frame();
}
else if (TP_Rx_Frame_Type == CONSECUTIVE_FRAME)
{
if (false == TP_Received_DLC_Check())
{
TP_Result = N_WRONG_DLC;
TP_Rx_To_Idle_Init (TP_Result);
}
else
{
if (TP_Rx_Sequence_Number == (TP_Frame_Array[0] &
SEQUENCE_NUMBER_MASK))
{
TP_Receive_Sub_State = TP_RX_UNLOAD_CF_DATA;
TP_Receive_Consecutive_Frame();
TPN_Cr_Timer = N_Cr_TIMER_COUNT;
TP_N_Cr_Timer_Control = TIMER_RUN;
if (TP_Receive_Sub_State == TP_RX_UNLOAD_CF_DATA)
{
TP_Check_Rx_Message_Length();
}
}
else
{
TP_Result = N_WRONG_SN;
TP_Rx_To_Idle_Init (TP_Result);
}
}
}
else
{
/* do nothing */
}
}
else
{
/* do nothing */
}
}
/*!
* @brief TP_Wait_For_DataRead_State_Process
* This function handles TP_Wait_For_DataRead_State
*/
static void TP_Wait_For_DataRead_State_Process (void)
{
if (TPN_Cr_Timer == 0)
{
TP_Result = N_TIMEOUTCr;
TP_Rx_To_Idle_Init (TP_Result);
}
else if (Frame_Available == true)
{
Frame_Available = false;
TP_Result = TP_BUFFER_OVER_FLOW;
TP_Rx_To_Idle_Init (TP_Result);
}
else
{
TP_Receive_Consecutive_Frame();
if (TP_Receive_Sub_State == TP_RX_UNLOAD_CF_DATA)
{
TP_Check_Rx_Message_Length();
}
}
}
/*!
* @brief TP_Tx_To_Idle_Init
* This function handles TP transmit variables initialization
* when transmit operation is completed suceesfully / unsuceesfully
*
* @param TP_Result TP Result
*/
static void TP_Tx_To_Idle_Init (uint8_t TP_Result)
{
UCB_TP_N_USData_Confirm (TP_Result);
TP_State = TP_Idle_State;
TP_Tx_Message_Status = TP_TRANSMIT_IDLE;
TP_Tx_Buffer_Status = EMPTY;
Frame_Tx_Complete = false;
}
/*!
* @brief TP_FC_Frame_Process
* This function handles flow control parameter processing
*/
static void TP_FC_Frame_Process (void)
{
if (Update_Tp_Parameter_Req)
{
TP_Tx_Block_Size_Constant = TP_Frame_Array[1];
/* function to calcualte stmin */
TP_Tx_Separation_Time_Min_Constant =
TP_STmin_Calculate();
}
TP_Tx_Block_Size = TP_Tx_Block_Size_Constant;
TP_Tx_Separation_Time_min =
TP_Tx_Separation_Time_Min_Constant;
TP_Transmit_Sub_State = TP_TX_LOAD_CF_DATA;
TP_Transmit_Consecutive_Frame();
if (TP_Transmit_Sub_State == TP_TX_LOAD_CF_DATA)
{
TP_State = TP_Wait_For_CF_TxConf_State;
}
else
{
TP_State = TP_Transmit_CF_State;
}
}
/*!
* @brief TP_Rx_To_Idle_Init
* This function handles TP receive variables initialization
* when receive operation is completed suceesfully / unsuceesfully
*/
static void TP_Rx_To_Idle_Init (uint8_t TP_Result)
{
UCB_TP_N_USData_Indication (TP_Rx_Message_DLC, TP_Result);
TP_State = TP_Idle_State;
TP_Rx_Message_Status = TP_RECEIVE_IDLE;
TP_Rx_Buffer_Status = EMPTY;
}
/*!
* @brief TP_Transmit_Single_OR_First_Frame
* This function handles transmission of 'single' or 'first'
* frame
*/
static void TP_Transmit_Single_OR_First_Frame (void)
{
if (TP_Tx_Frame_Type == SINGLE_FRAME)
{
TP_Transmit_Single_Frame();
}
else if (TP_Tx_Frame_Type == FIRST_FRAME)
{
TP_Transmit_First_Frame();
}
else
{
/* do nothing */
}
/* for CF1 count starts with '1'. Becomes '0' if it reaches 16 */
TP_Tx_Sequence_Number = 1;
/* TL API is called to set DLC */
HAL_UDS_Set_Tx_DLC (TP_Tx_Frame_DLC);
HAL_UDS_Set_Tx_Buf (TP_Frame_Array);
/* TL API is called to transmit a frame */
TP_State = TP_Wait_For_SFORFF_TxConf_State;
TPN_As_Timer = N_As_TIMER_COUNT;
TP_N_As_Timer_Control = TIMER_RUN;
}/* End of TP_Transmit_Single_OR_First_Frame*/
/*!
* @brief TP_Transmit_Single_Frame
* This function handles transmission of 'single' frame
*/
static void TP_Transmit_Single_Frame (void)
{
uint8_t Frame_Array_Index, Data_Count ;
/* store N_PCI and message length in the first byte of Frame buffer */
TP_Frame_Array[0] = (uint8_t) (SINGLE_FRAME | TP_Tx_Message_DLC);
Data_Count = 1;
for (Frame_Array_Index = 1; Frame_Array_Index <= TP_Tx_Message_DLC;
Frame_Array_Index++)
{
/* copy the data bytes from TP buffer to frame buffer */
TP_Frame_Array[Frame_Array_Index] = TP_Buffer[TP_Tx_Index];
TP_Tx_Index++;
Data_Count++;
}
/* DLC of the frame to be transmitted: Data bytes + N_PCI */
TP_Tx_Frame_DLC = (uint8_t) (TP_Tx_Message_DLC + 1);
if (PADDING_OPERATION == true)
{
if (Data_Count <= CAN_FRAME_BYTES_UPPER_RANGE)
{
/* padd the remaining space in the frame buffer */
for (; Data_Count <= CAN_FRAME_BYTES_UPPER_RANGE;
Data_Count++)
{
TP_Frame_Array[Data_Count] = PADDING_BYTE;
}
/* DLC of the frame to be transmitted: DLC Max bytes */
TP_Tx_Frame_DLC = NW_DLC_MAX_BYTES;
}
}
}
/*!
* @brief TP_Transmit_First_Frame
* This function handles transmission of 'first' frame
*/
static void TP_Transmit_First_Frame (void)
{
uint8_t Frame_Array_Index;
/*store N_PCI and message length in the first and second byte of Frame buffer*/
TP_Frame_Array[0] = (uint8_t) (FIRST_FRAME | ( (TP_Tx_Message_DLC & 0X0F00) >> 8));
TP_Frame_Array[1] = (uint8_t) (TP_Tx_Message_DLC & 0X00FF);
for (Frame_Array_Index = 2; Frame_Array_Index <=
CAN_FRAME_BYTES_UPPER_RANGE; Frame_Array_Index++)
{
TP_Frame_Array[Frame_Array_Index] = TP_Buffer[TP_Tx_Index];
TP_Tx_Index++;
TP_Tx_Message_DLC--;
}
/* DLC of the frame to be transmitted: DLC Max bytes */
TP_Tx_Frame_DLC = NW_DLC_MAX_BYTES;
}
/*!
* @brief TP_Receive_Single_OR_First_Frame
* This function handles reception of 'single' or 'first' frame
*/
static void TP_Receive_Single_OR_First_Frame (void)
{
/* first byte: MSB Nibble indicates frame type :-N_PCI */
TP_Rx_Frame_Type = TP_Frame_Array[0] & FRAME_TYPE_MASK;
TP_Rx_Index = 0;
TP_Request_Type = PHYSICAL_ADDRESS_TYPE;
UdsService.FrameType=TP_Rx_Frame_Type;
if (TP_Rx_Frame_Type == SINGLE_FRAME)
{
TP_Receive_Single_Frame();
}
else if (TP_Rx_Frame_Type == FIRST_FRAME)
{
TP_Receive_First_Frame();
}
else
{
/* do nothing */
}
}/* End of TP_Receive_Single_OR_First_Frame*/
/*!
* @brief TP_Receive_Single_Frame
* This function handles reception of 'single' frame
*/
static void TP_Receive_Single_Frame (void)//THT
{
uint8_t Frame_Array_Index;
/* first byte: LSB Nibble indicates data length */
TP_Rx_Message_DLC = TP_Frame_Array[0] & SINGLE_FRAME_DATA_LENGTH_MASK;
//UdsService.RxDlc = TP_Rx_Message_DLC;
for (Frame_Array_Index = 1; Frame_Array_Index <= TP_Rx_Message_DLC;
Frame_Array_Index++)
{
TP_Buffer[TP_Rx_Index] = TP_Frame_Array[Frame_Array_Index];
TP_Rx_Index++;
}
if (false == TP_Received_DLC_Check())
{
TP_Result = N_WRONG_DLC;
UCB_TP_N_USData_Indication (TP_Rx_Message_DLC, TP_Result);
}
else
{
TP_Result = N_OK;
UCB_TP_N_USData_Indication (TP_Rx_Message_DLC, TP_Result);
}
}
/*!
* @brief TP_Receive_First_Frame
* This function handles reception of 'first' frame
*/
static void TP_Receive_First_Frame (void)
{
uint8_t Frame_Array_Index;
TP_Rx_Message_DLC = ( (uint16_t) ( (TP_Frame_Array[0] &
FIRST_FRAME_DATA_LENGTH_MSB_NIBBLE_MASK) << 8) | TP_Frame_Array[1]);
TP_Rx_Message_Length = TP_Rx_Message_DLC;
if ( (RECEIVE_MULTI_BUFFER_SUPPORT == false) &&
(TP_Rx_Message_DLC > TP_BUFFER_SIZE))
{
TP_Result = TP_RX_LENGTH_INVALID;
UCB_TP_N_USData_Indication (TP_Rx_Message_DLC, TP_Result);
Flow_Status = OVERFLOW;
TP_Transmit_Flow_Control();
Flow_Status = CLEAR_TO_SEND;
TP_State = TP_Idle_State;
}
else
{
if (TP_Rx_Message_DLC >= MINIMUM_FIRST_FRAME_DATA_LENGTH)
{
if (false == TP_Received_DLC_Check())
{
TP_Result = N_WRONG_DLC;
UCB_TP_N_USData_Indication (TP_Rx_Message_DLC, TP_Result);
}
else
{
for (Frame_Array_Index = 2; Frame_Array_Index <=
CAN_FRAME_BYTES_UPPER_RANGE; Frame_Array_Index++)
{
TP_Buffer[TP_Rx_Index] = TP_Frame_Array[Frame_Array_Index];
TP_Rx_Message_Length--;
TP_Rx_Index++;
}
TP_Rx_Sequence_Number = 1;
/* User call back function to notify the first frame of multiframe message
arrival */
UCB_TP_N_USData_FF_Indication (TP_Rx_Message_DLC);
TP_Rx_Message_Status = TP_RECEIVE_START;
/* After receiveing first frame this API is called to transmit flow control
frame */
TP_Transmit_Flow_Control();
}
}
}
}
/*!
* @brief TP_Transmit_Consecutive_Frame
* Handles the consecutive frame transmission with respect to
* total message length and the TP buffer
*/
static void TP_Transmit_Consecutive_Frame (void)
{
switch (TP_Transmit_Sub_State)
{
case TP_TX_LOAD_CF_DATA:
TP_Tx_Load_CF_Data_Process();
break;
case TP_TX_LOAD_REMAINING_BYTES_OF_CF:
TP_Tx_Load_Remaining_Bytes_OF_CF_Process();
break;
case TP_TX_LOAD_REMAINING_BYTES_OF_LAST_CF:
TP_Tx_Load_Remaining_Bytes_OF_Last_CF_Process();
break;
default:
break;
}/* end of TP_Transmit_Sub_State switch */
}/* End of TP_Transmit_Consecutive_Frame*/
/*!
* @brief TP_Tx_Load_CF_Data_Process
* Handles the consecutive frame transmission with respect to
* total message length and the TP buffer
*/
static void TP_Tx_Load_CF_Data_Process (void)
{
TP_Frame_Array[0] = CONSECUTIVE_FRAME | TP_Tx_Sequence_Number;
TP_Data_Count = TP_BUFFER_SIZE - TP_Tx_Index;
if (TP_Tx_Message_DLC >= CONSECUTIVE_FRAME_DATA_BYTE)
{
TP_Tx_CF_Data_Process();
}
else if (TP_Tx_Message_DLC < CONSECUTIVE_FRAME_DATA_BYTE)
{
TP_Tx_Last_CF_Data_Process();
}
else
{
/* do nothing */
}
}
/*!
* @brief TP_Tx_CF_Data_Process
* Checks the data availability in TP buffer and loads the CF
* accordingly when CF is other than last CF
*/
static void TP_Tx_CF_Data_Process (void)
{
uint8_t Frame_Array_Index;
if (TP_Data_Count < CONSECUTIVE_FRAME_DATA_BYTE)
{
TP_Next_Loop_Count = 1;
for (Frame_Array_Index = 1; Frame_Array_Index <=
TP_Data_Count; Frame_Array_Index++)
{
TP_Frame_Array[Frame_Array_Index] = TP_Buffer[TP_Tx_Index];
TP_Tx_Index++;
TP_Tx_Message_DLC--;
TP_Next_Loop_Count++;
}
TP_Transmit_Sub_State = TP_TX_LOAD_REMAINING_BYTES_OF_CF;
TP_Tx_Buffer_Status = EMPTY;
UCB_TP_Transmit_Buffer_Empty();
TP_Tx_Index = 0;
}
else if (TP_Data_Count >= CONSECUTIVE_FRAME_DATA_BYTE)
{
for (Frame_Array_Index = 1; Frame_Array_Index <=
CAN_FRAME_BYTES_UPPER_RANGE; Frame_Array_Index++)
{
TP_Frame_Array[Frame_Array_Index] = TP_Buffer[TP_Tx_Index];
TP_Tx_Index++;
TP_Tx_Message_DLC--;
}
TP_Tx_Frame_DLC = NW_DLC_MAX_BYTES;
TP_Load_TL_Buffer_Start_NAs_Timer();
TP_State = TP_Wait_For_CF_TxConf_State;
TP_Update_SN_and_BS();
}
else
{
/* do nothing */
}
}
/*!
* @brief TP_Tx_Last_CF_Data_Process
* Checks the data availability in TP buffer and loads the CF
* accordingly for last CF
*/
static void TP_Tx_Last_CF_Data_Process (void)//THT
{
uint8_t Frame_Array_Index, Data_Count, TempLoopCount;
if (TP_Data_Count >= TP_Tx_Message_DLC)
{
Data_Count = 1;
TempLoopCount = (uint8_t) TP_Tx_Message_DLC;
for (Frame_Array_Index = 1; Frame_Array_Index <=
TempLoopCount; Frame_Array_Index++)
{
TP_Frame_Array[Frame_Array_Index] =
TP_Buffer[TP_Tx_Index];
TP_Tx_Index++;
TP_Tx_Message_DLC--;
Data_Count++;
}
TP_Tx_Frame_DLC = TempLoopCount;
if (PADDING_OPERATION == true)
{
for (; Data_Count <=
CAN_FRAME_BYTES_UPPER_RANGE; Data_Count++)
{
TP_Frame_Array[Data_Count] = PADDING_BYTE;
}
TP_Tx_Frame_DLC = NW_DLC_MAX_BYTES;
}
TP_Load_TL_Buffer_Start_NAs_Timer();
TP_State = TP_Wait_For_CF_TxConf_State;
}
else if (TP_Data_Count < TP_Tx_Message_DLC)
{
TP_Next_Loop_Count = 1;
for (Frame_Array_Index = 1; Frame_Array_Index <=
TP_Data_Count; Frame_Array_Index++)
{
TP_Frame_Array[Frame_Array_Index] =
TP_Buffer[TP_Tx_Index];
TP_Tx_Index++;
TP_Tx_Message_DLC--;
TP_Next_Loop_Count++;
}
TP_Transmit_Sub_State = TP_TX_LOAD_REMAINING_BYTES_OF_LAST_CF;
TP_Tx_Buffer_Status = EMPTY;
UCB_TP_Transmit_Buffer_Empty();
TP_Tx_Index = 0;
}
else
{
/* do nothing */
}
}
/*!
* @brief TP_Tx_Load_Remaining_Bytes_OF_CF_Process
* Handles the consecutive frame transmission with respect to
* remaining bytes of CF
*/
static void TP_Tx_Load_Remaining_Bytes_OF_CF_Process (void)
{
if (TP_Tx_Buffer_Status == FILLED)
{
for (; TP_Next_Loop_Count <=
CAN_FRAME_BYTES_UPPER_RANGE; TP_Next_Loop_Count++)
{
TP_Frame_Array[TP_Next_Loop_Count] = TP_Buffer[TP_Tx_Index];
TP_Tx_Index++;
TP_Tx_Message_DLC--;
}
TP_Tx_Frame_DLC = NW_DLC_MAX_BYTES;
TP_Load_TL_Buffer_Start_NAs_Timer();
TP_Transmit_Sub_State = TP_TX_LOAD_CF_DATA;
TP_State = TP_Wait_For_CF_TxConf_State;
TP_Update_SN_and_BS();
}
}
/*!
* @brief TP_Tx_Load_Remaining_Bytes_OF_Last_CF_Process
* Handles the consecutive frame transmission with respect to
* remaining bytes of last CF
*/
static void TP_Tx_Load_Remaining_Bytes_OF_Last_CF_Process (void)
{
uint8_t Data_Count;
//uint8_t TempLoopCount;
if (TP_Tx_Buffer_Status == FILLED)
{
Data_Count = (uint8_t) TP_Next_Loop_Count;
//TempLoopCount = (uint8_t) TP_Tx_Message_DLC;
TP_Tx_Frame_DLC = (uint8_t) (TP_Next_Loop_Count + TP_Tx_Message_DLC);
for (; TP_Next_Loop_Count < TP_Tx_Frame_DLC
; TP_Next_Loop_Count++)
{
TP_Frame_Array[TP_Next_Loop_Count] =
TP_Buffer[TP_Tx_Index];
TP_Tx_Index++;
TP_Tx_Message_DLC--;
Data_Count++;
}
if (PADDING_OPERATION == true)
{
for (; Data_Count <= CAN_FRAME_BYTES_UPPER_RANGE;
Data_Count++)
{
TP_Frame_Array[Data_Count] = PADDING_BYTE;
}
TP_Tx_Frame_DLC = NW_DLC_MAX_BYTES;
}
TP_Load_TL_Buffer_Start_NAs_Timer();
TP_Transmit_Sub_State = TP_TX_LOAD_CF_DATA;
TP_State = TP_Wait_For_CF_TxConf_State;
}
}
/*!
* @brief TP_Load_TL_Buffer_Start_NAs_Timer
* Loads the frame into TL s/w buffer and starts the NAs timer
* counter.
*/
static void TP_Load_TL_Buffer_Start_NAs_Timer (void)
{
HAL_UDS_Set_Tx_DLC (TP_Tx_Frame_DLC);
HAL_UDS_Set_Tx_Buf (TP_Frame_Array);
TPN_As_Timer = N_As_TIMER_COUNT;
TP_N_As_Timer_Control = TIMER_RUN;
}
/*!
* @brief TP_Update_SN_and_BS
* updates the sequence number and the block size parameters
*/
static void TP_Update_SN_and_BS (void)
{
TP_Tx_Sequence_Number++;
if (TP_Tx_Sequence_Number == SEQUENCE_NUMBER_MAX)
{
TP_Tx_Sequence_Number = 0;
}
if (TP_Tx_Block_Size_Constant != 0)
{
TP_Tx_Block_Size--;
}
}
/*!
* @brief TP_Receive_Consecutive_Frame
* Handles the consecutive frame reception with respect to total
* message length and the TP buffer
*/
static void TP_Receive_Consecutive_Frame (void)
{
switch (TP_Receive_Sub_State)
{
case TP_RX_UNLOAD_CF_DATA:
TP_Rx_Unload_CF_Data_Process();
break;
case TP_RX_UNLOAD_REMAINING_BYTES_OF_CF:
TP_Rx_Unload_Remaining_Bytes_OF_CF_Process();
break;
case TP_RX_UNLOAD_REMAINING_BYTES_OF_LAST_CF:
TP_Rx_Unload_Remaining_Bytes_OF_Last_CF_Process();
break;
default:
break;
}/* end of TP_Receive_Sub_State switch */
}/* End of TP_Receive_Consecutive_Frame */
/*!
* @brief TP_Rx_Unload_CF_Data_Process
* Handles the consecutive frame reception with respect to total
* message length and the TP buffer
*/
static void TP_Rx_Unload_CF_Data_Process (void)
{
TP_Data_Count = TP_BUFFER_SIZE - TP_Rx_Index;
if (TP_Rx_Message_Length >= CONSECUTIVE_FRAME_DATA_BYTE)
{
TP_Rx_CF_Data_Process();
}
else if (TP_Rx_Message_Length < CONSECUTIVE_FRAME_DATA_BYTE)
{
TP_Rx_Last_CF_Data_Process();
}
else
{
/* do nothing */
}
}
/*!
* @brief TP_Rx_CF_Data_Process
* Checks the memory availability in TP buffer and unloads the CF
* accordingly when CF is other than last CF ( From TL to TP Buffer)
*/
static void TP_Rx_CF_Data_Process (void)
{
uint8_t Frame_Array_Index;
if (TP_Data_Count < CONSECUTIVE_FRAME_DATA_BYTE)
{
TP_Next_Loop_Count = 1;
for (Frame_Array_Index = 1; Frame_Array_Index <=
TP_Data_Count; Frame_Array_Index++)
{
TP_Buffer[TP_Rx_Index] = TP_Frame_Array[Frame_Array_Index];
TP_Rx_Index++;
TP_Rx_Message_Length--;
TP_Next_Loop_Count++;
}
if(!TP_Rx_Message_Length)
{
UdsService.MultFrameComp=1;
}
TP_Receive_Sub_State = TP_RX_UNLOAD_REMAINING_BYTES_OF_CF;
TP_State = TP_Wait_For_DataRead_State;
TP_Rx_Buffer_Status = FILLED;
#ifdef RX_MULTI_BUFFER_SUPPORT
UCB_TP_Receive_Buffer_Filled();
#endif
TP_Rx_Index = 0;
}
else if (TP_Data_Count >= CONSECUTIVE_FRAME_DATA_BYTE)
{
for (Frame_Array_Index = 1; Frame_Array_Index <=
CAN_FRAME_BYTES_UPPER_RANGE; Frame_Array_Index++)
{
TP_Buffer[TP_Rx_Index] = TP_Frame_Array[Frame_Array_Index];
TP_Rx_Index++;
TP_Rx_Message_Length--; // THT
}
if(!TP_Rx_Message_Length)
{
UdsService.MultFrameComp=1;
}
}
else
{
/* do nothing */
}
}
/*!
* @brief TP_Rx_Last_CF_Data_Process
* Checks the memory availability in TP buffer and unloads the CF
* accordingly for last CF ( From TL to TP Buffer)
*/
static void TP_Rx_Last_CF_Data_Process (void)
{
uint8_t TempLoopCount, Frame_Array_Index;
if (TP_Data_Count >= TP_Rx_Message_Length)
{
TempLoopCount = (uint8_t) TP_Rx_Message_Length;
for (Frame_Array_Index = 1; Frame_Array_Index <=
TempLoopCount; Frame_Array_Index++)
{
TP_Buffer[TP_Rx_Index] = TP_Frame_Array[Frame_Array_Index];
TP_Rx_Index++;
TP_Rx_Message_Length--;
}
if(!TP_Rx_Message_Length)//THT
{
UdsService.MultFrameComp=1;
}
}
else if (TP_Data_Count < TP_Rx_Message_Length)
{
TP_Next_Loop_Count = 1;
for (Frame_Array_Index = 1; Frame_Array_Index <=
TP_Data_Count; Frame_Array_Index++)
{
TP_Buffer[TP_Rx_Index] = TP_Frame_Array[Frame_Array_Index];
TP_Rx_Index++;
TP_Rx_Message_Length--;
TP_Next_Loop_Count++;
}
TP_Receive_Sub_State = TP_RX_UNLOAD_REMAINING_BYTES_OF_LAST_CF;
TP_State = TP_Wait_For_DataRead_State;
TP_Rx_Buffer_Status = FILLED;
#ifdef RX_MULTI_BUFFER_SUPPORT
UCB_TP_Receive_Buffer_Filled();
#endif
TP_Rx_Index = 0;
}
else
{
/* do nothing */
}
}
/*!
* @brief TP_Rx_Unload_Remaining_Bytes_Of_CFProcess
* Handles the consecutive frame reception with respect to
* remaining bytes of CF
*/
static void TP_Rx_Unload_Remaining_Bytes_OF_CF_Process (void)
{
if (TP_Rx_Buffer_Status == EMPTY)
{
for (; TP_Next_Loop_Count <=
CAN_FRAME_BYTES_UPPER_RANGE; TP_Next_Loop_Count++)
{
TP_Buffer[TP_Rx_Index] = TP_Frame_Array[TP_Next_Loop_Count];
TP_Rx_Index++;
TP_Rx_Message_Length--;
}
TP_Receive_Sub_State = TP_RX_UNLOAD_CF_DATA;
TP_State = TP_Rx_CF_State;
}
}
/*!
* @brief TP_Rx_Unload_Remaining_Bytes_OF_Last_CF_Process
* Handles the consecutive frame reception with respect to
* remaining bytes of last CF
*/
static void TP_Rx_Unload_Remaining_Bytes_OF_Last_CF_Process (void)
{
uint8_t TempLoopCount;
//uint8_t Data_Count;
if (TP_Rx_Buffer_Status == EMPTY)
{
// Data_Count = 0;
TempLoopCount = (uint8_t) TP_Rx_Message_Length;
for (; TP_Next_Loop_Count <=
(TempLoopCount + 1); TP_Next_Loop_Count++)
{
TP_Buffer[TP_Rx_Index] = TP_Frame_Array[TP_Next_Loop_Count];
TP_Rx_Index++;
TP_Rx_Message_Length--;
}
TP_Receive_Sub_State = TP_RX_UNLOAD_CF_DATA;
TP_State = TP_Rx_CF_State;
}
}
/*!
* @brief TP_Transmit_Buffer_Filled
* Sets the TP buffer to true state. After filling the buffer,
* application will call the function to indicate TP layer that buffer has
* been filled.
*/
void TP_Transmit_Buffer_Filled (void)
{
TP_Tx_Buffer_Status = FILLED;
}/* End of TP_Transmit_Buffer_Filled*/
/*!
* @brief TP_Receive_Buffer_Read
* Clears the TP buffer to false state. After emptying the buffer,
* application will call the function to indicate TP layer that buffer is
* emptied.
*/
void TP_Receive_Buffer_Read (void)
{
TP_Rx_Buffer_Status = EMPTY;
}/* End of TP_Receive_Buffer_Read */
/*!
* @brief TP_Check_Rx_Message_Length
* This API checks for the remaining length. If all the bytes are
* received it goes to idle stste. Otherwise it goes to a state to receive
* next CF
*/
static void TP_Check_Rx_Message_Length (void)
{
if (TP_Rx_Message_Length == 0)
{
TP_N_Cr_Timer_Control = TIMER_STOP;
TP_State = TP_Idle_State;
TP_Rx_Message_Status = TP_RECEIVE_IDLE;
TP_Rx_Buffer_Status = EMPTY;
TP_Result = N_OK;
UCB_TP_N_USData_Indication (TP_Rx_Message_DLC, TP_Result);
}
else
{
if (TP_RX_BLOCK_SIZE_MAX == 0)
{
TP_State = TP_Rx_CF_State;
}
else
{
TP_Rx_Block_Size--;
if (TP_Rx_Block_Size == 0)
{
TP_Transmit_Flow_Control();
TP_State = TP_Wait_For_FC_TXconf_State;
}
}
TP_Rx_Sequence_Number++;
if (TP_Rx_Sequence_Number == SEQUENCE_NUMBER_MAX)
{
TP_Rx_Sequence_Number = 0;
}
}
}/* End of TP_Check_Rx_Message_Length */
/*!
* @brief TP_Transmit_Flow_Control
* This API is responsible for framing the flowcontrol message
* and transmitting to the transmitter using TL API's
*/
static void TP_Transmit_Flow_Control (void)
{
uint8_t Frame_Array_Index;
/* frame a control-frame using modifiable parameters */
/* store N_PCI and flow status, as first byte */
TP_Frame_Array[0] = FLOW_CONTROL_FRAME | Flow_Status;
/* store ECU's BS parameter for receiving, as second byte */
TP_Frame_Array[1] = TP_RX_BLOCK_SIZE_MAX; // 20190315 lbin
/* store ECU's STmin parameter for receiving, as third byte */
TP_Frame_Array[2] = TP_RX_SEPARATION_TIME_MIN;//TP_Rx_Seperation_Time_Parameter;
/* store BS to another variable */
TP_Rx_Block_Size = TP_RX_BLOCK_SIZE_MAX;
TP_Tx_Frame_DLC = FLOW_CONTROL_N_PCI_PLUS_DATA_BYTE;
if (PADDING_OPERATION == true)
{
for (Frame_Array_Index = 3; Frame_Array_Index <=
CAN_FRAME_BYTES_UPPER_RANGE; Frame_Array_Index++)
{
TP_Frame_Array[Frame_Array_Index] = PADDING_BYTE;
}
TP_Tx_Frame_DLC = NW_DLC_MAX_BYTES;
}
HAL_UDS_Set_Tx_ID(0);
HAL_UDS_Set_Tx_DLC (TP_Tx_Frame_DLC);
HAL_UDS_Set_Tx_Buf (TP_Frame_Array);
TP_State = TP_Wait_For_FC_TXconf_State;
TPN_Ar_Timer = N_Ar_TIMER_COUNT;
TP_N_Ar_Timer_Control = TIMER_RUN;
}/* End of TP_Transmit_Flow_Control */
/*!
* @brief TP_Received_DLC_Check
* This API checks for the received DLC.If the received DLC is
* less than the expected DLC it returns false. Otherwise it returns true.
*/
static bool TP_Received_DLC_Check (void)
{
bool ReceivedDLCResult = false;
//uint8_t len=0;
switch (TP_Rx_Frame_Type)//THT
{
case SINGLE_FRAME:
//len = (TP_Rx_Message_DLC + SINGLE_FRAME_N_PCI_BYTE);
if (TP_Rx_Message_DLC != 0)
{
if (TP_Rx_Frame_DLC < (TP_Rx_Message_DLC + SINGLE_FRAME_N_PCI_BYTE))
{
ReceivedDLCResult = false;
}
else
{
ReceivedDLCResult = true;
}
}
break;
case FIRST_FRAME:
if (TP_Rx_Frame_DLC < FIRST_FRAME_N_PCI_PLUS_DATA_BYTE)
{
ReceivedDLCResult = false;
}
else
{
ReceivedDLCResult = true;
}
break;
case CONSECUTIVE_FRAME:
if (TP_Rx_Message_Length >= CONSECUTIVE_FRAME_DATA_BYTE)
{
if (TP_Rx_Frame_DLC < CONSECUTIVE_FRAME_N_PCI_PLUS_DATA_BYTE)
{
ReceivedDLCResult = false;
}
else
{
ReceivedDLCResult = true;
}
}
else
{
if (TP_Rx_Frame_DLC < (TP_Rx_Message_Length +
CONSECUTIVE_FRAME_N_PCI_BYTE))
{
ReceivedDLCResult = false;
}
else
{
ReceivedDLCResult = true;
}
}
break;
case FLOW_CONTROL_FRAME:
if (TP_Rx_Frame_DLC < FLOW_CONTROL_N_PCI_PLUS_DATA_BYTE)
{
ReceivedDLCResult = false;
}
else
{
ReceivedDLCResult = true;
}
break;
default:
break;
}
return (ReceivedDLCResult);
}/* End of TP_Received_DLC_Check */
/*!
* @brief TP_Update_Timers
* If the timers are enabled, timercount for each timer is
* decremented. Timers are: N_As, N_Ar, N_Bs and N_Cr
*/
static void TP_Update_Timers (void)
{
if (TP_N_As_Timer_Control == TIMER_RUN)
{
if (TPN_As_Timer > 0)
{
TPN_As_Timer--;
}
else
{
// _P101 = 0x00; TBD-PVD : Timer needs to be identified.
}
}
if (TP_N_Ar_Timer_Control == TIMER_RUN)
{
if (TPN_Ar_Timer > 0)
{
TPN_Ar_Timer--;
}
}
if (TP_N_Bs_Timer_Control == TIMER_RUN)
{
if (TPN_Bs_Timer > 0)
{
TPN_Bs_Timer--;
}
}
if (TP_N_Cr_Timer_Control == TIMER_RUN)
{
if (TPN_Cr_Timer > 0)
{
TPN_Cr_Timer--;
}
}
}/* End of TP_Update_Timers */
/*!
* @brief TP_GetBufferSize
* User calls this API to get the size of the buffer.
* decremented. Timers are: N_As, N_Ar, N_Bs and N_Cr
*
* @return TP Buffer size
*/
uint16_t TP_Get_Message_Buffer_Size (void)
{
return (TP_BUFFER_SIZE); /* size of the TP_Buffer as configured in the
config file */
}/* End of TP_Get_Message_Buffer_Size */
/*!
* @brief TP_GetBufferPointer
* User calls this API to get the pointer(address)of the
* TP_Buffer.
*
* @return Address of the TP buffer
*/
uint8_t *TP_Get_Message_Buffer_Pointer (void)
{
//memset(TP_Tx_Buffer,0x0,TP_BUFFER_SIZE);
// memcpy(TP_Tx_Buffer,TP_Buffer,TP_BUFFER_SIZE);
// memset(TP_Buffer,0x0,TP_BUFFER_SIZE);
return (TP_Buffer); /* returns the starting address of the TP buffer */
}/* End of TP_Get_Message_Buffer_Pointer */
/*!
* @brief TP_Get_Request_Type
* User calls this API to get the type of
* request(physical/functional).
*
* @return Address of the TP buffer
*/
uint8_t TP_Get_Request_Type (void)
{
return (TP_Request_Type); /* returns the type of request */
}/* End of TP_Get_Request_Type */
/*!
* @brief TP_N_USData_Request
* User calls this API to transmit a message. It passes the length
* of the message to be transmitted.
*
* @param TPTransmitMessageLength Transmit message length
*/
void TP_N_USData_Request (uint16_t TPTransmitMessageLength)
{
TP_Tx_Message_DLC = TPTransmitMessageLength;
if (TP_Tx_Message_DLC <= MAXIMUM_SINGLE_FRAME_DATA_BYTE)
{
TP_Tx_Frame_Type = SINGLE_FRAME;
}
else
{
TP_Tx_Frame_Type = FIRST_FRAME;
}
TP_Tx_Message_Status = TP_TRANSMIT_START;
TP_Tx_Index = 0;
if (TP_Tx_Buffer_Status == FILLED)
{
TP_Transmit_Single_OR_First_Frame();
}
else
{
TP_Result = TP_BUFFER_NOT_FILLED;
UCB_TP_N_USData_Confirm (TP_Result);
TP_Tx_Message_Status = TP_TRANSMIT_IDLE;
}
}/* End of TP_N_USData_Request */
/*!
* @brief TP_D_UUData_Confirm
* This is a callback function called by TL after transmitting
* a message corresponding to TP. Flag is set to inform the TP about frame
* transmission completion.
*
*/
void TP_D_UUData_Confirm (void)
{
Frame_Tx_Complete = true;
TP_N_As_Timer_Control = TIMER_STOP;
if ( (TP_State == TP_Wait_For_SFORFF_TxConf_State) &&
(TP_Tx_Frame_Type == FIRST_FRAME))
{
UCB_TP_N_USData_FF_Confirmation();
}
if ( ( (TP_State == TP_Wait_For_SFORFF_TxConf_State) &&
(TP_Tx_Frame_Type == FIRST_FRAME)) ||
( (TP_Tx_Block_Size_Constant != 0) && (TP_Tx_Block_Size == 0)))
{
TPN_Bs_Timer = N_Bs_TIMER_COUNT;
TP_N_Bs_Timer_Control = TIMER_RUN;
TP_Tx_Message_Status = WAITINGFORFLOWCONTROL;
}
if ( ( (TP_Tx_Message_Status == TP_TRANSMIT_START) &&
(TP_Tx_Separation_Time_Min_Constant == 0)) ||
(SINGLE_FRAME == TP_Tx_Frame_Type) ||
( (TP_State == TP_Wait_For_CF_TxConf_State) && (0 == TP_Tx_Message_DLC)))
{
/* to transmit 2nd CF onwards if stmin =0......*/
/* to handle next request within loop time of response */
TP_Task();
}
if ( (TP_Rx_Message_Status == TP_RECEIVE_START) &&
(TP_State == TP_Wait_For_FC_TXconf_State))
{
/* to notify flow control tx so that cf's can be received(any time)*/
TP_Task();
}
}/* End of TP_D_UUData_Confirm */
/*!
* @brief TP_D_UUData_Indication_Physical
* This is a callback function called by TL after receiving
* a message(Physical) corresponding to TP. If the ECU is transmitting,
* and if it receives a frame it is ignored. Flag is set to inform the TP about
* frame arrival.Data is copied from the software buffer to TP's Frame buffer.
*
*/
bool TpRxFlg=false;
uint8_t g_ucTpRxStatusCnt;
void TP_D_UUData_Indication_Physical (void)
{
//uint8_t Frame_Array_Index;
uint8_t FlowControlStatus;
if (TP_Tx_Message_Status != TP_TRANSMIT_START)
{
Frame_Available = true;
TP_Rx_Frame_DLC = HAL_UDS_Rx_DLC();
HAL_UDS_Get_Buf(TP_Frame_Array);
FlowControlStatus = TP_Frame_Array[0] & FLOW_STATUS_MASK;
if ( (TP_Tx_Message_Status == WAITINGFORFLOWCONTROL) &&
(FlowControlStatus == CLEAR_TO_SEND))
{
TP_Tx_Message_Status = TP_TRANSMIT_START;
}
if ( (TP_Rx_Message_Status == TP_RECEIVE_START))
{
TP_Task(); /* to receive cf's......*/
}
g_ucTpRxStatusCnt=0;
TpRxFlg=true;
UdsService.PhyFlg = true;
//Debug("UDS REC:\r\n"); //
}
else
{
if(++g_ucTpRxStatusCnt>=2)
{
UDS_Service_Init();
TP_Init();
//TP_Rx_To_Idle_Init(TP_Result);
//Debug("UDS g_ucTpRxStatusCnt:\r\n");
g_ucTpRxStatusCnt=0;
TP_Tx_Message_Status=TP_TRANSMIT_IDLE;
TP_State =TP_Idle_State;
HAL_Response_Pocessing = false;
}
}
}/* End of TP_D_UUData_Indication_Physical */
#ifdef TP_DIAG_FUNCTIONAL_MSG_SUPPORT
/*!
* @brief TP_D_UUData_Indication_Functional
* This is a callback function called by TL after receiving
* a message(functional) corresponding to TP. If the ECU is transmitting,
* and if it receives a frame it is ignored. Flag is set to inform the TP about
* frame arrival. Data is copied from the software buffer to TP's Frame buffer
*/
void TP_D_UUData_Indication_Functional (void)
{
// uint8_t *ReceivedMessageAddress;
uint8_t Frame_Array_Index;
uint8_t FlowControlStatus;
if (TP_Tx_Message_Status != TP_TRANSMIT_START) //if ((TP_Tx_Message_Status == TP_TRANSMIT_IDLE)||(TP_Tx_Message_Status != TP_TRANSMIT_START))
{
if ((UdsService.PhyFlg == true) && (TP_Rx_Message_Status == TP_RECEIVE_START)) {
return;
}
TP_Rx_Frame_DLC = HAL_UDS_Rx_DLC();
HAL_UDS_Get_Buf(TP_Frame_Array);
TP_Rx_Frame_Type = TP_Frame_Array[0] & FRAME_TYPE_MASK;
TP_Rx_Index = 0;
UdsService.RxDlc = TP_Rx_Message_DLC;
UdsService.PhyFlg = false;
FlowControlStatus = TP_Frame_Array[0] & FLOW_STATUS_MASK;
if ( (TP_Tx_Message_Status == WAITINGFORFLOWCONTROL) &&
(FlowControlStatus == CLEAR_TO_SEND))
{
TP_Tx_Message_Status = TP_TRANSMIT_START;
}
if ( (TP_Rx_Message_Status == TP_RECEIVE_START))
{
TP_Task(); /* to receive cf's......*/
}
if (TP_Rx_Frame_Type == SINGLE_FRAME)
{
TP_Rx_Message_DLC = TP_Frame_Array[0] &
SINGLE_FRAME_DATA_LENGTH_MASK;
for (Frame_Array_Index = 1; Frame_Array_Index <=
TP_Rx_Message_DLC; Frame_Array_Index++)
{
TP_Buffer[TP_Rx_Index] = TP_Frame_Array[Frame_Array_Index];
TP_Rx_Index++;
}
if (false == TP_Received_DLC_Check())
{
TP_Result = N_WRONG_DLC;
UCB_TP_N_USData_Indication (TP_Rx_Message_DLC, TP_Result);
}
else
{
TP_Request_Type = FUNCTIONAL_ADDRESS_TYPE;
TP_Result = N_OK;
UCB_TP_N_USData_Indication (TP_Rx_Message_DLC, TP_Result);
}
}
}
}/* End of TP_D_UUData_Indication_Functional */
#endif
/*!
* @brief TP_N_Change_Parameters_Request
* This API is called by user to change the parameter values of
* the parameters BlockSize and the Minimum SeparationTime
*
* @param Parameter Parameter
* @param ParameterValue Parameter Value
*/
void TP_N_Change_Parameters_Request (uint8_t Parameter, uint16_t ParameterValue)
{
/* if it is in the multiframe receive mode, change is not permitted */
if (TP_Rx_Message_Status != TP_RECEIVE_START)
{
switch (Parameter)
{
case N_BLOCKSIZE:
if ((ParameterValue <= 0xff))
{
// TP_Rx_Block_Size_Parameter = (uint8_t) ParameterValue;
TP_Change_Parameter_Result = N_OK_R;
UCB_TP_N_Change_Parameter_Confirm (Parameter,
TP_Change_Parameter_Result);
}
else
{
TP_Change_Parameter_Result = N_WRONG_VALUE;
UCB_TP_N_Change_Parameter_Confirm (Parameter,
TP_Change_Parameter_Result);
}
break;
case N_SEPERATIONTIME:
if ((ParameterValue <= 0xff))
{
// TP_Rx_Seperation_Time_Parameter = (uint8_t) ParameterValue;
TP_Change_Parameter_Result = N_OK_R;
UCB_TP_N_Change_Parameter_Confirm (Parameter,
TP_Change_Parameter_Result);
//Debug("TP_Rx_Seperation_Time_Parameter=%d",TP_Rx_Seperation_Time_Parameter);
}
else
{
TP_Change_Parameter_Result = N_WRONG_VALUE;
UCB_TP_N_Change_Parameter_Confirm (Parameter,
TP_Change_Parameter_Result);
}
break;
default:
TP_Change_Parameter_Result = N_WRONG_PARAMETER;
UCB_TP_N_Change_Parameter_Confirm (Parameter,
TP_Change_Parameter_Result);
break;
}
}
else
{
TP_Change_Parameter_Result = N_RX_ON;
UCB_TP_N_Change_Parameter_Confirm (Parameter,
TP_Change_Parameter_Result);
}
}/* End of TP_N_Change_Parameters_Request */
static uint8_t TP_STmin_Calculate (void)
{
uint8_t TP_STmin_Result,TP_FC_STmin;
TP_FC_STmin = TP_Frame_Array[2];
if (TP_FC_STmin != 0)
{
if (TP_FC_STmin > 0x7F)
{
TP_FC_STmin = 0x7F;
}
TP_STmin_Result = TP_FC_STmin / CALL_RATE_TP;
TP_STmin_Result += 1;
}
else
{
if (STmin_ZERO == CALL_RATE_TP)
{
TP_STmin_Result = 1;
}
else
{
TP_STmin_Result = 0;
}
}
return (TP_STmin_Result);
}/*/TP_STmin_Calculate*/