4
4
//!
5
5
//! - nrf52832: Section 35
6
6
//! - nrf52840: Section 6.34
7
+
8
+ use core:: cmp:: min;
7
9
use core:: fmt;
10
+ use core:: hint:: spin_loop;
8
11
use core:: ops:: Deref ;
9
12
use core:: sync:: atomic:: { compiler_fence, Ordering :: SeqCst } ;
10
-
11
13
use embedded_hal_02:: blocking:: serial as bserial;
12
14
use embedded_hal_02:: digital:: v2:: OutputPin ;
13
15
use embedded_hal_02:: serial;
16
+ use embedded_io:: { ErrorKind , ErrorType , ReadReady , WriteReady } ;
14
17
15
18
#[ cfg( any( feature = "52833" , feature = "52840" ) ) ]
16
19
use crate :: pac:: UARTE1 ;
17
20
18
21
#[ cfg( feature = "9160" ) ]
19
22
use crate :: pac:: {
20
- uarte0_ns as uarte0,
21
- UARTE0_NS as UARTE0 ,
22
- UARTE1_NS as UARTE1 ,
23
- UARTE2_NS as UARTE2 ,
23
+ uarte0_ns as uarte0, UARTE0_NS as UARTE0 , UARTE1_NS as UARTE1 , UARTE2_NS as UARTE2 ,
24
24
UARTE3_NS as UARTE3 ,
25
25
} ;
26
26
@@ -421,6 +421,9 @@ fn start_read(uarte: &uarte0::RegisterBlock, rx_buffer: &mut [u8]) -> Result<(),
421
421
uarte. tasks_startrx . write ( |w|
422
422
// `1` is a valid value to write to task registers.
423
423
unsafe { w. bits ( 1 ) } ) ;
424
+ while uarte. events_rxstarted . read ( ) . bits ( ) == 0 {
425
+ spin_loop ( ) ;
426
+ }
424
427
425
428
Ok ( ( ) )
426
429
}
@@ -492,6 +495,20 @@ pub enum Error {
492
495
BufferNotInRAM ,
493
496
}
494
497
498
+ impl embedded_io:: Error for Error {
499
+ fn kind ( & self ) -> ErrorKind {
500
+ match self {
501
+ Self :: TxBufferTooSmall
502
+ | Self :: RxBufferTooSmall
503
+ | Self :: TxBufferTooLong
504
+ | Self :: RxBufferTooLong
505
+ | Self :: BufferNotInRAM => ErrorKind :: InvalidInput ,
506
+ Self :: Transmit | Self :: Receive => ErrorKind :: Interrupted ,
507
+ Self :: Timeout ( _) => ErrorKind :: TimedOut ,
508
+ }
509
+ }
510
+ }
511
+
495
512
pub trait Instance : Deref < Target = uarte0:: RegisterBlock > + sealed:: Sealed {
496
513
fn ptr ( ) -> * const uarte0:: RegisterBlock ;
497
514
}
@@ -662,6 +679,52 @@ where
662
679
}
663
680
}
664
681
682
+ impl < T : Instance > ErrorType for UarteTx < T > {
683
+ type Error = Error ;
684
+ }
685
+
686
+ impl < T : Instance > WriteReady for UarteTx < T > {
687
+ fn write_ready ( & mut self ) -> Result < bool , Self :: Error > {
688
+ let uarte = unsafe { & * T :: ptr ( ) } ;
689
+
690
+ let dma_transfer_in_progress =
691
+ uarte. events_txstarted . read ( ) . bits ( ) == 1 && uarte. events_endtx . read ( ) . bits ( ) == 0 ;
692
+
693
+ Ok ( !dma_transfer_in_progress && self . written < self . tx_buf . len ( ) )
694
+ }
695
+ }
696
+
697
+ impl < T : Instance > embedded_io:: Write for UarteTx < T > {
698
+ fn write ( & mut self , buf : & [ u8 ] ) -> Result < usize , Self :: Error > {
699
+ if buf. is_empty ( ) {
700
+ return Ok ( 0 ) ;
701
+ }
702
+
703
+ // If the internal buffer is full or a DMA transfer is in progress, flush and block until it
704
+ // is finished.
705
+ if !self . write_ready ( ) ? {
706
+ nb:: block!( serial:: Write :: flush( self ) ) ?;
707
+ }
708
+
709
+ // Copy as many bytes as possible to the internal TX buffer.
710
+ let length_to_copy = min ( buf. len ( ) , self . tx_buf . len ( ) - self . written ) ;
711
+ self . tx_buf [ self . written ..] . copy_from_slice ( & buf[ ..length_to_copy] ) ;
712
+ self . written += length_to_copy;
713
+
714
+ // If the internal buffer is now full, flush but don't block.
715
+ match serial:: Write :: flush ( self ) {
716
+ Err ( nb:: Error :: Other ( e) ) => return Err ( e) ,
717
+ _ => { }
718
+ }
719
+
720
+ Ok ( length_to_copy)
721
+ }
722
+
723
+ fn flush ( & mut self ) -> Result < ( ) , Self :: Error > {
724
+ nb:: block!( serial:: Write :: flush( self ) )
725
+ }
726
+ }
727
+
665
728
impl < T > serial:: Write < u8 > for UarteTx < T >
666
729
where
667
730
T : Instance ,
@@ -748,6 +811,59 @@ where
748
811
}
749
812
}
750
813
814
+ impl < T : Instance > ErrorType for UarteRx < T > {
815
+ type Error = Error ;
816
+ }
817
+
818
+ impl < T : Instance > ReadReady for UarteRx < T > {
819
+ fn read_ready ( & mut self ) -> Result < bool , Self :: Error > {
820
+ let uarte = unsafe { & * T :: ptr ( ) } ;
821
+
822
+ compiler_fence ( SeqCst ) ;
823
+
824
+ if uarte. events_rxstarted . read ( ) . bits ( ) == 0 {
825
+ start_read ( uarte, self . rx_buf ) ?;
826
+ Ok ( false )
827
+ } else {
828
+ Ok ( uarte. events_endrx . read ( ) . bits ( ) != 0 )
829
+ }
830
+ }
831
+ }
832
+
833
+ impl < T : Instance > embedded_io:: Read for UarteRx < T > {
834
+ fn read ( & mut self , buf : & mut [ u8 ] ) -> Result < usize , Self :: Error > {
835
+ if buf. is_empty ( ) {
836
+ return Ok ( 0 ) ;
837
+ }
838
+
839
+ let uarte = unsafe { & * T :: ptr ( ) } ;
840
+
841
+ compiler_fence ( SeqCst ) ;
842
+
843
+ // This complexity to handle in-progress reads is needed because calls to this read method
844
+ // might be interleaved with calls to serial::Read::read.
845
+
846
+ // If no read transaction is started yet, start one and wait for it to start.
847
+ if uarte. events_rxstarted . read ( ) . bits ( ) == 0 {
848
+ start_read ( & uarte, self . rx_buf ) ?;
849
+ }
850
+
851
+ // Wait for the transaction to finish.
852
+ while uarte. events_endrx . read ( ) . bits ( ) == 0 {
853
+ spin_loop ( ) ;
854
+ }
855
+
856
+ // Tidy up and return the byte read.
857
+ uarte. events_rxstarted . reset ( ) ;
858
+ finalize_read ( uarte) ;
859
+ if uarte. rxd . amount . read ( ) . bits ( ) != 1 {
860
+ return Err ( Error :: Receive ) ;
861
+ }
862
+ buf[ 0 ] = self . rx_buf [ 0 ] ;
863
+ Ok ( 1 )
864
+ }
865
+ }
866
+
751
867
impl < T > serial:: Read < u8 > for UarteRx < T >
752
868
where
753
869
T : Instance ,
@@ -768,7 +884,7 @@ where
768
884
769
885
finalize_read ( uarte) ;
770
886
771
- if uarte. rxd . amount . read ( ) . bits ( ) != 1 as u32 {
887
+ if uarte. rxd . amount . read ( ) . bits ( ) != 1 {
772
888
return Err ( nb:: Error :: Other ( Error :: Receive ) ) ;
773
889
}
774
890
Ok ( self . rx_buf [ 0 ] )
0 commit comments