cancel
Showing results for 
Search instead for 
Did you mean: 

STM32g474 fdcan RxFIFO1 issues

JRAxelrad
Associate

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.

2 REPLIES 2
Sarra.S
ST Employee

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"

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.

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.