mbed library sources. Supersedes mbed-src.

Dependents:   Nucleo_Hello_Encoder BLE_iBeaconScan AM1805_DEMO DISCO-F429ZI_ExportTemplate1 ... more

Committer:
AnnaBridge
Date:
Wed Feb 20 22:31:08 2019 +0000
Revision:
189:f392fc9709a3
Parent:
186:707f6e361f3e
mbed library release version 165

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Anna Bridge 186:707f6e361f3e 1 /**
Anna Bridge 186:707f6e361f3e 2 * @file
Anna Bridge 186:707f6e361f3e 3 * @brief Function implementations for the UART serial communications
Anna Bridge 186:707f6e361f3e 4 * peripheral module.
Anna Bridge 186:707f6e361f3e 5 */
Anna Bridge 186:707f6e361f3e 6 /* *****************************************************************************
Anna Bridge 186:707f6e361f3e 7 * Copyright (C) 2016 Maxim Integrated Products, Inc., All Rights Reserved.
Anna Bridge 186:707f6e361f3e 8 *
Anna Bridge 186:707f6e361f3e 9 * Permission is hereby granted, free of charge, to any person obtaining a
Anna Bridge 186:707f6e361f3e 10 * copy of this software and associated documentation files (the "Software"),
Anna Bridge 186:707f6e361f3e 11 * to deal in the Software without restriction, including without limitation
Anna Bridge 186:707f6e361f3e 12 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
Anna Bridge 186:707f6e361f3e 13 * and/or sell copies of the Software, and to permit persons to whom the
Anna Bridge 186:707f6e361f3e 14 * Software is furnished to do so, subject to the following conditions:
Anna Bridge 186:707f6e361f3e 15 *
Anna Bridge 186:707f6e361f3e 16 * The above copyright notice and this permission notice shall be included
Anna Bridge 186:707f6e361f3e 17 * in all copies or substantial portions of the Software.
Anna Bridge 186:707f6e361f3e 18 *
Anna Bridge 186:707f6e361f3e 19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
Anna Bridge 186:707f6e361f3e 20 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
Anna Bridge 186:707f6e361f3e 21 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
Anna Bridge 186:707f6e361f3e 22 * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES
Anna Bridge 186:707f6e361f3e 23 * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
Anna Bridge 186:707f6e361f3e 24 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
Anna Bridge 186:707f6e361f3e 25 * OTHER DEALINGS IN THE SOFTWARE.
Anna Bridge 186:707f6e361f3e 26 *
Anna Bridge 186:707f6e361f3e 27 * Except as contained in this notice, the name of Maxim Integrated
Anna Bridge 186:707f6e361f3e 28 * Products, Inc. shall not be used except as stated in the Maxim Integrated
Anna Bridge 186:707f6e361f3e 29 * Products, Inc. Branding Policy.
Anna Bridge 186:707f6e361f3e 30 *
Anna Bridge 186:707f6e361f3e 31 * The mere transfer of this software does not imply any licenses
Anna Bridge 186:707f6e361f3e 32 * of trade secrets, proprietary technology, copyrights, patents,
Anna Bridge 186:707f6e361f3e 33 * trademarks, maskwork rights, or any other form of intellectual
Anna Bridge 186:707f6e361f3e 34 * property whatsoever. Maxim Integrated Products, Inc. retains all
Anna Bridge 186:707f6e361f3e 35 * ownership rights.
Anna Bridge 186:707f6e361f3e 36 *
Anna Bridge 186:707f6e361f3e 37 * $Date: 2017-02-16 08:57:56 -0600 (Thu, 16 Feb 2017) $
Anna Bridge 186:707f6e361f3e 38 * $Revision: 26458 $
Anna Bridge 186:707f6e361f3e 39 *
Anna Bridge 186:707f6e361f3e 40 **************************************************************************** */
Anna Bridge 186:707f6e361f3e 41
Anna Bridge 186:707f6e361f3e 42 /* **** Includes **** */
Anna Bridge 186:707f6e361f3e 43 #include <string.h>
Anna Bridge 186:707f6e361f3e 44 #include "mxc_config.h"
Anna Bridge 186:707f6e361f3e 45 #include "mxc_assert.h"
Anna Bridge 186:707f6e361f3e 46 #include "mxc_lock.h"
Anna Bridge 186:707f6e361f3e 47 #include "mxc_sys.h"
Anna Bridge 186:707f6e361f3e 48 #include "uart.h"
Anna Bridge 186:707f6e361f3e 49
Anna Bridge 186:707f6e361f3e 50
Anna Bridge 186:707f6e361f3e 51
Anna Bridge 186:707f6e361f3e 52 /* **** Definitions **** */
Anna Bridge 186:707f6e361f3e 53 ///@cond
Anna Bridge 186:707f6e361f3e 54 #define UART_ERRORS (MXC_F_UART_INTEN_RX_FIFO_OVERFLOW | \
Anna Bridge 186:707f6e361f3e 55 MXC_F_UART_INTEN_RX_FRAMING_ERR | \
Anna Bridge 186:707f6e361f3e 56 MXC_F_UART_INTEN_RX_PARITY_ERR)
Anna Bridge 186:707f6e361f3e 57
Anna Bridge 186:707f6e361f3e 58 #define UART_READ_INTS (MXC_F_UART_INTEN_RX_FIFO_AF | \
Anna Bridge 186:707f6e361f3e 59 MXC_F_UART_INTEN_RX_FIFO_NOT_EMPTY | \
Anna Bridge 186:707f6e361f3e 60 MXC_F_UART_INTEN_RX_STALLED | \
Anna Bridge 186:707f6e361f3e 61 UART_ERRORS)
Anna Bridge 186:707f6e361f3e 62
Anna Bridge 186:707f6e361f3e 63 #define UART_WRITE_INTS (MXC_F_UART_INTEN_TX_UNSTALLED | \
Anna Bridge 186:707f6e361f3e 64 MXC_F_UART_INTEN_TX_FIFO_AE)
Anna Bridge 186:707f6e361f3e 65
Anna Bridge 186:707f6e361f3e 66 #define UART_RXFIFO_USABLE (MXC_UART_FIFO_DEPTH-3)
Anna Bridge 186:707f6e361f3e 67 ///@endcond
Anna Bridge 186:707f6e361f3e 68
Anna Bridge 186:707f6e361f3e 69 /**
Anna Bridge 186:707f6e361f3e 70 * @ingroup uart_top
Anna Bridge 186:707f6e361f3e 71 * @{
Anna Bridge 186:707f6e361f3e 72 */
Anna Bridge 186:707f6e361f3e 73 /* **** Globals **** */
Anna Bridge 186:707f6e361f3e 74
Anna Bridge 186:707f6e361f3e 75 /**
Anna Bridge 186:707f6e361f3e 76 * Saves the state of the non-blocking/asynchronous read requests
Anna Bridge 186:707f6e361f3e 77 */
Anna Bridge 186:707f6e361f3e 78 static uart_req_t *rx_states[MXC_CFG_UART_INSTANCES];
Anna Bridge 186:707f6e361f3e 79
Anna Bridge 186:707f6e361f3e 80 /**
Anna Bridge 186:707f6e361f3e 81 * Saves the state of the non-blocking/asynchronous write requests
Anna Bridge 186:707f6e361f3e 82 */
Anna Bridge 186:707f6e361f3e 83 static uart_req_t *tx_states[MXC_CFG_UART_INSTANCES];
Anna Bridge 186:707f6e361f3e 84
Anna Bridge 186:707f6e361f3e 85 /* **** Functions **** */
Anna Bridge 186:707f6e361f3e 86 /**
Anna Bridge 186:707f6e361f3e 87 * @brief Asynchronous low-level handler for UART writes.
Anna Bridge 186:707f6e361f3e 88 *
Anna Bridge 186:707f6e361f3e 89 * @param uart Pointer to the UART registers structure for the port being written.
Anna Bridge 186:707f6e361f3e 90 * @param req Pointer to the request structure containing the data left to be written.
Anna Bridge 186:707f6e361f3e 91 * @param[in] uart_num The UART number
Anna Bridge 186:707f6e361f3e 92 */
Anna Bridge 186:707f6e361f3e 93 static void UART_WriteHandler(mxc_uart_regs_t *uart, uart_req_t *req, int uart_num);
Anna Bridge 186:707f6e361f3e 94 /**
Anna Bridge 186:707f6e361f3e 95 * @brief Asynchronous low-level hander for UART reads.
Anna Bridge 186:707f6e361f3e 96 *
Anna Bridge 186:707f6e361f3e 97 * @param uart Pointer to the UART registers structure for the port being read.
Anna Bridge 186:707f6e361f3e 98 * @param req Pointer to the request structure containing the data storage for the read.
Anna Bridge 186:707f6e361f3e 99 * @param[in] uart_num The UART number
Anna Bridge 186:707f6e361f3e 100 * @param[in] flags The UART interrupt flags for error detection and handling.
Anna Bridge 186:707f6e361f3e 101 */
Anna Bridge 186:707f6e361f3e 102 static void UART_ReadHandler(mxc_uart_regs_t *uart, uart_req_t *req, int uart_num,
Anna Bridge 186:707f6e361f3e 103 uint32_t flags);
Anna Bridge 186:707f6e361f3e 104
Anna Bridge 186:707f6e361f3e 105 /* ************************************************************************* */
Anna Bridge 186:707f6e361f3e 106 int UART_Init(mxc_uart_regs_t *uart, const uart_cfg_t *cfg, const sys_cfg_uart_t *sys_cfg)
Anna Bridge 186:707f6e361f3e 107 {
Anna Bridge 186:707f6e361f3e 108 int err;
Anna Bridge 186:707f6e361f3e 109 int uart_num;
Anna Bridge 186:707f6e361f3e 110 uint32_t uart_clk;
Anna Bridge 186:707f6e361f3e 111 uint8_t baud_shift;
Anna Bridge 186:707f6e361f3e 112 uint16_t baud_div;
Anna Bridge 186:707f6e361f3e 113 uint32_t baud, diff_baud;
Anna Bridge 186:707f6e361f3e 114 uint32_t baud_1, diff_baud_1;
Anna Bridge 186:707f6e361f3e 115
Anna Bridge 186:707f6e361f3e 116 // Check the input parameters
Anna Bridge 186:707f6e361f3e 117 uart_num = MXC_UART_GET_IDX(uart);
Anna Bridge 186:707f6e361f3e 118 MXC_ASSERT(uart_num >= 0);
Anna Bridge 186:707f6e361f3e 119
Anna Bridge 186:707f6e361f3e 120 // Set system level configurations
Anna Bridge 186:707f6e361f3e 121 if(sys_cfg != NULL) {
Anna Bridge 186:707f6e361f3e 122 if ((err = SYS_UART_Init(uart, cfg, sys_cfg)) != E_NO_ERROR) {
Anna Bridge 186:707f6e361f3e 123 return err;
Anna Bridge 186:707f6e361f3e 124 }
Anna Bridge 186:707f6e361f3e 125 }
Anna Bridge 186:707f6e361f3e 126
Anna Bridge 186:707f6e361f3e 127 // Initialize state pointers
Anna Bridge 186:707f6e361f3e 128 rx_states[uart_num] = NULL;
Anna Bridge 186:707f6e361f3e 129 tx_states[uart_num] = NULL;
Anna Bridge 186:707f6e361f3e 130
Anna Bridge 186:707f6e361f3e 131 // Drain FIFOs and enable UART
Anna Bridge 186:707f6e361f3e 132 uart->ctrl = 0;
Anna Bridge 186:707f6e361f3e 133 uart->ctrl = (MXC_F_UART_CTRL_UART_EN | MXC_F_UART_CTRL_TX_FIFO_EN |
Anna Bridge 186:707f6e361f3e 134 MXC_F_UART_CTRL_RX_FIFO_EN |
Anna Bridge 186:707f6e361f3e 135 (UART_RXFIFO_USABLE << MXC_F_UART_CTRL_RTS_LEVEL_POS));
Anna Bridge 186:707f6e361f3e 136
Anna Bridge 186:707f6e361f3e 137 // Configure data size, stop bit, parity, cts, and rts
Anna Bridge 186:707f6e361f3e 138 uart->ctrl |= ((cfg->size << MXC_F_UART_CTRL_DATA_SIZE_POS) |
Anna Bridge 186:707f6e361f3e 139 (cfg->extra_stop << MXC_F_UART_CTRL_EXTRA_STOP_POS) |
Anna Bridge 186:707f6e361f3e 140 (cfg->parity << MXC_F_UART_CTRL_PARITY_POS) |
Anna Bridge 186:707f6e361f3e 141 (cfg->cts << MXC_F_UART_CTRL_CTS_EN_POS) |
Anna Bridge 186:707f6e361f3e 142 (cfg->rts << MXC_F_UART_CTRL_RTS_EN_POS));
Anna Bridge 186:707f6e361f3e 143
Anna Bridge 186:707f6e361f3e 144 // Configure the baud rate and divisor
Anna Bridge 186:707f6e361f3e 145 uart_clk = SYS_UART_GetFreq(uart);
Anna Bridge 186:707f6e361f3e 146 MXC_ASSERT(uart_clk > 0);
Anna Bridge 186:707f6e361f3e 147
Anna Bridge 186:707f6e361f3e 148 baud_shift = 2;
Anna Bridge 186:707f6e361f3e 149 baud_div = (uart_clk / (cfg->baud * 4));
Anna Bridge 186:707f6e361f3e 150
Anna Bridge 186:707f6e361f3e 151 // Can not support higher frequencies
Anna Bridge 186:707f6e361f3e 152 if(!baud_div) {
Anna Bridge 186:707f6e361f3e 153 return E_NOT_SUPPORTED;
Anna Bridge 186:707f6e361f3e 154 }
Anna Bridge 186:707f6e361f3e 155
Anna Bridge 186:707f6e361f3e 156 // Decrease the divisor if baud_div is overflowing
Anna Bridge 186:707f6e361f3e 157 while(baud_div > 0xFF) {
Anna Bridge 186:707f6e361f3e 158 if(baud_shift == 0) {
Anna Bridge 186:707f6e361f3e 159 return E_NOT_SUPPORTED;
Anna Bridge 186:707f6e361f3e 160 }
Anna Bridge 186:707f6e361f3e 161 baud_shift--;
Anna Bridge 186:707f6e361f3e 162 baud_div = (uart_clk / (cfg->baud * (16 >> baud_shift)));
Anna Bridge 186:707f6e361f3e 163 }
Anna Bridge 186:707f6e361f3e 164
Anna Bridge 186:707f6e361f3e 165 // Adjust baud_div so we don't overflow with the calculations below
Anna Bridge 186:707f6e361f3e 166 if(baud_div == 0xFF) {
Anna Bridge 186:707f6e361f3e 167 baud_div = 0xFE;
Anna Bridge 186:707f6e361f3e 168 }
Anna Bridge 186:707f6e361f3e 169 if(baud_div == 0) {
Anna Bridge 186:707f6e361f3e 170 baud_div = 1;
Anna Bridge 186:707f6e361f3e 171 }
Anna Bridge 186:707f6e361f3e 172
Anna Bridge 186:707f6e361f3e 173 // Figure out if the truncation increased the error
Anna Bridge 186:707f6e361f3e 174 baud = (uart_clk / (baud_div * (16 >> baud_shift)));
Anna Bridge 186:707f6e361f3e 175 baud_1 = (uart_clk / ((baud_div+1) * (16 >> baud_shift)));
Anna Bridge 186:707f6e361f3e 176
Anna Bridge 186:707f6e361f3e 177 if(cfg->baud > baud) {
Anna Bridge 186:707f6e361f3e 178 diff_baud = cfg->baud - baud;
Anna Bridge 186:707f6e361f3e 179 } else {
Anna Bridge 186:707f6e361f3e 180 diff_baud = baud - cfg->baud;
Anna Bridge 186:707f6e361f3e 181 }
Anna Bridge 186:707f6e361f3e 182
Anna Bridge 186:707f6e361f3e 183 if(cfg->baud > baud_1) {
Anna Bridge 186:707f6e361f3e 184 diff_baud_1 = cfg->baud - baud_1;
Anna Bridge 186:707f6e361f3e 185 } else {
Anna Bridge 186:707f6e361f3e 186 diff_baud_1 = baud_1 - cfg->baud;
Anna Bridge 186:707f6e361f3e 187 }
Anna Bridge 186:707f6e361f3e 188
Anna Bridge 186:707f6e361f3e 189 if(diff_baud < diff_baud_1) {
Anna Bridge 186:707f6e361f3e 190 uart->baud = ((baud_div & MXC_F_UART_BAUD_BAUD_DIVISOR) |
Anna Bridge 186:707f6e361f3e 191 (baud_shift << MXC_F_UART_BAUD_BAUD_MODE_POS));
Anna Bridge 186:707f6e361f3e 192 } else {
Anna Bridge 186:707f6e361f3e 193 uart->baud = (((baud_div+1) & MXC_F_UART_BAUD_BAUD_DIVISOR) |
Anna Bridge 186:707f6e361f3e 194 (baud_shift << MXC_F_UART_BAUD_BAUD_MODE_POS));
Anna Bridge 186:707f6e361f3e 195 }
Anna Bridge 186:707f6e361f3e 196
Anna Bridge 186:707f6e361f3e 197 return E_NO_ERROR;
Anna Bridge 186:707f6e361f3e 198 }
Anna Bridge 186:707f6e361f3e 199
Anna Bridge 186:707f6e361f3e 200 /* ************************************************************************* */
Anna Bridge 186:707f6e361f3e 201 int UART_Shutdown(mxc_uart_regs_t *uart)
Anna Bridge 186:707f6e361f3e 202 {
Anna Bridge 186:707f6e361f3e 203 int uart_num, err;
Anna Bridge 186:707f6e361f3e 204 uart_req_t *temp_req;
Anna Bridge 186:707f6e361f3e 205
Anna Bridge 186:707f6e361f3e 206 uart_num = MXC_UART_GET_IDX(uart);
Anna Bridge 186:707f6e361f3e 207 MXC_ASSERT(uart_num >= 0);
Anna Bridge 186:707f6e361f3e 208
Anna Bridge 186:707f6e361f3e 209 // Disable and clear interrupts
Anna Bridge 186:707f6e361f3e 210 uart->inten = 0;
Anna Bridge 186:707f6e361f3e 211 uart->intfl = uart->intfl;
Anna Bridge 186:707f6e361f3e 212
Anna Bridge 186:707f6e361f3e 213 // Disable UART and FIFOS
Anna Bridge 186:707f6e361f3e 214 uart->ctrl &= ~(MXC_F_UART_CTRL_UART_EN | MXC_F_UART_CTRL_TX_FIFO_EN |
Anna Bridge 186:707f6e361f3e 215 MXC_F_UART_CTRL_RX_FIFO_EN);
Anna Bridge 186:707f6e361f3e 216
Anna Bridge 186:707f6e361f3e 217 // Call all of the pending callbacks for this UART
Anna Bridge 186:707f6e361f3e 218 if(rx_states[uart_num] != NULL) {
Anna Bridge 186:707f6e361f3e 219
Anna Bridge 186:707f6e361f3e 220 // Save the request
Anna Bridge 186:707f6e361f3e 221 temp_req = rx_states[uart_num];
Anna Bridge 186:707f6e361f3e 222
Anna Bridge 186:707f6e361f3e 223 // Unlock this UART to read
Anna Bridge 186:707f6e361f3e 224 mxc_free_lock((uint32_t*)&rx_states[uart_num]);
Anna Bridge 186:707f6e361f3e 225
Anna Bridge 186:707f6e361f3e 226 // Callback if not NULL
Anna Bridge 186:707f6e361f3e 227 if(temp_req->callback != NULL) {
Anna Bridge 186:707f6e361f3e 228 temp_req->callback(temp_req, E_SHUTDOWN);
Anna Bridge 186:707f6e361f3e 229 }
Anna Bridge 186:707f6e361f3e 230 }
Anna Bridge 186:707f6e361f3e 231
Anna Bridge 186:707f6e361f3e 232 if(tx_states[uart_num] != NULL) {
Anna Bridge 186:707f6e361f3e 233
Anna Bridge 186:707f6e361f3e 234 // Save the request
Anna Bridge 186:707f6e361f3e 235 temp_req = tx_states[uart_num];
Anna Bridge 186:707f6e361f3e 236
Anna Bridge 186:707f6e361f3e 237 // Unlock this UART to write
Anna Bridge 186:707f6e361f3e 238 mxc_free_lock((uint32_t*)&tx_states[uart_num]);
Anna Bridge 186:707f6e361f3e 239
Anna Bridge 186:707f6e361f3e 240 // Callback if not NULL
Anna Bridge 186:707f6e361f3e 241 if(temp_req->callback != NULL) {
Anna Bridge 186:707f6e361f3e 242 temp_req->callback(temp_req, E_SHUTDOWN);
Anna Bridge 186:707f6e361f3e 243 }
Anna Bridge 186:707f6e361f3e 244 }
Anna Bridge 186:707f6e361f3e 245
Anna Bridge 186:707f6e361f3e 246 // Clears system level configurations
Anna Bridge 186:707f6e361f3e 247 if ((err = SYS_UART_Shutdown(uart)) != E_NO_ERROR) {
Anna Bridge 186:707f6e361f3e 248 return err;
Anna Bridge 186:707f6e361f3e 249 }
Anna Bridge 186:707f6e361f3e 250
Anna Bridge 186:707f6e361f3e 251 return E_NO_ERROR;
Anna Bridge 186:707f6e361f3e 252 }
Anna Bridge 186:707f6e361f3e 253
Anna Bridge 186:707f6e361f3e 254 /* ************************************************************************* */
Anna Bridge 186:707f6e361f3e 255 int UART_Write(mxc_uart_regs_t *uart, uint8_t* data, int len)
Anna Bridge 186:707f6e361f3e 256 {
Anna Bridge 186:707f6e361f3e 257 int num, uart_num;
Anna Bridge 186:707f6e361f3e 258 mxc_uart_fifo_regs_t *fifo;
Anna Bridge 186:707f6e361f3e 259
Anna Bridge 186:707f6e361f3e 260 uart_num = MXC_UART_GET_IDX(uart);
Anna Bridge 186:707f6e361f3e 261 MXC_ASSERT(uart_num >= 0);
Anna Bridge 186:707f6e361f3e 262
Anna Bridge 186:707f6e361f3e 263 if(data == NULL) {
Anna Bridge 186:707f6e361f3e 264 return E_NULL_PTR;
Anna Bridge 186:707f6e361f3e 265 }
Anna Bridge 186:707f6e361f3e 266
Anna Bridge 186:707f6e361f3e 267 // Make sure the UART has been initialized
Anna Bridge 186:707f6e361f3e 268 if(!(uart->ctrl & MXC_F_UART_CTRL_UART_EN)) {
Anna Bridge 186:707f6e361f3e 269 return E_UNINITIALIZED;
Anna Bridge 186:707f6e361f3e 270 }
Anna Bridge 186:707f6e361f3e 271
Anna Bridge 186:707f6e361f3e 272 if(!(len > 0)) {
Anna Bridge 186:707f6e361f3e 273 return E_NO_ERROR;
Anna Bridge 186:707f6e361f3e 274 }
Anna Bridge 186:707f6e361f3e 275
Anna Bridge 186:707f6e361f3e 276 // Lock this UART from writing
Anna Bridge 186:707f6e361f3e 277 while(mxc_get_lock((uint32_t*)&tx_states[uart_num], 1) != E_NO_ERROR) {}
Anna Bridge 186:707f6e361f3e 278
Anna Bridge 186:707f6e361f3e 279 // Get the FIFO for this UART
Anna Bridge 186:707f6e361f3e 280 fifo = MXC_UART_GET_FIFO(uart_num);
Anna Bridge 186:707f6e361f3e 281
Anna Bridge 186:707f6e361f3e 282 num = 0;
Anna Bridge 186:707f6e361f3e 283
Anna Bridge 186:707f6e361f3e 284 while(num < len) {
Anna Bridge 186:707f6e361f3e 285
Anna Bridge 186:707f6e361f3e 286 // Wait for TXFIFO to not be full
Anna Bridge 186:707f6e361f3e 287 while((uart->tx_fifo_ctrl & MXC_F_UART_TX_FIFO_CTRL_FIFO_ENTRY) ==
Anna Bridge 186:707f6e361f3e 288 MXC_F_UART_TX_FIFO_CTRL_FIFO_ENTRY) {}
Anna Bridge 186:707f6e361f3e 289
Anna Bridge 186:707f6e361f3e 290 // Write the data to the FIFO
Anna Bridge 186:707f6e361f3e 291 #if(MXC_UART_REV == 0)
Anna Bridge 186:707f6e361f3e 292 uart->intfl = MXC_F_UART_INTFL_TX_DONE;
Anna Bridge 186:707f6e361f3e 293 #endif
Anna Bridge 186:707f6e361f3e 294 fifo->tx = data[num++];
Anna Bridge 186:707f6e361f3e 295 }
Anna Bridge 186:707f6e361f3e 296
Anna Bridge 186:707f6e361f3e 297 // Unlock this UART to write
Anna Bridge 186:707f6e361f3e 298 mxc_free_lock((uint32_t*)&tx_states[uart_num]);
Anna Bridge 186:707f6e361f3e 299
Anna Bridge 186:707f6e361f3e 300 return num;
Anna Bridge 186:707f6e361f3e 301 }
Anna Bridge 186:707f6e361f3e 302
Anna Bridge 186:707f6e361f3e 303 /* ************************************************************************* */
Anna Bridge 186:707f6e361f3e 304 int UART_Read(mxc_uart_regs_t *uart, uint8_t* data, int len, int *num)
Anna Bridge 186:707f6e361f3e 305 {
Anna Bridge 186:707f6e361f3e 306 int num_local, remain, uart_num;
Anna Bridge 186:707f6e361f3e 307 mxc_uart_fifo_regs_t *fifo;
Anna Bridge 186:707f6e361f3e 308
Anna Bridge 186:707f6e361f3e 309 uart_num = MXC_UART_GET_IDX(uart);
Anna Bridge 186:707f6e361f3e 310 MXC_ASSERT(uart_num >= 0);
Anna Bridge 186:707f6e361f3e 311
Anna Bridge 186:707f6e361f3e 312 if(data == NULL) {
Anna Bridge 186:707f6e361f3e 313 return E_NULL_PTR;
Anna Bridge 186:707f6e361f3e 314 }
Anna Bridge 186:707f6e361f3e 315
Anna Bridge 186:707f6e361f3e 316 // Make sure the UART has been initialized
Anna Bridge 186:707f6e361f3e 317 if(!(uart->ctrl & MXC_F_UART_CTRL_UART_EN)) {
Anna Bridge 186:707f6e361f3e 318 return E_UNINITIALIZED;
Anna Bridge 186:707f6e361f3e 319 }
Anna Bridge 186:707f6e361f3e 320
Anna Bridge 186:707f6e361f3e 321 if(!(len > 0)) {
Anna Bridge 186:707f6e361f3e 322 return E_NO_ERROR;
Anna Bridge 186:707f6e361f3e 323 }
Anna Bridge 186:707f6e361f3e 324
Anna Bridge 186:707f6e361f3e 325 // Lock this UART from reading
Anna Bridge 186:707f6e361f3e 326 while(mxc_get_lock((uint32_t*)&rx_states[uart_num], 1) != E_NO_ERROR) {}
Anna Bridge 186:707f6e361f3e 327
Anna Bridge 186:707f6e361f3e 328 // Get the FIFO for this UART
Anna Bridge 186:707f6e361f3e 329 fifo = MXC_UART_GET_FIFO(uart_num);
Anna Bridge 186:707f6e361f3e 330
Anna Bridge 186:707f6e361f3e 331 num_local = 0;
Anna Bridge 186:707f6e361f3e 332 remain = len;
Anna Bridge 186:707f6e361f3e 333 while(remain) {
Anna Bridge 186:707f6e361f3e 334
Anna Bridge 186:707f6e361f3e 335 // Save the data in the FIFO
Anna Bridge 186:707f6e361f3e 336 while((uart->rx_fifo_ctrl & MXC_F_UART_RX_FIFO_CTRL_FIFO_ENTRY) && remain) {
Anna Bridge 186:707f6e361f3e 337 data[num_local] = fifo->rx;
Anna Bridge 186:707f6e361f3e 338 num_local++;
Anna Bridge 186:707f6e361f3e 339 remain--;
Anna Bridge 186:707f6e361f3e 340 }
Anna Bridge 186:707f6e361f3e 341
Anna Bridge 186:707f6e361f3e 342 // Break if there is an error
Anna Bridge 186:707f6e361f3e 343 if(uart->intfl & UART_ERRORS) {
Anna Bridge 186:707f6e361f3e 344 break;
Anna Bridge 186:707f6e361f3e 345 }
Anna Bridge 186:707f6e361f3e 346 }
Anna Bridge 186:707f6e361f3e 347
Anna Bridge 186:707f6e361f3e 348 // Save the number of bytes read if pointer is valid
Anna Bridge 186:707f6e361f3e 349 if(num != NULL) {
Anna Bridge 186:707f6e361f3e 350 *num = num_local;
Anna Bridge 186:707f6e361f3e 351 }
Anna Bridge 186:707f6e361f3e 352
Anna Bridge 186:707f6e361f3e 353 // Check for errors
Anna Bridge 186:707f6e361f3e 354 if(uart->intfl & MXC_F_UART_INTFL_RX_FIFO_OVERFLOW) {
Anna Bridge 186:707f6e361f3e 355
Anna Bridge 186:707f6e361f3e 356 // Clear errors and return error code
Anna Bridge 186:707f6e361f3e 357 uart->intfl = UART_ERRORS;
Anna Bridge 186:707f6e361f3e 358
Anna Bridge 186:707f6e361f3e 359
Anna Bridge 186:707f6e361f3e 360 // Unlock this UART to read
Anna Bridge 186:707f6e361f3e 361 mxc_free_lock((uint32_t*)&rx_states[uart_num]);
Anna Bridge 186:707f6e361f3e 362
Anna Bridge 186:707f6e361f3e 363 return E_OVERFLOW;
Anna Bridge 186:707f6e361f3e 364
Anna Bridge 186:707f6e361f3e 365 } else if(uart->intfl & (MXC_F_UART_INTFL_RX_FRAMING_ERR |
Anna Bridge 186:707f6e361f3e 366 MXC_F_UART_INTFL_RX_PARITY_ERR)) {
Anna Bridge 186:707f6e361f3e 367
Anna Bridge 186:707f6e361f3e 368 // Clear errors and return error code
Anna Bridge 186:707f6e361f3e 369 uart->intfl = UART_ERRORS;
Anna Bridge 186:707f6e361f3e 370
Anna Bridge 186:707f6e361f3e 371
Anna Bridge 186:707f6e361f3e 372 // Unlock this UART to read
Anna Bridge 186:707f6e361f3e 373 mxc_free_lock((uint32_t*)&rx_states[uart_num]);
Anna Bridge 186:707f6e361f3e 374
Anna Bridge 186:707f6e361f3e 375 return E_COMM_ERR;
Anna Bridge 186:707f6e361f3e 376 }
Anna Bridge 186:707f6e361f3e 377
Anna Bridge 186:707f6e361f3e 378 // Unlock this UART to read
Anna Bridge 186:707f6e361f3e 379 mxc_free_lock((uint32_t*)&rx_states[uart_num]);
Anna Bridge 186:707f6e361f3e 380
Anna Bridge 186:707f6e361f3e 381 return num_local;
Anna Bridge 186:707f6e361f3e 382 }
Anna Bridge 186:707f6e361f3e 383
Anna Bridge 186:707f6e361f3e 384 /* ************************************************************************* */
Anna Bridge 186:707f6e361f3e 385 int UART_WriteAsync(mxc_uart_regs_t *uart, uart_req_t *req)
Anna Bridge 186:707f6e361f3e 386 {
Anna Bridge 186:707f6e361f3e 387 int uart_num = MXC_UART_GET_IDX(uart);
Anna Bridge 186:707f6e361f3e 388 MXC_ASSERT(uart_num >= 0);
Anna Bridge 186:707f6e361f3e 389
Anna Bridge 186:707f6e361f3e 390 // Check the input parameters
Anna Bridge 186:707f6e361f3e 391 if(req->data == NULL) {
Anna Bridge 186:707f6e361f3e 392 return E_NULL_PTR;
Anna Bridge 186:707f6e361f3e 393 }
Anna Bridge 186:707f6e361f3e 394
Anna Bridge 186:707f6e361f3e 395 // Make sure the UART has been initialized
Anna Bridge 186:707f6e361f3e 396 if(!(uart->ctrl & MXC_F_UART_CTRL_UART_EN)) {
Anna Bridge 186:707f6e361f3e 397 return E_UNINITIALIZED;
Anna Bridge 186:707f6e361f3e 398 }
Anna Bridge 186:707f6e361f3e 399
Anna Bridge 186:707f6e361f3e 400 if(!(req->len > 0)) {
Anna Bridge 186:707f6e361f3e 401 return E_NO_ERROR;
Anna Bridge 186:707f6e361f3e 402 }
Anna Bridge 186:707f6e361f3e 403
Anna Bridge 186:707f6e361f3e 404 // Attempt to register this write request
Anna Bridge 186:707f6e361f3e 405 if(mxc_get_lock((uint32_t*)&tx_states[uart_num], (uint32_t)req) != E_NO_ERROR) {
Anna Bridge 186:707f6e361f3e 406 return E_BUSY;
Anna Bridge 186:707f6e361f3e 407 }
Anna Bridge 186:707f6e361f3e 408
Anna Bridge 186:707f6e361f3e 409 // Clear the number of bytes counter
Anna Bridge 186:707f6e361f3e 410 req->num = 0;
Anna Bridge 186:707f6e361f3e 411
Anna Bridge 186:707f6e361f3e 412 // Start the write
Anna Bridge 186:707f6e361f3e 413 UART_WriteHandler(uart, req, uart_num);
Anna Bridge 186:707f6e361f3e 414
Anna Bridge 186:707f6e361f3e 415 return E_NO_ERROR;
Anna Bridge 186:707f6e361f3e 416 }
Anna Bridge 186:707f6e361f3e 417
Anna Bridge 186:707f6e361f3e 418 /* ************************************************************************* */
Anna Bridge 186:707f6e361f3e 419 int UART_ReadAsync(mxc_uart_regs_t *uart, uart_req_t *req)
Anna Bridge 186:707f6e361f3e 420 {
Anna Bridge 186:707f6e361f3e 421 int uart_num;
Anna Bridge 186:707f6e361f3e 422 uint32_t flags;
Anna Bridge 186:707f6e361f3e 423
Anna Bridge 186:707f6e361f3e 424 uart_num = MXC_UART_GET_IDX(uart);
Anna Bridge 186:707f6e361f3e 425 MXC_ASSERT(uart_num >= 0);
Anna Bridge 186:707f6e361f3e 426
Anna Bridge 186:707f6e361f3e 427 if(req->data == NULL) {
Anna Bridge 186:707f6e361f3e 428 return E_NULL_PTR;
Anna Bridge 186:707f6e361f3e 429 }
Anna Bridge 186:707f6e361f3e 430
Anna Bridge 186:707f6e361f3e 431 // Make sure the UART has been initialized
Anna Bridge 186:707f6e361f3e 432 if(!(uart->ctrl & MXC_F_UART_CTRL_UART_EN)) {
Anna Bridge 186:707f6e361f3e 433 return E_UNINITIALIZED;
Anna Bridge 186:707f6e361f3e 434 }
Anna Bridge 186:707f6e361f3e 435
Anna Bridge 186:707f6e361f3e 436 if(!(req->len > 0)) {
Anna Bridge 186:707f6e361f3e 437 return E_NO_ERROR;
Anna Bridge 186:707f6e361f3e 438 }
Anna Bridge 186:707f6e361f3e 439
Anna Bridge 186:707f6e361f3e 440 // Attempt to register this write request
Anna Bridge 186:707f6e361f3e 441 if(mxc_get_lock((uint32_t*)&rx_states[uart_num], (uint32_t)req) != E_NO_ERROR) {
Anna Bridge 186:707f6e361f3e 442 return E_BUSY;
Anna Bridge 186:707f6e361f3e 443 }
Anna Bridge 186:707f6e361f3e 444
Anna Bridge 186:707f6e361f3e 445 // Clear the number of bytes counter
Anna Bridge 186:707f6e361f3e 446 req->num = 0;
Anna Bridge 186:707f6e361f3e 447
Anna Bridge 186:707f6e361f3e 448 // Start the read
Anna Bridge 186:707f6e361f3e 449 flags = uart->intfl;
Anna Bridge 186:707f6e361f3e 450 uart->intfl = flags;
Anna Bridge 186:707f6e361f3e 451 UART_ReadHandler(uart, req, uart_num, flags);
Anna Bridge 186:707f6e361f3e 452
Anna Bridge 186:707f6e361f3e 453 return E_NO_ERROR;
Anna Bridge 186:707f6e361f3e 454 }
Anna Bridge 186:707f6e361f3e 455
Anna Bridge 186:707f6e361f3e 456 /* ************************************************************************* */
Anna Bridge 186:707f6e361f3e 457 int UART_AbortAsync(uart_req_t *req)
Anna Bridge 186:707f6e361f3e 458 {
Anna Bridge 186:707f6e361f3e 459 int uart_num;
Anna Bridge 186:707f6e361f3e 460
Anna Bridge 186:707f6e361f3e 461 // Figure out if this was a read or write request, find the request, set to NULL
Anna Bridge 186:707f6e361f3e 462 for(uart_num = 0; uart_num < MXC_CFG_UART_INSTANCES; uart_num++) {
Anna Bridge 186:707f6e361f3e 463 if(req == rx_states[uart_num]) {
Anna Bridge 186:707f6e361f3e 464
Anna Bridge 186:707f6e361f3e 465 // Disable read interrupts, clear flags.
Anna Bridge 186:707f6e361f3e 466 MXC_UART_GET_UART(uart_num)->inten &= ~UART_READ_INTS;
Anna Bridge 186:707f6e361f3e 467 MXC_UART_GET_UART(uart_num)->intfl = UART_READ_INTS;
Anna Bridge 186:707f6e361f3e 468
Anna Bridge 186:707f6e361f3e 469 // Unlock this UART to read
Anna Bridge 186:707f6e361f3e 470 mxc_free_lock((uint32_t*)&rx_states[uart_num]);
Anna Bridge 186:707f6e361f3e 471
Anna Bridge 186:707f6e361f3e 472 // Callback if not NULL
Anna Bridge 186:707f6e361f3e 473 if(req->callback != NULL) {
Anna Bridge 186:707f6e361f3e 474 req->callback(req, E_ABORT);
Anna Bridge 186:707f6e361f3e 475 }
Anna Bridge 186:707f6e361f3e 476
Anna Bridge 186:707f6e361f3e 477 return E_NO_ERROR;
Anna Bridge 186:707f6e361f3e 478 }
Anna Bridge 186:707f6e361f3e 479
Anna Bridge 186:707f6e361f3e 480 if(req == tx_states[uart_num]) {
Anna Bridge 186:707f6e361f3e 481
Anna Bridge 186:707f6e361f3e 482 // Disable write interrupts, clear flags.
Anna Bridge 186:707f6e361f3e 483 MXC_UART_GET_UART(uart_num)->inten &= ~(UART_WRITE_INTS);
Anna Bridge 186:707f6e361f3e 484 MXC_UART_GET_UART(uart_num)->intfl = UART_WRITE_INTS;
Anna Bridge 186:707f6e361f3e 485
Anna Bridge 186:707f6e361f3e 486 // Unlock this UART to write
Anna Bridge 186:707f6e361f3e 487 mxc_free_lock((uint32_t*)&tx_states[uart_num]);
Anna Bridge 186:707f6e361f3e 488
Anna Bridge 186:707f6e361f3e 489 // Callback if not NULL
Anna Bridge 186:707f6e361f3e 490 if(req->callback != NULL) {
Anna Bridge 186:707f6e361f3e 491 req->callback(req, E_ABORT);
Anna Bridge 186:707f6e361f3e 492 }
Anna Bridge 186:707f6e361f3e 493
Anna Bridge 186:707f6e361f3e 494 return E_NO_ERROR;
Anna Bridge 186:707f6e361f3e 495 }
Anna Bridge 186:707f6e361f3e 496 }
Anna Bridge 186:707f6e361f3e 497
Anna Bridge 186:707f6e361f3e 498 return E_BAD_PARAM;
Anna Bridge 186:707f6e361f3e 499 }
Anna Bridge 186:707f6e361f3e 500
Anna Bridge 186:707f6e361f3e 501 /* ************************************************************************* */
Anna Bridge 186:707f6e361f3e 502 void UART_Handler(mxc_uart_regs_t *uart)
Anna Bridge 186:707f6e361f3e 503 {
Anna Bridge 186:707f6e361f3e 504 int uart_num;
Anna Bridge 186:707f6e361f3e 505 uint32_t flags;
Anna Bridge 186:707f6e361f3e 506
Anna Bridge 186:707f6e361f3e 507 uart_num = MXC_UART_GET_IDX(uart);
Anna Bridge 186:707f6e361f3e 508 MXC_ASSERT(uart_num >= 0);
Anna Bridge 186:707f6e361f3e 509
Anna Bridge 186:707f6e361f3e 510 flags = uart->intfl;
Anna Bridge 186:707f6e361f3e 511 uart->intfl = flags;
Anna Bridge 186:707f6e361f3e 512
Anna Bridge 186:707f6e361f3e 513 // Figure out if this UART has an active Read request
Anna Bridge 186:707f6e361f3e 514 if((rx_states[uart_num] != NULL) && (flags & UART_READ_INTS)) {
Anna Bridge 186:707f6e361f3e 515 UART_ReadHandler(uart, rx_states[uart_num], uart_num, flags);
Anna Bridge 186:707f6e361f3e 516 }
Anna Bridge 186:707f6e361f3e 517
Anna Bridge 186:707f6e361f3e 518 // Figure out if this UART has an active Write request
Anna Bridge 186:707f6e361f3e 519 if((tx_states[uart_num] != NULL) && (flags & (UART_WRITE_INTS))) {
Anna Bridge 186:707f6e361f3e 520
Anna Bridge 186:707f6e361f3e 521 UART_WriteHandler(uart, tx_states[uart_num], uart_num);
Anna Bridge 186:707f6e361f3e 522 }
Anna Bridge 186:707f6e361f3e 523 }
Anna Bridge 186:707f6e361f3e 524 /* ************************************************************************* */
Anna Bridge 186:707f6e361f3e 525 int UART_Busy(mxc_uart_regs_t *uart)
Anna Bridge 186:707f6e361f3e 526 {
Anna Bridge 186:707f6e361f3e 527 int uart_num = MXC_UART_GET_IDX(uart);
Anna Bridge 186:707f6e361f3e 528 MXC_ASSERT(uart_num >= 0);
Anna Bridge 186:707f6e361f3e 529
Anna Bridge 186:707f6e361f3e 530 // Check to see if there are any ongoing transactions or if the UART is disabled
Anna Bridge 186:707f6e361f3e 531 if(((tx_states[uart_num] == NULL) &&
Anna Bridge 186:707f6e361f3e 532 !(uart->tx_fifo_ctrl & MXC_F_UART_TX_FIFO_CTRL_FIFO_ENTRY) &&
Anna Bridge 186:707f6e361f3e 533 #if(MXC_UART_REV == 0)
Anna Bridge 186:707f6e361f3e 534 (uart->intfl & MXC_F_UART_INTFL_TX_DONE)) ||
Anna Bridge 186:707f6e361f3e 535 #else
Anna Bridge 186:707f6e361f3e 536 (uart->idle & MXC_F_UART_IDLE_TX_RX_IDLE)) ||
Anna Bridge 186:707f6e361f3e 537 #endif
Anna Bridge 186:707f6e361f3e 538 !(uart->ctrl & MXC_F_UART_CTRL_UART_EN)) {
Anna Bridge 186:707f6e361f3e 539
Anna Bridge 186:707f6e361f3e 540 return E_NO_ERROR;
Anna Bridge 186:707f6e361f3e 541 }
Anna Bridge 186:707f6e361f3e 542
Anna Bridge 186:707f6e361f3e 543 return E_BUSY;
Anna Bridge 186:707f6e361f3e 544 }
Anna Bridge 186:707f6e361f3e 545
Anna Bridge 186:707f6e361f3e 546 /* ************************************************************************* */
Anna Bridge 186:707f6e361f3e 547 int UART_PrepForSleep(mxc_uart_regs_t *uart)
Anna Bridge 186:707f6e361f3e 548 {
Anna Bridge 186:707f6e361f3e 549 if(UART_Busy(uart) != E_NO_ERROR) {
Anna Bridge 186:707f6e361f3e 550 return E_BUSY;
Anna Bridge 186:707f6e361f3e 551 }
Anna Bridge 186:707f6e361f3e 552
Anna Bridge 186:707f6e361f3e 553 // Leave read interrupts enabled, if already enabled
Anna Bridge 186:707f6e361f3e 554 uart->inten &= UART_READ_INTS;
Anna Bridge 186:707f6e361f3e 555
Anna Bridge 186:707f6e361f3e 556 return E_NO_ERROR;
Anna Bridge 186:707f6e361f3e 557 }
Anna Bridge 186:707f6e361f3e 558
Anna Bridge 186:707f6e361f3e 559 /* ************************************************************************* */
Anna Bridge 186:707f6e361f3e 560 static void UART_WriteHandler(mxc_uart_regs_t *uart, uart_req_t *req, int uart_num)
Anna Bridge 186:707f6e361f3e 561 {
Anna Bridge 186:707f6e361f3e 562 int avail, remain;
Anna Bridge 186:707f6e361f3e 563 mxc_uart_fifo_regs_t *fifo;
Anna Bridge 186:707f6e361f3e 564
Anna Bridge 186:707f6e361f3e 565 // Disable write interrupts
Anna Bridge 186:707f6e361f3e 566 uart->inten &= ~(UART_WRITE_INTS);
Anna Bridge 186:707f6e361f3e 567
Anna Bridge 186:707f6e361f3e 568 // Get the FIFO for this UART
Anna Bridge 186:707f6e361f3e 569 fifo = MXC_UART_GET_FIFO(uart_num);
Anna Bridge 186:707f6e361f3e 570
Anna Bridge 186:707f6e361f3e 571 // Refill the TX FIFO
Anna Bridge 186:707f6e361f3e 572 avail = UART_NumWriteAvail(uart);
Anna Bridge 186:707f6e361f3e 573 remain = req->len - req->num;
Anna Bridge 186:707f6e361f3e 574
Anna Bridge 186:707f6e361f3e 575 while(avail && remain) {
Anna Bridge 186:707f6e361f3e 576
Anna Bridge 186:707f6e361f3e 577 // Write the data to the FIFO
Anna Bridge 186:707f6e361f3e 578 #if(MXC_UART_REV == 0)
Anna Bridge 186:707f6e361f3e 579 uart->intfl = MXC_F_UART_INTFL_TX_DONE;
Anna Bridge 186:707f6e361f3e 580 #endif
Anna Bridge 186:707f6e361f3e 581 fifo->tx = req->data[req->num++];
Anna Bridge 186:707f6e361f3e 582 remain--;
Anna Bridge 186:707f6e361f3e 583 avail--;
Anna Bridge 186:707f6e361f3e 584 }
Anna Bridge 186:707f6e361f3e 585
Anna Bridge 186:707f6e361f3e 586 // All of the bytes have been written to the FIFO
Anna Bridge 186:707f6e361f3e 587 if(!remain) {
Anna Bridge 186:707f6e361f3e 588
Anna Bridge 186:707f6e361f3e 589 // Unlock this UART to write
Anna Bridge 186:707f6e361f3e 590 mxc_free_lock((uint32_t*)&tx_states[uart_num]);
Anna Bridge 186:707f6e361f3e 591
Anna Bridge 186:707f6e361f3e 592 if(req->callback != NULL) {
Anna Bridge 186:707f6e361f3e 593 req->callback(req, E_NO_ERROR);
Anna Bridge 186:707f6e361f3e 594 }
Anna Bridge 186:707f6e361f3e 595
Anna Bridge 186:707f6e361f3e 596 } else {
Anna Bridge 186:707f6e361f3e 597
Anna Bridge 186:707f6e361f3e 598 // Interrupt when there is one byte left in the TXFIFO
Anna Bridge 186:707f6e361f3e 599 uart->tx_fifo_ctrl = ((MXC_UART_FIFO_DEPTH - 1) << MXC_F_UART_TX_FIFO_CTRL_FIFO_AE_LVL_POS);
Anna Bridge 186:707f6e361f3e 600
Anna Bridge 186:707f6e361f3e 601 // Enable almost empty interrupt
Anna Bridge 186:707f6e361f3e 602 uart->inten |= (MXC_F_UART_INTEN_TX_FIFO_AE);
Anna Bridge 186:707f6e361f3e 603 }
Anna Bridge 186:707f6e361f3e 604 }
Anna Bridge 186:707f6e361f3e 605
Anna Bridge 186:707f6e361f3e 606 /* ************************************************************************* */
Anna Bridge 186:707f6e361f3e 607 static void UART_ReadHandler(mxc_uart_regs_t *uart, uart_req_t *req, int uart_num,
Anna Bridge 186:707f6e361f3e 608 uint32_t flags)
Anna Bridge 186:707f6e361f3e 609 {
Anna Bridge 186:707f6e361f3e 610 int avail, remain;
Anna Bridge 186:707f6e361f3e 611 mxc_uart_fifo_regs_t *fifo;
Anna Bridge 186:707f6e361f3e 612
Anna Bridge 186:707f6e361f3e 613 // Disable interrupts
Anna Bridge 186:707f6e361f3e 614 uart->inten &= ~UART_READ_INTS;
Anna Bridge 186:707f6e361f3e 615
Anna Bridge 186:707f6e361f3e 616 // Get the FIFO for this UART, uart_num
Anna Bridge 186:707f6e361f3e 617 fifo = MXC_UART_GET_FIFO(uart_num);
Anna Bridge 186:707f6e361f3e 618
Anna Bridge 186:707f6e361f3e 619 // Save the data in the FIFO while we still need data
Anna Bridge 186:707f6e361f3e 620 avail = UART_NumReadAvail(uart);
Anna Bridge 186:707f6e361f3e 621 remain = req->len - req->num;
Anna Bridge 186:707f6e361f3e 622 while(avail && remain) {
Anna Bridge 186:707f6e361f3e 623 req->data[req->num++] = fifo->rx;
Anna Bridge 186:707f6e361f3e 624 remain--;
Anna Bridge 186:707f6e361f3e 625 avail--;
Anna Bridge 186:707f6e361f3e 626 }
Anna Bridge 186:707f6e361f3e 627
Anna Bridge 186:707f6e361f3e 628 // Check for errors
Anna Bridge 186:707f6e361f3e 629 if(flags & MXC_F_UART_INTFL_RX_FIFO_OVERFLOW) {
Anna Bridge 186:707f6e361f3e 630
Anna Bridge 186:707f6e361f3e 631 // Unlock this UART to read
Anna Bridge 186:707f6e361f3e 632 mxc_free_lock((uint32_t*)&rx_states[uart_num]);
Anna Bridge 186:707f6e361f3e 633
Anna Bridge 186:707f6e361f3e 634 if(req->callback != NULL) {
Anna Bridge 186:707f6e361f3e 635 req->callback(req, E_OVERFLOW);
Anna Bridge 186:707f6e361f3e 636 }
Anna Bridge 186:707f6e361f3e 637
Anna Bridge 186:707f6e361f3e 638 return;
Anna Bridge 186:707f6e361f3e 639 }
Anna Bridge 186:707f6e361f3e 640
Anna Bridge 186:707f6e361f3e 641 if(flags & (MXC_F_UART_INTFL_RX_FRAMING_ERR |
Anna Bridge 186:707f6e361f3e 642 MXC_F_UART_INTFL_RX_PARITY_ERR)) {
Anna Bridge 186:707f6e361f3e 643
Anna Bridge 186:707f6e361f3e 644 // Unlock this UART to read
Anna Bridge 186:707f6e361f3e 645 mxc_free_lock((uint32_t*)&rx_states[uart_num]);
Anna Bridge 186:707f6e361f3e 646
Anna Bridge 186:707f6e361f3e 647 if(req->callback != NULL) {
Anna Bridge 186:707f6e361f3e 648 req->callback(req, E_COMM_ERR);
Anna Bridge 186:707f6e361f3e 649 }
Anna Bridge 186:707f6e361f3e 650
Anna Bridge 186:707f6e361f3e 651 return;
Anna Bridge 186:707f6e361f3e 652 }
Anna Bridge 186:707f6e361f3e 653
Anna Bridge 186:707f6e361f3e 654 // Check to see if we're done receiving
Anna Bridge 186:707f6e361f3e 655 if(remain == 0) {
Anna Bridge 186:707f6e361f3e 656
Anna Bridge 186:707f6e361f3e 657 // Unlock this UART to read
Anna Bridge 186:707f6e361f3e 658 mxc_free_lock((uint32_t*)&rx_states[uart_num]);
Anna Bridge 186:707f6e361f3e 659
Anna Bridge 186:707f6e361f3e 660 if(req->callback != NULL) {
Anna Bridge 186:707f6e361f3e 661 req->callback(req, E_NO_ERROR);
Anna Bridge 186:707f6e361f3e 662 }
Anna Bridge 186:707f6e361f3e 663
Anna Bridge 186:707f6e361f3e 664 return;
Anna Bridge 186:707f6e361f3e 665 }
Anna Bridge 186:707f6e361f3e 666
Anna Bridge 186:707f6e361f3e 667 if(remain == 1) {
Anna Bridge 186:707f6e361f3e 668 uart->inten |= (MXC_F_UART_INTEN_RX_FIFO_NOT_EMPTY | UART_ERRORS);
Anna Bridge 186:707f6e361f3e 669
Anna Bridge 186:707f6e361f3e 670 } else {
Anna Bridge 186:707f6e361f3e 671 // Set the RX FIFO AF threshold
Anna Bridge 186:707f6e361f3e 672 if(remain < UART_RXFIFO_USABLE) {
Anna Bridge 186:707f6e361f3e 673 uart->rx_fifo_ctrl = ((remain - 1) <<
Anna Bridge 186:707f6e361f3e 674 MXC_F_UART_RX_FIFO_CTRL_FIFO_AF_LVL_POS);
Anna Bridge 186:707f6e361f3e 675 } else {
Anna Bridge 186:707f6e361f3e 676 uart->rx_fifo_ctrl = (UART_RXFIFO_USABLE <<
Anna Bridge 186:707f6e361f3e 677 MXC_F_UART_RX_FIFO_CTRL_FIFO_AF_LVL_POS);
Anna Bridge 186:707f6e361f3e 678 }
Anna Bridge 186:707f6e361f3e 679 uart->inten |= (MXC_F_UART_INTEN_RX_FIFO_AF | UART_ERRORS);
Anna Bridge 186:707f6e361f3e 680 }
Anna Bridge 186:707f6e361f3e 681 }
Anna Bridge 186:707f6e361f3e 682 /** @} */