📄 can.c
字号:
//!
//! \return None.
//
//*****************************************************************************
void
CANIntClear(unsigned long ulBase, unsigned long ulIntClr)
{
//
// Check the arguments.
//
ASSERT(CANBaseValid(ulBase));
ASSERT((ulIntClr == CAN_INT_INTID_STATUS) ||
((ulIntClr>=1) && (ulIntClr <=32)));
if(ulIntClr == CAN_INT_INTID_STATUS)
{
//
// Simply read and discard the status to clear the interrupt.
//
CANRegRead(ulBase + CAN_O_STS);
}
else
{
//
// Wait to be sure that this interface is not busy.
//
while(CANRegRead(ulBase + CAN_O_IF1CRQ) & CAN_IF1CRQ_BUSY)
{
}
//
// Only change the interrupt pending state by setting only the
// CAN_IF1CMSK_CLRINTPND bit.
//
CANRegWrite(ulBase + CAN_O_IF1CMSK, CAN_IF1CMSK_CLRINTPND);
//
// Send the clear pending interrupt command to the CAN controller.
//
CANRegWrite(ulBase + CAN_O_IF1CRQ, ulIntClr & CAN_IF1CRQ_MNUM_M);
//
// Wait to be sure that this interface is not busy.
//
while(CANRegRead(ulBase + CAN_O_IF1CRQ) & CAN_IF1CRQ_BUSY)
{
}
}
}
//*****************************************************************************
//
//! Sets the CAN controller automatic retransmission behavior.
//!
//! \param ulBase is the base address of the CAN controller.
//! \param bAutoRetry enables automatic retransmission.
//!
//! Enables or disables automatic retransmission of messages with detected
//! errors. If \e bAutoRetry is \b true, then automatic retransmission is
//! enabled, otherwise it is disabled.
//!
//! \return None.
//
//*****************************************************************************
void
CANRetrySet(unsigned long ulBase, tBoolean bAutoRetry)
{
unsigned long ulCtlReg;
//
// Check the arguments.
//
ASSERT(CANBaseValid(ulBase));
ulCtlReg = CANRegRead(ulBase + CAN_O_CTL);
//
// Conditionally set the DAR bit to enable/disable auto-retry.
//
if(bAutoRetry)
{
//
// Clearing the DAR bit tells the controller to not disable the
// auto-retry of messages which were not transmitted or received
// correctly.
//
ulCtlReg &= ~CAN_CTL_DAR;
}
else
{
//
// Setting the DAR bit tells the controller to disable the auto-retry
// of messages which were not transmitted or received correctly.
//
ulCtlReg |= CAN_CTL_DAR;
}
CANRegWrite(ulBase + CAN_O_CTL, ulCtlReg);
}
//*****************************************************************************
//
//! Returns the current setting for automatic retransmission.
//!
//! \param ulBase is the base address of the CAN controller.
//!
//! Reads the current setting for the automatic retransmission in the CAN
//! controller and returns it to the caller.
//!
//! \return Returns \b true if automatic retransmission is enabled, \b false
//! otherwise.
//
//*****************************************************************************
tBoolean
CANRetryGet(unsigned long ulBase)
{
//
// Check the arguments.
//
ASSERT(CANBaseValid(ulBase));
//
// Read the disable automatic retry setting from the CAN controller.
//
if(CANRegRead(ulBase + CAN_O_CTL) & CAN_CTL_DAR)
{
//
// Automatic data retransmission is not enabled.
//
return(false);
}
//
// Automatic data retransmission is enabled.
//
return(true);
}
//*****************************************************************************
//
//! Reads one of the controller status registers.
//!
//! \param ulBase is the base address of the CAN controller.
//! \param eStatusReg is the status register to read.
//!
//! Reads a status register of the CAN controller and returns it to the caller.
//! The different status registers are:
//!
//! - \b CAN_STS_CONTROL - the main controller status
//! - \b CAN_STS_TXREQUEST - bit mask of objects pending transmission
//! - \b CAN_STS_NEWDAT - bit mask of objects with new data
//! - \b CAN_STS_MSGVAL - bit mask of objects with valid configuration
//!
//! When reading the main controller status register, a pending status
//! interrupt will be cleared. This should be used in the interrupt handler
//! for the CAN controller if the cause is a status interrupt. The controller
//! status register fields are as follows:
//!
//! - \b CAN_STATUS_BUS_OFF - controller is in bus-off condition
//! - \b CAN_STATUS_EWARN - an error counter has reached a limit of at least 96
//! - \b CAN_STATUS_EPASS - CAN controller is in the error passive state
//! - \b CAN_STATUS_RXOK - a message was received successfully (independent of
//! any message filtering).
//! - \b CAN_STATUS_TXOK - a message was successfully transmitted
//! - \b CAN_STATUS_LEC_MSK - mask of last error code bits (3 bits)
//! - \b CAN_STATUS_LEC_NONE - no error
//! - \b CAN_STATUS_LEC_STUFF - stuffing error detected
//! - \b CAN_STATUS_LEC_FORM - a format error occurred in the fixed format part
//! of a message
//! - \b CAN_STATUS_LEC_ACK - a transmitted message was not acknowledged
//! - \b CAN_STATUS_LEC_BIT1 - dominant level detected when trying to send in
//! recessive mode
//! - \b CAN_STATUS_LEC_BIT0 - recessive level detected when trying to send in
//! dominant mode
//! - \b CAN_STATUS_LEC_CRC - CRC error in received message
//!
//! The remaining status registers are 32-bit bit maps to the message objects.
//! They can be used to quickly obtain information about the status of all the
//! message objects without needing to query each one. They contain the
//! following information:
//!
//! - \b CAN_STS_TXREQUEST - if a message object's TxRequest bit is set, that
//! means that a transmission is pending on that object. The application can
//! use this to determine which objects are still waiting to send a message.
//! - \b CAN_STS_NEWDAT - if a message object's NewDat bit is set, that means
//! that a new message has been received in that object, and has not yet been
//! picked up by the host application
//! - \b CAN_STS_MSGVAL - if a message object's MsgVal bit is set, that means
//! it has a valid configuration programmed. The host application can use this
//! to determine which message objects are empty/unused.
//!
//! \return Returns the value of the status register.
//
//*****************************************************************************
unsigned long
CANStatusGet(unsigned long ulBase, tCANStsReg eStatusReg)
{
unsigned long ulStatus;
//
// Check the arguments.
//
ASSERT(CANBaseValid(ulBase));
switch(eStatusReg)
{
//
// Just return the global CAN status register since that is what was
// requested.
//
case CAN_STS_CONTROL:
{
ulStatus = CANRegRead(ulBase + CAN_O_STS);
CANRegWrite(ulBase + CAN_O_STS,
~(CAN_STS_RXOK | CAN_STS_TXOK | CAN_STS_LEC_M));
break;
}
//
// Combine the Transmit status bits into one 32bit value.
//
case CAN_STS_TXREQUEST:
{
ulStatus = CANRegRead(ulBase + CAN_O_TXRQ1);
ulStatus |= CANRegRead(ulBase + CAN_O_TXRQ2) << 16;
break;
}
//
// Combine the New Data status bits into one 32bit value.
//
case CAN_STS_NEWDAT:
{
ulStatus = CANRegRead(ulBase + CAN_O_NWDA1);
ulStatus |= CANRegRead(ulBase + CAN_O_NWDA2) << 16;
break;
}
//
// Combine the Message valid status bits into one 32bit value.
//
case CAN_STS_MSGVAL:
{
ulStatus = CANRegRead(ulBase + CAN_O_MSG1VAL);
ulStatus |= CANRegRead(ulBase + CAN_O_MSG2VAL) << 16;
break;
}
//
// Unknown CAN status requested so return 0.
//
default:
{
ulStatus = 0;
break;
}
}
return(ulStatus);
}
//*****************************************************************************
//
//! Reads the CAN controller error counter register.
//!
//! \param ulBase is the base address of the CAN controller.
//! \param pulRxCount is a pointer to storage for the receive error counter.
//! \param pulTxCount is a pointer to storage for the transmit error counter.
//!
//! Reads the error counter register and returns the transmit and receive error
//! counts to the caller along with a flag indicating if the controller receive
//! counter has reached the error passive limit. The values of the receive and
//! transmit error counters are returned through the pointers provided as
//! parameters.
//!
//! After this call, \e *pulRxCount will hold the current receive error count
//! and \e *pulTxCount will hold the current transmit error count.
//!
//! \return Returns \b true if the receive error count has reached the error
//! passive limit, and \b false if the error count is below the error passive
//! limit.
//
//*****************************************************************************
tBoolean
CANErrCntrGet(unsigned long ulBase, unsigned long *pulRxCount,
unsigned long *pulTxCount)
{
unsigned long ulCANError;
//
// Check the arguments.
//
ASSERT(CANBaseValid(ulBase));
//
// Read the current count of transmit/receive errors.
//
ulCANError = CANRegRead(ulBase + CAN_O_ERR);
//
// Extract the error numbers from the register value.
//
*pulRxCount = (ulCANError & CAN_ERR_REC_M) >> CAN_ERR_REC_S;
*pulTxCount = (ulCANError & CAN_ERR_TEC_M) >> CAN_ERR_TEC_S;
if(ulCANError & CAN_ERR_RP)
{
return(true);
}
return(false);
}
//*****************************************************************************
//
//! Configures a message object in the CAN controller.
//!
//! \param ulBase is the base address of the CAN controller.
//! \param ulObjID is the object number to configure (1-32).
//! \param pMsgObject is a pointer to a structure containing message object
//! settings.
//! \param eMsgType indicates the type of message for this object.
//!
//! This function is used to configure any one of the 32 message objects in the
//! CAN controller. A message object can be configured as any type of CAN
//! message object as well as several options for automatic transmission and
//! reception. This call also allows the message object to be configured to
//! generate interrupts on completion of message receipt or transmission. The
//! message object can also be configured with a filter/mask so that actions
//! are only taken when a message that meets certain parameters is seen on the
//! CAN bus.
//!
//! The \e eMsgType parameter must be one of the following values:
//!
//! - \b MSG_OBJ_TYPE_TX - CAN transmit message object.
//! - \b MSG_OBJ_TYPE_TX_REMOTE - CAN transmit remote request message object.
//! - \b MSG_OBJ_TYPE_RX - CAN receive message object.
//! - \b MSG_OBJ_TYPE_RX_REMOTE - CAN receive remote request message object.
//! - \b MSG_OBJ_TYPE_RXTX_REMOTE - CAN remote frame receive remote, then
//! transmit message object.
//!
//! The message object pointed to by \e pMsgObject must be populated by the
//! caller, as follows:
//!
//! - \e ulMsgID - contains the message ID, either 11 or 29 bits.
//! - \e ulMsgIDMask - mask of bits from \e ulMsgID that must match if
//! identifier filtering is enabled.
//! - \e ulFlags
//! - Set \b MSG_OBJ_TX_INT_ENABLE flag to enable interrupt on transmission.
//! - Set \b MSG_OBJ_RX_INT_ENABLE flag to enable interrupt on receipt.
//! - Set \b MSG_OBJ_USE_ID_FILTER flag to enable filtering based on the
//! identifier mask specified by \e ulMsgIDMask.
//! - \e ulMsgLen - the number of bytes in the message data. This should be
//! non-zero even for a remote frame; it should match the expected bytes of the
//! data responding data frame.
//! - \e pucMsgData - points to a buffer containing up to 8 bytes of data for a
//! data frame.
//!
//! \b Example: To send a data frame or remote frame(in response to a remote
//! request), take the following steps:
//!
//! -# Set \e eMsgType to \b MSG_OBJ_TYPE_TX.
//! -# Set \e pMsgObject->ulMsgID to the message ID.
//! -# Set \e pMsgObject->ulFlags. Make sure to set \b MSG_OBJ_TX_INT_ENABLE to
//! allow an interrupt to be generated when the message is sent.
//! -# Set \e pMsgObject->ulMsgLen to the number of bytes in the data frame.
//! -# Set \e pMsgObject->pucMsgData to point to an array containing the bytes
//! to send in the message.
//! -# Call this function with \e ulObjID set to one of the 32 object buffers.
//!
//! \b Example: To receive a specific data frame, take the following steps:
//!
//! -# Set \e eMsgObjType to \b MSG_OBJ_TYPE_RX.
//! -# Set \e pMsgObject->ulMsgID to the full message ID, or a partial mask to
//! use partial ID matching.
//! -# Set \e pMsgObject->ulMsgIDMask bits that should be used for masking
//! during comparison.
//! -# Set \e pMsgObject->ulFlags as follows:
//! - Set \b MSG_OBJ_RX_INT_ENABLE flag to be interrupted when the data frame
//! is received.
//! - Set \b MSG_OBJ_USE_ID_FILTER flag to enable identifier based filtering.
//! -# Set \e pMsgObject->ulMsgLen to the number of bytes in the expected data
//! frame.
//! -# The buffer pointed to by \e pMsgObject->pucMsgData is not used by this
//! call as no data is present at the time of the call.
//! -# Call this function with \e ulObjID set to one of the 32 object buffers.
//!
//! If you specify a message object buffer that already contains a message
//! definition, it will be overwritten.
//!
//! \return None.
//
//*****************************************************************************
void
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -