Skip to content

Commit 444ca2d

Browse files
committed
add: 使用constexpr函数自动计算时钟树配置
1 parent 42cfa29 commit 444ca2d

File tree

1 file changed

+96
-27
lines changed

1 file changed

+96
-27
lines changed

variants/AIR32F103/F103CB/generic_clock.cpp

Lines changed: 96 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/*
22
*******************************************************************************
3-
* Copyright (c) 2020-2021, STMicroelectronics
3+
* Copyright (c) 2023-2023, AirM2M, HalfSweet
44
* All rights reserved.
55
*
66
* This software component is licensed by ST under BSD 3-Clause license,
@@ -13,17 +13,55 @@
1313
#if defined(ARDUINO_AIR32F103CB)
1414
#include "pins_arduino.h"
1515

16-
constexpr void test(constexpr uint8_t a)
16+
#include <stdint.h>
17+
18+
enum class ClockSource : uint8_t
19+
{
20+
HSI = 0,
21+
HSE = 1,
22+
};
23+
24+
namespace CuluateClock
1725
{
18-
constexpr uint8_t b = a;
19-
return;
26+
constexpr uint8_t GetPLLMultiplier(ClockSource soure, uint32_t sourceFreq, uint32_t sysFrequency)
27+
{
28+
if (soure == ClockSource::HSI)
29+
{
30+
sourceFreq /= 2;
31+
}
32+
if (sysFrequency % sourceFreq != 0)
33+
{
34+
return (sysFrequency / sourceFreq) - 1;
35+
}
36+
else
37+
{
38+
return sysFrequency / sourceFreq;
39+
}
40+
}
41+
42+
constexpr uint32_t Get_RCC_CFGR_PLLMULL(uint8_t multiplier)
43+
{
44+
uint32_t mulTable[] = {
45+
RCC_PLL_MUL2, RCC_PLL_MUL3, RCC_PLL_MUL4, RCC_PLL_MUL5, RCC_PLL_MUL6, RCC_PLL_MUL7, RCC_PLL_MUL8, RCC_PLL_MUL9,
46+
RCC_PLL_MUL10, RCC_PLL_MUL11, RCC_PLL_MUL12, RCC_PLL_MUL13, RCC_PLL_MUL14, RCC_PLL_MUL15, RCC_PLL_MUL16, RCC_PLL_MUL17,
47+
RCC_PLL_MUL18, RCC_PLL_MUL19, RCC_PLL_MUL20, RCC_PLL_MUL21, RCC_PLL_MUL22, RCC_PLL_MUL23, RCC_PLL_MUL24, RCC_PLL_MUL25,
48+
RCC_PLL_MUL26, RCC_PLL_MUL27, RCC_PLL_MUL28, RCC_PLL_MUL29, RCC_PLL_MUL30, RCC_PLL_MUL31, RCC_PLL_MUL32};
49+
if (multiplier > 32 || multiplier < 2)
50+
{
51+
return 0xFFFFFFFF;
52+
}
53+
else
54+
{
55+
return mulTable[multiplier - 2];
56+
}
57+
}
2058
}
2159

2260
/**
23-
* @brief System Clock Configuration
24-
* @param None
25-
* @retval None
26-
*/
61+
* @brief System Clock Configuration
62+
* @param None
63+
* @retval None
64+
*/
2765
WEAK void SystemClock_Config(void)
2866
#if defined(USBCON)
2967
{
@@ -32,63 +70,94 @@ WEAK void SystemClock_Config(void)
3270
RCC_PeriphCLKInitTypeDef PeriphClkInit = {};
3371

3472
/** Initializes the RCC Oscillators according to the specified parameters
35-
* in the RCC_OscInitTypeDef structure.
36-
*/
73+
* in the RCC_OscInitTypeDef structure.
74+
*/
3775
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
3876
RCC_OscInitStruct.HSIState = RCC_HSI_ON;
3977
RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
4078
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
4179
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI_DIV2;
4280
RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL12;
43-
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) {
81+
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
82+
{
4483
Error_Handler();
4584
}
4685
/** Initializes the CPU, AHB and APB buses clocks
47-
*/
48-
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_SYSCLK
49-
| RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2;
86+
*/
87+
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2;
5088
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
5189
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
5290
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
5391
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
5492

55-
if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_1) != HAL_OK) {
93+
if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_1) != HAL_OK)
94+
{
5695
Error_Handler();
5796
}
5897
PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_USB;
5998
PeriphClkInit.UsbClockSelection = RCC_USBCLKSOURCE_PLL;
60-
if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK) {
99+
if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)
100+
{
61101
Error_Handler();
62102
}
63103
}
64104
#else
65105
{
66-
test(8);
67106
RCC_OscInitTypeDef RCC_OscInitStruct = {};
68107
RCC_ClkInitTypeDef RCC_ClkInitStruct = {};
69108

70109
/** Initializes the RCC Oscillators according to the specified parameters
71-
* in the RCC_OscInitTypeDef structure.
72-
*/
110+
* in the RCC_OscInitTypeDef structure.
111+
*/
112+
#if defined(USE_HSI)
73113
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
74114
RCC_OscInitStruct.HSIState = RCC_HSI_ON;
75115
RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
76-
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
77116
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI_DIV2;
78-
RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL16;
79-
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) {
117+
constexpr uint32_t sourceFreq = CLOCK_SOURCE;
118+
constexpr auto clockSource = ClockSource::HSI;
119+
constexpr auto sysClkSource = RCC_SYSCLKSOURCE_HSI;
120+
#elif defined(USE_HSE)
121+
#undef HSE_VALUE
122+
#define HSE_VALUE CLOCK_SOURCE
123+
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
124+
RCC_OscInitStruct.HSIState = RCC_HSI_OFF;
125+
RCC_OscInitStruct.HSEState = RCC_HSE_ON;
126+
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
127+
constexpr uint32_t sourceFreq = CLOCK_SOURCE;
128+
constexpr auto clockSource = ClockSource::HSE;
129+
constexpr auto sysClkSource = RCC_SYSCLKSOURCE_HSE;
130+
#else
131+
#error "No clock source defined"
132+
#endif
133+
134+
constexpr uint32_t sysFrequency = F_CPU;
135+
constexpr uint8_t multiplier = CuluateClock::GetPLLMultiplier(clockSource, sourceFreq, sysFrequency);
136+
if (multiplier < 2)
137+
{
138+
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_OFF;
139+
RCC_ClkInitStruct.SYSCLKSource = sysClkSource;
140+
}
141+
else
142+
{
143+
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
144+
RCC_OscInitStruct.PLL.PLLMUL = CuluateClock::Get_RCC_CFGR_PLLMULL(multiplier);
145+
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
146+
}
147+
148+
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
149+
{
80150
Error_Handler();
81151
}
82152
/** Initializes the CPU, AHB and APB buses clocks
83-
*/
84-
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_SYSCLK
85-
| RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2;
86-
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
153+
*/
154+
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2;
87155
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
88156
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
89157
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
90158

91-
if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK) {
159+
if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)
160+
{
92161
Error_Handler();
93162
}
94163
}

0 commit comments

Comments
 (0)