CAN Filter and Mask Calculator
See which identifiers a CAN filter and mask admit, or derive the tightest filter for a list of IDs and the extras it lets through. Both mask conventions.
1 = compare this bit
Separated by spaces, commas or newlines. The result is the tightest single filter that admits all of them.
0x1000x7FC49 / 11200100000000111111111··Every identifier admitted (4):
0x1000x1010x1020x103What a CAN acceptance filter does
A CAN controller sees every frame on the bus. Acceptance filtering is the hardware deciding, before any interrupt fires, whether a frame is worth handing to the software. The test is one comparison:
(received_id XOR filter) AND mask == 0
Wherever the mask says to compare, the identifier must equal the filter. Wherever it says to ignore, the identifier can be anything. That is the whole mechanism, and everything awkward about filters follows from it being this simple.
The mask convention is not universal
Two families of parts disagree about what a mask bit of 1 means, and nothing in a hex value tells you which one you are holding:
- 1 compares — STM32 bxCAN, MCP2515, and most modern controllers. A mask of all ones matches exactly one identifier.
- 1 ignores — SJA1000 in PeliCAN mode and parts that follow it. A mask of all ones accepts everything.
The failure this causes is unhelpfully quiet. A mask taken from the wrong reference does not warn, does not error, and usually does not partially work: it either blocks everything or accepts everything, and both look like a wiring or bitrate problem long before anyone suspects the filter. Setting the convention is the first control on this page for that reason.
Why one filter cannot match an arbitrary list
A filter compares bit positions, not values. It can only compare a bit when every identifier you want agrees on it, and it must ignore any bit where they differ. That makes the tightest filter for a set unique — there is nothing to choose — and it makes a certain amount of waste unavoidable.
Take 0x100 and 0x200. They differ in two bit positions, so both must be ignored, and ignoring two bits admits four identifiers: 0x000, 0x100, 0x200 and 0x300. There is no filter and mask pair that accepts the two you asked for and rejects the two you did not. The only options are to accept the extra frames and discard them in software, or to use a second filter bank.
Contiguous aligned blocks are the happy case. 0x100 through 0x103 differ only in the low two bits, so a filter of 0x100 with the low two bits ignored admits exactly those four. This is why identifier schemes that allocate a node a block of consecutive IDs are easier to filter than schemes that scatter them, and it is worth knowing while the identifiers are still being assigned rather than afterwards.
Reading the result
The number that matters is how many identifiers the filter admits against how many you wanted. A filter admitting four to deliver two is usually fine — two spurious frames per cycle cost almost nothing. A filter admitting 512 to deliver five is a filter that is not doing its job, and on a loaded bus it will show up as interrupt load rather than as a functional bug.
When the waste is too high, the set has to be split. Group the identifiers that share bits, give each group its own filter bank, and check each one separately. If the controller offers list mode, a small scattered set fits there exactly, with no false accepts at all.
Filtering is load management, not validation
It is worth being clear about what a filter is for. It reduces the frames the CPU has to look at, which on a busy bus is the difference between a node that keeps up and one that drops messages. It is not a safety or security boundary: anything that passes the filter still has to be checked, and a hostile or faulty node can transmit any identifier it likes.
Nor does a filter change what is on the wire. Every node still receives every frame electrically, still participates in arbitration, and still signals errors. Filtering happens after all of that.
A note on counts
An open filter on extended identifiers admits 536,870,912 of them, and this page says so rather than rounding it off to "everything". The count is the honest measure of how much a filter is actually constraining, and on a 29-bit identifier the numbers get large quickly: ignoring ten bits already admits over a thousand identifiers. Listing them all is not useful, so the first thirty-two are shown and the total is stated exactly.
Frequently asked questions
My filter blocks every frame. What is wrong?
Check the mask convention first. On bxCAN and MCP2515 a mask bit of 1 means compare that bit; on the SJA1000 in PeliCAN mode a 1 means ignore it. A mask copied from the wrong datasheet inverts the meaning of every bit, and the usual result is a filter that compares bits the identifier was never going to match, so nothing arrives at all.
Why does my filter let through IDs I did not ask for?
Because a single filter can only compare bits that every wanted identifier agrees on. If two of them differ in a bit, that bit has to be ignored, and ignoring it admits both values for every other combination too. Ignoring k bits admits 2^k identifiers whether or not you wanted them all. The calculator reports that count so the cost is visible before the firmware ships.
How many filters do I have?
It depends on the controller. STM32 bxCAN provides 14 filter banks on single-CAN parts and 28 shared between two instances, each configurable as masks or as identifier lists. The MCP2515 has two masks and six filters split across two receive buffers. M_CAN parts expose a configurable number of standard and extended filter elements. Check the reference manual before assuming a set can be split.
Should I filter in hardware at all?
Yes, when the bus carries more traffic than the software needs. Every frame that passes the filter costs an interrupt and a buffer, and on a busy bus that is the difference between a responsive node and one that drops frames. Hardware filtering is not a security measure, though; it reduces load, and anything that gets through still has to be validated.
What is list mode?
Some controllers let a filter bank hold exact identifiers instead of a filter and mask pair. Where a wanted set is small and scattered, list mode accepts precisely those identifiers with no false accepts at all, which a mask cannot do. The trade is capacity: a bank holds only a few entries in list mode.
Can one filter cover both standard and extended identifiers?
Not meaningfully. The two identifier formats have different widths and controllers match them against separate filter configurations, with an IDE bit deciding which applies. Work out the standard filters and the extended filters separately, which is why the width is chosen here before anything else.
Related tools
- UART Baud Rate Error CalculatorDivisor, error margin, and register values — plus the clocks that divide exactly.
- Timer Prescaler & Period CalculatorPrescaler and reload splits ranked by PWM resolution, with the register values.
- CAN Bit Timing CalculatorSegments, sample point, and register values for classic CAN and CAN FD.