cancel
Showing results for 
Search instead for 
Did you mean: 

How to use both FIFO's STM32F103

JBond.1
Senior

Hi, I am working with STM32F103 and configure CAN filter like this:

CAN_FilterTypeDef  sFilterConfig;
  sFilterConfig.FilterBank = 0;
  sFilterConfig.FilterMode = CAN_FILTERMODE_IDMASK;
  sFilterConfig.FilterScale = CAN_FILTERSCALE_32BIT;
  sFilterConfig.FilterIdHigh = 0x0000;
  sFilterConfig.FilterIdLow = 0x0000;
  sFilterConfig.FilterMaskIdHigh = 0x0000;
  sFilterConfig.FilterMaskIdLow = 0x0000;
  sFilterConfig.FilterFIFOAssignment = CAN_RX_FIFO0;
  sFilterConfig.FilterActivation = ENABLE;
  sFilterConfig.SlaveStartFilterBank = 14;
 
  if (HAL_CAN_ConfigFilter(&hcan, &sFilterConfig) != HAL_OK)
  {
    Error_Handler();
  }
  if (HAL_CAN_Start(&hcan) != HAL_OK)
  {
    Error_Handler();
  }
  if (HAL_CAN_ActivateNotification(&hcan, CAN_IT_RX_FIFO0_MSG_PENDING) != HAL_OK)
  {
    Error_Handler();
  }

This uses only FIFO0 memory, correct? So I can receive only up to 3 messages at the same time, otherwise it would overflow?

Could I also use FIFO1 memory? To receive up to 6 messages at the same time?

How could I do that?

1 ACCEPTED SOLUTION

Accepted Solutions

>> Or I dont understand something?

You attempt inject complexity where there isn't any?

Pretty sure it's a once and done thing, you're typically using an auto/local variable of limited life/scope

// Common initialization

sFilterConfig.FilterMode = CAN_FILTERMODE_IDMASK;

sFilterConfig.FilterScale = CAN_FILTERSCALE_32BIT;

sFilterConfig.FilterActivation = ENABLE;

sFilterConfig.SlaveStartFilterBank = 14; // Could be 28 if you're doing nothing with CAN2

sFilterConfig.FilterBank = 0; 

// Init settings for First Filter

sFilterConfig.FilterIdHigh = ...;

sFilterConfig.FilterIdLow = ...;

sFilterConfig.FilterMaskIdHigh = ...;

sFilterConfig.FilterMaskIdLow = ...;

sFilterConfig.FilterFIFOAssignment = CAN_RX_FIFO0;

HAL_CAN_ConfigFilter(&hcan, &sFilterConfig);

sFilterConfig.FilterBank = 1;

// Init settings for Second Filter 

sFilterConfig.FilterIdHigh = ...;

sFilterConfig.FilterIdLow = ...;

sFilterConfig.FilterMaskIdHigh = ...;

sFilterConfig.FilterMaskIdLow = ...;

sFilterConfig.FilterFIFOAssignment = CAN_RX_FIFO1;

HAL_CAN_ConfigFilter(&hcan, &sFilterConfig);

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..

View solution in original post

7 REPLIES 7

>>How could I do that?

Configure different filters to handle different subsets of the ID space, funnelling them into different FIFO's

You've basically created a single filter that takes everything and stuffs it in a single FIFO

You might want to optimize the code that you have consuming the FIFO content so it doesn't bottleneck in your processing code.

If you can't process the messages real-time, enqueue them in your own buffer management system, which you can make as deep as you need it.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
JBond.1
Senior

@Community member​ 

>>Configure different filters to handle different subsets of the ID space, funnelling them into different FIFO's

But one "CAN_HandleTypeDef hcan" can have only one filter "HAL_CAN_ConfigFilter(&hcan, &sFilterConfig)"?

Do I need to manually create second "CAN_HandleTypeDef hcan" object which would use same "hcan.Instance = CAN1" and other settings, the difference would be only "FilterFIFOAssignment = CAN_RX_FIFO1" and FilterMask/FilterId to handle different IDs? Also different banks? 0-14/15-29?

You could use one structure to initialize

sFilterConfig.FilterBank = 0; // Enumerate 0 thru 13 for CAN1, or change the slave split higher if not using/needing CAN2

Change the Filter ID/MASK to reflect the capturing window

Change the binning

sFilterConfig.FilterFIFOAssignment = CAN_RX_FIFOx;

Call once per filter you're adding

HAL_CAN_ConfigFilter(&hcan, &sFilterConfig);

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..

But wont assigning two filters to same "CAN_HandleTypeDef hcan" structure override each other?

HAL_CAN_ConfigFilter(&hcan, &sFilterConfig1);
HAL_CAN_ConfigFilter(&hcan, &sFilterConfig2);

This is the source code of "HAL_CAN_ConfigFilter" :

HAL_StatusTypeDef HAL_CAN_ConfigFilter(CAN_HandleTypeDef *hcan, CAN_FilterTypeDef *sFilterConfig)
{
    //...code skipped...
 
    /* Filter FIFO assignment */
    if (sFilterConfig->FilterFIFOAssignment == CAN_FILTER_FIFO0)
    {
      /* FIFO 0 assignation for the filter */
      CLEAR_BIT(can_ip->FFA1R, filternbrbitpos);
    }
    else
    {
      /* FIFO 1 assignation for the filter */
      SET_BIT(can_ip->FFA1R, filternbrbitpos);
    }
 
    //...code skipped...
}

So setting different filters with different FIFO will override the same FFA1R value? Or I dont understand something?

Unless starting from different FilterBanks?

CAN_FilterTypeDef  sFilterConfig1;
  sFilterConfig1.FilterBank = 0;
  sFilterConfig1.FilterMode = CAN_FILTERMODE_IDMASK;
  sFilterConfig1.FilterScale = CAN_FILTERSCALE_32BIT;
  sFilterConfig1.FilterIdHigh = 0x0000;             // will need to adjust
  sFilterConfig1.FilterIdLow = 0x0000;              // will need to adjust
  sFilterConfig1.FilterMaskIdHigh = 0x0000;   // will need to adjust
  sFilterConfig1.FilterMaskIdLow = 0x0000;    // will need to adjust
  sFilterConfig1.FilterFIFOAssignment = CAN_RX_FIFO0;
  sFilterConfig1.FilterActivation = ENABLE;
 
  if (HAL_CAN_ConfigFilter(&hcan, &sFilterConfig1) != HAL_OK)
  {
    Error_Handler();
  }
 
  CAN_FilterTypeDef  sFilterConfig2;
  sFilterConfig2.FilterBank = 14;
  sFilterConfig2.FilterMode = CAN_FILTERMODE_IDMASK;
  sFilterConfig2.FilterScale = CAN_FILTERSCALE_32BIT;
  sFilterConfig2.FilterIdHigh = 0x0000;            // will need to adjust
  sFilterConfig2.FilterIdLow = 0x0000;             // will need to adjust
  sFilterConfig2.FilterMaskIdHigh = 0x0000;   // will need to adjust
  sFilterConfig2.FilterMaskIdLow = 0x0000;    // will need to adjust
  sFilterConfig2.FilterFIFOAssignment = CAN_RX_FIFO1;
  sFilterConfig2.FilterActivation = ENABLE;
 
 
  if (HAL_CAN_ConfigFilter(&hcan, &sFilterConfig2) != HAL_OK)
  {
    Error_Handler();
  }

 So then it would change different can_ip->FFA1R bit?

>> Or I dont understand something?

You attempt inject complexity where there isn't any?

Pretty sure it's a once and done thing, you're typically using an auto/local variable of limited life/scope

// Common initialization

sFilterConfig.FilterMode = CAN_FILTERMODE_IDMASK;

sFilterConfig.FilterScale = CAN_FILTERSCALE_32BIT;

sFilterConfig.FilterActivation = ENABLE;

sFilterConfig.SlaveStartFilterBank = 14; // Could be 28 if you're doing nothing with CAN2

sFilterConfig.FilterBank = 0; 

// Init settings for First Filter

sFilterConfig.FilterIdHigh = ...;

sFilterConfig.FilterIdLow = ...;

sFilterConfig.FilterMaskIdHigh = ...;

sFilterConfig.FilterMaskIdLow = ...;

sFilterConfig.FilterFIFOAssignment = CAN_RX_FIFO0;

HAL_CAN_ConfigFilter(&hcan, &sFilterConfig);

sFilterConfig.FilterBank = 1;

// Init settings for Second Filter 

sFilterConfig.FilterIdHigh = ...;

sFilterConfig.FilterIdLow = ...;

sFilterConfig.FilterMaskIdHigh = ...;

sFilterConfig.FilterMaskIdLow = ...;

sFilterConfig.FilterFIFOAssignment = CAN_RX_FIFO1;

HAL_CAN_ConfigFilter(&hcan, &sFilterConfig);

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..

>>So setting different filters with different FIFO will override the same FFA1R value? 

No, it's a bit vector with 28 positions (ON/OFF), the ownership split of CAN1 vs CAN2 is controlled by SlaveStartFilterBank

There are 28 FilterID/MASK registers, these should attempt to have different picks.

The filters can have overlap, but you're really trying to subdivide and prioritize a sub-set.

They are taken in ORDER, you should put your broadest, catch-all, filter as the last one.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..

@Community member​ 

I want to catch all IDs or as many as possible. Splitting filters to odd and even IDs into FIFO0 and FIFO1 would give me better chance to catch all messages? (compared to my previous method catch all to FIFO0 only)

So with your help my could now looks like this:

  CAN_FilterTypeDef sFilterConfig;
  sFilterConfig.SlaveStartFilterBank = 28;
  sFilterConfig.FilterActivation = ENABLE;
  sFilterConfig.FilterMode = CAN_FILTERMODE_IDMASK;
  sFilterConfig.FilterScale = CAN_FILTERSCALE_32BIT;
  sFilterConfig.FilterBank = 0;
  sFilterConfig.FilterFIFOAssignment = CAN_RX_FIFO0;
  // odd IDs to FIFO0
  sFilterConfig.FilterIdHigh = 0x00000020;
  sFilterConfig.FilterIdLow = 0x00000000;
  sFilterConfig.FilterMaskIdHigh = 0x00000020;
  sFilterConfig.FilterMaskIdLow = 0x00000000;
 
  if (HAL_CAN_ConfigFilter(&hcan, &sFilterConfig) != HAL_OK)
  {
    Error_Handler();
  }
 
  sFilterConfig.FilterBank = 1;
  sFilterConfig.FilterFIFOAssignment = CAN_RX_FIFO1;
  // even IDs to FIFO1
  sFilterConfig.FilterIdHigh = 0x00000000;
  sFilterConfig.FilterIdLow = 0x00000000;
  sFilterConfig.FilterMaskIdHigh = 0x00000020;
  sFilterConfig.FilterMaskIdLow = 0x00000000;
 
  if (HAL_CAN_ConfigFilter(&hcan, &sFilterConfig) != HAL_OK)
  {
    Error_Handler();
  }
	
  if (HAL_CAN_Start(&hcan) != HAL_OK)
  {
    Error_Handler();
  }
	
  if (HAL_CAN_ActivateNotification(&hcan, CAN_IT_RX_FIFO0_MSG_PENDING) != HAL_OK)
  {
    Error_Handler();
  }
	
  if (HAL_CAN_ActivateNotification(&hcan, CAN_IT_RX_FIFO1_MSG_PENDING) != HAL_OK)
  {
    Error_Handler();
  }

Did I get correct FilterIds and FilterMasks?