33//! Check the documentation of [`Usart`] for details.
44
55use core:: cmp:: Ordering ;
6+ use core:: convert:: Infallible ;
67use core:: marker;
78
9+ use embedded_io:: ErrorType ;
10+
811use crate :: port;
912
1013/// Representation of a USART baudrate
@@ -183,21 +186,21 @@ pub trait UsartOps<H, RX, TX> {
183186 /// was flushed yet.
184187 ///
185188 /// **Warning**: This is a low-level method and should not be called directly from user code.
186- fn raw_flush ( & mut self ) -> nb:: Result < ( ) , core :: convert :: Infallible > ;
189+ fn raw_flush ( & mut self ) -> nb:: Result < ( ) , Infallible > ;
187190 /// Write a byte to the TX buffer.
188191 ///
189192 /// This operation must be non-blocking and return [`nb::Error::WouldBlock`] until the byte is
190193 /// enqueued. The operation should not wait for the byte to have actually been sent.
191194 ///
192195 /// **Warning**: This is a low-level method and should not be called directly from user code.
193- fn raw_write ( & mut self , byte : u8 ) -> nb:: Result < ( ) , core :: convert :: Infallible > ;
196+ fn raw_write ( & mut self , byte : u8 ) -> nb:: Result < ( ) , Infallible > ;
194197 /// Read a byte from the RX buffer.
195198 ///
196199 /// This operation must be non-blocking and return [`nb::Error::WouldBlock`] if no incoming
197200 /// byte is available.
198201 ///
199202 /// **Warning**: This is a low-level method and should not be called directly from user code.
200- fn raw_read ( & mut self ) -> nb:: Result < u8 , core :: convert :: Infallible > ;
203+ fn raw_read ( & mut self ) -> nb:: Result < u8 , Infallible > ;
201204
202205 /// Enable/Disable a certain interrupt.
203206 ///
@@ -335,7 +338,7 @@ impl<H, USART: UsartOps<H, RX, TX>, RX, TX, CLOCK> Usart<H, USART, RX, TX, CLOCK
335338}
336339
337340impl < H , USART : UsartOps < H , RX , TX > , RX , TX , CLOCK > ufmt:: uWrite for Usart < H , USART , RX , TX , CLOCK > {
338- type Error = core :: convert :: Infallible ;
341+ type Error = Infallible ;
339342
340343 fn write_str ( & mut self , s : & str ) -> Result < ( ) , Self :: Error > {
341344 for b in s. as_bytes ( ) . iter ( ) {
@@ -348,7 +351,7 @@ impl<H, USART: UsartOps<H, RX, TX>, RX, TX, CLOCK> ufmt::uWrite for Usart<H, USA
348351impl < H , USART : UsartOps < H , RX , TX > , RX , TX , CLOCK > hal:: serial:: Write < u8 >
349352 for Usart < H , USART , RX , TX , CLOCK >
350353{
351- type Error = core :: convert :: Infallible ;
354+ type Error = Infallible ;
352355
353356 fn write ( & mut self , byte : u8 ) -> nb:: Result < ( ) , Self :: Error > {
354357 self . p . raw_write ( byte)
@@ -359,16 +362,60 @@ impl<H, USART: UsartOps<H, RX, TX>, RX, TX, CLOCK> hal::serial::Write<u8>
359362 }
360363}
361364
365+ impl < H , USART : UsartOps < H , RX , TX > , RX , TX , CLOCK > ErrorType for Usart < H , USART , RX , TX , CLOCK > { type Error = embedded_io:: ErrorKind ; }
366+
367+ impl < H , USART : UsartOps < H , RX , TX > , RX , TX , CLOCK > embedded_io:: Write for Usart < H , USART , RX , TX , CLOCK > {
368+ fn write ( & mut self , buf : & [ u8 ] ) -> Result < usize , Self :: Error > {
369+ for byte in buf {
370+ self . write_byte ( * byte) ;
371+ }
372+ Ok ( buf. len ( ) )
373+ }
374+
375+ fn flush ( & mut self ) -> Result < ( ) , Self :: Error > {
376+ self . p . raw_flush ( ) . unwrap ( ) ; // `raw_write` is `Infallible`
377+ Ok ( ( ) )
378+ }
379+ }
380+
362381impl < H , USART : UsartOps < H , RX , TX > , RX , TX , CLOCK > hal:: serial:: Read < u8 >
363382 for Usart < H , USART , RX , TX , CLOCK >
364383{
365- type Error = core :: convert :: Infallible ;
384+ type Error = Infallible ;
366385
367386 fn read ( & mut self ) -> nb:: Result < u8 , Self :: Error > {
368387 self . p . raw_read ( )
369388 }
370389}
371390
391+ impl < H , USART : UsartOps < H , RX , TX > , RX , TX , CLOCK > embedded_io:: Read for Usart < H , USART , RX , TX , CLOCK > {
392+ fn read ( & mut self , buf : & mut [ u8 ] ) -> Result < usize , Self :: Error > {
393+ // block for first byte
394+ buf[ 0 ] = self . read_byte ( ) ;
395+ let mut i = 1 ;
396+
397+ // grab more bytes when available
398+ loop {
399+ match self . p . raw_read ( ) {
400+ Ok ( byte) => {
401+ buf[ i] = byte;
402+ i += 1 ;
403+
404+ if i == buf. len ( ) {
405+ return Ok ( i) ;
406+ }
407+ }
408+ Err ( nb:: Error :: WouldBlock ) => {
409+ return Ok ( i) ;
410+ }
411+ Err ( _) => {
412+ unreachable ! ( ) ; // `raw_read` is `Infallible`
413+ }
414+ }
415+ }
416+ }
417+ }
418+
372419/// Writer half of a [`Usart`] peripheral.
373420///
374421/// Created by calling [`Usart::split`]. Splitting a peripheral into reader and writer allows
@@ -412,6 +459,14 @@ impl<H, USART: UsartOps<H, RX, TX>, RX, TX, CLOCK> UsartWriter<H, USART, RX, TX,
412459 _h : marker:: PhantomData ,
413460 }
414461 }
462+
463+ /// Transmit a byte.
464+ ///
465+ /// This method will block until the byte has been enqueued for transmission but **not** until
466+ /// it was entirely sent.
467+ fn write_byte ( & mut self , byte : u8 ) {
468+ nb:: block!( self . p. raw_write( byte) ) . unwrap ( )
469+ }
415470}
416471
417472impl < H , USART : UsartOps < H , RX , TX > , RX , TX , CLOCK > UsartReader < H , USART , RX , TX , CLOCK > {
@@ -433,7 +488,7 @@ impl<H, USART: UsartOps<H, RX, TX>, RX, TX, CLOCK> UsartReader<H, USART, RX, TX,
433488impl < H , USART : UsartOps < H , RX , TX > , RX , TX , CLOCK > ufmt:: uWrite
434489 for UsartWriter < H , USART , RX , TX , CLOCK >
435490{
436- type Error = core :: convert :: Infallible ;
491+ type Error = Infallible ;
437492
438493 fn write_str ( & mut self , s : & str ) -> Result < ( ) , Self :: Error > {
439494 for b in s. as_bytes ( ) . iter ( ) {
@@ -446,7 +501,7 @@ impl<H, USART: UsartOps<H, RX, TX>, RX, TX, CLOCK> ufmt::uWrite
446501impl < H , USART : UsartOps < H , RX , TX > , RX , TX , CLOCK > hal:: serial:: Write < u8 >
447502 for UsartWriter < H , USART , RX , TX , CLOCK >
448503{
449- type Error = core :: convert :: Infallible ;
504+ type Error = Infallible ;
450505
451506 fn write ( & mut self , byte : u8 ) -> nb:: Result < ( ) , Self :: Error > {
452507 self . p . raw_write ( byte)
@@ -457,16 +512,59 @@ impl<H, USART: UsartOps<H, RX, TX>, RX, TX, CLOCK> hal::serial::Write<u8>
457512 }
458513}
459514
515+ impl < H , USART : UsartOps < H , RX , TX > , RX , TX , CLOCK > ErrorType for UsartWriter < H , USART , RX , TX , CLOCK > { type Error = Infallible ; }
516+
517+ impl < H , USART : UsartOps < H , RX , TX > , RX , TX , CLOCK > embedded_io:: Write for UsartWriter < H , USART , RX , TX , CLOCK > {
518+ fn write ( & mut self , buf : & [ u8 ] ) -> Result < usize , Self :: Error > {
519+ for byte in buf {
520+ self . write_byte ( * byte) ;
521+ }
522+ Ok ( buf. len ( ) )
523+ }
524+
525+ fn flush ( & mut self ) -> Result < ( ) , Self :: Error > {
526+ self . p . raw_flush ( ) . unwrap ( ) ; // `raw_flush` is `Infallible`
527+ Ok ( ( ) )
528+ }
529+ }
530+
460531impl < H , USART : UsartOps < H , RX , TX > , RX , TX , CLOCK > hal:: serial:: Read < u8 >
461532 for UsartReader < H , USART , RX , TX , CLOCK >
462533{
463- type Error = core :: convert :: Infallible ;
534+ type Error = Infallible ;
464535
465536 fn read ( & mut self ) -> nb:: Result < u8 , Self :: Error > {
466537 self . p . raw_read ( )
467538 }
468539}
469540
541+
542+ impl < H , USART : UsartOps < H , RX , TX > , RX , TX , CLOCK > ErrorType for UsartReader < H , USART , RX , TX , CLOCK > { type Error = Infallible ; }
543+
544+ impl < H , USART : UsartOps < H , RX , TX > , RX , TX , CLOCK > embedded_io:: Read for UsartReader < H , USART , RX , TX , CLOCK > {
545+ fn read ( & mut self , buf : & mut [ u8 ] ) -> Result < usize , Self :: Error > {
546+ let mut i = 0 ;
547+ loop {
548+ match self . p . raw_read ( ) {
549+ Ok ( byte) => {
550+ buf[ i] = byte;
551+ i += 1 ;
552+
553+ if i == buf. len ( ) {
554+ return Ok ( i) ;
555+ }
556+ }
557+ Err ( nb:: Error :: WouldBlock ) => {
558+ return Ok ( i) ;
559+ }
560+ Err ( _) => {
561+ unreachable ! ( ) ; // `raw_read` is `Infallible`
562+ }
563+ }
564+ }
565+ }
566+ }
567+
470568#[ macro_export]
471569macro_rules! impl_usart_traditional {
472570 (
0 commit comments