Upgrade to e-hal 1.0-rc1 (#295)

* Upgrade to e-hal 1.0-rc1

* e-hal is no longer alpha

* Fix for ESP IDF < 5

* Unite all delay impls in a single module

* Model delays between transactions

* SPI: Make queueing it a bit more readable

* SPI: Plug delays

* Shorten the threshold for the Delay provider

* Clippy

* Fix the examples

* SPI: Detect last transaction in the presence of delays

* SPI: Introduce CsPin

* SPI: Introduce CsPin

* SPI: Mark delays with TODO

* Clippy

* SPI: Rename CsPin to CsCtl

* Transfer_transaction not necessary
This commit is contained in:
ivmarkov 2023-09-06 09:36:48 +03:00 committed by GitHub
parent 1679d9ca83
commit bed45e741e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 738 additions and 434 deletions

View File

@ -14,6 +14,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
* Upgraded to `embedded-hal` 1.0.0-rc.1 and `embedded-hal-async` 1.0.0-rc.1 * Upgraded to `embedded-hal` 1.0.0-rc.1 and `embedded-hal-async` 1.0.0-rc.1
* OTA: `EspOtaUpdate` now parametric over time and returned by value * OTA: `EspOtaUpdate` now parametric over time and returned by value
* Dependency `esp-idf-sys` now re-exported as `esp_idf_hal::sys` * Dependency `esp-idf-sys` now re-exported as `esp_idf_hal::sys`
* Breaking change: `delay::Delay` struct extended with configurable threshold
## [0.41.2] - 2023-06-21 ## [0.41.2] - 2023-06-21

View File

@ -22,7 +22,7 @@ esp-idf-sys = { git = "https://github.com/esp-rs/esp-idf-sys" }
default = ["std", "native", "binstart"] default = ["std", "native", "binstart"]
std = ["alloc", "esp-idf-sys/std", "edge-executor?/std"] std = ["alloc", "esp-idf-sys/std", "edge-executor?/std"]
alloc = [] alloc = []
nightly = ["embedded-hal-async"] nightly = ["embedded-hal-async", "embedded-io-async"]
esp-idf-sys = ["dep:esp-idf-sys", "atomic-waker"] esp-idf-sys = ["dep:esp-idf-sys", "atomic-waker"]
riscv-ulp-hal = [] riscv-ulp-hal = []
embassy-sync = [] # Only for backwards compatibility embassy-sync = [] # Only for backwards compatibility
@ -38,10 +38,12 @@ libstart = ["esp-idf-sys/libstart"]
[dependencies] [dependencies]
nb = "1.0.0" nb = "1.0.0"
embedded-can = "0.4.1" embedded-can = "0.4.1"
embedded-hal = "=1.0.0-alpha.10" embedded-hal = "=1.0.0-rc.1"
embedded-hal-0-2 = { package = "embedded-hal", version = "0.2.7", features = ["unproven"] } embedded-hal-0-2 = { package = "embedded-hal", version = "0.2.7", features = ["unproven"] }
embedded-hal-nb = "=1.0.0-alpha.2" embedded-hal-nb = "=1.0.0-rc.1"
embedded-hal-async = { version = "0.2.0-alpha.1", optional = true } embedded-hal-async = { version = "=1.0.0-rc.1", optional = true }
embedded-io = "0.5"
embedded-io-async = { version = "0.5", optional = true }
esp-idf-sys = { version = "0.33", optional = true, default-features = false, features = ["native"] } esp-idf-sys = { version = "0.33", optional = true, default-features = false, features = ["native"] }
critical-section = { version = "1.1.1", optional = true } critical-section = { version = "1.1.1", optional = true }
heapless = "0.7" heapless = "0.7"

View File

@ -8,7 +8,7 @@
## Highlights ## Highlights
* Implements the traits of [embedded-hal](https://github.com/rust-embedded/embedded-hal) `V0.2` as well as those of `V1.0.alpha` * Implements the traits of [embedded-hal](https://github.com/rust-embedded/embedded-hal) `V0.2` as well as those of `V1.0` - both blocking and async
* Supports almost all ESP IDF drivers: GPIO, SPI, I2C, TIMER, PWM, I2S, UART, etc. * Supports almost all ESP IDF drivers: GPIO, SPI, I2C, TIMER, PWM, I2S, UART, etc.
* Blocking and `async` mode for each driver (`async` support in progress) * Blocking and `async` mode for each driver (`async` support in progress)
* Re-exports `esp-idf-sys` as `esp_idf_hal::sys` * Re-exports `esp-idf-sys` as `esp_idf_hal::sys`

View File

@ -7,7 +7,7 @@
//! Depending on your target and the board you are using you should change the pins. //! Depending on your target and the board you are using you should change the pins.
//! If your board doesn't have on-board LEDs don't forget to add an appropriate resistor. //! If your board doesn't have on-board LEDs don't forget to add an appropriate resistor.
use esp_idf_hal::delay::Delay; use esp_idf_hal::delay::FreeRtos;
use esp_idf_hal::gpio::*; use esp_idf_hal::gpio::*;
use esp_idf_hal::peripherals::Peripherals; use esp_idf_hal::peripherals::Peripherals;
@ -22,7 +22,7 @@ fn main() -> anyhow::Result<()> {
loop { loop {
// we are using thread::sleep here to make sure the watchdog isn't triggered // we are using thread::sleep here to make sure the watchdog isn't triggered
Delay::delay_ms(10); FreeRtos::delay_ms(10);
if button.is_high() { if button.is_high() {
led.set_low()?; led.set_low()?;

View File

@ -1,4 +1,4 @@
use esp_idf_hal::sys::{self as _, EspError, TaskHandle_t}; // If using the `binstart` feature of `esp-idf-sys`, always keep this module imported use esp_idf_hal::sys::{EspError, TaskHandle_t}; // If using the `binstart` feature of `esp-idf-sys`, always keep this module imported
fn main() -> Result<(), EspError> { fn main() -> Result<(), EspError> {
// It is necessary to call this function once. Otherwise some patches to the runtime // It is necessary to call this function once. Otherwise some patches to the runtime

View File

@ -459,6 +459,7 @@ pub mod continuous {
use crate::delay::{self, TickType}; use crate::delay::{self, TickType};
use crate::gpio::{sealed::ADCPin as _, ADCPin}; use crate::gpio::{sealed::ADCPin as _, ADCPin};
use crate::io::EspIOError;
use crate::peripheral::Peripheral; use crate::peripheral::Peripheral;
use crate::private::notification::Notification; use crate::private::notification::Notification;
@ -903,6 +904,26 @@ pub mod continuous {
Ok(read as usize / core::mem::size_of::<AdcMeasurement>()) Ok(read as usize / core::mem::size_of::<AdcMeasurement>())
} }
pub fn read_bytes(
&mut self,
buf: &mut [u8],
timeout: TickType_t,
) -> Result<usize, EspError> {
let mut read: u32 = 0;
esp!(unsafe {
adc_continuous_read(
self.handle,
buf.as_mut_ptr() as *mut _,
core::mem::size_of_val(buf) as _,
&mut read,
TickType(timeout).as_millis_u32(),
)
})?;
Ok(read as usize)
}
#[cfg(not(esp_idf_adc_continuous_isr_iram_safe))] #[cfg(not(esp_idf_adc_continuous_isr_iram_safe))]
pub async fn read_async(&mut self, buf: &mut [AdcMeasurement]) -> Result<usize, EspError> { pub async fn read_async(&mut self, buf: &mut [AdcMeasurement]) -> Result<usize, EspError> {
loop { loop {
@ -916,6 +937,19 @@ pub mod continuous {
} }
} }
#[cfg(not(esp_idf_adc_continuous_isr_iram_safe))]
pub async fn read_bytes_async(&mut self, buf: &mut [u8]) -> Result<usize, EspError> {
loop {
match self.read_bytes(buf, delay::NON_BLOCK) {
Ok(len) if len > 0 => return Ok(len),
Err(e) if e.code() != ESP_ERR_TIMEOUT => return Err(e),
_ => {
NOTIFIER[self.adc as usize].wait().await;
}
}
}
}
#[cfg(not(esp_idf_adc_continuous_isr_iram_safe))] #[cfg(not(esp_idf_adc_continuous_isr_iram_safe))]
extern "C" fn handle_isr( extern "C" fn handle_isr(
_handle: adc_continuous_handle_t, _handle: adc_continuous_handle_t,
@ -951,6 +985,24 @@ pub mod continuous {
unsafe impl<'d> Send for AdcDriver<'d> {} unsafe impl<'d> Send for AdcDriver<'d> {}
impl<'d> embedded_io::ErrorType for AdcDriver<'d> {
type Error = EspIOError;
}
impl<'d> embedded_io::Read for AdcDriver<'d> {
fn read(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error> {
self.read_bytes(buf, delay::BLOCK).map_err(EspIOError)
}
}
#[cfg(feature = "nightly")]
#[cfg(not(esp_idf_adc_continuous_isr_iram_safe))]
impl<'d> embedded_io_async::Read for AdcDriver<'d> {
async fn read(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error> {
self.read_bytes_async(buf).await.map_err(EspIOError)
}
}
#[cfg(not(esp_idf_adc_continuous_isr_iram_safe))] #[cfg(not(esp_idf_adc_continuous_isr_iram_safe))]
#[cfg(any(esp32c2, esp32h2, esp32c5, esp32c6, esp32p4))] // TODO: Check for esp32c5 and esp32p4 #[cfg(any(esp32c2, esp32h2, esp32c5, esp32c6, esp32p4))] // TODO: Check for esp32c5 and esp32p4
static NOTIFIER: [Notification; 1] = [Notification::new()]; static NOTIFIER: [Notification; 1] = [Notification::new()];

View File

@ -8,10 +8,6 @@ use core::{cmp::min, time::Duration};
use esp_idf_sys::*; use esp_idf_sys::*;
mod general_purpose;
pub use general_purpose::Delay;
#[allow(non_upper_case_globals)] #[allow(non_upper_case_globals)]
pub const BLOCK: TickType_t = TickType_t::MAX; pub const BLOCK: TickType_t = TickType_t::MAX;
@ -231,3 +227,69 @@ impl embedded_hal::delay::DelayUs for FreeRtos {
FreeRtos::delay_ms(ms) FreeRtos::delay_ms(ms)
} }
} }
/// A delay provider that uses [`Ets`] for delays below a certain threshold
/// and [`FreeRtos`] for delays equal or above the threshold.
#[derive(Copy, Clone)]
pub struct Delay(u32);
impl Delay {
/// Create a delay with a default threshold of 1ms
pub const fn new_default() -> Self {
Self::new(1000)
}
pub const fn new(threshold: u32) -> Self {
Self(threshold)
}
pub fn delay_us(&self, us: u32) {
if us < self.0 {
Ets::delay_us(us);
} else {
FreeRtos::delay_us(us);
}
}
pub fn delay_ms(&self, ms: u32) {
if ms * 1000 < self.0 {
Ets::delay_ms(ms);
} else {
FreeRtos::delay_ms(ms);
}
}
}
impl embedded_hal::delay::DelayUs for Delay {
fn delay_us(&mut self, us: u32) {
Delay::delay_us(self, us)
}
fn delay_ms(&mut self, ms: u32) {
Delay::delay_ms(self, ms)
}
}
impl embedded_hal_0_2::blocking::delay::DelayUs<u16> for Delay {
fn delay_us(&mut self, us: u16) {
Delay::delay_us(self, us as _);
}
}
impl embedded_hal_0_2::blocking::delay::DelayUs<u32> for Delay {
fn delay_us(&mut self, us: u32) {
Delay::delay_us(self, us);
}
}
impl embedded_hal_0_2::blocking::delay::DelayMs<u16> for Delay {
fn delay_ms(&mut self, ms: u16) {
Delay::delay_ms(self, ms as _)
}
}
impl embedded_hal_0_2::blocking::delay::DelayMs<u32> for Delay {
fn delay_ms(&mut self, ms: u32) {
Delay::delay_ms(self, ms)
}
}

View File

@ -1,58 +0,0 @@
use crate::delay::{Ets, FreeRtos};
/// A delay provider that uses [`Ets`] for delays <10ms, and [`FreeRtos`] for
/// delays >=10 ms
#[derive(Copy, Clone)]
pub struct Delay;
impl Delay {
pub fn delay_us(us: u32) {
if us < 10_000 {
Ets::delay_us(us);
} else {
FreeRtos::delay_us(us);
}
}
pub fn delay_ms(ms: u32) {
if ms < 10 {
Ets::delay_ms(ms);
} else {
FreeRtos::delay_ms(ms);
}
}
}
impl embedded_hal::delay::DelayUs for Delay {
fn delay_us(&mut self, us: u32) {
Delay::delay_us(us)
}
fn delay_ms(&mut self, ms: u32) {
Delay::delay_ms(ms)
}
}
impl embedded_hal_0_2::blocking::delay::DelayUs<u16> for Delay {
fn delay_us(&mut self, us: u16) {
Delay::delay_us(us as _);
}
}
impl embedded_hal_0_2::blocking::delay::DelayUs<u32> for Delay {
fn delay_us(&mut self, us: u32) {
Delay::delay_us(us);
}
}
impl embedded_hal_0_2::blocking::delay::DelayMs<u16> for Delay {
fn delay_ms(&mut self, ms: u16) {
Delay::delay_ms(ms as _)
}
}
impl embedded_hal_0_2::blocking::delay::DelayMs<u32> for Delay {
fn delay_ms(&mut self, ms: u32) {
Delay::delay_ms(ms)
}
}

View File

@ -22,6 +22,7 @@ use esp_idf_sys::{
#[cfg(not(esp_idf_version_major = "4"))] #[cfg(not(esp_idf_version_major = "4"))]
use crate::private::notification::Notification; use crate::private::notification::Notification;
use crate::{delay, io::EspIOError};
// For v5+, we rely configuration options for PDM/TDM support. // For v5+, we rely configuration options for PDM/TDM support.
// For v4, we have to examine the chip type. // For v4, we have to examine the chip type.
@ -1184,6 +1185,58 @@ impl<'d, Dir> I2sPort for I2sDriver<'d, Dir> {
} }
} }
impl<'d, Dir> embedded_io::ErrorType for I2sDriver<'d, Dir> {
type Error = EspIOError;
}
impl<'d, Dir> embedded_io::Read for I2sDriver<'d, Dir>
where
Dir: I2sRxSupported,
{
fn read(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error> {
self.read(buf, delay::BLOCK).map_err(EspIOError)
}
}
impl<'d, Dir> embedded_io::Write for I2sDriver<'d, Dir>
where
Dir: I2sTxSupported,
{
fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> {
self.write(buf, delay::BLOCK).map_err(EspIOError)
}
fn flush(&mut self) -> Result<(), Self::Error> {
Ok(())
}
}
#[cfg(feature = "nightly")]
#[cfg(not(esp_idf_version_major = "4"))]
impl<'d, Dir> embedded_io_async::Read for I2sDriver<'d, Dir>
where
Dir: I2sRxSupported,
{
async fn read(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error> {
self.read_async(buf).await.map_err(EspIOError)
}
}
#[cfg(feature = "nightly")]
#[cfg(not(esp_idf_version_major = "4"))]
impl<'d, Dir> embedded_io_async::Write for I2sDriver<'d, Dir>
where
Dir: I2sTxSupported,
{
async fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> {
self.write_async(buf).await.map_err(EspIOError)
}
async fn flush(&mut self) -> Result<(), Self::Error> {
Ok(())
}
}
/// C-facing ISR dispatcher for on_send_* callbacks. /// C-facing ISR dispatcher for on_send_* callbacks.
#[cfg(not(esp_idf_version_major = "4"))] #[cfg(not(esp_idf_version_major = "4"))]
unsafe extern "C" fn dispatch_send( unsafe extern "C" fn dispatch_send(

31
src/io.rs Normal file
View File

@ -0,0 +1,31 @@
//! Error types
use core::fmt::{self, Display, Formatter};
use embedded_io::{Error, ErrorKind};
use crate::sys::EspError;
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
pub struct EspIOError(pub EspError);
impl Error for EspIOError {
fn kind(&self) -> ErrorKind {
ErrorKind::Other
}
}
impl From<EspError> for EspIOError {
fn from(e: EspError) -> Self {
EspIOError(e)
}
}
impl Display for EspIOError {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
self.0.fmt(f)
}
}
#[cfg(feature = "std")]
impl std::error::Error for EspIOError {}

View File

@ -48,6 +48,8 @@ pub mod i2s;
#[cfg(not(feature = "riscv-ulp-hal"))] #[cfg(not(feature = "riscv-ulp-hal"))]
pub mod interrupt; pub mod interrupt;
#[cfg(not(feature = "riscv-ulp-hal"))] #[cfg(not(feature = "riscv-ulp-hal"))]
pub mod io;
#[cfg(not(feature = "riscv-ulp-hal"))]
pub mod ledc; pub mod ledc;
#[cfg(all( #[cfg(all(
any(all(esp32, esp_idf_eth_use_esp32_emac), esp_idf_eth_use_openeth), any(all(esp32, esp_idf_eth_use_esp32_emac), esp_idf_eth_use_openeth),

File diff suppressed because it is too large Load Diff

View File

@ -42,11 +42,13 @@ use core::mem::ManuallyDrop;
use core::ptr; use core::ptr;
use core::sync::atomic::{AtomicU8, Ordering}; use core::sync::atomic::{AtomicU8, Ordering};
use crate::delay::NON_BLOCK; use crate::delay::{self, NON_BLOCK};
use crate::gpio::*; use crate::gpio::*;
use crate::io::EspIOError;
use crate::units::*; use crate::units::*;
use embedded_hal_nb::serial::ErrorKind;
use esp_idf_sys::*; use esp_idf_sys::*;
use crate::peripheral::Peripheral; use crate::peripheral::Peripheral;
@ -422,8 +424,8 @@ pub trait Uart {
crate::embedded_hal_error!( crate::embedded_hal_error!(
SerialError, SerialError,
embedded_hal::serial::Error, embedded_hal_nb::serial::Error,
embedded_hal::serial::ErrorKind embedded_hal_nb::serial::ErrorKind
); );
/// Serial abstraction /// Serial abstraction
@ -609,8 +611,25 @@ impl<'d> Drop for UartDriver<'d> {
} }
} }
impl<'d> embedded_hal::serial::ErrorType for UartDriver<'d> { impl<'d> embedded_io::ErrorType for UartDriver<'d> {
type Error = SerialError; type Error = EspIOError;
}
impl<'d> embedded_io::Read for UartDriver<'d> {
fn read(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error> {
UartDriver::read(self, buf, delay::BLOCK).map_err(EspIOError)
}
}
impl<'d> embedded_io::Write for UartDriver<'d> {
fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> {
UartDriver::write(self, buf).map_err(EspIOError)
}
fn flush(&mut self) -> Result<(), Self::Error> {
UartDriver::flush_read(self).map_err(EspIOError)?;
UartDriver::flush_write(self).map_err(EspIOError)
}
} }
impl<'d> embedded_hal_0_2::serial::Read<u8> for UartDriver<'d> { impl<'d> embedded_hal_0_2::serial::Read<u8> for UartDriver<'d> {
@ -621,12 +640,6 @@ impl<'d> embedded_hal_0_2::serial::Read<u8> for UartDriver<'d> {
} }
} }
impl<'d> embedded_hal_nb::serial::Read<u8> for UartDriver<'d> {
fn read(&mut self) -> nb::Result<u8, Self::Error> {
embedded_hal_nb::serial::Read::read(&mut *self.rx())
}
}
impl<'d> embedded_hal_0_2::serial::Write<u8> for UartDriver<'d> { impl<'d> embedded_hal_0_2::serial::Write<u8> for UartDriver<'d> {
type Error = SerialError; type Error = SerialError;
@ -639,14 +652,24 @@ impl<'d> embedded_hal_0_2::serial::Write<u8> for UartDriver<'d> {
} }
} }
impl<'d> embedded_hal_nb::serial::Write<u8> for UartDriver<'d> { impl<'d> embedded_hal_nb::serial::ErrorType for UartDriver<'d> {
fn flush(&mut self) -> nb::Result<(), Self::Error> { type Error = SerialError;
embedded_hal_nb::serial::Write::flush(&mut *self.tx()) }
}
impl<'d> embedded_hal_nb::serial::Read<u8> for UartDriver<'d> {
fn read(&mut self) -> nb::Result<u8, Self::Error> {
embedded_hal_nb::serial::Read::read(&mut *self.rx())
}
}
impl<'d> embedded_hal_nb::serial::Write<u8> for UartDriver<'d> {
fn write(&mut self, byte: u8) -> nb::Result<(), Self::Error> { fn write(&mut self, byte: u8) -> nb::Result<(), Self::Error> {
embedded_hal_nb::serial::Write::write(&mut *self.tx(), byte) embedded_hal_nb::serial::Write::write(&mut *self.tx(), byte)
} }
fn flush(&mut self) -> nb::Result<(), Self::Error> {
embedded_hal_nb::serial::Write::flush(&mut *self.tx())
}
} }
impl<'d> core::fmt::Write for UartDriver<'d> { impl<'d> core::fmt::Write for UartDriver<'d> {
@ -655,10 +678,6 @@ impl<'d> core::fmt::Write for UartDriver<'d> {
} }
} }
impl<'d> embedded_hal::serial::ErrorType for UartRxDriver<'d> {
type Error = SerialError;
}
impl<'d> UartRxDriver<'d> { impl<'d> UartRxDriver<'d> {
/// Create a new serial receiver /// Create a new serial receiver
pub fn new<UART: Uart>( pub fn new<UART: Uart>(
@ -765,6 +784,16 @@ impl<'d> Drop for UartRxDriver<'d> {
} }
} }
impl<'d> embedded_io::ErrorType for UartRxDriver<'d> {
type Error = EspIOError;
}
impl<'d> embedded_io::Read for UartRxDriver<'d> {
fn read(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error> {
UartRxDriver::read(self, buf, delay::BLOCK).map_err(EspIOError)
}
}
impl<'d> embedded_hal_0_2::serial::Read<u8> for UartRxDriver<'d> { impl<'d> embedded_hal_0_2::serial::Read<u8> for UartRxDriver<'d> {
type Error = SerialError; type Error = SerialError;
@ -777,6 +806,10 @@ impl<'d> embedded_hal_0_2::serial::Read<u8> for UartRxDriver<'d> {
} }
} }
impl<'d> embedded_hal_nb::serial::ErrorType for UartRxDriver<'d> {
type Error = SerialError;
}
impl<'d> embedded_hal_nb::serial::Read<u8> for UartRxDriver<'d> { impl<'d> embedded_hal_nb::serial::Read<u8> for UartRxDriver<'d> {
fn read(&mut self) -> nb::Result<u8, Self::Error> { fn read(&mut self) -> nb::Result<u8, Self::Error> {
let mut buf = [0_u8]; let mut buf = [0_u8];
@ -892,8 +925,18 @@ impl<'d> Drop for UartTxDriver<'d> {
} }
} }
impl<'d> embedded_hal::serial::ErrorType for UartTxDriver<'d> { impl<'d> embedded_io::Write for UartTxDriver<'d> {
type Error = SerialError; fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> {
UartTxDriver::write(self, buf).map_err(EspIOError)
}
fn flush(&mut self) -> Result<(), Self::Error> {
UartTxDriver::flush(self).map_err(EspIOError)
}
}
impl<'d> embedded_io::ErrorType for UartTxDriver<'d> {
type Error = EspIOError;
} }
impl<'d> embedded_hal_0_2::serial::Write<u8> for UartTxDriver<'d> { impl<'d> embedded_hal_0_2::serial::Write<u8> for UartTxDriver<'d> {
@ -908,6 +951,10 @@ impl<'d> embedded_hal_0_2::serial::Write<u8> for UartTxDriver<'d> {
} }
} }
impl<'d> embedded_hal_nb::serial::ErrorType for UartTxDriver<'d> {
type Error = SerialError;
}
impl<'d> embedded_hal_nb::serial::Write<u8> for UartTxDriver<'d> { impl<'d> embedded_hal_nb::serial::Write<u8> for UartTxDriver<'d> {
fn flush(&mut self) -> nb::Result<(), Self::Error> { fn flush(&mut self) -> nb::Result<(), Self::Error> {
UartTxDriver::flush(self).map_err(to_nb_err) UartTxDriver::flush(self).map_err(to_nb_err)
@ -1108,7 +1155,7 @@ fn to_nb_err(err: EspError) -> nb::Error<SerialError> {
if err.code() == ESP_ERR_TIMEOUT { if err.code() == ESP_ERR_TIMEOUT {
nb::Error::WouldBlock nb::Error::WouldBlock
} else { } else {
nb::Error::Other(SerialError::from(err)) nb::Error::Other(SerialError::new(ErrorKind::Other, err))
} }
} }
@ -1117,7 +1164,7 @@ fn check_nb<T>(result: Result<usize, EspError>, value: T) -> nb::Result<T, Seria
Ok(1) => Ok(value), Ok(1) => Ok(value),
Ok(0) => Err(nb::Error::WouldBlock), Ok(0) => Err(nb::Error::WouldBlock),
Ok(_) => unreachable!(), Ok(_) => unreachable!(),
Err(err) => Err(nb::Error::Other(SerialError::other(err))), Err(err) => Err(nb::Error::Other(SerialError::new(ErrorKind::Other, err))),
} }
} }