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 checking transmit-acknowledge flag CANTA of mailbox transmitted

Part Number: TMS320F28335
Other Parts Discussed in Thread: CONTROLSUITE

I am writing a can protocol and I'm wondering if i had to check CANTA bit of transmitted mailbox. I checked eCAN reference guide for 320f2833x and there are several points to transmit mailbox:

 

To start a transmission :

1. Write the message data into the mailbox data field.

a. Since DBO (MC.10) is set to zero in the configuration section and MSGCTRL(1) is set to 2, the data are stored in the 2 MSBytes of CANMDL(1).

b. Write CANMDL(1) = xxxx0000h

2. Set the corresponding flag in the transmit request register (CANTRS.1 = 1) to start the transmission of the message. The CAN module now handles the complete transmission of the CAN message.

3. Wait until the transmit-acknowledge flag of the corresponding mailbox is set (TA.1 = 1). After a successful transmission, this flag is set by the CAN module.

4. The TRS flag is reset to 0 by the module after a successful or aborted transmission (TRS.1 = 0).

5. The transmit acknowledge must be cleared for the next transmission (from the same mailbox).

a. Set TA.1 = 1

b. Wait until read TA.1 is 0

6. To transmit another message in the same mailbox, the mailbox RAM data must be updated. Setting the TRS.1 flag starts the next transmission. Writing to the mailbox

RAM can be half-word (16 bits) or full word (32 bits) but the module always returns 32-bit from even boundary. The CPU must accept all the 32 bits or part of it.

 

I had write code without waiting for CANTA and it works fine. When I wait for CANTA with while loop it stack when there was CAN error and there can not be successful transmission, CANTA was never set to 1. I had to write additional timeout to ensure proper code execution. I had read about CANTRS flag that it is 0 when transmission is successful or aborted and I write some code that works:

 

extern struct ECAN_REGS ECanShadow;
Uint16 SendMboxNum(Uint16 MboxNum, Uint32 id, Uint32 mdl, Uint32 mdh, Uint32 ctrl, Uint16 dlc)
{
    Uint32 shiftRes = 0U;   
    Uint16 ret = 0U;        
    Uint16 timeout = 2000U;

    shiftRes = (0x00000001U) << MboxNum;              

    if ((ECanaRegs.CANTRS.all & shiftRes) == 0U) {      
	ECanShadow.CANTA.all  = 0U;
	ECanShadow.CANTA.all |= shiftRes;		/* Clear TA bit */
	ECanaRegs.CANTA.all = ECanShadow.CANTA.all;

        ECanShadow.CANME.all  = ECanaRegs.CANME.all;
        ECanShadow.CANME.all &= ~shiftRes; /* Disable Mailbox */
        ECanaRegs.CANME.all    = ECanShadow.CANME.all;

        ECanaMboxes.MSGBOX[MboxNum].MSGID.all = id;
        ECanaMboxes.MSGBOX[MboxNum].MDL.all    = mdl;
        ECanaMboxes.MSGBOX[MboxNum].MDH.all    = mdh;
        ECanaMboxes.MSGBOX[MboxNum].MSGCTRL.all    = ctrl;

        ECanaMboxes.MSGBOX[MboxNum].MSGCTRL.bit.DLC   = dlc;      
        ECanaMboxes.MSGBOX[MboxNum].MSGCTRL.bit.RTR   = 0U;       /*RTR = 0 */

        ECanShadow.CANME.all  = ECanaRegs.CANME.all;
        ECanShadow.CANME.all |= shiftRes;  /* Enable Mailbox */
        ECanaRegs.CANME.all    = ECanShadow.CANME.all;

	do {
		ECanShadow.CANTA.all = ECanaRegs.CANTA.all;
		if(--timeout>0U) {break;}
	} while(ECanShadow.CANTA.all & shiftRes);
	ECanShadow.CANTRS.all  = 0U;
	ECanShadow.CANTRS.all |= shiftRes;		/* Send mailbox */
	ECanaRegs.CANTRS.all    = ECanShadow.CANTRS.all;
        ret=1U;                 
    }
    return ret;
}

This program waits for CANTA but it is waiting for clearing bit not to successful transmit. In practice I don't have to check CANTA because it is always cleared before "do while" loop execution.

Is it necessary to meet point 3 of mailbox transmission or am I missing something?

  • The setting of the CANTA bit (alone) indicates successful transmission of data. This is also a signal to the application that the next frame could be transmitted. If you don’t check the TA bit, how do you verify/ascertain that the previous frame was successfully transmitted and that transmission could be initiated for the next frame? In a real-world CAN network, the time taken to transmit a frame is not deterministic due to bus contention (other nodes with a higher-priority message winning arbitration) or errors on the bus. So, you need to use CANTA bit (either by polling it or using interrupts).

     

    The TA bit does not get cleared automatically. It must be cleared by writing a 1 to it.

     

    If you are polling for the TA bit to be set, but need to implement some sort of a time-out, you could use the Time-out interrupt by leveraging the MOTO register.

     

    Please let me know if I have not understood your concern correctly.

  • Yes I had to check CANTA bit to indicate successful transmition. I am writing a protocol like CANopen and I want to write CAN transmition function. I need to send events witch is buffered and it's necessary to maintain order of events send. In sending events I had to check CANTA to determine that event is properly send. But in this protocol I had a cyclic data of measurements that don't need to be send successfully all the time. Even more there should be send actual data rather than old data and I don't need to check CANTA bit in cyclic data.

    When I write transmition function I read ecan datasheet and examples in ControlSuite. There is point "3. Wait until the transmit-acknowledge flag of the corresponding mailbox is set (TA.1 = 1)" and it suggest to make while loop like example in ControlSuite:

           do
           {
          	ECanaShadow.CANTA.all = ECanaRegs.CANTA.all;
           } while(ECanaShadow.CANTA.bit.TA25 == 0 );   // Wait for TA5 bit to be set..
    

    But in case of disconnected CAN line, arbitration or when CAN module sets abort of transmition CANAA bit program stacks in while loop. In case of abort of transmition it stacks in infinite while loop which is unacceptable. To indicate end of transmition it should check CANTRS bit and after this bit is cleared check CANTA to indicate that frame is send. I think that in datasheet and examples it is not clear that you should not wait until CANTA bit is set.

  • The ControlSuite example shows one way of detecting completion of transmission. It is a simple example that doesn’t worry about code getting stuck in an infinite loop. The objective of that example is to enable someone to check the transmission function quickly. Once could either use the Time-out function built into the module or use a s/w timer to ensure the code does not get stuck in an infinite loop. I agree with you that checking the TRS bit is a better option, since it accounts for an aborted message as well. Note, however, that real-world applications seldom use polling and typically employ interrupts.