Merge branch 'main' into readme-fix
This commit is contained in:
commit
e3996d9166
@ -36,8 +36,7 @@
|
|||||||
//! Users may try to convert value-level pins back to their type-level
|
//! Users may try to convert value-level pins back to their type-level
|
||||||
//! equivalents. However, this option is fallible, because the compiler cannot
|
//! equivalents. However, this option is fallible, because the compiler cannot
|
||||||
//! guarantee the pin has the correct ID or is in the correct mode at
|
//! guarantee the pin has the correct ID or is in the correct mode at
|
||||||
//! compile-time. Use [`TryFrom`](core::convert::TryFrom)/
|
//! compile-time. Use [TryFrom]/[TryInto] for this conversion.
|
||||||
//! [`TryInto`](core::convert::TryInto) for this conversion.
|
|
||||||
//!
|
//!
|
||||||
//! ```
|
//! ```
|
||||||
//! // Convert to a `DynPin`
|
//! // Convert to a `DynPin`
|
||||||
@ -55,7 +54,7 @@
|
|||||||
//! `Error = core::convert::Infallible`, the value-level API can return a real
|
//! `Error = core::convert::Infallible`, the value-level API can return a real
|
||||||
//! error. If the [`DynPin`] is not in the correct [`DynPinMode`] for the
|
//! error. If the [`DynPin`] is not in the correct [`DynPinMode`] for the
|
||||||
//! operation, the trait functions will return
|
//! operation, the trait functions will return
|
||||||
//! [`InvalidPinType`](PinError::InvalidPinType).
|
//! [InvalidPinTypeError].
|
||||||
|
|
||||||
use super::{
|
use super::{
|
||||||
pins::{FilterType, InterruptEdge, InterruptLevel, Pin, PinId, PinMode, PinState},
|
pins::{FilterType, InterruptEdge, InterruptLevel, Pin, PinId, PinMode, PinState},
|
||||||
|
@ -29,72 +29,47 @@
|
|||||||
//! }
|
//! }
|
||||||
//! ```
|
//! ```
|
||||||
//!
|
//!
|
||||||
//! A `PinId` identifies a pin by it's group (A, B, C or D) and pin number. Each
|
//! A [PinId] identifies a pin by it's group (A or B) and pin number. Each
|
||||||
//! `PinId` instance is named according to its datasheet identifier, e.g.
|
//! [PinId] instance is named according to its datasheet identifier, e.g.
|
||||||
//! [`PA02`].
|
//! [PA2].
|
||||||
//!
|
//!
|
||||||
//! A `PinMode` represents the various pin modes. The available `PinMode`
|
//! A [PinMode] represents the various pin modes. The available [PinMode]
|
||||||
//! variants are [`Disabled`], [`Input`], [`Interrupt`], [`Output`] and
|
//! variants are [`Input`], [`Output`] and [`Alternate`], each with its own
|
||||||
//! [`Alternate`], each with its own corresponding configurations.
|
//! corresponding configurations.
|
||||||
//!
|
//!
|
||||||
//! It is not possible for users to create new instances of a [`Pin`]. Singleton
|
//! 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 [`Pins`]
|
//! instances of each pin are made available to users through the PinsX
|
||||||
//! struct.
|
//! struct.
|
||||||
//!
|
//!
|
||||||
//! To create the [`Pins`] struct, users must supply the PAC
|
//! Example for the pins of PORT A:
|
||||||
//! [`PORT`](crate::pac::PORT) peripheral. The [`Pins`] struct takes
|
//!
|
||||||
//! ownership of the [`PORT`] and provides the corresponding pins. Each [`Pin`]
|
//! To create the [PinsA] struct, users must supply the PAC
|
||||||
//! within the [`Pins`] struct can be moved out and used individually.
|
//! [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.
|
||||||
//!
|
//!
|
||||||
//!
|
//!
|
||||||
//! ```
|
//! ```
|
||||||
//! let mut peripherals = Peripherals::take().unwrap();
|
//! let mut peripherals = Peripherals::take().unwrap();
|
||||||
//! let pins = Pins::new(peripherals.PORT);
|
//! let pinsa = PinsA::new(peripherals.PORT);
|
||||||
//! ```
|
//! ```
|
||||||
//!
|
//!
|
||||||
//! Pins can be converted between modes using several different methods.
|
//! Pins can be converted between modes using several different methods.
|
||||||
//!
|
//!
|
||||||
//! ```
|
//! ```no_run
|
||||||
//! // Use one of the literal function names
|
//! // Use one of the literal function names
|
||||||
//! let pa27 = pins.pa27.into_floating_input();
|
//! let pa0 = pinsa.pa0.into_floating_input();
|
||||||
//! // Use a generic method and one of the `PinMode` variant types
|
//! // Use a generic method and one of the `PinMode` variant types
|
||||||
//! let pa27 = pins.pa27.into_mode::<FloatingInput>();
|
//! let pa0 = pinsa.pa0.into_mode::<FloatingInput>();
|
||||||
//! // Specify the target type and use `From`/`Into`
|
//! // Specify the target type and use `From`/`Into`
|
||||||
//! let pa27: Pin<PA27, FloatingInput> = pins.pa27.into();
|
//! let pa0: Pin<PA0, FloatingInput> = pinsa.pa27.into();
|
||||||
//! ```
|
//! ```
|
||||||
//!
|
//!
|
||||||
//! # Embedded HAL traits
|
//! # Embedded HAL traits
|
||||||
//!
|
//!
|
||||||
//! This module implements all of the embedded HAL GPIO traits for each [`Pin`]
|
//! This module implements all of the embedded HAL GPIO traits for each [`Pin`]
|
||||||
//! in the corresponding [`PinMode`]s, namely: [`InputPin`], [`OutputPin`],
|
//! in the corresponding [`PinMode`]s, namely: [`InputPin`], [`OutputPin`],
|
||||||
//! [`ToggleableOutputPin`] and [`StatefulOutputPin`].
|
//! and [`StatefulOutputPin`].
|
||||||
//!
|
|
||||||
//! For example, you can control the logic level of an `OutputPin` like so
|
|
||||||
//!
|
|
||||||
//! ```
|
|
||||||
//! use atsamd_hal::pac::Peripherals;
|
|
||||||
//! use atsamd_hal::gpio::Pins;
|
|
||||||
//! use crate::ehal_02::digital::v2::OutputPin;
|
|
||||||
//!
|
|
||||||
//! let mut peripherals = Peripherals::take().unwrap();
|
|
||||||
//! let mut pins = Pins::new(peripherals.PORT);
|
|
||||||
//! pins.pa27.set_high();
|
|
||||||
//! ```
|
|
||||||
//!
|
|
||||||
//! # Type-level features
|
|
||||||
//!
|
|
||||||
//! This module also provides additional, type-level tools to work with GPIO
|
|
||||||
//! pins.
|
|
||||||
//!
|
|
||||||
//! The [`OptionalPinId`] and [`OptionalPin`] traits use the [`OptionalKind`]
|
|
||||||
//! pattern to act as type-level versions of [`Option`] for `PinId` and `Pin`
|
|
||||||
//! respectively. And the [`AnyPin`] trait defines an [`AnyKind`] type class
|
|
||||||
//! for all `Pin` types.
|
|
||||||
//!
|
|
||||||
//! [type classes]: crate::typelevel#type-classes
|
|
||||||
//! [type-level enum]: crate::typelevel#type-level-enum
|
|
||||||
//! [`OptionalKind`]: crate::typelevel#optionalkind-trait-pattern
|
|
||||||
//! [`AnyKind`]: crate::typelevel#anykind-trait-pattern
|
|
||||||
use super::dynpins::{DynAlternate, DynGroup, DynInput, DynOutput, DynPinId, DynPinMode};
|
use super::dynpins::{DynAlternate, DynGroup, DynInput, DynOutput, DynPinId, DynPinMode};
|
||||||
use super::reg::RegisterInterface;
|
use super::reg::RegisterInterface;
|
||||||
use crate::{
|
use crate::{
|
||||||
@ -137,9 +112,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;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -297,9 +272,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;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -319,7 +294,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;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -344,7 +319,7 @@ macro_rules! pin_id {
|
|||||||
// Pin
|
// Pin
|
||||||
//==================================================================================================
|
//==================================================================================================
|
||||||
|
|
||||||
/// A type-level GPIO pin, parameterized by [`PinId`] and [`PinMode`] types
|
/// A type-level GPIO pin, parameterized by [PinId] and [PinMode] types
|
||||||
|
|
||||||
pub struct Pin<I: PinId, M: PinMode> {
|
pub struct Pin<I: PinId, M: PinMode> {
|
||||||
pub(in crate::gpio) regs: Registers<I>,
|
pub(in crate::gpio) regs: Registers<I>,
|
||||||
@ -352,12 +327,12 @@ pub struct Pin<I: PinId, M: PinMode> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<I: PinId, M: PinMode> Pin<I, M> {
|
impl<I: PinId, M: PinMode> Pin<I, M> {
|
||||||
/// Create a new [`Pin`]
|
/// Create a new [Pin]
|
||||||
///
|
///
|
||||||
/// # Safety
|
/// # Safety
|
||||||
///
|
///
|
||||||
/// Each [`Pin`] must be a singleton. For a given [`PinId`], there must be
|
/// Each [Pin] must be a singleton. For a given [PinId], there must be
|
||||||
/// at most one corresponding [`Pin`] in existence at any given time.
|
/// at most one corresponding [Pin] in existence at any given time.
|
||||||
/// Violating this requirement is `unsafe`.
|
/// Violating this requirement is `unsafe`.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub(crate) unsafe fn new() -> Pin<I, M> {
|
pub(crate) unsafe fn new() -> Pin<I, M> {
|
||||||
|
@ -1,18 +1,19 @@
|
|||||||
use crate::{pac, PeripheralSelect};
|
use crate::{pac, PeripheralSelect};
|
||||||
|
|
||||||
#[derive(PartialEq, Eq, Debug)]
|
#[derive(PartialEq, Eq, Debug)]
|
||||||
pub struct InvalidounterResetVal(pub(crate) ());
|
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
|
||||||
|
pub struct InvalidCounterResetVal(pub(crate) ());
|
||||||
|
|
||||||
/// Enable scrubbing for the ROM
|
/// Enable scrubbing for the ROM
|
||||||
///
|
///
|
||||||
/// Returns [`UtilityError::InvalidCounterResetVal`] if the scrub rate is 0
|
/// Returns [InvalidCounterResetVal] if the scrub rate is 0
|
||||||
/// (equivalent to disabling) or larger than 24 bits
|
/// (equivalent to disabling) or larger than 24 bits
|
||||||
pub fn enable_rom_scrubbing(
|
pub fn enable_rom_scrubbing(
|
||||||
syscfg: &mut pac::Sysconfig,
|
syscfg: &mut pac::Sysconfig,
|
||||||
scrub_rate: u32,
|
scrub_rate: u32,
|
||||||
) -> Result<(), InvalidounterResetVal> {
|
) -> Result<(), InvalidCounterResetVal> {
|
||||||
if scrub_rate == 0 || scrub_rate > u32::pow(2, 24) {
|
if scrub_rate == 0 || scrub_rate > u32::pow(2, 24) {
|
||||||
return Err(InvalidounterResetVal(()));
|
return Err(InvalidCounterResetVal(()));
|
||||||
}
|
}
|
||||||
syscfg.rom_scrub().write(|w| unsafe { w.bits(scrub_rate) });
|
syscfg.rom_scrub().write(|w| unsafe { w.bits(scrub_rate) });
|
||||||
Ok(())
|
Ok(())
|
||||||
@ -24,14 +25,14 @@ pub fn disable_rom_scrubbing(syscfg: &mut pac::Sysconfig) {
|
|||||||
|
|
||||||
/// Enable scrubbing for the RAM
|
/// Enable scrubbing for the RAM
|
||||||
///
|
///
|
||||||
/// Returns [`UtilityError::InvalidCounterResetVal`] if the scrub rate is 0
|
/// Returns [InvalidCounterResetVal] if the scrub rate is 0
|
||||||
/// (equivalent to disabling) or larger than 24 bits
|
/// (equivalent to disabling) or larger than 24 bits
|
||||||
pub fn enable_ram_scrubbing(
|
pub fn enable_ram_scrubbing(
|
||||||
syscfg: &mut pac::Sysconfig,
|
syscfg: &mut pac::Sysconfig,
|
||||||
scrub_rate: u32,
|
scrub_rate: u32,
|
||||||
) -> Result<(), InvalidounterResetVal> {
|
) -> Result<(), InvalidCounterResetVal> {
|
||||||
if scrub_rate == 0 || scrub_rate > u32::pow(2, 24) {
|
if scrub_rate == 0 || scrub_rate > u32::pow(2, 24) {
|
||||||
return Err(InvalidounterResetVal(()));
|
return Err(InvalidCounterResetVal(()));
|
||||||
}
|
}
|
||||||
syscfg.ram_scrub().write(|w| unsafe { w.bits(scrub_rate) });
|
syscfg.ram_scrub().write(|w| unsafe { w.bits(scrub_rate) });
|
||||||
Ok(())
|
Ok(())
|
||||||
|
Loading…
Reference in New Issue
Block a user