cancel
Showing results for 
Search instead for 
Did you mean: 

STM32H7 FDCAN configured in CAN2.0 is not working

b1aze
Associate III

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.

1 ACCEPTED SOLUTION

Accepted Solutions

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

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.

View solution in original post

6 REPLIES 6
mƎALLEm
ST Employee

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.

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.)
    }
}

yes got that working now, now the main issue , reading message from esp32 through CAN bus. since i am in STM32H7A3VIT6 anything should i take care of ?

 


@b1aze wrote:

yes got that working now, now the main issue , reading message from esp32 through CAN bus. since i am in STM32H7A3VIT6 anything should i take care of ?


Sorry I didn't understand, what worked for you till now?

+ what are the differences between CAN_USED and hfdcan2 are they the same instance?

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.

okay i tested with the example code from an another post . i that they used FDCAN2 to run can in internal loopback mode . i had issues earlier but that worked when i properly configured the FDCAN2 . but my main goal was to enable can communication between different boards like from esp or another stm32 and recive it . and for can transceiver  i am using SN65HVD232D. so my test setup is esp ->SN65HVD232D ->CAN_H | CAN_L ->SN65HVD232D ->  stm32 

thank you for your resposne @mƎALLEm .

And also whats the use of data prescaler timeseg1,timeseg2 . how to cofigure them , and is that improtant

 

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

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.