Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
m480_uart.c
00001 /**************************************************************************//** 00002 * @file uart.c 00003 * @version V3.00 00004 * @brief M480 series UART driver source file 00005 * 00006 * @copyright (C) 2016 Nuvoton Technology Corp. All rights reserved. 00007 * 00008 * Redistribution and use in source and binary forms, with or without modification, 00009 * are permitted provided that the following conditions are met: 00010 * 1. Redistributions of source code must retain the above copyright notice, 00011 * this list of conditions and the following disclaimer. 00012 * 2. Redistributions in binary form must reproduce the above copyright notice, 00013 * this list of conditions and the following disclaimer in the documentation 00014 * and/or other materials provided with the distribution. 00015 * 3. Neither the name of Nuvoton Technology Corp. nor the names of its contributors 00016 * may be used to endorse or promote products derived from this software 00017 * without specific prior written permission. 00018 * 00019 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 00020 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 00021 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 00022 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 00023 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 00024 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 00025 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 00026 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 00027 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 00028 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00029 *****************************************************************************/ 00030 00031 #include <stdio.h> 00032 #include "NuMicro.h" 00033 00034 /** @addtogroup Standard_Driver Standard Driver 00035 @{ 00036 */ 00037 00038 /** @addtogroup UART_Driver UART Driver 00039 @{ 00040 */ 00041 00042 /** @addtogroup UART_EXPORTED_FUNCTIONS UART Exported Functions 00043 @{ 00044 */ 00045 00046 /** 00047 * @brief Clear UART specified interrupt flag 00048 * 00049 * @param[in] uart The pointer of the specified UART module. 00050 * @param[in] u32InterruptFlag The specified interrupt of UART module. 00051 * - \ref UART_INTSTS_LININT_Msk : LIN bus interrupt 00052 * - \ref UART_INTEN_WKIEN_Msk : Wake-up interrupt 00053 * - \ref UART_INTSTS_BUFERRINT_Msk : Buffer Error interrupt 00054 * - \ref UART_INTSTS_MODEMINT_Msk : Modem Status interrupt 00055 * - \ref UART_INTSTS_RLSINT_Msk : Receive Line Status interrupt 00056 * 00057 * @return None 00058 * 00059 * @details The function is used to clear UART specified interrupt flag. 00060 */ 00061 00062 void UART_ClearIntFlag(UART_T *uart, uint32_t u32InterruptFlag) 00063 { 00064 if (u32InterruptFlag & UART_INTSTS_RLSINT_Msk) { /* Clear Receive Line Status Interrupt */ 00065 uart->FIFOSTS = UART_FIFOSTS_BIF_Msk | UART_FIFOSTS_FEF_Msk | UART_FIFOSTS_PEF_Msk; 00066 uart->FIFOSTS = UART_FIFOSTS_ADDRDETF_Msk; 00067 } 00068 00069 if (u32InterruptFlag & UART_INTSTS_MODEMINT_Msk) { /* Clear Modem Status Interrupt */ 00070 uart->MODEMSTS |= UART_MODEMSTS_CTSDETF_Msk; 00071 } else { 00072 } 00073 00074 if (u32InterruptFlag & UART_INTSTS_BUFERRINT_Msk) { /* Clear Buffer Error Interrupt */ 00075 uart->FIFOSTS = UART_FIFOSTS_RXOVIF_Msk | UART_FIFOSTS_TXOVIF_Msk; 00076 } 00077 00078 if (u32InterruptFlag & UART_INTSTS_WKINT_Msk) { /* Clear Wake-up Interrupt */ 00079 uart->WKSTS = UART_WKSTS_CTSWKF_Msk | UART_WKSTS_DATWKF_Msk | 00080 UART_WKSTS_RFRTWKF_Msk | UART_WKSTS_RS485WKF_Msk | 00081 UART_WKSTS_TOUTWKF_Msk; 00082 } 00083 00084 if (u32InterruptFlag & UART_INTSTS_LININT_Msk) { /* Clear LIN Bus Interrupt */ 00085 uart->INTSTS = UART_INTSTS_LINIF_Msk; 00086 uart->LINSTS = UART_LINSTS_BITEF_Msk | UART_LINSTS_BRKDETF_Msk | 00087 UART_LINSTS_SLVSYNCF_Msk | UART_LINSTS_SLVIDPEF_Msk | 00088 UART_LINSTS_SLVHEF_Msk | UART_LINSTS_SLVHDETF_Msk ; 00089 } 00090 } 00091 00092 00093 /** 00094 * @brief Disable UART interrupt 00095 * 00096 * @param[in] uart The pointer of the specified UART module. 00097 * 00098 * @return None 00099 * 00100 * @details The function is used to disable UART interrupt. 00101 */ 00102 void UART_Close(UART_T *uart) 00103 { 00104 uart->INTEN = 0ul; 00105 } 00106 00107 00108 /** 00109 * @brief Disable UART auto flow control function 00110 * 00111 * @param[in] uart The pointer of the specified UART module. 00112 * 00113 * @return None 00114 * 00115 * @details The function is used to disable UART auto flow control. 00116 */ 00117 void UART_DisableFlowCtrl(UART_T *uart) 00118 { 00119 uart->INTEN &= ~(UART_INTEN_ATORTSEN_Msk | UART_INTEN_ATOCTSEN_Msk); 00120 } 00121 00122 00123 /** 00124 * @brief Disable UART specified interrupt 00125 * 00126 * @param[in] uart The pointer of the specified UART module. 00127 * @param[in] u32InterruptFlag The specified interrupt of UART module. 00128 * - \ref UART_INTEN_WKIEN_Msk : Wake-up interrupt 00129 * - \ref UART_INTEN_LINIEN_Msk : Lin bus interrupt 00130 * - \ref UART_INTEN_BUFERRIEN_Msk : Buffer Error interrupt 00131 * - \ref UART_INTEN_RXTOIEN_Msk : Rx time-out interrupt 00132 * - \ref UART_INTEN_MODEMIEN_Msk : Modem status interrupt 00133 * - \ref UART_INTEN_RLSIEN_Msk : Receive Line status interrupt 00134 * - \ref UART_INTEN_THREIEN_Msk : Tx empty interrupt 00135 * - \ref UART_INTEN_RDAIEN_Msk : Rx ready interrupt * 00136 * 00137 * @return None 00138 * 00139 * @details The function is used to disable UART specified interrupt and disable NVIC UART IRQ. 00140 */ 00141 void UART_DisableInt(UART_T *uart, uint32_t u32InterruptFlag) 00142 { 00143 /* Disable UART specified interrupt */ 00144 UART_DISABLE_INT(uart, u32InterruptFlag); 00145 } 00146 00147 00148 /** 00149 * @brief Enable UART auto flow control function 00150 * 00151 * @param[in] uart The pointer of the specified UART module. 00152 * 00153 * @return None 00154 * 00155 * @details The function is used to Enable UART auto flow control. 00156 */ 00157 void UART_EnableFlowCtrl(UART_T *uart) 00158 { 00159 /* Set RTS pin output is low level active */ 00160 uart->MODEM |= UART_MODEM_RTSACTLV_Msk; 00161 /* Set CTS pin input is low level active */ 00162 uart->MODEMSTS |= UART_MODEMSTS_CTSACTLV_Msk; 00163 /* Set RTS and CTS auto flow control enable */ 00164 uart->INTEN |= UART_INTEN_ATORTSEN_Msk | UART_INTEN_ATOCTSEN_Msk; 00165 } 00166 00167 00168 /** 00169 * @brief The function is used to enable UART specified interrupt and enable NVIC UART IRQ. 00170 * 00171 * @param[in] uart The pointer of the specified UART module. 00172 * @param[in] u32InterruptFlag The specified interrupt of UART module: 00173 * - \ref UART_INTEN_WKIEN_Msk : Wake-up interrupt 00174 * - \ref UART_INTEN_LINIEN_Msk : Lin bus interrupt 00175 * - \ref UART_INTEN_BUFERRIEN_Msk : Buffer Error interrupt 00176 * - \ref UART_INTEN_RXTOIEN_Msk : Rx time-out interrupt 00177 * - \ref UART_INTEN_MODEMIEN_Msk : Modem status interrupt 00178 * - \ref UART_INTEN_RLSIEN_Msk : Receive Line status interrupt 00179 * - \ref UART_INTEN_THREIEN_Msk : Tx empty interrupt 00180 * - \ref UART_INTEN_RDAIEN_Msk : Rx ready interrupt * 00181 * 00182 * @return None 00183 * 00184 * @details The function is used to enable UART specified interrupt and enable NVIC UART IRQ. 00185 */ 00186 void UART_EnableInt(UART_T *uart, uint32_t u32InterruptFlag) 00187 { 00188 /* Enable UART specified interrupt */ 00189 UART_ENABLE_INT(uart, u32InterruptFlag); 00190 } 00191 00192 00193 /** 00194 * @brief Open and set UART function 00195 * 00196 * @param[in] uart The pointer of the specified UART module. 00197 * @param[in] u32baudrate The baudrate of UART module. 00198 * 00199 * @return None 00200 * 00201 * @details This function use to enable UART function and set baud-rate. 00202 */ 00203 void UART_Open(UART_T *uart, uint32_t u32baudrate) 00204 { 00205 uint32_t u32UartClkSrcSel = 0ul, u32UartClkDivNum = 0ul; 00206 uint32_t u32ClkTbl[4] = {__HXT, 0ul, __LXT, __HIRC}; 00207 uint32_t u32Baud_Div = 0ul; 00208 00209 if (uart == (UART_T *)UART0) { 00210 /* Get UART clock source selection */ 00211 u32UartClkSrcSel = ((uint32_t)(CLK->CLKSEL1 & CLK_CLKSEL1_UART0SEL_Msk)) >> CLK_CLKSEL1_UART0SEL_Pos; 00212 /* Get UART clock divider number */ 00213 u32UartClkDivNum = (CLK->CLKDIV0 & CLK_CLKDIV0_UART0DIV_Msk) >> CLK_CLKDIV0_UART0DIV_Pos; 00214 } else if (uart == (UART_T *)UART1) { 00215 /* Get UART clock source selection */ 00216 u32UartClkSrcSel = (CLK->CLKSEL1 & CLK_CLKSEL1_UART1SEL_Msk) >> CLK_CLKSEL1_UART1SEL_Pos; 00217 /* Get UART clock divider number */ 00218 u32UartClkDivNum = (CLK->CLKDIV0 & CLK_CLKDIV0_UART1DIV_Msk) >> CLK_CLKDIV0_UART1DIV_Pos; 00219 } else if (uart == (UART_T *)UART2) { 00220 /* Get UART clock source selection */ 00221 u32UartClkSrcSel = (CLK->CLKSEL3 & CLK_CLKSEL3_UART2SEL_Msk) >> CLK_CLKSEL3_UART2SEL_Pos; 00222 /* Get UART clock divider number */ 00223 u32UartClkDivNum = (CLK->CLKDIV4 & CLK_CLKDIV4_UART2DIV_Msk) >> CLK_CLKDIV4_UART2DIV_Pos; 00224 } else if (uart == (UART_T *)UART3) { 00225 /* Get UART clock source selection */ 00226 u32UartClkSrcSel = (CLK->CLKSEL3 & CLK_CLKSEL3_UART3SEL_Msk) >> CLK_CLKSEL3_UART3SEL_Pos; 00227 /* Get UART clock divider number */ 00228 u32UartClkDivNum = (CLK->CLKDIV4 & CLK_CLKDIV4_UART3DIV_Msk) >> CLK_CLKDIV4_UART3DIV_Pos; 00229 } else if (uart == (UART_T *)UART4) { 00230 /* Get UART clock source selection */ 00231 u32UartClkSrcSel = (CLK->CLKSEL3 & CLK_CLKSEL3_UART4SEL_Msk) >> CLK_CLKSEL3_UART4SEL_Pos; 00232 /* Get UART clock divider number */ 00233 u32UartClkDivNum = (CLK->CLKDIV4 & CLK_CLKDIV4_UART4DIV_Msk) >> CLK_CLKDIV4_UART4DIV_Pos; 00234 } else if (uart == (UART_T *)UART5) { 00235 /* Get UART clock source selection */ 00236 u32UartClkSrcSel = (CLK->CLKSEL3 & CLK_CLKSEL3_UART5SEL_Msk) >> CLK_CLKSEL3_UART5SEL_Pos; 00237 /* Get UART clock divider number */ 00238 u32UartClkDivNum = (CLK->CLKDIV4 & CLK_CLKDIV4_UART5DIV_Msk) >> CLK_CLKDIV4_UART5DIV_Pos; 00239 } 00240 00241 /* Select UART function */ 00242 uart->FUNCSEL = UART_FUNCSEL_UART; 00243 /* Set UART line configuration */ 00244 uart->LINE = UART_WORD_LEN_8 | _UART_PARITY_NONE | UART_STOP_BIT_1; 00245 /* Set UART Rx and RTS trigger level */ 00246 uart->FIFO &= ~(UART_FIFO_RFITL_Msk | UART_FIFO_RTSTRGLV_Msk); 00247 00248 /* Get PLL clock frequency if UART clock source selection is PLL */ 00249 if (u32UartClkSrcSel == 1ul) { 00250 u32ClkTbl[u32UartClkSrcSel] = CLK_GetPLLClockFreq(); 00251 } 00252 00253 /* Set UART baud rate */ 00254 if (u32baudrate != 0ul) { 00255 u32Baud_Div = UART_BAUD_MODE2_DIVIDER((u32ClkTbl[u32UartClkSrcSel]) / (u32UartClkDivNum + 1ul), u32baudrate); 00256 00257 if (u32Baud_Div > 0xFFFFul) { 00258 uart->BAUD = (UART_BAUD_MODE0 | UART_BAUD_MODE0_DIVIDER((u32ClkTbl[u32UartClkSrcSel]) / (u32UartClkDivNum + 1ul), u32baudrate)); 00259 } else { 00260 uart->BAUD = (UART_BAUD_MODE2 | u32Baud_Div); 00261 } 00262 } 00263 } 00264 00265 00266 /** 00267 * @brief Read UART data 00268 * 00269 * @param[in] uart The pointer of the specified UART module. 00270 * @param[in] pu8RxBuf The buffer to receive the data of receive FIFO. 00271 * @param[in] u32ReadBytes The the read bytes number of data. 00272 * 00273 * @return u32Count Receive byte count 00274 * 00275 * @details The function is used to read Rx data from RX FIFO and the data will be stored in pu8RxBuf. 00276 */ 00277 uint32_t UART_Read(UART_T *uart, uint8_t pu8RxBuf[], uint32_t u32ReadBytes) 00278 { 00279 uint32_t u32Count, u32delayno; 00280 uint32_t u32Exit = 0ul; 00281 00282 for (u32Count = 0ul; u32Count < u32ReadBytes; u32Count++) { 00283 u32delayno = 0ul; 00284 00285 while (uart->FIFOSTS & UART_FIFOSTS_RXEMPTY_Msk) { /* Check RX empty => failed */ 00286 u32delayno++; 00287 00288 if (u32delayno >= 0x40000000ul) { 00289 u32Exit = 1ul; 00290 break; 00291 } else { 00292 } 00293 } 00294 00295 if (u32Exit == 1ul) { 00296 break; 00297 } else { 00298 pu8RxBuf[u32Count] = (uint8_t)uart->DAT; /* Get Data from UART RX */ 00299 } 00300 } 00301 00302 return u32Count; 00303 } 00304 00305 00306 /** 00307 * @brief Set UART line configuration 00308 * 00309 * @param[in] uart The pointer of the specified UART module. 00310 * @param[in] u32baudrate The register value of baudrate of UART module. 00311 * If u32baudrate = 0, UART baudrate will not change. 00312 * @param[in] u32data_width The data length of UART module. 00313 * - \ref UART_WORD_LEN_5 00314 * - \ref UART_WORD_LEN_6 00315 * - \ref UART_WORD_LEN_7 00316 * - \ref UART_WORD_LEN_8 00317 * @param[in] u32parity The parity setting (none/odd/even/mark/space) of UART module. 00318 * - \ref _UART_PARITY_NONE 00319 * - \ref _UART_PARITY_ODD 00320 * - \ref _UART_PARITY_EVEN 00321 * - \ref _UART_PARITY_MARK 00322 * - \ref _UART_PARITY_SPACE 00323 * @param[in] u32stop_bits The stop bit length (1/1.5/2 bit) of UART module. 00324 * - \ref UART_STOP_BIT_1 00325 * - \ref UART_STOP_BIT_1_5 00326 * - \ref UART_STOP_BIT_2 00327 * 00328 * @return None 00329 * 00330 * @details This function use to config UART line setting. 00331 */ 00332 void UART_SetLineConfig(UART_T *uart, uint32_t u32baudrate, uint32_t u32data_width, uint32_t u32parity, uint32_t u32stop_bits) 00333 { 00334 uint32_t u32UartClkSrcSel = 0ul, u32UartClkDivNum = 0ul; 00335 uint32_t u32ClkTbl[4ul] = {__HXT, 0ul, __LXT, __HIRC}; 00336 uint32_t u32Baud_Div = 0ul; 00337 00338 if (uart == (UART_T *)UART0) { 00339 /* Get UART clock source selection */ 00340 u32UartClkSrcSel = (CLK->CLKSEL1 & CLK_CLKSEL1_UART0SEL_Msk) >> CLK_CLKSEL1_UART0SEL_Pos; 00341 /* Get UART clock divider number */ 00342 u32UartClkDivNum = (CLK->CLKDIV0 & CLK_CLKDIV0_UART0DIV_Msk) >> CLK_CLKDIV0_UART0DIV_Pos; 00343 } else if (uart == (UART_T *)UART1) { 00344 /* Get UART clock source selection */ 00345 u32UartClkSrcSel = (CLK->CLKSEL1 & CLK_CLKSEL1_UART1SEL_Msk) >> CLK_CLKSEL1_UART1SEL_Pos; 00346 /* Get UART clock divider number */ 00347 u32UartClkDivNum = (CLK->CLKDIV0 & CLK_CLKDIV0_UART1DIV_Msk) >> CLK_CLKDIV0_UART1DIV_Pos; 00348 } else if (uart == (UART_T *)UART2) { 00349 /* Get UART clock source selection */ 00350 u32UartClkSrcSel = (CLK->CLKSEL3 & CLK_CLKSEL3_UART2SEL_Msk) >> CLK_CLKSEL3_UART2SEL_Pos; 00351 /* Get UART clock divider number */ 00352 u32UartClkDivNum = (CLK->CLKDIV4 & CLK_CLKDIV4_UART2DIV_Msk) >> CLK_CLKDIV4_UART2DIV_Pos; 00353 } else if (uart == (UART_T *)UART3) { 00354 /* Get UART clock source selection */ 00355 u32UartClkSrcSel = (CLK->CLKSEL3 & CLK_CLKSEL3_UART3SEL_Msk) >> CLK_CLKSEL3_UART3SEL_Pos; 00356 /* Get UART clock divider number */ 00357 u32UartClkDivNum = (CLK->CLKDIV4 & CLK_CLKDIV4_UART3DIV_Msk) >> CLK_CLKDIV4_UART3DIV_Pos; 00358 } else if (uart == (UART_T *)UART4) { 00359 /* Get UART clock source selection */ 00360 u32UartClkSrcSel = (CLK->CLKSEL3 & CLK_CLKSEL3_UART4SEL_Msk) >> CLK_CLKSEL3_UART4SEL_Pos; 00361 /* Get UART clock divider number */ 00362 u32UartClkDivNum = (CLK->CLKDIV4 & CLK_CLKDIV4_UART4DIV_Msk) >> CLK_CLKDIV4_UART4DIV_Pos; 00363 } else if (uart == (UART_T *)UART5) { 00364 /* Get UART clock source selection */ 00365 u32UartClkSrcSel = (CLK->CLKSEL3 & CLK_CLKSEL3_UART5SEL_Msk) >> CLK_CLKSEL3_UART5SEL_Pos; 00366 /* Get UART clock divider number */ 00367 u32UartClkDivNum = (CLK->CLKDIV4 & CLK_CLKDIV4_UART5DIV_Msk) >> CLK_CLKDIV4_UART5DIV_Pos; 00368 } 00369 00370 /* Get PLL clock frequency if UART clock source selection is PLL */ 00371 if (u32UartClkSrcSel == 1ul) { 00372 u32ClkTbl[u32UartClkSrcSel] = CLK_GetPLLClockFreq(); 00373 } else { 00374 } 00375 00376 /* Set UART baud rate */ 00377 if (u32baudrate != 0ul) { 00378 u32Baud_Div = UART_BAUD_MODE2_DIVIDER((u32ClkTbl[u32UartClkSrcSel]) / (u32UartClkDivNum + 1ul), u32baudrate); 00379 00380 if (u32Baud_Div > 0xFFFFul) { 00381 uart->BAUD = (UART_BAUD_MODE0 | UART_BAUD_MODE0_DIVIDER((u32ClkTbl[u32UartClkSrcSel]) / (u32UartClkDivNum + 1ul), u32baudrate)); 00382 } else { 00383 uart->BAUD = (UART_BAUD_MODE2 | u32Baud_Div); 00384 } 00385 } 00386 00387 /* Set UART line configuration */ 00388 uart->LINE = u32data_width | u32parity | u32stop_bits; 00389 } 00390 00391 00392 /** 00393 * @brief Set Rx timeout count 00394 * 00395 * @param[in] uart The pointer of the specified UART module. 00396 * @param[in] u32TOC Rx timeout counter. 00397 * 00398 * @return None 00399 * 00400 * @details This function use to set Rx timeout count. 00401 */ 00402 void UART_SetTimeoutCnt(UART_T *uart, uint32_t u32TOC) 00403 { 00404 /* Set time-out interrupt comparator */ 00405 uart->TOUT = (uart->TOUT & ~UART_TOUT_TOIC_Msk) | (u32TOC); 00406 /* Set time-out counter enable */ 00407 uart->INTEN |= UART_INTEN_TOCNTEN_Msk; 00408 } 00409 00410 00411 /** 00412 * @brief Select and configure IrDA function 00413 * 00414 * @param[in] uart The pointer of the specified UART module. 00415 * @param[in] u32Buadrate The baudrate of UART module. 00416 * @param[in] u32Direction The direction of UART module in IrDA mode: 00417 * - \ref UART_IRDA_TXEN 00418 * - \ref UART_IRDA_RXEN 00419 * 00420 * @return None 00421 * 00422 * @details The function is used to configure IrDA relative settings. It consists of TX or RX mode and baudrate. 00423 */ 00424 void UART_SelectIrDAMode(UART_T *uart, uint32_t u32Buadrate, uint32_t u32Direction) 00425 { 00426 uint32_t u32UartClkSrcSel = 0ul, u32UartClkDivNum = 0ul; 00427 uint32_t u32ClkTbl[4ul] = {__HXT, 0ul, __LXT, __HIRC}; 00428 uint32_t u32Baud_Div; 00429 /* Select IrDA function mode */ 00430 uart->FUNCSEL = UART_FUNCSEL_IrDA; 00431 00432 if (uart == UART0) { 00433 /* Get UART clock source selection */ 00434 u32UartClkSrcSel = (CLK->CLKSEL1 & CLK_CLKSEL1_UART0SEL_Msk) >> CLK_CLKSEL1_UART0SEL_Pos; 00435 /* Get UART clock divider number */ 00436 u32UartClkDivNum = (CLK->CLKDIV0 & CLK_CLKDIV0_UART0DIV_Msk) >> CLK_CLKDIV0_UART0DIV_Pos; 00437 } else if (uart == UART1) { 00438 /* Get UART clock source selection */ 00439 u32UartClkSrcSel = (CLK->CLKSEL1 & CLK_CLKSEL1_UART1SEL_Msk) >> CLK_CLKSEL1_UART1SEL_Pos; 00440 /* Get UART clock divider number */ 00441 u32UartClkDivNum = (CLK->CLKDIV0 & CLK_CLKDIV0_UART1DIV_Msk) >> CLK_CLKDIV0_UART1DIV_Pos; 00442 } else if (uart == UART2) { 00443 /* Get UART clock source selection */ 00444 u32UartClkSrcSel = (CLK->CLKSEL3 & CLK_CLKSEL3_UART2SEL_Msk) >> CLK_CLKSEL3_UART2SEL_Pos; 00445 /* Get UART clock divider number */ 00446 u32UartClkDivNum = (CLK->CLKDIV4 & CLK_CLKDIV4_UART2DIV_Msk) >> CLK_CLKDIV4_UART2DIV_Pos; 00447 } else if (uart == UART3) { 00448 /* Get UART clock source selection */ 00449 u32UartClkSrcSel = (CLK->CLKSEL3 & CLK_CLKSEL3_UART3SEL_Msk) >> CLK_CLKSEL3_UART3SEL_Pos; 00450 /* Get UART clock divider number */ 00451 u32UartClkDivNum = (CLK->CLKDIV4 & CLK_CLKDIV4_UART3DIV_Msk) >> CLK_CLKDIV4_UART3DIV_Pos; 00452 } else if (uart == UART4) { 00453 /* Get UART clock source selection */ 00454 u32UartClkSrcSel = (CLK->CLKSEL3 & CLK_CLKSEL3_UART4SEL_Msk) >> CLK_CLKSEL3_UART4SEL_Pos; 00455 /* Get UART clock divider number */ 00456 u32UartClkDivNum = (CLK->CLKDIV4 & CLK_CLKDIV4_UART4DIV_Msk) >> CLK_CLKDIV4_UART4DIV_Pos; 00457 } else if (uart == UART5) { 00458 /* Get UART clock source selection */ 00459 u32UartClkSrcSel = (CLK->CLKSEL3 & CLK_CLKSEL3_UART5SEL_Msk) >> CLK_CLKSEL3_UART5SEL_Pos; 00460 /* Get UART clock divider number */ 00461 u32UartClkDivNum = (CLK->CLKDIV4 & CLK_CLKDIV4_UART5DIV_Msk) >> CLK_CLKDIV4_UART5DIV_Pos; 00462 } 00463 00464 /* Get PLL clock frequency if UART clock source selection is PLL */ 00465 if (u32UartClkSrcSel == 1ul) { 00466 u32ClkTbl[u32UartClkSrcSel] = CLK_GetPLLClockFreq(); 00467 } else { 00468 } 00469 00470 /* Set UART IrDA baud rate in mode 0 */ 00471 if (u32Buadrate != 0ul) { 00472 u32Baud_Div = UART_BAUD_MODE0_DIVIDER((u32ClkTbl[u32UartClkSrcSel]) / (u32UartClkDivNum + 1ul), u32Buadrate); 00473 00474 if (u32Baud_Div < 0xFFFFul) { 00475 uart->BAUD = (UART_BAUD_MODE0 | u32Baud_Div); 00476 } else { 00477 } 00478 } 00479 00480 /* Configure IrDA relative settings */ 00481 if (u32Direction == UART_IRDA_RXEN) { 00482 uart->IRDA |= UART_IRDA_RXINV_Msk; /*Rx signal is inverse*/ 00483 uart->IRDA &= ~UART_IRDA_TXEN_Msk; 00484 } else { 00485 uart->IRDA &= ~UART_IRDA_TXINV_Msk; /*Tx signal is not inverse*/ 00486 uart->IRDA |= UART_IRDA_TXEN_Msk; 00487 } 00488 } 00489 00490 00491 /** 00492 * @brief Select and configure RS485 function 00493 * 00494 * @param[in] uart The pointer of the specified UART module. 00495 * @param[in] u32Mode The operation mode(NMM/AUD/AAD). 00496 * - \ref UART_ALTCTL_RS485NMM_Msk 00497 * - \ref UART_ALTCTL_RS485AUD_Msk 00498 * - \ref UART_ALTCTL_RS485AAD_Msk 00499 * @param[in] u32Addr The RS485 address. 00500 * 00501 * @return None 00502 * 00503 * @details The function is used to set RS485 relative setting. 00504 */ 00505 void UART_SelectRS485Mode(UART_T *uart, uint32_t u32Mode, uint32_t u32Addr) 00506 { 00507 /* Select UART RS485 function mode */ 00508 uart->FUNCSEL = UART_FUNCSEL_RS485; 00509 /* Set RS585 configuration */ 00510 uart->ALTCTL &= ~(UART_ALTCTL_RS485NMM_Msk | UART_ALTCTL_RS485AUD_Msk | UART_ALTCTL_RS485AAD_Msk | UART_ALTCTL_ADDRMV_Msk); 00511 uart->ALTCTL |= (u32Mode | (u32Addr << UART_ALTCTL_ADDRMV_Pos)); 00512 } 00513 00514 00515 /** 00516 * @brief Select and configure LIN function 00517 * 00518 * @param[in] uart The pointer of the specified UART module. 00519 * @param[in] u32Mode The LIN direction : 00520 * - \ref UART_ALTCTL_LINTXEN_Msk 00521 * - \ref UART_ALTCTL_LINRXEN_Msk 00522 * @param[in] u32BreakLength The break field length. 00523 * 00524 * @return None 00525 * 00526 * @details The function is used to set LIN relative setting. 00527 */ 00528 void UART_SelectLINMode(UART_T *uart, uint32_t u32Mode, uint32_t u32BreakLength) 00529 { 00530 /* Select LIN function mode */ 00531 uart->FUNCSEL = UART_FUNCSEL_LIN; 00532 /* Select LIN function setting : Tx enable, Rx enable and break field length */ 00533 uart->ALTCTL &= ~(UART_ALTCTL_LINTXEN_Msk | UART_ALTCTL_LINRXEN_Msk | UART_ALTCTL_BRKFL_Msk); 00534 uart->ALTCTL |= (u32Mode | (u32BreakLength << UART_ALTCTL_BRKFL_Pos)); 00535 } 00536 00537 00538 /** 00539 * @brief Write UART data 00540 * 00541 * @param[in] uart The pointer of the specified UART module. 00542 * @param[in] pu8TxBuf The buffer to send the data to UART transmission FIFO. 00543 * @param[out] u32WriteBytes The byte number of data. 00544 * 00545 * @return u32Count transfer byte count 00546 * 00547 * @details The function is to write data into TX buffer to transmit data by UART. 00548 */ 00549 uint32_t UART_Write(UART_T *uart, uint8_t pu8TxBuf[], uint32_t u32WriteBytes) 00550 { 00551 uint32_t u32Count, u32delayno; 00552 uint32_t u32Exit = 0ul; 00553 00554 for (u32Count = 0ul; u32Count != u32WriteBytes; u32Count++) { 00555 u32delayno = 0ul; 00556 00557 while (uart->FIFOSTS & UART_FIFOSTS_TXFULL_Msk) { /* Check Tx Full */ 00558 u32delayno++; 00559 00560 if (u32delayno >= 0x40000000ul) { 00561 u32Exit = 1ul; 00562 break; 00563 } else { 00564 } 00565 } 00566 00567 if (u32Exit == 1ul) { 00568 break; 00569 } else { 00570 uart->DAT = pu8TxBuf[u32Count]; /* Send UART Data from buffer */ 00571 } 00572 } 00573 00574 return u32Count; 00575 } 00576 00577 00578 /*@}*/ /* end of group UART_EXPORTED_FUNCTIONS */ 00579 00580 /*@}*/ /* end of group UART_Driver */ 00581 00582 /*@}*/ /* end of group Standard_Driver */ 00583 00584 /*** (C) COPYRIGHT 2016 Nuvoton Technology Corp. ***/ 00585 00586 00587
Generated on Tue Jul 12 2022 15:37:20 by
1.7.2