11//! # Clock Control
2- use fugit:: MegahertzU32 ;
2+ use fugit:: HertzU32 ;
33
44use crate :: system:: SystemClockControl ;
55
@@ -9,6 +9,18 @@ use crate::system::SystemClockControl;
99#[ cfg_attr( feature = "esp32s3" , path = "clocks_ll/esp32s3.rs" ) ]
1010mod clocks_ll;
1111
12+ pub trait Clock {
13+ fn frequency ( & self ) -> HertzU32 ;
14+
15+ fn mhz ( & self ) -> u32 {
16+ self . frequency ( ) . to_MHz ( )
17+ }
18+
19+ fn hz ( & self ) -> u32 {
20+ self . frequency ( ) . to_Hz ( )
21+ }
22+ }
23+
1224/// CPU clock speed
1325#[ derive( Debug , Clone , Copy ) ]
1426pub enum CpuClock {
@@ -19,22 +31,64 @@ pub enum CpuClock {
1931}
2032
2133#[ allow( dead_code) ]
22- impl CpuClock {
23- fn frequency ( & self ) -> MegahertzU32 {
34+ impl Clock for CpuClock {
35+ fn frequency ( & self ) -> HertzU32 {
2436 match self {
25- CpuClock :: Clock80MHz => MegahertzU32 :: MHz ( 80 ) ,
26- CpuClock :: Clock160MHz => MegahertzU32 :: MHz ( 160 ) ,
37+ CpuClock :: Clock80MHz => HertzU32 :: MHz ( 80 ) ,
38+ CpuClock :: Clock160MHz => HertzU32 :: MHz ( 160 ) ,
2739 #[ cfg( not( feature = "esp32c3" ) ) ]
28- CpuClock :: Clock240MHz => MegahertzU32 :: MHz ( 240 ) ,
40+ CpuClock :: Clock240MHz => HertzU32 :: MHz ( 240 ) ,
2941 }
3042 }
43+ }
3144
32- fn mhz ( & self ) -> u32 {
45+ #[ allow( unused) ]
46+ #[ derive( Debug , Clone , Copy ) ]
47+ pub ( crate ) enum XtalClock {
48+ RtcXtalFreq40M ,
49+ #[ cfg( feature = "esp32" ) ]
50+ RtcXtalFreq26M ,
51+ #[ cfg( feature = "esp32" ) ]
52+ RtcXtalFreq24M ,
53+ #[ cfg( any( feature = "esp32c3" , feature = "esp32s3" ) ) ]
54+ RtcXtalFreq32M ,
55+ RtcXtalFreqOther ( u32 ) ,
56+ }
57+
58+ impl Clock for XtalClock {
59+ fn frequency ( & self ) -> HertzU32 {
3360 match self {
34- CpuClock :: Clock80MHz => 80 ,
35- CpuClock :: Clock160MHz => 160 ,
36- #[ cfg( not( feature = "esp32c3" ) ) ]
37- CpuClock :: Clock240MHz => 240 ,
61+ XtalClock :: RtcXtalFreq40M => HertzU32 :: MHz ( 40 ) ,
62+ #[ cfg( feature = "esp32" ) ]
63+ XtalClock :: RtcXtalFreq26M => HertzU32 :: MHz ( 26 ) ,
64+ #[ cfg( feature = "esp32" ) ]
65+ XtalClock :: RtcXtalFreq24M => HertzU32 :: MHz ( 24 ) ,
66+ #[ cfg( any( feature = "esp32c3" , feature = "esp32s3" ) ) ]
67+ XtalClock :: RtcXtalFreq32M => HertzU32 :: MHz ( 32 ) ,
68+ XtalClock :: RtcXtalFreqOther ( mhz) => HertzU32 :: MHz ( * mhz) ,
69+ }
70+ }
71+ }
72+
73+ #[ allow( unused) ]
74+ #[ derive( Debug , Clone , Copy ) ]
75+ pub ( crate ) enum PllClock {
76+ Pll320MHz ,
77+ Pll480MHz ,
78+ }
79+
80+ #[ allow( unused) ]
81+ #[ derive( Debug , Clone , Copy ) ]
82+ pub ( crate ) enum ApbClock {
83+ ApbFreq80MHz ,
84+ ApbFreqOther ( u32 ) ,
85+ }
86+
87+ impl Clock for ApbClock {
88+ fn frequency ( & self ) -> HertzU32 {
89+ match self {
90+ ApbClock :: ApbFreq80MHz => HertzU32 :: MHz ( 80 ) ,
91+ ApbClock :: ApbFreqOther ( mhz) => HertzU32 :: MHz ( * mhz) ,
3892 }
3993 }
4094}
@@ -45,10 +99,10 @@ impl CpuClock {
4599/// longer be changed
46100pub struct Clocks {
47101 _private : ( ) ,
48- pub cpu_clock : MegahertzU32 ,
49- pub apb_clock : MegahertzU32 ,
50- pub xtal_clock : MegahertzU32 ,
51- pub i2c_clock : MegahertzU32 ,
102+ pub cpu_clock : HertzU32 ,
103+ pub apb_clock : HertzU32 ,
104+ pub xtal_clock : HertzU32 ,
105+ pub i2c_clock : HertzU32 ,
52106 // TODO chip specific additional ones as needed
53107}
54108
@@ -71,10 +125,10 @@ impl Clocks {
71125
72126#[ doc( hidden) ]
73127pub struct RawClocks {
74- pub cpu_clock : MegahertzU32 ,
75- pub apb_clock : MegahertzU32 ,
76- pub xtal_clock : MegahertzU32 ,
77- pub i2c_clock : MegahertzU32 ,
128+ pub cpu_clock : HertzU32 ,
129+ pub apb_clock : HertzU32 ,
130+ pub xtal_clock : HertzU32 ,
131+ pub i2c_clock : HertzU32 ,
78132 // TODO chip specific additional ones as needed
79133}
80134/// Used to configure the frequencies of the clocks present in the chip.
@@ -103,10 +157,10 @@ impl ClockControl {
103157 ClockControl {
104158 _private : ( ) ,
105159 desired_rates : RawClocks {
106- cpu_clock : MegahertzU32 :: MHz ( 80 ) ,
107- apb_clock : MegahertzU32 :: MHz ( 80 ) ,
108- xtal_clock : MegahertzU32 :: MHz ( 40 ) ,
109- i2c_clock : MegahertzU32 :: MHz ( 80 ) ,
160+ cpu_clock : HertzU32 :: MHz ( 80 ) ,
161+ apb_clock : HertzU32 :: MHz ( 80 ) ,
162+ xtal_clock : HertzU32 :: MHz ( 40 ) ,
163+ i2c_clock : HertzU32 :: MHz ( 80 ) ,
110164 } ,
111165 }
112166 }
@@ -116,11 +170,11 @@ impl ClockControl {
116170 pub fn configure ( clock_control : SystemClockControl , cpu_clock_speed : CpuClock ) -> ClockControl {
117171 // like NuttX use 40M hardcoded - if it turns out to be a problem
118172 // we will take care then
119- let xtal_freq = clocks_ll :: XtalFrequency :: RtcXtalFreq40M ;
173+ let xtal_freq = XtalClock :: RtcXtalFreq40M ;
120174 let pll_freq = match cpu_clock_speed {
121- CpuClock :: Clock80MHz => clocks_ll :: PllFequency :: Pll320MHz ,
122- CpuClock :: Clock160MHz => clocks_ll :: PllFequency :: Pll320MHz ,
123- CpuClock :: Clock240MHz => clocks_ll :: PllFequency :: Pll480MHz ,
175+ CpuClock :: Clock80MHz => PllClock :: Pll320MHz ,
176+ CpuClock :: Clock160MHz => PllClock :: Pll320MHz ,
177+ CpuClock :: Clock240MHz => PllClock :: Pll480MHz ,
124178 } ;
125179
126180 clocks_ll:: esp32_rtc_update_to_xtal ( xtal_freq, 1 ) ;
@@ -132,9 +186,9 @@ impl ClockControl {
132186 _private : ( ) ,
133187 desired_rates : RawClocks {
134188 cpu_clock : cpu_clock_speed. frequency ( ) ,
135- apb_clock : MegahertzU32 :: MHz ( 80 ) ,
136- xtal_clock : MegahertzU32 :: MHz ( 40 ) ,
137- i2c_clock : MegahertzU32 :: MHz ( 40 ) ,
189+ apb_clock : HertzU32 :: MHz ( 80 ) ,
190+ xtal_clock : HertzU32 :: MHz ( 40 ) ,
191+ i2c_clock : HertzU32 :: MHz ( 40 ) ,
138192 } ,
139193 }
140194 }
@@ -148,26 +202,40 @@ impl ClockControl {
148202 ClockControl {
149203 _private : ( ) ,
150204 desired_rates : RawClocks {
151- cpu_clock : MegahertzU32 :: MHz ( 80 ) ,
152- apb_clock : MegahertzU32 :: MHz ( 80 ) ,
153- xtal_clock : MegahertzU32 :: MHz ( 40 ) ,
154- i2c_clock : MegahertzU32 :: MHz ( 40 ) ,
205+ cpu_clock : HertzU32 :: MHz ( 80 ) ,
206+ apb_clock : HertzU32 :: MHz ( 80 ) ,
207+ xtal_clock : HertzU32 :: MHz ( 40 ) ,
208+ i2c_clock : HertzU32 :: MHz ( 40 ) ,
155209 } ,
156210 }
157211 }
158212
159213 /// Configure the CPU clock speed.
160214 #[ allow( unused) ]
161215 pub fn configure ( clock_control : SystemClockControl , cpu_clock_speed : CpuClock ) -> ClockControl {
162- clocks_ll:: set_cpu_clock ( cpu_clock_speed) ;
216+ let apb_freq;
217+ let xtal_freq = XtalClock :: RtcXtalFreq40M ;
218+ let pll_freq = PllClock :: Pll480MHz ;
219+
220+ if cpu_clock_speed. mhz ( ) <= xtal_freq. mhz ( ) {
221+ apb_freq = ApbClock :: ApbFreqOther ( cpu_clock_speed. mhz ( ) ) ;
222+ clocks_ll:: esp32c3_rtc_update_to_xtal ( xtal_freq, 1 ) ;
223+ clocks_ll:: esp32c3_rtc_apb_freq_update ( apb_freq) ;
224+ } else {
225+ apb_freq = ApbClock :: ApbFreq80MHz ;
226+ clocks_ll:: esp32c3_rtc_bbpll_enable ( ) ;
227+ clocks_ll:: esp32c3_rtc_bbpll_configure ( xtal_freq, pll_freq) ;
228+ clocks_ll:: esp32c3_rtc_freq_to_pll_mhz ( cpu_clock_speed) ;
229+ clocks_ll:: esp32c3_rtc_apb_freq_update ( apb_freq) ;
230+ }
163231
164232 ClockControl {
165233 _private : ( ) ,
166234 desired_rates : RawClocks {
167235 cpu_clock : cpu_clock_speed. frequency ( ) ,
168- apb_clock : MegahertzU32 :: MHz ( 80 ) ,
169- xtal_clock : MegahertzU32 :: MHz ( 40 ) ,
170- i2c_clock : MegahertzU32 :: MHz ( 40 ) ,
236+ apb_clock : apb_freq . frequency ( ) ,
237+ xtal_clock : xtal_freq . frequency ( ) ,
238+ i2c_clock : HertzU32 :: MHz ( 40 ) ,
171239 } ,
172240 }
173241 }
@@ -181,10 +249,10 @@ impl ClockControl {
181249 ClockControl {
182250 _private : ( ) ,
183251 desired_rates : RawClocks {
184- cpu_clock : MegahertzU32 :: MHz ( 80 ) ,
185- apb_clock : MegahertzU32 :: MHz ( 80 ) ,
186- xtal_clock : MegahertzU32 :: MHz ( 40 ) ,
187- i2c_clock : MegahertzU32 :: MHz ( 80 ) ,
252+ cpu_clock : HertzU32 :: MHz ( 80 ) ,
253+ apb_clock : HertzU32 :: MHz ( 80 ) ,
254+ xtal_clock : HertzU32 :: MHz ( 40 ) ,
255+ i2c_clock : HertzU32 :: MHz ( 80 ) ,
188256 } ,
189257 }
190258 }
@@ -198,9 +266,9 @@ impl ClockControl {
198266 _private : ( ) ,
199267 desired_rates : RawClocks {
200268 cpu_clock : cpu_clock_speed. frequency ( ) ,
201- apb_clock : MegahertzU32 :: MHz ( 80 ) ,
202- xtal_clock : MegahertzU32 :: MHz ( 40 ) ,
203- i2c_clock : MegahertzU32 :: MHz ( 40 ) ,
269+ apb_clock : HertzU32 :: MHz ( 80 ) ,
270+ xtal_clock : HertzU32 :: MHz ( 40 ) ,
271+ i2c_clock : HertzU32 :: MHz ( 40 ) ,
204272 } ,
205273 }
206274 }
@@ -214,10 +282,10 @@ impl ClockControl {
214282 ClockControl {
215283 _private : ( ) ,
216284 desired_rates : RawClocks {
217- cpu_clock : MegahertzU32 :: MHz ( 80 ) ,
218- apb_clock : MegahertzU32 :: MHz ( 80 ) ,
219- xtal_clock : MegahertzU32 :: MHz ( 40 ) ,
220- i2c_clock : MegahertzU32 :: MHz ( 40 ) ,
285+ cpu_clock : HertzU32 :: MHz ( 80 ) ,
286+ apb_clock : HertzU32 :: MHz ( 80 ) ,
287+ xtal_clock : HertzU32 :: MHz ( 40 ) ,
288+ i2c_clock : HertzU32 :: MHz ( 40 ) ,
221289 } ,
222290 }
223291 }
@@ -231,9 +299,9 @@ impl ClockControl {
231299 _private : ( ) ,
232300 desired_rates : RawClocks {
233301 cpu_clock : cpu_clock_speed. frequency ( ) ,
234- apb_clock : MegahertzU32 :: MHz ( 80 ) ,
235- xtal_clock : MegahertzU32 :: MHz ( 40 ) ,
236- i2c_clock : MegahertzU32 :: MHz ( 40 ) ,
302+ apb_clock : HertzU32 :: MHz ( 80 ) ,
303+ xtal_clock : HertzU32 :: MHz ( 40 ) ,
304+ i2c_clock : HertzU32 :: MHz ( 40 ) ,
237305 } ,
238306 }
239307 }
0 commit comments