📄 lpc_fullcan_sw.c
字号:
{
case 1:
offset = 0x00000000L; // Use 1st set of CAN registers
break;
#if (MAX_CANPORTS > 1)
case 2:
offset = 0x00001000L; // Use 2nd set of CAN registers
break;
#endif
#if (MAX_CANPORTS > 2)
case 3:
offset = 0x00002000L; // Use 3rd set of CAN registers
break;
#endif
#if (MAX_CANPORTS > 3)
case 4:
offset = 0x00003000L; // Use 4th set of CAN registers
break;
#endif
default:
return 0; // illegal value used
}
pAddr = (unsigned int *) &C1SR + offset; // CANSR
if (!(*pAddr & 0x00000004L))
{ // Transmit Channel is not available
return 0; // No channel available
}
// Write DLC
pAddr = (unsigned int *) &C1TFI1 + offset;
*pAddr = pTransmitBuf->Dat1 & 0x000F0000L;
// Write CAN ID
pAddr++;
*pAddr = pTransmitBuf->Dat1 & 0x000007FFL;
// Write first 4 data bytes
pCandata = (unsigned int *) &(pTransmitBuf->DatA);
pAddr++;
*pAddr = *pCandata;
// Write second 4 data bytes
pCandata++;
pAddr++;
*pAddr = *pCandata;
// Write self transmission request
pAddr = (unsigned int *) &C1CMR + offset;
*pAddr = 0x30; // Self Transmission Request Buf 1
return 1;
}
/**************************************************************************
Receiving a CAN message
as described in LPC_FullCAN_SW.h
***************************************************************************/
short FullCAN_PullMessage (
unsigned short can_port,
FULLCAN_MSG *pReceiveBuf
)
{
unsigned short obj; // loop counter for message objects/filters
unsigned int *pSrc; // Source pointer
unsigned int *pDst; // Destination pointer
unsigned int match; // Match value for can_port and semaphore
// Double check can_port value
if ((can_port < 1) || (can_port > MAX_CANPORTS))
{ // Illegal value for can_port
return 0;
}
// Initialize pointers
pSrc = (unsigned int *) &(gFullCANList[0].Dat1);
pDst = (unsigned int *) &(pReceiveBuf->Dat1);
// Prepare match value for CAN interface
match = can_port << 13;
match |= 0x03000000L; // Semaphore bits are 11b
obj = 0;
while (obj < gCANFilter)
{
// match can_port and semaphore set to 11?
if ((*pSrc & 0x0300E000L) == match)
{ // Object Updated since last access
*pSrc &= 0xFCFFFFFFL; // clear Semaphore
*pDst = *pSrc; // Copy Dat1
pSrc++; // set to gFullCANList[obj].DatA
pDst++; // set to pReceiveBuf->DatA
*pDst = *pSrc; // Copy DatA
pSrc++; // set to gFullCANList[obj].DatB
pDst++; // set to pReceiveBuf->DatB
*pDst = *pSrc; // Copy DatB
pSrc -= 2; // set back to gFullCANList[obj].Dat1
pDst -= 2; // set back to &(pReceiveBuf->Dat1)
if ((*pSrc & 0x03000000L) == 0)
{ // Only return it, if not updated while reading
return 1;
}
}
obj ++; // Next message object buffer
pSrc += 3; // set to gFullCANList[obj].Dat1
}
return 0; // Return False, no msg rcvd
}
/**************************************************************************
PRIVATE FUNCTIONS
***************************************************************************/
/**************************************************************************
DOES: Interrupt Service Routine for CAN Errors
GLOBALS: none
RETURNS: nothing
***************************************************************************/
void FullCAN_CANISR_Err (
void
)
{
// DEBUG VERSION: do not return from Errors
// Replace this with application specific error handling
while (1)
{
}
VICVectAddr = 0xFFFFFFFFL; // acknowledge Interrupt
}
/**************************************************************************
DOES: Interrupt Service Routine for CAN receive on CAN interface 1
GLOBALS: Copies the received message into the gFullCANList[] array
Handles semaphore bits as described in LPC user manual
RETURNS: nothing
***************************************************************************/
void FullCAN_CANISR_Rx1 (
void
)
{
unsigned int buf;
unsigned int *pDest;
if (!(C1RFS & 0xC0000400L))
{ // 11-bit ID, no RTR, matched a filter
// initialize destination pointer
// filter number is in lower 10 bits of C1RFS
pDest = (unsigned int *) &(gFullCANList[(C1RFS & 0x000003FFL)].Dat1);
// calculate contents for first entry into FullCAN list
buf = C1RFS & 0xC00F0000L; // mask FF, RTR and DLC
buf |= 0x01002000L; // set semaphore to 01b and CAN port to 1
buf |= C1RID & 0x000007FFL; // get CAN message ID
// now copy entire message to FullCAN list
*pDest = buf;
pDest++; // set to gFullCANList[(C1RFS & 0x000003FFL)].DatA
*pDest = C1RDA;
pDest++; // set to gFullCANList[(C1RFS & 0x000003FFL)].DatB
*pDest = C1RDB;
// now set the sempahore to complete
buf |= 0x03000000L; // set semaphore to 11b
pDest -= 2; // set to gFullCANList[(C1RFS & 0x000003FFL)].Dat1
*pDest = buf;
}
C1CMR = 0x04; // release receive buffer
VICVectAddr = 0xFFFFFFFFL; // acknowledge Interrupt
}
#if (MAX_CANPORTS > 1)
/**************************************************************************
DOES: Interrupt Service Routine for CAN receive on CAN interface 2
GLOBALS: Copies the received message into the gFullCANList[] array
Handles semaphore bits as described in LPC user manual
RETURNS: nothing
***************************************************************************/
void FullCAN_CANISR_Rx2 (
void
)
{
unsigned int buf;
unsigned int *pDest;
if (!(C2RFS & 0xC0000400L))
{ // 11-bit ID, no RTR, matched a filter
// initialize destination pointer
// filter number is in lower 10 bits of C2RFS
pDest = (unsigned int *) &(gFullCANList[(C2RFS & 0x000003FFL)].Dat1);
// calculate contents for first entry into FullCAN list
buf = C2RFS & 0xC00F0000L; // mask FF, RTR and DLC
buf |= 0x01004000L; // set semaphore to 01b and CAN port to 2
buf |= C2RID & 0x000007FFL; // get CAN message ID
// now copy entire message to FullCAN list
*pDest = buf;
pDest++; // set to gFullCANList[(C2RFS & 0x000003FFL)].DatA
*pDest = C2RDA;
pDest++; // set to gFullCANList[(C2RFS & 0x000003FFL)].DatB
*pDest = C2RDB;
// now set the sempahore to complete
buf |= 0x03000000L; // set semaphore to 11b
pDest -= 2; // set to gFullCANList[(C2RFS & 0x000003FFL)].Dat1
*pDest = buf;
}
C2CMR = 0x04; // release receive buffer
VICVectAddr = 0xFFFFFFFFL; // acknowledge Interrupt
}
#endif // MAX_CANPORTS > 1
#if (MAX_CANPORTS > 2)
/**************************************************************************
DOES: Interrupt Service Routine for CAN receive on CAN interface 3
GLOBALS: Copies the received message into the gFullCANList[] array
Handles semaphore bits as described in LPC user manual
RETURNS: nothing
***************************************************************************/
void FullCAN_CANISR_Rx3 (
void
)
{
unsigned int buf;
unsigned int *pDest;
if (!(C3RFS & 0xC0000400L))
{ // 11-bit ID, no RTR, matched a filter
// initialize destination pointer
// filter number is in lower 10 bits of C3RFS
pDest = (unsigned int *) &(gFullCANList[(C3RFS & 0x000003FFL)].Dat1);
// calculate contents for first entry into FullCAN list
buf = C3RFS & 0xC00F0000L; // mask FF, RTR and DLC
buf |= 0x01006000L; // set semaphore to 01b and CAN port to 3
buf |= C3RID & 0x000007FFL; // get CAN message ID
// now copy entire message to FullCAN list
*pDest = buf;
pDest++; // set to gFullCANList[(C3RFS & 0x000003FFL)].DatA
*pDest = C3RDA;
pDest++; // set to gFullCANList[(C3RFS & 0x000003FFL)].DatB
*pDest = C3RDB;
// now set the sempahore to complete
buf |= 0x03000000L; // set semaphore to 11b
pDest -= 2; // set to gFullCANList[(C3RFS & 0x000003FFL)].Dat1
*pDest = buf;
}
C3CMR = 0x04; // release receive buffer
VICVectAddr = 0xFFFFFFFFL; // acknowledge Interrupt
}
#endif // MAX_CANPORTS > 2
#if (MAX_CANPORTS > 3)
/**************************************************************************
DOES: Interrupt Service Routine for CAN receive on CAN interface 4
GLOBALS: Copies the received message into the gFullCANList[] array
Handles semaphore bits as described in LPC user manual
RETURNS: nothing
***************************************************************************/
void FullCAN_CANISR_Rx4 (
void
)
{
unsigned int buf;
unsigned int *pDest;
if (!(C4RFS & 0xC0000400L))
{ // 11-bit ID, no RTR, matched a filter
// initialize destination pointer
// filter number is in lower 10 bits of C4RFS
pDest = (unsigned int *) &(gFullCANList[(C4RFS & 0x000003FFL)].Dat1);
// calculate contents for first entry into FullCAN list
buf = C4RFS & 0xC00F0000L; // mask FF, RTR and DLC
buf |= 0x01008000L; // set semaphore to 01b and CAN port to 4
buf |= C2RID & 0x000007FFL; // get CAN message ID
// now copy entire message to FullCAN list
*pDest = buf;
pDest++; // set to gFullCANList[(C4RFS & 0x000003FFL)].DatA
*pDest = C4RDA;
pDest++; // set to gFullCANList[(C4RFS & 0x000003FFL)].DatB
*pDest = C4RDB;
// now set the sempahore to complete
buf |= 0x03000000L; // set semaphore to 11b
pDest -= 2; // set to gFullCANList[(C4RFS & 0x000003FFL)].Dat1
*pDest = buf;
}
C4CMR = 0x04; // release receive buffer
VICVectAddr = 0xFFFFFFFFL; // acknowledge Interrupt
}
#endif // MAX_CANPORTS > 4
/*----------------------- END OF FILE ----------------------------------*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -