📄 elinmint.c
字号:
// _ELINMIntReadBack=RCREG; // read the receive register to clear RCIF flag
#if ELINMINT_EXTENDED_MESSAGE==1 // if an extended error message in place
if(_ELINMIntStatus1.ELINMINTSTS.EXTENDED==0) // and extended ID not selected
{
#endif
if(_ELINMIntStatus1.ELINMINTSTS.FRAME==1) // check flag bit of transmission of frame
{
if(_ELINMIntStatus1.ELINMINTSTS.HEADER==1) // check flag bit of transmission of header
{
if(_ELINMIntTHeaderMin) // while the min. header time > 0 decrement it
_ELINMIntTHeaderMin--;
if(_ELINMIntTHeaderMax) // while the max. header time > 0 decrement it
_ELINMIntTHeaderMax--;
else // however, if max. header time == 0 and header transmission not completed
_ELINMIntResetProtocol(ELINMINT_IDLEBIT+ELINMINT_ERRORBIT+ELINMINT_THMAX_ERROR); // then reset with error
}
else // if(_ELINMIntStatus1.ELINMINTSTS.HEADER==1) // check flag bit of transmission of header
{
if(_ELINMIntTHeaderMin) // check header minimum time
_ELINMIntResetProtocol(ELINMINT_IDLEBIT+ELINMINT_ERRORBIT+ELINMINT_THMIN_ERROR); // if > 0 --> error
}
if(_ELINMIntTFrameMin) // while min. frame time > 0 decrement it
_ELINMIntTFrameMin--;
if(_ELINMIntTFrameMax) // while max. frame time > 0 decrement it
_ELINMIntTFrameMax--;
else // however if the max. frame time ==0 and frame not completed
_ELINMIntResetProtocol(ELINMINT_IDLEBIT+ELINMINT_ERRORBIT+ELINMINT_TFMAX_ERROR); // signal error
}
else // if frame transmission (or reception) completed
{
if(_ELINMIntTFrameMin) // check frame min. time
_ELINMIntResetProtocol(ELINMINT_IDLEBIT+ELINMINT_ERRORBIT+ELINMINT_TFMIN_ERROR); // if >0 --> error
}
#if ELINMINT_EXTENDED_MESSAGE==1
}
#endif
}
else // if(_ELINMIntStatus.ELINMINTSTS.IDLE==0)
{
if(_ELINMIntStatus1.ELINMINTSTS.WAKEUP_SENT==0) // once the wake-up process is initiated
{ // the sleep timeout is blocked
if(_ELINMIntSleepTimeout)
_ELINMIntSleepTimeout--;
else
_ELINMIntStatus1.ELINMINTSTS.SLEEP_TIMEOUT=1;
}
}
} //function
/*********************************************************************
* Function: BYTE _ELINMIntCalcIDParity(ELINMINT_ID ELINM_idtr)
*
* PreCondition:
*
* Input: An ID
*
* Output: The same ID with parity bits set
*
* Side Effects:
*
* Stack Requirements:
*
* Overview: This functions calculates the Parity and then sends the ID.
* It doesn't check if the TXREG is available according to the
* LIN spec.
*
********************************************************************/
BYTE _ELINMIntCalcIDParity(ELINMINT_ID ELINM_idtr)
{
ELINM_idtr.ID &= 0x3F; // ensure parity bits are clean
if(ELINM_idtr.IDbits.ID0) // calculates the Parity bit 6
ELINM_idtr.ID^=0x40;
if(ELINM_idtr.IDbits.ID1)
ELINM_idtr.ID^=0x40;
if(ELINM_idtr.IDbits.ID2)
ELINM_idtr.ID^=0x40;
if(ELINM_idtr.IDbits.ID4)
ELINM_idtr.ID^=0x40;
ELINM_idtr.IDbits.ID7=1; // calculates the Parity bit 7
if(ELINM_idtr.IDbits.ID1)
ELINM_idtr.ID^=0x80;
if(ELINM_idtr.IDbits.ID3)
ELINM_idtr.ID^=0x80;
if(ELINM_idtr.IDbits.ID4)
ELINM_idtr.ID^=0x80;
if(ELINM_idtr.IDbits.ID5)
ELINM_idtr.ID^=0x80;
return((BYTE)ELINM_idtr.ID);
}
/*********************************************************************
* Function: void _ELINMIntSendMessage(BYTE _ELINM_idr,char _ELINM_size,unsigned
* int _ELINM_fmin,unsigned int _ELINM_fmax)
*
* PreCondition:ELINMIntInitialize invoked
* TX Buffer Available (using mELINMIntTXBufferAvailable())
*
* Input: The ID of the message
* The size of the message
* The minimum frame time
* The maximum frame time
*
* Output:
*
* Side Effects:Error Code is reset
*
* Stack Requirements:
*
* Overview: This function sends a message. It is not to be invoked
* by the user directly but through the mELINMIntSendMessage
* macro, which calculates the frame timing.
*
********************************************************************/
void _ELINMIntSendMessage(BYTE _ELINM_idr,char _ELINM_size,unsigned int _ELINM_fmin,unsigned int _ELINM_fmax)
{
char _ELINM_i;
ELINMINT_ID _ELINM_tid;
unsigned int _ELINM_chk;
_ELINM_tid.ID=_ELINM_idr;
_ELINMIntStatus.ELINMIntStatusByte&=0x0F; // reset error codes (High Nibble of the byte)
// the low nibble contains the state (IDLE, TX,....)
_ELINMIntTHeaderMin = ELINMINT_THEADER_MIN; // initialize min/max time for Header Variables
_ELINMIntTHeaderMax = ELINMINT_THEADER_MAX;
_ELINMIntTFrameMin=_ELINM_fmin; // initialize min/max time for Frame Variables // the same for the entire frame
_ELINMIntTFrameMax=_ELINM_fmax;
// if the user wants to use extended message the it must set the (ELINMINT_EXTENDED_MESSAGE==1)
// In this case a special EXTENDED flag is set when the extended frame message is used so
// that the normal Frame timing check is disabled. This is done because depending on the size
// of the extended message it will result in transmission times that cannot be handled by
// the unsigned int _ELINMIntTFrameMax and _ELINMIntTFrameMin variables.
// in this case the user must redefine these variables and measure the time/code overhead created
if(_ELINMIntStatus.ELINMINTSTS.IDLE) // if idle start
{
#if ELINMINT_EXTENDED_MESSAGE==1 // if extended ID is going to be used
if(_ELINM_idr==ELINMINT_EXTENDED_ID || _ELINM_idr==ELINMINT_EXTENDED_ID1) // then check if in use and set proper flag
_ELINMIntStatus1.ELINMINTSTS.EXTENDED=1;
#endif
_ELINMIntMessageBuffer[0]=ELINMINT_SYNC_VALUE; // load SYNC value
_ELINMIntMessageBuffer[1]=_ELINMIntCalcIDParity(_ELINM_tid); // calculates ID's Parity
_ELINMIntMessageBufferPointer=0; // initiate pointer
// if reception is activated the number of bytes to be received is passed as a parameter so that the
// min. and max. frame times can be calculated, however the number of bytes to be transmitted must be
// set to 2 so that only the sync and ID are sent.
if(_ELINMIntStatus.ELINMINTSTS.RX)
_ELINMIntMessageSize.SIZE=2;
else
{
_ELINMIntMessageSize.SIZE=_ELINM_size+2;
_ELINM_chk=0;
for(_ELINM_i=ELIMINT_TXMSG_INIT;_ELINM_i<_ELINMIntMessageSize.SIZE;_ELINM_i++)
_ELINM_chk+=_ELINMIntMessageBuffer[_ELINM_i]; // add data bytes for CRC calc.
_ELINMIntMessageBuffer[_ELINMIntMessageSize.SIZE]=(~(_ELINM_chk+(_ELINM_chk>>8))); // calc. Checksum
_ELINMIntMessageSize.SIZE++;
}
TXSTA_SENDB=1; // break character bit
TXREG=ELINMINT_DUMMY_VALUE; // load a dummy character in TX reg. (start TX)
_ELINMIntStatus.ELINMIntStatusByte&=0x0F; // reset errors
_ELINMIntStatus.ELINMINTSTS.TX=1; // set TX byte
_ELINMIntStatus1.ELINMINTSTS.HEADER=1; // enable header timing check
_ELINMIntStatus1.ELINMINTSTS.FRAME=1; // enable header timing check
_ELINMIntReadBack=0x00; // break read back (expected)
_ELINMIntStatus.ELINMINTSTS.IDLE=0; // clear the IDLE bit
}
}
/*********************************************************************
* Function: void _ELINMIntReceiveMessage(BYTE _ELINM_tag,BYTE _ELINM_id,char _ELINM_size)
*
* PreCondition:ELINMIntInitialize invoked
* RX Buffer Available (using mELINMIntRXBufferAvailable())
*
*
* Input: tag - an identifier to the message
* id - the ID of the message
* size - the size of the message
*
* Output:
*
* Side Effects:
*
* Stack Requirements:
*
* Overview: This function requests a message to be sent by a
* slave. It saves the tag so the user can check which message
* had a problem is the case of an error being detected
* The ID is used to create the Header used to request
* the data.
*
*
********************************************************************/
void _ELINMIntReceiveMessage(BYTE _ELINM_tag,BYTE _ELINM_id,char _ELINM_size)
{
if(_ELINMIntStatus.ELINMINTSTS.IDLE) // if idle start
{
_ELINMIntMessageTag=_ELINM_tag; // save tag of the message
_ELINMIntRXMessageSize.SIZE=_ELINM_size; // initiate the size of the received message
_ELINMIntStatus.ELINMINTSTS.RX=1; // set RX flag requesting Reception
_ELINMIntRXCRC.CRC=0; // clear CRC (in fact checksum)
mELINMIntSendMessage(_ELINMIntMessageBuffer,_ELINM_id,0); // request the HEADER to be sent
}
}
/*********************************************************************
* Function: BYTE *_ELINMIntGetPointer(char _ELINMInt_tag, BYTE _ELINMInt_position)
*
* PreCondition:ELINMIntInitialize invoked
* TX Buffer Available (using mELINMIntTXBufferAvailable())
*
* Input:
* _ELINMInt_tag -> The specific message tag
* to be associated with the TX message buffer.
* _ELINMInt_position -> the position of the buffer to be
* returned.
*
* Output: A pointer to the TX data buffer to be loaded.
*
* Side Effects:
*
* Stack Requirements:
*
* Overview: This function takes a tag and associates it with a
* TX buffer and returns a BYTE pointer that allows the user
* to load the message to be transmitted. The tag lets the
* user identifies his(hers) message in case of an error
*
* OBS: This function is not invoked directly by the user but
* through a macro (mELINMIntGetTXPointer(tag))
********************************************************************/
BYTE *_ELINMIntGetPointer(char _ELINMInt_tag, BYTE _ELINMInt_position)
{
_ELINMIntMessageTag=_ELINMInt_tag; // save the TAG
return((BYTE *)&_ELINMIntMessageBuffer[_ELINMInt_position]); // returns the data pointer
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -