2021-05-04 02:05 PM
Hello all, I am starting a new project based on the STM32F302 MCU and I am running into an interesting clock configuration timeout issue that results in a fault during most debug sessions. So far, all I have done is configure the clock tree and enabled the USB peripheral as a virtual COM port.
I am using an external 16 MHz oscillator which feeds directly to the system clock. The USB peripheral clock is generated using the internal PLL x3 to 48 MHz.
The System Clock Config function generated is given below:
void SystemClock_Config(void)
{
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
RCC_PeriphCLKInitTypeDef PeriphClkInit = {0};
/** Initializes the RCC Oscillators according to the specified parameters
* in the RCC_OscInitTypeDef structure.
*/
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
RCC_OscInitStruct.HSEState = RCC_HSE_ON;
RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1;
RCC_OscInitStruct.HSIState = RCC_HSI_ON;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL3;
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_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_HSE;
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_0) != HAL_OK)
{
Error_Handler();
}
PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_USB;
PeriphClkInit.USBClockSelection = RCC_USBCLKSOURCE_PLL;
if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)
{
Error_Handler();
}
}
The timeout occurs in the first snippet:
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
RCC_PeriphCLKInitTypeDef PeriphClkInit = {0};
/** Initializes the RCC Oscillators according to the specified parameters
* in the RCC_OscInitTypeDef structure.
*/
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
RCC_OscInitStruct.HSEState = RCC_HSE_ON;
RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1;
RCC_OscInitStruct.HSIState = RCC_HSI_ON;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL3;
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) // RETURNS HAL_TIMEOUT
{
Error_Handler();
}
The timeout occurs about 80% of the time, and I can not get the device to register as a virtual com port at all. I have a very similar setup running on a STM32F405 with no issues. I have included the external pullup since it is required by the F302.
Do any of you have any wisdom as to what is going on here? I have the same code running on another part number just fine.
Thank you!
Matthew
Solved! Go to Solution.
2021-05-04 03:32 PM
RCC_OscInitStruct.HSEState = RCC_HSE_BYPASS; // Not required to need starting or wait for it to come ready
2021-05-04 02:08 PM
Is this a custom board? You could dig into HAL_RCC_OscConfig to find the reason. Probably the HSE is never going stable, which would suggest a hardware error.
2021-05-04 02:09 PM
Is this a custom board? You could dig into HAL_RCC_OscConfig to find the reason. Probably the HSE is never going stable, which would suggest a hardware error.
2021-05-04 02:34 PM
External oscillator? Should RCC_HSE_BYPASS be used?
2021-05-04 03:12 PM
Hi TDK, thanks for the reply. Yes, this is a custom board, but the external oscillator setup is very similar to other boards I have made that work reliably. I have also looked at the oscillator output on an oscilloscope and everything looks good.
2021-05-04 03:12 PM
Hi Tesla, yes I am using an external oscillator. I am still a little inexperienced with this, could you clarify what RCC_HSE_BYPASS does, and where you think it should be used? Thanks!
2021-05-04 03:32 PM
RCC_OscInitStruct.HSEState = RCC_HSE_BYPASS; // Not required to need starting or wait for it to come ready
2021-05-04 04:53 PM
Hi Tesla, it looks like that was the problem! Thank you so much!
Can I ask, what is the reason that this option is preferred? When I connect an external oscillator (not a crystal), is this always the correct option to use?
Thanks again,
Matthew
2021-05-04 06:11 PM
The primary effects are how OSC_IN buffers, standard GPIO INPUT, Schmitt Trigger, and it turns off the inverter allowing OSC_OUT to be a GPIO.
It allows for higher input frequencies in most STM32 designs, say 50 MHz, although the F3 is 32 MHz per data sheet.
2021-05-05 08:19 AM
> Can I ask, what is the reason that this option is preferred?
If you have an external clock source that doesn't need driven by the chip, and only one pin is connected, you should select bypass mode.
If you have a crystal that needs driven, with both OSC pins connected, you need normal HSE mode.