update docs #7
@ -35,4 +35,5 @@ features = ["critical-section"]
|
|||||||
[features]
|
[features]
|
||||||
default = ["rt", "revb"]
|
default = ["rt", "revb"]
|
||||||
rt = ["va416xx/rt"]
|
rt = ["va416xx/rt"]
|
||||||
|
defmt = ["dep:defmt", "fugit/defmt"]
|
||||||
revb = []
|
revb = []
|
||||||
|
@ -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::pac;
|
||||||
|
|
||||||
use crate::time::Hertz;
|
use crate::time::Hertz;
|
||||||
@ -444,7 +455,9 @@ impl ClkgenCfgr {
|
|||||||
|
|
||||||
/// Frozen clock frequencies
|
/// 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)]
|
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
|
||||||
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
|
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
|
||||||
pub struct Clocks {
|
pub struct Clocks {
|
||||||
|
@ -3,10 +3,10 @@
|
|||||||
//! The implementation of this GPIO module is heavily based on the
|
//! 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).
|
//! [ATSAMD HAL implementation](https://docs.rs/atsamd-hal/latest/atsamd_hal/gpio/index.html).
|
||||||
//!
|
//!
|
||||||
//! This API provides two different submodules, [`mod@pins`] and [`dynpins`],
|
//! This API provides two different submodules, [pin] and [dynpin],
|
||||||
//! representing two different ways to handle GPIO pins. The default, [`mod@pins`],
|
//! 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
|
//! 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.
|
//! state of each pin at run-time.
|
||||||
//!
|
//!
|
||||||
//! The type-level API is strongly preferred. By representing the state of each
|
//! 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
|
//! compile-time. Furthermore, the type-level API has absolutely zero run-time
|
||||||
//! cost.
|
//! 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,
|
//! between pins. However, by doing so, pins must now be tracked at run-time,
|
||||||
//! and each pin has a non-zero memory footprint.
|
//! and each pin has a non-zero memory footprint.
|
||||||
//!
|
//!
|
||||||
//! ## Examples
|
//! ## 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)]
|
#[derive(Debug, PartialEq, Eq)]
|
||||||
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
|
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
|
||||||
|
@ -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<I, M>
|
||||||
|
//! 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::<FloatingInput>();
|
||||||
|
//! // Specify the target type and use `From`/`Into`
|
||||||
|
//! let pa0: Pin<PA0, FloatingInput> = 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};
|
use core::{convert::Infallible, marker::PhantomData, mem::transmute};
|
||||||
|
|
||||||
pub use crate::clock::FilterClkSel;
|
pub use crate::clock::FilterClkSel;
|
||||||
@ -38,9 +110,9 @@ pub enum PinState {
|
|||||||
|
|
||||||
/// Type-level enum for input configurations
|
/// 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 {
|
pub trait InputConfig: Sealed {
|
||||||
/// Corresponding [`DynInput`](super::DynInput)
|
/// Corresponding [DynInput]
|
||||||
const DYN: DynInput;
|
const DYN: DynInput;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -62,17 +134,17 @@ impl Sealed for Floating {}
|
|||||||
impl Sealed for PullDown {}
|
impl Sealed for PullDown {}
|
||||||
impl Sealed for PullUp {}
|
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<Floating>;
|
pub type InputFloating = Input<Floating>;
|
||||||
/// Type-level variant of [`PinMode`] for pull-down input mode
|
/// Type-level variant of [PinMode] for pull-down input mode
|
||||||
pub type InputPullDown = Input<PullDown>;
|
pub type InputPullDown = Input<PullDown>;
|
||||||
/// Type-level variant of [`PinMode`] for pull-up input mode
|
/// Type-level variant of [PinMode] for pull-up input mode
|
||||||
pub type InputPullUp = Input<PullUp>;
|
pub type InputPullUp = Input<PullUp>;
|
||||||
|
|
||||||
/// 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
|
/// Type `C` is one of three input configurations: [Floating], [PullDown] or
|
||||||
/// [`PullUp`]
|
/// [PullUp]
|
||||||
pub struct Input<C: InputConfig> {
|
pub struct Input<C: InputConfig> {
|
||||||
cfg: PhantomData<C>,
|
cfg: PhantomData<C>,
|
||||||
}
|
}
|
||||||
@ -196,9 +268,9 @@ pub type Reset = InputFloating;
|
|||||||
|
|
||||||
/// Type-level enum representing pin modes
|
/// 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 {
|
pub trait PinMode: Sealed {
|
||||||
/// Corresponding [`DynPinMode`](super::DynPinMode)
|
/// Corresponding [DynPinMode]
|
||||||
const DYN: DynPinMode;
|
const DYN: DynPinMode;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -218,7 +290,7 @@ impl<C: AlternateConfig> PinMode for Alternate<C> {
|
|||||||
|
|
||||||
/// Type-level enum for pin IDs
|
/// Type-level enum for pin IDs
|
||||||
pub trait PinId: Sealed {
|
pub trait PinId: Sealed {
|
||||||
/// Corresponding [`DynPinId`](super::DynPinId)
|
/// Corresponding [DynPinId]
|
||||||
const DYN: DynPinId;
|
const DYN: DynPinId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -786,8 +786,7 @@ impl<Tim: ValidTim> DelayMs<Tim> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// This assumes that the user has already set up a MS tick timer in TIM0 as a system tick
|
/// This assumes that the user has already set up a MS tick timer with [set_up_ms_tick]
|
||||||
/// with [`set_up_ms_delay_provider`]
|
|
||||||
impl embedded_hal::delay::DelayNs for DelayMs {
|
impl embedded_hal::delay::DelayNs for DelayMs {
|
||||||
fn delay_ns(&mut self, ns: u32) {
|
fn delay_ns(&mut self, ns: u32) {
|
||||||
let ns_as_ms = ns / 1_000_000;
|
let ns_as_ms = ns / 1_000_000;
|
||||||
|
@ -282,7 +282,7 @@ enum IrqReceptionMode {
|
|||||||
// UART implementation
|
// 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> {
|
pub struct UartBase<Uart> {
|
||||||
uart: Uart,
|
uart: Uart,
|
||||||
tx: Tx<Uart>,
|
tx: Tx<Uart>,
|
||||||
@ -615,6 +615,14 @@ impl<UartInstance: Instance, Pins> Uart<UartInstance, Pins> {
|
|||||||
(base, self.pins)
|
(base, self.pins)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn downgrade(self) -> UartBase<UartInstance> {
|
||||||
|
UartBase {
|
||||||
|
uart: self.inner.uart,
|
||||||
|
tx: self.inner.tx,
|
||||||
|
rx: self.inner.rx,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn release(self) -> (UartInstance, Pins) {
|
pub fn release(self) -> (UartInstance, Pins) {
|
||||||
(self.inner.release(), self.pins)
|
(self.inner.release(), self.pins)
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user