@@ -14,10 +14,12 @@ use gpiocdev::{
1414} ;
1515
1616/// Newtype around [`gpiocdev::request::Request`] that implements the `embedded-hal` traits.
17- #[ derive( Debug ) ]
17+ #[ cfg_attr ( not ( feature = "async-tokio" ) , derive( Debug ) ) ]
1818pub 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 ,
2123 line : Offset ,
2224}
2325
@@ -42,13 +44,10 @@ impl CdevPin {
4244 . with_line ( line)
4345 . request ( ) ?;
4446
45- let config = req. config ( ) ;
47+ #[ cfg( feature = "async-tokio" ) ]
48+ let req = AsyncRequest :: new ( req) ;
4649
47- Ok ( Self {
48- req : Some ( req) ,
49- config,
50- line,
51- } )
50+ Ok ( Self { req, line } )
5251 }
5352
5453 /// Creates a new pin from a [`Request`](gpiocdev::request::Request).
@@ -66,86 +65,80 @@ impl CdevPin {
6665 ) ;
6766 let line = lines[ 0 ] ;
6867
69- let config = req. config ( ) ;
68+ #[ cfg( feature = "async-tokio" ) ]
69+ let req = AsyncRequest :: new ( req) ;
7070
71- Ok ( CdevPin {
72- req : Some ( req) ,
73- config,
74- line,
75- } )
71+ Ok ( CdevPin { req, line } )
7672 }
7773
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
8179 }
8280
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+ }
8585 }
8686
87- fn config ( & self ) -> & Config {
88- & self . config
87+ fn config ( & self ) -> Config {
88+ self . request ( ) . config ( )
8989 }
9090
9191 fn is_active_low ( & self ) -> bool {
9292 self . line_config ( ) . active_low
9393 }
9494
95- fn line_config ( & self ) -> & gpiocdev:: line:: Config {
95+ fn line_config ( & self ) -> gpiocdev:: line:: Config {
9696 // 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 ( )
9898 }
9999
100100 /// 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 > {
102102 let line_config = self . line_config ( ) ;
103103
104104 if line_config. direction == Some ( gpiocdev:: line:: Direction :: Output ) {
105105 return Ok ( self ) ;
106106 }
107107
108- drop ( self . req . take ( ) ) ;
108+ let mut new_config = self . config ( ) ;
109+ new_config. as_input ( ) ;
110+ self . request ( ) . reconfigure ( & new_config) ?;
109111
110- CdevPin :: from_request ( Request :: from_config ( self . config ) . as_input ( ) . request ( ) ? )
112+ Ok ( self )
111113 }
112114
113115 /// Set this pin to output mode
114116 pub fn into_output_pin (
115- mut self ,
117+ self ,
116118 state : embedded_hal:: digital:: PinState ,
117119 ) -> Result < CdevPin , CdevPinError > {
118120 let line_config = self . line_config ( ) ;
119- let is_active_low = line_config. active_low ;
120121
121122 if line_config. direction == Some ( gpiocdev:: line:: Direction :: Output ) {
122123 return Ok ( self ) ;
123124 }
124125
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) ?;
126129
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 )
132131 }
133132
134133 #[ cfg( feature = "async-tokio" ) ]
135134 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+ }
148140
141+ self . req . read_edge_event ( ) . await ?;
149142 Ok ( ( ) )
150143 }
151144}
@@ -205,7 +198,7 @@ impl embedded_hal::digital::OutputPin for CdevPin {
205198 fn set_low ( & mut self ) -> Result < ( ) , Self :: Error > {
206199 let line = self . line ;
207200 let is_active_low = self . is_active_low ( ) ;
208- self . request ( ) ?
201+ self . request ( )
209202 . set_value (
210203 line,
211204 state_to_value ( embedded_hal:: digital:: PinState :: Low , is_active_low) ,
@@ -217,7 +210,7 @@ impl embedded_hal::digital::OutputPin for CdevPin {
217210 fn set_high ( & mut self ) -> Result < ( ) , Self :: Error > {
218211 let line = self . line ;
219212 let is_active_low = self . is_active_low ( ) ;
220- self . request ( ) ?
213+ self . request ( )
221214 . set_value (
222215 line,
223216 state_to_value ( embedded_hal:: digital:: PinState :: High , is_active_low) ,
@@ -230,7 +223,7 @@ impl embedded_hal::digital::OutputPin for CdevPin {
230223impl InputPin for CdevPin {
231224 fn is_high ( & mut self ) -> Result < bool , Self :: Error > {
232225 let line = self . line ;
233- self . request ( ) ?
226+ self . request ( )
234227 . value ( line)
235228 . map ( |val| {
236229 val == state_to_value ( embedded_hal:: digital:: PinState :: High , self . is_active_low ( ) )
0 commit comments