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