FlexCAN_T4 - FlexCAN for Teensy 4

begin() in a for loop

Ok but why do you need to run begin() in a for loop? signal sending with write() works with the base class

I am only setting up a controller if there is a corresponding DBC file.

So if the DBC file has no messages (no file) then I am not setting up that controller.

I have no idea which can controller the user will have hooked up to what speed/protocol/frame size and so on so I am figuring that all out based on the DBC file being placed on the SD card.

For example, there is nothing that does not allow both standard and extended frames on the same bus so if the DBC file has both and there are more messages than mail boxes I need to divide the MB up based on how many of each ID (STD or EXT) there is and from there, based on message priority I assign one of two messages to each MB via the filter. This way when the mail box is received I only need to look at one to two messages to see which signals I need to decode.

Do it all a look just makes for more compact, readable code.

Just a preference, not a must.

Hope that helps answer your question.

Thanks

Bruce
 
Hi Tony! What can you recommend to use to implement a can relay in real car can network? I've tried to run different versions of the forwarding code on Teensy 3.6 with hvd230 using FlexCan_T4. But it seems 99% of frames was lost or distorted. So I couldn't just get and translate the same frame from CAN1 to CAN2 and vv. Technically it was a relay between odb2 and elm327 adapter and I'm sure all the connections was correct. Thanks in advance for any help.
 
remove events() from the loop() use interrupts and bump the controller to 60MHz using setClock()

bvernham, try adding the functions you think you'll be using in the base class, they must match the template class function but set as virtual so the template can override, check if that will work with your CAN pointers
 
set as virtual so the template can override

:confused:

They don't have a "mind blown emoji".....

Code:
class FlexCAN_T4_Base {
so got the base class

Got the
Code:
FCTP_CLASS class FlexCAN_T4 : public FlexCAN_T4_Base {
templated class

So
class FlexCAN_T4_Base {
virtual void begin();
virtual void setBaudRate(uint32_t baud = 1000000, FLEXCAN_RXTX listen_only = TX);

and so on?

Thanks

Bruce
 
bool setMBUserFilter(FLEXCAN_MAILBOX mb_num, uint32_t id1, uint32_t mask);
bool setMBUserFilter(FLEXCAN_MAILBOX mb_num, uint32_t id1, uint32_t id2, uint32_t mask);
bool setMBUserFilter(FLEXCAN_MAILBOX mb_num, uint32_t id1, uint32_t id2, uint32_t id3, uint32_t mask);
bool setMBUserFilter(FLEXCAN_MAILBOX mb_num, uint32_t id1, uint32_t id2, uint32_t id3, uint32_t id4, uint32_t mask);

Where are these stashed?

I can't find them in the FlexCAN_T4.h.

Thanks

Bruce
 
it's in there, search for it, you are probably looking in wrong template class, CAN & CANFD have a different class, but I don't think that will work because to be a base class both will have to have the identical functions to have a virtual function call and only CAN2.0 has the function. If it does fail to compile though, you can put a dummy function in the CANFD class so it matches the CAN2.0 class and put the semi-colon surrounded by brackets "{;}", this will create an empty function for the FD side

Do you plan to use every single function? ��
 
Last edited:
We are both right on this one.....

it's in there, search for it, you are probably looking in wrong template class, CAN & CANFD have a different class, but I don't think that will work because to be a base class both will have to have the identical functions to have a virtual function call and only CAN2.0 has the function. If it does fail to compile though, you can put a dummy function in the CANFD class so it matches the CAN2.0 class and put the semi-colon surrounded by brackets "{;}", this will create an empty function for the FD side

Do you plan to use every single function? ��

Well you are right because it is in github.

I am right because it was not packaged with Teensyduino.

Which also makes sense because when I compiled some examples I got compiler warnings.

No, I am not using all of the just the key ones associated with MB and to disable FIFO.

Thanks

Bruce
 
Code:
FCTPFD_CLASS class FlexCAN_T4FD : public FlexCAN_T4_Base {
  public:
virtual bool setMBUserFilter(FLEXCAN_MAILBOX mb_num, uint32_t id1, uint32_t id2, uint32_t id3, uint32_t id4, uint32_t mask) = 0{;}
??

I tried to find dummy functions in C++ on the internet but can not find anything applicable.

Thanks
 
dont use virtual and dont use = 0 for the class

Code:
bool setMBUserFilter(FLEXCAN_MAILBOX mb_num, uint32_t id1, uint32_t id2, uint32_t id3, uint32_t id4, uint32_t mask) {;} // empty function to satisfy base class
 
dont use virtual and dont use = 0 for the class

Code:
bool setMBUserFilter(FLEXCAN_MAILBOX mb_num, uint32_t id1, uint32_t id2, uint32_t id3, uint32_t id4, uint32_t mask) {;} // empty function to satisfy base class


I will 100% have to take your word for it as I can't find anything like the on the interweb....

Thanks

I dive it and let you know.
 
C:\Users\bvernham\Dropbox (Isuzu North America)\Personal Backup\arduino-1.8.13\hardware\teensy\avr\libraries\FlexCAN_T4/FlexCAN_T4.h:314:18: error: 'virtual void FlexCAN_T4_Base::setBaudRate(uint32_t, FLEXCAN_RXTX)' cannot be overloaded
virtual void setBaudRate(uint32_t baud = 1000000, FLEXCAN_RXTX listen_only = TX) = 0;
^
C:\Users\bvernham\Dropbox (Isuzu North America)\Personal Backup\arduino-1.8.13\hardware\teensy\avr\libraries\FlexCAN_T4/FlexCAN_T4.h:308:18: error: with 'virtual void FlexCAN_T4_Base::setBaudRate(uint32_t, FLEXCAN_RXTX)'
virtual void setBaudRate(uint32_t baud = 1000000, FLEXCAN_RXTX listen_only = TX) = 0;
^
C:\Users\bvernham\Dropbox (Isuzu North America)\Personal Backup\arduino-1.8.13\hardware\teensy\avr\libraries\FlexCAN_T4/FlexCAN_T4.h:336:18: error: 'virtual void FlexCAN_T4_Base::eek:nReceive(_MB_ptr)' cannot be overloaded
virtual void onReceive(_MB_ptr handler) = 0; /* global callback function */
^
C:\Users\bvernham\Dropbox (Isuzu North America)\Personal Backup\arduino-1.8.13\hardware\teensy\avr\libraries\FlexCAN_T4/FlexCAN_T4.h:331:15: error: with 'virtual void FlexCAN_T4_Base::eek:nReceive(_MB_ptr)'
virtual void onReceive(_MB_ptr handler) = 0; /* global callback function */
^
C:\Users\bvernham\Dropbox (Isuzu North America)\Personal Backup\arduino-1.8.13\hardware\teensy\avr\libraries\FlexCAN_T4/FlexCAN_T4.h: In member function 'virtual void FlexCAN_T4_Base::reset()':
C:\Users\bvernham\Dropbox (Isuzu North America)\Personal Backup\arduino-1.8.13\hardware\teensy\avr\libraries\FlexCAN_T4/FlexCAN_T4.h:315:38: error: 'softReset' was not declared in this scope
virtual void reset() { softReset() = 0; } /* reset flexcan controller (needs register restore capabilities...) */
^
C:\Users\bvernham\Dropbox (Isuzu North America)\Personal Backup\arduino-1.8.13\hardware\teensy\avr\libraries\FlexCAN_T4/FlexCAN_T4.h: In member function 'virtual void FlexCAN_T4_Base::disableFIFO()':
C:\Users\bvernham\Dropbox (Isuzu North America)\Personal Backup\arduino-1.8.13\hardware\teensy\avr\libraries\FlexCAN_T4/FlexCAN_T4.h:318:48: error: invalid use of 'void'
virtual void disableFIFO() { enableFIFO(0) = 0; }
^
C:\Users\bvernham\Dropbox (Isuzu North America)\Personal Backup\arduino-1.8.13\hardware\teensy\avr\libraries\FlexCAN_T4/FlexCAN_T4.h: In member function 'virtual void FlexCAN_T4_Base::disableFIFOInterrupt()':
C:\Users\bvernham\Dropbox (Isuzu North America)\Personal Backup\arduino-1.8.13\hardware\teensy\avr\libraries\FlexCAN_T4/FlexCAN_T4.h:320:66: error: invalid use of 'void'
virtual void disableFIFOInterrupt() { enableFIFOInterrupt(0) = 0; }
^
C:\Users\bvernham\Dropbox (Isuzu North America)\Personal Backup\arduino-1.8.13\hardware\teensy\avr\libraries\FlexCAN_T4/FlexCAN_T4.h: In member function 'virtual void FlexCAN_T4_Base::disableMBInterrupts()':
C:\Users\bvernham\Dropbox (Isuzu North America)\Personal Backup\arduino-1.8.13\hardware\teensy\avr\libraries\FlexCAN_T4/FlexCAN_T4.h:329:64: error: invalid use of 'void'
virtual void disableMBInterrupts() { enableMBInterrupts(0) = 0; }
^
C:\Users\bvernham\Dropbox (Isuzu North America)\Personal Backup\arduino-1.8.13\hardware\teensy\avr\libraries\FlexCAN_T4/FlexCAN_T4.h: In member function 'bool FlexCAN_T4FD<_bus, _rxSize, _txSize>::setMBUserFilter(FLEXCAN_MAILBOX, uint32_t, uint32_t)':
C:\Users\bvernham\Dropbox (Isuzu North America)\Personal Backup\arduino-1.8.13\hardware\teensy\avr\libraries\FlexCAN_T4/FlexCAN_T4.h:405:80: warning: no return statement in function returning non-void [-Wreturn-type]
bool setMBUserFilter(FLEXCAN_MAILBOX mb_num, uint32_t id1, uint32_t mask){;}
^
C:\Users\bvernham\Dropbox (Isuzu North America)\Personal Backup\arduino-1.8.13\hardware\teensy\avr\libraries\FlexCAN_T4/FlexCAN_T4.h: In member function 'bool FlexCAN_T4FD<_bus, _rxSize, _txSize>::setMBUserFilter(FLEXCAN_MAILBOX, uint32_t, uint32_t, uint32_t)':
C:\Users\bvernham\Dropbox (Isuzu North America)\Personal Backup\arduino-1.8.13\hardware\teensy\avr\libraries\FlexCAN_T4/FlexCAN_T4.h:406:94: warning: no return statement in function returning non-void [-Wreturn-type]
bool setMBUserFilter(FLEXCAN_MAILBOX mb_num, uint32_t id1, uint32_t id2, uint32_t mask){;}
^
C:\Users\bvernham\Dropbox (Isuzu North America)\Personal Backup\arduino-1.8.13\hardware\teensy\avr\libraries\FlexCAN_T4/FlexCAN_T4.h: In member function 'bool FlexCAN_T4FD<_bus, _rxSize, _txSize>::setMBUserFilter(FLEXCAN_MAILBOX, uint32_t, uint32_t, uint32_t, uint32_t)':
C:\Users\bvernham\Dropbox (Isuzu North America)\Personal Backup\arduino-1.8.13\hardware\teensy\avr\libraries\FlexCAN_T4/FlexCAN_T4.h:407:108: warning: no return statement in function returning non-void [-Wreturn-type]
bool setMBUserFilter(FLEXCAN_MAILBOX mb_num, uint32_t id1, uint32_t id2, uint32_t id3, uint32_t mask){;}
^
C:\Users\bvernham\Dropbox (Isuzu North America)\Personal Backup\arduino-1.8.13\hardware\teensy\avr\libraries\FlexCAN_T4/FlexCAN_T4.h: In member function 'bool FlexCAN_T4FD<_bus, _rxSize, _txSize>::setMBUserFilter(FLEXCAN_MAILBOX, uint32_t, uint32_t, uint32_t, uint32_t, uint32_t)':
C:\Users\bvernham\Dropbox (Isuzu North America)\Personal Backup\arduino-1.8.13\hardware\teensy\avr\libraries\FlexCAN_T4/FlexCAN_T4.h:408:122: warning: no return statement in function returning non-void [-Wreturn-type]
bool setMBUserFilter(FLEXCAN_MAILBOX mb_num, uint32_t id1, uint32_t id2, uint32_t id3, uint32_t id4, uint32_t mask){;} ^
Code:
static FlexCAN_T4_Base* myCAN[3] = { nullptr };
FlexCAN_T4<CAN1, RX_SIZE_2, TX_SIZE_16> Can1;
FlexCAN_T4<CAN2, RX_SIZE_2, TX_SIZE_16> Can2;
FlexCAN_T4<CAN3, RX_SIZE_2, TX_SIZE_16> Can3;

bool StartCAN()
{
  myCAN[0] = &Can1;
  myCAN[1] = &Can2;
  myCAN[2] = &Can3;
  myCAN[0]->begin();
  myCAN[0]->disableFIFO();
  myCAN[0]->setMBFilter(REJECT_ALL);
  myCAN[0]->setBaudRate((uint16_t)(bus[0].BaudRate * 500));
  myCAN[0]->setMaxMB(NUM_TX_MAILBOXES + Num_Tot_RX_MB);

Apparently it does not like a lot of these functions even setbaurdrate(

Thanks

Bruce
 
virtual void disableFIFO() = 0; dont copy the bracket stuff
Add only one at a time and compile to see if it is correct before pasting alot, too many errors to deal with after
 
Last edited:
What about the function overloading for baud rate?

Also it does not seem to like C:\Users\bvernham\Dropbox (Isuzu North America)\Personal Backup\arduino-1.8.13\hardware\teensy\avr\libraries\FlexCAN_T4/FlexCAN_T4.h:408:122: warning: no return statement in function returning non-void [-Wreturn-type]
bool setMBUserFilter(FLEXCAN_MAILBOX mb_num, uint32_t id1, uint32_t id2, uint32_t id3, uint32_t id4, uint32_t mask){;} ^

Thanks
 
Code:
class FlexCAN_T4_Base {
  public:
    virtual void flexcan_interrupt() = 0;
    virtual void setBaudRate(uint32_t baud = 1000000, FLEXCAN_RXTX listen_only = TX) = 0;
    virtual uint64_t events() = 0;
    virtual int write(const CANFD_message_t &msg) = 0;
    virtual int write(const CAN_message_t &msg) = 0;
    virtual bool isFD() = 0;
    virtual uint8_t getFirstTxBoxSize();
};

it's already there, did you duplicate it? Only reason it's there is because setClock uses it to reconfigure baudrate on a new controller clock switch
 
Yeah, missed that one...

Code:
class FlexCAN_T4_Base {
  public:
    virtual void flexcan_interrupt() = 0;
    virtual void setBaudRate(uint32_t baud = 1000000, FLEXCAN_RXTX listen_only = TX) = 0;
    virtual uint64_t events() = 0;
    virtual int write(const CANFD_message_t &msg) = 0;
    virtual int write(const CAN_message_t &msg) = 0;
    virtual bool isFD() = 0;
    virtual uint8_t getFirstTxBoxSize();
};

it's already there, did you duplicate it? Only reason it's there is because setClock uses it to reconfigure baudrate on a new controller clock switch

Yeah, I duplicated it...missed it.

Does it matter which one is included?
Code:
	virtual void onReceive(const FLEXCAN_MAILBOX &mb_num, _MB_ptr handler) = 0; /* individual mailbox callback function */
	//virtual void onReceive(_MB_ptr handler) = 0; /* global callback function */[/CODE

I do not think it does but just checking.

Thanks

Bruce
 
Code:
  for (int i = 0; i<NUM_TX_MAILBOXES; i++)
  {
    if (bus[CanChannels].STDFrame == 0)
    {
      myCAN[channel]->setMB(i,TX,EXT);
    }

Then the compiler complains

6_CANFunctions.h: In function 'bool SetCAN(uint8_t)':
C:\Users\bvernham\AppData\Local\Temp\arduino_build_605453\sketch\6_CANFunctions.h:97:37: warning: invalid conversion from 'int' to 'FLEXCAN_MAILBOX' [-fpermissive]
myCAN[channel]->setMB(i,TX,EXT);
^
In file included from C:\Users\bvernham\Dropbox (Isuzu North America)\Personal Backup\Arduino\ReadDBCV1\ReadDBCV1.ino:4:0:
C:\Users\bvernham\Dropbox (Isuzu North America)\Personal Backup\arduino-1.8.13\hardware\teensy\avr\libraries\FlexCAN_T4/FlexCAN_T4.h:324:18: note: initializing argument 1 of 'virtual bool FlexCAN_T4_Base::setMB(const FLEXCAN_MAILBOX&, const FLEXCAN_RXTX&, const FLEXCAN_IDE&)'
virtual bool setMB(const FLEXCAN_MAILBOX &mb_num, const FLEXCAN_RXTX &mb_rx_tx, const FLEXCAN_IDE &ide = STD) = 0;
^

But I know in the header file:

typedef enum FLEXCAN_MAILBOX {
MB0 = 0,
MB1 = 1,
MB2 = 2,
MB3 = 3,
MB4 = 4,
MB5 = 5,
MB6 = 6,
MB7 = 7,
MB8 = 8,
MB9 = 9,
MB10 = 10,
MB11 = 11,
MB12 = 12,
MB13 = 13,
MB14 = 14,
MB15 = 15,
MB16 = 16,
MB17 = 17,
MB18 = 18,
MB19 = 19,
MB20 = 20,
MB21 = 21,
MB22 = 22,

So in reality the enumeration is referencing an integer anyways so how do you get around the enumeration and just use and integer?

Thanks

Bruce
 
Just in case anyone is interested this is where I have gotten so far:
CAN1.dbc
CAN2.dbc
CAN3.dbc
Total Signal Count: 831
CAN: 1
Messages: 65
Baudrate: 500000
Protocol: J1939
STD ID: 0
EXT ID: 65
DBC Signals: 357
PID: 0
CAN: 2
Messages: 1
Baudrate: 500000
Protocol: OBD-2
STD ID: 1
EXT ID: 0
DBC Signals: 149
PID: 114
CAN: 3
Messages: 69
Baudrate: 500000
Protocol: Unknown
STD ID: 69
EXT ID: 0
DBC Signals: 325
PID: 0
SetCAN: CAN: 1
DBC Messages: 65, RX Mail Boxes: 60
STDFrame: 0, EXTFrame: 65
Num_STD_RX_MB: 0, Num_EXT_RX_MB: 60
STD_Num_SingMess_MB: 0, EXT_Num_SingMess_MB: 55
STD_Num_2Mess_MB: 0, EXT_Num_2Mess_MB: 5
Settting EXT TX MB #: 0 1 2 3
Settting EXT RX MB #: 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63

SetCAN: CAN: 2
DBC Messages: 1, RX Mail Boxes: 1
STDFrame: 1, EXTFrame: 0
Num_STD_RX_MB: 0, Num_EXT_RX_MB: 0
STD_Num_SingMess_MB: 1, EXT_Num_SingMess_MB: 0
STD_Num_2Mess_MB: 0, EXT_Num_2Mess_MB: 0
Settting STD TX MB #: 0 1 2 3
Settting STD RX MB #: 4

SetCAN: CAN: 3
DBC Messages: 69, RX Mail Boxes: 60
STDFrame: 69, EXTFrame: 0
Num_STD_RX_MB: 60, Num_EXT_RX_MB: 0
STD_Num_SingMess_MB: 51, EXT_Num_SingMess_MB: 0
STD_Num_2Mess_MB: 9, EXT_Num_2Mess_MB: 0
Settting STD TX MB #: 0 1 2 3
Settting STD RX MB #: 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63

Done

Work with mixed standard and extended in each DBC file.
 
Good morning. Is there something similar to the myCan.available() function (like in the older FlexCAN library) in this new library? I am using the 4.1 for a new project and I would like to only read in a message when one is waiting. Is there a function like this? Thank you for your time regarding this.
Code:
if (Can0.available())
    { // checks if there is a waiting message, if so then it reads it in
      digitalWrite(LED_U5, 0);
      digitalWrite(LED_U9, 1);

      while (Can0.read(rxmsg))
      {

        lostCommCounter = 0;
        //        Serial.println(CANid);
              Serial.println("Mask");
              Serial.println(CANid);
              Serial.println("ID");
              Serial.println(rxmsg.id);
        ////      Serial.println("\n");
        //      Serial.println("EXT");
        //      Serial.println(rxmsg.ext);
        //      Serial.println("LENGTH");
        //      Serial.println(rxmsg.len);
        //      Serial.println("timeout");
        //      Serial.println(rxmsg.timeout);
        //      if (CANid == (byte) rxmsg.id)
        //      {
        for (i = 0; i < 8; i++)
        {
          newCANinfo[i] = (byte) rxmsg.buf[i];
          //                      Serial.println(newCANinfo[i]);
          newCANinfoflag = true;
//          Serial.println(rxmsg.buf[i]);
        }
        //      }

        lostComms.reset();
      }

This is how I used the older FlexCAN on the 3.2
 
Back
Top