33/// Newtype around [`gpio_cdev::LineHandle`] that implements the `embedded-hal` traits
44///
55/// [`gpio_cdev::LineHandle`]: https://docs.rs/gpio-cdev/0.2.0/gpio_cdev/struct.LineHandle.html
6- pub struct CdevPin ( pub gpio_cdev:: LineHandle , bool ) ;
6+ pub struct CdevPin ( pub gpio_cdev:: LineHandle , gpio_cdev :: LineInfo ) ;
77
88impl CdevPin {
99 /// See [`gpio_cdev::Line::request`][0] for details.
1010 ///
1111 /// [0]: https://docs.rs/gpio-cdev/0.2.0/gpio_cdev/struct.Line.html#method.request
1212 pub fn new ( handle : gpio_cdev:: LineHandle ) -> Result < Self , gpio_cdev:: errors:: Error > {
1313 let info = handle. line ( ) . info ( ) ?;
14- Ok ( CdevPin ( handle, info. is_active_low ( ) ) )
14+ Ok ( CdevPin ( handle, info) )
15+ }
16+
17+ fn get_input_flags ( & self ) -> gpio_cdev:: LineRequestFlags {
18+ let mut flags = gpio_cdev:: LineRequestFlags :: INPUT ;
19+ if self . 1 . is_active_low ( ) {
20+ flags. insert ( gpio_cdev:: LineRequestFlags :: ACTIVE_LOW ) ;
21+ }
22+ return flags;
23+ }
24+
25+ fn get_output_flags ( & self ) -> gpio_cdev:: LineRequestFlags {
26+ let mut flags = gpio_cdev:: LineRequestFlags :: OUTPUT ;
27+ if self . 1 . is_open_drain ( ) {
28+ flags. insert ( gpio_cdev:: LineRequestFlags :: OPEN_DRAIN ) ;
29+ } else if self . 1 . is_open_source ( ) {
30+ flags. insert ( gpio_cdev:: LineRequestFlags :: OPEN_SOURCE ) ;
31+ }
32+ return flags;
1533 }
1634}
1735
@@ -31,7 +49,7 @@ impl embedded_hal::digital::InputPin for CdevPin {
3149 type Error = gpio_cdev:: errors:: Error ;
3250
3351 fn try_is_high ( & self ) -> Result < bool , Self :: Error > {
34- if !self . 1 {
52+ if !self . 1 . is_active_low ( ) {
3553 self . 0 . get_value ( ) . map ( |val| val != 0 )
3654 } else {
3755 self . 0 . get_value ( ) . map ( |val| val == 0 )
@@ -43,6 +61,49 @@ impl embedded_hal::digital::InputPin for CdevPin {
4361 }
4462}
4563
64+ impl embedded_hal:: digital:: IoPin < CdevPin , CdevPin > for CdevPin {
65+ type Error = gpio_cdev:: errors:: Error ;
66+
67+ fn try_into_input_pin ( self ) -> Result < CdevPin , Self :: Error > {
68+ if self . 1 . direction ( ) == gpio_cdev:: LineDirection :: In {
69+ return Ok ( self ) ;
70+ }
71+ let line = self . 0 . line ( ) . clone ( ) ;
72+ let input_flags = self . get_input_flags ( ) ;
73+ let consumer = self . 1 . consumer ( ) . unwrap_or ( "" ) . to_owned ( ) ;
74+
75+ // Drop self to free the line before re-requesting it in a new mode.
76+ std:: mem:: drop ( self ) ;
77+
78+ CdevPin :: new ( line. request ( input_flags, 0 , & consumer) ?)
79+ }
80+
81+ fn try_into_output_pin (
82+ self ,
83+ state : embedded_hal:: digital:: PinState ,
84+ ) -> Result < CdevPin , Self :: Error > {
85+ if self . 1 . direction ( ) == gpio_cdev:: LineDirection :: Out {
86+ return Ok ( self ) ;
87+ }
88+
89+ let line = self . 0 . line ( ) . clone ( ) ;
90+ let output_flags = self . get_output_flags ( ) ;
91+ let consumer = self . 1 . consumer ( ) . unwrap_or ( "" ) . to_owned ( ) ;
92+
93+ // Drop self to free the line before re-requesting it in a new mode.
94+ std:: mem:: drop ( self ) ;
95+
96+ CdevPin :: new ( line. request (
97+ output_flags,
98+ match state {
99+ embedded_hal:: digital:: PinState :: High => 1 ,
100+ embedded_hal:: digital:: PinState :: Low => 0 ,
101+ } ,
102+ & consumer,
103+ ) ?)
104+ }
105+ }
106+
46107impl core:: ops:: Deref for CdevPin {
47108 type Target = gpio_cdev:: LineHandle ;
48109
0 commit comments