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.

Receiving messages via CAN

Hello

I am having hard time with receiving/Transmitting via CAN. I am simultaneously sending all 32 messages, however on CANanalyzer, only showing 17 of them(message number 1- 15 and 31).  I check the init and std type but cannot figure out why. Is it a bug? I tried to send one message at a time but still only first 16 messages and last message are shown. Is it a bug ?

Thanks

 

  • Would you please give us the device type, which you are using?

     

  • thanks for reply

    well, I am using "TMS 320f280" for the processor and eCan is enabled

    This is my configuration for transmit/receive mailbox .

     unsigned int CANAB_Std_Object_Setup(unsigned int object_num,      unsigned char num_bytes,
           unsigned char rx_tx,
           unsigned int mesg_id,
           unsigned char INT_level,
           unsigned char CAN_A_B)
    {

     volatile struct MBOX *Mailbox;
     unsigned long mask;

     if (CAN_A_B == 1)
     {
      if ((object_num > 31) || (num_bytes > 8) || (mesg_id > 65535) || (rx_tx > 1) || (INT_level > 1))
       return (-1);
      

      else
      {
       // assign pointers to the mailbox with respect to object numbers
       Mailbox = &ECanaMboxes.MBOX0 + object_num;

       // init the msgctrl with all zeros, as reg come up in an unknown state
       Mailbox->MSGCTRL.all = 0x00;

       // get a mask for mailbox object num
       mask = (long)(0x01) << object_num;
       
       // check for receive object
       if(rx_tx == 1)
       {
        // overwrite protection is enabled
        ECanaRegs.CANOPC.all |= mask;

        // set the respective bit to configure as receive mailbox
        ECanaRegs.CANMD.all |= mask; 
       }
       else if (rx_tx == 0)  // check for transmit object
       {
        // set the TRR bit
        ECanaRegs.CANTRR.all |= mask;

        // wait till the TRS bit is clear
        if ((ECanaRegs.CANTRS.all & mask) != 0 ) {  }

        // clear the respective bit to configure as transmit mailbox
        ECanaRegs.CANMD.all &= ~mask;
       }
       else
       { /* do nothing */ }

       if (INT_level == 1)
       {
        // set the interrupt level to ECAN1INT (Rx function)
        ECanaRegs.CANMIL.all |= mask;
        
        // enable the mailbox interrupts
        EALLOW;
        ECanaRegs.CANMIM.all |= mask;
        EDIS;

       }
       else if (INT_level == 0)
       {
        // set(0) the interrupt level to ECAN0INT (Tx function)
        ECanaRegs.CANMIL.all &= ~mask;

        // enable the mailbox interrupts
        EALLOW;
        ECanaRegs.CANMIM.all |= mask;
        EDIS;

       }
       else
       { /* do nothing */ }

       // disable (clear) the corresponding mailbox before writing the mesg id
       ECanaRegs.CANME.all &= ~mask;

       // set the mesg id for the corresponding mailbox
       Mailbox->MSGID.all = (Uint32)mesg_id << 18;

       // set the data length of the corresponding mailbox
       Mailbox->MSGCTRL.bit.DLC = num_bytes;

       // clear all the data register values
       Mailbox->MDL.all = 0x00;
       Mailbox->MDH.all = 0x00;

       // enable the corresponding mailbox
       ECanaRegs.CANME.all |= mask;

       return (0);
      }
     }
     

    here is the thing. If I use all 32 mailboxes to transmit, then only mailbox #1-15 and 31 is seems working, and if comment out some of object setup, then some mailbox between #16-30.

    CANAB_Std_Object_Setup(0, 8, 0, 0x0, 0, 1);
    CANAB_Std_Object_Setup(1, 8, 0, 0x1, 0, 1);
    CANAB_Std_Object_Setup(2, 8, 0, 0x2, 0, 1);
    CANAB_Std_Object_Setup(3, 8, 0, 0x3, 0, 1);
    CANAB_Std_Object_Setup(4, 8, 0, 0x4, 0, 1);
    CANAB_Std_Object_Setup(5, 8, 0, 0x5, 0, 1);
    CANAB_Std_Object_Setup(6, 8, 0, 0x6, 0, 1);
    CANAB_Std_Object_Setup(7, 8, 0, 0x7, 0, 1);
    CANAB_Std_Object_Setup(8, 8, 0, 0x8, 0, 1);
    CANAB_Std_Object_Setup(9, 8, 0, 0x09, 0, 1);
    CANAB_Std_Object_Setup(10, 8, 0, 0x0A, 0, 1);
    CANAB_Std_Object_Setup(11, 8, 0, 0x0B, 0, 1);
    CANAB_Std_Object_Setup(12, 8, 0, 0x0C, 0, 1);
    CANAB_Std_Object_Setup(13, 8, 0, 0x0D, 0, 1);
    CANAB_Std_Object_Setup(14, 8, 0, 0x0E, 0, 1);
    CANAB_Std_Object_Setup(15, 8, 0, 0x0F, 0, 1);
    CANAB_Std_Object_Setup(16, 8, 0, 0x10, 0, 1);
    CANAB_Std_Object_Setup(17, 8, 0, 0x120, 0, 1);
    CANAB_Std_Object_Setup(18, 8, 0, 0x12, 0, 1);
    CANAB_Std_Object_Setup(19, 8, 0, 0x13, 0, 1);
    CANAB_Std_Object_Setup(20, 8, 0, 0x14, 0, 1);
    CANAB_Std_Object_Setup(21, 8, 0, 0x15, 0, 1);
    CANAB_Std_Object_Setup(22, 8, 0, 0x16, 0, 1);
    CANAB_Std_Object_Setup(23, 8, 0, 0x17, 0, 1);
    CANAB_Std_Object_Setup(24, 8, 0, 0x18, 0, 1);
    CANAB_Std_Object_Setup(25, 8, 0, 0x19, 0, 1);

    CANAB_Std_Object_Setup(26, 8, 0, 0x1A, 0, 1);
    CANAB_Std_Object_Setup(27, 8, 0, 0x1B, 0, 1);
    CANAB_Std_Object_Setup(28, 8, 0, 0x1C, 0, 1);
    CANAB_Std_Object_Setup(29, 8, 0, 0x1D, 0, 1);
    CANAB_Std_Object_Setup(30, 8, 0, 0x1E, 0, 1);
    CANAB_Std_Object_Setup(31, 8, 0, 0x1F, 0, 1);

  • The following lines from your code look wrong:

    // wait till the TRS bit is clear
       if ((ECanaRegs.CANTRS.all & mask) != 0 ) {  }

    1st: An "if" statement will not wait at all  - a classical basic error.

    2nd: If you set the TRS bit to request a transmission, the correct bit to poll for a succesful transmission is "TA"

     

     

  • Sung Han said:

       if(rx_tx == 1)
       {
        // overwrite protection is enabled
        ECanaRegs.CANOPC.all |= mask;

        // set the respective bit to configure as receive mailbox
        ECanaRegs.CANMD.all |= mask; 
       }

    In spru074e.pdf (e.g., footnote on page 1-12) it is stated, that only 32-bit accesses are allowed on control and status registers.

    Your code looks as if you were accessing control and status registers directly which could lead to 16-bit accesses.

    In the eCAN examples from TI, shadow structures are used to ensure 32-bit access:

      ECanaShadow.CANMD.bit.MD5 = 0;

      ECanaRegs.CANMD.all = ECanaShadow.CANMD.all;

    BTW, can someone from TI explain what forces the compiler to always generate code for one 32 bit write rather than two 16 bit writes for code like this?

    Thanks and regards, Johannes

  • I used ECanaShadow for all status and control registers, and it fixed the problem.

    Before, it led to 16bit accesss, now all 32bits are enabled and transmitting/receiving

    Thanks Johannes.