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,78 @@ 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 = Infallible ; }
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+ if buf. is_empty ( ) {
370+ return Ok ( 0 ) ;
371+ }
372+ // block for first byte
373+ self . write_byte ( buf[ 0 ] ) ;
374+ let mut i = 1 ;
375+
376+ // write more bytes if it's possible
377+ for byte in buf[ 1 ..] . iter ( ) {
378+ match self . p . raw_write ( * byte) {
379+ Ok ( _) => {
380+ i += 1 ;
381+ }
382+ Err ( nb:: Error :: WouldBlock ) => {
383+ return Ok ( i) ;
384+ }
385+ Err ( _) => {
386+ unreachable ! ( ) ; // `raw_write` is `Infallible`
387+ }
388+ }
389+ }
390+ Ok ( i)
391+ }
392+
393+ fn flush ( & mut self ) -> Result < ( ) , Self :: Error > {
394+ self . p . raw_flush ( ) . unwrap ( ) ; // `raw_write` is `Infallible`
395+ Ok ( ( ) )
396+ }
397+ }
398+
362399impl < H , USART : UsartOps < H , RX , TX > , RX , TX , CLOCK > hal:: serial:: Read < u8 >
363400 for Usart < H , USART , RX , TX , CLOCK >
364401{
365- type Error = core :: convert :: Infallible ;
402+ type Error = Infallible ;
366403
367404 fn read ( & mut self ) -> nb:: Result < u8 , Self :: Error > {
368405 self . p . raw_read ( )
369406 }
370407}
371408
409+ impl < H , USART : UsartOps < H , RX , TX > , RX , TX , CLOCK > embedded_io:: Read for Usart < H , USART , RX , TX , CLOCK > {
410+ fn read ( & mut self , buf : & mut [ u8 ] ) -> Result < usize , Self :: Error > {
411+ // block for first byte
412+ buf[ 0 ] = self . read_byte ( ) ;
413+ let mut i = 1 ;
414+
415+ // grab more bytes if available
416+ loop {
417+ match self . p . raw_read ( ) {
418+ Ok ( byte) => {
419+ buf[ i] = byte;
420+ i += 1 ;
421+
422+ if i == buf. len ( ) {
423+ return Ok ( i) ;
424+ }
425+ }
426+ Err ( nb:: Error :: WouldBlock ) => {
427+ return Ok ( i) ;
428+ }
429+ Err ( _) => {
430+ unreachable ! ( ) ; // `raw_read` is `Infallible`
431+ }
432+ }
433+ }
434+ }
435+ }
436+
372437/// Writer half of a [`Usart`] peripheral.
373438///
374439/// Created by calling [`Usart::split`]. Splitting a peripheral into reader and writer allows
@@ -412,6 +477,14 @@ impl<H, USART: UsartOps<H, RX, TX>, RX, TX, CLOCK> UsartWriter<H, USART, RX, TX,
412477 _h : marker:: PhantomData ,
413478 }
414479 }
480+
481+ /// Transmit a byte.
482+ ///
483+ /// This method will block until the byte has been enqueued for transmission but **not** until
484+ /// it was entirely sent.
485+ fn write_byte ( & mut self , byte : u8 ) {
486+ nb:: block!( self . p. raw_write( byte) ) . unwrap ( )
487+ }
415488}
416489
417490impl < H , USART : UsartOps < H , RX , TX > , RX , TX , CLOCK > UsartReader < H , USART , RX , TX , CLOCK > {
@@ -433,7 +506,7 @@ impl<H, USART: UsartOps<H, RX, TX>, RX, TX, CLOCK> UsartReader<H, USART, RX, TX,
433506impl < H , USART : UsartOps < H , RX , TX > , RX , TX , CLOCK > ufmt:: uWrite
434507 for UsartWriter < H , USART , RX , TX , CLOCK >
435508{
436- type Error = core :: convert :: Infallible ;
509+ type Error = Infallible ;
437510
438511 fn write_str ( & mut self , s : & str ) -> Result < ( ) , Self :: Error > {
439512 for b in s. as_bytes ( ) . iter ( ) {
@@ -446,7 +519,7 @@ impl<H, USART: UsartOps<H, RX, TX>, RX, TX, CLOCK> ufmt::uWrite
446519impl < H , USART : UsartOps < H , RX , TX > , RX , TX , CLOCK > hal:: serial:: Write < u8 >
447520 for UsartWriter < H , USART , RX , TX , CLOCK >
448521{
449- type Error = core :: convert :: Infallible ;
522+ type Error = Infallible ;
450523
451524 fn write ( & mut self , byte : u8 ) -> nb:: Result < ( ) , Self :: Error > {
452525 self . p . raw_write ( byte)
@@ -457,16 +530,77 @@ impl<H, USART: UsartOps<H, RX, TX>, RX, TX, CLOCK> hal::serial::Write<u8>
457530 }
458531}
459532
533+ impl < H , USART : UsartOps < H , RX , TX > , RX , TX , CLOCK > ErrorType for UsartWriter < H , USART , RX , TX , CLOCK > { type Error = Infallible ; }
534+
535+ impl < H , USART : UsartOps < H , RX , TX > , RX , TX , CLOCK > embedded_io:: Write for UsartWriter < H , USART , RX , TX , CLOCK > {
536+ fn write ( & mut self , buf : & [ u8 ] ) -> Result < usize , Self :: Error > {
537+ if buf. is_empty ( ) {
538+ return Ok ( 0 ) ;
539+ }
540+ // block for first byte
541+ self . write_byte ( buf[ 0 ] ) ;
542+ let mut i = 1 ;
543+
544+ // write more bytes if it's possible
545+ for byte in buf[ 1 ..] . iter ( ) {
546+ match self . p . raw_write ( * byte) {
547+ Ok ( _) => {
548+ i += 1 ;
549+ }
550+ Err ( nb:: Error :: WouldBlock ) => {
551+ return Ok ( i) ;
552+ }
553+ Err ( _) => {
554+ unreachable ! ( ) ; // `raw_write` is `Infallible`
555+ }
556+ }
557+ }
558+ Ok ( i)
559+ }
560+
561+ fn flush ( & mut self ) -> Result < ( ) , Self :: Error > {
562+ self . p . raw_flush ( ) . unwrap ( ) ; // `raw_flush` is `Infallible`
563+ Ok ( ( ) )
564+ }
565+ }
566+
460567impl < H , USART : UsartOps < H , RX , TX > , RX , TX , CLOCK > hal:: serial:: Read < u8 >
461568 for UsartReader < H , USART , RX , TX , CLOCK >
462569{
463- type Error = core :: convert :: Infallible ;
570+ type Error = Infallible ;
464571
465572 fn read ( & mut self ) -> nb:: Result < u8 , Self :: Error > {
466573 self . p . raw_read ( )
467574 }
468575}
469576
577+
578+ impl < H , USART : UsartOps < H , RX , TX > , RX , TX , CLOCK > ErrorType for UsartReader < H , USART , RX , TX , CLOCK > { type Error = Infallible ; }
579+
580+ impl < H , USART : UsartOps < H , RX , TX > , RX , TX , CLOCK > embedded_io:: Read for UsartReader < H , USART , RX , TX , CLOCK > {
581+ fn read ( & mut self , buf : & mut [ u8 ] ) -> Result < usize , Self :: Error > {
582+ let mut i = 0 ;
583+ loop {
584+ match self . p . raw_read ( ) {
585+ Ok ( byte) => {
586+ buf[ i] = byte;
587+ i += 1 ;
588+
589+ if i == buf. len ( ) {
590+ return Ok ( i) ;
591+ }
592+ }
593+ Err ( nb:: Error :: WouldBlock ) => {
594+ return Ok ( i) ;
595+ }
596+ Err ( _) => {
597+ unreachable ! ( ) ; // `raw_read` is `Infallible`
598+ }
599+ }
600+ }
601+ }
602+ }
603+
470604#[ macro_export]
471605macro_rules! impl_usart_traditional {
472606 (
0 commit comments