Skip to content

Commit 7d8b2c0

Browse files
committed
Fix regression towards older platforms (did not have RXBLOCK set, resulting in receiving characters even with RX set to NC) by condensing code.
1 parent 45dbe35 commit 7d8b2c0

File tree

1 file changed

+69
-90
lines changed
  • libraries/mbed/targets/hal/TARGET_Silicon_Labs/TARGET_EFM32

1 file changed

+69
-90
lines changed

libraries/mbed/targets/hal/TARGET_Silicon_Labs/TARGET_EFM32/serial_api.c

Lines changed: 69 additions & 90 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@ static void uart_irq(UARTName, SerialIrq);
8383
static uint8_t serial_get_index(serial_t *obj);
8484
static void serial_enable(serial_t *obj, uint8_t enable);
8585
static void serial_enable_pins(serial_t *obj, uint8_t enable);
86+
static void serial_set_route(serial_t *obj);
8687
static IRQn_Type serial_get_rx_irq_index(serial_t *obj);
8788
static IRQn_Type serial_get_tx_irq_index(serial_t *obj);
8889
static CMU_Clock_TypeDef serial_get_clock(serial_t *obj);
@@ -482,7 +483,7 @@ static void serial_enable_pins(serial_t *obj, uint8_t enable)
482483
}
483484
/* Set DOUT first to prevent glitches */
484485
if(obj->serial.tx_pin != NC) {
485-
GPIO_PinOutSet((GPIO_Port_TypeDef)(obj->serial.tx_pin >> 4 & 0xF), obj->serial.tx_pin & 0xF);
486+
GPIO_PinOutSet((GPIO_Port_TypeDef)(obj->serial.tx_pin >> 4 & 0xF), obj->serial.tx_pin & 0xF);
486487
pin_mode(obj->serial.tx_pin, PushPull);
487488
}
488489
} else {
@@ -495,54 +496,22 @@ static void serial_enable_pins(serial_t *obj, uint8_t enable)
495496
}
496497
}
497498

498-
499-
void serial_init(serial_t *obj, PinName tx, PinName rx)
499+
static void serial_set_route(serial_t *obj)
500500
{
501-
uint32_t baudrate;
502-
uint32_t uart_for_stdio = false;
503-
504-
serial_preinit(obj, tx, rx);
505-
506-
if(LEUART_REF_VALID(obj->serial.periph.leuart)) {
507-
// Set up LEUART clock tree
508-
#ifdef LEUART_USING_LFXO
509-
//set to use LFXO
510-
CMU_ClockEnable(cmuClock_CORELE, true);
511-
CMU_ClockSelectSet(cmuClock_LFB, cmuSelect_LFXO);
512-
#else
513-
//set to use high-speed clock
514-
#ifdef _SILICON_LABS_32B_PLATFORM_2
515-
CMU_ClockSelectSet(cmuClock_LFB, cmuSelect_HFCLKLE);
516-
#else
517-
CMU_ClockSelectSet(cmuClock_LFB, cmuSelect_CORELEDIV2);
518-
#endif
519-
#endif
520-
}
521-
522-
CMU_ClockEnable(serial_get_clock(obj), true);
523-
524-
/* Limitations of board controller: CDC port only supports 115kbaud */
525-
if(((tx == STDIO_UART_TX) || (rx == STDIO_UART_RX))
526-
&& (obj->serial.periph.uart == (USART_TypeDef*)STDIO_UART )
527-
) {
528-
baudrate = 115200;
529-
uart_for_stdio = true;
530-
} else {
531-
baudrate = 9600;
532-
}
533-
534-
/* Configure UART for async operation */
535-
uart_init(obj, baudrate, ParityNone, 1);
536-
537501
/* Enable pins for UART at correct location */
538502
if(LEUART_REF_VALID(obj->serial.periph.leuart)) {
539503
#ifdef _LEUART_ROUTE_LOCATION_SHIFT
540504
obj->serial.periph.leuart->ROUTE = (obj->serial.location << _LEUART_ROUTE_LOCATION_SHIFT);
541-
if(tx != (uint32_t)NC) {
505+
if(obj->serial.tx_pin != (uint32_t)NC) {
542506
obj->serial.periph.leuart->ROUTE |= LEUART_ROUTE_TXPEN;
507+
} else {
508+
obj->serial.periph.leuart->ROUTE &= ~LEUART_ROUTE_TXPEN;
543509
}
544-
if(rx != (uint32_t)NC) {
510+
if(obj->serial.rx_pin != (uint32_t)NC) {
545511
obj->serial.periph.leuart->ROUTE |= LEUART_ROUTE_RXPEN;
512+
} else {
513+
obj->serial.periph.leuart->CMD = LEUART_CMD_RXBLOCKEN;
514+
obj->serial.periph.leuart->ROUTE &= ~LEUART_ROUTE_RXPEN;
546515
}
547516
#else
548517
if(obj->serial.location_tx != NC) {
@@ -559,16 +528,19 @@ void serial_init(serial_t *obj, PinName tx, PinName rx)
559528
obj->serial.periph.leuart->ROUTEPEN = (obj->serial.periph.leuart->ROUTEPEN & (~_LEUART_ROUTEPEN_RXPEN_MASK));
560529
}
561530
#endif
562-
obj->serial.periph.leuart->IFC = LEUART_IFC_TXC;
563-
obj->serial.periph.leuart->CTRL |= LEUART_CTRL_RXDMAWU | LEUART_CTRL_TXDMAWU;
564531
} else {
565532
#ifdef _USART_ROUTE_LOCATION_SHIFT
566-
obj->serial.periph.uart->ROUTE = (obj->serial.location << _USART_ROUTE_LOCATION_SHIFT);
567-
if(tx != (uint32_t)NC) {
533+
obj->serial.periph.uart->ROUTE = (obj->serial.location << _LEUART_ROUTE_LOCATION_SHIFT);
534+
if(obj->serial.tx_pin != (uint32_t)NC) {
568535
obj->serial.periph.uart->ROUTE |= USART_ROUTE_TXPEN;
536+
} else {
537+
obj->serial.periph.uart->ROUTE &= ~USART_ROUTE_TXPEN;
569538
}
570-
if(rx != (uint32_t)NC) {
539+
if(obj->serial.rx_pin != (uint32_t)NC) {
571540
obj->serial.periph.uart->ROUTE |= USART_ROUTE_RXPEN;
541+
} else {
542+
obj->serial.periph.uart->CMD = USART_CMD_RXBLOCKEN;
543+
obj->serial.periph.uart->ROUTE &= ~USART_ROUTE_RXPEN;
572544
}
573545
#else
574546
if(obj->serial.location_tx != NC) {
@@ -585,6 +557,55 @@ void serial_init(serial_t *obj, PinName tx, PinName rx)
585557
obj->serial.periph.uart->ROUTEPEN = (obj->serial.periph.uart->ROUTEPEN & (~_USART_ROUTEPEN_RXPEN_MASK));
586558
}
587559
#endif
560+
}
561+
}
562+
563+
void serial_init(serial_t *obj, PinName tx, PinName rx)
564+
{
565+
uint32_t baudrate;
566+
uint32_t uart_for_stdio = false;
567+
568+
serial_preinit(obj, tx, rx);
569+
570+
if(LEUART_REF_VALID(obj->serial.periph.leuart)) {
571+
// Set up LEUART clock tree
572+
#ifdef LEUART_USING_LFXO
573+
//set to use LFXO
574+
CMU_ClockEnable(cmuClock_CORELE, true);
575+
CMU_ClockSelectSet(cmuClock_LFB, cmuSelect_LFXO);
576+
#else
577+
//set to use high-speed clock
578+
#ifdef _SILICON_LABS_32B_PLATFORM_2
579+
CMU_ClockSelectSet(cmuClock_LFB, cmuSelect_HFCLKLE);
580+
#else
581+
CMU_ClockSelectSet(cmuClock_LFB, cmuSelect_CORELEDIV2);
582+
#endif
583+
#endif
584+
}
585+
586+
CMU_ClockEnable(serial_get_clock(obj), true);
587+
588+
/* Limitations of board controller: CDC port only supports 115kbaud */
589+
if(((tx == STDIO_UART_TX) || (rx == STDIO_UART_RX))
590+
&& (obj->serial.periph.uart == (USART_TypeDef*)STDIO_UART )
591+
) {
592+
baudrate = 115200;
593+
uart_for_stdio = true;
594+
} else {
595+
baudrate = 9600;
596+
}
597+
598+
/* Configure UART for async operation */
599+
uart_init(obj, baudrate, ParityNone, 1);
600+
601+
/* Enable pins for UART at correct location */
602+
serial_set_route(obj);
603+
604+
/* Reset interrupts */
605+
if(LEUART_REF_VALID(obj->serial.periph.leuart)) {
606+
obj->serial.periph.leuart->IFC = LEUART_IFC_TXC;
607+
obj->serial.periph.leuart->CTRL |= LEUART_CTRL_RXDMAWU | LEUART_CTRL_TXDMAWU;
608+
} else {
588609
obj->serial.periph.uart->IFC = USART_IFC_TXC;
589610
}
590611

@@ -761,28 +782,7 @@ void serial_format(serial_t *obj, int data_bits, SerialParity parity, int stop_b
761782
LEUART_Init(obj->serial.periph.leuart, &init);
762783

763784
/* Re-enable pins for UART at correct location */
764-
#ifdef _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-
}
772-
#else
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-
}
785-
#endif
785+
serial_set_route(obj);
786786

787787
/* Re-enable interrupts */
788788
if(was_enabled != 0) {
@@ -827,28 +827,7 @@ void serial_format(serial_t *obj, int data_bits, SerialParity parity, int stop_b
827827
USART_InitAsync(obj->serial.periph.uart, &init);
828828

829829
/* Re-enable pins for UART at correct location */
830-
#ifdef _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-
}
838-
#else
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-
}
851-
#endif
830+
serial_set_route(obj);
852831

853832
/* Re-enable interrupts */
854833
if(was_enabled != 0) {

0 commit comments

Comments
 (0)