mbed library sources. Supersedes mbed-src.

Fork of mbed-dev by mbed official

Committer:
funshine
Date:
Sat Apr 08 17:03:55 2017 +0000
Revision:
162:16168a1438f3
Parent:
150:02e0a0aed4ec
add code to handle serial port rx error in uart_irq()

Who changed what in which revision?

UserRevisionLine numberNew contents of line
<> 149:156823d33999 1 /*
<> 149:156823d33999 2 * Copyright (c) 2013 Nordic Semiconductor ASA
<> 149:156823d33999 3 * All rights reserved.
<> 149:156823d33999 4 *
<> 149:156823d33999 5 * Redistribution and use in source and binary forms, with or without modification,
<> 149:156823d33999 6 * are permitted provided that the following conditions are met:
<> 149:156823d33999 7 *
<> 149:156823d33999 8 * 1. Redistributions of source code must retain the above copyright notice, this list
<> 149:156823d33999 9 * of conditions and the following disclaimer.
<> 149:156823d33999 10 *
<> 149:156823d33999 11 * 2. Redistributions in binary form, except as embedded into a Nordic Semiconductor ASA
<> 149:156823d33999 12 * integrated circuit in a product or a software update for such product, must reproduce
<> 149:156823d33999 13 * the above copyright notice, this list of conditions and the following disclaimer in
<> 149:156823d33999 14 * the documentation and/or other materials provided with the distribution.
<> 149:156823d33999 15 *
<> 149:156823d33999 16 * 3. Neither the name of Nordic Semiconductor ASA nor the names of its contributors may be
<> 149:156823d33999 17 * used to endorse or promote products derived from this software without specific prior
<> 149:156823d33999 18 * written permission.
<> 149:156823d33999 19 *
<> 149:156823d33999 20 * 4. This software, with or without modification, must only be used with a
<> 149:156823d33999 21 * Nordic Semiconductor ASA integrated circuit.
<> 149:156823d33999 22 *
<> 149:156823d33999 23 * 5. Any software provided in binary or object form under this license must not be reverse
<> 149:156823d33999 24 * engineered, decompiled, modified and/or disassembled.
<> 149:156823d33999 25 *
<> 149:156823d33999 26 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
<> 149:156823d33999 27 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
<> 149:156823d33999 28 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
<> 149:156823d33999 29 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
<> 149:156823d33999 30 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
<> 149:156823d33999 31 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
<> 149:156823d33999 32 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
<> 149:156823d33999 33 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
<> 149:156823d33999 34 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
<> 149:156823d33999 35 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
<> 149:156823d33999 36 *
<> 149:156823d33999 37 */
<> 149:156823d33999 38
<> 149:156823d33999 39 #include "serial_api.h"
<> 149:156823d33999 40
<> 149:156823d33999 41 #if DEVICE_SERIAL
<> 149:156823d33999 42
<> 149:156823d33999 43 #include <string.h>
<> 149:156823d33999 44 #include "mbed_assert.h"
<> 149:156823d33999 45 #include "mbed_error.h"
<> 149:156823d33999 46 #include "nrf_uart.h"
<> 149:156823d33999 47 #include "nrf_drv_common.h"
<> 149:156823d33999 48 #include "nrf_drv_config.h"
<> 149:156823d33999 49 #include "app_util_platform.h"
<> 149:156823d33999 50 #include "nrf_gpio.h"
<> 149:156823d33999 51
<> 149:156823d33999 52 #define UART_INSTANCE_COUNT 1
<> 149:156823d33999 53 #define UART_INSTANCE NRF_UART0
<> 149:156823d33999 54 #define UART_IRQn UART0_IRQn
<> 149:156823d33999 55 #define UART_IRQ_HANDLER UART0_IRQHandler
<> 149:156823d33999 56 #define UART_INSTANCE_ID 0
<> 149:156823d33999 57 #define UART_CB uart_cb[UART_INSTANCE_ID]
<> 149:156823d33999 58
<> 149:156823d33999 59 #define UART_DEFAULT_BAUDRATE UART0_CONFIG_BAUDRATE
<> 149:156823d33999 60 #define UART_DEFAULT_PARITY UART0_CONFIG_PARITY
<> 149:156823d33999 61
<> 149:156823d33999 62 // expected the macro from mbed configuration system
<> 149:156823d33999 63 #ifndef MBED_CONF_NORDIC_UART_HWFC
<> 149:156823d33999 64 #define MBED_CONF_NORDIC_UART_HWFC 1
<> 149:156823d33999 65 #warning None of UART flow control configuration (expected macro MBED_CONF_NORDIC_UART_HWFC). The RTSCTS flow control is used by default .
<> 149:156823d33999 66 #endif
<> 149:156823d33999 67
<> 149:156823d33999 68 #if MBED_CONF_NORDIC_UART_HWFC == 1
<> 149:156823d33999 69 #define UART_DEFAULT_HWFC UART0_CONFIG_HWFC
<> 149:156823d33999 70 #else
<> 149:156823d33999 71 #define UART_DEFAULT_HWFC NRF_UART_HWFC_DISABLED
<> 149:156823d33999 72 #endif
<> 149:156823d33999 73
<> 149:156823d33999 74 #define UART_DEFAULT_CTS UART0_CONFIG_PSEL_CTS
<> 149:156823d33999 75 #define UART_DEFAULT_RTS UART0_CONFIG_PSEL_RTS
<> 149:156823d33999 76
<> 150:02e0a0aed4ec 77 #ifdef NRF51
<> 150:02e0a0aed4ec 78 #define NRFx_MBED_UART_IRQ_PRIORITY APP_IRQ_PRIORITY_LOW
<> 150:02e0a0aed4ec 79 #elif defined(NRF52)
<> 150:02e0a0aed4ec 80 #define NRFx_MBED_UART_IRQ_PRIORITY APP_IRQ_PRIORITY_LOWEST
<> 150:02e0a0aed4ec 81 #endif
<> 150:02e0a0aed4ec 82
<> 149:156823d33999 83 // Required by "retarget.cpp".
<> 149:156823d33999 84 int stdio_uart_inited = 0;
<> 149:156823d33999 85 serial_t stdio_uart;
<> 149:156823d33999 86
<> 149:156823d33999 87 typedef struct {
<> 149:156823d33999 88 bool initialized;
<> 149:156823d33999 89 uint32_t irq_context;
<> 149:156823d33999 90 uart_irq_handler irq_handler;
<> 149:156823d33999 91
<> 149:156823d33999 92 uint32_t pselrxd;
<> 149:156823d33999 93 uint32_t pseltxd;
<> 149:156823d33999 94 uint32_t pselcts;
<> 149:156823d33999 95 uint32_t pselrts;
<> 149:156823d33999 96 nrf_uart_hwfc_t hwfc;
<> 149:156823d33999 97 nrf_uart_parity_t parity;
<> 149:156823d33999 98 nrf_uart_baudrate_t baudrate;
<> 149:156823d33999 99
<> 149:156823d33999 100 #if DEVICE_SERIAL_ASYNCH
<> 149:156823d33999 101 bool volatile rx_active;
<> 149:156823d33999 102 uint8_t *rx_buffer;
<> 149:156823d33999 103 size_t rx_length;
<> 149:156823d33999 104 size_t rx_pos;
<> 149:156823d33999 105 void (*rx_asynch_handler)();
<> 149:156823d33999 106 uint8_t char_match;
<> 149:156823d33999 107
<> 149:156823d33999 108 bool volatile tx_active;
<> 149:156823d33999 109 const uint8_t *tx_buffer;
<> 149:156823d33999 110 size_t tx_length;
<> 149:156823d33999 111 size_t tx_pos;
<> 149:156823d33999 112 void (*tx_asynch_handler)();
<> 149:156823d33999 113
<> 149:156823d33999 114 uint32_t events_wanted;
<> 149:156823d33999 115 uint32_t events_occured;
<> 149:156823d33999 116
<> 149:156823d33999 117 #define UART_IRQ_TX 1
<> 149:156823d33999 118 #define UART_IRQ_RX 2
<> 149:156823d33999 119 uint8_t irq_enabled;
<> 149:156823d33999 120 #endif // DEVICE_SERIAL_ASYNCH
<> 149:156823d33999 121 } uart_ctlblock_t;
<> 149:156823d33999 122
<> 149:156823d33999 123 static uart_ctlblock_t uart_cb[UART_INSTANCE_COUNT];
<> 149:156823d33999 124
<> 150:02e0a0aed4ec 125 static void internal_set_hwfc(FlowControl type,
<> 150:02e0a0aed4ec 126 PinName rxflow, PinName txflow);
<> 150:02e0a0aed4ec 127
<> 149:156823d33999 128
<> 149:156823d33999 129 #if DEVICE_SERIAL_ASYNCH
<> 149:156823d33999 130 static void end_asynch_rx(void)
<> 149:156823d33999 131 {
<> 149:156823d33999 132 // If RX interrupt is activated for synchronous operations,
<> 149:156823d33999 133 // don't disable it, just stop handling it here.
<> 149:156823d33999 134 if (!(UART_CB.irq_enabled & UART_IRQ_RX)) {
<> 149:156823d33999 135 nrf_uart_int_disable(UART_INSTANCE, NRF_UART_INT_MASK_RXDRDY);
<> 149:156823d33999 136 }
<> 149:156823d33999 137 UART_CB.rx_active = false;
<> 149:156823d33999 138 }
<> 149:156823d33999 139 static void end_asynch_tx(void)
<> 149:156823d33999 140 {
<> 149:156823d33999 141 // If TX interrupt is activated for synchronous operations,
<> 149:156823d33999 142 // don't disable it, just stop handling it here.
<> 149:156823d33999 143 if (!(UART_CB.irq_enabled & UART_IRQ_TX)) {
<> 149:156823d33999 144 nrf_uart_int_disable(UART_INSTANCE, NRF_UART_INT_MASK_TXDRDY);
<> 149:156823d33999 145 }
<> 149:156823d33999 146 UART_CB.tx_active = false;
<> 149:156823d33999 147 }
<> 149:156823d33999 148 #endif // DEVICE_SERIAL_ASYNCH
<> 149:156823d33999 149
<> 149:156823d33999 150 void UART_IRQ_HANDLER(void)
<> 149:156823d33999 151 {
<> 149:156823d33999 152 if (nrf_uart_int_enable_check(UART_INSTANCE, NRF_UART_INT_MASK_RXDRDY) &&
<> 149:156823d33999 153 nrf_uart_event_check(UART_INSTANCE, NRF_UART_EVENT_RXDRDY)) {
<> 149:156823d33999 154
<> 149:156823d33999 155 #if DEVICE_SERIAL_ASYNCH
<> 149:156823d33999 156 if (UART_CB.rx_active) {
<> 149:156823d33999 157 nrf_uart_event_clear(UART_INSTANCE, NRF_UART_EVENT_RXDRDY);
<> 149:156823d33999 158
<> 149:156823d33999 159 uint8_t rx_data = nrf_uart_rxd_get(UART_INSTANCE);
<> 149:156823d33999 160 UART_CB.rx_buffer[UART_CB.rx_pos] = rx_data;
<> 149:156823d33999 161
<> 149:156823d33999 162 bool end_rx = false;
<> 149:156823d33999 163 // If character matching should be performed, check if the current
<> 149:156823d33999 164 // data matches the given one.
<> 149:156823d33999 165 if (UART_CB.char_match != SERIAL_RESERVED_CHAR_MATCH &&
<> 149:156823d33999 166 rx_data == UART_CB.char_match) {
<> 149:156823d33999 167 // If it does, report the match and abort further receiving.
<> 149:156823d33999 168 UART_CB.events_occured |= SERIAL_EVENT_RX_CHARACTER_MATCH;
<> 149:156823d33999 169 if (UART_CB.events_wanted & SERIAL_EVENT_RX_CHARACTER_MATCH) {
<> 149:156823d33999 170 end_rx = true;
<> 149:156823d33999 171 }
<> 149:156823d33999 172 }
<> 149:156823d33999 173 if (++UART_CB.rx_pos >= UART_CB.rx_length) {
<> 149:156823d33999 174 UART_CB.events_occured |= SERIAL_EVENT_RX_COMPLETE;
<> 149:156823d33999 175 end_rx = true;
<> 149:156823d33999 176 }
<> 149:156823d33999 177 if (end_rx) {
<> 149:156823d33999 178 end_asynch_rx();
<> 149:156823d33999 179
<> 149:156823d33999 180 if (UART_CB.rx_asynch_handler) {
<> 149:156823d33999 181 // Use local variable to make it possible to start a next
<> 149:156823d33999 182 // transfer from callback routine.
<> 149:156823d33999 183 void (*handler)() = UART_CB.rx_asynch_handler;
<> 149:156823d33999 184 UART_CB.rx_asynch_handler = NULL;
<> 149:156823d33999 185 handler();
<> 149:156823d33999 186 }
<> 149:156823d33999 187 }
<> 149:156823d33999 188 }
<> 149:156823d33999 189 else
<> 149:156823d33999 190 #endif
<> 149:156823d33999 191
<> 149:156823d33999 192 if (UART_CB.irq_handler) {
<> 149:156823d33999 193 UART_CB.irq_handler(UART_CB.irq_context, RxIrq);
<> 149:156823d33999 194 }
<> 149:156823d33999 195 }
<> 149:156823d33999 196
<> 149:156823d33999 197 if (nrf_uart_int_enable_check(UART_INSTANCE, NRF_UART_INT_MASK_TXDRDY) &&
<> 149:156823d33999 198 nrf_uart_event_check(UART_INSTANCE, NRF_UART_EVENT_TXDRDY)) {
<> 149:156823d33999 199
<> 149:156823d33999 200 #if DEVICE_SERIAL_ASYNCH
<> 149:156823d33999 201 if (UART_CB.tx_active) {
<> 149:156823d33999 202 if (++UART_CB.tx_pos <= UART_CB.tx_length) {
<> 149:156823d33999 203 // When there is still something to send, clear the TXDRDY event
<> 149:156823d33999 204 // and put next byte to transmitter.
<> 149:156823d33999 205 nrf_uart_event_clear(UART_INSTANCE, NRF_UART_EVENT_TXDRDY);
<> 149:156823d33999 206 nrf_uart_txd_set(UART_INSTANCE,
<> 149:156823d33999 207 UART_CB.tx_buffer[UART_CB.tx_pos]);
<> 149:156823d33999 208 }
<> 149:156823d33999 209 else {
<> 149:156823d33999 210 // When the TXDRDY event is set after the last byte to be sent
<> 149:156823d33999 211 // has been passed to the transmitter, the job is done and TX
<> 149:156823d33999 212 // complete can be indicated.
<> 149:156823d33999 213 // Don't clear the TXDRDY event, it needs to remain set for the
<> 149:156823d33999 214 // 'serial_writable' function to work properly.
<> 149:156823d33999 215 end_asynch_tx();
<> 149:156823d33999 216
<> 149:156823d33999 217 UART_CB.events_occured |= SERIAL_EVENT_TX_COMPLETE;
<> 149:156823d33999 218 if (UART_CB.tx_asynch_handler) {
<> 149:156823d33999 219 // Use local variable to make it possible to start a next
<> 149:156823d33999 220 // transfer from callback routine.
<> 149:156823d33999 221 void (*handler)() = UART_CB.tx_asynch_handler;
<> 149:156823d33999 222 UART_CB.tx_asynch_handler = NULL;
<> 149:156823d33999 223 handler();
<> 149:156823d33999 224 }
<> 149:156823d33999 225 }
<> 149:156823d33999 226 }
<> 149:156823d33999 227 else
<> 149:156823d33999 228 #endif
<> 149:156823d33999 229
<> 149:156823d33999 230 if (UART_CB.irq_handler) {
<> 149:156823d33999 231 UART_CB.irq_handler(UART_CB.irq_context, TxIrq);
<> 149:156823d33999 232 }
<> 149:156823d33999 233 }
<> 149:156823d33999 234
<> 149:156823d33999 235 #if DEVICE_SERIAL_ASYNCH
<> 149:156823d33999 236 if (nrf_uart_event_check(UART_INSTANCE, NRF_UART_EVENT_ERROR)) {
<> 149:156823d33999 237 nrf_uart_event_clear(UART_INSTANCE, NRF_UART_EVENT_ERROR);
<> 149:156823d33999 238
<> 149:156823d33999 239 uint8_t errorsrc = nrf_uart_errorsrc_get_and_clear(UART_INSTANCE);
<> 149:156823d33999 240 if (UART_CB.rx_asynch_handler) {
<> 149:156823d33999 241 UART_CB.events_occured |= SERIAL_EVENT_ERROR;
<> 149:156823d33999 242 if (errorsrc & NRF_UART_ERROR_PARITY_MASK) {
<> 149:156823d33999 243 UART_CB.events_occured |= SERIAL_EVENT_RX_PARITY_ERROR;
<> 149:156823d33999 244 }
<> 149:156823d33999 245 if (errorsrc & NRF_UART_ERROR_FRAMING_MASK) {
<> 149:156823d33999 246 UART_CB.events_occured |= SERIAL_EVENT_RX_FRAMING_ERROR;
<> 149:156823d33999 247 }
<> 149:156823d33999 248 if (errorsrc & NRF_UART_ERROR_OVERRUN_MASK) {
<> 149:156823d33999 249 UART_CB.events_occured |= SERIAL_EVENT_RX_OVERRUN_ERROR;
<> 149:156823d33999 250 }
<> 149:156823d33999 251 UART_CB.rx_asynch_handler();
<> 149:156823d33999 252 }
<> 149:156823d33999 253 }
<> 149:156823d33999 254 #endif // DEVICE_SERIAL_ASYNCH
<> 149:156823d33999 255 }
<> 149:156823d33999 256
<> 149:156823d33999 257 void serial_init(serial_t *obj, PinName tx, PinName rx) {
<> 150:02e0a0aed4ec 258
<> 150:02e0a0aed4ec 259 NVIC_SetVector(UART0_IRQn, (uint32_t) UART0_IRQHandler);
<> 150:02e0a0aed4ec 260
<> 150:02e0a0aed4ec 261
<> 149:156823d33999 262 UART_CB.pseltxd =
<> 149:156823d33999 263 (tx == NC) ? NRF_UART_PSEL_DISCONNECTED : (uint32_t)tx;
<> 149:156823d33999 264 UART_CB.pselrxd =
<> 149:156823d33999 265 (rx == NC) ? NRF_UART_PSEL_DISCONNECTED : (uint32_t)rx;
<> 149:156823d33999 266 if (UART_CB.pseltxd != NRF_UART_PSEL_DISCONNECTED) {
<> 149:156823d33999 267 nrf_gpio_pin_set(UART_CB.pseltxd);
<> 149:156823d33999 268 nrf_gpio_cfg_output(UART_CB.pseltxd);
<> 149:156823d33999 269 }
<> 149:156823d33999 270 if (UART_CB.pselrxd != NRF_UART_PSEL_DISCONNECTED) {
<> 149:156823d33999 271 nrf_gpio_cfg_input(UART_CB.pselrxd, NRF_GPIO_PIN_NOPULL);
<> 149:156823d33999 272 }
<> 149:156823d33999 273
<> 149:156823d33999 274 if (UART_CB.initialized) {
<> 149:156823d33999 275 // For already initialized peripheral it is sufficient to reconfigure
<> 149:156823d33999 276 // RX/TX pins only.
<> 149:156823d33999 277
<> 149:156823d33999 278 // Ensure that there is no unfinished TX transfer.
<> 149:156823d33999 279 while (!serial_writable(obj)) {
<> 149:156823d33999 280 }
<> 149:156823d33999 281 // UART pins can be configured only when the peripheral is disabled.
<> 149:156823d33999 282 nrf_uart_disable(UART_INSTANCE);
<> 149:156823d33999 283 nrf_uart_txrx_pins_set(UART_INSTANCE, UART_CB.pseltxd, UART_CB.pselrxd);
<> 149:156823d33999 284 nrf_uart_enable(UART_INSTANCE);
<> 149:156823d33999 285 }
<> 149:156823d33999 286 else {
<> 149:156823d33999 287 UART_CB.baudrate = UART_DEFAULT_BAUDRATE;
<> 149:156823d33999 288 UART_CB.parity = UART_DEFAULT_PARITY;
<> 149:156823d33999 289 UART_CB.hwfc = UART_DEFAULT_HWFC;
<> 149:156823d33999 290 UART_CB.pselcts = UART_DEFAULT_CTS;
<> 149:156823d33999 291 UART_CB.pselrts = UART_DEFAULT_RTS;
<> 149:156823d33999 292
<> 149:156823d33999 293 nrf_uart_event_clear(UART_INSTANCE, NRF_UART_EVENT_RXDRDY);
<> 149:156823d33999 294 nrf_uart_event_clear(UART_INSTANCE, NRF_UART_EVENT_TXDRDY);
<> 149:156823d33999 295 nrf_uart_task_trigger(UART_INSTANCE, NRF_UART_TASK_STARTRX);
<> 149:156823d33999 296 nrf_uart_task_trigger(UART_INSTANCE, NRF_UART_TASK_STARTTX);
<> 149:156823d33999 297
<> 149:156823d33999 298 nrf_uart_int_disable(UART_INSTANCE, NRF_UART_INT_MASK_RXDRDY |
<> 149:156823d33999 299 NRF_UART_INT_MASK_TXDRDY);
<> 149:156823d33999 300 #if DEVICE_SERIAL_ASYNCH
<> 149:156823d33999 301 nrf_uart_int_enable(UART_INSTANCE, NRF_UART_INT_MASK_ERROR);
<> 149:156823d33999 302 #endif
<> 150:02e0a0aed4ec 303 nrf_drv_common_irq_enable(UART_IRQn, NRFx_MBED_UART_IRQ_PRIORITY);
<> 149:156823d33999 304
<> 149:156823d33999 305 // TX interrupt needs to be signaled when transmitter buffer is empty,
<> 149:156823d33999 306 // so a dummy transmission is needed to get the TXDRDY event initially
<> 149:156823d33999 307 // set.
<> 149:156823d33999 308 nrf_uart_configure(UART_INSTANCE,
<> 149:156823d33999 309 NRF_UART_PARITY_EXCLUDED, NRF_UART_HWFC_DISABLED);
<> 149:156823d33999 310 // Use maximum baud rate, so this dummy transmission takes as little
<> 149:156823d33999 311 // time as possible.
<> 149:156823d33999 312 nrf_uart_baudrate_set(UART_INSTANCE, NRF_UART_BAUDRATE_1000000);
<> 149:156823d33999 313 // Perform it with disconnected TX pin, so nothing actually comes out
<> 149:156823d33999 314 // of the device.
<> 149:156823d33999 315 nrf_uart_txrx_pins_disconnect(UART_INSTANCE);
<> 149:156823d33999 316 nrf_uart_hwfc_pins_disconnect(UART_INSTANCE);
<> 149:156823d33999 317 nrf_uart_enable(UART_INSTANCE);
<> 149:156823d33999 318 nrf_uart_txd_set(UART_INSTANCE, 0);
<> 149:156823d33999 319 while (!nrf_uart_event_check(UART_INSTANCE, NRF_UART_EVENT_TXDRDY)) {
<> 149:156823d33999 320 }
<> 149:156823d33999 321 nrf_uart_disable(UART_INSTANCE);
<> 149:156823d33999 322
<> 149:156823d33999 323 // Now everything is prepared to set the default configuration and
<> 149:156823d33999 324 // connect the peripheral to actual pins.
<> 149:156823d33999 325 nrf_uart_txrx_pins_set(UART_INSTANCE, UART_CB.pseltxd, UART_CB.pselrxd);
<> 149:156823d33999 326 nrf_uart_baudrate_set(UART_INSTANCE, UART_CB.baudrate);
<> 149:156823d33999 327 nrf_uart_configure(UART_INSTANCE, UART_CB.parity, UART_CB.hwfc);
<> 149:156823d33999 328 if (UART_CB.hwfc == NRF_UART_HWFC_ENABLED) {
<> 150:02e0a0aed4ec 329 internal_set_hwfc(FlowControlRTSCTS,
<> 149:156823d33999 330 (PinName) UART_CB.pselrts, (PinName) UART_CB.pselcts);
<> 149:156823d33999 331 }
<> 150:02e0a0aed4ec 332
<> 149:156823d33999 333 nrf_uart_enable(UART_INSTANCE);
<> 149:156823d33999 334
<> 149:156823d33999 335 UART_CB.initialized = true;
<> 149:156823d33999 336 }
<> 149:156823d33999 337
<> 149:156823d33999 338 if (tx == STDIO_UART_TX && rx == STDIO_UART_RX) {
<> 149:156823d33999 339 stdio_uart_inited = 1;
<> 149:156823d33999 340 memcpy(&stdio_uart, obj, sizeof(serial_t));
<> 149:156823d33999 341 }
<> 149:156823d33999 342 else {
<> 149:156823d33999 343 stdio_uart_inited = 0;
<> 149:156823d33999 344 }
<> 149:156823d33999 345 }
<> 149:156823d33999 346
<> 149:156823d33999 347 void serial_free(serial_t *obj)
<> 149:156823d33999 348 {
<> 149:156823d33999 349 (void)obj;
<> 149:156823d33999 350
<> 149:156823d33999 351 if (UART_CB.initialized) {
<> 149:156823d33999 352 nrf_uart_disable(UART_INSTANCE);
<> 149:156823d33999 353 nrf_uart_int_disable(UART_INSTANCE, NRF_UART_INT_MASK_RXDRDY |
<> 149:156823d33999 354 NRF_UART_INT_MASK_TXDRDY |
<> 149:156823d33999 355 NRF_UART_INT_MASK_ERROR);
<> 149:156823d33999 356 nrf_drv_common_irq_disable(UART_IRQn);
<> 149:156823d33999 357 UART_CB.initialized = false;
<> 149:156823d33999 358
<> 149:156823d33999 359 // There is only one UART instance, thus at this point the stdio UART
<> 149:156823d33999 360 // can no longer be initialized.
<> 149:156823d33999 361 stdio_uart_inited = 0;
<> 149:156823d33999 362 }
<> 149:156823d33999 363 }
<> 149:156823d33999 364
<> 149:156823d33999 365 void serial_baud(serial_t *obj, int baudrate)
<> 149:156823d33999 366 {
<> 149:156823d33999 367 // nrf_uart_baudrate_set() is not used here (registers are accessed
<> 149:156823d33999 368 // directly) to make it possible to set special baud rates like 56000
<> 149:156823d33999 369 // or 31250.
<> 149:156823d33999 370
<> 149:156823d33999 371 static uint32_t const acceptedSpeeds[][2] = {
<> 149:156823d33999 372 { 1200, UART_BAUDRATE_BAUDRATE_Baud1200 },
<> 149:156823d33999 373 { 2400, UART_BAUDRATE_BAUDRATE_Baud2400 },
<> 149:156823d33999 374 { 4800, UART_BAUDRATE_BAUDRATE_Baud4800 },
<> 149:156823d33999 375 { 9600, UART_BAUDRATE_BAUDRATE_Baud9600 },
<> 149:156823d33999 376 { 14400, UART_BAUDRATE_BAUDRATE_Baud14400 },
<> 149:156823d33999 377 { 19200, UART_BAUDRATE_BAUDRATE_Baud19200 },
<> 149:156823d33999 378 { 28800, UART_BAUDRATE_BAUDRATE_Baud28800 },
<> 149:156823d33999 379 { 31250, (0x00800000UL) /* 31250 baud */ },
<> 149:156823d33999 380 { 38400, UART_BAUDRATE_BAUDRATE_Baud38400 },
<> 149:156823d33999 381 { 56000, (0x00E51000UL) /* 56000 baud */ },
<> 149:156823d33999 382 { 57600, UART_BAUDRATE_BAUDRATE_Baud57600 },
<> 149:156823d33999 383 { 76800, UART_BAUDRATE_BAUDRATE_Baud76800 },
<> 149:156823d33999 384 { 115200, UART_BAUDRATE_BAUDRATE_Baud115200 },
<> 149:156823d33999 385 { 230400, UART_BAUDRATE_BAUDRATE_Baud230400 },
<> 149:156823d33999 386 { 250000, UART_BAUDRATE_BAUDRATE_Baud250000 },
<> 149:156823d33999 387 { 460800, UART_BAUDRATE_BAUDRATE_Baud460800 },
<> 149:156823d33999 388 { 921600, UART_BAUDRATE_BAUDRATE_Baud921600 },
<> 149:156823d33999 389 { 1000000, UART_BAUDRATE_BAUDRATE_Baud1M }
<> 149:156823d33999 390 };
<> 149:156823d33999 391
<> 149:156823d33999 392 if (baudrate <= 1200) {
<> 149:156823d33999 393 UART_INSTANCE->BAUDRATE = UART_BAUDRATE_BAUDRATE_Baud1200;
<> 149:156823d33999 394 return;
<> 149:156823d33999 395 }
<> 149:156823d33999 396
<> 149:156823d33999 397 int const item_cnt = sizeof(acceptedSpeeds)/sizeof(acceptedSpeeds[0]);
<> 149:156823d33999 398 for (int i = 1; i < item_cnt; i++) {
<> 149:156823d33999 399 if ((uint32_t)baudrate < acceptedSpeeds[i][0]) {
<> 149:156823d33999 400 UART_INSTANCE->BAUDRATE = acceptedSpeeds[i - 1][1];
<> 149:156823d33999 401 return;
<> 149:156823d33999 402 }
<> 149:156823d33999 403 }
<> 149:156823d33999 404
<> 149:156823d33999 405 UART_INSTANCE->BAUDRATE = UART_BAUDRATE_BAUDRATE_Baud1M;
<> 149:156823d33999 406 }
<> 149:156823d33999 407
<> 149:156823d33999 408 void serial_format(serial_t *obj,
<> 149:156823d33999 409 int data_bits, SerialParity parity, int stop_bits)
<> 149:156823d33999 410 {
<> 149:156823d33999 411 (void)obj;
<> 149:156823d33999 412
<> 149:156823d33999 413 if (data_bits != 8) {
<> 149:156823d33999 414 error("UART supports only 8 data bits.\r\n");
<> 149:156823d33999 415 }
<> 149:156823d33999 416 if (stop_bits != 1) {
<> 149:156823d33999 417 error("UART supports only 1 stop bits.\r\n");
<> 149:156823d33999 418 }
<> 149:156823d33999 419 if (parity == ParityNone) {
<> 149:156823d33999 420 UART_CB.parity = NRF_UART_PARITY_EXCLUDED;
<> 149:156823d33999 421 } else if (parity == ParityEven) {
<> 149:156823d33999 422 UART_CB.parity = NRF_UART_PARITY_INCLUDED;
<> 149:156823d33999 423 } else {
<> 149:156823d33999 424 error("UART supports only even parity.\r\n");
<> 149:156823d33999 425 }
<> 149:156823d33999 426
<> 149:156823d33999 427 // Reconfigure UART peripheral.
<> 149:156823d33999 428 nrf_uart_configure(UART_INSTANCE, UART_CB.parity, UART_CB.hwfc);
<> 149:156823d33999 429 }
<> 149:156823d33999 430
<> 149:156823d33999 431 void serial_irq_handler(serial_t *obj, uart_irq_handler handler, uint32_t id)
<> 149:156823d33999 432 {
<> 149:156823d33999 433 (void)obj;
<> 149:156823d33999 434 UART_CB.irq_handler = handler;
<> 149:156823d33999 435 UART_CB.irq_context = id;
<> 149:156823d33999 436 }
<> 149:156823d33999 437
<> 149:156823d33999 438 void serial_irq_set(serial_t *obj, SerialIrq irq, uint32_t enable)
<> 149:156823d33999 439 {
<> 149:156823d33999 440 (void)obj;
<> 149:156823d33999 441 if (enable) {
<> 149:156823d33999 442 switch (irq) {
<> 149:156823d33999 443 case RxIrq:
<> 149:156823d33999 444 #if DEVICE_SERIAL_ASYNCH
<> 149:156823d33999 445 UART_CB.irq_enabled |= UART_IRQ_RX;
<> 149:156823d33999 446 #endif
<> 149:156823d33999 447 nrf_uart_int_enable(UART_INSTANCE, NRF_UART_INT_MASK_RXDRDY);
<> 149:156823d33999 448 break;
<> 149:156823d33999 449
<> 149:156823d33999 450 case TxIrq:
<> 149:156823d33999 451 #if DEVICE_SERIAL_ASYNCH
<> 149:156823d33999 452 UART_CB.irq_enabled |= UART_IRQ_TX;
<> 149:156823d33999 453 #endif
<> 149:156823d33999 454 nrf_uart_int_enable(UART_INSTANCE, NRF_UART_INT_MASK_TXDRDY);
<> 149:156823d33999 455 break;
<> 149:156823d33999 456 }
<> 149:156823d33999 457 } else {
<> 149:156823d33999 458 switch (irq) {
<> 149:156823d33999 459 case RxIrq:
<> 149:156823d33999 460 #if DEVICE_SERIAL_ASYNCH
<> 149:156823d33999 461 UART_CB.irq_enabled &= ~UART_IRQ_RX;
<> 149:156823d33999 462 if (!UART_CB.rx_active)
<> 149:156823d33999 463 #endif
<> 149:156823d33999 464 {
<> 149:156823d33999 465 nrf_uart_int_disable(UART_INSTANCE,
<> 149:156823d33999 466 NRF_UART_INT_MASK_RXDRDY);
<> 149:156823d33999 467 }
<> 149:156823d33999 468 break;
<> 149:156823d33999 469
<> 149:156823d33999 470 case TxIrq:
<> 149:156823d33999 471 #if DEVICE_SERIAL_ASYNCH
<> 149:156823d33999 472 UART_CB.irq_enabled &= ~UART_IRQ_TX;
<> 149:156823d33999 473 if (!UART_CB.tx_active)
<> 149:156823d33999 474 #endif
<> 149:156823d33999 475 {
<> 149:156823d33999 476 nrf_uart_int_disable(UART_INSTANCE,
<> 149:156823d33999 477 NRF_UART_INT_MASK_TXDRDY);
<> 149:156823d33999 478 }
<> 149:156823d33999 479 break;
<> 149:156823d33999 480 }
<> 149:156823d33999 481 }
<> 149:156823d33999 482 }
<> 149:156823d33999 483
<> 149:156823d33999 484 int serial_getc(serial_t *obj)
<> 149:156823d33999 485 {
<> 149:156823d33999 486 while (!serial_readable(obj)) {
<> 149:156823d33999 487 }
<> 149:156823d33999 488
<> 149:156823d33999 489 nrf_uart_event_clear(UART_INSTANCE, NRF_UART_EVENT_RXDRDY);
<> 149:156823d33999 490 return nrf_uart_rxd_get(UART_INSTANCE);
<> 149:156823d33999 491 }
<> 149:156823d33999 492
<> 149:156823d33999 493 void serial_putc(serial_t *obj, int c)
<> 149:156823d33999 494 {
<> 149:156823d33999 495 while (!serial_writable(obj)) {
<> 149:156823d33999 496 }
<> 149:156823d33999 497
<> 149:156823d33999 498 nrf_uart_event_clear(UART_INSTANCE, NRF_UART_EVENT_TXDRDY);
<> 149:156823d33999 499 nrf_uart_txd_set(UART_INSTANCE, (uint8_t)c);
<> 149:156823d33999 500 }
<> 149:156823d33999 501
<> 149:156823d33999 502 int serial_readable(serial_t *obj)
<> 149:156823d33999 503 {
<> 149:156823d33999 504 (void)obj;
<> 149:156823d33999 505 #if DEVICE_SERIAL_ASYNCH
<> 149:156823d33999 506 if (UART_CB.rx_active) {
<> 149:156823d33999 507 return 0;
<> 149:156823d33999 508 }
<> 149:156823d33999 509 #endif
<> 149:156823d33999 510 return (nrf_uart_event_check(UART_INSTANCE, NRF_UART_EVENT_RXDRDY));
<> 149:156823d33999 511 }
<> 149:156823d33999 512
<> 149:156823d33999 513 int serial_writable(serial_t *obj)
<> 149:156823d33999 514 {
<> 149:156823d33999 515 (void)obj;
<> 149:156823d33999 516 #if DEVICE_SERIAL_ASYNCH
<> 149:156823d33999 517 if (UART_CB.tx_active) {
<> 149:156823d33999 518 return 0;
<> 149:156823d33999 519 }
<> 149:156823d33999 520 #endif
<> 149:156823d33999 521 return (nrf_uart_event_check(UART_INSTANCE, NRF_UART_EVENT_TXDRDY));
<> 149:156823d33999 522 }
<> 149:156823d33999 523
<> 149:156823d33999 524 void serial_break_set(serial_t *obj)
<> 149:156823d33999 525 {
<> 149:156823d33999 526 (void)obj;
<> 149:156823d33999 527 nrf_uart_task_trigger(UART_INSTANCE, NRF_UART_TASK_SUSPEND);
<> 149:156823d33999 528 nrf_uart_txrx_pins_disconnect(UART_INSTANCE);
<> 149:156823d33999 529 nrf_gpio_pin_clear(UART_CB.pseltxd);
<> 149:156823d33999 530 }
<> 149:156823d33999 531
<> 149:156823d33999 532 void serial_break_clear(serial_t *obj)
<> 149:156823d33999 533 {
<> 149:156823d33999 534 (void)obj;
<> 149:156823d33999 535 nrf_gpio_pin_set(UART_CB.pseltxd);
<> 149:156823d33999 536 nrf_uart_txrx_pins_set(UART_INSTANCE, UART_CB.pseltxd, UART_CB.pselrxd);
<> 149:156823d33999 537 nrf_uart_task_trigger(UART_INSTANCE, NRF_UART_TASK_STARTRX);
<> 149:156823d33999 538 nrf_uart_task_trigger(UART_INSTANCE, NRF_UART_TASK_STARTTX);
<> 149:156823d33999 539 }
<> 149:156823d33999 540
<> 150:02e0a0aed4ec 541
<> 150:02e0a0aed4ec 542 static void internal_set_hwfc(FlowControl type,
<> 149:156823d33999 543 PinName rxflow, PinName txflow)
<> 149:156823d33999 544 {
<> 149:156823d33999 545 UART_CB.pselrts =
<> 150:02e0a0aed4ec 546 ((rxflow == NC) || (type == FlowControlCTS)) ? NRF_UART_PSEL_DISCONNECTED : (uint32_t)rxflow;
<> 149:156823d33999 547 UART_CB.pselcts =
<> 150:02e0a0aed4ec 548 ((txflow == NC) || (type == FlowControlRTS)) ? NRF_UART_PSEL_DISCONNECTED : (uint32_t)txflow;
<> 149:156823d33999 549
<> 149:156823d33999 550 if (UART_CB.pselrts != NRF_UART_PSEL_DISCONNECTED) {
<> 149:156823d33999 551 nrf_gpio_pin_set(UART_CB.pselrts);
<> 149:156823d33999 552 nrf_gpio_cfg_output(UART_CB.pselrts);
<> 149:156823d33999 553 }
<> 149:156823d33999 554 if (UART_CB.pselcts != NRF_UART_PSEL_DISCONNECTED) {
<> 149:156823d33999 555 nrf_gpio_cfg_input(UART_CB.pselcts, NRF_GPIO_PIN_NOPULL);
<> 149:156823d33999 556 }
<> 150:02e0a0aed4ec 557
<> 150:02e0a0aed4ec 558 UART_CB.hwfc = (type == FlowControlNone)? NRF_UART_HWFC_DISABLED : UART0_CONFIG_HWFC;
<> 150:02e0a0aed4ec 559
<> 150:02e0a0aed4ec 560 nrf_uart_configure(UART_INSTANCE, UART_CB.parity, UART_CB.hwfc);
<> 150:02e0a0aed4ec 561 nrf_uart_hwfc_pins_set(UART_INSTANCE, UART_CB.pselrts, UART_CB.pselcts);
<> 150:02e0a0aed4ec 562 }
<> 150:02e0a0aed4ec 563
<> 150:02e0a0aed4ec 564 void serial_set_flow_control(serial_t *obj, FlowControl type,
<> 150:02e0a0aed4ec 565 PinName rxflow, PinName txflow)
<> 150:02e0a0aed4ec 566 {
<> 150:02e0a0aed4ec 567 (void)obj;
<> 150:02e0a0aed4ec 568
<> 149:156823d33999 569 nrf_uart_disable(UART_INSTANCE);
<> 150:02e0a0aed4ec 570 internal_set_hwfc(type, rxflow, txflow);
<> 149:156823d33999 571 nrf_uart_enable(UART_INSTANCE);
<> 149:156823d33999 572 }
<> 149:156823d33999 573
<> 150:02e0a0aed4ec 574
<> 149:156823d33999 575 void serial_clear(serial_t *obj) {
<> 149:156823d33999 576 (void)obj;
<> 149:156823d33999 577 }
<> 149:156823d33999 578
<> 149:156823d33999 579 #if DEVICE_SERIAL_ASYNCH
<> 149:156823d33999 580
<> 149:156823d33999 581 int serial_tx_asynch(serial_t *obj, const void *tx, size_t tx_length,
<> 149:156823d33999 582 uint8_t tx_width, uint32_t handler, uint32_t event,
<> 149:156823d33999 583 DMAUsage hint)
<> 149:156823d33999 584 {
<> 149:156823d33999 585 (void)obj;
<> 149:156823d33999 586 (void)tx_width;
<> 149:156823d33999 587 (void)hint;
<> 149:156823d33999 588 if (UART_CB.tx_active || !tx_length) {
<> 149:156823d33999 589 return 0;
<> 149:156823d33999 590 }
<> 149:156823d33999 591
<> 149:156823d33999 592 UART_CB.tx_buffer = tx;
<> 149:156823d33999 593 UART_CB.tx_length = tx_length;
<> 149:156823d33999 594 UART_CB.tx_pos = 0;
<> 149:156823d33999 595 UART_CB.tx_asynch_handler = (void(*)())handler;
<> 149:156823d33999 596 UART_CB.events_wanted &= ~SERIAL_EVENT_TX_ALL;
<> 149:156823d33999 597 UART_CB.events_wanted |= event;
<> 149:156823d33999 598
<> 149:156823d33999 599 UART_CB.tx_active = true;
<> 149:156823d33999 600 nrf_uart_int_enable(UART_INSTANCE, NRF_UART_INT_MASK_TXDRDY);
<> 149:156823d33999 601
<> 149:156823d33999 602 return 0;
<> 149:156823d33999 603 }
<> 149:156823d33999 604
<> 149:156823d33999 605 void serial_rx_asynch(serial_t *obj, void *rx, size_t rx_length,
<> 149:156823d33999 606 uint8_t rx_width, uint32_t handler, uint32_t event,
<> 149:156823d33999 607 uint8_t char_match, DMAUsage hint)
<> 149:156823d33999 608 {
<> 149:156823d33999 609 (void)obj;
<> 149:156823d33999 610 (void)rx_width;
<> 149:156823d33999 611 (void)hint;
<> 149:156823d33999 612 if (UART_CB.rx_active || !rx_length) {
<> 149:156823d33999 613 return;
<> 149:156823d33999 614 }
<> 149:156823d33999 615
<> 149:156823d33999 616 UART_CB.rx_buffer = rx;
<> 149:156823d33999 617 UART_CB.rx_length = rx_length;
<> 149:156823d33999 618 UART_CB.rx_pos = 0;
<> 149:156823d33999 619 UART_CB.rx_asynch_handler = (void(*)())handler;
<> 149:156823d33999 620 UART_CB.events_wanted &= ~SERIAL_EVENT_RX_ALL;
<> 149:156823d33999 621 UART_CB.events_wanted |= event;
<> 149:156823d33999 622 UART_CB.char_match = char_match;
<> 149:156823d33999 623
<> 149:156823d33999 624 UART_CB.rx_active = true;
<> 149:156823d33999 625 nrf_uart_int_enable(UART_INSTANCE, NRF_UART_INT_MASK_RXDRDY);
<> 149:156823d33999 626 }
<> 149:156823d33999 627
<> 149:156823d33999 628 uint8_t serial_tx_active(serial_t *obj)
<> 149:156823d33999 629 {
<> 149:156823d33999 630 (void)obj;
<> 149:156823d33999 631 return UART_CB.tx_active;
<> 149:156823d33999 632 }
<> 149:156823d33999 633
<> 149:156823d33999 634 uint8_t serial_rx_active(serial_t *obj)
<> 149:156823d33999 635 {
<> 149:156823d33999 636 (void)obj;
<> 149:156823d33999 637 return UART_CB.rx_active;
<> 149:156823d33999 638 }
<> 149:156823d33999 639
<> 149:156823d33999 640 int serial_irq_handler_asynch(serial_t *obj)
<> 149:156823d33999 641 {
<> 149:156823d33999 642 (void)obj;
<> 149:156823d33999 643 uint32_t events_to_report = UART_CB.events_wanted & UART_CB.events_occured;
<> 149:156823d33999 644 UART_CB.events_occured &= (~events_to_report);
<> 149:156823d33999 645 return events_to_report;
<> 149:156823d33999 646 }
<> 149:156823d33999 647
<> 149:156823d33999 648 void serial_tx_abort_asynch(serial_t *obj)
<> 149:156823d33999 649 {
<> 149:156823d33999 650 (void)obj;
<> 149:156823d33999 651 end_asynch_tx();
<> 149:156823d33999 652 UART_CB.tx_asynch_handler = NULL;
<> 149:156823d33999 653 }
<> 149:156823d33999 654
<> 149:156823d33999 655 void serial_rx_abort_asynch(serial_t *obj)
<> 149:156823d33999 656 {
<> 149:156823d33999 657 (void)obj;
<> 149:156823d33999 658 end_asynch_rx();
<> 149:156823d33999 659 UART_CB.rx_asynch_handler = NULL;
<> 149:156823d33999 660 }
<> 149:156823d33999 661
<> 149:156823d33999 662 #endif // DEVICE_SERIAL_ASYNCH
<> 149:156823d33999 663
<> 149:156823d33999 664 #endif // DEVICE_SERIAL