📄 lindriver.c
字号:
/*****************************************************************************************
*
* Copyright (C) 2003 Motorola, Inc.
* All Rights Reserved
*
* Filename: $RCSfile: LINdriver.c,v $
* Author: $Author: ttz778 $
* Locker: $Locker: $
* State: $State: Exp $
* Revision: $Revision: 1.2 $
*
* Functions: LIN908QY4 Driver
*
* History: Use the RCS command log to display revision history
* information.
*
*
*
*****************************************************************************************/
/* Includes */
#include <MC68HC908QY4.h>
#include "LINdriver.h"
#include "Tx_Config.h"
#pragma DATA_SEG SHORT _DATA_ZEROPAGE
/* Global Variables */
U8 volatile near TCH0LBuff, TCH0HBuff, BreakH, BreakL, BreakLimitH, BreakLimitL;
U8 volatile near BitTimeH, BitTimeL, HBitTimeH, HBitTimeL;
U8 volatile near LinState;
U8 volatile near MessageIndex;
U8 volatile near SyncFieldBits;
U8 volatile BitCount, ByteCount;
U8 volatile near SWSCIDR, SWSCIDRB;
U8 volatile near Id ;
U8 volatile near FrameBuffer[10];
U8 volatile near FrameTimeOut, NoRelevantID;
U8 volatile near BitClockReload8H;
U8 volatile near BitClockReload8L;
volatile LINERRORSTR _LinERROR; /* Look in the header file to see what this is */
#pragma DATA_SEG DEFAULT
/* Prototypes */
void AddBitTime8(void);
void AddBitTimeH(void);
void AddBitTime(void);
/******************************************************************************************/
interrupt void TimA1ISR(void)
{
U8 Dummy,i;
if (LinState == ReceiveId)
{
asm
{
ASR Id //Shift Rx into Id variable
BRCLR 1,PTA,LBL8
BSET 7,Id
BRA END1
LBL8:
BCLR 7,Id
END1:
//Finished shifting one .
}
/* Keep updating the timer to catch the next bit until all 8 are in Id (asm code above)*/
if (BitCount <= 6)
{
AddBitTime();
BitCount++;
}
else //got the whole Id
{
if (Id == SLEEP) //sleep defined in LINdriver.h, should be 0x80
{
LINSleep = 1; /* If LIN sleep command set the flag */
}
else
{
LINSleep = 0; //stay awake
}
BitCount = 0; //Reset BitCount and MessageIndex
MessageIndex = 0xFF;
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 (Id == IdTbl[i])
{
MessageIndex = i; //If found, save away index
}
}
if (MessageIndex == 0xFF){ //Found no id for this node, keep waiting...
LinState = Idle;
TSC1 = 0x48; /* Set for input capture on falling edge */
NoRelevantID++; //Keep track of how many Ids have been sent out that are NOT relevant for this node
ByteCount = 0;
}
/* Check if master or slave task */
else if ((MessageCountTbl[MessageIndex] & 0xF0) == 0)
{ //Id is relevant for this node and is a "To Send" Id
LinState = Sending;
NoRelevantID = 0; //reset NoRelevantId since has received a relevant id
//Loop from i=0 to "the Id's byte count" - 1 (1=checksum)
for (i=0 ; i <= ((MessageCountTbl[MessageIndex] & 0xF) - 1);i++)
{
// Copy data to framebuffer
FrameBuffer[i] = *(MessagePointerTbl[MessageIndex] + i);
}
Dummy = ((MessageCountTbl[MessageIndex] & 0xF) - 1); //check how many messages the frame has, e.g the Id's byte count
//////////////////lin2.0 checksum/////////////////
asm { /* Calculate checksum */
PSHA
CLRA
CLC
LDX Dummy
Sloop:
ADC @FrameBuffer - 1,X
DBNZX Sloop
ADC Id
ADC #0
COMA
STA i
PULA
}
///////////////////////////////////////////////////
FrameBuffer[Dummy] = i; // load Checksum in to the byte after last databyte
AddBitTime8(); //Time has moved on so need to catch up and get ahead of time again - add 8 bit times
TSC1 = 0x50; // Output compare no pin action
ByteCount = 0;
BitCount = 0;
}
//else { //Id is relevant for this node and is a "To Receive" Id
else if ((MessageCountTbl[MessageIndex] & 0xF0) == 0x10) {
LinState = ReceivingWFS;
TSC1 = 0x48; // Set for input capture on falling edge
NoRelevantID = 0; //reset NoRelevantId since has received a relevant id
ByteCount = 0;
BitCount = 0;
}
//************ added by JA to make sure only "new" msgs are sent if defined as F (ignore)
//Check if the message only should be sent if updated, and the msg has been updated
else if (((MessageCountTbl[MessageIndex] & 0xF0) == 0xF0) &&
(LinMsgStatus[MessageIndex]!= LIN_MSG_NOCHANGE) &&
(LinMsgStatus[MessageIndex]!= LIN_MSG_NODATA))
{
LinState = Sending;
NoRelevantID = 0; //reset NoRelevantId since has received a relevant id
//Loop from i=0 to "the Id's byte count" - 1 (1=checksum)
for (i=0 ; i <= ((MessageCountTbl[MessageIndex] & 0xF) - 1);i++)
{
FrameBuffer[i] = *(MessagePointerTbl[MessageIndex] + i); // Copy data to framebuffer
}
//check how many messages the frame has, e.g the Id's byte count
Dummy = ((MessageCountTbl[MessageIndex] & 0xF) - 1);
//////////////////lin2.0 checksum/////////////////
asm { /* Calculate checksum */
PSHA
CLRA
CLC
LDX Dummy
Sloop2:
ADC @FrameBuffer - 1,X
DBNZX Sloop2
ADC Id
ADC #0
COMA
STA i
PULA
}
///////////////////////////////////////////////////
FrameBuffer[Dummy] = i; // load Checksum in to the byte after last databyte
AddBitTime8(); //Sample 8 bit times ahead
TSC1 = 0x50; // Output compare no pin action
ByteCount = 0;
BitCount = 0;
}
//***************** END of send only new msgs
else
{ //ignore this message
LinState = Idle;
TSC1 = 0x48; /* Set for input capture on falling edge */
ByteCount = 0;
}
}
}
/***************************************/
else if (LinState == Sending)
{
switch(BitCount)
{
case 0: //Has not started sending yet
BitCount++;
TxPIN = 0; /* Start bit */
SWSCIDR = FrameBuffer[ByteCount]; /* Load byte to transmit */
AddBitTime();
break;
case 9: //Has sent all bits in the byte
/* SWSCIDRB is used to store the read value from the LINbus for biterror checking */
asm
{ // Shift Rx pin in to SoftwareSCIDataRegBackup. for BitError checking
ASR SWSCIDRB
BRCLR 1,PTA,S9LBL8
BSET 7,SWSCIDRB
BRA S9END1
S9LBL8:
BCLR 7,SWSCIDRB
S9END1:
}
TxPIN = 1; /* Stopbit */
AddBitTime();
/* check for Bit Error - e.g. when someone has messed with FrameBuffer */
if (SWSCIDRB != FrameBuffer[ByteCount])
{
BitERROR = 1;
BitERROR2 = 1; /* Set 2 biterror flags */
}
BitCount = 0;
ByteCount++;
/* JA add msg status ---------------*/
/* After data sent from node, its status is changed from
LIN_MSG_UPDATED or LIN_MSG_OVERRUN to LIN_MSG_OK. From
LIN_MSG_OK to LIN_MSG_NOCHANGE.
From LIN_MSG_NODATA or LIN_MSG_NOCHANGE it will stay the same.*/
if (ByteCount >= (MessageCountTbl[MessageIndex] & 0xF))
{
if ((LinMsgStatus[MessageIndex] == LIN_MSG_UPDATED) ||
(LinMsgStatus[MessageIndex] == LIN_MSG_OVERRUN) )
{
LinMsgStatus[MessageIndex] = LIN_MSG_OK;
}
else if ((LinMsgStatus[MessageIndex] & LIN_MSG_OK) != 0 )
{
LinMsgStatus[MessageIndex] = LIN_MSG_NOCHANGE;
}
}
/* end msg status -------------------------*/
/* If all bytes are sent or BitError detected abort transmission */
if ((ByteCount >= (MessageCountTbl[MessageIndex] & 0xF)) || (BitERROR2 == 1))
{
LinState = Idle; //Back to waiting for Id again...
BitERROR2 = 0; /* Reset bit error flag */
TSC1 = 0x48; /* Set to IC on falling edge */
}
break;
default: //In the middle of sending....
asm
{
ASR SWSCIDRB /* save the active state for Bit ERROR check */
BRCLR 1,PTA,SLBL8
BSET 7,SWSCIDRB
BRA SEND1
SLBL8:
BCLR 7,SWSCIDRB
SEND1: //Shift Rx pin in to SoftSCIDataRegBackup.
BRCLR 0,SWSCIDR,LBL1
BSET TxBIT, TxPORT
BRA END
LBL1:
BCLR TxBIT, TxPORT
END:
ASR SWSCIDR
}
BitCount++;
AddBitTime();
break;
}
}
/********************************/
else if (LinState == Receiving)
{
asm
{
ASR SWSCIDR /* Shift RxPin in to Data register variable. */
BRCLR 1,PTA,RLBL8
BSET 7,SWSCIDR
BRA REND1
RLBL8:
BCLR 7,SWSCIDR
REND1: /* Shifted one */
}
/* Keep updating the timer to catch the next bit until all 8 are in SWSCIDR (asm code above)*/
if (BitCount <= 6)
{
AddBitTime();
BitCount++;
}
else //Whole byte is in
{
TSC1 = 0x48; /* set for input capture on falling edge */
FrameBuffer[ByteCount] = SWSCIDR; /* Save data in buffer */
BitCount = 0;
ByteCount++;
if (ByteCount >= (MessageCountTbl[MessageIndex] & 0xF)) /* If all bytes are received */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -