/* * Copyright (C) 2015 Rakendra Thapa * @} */ #include #include "cpu.h" #include "sched.h" #include "thread.h" #include "periph/uart.h" #include "periph_conf.h" /* guard the file in case no UART is defined */ #if (UART_0_EN) /** * @brief Struct holding the configuration data for a UART device */ typedef struct { uart_rx_cb_t rx_cb; /**< receive callback */ uart_tx_cb_t tx_cb; /**< transmit callback */ void *arg; /**< callback argument */ } uart_conf_t; /** * @brief Unified interrupt handler for all UART devices * * @param uartnum the number of the UART that triggered the ISR * @param uart the UART device that triggered the ISR */ //static inline void irq_handler(uart_t uartnum, USART_TypeDef *uart); /** * @brief UART device configurations */ static uart_conf_t config[UART_NUMOF]; /** * The list of UART peripherals. */ static const unsigned long g_ulUARTPeriph[3] = { SYSCTL_PERIPH_UART0, SYSCTL_PERIPH_UART1, SYSCTL_PERIPH_UART2 }; /** * The list of all possible base address of the console UART */ static const unsigned long g_ulUARTBase[3] = { UART0_BASE, UART1_BASE, UART2_BASE }; // The list of possible interrupts for the console UART. // //***************************************************************************** static const unsigned long g_ulUARTInt[3] = { INT_UART0, INT_UART1, INT_UART2 }; /**********************************************************************************/ /* Configuring the UART console */ int uart_init(uart_t uart, uint32_t baudrate, uart_rx_cb_t rx_cb, uart_tx_cb_t tx_cb, void *arg) { // Check the arguments ASSERT(uart == 0); // Check to make sure the UART peripheral is present if(!ROM_SysCtlPeripheralPresent(SYSCTL_PERIPH_UART0)){ return -1; } int res = uart_init_blocking(uart, baudrate); if(res < 0){ return res; } /* save callbacks */ config[uart].rx_cb = rx_cb; config[uart].tx_cb = tx_cb; config[uart].arg = arg; // ulBase = g_ulUARTBase[uart]; // Configure the relevant UART pins for operations as a UART rather than GPIOs. /* enable recieve interrupt */ switch (uart){ #if UART_0_EN case UART_0: NVIC_SetPriority(UART_0_IRQ_CHAN, UART_IRQ_PRIO); ROM_UARTTxIntModeSet(UART0_BASE, UART_TXINT_MODE_EOT); ROM_UARTFIFOLevelSet(UART0_BASE, UART_FIFO_TX4_8, UART_FIFO_RX4_8); // Set FIFO to 8 Characters ROM_UARTFIFOEnable(UART0_BASE); // Enable FIFOs // Enable the UART interrupt NVIC_EnableIRQ(UART_0_IRQ_CHAN); // Enable RX interrupt UART0_IM_R = UART_IM_RXIM | UART_IM_RTIM; break; #endif #if UART_1_EN case UART_1: NVIC_SetPriority(UART_1_IRQ_CHAN, UART_IRQ_PRIO); // Enable the UART interrupt NVIC_EnableIRQ(UART_1_IRQ_CHAN); break; #endif } return 0; } int uart_init_blocking(uart_t uart, uint32_t baudrate) { switch(uart){ #if UART_0_EN case UART_0: ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_UART0); ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA); ROM_GPIOPinConfigure(GPIO_PA0_U0RX); ROM_GPIOPinConfigure(GPIO_PA1_U0TX); ROM_GPIOPinTypeUART(GPIO_PORTA_BASE, GPIO_PIN_0 | GPIO_PIN_1); ROM_UARTDisable(UART0_BASE); ROM_UARTConfigSetExpClk(UART0_BASE,ROM_SysCtlClockGet(), baudrate, (UART_CONFIG_PAR_NONE | UART_CONFIG_STOP_ONE | UART_CONFIG_WLEN_8)); ROM_UARTEnable(UART0_BASE); break; #endif } return 0; } void uart_tx_begin(uart_t uart) { uart_write(uart, '\0'); UART0_IM_R |= UART_IM_TXIM; } int uart_write(uart_t uart, char data) { int ret=ROM_UARTCharPutNonBlocking(UART0_BASE, data); return ret; } int uart_read_blocking(uart_t uart, char *data) { *data = (char)ROM_UARTCharGet(UART0_BASE); return 1; } int uart_write_blocking(uart_t uart, char data) { ROM_UARTCharPut(UART0_BASE, data); return 1; } void uart_poweron(uart_t uart) { ROM_UARTEnable(UART0_BASE); } void uart_poweroff(uart_t uart) { ROM_UARTDisable(UART0_BASE); } //***************************************************************************** // // The UART interrupt handler. // //***************************************************************************** void isr_usart0(void) { unsigned long ulStatus; char cChar; long lChar; // Get the interrupt status ulStatus = ROM_UARTIntStatus(UART0_BASE, true); // Clear the asserted interrupts ROM_UARTIntClear(UART0_BASE, ulStatus); // Are we interrupted due to TX done if(ulStatus & UART_INT_TX) { if (config[UART_0].tx_cb(config[UART_0].arg) == 0){ UART0_IM_R &= ~UART_IM_TXIM; } } // Are we interrupted due to a recieved character if(ulStatus & (UART_INT_RX | UART_INT_RT)) { // Get all the available characters from the UART while(ROM_UARTCharsAvail(UART0_BASE)) { // Read a character lChar = ROM_UARTCharGetNonBlocking(UART0_BASE); cChar = (unsigned char)(lChar & 0xFF); config[UART_0].rx_cb(config[UART_0].arg, cChar); } } if (sched_context_switch_request) { thread_yield(); } } #endif /* (UART_0_EN || UART_1_EN) */