@@ -373,11 +373,16 @@ where
373
373
)
374
374
}
375
375
376
- // Split into implementations of embedded_hal::serial traits
377
- pub fn split ( self ) -> ( UarteTx < T > , UarteRx < T > ) {
378
- let tx = UarteTx :: new ( ) ;
379
- let rx = UarteRx :: new ( ) ;
380
- ( tx, rx)
376
+ // Split into implementations of embedded_hal::serial traits. The buffers passed here must outlive any DMA transfers
377
+ // that are initiated by the UartTx and UartRx.
378
+ pub fn split < ' a > (
379
+ self ,
380
+ tx_buf : & ' a mut [ u8 ] ,
381
+ rx_buf : & ' a mut [ u8 ] ,
382
+ ) -> Result < ( UarteTx < ' a , T > , UarteRx < ' a , T > ) , Error > {
383
+ let tx = UarteTx :: new ( tx_buf) ?;
384
+ let rx = UarteRx :: new ( rx_buf) ?;
385
+ Ok ( ( tx, rx) )
381
386
}
382
387
}
383
388
@@ -407,6 +412,8 @@ pub struct Pins {
407
412
408
413
#[ derive( Debug ) ]
409
414
pub enum Error {
415
+ TxBufferTooSmall ,
416
+ RxBufferTooSmall ,
410
417
TxBufferTooLong ,
411
418
RxBufferTooLong ,
412
419
Transmit ,
@@ -442,40 +449,46 @@ mod _uarte1 {
442
449
}
443
450
444
451
/// Interface for the TX part of a UART instance that can be used independently of the RX part.
445
- pub struct UarteTx < T > {
452
+ pub struct UarteTx < ' a , T > {
446
453
_marker : core:: marker:: PhantomData < T > ,
447
- tx_buf : [ u8 ; 1 ] ,
454
+ tx_buf : & ' a mut [ u8 ] ,
448
455
}
449
456
450
457
/// Interface for the RX part of a UART instance that can be used independently of the TX part.
451
- pub struct UarteRx < T > {
458
+ pub struct UarteRx < ' a , T > {
452
459
_marker : core:: marker:: PhantomData < T > ,
453
- rx_buf : [ u8 ; 1 ] ,
460
+ rx_buf : & ' a mut [ u8 ] ,
454
461
}
455
462
456
- impl < T > UarteTx < T >
463
+ impl < ' a , T > UarteTx < ' a , T >
457
464
where
458
465
T : Instance ,
459
466
{
460
- fn new ( ) -> UarteTx < T > {
461
- let tx = UarteTx {
462
- _marker : core:: marker:: PhantomData ,
463
- tx_buf : [ 0 ; 1 ] ,
464
- } ;
465
- tx
467
+ fn new ( tx_buf : & ' a mut [ u8 ] ) -> Result < UarteTx < ' a , T > , Error > {
468
+ if tx_buf. len ( ) > 0 {
469
+ Ok ( UarteTx {
470
+ _marker : core:: marker:: PhantomData ,
471
+ tx_buf,
472
+ } )
473
+ } else {
474
+ Err ( Error :: TxBufferTooSmall )
475
+ }
466
476
}
467
477
}
468
478
469
- impl < T > UarteRx < T >
479
+ impl < ' a , T > UarteRx < ' a , T >
470
480
where
471
481
T : Instance ,
472
482
{
473
- fn new ( ) -> UarteRx < T > {
474
- let rx = UarteRx {
475
- _marker : core:: marker:: PhantomData ,
476
- rx_buf : [ 0 ; 1 ] ,
477
- } ;
478
- rx
483
+ fn new ( rx_buf : & ' a mut [ u8 ] ) -> Result < UarteRx < ' a , T > , Error > {
484
+ if rx_buf. len ( ) > 0 {
485
+ Ok ( UarteRx {
486
+ _marker : core:: marker:: PhantomData ,
487
+ rx_buf,
488
+ } )
489
+ } else {
490
+ Err ( Error :: RxBufferTooSmall )
491
+ }
479
492
}
480
493
}
481
494
@@ -486,7 +499,7 @@ pub mod serial {
486
499
use embedded_hal:: serial;
487
500
use nb;
488
501
489
- impl < T > serial:: Write < u8 > for UarteTx < T >
502
+ impl < ' a , T > serial:: Write < u8 > for UarteTx < ' a , T >
490
503
where
491
504
T : Instance ,
492
505
{
@@ -504,8 +517,7 @@ pub mod serial {
504
517
} else {
505
518
// Start a new transmission, copy value into transmit buffer.
506
519
507
- let tx_buffer = & mut self . tx_buf ;
508
- tx_buffer[ 0 ] = b;
520
+ self . tx_buf [ 0 ] = b;
509
521
510
522
// Conservative compiler fence to prevent optimizations that do not
511
523
// take in to account actions by DMA. The fence has been placed here,
@@ -524,18 +536,13 @@ pub mod serial {
524
536
uarte
525
537
. txd
526
538
. ptr
527
- . write ( |w| unsafe { w. ptr ( ) . bits ( tx_buffer . as_ptr ( ) as u32 ) } ) ;
539
+ . write ( |w| unsafe { w. ptr ( ) . bits ( self . tx_buf . as_ptr ( ) as u32 ) } ) ;
528
540
529
- // We're giving it the length of the buffer, so no danger of
530
- // accessing invalid memory. We have verified that the length of the
531
- // buffer fits in an `u8`, so the cast to `u8` is also fine.
541
+ // We're giving it a length of 1 to transmit 1 byte at a time.
532
542
//
533
543
// The MAXCNT field is 8 bits wide and accepts the full range of
534
544
// values.
535
- uarte
536
- . txd
537
- . maxcnt
538
- . write ( |w| unsafe { w. maxcnt ( ) . bits ( tx_buffer. len ( ) as _ ) } ) ;
545
+ uarte. txd . maxcnt . write ( |w| unsafe { w. maxcnt ( ) . bits ( 1 ) } ) ;
539
546
540
547
// Start UARTE Transmit transaction.
541
548
// `1` is a valid value to write to task registers.
@@ -579,7 +586,7 @@ pub mod serial {
579
586
}
580
587
}
581
588
582
- impl < T > core:: fmt:: Write for UarteTx < T >
589
+ impl < ' a , T > core:: fmt:: Write for UarteTx < ' a , T >
583
590
where
584
591
T : Instance ,
585
592
{
@@ -591,7 +598,7 @@ pub mod serial {
591
598
}
592
599
}
593
600
594
- impl < T > serial:: Read < u8 > for UarteRx < T >
601
+ impl < ' a , T > serial:: Read < u8 > for UarteRx < ' a , T >
595
602
where
596
603
T : Instance ,
597
604
{
@@ -617,26 +624,20 @@ pub mod serial {
617
624
}
618
625
Ok ( b)
619
626
} else {
620
- let rx_buf = & mut self . rx_buf ;
621
-
622
627
// We're giving the register a pointer to the rx buffer.
623
628
//
624
629
// The PTR field is a full 32 bits wide and accepts the full range
625
630
// of values.
626
631
uarte
627
632
. rxd
628
633
. ptr
629
- . write ( |w| unsafe { w. ptr ( ) . bits ( rx_buf. as_ptr ( ) as u32 ) } ) ;
634
+ . write ( |w| unsafe { w. ptr ( ) . bits ( self . rx_buf . as_ptr ( ) as u32 ) } ) ;
630
635
631
- // We're giving it the length of the buffer, so no danger of
632
- // accessing invalid memory.
636
+ // We're giving it a length of 1 to read only 1 byte.
633
637
//
634
638
// The MAXCNT field is at least 8 bits wide and accepts the full
635
639
// range of values.
636
- uarte
637
- . rxd
638
- . maxcnt
639
- . write ( |w| unsafe { w. maxcnt ( ) . bits ( rx_buf. len ( ) as _ ) } ) ;
640
+ uarte. rxd . maxcnt . write ( |w| unsafe { w. maxcnt ( ) . bits ( 1 ) } ) ;
640
641
641
642
// Start UARTE Receive transaction.
642
643
// `1` is a valid value to write to task registers.
0 commit comments