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.

TMS320F280025C: Send and receive CAN messages

Part Number: TMS320F280025C
Other Parts Discussed in Thread: C2000WARE

Hi,

Need direction for sending and receiving CAN messages.

1. I want send CAN messages with arbitrary CANID and DATA

2. I want to receive CAN messages with  arbitrary CANID and DATA

Full duplex TX and RX.

 

How should I setup can controller?

What should be objID, msgIDMask in CAN_setupMessageObject on both situations.

Thanks

Rasty

  • Rasty, 

    Kindly download the latest C2000ware package from https://www.ti.com/tool/C2000WARE to access examples, drivers and related files for C2000 devices.

    Within this package, go to "C2000Ware_X_XX_00_00\driverlib\f28002x\examples\can". Specifically, look at the example "can_ex5_transmit_receive" where code for transmitting and receiving CAN messages has been given.

    In case of further questions, please let us know.

    Thanks.

  • Hi

    In suggested example setup of RX is with known in advance id 0x15555555. This does not help if I do not know ID in advance.

    CAN_setupMessageObject(CANA_BASE, RX_MSG_OBJ_ID, 0x15555555,
    CAN_MSG_FRAME_EXT, CAN_MSG_OBJ_TYPE_RX, 0,
    CAN_MSG_OBJ_RX_INT_ENABLE, MSG_DATA_LENGTH);

    In real life I can get a message with Any ID.

    How do I setup CAN RX to get message with Any Id?

    Thanks

    Rasty

  • Rasty,

    In real life I can get a message with Any ID.

    You are right about that, which is why it there is a feature of acceptance filtering. 

    In order to set up the message object to accept messages with any ID, the function call will look like this:

    CAN_setupMessageObject(CANA_BASE, RX_MSG_OBJ_ID, 0x15555555,
    CAN_MSG_FRAME_EXT, CAN_MSG_OBJ_TYPE_RX, 0,
    CAN_MSG_OBJ_RX_INT_ENABLE | CAN_MSG_OBJ_USE_ID_FILTER, MSG_DATA_LENGTH);

    Setting the flag "CAN_MSG_OBJ_USE_ID_FILTER" will allow to use filtering to parse message IDs and the previous parameter in the function will allow for bit masking to accept specific msgIDs. Take a look at the device TRM for more information on acceptance filtering, especially CAN_IF1MSK Register. 

    Kindly refer to example "can_ex8_mask" for demonstration on how to utilise acceptance filtering.

    Thanks.

  • 1. I want send CAN messages with arbitrary CANID and DATA

    You need to initialize the message object with the ID and data every time.

    2. I want to receive CAN messages with  arbitrary CANID and DATA

    You need to setup the acceptance mask in such a way that any ID is received. Please refer to the Mask example in C2000ware (C:\ti\c2000\C2000Ware_4_00_00_00\driverlib\f28002x\examples\can\can_ex8_mask.c). I have explained the operation of this example in my Application Report (www.ti.com/lit/SPRACE5). 

    Full duplex TX and RX.

    Not sure what you mean by this. By the nature of the protocol, CAN is half-duplex. At any given point in time, a node can either transmit or receive but not do both.

  • Hi,

    I tried this as well.

    This example uses polling instead of interrupts.

    If I use mask like in this example, interrupts start to behave differently.

    Namely , I get interrupt, but CAN_getInterruptCause  (CAN_INT Register (Offset = 10h)) changes its behavior. 

    Instead of returning "Number of message object which caused the interrupt", which should be number 1 to 32 I get 0x8000.

    Is it expected? What I do wrong?

    Best regards

    Rasty

  • Rasty,

    The function CAN_getInterruptCause essentially reads the register CAN_INT. If you refer to the device TRM (refer to attached snippet) it is given that getting the value 0x8000 implies that there is an error in the CAN operation. So kindly check your work. You can refer to example "can_ex2_loopback_interrupts" to understand how to operate interrupts. 

    Thanks.

  • Hi,

    can_ex2_loopback_interrupts uses specific message ID. Which is not real-life use case.

    CAN_setupMessageObject(CANA_BASE, RX_MSG_OBJ_ID, 0x1, CAN_MSG_FRAME_STD,
    CAN_MSG_OBJ_TYPE_RX, 0, CAN_MSG_OBJ_RX_INT_ENABLE,
    MSG_DATA_LENGTH);

     Any attempt to modify example and use CAN_MSG_OBJ_USE_ID_FILTER  leads to change in behavior of CAN_INT.

    Namely, instead of object number (1 or 2) I get Error indication in CAN_INT.

    The weird thing that I still can read CAN RX data  and obtain valid frame, despite 0x8000 read from CAN_INT . Can I trust in this behavior?

    I need explanation how to properly use CAN_MSG_OBJ_USE_ID_FILTER  and CAN_INT together.

    Need example/explanation of using CAN_MSG_OBJ_USE_ID_FILTER  together with RX interrupt.

    Thanks

    Rasty

  • Rasty,

           Did you try:

    CAN_setupMessageObject(CANA_BASE, RX_MSG_OBJ_ID, 0x1, CAN_MSG_FRAME_STD,

    CAN_MSG_OBJ_TYPE_RX, 0, (CAN_MSG_OBJ_USE_ID_FILTER | CAN_MSG_OBJ_RX_INT_ENABLE),

    MSG_DATA_LENGTH);

  • Hi

    It looks that for every RX and TX interrupt I get additional interrupt with 

    0x8000U in CAN_O_INT           0x10U    // Interrupt Register

    When this happens, I see 

    8 in CAN_O_ES            0x4U     // Error and Status Register

    Why I get additional interrupt for each TX and RX events? Is it normal?

    Thanks

    Rasty

  • Randy,

         ISR will be executed twice for every frame, first time for status change and second time for the message object interrupt. 

  • Hi

    Is it possible to get rid of unnecessary interrupts?

    Thanks

    Rasty

  • You can disable the status interrupt (bit 2 of CAN_CTL register).