lib

Fork of mbed-dev by mbed official

Committer:
<>
Date:
Fri Oct 28 11:17:30 2016 +0100
Revision:
149:156823d33999
This updates the lib to the mbed lib v128

NOTE: This release includes a restructuring of the file and directory locations and thus some
include paths in your code may need updating accordingly.

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
<> 149:156823d33999 77 // Required by "retarget.cpp".
<> 149:156823d33999 78 int stdio_uart_inited = 0;
<> 149:156823d33999 79 serial_t stdio_uart;
<> 149:156823d33999 80
<> 149:156823d33999 81 typedef struct {
<> 149:156823d33999 82 bool initialized;
<> 149:156823d33999 83 uint32_t irq_context;
<> 149:156823d33999 84 uart_irq_handler irq_handler;
<> 149:156823d33999 85
<> 149:156823d33999 86 uint32_t pselrxd;
<> 149:156823d33999 87 uint32_t pseltxd;
<> 149:156823d33999 88 uint32_t pselcts;
<> 149:156823d33999 89 uint32_t pselrts;
<> 149:156823d33999 90 nrf_uart_hwfc_t hwfc;
<> 149:156823d33999 91 nrf_uart_parity_t parity;
<> 149:156823d33999 92 nrf_uart_baudrate_t baudrate;
<> 149:156823d33999 93
<> 149:156823d33999 94 #if DEVICE_SERIAL_ASYNCH
<> 149:156823d33999 95 bool volatile rx_active;
<> 149:156823d33999 96 uint8_t *rx_buffer;
<> 149:156823d33999 97 size_t rx_length;
<> 149:156823d33999 98 size_t rx_pos;
<> 149:156823d33999 99 void (*rx_asynch_handler)();
<> 149:156823d33999 100 uint8_t char_match;
<> 149:156823d33999 101
<> 149:156823d33999 102 bool volatile tx_active;
<> 149:156823d33999 103 const uint8_t *tx_buffer;
<> 149:156823d33999 104 size_t tx_length;
<> 149:156823d33999 105 size_t tx_pos;
<> 149:156823d33999 106 void (*tx_asynch_handler)();
<> 149:156823d33999 107
<> 149:156823d33999 108 uint32_t events_wanted;
<> 149:156823d33999 109 uint32_t events_occured;
<> 149:156823d33999 110
<> 149:156823d33999 111 #define UART_IRQ_TX 1
<> 149:156823d33999 112 #define UART_IRQ_RX 2
<> 149:156823d33999 113 uint8_t irq_enabled;
<> 149:156823d33999 114 #endif // DEVICE_SERIAL_ASYNCH
<> 149:156823d33999 115 } uart_ctlblock_t;
<> 149:156823d33999 116
<> 149:156823d33999 117 static uart_ctlblock_t uart_cb[UART_INSTANCE_COUNT];
<> 149:156823d33999 118
<> 149:156823d33999 119
<> 149:156823d33999 120 #if DEVICE_SERIAL_ASYNCH
<> 149:156823d33999 121 static void end_asynch_rx(void)
<> 149:156823d33999 122 {
<> 149:156823d33999 123 // If RX interrupt is activated for synchronous operations,
<> 149:156823d33999 124 // don't disable it, just stop handling it here.
<> 149:156823d33999 125 if (!(UART_CB.irq_enabled & UART_IRQ_RX)) {
<> 149:156823d33999 126 nrf_uart_int_disable(UART_INSTANCE, NRF_UART_INT_MASK_RXDRDY);
<> 149:156823d33999 127 }
<> 149:156823d33999 128 UART_CB.rx_active = false;
<> 149:156823d33999 129 }
<> 149:156823d33999 130 static void end_asynch_tx(void)
<> 149:156823d33999 131 {
<> 149:156823d33999 132 // If TX 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_TX)) {
<> 149:156823d33999 135 nrf_uart_int_disable(UART_INSTANCE, NRF_UART_INT_MASK_TXDRDY);
<> 149:156823d33999 136 }
<> 149:156823d33999 137 UART_CB.tx_active = false;
<> 149:156823d33999 138 }
<> 149:156823d33999 139 #endif // DEVICE_SERIAL_ASYNCH
<> 149:156823d33999 140
<> 149:156823d33999 141 void UART_IRQ_HANDLER(void)
<> 149:156823d33999 142 {
<> 149:156823d33999 143 if (nrf_uart_int_enable_check(UART_INSTANCE, NRF_UART_INT_MASK_RXDRDY) &&
<> 149:156823d33999 144 nrf_uart_event_check(UART_INSTANCE, NRF_UART_EVENT_RXDRDY)) {
<> 149:156823d33999 145
<> 149:156823d33999 146 #if DEVICE_SERIAL_ASYNCH
<> 149:156823d33999 147 if (UART_CB.rx_active) {
<> 149:156823d33999 148 nrf_uart_event_clear(UART_INSTANCE, NRF_UART_EVENT_RXDRDY);
<> 149:156823d33999 149
<> 149:156823d33999 150 uint8_t rx_data = nrf_uart_rxd_get(UART_INSTANCE);
<> 149:156823d33999 151 UART_CB.rx_buffer[UART_CB.rx_pos] = rx_data;
<> 149:156823d33999 152
<> 149:156823d33999 153 bool end_rx = false;
<> 149:156823d33999 154 // If character matching should be performed, check if the current
<> 149:156823d33999 155 // data matches the given one.
<> 149:156823d33999 156 if (UART_CB.char_match != SERIAL_RESERVED_CHAR_MATCH &&
<> 149:156823d33999 157 rx_data == UART_CB.char_match) {
<> 149:156823d33999 158 // If it does, report the match and abort further receiving.
<> 149:156823d33999 159 UART_CB.events_occured |= SERIAL_EVENT_RX_CHARACTER_MATCH;
<> 149:156823d33999 160 if (UART_CB.events_wanted & SERIAL_EVENT_RX_CHARACTER_MATCH) {
<> 149:156823d33999 161 end_rx = true;
<> 149:156823d33999 162 }
<> 149:156823d33999 163 }
<> 149:156823d33999 164 if (++UART_CB.rx_pos >= UART_CB.rx_length) {
<> 149:156823d33999 165 UART_CB.events_occured |= SERIAL_EVENT_RX_COMPLETE;
<> 149:156823d33999 166 end_rx = true;
<> 149:156823d33999 167 }
<> 149:156823d33999 168 if (end_rx) {
<> 149:156823d33999 169 end_asynch_rx();
<> 149:156823d33999 170
<> 149:156823d33999 171 if (UART_CB.rx_asynch_handler) {
<> 149:156823d33999 172 // Use local variable to make it possible to start a next
<> 149:156823d33999 173 // transfer from callback routine.
<> 149:156823d33999 174 void (*handler)() = UART_CB.rx_asynch_handler;
<> 149:156823d33999 175 UART_CB.rx_asynch_handler = NULL;
<> 149:156823d33999 176 handler();
<> 149:156823d33999 177 }
<> 149:156823d33999 178 }
<> 149:156823d33999 179 }
<> 149:156823d33999 180 else
<> 149:156823d33999 181 #endif
<> 149:156823d33999 182
<> 149:156823d33999 183 if (UART_CB.irq_handler) {
<> 149:156823d33999 184 UART_CB.irq_handler(UART_CB.irq_context, RxIrq);
<> 149:156823d33999 185 }
<> 149:156823d33999 186 }
<> 149:156823d33999 187
<> 149:156823d33999 188 if (nrf_uart_int_enable_check(UART_INSTANCE, NRF_UART_INT_MASK_TXDRDY) &&
<> 149:156823d33999 189 nrf_uart_event_check(UART_INSTANCE, NRF_UART_EVENT_TXDRDY)) {
<> 149:156823d33999 190
<> 149:156823d33999 191 #if DEVICE_SERIAL_ASYNCH
<> 149:156823d33999 192 if (UART_CB.tx_active) {
<> 149:156823d33999 193 if (++UART_CB.tx_pos <= UART_CB.tx_length) {
<> 149:156823d33999 194 // When there is still something to send, clear the TXDRDY event
<> 149:156823d33999 195 // and put next byte to transmitter.
<> 149:156823d33999 196 nrf_uart_event_clear(UART_INSTANCE, NRF_UART_EVENT_TXDRDY);
<> 149:156823d33999 197 nrf_uart_txd_set(UART_INSTANCE,
<> 149:156823d33999 198 UART_CB.tx_buffer[UART_CB.tx_pos]);
<> 149:156823d33999 199 }
<> 149:156823d33999 200 else {
<> 149:156823d33999 201 // When the TXDRDY event is set after the last byte to be sent
<> 149:156823d33999 202 // has been passed to the transmitter, the job is done and TX
<> 149:156823d33999 203 // complete can be indicated.
<> 149:156823d33999 204 // Don't clear the TXDRDY event, it needs to remain set for the
<> 149:156823d33999 205 // 'serial_writable' function to work properly.
<> 149:156823d33999 206 end_asynch_tx();
<> 149:156823d33999 207
<> 149:156823d33999 208 UART_CB.events_occured |= SERIAL_EVENT_TX_COMPLETE;
<> 149:156823d33999 209 if (UART_CB.tx_asynch_handler) {
<> 149:156823d33999 210 // Use local variable to make it possible to start a next
<> 149:156823d33999 211 // transfer from callback routine.
<> 149:156823d33999 212 void (*handler)() = UART_CB.tx_asynch_handler;
<> 149:156823d33999 213 UART_CB.tx_asynch_handler = NULL;
<> 149:156823d33999 214 handler();
<> 149:156823d33999 215 }
<> 149:156823d33999 216 }
<> 149:156823d33999 217 }
<> 149:156823d33999 218 else
<> 149:156823d33999 219 #endif
<> 149:156823d33999 220
<> 149:156823d33999 221 if (UART_CB.irq_handler) {
<> 149:156823d33999 222 UART_CB.irq_handler(UART_CB.irq_context, TxIrq);
<> 149:156823d33999 223 }
<> 149:156823d33999 224 }
<> 149:156823d33999 225
<> 149:156823d33999 226 #if DEVICE_SERIAL_ASYNCH
<> 149:156823d33999 227 if (nrf_uart_event_check(UART_INSTANCE, NRF_UART_EVENT_ERROR)) {
<> 149:156823d33999 228 nrf_uart_event_clear(UART_INSTANCE, NRF_UART_EVENT_ERROR);
<> 149:156823d33999 229
<> 149:156823d33999 230 uint8_t errorsrc = nrf_uart_errorsrc_get_and_clear(UART_INSTANCE);
<> 149:156823d33999 231 if (UART_CB.rx_asynch_handler) {
<> 149:156823d33999 232 UART_CB.events_occured |= SERIAL_EVENT_ERROR;
<> 149:156823d33999 233 if (errorsrc & NRF_UART_ERROR_PARITY_MASK) {
<> 149:156823d33999 234 UART_CB.events_occured |= SERIAL_EVENT_RX_PARITY_ERROR;
<> 149:156823d33999 235 }
<> 149:156823d33999 236 if (errorsrc & NRF_UART_ERROR_FRAMING_MASK) {
<> 149:156823d33999 237 UART_CB.events_occured |= SERIAL_EVENT_RX_FRAMING_ERROR;
<> 149:156823d33999 238 }
<> 149:156823d33999 239 if (errorsrc & NRF_UART_ERROR_OVERRUN_MASK) {
<> 149:156823d33999 240 UART_CB.events_occured |= SERIAL_EVENT_RX_OVERRUN_ERROR;
<> 149:156823d33999 241 }
<> 149:156823d33999 242 UART_CB.rx_asynch_handler();
<> 149:156823d33999 243 }
<> 149:156823d33999 244 }
<> 149:156823d33999 245 #endif // DEVICE_SERIAL_ASYNCH
<> 149:156823d33999 246 }
<> 149:156823d33999 247
<> 149:156823d33999 248 void serial_init(serial_t *obj, PinName tx, PinName rx) {
<> 149:156823d33999 249 UART_CB.pseltxd =
<> 149:156823d33999 250 (tx == NC) ? NRF_UART_PSEL_DISCONNECTED : (uint32_t)tx;
<> 149:156823d33999 251 UART_CB.pselrxd =
<> 149:156823d33999 252 (rx == NC) ? NRF_UART_PSEL_DISCONNECTED : (uint32_t)rx;
<> 149:156823d33999 253 if (UART_CB.pseltxd != NRF_UART_PSEL_DISCONNECTED) {
<> 149:156823d33999 254 nrf_gpio_pin_set(UART_CB.pseltxd);
<> 149:156823d33999 255 nrf_gpio_cfg_output(UART_CB.pseltxd);
<> 149:156823d33999 256 }
<> 149:156823d33999 257 if (UART_CB.pselrxd != NRF_UART_PSEL_DISCONNECTED) {
<> 149:156823d33999 258 nrf_gpio_cfg_input(UART_CB.pselrxd, NRF_GPIO_PIN_NOPULL);
<> 149:156823d33999 259 }
<> 149:156823d33999 260
<> 149:156823d33999 261 if (UART_CB.initialized) {
<> 149:156823d33999 262 // For already initialized peripheral it is sufficient to reconfigure
<> 149:156823d33999 263 // RX/TX pins only.
<> 149:156823d33999 264
<> 149:156823d33999 265 // Ensure that there is no unfinished TX transfer.
<> 149:156823d33999 266 while (!serial_writable(obj)) {
<> 149:156823d33999 267 }
<> 149:156823d33999 268 // UART pins can be configured only when the peripheral is disabled.
<> 149:156823d33999 269 nrf_uart_disable(UART_INSTANCE);
<> 149:156823d33999 270 nrf_uart_txrx_pins_set(UART_INSTANCE, UART_CB.pseltxd, UART_CB.pselrxd);
<> 149:156823d33999 271 nrf_uart_enable(UART_INSTANCE);
<> 149:156823d33999 272 }
<> 149:156823d33999 273 else {
<> 149:156823d33999 274 UART_CB.baudrate = UART_DEFAULT_BAUDRATE;
<> 149:156823d33999 275 UART_CB.parity = UART_DEFAULT_PARITY;
<> 149:156823d33999 276 UART_CB.hwfc = UART_DEFAULT_HWFC;
<> 149:156823d33999 277 UART_CB.pselcts = UART_DEFAULT_CTS;
<> 149:156823d33999 278 UART_CB.pselrts = UART_DEFAULT_RTS;
<> 149:156823d33999 279
<> 149:156823d33999 280 nrf_uart_event_clear(UART_INSTANCE, NRF_UART_EVENT_RXDRDY);
<> 149:156823d33999 281 nrf_uart_event_clear(UART_INSTANCE, NRF_UART_EVENT_TXDRDY);
<> 149:156823d33999 282 nrf_uart_task_trigger(UART_INSTANCE, NRF_UART_TASK_STARTRX);
<> 149:156823d33999 283 nrf_uart_task_trigger(UART_INSTANCE, NRF_UART_TASK_STARTTX);
<> 149:156823d33999 284
<> 149:156823d33999 285 nrf_uart_int_disable(UART_INSTANCE, NRF_UART_INT_MASK_RXDRDY |
<> 149:156823d33999 286 NRF_UART_INT_MASK_TXDRDY);
<> 149:156823d33999 287 #if DEVICE_SERIAL_ASYNCH
<> 149:156823d33999 288 nrf_uart_int_enable(UART_INSTANCE, NRF_UART_INT_MASK_ERROR);
<> 149:156823d33999 289 #endif
<> 149:156823d33999 290 nrf_drv_common_irq_enable(UART_IRQn, APP_IRQ_PRIORITY_LOW);
<> 149:156823d33999 291
<> 149:156823d33999 292 // TX interrupt needs to be signaled when transmitter buffer is empty,
<> 149:156823d33999 293 // so a dummy transmission is needed to get the TXDRDY event initially
<> 149:156823d33999 294 // set.
<> 149:156823d33999 295 nrf_uart_configure(UART_INSTANCE,
<> 149:156823d33999 296 NRF_UART_PARITY_EXCLUDED, NRF_UART_HWFC_DISABLED);
<> 149:156823d33999 297 // Use maximum baud rate, so this dummy transmission takes as little
<> 149:156823d33999 298 // time as possible.
<> 149:156823d33999 299 nrf_uart_baudrate_set(UART_INSTANCE, NRF_UART_BAUDRATE_1000000);
<> 149:156823d33999 300 // Perform it with disconnected TX pin, so nothing actually comes out
<> 149:156823d33999 301 // of the device.
<> 149:156823d33999 302 nrf_uart_txrx_pins_disconnect(UART_INSTANCE);
<> 149:156823d33999 303 nrf_uart_hwfc_pins_disconnect(UART_INSTANCE);
<> 149:156823d33999 304 nrf_uart_enable(UART_INSTANCE);
<> 149:156823d33999 305 nrf_uart_txd_set(UART_INSTANCE, 0);
<> 149:156823d33999 306 while (!nrf_uart_event_check(UART_INSTANCE, NRF_UART_EVENT_TXDRDY)) {
<> 149:156823d33999 307 }
<> 149:156823d33999 308 nrf_uart_disable(UART_INSTANCE);
<> 149:156823d33999 309
<> 149:156823d33999 310 // Now everything is prepared to set the default configuration and
<> 149:156823d33999 311 // connect the peripheral to actual pins.
<> 149:156823d33999 312 nrf_uart_txrx_pins_set(UART_INSTANCE, UART_CB.pseltxd, UART_CB.pselrxd);
<> 149:156823d33999 313 nrf_uart_baudrate_set(UART_INSTANCE, UART_CB.baudrate);
<> 149:156823d33999 314 nrf_uart_configure(UART_INSTANCE, UART_CB.parity, UART_CB.hwfc);
<> 149:156823d33999 315 if (UART_CB.hwfc == NRF_UART_HWFC_ENABLED) {
<> 149:156823d33999 316 serial_set_flow_control(obj, FlowControlRTSCTS,
<> 149:156823d33999 317 (PinName) UART_CB.pselrts, (PinName) UART_CB.pselcts);
<> 149:156823d33999 318 }
<> 149:156823d33999 319 nrf_uart_enable(UART_INSTANCE);
<> 149:156823d33999 320
<> 149:156823d33999 321 UART_CB.initialized = true;
<> 149:156823d33999 322 }
<> 149:156823d33999 323
<> 149:156823d33999 324 if (tx == STDIO_UART_TX && rx == STDIO_UART_RX) {
<> 149:156823d33999 325 stdio_uart_inited = 1;
<> 149:156823d33999 326 memcpy(&stdio_uart, obj, sizeof(serial_t));
<> 149:156823d33999 327 }
<> 149:156823d33999 328 else {
<> 149:156823d33999 329 stdio_uart_inited = 0;
<> 149:156823d33999 330 }
<> 149:156823d33999 331 }
<> 149:156823d33999 332
<> 149:156823d33999 333 void serial_free(serial_t *obj)
<> 149:156823d33999 334 {
<> 149:156823d33999 335 (void)obj;
<> 149:156823d33999 336
<> 149:156823d33999 337 if (UART_CB.initialized) {
<> 149:156823d33999 338 nrf_uart_disable(UART_INSTANCE);
<> 149:156823d33999 339 nrf_uart_int_disable(UART_INSTANCE, NRF_UART_INT_MASK_RXDRDY |
<> 149:156823d33999 340 NRF_UART_INT_MASK_TXDRDY |
<> 149:156823d33999 341 NRF_UART_INT_MASK_ERROR);
<> 149:156823d33999 342 nrf_drv_common_irq_disable(UART_IRQn);
<> 149:156823d33999 343 UART_CB.initialized = false;
<> 149:156823d33999 344
<> 149:156823d33999 345 // There is only one UART instance, thus at this point the stdio UART
<> 149:156823d33999 346 // can no longer be initialized.
<> 149:156823d33999 347 stdio_uart_inited = 0;
<> 149:156823d33999 348 }
<> 149:156823d33999 349 }
<> 149:156823d33999 350
<> 149:156823d33999 351 void serial_baud(serial_t *obj, int baudrate)
<> 149:156823d33999 352 {
<> 149:156823d33999 353 // nrf_uart_baudrate_set() is not used here (registers are accessed
<> 149:156823d33999 354 // directly) to make it possible to set special baud rates like 56000
<> 149:156823d33999 355 // or 31250.
<> 149:156823d33999 356
<> 149:156823d33999 357 static uint32_t const acceptedSpeeds[][2] = {
<> 149:156823d33999 358 { 1200, UART_BAUDRATE_BAUDRATE_Baud1200 },
<> 149:156823d33999 359 { 2400, UART_BAUDRATE_BAUDRATE_Baud2400 },
<> 149:156823d33999 360 { 4800, UART_BAUDRATE_BAUDRATE_Baud4800 },
<> 149:156823d33999 361 { 9600, UART_BAUDRATE_BAUDRATE_Baud9600 },
<> 149:156823d33999 362 { 14400, UART_BAUDRATE_BAUDRATE_Baud14400 },
<> 149:156823d33999 363 { 19200, UART_BAUDRATE_BAUDRATE_Baud19200 },
<> 149:156823d33999 364 { 28800, UART_BAUDRATE_BAUDRATE_Baud28800 },
<> 149:156823d33999 365 { 31250, (0x00800000UL) /* 31250 baud */ },
<> 149:156823d33999 366 { 38400, UART_BAUDRATE_BAUDRATE_Baud38400 },
<> 149:156823d33999 367 { 56000, (0x00E51000UL) /* 56000 baud */ },
<> 149:156823d33999 368 { 57600, UART_BAUDRATE_BAUDRATE_Baud57600 },
<> 149:156823d33999 369 { 76800, UART_BAUDRATE_BAUDRATE_Baud76800 },
<> 149:156823d33999 370 { 115200, UART_BAUDRATE_BAUDRATE_Baud115200 },
<> 149:156823d33999 371 { 230400, UART_BAUDRATE_BAUDRATE_Baud230400 },
<> 149:156823d33999 372 { 250000, UART_BAUDRATE_BAUDRATE_Baud250000 },
<> 149:156823d33999 373 { 460800, UART_BAUDRATE_BAUDRATE_Baud460800 },
<> 149:156823d33999 374 { 921600, UART_BAUDRATE_BAUDRATE_Baud921600 },
<> 149:156823d33999 375 { 1000000, UART_BAUDRATE_BAUDRATE_Baud1M }
<> 149:156823d33999 376 };
<> 149:156823d33999 377
<> 149:156823d33999 378 if (baudrate <= 1200) {
<> 149:156823d33999 379 UART_INSTANCE->BAUDRATE = UART_BAUDRATE_BAUDRATE_Baud1200;
<> 149:156823d33999 380 return;
<> 149:156823d33999 381 }
<> 149:156823d33999 382
<> 149:156823d33999 383 int const item_cnt = sizeof(acceptedSpeeds)/sizeof(acceptedSpeeds[0]);
<> 149:156823d33999 384 for (int i = 1; i < item_cnt; i++) {
<> 149:156823d33999 385 if ((uint32_t)baudrate < acceptedSpeeds[i][0]) {
<> 149:156823d33999 386 UART_INSTANCE->BAUDRATE = acceptedSpeeds[i - 1][1];
<> 149:156823d33999 387 return;
<> 149:156823d33999 388 }
<> 149:156823d33999 389 }
<> 149:156823d33999 390
<> 149:156823d33999 391 UART_INSTANCE->BAUDRATE = UART_BAUDRATE_BAUDRATE_Baud1M;
<> 149:156823d33999 392 }
<> 149:156823d33999 393
<> 149:156823d33999 394 void serial_format(serial_t *obj,
<> 149:156823d33999 395 int data_bits, SerialParity parity, int stop_bits)
<> 149:156823d33999 396 {
<> 149:156823d33999 397 (void)obj;
<> 149:156823d33999 398
<> 149:156823d33999 399 if (data_bits != 8) {
<> 149:156823d33999 400 error("UART supports only 8 data bits.\r\n");
<> 149:156823d33999 401 }
<> 149:156823d33999 402 if (stop_bits != 1) {
<> 149:156823d33999 403 error("UART supports only 1 stop bits.\r\n");
<> 149:156823d33999 404 }
<> 149:156823d33999 405 if (parity == ParityNone) {
<> 149:156823d33999 406 UART_CB.parity = NRF_UART_PARITY_EXCLUDED;
<> 149:156823d33999 407 } else if (parity == ParityEven) {
<> 149:156823d33999 408 UART_CB.parity = NRF_UART_PARITY_INCLUDED;
<> 149:156823d33999 409 } else {
<> 149:156823d33999 410 error("UART supports only even parity.\r\n");
<> 149:156823d33999 411 }
<> 149:156823d33999 412
<> 149:156823d33999 413 // Reconfigure UART peripheral.
<> 149:156823d33999 414 nrf_uart_configure(UART_INSTANCE, UART_CB.parity, UART_CB.hwfc);
<> 149:156823d33999 415 }
<> 149:156823d33999 416
<> 149:156823d33999 417 void serial_irq_handler(serial_t *obj, uart_irq_handler handler, uint32_t id)
<> 149:156823d33999 418 {
<> 149:156823d33999 419 (void)obj;
<> 149:156823d33999 420 UART_CB.irq_handler = handler;
<> 149:156823d33999 421 UART_CB.irq_context = id;
<> 149:156823d33999 422 }
<> 149:156823d33999 423
<> 149:156823d33999 424 void serial_irq_set(serial_t *obj, SerialIrq irq, uint32_t enable)
<> 149:156823d33999 425 {
<> 149:156823d33999 426 (void)obj;
<> 149:156823d33999 427 if (enable) {
<> 149:156823d33999 428 switch (irq) {
<> 149:156823d33999 429 case RxIrq:
<> 149:156823d33999 430 #if DEVICE_SERIAL_ASYNCH
<> 149:156823d33999 431 UART_CB.irq_enabled |= UART_IRQ_RX;
<> 149:156823d33999 432 #endif
<> 149:156823d33999 433 nrf_uart_int_enable(UART_INSTANCE, NRF_UART_INT_MASK_RXDRDY);
<> 149:156823d33999 434 break;
<> 149:156823d33999 435
<> 149:156823d33999 436 case TxIrq:
<> 149:156823d33999 437 #if DEVICE_SERIAL_ASYNCH
<> 149:156823d33999 438 UART_CB.irq_enabled |= UART_IRQ_TX;
<> 149:156823d33999 439 #endif
<> 149:156823d33999 440 nrf_uart_int_enable(UART_INSTANCE, NRF_UART_INT_MASK_TXDRDY);
<> 149:156823d33999 441 break;
<> 149:156823d33999 442 }
<> 149:156823d33999 443 } else {
<> 149:156823d33999 444 switch (irq) {
<> 149:156823d33999 445 case RxIrq:
<> 149:156823d33999 446 #if DEVICE_SERIAL_ASYNCH
<> 149:156823d33999 447 UART_CB.irq_enabled &= ~UART_IRQ_RX;
<> 149:156823d33999 448 if (!UART_CB.rx_active)
<> 149:156823d33999 449 #endif
<> 149:156823d33999 450 {
<> 149:156823d33999 451 nrf_uart_int_disable(UART_INSTANCE,
<> 149:156823d33999 452 NRF_UART_INT_MASK_RXDRDY);
<> 149:156823d33999 453 }
<> 149:156823d33999 454 break;
<> 149:156823d33999 455
<> 149:156823d33999 456 case TxIrq:
<> 149:156823d33999 457 #if DEVICE_SERIAL_ASYNCH
<> 149:156823d33999 458 UART_CB.irq_enabled &= ~UART_IRQ_TX;
<> 149:156823d33999 459 if (!UART_CB.tx_active)
<> 149:156823d33999 460 #endif
<> 149:156823d33999 461 {
<> 149:156823d33999 462 nrf_uart_int_disable(UART_INSTANCE,
<> 149:156823d33999 463 NRF_UART_INT_MASK_TXDRDY);
<> 149:156823d33999 464 }
<> 149:156823d33999 465 break;
<> 149:156823d33999 466 }
<> 149:156823d33999 467 }
<> 149:156823d33999 468 }
<> 149:156823d33999 469
<> 149:156823d33999 470 int serial_getc(serial_t *obj)
<> 149:156823d33999 471 {
<> 149:156823d33999 472 while (!serial_readable(obj)) {
<> 149:156823d33999 473 }
<> 149:156823d33999 474
<> 149:156823d33999 475 nrf_uart_event_clear(UART_INSTANCE, NRF_UART_EVENT_RXDRDY);
<> 149:156823d33999 476 return nrf_uart_rxd_get(UART_INSTANCE);
<> 149:156823d33999 477 }
<> 149:156823d33999 478
<> 149:156823d33999 479 void serial_putc(serial_t *obj, int c)
<> 149:156823d33999 480 {
<> 149:156823d33999 481 while (!serial_writable(obj)) {
<> 149:156823d33999 482 }
<> 149:156823d33999 483
<> 149:156823d33999 484 nrf_uart_event_clear(UART_INSTANCE, NRF_UART_EVENT_TXDRDY);
<> 149:156823d33999 485 nrf_uart_txd_set(UART_INSTANCE, (uint8_t)c);
<> 149:156823d33999 486 }
<> 149:156823d33999 487
<> 149:156823d33999 488 int serial_readable(serial_t *obj)
<> 149:156823d33999 489 {
<> 149:156823d33999 490 (void)obj;
<> 149:156823d33999 491 #if DEVICE_SERIAL_ASYNCH
<> 149:156823d33999 492 if (UART_CB.rx_active) {
<> 149:156823d33999 493 return 0;
<> 149:156823d33999 494 }
<> 149:156823d33999 495 #endif
<> 149:156823d33999 496 return (nrf_uart_event_check(UART_INSTANCE, NRF_UART_EVENT_RXDRDY));
<> 149:156823d33999 497 }
<> 149:156823d33999 498
<> 149:156823d33999 499 int serial_writable(serial_t *obj)
<> 149:156823d33999 500 {
<> 149:156823d33999 501 (void)obj;
<> 149:156823d33999 502 #if DEVICE_SERIAL_ASYNCH
<> 149:156823d33999 503 if (UART_CB.tx_active) {
<> 149:156823d33999 504 return 0;
<> 149:156823d33999 505 }
<> 149:156823d33999 506 #endif
<> 149:156823d33999 507 return (nrf_uart_event_check(UART_INSTANCE, NRF_UART_EVENT_TXDRDY));
<> 149:156823d33999 508 }
<> 149:156823d33999 509
<> 149:156823d33999 510 void serial_break_set(serial_t *obj)
<> 149:156823d33999 511 {
<> 149:156823d33999 512 (void)obj;
<> 149:156823d33999 513 nrf_uart_task_trigger(UART_INSTANCE, NRF_UART_TASK_SUSPEND);
<> 149:156823d33999 514 nrf_uart_txrx_pins_disconnect(UART_INSTANCE);
<> 149:156823d33999 515 nrf_gpio_pin_clear(UART_CB.pseltxd);
<> 149:156823d33999 516 }
<> 149:156823d33999 517
<> 149:156823d33999 518 void serial_break_clear(serial_t *obj)
<> 149:156823d33999 519 {
<> 149:156823d33999 520 (void)obj;
<> 149:156823d33999 521 nrf_gpio_pin_set(UART_CB.pseltxd);
<> 149:156823d33999 522 nrf_uart_txrx_pins_set(UART_INSTANCE, UART_CB.pseltxd, UART_CB.pselrxd);
<> 149:156823d33999 523 nrf_uart_task_trigger(UART_INSTANCE, NRF_UART_TASK_STARTRX);
<> 149:156823d33999 524 nrf_uart_task_trigger(UART_INSTANCE, NRF_UART_TASK_STARTTX);
<> 149:156823d33999 525 }
<> 149:156823d33999 526
<> 149:156823d33999 527 void serial_set_flow_control(serial_t *obj, FlowControl type,
<> 149:156823d33999 528 PinName rxflow, PinName txflow)
<> 149:156823d33999 529 {
<> 149:156823d33999 530 (void)obj;
<> 149:156823d33999 531
<> 149:156823d33999 532 UART_CB.pselrts =
<> 149:156823d33999 533 (rxflow == NC) ? NRF_UART_PSEL_DISCONNECTED : (uint32_t)rxflow;
<> 149:156823d33999 534 UART_CB.pselcts =
<> 149:156823d33999 535 (txflow == NC) ? NRF_UART_PSEL_DISCONNECTED : (uint32_t)txflow;
<> 149:156823d33999 536
<> 149:156823d33999 537 if (UART_CB.pselrts != NRF_UART_PSEL_DISCONNECTED) {
<> 149:156823d33999 538 nrf_gpio_pin_set(UART_CB.pselrts);
<> 149:156823d33999 539 nrf_gpio_cfg_output(UART_CB.pselrts);
<> 149:156823d33999 540 }
<> 149:156823d33999 541 if (UART_CB.pselcts != NRF_UART_PSEL_DISCONNECTED) {
<> 149:156823d33999 542 nrf_gpio_cfg_input(UART_CB.pselcts, NRF_GPIO_PIN_NOPULL);
<> 149:156823d33999 543 }
<> 149:156823d33999 544 nrf_uart_disable(UART_INSTANCE);
<> 149:156823d33999 545 nrf_uart_hwfc_pins_set(UART_INSTANCE, UART_CB.pselrts, UART_CB.pselcts);
<> 149:156823d33999 546 nrf_uart_enable(UART_INSTANCE);
<> 149:156823d33999 547 }
<> 149:156823d33999 548
<> 149:156823d33999 549 void serial_clear(serial_t *obj) {
<> 149:156823d33999 550 (void)obj;
<> 149:156823d33999 551 }
<> 149:156823d33999 552
<> 149:156823d33999 553 #if DEVICE_SERIAL_ASYNCH
<> 149:156823d33999 554
<> 149:156823d33999 555 int serial_tx_asynch(serial_t *obj, const void *tx, size_t tx_length,
<> 149:156823d33999 556 uint8_t tx_width, uint32_t handler, uint32_t event,
<> 149:156823d33999 557 DMAUsage hint)
<> 149:156823d33999 558 {
<> 149:156823d33999 559 (void)obj;
<> 149:156823d33999 560 (void)tx_width;
<> 149:156823d33999 561 (void)hint;
<> 149:156823d33999 562 if (UART_CB.tx_active || !tx_length) {
<> 149:156823d33999 563 return 0;
<> 149:156823d33999 564 }
<> 149:156823d33999 565
<> 149:156823d33999 566 UART_CB.tx_buffer = tx;
<> 149:156823d33999 567 UART_CB.tx_length = tx_length;
<> 149:156823d33999 568 UART_CB.tx_pos = 0;
<> 149:156823d33999 569 UART_CB.tx_asynch_handler = (void(*)())handler;
<> 149:156823d33999 570 UART_CB.events_wanted &= ~SERIAL_EVENT_TX_ALL;
<> 149:156823d33999 571 UART_CB.events_wanted |= event;
<> 149:156823d33999 572
<> 149:156823d33999 573 UART_CB.tx_active = true;
<> 149:156823d33999 574 nrf_uart_int_enable(UART_INSTANCE, NRF_UART_INT_MASK_TXDRDY);
<> 149:156823d33999 575
<> 149:156823d33999 576 return 0;
<> 149:156823d33999 577 }
<> 149:156823d33999 578
<> 149:156823d33999 579 void serial_rx_asynch(serial_t *obj, void *rx, size_t rx_length,
<> 149:156823d33999 580 uint8_t rx_width, uint32_t handler, uint32_t event,
<> 149:156823d33999 581 uint8_t char_match, DMAUsage hint)
<> 149:156823d33999 582 {
<> 149:156823d33999 583 (void)obj;
<> 149:156823d33999 584 (void)rx_width;
<> 149:156823d33999 585 (void)hint;
<> 149:156823d33999 586 if (UART_CB.rx_active || !rx_length) {
<> 149:156823d33999 587 return;
<> 149:156823d33999 588 }
<> 149:156823d33999 589
<> 149:156823d33999 590 UART_CB.rx_buffer = rx;
<> 149:156823d33999 591 UART_CB.rx_length = rx_length;
<> 149:156823d33999 592 UART_CB.rx_pos = 0;
<> 149:156823d33999 593 UART_CB.rx_asynch_handler = (void(*)())handler;
<> 149:156823d33999 594 UART_CB.events_wanted &= ~SERIAL_EVENT_RX_ALL;
<> 149:156823d33999 595 UART_CB.events_wanted |= event;
<> 149:156823d33999 596 UART_CB.char_match = char_match;
<> 149:156823d33999 597
<> 149:156823d33999 598 UART_CB.rx_active = true;
<> 149:156823d33999 599 nrf_uart_int_enable(UART_INSTANCE, NRF_UART_INT_MASK_RXDRDY);
<> 149:156823d33999 600 }
<> 149:156823d33999 601
<> 149:156823d33999 602 uint8_t serial_tx_active(serial_t *obj)
<> 149:156823d33999 603 {
<> 149:156823d33999 604 (void)obj;
<> 149:156823d33999 605 return UART_CB.tx_active;
<> 149:156823d33999 606 }
<> 149:156823d33999 607
<> 149:156823d33999 608 uint8_t serial_rx_active(serial_t *obj)
<> 149:156823d33999 609 {
<> 149:156823d33999 610 (void)obj;
<> 149:156823d33999 611 return UART_CB.rx_active;
<> 149:156823d33999 612 }
<> 149:156823d33999 613
<> 149:156823d33999 614 int serial_irq_handler_asynch(serial_t *obj)
<> 149:156823d33999 615 {
<> 149:156823d33999 616 (void)obj;
<> 149:156823d33999 617 uint32_t events_to_report = UART_CB.events_wanted & UART_CB.events_occured;
<> 149:156823d33999 618 UART_CB.events_occured &= (~events_to_report);
<> 149:156823d33999 619 return events_to_report;
<> 149:156823d33999 620 }
<> 149:156823d33999 621
<> 149:156823d33999 622 void serial_tx_abort_asynch(serial_t *obj)
<> 149:156823d33999 623 {
<> 149:156823d33999 624 (void)obj;
<> 149:156823d33999 625 end_asynch_tx();
<> 149:156823d33999 626 UART_CB.tx_asynch_handler = NULL;
<> 149:156823d33999 627 }
<> 149:156823d33999 628
<> 149:156823d33999 629 void serial_rx_abort_asynch(serial_t *obj)
<> 149:156823d33999 630 {
<> 149:156823d33999 631 (void)obj;
<> 149:156823d33999 632 end_asynch_rx();
<> 149:156823d33999 633 UART_CB.rx_asynch_handler = NULL;
<> 149:156823d33999 634 }
<> 149:156823d33999 635
<> 149:156823d33999 636 #endif // DEVICE_SERIAL_ASYNCH
<> 149:156823d33999 637
<> 149:156823d33999 638 #endif // DEVICE_SERIAL