esp_hal/clock/
mod.rs

1//! # CPU Clock Control
2//!
3//! ## Overview
4//!
5//! Clocks are mainly sourced from oscillator (OSC), RC, and PLL circuits, and
6//! then processed by the dividers or selectors, which allows most functional
7//! modules to select their working clock according to their power consumption
8//! and performance requirements.
9//!
10//! The clock subsystem  is used to source and distribute system/module clocks
11//! from a range of root clocks. The clock tree driver maintains the basic
12//! functionality of the system clock and the intricate relationship among
13//! module clocks.
14//!
15//! ## Configuration
16//!
17//! During HAL initialization, specify a CPU clock speed to configure the
18//! desired clock frequencies.
19//!
20//! The `CPU clock` is responsible for defining the speed at which the central
21//! processing unit (CPU) operates. This driver provides predefined options for
22//! different CPU clock speeds, such as
23#![cfg_attr(not(esp32h2), doc = "* 80MHz")]
24#![cfg_attr(esp32h2, doc = "* 96MHz")]
25#![cfg_attr(esp32c2, doc = "* 120MHz")]
26#![cfg_attr(not(any(esp32c2, esp32h2)), doc = "* 160MHz")]
27#![cfg_attr(xtensa, doc = "* 240MHz")]
28//! ### Frozen Clock Frequencies
29//!
30//! Once the clock configuration is applied, the clock frequencies become
31//! `frozen` and cannot be changed.
32//!
33//! ## Examples
34//!
35//! ### Initialize With Different Clock Frequencies
36//! ```rust, no_run
37#![doc = crate::before_snippet!()]
38//! use esp_hal::clock::CpuClock;
39//!
40//! // Initialize with the highest possible frequency for this chip
41//! let config = esp_hal::Config::default().with_cpu_clock(CpuClock::max());
42//! let peripherals = esp_hal::init(config);
43//! # Ok(())
44//! # }
45//! ```
46
47#[cfg(any(esp32, esp32c2))]
48use crate::rtc_cntl::RtcClock;
49use crate::time::Rate;
50
51#[cfg_attr(esp32, path = "clocks_ll/esp32.rs")]
52#[cfg_attr(esp32c2, path = "clocks_ll/esp32c2.rs")]
53#[cfg_attr(esp32c3, path = "clocks_ll/esp32c3.rs")]
54#[cfg_attr(esp32c6, path = "clocks_ll/esp32c6.rs")]
55#[cfg_attr(esp32h2, path = "clocks_ll/esp32h2.rs")]
56#[cfg_attr(esp32s2, path = "clocks_ll/esp32s2.rs")]
57#[cfg_attr(esp32s3, path = "clocks_ll/esp32s3.rs")]
58pub(crate) mod clocks_ll;
59
60/// Clock properties
61#[doc(hidden)]
62pub trait Clock {
63    /// Frequency of the clock in [Rate].
64    fn frequency(&self) -> Rate;
65
66    /// Frequency of the clock in Megahertz
67    fn mhz(&self) -> u32 {
68        self.frequency().as_mhz()
69    }
70
71    /// Frequency of the clock in Hertz
72    fn hz(&self) -> u32 {
73        self.frequency().as_hz()
74    }
75}
76
77/// CPU clock speed
78#[derive(Debug, Clone, Copy, PartialEq, Eq)]
79#[cfg_attr(feature = "defmt", derive(defmt::Format))]
80#[allow(
81    clippy::enum_variant_names,
82    reason = "MHz suffix indicates physical unit."
83)]
84#[non_exhaustive]
85pub enum CpuClock {
86    /// 80MHz CPU clock
87    #[cfg(not(esp32h2))]
88    _80MHz  = 80,
89
90    /// 96MHz CPU clock
91    #[cfg(esp32h2)]
92    _96MHz  = 96,
93
94    /// 120MHz CPU clock
95    #[cfg(esp32c2)]
96    _120MHz = 120,
97
98    /// 160MHz CPU clock
99    #[cfg(not(any(esp32c2, esp32h2)))]
100    _160MHz = 160,
101
102    /// 240MHz CPU clock
103    #[cfg(xtensa)]
104    _240MHz = 240,
105}
106
107impl Default for CpuClock {
108    fn default() -> Self {
109        cfg_if::cfg_if! {
110            if #[cfg(esp32h2)] {
111                Self::_96MHz
112            } else {
113                // FIXME: I don't think this is correct in general?
114                Self::_80MHz
115            }
116        }
117    }
118}
119
120impl CpuClock {
121    /// Use the highest possible frequency for a particular chip.
122    pub const fn max() -> Self {
123        cfg_if::cfg_if! {
124            if #[cfg(esp32c2)] {
125                Self::_120MHz
126            } else if #[cfg(any(esp32c3, esp32c6))] {
127                Self::_160MHz
128            } else if #[cfg(esp32h2)] {
129                Self::_96MHz
130            } else {
131                Self::_240MHz
132            }
133        }
134    }
135}
136
137impl Clock for CpuClock {
138    fn frequency(&self) -> Rate {
139        Rate::from_mhz(*self as u32)
140    }
141}
142
143/// XTAL clock speed
144#[instability::unstable]
145#[derive(Debug, Clone, Copy)]
146#[non_exhaustive]
147pub enum XtalClock {
148    /// 26MHz XTAL clock
149    #[cfg(any(esp32, esp32c2))]
150    _26M,
151    /// 32MHz XTAL clock
152    #[cfg(any(esp32c3, esp32h2, esp32s3))]
153    _32M,
154    /// 40MHz XTAL clock
155    #[cfg(not(esp32h2))]
156    _40M,
157    /// Other XTAL clock
158    Other(u32),
159}
160
161impl Clock for XtalClock {
162    fn frequency(&self) -> Rate {
163        match self {
164            #[cfg(any(esp32, esp32c2))]
165            XtalClock::_26M => Rate::from_mhz(26),
166            #[cfg(any(esp32c3, esp32h2, esp32s3))]
167            XtalClock::_32M => Rate::from_mhz(32),
168            #[cfg(not(esp32h2))]
169            XtalClock::_40M => Rate::from_mhz(40),
170            XtalClock::Other(mhz) => Rate::from_mhz(*mhz),
171        }
172    }
173}
174
175#[allow(clippy::enum_variant_names, unused)]
176#[derive(Debug, Clone, Copy, PartialEq)]
177pub(crate) enum PllClock {
178    #[cfg(esp32h2)]
179    Pll8MHz,
180    #[cfg(any(esp32c6, esp32h2))]
181    Pll48MHz,
182    #[cfg(esp32h2)]
183    Pll64MHz,
184    #[cfg(esp32c6)]
185    Pll80MHz,
186    #[cfg(esp32h2)]
187    Pll96MHz,
188    #[cfg(esp32c6)]
189    Pll120MHz,
190    #[cfg(esp32c6)]
191    Pll160MHz,
192    #[cfg(esp32c6)]
193    Pll240MHz,
194    #[cfg(not(any(esp32c2, esp32c6, esp32h2)))]
195    Pll320MHz,
196    #[cfg(not(esp32h2))]
197    Pll480MHz,
198}
199
200impl Clock for PllClock {
201    fn frequency(&self) -> Rate {
202        match self {
203            #[cfg(esp32h2)]
204            Self::Pll8MHz => Rate::from_mhz(8),
205            #[cfg(any(esp32c6, esp32h2))]
206            Self::Pll48MHz => Rate::from_mhz(48),
207            #[cfg(esp32h2)]
208            Self::Pll64MHz => Rate::from_mhz(64),
209            #[cfg(esp32c6)]
210            Self::Pll80MHz => Rate::from_mhz(80),
211            #[cfg(esp32h2)]
212            Self::Pll96MHz => Rate::from_mhz(96),
213            #[cfg(esp32c6)]
214            Self::Pll120MHz => Rate::from_mhz(120),
215            #[cfg(esp32c6)]
216            Self::Pll160MHz => Rate::from_mhz(160),
217            #[cfg(esp32c6)]
218            Self::Pll240MHz => Rate::from_mhz(240),
219            #[cfg(not(any(esp32c2, esp32c6, esp32h2)))]
220            Self::Pll320MHz => Rate::from_mhz(320),
221            #[cfg(not(esp32h2))]
222            Self::Pll480MHz => Rate::from_mhz(480),
223        }
224    }
225}
226
227#[allow(unused)]
228#[derive(Debug, Clone, Copy)]
229pub(crate) enum ApbClock {
230    #[cfg(esp32h2)]
231    ApbFreq32MHz,
232    #[cfg(not(esp32h2))]
233    ApbFreq40MHz,
234    #[cfg(not(esp32h2))]
235    ApbFreq80MHz,
236    ApbFreqOther(u32),
237}
238
239impl Clock for ApbClock {
240    fn frequency(&self) -> Rate {
241        match self {
242            #[cfg(esp32h2)]
243            ApbClock::ApbFreq32MHz => Rate::from_mhz(32),
244            #[cfg(not(esp32h2))]
245            ApbClock::ApbFreq40MHz => Rate::from_mhz(40),
246            #[cfg(not(esp32h2))]
247            ApbClock::ApbFreq80MHz => Rate::from_mhz(80),
248            ApbClock::ApbFreqOther(mhz) => Rate::from_mhz(*mhz),
249        }
250    }
251}
252
253/// Clock frequencies.
254#[derive(Debug, Clone, Copy)]
255#[cfg_attr(feature = "defmt", derive(defmt::Format))]
256#[non_exhaustive]
257#[doc(hidden)]
258pub struct Clocks {
259    /// CPU clock frequency
260    pub cpu_clock: Rate,
261
262    /// APB clock frequency
263    pub apb_clock: Rate,
264
265    /// XTAL clock frequency
266    pub xtal_clock: Rate,
267
268    /// I2C clock frequency
269    #[cfg(esp32)]
270    pub i2c_clock: Rate,
271
272    /// PWM clock frequency
273    #[cfg(esp32)]
274    pub pwm_clock: Rate,
275
276    /// Crypto PWM  clock frequency
277    #[cfg(esp32s3)]
278    pub crypto_pwm_clock: Rate,
279
280    /// Crypto clock frequency
281    #[cfg(any(esp32c6, esp32h2))]
282    pub crypto_clock: Rate,
283
284    /// PLL 48M clock frequency (fixed)
285    #[cfg(esp32h2)]
286    pub pll_48m_clock: Rate,
287
288    /// PLL 96M clock frequency (fixed)
289    #[cfg(esp32h2)]
290    pub pll_96m_clock: Rate,
291}
292
293static mut ACTIVE_CLOCKS: Option<Clocks> = None;
294
295impl Clocks {
296    pub(crate) fn init(cpu_clock_speed: CpuClock) {
297        critical_section::with(|_| {
298            unsafe { ACTIVE_CLOCKS = Some(Self::configure(cpu_clock_speed)) };
299        })
300    }
301
302    fn try_get<'a>() -> Option<&'a Clocks> {
303        unsafe {
304            // Safety: ACTIVE_CLOCKS is only set in `init` and never modified after that.
305            let clocks = &*core::ptr::addr_of!(ACTIVE_CLOCKS);
306            clocks.as_ref()
307        }
308    }
309
310    /// Get the active clock configuration.
311    pub fn get<'a>() -> &'a Clocks {
312        unwrap!(Self::try_get())
313    }
314
315    /// Returns the xtal frequency.
316    ///
317    /// This function will run the frequency estimation if called before
318    /// [`crate::init()`].
319    #[cfg(systimer)]
320    #[inline]
321    pub(crate) fn xtal_freq() -> Rate {
322        if esp_config::esp_config_str!("ESP_HAL_CONFIG_XTAL_FREQUENCY") == "auto" {
323            if let Some(clocks) = Self::try_get() {
324                return clocks.xtal_clock;
325            }
326        }
327
328        Self::measure_xtal_frequency().frequency()
329    }
330}
331
332#[cfg(esp32)]
333impl Clocks {
334    fn measure_xtal_frequency() -> XtalClock {
335        if esp_config::esp_config_str!("ESP_HAL_CONFIG_XTAL_FREQUENCY") == "auto" {
336            if RtcClock::estimate_xtal_frequency() > 33 {
337                XtalClock::_40M
338            } else {
339                XtalClock::_26M
340            }
341        } else {
342            const {
343                let frequency_conf = esp_config::esp_config_str!("ESP_HAL_CONFIG_XTAL_FREQUENCY");
344                match frequency_conf.as_bytes() {
345                    b"auto" => XtalClock::Other(0), // Can't be `unreachable!` due to const eval.
346                    b"26" => XtalClock::_26M,
347                    b"40" => XtalClock::_40M,
348                    _ => XtalClock::Other(esp_config::esp_config_int_parse!(u32, frequency_conf)),
349                }
350            }
351        }
352    }
353
354    /// Configure the CPU clock speed.
355    pub(crate) fn configure(cpu_clock_speed: CpuClock) -> Self {
356        let xtal_freq = Self::measure_xtal_frequency();
357
358        if cpu_clock_speed != CpuClock::default() {
359            let pll_freq = match cpu_clock_speed {
360                CpuClock::_80MHz => PllClock::Pll320MHz,
361                CpuClock::_160MHz => PllClock::Pll320MHz,
362                CpuClock::_240MHz => PllClock::Pll480MHz,
363            };
364
365            clocks_ll::esp32_rtc_update_to_xtal(xtal_freq, 1);
366            clocks_ll::esp32_rtc_bbpll_enable();
367            clocks_ll::esp32_rtc_bbpll_configure(xtal_freq, pll_freq);
368            clocks_ll::set_cpu_freq(cpu_clock_speed);
369        }
370
371        Self {
372            cpu_clock: cpu_clock_speed.frequency(),
373            apb_clock: Rate::from_mhz(80),
374            xtal_clock: Rate::from_mhz(xtal_freq.mhz()),
375            i2c_clock: Rate::from_mhz(80),
376            // The docs are unclear here. pwm_clock seems to be tied to clocks.apb_clock
377            // while simultaneously being fixed at 160 MHz.
378            // Testing showed 160 MHz to be correct for current clock configurations.
379            pwm_clock: Rate::from_mhz(160),
380        }
381    }
382}
383
384#[cfg(esp32c2)]
385impl Clocks {
386    fn measure_xtal_frequency() -> XtalClock {
387        if esp_config::esp_config_str!("ESP_HAL_CONFIG_XTAL_FREQUENCY") == "auto" {
388            if RtcClock::estimate_xtal_frequency() > 33 {
389                XtalClock::_40M
390            } else {
391                XtalClock::_26M
392            }
393        } else {
394            const {
395                let frequency_conf = esp_config::esp_config_str!("ESP_HAL_CONFIG_XTAL_FREQUENCY");
396                match frequency_conf.as_bytes() {
397                    b"auto" => XtalClock::Other(0), // Can't be `unreachable!` due to const eval.
398                    b"26" => XtalClock::_26M,
399                    b"40" => XtalClock::_40M,
400                    _ => XtalClock::Other(esp_config::esp_config_int_parse!(u32, frequency_conf)),
401                }
402            }
403        }
404    }
405
406    /// Configure the CPU clock speed.
407    pub(crate) fn configure(cpu_clock_speed: CpuClock) -> Self {
408        let xtal_freq = Self::measure_xtal_frequency();
409
410        let apb_freq;
411        if cpu_clock_speed != CpuClock::default() {
412            let pll_freq = PllClock::Pll480MHz;
413
414            if cpu_clock_speed.mhz() <= xtal_freq.mhz() {
415                apb_freq = ApbClock::ApbFreqOther(cpu_clock_speed.mhz());
416                clocks_ll::esp32c2_rtc_update_to_xtal(xtal_freq, 1);
417                clocks_ll::esp32c2_rtc_apb_freq_update(apb_freq);
418            } else {
419                apb_freq = ApbClock::ApbFreq40MHz;
420                clocks_ll::esp32c2_rtc_bbpll_enable();
421                clocks_ll::esp32c2_rtc_bbpll_configure(xtal_freq, pll_freq);
422                clocks_ll::esp32c2_rtc_freq_to_pll_mhz(cpu_clock_speed);
423                clocks_ll::esp32c2_rtc_apb_freq_update(apb_freq);
424            }
425        } else {
426            apb_freq = ApbClock::ApbFreq40MHz;
427        }
428
429        Self {
430            cpu_clock: cpu_clock_speed.frequency(),
431            apb_clock: apb_freq.frequency(),
432            xtal_clock: xtal_freq.frequency(),
433        }
434    }
435}
436
437#[cfg(esp32c3)]
438impl Clocks {
439    fn measure_xtal_frequency() -> XtalClock {
440        XtalClock::_40M
441    }
442
443    /// Configure the CPU clock speed.
444    pub(crate) fn configure(cpu_clock_speed: CpuClock) -> Self {
445        let xtal_freq = Self::measure_xtal_frequency();
446
447        let apb_freq;
448        if cpu_clock_speed != CpuClock::default() {
449            if cpu_clock_speed.mhz() <= xtal_freq.mhz() {
450                apb_freq = ApbClock::ApbFreqOther(cpu_clock_speed.mhz());
451                clocks_ll::esp32c3_rtc_update_to_xtal(xtal_freq, 1);
452                clocks_ll::esp32c3_rtc_apb_freq_update(apb_freq);
453            } else {
454                let pll_freq = PllClock::Pll480MHz;
455                apb_freq = ApbClock::ApbFreq80MHz;
456                clocks_ll::esp32c3_rtc_bbpll_enable();
457                clocks_ll::esp32c3_rtc_bbpll_configure(xtal_freq, pll_freq);
458                clocks_ll::esp32c3_rtc_freq_to_pll_mhz(cpu_clock_speed);
459                clocks_ll::esp32c3_rtc_apb_freq_update(apb_freq);
460            }
461        } else {
462            apb_freq = ApbClock::ApbFreq80MHz;
463        }
464
465        Self {
466            cpu_clock: cpu_clock_speed.frequency(),
467            apb_clock: apb_freq.frequency(),
468            xtal_clock: xtal_freq.frequency(),
469        }
470    }
471}
472
473#[cfg(esp32c6)]
474impl Clocks {
475    fn measure_xtal_frequency() -> XtalClock {
476        XtalClock::_40M
477    }
478
479    /// Configure the CPU clock speed.
480    pub(crate) fn configure(cpu_clock_speed: CpuClock) -> Self {
481        let xtal_freq = Self::measure_xtal_frequency();
482
483        let apb_freq;
484        if cpu_clock_speed != CpuClock::default() {
485            if cpu_clock_speed.mhz() <= xtal_freq.mhz() {
486                apb_freq = ApbClock::ApbFreqOther(cpu_clock_speed.mhz());
487                clocks_ll::esp32c6_rtc_update_to_xtal(xtal_freq, 1);
488                clocks_ll::esp32c6_rtc_apb_freq_update(apb_freq);
489            } else {
490                let pll_freq = PllClock::Pll480MHz;
491                apb_freq = ApbClock::ApbFreq80MHz;
492                clocks_ll::esp32c6_rtc_bbpll_enable();
493                clocks_ll::esp32c6_rtc_bbpll_configure(xtal_freq, pll_freq);
494                clocks_ll::esp32c6_rtc_freq_to_pll_mhz(cpu_clock_speed);
495                clocks_ll::esp32c6_rtc_apb_freq_update(apb_freq);
496            }
497        } else {
498            apb_freq = ApbClock::ApbFreq80MHz;
499        }
500
501        Self {
502            cpu_clock: cpu_clock_speed.frequency(),
503            apb_clock: apb_freq.frequency(),
504            xtal_clock: xtal_freq.frequency(),
505            crypto_clock: Rate::from_mhz(160),
506        }
507    }
508}
509
510#[cfg(esp32h2)]
511impl Clocks {
512    fn measure_xtal_frequency() -> XtalClock {
513        XtalClock::_32M
514    }
515
516    /// Configure the CPU clock speed.
517    pub(crate) fn configure(cpu_clock_speed: CpuClock) -> Self {
518        let xtal_freq = Self::measure_xtal_frequency();
519
520        let apb_freq;
521        if cpu_clock_speed != CpuClock::default() {
522            if cpu_clock_speed.mhz() <= xtal_freq.mhz() {
523                apb_freq = ApbClock::ApbFreqOther(cpu_clock_speed.mhz());
524                clocks_ll::esp32h2_rtc_update_to_xtal(xtal_freq, 1);
525                clocks_ll::esp32h2_rtc_apb_freq_update(apb_freq);
526            } else {
527                let pll_freq = PllClock::Pll96MHz;
528                apb_freq = ApbClock::ApbFreq32MHz;
529                clocks_ll::esp32h2_rtc_bbpll_enable();
530                clocks_ll::esp32h2_rtc_bbpll_configure(xtal_freq, pll_freq);
531                clocks_ll::esp32h2_rtc_freq_to_pll_mhz(cpu_clock_speed);
532                clocks_ll::esp32h2_rtc_apb_freq_update(apb_freq);
533            }
534        } else {
535            apb_freq = ApbClock::ApbFreq32MHz;
536        }
537
538        Self {
539            cpu_clock: cpu_clock_speed.frequency(),
540            apb_clock: apb_freq.frequency(),
541            xtal_clock: xtal_freq.frequency(),
542            pll_48m_clock: Rate::from_mhz(48),
543            crypto_clock: Rate::from_mhz(96),
544            pll_96m_clock: Rate::from_mhz(96),
545        }
546    }
547}
548
549#[cfg(esp32s2)]
550impl Clocks {
551    fn measure_xtal_frequency() -> XtalClock {
552        XtalClock::_40M
553    }
554
555    /// Configure the CPU clock speed.
556    pub(crate) fn configure(cpu_clock_speed: CpuClock) -> Self {
557        let xtal_freq = Self::measure_xtal_frequency();
558
559        if cpu_clock_speed != CpuClock::default() {
560            clocks_ll::set_cpu_clock(cpu_clock_speed);
561        }
562
563        Self {
564            cpu_clock: cpu_clock_speed.frequency(),
565            apb_clock: Rate::from_mhz(80),
566            xtal_clock: xtal_freq.frequency(),
567        }
568    }
569}
570
571#[cfg(esp32s3)]
572impl Clocks {
573    fn measure_xtal_frequency() -> XtalClock {
574        XtalClock::_40M
575    }
576
577    /// Configure the CPU clock speed.
578    pub(crate) fn configure(cpu_clock_speed: CpuClock) -> Self {
579        let xtal_freq = Self::measure_xtal_frequency();
580
581        if cpu_clock_speed != CpuClock::default() {
582            clocks_ll::set_cpu_clock(cpu_clock_speed);
583        }
584
585        Self {
586            cpu_clock: cpu_clock_speed.frequency(),
587            apb_clock: Rate::from_mhz(80),
588            xtal_clock: xtal_freq.frequency(),
589            crypto_pwm_clock: Rate::from_mhz(160),
590        }
591    }
592}
593
594/// Control the radio peripheral clocks
595#[cfg(any(bt, ieee802154, wifi))]
596#[instability::unstable]
597pub struct RadioClockController<'d> {
598    _rcc: crate::peripherals::RADIO_CLK<'d>,
599}
600
601#[cfg(any(bt, ieee802154, wifi))]
602impl<'d> RadioClockController<'d> {
603    /// Create a new instance of the radio clock controller
604    #[instability::unstable]
605    pub fn new(rcc: crate::peripherals::RADIO_CLK<'d>) -> Self {
606        Self { _rcc: rcc }
607    }
608
609    /// Enable the PHY clocks
610    #[instability::unstable]
611    #[cfg(phy)]
612    #[inline]
613    pub fn enable_phy(&mut self, enable: bool) {
614        clocks_ll::enable_phy(enable);
615    }
616
617    /// Enable the Bluetooth clocks
618    #[instability::unstable]
619    #[cfg(bt)]
620    #[inline]
621    pub fn enable_bt(&mut self, enable: bool) {
622        clocks_ll::enable_bt(enable);
623    }
624
625    /// Enable the WiFi clocks
626    #[instability::unstable]
627    #[cfg(wifi)]
628    #[inline]
629    pub fn enable_wifi(&mut self, enable: bool) {
630        clocks_ll::enable_wifi(enable);
631    }
632
633    /// Enable the IEEE 802.15.4 peripheral clocks
634    #[instability::unstable]
635    #[cfg(ieee802154)]
636    #[inline]
637    pub fn enable_ieee802154(&mut self, enable: bool) {
638        clocks_ll::enable_ieee802154(enable);
639    }
640
641    /// Reset the MAC
642    #[instability::unstable]
643    #[inline]
644    pub fn reset_mac(&mut self) {
645        clocks_ll::reset_mac();
646    }
647
648    /// Do any common initial initialization needed
649    #[instability::unstable]
650    #[inline]
651    pub fn init_clocks(&mut self) {
652        clocks_ll::init_clocks();
653    }
654
655    /// Initialize BLE RTC clocks
656    #[instability::unstable]
657    #[inline]
658    pub fn ble_rtc_clk_init(&mut self) {
659        clocks_ll::ble_rtc_clk_init();
660    }
661
662    /// Reset the Resolvable Private Address (RPA).
663    #[instability::unstable]
664    #[inline]
665    pub fn reset_rpa(&mut self) {
666        clocks_ll::reset_rpa();
667    }
668}