This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

F28377D Can NewDat Flag

Other Parts Discussed in Thread: CONTROLSUITE

Hello and good morning,

I have a question regarding the CAN interface and the can library which comes within the control suite:

I use "CANMessageSet" and "CANMessageGet" for sending/receiving messages over the CAN interface in loopback mode (for testing). The CANMessageGet-Method also sets the Bit TxRqst in CAN_IF2CMD, so the "NewData" Flag for this message object should be cleared, but it does not get cleared.

When I call "CANMessageGet" several times (without a new message), i always get the "NewData" flag set, and of course if new data comes in the "DataLost" flag is also set (even if there is no data lost, but the NewData flag was still set).

Any ideas what might be the problem here?

BR,
Michael

  • Hi Michael,

    Are you using a sample code present in controlSuite or have you modified it?

    When I call "CANMessageGet" several times (without a new message), i always get the "NewData" flag set, and of course if new data comes in the "DataLost" flag is also set (even if there is no data lost, but the NewData flag was still set).

    This indicates that you've modified the sample code. BTW did you go through the CAN routine for CANMessageGET?

    Go through this and all your doubts would be cleared: (If you still have any, do let us know)

    //*****************************************************************************
    //! Reads a CAN message from one of the message object buffers.
    //!
    //! \param ui32Base is the base address of the CAN controller.
    //! \param ui32ObjID is the object number to read (1-32).
    //! \param pMsgObject 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 pMsgObject.  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 pMsgObject->ui32Flags:
    //!
    //! - \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(uint32_t ui32Base, uint32_t ui32ObjID, tCANMsgObject *pMsgObject,
                  bool bClrPendingInt)
    {
        uint32_t ui32CmdMaskReg;
        uint32_t ui32MaskReg;
        uint32_t ui32ArbReg;
        uint32_t ui32MsgCtrl;
    
        // Check the arguments.
        ASSERT(CANBaseValid(ui32Base));
        ASSERT((ui32ObjID <= 32) && (ui32ObjID != 0));
    
        // This is always a read to the Message object as this call is setting a
        // message object.
        ui32CmdMaskReg = (CAN_IF2CMD_DATA_A | CAN_IF2CMD_DATA_B |
                          CAN_IF2CMD_CONTROL | CAN_IF2CMD_MASK | CAN_IF2CMD_ARB);
    
        // Clear a pending interrupt and new data in a message object.
        if(bClrPendingInt)
        {
            ui32CmdMaskReg |= CAN_IF2CMD_CLRINTPND;
        }
    
        // Set up the request for data from the message object.
        HWREGH(ui32Base + CAN_O_IF2CMD+2) =  ui32CmdMaskReg >> 16;
    
        // Transfer the message object to the message object specified by ui32ObjID.
        HWREGH(ui32Base + CAN_O_IF2CMD) = ui32ObjID & CAN_IF2CMD_MSG_NUM_M;
    
        // Wait for busy bit to clear
        while(HWREG(ui32Base + CAN_O_IF2CMD) & CAN_IF2CMD_BUSY)
        {
        }
    
        // Read out the IF Registers.
        ui32MaskReg = HWREG(ui32Base + CAN_O_IF2MSK);
        ui32ArbReg = HWREG(ui32Base + CAN_O_IF2ARB);
        ui32MsgCtrl = HWREG(ui32Base + CAN_O_IF2MCTL);
        pMsgObject->ui32Flags = MSG_OBJ_NO_FLAGS;
    
        // Determine if this is a remote frame by checking the TXRQST and DIR bits.
        if((!(ui32MsgCtrl & CAN_IF2MCTL_TXRQST) && (ui32ArbReg & CAN_IF2ARB_DIR)) ||
           ((ui32MsgCtrl & CAN_IF2MCTL_TXRQST) && (!(ui32ArbReg & CAN_IF2ARB_DIR))))
        {
            pMsgObject->ui32Flags |= MSG_OBJ_REMOTE_FRAME;
        }
    
        // Get the identifier out of the register, the format depends on size of
        // the mask.
        if(ui32ArbReg & CAN_IF2ARB_XTD)
        {
            // Set the 29 bit version of the Identifier for this message object.
            pMsgObject->ui32MsgID = ui32ArbReg & CAN_IF2ARB_ID_M;
    
            pMsgObject->ui32Flags |= MSG_OBJ_EXTENDED_ID;
        }
        else
        {
            // The Identifier is an 11 bit value.
            pMsgObject->ui32MsgID =
                (ui32ArbReg & CAN_IF2ARB_STD_ID_M) >> CAN_IF2ARB_STD_ID_S;
        }
    
        // Indicate that we lost some data.
        if(ui32MsgCtrl & CAN_IF2MCTL_MSGLST)
        {
            pMsgObject->ui32Flags |= MSG_OBJ_DATA_LOST;
        }
    
        // Set the flag to indicate if ID masking was used.
        if(ui32MsgCtrl & CAN_IF2MCTL_UMASK)
        {
            if(ui32ArbReg & CAN_IF2ARB_XTD)
            {
                // The Identifier Mask is assumed to also be a 29 bit value.
                pMsgObject->ui32MsgIDMask = (ui32MaskReg & CAN_IF2MSK_MSK_M);
    
                // 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((pMsgObject->ui32MsgIDMask != 0x1fffffff) ||
                   ((pMsgObject->ui32Flags & MSG_OBJ_REMOTE_FRAME) == 0))
                {
                    pMsgObject->ui32Flags |= MSG_OBJ_USE_ID_FILTER;
                }
            }
            else
            {
                // The Identifier Mask is assumed to also be an 11 bit value.
                pMsgObject->ui32MsgIDMask = ((ui32MaskReg & CAN_IF2MSK_MSK_M) >>
                                           18);
    
                // 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((pMsgObject->ui32MsgIDMask != 0x7ff) ||
                   ((pMsgObject->ui32Flags & MSG_OBJ_REMOTE_FRAME) == 0))
                {
                    pMsgObject->ui32Flags |= MSG_OBJ_USE_ID_FILTER;
                }
            }
    
            // Indicate if the extended bit was used in filtering.
            if(ui32MaskReg & CAN_IF2MSK_MXTD)
            {
                pMsgObject->ui32Flags |= MSG_OBJ_USE_EXT_FILTER;
            }
    
            // Indicate if direction filtering was enabled.
            if(ui32MaskReg & CAN_IF2MSK_MDIR)
            {
                pMsgObject->ui32Flags |= MSG_OBJ_USE_DIR_FILTER;
            }
        }
    
        // Set the interrupt flags.
        if(ui32MsgCtrl & CAN_IF2MCTL_TXIE)
        {
            pMsgObject->ui32Flags |= MSG_OBJ_TX_INT_ENABLE;
        }
        if(ui32MsgCtrl & CAN_IF2MCTL_RXIE)
        {
            pMsgObject->ui32Flags |= MSG_OBJ_RX_INT_ENABLE;
        }
    
        // See if there is new data available.
        if(ui32MsgCtrl & CAN_IF2MCTL_NEWDAT)
        {
            // Get the amount of data needed to be read.
            pMsgObject->ui32MsgLen = (ui32MsgCtrl & CAN_IF2MCTL_DLC_M);
    
            // Don't read any data for a remote frame, there is nothing valid in
            // that buffer anyway.
            if((pMsgObject->ui32Flags & MSG_OBJ_REMOTE_FRAME) == 0)
            {
                // Read out the data from the CAN registers.
                CANDataRegRead(pMsgObject->pucMsgData,
                               (uint32_t *)(ui32Base + CAN_O_IF2DATA),
                               pMsgObject->ui32MsgLen);
            }
    
            // Now clear out the new data flag.
            HWREG(ui32Base + CAN_O_IF2CMD + 2) = CAN_IF2CMD_TXRQST >> 16;
    
            // Transfer the message object to the message object specified by
            // ui32ObjID.
            HWREGH(ui32Base + CAN_O_IF2CMD) = ui32ObjID & CAN_IF2CMD_MSG_NUM_M;
    
            // Wait for busy bit to clear
            while(HWREG(ui32Base + CAN_O_IF2CMD) & CAN_IF2CMD_BUSY)
            {
            }
    
            // Indicate that there is new data in this message.
            pMsgObject->ui32Flags |= MSG_OBJ_NEW_DATA;
        }
        else
        {
            // Along with the MSG_OBJ_NEW_DATA not being set the amount of data
            // needs to be set to zero if none was available.
            pMsgObject->ui32MsgLen = 0;
        }
    }

    Regards,

    Gautam

  • Hello and thanks for your answer,

    but the issue persists with both the sample project (can_loopback_cpu1) and my own project. I am just calling CANMessageSet and CANMessageGet, as supposed in the example.

    The flag should get cleared in CANMessageGet in this line, but unfortunately this does just not happen.

    // Now clear out the new data flag.
    HWREG(ui32Base + CAN_O_IF2CMD + 2) = CAN_IF2CMD_TXRQST >> 16;

    So everytime i call CANMessageGet, the flag for a new message is set, or (when new data has really arrived) the flag for lost data is set as well.

    Please use the sample code to verify the problem at your own. (I am using controlSuite 3.2.5 with support code v110)

  • Michael,

    CANMessageGet is only designed to read data out of the message objects.  It has no capability to clear flags.  To clear the flags you should use the CanMessageSet API.

    That said, I looked at the example and even added a second call to CanMessageGet after the first one in the infinite for loop.  I did not see NewDat or MsgLst set.  If you could provide the modified example code you are using, I would be happy to look into this further.

    BR,

  • Hello,

    I am currently stuck at another issue regarding the CAN driver provided in the peripheral lib. In the example project there is a char array used for sending, so the driver copies 8 bit from each memory address and stores them in the data register.

    With this implementation it looks not to be possible to use (for example) an array consisting of 16 bit integers, cast dem to chars and send them as "raw data", because the driver takes only half of every 16 bit data.

    Is this assumtion correct, or did i oversee something?

    br,
    Michael

  • Michael,

    This is a "grey" area... Let me explain...

    This CAN peripheral is designed for a 8 bit byte addressable architecture.  C2000 devices are a 16 bit byte machine, so when you create a char on our machine you actually get a 16 bit location (i.e. the smallest addressable location).

    In order to interface the CAN peripheral with our bus, we've added an address/data bus bridge that translates accesses so that they should work no matter what the size of the access (8, 16, or 32 bit).

    The driver is written to give the most granularity to the user.  Want to send a single 8 bit byte with the CAN peripheral? You can do that.  Want to send 32 bits efficiently by doing a single access? You can do that too, but not with the way the drivers are currently written.  If you were to swap out the accesses in CANDataRegWrite and modify the calls to that API, you could in theory perform more efficient operations with the CAN peripheral at the cost of access granularity.

    That was probably too much information, but hopefully it helps you understand the hardware a little better.

    BR,

    Trey

  • Ok, it looks like I assumed it in a correct way. 

    Just to be clear, the issue is like this:
    I have my data (16 bit integers) stored in certain arrays and the target was to give the pointer to the array location to the CAN driver, but this is not possible due to the addressing mode (driver places data 8-bit wise), so in my oppinion I have two options:

    - Rearrange my data in 8 bit char arrays and then hand it over to the CAN driver (currently I do it like this)
    - Rewrite the CAN driver, to be able to deal with different data types (char, Uint16, Uint32) and place the data correctly in the CAN peripheral (how i want to implement it in the future)

    PS: It's impossible to give too much information ;)

  • You are 100% correct! :-)