Skip to main content
b1aze
Associate III
December 17, 2025
Solved

STM32H7 FDCAN configured in CAN2.0 is not working

  • December 17, 2025
  • 1 reply
  • 985 views

Hi guys i have a nucleo h7A3Zi-q dev board . i am trying to receive CAN messges sent from ESP32 borads . esp is sending can  frame by using SN65HVD232D. and i configured the FDCAN to receive the can messages . esp can is set at 500 kbits , and my stm configurations is like this 

static void MX_FDCAN1_Init(void)
{

 /* USER CODE BEGIN FDCAN1_Init 0 */

 /* USER CODE END FDCAN1_Init 0 */

 FDCAN_ClkCalUnitTypeDef sCcuConfig = {0};

 /* USER CODE BEGIN FDCAN1_Init 1 */

 /* USER CODE END FDCAN1_Init 1 */
 hfdcan1.Instance = FDCAN1;
 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 = 8;
 hfdcan1.Init.NominalSyncJumpWidth = 1;
 hfdcan1.Init.NominalTimeSeg1 = 13;
 hfdcan1.Init.NominalTimeSeg2 = 2;
 hfdcan1.Init.DataPrescaler = 1;
 hfdcan1.Init.DataSyncJumpWidth = 1;
 hfdcan1.Init.DataTimeSeg1 = 1;
 hfdcan1.Init.DataTimeSeg2 = 1;
 hfdcan1.Init.MessageRAMOffset = 0;
 hfdcan1.Init.StdFiltersNbr = 1;
 hfdcan1.Init.ExtFiltersNbr = 0;
 hfdcan1.Init.RxFifo0ElmtsNbr = 0;
 hfdcan1.Init.RxFifo0ElmtSize = FDCAN_DATA_BYTES_8;
 hfdcan1.Init.RxFifo1ElmtsNbr = 0;
 hfdcan1.Init.RxFifo1ElmtSize = FDCAN_DATA_BYTES_8;
 hfdcan1.Init.RxBuffersNbr = 0;
 hfdcan1.Init.RxBufferSize = FDCAN_DATA_BYTES_8;
 hfdcan1.Init.TxEventsNbr = 0;
 hfdcan1.Init.TxBuffersNbr = 0;
 hfdcan1.Init.TxFifoQueueElmtsNbr = 0;
 hfdcan1.Init.TxFifoQueueMode = FDCAN_TX_FIFO_OPERATION;
 hfdcan1.Init.TxElmtSize = FDCAN_DATA_BYTES_8;
 if (HAL_FDCAN_Init(&hfdcan1) != HAL_OK)
 {
 Error_Handler();
 }
 sCcuConfig.ClockDivider = FDCAN_CLOCK_DIV1;
 sCcuConfig.MinOscClkPeriods = 0x00;
 sCcuConfig.CalFieldLength = FDCAN_CALIB_FIELD_LENGTH_32;
 sCcuConfig.TimeQuantaPerBitTime = 4;
 sCcuConfig.WatchdogStartValue = 0x0000;
 if (HAL_FDCAN_ConfigClockCalibration(&hfdcan1, &sCcuConfig) != HAL_OK)
 {
 Error_Handler();
 }
 /* USER CODE BEGIN FDCAN1_Init 2 */

 /* USER CODE END FDCAN1_Init 2 */

}
void can_init(void)
{
	if(can_h == NULL)
		Error_Handler();
	CanRxQueue = xQueueCreateStatic(16,sizeof(can_frame_t),ucQueueStorageArea,&xStaticQueue);
	if (CanRxQueue == NULL)
		Error_Handler();

	sFilter.IdType = FDCAN_STANDARD_ID;
	sFilter.FilterIndex = 0u;
	sFilter.FilterID1 = 0;
	sFilter.FilterID2 = 0x1FFFFFFF;
	sFilter.FilterType = FDCAN_FILTER_RANGE;
	sFilter.FilterConfig = FDCAN_FILTER_TO_RXFIFO0;
	//sFilter.RxBufferIndex = FDCAN_FILTER_TO_RXBUFFER;

	if(HAL_FDCAN_ConfigFilter(can_h,&sFilter)!= HAL_OK){
		Error_Handler();
	}
	if(HAL_FDCAN_Start(can_h) != HAL_OK){
		Error_Handler();
	}

	if(HAL_FDCAN_ActivateNotification(can_h,FDCAN_IT_RX_FIFO0_NEW_MESSAGE,0)!=HAL_OK){
		Error_Handler();
	}

	printf("can initialized \n");
}
void HAL_FDCAN_RxFifoCallback(FDCAN_HandleTypeDef *hfdcan,uint32_t RxFifo0ITs)
{
	printf("can callback \n");
	Error_Handler();
	if((RxFifo0ITs & FDCAN_IT_RX_FIFO0_NEW_MESSAGE) != RESET)
	{
		if(HAL_FDCAN_GetRxMessage(can_h, FDCAN_RX_FIFO0, &RxHeader, RxData) != HAL_OK)
			/* Reception Error */
			Error_Handler();

		rxdata.can_id = RxHeader.Identifier;
		rxdata.can_dlc = RxHeader.DataLength;
		memcpy(rxdata.data , RxData , CAN_MAX_DATA);

		BaseType_t xHigherPriorityTaskWoken = pdFALSE;
		xQueueSendFromISR(CanRxQueue,&rxdata,&xHigherPriorityTaskWoken);

		if(xHigherPriorityTaskWoken)
		{
			portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
		}

		if (HAL_FDCAN_ActivateNotification(hfdcan, FDCAN_IT_RX_FIFO0_NEW_MESSAGE, 0) != HAL_OK)
		 /* Notification Error */
		 Error_Handler();
	}

}

.

b1aze_0-1765963936905.png

b1aze_1-1765963951279.png

 

what i need is the can should work in interrupt mode . and i have to set up multiple esp and receive those messges.

 

edit : currently working with internal loopback mode still not reciving anything , i am not sure if sending is working  but defintely sure that not reciving anything.

Best answer by mƎALLEm

I don't know about ESP, you need to check your ESP CAN configuration. You should have the same CAN bitrate.

For the timing and as you are using Classical CAN, you can refer to this knowledge base, it was written for bxCAN but the principle is the same: select a sample point at about 87.5%CAN (bxCAN) bit time configuration on STM32 MCUs

1 reply

mƎALLEm
Technical Moderator
December 19, 2025

You are using a standard ID filter while ID2 is an extended ID!

mALLEm_0-1766137918590.png

Use Mask ID with all filters IDs set to 0 if you want to receive all the CAN messages.

Did you enable the NVIC interrupt line for FDCAN?

Refer also to the following knowledge base articles:

STM32 FDCAN running at 8 Mb/s on NUCLEO boards

How to use FDCAN to create a simple communication with a basic filter

 

"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."
b1aze
b1azeAuthor
Associate III
December 20, 2025

yeah now i tried one of your example with the loop back mode . almost got it working but with one issue. i can read from RX_FIFO0 while in debug mode , because of breakpoints , but if i try to run it in normal i am not getting anything inside my rxbuffer . can is running at 500 kbits . any idea to fix this issue  or whats causing it

MX_GPIO_Init();
 MX_FDCAN2_Init();
 MX_USART3_UART_Init();
 /* USER CODE BEGIN 2 */
 
 /* Configure standard ID reception filter to Rx buffer 0 */
 sFilterConfig.IdType = FDCAN_STANDARD_ID;
 sFilterConfig.FilterIndex = 0;
 sFilterConfig.FilterType = FDCAN_FILTER_MASK;
 sFilterConfig.FilterConfig = FDCAN_FILTER_TO_RXBUFFER;
 sFilterConfig.FilterID1 = 0x000;
 sFilterConfig.FilterID2 = 0x000;
 sFilterConfig.RxBufferIndex = 0;
 if(HAL_FDCAN_ConfigFilter(&CAN_USED, &sFilterConfig) != HAL_OK)
 {
	 Error_Handler();
 }

 /* Configure extended ID reception filter to Rx FIFO 1 */
 sFilterConfig.IdType = FDCAN_EXTENDED_ID;
 sFilterConfig.FilterIndex = 0;
 sFilterConfig.FilterType = FDCAN_FILTER_RANGE_NO_EIDM;
 sFilterConfig.FilterConfig = FDCAN_FILTER_TO_RXFIFO1;
 sFilterConfig.FilterID1 = 0x1111111;
 sFilterConfig.FilterID2 = 0x2222222;
 if(HAL_FDCAN_ConfigFilter(&CAN_USED, &sFilterConfig) != HAL_OK)
 {
	 Error_Handler();
 }
 HAL_FDCAN_GetRxFifoFillLevel(&hfdcan2,FDCAN_RX_FIFO0);
 /* Start the FDCAN module */
 if(HAL_FDCAN_Start(&CAN_USED) != HAL_OK)
 {
	 Error_Handler();
 }
 HAL_FDCAN_ActivateNotification(
 &hfdcan2,
 FDCAN_IT_RX_FIFO0_NEW_MESSAGE,
 0
 );
 /* Configure Tx buffer message */
 TxHeader.Identifier = 0x111;
 TxHeader.IdType = FDCAN_STANDARD_ID;
 TxHeader.TxFrameType = FDCAN_DATA_FRAME;
 TxHeader.DataLength = FDCAN_DLC_BYTES_8;
 TxHeader.ErrorStateIndicator = FDCAN_ESI_ACTIVE;
 TxHeader.BitRateSwitch = FDCAN_BRS_OFF;
 TxHeader.FDFormat = FDCAN_CLASSIC_CAN;
 TxHeader.TxEventFifoControl = FDCAN_STORE_TX_EVENTS;
 TxHeader.MessageMarker = 0x52;
 if(HAL_FDCAN_AddMessageToTxBuffer(&CAN_USED, &TxHeader, TxData0, FDCAN_TX_BUFFER0) !=HAL_OK)
 {
	 Error_Handler();
 }

 /* Send Tx buffer message */
 HAL_FDCAN_EnableTxBufferRequest(&CAN_USED, FDCAN_TX_BUFFER0);

 

void HAL_FDCAN_RxFifo0Callback(FDCAN_HandleTypeDef *hfdcan, uint32_t RxFifo0ITs)
{
 if (RxFifo0ITs & FDCAN_IT_RX_FIFO0_NEW_MESSAGE)
 {


 HAL_FDCAN_GetRxMessage(&hfdcan2,
 FDCAN_RX_FIFO0,
 &RxHeader,
							 RxData);

 // Process data here
 // (toggle LED, set flag, copy buffer, etc.)
 }
}