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.

Regarding CAN in TMS570LS0332

Other Parts Discussed in Thread: TMS570LS0332, HALCOGEN

Hi,

I am using the TMS570LS0332 in my design. I am using the CAN peripheral of the device. I have more CAN IDs in my application than the number of message boxes provided by the micro controller hardware. I would like to implement a software function which can change the CAN ID and CAN message length dynamically.

Do you have any suggestions/Application notes regarding the implementation? 

Thanks & Best Regards,

Sreekanth Challa

  • Did you use HALCoGen to generate your project? If so, you can change the message ID of a mail box with a call to the function canUpdateID(); The number of bytes in the message is set by the DLC (bits 3:0 of IFxMCTL).  You can look at the canInit() function from HALCoGen as an example on how to set the DLC.

  • Hi Bob Crosby,

    Thanks for prompt response. The information was very helpful. I have the following questions.+

    1. When is the following busy wait is required in code?

    while ((canNode->IF1STAT & 0x80U) ==0x80U)

    {

    } / Wait /

    2. Is it possible to set the CAN ID  and data transmission in the code you specified in your response? (So no need to call canUpdateID() function). The code would look as follows. We would like to do as follows to reduce the execution time.

    while ((canNode->IF1STAT & 0x80U) ==0x80U)

    {

    } / Wait /

    // write canId, canMessageBox and canDlc into register

    canNode->IF1MSK  = 0xC0000000U | (uint32)((uint32)((uint32)0x000007FFU & (uint32)0x000007FFU) << (uint32)18U);

    canNode->IF1ARB  = (uint32)0x80000000U | (uint32)0x00000000U | (uint32)0x20000000U | (uint32)((uint32)((uint32)(canId) & (uint32)0x000007FFU) << (uint32)18U);

    canNode->IF1MCTL = 0x00001080U | (uint32)0x00000000U | (uint32)0x00000000U | (uint32)(canDlc);

    canNode->IF1CMD  = (uint8) 0xFFU;

    uint8_t i;

    for (i = 0U; i < 8U; i++)

    {

    /*SAFETYMCUSW 45 D MR:21.1 <APPROVED> "Valid non NULL input parameters are only allowed in this driver" */

    canNode->IF1DATx[s_canByteOrder[i]] = *canData;

    /*SAFETYMCUSW 567 S MR:17.1,17.4 <APPROVED> "Pointer increment needed" */

    canData++;

    }

    // write messagebox

    canNode->IF1NO   = (canMessageBox+1U); // one based msgbox

    Thanks & Best regards,

    Sreekanth Challa

  • 1. The check to see if the interface registers are busy is needed because a write to an interface register while it is busy will be ignored. Notice in the HALCoGen function canInit() that they alternate between using IF1 registers and IF2 registers as they setup multiple mailboxes. That is done to minimize the time waiting on the can state-machine to finish using the interface registers. As mentioned in the Technical Reference Manual (SPNU517 section 20.3.18) it can take up to 14 VBUS cycles for the CAN state-machine to actually do the write to the CAN mailboxes. It can take even more if for some reason you write to the same mailbox twice using both sets of interface registers. Can the busy check be skipped? Sure, if you know absolutely for sure that the interface registers are not busy. But putting the check before using the registers is a small execution time penalty to pay for avoiding what could be a very difficult run-time issue to debug.
    2. Yes, you can update the canId and the canDlc in the same routine as you propose.
  • Sreekanth,

    Please note that it is not allowed to change all fields in an active transmit message object:

    20.2.7.7 Reconfiguration of Message Objects for the Reception Transmission of Frames
    
    A message object with Dir = 1 AND (Umask = 0 OR RmtEn = 1) is configured for the transmission of data frames.
    
    It is neccessary to reset MsgVal to not valid before changing any of the following configuration and control bits: Dir, RxIE, TxIE, RmtEn, EoB, Umask, Msk[28:0], MXtd, and MDir.
    
    These parts of a message object may be changed without clearing MsgVal: ID[28-0], Xtd, DLC[3:0], Data[7:0], TxRqst, NewDat, MsgLst, and IntPnd.

    Please follow the guides from this section to change a transmit message object:

    20.2.8.5 Changing a Transmit Object
    
    If the number of implemented message objects is not sufficient to be used as permanent message objects
    only, the Transmit Objects may be managed dynamically. The CPU can write the whole message
    (Arbitration, Control, and Data) into the Interface Register. The bits [23:16] of the Command Register can
    be set to 0xB7 for the transfer of the whole message object content into the message object. Before
    changing the configuration of a message object, MsgVal has to be reset (see Section 20.2.7.7).
    
    If a previously requested transmission of this message object is not completed but already in progress, it
    will be continued; however it will not be repeated if it is disturbed.
    
    To only update the data bytes of a message to be transmitted, bits [23:16] of the Command Register should be set to 0x87.

    Best Regards,
    Christian

  • Hi Christian,

    Thanks for your feedback. The problem got solved. 

    Best Regards,

    Sreekanth Challa