1414#include < modm/driver/inertial/lis3dsh.hpp>
1515#include < modm/platform.hpp>
1616
17+ #include " rcc_prototype.hpp"
18+
1719using namespace modm ::platform;
1820
1921namespace Board
@@ -22,13 +24,49 @@ namespace Board
2224// / @{
2325using namespace modm ::literals;
2426
25- // / STM32F411 running at 96MHz generated from the external 8MHz crystal
27+
2628struct SystemClock
2729{
28- static constexpr uint32_t Frequency = 96_MHz;
29- static constexpr uint32_t Ahb = Frequency;
30- static constexpr uint32_t Apb1 = Frequency / 2 ;
31- static constexpr uint32_t Apb2 = Frequency;
30+ static constexpr uint32_t ExternalCrystalClock = 8_MHz;
31+
32+ static constexpr Rcc::PllFactors pllFactors{
33+ .pllM = 8 ,
34+ .pllN = 336 ,
35+ .pllP = 4 ,
36+ .pllQ = 7 ,
37+ };
38+ static constexpr Rcc::AhbPrescaler Ahb_pre = Rcc::AhbPrescaler::Div1;
39+ static constexpr Rcc::Apb1Prescaler Apb1_pre = Rcc::Apb1Prescaler::Div2;
40+ static constexpr Rcc::Apb2Prescaler Apb2_pre = Rcc::Apb2Prescaler::Div1;
41+
42+ // ------------------------------------------
43+
44+ static constexpr uint32_t MainPllClock = ExternalCrystalClock / pllFactors.pllM * pllFactors.pllN;
45+ static constexpr uint32_t SystemFrequency = MainPllClock / pllFactors.pllP; // 96_Mhz
46+
47+ static constexpr uint32_t Ahb = SystemFrequency / RccProto::prescalerToValue<Ahb_pre>();
48+ static constexpr uint32_t Apb1 = Ahb / RccProto::prescalerToValue<Apb1_pre>();
49+ static constexpr uint32_t Apb2 = Ahb / RccProto::prescalerToValue<Apb2_pre>();
50+
51+ // @todo find a nice home for these
52+ static_assert (SystemFrequency <= 100_MHz, " SystemFrequency has max. 100MHz!" );
53+ static_assert (Apb1 <= 50_MHz, " Apb1 has max. 50MHz!" );
54+ static_assert (Apb2 <= 100_MHz, " Apb2 has max. 100MHz!" );
55+
56+ // @todo is this correct?
57+ // prescaler is one ? -> multiply by one, otherwise multiply by two
58+ static constexpr uint32_t Apb1Timer = Apb1 * (RccProto::prescalerToValue<Apb1_pre>() == 1 ? 1 : 2 );
59+ static constexpr uint32_t Apb2Timer = Apb2 * (RccProto::prescalerToValue<Apb2_pre>() == 1 ? 1 : 2 );
60+
61+ // static_assert(Ahb == 84_MHz, "Wrong");
62+ // static_assert(Apb1 == 42_MHz, "Wrong");
63+ // static_assert(Apb2 == 84_MHz, "Wrong");
64+ // static_assert(Apb1Timer == 84_MHz, "Wrong");
65+ // static_assert(Apb2Timer == 84_MHz, "Wrong");
66+
67+ // ------------------------------------------
68+
69+ static constexpr uint32_t Frequency = Ahb;
3270
3371 static constexpr uint32_t Adc = Apb2;
3472
@@ -51,8 +89,6 @@ struct SystemClock
5189 static constexpr uint32_t I2c2 = Apb1;
5290 static constexpr uint32_t I2c3 = Apb1;
5391
54- static constexpr uint32_t Apb1Timer = Apb1 * 2 ;
55- static constexpr uint32_t Apb2Timer = Apb2 * 2 ;
5692 static constexpr uint32_t Timer1 = Apb2Timer;
5793 static constexpr uint32_t Timer2 = Apb1Timer;
5894 static constexpr uint32_t Timer3 = Apb1Timer;
@@ -62,27 +98,20 @@ struct SystemClock
6298 static constexpr uint32_t Timer10 = Apb2Timer;
6399 static constexpr uint32_t Timer11 = Apb2Timer;
64100
65- static constexpr uint32_t Usb = 48_MHz;
101+ static constexpr uint32_t Usb = MainPllClock / pllFactors.pllQ; // 48_Mhz
66102
67103 static bool inline enable ()
68104 {
69- Rcc::enableExternalCrystal (); // 8MHz
70- const Rcc::PllFactors pllFactors{
71- .pllM = 7 , // 8MHz / M=7 -> ~1.14MHz
72- .pllN = 336 , // 1.14MHz * N=336 -> 384MHz
73- .pllP = 4 , // 384MHz / P=4 -> 96MHz = F_cpu
74- .pllQ = 8 , // 384MHz / P=8 -> 48MHz = F_usb
75- };
105+ // / STM32F411 running at 84MHz generated from the external 8MHz crystal
106+ Rcc::enableExternalCrystal ();
76107 Rcc::enablePll (Rcc::PllSource::ExternalCrystal, pllFactors);
77108 // set flash latency for 100MHz
78109 Rcc::setFlashLatency<Frequency>();
79110 // switch system clock to PLL output
80111 Rcc::enableSystemClock (Rcc::SystemClockSource::Pll);
81- Rcc::setAhbPrescaler (Rcc::AhbPrescaler::Div1);
82- // APB1 has max. 50MHz
83- // APB2 has max. 100MHz
84- Rcc::setApb1Prescaler (Rcc::Apb1Prescaler::Div2);
85- Rcc::setApb2Prescaler (Rcc::Apb2Prescaler::Div1);
112+ Rcc::setAhbPrescaler (Ahb_pre);
113+ Rcc::setApb1Prescaler (Apb1_pre);
114+ Rcc::setApb2Prescaler (Apb2_pre);
86115 // update frequencies for busy-wait delay functions
87116 Rcc::updateCoreFrequency<Frequency>();
88117
@@ -188,7 +217,7 @@ initializeLis3()
188217 lis3::Cs::setOutput (modm::Gpio::High);
189218
190219 lis3::SpiMaster::connect<lis3::Sck::Sck, lis3::Mosi::Mosi, lis3::Miso::Miso>();
191- lis3::SpiMaster::initialize<SystemClock, 6_MHz >();
220+ lis3::SpiMaster::initialize<SystemClock, 5 .25_MHz >();
192221 lis3::SpiMaster::setDataMode (lis3::SpiMaster::DataMode::Mode3);
193222}
194223
0 commit comments