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.

CAN interface with TMS320f28335 on external CAN B

Other Parts Discussed in Thread: TMS320F28335, CONTROLSUITE

Hello,

I am using an TMS320f28335 processor and communicating with external world with a grid connect CAN-USB interface device, as per the implementation I am reading the message from the interface on MBOX1 which I have configured to receive message. When I read message from the CAN-USB interface on to my board I am getting the same CAN data i.e. if mail box has 00001000200030004, this data is copied in my entire buffer but when I debug and do single stepping through my code I read entire CAN data correctly and all the data is correctly populated in buffer. I have tried introducing delay to read between two messages but still the same data is copied for the entire length of my buffer.

Attached is the initialization of CAN B which I do and also before reading each message I clear the RMP bit as shown below

ECanbShadow.CANRMP.all = ECanbRegs.CANRMP.all;

ECanbShadow.CANRMP.bit.RMP1 = 1;

ECanbRegs.CANRMP.all = ECanbShadow.CANRMP.all;

 

Am I missing something?

 

Thanks,

Ajay

void InitECanb()
{

	struct ECAN_REGS ECanbShadow;

	asm(" EALLOW");		// EALLOW enables access to protected bits

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

    ECanbShadow.CANRIOC.all = ECanbRegs.CANRIOC.all;
    ECanbShadow.CANRIOC.bit.RXFUNC = 1;
    ECanbRegs.CANRIOC.all = ECanbShadow.CANRIOC.all;

	// Configure eCAN for HECC mode - (reqd to access mailboxes 16 thru 31)
	ECanbShadow.CANMC.all = ECanbRegs.CANMC.all;
	ECanbShadow.CANMC.bit.WUBA = 1;
	ECanbShadow.CANMC.bit.SCB = 1;
	ECanbShadow.CANMC.bit.SUSP = 1; 		//enable Free mode
	ECanbRegs.CANMC.all = ECanbShadow.CANMC.all;

	// Initialize all bits of 'Master Control Field' 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
    ECanbMboxes.MBOX0.MSGCTRL.all = 0x00000000;
    ECanbMboxes.MBOX1.MSGCTRL.all = 0x00000000;
    ECanbMboxes.MBOX2.MSGCTRL.all = 0x00000000;
    ECanbMboxes.MBOX3.MSGCTRL.all = 0x00000000;
    ECanbMboxes.MBOX4.MSGCTRL.all = 0x00000000;
    ECanbMboxes.MBOX5.MSGCTRL.all = 0x00000000;
    ECanbMboxes.MBOX6.MSGCTRL.all = 0x00000000;
    ECanbMboxes.MBOX7.MSGCTRL.all = 0x00000000;
    ECanbMboxes.MBOX8.MSGCTRL.all = 0x00000000;
    ECanbMboxes.MBOX9.MSGCTRL.all = 0x00000000;
    ECanbMboxes.MBOX10.MSGCTRL.all = 0x00000000;
    ECanbMboxes.MBOX11.MSGCTRL.all = 0x00000000;
    ECanbMboxes.MBOX12.MSGCTRL.all = 0x00000000;
    ECanbMboxes.MBOX13.MSGCTRL.all = 0x00000000;
    ECanbMboxes.MBOX14.MSGCTRL.all = 0x00000000;
    ECanbMboxes.MBOX15.MSGCTRL.all = 0x00000000;
    ECanbMboxes.MBOX16.MSGCTRL.all = 0x00000000;
    ECanbMboxes.MBOX17.MSGCTRL.all = 0x00000000;
    ECanbMboxes.MBOX18.MSGCTRL.all = 0x00000000;
    ECanbMboxes.MBOX19.MSGCTRL.all = 0x00000000;
    ECanbMboxes.MBOX20.MSGCTRL.all = 0x00000000;
    ECanbMboxes.MBOX21.MSGCTRL.all = 0x00000000;
    ECanbMboxes.MBOX22.MSGCTRL.all = 0x00000000;
    ECanbMboxes.MBOX23.MSGCTRL.all = 0x00000000;
    ECanbMboxes.MBOX24.MSGCTRL.all = 0x00000000;
    ECanbMboxes.MBOX25.MSGCTRL.all = 0x00000000;
    ECanbMboxes.MBOX26.MSGCTRL.all = 0x00000000;
    ECanbMboxes.MBOX27.MSGCTRL.all = 0x00000000;
    ECanbMboxes.MBOX28.MSGCTRL.all = 0x00000000;
    ECanbMboxes.MBOX29.MSGCTRL.all = 0x00000000;
    ECanbMboxes.MBOX30.MSGCTRL.all = 0x00000000;
    ECanbMboxes.MBOX31.MSGCTRL.all = 0x00000000;

	// TAn, RMPn, GIFn bits are all zero upon reset and are cleared again
	//	as a matter of precaution.
	ECanbRegs.CANTA.all	= 0xFFFFFFFF;	/* Clear all TAn bits */
	ECanbRegs.CANRMP.all = 0xFFFFFFFF;	/* Clear all RMPn bits */
	ECanbRegs.CANGIF0.all = 0xFFFFFFFF;	/* Clear all interrupt flag bits */
	ECanbRegs.CANGIF1.all = 0xFFFFFFFF;

	// Configure bit timing parameters for eCANB
	ECanbShadow.CANMC.all = ECanbRegs.CANMC.all;
	ECanbShadow.CANMC.bit.CCR = 1 ;            // Set CCR = 1
    ECanbRegs.CANMC.all = ECanbShadow.CANMC.all;

    ECanbShadow.CANES.all = ECanbRegs.CANES.all;

    do
	{
	    ECanbShadow.CANES.all = ECanbRegs.CANES.all;
	} while(ECanbShadow.CANES.bit.CCE != 1 ); 		// Wait for CCE bit to be  cleared..


    ECanbShadow.CANBTC.all = 0;

	// The following block for all 150 MHz SYSCLKOUT - Bit rate = 500Kbps
	ECanbShadow.CANBTC.bit.BRPREG = 9;  //19;
	ECanbShadow.CANBTC.bit.TSEG2REG = 2;
	ECanbShadow.CANBTC.bit.TSEG1REG = 10;

    ECanbShadow.CANBTC.bit.SAM = 1;
    ECanbRegs.CANBTC.all = ECanbShadow.CANBTC.all;

    ECanbShadow.CANMC.all = ECanbRegs.CANMC.all;
	ECanbShadow.CANMC.bit.CCR = 0 ;            // Set CCR = 0
    ECanbRegs.CANMC.all = ECanbShadow.CANMC.all;

    ECanbShadow.CANES.all = ECanbRegs.CANES.all;

    do
    {
        ECanbShadow.CANES.all = ECanbRegs.CANES.all;
    } while(ECanbShadow.CANES.bit.CCE != 0 ); 		// Wait for CCE bit to be  cleared..


	// Disable all Mailboxes
 	ECanbRegs.CANME.all = 0;		// Required before writing the MSGIDs
    asm(" EDIS");

    // Write to the MSGID field of TRANSMIT mailboxes MBOX0
//    ECanbMboxes.MBOX31.MSGID.all = 0x00400000;	//id 0x10

    // Write to the MSGID field of RECEIVE mailboxes MBOX1 - 31
	// see TI app note SPRU074E, page 2-42, ID is bit[28..18]
    ECanbMboxes.MBOX0.MSGID.all = 0x1D000000;	//id 0x740
    ECanbMboxes.MBOX1.MSGID.all = 0x1D040000;	//id 0x741
    ECanbMboxes.MBOX2.MSGID.all = 0x1D080000;	//id 0x742
    ECanbMboxes.MBOX3.MSGID.all = 0x1D0C0000;	//id 0x743
    ECanbMboxes.MBOX4.MSGID.all = 0x00100000;	//id 0x4
    ECanbMboxes.MBOX5.MSGID.all = 0x00140000;	//id 0x5
    ECanbMboxes.MBOX6.MSGID.all = 0x00180000;	//id 0x6
    ECanbMboxes.MBOX7.MSGID.all = 0x001C0000;	//id 0x7
    ECanbMboxes.MBOX8.MSGID.all = 0x00200000;	//id 0x8
    ECanbMboxes.MBOX9.MSGID.all = 0x00240000;	//id 0x9
    ECanbMboxes.MBOX10.MSGID.all = 0x00280000;	//id 0xA
    ECanbMboxes.MBOX11.MSGID.all = 0x002C0000;	//id 0xB
    ECanbMboxes.MBOX12.MSGID.all = 0x00300000;	//id 0xC
    ECanbMboxes.MBOX13.MSGID.all = 0x00340000;	//id 0xD
    ECanbMboxes.MBOX14.MSGID.all = 0x00380000;	//id 0xE
    ECanbMboxes.MBOX15.MSGID.all = 0x003C0000;	//id 0xF
    ECanbMboxes.MBOX16.MSGID.all = 0x00400000;	//id 0x10
    ECanbMboxes.MBOX17.MSGID.all = 0x00440000;	//id 0x11
    ECanbMboxes.MBOX18.MSGID.all = 0x004C0000;	//id 0x12
    ECanbMboxes.MBOX19.MSGID.all = 0x00500000;	//id 0x13
    ECanbMboxes.MBOX20.MSGID.all = 0x00540000;	//id 0x14
    ECanbMboxes.MBOX21.MSGID.all = 0x005C0000;	//id 0x15
    ECanbMboxes.MBOX22.MSGID.all = 0x00600000;	//id 0x16
    ECanbMboxes.MBOX23.MSGID.all = 0x00640000;	//id 0x17
    ECanbMboxes.MBOX24.MSGID.all = 0x006C0000;	//id 0x18
    ECanbMboxes.MBOX25.MSGID.all = 0x00700000;	//id 0x19
    ECanbMboxes.MBOX26.MSGID.all = 0x00740000;	//id 0x1A
    ECanbMboxes.MBOX27.MSGID.all = 0x007C0000;	//id 0x1B
    ECanbMboxes.MBOX28.MSGID.all = 0x00800000;	//id 0x1C
    ECanbMboxes.MBOX29.MSGID.all = 0x00840000;	//id 0x1D
    ECanbMboxes.MBOX30.MSGID.all = 0x008C0000;	//id 0x1E
    ECanbMboxes.MBOX31.MSGID.all = 0x00900000;	//id 0x1F

    // Configure Mailboxes 31 and 2 as Tx, 1-30 as Rx
    // Since this write is to the entire register (instead of a bit
    // field) a shadow register is not required.
    ECanbRegs.CANMD.all = 0x7FFFFFFB;

    // Enable MBOX0 to MBOX3 Mailboxes */
    // Since this write is to the entire register (instead of a bit
    // field) a shadow register is not required.
    ECanbRegs.CANME.all = 0x0000000F;

    // Write to the DLC field of MSGCTRL register of RECEIVE mailboxes MBOX0 - 30
    ECanbMboxes.MBOX0.MSGCTRL.bit.DLC = 8;
    ECanbMboxes.MBOX1.MSGCTRL.bit.DLC = 8;
    ECanbMboxes.MBOX2.MSGCTRL.bit.DLC = 8;
    ECanbMboxes.MBOX3.MSGCTRL.bit.DLC = 8;
/*    ECanbMboxes.MBOX4.MSGCTRL.bit.DLC = 8;
    ECanbMboxes.MBOX5.MSGCTRL.bit.DLC = 8;
    ECanbMboxes.MBOX6.MSGCTRL.bit.DLC = 8;
    ECanbMboxes.MBOX7.MSGCTRL.bit.DLC = 8;
    ECanbMboxes.MBOX8.MSGCTRL.bit.DLC = 8;
    ECanbMboxes.MBOX9.MSGCTRL.bit.DLC = 8;
    ECanbMboxes.MBOX10.MSGCTRL.bit.DLC = 8;
    ECanbMboxes.MBOX11.MSGCTRL.bit.DLC = 8;
    ECanbMboxes.MBOX12.MSGCTRL.bit.DLC = 8;
    ECanbMboxes.MBOX13.MSGCTRL.bit.DLC = 8;
    ECanbMboxes.MBOX14.MSGCTRL.bit.DLC = 8;
    ECanbMboxes.MBOX15.MSGCTRL.bit.DLC = 8;
    ECanbMboxes.MBOX16.MSGCTRL.bit.DLC = 8;
    ECanbMboxes.MBOX17.MSGCTRL.bit.DLC = 8;
    ECanbMboxes.MBOX18.MSGCTRL.bit.DLC = 8;
    ECanbMboxes.MBOX19.MSGCTRL.bit.DLC = 8;
    ECanbMboxes.MBOX20.MSGCTRL.bit.DLC = 8;
    ECanbMboxes.MBOX21.MSGCTRL.bit.DLC = 8;
    ECanbMboxes.MBOX22.MSGCTRL.bit.DLC = 8;
    ECanbMboxes.MBOX23.MSGCTRL.bit.DLC = 8;
    ECanbMboxes.MBOX24.MSGCTRL.bit.DLC = 8;
    ECanbMboxes.MBOX25.MSGCTRL.bit.DLC = 8;
    ECanbMboxes.MBOX26.MSGCTRL.bit.DLC = 8;
    ECanbMboxes.MBOX27.MSGCTRL.bit.DLC = 8;
    ECanbMboxes.MBOX28.MSGCTRL.bit.DLC = 8;
    ECanbMboxes.MBOX29.MSGCTRL.bit.DLC = 8;
    ECanbMboxes.MBOX30.MSGCTRL.bit.DLC = 8;
*/

    ECanbShadow.CANOPC.all = ECanbRegs.CANOPC.all;
    ECanbShadow.CANOPC.bit.OPC1 = 0;
    ECanbRegs.CANOPC.all = ECanbShadow.CANOPC.all;

	// enable receive mailbox interrupts, disable transmit mailbox interrupts
    // Since this write is to the entire register (instead of a bit
    // field) a shadow register is not required.
    asm(" EALLOW");
    ECanbRegs.CANMIM.all = 0xFFFFFFFF;
	asm(" EDIS");
	// Enable eCAN0INT

	asm(" EALLOW");
    ECanbShadow.CANGIM.all = ECanbRegs.CANGIM.all;
	ECanbShadow.CANGIM.bit.GIL  = 1;
	ECanbShadow.CANGIM.bit.I0EN = 1;
    ECanbRegs.CANGIM.all = ECanbShadow.CANGIM.all;
    asm(" EDIS");

}

  • Ajay,

       I regret your description of the problem is not clear. Please answer all the questions below:

    1. How many nodes are on the network?
    2. Who is transmitting to who? When? How often?
    3. What is being transmitted?
    4. Is the transmitted data matching the received data in MBOX1?
    5. What is the exact sequence of transmission.

    I read your post many times, but still unable to understand what exactly your problem is.

  • Hello Harish,

    Sorry that u didn't get the issue, the set up is a device which is having TMS320F28335 processor and I am trying to develop a boot loader which uses external CAN to send application software. To communicate on external CAN of TMS device a CAN-USB interface ( Grid Connect) is used. Its a two way communication in which TMS device external CAN B mailboxes MBOX0, MOBX1 and MBOX3 are configured as receive and MBOX2 is configured as transmit.

    Sequence of transmission and receive is as follows

    1) PC to send 8 bytes of CAN data to TMS device on MBOX1

    2) TMS device acknowledges the data on MBOX1 and read and store the data in buffer, after reading data clear the RMP bit for MBOX1 and send an acknowledgment to PC via  MBOX2.

    3) After receiving acknowledgement PC sends the next 8 bytes in MBOX1 and TMS device waits till RMP bit is set for MBOX1.

    4) This process is repeated till entire block of expected data is sent via PC to TMS device.

    Currently I am able to receive data from PC to MBOX1 if I single step through the program i.e. 8 bytes at a time but if I send the entire data without single stepping I am not getting the entire data and missing some bytes.

    Speed of CAN bus is set to 500 Kbps in TMS device as well as CAN-USB interface is set to 500 Kbps.

    My question is on the TMS device front, whether I am missing some more checks for receiving data on TMS processor or I need to do some more additional checks for storing data?

    Regards,

    Ajay

  • Ajay,

    there is still not enough input from your side. You mentioned that you have problems in receiving messages in real-time. However, you did not explain, how you actually handle the CAN-receiving. Also, you did not explain, how often the 2nd node transmits. You mentioned a sort of a handshake between the 28335 and the PC based on a transmission of MBOX2 backt to PC. Does this work? Does the PC actually wait, if there is no message coming from the F28335?

    Frank
  • Ajay,

    You have 3 receive mailboxes configured on the 28335, but use only MBX1 for reception? Frank has a good point: Does the host actually wait for the ACK from the 28335 before transmitting the next set of data? If not, MBX1 content could be simply overwritten. Do you have OPC set for MBX1? Have you checked the status of RML flag? I have a feeling, MBX1 is being overwritten. Checking the RMP flag is indeed a reliable way to ensure reception of communication.
  • Harish and Frank,

    The communication between PC and TMS device is continuous and the TMS processor waits till it receives an message on MBOX1 from PC, this I do by checking the RMP bit for MBOX1

    while (ECanbRegs.CANRMP.bit.RMP1 == 0){}

    Once I receive the message and store the same in buffer of TMS device, I clear the RMP bit and send acknowledgment to PC for sending the next 8 bytes of data.

    ECanbShadow.CANRMP.all = ECanbRegs.CANRMP.all;
    ECanbShadow.CANRMP.bit.RMP1 = 1;
    ECanbRegs.CANRMP.all = ECanbShadow.CANRMP.all;

    Yes PC host will wait for an acknowledgement before transmitting any data and MBOX1 is protected from being overwritten, I am not checking the RML status, yes the acknowledgment back to PC is checked via the CANTA bit and it will wait till data is sent on MBOX2

    while(ECanbRegs.CANTA.all != 0x00000004 ) {}

    My question was that on the TMS front do I need to do additional checks to ensure that data is received from PC on MBOX1?

    Regards,
    Ajay
  • You cannot do the following:
    while (ECanbRegs.CANRMP.bit.RMP1 == 0){} , since it does not employ 32-bit R/W.
     
    You should use 32-bit R/W (using the shadow registers) even while checking for the RMP bit . You could employ a do-while , as shown in some Controlsuite examples.
  • Please try this:

     ECanbShadow.CANRMP.all = ECanbRegs.CANRMP.all; 

    do

       {

             ECanbShadow. CANRMP.all = ECanbRegs. CANRMP.all;

       } while(ECanbShadow. CANRMP.bit.RMP1 != 1 );                       // Wait for RMP1 bit to be set..

    ECanbShadow.CANRMP.bit.RMP1 = 1;

    ECanbRegs.CANRMP.all = ECanbShadow.CANRMP.all;

    You mention that " MBOX1 is protected from being overwritten", but do you have one or more receive mailboxes configured for the same MSGID, so that if MBOX1 is yet to be read, data will be received in these "overflow" mailboxes? Please do check RML1 bit to see if any messages are indeed being overwritten.

  • Hareesh,

    After trying all options and different combinations I found that TMS processor is not waiting for new data to come from PC utility and just reads the old data present in the same mailbox, I tried GMIF0 and MIV0 bits but still not able to receive new message.

    TMS processor is working at a much faster rate that the PC utility, is there a way to clear the receive mailbox after reading the data ( CANRMP also didn't help much).

    Regards,

    Ajay