cancel
Showing results for 
Search instead for 
Did you mean: 

FDCAN on STM32C0: transmitting every 100ms, receiver sees frames only every ~497ms

anuj18ap
Associate III

Post edited by ST moderator to be inline with the community rules for the code sharing. In next time please use </> button to paste your code and a linker script content. Please read this post: How to insert source code.

i, I am using STM32C092CCT6 with FDCAN.
I transmit one CAN frame every 100 ms (even tried 50 ms).
But on the receiver side, I always receive frames only every ~497 ms.

It looks like something is delaying or buffering the frames.

What I want to know:
Which FDCAN settings could cause the frames to appear only every ~497 ms?

My problem summary:

  • Tx interval configured: 100 ms → Rx sees ~497 ms

  • Tx interval configured: 50 ms → Rx still ~497 ms

  • So the transmit timing is not coming out correctly.

Request:
Please check if anything is wrong with my FDCAN configuration (below).

/**
* @brief FDCAN1 Initialization Function
*  None
* @retval None
*/
static void MX_FDCAN1_Init(void)
{

/* USER CODE BEGIN FDCAN1_Init 0 */

/* USER CODE END FDCAN1_Init 0 */

/* USER CODE BEGIN FDCAN1_Init 1 */

/* USER CODE END FDCAN1_Init 1 */
hfdcan1.Instance = FDCAN1;
hfdcan1.Init.ClockDivider = FDCAN_CLOCK_DIV1;
hfdcan1.Init.FrameFormat = FDCAN_FRAME_CLASSIC;
hfdcan1.Init.Mode = FDCAN_MODE_NORMAL;
hfdcan1.Init.AutoRetransmission = DISABLE;
hfdcan1.Init.TransmitPause = DISABLE;
hfdcan1.Init.ProtocolException = DISABLE;
hfdcan1.Init.NominalPrescaler = 16;
hfdcan1.Init.NominalSyncJumpWidth = 1;
hfdcan1.Init.NominalTimeSeg1 = 58;
hfdcan1.Init.NominalTimeSeg2 = 1;
hfdcan1.Init.DataPrescaler = 1;
hfdcan1.Init.DataSyncJumpWidth = 1;
hfdcan1.Init.DataTimeSeg1 = 1;
hfdcan1.Init.DataTimeSeg2 = 1;
hfdcan1.Init.StdFiltersNbr = 0;
hfdcan1.Init.ExtFiltersNbr = 0;
hfdcan1.Init.TxFifoQueueMode = FDCAN_TX_FIFO_OPERATION;
if (HAL_FDCAN_Init(&hfdcan1) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN FDCAN1_Init 2 */

/* USER CODE END FDCAN1_Init 2 */

}
13 REPLIES 13
anuj18ap
Associate III

.

anuj18ap
Associate III

The timer interrupt is working properly. It is triggering every 1 ms, and I am counting 100 ms before setting the flag and transmitting the CAN frame. So the transmit function is definitely being called every 100 ms, but on the receiver side I still see approximately 497 ms between frames.

Is there any FDCAN configuration that could cause this delay? I have already tried using HAL_FDCAN_ConfigTxDelayCompensation(&hfdcan1, 5, 0U); in the CAN initialization, but it did not change the result.

void can_bus_init()
{
  /* Configure reception filter to Rx FIFO 0 */
  FDCAN_FilterTypeDef        sFilterConfig;
  sFilterConfig.IdType       = FDCAN_STANDARD_ID;
  sFilterConfig.FilterIndex  = 0U;
  sFilterConfig.FilterType   = FDCAN_FILTER_MASK;
  sFilterConfig.FilterConfig = FDCAN_FILTER_TO_RXFIFO0;
  sFilterConfig.FilterID1    = 0x008;
  sFilterConfig.FilterID2    = 0x7FF;
  if (HAL_FDCAN_ConfigFilter(&hfdcan1, &sFilterConfig) != HAL_OK)
  {
    Error_Handler();
  }
  
 
  sFilterConfig.IdType       = FDCAN_STANDARD_ID;
  sFilterConfig.FilterIndex  = 1U;
  sFilterConfig.FilterType   = FDCAN_FILTER_MASK;
  sFilterConfig.FilterConfig = FDCAN_FILTER_TO_RXFIFO0;
  sFilterConfig.FilterID1    = 0x009;
  sFilterConfig.FilterID2    = 0x7FF;
  if (HAL_FDCAN_ConfigFilter(&hfdcan1, &sFilterConfig) != HAL_OK)
  {
    Error_Handler();
  }
  
  sFilterConfig.IdType       = FDCAN_STANDARD_ID;
  sFilterConfig.FilterIndex  = 2U;
  sFilterConfig.FilterType   = FDCAN_FILTER_MASK;
  sFilterConfig.FilterConfig = FDCAN_FILTER_TO_RXFIFO0;
  sFilterConfig.FilterID1    = 0x00A;
  sFilterConfig.FilterID2    = 0x7FF;
  if (HAL_FDCAN_ConfigFilter(&hfdcan1, &sFilterConfig) != HAL_OK)
  {
    Error_Handler();
  }
  
    /**
    *  Configure global filter:
    *    - Filter all remote frames with STD and EXT ID
    *    - Reject non matching frames with STD ID and EXT ID
    */
  if (HAL_FDCAN_ConfigGlobalFilter(&hfdcan1,
                             FDCAN_ACCEPT_IN_RX_FIFO0, FDCAN_ACCEPT_IN_RX_FIFO0,
                             FDCAN_FILTER_REMOTE, FDCAN_FILTER_REMOTE))
  {
    Error_Handler();
  }
  
  HAL_FDCAN_ConfigTxDelayCompensation(&hfdcan1, 5, 0U);
  
  
  if (HAL_FDCAN_EnableTxDelayCompensation(&hfdcan1) != HAL_OK)
  {
    Error_Handler();
  }

  /* Activate Rx FIFO 0 new message notification */
//  if (HAL_FDCAN_ActivateNotification(&hfdcan1, FDCAN_IT_RX_FIFO0_NEW_MESSAGE, 0U) != HAL_OK)
//  {
//    Error_Handler();
//  }
  
  /* Activate the Tx FiFo Callback */
  HAL_FDCAN_ActivateNotification(&hfdcan1, FDCAN_IT_TX_FIFO_EMPTY, 0U);
  
  /* Start FDCAN controller */
  if (HAL_FDCAN_Start(&hfdcan1) != HAL_OK)
  {
    Error_Handler();
  }
  
}

 

"The timer interrupt is working properly. It triggers every 1 ms, and I am counting 100 ms before setting the flag and transmitting the CAN frame."

-> How are you sure?

Do the test without the timer, use:

HAL_Delay(100);

 

 

To give better visibility on the answered topics, please click on "Accept as Solution" on the reply which solved your issue or answered your question.

If you changed your timer from 100ms to 50ms and you still receive at 497ms, then the problem is likely your Korlan USB-CAN device and/or software, USB driver, etc. To really know for sure is to use an oscilloscope to see the CAN bus message timing. What else are you doing in your main while loop other than checking the flag?

If a reply has proven helpful, click on Accept as Solution so that it'll show at top of the post.
CAN Jammer an open source CAN bus hacking tool
CANableV3 Open Source