Skip to content

Commit 65fd627

Browse files
authored
Merge pull request #44 from GrantM11235/fix-genericbus
parallel-gpio: Fix bug with fallible pins
2 parents cf85e70 + 7add7b9 commit 65fd627

File tree

2 files changed

+34
-31
lines changed

2 files changed

+34
-31
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
1919

2020
- spi: `SPIInterface` now wraps objects that implement the `SpiDeviceWrite` trait from embedded-hal 1.0.0-alpha.10.
2121
- spi: `SPIInterface` now wraps objects that implement the `SpiDeviceWrite` trait from embedded-hal-async 0.2.0-alpha.1.
22+
- parallel-gpio: Fixed bug with fallible pins
23+
- **Breaking** parallel-gpio: `GenericxBitBus::new` is now infallible
2224

2325
## [v0.4.1] - 2021-05-10
2426

parallel-gpio/src/lib.rs

Lines changed: 32 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -23,23 +23,18 @@ macro_rules! generic_bus {
2323
/// A generic implementation of [OutputBus] using [OutputPin]s
2424
pub struct $GenericxBitBus<$($PX, )*> {
2525
pins: ($($PX, )*),
26-
last: $Word,
26+
last: Option<$Word>,
2727
}
2828

2929
impl<$($PX, )*> $GenericxBitBus<$($PX, )*>
3030
where
3131
$($PX: OutputPin, )*
3232
{
33-
/// Creates a new instance and initializes the bus to `0`.
33+
/// Creates a new bus. This does not change the state of the pins.
3434
///
3535
/// The first pin in the tuple is the least significant bit.
36-
pub fn new(pins: ($($PX, )*)) -> Result<Self> {
37-
let mut bus = Self { pins, last: $Word::MAX };
38-
39-
// By setting `last` to all ones, we ensure that this will update all the pins
40-
bus.set_value(0)?;
41-
42-
Ok(bus)
36+
pub fn new(pins: ($($PX, )*)) -> Self {
37+
Self { pins, last: None }
4338
}
4439

4540
/// Consumes the bus and returns the pins. This does not change the state of the pins.
@@ -56,38 +51,44 @@ macro_rules! generic_bus {
5651
type Word = $Word;
5752

5853
fn set_value(&mut self, value: Self::Word) -> Result {
59-
let changed = value ^ self.last;
60-
61-
// It's quite common for multiple consecutive values to be identical, e.g. when filling or
62-
// clearing the screen, so let's optimize for that case
63-
if changed != 0 {
64-
$(
65-
let mask = 1 << $x;
66-
if changed & mask != 0 {
67-
if value & mask != 0 {
68-
self.pins.$x.set_high()
69-
} else {
70-
self.pins.$x.set_low()
71-
}
72-
.map_err(|_| DisplayError::BusWriteError)?;
73-
}
74-
)*
75-
76-
self.last = value;
54+
if self.last == Some(value) {
55+
// It's quite common for multiple consecutive values to be identical, e.g. when filling or
56+
// clearing the screen, so let's optimize for that case
57+
return Ok(())
7758
}
7859

60+
// Sets self.last to None.
61+
// We will update it to Some(value) *after* all the pins are succesfully set.
62+
let last = self.last.take();
63+
64+
let changed = match last {
65+
Some(old_value) => value ^ old_value,
66+
None => !0, // all ones, this ensures that we will update all the pins
67+
};
68+
69+
$(
70+
let mask = 1 << $x;
71+
if changed & mask != 0 {
72+
if value & mask != 0 {
73+
self.pins.$x.set_high()
74+
} else {
75+
self.pins.$x.set_low()
76+
}
77+
.map_err(|_| DisplayError::BusWriteError)?;
78+
}
79+
)*
80+
81+
self.last = Some(value);
7982
Ok(())
8083
}
8184
}
8285

83-
impl<$($PX, )*> core::convert::TryFrom<($($PX, )*)>
86+
impl<$($PX, )*> From<($($PX, )*)>
8487
for $GenericxBitBus<$($PX, )*>
8588
where
8689
$($PX: OutputPin, )*
8790
{
88-
type Error = DisplayError;
89-
90-
fn try_from(pins: ($($PX, )*)) -> Result<Self> {
91+
fn from(pins: ($($PX, )*)) -> Self {
9192
Self::new(pins)
9293
}
9394
}

0 commit comments

Comments
 (0)