diff --git a/CHANGELOG.md b/CHANGELOG.md index a8b663d..fc5f967 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,9 @@ and this project adheres to [Semantic Versioning](http://semver.org/). ## [unreleased] +### Changed + +- Minor optimizations and tweaks for GPIO module ## [0.2.0] diff --git a/src/clock.rs b/src/clock.rs index e8740ae..d0c9656 100644 --- a/src/clock.rs +++ b/src/clock.rs @@ -1,3 +1,6 @@ +//! # API for clock related functionality +//! +//! This also includes functionality to enable the peripheral clocks use crate::time::Hertz; use cortex_m::interrupt::{self, Mutex}; use once_cell::unsync::OnceCell; diff --git a/src/gpio/mod.rs b/src/gpio/mod.rs index 69e49df..53dbe5f 100644 --- a/src/gpio/mod.rs +++ b/src/gpio/mod.rs @@ -1,12 +1,12 @@ -//! # GPIO module +//! # API for the GPIO peripheral //! //! The implementation of this GPIO module is heavily based on the //! [ATSAMD HAL implementation](https://docs.rs/atsamd-hal/0.13.0/atsamd_hal/gpio/v2/index.html). //! -//! This API provides two different submodules, [`pin`] and [`dynpin`], -//! representing two different ways to handle GPIO pins. The default, [`pin`], +//! This API provides two different submodules, [`pins`] and [`dynpins`], +//! representing two different ways to handle GPIO pins. The default, [`pins`], //! is a type-level API that tracks the state of each pin at compile-time. The -//! alternative, [`dynpin`] is a type-erased, value-level API that tracks the +//! alternative, [`dynpins`] 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,7 +14,7 @@ //! compile-time. Furthermore, the type-level API has absolutely zero run-time //! cost. //! -//! If needed, [`dynpin`] can be used to erase the type-level differences +//! If needed, [`dynpins`] 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. //! diff --git a/src/gpio/pins.rs b/src/gpio/pins.rs index 681c1cd..6656087 100644 --- a/src/gpio/pins.rs +++ b/src/gpio/pins.rs @@ -84,15 +84,8 @@ //! 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 +//! 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::reg::RegisterInterface; @@ -115,14 +108,12 @@ pub enum PinState { } /// GPIO error type -/// -/// [`DynPin`]s are not tracked and verified at compile-time, so run-time -/// operations are fallible. This `enum` represents the corresponding errors. #[derive(Debug, PartialEq)] pub enum PinError { - /// The pin did not have the correct ID or mode for the requested operation + /// The pin did not have the correct ID or mode for the requested operation. + /// [`DynPin`](crate::gpio::DynPin)s are not tracked and verified at compile-time, so run-time + /// operations are fallible. InvalidPinType, - InputDisabledForOutput, IsMasked, } diff --git a/src/gpio/reg.rs b/src/gpio/reg.rs index 13f53b9..72e2e76 100644 --- a/src/gpio/reg.rs +++ b/src/gpio/reg.rs @@ -200,11 +200,13 @@ pub(super) unsafe trait RegisterInterface { } } + #[inline] fn get_perid(&self) -> u32 { let portreg = self.port_reg(); portreg.perid.read().bits() } + #[inline] /// Read the logic level of an output pin fn read_pin(&self) -> bool { let portreg = self.port_reg(); @@ -220,27 +222,25 @@ pub(super) unsafe trait RegisterInterface { /// Read a pin but use the masked version but check whether the datamask for the pin is /// cleared as well + #[inline] fn read_pin_masked(&self) -> Result { if !self.datamask() { Err(PinError::IsMasked) } else { - let portreg = self.port_reg(); - Ok(((portreg.datain().read().bits() >> self.id().num) & 0x01) == 1) + Ok(((self.port_reg().datain().read().bits() >> self.id().num) & 0x01) == 1) } } /// Write the logic level of an output pin #[inline] fn write_pin(&mut self, bit: bool) { - let portreg = self.port_reg(); - let mask = self.mask_32(); // Safety: SETOUT is a "mask" register, and we only write the bit for // this pin ID unsafe { if bit { - portreg.setout().write(|w| w.bits(mask)); + self.port_reg().setout().write(|w| w.bits(self.mask_32())); } else { - portreg.clrout().write(|w| w.bits(mask)); + self.port_reg().clrout().write(|w| w.bits(self.mask_32())); } } } @@ -252,15 +252,13 @@ pub(super) unsafe trait RegisterInterface { if !self.datamask() { Err(PinError::IsMasked) } else { - let portreg = self.port_reg(); - let mask = self.mask_32(); // Safety: SETOUT is a "mask" register, and we only write the bit for // this pin ID unsafe { if bit { - portreg.setout().write(|w| w.bits(mask)); + self.port_reg().setout().write(|w| w.bits(self.mask_32())); } else { - portreg.clrout().write(|w| w.bits(mask)); + self.port_reg().clrout().write(|w| w.bits(self.mask_32())); } Ok(()) } @@ -270,18 +268,15 @@ pub(super) unsafe trait RegisterInterface { /// Toggle the logic level of an output pin #[inline] fn toggle(&mut self) { - let portreg = self.port_reg(); - let mask = self.mask_32(); // Safety: TOGOUT is a "mask" register, and we only write the bit for // this pin ID - unsafe { portreg.togout().write(|w| w.bits(mask)) }; + unsafe { self.port_reg().togout().write(|w| w.bits(self.mask_32())) }; } /// Only useful for input pins #[inline] fn filter_type(&self, filter: FilterType, clksel: FilterClkSel) { - let iocfg = self.iocfg_port(); - iocfg.port[self.id().num as usize].modify(|_, w| { + self.iocfg_port().port[self.id().num as usize].modify(|_, w| { // Safety: Only write to register for this Pin ID unsafe { w.flttype().bits(filter as u8); diff --git a/src/uart.rs b/src/uart.rs index 499a189..60355f5 100644 --- a/src/uart.rs +++ b/src/uart.rs @@ -1,4 +1,7 @@ -//! API for the UART peripheral +//! # API for the UART peripheral +//! +//! ## Examples +//! - [UART example](https://github.com/robamu-org/va108xx-hal-rs/blob/main/examples/uart.rs) use core::{convert::Infallible, ptr}; use core::{marker::PhantomData, ops::Deref}; use libm::floorf;