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.

CCS/TMS320F28379D: CAN communication philosophy and advices

Part Number: TMS320F28379D
Other Parts Discussed in Thread: C2000WARE

Tool/software: Code Composer Studio

Hello everyone,

I am absolutely beginner in CAN bus and more generally in numeric communications.

I have read the F28379d manual about CAN, I have understood some things but I can't understand the best way for using the module.

I know the 32 message objects and their configuration but how to use them ? 

Imagine : I have a machine that counts potatoes and carrots (5 bytes for each ... lots of vegetables !!) and a master has to ask it for know the amounts and machine states (1 byte for faults ).

What is the best configuration : 1 TX message object filled with 6 bytes (1+5 potatoes number) or (1+5carrots number) and 1 RX message object wich saves in differents registers the differents values (variable msg ID) ?

OR 2 TX message objects (1 for each values to send) and 2 RX message objects (corresponding to the 2 TX msg objects) ?

OR other manner ?

In case of more than one msg object, how the node will know which read ? In loopback example it's easy because the CAN core send the message to itself (moreover in the same code) but how to use the CANMessageGet function when there is 32 different message objects and 50 nodes on the bus.

Also, in the loopback example, there is one seconde delay between send and receive functions : does it mean that the received message is stored until the next send even if it is not read by the CAN module ?

Finally, does ALL nodes need to have the SAME messages objects configuration ?

I am sorry for all this questions but they can really help me.

Thank you very much and have a nice day,

Jérémy

  • Hi Jeremy,

    You can configure all the 32 CAN message objects for either TX or RX, or a combination of say 10 TX message objects and 22 RX message object, or any combination thereof.  Note that one message object can hold data of up to 8 bytes which can be used for TX or RX.  The 32 message objects can represent a lot of data.

    For the vegetable counter that you used as an example, say you have 50 machines that count potatoes and carrots.  These 50 machines would all connect to the CANBUS to make up 50 nodes (51 if you add another node that just monitors or receives data from the vegetable counting machines).  You can assign 1 TX message object for the potato count and another TX object for the carrot count per machine.  You decide to use 5 bytes of the 8bytes for the count and you can use the remaining 3bytes for some other purpose (like fault or status codes).  Each message object will have its unique identifier.  In CAN, this is commonly known as the arbitration ID, which is a means of identifying or associating a message object.  By default the arbitration ID is 11-bit field (but there is an option to expand this o 29 bits if you use the extended option).  In the vegetable counting example, you may need to assign each counting machine with a unique ID, so let us say you chose to use the standard arbID width of 11-bits and used the upper 8 bits for the machine number and the lower 3 bits to hold the information for the type of vegetable it is counting (001 for potato, 010, for carrot...etc)  so that:

    Machine counter 1 :  Arb ID for potato counter = 0000 0001 001

                                      Arb ID for carrot counter = 0000 0001 010

    Machine counter 2 :  Arb ID for potato counter = 0000 0010 001

                                      Arb ID for carrot counter = 0000 0010 010

    ...and so on...

    When all machines are ready to transmit the vegetable count data, you can define the 2 TX message objects accordingly for all 50 machines, populate the 5 byte counters and the rest of the 3bytes for fault codes (or some other status data) and identify these objects accordingly by the arbID defined above.  For the node that monitors the CANBUS, all the unique message object will be available.  CAN has a mask option for the arbID so that you can set it to just receive data only from certain machines (if for instance you are only interested in receiving count data from machine 32 for the carrot count) through the mask/filtering option which is discussed in the CAN section of the Technical Reference Manual.  How to use the message objects is really up to your application.  I have just illustrated a simple way to use this using  your example.

    Hope this helps to illustrate the use of message objects.

    Best regards,

    Joseph

  • Jeremy,
    As Joseph rightly mentioned, exactly how to use the 32 message objects (or whether to even use 32) is completely up to you. There is no "right" way or "wrong" way here. As one who is most knowledgeable of the end-application, you are best positioned to choose the scheme that works for you the best. To me, it sounds like you are really looking for a good Higher Layer Protocol (HLP). You may choose one that is already available or you may come up with one of your own, although you may not call it that. There are many resources on the web to learn more about HLPs. Perhaps you could start with the two below:

    www.kvaser.com/.../
    www.can-cia.org/.../
  • Hello,

    Thank you very much for your precise answer, It's a bit clearer for me. Allow me to add points to my situation : we still have the vegetables machines, with 2 TX msg for each (like Joseph have proposed it) but now, we have a supervision machine which send start/stop order and amount setpoint for each kind of vegetable (6bytes per frame).

    Vegetable machine comunicate only with supervision machine, not between them.

    On the supervision machine, Do I need to create  TX message object for each vegetable type for each machine ( 2 x Number of machine in this case with fixed Arb ID) ? Or only 2 TX msg for each kind of vegetable with a variable Arb ID for adressing n machines ?

    In complement I need to add two RX msg for receiving data from vegetable machines, right ? and there is the need of remote/transmit object frame ?

    In RX msg object, the Arb ID contains emiter ID and in TX msg its contains receiver ID ?I have trouble with this giver/receiver notion.

    I am sorry with my beginner questions but I think basic situations can take us away,

    Thank you again for your help and have a nice day.

    Best regards,

    Jérémy

  • Hi Jeremy,

    There are several ways to implement your expanded example with your supervisor machine.  Both options you have pointed out will work (TX message for each vegetable type per machine or 2 TX message object for each vegetable type with variable Arb ID).  Again, this really depends on how you want to write your application code.

    I think a more efficient way would be to first define the parameters needed by your system, like what are the specific tasks of the supervisor and the counting machines, what are the vegetable count limits for each type, or if you want certain machines to output specific amounts of vegetables, or if every machine will have a uniform output.  You could pass these initial parameters from the supersvisor during system start up.  You could pass a broadcast message (TX message) from the supervisor with fixed Arb ID for stop counts for each vegetable type or you could pack this information in the 8-byte message in a single TX object or in addition, you could also individually transmit specific stop counts for certain machines.

    During system start up,  the counting machines will not proceed with their counting tasks unless the initial parameters from the supervisor is received so you may have several defined RX objects in the counting machines that have no message filters (meaning they will receive the message from the supervisor which is intended for all the nodes in the CAN bus).  Another RX object would allow filtering so that specific machines would only receive specific data packets from the supervisor.  You could also define a message object in the supervisor/machines that would associate transmitted data with specific tasks, like request for information on current  vegetable counts, status checks (idle/busy/machine down...etc), or forced stop or restart of a counting sequence.  Once these information have been passed from the supervisor to the machines through the CAN bus, then counting can begin.

    Also take note of one very important aspect in CAN communication which makes it an efficient way to handle message traffic, which is arbitration.  These may be covered in the links that Hareesh provided below (I strongly suggest to check these out).  Arbitration in CAN communication is a means of managing which node gets priority in transmitting data over the CAN bus.  The node with the lowest arbitration ID gets to transmit its data first.  Again, back to the example with the vegetable counting system, it would be good to assign the ID of the supervisor with the lowest number in the node so when it transmits data, it will always be given priority over the rest of the machines.

    As for the remote frame, I do not see a need for it in the system using the example you provided, but you may use it like some sort of a message transmitted as some intervals from the counting machines that they are up and running.

    The Arb ID in the TX message object would dictate the order as to when a node can transmit if there are several nodes that are transmitting simultaneously (lowest Arb ID gets to transmit first, highest Arb ID number gets to transmit last).  During message reception, the Arb ID can be associated with message filtering (if UMask is set, then only transmitted messages having the same Arb ID as the one defined in the RX object will be received).  More of this is covered in the manual.

    Hopefully this helps...

    Regards,

    Joseph

  • Hi Joseph,

    Thank you for your reply and sorry for my late, I try to implement CAN bus for don't ask stupid questions ... but it's not won !!

    Your last message help me again and I am working now on the code examples. For the moment let's leave out vegetables (in real life, I have to comunicate with lots of power converter which they have they own states machine and about 20 setpoints,flags, imput/output ...).

    I have started with the CCS example and try to make my own. I am working on the F28379D launchpad.

    On the CCS example I don't understanding something : why the two msg objects have the same msgID ? If I have correctly understood, Msg ID is the n° of msg object (1-32) and the ID mask is the arbitration, right ? Moreover msgID is different in the msg declaration and the CANSetmessage function (1 and 2). I don't understand the logic.

    Then I have tryiend to implement my own code : I am using CAN A and CAN B which are comunicating by two MCP2551. CANA send and "start order" (0 or 1 for msgData[0]) and CANB is suppose to read this order. I am displaying it in a console via the UART.

    Currently, I can send message (and read frame via an oscilloscope) but CANB doesn't see nothing.

    Again I think I have a basic configuration problem, can you help me please ?

    Thank you again for your precise support !!

    Jérémy

  • Hi Jeremy,

     

    Great to hear you are finally working on the CAN code examples. Seems like you have the correct setup but just making sure that my assumptions below are correct:

     

    • You are using the external transmit example since you have used a CAN transceiver to link the 2 CAN modules

    • You have correctly assigned the GPIO configuration for CAN-A and B RX/TX pins you want to use

     

    As for your questions below regarding the example:

     

    • Why do the 2 message objects have the same message ID? In the example, note that ui32MsgIDMask is set to 0. This means that there is no masking involved with the message ID. In this case, the receiver has to match the exact ID from the transmitted object. If IDMask is set to something else, then message filtering will be applied. Depending on the bits that are masked, the receiver can be configured to receive data from tx message IDs that meet the mask criteria.

    • If I have correctly understood, Msg ID is the n* of msg object (1-32 ) and the ID mask is the arbitration, right? The element ui32MsgID is the message ID or arbitration ID. This is the unique ID that a node identifies with. In this example code ui32MsgID is not the same as the message object number (1 to 32). The message object will be the 2nd argument in the CANMessageSet(CANA_BASE, object#,…) and CANMessageGet(CANA_BASE, object#,…).

     

    In your HW configuration, are you transmitting data in CANA and receiving in CANB? If this is the case, you would need to change your code for CANMessageGet to CANMessageGe(CANB_BASE, 2, &sRXCANMessage, true) and also make sure you have configured the correct GPIO pins for CANB. This is probably the reason why CANB is not receiving the data.

     

    Best regards,

    Joseph

     

  • Hi joseph,

    Thanks you again for your reply.

    For answering to your questions :

    "

    • You are using the external transmit example since you have used a CAN transceiver to link the 2 CAN modules

    It's the loop back example which I have modified code for my own test. CANA sends message to CANB (8bytes but I am using only one bit).

    • You have correctly assigned the GPIO configuration for CAN-A and B RX/TX pins you want to use

    Yes, i am using GPIO6-7 (CANB) and 18-19 (CANA) of the 28379D launchpad (input are ASYNC and output in PUSHPULL)

     

    As for your questions below regarding the example:

     

    • Why do the 2 message objects have the same message ID? In the example, note that ui32MsgIDMask is set to 0. This means that there is no masking involved with the message ID. In this case, the receiver has to match the exact ID from the transmitted object. If IDMask is set to something else, then message filtering will be applied. Depending on the bits that are masked, the receiver can be configured to receive data from tx message IDs that meet the mask criteria.

    • If I have correctly understood, Msg ID is the n* of msg object (1-32 ) and the ID mask is the arbitration, right? The element ui32MsgID is the message ID or arbitration ID. This is the unique ID that a node identifies with. In this example code ui32MsgID is not the same as the message object number (1 to 32). The message object will be the 2nd argument in the CANMessageSet(CANA_BASE, object#,…) and CANMessageGet(CANA_BASE, object#,…).

    Ok, I will try different configuration for perfectly understand it.

     

    In your HW configuration, are you transmitting data in CANA and receiving in CANB? If this is the case, you would need to change your code for CANMessageGet to CANMessageGe(CANB_BASE, 2, &sRXCANMessage, true) and also make sure you have configured the correct GPIO pins for CANB. This is probably the reason why CANB is not receiving the data."

    I think It's good for GPIO and HW, I have also measured RX TX for each module and CANh-CANL voltages, on the oscilloscope it looks like frames with correct levels.

     

     

     

    I still can't read frame with CANB. I have something strange, when I am using the GetMessage function, the msgLen of RX object is erased and put to 0 :

     

    Do you have an idea why ? And my problem can be due to bad types conversion/gestion ?

     

    i have also tryied lots of flags (other than "MSG_OBJ_NO_FLAG") and result is the same I can't change msgRXdata (or MsgDataCANB[0]). I will try interrupt but I am not sure that resolve my trouble.

     

    EDIT: I was inspired by this two examples, do you see something totally anormal ? (except register/constants are not the same beacause it's not the same component)

    https://e2e.ti.com/support/microcontrollers/tiva_arm/f/908/p/376339/1324292

    http://ohm.ninja/tiva-c-series-can-bus-with-mcp2551/

     

     

    Thank you for your support and have a nice day.

     

    Best regards,

    Jérémy

  • Hi Jeremy,

    Based from your previous post, you indicated that you are using a MCP2551 transceiver to pass data from CANA to CANB hence I wanted to confirm that the external transmit example code is used.  The loopback example is a test that confirms that what is sent to the TX pin is received in the RX pin on the same CAN module. This is the reason why you are not seeing anything on CANB.  You should use the external transmit example as this will demonstrate what you are trying to accomplish.  The external transmit example shows how two CAN nodes process data on the CAN bus.  The first node is CANA interfacing with the CAN bus through CAN RT/TX pins to the MCP2551 transceiver  and the second node is CANB  interfacing with the CAN bus through CAN RT/TX pins to the second  MCP2551 transceiver.  Both transceivers connect to the CAN bus to the CANL/CANH lines.

    The external transmit example should work for you.

    Regards,

    Joseph  

  • Hi Joseph,

    Thank you for your fast reply.

    I have resolved the problem, indeed there was two : First my board had a bad contact on one MCP2551 +5v pin, and I am using my "global" code which contain adc,pwm and other periphericals... You were right, GPIO config was bad, it was good on the CAN configuration but the PWM configuration was called after... Idiot mistake !!

    Thank you for your support, the next step is to deepen and master the msgID, mask ID and interruption with status. I will come back to my post if I have further questions :)

    Thank you and have a nice day,

    Best regards,
    Jérémy

  • Hi Jeremy,

    Happy to help. Glad to hear you have resolved your issues.

    Regards,
    Joseph
  • Hello again,

    I have new problem now : I have reached to setting up CAN Interrupt (CANB0 exactly), like lots example I've seen but the problem is every interrupt the source is "CAN_INT_INT0ID_STATUS", so a status interrupt, never message ID ...

    Moreover the program seems to not go out  intHandler code :

    I don't know if the program is really stuck here or if the interrupt is continuesly generated. For remember, I am sending one frame each seconde so the RX interrupt should not appear before.

    Can you help me please, do you have first opinion please ?


    Thank you very much and have an nice day,

    Jérémy

  • Hello everyone,

    I reached to work with interrupt, I had lots of mistakes in my code like CANA/CANB copy past or wrong interrupt acquit ... So it's ok for this point.

    Now I can't understand totally the using of masks : I know we are limited to 32 message objects but it is possible to assign multi-mask for one message object ?

    By example I have 10 differents measures and 4 setpoint setting to transmit/receive from my machine, is it possible to make ONE message object for measures and ONE for setpoints with different mask for know which measure/setpoint is transmited/received ?

    Moreover I want add lots of information like emiter, receiver, broadcasting or not (setpoit refresh or stop for all machine by example), is it possible via multiple masks+ID filtering ? Or am I obliged to work with data frame ?

    I think it's possible with masks but I don't understand how, if we reasonning by absurd, what is the the aim to put 29 bits for ID but only 32 msg objects ?


    Thank you very much and have a nice day,
    Jérémy
  • Jeremy,

                Each message object has only one mask. Depending on how you setup the mask (in other words, what mask "value" you write), you will be able to receive a group of MSGIDs that satisfy the mask filtering criterion.

    is it possible to make ONE message object for measures and ONE for setpoints with different mask for know which measure/setpoint is transmited/received ?

    Yes, this is possible.

     

    Moreover I want add lots of information like emiter, receiver, broadcasting or not (setpoit refresh or stop for all machine by example), is it possible via multiple masks+ID filtering ? Or am I obliged to work with data frame ?

    This question is too specific to the application and I regret I cannot answer it accurately. As mentioned in an earlier post, you know your application the best and hence you are better positioned to use the features of the module that would satisfy the application requirements. I am happy to clarify questions about any specific bits/registers/features in the module. I didn’t quite understand your question "am I obliged to work with data frame ?". Data frames are the only mechanism by which data is transported between CAN nodes.

     

    If you need some insight into how Acceptance Mask Filtering works, I recommend you download my app.note http://www.ti.com/lit/an/spra876b/spra876b.pdf and look at the example LAM.c. If you have c2000ware installed, you should see it in the C:\ti\c2000\C2000Ware_1_00_01_00\device_support\f2833x\examples\CAN_LAM directory. (You may have to edit the path to reflect which version of c2000ware you have). Note that this app.note was written for the eCAN module in older c2000 devices, NOT for the DCAN module you are working on. However, the masking/filtering concept is fairly similar (with the exception that the mask bits work oppositely in eCAN compared to DCAN). The code example is well commented and clearly illustrates how filtering works. A similar app.note for DCAN is in the plans, although the timeline is not frozen right now.

     

    On a different note, it would be good if you could open a new post, rather than adding more questions to the old post, especially when the new questions are unrelated to your original post. Otherwise, someone wanting to answer your last post may be tempted to read from the original post, only to realize that many of your old questions have already been answered.

  • Clarification: You need to install the zip file that comes with the app.note., in order to look at the example I quoted. The examples should install in C:\ti\c2000\C2000Ware_1_00_01_00\device_support\f2833x\examples. I have attached that testcase, in case you are not inclined to install the example codes.

    2742.LAM.c
    // TI Release: 28xx eCAN programming example
    // Release Date: Fri Aug 4 2017
    // Copyright:
    // Copyright (C) 2017 Texas Instruments Incorporated - http://www.ti.com/
    //
    // Redistribution and use in source and binary forms, with or without 
    // modification, are permitted provided that the following conditions 
    // are met:
    // 
    //   Redistributions of source code must retain the above copyright 
    //   notice, this list of conditions and the following disclaimer.
    // 
    //   Redistributions in binary form must reproduce the above copyright
    //   notice, this list of conditions and the following disclaimer in the 
    //   documentation and/or other materials provided with the   
    //   distribution.
    // 
    //   Neither the name of Texas Instruments Incorporated nor the names of
    //   its contributors may be used to endorse or promote products derived
    //   from this software without specific prior written permission.
    // 
    // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
    // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
    // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
    // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
    // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
    // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
    // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
    // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
    // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
    // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
    // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    // 
    
    /*******************************************************************************
    * Filename: LAM.c
    *                                                                    
    * Description: This example code illustrates how Acceptance Mask Filtering
    * works using CANLAM registers. 4 different cases are illustrated
    *
    * CAN-B is the transmitter and CAN-A is the receiver. They need to be connected
    * together through CAN transceivers. This code can only be run with 28xx devices
    * that have two eCAN modules on-chip.
    *
    *******************************************************************************/
    
    //
    // Included Files
    //
    #include "DSP28x_Project.h"     // Device Headerfile and Examples Include File
    
    int TX_COUNT = 0;
    int j = 0;
    
    void Config_Transmit_B(void);       // Configure Transmit Mailboxes in eCAN-B
    void Check_Tx_B(void);              // Ensure completion of message transmission and clears TA flag
    void MBXwrA(void);                 // This function initializes all 32 MBOXes of CAN-A
    void MBXwrB(void);                 // This function initializes all 32 MBOXes of CAN-B
    
    main() 
    {
    
    /* Kill Watchdog, Init PLL, Enable peripheral clocks */
    
        InitSysCtrl();
    
    /* Initialize the CAN modules */
    
        InitECan();
        InitECanGpio();
    
        EALLOW;
    
    /* Zero out the entire MBX RAM area - Makes it easy to debug */
    
        MBXwrA();
        MBXwrB();
    
    /* Configure Transmit Mailboxes in eCAN-B */
    
        Config_Transmit_B();
        
    /* Write to the MSGID field of RECEIVE mailboxes */
    
        ECanaMboxes.MBOX30.MSGID.all = 0x90000030; // Extended Identifier - Acceptance mask NOT enabled
    
        ECanaMboxes.MBOX20.MSGID.all = 0xC1111120; // Extended Identifier - Acceptance mask enabled
    
        ECanaMboxes.MBOX10.MSGID.all = 0xC5555553; // Extended Identifier (0x9555555X - last nibble is a "don't care") - Acceptance mask enabled
    
        ECanaMboxes.MBOX5.MSGID.all  = 0xC48F2B95; // Extended Identifier (0xXXXXXXXX - All MSGIDs will be received in this mailbox) - Acceptance mask enabled
    
    /* Configure the LAM registers */
    
    	  ECanaLAMRegs.LAM20.all = 0x00000000;
    	  ECanaLAMRegs.LAM10.all = 0x0000000F;
    	  ECanaLAMRegs.LAM5.all  = 0x1FFFFFFF;
    	 
     /* Configure Mailbox direction */
    
    	ECanaRegs.CANMD.all = 0x40100420;   // Configure Mboxes30,20,10,5 in CAN-A for reception
    	ECanbRegs.CANMD.all = 0x00000000;   // Configure Mboxes in CAN-B for transmission
    	 
    /* Enable Mailboxes */
    	
    	ECanaRegs.CANME.all = 0x40100420;
    	ECanbRegs.CANME.all = 0xFFFFFFFF;
    
    /* Begin transmitting */     
         
         ECanbRegs.CANTRS.all = 0x40000000;	// Set TRS for MBX30 (Will be received in eCAN-A.MBX30)
         Check_Tx_B();
    
         ECanbRegs.CANTRS.all = 0x00100000;	// Set TRS for MBX20 (Will be received in eCAN-A.MBX20)
         Check_Tx_B();
    
         ECanbRegs.CANTRS.all = 0x00000400;	// Set TRS for MBX10 (Will be received in eCAN-A.MBX10, but will be overwritten by the next message)
         Check_Tx_B();
    
         ECanbRegs.CANTRS.all = 0x00000200;	// Set TRS for MBX9  (Will be received in eCAN-A.MBX10, but will be overwritten by the next message)
         Check_Tx_B();						// By setting up a breakpoint in the previous code line, it could be seen that MBX10 has a data of 1010101010101010
    
         ECanbRegs.CANTRS.all = 0x00000100;	// Set TRS for MBX8  (Will be received in eCAN-A.MBX10)
         Check_Tx_B();						// By setting up a breakpoint in the previous code line, it could be seen that MBX10's data of 1010101010101010 is overwritten by 0909090909090909
    
         ECanbRegs.CANTRS.all = 0x00000020;	// Set TRS for MBX5  (Will be received in eCAN-A.MBX5, but will be overwritten by the next message)
         Check_Tx_B();						// By setting up a breakpoint in the previous code line, it could be seen that MBX10's data of 0909090909090909 is overwritten by 0808080808080808
    
         ECanbRegs.CANTRS.all = 0x00000010; // Set TRS for MBX4  (Will be received in eCAN-A.MBX5, but will be overwritten by the next message)
         Check_Tx_B();						// By setting up a breakpoint in the previous code line, it could be seen that MBX5 has a data of 0505050505050505
    
         ECanbRegs.CANTRS.all = 0x00000008;	// Set TRS for MBX3  (Will be received in eCAN-A.MBX5, but will be overwritten by the next message)
         Check_Tx_B();						// By setting up a breakpoint in the previous code line, it could be seen that MBX5's data of 0505050505050505 is overwritten by 0404040404040404
    
         ECanbRegs.CANTRS.all = 0x00000004;	// Set TRS for MBX2  (Will be received in eCAN-A.MBX5, but will be overwritten by the next message)
         Check_Tx_B();						// By setting up a breakpoint in the previous code line, it could be seen that MBX5's data of 0404040404040404 is overwritten by 0303030303030303
    
         ECanbRegs.CANTRS.all = 0x00000002;	// Set TRS for MBX1  (Will be received in eCAN-A.MBX5)
         Check_Tx_B();						// By setting up a breakpoint in the previous code line, it could be seen that MBX5's data of 0303030303030303 is overwritten by 0202020202020202
    
         asm("     ESTOP0");				// Stop here after program termination. MBX5 should have a data of 0101010101010101
    
    }
    
    /* -------------------------------------------------------------------------- */
    /* Function that ensures transmission is complete and then clears the TAn bit */
    /* -------------------------------------------------------------------------- */
    
    void Check_Tx_B(void)
    {
    
        while(ECanbRegs.CANTA.all == 0 ) {}         // Loop here until TAn bit is set..
             ECanbRegs.CANTA.all = 0xFFFFFFFF;      // Simply Clear all TAn
             TX_COUNT ++;                           // Should be 10 at program completion
    }
    
    /* ---------------------------------------------------- */
    /* Function that configures transmit mailboxes in CAN-B */
    /* ---------------------------------------------------- */
    
    void Config_Transmit_B(void)
    {
    
        /* Write to the MSGID field of TRANSMIT mailboxes */
    
            ECanbMboxes.MBOX30.MSGID.all = 0x90000030; // Extended Identifier
    
            ECanbMboxes.MBOX20.MSGID.all = 0x81111120; // Extended Identifier
    
            ECanbMboxes.MBOX10.MSGID.all = 0x85555553; // Extended Identifier
            ECanbMboxes.MBOX9.MSGID.all  = 0x85555554; // Extended Identifier
            ECanbMboxes.MBOX8.MSGID.all  = 0x85555558; // Extended Identifier
    
            ECanbMboxes.MBOX5.MSGID.all  = 0x848F2B95; // Extended Identifier
            ECanbMboxes.MBOX4.MSGID.all  = 0x8A6E50D4; // Extended Identifier
            ECanbMboxes.MBOX3.MSGID.all  = 0x80B37CA3; // Extended Identifier
            ECanbMboxes.MBOX2.MSGID.all  = 0x819D4E52; // Extended Identifier
            ECanbMboxes.MBOX1.MSGID.all  = 0x840F7E01; // Extended Identifier
    
         /* Write to Master Control field */
    
            ECanbMboxes.MBOX30.MSGCTRL.bit.DLC = 8;
            ECanbMboxes.MBOX20.MSGCTRL.bit.DLC = 8;
            ECanbMboxes.MBOX10.MSGCTRL.bit.DLC = 8;
            ECanbMboxes.MBOX9.MSGCTRL.bit.DLC = 8;
            ECanbMboxes.MBOX8.MSGCTRL.bit.DLC = 8;
            ECanbMboxes.MBOX5.MSGCTRL.bit.DLC = 8;
            ECanbMboxes.MBOX4.MSGCTRL.bit.DLC = 8;
            ECanbMboxes.MBOX3.MSGCTRL.bit.DLC = 8;
            ECanbMboxes.MBOX2.MSGCTRL.bit.DLC = 8;
            ECanbMboxes.MBOX1.MSGCTRL.bit.DLC = 8;
    
            /* Write to the mailbox RAM field */
    
            ECanbMboxes.MBOX30.MDL.all = 0x30303030;
            ECanbMboxes.MBOX30.MDH.all = 0x30303030;
    
            ECanbMboxes.MBOX20.MDL.all = 0x20202020;
            ECanbMboxes.MBOX20.MDH.all = 0x20202020;
    
            ECanbMboxes.MBOX10.MDL.all = 0x10101010;
            ECanbMboxes.MBOX10.MDH.all = 0x10101010;
    
            ECanbMboxes.MBOX9.MDL.all = 0x09090909;
            ECanbMboxes.MBOX9.MDH.all = 0x09090909;
    
            ECanbMboxes.MBOX8.MDL.all = 0x08080808;
            ECanbMboxes.MBOX8.MDH.all = 0x08080808;
    
            ECanbMboxes.MBOX5.MDL.all = 0x05050505;
            ECanbMboxes.MBOX5.MDH.all = 0x05050505;
    
            ECanbMboxes.MBOX4.MDL.all = 0x04040404;
            ECanbMboxes.MBOX4.MDH.all = 0x04040404;
    
            ECanbMboxes.MBOX3.MDL.all = 0x03030303;
            ECanbMboxes.MBOX3.MDH.all = 0x03030303;
    
            ECanbMboxes.MBOX2.MDL.all = 0x02020202;
            ECanbMboxes.MBOX2.MDH.all = 0x02020202;
    
            ECanbMboxes.MBOX1.MDL.all = 0x01010101;
            ECanbMboxes.MBOX1.MDH.all = 0x01010101;
    
    }
    
    
    /* Zero-out the MBX RAM of CAN-A */
    
    void MBXwrA()
        {
        int j;
        volatile struct MBOX *Mailbox  = (void *) 0x6100;
    
            for(j=0; j<32; j++)
            {
                Mailbox->MSGID.all = 0;
                Mailbox->MSGCTRL.all = 0;
                Mailbox->MDH.all = 0;
                Mailbox->MDL.all = 0;
                Mailbox = Mailbox + 1;
    
            }
        }
    
    /* Zero-out the MBX RAM of CAN-B */
    
    void MBXwrB()
        {
        int j;
        volatile struct MBOX *Mailbox  = (void *) 0x6300;
    
            for(j=0; j<32; j++)
            {
                Mailbox->MSGID.all = 0;
                Mailbox->MSGCTRL.all = 0;
                Mailbox->MDH.all = 0;
                Mailbox->MDL.all = 0;
                Mailbox = Mailbox + 1;
    
            }
        }
    
    
    /* 
    
    
    Notes:
    --------------------
    
    When a message is received, the message controller starts looking for a matching identifier
    at the mailbox with the highest mailbox number.
    
    * Case A: No Acceptance Mask Filtering is used
    * --------------------------------------------
    * In this case, every bit of the transmitted frame's MSGID must match with
    * (have the same value as) the corresponding bit of the Receive mailbox's MSGID.
    *
    * CANB.Mailbox30 will transmit to CANA.Mailbox30 and that message would be received in CANA.Mailbox30 only
    *
    * Case B: Acceptance Mask Filtering is used, but LAM bits are all zeroes
    * ----------------------------------------------------------------------
    * In this case, every bit of the transmitted frame's MSGID must STILL match with
    * (have the same value as) the corresponding bit of the Receive mailbox's MSGID.
    *
    * CANB.Mailbox20 will transmit to CANA.Mailbox20 and that message would be received in CANA.Mailbox20 only
    *
    * Case C: Acceptance Mask Filtering is used; Some LAM bits are ones
    * ----------------------------------------------------------------------
    * In this case, SOME bits of the transmitted frame's MSGID are masked as
    * "don't care" by making those bit-positions in the CANLAM register as "1".
    * Transmitted MSGID bits that have a "0" in the corresponding bit-positions in CANLAM
    * must match with the same bits of the Receive mailbox's MSGID. This is useful to
    * receive a GROUP of MSGIDs that differ only in a few bit positions.
    *
    * CANB.Mailboxes 10,9,8 will transmit to CANA.Mailbox10 and those messages would be received in CANA.Mailbox10.
    * Note that mailboxes 10,9,8 transmit messages with MSGIDs that are not exactly identical, but differing
    * in a few bit positions. However, since the LAM is setup to ignore (mask) those differing bits, the messages
    * will be correctly received in CANA.Mailbox10.
    *
    * Case D: Acceptance Mask Filtering is used; All LAM bits are ones
    * ----------------------------------------------------------------------
    * In this case, ALL bits of the transmitted frame's MSGID are masked as
    * "don't care" by making ALL bit-positions in the CANLAM register as "1".
    * This is useful to receive ANY MSGID in the same mailbox.
    *
    * CANB.Mailboxes 5,4,3,2,1 will transmit to CANA.Mailbox5 and those messages would be received in CANA.Mailbox5.
    * Note that mailboxes 5,4,3,2,1 transmit messages with completely different/random MSGIDs.
    * However, since the LAM is setup to ignore (mask) all bits, the messages will be correctly received in CANA.Mailbox5.
    *
    
    Status: Verified 3/27/2017
    
    ... */ 
    

  • Hi Hareesh,

    Thank you for your reply,

    With "am I obliged to work with data frame ?" I am speaking about arbitration, my question was about multi/sub mask using.

    My question can be : If I am using one msg object, so only one mask, for three different measures, am I obliged to select one with data frame ?

    example :
    Msg ID 0b00000000001 (msg object n°1)
    Msg Data (8 bytes) : 1 byte for measure type (byte 0) + 7 bytes for values (bytes 1-7)

    When msg object n°1 is received, I make an if elseif/case on the byte 0 then I save the measure value at the good place.


    I discovered the documentation with your previous post, I will study it before ask another question.

    Thank you for your help, I will create a new post for my next question.

    Have a nice day,
    Jérémy
  • Jeremy,

    I regret I still don’t understand exactly what your concern is with the question "If I am using one msg object, so only one mask, for three different measures, am I obliged to select one with data frame?" Data frames are the most common frames in the CAN protocol. Data frames are how data is transported from one node to other(s). If you don't use data frames how else would you move data? Can you re-phrase your question?

  • Hi Hareesh,

    No problem, I know that data are basis of the communication but all my post is about arbitration. I have spoken about data frame as complement of arbitration :

    Example, I use one message object for send three float numbers on three different CAN frames.

    Message object n°17

    Message ID : 0b010101010101

    data frame (5 bytes)  :               data[4]                         |          data[3] - data[0]

    use :                  type of measure              |                floatValue

    On reception of message object n°17:

    if (data[4] == 00000001){

    Xposition = floatValue;

    }

    else if (data[4] == 00000010){

    Yposition = floatValue;

    }

    else if (data[4] == 00000011){

    Zposition = floatValue;

    }

    Like this, with only one message object I can send three different values that can't be sent in one frame. It's why I speak about data frame as arbitration extention.

    What do you think about this manner ?

    Thank you,

    Jérémy

  • Jeremy,

                "Arbitration" (or more precisely, non-destructive, bit-wise arbitration of the MessageID) as used in the context of the CAN protocol has a completely different meaning. We use that term only in the context of resolving contention on the bus when two or more nodes attempt to start transmission at the same time. With that being said, what you have outlined appears to be a plausible approach. However, you are aware there are very many ways in which an application can be coded. While I am happy to help you with difficulties you are facing with specific bits/registers/features of the module on our device, my ability to help you with how you code your application is fairly limited. Thank you for your understanding.

  • Hi Hareesh,

    Thank you for your clarification but my attempt is not to have specific advice (all my example in my post are random situation). My aim was to have suggestion about different approaches because I am beginner in CAN and it's always rewarding to see different ways to make the same things.

    I will probably make a new post about message collision and priorities :)

    Thany you again and have a nice day,

    Best regards,
    Jérémy