int uart_init(uart_t uart, uint32_t baudrate, uart_rx_cb_t rx_cb, void *arg) { /* do basic initialization */ int res = uart_init_blocking(uart, baudrate); if(res < 0) { return res; } /* remember callback addresses */ uart_config[uart].rx_cb = rx_cb; uart_config[uart].arg = arg; /* enable receive and send interrupt */ switch(uart) { #if UART_0_EN case UART_0: NVIC_SetPriority(UART_0_IRQ_RX_CHAN, UART_0_IRQ_RX_PRIO); NVIC_EnableIRQ(UART_0_IRQ_RX_CHAN); USART_IntEnable(UART_0_DEV, _USART_IEN_RXDATAV_MASK); #if UART_0_ENABLE_BUF ringbuffer_init(&rb_uart0, buffer0, UART_0_BUFSIZE); NVIC_SetPriority(UART_0_IRQ_TX_CHAN, UART_0_IRQ_TX_PRIO); NVIC_EnableIRQ(UART_0_IRQ_TX_CHAN); USART_IntEnable(UART_0_DEV, _USART_IEN_TXBL_MASK); #endif break; #endif #if UART_1_EN case UART_1: NVIC_SetPriority(UART_1_IRQ_RX_CHAN, UART_1_IRQ_RX_PRIO); NVIC_SetPriority(UART_1_IRQ_TX_CHAN, UART_1_IRQ_TX_PRIO); NVIC_EnableIRQ(UART_1_IRQ_RX_CHAN); NVIC_EnableIRQ(UART_1_IRQ_TX_CHAN); USART_IntEnable(UART_1_DEV, _USART_IEN_RXDATAV_MASK); #if UART_1_ENABLE_BUF ringbuffer_init(&rb_uart1, buffer1, UART_1_BUFSIZE); NVIC_SetPriority(UART_1_IRQ_TX_CHAN, UART_1_IRQ_TX_PRIO); NVIC_EnableIRQ(UART_1_IRQ_TX_CHAN); USART_IntEnable(UART_1_DEV, _USART_IEN_TXBL_MASK); #endif break; #endif /* UART2 is considered as LEUART device which is functionable in low power mode */ #if UART_2_EN case UART_2: NVIC_SetPriority(UART_2_IRQ, UART_2_IRQ_PRIO); NVIC_EnableIRQ(UART_2_IRQ); LEUART_IntEnable(UART_2_DEV, LEUART_IEN_RXDATAV); #if UART_2_ENABLE_BUF ringbuffer_init(&rb_uart2, buffer2, UART_2_BUFSIZE); LEUART_IntEnable(UART_2_DEV, _LEUART_IEN_TXBL_MASK); #endif break; #endif default: /* Invalid usart device */ return -1; } return 0; }
/**************************************************************************** * void spi_enable_interrupt(spi_t *obj, uint32_t handler, uint8_t enable) * * This will enable the interrupt in NVIC for the associated USART RX channel * * * obj: pointer to spi object * * handler: pointer to interrupt handler for this channel * * enable: Whether to enable (true) or disable (false) the interrupt * ****************************************************************************/ void spi_enable_interrupt(spi_t *obj, uint32_t handler, uint8_t enable) { IRQn_Type IRQvector; switch ((uint32_t)obj->spi.spi) { #ifdef USART0 case USART_0: IRQvector = USART0_RX_IRQn; break; #endif #ifdef USART1 case USART_1: IRQvector = USART1_RX_IRQn; break; #endif #ifdef USART2 case USART_2: IRQvector = USART2_RX_IRQn; break; #endif default: error("Undefined SPI peripheral"); return; } if (enable == true) { vIRQ_SetVector(IRQvector, handler); USART_IntEnable(obj->spi.spi, USART_IEN_RXDATAV); vIRQ_EnableIRQ(IRQvector); } else { vIRQ_SetVector(IRQvector, handler); USART_IntDisable(obj->spi.spi, USART_IEN_RXDATAV); vIRQ_DisableIRQ(IRQvector); } }
/****************************************************************************** * @brief uartPutData function * *****************************************************************************/ void uartPutData(uint8_t * dataPtr, uint32_t dataLen) { uint32_t i = 0; /* Check if buffer is large enough for data */ if (dataLen > BUFFERSIZE) { /* Buffer can never fit the requested amount of data */ return; } /* Check if buffer has room for new data */ if ((txBuf.pendingBytes + dataLen) > BUFFERSIZE) { /* Wait until room */ while ((txBuf.pendingBytes + dataLen) > BUFFERSIZE) ; } /* Fill dataPtr[0:dataLen-1] into txBuffer */ while (i < dataLen) { txBuf.data[txBuf.wrI] = *(dataPtr + i); txBuf.wrI = (txBuf.wrI + 1) % BUFFERSIZE; i++; } /* Increment pending byte counter */ txBuf.pendingBytes += dataLen; /* Enable interrupt on USART TX Buffer*/ USART_IntEnable(uart, USART_IF_TXBL); }
static void uart_gecko_irq_rx_enable(struct device *dev) { const struct uart_gecko_config *config = dev->config->config_info; u32_t mask = USART_IEN_RXDATAV; USART_IntEnable(config->base, mask); }
/** * Initialize the UART. * */ void usart2_init(unsigned long baudrate) { USART_InitAsync_TypeDef init = USART_INITASYNC_DEFAULT; /* Configure controller */ // Enable clocks CMU_ClockEnable(cmuClock_HFPER, true); CMU_ClockEnable(cmuClock_USART2, true); init.enable = usartDisable; init.baudrate = baudrate; USART_InitAsync(USART2, &init); /* Enable pins at USART2 location */ USART2->ROUTE = USART_ROUTE_RXPEN | USART_ROUTE_TXPEN | (USART2_LOCATION << _USART_ROUTE_LOCATION_SHIFT); /* Clear previous RX interrupts */ USART_IntClear(USART2, USART_IF_RXDATAV); NVIC_ClearPendingIRQ(USART2_RX_IRQn); /* Enable RX interrupts */ USART_IntEnable(USART2, USART_IF_RXDATAV); NVIC_EnableIRQ(USART2_RX_IRQn); /* Finally enable it */ USART_Enable(USART2, usartEnable); }
static void uart_gecko_irq_err_enable(struct device *dev) { const struct uart_gecko_config *config = dev->config->config_info; USART_IntEnable(config->base, USART_IF_RXOF | USART_IF_PERR | USART_IF_FERR); }
/* "power down" COM by switching from DMA to UART byte interrupts */ void COM_InternalPowerDown() { if (DMA_REG->IEN!=0) { dma_IEN= DMA_REG->IEN; DMA_REG->IEN = 0; } #ifdef COM_USART0_ENABLE NVIC_ClearPendingIRQ( USART0_RX_IRQn ); NVIC_EnableIRQ( USART0_RX_IRQn ); USART_IntEnable(USART0, USART_IF_RXDATAV); #endif #ifdef COM_USART1_ENABLE NVIC_ClearPendingIRQ( USART1_RX_IRQn ); NVIC_EnableIRQ( USART1_RX_IRQn ); USART_IntEnable(USART1, USART_IF_RXDATAV); #endif #ifdef COM_USART2_ENABLE NVIC_ClearPendingIRQ( USART2_RX_IRQn ); NVIC_EnableIRQ( USART2_RX_IRQn ); USART_IntEnable(USART2, USART_IF_RXDATAV); #endif }
/****************************************************************************** * @brief uartPutChar function * *****************************************************************************/ void uartPutChar(uint8_t ch) { /* Check if Tx queue has room for new data */ if ((txBuf.pendingBytes + 1) > BUFFERSIZE) { /* Wait until there is room in queue */ while ((txBuf.pendingBytes + 1) > BUFFERSIZE) ; } /* Copy ch into txBuffer */ txBuf.data[txBuf.wrI] = ch; txBuf.wrI = (txBuf.wrI + 1) % BUFFERSIZE; /* Increment pending byte counter */ txBuf.pendingBytes++; /* Enable interrupt on USART TX Buffer*/ USART_IntEnable(uart, USART_IF_TXBL); }
/**************************************************************************//** * @brief Intializes UART/LEUART *****************************************************************************/ void UART1_SerialInit(void) { /* Configure GPIO pins */ CMU_ClockEnable(cmuClock_GPIO, true); /* To avoid false start, configure output as high */ GPIO_PinModeSet(gpioPortB, 9, gpioModePushPull, 1); GPIO_PinModeSet(gpioPortB, 10, gpioModeInput, 0); USART_TypeDef *usart = UART1; USART_InitAsync_TypeDef init = USART_INITASYNC_DEFAULT; /* Enable EFM32GG_DK3750 RS232/UART switch */ BSP_PeripheralAccess(BSP_RS232_UART, true); /* Enable peripheral clocks */ CMU_ClockEnable(cmuClock_HFPER, true); CMU_ClockEnable(cmuClock_UART1, true); /* Configure USART for basic async operation */ init.enable = usartDisable; USART_InitAsync(usart, &init); /* Enable pins at UART1 location #2 */ usart->ROUTE = USART_ROUTE_RXPEN | USART_ROUTE_TXPEN | USART_ROUTE_LOCATION_LOC2; /* Clear previous RX interrupts */ USART_IntClear(UART1, USART_IF_RXDATAV); NVIC_ClearPendingIRQ(UART1_RX_IRQn); /* Enable RX interrupts */ USART_IntEnable(UART1, USART_IF_RXDATAV); NVIC_EnableIRQ(UART1_RX_IRQn); /* Finally enable it */ USART_Enable(usart, usartEnable); #if !defined(__CROSSWORKS_ARM) && defined(__GNUC__) setvbuf(stdout, NULL, _IONBF, 0); /*Set unbuffered mode for stdout (newlib)*/ #endif initialized = true; }
/****************************************************************************** * @brief usartSetup function * ******************************************************************************/ void usartSetup(void) { cmuSetup(); /* Configure GPIO pin as open drain */ GPIO_PinModeSet(SC_GPIO_DATA_PORT, SC_GPIO_DATA_PIN, gpioModeWiredAndPullUp, 1); /* Prepare struct for initializing USART in asynchronous mode*/ usartInit.enable = usartDisable; /* Don't enable USART upon intialization */ usartInit.refFreq = 0; /* Provide information on reference frequency. When set to 0, the reference frequency is */ usartInit.baudrate = SC_BAUD_RATE; /* Baud rate */ usartInit.oversampling = usartOVS16; /* Oversampling. Range is 4x, 6x, 8x or 16x */ usartInit.databits = usartDatabits8; /* Number of data bits. Range is 4 to 10 */ usartInit.parity = usartEvenParity; /* Parity mode */ usartInit.stopbits = usartStopbits1p5; /* Number of stop bits. Range is 0 to 2, 1.5 for smartcard. */ usartInit.mvdis = false; /* Disable majority voting */ usartInit.prsRxEnable = false; /* Enable USART Rx via Peripheral Reflex System */ usartInit.prsRxCh = usartPrsRxCh0; /* Select PRS channel if enabled */ /* Initialize USART with usartInit struct */ USART_InitAsync(usart, &usartInit); /* Smart card specific settings for T0 mode. */ usart->CTRL |= USART_CTRL_SCMODE | USART_CTRL_AUTOTRI | USART_CTRL_LOOPBK; /* Prepare USART Rx interrupt */ USART_IntClear(usart, _USART_IF_MASK); USART_IntEnable(usart, USART_IF_RXDATAV); NVIC_ClearPendingIRQ(USART1_RX_IRQn); NVIC_EnableIRQ(USART1_RX_IRQn); /* Enable I/O pins at USART1 location #2 */ usart->ROUTE = USART_ROUTE_TXPEN | SC_USART_LOCATION; /* Disable reception before enabling uart to discard erroneus stuff while card is unpowered. */ usartFlushBuffer(); usartAcceptRX(false); /* Enable USART */ USART_Enable(usart, usartEnable); }
/****************************************************************************** * @brief uartSetup function * ******************************************************************************/ void uartSetup(void) { /* Enable clock for GPIO module (required for pin configuration) */ CMU_ClockEnable(cmuClock_GPIO, true); /* Configure GPIO pins */ GPIO_PinModeSet(gpioPortB, 9, gpioModePushPull, 1); GPIO_PinModeSet(gpioPortB, 10, gpioModeInput, 0); /* Prepare struct for initializing UART in asynchronous mode*/ uartInit.enable = usartDisable; /* Don't enable UART upon intialization */ uartInit.refFreq = 0; /* Provide information on reference frequency. When set to 0, the reference frequency is */ uartInit.baudrate = 115200; /* Baud rate */ uartInit.oversampling = usartOVS16; /* Oversampling. Range is 4x, 6x, 8x or 16x */ uartInit.databits = usartDatabits8; /* Number of data bits. Range is 4 to 10 */ uartInit.parity = usartNoParity; /* Parity mode */ uartInit.stopbits = usartStopbits1; /* Number of stop bits. Range is 0 to 2 */ uartInit.mvdis = false; /* Disable majority voting */ uartInit.prsRxEnable = false; /* Enable USART Rx via Peripheral Reflex System */ uartInit.prsRxCh = usartPrsRxCh0; /* Select PRS channel if enabled */ /* Initialize USART with uartInit struct */ USART_InitAsync(uart, &uartInit); /* Prepare UART Rx and Tx interrupts */ USART_IntClear(uart, _UART_IF_MASK); USART_IntEnable(uart, UART_IF_RXDATAV); NVIC_ClearPendingIRQ(UART1_RX_IRQn); NVIC_ClearPendingIRQ(UART1_TX_IRQn); NVIC_EnableIRQ(UART1_RX_IRQn); NVIC_EnableIRQ(UART1_TX_IRQn); /* Enable I/O pins at UART1 location #2 */ uart->ROUTE = UART_ROUTE_RXPEN | UART_ROUTE_TXPEN | UART_ROUTE_LOCATION_LOC2; /* Enable UART */ USART_Enable(uart, usartEnable); }
/**************************************************************************//** * @brief UART/LEUART IRQ Handler *****************************************************************************/ void RETARGET_IRQ_NAME(void) { #if defined(RETARGET_USART) if (RETARGET_UART->STATUS & USART_STATUS_RXDATAV) { #else if (RETARGET_UART->IF & LEUART_IF_RXDATAV) { #endif /* Store Data */ rxBuffer[rxWriteIndex] = RETARGET_RX(RETARGET_UART); rxWriteIndex++; rxCount++; if (rxWriteIndex == RXBUFSIZE) { rxWriteIndex = 0; } /* Check for overflow - flush buffer */ if (rxCount > RXBUFSIZE) { rxWriteIndex = 0; rxCount = 0; rxReadIndex = 0; } } } /** @} (end group RetargetIo) */ /**************************************************************************//** * @brief UART/LEUART toggle LF to CRLF conversion * @param on If non-zero, automatic LF to CRLF conversion will be enabled *****************************************************************************/ void RETARGET_SerialCrLf(int on) { if (on) LFtoCRLF = 1; else LFtoCRLF = 0; } /**************************************************************************//** * @brief Intializes UART/LEUART *****************************************************************************/ void RETARGET_SerialInit(void) { /* Enable peripheral clocks */ CMU_ClockEnable(cmuClock_HFPER, true); /* Configure GPIO pins */ CMU_ClockEnable(cmuClock_GPIO, true); /* To avoid false start, configure output as high */ GPIO_PinModeSet(RETARGET_TXPORT, RETARGET_TXPIN, gpioModePushPull, 1); GPIO_PinModeSet(RETARGET_RXPORT, RETARGET_RXPIN, gpioModeInput, 0); #if defined(RETARGET_USART) USART_TypeDef *usart = RETARGET_UART; USART_InitAsync_TypeDef init = USART_INITASYNC_DEFAULT; /* Enable DK RS232/UART switch */ RETARGET_PERIPHERAL_ENABLE(); CMU_ClockEnable(RETARGET_CLK, true); /* Configure USART for basic async operation */ init.enable = usartDisable; USART_InitAsync(usart, &init); /* Enable pins at correct UART/USART location. */ #if defined( USART_ROUTEPEN_RXPEN ) usart->ROUTEPEN = USART_ROUTEPEN_RXPEN | USART_ROUTEPEN_TXPEN; usart->ROUTELOC0 = ( usart->ROUTELOC0 & ~( _USART_ROUTELOC0_TXLOC_MASK | _USART_ROUTELOC0_RXLOC_MASK ) ) | ( RETARGET_TX_LOCATION << _USART_ROUTELOC0_TXLOC_SHIFT ) | ( RETARGET_RX_LOCATION << _USART_ROUTELOC0_RXLOC_SHIFT ); #else usart->ROUTE = USART_ROUTE_RXPEN | USART_ROUTE_TXPEN | RETARGET_LOCATION; #endif /* Clear previous RX interrupts */ USART_IntClear(RETARGET_UART, USART_IF_RXDATAV); NVIC_ClearPendingIRQ(RETARGET_IRQn); /* Enable RX interrupts */ USART_IntEnable(RETARGET_UART, USART_IF_RXDATAV); NVIC_EnableIRQ(RETARGET_IRQn); /* Finally enable it */ USART_Enable(usart, usartEnable); #else LEUART_TypeDef *leuart = RETARGET_UART; LEUART_Init_TypeDef init = LEUART_INIT_DEFAULT; /* Enable DK LEUART/RS232 switch */ RETARGET_PERIPHERAL_ENABLE(); /* Enable CORE LE clock in order to access LE modules */ CMU_ClockEnable(cmuClock_CORELE, true); #if defined(RETARGET_VCOM) /* Select HFXO/2 for LEUARTs (and wait for it to stabilize) */ CMU_ClockSelectSet(cmuClock_LFB, cmuSelect_CORELEDIV2); #else /* Select LFXO for LEUARTs (and wait for it to stabilize) */ CMU_ClockSelectSet(cmuClock_LFB, cmuSelect_LFXO); #endif CMU_ClockEnable(RETARGET_CLK, true); /* Do not prescale clock */ CMU_ClockDivSet(RETARGET_CLK, cmuClkDiv_1); /* Configure LEUART */ init.enable = leuartDisable; #if defined(RETARGET_VCOM) init.baudrate = 115200; #endif LEUART_Init(leuart, &init); /* Enable pins at default location */ leuart->ROUTE = LEUART_ROUTE_RXPEN | LEUART_ROUTE_TXPEN | RETARGET_LOCATION; /* Clear previous RX interrupts */ LEUART_IntClear(RETARGET_UART, LEUART_IF_RXDATAV); NVIC_ClearPendingIRQ(RETARGET_IRQn); /* Enable RX interrupts */ LEUART_IntEnable(RETARGET_UART, LEUART_IF_RXDATAV); NVIC_EnableIRQ(RETARGET_IRQn); /* Finally enable it */ LEUART_Enable(leuart, leuartEnable); #endif #if !defined(__CROSSWORKS_ARM) && defined(__GNUC__) setvbuf(stdout, NULL, _IONBF, 0); /*Set unbuffered mode for stdout (newlib)*/ #endif initialized = true; }
void uart_write(uart_t uart, const uint8_t *data, size_t len) { switch(uart) { #if UART_0_EN case UART_0: #if UART_0_ENABLE_BUF for(int count = 0; count < len; count++) { NVIC_DisableIRQ(UART_0_IRQ_TX_CHAN); ringbuffer_add_one(&rb_uart0, data[count]); NVIC_EnableIRQ(UART_0_IRQ_TX_CHAN); } USART_IntEnable(UART_0_DEV, USART_IF_TXBL); #else for(size_t i = 0; i < len; i++) { /* Check that transmit buffer is empty */ while(!(UART_0_DEV->STATUS & USART_STATUS_TXBL)) ; /* Write data to buffer */ UART_0_DEV->TXDATA = (uint32_t)data[i]; } #endif break; #endif #if UART_1_EN case UART_1: #if UART_1_ENABLE_BUF for(int count = 0; count < len; count++) { NVIC_DisableIRQ(UART_1_IRQ_TX_CHAN); ringbuffer_add_one(&rb_uart1, data[count]); NVIC_EnableIRQ(UART_1_IRQ_TX_CHAN); } USART_IntEnable(UART_1_DEV, USART_IF_TXBL); #else for(size_t i = 0; i < len; i++) { /* Check that transmit buffer is empty */ while(!(UART_1_DEV->STATUS & USART_STATUS_TXBL)) ; /* Write data to buffer */ UART_1_DEV->TXDATA = (uint32_t)data[i]; } #endif break; #endif #if UART_2_EN case UART_2: #if UART_2_ENABLE_BUF for(int count = 0; count < len; count++) { NVIC_DisableIRQ(UART_2_IRQ); ringbuffer_add_one(&rb_uart2, data[count]); NVIC_EnableIRQ(UART_2_IRQ); } LEUART_IntEnable(UART_2_DEV, LEUART_IF_TXBL); #else for(size_t i = 0; i < len; i++) { /* Check that transmit buffer is empty */ while (!(UART_2_DEV->STATUS & LEUART_STATUS_TXBL)) ; /* Avoid deadlock if modifying the same register twice when freeze mode is */ /* activated. */ if (!(UART_2_DEV->FREEZE & LEUART_FREEZE_REGFREEZE)) { /* Wait for any pending previous write operation to have been completed */ /* in low frequency domain */ while (UART_2_DEV->SYNCBUSY & LEUART_SYNCBUSY_TXDATA); ; UART_2_DEV->TXDATA = (uint32_t)data[i]; } } #endif break; #endif } }