cancel
Showing results for 
Search instead for 
Did you mean: 

CAN FIFO0 and FIFO1 stm32f429

kruft
Associate III
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)?

1 ACCEPTED SOLUTION

Accepted Solutions
kruft
Associate III
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.

View solution in original post

16 REPLIES 16
T J
Lead
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
Associate III
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);

}

kruft
Associate III
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?
kruft
Associate III
Posted on June 14, 2018 at 12:21

Could you test only CAN2 with FIFO1?

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
Associate III
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.

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,
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 ?

Posted on June 14, 2018 at 12:45

Not something I can readily test, but the FIFO selection in the design was supposed to allow messages of different importance to be queued differently, and not a CAN1 vs CAN2 issue

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..