| /****************************************************************************** |
| * Filename: uart.c |
| * Revised: 2015-11-16 19:41:47 +0100 (Mon, 16 Nov 2015) |
| * Revision: 45094 |
| * |
| * Description: Driver for the UART. |
| * |
| * Copyright (c) 2015 - 2016, Texas Instruments Incorporated |
| * All rights reserved. |
| * |
| * Redistribution and use in source and binary forms, with or without |
| * modification, are permitted provided that the following conditions are met: |
| * |
| * 1) Redistributions of source code must retain the above copyright notice, |
| * this list of conditions and the following disclaimer. |
| * |
| * 2) Redistributions in binary form must reproduce the above copyright notice, |
| * this list of conditions and the following disclaimer in the documentation |
| * and/or other materials provided with the distribution. |
| * |
| * 3) Neither the name of the ORGANIZATION nor the names of its contributors may |
| * be used to endorse or promote products derived from this software without |
| * specific prior written permission. |
| * |
| * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
| * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
| * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
| * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE |
| * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
| * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
| * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
| * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
| * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
| * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
| * POSSIBILITY OF SUCH DAMAGE. |
| * |
| ******************************************************************************/ |
| |
| #include <driverlib/uart.h> |
| |
| //***************************************************************************** |
| // |
| // Handle support for DriverLib in ROM: |
| // This section will undo prototype renaming made in the header file |
| // |
| //***************************************************************************** |
| #if !defined(DOXYGEN) |
| #undef UARTFIFOLevelGet |
| #define UARTFIFOLevelGet NOROM_UARTFIFOLevelGet |
| #undef UARTConfigSetExpClk |
| #define UARTConfigSetExpClk NOROM_UARTConfigSetExpClk |
| #undef UARTConfigGetExpClk |
| #define UARTConfigGetExpClk NOROM_UARTConfigGetExpClk |
| #undef UARTDisable |
| #define UARTDisable NOROM_UARTDisable |
| #undef UARTCharGetNonBlocking |
| #define UARTCharGetNonBlocking NOROM_UARTCharGetNonBlocking |
| #undef UARTCharGet |
| #define UARTCharGet NOROM_UARTCharGet |
| #undef UARTCharPutNonBlocking |
| #define UARTCharPutNonBlocking NOROM_UARTCharPutNonBlocking |
| #undef UARTCharPut |
| #define UARTCharPut NOROM_UARTCharPut |
| #undef UARTIntRegister |
| #define UARTIntRegister NOROM_UARTIntRegister |
| #undef UARTIntUnregister |
| #define UARTIntUnregister NOROM_UARTIntUnregister |
| #endif |
| |
| //***************************************************************************** |
| // |
| //! Gets the FIFO level at which interrupts are generated |
| // |
| //***************************************************************************** |
| void |
| UARTFIFOLevelGet(uint32_t ui32Base, uint32_t *pui32TxLevel, |
| uint32_t *pui32RxLevel) |
| { |
| uint32_t ui32Temp; |
| |
| // |
| // Check the arguments. |
| // |
| ASSERT(UARTBaseValid(ui32Base)); |
| |
| // |
| // Read the FIFO level register. |
| // |
| ui32Temp = HWREG(ui32Base + UART_O_IFLS); |
| |
| // |
| // Extract the transmit and receive FIFO levels. |
| // |
| *pui32TxLevel = ui32Temp & UART_IFLS_TXSEL_M; |
| *pui32RxLevel = ui32Temp & UART_IFLS_RXSEL_M; |
| } |
| |
| //***************************************************************************** |
| // |
| //! Sets the configuration of a UART |
| // |
| //***************************************************************************** |
| void |
| UARTConfigSetExpClk(uint32_t ui32Base, uint32_t ui32UARTClk, |
| uint32_t ui32Baud, uint32_t ui32Config) |
| { |
| uint32_t ui32Div; |
| |
| // |
| // Check the arguments. |
| // |
| ASSERT(UARTBaseValid(ui32Base)); |
| ASSERT(ui32Baud != 0); |
| |
| // |
| // Stop the UART. |
| // |
| UARTDisable(ui32Base); |
| |
| // |
| // Compute the fractional baud rate divider. |
| // |
| ui32Div = (((ui32UARTClk * 8) / ui32Baud) + 1) / 2; |
| |
| // |
| // Set the baud rate. |
| // |
| HWREG(ui32Base + UART_O_IBRD) = ui32Div / 64; |
| HWREG(ui32Base + UART_O_FBRD) = ui32Div % 64; |
| |
| // |
| // Set parity, data length, and number of stop bits. |
| // |
| HWREG(ui32Base + UART_O_LCRH) = ui32Config; |
| } |
| |
| //***************************************************************************** |
| // |
| //! Gets the current configuration of a UART |
| // |
| //***************************************************************************** |
| void |
| UARTConfigGetExpClk(uint32_t ui32Base, uint32_t ui32UARTClk, |
| uint32_t *pui32Baud, uint32_t *pui32Config) |
| { |
| uint32_t ui32Int, ui32Frac; |
| |
| // |
| // Check the arguments. |
| // |
| ASSERT(UARTBaseValid(ui32Base)); |
| |
| // |
| // Compute the baud rate. |
| // |
| ui32Int = HWREG(ui32Base + UART_O_IBRD); |
| ui32Frac = HWREG(ui32Base + UART_O_FBRD); |
| *pui32Baud = (ui32UARTClk * 4) / ((64 * ui32Int) + ui32Frac); |
| |
| // |
| // Get the parity, data length, and number of stop bits. |
| // |
| *pui32Config = (HWREG(ui32Base + UART_O_LCRH) & |
| (UART_LCRH_SPS | UART_LCRH_WLEN_M | UART_LCRH_STP2 | |
| UART_LCRH_EPS | UART_LCRH_PEN)); |
| } |
| |
| //***************************************************************************** |
| // |
| //! Disables transmitting and receiving |
| // |
| //***************************************************************************** |
| void |
| UARTDisable(uint32_t ui32Base) |
| { |
| |
| // |
| // Check the arguments. |
| // |
| ASSERT(UARTBaseValid(ui32Base)); |
| |
| // |
| // Wait for end of TX. |
| // |
| while(HWREG(ui32Base + UART_O_FR) & UART_FR_BUSY) |
| { |
| } |
| |
| // |
| // Disable the FIFO. |
| // |
| HWREG(ui32Base + UART_O_LCRH) &= ~(UART_LCRH_FEN); |
| |
| // |
| // Disable the UART. |
| // |
| HWREG(ui32Base + UART_O_CTL) &= ~(UART_CTL_UARTEN | UART_CTL_TXE | |
| UART_CTL_RXE); |
| } |
| |
| //***************************************************************************** |
| // |
| //! Receives a character from the specified port |
| // |
| //***************************************************************************** |
| int32_t |
| UARTCharGetNonBlocking(uint32_t ui32Base) |
| { |
| // |
| // Check the arguments. |
| // |
| ASSERT(UARTBaseValid(ui32Base)); |
| |
| // |
| // See if there are any characters in the receive FIFO. |
| // |
| if(!(HWREG(ui32Base + UART_O_FR) & UART_FR_RXFE)) |
| { |
| // |
| // Read and return the next character. |
| // |
| return(HWREG(ui32Base + UART_O_DR)); |
| } |
| else |
| { |
| // |
| // There are no characters, so return a failure. |
| // |
| return(-1); |
| } |
| } |
| |
| //***************************************************************************** |
| // |
| //! Waits for a character from the specified port |
| // |
| //***************************************************************************** |
| int32_t |
| UARTCharGet(uint32_t ui32Base) |
| { |
| // |
| // Check the arguments. |
| // |
| ASSERT(UARTBaseValid(ui32Base)); |
| |
| // |
| // Wait until a char is available. |
| // |
| while(HWREG(ui32Base + UART_O_FR) & UART_FR_RXFE) |
| { |
| } |
| |
| // |
| // Now get the character. |
| // |
| return(HWREG(ui32Base + UART_O_DR)); |
| } |
| |
| //***************************************************************************** |
| // |
| //! Sends a character to the specified port |
| // |
| //***************************************************************************** |
| bool |
| UARTCharPutNonBlocking(uint32_t ui32Base, uint8_t ui8Data) |
| { |
| // |
| // Check the arguments. |
| // |
| ASSERT(UARTBaseValid(ui32Base)); |
| |
| // |
| // See if there is space in the transmit FIFO. |
| // |
| if(!(HWREG(ui32Base + UART_O_FR) & UART_FR_TXFF)) |
| { |
| // |
| // Write this character to the transmit FIFO. |
| // |
| HWREG(ui32Base + UART_O_DR) = ui8Data; |
| |
| // |
| // Success. |
| // |
| return(true); |
| } |
| else |
| { |
| // |
| // There is no space in the transmit FIFO, so return a failure. |
| // |
| return(false); |
| } |
| } |
| |
| //***************************************************************************** |
| // |
| //! Waits to send a character from the specified port |
| // |
| //***************************************************************************** |
| void |
| UARTCharPut(uint32_t ui32Base, uint8_t ui8Data) |
| { |
| // |
| // Check the arguments. |
| // |
| ASSERT(UARTBaseValid(ui32Base)); |
| |
| // |
| // Wait until space is available. |
| // |
| while(HWREG(ui32Base + UART_O_FR) & UART_FR_TXFF) |
| { |
| } |
| |
| // |
| // Send the char. |
| // |
| HWREG(ui32Base + UART_O_DR) = ui8Data; |
| } |
| |
| //***************************************************************************** |
| // |
| //! Registers an interrupt handler for a UART interrupt |
| // |
| //***************************************************************************** |
| void |
| UARTIntRegister(uint32_t ui32Base, void (*pfnHandler)(void)) |
| { |
| // |
| // Check the arguments. |
| // |
| ASSERT(UARTBaseValid(ui32Base)); |
| (void)ui32Base; |
| |
| // |
| // Register the interrupt handler. |
| // |
| IntRegister(INT_UART0_COMB, pfnHandler); |
| |
| // |
| // Enable the UART interrupt. |
| // |
| IntEnable(INT_UART0_COMB); |
| } |
| |
| //***************************************************************************** |
| // |
| //! Unregisters an interrupt handler for a UART interrupt |
| // |
| //***************************************************************************** |
| void |
| UARTIntUnregister(uint32_t ui32Base) |
| { |
| // |
| // Check the arguments. |
| // |
| ASSERT(UARTBaseValid(ui32Base)); |
| (void)ui32Base; |
| |
| // |
| // Disable the interrupt. |
| // |
| IntDisable(INT_UART0_COMB); |
| |
| // |
| // Unregister the interrupt handler. |
| // |
| IntUnregister(INT_UART0_COMB); |
| } |