📄 mcohw_lpc2.c
字号:
}
#ifndef USE_CANOPEN_MANAGER
/**************************************************************************
DOES: CAN receive interrupt handler
**************************************************************************/
void MCOHW_CANISR_Rx1
(
void
)
{
UNSIGNED32 buf;
UNSIGNED32 *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 = (UNSIGNED32 *) &(gFullCANList[C1RFS & 0x000003FFL].Dat1);
// calculate contents for first entry into FullCAN list
buf = C1RFS & 0xC00F0000L; // mask FF, RTR and DLC
buf |= 0x01000000L; // set semaphore to 01b
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 = 0xFFFFFFFF; // acknowledge Interrupt
}
/**************************************************************************
DOES: CAN transmit interrupt handler
**************************************************************************/
void MCOHW_CANISR_Tx1
(
void
)
{
UNSIGNED32 istat;
istat = C1ICR; // Reset interrupt by reading the register
VICSoftIntClr = 0x00100000;
MCOHW_CheckTxQueue(); // check if something is in the Tx queue
VICVectAddr = 0xFFFFFFFF; // acknowledge Interrupt
}
#endif // USE_CANOPEN_MANAGER
/**************************************************************************
DOES: This function implements the initialization of the CAN interface.
RETURNS: 1 if init is completed
0 if init failed, bit INIT of MCOHW_GetStatus stays 0
**************************************************************************/
UNSIGNED8 MCOHW_Init
(
UNSIGNED16 BaudRate
)
{
if (BaudRate != 125)
{ // This implementation only supports 125kbit
return 0;
}
// Enable Pins for CAN port 1 and 2
PINSEL1 |= (UNSIGNED32) 0x00054000;
C1MOD = 1; // Enter Reset Mode
C1GSR = 0; // Clear status register
C1BTR = CANBitrate125k_12MHz; // Set bit timing
AFMR = 0x00000001; // Disable acceptance filter
// Disable All Interrupts
C1IER = 0;
// Enter Normal Operating Mode
C1MOD = 0; // Operating Mode
// Init Interrupts
VICDefVectAddr = (unsigned long) MCOHW_DefaultISR;
// Initialize Timer Interrupt
T0MR0 = 59999; // 1mSec = 60.000-1 counts
T0MCR = 3; // Interrupt and Reset on MR0
T0TCR = 1; // Timer0 Enable
VICVectAddr0 = (unsigned long) MCOHW_TimerISR; // set interrupt vector
VICVectCntl0 = 0x20 | 4; // use it for Timer 0 Interrupt
VICIntEnable = 0x00000010; // Enable Timer0 Interrupt
VICVectAddr1 = (unsigned long) MCOHW_CANISR_Rx1; // set interrupt vector
VICVectCntl1 = 0x20 | 26; // use it for CAN Rx1 Interrupt
VICIntEnable = 0x04000000; // Enable CAN Rx1 Interrupt
VICVectAddr2 = (unsigned long) MCOHW_CANISR_Tx1; // set interrupt vector
VICVectCntl2 = 0x20 | 20; // use it for CAN Tx1 Interrupt
VICIntEnable = 0x00100000; // Enable CAN Tx1 Interrupt
C1IER = 0x0003; // Enable CAN 1 RX and TX interrupt
gCANFilter = 0; // Reset all filters
// Init Tx queue buffer pointer
mTxIn = 0;
mTxOut = 0;
mStatus |= HW_INIT;
return 1;
}
#ifndef USE_CANOPEN_MANAGER
/**************************************************************************
DOES: This function implements the initialization of a CAN ID hardware
filter as supported by many CAN controllers.
RETURNS: 1 if filter was set
2 if this HW does not support filters
(in this case HW will receive EVERY CAN message)
0 if no more filter is available
**************************************************************************/
UNSIGNED8 MCOHW_SetCANFilter
(
UNSIGNED16 CANID
)
{
int p, n;
int buf0, buf1;
int ID_lower, ID_upper;
UNSIGNED32 candata;
UNSIGNED32 *pAddr;
if (gCANFilter == 0)
{ // First call, init entry zero
gFilterList[0] = 0x37FF; // Disabled and unused
}
if (gCANFilter >= MAX_FILTERS)
{
return 0;
}
// Filters must be sorted by priority
// new filter is sorted into array
p = 0;
while (p < gCANFilter) // loop through all existing filters
{
if (gFilterList[p] > CANID)
{
break;
}
p++;
}
// insert new filter here
buf0 = gFilterList[p]; // save current entry
gFilterList[p] = CANID; // insert the new entry
// move all remaining entries one row up
gCANFilter++;
while (p < gCANFilter)
{
p++;
buf1 = gFilterList[p];
gFilterList[p] = buf0;
buf0 = buf1;
}
// Now work on Acceptance Filter Configuration
// Acceptance Filter Mode Register = off !
AFMR = 0x00000001;
// Set CAN filter for 11-bit standard identifiers
p = 0;
// Set pointer for Standard Frame Individual
// Standard Frame Explicit
SFF_sa = p;
pAddr = (UNSIGNED32 *) ACCEPTANCE_FILTER_RAM_BASE;
for (n = 0; n < (MAX_FILTERS/2); n++)
{
if (n < ((gCANFilter+1)/2))
{
ID_lower = gFilterList[n * 2];
ID_upper = gFilterList[n * 2 + 1];
// 0x20002000 indicates CAN interface 1
candata = 0x20002000 + (ID_lower << 16) + ID_upper;
}
else
{
candata = 0x37FF37FF; // Disabled and unused
}
*pAddr = candata;
p += 4;
pAddr++;
}
// p is still ENDofTable;
// Set pointer for Standard Frame Groups
// Standard Frame Group Start Address Register
SFF_GRP_sa = p;
// Set pointer for Extended Frame Individual
// Extended Frame Start Address Register
EFF_sa = p;
// Set pointer for Extended Frame Groups
// Extended Frame Group Start Address Register
EFF_GRP_sa = p;
// Set ENDofTable
// End of AF Tables Register
ENDofTable = p;
// Acceptance Filter Mode Register, start using filter
AFMR = 0x00000000;
return 1;
}
#endif // USE_CANOPEN_MANAGER
/**************************************************************************
DOES: Timer interrupt handler (1ms)
**************************************************************************/
void MCOHW_TimerISR
(
void
)
{
T0IR = 1; // Clear interrupt flag
gTimCnt++; // increment global timer counter
VICVectAddr = 0xFFFFFFFF; // Acknowledge Interrupt
}
#endif // (NROF_CANPORTS == 1)
/**************************************************************************
DOES: This function reads a 1 millisecond timer tick. The timer tick
must be a UNSIGNED16 and must be incremented once per millisecond.
RETURNS: 1 millisecond timer tick
**************************************************************************/
UNSIGNED16 MCOHW_GetTime (void)
{
return gTimCnt;
}
/**************************************************************************
DOES: This function compares a UNSIGNED16 timestamp to the internal
timer tick and returns 1 if the timestamp expired/passed.
RETURNS: 1 if timestamp expired/passed
0 if timestamp is not yet reached
NOTES: The maximum timer runtime measurable is 0x8000 (about 32 seconds).
For the usage in MicroCANopen that is sufficient.
**************************************************************************/
UNSIGNED8 MCOHW_IsTimeExpired (
UNSIGNED16 timestamp
)
{
UNSIGNED16 time_now;
time_now = gTimCnt;
if (time_now > timestamp)
{
if ((time_now - timestamp) < 0x8000)
return 1;
else
return 0;
}
else
{
if ((timestamp - time_now) > 0x8000)
return 1;
else
return 0;
}
}
/*----------------------- END OF FILE ----------------------------------*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -