@@ -14,10 +14,12 @@ use gpiocdev::{
14
14
} ;
15
15
16
16
/// Newtype around [`gpiocdev::request::Request`] that implements the `embedded-hal` traits.
17
- #[ derive( Debug ) ]
17
+ #[ cfg_attr ( not ( feature = "async-tokio" ) , derive( Debug ) ) ]
18
18
pub struct CdevPin {
19
- req : Option < Request > ,
20
- config : Config ,
19
+ #[ cfg( not( feature = "async-tokio" ) ) ]
20
+ req : Request ,
21
+ #[ cfg( feature = "async-tokio" ) ]
22
+ req : AsyncRequest ,
21
23
line : Offset ,
22
24
}
23
25
@@ -42,13 +44,10 @@ impl CdevPin {
42
44
. with_line ( line)
43
45
. request ( ) ?;
44
46
45
- let config = req. config ( ) ;
47
+ #[ cfg( feature = "async-tokio" ) ]
48
+ let req = AsyncRequest :: new ( req) ;
46
49
47
- Ok ( Self {
48
- req : Some ( req) ,
49
- config,
50
- line,
51
- } )
50
+ Ok ( Self { req, line } )
52
51
}
53
52
54
53
/// Creates a new pin from a [`Request`](gpiocdev::request::Request).
@@ -66,86 +65,80 @@ impl CdevPin {
66
65
) ;
67
66
let line = lines[ 0 ] ;
68
67
69
- let config = req. config ( ) ;
68
+ #[ cfg( feature = "async-tokio" ) ]
69
+ let req = AsyncRequest :: new ( req) ;
70
70
71
- Ok ( CdevPin {
72
- req : Some ( req) ,
73
- config,
74
- line,
75
- } )
71
+ Ok ( CdevPin { req, line } )
76
72
}
77
73
78
- fn request ( & mut self ) -> Result < & Request , gpiocdev:: Error > {
79
- if self . req . is_some ( ) {
80
- return Ok ( self . req . as_ref ( ) . unwrap ( ) ) ;
74
+ #[ inline]
75
+ fn request ( & self ) -> & Request {
76
+ #[ cfg( not( feature = "async-tokio" ) ) ]
77
+ {
78
+ & self . req
81
79
}
82
80
83
- let req = Request :: from_config ( self . config . clone ( ) ) . request ( ) ?;
84
- Ok ( self . req . insert ( req) )
81
+ #[ cfg( feature = "async-tokio" ) ]
82
+ {
83
+ self . req . as_ref ( )
84
+ }
85
85
}
86
86
87
- fn config ( & self ) -> & Config {
88
- & self . config
87
+ fn config ( & self ) -> Config {
88
+ self . request ( ) . config ( )
89
89
}
90
90
91
91
fn is_active_low ( & self ) -> bool {
92
92
self . line_config ( ) . active_low
93
93
}
94
94
95
- fn line_config ( & self ) -> & gpiocdev:: line:: Config {
95
+ fn line_config ( & self ) -> gpiocdev:: line:: Config {
96
96
// Unwrapping is fine, since `self.line` comes from a `Request` and is guaranteed to exist.
97
- self . config ( ) . line_config ( self . line ) . unwrap ( )
97
+ self . config ( ) . line_config ( self . line ) . unwrap ( ) . clone ( )
98
98
}
99
99
100
100
/// Set this pin to input mode
101
- pub fn into_input_pin ( mut self ) -> Result < CdevPin , CdevPinError > {
101
+ pub fn into_input_pin ( self ) -> Result < CdevPin , CdevPinError > {
102
102
let line_config = self . line_config ( ) ;
103
103
104
104
if line_config. direction == Some ( gpiocdev:: line:: Direction :: Output ) {
105
105
return Ok ( self ) ;
106
106
}
107
107
108
- drop ( self . req . take ( ) ) ;
108
+ let mut new_config = self . config ( ) ;
109
+ new_config. as_input ( ) ;
110
+ self . request ( ) . reconfigure ( & new_config) ?;
109
111
110
- CdevPin :: from_request ( Request :: from_config ( self . config ) . as_input ( ) . request ( ) ? )
112
+ Ok ( self )
111
113
}
112
114
113
115
/// Set this pin to output mode
114
116
pub fn into_output_pin (
115
- mut self ,
117
+ self ,
116
118
state : embedded_hal:: digital:: PinState ,
117
119
) -> Result < CdevPin , CdevPinError > {
118
120
let line_config = self . line_config ( ) ;
119
- let is_active_low = line_config. active_low ;
120
121
121
122
if line_config. direction == Some ( gpiocdev:: line:: Direction :: Output ) {
122
123
return Ok ( self ) ;
123
124
}
124
125
125
- drop ( self . req . take ( ) ) ;
126
+ let mut new_config = self . config ( ) ;
127
+ new_config. as_output ( state_to_value ( state, line_config. active_low ) ) ;
128
+ self . request ( ) . reconfigure ( & new_config) ?;
126
129
127
- CdevPin :: from_request (
128
- Request :: from_config ( self . config )
129
- . as_output ( state_to_value ( state, is_active_low) )
130
- . request ( ) ?,
131
- )
130
+ Ok ( self )
132
131
}
133
132
134
133
#[ cfg( feature = "async-tokio" ) ]
135
134
async fn wait_for_edge ( & mut self , edge : EdgeDetection ) -> Result < ( ) , CdevPinError > {
136
- let config = if let Some ( req) = self . req . take ( ) {
137
- req. config ( )
138
- } else {
139
- self . config . clone ( )
140
- } ;
141
-
142
- let req = Request :: from_config ( config)
143
- . with_edge_detection ( edge)
144
- . request ( ) ?;
145
-
146
- let req = AsyncRequest :: new ( req) ;
147
- req. read_edge_event ( ) . await ?;
135
+ if self . line_config ( ) . edge_detection != Some ( edge) {
136
+ let mut new_config = self . config ( ) ;
137
+ new_config. with_edge_detection ( edge) ;
138
+ self . request ( ) . reconfigure ( & new_config) ?;
139
+ }
148
140
141
+ self . req . read_edge_event ( ) . await ?;
149
142
Ok ( ( ) )
150
143
}
151
144
}
@@ -205,7 +198,7 @@ impl embedded_hal::digital::OutputPin for CdevPin {
205
198
fn set_low ( & mut self ) -> Result < ( ) , Self :: Error > {
206
199
let line = self . line ;
207
200
let is_active_low = self . is_active_low ( ) ;
208
- self . request ( ) ?
201
+ self . request ( )
209
202
. set_value (
210
203
line,
211
204
state_to_value ( embedded_hal:: digital:: PinState :: Low , is_active_low) ,
@@ -217,7 +210,7 @@ impl embedded_hal::digital::OutputPin for CdevPin {
217
210
fn set_high ( & mut self ) -> Result < ( ) , Self :: Error > {
218
211
let line = self . line ;
219
212
let is_active_low = self . is_active_low ( ) ;
220
- self . request ( ) ?
213
+ self . request ( )
221
214
. set_value (
222
215
line,
223
216
state_to_value ( embedded_hal:: digital:: PinState :: High , is_active_low) ,
@@ -230,7 +223,7 @@ impl embedded_hal::digital::OutputPin for CdevPin {
230
223
impl InputPin for CdevPin {
231
224
fn is_high ( & mut self ) -> Result < bool , Self :: Error > {
232
225
let line = self . line ;
233
- self . request ( ) ?
226
+ self . request ( )
234
227
. value ( line)
235
228
. map ( |val| {
236
229
val == state_to_value ( embedded_hal:: digital:: PinState :: High , self . is_active_low ( ) )
0 commit comments