Skip to content

Commit cf1eace

Browse files
bors[bot]burrbull
andauthored
Merge #469
469: Pin::into_mode r=therealprof a=burrbull Depends on #467 Co-authored-by: Andrey Zgarbul <[email protected]>
2 parents 7241225 + 330e49f commit cf1eace

13 files changed

+232
-620
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
1010
### Changed
1111

1212
- CI updates + cache
13+
- Remove pull resistor from `Input` mode, use `Pull` enum instead, add universal `into_mode` pin converter
1314
- Move pin mode at the end of generics, add defaults for modes,
1415
bump MSRV to 1.59 [#418]
1516
- Move hd44780-driver to dev-dependencies

examples/analog-stopwatch-with-spi-ssd1306.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ use panic_semihosting as _;
1111
use stm32f4xx_hal as hal;
1212

1313
use crate::hal::{
14-
gpio::{Edge, Input, PullDown, PA0},
14+
gpio::{Edge, Input, PA0},
1515
interrupt, pac,
1616
prelude::*,
1717
rcc::{Clocks, Rcc},
@@ -45,7 +45,7 @@ static ELAPSED_MS: Mutex<Cell<u32>> = Mutex::new(Cell::new(0u32));
4545
static ELAPSED_RESET_MS: Mutex<Cell<u32>> = Mutex::new(Cell::new(0u32));
4646
static TIMER_TIM2: Mutex<RefCell<Option<CounterUs<pac::TIM2>>>> = Mutex::new(RefCell::new(None));
4747
static STATE: Mutex<Cell<StopwatchState>> = Mutex::new(Cell::new(StopwatchState::Ready));
48-
static BUTTON: Mutex<RefCell<Option<PA0<Input<PullDown>>>>> = Mutex::new(RefCell::new(None));
48+
static BUTTON: Mutex<RefCell<Option<PA0<Input>>>> = Mutex::new(RefCell::new(None));
4949

5050
/// The center of the clock face
5151
const CENTER: Point = Point::new(64, 40);

examples/rtic.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ use panic_halt as _;
88
#[rtic::app(device = stm32f4xx_hal::pac)]
99
mod app {
1010
use stm32f4xx_hal::{
11-
gpio::{Edge, Input, Output, PullUp, PushPull, PA0, PC13},
11+
gpio::{Edge, Input, Output, PushPull, PA0, PC13},
1212
prelude::*,
1313
};
1414

@@ -17,7 +17,7 @@ mod app {
1717

1818
#[local]
1919
struct Local {
20-
button: PA0<Input<PullUp>>,
20+
button: PA0<Input>,
2121
led: PC13<Output<PushPull>>,
2222
}
2323

examples/stopwatch-with-ssd1306-and-interrupts.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ use panic_semihosting as _; // logs messages to the host stderr; requires a debu
2222
use stm32f4xx_hal as hal;
2323

2424
use crate::hal::{
25-
gpio::{Edge, Input, PullUp, PC13},
25+
gpio::{Edge, Input, PC13},
2626
i2c::I2c,
2727
interrupt, pac,
2828
prelude::*,
@@ -50,7 +50,7 @@ use ssd1306::{prelude::*, I2CDisplayInterface, Ssd1306};
5050
static ELAPSED_MS: Mutex<Cell<u32>> = Mutex::new(Cell::new(0u32));
5151
static TIMER_TIM2: Mutex<RefCell<Option<CounterUs<pac::TIM2>>>> = Mutex::new(RefCell::new(None));
5252
static STATE: Mutex<Cell<StopwatchState>> = Mutex::new(Cell::new(StopwatchState::Ready));
53-
static BUTTON: Mutex<RefCell<Option<PC13<Input<PullUp>>>>> = Mutex::new(RefCell::new(None));
53+
static BUTTON: Mutex<RefCell<Option<PC13<Input>>>> = Mutex::new(RefCell::new(None));
5454

5555
#[derive(Clone, Copy)]
5656
enum StopwatchState {

src/gpio.rs

Lines changed: 62 additions & 83 deletions
Original file line numberDiff line numberDiff line change
@@ -102,18 +102,19 @@ pub trait PinExt {
102102
pub struct Alternate<const A: u8, Otype = PushPull>(PhantomData<Otype>);
103103

104104
/// Input mode (type state)
105-
pub struct Input<MODE = Floating> {
106-
_mode: PhantomData<MODE>,
107-
}
108-
109-
/// Floating input (type state)
110-
pub struct Floating;
105+
pub struct Input;
111106

112-
/// Pulled down input (type state)
113-
pub struct PullDown;
114-
115-
/// Pulled up input (type state)
116-
pub struct PullUp;
107+
/// Pull setting for an input.
108+
#[derive(Debug, Eq, PartialEq)]
109+
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
110+
pub enum Pull {
111+
/// Floating
112+
None = 0,
113+
/// Pulled up
114+
Up = 1,
115+
/// Pulled down
116+
Down = 2,
117+
}
117118

118119
/// Open drain input or output (type state)
119120
pub struct OpenDrain;
@@ -131,6 +132,26 @@ pub struct Analog;
131132

132133
pub type Debugger = Alternate<0, PushPull>;
133134

135+
mod sealed {
136+
/// Marker trait that show if `ExtiPin` can be implemented
137+
pub trait Interruptable {}
138+
/// Marker trait for slew rate configurable pin modes
139+
pub trait OutputSpeed {}
140+
/// Marker trait for active pin modes
141+
pub trait Active {}
142+
/// Marker trait for all pin modes except alternate
143+
pub trait NotAlt {}
144+
}
145+
146+
impl sealed::Active for Input {}
147+
impl<Otype> sealed::OutputSpeed for Output<Otype> {}
148+
impl<const A: u8, Otype> sealed::OutputSpeed for Alternate<A, Otype> {}
149+
impl<Otype> sealed::Active for Output<Otype> {}
150+
impl<const A: u8, Otype> sealed::Active for Alternate<A, Otype> {}
151+
impl sealed::NotAlt for Input {}
152+
impl<Otype> sealed::NotAlt for Output<Otype> {}
153+
impl sealed::NotAlt for Analog {}
154+
134155
/// GPIO Pin speed selection
135156
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
136157
#[derive(Debug, PartialEq, Eq, Clone, Copy)]
@@ -149,14 +170,9 @@ pub enum Edge {
149170
RisingFalling,
150171
}
151172

152-
mod sealed {
153-
/// Marker trait that show if `ExtiPin` can be implemented
154-
pub trait Interruptable {}
155-
}
156-
157173
use sealed::Interruptable;
158174
impl<MODE> Interruptable for Output<MODE> {}
159-
impl<MODE> Interruptable for Input<MODE> {}
175+
impl Interruptable for Input {}
160176

161177
/// External Interrupt Pin
162178
pub trait ExtiPin {
@@ -262,7 +278,7 @@ where
262278
/// - `MODE` is one of the pin modes (see [Modes](crate::gpio#modes) section).
263279
/// - `P` is port name: `A` for GPIOA, `B` for GPIOB, etc.
264280
/// - `N` is pin number: from `0` to `15`.
265-
pub struct Pin<const P: char, const N: u8, MODE = Input<Floating>> {
281+
pub struct Pin<const P: char, const N: u8, MODE = Input> {
266282
_mode: PhantomData<MODE>,
267283
}
268284
impl<const P: char, const N: u8, MODE> Pin<P, N, MODE> {
@@ -302,7 +318,10 @@ impl<const P: char, const N: u8, MODE> PinExt for Pin<P, N, MODE> {
302318
}
303319
}
304320

305-
impl<const P: char, const N: u8, MODE> Pin<P, N, Output<MODE>> {
321+
impl<const P: char, const N: u8, MODE> Pin<P, N, MODE>
322+
where
323+
MODE: sealed::OutputSpeed,
324+
{
306325
/// Set pin speed
307326
pub fn set_speed(self, speed: Speed) -> Self {
308327
let offset = 2 * { N };
@@ -317,24 +336,11 @@ impl<const P: char, const N: u8, MODE> Pin<P, N, Output<MODE>> {
317336
}
318337
}
319338

320-
impl<const P: char, const N: u8> Pin<P, N, Output<OpenDrain>> {
321-
/// Enables / disables the internal pull up
322-
pub fn internal_pull_up(self, on: bool) -> Self {
323-
let offset = 2 * { N };
324-
let value = if on { 0b01 } else { 0b00 };
325-
unsafe {
326-
(*Gpio::<P>::ptr())
327-
.pupdr
328-
.modify(|r, w| w.bits((r.bits() & !(0b11 << offset)) | (value << offset)))
329-
};
330-
331-
self
332-
}
333-
334-
/// Enables / disables the internal pull down
335-
pub fn internal_pull_down(self, on: bool) -> Self {
339+
impl<const P: char, const N: u8, MODE> Pin<P, N, MODE> {
340+
/// Set the internal pull-up and pull-down resistor
341+
fn _internal_resistor(self, resistor: Pull) -> Self {
336342
let offset = 2 * { N };
337-
let value = if on { 0b10 } else { 0b00 };
343+
let value = resistor as u32;
338344
unsafe {
339345
(*Gpio::<P>::ptr())
340346
.pupdr
@@ -345,58 +351,31 @@ impl<const P: char, const N: u8> Pin<P, N, Output<OpenDrain>> {
345351
}
346352
}
347353

348-
impl<const P: char, const N: u8, const A: u8> Pin<P, N, Alternate<A, PushPull>> {
349-
/// Set pin speed
350-
pub fn set_speed(self, speed: Speed) -> Self {
351-
let offset = 2 * { N };
352-
353-
unsafe {
354-
(*Gpio::<P>::ptr())
355-
.ospeedr
356-
.modify(|r, w| w.bits((r.bits() & !(0b11 << offset)) | ((speed as u32) << offset)))
357-
};
358-
359-
self
354+
impl<const P: char, const N: u8, MODE> Pin<P, N, MODE>
355+
where
356+
MODE: sealed::Active,
357+
{
358+
/// Set the internal pull-up and pull-down resistor
359+
pub fn internal_resistor(self, resistor: Pull) -> Self {
360+
self._internal_resistor(resistor)
360361
}
361362

362363
/// Enables / disables the internal pull up
363364
pub fn internal_pull_up(self, on: bool) -> Self {
364-
let offset = 2 * { N };
365-
let value = if on { 0b01 } else { 0b00 };
366-
unsafe {
367-
(*Gpio::<P>::ptr())
368-
.pupdr
369-
.modify(|r, w| w.bits((r.bits() & !(0b11 << offset)) | (value << offset)))
370-
};
371-
372-
self
365+
if on {
366+
self.internal_resistor(Pull::Up)
367+
} else {
368+
self.internal_resistor(Pull::None)
369+
}
373370
}
374371

375372
/// Enables / disables the internal pull down
376373
pub fn internal_pull_down(self, on: bool) -> Self {
377-
let offset = 2 * { N };
378-
let value = if on { 0b10 } else { 0b00 };
379-
unsafe {
380-
(*Gpio::<P>::ptr())
381-
.pupdr
382-
.modify(|r, w| w.bits((r.bits() & !(0b11 << offset)) | (value << offset)))
383-
};
384-
385-
self
386-
}
387-
}
388-
389-
impl<const P: char, const N: u8, const A: u8> Pin<P, N, Alternate<A, PushPull>> {
390-
/// Turns pin alternate configuration pin into open drain
391-
pub fn set_open_drain(self) -> Pin<P, N, Alternate<A, OpenDrain>> {
392-
let offset = { N };
393-
unsafe {
394-
(*Gpio::<P>::ptr())
395-
.otyper
396-
.modify(|r, w| w.bits(r.bits() | (1 << offset)))
397-
};
398-
399-
Pin::new()
374+
if on {
375+
self.internal_resistor(Pull::Down)
376+
} else {
377+
self.internal_resistor(Pull::None)
378+
}
400379
}
401380
}
402381

@@ -512,7 +491,7 @@ impl<const P: char, const N: u8> Pin<P, N, Output<OpenDrain>> {
512491
}
513492
}
514493

515-
impl<const P: char, const N: u8, MODE> Pin<P, N, Input<MODE>> {
494+
impl<const P: char, const N: u8> Pin<P, N, Input> {
516495
#[inline(always)]
517496
pub fn is_high(&self) -> bool {
518497
!self.is_low()
@@ -533,7 +512,7 @@ macro_rules! gpio {
533512
use crate::pac::{$GPIOX, RCC};
534513
use crate::rcc::{Enable, Reset};
535514
use super::{
536-
Floating, Input,
515+
Input,
537516
};
538517

539518
/// GPIO parts
@@ -567,7 +546,7 @@ macro_rules! gpio {
567546
pub type $PXn<MODE> = super::PEPin<$port_id, MODE>;
568547

569548
$(
570-
pub type $PXi<MODE = Input<Floating>> = super::Pin<$port_id, $i, MODE>;
549+
pub type $PXi<MODE = Input> = super::Pin<$port_id, $i, MODE>;
571550
)+
572551

573552
}

src/gpio/alt.rs

Lines changed: 7 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use super::{Alternate, Gpio, NoPin, OpenDrain, Pin, PinMode, PushPull};
1+
use super::{Alternate, NoPin, OpenDrain, Pin, PinMode, PushPull};
22
use crate::{gpio, i2c, i2s, pac, serial, spi};
33

44
pub struct Const<const A: u8>;
@@ -11,28 +11,23 @@ impl<Otype> SetAlternate<0, Otype> for NoPin {
1111
fn set_alt_mode(&mut self) {}
1212
fn restore_mode(&mut self) {}
1313
}
14-
impl<const P: char, const N: u8, MODE: PinMode, const A: u8> SetAlternate<A, PushPull>
15-
for Pin<P, N, MODE>
14+
impl<const P: char, const N: u8, MODE: PinMode + super::sealed::NotAlt, const A: u8>
15+
SetAlternate<A, PushPull> for Pin<P, N, MODE>
1616
{
1717
fn set_alt_mode(&mut self) {
18-
self.set_alternate::<A>();
18+
self.mode::<Alternate<A, PushPull>>();
1919
}
2020

2121
fn restore_mode(&mut self) {
2222
self.mode::<MODE>();
2323
}
2424
}
2525

26-
impl<const P: char, const N: u8, MODE: PinMode, const A: u8> SetAlternate<A, OpenDrain>
27-
for Pin<P, N, MODE>
26+
impl<const P: char, const N: u8, MODE: PinMode + super::sealed::NotAlt, const A: u8>
27+
SetAlternate<A, OpenDrain> for Pin<P, N, MODE>
2828
{
2929
fn set_alt_mode(&mut self) {
30-
self.set_alternate::<A>();
31-
unsafe {
32-
(*Gpio::<P>::ptr())
33-
.otyper
34-
.modify(|r, w| w.bits(r.bits() | (1 << N)))
35-
};
30+
self.mode::<Alternate<A, OpenDrain>>();
3631
}
3732

3833
fn restore_mode(&mut self) {

0 commit comments

Comments
 (0)