33//! Check the documentation of [`Usart`] for details.
44
55use core:: cmp:: Ordering ;
6+ use core:: convert:: Infallible ;
67use core:: marker;
78use crate :: prelude:: * ;
89
10+ use embedded_io:: ErrorType ;
11+
912use crate :: port;
1013
1114/// Representation of a USART baudrate
@@ -184,21 +187,21 @@ pub trait UsartOps<H, RX, TX> {
184187 /// was flushed yet.
185188 ///
186189 /// **Warning**: This is a low-level method and should not be called directly from user code.
187- fn raw_flush ( & mut self ) -> nb:: Result < ( ) , core :: convert :: Infallible > ;
190+ fn raw_flush ( & mut self ) -> nb:: Result < ( ) , Infallible > ;
188191 /// Write a byte to the TX buffer.
189192 ///
190193 /// This operation must be non-blocking and return [`nb::Error::WouldBlock`] until the byte is
191194 /// enqueued. The operation should not wait for the byte to have actually been sent.
192195 ///
193196 /// **Warning**: This is a low-level method and should not be called directly from user code.
194- fn raw_write ( & mut self , byte : u8 ) -> nb:: Result < ( ) , core :: convert :: Infallible > ;
197+ fn raw_write ( & mut self , byte : u8 ) -> nb:: Result < ( ) , Infallible > ;
195198 /// Read a byte from the RX buffer.
196199 ///
197200 /// This operation must be non-blocking and return [`nb::Error::WouldBlock`] if no incoming
198201 /// byte is available.
199202 ///
200203 /// **Warning**: This is a low-level method and should not be called directly from user code.
201- fn raw_read ( & mut self ) -> nb:: Result < u8 , core :: convert :: Infallible > ;
204+ fn raw_read ( & mut self ) -> nb:: Result < u8 , Infallible > ;
202205
203206 /// Enable/Disable a certain interrupt.
204207 ///
@@ -336,7 +339,7 @@ impl<H, USART: UsartOps<H, RX, TX>, RX, TX, CLOCK> Usart<H, USART, RX, TX, CLOCK
336339}
337340
338341impl < H , USART : UsartOps < H , RX , TX > , RX , TX , CLOCK > ufmt:: uWrite for Usart < H , USART , RX , TX , CLOCK > {
339- type Error = core :: convert :: Infallible ;
342+ type Error = Infallible ;
340343
341344 fn write_str ( & mut self , s : & str ) -> Result < ( ) , Self :: Error > {
342345 for b in s. as_bytes ( ) . iter ( ) {
@@ -349,7 +352,7 @@ impl<H, USART: UsartOps<H, RX, TX>, RX, TX, CLOCK> ufmt::uWrite for Usart<H, USA
349352impl < H , USART : UsartOps < H , RX , TX > , RX , TX , CLOCK > embedded_hal_v0:: serial:: Write < u8 >
350353 for Usart < H , USART , RX , TX , CLOCK >
351354{
352- type Error = core :: convert :: Infallible ;
355+ type Error = Infallible ;
353356
354357 fn write ( & mut self , byte : u8 ) -> nb:: Result < ( ) , Self :: Error > {
355358 self . p . raw_write ( byte)
@@ -360,16 +363,78 @@ impl<H, USART: UsartOps<H, RX, TX>, RX, TX, CLOCK> embedded_hal_v0::serial::Writ
360363 }
361364}
362365
366+ impl < H , USART : UsartOps < H , RX , TX > , RX , TX , CLOCK > ErrorType for Usart < H , USART , RX , TX , CLOCK > { type Error = Infallible ; }
367+
368+ impl < H , USART : UsartOps < H , RX , TX > , RX , TX , CLOCK > embedded_io:: Write for Usart < H , USART , RX , TX , CLOCK > {
369+ fn write ( & mut self , buf : & [ u8 ] ) -> Result < usize , Self :: Error > {
370+ if buf. is_empty ( ) {
371+ return Ok ( 0 ) ;
372+ }
373+ // block for first byte
374+ self . write_byte ( buf[ 0 ] ) ;
375+ let mut i = 1 ;
376+
377+ // write more bytes if it's possible
378+ for byte in buf[ 1 ..] . iter ( ) {
379+ match self . p . raw_write ( * byte) {
380+ Ok ( _) => {
381+ i += 1 ;
382+ }
383+ Err ( nb:: Error :: WouldBlock ) => {
384+ return Ok ( i) ;
385+ }
386+ Err ( _) => {
387+ unreachable ! ( ) ; // `raw_write` is `Infallible`
388+ }
389+ }
390+ }
391+ Ok ( i)
392+ }
393+
394+ fn flush ( & mut self ) -> Result < ( ) , Self :: Error > {
395+ self . p . raw_flush ( ) . unwrap ( ) ; // `raw_write` is `Infallible`
396+ Ok ( ( ) )
397+ }
398+ }
399+
363400impl < H , USART : UsartOps < H , RX , TX > , RX , TX , CLOCK > embedded_hal_v0:: serial:: Read < u8 >
364401 for Usart < H , USART , RX , TX , CLOCK >
365402{
366- type Error = core :: convert :: Infallible ;
403+ type Error = Infallible ;
367404
368405 fn read ( & mut self ) -> nb:: Result < u8 , Self :: Error > {
369406 self . p . raw_read ( )
370407 }
371408}
372409
410+ impl < H , USART : UsartOps < H , RX , TX > , RX , TX , CLOCK > embedded_io:: Read for Usart < H , USART , RX , TX , CLOCK > {
411+ fn read ( & mut self , buf : & mut [ u8 ] ) -> Result < usize , Self :: Error > {
412+ // block for first byte
413+ buf[ 0 ] = self . read_byte ( ) ;
414+ let mut i = 1 ;
415+
416+ // grab more bytes if available
417+ loop {
418+ match self . p . raw_read ( ) {
419+ Ok ( byte) => {
420+ buf[ i] = byte;
421+ i += 1 ;
422+
423+ if i == buf. len ( ) {
424+ return Ok ( i) ;
425+ }
426+ }
427+ Err ( nb:: Error :: WouldBlock ) => {
428+ return Ok ( i) ;
429+ }
430+ Err ( _) => {
431+ unreachable ! ( ) ; // `raw_read` is `Infallible`
432+ }
433+ }
434+ }
435+ }
436+ }
437+
373438/// Writer half of a [`Usart`] peripheral.
374439///
375440/// Created by calling [`Usart::split`]. Splitting a peripheral into reader and writer allows
@@ -413,6 +478,14 @@ impl<H, USART: UsartOps<H, RX, TX>, RX, TX, CLOCK> UsartWriter<H, USART, RX, TX,
413478 _h : marker:: PhantomData ,
414479 }
415480 }
481+
482+ /// Transmit a byte.
483+ ///
484+ /// This method will block until the byte has been enqueued for transmission but **not** until
485+ /// it was entirely sent.
486+ fn write_byte ( & mut self , byte : u8 ) {
487+ nb:: block!( self . p. raw_write( byte) ) . unwrap ( )
488+ }
416489}
417490
418491impl < H , USART : UsartOps < H , RX , TX > , RX , TX , CLOCK > UsartReader < H , USART , RX , TX , CLOCK > {
@@ -434,7 +507,7 @@ impl<H, USART: UsartOps<H, RX, TX>, RX, TX, CLOCK> UsartReader<H, USART, RX, TX,
434507impl < H , USART : UsartOps < H , RX , TX > , RX , TX , CLOCK > ufmt:: uWrite
435508 for UsartWriter < H , USART , RX , TX , CLOCK >
436509{
437- type Error = core :: convert :: Infallible ;
510+ type Error = Infallible ;
438511
439512 fn write_str ( & mut self , s : & str ) -> Result < ( ) , Self :: Error > {
440513 for b in s. as_bytes ( ) . iter ( ) {
@@ -447,7 +520,7 @@ impl<H, USART: UsartOps<H, RX, TX>, RX, TX, CLOCK> ufmt::uWrite
447520impl < H , USART : UsartOps < H , RX , TX > , RX , TX , CLOCK > embedded_hal_v0:: serial:: Write < u8 >
448521 for UsartWriter < H , USART , RX , TX , CLOCK >
449522{
450- type Error = core :: convert :: Infallible ;
523+ type Error = Infallible ;
451524
452525 fn write ( & mut self , byte : u8 ) -> nb:: Result < ( ) , Self :: Error > {
453526 self . p . raw_write ( byte)
@@ -458,16 +531,77 @@ impl<H, USART: UsartOps<H, RX, TX>, RX, TX, CLOCK> embedded_hal_v0::serial::Writ
458531 }
459532}
460533
534+ impl < H , USART : UsartOps < H , RX , TX > , RX , TX , CLOCK > ErrorType for UsartWriter < H , USART , RX , TX , CLOCK > { type Error = Infallible ; }
535+
536+ impl < H , USART : UsartOps < H , RX , TX > , RX , TX , CLOCK > embedded_io:: Write for UsartWriter < H , USART , RX , TX , CLOCK > {
537+ fn write ( & mut self , buf : & [ u8 ] ) -> Result < usize , Self :: Error > {
538+ if buf. is_empty ( ) {
539+ return Ok ( 0 ) ;
540+ }
541+ // block for first byte
542+ self . write_byte ( buf[ 0 ] ) ;
543+ let mut i = 1 ;
544+
545+ // write more bytes if it's possible
546+ for byte in buf[ 1 ..] . iter ( ) {
547+ match self . p . raw_write ( * byte) {
548+ Ok ( _) => {
549+ i += 1 ;
550+ }
551+ Err ( nb:: Error :: WouldBlock ) => {
552+ return Ok ( i) ;
553+ }
554+ Err ( _) => {
555+ unreachable ! ( ) ; // `raw_write` is `Infallible`
556+ }
557+ }
558+ }
559+ Ok ( i)
560+ }
561+
562+ fn flush ( & mut self ) -> Result < ( ) , Self :: Error > {
563+ self . p . raw_flush ( ) . unwrap ( ) ; // `raw_flush` is `Infallible`
564+ Ok ( ( ) )
565+ }
566+ }
567+
461568impl < H , USART : UsartOps < H , RX , TX > , RX , TX , CLOCK > embedded_hal_v0:: serial:: Read < u8 >
462569 for UsartReader < H , USART , RX , TX , CLOCK >
463570{
464- type Error = core :: convert :: Infallible ;
571+ type Error = Infallible ;
465572
466573 fn read ( & mut self ) -> nb:: Result < u8 , Self :: Error > {
467574 self . p . raw_read ( )
468575 }
469576}
470577
578+
579+ impl < H , USART : UsartOps < H , RX , TX > , RX , TX , CLOCK > ErrorType for UsartReader < H , USART , RX , TX , CLOCK > { type Error = Infallible ; }
580+
581+ impl < H , USART : UsartOps < H , RX , TX > , RX , TX , CLOCK > embedded_io:: Read for UsartReader < H , USART , RX , TX , CLOCK > {
582+ fn read ( & mut self , buf : & mut [ u8 ] ) -> Result < usize , Self :: Error > {
583+ let mut i = 0 ;
584+ loop {
585+ match self . p . raw_read ( ) {
586+ Ok ( byte) => {
587+ buf[ i] = byte;
588+ i += 1 ;
589+
590+ if i == buf. len ( ) {
591+ return Ok ( i) ;
592+ }
593+ }
594+ Err ( nb:: Error :: WouldBlock ) => {
595+ return Ok ( i) ;
596+ }
597+ Err ( _) => {
598+ unreachable ! ( ) ; // `raw_read` is `Infallible`
599+ }
600+ }
601+ }
602+ }
603+ }
604+
471605#[ macro_export]
472606macro_rules! impl_usart_traditional {
473607 (
0 commit comments