1) set boards manager to 3.2
2) select FlexCAN_T4 example FIFO with interrupt
3) in the example make sure CAN0 is set in the FlexCAN_T4 constructor
should be fine
#include <FlexCAN_T4.h>
FlexCAN_T4<CAN0, RX_SIZE_256, TX_SIZE_16> Can0;
void setup(void) {
Serial.begin(115200); delay(400);
pinMode(6, OUTPUT); digitalWrite(6, LOW); /* optional tranceiver enable pin */
Can0.begin();
Can0.setBaudRate(500000);
Can0.setMaxMB(16);
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();
}
Code:#include <FlexCAN_T4.h> FlexCAN_T4<CAN0, RX_SIZE_256, TX_SIZE_16> Can0; void setup(void) { Serial.begin(115200); delay(400); pinMode(6, OUTPUT); digitalWrite(6, LOW); /* optional tranceiver enable pin */ Can0.begin(); Can0.setBaudRate(500000); Can0.setMaxMB(16); 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(); }
It's the Tx TS recorded when the message actually makes it on the bus after any arbitration delays.
OK, I'll look into it.
For reference, time synchronisation over CAN:
https://www.autosar.org/fileadmin/user_upload/standards/classic/4-3/AUTOSAR_SWS_TimeSyncOverCAN.pdf
Thanks
Oh wow, thank you that's incredibly useful. Had to drop this for the moment, but I'll be back on it eventually!I just added transmit callback support. It is same as onReceive, just use onTransmit(MB8, callback) (mailbox specific) or onTransmit(callback) (global). The demo canSniff function can be used as a callback for onTransmit to show what has been sent on the bus and with current timestamp.
#include <FlexCAN_T4.h>
FlexCAN_T4<CAN1, RX_SIZE_256, TX_SIZE_16> can1;
FlexCAN_T4<CAN2, RX_SIZE_256, TX_SIZE_16> can2;
CAN_message_t msg;
CAN_message_t txMsg;
void setup(void) {
can1.begin();
can1.setBaudRate(250000);
can2.begin();
can2.setBaudRate(250000);
txMsg.id = 0x34A;
txMsg.len = 8;
txMsg.buf[0] = 0x10;
txMsg.buf[1] = 0xAC;
txMsg.buf[2] = 0x54;
txMsg.buf[3] = 0x31;
txMsg.buf[4] = 0xA6;
txMsg.buf[5] = 0xF4;
txMsg.buf[6] = 0x7E;
txMsg.buf[7] = 0x37;
}
void loop() {
if ( can1.read(msg) ) {
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[i]); Serial.print(" ");
}
Serial.print(" TS: "); Serial.println(msg.timestamp);
}
else if ( can2.read(msg) ) {
Serial.print("CAN2 ");
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[i]); Serial.print(" ");
}
Serial.print(" TS: "); Serial.println(msg.timestamp);
}
if (Serial.available())
{
int c = Serial.read();
if (c == 'c') can1.write(txMsg);
if (c == 'd') can2.write(txMsg);
}
}
#include <FlexCAN_T4.h>
FlexCAN_T4<CAN1, RX_SIZE_256, TX_SIZE_16> canBus;
static CAN_message_t dashMsg;
void setup()
{
// Init Serial
Serial.begin(9600);
// while (!Serial) ; // wait for Arduino Serial Monitor
Serial.println("Teensy 4.0 CAN Example test");
// Init CAN
canBus.begin();
Serial.println("begin");
canBus.setBaudRate(1000000);
Serial.println("setbaud");
// Turn LED on
pinMode(13, OUTPUT);
digitalWrite(13, HIGH);
}
void loop()
{
// Get CAN Messages & Update values
if (canBus.read(dashMsg) ) {
// Flash onboard LED
digitalWrite(13, LOW);
Serial.println("read");
// Get ID
String id = String(dashMsg.id, HEX);
Serial.println(id);
// Flash onboard LED
digitalWrite(13, HIGH);
}
}
#include <FlexCAN_T4.h>
FlexCAN_T4<CAN2, RX_SIZE_256, TX_SIZE_16> can;
CAN_message_t msg;
#define DRIVER1_ADDRESS 0x601
int counter = 0;
void sendMessage();
void setup(void) {
can.begin();
can.setBaudRate(1000000);
pinMode(LED_BUILTIN, OUTPUT);
}
void loop() {
if ( can.read(msg) ) {
Serial.print("CAN2 ");
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[i]); Serial.print(" ");
}
Serial.print(" TS: "); Serial.println(msg.timestamp);
}
counter++;
if(counter % 200000 == 0)
{
//digitalWrite( LED_BUILTIN, !digitalRead(LED_BUILTIN) );
digitalWrite( LED_BUILTIN, HIGH );
delay(200);
sendMessage();
digitalWrite( LED_BUILTIN, LOW );
}
}
void sendMessage()
{
uint16_t index = 0x6040;
uint32_t data = 0x80;
msg.id = DRIVER1_ADDRESS;
msg.buf[0] = 0x2B; // Command specifier
msg.buf[1] = (index >> 8) & 0xFF; // Index bit 1
msg.buf[2] = (index >> 0) & 0xFF; // Index bit 2
msg.buf[3] = 0x00; // Subindex
msg.buf[4] = (data >> 24) & 0xFF; // Data bit 1
msg.buf[5] = (data >> 16) & 0xFF; // Data bit 2
msg.buf[6] = (data >> 8) & 0xFF; // Data bit 3
msg.buf[7] = (data >> 0) & 0xFF; // Data bit 4
can.write(msg);
}