Search code examples
ccallbackstm32can-bus

the receive Callaback pending of fifo on CAN does not fire when there is frames on CAN bus


I am developing On STM32F1xx with C language, Until now I am trying to implement CANopen stack using "CANopenNode-master", and I am using 2 interruption.

The first is for timer interruption which process SYNC TPDO and RPDO, the second CAN_Rx_fifo0_msgpendingCallback and in this interruption I manage received message but after doing all configuration needs this interruption (fifo0) does not work. timer period is 1ms.

I used NVIC to give priority and subpriority and to enable IRQ of each interruption.
I put CAN receive fifo0 with high priority (first).
I did setting of my CAN like it should be (I think), but it does not work unlike the timer interruption which works correctly.

to verify that the callback does not works every time there frame on bus from other node than mine:

  1. I just used a printf inside my callback function and it does not work.
  2. I check all time the value of Instance->RF0R and it equal 0 always.

//HeaderCaninit is pointer to hcan .

     CANmodule->CANbaseAddress = *(HeaderCaninit);
                CANmodule->CANbaseAddress.Instance = HeaderCaninit->Instance;

   

     switch (CANbitRate)
            {
            case 1000: CANmodule->CANbaseAddress.Init.Prescaler = 2;
            break;
            case 500: CANmodule->CANbaseAddress.Init.Prescaler = 4;// in our example we choose a prescaler 4 with other setting to get the 1Mb/s
            break;
            default:
            case 250: CANmodule->CANbaseAddress.Init.Prescaler = 8;
            break;
            case 125: CANmodule->CANbaseAddress.Init.Prescaler = 16;
            break;
            case 100: CANmodule->CANbaseAddress.Init.Prescaler = 20;
            break;
            case 50: CANmodule->CANbaseAddress.Init.Prescaler = 40;
            break;
            case 20: CANmodule->CANbaseAddress.Init.Prescaler = 100;
            break;
            case 10: CANmodule->CANbaseAddress.Init.Prescaler = 200;
            break;
            }
    

    CANmodule->CANbaseAddress.Init.SyncJumpWidth =CAN_SJW_1TQ;     // changed by VJ, old value = CAN_SJW_1tq;//chngeD by aziz grib and we follow our CAN setting to get 1Mb/s
        CANmodule->CANbaseAddress.Init.TimeSeg1 = CAN_BS1_4TQ;    // changed by VJ, old value = CAN_BS1_3tq;// changed by GA to follow CAN transmit example = CAN_BS1_4TQ
        CANmodule->CANbaseAddress.Init.TimeSeg2 = CAN_BS2_1TQ;   ``
        CANmodule->CANbaseAddress.Init.AutoRetransmission= DISABLE;   // No Automatic retransmision//AG:if the first transmission fail the seconde is done automatically
        CANmodule->CANbaseAddress.Init.Mode = CAN_MODE_NORMAL;
        CANmodule->CANbaseAddress.Init.TimeTriggeredMode = DISABLE;
        CANmodule->CANbaseAddress.Init.ReceiveFifoLocked = DISABLE;
        CANmodule->CANbaseAddress.Init.TransmitFifoPriority = DISABLE;
    
    
    memset(&CAN_FilterInitStruct, 0, sizeof (CAN_FilterInitStruct));
    //CAN_FilterInitStruct.FilterNumber = 0; // for STM32F4
    CAN_FilterInitStruct.FilterMaskIdHigh = 0x0000;
    CAN_FilterInitStruct.FilterIdLow = 0x0000;
    CAN_FilterInitStruct.FilterIdHigh = 0x0000;
    CAN_FilterInitStruct.FilterMaskIdLow = 0x0000;
    CAN_FilterInitStruct.FilterFIFOAssignment = CAN_RX_FIFO0; 
    CAN_FilterInitStruct.FilterMode = CAN_FILTERMODE_IDMASK;
    CAN_FilterInitStruct.FilterScale = CAN_FILTERSCALE_32BIT;
    CAN_FilterInitStruct.FilterActivation = DISABLE;
    CAN_FilterInitStruct.FilterBank = 0;
    CAN_FilterInitStruct.SlaveStartFilterBank = 14;

  
    if (HAL_CAN_Init(&CANmodule->CANbaseAddress) != HAL_OK)
        {
               // TRACE_DEBUG_WP("res=%d\n\r", result);
               return CO_ERROR_PARAMETERS;  /* CO- Return Init failed */
            }

 

     HAL_CAN_ConfigFilter(&CANmodule->CANbaseAddress, &CAN_FilterInitStruct);
     CAN_OperatingModeRequest(CANmodule->CANbaseAddress, CAN_Mode_Normal);
    if (HAL_CAN_Start(&CANmodule->CANbaseAddress) != HAL_OK)
        {
            /* Start Error */
            Error_Handler();
            printf("--------------------------CANstart_error------------- 
        --------");
        }

// this is the NVIC setting

         static void MX_NVIC_Init(void)
          {
      /* TIM4_IRQn interrupt configuration */
      HAL_NVIC_SetPriority(TIM4_IRQn, 0, 1);
      HAL_NVIC_EnableIRQ(TIM4_IRQn);
      /* CAN1_RX1_IRQn interrupt configuration */
      HAL_NVIC_SetPriority(CAN1_RX1_IRQn, 0, 0);
      HAL_NVIC_EnableIRQ(CAN1_RX1_IRQn);
      /* CAN1_SCE_IRQn interrupt configuration */
      HAL_NVIC_SetPriority(CAN1_SCE_IRQn, 1, 2);
      HAL_NVIC_EnableIRQ(CAN1_SCE_IRQn);
      /* EXTI9_5_IRQn interrupt configuration */
      HAL_NVIC_SetPriority(EXTI9_5_IRQn, 15, 15);
      HAL_NVIC_EnableIRQ(EXTI9_5_IRQn);
    }

//in the main I did

     HAL_CAN_ActivateNotification(&CO->CANmodule[0]->CANbaseAddress,CAN_IT_TX_MAILBOX_EMPTY|CAN_IT_RX_FIFO0_MSG_PENDING);

//in the function callback

    void HAL_CAN_RxFifo0MsgPendingCallback(CAN_HandleTypeDef *hcan)
    {
        printf("TIMI");// it does not work
    
    
        /* Get RX message */
        CO_CANinterrupt_Rx(CO->CANmodule[0]);
    }

expected results:
I put a printf it must be executed.
and the function inside the callback should be executed too.


Solution

  • i resolved that by choosing USB0_CAN_Callback_interrupt on CubeMx instead of Rx0 interrupt than everything is gone right.