FlexCAN_T4 - FlexCAN for Teensy 4

Houston, I think I found the problem...

I am using "AUD_MCLK" for CRX1 and SPI_SCOPI for CTX1. But I think I missed the part which I need to use can1.setTX(alt). I was thinking some how I was missing the ACK from CAN1 not this makes sense! So you are using can1.setTX(11)?

What is "McLean"?

Thanks
 
Oops typing on my phone and missed the auto correct. Should read MCLK. Yes you have to use the alt pin for tx. The primary pin is not brought out on the TMM. Somewhere on the TMM thread I posted a picture of atp carrier with the T41 pin equivalents
 
Yes you have to use the alt pin for tx. The primary pin is not brought out on the TMM. Somewhere on the TMM thread I posted a picture of atp carrier with the T41 pin equivalents

!!!! I made my own Teensy MM carrier board and I was shocked to hear this. I checked all three CAN buses to work perfectly well. Checking the schematics, CAN1 is normally found on Teensy 4.1 pins 22 and 23 which are A8 and A9. Checking the MM schematic, A8 and A9 are exposed on the pins of the M.2 socket. A8 at pin 49, A9 at pin 58. This is how I have my CAN1 hooked up on my custom board. It sure seems to work fine. So, I assume you mean that the primary pin is not brought out on the carrier board you are using. This is different from not being brought out at all (which many pins are indeed not brought out anywhere). I just checked the ATP schematic and it seems they really did tie that pin to VIN with a voltage divider. But, this is not the case on the actual TMM itself. Nothing stopped me from using that pin for CAN1 directly.

So, just to be clear, so far as my experience goes, and according to the schematic, there is no reason that a custom carrier board cannot use CAN1 directly without the use of alternate pins. In fact, all three CAN buses are directly able to be connected with no problems.
 
Last edited:
Oops typing on my phone and missed the auto correct. Should read MCLK. Yes you have to use the alt pin for tx. The primary pin is not brought out on the TMM. Somewhere on the TMM thread I posted a picture of atp carrier with the T41 pin equivalents

The pin out picture shows COPI as CTX1 but does not say anything about need to use alt pin definition for to use COPI you need to can1.setTX(11)?

Also, where do you call it? Before begin? After begin?

Thanks
 
Last edited:
!!!! I made my own Teensy MM carrier board and I was shocked to hear this. I checked all three CAN buses to work perfectly well. Checking the schematics, CAN1 is normally found on Teensy 4.1 pins 22 and 23 which are A8 and A9. Checking the MM schematic, A8 and A9 are exposed on the pins of the M.2 socket. A8 at pin 49, A9 at pin 58. This is how I have my CAN1 hooked up on my custom board. It sure seems to work fine. So, I assume you mean that the primary pin is not brought out on the carrier board you are using. This is different from not being brought out at all (which many pins are indeed not brought out anywhere). I just checked the ATP schematic and it seems they really did tie that pin to VIN with a voltage divider. But, this is not the case on the actual TMM itself. Nothing stopped me from using that pin for CAN1 directly.

So, just to be clear, so far as my experience goes, and according to the schematic, there is no reason that a custom carrier board cannot use CAN1 directly without the use of alternate pins. In fact, all three CAN buses are directly able to be connected with no problems.

You are absolutely correct. If you design your own carrier board the actual TMM processor has pins 22/23 on the M.2 edge connector as shown in the table on this page: https://learn.sparkfun.com/tutorials/micromod-teensy-processor-hookup-guide/hardware-overview. And a custom carrier can use these pins directly with resorting to use pin 11 as an alternate for CTX1. The board designed here is more of a ATP Carrier CAN Shield if I am reading the design correctly.

The ATP carrier unfortunately doesn' t appear to have all the M.2 edge pins broken out on the carrier board. The image I was referencing shows that:
Picture1.jpg

Hard to write a detailed explanation when typing on your phone.
 
The pin out picture shows COPI as CTX1 but does not say anything about need to use alt pin definition for to use COPI you need to can1.setTX(11)?

Also, where do you call it? Before begin? After begin?

Thanks

When I ran the test I did:
Code:
  Can1.begin();
  Can1.setTX(ALT);
  Can1.setBaudRate(250000);

As for knowing when to use the Alternate pin 11, if you look at the Teensy 4 pinout card it shows pin 11 CTX1 in a lighter shade of pink than the other Can pins indicating that its an alternate pin. Also just for reference pin 13 is an alternate pin for CRX1.
 
Last edited:
yes i use an enum ALT for alternate pin, teensy products don't really have 3 or more alternate sets of pins for any CAN bus lines and i didnt want to do condition checks on pins, especially if the user entered an invalid pin.
 
shows pin 11 CTX1 in a lighter shade of pink than the other Can pins indicating that its an alternate pin.

Like I said I missed that part. I could not discern from the image any color differences.

An asterisk could be included like "CTX1*" or the like could be included to make it more obvious.

So I decided to try the theory that not having a CTX1 not connected would give me the same issue on the T4.1.

Well it didn't.

T4.1 has pin 11 as a TX1 alt pin and my CAN1 transceiver CTX/CRX are connected to 22 and 23 as expected.

So I set Can1.setTX(ALT) in the same demo sketch and to my surprise, even with CTX1 set to alt CAN1 is reading the CAN bus just fine.

So I am confused as to how the sender is getting an ACK on the bus if the CTX1 pin is not connected to the transceiver?

OK, so I had another thought. I am old (really old) school DIP kind of guy and as I am still working on this stuff it is in sockets so I physically bent the TX pin out of the way and guess what.

It duplicated what I am seeing on the TMM.

So apparently "Can1.setTX(ALT)" did not disconnect pin 22 as I thought it would.

So without the CTX pin connected the transceiver CAN1 by itself can not "receive" messages but when CAN2/3 is connected and can send the ACK then CAN1 can is "receiving" the messages.

I have a feeling that if CAN1 for the TMM without "Can1.setTX(ALT)" was sent to listen only mode then I would not have seen this problem.

Just ramblings from an old school guy and maybe someone else can not waste half a day trying to figure this out.

Thanks for everyone's help.
 
Last edited:
I am having a problem with teensy 3.2 and can tranceiver SN65HVD230 connected to a car ecu.
I receive every id 100 times before I receive the next id's also 100 times. When i try to send something, everything freezes..
Anyone has an idea why?
 
also during transmissions if mailboxStatus() shows all TX mailboxes full, it's likely your transceiver is either in listen-only mode or your termination is not correct (considering you do see frames)
 
do you have a sketch we can look at?

#include <FlexCAN_T4.h>

FlexCAN_T4<CAN0, RX_SIZE_256, TX_SIZE_16> Can0;
CAN_message_t txmsg, msg;
CAN_error_t can_error_data;

int test;

void setup(void) {
Serial.begin(9600);
Can0.begin();
Can0.setBaudRate(500000); //500kbps
}

void loop() {
if ( Can0.read(msg) ) {
//Can0.write(txmsg);
Serial.print("CAN1 ");
Serial.print("MB: "); Serial.print(msg.mb);
Serial.print(" ID: 0x"); Serial.print(msg.id, HEX );
Serial.print(" EXT: "); Serial.print(msg.flags.extended );
Serial.print(" LEN: "); Serial.print(msg.len);
Serial.print(" DATA: ");
for ( uint8_t i = 0; i < 8; i++ ) {
Serial.print(msg.buf); Serial.print(" ");
}
Serial.print(" TS: "); Serial.println(msg.timestamp);
}

}

120Ohm terminators are in place
 
if you are connecting to the car did you try removing the terminations? you don't terminate for cars as they are already terminated, also check for common ground
 
if you are connecting to the car did you try removing the terminations? you don't terminate for cars as they are already terminated, also check for common ground

Only 2 resistors are on the bus. As it schould
Just read an article about fake vp230 chips.. , might be my problem i think, would it work if i replace the vp230 with a tja1050 on the board?
 
Completely unasked for update on my issues with getting CAN-FD to work with my custom board. I have it working now. But, I don't understand it. I am using the library unmodified at this point and it is working but here is what I have experienced:

1. Using a nominal bitrate of 500k works fine for standard CAN frames. It does not work for CAN-FD frames with a faster data rate unless that data rate is 1M. With either no speed up or 1M rate I can then transmit even large FD frames properly.
2. I can always receive CAN-FD frames properly. If I set the rates to 500k/2M then an external device can send FD frames to my board perfectly well.
3. If I increase the nominal rate to 1M then everything works fine all of the time. 1M/2M works fine for sending. 1M/4M also works fine. I didn't test higher but generally nobody is going over 1M/5M as some transceivers can't do any better.

So, it appears my trouble was related to the use of a 500k nominal rate with >1M data rates. However, it sure seems like other users have successfully used such parameters. I wonder if it matters that I have all three CAN buses running at the same time? Do other people do that as well? Can anyone confirm that they are able to send CAN-FD traffic with a speed set up of 500k/2M? I'm wondering if my transceiver is being strange or what else might cause this. It certainly is weird that faster works better. It could be some obscure issue with the driver or the hardware in the chip but it seems doubtful. I've had the issue even with simpler sketches so it seems like it isn't something weird I was doing in my large program. But, I'm a bit uneasy that I can't get CAN-FD to work at 500k nominal rate. That's not that uncommon of a configuration and I'd sure like to get it working.
 
Completely unasked for update on my issues with getting CAN-FD to work with my custom board. I have it working now. But, I don't understand it. I am using the library unmodified at this point and it is working but here is what I have experienced:

1. Using a nominal bitrate of 500k works fine for standard CAN frames. It does not work for CAN-FD frames with a faster data rate unless that data rate is 1M. With either no speed up or 1M rate I can then transmit even large FD frames properly.
2. I can always receive CAN-FD frames properly. If I set the rates to 500k/2M then an external device can send FD frames to my board perfectly well.
3. If I increase the nominal rate to 1M then everything works fine all of the time. 1M/2M works fine for sending. 1M/4M also works fine. I didn't test higher but generally nobody is going over 1M/5M as some transceivers can't do any better.

So, it appears my trouble was related to the use of a 500k nominal rate with >1M data rates. However, it sure seems like other users have successfully used such parameters. I wonder if it matters that I have all three CAN buses running at the same time? Do other people do that as well? Can anyone confirm that they are able to send CAN-FD traffic with a speed set up of 500k/2M? I'm wondering if my transceiver is being strange or what else might cause this. It certainly is weird that faster works better. It could be some obscure issue with the driver or the hardware in the chip but it seems doubtful. I've had the issue even with simpler sketches so it seems like it isn't something weird I was doing in my large program. But, I'm a bit uneasy that I can't get CAN-FD to work at 500k nominal rate. That's not that uncommon of a configuration and I'd sure like to get it working.

Its been awhile but most of my testing was always at 1M or above for FD. But wondering if you need to lower the clock when using 500Mhz.

If you look at the code 1M/2M is set to 24Mhz and goes up from there. If using 500K/1M you might try lowering it to maybe 20Mhz or 16Mhz using setClock(CLK_20MHz) or setClock(CLK_16MHz)
 
Can I use iso-tp onRecieve callback to trigger per message ID?
For example:
id = 0x001 - trigger function callBack1
id = 0x002 - trigger function callBack2
id = 0x003 - trigger function callBack3

Also, I might have asked this before (or maybe not)..
But can the iso-tp library handle the rx of a first frame, flow control and consecutive frame and place the full response into a long buffer? or can it only do this for transmission?
 
currently i am printing debug from an ESP32 to Teensy using the same isotp that comes with flexcan_t4. so much easier snprintf'ing buffers and esp32 sending it to print to a teensy serial monitor :)

yes the ID is in the callback. it's a struct
 
@tony I'd like to do on iso-tp something similar to FlexCAN where I can assign a mailbox to a specific ID
Code:
Can0.setMBFilter(MB1, 0x100);
and trigger a specific callback when a message arrives in that mailbox
Code:
Can0.onReceive(MB1, callback_1);

I currently have three mailboxes set up to catch frames from three different ID's, and each one has it's own callback for processing the data.
I'd like to do the same but use iso-tp to manage consecutive frames rather than using a bunch of if else statements I have today and manually send flow control frames to the server.
 
it doesn't work that way, it works based on the payload which can come in from anywhere. if you do go that route you'll most likely use filtering, but its a background queue that reassembles the buffers before sending the final copy to your isotp callback. isotp has its own callback it's not mailbox specific it's based on synchronized packet stream
 
Big time noob here. Playing with this, and cant understand how to recieve all messages with no filtering. Reading the Ref Manual for RT1060 I dont understand how this can happen but yet its happening. What am I overlooking on register setup?
 
Hello all,
I'm currently using a Teesny 4.0 and have a jumper cable connected from pin 23 (CAN RX1) to pin 22 (CAN TX1) (Screenshot: https://github.com/martovens/Testing_FlexCAN_T4/blob/main/Screenshot 2022-03-26 232112.jpg). I've been unable to get this working. I'm using FlexCAN_T4 by tonton81 at commit # ef2a838b8c35b8fd8a7a0ee7a85a615a18335127. I am also programming the Teensy 4.0 using PlatformIO on Visual Studio Code. Here is my code:

Code:
#include <Arduino.h>
#include <FlexCAN_T4.h>

FlexCAN_T4<CAN1, RX_SIZE_256, TX_SIZE_16> can1;
CAN_message_t readFrame;

void canSniff(const CAN_message_t &msg) {
  Serial.print("MB "); Serial.print(msg.mb);
  Serial.print("  OVERRUN: "); Serial.print(msg.flags.overrun);
  Serial.print("  LEN: "); Serial.print(msg.len);
  Serial.print(" EXT: "); Serial.print(msg.flags.extended);
  Serial.print(" TS: "); Serial.print(msg.timestamp);
  Serial.print(" ID: "); Serial.print(msg.id, HEX);
  Serial.print(" Buffer: ");
  for ( uint8_t i = 0; i < msg.len; i++ ) {
    Serial.print(msg.buf[i], HEX); Serial.print(" ");
  } Serial.println();
}

void setup()
{
  Serial.begin(9600);

  can1.begin();
  can1.setBaudRate(9600);
  can1.onReceive(canSniff);
  can1.enableFIFO();
  
}

void canTX()
{
  CAN_message_t msg;
  msg.id = 0x7E0;
  msg.buf[0] = 1;
  msg.buf[1] = 2;
  msg.buf[2] = 3;
  msg.buf[3] = 4;
  msg.buf[4] = 5;
  msg.buf[5] = 6;
  msg.buf[6] = 7;
  msg.buf[7] = 8;
  msg.len = 8;
  msg.flags.extended = 0;
  msg.flags.remote = 0;
  can1.write(msg);
}

void loop(){
  can1.events();

  canTX();
  can1.read(readFrame);
  canSniff(readFrame);
  
  can1.mailboxStatus();

  digitalWrite(13, HIGH);
}

Here is the printout from running the code:

MB 0 OVERRUN: 0 LEN: 8 EXT: 0 TS: 0 ID: 0 Buffer: 0 0 0 0 0 0 0 0
FIFO Enabled --> Interrupt Disabled
FIFO Filters in use: 8
Remaining Mailboxes: 8
MB8 code: TX_DATA (Transmitting)(Standard Frame)(ID: 0x7E0)(Payload: 1 2 3 4 5 6 7 8)
MB9 code: TX_DATA (Transmitting)(Standard Frame)(ID: 0x7E0)(Payload: 1 2 3 4 5 6 7 8)
MB10 code: TX_DATA (Transmitting)(Standard Frame)(ID: 0x7E0)(Payload: 1 2 3 4 5 6 7 8)
MB11 code: TX_DATA (Transmitting)(Standard Frame)(ID: 0x7E0)(Payload: 1 2 3 4 5 6 7 8)
MB12 code: TX_DATA (Transmitting)(Standard Frame)(ID: 0x7E0)(Payload: 1 2 3 4 5 6 7 8)
MB13 code: TX_DATA (Transmitting)(Standard Frame)(ID: 0x7E0)(Payload: 1 2 3 4 5 6 7 8)
MB14 code: TX_DATA (Transmitting)(Standard Frame)(ID: 0x7E0)(Payload: 1 2 3 4 5 6 7 8)
MB15 code: TX_DATA (Transmitting)(Standard Frame)(ID: 0x7E0)(Payload: 1 2 3 4 5 6 7 8)

I've also tried commenting out the can1.read(readFrame), canSniff(readFrame), and can1.mailboxStatus() statements in the loop(), and nothing prints out. I'm not sure what I'm doing wrong here, I've been scouring through this and other forums as well as projects that use FlexCAN_T4 but I still cannot get this to work.
 
Last edited:
You can not connect CAN RX1 to CAN TX1 like you did. You need to connect a CAN transceiver such as the MCP2562 to pin 23 and 22 then the CAN_H and CAN_L to your CAN network.

You also need another node on the CAN network to see the ACK.

There are no solder on the header pins.
 
Back
Top