Skip to content

Commit

Permalink
Use unwrap-infallible
Browse files Browse the repository at this point in the history
After removing `void`, we're still missing a way to explicitly unwrap
infallible results such that it is clear that no panic can occur in this
location.  Because the standard library does not yet provide a solution
to this, let's use the `unwrap-infallible` crate [1] in the meantime.

This topic was also discussed in more detail in the embedded-hal project [2].

[1]: https://crates.io/crates/unwrap-infallible
[2]: rust-embedded/embedded-hal#329
  • Loading branch information
Rahix committed Jan 13, 2024
1 parent 411b110 commit 1c08c35
Show file tree
Hide file tree
Showing 42 changed files with 188 additions and 147 deletions.
1 change: 1 addition & 0 deletions avr-hal-generic/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ paste = "1.0.0"
avr-device = "0.5.3"
embedded-storage = "0.2"
embedded-hal = "1.0"
unwrap-infallible = "0.1.5"

[dependencies.embedded-hal-v0]
version = "0.2.3"
Expand Down
2 changes: 1 addition & 1 deletion avr-hal-generic/src/adc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ impl<H, ADC: AdcOps<H>> AdcChannel<H, ADC> for Channel<H, ADC> {
/// let voltage = adc.read_blocking(&a0);
///
/// // alternatively, a non-blocking interface exists
/// let voltage = nb::block!(adc.read_nonblocking(&a0)).unwrap();
/// let voltage = nb::block!(adc.read_nonblocking(&a0)).unwrap_infallible();
/// ```
pub struct Adc<H, ADC: AdcOps<H>, CLOCK> {
p: ADC,
Expand Down
1 change: 1 addition & 0 deletions avr-hal-generic/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ pub mod wdt;
pub mod prelude {
pub use hal::prelude::*;
pub use ufmt::uWrite as _ufmt_uWrite;
pub use unwrap_infallible::UnwrapInfallible as _unwrap_infallible_UnwrapInfallible;
}

// For making certain traits unimplementable from outside this crate.
Expand Down
15 changes: 8 additions & 7 deletions avr-hal-generic/src/usart.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
use core::cmp::Ordering;
use core::marker;
use crate::prelude::*;

use crate::port;

Expand Down Expand Up @@ -219,11 +220,11 @@ pub trait UsartOps<H, RX, TX> {
/// 57600.into_baudrate(),
/// );
///
/// ufmt::uwriteln!(&mut serial, "Hello from Arduino!\r").unwrap();
/// ufmt::uwriteln!(&mut serial, "Hello from Arduino!\r").unwrap_infallible();
///
/// loop {
/// let b = nb::block!(serial.read()).unwrap();
/// ufmt::uwriteln!(&mut serial, "Got {}!\r", b).unwrap();
/// let b = nb::block!(serial.read()).unwrap_infallible();
/// ufmt::uwriteln!(&mut serial, "Got {}!\r", b).unwrap_infallible();
/// }
/// ```
pub struct Usart<H, USART: UsartOps<H, RX, TX>, RX, TX, CLOCK> {
Expand Down Expand Up @@ -278,22 +279,22 @@ impl<H, USART: UsartOps<H, RX, TX>, RX, TX, CLOCK> Usart<H, USART, RX, TX, CLOCK

/// Block until all remaining data has been transmitted.
pub fn flush(&mut self) {
nb::block!(self.p.raw_flush()).unwrap()
nb::block!(self.p.raw_flush()).unwrap_infallible()
}

/// Transmit a byte.
///
/// This method will block until the byte has been enqueued for transmission but **not** until
/// it was entirely sent.
pub fn write_byte(&mut self, byte: u8) {
nb::block!(self.p.raw_write(byte)).unwrap()
nb::block!(self.p.raw_write(byte)).unwrap_infallible()
}

/// Receive a byte.
///
/// This method will block until a byte could be received.
pub fn read_byte(&mut self) -> u8 {
nb::block!(self.p.raw_read()).unwrap()
nb::block!(self.p.raw_read()).unwrap_infallible()
}

/// Enable the interrupt for [`Event`].
Expand Down Expand Up @@ -437,7 +438,7 @@ impl<H, USART: UsartOps<H, RX, TX>, RX, TX, CLOCK> ufmt::uWrite

fn write_str(&mut self, s: &str) -> Result<(), Self::Error> {
for b in s.as_bytes().iter() {
nb::block!(self.p.raw_write(*b)).unwrap()
nb::block!(self.p.raw_write(*b)).unwrap_infallible()
}
Ok(())
}
Expand Down
9 changes: 5 additions & 4 deletions examples/arduino-diecimila/src/bin/diecimila-adc.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#![no_std]
#![no_main]

use arduino_hal::prelude::*;
use panic_halt as _;

use arduino_hal::adc;
Expand All @@ -17,8 +18,8 @@ fn main() -> ! {
adc.read_blocking(&adc::channel::Vbg),
adc.read_blocking(&adc::channel::Gnd),
);
ufmt::uwriteln!(&mut serial, "Vbandgap: {}", vbg).unwrap();
ufmt::uwriteln!(&mut serial, "Ground: {}", gnd).unwrap();
ufmt::uwriteln!(&mut serial, "Vbandgap: {}", vbg).unwrap_infallible();
ufmt::uwriteln!(&mut serial, "Ground: {}", gnd).unwrap_infallible();

// To store multiple channels in an array, we use the `into_channel()` method.
let channels: [adc::Channel; 6] = [
Expand All @@ -33,10 +34,10 @@ fn main() -> ! {
loop {
for (i, ch) in channels.iter().enumerate() {
let v = adc.read_blocking(ch);
ufmt::uwrite!(&mut serial, "A{}: {} ", i, v).unwrap();
ufmt::uwrite!(&mut serial, "A{}: {} ", i, v).unwrap_infallible();
}

ufmt::uwriteln!(&mut serial, "").unwrap();
ufmt::uwriteln!(&mut serial, "").unwrap_infallible();
arduino_hal::delay_ms(1000);
}
}
9 changes: 5 additions & 4 deletions examples/arduino-diecimila/src/bin/diecimila-i2cdetect.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#![no_std]
#![no_main]

use arduino_hal::prelude::*;
use panic_halt as _;

#[arduino_hal::entry]
Expand All @@ -16,12 +17,12 @@ fn main() -> ! {
50000,
);

ufmt::uwriteln!(&mut serial, "Write direction test:\r").unwrap();
ufmt::uwriteln!(&mut serial, "Write direction test:\r").unwrap_infallible();
i2c.i2cdetect(&mut serial, arduino_hal::i2c::Direction::Write)
.unwrap();
ufmt::uwriteln!(&mut serial, "\r\nRead direction test:\r").unwrap();
.unwrap_infallible();
ufmt::uwriteln!(&mut serial, "\r\nRead direction test:\r").unwrap_infallible();
i2c.i2cdetect(&mut serial, arduino_hal::i2c::Direction::Read)
.unwrap();
.unwrap_infallible();

loop {}
}
7 changes: 4 additions & 3 deletions examples/arduino-diecimila/src/bin/diecimila-spi-feedback.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#![no_std]
#![no_main]

use arduino_hal::prelude::*;
use arduino_hal::spi;
use embedded_hal_v0::spi::FullDuplex;
use panic_halt as _;
Expand All @@ -39,11 +40,11 @@ fn main() -> ! {

loop {
// Send a byte
nb::block!(spi.send(0b00001111)).unwrap();
nb::block!(spi.send(0b00001111)).unwrap_infallible();
// Because MISO is connected to MOSI, the read data should be the same
let data = nb::block!(spi.read()).unwrap();
let data = nb::block!(spi.read()).unwrap_infallible();

ufmt::uwriteln!(&mut serial, "data: {}\r", data).unwrap();
ufmt::uwriteln!(&mut serial, "data: {}\r", data).unwrap_infallible();
arduino_hal::delay_ms(1000);
}
}
7 changes: 4 additions & 3 deletions examples/arduino-diecimila/src/bin/diecimila-usart.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#![no_std]
#![no_main]

use arduino_hal::prelude::*;
use panic_halt as _;

use embedded_hal_v0::serial::Read;
Expand All @@ -11,13 +12,13 @@ fn main() -> ! {
let pins = arduino_hal::pins!(dp);
let mut serial = arduino_hal::default_serial!(dp, pins, 57600);

ufmt::uwriteln!(&mut serial, "Hello from Arduino!\r").unwrap();
ufmt::uwriteln!(&mut serial, "Hello from Arduino!\r").unwrap_infallible();

loop {
// Read a byte from the serial connection default
let b = nb::block!(serial.read()).unwrap();
let b = nb::block!(serial.read()).unwrap_infallible();

// Answer
ufmt::uwriteln!(&mut serial, "Got {}!\r", b).unwrap();
ufmt::uwriteln!(&mut serial, "Got {}!\r", b).unwrap_infallible();
}
}
11 changes: 6 additions & 5 deletions examples/arduino-leonardo/src/bin/leonardo-adc.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#![no_std]
#![no_main]

use arduino_hal::prelude::*;
use panic_halt as _;

use arduino_hal::adc;
Expand All @@ -18,9 +19,9 @@ fn main() -> ! {
adc.read_blocking(&adc::channel::Gnd),
adc.read_blocking(&adc::channel::Temperature),
);
ufmt::uwriteln!(&mut serial, "Vbandgap: {}", vbg).unwrap();
ufmt::uwriteln!(&mut serial, "Ground: {}", gnd).unwrap();
ufmt::uwriteln!(&mut serial, "Temperature: {}", tmp).unwrap();
ufmt::uwriteln!(&mut serial, "Vbandgap: {}", vbg).unwrap_infallible();
ufmt::uwriteln!(&mut serial, "Ground: {}", gnd).unwrap_infallible();
ufmt::uwriteln!(&mut serial, "Temperature: {}", tmp).unwrap_infallible();

let a0 = pins.a0.into_analog_input(&mut adc);
let a1 = pins.a1.into_analog_input(&mut adc);
Expand All @@ -40,10 +41,10 @@ fn main() -> ! {
];

for (i, v) in values.iter().enumerate() {
ufmt::uwrite!(&mut serial, "A{}: {} ", i, v).unwrap();
ufmt::uwrite!(&mut serial, "A{}: {} ", i, v).unwrap_infallible();
}

ufmt::uwriteln!(&mut serial, "").unwrap();
ufmt::uwriteln!(&mut serial, "").unwrap_infallible();
arduino_hal::delay_ms(1000);
}
}
9 changes: 5 additions & 4 deletions examples/arduino-leonardo/src/bin/leonardo-i2cdetect.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#![no_std]
#![no_main]

use arduino_hal::prelude::*;
use panic_halt as _;

#[arduino_hal::entry]
Expand All @@ -16,10 +17,10 @@ fn main() -> ! {
50000,
);

ufmt::uwriteln!(&mut serial, "Write direction test:\r").unwrap();
i2c.i2cdetect(&mut serial, arduino_hal::i2c::Direction::Write).unwrap();
ufmt::uwriteln!(&mut serial, "\r\nRead direction test:\r").unwrap();
i2c.i2cdetect(&mut serial, arduino_hal::i2c::Direction::Read).unwrap();
ufmt::uwriteln!(&mut serial, "Write direction test:\r").unwrap_infallible();
i2c.i2cdetect(&mut serial, arduino_hal::i2c::Direction::Write).unwrap_infallible();
ufmt::uwriteln!(&mut serial, "\r\nRead direction test:\r").unwrap_infallible();
i2c.i2cdetect(&mut serial, arduino_hal::i2c::Direction::Read).unwrap_infallible();

loop {}
}
7 changes: 4 additions & 3 deletions examples/arduino-leonardo/src/bin/leonardo-spi-feedback.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#![no_std]
#![no_main]

use arduino_hal::prelude::*;
use arduino_hal::spi;
use embedded_hal_v0::spi::FullDuplex;
use panic_halt as _;
Expand All @@ -39,11 +40,11 @@ fn main() -> ! {

loop {
// Send a byte
nb::block!(spi.send(0b00001111)).unwrap();
nb::block!(spi.send(0b00001111)).unwrap_infallible();
// Because MISO is connected to MOSI, the read data should be the same
let data = nb::block!(spi.read()).unwrap();
let data = nb::block!(spi.read()).unwrap_infallible();

ufmt::uwriteln!(&mut serial, "data: {}\r", data).unwrap();
ufmt::uwriteln!(&mut serial, "data: {}\r", data).unwrap_infallible();
arduino_hal::delay_ms(1000);
}
}
7 changes: 4 additions & 3 deletions examples/arduino-leonardo/src/bin/leonardo-usart.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#![no_std]
#![no_main]

use arduino_hal::prelude::*;
use panic_halt as _;

use embedded_hal_v0::serial::Read;
Expand All @@ -11,13 +12,13 @@ fn main() -> ! {
let pins = arduino_hal::pins!(dp);
let mut serial = arduino_hal::default_serial!(dp, pins, 57600);

ufmt::uwriteln!(&mut serial, "Hello from Arduino!\r").unwrap();
ufmt::uwriteln!(&mut serial, "Hello from Arduino!\r").unwrap_infallible();

loop {
// Read a byte from the serial connection
let b = nb::block!(serial.read()).unwrap();
let b = nb::block!(serial.read()).unwrap_infallible();

// Answer
ufmt::uwriteln!(&mut serial, "Got {}!\r", b).unwrap();
ufmt::uwriteln!(&mut serial, "Got {}!\r", b).unwrap_infallible();
}
}
9 changes: 5 additions & 4 deletions examples/arduino-mega1280/src/bin/mega1280-adc.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#![no_std]
#![no_main]

use arduino_hal::prelude::*;
use panic_halt as _;

use arduino_hal::adc;
Expand All @@ -17,8 +18,8 @@ fn main() -> ! {
adc.read_blocking(&adc::channel::Vbg),
adc.read_blocking(&adc::channel::Gnd),
);
ufmt::uwriteln!(&mut serial, "Vbandgap: {}", vbg).unwrap();
ufmt::uwriteln!(&mut serial, "Ground: {}", gnd).unwrap();
ufmt::uwriteln!(&mut serial, "Vbandgap: {}", vbg).unwrap_infallible();
ufmt::uwriteln!(&mut serial, "Ground: {}", gnd).unwrap_infallible();

// To store multiple channels in an array, we use the `into_channel()` method.
let channels: [adc::Channel; 16] = [
Expand All @@ -43,10 +44,10 @@ fn main() -> ! {
loop {
for (i, ch) in channels.iter().enumerate() {
let v = adc.read_blocking(ch);
ufmt::uwrite!(&mut serial, "A{}: {} ", i, v).unwrap();
ufmt::uwrite!(&mut serial, "A{}: {} ", i, v).unwrap_infallible();
}

ufmt::uwriteln!(&mut serial, "").unwrap();
ufmt::uwriteln!(&mut serial, "").unwrap_infallible();
arduino_hal::delay_ms(1000);
}
}
9 changes: 5 additions & 4 deletions examples/arduino-mega1280/src/bin/mega1280-i2cdetect.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#![no_std]
#![no_main]

use arduino_hal::prelude::*;
use panic_halt as _;

#[arduino_hal::entry]
Expand All @@ -16,10 +17,10 @@ fn main() -> ! {
50000,
);

ufmt::uwriteln!(&mut serial, "Write direction test:\r").unwrap();
i2c.i2cdetect(&mut serial, arduino_hal::i2c::Direction::Write).unwrap();
ufmt::uwriteln!(&mut serial, "\r\nRead direction test:\r").unwrap();
i2c.i2cdetect(&mut serial, arduino_hal::i2c::Direction::Read).unwrap();
ufmt::uwriteln!(&mut serial, "Write direction test:\r").unwrap_infallible();
i2c.i2cdetect(&mut serial, arduino_hal::i2c::Direction::Write).unwrap_infallible();
ufmt::uwriteln!(&mut serial, "\r\nRead direction test:\r").unwrap_infallible();
i2c.i2cdetect(&mut serial, arduino_hal::i2c::Direction::Read).unwrap_infallible();

loop {}
}
7 changes: 4 additions & 3 deletions examples/arduino-mega1280/src/bin/mega1280-usart.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#![no_std]
#![no_main]

use arduino_hal::prelude::*;
use panic_halt as _;

use embedded_hal_v0::serial::Read;
Expand All @@ -11,13 +12,13 @@ fn main() -> ! {
let pins = arduino_hal::pins!(dp);
let mut serial = arduino_hal::default_serial!(dp, pins, 57600);

ufmt::uwriteln!(&mut serial, "Hello from Arduino!\r").unwrap();
ufmt::uwriteln!(&mut serial, "Hello from Arduino!\r").unwrap_infallible();

loop {
// Read a byte from the serial connection
let b = nb::block!(serial.read()).unwrap();
let b = nb::block!(serial.read()).unwrap_infallible();

// Answer
ufmt::uwriteln!(&mut serial, "Got {}!\r", b).unwrap();
ufmt::uwriteln!(&mut serial, "Got {}!\r", b).unwrap_infallible();
}
}
7 changes: 4 additions & 3 deletions examples/arduino-mega1280/src/bin/mega1280spi-feedback.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#![no_std]
#![no_main]

use arduino_hal::prelude::*;
use arduino_hal::spi;
use embedded_hal_v0::spi::FullDuplex;
use panic_halt as _;
Expand All @@ -39,11 +40,11 @@ fn main() -> ! {

loop {
// Send a byte
nb::block!(spi.send(0b00001111)).unwrap();
nb::block!(spi.send(0b00001111)).unwrap_infallible();
// Because MISO is connected to MOSI, the read data should be the same
let data = nb::block!(spi.read()).unwrap();
let data = nb::block!(spi.read()).unwrap_infallible();

ufmt::uwriteln!(&mut serial, "data: {}\r", data).unwrap();
ufmt::uwriteln!(&mut serial, "data: {}\r", data).unwrap_infallible();
arduino_hal::delay_ms(1000);
}
}
Loading

0 comments on commit 1c08c35

Please sign in to comment.