From 7d8b2c0ca48547c4a1ecf62ecd56779ca88c9652 Mon Sep 17 00:00:00 2001 From: Steven Cooreman Date: Fri, 15 Jan 2016 12:02:25 +0100 Subject: [PATCH] Fix regression towards older platforms (did not have RXBLOCK set, resulting in receiving characters even with RX set to NC) by condensing code. --- .../TARGET_EFM32/serial_api.c | 161 ++++++++---------- 1 file changed, 70 insertions(+), 91 deletions(-) diff --git a/libraries/mbed/targets/hal/TARGET_Silicon_Labs/TARGET_EFM32/serial_api.c b/libraries/mbed/targets/hal/TARGET_Silicon_Labs/TARGET_EFM32/serial_api.c index 6996b15258..9dab25bbbe 100644 --- a/libraries/mbed/targets/hal/TARGET_Silicon_Labs/TARGET_EFM32/serial_api.c +++ b/libraries/mbed/targets/hal/TARGET_Silicon_Labs/TARGET_EFM32/serial_api.c @@ -83,6 +83,7 @@ static void uart_irq(UARTName, SerialIrq); static uint8_t serial_get_index(serial_t *obj); static void serial_enable(serial_t *obj, uint8_t enable); static void serial_enable_pins(serial_t *obj, uint8_t enable); +static void serial_set_route(serial_t *obj); static IRQn_Type serial_get_rx_irq_index(serial_t *obj); static IRQn_Type serial_get_tx_irq_index(serial_t *obj); 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) } /* Set DOUT first to prevent glitches */ if(obj->serial.tx_pin != NC) { - GPIO_PinOutSet((GPIO_Port_TypeDef)(obj->serial.tx_pin >> 4 & 0xF), obj->serial.tx_pin & 0xF); + GPIO_PinOutSet((GPIO_Port_TypeDef)(obj->serial.tx_pin >> 4 & 0xF), obj->serial.tx_pin & 0xF); pin_mode(obj->serial.tx_pin, PushPull); } } else { @@ -495,6 +496,69 @@ static void serial_enable_pins(serial_t *obj, uint8_t enable) } } +static void serial_set_route(serial_t *obj) +{ + /* Enable pins for UART at correct location */ + if(LEUART_REF_VALID(obj->serial.periph.leuart)) { +#ifdef _LEUART_ROUTE_LOCATION_SHIFT + obj->serial.periph.leuart->ROUTE = (obj->serial.location << _LEUART_ROUTE_LOCATION_SHIFT); + if(obj->serial.tx_pin != (uint32_t)NC) { + obj->serial.periph.leuart->ROUTE |= LEUART_ROUTE_TXPEN; + } else { + obj->serial.periph.leuart->ROUTE &= ~LEUART_ROUTE_TXPEN; + } + if(obj->serial.rx_pin != (uint32_t)NC) { + obj->serial.periph.leuart->ROUTE |= LEUART_ROUTE_RXPEN; + } else { + obj->serial.periph.leuart->CMD = LEUART_CMD_RXBLOCKEN; + obj->serial.periph.leuart->ROUTE &= ~LEUART_ROUTE_RXPEN; + } +#else + if(obj->serial.location_tx != NC) { + obj->serial.periph.leuart->ROUTELOC0 = (obj->serial.periph.leuart->ROUTELOC0 & (~_LEUART_ROUTELOC0_TXLOC_MASK)) | (obj->serial.location_tx << _LEUART_ROUTELOC0_TXLOC_SHIFT); + obj->serial.periph.leuart->ROUTEPEN = (obj->serial.periph.leuart->ROUTEPEN & (~_LEUART_ROUTEPEN_TXPEN_MASK)) | LEUART_ROUTEPEN_TXPEN; + } else { + obj->serial.periph.leuart->ROUTEPEN = (obj->serial.periph.leuart->ROUTEPEN & (~_LEUART_ROUTEPEN_TXPEN_MASK)); + } + if(obj->serial.location_rx != NC) { + obj->serial.periph.leuart->ROUTELOC0 = (obj->serial.periph.leuart->ROUTELOC0 & (~_LEUART_ROUTELOC0_RXLOC_MASK)) | (obj->serial.location_rx << _LEUART_ROUTELOC0_RXLOC_SHIFT); + obj->serial.periph.leuart->ROUTEPEN = (obj->serial.periph.leuart->ROUTEPEN & (~_LEUART_ROUTEPEN_RXPEN_MASK)) | LEUART_ROUTEPEN_RXPEN; + } else { + obj->serial.periph.leuart->CMD = LEUART_CMD_RXBLOCKEN; + obj->serial.periph.leuart->ROUTEPEN = (obj->serial.periph.leuart->ROUTEPEN & (~_LEUART_ROUTEPEN_RXPEN_MASK)); + } +#endif + } else { +#ifdef _USART_ROUTE_LOCATION_SHIFT + obj->serial.periph.uart->ROUTE = (obj->serial.location << _LEUART_ROUTE_LOCATION_SHIFT); + if(obj->serial.tx_pin != (uint32_t)NC) { + obj->serial.periph.uart->ROUTE |= USART_ROUTE_TXPEN; + } else { + obj->serial.periph.uart->ROUTE &= ~USART_ROUTE_TXPEN; + } + if(obj->serial.rx_pin != (uint32_t)NC) { + obj->serial.periph.uart->ROUTE |= USART_ROUTE_RXPEN; + } else { + obj->serial.periph.uart->CMD = USART_CMD_RXBLOCKEN; + obj->serial.periph.uart->ROUTE &= ~USART_ROUTE_RXPEN; + } +#else + if(obj->serial.location_tx != NC) { + obj->serial.periph.uart->ROUTELOC0 = (obj->serial.periph.uart->ROUTELOC0 & (~_USART_ROUTELOC0_TXLOC_MASK)) | (obj->serial.location_tx << _USART_ROUTELOC0_TXLOC_SHIFT); + obj->serial.periph.uart->ROUTEPEN = (obj->serial.periph.uart->ROUTEPEN & (~_USART_ROUTEPEN_TXPEN_MASK)) | USART_ROUTEPEN_TXPEN; + } else { + obj->serial.periph.uart->ROUTEPEN = (obj->serial.periph.uart->ROUTEPEN & (~_USART_ROUTEPEN_TXPEN_MASK)); + } + if(obj->serial.location_rx != NC) { + obj->serial.periph.uart->ROUTELOC0 = (obj->serial.periph.uart->ROUTELOC0 & (~_USART_ROUTELOC0_RXLOC_MASK)) | (obj->serial.location_rx << _USART_ROUTELOC0_RXLOC_SHIFT); + obj->serial.periph.uart->ROUTEPEN = (obj->serial.periph.uart->ROUTEPEN & (~_USART_ROUTEPEN_RXPEN_MASK)) | USART_ROUTEPEN_RXPEN; + } else { + obj->serial.periph.uart->CMD = USART_CMD_RXBLOCKEN; + obj->serial.periph.uart->ROUTEPEN = (obj->serial.periph.uart->ROUTEPEN & (~_USART_ROUTEPEN_RXPEN_MASK)); + } +#endif + } +} void serial_init(serial_t *obj, PinName tx, PinName rx) { @@ -535,56 +599,13 @@ void serial_init(serial_t *obj, PinName tx, PinName rx) uart_init(obj, baudrate, ParityNone, 1); /* Enable pins for UART at correct location */ + serial_set_route(obj); + + /* Reset interrupts */ if(LEUART_REF_VALID(obj->serial.periph.leuart)) { -#ifdef _LEUART_ROUTE_LOCATION_SHIFT - obj->serial.periph.leuart->ROUTE = (obj->serial.location << _LEUART_ROUTE_LOCATION_SHIFT); - if(tx != (uint32_t)NC) { - obj->serial.periph.leuart->ROUTE |= LEUART_ROUTE_TXPEN; - } - if(rx != (uint32_t)NC) { - obj->serial.periph.leuart->ROUTE |= LEUART_ROUTE_RXPEN; - } -#else - if(obj->serial.location_tx != NC) { - obj->serial.periph.leuart->ROUTELOC0 = (obj->serial.periph.leuart->ROUTELOC0 & (~_LEUART_ROUTELOC0_TXLOC_MASK)) | (obj->serial.location_tx << _LEUART_ROUTELOC0_TXLOC_SHIFT); - obj->serial.periph.leuart->ROUTEPEN = (obj->serial.periph.leuart->ROUTEPEN & (~_LEUART_ROUTEPEN_TXPEN_MASK)) | LEUART_ROUTEPEN_TXPEN; - } else { - obj->serial.periph.leuart->ROUTEPEN = (obj->serial.periph.leuart->ROUTEPEN & (~_LEUART_ROUTEPEN_TXPEN_MASK)); - } - if(obj->serial.location_rx != NC) { - obj->serial.periph.leuart->ROUTELOC0 = (obj->serial.periph.leuart->ROUTELOC0 & (~_LEUART_ROUTELOC0_RXLOC_MASK)) | (obj->serial.location_rx << _LEUART_ROUTELOC0_RXLOC_SHIFT); - obj->serial.periph.leuart->ROUTEPEN = (obj->serial.periph.leuart->ROUTEPEN & (~_LEUART_ROUTEPEN_RXPEN_MASK)) | LEUART_ROUTEPEN_RXPEN; - } else { - obj->serial.periph.leuart->CMD = LEUART_CMD_RXBLOCKEN; - obj->serial.periph.leuart->ROUTEPEN = (obj->serial.periph.leuart->ROUTEPEN & (~_LEUART_ROUTEPEN_RXPEN_MASK)); - } -#endif obj->serial.periph.leuart->IFC = LEUART_IFC_TXC; obj->serial.periph.leuart->CTRL |= LEUART_CTRL_RXDMAWU | LEUART_CTRL_TXDMAWU; } else { -#ifdef _USART_ROUTE_LOCATION_SHIFT - obj->serial.periph.uart->ROUTE = (obj->serial.location << _USART_ROUTE_LOCATION_SHIFT); - if(tx != (uint32_t)NC) { - obj->serial.periph.uart->ROUTE |= USART_ROUTE_TXPEN; - } - if(rx != (uint32_t)NC) { - obj->serial.periph.uart->ROUTE |= USART_ROUTE_RXPEN; - } -#else - if(obj->serial.location_tx != NC) { - obj->serial.periph.uart->ROUTELOC0 = (obj->serial.periph.uart->ROUTELOC0 & (~_USART_ROUTELOC0_TXLOC_MASK)) | (obj->serial.location_tx << _USART_ROUTELOC0_TXLOC_SHIFT); - obj->serial.periph.uart->ROUTEPEN = (obj->serial.periph.uart->ROUTEPEN & (~_USART_ROUTEPEN_TXPEN_MASK)) | USART_ROUTEPEN_TXPEN; - } else { - obj->serial.periph.uart->ROUTEPEN = (obj->serial.periph.uart->ROUTEPEN & (~_USART_ROUTEPEN_TXPEN_MASK)); - } - if(obj->serial.location_rx != NC) { - obj->serial.periph.uart->ROUTELOC0 = (obj->serial.periph.uart->ROUTELOC0 & (~_USART_ROUTELOC0_RXLOC_MASK)) | (obj->serial.location_rx << _USART_ROUTELOC0_RXLOC_SHIFT); - obj->serial.periph.uart->ROUTEPEN = (obj->serial.periph.uart->ROUTEPEN & (~_USART_ROUTEPEN_RXPEN_MASK)) | USART_ROUTEPEN_RXPEN; - } else { - obj->serial.periph.uart->CMD = USART_CMD_RXBLOCKEN; - obj->serial.periph.uart->ROUTEPEN = (obj->serial.periph.uart->ROUTEPEN & (~_USART_ROUTEPEN_RXPEN_MASK)); - } -#endif obj->serial.periph.uart->IFC = USART_IFC_TXC; } @@ -761,28 +782,7 @@ void serial_format(serial_t *obj, int data_bits, SerialParity parity, int stop_b LEUART_Init(obj->serial.periph.leuart, &init); /* Re-enable pins for UART at correct location */ -#ifdef _LEUART_ROUTE_LOCATION_SHIFT - obj->serial.periph.leuart->ROUTE = (obj->serial.location << _LEUART_ROUTE_LOCATION_SHIFT); - if(obj->serial.tx_pin != (uint32_t)NC) { - obj->serial.periph.leuart->ROUTE |= LEUART_ROUTE_TXPEN; - } - if(obj->serial.rx_pin != (uint32_t)NC) { - obj->serial.periph.leuart->ROUTE |= LEUART_ROUTE_RXPEN; - } -#else - if(obj->serial.location_tx != NC) { - obj->serial.periph.leuart->ROUTELOC0 = (obj->serial.periph.leuart->ROUTELOC0 & (~_LEUART_ROUTELOC0_TXLOC_MASK)) | (obj->serial.location_tx << _LEUART_ROUTELOC0_TXLOC_SHIFT); - obj->serial.periph.leuart->ROUTEPEN = (obj->serial.periph.leuart->ROUTEPEN & (~_LEUART_ROUTEPEN_TXPEN_MASK)) | LEUART_ROUTEPEN_TXPEN; - } else { - obj->serial.periph.leuart->ROUTEPEN = (obj->serial.periph.leuart->ROUTEPEN & (~_LEUART_ROUTEPEN_TXPEN_MASK)); - } - if(obj->serial.location_rx != NC) { - obj->serial.periph.leuart->ROUTELOC0 = (obj->serial.periph.leuart->ROUTELOC0 & (~_LEUART_ROUTELOC0_RXLOC_MASK)) | (obj->serial.location_rx << _LEUART_ROUTELOC0_RXLOC_SHIFT); - obj->serial.periph.leuart->ROUTEPEN = (obj->serial.periph.leuart->ROUTEPEN & (~_LEUART_ROUTEPEN_RXPEN_MASK)) | LEUART_ROUTEPEN_RXPEN; - } else { - obj->serial.periph.leuart->ROUTEPEN = (obj->serial.periph.leuart->ROUTEPEN & (~_LEUART_ROUTEPEN_RXPEN_MASK)); - } -#endif + serial_set_route(obj); /* Re-enable interrupts */ if(was_enabled != 0) { @@ -827,28 +827,7 @@ void serial_format(serial_t *obj, int data_bits, SerialParity parity, int stop_b USART_InitAsync(obj->serial.periph.uart, &init); /* Re-enable pins for UART at correct location */ -#ifdef _USART_ROUTE_LOCATION_SHIFT - obj->serial.periph.uart->ROUTE = (obj->serial.location << _USART_ROUTE_LOCATION_SHIFT); - if(obj->serial.tx_pin != (uint32_t)NC) { - obj->serial.periph.uart->ROUTE |= USART_ROUTE_TXPEN; - } - if(obj->serial.rx_pin != (uint32_t)NC) { - obj->serial.periph.uart->ROUTE |= USART_ROUTE_RXPEN; - } -#else - if(obj->serial.location_tx != NC) { - obj->serial.periph.uart->ROUTELOC0 = (obj->serial.periph.uart->ROUTELOC0 & (~_USART_ROUTELOC0_TXLOC_MASK)) | (obj->serial.location_tx << _USART_ROUTELOC0_TXLOC_SHIFT); - obj->serial.periph.uart->ROUTEPEN = (obj->serial.periph.uart->ROUTEPEN & (~_USART_ROUTEPEN_TXPEN_MASK)) | USART_ROUTEPEN_TXPEN; - } else { - obj->serial.periph.uart->ROUTEPEN = (obj->serial.periph.uart->ROUTEPEN & (~_USART_ROUTEPEN_TXPEN_MASK)); - } - if(obj->serial.location_rx != NC) { - obj->serial.periph.uart->ROUTELOC0 = (obj->serial.periph.uart->ROUTELOC0 & (~_USART_ROUTELOC0_RXLOC_MASK)) | (obj->serial.location_rx << _USART_ROUTELOC0_RXLOC_SHIFT); - obj->serial.periph.uart->ROUTEPEN = (obj->serial.periph.uart->ROUTEPEN & (~_USART_ROUTEPEN_RXPEN_MASK)) | USART_ROUTEPEN_RXPEN; - } else { - obj->serial.periph.uart->ROUTEPEN = (obj->serial.periph.uart->ROUTEPEN & (~_USART_ROUTEPEN_RXPEN_MASK)); - } -#endif + serial_set_route(obj); /* Re-enable interrupts */ if(was_enabled != 0) {