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.

TMS320F28377S: CAN conversion

Part Number: TMS320F28377S
Other Parts Discussed in Thread: C2000WARE

Hello,

One of my customer is facing an issue with the CAN conversion of the TMS320F28377S.

He agreed to share his issue on the forum so I hope you will be able to help us on this topic.

Here is his description of the issue :

I need some help because I'm facing a problem with CAN interface on 377s, using driverlib (C2000Ware_1_00_03_00)

I've looked for some idea in C2000 wiki but I haven't found an answer....

 

I'm trying to setup both CAN interfaces (CANA and CANB) with a general purpose driver, compliant with out specific requirements.

At this moment I don't know which CobID the application need to transfer nor which could be the message length

 

I have started to write my code from the examples from C2000Ware and I'am able to transmit and receive data

(the device has loopback enabled)

In the attached code if I change at run time (with CCS) the variable vIntTxCobId_guh, the CAN_readMessage return the received data

But if I change the variable vIntTxDlc_guc I can see frame with different length on CAN TX pin but the CAN_readMessage  returns

always false

 

I've also tryed adding "CAN_disableController" before the 2 "CAN_setupMessageObject" and a CAN_enableController" after

but any frame has been received.

 

Is it possible to dynamically change the msgLen?

Otherwise which could be a solution?

Do I have to setup a different mailbox for each msgLen (from 1 to 8)?

------------------------

I haven't understood the behaviour of CAN_getStatus

I've added the call vStatus_guh = CAN_getStatus(CANA_BASE);

Also when I receive data correctly (no changing in msgLen) I've never seen the RxOk flag at 1 (Bit 4 of CAN_ES Register)

vStatus_guh = 8

Is this correct?

------------------------

I have taken a look at the file can.c in C2000Ware_1_00_03_00\driverlib\f2837xs\driverlib

Are the CANA_BASE constant correct?

------------------------

row 556.....

    //
    // See if there is new data available.
    //
    if((msgCtrl & CAN_IF2MCTL_NEWDAT) == CAN_IF2MCTL_NEWDAT)
    {
        //
        // Read out the data from the CAN registers.
        //
        CAN_readDataReg(msgData, (int16_t *)(base + CAN_O_IF2DATA),
                        (msgCtrl & CAN_IF2MCTL_DLC_M));

        status = true;

        //
        // Now clear out the new data flag
        //
        // Transfer the message object to the message object specified by
        // objID.
        //
        HWREG_BP(CANA_BASE + CAN_O_IF2CMD) = CAN_IF2CMD_TXRQST |
                                             (objID & CAN_IF2CMD_MSG_NUM_M);

        //
        // Wait for busy bit to clear
        //
        while((HWREGH(CANA_BASE + CAN_O_IF2CMD) & CAN_IF2CMD_BUSY) == CAN_IF2CMD_BUSY)
        {
        }
    }
row 584

  • Hi Mickael,

    Based on the description from the customer, the main questions they are having (from what I can interpret) are as follows (I have also added some response/comments):

    1.) Can the message length be dynamically changed?

    Yes, the message length can be dynamically changed.  In C2000Ware driverlib function CAN_setupMessageObject(), the last argument is message length.  Prior to data transmission, user should call the CAN_setupMessageObject() function and set the message length accordingly.  Per definition, CAN may transmit a maximum of 8 bytes of data.

    2.) What does CAN_getStatus function return?

            This function returns the contents of the CAN_ES register (refer to the Technical Reference Manual for TMS320F28377S for the CAN register descriptions).  A return value of 8 means that data transmission was OK.  If the customer was using the loopback test which may be the case based from the description, the RxOk bit will not be set since the loopback example is a test mode where CANA transmits data and making sure that the data propagates back to the mailboxes through an internal path (not the external CAN bus).  RxOk bit will only be set it the CAN module is in a receiving mode. 

            There is another example where the 2 CAN modules are used, where CANA transmits and CANB receives data.  I think this example will best demonstrate how CAN_ES register polling, specifically TxOk and RxOk bit status get updated after each transaction.  This example would need to use the CAN bus and transceivers though.

    3.) Is CANA_BASE constant?

           Yes, CANA_BASE is constant.  This is the base peripheral address of the first of the two CAN modules that the TMS320F28377S has.  If the second CAN module needs to be used, the routines have to be changed to CANB_BASE.

    Please let me know if this information is helpful and if customer is still having issues with the above.

    Regards,

    Joseph

  • Hi Joseph

    I'm the customer involved in this thread

    Thanks for the replay

    If possible, I need some explanations

    Question 1)

    Ok for the transmission path but for the reception?

    Do I have to use CAN_MSG_OBJ_USE_ID_FILTER as flag in CAN_setupMessageObject?

    Is there a field to don't filter only on lenght?

    Question 2)

    Ok, clear

    I'm using CAN_getNewDataFlags; it seems to work also in LoopBack mode

    Question 3)

    The attached code is from can.c in driverlib source code.

    In may opinion variable "base"  should have been used instead of CANA_BASE

    In my tests, the CAN_readMessage function clear the NewDataFlag only on CANA interface, not on CANB

    Could it depend on that?

    Regards

    Antonio

  • Hi Antonio,

    Welcome to the forum!  It is good that you have placed your posts directly on the forum as several community members and experts are also able to share answers on other question you may have from a wide variety of topics discussed here.

    For the first question: -  Message length and filtering are totally independent of each other.  Setting up message length prior to calling CAN_setupMessageObject during transmission sets up the CAN parameters correctly as to how many bytes are there to transfer.  During reception, message length will be updated accordingly in the CAN IFx registers, (DLC field) depending on how many bytes were sent.  Message filtering (using CAN_MSG_OBJ_USE_ID_FILTER flag) is entirely a different subject and in no way going to dictate how long the message is.  Message ID filtering option in CAN is a feature that allows only specific nodes to receive data depending on the message ID (sometimes called arbitration ID) associated with the message object.  During reception, if CAN_MSG_OBJ_USE_ID_FILTER flag is used, only nodes that match the message ID and some mask rules will ever receive the data.  For simple illustration purposes, a transmitting node will be assigned a arbitration ID of 0x0F and will be transmitting 4 bytes of data.  Say in the CAN bus, there are several nodes, assigned as nodes 1 to 15 (with node 15 having the arbitration ID of 0x0F transmitting).  If it is desired that only nodes 8 to 14 are to receive the transmission from node 15, use the CAN_MSG_OBJ_USE_ID_FILTER flag and at the same time set the mask bits to ignore the last three bits of the message ID when setting up the message object.  This way, nodes 0-7 will not receive any data while nodes 8-14 will receive the 4 bytes of data from node 15.

    For the second question: - I think this is clarified so I am assuming there are no other issues here.

    For the last question: - You have a point in that assigning this variable simply as 'base' will work, however this means that users will have to provide the base peripheral address of the module being used.  The C2000Ware utilities/headers are written such that users should not need to go back to different device documentations to find out what 'base' address they need to provide for the different modules.  A more efficient and intuitive way to abstract this is use of predefined header values like CANA_BASE, or CANB_BASE,  As long as users are consistent in passing this parameter in function calls like CAN_initModule(CANA_BASE,..... CAN_setupMessageObjec(CANA_BASE...., CAN_startModule(CANA_BASE,..... CAN_sendMessage(CANA_BASE,.... CAN_readMessage(CANA_BASE,... then these should work.  This way, user will just have to use CANA_BASE or CANB_BASE and not have to worry about obtaining the different base addresses of each module (and potentially committing typo error when entering these values).

    Best regards,

    Joseph

  • Hi Joseph

    I'm trying to proceed with my CAN functions but I'm facing with some other issues.

    I'm using the F2837xS Peripheral Driver Library 1.03.00.0

    After the receipt of a frame, how can I read its parameter?

    I mean, I have any input filter so in the RX mailbox there can be a message with any COD_ID, with an RTR or different MSG_LENGTH... ( please let me know if this statement is correct )

    I have seen that there is also a Deprecated_F2837xS_DRL_UG with CAN controller API

    In that library there is void CANMessageGet (uint32_t ui32Base, uint32_t ui32ObjID, tCANMsgObject ∗pMsgObject,
    bool bClrPendingInt) to get all frame parameters.

    Why there is not one like it in the "new" lib?

    How it should be managed?

    Thanks in advance

    Best regards

     

  • Hi Antonio,

              There is an equivalent function for CANMessageGet.  It is  void CAN_readMessage(uint32_t base, uint32_t objID, uint16_t *msgData).  Did you try using this?  Data should be available in parameter msgData.  You can also read the IF registers for the other parameters.  (e.g. CAN_IFxCTL, DLC field for the length of the received data).

             Let me know if you still have issues reading CAN parameters.

    Best regards,
    Joseph

     

     

  • Hi Joseph

    Yes, I have tryed with void CAN_readMessage(uint32_t base, uint32_t objID, uint16_t *msgData)

    But it read only the data part of the received frame

    Is there a function to get the other "flags" or I have to use direct register accesses?

    Is it not reccommended to useCANMessageGet and the other functions in the same lib?

    Best Regards

    Antonio

  • Hi Antonio,

    It is not recommended to use the deprecated functions since those will not be supported in the future.  Your other option is to read the IF registers for the other flags or parameters that are not available with CAN_readMessage.  Try also looking at file can.h from line# 1119 onwards.  There are function definitions that you can use to read out register values (example CAN_getStatus for reading out CAN_ES flags) or other information with functions like CAN_getTxRequests, CAN_getValidMessageObjects, CAN_getNewDataFlags and CAN_getInterruptMessageSource.  You may be able to find an equivalent function you need in can.h file. 

    Also try going to the docs subdirectory in driverlib.  One of the documentations that you can find there is a pdf file called F2837xS_Driverlib_Users_Guide.pdf.  Go to chapter 7 for a complete list and description of the supported CAN functions.  Hopefully this will help narrow your search for the specific read functions you need.

    Best regards,

    Joseph

  • Hi Antonio,

    I have not heard from you in a while so I am assuming that you have resolved your issue.

    Regards,
    Joseph