/***************************************************************************
Author:Huanglongjie Date:2016-12-13 功能:LIN中间层
Version:1.0
NOTE:加快LIN中间层模块移植,此模块暂无主模式节点状态查询功能[LIN软件协议栈]
Update: 更新日志:
****************************************************************************/
#include "lin_mid_structure.h"
#include "mb96f683_lin_base_program.h"
#include "mb96f683rb_base_layer_program.h"
#include "panle.h"
#define UINT unsigned int
#define UCHAR unsigned char
#define ULONG unsigned long
/******************************局部静态函数声明*****************************/
static void Lin_Switch_SendOrReceive(UCHAR Lin_Pid_Temp);
static void Write_Data_To_SendBuffer(unsigned char * Data,unsigned char Data_Lenth);
static void Read_Buffer_Data(void);
static void Clear_Lin_Frame_Buffer_Data_Field(void);
static UCHAR Lin_Caculate_CheckSum(UCHAR Data_Length);
/**********************************变量定义*********************************/
#if LIN_MODE == HOST
const UCHAR Lin_Sch_Array[LIN_SCH_LEN] = {0};//调度表
#endif
//数据类
struct LIN_FRAME_BUFFER Lin_Send_Data_Frame[LIN_SEND_DATA_FRAME_NUM];
struct LIN_FRAME_BUFFER Lin_Receive_Data_Frame[LIN_RECEIVE_DATA_FRAME_NUM];
struct LIN_FRAME_BUFFER Lin_Frame_Buffer;//LIN数据buffer
static UCHAR UC_Lin_Frame_Buffer_Data_Field[8];
static UCHAR Lin_Sleep_DataArray[8];
//状态类
UCHAR Lin_RxTx_Status_Flag;// = CHECK_FIELD_RECEIVE_FINISH_IDLE;
UCHAR Check_Sum_Flag;
UCHAR Lin_Offline_Flag;
static UCHAR Lin_Sch_Count;
static UCHAR Lin_Ms_Counter;
static UCHAR Lin_Offline_Sec_Counter;
static UCHAR Lin_RxTx_Count;
//外部变量
extern union LIN_28_TYPE Un_Lin_Send_Msg;
extern union LIN_0C_TYPE Un_Lin_Rec_Msg;
/**********************************函数实现*********************************/
/*****************************************
Function Name: Lin_Application_Structure_Init()
Engineer: created by Huanglongjie
function: 链接应用层需要配置的相关参数
caution: 需要配置PID,数据长度等
*****************************************/
void Lin_Application_Structure_Init(void)
{
UCHAR i,j;
//Buffer配置
Lin_Frame_Buffer.P_Data = UC_Lin_Frame_Buffer_Data_Field;
//本地PID相关配置
Lin_Send_Data_Frame[0].Pid = 0xa8;
Lin_Send_Data_Frame[0].Dlc = 8;
Lin_Send_Data_Frame[0].P_Data = Un_Lin_Send_Msg.UC_Byte_Data;
//异地接收PID配置
Lin_Receive_Data_Frame[0].Pid = 0x80;
Lin_Receive_Data_Frame[0].Dlc = 8;
Lin_Receive_Data_Frame[0].P_Data = Un_Lin_Rec_Msg.UC_Byte_Data;
}
/*****************************************
Function Name: Lin_Mid_Structure_Init()
Engineer: created by Huanglongjie
function: LIN中间层初始化
caution: none
*****************************************/
void Lin_Mid_Structure_Init(void)
{
Lin_RxTx_Status_Flag = LIN_IDLE;
Lin_RxTx_Count = 0;
Check_Sum_Flag = CHECK_ERROR;
Lin_Offline_Sec_Counter = LIN_OFFLINE_DELAY;
Lin_Sch_Count = 0;
Lin_Ms_Counter = 100;//主模式时初始化200ms后开始正常工作
}
/*****************************************
Function Name: Lin_Sleep_Deal()
Engineer: created by Huanglongjie
function: 用于LIN掉线网络从节点睡眠
caution: [从节点收到LIN调度开始清计时,
主节点从收到从任一节点LIN正
确响应开始清计时]
*****************************************/
void Lin_Sleep_Deal(void)
{
UCHAR i,k;
i = 0;
if(Lin_Offline_Sec_Counter == 0)
Lin_Offline_Flag = LIN_OFFLINE;
else
{
if(Lin_Sleep_DataArray[0] == 0x00)
i++;
for(k=1;k<8;k++)
{
if(Lin_Sleep_DataArray[k] == 0xff)
i++;
}
if(i == 8)
Lin_Offline_Flag = LIN_OFFLINE;
else
Lin_Offline_Flag = LIN_ONLINE;
}
}
/*****************************************
Function Name: Lin_Service()
Engineer: created by Huanglongjie
function: LIN服务函数放在中断中
caution: none
*****************************************/
void Lin_Service(void)
{
UCHAR Lin_TxRx_Buffer,i;
Lin_TxRx_Buffer = 0xff;
#if LIN_MODE == SLAVE//从模式刷新离线计时
{
Lin_Offline_Sec_Counter = LIN_OFFLINE_DELAY;
}
#endif
Lin_TxRx_Buffer = Lin_Read_Data();//读数据【注意这个函数必须在Lin_Clear_Flag之前,以免读之前数据已经被读过一次清掉了】
if(Lin_Read_Break_Flag() == REC_BREAK_FRAME_FLAG)
{
Lin_RxTx_Status_Flag = BREAK_FIELD_RECEIVE_FINISH;
Lin_Clear_Break_Flag();
Lin_Clear_Flag();
#if LIN_WORK_MODE == LIN_HOST_MODE
Lin_Send_Data(SYNCHRO_FIELD_MSG);
#endif
return;
}
Lin_Clear_Flag();
//LIN状态流程跳转
switch(Lin_RxTx_Status_Flag)
{
case BREAK_FIELD_RECEIVE_FINISH://收到同步场
if(Lin_TxRx_Buffer == SYNCHRO_FIELD_MSG)
{
Lin_RxTx_Status_Flag = SYNCHRO_FIELD_RECEIVE_FINISH;
#if LIN_WORK_MODE == LIN_HOST_MODE//主模式发送Pid
{
Lin_Send_Data(Lin_Sch_Array[Lin_Sch_Count]);
Lin_Sch_Count++;
if(Lin_Sch_Count == LIN_SCH_LEN)
Lin_Sch_Count = 0;
}
#endif
}
break;
case SYNCHRO_FIELD_RECEIVE_FINISH://收到Pid
Lin_Frame_Buffer.Pid = Lin_TxRx_Buffer;
Lin_Switch_SendOrReceive(Lin_Frame_Buffer.Pid);//分流函数
break;
case LIN_DATA_SEND:
if(Lin_TxRx_Buffer != (Lin_Frame_Buffer.P_Data[Lin_RxTx_Count - 1]))
{
;//假如发送的数据场和收到的不一样如何处理!
}
Lin_Send_Data(Lin_Frame_Buffer.P_Data[Lin_RxTx_Count]);
Lin_RxTx_Count++;
if(Lin_RxTx_Count == Lin_Frame_Buffer.Dlc)
Lin_RxTx_Status_Flag = DATA_FIELD_FINISH;
break;
case LIN_DATA_RECEIVE:
if(Lin_RxTx_Count < Lin_Frame_Buffer.Dlc)
{
Lin_Frame_Buffer.P_Data[Lin_RxTx_Count] = Lin_TxRx_Buffer;
Lin_RxTx_Count++;
if(Lin_RxTx_Count == Lin_Frame_Buffer.Dlc)
{
Lin_Frame_Buffer.CheckSum = (UCHAR)Lin_Caculate_CheckSum(Lin_Frame_Buffer.Dlc);//根据接收的数据算校验和
Lin_RxTx_Status_Flag = CHECK_FIELD_RECEIVE_FINISH;
}
}
break;
case LIN_DONT_DEAL_DATA: //本节点不需要要关心该节点数据,不做任何数据处理
return;
break;
case DATA_FIELD_FINISH:
if(Lin_RxTx_Count == Lin_Frame_Buffer.Dlc)
{
Lin_Send_Data(Lin_Frame_Buffer.CheckSum);
Lin_RxTx_Status_Flag = CHECK_FIELD_RECEIVE_FINISH;
}
break;
case CHECK_FIELD_RECEIVE_FINISH:
if(Lin_Frame_Buffer.CheckSum == Lin_TxRx_Buffer)
{
Check_Sum_Flag = CHECK_SUCCESS;
Read_Buffer_Data(); //把校验成功的Buffer数据赋值给对应的变量空间
}
else
{
Check_Sum_Flag = CHECK_ERROR;
Clear_Lin_Frame_Buffer_Data_Field();
}
Lin_RxTx_Status_Flag = LIN_IDLE;
break;
default://LIN_IDLE
;
break;
}
}
/*****************************************
Function Name: Lin_Switch_SendOrReceive()
Engineer: created by Huanglongjie
function: 接收发送分流函数
caution: none
*****************************************/
static void Lin_Switch_SendOrReceive(UCHAR Lin_Pid_Temp)
{
UCHAR i,k;
Lin_RxTx_Count = 0;
for(k = 0;k < LIN_SEND_DATA_FRAME_NUM;k++) //发送匹配
{
if(Lin_Pid_Temp == Lin_Send_Data_Frame[k].Pid)
{
Lin_RxTx_Status_Flag = LIN_DATA_SEND;
Clear_Lin_Frame_Buffer_Data_Field();
Write_Data_To_SendBuffer(Lin_Send_Data_Frame[k].P_Data,Lin_Send_Data_Frame[k].Dlc);
//清数据[根据应用层需要添加的]
for(i = 0;i < Lin_Send_Data_Frame[k].Dlc;i++)
Lin_Send_Data_Frame[k].P_Data[i] = 0x00;
//
Lin_Frame_Buffer.CheckSum = (UCHAR)Lin_Caculate_CheckSum(Lin_Send_Data_Frame[k].Dlc);
Lin_Frame_Buffer.Dlc = Lin_Send_Data_Frame[k].Dlc;
Lin_Send_Data(Lin_Frame_Buffer.P_Data[Lin_RxTx_Count]);//发送状态,收到PID后直接发送第一个字节数据
Lin_RxTx_Count++;
return;
}
}
for(k = 0;k < LIN_RECEIVE_DATA_FRAME_NUM;k++) //接收匹配
{
if(Lin_Pid_Temp == Lin_Receive_Data_Frame[k].Pid)
{
Lin_RxTx_Status_Flag = LIN_DATA_RECEIVE;
Clear_Lin_Frame_Buffer_Data_Field(); //清空缓冲区域
Lin_Frame_Buff