Hi all - just recently bought a Teensy 4.0 to start testing and working on moving my CANBUS projects to this platform. Have currently been running with a few different platforms - Arduino Pro Mini with MCP2515 Can Controllers (SLOW!), ESP32s, and Arduino Due's. The performance of the T4 and 3 can controller built in is going to be nice! I'm using CAN2.0 with Extended IDs, so no need for FD for me.
Couple questions/comments about the library.
First - in the lastest version, I found that the writeTXMailbox function was modified and the original is commented out. I had to swap them and re-enable the 2nd one to make it work. Was there a reason for that, or just some testing?
Code:
FCTP_FUNC void FCTP_OPT::writeTxMailbox(uint8_t mb_num, const CAN_message_t &msg) {
writeIFLAGBit(mb_num); // 1st step clear flag in case it's set as per datasheet
( msg.flags.remote ) ? FLEXCANb_MBn_CS(_bus, mb_num) |= FLEXCAN_MB_CS_RTR : FLEXCANb_MBn_CS(_bus, mb_num) &= ~FLEXCAN_MB_CS_RTR;
//FLEXCANb_MBn_CS(_bus, mb_num) = (1UL << 31); // FD frame
FLEXCANb_MBn_CS(_bus, mb_num) |= FLEXCAN_MB_CS_LENGTH(msg.len+7);
FLEXCANb_MBn_WORD0(_bus, mb_num) |= 0x55555555;
//FLEXCANb_MBn_WORD1(_bus, mb_num) |= 0x55555555;
//FLEXCANb_MBn_WORD2(_bus, mb_num) |= 0x55555555;
// for ( uint8_t i = 0; i < msg.len; i++ ) ( i < 4 ) ? (FLEXCANb_MBn_WORD0(_bus, mb_num) |= (*(msg.buf + i)) << ((3 - i) * 8)) : (FLEXCANb_MBn_WORD1(_bus, mb_num) |= (*(msg.buf + i)) << ((7 - i) * 8));
//for ( uint8_t i = 0; i < 8; i++ ) FLEXCANb_MBn_DATA(_bus, mb_num, i) = 0x55555555;
FLEXCANb_MBn_ID(_bus, mb_num) = (( msg.flags.extended ) ? ( msg.id & FLEXCAN_MB_ID_EXT_MASK ) : FLEXCAN_MB_ID_IDSTD(msg.id));
FLEXCANb_MBn_CS(_bus, mb_num) |= FLEXCAN_MB_CS_CODE(FLEXCAN_MB_CODE_TX_ONCE);
if ( msg.flags.remote ) {
uint32_t timeout = millis();
while ( !(readIFLAG() & (1ULL << mb_num)) && (millis() - timeout < 10) );
writeIFLAGBit(mb_num);
FLEXCANb_MBn_CS(_bus, mb_num) = FLEXCAN_MB_CS_CODE(FLEXCAN_MB_CODE_TX_INACTIVE);
}
}
/*
FCTP_FUNC void FCTP_OPT::writeTxMailbox(uint8_t mb_num, const CAN_message_t &msg) {
writeIFLAGBit(mb_num); // 1st step clear flag in case it's set as per datasheet
( msg.flags.remote ) ? FLEXCANb_MBn_CS(_bus, mb_num) |= FLEXCAN_MB_CS_RTR : FLEXCANb_MBn_CS(_bus, mb_num) &= ~FLEXCAN_MB_CS_RTR;
FLEXCANb_MBn_CS(_bus, mb_num) |= FLEXCAN_MB_CS_LENGTH(msg.len);
FLEXCANb_MBn_WORD0(_bus, mb_num) = FLEXCANb_MBn_WORD1(_bus, mb_num) = 0;
for ( uint8_t i = 0; i < msg.len; i++ ) ( i < 4 ) ? (FLEXCANb_MBn_WORD0(_bus, mb_num) |= (*(msg.buf + i)) << ((3 - i) * 8)) : (FLEXCANb_MBn_WORD1(_bus, mb_num) |= (*(msg.buf + i)) << ((7 - i) * 8));
FLEXCANb_MBn_ID(_bus, mb_num) = (( msg.flags.extended ) ? ( msg.id & FLEXCAN_MB_ID_EXT_MASK ) : FLEXCAN_MB_ID_IDSTD(msg.id));
FLEXCANb_MBn_CS(_bus, mb_num) |= FLEXCAN_MB_CS_CODE(FLEXCAN_MB_CODE_TX_ONCE);
if ( msg.flags.remote ) {
uint32_t timeout = millis();
while ( !(readIFLAG() & (1ULL << mb_num)) && (millis() - timeout < 10) );
writeIFLAGBit(mb_num);
FLEXCANb_MBn_CS(_bus, mb_num) = FLEXCAN_MB_CS_CODE(FLEXCAN_MB_CODE_TX_INACTIVE);
}
}
*/
Second - It took me a while to figure out, but it was not sending Extended frames correctly. I figured out what was missing and added it to my code. Just needed the line that sets the extended flag in the msg ID. Before it would send as a standard, even if you set the flag when setting up the message.
Code:
FCTP_FUNC void FCTP_OPT::writeTxMailbox(uint8_t mb_num, const CAN_message_t &msg) {
writeIFLAGBit(mb_num); // 1st step clear flag in case it's set as per datasheet
( msg.flags.remote ) ? FLEXCANb_MBn_CS(_bus, mb_num) |= FLEXCAN_MB_CS_RTR : FLEXCANb_MBn_CS(_bus, mb_num) &= ~FLEXCAN_MB_CS_RTR;
FLEXCANb_MBn_CS(_bus, mb_num) |= FLEXCAN_MB_CS_LENGTH(msg.len);
if (msg.flags.extended) FLEXCANb_MBn_CS(_bus, mb_num) |= FLEXCAN_MB_CS_IDE;
FLEXCANb_MBn_WORD0(_bus, mb_num) = FLEXCANb_MBn_WORD1(_bus, mb_num) = 0;
for ( uint8_t i = 0; i < msg.len; i++ ) ( i < 4 ) ? (FLEXCANb_MBn_WORD0(_bus, mb_num) |= (*(msg.buf + i)) << ((3 - i) * 8)) : (FLEXCANb_MBn_WORD1(_bus, mb_num) |= (*(msg.buf + i)) << ((7 - i) * 8));
FLEXCANb_MBn_ID(_bus, mb_num) = (( msg.flags.extended ) ? ( msg.id & FLEXCAN_MB_ID_EXT_MASK ) : FLEXCAN_MB_ID_IDSTD(msg.id));
FLEXCANb_MBn_CS(_bus, mb_num) |= FLEXCAN_MB_CS_CODE(FLEXCAN_MB_CODE_TX_ONCE);
if ( msg.flags.remote ) {
uint32_t timeout = millis();
while ( !(readIFLAG() & (1ULL << mb_num)) && (millis() - timeout < 10) );
writeIFLAGBit(mb_num);
FLEXCANb_MBn_CS(_bus, mb_num) = FLEXCAN_MB_CS_CODE(FLEXCAN_MB_CODE_TX_INACTIVE);
}
}
I'm no expert, so there may be more that is needed, but it all appears to be working for now! Looking forward to working with this library! These boards have a lot of potential!
Tom