From 3e2678c5b91737f713838ccef492b9a3cf9ca4a4 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Tue, 25 Jun 2024 10:45:28 +0200 Subject: [PATCH] update docs --- va416xx-hal/Cargo.toml | 1 + va416xx-hal/src/clock.rs | 17 ++++++- va416xx-hal/src/gpio/mod.rs | 10 ++-- va416xx-hal/src/gpio/pin.rs | 94 ++++++++++++++++++++++++++++++++----- va416xx-hal/src/timer.rs | 3 +- va416xx-hal/src/uart.rs | 10 +++- 6 files changed, 114 insertions(+), 21 deletions(-) diff --git a/va416xx-hal/Cargo.toml b/va416xx-hal/Cargo.toml index 05d99d2..94ff791 100644 --- a/va416xx-hal/Cargo.toml +++ b/va416xx-hal/Cargo.toml @@ -35,4 +35,5 @@ features = ["critical-section"] [features] default = ["rt", "revb"] rt = ["va416xx/rt"] +defmt = ["dep:defmt", "fugit/defmt"] revb = [] diff --git a/va416xx-hal/src/clock.rs b/va416xx-hal/src/clock.rs index adc12eb..81468a2 100644 --- a/va416xx-hal/src/clock.rs +++ b/va416xx-hal/src/clock.rs @@ -1,4 +1,15 @@ -//! This also includes functionality to enable the peripheral clocks +//! API for using the [crate::pac::Clkgen] peripheral. +//! +//! It also includes functionality to enable the peripheral clocks. +//! Calling [ClkgenExt::constrain] on the [crate::pac::Clkgen] peripheral generates the +//! [ClkgenCfgr] structure which can be used to configure and set up the clock. +//! +//! Calling [ClkgenCfgr::freeze] returns the frozen clock configuration inside the [Clocks] +//! structure. This structure can also be used to configure other structures provided by this HAL. +//! +//! # Examples +//! +//! - [UART example on the PEB1 board](https://egit.irs.uni-stuttgart.de/rust/va416xx-rs/src/branch/main/examples/simple/examples/uart.rs) use crate::pac; use crate::time::Hertz; @@ -444,7 +455,9 @@ impl ClkgenCfgr { /// Frozen clock frequencies /// -/// The existence of this value indicates that the clock configuration can no longer be changed +/// The existence of this value indicates that the clock configuration can no longer be changed. +/// The [self] module documentation gives some more information on how to retrieve an instance +/// of this structure. #[derive(Copy, Clone, PartialEq, Eq, Debug)] #[cfg_attr(feature = "defmt", derive(defmt::Format))] pub struct Clocks { diff --git a/va416xx-hal/src/gpio/mod.rs b/va416xx-hal/src/gpio/mod.rs index bfe6aa7..6290bda 100644 --- a/va416xx-hal/src/gpio/mod.rs +++ b/va416xx-hal/src/gpio/mod.rs @@ -3,10 +3,10 @@ //! The implementation of this GPIO module is heavily based on the //! [ATSAMD HAL implementation](https://docs.rs/atsamd-hal/latest/atsamd_hal/gpio/index.html). //! -//! This API provides two different submodules, [`mod@pins`] and [`dynpins`], -//! representing two different ways to handle GPIO pins. The default, [`mod@pins`], +//! This API provides two different submodules, [pin] and [dynpin], +//! representing two different ways to handle GPIO pins. The default, [pin], //! is a type-level API that tracks the state of each pin at compile-time. The -//! alternative, [`dynpins`] is a type-erased, value-level API that tracks the +//! alternative, [dynpin] is a type-erased, value-level API that tracks the //! state of each pin at run-time. //! //! The type-level API is strongly preferred. By representing the state of each @@ -14,13 +14,13 @@ //! compile-time. Furthermore, the type-level API has absolutely zero run-time //! cost. //! -//! If needed, [`dynpins`] can be used to erase the type-level differences +//! If needed, [dynpin] can be used to erase the type-level differences //! between pins. However, by doing so, pins must now be tracked at run-time, //! and each pin has a non-zero memory footprint. //! //! ## Examples //! -//! - [Blinky example](https://egit.irs.uni-stuttgart.de/rust/va108xx-hal/src/branch/main/examples/blinky.rs) +//! - [Blinky example](https://egit.irs.uni-stuttgart.de/rust/va416xx-rs/src/branch/main/examples/simple/examples/blinky.rs) #[derive(Debug, PartialEq, Eq)] #[cfg_attr(feature = "defmt", derive(defmt::Format))] diff --git a/va416xx-hal/src/gpio/pin.rs b/va416xx-hal/src/gpio/pin.rs index feb9b29..863b881 100644 --- a/va416xx-hal/src/gpio/pin.rs +++ b/va416xx-hal/src/gpio/pin.rs @@ -1,3 +1,75 @@ +//! # Type-level module for GPIO pins +//! +//! This documentation is strongly based on the +//! [atsamd documentation](https://docs.rs/atsamd-hal/latest/atsamd_hal/gpio/pin/index.html). +//! +//! This module provides a type-level API for GPIO pins. It uses the type system +//! to track the state of pins at compile-time. Representing GPIO pins in this +//! manner incurs no run-time overhead. Each [`Pin`] struct is zero-sized, so +//! there is no data to copy around. Instead, real code is generated as a side +//! effect of type transformations, and the resulting assembly is nearly +//! identical to the equivalent, hand-written C. +//! +//! To track the state of pins at compile-time, this module uses traits to +//! represent [type classes] and types as instances of those type classes. For +//! example, the trait [`InputConfig`] acts as a [type-level enum] of the +//! available input configurations, and the types [`Floating`], [`PullDown`] and +//! [`PullUp`] are its type-level variants. +//! +//! Type-level [`Pin`]s are parameterized by two type-level enums, [`PinId`] and +//! [`PinMode`]. +//! +//! ``` +//! pub struct Pin +//! where +//! I: PinId, +//! M: PinMode, +//! { +//! // ... +//! } +//! ``` +//! +//! A `PinId` identifies a pin by it's group (A to G) and pin number. Each +//! `PinId` instance is named according to its datasheet identifier, e.g. +//! [PA2]. +//! +//! A `PinMode` represents the various pin modes. The available `PinMode` +//! variants are [`Input`], [`Output`] and [`Alternate`], each with its own +//! corresponding configurations. +//! +//! It is not possible for users to create new instances of a [`Pin`]. Singleton +//! instances of each pin are made available to users through the PinsX +//! struct. +//! +//! Example for the pins of PORT A: +//! +//! To create the [PinsA] struct, users must supply the PAC +//! [Port](crate::pac::Porta) peripheral. The [PinsA] struct takes +//! ownership of the [Porta] and provides the corresponding pins. Each [`Pin`] +//! within the [PinsA] struct can be moved out and used individually. +//! +//! +//! ```no_run +//! let mut peripherals = Peripherals::take().unwrap(); +//! let pinsa = PinsA::new(peripherals.porta); +//! ``` +//! +//! Pins can be converted between modes using several different methods. +//! +//! ```no_run +//! // Use one of the literal function names +//! let pa0 = pinsa.pa0.into_floating_input(); +//! // Use a generic method and one of the `PinMode` variant types +//! let pa0 = pinsa.pa0.into_mode::(); +//! // Specify the target type and use `From`/`Into` +//! let pa0: Pin = pinsa.pa27.into(); +//! ``` +//! +//! # Embedded HAL traits +//! +//! This module implements all of the embedded HAL GPIO traits for each [`Pin`] +//! in the corresponding [`PinMode`]s, namely: [`InputPin`], [`OutputPin`], +//! and [`StatefulOutputPin`]. use core::{convert::Infallible, marker::PhantomData, mem::transmute}; pub use crate::clock::FilterClkSel; @@ -38,9 +110,9 @@ pub enum PinState { /// Type-level enum for input configurations /// -/// The valid options are [`Floating`], [`PullDown`] and [`PullUp`]. +/// The valid options are [Floating], [PullDown] and [PullUp]. pub trait InputConfig: Sealed { - /// Corresponding [`DynInput`](super::DynInput) + /// Corresponding [DynInput] const DYN: DynInput; } @@ -62,17 +134,17 @@ impl Sealed for Floating {} impl Sealed for PullDown {} impl Sealed for PullUp {} -/// Type-level variant of [`PinMode`] for floating input mode +/// Type-level variant of [PinMode] for floating input mode pub type InputFloating = Input; -/// Type-level variant of [`PinMode`] for pull-down input mode +/// Type-level variant of [PinMode] for pull-down input mode pub type InputPullDown = Input; -/// Type-level variant of [`PinMode`] for pull-up input mode +/// Type-level variant of [PinMode] for pull-up input mode pub type InputPullUp = Input; -/// Type-level variant of [`PinMode`] for input modes +/// Type-level variant of [PinMode] for input modes /// -/// Type `C` is one of three input configurations: [`Floating`], [`PullDown`] or -/// [`PullUp`] +/// Type `C` is one of three input configurations: [Floating], [PullDown] or +/// [PullUp] pub struct Input { cfg: PhantomData, } @@ -196,9 +268,9 @@ pub type Reset = InputFloating; /// Type-level enum representing pin modes /// -/// The valid options are [`Input`], [`Output`] and [`Alternate`]. +/// The valid options are [Input], [Output] and [Alternate]. pub trait PinMode: Sealed { - /// Corresponding [`DynPinMode`](super::DynPinMode) + /// Corresponding [DynPinMode] const DYN: DynPinMode; } @@ -218,7 +290,7 @@ impl PinMode for Alternate { /// Type-level enum for pin IDs pub trait PinId: Sealed { - /// Corresponding [`DynPinId`](super::DynPinId) + /// Corresponding [DynPinId] const DYN: DynPinId; } diff --git a/va416xx-hal/src/timer.rs b/va416xx-hal/src/timer.rs index 267317f..e3831b8 100644 --- a/va416xx-hal/src/timer.rs +++ b/va416xx-hal/src/timer.rs @@ -786,8 +786,7 @@ impl DelayMs { } } -/// This assumes that the user has already set up a MS tick timer in TIM0 as a system tick -/// with [`set_up_ms_delay_provider`] +/// This assumes that the user has already set up a MS tick timer with [set_up_ms_tick] impl embedded_hal::delay::DelayNs for DelayMs { fn delay_ns(&mut self, ns: u32) { let ns_as_ms = ns / 1_000_000; diff --git a/va416xx-hal/src/uart.rs b/va416xx-hal/src/uart.rs index 7bd26e4..d9b8cf4 100644 --- a/va416xx-hal/src/uart.rs +++ b/va416xx-hal/src/uart.rs @@ -282,7 +282,7 @@ enum IrqReceptionMode { // UART implementation //================================================================================================== -/// Type erased variant of a UART. Can be created with the [`Uart::downgrade`] function. +/// Type erased variant of a UART. Can be created with the [Uart::downgrade] function. pub struct UartBase { uart: Uart, tx: Tx, @@ -615,6 +615,14 @@ impl Uart { (base, self.pins) } + pub fn downgrade(self) -> UartBase { + UartBase { + uart: self.inner.uart, + tx: self.inner.tx, + rx: self.inner.rx, + } + } + pub fn release(self) -> (UartInstance, Pins) { (self.inner.release(), self.pins) }