Skip to main content
Graduate
April 24, 2024
Question

STM32g474 fdcan RxFIFO1 issues

  • April 24, 2024
  • 2 replies
  • 1392 views

Hello everyone.
I'm working on the stm32G474RBT6 MCU and I'm trying to set up both FDCAN1 and FDCAN2 to work simultaneously.
I wanted to map the FDCAN1 to RxFIFO0 and the FDCAN2 to RFIFO1. The FDCAN1 work perfectly while the FDCAN2 doesn't seem to get any callback from the RxFIFO1 at all (I tried using both of them on the RxFIFO0 and in that configuration I was able to communicate with both FDCAN peripherals, but this won't due as I need them to have separate callback functionalities).

This is how I setup my peripherals:

 

 

/* FDCAN1 init function */
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_FD_BRS;
 hfdcan1.Init.Mode = FDCAN_MODE_NORMAL;
 hfdcan1.Init.AutoRetransmission = DISABLE;
 hfdcan1.Init.TransmitPause = DISABLE;
 hfdcan1.Init.ProtocolException = DISABLE;
 hfdcan1.Init.NominalPrescaler = 2;
 hfdcan1.Init.NominalSyncJumpWidth = 20;
 hfdcan1.Init.NominalTimeSeg1 = 59;
 hfdcan1.Init.NominalTimeSeg2 = 20;
 hfdcan1.Init.DataPrescaler = 2;
 hfdcan1.Init.DataSyncJumpWidth = 4;
 hfdcan1.Init.DataTimeSeg1 = 15;
 hfdcan1.Init.DataTimeSeg2 = 4;
 hfdcan1.Init.StdFiltersNbr = 1;
 hfdcan1.Init.ExtFiltersNbr = 0;
 hfdcan1.Init.TxFifoQueueMode = FDCAN_TX_QUEUE_OPERATION;
 if (HAL_FDCAN_Init(&hfdcan1) != HAL_OK)
 {
 Error_Handler();
 }
 /* USER CODE BEGIN FDCAN1_Init 2 */

 /* USER CODE END FDCAN1_Init 2 */

}
/* FDCAN2 init function */
void MX_FDCAN2_Init(void)
{

 /* USER CODE BEGIN FDCAN2_Init 0 */

 /* USER CODE END FDCAN2_Init 0 */

 /* USER CODE BEGIN FDCAN2_Init 1 */

 /* USER CODE END FDCAN2_Init 1 */
 hfdcan2.Instance = FDCAN2;
 hfdcan2.Init.ClockDivider = FDCAN_CLOCK_DIV1;
 hfdcan2.Init.FrameFormat = FDCAN_FRAME_FD_BRS;
 hfdcan2.Init.Mode = FDCAN_MODE_NORMAL;
 hfdcan2.Init.AutoRetransmission = DISABLE;
 hfdcan2.Init.TransmitPause = DISABLE;
 hfdcan2.Init.ProtocolException = DISABLE;
 hfdcan2.Init.NominalPrescaler = 2;
 hfdcan2.Init.NominalSyncJumpWidth = 20;
 hfdcan2.Init.NominalTimeSeg1 = 59;
 hfdcan2.Init.NominalTimeSeg2 = 20;
 hfdcan2.Init.DataPrescaler = 2;
 hfdcan2.Init.DataSyncJumpWidth = 4;
 hfdcan2.Init.DataTimeSeg1 = 15;
 hfdcan2.Init.DataTimeSeg2 = 4;
 hfdcan2.Init.StdFiltersNbr = 1;
 hfdcan2.Init.ExtFiltersNbr = 0;
 hfdcan2.Init.TxFifoQueueMode = FDCAN_TX_QUEUE_OPERATION;
 if (HAL_FDCAN_Init(&hfdcan2) != HAL_OK)
 {
 Error_Handler();
 }
 /* USER CODE BEGIN FDCAN2_Init 2 */

 /* USER CODE END FDCAN2_Init 2 */

}

void fd_controller_init(FDCAN_HandleTypeDef* fdcan, FDcanController *comm, uint8_t deviceID){

	comm->fdcan = *fdcan;
	comm->device_id = deviceID;
	comm->send_message = false;
	comm->received_message = false;

	comm->fd_can_delay1 = 5;
	comm->fd_can_delay2 = 0;

	comm->TxHeader.Identifier = comm->device_id;
	comm->TxHeader.IdType=FDCAN_STANDARD_ID;
	comm->TxHeader.TxFrameType=FDCAN_DATA_FRAME;
	comm->TxHeader.DataLength=FDCAN_DLC_BYTES_2;
	comm->TxHeader.ErrorStateIndicator=FDCAN_ESI_PASSIVE;
	comm->TxHeader.BitRateSwitch=FDCAN_BRS_OFF;
	comm->TxHeader.FDFormat=FDCAN_FD_CAN;
	comm->TxHeader.TxEventFifoControl=FDCAN_NO_TX_EVENTS;
	comm->TxHeader.MessageMarker=0;

	// Set BRS on for FDcan RX
	comm->RxHeader.BitRateSwitch = FDCAN_BRS_ON;

	comm->TxFrame.id.isCANFD = true;
	comm->TxFrame.id.isExt = false;
	comm->TxFrame.id.isRemote = false;
	comm->TxFrame.dlc = 32;

	memset(comm->RxFrame.data, 0, 64);

	HAL_FDCAN_ConfigTxDelayCompensation(&comm->fdcan, comm->fd_can_delay1, comm->fd_can_delay2);
	HAL_FDCAN_EnableTxDelayCompensation(&comm->fdcan);

	memset(comm->RxData , 0 , RX_BUFFER_SIZE);

}

bool fd_controller_start(FDcanController *comm){

	if (HAL_FDCAN_Start(&comm->fdcan) != HAL_OK) {
		FD_CAN_Error_Handler("start bus");
		return false;
	}

	if (comm->device_id == FDCAN_TX_ID){
	 // Activate the notification for new data in FIFO0 for FDCAN1
	 if (HAL_FDCAN_ActivateNotification(&comm->fdcan, FDCAN_IT_RX_FIFO0_NEW_MESSAGE, 0) != HAL_OK) {
	 FD_CAN_Error_Handler("activate bus");
	 return false;
	 }
	} else {
	 // Activate the notification for new data in FIFO1 for FDCAN2
	 if (HAL_FDCAN_ActivateNotification(&comm->fdcan, FDCAN_IT_RX_FIFO1_NEW_MESSAGE, 0) != HAL_OK) {
	 FD_CAN_Error_Handler("activate bus");
	 return false;
	 }
	}

	return true;
}

// FDCAN1 Callback
void HAL_FDCAN_RxFifo0Callback(FDCAN_HandleTypeDef *hfdcan, uint32_t RxFifo0ITs) {
	if ((RxFifo0ITs & FDCAN_IT_RX_FIFO0_NEW_MESSAGE) != RESET) {
		/* Retreive Rx messages from RX FIFO0 */
		if (HAL_FDCAN_GetRxMessage(&fdcan_controller.fdcan, FDCAN_RX_FIFO0, &fdcan_controller.RxHeader, &fdcan_controller.RxFrame.data) != HAL_OK) {
			/* Reception Error */
			FD_CAN_Error_Handler("get message on CANBUS");
			g_Flags.newCANBUSMessage = false;
			return;
		}
		fdcan_controller.RxFrame.id.id = fdcan_controller.RxHeader.Identifier;
		fdcan_controller.RxFrame.id.isCANFD = (FDCAN_FD_CAN == fdcan_controller.RxHeader.FDFormat) ? true : false;
		fdcan_controller.RxFrame.id.isExt = (FDCAN_EXTENDED_ID == fdcan_controller.RxHeader.IdType) ? true : false;
		fdcan_controller.RxFrame.id.isRemote = (FDCAN_REMOTE_FRAME == fdcan_controller.RxHeader.RxFrameType) ? true : false;
		//RxFrame.dlc = (uint8_t)dlc_len_table[rxHeader.DataLength>>16U ]; //(rxHeader.DataLength >> 16U);
		fdcan_controller.RxFrame.dlc = dlc_len_table[fdcan_controller.RxHeader.DataLength >> 16U]; //(rxHeader.DataLength >> 16U);

		g_Flags.newCANBUSMessage = true;

	}
}

// FDCAN2 Callback
void HAL_FDCAN_RxFifo1Callback(FDCAN_HandleTypeDef *hfdcan, uint32_t RxFifo1ITs) {
	if ((RxFifo1ITs & FDCAN_IT_RX_FIFO1_NEW_MESSAGE) != RESET) {
		/* Retreive Rx messages from RX FIFO1 */
		if (HAL_FDCAN_GetRxMessage(&fdcan_controller_2.fdcan, FDCAN_RX_FIFO1, &fdcan_controller_2.RxHeader, &fdcan_controller_2.RxFrame.data) != HAL_OK) {
			/* Reception Error */
			FD_CAN_Error_Handler("get message on CANBUS");
			g_Flags.newCANBUSMessage = false;
			return;
		}
		fdcan_controller_2.RxFrame.id.id = fdcan_controller_2.RxHeader.Identifier;
		fdcan_controller_2.RxFrame.id.isCANFD = (FDCAN_FD_CAN == fdcan_controller_2.RxHeader.FDFormat) ? true : false;
		fdcan_controller_2.RxFrame.id.isExt = (FDCAN_EXTENDED_ID == fdcan_controller_2.RxHeader.IdType) ? true : false;
		fdcan_controller_2.RxFrame.id.isRemote = (FDCAN_REMOTE_FRAME == fdcan_controller_2.RxHeader.RxFrameType) ? true : false;
		//RxFrame.dlc = (uint8_t)dlc_len_table[rxHeader.DataLength>>16U ]; //(rxHeader.DataLength >> 16U);
		fdcan_controller_2.RxFrame.dlc = dlc_len_table[fdcan_controller_2.RxHeader.DataLength >> 16U]; //(rxHeader.DataLength >> 16U);

		g_Flags.newCANBUSMessage = true;

	}
}

 

 

 And this is how I call them in my main.c file:

 

 

MX_FDCAN1_Init();
MX_FDCAN2_Init(); 

fd_controller_init(&hfdcan1, &fdcan_controller, FDCAN_TX_ID);
fd_controller_start(&fdcan_controller);

fd_controller_init(&hfdcan2, &fdcan_controller_2, FDCAN_TX_ID_2);
fd_controller_start(&fdcan_controller_2);

 

 

 
If anyone has any ideas as to why I can't seem to get any callback from the RxFIFO1 please let me know.
Thank you in advance.

    This topic has been closed for replies.

    2 replies

    ST Employee
    April 24, 2024

    Hello @JRAxelrad

    Ensure that the dedicated FDCAN RAM is properly configured and divided between FDCAN1 and FDCAN2, with correct start offset addresses for each instance

    You can refer to the "RAM management" section in AN5348 "FDCAN peripheral on STM32 devices" for more details, particularly the section "4.2.2 Multiple FDCAN instances"

    JRAxelradAuthor
    Graduate
    April 24, 2024

    Thank you @Sarra.S  for the quick reply!
    I thought about this, but I couldn't find a method of properly adding an offset to the message ram property of the FDCAN on the stm32g474 mcu.

    Explorer
    September 24, 2025

    is this solved by a manual/example or related to my observations?

    Im using a STM32G0B1 with 

    #define __STM32G0xx_HAL_VERSION_MAIN (0x01U) /*!< [31:24] main version */
    #define __STM32G0xx_HAL_VERSION_SUB1 (0x04U) /*!< [23:16] sub1 version */
    #define __STM32G0xx_HAL_VERSION_SUB2 (0x06U) /*!< [15:8] sub2 version */
    #define __STM32G0xx_HAL_VERSION_RC (0x00U) /*!< [7:0] release candidate */

    initially i had two can handles and wanted to use one RXFifo for each:

    hfdcan2 -> Fifo0
    hfdcan1 -> Fifo1

    After i cant get Fifo1 to work i read this article and unconfigured can1 completely and tried it only with can2 which is constantly receiving in my setup.

     
    HAL_FDCAN_ActivateNotification(&hfdcan2, FDCAN_IT_RX_FIFO0_NEW_MESSAGE, 0);
    HAL_FDCAN_Start(&hfdcan2);
    // triggers HAL_FDCAN_RxFifo0Callback(FDCAN_HandleTypeDef *hfdcan, uint32_t RxFifo0ITs)
    
    // ---------
    HAL_FDCAN_ActivateNotification(&hfdcan2, FDCAN_IT_RX_FIFO1_NEW_MESSAGE, 0);
    HAL_FDCAN_Start(&hfdcan2);
    // wont trigger HAL_FDCAN_RxFifo1Callback(FDCAN_HandleTypeDef *hfdcan, uint32_t RxFifo1ITs)

    HAL_FDCAN_IRQHandler is not called when configured with Fifo1