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.

TMS320F28069M: eCAN module suddenly resets after some error frames

Part Number: TMS320F28069M
Other Parts Discussed in Thread: MOTORWARE

I've got a CAN network of 7 controllers which are communicating at 500Kbit/s baud rate successfully. The problem is when sometimes one or some of the controllers give up on communication until restarted. I'm observing the following behaviour - I start the power supply and all the controllers begin sending heartbeat packages at 2Hz rate. If I connect the JTAG to one of the controllers and if I catch it behaving strangely it goes like this: After a while on the CANES register I start to see some FE, SE and BE which I acknowledge by writing 1 to them via the Code composer studio debugger. After some more time I can see the EW and EP registers both got 1 and the CCE bit set to 1. The controller continues to work, but the CAN module stops sending or receiving anything. CANES looks like this - CCE = 1, EW = 1, EP = 1, everything else is 0. CCE = 1 is the default state after reset, so I'm wondering what is going on with the controllers.

Usually I can see them communicating more than 48 hours straight, but sometimes, usually when the PSU has been off for some time the CANbus nodes behaves strangely. After a couple of quick restarts of the PSU the nodes start communicating reliably. Only sometimes one of them gives up on communication.

Some thoughts: Maybe it is not OK to set some bits through the code composer studio directly in the ECanaRegs register and this is why I might get the CCE bit set unexpectedly, but when JTAG is disconnected I can observe the same behaviour.

The design is a copy of the respective Launchpad and I'm using the same CAN transceiver.

Here is my initialisation code if it matters:

void InitECana(void)        // Initialize eCAN-A module
{

/* Create a shadow register structure for the CAN control registers. This is
 needed, since only 32-bit access is allowed to these registers. 16-bit access
 to these registers could potentially corrupt the register contents or return
 false data. */

struct ECAN_REGS ECanaShadow;

    EALLOW;     // EALLOW enables access to protected bits

/* Configure eCAN RX and TX pins for CAN operation using eCAN regs*/

    ECanaShadow.CANTIOC.all = ECanaRegs.CANTIOC.all;
    ECanaShadow.CANTIOC.bit.TXFUNC = 1;
    ECanaRegs.CANTIOC.all = ECanaShadow.CANTIOC.all;

    ECanaShadow.CANRIOC.all = ECanaRegs.CANRIOC.all;
    ECanaShadow.CANRIOC.bit.RXFUNC = 1;
    ECanaRegs.CANRIOC.all = ECanaShadow.CANRIOC.all;

    /* Configure bit timing parameters for eCANA*/

    ECanaShadow.CANMC.all = ECanaRegs.CANMC.all;
    ECanaShadow.CANMC.bit.CCR = 1 ;            // Set CCR = 1
    ECanaRegs.CANMC.all = ECanaShadow.CANMC.all;

    // Wait until the CPU has been granted permission to change the configuration registers
    do
    {
      ECanaShadow.CANES.all = ECanaRegs.CANES.all;
    } while(ECanaShadow.CANES.bit.CCE != 1 );       // Wait for CCE bit to be set..

    ECanaShadow.CANBTC.all = 0;

    //500Kbit
    ECanaShadow.CANBTC.bit.BRPREG = 9;
    ECanaShadow.CANBTC.bit.TSEG1REG = 14;
    ECanaShadow.CANBTC.bit.TSEG2REG = 1;

    // 125Kbit
    //ECanaShadow.CANBTC.bit.BRPREG = 39;
    //ECanaShadow.CANBTC.bit.TSEG1REG = 14;
    //ECanaShadow.CANBTC.bit.TSEG2REG = 1;
    //ECanaShadow.CANBTC.bit.SAM = 1;

    ECanaRegs.CANBTC.all = ECanaShadow.CANBTC.all;

    ECanaShadow.CANMC.all = ECanaRegs.CANMC.all;
    // Clear some bits first
    ECanaShadow.CANMC.bit.CCR   = 0;
    ECanaShadow.CANMC.bit.PDR   = 0;
    ECanaShadow.CANMC.bit.DBO   = 0;
    ECanaShadow.CANMC.bit.WUBA  = 0;
    ECanaShadow.CANMC.bit.CDR   = 0;
    ECanaShadow.CANMC.bit.ABO   = 0;
    ECanaShadow.CANMC.bit.STM   = 0;
    ECanaShadow.CANMC.bit.SRES  = 0;
    ECanaShadow.CANMC.bit.MBNR  = 0;
    // self-test mode
    //ECanaShadow.CANMC.bit.STM = 1;
    // Enable HECC mode
    ECanaShadow.CANMC.bit.SCB   = 1;
    ECanaRegs.CANMC.all = ECanaShadow.CANMC.all;

/* Initialize all bits of 'Message Control Register' 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

    ECanaMboxes.MBOX0.MSGCTRL.all = 0x00000000;
    ECanaMboxes.MBOX1.MSGCTRL.all = 0x00000000;
    ECanaMboxes.MBOX2.MSGCTRL.all = 0x00000000;
    ECanaMboxes.MBOX3.MSGCTRL.all = 0x00000000;
    ECanaMboxes.MBOX4.MSGCTRL.all = 0x00000000;
    ECanaMboxes.MBOX5.MSGCTRL.all = 0x00000000;
    ECanaMboxes.MBOX6.MSGCTRL.all = 0x00000000;
    ECanaMboxes.MBOX7.MSGCTRL.all = 0x00000000;
    ECanaMboxes.MBOX8.MSGCTRL.all = 0x00000000;
    ECanaMboxes.MBOX9.MSGCTRL.all = 0x00000000;
    ECanaMboxes.MBOX10.MSGCTRL.all = 0x00000000;
    ECanaMboxes.MBOX11.MSGCTRL.all = 0x00000000;
    ECanaMboxes.MBOX12.MSGCTRL.all = 0x00000000;
    ECanaMboxes.MBOX13.MSGCTRL.all = 0x00000000;
    ECanaMboxes.MBOX14.MSGCTRL.all = 0x00000000;
    ECanaMboxes.MBOX15.MSGCTRL.all = 0x00000000;
    ECanaMboxes.MBOX16.MSGCTRL.all = 0x00000000;
    ECanaMboxes.MBOX17.MSGCTRL.all = 0x00000000;
    ECanaMboxes.MBOX18.MSGCTRL.all = 0x00000000;
    ECanaMboxes.MBOX19.MSGCTRL.all = 0x00000000;
    ECanaMboxes.MBOX20.MSGCTRL.all = 0x00000000;
    ECanaMboxes.MBOX21.MSGCTRL.all = 0x00000000;
    ECanaMboxes.MBOX22.MSGCTRL.all = 0x00000000;
    ECanaMboxes.MBOX23.MSGCTRL.all = 0x00000000;
    ECanaMboxes.MBOX24.MSGCTRL.all = 0x00000000;
    ECanaMboxes.MBOX25.MSGCTRL.all = 0x00000000;
    ECanaMboxes.MBOX26.MSGCTRL.all = 0x00000000;
    ECanaMboxes.MBOX27.MSGCTRL.all = 0x00000000;
    ECanaMboxes.MBOX28.MSGCTRL.all = 0x00000000;
    ECanaMboxes.MBOX29.MSGCTRL.all = 0x00000000;
    ECanaMboxes.MBOX30.MSGCTRL.all = 0x00000000;
    ECanaMboxes.MBOX31.MSGCTRL.all = 0x00000000;

    // Wait until the CPU no longer has permission to change the configuration registers
    do
    {
      ECanaShadow.CANES.all = ECanaRegs.CANES.all;
    } while(ECanaShadow.CANES.bit.CCE != 0 );       // Wait for CCE bit to be  cleared..

// TAn, RMPn, GIFn bits are all zero upon reset and are cleared again
//  as a matter of precaution.

    ECanaRegs.CANTA.all = 0xFFFFFFFF;   /* Clear all TAn bits */

    ECanaRegs.CANRMP.all = 0xFFFFFFFF;  /* Clear all RMPn bits */

    ECanaRegs.CANGIF0.all = 0xFFFFFFFF; /* Clear all interrupt flag bits */
    ECanaRegs.CANGIF1.all = 0xFFFFFFFF;

/* Disable all Mailboxes  */
    ECanaRegs.CANME.all = 0;        // Required before writing the MSGIDs

    EDIS;
}

I'm not using any interrupts. This is working in combination with Motorware and InstaspinMotion. The can mailboxes are read in the mainISR at the frequency of the mainloop - in my case - 15Khz. And I transmit at 3Hz rate.

This is how I transmit messages:

ECanaShadow.CANTA.all = ECanaRegs.CANTA.all;

      // Wait for all TAn bits to be set..
      if (msgPending && msgAck == false && ECanaShadow.CANTA.bit.TA1 == 1) {
          ECanaShadow.CANTA.bit.TA1 = 1;
            msgAck = true;
        }

        if (msgPending && msgAck && ECanaShadow.CANTA.bit.TA1 == 0) {
            msgPending = false;
            //msgAck = true;
        }

        ECanaRegs.CANTA.all = ECanaShadow.CANTA.all;

        if (msgPending == false) {
            ECanaMboxes.MBOX1.MDL.all = values.i_value;
            ECanaMboxes.MBOX1.MDH.all = USER_ID;

            // Set transmission flag
            ECanaShadow.CANTRS.all = ECanaRegs.CANTRS.all;
            ECanaShadow.CANTRS.bit.TRS1 = 1;
            ECanaRegs.CANTRS.all = ECanaShadow.CANTRS.all;

            msgPending = true;
            msgAck = false;
            MessageSentCount++;
        }

  • I'm using the internal oscillator as on the launchpad board. Could this be a potential problem and can I compensate it/test it without redesigning the board?
  • We need to understand why this is happening in the first place: “problem is when sometimes one or some of the controllers give up on communication until restarted”. In a properly configured network, error frames should not occur. A disturbance to the bus is understandable when a node is powered up or powered down. It is also to be expected due to noise on the circuit board or noise coupled on the bus due to external events. Otherwise, the communication should be uneventful. Please look into whether the sampling point must be adjusted. There are excellent resources online that deal with this topic.

    True, CCE is set upon a reset or when you set CCR in order to configure CANBTC. CCE will also be set when CCR is set due to a bus-off condition. It is conceivable the node is going bus-off.

    Yes, you could (should) try internal compensation. SPRABI7A discusses this in detail. SPRA876 points to other good material from TI in the References section.
  • Also, do you have a CAN bus analyzer with which you can monitor error frames on the bus? That could clue you in on when error frames occur (say switching on a high inductive load nearby).