From 8e151273b597f4e2cada17b5bcfc73a687af8d7a Mon Sep 17 00:00:00 2001 From: Wilfried Chauveau Date: Wed, 18 Oct 2023 19:08:39 +0100 Subject: [PATCH] Implement `send_break` support --- rp2040-hal/src/uart/peripheral.rs | 34 +++++++++++++++++++++++++++++++ rp2040-hal/src/uart/writer.rs | 34 +++++++++++++++++++++++++++++++ 2 files changed, 68 insertions(+) diff --git a/rp2040-hal/src/uart/peripheral.rs b/rp2040-hal/src/uart/peripheral.rs index 70fffbccb..160c56bc1 100644 --- a/rp2040-hal/src/uart/peripheral.rs +++ b/rp2040-hal/src/uart/peripheral.rs @@ -200,6 +200,40 @@ impl> UartPeripheral { super::reader::read_full_blocking(&self.device, buffer) } + /// Initiates a break + /// + /// If transmitting, this takes effect immediately after the current byte has completed. + /// For proper execution of the break command, this must be held for at least 2 complete frames + /// worth of time. + /// + ///
The device won’t be able to send anything while breaking.
+ /// + /// # Example + /// + /// ```no_run + /// # use rp2040_hal::uart::{Pins, ValidUartPinout, Enabled, UartPeripheral}; + /// # use rp2040_hal::pac::UART0; + /// # use rp2040_hal::typelevel::OptionTNone; + /// # use embedded_hal_0_2::blocking::delay::DelayUs; + /// # type PINS = Pins; + /// # let mut serial: UartPeripheral = unsafe { core::mem::zeroed() }; + /// # let mut timer: rp2040_hal::Timer = unsafe { core::mem::zeroed() }; + /// serial.lowlevel_break_start(); + /// // at 115_200Bps on 8N1 configuration, 20bits takes (20*10⁶)/115200 = 173.611…μs. + /// timer.delay_us(175); + /// serial.lowlevel_break_stop(); + /// ``` + pub fn lowlevel_break_start(&mut self) { + self.device.uartlcr_h().modify(|_, w| w.brk().set_bit()); + } + + /// Terminates a break condition. + /// + /// See `lowlevel_break_start` for more details. + pub fn lowlevel_break_stop(&mut self) { + self.device.uartlcr_h().modify(|_, w| w.brk().clear_bit()); + } + /// Join the reader and writer halves together back into the original Uart peripheral. /// /// A reader/writer pair can be obtained by calling [`split`]. diff --git a/rp2040-hal/src/uart/writer.rs b/rp2040-hal/src/uart/writer.rs index d90072a59..4e5a930f2 100644 --- a/rp2040-hal/src/uart/writer.rs +++ b/rp2040-hal/src/uart/writer.rs @@ -172,6 +172,40 @@ impl> Writer { pub fn disable_tx_interrupt(&mut self) { disable_tx_interrupt(&self.device) } + + /// Initiates a break + /// + /// If transmitting, this takes effect immediately after the current byte has completed. + /// For proper execution of the break command, this must be held for at least 2 complete frames + /// worth of time. + /// + ///
The device won’t be able to send anything while breaking.
+ /// + /// # Example + /// + /// ```no_run + /// # use rp2040_hal::uart::{Pins, ValidUartPinout, Enabled, UartPeripheral}; + /// # use rp2040_hal::pac::UART0; + /// # use rp2040_hal::typelevel::OptionTNone; + /// # use embedded_hal_0_2::blocking::delay::DelayUs; + /// # type PINS = Pins; + /// # let mut serial: UartPeripheral = unsafe { core::mem::zeroed() }; + /// # let mut timer: rp2040_hal::Timer = unsafe { core::mem::zeroed() }; + /// serial.lowlevel_break_start(); + /// // at 115_200Bps on 8N1 configuration, 20bits takes (20*10⁶)/115200 = 173.611…μs. + /// timer.delay_us(175); + /// serial.lowlevel_break_stop(); + /// ``` + pub fn lowlevel_break_start(&mut self) { + self.device.uartlcr_h().modify(|_, w| w.brk().set_bit()); + } + + /// Terminates a break condition. + /// + /// See `lowlevel_break_start` for more details. + pub fn lowlevel_break_stop(&mut self) { + self.device.uartlcr_h().modify(|_, w| w.brk().clear_bit()); + } } impl> Write02 for Writer {