2021-05-11 03:04:59 +02:00
#![ macro_use ]
2021-03-22 02:10:59 +01:00
//! Async UART
2021-11-30 23:29:45 +01:00
//!
2021-12-12 07:47:38 +01:00
//! Async UART is provided in two flavors - this one and also [crate::buffered_uarte::BufferedUarte].
2021-11-30 23:29:45 +01: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 07:47:38 +01:00
//! [crate::buffered_uarte::BufferedUarte] so that reads may continue while processing these
2021-11-30 23:29:45 +01:00
//! other futures. If you do not then you may lose data between reads.
//!
2021-12-12 07:47:38 +01:00
//! An advantage of the [Uarte] has over [crate::buffered_uarte::BufferedUarte] is that less
2021-11-30 23:29:45 +01:00
//! memory may be used given that buffers are passed in directly to its read and write
//! methods.
2020-12-23 16:18:29 +01:00
2021-04-14 16:01:43 +02:00
use core ::sync ::atomic ::{ compiler_fence , Ordering } ;
2021-03-22 01:15:44 +01:00
use core ::task ::Poll ;
2022-06-12 22:15:44 +02:00
2021-09-11 01:53:53 +02:00
use embassy_hal_common ::drop ::OnDrop ;
2022-07-23 14:00:19 +02:00
use embassy_hal_common ::{ into_ref , PeripheralRef } ;
2022-06-25 23:53:41 +02:00
use futures ::future ::poll_fn ;
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 16:18:29 +01:00
2022-03-02 22:23:43 +01:00
use crate ::chip ::{ EASY_DMA_SIZE , FORCE_COPY_BUFFER_SIZE } ;
2021-03-22 02:10:59 +01:00
use crate ::gpio ::sealed ::Pin as _ ;
2022-02-12 01:04:01 +01:00
use crate ::gpio ::{ self , AnyPin , Pin as GpioPin , PselBits } ;
2022-06-12 22:15:44 +02:00
use crate ::interrupt ::{ Interrupt , InterruptExt } ;
2021-10-26 09:45:29 +02:00
use crate ::ppi ::{ AnyConfigurableChannel , ConfigurableChannel , Event , Ppi , Task } ;
2022-06-12 22:15:44 +02:00
use crate ::timer ::{ Frequency , Instance as TimerInstance , Timer } ;
2022-01-13 22:24:13 +01:00
use crate ::util ::slice_in_ram_or ;
2022-07-23 14:00:19 +02:00
use crate ::{ pac , Peripheral } ;
2020-12-23 16:18:29 +01:00
2022-06-25 23:53:41 +02:00
#[ derive(Clone) ]
2021-03-22 01:15:44 +01:00
#[ non_exhaustive ]
pub struct Config {
pub parity : Parity ,
pub baudrate : Baudrate ,
2020-12-23 16:18:29 +01:00
}
2021-03-22 01:15:44 +01:00
impl Default for Config {
fn default ( ) -> Self {
Self {
parity : Parity ::EXCLUDED ,
baudrate : Baudrate ::BAUD115200 ,
}
}
2020-12-23 16:18:29 +01:00
}
2022-01-13 22:24:13 +01:00
#[ derive(Debug, Clone, Copy, PartialEq, Eq) ]
#[ cfg_attr(feature = " defmt " , derive(defmt::Format)) ]
#[ non_exhaustive ]
pub enum Error {
BufferTooLong ,
BufferZeroLength ,
DMABufferNotInDataMemory ,
// TODO: add other error variants.
}
2022-03-08 16:42:46 +01:00
/// Interface to the UARTE peripheral using EasyDMA to offload the transmission and reception workload.
///
/// For more details about EasyDMA, consult the module documentation.
2021-03-22 01:15:44 +01:00
pub struct Uarte < ' d , T : Instance > {
2021-12-15 07:51:26 +01:00
tx : UarteTx < ' d , T > ,
rx : UarteRx < ' d , T > ,
}
/// Transmitter interface to the UARTE peripheral obtained
/// via [Uarte]::split.
pub struct UarteTx < ' d , T : Instance > {
2022-07-23 15:13:47 +02:00
_p : PeripheralRef < ' d , T > ,
2021-12-15 07:51:26 +01:00
}
/// Receiver interface to the UARTE peripheral obtained
/// via [Uarte]::split.
pub struct UarteRx < ' d , T : Instance > {
2022-07-23 15:13:47 +02:00
_p : PeripheralRef < ' d , T > ,
2021-03-22 01:15:44 +01:00
}
impl < ' d , T : Instance > Uarte < ' d , T > {
2022-02-12 01:04:01 +01:00
/// Create a new UARTE without hardware flow control
2021-11-30 23:14:24 +01:00
pub fn new (
2022-07-23 14:00:19 +02:00
uarte : impl Peripheral < P = T > + ' d ,
irq : impl Peripheral < P = T ::Interrupt > + ' d ,
rxd : impl Peripheral < P = impl GpioPin > + ' d ,
txd : impl Peripheral < P = impl GpioPin > + ' d ,
2022-02-12 01:04:01 +01:00
config : Config ,
) -> Self {
2022-07-23 14:27:45 +02:00
into_ref! ( rxd , txd ) ;
Self ::new_inner ( uarte , irq , rxd . map_into ( ) , txd . map_into ( ) , None , None , config )
2022-02-12 01:04:01 +01:00
}
/// Create a new UARTE with hardware flow control (RTS/CTS)
pub fn new_with_rtscts (
2022-07-23 14:00:19 +02:00
uarte : impl Peripheral < P = T > + ' d ,
irq : impl Peripheral < P = T ::Interrupt > + ' d ,
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 01:04:01 +01:00
config : Config ,
) -> Self {
2022-07-23 14:27:45 +02:00
into_ref! ( rxd , txd , cts , rts ) ;
Self ::new_inner (
uarte ,
irq ,
rxd . map_into ( ) ,
txd . map_into ( ) ,
Some ( cts . map_into ( ) ) ,
Some ( rts . map_into ( ) ) ,
config ,
)
2022-02-12 01:04:01 +01:00
}
fn new_inner (
2022-07-23 15:13:47 +02:00
uarte : impl Peripheral < P = T > + ' d ,
2022-07-23 14:00:19 +02:00
irq : impl Peripheral < P = T ::Interrupt > + ' d ,
rxd : PeripheralRef < ' d , AnyPin > ,
txd : PeripheralRef < ' d , AnyPin > ,
cts : Option < PeripheralRef < ' d , AnyPin > > ,
rts : Option < PeripheralRef < ' d , AnyPin > > ,
2021-03-22 01:15:44 +01:00
config : Config ,
2020-12-23 16:18:29 +01:00
) -> Self {
2022-07-23 15:13:47 +02:00
into_ref! ( uarte , irq ) ;
2020-12-23 16:18:29 +01:00
2021-04-14 16:01:43 +02:00
let r = T ::regs ( ) ;
2020-12-23 16:18:29 +01:00
2021-03-22 02:10:59 +01:00
rxd . conf ( ) . write ( | w | w . input ( ) . connect ( ) . drive ( ) . h0h1 ( ) ) ;
r . psel . rxd . write ( | w | unsafe { w . bits ( rxd . psel_bits ( ) ) } ) ;
2020-12-23 16:18:29 +01:00
2021-03-22 01:15:44 +01: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 02:10:59 +01:00
2022-02-12 01:04:01 +01:00
if let Some ( pin ) = & cts {
pin . conf ( ) . write ( | w | w . input ( ) . connect ( ) . drive ( ) . h0h1 ( ) ) ;
2021-03-22 02:10:59 +01:00
}
r . psel . cts . write ( | w | unsafe { w . bits ( cts . psel_bits ( ) ) } ) ;
2022-02-12 01:04:01 +01:00
if let Some ( pin ) = & rts {
pin . set_high ( ) ;
pin . conf ( ) . write ( | w | w . dir ( ) . output ( ) . drive ( ) . h0h1 ( ) ) ;
2021-03-22 02:10:59 +01:00
}
r . psel . rts . write ( | w | unsafe { w . bits ( rts . psel_bits ( ) ) } ) ;
2020-12-23 16:18:29 +01:00
2022-06-25 23:53:41 +02:00
irq . set_handler ( Self ::on_interrupt ) ;
irq . unpend ( ) ;
irq . enable ( ) ;
2022-02-12 01:04:01 +01:00
let hardware_flow_control = match ( rts . is_some ( ) , cts . is_some ( ) ) {
2021-03-28 22:39:09 +02:00
( false , false ) = > false ,
( true , true ) = > true ,
_ = > panic! ( " RTS and CTS pins must be either both set or none set. " ) ,
} ;
2022-06-25 23:53:41 +02:00
configure ( r , config , hardware_flow_control ) ;
2020-12-23 16:18:29 +01:00
2021-12-16 08:15:28 +01:00
let s = T ::state ( ) ;
s . tx_rx_refcount . store ( 2 , Ordering ::Relaxed ) ;
2021-03-22 01:15:44 +01:00
Self {
2022-07-23 15:13:47 +02:00
tx : UarteTx {
_p : unsafe { uarte . clone_unchecked ( ) } ,
} ,
rx : UarteRx { _p : uarte } ,
2021-03-22 01:15:44 +01:00
}
2020-12-23 16:18:29 +01:00
}
2021-03-26 23:22:06 +01:00
2021-12-15 07:51:26 +01:00
/// Split the Uarte into a transmitter and receiver, which is
/// particuarly useful when having two tasks correlating to
/// transmitting and receiving.
pub fn split ( self ) -> ( UarteTx < ' d , T > , UarteRx < ' d , T > ) {
( self . tx , self . rx )
}
2022-01-10 09:14:02 +01: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 )
}
2021-04-14 16:01:43 +02:00
fn on_interrupt ( _ : * mut ( ) ) {
let r = T ::regs ( ) ;
let s = T ::state ( ) ;
2021-03-26 23:22:06 +01:00
if r . events_endrx . read ( ) . bits ( ) ! = 0 {
2021-04-14 16:01:43 +02:00
s . endrx_waker . wake ( ) ;
2021-03-26 23:22:06 +01:00
r . intenclr . write ( | w | w . endrx ( ) . clear ( ) ) ;
}
if r . events_endtx . read ( ) . bits ( ) ! = 0 {
2021-04-14 16:01:43 +02:00
s . endtx_waker . wake ( ) ;
2021-03-26 23:22:06 +01:00
r . intenclr . write ( | w | w . endtx ( ) . clear ( ) ) ;
}
}
2022-01-13 22:24:13 +01:00
pub async fn read ( & mut self , buffer : & mut [ u8 ] ) -> Result < ( ) , Error > {
self . rx . read ( buffer ) . await
}
2021-12-15 07:51:26 +01:00
2022-01-13 22:24:13 +01:00
pub async fn write ( & mut self , buffer : & [ u8 ] ) -> Result < ( ) , Error > {
self . tx . write ( buffer ) . await
2021-12-15 07:51:26 +01:00
}
2022-03-08 16:42:46 +01: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 22:23:43 +01:00
pub async fn write_from_ram ( & mut self , buffer : & [ u8 ] ) -> Result < ( ) , Error > {
self . tx . write_from_ram ( buffer ) . await
}
2022-01-13 22:24:13 +01:00
pub fn blocking_read ( & mut self , buffer : & mut [ u8 ] ) -> Result < ( ) , Error > {
self . rx . blocking_read ( buffer )
}
2021-12-15 07:51:26 +01:00
2022-01-13 22:24:13 +01:00
pub fn blocking_write ( & mut self , buffer : & [ u8 ] ) -> Result < ( ) , Error > {
self . tx . blocking_write ( buffer )
2021-12-15 07:51:26 +01:00
}
2022-03-02 22:23:43 +01:00
2022-03-08 16:42:46 +01: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 22:23:43 +01:00
pub fn blocking_write_from_ram ( & mut self , buffer : & [ u8 ] ) -> Result < ( ) , Error > {
self . tx . blocking_write_from_ram ( buffer )
}
2021-12-15 07:51:26 +01:00
}
2022-06-25 23:53:41 +02: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 07:51:26 +01:00
impl < ' d , T : Instance > UarteTx < ' d , T > {
2022-06-25 23:53:41 +02:00
/// Create a new tx-only UARTE without hardware flow control
pub fn new (
2022-07-23 14:00:19 +02:00
uarte : impl Peripheral < P = T > + ' d ,
irq : impl Peripheral < P = T ::Interrupt > + ' d ,
txd : impl Peripheral < P = impl GpioPin > + ' d ,
2022-06-25 23:53:41 +02:00
config : Config ,
) -> Self {
2022-07-23 14:27:45 +02:00
into_ref! ( txd ) ;
Self ::new_inner ( uarte , irq , txd . map_into ( ) , None , config )
2022-06-25 23:53:41 +02:00
}
/// Create a new tx-only UARTE with hardware flow control (RTS/CTS)
pub fn new_with_rtscts (
2022-07-23 14:00:19 +02:00
uarte : impl Peripheral < P = T > + ' d ,
irq : impl Peripheral < P = T ::Interrupt > + ' d ,
txd : impl Peripheral < P = impl GpioPin > + ' d ,
cts : impl Peripheral < P = impl GpioPin > + ' d ,
2022-06-25 23:53:41 +02:00
config : Config ,
) -> Self {
2022-07-23 14:27:45 +02:00
into_ref! ( txd , cts ) ;
Self ::new_inner ( uarte , irq , txd . map_into ( ) , Some ( cts . map_into ( ) ) , config )
2022-06-25 23:53:41 +02:00
}
fn new_inner (
2022-07-23 15:13:47 +02:00
uarte : impl Peripheral < P = T > + ' d ,
2022-07-23 14:00:19 +02:00
irq : impl Peripheral < P = T ::Interrupt > + ' d ,
txd : PeripheralRef < ' d , AnyPin > ,
cts : Option < PeripheralRef < ' d , AnyPin > > ,
2022-06-25 23:53:41 +02:00
config : Config ,
) -> Self {
2022-07-23 15:13:47 +02:00
into_ref! ( uarte , irq ) ;
2022-06-25 23:53:41 +02: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 ) ;
irq . set_handler ( Uarte ::< T > ::on_interrupt ) ;
irq . unpend ( ) ;
irq . enable ( ) ;
let s = T ::state ( ) ;
s . tx_rx_refcount . store ( 1 , Ordering ::Relaxed ) ;
2022-07-23 15:13:47 +02:00
Self { _p : uarte }
2022-06-25 23:53:41 +02:00
}
2022-01-13 22:24:13 +01:00
pub async fn write ( & mut self , buffer : & [ u8 ] ) -> Result < ( ) , Error > {
2022-03-02 22:23:43 +01:00
match self . write_from_ram ( buffer ) . await {
Ok ( _ ) = > Ok ( ( ) ) ,
Err ( Error ::DMABufferNotInDataMemory ) = > {
trace! ( " Copying UARTE tx buffer into RAM for DMA " ) ;
2022-03-02 22:48:58 +01: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 22:23:43 +01:00
}
Err ( error ) = > Err ( error ) ,
}
}
pub async fn write_from_ram ( & mut self , buffer : & [ u8 ] ) -> Result < ( ) , Error > {
2022-01-13 22:24:13 +01:00
slice_in_ram_or ( buffer , Error ::DMABufferNotInDataMemory ) ? ;
if buffer . len ( ) = = 0 {
return Err ( Error ::BufferZeroLength ) ;
}
if buffer . len ( ) > EASY_DMA_SIZE {
return Err ( Error ::BufferTooLong ) ;
2021-12-15 07:51:26 +01:00
}
2022-01-13 22:24:13 +01:00
let ptr = buffer . as_ptr ( ) ;
let len = buffer . len ( ) ;
2021-12-15 07:51:26 +01:00
2022-01-13 22:24:13 +01:00
let r = T ::regs ( ) ;
let s = T ::state ( ) ;
2021-12-15 07:51:26 +01:00
2022-01-13 22:24:13 +01:00
let drop = OnDrop ::new ( move | | {
trace! ( " write drop: stopping " ) ;
2021-12-15 07:51:26 +01:00
2022-01-13 22:24:13 +01:00
r . intenclr . write ( | w | w . endtx ( ) . clear ( ) ) ;
r . events_txstopped . reset ( ) ;
r . tasks_stoptx . write ( | w | unsafe { w . bits ( 1 ) } ) ;
2021-12-15 07:51:26 +01:00
2022-01-13 22:24:13 +01:00
// TX is stopped almost instantly, spinning is fine.
while r . events_endtx . read ( ) . bits ( ) = = 0 { }
trace! ( " write drop: stopped " ) ;
} ) ;
2021-12-15 07:51:26 +01:00
2022-01-13 22:24:13 +01: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 07:51:26 +01:00
2022-01-13 22:24:13 +01:00
r . events_endtx . reset ( ) ;
r . intenset . write ( | w | w . endtx ( ) . set ( ) ) ;
2021-12-15 07:51:26 +01:00
2022-01-13 22:24:13 +01:00
compiler_fence ( Ordering ::SeqCst ) ;
2021-12-15 07:51:26 +01:00
2022-01-13 22:24:13 +01:00
trace! ( " starttx " ) ;
r . tasks_starttx . write ( | w | unsafe { w . bits ( 1 ) } ) ;
2021-12-15 07:51:26 +01:00
2022-01-13 22:24:13 +01: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 07:51:26 +01:00
2022-01-13 22:24:13 +01:00
compiler_fence ( Ordering ::SeqCst ) ;
r . events_txstarted . reset ( ) ;
drop . defuse ( ) ;
2021-12-15 07:51:26 +01:00
2022-01-13 22:24:13 +01:00
Ok ( ( ) )
}
2021-12-15 07:51:26 +01:00
2022-01-13 22:24:13 +01:00
pub fn blocking_write ( & mut self , buffer : & [ u8 ] ) -> Result < ( ) , Error > {
2022-03-02 22:23:43 +01:00
match self . blocking_write_from_ram ( buffer ) {
Ok ( _ ) = > Ok ( ( ) ) ,
Err ( Error ::DMABufferNotInDataMemory ) = > {
trace! ( " Copying UARTE tx buffer into RAM for DMA " ) ;
2022-03-02 22:48:58 +01: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 22:23:43 +01:00
}
Err ( error ) = > Err ( error ) ,
}
}
pub fn blocking_write_from_ram ( & mut self , buffer : & [ u8 ] ) -> Result < ( ) , Error > {
2022-01-13 22:24:13 +01:00
slice_in_ram_or ( buffer , Error ::DMABufferNotInDataMemory ) ? ;
if buffer . len ( ) = = 0 {
return Err ( Error ::BufferZeroLength ) ;
}
if buffer . len ( ) > EASY_DMA_SIZE {
return Err ( Error ::BufferTooLong ) ;
2021-12-15 07:51:26 +01:00
}
2022-01-13 22:24:13 +01: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 07:51:26 +01:00
}
}
impl < ' a , T : Instance > Drop for UarteTx < ' a , T > {
2021-03-26 23:22:06 +01:00
fn drop ( & mut self ) {
2021-12-17 07:06:46 +01:00
trace! ( " uarte tx drop " ) ;
2021-03-26 23:22:06 +01:00
2021-04-14 16:01:43 +02:00
let r = T ::regs ( ) ;
2021-03-26 23:22:06 +01:00
2021-03-27 02:08:58 +01:00
let did_stoptx = r . events_txstarted . read ( ) . bits ( ) ! = 0 ;
2021-12-17 07:06:46 +01:00
trace! ( " did_stoptx {} " , did_stoptx ) ;
2021-03-26 23:22:06 +01:00
2021-12-15 07:51:26 +01:00
// Wait for txstopped, if needed.
while did_stoptx & & r . events_txstopped . read ( ) . bits ( ) = = 0 { }
2021-03-26 23:22:06 +01:00
2021-12-15 21:09:33 +01:00
let s = T ::state ( ) ;
drop_tx_rx ( & r , & s ) ;
2021-12-15 07:51:26 +01:00
}
}
2021-03-26 23:22:06 +01:00
2021-12-15 07:51:26 +01:00
impl < ' d , T : Instance > UarteRx < ' d , T > {
2022-06-25 23:53:41 +02:00
/// Create a new rx-only UARTE without hardware flow control
pub fn new (
2022-07-23 14:00:19 +02:00
uarte : impl Peripheral < P = T > + ' d ,
irq : impl Peripheral < P = T ::Interrupt > + ' d ,
rxd : impl Peripheral < P = impl GpioPin > + ' d ,
2022-06-25 23:53:41 +02:00
config : Config ,
) -> Self {
2022-07-23 14:27:45 +02:00
into_ref! ( rxd ) ;
Self ::new_inner ( uarte , irq , rxd . map_into ( ) , None , config )
2022-06-25 23:53:41 +02:00
}
/// Create a new rx-only UARTE with hardware flow control (RTS/CTS)
pub fn new_with_rtscts (
2022-07-23 14:00:19 +02:00
uarte : impl Peripheral < P = T > + ' d ,
irq : impl Peripheral < P = T ::Interrupt > + ' d ,
rxd : impl Peripheral < P = impl GpioPin > + ' d ,
rts : impl Peripheral < P = impl GpioPin > + ' d ,
2022-06-25 23:53:41 +02:00
config : Config ,
) -> Self {
2022-07-23 14:27:45 +02:00
into_ref! ( rxd , rts ) ;
Self ::new_inner ( uarte , irq , rxd . map_into ( ) , Some ( rts . map_into ( ) ) , config )
2022-06-25 23:53:41 +02:00
}
fn new_inner (
2022-07-23 15:13:47 +02:00
uarte : impl Peripheral < P = T > + ' d ,
2022-07-23 14:00:19 +02:00
irq : impl Peripheral < P = T ::Interrupt > + ' d ,
rxd : PeripheralRef < ' d , AnyPin > ,
rts : Option < PeripheralRef < ' d , AnyPin > > ,
2022-06-25 23:53:41 +02:00
config : Config ,
) -> Self {
2022-07-23 15:13:47 +02:00
into_ref! ( uarte , irq ) ;
2022-06-25 23:53:41 +02: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 ( ) ) ;
irq . set_handler ( Uarte ::< T > ::on_interrupt ) ;
irq . unpend ( ) ;
irq . enable ( ) ;
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 15:13:47 +02:00
Self { _p : uarte }
2022-06-25 23:53:41 +02:00
}
2022-01-13 22:24:13 +01:00
pub async fn read ( & mut self , buffer : & mut [ u8 ] ) -> Result < ( ) , Error > {
if buffer . len ( ) = = 0 {
return Err ( Error ::BufferZeroLength ) ;
}
if buffer . len ( ) > EASY_DMA_SIZE {
return Err ( Error ::BufferTooLong ) ;
2021-12-15 07:51:26 +01:00
}
2020-12-23 16:18:29 +01:00
2022-01-13 22:24:13 +01:00
let ptr = buffer . as_ptr ( ) ;
let len = buffer . len ( ) ;
2021-01-02 19:59:37 +01:00
2022-01-13 22:24:13 +01:00
let r = T ::regs ( ) ;
let s = T ::state ( ) ;
2021-03-22 01:15:44 +01:00
2022-01-13 22:24:13 +01:00
let drop = OnDrop ::new ( move | | {
trace! ( " read drop: stopping " ) ;
2021-03-22 01:15:44 +01:00
2022-01-13 22:24:13 +01:00
r . intenclr . write ( | w | w . endrx ( ) . clear ( ) ) ;
r . events_rxto . reset ( ) ;
r . tasks_stoprx . write ( | w | unsafe { w . bits ( 1 ) } ) ;
2021-03-22 01:15:44 +01:00
2022-01-13 22:24:13 +01:00
while r . events_endrx . read ( ) . bits ( ) = = 0 { }
2021-03-22 01:15:44 +01:00
2022-01-13 22:24:13 +01:00
trace! ( " read drop: stopped " ) ;
} ) ;
2021-03-26 23:22:06 +01:00
2022-01-13 22:24:13 +01: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 01:15:44 +01:00
2022-01-13 22:24:13 +01:00
r . events_endrx . reset ( ) ;
r . intenset . write ( | w | w . endrx ( ) . set ( ) ) ;
2021-03-22 01:15:44 +01:00
2022-01-13 22:24:13 +01:00
compiler_fence ( Ordering ::SeqCst ) ;
2021-03-22 01:15:44 +01:00
2022-01-13 22:24:13 +01:00
trace! ( " startrx " ) ;
r . tasks_startrx . write ( | w | unsafe { w . bits ( 1 ) } ) ;
2021-03-22 01:15:44 +01:00
2022-01-13 22:24:13 +01: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 01:15:44 +01:00
2022-01-13 22:24:13 +01:00
compiler_fence ( Ordering ::SeqCst ) ;
r . events_rxstarted . reset ( ) ;
drop . defuse ( ) ;
2021-03-22 01:15:44 +01:00
2022-01-13 22:24:13 +01:00
Ok ( ( ) )
}
2021-03-22 01:15:44 +01:00
2022-01-13 22:24:13 +01:00
pub fn blocking_read ( & mut self , buffer : & mut [ u8 ] ) -> Result < ( ) , Error > {
if buffer . len ( ) = = 0 {
return Err ( Error ::BufferZeroLength ) ;
}
if buffer . len ( ) > EASY_DMA_SIZE {
return Err ( Error ::BufferTooLong ) ;
2021-01-02 19:59:37 +01:00
}
2022-01-13 22:24:13 +01: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 19:59:37 +01:00
}
}
2021-12-15 07:51:26 +01:00
impl < ' a , T : Instance > Drop for UarteRx < ' a , T > {
fn drop ( & mut self ) {
2021-12-17 07:06:46 +01:00
trace! ( " uarte rx drop " ) ;
2021-12-15 07:51:26 +01:00
let r = T ::regs ( ) ;
let did_stoprx = r . events_rxstarted . read ( ) . bits ( ) ! = 0 ;
2021-12-17 07:06:46 +01:00
trace! ( " did_stoprx {} " , did_stoprx ) ;
2021-12-15 07:51:26 +01:00
// Wait for rxto, if needed.
while did_stoprx & & r . events_rxto . read ( ) . bits ( ) = = 0 { }
2021-12-15 21:09:33 +01:00
let s = T ::state ( ) ;
2021-12-15 07:51:26 +01:00
2021-12-15 21:09:33 +01:00
drop_tx_rx ( & r , & s ) ;
2021-12-15 07:51:26 +01:00
}
}
2021-12-08 01:40:12 +01:00
#[ cfg(not(any(feature = " _nrf9160 " , feature = " nrf5340 " ))) ]
2022-06-18 01:44:02 +02:00
pub ( crate ) fn apply_workaround_for_enable_anomaly ( _r : & crate ::pac ::uarte0 ::RegisterBlock ) {
2021-12-08 01:40:12 +01:00
// Do nothing
}
#[ cfg(any(feature = " _nrf9160 " , feature = " nrf5340 " )) ]
2022-06-18 01:44:02 +02:00
pub ( crate ) fn apply_workaround_for_enable_anomaly ( r : & crate ::pac ::uarte0 ::RegisterBlock ) {
2021-12-08 01:40:12 +01:00
use core ::ops ::Deref ;
// Apply workaround for anomalies:
// - nRF9160 - anomaly 23
// - nRF5340 - anomaly 44
let rxenable_reg : * const u32 = ( ( r . deref ( ) as * const _ as usize ) + 0x564 ) as * const u32 ;
let txenable_reg : * const u32 = ( ( r . deref ( ) as * const _ as usize ) + 0x568 ) as * const u32 ;
// 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 ( ) ) ;
}
}
2022-06-18 01:44:02 +02:00
pub ( crate ) fn drop_tx_rx ( r : & pac ::uarte0 ::RegisterBlock , s : & sealed ::State ) {
2021-12-15 21:09:33 +01:00
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 ( ) ) ;
2021-12-17 07:06:46 +01:00
trace! ( " uarte tx and rx drop: done " ) ;
2021-12-15 21:09:33 +01:00
}
}
2021-05-10 20:20:35 +02:00
/// Interface to an UARTE peripheral that uses an additional timer and two PPI channels,
/// allowing it to implement the ReadUntilIdle trait.
2021-05-10 15:45:40 +02:00
pub struct UarteWithIdle < ' d , U : Instance , T : TimerInstance > {
2022-04-27 20:33:41 +02:00
tx : UarteTx < ' d , U > ,
rx : UarteRxWithIdle < ' d , U , T > ,
2021-05-10 15:45:40 +02:00
}
impl < ' d , U : Instance , T : TimerInstance > UarteWithIdle < ' d , U , T > {
2022-02-12 01:04:01 +01:00
/// Create a new UARTE without hardware flow control
2022-01-13 22:24:13 +01:00
pub fn new (
2022-07-23 14:00:19 +02:00
uarte : impl Peripheral < P = U > + ' d ,
timer : impl Peripheral < P = T > + ' d ,
ppi_ch1 : impl Peripheral < P = impl ConfigurableChannel + ' d > + ' d ,
ppi_ch2 : impl Peripheral < P = impl ConfigurableChannel + ' d > + ' d ,
irq : impl Peripheral < P = U ::Interrupt > + ' d ,
rxd : impl Peripheral < P = impl GpioPin > + ' d ,
txd : impl Peripheral < P = impl GpioPin > + ' d ,
2022-02-12 01:04:01 +01:00
config : Config ,
) -> Self {
2022-07-23 14:27:45 +02:00
into_ref! ( rxd , txd ) ;
Self ::new_inner (
uarte ,
timer ,
ppi_ch1 ,
ppi_ch2 ,
irq ,
rxd . map_into ( ) ,
txd . map_into ( ) ,
None ,
None ,
config ,
)
2022-02-12 01:04:01 +01:00
}
/// Create a new UARTE with hardware flow control (RTS/CTS)
pub fn new_with_rtscts (
2022-07-23 14:00:19 +02:00
uarte : impl Peripheral < P = U > + ' d ,
timer : impl Peripheral < P = T > + ' d ,
ppi_ch1 : impl Peripheral < P = impl ConfigurableChannel + ' d > + ' d ,
ppi_ch2 : impl Peripheral < P = impl ConfigurableChannel + ' d > + ' d ,
irq : impl Peripheral < P = U ::Interrupt > + ' d ,
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 01:04:01 +01:00
config : Config ,
) -> Self {
2022-07-23 14:27:45 +02:00
into_ref! ( rxd , txd , cts , rts ) ;
2022-02-12 01:04:01 +01:00
Self ::new_inner (
uarte ,
timer ,
ppi_ch1 ,
ppi_ch2 ,
irq ,
2022-07-23 14:27:45 +02:00
rxd . map_into ( ) ,
txd . map_into ( ) ,
Some ( cts . map_into ( ) ) ,
Some ( rts . map_into ( ) ) ,
2022-02-12 01:04:01 +01:00
config ,
)
}
fn new_inner (
2022-07-23 14:00:19 +02:00
uarte : impl Peripheral < P = U > + ' d ,
timer : impl Peripheral < P = T > + ' d ,
ppi_ch1 : impl Peripheral < P = impl ConfigurableChannel + ' d > + ' d ,
ppi_ch2 : impl Peripheral < P = impl ConfigurableChannel + ' d > + ' d ,
irq : impl Peripheral < P = U ::Interrupt > + ' d ,
rxd : PeripheralRef < ' d , AnyPin > ,
txd : PeripheralRef < ' d , AnyPin > ,
cts : Option < PeripheralRef < ' d , AnyPin > > ,
rts : Option < PeripheralRef < ' d , AnyPin > > ,
2021-05-10 15:45:40 +02:00
config : Config ,
2021-10-18 16:23:39 +02:00
) -> Self {
2021-05-10 15:45:40 +02:00
let baudrate = config . baudrate ;
2022-04-27 20:33:41 +02:00
let ( tx , rx ) = Uarte ::new_inner ( uarte , irq , rxd , txd , cts , rts , config ) . split ( ) ;
2021-09-02 12:02:31 +02:00
let mut timer = Timer ::new ( timer ) ;
2021-05-10 15:45:40 +02:00
2022-07-23 14:00:19 +02:00
into_ref! ( ppi_ch1 , ppi_ch2 ) ;
2021-05-10 15:45:40 +02:00
let r = U ::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 timeout = 0x8000_0000 / ( baudrate as u32 / 40 ) ;
2021-06-26 09:58:36 +02:00
timer . set_frequency ( Frequency ::F16MHz ) ;
2021-06-29 02:33:41 +02:00
timer . cc ( 0 ) . write ( timeout ) ;
timer . cc ( 0 ) . short_compare_clear ( ) ;
timer . cc ( 0 ) . short_compare_stop ( ) ;
2021-05-10 15:45:40 +02:00
2021-10-18 16:23:39 +02:00
let mut ppi_ch1 = Ppi ::new_one_to_two (
2022-07-23 14:27:45 +02:00
ppi_ch1 . map_into ( ) ,
2021-10-18 16:23:39 +02:00
Event ::from_reg ( & r . events_rxdrdy ) ,
timer . task_clear ( ) ,
timer . task_start ( ) ,
2021-10-26 09:45:29 +02:00
) ;
2021-05-10 15:45:40 +02:00
ppi_ch1 . enable ( ) ;
2021-10-18 16:23:39 +02:00
let mut ppi_ch2 = Ppi ::new_one_to_one (
2022-07-23 14:27:45 +02:00
ppi_ch2 . map_into ( ) ,
2021-10-18 16:23:39 +02:00
timer . cc ( 0 ) . event_compare ( ) ,
Task ::from_reg ( & r . tasks_stoprx ) ,
2021-10-26 09:45:29 +02:00
) ;
2021-05-10 15:45:40 +02:00
ppi_ch2 . enable ( ) ;
2021-10-18 16:23:39 +02:00
Self {
2022-04-27 20:33:41 +02:00
tx ,
rx : UarteRxWithIdle {
rx ,
timer ,
ppi_ch1 : ppi_ch1 ,
_ppi_ch2 : ppi_ch2 ,
} ,
2021-10-18 16:23:39 +02:00
}
2021-05-10 15:45:40 +02:00
}
2022-04-27 20:33:41 +02:00
/// Split the Uarte into a transmitter and receiver, which is
/// particuarly useful when having two tasks correlating to
/// transmitting and receiving.
pub fn split ( self ) -> ( UarteTx < ' d , U > , UarteRxWithIdle < ' d , U , T > ) {
( self . tx , self . rx )
}
2022-01-13 22:24:13 +01:00
pub async fn read ( & mut self , buffer : & mut [ u8 ] ) -> Result < ( ) , Error > {
2022-04-27 20:33:41 +02:00
self . rx . read ( buffer ) . await
2022-01-13 22:24:13 +01:00
}
2021-05-10 15:45:40 +02:00
2022-01-13 22:24:13 +01:00
pub async fn write ( & mut self , buffer : & [ u8 ] ) -> Result < ( ) , Error > {
2022-04-27 20:33:41 +02:00
self . tx . write ( buffer ) . await
2022-01-13 22:24:13 +01:00
}
2021-05-10 15:45:40 +02:00
2022-01-13 22:24:13 +01:00
pub fn blocking_read ( & mut self , buffer : & mut [ u8 ] ) -> Result < ( ) , Error > {
2022-04-27 20:33:41 +02:00
self . rx . blocking_read ( buffer )
2022-01-13 22:24:13 +01:00
}
2021-05-10 15:45:40 +02:00
2022-01-13 22:24:13 +01:00
pub fn blocking_write ( & mut self , buffer : & [ u8 ] ) -> Result < ( ) , Error > {
2022-04-27 20:33:41 +02:00
self . tx . blocking_write ( buffer )
}
pub async fn read_until_idle ( & mut self , buffer : & mut [ u8 ] ) -> Result < usize , Error > {
self . rx . read_until_idle ( buffer ) . await
}
pub fn blocking_read_until_idle ( & mut self , buffer : & mut [ u8 ] ) -> Result < usize , Error > {
self . rx . blocking_read_until_idle ( buffer )
}
}
pub struct UarteRxWithIdle < ' d , U : Instance , T : TimerInstance > {
rx : UarteRx < ' d , U > ,
timer : Timer < ' d , T > ,
ppi_ch1 : Ppi < ' d , AnyConfigurableChannel , 1 , 2 > ,
_ppi_ch2 : Ppi < ' d , AnyConfigurableChannel , 1 , 1 > ,
}
impl < ' d , U : Instance , T : TimerInstance > UarteRxWithIdle < ' d , U , T > {
pub async fn read ( & mut self , buffer : & mut [ u8 ] ) -> Result < ( ) , Error > {
self . ppi_ch1 . disable ( ) ;
self . rx . read ( buffer ) . await
}
pub fn blocking_read ( & mut self , buffer : & mut [ u8 ] ) -> Result < ( ) , Error > {
self . ppi_ch1 . disable ( ) ;
self . rx . blocking_read ( buffer )
2022-01-13 22:24:13 +01:00
}
2021-05-10 15:45:40 +02:00
2022-01-13 22:24:13 +01:00
pub async fn read_until_idle ( & mut self , buffer : & mut [ u8 ] ) -> Result < usize , Error > {
if buffer . len ( ) = = 0 {
return Err ( Error ::BufferZeroLength ) ;
}
if buffer . len ( ) > EASY_DMA_SIZE {
return Err ( Error ::BufferTooLong ) ;
}
2021-05-10 15:45:40 +02:00
2022-01-13 22:24:13 +01:00
let ptr = buffer . as_ptr ( ) ;
let len = buffer . len ( ) ;
2021-05-10 15:45:40 +02:00
2022-01-13 22:24:13 +01:00
let r = U ::regs ( ) ;
let s = U ::state ( ) ;
2021-05-10 15:45:40 +02:00
2022-01-13 22:24:13 +01:00
self . ppi_ch1 . enable ( ) ;
2021-05-10 15:45:40 +02:00
2022-01-13 22:24:13 +01:00
let drop = OnDrop ::new ( | | {
self . timer . stop ( ) ;
2021-05-10 15:45:40 +02:00
2022-01-13 22:24:13 +01:00
r . intenclr . write ( | w | w . endrx ( ) . clear ( ) ) ;
r . events_rxto . reset ( ) ;
r . tasks_stoprx . write ( | w | unsafe { w . bits ( 1 ) } ) ;
2021-05-10 15:45:40 +02:00
2022-01-13 22:24:13 +01:00
while r . events_endrx . read ( ) . bits ( ) = = 0 { }
} ) ;
2021-05-10 20:16:13 +02:00
2022-01-13 22:24:13 +01: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 20:16:52 +02:00
2022-01-13 22:24:13 +01:00
r . events_endrx . reset ( ) ;
r . intenset . write ( | w | w . endrx ( ) . set ( ) ) ;
2021-05-10 15:45:40 +02:00
2022-01-13 22:24:13 +01: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 15:45:40 +02:00
}
2022-01-13 22:24:13 +01:00
pub fn blocking_read_until_idle ( & mut self , buffer : & mut [ u8 ] ) -> Result < usize , Error > {
if buffer . len ( ) = = 0 {
return Err ( Error ::BufferZeroLength ) ;
}
if buffer . len ( ) > EASY_DMA_SIZE {
return Err ( Error ::BufferTooLong ) ;
2021-05-10 20:16:52 +02:00
}
2021-05-10 15:45:40 +02:00
2022-01-13 22:24:13 +01:00
let ptr = buffer . as_ptr ( ) ;
let len = buffer . len ( ) ;
let r = U ::regs ( ) ;
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 15:45:40 +02:00
2022-01-13 22:24:13 +01:00
Ok ( n )
2021-05-10 15:45:40 +02:00
}
}
2021-05-11 03:04:59 +02:00
pub ( crate ) mod sealed {
2021-12-15 21:09:33 +01:00
use core ::sync ::atomic ::AtomicU8 ;
2022-08-22 21:46:09 +02:00
use embassy_sync ::waitqueue ::AtomicWaker ;
2021-09-11 01:53:53 +02:00
2021-03-22 01:15:44 +01:00
use super ::* ;
2020-12-23 16:18:29 +01:00
2021-04-14 16:01:43 +02:00
pub struct State {
pub endrx_waker : AtomicWaker ,
pub endtx_waker : AtomicWaker ,
2021-12-15 21:09:33 +01:00
pub tx_rx_refcount : AtomicU8 ,
2021-04-14 16:01:43 +02:00
}
impl State {
pub const fn new ( ) -> Self {
Self {
endrx_waker : AtomicWaker ::new ( ) ,
endtx_waker : AtomicWaker ::new ( ) ,
2021-12-16 08:15:28 +01:00
tx_rx_refcount : AtomicU8 ::new ( 0 ) ,
2021-04-14 16:01:43 +02:00
}
}
}
2021-03-22 01:15:44 +01:00
pub trait Instance {
2021-10-12 11:43:57 +02:00
fn regs ( ) -> & 'static pac ::uarte0 ::RegisterBlock ;
2021-04-14 16:01:43 +02:00
fn state ( ) -> & 'static State ;
2021-03-22 01:15:44 +01:00
}
2020-12-23 16:18:29 +01:00
}
2022-07-23 14:00:19 +02:00
pub trait Instance : Peripheral < P = Self > + sealed ::Instance + 'static + Send {
2021-02-26 01:55:27 +01:00
type Interrupt : Interrupt ;
2020-12-23 16:18:29 +01:00
}
2021-05-11 03:04:59 +02:00
macro_rules ! impl_uarte {
( $type :ident , $pac_type :ident , $irq :ident ) = > {
impl crate ::uarte ::sealed ::Instance for peripherals ::$type {
2021-10-12 11:43:57 +02:00
fn regs ( ) -> & 'static pac ::uarte0 ::RegisterBlock {
2021-05-11 03:04:59 +02:00
unsafe { & * pac ::$pac_type ::ptr ( ) }
2021-03-22 01:15:44 +01:00
}
2021-05-11 03:04:59 +02:00
fn state ( ) -> & 'static crate ::uarte ::sealed ::State {
static STATE : crate ::uarte ::sealed ::State = crate ::uarte ::sealed ::State ::new ( ) ;
2021-04-14 16:01:43 +02:00
& STATE
}
2021-03-22 01:15:44 +01:00
}
2021-05-11 03:04:59 +02:00
impl crate ::uarte ::Instance for peripherals ::$type {
type Interrupt = crate ::interrupt ::$irq ;
2021-03-22 01:15:44 +01:00
}
} ;
2020-12-23 16:18:29 +01:00
}
2022-01-13 23:56:25 +01: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 ( ( ) )
}
}
2022-06-12 22:15:44 +02:00
impl < ' d , U : Instance , T : TimerInstance > embedded_hal_02 ::blocking ::serial ::Write < u8 > for UarteWithIdle < ' d , U , T > {
2022-01-13 23:56:25 +01:00
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 ( ( ) )
}
}
}
#[ cfg(feature = " unstable-traits " ) ]
mod eh1 {
use super ::* ;
impl embedded_hal_1 ::serial ::Error for Error {
fn kind ( & self ) -> embedded_hal_1 ::serial ::ErrorKind {
match * self {
Self ::BufferTooLong = > embedded_hal_1 ::serial ::ErrorKind ::Other ,
Self ::BufferZeroLength = > embedded_hal_1 ::serial ::ErrorKind ::Other ,
Self ::DMABufferNotInDataMemory = > embedded_hal_1 ::serial ::ErrorKind ::Other ,
}
}
}
// =====================
impl < ' d , T : Instance > embedded_hal_1 ::serial ::ErrorType for Uarte < ' d , T > {
type Error = Error ;
}
impl < ' d , T : Instance > embedded_hal_1 ::serial ::blocking ::Write for Uarte < ' d , T > {
fn write ( & mut self , buffer : & [ u8 ] ) -> Result < ( ) , Self ::Error > {
self . blocking_write ( buffer )
}
fn flush ( & mut self ) -> Result < ( ) , Self ::Error > {
Ok ( ( ) )
}
}
2022-02-12 00:24:04 +01:00
impl < ' d , T : Instance > embedded_hal_1 ::serial ::ErrorType for UarteTx < ' d , T > {
type Error = Error ;
}
impl < ' d , T : Instance > embedded_hal_1 ::serial ::blocking ::Write for UarteTx < ' d , T > {
fn write ( & mut self , buffer : & [ u8 ] ) -> Result < ( ) , Self ::Error > {
self . blocking_write ( buffer )
}
fn flush ( & mut self ) -> Result < ( ) , Self ::Error > {
Ok ( ( ) )
}
}
impl < ' d , T : Instance > embedded_hal_1 ::serial ::ErrorType for UarteRx < ' d , T > {
type Error = Error ;
}
2022-06-12 22:15:44 +02:00
impl < ' d , U : Instance , T : TimerInstance > embedded_hal_1 ::serial ::ErrorType for UarteWithIdle < ' d , U , T > {
2022-02-12 00:24:04 +01:00
type Error = Error ;
}
}
2022-02-16 03:54:39 +01:00
cfg_if ::cfg_if! {
2022-04-22 19:58:24 +02:00
if #[ cfg(all(feature = " unstable-traits " , feature = " nightly " , feature = " _todo_embedded_hal_serial " )) ] {
2022-02-16 03:54:39 +01:00
use core ::future ::Future ;
2022-02-12 00:24:04 +01:00
2022-02-16 03:54:39 +01:00
impl < ' d , T : Instance > embedded_hal_async ::serial ::Read for Uarte < ' d , T > {
type ReadFuture < ' a > = impl Future < Output = Result < ( ) , Self ::Error > > + ' a where Self : ' a ;
2022-01-13 23:56:25 +01:00
2022-02-16 03:54:39 +01:00
fn read < ' a > ( & ' a mut self , buffer : & ' a mut [ u8 ] ) -> Self ::ReadFuture < ' a > {
self . read ( buffer )
}
2022-01-13 23:56:25 +01:00
}
2022-02-16 03:54:39 +01:00
impl < ' d , T : Instance > embedded_hal_async ::serial ::Write for Uarte < ' d , T > {
type WriteFuture < ' a > = impl Future < Output = Result < ( ) , Self ::Error > > + ' a where Self : ' a ;
2022-01-13 23:56:25 +01:00
2022-02-16 03:54:39 +01:00
fn write < ' a > ( & ' a mut self , buffer : & ' a [ u8 ] ) -> Self ::WriteFuture < ' a > {
self . write ( buffer )
}
2022-01-13 23:56:25 +01:00
2022-02-16 03:54:39 +01:00
type FlushFuture < ' a > = impl Future < Output = Result < ( ) , Self ::Error > > + ' a where Self : ' a ;
2022-01-13 23:56:25 +01:00
2022-02-16 03:54:39 +01:00
fn flush < ' a > ( & ' a mut self ) -> Self ::FlushFuture < ' a > {
async move { Ok ( ( ) ) }
}
2022-01-13 23:56:25 +01:00
}
2022-02-16 03:54:39 +01:00
impl < ' d , T : Instance > embedded_hal_async ::serial ::Write for UarteTx < ' d , T > {
type WriteFuture < ' a > = impl Future < Output = Result < ( ) , Self ::Error > > + ' a where Self : ' a ;
2022-01-13 23:56:25 +01:00
2022-02-16 03:54:39 +01:00
fn write < ' a > ( & ' a mut self , buffer : & ' a [ u8 ] ) -> Self ::WriteFuture < ' a > {
self . write ( buffer )
}
2022-01-13 23:56:25 +01:00
2022-02-16 03:54:39 +01:00
type FlushFuture < ' a > = impl Future < Output = Result < ( ) , Self ::Error > > + ' a where Self : ' a ;
2022-01-13 23:56:25 +01:00
2022-02-16 03:54:39 +01:00
fn flush < ' a > ( & ' a mut self ) -> Self ::FlushFuture < ' a > {
async move { Ok ( ( ) ) }
}
2022-01-13 23:56:25 +01:00
}
2022-02-16 03:54:39 +01:00
impl < ' d , T : Instance > embedded_hal_async ::serial ::Read for UarteRx < ' d , T > {
type ReadFuture < ' a > = impl Future < Output = Result < ( ) , Self ::Error > > + ' a where Self : ' a ;
2022-01-13 23:56:25 +01:00
2022-02-16 03:54:39 +01:00
fn read < ' a > ( & ' a mut self , buffer : & ' a mut [ u8 ] ) -> Self ::ReadFuture < ' a > {
self . read ( buffer )
}
2022-01-13 23:56:25 +01:00
}
2022-02-16 03:54:39 +01:00
impl < ' d , U : Instance , T : TimerInstance > embedded_hal_async ::serial ::Read
for UarteWithIdle < ' d , U , T >
{
type ReadFuture < ' a > = impl Future < Output = Result < ( ) , Self ::Error > > + ' a where Self : ' a ;
2022-01-13 23:56:25 +01:00
2022-02-16 03:54:39 +01:00
fn read < ' a > ( & ' a mut self , buffer : & ' a mut [ u8 ] ) -> Self ::ReadFuture < ' a > {
self . read ( buffer )
}
2022-01-13 23:56:25 +01:00
}
2022-02-16 03:54:39 +01:00
impl < ' d , U : Instance , T : TimerInstance > embedded_hal_async ::serial ::Write
for UarteWithIdle < ' d , U , T >
{
type WriteFuture < ' a > = impl Future < Output = Result < ( ) , Self ::Error > > + ' a where Self : ' a ;
2022-01-13 23:56:25 +01:00
2022-02-16 03:54:39 +01:00
fn write < ' a > ( & ' a mut self , buffer : & ' a [ u8 ] ) -> Self ::WriteFuture < ' a > {
self . write ( buffer )
}
2022-01-13 23:56:25 +01:00
2022-02-16 03:54:39 +01:00
type FlushFuture < ' a > = impl Future < Output = Result < ( ) , Self ::Error > > + ' a where Self : ' a ;
2022-01-13 23:56:25 +01:00
2022-02-16 03:54:39 +01:00
fn flush < ' a > ( & ' a mut self ) -> Self ::FlushFuture < ' a > {
async move { Ok ( ( ) ) }
}
2022-01-13 23:56:25 +01:00
}
}
}