Arrow / Mbed OS DAPLink Reset
Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers fsl_uart.c Source File

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