Why are my uarts not working after rcc clock configuration?
Hi all,
I got a strange issue. I'd like to use USART3 or UART5 on my STM32F446 chip. We have the chip on a pcb, so I am not talking about the nucleo board.
The issue is when I do the system_clock_config(), the listed uarts does not work.
void init()
{
// Loop forever on error such that the error can be diagnosed with a debugger.
auto loop_forever = []() { while (true) {} };
if (HAL_Init() != HAL_OK) { loop_forever(); }
if (system_clock_config() != HAL_OK) { loop_forever(); }
gpio_config();
}auto system_clock_config()
{
RCC_ClkInitTypeDef rcc_clk_init {};
RCC_OscInitTypeDef rcc_osc_init {};
/* Enable Power Control clock */
__HAL_RCC_PWR_CLK_ENABLE();
/* Max frequency of the chip is 168MHz (voltage scale 1, normal mode)
* or 180Mhz (voltage scale 1, overdrive mode)
* Lower power consumption and heat can be achieved if the internal voltage regulator
* is set to a lower level.
* With a scale factor of 3, the lowest voltage across the two ceramic condensators
* of the oscillator is configured. The maximum frequency for a scale factor 3 is 120MHz.
* The RCC frequency HCLK (SystemCoreClock) is configured to 80MHz, which results in
* even lower energy consumption.
* It must be taken into account that the TSIC506 of this sensorhub is based on timer
* configuration for data bit reading. Configuring HCLK below 80MHz is therefore not considered.
* To update the voltage scaling value regarding system frequency,
* refer to product datasheet and the CubeMX graphical clock configuration tool.
*/
__HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE3);
/* Enable HSI Oscillator and activate PLL with HSI as source */
rcc_osc_init.OscillatorType = RCC_OSCILLATORTYPE_HSI;
rcc_osc_init.HSIState = RCC_HSI_ON;
rcc_osc_init.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
rcc_osc_init.LSIState = RCC_LSI_ON;
rcc_osc_init.PLL.PLLState = RCC_PLL_ON;
rcc_osc_init.PLL.PLLSource = RCC_PLLSOURCE_HSI;
rcc_osc_init.PLL.PLLM = 8;
rcc_osc_init.PLL.PLLN = 80;
rcc_osc_init.PLL.PLLP = RCC_PLLP_DIV2;
if (const auto ret = HAL_RCC_OscConfig(&rcc_osc_init); ret != HAL_OK)
{
return ret;
}
/* Select PLL as system clock source and configure the HCLK, PCLK1 and PCLK2
clocks dividers */
rcc_clk_init.ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK |
RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2);
rcc_clk_init.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
rcc_clk_init.AHBCLKDivider = RCC_SYSCLK_DIV1;
rcc_clk_init.APB1CLKDivider = RCC_HCLK_DIV2;
rcc_clk_init.APB2CLKDivider = RCC_HCLK_DIV2;
if (const auto ret = HAL_RCC_ClockConfig(&rcc_clk_init, FLASH_LATENCY_3); ret != HAL_OK)
{
return ret;
}
return HAL_OK;
}I went deeper into this and found out it is only HAL_RCC_ClockConfig() and the configured struct which makes uarts not workable. Makes also sense since HAL_RCC_OscConfig() has no direct influence on the peripherials. Anyway, if I just leave system_clock_config() out and only do HAL_Init(), the uarts work but all our I2C and Timer related sensor measurements will fail.
I saw in the manual there is a mapping table and it says that APB1 covers UART2-5 (plus Timers and all I2Cs) and APB2 "only" covers UART1 and 6. If I execute system_clock_config(), UART1 still works (thats the uart we have been operating the whole time on this board, it was our only needed uart. UART 3 or 5 is now our extension. And they fail with our standart initialisation "system_clock_config()").
I hope I can make you my issue plus or minus clear, it has been a long day...
Thank you very much in advance.
KR