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.

TMS320F28065: ecan Mailbox receives the wrong message

Part Number: TMS320F28065
Other Parts Discussed in Thread: C2000WARE

Hi experts,

I have a question about Mailbox data reception.

I modify a back2bak demo code(C:\software\c2000ware\C2000Ware_4_03_00_00\device_support\f2806x\examples\c28\ecan_back2back) in order to test the acceptance mask. I set mailbox 30 and mailbox 31 as receiving mailbox, mailbox13 and mailbox15 as transmitting mailbox. The mailbox30 receives the message from mailbox 13. The mailbox31 receives the message from mailbox 15. I didn't modify the InitECana() and InitECanGpio().

This is the code 

#define REC_MBOX31_MSGID_ID        0x784UL
#define REC_MBOX31_LOCAL_FILTER    0x0003FFFF
#define REC_MBOX30_MSGID_ID        0x785UL
#define REC_MBOX30_LOCAL_FILTER    0x0003FFFF

#define REC_MBOX_LAM_LAMI         0x80000000UL
#define REC_MBOX_MSGIN_AME        0x40000000UL

#define REC_MBOX30_LAM_REG        ((REC_MBOX30_MSGID_ID<<18)&0x1FFFFFFF | REC_MBOX_LAM_LAMI)
#define REC_MBOX30_MSGID_REG      ((REC_MBOX30_MSGID_ID<<18)&0x1FFFFFFF | REC_MBOX_MSGIN_AME)

#define REC_MBOX31_LAM_REG        ((REC_MBOX31_MSGID_ID<<18)&0x1FFFFFFF | REC_MBOX_LAM_LAMI)
#define REC_MBOX31_MSGID_REG      ((REC_MBOX31_MSGID_ID<<18)&0x1FFFFFFF | REC_MBOX_MSGIN_AME)

void main(void)
{
    Uint16  j;

    Uint16 i;

    struct ECAN_REGS ECanaShadow;

    InitSysCtrl();

    InitECanGpio();

    DINT;

    InitPieCtrl();

    IER = 0x0000;
    IFR = 0x0000;

    InitPieVectTable();

    MessageReceivedCount = 0;
    ErrorCount = 0;
    PassCount = 0;

    InitECana();            // Initialize eCAN-A module


    //transmit setting
    ECanaMboxes.MBOX13.MSGID.all = REC_MBOX30_MSGID_REG;// 0x9555AAAF;//
    ECanaMboxes.MBOX15.MSGID.all = REC_MBOX31_MSGID_REG;// 0x9555AAAF;//
    ECanaMboxes.MBOX30.MSGID.all = REC_MBOX30_MSGID_REG;// 0x9555AAAF;//
    ECanaMboxes.MBOX31.MSGID.all = REC_MBOX31_MSGID_REG;//0x9555AAAF;//

    ECanaRegs.CANMD.all = 0xC0000000;//CHANGE

    ECanaMboxes.MBOX13.MSGCTRL.bit.DLC = 8;

    ECanaMboxes.MBOX15.MSGCTRL.bit.DLC = 8;

    ECanaMboxes.MBOX13.MDL.all = 0x22222222;
     ECanaMboxes.MBOX13.MDH.all = 0x22334455;


     ECanaMboxes.MBOX15.MDL.all = 0x11111111;
     ECanaMboxes.MBOX15.MDH.all = 0x11223344;

    ECanaRegs.CANTA.all = 0xFFFFFFFF;    // Clear all TAn bits
    ECanaRegs.CANRMP.all = 0xFFFFFFFF;   // Clear all RMPn bits

    ECanaRegs.CANGIF0.all = 0xFFFFFFFF;  // Clear all interrupt flag bits
    ECanaRegs.CANGIF1.all = 0xFFFFFFFF;

    ECanaLAMRegs.LAM30.all = REC_MBOX30_LAM_REG;
    ECanaLAMRegs.LAM31.all = REC_MBOX31_LAM_REG;

    ECanaRegs.CANOPC.all  = 0xC0000000;  //change

    //
    EALLOW;

    ECanaRegs.CANGIM.all = 0x00000000;

    ECanaRegs.CANMIM.all = 0xFFFFFFFF;



    ECanaShadow.CANMC.all = ECanaRegs.CANMC.all;
    ECanaShadow.CANMC.bit.STM = 1;    // Configure CAN for self-test mode
    ECanaRegs.CANMC.all = ECanaShadow.CANMC.all;
    EDIS;


    ECanaRegs.CANMD.all = 0xC0000000;
    ECanaRegs.CANME.all = 0xC000A000;

    //
    // Begin transmitting
    //
    for(;;)
    {
        //
        // Set TRS for all transmit mailboxes
        //
        ECanaRegs.CANTRS.all = 0x0000A000;
        
        while(ECanaRegs.CANTA.all != 0x0000A000 )
        {


        }
        ECanaRegs.CANTA.all = 0x0000A000;

        j=30;

            mailbox_read(j);         

    }
}

void
InitECanaGpio(void)
{
    EALLOW;

    //
    // Enable internal pull-up for the selected CAN pins
    // Pull-ups can be enabled or disabled by the user.
    // This will enable the pullups for the specified pins.
    // Comment out other unwanted lines.
    //
    GpioCtrlRegs.GPAPUD.bit.GPIO30 = 0;   // Enable pull-up for GPIO30 (CANRXA)
    GpioCtrlRegs.GPAPUD.bit.GPIO31 = 0;   // Enable pull-up for GPIO31 (CANTXA)

    //
    // Set qualification for selected CAN pins to asynch only
    // Inputs are synchronized to SYSCLKOUT by default.
    // This will select asynch (no qualification) for the selected pins.
    //
    GpioCtrlRegs.GPAQSEL2.bit.GPIO30 = 3;   // Asynch qual for GPIO30 (CANRXA)

    //
    // Configure eCAN-A pins using GPIO regs
    // This specifies which of the possible GPIO pins will be eCAN functional 
    // pins.
    //
    
    //
    // Configure GPIO30 for CANRXA operation
    //
    GpioCtrlRegs.GPAMUX2.bit.GPIO30 = 1;    
    
    //
    // Configure GPIO31 for CANTXA operation
    //
    GpioCtrlRegs.GPAMUX2.bit.GPIO31 = 1;

    EDIS;
}
#endif

void
InitECana(void)
{
    //
    // Create a shadow register structure for the CAN control registers. 
    // This is needed, since only 32-bit access is allowed to these registers. 
    // 16-bit access to these registers could potentially corrupt the register 
    // contents or return false data.
    //
    struct ECAN_REGS ECanaShadow;
    
    //
    // Setup variables to initialize mailboxes to zero
    //
    int16 mboxCount;
    volatile struct MBOX *Mailbox = (void *) 0x6100;

    EALLOW;     // EALLOW enables access to protected bits

    //
    // Configure eCAN RX and TX pins for CAN operation using eCAN regs
    //
    ECanaShadow.CANTIOC.all = ECanaRegs.CANTIOC.all;
    ECanaShadow.CANTIOC.bit.TXFUNC = 1;
    ECanaRegs.CANTIOC.all = ECanaShadow.CANTIOC.all;

    ECanaShadow.CANRIOC.all = ECanaRegs.CANRIOC.all;
    ECanaShadow.CANRIOC.bit.RXFUNC = 1;
    ECanaRegs.CANRIOC.all = ECanaShadow.CANRIOC.all;

    //
    // Configure eCAN for HECC mode - (reqd to access mailboxes 16 thru 31)
    // HECC mode also enables time-stamping feature
    //
    ECanaShadow.CANMC.all = ECanaRegs.CANMC.all;
    ECanaShadow.CANMC.bit.SCB = 1;
    ECanaRegs.CANMC.all = ECanaShadow.CANMC.all;

    //
    // Initialize all registers of the mailboxes to zero
    // Some bits of MSGCTRL register come up in an unknown state. 
    // For proper operation, all bits (including reserved bits) of MSGCTRL must
    // be initialized to zero
    //
    for(mboxCount=0; mboxCount<32; mboxCount++)
    {
        Mailbox->MSGID.all = 0;
        Mailbox->MSGCTRL.all = 0;
        Mailbox->MDH.all = 0;
        Mailbox->MDL.all = 0;
        Mailbox = Mailbox + 1;
    }

    //
    // TAn, RMPn, GIFn bits are all zero upon reset and are cleared again
    //  as a matter of precaution.
    //
    ECanaRegs.CANTA.all = 0xFFFFFFFF;    // Clear all TAn bits

    ECanaRegs.CANRMP.all = 0xFFFFFFFF;   // Clear all RMPn bits

    ECanaRegs.CANGIF0.all = 0xFFFFFFFF;  // Clear all interrupt flag bits
    ECanaRegs.CANGIF1.all = 0xFFFFFFFF;

    //
    // Configure bit timing parameters for eCANA
    //
    ECanaShadow.CANMC.all = ECanaRegs.CANMC.all;
    ECanaShadow.CANMC.bit.CCR = 1 ;            // Set CCR = 1
    ECanaRegs.CANMC.all = ECanaShadow.CANMC.all;
    
    //
    // Wait until the CPU has been granted permission to change the 
    // configuration registers
    //
    do
    {
        ECanaShadow.CANES.all = ECanaRegs.CANES.all;
    } while(ECanaShadow.CANES.bit.CCE != 1 );   // Wait for CCE bit to be set

    ECanaShadow.CANBTC.all = 0;
    
    //
    // The following block is for 90 MHz SYSCLKOUT. 
    // (45 MHz CAN module clock Bit rate = 1 Mbps)
    // See Note at end of file.
    //
    ECanaShadow.CANBTC.bit.BRPREG = 2;
    ECanaShadow.CANBTC.bit.TSEG1REG = 10;
    ECanaShadow.CANBTC.bit.TSEG2REG = 2;

    ECanaRegs.CANBTC.all = ECanaShadow.CANBTC.all;

    ECanaShadow.CANMC.all = ECanaRegs.CANMC.all;
    ECanaShadow.CANMC.bit.CCR = 0 ;            // Set CCR = 0
    ECanaRegs.CANMC.all = ECanaShadow.CANMC.all;

    //
    // Wait until the CPU no longer has permission to change the 
    // configuration registers
    //
    do
    {
        ECanaShadow.CANES.all = ECanaRegs.CANES.all;
    } while(ECanaShadow.CANES.bit.CCE != 0 );// Wait for CCE bit to be  cleared

    //
    //  Disable all Mailboxes
    //
    ECanaRegs.CANME.all = 0;        // Required before writing the MSGIDs

    EDIS;
}
#endif // endif DSP28_ECANA

If the setting is correct, the mailbox 30 should receive 0x22222222 and 0x22334455. The mailbox 30 should receive 0x11111111 and 0x11223344.

But when I debug, the mailbox30 receives sometimes 0x22222222 and 0x22334455, sometimes 0x11111111 and 0x11223344. It seems that the mailbox30 receives the message of both transmitting mailbox.

But if I comment the code ECanaRegs.CANOPC.all  = 0xC0000000;, the problem will not occur anymore.

Could you help me to find out where is wrong?

Besides I want a demo about acceptance mask because I think the setting in this code maybe wrong. I have download in c2000ware_1_00_01_00 which is mentioned in SPRA876B but I can't find the CAN_LAM  example in C:\ti\c2000\C2000Ware_1_00_01_00\device_support\f2833x\examples. Could you give me a example about that?

The code is in attachment.

Thanks for your help!!

Best Regards

Kita

ecan_test.zip

  • Kita,

                    There is an example in SPRA876 that shows how acceptance filtering works. The examples are not part of C2000ware. They need to be downloaded from http://www.ti.com/lit/zip/spra876. Also, features like acceptance mask filtering is better tested using two separate nodes and not within the same node using self-test mode.

  • Hi Hareesh,

    Thanks for your advice.

    I modify the code and the current code is without  acceptance mask filtering, but the issue still occurs.

    I am sure that the identifier of mailbox 13 equals identifier of mailbox 30, the identifier of mailbox 15 equals identifier of mailbox 31.

    Sometimes the mailbox 30 receives the data of mailbox 15.

    Sometimes the mailbox 30 receives the data of mailbox 13, the right data.

    Then I try to clear CANRMP of mailbox30 and mailbox31 before the CANTRS is cleared. The issue doesn't occur anymore. The mailbox 30 receives the data of mailbox 13, the right data.

    But if I comment "ECanaRegs.CANRMP.all = 0xC0000000", the issue still occurs.

    I am confused about that.

    1. According to TRM, the receiving mailbox will only receive the data information corresponding to the identifier. If the CANOPC is enabled, the unread messages is prevented from being overwritten.

    The CANRMP-bit of the mailbox must be cleared after the message has been copied from the mailbox. Otherwise the mailbox cannot receive a next message (assuming the OPC feature is used).  The clear command can be executed directly into the original register, no shadow is needed.

    In this code the CANOPC of mailbox 30 and mailbox 31 is both enabled. Why does the mailbox30 sometimes receive the wrong value??? 

    2. If CANRMP bit of the mailbox isn't cleared, the mailbox cannot receive a next message (assuming the OPC feature is used).  

    But in the original code, the mailbox30 can still receive the message(sometimes is wrong) even though CANRMP is not cleared.

    Could you tell me the reason?

    3. Why the CANRMP is cleared, the issue doesn't occur anymore???

    ecan_test_new.zip

    The code is in attachment.

    Thanks for your help!

    Best Regards

    Kita

  • Kita,

                  CANRMP bit must be cleared as soon as the data is read. This is the correct way of using the module.

    1. According to TRM, the receiving mailbox will only receive the data information corresponding to the identifier. If the CANOPC is enabled, the unread messages is prevented from being overwritten.

    Correct.

    The CANRMP-bit of the mailbox must be cleared after the message has been copied from the mailbox. Otherwise the mailbox cannot receive a next message (assuming the OPC feature is used).  The clear command can be executed directly into the original register, no shadow is needed.

    Use of shadow register is mandatory if all 32-bits are not written to.

    In this code the CANOPC of mailbox 30 and mailbox 31 is both enabled. Why does the mailbox30 sometimes receive the wrong value??? 

    As mentioned before, please try communication between two nodes, not in self-test mode.

    But in the original code, the mailbox30 can still receive the message(sometimes is wrong) even though CANRMP is not cleared.

    Could you tell me the reason?

    It could be that the behavior is not well-defined in self-test mode.

    The code is in attachment.

    Debugging code is not something we can support in e2e. All examples in SPRA876 are tested examples. Please try them.