FlexCAN_T4 - FlexCAN for Teensy 4

@skpang @msadie

Oh my god... Thank you so much you two. I feel really dumb for making such a mistake!
I cant believe it was something so simple.
I was searching for this for ages and couldnt find the sollution. I was almost sure, that I had a problem with the hardware at the end and didnt even think that it was an issue with the clock settings.

I made a mistake with the termination. I am using 120Ohms on both sides so that should be fine. But I really didnt think about the clock settings beeing to HIGH so that I can not achieve slower CANFD rates.

I was sure that the clock settings I was using would work as the PEAK Bit Rate Tool was giving me timing options for 80MHz 500K nominal rate and 2M data rate and I imagined I could just use the same setting on the PEAK device as well as on the Teensy but looks like I was mistaken.
That shows that maybe I should test around with different clock settings before diving to deep into the documentation of the hardware.

Now I just need to test and see if I can achieve higher bit rates as well.
 
Trying to get comms working with a Megasquirt ECU and teensy 4.0. I get this readout when I use FlexCan sketchs. I've read on a post about a setting a transceiver enable pin, but I have found nothing that explains connections. Not a coder in any sense, and just getting into using these devices.
Teensy Output.PNG


What settings/code/connection should I be using to make this work? I'm using the RX1/TX1 pins on the teensy, connected to the SN65hVD230 transceiver.

The following test code works, I see T4.0Cantest Repeat: Read bus2, Write bus1 on the serial monitor, so I assume the board is ok.



Code:
// -------------------------------------------------------------
// CANtest for Teensy 4.0 using CAN2 and CAN2 bus
#include <FlexCAN_T4.h>

#define debug(msg) Serial.print("["); Serial.print(__FILE__); Serial.print("::"); Serial.print(__LINE__);  Serial.print("::"); Serial.print(msg); Serial.println("]");
void debug_pause(void)
{
  Serial.print("Paused...");
  while (!Serial.available());
  while (Serial.available()) Serial.read();
  Serial.println("Restarted.");
}

FlexCAN_T4<CAN1, RX_SIZE_256, TX_SIZE_16> Can1;
FlexCAN_T4<CAN2, RX_SIZE_256, TX_SIZE_16> Can2;

static CAN_message_t msg;
static uint8_t hex[17] = "0123456789abcdef";

// -------------------------------------------------------------
static void hexDump(uint8_t dumpLen, uint8_t *bytePtr)
{
  uint8_t working;
  while( dumpLen-- ) {
    working = *bytePtr++;
    Serial.write( hex[ working>>4 ] );
    Serial.write( hex[ working&15 ] );
  }
  Serial.write('\r');
  Serial.write('\n');
}


// -------------------------------------------------------------
void setup(void)
{
  Serial.begin(115200);
  int iSerialTimeout = 1000000;
  delay(100);
  while (!Serial && (iSerialTimeout-- != 0));
  debug (F("start setup"));

  Can1.begin();
  Can2.begin();
  Can1.setBaudRate(1000000);  
  Can2.setBaudRate(1000000);

  // t4 missing msg.ext = 0;
  msg.id = 0x100;
  msg.len = 8;
  msg.flags.extended = 0;
  msg.flags.remote   = 0;
  msg.flags.overrun  = 0;
  msg.flags.reserved = 0;
  msg.buf[0] = 10;
  msg.buf[1] = 20;
  msg.buf[2] = 0;
  msg.buf[3] = 100;
  msg.buf[4] = 128;
  msg.buf[5] = 64;
  msg.buf[6] = 32;
  msg.buf[7] = 16;
  debug (F("setup complete"));
  //debug_pause();
}


// -------------------------------------------------------------
void loop(void)
{
  msg.buf[0]++;       //since you are in a loop i just incremented each time in stead of doing it 5 times[/COLOR]
  Can1.write(msg);    //you could do it your way as well[/COLOR]
  Serial.println("T4.0cantest - Repeat: Read bus2, Write bus1");
  CAN_message_t inMsg;
  if (Can2.read(inMsg)!=0)     // Changed this to if as as opposed to while - the way you had it just gets stuck since you haven't even sent a message yet[/COLOR]
  {
    Serial.print("W RD bus 2: "); hexDump(8, inMsg.buf);
  }
  delay(20);
}
 
You might try the sketch given in <this> post. Note that it works best when an RA8875 800x480 display is attached to the T4, but if you just want to read the CAN bus data, the received data displayed in the Serial Monitor can be used for this.

Hope that helps . . .

Mark J Culross
KD5RXT
 
Hello to all and @tonton81

how can i implement with Teensy4.1 UDS server like this ,
Receive request 0x18DA00F1 and
send answer with id 0x18DAF100

Also tester send with 0x18DA00F1 and teensy need answer with 0x18DAF100.
in this sample teensy accept only request from ID 0x18DAF100.

Code:
#include <FlexCAN_T4.h>
#include <isotp_server.h>
const uint32_t canid = 0x18DAF100;
const uint32_t request = 0x020902;
uint8_t myData[] = { 0x49, 0x2, 0x1, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 1, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 3, 3, 2, 4, 4, 0xF, 0xF, 0xF, 0xF, 0xF, 0xF, 0xF, 0xF, 0xF, 0xF, 0xF, 0xF, 0xF, 0xF, 0xF, 0xF, 0xF, 0xF, 0xF, 0xF, 0xF, 0xF, 0xF, 0xF, 0xF, 0xF, 0xF, 0xF, 0xF, 0xF, 0xF, 0xF, 0xF, 0xF, 0xF, 0xF, 0xF, 0xF, 0xF, 0xF, 0xF, 0xF, 0xF, 0xF, 0xF, 0xF, 0xF, 0xF, 0xF, 0xF, 0xF, 0xF, 0xF, 0xF, 0xF, 0xF, 0xF, 0xF, 0xF, 0xF, 0xF, 0x5 };
isotp_server<canid, EXTENDED_ID, request, myData, sizeof(myData)> myResource;

FlexCAN_T4<CAN1, RX_SIZE_256, TX_SIZE_16> Can1;

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(" BUS: "); Serial.print(msg.bus);
  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(115200); delay(400);
  Can1.begin();
  Can1.setClock(CLK_60MHz);
  Can1.setBaudRate(500000);
  Can1.setMaxMB(16);
  Can1.enableFIFO();
  Can1.enableFIFOInterrupt();
  Can1.onReceive(canSniff);
  myResource.begin();
 
  myResource.setWriteBus(&Can1); /* we write to this bus */
}

void loop() {
}

Best Regards
 
Last edited:
I'm looking for a non-iso CAN FD example. I have a Teensy 4.1 working as CAN FD on CAN3 and am to receive a 64 byte message sent by a TCAN4550. When sending a 64 byte message with the Teensy it only outputs 8 bytes even though the msg.len to 64. I'm monitoring the data with candump on a Raspberry Pi with a Waveshare 2-Channel CAN FD HAT.
 
I'm looking for a non-iso CAN FD example. I have a Teensy 4.1 working as CAN FD on CAN3 and am to receive a 64 byte message sent by a TCAN4550. When sending a 64 byte message with the Teensy it only outputs 8 bytes even though the msg.len to 64. I'm monitoring the data with candump on a Raspberry Pi with a Waveshare 2-Channel CAN FD HAT.
Actually I found one that works for CAN FD that I haven't tested with the regular CAN: https://github.com/cburgess5294/Arduino-Teensy41/blob/main/TEENSY_4.1_CAN_TEST_2.ino
 
FlexCAN_T4 users and tonton81:
I'm having some difficult with FlexCAN_T4 being able to reliably see CAN messages on the bus when it starts up. When there is traffic on the bus already as the Teensy 4.1 boots up, it sometimes can't receive it, as though the FlexCAN_T4 library didn't start up well. When there is not traffic on the bus, and I power up the Teensy 4.1, then start the can bus traffic simulator, it more reliably begins to receive CAN messages. This is a closed, known can bus with only a few devices and my Teensy 4.1 is a monitoring and logging device, so it wants to receive and process every can bus message, and therefore no filtering is necessary. I am simulating the messages with a Peak Systems USB-CAN device and their PcanView software on my PC, because I don't have access to the actual hardware devices that will be on the monitored can bus. This means that the USB-CAN simulator and my Teensy 4.1 are the only devices on the can bus now. If the Teensy 4.1 board is off, the PcanView software of course shows that the bus has gone error passive but it keeps transmitting indefinitely.

My software follows the example from the FlexCAN_T4 library:

#include < FlexCAN_T4.h>

// global CAN Bus Interface object
FlexCAN_T4<CAN1, RX_SIZE_256, TX_SIZE_16> g_pdbCan;

// in the setup function:
g_pdbCan.begin();
g_pdbCan.setBaudRate(1000000);
g_pdbCan.setMaxMB(16);
g_pdbCan.enableFIFO();
g_pdbCan.enableFIFOInterrupt();
g_pdbCan.onReceive(PdbCanSniff);
g_pdbCan.mailboxStatus();

// at the top of the loop function:
g_pdbCan.events();

and in function PdbCanSniff I'm extracting the CAN bus id, length, and payload data from the (const CAN_message_t &canMsg). I do some serial.print debugging to show the incoming can bus contents on the serial monitor and flash the Teensy 4.1 board light faster when its receiving can bus messages so I can tell reliably when it starts up whether its getting can bus messages or not.

Has anybody experienced this behavior or have ideas how to chase it ? I need it to start up reliably whether there is already can bus traffic or not.

Mike
 
FlexCAN_T4 users and tonton81:
I'm having some difficult with FlexCAN_T4 being able to reliably see CAN messages on the bus when it starts up. When there is traffic on the bus already as the Teensy 4.1 boots up, it sometimes can't receive it, as though the FlexCAN_T4 library didn't start up well. When there is not traffic on the bus, and I power up the Teensy 4.1, then start the can bus traffic simulator, it more reliably begins to receive CAN messages. This is a closed, known can bus with only a few devices and my Teensy 4.1 is a monitoring and logging device, so it wants to receive and process every can bus message, and therefore no filtering is necessary. I am simulating the messages with a Peak Systems USB-CAN device and their PcanView software on my PC, because I don't have access to the actual hardware devices that will be on the monitored can bus. This means that the USB-CAN simulator and my Teensy 4.1 are the only devices on the can bus now. If the Teensy 4.1 board is off, the PcanView software of course shows that the bus has gone error passive but it keeps transmitting indefinitely.

My software follows the example from the FlexCAN_T4 library:

#include < FlexCAN_T4.h>

// global CAN Bus Interface object
FlexCAN_T4<CAN1, RX_SIZE_256, TX_SIZE_16> g_pdbCan;

// in the setup function:
g_pdbCan.begin();
g_pdbCan.setBaudRate(1000000);
g_pdbCan.setMaxMB(16);
g_pdbCan.enableFIFO();
g_pdbCan.enableFIFOInterrupt();
g_pdbCan.onReceive(PdbCanSniff);
g_pdbCan.mailboxStatus();

// at the top of the loop function:
g_pdbCan.events();

and in function PdbCanSniff I'm extracting the CAN bus id, length, and payload data from the (const CAN_message_t &canMsg). I do some serial.print debugging to show the incoming can bus contents on the serial monitor and flash the Teensy 4.1 board light faster when its receiving can bus messages so I can tell reliably when it starts up whether its getting can bus messages or not.

Has anybody experienced this behavior or have ideas how to chase it ? I need it to start up reliably whether there is already can bus traffic or not.

Mike
I'm not very familiar with Peak tools, but in CANalyzer you can have the tool ACK its own tx messages to keep the bus from going into an error state while it is the only device on the bus. If you could do this, it could help narrow down if the problem is starting up on an active bus vs starting up with the transmitting node in the error-passive state.
https://forum.peak-system.com/viewtopic.php?t=7267
If this option isnt supported, could you use another teensy or any device with correct baud rate to ack messages until the problem device comes online (just for testing, of course).
-Mike
 
msadie, thanks for the idea, I'm looking at that. Turns out my Peak USB/CAN device can't do self ack unless I upgrade the firmware in it, so I'm looking at that and/or putting another teensy 4.1 on the can bus. Will report results so the group can benefit.
 
Hi,

I submitted a bug report to the github repo issue reporter. I can't provide an example program at the moment, but has anyone experienced something similar?

Data is damaged/changed when I send data. More information is in the whistleblower. (I formatted and attached information as well).

Thanks in advance if anyone can help with this. (Including @tonton81 who made the library)

https://github.com/tonton81/FlexCAN_T4/issues/78

megax
 
As usual when having problems on CAN:
twisted pair cable ?
120 ohms resistors at both ends ?
3.3V transceiver ?
good power supply decoupling on the transceiver ?
 
Thank you very much for your answers and questions. I will try to answer them.
I increased the 60mhz because there was an error (also on 24mhz), now I have taken it back to 24mhz, it is still there.
Double 120 ohms are included in the system, they may not be twisted, but ifm factory cables, in the box a very short section that is not twisted.
It was never a problem. We also have another system, particle photon 1. The code is the same (of course, the lower layers are not, but it is on the user side). There are 0 errors with 50k messages (everything else is the same, load level, etc.). In the case of Teensy, without the modification I included, 10k is good, 40k is wrong. With repair 50k good ~70 bad. And I only changed the interrupt.

I wrote out the messages in writeTXmailbox. Before calling write(), I wrote out what I would send and what writeTXmailbox would copy to canbus. What is sent is already changed in the writeTXmailbox. Sent (which I read on canbus) and writeTXmailbox are the same. However, write() and writeTXmailbox() do not. That's why I suspect there is something else wrong and not in the canbus network.
 
sorry, I understand the mesarments, but my translater who helps me, she doesn't know and I did not check it.
please, forgive me the mistakes of the traslation.
 
Back
Top