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

📄 can.c

📁 LPC11C14 CAN 代码
💻 C
📖 第 1 页 / 共 5 页
字号:
    
    //
    // Configure the Mask Registers.
    //
    if(ptMsgObj->ulFlags & MSG_OBJ_USE_ID_FILTER)
    {
        if(bUseExtendedID)
        {
            //
            // Set the 29 bits of Identifier mask that were requested.
            //
            usMaskReg[0] = ptMsgObj->ulMsgIDMask & CAN_IF1MSK1_IDMSK_M;
            usMaskReg[1] = ((ptMsgObj->ulMsgIDMask >> 16) &
            CAN_IF1MSK2_IDMSK_M);
        }
        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] = ((ptMsgObj->ulMsgIDMask << 2) &
            CAN_IF1MSK2_IDMSK_M);
        }
    }
    
    //
    // If the caller wants to filter on the extended ID bit then set it.
    //
    if((ptMsgObj->ulFlags & MSG_OBJ_USE_EXT_FILTER) ==
    MSG_OBJ_USE_EXT_FILTER)
    {
        usMaskReg[1] |= CAN_IF1MSK2_MXTD;
    }
    
    //
    // The caller wants to filter on the message direction field.
    //
    if((ptMsgObj->ulFlags & MSG_OBJ_USE_DIR_FILTER) ==
    MSG_OBJ_USE_DIR_FILTER)
    {
        usMaskReg[1] |= CAN_IF1MSK2_MDIR;
    }
    
    if(ptMsgObj->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_IF1MCTL_UMASK;
        
        //
        // Set the MASK bit so that this gets trasferred to the Message Object.
        //
        usCmdMaskReg |= CAN_IF1CMSK_MASK;
    }
    
    //
    // Set the Arb bit so that this gets transferred to the Message object.
    //
    usCmdMaskReg |= CAN_IF1CMSK_ARB;
    
    //
    // Configure the Arbitration registers.
    //
    if(bUseExtendedID)
    {
        //
        // Set the 29 bit version of the Identifier for this message object.
        //
        usArbReg[0] |= ptMsgObj->ulMsgID & CAN_IF1ARB1_ID_M;
        usArbReg[1] |= (ptMsgObj->ulMsgID >> 16) & CAN_IF1ARB2_ID_M;
        
        //
        // Mark the message as valid and set the extended ID bit.
        //
        usArbReg[1] |= CAN_IF1ARB2_MSGVAL | CAN_IF1ARB2_XTD;
    }
    else
    {
        //
        // Set the 11 bit version of the Identifier for this message object.
        // The lower 18 bits are set to zero.
        //
        usArbReg[1] |= (ptMsgObj->ulMsgID << 2) & CAN_IF1ARB2_ID_M;
        
        //
        // Mark the message as valid.
        //
        usArbReg[1] |= CAN_IF1ARB2_MSGVAL;
    }
    
    //
    // Set the data length since this is set for all transfers.  This is also a
    // single transfer and not a FIFO transfer so set EOB bit.
    //
    usMsgCtrl |= (ptMsgObj->ulMsgLen & CAN_IF1MCTL_DLC_M) | CAN_IF1MCTL_EOB;
    
    //
    // Enable transmit interrupts if they should be enabled.
    //
    if(ptMsgObj->ulFlags & MSG_OBJ_TX_INT_ENABLE)
    {
        usMsgCtrl |= CAN_IF1MCTL_TXIE;
    }
    
    //
    // Enable receive interrupts if they should be enabled.
    //
    if(ptMsgObj->ulFlags & MSG_OBJ_RX_INT_ENABLE)
    {
        usMsgCtrl |= CAN_IF1MCTL_RXIE;
    }
    
    //
    // Write the data out to the CAN Data registers if needed.
    //
    if(bTransferData)
    {
        CANDataRegWrite(ptMsgObj->pucMsgData,
        (unsigned long *)(&ptBase->IF1_DA1),
        ptMsgObj->ulMsgLen);
    }
    
    //
    // Write out the registers to program the message object.
    //
    canRegWrite((unsigned long)&ptBase->IF1_CMDMSK, usCmdMaskReg);
    canRegWrite((unsigned long)&ptBase->IF1_MSK1, usMaskReg[0]);
    canRegWrite((unsigned long)&ptBase->IF1_MSK2, usMaskReg[1]);
    canRegWrite((unsigned long)&ptBase->IF1_ARB1, usArbReg[0]);
    canRegWrite((unsigned long)&ptBase->IF1_ARB2, usArbReg[1]);
    canRegWrite((unsigned long)&ptBase->IF1_MCTRL, usMsgCtrl);
    
    //
    // Transfer the message object to the message object specifiec by ulObjID.
    //
    canRegWrite((unsigned long)&ptBase->IF1_CMDREQ, ulObjID & CAN_IF1CRQ_MNUM_M);
    
    return;
}

//*****************************************************************************
//
//! Reads a CAN message from one of the message object buffers.
//!
//! \param ptBase is the base address of the CAN controller.
//! \param ulObjID is the object number to read (1-32).
//! \param ptMsgObj points to a structure containing message object fields.
//! \param bClrPendingInt indicates whether an associated interrupt should be
//! cleared.
//!
//! This function is used to read the contents of one of the 32 message objects
//! in the CAN controller, and return it to the caller.  The data returned is
//! stored in the fields of the caller-supplied structure pointed to by
//! \e ptMsgObj.  The data consists of all of the parts of a CAN message,
//! plus some control and status information.
//!
//! Normally this is used to read a message object that has received and stored
//! a CAN message with a certain identifier.  However, this could also be used
//! to read the contents of a message object in order to load the fields of the
//! structure in case only part of the structure needs to be changed from a
//! previous setting.
//!
//! When using CANMessageGet, all of the same fields of the structure are
//! populated in the same way as when the CANMessageSet() function is used,
//! with the following exceptions:
//!
//! \e ptMsgObj->ulFlags:
//!
//! - \b MSG_OBJ_NEW_DATA indicates if this is new data since the last time it
//! was read
//! - \b MSG_OBJ_DATA_LOST indicates that at least one message was received on
//! this message object, and not read by the host before being overwritten.
//!
//! \return None.
//
//*****************************************************************************
void CANMessageGet(unsigned long ulBaseAddr, unsigned long ulObjID,
CAN_MSG_OBJ *ptMsgObj, tBoolean bClrPendingInt)
{
    unsigned short usCmdMaskReg;
    unsigned short usMaskReg[2];
    unsigned short usArbReg[2];
    unsigned short usMsgCtrl;
    LPC_CAN_TypeDef *ptBase = (LPC_CAN_TypeDef *)ulBaseAddr;
    
    //
    // Check the arguments.
    //
    ASSERT(CANBaseValid((unsigned long)ptBase));
    ASSERT((ulObjID <= 32) && (ulObjID != 0));
    
    //
    // This is always a read to the Message object as this call is setting a
    // message object.
    //
    usCmdMaskReg = (CAN_IF1CMSK_DATAA | CAN_IF1CMSK_DATAB |
    CAN_IF1CMSK_CONTROL | CAN_IF1CMSK_MASK | CAN_IF1CMSK_ARB);
    
    //
    // Clear a pending interrupt and new data in a message object.
    //
    if(bClrPendingInt)
    {
        usCmdMaskReg |= CAN_IF1CMSK_CLRINTPND;
    }
    
    //
    // Set up the request for data from the message object.
    //
    canRegWrite((unsigned long)&ptBase->IF2_CMDMSK, usCmdMaskReg);
    
    //
    // Transfer the message object to the message object specifiec by ulObjID.
    //
    canRegWrite((unsigned long)&ptBase->IF2_CMDREQ, ulObjID & CAN_IF1CRQ_MNUM_M);
    
    //
    // Wait for busy bit to clear
    //
    while(canRegRead((unsigned long)&ptBase->IF2_CMDREQ) & CAN_IF1CRQ_BUSY)
    {
    }
    
    //
    // Read out the IF Registers.
    //
    usMaskReg[0] = canRegRead((unsigned long)&ptBase->IF2_MSK1);
    usMaskReg[1] = canRegRead((unsigned long)&ptBase->IF2_MSK2);
    usArbReg[0] = canRegRead((unsigned long)&ptBase->IF2_ARB1);
    usArbReg[1] = canRegRead((unsigned long)&ptBase->IF2_ARB2);
    usMsgCtrl = canRegRead((unsigned long)&ptBase->IF2_MCTRL);
    
    ptMsgObj->ulFlags = MSG_OBJ_NO_FLAGS;
    
    //
    // Determine if this is a remote frame by checking the TXRQST and DIR bits.
    //
    if((!(usMsgCtrl & CAN_IF1MCTL_TXRQST) &&
    (usArbReg[1] & CAN_IF1ARB2_DIR)) ||
    ((usMsgCtrl & CAN_IF1MCTL_TXRQST) &&
    (!(usArbReg[1] & CAN_IF1ARB2_DIR))))
    {
        ptMsgObj->ulFlags |= MSG_OBJ_REMOTE_FRAME;
    }
    
    //
    // Get the identifier out of the register, the format depends on size of
    // the mask.
    //
    if(usArbReg[1] & CAN_IF1ARB2_XTD)
    {
        //
        // Set the 29 bit version of the Identifier for this message object.
        //
        ptMsgObj->ulMsgID = ((usArbReg[1] & CAN_IF1ARB2_ID_M) << 16) |
        usArbReg[0];
        
        ptMsgObj->ulFlags |= MSG_OBJ_EXTENDED_ID;
    }
    else
    {
        //
        // The Identifier is an 11 bit value.
        //
        ptMsgObj->ulMsgID = (usArbReg[1] & CAN_IF1ARB2_ID_M) >> 2;
    }
    
    //
    // Indicate that we lost some data.
    //
    if(usMsgCtrl & CAN_IF1MCTL_MSGLST)
    {
        ptMsgObj->ulFlags |= MSG_OBJ_DATA_LOST;
    }
    
    //
    // Set the flag to indicate if ID masking was used.
    //
    if(usMsgCtrl & CAN_IF1MCTL_UMASK)
    {
        if(usArbReg[1] & CAN_IF1ARB2_XTD)
        {
            //
            // The Identifier Mask is assumed to also be a 29 bit value.
            //
            ptMsgObj->ulMsgIDMask =
            ((usMaskReg[1] & CAN_IF1MSK2_IDMSK_M) << 16) | usMaskReg[0];
            //
            // If this is a fully specified Mask and a remote frame then don't
            // set the MSG_OBJ_USE_ID_FILTER because the ID was not really
            // filtered.
            //
            if((ptMsgObj->ulMsgIDMask != 0x1fffffff) ||
            ((ptMsgObj->ulFlags & MSG_OBJ_REMOTE_FRAME) == 0))
            {
                ptMsgObj->ulFlags |= MSG_OBJ_USE_ID_FILTER;
            }
        }
        else
        {
            //
            // The Identifier Mask is assumed to also be an 11 bit value.
            //
            ptMsgObj->ulMsgIDMask = ((usMaskReg[1] & CAN_IF1MSK2_IDMSK_M) >>
            2);
            
            //
            // If this is a fully specified Mask and a remote frame then don't
            // set the MSG_OBJ_USE_ID_FILTER because the ID was not really
            // filtered.
            //
            if((ptMsgObj->ulMsgIDMask != 0x7ff) ||
            ((ptMsgObj->ulFlags & MSG_OBJ_REMOTE_FRAME) == 0))
            {
                ptMsgObj->ulFlags |= MSG_OBJ_USE_ID_FILTER;
            }
        }
        
        //
        // Indicate if the extended bit was used in filtering.
        //
        if(usMaskReg[1] & CAN_IF1MSK2_MXTD)
        {
            ptMsgObj->ulFlags |= MSG_OBJ_USE_EXT_FILTER;
        }
        
        //
        // Indicate if direction filtering was enabled.
        //
        if(usMaskReg[1] & CAN_IF1MSK2_MDIR)
        {
            ptMsgObj->ulFlags |= MSG_OBJ_USE_DIR_FILTER;
        }
    }
    
    //
    // Set the interupt flags.
    //
    if(usMsgCtrl & CAN_IF1MCTL_TXIE)
    {
        ptMsgObj->ulFlags |= MSG_OBJ_TX_INT_ENABLE;
    }
    if(usMsgCtrl & CAN_IF1MCTL_RXIE)
    {
        ptMsgObj->ulFlags |= MSG_OBJ_RX_INT_ENABLE;
    }
    
    //
    // See if there is new data available.
    //
    if(usMsgCtrl & CAN_IF1MCTL_NEWDAT)
    {
        //
        // Get the amount of data needed to be read.
        //
        ptMsgObj->ulMsgLen = (usMsgCtrl & CAN_IF1MCTL_DLC_

⌨️ 快捷键说明

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