IFCT - Improved Flexcan Teensy Library

Status
Not open for further replies.
Good evening everyone. I've added yet another update to IFCT, FlexCAN_Library emulation, library is able to mimic both teachop/pawelsky's FIFO version and collin80's MB-only version.

Both emulations automatically switch based on demo selection, just load up collin80's/pawelsky's demos and you only have to do minor changes to demo:

1) Change FlexCAN.h to IFCT.h
2) Enable your transceiver if needed
3) enjoy.

I've also corrected a bug in pawelsky's/teachop's code when setting the filter after setup, the code doesn't take into consideration it may be out of freeze mode and does a hard fault. This is fixed in the emulation code

IFCT native methods may be called during emulation mode as well, this further enhances user's ability to use more features, like the automatic masking ability in emulation mode.
This can be referred to as hybrid mode

Tony
 
Last edited:
I’ve updated the library today with keywords.txt file as well as 2 demos from collin80 & pawelsky, with a little update to their output stream code. I’ll push more updates tomorrow when I get back home :)

Tony
 
New update, IFCT has been updated to include transmit buffering. The library will automatically queue your transfers and handle the transmitting for them automatically. This is also supported in emulation/hybrid mode.

Sending to a specific TX mailbox will be handled automatically by that function if you choose to use a specific mailbox for sending.
 
Hi Tony,
Paul (maker of the DualCAN board) here. Got your email and haven't had much time to go through this thread, until now.
Impressive work on the library! Can't wait to try it out.
 
Hi all, another new feature of IFCT is sequential transmit ordering. Your frames will be ordered on transmit irregardless if you have 1 TX mailbox, or if you have 16 TX mailboxes.

When writing to the write function, it will typically write accross your TX mailboxes before queueing up the extra frames when the TX buffers are full.

To use the sequential ordering, a bool was added to the CAN_message_t struct. To enable a message to use sequential writing, set it to 1 via "msg.seq = 1;" before doing Can0.write(msg);
It will check that the first hardware TX mailbox is busy or not, and write it directly if it isn't, otherwise it goes directly into the queue (even if you have other buffers available). Once the ISR fires a TX interrupt on that first TX mailbox and queue's sequential flag is set, the ISR will dequeue that frame specifically to that mailbox automatically.

By default,CAN_message_t has the seq flag set to 0 for normal TX mailbox distribution, followed by queueing should there be no TX buffers available, if your APP requires sequential frames, enable it when needed :)

This allows you to send normal and sequential frames dynamically from your program

Tony
 
Last edited:
I'm currently adding FIFO support to the acceptedID() acceptance filter since mailboxes are currently only implemented. I think I am pretty much done with table B then I will have to work on Tables A and C.
The acceptedID function lists the detailed information about your acceptance filter. When dealing with the FIFO tables, we also have to deal with offsets and partial masks. Example, in table B, a filter can contain 2 entries, standard containing a full mask, and the extended containing a partial mast of the 14 most significant bits checked. The details also include a list of acceptance criteria as well as your setFIFOFilter configuration details.

Here is a runtime example of the FIFO filter region being dumped and printed out

Code:
Can0.acceptedIDs(FIFO);

The output is below:

Code:
FIFO Table B: 
	Specifies an ID to be used as acceptance criteria for the FIFO. In the standard frame
	format, the 11 most significant bits (a full standard ID) (29 to 19 and 13 to 3) are used for
	frame identification. In the extended frame format, all 14 bits of the field are compared to
	the 14 most significant bits of the received ID.

  *** Filter[0] accepted IDs: 
		FILTER NOT SET! Currently set to reject all traffic


  *** Filter[1] accepted IDs: 
			min search: 0x18DC8000		max search: 0x18DCFFFF

			0x18DC8000	0x18DC8001	0x18DC8002	0x18DC8003	0x18DC8004	0x18DC8005
			0x18DC8006	0x18DC8007	0x18DC8008	0x18DC8009	0x18DC800A	0x18DC800B
			0x18DC800C	0x18DC800D	0x18DC800E	0x18DC800F	0x18DC8010	0x18DC8011
			0x18DC8012	0x18DC8013	0x18DC8014	0x18DC8015	0x18DC8016	0x18DC8017
			0x18DC8018	0x18DC8019	0x18DC801A	0x18DC801B	0x18DC801C	0x18DC801D
			0x18DC801E	0x18DC801F	0x18DC8020	0x18DC8021	0x18DC8022	0x18DC8023
			0x18DC8024	0x18DC8025	0x18DC8026	0x18DC8027	0x18DC8028	0x18DC8029
			0x18DC802A	0x18DC802B	0x18DC802C	0x18DC802D	0x18DC802E	0x18DC802F
			0x18DC8030	0x18DC8031	0x18DC8032	...

	Enhancement Disabled
		* Enhanced Multi-ID mode filtering:  0x18DCFFEA

			min search: 0x18DC8000		max search: 0x18DCFFFF

			0x18DC8000	0x18DC8001	0x18DC8002	0x18DC8003	0x18DC8004	0x18DC8005
			0x18DC8006	0x18DC8007	0x18DC8008	0x18DC8009	0x18DC800A	0x18DC800B
			0x18DC800C	0x18DC800D	0x18DC800E	0x18DC800F	0x18DC8010	0x18DC8011
			0x18DC8012	0x18DC8013	0x18DC8014	0x18DC8015	0x18DC8016	0x18DC8017
			0x18DC8018	0x18DC8019	0x18DC801A	0x18DC801B	0x18DC801C	0x18DC801D
			0x18DC801E	0x18DC801F	0x18DC8020	0x18DC8021	0x18DC8022	0x18DC8023
			0x18DC8024	0x18DC8025	0x18DC8026	0x18DC8027	0x18DC8028	0x18DC8029
			0x18DC802A	0x18DC802B	0x18DC802C	0x18DC802D	0x18DC802E	0x18DC802F
			0x18DC8030	0x18DC8031	0x18DC8032	...

	Enhancement Disabled
		* Enhanced Multi-ID mode filtering:  0x18DCFFEF


  *** Filter[2] accepted IDs: 
			min search: 0x0		max search: 0x7DE

			0x0	0x1	0x20	0x21	

	Enhancement Disabled
		* Enhanced Multi-ID mode filtering:  0x1 0x20

			min search: 0x0		max search: 0x7DF

			0x50	0x70	

	Enhancement Disabled
		* Enhanced Multi-ID mode filtering:  0x50 0x70


  *** Filter[3] accepted IDs: 
			min search: 0x0		max search: 0x7C0

			0x40	0x41	0x42	0x43	0x44	0x45
			0x46	0x47	0x48	0x49	0x4A	0x4B
			0x4C	0x4D	0x4E	0x4F	0x50	0x51
			0x52	0x53	0x54	0x55	0x56	0x57
			0x58	0x59	0x5A	0x5B	0x5C	0x5D
			0x5E	0x5F	0x60	0x61	0x62	0x63
			0x64	0x65	0x66	0x67	0x68	0x69
			0x6A	0x6B	0x6C	0x6D	0x6E	0x6F
			0x70	0x71	0x72	...

	Enhancement Disabled
		* Enhanced ID-range mode filtering:  0x55 <--> 0x66

			min search: 0x18DC8000		max search: 0x18DCFFFF

			0x18DC8000	0x18DC8001	0x18DC8002	0x18DC8003	0x18DC8004	0x18DC8005
			0x18DC8006	0x18DC8007	0x18DC8008	0x18DC8009	0x18DC800A	0x18DC800B
			0x18DC800C	0x18DC800D	0x18DC800E	0x18DC800F	0x18DC8010	0x18DC8011
			0x18DC8012	0x18DC8013	0x18DC8014	0x18DC8015	0x18DC8016	0x18DC8017
			0x18DC8018	0x18DC8019	0x18DC801A	0x18DC801B	0x18DC801C	0x18DC801D
			0x18DC801E	0x18DC801F	0x18DC8020	0x18DC8021	0x18DC8022	0x18DC8023
			0x18DC8024	0x18DC8025	0x18DC8026	0x18DC8027	0x18DC8028	0x18DC8029
			0x18DC802A	0x18DC802B	0x18DC802C	0x18DC802D	0x18DC802E	0x18DC802F
			0x18DC8030	0x18DC8031	0x18DC8032	...

	Enhancement Disabled
		* Enhanced ID-range mode filtering:  0x18DCFFEA <--> 0x18DCFFFF


  *** Filter[4] accepted IDs: 
		FILTER NOT SET! Currently set to reject all traffic


  *** Filter[5] accepted IDs: 
		FILTER NOT SET! Currently set to reject all traffic


  *** Filter[6] accepted IDs: 
		FILTER NOT SET! Currently set to reject all traffic


  *** Filter[7] accepted IDs: 
		FILTER NOT SET! Currently set to reject all traffic
 
Table A is finished, here is the output for it:

Code:
FIFO Table A: 
	Specifies an ID to be used as acceptance criteria for the FIFO. In the standard frame
	format, only the 11 most significant bits (29 to 19) are used for frame identification. In
	the extended frame format, all bits are used.

  *** Filter[0] accepted IDs: 
		FILTER NOT SET! Currently set to reject all traffic


  *** Filter[1] accepted IDs: 
		FILTER NOT SET! Currently set to reject all traffic


  *** Filter[2] accepted IDs: 
			[COLOR="#FF0000"]min search: 0x0		max search: 0x6[/COLOR]

			0x6	

	Enhancement Disabled
		* Enhanced Multi-ID mode filtering:  0x6 


  *** Filter[3] accepted IDs: 
			[COLOR="#FF0000"]min search: 0x11		max search: 0x77[/COLOR]

			0x44	0x45	0x46	0x47	0x54	0x55
			0x56	0x57	0x64	0x65	0x66	0x67
			0x74	0x75	0x76	0x77	

	Enhancement Disabled
		* Enhanced Multi-ID mode filtering:  0x55 0x66 


  *** Filter[4] accepted IDs: 
		FILTER NOT SET! Currently set to reject all traffic


  *** Filter[5] accepted IDs: 
			[COLOR="#FF0000"]min search: 0x18DCF8E8		max search: 0x18DCFFEB[/COLOR]

			0x18DCF8EA	0x18DCF8EB	0x18DCF9C2	0x18DCF9C3	0x18DCF9CA	0x18DCF9CB
			0x18DCF9E2	0x18DCF9E3	0x18DCF9EA	0x18DCF9EB	0x18DCFAC2	0x18DCFAC3
			0x18DCFACA	0x18DCFACB	0x18DCFAE2	0x18DCFAE3	0x18DCFAEA	0x18DCFAEB
			0x18DCFBC2	0x18DCFBC3	0x18DCFBCA	0x18DCFBCB	0x18DCFBE2	0x18DCFBE3
			0x18DCFBEA	0x18DCFBEB	0x18DCFCC2	0x18DCFCC3	0x18DCFCCA	0x18DCFCCB
			0x18DCFCE2	0x18DCFCE3	0x18DCFCEA	0x18DCFCEB	0x18DCFDC2	0x18DCFDC3
			0x18DCFDCA	0x18DCFDCB	0x18DCFDE2	0x18DCFDE3	0x18DCFDEA	0x18DCFDEB
			0x18DCFEC2	0x18DCFEC3	0x18DCFECA	0x18DCFECB	0x18DCFEE2	0x18DCFEE3
			0x18DCFEEA	0x18DCFEEB	0x18DCFFC2	...

	Enhancement Disabled
		* Enhanced Multi-ID mode filtering:  0x18DCF8EA 0x18DCFFC3 


  *** Filter[6] accepted IDs: 
		FILTER NOT SET! Currently set to reject all traffic


  *** Filter[7] accepted IDs: 
		FILTER NOT SET! Currently set to reject all traffic

I also increased the performance of the scans in table A to absolutely scan acceptance criteria within the masking region, it is much much faster now as you see above in RED. TableB has been updated with this improvement as well.


Here's the output of table B.
Code:
FIFO Table B: 
	Specifies an ID to be used as acceptance criteria for the FIFO. In the standard frame
	format, the 11 most significant bits (a full standard ID) (29 to 19 and 13 to 3) are used for
	frame identification. In the extended frame format, all 14 bits of the field are compared to
	the 14 most significant bits of the received ID.

  *** Filter[0] accepted IDs: 
		FILTER NOT SET! Currently set to reject all traffic


  *** Filter[1] accepted IDs: 
			[COLOR="#FF0000"]min search: 0x18DCFFE8		max search: 0x18DCFFFF[/COLOR]

			0x18DCFFE8	0x18DCFFE9	0x18DCFFEA	0x18DCFFEB	0x18DCFFEC	0x18DCFFED
			0x18DCFFEE	0x18DCFFEF	0x18DCFFF0	0x18DCFFF1	0x18DCFFF2	0x18DCFFF3
			0x18DCFFF4	0x18DCFFF5	0x18DCFFF6	0x18DCFFF7	0x18DCFFF8	0x18DCFFF9
			0x18DCFFFA	0x18DCFFFB	0x18DCFFFC	0x18DCFFFD	0x18DCFFFE	0x18DCFFFF
			

	Enhancement Disabled
		* Enhanced Multi-ID mode filtering:  0x18DCFFEA

			[COLOR="#FF0000"]min search: 0x18DCFFE8		max search: 0x18DCFFFF[/COLOR]

			0x18DCFFE8	0x18DCFFE9	0x18DCFFEA	0x18DCFFEB	0x18DCFFEC	0x18DCFFED
			0x18DCFFEE	0x18DCFFEF	0x18DCFFF0	0x18DCFFF1	0x18DCFFF2	0x18DCFFF3
			0x18DCFFF4	0x18DCFFF5	0x18DCFFF6	0x18DCFFF7	0x18DCFFF8	0x18DCFFF9
			0x18DCFFFA	0x18DCFFFB	0x18DCFFFC	0x18DCFFFD	0x18DCFFFE	0x18DCFFFF
			

	Enhancement Disabled
		* Enhanced Multi-ID mode filtering:  0x18DCFFEF


  *** Filter[2] accepted IDs: 
			[COLOR="#FF0000"]min search: 0x1		max search: 0x21[/COLOR]

			0x1	0x20	0x21	

	Enhancement Disabled
		* Enhanced Multi-ID mode filtering:  0x1 0x20

			[COLOR="#FF0000"]min search: 0x0		max search: 0x70[/COLOR]

			0x50	0x70	

	Enhancement Disabled
		* Enhanced Multi-ID mode filtering:  0x50 0x70


  *** Filter[3] accepted IDs: 
			[COLOR="#FF0000"]min search: 0x15		max search: 0x7F[/COLOR]

			0x40	0x41	0x42	0x43	0x44	0x45
			0x46	0x47	0x48	0x49	0x4A	0x4B
			0x4C	0x4D	0x4E	0x4F	0x50	0x51
			0x52	0x53	0x54	0x55	0x56	0x57
			0x58	0x59	0x5A	0x5B	0x5C	0x5D
			0x5E	0x5F	0x60	0x61	0x62	0x63
			0x64	0x65	0x66	0x67	0x68	0x69
			0x6A	0x6B	0x6C	0x6D	0x6E	0x6F
			0x70	0x71	0x72	...

	Enhancement Disabled
		* Enhanced ID-range mode filtering:  0x55 <--> 0x66

			[COLOR="#FF0000"]min search: 0x18DCFFE8		max search: 0x18DCFFFF[/COLOR]

			0x18DCFFE8	0x18DCFFE9	0x18DCFFEA	0x18DCFFEB	0x18DCFFEC	0x18DCFFED
			0x18DCFFEE	0x18DCFFEF	0x18DCFFF0	0x18DCFFF1	0x18DCFFF2	0x18DCFFF3
			0x18DCFFF4	0x18DCFFF5	0x18DCFFF6	0x18DCFFF7	0x18DCFFF8	0x18DCFFF9
			0x18DCFFFA	0x18DCFFFB	0x18DCFFFC	0x18DCFFFD	0x18DCFFFE	0x18DCFFFF
			

	Enhancement Disabled
		* Enhanced ID-range mode filtering:  0x18DCFFEA <--> 0x18DCFFFF


  *** Filter[4] accepted IDs: 
		FILTER NOT SET! Currently set to reject all traffic


  *** Filter[5] accepted IDs: 
		FILTER NOT SET! Currently set to reject all traffic


  *** Filter[6] accepted IDs: 
		FILTER NOT SET! Currently set to reject all traffic


  *** Filter[7] accepted IDs: 
		FILTER NOT SET! Currently set to reject all traffic
 
Last edited:
Here is the output when I call upon 3 mailboxes

Code:
  Can0.acceptedIDs(MB8);
  Can0.acceptedIDs(MB9);
  Can0.acceptedIDs(MB10);

Code:
Mailbox: 8
	In standard frame format, only the 11 most significant bits (28 to 18) are used for frame
	identification in both receive and transmit cases. The 18 least significant bits are ignored.
	In extended frame format, all bits are used for frame identification in both receive and
	transmit cases.

  *** MB8 accepted IDs: 
			[COLOR="#FF0000"]min search: 0x11		max search: 0x77[/COLOR]

			0x44	0x45	0x46	0x47	0x54	0x55
			0x56	0x57	0x64	0x65	0x66	0x67
			0x74	0x75	0x76	0x77	

	Enhancement Enabled
		* Enhanced Multi-ID mode filtering:  0x55 0x66 


Mailbox: 9
	In standard frame format, only the 11 most significant bits (28 to 18) are used for frame
	identification in both receive and transmit cases. The 18 least significant bits are ignored.
	In extended frame format, all bits are used for frame identification in both receive and
	transmit cases.

  *** MB9 accepted IDs: 
			[COLOR="#FF0000"]min search: 0x18DCFFE0		max search: 0x18DCFFFF[/COLOR]

			0x18DCFFE0	0x18DCFFE1	0x18DCFFE2	0x18DCFFE3	0x18DCFFE4	0x18DCFFE5
			0x18DCFFE6	0x18DCFFE7	0x18DCFFE8	0x18DCFFE9	0x18DCFFEA	0x18DCFFEB
			0x18DCFFEC	0x18DCFFED	0x18DCFFEE	0x18DCFFEF	0x18DCFFF0	0x18DCFFF1
			0x18DCFFF2	0x18DCFFF3	0x18DCFFF4	0x18DCFFF5	0x18DCFFF6	0x18DCFFF7
			0x18DCFFF8	0x18DCFFF9	0x18DCFFFA	0x18DCFFFB	0x18DCFFFC	0x18DCFFFD
			0x18DCFFFE	0x18DCFFFF	

	Enhancement Enabled
		* Enhanced Multi-ID mode filtering:  0x18DCFFE2 0x18DCFFE7 


Mailbox: 10
	In standard frame format, only the 11 most significant bits (28 to 18) are used for frame
	identification in both receive and transmit cases. The 18 least significant bits are ignored.
	In extended frame format, all bits are used for frame identification in both receive and
	transmit cases.

  *** MB10 accepted IDs: 
			[COLOR="#FF0000"]min search: 0x18DCFEC8		max search: 0x18DCFFFF[/COLOR]

			0x18DCFEC8	0x18DCFEC9	0x18DCFECA	0x18DCFECB	0x18DCFECC	0x18DCFECD
			0x18DCFECE	0x18DCFECF	0x18DCFED0	0x18DCFED1	0x18DCFED2	0x18DCFED3
			0x18DCFED4	0x18DCFED5	0x18DCFED6	0x18DCFED7	0x18DCFED8	0x18DCFED9
			0x18DCFEDA	0x18DCFEDB	0x18DCFEDC	0x18DCFEDD	0x18DCFEDE	0x18DCFEDF
			0x18DCFEE0	0x18DCFEE1	0x18DCFEE2	0x18DCFEE3	0x18DCFEE4	0x18DCFEE5
			0x18DCFEE6	0x18DCFEE7	0x18DCFEE8	0x18DCFEE9	0x18DCFEEA	0x18DCFEEB
			0x18DCFEEC	0x18DCFEED	0x18DCFEEE	0x18DCFEEF	0x18DCFEF0	0x18DCFEF1
			0x18DCFEF2	0x18DCFEF3	0x18DCFEF4	0x18DCFEF5	0x18DCFEF6	0x18DCFEF7
			0x18DCFEF8	0x18DCFEF9	0x18DCFEFA	...

	Enhancement Enabled
		* Enhanced ID-range mode filtering:  0x18DCFECC <--> 0x18DCFFEA
 
The acceptance filter printout has been updated on github: https://github.com/tonton81/IFCT/commit/01c373331523bb3aeeb112e6af6ed1f0f3a017c8

Due to the amount of IDs that could be captured in TableC using a quad ID per filter (and they use only the 8 most significant bits), laying out tables would be pretty pointless. You'll either benefit from software filtering, or enabling enhance mode to capture those specific IDs.
Note: filtering through callback is possible (software) however all frames that match the hardware mask would be queued. However, using enhanced Mailboxes/FIFO, IFCT only fills your queue with what you requested, and not what the mask passes through. This allows your queues not to be bloated or filled with "junk" frames you don't need.

Mailboxes, and FIFO TableA & TableB have a good layout on the acceptance filtering setup.

Tony
 
I uploaded a few very simple demo's to help people get up and running using the native functions of IFCT, using interrupts or polling as well.

Code:
 	IFCTsimpleFIFOPolling
	IFCTsimpleFIFOwithInterrupt
	IFCTsimpleMBPolling
	IFCTsimpleMBwithInterrupt
 
Awesome work Mike! :)

Hey everyone I'm currently writing a CAN sniffer to help reverse engineer vehicle data using the console screen, the data is very smooth, ordered, and I even added a count for the catched frames, so when your testing vehicle messages you can see the incremental counter increase to help find results faster :)

I send it random IDs from a teensy 3.2 between 50 and 64 range inclusively, the output is below.

https://www.youtube.com/watch?v=lk7fk_0nxfQ

The nice thing about this is, some modules don't always send frames consistantly. If you let this run, you will catch those IDs whenever they do decide to send.
Console demo shown is on a T3.6 sniffer with a T3.2 random sender
 
Added another demo of IFCT sniffer using Serial as input.
Led toggles on every input.

https://github.com/tonton81/IFCT/bl...snifferSerialInput/IFCTsnifferSerialInput.ino

Valid inputs are:

Code:
H<enter>                        // (HEX) Show values in HEX format
D<enter>                        // (DEC)Show values in DEC format
R<enter>                        // (RESET) Resets the buffer to start new capture, on main screen
M<enter>                       // (MAIN) Goes back to main output
O<space><hex can ID><enter>    // (OPEN) Display last entries for a specific CAN ID in the main output list. If the ID does not appear on the list, the page won't activate.


Output when started, and running "O 0x36"
Code:
   Lastest results for CAN ID: 0x36	  ID hit count: 141
	DATA[0]	DATA[1]	DATA[2]	DATA[3]	DATA[4]	DATA[5]	DATA[6]	DATA[7]	
	 0xAC	 0x9F	 0xD7	 0x67	 0x3C	 0x9C	 0x58	 0x8C	 
	 0x88	 0xDF	 0xE5	 0x91	 0xC6	 0x88	 0xD1	 0xB1	 
	 0x51	 0x43	 0xA2	 0x3B	 0x1D	 0x69	 0x1F	 0x0E	 
	 0x2E	 0x39	 0x86	 0x88	 0x5F	 0xCC	 0x88	 0xF1	 
	 0x2C	 0x72	 0xD4	 0x4D	 0xEF	 0x81	 0x80	 0x52	 
	 0xE4	 0x3F	 0xBC	 0xAB	 0x04	 0xAD	 0xB5	 0xB2	 
	 0x9C	 0xAF	 0x83	 0x80	 0x76	 0x37	 0x26	 0x3E	 
	 0xAA	 0xC4	 0xEF	 0x35	 0x02	 0x67	 0x78	 0x1E	 
	 0xE4	 0x9C	 0x30	 0x74	 0x8C	 0x7A	 0x10	 0xB6	 
	 0xBD	 0x14	 0x6D	 0x7E	 0x13	 0x3B	 0x38	 0x80	 
	 0xCE	 0xEC	 0x1A	 0x61	 0x83	 0xA0	 0x52	 0x34	 
	 0x3B	 0x3D	 0x1C	 0x01	 0xF7	 0x33	 0x00	 0x19	 
	 0xE6	 0x39	 0x4D	 0x25	 0xD7	 0xB9	 0x4B	 0x12	 
	 0xE3	 0x3C	 0xDA	 0x61	 0xF0	 0x95	 0xA3	 0xF0	 
	 0x4C	 0x6A	 0x5C	 0x10	 0x78	 0xA6	 0xCA	 0x62	 
	 0xDE	 0x4D	 0xF3	 0x16	 0x4D	 0x65	 0x52	 0xDD

pressing "D":
Code:
   Lastest results for CAN ID: 0x36	  ID hit count: 169
	DATA[0]	DATA[1]	DATA[2]	DATA[3]	DATA[4]	DATA[5]	DATA[6]	DATA[7]	
	 234	 12	 62	 183	 233	 232	 191	 248	 
	 168	 45	 174	 159	 115	 79	 172	 217	 
	 236	 7	 195	 133	 254	 199	 167	 178	 
	 74	 144	 182	 185	 89	 207	 77	 130	 
	 233	 107	 65	 18	 50	 199	 187	 203	 
	 253	 5	 59	 99	 84	 157	 252	 33	 
	 236	 140	 58	 122	 112	 191	 139	 71	 
	 248	 146	 240	 67	 136	 35	 35	 146	 
	 98	 130	 73	 46	 40	 60	 126	 106	 
	 135	 213	 31	 98	 196	 79	 208	 220	 
	 102	 162	 132	 8	 244	 225	 154	 211	 
	 46	 209	 28	 250	 116	 39	 54	 142	 
	 84	 116	 206	 217	 171	 249	 167	 245	 
	 175	 141	 42	 52	 31	 87	 233	 35	 
	 135	 159	 64	 205	 165	 223	 112	 63	 
	 100	 65	 203	 63	 183	 72	 66	 108

For last entries, newest are at top, going to oldest at bottom
 
Last edited:
I just added binary support to the CAN sniffer (B<enter>), this allows you to see the data as binary allowing you to see the exact bits being toggled when reverse engineering vehicles. This is alot easier to see than watching numbers jump in wide gaps trying to pinpoint data..

https://github.com/tonton81/IFCT/commit/32523b4652b42d49f431766179752cc3e0f87e85

output:

Code:
	CAN ID	   DATA[0]	   DATA[1]	   DATA[2]	   DATA[3]	   DATA[4]	   DATA[5]	   DATA[6]	   DATA[7]	COUNT
    0x00000032	 0b10011000	 0b10011100	 0b00011101	 0b10110101	 0b11101100	 0b00000100	 0b10010100	 0b01111011	 87	 
    0x00000033	 0b00101111	 0b00001010	 0b10100111	 0b00110011	 0b10111011	 0b00001111	 0b10110011	 0b11110011	 111	 
    0x00000034	 0b00011011	 0b10100001	 0b10000101	 0b01011110	 0b11111110	 0b00110001	 0b10100100	 0b01001100	 111	 
    0x00000035	 0b10101001	 0b01001100	 0b10000001	 0b10111001	 0b10011101	 0b00001011	 0b01111111	 0b01111011	 98	 
    0x00000036	 0b00111100	 0b01100001	 0b00001001	 0b10011101	 0b11001100	 0b00000100	 0b10011011	 0b11010000	 102	 
    0x00000037	 0b01011011	 0b01011001	 0b00101101	 0b00001011	 0b01010111	 0b01011001	 0b01101010	 0b00100101	 95	 
    0x00000038	 0b01001100	 0b11100011	 0b00011000	 0b11010000	 0b01000110	 0b11010010	 0b11010000	 0b10010011	 81	 
    0x00000039	 0b01111011	 0b11110000	 0b01001010	 0b10101010	 0b00100100	 0b11101010	 0b10001001	 0b00101010	 100	 
    0x0000003A	 0b01101011	 0b00111101	 0b01011100	 0b01001111	 0b01110111	 0b01110111	 0b11000110	 0b01100110	 100	 
    0x0000003B	 0b01100010	 0b00100110	 0b11001111	 0b10111010	 0b01101100	 0b10000011	 0b00101111	 0b01001101	 95	 
    0x0000003C	 0b10101001	 0b01100011	 0b11001110	 0b01111011	 0b01011001	 0b11001000	 0b01100000	 0b11001010	 109	 
    0x0000003D	 0b10100110	 0b01000100	 0b10001011	 0b00000101	 0b01011010	 0b10010110	 0b11001001	 0b01111110	 103	 
    0x0000003E	 0b01110110	 0b10110100	 0b10110111	 0b10001001	 0b10011100	 0b00101101	 0b11000101	 0b10011110	 97	 
    0x0000003F	 0b01100010	 0b11100100	 0b00100010	 0b01110010	 0b01000001	 0b11011100	 0b10011111	 0b11100101	 98	 
    0x00000040	 0b00001010	 0b11110001	 0b01100001	 0b11101011	 0b11111011	 0b01011011	 0b11011010	 0b11011010	 90
 
IFCT sniffer demo has been updated with more helpful prints!

1) ASCII text is now shown in both <M>ain and <O>pen modes.

2) Time between frames is listed now to show how often the frame is triggered.

3) <T> <val> was added (TRIMMING), which would hide frames that don't broadcast within a set timeframe. This allows inactive IDs to drop from the printouts when looking for active ones to list.
Ex. T 2000 // this would not list IDs that take more than 2 seconds between updates, everything else would show on the active list

4) <I> <val> was added (IGNORE), might be a useful feature. Turn your vehicle on and let it run for about a few minutes. Once the active ID list populates a count (lets say they're above 1000), activate the <I>gnore function with:
Code:
I 1000<enter>
This would hide the IDs with the high counters while your anxiously ready to get captured data. Start turning your steering wheel, pushing radio buttons, door locks, blinkers, handbrake, etc and see what pops up :)

Main output currently :

Code:
	CAN ID	DATA[0]	DATA[1]	DATA[2]	DATA[3]	DATA[4]	DATA[5]	DATA[6]	DATA[7]	COUNT	  TIME		ASCII
    0x00000032	 0x77	 0xA7	 0x96	 0x84	 0x6D	 0x32	 0x7C	 0x31	 636	 3662	 	w§–„m2|1
    0x00000033	 0xB7	 0xA4	 0xA7	 0x65	 0x34	 0x77	 0x59	 0xB1	 573	 9157	 	·¤§e4wY±
    0x00000034	 0xA8	 0x8D	 0x94	 0x22	 0x7D	 0x01	 0xA1	 0xC4	 612	 813	 	¨�”"}¡Ä
    0x00000035	 0xEA	 0xF2	 0xF2	 0xDF	 0x6D	 0xA5	 0xB9	 0xED	 649	 600	 	êòòßm¥¹í
    0x00000036	 0x99	 0xA3	 0x01	 0x72	 0xF8	 0x38	 0x84	 0x10	 628	 8342	 	™£rø8„
    0x00000037	 0xF1	 0xD9	 0x64	 0x90	 0x92	 0x94	 0x0B	 0xCA	 639	 2439	 	ñÙd�’”Ê
    0x00000038	 0x50	 0xF7	 0xD5	 0x21	 0xA0	 0x89	 0xAF	 0xE7	 662	 2848	 	P÷Õ!*‰¯ç
    0x00000039	 0x52	 0x09	 0xF1	 0xF5	 0x0D	 0xB3	 0x71	 0xC2	 676	 2840	 	Rñõ³qÂ
    0x0000003A	 0xAA	 0x8C	 0xE8	 0x08	 0xC7	 0x26	 0xCD	 0x78	 588	 820	 	ªŒèÇ&Íx
    0x0000003B	 0xBB	 0xEF	 0x36	 0xF6	 0x5F	 0x05	 0x84	 0xD5	 644	 4467	 	»ï6ö_„Õ
    0x0000003C	 0xD3	 0xE6	 0xC7	 0x06	 0x47	 0x01	 0x03	 0x87	 597	 4288	 	ÓæÇG‡
    0x0000003D	 0x89	 0x0B	 0x38	 0xB1	 0x66	 0x10	 0x3E	 0xFD	 602	 1227	 	‰8±f>ý
    0x0000003E	 0x84	 0x28	 0xA5	 0xB7	 0x04	 0x3F	 0x18	 0xC0	 646	 3470	 	„(¥·?À
    0x0000003F	 0x3B	 0x18	 0x47	 0xE9	 0xD2	 0x94	 0x79	 0x34	 615	 5092	 	;GéÒ”y4
    0x00000040	 0xD6	 0x1D	 0xC5	 0x80	 0x06	 0x76	 0xFC	 0xE5	 619	 2647	 	ÖÅ€vüå

Added video of output and some usage:

https://www.youtube.com/watch?v=VT4it1r-ohA

Also like to note the code runs 24/7 when im not home, so it's pretty solid :)
 
Last edited:
Pretty impressive. Ill be checking your library soon.

I doubt you'll ever pull me away from Linux + can-utils and python programming for analysis, but for live gateway routing and manipulating data in a car, this is a great solution with the fusion add-on boards.

What i use for analysis is here:
https://youtu.be/tNAmKgHUyyw
 
1) Fixed output with <B>INary numbers showing where Time was represented as <B>INary instead of <D>ECimal.

2) Added <W>indow spacing support, to look more like a console by having the text shifted up instead of down.

3) Added output reprint when calling commands for an immediate refresh instead of on next CANID capture.

shows the console being padded to look more like a terminal, easy to see data flow :)
https://www.youtube.com/watch?v=kE7Ko_spAi4

doing a <R>eset shows how the console doesn't jump anywhere when the list is cleared and re-populated
https://www.youtube.com/watch?v=izRzoVOu4Eg
 
Got the Backpack Reading Can0 as well as Can1 successfully. here's the code to initialize the information and setup in IFCTsnifferSerialInput . just copy and paste before the loop in the file if necessary for anyone interested.

now i need to understand sending packets, routing packets from bus 0 to bus1 and vise versa, defining variables from bus packets, and collaborating it all together.

Special thanks to tonton81 for helping me understand some key information, like the enable pins haha.

Code:
#include <IFCT.h>
const int can0_enable = 28;  // defines can0 enable pin, pin 28, as can0_enable
const int can1_enable = 35;  // defines can1 enable pin, pin 35, as can1_enable


#define CB_SIZE 16
#define DATA_LEN 12


Circular_Buffer<uint32_t, CB_SIZE> ids;
Circular_Buffer<uint32_t, CB_SIZE, DATA_LEN> storage;
Circular_Buffer<uint32_t, CB_SIZE, DATA_LEN> last_entries;


uint8_t option = 0;
uint8_t format = HEX;
uint32_t last_id = 0;
uint32_t timer_frame = millis();
uint32_t trim_frames = 0;
uint16_t ignore_count = 0;


void setup() {




  pinMode(can0_enable, OUTPUT);  // for the can0 transceiver enable pin
  digitalWrite(can0_enable, LOW);  // can0 enable pin needs to be low to receive messages
  Can0.setRX(ALT);  // sets Rx alternate pin for fusion 360 dual can backpack
  Can0.setTX(ALT);  // sets Tx alternate pin for fusion 360 dual can backpack
  Can0.setBaudRate(1000000);
  Can0.enableFIFO();
  Can0.enableFIFOInterrupt();
  Can0.onReceive(canSniff);
  Can0.intervalTimer(); // enable queue system and run callback in background.


  pinMode(can1_enable, OUTPUT);  // for the can1 transceiver enable pin
  digitalWrite(can1_enable, LOW);  // can1 enable pin needs to be low to receive messages
  Can1.setRX();  // sets Rx alternate pin for fusion 360 dual can backpack
  Can1.setTX();  // sets Tx alternate pin for fusion 360 dual can backpack
  Can1.setBaudRate(1000000);
  Can1.enableFIFO(1);
  Can1.enableFIFOInterrupt(1);
  Can1.onReceive(canSniff);
  Can1.intervalTimer(); // enable queue system and run callback in background.
}
 
Since you have both controllers going to the same callback, you may differentiate the messages using msg.bus

Ex, to setup a 2-way gateway between 2 busses at same or different speeds a single line is all thats needed in the callback:

Code:
( msg.bus ) ? Can0.write(msg) : Can1.write(msg);

you may also copy the msg and modify it then send the modified frame after:

Code:
CAN_message_t modded_msg = msg;
modded_msg.buf[0] = 0x50;
modded_msg.id = 0x18DCFFEA;
( modded_message.bus ) ? Can0.write(modded_message) : Can1.write(modded_msg);
 
IFCT comes back with yet another new update, with a custom protocol in development and testing.

The library now (IFCT) has weak functions, one for events(), and one for raw canbus output (after the hardware filters) that go directly to the 3rd party library. This allows external libraries to develop CAN protocols to immediately gain access to the stream without changing how you control your IFCT configurations. One will be demonstrated a few notes down that currently uses this feature.

the weak function of events() allows the other libraries to hook onto the internal IFCT events() function by overriding the external one implemented in IFCT. This allows CAN libraries to run background process with Can0.events(), be it via loop(), interval Timer, or teensyThreads.

The protocol I've worked on is similar to how SPI_MST callbacks work, Mike & I decided to give it the name CANquitto.

CANquitto is a 2-way multi-node communication link over CAN. It's current abilities are as follows:

1) Payloads can be sent to any node on the network in the 1-127 ID range, which is capable of sending up to 255 bytes to a callback currently on the other node.
2) The frames can be received in any order, the library automatically orders them and creates the array needed for the node's callback.
3) Upon a CRC validated full array transfer, the node ACKnowleges the receipt to the sender. This is done via interrupt so the sender receives the update before even exiting the write() function. a return of 1 for write means the send was a success.
4) 2 or more nodes can send requests at once, no need to take turns.
5) After further tests if progress looks good, teensy controls will be added for analog/gpio etc

Currently CANquitto is in testing stages, using the 2-way send data -> node and send ACK back to sender , so while write() returns 1 for all successes, using that to toggle a led on and off every second while sending a 34 byte array over CAN every second.


Sketches are pretty clean, once you have your IFCT setup, you only need to add these to the code:

Code:
...
#include <CANquitto.h>
...
->setup() {
...
Node.begin(112);
Node.onReceive(myCallback);
...
}
->loop() {
... //millis() timer 1 sec

uint8_t myArray[34] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34 };
pinMode(13, OUTPUT);
if (Node.write(myArray, sizeof(myArray), 123)) digitalWrite(13, !digitalRead(13));
...
}
...
//callback
void myCallback(const uint8_t* buffer, uint16_t length, AsyncCQ info) {
  Serial.print("PAYLOAD!!: ");
  for ( uint8_t i = 0; i < length; i++ ) {
    Serial.print(buffer[i]); Serial.print(" ");
  } Serial.println();
  Serial.print("From Node: ");
  Serial.println(info.node);
}
...

The output of the other node callback:

Code:
PAYLOAD!!: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 
From Node: 112
 
Last edited:
Hello...
I use your IFCT library... and Ilike IFCT...
1. I tested only can0 function everyday. It's OK.
2. next I try can0 and can1.
- can0 500kbps, golbal callback function is Flexcan_CAN0_RX
- can1 1Mbps, golbal callback function is Flexcan_CAN1_RX

but only called Flexcan_CAN1_RX. Callback function is not separate.
so I ask you. Do you plan to isolate the callback function?

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
Can0.setBaudRate( 500000 );
Can0.enableFIFO( 1 );
Can0.enableFIFOInterrupt( 1 );

Can0.setFIFOFilter( REJECT_ALL );
Can0.setFIFOFilter( 0, 0x412, STD );
Can0.setFIFOFilterRange( 1, 0x700, 0x710, STD );
Can0.enhanceFilter( FIFO );

Can0.onReceive( IFCT_CAN0_RX );
Can0.intervalTimer();

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
Can1.setBaudRate( 1000000 );
Can1.enableFIFO( 1 );
Can1.enableFIFOInterrupt( 1 );

Can1.setMBFilter( REJECT_ALL );
Can1.setFIFOFilter( REJECT_ALL );
Can1.setFIFOFilter( 0, 0x412, STD );
Can1.setFIFOFilterRange( 1, 0x700, 0x710, STD );
Can1.enhanceFilter( FIFO );

Can1.onReceive( IFCT_CAN1_RX );
Can1.intervalTimer();


- My solution is
void IFCT_CAN1_RX( const CAN_message_t &msg )
{
if( msg.bus == 0 )
{
//call can0 callback function
IFCT_CAN0_RX( msg );
}
else
{
//can1 callback
..........................
}
}


Thank you very much. Tony(tonton81)
 
yes ill keep notes and fix later to separate the callbacks for can0 and 1.

you could also do a msg.bus to show which bus it came from from the callback currently (which you already did), ill try to have it patched today when i get home

thanks for the feedback
 
Last edited:
Status
Not open for further replies.
Back
Top