FlexCAN_T4 - FlexCAN for Teensy 4

yes but 2 bytes isn't an int32_t, you are looking for int16_t, in an int var the most significant bit is set for a negative value, which your bytes never set or do..
 
I've never done anything before with buffers etc so am still learning and haven't grasped how they work yet..
 
Hi Guys,
I’m using the SKPang Triple CAN Board.
I’m not able to control repetition rate or stop the broadcast of a generated CAN message (TSC1(PGN0) to control an engine RPM)
As soon the “can.write” statement has fired once, the message is looping by itself on the bus (bursts continuously).
This behavior has been detected with an oscilloscope.
I’m using a loop with elapsedMillis, a parrallel message in the serial monitor to check the repetition rate works as expected.
Any ideas on which parameter to use to send out a single shot message, adjust the repetition rate of the burst or to stop the broadcast of a specific message?

Thx for the advice.
 
Last edited:
you need 2 or more nodes on the bus to ACK the message, a scope won't do this. The software sends a one shot frame, then when it reaches hardware the mailbox tries to send out until an ACK is received. If no ACK is received it will attempt to retry until it does.

If you do have another node on the bus, verify your tranceiver connections and terminations of the bus
 
you need 2 or more nodes on the bus to ACK the message, a scope won't do this. The software sends a one shot frame, then when it reaches hardware the mailbox tries to send out until an ACK is received. If no ACK is received it will attempt to retry until it does.

If you do have another node on the bus, verify your tranceiver connections and terminations of the bus

Strange, on J1939 the messages are typically a broadcast message and don’t need an acknowledge message.
I’ll try in the following days to connect it with other nodes. I’ll let you know. Thx for the tip.
 
Indeed, stupid me, forgot about the Hardware ACK bit at the end, which has typically a higher pulse, because multiple nodes are confirming on the bus.
Repetition rate = solved. Thx.
 
oh ok I see, you are sending and the TX is just filling, and you only see the first frame being constantly sent. This is because there is no node ACKing on the network. This is a hardware thing not software. Make sure 2 or more nodes are on the network for transmissions to work, at least 1 node needs to ACK for the transmits to send and remove themselves from the mailbox, hardware removes them not you :)

Thanks a lot - I checked my wiring and now it works perfectly:)

I have another question:
Is there a "silent mode" where it is possible to detect the baudrate of the CAN/CAN-FD network?
For example if you connect the teensy-triple-can board to different cars with different baudrates.
 
Ok, so the CAN-FD input does not support listen-only mode?
Because in my case, the CAN-FD data-baudrate could change
 
Ok thank you, but I am not sure how to adapt the baudrate dynamically.
I tried following:

Code:
CAN_FD.begin();
[...]
config.baudrate = 500000;             
config.baudrateFD = CAN_FD.setBaudRate(config, LISTEN_ONLY);   
Serial.println(config.baudrateFD);

But it only prints CAN-FD messages to my serial monitor, when they come with a baudrate from 2.000 kBaud and not e.g. 1.000 kBaud
So I assume:
- the listen only mode is not activated
- "config.baudrateFD" takes a default value which is allegedly 2.000 kBaud

How can I sniff the bus in Listen-Only-Mode, save the detected baudrate-value, save it to "config.baudrateFD" and restart the CAN-FD in Mormal-Mode?
 
config.baudrateFD should be a value.
then you apply config to the the function
Code:
FCTPFD_OPT::setBaudRate(CANFD_timings_t config, FLEXCAN_RXTX listen_only)

I would say keep changing baudrates in listen only mode, and if the callback starts working you found it.
 
I can activate listen only mode only by using the setBaudRate()-fuction, right?
My approach would be to loop through the possible baudrates but how can I detect whether the callback start or not?
With callback you mean the onReceive()-function?
 
yes the interrupt would fire with CAN data if a correct rate was found, so you can save the rate data from the callback on success.
 
But how can I detect, that the interrupt is firing?
Is there a flag, something like a bool, which is true when recognized CAN data with a correct baud rate?
 
Call back function will fire when interrupt is raised.

But how can I detect, that the interrupt is firing?
Is there a flag, something like a bool, which is true when recognized CAN data with a correct baud rate?

You can set what ever you want in the call back function.

I use the same call back function for CAN1 to 3 so I have a bit encoded uint8_t that I set and clear the bits based on the state of the frame received from the interrupt.

Set when new frame on a CAN controller is received and clear after I finish doing something with the frame.

Hope this helps.

Bruce
 
Thanks for the answer Bruce, but I'am missing something.
When I try to switch through different baudrates I came across the FLEXCAN_FDRATES enum
Code:
typedef*enum*FLEXCAN_FDRATES*{
**CAN_1M_2M,
**CAN_1M_4M,
**CAN_1M_6M,
**CAN_1M_8M
}*FLEXCAN_FDRATES;
and the FCTPFD_FUNC void FCTPFD_OPT::setBaudRate(FLEXCAN_FDRATES input, FLEXCAN_RXTX listen_only) function.
But I can't request whether I received a frame or not.
I tried following:
Code:
void loop() {
  CAN_FD.events();                      
  for (int i = 0; i < 4; i++){
     if(millis() >= time_now + period){
      time_now += period;
      CAN_FD.setBaudRate(FLEXCAN_FDRATES(i), LISTEN_ONLY);
      CAN_FD.onReceive(canfdSniff);
      Serial.println(FLEXCAN_FDRATES(i));
      }
  }
}
It always prints 0 (even if the bus is turned off) and but sometimes it glitches to 2 or 3 (which is 6MBaud and 8MBaud, my bus always sends with 2MBaud).So I am on the right path?
Besides this attempt I found the readIFLAG function but unfortunately I haven't been able to use it yet.
I would be glad if you could give me some hints to achieve some kind of automatic baudrate detection
 
Is your bus 1M nominal? if not it won't work. onReceive only needs to be set once, not repeatedly. Why not use the config defaults and change the bitrates at startup like normally? Once you have that working with your setup you can then work on doing autobaud support from the loop
 
I would also suggest sticking with a nominal speed and trying various flexdata speeds to see which detects, then move on to the next nominal rate to try different flexdata rates, FD has many dual rates to choose from and they have to be correct.

An array of values would be essential for a project like this
Your callback will only fire if a successful rate is chosen.
 
No my bus has 500kBaud arbitration and 2MBaud datarate. Arbitration stays always the same, only datarate will change.
I am using the config defaults, in case you mean CANFD_timings_t config;
What do you mean with "change the bitrates at startup like normally"?

My Setup is working perfectly when setting the fixed correct bitrate. But when I am trying to loop through an array with standard CANFD datarate speeds I don't know at which part of the program this should happen. I assume after the onReceive
Which command I should use - I tried following:

Code:
int std_datarates[6] = {500000, 1000000, 2000000, 4000000, 6000000, 8000000};
void setup(void) {
  CAN_FD.begin();
  CANFD_timings_t config;
  [...]  //standard config settings with the wrong init baudrate on purpose
  for(int i = 1; i < 7; i++){config.baudrateFD = std_datarates[i];}
  CAN_FD.onReceive(canfdSniff);
}
 
1M enum is not 500kbps nominal...
Ignore the enum setbaudrate.
Use the config timings version

Code:
CANFD_timings_t config;
config.clock = CLK_60MHz;
config.baudrate = 500000;
config.baudrateFD = 2000000;
config.propdelay = 190;
config.bus_length = 1;
config.sample = 70;
FD.setBaudRate(config);

Just change the baudrate/baudrateFD values as needed and re-run FD.setBaudRate(config) with the listen only flag.You'll need to keep the clock at 60MHz for the higher bitrates to work
 
Thanks for the hints, I got it to work after I realised, that I have to set the whole config values once again instead of simply change the baudrate.

Another question:
My program works perfectly with config.clock at "CLK_24MHz" as well as "CLK_60MHz" for 0,5 MBaud / 1 MBaud and 2 Mbaud.
4 Mbaud does not work at all.
Do I need to set some other parameters or clock values?
 
Back
Top