Skip to main content
kruft
Associate II
June 14, 2018
Solved

CAN FIFO0 and FIFO1 stm32f429

  • June 14, 2018
  • 16 replies
  • 7515 views
Posted on June 14, 2018 at 08:37

Hello,

Could you describe difference in use FIFO0 and FIFO1 for CAN1 and CAN2 in stm32f4 mcu? For example if I configure CAN2 for receive in FIFO0 and configurate filters 14 all work success, but if I try use FIFO1 with CAN2 no interrupt CAN2 happen in receive in this case. CAN0 need use with FIFO0 and CAN2 need use with FIFO1 if big data transfer happen, isn't it(or what case when need use separately FIFO for CAN1 and CAN2)?

    This topic has been closed for replies.
    Best answer by kruft
    Posted on June 15, 2018 at 09:36

    Thank you for good discussion I solved it. FIFO1 didn't work because I don't create CAN2_RX1_IRQHandler() I have only 

    CAN2_RX0_IRQHandler() and not permit CAN2_RX1 interrupts. I didn't take note that needed 2 different interrupt handlers for FIFO0 and FIFO1 in my opinion it's strange struct organisation because we have 1 CAN_RxCplt handler and 2 same CAN2_RX0 and CAN2_RX1 interrupt handlers.

    16 replies

    T J
    Senior III
    June 14, 2018
    Posted on June 14, 2018 at 09:13

    did you enable the interrupts of both fifos ?

        __HAL_CAN_ENABLE_IT (&hcan1, CAN_IT_FMP0);       //!< FIFO 0 message pending interrupt //

        __HAL_CAN_ENABLE_IT (&hcan1, CAN_IT_FMP1);       //!< FIFO 1 message pending interrupt //
    kruft
    kruftAuthor
    Associate II
    June 14, 2018
    Posted on June 14, 2018 at 09:57

    I use CubeMX HAL driver system and not use special macros like 

    __HAL_CAN_ENABLE_IT. In success way HAL_CAN_Receive_IT(&hcan2, CAN_FIFO0) work without previous calls 

    __HAL_CAN_ENABLE_IT (&hcan1, CAN_IT_FMP0); but HAL_CAN_Receive_IT(&hcan2, CAN_FIFO1) doesn't work. In function HAL_CAN_Receive_IT() file stm32f4xx_hal_can.c there is next code:  

    if(FIFONumber == CAN_FIFO0)

    {

    /* Enable FIFO 0 message pending Interrupt */

    __HAL_CAN_ENABLE_IT(hcan, CAN_IT_FMP0);

    }

    else

    {

    /* Enable FIFO 1 message pending Interrupt */

    __HAL_CAN_ENABLE_IT(hcan, CAN_IT_FMP1);

    }

    T J
    Senior III
    June 14, 2018
    Posted on June 14, 2018 at 10:34

    I use this method:  step 11 re-enables the interrupt

    void CAN1_RX0_IRQHandler(void)

    {

      /* USER CODE BEGIN CAN1_RX0_IRQn 0 */

        checkCanRxFifos();

      /* USER CODE END CAN1_RX0_IRQn 0 */

      HAL_CAN_IRQHandler(&hcan1);

      /* USER CODE BEGIN CAN1_RX0_IRQn 1 */

      /* USER CODE END CAN1_RX0_IRQn 1 */

    }

    void CAN1_RX1_IRQHandler(void)

    {

      /* USER CODE BEGIN CAN1_RX1_IRQn 0 */

    //    CAN_Rx1_IRQFlag = true;

    //    CAN_IRQFlag = true;

        checkCanRxFifos();

      /* USER CODE END CAN1_RX1_IRQn 0 */

      HAL_CAN_IRQHandler(&hcan1);

      /* USER CODE BEGIN CAN1_RX1_IRQn 1 */

      /* USER CODE END CAN1_RX1_IRQn 1 */

    }

    void checkCanRxFifos(void) {

        int readCanBytecount;

        char canFifo1FullFlag = CAN1->RF1R & CAN_RF1R_FMP1;

        if (canFifo1FullFlag) {

            {

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

                canRxMsgBottomWord[canRxMsgIN]    = CAN1->sFIFOMailBox[1].RDLR;        // load all eight bytes in 2 cycles

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

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

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

                canRxMsgLength[canRxMsgIN] =    readCanBytecount;      

                ++canRxMsgIN &= 0x3F;    // 64 entries only

                canRxMsgTableEMPTY = false;

                if (canRxMsgIN == canRxMsgOUT) canRxMsgTableFULL = true;

            }

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

        }

        char canFifo0FullFlag = CAN1->RF0R & CAN_RF0R_FMP0;

        if (canFifo0FullFlag) {

            {

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

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

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

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

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

                if (canRxMsgTableFULL) {    

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

                }

                else {

                    canRxMsgID[canRxMsgIN] = canRxmsgID;

                    canRxMsgLength[canRxMsgIN] = readCanBytecount;    

                    ++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

            }

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

        }

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

    }

    kruft
    kruftAuthor
    Associate II
    June 14, 2018
    Posted on June 14, 2018 at 11:31

    May be there is a simple solution. I need in CAN1 and CAN2 simultaneously. I don't understand why no interrupts CAN2 happen when I use 

    HAL_CAN_Receive_IT(&hcan2, CAN_FIFO1) instead 

    HAL_CAN_Receive_IT(&hcan2, CAN_FIFO0) when I configurate correct filters for FIFO1:

    CAN_FilterConfTypeDef canFilterConfig;

    canFilterConfig.FilterNumber = 14;

    canFilterConfig.FilterMode = CAN_FILTERMODE_IDMASK;

    canFilterConfig.FilterScale = CAN_FILTERSCALE_32BIT;

    canFilterConfig.FilterIdHigh = 0;

    canFilterConfig.FilterIdLow = 0;

    canFilterConfig.FilterMaskIdHigh = 0;

    canFilterConfig.FilterMaskIdLow = 0;

    canFilterConfig.FilterFIFOAssignment = 1;

    canFilterConfig.FilterActivation = ENABLE;

    canFilterConfig.BankNumber = 14;

    HAL_CAN_ConfigFilter(&hcan2, &canFilterConfig);

    HAL_CAN_Receive_IT(&hcan2, CAN_FIFO1);

    Or you think that it's good if I will be use only FIFO0 for CAN1 and CAN2 simultaneously?
    T J
    Senior III
    June 14, 2018
    Posted on June 14, 2018 at 11:42

     ,

     ,

    // ♯ ♯ -2- Configure the CAN1 Filter ♯ ♯ ♯ ♯ ♯ ♯ ♯ ♯ ♯ ♯ ♯ ♯ ♯ ♯ ♯ ♯ ♯ ♯ ♯ ♯ ♯ ♯ ♯ ♯ ♯ ♯ ♯ ♯ ♯ ♯ ♯ ♯ ♯ ♯ ♯ ♯ ♯ ♯ ♯ ♯ ♯ ♯ ♯

     ,

     , sFilterConfig.FilterNumber  , ,  , , ,  , , ,  , , ,  , , ,  ,= 0,

     ,

     , sFilterConfig.FilterMode ,  , , ,  , , ,  , , ,  , , ,  , , ,  ,= CAN_FILTERMODE_IDMASK,

     ,

     , sFilterConfig.FilterScale  , , ,  , , ,  , , ,  , , ,  , , ,  ,= CAN_FILTERSCALE_32BIT,

     ,

     , sFilterConfig.FilterIdHigh  , ,  , , ,  , , ,  , , ,  , , ,  ,= 0x400 <,<, 5, //11-bit ID in top bits

     ,

     , sFilterConfig.FilterIdLow  , , ,  , , ,  , , ,  , , ,  , , ,  ,= 0x0000,

     ,

     , sFilterConfig.FilterMaskIdHigh , ,  ,  , , ,  , , , , , , , , = 0x600 <,<, 5, , ,  ,// resolves as 0x0400 - 0x05FF

     ,

     , sFilterConfig.FilterMaskIdLow , ,  , , ,  , , ,  , , ,  , , , , = 0x0000,

     ,

     , sFilterConfig.FilterFIFOAssignment , ,  , , , , , , , , = 0,

     ,

     , sFilterConfig.FilterActivation , ,  , , , , , , , , , , , , = ENABLE,

     ,

     , sFilterConfig.BankNumber  , ,  , , ,  , , ,  , , ,  , , ,  , , ,  ,= 0,

    // ♯ ♯ -2- Configure the 2nd CAN1 Filter ♯ ♯ ♯ ♯ ♯ ♯ ♯ ♯ ♯ ♯ ♯ ♯ ♯ ♯ ♯ ♯ ♯ ♯ ♯ ♯ ♯ ♯ ♯ ♯ ♯ ♯ ♯ ♯ ♯ ♯ ♯ ♯ ♯ ♯ ♯ ♯ ♯ ♯ ♯ ♯ ♯ ♯ ♯

     ,

     , sFilterConfig.FilterNumber  , ,  , , ,  , , ,  , , ,  , , ,  ,= 1,

     ,

     , sFilterConfig.FilterMode ,  , , ,  , , ,  , , ,  , , ,  , , ,  ,= CAN_FILTERMODE_IDMASK,

     ,

     , sFilterConfig.FilterScale  , , ,  , , ,  , , ,  , , ,  , , ,  ,= CAN_FILTERSCALE_32BIT,

     ,

     , sFilterConfig.FilterIdHigh  , ,  , , ,  , , ,  , , ,  , , ,  ,= 0x600 <,<, 5, //11-bit ID in top bits , ,  , , ,  ,// command channel

     ,

     , sFilterConfig.FilterIdLow  , , ,  , , ,  , , ,  , , ,  , , ,  ,= 0x0000,

     ,

     , sFilterConfig.FilterMaskIdHigh , ,  , , ,  , , ,  , , , , = 0x700 <,<, 5, , ,  ,// resolves as 0x0600 - 0x06FF

     ,

     , sFilterConfig.FilterMaskIdLow , ,  , , ,  , , ,  , , ,  , , , , = 0x0000,

     ,

     , sFilterConfig.FilterFIFOAssignment , ,  , , , , , , , , = 1,

     ,

     , sFilterConfig.FilterActivation , ,  , , ,  , , ,  , , , , = ENABLE,

     ,

     , sFilterConfig.BankNumber  , ,  , , ,  , , ,  , , ,  , , ,  , , ,  ,= 0,
    kruft
    kruftAuthor
    Associate II
    June 14, 2018
    Posted on June 14, 2018 at 12:21

    Could you test only CAN2 with FIFO1?

    T J
    Senior III
    June 14, 2018
    Posted on June 14, 2018 at 12:41

    Sorry, I only use my personal boards, I only have can1 set up..

    did you change your bank numbers ? and filter numbers ?

    it is your work now.

    did you disable the filter activation ?

    kruft
    kruftAuthor
    Associate II
    June 14, 2018
    Posted on June 14, 2018 at 12:47

    I try change filter number and bank number for CAN2 with FIFO1 (14, 15...) but no success. After 5 hour today I try disable filter activation. Also there is a way test CAN2 in loopback mode for example.

    T J
    Senior III
    June 14, 2018
    Posted on June 14, 2018 at 12:52

    why are your bank and filter numbers so high ?

    what page in the reference manual is that on ?

    this is your work,

    did you see my bank and filter numbers ?

    kruft
    kruftAuthor
    Associate II
    June 14, 2018
    Posted on June 14, 2018 at 13:08

    As I know bank number for CAN1: 0...13 CAN2: 14...27 . In reference manual didn't find full description about it, only phrase that bank number 'shared between CAN1 and CAN2' at page 1076 of 

    http://www.st.com/content/ccc/resource/technical/document/reference_manual/3d/6d/5a/66/b4/99/40/d4/DM00031020.pdf/files/DM00031020.pdf/jcr:content/translations/en.DM00031020.pdf

     
    kruft
    kruftAuthorBest answer
    Associate II
    June 15, 2018
    Posted on June 15, 2018 at 09:36

    Thank you for good discussion I solved it. FIFO1 didn't work because I don't create CAN2_RX1_IRQHandler() I have only 

    CAN2_RX0_IRQHandler() and not permit CAN2_RX1 interrupts. I didn't take note that needed 2 different interrupt handlers for FIFO0 and FIFO1 in my opinion it's strange struct organisation because we have 1 CAN_RxCplt handler and 2 same CAN2_RX0 and CAN2_RX1 interrupt handlers.

    T J
    Senior III
    June 15, 2018
    Posted on June 15, 2018 at 11:09

    happy to help