diff --git a/CHANGELOG.md b/CHANGELOG.md index 21d8603..25955d0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,16 @@ and this project adheres to [Semantic Versioning](http://semver.org/). ## [unreleased] +## [v0.4.2] + +### Added + +- `port_mux` function to set pin function select manually + +### Changed + +- Clear TX and RX FIFO in SPI transfer function + ## [v0.4.1] ### Fixed diff --git a/Cargo.toml b/Cargo.toml index 28341dc..41c7005 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "va108xx-hal" -version = "0.4.1" +version = "0.4.2" authors = ["Robin Mueller "] edition = "2021" description = "HAL for the Vorago VA108xx family of microcontrollers" diff --git a/src/gpio/dynpins.rs b/src/gpio/dynpins.rs index 28b7a1f..f3b2122 100644 --- a/src/gpio/dynpins.rs +++ b/src/gpio/dynpins.rs @@ -57,14 +57,17 @@ //! operation, the trait functions will return //! [`InvalidPinType`](PinError::InvalidPinType). -use super::pins::{ - common_reg_if_functions, FilterType, InterruptEdge, InterruptLevel, Pin, PinError, PinId, - PinMode, PinState, +use super::{ + pins::{ + common_reg_if_functions, FilterType, InterruptEdge, InterruptLevel, Pin, PinError, PinId, + PinMode, PinState, + }, + reg::RegisterInterface, }; -use super::reg::RegisterInterface; use crate::{ clock::FilterClkSel, pac::{self, IRQSEL, SYSCONFIG}, + utility::Funsel, }; use embedded_hal::digital::v2::{InputPin, OutputPin, ToggleableOutputPin}; use paste::paste; @@ -98,13 +101,7 @@ pub enum DynOutput { ReadableOpenDrain, } -/// Value-level `enum` for alternate peripheral function configurations -#[derive(PartialEq, Eq, Clone, Copy)] -pub enum DynAlternate { - Funsel1, - Funsel2, - Funsel3, -} +pub type DynAlternate = Funsel; //================================================================================================== // DynPinMode diff --git a/src/gpio/reg.rs b/src/gpio/reg.rs index 8f94912..6614a34 100644 --- a/src/gpio/reg.rs +++ b/src/gpio/reg.rs @@ -60,18 +60,7 @@ impl From for ModeFields { } } Alternate(config) => { - use dynpins::DynAlternate::*; - match config { - Funsel1 => { - fields.funsel = 1; - } - Funsel2 => { - fields.funsel = 2; - } - Funsel3 => { - fields.funsel = 3; - } - } + fields.funsel = config as u8; } } fields diff --git a/src/spi.rs b/src/spi.rs index 4a95748..821fa2b 100644 --- a/src/spi.rs +++ b/src/spi.rs @@ -504,6 +504,16 @@ macro_rules! spi { }); } + #[inline] + pub fn clear_tx_fifo(&self) { + self.spi.fifo_clr.write(|w| w.txfifo().set_bit()); + } + + #[inline] + pub fn clear_rx_fifo(&self) { + self.spi.fifo_clr.write(|w| w.rxfifo().set_bit()); + } + #[inline] pub fn perid(&self) -> u32 { self.spi.perid.read().bits() @@ -640,6 +650,9 @@ macro_rules! spi { // FIFO has a depth of 16. const FILL_DEPTH: usize = 12; + self.clear_tx_fifo(); + self.clear_rx_fifo(); + if self.blockmode { self.spi.ctrl1.modify(|_, w| { w.mtxpause().set_bit() diff --git a/src/utility.rs b/src/utility.rs index 9f91903..edbe74d 100644 --- a/src/utility.rs +++ b/src/utility.rs @@ -3,11 +3,25 @@ //! Some more information about the recommended scrub rates can be found on the //! [Vorago White Paper website](https://www.voragotech.com/resources) in the //! application note AN1212 -use va108xx::SYSCONFIG; +use va108xx::{IOCONFIG, SYSCONFIG}; #[derive(PartialEq, Debug)] pub enum UtilityError { InvalidCounterResetVal, + InvalidPin, +} + +#[derive(Debug, Eq, Copy, Clone, PartialEq)] +pub enum Funsel { + Funsel1 = 0b01, + Funsel2 = 0b10, + Funsel3 = 0b11, +} + +#[derive(Debug, Copy, Clone, PartialEq)] +pub enum PortSel { + PortA, + PortB, } #[derive(Copy, Clone, PartialEq)] @@ -72,3 +86,28 @@ pub fn set_reset_bit(syscfg: &mut SYSCONFIG, periph_sel: PeripheralSelect) { .peripheral_reset .modify(|r, w| unsafe { w.bits(r.bits() | (1 << periph_sel as u8)) }); } + +/// Can be used to manually manipulate the function select of port pins +pub fn port_mux( + ioconfig: &mut IOCONFIG, + port: PortSel, + pin: u8, + funsel: Funsel, +) -> Result<(), UtilityError> { + match port { + PortSel::PortA => { + if pin > 31 { + return Err(UtilityError::InvalidPin); + } + ioconfig.porta[pin as usize].modify(|_, w| unsafe { w.funsel().bits(funsel as u8) }); + Ok(()) + } + PortSel::PortB => { + if pin > 23 { + return Err(UtilityError::InvalidPin); + } + ioconfig.portb[pin as usize].modify(|_, w| unsafe { w.funsel().bits(funsel as u8) }); + Ok(()) + } + } +}