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.
 
First loop

Code:
FIFO Disabled
    Mailboxes:
        MB0 code: RX_EMPTY    (Standard Frame)
        MB1 code: RX_EMPTY    (Standard Frame)
        MB2 code: RX_EMPTY    (Standard Frame)
        MB3 code: RX_EMPTY    (Standard Frame)
        MB4 code: RX_EMPTY    (Extended Frame)
        MB5 code: RX_EMPTY    (Extended Frame)
        MB6 code: RX_EMPTY    (Extended Frame)
        MB7 code: RX_EMPTY    (Extended Frame)
        MB8 code: TX_INACTIVE
        MB9 code: TX_INACTIVE
        MB10 code: TX_INACTIVE
        MB11 code: TX_INACTIVE
        MB12 code: TX_INACTIVE
        MB13 code: TX_INACTIVE
        MB14 code: TX_INACTIVE
        MB15 code: TX_INACTIVE

Second loop

Code:
FIFO Disabled
    Mailboxes:
        MB0 code: RX_FULL
        MB1 code: RX_FULL
        MB2 code: RX_FULL
        MB3 code: RX_OVERRUN
        MB4 code: RX_EMPTY    (Extended Frame)
        MB5 code: RX_EMPTY    (Extended Frame)
        MB6 code: RX_EMPTY    (Extended Frame)
        MB7 code: RX_EMPTY    (Extended Frame)
        MB8 code: TX_INACTIVE
        MB9 code: TX_INACTIVE
        MB10 code: TX_INACTIVE
        MB11 code: TX_INACTIVE
        MB12 code: TX_INACTIVE
        MB13 code: TX_INACTIVE
        MB14 code: TX_INACTIVE
        MB15 code: TX_INACTIVE

Edit:
Used this code from post #75 (just different enable pin) and everything seems fine.

Code:
#include <FlexCAN_T4.h>
FlexCAN_T4<CAN2, RX_SIZE_256, TX_SIZE_16> Can0;

void setup(void) {
  Serial.begin(115200); delay(400);
  pinMode(2, OUTPUT); digitalWrite(2, LOW); // enable tranceiver
  Can0.begin();
  Can0.setBaudRate(500000);
  Can0.setMaxMB(16); // up to 64 max for T4, not important in FIFO mode, unless you want to use additional mailboxes with FIFO
  Can0.enableFIFO();
  Can0.enableFIFOInterrupt();
  Can0.onReceive(canSniff);
  Can0.mailboxStatus();
}

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 loop() {
  Can0.events();

  static uint32_t timeout = millis();
  if ( millis() - timeout > 20 ) { // send random frame every 20ms
    CAN_message_t msg;
    msg.id = random(0x1,0x7FE);
    for ( uint8_t i = 0; i < 8; i++ ) msg.buf[i] = i + 1;
    Can0.write(msg);
    timeout = millis();
  }

}

Output

Code:
FIFO Enabled --> Interrupt Enabled
    FIFO Filters in use: 8
    Remaining Mailboxes: 8
        MB8 code: TX_INACTIVE
        MB9 code: TX_INACTIVE
        MB10 code: TX_INACTIVE
        MB11 code: TX_INACTIVE
        MB12 code: TX_INACTIVE
        MB13 code: TX_INACTIVE
        MB14 code: TX_INACTIVE
        MB15 code: TX_INACTIVE
MB 99  OVERRUN: 0  LEN: 8 EXT: 0 TS: 40290 ID: 7E8 Buffer: 3 7F 2 31 55 55 55 55
MB 99  OVERRUN: 0  LEN: 8 EXT: 0 TS: 34684 ID: 7E8 Buffer: 3 7F 2 31 55 55 55 55
MB 99  OVERRUN: 0  LEN: 8 EXT: 0 TS: 44981 ID: 7DF Buffer: 2 1 0 0 0 0 0 0
MB 99  OVERRUN: 0  LEN: 7 EXT: 0 TS: 55476 ID: 7E8 Buffer: 6 41 0 FF FF FF FF
MB 99  OVERRUN: 0  LEN: 8 EXT: 0 TS: 40179 ID: 7DF Buffer: 2 1 0 0 0 0 0 0
MB 99  OVERRUN: 0  LEN: 7 EXT: 0 TS: 49934 ID: 7E8 Buffer: 6 41 0 FF FF FF FF
MB 99  OVERRUN: 0  LEN: 8 EXT: 0 TS: 13198 ID: 7DF Buffer: 2 1 0 0 0 0 0 0
MB 99  OVERRUN: 0  LEN: 7 EXT: 0 TS: 23311 ID: 7E8 Buffer: 6 41 0 FF FF FF FF
MB 99  OVERRUN: 0  LEN: 8 EXT: 0 TS: 34185 ID: 7DF Buffer: 2 1 20 0 0 0 0 0
MB 99  OVERRUN: 0  LEN: 7 EXT: 0 TS: 45268 ID: 7E8 Buffer: 6 41 20 FF FF FF FF
MB 99  OVERRUN: 0  LEN: 8 EXT: 0 TS: 50372 ID: 7DF Buffer: 2 1 40 0 0 0 0 0
MB 99  OVERRUN: 0  LEN: 7 EXT: 0 TS: 62225 ID: 7E8 Buffer: 6 41 40 FF FF FF FE
MB 99  OVERRUN: 0  LEN: 8 EXT: 0 TS: 42899 ID: 7DF Buffer: 2 9 A 0 0 0 0 0
MB 99  OVERRUN: 0  LEN: 8 EXT: 0 TS: 54184 ID: 7E8 Buffer: 10 17 49 A 1 45 43 4D
MB 99  OVERRUN: 0  LEN: 8 EXT: 0 TS: 54317 ID: 7E0 Buffer: 30 0 0 0 0 0 0 0
Assistance with CAN FD Communication Setup in Senior Design Project Using Teensy**


I’m currently working on a Senior Design project that involves real-time motor control using a Teensy microcontroller and CAN FD communication. Here's a brief overview of the project and my setup:


Project Overview:

Our project focuses on controlling a motor via an Escon motor controller, which is interfaced with a Teensy microcontroller. The system includes a torque meter for measuring torque generated by the motor, which outputs an analog signal that is converted to digital for processing by the Teensy. The ultimate goal is to enable real-time control and monitoring of the motor through a laptop application using CAN FD (Controller Area Network Flexible Data-rate) communication.



Setup Details:

- **Teensy Microcontroller**: Acts as the main control unit, receiving signals from the motor controller and transmitting data to the laptop via CAN FD.

- **Escon Motor Controller**: Interfaces with the Teensy to control the motor based on PWM signals.

- **Torque Meter**: Measures torque and sends analog signals, which are converted and read by the Teensy.

- **CAN FD Communication**: Implemented to allow real-time data exchange between the Teensy and a laptop application. The CAN FD protocol was chosen for its high data rate, error correction capabilities, and scalability.



Code and Current Output:

I’ve used the following code to initialize the CAN FD communication and periodically send random CAN frames:



```cpp

#include <FlexCAN_T4.h>

FlexCAN_T4<CAN2, RX_SIZE_256, TX_SIZE_16> Can0;



void setup(void) {

Serial.begin(115200); delay(400);

pinMode(2, OUTPUT); digitalWrite(2, LOW); // enable transceiver

Can0.begin();

Can0.setBaudRate(500000);

Can0.setMaxMB(16); // up to 64 max for T4, not important in FIFO mode, unless you want to use additional mailboxes with FIFO

Can0.enableFIFO();

Can0.enableFIFOInterrupt();

Can0.onReceive(canSniff);

Can0.mailboxStatus();

}



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, HEX); Serial.print(" ");

} Serial.println();

}



void loop() {

Can0.events();



static uint32_t timeout = millis();

if ( millis() - timeout > 20 ) { // send random frame every 20ms

CAN_message_t msg;

msg.id = random(0x1,0x7FE);

for ( uint8_t i = 0; i < 8; i++ ) msg.buf = i + 1;

Can0.write(msg);

timeout = millis();

}

}

```



The output I’m currently seeing is:



- **FIFO Enabled → Interrupt Enabled**

- **FIFO Filters in use: 8**

- **Remaining Mailboxes: 8**

- **MB8 code: TX_INACTIVE**

- **MB9 code: TX_INACTIVE**

- **MB10 code: TX_INACTIVE**

- **MB11 code: TX_INACTIVE**

- **MB12 code: TX_INACTIVE**

- **MB13 code: TX_INACTIVE**

- **MB14 code: TX_INACTIVE**

- **MB15 code: TX_INACTIVE**

- **CAN FD communication started.**



### Issue:

The output doesn’t match my expectations, especially with all the mailboxes showing as inactive. I’m unsure if this indicates a problem with the CAN FD communication setup or the way the mailboxes are configured.



Could you please provide guidance on why this might be happening and suggest any steps I can take to debug or correct the issue? Your expertise and advice would be greatly appreciated.



Also how can I make sure that CAN FD messages are actually being sent because I am not sure whats happening as I am a beginner and totally new to this protocol.



Thank you for your assistance!
 
Hi all,

I am working on a university project with CAN-FD that required explicit RJW, pseg1, and pseg2 values (2, 6, 3 respectfully for both arbitration and data, baud of 500kb/s for arb. 2000kb/s for data). What would be the best way of undertaking this?

Have spent a fair amount of time just trial and error with the prop delay, bus length, and clock speed (using setBaudRateAdvanced() ), but nothing seems to get me close enough!

Thanks!
 
Hi,

i am using this great piece of code to get my CAN (FD) application to work.... It works nice with interrupt driven mode, data is readout correctly => nice!

I am using the CAN 2.0, no FD
When I try "polling" the CAN data it "hangs" and the Teensy boots/resets (i think in the line below marked with "HANGS here").
Is this a blocking read, or do i something wrong with the CAN init? => What to init when i only use polling?
Do i have to call CAN_OBJECT.events(); in the Loop when i only want to poll?

Code:
FlexCAN_T4<CAN3, RX_SIZE_256, TX_SIZE_16> CAN_OBJECT;       // CAN 2.0

void ShowCAN_Data(const CAN_message_t &CAN_Message)
{
  Serial.print("MB "); Serial.print(CAN_Message.mb);
  Serial.print("  OVERRUN: "); Serial.print(CAN_Message.flags.overrun);
  Serial.print("  LEN: "); Serial.print(CAN_Message.len);
  Serial.print(" EXT: "); Serial.print(CAN_Message.flags.extended);
  Serial.print(" TS: "); Serial.print(CAN_Message.timestamp);
  Serial.print(" ID: "); Serial.print(CAN_Message.id, HEX);
  Serial.print(" Buffer: ");
  for ( uint8_t i = 0; i < CAN_Message.len; i++ )
  {
    Serial.print(CAN_Message.buf[i], HEX); Serial.print(" ");
  }
  Serial.println();
}
//
//    Inits the CAN interface
//
void Init_CAN()
{
  CAN_OBJECT.begin();
  CAN_OBJECT.setBaudRate(CAN_BAUD_RATE);
  CAN_OBJECT.setMaxMB(MAX_CAN_MB_COUNT);
  CAN_OBJECT.enableFIFO();
  CAN_OBJECT.enableFIFOInterrupt();
  CAN_OBJECT.onReceive(ShowCAN_Data);
  CAN_OBJECT.mailboxStatus();

  //******FIFO**************
  // CAN_OBJECT.setFIFOFilter(REJECT_ALL);
  // CAN_OBJECT.setFIFOFilter(0, 0x123, STD); // Set filter0 to allow STANDARD CAN ID 0x123 to be collected by FIFO.
  // CAN_OBJECT.setFIFOFilter(1, 0x456, EXT); // Set filter1 to allow EXTENDED CAN ID 0x456 to be collected by FIFO.
  //
  //*****Mailbox*********
  // CAN_OBJECT.setMBFilter(REJECT_ALL);
  // CAN_OBJECT.setMBFilter(MB6, 0x123); // Set mailbox 6 to allow CAN ID 0x123 to be collected.   
  // CAN_OBJECT.setMBUserFilter(MB0,0x00,0xFF);
}
//
//  Poll CAN data
//
int GetCAN_Data(CAN_message_t &CAN_MessageBuffer)
{
//  Polling frames is possible and won't touch interrupt driven mailboxes.
//  You may use your correct message structure (CAN_message_t or CANFD_message_t), and simply call:
//  myCan.read(myFrame); If FIFO is enabled, each read() call will read from FIFO or Mailbox randomly,
//  provided they are not interrupt driven.
#ifdef DEBUG
        totalCAN_MicrosStart = micros();
#endif 

  int rxCount = CAN_OBJECT.read(CAN_MessageBuffer);    <==== HANGS here

#ifdef DEBUG
        totalCAN_MicrosEnd = micros();
        totalCAN_ElapsedMicros = totalCAN_MicrosEnd - totalCAN_MicrosStart;
        if (totalCAN_ElapsedMicros > totalCAN_MaxMicros)
            totalCAN_MaxMicros = totalCAN_ElapsedMicros;
#endif
  return rxCount;
}

void setup() {
    pinMode(LED_BUILTIN, OUTPUT);
    //    Start the serial communication
    Serial.begin (115200);
    while (!Serial && millis() < 5000);
    Serial.printf("\n\n");
    Serial.printf("//**********************************//\n");
    Serial.printf("//* CAN Test                                  //\n");
    Serial.printf("//**********************************//\n\n");
    Serial.flush();
    Init_CAN();
    totalCAN_MaxMicros = 0;
}

void loop()
{
  CAN_message_t CAN_MessageBuffer;
  CAN_OBJECT.events();

 //  Call every 1'000'000 µsec
  SCHEDULE(1'000'000, GET_CAN_DATA)
  {
    //  Poll the CAN data
    int readBytes = GetCAN_Data(CAN_MessageBuffer);
    Serial.printf("CAN read count        : %i bytes\n", readBytes);
    ShowCAN_Data(CAN_MessageBuffer);
  }
}

Thank you very much

Torsten
 
Hi,
I have aquestion regarding the CAN msg.overrun flag. This seems to be set, when CAN data is overwritten on the rx side, because it is not consumed fast enough. That is okay. But how can i reset this flag to start "fresh" again?

Thank you very much

Torsten
 
Back
Top