STMicroelectronics / STM32CubeH7

STM32Cube MCU Full Package for the STM32H7 series - (HAL + LL Drivers, CMSIS Core, CMSIS Device, MW libraries plus a set of Projects running on all boards provided by ST (Nucleo, Evaluation and Discovery Kits))
https://www.st.com/en/embedded-software/stm32cubeh7.html
Other
498 stars 305 forks source link

FDCAN HAL_FDCAN_ConfigGlobalFilter() doesnt filter #292

Closed cstyx closed 3 months ago

cstyx commented 3 months ago

Describe the set-up

Describe the bug

How To Reproduce

canFilterConfig.FilterConfig = FDCAN_FILTER_TO_RXFIFO1;
canFilterConfig.IdType = FDCAN_EXTENDED_ID;
canFilterConfig.FilterType = FDCAN_FILTER_MASK;
  1. receive H723B FAIL

    • FilterID2 matches the only incomming CAN ID (0x1FFFFFFF matches all 29Bit)
    • gobal reject all non matching CAN IDs
    • should be receiving since FIlterID2 matches the send ID and the global filter rejects all other CAN IDs (no others are send, so nothing left to reject)
canFilterConfig.FilterID1 = own_address;    // canIdentifier
canFilterConfig.FilterID2 = 0x1FFFFFFF;     // mask: 0 => accept all messages

HAL_FDCAN_ConfigGlobalFilter(&hfdcan2,
            FDCAN_REJECT,
            FDCAN_REJECT,
            FDCAN_FILTER_REMOTE,
            FDCAN_FILTER_REMOTE);
  1. receive H723B FAIL

    • FilterID2 match all CAN IDs
    • gobal reject all non matching CAN IDs
    • should be receiving since the FilterID matches all CAN IDs and the global filter rejects all other CAN IDs (no others are send, so nothing left to reject)
canFilterConfig.FilterID1 = own_address;    // canIdentifier
canFilterConfig.FilterID2 = 0;          // mask: 0 => accept all messages

HAL_FDCAN_ConfigGlobalFilter(&hfdcan2,
            FDCAN_REJECT,
            FDCAN_REJECT,
            FDCAN_FILTER_REMOTE,
            FDCAN_FILTER_REMOTE);
  1. receive H723B OK

    • FilterID2 matches the only incomming CAN ID (0x1FFFFFFF matches all 29Bit)
    • gobal accept all non matching CAN IDs
    • receives since all IDs are allowed by global filter
canFilterConfig.FilterID1 = own_address;    // canIdentifier
canFilterConfig.FilterID2 = 0x1FFFFFFF;     // mask: 0 => accept all messages

HAL_FDCAN_ConfigGlobalFilter(&hfdcan2,
            FDCAN_ACCEPT_IN_RX_FIFO1,
            FDCAN_ACCEPT_IN_RX_FIFO1,
            FDCAN_FILTER_REMOTE,
            FDCAN_FILTER_REMOTE);
  1. receive H723B OK

FilterID2 matches the all incomming CAN IDs gobal accept all non matching CAN IDs receives since all ID are allowed by FilterID2 and by global filter

canFilterConfig.FilterID1 = own_address;    // canIdentifier
canFilterConfig.FilterID2 = 0;      // mask: 0 => accept all messages

HAL_FDCAN_ConfigGlobalFilter(&hfdcan2,
            FDCAN_ACCEPT_IN_RX_FIFO1,
            FDCAN_ACCEPT_IN_RX_FIFO1,
            FDCAN_FILTER_REMOTE,
            FDCAN_FILTER_REMOTE);

Not calling HAL_FDCAN_ConfigGlobalFilter() at all will lead to no received message.

In my understanding 1. and 2. should receive too. I seems like either the FilterID2 is set false, or that FDCAN_REJECT recjects always, despite any FilterID2 setting.

Testproject Attached is a test project using 2 NUCLEO-144-H723 boards using FDCAN2, where H723A is the sender and H723B is the receiver.

The sender will send an extended FDCAN message every second, indicated by the RED on-board LED toggling. Every successful received extended FDCAN message at the receiver will be indicated by a toggled GREEN on-board LED. Both H723A/B use the same project code, two #defines select the task.

Setup the sender H723A

uncomment line 105 at the main.c

#define sender          // use this definition for the sender H723A

compile, program and run.

Setup the receiver H723B

comment out line 105 at the main.c

//#define sender            // use this definition for the sender H723A
  1. setup for successful receiving

uncomment line 188 at the ProcessCAN.c

#define RECEIVE_SUCCSEFUL

compile, program and run.

The receiver will use the following global CAN filter setup

// EITHER uncomment this and GREEN BOARD LED toggles -> receiving
HAL_FDCAN_ConfigGlobalFilter(&hfdcan2,
            FDCAN_ACCEPT_IN_RX_FIFO1,
            FDCAN_ACCEPT_IN_RX_FIFO1,
            FDCAN_FILTER_REMOTE,
            FDCAN_FILTER_REMOTE);
  1. setup for unsuccessful receiving

comment out line 188 at the ProcessCAN.c

//#define RECEIVE_SUCCSEFUL

compile, program and run.

The receiver will use the following global CAN filter setup, which should allow the message to pass the filter, but it doesn't.

// OR uncomment this and GREEN BOARD LED does not toggle -> not receiving
HAL_FDCAN_ConfigGlobalFilter(&hfdcan2,
            FDCAN_REJECT,
            FDCAN_REJECT,
            FDCAN_FILTER_REMOTE,
            FDCAN_FILTER_REMOTE);

NUCLEO - H723 - FDCAN - Test.zip

ALABSTM commented 3 months ago

Hi @cstyx,

Thank you for all these details and for the attached project too. I noticed the following about the configuration you are using:

It looks like you are configuring the sender with the standard mode and the receiver with the flexible mode while trying to send data longer than 8 bytes. But, according to pages 2509 and 2510 of RM0468 revision 3:

In the CAN FD format, the coding of the DLC differs from the standard CAN format. DLC codes 0 to 8 have the same coding as in standard CAN, codes 9 to 15 (that in standard CAN all code a data field of 8 bytes) are coded according to Table 503.

Could this be the source of the abnormal behavior you are noticing?

With regards,

cstyx commented 3 months ago

Hi @ALABSTM

At the "real" project there are 2 communication channels used at the same time. I left channel 1 as dummy in the test project to show my case with different settings on FDCAN1 and FDCAN2

channel 1 H723A on FDCAN1 -> CAN -> L432 on CAN

FDCAN1 is used to talk to serveral L432, which are only providing a single CAN port and implement only the classic settings

channel 2 H723A on FDCAN2 -> CANFD -> H723B on FDCAN2

FDCAN2 is used to talk to another STM32H723 with the same settings (also on port FDCAN2)

You can check the behaviour of the project with two NUCLEO-STM32H723ZG boards and the short RxCAN and TxCAN lines crossed over.

Regards

KRASTM commented 3 months ago

Hello @cstyx,

Thank you for the report.

After analyzing your issue, I started with an example FDCAN_Loopback on STM32H743I-EVAL board to check the behavior of the HAL_FDCAN_ConfigGlobalFilter() especially with the FDCAN_REJECT option. Honestly, the project work Fine and as expected, also I tested with your config:

In other word, when non-matching, the frame will be rejected in case of FDCAN_REJECT or accepted and redirected to RX_FIFOX in case of FDCAN_ACCEPT_IN_RX_FIFOX.

In your project, you configured your project with FDCAN_MODE_EXTERNAL_LOOPBACK in the sender board, so the Msg will be checked in the first time on the 1rst board, then will be transmitted to 2nd board (the receiver), I have some questions regarding your project:

Why you added this line of code result += CAN_BusMonitoring(&hfdcan2); ?, despite you will work with MODE_EXTERNAL_LOOPBACK A lot of initializations due the change of operating mode?

I shared your Config with our team, and they said it's not recommended or inappropriate way to call HAL_FDCAN_Stop(), HAL_FDCAN_Init(), HAL_FDCAN_ConfigFilter() and HAL_FDCAN_Start() many times.

We know that when changing the mode, we must use the "init" function, and this could be an enhancement to change the operating mode without going through the init function, our Development team is aware of this possible enhancement. But unfortunately, we do not have a date yet.

Finally, I managed to successfully test your project through a few modifications to the source code with this config:

HAL_FDCAN_ConfigGlobalFilter(&hfdcan2, FDCAN_REJECT, FDCAN_REJECT, FDCAN_FILTER_REMOTE, FDCAN_FILTER_REMOTE);

I chose the FDCAN_MODE_EXTERNAL_LOOPBACK for the mode in FDCAN_HandleTypeDef, and I deleted the line 140 from the main.c and line 541 form ProcessCAN.c

With regards,

KRASTM commented 3 months ago

Hello @cstyx,

Please allow me to close this issue, thank you for your comprehension.

With regards,