From b9fc2a6b33d8af88d95d750965f3fb8b1e9032d4 Mon Sep 17 00:00:00 2001 From: Jacob Davis-Hansson Date: Fri, 14 Apr 2023 21:05:03 +0200 Subject: [PATCH 1/3] Add ability to invert UART pins This is useful in some cases where the surrounding circuit for some reason inverts the UART signal, for instance if you're talking to a device via an optocoupler. --- embassy-rp/src/uart/mod.rs | 33 +++++++++++++++++++++++++++++---- 1 file changed, 29 insertions(+), 4 deletions(-) diff --git a/embassy-rp/src/uart/mod.rs b/embassy-rp/src/uart/mod.rs index a945f229..dfa56a84 100644 --- a/embassy-rp/src/uart/mod.rs +++ b/embassy-rp/src/uart/mod.rs @@ -6,6 +6,7 @@ use crate::dma::{AnyChannel, Channel}; use crate::gpio::sealed::Pin; use crate::gpio::AnyPin; use crate::{pac, peripherals, Peripheral}; +use crate::pac::io::vals::Inover; #[cfg(feature = "nightly")] mod buffered; @@ -53,6 +54,14 @@ pub struct Config { pub data_bits: DataBits, pub stop_bits: StopBits, pub parity: Parity, + /// Invert the tx pin output + pub invert_tx: bool, + /// Invert the rx pin input + pub invert_rx: bool, + // Invert the rts pin + pub invert_rts: bool, + // Invert the cts pin + pub invert_cts: bool, } impl Default for Config { @@ -62,6 +71,10 @@ impl Default for Config { data_bits: DataBits::DataBits8, stop_bits: StopBits::STOP1, parity: Parity::ParityNone, + invert_rx: false, + invert_tx: false, + invert_rts: false, + invert_cts: false, } } } @@ -381,19 +394,31 @@ impl<'d, T: Instance + 'd, M: Mode> Uart<'d, T, M> { let r = T::regs(); unsafe { if let Some(pin) = &tx { - pin.io().ctrl().write(|w| w.set_funcsel(2)); + pin.io().ctrl().write(|w| { + w.set_funcsel(2); + w.set_inover(if config.invert_tx { Inover::INVERT } else { Inover::NORMAL }); + }); pin.pad_ctrl().write(|w| w.set_ie(true)); } if let Some(pin) = &rx { - pin.io().ctrl().write(|w| w.set_funcsel(2)); + pin.io().ctrl().write(|w| { + w.set_funcsel(2); + w.set_inover(if config.invert_rx { Inover::INVERT } else { Inover::NORMAL }); + }); pin.pad_ctrl().write(|w| w.set_ie(true)); } if let Some(pin) = &cts { - pin.io().ctrl().write(|w| w.set_funcsel(2)); + pin.io().ctrl().write(|w| { + w.set_funcsel(2); + w.set_inover(if config.invert_cts { Inover::INVERT } else { Inover::NORMAL }); + }); pin.pad_ctrl().write(|w| w.set_ie(true)); } if let Some(pin) = &rts { - pin.io().ctrl().write(|w| w.set_funcsel(2)); + pin.io().ctrl().write(|w| { + w.set_funcsel(2); + w.set_inover(if config.invert_rts { Inover::INVERT } else { Inover::NORMAL }); + }); pin.pad_ctrl().write(|w| w.set_ie(true)); } From 81f10e136a95c33f98f5fa06ac3996bee97e66d3 Mon Sep 17 00:00:00 2001 From: Jacob Davis-Hansson Date: Sat, 15 Apr 2023 15:13:44 +0200 Subject: [PATCH 2/3] outover instead of inover --- embassy-rp/src/uart/mod.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/embassy-rp/src/uart/mod.rs b/embassy-rp/src/uart/mod.rs index dfa56a84..f7a4c5a6 100644 --- a/embassy-rp/src/uart/mod.rs +++ b/embassy-rp/src/uart/mod.rs @@ -6,7 +6,7 @@ use crate::dma::{AnyChannel, Channel}; use crate::gpio::sealed::Pin; use crate::gpio::AnyPin; use crate::{pac, peripherals, Peripheral}; -use crate::pac::io::vals::Inover; +use crate::pac::io::vals::{Inover, Outover}; #[cfg(feature = "nightly")] mod buffered; @@ -396,7 +396,7 @@ impl<'d, T: Instance + 'd, M: Mode> Uart<'d, T, M> { if let Some(pin) = &tx { pin.io().ctrl().write(|w| { w.set_funcsel(2); - w.set_inover(if config.invert_tx { Inover::INVERT } else { Inover::NORMAL }); + w.set_outover(if config.invert_tx { Outover::INVERT } else { Outover::NORMAL }); }); pin.pad_ctrl().write(|w| w.set_ie(true)); } @@ -417,7 +417,7 @@ impl<'d, T: Instance + 'd, M: Mode> Uart<'d, T, M> { if let Some(pin) = &rts { pin.io().ctrl().write(|w| { w.set_funcsel(2); - w.set_inover(if config.invert_rts { Inover::INVERT } else { Inover::NORMAL }); + w.set_outover(if config.invert_rts { Outover::INVERT } else { Outover::NORMAL }); }); pin.pad_ctrl().write(|w| w.set_ie(true)); } From 21ea98810aed1a4a820ac8cc357d66821f80c3fc Mon Sep 17 00:00:00 2001 From: Jacob Davis-Hansson Date: Tue, 18 Apr 2023 17:44:19 +0200 Subject: [PATCH 3/3] Pass rx pin to right init arg --- embassy-rp/src/uart/mod.rs | 30 +++++++++++++++++++++++------- 1 file changed, 23 insertions(+), 7 deletions(-) diff --git a/embassy-rp/src/uart/mod.rs b/embassy-rp/src/uart/mod.rs index f7a4c5a6..f9e30a78 100644 --- a/embassy-rp/src/uart/mod.rs +++ b/embassy-rp/src/uart/mod.rs @@ -5,8 +5,8 @@ use embassy_hal_common::{into_ref, PeripheralRef}; use crate::dma::{AnyChannel, Channel}; use crate::gpio::sealed::Pin; use crate::gpio::AnyPin; -use crate::{pac, peripherals, Peripheral}; use crate::pac::io::vals::{Inover, Outover}; +use crate::{pac, peripherals, Peripheral}; #[cfg(feature = "nightly")] mod buffered; @@ -180,7 +180,7 @@ impl<'d, T: Instance> UartTx<'d, T, Async> { } impl<'d, T: Instance, M: Mode> UartRx<'d, T, M> { - /// Create a new DMA-enabled UART which can only send data + /// Create a new DMA-enabled UART which can only recieve data pub fn new( _uart: impl Peripheral

+ 'd, rx: impl Peripheral

> + 'd, @@ -188,7 +188,7 @@ impl<'d, T: Instance, M: Mode> UartRx<'d, T, M> { config: Config, ) -> Self { into_ref!(rx, rx_dma); - Uart::::init(Some(rx.map_into()), None, None, None, config); + Uart::::init(None, Some(rx.map_into()), None, None, config); Self::new_inner(Some(rx_dma.map_into())) } @@ -396,28 +396,44 @@ impl<'d, T: Instance + 'd, M: Mode> Uart<'d, T, M> { if let Some(pin) = &tx { pin.io().ctrl().write(|w| { w.set_funcsel(2); - w.set_outover(if config.invert_tx { Outover::INVERT } else { Outover::NORMAL }); + w.set_outover(if config.invert_tx { + Outover::INVERT + } else { + Outover::NORMAL + }); }); pin.pad_ctrl().write(|w| w.set_ie(true)); } if let Some(pin) = &rx { pin.io().ctrl().write(|w| { w.set_funcsel(2); - w.set_inover(if config.invert_rx { Inover::INVERT } else { Inover::NORMAL }); + w.set_inover(if config.invert_rx { + Inover::INVERT + } else { + Inover::NORMAL + }); }); pin.pad_ctrl().write(|w| w.set_ie(true)); } if let Some(pin) = &cts { pin.io().ctrl().write(|w| { w.set_funcsel(2); - w.set_inover(if config.invert_cts { Inover::INVERT } else { Inover::NORMAL }); + w.set_inover(if config.invert_cts { + Inover::INVERT + } else { + Inover::NORMAL + }); }); pin.pad_ctrl().write(|w| w.set_ie(true)); } if let Some(pin) = &rts { pin.io().ctrl().write(|w| { w.set_funcsel(2); - w.set_outover(if config.invert_rts { Outover::INVERT } else { Outover::NORMAL }); + w.set_outover(if config.invert_rts { + Outover::INVERT + } else { + Outover::NORMAL + }); }); pin.pad_ctrl().write(|w| w.set_ie(true)); }