📄 linprot.c
字号:
#define LINPROT_C
/******************************************************************************
*
* Copyright (C) 2005 Freescale Semiconductor, Inc.
* All Rights Reserved
*
* Filename: linprot.c
*
* Revision:
*
* Functions: LIN Protocol module. Master and Slave State Machines
*
* Description:
*
* Notes:
*
******************************************************************************/
#include <linbase.h>
#define LIN_SYNC_FIELD 0x55 /* Sync byte */
#define LIN_REQUEST_COMMAND_FRAME 0x3C /* Master Request Command Frame ID */
#define LIN_RESPONSE_COMMAND_FRAME 0x3D /* Slave Response Command Frame ID */
#define LIN_COMMAND_SLEEP 0x00 /* Command code for Go to Sleep Mode */
#pragma MESSAGE DISABLE C4200 /* WARNING C4200: other segment than in previous declaration */
/****************************************************************************
* All common-purpose RAM variables shall be declared here.
***************************************************************************/
/****************************************************************************
* Some of the variables (more often used) can be declared using LIN_ZPAGE
* modifier.
* It require to perform zero page RAM placement optimisation.
***************************************************************************/
#if defined(S08) && defined(CW08)
#pragma DATA_SEG SHORT ZeroSeg
#endif /* defined(S08) && defined(CW08) */
LIN_ZPAGE LIN_BYTE LIN_StateFlags; /* State machine status */
LIN_ZPAGE LIN_BYTE LIN_ProtBuf[LIN_PROT_BUF_LEN]; /* Protocol buffer */
LIN_ZPAGE LIN_BYTE LIN_TmpSCIByte; /* byte to receive byte from SCI */
/* it shoud be used only under disabled interrupts */
LIN_ZPAGE LIN_BYTE LIN_ChkSum; /* byte to calculate checksum */
LIN_ZPAGE LIN_BYTE LIN_MsgLength; /* Message length [2, 4, 8] */
LIN_ZPAGE LIN_BYTE LIN_SaveIdx; /* Current processed message index */
LIN_ZPAGE LIN_BYTE LIN_BufCounter; /* ProtBuf counter point to sended byte for FLAG_DATA_SEND */
/* or to first free byte for FLAG_DATA_RECEIVE or FLAG_DATA_IGNORE */
#if defined(MASTER)
LIN_ZPAGE LINMsgIdType LIN_SaveIdentifier; /* Message identifier */
#endif /* defined(MASTER) */
#if defined(S08) && defined(CW08)
#pragma DATA_SEG DEFAULT
#endif /* defined(S08) && defined(CW08) */
/****************************************************************************
* Functions
***************************************************************************/
/***************************************************************************
* Function : LIN_CopyToBuf
*
* Description: Copy data from src to LIN_ProtBuf
*
* Returns: none
*
* Notes: OPTIM
**************************************************************************/
void LIN_CopyToBuf( LIN_BYTE * src )
{
LIN_BYTE i;
#if defined(LINAPI_1_0)
/* reverse copy for LIN API */
for( i = 0; i < LIN_MsgLength; i++ )
{
LIN_ProtBuf[i] = src[LIN_MsgLength - i - 1];
}
#else /* !defined(LINAPI_1_0) */
/* normal copy for Freescale API */
for( i = 0; i < LIN_MsgLength; i++ )
{
LIN_ProtBuf[i] = src[i];
}
#endif
}
/***************************************************************************
* Function : LIN_CopyFromBuf
*
* Description: Copy data from LIN_ProtBuf to dst
*
* Returns: none
*
* Notes: OPTIM
**************************************************************************/
void LIN_CopyFromBuf( LIN_BYTE * dst )
{
LIN_BYTE i;
#if defined(LINAPI_1_0)
/* reverse copy for LIN API */
for( i = 0; i < LIN_MsgLength; i++ )
{
dst[i] = LIN_ProtBuf[LIN_MsgLength - i - 1];
}
#else /* !defined(LINAPI_1_0) */
/* normal copy for Freescale API */
for( i = 0; i < LIN_MsgLength; i++ )
{
dst[i] = LIN_ProtBuf[i];
}
#endif
}
/***************************************************************************
* Function : LIN_ChkAddByte
*
* Description: Add byte with carry to LIN_ChkSum variable
*
* Returns: none
*
* Notes:
*
**************************************************************************/
#if defined(S08) && defined(CW08)
#pragma OPTION ADD handle_register "-Or"
#endif /* defined(S08) && defined(CW08) */
void LIN_ChkAddByte(LIN_BYTE byte)
{
#if defined(S08) && defined(CW08)
asm
{
ADD LIN_ChkSum;
ADC #0;
STA LIN_ChkSum;
}
#endif /* defined(S08) && defined(CW08) */
}
#if defined(S08) && defined(CW08)
#pragma OPTION DEL handle_register
#endif /* defined(S08) && defined(CW08) */
/***************************************************************************
* Function : LIN_Error
*
* Description: Set error and go to LIN_FLAG_IGNORE state
*
* Returns: none
*
* Notes: Can be called only from states:
* MASTER: LIN_FLAG_SEND_HEADER,
* LIN_FLAG_SEND_DATA,
* LIN_FLAG_IGNORE_DATA,
* LIN_FLAG_RECEIVE_DATA
* SLAVE: LIN_FLAG_RECEIVE_SYNC,
* LIN_FLAG_RECEIVE_ID,
* LIN_FLAG_SEND_DATA,
* LIN_FLAG_RECEIVE_DATA
*
**************************************************************************/
void LIN_Error( void )
{
#if defined(MASTER)
LIN_CancelTimeout(); /* Cancel MaxFrame timeout */
#endif /* defined(MASTER) */
/* Check what type of the error occure -- Tx or Rx */
#if defined(MASTER)
if ( LIN_StateFlags & ( LIN_FLAG_SEND_HEADER | LIN_FLAG_SEND_DATA ))
#endif /* defined(MASTER) */
#if defined(SLAVE)
if ( LIN_StateFlags & LIN_FLAG_SEND_DATA )
#endif /* defined(SLAVE) */
{
LIN_SetTxErr();
}
else
{
LIN_SetRxErr();
}
LIN_StateFlags = LIN_FLAG_IGNORE;
}
/***************************************************************************
* Function : LIN_EndOfFrame
*
* Description: Non-error end of frame
*
* Returns: none
*
* Notes: Can be called only from states:
* MASTER:
* LIN_FLAG_SEND_DATA,
* LIN_FLAG_IGNORE_DATA,
* LIN_FLAG_RECEIVE_DATA
* SLAVE:
* LIN_FLAG_RECEIVE_ID,
* LIN_FLAG_SEND_DATA,
* LIN_FLAG_RECEIVE_DATA
*
**************************************************************************/
void LIN_EndOfFrame( void )
{
#if defined(MASTER)
LIN_CancelTimeout(); /* Cancel MaxFrame timeout */
#endif /* defined(MASTER) */
/* Check what type of frame ended -- Tx or Rx */
if ( LIN_StateFlags & LIN_FLAG_SEND_DATA )
{
LIN_ShiftTxErr();
}
else
{
LIN_ShiftRxErr();
}
#if !defined(LINAPI_1_0)
/* Check Command Frame -- only for Freescale API -- OPTIM */
if (
/* We process Command Frame only if node configured to Receive or send data for it */
( LIN_StateFlags & (LIN_FLAG_SEND_DATA | LIN_FLAG_RECEIVE_DATA) ) &&
/* AND check frame's ID that we have just processed */
#if defined(MASTER)
/* For Master: LIN_SaveIdentifier -- just processed frame's identifier */
( LIN_SaveIdentifier == LIN_REQUEST_COMMAND_FRAME )
#endif /* defined(MASTER) */
#if defined(SLAVE)
/* For Slave: LinMsgId[LIN_SaveIdx] & LIN_MSG_INDEX_MASK -- just processed frame's identifier */
/* NB: LIN_SaveIdx exists becouse we already check that we are not ignore this message */
( (LinMsgId[LIN_SaveIdx] & LIN_MSG_INDEX_MASK) == LIN_REQUEST_COMMAND_FRAME )
#endif /* defined(SLAVE) */
)
{
/* yes, we have just processed Master Command Request Frame */
/* Check Command code */
if ( LIN_ProtBuf[0] == LIN_COMMAND_SLEEP )
{
/* Go to Sleep Mode command */
LIN_StateFlags = LIN_FLAG_IGNORE | LIN_FLAG_SLEEP;
}
/* ... any other commands ... */
else
{
/* not specific command */
LIN_StateFlags = LIN_FLAG_IGNORE;
}
LIN_Command(); /* user hook after any Command */
}
else
#endif /* !defined(LINAPI_1_0) */
{ /* no any commands */
LIN_StateFlags = LIN_FLAG_IGNORE;
}
}
/***************************************************************************
* Function : LIN_RxCompleted
*
* Description: Rx interrupt
* LIN_TmpSCIByte = SCI Data Register
*
* Returns: none
*
* Notes: cases are in order of frequency of occuring
*
**************************************************************************/
void LIN_RxCompleted( void )
{
LIN_BYTE tmp; /* temporary variable: counter or message direction flags */
/**********************************************************************/
/*** MASTER & SLAVE : LIN_FLAG_RECEIVE_DATA ***/
/**********************************************************************/
if (LIN_StateFlags & LIN_FLAG_RECEIVE_DATA )
{
if (LIN_BufCounter < LIN_MsgLength) /* NB: LIN_MsgLength = 1..8 */
{
/* not all bytes received */
/* receive message data */
LIN_ProtBuf[LIN_BufCounter] = LIN_TmpSCIByte;
++LIN_BufCounter;
/* calculate checksum from received byte */
LIN_ChkAddByte(LIN_TmpSCIByte);
}
else
{ /* all data and checksum has been received */
if ( (LIN_ChkSum + LIN_TmpSCIByte) != 0xff )
{
/* Checksum error */
LIN_Error(); /* Rx error */
}
else
{ /* no error */
/* Message received succesfuly so copy it to proper place and update flags */
LIN_CopyFromBuf(LinMsgBuf[LIN_SaveIdx]);
#if defined(LINAPI_1_0)
/* set flags for all signals placed into received message */
for( tmp = LinFlagLookup[LIN_SaveIdx]; tmp < LinFlagLookup[LIN_SaveIdx + 1]; tmp++ )
{
LinSigFlags[tmp] = 0xFFu;
}
#else /* defined(LINAPI_1_0) */
/* set appropriate status for received message */
if (( LinMsgStatus[LIN_SaveIdx] & ((LIN_BYTE)LIN_MSG_OK | (LIN_BYTE)LIN_MSG_OVERRUN )) != 0 )
{
LinMsgStatus[LIN_SaveIdx] = LIN_MSG_OVERRUN;
}
else
{
LinMsgStatus[LIN_SaveIdx] = LIN_MSG_OK;
}
#endif /* defined(LINAPI_1_0) */
LIN_EndOfFrame();
}
}
}
/**********************************************************************/
/*** MASTER & SLAVE: LIN_FLAG_SEND_DATA ***/
/**********************************************************************/
else if (LIN_StateFlags & LIN_FLAG_SEND_DATA)
{
if (LIN_BufCounter < LIN_MsgLength)
{
/* not all bytes sended */
if (LIN_ProtBuf[LIN_BufCounter] != LIN_TmpSCIByte )
{
/* bit error in data */
LIN_Error(); /* Tx error */
}
else
{ /* send next byte */
++LIN_BufCounter;
if (LIN_BufCounter == LIN_MsgLength)
{
/* send check sum */
LIN_ChkSum = ~LIN_ChkSum;
LIN_SCDRPut(LIN_ChkSum);
}
else
{
LIN_ChkAddByte(LIN_ProtBuf[LIN_BufCounter]); /* OPTIM */
LIN_SCDRPut(LIN_ProtBuf[LIN_BufCounter]);
}
}
}
else
{ /* all data has been transfered so check biterror in checksum */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -