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.

RM48L952: Data receiving problem in CAN IF3 Interrupt

Part Number: RM48L952

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.

Fullscreen
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#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
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

Fullscreen
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#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;
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

  • 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?

  • The DCAN ES Register value maintains 0x00000007. Therefore, Error and Status shows that there is no problem.
    However, in the test, the last frame is not received because the reception interrupt (can1IF3UpdateInterrupt) for the last frame does not occur.

  • Is the IF3Upd bit of IF3OBS register not set?

  • As a test result, when can1IF3Update Interrupt for the last 3rd Frame did not occur, can1IF3Upd Bit was not enabled in the reception Interrupt for the 2nd Frame.
    Interrupt delay is therefore not the cause.

  • 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