Skip to content

Commit ac5feff

Browse files
committed
Add stateful versions of the output pin temp conversions
1 parent 890ffc9 commit ac5feff

File tree

2 files changed

+60
-11
lines changed

2 files changed

+60
-11
lines changed

examples/multi_mode_gpio.rs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,10 @@ use panic_halt as _;
66

77
use nb::block;
88

9-
use cortex_m_semihosting::hprintln;
109
use cortex_m_rt::entry;
10+
use cortex_m_semihosting::hprintln;
1111
use embedded_hal::digital::v2::{InputPin, OutputPin};
12-
use stm32f1xx_hal::{pac, prelude::*, timer::Timer};
12+
use stm32f1xx_hal::{pac, prelude::*, timer::Timer, gpio::State};
1313

1414
#[entry]
1515
fn main() -> ! {
@@ -44,5 +44,10 @@ fn main() -> ! {
4444
out.set_low().unwrap();
4545
block!(timer.wait()).unwrap();
4646
});
47+
pin.as_push_pull_output_with_state(&mut gpioc.crh, State::High, |out| {
48+
block!(timer.wait()).unwrap();
49+
out.set_low().unwrap();
50+
block!(timer.wait()).unwrap();
51+
});
4752
}
4853
}

src/gpio.rs

Lines changed: 53 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -490,17 +490,59 @@ macro_rules! gpio {
490490
}
491491
}
492492

493-
// TODO: Add the stateful versions
494-
macro_rules! impl_temp_mode {
493+
macro_rules! impl_temp_output {
495494
(
496495
$fn_name:ident,
496+
$stateful_fn_name:ident,
497497
$mode:ty
498498
) => {
499499
/**
500500
Temporarily change the mode of the pin.
501501
502-
When changing to an output, the value of the pin is
503-
undefined.
502+
The value of the pin after conversion is undefined. If you
503+
want to control it, use `$stateful_fn_name`
504+
*/
505+
pub fn $fn_name(
506+
&mut self,
507+
cr: &mut $CR,
508+
mut f: impl FnMut(&mut $PXi<$mode>)
509+
) {
510+
let mut temp = unsafe { $PXi::<$mode>::set_mode(cr) };
511+
f(&mut temp);
512+
unsafe {
513+
Self::set_mode(cr);
514+
}
515+
}
516+
517+
/**
518+
Temporarily change the mode of the pin.
519+
520+
Note that the new state is set slightly before conversion
521+
happens. This can cause a short output glitch if switching
522+
between output modes
523+
*/
524+
pub fn $stateful_fn_name(
525+
&mut self,
526+
cr: &mut $CR,
527+
state: State,
528+
mut f: impl FnMut(&mut $PXi<$mode>)
529+
) {
530+
self.set_state(state);
531+
let mut temp = unsafe { $PXi::<$mode>::set_mode(cr) };
532+
f(&mut temp);
533+
unsafe {
534+
Self::set_mode(cr);
535+
}
536+
}
537+
}
538+
}
539+
macro_rules! impl_temp_input {
540+
(
541+
$fn_name:ident,
542+
$mode:ty
543+
) => {
544+
/**
545+
Temporarily change the mode of the pin.
504546
*/
505547
pub fn $fn_name(
506548
&mut self,
@@ -517,23 +559,25 @@ macro_rules! gpio {
517559
}
518560

519561
impl<MODE> $PXi<MODE> where MODE: Active, $PXi<MODE>: PinMode<$CR> {
520-
impl_temp_mode!(
562+
impl_temp_output!(
521563
as_push_pull_output,
564+
as_push_pull_output_with_state,
522565
Output<PushPull>
523566
);
524-
impl_temp_mode!(
567+
impl_temp_output!(
525568
as_open_drain_output,
569+
as_open_drain_output_with_state,
526570
Output<OpenDrain>
527571
);
528-
impl_temp_mode!(
572+
impl_temp_input!(
529573
as_floating_input,
530574
Input<Floating>
531575
);
532-
impl_temp_mode!(
576+
impl_temp_input!(
533577
as_pull_up_input,
534578
Input<PullUp>
535579
);
536-
impl_temp_mode!(
580+
impl_temp_input!(
537581
as_pull_down_input,
538582
Input<PullDown>
539583
);

0 commit comments

Comments
 (0)