//########################################################################### // // FILE: uart.c // // TITLE: CM UARTdriver. // //########################################################################### // $TI Release: F2838x Support Library v3.04.00.00 $ // $Release Date: Fri Feb 12 19:08:49 IST 2021 $ // $Copyright: // Copyright (C) 2021 Texas Instruments Incorporated - http://www.ti.com/ // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions // are met: // // Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // // 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. // // Neither the name of Texas Instruments Incorporated 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 // OWNER 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 #include #include "inc/hw_memmap.h" #include "inc/hw_types.h" #include "inc/hw_uart.h" #include "debug.h" #include "interrupt.h" #include "uart.h" //***************************************************************************** // // API Function prototypes // //***************************************************************************** //***************************************************************************** // // UART_setConfig() // //***************************************************************************** void UART_setConfig(uint32_t base, uint32_t uartClk, uint32_t baud, uint32_t config) { uint32_t div, baudrt; baudrt = baud; // // Check the arguments. // ASSERT(UART_isBaseValid(base)); ASSERT(baudrt != 0U); ASSERT(uartClk >= (baudrt * UART_CLK_DIVIDER)); // // Stop the UART. // UART_disableModule(base); // // Is the required baud rate greater than the maximum rate supported // without the use of high speed mode? // if((baudrt * 16U) > uartClk) { // // Enable high speed mode. // HWREG(base + UART_O_CTL) |= UART_CTL_HSE; // // Half the supplied baud rate to compensate for enabling high speed // mode. This allows the following code to be common to both cases. // baudrt /= 2U; } else { // // Disable high speed mode. // HWREG(base + UART_O_CTL) &= ~(UART_CTL_HSE); } // // Compute the fractional baud rate divider. // div = (((uartClk * 8U) / baudrt) + 1U) / 2U; // // Set the baud rate. // HWREG(base + UART_O_IBRD) = div / 64U; HWREG(base + UART_O_FBRD) = div % 64U; // // Set parity, data length, and number of stop bits. // HWREG(base + UART_O_LCRH) = config; // // Start the UART. // UART_enableModule(base); } //***************************************************************************** // // UART_getConfig() // //***************************************************************************** void UART_getConfig(uint32_t base, uint32_t uartClk, uint32_t *baud, uint32_t *config) { uint32_t integr, frac; // // Check the arguments. // ASSERT(UART_isBaseValid(base)); // // Compute the baud rate. // integr = HWREG(base + UART_O_IBRD); frac = HWREG(base + UART_O_FBRD); *baud = (uartClk * 4U) / ((64U * integr) + frac); // // See if high speed mode enabled. // if((HWREG(base + UART_O_CTL) & UART_CTL_HSE) == UART_CTL_HSE) { // // High speed mode is enabled so the actual baud rate is actually // double what was just calculated. // *baud *= 2U; } // // Get the parity, data length, and number of stop bits. // *config = (HWREG(base + UART_O_LCRH) & (UART_LCRH_SPS | UART_LCRH_WLEN_M | UART_LCRH_STP2 | UART_LCRH_EPS | UART_LCRH_PEN)); } //***************************************************************************** // // UART_writeCharNonBlocking() // //***************************************************************************** bool UART_writeCharNonBlocking(uint32_t base, uint8_t data) { bool ret; // // Check the arguments. // ASSERT(UART_isBaseValid(base)); // // See if there is space in the transmit FIFO. // if((HWREG(base + UART_O_FR) & UART_FR_TXFF) == 0U) { // // Write this character to the transmit FIFO. // HWREG(base + UART_O_DR) = data; // // Success. // ret = true; } else { // // There is no space in the transmit FIFO, so return a failure. // ret = false; } return(ret); } //***************************************************************************** // // UART_send9BitAddress() // //***************************************************************************** void UART_send9BitAddress(uint32_t base, uint8_t addr) { uint32_t lcrh; // // Check the arguments. // ASSERT(UART_isBaseValid(base)); // // Wait until the FIFO is empty and the UART is not busy. // while((HWREG(base + UART_O_FR) & (UART_FR_TXFE | UART_FR_BUSY)) != UART_FR_TXFE) { } // // Force the address/data bit to 1 to indicate this is an address byte. // lcrh = HWREG(base + UART_O_LCRH); HWREG(base + UART_O_LCRH) = ((lcrh & ~UART_LCRH_EPS) | UART_LCRH_SPS | UART_LCRH_PEN); // // Send the address. // HWREG(base + UART_O_DR) = addr; // // Wait until the address has been sent. // while((HWREG(base + UART_O_FR) & (UART_FR_TXFE | UART_FR_BUSY)) != UART_FR_TXFE) { } // // Restore the address/data setting. // HWREG(base + UART_O_LCRH) = lcrh; } //***************************************************************************** // // UART_stop9BitDataMode() // //***************************************************************************** void UART_stop9BitDataMode(uint32_t base, uint32_t lcrh) { // // Check the arguments. // ASSERT(UART_isBaseValid(base)); // // Wait until the FIFO is empty and the UART is not busy. // while((HWREG(base + UART_O_FR) & (UART_FR_TXFE | UART_FR_BUSY)) != UART_FR_TXFE) { } // // Restore the address/data setting to enter normal transmission mode. // HWREG(base + UART_O_LCRH) = lcrh; } //***************************************************************************** // // UART_configure9BitDataMode() // //***************************************************************************** uint32_t UART_configure9BitDataMode(uint32_t base) { uint32_t lcrh; // // Check the arguments. // ASSERT(UART_isBaseValid(base)); // // Wait until the FIFO is empty and the UART is not busy. // while((HWREG(base + UART_O_FR) & (UART_FR_TXFE | UART_FR_BUSY)) != UART_FR_TXFE) { } // // Force the address/data bit to 0 to indicate this is an data byte. // lcrh = HWREG(base + UART_O_LCRH); HWREG(base + UART_O_LCRH) = (lcrh | UART_LCRH_EPS | UART_LCRH_SPS | UART_LCRH_PEN); // // Needed to restore the address/data setting after the full // 9-bit data transmission. // return(lcrh); }