diff --git a/examples/button.rs b/examples/button.rs index e4a3126e6..c1326592f 100644 --- a/examples/button.rs +++ b/examples/button.rs @@ -7,9 +7,7 @@ //! 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. -use std::thread; -use std::time::Duration; - +use esp_idf_hal::delay::FreeRtos; use esp_idf_hal::gpio::*; use esp_idf_hal::peripherals::Peripherals; @@ -24,7 +22,7 @@ fn main() -> anyhow::Result<()> { loop { // we are using thread::sleep here to make sure the watchdog isn't triggered - thread::sleep(Duration::from_millis(10)); + FreeRtos::delay_ms(10); if button.is_high() { led.set_low()?; diff --git a/examples/rmt_morse_code.rs b/examples/rmt_morse_code.rs index 260805ff4..8436a33cb 100644 --- a/examples/rmt_morse_code.rs +++ b/examples/rmt_morse_code.rs @@ -65,11 +65,11 @@ fn main() -> anyhow::Result<()> { } fn send_morse_code<'d>( - channel: impl Peripheral

+ 'd, + channel: impl Peripheral

+ 'd, led: impl Peripheral

+ 'd, config: &TransmitConfig, message: &str, -) -> anyhow::Result> { +) -> anyhow::Result> { println!("Sending morse message '{}'.", message); let mut signal = VariableLengthSignal::new(); diff --git a/examples/rmt_musical_buzzer.rs b/examples/rmt_musical_buzzer.rs index 921d9a5d7..8059d94d7 100644 --- a/examples/rmt_musical_buzzer.rs +++ b/examples/rmt_musical_buzzer.rs @@ -20,7 +20,7 @@ fn main() -> anyhow::Result<()> { let led = peripherals.pins.gpio17; let channel = peripherals.rmt.channel0; let config = TransmitConfig::new().looping(Loop::Endless); - let mut tx: RmtDriver<'static, _> = RmtDriver::new(channel, led, &config)?; + let mut tx: RmtDriver<'static> = RmtDriver::new(channel, led, &config)?; loop { play_song(&mut tx, ODE_TO_JOY)?; @@ -28,10 +28,7 @@ fn main() -> anyhow::Result<()> { } } -pub fn play_song( - tx: &mut RmtDriver<'static, impl RmtChannel>, - song: &[NoteValue], -) -> anyhow::Result<()> { +pub fn play_song(tx: &mut RmtDriver<'static>, song: &[NoteValue]) -> anyhow::Result<()> { for note_value in song { play_note(tx, note_value.note.0, note_value.duration)?; } @@ -39,7 +36,7 @@ pub fn play_song( } pub fn play_note( - tx: &mut RmtDriver<'static, impl RmtChannel>, + tx: &mut RmtDriver<'static>, pitch: u16, duration: Duration, ) -> anyhow::Result<()> { diff --git a/examples/spi_loopback.rs b/examples/spi_loopback.rs index 36239161c..141c6bc5b 100644 --- a/examples/spi_loopback.rs +++ b/examples/spi_loopback.rs @@ -11,11 +11,9 @@ //! This example transfers data via SPI. //! Connect SDI and SDO pins to see the outgoing data is read as incoming data. -use std::thread; -use std::time::Duration; - use embedded_hal::spi::SpiDevice; +use esp_idf_hal::delay::FreeRtos; use esp_idf_hal::peripherals::Peripherals; use esp_idf_hal::prelude::*; use esp_idf_hal::spi::*; @@ -34,14 +32,14 @@ fn main() -> anyhow::Result<()> { println!("Starting SPI loopback test"); let config = config::Config::new().baudrate(26.MHz().into()); let mut spi = - SpiMasterDriver::::new(spi, sclk, serial_out, Some(serial_in), Some(cs), &config)?; + SpiMasterDriver::new::(spi, sclk, serial_out, Some(serial_in), Some(cs), &config)?; let mut read = [0u8; 4]; let write = [0xde, 0xad, 0xbe, 0xef]; loop { // we are using thread::sleep here to make sure the watchdog isn't triggered - thread::sleep(Duration::from_millis(500)); + FreeRtos::delay_ms(500); spi.transfer(&mut read, &write)?; println!("Wrote {:x?}, read {:x?}", write, read); } diff --git a/src/i2c.rs b/src/i2c.rs index 932d42a24..8af65c289 100644 --- a/src/i2c.rs +++ b/src/i2c.rs @@ -6,7 +6,7 @@ use esp_idf_sys::*; use crate::delay::*; use crate::gpio::*; -use crate::peripheral::{Peripheral, PeripheralRef}; +use crate::peripheral::Peripheral; use crate::units::*; pub use embedded_hal::i2c::Operation; @@ -121,29 +121,24 @@ pub trait I2c: Send { fn port() -> i2c_port_t; } -pub struct I2cMasterDriver<'d, I2C> -where - I2C: I2c, -{ - _i2c: PeripheralRef<'d, I2C>, +pub struct I2cMasterDriver<'d> { + i2c: u8, + _p: PhantomData<&'d ()>, } -impl<'d, I2C> I2cMasterDriver<'d, I2C> -where - I2C: I2c, -{ - pub fn new( - i2c: impl Peripheral

+ 'd, +impl<'d> I2cMasterDriver<'d> { + pub fn new( + _i2c: impl Peripheral

+ 'd, sda: impl Peripheral

+ 'd, scl: impl Peripheral

+ 'd, config: &config::MasterConfig, - ) -> Result, EspError> { + ) -> Result { // i2c_config_t documentation says that clock speed must be no higher than 1 MHz if config.baudrate > 1.MHz().into() { return Err(EspError::from(ESP_ERR_INVALID_ARG).unwrap()); } - crate::into_ref!(i2c, sda, scl); + crate::into_ref!(sda, scl); let sys_config = i2c_config_t { mode: i2c_mode_t_I2C_MODE_MASTER, @@ -171,7 +166,10 @@ where ) // TODO: set flags })?; - Ok(I2cMasterDriver { _i2c: i2c }) + Ok(I2cMasterDriver { + i2c: I2C::port() as _, + _p: PhantomData, + }) } pub fn read( @@ -297,22 +295,23 @@ where command_link: &CommandLink, timeout: TickType_t, ) -> Result<(), EspError> { - esp!(unsafe { i2c_master_cmd_begin(I2C::port(), command_link.0, timeout) }) + esp!(unsafe { i2c_master_cmd_begin(self.port(), command_link.0, timeout) }) + } + + pub fn port(&self) -> i2c_port_t { + self.i2c as _ } } -impl<'d, I2C: I2c> Drop for I2cMasterDriver<'d, I2C> { +impl<'d> Drop for I2cMasterDriver<'d> { fn drop(&mut self) { - esp!(unsafe { i2c_driver_delete(I2C::port()) }).unwrap(); + esp!(unsafe { i2c_driver_delete(self.port()) }).unwrap(); } } -unsafe impl<'d, I2C: I2c> Send for I2cMasterDriver<'d, I2C> {} +unsafe impl<'d> Send for I2cMasterDriver<'d> {} -impl<'d, I2C> embedded_hal_0_2::blocking::i2c::Read for I2cMasterDriver<'d, I2C> -where - I2C: I2c, -{ +impl<'d> embedded_hal_0_2::blocking::i2c::Read for I2cMasterDriver<'d> { type Error = I2cError; fn read(&mut self, addr: u8, buffer: &mut [u8]) -> Result<(), Self::Error> { @@ -320,10 +319,7 @@ where } } -impl<'d, I2C> embedded_hal_0_2::blocking::i2c::Write for I2cMasterDriver<'d, I2C> -where - I2C: I2c, -{ +impl<'d> embedded_hal_0_2::blocking::i2c::Write for I2cMasterDriver<'d> { type Error = I2cError; fn write(&mut self, addr: u8, bytes: &[u8]) -> Result<(), Self::Error> { @@ -331,10 +327,7 @@ where } } -impl<'d, I2C> embedded_hal_0_2::blocking::i2c::WriteRead for I2cMasterDriver<'d, I2C> -where - I2C: I2c, -{ +impl<'d> embedded_hal_0_2::blocking::i2c::WriteRead for I2cMasterDriver<'d> { type Error = I2cError; fn write_read(&mut self, addr: u8, bytes: &[u8], buffer: &mut [u8]) -> Result<(), Self::Error> { @@ -342,18 +335,11 @@ where } } -impl<'d, I2C> embedded_hal::i2c::ErrorType for I2cMasterDriver<'d, I2C> -where - I2C: I2c, -{ +impl<'d> embedded_hal::i2c::ErrorType for I2cMasterDriver<'d> { type Error = I2cError; } -impl<'d, I2C> embedded_hal::i2c::I2c - for I2cMasterDriver<'d, I2C> -where - I2C: I2c, -{ +impl<'d> embedded_hal::i2c::I2c for I2cMasterDriver<'d> { fn read(&mut self, addr: u8, buffer: &mut [u8]) -> Result<(), Self::Error> { I2cMasterDriver::read(self, addr, buffer, BLOCK).map_err(to_i2c_err) } @@ -409,27 +395,22 @@ fn to_i2c_err(err: EspError) -> I2cError { } } -pub struct I2cSlaveDriver<'d, I2C> -where - I2C: I2c, -{ - _i2c: PeripheralRef<'d, I2C>, +pub struct I2cSlaveDriver<'d> { + i2c: u8, + _p: PhantomData<&'d ()>, } -unsafe impl<'d, I2C: I2c> Send for I2cSlaveDriver<'d, I2C> {} +unsafe impl<'d> Send for I2cSlaveDriver<'d> {} -impl<'d, I2C> I2cSlaveDriver<'d, I2C> -where - I2C: I2c, -{ - pub fn new( - i2c: impl Peripheral

+ 'd, +impl<'d> I2cSlaveDriver<'d> { + pub fn new( + _i2c: impl Peripheral

+ 'd, sda: impl Peripheral

+ 'd, scl: impl Peripheral

+ 'd, slave_addr: u8, config: &config::SlaveConfig, ) -> Result { - crate::into_ref!(i2c, sda, scl); + crate::into_ref!(sda, scl); #[cfg(not(esp_idf_version = "4.3"))] let sys_config = i2c_config_t { @@ -476,13 +457,16 @@ where ) })?; - Ok(Self { _i2c: i2c }) + Ok(Self { + i2c: I2C::port() as _, + _p: PhantomData, + }) } pub fn read(&mut self, buffer: &mut [u8], timeout: TickType_t) -> Result { let n = unsafe { i2c_slave_read_buffer( - I2C::port(), + self.port(), buffer.as_mut_ptr(), buffer.len() as u32, timeout, @@ -499,7 +483,7 @@ where pub fn write(&mut self, bytes: &[u8], timeout: TickType_t) -> Result { let n = unsafe { i2c_slave_write_buffer( - I2C::port(), + self.port(), bytes.as_ptr() as *const u8 as *mut u8, bytes.len() as i32, timeout, @@ -512,6 +496,16 @@ where Err(EspError::from(ESP_ERR_TIMEOUT).unwrap()) } } + + pub fn port(&self) -> i2c_port_t { + self.i2c as _ + } +} + +impl<'d> Drop for I2cSlaveDriver<'d> { + fn drop(&mut self) { + esp!(unsafe { i2c_driver_delete(self.port()) }).unwrap(); + } } #[repr(u32)] diff --git a/src/ledc.rs b/src/ledc.rs index 9ba45ad98..6f88698f5 100644 --- a/src/ledc.rs +++ b/src/ledc.rs @@ -24,12 +24,13 @@ //! See the `examples/` folder of this repository for more. use core::borrow::Borrow; +use core::marker::PhantomData; use core::sync::atomic::{AtomicBool, Ordering}; use esp_idf_sys::*; use crate::gpio::OutputPin; -use crate::peripheral::{Peripheral, PeripheralRef}; +use crate::peripheral::Peripheral; use crate::task::CriticalSection; pub use chip::*; @@ -92,19 +93,18 @@ pub mod config { } /// LED Control timer driver -pub struct LedcTimerDriver<'d, T: LedcTimer> { - _timer: PeripheralRef<'d, T>, +pub struct LedcTimerDriver<'d> { + timer: u8, speed_mode: ledc_mode_t, max_duty: Duty, + _p: PhantomData<&'d ()>, } -impl<'d, T: LedcTimer> LedcTimerDriver<'d, T> { - pub fn new( - timer: impl Peripheral

+ 'd, +impl<'d> LedcTimerDriver<'d> { + pub fn new( + _timer: impl Peripheral

+ 'd, config: &config::TimerConfig, ) -> Result { - crate::into_ref!(timer); - let timer_config = ledc_timer_config_t { speed_mode: config.speed_mode, timer_num: T::timer(), @@ -122,67 +122,66 @@ impl<'d, T: LedcTimer> LedcTimerDriver<'d, T> { esp!(unsafe { ledc_timer_config(&timer_config) })?; Ok(Self { - _timer: timer, + timer: T::timer() as _, speed_mode: config.speed_mode, max_duty: config.resolution.max_duty(), + _p: PhantomData, }) } /// Pauses the timer. Operation can be resumed with [`resume_timer()`]. pub fn pause(&mut self) -> Result<(), EspError> { - esp!(unsafe { ledc_timer_pause(self.speed_mode, T::timer()) })?; + esp!(unsafe { ledc_timer_pause(self.speed_mode, self.timer()) })?; Ok(()) } /// Resumes the operation of the previously paused timer pub fn resume(&mut self) -> Result<(), EspError> { - esp!(unsafe { ledc_timer_resume(self.speed_mode, T::timer()) })?; + esp!(unsafe { ledc_timer_resume(self.speed_mode, self.timer()) })?; Ok(()) } fn reset(&mut self) -> Result<(), EspError> { - esp!(unsafe { ledc_timer_rst(self.speed_mode, T::timer()) })?; + esp!(unsafe { ledc_timer_rst(self.speed_mode, self.timer()) })?; Ok(()) } + + pub fn timer(&self) -> ledc_timer_t { + self.timer as _ + } } -impl<'d, T: LedcTimer> Drop for LedcTimerDriver<'d, T> { +impl<'d> Drop for LedcTimerDriver<'d> { fn drop(&mut self) { self.reset().unwrap(); } } -unsafe impl<'d, T: LedcTimer> Send for LedcTimerDriver<'d, T> {} +unsafe impl<'d> Send for LedcTimerDriver<'d> {} /// LED Control driver -pub struct LedcDriver<'d, C, B> -where - C: LedcChannel, -{ - _channel: PeripheralRef<'d, C>, - _timer_driver: B, +pub struct LedcDriver<'d> { + channel: u8, + timer: u8, duty: Duty, hpoint: HPoint, speed_mode: ledc_mode_t, max_duty: Duty, + _p: PhantomData<&'d ()>, } // TODO: Stop channel when the instance gets dropped. It seems that we can't // have both at the same time: a method for releasing its hardware resources // and implementing Drop. -impl<'d, C: LedcChannel, B> LedcDriver<'d, C, B> { +impl<'d> LedcDriver<'d> { /// Creates a new LED Control driver - pub fn new( - channel: impl Peripheral

+ 'd, + pub fn new>>( + _channel: impl Peripheral

+ 'd, timer_driver: B, pin: impl Peripheral

+ 'd, config: &config::TimerConfig, - ) -> Result - where - B: Borrow>, - T: LedcTimer + 'd, - { - crate::into_ref!(channel, pin); + ) -> Result { + crate::into_ref!(pin); let duty = 0; let hpoint = 0; @@ -190,7 +189,7 @@ impl<'d, C: LedcChannel, B> LedcDriver<'d, C, B> { let channel_config = ledc_channel_config_t { speed_mode: config.speed_mode, channel: C::channel(), - timer_sel: T::timer(), + timer_sel: timer_driver.borrow().timer(), intr_type: ledc_intr_type_t_LEDC_INTR_DISABLE, gpio_num: pin.pin(), duty, @@ -223,8 +222,9 @@ impl<'d, C: LedcChannel, B> LedcDriver<'d, C, B> { hpoint, speed_mode: timer_driver.borrow().speed_mode, max_duty: timer_driver.borrow().max_duty, - _channel: channel, - _timer_driver: timer_driver, + timer: timer_driver.borrow().timer() as _, + channel: C::channel() as _, + _p: PhantomData, }) } @@ -270,26 +270,34 @@ impl<'d, C: LedcChannel, B> LedcDriver<'d, C, B> { } fn stop(&mut self) -> Result<(), EspError> { - esp!(unsafe { ledc_stop(self.speed_mode, C::channel(), IDLE_LEVEL,) })?; + esp!(unsafe { ledc_stop(self.speed_mode, self.channel(), IDLE_LEVEL,) })?; Ok(()) } fn update_duty(&mut self, duty: Duty, hpoint: HPoint) -> Result<(), EspError> { - esp!(unsafe { ledc_set_duty_and_update(self.speed_mode, C::channel(), duty, hpoint) })?; + esp!(unsafe { ledc_set_duty_and_update(self.speed_mode, self.channel(), duty, hpoint) })?; Ok(()) } + + pub fn channel(&self) -> ledc_channel_t { + self.channel as _ + } + + pub fn timer(&self) -> ledc_timer_t { + self.timer as _ + } } -impl<'d, C: LedcChannel, B> Drop for LedcDriver<'d, C, B> { +impl<'d> Drop for LedcDriver<'d> { fn drop(&mut self) { self.stop().unwrap(); } } -unsafe impl<'d, C: LedcChannel, B> Send for LedcDriver<'d, C, B> {} +unsafe impl<'d> Send for LedcDriver<'d> {} // PwmPin temporarily removed from embedded-hal-1.0.alpha7 in anticipation of e-hal 1.0 release -// impl<'d, C: LedcChannel, B: Borrow>, T: LedcTimer> embedded_hal::pwm::blocking::PwmPin for LedcDriver<'d, C, B, T> { +// impl<'d> embedded_hal::pwm::blocking::PwmPin for LedcDriver<'d> { // type Duty = Duty; // type Error = EspError; @@ -314,7 +322,7 @@ unsafe impl<'d, C: LedcChannel, B> Send for LedcDriver<'d, C, B> {} // } // } -impl<'d, C: LedcChannel, B> embedded_hal_0_2::PwmPin for LedcDriver<'d, C, B> { +impl<'d> embedded_hal_0_2::PwmPin for LedcDriver<'d> { type Duty = Duty; fn disable(&mut self) { diff --git a/src/rmt.rs b/src/rmt.rs index 8fee1b8eb..35eb37cf9 100644 --- a/src/rmt.rs +++ b/src/rmt.rs @@ -52,6 +52,7 @@ //! ahead of time. use core::convert::TryFrom; +use core::marker::PhantomData; use core::time::Duration; #[cfg(feature = "alloc")] @@ -64,7 +65,7 @@ use core::cell::UnsafeCell; use esp_idf_sys::*; use crate::gpio::OutputPin; -use crate::peripheral::{Peripheral, PeripheralRef}; +use crate::peripheral::Peripheral; use crate::units::Hertz; use config::TransmitConfig; @@ -341,22 +342,23 @@ pub mod config { /// Use [`RmtDriver::start()`] or [`RmtDriver::start_blocking()`] to transmit pulses. /// /// See the [rmt module][crate::rmt] for more information. -pub struct RmtDriver<'d, C: RmtChannel> { - _channel: PeripheralRef<'d, C>, +pub struct RmtDriver<'d> { + channel: u8, + _p: PhantomData<&'d ()>, } -impl<'d, C: RmtChannel> RmtDriver<'d, C> { +impl<'d> RmtDriver<'d> { /// Initialise the rmt module with the specified pin, channel and configuration. /// /// To uninstall the driver just drop it. /// /// Internally this calls `rmt_config()` and `rmt_driver_install()`. - pub fn new( - channel: impl Peripheral

+ 'd, + pub fn new( + _channel: impl Peripheral

+ 'd, pin: impl Peripheral

+ 'd, config: &TransmitConfig, ) -> Result { - crate::into_ref!(channel, pin); + crate::into_ref!(pin); let mut flags = 0; if config.aware_dfs { @@ -396,7 +398,10 @@ impl<'d, C: RmtChannel> RmtDriver<'d, C> { esp!(rmt_driver_install(C::channel(), 0, 0))?; } - Ok(Self { _channel: channel }) + Ok(Self { + channel: C::channel() as _, + _p: PhantomData, + }) } /// Get speed of the channel’s internal counter clock. @@ -409,7 +414,7 @@ impl<'d, C: RmtChannel> RmtDriver<'d, C> { /// [rmt_get_counter_clock]: https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/peripherals/rmt.html#_CPPv421rmt_get_counter_clock13rmt_channel_tP8uint32_t pub fn counter_clock(&self) -> Result { let mut ticks_hz: u32 = 0; - esp!(unsafe { rmt_get_counter_clock(C::channel(), &mut ticks_hz) })?; + esp!(unsafe { rmt_get_counter_clock(self.channel(), &mut ticks_hz) })?; Ok(ticks_hz.into()) } @@ -436,7 +441,7 @@ impl<'d, C: RmtChannel> RmtDriver<'d, C> { S: Signal, { let items = signal.as_slice(); - esp!(unsafe { rmt_write_items(C::channel(), items.as_ptr(), items.len() as i32, block) }) + esp!(unsafe { rmt_write_items(self.channel(), items.as_ptr(), items.len() as i32, block) }) } /// Transmit all items in `iter` without blocking. @@ -458,12 +463,12 @@ impl<'d, C: RmtChannel> RmtDriver<'d, C> { let iter = Box::new(UnsafeCell::new(iter)); unsafe { esp!(rmt_translator_init( - C::channel(), + self.channel(), Some(Self::translate_iterator::), ))?; esp!(rmt_write_sample( - C::channel(), + self.channel(), Box::leak(iter) as *const _ as _, 1, false @@ -493,11 +498,11 @@ impl<'d, C: RmtChannel> RmtDriver<'d, C> { // TODO: maybe use a separate struct so that we don't have to do this when // transmitting the same iterator type. esp!(rmt_translator_init( - C::channel(), + self.channel(), Some(Self::translate_iterator::), ))?; esp!(rmt_write_sample( - C::channel(), + self.channel(), &iter as *const _ as _, 24, true @@ -563,16 +568,16 @@ impl<'d, C: RmtChannel> RmtDriver<'d, C> { /// Stop transmitting. pub fn stop(&mut self) -> Result<(), EspError> { - esp!(unsafe { rmt_tx_stop(C::channel()) }) + esp!(unsafe { rmt_tx_stop(self.channel()) }) } pub fn set_looping(&mut self, looping: config::Loop) -> Result<(), EspError> { - esp!(unsafe { rmt_set_tx_loop_mode(C::channel(), looping != config::Loop::None) })?; + esp!(unsafe { rmt_set_tx_loop_mode(self.channel(), looping != config::Loop::None) })?; #[cfg(not(any(esp32, esp32c2)))] esp!(unsafe { rmt_set_tx_loop_count( - C::channel(), + self.channel(), match looping { config::Loop::Count(count) if count > 0 && count < 1024 => count, _ => 0, @@ -582,17 +587,21 @@ impl<'d, C: RmtChannel> RmtDriver<'d, C> { Ok(()) } -} -impl<'d, C: RmtChannel> Drop for RmtDriver<'d, C> { - /// Stop transmitting and release the driver. - fn drop(&mut self) { - self.stop().unwrap(); - esp!(unsafe { rmt_driver_uninstall(C::channel()) }).unwrap(); + pub fn channel(&self) -> rmt_channel_t { + self.channel as _ } } -unsafe impl<'d, C: RmtChannel> Send for RmtDriver<'d, C> {} +impl<'d> Drop for RmtDriver<'d> { + /// Stop transmitting and release the driver. + fn drop(&mut self) { + self.stop().unwrap(); + esp!(unsafe { rmt_driver_uninstall(self.channel()) }).unwrap(); + } +} + +unsafe impl<'d> Send for RmtDriver<'d> {} /// Signal storage for [`Transmit`] in a format ready for the RMT driver. pub trait Signal { diff --git a/src/spi.rs b/src/spi.rs index 02d24670a..3d341fbea 100644 --- a/src/spi.rs +++ b/src/spi.rs @@ -30,7 +30,7 @@ use esp_idf_sys::*; use crate::delay::BLOCK; use crate::gpio::{self, InputPin, OutputPin}; -use crate::peripheral::{Peripheral, PeripheralRef}; +use crate::peripheral::Peripheral; crate::embedded_hal_error!( SpiError, @@ -299,13 +299,14 @@ impl<'d> SpiBus for SpiBusMasterDriver<'d> { } /// Master SPI abstraction -pub struct SpiMasterDriver<'d, SPI: Spi> { - _spi: PeripheralRef<'d, SPI>, +pub struct SpiMasterDriver<'d> { + host: u8, device: spi_device_handle_t, max_transfer_size: usize, + _p: PhantomData<&'d ()>, } -impl<'d> SpiMasterDriver<'d, SPI1> { +impl<'d> SpiMasterDriver<'d> { /// Create new instance of SPI controller for SPI1 /// /// SPI1 can only use fixed pin for SCLK, SDO and SDI as they are shared with SPI0. @@ -319,11 +320,9 @@ impl<'d> SpiMasterDriver<'d, SPI1> { ) -> Result { SpiMasterDriver::new_internal(spi, sclk, sdo, sdi, cs, config) } -} -impl<'d, SPI: SpiAnyPins> SpiMasterDriver<'d, SPI> { /// Create new instance of SPI controller for all others - pub fn new( + pub fn new( spi: impl Peripheral

+ 'd, sclk: impl Peripheral

+ 'd, sdo: impl Peripheral

+ 'd, @@ -333,19 +332,17 @@ impl<'d, SPI: SpiAnyPins> SpiMasterDriver<'d, SPI> { ) -> Result { SpiMasterDriver::new_internal(spi, sclk, sdo, sdi, cs, config) } -} -impl<'d, SPI: Spi> SpiMasterDriver<'d, SPI> { /// Internal implementation of new shared by all SPI controllers - fn new_internal( - spi: impl Peripheral

+ 'd, + fn new_internal( + _spi: impl Peripheral

+ 'd, sclk: impl Peripheral

+ 'd, sdo: impl Peripheral

+ 'd, sdi: Option + 'd>, cs: Option + 'd>, config: &config::Config, ) -> Result { - crate::into_ref!(spi, sclk, sdo); + crate::into_ref!(sclk, sdo); let sdi = sdi.map(|sdi| sdi.into_ref()); let cs = cs.map(|cs| cs.into_ref()); @@ -418,16 +415,21 @@ impl<'d, SPI: Spi> SpiMasterDriver<'d, SPI> { })?; Ok(Self { - _spi: spi, + host: SPI::device() as _, device: device_handle, max_transfer_size: config.dma.max_transfer_size(), + _p: PhantomData, }) } - pub fn device_handle(&mut self) -> spi_device_handle_t { + pub fn device(&self) -> spi_device_handle_t { self.device } + pub fn host(&self) -> spi_host_device_t { + self.host as _ + } + pub fn transaction( &mut self, f: impl FnOnce(&mut SpiBusMasterDriver<'d>) -> Result, @@ -465,20 +467,20 @@ impl<'d, SPI: Spi> SpiMasterDriver<'d, SPI> { } } -impl<'d, SPI: Spi> Drop for SpiMasterDriver<'d, SPI> { +impl<'d> Drop for SpiMasterDriver<'d> { fn drop(&mut self) { esp!(unsafe { spi_bus_remove_device(self.device) }).unwrap(); - esp!(unsafe { spi_bus_free(SPI::device()) }).unwrap(); + esp!(unsafe { spi_bus_free(self.host()) }).unwrap(); } } -unsafe impl<'d, SPI: Spi> Send for SpiMasterDriver<'d, SPI> {} +unsafe impl<'d> Send for SpiMasterDriver<'d> {} -impl<'d, SPI: Spi> embedded_hal::spi::ErrorType for SpiMasterDriver<'d, SPI> { +impl<'d> embedded_hal::spi::ErrorType for SpiMasterDriver<'d> { type Error = SpiError; } -impl<'d, SPI: Spi> SpiDevice for SpiMasterDriver<'d, SPI> { +impl<'d> SpiDevice for SpiMasterDriver<'d> { type Bus = SpiBusMasterDriver<'d>; fn transaction( @@ -489,7 +491,7 @@ impl<'d, SPI: Spi> SpiDevice for SpiMasterDriver<'d, SPI> { } } -impl<'d, SPI: Spi> embedded_hal_0_2::blocking::spi::Transfer for SpiMasterDriver<'d, SPI> { +impl<'d> embedded_hal_0_2::blocking::spi::Transfer for SpiMasterDriver<'d> { type Error = SpiError; fn transfer<'w>(&mut self, words: &'w mut [u8]) -> Result<&'w [u8], Self::Error> { @@ -506,7 +508,7 @@ impl<'d, SPI: Spi> embedded_hal_0_2::blocking::spi::Transfer for SpiMasterDr } } -impl<'d, SPI: Spi> embedded_hal_0_2::blocking::spi::Write for SpiMasterDriver<'d, SPI> { +impl<'d> embedded_hal_0_2::blocking::spi::Write for SpiMasterDriver<'d> { type Error = SpiError; fn write(&mut self, words: &[u8]) -> Result<(), Self::Error> { @@ -528,7 +530,7 @@ impl<'d, SPI: Spi> embedded_hal_0_2::blocking::spi::Write for SpiMasterDrive } } -impl<'d, SPI: Spi> embedded_hal_0_2::blocking::spi::WriteIter for SpiMasterDriver<'d, SPI> { +impl<'d> embedded_hal_0_2::blocking::spi::WriteIter for SpiMasterDriver<'d> { type Error = SpiError; fn write_iter(&mut self, words: WI) -> Result<(), Self::Error> @@ -563,7 +565,7 @@ impl<'d, SPI: Spi> embedded_hal_0_2::blocking::spi::WriteIter for SpiMasterD } } -impl<'d, SPI: Spi> embedded_hal_0_2::blocking::spi::Transactional for SpiMasterDriver<'d, SPI> { +impl<'d> embedded_hal_0_2::blocking::spi::Transactional for SpiMasterDriver<'d> { type Error = SpiError; fn exec<'a>( diff --git a/src/timer.rs b/src/timer.rs index 21001f985..9c407b0e2 100644 --- a/src/timer.rs +++ b/src/timer.rs @@ -1,6 +1,8 @@ +use core::marker::PhantomData; + use esp_idf_sys::*; -use crate::peripheral::{Peripheral, PeripheralRef}; +use crate::peripheral::Peripheral; #[cfg(feature = "alloc")] extern crate alloc; @@ -54,23 +56,16 @@ pub trait Timer: Send { fn index() -> timer_idx_t; } -pub struct TimerDriver<'d, TIMER> -where - TIMER: Timer, -{ - _timer: PeripheralRef<'d, TIMER>, +pub struct TimerDriver<'d> { + timer: u8, + _p: PhantomData<&'d ()>, } -impl<'d, TIMER> TimerDriver<'d, TIMER> -where - TIMER: Timer, -{ - pub fn new( - timer: impl Peripheral

+ 'd, +impl<'d> TimerDriver<'d> { + pub fn new( + _timer: impl Peripheral

+ 'd, config: &config::Config, - ) -> Result, EspError> { - crate::into_ref!(timer); - + ) -> Result { esp!(unsafe { timer_init( TIMER::group(), @@ -94,16 +89,19 @@ where ) })?; - Ok(TimerDriver { _timer: timer }) + Ok(TimerDriver { + timer: ((TIMER::group() as u8) << 4) | (TIMER::index() as u8), + _p: PhantomData, + }) } pub fn enable(&mut self, enable: bool) -> Result<(), EspError> { self.check(); if enable { - esp!(unsafe { timer_start(TIMER::group(), TIMER::index()) })?; + esp!(unsafe { timer_start(self.group(), self.index()) })?; } else { - esp!(unsafe { timer_pause(TIMER::group(), TIMER::index()) })?; + esp!(unsafe { timer_pause(self.group(), self.index()) })?; } Ok(()) @@ -111,12 +109,12 @@ where pub fn counter(&self) -> Result { let value = if crate::interrupt::active() { - unsafe { timer_group_get_counter_value_in_isr(TIMER::group(), TIMER::index()) } + unsafe { timer_group_get_counter_value_in_isr(self.group(), self.index()) } } else { let mut value = 0_u64; esp!(unsafe { - timer_get_counter_value(TIMER::group(), TIMER::index(), &mut value as *mut _) + timer_get_counter_value(self.group(), self.index(), &mut value as *mut _) })?; value @@ -128,7 +126,7 @@ where pub fn set_counter(&mut self, value: u64) -> Result<(), EspError> { self.check(); - esp!(unsafe { timer_set_counter_value(TIMER::group(), TIMER::index(), value) })?; + esp!(unsafe { timer_set_counter_value(self.group(), self.index(), value) })?; Ok(()) } @@ -137,7 +135,7 @@ where if crate::interrupt::active() { if enable { unsafe { - timer_group_enable_alarm_in_isr(TIMER::group(), TIMER::index()); + timer_group_enable_alarm_in_isr(self.group(), self.index()); } } else { panic!("Disabling alarm from an ISR is not supported"); @@ -145,8 +143,8 @@ where } else { esp!(unsafe { timer_set_alarm( - TIMER::group(), - TIMER::index(), + self.group(), + self.index(), if enable { timer_alarm_t_TIMER_ALARM_EN } else { @@ -164,7 +162,7 @@ where let mut value = 0_u64; - esp!(unsafe { timer_get_alarm_value(TIMER::group(), TIMER::index(), &mut value) })?; + esp!(unsafe { timer_get_alarm_value(self.group(), self.index(), &mut value) })?; Ok(value) } @@ -172,10 +170,10 @@ where pub fn set_alarm(&mut self, value: u64) -> Result<(), EspError> { if crate::interrupt::active() { unsafe { - timer_group_set_alarm_value_in_isr(TIMER::group(), TIMER::index(), value); + timer_group_set_alarm_value_in_isr(self.group(), self.index(), value); } } else { - esp!(unsafe { timer_set_alarm_value(TIMER::group(), TIMER::index(), value) })?; + esp!(unsafe { timer_set_alarm_value(self.group(), self.index(), value) })?; } Ok(()) @@ -184,7 +182,7 @@ where pub fn enable_interrupt(&mut self) -> Result<(), EspError> { self.check(); - esp!(unsafe { timer_enable_intr(TIMER::group(), TIMER::index()) })?; + esp!(unsafe { timer_enable_intr(self.group(), self.index()) })?; Ok(()) } @@ -192,7 +190,7 @@ where pub fn disable_interrupt(&mut self) -> Result<(), EspError> { self.check(); - esp!(unsafe { timer_disable_intr(TIMER::group(), TIMER::index()) })?; + esp!(unsafe { timer_disable_intr(self.group(), self.index()) })?; Ok(()) } @@ -209,16 +207,16 @@ where let callback: Box = Box::new(callback); - ISR_HANDLERS[(TIMER::group() * timer_group_t_TIMER_GROUP_MAX + TIMER::index()) as usize] = + ISR_HANDLERS[(self.group() * timer_group_t_TIMER_GROUP_MAX + self.index()) as usize] = Some(Box::new(callback)); esp!(timer_isr_callback_add( - TIMER::group(), - TIMER::index(), + self.group(), + self.index(), Some(Self::handle_isr), UnsafeCallback::from( ISR_HANDLERS - [(TIMER::group() * timer_group_t_TIMER_GROUP_MAX + TIMER::index()) as usize] + [(self.group() * timer_group_t_TIMER_GROUP_MAX + self.index()) as usize] .as_mut() .unwrap(), ) @@ -237,16 +235,15 @@ where unsafe { let subscribed = ISR_HANDLERS - [(TIMER::group() * timer_group_t_TIMER_GROUP_MAX + TIMER::index()) as usize] + [(self.group() * timer_group_t_TIMER_GROUP_MAX + self.index()) as usize] .is_some(); if subscribed { - esp!(timer_disable_intr(TIMER::group(), TIMER::index()))?; - esp!(timer_isr_callback_remove(TIMER::group(), TIMER::index()))?; + esp!(timer_disable_intr(self.group(), self.index()))?; + esp!(timer_isr_callback_remove(self.group(), self.index()))?; ISR_HANDLERS - [(TIMER::group() * timer_group_t_TIMER_GROUP_MAX + TIMER::index()) as usize] = - None; + [(self.group() * timer_group_t_TIMER_GROUP_MAX + self.index()) as usize] = None; } } @@ -265,20 +262,28 @@ where UnsafeCallback::from_ptr(unsafe_callback).call(); }) } + + pub fn group(&self) -> timer_group_t { + (self.timer >> 4) as _ + } + + pub fn index(&self) -> timer_idx_t { + (self.timer & 0xf) as _ + } } -impl<'d, TIMER: Timer> Drop for TimerDriver<'d, TIMER> { +impl<'d> Drop for TimerDriver<'d> { fn drop(&mut self) { #[cfg(feature = "alloc")] { self.unsubscribe().unwrap(); } - esp!(unsafe { timer_deinit(TIMER::group(), TIMER::index()) }).unwrap(); + esp!(unsafe { timer_deinit(self.group(), self.index()) }).unwrap(); } } -unsafe impl<'d, TIMER: Timer> Send for TimerDriver<'d, TIMER> {} +unsafe impl<'d> Send for TimerDriver<'d> {} #[cfg(feature = "alloc")] struct UnsafeCallback(*mut Box); diff --git a/src/uart.rs b/src/uart.rs index 172a8816a..702cd38ff 100644 --- a/src/uart.rs +++ b/src/uart.rs @@ -46,7 +46,7 @@ use crate::units::*; use esp_idf_sys::*; -use crate::peripheral::{Peripheral, PeripheralRef}; +use crate::peripheral::Peripheral; const UART_FIFO_SIZE: i32 = 128; @@ -283,33 +283,34 @@ crate::embedded_hal_error!( /// Serial abstraction /// -pub struct UartDriver<'d, UART: Uart> { - _uart: PeripheralRef<'d, UART>, - rx: UartRxDriver<'d, UART>, - tx: UartTxDriver<'d, UART>, +pub struct UartDriver<'d> { + port: u8, + _p: PhantomData<&'d ()>, } /// Serial receiver -pub struct UartRxDriver<'d, UART: Uart> { - _uart: PhantomData<&'d UART>, +pub struct UartRxDriver<'d> { + port: u8, + _p: PhantomData<&'d ()>, } /// Serial transmitter -pub struct UartTxDriver<'d, UART: Uart> { - _uart: PhantomData<&'d UART>, +pub struct UartTxDriver<'d> { + port: u8, + _p: PhantomData<&'d ()>, } -impl<'d, UART: Uart> UartDriver<'d, UART> { +impl<'d> UartDriver<'d> { /// Create a new serial driver - pub fn new( - uart: impl Peripheral

+ 'd, + pub fn new( + _uart: impl Peripheral

+ 'd, tx: impl Peripheral

+ 'd, rx: impl Peripheral

+ 'd, cts: Option + 'd>, rts: Option + 'd>, config: &config::Config, ) -> Result { - crate::into_ref!(uart, tx, rx); + crate::into_ref!(tx, rx); let cts = cts.map(|cts| cts.into_ref()); let rts = rts.map(|rts| rts.into_ref()); @@ -348,16 +349,15 @@ impl<'d, UART: Uart> UartDriver<'d, UART> { })?; Ok(Self { - _uart: uart, - rx: UartRxDriver { _uart: PhantomData }, - tx: UartTxDriver { _uart: PhantomData }, + port: UART::port() as _, + _p: PhantomData, }) } /// Change the number of stop bits pub fn change_stop_bits(&mut self, stop_bits: config::StopBits) -> Result<&mut Self, EspError> { esp_result!( - unsafe { uart_set_stop_bits(UART::port(), stop_bits.into()) }, + unsafe { uart_set_stop_bits(self.port(), stop_bits.into()) }, self ) } @@ -366,7 +366,7 @@ impl<'d, UART: Uart> UartDriver<'d, UART> { pub fn stop_bits(&self) -> Result { let mut stop_bits: uart_stop_bits_t = 0; esp_result!( - unsafe { uart_get_stop_bits(UART::port(), &mut stop_bits) }, + unsafe { uart_get_stop_bits(self.port(), &mut stop_bits) }, stop_bits.into() ) } @@ -374,7 +374,7 @@ impl<'d, UART: Uart> UartDriver<'d, UART> { /// Change the number of data bits pub fn change_data_bits(&mut self, data_bits: config::DataBits) -> Result<&mut Self, EspError> { esp_result!( - unsafe { uart_set_word_length(UART::port(), data_bits.into()) }, + unsafe { uart_set_word_length(self.port(), data_bits.into()) }, self ) } @@ -383,24 +383,21 @@ impl<'d, UART: Uart> UartDriver<'d, UART> { pub fn data_bits(&self) -> Result { let mut data_bits: uart_word_length_t = 0; esp_result!( - unsafe { uart_get_word_length(UART::port(), &mut data_bits) }, + unsafe { uart_get_word_length(self.port(), &mut data_bits) }, data_bits.into() ) } /// Change the type of parity checking pub fn change_parity(&mut self, parity: config::Parity) -> Result<&mut Self, EspError> { - esp_result!( - unsafe { uart_set_parity(UART::port(), parity.into()) }, - self - ) + esp_result!(unsafe { uart_set_parity(self.port(), parity.into()) }, self) } /// Returns the current type of parity checking pub fn parity(&self) -> Result { let mut parity: uart_parity_t = 0; esp_result!( - unsafe { uart_get_parity(UART::port(), &mut parity) }, + unsafe { uart_get_parity(self.port(), &mut parity) }, parity.into() ) } @@ -417,7 +414,7 @@ impl<'d, UART: Uart> UartDriver<'d, UART> { baudrate: T, ) -> Result<&mut Self, EspError> { esp_result!( - unsafe { uart_set_baudrate(UART::port(), baudrate.into().into()) }, + unsafe { uart_set_baudrate(self.port(), baudrate.into().into()) }, self ) } @@ -426,99 +423,117 @@ impl<'d, UART: Uart> UartDriver<'d, UART> { pub fn baudrate(&self) -> Result { let mut baudrate: u32 = 0; esp_result!( - unsafe { uart_get_baudrate(UART::port(), &mut baudrate) }, + unsafe { uart_get_baudrate(self.port(), &mut baudrate) }, baudrate.into() ) } /// Split the serial driver in separate TX and RX drivers - pub fn split(&mut self) -> (&mut UartTxDriver<'d, UART>, &mut UartRxDriver<'d, UART>) { - (&mut self.tx, &mut self.rx) + pub fn split(mut self) -> (UartTxDriver<'d>, UartRxDriver<'d>) { + (self.tx(), self.rx()) } /// Read multiple bytes into a slice pub fn read(&mut self, buf: &mut [u8], delay: TickType_t) -> Result { - self.rx.read(buf, delay) + self.rx().read(buf, delay) } /// Write multiple bytes from a slice pub fn write(&mut self, buf: &[u8]) -> Result { - self.tx.write(buf) + self.tx().write(buf) } pub fn flush_read(&mut self) -> Result<(), EspError> { - self.rx.flush() + self.rx().flush() } pub fn flush_write(&mut self) -> Result<(), EspError> { - self.tx.flush() + self.tx().flush() + } + + pub fn port(&self) -> uart_port_t { + self.port as _ + } + + fn rx(&mut self) -> UartRxDriver<'d> { + UartRxDriver { + port: self.port() as _, + _p: PhantomData, + } + } + + fn tx(&mut self) -> UartTxDriver<'d> { + UartTxDriver { + port: self.port() as _, + _p: PhantomData, + } } } -impl<'d, UART: Uart> Drop for UartDriver<'d, UART> { +impl<'d> Drop for UartDriver<'d> { fn drop(&mut self) { - esp!(unsafe { uart_driver_delete(UART::port()) }).unwrap(); + esp!(unsafe { uart_driver_delete(self.port()) }).unwrap(); } } -unsafe impl<'d, UART: Uart> Send for UartDriver<'d, UART> {} +unsafe impl<'d> Send for UartDriver<'d> {} -impl<'d, UART: Uart> embedded_hal::serial::ErrorType for UartDriver<'d, UART> { +impl<'d> embedded_hal::serial::ErrorType for UartDriver<'d> { type Error = SerialError; } -impl<'d, UART: Uart> embedded_hal_0_2::serial::Read for UartDriver<'d, UART> { +impl<'d> embedded_hal_0_2::serial::Read for UartDriver<'d> { type Error = SerialError; fn read(&mut self) -> nb::Result { - embedded_hal_0_2::serial::Read::read(&mut self.rx) + embedded_hal_0_2::serial::Read::read(&mut self.rx()) } } -impl<'d, UART: Uart> embedded_hal_nb::serial::Read for UartDriver<'d, UART> { +impl<'d> embedded_hal_nb::serial::Read for UartDriver<'d> { fn read(&mut self) -> nb::Result { - embedded_hal_nb::serial::Read::read(&mut self.rx) + embedded_hal_nb::serial::Read::read(&mut self.rx()) } } -impl<'d, UART: Uart> embedded_hal_0_2::serial::Write for UartDriver<'d, UART> { +impl<'d> embedded_hal_0_2::serial::Write for UartDriver<'d> { type Error = SerialError; fn flush(&mut self) -> nb::Result<(), Self::Error> { - embedded_hal_0_2::serial::Write::flush(&mut self.tx) + embedded_hal_0_2::serial::Write::flush(&mut self.tx()) } fn write(&mut self, byte: u8) -> nb::Result<(), Self::Error> { - embedded_hal_0_2::serial::Write::write(&mut self.tx, byte) + embedded_hal_0_2::serial::Write::write(&mut self.tx(), byte) } } -impl<'d, UART: Uart> embedded_hal_nb::serial::Write for UartDriver<'d, UART> { +impl<'d> embedded_hal_nb::serial::Write for UartDriver<'d> { fn flush(&mut self) -> nb::Result<(), Self::Error> { - embedded_hal_nb::serial::Write::flush(&mut self.tx) + embedded_hal_nb::serial::Write::flush(&mut self.tx()) } 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) } } -impl<'d, UART: Uart> core::fmt::Write for UartDriver<'d, UART> { +impl<'d> core::fmt::Write for UartDriver<'d> { fn write_str(&mut self, s: &str) -> core::fmt::Result { - self.tx.write_str(s) + self.tx().write_str(s) } } -impl<'d, UART: Uart> embedded_hal::serial::ErrorType for UartRxDriver<'d, UART> { +impl<'d> embedded_hal::serial::ErrorType for UartRxDriver<'d> { type Error = SerialError; } -impl<'d, UART: Uart> UartRxDriver<'d, UART> { +impl<'d> UartRxDriver<'d> { /// Get count of bytes in the receive FIFO pub fn count(&self) -> Result { let mut size = 0_u32; esp_result!( - unsafe { uart_get_buffered_data_len(UART::port(), &mut size) }, + unsafe { uart_get_buffered_data_len(self.port(), &mut size) }, size as u8 ) } @@ -529,7 +544,7 @@ impl<'d, UART: Uart> UartRxDriver<'d, UART> { // 0 means timeout and nothing is yet read out let len = unsafe { uart_read_bytes( - UART::port(), + self.port(), buf.as_mut_ptr() as *mut _, buf.len() as u32, delay, @@ -544,13 +559,17 @@ impl<'d, UART: Uart> UartRxDriver<'d, UART> { } pub fn flush(&self) -> Result<(), EspError> { - esp!(unsafe { uart_flush_input(UART::port()) })?; + esp!(unsafe { uart_flush_input(self.port()) })?; Ok(()) } + + pub fn port(&self) -> uart_port_t { + self.port as _ + } } -impl<'d, UART: Uart> embedded_hal_0_2::serial::Read for UartRxDriver<'d, UART> { +impl<'d> embedded_hal_0_2::serial::Read for UartRxDriver<'d> { type Error = SerialError; fn read(&mut self) -> nb::Result { @@ -562,7 +581,7 @@ impl<'d, UART: Uart> embedded_hal_0_2::serial::Read for UartRxDriver<'d, UAR } } -impl<'d, UART: Uart> embedded_hal_nb::serial::Read for UartRxDriver<'d, UART> { +impl<'d> embedded_hal_nb::serial::Read for UartRxDriver<'d> { fn read(&mut self) -> nb::Result { let mut buf = [0_u8]; @@ -572,12 +591,12 @@ impl<'d, UART: Uart> embedded_hal_nb::serial::Read for UartRxDriver<'d, UART } } -impl<'d, UART: Uart> UartTxDriver<'d, UART> { +impl<'d> UartTxDriver<'d> { /// Write multiple bytes from a slice pub fn write(&mut self, bytes: &[u8]) -> Result { // `uart_write_bytes()` returns error (-1) or how many bytes were written let len = unsafe { - uart_write_bytes(UART::port(), bytes.as_ptr() as *const _, bytes.len() as u32) + uart_write_bytes(self.port(), bytes.as_ptr() as *const _, bytes.len() as u32) }; if len >= 0 { @@ -588,17 +607,21 @@ impl<'d, UART: Uart> UartTxDriver<'d, UART> { } pub fn flush(&mut self) -> Result<(), EspError> { - esp!(unsafe { uart_wait_tx_done(UART::port(), 0) })?; + esp!(unsafe { uart_wait_tx_done(self.port(), 0) })?; Ok(()) } + + pub fn port(&self) -> uart_port_t { + self.port as _ + } } -impl<'d, UART: Uart> embedded_hal::serial::ErrorType for UartTxDriver<'d, UART> { +impl<'d> embedded_hal::serial::ErrorType for UartTxDriver<'d> { type Error = SerialError; } -impl<'d, UART: Uart> embedded_hal_0_2::serial::Write for UartTxDriver<'d, UART> { +impl<'d> embedded_hal_0_2::serial::Write for UartTxDriver<'d> { type Error = SerialError; fn flush(&mut self) -> nb::Result<(), Self::Error> { @@ -610,7 +633,7 @@ impl<'d, UART: Uart> embedded_hal_0_2::serial::Write for UartTxDriver<'d, UA } } -impl<'d, UART: Uart> embedded_hal_nb::serial::Write for UartTxDriver<'d, UART> { +impl<'d> embedded_hal_nb::serial::Write for UartTxDriver<'d> { fn flush(&mut self) -> nb::Result<(), Self::Error> { UartTxDriver::flush(self).map_err(to_nb_err) } @@ -620,7 +643,7 @@ impl<'d, UART: Uart> embedded_hal_nb::serial::Write for UartTxDriver<'d, UAR } } -impl<'d, UART: Uart> core::fmt::Write for UartTxDriver<'d, UART> { +impl<'d> core::fmt::Write for UartTxDriver<'d> { fn write_str(&mut self, s: &str) -> core::fmt::Result { let buf = s.as_bytes(); let mut offset = 0;