📄 co_candrv.c
字号:
*
* Input: unsigned char _uCAN_Bitrate
*
* Output: none
*
* Side Effects: none
*
* Overview: The predefined BRG values are set.
*
* Note: This message is intended to be called from within
* the event manager. It is also called on reset.
*
* An invalid bitrate will default to _BITRATE0
********************************************************************/
void _CANSetBitRate(void)
{
switch(_uCAN_Bitrate)
{
case 0: /* 1Mbit */
BRGCON1 = CAN_BITRATE0_BRGCON1;
BRGCON2 = CAN_BITRATE0_BRGCON2;
BRGCON3 = CAN_BITRATE0_BRGCON3;
break;
#if CAN_BITRATE1
case 1: /* 800kbits */
BRGCON1 = CAN_BITRATE1_BRGCON1;
BRGCON2 = CAN_BITRATE1_BRGCON2;
BRGCON3 = CAN_BITRATE1_BRGCON3;
break;
#endif
#if CAN_BITRATE2
case 2: /* 500kbits */
BRGCON1 = CAN_BITRATE2_BRGCON1;
BRGCON2 = CAN_BITRATE2_BRGCON2;
BRGCON3 = CAN_BITRATE2_BRGCON3;
break;
#endif
#if CAN_BITRATE3
case 3: /* 500kbits */
BRGCON1 = CAN_BITRATE3_BRGCON1;
BRGCON2 = CAN_BITRATE3_BRGCON2;
BRGCON3 = CAN_BITRATE3_BRGCON3;
break;
#endif
#if CAN_BITRATE4
case 4: /* 250kbits */
BRGCON1 = CAN_BITRATE4_BRGCON1;
BRGCON2 = CAN_BITRATE4_BRGCON2;
BRGCON3 = CAN_BITRATE4_BRGCON3;
break;
#endif
#if CAN_BITRATE5
case 5: /* 125kbits */
BRGCON1 = CAN_BITRATE5_BRGCON1;
BRGCON2 = CAN_BITRATE5_BRGCON2;
BRGCON3 = CAN_BITRATE5_BRGCON3;
break;
#endif
#if CAN_BITRATE6
case 6: /* 50kbits */
BRGCON1 = CAN_BITRATE6_BRGCON1;
BRGCON2 = CAN_BITRATE6_BRGCON2;
BRGCON3 = CAN_BITRATE6_BRGCON3;
break;
#endif
#if CAN_BITRATE7
case 7: /* 20kbits */
BRGCON1 = CAN_BITRATE7_BRGCON1;
BRGCON2 = CAN_BITRATE7_BRGCON2;
BRGCON3 = CAN_BITRATE7_BRGCON3;
break;
#endif
#if CAN_BITRATE8
case 8: /* 10kbits */
BRGCON1 = CAN_BITRATE8_BRGCON1;
BRGCON2 = CAN_BITRATE8_BRGCON2;
BRGCON3 = CAN_BITRATE8_BRGCON3;
break;
#endif
default:
BRGCON1 = CAN_BITRATE0_BRGCON1;
BRGCON2 = CAN_BITRATE0_BRGCON2;
BRGCON3 = CAN_BITRATE0_BRGCON3;
break;
}
}
/* ******** Message Write Services ******* */
/*********************************************************************
* Function: void _CANIsPutReady(void)
*
* PreCondition: A message must have been placed on the bus
* for this function to ever report anything.
*
* Input: unsigned char _uCAN_Handle
*
* Output: unsigned char _uCAN_ret
*
* Side Effects: none
*
* Overview: This function scans for an available output
* buffer. If successful the handle passed is the
* same as the handle returned. Else a NULL is
* returned on a failure.
*
* Note: Buffer access on successive transmit related calls
* is assumed. I.E. the handle is not required for
* associated write functions.
********************************************************************/
void _CANIsPutReady(void)
{
// Check to see if buffer 0 is available
if (!TXB0CONbits.TXREQ) {ECANCON = 0x43; _uCAN_ret = _uCANTxHndls[0] = _uCAN_Handle;}
// Else check to see if buffer 1 is available
else if (!TXB1CONbits.TXREQ) {ECANCON = 0x44; _uCAN_ret = _uCANTxHndls[1] = _uCAN_Handle;}
// Else check to see if buffer 2 is available
else if (!TXB2CONbits.TXREQ) {ECANCON = 0x45; _uCAN_ret = _uCANTxHndls[2] = _uCAN_Handle;}
// Else no more buffers available
else {_uCAN_ret = 0;}
}
/*********************************************************************
* Function: void _CANIsPutFin(void)
*
* PreCondition: A message must have been placed on the bus
* for this function to ever report anything.
*
* Input: none
*
* Output: unsigned char _uCAN_ret
*
* Side Effects: none
*
* Overview: This function scans the output buffers for any
* int flags indicating data has been sent. The
* handle to the message is returned to the user.
*
* Note: This function should only be called one time for
* a tx indication. Calling a second time after
* receiving an indication may not return the same
* handle.
********************************************************************/
void _CANIsPutFin(void)
{
// Check to see if buffer 0 has sent a message
if (TXB0CONbits.TXBIF) {ECANCON = 0x43; TXB0CONbits.TXBIF = 0; _uCAN_ret = _uCANTxHndls[0];}
// Else check to see if buffer 1 has sent a message
else if (TXB1CONbits.TXBIF) {ECANCON = 0x44; TXB0CONbits.TXBIF = 0; _uCAN_ret = _uCANTxHndls[1];}
// Else check to see if buffer 2 has sent a message
else if (TXB2CONbits.TXBIF) {ECANCON = 0x45; TXB0CONbits.TXBIF = 0; _uCAN_ret = _uCANTxHndls[2];}
// Else no message was sent
else {_uCAN_ret = 0;}
}
/* ******** Message Read Services ******* */
/*********************************************************************
* Function: void _CANOpenMessage(void)
*
* PreCondition: _CANEventManager() must be called frequently for
* proper operation.
*
* Input: (unsigned long) _uCAN_Param1
*
* Output: unsigned char _uCAN_ret
*
* Side Effects: none
*
* Overview: This function scans the available mailbox space
* for an open slot. If found the COBID is added to
* the list of received messages.
*
* Note: The COBID is added but not activated until the
* bus is ready. In future CAN modules this queuing
* functionality may be removed depending on
* hardware support.
********************************************************************/
void _CANOpenMessage(void)
{
unsigned char i;
// Scan for an open filter
for (i = 0; i < CAN_MAX_RCV_ENDP; i++)
{
if (_uCANRxHndls[i] == 0)
{
// Save the handle to the object
_uCAN_ret = _uCANRxHndls[i] = _uCAN_Handle;
// Store the ID in a buffer
_uCANRxIDRes[i].dword = *(unsigned long *)(&_uCAN_Param1);
// Set the filter change request flag
_uCANReq = 1;
return;
}
}
_uCAN_ret = 0;
}
/*********************************************************************
* Function: void _CANCloseMessage(void)
*
* PreCondition: Must be a valid handle.
* _CANEventManager() must be called frequently for
* proper operation.
*
* Input: (unsigned long) _uCAN_Param1
*
* Output: none
*
* Side Effects: none
*
* Overview: This function scans the mailbox space for the
* handle. If found the COBID is removed from the
* receive list.
*
* Note: The COBID is only queued to be removed from the
* list. In future CAN modules this queuing
* functionality may be removed depending on
* hardware support.
********************************************************************/
void _CANCloseMessage(void)
{
unsigned char i;
// Scan for an open filter
for (i = 0; i < CAN_MAX_RCV_ENDP; i++)
{
if (_uCANRxHndls[i] == _uCAN_Handle)
{
// Remove the handle
_uCANRxHndls[i] = 0;
// Set the filter change request flag
_uCANReq = 1;
// Indicate a successful close of the message receive endpoint
_uCAN_ret = 1;
return;
}
}
_uCAN_ret = 0;
}
/*********************************************************************
* Function: void _CANIsGetReady(void)
*
* PreCondition: none
*
* Input: none
*
* Output: unsigned char _uCAN_ret
*
* Side Effects: none
*
* Overview: This function scans for a receive event. If found
* it returns the handle associated to the receive
* buffer. Otherwise it returns NULL.
*
* Note: Buffer access on successive receive related calls
* is assumed. I.E. the handle is not required for
* associated read functions.
********************************************************************/
void _CANIsGetReady(void)
{
// Check for a receive interrupt
if (PIR3bits.RXB1IF)
{
// Default receive buffer
ECANCON = 0x50;
// Check for an interrupt and set the appropriate buffer
if (RXB0CONbits.RXFUL) {}
#if CAN_MAX_RCV_ENDP > 2
else if (RXB1CONbits.RXFUL) {ECANCON = 0x51;}
#endif
#if CAN_MAX_RCV_ENDP > 4
else if (B0CONbits.RXFUL) {ECANCON = 0x52;}
#endif
#if CAN_MAX_RCV_ENDP > 6
else if (B1CONbits.RXFUL) {ECANCON = 0x53;}
#endif
#if CAN_MAX_RCV_ENDP > 8
else if (B2CONbits.RXFUL) {ECANCON = 0x54;}
#endif
#if CAN_MAX_RCV_ENDP > 10
else if (B3CONbits.RXFUL) {ECANCON = 0x55;}
#endif
#if CAN_MAX_RCV_ENDP > 12
else if (B4CONbits.RXFUL) {ECANCON = 0x56;}
#endif
#if CAN_MAX_RCV_ENDP > 14
else if (B5CONbits.RXFUL) {ECANCON = 0x57;}
#endif
else {_uCAN_ret = 0; PIR3bits.RXB1IF = 0; return;}
// Remove the interrupt, it will set again if more are pending
//PIR3bits.RXB1IF = 0;
// Decode which filter passed the event and return the handle
// associated to the filter
_uCAN_ret = *((RXB0CON & 0x0F) + _uCANRxHndls);
}
else _uCAN_ret = 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -