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.

MSPM0G3507: CAN RX gets stuck when multiple messages are incoming

Part Number: MSPM0G3507
Other Parts Discussed in Thread: SYSCONFIG

Tool/software:

Hey there,

I adapted the example project mcan_message_rx_LP_MSPM0G3507_nortos_ticlang for receiving of CAN message.

If I send a CAN message from my PC CAN dongle (PCAN VIEW) the MSPM0G3507 triggers a CAN-RX-Interrupt and receives and processes the received message.

From time to time a single message does not trigger and interrupt..

But when I send a second message before the first one is processed, the second one is not processed.

And when I send multiple messages in a short time the CAN reveive seems to get completely stuck. Even if I wait some time a new CAN message won't trigger a new interrupt.

I need to restart my debug session to be able to receive CAN messages again.

I made a "watch expression" on "gInterruptLine1Status".

It changes to 0x0002000C or 0x00020004 when the receiving stops.

From the technical reference manual I found out that this seems to be the (raw or masked) interrupt status register value. And the SEC (single error correction) and/or the DED (dual error detection) bits are set.

I added/edited the following configurations to my sysconfig to somehow trigger an interrupt or anything else to be able to deal with the "getting stuck".

Fullscreen
1
2
3
4
5
6
MCAN1.m0interrupts = ["DL_MCAN_MSP_INTERRUPT_DOUBLE_ERROR_DETECTION","DL_MCAN_MSP_INTERRUPT_LINE0","DL_MCAN_MSP_INTERRUPT_LINE1","DL_MCAN_MSP_INTERRUPT_SINGLE_ERROR_CORRECTION "];
MCAN1.interruptLine = ["DL_MCAN_INTR_LINE_NUM_0","DL_MCAN_INTR_LINE_NUM_1"];
MCAN1.rxFIFO0size = 10;
MCAN1.rxFIFO0waterMark = 8;
MCAN1.interruptFlags = ["DL_MCAN_INTERRUPT_RF0F","DL_MCAN_INTERRUPT_RF0N","DL_MCAN_INTERRUPT_RF0W"];
MCAN1.interruptLine0Flag = ["DL_MCAN_INTERRUPT_RF0F","DL_MCAN_INTERRUPT_RF0W"];
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

But none of my interrupt cases get triggered apart from the rx interrupt. This is my CAN-interrupt-handler:

Fullscreen
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
void MCAN0_INST_IRQHandler(void)
{
printf("\nCAN_IRQ_handler");
switch (DL_MCAN_getPendingInterrupt(MCAN0_INST)) {
case DL_MCAN_IIDX_LINE0: // RX FIFO 0 Full - interrupt
__BKPT(0);
/* Check MCAN interrupts fired during TX/RX of CAN package */
gInterruptLine0Status |= DL_MCAN_getIntrStatus(MCAN0_INST);
DL_MCAN_clearIntrStatus(MCAN0_INST, gInterruptLine0Status,
DL_MCAN_INTR_SRC_MCAN_LINE_0);
printf("\nCAN_IRQ_Line0");
gServiceInt0 = true;
break;
case DL_MCAN_IIDX_LINE1: // RX FIFO 0 New Message - interrupt
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

Can anyone please help me?

If you need any more information, please let me know ;)

Thanks a lot in advance!

Matze

  • Hi, 

    Try this:

    mcan.zip

    Regards,

    Helic

  • Thank you!

    1.

    I see that the "MCAN" - "Advanced Configuration" - "Additional Core Configuration" is enabled and configured.

    I have not used this setting by now. might this be the reason why I have these problems?

    I don't really understand what I can achieve with these "advanced configuration settings". Is there any help, advice oder documentation concerning these settings? Or can anyone explain to me, what it is?

    2.

    In the example I find the comment:

    /* New message received by Rx FIFO 0 (Filter matched) */
    It sounds like the incoming message is already filtered and only the matching sid/eid-messages trigger an interrupt?
    Am I right? Where are the settings for that "pre-"filtering?
    In the "mcan_message_rx_LP_MSPM0G3507_nortos_ticlang" after an rx-interrupt each message first of all has to be gone through step by step and be filtered "manually" in code to decide whether it is the right sid/eid or not.
    Please tell me where the magic happens!
    Thanks a lot in advance!
    Matze

  • Hi, 

    I see that the "MCAN" - "Advanced Configuration" - "Additional Core Configuration" is enabled and configured.

    If you don't use the feature in this section, you can disable it~ But keep it as default is OK.

    I have not used this setting by now. might this be the reason why I have these problems?

    There are many reason cause CAN stuck, but I don't think that Advanced Configuration cause this issue.

    Is there any help, advice oder documentation concerning these settings? Or can anyone explain to me, what it is?

    Some feature can be found here: 20.4 MCAN Functional Description in TRM.

    It sounds like the incoming message is already filtered and only the matching sid/eid-messages trigger an interrupt?

    Yes.

    Where are the settings for that "pre-"filtering?

    In syscfg, CAN RAM setting, Filter setting.

    In the "mcan_message_rx_LP_MSPM0G3507_nortos_ticlang" after an rx-interrupt each message first of all has to be gone through step by step and be filtered "manually" in code to decide whether it is the right sid/eid or not.
    Please tell me where the magic happens!

    This is MCAN dual ID setting, You can find it in syscfg:

    In some use case, you can set ID1 as Filter ID and ID2 as Mask.

    Try this:

    mcan.zip

    Final, please refer to the demo I upload to this thread as MCAN reference, this demo passed pressure test.

    Regards,

    Helic

  • Hey,

    Thanks for your answers.

    I tried to implement everything as in the example that you provided.

    But I am facing the problem that my filtering does not seem to work.

    I defined the following filters:

    const uint32_t sid1 = 0x1A0;
    const uint32_t sid2 = 0x380;
    const uint32_t eid1 = 0x2294000;
    const uint32_t eid2 = 0x6214000;
        CANInfo.gMCAN0StdFiltelem1.sfec = 0x1;
        CANInfo.gMCAN0StdFiltelem1.sft  = 0x2;
        CANInfo.gMCAN0StdFiltelem1.sfid1 = sid1;
        CANInfo.gMCAN0StdFiltelem1.sfid2 = 0x7FF;  // 11 bit - alle bits auf 1
     
        CANInfo.gMCAN0StdFiltelem2.sfec = 0x1;
        CANInfo.gMCAN0StdFiltelem2.sft  = 0x2;
        CANInfo.gMCAN0StdFiltelem2.sfid1 = sid2;
        CANInfo.gMCAN0StdFiltelem2.sfid2 = 0x7FF;  // 11 bit - alle bits auf 1


        CANInfo.gMCAN0ExtFiltelem1.efec = 0x1;
        CANInfo.gMCAN0ExtFiltelem1.eft  = 0x2;
        CANInfo.gMCAN0ExtFiltelem1.efid1 = eid1;
        CANInfo.gMCAN0ExtFiltelem1.efid2 = 0x1FFFFFFF;  // 29 bit - alle bits auf 1


        CANInfo.gMCAN0ExtFiltelem2.efec = 0x1;
        CANInfo.gMCAN0ExtFiltelem2.eft  = 0x2;
        CANInfo.gMCAN0ExtFiltelem2.efid1 = eid2;
        CANInfo.gMCAN0ExtFiltelem2.efid2 = 0x1FFFFFFF;  // 29 bit - alle bits auf 1

    But the filtering has no effect. The MCAN new message interrupt gets triggered every time that any message with any ID is received on the CANBUS.

    Even any "wrong" message ID is stored in FIFO an triggers an interrupt.

    And I have the following lines in my void SYSCFG_DL_MCAN0_init(void)

        /* Configure Standard ID filter elements */
        DL_MCAN_addStdMsgIDFilter(MCAN0_INST, 0U, (DL_MCAN_StdMsgIDFilterElement *) &CANInfo.gMCAN0StdFiltelem1);
        DL_MCAN_addStdMsgIDFilter(MCAN0_INST, 1U, (DL_MCAN_StdMsgIDFilterElement *) &CANInfo.gMCAN0StdFiltelem2);

        /* Configure Extended ID filter elements*/
        DL_MCAN_addExtMsgIDFilter(MCAN0_INST, 0U, (DL_MCAN_ExtMsgIDFilterElement *) &CANInfo.gMCAN0ExtFiltelem1);
        DL_MCAN_addExtMsgIDFilter(MCAN0_INST, 1U, (DL_MCAN_ExtMsgIDFilterElement *) &CANInfo.gMCAN0ExtFiltelem2);

        /* Set Extended ID Mask. */
        DL_MCAN_setExtIDAndMask(MCAN0_INST, MCAN0_INST_MCAN_EXT_ID_AND_MASK );

    But when I remove these lines, everything stays unchanged. These lines seem to have no effect.

    What should these functions actually do and why don't they currently do that for me?

    Thanks a lot in advance!

    Matze

  • Hi, 

    I defined the following filters:

    Filter settings are right~

    But need to waiting for MCAN RAM init done, you can set the filter.

    There is no need to enter initialization mode to set the filter.

    ------------

    Could you please try to test the MCAN based on my project.

    It works normal when set the right filter.

    ------------------

    Check whether you enable the RXFIFO1 interrupt, this will also cause MCAN interrupt triggered.

    Also, interrupt need to check every interrupt you enabled to confirm which interrupt is triggered.

    Don't put printf function in interrupt, printf will takes a lot of time to printf string.

    Regards,

    Helic

  • Hi,

    But need to waiting for MCAN RAM init done, you can set the filter.

    I compared my SYSCFG_DL_MCAN0_init() to the SYSCFG_DL_MCAN0_init() in the mcan_multi_Msg_RxTx_Interrupt_LP_MSPM0G3507_nortos_ticlang example project.

    Both functions are completely identical.

    So the MCAN RAM init (

    /* Wait for Memory initialization to be completed. */
        while(false == DL_MCAN_isMemInitDone(MCAN0_INST));

    ) is waited to be done before I add my filters.

    Is this what you wanted me to make sure?

    ________________________________________________________________

    Could you please try to test the MCAN based on my project.

    It works normal when set the right filter.

    Yes, I will check that.

    ________________________________________________________________

    Check whether you enable the RXFIFO1 interrupt

    I enable the FIFO 0 New Message interrupt in the beginning of my int main(void).

    DL_MCAN_enableIntr(MCAN0_INST, DL_MCAN_INTERRUPT_RF0N, 1U);     // Rx FIFO 0 New Message interrupt

    Instead of

    DL_MCAN_INTERRUPT_RF0N

    I could have chosen

    DL_MCAN_INTR_SRC_RX_FIFO0_NEW_MSG

    Am I right?

    I have no corresponding activation/enabling of an interrupt for FIFO1 in my source code.

    ________________________________________________________________

    Also, interrupt need to check every interrupt you enabled to confirm which interrupt is triggered.

    I do check what triggered my IRQ like this:

    Fullscreen
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    void MCAN0_INST_IRQHandler(void)
    {
    switch (DL_MCAN_getPendingInterrupt(MCAN0_INST)) {
    case DL_MCAN_IIDX_LINE1: // RX FIFO 0 New Message - interrupt
    /* Check MCAN interrupts fired during RX of CAN package */
    gInterruptLine1Status |= DL_MCAN_getIntrStatus(MCAN0_INST);
    /* New message received by Rx FIFO 0 (Filter matched) */
    if(gInterruptLine1Status & DL_MCAN_INTERRUPT_RF0N)
    {
    ...
    }
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    EDIT:

    And I debugged my code and added a watch expression on "gInterruptLine1Status" and found out that every time the IRQ gets triggered the "gInterruptLine1Status" holds the value 0x20001. So the "Message RAM Access Failure bit" (MCAN_IR_MRAF_MASK) and the "RX FIFO 0 New Message bit" (DL_MCAN_INTERRUPT_RF0N) are set.

    Really every time both bits are set. Regardless of whether I receive a filter-matching or a not-filter-matching CAN Message ID.

    What could possibly cause this "Message RAM Access Failure" ?

    in hw_mcan.h it says: 

    Fullscreen
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    The
    flag is set, when the Rx Handler: -
    has not completed acceptance
    filtering or storage of an accepted
    message until the arbitration field
    of the following message has been
    received. In this case acceptance
    filtering or message storage is
    aborted and the Rx Handler starts
    processing of the following message.
    - was not able to write a message to
    the Message RAM. In this case message
    storage is aborted. In both cases
    the FIFO put index is not updated
    resp. the New Data flag for a
    dedicated Rx Buffer is not set, a
    partly stored message is overwritten
    when the next message is stored to
    this location. The flag is also set
    when the Tx Handler was not able to
    read a message from the Message RAM
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    but unfortunately i can't do much with these explanations..

    ________________________________________________________________

    EDIT2: And if I look at the received messages as “watch expression” during debugging, I see the following set bit:

    amnf = 1 : Accepted Non-matching Frame - Received frame did not match any Rx filter element

    The filter index (fidx) is also so high at “127” that it appears to have tried all the filters and none of them matched.

    So somehow there must be a way to set filters for receiving CAN messages that really only accept filter matching message IDs..
    So that an interrupt may only be triggered if a CAN message with a matching (filtered) ID is received.

    ________________________________________________________________

    Don't put printf function in interrupt, printf will takes a lot of time to printf string.

    Yes sure.. I just use it for debugging..

    But this does not cause my filtering issue, does it?

    Thanks in advance!

    Matze

  • Hi, 

    Is this what you wanted me to make sure?

    Yes, seems ok.

    I do check what triggered my IRQ like this:

    Also, remember to manually clear the interrupt.

    What could possibly cause this "Message RAM Access Failure" ?

    RAM init is nor finished, or your Filter is not written into CAN RAM successfully.

    Please try this demo, this demo can read the filter from CAN RAM, you need to verify your filter configuration.

    4174.mcan_multi_Filter_Control_LP_MSPM0G3507_nortos_ticlang.zip

    But this does not cause my filtering issue, does it?

    Not likely, but it's a risk.

    Regards,

    Helic

  • Hi!

    Also, remember to manually clear the interrupt

    I manually clear the interrupt status in the beginning of my IRQ-case by this line of code:

    DL_MCAN_clearIntrStatus(MCAN0_INST, gInterruptLine1Status, DL_MCAN_INTR_SRC_MCAN_LINE_1);

    And depending on the bit that is set in the Interrupt Status Register and in gInterruptLine1Status I clear these bits after processing the corresponding case in the IRQ by:

    gInterruptLine1Status &= ~(MCAN_IR_RF0N_MASK);

    and/or

    gInterruptLine1Status &= ~(MCAN_IR_MRAF_MASK);

    When I check gInterruptLine1Status after the IRQ it holds the value 0x00 as expected.

    AND I have to correct myself:

    When an incoming message (no matter what ID) triggers the Interrupt, only the RF0N-bit is set.

    But when an incoming message does not trigger the Interrupt (here, too, it makes no difference whether the ID is contained in my filter config or not) and after that a new message triggers the Interrupt, both bits RF0N and MRAF are set.

    RAM init is nor finished, or your Filter is not written into CAN RAM successfully.

    Please try this demo, this demo can read the filter from CAN RAM, you need to verify your filter configuration.

    4174.mcan_multi_Filter_Control_LP_MSPM0G3507_nortos_ticlang.zip

    Thanks, I will try this example!

  • Hi, 

    But when an incoming message does not trigger the Interrupt (here, too, it makes no difference whether the ID is contained in my filter config or not) and after that a new message triggers the Interrupt, both bits RF0N and MRAF are set.

    This is a bit weird. ID filter seems not work normally. And two message will cause MRAF.

    Please also check your MCAN RAM configuration, all filter and message RAM share the sam 1024bytes MCAN RAM region, please make sure that these parts do not overlap in using RAM.

    Here is an example:

    Thanks, I will try this example!

    Waiting for your feedback.

    Regards,

    Helic