lpc8xx_hal/syscon/
mod.rs

1//! API for system configuration (SYSCON)
2//!
3//! The entry point to this API is [`SYSCON`]. Please refer to [`SYSCON`]'s
4//! documentation for additional information.
5//!
6//! This module mostly provides infrastructure required by other parts of the
7//! HAL API. For this reason, only a small subset of SYSCON functionality is
8//! currently implemented.
9//!
10//! The SYSCON peripheral is described in the user manual, chapter 5.
11
12#[cfg(feature = "845")]
13pub mod frg;
14
15#[cfg(feature = "845")]
16pub use self::frg::FRG;
17
18pub mod clock_source;
19
20#[cfg(feature = "82x")]
21use crate::pac::syscon::{
22    pdruncfg, presetctrl as presetctrl0, starterp1,
23    sysahbclkctrl as sysahbclkctrl0, PDRUNCFG, PRESETCTRL as PRESETCTRL0,
24    STARTERP1, SYSAHBCLKCTRL as SYSAHBCLKCTRL0, UARTCLKDIV, UARTFRGDIV,
25    UARTFRGMULT,
26};
27
28#[cfg(feature = "845")]
29use crate::pac::syscon::{
30    pdruncfg, presetctrl0, starterp1, sysahbclkctrl0, FCLKSEL, PDRUNCFG,
31    PRESETCTRL0, STARTERP1, SYSAHBCLKCTRL0,
32};
33
34use crate::{clock, init_state, pac, reg_proxy::RegProxy};
35
36/// Entry point to the SYSCON API
37///
38/// The SYSCON API is split into multiple parts, which are all available through
39/// [`syscon::Parts`]. You can use [`SYSCON::split`] to gain access to
40/// [`syscon::Parts`].
41///
42/// You can also use this struct to gain access to the raw peripheral using
43/// [`SYSCON::free`]. This is the main reason this struct exists, as it's no
44/// longer possible to do this after the API has been split.
45///
46/// Use [`Peripherals`] to gain access to an instance of this struct.
47///
48/// Please refer to the [module documentation] for more information.
49///
50/// [`syscon::Parts`]: struct.Parts.html
51/// [`Peripherals`]: ../struct.Peripherals.html
52/// [module documentation]: index.html
53pub struct SYSCON {
54    syscon: pac::SYSCON,
55}
56
57impl SYSCON {
58    pub(crate) fn new(syscon: pac::SYSCON) -> Self {
59        SYSCON { syscon }
60    }
61
62    /// Splits the SYSCON API into its component parts
63    ///
64    /// This is the regular way to access the SYSCON API. It exists as an
65    /// explicit step, as it's no longer possible to gain access to the raw
66    /// peripheral using [`SYSCON::free`] after you've called this method.
67    pub fn split(self) -> Parts {
68        Parts {
69            handle: Handle {
70                pdruncfg: RegProxy::new(),
71                presetctrl0: RegProxy::new(),
72                starterp1: RegProxy::new(),
73                sysahbclkctrl: RegProxy::new(),
74                #[cfg(feature = "845")]
75                fclksel: RegProxy::new(),
76            },
77
78            bod: BOD(()),
79            flash: FLASH(()),
80            iosc: IOSC(()),
81            ioscout: IOSCOUT(()),
82            mtb: MTB(()),
83            ram0_1: RAM0_1(()),
84            rom: ROM(()),
85            sysosc: SYSOSC(()),
86            syspll: SYSPLL(()),
87
88            #[cfg(feature = "82x")]
89            uartfrg: UARTFRG {
90                uartclkdiv: RegProxy::new(),
91                uartfrgdiv: RegProxy::new(),
92                uartfrgmult: RegProxy::new(),
93            },
94
95            iosc_derived_clock: IoscDerivedClock::new(),
96            #[cfg(feature = "845")]
97            frg0: FRG::new(),
98            #[cfg(feature = "845")]
99            frg1: FRG::new(),
100        }
101    }
102
103    /// Return the raw peripheral
104    ///
105    /// This method serves as an escape hatch from the HAL API. It returns the
106    /// raw peripheral, allowing you to do whatever you want with it, without
107    /// limitations imposed by the API.
108    ///
109    /// If you are using this method because a feature you need is missing from
110    /// the HAL API, please [open an issue] or, if an issue for your feature
111    /// request already exists, comment on the existing issue, so we can
112    /// prioritize it accordingly.
113    ///
114    /// [open an issue]: https://github.com/lpc-rs/lpc8xx-hal/issues
115    pub fn free(self) -> pac::SYSCON {
116        self.syscon
117    }
118}
119
120/// The main API for the SYSCON peripheral
121///
122/// Provides access to all types that make up the SYSCON API. Please refer to
123/// the [module documentation] for more information.
124///
125/// [module documentation]: index.html
126pub struct Parts {
127    /// The handle to the SYSCON peripheral
128    pub handle: Handle,
129
130    /// Brown-out detection
131    pub bod: BOD,
132
133    /// Flash memory
134    pub flash: FLASH,
135
136    /// IRC/FRO
137    pub iosc: IOSC,
138
139    /// IRC/FRO output
140    pub ioscout: IOSCOUT,
141
142    /// Micro Trace Buffer
143    pub mtb: MTB,
144
145    /// Random access memory
146    pub ram0_1: RAM0_1,
147
148    /// Read-only memory
149    pub rom: ROM,
150
151    /// System oscillator
152    pub sysosc: SYSOSC,
153
154    /// PLL
155    pub syspll: SYSPLL,
156
157    #[cfg(feature = "82x")]
158    /// UART Fractional Baud Rate Generator
159    pub uartfrg: UARTFRG,
160
161    /// The 750 kHz internal oscillator/IRC/FRO-derived clock
162    pub iosc_derived_clock: IoscDerivedClock<init_state::Enabled>,
163
164    #[cfg(feature = "845")]
165    /// Fractional Baud Rate Generator 0
166    pub frg0: FRG<frg::FRG0>,
167
168    #[cfg(feature = "845")]
169    /// Fractional Baud Rate Generator 1
170    pub frg1: FRG<frg::FRG1>,
171}
172
173/// Handle to the SYSCON peripheral
174///
175/// This handle to the SYSCON peripheral provides access to the main part of the
176/// SYSCON API. It is also required by other parts of the HAL API to synchronize
177/// access the the underlying registers, wherever this is required.
178///
179/// Please refer to the [module documentation] for more information about the
180/// PMU.
181///
182/// [module documentation]: index.html
183pub struct Handle {
184    pdruncfg: RegProxy<PDRUNCFG>,
185    presetctrl0: RegProxy<PRESETCTRL0>,
186    starterp1: RegProxy<STARTERP1>,
187    sysahbclkctrl: RegProxy<SYSAHBCLKCTRL0>,
188    #[cfg(feature = "845")]
189    pub(crate) fclksel: RegProxy<FCLKSEL>,
190}
191
192impl Handle {
193    /// Enable peripheral clock
194    ///
195    /// Enables the clock for a peripheral or other hardware component. HAL
196    /// users usually won't have to call this method directly, as other
197    /// peripheral APIs will do this for them.
198    pub fn enable_clock<P: ClockControl>(&mut self, peripheral: &P) {
199        self.sysahbclkctrl.modify(|_, w| peripheral.enable_clock(w));
200    }
201
202    /// Disable peripheral clock
203    pub fn disable_clock<P: ClockControl>(&mut self, peripheral: &P) {
204        self.sysahbclkctrl
205            .modify(|_, w| peripheral.disable_clock(w));
206    }
207
208    /// Assert peripheral reset
209    pub fn assert_reset<P: ResetControl>(&mut self, peripheral: &P) {
210        self.presetctrl0.modify(|_, w| peripheral.assert_reset(w));
211    }
212
213    /// Clear peripheral reset
214    ///
215    /// Clears the reset for a peripheral or other hardware component. HAL users
216    /// usually won't have to call this method directly, as other peripheral
217    /// APIs will do this for them.
218    pub fn clear_reset<P: ResetControl>(&mut self, peripheral: &P) {
219        self.presetctrl0.modify(|_, w| peripheral.clear_reset(w));
220    }
221
222    /// Provide power to an analog block
223    ///
224    /// HAL users usually won't have to call this method themselves, as other
225    /// peripheral APIs will do this for them.
226    pub fn power_up<P: AnalogBlock>(&mut self, peripheral: &P) {
227        self.pdruncfg.modify(|_, w| peripheral.power_up(w));
228    }
229
230    /// Remove power from an analog block
231    pub fn power_down<P: AnalogBlock>(&mut self, peripheral: &P) {
232        self.pdruncfg.modify(|_, w| peripheral.power_down(w));
233    }
234
235    /// Enable interrupt wake-up from deep-sleep and power-down modes
236    ///
237    /// To use an interrupt for waking up the system from the deep-sleep and
238    /// power-down modes, it needs to be enabled using this method, in addition
239    /// to being enabled in the NVIC.
240    ///
241    /// This method is not required when using the regular sleep mode.
242    pub fn enable_interrupt_wakeup<I>(&mut self)
243    where
244        I: WakeUpInterrupt,
245    {
246        self.starterp1.modify(|_, w| I::enable(w));
247    }
248
249    /// Disable interrupt wake-up from deep-sleep and power-down modes
250    pub fn disable_interrupt_wakeup<I>(&mut self)
251    where
252        I: WakeUpInterrupt,
253    {
254        self.starterp1.modify(|_, w| I::disable(w));
255    }
256}
257
258/// Brown-out detection
259///
260/// Can be used to control brown-out detection using various methods on
261/// [`syscon::Handle`].
262///
263/// [`syscon::Handle`]: struct.Handle.html
264#[derive(Debug)]
265pub struct BOD(());
266
267/// Flash memory
268///
269/// Can be used to control flash memory using various methods on
270/// [`syscon::Handle`].
271///
272/// [`syscon::Handle`]: struct.Handle.html
273#[derive(Debug)]
274pub struct FLASH(());
275
276/// IOSC
277///
278/// Can be used to control the IRC/FRO using various methods on [`syscon::Handle`].
279///
280/// [`syscon::Handle`]: struct.Handle.html
281#[derive(Debug)]
282pub struct IOSC(());
283
284/// IOSC output
285///
286/// Can be used to control IRC/FRO output using various methods on
287/// [`syscon::Handle`].
288///
289/// [`syscon::Handle`]: struct.Handle.html
290#[derive(Debug)]
291pub struct IOSCOUT(());
292
293/// Micro Trace Buffer
294///
295/// Can be used to control the Micro Trace Buffer using various methods on
296/// [`syscon::Handle`].
297///
298/// [`syscon::Handle`]: struct.Handle.html
299#[derive(Debug)]
300pub struct MTB(());
301
302/// Random access memory
303///
304/// Can be used to control the RAM using various methods on [`syscon::Handle`].
305///
306/// [`syscon::Handle`]: struct.Handle.html
307#[derive(Debug)]
308#[allow(non_camel_case_types)]
309pub struct RAM0_1(());
310
311/// Read-only memory
312///
313/// Can be used to control the ROM using various methods on [`syscon::Handle`].
314///
315/// [`syscon::Handle`]: struct.Handle.html
316#[derive(Debug)]
317pub struct ROM(());
318
319/// System oscillator
320///
321/// Can be used to control the system oscillator using various methods on
322/// [`syscon::Handle`].
323///
324/// [`syscon::Handle`]: struct.Handle.html
325#[derive(Debug)]
326pub struct SYSOSC(());
327
328/// PLL
329///
330/// Can be used to control the PLL using various methods on [`syscon::Handle`].
331///
332/// [`syscon::Handle`]: struct.Handle.html
333#[derive(Debug)]
334pub struct SYSPLL(());
335
336#[cfg(feature = "82x")]
337/// UART Fractional Baud Rate Generator
338///
339/// Controls the common clock for all UART peripherals (U_PCLK).
340///
341/// Can also be used to control the UART FRG using various methods on
342/// [`syscon::Handle`].
343///
344/// [`syscon::Handle`]: struct.Handle.html
345pub struct UARTFRG {
346    uartclkdiv: RegProxy<UARTCLKDIV>,
347    uartfrgdiv: RegProxy<UARTFRGDIV>,
348    uartfrgmult: RegProxy<UARTFRGMULT>,
349}
350
351#[cfg(feature = "82x")]
352impl UARTFRG {
353    /// Set UART clock divider value (UARTCLKDIV)
354    ///
355    /// See user manual, section 5.6.15.
356    pub fn set_clkdiv(&mut self, value: u8) {
357        self.uartclkdiv.write(|w| unsafe { w.div().bits(value) });
358    }
359
360    /// Set UART fractional generator multiplier value (UARTFRGMULT)
361    ///
362    /// See user manual, section 5.6.20.
363    pub fn set_frgmult(&mut self, value: u8) {
364        self.uartfrgmult.write(|w| unsafe { w.mult().bits(value) });
365    }
366
367    /// Set UART fractional generator divider value (UARTFRGDIV)
368    ///
369    /// See user manual, section 5.6.19.
370    pub fn set_frgdiv(&mut self, value: u8) {
371        self.uartfrgdiv.write(|w| unsafe { w.div().bits(value) });
372    }
373}
374
375/// Internal trait for controlling peripheral clocks
376///
377/// This trait is an internal implementation detail and should neither be
378/// implemented nor used outside of LPC8xx HAL. Any changes to this trait won't
379/// be considered breaking changes.
380///
381/// Please refer to [`syscon::Handle::enable_clock`] and
382/// [`syscon::Handle::disable_clock`] for the public API that uses this trait.
383///
384/// [`syscon::Handle::enable_clock`]: struct.Handle.html#method.enable_clock
385/// [`syscon::Handle::disable_clock`]: struct.Handle.html#method.disable_clock
386pub trait ClockControl {
387    /// Internal method to enable a peripheral clock
388    fn enable_clock<'w>(
389        &self,
390        w: &'w mut sysahbclkctrl0::W,
391    ) -> &'w mut sysahbclkctrl0::W;
392
393    /// Internal method to disable a peripheral clock
394    fn disable_clock<'w>(
395        &self,
396        w: &'w mut sysahbclkctrl0::W,
397    ) -> &'w mut sysahbclkctrl0::W;
398}
399
400macro_rules! impl_clock_control {
401    ($clock_control:ty, $clock:ident) => {
402        impl ClockControl for $clock_control {
403            fn enable_clock<'w>(
404                &self,
405                w: &'w mut sysahbclkctrl0::W,
406            ) -> &'w mut sysahbclkctrl0::W {
407                w.$clock().set_bit()
408            }
409
410            fn disable_clock<'w>(
411                &self,
412                w: &'w mut sysahbclkctrl0::W,
413            ) -> &'w mut sysahbclkctrl0::W {
414                w.$clock().clear_bit()
415            }
416        }
417    };
418}
419
420impl_clock_control!(ROM, rom);
421impl_clock_control!(RAM0_1, ram0_1);
422#[cfg(feature = "82x")]
423impl_clock_control!(pac::FLASH_CTRL, flashreg);
424#[cfg(feature = "845")]
425impl_clock_control!(pac::FLASH_CTRL, flash);
426impl_clock_control!(FLASH, flash);
427impl_clock_control!(pac::I2C0, i2c0);
428#[cfg(feature = "82x")]
429impl_clock_control!(pac::GPIO, gpio);
430impl_clock_control!(pac::SWM0, swm);
431impl_clock_control!(pac::SCT0, sct);
432impl_clock_control!(pac::WKT, wkt);
433impl_clock_control!(pac::MRT0, mrt);
434#[cfg(feature = "845")]
435impl_clock_control!(pac::CTIMER0, ctimer);
436impl_clock_control!(pac::SPI0, spi0);
437impl_clock_control!(pac::SPI1, spi1);
438impl_clock_control!(pac::CRC, crc);
439impl_clock_control!(pac::USART0, uart0);
440impl_clock_control!(pac::USART1, uart1);
441impl_clock_control!(pac::USART2, uart2);
442#[cfg(feature = "845")]
443impl_clock_control!(pac::USART3, uart3);
444#[cfg(feature = "845")]
445impl_clock_control!(pac::USART4, uart4);
446impl_clock_control!(pac::WWDT, wwdt);
447impl_clock_control!(pac::IOCON, iocon);
448impl_clock_control!(pac::ACOMP, acmp);
449impl_clock_control!(pac::I2C1, i2c1);
450impl_clock_control!(pac::I2C2, i2c2);
451impl_clock_control!(pac::I2C3, i2c3);
452impl_clock_control!(pac::ADC0, adc);
453impl_clock_control!(MTB, mtb);
454impl_clock_control!(pac::DMA0, dma);
455#[cfg(feature = "845")]
456impl_clock_control!(pac::PINT, gpio_int);
457
458#[cfg(feature = "845")]
459impl ClockControl for pac::GPIO {
460    fn enable_clock<'w>(
461        &self,
462        w: &'w mut sysahbclkctrl0::W,
463    ) -> &'w mut sysahbclkctrl0::W {
464        w.gpio0().enable().gpio1().enable()
465    }
466
467    fn disable_clock<'w>(
468        &self,
469        w: &'w mut sysahbclkctrl0::W,
470    ) -> &'w mut sysahbclkctrl0::W {
471        w.gpio0().disable().gpio1().disable()
472    }
473}
474
475/// Internal trait for controlling peripheral reset
476///
477/// This trait is an internal implementation detail and should neither be
478/// implemented nor used outside of LPC8xx HAL. Any incompatible changes to this
479/// trait won't be considered breaking changes.
480///
481/// Please refer to [`syscon::Handle::assert_reset`] and
482/// [`syscon::Handle::clear_reset`] for the public API that uses this trait.
483///
484/// [`syscon::Handle::assert_reset`]: struct.Handle.html#method.assert_reset
485/// [`syscon::Handle::clear_reset`]: struct.Handle.html#method.clear_reset
486pub trait ResetControl {
487    /// Internal method to assert peripheral reset
488    fn assert_reset<'w>(
489        &self,
490        w: &'w mut presetctrl0::W,
491    ) -> &'w mut presetctrl0::W;
492
493    /// Internal method to clear peripheral reset
494    fn clear_reset<'w>(
495        &self,
496        w: &'w mut presetctrl0::W,
497    ) -> &'w mut presetctrl0::W;
498}
499
500macro_rules! impl_reset_control {
501    ($reset_control:ty, $field:ident) => {
502        impl<'a> ResetControl for $reset_control {
503            fn assert_reset<'w>(
504                &self,
505                w: &'w mut presetctrl0::W,
506            ) -> &'w mut presetctrl0::W {
507                w.$field().clear_bit()
508            }
509
510            fn clear_reset<'w>(
511                &self,
512                w: &'w mut presetctrl0::W,
513            ) -> &'w mut presetctrl0::W {
514                w.$field().set_bit()
515            }
516        }
517    };
518}
519
520impl_reset_control!(pac::SPI0, spi0_rst_n);
521impl_reset_control!(pac::SPI1, spi1_rst_n);
522#[cfg(feature = "82x")]
523impl_reset_control!(UARTFRG, uartfrg_rst_n);
524impl_reset_control!(pac::USART0, uart0_rst_n);
525impl_reset_control!(pac::USART1, uart1_rst_n);
526impl_reset_control!(pac::USART2, uart2_rst_n);
527#[cfg(feature = "845")]
528impl_reset_control!(pac::USART3, uart3_rst_n);
529#[cfg(feature = "845")]
530impl_reset_control!(pac::USART4, uart4_rst_n);
531impl_reset_control!(pac::I2C0, i2c0_rst_n);
532impl_reset_control!(pac::MRT0, mrt_rst_n);
533impl_reset_control!(pac::SCT0, sct_rst_n);
534impl_reset_control!(pac::WKT, wkt_rst_n);
535#[cfg(feature = "845")]
536impl_reset_control!(pac::CTIMER0, ctimer_rst_n);
537#[cfg(feature = "82x")]
538impl_reset_control!(pac::GPIO, gpio_rst_n);
539impl_reset_control!(pac::FLASH_CTRL, flash_rst_n);
540impl_reset_control!(pac::ACOMP, acmp_rst_n);
541impl_reset_control!(pac::I2C1, i2c1_rst_n);
542impl_reset_control!(pac::I2C2, i2c2_rst_n);
543impl_reset_control!(pac::I2C3, i2c3_rst_n);
544impl_reset_control!(pac::ADC0, adc_rst_n);
545impl_reset_control!(pac::DMA0, dma_rst_n);
546#[cfg(feature = "845")]
547impl_reset_control!(pac::PINT, gpioint_rst_n);
548
549#[cfg(feature = "845")]
550impl<'a> ResetControl for pac::GPIO {
551    fn assert_reset<'w>(
552        &self,
553        w: &'w mut presetctrl0::W,
554    ) -> &'w mut presetctrl0::W {
555        w.gpio0_rst_n().clear_bit();
556        w.gpio1_rst_n().clear_bit()
557    }
558
559    fn clear_reset<'w>(
560        &self,
561        w: &'w mut presetctrl0::W,
562    ) -> &'w mut presetctrl0::W {
563        w.gpio0_rst_n().set_bit();
564        w.gpio1_rst_n().set_bit()
565    }
566}
567
568/// Internal trait for powering analog blocks
569///
570/// This trait is an internal implementation detail and should neither be
571/// implemented nor used outside of LPC8xx HAL. Any changes to this trait won't
572/// be considered breaking changes.
573///
574/// Please refer to [`syscon::Handle::power_up`] and
575/// [`syscon::Handle::power_down`] for the public API that uses this trait.
576///
577/// [`syscon::Handle::power_up`]: struct.Handle.html#method.power_up
578/// [`syscon::Handle::power_down`]: struct.Handle.html#method.power_down
579pub trait AnalogBlock {
580    /// Internal method to power up an analog block
581    fn power_up<'w>(&self, w: &'w mut pdruncfg::W) -> &'w mut pdruncfg::W;
582
583    /// Internal method to power down an analog block
584    fn power_down<'w>(&self, w: &'w mut pdruncfg::W) -> &'w mut pdruncfg::W;
585}
586
587macro_rules! impl_analog_block {
588    ($analog_block:ty, $field:ident) => {
589        impl<'a> AnalogBlock for $analog_block {
590            fn power_up<'w>(
591                &self,
592                w: &'w mut pdruncfg::W,
593            ) -> &'w mut pdruncfg::W {
594                w.$field().clear_bit()
595            }
596
597            fn power_down<'w>(
598                &self,
599                w: &'w mut pdruncfg::W,
600            ) -> &'w mut pdruncfg::W {
601                w.$field().set_bit()
602            }
603        }
604    };
605}
606
607#[cfg(feature = "82x")]
608impl_analog_block!(IOSCOUT, ircout_pd);
609#[cfg(feature = "82x")]
610impl_analog_block!(IOSC, irc_pd);
611#[cfg(feature = "845")]
612impl_analog_block!(IOSCOUT, froout_pd);
613#[cfg(feature = "845")]
614impl_analog_block!(IOSC, fro_pd);
615impl_analog_block!(FLASH, flash_pd);
616impl_analog_block!(BOD, bod_pd);
617impl_analog_block!(pac::ADC0, adc_pd);
618impl_analog_block!(SYSOSC, sysosc_pd);
619impl_analog_block!(pac::WWDT, wdtosc_pd);
620impl_analog_block!(SYSPLL, syspll_pd);
621impl_analog_block!(pac::ACOMP, acmp);
622
623/// The 750 kHz IRC/FRO-derived clock
624///
625/// This is one of the clocks that can be used to run the self-wake-up timer
626/// (WKT). See user manual, section 18.5.1.
627#[derive(Debug)]
628pub struct IoscDerivedClock<State = init_state::Enabled> {
629    _state: State,
630}
631
632impl IoscDerivedClock<init_state::Enabled> {
633    pub(crate) fn new() -> Self {
634        Self {
635            _state: init_state::Enabled(()),
636        }
637    }
638}
639
640impl IoscDerivedClock<init_state::Disabled> {
641    /// Enable the IRC/FRO-derived clock
642    ///
643    /// This method is only available, if `IoscDerivedClock` is in the
644    /// [`Disabled`] state. Code that attempts to call this method when the
645    /// clock is already enabled will not compile.
646    ///
647    /// Consumes this instance of `IoscDerivedClock` and returns another instance
648    /// that has its `State` type parameter set to [`Enabled`]. That new
649    /// instance implements [`clock::Enabled`], which might be required by APIs
650    /// that need an enabled clock.
651    ///
652    /// Also consumes the handles to [`IOSC`] and [`IOSCOUT`], to make it
653    /// impossible (outside of unsafe code) to break API guarantees.
654    ///
655    /// [`Disabled`]: ../init_state/struct.Disabled.html
656    /// [`Enabled`]: ../init_state/struct.Enabled.html
657    /// [`clock::Enabled`]: ../clock/trait.Enabled.html
658    pub fn enable(
659        self,
660        syscon: &mut Handle,
661        iosc: IOSC,
662        ioscout: IOSCOUT,
663    ) -> IoscDerivedClock<init_state::Enabled> {
664        syscon.power_up(&iosc);
665        syscon.power_up(&ioscout);
666
667        IoscDerivedClock {
668            _state: init_state::Enabled(()),
669        }
670    }
671}
672
673impl<State> clock::Frequency for IoscDerivedClock<State> {
674    fn hz(&self) -> u32 {
675        750_000
676    }
677}
678
679impl clock::Enabled for IoscDerivedClock<init_state::Enabled> {}
680
681/// Internal trait used to configure interrupt wake-up
682///
683/// This trait is an internal implementation detail and should neither be
684/// implemented nor used outside of LPC8xx HAL. Any changes to this trait won't
685/// be considered breaking changes.
686///
687/// Please refer to [`syscon::Handle::enable_interrupt_wakeup`] and
688/// [`syscon::Handle::disable_interrupt_wakeup`] for the public API that uses
689/// this trait.
690///
691/// [`syscon::Handle::enable_interrupt_wakeup`]: struct.Handle.html#method.enable_interrupt_wakeup
692/// [`syscon::Handle::disable_interrupt_wakeup`]: struct.Handle.html#method.disable_interrupt_wakeup
693pub trait WakeUpInterrupt {
694    /// Internal method to configure interrupt wakeup behavior
695    fn enable(w: &mut starterp1::W) -> &mut starterp1::W;
696
697    /// Internal method to configure interrupt wakeup behavior
698    fn disable(w: &mut starterp1::W) -> &mut starterp1::W;
699}
700
701macro_rules! wakeup_interrupt {
702    ($name:ident, $field:ident) => {
703        /// Can be used to enable/disable interrupt wake-up behavior
704        ///
705        /// See [`syscon::Handle::enable_interrupt_wakeup`] and
706        /// [`syscon::Handle::disable_interrupt_wakeup`].
707        ///
708        /// [`syscon::Handle::enable_interrupt_wakeup`]: struct.Handle.html#method.enable_interrupt_wakeup
709        /// [`syscon::Handle::disable_interrupt_wakeup`]: struct.Handle.html#method.disable_interrupt_wakeup
710        pub struct $name;
711
712        impl WakeUpInterrupt for $name {
713            fn enable(w: &mut starterp1::W) -> &mut starterp1::W {
714                w.$field().enabled()
715            }
716
717            fn disable(w: &mut starterp1::W) -> &mut starterp1::W {
718                w.$field().disabled()
719            }
720        }
721    };
722}
723
724wakeup_interrupt!(Spi0Wakeup, spi0);
725wakeup_interrupt!(Spi1Wakeup, spi1);
726wakeup_interrupt!(Usart0Wakeup, usart0);
727wakeup_interrupt!(Usart1Wakeup, usart1);
728wakeup_interrupt!(Usart2Wakeup, usart2);
729wakeup_interrupt!(I2c1Wakeup, i2c1);
730wakeup_interrupt!(I2c0Wakeup, i2c0);
731wakeup_interrupt!(WwdtWakeup, wwdt);
732wakeup_interrupt!(BodWakeup, bod);
733wakeup_interrupt!(WktWakeup, wkt);
734wakeup_interrupt!(I2c2Wakeup, i2c2);
735wakeup_interrupt!(I2c3Wakeup, i2c3);
736
737reg!(PDRUNCFG, PDRUNCFG, pac::SYSCON, pdruncfg);
738#[cfg(feature = "82x")]
739reg!(PRESETCTRL0, PRESETCTRL0, pac::SYSCON, presetctrl);
740#[cfg(feature = "845")]
741reg!(PRESETCTRL0, PRESETCTRL0, pac::SYSCON, presetctrl0);
742reg!(STARTERP1, STARTERP1, pac::SYSCON, starterp1);
743#[cfg(feature = "82x")]
744reg!(SYSAHBCLKCTRL0, SYSAHBCLKCTRL0, pac::SYSCON, sysahbclkctrl);
745#[cfg(feature = "845")]
746reg!(SYSAHBCLKCTRL0, SYSAHBCLKCTRL0, pac::SYSCON, sysahbclkctrl0);
747#[cfg(feature = "845")]
748reg!(FCLKSEL, [FCLKSEL; 11], pac::SYSCON, fclksel);
749
750#[cfg(feature = "82x")]
751reg!(UARTCLKDIV, UARTCLKDIV, pac::SYSCON, uartclkdiv);
752#[cfg(feature = "82x")]
753reg!(UARTFRGDIV, UARTFRGDIV, pac::SYSCON, uartfrgdiv);
754#[cfg(feature = "82x")]
755reg!(UARTFRGMULT, UARTFRGMULT, pac::SYSCON, uartfrgmult);