diff --git a/Cargo.toml b/Cargo.toml index c7bb8829b..03b71643f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -18,6 +18,7 @@ exclude = [ "codegen", ".markdownlint.yml" ] +resolver = "2" [package.metadata.docs.rs] features = ["stm32f303xc", "rt", "stm32-usbd", "can"] diff --git a/src/adc.rs b/src/adc.rs index a68aa935e..f1b50046f 100644 --- a/src/adc.rs +++ b/src/adc.rs @@ -49,31 +49,31 @@ pub struct Adc { /// /// Each channel can be sampled with a different sample time. /// There is always an overhead of 13 ADC clock cycles. -/// E.g. For Sampletime T_19 the total conversion time (in ADC clock cycles) is +/// E.g. For Sampletime T19 the total conversion time (in ADC clock cycles) is /// 13 + 19 = 32 ADC Clock Cycles pub enum SampleTime { /// 1.5 ADC clock cycles - T_1, + T1, /// 2.5 ADC clock cycles - T_2, + T2, /// 4.5 ADC clock cycles - T_4, + T4, /// 7.5 ADC clock cycles - T_7, + T7, /// 19.5 ADC clock cycles - T_19, + T19, /// 61.5 ADC clock cycles - T_61, + T61, /// 181.5 ADC clock cycles - T_181, + T181, /// 601.5 ADC clock cycles - T_601, + T601, } impl Default for SampleTime { - /// T_1 is also the reset value. + /// T1 is also the reset value. fn default() -> Self { - SampleTime::T_1 + SampleTime::T1 } } @@ -81,14 +81,14 @@ impl SampleTime { /// Conversion to bits for SMP fn bitcode(&self) -> u8 { match self { - SampleTime::T_1 => 0b000, - SampleTime::T_2 => 0b001, - SampleTime::T_4 => 0b010, - SampleTime::T_7 => 0b011, - SampleTime::T_19 => 0b100, - SampleTime::T_61 => 0b101, - SampleTime::T_181 => 0b110, - SampleTime::T_601 => 0b111, + SampleTime::T1 => 0b000, + SampleTime::T2 => 0b001, + SampleTime::T4 => 0b010, + SampleTime::T7 => 0b011, + SampleTime::T19 => 0b100, + SampleTime::T61 => 0b101, + SampleTime::T181 => 0b110, + SampleTime::T601 => 0b111, } } } @@ -101,23 +101,23 @@ pub enum OperationMode { OneShot, } -#[derive(Clone, Copy, PartialEq)] /// ADC CkMode // TODO: Add ASYNCHRONOUS mode +#[derive(Clone, Copy, PartialEq)] pub enum CkMode { // /// Use Kernel Clock adc_ker_ck_input divided by PRESC. Asynchronous to AHB clock // ASYNCHRONOUS = 0, /// Use AHB clock rcc_hclk3. In this case rcc_hclk must equal sys_d1cpre_ck - SYNCDIV1 = 1, + SyncDiv1 = 1, /// Use AHB clock rcc_hclk3 divided by 2 - SYNCDIV2 = 2, + SyncDiv2 = 2, /// Use AHB clock rcc_hclk3 divided by 4 - SYNCDIV4 = 4, + SyncDiv4 = 4, } impl Default for CkMode { fn default() -> Self { - CkMode::SYNCDIV2 + CkMode::SyncDiv2 } } @@ -126,9 +126,9 @@ impl From for CKMODE_A { fn from(ckmode: CkMode) -> Self { match ckmode { //CkMode::ASYNCHRONOUS => CKMODE_A::ASYNCHRONOUS, - CkMode::SYNCDIV1 => CKMODE_A::SYNCDIV1, - CkMode::SYNCDIV2 => CKMODE_A::SYNCDIV2, - CkMode::SYNCDIV4 => CKMODE_A::SYNCDIV4, + CkMode::SyncDiv1 => CKMODE_A::SyncDiv1, + CkMode::SyncDiv2 => CKMODE_A::SyncDiv2, + CkMode::SyncDiv4 => CKMODE_A::SyncDiv4, } } } @@ -339,10 +339,10 @@ macro_rules! adc_hal { this_adc } - /// Software can use CkMode::SYNCDIV1 only if + /// Software can use CkMode::SyncDiv1 only if /// hclk and sysclk are the same. (see reference manual 15.3.3) fn clocks_welldefined(&self, clocks: Clocks) -> bool { - if (self.ckmode == CkMode::SYNCDIV1) { + if (self.ckmode == CkMode::SyncDiv1) { clocks.hclk().0 == clocks.sysclk().0 } else { true @@ -403,9 +403,9 @@ macro_rules! adc_hal { // mode is implemented (CKMODE[1:0] = 00b). This will force whoever is working // on it to rethink what needs to be done here :) let adc_per_cpu_cycles = match self.ckmode { - CkMode::SYNCDIV1 => 1, - CkMode::SYNCDIV2 => 2, - CkMode::SYNCDIV4 => 4, + CkMode::SyncDiv1 => 1, + CkMode::SyncDiv2 => 2, + CkMode::SyncDiv4 => 4, }; asm::delay(adc_per_cpu_cycles * cycles); } @@ -477,15 +477,15 @@ macro_rules! adc_hal { } - impl OneShot<$ADC, WORD, PIN> for Adc<$ADC> + impl OneShot<$ADC, Word, Pin> for Adc<$ADC> where - WORD: From, - PIN: Channel<$ADC, ID = u8>, + Word: From, + Pin: Channel<$ADC, ID = u8>, { type Error = (); - fn read(&mut self, _pin: &mut PIN) -> nb::Result { - let res = self.convert_one(PIN::channel()); + fn read(&mut self, _pin: &mut Pin) -> nb::Result { + let res = self.convert_one(Pin::channel()); return Ok(res.into()); } } diff --git a/src/gpio.rs b/src/gpio.rs index 1683ade7e..37c12f7d7 100644 --- a/src/gpio.rs +++ b/src/gpio.rs @@ -72,7 +72,7 @@ use crate::{ #[cfg(feature = "unproven")] use crate::hal::digital::v2::{toggleable, InputPin, StatefulOutputPin}; -use typenum::{Unsigned, U0, U1, U10, U11, U12, U13, U14, U15, U2, U3, U4, U5, U6, U7, U8, U9}; +use typenum::{Unsigned}; /// Extension trait to split a GPIO peripheral in independent pins and registers pub trait GpioExt { @@ -147,12 +147,6 @@ pub mod marker { type PUPDR: super::Pupdr; } - /// Marker trait for pin number - pub trait Index { - #[doc(hidden)] - fn index(&self) -> u8; - } - /// Marker trait for readable pin modes pub trait Readable {} @@ -202,28 +196,12 @@ impl marker::Gpio for Gpiox {} /// Runtime defined pin number (type state) pub struct Ux(u8); -impl marker::Index for Ux { - fn index(&self) -> u8 { - self.0 - } -} - -impl marker::Index for U -where - U: Unsigned, -{ - #[inline(always)] - fn index(&self) -> u8 { - Self::U8 - } -} - /// Input mode (type state) pub struct Input; /// Output mode (type state) pub struct Output(PhantomData); /// Alternate function (type state) -pub struct Alternate(PhantomData, PhantomData); +pub struct Alternate(u8, PhantomData); /// Analog mode (type state) pub struct Analog; @@ -235,10 +213,10 @@ pub struct OpenDrain; impl marker::Readable for Input {} impl marker::Readable for Output {} impl marker::OutputSpeed for Output {} -impl marker::OutputSpeed for Alternate {} +impl marker::OutputSpeed for Alternate {} impl marker::Active for Input {} impl marker::Active for Output {} -impl marker::Active for Alternate {} +impl marker::Active for Alternate {} /// Slew rate configuration pub enum Speed { @@ -271,22 +249,28 @@ pub enum Edge { } /// Generic pin -pub struct Pin { +pub struct Pin { gpio: Gpio, - index: Index, + index: u8, _mode: PhantomData, } -/// Fully erased pin -/// -/// This moves the pin type information to be known -/// at runtime, and erases the specific compile time type of the GPIO. -/// The only compile time information of the GPIO pin is it's Mode. -/// -/// See [examples/gpio_erased.rs] as an example. -/// -/// [examples/gpio_erased.rs]: https://github.com/stm32-rs/stm32f3xx-hal/blob/v0.6.0/examples/gpio_erased.rs -pub type PXx = Pin; +pub struct PXx { + gpio: Gpiox, + index: u8, + _mode: PhantomData, +} + +///// Fully erased pin +///// +///// This moves the pin type information to be known +///// at runtime, and erases the specific compile time type of the GPIO. +///// The only compile time information of the GPIO pin is it's Mode. +///// +///// See [examples/gpio_erased.rs] as an example. +///// +///// [examples/gpio_erased.rs]: https://github.com/stm32-rs/stm32f3xx-hal/blob/v0.6.0/examples/gpio_erased.rs +//pub type PXx = Pin; /// Modify specific index of array-like register macro_rules! modify_at { @@ -299,46 +283,43 @@ macro_rules! modify_at { }; } -impl Pin -where - Index: Unsigned, -{ +impl Pin { /// Erases the pin number from the type /// /// This is useful when you want to collect the pins into an array where you /// need all the elements to have the same type - pub fn downgrade(self) -> Pin { + pub fn downgrade(self) -> Pin { Pin { gpio: self.gpio, - index: Ux(Index::U8), + index: INDEX, _mode: self._mode, } } } -impl Pin -where - Gpio: marker::GpioStatic, - Gpio::Reg: 'static + Sized, -{ - /// Erases the port letter from the type - /// - /// This is useful when you want to collect the pins into an array where you - /// need all the elements to have the same type - pub fn downgrade(self) -> PXx { - PXx { - gpio: Gpiox { - ptr: self.gpio.ptr(), - index: self.gpio.port_index(), - }, - index: self.index, - _mode: self._mode, - } - } -} - -impl Pin { - fn into_mode(self) -> Pin { +//impl Pin +//where +// Gpio: marker::GpioStatic, +// Gpio::Reg: 'static + Sized, +//{ +// /// Erases the port letter from the type +// /// +// /// This is useful when you want to collect the pins into an array where you +// /// need all the elements to have the same type +// pub fn downgrade(self) -> PXx { +// PXx { +// gpio: Gpiox { +// ptr: self.gpio.ptr(), +// index: self.gpio.port_index(), +// }, +// index: self.index, +// _mode: self._mode, +// } +// } +//} + +impl Pin { + fn into_mode(self) -> Pin { Pin { gpio: self.gpio, index: self.index, @@ -347,14 +328,13 @@ impl Pin { } } -impl Pin +impl Pin where Gpio: marker::GpioStatic, - Index: marker::Index, { /// Configures the pin to operate as an input pin - pub fn into_input(self, moder: &mut Gpio::MODER) -> Pin { - moder.input(self.index.index()); + pub fn into_input(self, moder: &mut Gpio::MODER) -> Pin { + moder.input(self.index); self.into_mode() } @@ -364,9 +344,9 @@ where self, moder: &mut Gpio::MODER, pupdr: &mut Gpio::PUPDR, - ) -> Pin { - moder.input(self.index.index()); - pupdr.floating(self.index.index()); + ) -> Pin { + moder.input(self.index); + pupdr.floating(self.index); self.into_mode() } @@ -376,9 +356,9 @@ where self, moder: &mut Gpio::MODER, pupdr: &mut Gpio::PUPDR, - ) -> Pin { - moder.input(self.index.index()); - pupdr.pull_up(self.index.index()); + ) -> Pin { + moder.input(self.index); + pupdr.pull_up(self.index); self.into_mode() } @@ -388,9 +368,9 @@ where self, moder: &mut Gpio::MODER, pupdr: &mut Gpio::PUPDR, - ) -> Pin { - moder.input(self.index.index()); - pupdr.pull_down(self.index.index()); + ) -> Pin { + moder.input(self.index); + pupdr.pull_down(self.index); self.into_mode() } @@ -399,9 +379,9 @@ where self, moder: &mut Gpio::MODER, otyper: &mut Gpio::OTYPER, - ) -> Pin> { - moder.output(self.index.index()); - otyper.push_pull(self.index.index()); + ) -> Pin, INDEX> { + moder.output(self.index); + otyper.push_pull(self.index); self.into_mode() } @@ -410,9 +390,9 @@ where self, moder: &mut Gpio::MODER, otyper: &mut Gpio::OTYPER, - ) -> Pin> { - moder.output(self.index.index()); - otyper.open_drain(self.index.index()); + ) -> Pin, INDEX> { + moder.output(self.index); + otyper.open_drain(self.index); self.into_mode() } @@ -421,79 +401,78 @@ where self, moder: &mut Gpio::MODER, pupdr: &mut Gpio::PUPDR, - ) -> Pin { - moder.analog(self.index.index()); - pupdr.floating(self.index.index()); + ) -> Pin { + moder.analog(self.index); + pupdr.floating(self.index); self.into_mode() } } -impl Pin +impl Pin where Gpio: marker::GpioStatic, - Index: marker::Index, Mode: marker::OutputSpeed, { /// Set pin output slew rate pub fn set_speed(&mut self, ospeedr: &mut Gpio::OSPEEDR, speed: Speed) { match speed { - Speed::Low => ospeedr.low(self.index.index()), - Speed::Medium => ospeedr.medium(self.index.index()), - Speed::High => ospeedr.high(self.index.index()), + Speed::Low => ospeedr.low(self.index), + Speed::Medium => ospeedr.medium(self.index), + Speed::High => ospeedr.high(self.index), } } } -impl Pin +impl Pin where Gpio: marker::GpioStatic, - Index: marker::Index, Mode: marker::Active, { /// Set the internal pull-up and pull-down resistor pub fn set_internal_resistor(&mut self, pupdr: &mut Gpio::PUPDR, resistor: Resistor) { match resistor { - Resistor::Floating => pupdr.floating(self.index.index()), - Resistor::PullUp => pupdr.pull_up(self.index.index()), - Resistor::PullDown => pupdr.pull_down(self.index.index()), + Resistor::Floating => pupdr.floating(self.index), + Resistor::PullUp => pupdr.pull_up(self.index), + Resistor::PullDown => pupdr.pull_down(self.index), } } /// Enables / disables the internal pull up (Provided for compatibility with other stm32 HALs) + // TODO: This naming seems strange :( + // change it to enable_pull_resistor or remove it in favor of set_internal_resistor + // TODO: #[deprecate(since)] pub fn internal_pull_up(&mut self, pupdr: &mut Gpio::PUPDR, on: bool) { if on { - pupdr.pull_up(self.index.index()); + pupdr.pull_up(self.index); } else { - pupdr.floating(self.index.index()); + pupdr.floating(self.index); } } } -impl OutputPin for Pin> +impl OutputPin for Pin, { INDEX }> where Gpio: marker::Gpio, - Index: marker::Index, { type Error = Infallible; fn set_high(&mut self) -> Result<(), Self::Error> { // NOTE(unsafe) atomic write to a stateless register - unsafe { (*self.gpio.ptr()).set_high(self.index.index()) }; + unsafe { (*self.gpio.ptr()).set_high(self.index) }; Ok(()) } fn set_low(&mut self) -> Result<(), Self::Error> { // NOTE(unsafe) atomic write to a stateless register - unsafe { (*self.gpio.ptr()).set_low(self.index.index()) }; + unsafe { (*self.gpio.ptr()).set_low(self.index) }; Ok(()) } } #[cfg(feature = "unproven")] -impl InputPin for Pin +impl InputPin for Pin where Gpio: marker::Gpio, - Index: marker::Index, Mode: marker::Readable, { type Error = Infallible; @@ -504,15 +483,14 @@ where fn is_low(&self) -> Result { // NOTE(unsafe) atomic read with no side effects - Ok(unsafe { (*self.gpio.ptr()).is_low(self.index.index()) }) + Ok(unsafe { (*self.gpio.ptr()).is_low(self.index) }) } } #[cfg(feature = "unproven")] -impl StatefulOutputPin for Pin> +impl StatefulOutputPin for Pin, { INDEX }> where Gpio: marker::Gpio, - Index: marker::Index, { fn is_set_high(&self) -> Result { Ok(!self.is_set_low()?) @@ -520,15 +498,13 @@ where fn is_set_low(&self) -> Result { // NOTE(unsafe) atomic read with no side effects - Ok(unsafe { (*self.gpio.ptr()).is_set_low(self.index.index()) }) + Ok(unsafe { (*self.gpio.ptr()).is_set_low(self.index) }) } } #[cfg(feature = "unproven")] -impl toggleable::Default for Pin> -where - Gpio: marker::Gpio, - Index: marker::Index, +impl toggleable::Default for Pin, { INDEX }> where + Gpio: marker::Gpio { } @@ -550,15 +526,14 @@ macro_rules! reg_for_cpu { }; } -impl Pin +impl Pin where Gpio: marker::Gpio, - Index: marker::Index, Mode: marker::Active, { /// NVIC interrupt number of interrupt from this pin pub fn nvic(&self) -> Interrupt { - match self.index.index() { + match self.index { 0 => Interrupt::EXTI0, 1 => Interrupt::EXTI1, #[cfg(feature = "svd-f373")] @@ -579,9 +554,9 @@ where /// Make corresponding EXTI line sensitive to this pin pub fn make_interrupt_source(&mut self, syscfg: &mut SysCfg) { let bitwidth = 4; - let index = self.index.index() % 4; + let index = self.index % 4; let extigpionr = self.gpio.port_index() as u32; - match self.index.index() { + match self.index { 0..=3 => unsafe { modify_at!(syscfg.exticr1, bitwidth, index, extigpionr) }, 4..=7 => unsafe { modify_at!(syscfg.exticr2, bitwidth, index, extigpionr) }, 8..=11 => unsafe { modify_at!(syscfg.exticr3, bitwidth, index, extigpionr) }, @@ -593,7 +568,7 @@ where /// Generate interrupt on rising edge, falling edge, or both pub fn trigger_on_edge(&mut self, exti: &mut EXTI, edge: Edge) { let bitwidth = 1; - let index = self.index.index(); + let index = self.index; let (rise, fall) = match edge { Edge::Rising => (true as u32, false as u32), Edge::Falling => (false as u32, true as u32), @@ -608,7 +583,7 @@ where /// Enable external interrupts from this pin pub fn enable_interrupt(&mut self, exti: &mut EXTI) { let bitwidth = 1; - let index = self.index.index(); + let index = self.index; let value = 1; unsafe { modify_at!(reg_for_cpu!(exti, imr), bitwidth, index, value) }; } @@ -616,19 +591,19 @@ where /// Disable external interrupts from this pin pub fn disable_interrupt(&mut self, exti: &mut EXTI) { let bitwidth = 1; - let index = self.index.index(); + let index = self.index; let value = 0; unsafe { modify_at!(reg_for_cpu!(exti, imr), bitwidth, index, value) }; } /// Clear the interrupt pending bit for this pin pub fn clear_interrupt_pending_bit(&mut self) { - unsafe { reg_for_cpu!((*EXTI::ptr()), pr).write(|w| w.bits(1 << self.index.index())) }; + unsafe { reg_for_cpu!((*EXTI::ptr()), pr).write(|w| w.bits(1 << self.index)) }; } /// Reads the interrupt pending bit for this pin pub fn check_interrupt(&self) -> bool { - unsafe { reg_for_cpu!((*EXTI::ptr()), pr).read().bits() & (1 << self.index.index()) != 0 } + unsafe { reg_for_cpu!((*EXTI::ptr()), pr).read().bits() & (1 << self.index) != 0 } } } @@ -636,14 +611,13 @@ macro_rules! af { ($i:literal, $Ui:ty, $AFi:ident, $IntoAfi:ident, $into_afi_push_pull:ident, $into_afi_open_drain:ident) => { paste::paste! { #[doc = "Alternate function " $i " (type state)"] - pub type $AFi = Alternate<$Ui, Otype>; + pub type $AFi = Alternate; } - impl Pin + impl Pin where Self: marker::$IntoAfi, Gpio: marker::GpioStatic, - Index: marker::Index, { /// Configures the pin to operate as an alternate function push-pull output pin pub fn $into_afi_push_pull( @@ -651,10 +625,10 @@ macro_rules! af { moder: &mut Gpio::MODER, otyper: &mut Gpio::OTYPER, afr: &mut ::AFR, - ) -> Pin> { - moder.alternate(self.index.index()); - otyper.push_pull(self.index.index()); - afr.afx(self.index.index(), $i); + ) -> Pin, { INDEX }> { + moder.alternate(self.index); + otyper.push_pull(self.index); + afr.afx(self.index, $i); self.into_mode() } @@ -664,10 +638,10 @@ macro_rules! af { moder: &mut Gpio::MODER, otyper: &mut Gpio::OTYPER, afr: &mut ::AFR, - ) -> Pin> { - moder.alternate(self.index.index()); - otyper.open_drain(self.index.index()); - afr.afx(self.index.index(), $i); + ) -> Pin, { INDEX }> { + moder.alternate(self.index); + otyper.open_drain(self.index); + afr.afx(self.index, $i); self.into_mode() } } @@ -748,7 +722,7 @@ macro_rules! gpio { partially_erased_pin: $PXx:ty, pins: {$( $PXi:ty: ( - $pxi:ident, $Ui:ty, $MODE:ty, $AFR:ident, [$($IntoAfi:ident),*], + $pxi:ident, $i:literal, $MODE:ty, $AFR:ident, [$($IntoAfi:ident),*], ), )+}, }) => { @@ -798,11 +772,6 @@ macro_rules! gpio { AF0, AF1, AF2, AF3, AF4, AF5, AF6, AF7, AF8, AF9, AF10, AF11, AF12, AF13, AF14, AF15, }; - #[allow(unused_imports)] - use typenum::{ - U0, U1, U2, U3, U4, U5, U6, U7, U8, U9, U10, U11, U12, U13, U14, U15 - }; - /// GPIO parts pub struct Parts { /// Opaque AFRH register @@ -841,7 +810,7 @@ macro_rules! gpio { $( $pxi: $PXi { gpio: $Gpiox, - index: $Ui::new(), + index: $i, _mode: PhantomData, }, )+ @@ -919,12 +888,12 @@ macro_rules! gpio { } } - /// Partially erased pin - pub type $PXx = Pin<$Gpiox, Ux, Mode>; + // /// Partially erased pin + // pub type $PXx = Pin<$Gpiox, Mode,{ Ux }>; $( #[doc = "Pin " $PXi] - pub type $PXi = Pin<$Gpiox, $Ui, Mode>; + pub type $PXi = Pin<$Gpiox, Mode, { $i }>; $( impl marker::$IntoAfi for $PXi { @@ -965,7 +934,7 @@ macro_rules! gpio { partially_erased_pin: [

], pins: {$( [

]: ( - [

], [], $MODE, [], [$([]),*], + [

], $i, $MODE, [], [$([]),*], ), )+}, });