2023-01-31 23:48:33 +00:00
//! Universal Asynchronous Receiver Transmitter (UART) driver.
2021-11-30 22:29:45 +00:00
//!
2023-01-31 23:48:33 +00:00
//! The UART driver is provided in two flavors - this one and also [crate::buffered_uarte::BufferedUarte].
2021-11-30 22:29:45 +00:00
//! The [Uarte] here is useful for those use-cases where reading the UARTE peripheral is
//! exclusively awaited on. If the [Uarte] is required to be awaited on with some other future,
//! for example when using `futures_util::future::select`, then you should consider
2021-12-12 06:47:38 +00:00
//! [crate::buffered_uarte::BufferedUarte] so that reads may continue while processing these
2021-11-30 22:29:45 +00:00
//! other futures. If you do not then you may lose data between reads.
//!
2021-12-12 06:47:38 +00:00
//! An advantage of the [Uarte] has over [crate::buffered_uarte::BufferedUarte] is that less
2021-11-30 22:29:45 +00:00
//! memory may be used given that buffers are passed in directly to its read and write
//! methods.
2020-12-23 15:18:29 +00:00
2023-01-31 23:48:33 +00:00
#![ macro_use ]
2022-09-22 14:42:49 +00:00
use core ::future ::poll_fn ;
2023-03-05 19:17:52 +00:00
use core ::marker ::PhantomData ;
2021-04-14 14:01:43 +00:00
use core ::sync ::atomic ::{ compiler_fence , Ordering } ;
2021-03-22 00:15:44 +00:00
use core ::task ::Poll ;
2022-06-12 20:15:44 +00:00
2023-07-28 11:23:22 +00:00
use embassy_hal_internal ::drop ::OnDrop ;
use embassy_hal_internal ::{ into_ref , PeripheralRef } ;
2022-06-25 21:53:41 +00:00
use pac ::uarte0 ::RegisterBlock ;
// Re-export SVD variants to allow user to directly set values.
pub use pac ::uarte0 ::{ baudrate ::BAUDRATE_A as Baudrate , config ::PARITY_A as Parity } ;
2020-12-23 15:18:29 +00:00
2022-03-02 21:23:43 +00:00
use crate ::chip ::{ EASY_DMA_SIZE , FORCE_COPY_BUFFER_SIZE } ;
2021-03-22 01:10:59 +00:00
use crate ::gpio ::sealed ::Pin as _ ;
2022-02-12 00:04:01 +00:00
use crate ::gpio ::{ self , AnyPin , Pin as GpioPin , PselBits } ;
2023-06-08 14:08:40 +00:00
use crate ::interrupt ::typelevel ::Interrupt ;
2021-10-26 07:45:29 +00:00
use crate ::ppi ::{ AnyConfigurableChannel , ConfigurableChannel , Event , Ppi , Task } ;
2022-06-12 20:15:44 +00:00
use crate ::timer ::{ Frequency , Instance as TimerInstance , Timer } ;
2022-01-13 21:24:13 +00:00
use crate ::util ::slice_in_ram_or ;
2023-06-08 14:08:40 +00:00
use crate ::{ interrupt , pac , Peripheral } ;
2020-12-23 15:18:29 +00:00
2023-01-31 23:48:33 +00:00
/// UARTE config.
2022-06-25 21:53:41 +00:00
#[ derive(Clone) ]
2021-03-22 00:15:44 +00:00
#[ non_exhaustive ]
pub struct Config {
2023-01-31 23:48:33 +00:00
/// Parity bit.
2021-03-22 00:15:44 +00:00
pub parity : Parity ,
2023-01-31 23:48:33 +00:00
/// Baud rate.
2021-03-22 00:15:44 +00:00
pub baudrate : Baudrate ,
2020-12-23 15:18:29 +00:00
}
2021-03-22 00:15:44 +00:00
impl Default for Config {
fn default ( ) -> Self {
Self {
parity : Parity ::EXCLUDED ,
baudrate : Baudrate ::BAUD115200 ,
}
}
2020-12-23 15:18:29 +00:00
}
2023-01-31 23:48:33 +00:00
/// UART error.
2022-01-13 21:24:13 +00:00
#[ derive(Debug, Clone, Copy, PartialEq, Eq) ]
#[ cfg_attr(feature = " defmt " , derive(defmt::Format)) ]
#[ non_exhaustive ]
pub enum Error {
2023-01-31 23:48:33 +00:00
/// Buffer was too long.
2022-01-13 21:24:13 +00:00
BufferTooLong ,
2023-01-31 23:48:33 +00:00
/// The buffer is not in data RAM. It's most likely in flash, and nRF's DMA cannot access flash.
BufferNotInRAM ,
2022-01-13 21:24:13 +00:00
}
2023-03-05 19:17:52 +00:00
/// Interrupt handler.
pub struct InterruptHandler < T : Instance > {
_phantom : PhantomData < T > ,
}
2023-06-08 14:08:40 +00:00
impl < T : Instance > interrupt ::typelevel ::Handler < T ::Interrupt > for InterruptHandler < T > {
2023-03-05 19:17:52 +00:00
unsafe fn on_interrupt ( ) {
let r = T ::regs ( ) ;
let s = T ::state ( ) ;
if r . events_endrx . read ( ) . bits ( ) ! = 0 {
s . endrx_waker . wake ( ) ;
r . intenclr . write ( | w | w . endrx ( ) . clear ( ) ) ;
}
if r . events_endtx . read ( ) . bits ( ) ! = 0 {
s . endtx_waker . wake ( ) ;
r . intenclr . write ( | w | w . endtx ( ) . clear ( ) ) ;
}
}
}
2023-01-31 23:48:33 +00:00
/// UARTE driver.
2021-03-22 00:15:44 +00:00
pub struct Uarte < ' d , T : Instance > {
2021-12-15 06:51:26 +00:00
tx : UarteTx < ' d , T > ,
rx : UarteRx < ' d , T > ,
}
2023-01-31 23:48:33 +00:00
/// Transmitter part of the UARTE driver.
///
/// This can be obtained via [`Uarte::split`], or created directly.
2021-12-15 06:51:26 +00:00
pub struct UarteTx < ' d , T : Instance > {
2022-07-23 13:13:47 +00:00
_p : PeripheralRef < ' d , T > ,
2021-12-15 06:51:26 +00:00
}
2023-01-31 23:48:33 +00:00
/// Receiver part of the UARTE driver.
///
/// This can be obtained via [`Uarte::split`], or created directly.
2021-12-15 06:51:26 +00:00
pub struct UarteRx < ' d , T : Instance > {
2022-07-23 13:13:47 +00:00
_p : PeripheralRef < ' d , T > ,
2021-03-22 00:15:44 +00:00
}
impl < ' d , T : Instance > Uarte < ' d , T > {
2022-02-12 00:04:01 +00:00
/// Create a new UARTE without hardware flow control
2021-11-30 22:14:24 +00:00
pub fn new (
2022-07-23 12:00:19 +00:00
uarte : impl Peripheral < P = T > + ' d ,
2023-06-08 14:08:40 +00:00
_irq : impl interrupt ::typelevel ::Binding < T ::Interrupt , InterruptHandler < T > > + ' d ,
2022-07-23 12:00:19 +00:00
rxd : impl Peripheral < P = impl GpioPin > + ' d ,
txd : impl Peripheral < P = impl GpioPin > + ' d ,
2022-02-12 00:04:01 +00:00
config : Config ,
) -> Self {
2022-07-23 12:27:45 +00:00
into_ref! ( rxd , txd ) ;
2023-03-05 19:17:52 +00:00
Self ::new_inner ( uarte , rxd . map_into ( ) , txd . map_into ( ) , None , None , config )
2022-02-12 00:04:01 +00:00
}
/// Create a new UARTE with hardware flow control (RTS/CTS)
pub fn new_with_rtscts (
2022-07-23 12:00:19 +00:00
uarte : impl Peripheral < P = T > + ' d ,
2023-06-08 14:08:40 +00:00
_irq : impl interrupt ::typelevel ::Binding < T ::Interrupt , InterruptHandler < T > > + ' d ,
2022-07-23 12:00:19 +00:00
rxd : impl Peripheral < P = impl GpioPin > + ' d ,
txd : impl Peripheral < P = impl GpioPin > + ' d ,
cts : impl Peripheral < P = impl GpioPin > + ' d ,
rts : impl Peripheral < P = impl GpioPin > + ' d ,
2022-02-12 00:04:01 +00:00
config : Config ,
) -> Self {
2022-07-23 12:27:45 +00:00
into_ref! ( rxd , txd , cts , rts ) ;
Self ::new_inner (
uarte ,
rxd . map_into ( ) ,
txd . map_into ( ) ,
Some ( cts . map_into ( ) ) ,
Some ( rts . map_into ( ) ) ,
config ,
)
2022-02-12 00:04:01 +00:00
}
fn new_inner (
2022-07-23 13:13:47 +00:00
uarte : impl Peripheral < P = T > + ' d ,
2022-07-23 12:00:19 +00:00
rxd : PeripheralRef < ' d , AnyPin > ,
txd : PeripheralRef < ' d , AnyPin > ,
cts : Option < PeripheralRef < ' d , AnyPin > > ,
rts : Option < PeripheralRef < ' d , AnyPin > > ,
2021-03-22 00:15:44 +00:00
config : Config ,
2020-12-23 15:18:29 +00:00
) -> Self {
2023-03-05 19:17:52 +00:00
into_ref! ( uarte ) ;
2020-12-23 15:18:29 +00:00
2021-04-14 14:01:43 +00:00
let r = T ::regs ( ) ;
2020-12-23 15:18:29 +00:00
2021-03-22 01:10:59 +00:00
rxd . conf ( ) . write ( | w | w . input ( ) . connect ( ) . drive ( ) . h0h1 ( ) ) ;
r . psel . rxd . write ( | w | unsafe { w . bits ( rxd . psel_bits ( ) ) } ) ;
2020-12-23 15:18:29 +00:00
2021-03-22 00:15:44 +00:00
txd . set_high ( ) ;
txd . conf ( ) . write ( | w | w . dir ( ) . output ( ) . drive ( ) . h0h1 ( ) ) ;
r . psel . txd . write ( | w | unsafe { w . bits ( txd . psel_bits ( ) ) } ) ;
2021-03-22 01:10:59 +00:00
2022-02-12 00:04:01 +00:00
if let Some ( pin ) = & cts {
pin . conf ( ) . write ( | w | w . input ( ) . connect ( ) . drive ( ) . h0h1 ( ) ) ;
2021-03-22 01:10:59 +00:00
}
r . psel . cts . write ( | w | unsafe { w . bits ( cts . psel_bits ( ) ) } ) ;
2022-02-12 00:04:01 +00:00
if let Some ( pin ) = & rts {
pin . set_high ( ) ;
pin . conf ( ) . write ( | w | w . dir ( ) . output ( ) . drive ( ) . h0h1 ( ) ) ;
2021-03-22 01:10:59 +00:00
}
r . psel . rts . write ( | w | unsafe { w . bits ( rts . psel_bits ( ) ) } ) ;
2020-12-23 15:18:29 +00:00
2023-06-01 00:22:46 +00:00
T ::Interrupt ::unpend ( ) ;
unsafe { T ::Interrupt ::enable ( ) } ;
2022-06-25 21:53:41 +00:00
2022-02-12 00:04:01 +00:00
let hardware_flow_control = match ( rts . is_some ( ) , cts . is_some ( ) ) {
2021-03-28 20:39:09 +00:00
( false , false ) = > false ,
( true , true ) = > true ,
_ = > panic! ( " RTS and CTS pins must be either both set or none set. " ) ,
} ;
2022-06-25 21:53:41 +00:00
configure ( r , config , hardware_flow_control ) ;
2020-12-23 15:18:29 +00:00
2021-12-16 07:15:28 +00:00
let s = T ::state ( ) ;
s . tx_rx_refcount . store ( 2 , Ordering ::Relaxed ) ;
2021-03-22 00:15:44 +00:00
Self {
2022-07-23 13:13:47 +00:00
tx : UarteTx {
_p : unsafe { uarte . clone_unchecked ( ) } ,
} ,
rx : UarteRx { _p : uarte } ,
2021-03-22 00:15:44 +00:00
}
2020-12-23 15:18:29 +00:00
}
2021-03-26 22:22:06 +00:00
2023-01-31 23:48:33 +00:00
/// Split the Uarte into the transmitter and receiver parts.
///
/// This is useful to concurrently transmit and receive from independent tasks.
2021-12-15 06:51:26 +00:00
pub fn split ( self ) -> ( UarteTx < ' d , T > , UarteRx < ' d , T > ) {
( self . tx , self . rx )
}
2023-01-31 23:48:33 +00:00
/// Split the Uarte into the transmitter and receiver with idle support parts.
///
/// This is useful to concurrently transmit and receive from independent tasks.
2022-10-09 02:07:25 +00:00
pub fn split_with_idle < U : TimerInstance > (
self ,
timer : impl Peripheral < P = U > + ' d ,
ppi_ch1 : impl Peripheral < P = impl ConfigurableChannel + ' d > + ' d ,
ppi_ch2 : impl Peripheral < P = impl ConfigurableChannel + ' d > + ' d ,
) -> ( UarteTx < ' d , T > , UarteRxWithIdle < ' d , T , U > ) {
2023-06-12 07:36:07 +00:00
( self . tx , self . rx . with_idle ( timer , ppi_ch1 , ppi_ch2 ) )
2022-10-09 02:07:25 +00:00
}
2022-01-10 08:14:02 +00:00
/// Return the endtx event for use with PPI
pub fn event_endtx ( & self ) -> Event {
let r = T ::regs ( ) ;
Event ::from_reg ( & r . events_endtx )
}
2023-01-31 23:48:33 +00:00
/// Read bytes until the buffer is filled.
2022-01-13 21:24:13 +00:00
pub async fn read ( & mut self , buffer : & mut [ u8 ] ) -> Result < ( ) , Error > {
self . rx . read ( buffer ) . await
}
2021-12-15 06:51:26 +00:00
2023-01-31 23:48:33 +00:00
/// Write all bytes in the buffer.
2022-01-13 21:24:13 +00:00
pub async fn write ( & mut self , buffer : & [ u8 ] ) -> Result < ( ) , Error > {
self . tx . write ( buffer ) . await
2021-12-15 06:51:26 +00:00
}
2022-03-08 15:42:46 +00:00
/// Same as [`write`](Uarte::write) but will fail instead of copying data into RAM. Consult the module level documentation to learn more.
2022-03-02 21:23:43 +00:00
pub async fn write_from_ram ( & mut self , buffer : & [ u8 ] ) -> Result < ( ) , Error > {
self . tx . write_from_ram ( buffer ) . await
}
2023-01-31 23:48:33 +00:00
/// Read bytes until the buffer is filled.
2022-01-13 21:24:13 +00:00
pub fn blocking_read ( & mut self , buffer : & mut [ u8 ] ) -> Result < ( ) , Error > {
self . rx . blocking_read ( buffer )
}
2021-12-15 06:51:26 +00:00
2023-01-31 23:48:33 +00:00
/// Write all bytes in the buffer.
2022-01-13 21:24:13 +00:00
pub fn blocking_write ( & mut self , buffer : & [ u8 ] ) -> Result < ( ) , Error > {
self . tx . blocking_write ( buffer )
2021-12-15 06:51:26 +00:00
}
2022-03-02 21:23:43 +00:00
2022-03-08 15:42:46 +00:00
/// Same as [`blocking_write`](Uarte::blocking_write) but will fail instead of copying data into RAM. Consult the module level documentation to learn more.
2022-03-02 21:23:43 +00:00
pub fn blocking_write_from_ram ( & mut self , buffer : & [ u8 ] ) -> Result < ( ) , Error > {
self . tx . blocking_write_from_ram ( buffer )
}
2021-12-15 06:51:26 +00:00
}
2022-06-25 21:53:41 +00:00
fn configure ( r : & RegisterBlock , config : Config , hardware_flow_control : bool ) {
r . config . write ( | w | {
w . hwfc ( ) . bit ( hardware_flow_control ) ;
w . parity ( ) . variant ( config . parity ) ;
w
} ) ;
r . baudrate . write ( | w | w . baudrate ( ) . variant ( config . baudrate ) ) ;
// Disable all interrupts
r . intenclr . write ( | w | unsafe { w . bits ( 0xFFFF_FFFF ) } ) ;
// Reset rxstarted, txstarted. These are used by drop to know whether a transfer was
// stopped midway or not.
r . events_rxstarted . reset ( ) ;
r . events_txstarted . reset ( ) ;
// Enable
apply_workaround_for_enable_anomaly ( & r ) ;
r . enable . write ( | w | w . enable ( ) . enabled ( ) ) ;
}
2021-12-15 06:51:26 +00:00
impl < ' d , T : Instance > UarteTx < ' d , T > {
2022-06-25 21:53:41 +00:00
/// Create a new tx-only UARTE without hardware flow control
pub fn new (
2022-07-23 12:00:19 +00:00
uarte : impl Peripheral < P = T > + ' d ,
2023-06-08 14:08:40 +00:00
_irq : impl interrupt ::typelevel ::Binding < T ::Interrupt , InterruptHandler < T > > + ' d ,
2022-07-23 12:00:19 +00:00
txd : impl Peripheral < P = impl GpioPin > + ' d ,
2022-06-25 21:53:41 +00:00
config : Config ,
) -> Self {
2022-07-23 12:27:45 +00:00
into_ref! ( txd ) ;
2023-03-05 19:17:52 +00:00
Self ::new_inner ( uarte , txd . map_into ( ) , None , config )
2022-06-25 21:53:41 +00:00
}
/// Create a new tx-only UARTE with hardware flow control (RTS/CTS)
pub fn new_with_rtscts (
2022-07-23 12:00:19 +00:00
uarte : impl Peripheral < P = T > + ' d ,
2023-06-08 14:08:40 +00:00
_irq : impl interrupt ::typelevel ::Binding < T ::Interrupt , InterruptHandler < T > > + ' d ,
2022-07-23 12:00:19 +00:00
txd : impl Peripheral < P = impl GpioPin > + ' d ,
cts : impl Peripheral < P = impl GpioPin > + ' d ,
2022-06-25 21:53:41 +00:00
config : Config ,
) -> Self {
2022-07-23 12:27:45 +00:00
into_ref! ( txd , cts ) ;
2023-03-05 19:17:52 +00:00
Self ::new_inner ( uarte , txd . map_into ( ) , Some ( cts . map_into ( ) ) , config )
2022-06-25 21:53:41 +00:00
}
fn new_inner (
2022-07-23 13:13:47 +00:00
uarte : impl Peripheral < P = T > + ' d ,
2022-07-23 12:00:19 +00:00
txd : PeripheralRef < ' d , AnyPin > ,
cts : Option < PeripheralRef < ' d , AnyPin > > ,
2022-06-25 21:53:41 +00:00
config : Config ,
) -> Self {
2023-03-05 19:17:52 +00:00
into_ref! ( uarte ) ;
2022-06-25 21:53:41 +00:00
let r = T ::regs ( ) ;
txd . set_high ( ) ;
txd . conf ( ) . write ( | w | w . dir ( ) . output ( ) . drive ( ) . s0s1 ( ) ) ;
r . psel . txd . write ( | w | unsafe { w . bits ( txd . psel_bits ( ) ) } ) ;
if let Some ( pin ) = & cts {
pin . conf ( ) . write ( | w | w . input ( ) . connect ( ) . drive ( ) . h0h1 ( ) ) ;
}
r . psel . cts . write ( | w | unsafe { w . bits ( cts . psel_bits ( ) ) } ) ;
r . psel . rxd . write ( | w | w . connect ( ) . disconnected ( ) ) ;
r . psel . rts . write ( | w | w . connect ( ) . disconnected ( ) ) ;
let hardware_flow_control = cts . is_some ( ) ;
configure ( r , config , hardware_flow_control ) ;
2023-06-01 00:22:46 +00:00
T ::Interrupt ::unpend ( ) ;
unsafe { T ::Interrupt ::enable ( ) } ;
2022-06-25 21:53:41 +00:00
let s = T ::state ( ) ;
s . tx_rx_refcount . store ( 1 , Ordering ::Relaxed ) ;
2022-07-23 13:13:47 +00:00
Self { _p : uarte }
2022-06-25 21:53:41 +00:00
}
2023-01-31 23:48:33 +00:00
/// Write all bytes in the buffer.
2022-01-13 21:24:13 +00:00
pub async fn write ( & mut self , buffer : & [ u8 ] ) -> Result < ( ) , Error > {
2022-03-02 21:23:43 +00:00
match self . write_from_ram ( buffer ) . await {
Ok ( _ ) = > Ok ( ( ) ) ,
2023-01-31 23:48:33 +00:00
Err ( Error ::BufferNotInRAM ) = > {
2022-03-02 21:23:43 +00:00
trace! ( " Copying UARTE tx buffer into RAM for DMA " ) ;
2022-03-02 21:48:58 +00:00
let ram_buf = & mut [ 0 ; FORCE_COPY_BUFFER_SIZE ] [ .. buffer . len ( ) ] ;
ram_buf . copy_from_slice ( buffer ) ;
self . write_from_ram ( & ram_buf ) . await
2022-03-02 21:23:43 +00:00
}
Err ( error ) = > Err ( error ) ,
}
}
2023-01-31 23:48:33 +00:00
/// Same as [`write`](Self::write) but will fail instead of copying data into RAM. Consult the module level documentation to learn more.
2022-03-02 21:23:43 +00:00
pub async fn write_from_ram ( & mut self , buffer : & [ u8 ] ) -> Result < ( ) , Error > {
2022-01-13 21:24:13 +00:00
if buffer . len ( ) = = 0 {
2022-12-15 18:43:36 +00:00
return Ok ( ( ) ) ;
2022-01-13 21:24:13 +00:00
}
2022-12-15 18:43:36 +00:00
2023-01-31 23:48:33 +00:00
slice_in_ram_or ( buffer , Error ::BufferNotInRAM ) ? ;
2022-01-13 21:24:13 +00:00
if buffer . len ( ) > EASY_DMA_SIZE {
return Err ( Error ::BufferTooLong ) ;
2021-12-15 06:51:26 +00:00
}
2022-01-13 21:24:13 +00:00
let ptr = buffer . as_ptr ( ) ;
let len = buffer . len ( ) ;
2021-12-15 06:51:26 +00:00
2022-01-13 21:24:13 +00:00
let r = T ::regs ( ) ;
let s = T ::state ( ) ;
2021-12-15 06:51:26 +00:00
2022-01-13 21:24:13 +00:00
let drop = OnDrop ::new ( move | | {
trace! ( " write drop: stopping " ) ;
2021-12-15 06:51:26 +00:00
2022-01-13 21:24:13 +00:00
r . intenclr . write ( | w | w . endtx ( ) . clear ( ) ) ;
r . events_txstopped . reset ( ) ;
r . tasks_stoptx . write ( | w | unsafe { w . bits ( 1 ) } ) ;
2021-12-15 06:51:26 +00:00
2022-01-13 21:24:13 +00:00
// TX is stopped almost instantly, spinning is fine.
while r . events_endtx . read ( ) . bits ( ) = = 0 { }
trace! ( " write drop: stopped " ) ;
} ) ;
2021-12-15 06:51:26 +00:00
2022-01-13 21:24:13 +00:00
r . txd . ptr . write ( | w | unsafe { w . ptr ( ) . bits ( ptr as u32 ) } ) ;
r . txd . maxcnt . write ( | w | unsafe { w . maxcnt ( ) . bits ( len as _ ) } ) ;
2021-12-15 06:51:26 +00:00
2022-01-13 21:24:13 +00:00
r . events_endtx . reset ( ) ;
r . intenset . write ( | w | w . endtx ( ) . set ( ) ) ;
2021-12-15 06:51:26 +00:00
2022-01-13 21:24:13 +00:00
compiler_fence ( Ordering ::SeqCst ) ;
2021-12-15 06:51:26 +00:00
2022-01-13 21:24:13 +00:00
trace! ( " starttx " ) ;
r . tasks_starttx . write ( | w | unsafe { w . bits ( 1 ) } ) ;
2021-12-15 06:51:26 +00:00
2022-01-13 21:24:13 +00:00
poll_fn ( | cx | {
s . endtx_waker . register ( cx . waker ( ) ) ;
if r . events_endtx . read ( ) . bits ( ) ! = 0 {
return Poll ::Ready ( ( ) ) ;
}
Poll ::Pending
} )
. await ;
2021-12-15 06:51:26 +00:00
2022-01-13 21:24:13 +00:00
compiler_fence ( Ordering ::SeqCst ) ;
r . events_txstarted . reset ( ) ;
drop . defuse ( ) ;
2021-12-15 06:51:26 +00:00
2022-01-13 21:24:13 +00:00
Ok ( ( ) )
}
2021-12-15 06:51:26 +00:00
2023-01-31 23:48:33 +00:00
/// Write all bytes in the buffer.
2022-01-13 21:24:13 +00:00
pub fn blocking_write ( & mut self , buffer : & [ u8 ] ) -> Result < ( ) , Error > {
2022-03-02 21:23:43 +00:00
match self . blocking_write_from_ram ( buffer ) {
Ok ( _ ) = > Ok ( ( ) ) ,
2023-01-31 23:48:33 +00:00
Err ( Error ::BufferNotInRAM ) = > {
2022-03-02 21:23:43 +00:00
trace! ( " Copying UARTE tx buffer into RAM for DMA " ) ;
2022-03-02 21:48:58 +00:00
let ram_buf = & mut [ 0 ; FORCE_COPY_BUFFER_SIZE ] [ .. buffer . len ( ) ] ;
ram_buf . copy_from_slice ( buffer ) ;
self . blocking_write_from_ram ( & ram_buf )
2022-03-02 21:23:43 +00:00
}
Err ( error ) = > Err ( error ) ,
}
}
2023-01-31 23:48:33 +00:00
/// Same as [`write_from_ram`](Self::write_from_ram) but will fail instead of copying data into RAM. Consult the module level documentation to learn more.
2022-03-02 21:23:43 +00:00
pub fn blocking_write_from_ram ( & mut self , buffer : & [ u8 ] ) -> Result < ( ) , Error > {
2022-01-13 21:24:13 +00:00
if buffer . len ( ) = = 0 {
2022-12-15 18:43:36 +00:00
return Ok ( ( ) ) ;
2022-01-13 21:24:13 +00:00
}
2022-12-15 18:43:36 +00:00
2023-01-31 23:48:33 +00:00
slice_in_ram_or ( buffer , Error ::BufferNotInRAM ) ? ;
2022-01-13 21:24:13 +00:00
if buffer . len ( ) > EASY_DMA_SIZE {
return Err ( Error ::BufferTooLong ) ;
2021-12-15 06:51:26 +00:00
}
2022-01-13 21:24:13 +00:00
let ptr = buffer . as_ptr ( ) ;
let len = buffer . len ( ) ;
let r = T ::regs ( ) ;
r . txd . ptr . write ( | w | unsafe { w . ptr ( ) . bits ( ptr as u32 ) } ) ;
r . txd . maxcnt . write ( | w | unsafe { w . maxcnt ( ) . bits ( len as _ ) } ) ;
r . events_endtx . reset ( ) ;
r . intenclr . write ( | w | w . endtx ( ) . clear ( ) ) ;
compiler_fence ( Ordering ::SeqCst ) ;
trace! ( " starttx " ) ;
r . tasks_starttx . write ( | w | unsafe { w . bits ( 1 ) } ) ;
while r . events_endtx . read ( ) . bits ( ) = = 0 { }
compiler_fence ( Ordering ::SeqCst ) ;
r . events_txstarted . reset ( ) ;
Ok ( ( ) )
2021-12-15 06:51:26 +00:00
}
}
impl < ' a , T : Instance > Drop for UarteTx < ' a , T > {
2021-03-26 22:22:06 +00:00
fn drop ( & mut self ) {
2021-12-17 06:06:46 +00:00
trace! ( " uarte tx drop " ) ;
2021-03-26 22:22:06 +00:00
2021-04-14 14:01:43 +00:00
let r = T ::regs ( ) ;
2021-03-26 22:22:06 +00:00
2021-03-27 01:08:58 +00:00
let did_stoptx = r . events_txstarted . read ( ) . bits ( ) ! = 0 ;
2021-12-17 06:06:46 +00:00
trace! ( " did_stoptx {} " , did_stoptx ) ;
2021-03-26 22:22:06 +00:00
2021-12-15 06:51:26 +00:00
// Wait for txstopped, if needed.
while did_stoptx & & r . events_txstopped . read ( ) . bits ( ) = = 0 { }
2021-03-26 22:22:06 +00:00
2021-12-15 20:09:33 +00:00
let s = T ::state ( ) ;
drop_tx_rx ( & r , & s ) ;
2021-12-15 06:51:26 +00:00
}
}
2021-03-26 22:22:06 +00:00
2021-12-15 06:51:26 +00:00
impl < ' d , T : Instance > UarteRx < ' d , T > {
2022-06-25 21:53:41 +00:00
/// Create a new rx-only UARTE without hardware flow control
pub fn new (
2022-07-23 12:00:19 +00:00
uarte : impl Peripheral < P = T > + ' d ,
2023-06-08 14:08:40 +00:00
_irq : impl interrupt ::typelevel ::Binding < T ::Interrupt , InterruptHandler < T > > + ' d ,
2022-07-23 12:00:19 +00:00
rxd : impl Peripheral < P = impl GpioPin > + ' d ,
2022-06-25 21:53:41 +00:00
config : Config ,
) -> Self {
2022-07-23 12:27:45 +00:00
into_ref! ( rxd ) ;
2023-03-05 19:17:52 +00:00
Self ::new_inner ( uarte , rxd . map_into ( ) , None , config )
2022-06-25 21:53:41 +00:00
}
/// Create a new rx-only UARTE with hardware flow control (RTS/CTS)
pub fn new_with_rtscts (
2022-07-23 12:00:19 +00:00
uarte : impl Peripheral < P = T > + ' d ,
2023-06-08 14:08:40 +00:00
_irq : impl interrupt ::typelevel ::Binding < T ::Interrupt , InterruptHandler < T > > + ' d ,
2022-07-23 12:00:19 +00:00
rxd : impl Peripheral < P = impl GpioPin > + ' d ,
rts : impl Peripheral < P = impl GpioPin > + ' d ,
2022-06-25 21:53:41 +00:00
config : Config ,
) -> Self {
2022-07-23 12:27:45 +00:00
into_ref! ( rxd , rts ) ;
2023-03-05 19:17:52 +00:00
Self ::new_inner ( uarte , rxd . map_into ( ) , Some ( rts . map_into ( ) ) , config )
2022-06-25 21:53:41 +00:00
}
fn new_inner (
2022-07-23 13:13:47 +00:00
uarte : impl Peripheral < P = T > + ' d ,
2022-07-23 12:00:19 +00:00
rxd : PeripheralRef < ' d , AnyPin > ,
rts : Option < PeripheralRef < ' d , AnyPin > > ,
2022-06-25 21:53:41 +00:00
config : Config ,
) -> Self {
2023-03-05 19:17:52 +00:00
into_ref! ( uarte ) ;
2022-06-25 21:53:41 +00:00
let r = T ::regs ( ) ;
rxd . conf ( ) . write ( | w | w . input ( ) . connect ( ) . drive ( ) . h0h1 ( ) ) ;
r . psel . rxd . write ( | w | unsafe { w . bits ( rxd . psel_bits ( ) ) } ) ;
if let Some ( pin ) = & rts {
pin . set_high ( ) ;
pin . conf ( ) . write ( | w | w . dir ( ) . output ( ) . drive ( ) . h0h1 ( ) ) ;
}
r . psel . rts . write ( | w | unsafe { w . bits ( rts . psel_bits ( ) ) } ) ;
r . psel . txd . write ( | w | w . connect ( ) . disconnected ( ) ) ;
r . psel . cts . write ( | w | w . connect ( ) . disconnected ( ) ) ;
2023-06-01 00:22:46 +00:00
T ::Interrupt ::unpend ( ) ;
unsafe { T ::Interrupt ::enable ( ) } ;
2022-06-25 21:53:41 +00:00
let hardware_flow_control = rts . is_some ( ) ;
configure ( r , config , hardware_flow_control ) ;
let s = T ::state ( ) ;
s . tx_rx_refcount . store ( 1 , Ordering ::Relaxed ) ;
2022-07-23 13:13:47 +00:00
Self { _p : uarte }
2022-06-25 21:53:41 +00:00
}
2023-06-12 07:36:07 +00:00
/// Upgrade to an instance that supports idle line detection.
pub fn with_idle < U : TimerInstance > (
self ,
timer : impl Peripheral < P = U > + ' d ,
ppi_ch1 : impl Peripheral < P = impl ConfigurableChannel + ' d > + ' d ,
ppi_ch2 : impl Peripheral < P = impl ConfigurableChannel + ' d > + ' d ,
) -> UarteRxWithIdle < ' d , T , U > {
let timer = Timer ::new ( timer ) ;
into_ref! ( ppi_ch1 , ppi_ch2 ) ;
let r = T ::regs ( ) ;
// BAUDRATE register values are `baudrate * 2^32 / 16000000`
// source: https://devzone.nordicsemi.com/f/nordic-q-a/391/uart-baudrate-register-values
//
// We want to stop RX if line is idle for 2 bytes worth of time
// That is 20 bits (each byte is 1 start bit + 8 data bits + 1 stop bit)
// This gives us the amount of 16M ticks for 20 bits.
let baudrate = r . baudrate . read ( ) . baudrate ( ) . variant ( ) . unwrap ( ) ;
let timeout = 0x8000_0000 / ( baudrate as u32 / 40 ) ;
timer . set_frequency ( Frequency ::F16MHz ) ;
timer . cc ( 0 ) . write ( timeout ) ;
timer . cc ( 0 ) . short_compare_clear ( ) ;
timer . cc ( 0 ) . short_compare_stop ( ) ;
let mut ppi_ch1 = Ppi ::new_one_to_two (
ppi_ch1 . map_into ( ) ,
Event ::from_reg ( & r . events_rxdrdy ) ,
timer . task_clear ( ) ,
timer . task_start ( ) ,
) ;
ppi_ch1 . enable ( ) ;
let mut ppi_ch2 = Ppi ::new_one_to_one (
ppi_ch2 . map_into ( ) ,
timer . cc ( 0 ) . event_compare ( ) ,
Task ::from_reg ( & r . tasks_stoprx ) ,
) ;
ppi_ch2 . enable ( ) ;
UarteRxWithIdle {
rx : self ,
timer ,
ppi_ch1 : ppi_ch1 ,
_ppi_ch2 : ppi_ch2 ,
}
}
2023-01-31 23:48:33 +00:00
/// Read bytes until the buffer is filled.
2022-01-13 21:24:13 +00:00
pub async fn read ( & mut self , buffer : & mut [ u8 ] ) -> Result < ( ) , Error > {
if buffer . len ( ) = = 0 {
2022-12-15 18:43:36 +00:00
return Ok ( ( ) ) ;
2022-01-13 21:24:13 +00:00
}
if buffer . len ( ) > EASY_DMA_SIZE {
return Err ( Error ::BufferTooLong ) ;
2021-12-15 06:51:26 +00:00
}
2020-12-23 15:18:29 +00:00
2022-01-13 21:24:13 +00:00
let ptr = buffer . as_ptr ( ) ;
let len = buffer . len ( ) ;
2021-01-02 18:59:37 +00:00
2022-01-13 21:24:13 +00:00
let r = T ::regs ( ) ;
let s = T ::state ( ) ;
2021-03-22 00:15:44 +00:00
2022-01-13 21:24:13 +00:00
let drop = OnDrop ::new ( move | | {
trace! ( " read drop: stopping " ) ;
2021-03-22 00:15:44 +00:00
2022-01-13 21:24:13 +00:00
r . intenclr . write ( | w | w . endrx ( ) . clear ( ) ) ;
r . events_rxto . reset ( ) ;
r . tasks_stoprx . write ( | w | unsafe { w . bits ( 1 ) } ) ;
2021-03-22 00:15:44 +00:00
2022-01-13 21:24:13 +00:00
while r . events_endrx . read ( ) . bits ( ) = = 0 { }
2021-03-22 00:15:44 +00:00
2022-01-13 21:24:13 +00:00
trace! ( " read drop: stopped " ) ;
} ) ;
2021-03-26 22:22:06 +00:00
2022-01-13 21:24:13 +00:00
r . rxd . ptr . write ( | w | unsafe { w . ptr ( ) . bits ( ptr as u32 ) } ) ;
r . rxd . maxcnt . write ( | w | unsafe { w . maxcnt ( ) . bits ( len as _ ) } ) ;
2021-03-22 00:15:44 +00:00
2022-01-13 21:24:13 +00:00
r . events_endrx . reset ( ) ;
r . intenset . write ( | w | w . endrx ( ) . set ( ) ) ;
2021-03-22 00:15:44 +00:00
2022-01-13 21:24:13 +00:00
compiler_fence ( Ordering ::SeqCst ) ;
2021-03-22 00:15:44 +00:00
2022-01-13 21:24:13 +00:00
trace! ( " startrx " ) ;
r . tasks_startrx . write ( | w | unsafe { w . bits ( 1 ) } ) ;
2021-03-22 00:15:44 +00:00
2022-01-13 21:24:13 +00:00
poll_fn ( | cx | {
s . endrx_waker . register ( cx . waker ( ) ) ;
if r . events_endrx . read ( ) . bits ( ) ! = 0 {
return Poll ::Ready ( ( ) ) ;
}
Poll ::Pending
} )
. await ;
2021-03-22 00:15:44 +00:00
2022-01-13 21:24:13 +00:00
compiler_fence ( Ordering ::SeqCst ) ;
r . events_rxstarted . reset ( ) ;
drop . defuse ( ) ;
2021-03-22 00:15:44 +00:00
2022-01-13 21:24:13 +00:00
Ok ( ( ) )
}
2021-03-22 00:15:44 +00:00
2023-01-31 23:48:33 +00:00
/// Read bytes until the buffer is filled.
2022-01-13 21:24:13 +00:00
pub fn blocking_read ( & mut self , buffer : & mut [ u8 ] ) -> Result < ( ) , Error > {
if buffer . len ( ) = = 0 {
2022-12-15 18:43:36 +00:00
return Ok ( ( ) ) ;
2022-01-13 21:24:13 +00:00
}
if buffer . len ( ) > EASY_DMA_SIZE {
return Err ( Error ::BufferTooLong ) ;
2021-01-02 18:59:37 +00:00
}
2022-01-13 21:24:13 +00:00
let ptr = buffer . as_ptr ( ) ;
let len = buffer . len ( ) ;
let r = T ::regs ( ) ;
r . rxd . ptr . write ( | w | unsafe { w . ptr ( ) . bits ( ptr as u32 ) } ) ;
r . rxd . maxcnt . write ( | w | unsafe { w . maxcnt ( ) . bits ( len as _ ) } ) ;
r . events_endrx . reset ( ) ;
r . intenclr . write ( | w | w . endrx ( ) . clear ( ) ) ;
compiler_fence ( Ordering ::SeqCst ) ;
trace! ( " startrx " ) ;
r . tasks_startrx . write ( | w | unsafe { w . bits ( 1 ) } ) ;
while r . events_endrx . read ( ) . bits ( ) = = 0 { }
compiler_fence ( Ordering ::SeqCst ) ;
r . events_rxstarted . reset ( ) ;
Ok ( ( ) )
2021-01-02 18:59:37 +00:00
}
}
2021-12-15 06:51:26 +00:00
impl < ' a , T : Instance > Drop for UarteRx < ' a , T > {
fn drop ( & mut self ) {
2021-12-17 06:06:46 +00:00
trace! ( " uarte rx drop " ) ;
2021-12-15 06:51:26 +00:00
let r = T ::regs ( ) ;
let did_stoprx = r . events_rxstarted . read ( ) . bits ( ) ! = 0 ;
2021-12-17 06:06:46 +00:00
trace! ( " did_stoprx {} " , did_stoprx ) ;
2021-12-15 06:51:26 +00:00
// Wait for rxto, if needed.
while did_stoprx & & r . events_rxto . read ( ) . bits ( ) = = 0 { }
2021-12-15 20:09:33 +00:00
let s = T ::state ( ) ;
2021-12-15 06:51:26 +00:00
2021-12-15 20:09:33 +00:00
drop_tx_rx ( & r , & s ) ;
2021-12-15 06:51:26 +00:00
}
}
2023-01-31 23:48:33 +00:00
/// Receiver part of the UARTE driver, with `read_until_idle` support.
///
/// This can be obtained via [`Uarte::split_with_idle`].
2022-10-09 02:07:25 +00:00
pub struct UarteRxWithIdle < ' d , T : Instance , U : TimerInstance > {
rx : UarteRx < ' d , T > ,
timer : Timer < ' d , U > ,
2022-04-27 18:33:41 +00:00
ppi_ch1 : Ppi < ' d , AnyConfigurableChannel , 1 , 2 > ,
_ppi_ch2 : Ppi < ' d , AnyConfigurableChannel , 1 , 1 > ,
}
2022-10-09 02:07:25 +00:00
impl < ' d , T : Instance , U : TimerInstance > UarteRxWithIdle < ' d , T , U > {
2023-01-31 23:48:33 +00:00
/// Read bytes until the buffer is filled.
2022-04-27 18:33:41 +00:00
pub async fn read ( & mut self , buffer : & mut [ u8 ] ) -> Result < ( ) , Error > {
self . ppi_ch1 . disable ( ) ;
self . rx . read ( buffer ) . await
}
2023-01-31 23:48:33 +00:00
/// Read bytes until the buffer is filled.
2022-04-27 18:33:41 +00:00
pub fn blocking_read ( & mut self , buffer : & mut [ u8 ] ) -> Result < ( ) , Error > {
self . ppi_ch1 . disable ( ) ;
self . rx . blocking_read ( buffer )
2022-01-13 21:24:13 +00:00
}
2021-05-10 13:45:40 +00:00
2023-01-31 23:48:33 +00:00
/// Read bytes until the buffer is filled, or the line becomes idle.
///
/// Returns the amount of bytes read.
2022-01-13 21:24:13 +00:00
pub async fn read_until_idle ( & mut self , buffer : & mut [ u8 ] ) -> Result < usize , Error > {
if buffer . len ( ) = = 0 {
2022-12-15 18:43:36 +00:00
return Ok ( 0 ) ;
2022-01-13 21:24:13 +00:00
}
if buffer . len ( ) > EASY_DMA_SIZE {
return Err ( Error ::BufferTooLong ) ;
}
2021-05-10 13:45:40 +00:00
2022-01-13 21:24:13 +00:00
let ptr = buffer . as_ptr ( ) ;
let len = buffer . len ( ) ;
2021-05-10 13:45:40 +00:00
2022-10-09 02:07:25 +00:00
let r = T ::regs ( ) ;
let s = T ::state ( ) ;
2021-05-10 13:45:40 +00:00
2022-01-13 21:24:13 +00:00
self . ppi_ch1 . enable ( ) ;
2021-05-10 13:45:40 +00:00
2022-01-13 21:24:13 +00:00
let drop = OnDrop ::new ( | | {
self . timer . stop ( ) ;
2021-05-10 13:45:40 +00:00
2022-01-13 21:24:13 +00:00
r . intenclr . write ( | w | w . endrx ( ) . clear ( ) ) ;
r . events_rxto . reset ( ) ;
r . tasks_stoprx . write ( | w | unsafe { w . bits ( 1 ) } ) ;
2021-05-10 13:45:40 +00:00
2022-01-13 21:24:13 +00:00
while r . events_endrx . read ( ) . bits ( ) = = 0 { }
} ) ;
2021-05-10 18:16:13 +00:00
2022-01-13 21:24:13 +00:00
r . rxd . ptr . write ( | w | unsafe { w . ptr ( ) . bits ( ptr as u32 ) } ) ;
r . rxd . maxcnt . write ( | w | unsafe { w . maxcnt ( ) . bits ( len as _ ) } ) ;
2021-05-10 18:16:52 +00:00
2022-01-13 21:24:13 +00:00
r . events_endrx . reset ( ) ;
r . intenset . write ( | w | w . endrx ( ) . set ( ) ) ;
2021-05-10 13:45:40 +00:00
2022-01-13 21:24:13 +00:00
compiler_fence ( Ordering ::SeqCst ) ;
r . tasks_startrx . write ( | w | unsafe { w . bits ( 1 ) } ) ;
poll_fn ( | cx | {
s . endrx_waker . register ( cx . waker ( ) ) ;
if r . events_endrx . read ( ) . bits ( ) ! = 0 {
return Poll ::Ready ( ( ) ) ;
}
Poll ::Pending
} )
. await ;
compiler_fence ( Ordering ::SeqCst ) ;
let n = r . rxd . amount . read ( ) . amount ( ) . bits ( ) as usize ;
self . timer . stop ( ) ;
r . events_rxstarted . reset ( ) ;
drop . defuse ( ) ;
Ok ( n )
2021-05-10 13:45:40 +00:00
}
2023-01-31 23:48:33 +00:00
/// Read bytes until the buffer is filled, or the line becomes idle.
///
/// Returns the amount of bytes read.
2022-01-13 21:24:13 +00:00
pub fn blocking_read_until_idle ( & mut self , buffer : & mut [ u8 ] ) -> Result < usize , Error > {
if buffer . len ( ) = = 0 {
2022-12-15 18:43:36 +00:00
return Ok ( 0 ) ;
2022-01-13 21:24:13 +00:00
}
if buffer . len ( ) > EASY_DMA_SIZE {
return Err ( Error ::BufferTooLong ) ;
2021-05-10 18:16:52 +00:00
}
2021-05-10 13:45:40 +00:00
2022-01-13 21:24:13 +00:00
let ptr = buffer . as_ptr ( ) ;
let len = buffer . len ( ) ;
2022-10-09 02:07:25 +00:00
let r = T ::regs ( ) ;
2022-01-13 21:24:13 +00:00
self . ppi_ch1 . enable ( ) ;
r . rxd . ptr . write ( | w | unsafe { w . ptr ( ) . bits ( ptr as u32 ) } ) ;
r . rxd . maxcnt . write ( | w | unsafe { w . maxcnt ( ) . bits ( len as _ ) } ) ;
r . events_endrx . reset ( ) ;
r . intenclr . write ( | w | w . endrx ( ) . clear ( ) ) ;
compiler_fence ( Ordering ::SeqCst ) ;
r . tasks_startrx . write ( | w | unsafe { w . bits ( 1 ) } ) ;
while r . events_endrx . read ( ) . bits ( ) = = 0 { }
compiler_fence ( Ordering ::SeqCst ) ;
let n = r . rxd . amount . read ( ) . amount ( ) . bits ( ) as usize ;
self . timer . stop ( ) ;
r . events_rxstarted . reset ( ) ;
2021-05-10 13:45:40 +00:00
2022-01-13 21:24:13 +00:00
Ok ( n )
2021-05-10 13:45:40 +00:00
}
}
2022-10-09 02:07:25 +00:00
2023-05-19 16:25:34 +00:00
#[ cfg(not(any(feature = " _nrf9160 " , feature = " _nrf5340 " ))) ]
2022-10-09 02:07:25 +00:00
pub ( crate ) fn apply_workaround_for_enable_anomaly ( _r : & crate ::pac ::uarte0 ::RegisterBlock ) {
// Do nothing
}
2023-05-19 16:25:34 +00:00
#[ cfg(any(feature = " _nrf9160 " , feature = " _nrf5340 " )) ]
2022-10-09 02:07:25 +00:00
pub ( crate ) fn apply_workaround_for_enable_anomaly ( r : & crate ::pac ::uarte0 ::RegisterBlock ) {
// Apply workaround for anomalies:
// - nRF9160 - anomaly 23
// - nRF5340 - anomaly 44
2023-05-19 16:25:34 +00:00
let rxenable_reg : * const u32 = ( ( r as * const _ as usize ) + 0x564 ) as * const u32 ;
let txenable_reg : * const u32 = ( ( r as * const _ as usize ) + 0x568 ) as * const u32 ;
2022-10-09 02:07:25 +00:00
// NB Safety: This is taken from Nordic's driver -
// https://github.com/NordicSemiconductor/nrfx/blob/master/drivers/src/nrfx_uarte.c#L197
if unsafe { core ::ptr ::read_volatile ( txenable_reg ) } = = 1 {
r . tasks_stoptx . write ( | w | unsafe { w . bits ( 1 ) } ) ;
}
// NB Safety: This is taken from Nordic's driver -
// https://github.com/NordicSemiconductor/nrfx/blob/master/drivers/src/nrfx_uarte.c#L197
if unsafe { core ::ptr ::read_volatile ( rxenable_reg ) } = = 1 {
r . enable . write ( | w | w . enable ( ) . enabled ( ) ) ;
r . tasks_stoprx . write ( | w | unsafe { w . bits ( 1 ) } ) ;
let mut workaround_succeded = false ;
// The UARTE is able to receive up to four bytes after the STOPRX task has been triggered.
// On lowest supported baud rate (1200 baud), with parity bit and two stop bits configured
// (resulting in 12 bits per data byte sent), this may take up to 40 ms.
for _ in 0 .. 40000 {
// NB Safety: This is taken from Nordic's driver -
// https://github.com/NordicSemiconductor/nrfx/blob/master/drivers/src/nrfx_uarte.c#L197
if unsafe { core ::ptr ::read_volatile ( rxenable_reg ) } = = 0 {
workaround_succeded = true ;
break ;
} else {
// Need to sleep for 1us here
}
}
if ! workaround_succeded {
panic! ( " Failed to apply workaround for UART " ) ;
}
let errors = r . errorsrc . read ( ) . bits ( ) ;
// NB Safety: safe to write back the bits we just read to clear them
r . errorsrc . write ( | w | unsafe { w . bits ( errors ) } ) ;
r . enable . write ( | w | w . enable ( ) . disabled ( ) ) ;
}
}
pub ( crate ) fn drop_tx_rx ( r : & pac ::uarte0 ::RegisterBlock , s : & sealed ::State ) {
if s . tx_rx_refcount . fetch_sub ( 1 , Ordering ::Relaxed ) = = 1 {
// Finally we can disable, and we do so for the peripheral
// i.e. not just rx concerns.
r . enable . write ( | w | w . enable ( ) . disabled ( ) ) ;
gpio ::deconfigure_pin ( r . psel . rxd . read ( ) . bits ( ) ) ;
gpio ::deconfigure_pin ( r . psel . txd . read ( ) . bits ( ) ) ;
gpio ::deconfigure_pin ( r . psel . rts . read ( ) . bits ( ) ) ;
gpio ::deconfigure_pin ( r . psel . cts . read ( ) . bits ( ) ) ;
trace! ( " uarte tx and rx drop: done " ) ;
}
}
2021-05-11 01:04:59 +00:00
pub ( crate ) mod sealed {
2021-12-15 20:09:33 +00:00
use core ::sync ::atomic ::AtomicU8 ;
2022-08-22 19:46:09 +00:00
use embassy_sync ::waitqueue ::AtomicWaker ;
2021-09-10 23:53:53 +00:00
2021-03-22 00:15:44 +00:00
use super ::* ;
2020-12-23 15:18:29 +00:00
2021-04-14 14:01:43 +00:00
pub struct State {
pub endrx_waker : AtomicWaker ,
pub endtx_waker : AtomicWaker ,
2021-12-15 20:09:33 +00:00
pub tx_rx_refcount : AtomicU8 ,
2021-04-14 14:01:43 +00:00
}
impl State {
pub const fn new ( ) -> Self {
Self {
endrx_waker : AtomicWaker ::new ( ) ,
endtx_waker : AtomicWaker ::new ( ) ,
2021-12-16 07:15:28 +00:00
tx_rx_refcount : AtomicU8 ::new ( 0 ) ,
2021-04-14 14:01:43 +00:00
}
}
}
2021-03-22 00:15:44 +00:00
pub trait Instance {
2021-10-12 09:43:57 +00:00
fn regs ( ) -> & 'static pac ::uarte0 ::RegisterBlock ;
2021-04-14 14:01:43 +00:00
fn state ( ) -> & 'static State ;
2023-03-04 04:27:29 +00:00
fn buffered_state ( ) -> & 'static crate ::buffered_uarte ::State ;
2021-03-22 00:15:44 +00:00
}
2020-12-23 15:18:29 +00:00
}
2023-01-31 23:48:33 +00:00
/// UARTE peripheral instance.
2022-07-23 12:00:19 +00:00
pub trait Instance : Peripheral < P = Self > + sealed ::Instance + 'static + Send {
2023-01-31 23:48:33 +00:00
/// Interrupt for this peripheral.
2023-06-08 14:08:40 +00:00
type Interrupt : interrupt ::typelevel ::Interrupt ;
2020-12-23 15:18:29 +00:00
}
2021-05-11 01:04:59 +00:00
macro_rules ! impl_uarte {
( $type :ident , $pac_type :ident , $irq :ident ) = > {
impl crate ::uarte ::sealed ::Instance for peripherals ::$type {
2021-10-12 09:43:57 +00:00
fn regs ( ) -> & 'static pac ::uarte0 ::RegisterBlock {
2021-05-11 01:04:59 +00:00
unsafe { & * pac ::$pac_type ::ptr ( ) }
2021-03-22 00:15:44 +00:00
}
2021-05-11 01:04:59 +00:00
fn state ( ) -> & 'static crate ::uarte ::sealed ::State {
static STATE : crate ::uarte ::sealed ::State = crate ::uarte ::sealed ::State ::new ( ) ;
2021-04-14 14:01:43 +00:00
& STATE
}
2023-03-04 04:27:29 +00:00
fn buffered_state ( ) -> & 'static crate ::buffered_uarte ::State {
static STATE : crate ::buffered_uarte ::State = crate ::buffered_uarte ::State ::new ( ) ;
& STATE
}
2021-03-22 00:15:44 +00:00
}
2021-05-11 01:04:59 +00:00
impl crate ::uarte ::Instance for peripherals ::$type {
2023-06-08 14:08:40 +00:00
type Interrupt = crate ::interrupt ::typelevel ::$irq ;
2021-03-22 00:15:44 +00:00
}
} ;
2020-12-23 15:18:29 +00:00
}
2022-01-13 22:56:25 +00:00
// ====================
mod eh02 {
use super ::* ;
impl < ' d , T : Instance > embedded_hal_02 ::blocking ::serial ::Write < u8 > for Uarte < ' d , T > {
type Error = Error ;
fn bwrite_all ( & mut self , buffer : & [ u8 ] ) -> Result < ( ) , Self ::Error > {
self . blocking_write ( buffer )
}
fn bflush ( & mut self ) -> Result < ( ) , Self ::Error > {
Ok ( ( ) )
}
}
impl < ' d , T : Instance > embedded_hal_02 ::blocking ::serial ::Write < u8 > for UarteTx < ' d , T > {
type Error = Error ;
fn bwrite_all ( & mut self , buffer : & [ u8 ] ) -> Result < ( ) , Self ::Error > {
self . blocking_write ( buffer )
}
fn bflush ( & mut self ) -> Result < ( ) , Self ::Error > {
Ok ( ( ) )
}
}
}