⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 can.c

📁 uCOS-II V2.84 LM3S6965 TCPIP Demo
💻 C
📖 第 1 页 / 共 5 页
字号:

        //
        // Combine the Message valid status bits into one 32bit value.
        //
        case CAN_STS_MSGVAL:
        {
            ulStatus = CANReadReg(ulBase + CAN_O_MSGVAL1);
            ulStatus |= CANReadReg(ulBase + CAN_O_MSGVAL2) << 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
//! - \b true if the receive error count has reached the error passive limit.
//! - \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((ulBase == CAN0_BASE) ||
           (ulBase == CAN1_BASE));

    //
    // Read the current count of transmit/receive errors.
    //
    ulCANError = CANReadReg(ulBase + CAN_O_ERR);

    //
    // Extract the error numbers from the register value.
    //
    *pulRxCount = (ulCANError & CAN_ERR_REC_MASK) >> CAN_ERR_REC_SHIFT;
    *pulTxCount = (ulCANError & CAN_ERR_TEC_MASK) >> CAN_ERR_TEC_SHIFT;

    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 what type of message this object is.
//!
//! 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:
//!
//! - MSG_OBJ_TYPE_TX - CAN transmit message object.
//! - MSG_OBJ_TYPE_TX_REMOTE - CAN transmit remote request message
//! object.
//! - MSG_OBJ_TYPE_RX - CAN receive message object.
//! - MSG_OBJ_TYPE_RX_REMOTE - CAN receive remote request message object.
//! - 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 MSG_OBJ_TX_INT_ENABLE flag to enable interrupt on transmission.
//!   - Set MSG_OBJ_RX_INT_ENABLE flag to enable interrupt on receipt.
//!   - Set 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
//!
//! To send a data frame or remote frame directly, take the following steps:
//!
//! - set \e tMsgObjType to MSG_OBJ_TYPE_TX.
//! - set \e ulMsgID to the message ID.
//! - set \e ulFlags Set MSG_OBJ_TX_INT_ENABLE to to get an interrupt when the
//! message is sent. To disable filtering based on message identifiers, do not
//! set MSG_OBJ_USE_ID_FILTER.
//! - set \e ulMsgLen to the number of bytes in the data frame.
//! - set \e pucMsgData to point to an array containing the bytes in the
//! message (if a data frame, n/a if remote frame, though it is a good
//! idea to set this to point to a valid buffer).
//! - call this function with \e ulObjID set to one of the 32 object buffers.
//!
//! To receive a specific data frame, take the following steps:
//!
//! - set \e tMsgObjType to MSG_OBJ_TYPE_RX.
//! - set \e ulMsgID to the full message ID, or a partial mask to use partial
//! ID matching.
//! - set \e ulMsgIDMask bits that should be used for masking during
//! comparison.
//! - \e ulFlags
//!   - Set MSG_OBJ_TX_INT_ENABLE flag to be interrupted when the data frame is
//!   received.
//!   - Set MSG_OBJ_USE_ID_FILTER flag to enable identifier based filtering.
//! - set \e ulMsgLen to the number of bytes in the expected data frame
//! - the buffer pointed to by \e pucMsgData is not used for this 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
CANMessageSet(unsigned long ulBase, unsigned long ulObjID,
              tCANMsgObject *pMsgObject, tMsgObjType eMsgType)
{
    unsigned short usCmdMaskReg;
    unsigned short usMaskReg[2];
    unsigned short usArbReg[2];
    unsigned short usMsgCtrl;
    tBoolean bTransferData;
    tBoolean bUseExtendedID;

    bTransferData = 0;

    //
    // Check the arguments.
    //
    ASSERT((ulBase == CAN0_BASE) ||
           (ulBase == CAN1_BASE));
    ASSERT((ulObjID <= 32) && (ulObjID != 0));
    ASSERT((eMsgType == MSG_OBJ_TYPE_TX) ||
           (eMsgType == MSG_OBJ_TYPE_TX_REMOTE) ||
           (eMsgType == MSG_OBJ_TYPE_RX) ||
           (eMsgType == MSG_OBJ_TYPE_RX_REMOTE) ||
           (eMsgType == MSG_OBJ_TYPE_TX_REMOTE));

    //
    // Wait for busy bit to clear
    //
    while(CANReadReg(ulBase + CAN_O_IF1CRQ) & CAN_IFCRQ_BUSY)
    {
    }

    //
    // See if we need to use an extended identifier or not.
    //
    if((pMsgObject->ulMsgID > CAN_MAX_11BIT_MSG_ID) ||
       (pMsgObject->ulFlags & MSG_OBJ_EXTENDED_ID))
    {
        bUseExtendedID = 1;
    }
    else
    {
        bUseExtendedID = 0;
    }

    //
    // This is always a write to the Message object as this call is setting
    // a message object.
    // This call will also always set all size bits so it sets both data bits.
    // The call will use the CONTROL register to set control bits so this bit
    // needs to be set as well.
    //
    usCmdMaskReg = CAN_IFCMSK_WRNRD | CAN_IFCMSK_DATAA | CAN_IFCMSK_DATAB |
        CAN_IFCMSK_CONTROL;

    //
    // Initialize the values to a known state before filling them in based
    // on the type of message object that is being configured.
    //
    usArbReg[0] = 0;
    usMsgCtrl = 0;
    usMaskReg[0] = 0;
    usMaskReg[1] = 0;

    switch(eMsgType)
    {
        //
        // Transmit message object.
        //
        case MSG_OBJ_TYPE_TX:
        {
            //
            // Set the TXRQST bit and the reset the rest of the register.
            //
            usMsgCtrl |= CAN_IFMCTL_TXRQST;
            usArbReg[1] = CAN_IFARB2_DIR;
            bTransferData = 1;
            break;
        }

        //
        // Transmit remote request message object
        //
        case MSG_OBJ_TYPE_TX_REMOTE:
        {
            //
            // Set the TXRQST bit and the reset the rest of the register.
            //
            usMsgCtrl |= CAN_IFMCTL_TXRQST;
            usArbReg[1] = 0;
            break;
        }

        //
        // Receive message object.
        //
        case MSG_OBJ_TYPE_RX:
        {
            //
            // This clears the DIR bit along with everthing else.  The
            // TXRQST bit was cleard by defaulting usMsgCtrl to 0.
            //
            usArbReg[1] = 0;
            break;
        }

        //
        // Receive remote request message object.
        //
        case MSG_OBJ_TYPE_RX_REMOTE:
        {
            //
            // The DIR bit is set to one for remote receivers.  The
            // TXRQST bit was cleard by defaulting usMsgCtrl to 0.
            //
            usArbReg[1] = CAN_IFARB2_DIR;

            //
            // Set this object so that it only indicates that a remote frame
            // was received and allow for software to handle it by sending back
            // a data frame.
            //
            usMsgCtrl = CAN_IFMCTL_UMASK;

            //
            // Use the full Identifier by default.
            //
            usMaskReg[0] = 0xffff;
            usMaskReg[1] = 0x1fff;

            //
            // Make sure to send the mask to the message object.
            //
            usCmdMaskReg |= CAN_IFCMSK_MASK;
            break;
        }

        //
        // Remote frame receive remote, with auto-transmit message object.
        //
        case MSG_OBJ_TYPE_RXTX_REMOTE:
        {
            //
            // Oddly the DIR bit is set to one for remote receivers.
            //
            usArbReg[1] = CAN_IFARB2_DIR;

            //
            // Set this object to auto answer if a matching identifier is seen.
            //
            usMsgCtrl = CAN_IFMCTL_RMTEN | CAN_IFMCTL_UMASK;

            //
            // The data to be returned needs to be filled in.
            //
            bTransferData = 1;
            break;
        }

        //
        // This case should never happen due to the ASSERT statement at the
        // beginning of this function.
        //
        default:
        {
            return;
        }
    }

    //
    // Configure the Mask Registers.
    //
    if(pMsgObject->ulFlags & MSG_OBJ_USE_ID_FILTER)
    {
        if(bUseExtendedID)
        {
            //
            // Set the 29 bits of Identifier mask that were requested.
            //
            usMaskReg[0] = pMsgObject->ulMsgIDMask & CAN_IFMSK1_MSK;
            usMaskReg[1] = (pMsgObject->ulMsgIDMask >> 16) & CAN_IFMSK2_MSK;
        }
        else
        {
            //
            // Lower 16 bit are unused so set them to zero.
            //
            usMaskReg[0] = 0;
            //
            // Put the 11 bit Mask Identifier into the upper bits of the field
            // in the register.
            //
            usMaskReg[1] = (pMsgObject->ulMsgIDMask << 2) & CAN_IFMSK2_MSK;
        }
    }

    //
    // If the caller wants to filter on the extended ID bit then set it.
    //
    if((pMsgObject->ulFlags & MSG_OBJ_USE_EXT_FILTER) ==
        MSG_OBJ_USE_EXT_FILTER)
    {
        usMaskReg[1] |= CAN_IFMSK2_MXTD;
    }

    //
    // The caller wants to filter on the message direction field.
    //
    if((pMsgObject->ulFlags & MSG_OBJ_USE_DIR_FILTER) ==
        MSG_OBJ_USE_DIR_FILTER)
    {
        usMaskReg[1] |= CAN_IFMSK2_MDIR;
    }

    if(pMsgObject->ulFlags & (MSG_OBJ_USE_ID_FILTER | MSG_OBJ_USE_DIR_FILTER |
       MSG_OBJ_USE_EXT_FILTER))
    {
        //
        // Set the UMASK bit to enable using the mask register.
        //
        usMsgCtrl |= CAN_IFMCTL_UMASK;

        //
        // Set the MASK bit so that this gets trasferred to the Message Object.
        //
        usCmdMaskReg |= CAN_IFCMSK_MASK;
    }

    //
    // Set the Arb bit so that this gets transferred to the Message object.
    //
    usCmdMaskReg |= CAN_IFCMSK_ARB;

    //
    // Configure the Arbitration registers.
    //
    if(bUseExtendedID)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -