@@ -31,35 +31,76 @@ using namespace modm::literals;
3131// / STM32F407 running at 168MHz generated from the external 8MHz crystal
3232struct SystemClock
3333{
34- static constexpr uint32_t Frequency = 168_MHz;
34+ static constexpr uint32_t Hse = 8_MHz;
35+ static constexpr uint32_t Lse = 32 .768_kHz;
36+ static constexpr Rcc::PllConfig pll
37+ {
38+ .M = 4 , // 8 MHz / 4 = 2 MHz
39+ .N = 168 , // 2 MHz * 168 = 336 MHz
40+ .P = 2 , // 336 MHz / 2 = 168 MHz = F_cpu
41+ .Q = 7 , // 336 MHz / 7 = 48 MHz
42+ };
43+ static constexpr uint32_t PllP = Hse / pll.M * pll.N / pll.P;
44+ static constexpr uint32_t PllQ = Hse / pll.M * pll.N / pll.Q;
45+
46+ static constexpr uint32_t Frequency = PllP;
47+ static_assert (Frequency == Rcc::MaxFrequency);
48+
3549 static constexpr uint32_t Ahb = Frequency;
3650 static constexpr uint32_t Apb1 = Frequency / 4 ;
3751 static constexpr uint32_t Apb2 = Frequency / 2 ;
52+ static constexpr uint32_t Ahb1 = Ahb;
53+ static constexpr uint32_t Ahb2 = Ahb;
54+
55+ static constexpr uint32_t Crc = Ahb1;
56+ static constexpr uint32_t Dma1 = Ahb1;
57+ static constexpr uint32_t Dma2 = Ahb1;
58+ static constexpr uint32_t Eth = Ahb1;
59+ static constexpr uint32_t Flash = Ahb1;
60+ static constexpr uint32_t GpioA = Ahb1;
61+ static constexpr uint32_t GpioB = Ahb1;
62+ static constexpr uint32_t GpioC = Ahb1;
63+ static constexpr uint32_t GpioD = Ahb1;
64+ static constexpr uint32_t GpioE = Ahb1;
65+ static constexpr uint32_t GpioF = Ahb1;
66+ static constexpr uint32_t GpioG = Ahb1;
67+ static constexpr uint32_t GpioH = Ahb1;
68+ static constexpr uint32_t GpioI = Ahb1;
69+ static constexpr uint32_t RccBus = Ahb1;
70+
71+ static constexpr uint32_t Dcmi = Ahb2;
72+ static constexpr uint32_t Rng = Ahb2;
73+
74+ static constexpr uint32_t Can1 = Apb1;
75+ static constexpr uint32_t Can2 = Apb1;
76+ static constexpr uint32_t Dac = Apb1;
77+ static constexpr uint32_t I2c1 = Apb1;
78+ static constexpr uint32_t I2c2 = Apb1;
79+ static constexpr uint32_t I2c3 = Apb1;
80+ static constexpr uint32_t I2s2Ext = Apb1;
81+ static constexpr uint32_t I2s3Ext = Apb1;
82+ static constexpr uint32_t IwdgBus = Apb1;
83+ static constexpr uint32_t Pwr = Apb1;
84+ static constexpr uint32_t RtcBus = Apb1;
85+ static constexpr uint32_t Spi2 = Apb1;
86+ static constexpr uint32_t Spi3 = Apb1;
87+ static constexpr uint32_t Usart2 = Apb1;
88+ static constexpr uint32_t Usart3 = Apb1;
89+ static constexpr uint32_t Uart4 = Apb1;
90+ static constexpr uint32_t Uart5 = Apb1;
91+ static constexpr uint32_t Wwdg = Apb1;
3892
3993 static constexpr uint32_t Adc = Apb2;
40-
41- static constexpr uint32_t Can1 = Apb1;
42- static constexpr uint32_t Can2 = Apb1;
43-
44- static constexpr uint32_t Spi1 = Apb2;
45- static constexpr uint32_t Spi2 = Apb1;
46- static constexpr uint32_t Spi3 = Apb1;
47- static constexpr uint32_t Spi4 = Apb2;
48- static constexpr uint32_t Spi5 = Apb2;
49- static constexpr uint32_t Spi6 = Apb2;
50-
94+ static constexpr uint32_t Adc1 = Apb2;
95+ static constexpr uint32_t Adc2 = Apb2;
96+ static constexpr uint32_t Adc3 = Apb2;
97+ static constexpr uint32_t Adc123Common = Apb2;
98+ static constexpr uint32_t Exti = Apb2;
99+ static constexpr uint32_t Sdio = Apb2;
100+ static constexpr uint32_t Spi1 = Apb2;
101+ static constexpr uint32_t Syscfg = Apb2;
51102 static constexpr uint32_t Usart1 = Apb2;
52- static constexpr uint32_t Usart2 = Apb1;
53- static constexpr uint32_t Usart3 = Apb1;
54- static constexpr uint32_t Uart4 = Apb1;
55- static constexpr uint32_t Uart5 = Apb1;
56103 static constexpr uint32_t Usart6 = Apb2;
57- static constexpr uint32_t Uart7 = Apb1;
58- static constexpr uint32_t Uart8 = Apb1;
59-
60- static constexpr uint32_t I2c1 = Apb1;
61- static constexpr uint32_t I2c2 = Apb1;
62- static constexpr uint32_t I2c3 = Apb1;
63104
64105 static constexpr uint32_t Apb1Timer = Apb1 * 2 ;
65106 static constexpr uint32_t Apb2Timer = Apb2 * 2 ;
@@ -77,34 +118,28 @@ struct SystemClock
77118 static constexpr uint32_t Timer12 = Apb1Timer;
78119 static constexpr uint32_t Timer13 = Apb1Timer;
79120 static constexpr uint32_t Timer14 = Apb1Timer;
121+
122+ static constexpr uint32_t Usb = PllQ;
80123 static constexpr uint32_t Iwdg = Rcc::LsiFrequency;
81- static constexpr uint32_t Rtc = 32 .768_kHz ;
124+ static constexpr uint32_t Rtc = Lse ;
82125
83126 static bool inline
84127 enable ()
85128 {
86- Rcc::enableLowSpeedExternalCrystal ();
87- Rcc::enableRealTimeClock (Rcc::RealTimeClockSource::LowSpeedExternalCrystal);
88-
89- Rcc::enableExternalCrystal (); // 8MHz
90- const Rcc::PllFactors pllFactors{
91- .pllM = 4 , // 8MHz / M=4 -> 2MHz
92- .pllN = 168 , // 2MHz * N=168 -> 336MHz
93- .pllP = 2 // 336MHz / P=2 -> 168MHz = F_cpu
94- };
95- Rcc::enablePll (Rcc::PllSource::ExternalCrystal, pllFactors);
96- // set flash latency for 168MHz
129+ Rcc::enableLseCrystal ();
130+ Rcc::enableHseCrystal ();
131+
97132 Rcc::setFlashLatency<Frequency>();
98- // switch system clock to PLL output
99- Rcc::enableSystemClock (Rcc::SystemClockSource::Pll);
100- Rcc::setAhbPrescaler (Rcc::AhbPrescaler::Div1);
101- // APB1 has max. 42MHz
102- // APB2 has max. 84MHz
103- Rcc::setApb1Prescaler (Rcc::Apb1Prescaler::Div4);
104- Rcc::setApb2Prescaler (Rcc::Apb2Prescaler::Div2);
105- // update frequencies for busy-wait delay functions
106133 Rcc::updateCoreFrequency<Frequency>();
107134
135+ Rcc::setAhbPrescaler (Rcc::AhbPrescaler::Div1);
136+ Rcc::setApb1Prescaler (Rcc::ApbPrescaler::Div4);
137+ Rcc::setApb2Prescaler (Rcc::ApbPrescaler::Div2);
138+
139+ Rcc::enablePll (Rcc::PllSource::Hse, pll);
140+ Rcc::enableSystemClock (Rcc::SystemClockSource::PllP);
141+ Rcc::setRealTimeClockSource (Rcc::RealTimeClockSource::Lse);
142+
108143 return true ;
109144 }
110145};
0 commit comments