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.
Hello, thank you for always answering my questions.
Today, I would like to ask about the data receiving problem of CAN IF3 Interrupt.
The test I do is a test in which the HMI sends 3 frames of data to the CPU, and the CPU analyzes the data upon receiving the data and sends a response signal if the data is correct.
At this time, CPU receives data using CAN IF3.
However, sometimes the CPU could not receive the last frame data. Therefore, please check if the CAN IF3 Interrupt I made is wrong.
And I would like to ask if I need to check Interrupt pending register in CAN IF3 Interrupt.
Below is the CAN IF3 Interrupt code I made.
#pragma CODE_STATE(can1IF3UpdateInterrupt, 32) #pragma INTERRUPT(can1IF3UpdateInterrupt, IRQ) void can1IF3UpdateInterrupt(void) { uint32_t value = (canREG1->IF3OBS & 0x9800) >> 8; // IF3 Update data, IF3 Data A, IF3 Data B bit 확인 = 데이터 수신 확인 uint32_t ID = canREG1->IF3ARB; // IF3 수신 데이터 ID uint32_t ES_value; // error status register if(value == 0x98U) // IF3 데이터 수신 확인 { canIF3Notification(canREG1, ID); // canIF3Notification에서 CAN과 ID로 구분하여 수신 동작 처리 } else // CAN1 IF3 interrupt error { Send_SCI("Check IF3 1\r\n"); ES_value = canREG1->ES; if((ES_value & 0x1E0U) != 0U) { canErrorNotification(canREG1, ES_value & 0x1E0U); } else { canStatusChangeNotification(canREG1, ES_value & 0x618U); } } }
#pragma WEAK(canIF3Notification) void canIF3Notification(canBASE_t *node, uint32 ID) { uint32_t uiId = 0; uiId = ID & 0x1FFFFFFF; if((node == canREG1) && (uiId == CAN_HMI_ID_IN_CPU)) // CAN1 IF3의 ID 4 데이터 수신 from HMI { uint8_t i = 0; for(i = 0; i<8; i++) // 1Frame = 8Byte이므로 1Byte씩 8번 반복 { ucCan1RxBuffer[uiCan1RxIndex] = node->IF3DATx[i]; // IF3 Data A, B 데이터를 RX1 버퍼로 복사 Log_Msg_Save_RX(ucCan1RxBuffer[uiCan1RxIndex]); Frame_Data_Save(ucCan1RxBuffer[uiCan1RxIndex]); uiCan1RxIndex = (uiCan1RxIndex + 1) & CAN_RX_BUFFER_MASK; } #if 1 uint8_t ucMsb1ms; uint8_t ucLsb1ms; ucMsb1ms = (uint8_t)((us1sCounter & 0xFF00)>>8); ucLsb1ms = (uint8_t)(us1sCounter & 0x00FF); Log_Msg_Save_RX(ucMsb1ms); Log_Msg_Save_RX(ucLsb1ms); ucMsb1ms = (uint8_t)((us1msCounter & 0xFF00)>>8); ucLsb1ms = (uint8_t)(us1msCounter & 0x00FF); Log_Msg_Save_RX(ucMsb1ms); Log_Msg_Save_RX(ucLsb1ms); #endif } else { //asm(" nop "); Send_SCI("Check IF3 2\r\n"); } }
Hi,
Is the last frame copied to IF3x registers? or is the last frame copied to message object in message RAM?
It doesn't copy, rather it doesn't respond to the last frame at all.
As a result of observation with an oscilloscope, it was observed that 3 frames were transmitted through CAN communication from HMI.
But on the CPU, can1IF3UpdateInterrupt only responded twice.
I found it by counting how can1IFUpdateInterrupt reacts.
When a transmission failed (lost arbitration or error), the message will not discarded. Can you please check if TxOK is set on your transmitter side? Is any error flag set?
To explain in detail again, the CPU and HMI I mentioned above are the names of each module. I am testing CAN communication between HMI module and CPU module now.
Tests, as mentioned above, transmits 3 frames from HMI module to CPU module, and CPU module analyzes the frame and transmits a response signal when 3 frames are properly received.
However, sometimes the CPU module does not transmit the response signal. As a result of analyzing the cause, CPU module interrupt occurred only 2 times instead of 3 times. To be precise, no interrupt occurred in the CPU Module's can1IF3UdateInterrupt for the last frame.
I thought that the HMI module was not transmitting data, but as a result of checking with an oscilloscope, it was confirmed that all 3 frames were transmitted.
So I want to ask if the can1IF3UpdateInterrupt I made is the problem or if there is something missing in the code. Or, I want to ask why this happens.
the message will not discarded.
It should be "the message will be discarded".
So I want to ask if the can1IF3UpdateInterrupt I made is the problem or if there is something missing in the code.
Your code looks fine.
When the interrupt of 3rd frame is not generated, is there any error flag set?
I did same test using your function (simplified), it works as expected: Message ID is 18. CAN2 received all the data, IF3Upd flag is set every time.
CAN1 module transmits data: 3 frames (3 * 8 = 24 bytes)
for(cnt=0;cnt<D_COUNT/2;cnt++)
{
canTransmit(canREG1, canMESSAGE_BOX1, tx_ptr); //MSG ID=18
while(tx_done == 0){};
tx_done=0;
tx_ptr +=8; /* next chunk ...*/
}
/* USER CODE BEGIN (4) */
#if 1 //this function was written by one customer
uint8_t ucCan2RxBuffer[80];
uint8_t* rx_ptr2 = &ucCan2RxBuffer[0];
static const uint32 s_canByteOrder[8U] = {3U, 2U, 1U, 0U, 7U, 6U, 5U, 4U};
void canIF3Notification(canBASE_t *node, uint32 ID)
{
uint32_t uiId = 0;
uiId = ID & 0x1FFFFFFF;
if((node == canREG2) && (uiId == 18))
{
uint8_t i = 0;
for(i = 0; i<8; i++)
{
*rx_ptr2++ = node->IF3DATx[s_canByteOrder[i]];
}
}
else
{
}
}
#pragma CODE_STATE(can2IF3UpdateInterrupt, 32)
#pragma INTERRUPT(can2IF3UpdateInterrupt, IRQ)
void can2IF3UpdateInterrupt(void)
{
uint32_t value = (canREG2->IF3OBS & 0x9800) >> 8;
uint32_t ID = canREG2->IF3ARB;
if(value == 0x98U)
{
canIF3Notification(canREG2, ID);
}
else
{
}
}
#endif //end of customer's function