diff --git a/esp-hal-common/src/lib.rs b/esp-hal-common/src/lib.rs index 67ba95a5d..6bec37053 100644 --- a/esp-hal-common/src/lib.rs +++ b/esp-hal-common/src/lib.rs @@ -7,6 +7,9 @@ pub use esp32c3 as pac; #[cfg(feature = "esp32s2")] pub use esp32s2 as pac; +pub mod prelude; +pub mod serial; pub mod timer; +pub use serial::Serial; pub use timer::Timer; diff --git a/esp32-hal/src/prelude.rs b/esp-hal-common/src/prelude.rs similarity index 100% rename from esp32-hal/src/prelude.rs rename to esp-hal-common/src/prelude.rs diff --git a/esp32-hal/src/serial.rs b/esp-hal-common/src/serial.rs similarity index 87% rename from esp32-hal/src/serial.rs rename to esp-hal-common/src/serial.rs index 8a2897089..6f34ee357 100644 --- a/esp32-hal/src/serial.rs +++ b/esp-hal-common/src/serial.rs @@ -1,15 +1,8 @@ -//! UART Functionality (UART) -//! -//! Reference: ESP32-C3 TRM v0.3 Section 20 (as TRM) -//! -//! The ESP32-C3 has two identical UART groups UART0 and UART1. -//! -//! TODO: -//! - Interrupt support - use embedded_hal::serial::{Read, Write}; -use crate::pac::{uart0::RegisterBlock, UART0, UART1, UART2}; +#[cfg(feature = "enable-esp32")] +use crate::pac::UART2; +use crate::pac::{uart0::RegisterBlock, UART0, UART1}; const UART_FIFO_SIZE: u16 = 128; @@ -96,12 +89,22 @@ pub trait Instance { /// Check if the UART TX statemachine is is idle fn is_tx_idle(&mut self) -> bool { - self.as_uart0().status.read().st_utx_out().bits() == 0x0u8 + #[cfg(feature = "enable-esp32")] + let ret = self.as_uart0().status.read().st_utx_out().bits() == 0x0u8; + #[cfg(not(feature = "enable-esp32"))] + let ret = self.as_uart0().fsm_status.read().st_utx_out().bits() == 0x0u8; + + ret } /// Check if the UART RX statemachine is is idle fn is_rx_idle(&mut self) -> bool { - self.as_uart0().status.read().st_urx_out().bits() == 0x0u8 + #[cfg(feature = "enable-esp32")] + let ret = self.as_uart0().status.read().st_urx_out().bits() == 0x0u8; + #[cfg(not(feature = "enable-esp32"))] + let ret = self.as_uart0().fsm_status.read().st_urx_out().bits() == 0x0u8; + + ret } } @@ -171,6 +174,7 @@ impl Instance for UART1 { } } +#[cfg(feature = "enable-esp32")] /// Specific instance implementation for the UART2 peripheral impl Instance for UART2 { #[inline(always)] diff --git a/esp32-hal/src/lib.rs b/esp32-hal/src/lib.rs index c96674918..56ddc28a6 100644 --- a/esp32-hal/src/lib.rs +++ b/esp32-hal/src/lib.rs @@ -2,12 +2,7 @@ pub use embedded_hal as ehal; pub use esp32 as pac; -pub use esp_hal_common::Timer; - -pub mod prelude; -pub mod serial; - -pub use serial::Serial; +pub use esp_hal_common::{prelude, Serial, Timer}; #[no_mangle] extern "C" fn DefaultHandler(_level: u32, _interrupt: pac::Interrupt) {} diff --git a/esp32c3-hal/src/lib.rs b/esp32c3-hal/src/lib.rs index 9418ef4cc..229643a18 100644 --- a/esp32c3-hal/src/lib.rs +++ b/esp32c3-hal/src/lib.rs @@ -2,11 +2,8 @@ pub use embedded_hal as ehal; pub use esp32c3 as pac; -pub use esp_hal_common::Timer; +pub use esp_hal_common::{prelude, Serial, Timer}; -pub mod prelude; pub mod rtc_cntl; -pub mod serial; pub use rtc_cntl::RtcCntl; -pub use serial::Serial; diff --git a/esp32c3-hal/src/prelude.rs b/esp32c3-hal/src/prelude.rs deleted file mode 100644 index 8a9e87a91..000000000 --- a/esp32c3-hal/src/prelude.rs +++ /dev/null @@ -1,9 +0,0 @@ -pub use embedded_hal::{ - digital::v2::{ - InputPin as _, - OutputPin as _, - StatefulOutputPin as _, - ToggleableOutputPin as _, - }, - prelude::*, -}; diff --git a/esp32c3-hal/src/serial.rs b/esp32c3-hal/src/serial.rs deleted file mode 100644 index 473e16d18..000000000 --- a/esp32c3-hal/src/serial.rs +++ /dev/null @@ -1,171 +0,0 @@ -//! UART Functionality (UART) -//! -//! Reference: ESP32-C3 TRM v0.3 Section 20 (as TRM) -//! -//! The ESP32-C3 has two identical UART groups UART0 and UART1. -//! -//! TODO: -//! - Interrupt support - -use embedded_hal::serial::{Read, Write}; - -use crate::pac::{uart0::RegisterBlock, UART0, UART1}; - -const UART_FIFO_SIZE: u16 = 128; - -/// UART-specific errors -#[derive(Debug)] -pub enum Error {} - -/// UART peripheral (UART) -pub struct Serial { - uart: T, -} - -impl Serial { - pub fn new(uart: T) -> Result { - let mut serial = Serial { uart }; - serial.uart.disable_rx_interrupts(); - serial.uart.disable_tx_interrupts(); - Ok(serial) - } -} - -pub trait Instance { - /// Return registerblock of uart instance as if it were UART0 - fn as_uart0(&self) -> &RegisterBlock; - - /// Clear and disable all tx-related interrupts - fn disable_tx_interrupts(&mut self) { - // Disable UART TX interrupts - self.as_uart0().int_clr.write(|w| { - w.txfifo_empty_int_clr() - .set_bit() - .tx_brk_done_int_clr() - .set_bit() - .tx_brk_idle_done_int_clr() - .set_bit() - .tx_done_int_clr() - .set_bit() - }); - - self.as_uart0().int_ena.write(|w| { - w.txfifo_empty_int_ena() - .clear_bit() - .tx_brk_done_int_ena() - .clear_bit() - .tx_brk_idle_done_int_ena() - .clear_bit() - .tx_done_int_ena() - .clear_bit() - }); - } - - /// Clear and disable all rx-related interrupts - fn disable_rx_interrupts(&mut self) { - // Disable UART RX interrupts - self.as_uart0().int_clr.write(|w| { - w.rxfifo_full_int_clr() - .set_bit() - .rxfifo_ovf_int_clr() - .set_bit() - .rxfifo_tout_int_clr() - .set_bit() - }); - - self.as_uart0().int_ena.write(|w| { - w.rxfifo_full_int_ena() - .clear_bit() - .rxfifo_ovf_int_ena() - .clear_bit() - .rxfifo_tout_int_ena() - .clear_bit() - }); - } - - /// Get the number of occupied entries in the tx fifo buffer - fn get_tx_fifo_count(&mut self) -> u16 { - self.as_uart0().status.read().txfifo_cnt().bits() - } - - /// Get the number of occupied entries in the rx fifo buffer - fn get_rx_fifo_count(&mut self) -> u16 { - self.as_uart0().status.read().rxfifo_cnt().bits() - } - - /// Check if the UART TX statemachine is is idle - fn is_tx_idle(&mut self) -> bool { - self.as_uart0().fsm_status.read().st_utx_out().bits() == 0x0u8 - } - - /// Check if the UART RX statemachine is is idle - fn is_rx_idle(&mut self) -> bool { - self.as_uart0().fsm_status.read().st_urx_out().bits() == 0x0u8 - } -} - -/// Write half of a serial interface -impl Write for Serial { - type Error = Error; - - /// Writes a single word to the serial interface - fn write(&mut self, word: u8) -> nb::Result<(), Self::Error> { - if self.uart.get_tx_fifo_count() >= UART_FIFO_SIZE { - Err(nb::Error::WouldBlock) - } else { - self.uart - .as_uart0() - .fifo - .write(|w| unsafe { w.rxfifo_rd_byte().bits(word) }); - Ok(()) - } - } - - /// Ensures that none of the previously written words are still buffered - fn flush(&mut self) -> nb::Result<(), Self::Error> { - if self.uart.is_tx_idle() { - Ok(()) - } else { - Err(nb::Error::WouldBlock) - } - } -} - -/// Write half of a serial interface -impl Read for Serial { - type Error = Error; - - /// Reads a single word from the serial interface - fn read(&mut self) -> nb::Result { - if self.uart.get_rx_fifo_count() > 0 { - Ok(self.uart.as_uart0().fifo.read().rxfifo_rd_byte().bits()) - } else { - Err(nb::Error::WouldBlock) - } - } -} - -impl core::fmt::Write for Serial { - fn write_str(&mut self, s: &str) -> core::fmt::Result { - s.as_bytes() - .iter() - .try_for_each(|c| nb::block!(self.write(*c))) - .map_err(|_| core::fmt::Error) - } -} - -/// Specific instance implementation for the UART0 peripheral -impl Instance for UART0 { - #[inline(always)] - fn as_uart0(&self) -> &RegisterBlock { - self - } -} - -/// Specific instance implementation for the UART1 peripheral -impl Instance for UART1 { - #[inline(always)] - fn as_uart0(&self) -> &RegisterBlock { - self - } -}