Hi,
I am having some issues using a transmit mailbox to write to CAN. I followed the instructions on the technical guide for my microcontroller (TMS320F28069) on "how to configure a mailbox for transmit" and "how to transmit a message".
My main issue is that when I set the transmit request register (TRS.0) for the mailbox, I am stuck waiting for the the transmit acknowledge register to be set (TA.0).
As a result, when i halt the code and check the eCAN registers, CANAA for mailbox 0 is set. What can be the cause of this?
Here is my code:
void main() { InitSysCtrl(); // Defined in F2806x_SysCtrl.c // Initialize CAN GPIO pins canA_gpio_init(); EDIS; // Disable CPU interrupts DINT; EALLOW; InitPieCtrl(); // Defined in F2806x_PieCtrl.c EDIS; // Disable CPU interrupts and clear all interrupt flags IER = 0x0000; IFR = 0x0000; EALLOW; InitECana(); EDIS; EALLOW; InitPieVectTable(); // Defined in F2806x_PieVect.c EDIS; //canA_init(19); // TEST /* mailbox interrupt mask */ /* 1 = interrupt enabled */ ECanaRegs.CANMIM.all = 0xFFFFFFFF; /* mailbox interrupt level */ /* mailbox inerrupt is generated on interrupt line 1. */ ECanaRegs.CANMIL.all = 0xFFFFFFFF; /* Global Interrupt Mask Register */ ECanaShadow.CANGIM.all = ECanaRegs.CANGIM.all; ECanaShadow.CANGIM.all = 0; ECanaShadow.CANGIM.bit.AAIM = 1; /* Abort acknowledge */ ECanaShadow.CANGIM.bit.WDIM = 1; /* Write denied */ ECanaShadow.CANGIM.bit.WUIM = 1; /* Wake up */ ECanaShadow.CANGIM.bit.BOIM = 1; /* Bus-off */ ECanaShadow.CANGIM.bit.EPIM = 1; /* Error-passive */ ECanaShadow.CANGIM.bit.WLIM = 1; /* Warning level */ ECanaShadow.CANGIM.bit.I1EN = 1; /* Interrupt 1 enable */ ECanaShadow.CANGIM.bit.GIL = 1; /* Global Interrup Level. */ // ECanaShadow.CANGIM.bit.I0EN = 1; /* Interrupt 0 enable */ // ECanaShadow.CANGIM.bit.GIL = 0; /* Global Interrup Level. */ ECanaShadow.CANGIM.bit.RMLIM = 1; /* Received Message Lost */ ECanaRegs.CANGIM.all = ECanaShadow.CANGIM.all; EDIS; for(;;) { EALLOW; writeCan(); EDIS; } } void writeCan() { /* To transmit a message, the following steps need to be performed (in this example, for mailbox 1): 1. Clear the appropriate bit in the CANTRS register to 0: Clear CANTRS.1 = 0 (Writing a 0 to TRS has no effect; instead, set TRR.1 and wait until TRS.1 clears.) If the RTR bit is set, the TRS bit can send a remote frame. Once the remote frame is sent, the TRS bit of the mailbox is cleared by the CAN module. The same node can be used to request a data frame from another node. */ EALLOW; ECanaShadow.CANTRS.all = ECanaRegs.CANTRS.all; ECanaShadow.CANTRR.all = ECanaRegs.CANTRR.all; ECanaShadow.CANTRR.bit.TRR0 = 1; while (ECanaShadow.CANTRS.bit.TRS0 != 0) {}; ECanaRegs.CANTRR.all = ECanaShadow.CANTRR.all; ECanaRegs.CANTRS.all = ECanaShadow.CANTRS.all; /* 2. Disable the mailbox by clearing the corresponding bit in the mailbox enable (CANME) register. Clear CANME.filter1 = 0 */ ECanaShadow.CANME.all = ECanaRegs.CANME.all; ECanaShadow.CANME.bit.ME0 = 0; ECanaRegs.CANME.all = ECanaShadow.CANME.all; /* 3. Load the message identifier (MSGID) register of the mailbox. Clear the AME (MSGID.30) and AAM (MSGID.29) bits for a normal send mailbox (MSGID.30 = 0 and MSGID.29 = 0). This register is usually not modified during operation. It can only be modified when the mailbox is disabled. For example: (a) Write MSGID(1) = 0x15AC0000 (b) Write the data length into the DLC field of the message control field register (MSGCTRL.3:0). The RTR flag is usually cleared (MSGCTRL.4 = 0). (c) Set the mailbox direction by clearing the corresponding bit in the CANMD register. (d) Clear CANMD.1 = 0 */ /* Mailbox 0 */ // ID: 0x5A584B // AAM: 0 // AME: 0 // IDE: 1 ECanaMboxes.MBOX0.MSGID.all = 0x805A584B; // Specify that 8 bits will be sent/received ECanaMboxes.MBOX0.MSGCTRL.bit.DLC = 8; ECanaShadow.CANMD.all = ECanaRegs.CANMD.all; ECanaShadow.CANMD.bit.MD0 = 0; ECanaRegs.CANMD.all = ECanaShadow.CANMD.all; /* 4. Set the mailbox enable by setting the corresponding bit in the CANME register Set CANME.1 = 1 This configures mailbox 1 for transmit mode. 16.11.2 Transmitting a Message */ ECanaShadow.CANME.all = ECanaRegs.CANME.all; ECanaShadow.CANME.bit.ME0 = 1; ECanaRegs.CANME.all = ECanaShadow.CANME.all; /* To start a transmission (in this example, for mailbox: 1. Write the message data into the mailbox data field. (a) Since DBO (MC.10) is set to zero in the configuration section and MSGCTRL(1) is set to 2, the data are stored in the 2 MSBytes of CANMDL(1). (b) Write CANMDL(1) = xxxx0000h */ EALLOW; ECanaShadow.CANMC.all = ECanaRegs.CANMC.all; ECanaShadow.CANMC.bit.DBO = 0; // 1 = self-test mode ECanaShadow.CANMC.bit.STM = 0; // 1 = FREE mode (peripheral continues to run normally in SUSPEND) ECanaShadow.CANMC.bit.SUSP = 1; ECanaRegs.CANMC.all = ECanaShadow.CANMC.all; EDIS; // Write to the mailbox RAM field of MBOX0 ECanaMboxes.MBOX0.MDL.all = 0x9555AAA0; ECanaMboxes.MBOX0.MDH.all = 0x89ABCDEF; /* 2. Set the corresponding flag in the transmit request register (CANTRS.1 = 1) to start the transmission of the message. The CAN module now handles the complete transmission of the CAN message. */ ECanaShadow.CANTRS.all = ECanaRegs.CANTRS.all; ECanaShadow.CANTRS.bit.TRS0 = 1; ECanaRegs.CANTRS.all = ECanaShadow.CANTRS.all; /* 3. Wait until the transmit-acknowledge flag of the corresponding mailbox is set (TA.1 = 1). After a successful transmission, this flag is set by the CAN module. */ ECanaShadow.CANTA.all = ECanaRegs.CANTA.all; while (ECanaShadow.CANTA.bit.TA0 != 1) {}; // THIS IS WHERE THE CODE GETS STUCK ECanaRegs.CANTA.all = ECanaShadow.CANTA.all; /* 4. The TRS flag is reset to 0 by the module after a successful or aborted transmission (TRS.1 = 0). */ ECanaShadow.CANTRS.all = ECanaRegs.CANTRS.all; while (ECanaShadow.CANTRS.bit.TRS0 != 0) {}; ECanaRegs.CANTRS.all = ECanaShadow.CANTRS.all; /* 5. The transmit acknowledge must be cleared for the next transmission (from the same mailbox). (a) Set TA.1 = 1 (b) Wait until read TA.1 is 0 */ ECanaShadow.CANTA.all = ECanaRegs.CANTA.all; ECanaShadow.CANTA.bit.TA0 = 1; while (ECanaShadow.CANTA.bit.TA0 != 0) {}; ECanaRegs.CANTA.all = ECanaShadow.CANTA.all; /* 6. To transmit another message in the same mailbox, the mailbox RAM data must be updated. Setting the TRS.1 flag starts the next transmission. Writing to the mailbox RAM can be half-word (16 bits) or full word (32 bits) but the module always returns 32-bit from even boundary. The CPU must accept all the 32 bits or part of it. */ MessageReceivedCount++; EDIS; }