CAN module re-transmits frame infinitely when not connected to bus

キャンセル
次の結果を表示 
表示  限定  | 次の代わりに検索 
もしかして: 

CAN module re-transmits frame infinitely when not connected to bus

1,626件の閲覧回数
abdalmoniemalhi
Contributor I

Hello, I'm writing a CAN driver for the S12ZVC using MSCAN, I modified the example code so that it transmits the frame inside the CAN_TX_ISR, it works fine if it is connected to a bus, but if it is not it receives a NACK. and re-transmits the frame again and again until it connects to the bus and receives an ACK.

NB. I've made a workaround using CAN_ERR_ISR to stop the TX ISR if an error occurs, but I'm unable to flush the tx buffer or restart the can module; however it works only if I call CAN_send() once, but when I call it inside the loop, it misbehaves as described.

here is my code:

int main(void) { 
 CAN_init();
 //construct frame
 txBuffer.id = 0x5A;
 txBuffer.data[0] = 0x23;
 txBuffer.data[1] = 0x08;
 txBuffer.data[2] = 0x93;txBuffer.length = 1;
 txBuffer.priority = 0;
 CAN_send(&txBuffer);
 for(;;){}
}

//sends a CAN message
void CAN_send(transmitBuffer *txBuffer) {
 bTxBuffer = txBuffer;
 
 //prepare frame
 CAN0TBSEL = CAN0TFLG; /* select lowest empty buffer */
 bTxBuffer->bufferNumber = CAN0TBSEL;
 
 //enable tx interrupt
 CAN0TFLG_TXE = bTxBuffer->bufferNumber;
 CAN0TIER_TXEIE = bTxBuffer->bufferNumber;
 
 //enable can change status interrupt
 CAN0RIER_CSCIE = 0x01;
 
 //enable interrupts on TxErr or Bus-Off
 CAN0RIER_TSTATE = 0x02;
}

//CAN message transmission interrupt
void interrupt VectorNumber_Vcan0tx CAN_TX_ISR() {
 uint8 index;

 //prepare frame
 CAN0TBSEL = CAN0TFLG; /* select lowest empty buffer */
 bTxBuffer->bufferNumber = CAN0TBSEL;

 //load ID
 CAN0TXIDR0 = (bTxBuffer->id & 0b11111111000) >> 3;
 CAN0TXIDR1 = (bTxBuffer->id & 0b00000000111) << 5;

 //load data for(index = 0; index < bTxBuffer->length; index++) {
 *(&CAN0TXDSR0 + index) = bTxBuffer->data[index];
 }

 //send frame
 CAN0TXDLR = bTxBuffer->length; /* set data length */
 CAN0TXTBPR = bTxBuffer->priority; /* set priority */

 //clear tx interrupt flag
 CAN0TFLG_TXE = bTxBuffer->bufferNumber; /* start transmission */
}

void interrupt VectorNumber_Vcan0err CAN_ERR_ISR() {
 CAN0TARQ = 0x07;
 while (!(CAN0TAAK & 0x07)){}
 
 //clear can change status flag
 CAN0RFLG_CSCIF = 1;
 
 //disable tx interrupt
 CAN0TIER_TXEIE = 0;
 
 //clear tx flag
 //CAN0TFLG = 0x07;
}
ラベル(1)
タグ(3)
0 件の賞賛
返信
3 返答(返信)

1,379件の閲覧回数
lama
NXP TechSupport
NXP TechSupport

Hi,

when Tx node does not receive ACK it goes to an error passive node and tries to send message in a loop.

The solution is ABORT (MSCAN Transmitter Message Abort Request Register (CANTARQ)

Best regards,

Ladislav

0 件の賞賛
返信

951件の閲覧回数
gumu
Contributor IV

Hi @lama ,

I alse have this problem with my project.

How do I know the connecting status of CAN.

Here is the waveform without CAN connecting

gumu_0-1690018499516.png

 

0 件の賞賛
返信

1,379件の閲覧回数
abdalmoniemalhi
Contributor I

Thank you for your answer

I do this in the CAN_ERR_ISR, but what happens is that it aborts the message, triggers a TX interrupt then goes to the CAN_TX_ISR which in turn resends the message again.

is there something I should do ?

0 件の賞賛
返信