Search code examples
filterstm32can-bushal

STM32 with dual CAN - configure filters


Looking for help with a strange issue while trying to set up filters on STM32F105 that has 2 CAN busses - the filters in 16bit list mode work only for the first 2 banks. But the same configuration works well for STM32F103 with single CAN bus.

Here is the code:

bool CanSetFilter(CAN_HandleTypeDef *can, uint8_t bank, uint16_t id1, uint16_t id2, uint16_t id3, uint16_t id4) {
  return CanSetFilterList16bit(can, bank, (uint32_t(id1)<<21) | (uint32_t(id2)<<5), (uint32_t(id3)<<21) | (uint32_t(id4)<<5), CAN_FILTERMODE_IDLIST, CAN_FILTERSCALE_16BIT, CAN_FILTER_FIFO0);
}

bool CanSetFilterList16bit(CAN_HandleTypeDef *can, uint8_t bank_num, uint32_t filter_id, uint32_t mask, uint32_t filter_mode, uint32_t filter_scale, uint32_t fifo) {
  CAN_FilterTypeDef sFilterConfig;
  sFilterConfig.FilterBank = bank_num;
  sFilterConfig.FilterMode = filter_mode;
  sFilterConfig.FilterScale = filter_scale;
  sFilterConfig.FilterFIFOAssignment = fifo;
  sFilterConfig.FilterActivation = ENABLE;
  sFilterConfig.FilterIdHigh = filter_id&0xFFFF;
  sFilterConfig.FilterIdLow = filter_id>>16;
  sFilterConfig.FilterMaskIdHigh = mask&0xFFFF;
  sFilterConfig.FilterMaskIdLow = mask>>16;
  bool result = (HAL_CAN_ConfigFilter(can, &sFilterConfig ) == HAL_OK);
  return result;
}

// and apply filters:
uint16_t canFilterIds[] = {
    0x076, 0x077, 0x07D, 0x167, 
    0x171, 0x204, 0x213, 0x217, 
    0x230, 0x3B3, 0x42F, 0x43E, // < this goes to bank 3 and doesn't work in result
};

const int canFiltersCount = sizeof(canFilterIds) / sizeof(canFilterIds[0]);
int filter = 0;
for (int i=0; (i<canFiltersCount) && (filter<28); filter++) {
    uint32_t f1 = (i<canFiltersCount) ? canFilterIds[i++] : canFilterIds[i];
    uint32_t f2 = (i<canFiltersCount) ? canFilterIds[i++] : canFilterIds[i];
    uint32_t f3 = (i<canFiltersCount) ? canFilterIds[i++] : canFilterIds[i];
    uint32_t f4 = (i<canFiltersCount) ? canFilterIds[i++] : canFilterIds[i];
    CanSetFilter(&hcan1, filter, f1, f2, f3, f4);
}

I see in debug mode that all three calls of CanSetFilter(...) are successful. Here is the corresponding result in CAN_FilterTypeDef: enter image description here

enter image description here

enter image description here

I have no idea what's the issue, so looking forward if anyone has a working example or has met the issue.


Solution

  • Ok, the problem was in filter initialization for CAN 2. Supposed to disable the filter I set sFilterConfig.FilterBank = 27;. And it causes incorrect behavior. When I change it to sFilterConfig.FilterBank = 0; it works well. Here is the filters initialization code for CAN2 bus that disables filtering on it but keeps filters working for CAN1, maybe will be helpful for someone.

    CAN_FilterTypeDef sFilterConfig;
    sFilterConfig.FilterBank = 0;
    sFilterConfig.FilterActivation = CAN_FILTER_DISABLE;
    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_FIFO1;
    sFilterConfig.FilterActivation = ENABLE;
    sFilterConfig.SlaveStartFilterBank = 28;
    HAL_result = HAL_CAN_ConfigFilter(&hcan2, &sFilterConfig);
    

    Inspired by discussion here: https://community.st.com/t5/stm32-mcus-products/how-to-configure-can-filters-to-use-can1-and-can2-parallelly/td-p/56553