diff --git a/va416xx-hal/examples/blinky.rs b/va416xx-hal/examples/blinky.rs index be5633d..5ed2c39 100644 --- a/va416xx-hal/examples/blinky.rs +++ b/va416xx-hal/examples/blinky.rs @@ -3,7 +3,7 @@ #![no_std] use cortex_m_rt::entry; -use embedded_hal::digital::{OutputPin, StatefulOutputPin}; +use embedded_hal::digital::StatefulOutputPin; use panic_halt as _; use va416xx_hal::{gpio::PinsG, pac}; @@ -11,17 +11,11 @@ use va416xx_hal::{gpio::PinsG, pac}; fn main() -> ! { // SAFETY: Peripherals are only stolen once here. let mut dp = unsafe { pac::Peripherals::steal() }; - // Enable all peripheral clocks - dp.sysconfig - .peripheral_clk_enable() - .modify(|_, w| unsafe { w.bits(0xffffffff) }); let portg = PinsG::new(&mut dp.sysconfig, Some(dp.ioconfig), dp.portg); let mut led = portg.pg5.into_readable_push_pull_output(); //let mut delay = CountDownTimer::new(&mut dp.SYSCONFIG, 50.mhz(), dp.TIM0); loop { - led.set_high().ok(); - cortex_m::asm::delay(2_000_000); - led.set_low().ok(); cortex_m::asm::delay(2_000_000); + led.toggle().ok(); } } diff --git a/va416xx-hal/src/gpio/dynpin.rs b/va416xx-hal/src/gpio/dynpin.rs index 07455e3..ab1c20c 100644 --- a/va416xx-hal/src/gpio/dynpin.rs +++ b/va416xx-hal/src/gpio/dynpin.rs @@ -138,7 +138,7 @@ impl DynRegisters { /// operations are fallible. This `enum` represents the corresponding errors. #[derive(Debug)] #[cfg_attr(feature = "defmt", derive(defmt::Format))] -pub struct InvalidPinTypeError(pub (crate) ()); +pub struct InvalidPinTypeError(pub(crate) ()); impl embedded_hal::digital::Error for InvalidPinTypeError { fn kind(&self) -> embedded_hal::digital::ErrorKind { @@ -268,32 +268,40 @@ impl DynPin { self.regs.delay(delay_1, delay_2); Ok(self) } - _ => Err(InvalidPinTypeError(())) + _ => Err(InvalidPinTypeError(())), } } /// See p.52 of the programmers guide for more information. /// When configured for pulse mode, a given pin will set the non-default state for exactly /// one clock cycle before returning to the configured default state - pub fn pulse_mode(self, enable: bool, default_state: PinState) -> Result { + pub fn pulse_mode( + self, + enable: bool, + default_state: PinState, + ) -> Result { match self.mode { DynPinMode::Output(_) => { self.regs.pulse_mode(enable, default_state); Ok(self) } - _ => Err(InvalidPinTypeError(())) + _ => Err(InvalidPinTypeError(())), } } /// See p.37 and p.38 of the programmers guide for more information. #[inline] - pub fn filter_type(self, filter: FilterType, clksel: FilterClkSel) -> Result { + pub fn filter_type( + self, + filter: FilterType, + clksel: FilterClkSel, + ) -> Result { match self.mode { DynPinMode::Input(_) => { self.regs.filter_type(filter, clksel); Ok(self) } - _ => Err(InvalidPinTypeError(())) + _ => Err(InvalidPinTypeError(())), } } @@ -304,18 +312,21 @@ impl DynPin { self.irq_enb(); Ok(self) } - _ => Err(InvalidPinTypeError(())) + _ => Err(InvalidPinTypeError(())), } } - pub fn interrupt_level(mut self, level_type: InterruptLevel) -> Result { + pub fn interrupt_level( + mut self, + level_type: InterruptLevel, + ) -> Result { match self.mode { DynPinMode::Input(_) | DynPinMode::Output(_) => { self.regs.interrupt_level(level_type); self.irq_enb(); Ok(self) } - _ => Err(InvalidPinTypeError(())) + _ => Err(InvalidPinTypeError(())), } } @@ -325,7 +336,7 @@ impl DynPin { DynPinMode::Input(_) | DYN_RD_OPEN_DRAIN_OUTPUT | DYN_RD_PUSH_PULL_OUTPUT => { Ok(self.regs.read_pin()) } - _ => Err(InvalidPinTypeError(())) + _ => Err(InvalidPinTypeError(())), } } #[inline] @@ -335,7 +346,7 @@ impl DynPin { self.regs.write_pin(bit); Ok(()) } - _ => Err(InvalidPinTypeError(())) + _ => Err(InvalidPinTypeError(())), } } diff --git a/va416xx-hal/src/gpio/pin.rs b/va416xx-hal/src/gpio/pin.rs index d01dcc6..ddd73b6 100644 --- a/va416xx-hal/src/gpio/pin.rs +++ b/va416xx-hal/src/gpio/pin.rs @@ -97,6 +97,8 @@ pub trait OutputConfig: Sealed { const DYN: DynOutput; } +pub trait ReadableOutput: Sealed {} + /// Type-level variant of [`OutputConfig`] for a push-pull configuration pub enum PushPull {} /// Type-level variant of [`OutputConfig`] for an open drain configuration @@ -111,6 +113,8 @@ impl Sealed for PushPull {} impl Sealed for OpenDrain {} impl Sealed for ReadableOpenDrain {} impl Sealed for ReadablePushPull {} +impl ReadableOutput for ReadableOpenDrain {} +impl ReadableOutput for ReadablePushPull {} impl OutputConfig for PushPull { const DYN: DynOutput = DynOutput::PushPull; @@ -538,7 +542,7 @@ where impl StatefulOutputPin for Pin> where I: PinId, - C: OutputConfig, + C: OutputConfig + ReadableOutput, { #[inline] fn is_set_high(&mut self) -> Result { diff --git a/va416xx-hal/src/gpio/reg.rs b/va416xx-hal/src/gpio/reg.rs index 9c81c12..2067fb9 100644 --- a/va416xx-hal/src/gpio/reg.rs +++ b/va416xx-hal/src/gpio/reg.rs @@ -76,11 +76,7 @@ impl From for ModeFields { // RegisterInterface //============================================================================== -pub type IocfgPort = ioconfig::Porta; -#[repr(C)] -pub(super) struct IocfgConfigGroupDefault { - port: [IocfgPort; 16], -} +pub type PortReg = ioconfig::Porta; /// Provide a safe register interface for pin objects /// @@ -124,7 +120,6 @@ pub(super) unsafe trait RegisterInterface { const PORTE: *const PortRegisterBlock = Porte::ptr(); const PORTF: *const PortRegisterBlock = Portf::ptr(); const PORTG: *const PortRegisterBlock = Portg::ptr(); - const PORT_CFG_BASE: *const IocfgConfigGroupDefault = Ioconfig::ptr() as *const _; /// Change the pin mode #[inline] @@ -138,7 +133,7 @@ pub(super) unsafe trait RegisterInterface { enb_input, } = mode.into(); let (portreg, iocfg) = (self.port_reg(), self.iocfg_port()); - iocfg.port[self.id().num as usize].write(|w| { + iocfg.write(|w| { w.opendrn().bit(opendrn); w.pen().bit(pull_en); w.plevel().bit(pull_dir); @@ -170,15 +165,16 @@ pub(super) unsafe trait RegisterInterface { } } - fn iocfg_port(&self) -> &IocfgConfigGroupDefault { + fn iocfg_port(&self) -> &PortReg { + let ioconfig = unsafe { Ioconfig::ptr().as_ref().unwrap() }; match self.id().group { - DynGroup::A => unsafe { &*Self::PORT_CFG_BASE }, - DynGroup::B => unsafe { &*Self::PORT_CFG_BASE.add(1) }, - DynGroup::C => unsafe { &*Self::PORT_CFG_BASE.add(3) }, - DynGroup::D => unsafe { &*Self::PORT_CFG_BASE.add(4) }, - DynGroup::E => unsafe { &*Self::PORT_CFG_BASE.add(5) }, - DynGroup::F => unsafe { &*Self::PORT_CFG_BASE.add(6) }, - DynGroup::G => unsafe { &*Self::PORT_CFG_BASE.add(7) }, + DynGroup::A => ioconfig.porta(self.id().num as usize), + DynGroup::B => ioconfig.portb0(self.id().num as usize), + DynGroup::C => ioconfig.portc0(self.id().num as usize), + DynGroup::D => ioconfig.portd0(self.id().num as usize), + DynGroup::E => ioconfig.porte0(self.id().num as usize), + DynGroup::F => ioconfig.portf0(self.id().num as usize), + DynGroup::G => ioconfig.portg0(self.id().num as usize), } } @@ -303,7 +299,7 @@ pub(super) unsafe trait RegisterInterface { /// Only useful for input pins #[inline] fn filter_type(&self, filter: FilterType, clksel: FilterClkSel) { - self.iocfg_port().port[self.id().num as usize].modify(|_, w| { + self.iocfg_port().modify(|_, w| { // Safety: Only write to register for this Pin ID unsafe { w.flttype().bits(filter as u8); diff --git a/va416xx-hal/src/lib.rs b/va416xx-hal/src/lib.rs index c672edd..6aad93a 100644 --- a/va416xx-hal/src/lib.rs +++ b/va416xx-hal/src/lib.rs @@ -5,8 +5,8 @@ pub use va416xx as pac; pub mod prelude; pub mod clock; -pub mod time; pub mod gpio; +pub mod time; pub mod typelevel; #[derive(Debug, Eq, Copy, Clone, PartialEq)] diff --git a/va416xx-hal/src/prelude.rs b/va416xx-hal/src/prelude.rs index e69de29..8b13789 100644 --- a/va416xx-hal/src/prelude.rs +++ b/va416xx-hal/src/prelude.rs @@ -0,0 +1 @@ + diff --git a/va416xx/src/porta.rs b/va416xx/src/porta.rs index 99b21b6..7d18568 100644 --- a/va416xx/src/porta.rs +++ b/va416xx/src/porta.rs @@ -1,3 +1,6 @@ +// Manually inserted. +#![allow(clippy::identity_op)] + #[repr(C)] #[doc = "Register block"] pub struct RegisterBlock { diff --git a/vorago-peb1/examples/blinky.rs b/vorago-peb1/examples/blinky.rs index 44d14f7..a261fcb 100644 --- a/vorago-peb1/examples/blinky.rs +++ b/vorago-peb1/examples/blinky.rs @@ -3,12 +3,9 @@ #![no_std] use cortex_m_rt::entry; +use embedded_hal::digital::v2::{OutputPin, ToggleableOutputPin}; use panic_halt as _; -use va416xx_hal::{ - pac, - gpio::PinsG -}; -use embedded_hal::digital::v2::{ToggleableOutputPin, OutputPin}; +use va416xx_hal::{gpio::PinsG, pac}; // Mask for the LED const LED_PG5: u32 = 1 << 5; @@ -54,7 +51,7 @@ fn main() -> ! { led.set_low().ok(); cortex_m::asm::delay(5_000_000); led.set_high().ok(); - }; + } loop { led.toggle().ok(); cortex_m::asm::delay(25_000_000);