cancel
Showing results for 
Search instead for 
Did you mean: 

STM32H70-DK FDCAN Hello everyone: I want to use FDCAN in my board but it is not working. I've been using a few examples I've found as reference but none of them are for my exact board (STM32 H735). Does anyone have an example I can run?

mhuar.1
Associate II
 
10 REPLIES 10
SofLit
ST Employee

Hello,

You didn't mention which example you did use for this?

What is your HW configuration? are you using FDCAN in loopback or Normal mode?

Please provide more details ..

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.
Imen.D
ST Employee

Hello @mhuar.1​ and welcome to the Community :)

Would you please specify the problem that you faced, and when it occurs ?

Try to debug your project and try to identify where is it sticking.

I advise you to review the pins assignment and clock configuration in your code compared to the datasheet of used product.

Have a look to the STM32H73xx device Errata sheet to check if you have the same conditions as described in the doc.

Imen

When your question is answered, please close this topic by clicking "Accept as Solution".
Thanks
Imen

Hello, thanks a lot for answering

My board is the STM32H750-DK, The progrma doesn't stop anywhere, it's just that I dont' get any signal in the CANH or CANL.

Right now, the program is very simple, it's supposed to send the same data over and over.

It runs fine until the FIFO is full then it stops.

As fot the clock, Ive trieg generating code on the IDE and coping examples, it doesn't fix the problem, but it doesn't cause errors either.

Thanks a lot, here are some parts of the program.

This is the while(1) loop:

 while (1)

 {

// HAL_FDCAN_AddMessageToTxFifoQ(&hfdcan1, &TxHeader, TxData0);

 HAL_Delay(200);

 HAL_GPIO_TogglePin(GPIOJ, GPIO_PIN_2);

   /* Start the Transmission process */

   if (HAL_FDCAN_AddMessageToTxFifoQ(&hfdcan1, &TxHeader, TxData1) != HAL_OK)

   {

    /* Transmission request Error */

    Error_Handler();

   }

  /* USER CODE END WHILE */

  /* USER CODE BEGIN 3 */

 }

This is the can config.

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.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 = 1;

 hfdcan1.Init.NominalSyncJumpWidth = 1;

 hfdcan1.Init.NominalTimeSeg1 = 18;

 hfdcan1.Init.NominalTimeSeg2 = 4;

 hfdcan1.Init.DataPrescaler = 1;

 hfdcan1.Init.DataSyncJumpWidth = 1;

 hfdcan1.Init.DataTimeSeg1 = 18;

 hfdcan1.Init.DataTimeSeg2 = 4;

 hfdcan1.Init.MessageRAMOffset = 0;

 hfdcan1.Init.StdFiltersNbr = 0;

 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 = 8;

 hfdcan1.Init.TxFifoQueueElmtsNbr = 15;

 hfdcan1.Init.TxFifoQueueMode = FDCAN_TX_FIFO_OPERATION;

 hfdcan1.Init.TxElmtSize = FDCAN_DATA_BYTES_64;

 if (HAL_FDCAN_Init(&hfdcan1) != HAL_OK)

 {

  Error_Handler();

 }

}

Hello, thanks for the help.

I started with the can loopback example for STM32H735 that was in the IDE because that board was similar to mine (changing some parts the code), I have tried both loopback and normal mode after. I have shared parts of the code, but if you prefer the whole main.c I can send it too.

Here is the clock configuration:

void SystemClock_Config(void)

{

 RCC_OscInitTypeDef RCC_OscInitStruct = {0};

 RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};

 /** Supply configuration update enable

 */

 HAL_PWREx_ConfigSupply(PWR_LDO_SUPPLY);

 /** Configure the main internal regulator output voltage

 */

 __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE3);

 while(!__HAL_PWR_GET_FLAG(PWR_FLAG_VOSRDY)) {}

 /** Initializes the RCC Oscillators according to the specified parameters

 * in the RCC_OscInitTypeDef structure.

 */

 RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;

 RCC_OscInitStruct.HSIState = RCC_HSI_DIV1;

 RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;

 RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;

 RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI;

 RCC_OscInitStruct.PLL.PLLM = 4;

 RCC_OscInitStruct.PLL.PLLN = 9;

 RCC_OscInitStruct.PLL.PLLP = 2;

 RCC_OscInitStruct.PLL.PLLQ = 3;

 RCC_OscInitStruct.PLL.PLLR = 2;

 RCC_OscInitStruct.PLL.PLLRGE = RCC_PLL1VCIRANGE_3;

 RCC_OscInitStruct.PLL.PLLVCOSEL = RCC_PLL1VCOMEDIUM;

 RCC_OscInitStruct.PLL.PLLFRACN = 3072;

 if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)

 {

  Error_Handler();

 }

 /** Initializes the CPU, AHB and APB buses clocks

 */

 RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK

               |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2

               |RCC_CLOCKTYPE_D3PCLK1|RCC_CLOCKTYPE_D1PCLK1;

 RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_HSI;

 RCC_ClkInitStruct.SYSCLKDivider = RCC_SYSCLK_DIV1;

 RCC_ClkInitStruct.AHBCLKDivider = RCC_HCLK_DIV1;

 RCC_ClkInitStruct.APB3CLKDivider = RCC_APB3_DIV1;

 RCC_ClkInitStruct.APB1CLKDivider = RCC_APB1_DIV1;

 RCC_ClkInitStruct.APB2CLKDivider = RCC_APB2_DIV1;

 RCC_ClkInitStruct.APB4CLKDivider = RCC_APB4_DIV1;

 if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_1) != HAL_OK)

 {

  Error_Handler();

 }

}

There is also this part IN the MX_FDCAN1_init function

 TxHeader.Identifier = 10;

 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_ON;

 TxHeader.FDFormat = FDCAN_FD_CAN;

 TxHeader.TxEventFifoControl = FDCAN_STORE_TX_EVENTS;

 //TxHeader.TxEventFifoControl = FDCAN_NO_TX_EVENTS;

 TxHeader.MessageMarker = 0x52;

 HAL_FDCAN_AddMessageToTxBuffer(&hfdcan1, &TxHeader, TxData0, FDCAN_TX_BUFFER0);

 HAL_FDCAN_Start(&hfdcan1);

 HAL_FDCAN_EnableTxBufferRequest(&hfdcan1, FDCAN_TX_BUFFER0);

 /* USER CODE END FDCAN1_Init 2 */

Hello,

You can't use FDCAN in normal mode as there is no complete CAN bus: 2 nodes on the bus. The only mode you can test is the Loopback mode. You can inspire from the example provided under Projects\STM32H743I-EVAL\Examples\FDCAN\FDCAN_Loopback

CAN and CAN-FD are not UART or SPI .. to test them with a single board and see what happen on the pins.

To run the test you provided here (normal mode), you need another board featuring CAN-FD peripheral connected on the same bus of your board.

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.

Please consider my comment above .. + Please use HSE as source clock instead of HSI to avoid some troubleshooting on CAN bit timing.

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.

Hello,

I have tried loopback mode, when I do so, it runs continuously which means the FIFO is working.

I have tried connecting it to a raspberry pi, which already has a CAN recieve program that we know works, but when I try, the FIFO just gets full without sending.

I have changed the clock to HSE, but I don't know if the configuration is correct (I'll add it), as it doesn't allow me to go up to 250000 (bitrate for the raspberry pi is 250000).

Also, the example sets up MPU and CPU_CACHE, is this needed for a basic example?

We are using a IXXAT usb to CAN v2, which is supposed to light up as soon as a device is connected to the bus (it doesn't).

Thanks for the help, since this is my first time doing this, I might have made a lot of mistakes, this is why I originally asked for an example. (STM32H750-DK)

In the end I added the whole main.c

uint8_t TxData0[] = {0x10, 0x32, 0x54, 0x76, 0x98, 0x00, 0x11, 0x22};

uint8_t TxData1[] = {0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55};

int main(void)

{

 HAL_Init();

 /* Configure the system clock */

 SystemClock_Config();

 /* USER CODE BEGIN SysInit */

 /* USER CODE END SysInit */

 /* Initialize all configured peripherals */

 MX_GPIO_Init();

 MX_FDCAN1_Init();

 /* USER CODE BEGIN 2 */

 /* USER CODE END 2 */

 /* Infinite loop */

 /* USER CODE BEGIN WHILE */

 while (1)

 {

// HAL_FDCAN_AddMessageToTxFifoQ(&hfdcan1, &TxHeader, TxData0);

 HAL_Delay(200);

 HAL_GPIO_TogglePin(GPIOJ, GPIO_PIN_2);

   /* Start the Transmission process */

   if (HAL_FDCAN_AddMessageToTxFifoQ(&hfdcan1, &TxHeader, TxData1) != HAL_OK)

   {

    /* Transmission request Error */

    Error_Handler();

   }

  /* USER CODE END WHILE */

  /* USER CODE BEGIN 3 */

 }

 /* USER CODE END 3 */

}

/**

 * @brief System Clock Configuration

 * @retval None

 */

void SystemClock_Config(void)

{

 RCC_OscInitTypeDef RCC_OscInitStruct = {0};

 RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};

 /** Supply configuration update enable

 */

 HAL_PWREx_ConfigSupply(PWR_EXTERNAL_SOURCE_SUPPLY);

 /** Configure the main internal regulator output voltage

 */

 __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE3);

 while(!__HAL_PWR_GET_FLAG(PWR_FLAG_VOSRDY)) {}

 /** Initializes the RCC Oscillators according to the specified parameters

 * in the RCC_OscInitTypeDef structure.

 */

 RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI|RCC_OSCILLATORTYPE_HSE;

 RCC_OscInitStruct.HSEState = RCC_HSE_ON;

 RCC_OscInitStruct.HSIState = RCC_HSI_DIV1;

 RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;

 RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;

 RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;

 RCC_OscInitStruct.PLL.PLLM = 4;

 RCC_OscInitStruct.PLL.PLLN = 24;

 RCC_OscInitStruct.PLL.PLLP = 4;

 RCC_OscInitStruct.PLL.PLLQ = 3;

 RCC_OscInitStruct.PLL.PLLR = 2;

 RCC_OscInitStruct.PLL.PLLRGE = RCC_PLL1VCIRANGE_2;

 RCC_OscInitStruct.PLL.PLLVCOSEL = RCC_PLL1VCOMEDIUM;

 RCC_OscInitStruct.PLL.PLLFRACN = 0;

 if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)

 {

  Error_Handler();

 }

 /** Initializes the CPU, AHB and APB buses clocks

 */

 RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK

               |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2

               |RCC_CLOCKTYPE_D3PCLK1|RCC_CLOCKTYPE_D1PCLK1;

 RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_HSI;

 RCC_ClkInitStruct.SYSCLKDivider = RCC_SYSCLK_DIV1;

 RCC_ClkInitStruct.AHBCLKDivider = RCC_HCLK_DIV1;

 RCC_ClkInitStruct.APB3CLKDivider = RCC_APB3_DIV1;

 RCC_ClkInitStruct.APB1CLKDivider = RCC_APB1_DIV1;

 RCC_ClkInitStruct.APB2CLKDivider = RCC_APB2_DIV1;

 RCC_ClkInitStruct.APB4CLKDivider = RCC_APB4_DIV1;

 if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_1) != HAL_OK)

 {

  Error_Handler();

 }

}

/**

 * @brief FDCAN1 Initialization Function

 * @param 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.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 = 1;

 hfdcan1.Init.NominalSyncJumpWidth = 1;

 hfdcan1.Init.NominalTimeSeg1 = 2;

 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 = 0;

 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 = 8;

 hfdcan1.Init.TxFifoQueueElmtsNbr = 15;

 hfdcan1.Init.TxFifoQueueMode = FDCAN_TX_FIFO_OPERATION;

 hfdcan1.Init.TxElmtSize = FDCAN_DATA_BYTES_8;

 if (HAL_FDCAN_Init(&hfdcan1) != HAL_OK)

 {

  Error_Handler();

 }

 /* USER CODE BEGIN FDCAN1_Init 2 */

 TxHeader.Identifier = 10;

 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_ON;

 TxHeader.FDFormat = FDCAN_FD_CAN;

 TxHeader.TxEventFifoControl = FDCAN_STORE_TX_EVENTS;

 //TxHeader.TxEventFifoControl = FDCAN_NO_TX_EVENTS;

 TxHeader.MessageMarker = 0x52;

 HAL_FDCAN_AddMessageToTxBuffer(&hfdcan1, &TxHeader, TxData0, FDCAN_TX_BUFFER0);

 HAL_FDCAN_Start(&hfdcan1);

 HAL_FDCAN_EnableTxBufferRequest(&hfdcan1, FDCAN_TX_BUFFER0);

 /* USER CODE END FDCAN1_Init 2 */

}

/**

 * @brief GPIO Initialization Function

 * @param None

 * @retval None

 */

static void MX_GPIO_Init(void)

{

 /* GPIO Ports Clock Enable */

 __HAL_RCC_GPIOH_CLK_ENABLE();

 __HAL_RCC_GPIOB_CLK_ENABLE();

/* USER CODE BEGIN 4 */

  GPIO_InitTypeDef GPIO_InitStruct = {0};

 __HAL_RCC_GPIOJ_CLK_ENABLE();

 HAL_GPIO_WritePin(GPIOJ, GPIO_PIN_2|GPIO_PIN_3, GPIO_PIN_RESET);

 GPIO_InitStruct.Pin = GPIO_PIN_2|GPIO_PIN_3;

 GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;

 GPIO_InitStruct.Pull = GPIO_NOPULL;

 GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;

 HAL_GPIO_Init(GPIOJ, &GPIO_InitStruct);

 }

/* USER CODE END 4 */

/**

 * @brief This function is executed in case of error occurrence.

 * @retval None

 */

void Error_Handler(void)

{

 /* USER CODE BEGIN Error_Handler_Debug */

 /* User can add his own implementation to report the HAL error return state */

 __disable_irq();

 while (1)

 {

 }

 /* USER CODE END Error_Handler_Debug */

}