@@ -477,12 +477,21 @@ static void serial_enable_pins(serial_t *obj, uint8_t enable)
477
477
{
478
478
if (enable ) {
479
479
/* Configure GPIO pins*/
480
- pin_mode (obj -> serial .rx_pin , Input );
481
- /* 0x10 sets DOUT. Prevents false start. */
482
- pin_mode (obj -> serial .tx_pin , PushPull | 0x10 );
480
+ if (obj -> serial .rx_pin != NC ) {
481
+ pin_mode (obj -> serial .rx_pin , Input );
482
+ }
483
+ /* Set DOUT first to prevent glitches */
484
+ if (obj -> serial .tx_pin != NC ) {
485
+ GPIO_PinOutSet ((GPIO_Port_TypeDef )(obj -> serial .tx_pin >> 4 & 0xF ), obj -> serial .tx_pin & 0xF );
486
+ pin_mode (obj -> serial .tx_pin , PushPull );
487
+ }
483
488
} else {
484
- pin_mode (obj -> serial .rx_pin , Disabled );
485
- pin_mode (obj -> serial .tx_pin , Disabled );
489
+ if (obj -> serial .rx_pin != NC ) {
490
+ pin_mode (obj -> serial .rx_pin , Disabled );
491
+ }
492
+ if (obj -> serial .tx_pin != NC ) {
493
+ pin_mode (obj -> serial .tx_pin , Disabled );
494
+ }
486
495
}
487
496
}
488
497
@@ -513,7 +522,7 @@ void serial_init(serial_t *obj, PinName tx, PinName rx)
513
522
CMU_ClockEnable (serial_get_clock (obj ), true);
514
523
515
524
/* Limitations of board controller: CDC port only supports 115kbaud */
516
- if ((tx == STDIO_UART_TX ) && (rx == STDIO_UART_RX )
525
+ if ((( tx == STDIO_UART_TX ) || (rx == STDIO_UART_RX ) )
517
526
&& (obj -> serial .periph .uart == (USART_TypeDef * )STDIO_UART )
518
527
) {
519
528
baudrate = 115200 ;
@@ -528,21 +537,53 @@ void serial_init(serial_t *obj, PinName tx, PinName rx)
528
537
/* Enable pins for UART at correct location */
529
538
if (LEUART_REF_VALID (obj -> serial .periph .leuart )) {
530
539
#ifdef _LEUART_ROUTE_LOCATION_SHIFT
531
- obj -> serial .periph .leuart -> ROUTE = LEUART_ROUTE_RXPEN | LEUART_ROUTE_TXPEN | (obj -> serial .location << _LEUART_ROUTE_LOCATION_SHIFT );
540
+ obj -> serial .periph .leuart -> ROUTE = (obj -> serial .location << _LEUART_ROUTE_LOCATION_SHIFT );
541
+ if (tx != (uint32_t )NC ) {
542
+ obj -> serial .periph .leuart -> ROUTE |= LEUART_ROUTE_TXPEN ;
543
+ }
544
+ if (rx != (uint32_t )NC ) {
545
+ obj -> serial .periph .leuart -> ROUTE |= LEUART_ROUTE_RXPEN ;
546
+ }
532
547
#else
533
- obj -> serial .periph .leuart -> ROUTELOC0 = (obj -> serial .location_tx << _LEUART_ROUTELOC0_TXLOC_SHIFT ) |
534
- (obj -> serial .location_rx << _LEUART_ROUTELOC0_RXLOC_SHIFT );
535
- obj -> serial .periph .leuart -> ROUTEPEN = LEUART_ROUTEPEN_RXPEN | LEUART_ROUTEPEN_TXPEN ;
548
+ if (obj -> serial .location_tx != NC ) {
549
+ obj -> serial .periph .leuart -> ROUTELOC0 = (obj -> serial .periph .leuart -> ROUTELOC0 & (~_LEUART_ROUTELOC0_TXLOC_MASK )) | (obj -> serial .location_tx << _LEUART_ROUTELOC0_TXLOC_SHIFT );
550
+ obj -> serial .periph .leuart -> ROUTEPEN = (obj -> serial .periph .leuart -> ROUTEPEN & (~_LEUART_ROUTEPEN_TXPEN_MASK )) | LEUART_ROUTEPEN_TXPEN ;
551
+ } else {
552
+ obj -> serial .periph .leuart -> ROUTEPEN = (obj -> serial .periph .leuart -> ROUTEPEN & (~_LEUART_ROUTEPEN_TXPEN_MASK ));
553
+ }
554
+ if (obj -> serial .location_rx != NC ) {
555
+ obj -> serial .periph .leuart -> ROUTELOC0 = (obj -> serial .periph .leuart -> ROUTELOC0 & (~_LEUART_ROUTELOC0_RXLOC_MASK )) | (obj -> serial .location_rx << _LEUART_ROUTELOC0_RXLOC_SHIFT );
556
+ obj -> serial .periph .leuart -> ROUTEPEN = (obj -> serial .periph .leuart -> ROUTEPEN & (~_LEUART_ROUTEPEN_RXPEN_MASK )) | LEUART_ROUTEPEN_RXPEN ;
557
+ } else {
558
+ obj -> serial .periph .leuart -> CMD = LEUART_CMD_RXBLOCKEN ;
559
+ obj -> serial .periph .leuart -> ROUTEPEN = (obj -> serial .periph .leuart -> ROUTEPEN & (~_LEUART_ROUTEPEN_RXPEN_MASK ));
560
+ }
536
561
#endif
537
562
obj -> serial .periph .leuart -> IFC = LEUART_IFC_TXC ;
538
563
obj -> serial .periph .leuart -> CTRL |= LEUART_CTRL_RXDMAWU | LEUART_CTRL_TXDMAWU ;
539
564
} else {
540
565
#ifdef _USART_ROUTE_LOCATION_SHIFT
541
- obj -> serial .periph .uart -> ROUTE = USART_ROUTE_RXPEN | USART_ROUTE_TXPEN | (obj -> serial .location << _USART_ROUTE_LOCATION_SHIFT );
566
+ obj -> serial .periph .uart -> ROUTE = (obj -> serial .location << _USART_ROUTE_LOCATION_SHIFT );
567
+ if (tx != (uint32_t )NC ) {
568
+ obj -> serial .periph .uart -> ROUTE |= USART_ROUTE_TXPEN ;
569
+ }
570
+ if (rx != (uint32_t )NC ) {
571
+ obj -> serial .periph .uart -> ROUTE |= USART_ROUTE_RXPEN ;
572
+ }
542
573
#else
543
- obj -> serial .periph .uart -> ROUTELOC0 = (obj -> serial .location_tx << _USART_ROUTELOC0_TXLOC_SHIFT ) |
544
- (obj -> serial .location_rx << _USART_ROUTELOC0_RXLOC_SHIFT );
545
- obj -> serial .periph .uart -> ROUTEPEN = USART_ROUTEPEN_RXPEN | USART_ROUTEPEN_TXPEN ;
574
+ if (obj -> serial .location_tx != NC ) {
575
+ obj -> serial .periph .uart -> ROUTELOC0 = (obj -> serial .periph .uart -> ROUTELOC0 & (~_USART_ROUTELOC0_TXLOC_MASK )) | (obj -> serial .location_tx << _USART_ROUTELOC0_TXLOC_SHIFT );
576
+ obj -> serial .periph .uart -> ROUTEPEN = (obj -> serial .periph .uart -> ROUTEPEN & (~_USART_ROUTEPEN_TXPEN_MASK )) | USART_ROUTEPEN_TXPEN ;
577
+ } else {
578
+ obj -> serial .periph .uart -> ROUTEPEN = (obj -> serial .periph .uart -> ROUTEPEN & (~_USART_ROUTEPEN_TXPEN_MASK ));
579
+ }
580
+ if (obj -> serial .location_rx != NC ) {
581
+ obj -> serial .periph .uart -> ROUTELOC0 = (obj -> serial .periph .uart -> ROUTELOC0 & (~_USART_ROUTELOC0_RXLOC_MASK )) | (obj -> serial .location_rx << _USART_ROUTELOC0_RXLOC_SHIFT );
582
+ obj -> serial .periph .uart -> ROUTEPEN = (obj -> serial .periph .uart -> ROUTEPEN & (~_USART_ROUTEPEN_RXPEN_MASK )) | USART_ROUTEPEN_RXPEN ;
583
+ } else {
584
+ obj -> serial .periph .uart -> CMD = USART_CMD_RXBLOCKEN ;
585
+ obj -> serial .periph .uart -> ROUTEPEN = (obj -> serial .periph .uart -> ROUTEPEN & (~_USART_ROUTEPEN_RXPEN_MASK ));
586
+ }
546
587
#endif
547
588
obj -> serial .periph .uart -> IFC = USART_IFC_TXC ;
548
589
}
@@ -571,6 +612,7 @@ void serial_free(serial_t *obj)
571
612
} else {
572
613
USART_Enable (obj -> serial .periph .uart , usartDisable );
573
614
}
615
+ serial_enable_pins (obj , false);
574
616
}
575
617
576
618
static void serial_enable (serial_t * obj , uint8_t enable )
@@ -599,7 +641,7 @@ void serial_baud(serial_t *obj, int baudrate)
599
641
if (LEUART_REF_VALID (obj -> serial .periph .leuart )) {
600
642
serial_leuart_baud (obj , baudrate );
601
643
} else {
602
- USART_BaudrateAsyncSet (obj -> serial .periph .uart , 0 , (uint32_t )baudrate , usartOVS16 );
644
+ USART_BaudrateAsyncSet (obj -> serial .periph .uart , REFERENCE_FREQUENCY , (uint32_t )baudrate , usartOVS16 );
603
645
}
604
646
}
605
647
@@ -720,11 +762,26 @@ void serial_format(serial_t *obj, int data_bits, SerialParity parity, int stop_b
720
762
721
763
/* Re-enable pins for UART at correct location */
722
764
#ifdef _LEUART_ROUTE_LOCATION_SHIFT
723
- obj -> serial .periph .leuart -> ROUTE = LEUART_ROUTE_RXPEN | LEUART_ROUTE_TXPEN | (obj -> serial .location << _LEUART_ROUTE_LOCATION_SHIFT );
765
+ obj -> serial .periph .leuart -> ROUTE = (obj -> serial .location << _LEUART_ROUTE_LOCATION_SHIFT );
766
+ if (obj -> serial .tx_pin != (uint32_t )NC ) {
767
+ obj -> serial .periph .leuart -> ROUTE |= LEUART_ROUTE_TXPEN ;
768
+ }
769
+ if (obj -> serial .rx_pin != (uint32_t )NC ) {
770
+ obj -> serial .periph .leuart -> ROUTE |= LEUART_ROUTE_RXPEN ;
771
+ }
724
772
#else
725
- obj -> serial .periph .leuart -> ROUTELOC0 = (obj -> serial .location_tx << _LEUART_ROUTELOC0_TXLOC_SHIFT ) |
726
- (obj -> serial .location_rx << _LEUART_ROUTELOC0_RXLOC_SHIFT );
727
- obj -> serial .periph .leuart -> ROUTEPEN = LEUART_ROUTEPEN_RXPEN | LEUART_ROUTEPEN_TXPEN ;
773
+ if (obj -> serial .location_tx != NC ) {
774
+ obj -> serial .periph .leuart -> ROUTELOC0 = (obj -> serial .periph .leuart -> ROUTELOC0 & (~_LEUART_ROUTELOC0_TXLOC_MASK )) | (obj -> serial .location_tx << _LEUART_ROUTELOC0_TXLOC_SHIFT );
775
+ obj -> serial .periph .leuart -> ROUTEPEN = (obj -> serial .periph .leuart -> ROUTEPEN & (~_LEUART_ROUTEPEN_TXPEN_MASK )) | LEUART_ROUTEPEN_TXPEN ;
776
+ } else {
777
+ obj -> serial .periph .leuart -> ROUTEPEN = (obj -> serial .periph .leuart -> ROUTEPEN & (~_LEUART_ROUTEPEN_TXPEN_MASK ));
778
+ }
779
+ if (obj -> serial .location_rx != NC ) {
780
+ obj -> serial .periph .leuart -> ROUTELOC0 = (obj -> serial .periph .leuart -> ROUTELOC0 & (~_LEUART_ROUTELOC0_RXLOC_MASK )) | (obj -> serial .location_rx << _LEUART_ROUTELOC0_RXLOC_SHIFT );
781
+ obj -> serial .periph .leuart -> ROUTEPEN = (obj -> serial .periph .leuart -> ROUTEPEN & (~_LEUART_ROUTEPEN_RXPEN_MASK )) | LEUART_ROUTEPEN_RXPEN ;
782
+ } else {
783
+ obj -> serial .periph .leuart -> ROUTEPEN = (obj -> serial .periph .leuart -> ROUTEPEN & (~_LEUART_ROUTEPEN_RXPEN_MASK ));
784
+ }
728
785
#endif
729
786
730
787
/* Re-enable interrupts */
@@ -771,11 +828,26 @@ void serial_format(serial_t *obj, int data_bits, SerialParity parity, int stop_b
771
828
772
829
/* Re-enable pins for UART at correct location */
773
830
#ifdef _USART_ROUTE_LOCATION_SHIFT
774
- obj -> serial .periph .uart -> ROUTE = USART_ROUTE_RXPEN | USART_ROUTE_TXPEN | (obj -> serial .location << _USART_ROUTE_LOCATION_SHIFT );
831
+ obj -> serial .periph .uart -> ROUTE = (obj -> serial .location << _USART_ROUTE_LOCATION_SHIFT );
832
+ if (obj -> serial .tx_pin != (uint32_t )NC ) {
833
+ obj -> serial .periph .uart -> ROUTE |= USART_ROUTE_TXPEN ;
834
+ }
835
+ if (obj -> serial .rx_pin != (uint32_t )NC ) {
836
+ obj -> serial .periph .uart -> ROUTE |= USART_ROUTE_RXPEN ;
837
+ }
775
838
#else
776
- obj -> serial .periph .uart -> ROUTELOC0 = (obj -> serial .location_tx << _USART_ROUTELOC0_TXLOC_SHIFT ) |
777
- (obj -> serial .location_rx << _USART_ROUTELOC0_RXLOC_SHIFT );
778
- obj -> serial .periph .uart -> ROUTEPEN = USART_ROUTEPEN_RXPEN | USART_ROUTEPEN_TXPEN ;
839
+ if (obj -> serial .location_tx != NC ) {
840
+ obj -> serial .periph .uart -> ROUTELOC0 = (obj -> serial .periph .uart -> ROUTELOC0 & (~_USART_ROUTELOC0_TXLOC_MASK )) | (obj -> serial .location_tx << _USART_ROUTELOC0_TXLOC_SHIFT );
841
+ obj -> serial .periph .uart -> ROUTEPEN = (obj -> serial .periph .uart -> ROUTEPEN & (~_USART_ROUTEPEN_TXPEN_MASK )) | USART_ROUTEPEN_TXPEN ;
842
+ } else {
843
+ obj -> serial .periph .uart -> ROUTEPEN = (obj -> serial .periph .uart -> ROUTEPEN & (~_USART_ROUTEPEN_TXPEN_MASK ));
844
+ }
845
+ if (obj -> serial .location_rx != NC ) {
846
+ obj -> serial .periph .uart -> ROUTELOC0 = (obj -> serial .periph .uart -> ROUTELOC0 & (~_USART_ROUTELOC0_RXLOC_MASK )) | (obj -> serial .location_rx << _USART_ROUTELOC0_RXLOC_SHIFT );
847
+ obj -> serial .periph .uart -> ROUTEPEN = (obj -> serial .periph .uart -> ROUTEPEN & (~_USART_ROUTEPEN_RXPEN_MASK )) | USART_ROUTEPEN_RXPEN ;
848
+ } else {
849
+ obj -> serial .periph .uart -> ROUTEPEN = (obj -> serial .periph .uart -> ROUTEPEN & (~_USART_ROUTEPEN_RXPEN_MASK ));
850
+ }
779
851
#endif
780
852
781
853
/* Re-enable interrupts */
@@ -997,8 +1069,10 @@ void serial_putc(serial_t *obj, int c)
997
1069
* need to use serial_writable(). */
998
1070
if (LEUART_REF_VALID (obj -> serial .periph .leuart )) {
999
1071
LEUART_Tx (obj -> serial .periph .leuart , (uint8_t )(c ));
1072
+ while (!(obj -> serial .periph .leuart -> STATUS & LEUART_STATUS_TXC ));
1000
1073
} else {
1001
1074
USART_Tx (obj -> serial .periph .uart , (uint8_t )(c ));
1075
+ while (!(obj -> serial .periph .uart -> STATUS & USART_STATUS_TXC ));
1002
1076
}
1003
1077
}
1004
1078
@@ -1418,7 +1492,7 @@ static void serial_dmaActivate(serial_t *obj, void* cb, void* buffer, int length
1418
1492
break ;
1419
1493
#endif
1420
1494
default :
1421
- EFM_ASSERT (0 );
1495
+ MBED_ASSERT (0 );
1422
1496
while (1 );
1423
1497
break ;
1424
1498
}
0 commit comments