cancel
Showing results for 
Search instead for 
Did you mean: 

STM32H7 FDCAN FILTER

Asantos
Senior
Posted on May 23, 2018 at 02:26

Hi,

I tested the example FDCAN_Com_IT. FDCAN configuration copied below.

When I transmit a frame from another board with the ID different from 0x111, the message is received in the 'HAL_FDCAN_RxFifo0Callback' function anyway. I suppose that this configuration should only accept frames with the ID = 0x111.

I did verify that the FDCAN1->GFC = 0x00. When I forced FDCAN1->GFC = 0x3F inside the  '

HAL_FDCAN_Init ' function, I could receive frames only with the ID = 0x111.

Is that a bug in the HAL?  Or this configuration is wrong?

How can I change the configuration below for the extended ID = 0x011111111 and with the mask to receive only this ID?

Ari.

 hfdcan.Instance = FDCANx;

hfdcan.Init.FrameFormat = FDCAN_FRAME_FD_BRS;

hfdcan.Init.Mode = FDCAN_MODE_NORMAL;

hfdcan.Init.AutoRetransmission = ENABLE;

hfdcan.Init.TransmitPause = DISABLE;

hfdcan.Init.ProtocolException = ENABLE;

hfdcan.Init.NominalPrescaler = 0x1; /* tq = NominalPrescaler x (1/fdcan_ker_ck) */

hfdcan.Init.NominalSyncJumpWidth = 0x8;

hfdcan.Init.NominalTimeSeg1 = 0x1F; /* NominalTimeSeg1 = Propagation_segment + Phase_segment_1 */

hfdcan.Init.NominalTimeSeg2 = 0x8;

hfdcan.Init.DataPrescaler = 0x1;

hfdcan.Init.DataSyncJumpWidth = 0x4;

hfdcan.Init.DataTimeSeg1 = 0x5; /* DataTimeSeg1 = Propagation_segment + Phase_segment_1 */

hfdcan.Init.DataTimeSeg2 = 0x4;

hfdcan.Init.MessageRAMOffset = 0;

hfdcan.Init.StdFiltersNbr = 1;

hfdcan.Init.ExtFiltersNbr = 0;

hfdcan.Init.RxFifo0ElmtsNbr = 2;

hfdcan.Init.RxFifo0ElmtSize = FDCAN_DATA_BYTES_8;

hfdcan.Init.RxFifo1ElmtsNbr = 0;

hfdcan.Init.RxBuffersNbr = 0;

hfdcan.Init.TxEventsNbr = 0;

hfdcan.Init.TxBuffersNbr = 0;

hfdcan.Init.TxFifoQueueElmtsNbr = 2;

hfdcan.Init.TxFifoQueueMode = FDCAN_TX_FIFO_OPERATION;

hfdcan.Init.TxElmtSize = FDCAN_DATA_BYTES_8;

HAL_FDCAN_Init(&hfdcan);

/* Configure Rx filter */

sFilterConfig.IdType = FDCAN_STANDARD_ID;

sFilterConfig.FilterIndex = 0;

sFilterConfig.FilterType = FDCAN_FILTER_MASK;

sFilterConfig.FilterConfig = FDCAN_FILTER_TO_RXFIFO0;

sFilterConfig.FilterID1 = 0x111;

sFilterConfig.FilterID2 = 0x7FF; /* For acceptance, MessageID and FilterID1 must match exactly */

HAL_FDCAN_ConfigFilter(&hfdcan, &sFilterConfig);

/* Configure Rx FIFO 0 watermark to 2 */

HAL_FDCAN_ConfigFifoWatermark(&hfdcan, FDCAN_CFG_RX_FIFO0, 2);

/* Activate Rx FIFO 0 watermark notification */

HAL_FDCAN_ActivateNotification(&hfdcan, FDCAN_IT_RX_FIFO0_WATERMARK, 0);

/* Prepare Tx Header */

TxHeader.Identifier = 0x111;

TxHeader.IdType = FDCAN_STANDARD_ID;

TxHeader.TxFrameType = FDCAN_DATA_FRAME;

TxHeader.DataLength = FDCAN_DLC_BYTES_8;

TxHeader.ErrorStateIndicator = FDCAN_ESI_ACTIVE;

TxHeader.BitRateSwitch = FDCAN_BRS_ON;

TxHeader.FDFormat = FDCAN_FD_CAN;

TxHeader.TxEventFifoControl = FDCAN_NO_TX_EVENTS;

TxHeader.MessageMarker = 0;

/* Start the FDCAN module */

HAL_FDCAN_Start(&hfdcan);
1 ACCEPTED SOLUTION

Accepted Solutions
Imen.D
ST Employee

Hello,

We confirm that HAL_FDCAN_ConfigGlobalFilter is missing in the example.

Actually, by default, if the GlobalFilter is not configured, all non-matching frames are accepted and redirected to RxFIFO0. And it comes that in this example the matching frames are also redirected to RxFIFO0.

So, the following call should be added before starting the FDCAN module:

/* Configure global filter to reject all non-matching frames */

HAL_FDCAN_ConfigGlobalFilter(&hfdcan, FDCAN_REJECT, FDCAN_REJECT, FDCAN_REJECT_REMOTE, FDCAN_REJECT_REMOTE);

The fix will be implemented in the next release of STM32CubeH7 firmware package.

To change the configuration for the extended ID = 0x011111111 and with the mask to receive only this ID:

a/ into FDCAN Init structure, set number of extended ID filters to 1:

hfdcan.Init.ExtFiltersNbr = 1;

b/ change Rx filter configuration as following:

/* Configure Rx filter */

sFilterConfig.IdType = FDCAN_EXTENDED_ID;

sFilterConfig.FilterIndex = 0;

sFilterConfig.FilterType = FDCAN_FILTER_MASK;

sFilterConfig.FilterConfig = FDCAN_FILTER_TO_RXFIFO0;

sFilterConfig.FilterID1 = 0x011111111;

sFilterConfig.FilterID2 = 0x1FFFFFFF; /* For acceptance, MessageID and FilterID1 must match exactly */

HAL_FDCAN_ConfigFilter(&hfdcan, &sFilterConfig);

c/ don't forget the global filter configuration (the fix above)

2/ The fact, that FIFO1 does not receive messages is not a bug, neither a wrong configuration. It is just that in the example the FIFO1 is not activated (number of Rx FIFO1 elements = 0):

hfdcan.Init.RxFifo1ElmtsNbr = 0; (in FDCAN Init structure)

also, Rx filter is configured to store matching frames in FIFO0:

sFilterConfig.FilterConfig = FDCAN_FILTER_TO_RXFIFO0;

Best regards,

Imen.

When your question is answered, please close this topic by clicking "Accept as Solution".
Thanks
Imen

View solution in original post

9 REPLIES 9
T J
Lead
Posted on May 23, 2018 at 07:47

I haven't worked with FDCan as yet, sorry to be unsure,

but I cannot see filter 1 setup.

I thought the Rx Fifos have separate filters.

how are you setting Filter 1 ?

If FiFo0 is ful,l FiFo1 will be receiving the next frame.

I will have my H753 board up in a month..

:(

Posted on May 23, 2018 at 14:14

TJ

Fifo1 does not receive messages, and the callback function is for the Fifo0: 

'HAL_FDCAN_RxFifo0Callback'. I think that is another bug in the HAL. I noted that the function 'HAL_FDCAN_ConfigGlobalFilter' isn't called for any other driver function. 

Ari.

Posted on May 23, 2018 at 14:30

Hello

Mendes.Ari

,

Can you please precise which device hardware board and firmware version is used ?

With Regards,

Ime,

When your question is answered, please close this topic by clicking "Accept as Solution".
Thanks
Imen
Posted on May 23, 2018 at 18:50

Ime,

  I'm using the firmware STM32Cube_FW_H7_V1.2.0 and two custom boards with STM32H743VI rev. Y, the boards can run the STM32H743I-EVAL CANFD examples without modifications. 

  

 I only receive frames with filter if the register FDCAN1->GFC.ANFS != 0 for standards frame and if with FDCAN1->GFC.ANFE !=0 for extendeds frames. 

   So I did modify the 'HAL_FDCAN_Init' function to include the line: hfdcan->Instance->GFC = 0x3F;  After the command SET_BIT(hfdcan->Instance->CCCR, FDCAN_CCCR_CCE); To enable writes in GFC.

    With this modification the example works as expected, with filter and mask active. 

   Ari.

Posted on May 24, 2018 at 10:14

Hello

Mendes.Ari

,

Thanks forreported your issues and

providing us with detailed explanations

on your case, so that it will be easier to understand theproblem.

We will check your reported issues and come back to you.

Best Regards,

Imen.

When your question is answered, please close this topic by clicking "Accept as Solution".
Thanks
Imen
Sebastiain Fernandez
Associate II

Hi

You should use the function HAL_FDCAN_ConfigGlobalFilter which does the same instead of modifying a HAL function.

for example:

MX_FDCAN1_Init(); //FDCAN peripheral function generated by CubeMX

//then set the global filter configuration

HAL_FDCAN_ConfigGlobalFilter(&hfdcan1, 3,3,0,1);

/*this input parameters get the following configuration :

ANFS[1:0] = 3 (Reject non matching standard frames)

ANFE[1:0] = 3 (Reject non matching extended frames)

RRFS = 0 (filter remote frames with standard ID)

RRFE = 1 (Reject all remote frames with extended ID)*/

I found the FDCAN_GFC (global filter configuration register) in the reference manual RM0433 (page 2512)

I have this working in a board I designed recently using the part STM32H750VBT6 and on a nucleoH743ZI board as well.

Cheers

Imen.D
ST Employee

Hello,

We confirm that HAL_FDCAN_ConfigGlobalFilter is missing in the example.

Actually, by default, if the GlobalFilter is not configured, all non-matching frames are accepted and redirected to RxFIFO0. And it comes that in this example the matching frames are also redirected to RxFIFO0.

So, the following call should be added before starting the FDCAN module:

/* Configure global filter to reject all non-matching frames */

HAL_FDCAN_ConfigGlobalFilter(&hfdcan, FDCAN_REJECT, FDCAN_REJECT, FDCAN_REJECT_REMOTE, FDCAN_REJECT_REMOTE);

The fix will be implemented in the next release of STM32CubeH7 firmware package.

To change the configuration for the extended ID = 0x011111111 and with the mask to receive only this ID:

a/ into FDCAN Init structure, set number of extended ID filters to 1:

hfdcan.Init.ExtFiltersNbr = 1;

b/ change Rx filter configuration as following:

/* Configure Rx filter */

sFilterConfig.IdType = FDCAN_EXTENDED_ID;

sFilterConfig.FilterIndex = 0;

sFilterConfig.FilterType = FDCAN_FILTER_MASK;

sFilterConfig.FilterConfig = FDCAN_FILTER_TO_RXFIFO0;

sFilterConfig.FilterID1 = 0x011111111;

sFilterConfig.FilterID2 = 0x1FFFFFFF; /* For acceptance, MessageID and FilterID1 must match exactly */

HAL_FDCAN_ConfigFilter(&hfdcan, &sFilterConfig);

c/ don't forget the global filter configuration (the fix above)

2/ The fact, that FIFO1 does not receive messages is not a bug, neither a wrong configuration. It is just that in the example the FIFO1 is not activated (number of Rx FIFO1 elements = 0):

hfdcan.Init.RxFifo1ElmtsNbr = 0; (in FDCAN Init structure)

also, Rx filter is configured to store matching frames in FIFO0:

sFilterConfig.FilterConfig = FDCAN_FILTER_TO_RXFIFO0;

Best regards,

Imen.

When your question is answered, please close this topic by clicking "Accept as Solution".
Thanks
Imen

Thanks for this answer which was helpful for me and I now have filters working on my STM32G0B1. I would also like to know for this part:

hfdcan.Init.ExtFiltersNbr = 1;

I added this as part of the MX_FDCAN1_Init() function in main.c but my filter config code is in my own can_msg.c file. Is it possible to initially set the number of filters to 0 in MX_FDCAN1_Init() and then later update the number in my own code?

What I would like to do is dynamically set the number of filters based on the CAN IDs I have, so if I add more CAN IDs my code can add new filters and increase the number of filters without having to re-init the CAN peripheral.

To follow up on this, in my can_msg module I tried simply setting the number of filters like:

pCanHandle->Init.StdFiltersNbr = 3;

And then setting up my filters as so:

can_msg_config_filter(0, 0x000, 0x616);
can_msg_config_filter(1, 0x216, 0x316);
can_msg_config_filter(2, 0x416, 0x516);
can_msg_config_global_filter();

And this means that the check should pass in HAL_FDCAN_ConfigFilter() (in actuality it passes either way! The check doesn't seem to work?)

assert_param(IS_FDCAN_MAX_VALUE(sFilterConfig->FilterIndex, (hfdcan->Init.StdFiltersNbr - 1U)));

But I found that the number of filters is also used inside the function FDCAN_CalcultateRamBlockAddresses() (note the spelling mistake is the genuine function name, not my typo) and this is called as part of HAL_FDCAN_Init().

So in conclusion if I want to initialise the peripheral with 0 standard filters and then later on change the number of filters and configure the filters, I will need to DeInit the whole FDCAN peripheral and Init it again with the updated filter number?