cancel
Showing results for 
Search instead for 
Did you mean: 

CAN Filter passes more messages as defined

klaus2
Associate II
Posted on February 17, 2018 at 10:09

I have a problem with STM32F042 CAN Filter mechanism. Basically the CAN is working. I can send and receive messages. But my filter are passing more messages to the FIFO as defined. This is leading to an overrun.Proved by the status bits. I carefully read the register in the reference manual and can not find what I am doing wrong. Here is my code

void initCAN(void){
RCC->APB1ENR|=RCC_APB1ENR_CANEN; // enable CAN clk
CAN->MCR |= CAN_MCR_INRQ; // Enter CAN init mode to write the configuration
while ((CAN->MSR & CAN_MSR_INAK) != CAN_MSR_INAK) { // Wait the init mode entering
/* add time out here for a robust application */
}
 CAN->MCR &=~ CAN_MCR_SLEEP; // Exit sleep mode
CAN->BTR &= ~CAN_BTR_TS1_0; // reset Bit0 and Bit1 
CAN->BTR &= ~CAN_BTR_TS1_1;
CAN->BTR &= ~CAN_BTR_TS2_1; // reset Bit 1 in TS2
CAN->BTR |= 0x1 << 20 | 0x4 << 16 | 0x02F << 0; // set timing to 125kb/s@75%: BS1 = 5, BS2 = 2, prescaler = 48 
CAN->MCR &=~ CAN_MCR_INRQ; // Leave init mode
while ((CAN->MSR & CAN_MSR_INAK) == CAN_MSR_INAK) // Wait the init mode leaving
{
/* add time out here for a robust application */
}
CAN->FMR |= CAN_FMR_FINIT;// enter Filter init mode
 CAN->FA1R &= ~(uint32_t)(CAN_FA1R_FACT0|CAN_FA1R_FACT1); // deactivate filter 0 and 1
CAN->FS1R|=CAN_FS1R_FSC0; // Teo single 32 bit register on filterbank 0
CAN->sFilterRegister[0].FR1 = (uint32_t)(13)<<21 ; // only IDs with stdID 13 should pass
CAN->sFilterRegister[0].FR2 = (uint32_t)(14)<<21;// only IDs with stdID 14 should pass
CAN->FM1R |= CAN_FM1R_FBM0; // Filterbank 0 in ID List mode
CAN->FFA1R|=0x03;// route Filteroutput 0 and 1 to FIFO 1
CAN->FA1R |= CAN_FA1R_FACT0|CAN_FA1R_FACT1; // activate Filter 0 and 1
CAN->FMR &=~ CAN_FMR_FINIT; // leave filterinit mode
}�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?

#stm32f042can #can-filter #can-init
3 REPLIES 3
Posted on February 18, 2018 at 15:25

Not sure I'm up for grinding through the bit level settings.

To filter 13 (0x0D) and 14 (0x0E)

{

  CAN_FilterInitTypeDef CAN_FilterInitStructure;

   

  /* CAN filter configuration */

  CAN_FilterInitStructure.CAN_FilterFIFOAssignment = CAN_FIFO0; // FIFO = 0

  CAN_FilterInitStructure.CAN_FilterMode           = CAN_FilterMode_IdMask; // Filter mode = identifier mask based filtering

  CAN_FilterInitStructure.CAN_FilterScale          = CAN_FilterScale_32bit;

  CAN_FilterInitStructure.CAN_FilterActivation     = ENABLE;

  /* Filter 0x00D */

  CAN_FilterInitStructure.CAN_FilterNumber         = 0;  // CAN 1 [0..13]  CAN 2 [14..27]

  CAN_FilterInitStructure.CAN_FilterIdHigh         = 0x00D << 5; //11-bit ID in top bits

  CAN_FilterInitStructure.CAN_FilterIdLow          = 0;

  CAN_FilterInitStructure.CAN_FilterMaskIdHigh     = 0x7FF << 5;

  CAN_FilterInitStructure.CAN_FilterMaskIdLow      = 0;

   

  CAN_FilterInit(&CAN_FilterInitStructure);

  /* Filter 0x00E */

  CAN_FilterInitStructure.CAN_FilterNumber         = 1;  // CAN 1 [0..13]  CAN 2 [14..27]

  CAN_FilterInitStructure.CAN_FilterIdHigh         = 0x00E << 5; //11-bit ID in top bits

  CAN_FilterInitStructure.CAN_FilterIdLow          = 0;

  CAN_FilterInitStructure.CAN_FilterMaskIdHigh     = 0x7FF << 5;

  CAN_FilterInitStructure.CAN_FilterMaskIdLow      = 0;

   

  CAN_FilterInit(&CAN_FilterInitStructure);

}
Tips, buy me a coffee, or three.. PayPal Venmo Up vote any posts that you find helpful, it shows what's working..
T J
Lead
Posted on February 19, 2018 at 00:35

if you enable the interrupts, you can stack the receieved frames into a LOOKUPTABLE....

void CEC_CAN_IRQHandler(void) {

    /* USER CODE BEGIN CEC_CAN_IRQn 0 */

    CAN_IRQFlag = true;

    checkCanRxFifos();

    /* USER CODE END CEC_CAN_IRQn 0 */

    HAL_CAN_IRQHandler(&hcan);

    /* USER CODE BEGIN CEC_CAN_IRQn 1 */

    /* USER CODE END CEC_CAN_IRQn 1 */

}

void checkCanRxFifos(void) {

    

    int readCanBytecount;

    

    char canFifo1FullFlag = CAN->RF1R & CAN_RF1R_FMP1;

    if (canFifo1FullFlag) {

        {

            readCanBytecount = (CAN->sFIFOMailBox[1].RDTR & 0x0f);    

            canRxMsgBottomWord[canRxMsgIN]    = CAN->sFIFOMailBox[1].RDLR;

            canRxMsgTopWord[canRxMsgIN]    = CAN->sFIFOMailBox[1].RDHR;

            canRxMsgID[canRxMsgIN] = CAN->sFIFOMailBox[1].RIR >> 21;

            CAN->RF1R |= CAN_RF1R_RFOM1;                           // release FIFO

            canRxMsgLength[canRxMsgIN] =    readCanBytecount;  

            canRxMsgIN++;

            canRxMsgIN &= 0x3F;       // 64 entries only

            canRxMsgTableEMPTY = false;

            if (canRxMsgIN == canRxMsgOUT) canRxMsgTableFULL = true;

        }

        CAN->IER |= CAN_IER_FMPIE1;                              // (11)        Set FIFO1 message pending IT enable

    }

    char canFifo0FullFlag = CAN->RF0R & CAN_RF0R_FMP0;

    if (canFifo0FullFlag) {

        {

            readCanBytecount         = (CAN->sFIFOMailBox[0].RDTR & 0x0f);    

            canRxMsgBottomWord[canRxMsgIN]    = CAN->sFIFOMailBox[0].RDLR;

            canRxMsgTopWord[canRxMsgIN]    = CAN->sFIFOMailBox[0].RDHR;

            uint32_t canRxmsgID =  CAN->sFIFOMailBox[0].RIR >> 21;

            CAN->RF0R |= CAN_RF0R_RFOM0;                          // release FIFO

            if(canRxMsgTableFULL) {    

                canRxMsgTableOverflow = true;   // now dump new frame...

            }else {

                canRxMsgID[canRxMsgIN] = canRxmsgID;

                canRxMsgLength[canRxMsgIN] = readCanBytecount;          // to signify FIFO0

                canRxMsgIN++;

                canRxMsgIN &= 0x3F;      // 64 entries only

                canRxMsgTableEMPTY = false;

                if (canRxMsgIN == canRxMsgOUT)

                    canRxMsgTableFULL = true;

            }

            

            //length = sprintf(string + length,'%08X, %08X :W',canFifoBuf.d32[0],canFifoBuf.d32[1]);

            //            for( int i = 0; i < readCanBytecount; i++){            

            //                canRxBuffer[canRxpointerIN++] =  canFifoBuf.d8[i];            

            //                canRxpointerIN &= 0xFF;

            //                if (canRxpointerIN == canRxpointerOUT )        CanRxbufferOverrun = true;

            //                //length += sprintf(string + length,'%02X, ',canFifoBuf.d8[i]);

            //            }

            //sprintf(string + length -2,'\n\r');        // remove 2 bytes, the last comma and space

            

        }

        CAN->IER |= CAN_IER_FMPIE0;          // (11)        Set FIFO1 message pending IT enable

    }

    //            if (length >0)  puts(string);

}

Ben K
Senior III
Posted on February 19, 2018 at 10:22

You seem to be confusing the filter banks with the filters themselves. In your configuration (32 bit ID list mode) filter bank 0 (CAN->sFilterRegister[0]) stores two ID filters. Therefore you need to enable filter bank 0 only, and not enable filter bank 1, which is why you get undesired frames now.