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.
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++; }