Skip to content

CAN filter API not correctly implemented for STM32F0 (and possibly other STM32) #2987

Closed
@martinjaeger

Description

@martinjaeger

Description

  • Type: Bug
  • Priority: Minor

Target
STM32F0 and possibly other STM32 family MCUs

The function int can_filter(can_t *obj, uint32_t id, uint32_t mask, CANFormat format, int32_t handle) in can_api.c is not correctly implemented for STM32F0.

Current implementation:

    sFilterConfig.FilterIdHigh = (uint8_t) (id >> 8);
    sFilterConfig.FilterIdLow = (uint8_t) id;
    sFilterConfig.FilterMaskIdHigh = (uint8_t) (mask >> 8);
    sFilterConfig.FilterMaskIdLow = (uint8_t) mask;

does not set the filter according to actual register layout described in Reference Manual RM0091 (page 832).

Fixed implementation of entire function

int can_filter(can_t *obj, uint32_t id, uint32_t mask, CANFormat format, int32_t handle) 
{
    int retval = 0;

    // filter for CANAny format cannot be configured for STM32
    if((format == CANStandard) || (format == CANExtended)) {

        CanHandle.Instance = (CAN_TypeDef *)(obj->can);
        CAN_FilterConfTypeDef  sFilterConfig;

        sFilterConfig.FilterNumber = handle;
        sFilterConfig.FilterMode = CAN_FILTERMODE_IDMASK;
        sFilterConfig.FilterScale = CAN_FILTERSCALE_32BIT;

        if(format == CANStandard) {
            sFilterConfig.FilterIdHigh = id << 5;
            sFilterConfig.FilterIdLow =  0x0;
            sFilterConfig.FilterMaskIdHigh = mask << 5;
            sFilterConfig.FilterMaskIdLow = 0x0;    // allows both remote and data frames
        }
        else if(format == CANExtended){
            sFilterConfig.FilterIdHigh = id >> 13;  // EXTID[28:13]
            sFilterConfig.FilterIdLow = (0x00FF & (id << 3)) | (1 << 2);  // EXTID[12:0]
            sFilterConfig.FilterMaskIdHigh = mask >> 13;
            sFilterConfig.FilterMaskIdLow = (0x00FF & (mask << 3)) | (1 << 2);
        }

        sFilterConfig.FilterFIFOAssignment = 0;
        sFilterConfig.FilterActivation = ENABLE;
        sFilterConfig.BankNumber = 14 + handle;

        HAL_CAN_ConfigFilter(&CanHandle, &sFilterConfig);   
        retval = handle;
    }
    return retval;
}

The fixed function was successfully tested with STM32F072 Nucleo board, using extended and standard format.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions