Skip to content

Commit 170003c

Browse files
committed
Merge pull request #1504 from stevew817/feature/fix/serial_NC
[Silicon Labs] Fix regression towards older platforms
2 parents 45dbe35 + 7d8b2c0 commit 170003c

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)