Repostiory containing DAPLink source code with Reset Pin workaround for HANI_IOT board.
Upstream: https://github.com/ARMmbed/DAPLink
source/hic_hal/freescale/k26f/fsl_uart.c@0:01f31e923fe2, 2020-04-07 (annotated)
- Committer:
- Pawel Zarembski
- Date:
- Tue Apr 07 12:55:42 2020 +0200
- Revision:
- 0:01f31e923fe2
hani: DAPLink with reset workaround
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
Pawel Zarembski |
0:01f31e923fe2 | 1 | /* |
Pawel Zarembski |
0:01f31e923fe2 | 2 | * Copyright (c) 2015-2016, Freescale Semiconductor, Inc. |
Pawel Zarembski |
0:01f31e923fe2 | 3 | * Copyright 2016-2017 NXP |
Pawel Zarembski |
0:01f31e923fe2 | 4 | * All rights reserved. |
Pawel Zarembski |
0:01f31e923fe2 | 5 | * |
Pawel Zarembski |
0:01f31e923fe2 | 6 | * SPDX-License-Identifier: BSD-3-Clause |
Pawel Zarembski |
0:01f31e923fe2 | 7 | */ |
Pawel Zarembski |
0:01f31e923fe2 | 8 | |
Pawel Zarembski |
0:01f31e923fe2 | 9 | #include "fsl_uart.h" |
Pawel Zarembski |
0:01f31e923fe2 | 10 | #include "fsl_clock.h" |
Pawel Zarembski |
0:01f31e923fe2 | 11 | |
Pawel Zarembski |
0:01f31e923fe2 | 12 | /******************************************************************************* |
Pawel Zarembski |
0:01f31e923fe2 | 13 | * Definitions |
Pawel Zarembski |
0:01f31e923fe2 | 14 | ******************************************************************************/ |
Pawel Zarembski |
0:01f31e923fe2 | 15 | |
Pawel Zarembski |
0:01f31e923fe2 | 16 | /* Component ID definition, used by tools. */ |
Pawel Zarembski |
0:01f31e923fe2 | 17 | #ifndef FSL_COMPONENT_ID |
Pawel Zarembski |
0:01f31e923fe2 | 18 | #define FSL_COMPONENT_ID "platform.drivers.uart" |
Pawel Zarembski |
0:01f31e923fe2 | 19 | #endif |
Pawel Zarembski |
0:01f31e923fe2 | 20 | |
Pawel Zarembski |
0:01f31e923fe2 | 21 | /* UART transfer state. */ |
Pawel Zarembski |
0:01f31e923fe2 | 22 | enum _uart_tansfer_states |
Pawel Zarembski |
0:01f31e923fe2 | 23 | { |
Pawel Zarembski |
0:01f31e923fe2 | 24 | kUART_TxIdle, /* TX idle. */ |
Pawel Zarembski |
0:01f31e923fe2 | 25 | kUART_TxBusy, /* TX busy. */ |
Pawel Zarembski |
0:01f31e923fe2 | 26 | kUART_RxIdle, /* RX idle. */ |
Pawel Zarembski |
0:01f31e923fe2 | 27 | kUART_RxBusy, /* RX busy. */ |
Pawel Zarembski |
0:01f31e923fe2 | 28 | kUART_RxFramingError, /* Rx framing error */ |
Pawel Zarembski |
0:01f31e923fe2 | 29 | kUART_RxParityError /* Rx parity error */ |
Pawel Zarembski |
0:01f31e923fe2 | 30 | }; |
Pawel Zarembski |
0:01f31e923fe2 | 31 | |
Pawel Zarembski |
0:01f31e923fe2 | 32 | /* Typedef for interrupt handler. */ |
Pawel Zarembski |
0:01f31e923fe2 | 33 | typedef void (*uart_isr_t)(UART_Type *base, uart_handle_t *handle); |
Pawel Zarembski |
0:01f31e923fe2 | 34 | |
Pawel Zarembski |
0:01f31e923fe2 | 35 | /******************************************************************************* |
Pawel Zarembski |
0:01f31e923fe2 | 36 | * Prototypes |
Pawel Zarembski |
0:01f31e923fe2 | 37 | ******************************************************************************/ |
Pawel Zarembski |
0:01f31e923fe2 | 38 | /*! |
Pawel Zarembski |
0:01f31e923fe2 | 39 | * @brief Check whether the RX ring buffer is full. |
Pawel Zarembski |
0:01f31e923fe2 | 40 | * |
Pawel Zarembski |
0:01f31e923fe2 | 41 | * @param handle UART handle pointer. |
Pawel Zarembski |
0:01f31e923fe2 | 42 | * @retval true RX ring buffer is full. |
Pawel Zarembski |
0:01f31e923fe2 | 43 | * @retval false RX ring buffer is not full. |
Pawel Zarembski |
0:01f31e923fe2 | 44 | */ |
Pawel Zarembski |
0:01f31e923fe2 | 45 | static bool UART_TransferIsRxRingBufferFull(uart_handle_t *handle); |
Pawel Zarembski |
0:01f31e923fe2 | 46 | |
Pawel Zarembski |
0:01f31e923fe2 | 47 | /*! |
Pawel Zarembski |
0:01f31e923fe2 | 48 | * @brief Read RX register using non-blocking method. |
Pawel Zarembski |
0:01f31e923fe2 | 49 | * |
Pawel Zarembski |
0:01f31e923fe2 | 50 | * This function reads data from the TX register directly, upper layer must make |
Pawel Zarembski |
0:01f31e923fe2 | 51 | * sure the RX register is full or TX FIFO has data before calling this function. |
Pawel Zarembski |
0:01f31e923fe2 | 52 | * |
Pawel Zarembski |
0:01f31e923fe2 | 53 | * @param base UART peripheral base address. |
Pawel Zarembski |
0:01f31e923fe2 | 54 | * @param data Start addresss of the buffer to store the received data. |
Pawel Zarembski |
0:01f31e923fe2 | 55 | * @param length Size of the buffer. |
Pawel Zarembski |
0:01f31e923fe2 | 56 | */ |
Pawel Zarembski |
0:01f31e923fe2 | 57 | static void UART_ReadNonBlocking(UART_Type *base, uint8_t *data, size_t length); |
Pawel Zarembski |
0:01f31e923fe2 | 58 | |
Pawel Zarembski |
0:01f31e923fe2 | 59 | /*! |
Pawel Zarembski |
0:01f31e923fe2 | 60 | * @brief Write to TX register using non-blocking method. |
Pawel Zarembski |
0:01f31e923fe2 | 61 | * |
Pawel Zarembski |
0:01f31e923fe2 | 62 | * This function writes data to the TX register directly, upper layer must make |
Pawel Zarembski |
0:01f31e923fe2 | 63 | * sure the TX register is empty or TX FIFO has empty room before calling this function. |
Pawel Zarembski |
0:01f31e923fe2 | 64 | * |
Pawel Zarembski |
0:01f31e923fe2 | 65 | * @note This function does not check whether all the data has been sent out to bus, |
Pawel Zarembski |
0:01f31e923fe2 | 66 | * so before disable TX, check kUART_TransmissionCompleteFlag to ensure the TX is |
Pawel Zarembski |
0:01f31e923fe2 | 67 | * finished. |
Pawel Zarembski |
0:01f31e923fe2 | 68 | * |
Pawel Zarembski |
0:01f31e923fe2 | 69 | * @param base UART peripheral base address. |
Pawel Zarembski |
0:01f31e923fe2 | 70 | * @param data Start address of the data to write. |
Pawel Zarembski |
0:01f31e923fe2 | 71 | * @param length Size of the buffer to be sent. |
Pawel Zarembski |
0:01f31e923fe2 | 72 | */ |
Pawel Zarembski |
0:01f31e923fe2 | 73 | static void UART_WriteNonBlocking(UART_Type *base, const uint8_t *data, size_t length); |
Pawel Zarembski |
0:01f31e923fe2 | 74 | |
Pawel Zarembski |
0:01f31e923fe2 | 75 | /******************************************************************************* |
Pawel Zarembski |
0:01f31e923fe2 | 76 | * Variables |
Pawel Zarembski |
0:01f31e923fe2 | 77 | ******************************************************************************/ |
Pawel Zarembski |
0:01f31e923fe2 | 78 | /* Array of UART handle. */ |
Pawel Zarembski |
0:01f31e923fe2 | 79 | #if (defined(UART5)) |
Pawel Zarembski |
0:01f31e923fe2 | 80 | #define UART_HANDLE_ARRAY_SIZE 6 |
Pawel Zarembski |
0:01f31e923fe2 | 81 | #else /* UART5 */ |
Pawel Zarembski |
0:01f31e923fe2 | 82 | #if (defined(UART4)) |
Pawel Zarembski |
0:01f31e923fe2 | 83 | #define UART_HANDLE_ARRAY_SIZE 5 |
Pawel Zarembski |
0:01f31e923fe2 | 84 | #else /* UART4 */ |
Pawel Zarembski |
0:01f31e923fe2 | 85 | #if (defined(UART3)) |
Pawel Zarembski |
0:01f31e923fe2 | 86 | #define UART_HANDLE_ARRAY_SIZE 4 |
Pawel Zarembski |
0:01f31e923fe2 | 87 | #else /* UART3 */ |
Pawel Zarembski |
0:01f31e923fe2 | 88 | #if (defined(UART2)) |
Pawel Zarembski |
0:01f31e923fe2 | 89 | #define UART_HANDLE_ARRAY_SIZE 3 |
Pawel Zarembski |
0:01f31e923fe2 | 90 | #else /* UART2 */ |
Pawel Zarembski |
0:01f31e923fe2 | 91 | #if (defined(UART1)) |
Pawel Zarembski |
0:01f31e923fe2 | 92 | #define UART_HANDLE_ARRAY_SIZE 2 |
Pawel Zarembski |
0:01f31e923fe2 | 93 | #else /* UART1 */ |
Pawel Zarembski |
0:01f31e923fe2 | 94 | #if (defined(UART0)) |
Pawel Zarembski |
0:01f31e923fe2 | 95 | #define UART_HANDLE_ARRAY_SIZE 1 |
Pawel Zarembski |
0:01f31e923fe2 | 96 | #else /* UART0 */ |
Pawel Zarembski |
0:01f31e923fe2 | 97 | #error No UART instance. |
Pawel Zarembski |
0:01f31e923fe2 | 98 | #endif /* UART 0 */ |
Pawel Zarembski |
0:01f31e923fe2 | 99 | #endif /* UART 1 */ |
Pawel Zarembski |
0:01f31e923fe2 | 100 | #endif /* UART 2 */ |
Pawel Zarembski |
0:01f31e923fe2 | 101 | #endif /* UART 3 */ |
Pawel Zarembski |
0:01f31e923fe2 | 102 | #endif /* UART 4 */ |
Pawel Zarembski |
0:01f31e923fe2 | 103 | #endif /* UART 5 */ |
Pawel Zarembski |
0:01f31e923fe2 | 104 | static uart_handle_t *s_uartHandle[UART_HANDLE_ARRAY_SIZE]; |
Pawel Zarembski |
0:01f31e923fe2 | 105 | /* Array of UART peripheral base address. */ |
Pawel Zarembski |
0:01f31e923fe2 | 106 | static UART_Type *const s_uartBases[] = UART_BASE_PTRS; |
Pawel Zarembski |
0:01f31e923fe2 | 107 | |
Pawel Zarembski |
0:01f31e923fe2 | 108 | /* Array of UART IRQ number. */ |
Pawel Zarembski |
0:01f31e923fe2 | 109 | static const IRQn_Type s_uartIRQ[] = UART_RX_TX_IRQS; |
Pawel Zarembski |
0:01f31e923fe2 | 110 | #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) |
Pawel Zarembski |
0:01f31e923fe2 | 111 | /* Array of UART clock name. */ |
Pawel Zarembski |
0:01f31e923fe2 | 112 | static const clock_ip_name_t s_uartClock[] = UART_CLOCKS; |
Pawel Zarembski |
0:01f31e923fe2 | 113 | #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ |
Pawel Zarembski |
0:01f31e923fe2 | 114 | |
Pawel Zarembski |
0:01f31e923fe2 | 115 | /* UART ISR for transactional APIs. */ |
Pawel Zarembski |
0:01f31e923fe2 | 116 | static uart_isr_t s_uartIsr; |
Pawel Zarembski |
0:01f31e923fe2 | 117 | |
Pawel Zarembski |
0:01f31e923fe2 | 118 | /******************************************************************************* |
Pawel Zarembski |
0:01f31e923fe2 | 119 | * Code |
Pawel Zarembski |
0:01f31e923fe2 | 120 | ******************************************************************************/ |
Pawel Zarembski |
0:01f31e923fe2 | 121 | |
Pawel Zarembski |
0:01f31e923fe2 | 122 | /*! |
Pawel Zarembski |
0:01f31e923fe2 | 123 | * brief Get the UART instance from peripheral base address. |
Pawel Zarembski |
0:01f31e923fe2 | 124 | * |
Pawel Zarembski |
0:01f31e923fe2 | 125 | * param base UART peripheral base address. |
Pawel Zarembski |
0:01f31e923fe2 | 126 | * return UART instance. |
Pawel Zarembski |
0:01f31e923fe2 | 127 | */ |
Pawel Zarembski |
0:01f31e923fe2 | 128 | uint32_t UART_GetInstance(UART_Type *base) |
Pawel Zarembski |
0:01f31e923fe2 | 129 | { |
Pawel Zarembski |
0:01f31e923fe2 | 130 | uint32_t instance; |
Pawel Zarembski |
0:01f31e923fe2 | 131 | uint32_t uartArrayCount = (sizeof(s_uartBases) / sizeof(s_uartBases[0])); |
Pawel Zarembski |
0:01f31e923fe2 | 132 | |
Pawel Zarembski |
0:01f31e923fe2 | 133 | /* Find the instance index from base address mappings. */ |
Pawel Zarembski |
0:01f31e923fe2 | 134 | for (instance = 0; instance < uartArrayCount; instance++) |
Pawel Zarembski |
0:01f31e923fe2 | 135 | { |
Pawel Zarembski |
0:01f31e923fe2 | 136 | if (s_uartBases[instance] == base) |
Pawel Zarembski |
0:01f31e923fe2 | 137 | { |
Pawel Zarembski |
0:01f31e923fe2 | 138 | break; |
Pawel Zarembski |
0:01f31e923fe2 | 139 | } |
Pawel Zarembski |
0:01f31e923fe2 | 140 | } |
Pawel Zarembski |
0:01f31e923fe2 | 141 | |
Pawel Zarembski |
0:01f31e923fe2 | 142 | assert(instance < uartArrayCount); |
Pawel Zarembski |
0:01f31e923fe2 | 143 | |
Pawel Zarembski |
0:01f31e923fe2 | 144 | return instance; |
Pawel Zarembski |
0:01f31e923fe2 | 145 | } |
Pawel Zarembski |
0:01f31e923fe2 | 146 | |
Pawel Zarembski |
0:01f31e923fe2 | 147 | /*! |
Pawel Zarembski |
0:01f31e923fe2 | 148 | * brief Get the length of received data in RX ring buffer. |
Pawel Zarembski |
0:01f31e923fe2 | 149 | * |
Pawel Zarembski |
0:01f31e923fe2 | 150 | * param handle UART handle pointer. |
Pawel Zarembski |
0:01f31e923fe2 | 151 | * return Length of received data in RX ring buffer. |
Pawel Zarembski |
0:01f31e923fe2 | 152 | */ |
Pawel Zarembski |
0:01f31e923fe2 | 153 | size_t UART_TransferGetRxRingBufferLength(uart_handle_t *handle) |
Pawel Zarembski |
0:01f31e923fe2 | 154 | { |
Pawel Zarembski |
0:01f31e923fe2 | 155 | assert(handle); |
Pawel Zarembski |
0:01f31e923fe2 | 156 | |
Pawel Zarembski |
0:01f31e923fe2 | 157 | size_t size; |
Pawel Zarembski |
0:01f31e923fe2 | 158 | |
Pawel Zarembski |
0:01f31e923fe2 | 159 | if (handle->rxRingBufferTail > handle->rxRingBufferHead) |
Pawel Zarembski |
0:01f31e923fe2 | 160 | { |
Pawel Zarembski |
0:01f31e923fe2 | 161 | size = (size_t)(handle->rxRingBufferHead + handle->rxRingBufferSize - handle->rxRingBufferTail); |
Pawel Zarembski |
0:01f31e923fe2 | 162 | } |
Pawel Zarembski |
0:01f31e923fe2 | 163 | else |
Pawel Zarembski |
0:01f31e923fe2 | 164 | { |
Pawel Zarembski |
0:01f31e923fe2 | 165 | size = (size_t)(handle->rxRingBufferHead - handle->rxRingBufferTail); |
Pawel Zarembski |
0:01f31e923fe2 | 166 | } |
Pawel Zarembski |
0:01f31e923fe2 | 167 | |
Pawel Zarembski |
0:01f31e923fe2 | 168 | return size; |
Pawel Zarembski |
0:01f31e923fe2 | 169 | } |
Pawel Zarembski |
0:01f31e923fe2 | 170 | |
Pawel Zarembski |
0:01f31e923fe2 | 171 | static bool UART_TransferIsRxRingBufferFull(uart_handle_t *handle) |
Pawel Zarembski |
0:01f31e923fe2 | 172 | { |
Pawel Zarembski |
0:01f31e923fe2 | 173 | assert(handle); |
Pawel Zarembski |
0:01f31e923fe2 | 174 | |
Pawel Zarembski |
0:01f31e923fe2 | 175 | bool full; |
Pawel Zarembski |
0:01f31e923fe2 | 176 | |
Pawel Zarembski |
0:01f31e923fe2 | 177 | if (UART_TransferGetRxRingBufferLength(handle) == (handle->rxRingBufferSize - 1U)) |
Pawel Zarembski |
0:01f31e923fe2 | 178 | { |
Pawel Zarembski |
0:01f31e923fe2 | 179 | full = true; |
Pawel Zarembski |
0:01f31e923fe2 | 180 | } |
Pawel Zarembski |
0:01f31e923fe2 | 181 | else |
Pawel Zarembski |
0:01f31e923fe2 | 182 | { |
Pawel Zarembski |
0:01f31e923fe2 | 183 | full = false; |
Pawel Zarembski |
0:01f31e923fe2 | 184 | } |
Pawel Zarembski |
0:01f31e923fe2 | 185 | |
Pawel Zarembski |
0:01f31e923fe2 | 186 | return full; |
Pawel Zarembski |
0:01f31e923fe2 | 187 | } |
Pawel Zarembski |
0:01f31e923fe2 | 188 | |
Pawel Zarembski |
0:01f31e923fe2 | 189 | /*! |
Pawel Zarembski |
0:01f31e923fe2 | 190 | * brief Initializes a UART instance with a user configuration structure and peripheral clock. |
Pawel Zarembski |
0:01f31e923fe2 | 191 | * |
Pawel Zarembski |
0:01f31e923fe2 | 192 | * This function configures the UART module with the user-defined settings. The user can configure the configuration |
Pawel Zarembski |
0:01f31e923fe2 | 193 | * structure and also get the default configuration by using the UART_GetDefaultConfig() function. |
Pawel Zarembski |
0:01f31e923fe2 | 194 | * The example below shows how to use this API to configure UART. |
Pawel Zarembski |
0:01f31e923fe2 | 195 | * code |
Pawel Zarembski |
0:01f31e923fe2 | 196 | * uart_config_t uartConfig; |
Pawel Zarembski |
0:01f31e923fe2 | 197 | * uartConfig.baudRate_Bps = 115200U; |
Pawel Zarembski |
0:01f31e923fe2 | 198 | * uartConfig.parityMode = kUART_ParityDisabled; |
Pawel Zarembski |
0:01f31e923fe2 | 199 | * uartConfig.stopBitCount = kUART_OneStopBit; |
Pawel Zarembski |
0:01f31e923fe2 | 200 | * uartConfig.txFifoWatermark = 0; |
Pawel Zarembski |
0:01f31e923fe2 | 201 | * uartConfig.rxFifoWatermark = 1; |
Pawel Zarembski |
0:01f31e923fe2 | 202 | * UART_Init(UART1, &uartConfig, 20000000U); |
Pawel Zarembski |
0:01f31e923fe2 | 203 | * endcode |
Pawel Zarembski |
0:01f31e923fe2 | 204 | * |
Pawel Zarembski |
0:01f31e923fe2 | 205 | * param base UART peripheral base address. |
Pawel Zarembski |
0:01f31e923fe2 | 206 | * param config Pointer to the user-defined configuration structure. |
Pawel Zarembski |
0:01f31e923fe2 | 207 | * param srcClock_Hz UART clock source frequency in HZ. |
Pawel Zarembski |
0:01f31e923fe2 | 208 | * retval kStatus_UART_BaudrateNotSupport Baudrate is not support in current clock source. |
Pawel Zarembski |
0:01f31e923fe2 | 209 | * retval kStatus_Success Status UART initialize succeed |
Pawel Zarembski |
0:01f31e923fe2 | 210 | */ |
Pawel Zarembski |
0:01f31e923fe2 | 211 | status_t UART_Init(UART_Type *base, const uart_config_t *config, uint32_t srcClock_Hz) |
Pawel Zarembski |
0:01f31e923fe2 | 212 | { |
Pawel Zarembski |
0:01f31e923fe2 | 213 | assert(config); |
Pawel Zarembski |
0:01f31e923fe2 | 214 | assert(config->baudRate_Bps); |
Pawel Zarembski |
0:01f31e923fe2 | 215 | #if defined(FSL_FEATURE_UART_HAS_FIFO) && FSL_FEATURE_UART_HAS_FIFO |
Pawel Zarembski |
0:01f31e923fe2 | 216 | assert(FSL_FEATURE_UART_FIFO_SIZEn(base) >= config->txFifoWatermark); |
Pawel Zarembski |
0:01f31e923fe2 | 217 | assert(FSL_FEATURE_UART_FIFO_SIZEn(base) >= config->rxFifoWatermark); |
Pawel Zarembski |
0:01f31e923fe2 | 218 | #endif |
Pawel Zarembski |
0:01f31e923fe2 | 219 | |
Pawel Zarembski |
0:01f31e923fe2 | 220 | uint16_t sbr = 0; |
Pawel Zarembski |
0:01f31e923fe2 | 221 | uint8_t temp = 0; |
Pawel Zarembski |
0:01f31e923fe2 | 222 | uint32_t baudDiff = 0; |
Pawel Zarembski |
0:01f31e923fe2 | 223 | |
Pawel Zarembski |
0:01f31e923fe2 | 224 | /* Calculate the baud rate modulo divisor, sbr*/ |
Pawel Zarembski |
0:01f31e923fe2 | 225 | sbr = srcClock_Hz / (config->baudRate_Bps * 16); |
Pawel Zarembski |
0:01f31e923fe2 | 226 | /* set sbrTemp to 1 if the sourceClockInHz can not satisfy the desired baud rate */ |
Pawel Zarembski |
0:01f31e923fe2 | 227 | if (sbr == 0) |
Pawel Zarembski |
0:01f31e923fe2 | 228 | { |
Pawel Zarembski |
0:01f31e923fe2 | 229 | sbr = 1; |
Pawel Zarembski |
0:01f31e923fe2 | 230 | } |
Pawel Zarembski |
0:01f31e923fe2 | 231 | #if defined(FSL_FEATURE_UART_HAS_BAUD_RATE_FINE_ADJUST_SUPPORT) && FSL_FEATURE_UART_HAS_BAUD_RATE_FINE_ADJUST_SUPPORT |
Pawel Zarembski |
0:01f31e923fe2 | 232 | /* Determine if a fractional divider is needed to fine tune closer to the |
Pawel Zarembski |
0:01f31e923fe2 | 233 | * desired baud, each value of brfa is in 1/32 increments, |
Pawel Zarembski |
0:01f31e923fe2 | 234 | * hence the multiply-by-32. */ |
Pawel Zarembski |
0:01f31e923fe2 | 235 | uint32_t tempBaud = 0; |
Pawel Zarembski |
0:01f31e923fe2 | 236 | |
Pawel Zarembski |
0:01f31e923fe2 | 237 | uint16_t brfa = (2 * srcClock_Hz / (config->baudRate_Bps)) - 32 * sbr; |
Pawel Zarembski |
0:01f31e923fe2 | 238 | |
Pawel Zarembski |
0:01f31e923fe2 | 239 | /* Calculate the baud rate based on the temporary SBR values and BRFA */ |
Pawel Zarembski |
0:01f31e923fe2 | 240 | tempBaud = (srcClock_Hz * 2 / ((sbr * 32 + brfa))); |
Pawel Zarembski |
0:01f31e923fe2 | 241 | baudDiff = |
Pawel Zarembski |
0:01f31e923fe2 | 242 | (tempBaud > config->baudRate_Bps) ? (tempBaud - config->baudRate_Bps) : (config->baudRate_Bps - tempBaud); |
Pawel Zarembski |
0:01f31e923fe2 | 243 | |
Pawel Zarembski |
0:01f31e923fe2 | 244 | #else |
Pawel Zarembski |
0:01f31e923fe2 | 245 | /* Calculate the baud rate based on the temporary SBR values */ |
Pawel Zarembski |
0:01f31e923fe2 | 246 | baudDiff = (srcClock_Hz / (sbr * 16)) - config->baudRate_Bps; |
Pawel Zarembski |
0:01f31e923fe2 | 247 | |
Pawel Zarembski |
0:01f31e923fe2 | 248 | /* Select the better value between sbr and (sbr + 1) */ |
Pawel Zarembski |
0:01f31e923fe2 | 249 | if (baudDiff > (config->baudRate_Bps - (srcClock_Hz / (16 * (sbr + 1))))) |
Pawel Zarembski |
0:01f31e923fe2 | 250 | { |
Pawel Zarembski |
0:01f31e923fe2 | 251 | baudDiff = config->baudRate_Bps - (srcClock_Hz / (16 * (sbr + 1))); |
Pawel Zarembski |
0:01f31e923fe2 | 252 | sbr++; |
Pawel Zarembski |
0:01f31e923fe2 | 253 | } |
Pawel Zarembski |
0:01f31e923fe2 | 254 | #endif |
Pawel Zarembski |
0:01f31e923fe2 | 255 | |
Pawel Zarembski |
0:01f31e923fe2 | 256 | /* next, check to see if actual baud rate is within 3% of desired baud rate |
Pawel Zarembski |
0:01f31e923fe2 | 257 | * based on the calculate SBR value */ |
Pawel Zarembski |
0:01f31e923fe2 | 258 | if (baudDiff > ((config->baudRate_Bps / 100) * 3)) |
Pawel Zarembski |
0:01f31e923fe2 | 259 | { |
Pawel Zarembski |
0:01f31e923fe2 | 260 | /* Unacceptable baud rate difference of more than 3%*/ |
Pawel Zarembski |
0:01f31e923fe2 | 261 | return kStatus_UART_BaudrateNotSupport; |
Pawel Zarembski |
0:01f31e923fe2 | 262 | } |
Pawel Zarembski |
0:01f31e923fe2 | 263 | |
Pawel Zarembski |
0:01f31e923fe2 | 264 | #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) |
Pawel Zarembski |
0:01f31e923fe2 | 265 | /* Enable uart clock */ |
Pawel Zarembski |
0:01f31e923fe2 | 266 | CLOCK_EnableClock(s_uartClock[UART_GetInstance(base)]); |
Pawel Zarembski |
0:01f31e923fe2 | 267 | #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ |
Pawel Zarembski |
0:01f31e923fe2 | 268 | |
Pawel Zarembski |
0:01f31e923fe2 | 269 | /* Disable UART TX RX before setting. */ |
Pawel Zarembski |
0:01f31e923fe2 | 270 | base->C2 &= ~(UART_C2_TE_MASK | UART_C2_RE_MASK); |
Pawel Zarembski |
0:01f31e923fe2 | 271 | |
Pawel Zarembski |
0:01f31e923fe2 | 272 | /* Write the sbr value to the BDH and BDL registers*/ |
Pawel Zarembski |
0:01f31e923fe2 | 273 | base->BDH = (base->BDH & ~UART_BDH_SBR_MASK) | (uint8_t)(sbr >> 8); |
Pawel Zarembski |
0:01f31e923fe2 | 274 | base->BDL = (uint8_t)sbr; |
Pawel Zarembski |
0:01f31e923fe2 | 275 | |
Pawel Zarembski |
0:01f31e923fe2 | 276 | #if defined(FSL_FEATURE_UART_HAS_BAUD_RATE_FINE_ADJUST_SUPPORT) && FSL_FEATURE_UART_HAS_BAUD_RATE_FINE_ADJUST_SUPPORT |
Pawel Zarembski |
0:01f31e923fe2 | 277 | /* Write the brfa value to the register*/ |
Pawel Zarembski |
0:01f31e923fe2 | 278 | base->C4 = (base->C4 & ~UART_C4_BRFA_MASK) | (brfa & UART_C4_BRFA_MASK); |
Pawel Zarembski |
0:01f31e923fe2 | 279 | #endif |
Pawel Zarembski |
0:01f31e923fe2 | 280 | |
Pawel Zarembski |
0:01f31e923fe2 | 281 | /* Set bit count/parity mode/idle type. */ |
Pawel Zarembski |
0:01f31e923fe2 | 282 | temp = base->C1 & ~(UART_C1_PE_MASK | UART_C1_PT_MASK | UART_C1_M_MASK | UART_C1_ILT_MASK); |
Pawel Zarembski |
0:01f31e923fe2 | 283 | |
Pawel Zarembski |
0:01f31e923fe2 | 284 | temp |= UART_C1_ILT(config->idleType); |
Pawel Zarembski |
0:01f31e923fe2 | 285 | |
Pawel Zarembski |
0:01f31e923fe2 | 286 | if (kUART_ParityDisabled != config->parityMode) |
Pawel Zarembski |
0:01f31e923fe2 | 287 | { |
Pawel Zarembski |
0:01f31e923fe2 | 288 | temp |= (UART_C1_M_MASK | (uint8_t)config->parityMode); |
Pawel Zarembski |
0:01f31e923fe2 | 289 | } |
Pawel Zarembski |
0:01f31e923fe2 | 290 | |
Pawel Zarembski |
0:01f31e923fe2 | 291 | base->C1 = temp; |
Pawel Zarembski |
0:01f31e923fe2 | 292 | |
Pawel Zarembski |
0:01f31e923fe2 | 293 | #if defined(FSL_FEATURE_UART_HAS_STOP_BIT_CONFIG_SUPPORT) && FSL_FEATURE_UART_HAS_STOP_BIT_CONFIG_SUPPORT |
Pawel Zarembski |
0:01f31e923fe2 | 294 | /* Set stop bit per char */ |
Pawel Zarembski |
0:01f31e923fe2 | 295 | base->BDH = (base->BDH & ~UART_BDH_SBNS_MASK) | UART_BDH_SBNS((uint8_t)config->stopBitCount); |
Pawel Zarembski |
0:01f31e923fe2 | 296 | #endif |
Pawel Zarembski |
0:01f31e923fe2 | 297 | |
Pawel Zarembski |
0:01f31e923fe2 | 298 | #if defined(FSL_FEATURE_UART_HAS_FIFO) && FSL_FEATURE_UART_HAS_FIFO |
Pawel Zarembski |
0:01f31e923fe2 | 299 | /* Set tx/rx FIFO watermark |
Pawel Zarembski |
0:01f31e923fe2 | 300 | Note: |
Pawel Zarembski |
0:01f31e923fe2 | 301 | Take care of the RX FIFO, RX interrupt request only assert when received bytes |
Pawel Zarembski |
0:01f31e923fe2 | 302 | equal or more than RX water mark, there is potential issue if RX water |
Pawel Zarembski |
0:01f31e923fe2 | 303 | mark larger than 1. |
Pawel Zarembski |
0:01f31e923fe2 | 304 | For example, if RX FIFO water mark is 2, upper layer needs 5 bytes and |
Pawel Zarembski |
0:01f31e923fe2 | 305 | 5 bytes are received. the last byte will be saved in FIFO but not trigger |
Pawel Zarembski |
0:01f31e923fe2 | 306 | RX interrupt because the water mark is 2. |
Pawel Zarembski |
0:01f31e923fe2 | 307 | */ |
Pawel Zarembski |
0:01f31e923fe2 | 308 | base->TWFIFO = config->txFifoWatermark; |
Pawel Zarembski |
0:01f31e923fe2 | 309 | base->RWFIFO = config->rxFifoWatermark; |
Pawel Zarembski |
0:01f31e923fe2 | 310 | |
Pawel Zarembski |
0:01f31e923fe2 | 311 | /* Enable tx/rx FIFO */ |
Pawel Zarembski |
0:01f31e923fe2 | 312 | base->PFIFO |= (UART_PFIFO_TXFE_MASK | UART_PFIFO_RXFE_MASK); |
Pawel Zarembski |
0:01f31e923fe2 | 313 | |
Pawel Zarembski |
0:01f31e923fe2 | 314 | /* Flush FIFO */ |
Pawel Zarembski |
0:01f31e923fe2 | 315 | base->CFIFO |= (UART_CFIFO_TXFLUSH_MASK | UART_CFIFO_RXFLUSH_MASK); |
Pawel Zarembski |
0:01f31e923fe2 | 316 | #endif |
Pawel Zarembski |
0:01f31e923fe2 | 317 | #if defined(FSL_FEATURE_UART_HAS_MODEM_SUPPORT) && FSL_FEATURE_UART_HAS_MODEM_SUPPORT |
Pawel Zarembski |
0:01f31e923fe2 | 318 | if (config->enableRxRTS) |
Pawel Zarembski |
0:01f31e923fe2 | 319 | { |
Pawel Zarembski |
0:01f31e923fe2 | 320 | /* Enable receiver RTS(request-to-send) function. */ |
Pawel Zarembski |
0:01f31e923fe2 | 321 | base->MODEM |= UART_MODEM_RXRTSE_MASK; |
Pawel Zarembski |
0:01f31e923fe2 | 322 | } |
Pawel Zarembski |
0:01f31e923fe2 | 323 | if (config->enableTxCTS) |
Pawel Zarembski |
0:01f31e923fe2 | 324 | { |
Pawel Zarembski |
0:01f31e923fe2 | 325 | /* Enable transmitter CTS(clear-to-send) function. */ |
Pawel Zarembski |
0:01f31e923fe2 | 326 | base->MODEM |= UART_MODEM_TXCTSE_MASK; |
Pawel Zarembski |
0:01f31e923fe2 | 327 | } |
Pawel Zarembski |
0:01f31e923fe2 | 328 | #endif |
Pawel Zarembski |
0:01f31e923fe2 | 329 | |
Pawel Zarembski |
0:01f31e923fe2 | 330 | /* Enable TX/RX base on configure structure. */ |
Pawel Zarembski |
0:01f31e923fe2 | 331 | temp = base->C2; |
Pawel Zarembski |
0:01f31e923fe2 | 332 | |
Pawel Zarembski |
0:01f31e923fe2 | 333 | if (config->enableTx) |
Pawel Zarembski |
0:01f31e923fe2 | 334 | { |
Pawel Zarembski |
0:01f31e923fe2 | 335 | temp |= UART_C2_TE_MASK; |
Pawel Zarembski |
0:01f31e923fe2 | 336 | } |
Pawel Zarembski |
0:01f31e923fe2 | 337 | |
Pawel Zarembski |
0:01f31e923fe2 | 338 | if (config->enableRx) |
Pawel Zarembski |
0:01f31e923fe2 | 339 | { |
Pawel Zarembski |
0:01f31e923fe2 | 340 | temp |= UART_C2_RE_MASK; |
Pawel Zarembski |
0:01f31e923fe2 | 341 | } |
Pawel Zarembski |
0:01f31e923fe2 | 342 | |
Pawel Zarembski |
0:01f31e923fe2 | 343 | base->C2 = temp; |
Pawel Zarembski |
0:01f31e923fe2 | 344 | |
Pawel Zarembski |
0:01f31e923fe2 | 345 | return kStatus_Success; |
Pawel Zarembski |
0:01f31e923fe2 | 346 | } |
Pawel Zarembski |
0:01f31e923fe2 | 347 | |
Pawel Zarembski |
0:01f31e923fe2 | 348 | /*! |
Pawel Zarembski |
0:01f31e923fe2 | 349 | * brief Deinitializes a UART instance. |
Pawel Zarembski |
0:01f31e923fe2 | 350 | * |
Pawel Zarembski |
0:01f31e923fe2 | 351 | * This function waits for TX complete, disables TX and RX, and disables the UART clock. |
Pawel Zarembski |
0:01f31e923fe2 | 352 | * |
Pawel Zarembski |
0:01f31e923fe2 | 353 | * param base UART peripheral base address. |
Pawel Zarembski |
0:01f31e923fe2 | 354 | */ |
Pawel Zarembski |
0:01f31e923fe2 | 355 | void UART_Deinit(UART_Type *base) |
Pawel Zarembski |
0:01f31e923fe2 | 356 | { |
Pawel Zarembski |
0:01f31e923fe2 | 357 | #if defined(FSL_FEATURE_UART_HAS_FIFO) && FSL_FEATURE_UART_HAS_FIFO |
Pawel Zarembski |
0:01f31e923fe2 | 358 | /* Wait tx FIFO send out*/ |
Pawel Zarembski |
0:01f31e923fe2 | 359 | while (0 != base->TCFIFO) |
Pawel Zarembski |
0:01f31e923fe2 | 360 | { |
Pawel Zarembski |
0:01f31e923fe2 | 361 | } |
Pawel Zarembski |
0:01f31e923fe2 | 362 | #endif |
Pawel Zarembski |
0:01f31e923fe2 | 363 | /* Wait last char shoft out */ |
Pawel Zarembski |
0:01f31e923fe2 | 364 | while (0 == (base->S1 & UART_S1_TC_MASK)) |
Pawel Zarembski |
0:01f31e923fe2 | 365 | { |
Pawel Zarembski |
0:01f31e923fe2 | 366 | } |
Pawel Zarembski |
0:01f31e923fe2 | 367 | |
Pawel Zarembski |
0:01f31e923fe2 | 368 | /* Disable the module. */ |
Pawel Zarembski |
0:01f31e923fe2 | 369 | base->C2 = 0; |
Pawel Zarembski |
0:01f31e923fe2 | 370 | |
Pawel Zarembski |
0:01f31e923fe2 | 371 | #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) |
Pawel Zarembski |
0:01f31e923fe2 | 372 | /* Disable uart clock */ |
Pawel Zarembski |
0:01f31e923fe2 | 373 | CLOCK_DisableClock(s_uartClock[UART_GetInstance(base)]); |
Pawel Zarembski |
0:01f31e923fe2 | 374 | #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ |
Pawel Zarembski |
0:01f31e923fe2 | 375 | } |
Pawel Zarembski |
0:01f31e923fe2 | 376 | |
Pawel Zarembski |
0:01f31e923fe2 | 377 | /*! |
Pawel Zarembski |
0:01f31e923fe2 | 378 | * brief Gets the default configuration structure. |
Pawel Zarembski |
0:01f31e923fe2 | 379 | * |
Pawel Zarembski |
0:01f31e923fe2 | 380 | * This function initializes the UART configuration structure to a default value. The default |
Pawel Zarembski |
0:01f31e923fe2 | 381 | * values are as follows. |
Pawel Zarembski |
0:01f31e923fe2 | 382 | * uartConfig->baudRate_Bps = 115200U; |
Pawel Zarembski |
0:01f31e923fe2 | 383 | * uartConfig->bitCountPerChar = kUART_8BitsPerChar; |
Pawel Zarembski |
0:01f31e923fe2 | 384 | * uartConfig->parityMode = kUART_ParityDisabled; |
Pawel Zarembski |
0:01f31e923fe2 | 385 | * uartConfig->stopBitCount = kUART_OneStopBit; |
Pawel Zarembski |
0:01f31e923fe2 | 386 | * uartConfig->txFifoWatermark = 0; |
Pawel Zarembski |
0:01f31e923fe2 | 387 | * uartConfig->rxFifoWatermark = 1; |
Pawel Zarembski |
0:01f31e923fe2 | 388 | * uartConfig->idleType = kUART_IdleTypeStartBit; |
Pawel Zarembski |
0:01f31e923fe2 | 389 | * uartConfig->enableTx = false; |
Pawel Zarembski |
0:01f31e923fe2 | 390 | * uartConfig->enableRx = false; |
Pawel Zarembski |
0:01f31e923fe2 | 391 | * |
Pawel Zarembski |
0:01f31e923fe2 | 392 | * param config Pointer to configuration structure. |
Pawel Zarembski |
0:01f31e923fe2 | 393 | */ |
Pawel Zarembski |
0:01f31e923fe2 | 394 | void UART_GetDefaultConfig(uart_config_t *config) |
Pawel Zarembski |
0:01f31e923fe2 | 395 | { |
Pawel Zarembski |
0:01f31e923fe2 | 396 | assert(config); |
Pawel Zarembski |
0:01f31e923fe2 | 397 | |
Pawel Zarembski |
0:01f31e923fe2 | 398 | /* Initializes the configure structure to zero. */ |
Pawel Zarembski |
0:01f31e923fe2 | 399 | memset(config, 0, sizeof(*config)); |
Pawel Zarembski |
0:01f31e923fe2 | 400 | |
Pawel Zarembski |
0:01f31e923fe2 | 401 | config->baudRate_Bps = 115200U; |
Pawel Zarembski |
0:01f31e923fe2 | 402 | config->parityMode = kUART_ParityDisabled; |
Pawel Zarembski |
0:01f31e923fe2 | 403 | #if defined(FSL_FEATURE_UART_HAS_STOP_BIT_CONFIG_SUPPORT) && FSL_FEATURE_UART_HAS_STOP_BIT_CONFIG_SUPPORT |
Pawel Zarembski |
0:01f31e923fe2 | 404 | config->stopBitCount = kUART_OneStopBit; |
Pawel Zarembski |
0:01f31e923fe2 | 405 | #endif |
Pawel Zarembski |
0:01f31e923fe2 | 406 | #if defined(FSL_FEATURE_UART_HAS_FIFO) && FSL_FEATURE_UART_HAS_FIFO |
Pawel Zarembski |
0:01f31e923fe2 | 407 | config->txFifoWatermark = 0; |
Pawel Zarembski |
0:01f31e923fe2 | 408 | config->rxFifoWatermark = 1; |
Pawel Zarembski |
0:01f31e923fe2 | 409 | #endif |
Pawel Zarembski |
0:01f31e923fe2 | 410 | #if defined(FSL_FEATURE_UART_HAS_MODEM_SUPPORT) && FSL_FEATURE_UART_HAS_MODEM_SUPPORT |
Pawel Zarembski |
0:01f31e923fe2 | 411 | config->enableRxRTS = false; |
Pawel Zarembski |
0:01f31e923fe2 | 412 | config->enableTxCTS = false; |
Pawel Zarembski |
0:01f31e923fe2 | 413 | #endif |
Pawel Zarembski |
0:01f31e923fe2 | 414 | config->idleType = kUART_IdleTypeStartBit; |
Pawel Zarembski |
0:01f31e923fe2 | 415 | config->enableTx = false; |
Pawel Zarembski |
0:01f31e923fe2 | 416 | config->enableRx = false; |
Pawel Zarembski |
0:01f31e923fe2 | 417 | } |
Pawel Zarembski |
0:01f31e923fe2 | 418 | |
Pawel Zarembski |
0:01f31e923fe2 | 419 | /*! |
Pawel Zarembski |
0:01f31e923fe2 | 420 | * brief Sets the UART instance baud rate. |
Pawel Zarembski |
0:01f31e923fe2 | 421 | * |
Pawel Zarembski |
0:01f31e923fe2 | 422 | * This function configures the UART module baud rate. This function is used to update |
Pawel Zarembski |
0:01f31e923fe2 | 423 | * the UART module baud rate after the UART module is initialized by the UART_Init. |
Pawel Zarembski |
0:01f31e923fe2 | 424 | * code |
Pawel Zarembski |
0:01f31e923fe2 | 425 | * UART_SetBaudRate(UART1, 115200U, 20000000U); |
Pawel Zarembski |
0:01f31e923fe2 | 426 | * endcode |
Pawel Zarembski |
0:01f31e923fe2 | 427 | * |
Pawel Zarembski |
0:01f31e923fe2 | 428 | * param base UART peripheral base address. |
Pawel Zarembski |
0:01f31e923fe2 | 429 | * param baudRate_Bps UART baudrate to be set. |
Pawel Zarembski |
0:01f31e923fe2 | 430 | * param srcClock_Hz UART clock source freqency in Hz. |
Pawel Zarembski |
0:01f31e923fe2 | 431 | * retval kStatus_UART_BaudrateNotSupport Baudrate is not support in the current clock source. |
Pawel Zarembski |
0:01f31e923fe2 | 432 | * retval kStatus_Success Set baudrate succeeded. |
Pawel Zarembski |
0:01f31e923fe2 | 433 | */ |
Pawel Zarembski |
0:01f31e923fe2 | 434 | status_t UART_SetBaudRate(UART_Type *base, uint32_t baudRate_Bps, uint32_t srcClock_Hz) |
Pawel Zarembski |
0:01f31e923fe2 | 435 | { |
Pawel Zarembski |
0:01f31e923fe2 | 436 | assert(baudRate_Bps); |
Pawel Zarembski |
0:01f31e923fe2 | 437 | |
Pawel Zarembski |
0:01f31e923fe2 | 438 | uint16_t sbr = 0; |
Pawel Zarembski |
0:01f31e923fe2 | 439 | uint32_t baudDiff = 0; |
Pawel Zarembski |
0:01f31e923fe2 | 440 | uint8_t oldCtrl; |
Pawel Zarembski |
0:01f31e923fe2 | 441 | |
Pawel Zarembski |
0:01f31e923fe2 | 442 | /* Calculate the baud rate modulo divisor, sbr*/ |
Pawel Zarembski |
0:01f31e923fe2 | 443 | sbr = srcClock_Hz / (baudRate_Bps * 16); |
Pawel Zarembski |
0:01f31e923fe2 | 444 | /* set sbrTemp to 1 if the sourceClockInHz can not satisfy the desired baud rate */ |
Pawel Zarembski |
0:01f31e923fe2 | 445 | if (sbr == 0) |
Pawel Zarembski |
0:01f31e923fe2 | 446 | { |
Pawel Zarembski |
0:01f31e923fe2 | 447 | sbr = 1; |
Pawel Zarembski |
0:01f31e923fe2 | 448 | } |
Pawel Zarembski |
0:01f31e923fe2 | 449 | #if defined(FSL_FEATURE_UART_HAS_BAUD_RATE_FINE_ADJUST_SUPPORT) && FSL_FEATURE_UART_HAS_BAUD_RATE_FINE_ADJUST_SUPPORT |
Pawel Zarembski |
0:01f31e923fe2 | 450 | /* Determine if a fractional divider is needed to fine tune closer to the |
Pawel Zarembski |
0:01f31e923fe2 | 451 | * desired baud, each value of brfa is in 1/32 increments, |
Pawel Zarembski |
0:01f31e923fe2 | 452 | * hence the multiply-by-32. */ |
Pawel Zarembski |
0:01f31e923fe2 | 453 | uint32_t tempBaud = 0; |
Pawel Zarembski |
0:01f31e923fe2 | 454 | |
Pawel Zarembski |
0:01f31e923fe2 | 455 | uint16_t brfa = (2 * srcClock_Hz / (baudRate_Bps)) - 32 * sbr; |
Pawel Zarembski |
0:01f31e923fe2 | 456 | |
Pawel Zarembski |
0:01f31e923fe2 | 457 | /* Calculate the baud rate based on the temporary SBR values and BRFA */ |
Pawel Zarembski |
0:01f31e923fe2 | 458 | tempBaud = (srcClock_Hz * 2 / ((sbr * 32 + brfa))); |
Pawel Zarembski |
0:01f31e923fe2 | 459 | baudDiff = (tempBaud > baudRate_Bps) ? (tempBaud - baudRate_Bps) : (baudRate_Bps - tempBaud); |
Pawel Zarembski |
0:01f31e923fe2 | 460 | #else |
Pawel Zarembski |
0:01f31e923fe2 | 461 | /* Calculate the baud rate based on the temporary SBR values */ |
Pawel Zarembski |
0:01f31e923fe2 | 462 | baudDiff = (srcClock_Hz / (sbr * 16)) - baudRate_Bps; |
Pawel Zarembski |
0:01f31e923fe2 | 463 | |
Pawel Zarembski |
0:01f31e923fe2 | 464 | /* Select the better value between sbr and (sbr + 1) */ |
Pawel Zarembski |
0:01f31e923fe2 | 465 | if (baudDiff > (baudRate_Bps - (srcClock_Hz / (16 * (sbr + 1))))) |
Pawel Zarembski |
0:01f31e923fe2 | 466 | { |
Pawel Zarembski |
0:01f31e923fe2 | 467 | baudDiff = baudRate_Bps - (srcClock_Hz / (16 * (sbr + 1))); |
Pawel Zarembski |
0:01f31e923fe2 | 468 | sbr++; |
Pawel Zarembski |
0:01f31e923fe2 | 469 | } |
Pawel Zarembski |
0:01f31e923fe2 | 470 | #endif |
Pawel Zarembski |
0:01f31e923fe2 | 471 | |
Pawel Zarembski |
0:01f31e923fe2 | 472 | /* next, check to see if actual baud rate is within 3% of desired baud rate |
Pawel Zarembski |
0:01f31e923fe2 | 473 | * based on the calculate SBR value */ |
Pawel Zarembski |
0:01f31e923fe2 | 474 | if (baudDiff < ((baudRate_Bps / 100) * 3)) |
Pawel Zarembski |
0:01f31e923fe2 | 475 | { |
Pawel Zarembski |
0:01f31e923fe2 | 476 | /* Store C2 before disable Tx and Rx */ |
Pawel Zarembski |
0:01f31e923fe2 | 477 | oldCtrl = base->C2; |
Pawel Zarembski |
0:01f31e923fe2 | 478 | |
Pawel Zarembski |
0:01f31e923fe2 | 479 | /* Disable UART TX RX before setting. */ |
Pawel Zarembski |
0:01f31e923fe2 | 480 | base->C2 &= ~(UART_C2_TE_MASK | UART_C2_RE_MASK); |
Pawel Zarembski |
0:01f31e923fe2 | 481 | |
Pawel Zarembski |
0:01f31e923fe2 | 482 | /* Write the sbr value to the BDH and BDL registers*/ |
Pawel Zarembski |
0:01f31e923fe2 | 483 | base->BDH = (base->BDH & ~UART_BDH_SBR_MASK) | (uint8_t)(sbr >> 8); |
Pawel Zarembski |
0:01f31e923fe2 | 484 | base->BDL = (uint8_t)sbr; |
Pawel Zarembski |
0:01f31e923fe2 | 485 | |
Pawel Zarembski |
0:01f31e923fe2 | 486 | #if defined(FSL_FEATURE_UART_HAS_BAUD_RATE_FINE_ADJUST_SUPPORT) && FSL_FEATURE_UART_HAS_BAUD_RATE_FINE_ADJUST_SUPPORT |
Pawel Zarembski |
0:01f31e923fe2 | 487 | /* Write the brfa value to the register*/ |
Pawel Zarembski |
0:01f31e923fe2 | 488 | base->C4 = (base->C4 & ~UART_C4_BRFA_MASK) | (brfa & UART_C4_BRFA_MASK); |
Pawel Zarembski |
0:01f31e923fe2 | 489 | #endif |
Pawel Zarembski |
0:01f31e923fe2 | 490 | /* Restore C2. */ |
Pawel Zarembski |
0:01f31e923fe2 | 491 | base->C2 = oldCtrl; |
Pawel Zarembski |
0:01f31e923fe2 | 492 | |
Pawel Zarembski |
0:01f31e923fe2 | 493 | return kStatus_Success; |
Pawel Zarembski |
0:01f31e923fe2 | 494 | } |
Pawel Zarembski |
0:01f31e923fe2 | 495 | else |
Pawel Zarembski |
0:01f31e923fe2 | 496 | { |
Pawel Zarembski |
0:01f31e923fe2 | 497 | /* Unacceptable baud rate difference of more than 3%*/ |
Pawel Zarembski |
0:01f31e923fe2 | 498 | return kStatus_UART_BaudrateNotSupport; |
Pawel Zarembski |
0:01f31e923fe2 | 499 | } |
Pawel Zarembski |
0:01f31e923fe2 | 500 | } |
Pawel Zarembski |
0:01f31e923fe2 | 501 | |
Pawel Zarembski |
0:01f31e923fe2 | 502 | /*! |
Pawel Zarembski |
0:01f31e923fe2 | 503 | * brief Enables UART interrupts according to the provided mask. |
Pawel Zarembski |
0:01f31e923fe2 | 504 | * |
Pawel Zarembski |
0:01f31e923fe2 | 505 | * This function enables the UART interrupts according to the provided mask. The mask |
Pawel Zarembski |
0:01f31e923fe2 | 506 | * is a logical OR of enumeration members. See ref _uart_interrupt_enable. |
Pawel Zarembski |
0:01f31e923fe2 | 507 | * For example, to enable TX empty interrupt and RX full interrupt, do the following. |
Pawel Zarembski |
0:01f31e923fe2 | 508 | * code |
Pawel Zarembski |
0:01f31e923fe2 | 509 | * UART_EnableInterrupts(UART1,kUART_TxDataRegEmptyInterruptEnable | kUART_RxDataRegFullInterruptEnable); |
Pawel Zarembski |
0:01f31e923fe2 | 510 | * endcode |
Pawel Zarembski |
0:01f31e923fe2 | 511 | * |
Pawel Zarembski |
0:01f31e923fe2 | 512 | * param base UART peripheral base address. |
Pawel Zarembski |
0:01f31e923fe2 | 513 | * param mask The interrupts to enable. Logical OR of ref _uart_interrupt_enable. |
Pawel Zarembski |
0:01f31e923fe2 | 514 | */ |
Pawel Zarembski |
0:01f31e923fe2 | 515 | void UART_EnableInterrupts(UART_Type *base, uint32_t mask) |
Pawel Zarembski |
0:01f31e923fe2 | 516 | { |
Pawel Zarembski |
0:01f31e923fe2 | 517 | mask &= kUART_AllInterruptsEnable; |
Pawel Zarembski |
0:01f31e923fe2 | 518 | |
Pawel Zarembski |
0:01f31e923fe2 | 519 | /* The interrupt mask is combined by control bits from several register: ((CFIFO<<24) | (C3<<16) | (C2<<8) |(BDH)) |
Pawel Zarembski |
0:01f31e923fe2 | 520 | */ |
Pawel Zarembski |
0:01f31e923fe2 | 521 | base->BDH |= mask; |
Pawel Zarembski |
0:01f31e923fe2 | 522 | base->C2 |= (mask >> 8); |
Pawel Zarembski |
0:01f31e923fe2 | 523 | base->C3 |= (mask >> 16); |
Pawel Zarembski |
0:01f31e923fe2 | 524 | |
Pawel Zarembski |
0:01f31e923fe2 | 525 | #if defined(FSL_FEATURE_UART_HAS_FIFO) && FSL_FEATURE_UART_HAS_FIFO |
Pawel Zarembski |
0:01f31e923fe2 | 526 | base->CFIFO |= (mask >> 24); |
Pawel Zarembski |
0:01f31e923fe2 | 527 | #endif |
Pawel Zarembski |
0:01f31e923fe2 | 528 | } |
Pawel Zarembski |
0:01f31e923fe2 | 529 | |
Pawel Zarembski |
0:01f31e923fe2 | 530 | /*! |
Pawel Zarembski |
0:01f31e923fe2 | 531 | * brief Disables the UART interrupts according to the provided mask. |
Pawel Zarembski |
0:01f31e923fe2 | 532 | * |
Pawel Zarembski |
0:01f31e923fe2 | 533 | * This function disables the UART interrupts according to the provided mask. The mask |
Pawel Zarembski |
0:01f31e923fe2 | 534 | * is a logical OR of enumeration members. See ref _uart_interrupt_enable. |
Pawel Zarembski |
0:01f31e923fe2 | 535 | * For example, to disable TX empty interrupt and RX full interrupt do the following. |
Pawel Zarembski |
0:01f31e923fe2 | 536 | * code |
Pawel Zarembski |
0:01f31e923fe2 | 537 | * UART_DisableInterrupts(UART1,kUART_TxDataRegEmptyInterruptEnable | kUART_RxDataRegFullInterruptEnable); |
Pawel Zarembski |
0:01f31e923fe2 | 538 | * endcode |
Pawel Zarembski |
0:01f31e923fe2 | 539 | * |
Pawel Zarembski |
0:01f31e923fe2 | 540 | * param base UART peripheral base address. |
Pawel Zarembski |
0:01f31e923fe2 | 541 | * param mask The interrupts to disable. Logical OR of ref _uart_interrupt_enable. |
Pawel Zarembski |
0:01f31e923fe2 | 542 | */ |
Pawel Zarembski |
0:01f31e923fe2 | 543 | void UART_DisableInterrupts(UART_Type *base, uint32_t mask) |
Pawel Zarembski |
0:01f31e923fe2 | 544 | { |
Pawel Zarembski |
0:01f31e923fe2 | 545 | mask &= kUART_AllInterruptsEnable; |
Pawel Zarembski |
0:01f31e923fe2 | 546 | |
Pawel Zarembski |
0:01f31e923fe2 | 547 | /* The interrupt mask is combined by control bits from several register: ((CFIFO<<24) | (C3<<16) | (C2<<8) |(BDH)) |
Pawel Zarembski |
0:01f31e923fe2 | 548 | */ |
Pawel Zarembski |
0:01f31e923fe2 | 549 | base->BDH &= ~mask; |
Pawel Zarembski |
0:01f31e923fe2 | 550 | base->C2 &= ~(mask >> 8); |
Pawel Zarembski |
0:01f31e923fe2 | 551 | base->C3 &= ~(mask >> 16); |
Pawel Zarembski |
0:01f31e923fe2 | 552 | |
Pawel Zarembski |
0:01f31e923fe2 | 553 | #if defined(FSL_FEATURE_UART_HAS_FIFO) && FSL_FEATURE_UART_HAS_FIFO |
Pawel Zarembski |
0:01f31e923fe2 | 554 | base->CFIFO &= ~(mask >> 24); |
Pawel Zarembski |
0:01f31e923fe2 | 555 | #endif |
Pawel Zarembski |
0:01f31e923fe2 | 556 | } |
Pawel Zarembski |
0:01f31e923fe2 | 557 | |
Pawel Zarembski |
0:01f31e923fe2 | 558 | /*! |
Pawel Zarembski |
0:01f31e923fe2 | 559 | * brief Gets the enabled UART interrupts. |
Pawel Zarembski |
0:01f31e923fe2 | 560 | * |
Pawel Zarembski |
0:01f31e923fe2 | 561 | * This function gets the enabled UART interrupts. The enabled interrupts are returned |
Pawel Zarembski |
0:01f31e923fe2 | 562 | * as the logical OR value of the enumerators ref _uart_interrupt_enable. To check |
Pawel Zarembski |
0:01f31e923fe2 | 563 | * a specific interrupts enable status, compare the return value with enumerators |
Pawel Zarembski |
0:01f31e923fe2 | 564 | * in ref _uart_interrupt_enable. |
Pawel Zarembski |
0:01f31e923fe2 | 565 | * For example, to check whether TX empty interrupt is enabled, do the following. |
Pawel Zarembski |
0:01f31e923fe2 | 566 | * code |
Pawel Zarembski |
0:01f31e923fe2 | 567 | * uint32_t enabledInterrupts = UART_GetEnabledInterrupts(UART1); |
Pawel Zarembski |
0:01f31e923fe2 | 568 | * |
Pawel Zarembski |
0:01f31e923fe2 | 569 | * if (kUART_TxDataRegEmptyInterruptEnable & enabledInterrupts) |
Pawel Zarembski |
0:01f31e923fe2 | 570 | * { |
Pawel Zarembski |
0:01f31e923fe2 | 571 | * ... |
Pawel Zarembski |
0:01f31e923fe2 | 572 | * } |
Pawel Zarembski |
0:01f31e923fe2 | 573 | * endcode |
Pawel Zarembski |
0:01f31e923fe2 | 574 | * |
Pawel Zarembski |
0:01f31e923fe2 | 575 | * param base UART peripheral base address. |
Pawel Zarembski |
0:01f31e923fe2 | 576 | * return UART interrupt flags which are logical OR of the enumerators in ref _uart_interrupt_enable. |
Pawel Zarembski |
0:01f31e923fe2 | 577 | */ |
Pawel Zarembski |
0:01f31e923fe2 | 578 | uint32_t UART_GetEnabledInterrupts(UART_Type *base) |
Pawel Zarembski |
0:01f31e923fe2 | 579 | { |
Pawel Zarembski |
0:01f31e923fe2 | 580 | uint32_t temp; |
Pawel Zarembski |
0:01f31e923fe2 | 581 | |
Pawel Zarembski |
0:01f31e923fe2 | 582 | temp = base->BDH | ((uint32_t)(base->C2) << 8) | ((uint32_t)(base->C3) << 16); |
Pawel Zarembski |
0:01f31e923fe2 | 583 | |
Pawel Zarembski |
0:01f31e923fe2 | 584 | #if defined(FSL_FEATURE_UART_HAS_FIFO) && FSL_FEATURE_UART_HAS_FIFO |
Pawel Zarembski |
0:01f31e923fe2 | 585 | temp |= ((uint32_t)(base->CFIFO) << 24); |
Pawel Zarembski |
0:01f31e923fe2 | 586 | #endif |
Pawel Zarembski |
0:01f31e923fe2 | 587 | |
Pawel Zarembski |
0:01f31e923fe2 | 588 | return temp & kUART_AllInterruptsEnable; |
Pawel Zarembski |
0:01f31e923fe2 | 589 | } |
Pawel Zarembski |
0:01f31e923fe2 | 590 | |
Pawel Zarembski |
0:01f31e923fe2 | 591 | /*! |
Pawel Zarembski |
0:01f31e923fe2 | 592 | * brief Gets UART status flags. |
Pawel Zarembski |
0:01f31e923fe2 | 593 | * |
Pawel Zarembski |
0:01f31e923fe2 | 594 | * This function gets all UART status flags. The flags are returned as the logical |
Pawel Zarembski |
0:01f31e923fe2 | 595 | * OR value of the enumerators ref _uart_flags. To check a specific status, |
Pawel Zarembski |
0:01f31e923fe2 | 596 | * compare the return value with enumerators in ref _uart_flags. |
Pawel Zarembski |
0:01f31e923fe2 | 597 | * For example, to check whether the TX is empty, do the following. |
Pawel Zarembski |
0:01f31e923fe2 | 598 | * code |
Pawel Zarembski |
0:01f31e923fe2 | 599 | * if (kUART_TxDataRegEmptyFlag & UART_GetStatusFlags(UART1)) |
Pawel Zarembski |
0:01f31e923fe2 | 600 | * { |
Pawel Zarembski |
0:01f31e923fe2 | 601 | * ... |
Pawel Zarembski |
0:01f31e923fe2 | 602 | * } |
Pawel Zarembski |
0:01f31e923fe2 | 603 | * endcode |
Pawel Zarembski |
0:01f31e923fe2 | 604 | * |
Pawel Zarembski |
0:01f31e923fe2 | 605 | * param base UART peripheral base address. |
Pawel Zarembski |
0:01f31e923fe2 | 606 | * return UART status flags which are ORed by the enumerators in the _uart_flags. |
Pawel Zarembski |
0:01f31e923fe2 | 607 | */ |
Pawel Zarembski |
0:01f31e923fe2 | 608 | uint32_t UART_GetStatusFlags(UART_Type *base) |
Pawel Zarembski |
0:01f31e923fe2 | 609 | { |
Pawel Zarembski |
0:01f31e923fe2 | 610 | uint32_t status_flag; |
Pawel Zarembski |
0:01f31e923fe2 | 611 | |
Pawel Zarembski |
0:01f31e923fe2 | 612 | status_flag = base->S1 | ((uint32_t)(base->S2) << 8); |
Pawel Zarembski |
0:01f31e923fe2 | 613 | |
Pawel Zarembski |
0:01f31e923fe2 | 614 | #if defined(FSL_FEATURE_UART_HAS_EXTENDED_DATA_REGISTER_FLAGS) && FSL_FEATURE_UART_HAS_EXTENDED_DATA_REGISTER_FLAGS |
Pawel Zarembski |
0:01f31e923fe2 | 615 | status_flag |= ((uint32_t)(base->ED) << 16); |
Pawel Zarembski |
0:01f31e923fe2 | 616 | #endif |
Pawel Zarembski |
0:01f31e923fe2 | 617 | |
Pawel Zarembski |
0:01f31e923fe2 | 618 | #if defined(FSL_FEATURE_UART_HAS_FIFO) && FSL_FEATURE_UART_HAS_FIFO |
Pawel Zarembski |
0:01f31e923fe2 | 619 | status_flag |= ((uint32_t)(base->SFIFO) << 24); |
Pawel Zarembski |
0:01f31e923fe2 | 620 | #endif |
Pawel Zarembski |
0:01f31e923fe2 | 621 | |
Pawel Zarembski |
0:01f31e923fe2 | 622 | return status_flag; |
Pawel Zarembski |
0:01f31e923fe2 | 623 | } |
Pawel Zarembski |
0:01f31e923fe2 | 624 | |
Pawel Zarembski |
0:01f31e923fe2 | 625 | /*! |
Pawel Zarembski |
0:01f31e923fe2 | 626 | * brief Clears status flags with the provided mask. |
Pawel Zarembski |
0:01f31e923fe2 | 627 | * |
Pawel Zarembski |
0:01f31e923fe2 | 628 | * This function clears UART status flags with a provided mask. An automatically cleared flag |
Pawel Zarembski |
0:01f31e923fe2 | 629 | * can't be cleared by this function. |
Pawel Zarembski |
0:01f31e923fe2 | 630 | * These flags can only be cleared or set by hardware. |
Pawel Zarembski |
0:01f31e923fe2 | 631 | * kUART_TxDataRegEmptyFlag, kUART_TransmissionCompleteFlag, kUART_RxDataRegFullFlag, |
Pawel Zarembski |
0:01f31e923fe2 | 632 | * kUART_RxActiveFlag, kUART_NoiseErrorInRxDataRegFlag, kUART_ParityErrorInRxDataRegFlag, |
Pawel Zarembski |
0:01f31e923fe2 | 633 | * kUART_TxFifoEmptyFlag,kUART_RxFifoEmptyFlag |
Pawel Zarembski |
0:01f31e923fe2 | 634 | * Note that this API should be called when the Tx/Rx is idle. Otherwise it has no effect. |
Pawel Zarembski |
0:01f31e923fe2 | 635 | * |
Pawel Zarembski |
0:01f31e923fe2 | 636 | * param base UART peripheral base address. |
Pawel Zarembski |
0:01f31e923fe2 | 637 | * param mask The status flags to be cleared; it is logical OR value of ref _uart_flags. |
Pawel Zarembski |
0:01f31e923fe2 | 638 | * retval kStatus_UART_FlagCannotClearManually The flag can't be cleared by this function but |
Pawel Zarembski |
0:01f31e923fe2 | 639 | * it is cleared automatically by hardware. |
Pawel Zarembski |
0:01f31e923fe2 | 640 | * retval kStatus_Success Status in the mask is cleared. |
Pawel Zarembski |
0:01f31e923fe2 | 641 | */ |
Pawel Zarembski |
0:01f31e923fe2 | 642 | status_t UART_ClearStatusFlags(UART_Type *base, uint32_t mask) |
Pawel Zarembski |
0:01f31e923fe2 | 643 | { |
Pawel Zarembski |
0:01f31e923fe2 | 644 | uint8_t reg = base->S2; |
Pawel Zarembski |
0:01f31e923fe2 | 645 | status_t status; |
Pawel Zarembski |
0:01f31e923fe2 | 646 | |
Pawel Zarembski |
0:01f31e923fe2 | 647 | #if defined(FSL_FEATURE_UART_HAS_LIN_BREAK_DETECT) && FSL_FEATURE_UART_HAS_LIN_BREAK_DETECT |
Pawel Zarembski |
0:01f31e923fe2 | 648 | reg &= ~(UART_S2_RXEDGIF_MASK | UART_S2_LBKDIF_MASK); |
Pawel Zarembski |
0:01f31e923fe2 | 649 | #else |
Pawel Zarembski |
0:01f31e923fe2 | 650 | reg &= ~UART_S2_RXEDGIF_MASK; |
Pawel Zarembski |
0:01f31e923fe2 | 651 | #endif |
Pawel Zarembski |
0:01f31e923fe2 | 652 | |
Pawel Zarembski |
0:01f31e923fe2 | 653 | base->S2 = reg | (uint8_t)(mask >> 8); |
Pawel Zarembski |
0:01f31e923fe2 | 654 | |
Pawel Zarembski |
0:01f31e923fe2 | 655 | #if defined(FSL_FEATURE_UART_HAS_FIFO) && FSL_FEATURE_UART_HAS_FIFO |
Pawel Zarembski |
0:01f31e923fe2 | 656 | base->SFIFO = (uint8_t)(mask >> 24); |
Pawel Zarembski |
0:01f31e923fe2 | 657 | #endif |
Pawel Zarembski |
0:01f31e923fe2 | 658 | |
Pawel Zarembski |
0:01f31e923fe2 | 659 | if (mask & (kUART_IdleLineFlag | kUART_NoiseErrorFlag | kUART_FramingErrorFlag | kUART_ParityErrorFlag)) |
Pawel Zarembski |
0:01f31e923fe2 | 660 | { |
Pawel Zarembski |
0:01f31e923fe2 | 661 | /* Read base->D to clear the flags. */ |
Pawel Zarembski |
0:01f31e923fe2 | 662 | (void)base->S1; |
Pawel Zarembski |
0:01f31e923fe2 | 663 | (void)base->D; |
Pawel Zarembski |
0:01f31e923fe2 | 664 | } |
Pawel Zarembski |
0:01f31e923fe2 | 665 | |
Pawel Zarembski |
0:01f31e923fe2 | 666 | if (mask & kUART_RxOverrunFlag) |
Pawel Zarembski |
0:01f31e923fe2 | 667 | { |
Pawel Zarembski |
0:01f31e923fe2 | 668 | /* Read base->D to clear the flags and Flush all data in FIFO. */ |
Pawel Zarembski |
0:01f31e923fe2 | 669 | (void)base->S1; |
Pawel Zarembski |
0:01f31e923fe2 | 670 | (void)base->D; |
Pawel Zarembski |
0:01f31e923fe2 | 671 | #if defined(FSL_FEATURE_UART_HAS_FIFO) && FSL_FEATURE_UART_HAS_FIFO |
Pawel Zarembski |
0:01f31e923fe2 | 672 | /* Flush FIFO date, otherwise FIFO pointer will be in unknown state. */ |
Pawel Zarembski |
0:01f31e923fe2 | 673 | base->CFIFO |= UART_CFIFO_RXFLUSH_MASK; |
Pawel Zarembski |
0:01f31e923fe2 | 674 | #endif |
Pawel Zarembski |
0:01f31e923fe2 | 675 | } |
Pawel Zarembski |
0:01f31e923fe2 | 676 | |
Pawel Zarembski |
0:01f31e923fe2 | 677 | /* If some flags still pending. */ |
Pawel Zarembski |
0:01f31e923fe2 | 678 | if (mask & UART_GetStatusFlags(base)) |
Pawel Zarembski |
0:01f31e923fe2 | 679 | { |
Pawel Zarembski |
0:01f31e923fe2 | 680 | /* Some flags can only clear or set by the hardware itself, these flags are: kUART_TxDataRegEmptyFlag, |
Pawel Zarembski |
0:01f31e923fe2 | 681 | kUART_TransmissionCompleteFlag, kUART_RxDataRegFullFlag, kUART_RxActiveFlag, kUART_NoiseErrorInRxDataRegFlag, |
Pawel Zarembski |
0:01f31e923fe2 | 682 | kUART_ParityErrorInRxDataRegFlag, kUART_TxFifoEmptyFlag, kUART_RxFifoEmptyFlag. */ |
Pawel Zarembski |
0:01f31e923fe2 | 683 | status = kStatus_UART_FlagCannotClearManually; |
Pawel Zarembski |
0:01f31e923fe2 | 684 | } |
Pawel Zarembski |
0:01f31e923fe2 | 685 | else |
Pawel Zarembski |
0:01f31e923fe2 | 686 | { |
Pawel Zarembski |
0:01f31e923fe2 | 687 | status = kStatus_Success; |
Pawel Zarembski |
0:01f31e923fe2 | 688 | } |
Pawel Zarembski |
0:01f31e923fe2 | 689 | |
Pawel Zarembski |
0:01f31e923fe2 | 690 | return status; |
Pawel Zarembski |
0:01f31e923fe2 | 691 | } |
Pawel Zarembski |
0:01f31e923fe2 | 692 | |
Pawel Zarembski |
0:01f31e923fe2 | 693 | /*! |
Pawel Zarembski |
0:01f31e923fe2 | 694 | * brief Writes to the TX register using a blocking method. |
Pawel Zarembski |
0:01f31e923fe2 | 695 | * |
Pawel Zarembski |
0:01f31e923fe2 | 696 | * This function polls the TX register, waits for the TX register to be empty or for the TX FIFO |
Pawel Zarembski |
0:01f31e923fe2 | 697 | * to have room and writes data to the TX buffer. |
Pawel Zarembski |
0:01f31e923fe2 | 698 | * |
Pawel Zarembski |
0:01f31e923fe2 | 699 | * note This function does not check whether all data is sent out to the bus. |
Pawel Zarembski |
0:01f31e923fe2 | 700 | * Before disabling the TX, check kUART_TransmissionCompleteFlag to ensure that the TX is |
Pawel Zarembski |
0:01f31e923fe2 | 701 | * finished. |
Pawel Zarembski |
0:01f31e923fe2 | 702 | * |
Pawel Zarembski |
0:01f31e923fe2 | 703 | * param base UART peripheral base address. |
Pawel Zarembski |
0:01f31e923fe2 | 704 | * param data Start address of the data to write. |
Pawel Zarembski |
0:01f31e923fe2 | 705 | * param length Size of the data to write. |
Pawel Zarembski |
0:01f31e923fe2 | 706 | */ |
Pawel Zarembski |
0:01f31e923fe2 | 707 | void UART_WriteBlocking(UART_Type *base, const uint8_t *data, size_t length) |
Pawel Zarembski |
0:01f31e923fe2 | 708 | { |
Pawel Zarembski |
0:01f31e923fe2 | 709 | /* This API can only ensure that the data is written into the data buffer but can't |
Pawel Zarembski |
0:01f31e923fe2 | 710 | ensure all data in the data buffer are sent into the transmit shift buffer. */ |
Pawel Zarembski |
0:01f31e923fe2 | 711 | while (length--) |
Pawel Zarembski |
0:01f31e923fe2 | 712 | { |
Pawel Zarembski |
0:01f31e923fe2 | 713 | while (!(base->S1 & UART_S1_TDRE_MASK)) |
Pawel Zarembski |
0:01f31e923fe2 | 714 | { |
Pawel Zarembski |
0:01f31e923fe2 | 715 | } |
Pawel Zarembski |
0:01f31e923fe2 | 716 | base->D = *(data++); |
Pawel Zarembski |
0:01f31e923fe2 | 717 | } |
Pawel Zarembski |
0:01f31e923fe2 | 718 | } |
Pawel Zarembski |
0:01f31e923fe2 | 719 | |
Pawel Zarembski |
0:01f31e923fe2 | 720 | static void UART_WriteNonBlocking(UART_Type *base, const uint8_t *data, size_t length) |
Pawel Zarembski |
0:01f31e923fe2 | 721 | { |
Pawel Zarembski |
0:01f31e923fe2 | 722 | assert(data); |
Pawel Zarembski |
0:01f31e923fe2 | 723 | |
Pawel Zarembski |
0:01f31e923fe2 | 724 | size_t i; |
Pawel Zarembski |
0:01f31e923fe2 | 725 | |
Pawel Zarembski |
0:01f31e923fe2 | 726 | /* The Non Blocking write data API assume user have ensured there is enough space in |
Pawel Zarembski |
0:01f31e923fe2 | 727 | peripheral to write. */ |
Pawel Zarembski |
0:01f31e923fe2 | 728 | for (i = 0; i < length; i++) |
Pawel Zarembski |
0:01f31e923fe2 | 729 | { |
Pawel Zarembski |
0:01f31e923fe2 | 730 | base->D = data[i]; |
Pawel Zarembski |
0:01f31e923fe2 | 731 | } |
Pawel Zarembski |
0:01f31e923fe2 | 732 | } |
Pawel Zarembski |
0:01f31e923fe2 | 733 | |
Pawel Zarembski |
0:01f31e923fe2 | 734 | /*! |
Pawel Zarembski |
0:01f31e923fe2 | 735 | * brief Read RX data register using a blocking method. |
Pawel Zarembski |
0:01f31e923fe2 | 736 | * |
Pawel Zarembski |
0:01f31e923fe2 | 737 | * This function polls the RX register, waits for the RX register to be full or for RX FIFO to |
Pawel Zarembski |
0:01f31e923fe2 | 738 | * have data, and reads data from the TX register. |
Pawel Zarembski |
0:01f31e923fe2 | 739 | * |
Pawel Zarembski |
0:01f31e923fe2 | 740 | * param base UART peripheral base address. |
Pawel Zarembski |
0:01f31e923fe2 | 741 | * param data Start address of the buffer to store the received data. |
Pawel Zarembski |
0:01f31e923fe2 | 742 | * param length Size of the buffer. |
Pawel Zarembski |
0:01f31e923fe2 | 743 | * retval kStatus_UART_RxHardwareOverrun Receiver overrun occurred while receiving data. |
Pawel Zarembski |
0:01f31e923fe2 | 744 | * retval kStatus_UART_NoiseError A noise error occurred while receiving data. |
Pawel Zarembski |
0:01f31e923fe2 | 745 | * retval kStatus_UART_FramingError A framing error occurred while receiving data. |
Pawel Zarembski |
0:01f31e923fe2 | 746 | * retval kStatus_UART_ParityError A parity error occurred while receiving data. |
Pawel Zarembski |
0:01f31e923fe2 | 747 | * retval kStatus_Success Successfully received all data. |
Pawel Zarembski |
0:01f31e923fe2 | 748 | */ |
Pawel Zarembski |
0:01f31e923fe2 | 749 | status_t UART_ReadBlocking(UART_Type *base, uint8_t *data, size_t length) |
Pawel Zarembski |
0:01f31e923fe2 | 750 | { |
Pawel Zarembski |
0:01f31e923fe2 | 751 | assert(data); |
Pawel Zarembski |
0:01f31e923fe2 | 752 | |
Pawel Zarembski |
0:01f31e923fe2 | 753 | uint32_t statusFlag; |
Pawel Zarembski |
0:01f31e923fe2 | 754 | |
Pawel Zarembski |
0:01f31e923fe2 | 755 | while (length--) |
Pawel Zarembski |
0:01f31e923fe2 | 756 | { |
Pawel Zarembski |
0:01f31e923fe2 | 757 | #if defined(FSL_FEATURE_UART_HAS_FIFO) && FSL_FEATURE_UART_HAS_FIFO |
Pawel Zarembski |
0:01f31e923fe2 | 758 | while (!base->RCFIFO) |
Pawel Zarembski |
0:01f31e923fe2 | 759 | #else |
Pawel Zarembski |
0:01f31e923fe2 | 760 | while (!(base->S1 & UART_S1_RDRF_MASK)) |
Pawel Zarembski |
0:01f31e923fe2 | 761 | #endif |
Pawel Zarembski |
0:01f31e923fe2 | 762 | { |
Pawel Zarembski |
0:01f31e923fe2 | 763 | statusFlag = UART_GetStatusFlags(base); |
Pawel Zarembski |
0:01f31e923fe2 | 764 | |
Pawel Zarembski |
0:01f31e923fe2 | 765 | if (statusFlag & kUART_RxOverrunFlag) |
Pawel Zarembski |
0:01f31e923fe2 | 766 | { |
Pawel Zarembski |
0:01f31e923fe2 | 767 | return kStatus_UART_RxHardwareOverrun; |
Pawel Zarembski |
0:01f31e923fe2 | 768 | } |
Pawel Zarembski |
0:01f31e923fe2 | 769 | |
Pawel Zarembski |
0:01f31e923fe2 | 770 | if (statusFlag & kUART_NoiseErrorFlag) |
Pawel Zarembski |
0:01f31e923fe2 | 771 | { |
Pawel Zarembski |
0:01f31e923fe2 | 772 | return kStatus_UART_NoiseError; |
Pawel Zarembski |
0:01f31e923fe2 | 773 | } |
Pawel Zarembski |
0:01f31e923fe2 | 774 | |
Pawel Zarembski |
0:01f31e923fe2 | 775 | if (statusFlag & kUART_FramingErrorFlag) |
Pawel Zarembski |
0:01f31e923fe2 | 776 | { |
Pawel Zarembski |
0:01f31e923fe2 | 777 | return kStatus_UART_FramingError; |
Pawel Zarembski |
0:01f31e923fe2 | 778 | } |
Pawel Zarembski |
0:01f31e923fe2 | 779 | |
Pawel Zarembski |
0:01f31e923fe2 | 780 | if (statusFlag & kUART_ParityErrorFlag) |
Pawel Zarembski |
0:01f31e923fe2 | 781 | { |
Pawel Zarembski |
0:01f31e923fe2 | 782 | return kStatus_UART_ParityError; |
Pawel Zarembski |
0:01f31e923fe2 | 783 | } |
Pawel Zarembski |
0:01f31e923fe2 | 784 | } |
Pawel Zarembski |
0:01f31e923fe2 | 785 | *(data++) = base->D; |
Pawel Zarembski |
0:01f31e923fe2 | 786 | } |
Pawel Zarembski |
0:01f31e923fe2 | 787 | |
Pawel Zarembski |
0:01f31e923fe2 | 788 | return kStatus_Success; |
Pawel Zarembski |
0:01f31e923fe2 | 789 | } |
Pawel Zarembski |
0:01f31e923fe2 | 790 | |
Pawel Zarembski |
0:01f31e923fe2 | 791 | static void UART_ReadNonBlocking(UART_Type *base, uint8_t *data, size_t length) |
Pawel Zarembski |
0:01f31e923fe2 | 792 | { |
Pawel Zarembski |
0:01f31e923fe2 | 793 | assert(data); |
Pawel Zarembski |
0:01f31e923fe2 | 794 | |
Pawel Zarembski |
0:01f31e923fe2 | 795 | size_t i; |
Pawel Zarembski |
0:01f31e923fe2 | 796 | |
Pawel Zarembski |
0:01f31e923fe2 | 797 | /* The Non Blocking read data API assume user have ensured there is enough space in |
Pawel Zarembski |
0:01f31e923fe2 | 798 | peripheral to write. */ |
Pawel Zarembski |
0:01f31e923fe2 | 799 | for (i = 0; i < length; i++) |
Pawel Zarembski |
0:01f31e923fe2 | 800 | { |
Pawel Zarembski |
0:01f31e923fe2 | 801 | data[i] = base->D; |
Pawel Zarembski |
0:01f31e923fe2 | 802 | } |
Pawel Zarembski |
0:01f31e923fe2 | 803 | } |
Pawel Zarembski |
0:01f31e923fe2 | 804 | |
Pawel Zarembski |
0:01f31e923fe2 | 805 | /*! |
Pawel Zarembski |
0:01f31e923fe2 | 806 | * brief Initializes the UART handle. |
Pawel Zarembski |
0:01f31e923fe2 | 807 | * |
Pawel Zarembski |
0:01f31e923fe2 | 808 | * This function initializes the UART handle which can be used for other UART |
Pawel Zarembski |
0:01f31e923fe2 | 809 | * transactional APIs. Usually, for a specified UART instance, |
Pawel Zarembski |
0:01f31e923fe2 | 810 | * call this API once to get the initialized handle. |
Pawel Zarembski |
0:01f31e923fe2 | 811 | * |
Pawel Zarembski |
0:01f31e923fe2 | 812 | * param base UART peripheral base address. |
Pawel Zarembski |
0:01f31e923fe2 | 813 | * param handle UART handle pointer. |
Pawel Zarembski |
0:01f31e923fe2 | 814 | * param callback The callback function. |
Pawel Zarembski |
0:01f31e923fe2 | 815 | * param userData The parameter of the callback function. |
Pawel Zarembski |
0:01f31e923fe2 | 816 | */ |
Pawel Zarembski |
0:01f31e923fe2 | 817 | void UART_TransferCreateHandle(UART_Type *base, |
Pawel Zarembski |
0:01f31e923fe2 | 818 | uart_handle_t *handle, |
Pawel Zarembski |
0:01f31e923fe2 | 819 | uart_transfer_callback_t callback, |
Pawel Zarembski |
0:01f31e923fe2 | 820 | void *userData) |
Pawel Zarembski |
0:01f31e923fe2 | 821 | { |
Pawel Zarembski |
0:01f31e923fe2 | 822 | assert(handle); |
Pawel Zarembski |
0:01f31e923fe2 | 823 | |
Pawel Zarembski |
0:01f31e923fe2 | 824 | uint32_t instance; |
Pawel Zarembski |
0:01f31e923fe2 | 825 | |
Pawel Zarembski |
0:01f31e923fe2 | 826 | /* Zero the handle. */ |
Pawel Zarembski |
0:01f31e923fe2 | 827 | memset(handle, 0, sizeof(*handle)); |
Pawel Zarembski |
0:01f31e923fe2 | 828 | |
Pawel Zarembski |
0:01f31e923fe2 | 829 | /* Set the TX/RX state. */ |
Pawel Zarembski |
0:01f31e923fe2 | 830 | handle->rxState = kUART_RxIdle; |
Pawel Zarembski |
0:01f31e923fe2 | 831 | handle->txState = kUART_TxIdle; |
Pawel Zarembski |
0:01f31e923fe2 | 832 | |
Pawel Zarembski |
0:01f31e923fe2 | 833 | /* Set the callback and user data. */ |
Pawel Zarembski |
0:01f31e923fe2 | 834 | handle->callback = callback; |
Pawel Zarembski |
0:01f31e923fe2 | 835 | handle->userData = userData; |
Pawel Zarembski |
0:01f31e923fe2 | 836 | |
Pawel Zarembski |
0:01f31e923fe2 | 837 | /* Get instance from peripheral base address. */ |
Pawel Zarembski |
0:01f31e923fe2 | 838 | instance = UART_GetInstance(base); |
Pawel Zarembski |
0:01f31e923fe2 | 839 | |
Pawel Zarembski |
0:01f31e923fe2 | 840 | /* Save the handle in global variables to support the double weak mechanism. */ |
Pawel Zarembski |
0:01f31e923fe2 | 841 | s_uartHandle[instance] = handle; |
Pawel Zarembski |
0:01f31e923fe2 | 842 | |
Pawel Zarembski |
0:01f31e923fe2 | 843 | s_uartIsr = UART_TransferHandleIRQ; |
Pawel Zarembski |
0:01f31e923fe2 | 844 | /* Enable interrupt in NVIC. */ |
Pawel Zarembski |
0:01f31e923fe2 | 845 | EnableIRQ(s_uartIRQ[instance]); |
Pawel Zarembski |
0:01f31e923fe2 | 846 | } |
Pawel Zarembski |
0:01f31e923fe2 | 847 | |
Pawel Zarembski |
0:01f31e923fe2 | 848 | /*! |
Pawel Zarembski |
0:01f31e923fe2 | 849 | * brief Sets up the RX ring buffer. |
Pawel Zarembski |
0:01f31e923fe2 | 850 | * |
Pawel Zarembski |
0:01f31e923fe2 | 851 | * This function sets up the RX ring buffer to a specific UART handle. |
Pawel Zarembski |
0:01f31e923fe2 | 852 | * |
Pawel Zarembski |
0:01f31e923fe2 | 853 | * When the RX ring buffer is used, data received are stored into the ring buffer even when the |
Pawel Zarembski |
0:01f31e923fe2 | 854 | * user doesn't call the UART_TransferReceiveNonBlocking() API. If data is already received |
Pawel Zarembski |
0:01f31e923fe2 | 855 | * in the ring buffer, the user can get the received data from the ring buffer directly. |
Pawel Zarembski |
0:01f31e923fe2 | 856 | * |
Pawel Zarembski |
0:01f31e923fe2 | 857 | * note When using the RX ring buffer, one byte is reserved for internal use. In other |
Pawel Zarembski |
0:01f31e923fe2 | 858 | * words, if p ringBufferSize is 32, only 31 bytes are used for saving data. |
Pawel Zarembski |
0:01f31e923fe2 | 859 | * |
Pawel Zarembski |
0:01f31e923fe2 | 860 | * param base UART peripheral base address. |
Pawel Zarembski |
0:01f31e923fe2 | 861 | * param handle UART handle pointer. |
Pawel Zarembski |
0:01f31e923fe2 | 862 | * param ringBuffer Start address of the ring buffer for background receiving. Pass NULL to disable the ring buffer. |
Pawel Zarembski |
0:01f31e923fe2 | 863 | * param ringBufferSize Size of the ring buffer. |
Pawel Zarembski |
0:01f31e923fe2 | 864 | */ |
Pawel Zarembski |
0:01f31e923fe2 | 865 | void UART_TransferStartRingBuffer(UART_Type *base, uart_handle_t *handle, uint8_t *ringBuffer, size_t ringBufferSize) |
Pawel Zarembski |
0:01f31e923fe2 | 866 | { |
Pawel Zarembski |
0:01f31e923fe2 | 867 | assert(handle); |
Pawel Zarembski |
0:01f31e923fe2 | 868 | assert(ringBuffer); |
Pawel Zarembski |
0:01f31e923fe2 | 869 | |
Pawel Zarembski |
0:01f31e923fe2 | 870 | /* Setup the ringbuffer address */ |
Pawel Zarembski |
0:01f31e923fe2 | 871 | handle->rxRingBuffer = ringBuffer; |
Pawel Zarembski |
0:01f31e923fe2 | 872 | handle->rxRingBufferSize = ringBufferSize; |
Pawel Zarembski |
0:01f31e923fe2 | 873 | handle->rxRingBufferHead = 0U; |
Pawel Zarembski |
0:01f31e923fe2 | 874 | handle->rxRingBufferTail = 0U; |
Pawel Zarembski |
0:01f31e923fe2 | 875 | |
Pawel Zarembski |
0:01f31e923fe2 | 876 | /* Enable the interrupt to accept the data when user need the ring buffer. */ |
Pawel Zarembski |
0:01f31e923fe2 | 877 | UART_EnableInterrupts( |
Pawel Zarembski |
0:01f31e923fe2 | 878 | base, kUART_RxDataRegFullInterruptEnable | kUART_RxOverrunInterruptEnable | kUART_FramingErrorInterruptEnable); |
Pawel Zarembski |
0:01f31e923fe2 | 879 | /* Enable parity error interrupt when parity mode is enable*/ |
Pawel Zarembski |
0:01f31e923fe2 | 880 | if (UART_C1_PE_MASK & base->C1) |
Pawel Zarembski |
0:01f31e923fe2 | 881 | { |
Pawel Zarembski |
0:01f31e923fe2 | 882 | UART_EnableInterrupts(base, kUART_ParityErrorInterruptEnable); |
Pawel Zarembski |
0:01f31e923fe2 | 883 | } |
Pawel Zarembski |
0:01f31e923fe2 | 884 | } |
Pawel Zarembski |
0:01f31e923fe2 | 885 | |
Pawel Zarembski |
0:01f31e923fe2 | 886 | /*! |
Pawel Zarembski |
0:01f31e923fe2 | 887 | * brief Aborts the background transfer and uninstalls the ring buffer. |
Pawel Zarembski |
0:01f31e923fe2 | 888 | * |
Pawel Zarembski |
0:01f31e923fe2 | 889 | * This function aborts the background transfer and uninstalls the ring buffer. |
Pawel Zarembski |
0:01f31e923fe2 | 890 | * |
Pawel Zarembski |
0:01f31e923fe2 | 891 | * param base UART peripheral base address. |
Pawel Zarembski |
0:01f31e923fe2 | 892 | * param handle UART handle pointer. |
Pawel Zarembski |
0:01f31e923fe2 | 893 | */ |
Pawel Zarembski |
0:01f31e923fe2 | 894 | void UART_TransferStopRingBuffer(UART_Type *base, uart_handle_t *handle) |
Pawel Zarembski |
0:01f31e923fe2 | 895 | { |
Pawel Zarembski |
0:01f31e923fe2 | 896 | assert(handle); |
Pawel Zarembski |
0:01f31e923fe2 | 897 | |
Pawel Zarembski |
0:01f31e923fe2 | 898 | if (handle->rxState == kUART_RxIdle) |
Pawel Zarembski |
0:01f31e923fe2 | 899 | { |
Pawel Zarembski |
0:01f31e923fe2 | 900 | UART_DisableInterrupts(base, kUART_RxDataRegFullInterruptEnable | kUART_RxOverrunInterruptEnable | |
Pawel Zarembski |
0:01f31e923fe2 | 901 | kUART_FramingErrorInterruptEnable); |
Pawel Zarembski |
0:01f31e923fe2 | 902 | /* Disable parity error interrupt when parity mode is enable*/ |
Pawel Zarembski |
0:01f31e923fe2 | 903 | if (UART_C1_PE_MASK & base->C1) |
Pawel Zarembski |
0:01f31e923fe2 | 904 | { |
Pawel Zarembski |
0:01f31e923fe2 | 905 | UART_DisableInterrupts(base, kUART_ParityErrorInterruptEnable); |
Pawel Zarembski |
0:01f31e923fe2 | 906 | } |
Pawel Zarembski |
0:01f31e923fe2 | 907 | } |
Pawel Zarembski |
0:01f31e923fe2 | 908 | |
Pawel Zarembski |
0:01f31e923fe2 | 909 | handle->rxRingBuffer = NULL; |
Pawel Zarembski |
0:01f31e923fe2 | 910 | handle->rxRingBufferSize = 0U; |
Pawel Zarembski |
0:01f31e923fe2 | 911 | handle->rxRingBufferHead = 0U; |
Pawel Zarembski |
0:01f31e923fe2 | 912 | handle->rxRingBufferTail = 0U; |
Pawel Zarembski |
0:01f31e923fe2 | 913 | } |
Pawel Zarembski |
0:01f31e923fe2 | 914 | |
Pawel Zarembski |
0:01f31e923fe2 | 915 | /*! |
Pawel Zarembski |
0:01f31e923fe2 | 916 | * brief Transmits a buffer of data using the interrupt method. |
Pawel Zarembski |
0:01f31e923fe2 | 917 | * |
Pawel Zarembski |
0:01f31e923fe2 | 918 | * This function sends data using an interrupt method. This is a non-blocking function, which |
Pawel Zarembski |
0:01f31e923fe2 | 919 | * returns directly without waiting for all data to be written to the TX register. When |
Pawel Zarembski |
0:01f31e923fe2 | 920 | * all data is written to the TX register in the ISR, the UART driver calls the callback |
Pawel Zarembski |
0:01f31e923fe2 | 921 | * function and passes the ref kStatus_UART_TxIdle as status parameter. |
Pawel Zarembski |
0:01f31e923fe2 | 922 | * |
Pawel Zarembski |
0:01f31e923fe2 | 923 | * note The kStatus_UART_TxIdle is passed to the upper layer when all data is written |
Pawel Zarembski |
0:01f31e923fe2 | 924 | * to the TX register. However, it does not ensure that all data is sent out. Before disabling the TX, |
Pawel Zarembski |
0:01f31e923fe2 | 925 | * check the kUART_TransmissionCompleteFlag to ensure that the TX is finished. |
Pawel Zarembski |
0:01f31e923fe2 | 926 | * |
Pawel Zarembski |
0:01f31e923fe2 | 927 | * param base UART peripheral base address. |
Pawel Zarembski |
0:01f31e923fe2 | 928 | * param handle UART handle pointer. |
Pawel Zarembski |
0:01f31e923fe2 | 929 | * param xfer UART transfer structure. See #uart_transfer_t. |
Pawel Zarembski |
0:01f31e923fe2 | 930 | * retval kStatus_Success Successfully start the data transmission. |
Pawel Zarembski |
0:01f31e923fe2 | 931 | * retval kStatus_UART_TxBusy Previous transmission still not finished; data not all written to TX register yet. |
Pawel Zarembski |
0:01f31e923fe2 | 932 | * retval kStatus_InvalidArgument Invalid argument. |
Pawel Zarembski |
0:01f31e923fe2 | 933 | */ |
Pawel Zarembski |
0:01f31e923fe2 | 934 | status_t UART_TransferSendNonBlocking(UART_Type *base, uart_handle_t *handle, uart_transfer_t *xfer) |
Pawel Zarembski |
0:01f31e923fe2 | 935 | { |
Pawel Zarembski |
0:01f31e923fe2 | 936 | assert(handle); |
Pawel Zarembski |
0:01f31e923fe2 | 937 | assert(xfer); |
Pawel Zarembski |
0:01f31e923fe2 | 938 | assert(xfer->dataSize); |
Pawel Zarembski |
0:01f31e923fe2 | 939 | assert(xfer->data); |
Pawel Zarembski |
0:01f31e923fe2 | 940 | |
Pawel Zarembski |
0:01f31e923fe2 | 941 | status_t status; |
Pawel Zarembski |
0:01f31e923fe2 | 942 | |
Pawel Zarembski |
0:01f31e923fe2 | 943 | /* Return error if current TX busy. */ |
Pawel Zarembski |
0:01f31e923fe2 | 944 | if (kUART_TxBusy == handle->txState) |
Pawel Zarembski |
0:01f31e923fe2 | 945 | { |
Pawel Zarembski |
0:01f31e923fe2 | 946 | status = kStatus_UART_TxBusy; |
Pawel Zarembski |
0:01f31e923fe2 | 947 | } |
Pawel Zarembski |
0:01f31e923fe2 | 948 | else |
Pawel Zarembski |
0:01f31e923fe2 | 949 | { |
Pawel Zarembski |
0:01f31e923fe2 | 950 | handle->txData = xfer->data; |
Pawel Zarembski |
0:01f31e923fe2 | 951 | handle->txDataSize = xfer->dataSize; |
Pawel Zarembski |
0:01f31e923fe2 | 952 | handle->txDataSizeAll = xfer->dataSize; |
Pawel Zarembski |
0:01f31e923fe2 | 953 | handle->txState = kUART_TxBusy; |
Pawel Zarembski |
0:01f31e923fe2 | 954 | |
Pawel Zarembski |
0:01f31e923fe2 | 955 | /* Enable transmitter interrupt. */ |
Pawel Zarembski |
0:01f31e923fe2 | 956 | UART_EnableInterrupts(base, kUART_TxDataRegEmptyInterruptEnable); |
Pawel Zarembski |
0:01f31e923fe2 | 957 | |
Pawel Zarembski |
0:01f31e923fe2 | 958 | status = kStatus_Success; |
Pawel Zarembski |
0:01f31e923fe2 | 959 | } |
Pawel Zarembski |
0:01f31e923fe2 | 960 | |
Pawel Zarembski |
0:01f31e923fe2 | 961 | return status; |
Pawel Zarembski |
0:01f31e923fe2 | 962 | } |
Pawel Zarembski |
0:01f31e923fe2 | 963 | |
Pawel Zarembski |
0:01f31e923fe2 | 964 | /*! |
Pawel Zarembski |
0:01f31e923fe2 | 965 | * brief Aborts the interrupt-driven data transmit. |
Pawel Zarembski |
0:01f31e923fe2 | 966 | * |
Pawel Zarembski |
0:01f31e923fe2 | 967 | * This function aborts the interrupt-driven data sending. The user can get the remainBytes to find out |
Pawel Zarembski |
0:01f31e923fe2 | 968 | * how many bytes are not sent out. |
Pawel Zarembski |
0:01f31e923fe2 | 969 | * |
Pawel Zarembski |
0:01f31e923fe2 | 970 | * param base UART peripheral base address. |
Pawel Zarembski |
0:01f31e923fe2 | 971 | * param handle UART handle pointer. |
Pawel Zarembski |
0:01f31e923fe2 | 972 | */ |
Pawel Zarembski |
0:01f31e923fe2 | 973 | void UART_TransferAbortSend(UART_Type *base, uart_handle_t *handle) |
Pawel Zarembski |
0:01f31e923fe2 | 974 | { |
Pawel Zarembski |
0:01f31e923fe2 | 975 | assert(handle); |
Pawel Zarembski |
0:01f31e923fe2 | 976 | |
Pawel Zarembski |
0:01f31e923fe2 | 977 | UART_DisableInterrupts(base, kUART_TxDataRegEmptyInterruptEnable | kUART_TransmissionCompleteInterruptEnable); |
Pawel Zarembski |
0:01f31e923fe2 | 978 | |
Pawel Zarembski |
0:01f31e923fe2 | 979 | handle->txDataSize = 0; |
Pawel Zarembski |
0:01f31e923fe2 | 980 | handle->txState = kUART_TxIdle; |
Pawel Zarembski |
0:01f31e923fe2 | 981 | } |
Pawel Zarembski |
0:01f31e923fe2 | 982 | |
Pawel Zarembski |
0:01f31e923fe2 | 983 | /*! |
Pawel Zarembski |
0:01f31e923fe2 | 984 | * brief Gets the number of bytes written to the UART TX register. |
Pawel Zarembski |
0:01f31e923fe2 | 985 | * |
Pawel Zarembski |
0:01f31e923fe2 | 986 | * This function gets the number of bytes written to the UART TX |
Pawel Zarembski |
0:01f31e923fe2 | 987 | * register by using the interrupt method. |
Pawel Zarembski |
0:01f31e923fe2 | 988 | * |
Pawel Zarembski |
0:01f31e923fe2 | 989 | * param base UART peripheral base address. |
Pawel Zarembski |
0:01f31e923fe2 | 990 | * param handle UART handle pointer. |
Pawel Zarembski |
0:01f31e923fe2 | 991 | * param count Send bytes count. |
Pawel Zarembski |
0:01f31e923fe2 | 992 | * retval kStatus_NoTransferInProgress No send in progress. |
Pawel Zarembski |
0:01f31e923fe2 | 993 | * retval kStatus_InvalidArgument The parameter is invalid. |
Pawel Zarembski |
0:01f31e923fe2 | 994 | * retval kStatus_Success Get successfully through the parameter \p count; |
Pawel Zarembski |
0:01f31e923fe2 | 995 | */ |
Pawel Zarembski |
0:01f31e923fe2 | 996 | status_t UART_TransferGetSendCount(UART_Type *base, uart_handle_t *handle, uint32_t *count) |
Pawel Zarembski |
0:01f31e923fe2 | 997 | { |
Pawel Zarembski |
0:01f31e923fe2 | 998 | assert(handle); |
Pawel Zarembski |
0:01f31e923fe2 | 999 | assert(count); |
Pawel Zarembski |
0:01f31e923fe2 | 1000 | |
Pawel Zarembski |
0:01f31e923fe2 | 1001 | if (kUART_TxIdle == handle->txState) |
Pawel Zarembski |
0:01f31e923fe2 | 1002 | { |
Pawel Zarembski |
0:01f31e923fe2 | 1003 | return kStatus_NoTransferInProgress; |
Pawel Zarembski |
0:01f31e923fe2 | 1004 | } |
Pawel Zarembski |
0:01f31e923fe2 | 1005 | |
Pawel Zarembski |
0:01f31e923fe2 | 1006 | *count = handle->txDataSizeAll - handle->txDataSize; |
Pawel Zarembski |
0:01f31e923fe2 | 1007 | |
Pawel Zarembski |
0:01f31e923fe2 | 1008 | return kStatus_Success; |
Pawel Zarembski |
0:01f31e923fe2 | 1009 | } |
Pawel Zarembski |
0:01f31e923fe2 | 1010 | |
Pawel Zarembski |
0:01f31e923fe2 | 1011 | /*! |
Pawel Zarembski |
0:01f31e923fe2 | 1012 | * brief Receives a buffer of data using an interrupt method. |
Pawel Zarembski |
0:01f31e923fe2 | 1013 | * |
Pawel Zarembski |
0:01f31e923fe2 | 1014 | * This function receives data using an interrupt method. This is a non-blocking function, which |
Pawel Zarembski |
0:01f31e923fe2 | 1015 | * returns without waiting for all data to be received. |
Pawel Zarembski |
0:01f31e923fe2 | 1016 | * If the RX ring buffer is used and not empty, the data in the ring buffer is copied and |
Pawel Zarembski |
0:01f31e923fe2 | 1017 | * the parameter p receivedBytes shows how many bytes are copied from the ring buffer. |
Pawel Zarembski |
0:01f31e923fe2 | 1018 | * After copying, if the data in the ring buffer is not enough to read, the receive |
Pawel Zarembski |
0:01f31e923fe2 | 1019 | * request is saved by the UART driver. When the new data arrives, the receive request |
Pawel Zarembski |
0:01f31e923fe2 | 1020 | * is serviced first. When all data is received, the UART driver notifies the upper layer |
Pawel Zarembski |
0:01f31e923fe2 | 1021 | * through a callback function and passes the status parameter ref kStatus_UART_RxIdle. |
Pawel Zarembski |
0:01f31e923fe2 | 1022 | * For example, the upper layer needs 10 bytes but there are only 5 bytes in the ring buffer. |
Pawel Zarembski |
0:01f31e923fe2 | 1023 | * The 5 bytes are copied to the xfer->data and this function returns with the |
Pawel Zarembski |
0:01f31e923fe2 | 1024 | * parameter p receivedBytes set to 5. For the left 5 bytes, newly arrived data is |
Pawel Zarembski |
0:01f31e923fe2 | 1025 | * saved from the xfer->data[5]. When 5 bytes are received, the UART driver notifies the upper layer. |
Pawel Zarembski |
0:01f31e923fe2 | 1026 | * If the RX ring buffer is not enabled, this function enables the RX and RX interrupt |
Pawel Zarembski |
0:01f31e923fe2 | 1027 | * to receive data to the xfer->data. When all data is received, the upper layer is notified. |
Pawel Zarembski |
0:01f31e923fe2 | 1028 | * |
Pawel Zarembski |
0:01f31e923fe2 | 1029 | * param base UART peripheral base address. |
Pawel Zarembski |
0:01f31e923fe2 | 1030 | * param handle UART handle pointer. |
Pawel Zarembski |
0:01f31e923fe2 | 1031 | * param xfer UART transfer structure, see #uart_transfer_t. |
Pawel Zarembski |
0:01f31e923fe2 | 1032 | * param receivedBytes Bytes received from the ring buffer directly. |
Pawel Zarembski |
0:01f31e923fe2 | 1033 | * retval kStatus_Success Successfully queue the transfer into transmit queue. |
Pawel Zarembski |
0:01f31e923fe2 | 1034 | * retval kStatus_UART_RxBusy Previous receive request is not finished. |
Pawel Zarembski |
0:01f31e923fe2 | 1035 | * retval kStatus_InvalidArgument Invalid argument. |
Pawel Zarembski |
0:01f31e923fe2 | 1036 | */ |
Pawel Zarembski |
0:01f31e923fe2 | 1037 | status_t UART_TransferReceiveNonBlocking(UART_Type *base, |
Pawel Zarembski |
0:01f31e923fe2 | 1038 | uart_handle_t *handle, |
Pawel Zarembski |
0:01f31e923fe2 | 1039 | uart_transfer_t *xfer, |
Pawel Zarembski |
0:01f31e923fe2 | 1040 | size_t *receivedBytes) |
Pawel Zarembski |
0:01f31e923fe2 | 1041 | { |
Pawel Zarembski |
0:01f31e923fe2 | 1042 | assert(handle); |
Pawel Zarembski |
0:01f31e923fe2 | 1043 | assert(xfer); |
Pawel Zarembski |
0:01f31e923fe2 | 1044 | assert(xfer->data); |
Pawel Zarembski |
0:01f31e923fe2 | 1045 | assert(xfer->dataSize); |
Pawel Zarembski |
0:01f31e923fe2 | 1046 | |
Pawel Zarembski |
0:01f31e923fe2 | 1047 | uint32_t i; |
Pawel Zarembski |
0:01f31e923fe2 | 1048 | status_t status; |
Pawel Zarembski |
0:01f31e923fe2 | 1049 | /* How many bytes to copy from ring buffer to user memory. */ |
Pawel Zarembski |
0:01f31e923fe2 | 1050 | size_t bytesToCopy = 0U; |
Pawel Zarembski |
0:01f31e923fe2 | 1051 | /* How many bytes to receive. */ |
Pawel Zarembski |
0:01f31e923fe2 | 1052 | size_t bytesToReceive; |
Pawel Zarembski |
0:01f31e923fe2 | 1053 | /* How many bytes currently have received. */ |
Pawel Zarembski |
0:01f31e923fe2 | 1054 | size_t bytesCurrentReceived; |
Pawel Zarembski |
0:01f31e923fe2 | 1055 | |
Pawel Zarembski |
0:01f31e923fe2 | 1056 | /* How to get data: |
Pawel Zarembski |
0:01f31e923fe2 | 1057 | 1. If RX ring buffer is not enabled, then save xfer->data and xfer->dataSize |
Pawel Zarembski |
0:01f31e923fe2 | 1058 | to uart handle, enable interrupt to store received data to xfer->data. When |
Pawel Zarembski |
0:01f31e923fe2 | 1059 | all data received, trigger callback. |
Pawel Zarembski |
0:01f31e923fe2 | 1060 | 2. If RX ring buffer is enabled and not empty, get data from ring buffer first. |
Pawel Zarembski |
0:01f31e923fe2 | 1061 | If there are enough data in ring buffer, copy them to xfer->data and return. |
Pawel Zarembski |
0:01f31e923fe2 | 1062 | If there are not enough data in ring buffer, copy all of them to xfer->data, |
Pawel Zarembski |
0:01f31e923fe2 | 1063 | save the xfer->data remained empty space to uart handle, receive data |
Pawel Zarembski |
0:01f31e923fe2 | 1064 | to this empty space and trigger callback when finished. */ |
Pawel Zarembski |
0:01f31e923fe2 | 1065 | |
Pawel Zarembski |
0:01f31e923fe2 | 1066 | if (kUART_RxBusy == handle->rxState) |
Pawel Zarembski |
0:01f31e923fe2 | 1067 | { |
Pawel Zarembski |
0:01f31e923fe2 | 1068 | status = kStatus_UART_RxBusy; |
Pawel Zarembski |
0:01f31e923fe2 | 1069 | } |
Pawel Zarembski |
0:01f31e923fe2 | 1070 | else |
Pawel Zarembski |
0:01f31e923fe2 | 1071 | { |
Pawel Zarembski |
0:01f31e923fe2 | 1072 | bytesToReceive = xfer->dataSize; |
Pawel Zarembski |
0:01f31e923fe2 | 1073 | bytesCurrentReceived = 0U; |
Pawel Zarembski |
0:01f31e923fe2 | 1074 | |
Pawel Zarembski |
0:01f31e923fe2 | 1075 | /* If RX ring buffer is used. */ |
Pawel Zarembski |
0:01f31e923fe2 | 1076 | if (handle->rxRingBuffer) |
Pawel Zarembski |
0:01f31e923fe2 | 1077 | { |
Pawel Zarembski |
0:01f31e923fe2 | 1078 | /* Disable UART RX IRQ, protect ring buffer. */ |
Pawel Zarembski |
0:01f31e923fe2 | 1079 | UART_DisableInterrupts(base, kUART_RxDataRegFullInterruptEnable); |
Pawel Zarembski |
0:01f31e923fe2 | 1080 | |
Pawel Zarembski |
0:01f31e923fe2 | 1081 | /* How many bytes in RX ring buffer currently. */ |
Pawel Zarembski |
0:01f31e923fe2 | 1082 | bytesToCopy = UART_TransferGetRxRingBufferLength(handle); |
Pawel Zarembski |
0:01f31e923fe2 | 1083 | |
Pawel Zarembski |
0:01f31e923fe2 | 1084 | if (bytesToCopy) |
Pawel Zarembski |
0:01f31e923fe2 | 1085 | { |
Pawel Zarembski |
0:01f31e923fe2 | 1086 | bytesToCopy = MIN(bytesToReceive, bytesToCopy); |
Pawel Zarembski |
0:01f31e923fe2 | 1087 | |
Pawel Zarembski |
0:01f31e923fe2 | 1088 | bytesToReceive -= bytesToCopy; |
Pawel Zarembski |
0:01f31e923fe2 | 1089 | |
Pawel Zarembski |
0:01f31e923fe2 | 1090 | /* Copy data from ring buffer to user memory. */ |
Pawel Zarembski |
0:01f31e923fe2 | 1091 | for (i = 0U; i < bytesToCopy; i++) |
Pawel Zarembski |
0:01f31e923fe2 | 1092 | { |
Pawel Zarembski |
0:01f31e923fe2 | 1093 | xfer->data[bytesCurrentReceived++] = handle->rxRingBuffer[handle->rxRingBufferTail]; |
Pawel Zarembski |
0:01f31e923fe2 | 1094 | |
Pawel Zarembski |
0:01f31e923fe2 | 1095 | /* Wrap to 0. Not use modulo (%) because it might be large and slow. */ |
Pawel Zarembski |
0:01f31e923fe2 | 1096 | if (handle->rxRingBufferTail + 1U == handle->rxRingBufferSize) |
Pawel Zarembski |
0:01f31e923fe2 | 1097 | { |
Pawel Zarembski |
0:01f31e923fe2 | 1098 | handle->rxRingBufferTail = 0U; |
Pawel Zarembski |
0:01f31e923fe2 | 1099 | } |
Pawel Zarembski |
0:01f31e923fe2 | 1100 | else |
Pawel Zarembski |
0:01f31e923fe2 | 1101 | { |
Pawel Zarembski |
0:01f31e923fe2 | 1102 | handle->rxRingBufferTail++; |
Pawel Zarembski |
0:01f31e923fe2 | 1103 | } |
Pawel Zarembski |
0:01f31e923fe2 | 1104 | } |
Pawel Zarembski |
0:01f31e923fe2 | 1105 | } |
Pawel Zarembski |
0:01f31e923fe2 | 1106 | |
Pawel Zarembski |
0:01f31e923fe2 | 1107 | /* If ring buffer does not have enough data, still need to read more data. */ |
Pawel Zarembski |
0:01f31e923fe2 | 1108 | if (bytesToReceive) |
Pawel Zarembski |
0:01f31e923fe2 | 1109 | { |
Pawel Zarembski |
0:01f31e923fe2 | 1110 | /* No data in ring buffer, save the request to UART handle. */ |
Pawel Zarembski |
0:01f31e923fe2 | 1111 | handle->rxData = xfer->data + bytesCurrentReceived; |
Pawel Zarembski |
0:01f31e923fe2 | 1112 | handle->rxDataSize = bytesToReceive; |
Pawel Zarembski |
0:01f31e923fe2 | 1113 | handle->rxDataSizeAll = bytesToReceive; |
Pawel Zarembski |
0:01f31e923fe2 | 1114 | handle->rxState = kUART_RxBusy; |
Pawel Zarembski |
0:01f31e923fe2 | 1115 | } |
Pawel Zarembski |
0:01f31e923fe2 | 1116 | |
Pawel Zarembski |
0:01f31e923fe2 | 1117 | /* Enable UART RX IRQ if previously enabled. */ |
Pawel Zarembski |
0:01f31e923fe2 | 1118 | UART_EnableInterrupts(base, kUART_RxDataRegFullInterruptEnable); |
Pawel Zarembski |
0:01f31e923fe2 | 1119 | |
Pawel Zarembski |
0:01f31e923fe2 | 1120 | /* Call user callback since all data are received. */ |
Pawel Zarembski |
0:01f31e923fe2 | 1121 | if (0 == bytesToReceive) |
Pawel Zarembski |
0:01f31e923fe2 | 1122 | { |
Pawel Zarembski |
0:01f31e923fe2 | 1123 | if (handle->callback) |
Pawel Zarembski |
0:01f31e923fe2 | 1124 | { |
Pawel Zarembski |
0:01f31e923fe2 | 1125 | handle->callback(base, handle, kStatus_UART_RxIdle, handle->userData); |
Pawel Zarembski |
0:01f31e923fe2 | 1126 | } |
Pawel Zarembski |
0:01f31e923fe2 | 1127 | } |
Pawel Zarembski |
0:01f31e923fe2 | 1128 | } |
Pawel Zarembski |
0:01f31e923fe2 | 1129 | /* Ring buffer not used. */ |
Pawel Zarembski |
0:01f31e923fe2 | 1130 | else |
Pawel Zarembski |
0:01f31e923fe2 | 1131 | { |
Pawel Zarembski |
0:01f31e923fe2 | 1132 | handle->rxData = xfer->data + bytesCurrentReceived; |
Pawel Zarembski |
0:01f31e923fe2 | 1133 | handle->rxDataSize = bytesToReceive; |
Pawel Zarembski |
0:01f31e923fe2 | 1134 | handle->rxDataSizeAll = bytesToReceive; |
Pawel Zarembski |
0:01f31e923fe2 | 1135 | handle->rxState = kUART_RxBusy; |
Pawel Zarembski |
0:01f31e923fe2 | 1136 | |
Pawel Zarembski |
0:01f31e923fe2 | 1137 | /* Enable RX/Rx overrun/framing error/idle line interrupt. */ |
Pawel Zarembski |
0:01f31e923fe2 | 1138 | UART_EnableInterrupts(base, kUART_RxDataRegFullInterruptEnable | kUART_RxOverrunInterruptEnable | |
Pawel Zarembski |
0:01f31e923fe2 | 1139 | kUART_FramingErrorInterruptEnable | kUART_IdleLineInterruptEnable); |
Pawel Zarembski |
0:01f31e923fe2 | 1140 | /* Enable parity error interrupt when parity mode is enable*/ |
Pawel Zarembski |
0:01f31e923fe2 | 1141 | if (UART_C1_PE_MASK & base->C1) |
Pawel Zarembski |
0:01f31e923fe2 | 1142 | { |
Pawel Zarembski |
0:01f31e923fe2 | 1143 | UART_EnableInterrupts(base, kUART_ParityErrorInterruptEnable); |
Pawel Zarembski |
0:01f31e923fe2 | 1144 | } |
Pawel Zarembski |
0:01f31e923fe2 | 1145 | } |
Pawel Zarembski |
0:01f31e923fe2 | 1146 | |
Pawel Zarembski |
0:01f31e923fe2 | 1147 | /* Return the how many bytes have read. */ |
Pawel Zarembski |
0:01f31e923fe2 | 1148 | if (receivedBytes) |
Pawel Zarembski |
0:01f31e923fe2 | 1149 | { |
Pawel Zarembski |
0:01f31e923fe2 | 1150 | *receivedBytes = bytesCurrentReceived; |
Pawel Zarembski |
0:01f31e923fe2 | 1151 | } |
Pawel Zarembski |
0:01f31e923fe2 | 1152 | |
Pawel Zarembski |
0:01f31e923fe2 | 1153 | status = kStatus_Success; |
Pawel Zarembski |
0:01f31e923fe2 | 1154 | } |
Pawel Zarembski |
0:01f31e923fe2 | 1155 | |
Pawel Zarembski |
0:01f31e923fe2 | 1156 | return status; |
Pawel Zarembski |
0:01f31e923fe2 | 1157 | } |
Pawel Zarembski |
0:01f31e923fe2 | 1158 | |
Pawel Zarembski |
0:01f31e923fe2 | 1159 | /*! |
Pawel Zarembski |
0:01f31e923fe2 | 1160 | * brief Aborts the interrupt-driven data receiving. |
Pawel Zarembski |
0:01f31e923fe2 | 1161 | * |
Pawel Zarembski |
0:01f31e923fe2 | 1162 | * This function aborts the interrupt-driven data receiving. The user can get the remainBytes to know |
Pawel Zarembski |
0:01f31e923fe2 | 1163 | * how many bytes are not received yet. |
Pawel Zarembski |
0:01f31e923fe2 | 1164 | * |
Pawel Zarembski |
0:01f31e923fe2 | 1165 | * param base UART peripheral base address. |
Pawel Zarembski |
0:01f31e923fe2 | 1166 | * param handle UART handle pointer. |
Pawel Zarembski |
0:01f31e923fe2 | 1167 | */ |
Pawel Zarembski |
0:01f31e923fe2 | 1168 | void UART_TransferAbortReceive(UART_Type *base, uart_handle_t *handle) |
Pawel Zarembski |
0:01f31e923fe2 | 1169 | { |
Pawel Zarembski |
0:01f31e923fe2 | 1170 | assert(handle); |
Pawel Zarembski |
0:01f31e923fe2 | 1171 | |
Pawel Zarembski |
0:01f31e923fe2 | 1172 | /* Only abort the receive to handle->rxData, the RX ring buffer is still working. */ |
Pawel Zarembski |
0:01f31e923fe2 | 1173 | if (!handle->rxRingBuffer) |
Pawel Zarembski |
0:01f31e923fe2 | 1174 | { |
Pawel Zarembski |
0:01f31e923fe2 | 1175 | /* Disable RX interrupt. */ |
Pawel Zarembski |
0:01f31e923fe2 | 1176 | UART_DisableInterrupts(base, kUART_RxDataRegFullInterruptEnable | kUART_RxOverrunInterruptEnable | |
Pawel Zarembski |
0:01f31e923fe2 | 1177 | kUART_FramingErrorInterruptEnable | kUART_IdleLineInterruptEnable); |
Pawel Zarembski |
0:01f31e923fe2 | 1178 | /* Disable parity error interrupt when parity mode is enable*/ |
Pawel Zarembski |
0:01f31e923fe2 | 1179 | if (UART_C1_PE_MASK & base->C1) |
Pawel Zarembski |
0:01f31e923fe2 | 1180 | { |
Pawel Zarembski |
0:01f31e923fe2 | 1181 | UART_DisableInterrupts(base, kUART_ParityErrorInterruptEnable); |
Pawel Zarembski |
0:01f31e923fe2 | 1182 | } |
Pawel Zarembski |
0:01f31e923fe2 | 1183 | } |
Pawel Zarembski |
0:01f31e923fe2 | 1184 | |
Pawel Zarembski |
0:01f31e923fe2 | 1185 | handle->rxDataSize = 0U; |
Pawel Zarembski |
0:01f31e923fe2 | 1186 | handle->rxState = kUART_RxIdle; |
Pawel Zarembski |
0:01f31e923fe2 | 1187 | } |
Pawel Zarembski |
0:01f31e923fe2 | 1188 | |
Pawel Zarembski |
0:01f31e923fe2 | 1189 | /*! |
Pawel Zarembski |
0:01f31e923fe2 | 1190 | * brief Gets the number of bytes that have been received. |
Pawel Zarembski |
0:01f31e923fe2 | 1191 | * |
Pawel Zarembski |
0:01f31e923fe2 | 1192 | * This function gets the number of bytes that have been received. |
Pawel Zarembski |
0:01f31e923fe2 | 1193 | * |
Pawel Zarembski |
0:01f31e923fe2 | 1194 | * param base UART peripheral base address. |
Pawel Zarembski |
0:01f31e923fe2 | 1195 | * param handle UART handle pointer. |
Pawel Zarembski |
0:01f31e923fe2 | 1196 | * param count Receive bytes count. |
Pawel Zarembski |
0:01f31e923fe2 | 1197 | * retval kStatus_NoTransferInProgress No receive in progress. |
Pawel Zarembski |
0:01f31e923fe2 | 1198 | * retval kStatus_InvalidArgument Parameter is invalid. |
Pawel Zarembski |
0:01f31e923fe2 | 1199 | * retval kStatus_Success Get successfully through the parameter \p count; |
Pawel Zarembski |
0:01f31e923fe2 | 1200 | */ |
Pawel Zarembski |
0:01f31e923fe2 | 1201 | status_t UART_TransferGetReceiveCount(UART_Type *base, uart_handle_t *handle, uint32_t *count) |
Pawel Zarembski |
0:01f31e923fe2 | 1202 | { |
Pawel Zarembski |
0:01f31e923fe2 | 1203 | assert(handle); |
Pawel Zarembski |
0:01f31e923fe2 | 1204 | assert(count); |
Pawel Zarembski |
0:01f31e923fe2 | 1205 | |
Pawel Zarembski |
0:01f31e923fe2 | 1206 | if (kUART_RxIdle == handle->rxState) |
Pawel Zarembski |
0:01f31e923fe2 | 1207 | { |
Pawel Zarembski |
0:01f31e923fe2 | 1208 | return kStatus_NoTransferInProgress; |
Pawel Zarembski |
0:01f31e923fe2 | 1209 | } |
Pawel Zarembski |
0:01f31e923fe2 | 1210 | |
Pawel Zarembski |
0:01f31e923fe2 | 1211 | if (!count) |
Pawel Zarembski |
0:01f31e923fe2 | 1212 | { |
Pawel Zarembski |
0:01f31e923fe2 | 1213 | return kStatus_InvalidArgument; |
Pawel Zarembski |
0:01f31e923fe2 | 1214 | } |
Pawel Zarembski |
0:01f31e923fe2 | 1215 | |
Pawel Zarembski |
0:01f31e923fe2 | 1216 | *count = handle->rxDataSizeAll - handle->rxDataSize; |
Pawel Zarembski |
0:01f31e923fe2 | 1217 | |
Pawel Zarembski |
0:01f31e923fe2 | 1218 | return kStatus_Success; |
Pawel Zarembski |
0:01f31e923fe2 | 1219 | } |
Pawel Zarembski |
0:01f31e923fe2 | 1220 | |
Pawel Zarembski |
0:01f31e923fe2 | 1221 | /*! |
Pawel Zarembski |
0:01f31e923fe2 | 1222 | * brief UART IRQ handle function. |
Pawel Zarembski |
0:01f31e923fe2 | 1223 | * |
Pawel Zarembski |
0:01f31e923fe2 | 1224 | * This function handles the UART transmit and receive IRQ request. |
Pawel Zarembski |
0:01f31e923fe2 | 1225 | * |
Pawel Zarembski |
0:01f31e923fe2 | 1226 | * param base UART peripheral base address. |
Pawel Zarembski |
0:01f31e923fe2 | 1227 | * param handle UART handle pointer. |
Pawel Zarembski |
0:01f31e923fe2 | 1228 | */ |
Pawel Zarembski |
0:01f31e923fe2 | 1229 | void UART_TransferHandleIRQ(UART_Type *base, uart_handle_t *handle) |
Pawel Zarembski |
0:01f31e923fe2 | 1230 | { |
Pawel Zarembski |
0:01f31e923fe2 | 1231 | assert(handle); |
Pawel Zarembski |
0:01f31e923fe2 | 1232 | |
Pawel Zarembski |
0:01f31e923fe2 | 1233 | uint8_t count; |
Pawel Zarembski |
0:01f31e923fe2 | 1234 | uint8_t tempCount; |
Pawel Zarembski |
0:01f31e923fe2 | 1235 | uint32_t status = UART_GetStatusFlags(base); |
Pawel Zarembski |
0:01f31e923fe2 | 1236 | |
Pawel Zarembski |
0:01f31e923fe2 | 1237 | /* If RX framing error */ |
Pawel Zarembski |
0:01f31e923fe2 | 1238 | if (kUART_FramingErrorFlag & status) |
Pawel Zarembski |
0:01f31e923fe2 | 1239 | { |
Pawel Zarembski |
0:01f31e923fe2 | 1240 | /* Read base->D to clear framing error flag, otherwise the RX does not work. */ |
Pawel Zarembski |
0:01f31e923fe2 | 1241 | while (base->S1 & UART_S1_RDRF_MASK) |
Pawel Zarembski |
0:01f31e923fe2 | 1242 | { |
Pawel Zarembski |
0:01f31e923fe2 | 1243 | (void)base->D; |
Pawel Zarembski |
0:01f31e923fe2 | 1244 | } |
Pawel Zarembski |
0:01f31e923fe2 | 1245 | #if defined(FSL_FEATURE_UART_HAS_FIFO) && FSL_FEATURE_UART_HAS_FIFO |
Pawel Zarembski |
0:01f31e923fe2 | 1246 | /* Flush FIFO date, otherwise FIFO pointer will be in unknown state. */ |
Pawel Zarembski |
0:01f31e923fe2 | 1247 | base->CFIFO |= UART_CFIFO_RXFLUSH_MASK; |
Pawel Zarembski |
0:01f31e923fe2 | 1248 | #endif |
Pawel Zarembski |
0:01f31e923fe2 | 1249 | |
Pawel Zarembski |
0:01f31e923fe2 | 1250 | handle->rxState = kUART_RxFramingError; |
Pawel Zarembski |
0:01f31e923fe2 | 1251 | handle->rxDataSize = 0U; |
Pawel Zarembski |
0:01f31e923fe2 | 1252 | /* Trigger callback. */ |
Pawel Zarembski |
0:01f31e923fe2 | 1253 | if (handle->callback) |
Pawel Zarembski |
0:01f31e923fe2 | 1254 | { |
Pawel Zarembski |
0:01f31e923fe2 | 1255 | handle->callback(base, handle, kStatus_UART_FramingError, handle->userData); |
Pawel Zarembski |
0:01f31e923fe2 | 1256 | } |
Pawel Zarembski |
0:01f31e923fe2 | 1257 | } |
Pawel Zarembski |
0:01f31e923fe2 | 1258 | |
Pawel Zarembski |
0:01f31e923fe2 | 1259 | /* If RX parity error */ |
Pawel Zarembski |
0:01f31e923fe2 | 1260 | if (kUART_ParityErrorFlag & status) |
Pawel Zarembski |
0:01f31e923fe2 | 1261 | { |
Pawel Zarembski |
0:01f31e923fe2 | 1262 | /* Read base->D to clear parity error flag, otherwise the RX does not work. */ |
Pawel Zarembski |
0:01f31e923fe2 | 1263 | while (base->S1 & UART_S1_RDRF_MASK) |
Pawel Zarembski |
0:01f31e923fe2 | 1264 | { |
Pawel Zarembski |
0:01f31e923fe2 | 1265 | (void)base->D; |
Pawel Zarembski |
0:01f31e923fe2 | 1266 | } |
Pawel Zarembski |
0:01f31e923fe2 | 1267 | #if defined(FSL_FEATURE_UART_HAS_FIFO) && FSL_FEATURE_UART_HAS_FIFO |
Pawel Zarembski |
0:01f31e923fe2 | 1268 | /* Flush FIFO date, otherwise FIFO pointer will be in unknown state. */ |
Pawel Zarembski |
0:01f31e923fe2 | 1269 | base->CFIFO |= UART_CFIFO_RXFLUSH_MASK; |
Pawel Zarembski |
0:01f31e923fe2 | 1270 | #endif |
Pawel Zarembski |
0:01f31e923fe2 | 1271 | |
Pawel Zarembski |
0:01f31e923fe2 | 1272 | handle->rxState = kUART_RxParityError; |
Pawel Zarembski |
0:01f31e923fe2 | 1273 | handle->rxDataSize = 0U; |
Pawel Zarembski |
0:01f31e923fe2 | 1274 | /* Trigger callback. */ |
Pawel Zarembski |
0:01f31e923fe2 | 1275 | if (handle->callback) |
Pawel Zarembski |
0:01f31e923fe2 | 1276 | { |
Pawel Zarembski |
0:01f31e923fe2 | 1277 | handle->callback(base, handle, kStatus_UART_ParityError, handle->userData); |
Pawel Zarembski |
0:01f31e923fe2 | 1278 | } |
Pawel Zarembski |
0:01f31e923fe2 | 1279 | } |
Pawel Zarembski |
0:01f31e923fe2 | 1280 | |
Pawel Zarembski |
0:01f31e923fe2 | 1281 | /* If RX overrun. */ |
Pawel Zarembski |
0:01f31e923fe2 | 1282 | if (kUART_RxOverrunFlag & status) |
Pawel Zarembski |
0:01f31e923fe2 | 1283 | { |
Pawel Zarembski |
0:01f31e923fe2 | 1284 | /* Read base->D to clear overrun flag, otherwise the RX does not work. */ |
Pawel Zarembski |
0:01f31e923fe2 | 1285 | while (base->S1 & UART_S1_RDRF_MASK) |
Pawel Zarembski |
0:01f31e923fe2 | 1286 | { |
Pawel Zarembski |
0:01f31e923fe2 | 1287 | (void)base->D; |
Pawel Zarembski |
0:01f31e923fe2 | 1288 | } |
Pawel Zarembski |
0:01f31e923fe2 | 1289 | #if defined(FSL_FEATURE_UART_HAS_FIFO) && FSL_FEATURE_UART_HAS_FIFO |
Pawel Zarembski |
0:01f31e923fe2 | 1290 | /* Flush FIFO date, otherwise FIFO pointer will be in unknown state. */ |
Pawel Zarembski |
0:01f31e923fe2 | 1291 | base->CFIFO |= UART_CFIFO_RXFLUSH_MASK; |
Pawel Zarembski |
0:01f31e923fe2 | 1292 | #endif |
Pawel Zarembski |
0:01f31e923fe2 | 1293 | /* Trigger callback. */ |
Pawel Zarembski |
0:01f31e923fe2 | 1294 | if (handle->callback) |
Pawel Zarembski |
0:01f31e923fe2 | 1295 | { |
Pawel Zarembski |
0:01f31e923fe2 | 1296 | handle->callback(base, handle, kStatus_UART_RxHardwareOverrun, handle->userData); |
Pawel Zarembski |
0:01f31e923fe2 | 1297 | } |
Pawel Zarembski |
0:01f31e923fe2 | 1298 | } |
Pawel Zarembski |
0:01f31e923fe2 | 1299 | |
Pawel Zarembski |
0:01f31e923fe2 | 1300 | /* If IDLE line was detected. */ |
Pawel Zarembski |
0:01f31e923fe2 | 1301 | if ((kUART_IdleLineFlag & status) && (UART_C2_ILIE_MASK & base->C2)) |
Pawel Zarembski |
0:01f31e923fe2 | 1302 | { |
Pawel Zarembski |
0:01f31e923fe2 | 1303 | #if defined(FSL_FEATURE_UART_HAS_FIFO) && FSL_FEATURE_UART_HAS_FIFO |
Pawel Zarembski |
0:01f31e923fe2 | 1304 | /* If still some data in the FIFO, read out these data to user data buffer. */ |
Pawel Zarembski |
0:01f31e923fe2 | 1305 | count = base->RCFIFO; |
Pawel Zarembski |
0:01f31e923fe2 | 1306 | /* If handle->rxDataSize is not 0, first save data to handle->rxData. */ |
Pawel Zarembski |
0:01f31e923fe2 | 1307 | while ((count) && (handle->rxDataSize)) |
Pawel Zarembski |
0:01f31e923fe2 | 1308 | { |
Pawel Zarembski |
0:01f31e923fe2 | 1309 | tempCount = MIN(handle->rxDataSize, count); |
Pawel Zarembski |
0:01f31e923fe2 | 1310 | |
Pawel Zarembski |
0:01f31e923fe2 | 1311 | /* Using non block API to read the data from the registers. */ |
Pawel Zarembski |
0:01f31e923fe2 | 1312 | UART_ReadNonBlocking(base, handle->rxData, tempCount); |
Pawel Zarembski |
0:01f31e923fe2 | 1313 | handle->rxData += tempCount; |
Pawel Zarembski |
0:01f31e923fe2 | 1314 | handle->rxDataSize -= tempCount; |
Pawel Zarembski |
0:01f31e923fe2 | 1315 | count -= tempCount; |
Pawel Zarembski |
0:01f31e923fe2 | 1316 | |
Pawel Zarembski |
0:01f31e923fe2 | 1317 | /* If all the data required for upper layer is ready, trigger callback. */ |
Pawel Zarembski |
0:01f31e923fe2 | 1318 | if (!handle->rxDataSize) |
Pawel Zarembski |
0:01f31e923fe2 | 1319 | { |
Pawel Zarembski |
0:01f31e923fe2 | 1320 | handle->rxState = kUART_RxIdle; |
Pawel Zarembski |
0:01f31e923fe2 | 1321 | |
Pawel Zarembski |
0:01f31e923fe2 | 1322 | /* Disable RX interrupt/overrun interrupt/fram error/idle line detected interrupt */ |
Pawel Zarembski |
0:01f31e923fe2 | 1323 | UART_DisableInterrupts(base, kUART_RxDataRegFullInterruptEnable | kUART_RxOverrunInterruptEnable | |
Pawel Zarembski |
0:01f31e923fe2 | 1324 | kUART_FramingErrorInterruptEnable); |
Pawel Zarembski |
0:01f31e923fe2 | 1325 | |
Pawel Zarembski |
0:01f31e923fe2 | 1326 | /* Disable parity error interrupt when parity mode is enable*/ |
Pawel Zarembski |
0:01f31e923fe2 | 1327 | if (UART_C1_PE_MASK & base->C1) |
Pawel Zarembski |
0:01f31e923fe2 | 1328 | { |
Pawel Zarembski |
0:01f31e923fe2 | 1329 | UART_DisableInterrupts(base, kUART_ParityErrorInterruptEnable); |
Pawel Zarembski |
0:01f31e923fe2 | 1330 | } |
Pawel Zarembski |
0:01f31e923fe2 | 1331 | |
Pawel Zarembski |
0:01f31e923fe2 | 1332 | if (handle->callback) |
Pawel Zarembski |
0:01f31e923fe2 | 1333 | { |
Pawel Zarembski |
0:01f31e923fe2 | 1334 | handle->callback(base, handle, kStatus_UART_RxIdle, handle->userData); |
Pawel Zarembski |
0:01f31e923fe2 | 1335 | } |
Pawel Zarembski |
0:01f31e923fe2 | 1336 | } |
Pawel Zarembski |
0:01f31e923fe2 | 1337 | } |
Pawel Zarembski |
0:01f31e923fe2 | 1338 | #endif |
Pawel Zarembski |
0:01f31e923fe2 | 1339 | /* To clear IDLE, read UART status S1 with IDLE set and then read D.*/ |
Pawel Zarembski |
0:01f31e923fe2 | 1340 | while (UART_S1_IDLE_MASK & base->S1) |
Pawel Zarembski |
0:01f31e923fe2 | 1341 | { |
Pawel Zarembski |
0:01f31e923fe2 | 1342 | (void)base->D; |
Pawel Zarembski |
0:01f31e923fe2 | 1343 | } |
Pawel Zarembski |
0:01f31e923fe2 | 1344 | #if defined(FSL_FEATURE_UART_HAS_FIFO) && FSL_FEATURE_UART_HAS_FIFO |
Pawel Zarembski |
0:01f31e923fe2 | 1345 | /* Flush FIFO date, otherwise FIFO pointer will be in unknown state. */ |
Pawel Zarembski |
0:01f31e923fe2 | 1346 | base->CFIFO |= UART_CFIFO_RXFLUSH_MASK; |
Pawel Zarembski |
0:01f31e923fe2 | 1347 | #endif |
Pawel Zarembski |
0:01f31e923fe2 | 1348 | /* If rxDataSize is 0, disable idle line interrupt.*/ |
Pawel Zarembski |
0:01f31e923fe2 | 1349 | if (!(handle->rxDataSize)) |
Pawel Zarembski |
0:01f31e923fe2 | 1350 | { |
Pawel Zarembski |
0:01f31e923fe2 | 1351 | UART_DisableInterrupts(base, kUART_IdleLineInterruptEnable); |
Pawel Zarembski |
0:01f31e923fe2 | 1352 | } |
Pawel Zarembski |
0:01f31e923fe2 | 1353 | /* If callback is not NULL and rxDataSize is not 0. */ |
Pawel Zarembski |
0:01f31e923fe2 | 1354 | if ((handle->callback) && (handle->rxDataSize)) |
Pawel Zarembski |
0:01f31e923fe2 | 1355 | { |
Pawel Zarembski |
0:01f31e923fe2 | 1356 | handle->callback(base, handle, kStatus_UART_IdleLineDetected, handle->userData); |
Pawel Zarembski |
0:01f31e923fe2 | 1357 | } |
Pawel Zarembski |
0:01f31e923fe2 | 1358 | } |
Pawel Zarembski |
0:01f31e923fe2 | 1359 | /* Receive data register full */ |
Pawel Zarembski |
0:01f31e923fe2 | 1360 | if ((kUART_RxDataRegFullFlag & status) && (UART_C2_RIE_MASK & base->C2)) |
Pawel Zarembski |
0:01f31e923fe2 | 1361 | { |
Pawel Zarembski |
0:01f31e923fe2 | 1362 | /* Get the size that can be stored into buffer for this interrupt. */ |
Pawel Zarembski |
0:01f31e923fe2 | 1363 | #if defined(FSL_FEATURE_UART_HAS_FIFO) && FSL_FEATURE_UART_HAS_FIFO |
Pawel Zarembski |
0:01f31e923fe2 | 1364 | count = base->RCFIFO; |
Pawel Zarembski |
0:01f31e923fe2 | 1365 | #else |
Pawel Zarembski |
0:01f31e923fe2 | 1366 | count = 1; |
Pawel Zarembski |
0:01f31e923fe2 | 1367 | #endif |
Pawel Zarembski |
0:01f31e923fe2 | 1368 | |
Pawel Zarembski |
0:01f31e923fe2 | 1369 | /* If handle->rxDataSize is not 0, first save data to handle->rxData. */ |
Pawel Zarembski |
0:01f31e923fe2 | 1370 | while ((count) && (handle->rxDataSize)) |
Pawel Zarembski |
0:01f31e923fe2 | 1371 | { |
Pawel Zarembski |
0:01f31e923fe2 | 1372 | #if defined(FSL_FEATURE_UART_HAS_FIFO) && FSL_FEATURE_UART_HAS_FIFO |
Pawel Zarembski |
0:01f31e923fe2 | 1373 | tempCount = MIN(handle->rxDataSize, count); |
Pawel Zarembski |
0:01f31e923fe2 | 1374 | #else |
Pawel Zarembski |
0:01f31e923fe2 | 1375 | tempCount = 1; |
Pawel Zarembski |
0:01f31e923fe2 | 1376 | #endif |
Pawel Zarembski |
0:01f31e923fe2 | 1377 | |
Pawel Zarembski |
0:01f31e923fe2 | 1378 | /* Using non block API to read the data from the registers. */ |
Pawel Zarembski |
0:01f31e923fe2 | 1379 | UART_ReadNonBlocking(base, handle->rxData, tempCount); |
Pawel Zarembski |
0:01f31e923fe2 | 1380 | handle->rxData += tempCount; |
Pawel Zarembski |
0:01f31e923fe2 | 1381 | handle->rxDataSize -= tempCount; |
Pawel Zarembski |
0:01f31e923fe2 | 1382 | count -= tempCount; |
Pawel Zarembski |
0:01f31e923fe2 | 1383 | |
Pawel Zarembski |
0:01f31e923fe2 | 1384 | /* If all the data required for upper layer is ready, trigger callback. */ |
Pawel Zarembski |
0:01f31e923fe2 | 1385 | if (!handle->rxDataSize) |
Pawel Zarembski |
0:01f31e923fe2 | 1386 | { |
Pawel Zarembski |
0:01f31e923fe2 | 1387 | handle->rxState = kUART_RxIdle; |
Pawel Zarembski |
0:01f31e923fe2 | 1388 | |
Pawel Zarembski |
0:01f31e923fe2 | 1389 | if (handle->callback) |
Pawel Zarembski |
0:01f31e923fe2 | 1390 | { |
Pawel Zarembski |
0:01f31e923fe2 | 1391 | handle->callback(base, handle, kStatus_UART_RxIdle, handle->userData); |
Pawel Zarembski |
0:01f31e923fe2 | 1392 | } |
Pawel Zarembski |
0:01f31e923fe2 | 1393 | } |
Pawel Zarembski |
0:01f31e923fe2 | 1394 | } |
Pawel Zarembski |
0:01f31e923fe2 | 1395 | |
Pawel Zarembski |
0:01f31e923fe2 | 1396 | /* If use RX ring buffer, receive data to ring buffer. */ |
Pawel Zarembski |
0:01f31e923fe2 | 1397 | if (handle->rxRingBuffer) |
Pawel Zarembski |
0:01f31e923fe2 | 1398 | { |
Pawel Zarembski |
0:01f31e923fe2 | 1399 | while (count--) |
Pawel Zarembski |
0:01f31e923fe2 | 1400 | { |
Pawel Zarembski |
0:01f31e923fe2 | 1401 | /* If RX ring buffer is full, trigger callback to notify over run. */ |
Pawel Zarembski |
0:01f31e923fe2 | 1402 | if (UART_TransferIsRxRingBufferFull(handle)) |
Pawel Zarembski |
0:01f31e923fe2 | 1403 | { |
Pawel Zarembski |
0:01f31e923fe2 | 1404 | if (handle->callback) |
Pawel Zarembski |
0:01f31e923fe2 | 1405 | { |
Pawel Zarembski |
0:01f31e923fe2 | 1406 | handle->callback(base, handle, kStatus_UART_RxRingBufferOverrun, handle->userData); |
Pawel Zarembski |
0:01f31e923fe2 | 1407 | } |
Pawel Zarembski |
0:01f31e923fe2 | 1408 | } |
Pawel Zarembski |
0:01f31e923fe2 | 1409 | |
Pawel Zarembski |
0:01f31e923fe2 | 1410 | /* If ring buffer is still full after callback function, the oldest data is overrided. */ |
Pawel Zarembski |
0:01f31e923fe2 | 1411 | if (UART_TransferIsRxRingBufferFull(handle)) |
Pawel Zarembski |
0:01f31e923fe2 | 1412 | { |
Pawel Zarembski |
0:01f31e923fe2 | 1413 | /* Increase handle->rxRingBufferTail to make room for new data. */ |
Pawel Zarembski |
0:01f31e923fe2 | 1414 | if (handle->rxRingBufferTail + 1U == handle->rxRingBufferSize) |
Pawel Zarembski |
0:01f31e923fe2 | 1415 | { |
Pawel Zarembski |
0:01f31e923fe2 | 1416 | handle->rxRingBufferTail = 0U; |
Pawel Zarembski |
0:01f31e923fe2 | 1417 | } |
Pawel Zarembski |
0:01f31e923fe2 | 1418 | else |
Pawel Zarembski |
0:01f31e923fe2 | 1419 | { |
Pawel Zarembski |
0:01f31e923fe2 | 1420 | handle->rxRingBufferTail++; |
Pawel Zarembski |
0:01f31e923fe2 | 1421 | } |
Pawel Zarembski |
0:01f31e923fe2 | 1422 | } |
Pawel Zarembski |
0:01f31e923fe2 | 1423 | |
Pawel Zarembski |
0:01f31e923fe2 | 1424 | /* Read data. */ |
Pawel Zarembski |
0:01f31e923fe2 | 1425 | handle->rxRingBuffer[handle->rxRingBufferHead] = base->D; |
Pawel Zarembski |
0:01f31e923fe2 | 1426 | |
Pawel Zarembski |
0:01f31e923fe2 | 1427 | /* Increase handle->rxRingBufferHead. */ |
Pawel Zarembski |
0:01f31e923fe2 | 1428 | if (handle->rxRingBufferHead + 1U == handle->rxRingBufferSize) |
Pawel Zarembski |
0:01f31e923fe2 | 1429 | { |
Pawel Zarembski |
0:01f31e923fe2 | 1430 | handle->rxRingBufferHead = 0U; |
Pawel Zarembski |
0:01f31e923fe2 | 1431 | } |
Pawel Zarembski |
0:01f31e923fe2 | 1432 | else |
Pawel Zarembski |
0:01f31e923fe2 | 1433 | { |
Pawel Zarembski |
0:01f31e923fe2 | 1434 | handle->rxRingBufferHead++; |
Pawel Zarembski |
0:01f31e923fe2 | 1435 | } |
Pawel Zarembski |
0:01f31e923fe2 | 1436 | } |
Pawel Zarembski |
0:01f31e923fe2 | 1437 | } |
Pawel Zarembski |
0:01f31e923fe2 | 1438 | |
Pawel Zarembski |
0:01f31e923fe2 | 1439 | else if (!handle->rxDataSize) |
Pawel Zarembski |
0:01f31e923fe2 | 1440 | { |
Pawel Zarembski |
0:01f31e923fe2 | 1441 | /* Disable RX interrupt/overrun interrupt/fram error/idle line detected interrupt */ |
Pawel Zarembski |
0:01f31e923fe2 | 1442 | UART_DisableInterrupts(base, kUART_RxDataRegFullInterruptEnable | kUART_RxOverrunInterruptEnable | |
Pawel Zarembski |
0:01f31e923fe2 | 1443 | kUART_FramingErrorInterruptEnable); |
Pawel Zarembski |
0:01f31e923fe2 | 1444 | |
Pawel Zarembski |
0:01f31e923fe2 | 1445 | /* Disable parity error interrupt when parity mode is enable*/ |
Pawel Zarembski |
0:01f31e923fe2 | 1446 | if (UART_C1_PE_MASK & base->C1) |
Pawel Zarembski |
0:01f31e923fe2 | 1447 | { |
Pawel Zarembski |
0:01f31e923fe2 | 1448 | UART_DisableInterrupts(base, kUART_ParityErrorInterruptEnable); |
Pawel Zarembski |
0:01f31e923fe2 | 1449 | } |
Pawel Zarembski |
0:01f31e923fe2 | 1450 | } |
Pawel Zarembski |
0:01f31e923fe2 | 1451 | else |
Pawel Zarembski |
0:01f31e923fe2 | 1452 | { |
Pawel Zarembski |
0:01f31e923fe2 | 1453 | } |
Pawel Zarembski |
0:01f31e923fe2 | 1454 | } |
Pawel Zarembski |
0:01f31e923fe2 | 1455 | |
Pawel Zarembski |
0:01f31e923fe2 | 1456 | /* If framing error or parity error happened, stop the RX interrupt when ues no ring buffer */ |
Pawel Zarembski |
0:01f31e923fe2 | 1457 | if (((handle->rxState == kUART_RxFramingError) || (handle->rxState == kUART_RxParityError)) && |
Pawel Zarembski |
0:01f31e923fe2 | 1458 | (!handle->rxRingBuffer)) |
Pawel Zarembski |
0:01f31e923fe2 | 1459 | { |
Pawel Zarembski |
0:01f31e923fe2 | 1460 | UART_DisableInterrupts(base, kUART_RxDataRegFullInterruptEnable | kUART_RxOverrunInterruptEnable | |
Pawel Zarembski |
0:01f31e923fe2 | 1461 | kUART_FramingErrorInterruptEnable | kUART_IdleLineInterruptEnable); |
Pawel Zarembski |
0:01f31e923fe2 | 1462 | |
Pawel Zarembski |
0:01f31e923fe2 | 1463 | /* Disable parity error interrupt when parity mode is enable*/ |
Pawel Zarembski |
0:01f31e923fe2 | 1464 | if (UART_C1_PE_MASK & base->C1) |
Pawel Zarembski |
0:01f31e923fe2 | 1465 | { |
Pawel Zarembski |
0:01f31e923fe2 | 1466 | UART_DisableInterrupts(base, kUART_ParityErrorInterruptEnable); |
Pawel Zarembski |
0:01f31e923fe2 | 1467 | } |
Pawel Zarembski |
0:01f31e923fe2 | 1468 | } |
Pawel Zarembski |
0:01f31e923fe2 | 1469 | |
Pawel Zarembski |
0:01f31e923fe2 | 1470 | /* Send data register empty and the interrupt is enabled. */ |
Pawel Zarembski |
0:01f31e923fe2 | 1471 | if ((kUART_TxDataRegEmptyFlag & status) && (base->C2 & UART_C2_TIE_MASK)) |
Pawel Zarembski |
0:01f31e923fe2 | 1472 | { |
Pawel Zarembski |
0:01f31e923fe2 | 1473 | /* Get the bytes that available at this moment. */ |
Pawel Zarembski |
0:01f31e923fe2 | 1474 | #if defined(FSL_FEATURE_UART_HAS_FIFO) && FSL_FEATURE_UART_HAS_FIFO |
Pawel Zarembski |
0:01f31e923fe2 | 1475 | count = FSL_FEATURE_UART_FIFO_SIZEn(base) - base->TCFIFO; |
Pawel Zarembski |
0:01f31e923fe2 | 1476 | #else |
Pawel Zarembski |
0:01f31e923fe2 | 1477 | count = 1; |
Pawel Zarembski |
0:01f31e923fe2 | 1478 | #endif |
Pawel Zarembski |
0:01f31e923fe2 | 1479 | |
Pawel Zarembski |
0:01f31e923fe2 | 1480 | while ((count) && (handle->txDataSize)) |
Pawel Zarembski |
0:01f31e923fe2 | 1481 | { |
Pawel Zarembski |
0:01f31e923fe2 | 1482 | #if defined(FSL_FEATURE_UART_HAS_FIFO) && FSL_FEATURE_UART_HAS_FIFO |
Pawel Zarembski |
0:01f31e923fe2 | 1483 | tempCount = MIN(handle->txDataSize, count); |
Pawel Zarembski |
0:01f31e923fe2 | 1484 | #else |
Pawel Zarembski |
0:01f31e923fe2 | 1485 | tempCount = 1; |
Pawel Zarembski |
0:01f31e923fe2 | 1486 | #endif |
Pawel Zarembski |
0:01f31e923fe2 | 1487 | |
Pawel Zarembski |
0:01f31e923fe2 | 1488 | /* Using non block API to write the data to the registers. */ |
Pawel Zarembski |
0:01f31e923fe2 | 1489 | UART_WriteNonBlocking(base, handle->txData, tempCount); |
Pawel Zarembski |
0:01f31e923fe2 | 1490 | handle->txData += tempCount; |
Pawel Zarembski |
0:01f31e923fe2 | 1491 | handle->txDataSize -= tempCount; |
Pawel Zarembski |
0:01f31e923fe2 | 1492 | count -= tempCount; |
Pawel Zarembski |
0:01f31e923fe2 | 1493 | |
Pawel Zarembski |
0:01f31e923fe2 | 1494 | /* If all the data are written to data register, TX finished. */ |
Pawel Zarembski |
0:01f31e923fe2 | 1495 | if (!handle->txDataSize) |
Pawel Zarembski |
0:01f31e923fe2 | 1496 | { |
Pawel Zarembski |
0:01f31e923fe2 | 1497 | handle->txState = kUART_TxIdle; |
Pawel Zarembski |
0:01f31e923fe2 | 1498 | |
Pawel Zarembski |
0:01f31e923fe2 | 1499 | /* Disable TX register empty interrupt. */ |
Pawel Zarembski |
0:01f31e923fe2 | 1500 | base->C2 = (base->C2 & ~UART_C2_TIE_MASK); |
Pawel Zarembski |
0:01f31e923fe2 | 1501 | |
Pawel Zarembski |
0:01f31e923fe2 | 1502 | /* Trigger callback. */ |
Pawel Zarembski |
0:01f31e923fe2 | 1503 | if (handle->callback) |
Pawel Zarembski |
0:01f31e923fe2 | 1504 | { |
Pawel Zarembski |
0:01f31e923fe2 | 1505 | handle->callback(base, handle, kStatus_UART_TxIdle, handle->userData); |
Pawel Zarembski |
0:01f31e923fe2 | 1506 | } |
Pawel Zarembski |
0:01f31e923fe2 | 1507 | } |
Pawel Zarembski |
0:01f31e923fe2 | 1508 | } |
Pawel Zarembski |
0:01f31e923fe2 | 1509 | } |
Pawel Zarembski |
0:01f31e923fe2 | 1510 | } |
Pawel Zarembski |
0:01f31e923fe2 | 1511 | |
Pawel Zarembski |
0:01f31e923fe2 | 1512 | /*! |
Pawel Zarembski |
0:01f31e923fe2 | 1513 | * brief UART Error IRQ handle function. |
Pawel Zarembski |
0:01f31e923fe2 | 1514 | * |
Pawel Zarembski |
0:01f31e923fe2 | 1515 | * This function handles the UART error IRQ request. |
Pawel Zarembski |
0:01f31e923fe2 | 1516 | * |
Pawel Zarembski |
0:01f31e923fe2 | 1517 | * param base UART peripheral base address. |
Pawel Zarembski |
0:01f31e923fe2 | 1518 | * param handle UART handle pointer. |
Pawel Zarembski |
0:01f31e923fe2 | 1519 | */ |
Pawel Zarembski |
0:01f31e923fe2 | 1520 | void UART_TransferHandleErrorIRQ(UART_Type *base, uart_handle_t *handle) |
Pawel Zarembski |
0:01f31e923fe2 | 1521 | { |
Pawel Zarembski |
0:01f31e923fe2 | 1522 | /* To be implemented by User. */ |
Pawel Zarembski |
0:01f31e923fe2 | 1523 | } |
Pawel Zarembski |
0:01f31e923fe2 | 1524 | |
Pawel Zarembski |
0:01f31e923fe2 | 1525 | #if defined(UART0) |
Pawel Zarembski |
0:01f31e923fe2 | 1526 | #if ((!(defined(FSL_FEATURE_SOC_LPSCI_COUNT))) || \ |
Pawel Zarembski |
0:01f31e923fe2 | 1527 | ((defined(FSL_FEATURE_SOC_LPSCI_COUNT)) && (FSL_FEATURE_SOC_LPSCI_COUNT == 0))) |
Pawel Zarembski |
0:01f31e923fe2 | 1528 | void UART0_DriverIRQHandler(void) |
Pawel Zarembski |
0:01f31e923fe2 | 1529 | { |
Pawel Zarembski |
0:01f31e923fe2 | 1530 | s_uartIsr(UART0, s_uartHandle[0]); |
Pawel Zarembski |
0:01f31e923fe2 | 1531 | /* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping |
Pawel Zarembski |
0:01f31e923fe2 | 1532 | exception return operation might vector to incorrect interrupt */ |
Pawel Zarembski |
0:01f31e923fe2 | 1533 | #if defined __CORTEX_M && (__CORTEX_M == 4U) |
Pawel Zarembski |
0:01f31e923fe2 | 1534 | __DSB(); |
Pawel Zarembski |
0:01f31e923fe2 | 1535 | #endif |
Pawel Zarembski |
0:01f31e923fe2 | 1536 | } |
Pawel Zarembski |
0:01f31e923fe2 | 1537 | |
Pawel Zarembski |
0:01f31e923fe2 | 1538 | void UART0_RX_TX_DriverIRQHandler(void) |
Pawel Zarembski |
0:01f31e923fe2 | 1539 | { |
Pawel Zarembski |
0:01f31e923fe2 | 1540 | UART0_DriverIRQHandler(); |
Pawel Zarembski |
0:01f31e923fe2 | 1541 | /* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping |
Pawel Zarembski |
0:01f31e923fe2 | 1542 | exception return operation might vector to incorrect interrupt */ |
Pawel Zarembski |
0:01f31e923fe2 | 1543 | #if defined __CORTEX_M && (__CORTEX_M == 4U) |
Pawel Zarembski |
0:01f31e923fe2 | 1544 | __DSB(); |
Pawel Zarembski |
0:01f31e923fe2 | 1545 | #endif |
Pawel Zarembski |
0:01f31e923fe2 | 1546 | } |
Pawel Zarembski |
0:01f31e923fe2 | 1547 | #endif |
Pawel Zarembski |
0:01f31e923fe2 | 1548 | #endif |
Pawel Zarembski |
0:01f31e923fe2 | 1549 | |
Pawel Zarembski |
0:01f31e923fe2 | 1550 | #if defined(UART1) |
Pawel Zarembski |
0:01f31e923fe2 | 1551 | void UART1_DriverIRQHandler(void) |
Pawel Zarembski |
0:01f31e923fe2 | 1552 | { |
Pawel Zarembski |
0:01f31e923fe2 | 1553 | s_uartIsr(UART1, s_uartHandle[1]); |
Pawel Zarembski |
0:01f31e923fe2 | 1554 | /* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping |
Pawel Zarembski |
0:01f31e923fe2 | 1555 | exception return operation might vector to incorrect interrupt */ |
Pawel Zarembski |
0:01f31e923fe2 | 1556 | #if defined __CORTEX_M && (__CORTEX_M == 4U) |
Pawel Zarembski |
0:01f31e923fe2 | 1557 | __DSB(); |
Pawel Zarembski |
0:01f31e923fe2 | 1558 | #endif |
Pawel Zarembski |
0:01f31e923fe2 | 1559 | } |
Pawel Zarembski |
0:01f31e923fe2 | 1560 | |
Pawel Zarembski |
0:01f31e923fe2 | 1561 | void UART1_RX_TX_DriverIRQHandler(void) |
Pawel Zarembski |
0:01f31e923fe2 | 1562 | { |
Pawel Zarembski |
0:01f31e923fe2 | 1563 | UART1_DriverIRQHandler(); |
Pawel Zarembski |
0:01f31e923fe2 | 1564 | /* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping |
Pawel Zarembski |
0:01f31e923fe2 | 1565 | exception return operation might vector to incorrect interrupt */ |
Pawel Zarembski |
0:01f31e923fe2 | 1566 | #if defined __CORTEX_M && (__CORTEX_M == 4U) |
Pawel Zarembski |
0:01f31e923fe2 | 1567 | __DSB(); |
Pawel Zarembski |
0:01f31e923fe2 | 1568 | #endif |
Pawel Zarembski |
0:01f31e923fe2 | 1569 | } |
Pawel Zarembski |
0:01f31e923fe2 | 1570 | #endif |
Pawel Zarembski |
0:01f31e923fe2 | 1571 | |
Pawel Zarembski |
0:01f31e923fe2 | 1572 | #if defined(UART2) |
Pawel Zarembski |
0:01f31e923fe2 | 1573 | void UART2_DriverIRQHandler(void) |
Pawel Zarembski |
0:01f31e923fe2 | 1574 | { |
Pawel Zarembski |
0:01f31e923fe2 | 1575 | s_uartIsr(UART2, s_uartHandle[2]); |
Pawel Zarembski |
0:01f31e923fe2 | 1576 | /* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping |
Pawel Zarembski |
0:01f31e923fe2 | 1577 | exception return operation might vector to incorrect interrupt */ |
Pawel Zarembski |
0:01f31e923fe2 | 1578 | #if defined __CORTEX_M && (__CORTEX_M == 4U) |
Pawel Zarembski |
0:01f31e923fe2 | 1579 | __DSB(); |
Pawel Zarembski |
0:01f31e923fe2 | 1580 | #endif |
Pawel Zarembski |
0:01f31e923fe2 | 1581 | } |
Pawel Zarembski |
0:01f31e923fe2 | 1582 | |
Pawel Zarembski |
0:01f31e923fe2 | 1583 | void UART2_RX_TX_DriverIRQHandler(void) |
Pawel Zarembski |
0:01f31e923fe2 | 1584 | { |
Pawel Zarembski |
0:01f31e923fe2 | 1585 | UART2_DriverIRQHandler(); |
Pawel Zarembski |
0:01f31e923fe2 | 1586 | /* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping |
Pawel Zarembski |
0:01f31e923fe2 | 1587 | exception return operation might vector to incorrect interrupt */ |
Pawel Zarembski |
0:01f31e923fe2 | 1588 | #if defined __CORTEX_M && (__CORTEX_M == 4U) |
Pawel Zarembski |
0:01f31e923fe2 | 1589 | __DSB(); |
Pawel Zarembski |
0:01f31e923fe2 | 1590 | #endif |
Pawel Zarembski |
0:01f31e923fe2 | 1591 | } |
Pawel Zarembski |
0:01f31e923fe2 | 1592 | #endif |
Pawel Zarembski |
0:01f31e923fe2 | 1593 | |
Pawel Zarembski |
0:01f31e923fe2 | 1594 | #if defined(UART3) |
Pawel Zarembski |
0:01f31e923fe2 | 1595 | void UART3_DriverIRQHandler(void) |
Pawel Zarembski |
0:01f31e923fe2 | 1596 | { |
Pawel Zarembski |
0:01f31e923fe2 | 1597 | s_uartIsr(UART3, s_uartHandle[3]); |
Pawel Zarembski |
0:01f31e923fe2 | 1598 | /* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping |
Pawel Zarembski |
0:01f31e923fe2 | 1599 | exception return operation might vector to incorrect interrupt */ |
Pawel Zarembski |
0:01f31e923fe2 | 1600 | #if defined __CORTEX_M && (__CORTEX_M == 4U) |
Pawel Zarembski |
0:01f31e923fe2 | 1601 | __DSB(); |
Pawel Zarembski |
0:01f31e923fe2 | 1602 | #endif |
Pawel Zarembski |
0:01f31e923fe2 | 1603 | } |
Pawel Zarembski |
0:01f31e923fe2 | 1604 | |
Pawel Zarembski |
0:01f31e923fe2 | 1605 | void UART3_RX_TX_DriverIRQHandler(void) |
Pawel Zarembski |
0:01f31e923fe2 | 1606 | { |
Pawel Zarembski |
0:01f31e923fe2 | 1607 | UART3_DriverIRQHandler(); |
Pawel Zarembski |
0:01f31e923fe2 | 1608 | /* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping |
Pawel Zarembski |
0:01f31e923fe2 | 1609 | exception return operation might vector to incorrect interrupt */ |
Pawel Zarembski |
0:01f31e923fe2 | 1610 | #if defined __CORTEX_M && (__CORTEX_M == 4U) |
Pawel Zarembski |
0:01f31e923fe2 | 1611 | __DSB(); |
Pawel Zarembski |
0:01f31e923fe2 | 1612 | #endif |
Pawel Zarembski |
0:01f31e923fe2 | 1613 | } |
Pawel Zarembski |
0:01f31e923fe2 | 1614 | #endif |
Pawel Zarembski |
0:01f31e923fe2 | 1615 | |
Pawel Zarembski |
0:01f31e923fe2 | 1616 | #if defined(UART4) |
Pawel Zarembski |
0:01f31e923fe2 | 1617 | void UART4_DriverIRQHandler(void) |
Pawel Zarembski |
0:01f31e923fe2 | 1618 | { |
Pawel Zarembski |
0:01f31e923fe2 | 1619 | s_uartIsr(UART4, s_uartHandle[4]); |
Pawel Zarembski |
0:01f31e923fe2 | 1620 | /* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping |
Pawel Zarembski |
0:01f31e923fe2 | 1621 | exception return operation might vector to incorrect interrupt */ |
Pawel Zarembski |
0:01f31e923fe2 | 1622 | #if defined __CORTEX_M && (__CORTEX_M == 4U) |
Pawel Zarembski |
0:01f31e923fe2 | 1623 | __DSB(); |
Pawel Zarembski |
0:01f31e923fe2 | 1624 | #endif |
Pawel Zarembski |
0:01f31e923fe2 | 1625 | } |
Pawel Zarembski |
0:01f31e923fe2 | 1626 | |
Pawel Zarembski |
0:01f31e923fe2 | 1627 | void UART4_RX_TX_DriverIRQHandler(void) |
Pawel Zarembski |
0:01f31e923fe2 | 1628 | { |
Pawel Zarembski |
0:01f31e923fe2 | 1629 | UART4_DriverIRQHandler(); |
Pawel Zarembski |
0:01f31e923fe2 | 1630 | /* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping |
Pawel Zarembski |
0:01f31e923fe2 | 1631 | exception return operation might vector to incorrect interrupt */ |
Pawel Zarembski |
0:01f31e923fe2 | 1632 | #if defined __CORTEX_M && (__CORTEX_M == 4U) |
Pawel Zarembski |
0:01f31e923fe2 | 1633 | __DSB(); |
Pawel Zarembski |
0:01f31e923fe2 | 1634 | #endif |
Pawel Zarembski |
0:01f31e923fe2 | 1635 | } |
Pawel Zarembski |
0:01f31e923fe2 | 1636 | #endif |
Pawel Zarembski |
0:01f31e923fe2 | 1637 | |
Pawel Zarembski |
0:01f31e923fe2 | 1638 | #if defined(UART5) |
Pawel Zarembski |
0:01f31e923fe2 | 1639 | void UART5_DriverIRQHandler(void) |
Pawel Zarembski |
0:01f31e923fe2 | 1640 | { |
Pawel Zarembski |
0:01f31e923fe2 | 1641 | s_uartIsr(UART5, s_uartHandle[5]); |
Pawel Zarembski |
0:01f31e923fe2 | 1642 | /* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping |
Pawel Zarembski |
0:01f31e923fe2 | 1643 | exception return operation might vector to incorrect interrupt */ |
Pawel Zarembski |
0:01f31e923fe2 | 1644 | #if defined __CORTEX_M && (__CORTEX_M == 4U) |
Pawel Zarembski |
0:01f31e923fe2 | 1645 | __DSB(); |
Pawel Zarembski |
0:01f31e923fe2 | 1646 | #endif |
Pawel Zarembski |
0:01f31e923fe2 | 1647 | } |
Pawel Zarembski |
0:01f31e923fe2 | 1648 | |
Pawel Zarembski |
0:01f31e923fe2 | 1649 | void UART5_RX_TX_DriverIRQHandler(void) |
Pawel Zarembski |
0:01f31e923fe2 | 1650 | { |
Pawel Zarembski |
0:01f31e923fe2 | 1651 | UART5_DriverIRQHandler(); |
Pawel Zarembski |
0:01f31e923fe2 | 1652 | /* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping |
Pawel Zarembski |
0:01f31e923fe2 | 1653 | exception return operation might vector to incorrect interrupt */ |
Pawel Zarembski |
0:01f31e923fe2 | 1654 | #if defined __CORTEX_M && (__CORTEX_M == 4U) |
Pawel Zarembski |
0:01f31e923fe2 | 1655 | __DSB(); |
Pawel Zarembski |
0:01f31e923fe2 | 1656 | #endif |
Pawel Zarembski |
0:01f31e923fe2 | 1657 | } |
Pawel Zarembski |
0:01f31e923fe2 | 1658 | #endif |