5 years, 7 months ago.

Does the CAN Filter work?

I tried to use CAN filter but it returns 0 whenever I try to setup a handle. I'm on LPC1768. I thought that may I should disable can first to setup this handle, but I don't know how. Any ways to avoid or fix this issue?

CAN filtering

#include "mbed.h"

RawSerial pcLogCOM13(USBTX,USBRX);      

CAN can1(p30, p29, 500000);
CANMessage CANin;

int main() {
    wait(2);
    bool respFilter = can1.filter(0x291, 0x1FFFFFFF, CANAny, 1);
    pcLogCOM13.printf("Filter set: %d\n", respFilter);
    wait(1);
    while(1) {
        
    }
}

Output: 0

3 Answers

5 years, 7 months ago.

Hello L B (or W K?),

There seems to be some mismatch in the Mbed documentation/comments and the implementation code.
The API says:

    /** Filter out incoming messages
     *
     *  @param id the id to filter on
     *  @param mask the mask applied to the id
     *  @param format format to filter on (Default CANAny)
     *  @param handle message filter handle (Optional)
     *
     *  @returns
     *    0 if filter change failed or unsupported,
     *    new filter handle if successful
     */
    int filter(unsigned int id, unsigned int mask, CANFormat format = CANAny, int handle = 0);

But the CAN::filter method always returns 0 for LPC1768 because it seems to be not implemented:

int can_filter(can_t *obj, uint32_t id, uint32_t mask, CANFormat format, int32_t handle) {
    return 0; // not implemented
}

On the other hand, for the STM targets the same method always returns 1:

int can_filter(can_t *obj, uint32_t id, uint32_t mask, CANFormat format, int32_t handle)
{
    // filter for CANAny format cannot be configured for STM32
    if ((format == CANStandard) || (format == CANExtended)) {
        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 { // format == CANExtended
            sFilterConfig.FilterIdHigh = id >> 13; // EXTID[28:13]
            sFilterConfig.FilterIdLow = (0xFFFF & (id << 3)) | (1 << 2); // EXTID[12:0] + IDE
            sFilterConfig.FilterMaskIdHigh = mask >> 13;
            sFilterConfig.FilterMaskIdLow = (0xFFFF & (mask << 3)) | (1 << 2);
        }

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

        HAL_CAN_ConfigFilter(&obj->CanHandle, &sFilterConfig);
    }

    return 1;
}

Accepted Answer

If I wanted to add my own method for LPC1768, how would I go about it from the online compiler? In which file can the filter function be devised? How would I make it part of my project? I want to edit only this function so that I can still use the CAN class.

When I look into my online compiler. mbed-os consists only of documentation. I don't find the code behind what's happening. How to reach and change this code?

posted by L B 05 Apr 2019

You are right. The source code of mbed library is not available when working online. I'm afraid the only option you have online is to build your own CAN library. Actually, I have done it in the past for the STM Nucleo boards (see the CANnucleo library) because CAN support was missing for such targets in mbed at that time.

posted by Zoltan Hudak 05 Apr 2019
5 years, 7 months ago.

In the past it's been possible to import the source of mbed from github and then delete the mbed lib from your project. Then you can tunnel into the source code and customize the driver.

5 years, 7 months ago.

Please refer to following thread.
https://os.mbed.com/forum/mbed/topic/2033/

Hello. I've had a look at that thread a while ago and whilst it did filter CAN I wouldn't be able to fill in the gaps for the other things I need from it since I'm a beginner to this sort of high level stuff. I'd need to implement masks, create handles so that filters can be overwritten, and be able to clear the filtering. It would take too long to learn and then implement for me unfortunately. But thanks for your help!

posted by L B 08 Apr 2019