@@ -300,6 +300,37 @@ macro_rules! gpio {
300300 }
301301 }
302302
303+ fn with_mode<M , F , R >(
304+ & mut self ,
305+ f: F
306+ ) -> R
307+ where
308+ M : PinMode ,
309+ F : FnOnce ( & mut $PXi<M >) -> R ,
310+ {
311+ struct ResetMode <' a, ORIG : PinMode > {
312+ pin: & ' a mut $PXi<ORIG >,
313+ }
314+
315+ impl <' a, ORIG : PinMode > Drop for ResetMode <' a, ORIG > {
316+ fn drop( & mut self ) {
317+ self . pin. mode:: <ORIG >( ) ;
318+ }
319+ }
320+
321+ self . mode:: <M >( ) ;
322+
323+ // This will reset the pin back to the original mode when dropped.
324+ // (so either when `with_mode` returns or when `f` unwinds)
325+ let _resetti = ResetMode { pin: self } ;
326+
327+ let mut witness = $PXi {
328+ _mode: PhantomData
329+ } ;
330+
331+ f( & mut witness)
332+ }
333+
303334 /// Configures the pin to operate as a floating input pin.
304335 pub fn into_floating_input(
305336 mut self ,
@@ -310,7 +341,18 @@ macro_rules! gpio {
310341 }
311342 }
312343
313- /// Configures the pin to operate as a pulled down input pin.
344+ /// Temporarily configures this pin as a floating input.
345+ ///
346+ /// The closure `f` is called with the reconfigured pin. After it returns,
347+ /// the pin will be configured back.
348+ pub fn with_floating_input<R >(
349+ & mut self ,
350+ f: impl FnOnce ( & mut $PXi<Input <Floating >>) -> R ,
351+ ) -> R {
352+ self . with_mode( f)
353+ }
354+
355+ /// Configures the pin to operate as a pulled-down input pin.
314356 pub fn into_pull_down_input(
315357 mut self ,
316358 ) -> $PXi<Input <PullDown >> {
@@ -320,7 +362,18 @@ macro_rules! gpio {
320362 }
321363 }
322364
323- /// Configures the pin to operate as a pulled up input pin.
365+ /// Temporarily configures this pin as a pulled-down input.
366+ ///
367+ /// The closure `f` is called with the reconfigured pin. After it returns,
368+ /// the pin will be configured back.
369+ pub fn with_pull_down_input<R >(
370+ & mut self ,
371+ f: impl FnOnce ( & mut $PXi<Input <PullDown >>) -> R ,
372+ ) -> R {
373+ self . with_mode( f)
374+ }
375+
376+ /// Configures the pin to operate as a pulled-up input pin.
324377 pub fn into_pull_up_input(
325378 mut self ,
326379 ) -> $PXi<Input <PullUp >> {
@@ -330,6 +383,17 @@ macro_rules! gpio {
330383 }
331384 }
332385
386+ /// Temporarily configures this pin as a pulled-up input.
387+ ///
388+ /// The closure `f` is called with the reconfigured pin. After it returns,
389+ /// the pin will be configured back.
390+ pub fn with_pull_up_input<R >(
391+ & mut self ,
392+ f: impl FnOnce ( & mut $PXi<Input <PullUp >>) -> R ,
393+ ) -> R {
394+ self . with_mode( f)
395+ }
396+
333397 /// Configures the pin to operate as an analog pin.
334398 pub fn into_analog(
335399 mut self ,
@@ -340,6 +404,17 @@ macro_rules! gpio {
340404 }
341405 }
342406
407+ /// Temporarily configures this pin as an analog pin.
408+ ///
409+ /// The closure `f` is called with the reconfigured pin. After it returns,
410+ /// the pin will be configured back.
411+ pub fn with_analog<R >(
412+ & mut self ,
413+ f: impl FnOnce ( & mut $PXi<Analog >) -> R ,
414+ ) -> R {
415+ self . with_mode( f)
416+ }
417+
343418 /// Configures the pin to operate as an open drain output pin.
344419 pub fn into_open_drain_output(
345420 mut self ,
@@ -350,7 +425,18 @@ macro_rules! gpio {
350425 }
351426 }
352427
353- /// Configures the pin to operate as an push pull output pin.
428+ /// Temporarily configures this pin as an open drain output.
429+ ///
430+ /// The closure `f` is called with the reconfigured pin. After it returns,
431+ /// the pin will be configured back.
432+ pub fn with_open_drain_output<R >(
433+ & mut self ,
434+ f: impl FnOnce ( & mut $PXi<Output <OpenDrain >>) -> R ,
435+ ) -> R {
436+ self . with_mode( f)
437+ }
438+
439+ /// Configures the pin to operate as an push-pull output pin.
354440 pub fn into_push_pull_output(
355441 mut self ,
356442 ) -> $PXi<Output <PushPull >> {
@@ -360,6 +446,17 @@ macro_rules! gpio {
360446 }
361447 }
362448
449+ /// Temporarily configures this pin as a push-pull output.
450+ ///
451+ /// The closure `f` is called with the reconfigured pin. After it returns,
452+ /// the pin will be configured back.
453+ pub fn with_push_pull_output<R >(
454+ & mut self ,
455+ f: impl FnOnce ( & mut $PXi<Output <PushPull >>) -> R ,
456+ ) -> R {
457+ self . with_mode( f)
458+ }
459+
363460 /// Set pin speed.
364461 pub fn set_speed( self , speed: Speed ) -> Self {
365462 let offset = 2 * $i;
0 commit comments