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,53 @@ 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 ExternalLSEclock = ;
31+ static constexpr uint32_t ExternalHSEclock = 8_MHz;
32+
33+ static constexpr Rcc::PllFactors pllFactors{
34+ .pllM = 8 ,
35+ .pllN = 336 ,
36+ .pllP = 4 ,
37+ .pllQ = 7 ,
38+ };
39+ static constexpr Rcc::AhbPrescaler Ahb_prescaler = Rcc::AhbPrescaler::Div1;
40+ static constexpr Rcc::Apb1Prescaler Apb1_prescaler = Rcc::Apb1Prescaler::Div2;
41+ static constexpr Rcc::Apb2Prescaler Apb2_prescaler = Rcc::Apb2Prescaler::Div1;
42+
43+ // ------------------------------------------
44+
45+ static constexpr int HsePredivision = 1 ;
46+ static constexpr uint32_t PllClock = ExternalHSEclock / HsePredivision / pllFactors.pllM * pllFactors.pllN;
47+
48+ static constexpr uint32_t Clock = PllClock / pllFactors.pllP; // 96_Mhz
49+ static_assert (Clock <= 100_MHz, " Clock has max. 100MHz!" );
50+
51+ static constexpr uint32_t Ahb = Clock / RccProto::prescalerToValue<Ahb_prescaler>();
52+ static_assert (Ahb <= 100_MHz, " Ahb has max. 100MHz!" );
53+
54+ static constexpr uint32_t Apb1 = Ahb / RccProto::prescalerToValue<Apb1_prescaler>();
55+ static_assert (Apb1 <= 50_MHz, " Apb1 has max. 50MHz!" );
56+
57+ static constexpr uint32_t Apb2 = Ahb / RccProto::prescalerToValue<Apb2_prescaler>();
58+ static_assert (Apb2 <= 100_MHz, " Apb2 has max. 100MHz!" );
59+
60+ // @todo is this correct?
61+ // prescaler is one ? -> multiply by one, otherwise multiply by two
62+ static constexpr uint32_t Apb1Timer = Apb1 * (RccProto::prescalerToValue<Apb1_prescaler>() == 1 ? 1 : 2 );
63+ static constexpr uint32_t Apb2Timer = Apb2 * (RccProto::prescalerToValue<Apb2_prescaler>() == 1 ? 1 : 2 );
64+
65+ // static_assert(Ahb == 84_MHz, "Wrong");
66+ // static_assert(Apb1 == 42_MHz, "Wrong");
67+ // static_assert(Apb2 == 84_MHz, "Wrong");
68+ // static_assert(Apb1Timer == 84_MHz, "Wrong");
69+ // static_assert(Apb2Timer == 84_MHz, "Wrong");
70+
71+ // ------------------------------------------
72+
73+ static constexpr uint32_t Frequency = Ahb;
3274
3375 static constexpr uint32_t Adc = Apb2;
3476
@@ -51,8 +93,6 @@ struct SystemClock
5193 static constexpr uint32_t I2c2 = Apb1;
5294 static constexpr uint32_t I2c3 = Apb1;
5395
54- static constexpr uint32_t Apb1Timer = Apb1 * 2 ;
55- static constexpr uint32_t Apb2Timer = Apb2 * 2 ;
5696 static constexpr uint32_t Timer1 = Apb2Timer;
5797 static constexpr uint32_t Timer2 = Apb1Timer;
5898 static constexpr uint32_t Timer3 = Apb1Timer;
@@ -62,27 +102,20 @@ struct SystemClock
62102 static constexpr uint32_t Timer10 = Apb2Timer;
63103 static constexpr uint32_t Timer11 = Apb2Timer;
64104
65- static constexpr uint32_t Usb = 48_MHz;
105+ static constexpr uint32_t Usb = PllClock / pllFactors.pllQ; // 48_Mhz
66106
67107 static bool inline enable ()
68108 {
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- };
109+ // / STM32F411 running at 84MHz generated from the external 8MHz crystal
110+ Rcc::enableExternalCrystal ();
76111 Rcc::enablePll (Rcc::PllSource::ExternalCrystal, pllFactors);
77112 // set flash latency for 100MHz
78113 Rcc::setFlashLatency<Frequency>();
79114 // switch system clock to PLL output
80115 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);
116+ Rcc::setAhbPrescaler (Ahb_prescaler);
117+ Rcc::setApb1Prescaler (Apb1_prescaler);
118+ Rcc::setApb2Prescaler (Apb2_prescaler);
86119 // update frequencies for busy-wait delay functions
87120 Rcc::updateCoreFrequency<Frequency>();
88121
@@ -188,7 +221,7 @@ initializeLis3()
188221 lis3::Cs::setOutput (modm::Gpio::High);
189222
190223 lis3::SpiMaster::connect<lis3::Sck::Sck, lis3::Mosi::Mosi, lis3::Miso::Miso>();
191- lis3::SpiMaster::initialize<SystemClock, 6_MHz >();
224+ lis3::SpiMaster::initialize<SystemClock, 5 .25_MHz >();
192225 lis3::SpiMaster::setDataMode (lis3::SpiMaster::DataMode::Mode3);
193226}
194227
0 commit comments