cancel
Showing results for 
Search instead for 
Did you mean: 

What is the correct systemClock_Config to use in order to have USB OTG FS with a 48MHz external cristal as the clock source ?

ALE C.1
Associate II

Hi,

I am working with a STM32H743 and I am trying to use USB OTG FS with the best clock configuration possible. I would like to have a SYSCLK at 480MHz and use the USB OTG FS with the external clock source HSE at 48MHz.

The frequency of the external cristal is 48MHz.

Currently, i have the USB working while using the internal 48MHz clock HSI48 and the SYSCLK at 64MHz using HSI.

Howerver it seem that the moment I switch either the SYSCLK or the USB OTG FS source frequency problems appears.

  • If i choose to use the external clock as the source clock for the USB, my device isn't recognized by the computer at all.
  • If i choose to use the external clock as the source clock for the SYSCLK, my device is recognized by the computer but is unable to start.

Either way, if i use the external clock, it doesn't seem to work.

Am I forgetting something in the systemClock_Config ?

Exemple of systemClock_Config with the external clock as the source clock for the SYSCLK :

RCC_PeriphCLKInitTypeDef PeriphClkInitStruct = {0};
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
 
 
HAL_PWREx_ConfigSupply(PWR_LDO_SUPPLY);
 
__HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE0);
 
while(!__HAL_PWR_GET_FLAG(PWR_FLAG_VOSRDY)) {}
 
 
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI48|RCC_OSCILLATORTYPE_HSI|RCC_OSCILLATORTYPE_HSE;
RCC_OscInitStruct.HSEState = RCC_HSE_ON;
RCC_OscInitStruct.HSIState = RCC_HSI_DIV1;
RCC_OscInitStruct.HSI48State = RCC_HSI48_ON;
RCC_OscInitStruct.CSIState = RCC_CSI_OFF;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
RCC_OscInitStruct.PLL.PLLM = 5;
RCC_OscInitStruct.PLL.PLLN = 100;
RCC_OscInitStruct.PLL.PLLP = 2;
RCC_OscInitStruct.PLL.PLLQ = 10;
RCC_OscInitStruct.PLL.PLLR = 2;
RCC_OscInitStruct.PLL.PLLRGE = RCC_PLL1VCIRANGE_3;
RCC_OscInitStruct.PLL.PLLVCOSEL = RCC_PLL1VCOWIDE;
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_PLLCLK;
RCC_ClkInitStruct.SYSCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.AHBCLKDivider = RCC_HCLK_DIV2;
RCC_ClkInitStruct.APB3CLKDivider = RCC_APB3_DIV2;
RCC_ClkInitStruct.APB1CLKDivider = RCC_APB1_DIV2;
RCC_ClkInitStruct.APB2CLKDivider = RCC_APB2_DIV2;
RCC_ClkInitStruct.APB4CLKDivider = RCC_APB4_DIV2;
 
if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_4) != HAL_OK)
{
	Error_Handler();
}
 
PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_SPI6|RCC_PERIPHCLK_SPI123|RCC_PERIPHCLK_I2C1|RCC_PERIPHCLK_USB;
PeriphClkInitStruct.PLL2.PLL2M = 32;
PeriphClkInitStruct.PLL2.PLL2N = 128;
PeriphClkInitStruct.PLL2.PLL2P = 3;
PeriphClkInitStruct.PLL2.PLL2Q = 3;
PeriphClkInitStruct.PLL2.PLL2R = 2;
PeriphClkInitStruct.PLL2.PLL2RGE = RCC_PLL2VCIRANGE_0;
PeriphClkInitStruct.PLL2.PLL2VCOSEL = RCC_PLL2VCOWIDE;
PeriphClkInitStruct.PLL2.PLL2FRACN = 0;
PeriphClkInitStruct.Spi123ClockSelection = RCC_SPI123CLKSOURCE_PLL2;
PeriphClkInitStruct.Spi6ClockSelection = RCC_SPI6CLKSOURCE_PLL2;
PeriphClkInitStruct.UsbClockSelection = RCC_USBCLKSOURCE_HSI48;
PeriphClkInitStruct.I2c123ClockSelection = RCC_I2C123CLKSOURCE_HSI;
if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK)
{
	Error_Handler();
}

6 REPLIES 6
TDK
Guru

Is HSE_VALUE set to 48000000?

> PeriphClkInitStruct.UsbClockSelection = RCC_USBCLKSOURCE_HSI48;

Since you're still using the same clock for USB as the other config, doesn't make sense that there would be issues with "frequency". Is the code still running correctly? Not stuck in an IRQ handler or infinite loop somewhere?

If you feel a post has answered your question, please click "Accept as Solution".

Still replying even if the message wasn't meant for me 🙂

I didn't have the HSE_VALUE set to the correct value.

I corrected it and it allowed me to use the external clock as the source clock for the SYSCLK (first issue solved).

I tried to use the HSE for the USB but it still doesn't work. If i use another clock source for the USB my device is not recognized.

As for the second part of your message, the rest of the code is running smoothly wether the USB is working/recognized or not.

Thanks for your help.

Aime
ST Employee

Hello ALEC.1,

There are three possibilities for the USB OTG FS's Clock Configuration (max frequency 66Mhz) :

  • By using the internal HSI48 (48Mhz)
  • By using the PLL1Q.
  • By using the PLL3Q.

In order to reach the best performances with SYSCLK at 480MHz and use the USB OTG FS with the external clock source HSE you should use the PLL1Q for the UsbClockSelection.

To avoid any issues you should use STM32CubeMX for the clock and peripherals initialization.

Exemple of systemClock_Config with the external clock as the source clock for the SYSCLK and USB on PLL1 at 64Mhz. Can you try this one ?

0693W00000HpP0QQAV.png0693W00000HpP0lQAF.png 

0693W00000HpP2mQAF.png 

BR,

AMVE.1

Hi and thank you for the fast reply,

I tried the configuration you presented and my device is still not recognized.

Like i mentionned above, when I try to change the USB clock source from HIS48, it stops working.

Hi,

When you switch the clock source for your USB (not connected to HSI48) which PLL do you use ? Because the USB can be clocked only by the HSI48, PLL1 and PLL3, and both PLLs are connected to your HSE oscillator (if configured).

Once you've identified the PLL, can you send me its configuration ? (Coefficients PLLM, PLLN, PLLP, PLLR and PLLQ)

BR

Hi,

I apologized for the delayed response, I tried another time the configuration I used : PLL1 for the USBclock and external clock as the clock source for SYSCLK. Here is the SystemClock_Config :

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_SCALE0);
 
while(!__HAL_PWR_GET_FLAG(PWR_FLAG_VOSRDY)) {}
/** Macro to configure the PLL clock source
 */
__HAL_RCC_PLL_PLLSOURCE_CONFIG(RCC_PLLSOURCE_HSE);
/** 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_DIV2;
RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
RCC_OscInitStruct.PLL.PLLM = 5;
RCC_OscInitStruct.PLL.PLLN = 100;
RCC_OscInitStruct.PLL.PLLP = 2;
RCC_OscInitStruct.PLL.PLLQ = 20;
RCC_OscInitStruct.PLL.PLLR = 2;
RCC_OscInitStruct.PLL.PLLRGE = RCC_PLL1VCIRANGE_3;
RCC_OscInitStruct.PLL.PLLVCOSEL = RCC_PLL1VCOWIDE;
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_PLLCLK;
RCC_ClkInitStruct.SYSCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.AHBCLKDivider = RCC_HCLK_DIV2;
RCC_ClkInitStruct.APB3CLKDivider = RCC_APB3_DIV2;
RCC_ClkInitStruct.APB1CLKDivider = RCC_APB1_DIV2;
RCC_ClkInitStruct.APB2CLKDivider = RCC_APB2_DIV2;
RCC_ClkInitStruct.APB4CLKDivider = RCC_APB4_DIV2;
 
if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_4) != HAL_OK)
{
Error_Handler();
}
}
 
/**
 * @brief Peripherals Common Clock Configuration
 * @retval None
 */
void PeriphCommonClock_Config(void)
{
RCC_PeriphCLKInitTypeDef PeriphClkInitStruct = {0};
 
/** Initializes the peripherals clock
 */
PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_SPI6|RCC_PERIPHCLK_SPI123|RCC_PERIPHCLK_I2C1|RCC_PERIPHCLK_USB;
PeriphClkInitStruct.PLL2.PLL2M = 3;
PeriphClkInitStruct.PLL2.PLL2N = 9;
PeriphClkInitStruct.PLL2.PLL2P = 2;
PeriphClkInitStruct.PLL2.PLL2Q = 3;
PeriphClkInitStruct.PLL2.PLL2R = 2;
PeriphClkInitStruct.PLL2.PLL2RGE = RCC_PLL2VCIRANGE_3;
PeriphClkInitStruct.PLL2.PLL2VCOSEL = RCC_PLL2VCOMEDIUM;
PeriphClkInitStruct.PLL2.PLL2FRACN = 3072;
PeriphClkInitStruct.Spi123ClockSelection = RCC_SPI123CLKSOURCE_PLL2;
PeriphClkInitStruct.Spi6ClockSelection = RCC_SPI6CLKSOURCE_PLL2;
PeriphClkInitStruct.I2c123ClockSelection = RCC_I2C123CLKSOURCE_HSI;
PeriphClkInitStruct.UsbClockSelection = RCC_USBCLKSOURCE_PLL;
if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK)
{
Error_Handler();
}
}

The first time, my device, still, was not recognized however the moment I tried to debug this program by removing all the breakpoints I was using, my device was recognized.

I don't understand how the use of breakpoints can disturb my program from running smoothly.

However, it seems like the device is recognized with the correct configuration so I guess i can't really complain 🙂

Thank you for your help.