Hello,
Recently I was working with the FlexCAN_t4 library but I encountered some behaviour that I was not expecting based on how I understand the filtering to work. I made a test script that displays the behaviour that I experienced. The behaviour is that only the 18 LSB of an extended CAN ID is used in the filter. So If the ID is 0x00070000 then other messages will alias with it such as 0x0003000 since they have the same 18 LSB. I looked at some of the library code and it appears that the ID is masked against 0x0003FFFF in FLEXCAN_MB_ID_IDEXT() so I'm assuming this is a known and required choice. My questions are:
1. Are the 18 LSB the bits that can be used on a HW filter of a non-FIFO, ie MB, when receiving extended ID CAN frames (even if I'm not using the FIFO, and each mailbox only has a single ID not a range); can I match a full 29 bits extended ID?
2. If it's not a HW limitation? I'm then curious on this design decision; otherwise then that makes a lot of sense but I swear I couldn't find anything on it in the manual (Rev 3). To me it looked like all of the FLEXCANx_RXIMRn registers are available.
Oh yeah, I should mention that I do know about the handy enhanceFilter() method available and I am able to use that. Just seemed odd that it would not be possible to use all 29 bits in a filter, especially since the FIFO can.
Recently I was working with the FlexCAN_t4 library but I encountered some behaviour that I was not expecting based on how I understand the filtering to work. I made a test script that displays the behaviour that I experienced. The behaviour is that only the 18 LSB of an extended CAN ID is used in the filter. So If the ID is 0x00070000 then other messages will alias with it such as 0x0003000 since they have the same 18 LSB. I looked at some of the library code and it appears that the ID is masked against 0x0003FFFF in FLEXCAN_MB_ID_IDEXT() so I'm assuming this is a known and required choice. My questions are:
1. Are the 18 LSB the bits that can be used on a HW filter of a non-FIFO, ie MB, when receiving extended ID CAN frames (even if I'm not using the FIFO, and each mailbox only has a single ID not a range); can I match a full 29 bits extended ID?
2. If it's not a HW limitation? I'm then curious on this design decision; otherwise then that makes a lot of sense but I swear I couldn't find anything on it in the manual (Rev 3). To me it looked like all of the FLEXCANx_RXIMRn registers are available.
Oh yeah, I should mention that I do know about the handy enhanceFilter() method available and I am able to use that. Just seemed odd that it would not be possible to use all 29 bits in a filter, especially since the FIFO can.
Code:
#include <FlexCAN_T4.h>
FlexCAN_T4<CAN1, RX_SIZE_256, TX_SIZE_16> can1;
FlexCAN_T4<CAN2, RX_SIZE_256, TX_SIZE_16> can2;
#define p(msg) Serial.print(msg)
#define pl(msg) Serial.println(msg)
#define ph(msg) Serial.print(msg, HEX)
#define phl(msg) Serial.println(msg, HEX)
#define myCAN_ID 0x00070000
#define mb_rx_test MB0
#define NUMBER_RX_MB 1
#define NUMBER_TX_MB 1
#define CAN_ID_START 0x20000000
#define CAN_ID_END 0x0
#define CAN_ID_INC 0x0001000
CAN_message_t get_ID_CAN_msg(const int id) {
CAN_message_t msg;
msg.len = 0;
msg.flags.extended = 1;
msg.id = id;
return msg;
}
CAN_message_t get_ID_CAN_msg_STD(const int id) {
CAN_message_t msg;
msg.len = 0;
msg.flags.extended = 0;
msg.id = id;
return msg;
}
CAN_message_t msg;
long sum = 0;
void setup() {
Serial.begin(9600);
while ((!Serial) && (millis() < 4000) );
can1.begin();
can1.setBaudRate(1000000);
can1.setMaxMB(NUMBER_TX_MB);
can1.setMB(MB0,TX);
can1.setMBFilter(REJECT_ALL);
can2.begin();
can2.setBaudRate(1000000);
can2.setMaxMB(NUMBER_RX_MB);
can2.setMB(mb_rx_test, RX, EXT);
can2.setMBFilter(mb_rx_test, myCAN_ID);
//can2.enhanceFilter(mb_rx_test);
pl("begin test");
/*for (int id = 0x20000000; id >= 0 ; --id) {*/
can1.write(get_ID_CAN_msg(myCAN_ID));
for (int id = CAN_ID_START; id >= CAN_ID_END ; id -= CAN_ID_INC) {
//if (id % 5000000 == 0) { p("Progess report: "); ph(id); p(" "); pl(sum); }
can1.write(get_ID_CAN_msg(id));
delayMicroseconds(500);
if(can2.read(msg)) {
++sum;
p(msg.mb); p(": "); phl(msg.id);
}
delayMicroseconds(500);
}
p("Sum: "); pl(sum);
pl("End test");
}
void loop() {}