3
3
/// Newtype around [`gpio_cdev::LineHandle`] that implements the `embedded-hal` traits
4
4
///
5
5
/// [`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 ) ;
7
7
8
8
impl CdevPin {
9
9
/// See [`gpio_cdev::Line::request`][0] for details.
10
10
///
11
11
/// [0]: https://docs.rs/gpio-cdev/0.2.0/gpio_cdev/struct.Line.html#method.request
12
12
pub fn new ( handle : gpio_cdev:: LineHandle ) -> Result < Self , gpio_cdev:: errors:: Error > {
13
13
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;
15
33
}
16
34
}
17
35
@@ -31,7 +49,7 @@ impl embedded_hal::digital::InputPin for CdevPin {
31
49
type Error = gpio_cdev:: errors:: Error ;
32
50
33
51
fn try_is_high ( & self ) -> Result < bool , Self :: Error > {
34
- if !self . 1 {
52
+ if !self . 1 . is_active_low ( ) {
35
53
self . 0 . get_value ( ) . map ( |val| val != 0 )
36
54
} else {
37
55
self . 0 . get_value ( ) . map ( |val| val == 0 )
@@ -43,6 +61,49 @@ impl embedded_hal::digital::InputPin for CdevPin {
43
61
}
44
62
}
45
63
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
+
46
107
impl core:: ops:: Deref for CdevPin {
47
108
type Target = gpio_cdev:: LineHandle ;
48
109
0 commit comments