CAN Filters STM32F767 Topic is solved

Report here problems in any of ChibiOS components. This forum is NOT for support.
mormod
Posts: 3
Joined: Thu Jan 28, 2021 5:09 pm
Been thanked: 1 time

CAN Filters STM32F767

Postby mormod » Thu Jan 28, 2021 5:50 pm

Hi,
I'm trying to implement a simple CAN RX thread for a STM32F767ZIT6 witch ChibiOS 20.3.2 using both RX FIFOs provided by the chip. The used transceiver is a MCP2551SN. As of now, I am able to receive messages just fine, if no filters are applied to them. Problem is, if the filters (shown below) get applied to the mailboxes, all messages get received in mailbox 2 (FIFO1). However, messages with ID 0x00000100 and 0x07000000 should be stored in mailbox 1 (FIFO0), while all other relevant messages should be stored in mailbox 2 (FIFO1).

Code: Select all

CANFilter cfp[3] = {
    {
      .filter = 0,
      .mode = 0,     
      .scale = 1,       
      .assignment = 0,   
      .register1 = 0x07000000,
      .register2 = 0xFFFFFFFF
    },
    {
      .filter = 1,
      .mode = 0,
      .scale = 1,
      .assignment = 0,
      .register1 = 0x00000100,
      .register2 = 0xFFFFFFFF
    },
    {
      .filter = 2,
      .mode = 0,
      .scale = 1,
      .assignment = 1,
      .register1 = 0x00000000,
      .register2 = 0xFFFF0000
    }
  };
 


Since I did not use identifier mode for any of the filters and all are scaled to be 32 bit, I expected filter 0 to be applied first, followed by filter 1 and then 2, leading all messages to their correct mailboxes. I looked at all registers for filters (CAN_FMR, CAN_FM1R, CAN_FS1R, CAN_FFA1R, CAN_FFA1R, CAN_FA1R, as well as all correspondig CAN_FiRx) and they seem to be set up correctly. Did I mess up something in the event system? The whole thread function is shown below.

Code: Select all

THD_FUNCTION(CAN_RX_THD, p) {
  (void)p;
  chRegSetThreadName("CAN_RX");

  event_listener_t receiveListener;
  event_listener_t errorListener;
  CANRxFrame rxFrame;
  CANConfig canConfig;

  /* Initialize filters */

  CANFilter cfp[3] = {
    {
      .filter = 0,
      .mode = 0,     
      .scale = 1,       
      .assignment = 0,   
      .register1 = 0x07000000,
      .register2 = 0xFFFFFFFF
    },
    {
      .filter = 1,
      .mode = 0,
      .scale = 1,
      .assignment = 0,
      .register1 = 0x00000100,
      .register2 = 0xFFFFFFFF
    },
    {
      .filter = 2,
      .mode = 0,
      .scale = 1,
      .assignment = 1,
      .register1 = 0x00000000,
      .register2 = 0xFFFF0000
    }
  };

  /* Activate filters */
  canSTM32SetFilters(&CAND1, 3, 3, cfp);

  /* 75% Sample point, AHP = 54MHz = ABP1. */
  canConfig.btr = CAN_BTR_TS2(3) | CAN_BTR_TS1(12) | CAN_BTR_BRP(2);
  canConfig.mcr = CAN_MCR_AWUM | CAN_MCR_ABOM;

  canStart(&CAND1, &canConfig);

  /* Listen to RX MB0 and MB1 */
  chEvtRegisterMask(&CAND1.rxfull_event, &receiveListener, EVENT_MASK(0));
  chEvtRegisterMask(&CAND1.error_event, &errorListener, EVENT_MASK(1));

  while (!chThdShouldTerminateX()) {
    eventmask_t mask = chEvtWaitAny(EVENT_MASK(0));

    /* Serve RX */
    if (mask & EVENT_MASK(0)) {
      eventflags_t flags = chEvtGetAndClearFlags(&receiveListener);

      /* Check if MB0 received */
      if (flags & CAN_MAILBOX_TO_MASK(1U)) {
        /* Service all messages in this queue */
        while (canReceiveTimeout(&CAND1, 1, &rxFrame, TIME_IMMEDIATE) == MSG_OK) {
         ...
        }
      }

      /* Check if MB1 received */
      if (flags & CAN_MAILBOX_TO_MASK(2U)) {
        /* Service all messages in this queue */
        while (canReceiveTimeout(&CAND1, 2, &rxFrame, TIME_IMMEDIATE) == MSG_OK) {
          ...
        }
      }
    }
    /* Serve errors */
    if (mask & EVENT_MASK(1)) {
        ...
    }
  }
  chEvtUnregister(&CAND1.rxfull_event, &receiveListener);
  chEvtUnregister(&CAND1.error_event, &errorListener);
}


Thanks,
mormod

User avatar
Giovanni
Site Admin
Posts: 14444
Joined: Wed May 27, 2009 8:48 am
Location: Salerno, Italy
Has thanked: 1074 times
Been thanked: 921 times
Contact:

Re: CAN Filters STM32F767

Postby Giovanni » Thu Jan 28, 2021 6:34 pm

Hi,

If all messages physically arrive in FIFO1 then it is not a problem with events but on how filters are encoded. This is more related to STM32 than the driver, which just copies those values into registers (register that you already checked, I assume the values are those expected).

Are the filter registers values correct? I never used that feature personally so I cannot tell right away.

You code looks correct regarding events anyway.

Giovanni

mormod
Posts: 3
Joined: Thu Jan 28, 2021 5:09 pm
Been thanked: 1 time

Re: CAN Filters STM32F767

Postby mormod » Fri Jan 29, 2021 12:22 pm

Hi,
I double checked all the registers.
FMR.CAN2SB = 0x03, so CAN2 gets all the filters from 3 on
FM1R = 0x0..0, so every filter is in masked mode
FS1R = 0x0..07, so every filter is in 32-bit mode
FFA1R = 0x0..04, so filter 2 is assigned to FIFO1, filter 0 and 1 to FIFO0
FA1R = 0x0..07, so filters 0, 1 and 2 are activated.

Interrupts for pendig messages are enabled for both mailboxes.
All the filterbank register are setup correctly with the corresponding masks and identifiers.
Since this does not concern the development of ChibiOS in any way, I'll go search somewhere else for whats wrong :D Thank you for taking a look at this.

On another note, the "assignment" field in the CANFilter struct is commented like this:

Code: Select all

 
  /**
   * @brief   Filter mode.
   * @note    This bit represent the CAN_FFA1R register bit associated to this
   *          filter, must be set to zero in this version of the driver.
   */
  uint32_t                  assignment:1;
 


I think it should be something along the lines of

Code: Select all

 
  /**
   * @brief   Filter assignment to FIFO.
   * @note    This bit represent the CAN_FFA1R register bit associated to this
   *          filter (0=filter for FIFO0, 1=filter for FIFO1).
   */
  uint32_t                  assignment:1;
 


as I cannot see any reason not to use the assignment field, since it gets used later on to set the according bits in the FFA1R register.

BR
mormod

mormod
Posts: 3
Joined: Thu Jan 28, 2021 5:09 pm
Been thanked: 1 time

Re: CAN Filters STM32F767

Postby mormod » Fri Jan 29, 2021 1:37 pm

I actually found the error. Due to the way that the controller compares filters and incoming message IDs, the programmed filters need to be shifted 3 bits to the left if scale = 1 or 5 bits if scale = 0. See figure 501 in the reference manual (also attached). The incoming IDs INCLUDING the IDE, RTR and reserved bit are left aligned with the filters before comparison.

So when writing the actual IDs and masks to filter for to the registers, it would be appropriate to shift the filters first, depending on their length, so users don't have to worry about it themselfs. Maybe something like

Code: Select all

canp->can->sFilterRegister[cfp->filter].FR1 = cfp->register1 << (cfp->scale ? 3 : 5);
canp->can->sFilterRegister[cfp->filter].FR2 = cfp->register2 << (cfp->scale ? 3 : 5);

instead of

Code: Select all

canp->can->sFilterRegister[cfp->filter].FR1 = cfp->register1;
canp->can->sFilterRegister[cfp->filter].FR2 = cfp->register2;

in CANv1/hal_can_lld.c?

BR
mormod
Attachments
filter_comparison.JPG
Demos of filter appliance
Last edited by mormod on Fri Jan 29, 2021 2:59 pm, edited 4 times in total.

User avatar
Giovanni
Site Admin
Posts: 14444
Joined: Wed May 27, 2009 8:48 am
Location: Salerno, Italy
Has thanked: 1074 times
Been thanked: 921 times
Contact:

Re: CAN Filters STM32F767  Topic is solved

Postby Giovanni » Fri Jan 29, 2021 1:45 pm

Hi,

Moving this in "bug reports".

Giovanni


Return to “Bug Reports”

Who is online

Users browsing this forum: Google [Bot] and 11 guests