Skip to content

Commit 8b89a3b

Browse files
committed
Documentation warnings for SAMD21G
1 parent 399c15c commit 8b89a3b

File tree

10 files changed

+186
-158
lines changed

10 files changed

+186
-158
lines changed

hal/src/clock/v2.rs

Lines changed: 39 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@
6565
//! In general, there are two classes of clock in ATSAMD chips. Some clocks map
6666
//! one-to-one (1:1) to a specific bus or peripheral. This is true for the AHB
6767
//! clocks ([`AhbClk`]s), APB clocks ([`ApbClk`]s), GCLK outputs ([`GclkOut`]s),
68-
//! peripheral channel clocks ([`Pclk`]s), and RTC oscillator ([`RtcOsc`]).
68+
//! peripheral channel clocks ([`Pclk`]s), and RTC oscillator (`RtcOsc`).
6969
//! Other clocks form one-to-many (1:N) relationships, like the external crystal
7070
//! oscillator ([`Xosc`]), the 48 MHz DFLL ([`Dfll`]) or the two DPLLs
7171
//! ([`Dpll`]).
@@ -115,9 +115,9 @@
115115
//! on the movement of `Producer` objects.
116116
//!
117117
//! Instead, the `clock` module takes a different approach. It uses type-level
118-
//! programming to track, at compile-time, the number of consumer clocks, N,
119-
//! fed by a particular producer clock. With this approach, we can move
120-
//! `Producer` objects while still making them impossible to modify if N > 0.
118+
//! programming to track, at compile-time, the number of consumer clocks, N, fed
119+
//! by a particular producer clock. With this approach, we can move `Producer`
120+
//! objects while still making them impossible to modify if N > 0.
121121
//!
122122
//! The following sections will describe the implementation of this strategy.
123123
//!
@@ -175,9 +175,9 @@
175175
//! can only `Decrement` the same producer it `Increment`ed. Stated differently,
176176
//! we need a way to track the identity of each consumer's clock source.
177177
//!
178-
//! The [`Source`] trait is designed for this purpose. It marks
179-
//! [`Enabled<T, N>`] producer clocks, and it's associated type, [`Id`], is the
180-
//! identity type that should be stored by consumers.
178+
//! The [`Source`] trait is designed for this purpose. It marks [`Enabled<T,
179+
//! N>`] producer clocks, and it's associated type, [`Id`], is the identity type
180+
//! that should be stored by consumers.
181181
//!
182182
//! Given that all implementers of `Source` are instances of `Enabled<T, N>`,
183183
//! the naïve choice for [`Source::Id`] would be `T`. However, in a moment, we
@@ -194,8 +194,8 @@
194194
//!
195195
//! While these type parameters are important and necessary for configuration of
196196
//! a given producer clock, they are not relevant to consumer clocks. A consumer
197-
//! clock does not need to know or care which `Mode` the XOSC is using, but
198-
//! it *does* need to track that its clock [`Source`] is XOSC0.
197+
//! clock does not need to know or care which `Mode` the XOSC is using, but it
198+
//! *does* need to track that its clock [`Source`] is XOSC0.
199199
//!
200200
//! From this, we can see that `Enabled<Xosc0<M>, N>` should not implement
201201
//! `Source` with `Source::Id = Xosc0<M>`, because that would require consumers
@@ -219,13 +219,13 @@
219219
//! corresponding clock. Moreover, they also fundamentally restructure the way
220220
//! registers are accessed relative to the [PAC].
221221
//!
222-
//! Each of the four PAC clocking structs ([`OSCCTRL`], [`OSC32KCTRL`], [`GCLK`]
223-
//! and [`MCLK`]) is a singleton object that controls a set of MMIO registers.
224-
//! It is impossible to create two instances of any PAC object without `unsafe`.
225-
//! However, each object controls a large set of registers that can be further
226-
//! sub-divided into smaller sets for individual clocks. For example, the
227-
//! [`GCLK`] object controls registers for 12 different clock generators and 48
228-
//! peripheral channel clocks.
222+
//! Each of the PAC clocking structs (which vary between targets, including
223+
//! `OSCCTRL`, `SYSCTRL`, `OSC32KCTRL`, [`GCLK`] and `MCLK`) is a singleton object
224+
//! that controls a set of MMIO registers. It is impossible to create two
225+
//! instances of any PAC object without `unsafe`. However, each object controls
226+
//! a large set of registers that can be further sub-divided into smaller sets
227+
//! for individual clocks. For example, the [`GCLK`] object controls registers
228+
//! for 12 different clock generators and 48 peripheral channel clocks.
229229
//!
230230
//! `Token` types serve to break up the large PAC objects into smaller,
231231
//! more-targetted pieces. And in the process, they also remove the PAC objects'
@@ -238,8 +238,8 @@
238238
//! Bus clocks are fundamentally different from the other clock types in this
239239
//! module, because they do not use mutually exclusive registers for
240240
//! configuration. For instance, the registers that control [`Dpll0`] are
241-
//! mutually exclusive to those that control [`Dpll1`], but `ApbClk<Sercom0>`
242-
//! and `ApbClk<Sercom1>` share a single register.
241+
//! mutually exclusive to those that control `Dpll1`, but `ApbClk<Sercom0>` and
242+
//! `ApbClk<Sercom1>` share a single register.
243243
//!
244244
//! This presents a challenge for memory safety, because we need some way to
245245
//! guarantee that there are no data races. For example, if both
@@ -403,24 +403,24 @@
403403
//!
404404
//! Next, we want to use a DPLL to multiply the 8 MHz crystal clock up to 100
405405
//! MHz. Once again, we need to decide between two instances of a clock, because
406-
//! each chip has two [`Dpll`]s. This time, however, our decision between
407-
//! [`Dpll0`] and [`Dpll1`] is arbitrary.
406+
//! this chip has two [`Dpll`]s. This time, however, our decision between
407+
//! [`Dpll0`] and `Dpll1` is arbitrary.
408408
//!
409409
//! Also note that, like before, `Dpll0<I>` and `Dpll1<I>` are aliases for
410-
//! `Dpll<Dpll0Id, I>` and `Dpll<Dpll1Id, I>`. [`Dpll0Id`] and [`Dpll1Id`]
410+
//! `Dpll<Dpll0Id, I>` and `Dpll<Dpll1Id, I>`. [`Dpll0Id`] and `Dpll1Id`
411411
//! represent the *identity* of the respective DPLL, while `I` represents the
412412
//! [`Id` type](self#id-types) for the [`Source`] driving the DPLL. In this
413413
//! particular case, we aim to create an instance of `Dpll0<Xosc0Id>`.
414414
//!
415415
//! Only certain clocks can drive the DPLL, so `I` is constrained by the
416-
//! [`DpllSourceId`] trait. Specifically, only the [`Xosc0Id`], [`Xosc1Id`],
417-
//! [`Xosc32kId`] and [`GclkId`] types implement this trait.
416+
//! [`DpllSourceId`] trait. Specifically, only the [`Xosc0Id`], `Xosc1Id` (only
417+
//! some targets), [`Xosc32kId`] and [`GclkId`] types implement this trait.
418418
//!
419419
//! As before, we access the [`Tokens`] struct and use the corresponding
420420
//! [`DpllToken`] when creating an instance of `Dpll`. However, unlike before,
421421
//! we are creating a new clock-tree relationship that must be tracked by the
422-
//! type system. Because DPLL0 will now consume XOSC0, we must [`Increment`]
423-
//! the [`Enabled`] counter for [`EnabledXosc0`].
422+
//! type system. Because DPLL0 will now consume XOSC0, we must [`Increment`] the
423+
//! [`Enabled`] counter for [`EnabledXosc0`].
424424
//!
425425
//! Thus, to create an instance of `Dpll0<XoscId0>`, we must provide the
426426
//! `EnabledXosc0`, so that its `U0` type parameter can be incremented to `U1`.
@@ -461,11 +461,11 @@
461461
//! # ).enable();
462462
//! let (dpll0, xosc0) = Dpll::from_xosc(tokens.dpll0, xosc0);
463463
//! ```
464-
//! Next, we set the DPLL pre-divider and loop divider. We must pre-divide
465-
//! the XOSC clock down from 8 MHz to 2 MHz, so that it is within the valid
466-
//! input frequency range for the DPLL. Then, we set the DPLL loop divider, so
467-
//! that it will multiply the 2 MHz clock by 50 for a 100 MHz output. We do not
468-
//! need fractional mutiplication here, so the fractional loop divider is zero.
464+
//! Next, we set the DPLL pre-divider and loop divider. We must pre-divide the
465+
//! XOSC clock down from 8 MHz to 2 MHz, so that it is within the valid input
466+
//! frequency range for the DPLL. Then, we set the DPLL loop divider, so that it
467+
//! will multiply the 2 MHz clock by 50 for a 100 MHz output. We do not need
468+
//! fractional mutiplication here, so the fractional loop divider is zero.
469469
//! Finally, we can enable the `Dpll`, yielding an instance of
470470
//! `EnabledDpll0<XoscId0>`.
471471
//!
@@ -515,11 +515,11 @@
515515
//! [`EnabledGclk0`] to change the base clock without disabling GCLK0 or the
516516
//! main clock.
517517
//!
518-
//! This time we will be modifying two [`Enabled`] counters simultaneously.
519-
//! We will [`Decrement`] the [`EnabledDfll`] count from `U1` to `U0`, and
520-
//! we will [`Increment`] the [`EnabledDpll0`] count from `U0` to `U1`.
521-
//! Again, we need to provide both the DFLL and DPLL clocks, so that their
522-
//! type parameters can be changed.
518+
//! This time we will be modifying two [`Enabled`] counters simultaneously. We
519+
//! will [`Decrement`] the [`EnabledDfll`] count from `U1` to `U0`, and we will
520+
//! [`Increment`] the [`EnabledDpll0`] count from `U0` to `U1`. Again, we need
521+
//! to provide both the DFLL and DPLL clocks, so that their type parameters can
522+
//! be changed.
523523
//!
524524
//! ```no_run
525525
//! # use atsamd_hal::{
@@ -597,8 +597,8 @@
597597
//! ```
598598
//!
599599
//! We have the clocks set up, but we're not using them for anything other than
600-
//! the main clock. Our final steps will create SERCOM APB and peripheral
601-
//! clocks and will output the raw GCLK0 to a GPIO pin.
600+
//! the main clock. Our final steps will create SERCOM APB and peripheral clocks
601+
//! and will output the raw GCLK0 to a GPIO pin.
602602
//!
603603
//! To enable the APB clock for SERCOM0, we must access the [`Apb`] bus struct.
604604
//! We provide an [`ApbToken`] to the [`Apb::enable`] method and receive an
@@ -768,10 +768,7 @@
768768
//! ```
769769
//!
770770
//! [PAC]: crate::pac
771-
//! [`OSCCTRL`]: crate::pac::Oscctrl
772-
//! [`OSC32KCTRL`]: crate::pac::Osc32kctrl
773771
//! [`GCLK`]: crate::pac::Gclk
774-
//! [`MCLK`]: crate::pac::Mclk
775772
//! [`Peripherals::steal`]: crate::pac::Peripherals::steal
776773
//!
777774
//! [`Ahb`]: ahb::Ahb
@@ -795,9 +792,7 @@
795792
//! [`Dpll`]: dpll::Dpll
796793
//! [`Dpll<D, I>`]: dpll::Dpll
797794
//! [`Dpll0`]: dpll::Dpll0
798-
//! [`Dpll1`]: dpll::Dpll1
799795
//! [`Dpll0Id`]: dpll::Dpll0Id
800-
//! [`Dpll1Id`]: dpll::Dpll1Id
801796
//! [`DpllSourceId`]: dpll::DpllSourceId
802797
//! [`DpllToken`]: dpll::DpllToken
803798
//! [`EnabledDpll0`]: dpll::EnabledDpll0
@@ -819,15 +814,12 @@
819814
//! [`PclkSourceId`]: pclk::PclkSourceId
820815
//! [`PclkToken`]: pclk::PclkToken
821816
//!
822-
//! [`RtcOsc`]: rtcosc::RtcOsc
823-
//!
824817
//! [`Xosc`]: xosc::Xosc
825818
//! [`Xosc::from_crystal`]: xosc::Xosc::from_crystal
826819
//! [`Xosc::enable`]: xosc::Xosc::enable
827820
//! [`Xosc0`]: xosc::Xosc0
828821
//! [`Xosc0<M>`]: xosc::Xosc0
829822
//! [`Xosc0Id`]: xosc::Xosc0Id
830-
//! [`Xosc1Id`]: xosc::Xosc1Id
831823
//! [`XoscToken`]: xosc::XoscToken
832824
//! [`EnabledXosc0`]: xosc::EnabledXosc0
833825
//! [`EnabledXosc0<M, N>`]: xosc::EnabledXosc0
@@ -850,7 +842,8 @@
850842
//! [`Sub1`]: typenum::Sub1
851843
//! [`Unsigned`]: typenum::Unsigned
852844
//!
853-
//! [interior mutability]: https://doc.rust-lang.org/reference/interior-mutability.html
845+
//! [interior mutability]:
846+
//! https://doc.rust-lang.org/reference/interior-mutability.html
854847
855848
#![allow(clippy::manual_range_contains)]
856849

hal/src/clock/v2/dpll.rs

Lines changed: 11 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -464,15 +464,14 @@ pub enum DynDpllId {
464464
// DpllId
465465
//==============================================================================
466466

467-
/// Type-level enum identifying one of two possible [`Dpll`]s
467+
/// Type-level enum identifying a [`Dpll`]
468468
///
469-
/// The types implementing this trait, i.e. [`Dpll0Id`] and [`Dpll1Id`], are
470-
/// type-level variants of `DpllId`, and they identify one of the two possible
471-
/// digital phase-locked loops.
469+
/// The types implementing this trait, i.e. [`Dpll0Id`] (and `Dpll1Id`, on
470+
/// targets with two DPLLs), identify a specific digital phase-locked loop.
472471
///
473472
/// `DpllId` is the type-level equivalent of [`DynDpllId`]. See the
474-
/// documentation on [type-level programming] and specifically
475-
/// [type-level enums] for more details.
473+
/// documentation on [type-level programming] and specifically [type-level
474+
/// enums] for more details.
476475
///
477476
/// [type-level programming]: crate::typelevel
478477
/// [type-level enums]: crate::typelevel#type-level-enums
@@ -778,12 +777,12 @@ mod settings {
778777
/// A DPLL is used to multiply clock frequencies, taking a lower-frequency input
779778
/// clock and producing a higher-frequency output clock.
780779
///
781-
/// The type parameter `D` is a [`DpllId`] that determines which of the two
782-
/// instances this `Dpll` represents ([`Dpll0`] or [`Dpll1`]). The type
783-
/// parameter `I` represents the `Id` type for the clock [`Source`] driving this
784-
/// `Dpll`. It must be one of the valid [`DpllSourceId`]s. See the
785-
/// [`clock` module documentation](super) for more detail on
786-
/// [`Id` types](super#id-types).
780+
/// The type parameter `D` is a [`DpllId`] that determines which of the one or
781+
/// two (depending on the target) instances this `Dpll` represents ([`Dpll0`] or
782+
/// `Dpll1`). The type parameter `I` represents the `Id` type for the clock
783+
/// [`Source`] driving this `Dpll`. It must be one of the valid
784+
/// [`DpllSourceId`]s. See the [`clock` module documentation](super) for more
785+
/// detail on [`Id` types](super#id-types).
787786
///
788787
/// On its own, an instance of `Dpll` does not represent an enabled DPLL.
789788
/// Instead, it must first be wrapped with [`Enabled`], which implements

hal/src/clock/v2/gclk.rs

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -83,10 +83,10 @@
8383
//!
8484
//! At this point, notice that [`Gclk<G, I>`] takes two type parameters. `G` is
8585
//! a [`GclkId`] identifying which of the 12 generators this `Gclk` represents.
86-
//! [`Gclk1<I>`] is simply an alias for `Gclk<Gclk1Id, I>`. `I` is an
87-
//! [`Id` type](super#id-types) identifying the input clock, which must be a
88-
//! valid [`GclkSourceId`]. In this case, `I` is [`PB14`](gpio::PB14), which is
89-
//! a `GclkSourceId` for `Gclk1`, because it implements [`GclkIo`] with
86+
//! [`Gclk1<I>`] is simply an alias for `Gclk<Gclk1Id, I>`. `I` is an [`Id`
87+
//! type](super#id-types) identifying the input clock, which must be a valid
88+
//! [`GclkSourceId`]. In this case, `I` is `PB14`, which is a `GclkSourceId` for
89+
//! `Gclk1` on this target, because it implements [`GclkIo`] with
9090
//! [`GclkIo::GclkId`]` = Gclk1Id`.
9191
//!
9292
//! ```no_run
@@ -488,15 +488,15 @@ pub enum DynGclkId {
488488
// GclkId
489489
//==============================================================================
490490

491-
/// Type-level enum identifying one of 12 possible [`Gclk`]s
491+
/// Type-level enum identifying one of possible [`Gclk`]s
492492
///
493-
/// The types implementing this trait, i.e. [`Gclk0Id`] - [`Gclk11Id`], are
494-
/// type-level variants of `GclkId`, and they identify one of the 12 possible
493+
/// The types implementing this trait, i.e. [`Gclk0Id`] - `Gclk11Id`, are
494+
/// type-level variants of `GclkId`, and they identify one of the possible
495495
/// generic clock generators.
496496
///
497497
/// `GclkId` is the type-level equivalent of [`DynGclkId`]. See the
498-
/// documentation on [type-level programming] and specifically
499-
/// [type-level enums] for more details.
498+
/// documentation on [type-level programming] and specifically [type-level
499+
/// enums] for more details.
500500
///
501501
/// [type-level programming]: crate::typelevel
502502
/// [type-level enums]: crate::typelevel#type-level-enums
@@ -1072,13 +1072,13 @@ impl<G: GclkId> Default for Settings<G> {
10721072
/// a root or branch clock to other branch or leaf clocks. In particular, all
10731073
/// peripheral [`Pclk`]s must be derived from a `Gclk`.
10741074
///
1075-
/// The type parameter `G` is a [`GclkId`] that determines which of the 12
1076-
/// generators this [`Gclk`] represents ([`Gclk0`] - [`Gclk11`]). The type
1077-
/// parameter `I` represents the `Id` type for the clock [`Source`] driving this
1078-
/// `Gclk`. It must be one of the valid [`GclkSourceId`]s. Alternatively, if the
1079-
/// `Gclk` is driven by a [GPIO](gpio) [`Pin`], then `I` is a [`PinId`]
1080-
/// implementing [`GclkIo`]. See the [`clock` module documentation](super) for
1081-
/// more detail on `Id` types.
1075+
/// The type parameter `G` is a [`GclkId`] that determines which of the
1076+
/// generators this [`Gclk`] represents ([`Gclk0`] - `Gclk11` on the largest
1077+
/// targets). The type parameter `I` represents the `Id` type for the clock
1078+
/// [`Source`] driving this `Gclk`. It must be one of the valid
1079+
/// [`GclkSourceId`]s. Alternatively, if the `Gclk` is driven by a [GPIO](gpio)
1080+
/// [`Pin`], then `I` is a [`PinId`] implementing [`GclkIo`]. See the [`clock`
1081+
/// module documentation](super) for more detail on `Id` types.
10821082
///
10831083
/// On its own, an instance of `Gclk` does not represent an enabled clock
10841084
/// generator. Instead, it must first be wrapped with [`Enabled`], which

hal/src/clock/v2/osc32k.rs

Lines changed: 19 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -2,35 +2,27 @@
22
//!
33
//! ## Overview
44
//!
5-
//! TODO this documentation is for the SAMD51 version, not the SYSCTRL sub-peripheral
5+
//! The `osc32k` module provides access to the 32 kHz oscillator (OSC32K),
6+
//! provided by the `SYSCTRL` peripheral. Depending on the target, it has one
7+
//! or two outputs: one at 32 kHz and another divided down to 1 kHz. These
8+
//! outputs can be disabled or enabled independently at any given time.
69
//!
7-
//! The `osc32k` module provides access to the 32 kHz ultra low power
8-
//! internal oscillator (OSC32K) within the `OSC32KCTRL` peripheral.
9-
//!
10-
//! The `OSC32K` clock is unlike most other clocks. First, it is an internal
11-
//! clock that is always enabled and can't be disabled. And second, it has two
12-
//! separate outputs, one at 32 kHz and another divided down to 1 kHz. Moreover,
13-
//! none, either or both of these outputs can be enabled at any given time.
14-
//!
15-
//! We can see, then, that the `OSC32K` peripheral forms its own, miniature
16-
//! clock tree. There is a 1:N producer clock that is always enabled; and there
17-
//! are two possible consumer clocks that can be independently and optionally
18-
//! enabled. In fact, this structure is illustrated by the `OSC32K`
19-
//! register, which has no regular `ENABLE` bit and two different enable bits
20-
//! for clock output, `EN32K` and `EN1K`.
10+
//! We can see, that the `OSC32K` peripheral forms its own, miniature clock
11+
//! tree. There is a 1:N producer clock; and there are one or two possible
12+
//! consumer clocks that can be independently and optionally enabled.
2113
//!
2214
//! To represent this structure in the type system, we divide the `OSC32K`
2315
//! peripheral into these three clocks. Users get access to the 1:N
24-
//! [`EnabledOsc32kBase`] clock [`Source`] at power-on reset, which can be
25-
//! consumed by both the [`Osc32k`] and [`Osc1k`] clocks. Note that
26-
//! `Osc32k` and `Osc1k` are themselves 1:N clocks as well.
16+
//! [`EnabledOsc32kBase`] clock [`Source`], which can be consumed by both the
17+
//! [`Osc32k`] and [`Osc1k`] clocks. Note that `Osc32k` and `Osc1k` are
18+
//! themselves 1:N clocks as well.
2719
//!
2820
//! ## Write lock
2921
//!
30-
//! Rhe `OSC32K` register has a dedicated write lock bit that will freeze its
22+
//! The `OSC32K` register has a dedicated write lock bit that will freeze its
3123
//! configuration until the next power-on reset. We implement this by simply
32-
//! dropping the [`Osc32kBase`] clock, which prevents any further access to
33-
//! the `OSC32K` register.
24+
//! dropping the [`Osc32kBase`] clock, which prevents any further access to the
25+
//! `OSC32K` register.
3426
//!
3527
//! ## Example
3628
//!
@@ -108,8 +100,7 @@
108100
//! ```
109101
//!
110102
//! And finally, we can set the write lock bit to freeze the configuation until
111-
//! the next power-on reset. Doing so also drops the `EnabledOsc32kBase`
112-
//! clock.
103+
//! the next power-on reset. Doing so also drops the `EnabledOsc32kBase` clock.
113104
//!
114105
//! ```no_run
115106
//! # use atsamd_hal::{
@@ -474,6 +465,11 @@ pub struct Osc1k {
474465
token: Osc1kToken,
475466
}
476467

468+
/// OSC1K is not available on the currently-documented target
469+
#[cfg(doc)]
470+
#[hal_cfg(not("sysctrl-d11"))]
471+
pub struct Osc1k {}
472+
477473
/// The [`Enabled`] [`Osc1k`] clock
478474
///
479475
/// As described in the [`clock` module documentation](super), the [`Enabled`]

0 commit comments

Comments
 (0)