Hi, I'm writting code for the above chip. I can receive messages into my application using the CAN simulator no problem. However, when I launch a message from my application, it is continuously re-transmitted (as seen on the can bus simulator). The TXOK flag is set OK and I get into my interrupt but, the only way I have been able to stop re-transmissions is by setting the CANCONCH register for the page to 0 and disabling the page. What am I doing wrong, should the simulator mimic a reply ACK to prevent multiple re-transmissions or is it my responsibility to disable further transmissions? Any clues? Regards Rob McKinley
You did not indicate is it data or remote frame we discuss about. Well, after a message object with data frame has been transmitted without errors then corresponding bit ENCHx of CANEN1/2 is cleared and CAN macro will not use this channel any more. Only one way to transmit it again is re-write CANCONCH of a message object. The strange thing I see is that TXOK bit has been set => so message object has been transmitted w/o errors. There are some possible reasons: - you re-enable transmission somewhere in your program yourself (check code again); - you do not clear TXOK flag before start transmission (you must do it each time to avoid dead loop on interrupt); - it is a bug in debugger/simulator. Please report result of your fix problem coz it is very interest problem for me (via private mail if so). Finally, as temporal workaroud: use TTC mode oc CAN macro - it will send a frame only one time even errors occur. Good days!
Agree with Oleg, also study aplication note 165 from Keil (a little hard to understand, but verry good) Example:
char CanSendIsr (unsigned char ch, unsigned char *p) { unsigned char i, typ; // check if CAN message object is defined for transmit if (ch >= sizeof (id_typ)) return (-1); typ = id_typ[ch]; if ((typ & CanCONCH) != CanTX) return (-1); i = typ & 0xF; // message length ECAN = 0; // disable CAN interupt CANPAGE = CanChannel(ch); // select CAN message object if ((CANCONCH & CanCONCH)) { // CAN channel busy? // yes copy to interrupt buffer memcpy (outbuf[ostart & (OLEN-1)], p, sizeof(outbuf[0])); ostart++; } else { // not, transfer to message object CANCONCH = 0; // reset previous status CANSTCH = 0; while (i) { // copy information to message buffer CANMSG = *p++; i--; } CANCONCH = typ; // send information } ECAN = 1; // enable CAN interupt return (0); }
Hi, TTC (time-triggered communication) mode has been announced via ISO11898 standard. In this mode any node sends message(s) inside own time slot. In short, nodes listen for a sync message. When it has been detected, each node sets own delay (by your program - timer, cycle, etc) and after this pause sends a frame to the net. So by this method you may create a very stable net which will work even if alot of messages are transmitted there because the bus arbitration method will not block nodes with low priority identifiers (see: each node has own time slot). As side effect, if any error occurs then node cannot resend message itself because its time-slot has been gone. Instead it, software should wait till next sync message and resend a frame again inside own time-slot. Thanks for Temic/Atmel, the T89C51CC01 does support this method (TTC bit in CANGCON register). Manual says that CAN macro in TTC mode will send a frame only one time even errors occur. Hmm, my tests show that if no ACK bit detected then CAN macro try to send a frame again till TEC<127 even in TTC mode. Now I am clearing up this question with Atmel. Good days!
View all questions in Keil forum