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.
fsl_uart.c
00001 /* 00002 * Copyright (c) 2015-2016, Freescale Semiconductor, Inc. 00003 * Copyright 2016-2017 NXP 00004 * All rights reserved. 00005 * 00006 * SPDX-License-Identifier: BSD-3-Clause 00007 */ 00008 00009 #include "fsl_uart.h" 00010 #include "fsl_clock.h " 00011 00012 /******************************************************************************* 00013 * Definitions 00014 ******************************************************************************/ 00015 00016 /* Component ID definition, used by tools. */ 00017 #ifndef FSL_COMPONENT_ID 00018 #define FSL_COMPONENT_ID "platform.drivers.uart" 00019 #endif 00020 00021 /* UART transfer state. */ 00022 enum _uart_tansfer_states 00023 { 00024 kUART_TxIdle, /* TX idle. */ 00025 kUART_TxBusy, /* TX busy. */ 00026 kUART_RxIdle, /* RX idle. */ 00027 kUART_RxBusy, /* RX busy. */ 00028 kUART_RxFramingError, /* Rx framing error */ 00029 kUART_RxParityError /* Rx parity error */ 00030 }; 00031 00032 /* Typedef for interrupt handler. */ 00033 typedef void (*uart_isr_t)(UART_Type *base, uart_handle_t *handle); 00034 00035 /******************************************************************************* 00036 * Prototypes 00037 ******************************************************************************/ 00038 /*! 00039 * @brief Check whether the RX ring buffer is full. 00040 * 00041 * @param handle UART handle pointer. 00042 * @retval true RX ring buffer is full. 00043 * @retval false RX ring buffer is not full. 00044 */ 00045 static bool UART_TransferIsRxRingBufferFull(uart_handle_t *handle); 00046 00047 /*! 00048 * @brief Read RX register using non-blocking method. 00049 * 00050 * This function reads data from the TX register directly, upper layer must make 00051 * sure the RX register is full or TX FIFO has data before calling this function. 00052 * 00053 * @param base UART peripheral base address. 00054 * @param data Start addresss of the buffer to store the received data. 00055 * @param length Size of the buffer. 00056 */ 00057 static void UART_ReadNonBlocking(UART_Type *base, uint8_t *data, size_t length); 00058 00059 /*! 00060 * @brief Write to TX register using non-blocking method. 00061 * 00062 * This function writes data to the TX register directly, upper layer must make 00063 * sure the TX register is empty or TX FIFO has empty room before calling this function. 00064 * 00065 * @note This function does not check whether all the data has been sent out to bus, 00066 * so before disable TX, check kUART_TransmissionCompleteFlag to ensure the TX is 00067 * finished. 00068 * 00069 * @param base UART peripheral base address. 00070 * @param data Start address of the data to write. 00071 * @param length Size of the buffer to be sent. 00072 */ 00073 static void UART_WriteNonBlocking(UART_Type *base, const uint8_t *data, size_t length); 00074 00075 /******************************************************************************* 00076 * Variables 00077 ******************************************************************************/ 00078 /* Array of UART handle. */ 00079 #if (defined(UART5)) 00080 #define UART_HANDLE_ARRAY_SIZE 6 00081 #else /* UART5 */ 00082 #if (defined(UART4)) 00083 #define UART_HANDLE_ARRAY_SIZE 5 00084 #else /* UART4 */ 00085 #if (defined(UART3)) 00086 #define UART_HANDLE_ARRAY_SIZE 4 00087 #else /* UART3 */ 00088 #if (defined(UART2)) 00089 #define UART_HANDLE_ARRAY_SIZE 3 00090 #else /* UART2 */ 00091 #if (defined(UART1)) 00092 #define UART_HANDLE_ARRAY_SIZE 2 00093 #else /* UART1 */ 00094 #if (defined(UART0)) 00095 #define UART_HANDLE_ARRAY_SIZE 1 00096 #else /* UART0 */ 00097 #error No UART instance. 00098 #endif /* UART 0 */ 00099 #endif /* UART 1 */ 00100 #endif /* UART 2 */ 00101 #endif /* UART 3 */ 00102 #endif /* UART 4 */ 00103 #endif /* UART 5 */ 00104 static uart_handle_t *s_uartHandle[UART_HANDLE_ARRAY_SIZE]; 00105 /* Array of UART peripheral base address. */ 00106 static UART_Type *const s_uartBases[] = UART_BASE_PTRS; 00107 00108 /* Array of UART IRQ number. */ 00109 static const IRQn_Type s_uartIRQ[] = UART_RX_TX_IRQS; 00110 #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) 00111 /* Array of UART clock name. */ 00112 static const clock_ip_name_t s_uartClock[] = UART_CLOCKS; 00113 #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ 00114 00115 /* UART ISR for transactional APIs. */ 00116 static uart_isr_t s_uartIsr; 00117 00118 /******************************************************************************* 00119 * Code 00120 ******************************************************************************/ 00121 00122 /*! 00123 * brief Get the UART instance from peripheral base address. 00124 * 00125 * param base UART peripheral base address. 00126 * return UART instance. 00127 */ 00128 uint32_t UART_GetInstance(UART_Type *base) 00129 { 00130 uint32_t instance; 00131 uint32_t uartArrayCount = (sizeof(s_uartBases) / sizeof(s_uartBases[0])); 00132 00133 /* Find the instance index from base address mappings. */ 00134 for (instance = 0; instance < uartArrayCount; instance++) 00135 { 00136 if (s_uartBases[instance] == base) 00137 { 00138 break; 00139 } 00140 } 00141 00142 assert(instance < uartArrayCount); 00143 00144 return instance; 00145 } 00146 00147 /*! 00148 * brief Get the length of received data in RX ring buffer. 00149 * 00150 * param handle UART handle pointer. 00151 * return Length of received data in RX ring buffer. 00152 */ 00153 size_t UART_TransferGetRxRingBufferLength(uart_handle_t *handle) 00154 { 00155 assert(handle); 00156 00157 size_t size; 00158 00159 if (handle->rxRingBufferTail > handle->rxRingBufferHead ) 00160 { 00161 size = (size_t)(handle->rxRingBufferHead + handle->rxRingBufferSize - handle->rxRingBufferTail ); 00162 } 00163 else 00164 { 00165 size = (size_t)(handle->rxRingBufferHead - handle->rxRingBufferTail ); 00166 } 00167 00168 return size; 00169 } 00170 00171 static bool UART_TransferIsRxRingBufferFull(uart_handle_t *handle) 00172 { 00173 assert(handle); 00174 00175 bool full; 00176 00177 if (UART_TransferGetRxRingBufferLength(handle) == (handle->rxRingBufferSize - 1U)) 00178 { 00179 full = true; 00180 } 00181 else 00182 { 00183 full = false; 00184 } 00185 00186 return full; 00187 } 00188 00189 /*! 00190 * brief Initializes a UART instance with a user configuration structure and peripheral clock. 00191 * 00192 * This function configures the UART module with the user-defined settings. The user can configure the configuration 00193 * structure and also get the default configuration by using the UART_GetDefaultConfig() function. 00194 * The example below shows how to use this API to configure UART. 00195 * code 00196 * uart_config_t uartConfig; 00197 * uartConfig.baudRate_Bps = 115200U; 00198 * uartConfig.parityMode = kUART_ParityDisabled; 00199 * uartConfig.stopBitCount = kUART_OneStopBit; 00200 * uartConfig.txFifoWatermark = 0; 00201 * uartConfig.rxFifoWatermark = 1; 00202 * UART_Init(UART1, &uartConfig, 20000000U); 00203 * endcode 00204 * 00205 * param base UART peripheral base address. 00206 * param config Pointer to the user-defined configuration structure. 00207 * param srcClock_Hz UART clock source frequency in HZ. 00208 * retval kStatus_UART_BaudrateNotSupport Baudrate is not support in current clock source. 00209 * retval kStatus_Success Status UART initialize succeed 00210 */ 00211 status_t UART_Init(UART_Type *base, const uart_config_t *config, uint32_t srcClock_Hz) 00212 { 00213 assert(config); 00214 assert(config->baudRate_Bps ); 00215 #if defined(FSL_FEATURE_UART_HAS_FIFO) && FSL_FEATURE_UART_HAS_FIFO 00216 assert(FSL_FEATURE_UART_FIFO_SIZEn(base) >= config->txFifoWatermark ); 00217 assert(FSL_FEATURE_UART_FIFO_SIZEn(base) >= config->rxFifoWatermark ); 00218 #endif 00219 00220 uint16_t sbr = 0; 00221 uint8_t temp = 0; 00222 uint32_t baudDiff = 0; 00223 00224 /* Calculate the baud rate modulo divisor, sbr*/ 00225 sbr = srcClock_Hz / (config->baudRate_Bps * 16); 00226 /* set sbrTemp to 1 if the sourceClockInHz can not satisfy the desired baud rate */ 00227 if (sbr == 0) 00228 { 00229 sbr = 1; 00230 } 00231 #if defined(FSL_FEATURE_UART_HAS_BAUD_RATE_FINE_ADJUST_SUPPORT) && FSL_FEATURE_UART_HAS_BAUD_RATE_FINE_ADJUST_SUPPORT 00232 /* Determine if a fractional divider is needed to fine tune closer to the 00233 * desired baud, each value of brfa is in 1/32 increments, 00234 * hence the multiply-by-32. */ 00235 uint32_t tempBaud = 0; 00236 00237 uint16_t brfa = (2 * srcClock_Hz / (config->baudRate_Bps )) - 32 * sbr; 00238 00239 /* Calculate the baud rate based on the temporary SBR values and BRFA */ 00240 tempBaud = (srcClock_Hz * 2 / ((sbr * 32 + brfa))); 00241 baudDiff = 00242 (tempBaud > config->baudRate_Bps ) ? (tempBaud - config->baudRate_Bps ) : (config->baudRate_Bps - tempBaud); 00243 00244 #else 00245 /* Calculate the baud rate based on the temporary SBR values */ 00246 baudDiff = (srcClock_Hz / (sbr * 16)) - config->baudRate_Bps ; 00247 00248 /* Select the better value between sbr and (sbr + 1) */ 00249 if (baudDiff > (config->baudRate_Bps - (srcClock_Hz / (16 * (sbr + 1))))) 00250 { 00251 baudDiff = config->baudRate_Bps - (srcClock_Hz / (16 * (sbr + 1))); 00252 sbr++; 00253 } 00254 #endif 00255 00256 /* next, check to see if actual baud rate is within 3% of desired baud rate 00257 * based on the calculate SBR value */ 00258 if (baudDiff > ((config->baudRate_Bps / 100) * 3)) 00259 { 00260 /* Unacceptable baud rate difference of more than 3%*/ 00261 return kStatus_UART_BaudrateNotSupport ; 00262 } 00263 00264 #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) 00265 /* Enable uart clock */ 00266 CLOCK_EnableClock(s_uartClock[UART_GetInstance(base)]); 00267 #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ 00268 00269 /* Disable UART TX RX before setting. */ 00270 base->C2 &= ~(UART_C2_TE_MASK | UART_C2_RE_MASK); 00271 00272 /* Write the sbr value to the BDH and BDL registers*/ 00273 base->BDH = (base->BDH & ~UART_BDH_SBR_MASK) | (uint8_t)(sbr >> 8); 00274 base->BDL = (uint8_t)sbr; 00275 00276 #if defined(FSL_FEATURE_UART_HAS_BAUD_RATE_FINE_ADJUST_SUPPORT) && FSL_FEATURE_UART_HAS_BAUD_RATE_FINE_ADJUST_SUPPORT 00277 /* Write the brfa value to the register*/ 00278 base->C4 = (base->C4 & ~UART_C4_BRFA_MASK) | (brfa & UART_C4_BRFA_MASK); 00279 #endif 00280 00281 /* Set bit count/parity mode/idle type. */ 00282 temp = base->C1 & ~(UART_C1_PE_MASK | UART_C1_PT_MASK | UART_C1_M_MASK | UART_C1_ILT_MASK); 00283 00284 temp |= UART_C1_ILT(config->idleType ); 00285 00286 if (kUART_ParityDisabled != config->parityMode ) 00287 { 00288 temp |= (UART_C1_M_MASK | (uint8_t)config->parityMode ); 00289 } 00290 00291 base->C1 = temp; 00292 00293 #if defined(FSL_FEATURE_UART_HAS_STOP_BIT_CONFIG_SUPPORT) && FSL_FEATURE_UART_HAS_STOP_BIT_CONFIG_SUPPORT 00294 /* Set stop bit per char */ 00295 base->BDH = (base->BDH & ~UART_BDH_SBNS_MASK) | UART_BDH_SBNS((uint8_t)config->stopBitCount ); 00296 #endif 00297 00298 #if defined(FSL_FEATURE_UART_HAS_FIFO) && FSL_FEATURE_UART_HAS_FIFO 00299 /* Set tx/rx FIFO watermark 00300 Note: 00301 Take care of the RX FIFO, RX interrupt request only assert when received bytes 00302 equal or more than RX water mark, there is potential issue if RX water 00303 mark larger than 1. 00304 For example, if RX FIFO water mark is 2, upper layer needs 5 bytes and 00305 5 bytes are received. the last byte will be saved in FIFO but not trigger 00306 RX interrupt because the water mark is 2. 00307 */ 00308 base->TWFIFO = config->txFifoWatermark ; 00309 base->RWFIFO = config->rxFifoWatermark ; 00310 00311 /* Enable tx/rx FIFO */ 00312 base->PFIFO |= (UART_PFIFO_TXFE_MASK | UART_PFIFO_RXFE_MASK); 00313 00314 /* Flush FIFO */ 00315 base->CFIFO |= (UART_CFIFO_TXFLUSH_MASK | UART_CFIFO_RXFLUSH_MASK); 00316 #endif 00317 #if defined(FSL_FEATURE_UART_HAS_MODEM_SUPPORT) && FSL_FEATURE_UART_HAS_MODEM_SUPPORT 00318 if (config->enableRxRTS ) 00319 { 00320 /* Enable receiver RTS(request-to-send) function. */ 00321 base->MODEM |= UART_MODEM_RXRTSE_MASK; 00322 } 00323 if (config->enableTxCTS ) 00324 { 00325 /* Enable transmitter CTS(clear-to-send) function. */ 00326 base->MODEM |= UART_MODEM_TXCTSE_MASK; 00327 } 00328 #endif 00329 00330 /* Enable TX/RX base on configure structure. */ 00331 temp = base->C2; 00332 00333 if (config->enableTx ) 00334 { 00335 temp |= UART_C2_TE_MASK; 00336 } 00337 00338 if (config->enableRx ) 00339 { 00340 temp |= UART_C2_RE_MASK; 00341 } 00342 00343 base->C2 = temp; 00344 00345 return kStatus_Success; 00346 } 00347 00348 /*! 00349 * brief Deinitializes a UART instance. 00350 * 00351 * This function waits for TX complete, disables TX and RX, and disables the UART clock. 00352 * 00353 * param base UART peripheral base address. 00354 */ 00355 void UART_Deinit(UART_Type *base) 00356 { 00357 #if defined(FSL_FEATURE_UART_HAS_FIFO) && FSL_FEATURE_UART_HAS_FIFO 00358 /* Wait tx FIFO send out*/ 00359 while (0 != base->TCFIFO) 00360 { 00361 } 00362 #endif 00363 /* Wait last char shoft out */ 00364 while (0 == (base->S1 & UART_S1_TC_MASK)) 00365 { 00366 } 00367 00368 /* Disable the module. */ 00369 base->C2 = 0; 00370 00371 #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) 00372 /* Disable uart clock */ 00373 CLOCK_DisableClock(s_uartClock[UART_GetInstance(base)]); 00374 #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ 00375 } 00376 00377 /*! 00378 * brief Gets the default configuration structure. 00379 * 00380 * This function initializes the UART configuration structure to a default value. The default 00381 * values are as follows. 00382 * uartConfig->baudRate_Bps = 115200U; 00383 * uartConfig->bitCountPerChar = kUART_8BitsPerChar; 00384 * uartConfig->parityMode = kUART_ParityDisabled; 00385 * uartConfig->stopBitCount = kUART_OneStopBit; 00386 * uartConfig->txFifoWatermark = 0; 00387 * uartConfig->rxFifoWatermark = 1; 00388 * uartConfig->idleType = kUART_IdleTypeStartBit; 00389 * uartConfig->enableTx = false; 00390 * uartConfig->enableRx = false; 00391 * 00392 * param config Pointer to configuration structure. 00393 */ 00394 void UART_GetDefaultConfig(uart_config_t *config) 00395 { 00396 assert(config); 00397 00398 /* Initializes the configure structure to zero. */ 00399 memset(config, 0, sizeof(*config)); 00400 00401 config->baudRate_Bps = 115200U; 00402 config->parityMode = kUART_ParityDisabled ; 00403 #if defined(FSL_FEATURE_UART_HAS_STOP_BIT_CONFIG_SUPPORT) && FSL_FEATURE_UART_HAS_STOP_BIT_CONFIG_SUPPORT 00404 config->stopBitCount = kUART_OneStopBit ; 00405 #endif 00406 #if defined(FSL_FEATURE_UART_HAS_FIFO) && FSL_FEATURE_UART_HAS_FIFO 00407 config->txFifoWatermark = 0; 00408 config->rxFifoWatermark = 1; 00409 #endif 00410 #if defined(FSL_FEATURE_UART_HAS_MODEM_SUPPORT) && FSL_FEATURE_UART_HAS_MODEM_SUPPORT 00411 config->enableRxRTS = false; 00412 config->enableTxCTS = false; 00413 #endif 00414 config->idleType = kUART_IdleTypeStartBit ; 00415 config->enableTx = false; 00416 config->enableRx = false; 00417 } 00418 00419 /*! 00420 * brief Sets the UART instance baud rate. 00421 * 00422 * This function configures the UART module baud rate. This function is used to update 00423 * the UART module baud rate after the UART module is initialized by the UART_Init. 00424 * code 00425 * UART_SetBaudRate(UART1, 115200U, 20000000U); 00426 * endcode 00427 * 00428 * param base UART peripheral base address. 00429 * param baudRate_Bps UART baudrate to be set. 00430 * param srcClock_Hz UART clock source freqency in Hz. 00431 * retval kStatus_UART_BaudrateNotSupport Baudrate is not support in the current clock source. 00432 * retval kStatus_Success Set baudrate succeeded. 00433 */ 00434 status_t UART_SetBaudRate(UART_Type *base, uint32_t baudRate_Bps, uint32_t srcClock_Hz) 00435 { 00436 assert(baudRate_Bps); 00437 00438 uint16_t sbr = 0; 00439 uint32_t baudDiff = 0; 00440 uint8_t oldCtrl; 00441 00442 /* Calculate the baud rate modulo divisor, sbr*/ 00443 sbr = srcClock_Hz / (baudRate_Bps * 16); 00444 /* set sbrTemp to 1 if the sourceClockInHz can not satisfy the desired baud rate */ 00445 if (sbr == 0) 00446 { 00447 sbr = 1; 00448 } 00449 #if defined(FSL_FEATURE_UART_HAS_BAUD_RATE_FINE_ADJUST_SUPPORT) && FSL_FEATURE_UART_HAS_BAUD_RATE_FINE_ADJUST_SUPPORT 00450 /* Determine if a fractional divider is needed to fine tune closer to the 00451 * desired baud, each value of brfa is in 1/32 increments, 00452 * hence the multiply-by-32. */ 00453 uint32_t tempBaud = 0; 00454 00455 uint16_t brfa = (2 * srcClock_Hz / (baudRate_Bps)) - 32 * sbr; 00456 00457 /* Calculate the baud rate based on the temporary SBR values and BRFA */ 00458 tempBaud = (srcClock_Hz * 2 / ((sbr * 32 + brfa))); 00459 baudDiff = (tempBaud > baudRate_Bps) ? (tempBaud - baudRate_Bps) : (baudRate_Bps - tempBaud); 00460 #else 00461 /* Calculate the baud rate based on the temporary SBR values */ 00462 baudDiff = (srcClock_Hz / (sbr * 16)) - baudRate_Bps; 00463 00464 /* Select the better value between sbr and (sbr + 1) */ 00465 if (baudDiff > (baudRate_Bps - (srcClock_Hz / (16 * (sbr + 1))))) 00466 { 00467 baudDiff = baudRate_Bps - (srcClock_Hz / (16 * (sbr + 1))); 00468 sbr++; 00469 } 00470 #endif 00471 00472 /* next, check to see if actual baud rate is within 3% of desired baud rate 00473 * based on the calculate SBR value */ 00474 if (baudDiff < ((baudRate_Bps / 100) * 3)) 00475 { 00476 /* Store C2 before disable Tx and Rx */ 00477 oldCtrl = base->C2; 00478 00479 /* Disable UART TX RX before setting. */ 00480 base->C2 &= ~(UART_C2_TE_MASK | UART_C2_RE_MASK); 00481 00482 /* Write the sbr value to the BDH and BDL registers*/ 00483 base->BDH = (base->BDH & ~UART_BDH_SBR_MASK) | (uint8_t)(sbr >> 8); 00484 base->BDL = (uint8_t)sbr; 00485 00486 #if defined(FSL_FEATURE_UART_HAS_BAUD_RATE_FINE_ADJUST_SUPPORT) && FSL_FEATURE_UART_HAS_BAUD_RATE_FINE_ADJUST_SUPPORT 00487 /* Write the brfa value to the register*/ 00488 base->C4 = (base->C4 & ~UART_C4_BRFA_MASK) | (brfa & UART_C4_BRFA_MASK); 00489 #endif 00490 /* Restore C2. */ 00491 base->C2 = oldCtrl; 00492 00493 return kStatus_Success; 00494 } 00495 else 00496 { 00497 /* Unacceptable baud rate difference of more than 3%*/ 00498 return kStatus_UART_BaudrateNotSupport ; 00499 } 00500 } 00501 00502 /*! 00503 * brief Enables UART interrupts according to the provided mask. 00504 * 00505 * This function enables the UART interrupts according to the provided mask. The mask 00506 * is a logical OR of enumeration members. See ref _uart_interrupt_enable. 00507 * For example, to enable TX empty interrupt and RX full interrupt, do the following. 00508 * code 00509 * UART_EnableInterrupts(UART1,kUART_TxDataRegEmptyInterruptEnable | kUART_RxDataRegFullInterruptEnable); 00510 * endcode 00511 * 00512 * param base UART peripheral base address. 00513 * param mask The interrupts to enable. Logical OR of ref _uart_interrupt_enable. 00514 */ 00515 void UART_EnableInterrupts(UART_Type *base, uint32_t mask) 00516 { 00517 mask &= kUART_AllInterruptsEnable; 00518 00519 /* The interrupt mask is combined by control bits from several register: ((CFIFO<<24) | (C3<<16) | (C2<<8) |(BDH)) 00520 */ 00521 base->BDH |= mask; 00522 base->C2 |= (mask >> 8); 00523 base->C3 |= (mask >> 16); 00524 00525 #if defined(FSL_FEATURE_UART_HAS_FIFO) && FSL_FEATURE_UART_HAS_FIFO 00526 base->CFIFO |= (mask >> 24); 00527 #endif 00528 } 00529 00530 /*! 00531 * brief Disables the UART interrupts according to the provided mask. 00532 * 00533 * This function disables the UART interrupts according to the provided mask. The mask 00534 * is a logical OR of enumeration members. See ref _uart_interrupt_enable. 00535 * For example, to disable TX empty interrupt and RX full interrupt do the following. 00536 * code 00537 * UART_DisableInterrupts(UART1,kUART_TxDataRegEmptyInterruptEnable | kUART_RxDataRegFullInterruptEnable); 00538 * endcode 00539 * 00540 * param base UART peripheral base address. 00541 * param mask The interrupts to disable. Logical OR of ref _uart_interrupt_enable. 00542 */ 00543 void UART_DisableInterrupts(UART_Type *base, uint32_t mask) 00544 { 00545 mask &= kUART_AllInterruptsEnable; 00546 00547 /* The interrupt mask is combined by control bits from several register: ((CFIFO<<24) | (C3<<16) | (C2<<8) |(BDH)) 00548 */ 00549 base->BDH &= ~mask; 00550 base->C2 &= ~(mask >> 8); 00551 base->C3 &= ~(mask >> 16); 00552 00553 #if defined(FSL_FEATURE_UART_HAS_FIFO) && FSL_FEATURE_UART_HAS_FIFO 00554 base->CFIFO &= ~(mask >> 24); 00555 #endif 00556 } 00557 00558 /*! 00559 * brief Gets the enabled UART interrupts. 00560 * 00561 * This function gets the enabled UART interrupts. The enabled interrupts are returned 00562 * as the logical OR value of the enumerators ref _uart_interrupt_enable. To check 00563 * a specific interrupts enable status, compare the return value with enumerators 00564 * in ref _uart_interrupt_enable. 00565 * For example, to check whether TX empty interrupt is enabled, do the following. 00566 * code 00567 * uint32_t enabledInterrupts = UART_GetEnabledInterrupts(UART1); 00568 * 00569 * if (kUART_TxDataRegEmptyInterruptEnable & enabledInterrupts) 00570 * { 00571 * ... 00572 * } 00573 * endcode 00574 * 00575 * param base UART peripheral base address. 00576 * return UART interrupt flags which are logical OR of the enumerators in ref _uart_interrupt_enable. 00577 */ 00578 uint32_t UART_GetEnabledInterrupts(UART_Type *base) 00579 { 00580 uint32_t temp; 00581 00582 temp = base->BDH | ((uint32_t)(base->C2) << 8) | ((uint32_t)(base->C3) << 16); 00583 00584 #if defined(FSL_FEATURE_UART_HAS_FIFO) && FSL_FEATURE_UART_HAS_FIFO 00585 temp |= ((uint32_t)(base->CFIFO) << 24); 00586 #endif 00587 00588 return temp & kUART_AllInterruptsEnable; 00589 } 00590 00591 /*! 00592 * brief Gets UART status flags. 00593 * 00594 * This function gets all UART status flags. The flags are returned as the logical 00595 * OR value of the enumerators ref _uart_flags. To check a specific status, 00596 * compare the return value with enumerators in ref _uart_flags. 00597 * For example, to check whether the TX is empty, do the following. 00598 * code 00599 * if (kUART_TxDataRegEmptyFlag & UART_GetStatusFlags(UART1)) 00600 * { 00601 * ... 00602 * } 00603 * endcode 00604 * 00605 * param base UART peripheral base address. 00606 * return UART status flags which are ORed by the enumerators in the _uart_flags. 00607 */ 00608 uint32_t UART_GetStatusFlags(UART_Type *base) 00609 { 00610 uint32_t status_flag; 00611 00612 status_flag = base->S1 | ((uint32_t)(base->S2) << 8); 00613 00614 #if defined(FSL_FEATURE_UART_HAS_EXTENDED_DATA_REGISTER_FLAGS) && FSL_FEATURE_UART_HAS_EXTENDED_DATA_REGISTER_FLAGS 00615 status_flag |= ((uint32_t)(base->ED) << 16); 00616 #endif 00617 00618 #if defined(FSL_FEATURE_UART_HAS_FIFO) && FSL_FEATURE_UART_HAS_FIFO 00619 status_flag |= ((uint32_t)(base->SFIFO) << 24); 00620 #endif 00621 00622 return status_flag; 00623 } 00624 00625 /*! 00626 * brief Clears status flags with the provided mask. 00627 * 00628 * This function clears UART status flags with a provided mask. An automatically cleared flag 00629 * can't be cleared by this function. 00630 * These flags can only be cleared or set by hardware. 00631 * kUART_TxDataRegEmptyFlag, kUART_TransmissionCompleteFlag, kUART_RxDataRegFullFlag, 00632 * kUART_RxActiveFlag, kUART_NoiseErrorInRxDataRegFlag, kUART_ParityErrorInRxDataRegFlag, 00633 * kUART_TxFifoEmptyFlag,kUART_RxFifoEmptyFlag 00634 * Note that this API should be called when the Tx/Rx is idle. Otherwise it has no effect. 00635 * 00636 * param base UART peripheral base address. 00637 * param mask The status flags to be cleared; it is logical OR value of ref _uart_flags. 00638 * retval kStatus_UART_FlagCannotClearManually The flag can't be cleared by this function but 00639 * it is cleared automatically by hardware. 00640 * retval kStatus_Success Status in the mask is cleared. 00641 */ 00642 status_t UART_ClearStatusFlags(UART_Type *base, uint32_t mask) 00643 { 00644 uint8_t reg = base->S2; 00645 status_t status; 00646 00647 #if defined(FSL_FEATURE_UART_HAS_LIN_BREAK_DETECT) && FSL_FEATURE_UART_HAS_LIN_BREAK_DETECT 00648 reg &= ~(UART_S2_RXEDGIF_MASK | UART_S2_LBKDIF_MASK); 00649 #else 00650 reg &= ~UART_S2_RXEDGIF_MASK; 00651 #endif 00652 00653 base->S2 = reg | (uint8_t)(mask >> 8); 00654 00655 #if defined(FSL_FEATURE_UART_HAS_FIFO) && FSL_FEATURE_UART_HAS_FIFO 00656 base->SFIFO = (uint8_t)(mask >> 24); 00657 #endif 00658 00659 if (mask & (kUART_IdleLineFlag | kUART_NoiseErrorFlag | kUART_FramingErrorFlag | kUART_ParityErrorFlag )) 00660 { 00661 /* Read base->D to clear the flags. */ 00662 (void)base->S1; 00663 (void)base->D; 00664 } 00665 00666 if (mask & kUART_RxOverrunFlag ) 00667 { 00668 /* Read base->D to clear the flags and Flush all data in FIFO. */ 00669 (void)base->S1; 00670 (void)base->D; 00671 #if defined(FSL_FEATURE_UART_HAS_FIFO) && FSL_FEATURE_UART_HAS_FIFO 00672 /* Flush FIFO date, otherwise FIFO pointer will be in unknown state. */ 00673 base->CFIFO |= UART_CFIFO_RXFLUSH_MASK; 00674 #endif 00675 } 00676 00677 /* If some flags still pending. */ 00678 if (mask & UART_GetStatusFlags(base)) 00679 { 00680 /* Some flags can only clear or set by the hardware itself, these flags are: kUART_TxDataRegEmptyFlag, 00681 kUART_TransmissionCompleteFlag, kUART_RxDataRegFullFlag, kUART_RxActiveFlag, kUART_NoiseErrorInRxDataRegFlag, 00682 kUART_ParityErrorInRxDataRegFlag, kUART_TxFifoEmptyFlag, kUART_RxFifoEmptyFlag. */ 00683 status = kStatus_UART_FlagCannotClearManually ; 00684 } 00685 else 00686 { 00687 status = kStatus_Success; 00688 } 00689 00690 return status; 00691 } 00692 00693 /*! 00694 * brief Writes to the TX register using a blocking method. 00695 * 00696 * This function polls the TX register, waits for the TX register to be empty or for the TX FIFO 00697 * to have room and writes data to the TX buffer. 00698 * 00699 * note This function does not check whether all data is sent out to the bus. 00700 * Before disabling the TX, check kUART_TransmissionCompleteFlag to ensure that the TX is 00701 * finished. 00702 * 00703 * param base UART peripheral base address. 00704 * param data Start address of the data to write. 00705 * param length Size of the data to write. 00706 */ 00707 void UART_WriteBlocking(UART_Type *base, const uint8_t *data, size_t length) 00708 { 00709 /* This API can only ensure that the data is written into the data buffer but can't 00710 ensure all data in the data buffer are sent into the transmit shift buffer. */ 00711 while (length--) 00712 { 00713 while (!(base->S1 & UART_S1_TDRE_MASK)) 00714 { 00715 } 00716 base->D = *(data++); 00717 } 00718 } 00719 00720 static void UART_WriteNonBlocking(UART_Type *base, const uint8_t *data, size_t length) 00721 { 00722 assert(data); 00723 00724 size_t i; 00725 00726 /* The Non Blocking write data API assume user have ensured there is enough space in 00727 peripheral to write. */ 00728 for (i = 0; i < length; i++) 00729 { 00730 base->D = data[i]; 00731 } 00732 } 00733 00734 /*! 00735 * brief Read RX data register using a blocking method. 00736 * 00737 * This function polls the RX register, waits for the RX register to be full or for RX FIFO to 00738 * have data, and reads data from the TX register. 00739 * 00740 * param base UART peripheral base address. 00741 * param data Start address of the buffer to store the received data. 00742 * param length Size of the buffer. 00743 * retval kStatus_UART_RxHardwareOverrun Receiver overrun occurred while receiving data. 00744 * retval kStatus_UART_NoiseError A noise error occurred while receiving data. 00745 * retval kStatus_UART_FramingError A framing error occurred while receiving data. 00746 * retval kStatus_UART_ParityError A parity error occurred while receiving data. 00747 * retval kStatus_Success Successfully received all data. 00748 */ 00749 status_t UART_ReadBlocking(UART_Type *base, uint8_t *data, size_t length) 00750 { 00751 assert(data); 00752 00753 uint32_t statusFlag; 00754 00755 while (length--) 00756 { 00757 #if defined(FSL_FEATURE_UART_HAS_FIFO) && FSL_FEATURE_UART_HAS_FIFO 00758 while (!base->RCFIFO) 00759 #else 00760 while (!(base->S1 & UART_S1_RDRF_MASK)) 00761 #endif 00762 { 00763 statusFlag = UART_GetStatusFlags(base); 00764 00765 if (statusFlag & kUART_RxOverrunFlag ) 00766 { 00767 return kStatus_UART_RxHardwareOverrun ; 00768 } 00769 00770 if (statusFlag & kUART_NoiseErrorFlag ) 00771 { 00772 return kStatus_UART_NoiseError ; 00773 } 00774 00775 if (statusFlag & kUART_FramingErrorFlag ) 00776 { 00777 return kStatus_UART_FramingError ; 00778 } 00779 00780 if (statusFlag & kUART_ParityErrorFlag ) 00781 { 00782 return kStatus_UART_ParityError ; 00783 } 00784 } 00785 *(data++) = base->D; 00786 } 00787 00788 return kStatus_Success; 00789 } 00790 00791 static void UART_ReadNonBlocking(UART_Type *base, uint8_t *data, size_t length) 00792 { 00793 assert(data); 00794 00795 size_t i; 00796 00797 /* The Non Blocking read data API assume user have ensured there is enough space in 00798 peripheral to write. */ 00799 for (i = 0; i < length; i++) 00800 { 00801 data[i] = base->D; 00802 } 00803 } 00804 00805 /*! 00806 * brief Initializes the UART handle. 00807 * 00808 * This function initializes the UART handle which can be used for other UART 00809 * transactional APIs. Usually, for a specified UART instance, 00810 * call this API once to get the initialized handle. 00811 * 00812 * param base UART peripheral base address. 00813 * param handle UART handle pointer. 00814 * param callback The callback function. 00815 * param userData The parameter of the callback function. 00816 */ 00817 void UART_TransferCreateHandle(UART_Type *base, 00818 uart_handle_t *handle, 00819 uart_transfer_callback_t callback, 00820 void *userData) 00821 { 00822 assert(handle); 00823 00824 uint32_t instance; 00825 00826 /* Zero the handle. */ 00827 memset(handle, 0, sizeof(*handle)); 00828 00829 /* Set the TX/RX state. */ 00830 handle->rxState = kUART_RxIdle; 00831 handle->txState = kUART_TxIdle; 00832 00833 /* Set the callback and user data. */ 00834 handle->callback = callback; 00835 handle->userData = userData; 00836 00837 /* Get instance from peripheral base address. */ 00838 instance = UART_GetInstance(base); 00839 00840 /* Save the handle in global variables to support the double weak mechanism. */ 00841 s_uartHandle[instance] = handle; 00842 00843 s_uartIsr = UART_TransferHandleIRQ; 00844 /* Enable interrupt in NVIC. */ 00845 EnableIRQ(s_uartIRQ[instance]); 00846 } 00847 00848 /*! 00849 * brief Sets up the RX ring buffer. 00850 * 00851 * This function sets up the RX ring buffer to a specific UART handle. 00852 * 00853 * When the RX ring buffer is used, data received are stored into the ring buffer even when the 00854 * user doesn't call the UART_TransferReceiveNonBlocking() API. If data is already received 00855 * in the ring buffer, the user can get the received data from the ring buffer directly. 00856 * 00857 * note When using the RX ring buffer, one byte is reserved for internal use. In other 00858 * words, if p ringBufferSize is 32, only 31 bytes are used for saving data. 00859 * 00860 * param base UART peripheral base address. 00861 * param handle UART handle pointer. 00862 * param ringBuffer Start address of the ring buffer for background receiving. Pass NULL to disable the ring buffer. 00863 * param ringBufferSize Size of the ring buffer. 00864 */ 00865 void UART_TransferStartRingBuffer(UART_Type *base, uart_handle_t *handle, uint8_t *ringBuffer, size_t ringBufferSize) 00866 { 00867 assert(handle); 00868 assert(ringBuffer); 00869 00870 /* Setup the ringbuffer address */ 00871 handle->rxRingBuffer = ringBuffer; 00872 handle->rxRingBufferSize = ringBufferSize; 00873 handle->rxRingBufferHead = 0U; 00874 handle->rxRingBufferTail = 0U; 00875 00876 /* Enable the interrupt to accept the data when user need the ring buffer. */ 00877 UART_EnableInterrupts( 00878 base, kUART_RxDataRegFullInterruptEnable | kUART_RxOverrunInterruptEnable | kUART_FramingErrorInterruptEnable ); 00879 /* Enable parity error interrupt when parity mode is enable*/ 00880 if (UART_C1_PE_MASK & base->C1) 00881 { 00882 UART_EnableInterrupts(base, kUART_ParityErrorInterruptEnable ); 00883 } 00884 } 00885 00886 /*! 00887 * brief Aborts the background transfer and uninstalls the ring buffer. 00888 * 00889 * This function aborts the background transfer and uninstalls the ring buffer. 00890 * 00891 * param base UART peripheral base address. 00892 * param handle UART handle pointer. 00893 */ 00894 void UART_TransferStopRingBuffer(UART_Type *base, uart_handle_t *handle) 00895 { 00896 assert(handle); 00897 00898 if (handle->rxState == kUART_RxIdle) 00899 { 00900 UART_DisableInterrupts(base, kUART_RxDataRegFullInterruptEnable | kUART_RxOverrunInterruptEnable | 00901 kUART_FramingErrorInterruptEnable ); 00902 /* Disable parity error interrupt when parity mode is enable*/ 00903 if (UART_C1_PE_MASK & base->C1) 00904 { 00905 UART_DisableInterrupts(base, kUART_ParityErrorInterruptEnable ); 00906 } 00907 } 00908 00909 handle->rxRingBuffer = NULL; 00910 handle->rxRingBufferSize = 0U; 00911 handle->rxRingBufferHead = 0U; 00912 handle->rxRingBufferTail = 0U; 00913 } 00914 00915 /*! 00916 * brief Transmits a buffer of data using the interrupt method. 00917 * 00918 * This function sends data using an interrupt method. This is a non-blocking function, which 00919 * returns directly without waiting for all data to be written to the TX register. When 00920 * all data is written to the TX register in the ISR, the UART driver calls the callback 00921 * function and passes the ref kStatus_UART_TxIdle as status parameter. 00922 * 00923 * note The kStatus_UART_TxIdle is passed to the upper layer when all data is written 00924 * to the TX register. However, it does not ensure that all data is sent out. Before disabling the TX, 00925 * check the kUART_TransmissionCompleteFlag to ensure that the TX is finished. 00926 * 00927 * param base UART peripheral base address. 00928 * param handle UART handle pointer. 00929 * param xfer UART transfer structure. See #uart_transfer_t. 00930 * retval kStatus_Success Successfully start the data transmission. 00931 * retval kStatus_UART_TxBusy Previous transmission still not finished; data not all written to TX register yet. 00932 * retval kStatus_InvalidArgument Invalid argument. 00933 */ 00934 status_t UART_TransferSendNonBlocking(UART_Type *base, uart_handle_t *handle, uart_transfer_t *xfer) 00935 { 00936 assert(handle); 00937 assert(xfer); 00938 assert(xfer->dataSize ); 00939 assert(xfer->data ); 00940 00941 status_t status; 00942 00943 /* Return error if current TX busy. */ 00944 if (kUART_TxBusy == handle->txState ) 00945 { 00946 status = kStatus_UART_TxBusy ; 00947 } 00948 else 00949 { 00950 handle->txData = xfer->data ; 00951 handle->txDataSize = xfer->dataSize ; 00952 handle->txDataSizeAll = xfer->dataSize ; 00953 handle->txState = kUART_TxBusy; 00954 00955 /* Enable transmitter interrupt. */ 00956 UART_EnableInterrupts(base, kUART_TxDataRegEmptyInterruptEnable ); 00957 00958 status = kStatus_Success; 00959 } 00960 00961 return status; 00962 } 00963 00964 /*! 00965 * brief Aborts the interrupt-driven data transmit. 00966 * 00967 * This function aborts the interrupt-driven data sending. The user can get the remainBytes to find out 00968 * how many bytes are not sent out. 00969 * 00970 * param base UART peripheral base address. 00971 * param handle UART handle pointer. 00972 */ 00973 void UART_TransferAbortSend(UART_Type *base, uart_handle_t *handle) 00974 { 00975 assert(handle); 00976 00977 UART_DisableInterrupts(base, kUART_TxDataRegEmptyInterruptEnable | kUART_TransmissionCompleteInterruptEnable ); 00978 00979 handle->txDataSize = 0; 00980 handle->txState = kUART_TxIdle; 00981 } 00982 00983 /*! 00984 * brief Gets the number of bytes written to the UART TX register. 00985 * 00986 * This function gets the number of bytes written to the UART TX 00987 * register by using the interrupt method. 00988 * 00989 * param base UART peripheral base address. 00990 * param handle UART handle pointer. 00991 * param count Send bytes count. 00992 * retval kStatus_NoTransferInProgress No send in progress. 00993 * retval kStatus_InvalidArgument The parameter is invalid. 00994 * retval kStatus_Success Get successfully through the parameter \p count; 00995 */ 00996 status_t UART_TransferGetSendCount(UART_Type *base, uart_handle_t *handle, uint32_t *count) 00997 { 00998 assert(handle); 00999 assert(count); 01000 01001 if (kUART_TxIdle == handle->txState ) 01002 { 01003 return kStatus_NoTransferInProgress; 01004 } 01005 01006 *count = handle->txDataSizeAll - handle->txDataSize ; 01007 01008 return kStatus_Success; 01009 } 01010 01011 /*! 01012 * brief Receives a buffer of data using an interrupt method. 01013 * 01014 * This function receives data using an interrupt method. This is a non-blocking function, which 01015 * returns without waiting for all data to be received. 01016 * If the RX ring buffer is used and not empty, the data in the ring buffer is copied and 01017 * the parameter p receivedBytes shows how many bytes are copied from the ring buffer. 01018 * After copying, if the data in the ring buffer is not enough to read, the receive 01019 * request is saved by the UART driver. When the new data arrives, the receive request 01020 * is serviced first. When all data is received, the UART driver notifies the upper layer 01021 * through a callback function and passes the status parameter ref kStatus_UART_RxIdle. 01022 * For example, the upper layer needs 10 bytes but there are only 5 bytes in the ring buffer. 01023 * The 5 bytes are copied to the xfer->data and this function returns with the 01024 * parameter p receivedBytes set to 5. For the left 5 bytes, newly arrived data is 01025 * saved from the xfer->data[5]. When 5 bytes are received, the UART driver notifies the upper layer. 01026 * If the RX ring buffer is not enabled, this function enables the RX and RX interrupt 01027 * to receive data to the xfer->data. When all data is received, the upper layer is notified. 01028 * 01029 * param base UART peripheral base address. 01030 * param handle UART handle pointer. 01031 * param xfer UART transfer structure, see #uart_transfer_t. 01032 * param receivedBytes Bytes received from the ring buffer directly. 01033 * retval kStatus_Success Successfully queue the transfer into transmit queue. 01034 * retval kStatus_UART_RxBusy Previous receive request is not finished. 01035 * retval kStatus_InvalidArgument Invalid argument. 01036 */ 01037 status_t UART_TransferReceiveNonBlocking(UART_Type *base, 01038 uart_handle_t *handle, 01039 uart_transfer_t *xfer, 01040 size_t *receivedBytes) 01041 { 01042 assert(handle); 01043 assert(xfer); 01044 assert(xfer->data ); 01045 assert(xfer->dataSize ); 01046 01047 uint32_t i; 01048 status_t status; 01049 /* How many bytes to copy from ring buffer to user memory. */ 01050 size_t bytesToCopy = 0U; 01051 /* How many bytes to receive. */ 01052 size_t bytesToReceive; 01053 /* How many bytes currently have received. */ 01054 size_t bytesCurrentReceived; 01055 01056 /* How to get data: 01057 1. If RX ring buffer is not enabled, then save xfer->data and xfer->dataSize 01058 to uart handle, enable interrupt to store received data to xfer->data. When 01059 all data received, trigger callback. 01060 2. If RX ring buffer is enabled and not empty, get data from ring buffer first. 01061 If there are enough data in ring buffer, copy them to xfer->data and return. 01062 If there are not enough data in ring buffer, copy all of them to xfer->data, 01063 save the xfer->data remained empty space to uart handle, receive data 01064 to this empty space and trigger callback when finished. */ 01065 01066 if (kUART_RxBusy == handle->rxState ) 01067 { 01068 status = kStatus_UART_RxBusy ; 01069 } 01070 else 01071 { 01072 bytesToReceive = xfer->dataSize ; 01073 bytesCurrentReceived = 0U; 01074 01075 /* If RX ring buffer is used. */ 01076 if (handle->rxRingBuffer ) 01077 { 01078 /* Disable UART RX IRQ, protect ring buffer. */ 01079 UART_DisableInterrupts(base, kUART_RxDataRegFullInterruptEnable ); 01080 01081 /* How many bytes in RX ring buffer currently. */ 01082 bytesToCopy = UART_TransferGetRxRingBufferLength(handle); 01083 01084 if (bytesToCopy) 01085 { 01086 bytesToCopy = MIN(bytesToReceive, bytesToCopy); 01087 01088 bytesToReceive -= bytesToCopy; 01089 01090 /* Copy data from ring buffer to user memory. */ 01091 for (i = 0U; i < bytesToCopy; i++) 01092 { 01093 xfer->data [bytesCurrentReceived++] = handle->rxRingBuffer [handle->rxRingBufferTail ]; 01094 01095 /* Wrap to 0. Not use modulo (%) because it might be large and slow. */ 01096 if (handle->rxRingBufferTail + 1U == handle->rxRingBufferSize ) 01097 { 01098 handle->rxRingBufferTail = 0U; 01099 } 01100 else 01101 { 01102 handle->rxRingBufferTail ++; 01103 } 01104 } 01105 } 01106 01107 /* If ring buffer does not have enough data, still need to read more data. */ 01108 if (bytesToReceive) 01109 { 01110 /* No data in ring buffer, save the request to UART handle. */ 01111 handle->rxData = xfer->data + bytesCurrentReceived; 01112 handle->rxDataSize = bytesToReceive; 01113 handle->rxDataSizeAll = bytesToReceive; 01114 handle->rxState = kUART_RxBusy; 01115 } 01116 01117 /* Enable UART RX IRQ if previously enabled. */ 01118 UART_EnableInterrupts(base, kUART_RxDataRegFullInterruptEnable ); 01119 01120 /* Call user callback since all data are received. */ 01121 if (0 == bytesToReceive) 01122 { 01123 if (handle->callback ) 01124 { 01125 handle->callback (base, handle, kStatus_UART_RxIdle , handle->userData ); 01126 } 01127 } 01128 } 01129 /* Ring buffer not used. */ 01130 else 01131 { 01132 handle->rxData = xfer->data + bytesCurrentReceived; 01133 handle->rxDataSize = bytesToReceive; 01134 handle->rxDataSizeAll = bytesToReceive; 01135 handle->rxState = kUART_RxBusy; 01136 01137 /* Enable RX/Rx overrun/framing error/idle line interrupt. */ 01138 UART_EnableInterrupts(base, kUART_RxDataRegFullInterruptEnable | kUART_RxOverrunInterruptEnable | 01139 kUART_FramingErrorInterruptEnable | kUART_IdleLineInterruptEnable ); 01140 /* Enable parity error interrupt when parity mode is enable*/ 01141 if (UART_C1_PE_MASK & base->C1) 01142 { 01143 UART_EnableInterrupts(base, kUART_ParityErrorInterruptEnable ); 01144 } 01145 } 01146 01147 /* Return the how many bytes have read. */ 01148 if (receivedBytes) 01149 { 01150 *receivedBytes = bytesCurrentReceived; 01151 } 01152 01153 status = kStatus_Success; 01154 } 01155 01156 return status; 01157 } 01158 01159 /*! 01160 * brief Aborts the interrupt-driven data receiving. 01161 * 01162 * This function aborts the interrupt-driven data receiving. The user can get the remainBytes to know 01163 * how many bytes are not received yet. 01164 * 01165 * param base UART peripheral base address. 01166 * param handle UART handle pointer. 01167 */ 01168 void UART_TransferAbortReceive(UART_Type *base, uart_handle_t *handle) 01169 { 01170 assert(handle); 01171 01172 /* Only abort the receive to handle->rxData, the RX ring buffer is still working. */ 01173 if (!handle->rxRingBuffer ) 01174 { 01175 /* Disable RX interrupt. */ 01176 UART_DisableInterrupts(base, kUART_RxDataRegFullInterruptEnable | kUART_RxOverrunInterruptEnable | 01177 kUART_FramingErrorInterruptEnable | kUART_IdleLineInterruptEnable ); 01178 /* Disable parity error interrupt when parity mode is enable*/ 01179 if (UART_C1_PE_MASK & base->C1) 01180 { 01181 UART_DisableInterrupts(base, kUART_ParityErrorInterruptEnable ); 01182 } 01183 } 01184 01185 handle->rxDataSize = 0U; 01186 handle->rxState = kUART_RxIdle; 01187 } 01188 01189 /*! 01190 * brief Gets the number of bytes that have been received. 01191 * 01192 * This function gets the number of bytes that have been received. 01193 * 01194 * param base UART peripheral base address. 01195 * param handle UART handle pointer. 01196 * param count Receive bytes count. 01197 * retval kStatus_NoTransferInProgress No receive in progress. 01198 * retval kStatus_InvalidArgument Parameter is invalid. 01199 * retval kStatus_Success Get successfully through the parameter \p count; 01200 */ 01201 status_t UART_TransferGetReceiveCount(UART_Type *base, uart_handle_t *handle, uint32_t *count) 01202 { 01203 assert(handle); 01204 assert(count); 01205 01206 if (kUART_RxIdle == handle->rxState ) 01207 { 01208 return kStatus_NoTransferInProgress; 01209 } 01210 01211 if (!count) 01212 { 01213 return kStatus_InvalidArgument; 01214 } 01215 01216 *count = handle->rxDataSizeAll - handle->rxDataSize ; 01217 01218 return kStatus_Success; 01219 } 01220 01221 /*! 01222 * brief UART IRQ handle function. 01223 * 01224 * This function handles the UART transmit and receive IRQ request. 01225 * 01226 * param base UART peripheral base address. 01227 * param handle UART handle pointer. 01228 */ 01229 void UART_TransferHandleIRQ(UART_Type *base, uart_handle_t *handle) 01230 { 01231 assert(handle); 01232 01233 uint8_t count; 01234 uint8_t tempCount; 01235 uint32_t status = UART_GetStatusFlags(base); 01236 01237 /* If RX framing error */ 01238 if (kUART_FramingErrorFlag & status) 01239 { 01240 /* Read base->D to clear framing error flag, otherwise the RX does not work. */ 01241 while (base->S1 & UART_S1_RDRF_MASK) 01242 { 01243 (void)base->D; 01244 } 01245 #if defined(FSL_FEATURE_UART_HAS_FIFO) && FSL_FEATURE_UART_HAS_FIFO 01246 /* Flush FIFO date, otherwise FIFO pointer will be in unknown state. */ 01247 base->CFIFO |= UART_CFIFO_RXFLUSH_MASK; 01248 #endif 01249 01250 handle->rxState = kUART_RxFramingError; 01251 handle->rxDataSize = 0U; 01252 /* Trigger callback. */ 01253 if (handle->callback ) 01254 { 01255 handle->callback (base, handle, kStatus_UART_FramingError , handle->userData ); 01256 } 01257 } 01258 01259 /* If RX parity error */ 01260 if (kUART_ParityErrorFlag & status) 01261 { 01262 /* Read base->D to clear parity error flag, otherwise the RX does not work. */ 01263 while (base->S1 & UART_S1_RDRF_MASK) 01264 { 01265 (void)base->D; 01266 } 01267 #if defined(FSL_FEATURE_UART_HAS_FIFO) && FSL_FEATURE_UART_HAS_FIFO 01268 /* Flush FIFO date, otherwise FIFO pointer will be in unknown state. */ 01269 base->CFIFO |= UART_CFIFO_RXFLUSH_MASK; 01270 #endif 01271 01272 handle->rxState = kUART_RxParityError; 01273 handle->rxDataSize = 0U; 01274 /* Trigger callback. */ 01275 if (handle->callback ) 01276 { 01277 handle->callback (base, handle, kStatus_UART_ParityError , handle->userData ); 01278 } 01279 } 01280 01281 /* If RX overrun. */ 01282 if (kUART_RxOverrunFlag & status) 01283 { 01284 /* Read base->D to clear overrun flag, otherwise the RX does not work. */ 01285 while (base->S1 & UART_S1_RDRF_MASK) 01286 { 01287 (void)base->D; 01288 } 01289 #if defined(FSL_FEATURE_UART_HAS_FIFO) && FSL_FEATURE_UART_HAS_FIFO 01290 /* Flush FIFO date, otherwise FIFO pointer will be in unknown state. */ 01291 base->CFIFO |= UART_CFIFO_RXFLUSH_MASK; 01292 #endif 01293 /* Trigger callback. */ 01294 if (handle->callback ) 01295 { 01296 handle->callback (base, handle, kStatus_UART_RxHardwareOverrun , handle->userData ); 01297 } 01298 } 01299 01300 /* If IDLE line was detected. */ 01301 if ((kUART_IdleLineFlag & status) && (UART_C2_ILIE_MASK & base->C2)) 01302 { 01303 #if defined(FSL_FEATURE_UART_HAS_FIFO) && FSL_FEATURE_UART_HAS_FIFO 01304 /* If still some data in the FIFO, read out these data to user data buffer. */ 01305 count = base->RCFIFO; 01306 /* If handle->rxDataSize is not 0, first save data to handle->rxData. */ 01307 while ((count) && (handle->rxDataSize )) 01308 { 01309 tempCount = MIN(handle->rxDataSize , count); 01310 01311 /* Using non block API to read the data from the registers. */ 01312 UART_ReadNonBlocking(base, handle->rxData , tempCount); 01313 handle->rxData += tempCount; 01314 handle->rxDataSize -= tempCount; 01315 count -= tempCount; 01316 01317 /* If all the data required for upper layer is ready, trigger callback. */ 01318 if (!handle->rxDataSize ) 01319 { 01320 handle->rxState = kUART_RxIdle; 01321 01322 /* Disable RX interrupt/overrun interrupt/fram error/idle line detected interrupt */ 01323 UART_DisableInterrupts(base, kUART_RxDataRegFullInterruptEnable | kUART_RxOverrunInterruptEnable | 01324 kUART_FramingErrorInterruptEnable ); 01325 01326 /* Disable parity error interrupt when parity mode is enable*/ 01327 if (UART_C1_PE_MASK & base->C1) 01328 { 01329 UART_DisableInterrupts(base, kUART_ParityErrorInterruptEnable ); 01330 } 01331 01332 if (handle->callback ) 01333 { 01334 handle->callback (base, handle, kStatus_UART_RxIdle , handle->userData ); 01335 } 01336 } 01337 } 01338 #endif 01339 /* To clear IDLE, read UART status S1 with IDLE set and then read D.*/ 01340 while (UART_S1_IDLE_MASK & base->S1) 01341 { 01342 (void)base->D; 01343 } 01344 #if defined(FSL_FEATURE_UART_HAS_FIFO) && FSL_FEATURE_UART_HAS_FIFO 01345 /* Flush FIFO date, otherwise FIFO pointer will be in unknown state. */ 01346 base->CFIFO |= UART_CFIFO_RXFLUSH_MASK; 01347 #endif 01348 /* If rxDataSize is 0, disable idle line interrupt.*/ 01349 if (!(handle->rxDataSize )) 01350 { 01351 UART_DisableInterrupts(base, kUART_IdleLineInterruptEnable ); 01352 } 01353 /* If callback is not NULL and rxDataSize is not 0. */ 01354 if ((handle->callback ) && (handle->rxDataSize )) 01355 { 01356 handle->callback (base, handle, kStatus_UART_IdleLineDetected , handle->userData ); 01357 } 01358 } 01359 /* Receive data register full */ 01360 if ((kUART_RxDataRegFullFlag & status) && (UART_C2_RIE_MASK & base->C2)) 01361 { 01362 /* Get the size that can be stored into buffer for this interrupt. */ 01363 #if defined(FSL_FEATURE_UART_HAS_FIFO) && FSL_FEATURE_UART_HAS_FIFO 01364 count = base->RCFIFO; 01365 #else 01366 count = 1; 01367 #endif 01368 01369 /* If handle->rxDataSize is not 0, first save data to handle->rxData. */ 01370 while ((count) && (handle->rxDataSize )) 01371 { 01372 #if defined(FSL_FEATURE_UART_HAS_FIFO) && FSL_FEATURE_UART_HAS_FIFO 01373 tempCount = MIN(handle->rxDataSize , count); 01374 #else 01375 tempCount = 1; 01376 #endif 01377 01378 /* Using non block API to read the data from the registers. */ 01379 UART_ReadNonBlocking(base, handle->rxData , tempCount); 01380 handle->rxData += tempCount; 01381 handle->rxDataSize -= tempCount; 01382 count -= tempCount; 01383 01384 /* If all the data required for upper layer is ready, trigger callback. */ 01385 if (!handle->rxDataSize ) 01386 { 01387 handle->rxState = kUART_RxIdle; 01388 01389 if (handle->callback ) 01390 { 01391 handle->callback (base, handle, kStatus_UART_RxIdle , handle->userData ); 01392 } 01393 } 01394 } 01395 01396 /* If use RX ring buffer, receive data to ring buffer. */ 01397 if (handle->rxRingBuffer ) 01398 { 01399 while (count--) 01400 { 01401 /* If RX ring buffer is full, trigger callback to notify over run. */ 01402 if (UART_TransferIsRxRingBufferFull(handle)) 01403 { 01404 if (handle->callback ) 01405 { 01406 handle->callback (base, handle, kStatus_UART_RxRingBufferOverrun , handle->userData ); 01407 } 01408 } 01409 01410 /* If ring buffer is still full after callback function, the oldest data is overrided. */ 01411 if (UART_TransferIsRxRingBufferFull(handle)) 01412 { 01413 /* Increase handle->rxRingBufferTail to make room for new data. */ 01414 if (handle->rxRingBufferTail + 1U == handle->rxRingBufferSize ) 01415 { 01416 handle->rxRingBufferTail = 0U; 01417 } 01418 else 01419 { 01420 handle->rxRingBufferTail ++; 01421 } 01422 } 01423 01424 /* Read data. */ 01425 handle->rxRingBuffer [handle->rxRingBufferHead ] = base->D; 01426 01427 /* Increase handle->rxRingBufferHead. */ 01428 if (handle->rxRingBufferHead + 1U == handle->rxRingBufferSize ) 01429 { 01430 handle->rxRingBufferHead = 0U; 01431 } 01432 else 01433 { 01434 handle->rxRingBufferHead ++; 01435 } 01436 } 01437 } 01438 01439 else if (!handle->rxDataSize ) 01440 { 01441 /* Disable RX interrupt/overrun interrupt/fram error/idle line detected interrupt */ 01442 UART_DisableInterrupts(base, kUART_RxDataRegFullInterruptEnable | kUART_RxOverrunInterruptEnable | 01443 kUART_FramingErrorInterruptEnable ); 01444 01445 /* Disable parity error interrupt when parity mode is enable*/ 01446 if (UART_C1_PE_MASK & base->C1) 01447 { 01448 UART_DisableInterrupts(base, kUART_ParityErrorInterruptEnable ); 01449 } 01450 } 01451 else 01452 { 01453 } 01454 } 01455 01456 /* If framing error or parity error happened, stop the RX interrupt when ues no ring buffer */ 01457 if (((handle->rxState == kUART_RxFramingError) || (handle->rxState == kUART_RxParityError)) && 01458 (!handle->rxRingBuffer )) 01459 { 01460 UART_DisableInterrupts(base, kUART_RxDataRegFullInterruptEnable | kUART_RxOverrunInterruptEnable | 01461 kUART_FramingErrorInterruptEnable | kUART_IdleLineInterruptEnable ); 01462 01463 /* Disable parity error interrupt when parity mode is enable*/ 01464 if (UART_C1_PE_MASK & base->C1) 01465 { 01466 UART_DisableInterrupts(base, kUART_ParityErrorInterruptEnable ); 01467 } 01468 } 01469 01470 /* Send data register empty and the interrupt is enabled. */ 01471 if ((kUART_TxDataRegEmptyFlag & status) && (base->C2 & UART_C2_TIE_MASK)) 01472 { 01473 /* Get the bytes that available at this moment. */ 01474 #if defined(FSL_FEATURE_UART_HAS_FIFO) && FSL_FEATURE_UART_HAS_FIFO 01475 count = FSL_FEATURE_UART_FIFO_SIZEn(base) - base->TCFIFO; 01476 #else 01477 count = 1; 01478 #endif 01479 01480 while ((count) && (handle->txDataSize )) 01481 { 01482 #if defined(FSL_FEATURE_UART_HAS_FIFO) && FSL_FEATURE_UART_HAS_FIFO 01483 tempCount = MIN(handle->txDataSize , count); 01484 #else 01485 tempCount = 1; 01486 #endif 01487 01488 /* Using non block API to write the data to the registers. */ 01489 UART_WriteNonBlocking(base, handle->txData , tempCount); 01490 handle->txData += tempCount; 01491 handle->txDataSize -= tempCount; 01492 count -= tempCount; 01493 01494 /* If all the data are written to data register, TX finished. */ 01495 if (!handle->txDataSize ) 01496 { 01497 handle->txState = kUART_TxIdle; 01498 01499 /* Disable TX register empty interrupt. */ 01500 base->C2 = (base->C2 & ~UART_C2_TIE_MASK); 01501 01502 /* Trigger callback. */ 01503 if (handle->callback ) 01504 { 01505 handle->callback (base, handle, kStatus_UART_TxIdle , handle->userData ); 01506 } 01507 } 01508 } 01509 } 01510 } 01511 01512 /*! 01513 * brief UART Error IRQ handle function. 01514 * 01515 * This function handles the UART error IRQ request. 01516 * 01517 * param base UART peripheral base address. 01518 * param handle UART handle pointer. 01519 */ 01520 void UART_TransferHandleErrorIRQ(UART_Type *base, uart_handle_t *handle) 01521 { 01522 /* To be implemented by User. */ 01523 } 01524 01525 #if defined(UART0) 01526 #if ((!(defined(FSL_FEATURE_SOC_LPSCI_COUNT))) || \ 01527 ((defined(FSL_FEATURE_SOC_LPSCI_COUNT)) && (FSL_FEATURE_SOC_LPSCI_COUNT == 0))) 01528 void UART0_DriverIRQHandler(void) 01529 { 01530 s_uartIsr(UART0, s_uartHandle[0]); 01531 /* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping 01532 exception return operation might vector to incorrect interrupt */ 01533 #if defined __CORTEX_M && (__CORTEX_M == 4U) 01534 __DSB(); 01535 #endif 01536 } 01537 01538 void UART0_RX_TX_DriverIRQHandler(void) 01539 { 01540 UART0_DriverIRQHandler(); 01541 /* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping 01542 exception return operation might vector to incorrect interrupt */ 01543 #if defined __CORTEX_M && (__CORTEX_M == 4U) 01544 __DSB(); 01545 #endif 01546 } 01547 #endif 01548 #endif 01549 01550 #if defined(UART1) 01551 void UART1_DriverIRQHandler(void) 01552 { 01553 s_uartIsr(UART1, s_uartHandle[1]); 01554 /* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping 01555 exception return operation might vector to incorrect interrupt */ 01556 #if defined __CORTEX_M && (__CORTEX_M == 4U) 01557 __DSB(); 01558 #endif 01559 } 01560 01561 void UART1_RX_TX_DriverIRQHandler(void) 01562 { 01563 UART1_DriverIRQHandler(); 01564 /* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping 01565 exception return operation might vector to incorrect interrupt */ 01566 #if defined __CORTEX_M && (__CORTEX_M == 4U) 01567 __DSB(); 01568 #endif 01569 } 01570 #endif 01571 01572 #if defined(UART2) 01573 void UART2_DriverIRQHandler(void) 01574 { 01575 s_uartIsr(UART2, s_uartHandle[2]); 01576 /* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping 01577 exception return operation might vector to incorrect interrupt */ 01578 #if defined __CORTEX_M && (__CORTEX_M == 4U) 01579 __DSB(); 01580 #endif 01581 } 01582 01583 void UART2_RX_TX_DriverIRQHandler(void) 01584 { 01585 UART2_DriverIRQHandler(); 01586 /* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping 01587 exception return operation might vector to incorrect interrupt */ 01588 #if defined __CORTEX_M && (__CORTEX_M == 4U) 01589 __DSB(); 01590 #endif 01591 } 01592 #endif 01593 01594 #if defined(UART3) 01595 void UART3_DriverIRQHandler(void) 01596 { 01597 s_uartIsr(UART3, s_uartHandle[3]); 01598 /* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping 01599 exception return operation might vector to incorrect interrupt */ 01600 #if defined __CORTEX_M && (__CORTEX_M == 4U) 01601 __DSB(); 01602 #endif 01603 } 01604 01605 void UART3_RX_TX_DriverIRQHandler(void) 01606 { 01607 UART3_DriverIRQHandler(); 01608 /* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping 01609 exception return operation might vector to incorrect interrupt */ 01610 #if defined __CORTEX_M && (__CORTEX_M == 4U) 01611 __DSB(); 01612 #endif 01613 } 01614 #endif 01615 01616 #if defined(UART4) 01617 void UART4_DriverIRQHandler(void) 01618 { 01619 s_uartIsr(UART4, s_uartHandle[4]); 01620 /* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping 01621 exception return operation might vector to incorrect interrupt */ 01622 #if defined __CORTEX_M && (__CORTEX_M == 4U) 01623 __DSB(); 01624 #endif 01625 } 01626 01627 void UART4_RX_TX_DriverIRQHandler(void) 01628 { 01629 UART4_DriverIRQHandler(); 01630 /* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping 01631 exception return operation might vector to incorrect interrupt */ 01632 #if defined __CORTEX_M && (__CORTEX_M == 4U) 01633 __DSB(); 01634 #endif 01635 } 01636 #endif 01637 01638 #if defined(UART5) 01639 void UART5_DriverIRQHandler(void) 01640 { 01641 s_uartIsr(UART5, s_uartHandle[5]); 01642 /* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping 01643 exception return operation might vector to incorrect interrupt */ 01644 #if defined __CORTEX_M && (__CORTEX_M == 4U) 01645 __DSB(); 01646 #endif 01647 } 01648 01649 void UART5_RX_TX_DriverIRQHandler(void) 01650 { 01651 UART5_DriverIRQHandler(); 01652 /* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping 01653 exception return operation might vector to incorrect interrupt */ 01654 #if defined __CORTEX_M && (__CORTEX_M == 4U) 01655 __DSB(); 01656 #endif 01657 } 01658 #endif
Generated on Tue Jul 12 2022 15:37:18 by
1.7.2