Skip to content

Commit 371b6c2

Browse files
committed
Don't recreate Request.
1 parent 9162206 commit 371b6c2

File tree

1 file changed

+43
-50
lines changed

1 file changed

+43
-50
lines changed

src/cdev_pin.rs

+43-50
Original file line numberDiff line numberDiff line change
@@ -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))]
1818
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,
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 {
230223
impl 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

Comments
 (0)