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.

CCS/LAUNCHXL-F280049C: Can't read messages from CANbus...

Part Number: LAUNCHXL-F280049C

Tool/software: Code Composer Studio

I'm working with the LaunchPad at the moment. I can't get CAN to read a message, but I can send and the transceiver is acking messages properly.

When the interrupt (Status Change interrupt) runs, the resister CAN_ES shows that RxOK is flagged, but CAN_INT.INTI0D always reads back 0x8000 (Error).   How messages are setup is below.  The IPEN register doesn't change either (all show 0), eventhough the RxIE (or TxIE for transmit boxes) is set on the mailboxes.  

1.  What am I doing wrong, that CAN_INT.INTI0D always comes back with an error, and not the proper mailbox?

2.  For RX messages, does the DLC (length) value matter in the MCTL message, or does setting a 6 mean it will only receive 6 byte long message.  Is there a way to allow all lengths, if that is the case?

NOTE:  On TxOK interrupts, CAN_INT.INTI0D also reads back 0x8000 (error), but the messages are being sent properly and acked properly by the other devices on the bus.

Thanks,

Kyle M

Rx message setup:

for(i = FIRST_MAILBOX_FOR_STANDARD_MESSAGES; i <= LAST_MAILBOX_FOR_STANDARD_MESSAGES; i++)
{
HWREG_BP(CANA_BASE + CAN_O_IF1ARB) = CAN_IF1ARB_MSGVAL | 0x1FFFFFFF; //Setup No mask and message Valid

HWREG_BP(CANA_BASE + CAN_O_IF1MCTL) = 6 | CAN_IF1MCTL_EOB | CAN_IF1MCTL_RXIE;
//Setup the mask:
//CanaRegs.CAN_IF1MSK.all = 0;
HWREG_BP(CANA_BASE + CAN_O_IF1MSK) = 0;

//Tell the buffer to force a copy to the mailbox:
HWREG_BP(CANA_BASE + CAN_O_IF1CMD) = i | CAN_IF1CMD_ARB | CAN_IF1CMD_CONTROL
| CAN_IF1CMD_MASK | CAN_IF1CMD_DIR | CAN_IF1CMD_CLRINTPND;
}

Tx Message setup:

HWREG_BP(CANA_BASE + CAN_O_IF1ARB) = Msg.ui32MsgARB.all | CAN_IF1ARB_DIR;
HWREG_BP(CANA_BASE + CAN_O_IF1MCTL) = (Uint32)Msg.ui16MsgLen | CAN_IF1MCTL_EOB; //|CAN_IF1MCTL_TXRQST
//Setup the mask:
//CanaRegs.CAN_IF1MSK.all = 0;
HWREG_BP(CANA_BASE + CAN_O_IF1MSK) = 0;
//Load the Low Data Bytes:
//CanaRegs.CAN_IF1DATA.all = Msg.Data[0];
HWREG_BP(CANA_BASE + CAN_O_IF1DATA) = Msg.Data[0];
//Load the High Data Bytes:
//CanaRegs.CAN_IF1DATB.all = Msg.Data[1];
HWREG_BP(CANA_BASE + CAN_O_IF1DATB) = Msg.Data[1];

//Tell the buffer to force a copy to the mailbox so the hardware will transmit:

HWREG_BP(CANA_BASE + CAN_O_IF1CMD) = MailBox_Num | CAN_IF1CMD_ARB | CAN_IF1CMD_CONTROL
| CAN_IF1CMD_MASK | CAN_IF1CMD_DIR
| CAN_IF1CMD_DATA_B | CAN_IF1CMD_DATA_A
| CAN_IF1CMD_TXRQST;

  • Kyle,
    From what I understand, transmit happens correctly, but receive does not. In both cases, interrupt does not occur. Correct?

    Do you have a CAN bus analyzer tool that gives you visibility to the traffic on the bus? If so, have you confirmed the traffic on the bus is along the expected lines?

    DLC should have no bearing on the receive mailbox.

    Let me think through this some more.
  • Hareesh,

    An interrupt does occur for both TxOK and RxOK.  Specifically, it's the CAN Status change interrupt because the TxOK and RxOK are flipping.  There doesn't seem to be an interrupt that is specific to Transmit or Receive, or at least that's not the interrupt I can get to trigger it.  Or maybe that's more indicative to the problem. 

    Yes, I have multiple CAN analyzer tools, but for the moment I'm using a logic analyzer on the RX and TX pins of the processor so I know when it's interacting with the bus.  As I said before, CAN traffic is correct and other devices are receiving the messages sent by the F280049 correct and they are responding to it.  Those responses are being ACKed by the 49 (I can see the TX pin go low on the 49 after a complete message from another device) then I can't retrieve them because of the issues I stated earlier (CAN Status interrupt triggers, and shows RxOK, but mailbox data shows error, not a mailbox). 

    In reading through the spec more, it seems the CAN works differently when the debugger is attached (the spec sheet says it remaps the CAN mailboxes to a different memory space).  Thus the normal commands to shuffle data between the two usable buffers and the 32 mailboxes don't work.  Is this true?  Could this be my problem?  Is there anyway to disable this?  This is going to cause numerous problems during design if CAN can't work if there is a debugger attached.

  • Debug mode provides visibility to the message RAM. (Normally, code accesses message RAM only through the IF registers). However, code using the IF registers should work normally with the debug probe connected.
  • So, I started with a new project built on TI's CAN loopback example.

    I've narrowed it down to what's happening.

    On receive:

    1. An interrupt will trigger.  This first one will just be an interrupt with no mailbox (CAN_INT.INT01D = 0x8000), and RxOK will be set in CAN_ES

    2.  If the message fits the acceptance filtering then a second interrupt will be triggered that has the correct mailbox and RxOK as well.  If the message doesn't match, this 2nd interrupt will not be triggered.  

    So the problem I really have, is that I can't get the acceptance filtering turned off.  I have UMask set to 0 in MCTL, I set MSK to zero to ignore the mask for all bytes... ARB, CTRL, and MSK are set when I write to the CMD...  Nothing seems to stop this filter.  I need to accept everything.

    What am I doing wrong?

  • RxOK gets set only when a message is received into a mailbox, so it is strange that you see it set, but there is no data in the mailbox.

    Which mailbox are you using for reception?

    Do you transmit the same MSGID multiple times? I am referring to #2 where you say “If the message fits the acceptance filtering then a second interrupt will be triggered that has the correct mailbox and RxOK as well.” So, is the MSGID the same for the first message (where the mailbox # was NOT correctly reflected in INT0ID register) and the second message (where the mailbox # IS correctly reflected in INT0ID register).

    Is the behavior any different if the MSGID is an exact match between the receive mailbox and the received frame?

    How do you check the mailbox data? Are you reading the mailbox RAM through the IF registers into a variable or are you visually examining the MBX RAM via the debugger?

  • RxOK gets set only when a message is received into a mailbox, so it is strange that you see it set, but there is no data in the mailbox.

    Technically it seems to be the CAN Status change (CAN_ES) interrupt is triggered when a message comes in that doesn't match the MsgID in the ARB portion of the mailbox.  No mailbox is shown in IN10D, so I have no idea if there is any data in any mailbox.

    Which mailbox are you using for reception?

    For this specific test I am using only box 2 (same as TI's examples)

    Do you transmit the same MSGID multiple times? I am referring to #2 where you say “If the message fits the acceptance filtering then a second interrupt will be triggered that has the correct mailbox and RxOK as well.” So, is the MSGID the same for the first message (where the mailbox # was NOT correctly reflected in INT0ID register) and the second message (where the mailbox # IS correctly reflected in INT0ID register).

    No,  A single message is sent.  Two interrupts happen (CAN_ES changed, where the mailbox doesn't show up, then the actual interrupt for the specific mailbox).  If I turn off the CAN status change interrupt, it just triggers once and it's the one for the mailbox only.

    Note:  It does this double interrupt for Tx as well if the CAN status change interrupt is enabled.

    Is the behavior any different if the MSGID is an exact match between the receive mailbox and the received frame?

    I'm not sure what you mean.  I can only receive a message if the MSGID and the PID of the actual message are identical.  It's like the acceptance filter can not be turned off.

    Can you give me a mailbox setup that accepts all messages (no acceptance filter), that you have tested?  Or I can send my code and you can run it on a launchpad (that's what I'm using to test).

    How do you check the mailbox data? Are you reading the mailbox RAM through the IF registers into a variable or are you visually examining the MBX RAM via the debugger?

    I'm getting the data through the buffer.  I've looked at the RAM via the debugger, but since it isn't broken out into the proper unions and such nor specified in the CMD file, the data is pretty hard to read, but from what I think I can read, when the PID doesn't match what's in the ARB register, the message data doesn't seem to make to the mailbox.  If you have those message defined somewhere in code, I'd be happy to paste it in my code and give you more information.

  • Hareesh,
    OK...
    I got it to accept all messages after some experimentation.

    1. Set all Mask Bits to zero (ignore) (I was doing this before as well).
    2. Set UMask bit in MCTL. This disagrees with the technical datasheet as zero should allow all messages, if I'm reading it correctly.
    3. The values in ARB don't really matter at this point except MSGVAL needs to be set.

    For people looking to have accept all messages use this for the setup:
    //Setup the mask:
    //Accept all (ignore all id Mask bits):HWREG_BP(CANA_BASE + CAN_O_IF1MSK) = 0;
    //Setup ARB... Really the only thing that matters here is that MSGVAL is set
    HWREG_BP(CANA_BASE + CAN_O_IF1ARB) = CAN_IF1ARB_MSGVAL | ((Uint32)0x000 << CAN_IF1ARB_STD_ID_S);
    //For Ext Messages:
    //HWREG_BP(CANA_BASE + CAN_O_IF1ARB) = CAN_IF1ARB_MSGVAL | CAN_IF1ARB_XTD | 0x0;

    //Single message, Interrupt on RX, Use the mask (disagrees with datasheet)
    HWREG_BP(CANA_BASE + CAN_O_IF1MCTL) = 8 | CAN_IF1MCTL_EOB | CAN_IF1MCTL_RXIE | CAN_IF1MCTL_UMASK;

    //Tell the buffer to force a copy to the mailbox:
    HWREG_BP(CANA_BASE + CAN_O_IF1CMD) = BoxNum | CAN_IF1CMD_ARB | CAN_IF1CMD_CONTROL
    | CAN_IF1CMD_MASK | CAN_IF1CMD_DIR | CAN_IF1CMD_CLRINTPND;

    Thanks,
    Kyle