📄 linapi.c
字号:
/******************************************************************************
*
* Copyright (C) 2003 Motorola, Inc.
* All Rights Reserved
*
* Filename: $RCSfile: LINapi.c,v $
* Author: $Author: ttz778 $
* Locker: $Locker: $
* State: $State: Exp $
* Revision: $Revision: 1.2 $
*
* Functions: Motorola API definition file
*
* History: Use the RCS command log to display revision history
* information.
*
* Description:
*
* Notes: Users should not alter this file
*
******************************************************************************/
/******************************************************************************
* *
* Includes, defines, globals and function prototypes *
* *
******************************************************************************/
#include <MC68HC908QY4.h>
#include "LINdriver.h"
#include "Tx_Config.h"
//Function Prototypes
static void LinMemCopy( U8 volatile *dst, U8 volatile *src, U8 len);
/**********************************************************************************
* *
* Function name: LIN_Init *
* Description: Initialises the LIN driver. *
* Always have to be run before any other function in the API. *
* *
* Parameters: None *
* Return: Void *
* *
**********************************************************************************/
void LIN_Init(void){
U8 Dummy, i;
TxPIN = 1; // Set Tx pin to recessive state
TxPIN_DDR = 1; // Set Tx pin as output
LINSleep = 0; // Reset flag to make sure not asleep
Dummy = TSC1; // Read byte...
TSC1_CH1F = 0; // ...and reset CH0F in case of a pending interrupt
Dummy = TSC;
TSC_TOF = 0; // Clear the flag in case of a pending int.
TSC1 = 0x48; // CH1 int enable, trigger on falling edge
TSC_TSTOP = 0; // Start Timer Counter
BreakH = BreakL = 0xFF;
BitERROR = 0; //clear the bit error flag
ChecksumERROR = 0; //clear the checksum error flag
LinState = Unsyncronized; //Set driver to be in Unsynchronised state - added by JA
/* Initialise messages with LIN_MSG_NODATA */
for (i=0;i < No_of_Ids;i++)
{
LinMsgStatus[i] = LIN_MSG_NODATA; /* Set LIN_MSG_NODATA */
}
}
/**********************************************************************************
* *
* Function name: LIN_GetMsg *
* Description: Finds message "Id" and copies the message data into "MsgData",*
* and changes the message status. *
* Parameters: U8 Id - Id of message to be retrieved *
* U8 *MsgData - Buffer for putting the copied message *
* Return: LIN_NO_ID - Id is not defined for this node *
* LIN_ID_INVALID - Id is defined as Send for this node *
* LIN_OK - Msg copied OK. *
* *
**********************************************************************************/
U8 LIN_GetMsg(U8 msgId, U8 *msgData )
{
U8 i=0;
U8 MsgIndex = 0xFF;
*msgData = 0x00;
//First, look if Id defined for this node
for (i=0;i < No_of_Ids;i++) //loop through identifier table...
{
if (msgId == IdTbl[i]) // ...to check if Id exist in the table, i.e. is relevant to this node.
{
MsgIndex =i; //If found, save away index
break;
}
}
if (MsgIndex== 0xFF){ //Id not Found
return LIN_NO_ID;
}
//Id is defined for this node and received (or to ignore)
else if ((MessageCountTbl[MsgIndex] & 0xF0) != 0)
{
/* Check if there is data */
if (( LinMsgStatus[MsgIndex] & LIN_MSG_NODATA ) != 0 )
{
/* no data -> don't copy */
return LIN_MSG_NODATA;
}
else
{
/* If message was found copy the data */
//look in MessagePointerTbl[MsgIndex] to get the message data.
LinMemCopy( msgData, MessagePointerTbl[MsgIndex],(MessageCountTbl[MsgIndex] & 0xF)-1);
/* change message status */
/* After GetMsg() is called, its status is changed from LIN_MSG_UPDATED or
LIN_MSG_OVERRUN to LIN_MSG_OK. From LIN_MSG_OK it changes to to LIN_MSG_NOCHANGE.
From LIN_MSG_NODATA and LIN_MSG_NOCHANGE it will stay the same.*/
if ( ((LinMsgStatus[MsgIndex] & LIN_MSG_OVERRUN) != 0) ||
((LinMsgStatus[MsgIndex] & LIN_MSG_UPDATED) !=0) )
{
LinMsgStatus[MsgIndex]= LIN_MSG_OK;
}
else if (LinMsgStatus[MsgIndex] & (U8)LIN_MSG_OK != 0)
{
LinMsgStatus[MsgIndex]= LIN_MSG_NOCHANGE;
}
return LIN_OK;
}
}
else { //Id is defined for this node, but is a SEND-Id.
return LIN_INVALID_ID;
}
}
/***************************************************************************
* Function : LIN_PutMsg
*
* Description: Find id and copy message to send into message data
* and changes the message status.
* Parameters: U8 msgId - the id of msg to send
* U8 *msgData - pointer to buffer containing data to send
*
* Returns:
* LIN_NO_ID - Id is not configured for this node
* LIN_INVALID_ID - Id is received by this node
* LIN_OK - The data is copied to the msg buffer
*
**************************************************************************/
U8 LIN_PutMsg(U8 msgId, U8 *msgData)
{
U8 i=0;
U8 MsgIndex = 0xFF;
//First, look if Id defined for this node
for (i=0;i < No_of_Ids;i++) //loop through identifier table...
{
//...to check if Id exist in the table, i.e. is relevant to this node.
if (msgId == IdTbl[i])
{
MsgIndex =i; //If found, save away index
break;
}
}
if (MsgIndex== 0xFF) //Id not Found
{
return LIN_NO_ID;
}
//Id is defined for this node and to send (or ignore)
else if ( ((MessageCountTbl[MsgIndex] & 0xF0) == 0) ||
((MessageCountTbl[MsgIndex] & 0xF0) == 0xF0) )
{
//look in MessagePointerTbl[MsgIndex] to get the message data.
LinMemCopy(MessagePointerTbl[MsgIndex], msgData, (MessageCountTbl[MsgIndex] & 0xF)-1);
/* change the status */
/* After PutMsg() called, status is changed to LIN_MSG_UPDATED (0x20)
if previously it was in LIN_MSG_NODATA, LIN_MSG_OK or LIN_MSG_NOCHANGE.
If it was in LIN_MSG_UPDATED it is changed to LIN_MSG_OVERRUN (0x04).
If it was in LIN_MSG_OVERRUN it will stay the same.*/
if ((LinMsgStatus[MsgIndex] == LIN_MSG_OVERRUN) ||
(LinMsgStatus[MsgIndex] == LIN_MSG_UPDATED) )
{
LinMsgStatus[MsgIndex] = LIN_MSG_OVERRUN;
}
else
{
LinMsgStatus[MsgIndex] = LIN_MSG_UPDATED;
}
return LIN_OK;
}
else { //Id is defined for this node, but is a receive-Id.
return LIN_INVALID_ID;
}
}
/******************************************************************************
* *
* Function name: LinMemCopy *
* Description: Copies len chars from src to dest. *
* Return: Void *
* *
******************************************************************************/
void LinMemCopy( U8 volatile *dst, U8 volatile *src, U8 len)
{
while( len > 0 )
{
len-- ;
dst[len] = src[len];
}
return;
}
/***************************************************************************
* Function : LIN_GotoRun
*
* Description: Change the current driver state from SLEEP to RUN,
* i.e. resets the LINSleep flag.
*
* Returns: none
*
**************************************************************************/
void LIN_GotoRun( void )
{
if (LINSleep) //sleep flag is set, so driver asleep
{
LINSleep = 0; //reset sleep flag
}
}
/***************************************************************************
* Function : LIN_MsgStatus
*
* Description: Return current message status
*
* Returns:
* LIN_NO_ID - msg is not configured for this node
* LIN_OK - msg data changed/transmitted since last LIN_GetMsg/LIN_PutMsg call;
* LIN_MSG_NOCHANGE - msg data not received/transmitted since last LIN_GetMsg/LIN_PutMsg call;
* LIN_MSG_NODATA - msg data not received since driver initialization;
* LIN_MSG_OVERRUN - msg data was overwritten by driver before read.
*
**************************************************************************/
U8 LIN_MsgStatus(U8 msgId)
{
U8 i;
U8 MsgIndex = 0xFF;
//First, look if Id defined for this node
for (i=0;i < No_of_Ids;i++) //loop through identifier table...
{
// ...to check if Id exist in the table, i.e. is relevant to this node.
if (msgId == IdTbl[i])
{
MsgIndex =i; //If found, save away index
break;
}
}
if (MsgIndex== 0xFF){ //Id not Found
return LIN_NO_ID;
}
else { //Id is found, return Message Status
return LinMsgStatus[MsgIndex];
}
}
/***************************************************************************
* Function : LIN_Wakeup
*
* Description: Send wakeup signal
*
* Returns: LIN_OK No error, service call has succeeded.
* LIN_INVALID_MODE The driver is in the sleep mode during
* message request.
*
* Notes: Before calling this function, LIN_GotoRun() should be called
*
**************************************************************************/
U8 LIN_Wakeup( void )
{
U8 i;
U8 TCNHstart;
U8 TCNLstart;
U8 TCNHstop;
U8 TCNLstop;
if (LINSleep) //driver in SLEEP mode - do nothing
{
return LIN_INVALID_MODE;
}
else //when driver is in RUN state (LINSleep =0)
{
// send Wakeup signal - 0x80
//set TxPIN to 0 and wait 8 bit times
TxPIN = 0;
for (i=0; i<8; i++) //wait 1 bit time *8
{
TCNHstart = TCNTH; //save away timer values
TCNLstart = TCNTL;
//calculate new stop time
TCNHstop = (TCNHstart + BitTimeH)+((TCNLstart + BitTimeL)/0xFF);
TCNLstop = TCNLstart + BitTimeL;
//waiting 1 bit time
while ((TCNTH < TCNHstop) || ((TCNTH == TCNHstop) && (TCNTL < TCNLstop))) {}
}
//send four 1 (including stop-bit and a recessive pause)
TxPIN = 1;
for (i=0; i<4; i++)
{
TCNHstart = TCNTH; //save away timer values
TCNLstart = TCNTL;
//calculate new stop time
TCNHstop = (TCNHstart + BitTimeH)+((TCNLstart + BitTimeL)/0xFF);
TCNLstop = TCNLstart + BitTimeL;
//waiting 1 bit time
while ((TCNTH < TCNHstop) || ((TCNTH == TCNHstop) && (TCNTL < TCNLstop))) {}
}
LinState = Idle;
return LIN_OK;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -