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.

TMS320F28335: eCAN Receive Help

Part Number: TMS320F28335


Hello, 

I am having some issues with receiving messages via CAN. I have configured 3 mailboxes where mailbox 0 and 1 are used for transmitting data and mailbox 2 is used for receiving data. I have had no issue with transmitting messages.

To help debug the problem, I have reduced the code to solely receive messages and I have disabled interrupts. 

Can anyone see an issue with the code? Thanks in advance. 

Configuration: (bit timing not included to reduce number of lines in post) 

struct ECAN_REGS ECanaShadow; // Create a shadow register structure for the CAN control registers. This is needed, since only 32-bit access is allowed to these registers.

EALLOW; // EALLOW enables access to protected bits

GpioCtrlRegs.GPAMUX2.bit.GPIO18 = 3; 
GpioCtrlRegs.GPAMUX2.bit.GPIO19 = 3; 

SysCtrlRegs.PCLKCR0.bit.ECANAENCLK = 1; //Enable CAN A clock

ECanaShadow.CANRIOC.all = ECanaRegs.CANRIOC.all;
ECanaShadow.CANRIOC.bit.RXFUNC = 1; //CAN receive functions
ECanaRegs.CANRIOC.all = ECanaShadow.CANRIOC.all;

ECanaShadow.CANMC.all = ECanaRegs.CANMC.all;
ECanaShadow.CANMC.bit.SCB = 0; //Standard CAN controller
ECanaShadow.CANMC.bit.DBO = 1; //Data byte order
ECanaRegs.CANMC.all = ECanaShadow.CANMC.all;

//initialize registers to zero
ECanaMboxes.MBOX2.MSGCTRL.all = 0x00000000;

ECanaRegs.CANTA.all = 0xFFFFFFFF; /* Clear all TAn bits TA = transmission acknowledge*/
ECanaRegs.CANRMP.all = 0xFFFFFFFF; /* Clear all RMPn bits RMP = receive message pending*/
ECanaRegs.CANGIF0.all = 0xFFFFFFFF; /* Clear all interrupt flag bits */
ECanaRegs.CANGIF1.all = 0xFFFFFFFF;

ECanaShadow.CANGAM.all = ECanaRegs.CANGAM.all;
ECanaShadow.CANGAM.bit.AMI = 0;
ECanaRegs.CANGAM.all = ECanaShadow.CANGAM.all;


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

EDIS;

//Mailbox 2:
ECanaMboxes.MBOX2.MSGID.bit.AAM = 0; //No automatic replies to remote requests (AAM = auto answer mode)
ECanaMboxes.MBOX2.MSGID.bit.AME = 0; //No acceptance mask is used, all identifier bits must match to receive the message
ECanaMboxes.MBOX2.MSGID.bit.IDE = 0; //No extended identifier (IDE = identifier extension bit)
ECanaMboxes.MBOX2.MSGID.bit.STDMSGID = 0x100; //Message identifier

//Configure Mailbox(s) as either transmit or receive
ECanaShadow.CANMD.all = ECanaRegs.CANMD.all;
ECanaShadow.CANMD.bit.MD2 = 1; //receive
ECanaRegs.CANMD.all = ECanaShadow.CANMD.all;

//Enable Mailbox(s)
ECanaShadow.CANME.all = ECanaRegs.CANME.all;
ECanaShadow.CANME.bit.ME2 = 1;
ECanaRegs.CANME.all = ECanaShadow.CANME.all;

//Write to DLC field
ECanaMboxes.MBOX2.MSGCTRL.bit.DLC = 1;

ECanaRegs.CANMIM.all = 0x00000000;

Code in main.c:

for(;;){

if (ECanaRegs.CANRMP.bit.RMP2 = 1){

ECanaRegs.CANRMP.bit.RMP2 = 1; //Clear RMP

volatile struct MBOX *Mailbox;
Mailbox = &ECanaMboxes.MBOX2;

receive_l = Mailbox->MDL.all;
receive_h = Mailbox->MDH.all;
}

}

  • Hello,
    I am writing to let you know that a C2000 team member has been assigned to this post and should be answering shortly.

    Regards
    Baskaran
  • Himesh,

                Problem is in these two lines:

     

    if (ECanaRegs.CANRMP.bit.RMP2 = 1){

    ECanaRegs.CANRMP.bit.RMP2 = 1; //Clear RMP

     

    (1) You are not using 32-bit R/W

    (2) You are using "=" instead of "==".

     

    One way to check for reception is:

     

    while(1)                                                                                  

        {

         ECanaShadow.CANRMP.all = ECanaRegs.CANRMP.all;

     

         while(ECanaShadow.CANRMP.bit.RMP2 != 1 )

                {ECanaShadow.CANRMP.all = ECanaRegs.CANRMP.all;}  // Wait for RMPn to be set..

                 

         ECanaRegs.CANRMP.bit.RMP2 = 1;                                              // Clear RMPn bit and start all over again...

                                                                                                                                                    

        }      

  • Hi Hareesh,

    Thank you for reviewing my code. I have made the changes you recommended but I'm still not able to receive messages. I thought writing to the RMP2 bit would cause an issue related to 32-bit R/W so I made these additional changes but still no luck.

    ECanaShadow.CANRMP.all = ECanaRegs.CANRMP.all;

    while(ECanaShadow.CANRMP.bit.RMP2 != 1 )
    {ECanaShadow.CANRMP.all = ECanaRegs.CANRMP.all;} // Wait for RMPn to be set..

    ECanaShadow.CANRMP.all = 0;
    ECanaShadow.CANRMP.bit.RMP2 = 1; // Clear RMPn bit and start all over again...
    ECanaRegs.CANRMP.all = ECanaShadow.CANRMP.all;

    The software I am using to send messages generates an error related to the acknowledgement of the message. I will take a look at the configuration again to see if I can find the problem.

    Thanks,

    Himesh
  • Himesh,

                You are correct that the write to RMP2 in my code snippet does not employ 32-bit R/W. Thanks for catching that ! Can you post the schematics of your CAN bus connections?

     

    Please go through this debug checklist:

     

    •          Is clock to the CAN module enabled? (check for this if writes to CAN registers are not going through)

    •          Was the MSGGID register initialized to zero, before the individual bits/Bit-fields were configured?

    •          Are all CAN nodes configured for the same bit-rate? VERY important.

    •          Comment all EDIS from your code until you get it to work. You could add it later. Many registers and bits are EALLOW protected and a write may not go through if EALLOW is not active.

    •          Do not use Acceptance Mask Filtering initially. Transmit the same MSGID. Filtering could be added later.

    •          Check if the CAN frame is correctly seen at the CANRX pin of the MCU. You could verify the bit-rate in this step.

    •          Has the bus been terminated correctly (with 120-ohms) at either ends (only)? (The bus must be terminated only at either ends and with a 120-ohm resistor. In other words, no more than two terminator resistors may be present on the bus, unless split termination is followed, in which case there will be two resistors on either ends).

  • Hi Hareesh,

    I was able to figure out the issue, thank you for helping me debug! 

    In the code posted, I was trying to write to the CANGAM register before the CPU had write access.

    I have attached the code used to configure CAN communication for anyone else with a similar problem 

    void CAN_init(void){
    
    	struct ECAN_REGS ECanaShadow; // Create a shadow register structure for the CAN control registers. This is needed, since only 32-bit access is allowed to these registers.
    
    	EALLOW;		// EALLOW enables access to protected bits
    
    	GpioCtrlRegs.GPAMUX2.bit.GPIO18 = 3;   // Configure GPIO18 for CANRX operation
    	GpioCtrlRegs.GPAMUX2.bit.GPIO19 = 3;   // Configure GPIO19 for CANTX operation
    
    	SysCtrlRegs.PCLKCR0.bit.ECANAENCLK = 1; //Enable CAN A clock
    
        //Configure eCAN RX and TX pins for CAN operation using eCAN reg
        ECanaShadow.CANTIOC.all = ECanaRegs.CANTIOC.all;
        ECanaShadow.CANTIOC.bit.TXFUNC = 1; //CAN transmit functions
        ECanaRegs.CANTIOC.all = ECanaShadow.CANTIOC.all;
    
        ECanaShadow.CANRIOC.all = ECanaRegs.CANRIOC.all;
        ECanaShadow.CANRIOC.bit.RXFUNC = 1; //CAN receive functions
        ECanaRegs.CANRIOC.all = ECanaShadow.CANRIOC.all;
    
    	ECanaShadow.CANMC.all = ECanaRegs.CANMC.all;
    	ECanaShadow.CANMC.bit.SCB = 0; //Standard CAN controller
    	ECanaShadow.CANMC.bit.DBO = 1; //Data byte order
    	ECanaRegs.CANMC.all = ECanaShadow.CANMC.all;
    
    	//initialize registers to zero
        ECanaMboxes.MBOX0.MSGCTRL.all = 0x00000000;
        ECanaMboxes.MBOX1.MSGCTRL.all = 0x00000000;
        ECanaMboxes.MBOX2.MSGCTRL.all = 0x00000000;
    
    	ECanaRegs.CANTA.all	= 0xFFFFFFFF;	/* Clear all TAn bits TA = transmission acknowledge*/
    	ECanaRegs.CANRMP.all = 0xFFFFFFFF;	/* Clear all RMPn bits RMP = receive message pending*/
    	ECanaRegs.CANGIF0.all = 0xFFFFFFFF;	/* Clear all interrupt flag bits */
    	ECanaRegs.CANGIF1.all = 0xFFFFFFFF;
    
        // Request a configuration change  to the bit timing configuration and global acceptance mask registers
    	ECanaShadow.CANMC.all = ECanaRegs.CANMC.all;
    	ECanaShadow.CANMC.bit.CCR = 1 ;
        ECanaRegs.CANMC.all = ECanaShadow.CANMC.all;
    
        ECanaShadow.CANES.all = ECanaRegs.CANES.all;
    
        do
    	{
    	    ECanaShadow.CANES.all = ECanaRegs.CANES.all;
        } while(ECanaShadow.CANES.bit.CCE != 1 );  		// Wait until the CPU has write access to the configuration registers...
    
        //Configure global acceptance mask
        ECanaShadow.CANGAM.all = ECanaRegs.CANGAM.all;
        ECanaShadow.CANGAM.bit.AMI = 0;
        ECanaRegs.CANGAM.all = ECanaShadow.CANGAM.all;
    
        //Configure bit timing parameters for eCANA
        ECanaShadow.CANBTC.all = 0;
    
        #if (CPU_FRQ_150MHZ)                       // CPU_FRQ_150MHz is defined in DSP2833x_Examples.h
    		    // Bit rate = 500 kbps
    			ECanaShadow.CANBTC.bit.BRPREG = 9;
    			ECanaShadow.CANBTC.bit.TSEG2REG = 2;
    			ECanaShadow.CANBTC.bit.TSEG1REG = 10;
        #endif
    
        ECanaShadow.CANBTC.bit.SAM = 1;
        ECanaRegs.CANBTC.all = ECanaShadow.CANBTC.all;
    
        //Finished configuring bit timing parameters for eCANa
        ECanaShadow.CANMC.all = ECanaRegs.CANMC.all;
    	ECanaShadow.CANMC.bit.CCR = 0 ;            // Set CCR = 0
        ECanaRegs.CANMC.all = ECanaShadow.CANMC.all;
    
        ECanaShadow.CANES.all = ECanaRegs.CANES.all;
    
        do
        {
           ECanaShadow.CANES.all = ECanaRegs.CANES.all;
        } while(ECanaShadow.CANES.bit.CCE != 0 ); 		// Wait for CCE bit to be  cleared..
    
     	ECanaRegs.CANME.all = 0;		// Disable all Mailboxes, Required before writing the MSGIDs
    
        EDIS;
    
    }
    
    void CAN_Mbox_config(void){
    
    	struct ECAN_REGS ECanaShadow; // Create a shadow register structure for the CAN control registers. This is needed, since only 32-bit access is allowed to these registers.
    
       //Mailbox 0 - Transmit:
       ECanaMboxes.MBOX0.MSGID.all = 0;
       ECanaMboxes.MBOX0.MSGID.bit.AAM = 0; //No automatic replies to remote requests (AAM = auto answer mode)
       ECanaMboxes.MBOX0.MSGID.bit.IDE = 0; //No extended identifier (IDE = identifier extension bit)
       ECanaMboxes.MBOX0.MSGID.bit.STDMSGID = 0x200; //Message identifier
    
       //Configure Mailbox(s) as either transmit or receive
       ECanaShadow.CANMD.all = ECanaRegs.CANMD.all;
       ECanaShadow.CANMD.bit.MD0 = 0; //transmit
       ECanaRegs.CANMD.all = ECanaShadow.CANMD.all;
    
       //Enable Mailbox(s)
       ECanaShadow.CANME.all = ECanaRegs.CANME.all;
       ECanaShadow.CANME.bit.ME0 = 1;
       ECanaRegs.CANME.all = ECanaShadow.CANME.all;
    
       //Write to DLC field
       ECanaMboxes.MBOX0.MSGCTRL.bit.DLC = 8;
    
     	//Mailbox 1 - Transmit:
       ECanaMboxes.MBOX1.MSGID.all = 0;
       ECanaMboxes.MBOX1.MSGID.bit.AAM = 0; //No automatic replies to remote requests (AAM = auto answer mode)
       ECanaMboxes.MBOX1.MSGID.bit.IDE = 0; //No extended identifier (IDE = identifier extension bit)
       ECanaMboxes.MBOX1.MSGID.bit.STDMSGID = 0x300; //Message identifier
    
       //Configure Mailbox(s) as either transmit or receive
       ECanaShadow.CANMD.all = ECanaRegs.CANMD.all;
       ECanaShadow.CANMD.bit.MD1 = 0; //transmit
       ECanaRegs.CANMD.all = ECanaShadow.CANMD.all;
    
       //Enable Mailbox(s)
       ECanaShadow.CANME.all = ECanaRegs.CANME.all;
       ECanaShadow.CANME.bit.ME1 = 1;
       ECanaRegs.CANME.all = ECanaShadow.CANME.all;
    
       //Write to DLC field
       ECanaMboxes.MBOX1.MSGCTRL.bit.DLC = 8;
    
    	//Mailbox 2:
      ECanaMboxes.MBOX2.MSGID.all = 0;
      ECanaMboxes.MBOX2.MSGID.bit.AAM = 0; //No automatic replies to remote requests (AAM = auto answer mode)
      ECanaMboxes.MBOX2.MSGID.bit.AME = 0; //No acceptance mask is used, all identifier bits must match to receive the message
      ECanaMboxes.MBOX2.MSGID.bit.IDE = 0; //No extended identifier (IDE = identifier extension bit)
      ECanaMboxes.MBOX2.MSGID.bit.STDMSGID = 0x100; //Message identifier
    
      //Configure Mailbox(s) as either transmit or receive
      ECanaShadow.CANMD.all = ECanaRegs.CANMD.all;
      ECanaShadow.CANMD.bit.MD2 = 1; //receive
      ECanaRegs.CANMD.all = ECanaShadow.CANMD.all;
    
      //Enable Mailbox(s)
      ECanaShadow.CANME.all = ECanaRegs.CANME.all;
      ECanaShadow.CANME.bit.ME2 = 1;
      ECanaRegs.CANME.all = ECanaShadow.CANME.all;
    
      //Write to DLC field
      ECanaMboxes.MBOX2.MSGCTRL.bit.DLC = 1;
    
      ECanaRegs.CANMIM.all = 0x00000000;
    }

    Himesh