📄 mscandrvlite.c
字号:
identifier reference
Return : ERR_OK if no error, otherwise error code
******************************************************************************/
UINT8
CAN_L_ConfigMB(UINT8 buffer, UINT8 cmode, UINT8 identifierRef)
{
UINT8 currentCANRIER,
currentCANTIER;
if (identifierRef >= NoOfID)
{
return (ERR_ID);
}
if (cmode >= INVALID)
{
return (ERR_MODE);
}
if (buffer >= NoOfMB)
{
return (ERR_MB);
}
SEI;
currentCANRIER = CANRIER; /* save interrupt enables */
currentCANTIER = CANTIER;
CANRIER = 0; /* disable all interrupts */
CANTIER = 0;
if (!(CCRcopy & IMASK))
{
CLI; /* restore interrupt mask */
}
if(BufferStatus_CAN0[buffer] == QUEUED2) /* MB in msCAN buffer */
{
if (MB_MSCAN[0] == buffer) /* MB in this MSCAN buffer */
{
CANTARQ |= 0x01; /* set ABTRQi for msCAN buffer */
}
else
{
if (MB_MSCAN[1] == buffer) /* MB in this MSCAN buffer */
{
CANTARQ |= 0x02; /* set ABTRQi for msCAN buffer */
}
else /* must be MB_MSCAN[2] */
{
CANTARQ |= 0x04; /* set ABTRQi for msCAN buffer */
}
}
#if (NO_OF_MSCAN_TXBUFFER != 3)
#error msCAN buffer not aborted
#endif
}
BufferMode_CAN0[buffer] = cmode;
BufferStatus_CAN0[buffer] = NODATA;
BufferID_Ref_CAN0[buffer] = identifierRef;
CANRIER = currentCANRIER; /* restore interrupts */
CANTIER = currentCANTIER;
return (ERR_OK);
}
/******************************************************************************
Function Name : CAN_L_CheckStatusMB
Engineer : Stuart Robb
Date : 10/8/98
Arguments : buffer number
address for status
Return : ERR_OK if no error, otherwise error code
******************************************************************************/
UINT8
CAN_L_CheckStatusMB (UINT8 buffer, UINT8 *statusPtr)
{
if (buffer >= NoOfMB)
{
return (ERR_MB);
}
SEI; /* disable interrupts */
*(statusPtr) = BufferStatus_CAN0[buffer];
*(statusPtr + 1) = BufferMode_CAN0[buffer];
if (!(CCRcopy & IMASK))
{
CLI; /* restore interrupt mask */
}
return (ERR_OK);
}
/******************************************************************************
Function Name : CAN_L_LoadMB
Engineer : Stuart Robb
Date : 10/8/98
Arguments : buffer number
address of data
Return : ERR_OK if no error, otherwise error code
******************************************************************************/
UINT8
CAN_L_LoadMB (UINT8 buffer, UINT8 *dataPtr)
{
UINT8 *bufferPtr;
UINT8 dataLength,
i;
if (buffer >= NoOfMB)
{
return (ERR_MB);
}
if (*dataPtr > 8)
{
return (ERR_DLC);
}
if ((BufferMode_CAN0[buffer] != TXDF)
&& (BufferMode_CAN0[buffer] != AUTOTXDF))
{
return (ERR_CONFIG);
}
if ((BufferStatus_CAN0[buffer] == QUEUED) /* Message Buffer already queued */
|| (BufferStatus_CAN0[buffer] == QUEUED2)
|| (BufferStatus_CAN0[buffer] == ABORTREQ))
{
return (ERR_QED);
}
SEI; /* disable ALL interrupts */
dataLength = *dataPtr;
BufferDLC_CAN0[buffer] = dataLength; /* copy DLC */
bufferPtr = BufferData_CAN0[buffer];
dataPtr++; /* increment to start of data */
for (i = 0; i < dataLength; i++)
{
bufferPtr[i] = dataPtr[i]; /* copy data */
}
if (!(CCRcopy & IMASK))
{
CLI; /* restore interrupt mask */
}
BufferStatus_CAN0[buffer] = VALIDDATA;
return (ERR_OK);
}
/******************************************************************************
Function Name : CAN_L_TransmitMB
Engineer : Stuart Robb
Date : 10/8/98
Arguments : buffer number
Return : ERR_OK if no error, otherwise error code
******************************************************************************/
UINT8
CAN_L_TransmitMB (UINT8 buffer)
{
UINT8 bufferStatus,
bufferMode;
if (CANCTL1 & INITAK)
{
return (ERR_INIT);
}
if ((CANRFLG & BUSOFF) == BUSOFF)
{
return (ERR_BOFF);
}
if (buffer >= NoOfMB)
{
return (ERR_MB);
}
SEI; /* mask ALL interrupts */
bufferMode = BufferMode_CAN0[buffer];
if (!((bufferMode == TXDF) || (bufferMode == TXRF)))
{
if (!(CCRcopy & IMASK))
{
CLI; /* restore interrupt mask */
}
return (ERR_CONFIG);
}
bufferStatus = BufferStatus_CAN0[buffer];
if ((bufferMode == TXDF)
&& (bufferStatus == NODATA))
{
if (!(CCRcopy & IMASK))
{
CLI; /* restore interrupt mask */
}
return (ERR_NODATA);
}
if ((bufferStatus == QUEUED) /* MB already queued */
|| (bufferStatus == QUEUED2)
|| (bufferStatus == ABORTREQ))
{
if (!(CCRcopy & IMASK))
{
CLI; /* restore interrupt mask */
}
return (ERR_QED);
}
CAN_L_QueueMB (buffer); /* queue buffer, copy to msCAN if buffer available, */
/* abort msCAN buffer if all full and this buffer higher priority */
if (!(CCRcopy & IMASK))
{
CLI; /* restore interrupt mask */
}
if (CANCTL1 & SLPAK) /* msCAN in SLEEP mode */
{
CANCTL0 &= ~SLPRQ; /* wake-up msCAN */
}
DriverFlags &= ~SLEEP; /* clear sleep request flag */
if (CANCTL0 & SYNCH)
{
return (ERR_OK);
}
else
{
return (ERR_SYNCH);
}
}
/******************************************************************************
Function Name : CAN_L_QueueMB
Engineer : Stuart Robb
Date : 10/8/98
Arguments : buffer number
Return : none
Notes : All interrupts must be disabled when this function is called
******************************************************************************/
void
CAN_L_QueueMB (UINT8 buffer)
{
UINT8 MB_ID_Ref = BufferID_Ref_CAN0[buffer]; /* ID_Ref of this MB = priority of MO */
/* Variables req. only if msCAN transmit buffer is not available */
UINT8 lowestPriority,
lowestPriorityTXBuffer;
/* If: All msCAN transmit buffers are already scheduled:
* and if priority of Message Object in buffer is greater (ID_Ref is less) than any
* Message Object already in msCAN transmit buffer, request abort transmission of the
* msCAN tx buffer with the lowest priority Message Object.
*/
if (CANTIER == 0x07) /* msCAN transmit buffers all scheduled */
/* do not use CANTFLG: TXEn could be set but interrupt not serviced yet */
{
if (buffer < LowestQueuedBuffer)
{
LowestQueuedBuffer = buffer; /* lowest buffer # with QUEUED status, used in TxISR */
}
BufferStatus_CAN0[buffer] = QUEUED;
if ( (MB_ID_Ref < MBP_MSCAN[0]) /* queued MO higher priority than MO in msCAN ? */
||(MB_ID_Ref <MBP_MSCAN[1])
||(MB_ID_Ref < MBP_MSCAN[2]))
{
lowestPriority = MBP_MSCAN[0]; /* find msCAN buffer with lowest priority MO */
lowestPriorityTXBuffer = 0x01;
if (MBP_MSCAN[1] > lowestPriority)
{
lowestPriority = MBP_MSCAN[1];
lowestPriorityTXBuffer = 0x02;
}
if (MBP_MSCAN[2] > lowestPriority)
{
// lowestPriority = TBP_MSCAN[2];
lowestPriorityTXBuffer = 0x04;
}
CANTARQ |= lowestPriorityTXBuffer; /* set ABTRQ for msCAN buffer */
if((AbortMessage == 0xff) || (MB_ID_Ref < BufferID_Ref_CAN0[AbortMessage]))
{
AbortMessage = buffer; /* highest priority queued MB, causing abort */
}
}
}
/* Else: msCAN transmit buffer is available:
* Find free tx buffer: copy identifier into buffer.
* If data frame is to be transmitted, copy data and DLC into buffer, otherwise set RTR bit.
* Write priority reg, schedule buffer and enable interrupt.
*/
else
{
if (MB_MSCAN[0] == 0xff) /* TX_BUFF0 is empty */
{
MBP_MSCAN[0] = BufferID_Ref_CAN0[buffer];
MB_MSCAN[0] = buffer; /* write buffer # */
MSCAN_L_Load_Buff(TX_BUFF0, buffer, MB_ID_Ref);
CANTFLG = 0x01; /* write 1 to TXE to schedule buffer */
CANTIER |= 0x01; /* enable interrupt for this buffer */
}
else
{
if (MB_MSCAN[1] == 0xff) /* TX_BUFF1 is empty */
{
MBP_MSCAN[1] = BufferID_Ref_CAN0[buffer];
MB_MSCAN[1] = buffer; /* write buffer # */
MSCAN_L_Load_Buff(TX_BUFF1, buffer, MB_ID_Ref);
CANTFLG = 0x02; /* write 1 to TXE to schedule buffer */
CANTIER |= 0x02; /* enable interrupt for this buffer */
}
else /* TX_BUFF2 is empty */
{
MBP_MSCAN[2] = BufferID_Ref_CAN0[buffer];
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -