@@ -373,12 +373,12 @@ where
373
373
)
374
374
}
375
375
376
- // Split into implementations of embedded_hal::serial traits. The buffers passed here must outlive any DMA transfers
376
+ // Split into implementations of embedded_hal::serial traits. The size of the slices passed to this method will determine the size of the DMA transfers performed.
377
377
// that are initiated by the UartTx and UartRx.
378
378
pub fn split < ' a > (
379
379
self ,
380
- tx_buf : & ' a mut [ u8 ] ,
381
- rx_buf : & ' a mut [ u8 ] ,
380
+ tx_buf : & ' static mut [ u8 ] ,
381
+ rx_buf : & ' static mut [ u8 ] ,
382
382
) -> Result < ( UarteTx < ' a , T > , UarteRx < ' a , T > ) , Error > {
383
383
let tx = UarteTx :: new ( tx_buf) ?;
384
384
let rx = UarteRx :: new ( rx_buf) ?;
@@ -455,6 +455,7 @@ where
455
455
{
456
456
_marker : core:: marker:: PhantomData < T > ,
457
457
tx_buf : & ' a mut [ u8 ] ,
458
+ written : u16 ,
458
459
}
459
460
460
461
/// Interface for the RX part of a UART instance that can be used independently of the TX part.
@@ -472,14 +473,19 @@ where
472
473
{
473
474
fn new ( tx_buf : & ' a mut [ u8 ] ) -> Result < UarteTx < ' a , T > , Error > {
474
475
slice_in_ram_or ( tx_buf, Error :: BufferNotInRAM ) ?;
475
- if tx_buf. len ( ) > 0 {
476
- Ok ( UarteTx {
477
- _marker : core:: marker:: PhantomData ,
478
- tx_buf,
479
- } )
480
- } else {
481
- Err ( Error :: TxBufferTooSmall )
476
+ if tx_buf. len ( ) == 0 {
477
+ return Err ( Error :: TxBufferTooSmall ) ;
482
478
}
479
+
480
+ if tx_buf. len ( ) > EASY_DMA_SIZE {
481
+ return Err ( Error :: TxBufferTooLong ) ;
482
+ }
483
+
484
+ Ok ( UarteTx {
485
+ _marker : core:: marker:: PhantomData ,
486
+ tx_buf,
487
+ written : 0 ,
488
+ } )
483
489
}
484
490
}
485
491
@@ -489,14 +495,18 @@ where
489
495
{
490
496
fn new ( rx_buf : & ' a mut [ u8 ] ) -> Result < UarteRx < ' a , T > , Error > {
491
497
slice_in_ram_or ( rx_buf, Error :: BufferNotInRAM ) ?;
492
- if rx_buf. len ( ) > 0 {
493
- Ok ( UarteRx {
494
- _marker : core:: marker:: PhantomData ,
495
- rx_buf,
496
- } )
497
- } else {
498
- Err ( Error :: RxBufferTooSmall )
498
+ if rx_buf. len ( ) == 0 {
499
+ return Err ( Error :: RxBufferTooSmall ) ;
500
+ }
501
+
502
+ if rx_buf. len ( ) > EASY_DMA_SIZE {
503
+ return Err ( Error :: RxBufferTooLong ) ;
499
504
}
505
+
506
+ Ok ( UarteRx {
507
+ _marker : core:: marker:: PhantomData ,
508
+ rx_buf,
509
+ } )
500
510
}
501
511
}
502
512
@@ -559,8 +569,9 @@ where
559
569
560
570
pub mod serial {
561
571
562
- ///! Implementation of the embedded_hal::serial::* traits for UartTx and UartRx.
572
+ ///! Implementation of the embedded_hal::serial::* and embedded_hal::blocking::serial::* traits for UartTx and UartRx.
563
573
use super :: * ;
574
+ use embedded_hal:: blocking:: serial as bserial;
564
575
use embedded_hal:: serial;
565
576
use nb;
566
577
@@ -570,48 +581,21 @@ pub mod serial {
570
581
{
571
582
type Error = Error ;
572
583
573
- /// Write a single byte non-blocking . Returns nb::Error::WouldBlock if not yet done .
584
+ /// Write a single byte to the internal buffer . Returns nb::Error::WouldBlock if buffer is full .
574
585
fn write ( & mut self , b : u8 ) -> nb:: Result < ( ) , Self :: Error > {
575
586
let uarte = unsafe { & * T :: ptr ( ) } ;
576
587
577
- // If txstarted is set, we are in the process of transmitting.
578
- let in_progress = uarte. events_txstarted . read ( ) . bits ( ) == 1 ;
588
+ // Prevent writing to buffer while DMA transfer is in progress.
589
+ if uarte. events_txstarted . read ( ) . bits ( ) == 1 {
590
+ return Err ( nb:: Error :: WouldBlock ) ;
591
+ }
579
592
580
- if in_progress {
581
- self . flush ( )
593
+ let written = self . written as usize ;
594
+ if written < self . tx_buf . len ( ) {
595
+ self . tx_buf [ written] = b;
596
+ self . written += 1 ;
597
+ Ok ( ( ) )
582
598
} else {
583
- // Start a new transmission, copy value into transmit buffer.
584
-
585
- self . tx_buf [ 0 ] = b;
586
-
587
- // Conservative compiler fence to prevent optimizations that do not
588
- // take in to account actions by DMA. The fence has been placed here,
589
- // before any DMA action has started.
590
- compiler_fence ( SeqCst ) ;
591
-
592
- // Reset the events.
593
- uarte. events_endtx . reset ( ) ;
594
- uarte. events_txstopped . reset ( ) ;
595
-
596
- // Set up the DMA write.
597
- // We're giving the register a pointer to the tx buffer.
598
- //
599
- // The PTR field is a full 32 bits wide and accepts the full range
600
- // of values.
601
- uarte
602
- . txd
603
- . ptr
604
- . write ( |w| unsafe { w. ptr ( ) . bits ( self . tx_buf . as_ptr ( ) as u32 ) } ) ;
605
-
606
- // We're giving it a length of 1 to transmit 1 byte at a time.
607
- //
608
- // The MAXCNT field is 8 bits wide and accepts the full range of
609
- // values.
610
- uarte. txd . maxcnt . write ( |w| unsafe { w. maxcnt ( ) . bits ( 1 ) } ) ;
611
-
612
- // Start UARTE Transmit transaction.
613
- // `1` is a valid value to write to task registers.
614
- uarte. tasks_starttx . write ( |w| unsafe { w. bits ( 1 ) } ) ;
615
599
Err ( nb:: Error :: WouldBlock )
616
600
}
617
601
}
@@ -620,10 +604,12 @@ pub mod serial {
620
604
fn flush ( & mut self ) -> nb:: Result < ( ) , Self :: Error > {
621
605
let uarte = unsafe { & * T :: ptr ( ) } ;
622
606
607
+ // If txstarted is set, we are in the process of transmitting.
623
608
let in_progress = uarte. events_txstarted . read ( ) . bits ( ) == 1 ;
624
- let endtx = uarte. events_endtx . read ( ) . bits ( ) != 0 ;
625
- let txstopped = uarte. events_txstopped . read ( ) . bits ( ) != 0 ;
609
+
626
610
if in_progress {
611
+ let endtx = uarte. events_endtx . read ( ) . bits ( ) != 0 ;
612
+ let txstopped = uarte. events_txstopped . read ( ) . bits ( ) != 0 ;
627
613
if endtx || txstopped {
628
614
// We are done, cleanup the state.
629
615
uarte. events_txstarted . reset ( ) ;
@@ -646,11 +632,45 @@ pub mod serial {
646
632
Err ( nb:: Error :: WouldBlock )
647
633
}
648
634
} else {
649
- Ok ( ( ) )
635
+ // Conservative compiler fence to prevent optimizations that do not
636
+ // take in to account actions by DMA. The fence has been placed here,
637
+ // before any DMA action has started.
638
+ compiler_fence ( SeqCst ) ;
639
+
640
+ // Reset the events.
641
+ uarte. events_endtx . reset ( ) ;
642
+ uarte. events_txstopped . reset ( ) ;
643
+
644
+ // Set up the DMA write.
645
+ // We're giving the register a pointer to the tx buffer.
646
+ //
647
+ // The PTR field is a full 32 bits wide and accepts the full range
648
+ // of values.
649
+ uarte
650
+ . txd
651
+ . ptr
652
+ . write ( |w| unsafe { w. ptr ( ) . bits ( self . tx_buf . as_ptr ( ) as u32 ) } ) ;
653
+
654
+ // We're giving it a length of the number of bytes written to the buffer.
655
+ //
656
+ // The MAXCNT field is 8 bits wide and accepts the full range of
657
+ // values.
658
+ uarte
659
+ . txd
660
+ . maxcnt
661
+ . write ( |w| unsafe { w. maxcnt ( ) . bits ( self . written ) } ) ;
662
+
663
+ // Start UARTE Transmit transaction.
664
+ // `1` is a valid value to write to task registers.
665
+ uarte. tasks_starttx . write ( |w| unsafe { w. bits ( 1 ) } ) ;
666
+ Err ( nb:: Error :: WouldBlock )
650
667
}
651
668
}
652
669
}
653
670
671
+ // Auto-implement the blocking variant
672
+ impl < ' a , T > bserial:: write:: Default < u8 > for UarteTx < ' a , T > where T : Instance { }
673
+
654
674
impl < ' a , T > core:: fmt:: Write for UarteTx < ' a , T >
655
675
where
656
676
T : Instance ,
0 commit comments