Other Parts Discussed in Thread: CONTROLSUITE
I am writing a can protocol and I'm wondering if i had to check CANTA bit of transmitted mailbox. I checked eCAN reference guide for 320f2833x and there are several points to transmit mailbox:
To start a transmission :
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
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.
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.
4. The TRS flag is reset to 0 by the module after a successful or aborted transmission (TRS.1 = 0).
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
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.
I had write code without waiting for CANTA and it works fine. When I wait for CANTA with while loop it stack when there was CAN error and there can not be successful transmission, CANTA was never set to 1. I had to write additional timeout to ensure proper code execution. I had read about CANTRS flag that it is 0 when transmission is successful or aborted and I write some code that works:
extern struct ECAN_REGS ECanShadow;
Uint16 SendMboxNum(Uint16 MboxNum, Uint32 id, Uint32 mdl, Uint32 mdh, Uint32 ctrl, Uint16 dlc)
{
Uint32 shiftRes = 0U;
Uint16 ret = 0U;
Uint16 timeout = 2000U;
shiftRes = (0x00000001U) << MboxNum;
if ((ECanaRegs.CANTRS.all & shiftRes) == 0U) {
ECanShadow.CANTA.all = 0U;
ECanShadow.CANTA.all |= shiftRes; /* Clear TA bit */
ECanaRegs.CANTA.all = ECanShadow.CANTA.all;
ECanShadow.CANME.all = ECanaRegs.CANME.all;
ECanShadow.CANME.all &= ~shiftRes; /* Disable Mailbox */
ECanaRegs.CANME.all = ECanShadow.CANME.all;
ECanaMboxes.MSGBOX[MboxNum].MSGID.all = id;
ECanaMboxes.MSGBOX[MboxNum].MDL.all = mdl;
ECanaMboxes.MSGBOX[MboxNum].MDH.all = mdh;
ECanaMboxes.MSGBOX[MboxNum].MSGCTRL.all = ctrl;
ECanaMboxes.MSGBOX[MboxNum].MSGCTRL.bit.DLC = dlc;
ECanaMboxes.MSGBOX[MboxNum].MSGCTRL.bit.RTR = 0U; /*RTR = 0 */
ECanShadow.CANME.all = ECanaRegs.CANME.all;
ECanShadow.CANME.all |= shiftRes; /* Enable Mailbox */
ECanaRegs.CANME.all = ECanShadow.CANME.all;
do {
ECanShadow.CANTA.all = ECanaRegs.CANTA.all;
if(--timeout>0U) {break;}
} while(ECanShadow.CANTA.all & shiftRes);
ECanShadow.CANTRS.all = 0U;
ECanShadow.CANTRS.all |= shiftRes; /* Send mailbox */
ECanaRegs.CANTRS.all = ECanShadow.CANTRS.all;
ret=1U;
}
return ret;
}
This program waits for CANTA but it is waiting for clearing bit not to successful transmit. In practice I don't have to check CANTA because it is always cleared before "do while" loop execution.
Is it necessary to meet point 3 of mailbox transmission or am I missing something?