Skip to content

Commit

Permalink
Merge pull request #1504 from stevew817/feature/fix/serial_NC
Browse files Browse the repository at this point in the history
[Silicon Labs] Fix regression towards older platforms
  • Loading branch information
0xc0170 committed Jan 15, 2016
2 parents 45dbe35 + 7d8b2c0 commit 170003c
Showing 1 changed file with 69 additions and 90 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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 {
Expand All @@ -495,54 +496,22 @@ static void serial_enable_pins(serial_t *obj, uint8_t enable)
}
}


void serial_init(serial_t *obj, PinName tx, PinName rx)
static void serial_set_route(serial_t *obj)
{
uint32_t baudrate;
uint32_t uart_for_stdio = false;

serial_preinit(obj, tx, rx);

if(LEUART_REF_VALID(obj->serial.periph.leuart)) {
// Set up LEUART clock tree
#ifdef LEUART_USING_LFXO
//set to use LFXO
CMU_ClockEnable(cmuClock_CORELE, true);
CMU_ClockSelectSet(cmuClock_LFB, cmuSelect_LFXO);
#else
//set to use high-speed clock
#ifdef _SILICON_LABS_32B_PLATFORM_2
CMU_ClockSelectSet(cmuClock_LFB, cmuSelect_HFCLKLE);
#else
CMU_ClockSelectSet(cmuClock_LFB, cmuSelect_CORELEDIV2);
#endif
#endif
}

CMU_ClockEnable(serial_get_clock(obj), true);

/* Limitations of board controller: CDC port only supports 115kbaud */
if(((tx == STDIO_UART_TX) || (rx == STDIO_UART_RX))
&& (obj->serial.periph.uart == (USART_TypeDef*)STDIO_UART )
) {
baudrate = 115200;
uart_for_stdio = true;
} else {
baudrate = 9600;
}

/* Configure UART for async operation */
uart_init(obj, baudrate, ParityNone, 1);

/* 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(tx != (uint32_t)NC) {
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(rx != (uint32_t)NC) {
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) {
Expand All @@ -559,16 +528,19 @@ void serial_init(serial_t *obj, PinName tx, PinName rx)
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 = (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(rx != (uint32_t)NC) {
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) {
Expand All @@ -585,6 +557,55 @@ void serial_init(serial_t *obj, PinName tx, PinName rx)
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)
{
uint32_t baudrate;
uint32_t uart_for_stdio = false;

serial_preinit(obj, tx, rx);

if(LEUART_REF_VALID(obj->serial.periph.leuart)) {
// Set up LEUART clock tree
#ifdef LEUART_USING_LFXO
//set to use LFXO
CMU_ClockEnable(cmuClock_CORELE, true);
CMU_ClockSelectSet(cmuClock_LFB, cmuSelect_LFXO);
#else
//set to use high-speed clock
#ifdef _SILICON_LABS_32B_PLATFORM_2
CMU_ClockSelectSet(cmuClock_LFB, cmuSelect_HFCLKLE);
#else
CMU_ClockSelectSet(cmuClock_LFB, cmuSelect_CORELEDIV2);
#endif
#endif
}

CMU_ClockEnable(serial_get_clock(obj), true);

/* Limitations of board controller: CDC port only supports 115kbaud */
if(((tx == STDIO_UART_TX) || (rx == STDIO_UART_RX))
&& (obj->serial.periph.uart == (USART_TypeDef*)STDIO_UART )
) {
baudrate = 115200;
uart_for_stdio = true;
} else {
baudrate = 9600;
}

/* Configure UART for async operation */
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)) {
obj->serial.periph.leuart->IFC = LEUART_IFC_TXC;
obj->serial.periph.leuart->CTRL |= LEUART_CTRL_RXDMAWU | LEUART_CTRL_TXDMAWU;
} else {
obj->serial.periph.uart->IFC = USART_IFC_TXC;
}

Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -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) {
Expand Down

0 comments on commit 170003c

Please sign in to comment.