FlexCAN Mailbox Provisioning

Status
Not open for further replies.

brad95411

Member
I'm looking to provision specific mailboxes for specific IDs, thus far I've been unable to get it to work with the code below. I have 4 IDs and 4 mailboxes I want to provision.

They currently use a common callback simply because I'm only interested in what mailbox each ID is ending up at this point.

My understanding from Collin80's readme for the the FlexCAN library is that you set a filter and mask for a particular mailbox and if the following equation:

MASK AND ID = FILTERID

evaluates to true then that is the mailbox that that particular CAN frame will be placed in when it is received.

The question is, have I misplaced something, or am I missing some piece to the puzzle that's not explicitly mentioned in the readme, or even more likely have I done something blatantly wrong? Any help is appreciated, thanks!

Code:
 #include <FlexCAN.h>

static CAN_filter_t status1Filter, status2Filter, status3Filter, statusEnergyFilter;

class CANClass : public CANListener 
{
public:
   void printFrame(CAN_message_t &frame, int mailbox);
   void gotFrame(CAN_message_t &frame, int mailbox); //overrides the parent version so we can actually do something
};

void CANClass::printFrame(CAN_message_t &frame, int mailbox)
{
   Serial.print(mailbox);
   Serial.print(" ID: ");
   Serial.print(frame.id, HEX);
   Serial.print(" Data: ");
   for (int c = 0; c < frame.len; c++) 
   {
      Serial.print(frame.buf[c], HEX);
      Serial.write(' ');
   }
   Serial.println("\n");
}

void CANClass::gotFrame(CAN_message_t &frame, int mailbox)
{
    printFrame(frame, mailbox);
}

CANClass inbound;

void setup() {
  delay(5000);
  Serial.println(F("Beginning initial setup\n"));

  Can0.begin(1000000);
  Can0.attachObj(&inbound);
  
  status1Filter.id = 0x8041400;
  status1Filter.ext = 1;
  status1Filter.rtr = 0;

  status2Filter.id = 0x8041440;
  status2Filter.ext = 1;
  status2Filter.rtr = 0;

  status3Filter.id = 0x8041480;
  status3Filter.ext = 1;
  status3Filter.rtr = 0;

  statusEnergyFilter.id = 0x8041740;
  statusEnergyFilter.ext = 1;
  statusEnergyFilter.rtr = 0;

  Serial.println(F("Mailbox filtering setup"));
  Can0.setFilter(status1Filter, 0);
  Can0.setFilter(status2Filter, 1);
  Can0.setFilter(status3Filter, 2);
  Can0.setFilter(statusEnergyFilter, 3);

  Serial.println(F("Mailbox masking setup"));
  Can0.setMask(0x8041400, 0);
  Can0.setMask(0x8041440, 1);
  Can0.setMask(0x8041480, 2);
  Can0.setMask(0x8041740, 3);

  Serial.println(F("Mailbox handling binding started"));
  inbound.attachMBHandler(0);
  inbound.attachMBHandler(1);
  inbound.attachMBHandler(2);
  inbound.attachMBHandler(3);

  Serial.println(F("Setup Done\n"));

}

void loop() {

}
 
Still struggling to figure this out, has anyone gotten masking and filtering to work at all with Collin80's verison of the FlexCAN library? The frames are just going into random mailboxes, whatever's readily available.

As a sub-update, I realized I was using Pawlesky's library not Collin80's, but I've retested and stuff is still not working. Code below:

Code:
#include <FlexCAN.h>

static CAN_filter_t status1Filter, status2Filter, status3Filter, statusEnergyFilter;

class CANClass : public CANListener 
{
public:
   bool printFrame(CAN_message_t &frame, int mailbox);
   bool frameHandler(CAN_message_t &frame, int mailbox, uint8_t controller); //overrides the parent version so we can actually do something
};

bool CANClass::printFrame(CAN_message_t &frame, int mailbox)
{
   Serial.print(mailbox);
   Serial.print(" ID: ");
   Serial.print(frame.id, HEX);
   Serial.print(" Data: ");
   for (int c = 0; c < frame.len; c++) 
   {
      Serial.print(frame.buf[c], HEX);
      Serial.write(' ');
   }
   Serial.println("\n");

   return true;
}

bool CANClass::frameHandler(CAN_message_t &frame, int mailbox, uint8_t controller)
{
    return printFrame(frame, mailbox);
}

CANClass inbound;

void setup() {
  delay(1000);
  Serial.println(F("Beginning initial setup\n"));

  Can0.begin(1000000);
  Can0.attachObj(&inbound);
   
  status1Filter.id = 0x8041400;
  status1Filter.ext = 1;
  status1Filter.rtr = 0;

  status2Filter.id = 0x8041440;
  status2Filter.ext = 1;
  status2Filter.rtr = 0;

  status3Filter.id = 0x8041480;
  status3Filter.ext = 1;
  status3Filter.rtr = 0;

  statusEnergyFilter.id = 0x8041740;
  statusEnergyFilter.ext = 1;
  statusEnergyFilter.rtr = 0;

  Serial.println(F("Mailbox masking setup"));
  Can0.setMask(0x8041400, 0);
  Can0.setMask(0x8041440, 1);
  Can0.setMask(0x8041480, 2);
  Can0.setMask(0x8041740, 3);

  Serial.println(F("Mailbox filtering setup"));
  Can0.setFilter(status1Filter, 0);
  Can0.setFilter(status2Filter, 1);
  Can0.setFilter(status3Filter, 2);
  Can0.setFilter(statusEnergyFilter, 3);

  Serial.println(F("Mailbox handling binding started"));
  inbound.attachMBHandler(0);
  inbound.attachMBHandler(1);
  inbound.attachMBHandler(2);
  inbound.attachMBHandler(3);

  Serial.println(F("Setup Done\n"));

}

void loop() {

}
 
MASK and ID = FILTER is incorrect. It uses contrarian logic. I think I just created a new term. It takes the difference between the ID and FILTER then checks set bits against the mask. If true they don’t make it to the mailbox.

If (ID xor FILTER) and MASK == true, don’t put it in the mb.

Also the readme for Collins lib has an example using 0x7ff. Incorrect. Use 0x07ff0000.
 
Status
Not open for further replies.
Back
Top