FlexCAN_T4 - FlexCAN for Teensy 4

so unneeded id's are bleeding through? and did you make sure all other mailboxes are setup, or refusing messages with exception ids, if a couple of message boxes have the same id & filter, other mailboxes may accept it if it fits their filter criteria
I put a few Serial print statement in your code to see what was going on in the
filter_match(FLEXCAN_MAILBOX mb_num, uint32_t id)

Something is getting garbled in

I am printing out the both sides of
id == mb_filter_table[mb_num][i+1]

When I do get a match I see

Got Frame CAN2
Engine_Demand_Percent_Torque: UINT32_T 0 -, Source_Address_of_Controller_Dev: UINT32_T 0 -, Engine_speed:896.0000 rpm, Actual_Engine_Percent_Torque:-125.0000 %, Drivers_Demand_Engine_Percent_To:-125.0000 %, Engine_and_Retarder_Torque_Mode: UINT32_T 0 -,

Everything is good.

When I don't see a match I get


ox18FED900 is the recieved ID
0x18FEFB03 is coming out of the filter table.

I have no idea where that comes from as my ID's assinged to MB are
CAN 2 RX MB Assignement(MB Type|MB#:ID)
4 : FF | 0 : 1CFEF803,1CFEF803/1 : 1CFEBE00,1CFEBE00
5 : FF | 2 : 1CECFF0B,1CECFF0B/3 : 1CECFF00,1CECFF00
6 : FF | 4 : 1CEBFF0B,1CEBFF0B/5 : 1CEBFF03,1CEBFF03
7 : FF | 6 : 1CEBFF00,1CEBFF00/7 : 18FF5800,18FF5800
8 : FF | 8 : 18FF5000,18FF5000/9 : 18FF4F00,18FF4F00
9 : FF | 10 : 18FF4E00,18FF4E00/11 : 18FF4D00,18FF4D00
10 : FF | 12 : 18FF3F00,18FF3F00/13 : 18FF3D00,18FF3D00
11 : FF | 14 : 18FF3C00,18FF3C00/15 : 18FF3B00,18FF3B00
12 : FF | 16 : 18FF3A00,18FF3A00/17 : 18FF3900,18FF3900
13 : FF | 18 : 18FF3800,18FF3800/19 : 18FF3700,18FF3700
14 : FF | 20 : 18FF3600,18FF3600/21 : 18FF3300,18FF3300
15 : FF | 22 : 18FF3018,18FF3018/23 : 18FF2A17,18FF2A17
16 : FF | 24 : 18FF2517,18FF2517/25 : 18FF2300,18FF2300
17 : FF | 26 : 18FF1702,18FF1702/27 : 18FF1002,18FF1002
18 : FF | 28 : 18FF1000,18FF1000/29 : 18FF0B00,18FF0B00
19 : FF | 30 : 18FF0A00,18FF0A00/31 : 18FF0900,18FF0900
20 : FF | 32 : 18FF0800,18FF0800/33 : 18FF0700,18FF0700
21 : FF | 34 : 18FF0300,18FF0300/35 : 18FF0200,18FF0200
22 : FF | 36 : 18FF0000,18FF0000/37 : 18FEFB03,18FEFB03
23 : FF | 38 : 18FEF117,18FEF117/39 : 18FEF10B,18FEF10B
24 : FF | 40 : 18FEF100,18FEF100/41 : 18FEEE00,18FEEE00
25 : FF | 42 : 18FEEB0B,18FEEB0B/43 : 18FEEB03,18FEEB03
26 : F0 | 44 : 18FEE518,18FEE518
27 : F0 | 45 : 18FEE203,18FEE203
28 : F0 | 46 : 18FEDF00,18FEDF00
29 : F0 | 47 : 18FEDA0B,18FEDA0B
30 : F0 | 48 : 18FEDA03,18FEDA03
31 : F0 | 49 : 18FED900,18FED900
32 : F0 | 50 : 18FECA0B,18FECA0B
33 : F0 | 51 : 18FECA03,18FECA03
34 : F0 | 52 : 18FEBF0B,18FEBF0B
35 : F0 | 53 : 18FEAE17,18FEAE17
36 : F0 | 54 : 18FE4B03,18FE4B03
37 : F0 | 55 : 18FE4A03,18FE4A03
38 : F0 | 56 : 18FDA403,18FDA403
39 : F0 | 57 : 18FDA400,18FDA400
40 : F0 | 58 : 18FD9503,18FD9503
41 : F0 | 59 : 18FD7C00,18FD7C00
42 : F0 | 60 : 18F00C03,18F00C03
43 : F0 | 61 : 18F00503,18F00503
44 : F0 | 62 : 18F0010B,18F0010B
45 : F0 | 63 : 18F00029,18F00029
46 : F0 | 64 : 18EF1817,18EF1817
47 : F0 | 65 : 18EF1718,18EF1718
48 : F0 | 66 : 18EF1700,18EF1700
49 : F0 | 67 : 18EF0503,18EF0503
50 : F0 | 68 : 18EF0017,18EF0017
51 : F0 | 69 : 18EEFF0B,18EEFF0B
52 : F0 | 70 : 18EEFF03,18EEFF03
53 : F0 | 71 : 18EAFF0B,18EAFF0B
54 : F0 | 72 : 18EAFF03,18EAFF03
55 : F0 | 73 : CFF0100,CFF0100
56 : F0 | 74 : CF00400,CF00400
57 : F0 | 75 : CF00300,CF00300
58 : F0 | 76 : CF00203,CF00203
59 : F0 | 77 : C01030B,C01030B
60 : F0 | 78 : C00290B,C00290B
61 : F0 | 79 : C000012,C000012
62 : F0 | 80 : C000003,C000003
63 : F0 | 81 : 8FE6E0B,8FE6E0B

I have a "0x18FEFB03" assigned to MB 22 but "0x8FED900" is assigned to MB 31.

Something is not correct with that? Wrong ID in the wrong table entry?

Again first set of ID come out the mb_filter_table[mb_num][i+1] the one after the "/" is "id".

I tried a doubled up MB9 which I have loaded ID's 0x18FF4E00 and 0x18FF4D00 into.
This is what I get out of the filter_match print statments:

Neither of the ID's stored in "mb_filter_table" are any of the id's which used for MB filter.

It looks like somehow some for stored ID's in "mb_filter_table" are getting 0x100 added and some are not?



Last edited:
See my next post...there are no duplicate ID's.

The point is I am receiving some messages but not others when enhanced filter is on.

Don't enable enhanced filter, it is received as expected.

I am "REJECT_ALL" before I am setting up each individual MB filter with one or two ID's

Going deeper on "mb_filter_table[mb_num][i+1]"

So just to make sure I was not messing something up I did this:
FCTP_FUNC bool FCTP_OPT::setMBFilter(FLEXCAN_MAILBOX mb_num, uint32_t id1, uint32_t id2) {
  if ( mb_num < mailboxOffset() || mb_num >= FLEXCANb_MAXMB_SIZE(_bus) ) return 0; /* mailbox not available */
  if ( (FLEXCAN_get_code(FLEXCANb_MBn_CS(_bus, mb_num)) >> 3) ) return 0; /* exit on TX mailbox */ 
  uint32_t mask = ( !(FLEXCANb_MBn_CS(_bus, mb_num) & FLEXCAN_MB_CS_IDE) ) ? FLEXCAN_MB_ID_IDSTD(((id1 | id2) ^ (id1 & id2)) ^ 0x7FF) : FLEXCAN_MB_ID_IDEXT(((id1 | id2) ^ (id1 & id2)) ^ 0x1FFFFFFF);
  filter_store(FLEXCAN_MULTI, mb_num, 2, id1, id2, 0, 0, 0);
  return 1;

And when I run the set up with this in place with my MB set up debugging enabled I get:

9 : FF | 10 : 18FF4E00,18FF4E00/11 : 18FF4D00,18FF4D00

Exactly what is expected.

Both "id1" and "id2" go into the function and are unaltered prior to entering
filter_store(FLEXCAN_MULTI, mb_num, 2, id1, id2, 0, 0, 0);

In my debug output the 9 means MB9, $FF means extended, double filter (nothing to do with any input into your code) . The 10 and 11 are first the id indexes for the message structure. The the "id1","id1"/"id2","id2" are showing the id1 entered into the "setMBFilter(" and that of the index stored in the MB structure ( am keeping track of what id indexes are applied to each MB filter).

So again, this is all good.

But when I send a frame with "0x18FF4E00" which is exactly what is stored in MB9.

As I said before I added print statement into your code for:
FCTP_FUNC volatile bool FCTP_OPT::filter_match(FLEXCAN_MAILBOX mb_num, uint32_t id) {
  if ( !(mb_filter_table[mb_num][0] & 0x10000000) ) return 1;
  if ( (mb_filter_table[mb_num][0] >> 29) == FLEXCAN_MULTI ) {
    for ( uint8_t i = 0; i < ((mb_filter_table[mb_num][0] & 0x380) >> 7); i++) 
		if ( id == mb_filter_table[mb_num][i+1] ) return 1;
  else if ( (mb_filter_table[mb_num][0] >> 29) == FLEXCAN_RANGE ) {
    if ( id >= mb_filter_table[mb_num][1] && id <= mb_filter_table[mb_num][2] ) return 1;
  else if ( (mb_filter_table[mb_num][0] >> 29) == FLEXCAN_USERMASK ) {
    for ( uint8_t i = 1; i < ((mb_filter_table[mb_num][0] & 0x380) >> 7) + 1; i++) {
      if ( (id & mb_filter_table[mb_num][5]) == (mb_filter_table[mb_num][i] & mb_filter_table[mb_num][5]) ) return 1;
  return 0;

I get the below:


What is being in "setMBFilter(" is not what is ending up in

I can the stored ID's get modified?


hmm that is indeed weird, yes if you want to try modifying the table move it from private to public, maybe after you set all the IDs and filters you can print out the table list so you can cross verify everything, I am not home to test this out but also try to make the table volatile, not sure if it will help but i would try to check what IDs we set are registered in the table and if it doesn't match it needs to be corrected. Like you said it works in one way but not another, which is weird, the IDs are not computed or modified in any way and should be put into the table for lookup as is, so if they are wrong, needs to be corrected
Well, the table is already volatile
volatile uint32_t mb_filter_table[64][6];

Will move public and see if I can get it to list out.

OK so after I finish assigning all the MB filters, I am listing out the message ID corresponding to the index(es) stored corresponding each MB.

cout << F("RX MB ") << dec << (uint16_t)(i);
        if (mb[j][i].single & MBSingEXTOffset) cout << F(" EXT");//Extended Recieve Frame
        else cout << F(" STD");//Starndard Recieve Frame
        cout << F(" ID: ");
        if ((mb[j][i].single & MBSingMultiOffset)) {
          cout << dec << (uint16_t)mb[j][i].StartMessage << F(":") << uppercase << hex << messages[j][mb[j][i].StartMessage].ID << F(",") << Can2.mb_filter_table[i][1] << F("/") << dec << (uint16_t)mb[j][i].EndMessage << F(":") << uppercase  << hex << messages[j][mb[j][i].EndMessage].ID << F(",") << Can2.mb_filter_table[i][2] << endl; //two ID Filter MB
        else cout << dec << (uint16_t)mb[j][i].StartMessage << F(":") << uppercase << hex << messages[j][mb[j][i].StartMessage].ID << F(",") << Can2.mb_filter_table[i][1]<< endl; //Single ID Filtered MB
      cout << endl;

I could not figure out how to go from Can2 to myCAN[1]-> When I tried putting the

virtual volatile uint32_t mb_filter_table[64][6] = 0;

Did not like it so I went with "Can2" for expeciancy.

CAN 2 RX MB Assignement(#:ID)
RX MB 4 EXT ID: 0:1CFEF803,1CFEF803/1:1CFEBE00,1CFEBE00
RX MB 7 EXT ID: 6:1CEBFF00,1CEBFF00/7:18FF5800,18FF5800
RX MB 8 EXT ID: 8:18FF5000,18FF5000/9:18FF4F00,18FF4F00
RX MB 9 EXT ID: 10:18FF4E00,18FF4E00/11:18FF4D00,18FF4D00
RX MB 10 EXT ID: 12:18FF3F00,18FF3F00/13:18FF3D00,18FF3D00
RX MB 11 EXT ID: 14:18FF3C00,18FF3C00/15:18FF3B00,18FF3B00
RX MB 12 EXT ID: 16:18FF3A00,18FF3A00/17:18FF3900,18FF3900
RX MB 13 EXT ID: 18:18FF3800,18FF3800/19:18FF3700,18FF3700
RX MB 14 EXT ID: 20:18FF3600,18FF3600/21:18FF3300,18FF3300
RX MB 15 EXT ID: 22:18FF3018,18FF3018/23:18FF2A17,18FF2A17
RX MB 16 EXT ID: 24:18FF2517,18FF2517/25:18FF2300,18FF2300
RX MB 17 EXT ID: 26:18FF1702,18FF1702/27:18FF1002,18FF1002
RX MB 18 EXT ID: 28:18FF1000,18FF1000/29:18FF0B00,18FF0B00
RX MB 19 EXT ID: 30:18FF0A00,18FF0A00/31:18FF0900,18FF0900
RX MB 20 EXT ID: 32:18FF0800,18FF0800/33:18FF0700,18FF0700
RX MB 21 EXT ID: 34:18FF0300,18FF0300/35:18FF0200,18FF0200
RX MB 22 EXT ID: 36:18FF0000,18FF0000/37:18FEFB03,18FEFB03
RX MB 23 EXT ID: 38:18FEF117,18FEF117/39:18FEF10B,18FEF10B
RX MB 24 EXT ID: 40:18FEF100,18FEF100/41:18FEEE00,18FEEE00
RX MB 25 EXT ID: 42:18FEEB0B,18FEEB0B/43:18FEEB03,18FEEB03
RX MB 26 EXT ID: 44:18FEE518,18FEE518
RX MB 27 EXT ID: 45:18FEE203,18FEE203
RX MB 28 EXT ID: 46:18FEDF00,18FEDF00
RX MB 30 EXT ID: 48:18FEDA03,18FEDA03
RX MB 31 EXT ID: 49:18FED900,18FED900
RX MB 33 EXT ID: 51:18FECA03,18FECA03
RX MB 35 EXT ID: 53:18FEAE17,18FEAE17
RX MB 36 EXT ID: 54:18FE4B03,18FE4B03
RX MB 37 EXT ID: 55:18FE4A03,18FE4A03
RX MB 38 EXT ID: 56:18FDA403,18FDA403
RX MB 39 EXT ID: 57:18FDA400,18FDA400
RX MB 40 EXT ID: 58:18FD9503,18FD9503
RX MB 41 EXT ID: 59:18FD7C00,18FD7C00
RX MB 42 EXT ID: 60:18F00C03,18F00C03
RX MB 43 EXT ID: 61:18F00503,18F00503
RX MB 44 EXT ID: 62:18F0010B,18F0010B
RX MB 45 EXT ID: 63:18F00029,18F00029
RX MB 46 EXT ID: 64:18EF1817,18EF1817
RX MB 47 EXT ID: 65:18EF1718,18EF1718
RX MB 48 EXT ID: 66:18EF1700,18EF1700
RX MB 49 EXT ID: 67:18EF0503,18EF0503
RX MB 50 EXT ID: 68:18EF0017,18EF0017
RX MB 52 EXT ID: 70:18EEFF03,18EEFF03
RX MB 54 EXT ID: 72:18EAFF03,18EAFF03
RX MB 55 EXT ID: 73:CFF0100,CFF0100
RX MB 56 EXT ID: 74:CF00400,CF00400
RX MB 57 EXT ID: 75:CF00300,CF00300
RX MB 58 EXT ID: 76:CF00203,CF00203
RX MB 59 EXT ID: 77:C01030B,C01030B
RX MB 60 EXT ID: 78:C00290B,C00290B
RX MB 61 EXT ID: 79:C000012,C000012
RX MB 62 EXT ID: 80:C000003,C000003
RX MB 63 EXT ID: 81:8FE6E0B,8FE6E0B

So if you look at MB9 it all looks good.

Again I send out 18FF4E00 the filter table entry is getting changed in between the entry and the message reception????

Set Up Done!


Last edited:
Got it, it is not matching on the correct MB;


It is supposed to match on MB9:

RX MB 8 EXT ID: 8:18FF5000,18FF5000/9:18FF4F00,18FF4F00
RX MB 9 EXT ID: 10:18FF4E00,18FF4E00/11:18FF4D00,18FF4D00

Even with some single frame filter is is missing the expected MB?

MB22 is hitting when it should be MB31
RX MB 31 EXT ID: 49:18FED900,18FED900

How can it get a single filtered MB wrong?


not sure I havn't faced this issue before or looked at it yet, ok, you dont need a base class if you use the template object directly to print the table, just make it public and use Can1.mb_filter_table[x][x] or whatever name you used in constructor

Think of the base class as a limited symbolic link to the constructor template object. The template object has full debug over the flexcan_t4 class but the base class only has selected functions which it could have access to.
distribute() seems to fix the issue.

With distribute and enhanced filter does it matter what ID I assign (via filter) to what MB?

Should I put the higher priority ID's (lower numerical value) to the lower numerical value MB's?

Does it matter?

Seems like I am banging on all cylinders!

Did stress test with ~23,400 frames giving ~ 117,285 signals/second. No overflows.



the lowest mailbox (granted they are free to receive) receives first, the last mailbox (if all full) always gets overridden if overflow occurs. If a message is destinated for one mailbox only, and no other mailboxes accept that same frame, then that mailbox will overflow and override the holding message

the SMB (serial message buffer, hardware) goes from small MB0 to largest MB64 to search for an acceptable free slot that is allowed to save a message to, if none accept it, the SMB tosses it to begin receiving next frame
OK, I have a new one.

I have some intermittent glitch in which CAN3 will not receive. I have all 3 CAN controllers receiving the same messages (on the same bus).

The scenario is that am reading in identical DBC files for CAN1 and CAN3. All my set up are is a loop so CAN1 and CAN3 use the exact same code to set everything up.

When I do this for CAN1/2/3 CAN1 or CAN2 does not have any issue... only CAN3.

Even when I just read in DBC files for CAN3 alone I have the same intermittent issue and it has something to do with the MB filtering. Because if I "accept_all" for filtering then I have no issues receiving frames.

So when I power up the controller and initialize everything I get nothing out of CAN3 (either by itself or in conjunction with the other two controllers). The other two controllers receive messages as expected.

But if after the power cycle and do not receive any messages from CAN I hit the "program button" and re-flash the same previously compiled code, CAN3 magically works.

This is very confusing to me and makes no sense what so ever.

Any ideas?'

Please note that within loop nothing happens until I receive CAN frames on one of the controllers. Each controller has it own call back that are all identical to each other except the CAN controller they point to.

Any help would be appreciated.


That is clearly odd, the hardware layout and code is identical on all 3 busses, perhaps you can try other things?

adjusting the can clock to max speed 60MHz,
try changing NVIC priority for CAN3?

I really doubt it is the software end otherwise the 2 first busses would expect the same thing, CAN3 did have an issue in FD mode if any of the LPUART clocks were disabled, it would lock up the entire cpu. Perhaps it's related as it's an issue on that part, however CAN2.0 legacy mode was fully supported with CAN3 as well with CAN 1,2.

Start playing with the clock, maybe lower or raise it, and change the priority of CAN3 to see if it works better

does it work sometimes or not at all with the filters?
wait, you said depending on how you power it up or use the button it can work? try to check the line termination or the bus state, I added bus reporting on github, i know you extended the library so maybe you can put those differences in your copy to see if the bus gives any details depending on how you power up and when it doesnt work etc

So when I power up the controller and initialize everything I get nothing out of CAN3 (either by itself or in conjunction with the other two controllers). The other two controllers receive messages as expected.

But if after the power cycle and do not receive any messages from CAN I hit the "program button" and re-flash the same previously compiled code, CAN3 magically works.

sounds like it went to bus-off and wont exit, can you also try another transceiver to make sure it's not at fault, as well as verify line termination 60ohms
Last edited:
#define CAN_Clock CLK_60MHz  //Enumeration for CAN clock speed.

try changing NVIC priority for CAN3?
How his this done?

does it work sometimes or not at all with the filters?
I used "accept_all" to determine is was something with the filter because if I accept all messages are always received. The MB filters work as expected for CAN1 and CAN2 but for CAN3 it acts as I described above.

try to check the line termination
60 ohms as expected (I have terminating resistors that can be enabled with jumper on the board.

try to check the line termination
One MCP2562FD removed...new MCP2562FD installed. Same result. Lucky everything on my board is DIP and socketed :cool:

I will look on github, implement and get back to you on what I find.


For get the previous post. Doesn't matter as soon as I power cycle the controller I do not get a interrupt call back from CAN3....really weird.
Last edited:
So just to confirm, for CAN3, it only shows this symptom only when using filtering, and works perfect otherwise?

I double checked the register locations and they are inlined same as other 2 controllers, so no issue there, maybe you found an errata, I'll have to dig the web to see if anyone else have this issue at nxp

Can you also add a little delay before setting up the controllers as a test? also change the order of their initialization, maybe init CAN3 first then the other 2, check if issue is same

do you experience this issue when only CAN3 is initialized and not the other 2?

EDIT: I don't see anything on the web, then again, they probably arn't using filtering or CAN3, we did find one time at the time it wasn't on the web that CAN3FD mode was LPUART dependant, perhaps you stumbled onto another errata, try to play with the steps above to see how it works out
Last edited:
I see the following new functions (notepad ++ compare):
bool error(CAN_error_t &error, bool printDetails); 
    Circular_Buffer<uint32_t, 16> busESR1;
    Circular_Buffer<uint16_t, 16> busECR;
    void printErrors(const CAN_error_t &error);

I know I am going to need to add "error" to the base class virtual like the other functions but what about the "private functions".

How would you suggest I proceed with this?


So just to confirm, for CAN3, it only shows this symptom only when using filtering, and works perfect otherwise?

Nope, I was wrong. I was mistaken by the re-flash vs power cycle.

I flashed with "accept_all" and confirmed all received frames were being accepted in MB 4. I power cycled the the controller and once again, no CAN3. CAN1 and CAN2 received all frames in MB4.

I re-flashed with the MB filtering scheme I used before and confirmed the frames were be accepted as expected within the MB indicated by the filtering set up for CAN1/2/3.

Power cycle...no CAN3 again but CAN1/2 were be accepted as expected within the MB indicated by the filtering set up.

So does not matter filtering or no filtering. CAN1/2/3 works as expected after re-flash but CAN3 disappears after the power cycle.

Why would reflash be different than a power cycle? This seems to be the common factor and it seems more to do with the interrupt setting and or calling the global call back.

Really really confusing....

Any guidance on the error message set up to work with myCAN[.]-> format.

I put the latest github version with the previous modification in arduiino 1.8.15/Teensyduino beta 10 with the necessary modifications to the header file.

do you experience this issue when only CAN3 is initialized and not the other 2?
Nope, CAN3 does it all by itself does the same thing.

I initialize in the following maner:

    myCAN[channel]->setBaudRate((bus[channel].BaudRate * 500));
    myCAN[channel]->setMaxMB(NUM_TX_MAILBOXES + Num_Tot_RX_MB);
Ideas how so switch the order?

Then I set up the TX/RX MB based on what is in the DBC file.
I set the filters for the RX filter based on how many messages are in the DBC. Basically either one or two ID are assigned to each MB (not using user filter)

After this is all done then I set the interrupts.

Is the a better order?

Anyways I will try some of the above suggestions tomorrow and get back to you.


Okay, so you can reproduce it. Basically a restart doesn't work but a reflash does, which is weird still.

I always reinitialize the registers whenever enableFIFO or begin() is called, so they are definately in a known state and not garbage.

Oh, don't set MaxMB last that basically un-do's what you set beforehand, run that basically right after begin before you configure because it reinits the hardware to limit the amount of mailboxes, and also comment out distribute temporarily to make sure that is not causing a conflict, hopefully not

you can just use the error in the base class, the functor will subcall it from private without issue.
Winner winner chicken dinner!

Moving the MaxMB to after begin did it!!

0.002171 2 0x18FF1000 8 0x00 0x00 0x01 0x32 0x00 0x00 0x00 0x00
0.002179 1 0x18FF1000 8 0x00 0x00 0x01 0x32 0x00 0x00 0x00 0x00
0.002187 0 0x18FF1000 8 0x00 0x00 0x01 0x32 0x00 0x00 0x00 0x00

3000 frames second. (1000 frames per second X 3 CAN controller)....8 micro seconds between frames....this thing is a beast!

Any examples for call the error functions?

Thanks for sticking with me.

yeah it's still open on github's issue tracker, a user requested it so i added it in

      CAN_error_t error; /* create a message struct to store the queue details, for data accesses */
      if ( Can1.error(error, 1) ) { // overload 1 means internally print everything in error event to serial monitor
        // Do Something...
        if ( error.ACK_ERR ) Serial.print("ACK error occured");
        if ( !strcmp(error.state, "Transmitting") ) Serial.println("TRANSMITTING!");

I've added the commits for error reporting, try it out :)
(me hot-plugging the esp32 and reconnecting)

FlexCAN State: Receiving, FLT_CONF: Error Active
FlexCAN State: Idle, FLT_CONF: Error Active
FlexCAN State: Transmitting, FLT_CONF: Error Active
FlexCAN State: Transmitting, ACK_ERR, FLT_CONF: Error Active
FlexCAN State: Transmitting, ACK_ERR, TX_WRN: 96, FLT_CONF: Error Active
FlexCAN State: Transmitting, ACK_ERR, TX_WRN: 104, FLT_CONF: Error Active
FlexCAN State: Transmitting, ACK_ERR, TX_WRN: 128, FLT_CONF: Bus off
FlexCAN State: Transmitting, TX_WRN: 127, FLT_CONF: Error Active
FlexCAN State: Transmitting, FLT_CONF: Error Active
FlexCAN State: Receiving, FLT_CONF: Error Active
FlexCAN State: Idle, FLT_CONF: Error Active
FlexCAN State: Transmitting, FLT_CONF: Error Active
can you please give usage example for ext_output1()

I use your sketch CAN2.0_example_FIFO_with_interrupts.ino and don't know how to do it right. Currently I have placed my code inside canSniff() which is probably not intended this way.

I have something to show meanwhile (it works but i don't like it)
ext_output1() is a background callback same as canSniff, it's intended for other libraries to access CAN data (isotp) without needing to add more sketch code to forward objects

putting your code in canSniff is correct way, if it gets too cluttered you could make sub function calls from the callback

bit more complex, you could also do individual mailbox filtering if you want each mailbox to receive a specific ID in it's own canSniff callback

KOMP_STELL should be volatile char
timeout should be volatile unsigned long, not long

variables that share both ISR (canSniff) and loop should be declared volatile, however,

if you are using Can.events(), voltaile is not needed. If you comment out events(), they should be volatile since theyll be from interrupt context
Last edited:
Thanks for that hints, really appreciate it!

Although I don't understand what Can.events() does I believe I should keep it in main. I added sub function and changed integer types as suggested, but when try to set volatile struct I get compiler warnings. If you know how to fix feel free to send me commit.

Have another issue with memcpy. I don't know how to map msg.buf into bit fields. It works fine with full bytes (uint8_t) and I receive KOMP_STELL correctly that means byte order is okay. I can even map single byte in little endian and receive bits (bool) for each 8-bit series in right order too. But it starts to fail for odd-numbered bit field size and empty paddings. I read here that we should use bit-wise operators instead, so I think I can throw my last commit into garbage.

Do you have any other template how to map msg.buf, for example bit-wise operator?
here is some example output of canSniff() https://pastebin.com/p4QuFHsn
i use something simple

msg.buf[1] & (1U << 3)

this gives you the bool at bit position 3 (from the right, of course)

1U basically checks if it matches if bit is set (unsigned), left shifted 3 times
So I am trying to figure out how to use the ISO-TP with the present frame work I have.

I am using the MB filtering to minimize the # of message ID (or a single ID if<60 ID's) that I have to search through so a maximum 2 ID assigned to a specific MB.

The ISO-TP config does not report MB nor does it report the bus to which call back is originated from.

The other issue there is broadcasted data on the same bus as the OBD data so for example mode 9 which requires iso-TP.

For ISO-TP "if ( msg.buf[0] <= 7 ) { /* single frame */ " but we have no idea what msg.buf[0] will be in the case of broad cast can data.

So not quite sure how we can have this implementation when there is broadcast data.

Please let me know you thoughts.