mbed official / mbed-dev

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:
188:bcfe06ba3d64
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 * Copyright (c) 2013 Nordic Semiconductor ASA
Anna Bridge 186:707f6e361f3e 3 * All rights reserved.
Anna Bridge 186:707f6e361f3e 4 *
Anna Bridge 186:707f6e361f3e 5 * Redistribution and use in source and binary forms, with or without modification,
Anna Bridge 186:707f6e361f3e 6 * are permitted provided that the following conditions are met:
Anna Bridge 186:707f6e361f3e 7 *
Anna Bridge 186:707f6e361f3e 8 * 1. Redistributions of source code must retain the above copyright notice, this list
Anna Bridge 186:707f6e361f3e 9 * of conditions and the following disclaimer.
Anna Bridge 186:707f6e361f3e 10 *
Anna Bridge 186:707f6e361f3e 11 * 2. Redistributions in binary form, except as embedded into a Nordic Semiconductor ASA
Anna Bridge 186:707f6e361f3e 12 * integrated circuit in a product or a software update for such product, must reproduce
Anna Bridge 186:707f6e361f3e 13 * the above copyright notice, this list of conditions and the following disclaimer in
Anna Bridge 186:707f6e361f3e 14 * the documentation and/or other materials provided with the distribution.
Anna Bridge 186:707f6e361f3e 15 *
Anna Bridge 186:707f6e361f3e 16 * 3. Neither the name of Nordic Semiconductor ASA nor the names of its contributors may be
Anna Bridge 186:707f6e361f3e 17 * used to endorse or promote products derived from this software without specific prior
Anna Bridge 186:707f6e361f3e 18 * written permission.
Anna Bridge 186:707f6e361f3e 19 *
Anna Bridge 186:707f6e361f3e 20 * 4. This software, with or without modification, must only be used with a
Anna Bridge 186:707f6e361f3e 21 * Nordic Semiconductor ASA integrated circuit.
Anna Bridge 186:707f6e361f3e 22 *
Anna Bridge 186:707f6e361f3e 23 * 5. Any software provided in binary or object form under this license must not be reverse
Anna Bridge 186:707f6e361f3e 24 * engineered, decompiled, modified and/or disassembled.
Anna Bridge 186:707f6e361f3e 25 *
Anna Bridge 186:707f6e361f3e 26 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
Anna Bridge 186:707f6e361f3e 27 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
Anna Bridge 186:707f6e361f3e 28 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
Anna Bridge 186:707f6e361f3e 29 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
Anna Bridge 186:707f6e361f3e 30 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
Anna Bridge 186:707f6e361f3e 31 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
Anna Bridge 186:707f6e361f3e 32 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
Anna Bridge 186:707f6e361f3e 33 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
Anna Bridge 186:707f6e361f3e 34 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
Anna Bridge 186:707f6e361f3e 35 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Anna Bridge 186:707f6e361f3e 36 *
Anna Bridge 186:707f6e361f3e 37 */
Anna Bridge 186:707f6e361f3e 38
Anna Bridge 186:707f6e361f3e 39 #if DEVICE_SERIAL
Anna Bridge 186:707f6e361f3e 40
Anna Bridge 186:707f6e361f3e 41 #include "hal/serial_api.h"
Anna Bridge 186:707f6e361f3e 42
Anna Bridge 186:707f6e361f3e 43 #include "nrf_uarte.h"
Anna Bridge 186:707f6e361f3e 44 #include "nrf_drv_uart.h"
Anna Bridge 186:707f6e361f3e 45 #include "nrf_drv_common.h"
Anna Bridge 186:707f6e361f3e 46 #include "nrf_atfifo.h"
Anna Bridge 186:707f6e361f3e 47 #include "app_util_platform.h"
Anna Bridge 186:707f6e361f3e 48 #include "pinmap_ex.h"
AnnaBridge 189:f392fc9709a3 49 #include "nrf_drv_ppi.h"
AnnaBridge 189:f392fc9709a3 50 #include "nrf_drv_gpiote.h"
Anna Bridge 186:707f6e361f3e 51
Anna Bridge 186:707f6e361f3e 52 #include "platform/mbed_critical.h"
Anna Bridge 186:707f6e361f3e 53
Anna Bridge 186:707f6e361f3e 54 #if UART0_ENABLED == 0
Anna Bridge 186:707f6e361f3e 55 #error UART0 is disabled. DEVICE_SERIAL must also be disabled to continue.
AnnaBridge 187:0387e8f68319 56 #endif
Anna Bridge 186:707f6e361f3e 57
Anna Bridge 186:707f6e361f3e 58
Anna Bridge 186:707f6e361f3e 59 /***
AnnaBridge 187:0387e8f68319 60 * _____ __ _ _ _
AnnaBridge 187:0387e8f68319 61 * / ____| / _(_) | | (_)
AnnaBridge 187:0387e8f68319 62 * | | ___ _ __ | |_ _ __ _ _ _ _ __ __ _| |_ _ ___ _ __
AnnaBridge 187:0387e8f68319 63 * | | / _ \| '_ \| _| |/ _` | | | | '__/ _` | __| |/ _ \| '_ \
Anna Bridge 186:707f6e361f3e 64 * | |___| (_) | | | | | | | (_| | |_| | | | (_| | |_| | (_) | | | |
Anna Bridge 186:707f6e361f3e 65 * \_____\___/|_| |_|_| |_|\__, |\__,_|_| \__,_|\__|_|\___/|_| |_|
AnnaBridge 187:0387e8f68319 66 * __/ |
AnnaBridge 187:0387e8f68319 67 * |___/
Anna Bridge 186:707f6e361f3e 68 */
Anna Bridge 186:707f6e361f3e 69
Anna Bridge 186:707f6e361f3e 70 /**
Anna Bridge 186:707f6e361f3e 71 * Default FIFO buffer size for UARTE0.
Anna Bridge 186:707f6e361f3e 72 */
Anna Bridge 186:707f6e361f3e 73 #ifndef MBED_CONF_NORDIC_UART_0_FIFO_SIZE
Anna Bridge 186:707f6e361f3e 74 #define MBED_CONF_NORDIC_UART_0_FIFO_SIZE 32
Anna Bridge 186:707f6e361f3e 75 #endif
Anna Bridge 186:707f6e361f3e 76
Anna Bridge 186:707f6e361f3e 77 /**
Anna Bridge 186:707f6e361f3e 78 * Default FIFO buffer size for UARTE1.
Anna Bridge 186:707f6e361f3e 79 */
Anna Bridge 186:707f6e361f3e 80 #ifndef MBED_CONF_NORDIC_UART_1_FIFO_SIZE
Anna Bridge 186:707f6e361f3e 81 #define MBED_CONF_NORDIC_UART_1_FIFO_SIZE 32
Anna Bridge 186:707f6e361f3e 82 #endif
Anna Bridge 186:707f6e361f3e 83
Anna Bridge 186:707f6e361f3e 84 /**
Anna Bridge 186:707f6e361f3e 85 * Internal short names.
Anna Bridge 186:707f6e361f3e 86 */
Anna Bridge 186:707f6e361f3e 87 #define UART0_FIFO_BUFFER_SIZE MBED_CONF_NORDIC_UART_0_FIFO_SIZE
Anna Bridge 186:707f6e361f3e 88 #define UART1_FIFO_BUFFER_SIZE MBED_CONF_NORDIC_UART_1_FIFO_SIZE
AnnaBridge 189:f392fc9709a3 89 #define DMA_BUFFER_SIZE 1
Anna Bridge 186:707f6e361f3e 90 #define NUMBER_OF_BANKS 2
AnnaBridge 189:f392fc9709a3 91 #define FIFO_MIN 3
Anna Bridge 186:707f6e361f3e 92
Anna Bridge 186:707f6e361f3e 93 /***
AnnaBridge 187:0387e8f68319 94 * _______ _ __
AnnaBridge 187:0387e8f68319 95 * |__ __| | | / _|
AnnaBridge 187:0387e8f68319 96 * | |_ _ _ __ ___ __| | ___| |_ ___
Anna Bridge 186:707f6e361f3e 97 * | | | | | '_ \ / _ \/ _` |/ _ \ _/ __|
Anna Bridge 186:707f6e361f3e 98 * | | |_| | |_) | __/ (_| | __/ | \__ \
Anna Bridge 186:707f6e361f3e 99 * |_|\__, | .__/ \___|\__,_|\___|_| |___/
AnnaBridge 187:0387e8f68319 100 * __/ | |
AnnaBridge 187:0387e8f68319 101 * |___/|_|
Anna Bridge 186:707f6e361f3e 102 */
Anna Bridge 186:707f6e361f3e 103
Anna Bridge 186:707f6e361f3e 104 /**
Anna Bridge 186:707f6e361f3e 105 * Missing event typedefs.
Anna Bridge 186:707f6e361f3e 106 */
Anna Bridge 186:707f6e361f3e 107 typedef enum
Anna Bridge 186:707f6e361f3e 108 {
Anna Bridge 186:707f6e361f3e 109 NRF_UARTE_EVENT_RXDRDY = offsetof(NRF_UARTE_Type, EVENTS_RXDRDY),
Anna Bridge 186:707f6e361f3e 110 NRF_UARTE_EVENT_TXDRDY = offsetof(NRF_UARTE_Type, EVENTS_TXDRDY),
Anna Bridge 186:707f6e361f3e 111 } nrf_uarte_event_extra_t;
Anna Bridge 186:707f6e361f3e 112
Anna Bridge 186:707f6e361f3e 113 /**
Anna Bridge 186:707f6e361f3e 114 * Missing interrupt masks.
Anna Bridge 186:707f6e361f3e 115 */
Anna Bridge 186:707f6e361f3e 116 typedef enum
Anna Bridge 186:707f6e361f3e 117 {
Anna Bridge 186:707f6e361f3e 118 NRF_UARTE_INT_RXDRDY_MASK = UARTE_INTENSET_RXDRDY_Msk,
Anna Bridge 186:707f6e361f3e 119 NRF_UARTE_INT_TXDRDY_MASK = UARTE_INTENSET_TXDRDY_Msk,
Anna Bridge 186:707f6e361f3e 120 } nrf_uarte_int_mask_extra_t;
Anna Bridge 186:707f6e361f3e 121
Anna Bridge 186:707f6e361f3e 122 /**
Anna Bridge 186:707f6e361f3e 123 * Internal struct for storing each UARTE instance's state:
AnnaBridge 187:0387e8f68319 124 *
Anna Bridge 186:707f6e361f3e 125 * owner: pointer to serial object currently using instance.
Anna Bridge 186:707f6e361f3e 126 * buffer: buffers assigned to EasyDMA.
Anna Bridge 186:707f6e361f3e 127 * tx_data: 1 byte Tx buffer for blocking putc.
Anna Bridge 186:707f6e361f3e 128 * tx_in_progress: mutex for atomic Tx.
Anna Bridge 186:707f6e361f3e 129 * rx_in_progress: mutex for atomic Rx when using async API.
Anna Bridge 186:707f6e361f3e 130 * tx_asynch: set synch or asynch mode for Tx.
Anna Bridge 186:707f6e361f3e 131 * rx_asynch: set synch or asynch mode for Rx.
Anna Bridge 186:707f6e361f3e 132 * callback_posted: flag for posting only one callback.
Anna Bridge 186:707f6e361f3e 133 * active_bank: flag for buffer swapping.
Anna Bridge 186:707f6e361f3e 134 * fifo: pointer to the FIFO buffer.
Anna Bridge 186:707f6e361f3e 135 */
Anna Bridge 186:707f6e361f3e 136 typedef struct {
Anna Bridge 186:707f6e361f3e 137 struct serial_s *owner;
Anna Bridge 186:707f6e361f3e 138 uint8_t buffer[NUMBER_OF_BANKS][DMA_BUFFER_SIZE];
Anna Bridge 186:707f6e361f3e 139 uint32_t usage_counter;
Anna Bridge 186:707f6e361f3e 140 uint8_t tx_data;
Anna Bridge 186:707f6e361f3e 141 volatile uint8_t tx_in_progress;
Anna Bridge 186:707f6e361f3e 142 volatile uint8_t rx_in_progress;
Anna Bridge 186:707f6e361f3e 143 bool tx_asynch;
Anna Bridge 186:707f6e361f3e 144 bool rx_asynch;
Anna Bridge 186:707f6e361f3e 145 bool callback_posted;
Anna Bridge 186:707f6e361f3e 146 uint8_t active_bank;
Anna Bridge 186:707f6e361f3e 147 nrf_atfifo_t *fifo;
AnnaBridge 189:f392fc9709a3 148 uint32_t fifo_free_count;
AnnaBridge 189:f392fc9709a3 149 nrf_ppi_channel_t ppi_rts;
AnnaBridge 189:f392fc9709a3 150 nrf_drv_gpiote_pin_t rts;
AnnaBridge 189:f392fc9709a3 151 bool rx_suspended;
Anna Bridge 186:707f6e361f3e 152 } nordic_uart_state_t;
Anna Bridge 186:707f6e361f3e 153
Anna Bridge 186:707f6e361f3e 154 /**
Anna Bridge 186:707f6e361f3e 155 * Turn Mbed HAL IRQ flags into maskable bit masks.
Anna Bridge 186:707f6e361f3e 156 */
Anna Bridge 186:707f6e361f3e 157 typedef enum {
Anna Bridge 186:707f6e361f3e 158 NORDIC_TX_IRQ = (1 << 0),
Anna Bridge 186:707f6e361f3e 159 NORDIC_RX_IRQ = (1 << 1),
Anna Bridge 186:707f6e361f3e 160 } nordic_irq_t;
Anna Bridge 186:707f6e361f3e 161
Anna Bridge 186:707f6e361f3e 162
Anna Bridge 186:707f6e361f3e 163 /***
AnnaBridge 187:0387e8f68319 164 * _____ _ _ _ __ __ _ _ _
AnnaBridge 187:0387e8f68319 165 * / ____| | | | | | \ \ / / (_) | | | |
AnnaBridge 187:0387e8f68319 166 * | | __| | ___ | |__ __ _| | \ \ / /_ _ _ __ _ __ _| |__ | | ___ ___
Anna Bridge 186:707f6e361f3e 167 * | | |_ | |/ _ \| '_ \ / _` | | \ \/ / _` | '__| |/ _` | '_ \| |/ _ \/ __|
Anna Bridge 186:707f6e361f3e 168 * | |__| | | (_) | |_) | (_| | | \ / (_| | | | | (_| | |_) | | __/\__ \
Anna Bridge 186:707f6e361f3e 169 * \_____|_|\___/|_.__/ \__,_|_| \/ \__,_|_| |_|\__,_|_.__/|_|\___||___/
AnnaBridge 187:0387e8f68319 170 *
AnnaBridge 187:0387e8f68319 171 *
Anna Bridge 186:707f6e361f3e 172 */
Anna Bridge 186:707f6e361f3e 173
Anna Bridge 186:707f6e361f3e 174 /**
Anna Bridge 186:707f6e361f3e 175 * UARTE state. One for each instance.
Anna Bridge 186:707f6e361f3e 176 */
Anna Bridge 186:707f6e361f3e 177 static nordic_uart_state_t nordic_nrf5_uart_state[UART_ENABLED_COUNT] = { 0 };
Anna Bridge 186:707f6e361f3e 178
Anna Bridge 186:707f6e361f3e 179 /**
Anna Bridge 186:707f6e361f3e 180 * Array with UARTE register pointers for easy access.
Anna Bridge 186:707f6e361f3e 181 */
Anna Bridge 186:707f6e361f3e 182 static NRF_UARTE_Type *nordic_nrf5_uart_register[UART_ENABLED_COUNT] = {
Anna Bridge 186:707f6e361f3e 183 NRF_UARTE0,
Anna Bridge 186:707f6e361f3e 184 #if UART1_ENABLED
Anna Bridge 186:707f6e361f3e 185 NRF_UARTE1,
Anna Bridge 186:707f6e361f3e 186 #endif
Anna Bridge 186:707f6e361f3e 187 };
Anna Bridge 186:707f6e361f3e 188
Anna Bridge 186:707f6e361f3e 189 /**
AnnaBridge 187:0387e8f68319 190 * @brief Create atomic fifo using macro. Macro defines static arrays
Anna Bridge 186:707f6e361f3e 191 * for buffer and internal state.
Anna Bridge 186:707f6e361f3e 192 */
Anna Bridge 186:707f6e361f3e 193 NRF_ATFIFO_DEF(nordic_nrf5_uart_fifo_0, uint8_t, UART0_FIFO_BUFFER_SIZE);
Anna Bridge 186:707f6e361f3e 194
Anna Bridge 186:707f6e361f3e 195 #if UART1_ENABLED
Anna Bridge 186:707f6e361f3e 196 NRF_ATFIFO_DEF(nordic_nrf5_uart_fifo_1, uint8_t, UART1_FIFO_BUFFER_SIZE);
Anna Bridge 186:707f6e361f3e 197 #endif
Anna Bridge 186:707f6e361f3e 198
Anna Bridge 186:707f6e361f3e 199 /**
AnnaBridge 187:0387e8f68319 200 * SWI IRQ mask.
AnnaBridge 187:0387e8f68319 201 */
AnnaBridge 187:0387e8f68319 202 static uint8_t nordic_nrf5_uart_swi_mask_tx_0 = 0;
AnnaBridge 187:0387e8f68319 203 static uint8_t nordic_nrf5_uart_swi_mask_rx_0 = 0;
AnnaBridge 187:0387e8f68319 204 static uint8_t nordic_nrf5_uart_swi_mask_tx_1 = 0;
AnnaBridge 187:0387e8f68319 205 static uint8_t nordic_nrf5_uart_swi_mask_rx_1 = 0;
AnnaBridge 187:0387e8f68319 206
AnnaBridge 187:0387e8f68319 207 /**
Anna Bridge 186:707f6e361f3e 208 * Global variables expected by mbed_retarget.cpp for STDOUT.
Anna Bridge 186:707f6e361f3e 209 */
Anna Bridge 186:707f6e361f3e 210 int stdio_uart_inited = 0;
Anna Bridge 186:707f6e361f3e 211 serial_t stdio_uart = { 0 };
Anna Bridge 186:707f6e361f3e 212
Anna Bridge 186:707f6e361f3e 213
Anna Bridge 186:707f6e361f3e 214 /***
AnnaBridge 187:0387e8f68319 215 * _____ __ _ _____ _ _
AnnaBridge 187:0387e8f68319 216 * / ____| / _| | |_ _| | | | |
AnnaBridge 187:0387e8f68319 217 * | (___ ___ | |_| |___ ____ _ _ __ ___ | | _ __ | |_ ___ _ __ _ __ _ _ _ __ | |_
AnnaBridge 187:0387e8f68319 218 * \___ \ / _ \| _| __\ \ /\ / / _` | '__/ _ \ | | | '_ \| __/ _ \ '__| '__| | | | '_ \| __|
AnnaBridge 187:0387e8f68319 219 * ____) | (_) | | | |_ \ V V / (_| | | | __/ _| |_| | | | || __/ | | | | |_| | |_) | |_
AnnaBridge 187:0387e8f68319 220 * |_____/ \___/|_| \__| \_/\_/ \__,_|_| \___| |_____|_| |_|\__\___|_| |_| \__,_| .__/ \__|
AnnaBridge 187:0387e8f68319 221 * | |
AnnaBridge 187:0387e8f68319 222 * |_|
AnnaBridge 187:0387e8f68319 223 */
AnnaBridge 187:0387e8f68319 224
AnnaBridge 187:0387e8f68319 225 /**
AnnaBridge 187:0387e8f68319 226 * @brief SWI interrupt handler for signaling RxIrq handler.
Anna Bridge 186:707f6e361f3e 227 *
Anna Bridge 186:707f6e361f3e 228 * @param[in] instance The instance
Anna Bridge 186:707f6e361f3e 229 */
Anna Bridge 186:707f6e361f3e 230 static void nordic_nrf5_uart_callback_handler(uint32_t instance)
Anna Bridge 186:707f6e361f3e 231 {
Anna Bridge 186:707f6e361f3e 232 /* Flag that no callback is posted. */
Anna Bridge 186:707f6e361f3e 233 nordic_nrf5_uart_state[instance].callback_posted = false;
Anna Bridge 186:707f6e361f3e 234
Anna Bridge 186:707f6e361f3e 235 /* Check if callback handler is set and if event mask match. */
Anna Bridge 186:707f6e361f3e 236 uart_irq_handler callback = (uart_irq_handler) nordic_nrf5_uart_state[instance].owner->handler;
Anna Bridge 186:707f6e361f3e 237 uint32_t mask = nordic_nrf5_uart_state[instance].owner->mask;
Anna Bridge 186:707f6e361f3e 238
Anna Bridge 186:707f6e361f3e 239 if (callback && (mask & NORDIC_RX_IRQ)) {
Anna Bridge 186:707f6e361f3e 240
Anna Bridge 186:707f6e361f3e 241 /* Invoke callback function. */
Anna Bridge 186:707f6e361f3e 242 uint32_t context = nordic_nrf5_uart_state[instance].owner->context;
Anna Bridge 186:707f6e361f3e 243 callback(context, RxIrq);
Anna Bridge 186:707f6e361f3e 244 }
Anna Bridge 186:707f6e361f3e 245 }
Anna Bridge 186:707f6e361f3e 246
Anna Bridge 186:707f6e361f3e 247 /**
AnnaBridge 187:0387e8f68319 248 * @brief SWI interrupt handler for when the Tx buffer has been transmitted.
AnnaBridge 187:0387e8f68319 249 *
AnnaBridge 187:0387e8f68319 250 * @param[in] instance The instance
Anna Bridge 186:707f6e361f3e 251 */
AnnaBridge 187:0387e8f68319 252 static void nordic_nrf5_uart_event_handler_endtx(int instance)
Anna Bridge 186:707f6e361f3e 253 {
AnnaBridge 187:0387e8f68319 254 /* Release mutex. As the owner this call is safe. */
AnnaBridge 187:0387e8f68319 255 nordic_nrf5_uart_state[instance].tx_in_progress = 0;
AnnaBridge 187:0387e8f68319 256
AnnaBridge 187:0387e8f68319 257 /* Check if callback handler and Tx event mask is set. */
AnnaBridge 187:0387e8f68319 258 uart_irq_handler callback = (uart_irq_handler) nordic_nrf5_uart_state[instance].owner->handler;
AnnaBridge 187:0387e8f68319 259 uint32_t mask = nordic_nrf5_uart_state[instance].owner->mask;
AnnaBridge 187:0387e8f68319 260
AnnaBridge 187:0387e8f68319 261 if (callback && (mask & NORDIC_TX_IRQ)) {
AnnaBridge 187:0387e8f68319 262
AnnaBridge 187:0387e8f68319 263 /* Invoke callback function. */
AnnaBridge 187:0387e8f68319 264 uint32_t context = nordic_nrf5_uart_state[instance].owner->context;
AnnaBridge 187:0387e8f68319 265 callback(context, TxIrq);
AnnaBridge 187:0387e8f68319 266 }
AnnaBridge 187:0387e8f68319 267 }
AnnaBridge 187:0387e8f68319 268
AnnaBridge 187:0387e8f68319 269 /**
AnnaBridge 187:0387e8f68319 270 * @brief Asynchronous event handler for when Tx DMA buffer has been sent.
AnnaBridge 187:0387e8f68319 271 *
AnnaBridge 187:0387e8f68319 272 * @param[in] instance The instance
AnnaBridge 187:0387e8f68319 273 */
AnnaBridge 187:0387e8f68319 274 #if DEVICE_SERIAL_ASYNCH
AnnaBridge 187:0387e8f68319 275 static void nordic_nrf5_uart_event_handler_endtx_asynch(int instance)
AnnaBridge 187:0387e8f68319 276 {
AnnaBridge 187:0387e8f68319 277 /* Set Tx done and reset Tx mode to be not asynchronous. */
AnnaBridge 187:0387e8f68319 278 nordic_nrf5_uart_state[instance].tx_in_progress = 0;
AnnaBridge 187:0387e8f68319 279 nordic_nrf5_uart_state[instance].tx_asynch = false;
AnnaBridge 187:0387e8f68319 280
AnnaBridge 187:0387e8f68319 281 /* Cast handler to callback function pointer. */
AnnaBridge 187:0387e8f68319 282 void (*callback)(void) = (void (*)(void)) nordic_nrf5_uart_state[instance].owner->tx_handler;
AnnaBridge 187:0387e8f68319 283 uint32_t mask = nordic_nrf5_uart_state[instance].owner->tx_mask;
AnnaBridge 187:0387e8f68319 284
AnnaBridge 187:0387e8f68319 285 /* Signal error if event mask matches and event handler is set. */
AnnaBridge 187:0387e8f68319 286 if (callback && (mask & SERIAL_EVENT_TX_COMPLETE)) {
AnnaBridge 187:0387e8f68319 287
AnnaBridge 187:0387e8f68319 288 /* Store event value so it can be read back. */
AnnaBridge 187:0387e8f68319 289 nordic_nrf5_uart_state[instance].owner->tx_event = SERIAL_EVENT_TX_COMPLETE;
Anna Bridge 186:707f6e361f3e 290
AnnaBridge 187:0387e8f68319 291 /* Signal callback handler. */
AnnaBridge 187:0387e8f68319 292 callback();
AnnaBridge 187:0387e8f68319 293 }
AnnaBridge 187:0387e8f68319 294 }
AnnaBridge 187:0387e8f68319 295 #endif
AnnaBridge 187:0387e8f68319 296
AnnaBridge 187:0387e8f68319 297 static void nordic_nrf5_uart_swi0(void)
AnnaBridge 187:0387e8f68319 298 {
AnnaBridge 187:0387e8f68319 299 if (nordic_nrf5_uart_swi_mask_tx_0) {
Anna Bridge 186:707f6e361f3e 300
AnnaBridge 187:0387e8f68319 301 nordic_nrf5_uart_swi_mask_tx_0 = 0;
AnnaBridge 187:0387e8f68319 302
AnnaBridge 187:0387e8f68319 303 #if DEVICE_SERIAL_ASYNCH
AnnaBridge 187:0387e8f68319 304 if (nordic_nrf5_uart_state[0].tx_asynch) {
AnnaBridge 187:0387e8f68319 305
AnnaBridge 187:0387e8f68319 306 nordic_nrf5_uart_event_handler_endtx_asynch(0);
AnnaBridge 187:0387e8f68319 307 } else
AnnaBridge 187:0387e8f68319 308 #endif
AnnaBridge 187:0387e8f68319 309 {
AnnaBridge 187:0387e8f68319 310 nordic_nrf5_uart_event_handler_endtx(0);
AnnaBridge 187:0387e8f68319 311 }
Anna Bridge 186:707f6e361f3e 312 }
Anna Bridge 186:707f6e361f3e 313
AnnaBridge 187:0387e8f68319 314 if (nordic_nrf5_uart_swi_mask_rx_0) {
Anna Bridge 186:707f6e361f3e 315
AnnaBridge 187:0387e8f68319 316 nordic_nrf5_uart_swi_mask_rx_0 = 0;
Anna Bridge 186:707f6e361f3e 317
Anna Bridge 186:707f6e361f3e 318 nordic_nrf5_uart_callback_handler(0);
Anna Bridge 186:707f6e361f3e 319 }
Anna Bridge 186:707f6e361f3e 320
AnnaBridge 187:0387e8f68319 321
Anna Bridge 186:707f6e361f3e 322 #if UART1_ENABLED
AnnaBridge 187:0387e8f68319 323 if (nordic_nrf5_uart_swi_mask_tx_1) {
AnnaBridge 187:0387e8f68319 324
AnnaBridge 187:0387e8f68319 325 nordic_nrf5_uart_swi_mask_tx_1 = 0;
Anna Bridge 186:707f6e361f3e 326
AnnaBridge 187:0387e8f68319 327 #if DEVICE_SERIAL_ASYNCH
AnnaBridge 187:0387e8f68319 328 if (nordic_nrf5_uart_state[1].tx_asynch) {
Anna Bridge 186:707f6e361f3e 329
AnnaBridge 187:0387e8f68319 330 nordic_nrf5_uart_event_handler_endtx_asynch(1);
AnnaBridge 187:0387e8f68319 331 } else
AnnaBridge 187:0387e8f68319 332 #endif
AnnaBridge 187:0387e8f68319 333 {
AnnaBridge 187:0387e8f68319 334 nordic_nrf5_uart_event_handler_endtx(1);
AnnaBridge 187:0387e8f68319 335 }
Anna Bridge 186:707f6e361f3e 336 }
Anna Bridge 186:707f6e361f3e 337
AnnaBridge 187:0387e8f68319 338 if (nordic_nrf5_uart_swi_mask_rx_1) {
Anna Bridge 186:707f6e361f3e 339
AnnaBridge 187:0387e8f68319 340 nordic_nrf5_uart_swi_mask_rx_1 = 0;
Anna Bridge 186:707f6e361f3e 341
Anna Bridge 186:707f6e361f3e 342 nordic_nrf5_uart_callback_handler(1);
Anna Bridge 186:707f6e361f3e 343 }
Anna Bridge 186:707f6e361f3e 344 #endif
Anna Bridge 186:707f6e361f3e 345 }
Anna Bridge 186:707f6e361f3e 346
AnnaBridge 187:0387e8f68319 347 /**
AnnaBridge 187:0387e8f68319 348 * @brief Trigger Tx SWI.
AnnaBridge 187:0387e8f68319 349 *
AnnaBridge 187:0387e8f68319 350 * @param[in] instance The instance.
AnnaBridge 187:0387e8f68319 351 */
AnnaBridge 187:0387e8f68319 352 static void nordic_swi_tx_trigger(int instance)
AnnaBridge 187:0387e8f68319 353 {
AnnaBridge 187:0387e8f68319 354 if (instance == 0) {
AnnaBridge 187:0387e8f68319 355
AnnaBridge 187:0387e8f68319 356 nordic_nrf5_uart_swi_mask_tx_0 = 1;
AnnaBridge 187:0387e8f68319 357 NVIC_SetPendingIRQ(SWI0_EGU0_IRQn);
AnnaBridge 187:0387e8f68319 358 }
AnnaBridge 187:0387e8f68319 359 #if UART1_ENABLED
AnnaBridge 187:0387e8f68319 360 else if (instance == 1) {
AnnaBridge 187:0387e8f68319 361
AnnaBridge 187:0387e8f68319 362 nordic_nrf5_uart_swi_mask_tx_1 = 1;
AnnaBridge 187:0387e8f68319 363 NVIC_SetPendingIRQ(SWI0_EGU0_IRQn);
AnnaBridge 187:0387e8f68319 364 }
AnnaBridge 187:0387e8f68319 365 #endif
AnnaBridge 187:0387e8f68319 366 }
AnnaBridge 187:0387e8f68319 367
AnnaBridge 187:0387e8f68319 368 /**
AnnaBridge 187:0387e8f68319 369 * @brief Trigger Rx SWI.
AnnaBridge 187:0387e8f68319 370 *
AnnaBridge 187:0387e8f68319 371 * @param[in] instance The instance
AnnaBridge 187:0387e8f68319 372 */
AnnaBridge 187:0387e8f68319 373 static void nordic_swi_rx_trigger(int instance)
AnnaBridge 187:0387e8f68319 374 {
AnnaBridge 187:0387e8f68319 375 if (instance == 0) {
AnnaBridge 187:0387e8f68319 376
AnnaBridge 187:0387e8f68319 377 nordic_nrf5_uart_swi_mask_rx_0 = 1;
AnnaBridge 187:0387e8f68319 378 NVIC_SetPendingIRQ(SWI0_EGU0_IRQn);
AnnaBridge 187:0387e8f68319 379 }
AnnaBridge 187:0387e8f68319 380 #if UART1_ENABLED
AnnaBridge 187:0387e8f68319 381 else if (instance == 1) {
AnnaBridge 187:0387e8f68319 382
AnnaBridge 187:0387e8f68319 383 nordic_nrf5_uart_swi_mask_rx_1 = 1;
AnnaBridge 187:0387e8f68319 384 NVIC_SetPendingIRQ(SWI0_EGU0_IRQn);
AnnaBridge 187:0387e8f68319 385 }
AnnaBridge 187:0387e8f68319 386 #endif
AnnaBridge 187:0387e8f68319 387 }
Anna Bridge 186:707f6e361f3e 388
Anna Bridge 186:707f6e361f3e 389 /***
AnnaBridge 187:0387e8f68319 390 * _ _ _____ _______ ______ _ _ _ _ _
AnnaBridge 187:0387e8f68319 391 * | | | | /\ | __ \__ __| | ____| | | | | | | | | |
AnnaBridge 187:0387e8f68319 392 * | | | | / \ | |__) | | | | |____ _____ _ __ | |_ | |__| | __ _ _ __ __| | | ___ _ __
Anna Bridge 186:707f6e361f3e 393 * | | | |/ /\ \ | _ / | | | __\ \ / / _ \ '_ \| __| | __ |/ _` | '_ \ / _` | |/ _ \ '__|
AnnaBridge 187:0387e8f68319 394 * | |__| / ____ \| | \ \ | | | |___\ V / __/ | | | |_ | | | | (_| | | | | (_| | | __/ |
AnnaBridge 187:0387e8f68319 395 * \____/_/ \_\_| \_\ |_| |______\_/ \___|_| |_|\__| |_| |_|\__,_|_| |_|\__,_|_|\___|_|
AnnaBridge 187:0387e8f68319 396 *
AnnaBridge 187:0387e8f68319 397 *
Anna Bridge 186:707f6e361f3e 398 */
Anna Bridge 186:707f6e361f3e 399
Anna Bridge 186:707f6e361f3e 400 /**
AnnaBridge 187:0387e8f68319 401 * @brief Event handler for when Rx buffer is full or buffer swap has been
Anna Bridge 186:707f6e361f3e 402 * triggered by idle task.
AnnaBridge 187:0387e8f68319 403 *
AnnaBridge 187:0387e8f68319 404 * Copy data from DMA buffer to FIFO buffer.
Anna Bridge 186:707f6e361f3e 405 * Post callback if not already posted.
Anna Bridge 186:707f6e361f3e 406 *
Anna Bridge 186:707f6e361f3e 407 * @param[in] instance The instance
Anna Bridge 186:707f6e361f3e 408 */
Anna Bridge 186:707f6e361f3e 409 static void nordic_nrf5_uart_event_handler_endrx(int instance)
Anna Bridge 186:707f6e361f3e 410 {
Anna Bridge 186:707f6e361f3e 411 /* Read out active bank flag and swap DMA buffers. */
Anna Bridge 186:707f6e361f3e 412 uint8_t active_bank = nordic_nrf5_uart_state[instance].active_bank;
Anna Bridge 186:707f6e361f3e 413 nordic_nrf5_uart_state[instance].active_bank = active_bank ^ 0x01;
Anna Bridge 186:707f6e361f3e 414
Anna Bridge 186:707f6e361f3e 415 /* Get number of bytes in DMA buffer. */
Anna Bridge 186:707f6e361f3e 416 uint32_t available = nrf_uarte_rx_amount_get(nordic_nrf5_uart_register[instance]);
Anna Bridge 186:707f6e361f3e 417
Anna Bridge 186:707f6e361f3e 418 if (available > 0) {
Anna Bridge 186:707f6e361f3e 419
Anna Bridge 186:707f6e361f3e 420 /* Copy data from DMA buffer to FIFO buffer. */
Anna Bridge 186:707f6e361f3e 421 for (size_t index = 0; index < available; index++) {
Anna Bridge 186:707f6e361f3e 422
Anna Bridge 186:707f6e361f3e 423 /* Atomic FIFO can be used safely without disabling interrutps. */
Anna Bridge 186:707f6e361f3e 424 nrf_atfifo_item_put_t fifo_context;
Anna Bridge 186:707f6e361f3e 425
Anna Bridge 186:707f6e361f3e 426 /* Get pointer to available space. */
Anna Bridge 186:707f6e361f3e 427 uint8_t *byte = (uint8_t *) nrf_atfifo_item_alloc(nordic_nrf5_uart_state[instance].fifo, &fifo_context);
Anna Bridge 186:707f6e361f3e 428
Anna Bridge 186:707f6e361f3e 429 if (byte != NULL) {
Anna Bridge 186:707f6e361f3e 430
Anna Bridge 186:707f6e361f3e 431 /* Copy 1 byte from DMA buffer and commit to FIFO buffer. */
Anna Bridge 186:707f6e361f3e 432 *byte = nordic_nrf5_uart_state[instance].buffer[active_bank][index];
Anna Bridge 186:707f6e361f3e 433 nrf_atfifo_item_put(nordic_nrf5_uart_state[instance].fifo, &fifo_context);
AnnaBridge 189:f392fc9709a3 434 core_util_atomic_decr_u32(&nordic_nrf5_uart_state[instance].fifo_free_count, 1);
Anna Bridge 186:707f6e361f3e 435
Anna Bridge 186:707f6e361f3e 436 } else {
Anna Bridge 186:707f6e361f3e 437
Anna Bridge 186:707f6e361f3e 438 /* Buffer overflow. */
Anna Bridge 186:707f6e361f3e 439 break;
Anna Bridge 186:707f6e361f3e 440 }
Anna Bridge 186:707f6e361f3e 441 }
Anna Bridge 186:707f6e361f3e 442
AnnaBridge 187:0387e8f68319 443 /* Signal callback through lower priority SWI if not already posted. */
Anna Bridge 186:707f6e361f3e 444 if (nordic_nrf5_uart_state[instance].callback_posted == false) {
Anna Bridge 186:707f6e361f3e 445
Anna Bridge 186:707f6e361f3e 446 nordic_nrf5_uart_state[instance].callback_posted = true;
AnnaBridge 187:0387e8f68319 447 nordic_swi_rx_trigger(instance);
Anna Bridge 186:707f6e361f3e 448 }
AnnaBridge 187:0387e8f68319 449 }
Anna Bridge 186:707f6e361f3e 450 }
Anna Bridge 186:707f6e361f3e 451
Anna Bridge 186:707f6e361f3e 452 /**
Anna Bridge 186:707f6e361f3e 453 * @brief Event handler for when DMA has been armed with Rx buffer.
AnnaBridge 187:0387e8f68319 454 *
AnnaBridge 187:0387e8f68319 455 * Arm Rx buffer with second buffer for optimal reception.
Anna Bridge 186:707f6e361f3e 456 *
Anna Bridge 186:707f6e361f3e 457 * @param[in] instance The instance
Anna Bridge 186:707f6e361f3e 458 */
Anna Bridge 186:707f6e361f3e 459 static void nordic_nrf5_uart_event_handler_rxstarted(int instance)
Anna Bridge 186:707f6e361f3e 460 {
Anna Bridge 186:707f6e361f3e 461 uint8_t next_bank = nordic_nrf5_uart_state[instance].active_bank ^ 0x01;
Anna Bridge 186:707f6e361f3e 462
AnnaBridge 187:0387e8f68319 463 nrf_uarte_rx_buffer_set(nordic_nrf5_uart_register[instance], nordic_nrf5_uart_state[instance].buffer[next_bank], DMA_BUFFER_SIZE);
AnnaBridge 189:f392fc9709a3 464 if (nordic_nrf5_uart_state[instance].rts != NRF_UART_PSEL_DISCONNECTED) {
AnnaBridge 189:f392fc9709a3 465 if (nordic_nrf5_uart_state[instance].fifo_free_count > FIFO_MIN) {
AnnaBridge 189:f392fc9709a3 466 /* Clear rts since we are ready to receive the next byte */
AnnaBridge 189:f392fc9709a3 467 nrf_drv_gpiote_clr_task_trigger(nordic_nrf5_uart_state[instance].rts);
AnnaBridge 189:f392fc9709a3 468 } else {
AnnaBridge 189:f392fc9709a3 469 /* Suspend reception since there isn't enough buffer space.
AnnaBridge 189:f392fc9709a3 470 * The function serial_getc will restart reception. */
AnnaBridge 189:f392fc9709a3 471 nordic_nrf5_uart_state[instance].rx_suspended = true;
AnnaBridge 189:f392fc9709a3 472 }
Anna Bridge 186:707f6e361f3e 473 }
Anna Bridge 186:707f6e361f3e 474 }
Anna Bridge 186:707f6e361f3e 475
Anna Bridge 186:707f6e361f3e 476 #if DEVICE_SERIAL_ASYNCH
Anna Bridge 186:707f6e361f3e 477 /**
AnnaBridge 187:0387e8f68319 478 * @brief Asynchronous event handler for when Rx DMA buffer is full.
Anna Bridge 186:707f6e361f3e 479 *
Anna Bridge 186:707f6e361f3e 480 * @param[in] instance The instance
Anna Bridge 186:707f6e361f3e 481 */
Anna Bridge 186:707f6e361f3e 482 static void nordic_nrf5_uart_event_handler_endrx_asynch(int instance)
Anna Bridge 186:707f6e361f3e 483 {
Anna Bridge 186:707f6e361f3e 484 /* Set Rx done and reset Rx mode to be not asynchronous. */
Anna Bridge 186:707f6e361f3e 485 nordic_nrf5_uart_state[instance].rx_in_progress = 0;
Anna Bridge 186:707f6e361f3e 486 nordic_nrf5_uart_state[instance].rx_asynch = false;
Anna Bridge 186:707f6e361f3e 487
Anna Bridge 186:707f6e361f3e 488 /* Cast handler to callback function pointer. */
Anna Bridge 186:707f6e361f3e 489 void (*callback)(void) = (void (*)(void)) nordic_nrf5_uart_state[instance].owner->rx_handler;
Anna Bridge 186:707f6e361f3e 490 uint32_t mask = nordic_nrf5_uart_state[instance].owner->rx_mask;
Anna Bridge 186:707f6e361f3e 491
Anna Bridge 186:707f6e361f3e 492 /* Signal error if event mask matches and event handler is set. */
Anna Bridge 186:707f6e361f3e 493 if (callback && (mask & SERIAL_EVENT_RX_COMPLETE)) {
Anna Bridge 186:707f6e361f3e 494
Anna Bridge 186:707f6e361f3e 495 /* Store event value so it can be read back. */
Anna Bridge 186:707f6e361f3e 496 nordic_nrf5_uart_state[instance].owner->rx_event = SERIAL_EVENT_RX_COMPLETE;
Anna Bridge 186:707f6e361f3e 497
Anna Bridge 186:707f6e361f3e 498 /* Signal callback handler. */
Anna Bridge 186:707f6e361f3e 499 callback();
Anna Bridge 186:707f6e361f3e 500 }
Anna Bridge 186:707f6e361f3e 501 }
Anna Bridge 186:707f6e361f3e 502 #endif
Anna Bridge 186:707f6e361f3e 503
Anna Bridge 186:707f6e361f3e 504 /**
AnnaBridge 187:0387e8f68319 505 * @brief UARTE event handler.
AnnaBridge 187:0387e8f68319 506 *
Anna Bridge 186:707f6e361f3e 507 * Collect signals from UARTE0 and UARTE1 ISR and translate to instance.
Anna Bridge 186:707f6e361f3e 508 *
Anna Bridge 186:707f6e361f3e 509 * @param[in] instance The instance
Anna Bridge 186:707f6e361f3e 510 */
Anna Bridge 186:707f6e361f3e 511 static void nordic_nrf5_uart_event_handler(int instance)
Anna Bridge 186:707f6e361f3e 512 {
Anna Bridge 186:707f6e361f3e 513 /* DMA buffer is full or has been swapped out by idle timeout. */
Anna Bridge 186:707f6e361f3e 514 if (nrf_uarte_event_check(nordic_nrf5_uart_register[instance], NRF_UARTE_EVENT_ENDRX))
Anna Bridge 186:707f6e361f3e 515 {
Anna Bridge 186:707f6e361f3e 516 nrf_uarte_event_clear(nordic_nrf5_uart_register[instance], NRF_UARTE_EVENT_ENDRX);
Anna Bridge 186:707f6e361f3e 517
Anna Bridge 186:707f6e361f3e 518 #if DEVICE_SERIAL_ASYNCH
Anna Bridge 186:707f6e361f3e 519 /* Call appropriate event handler based on current mode. */
Anna Bridge 186:707f6e361f3e 520 if (nordic_nrf5_uart_state[instance].rx_asynch) {
Anna Bridge 186:707f6e361f3e 521
Anna Bridge 186:707f6e361f3e 522 nordic_nrf5_uart_event_handler_endrx_asynch(instance);
AnnaBridge 187:0387e8f68319 523 } else
AnnaBridge 187:0387e8f68319 524 #endif
Anna Bridge 186:707f6e361f3e 525 {
Anna Bridge 186:707f6e361f3e 526 nordic_nrf5_uart_event_handler_endrx(instance);
Anna Bridge 186:707f6e361f3e 527 }
Anna Bridge 186:707f6e361f3e 528 }
Anna Bridge 186:707f6e361f3e 529
AnnaBridge 189:f392fc9709a3 530 /* Rx DMA buffer has been armed.
AnnaBridge 189:f392fc9709a3 531 *
AnnaBridge 189:f392fc9709a3 532 * Warning - Do not process NRF_UARTE_EVENT_RXSTARTED if NRF_UARTE_EVENT_ENDRX is pending.
AnnaBridge 189:f392fc9709a3 533 * NRF_UARTE_EVENT_RXSTARTED must be processed first or nordic_nrf5_uart_event_handler_rxstarted
AnnaBridge 189:f392fc9709a3 534 * will setup the wrong DMA buffer and cause data to be lost.
AnnaBridge 189:f392fc9709a3 535 */
AnnaBridge 189:f392fc9709a3 536 if (nrf_uarte_event_check(nordic_nrf5_uart_register[instance], NRF_UARTE_EVENT_RXSTARTED) &&
AnnaBridge 189:f392fc9709a3 537 !nrf_uarte_event_check(nordic_nrf5_uart_register[instance], NRF_UARTE_EVENT_ENDRX))
Anna Bridge 186:707f6e361f3e 538 {
Anna Bridge 186:707f6e361f3e 539 nrf_uarte_event_clear(nordic_nrf5_uart_register[instance], NRF_UARTE_EVENT_RXSTARTED);
Anna Bridge 186:707f6e361f3e 540
Anna Bridge 186:707f6e361f3e 541 nordic_nrf5_uart_event_handler_rxstarted(instance);
Anna Bridge 186:707f6e361f3e 542 }
Anna Bridge 186:707f6e361f3e 543
Anna Bridge 186:707f6e361f3e 544 /* Tx DMA buffer has been sent. */
Anna Bridge 186:707f6e361f3e 545 if (nrf_uarte_event_check(nordic_nrf5_uart_register[instance], NRF_UARTE_EVENT_ENDTX))
Anna Bridge 186:707f6e361f3e 546 {
AnnaBridge 187:0387e8f68319 547 nrf_uarte_event_clear(nordic_nrf5_uart_register[instance], NRF_UARTE_EVENT_ENDTX);
Anna Bridge 186:707f6e361f3e 548
AnnaBridge 187:0387e8f68319 549 /* Use SWI to de-prioritize callback. */
AnnaBridge 187:0387e8f68319 550 nordic_swi_tx_trigger(instance);
Anna Bridge 186:707f6e361f3e 551 }
Anna Bridge 186:707f6e361f3e 552 }
Anna Bridge 186:707f6e361f3e 553
Anna Bridge 186:707f6e361f3e 554 /**
Anna Bridge 186:707f6e361f3e 555 * @brief UARTE0 ISR.
Anna Bridge 186:707f6e361f3e 556 */
Anna Bridge 186:707f6e361f3e 557 static void nordic_nrf5_uart0_handler(void)
Anna Bridge 186:707f6e361f3e 558 {
Anna Bridge 186:707f6e361f3e 559 /* Call event handler with instance ID. */
Anna Bridge 186:707f6e361f3e 560 nordic_nrf5_uart_event_handler(0);
Anna Bridge 186:707f6e361f3e 561 }
Anna Bridge 186:707f6e361f3e 562
Anna Bridge 186:707f6e361f3e 563 #if UART1_ENABLED
Anna Bridge 186:707f6e361f3e 564 /**
Anna Bridge 186:707f6e361f3e 565 * @brief UARTE1 ISR.
Anna Bridge 186:707f6e361f3e 566 */
Anna Bridge 186:707f6e361f3e 567 static void nordic_nrf5_uart1_handler(void)
Anna Bridge 186:707f6e361f3e 568 {
Anna Bridge 186:707f6e361f3e 569 /* Call event handler with instance ID. */
Anna Bridge 186:707f6e361f3e 570 nordic_nrf5_uart_event_handler(1);
Anna Bridge 186:707f6e361f3e 571 }
Anna Bridge 186:707f6e361f3e 572 #endif
Anna Bridge 186:707f6e361f3e 573
Anna Bridge 186:707f6e361f3e 574
Anna Bridge 186:707f6e361f3e 575 /***
AnnaBridge 187:0387e8f68319 576 * _____ __ _ _ _
AnnaBridge 187:0387e8f68319 577 * / ____| / _(_) | | (_)
AnnaBridge 187:0387e8f68319 578 * | | ___ _ __ | |_ _ __ _ _ _ _ __ __ _| |_ _ ___ _ __
AnnaBridge 187:0387e8f68319 579 * | | / _ \| '_ \| _| |/ _` | | | | '__/ _` | __| |/ _ \| '_ \
Anna Bridge 186:707f6e361f3e 580 * | |___| (_) | | | | | | | (_| | |_| | | | (_| | |_| | (_) | | | |
Anna Bridge 186:707f6e361f3e 581 * \_____\___/|_| |_|_| |_|\__, |\__,_|_| \__,_|\__|_|\___/|_| |_|
AnnaBridge 187:0387e8f68319 582 * __/ |
AnnaBridge 187:0387e8f68319 583 * |___/
Anna Bridge 186:707f6e361f3e 584 */
Anna Bridge 186:707f6e361f3e 585
Anna Bridge 186:707f6e361f3e 586 /**
AnnaBridge 187:0387e8f68319 587 * @brief Configure UARTE based on serial object settings.
Anna Bridge 186:707f6e361f3e 588 *
Anna Bridge 186:707f6e361f3e 589 * Common for both Rx and Tx.
Anna Bridge 186:707f6e361f3e 590 *
Anna Bridge 186:707f6e361f3e 591 * @param obj The object
Anna Bridge 186:707f6e361f3e 592 */
Anna Bridge 186:707f6e361f3e 593 static void nordic_nrf5_uart_configure_object(serial_t *obj)
Anna Bridge 186:707f6e361f3e 594 {
Anna Bridge 186:707f6e361f3e 595 MBED_ASSERT(obj);
Anna Bridge 186:707f6e361f3e 596
Anna Bridge 186:707f6e361f3e 597 #if DEVICE_SERIAL_ASYNCH
Anna Bridge 186:707f6e361f3e 598 struct serial_s *uart_object = &obj->serial;
Anna Bridge 186:707f6e361f3e 599 #else
Anna Bridge 186:707f6e361f3e 600 struct serial_s *uart_object = obj;
Anna Bridge 186:707f6e361f3e 601 #endif
Anna Bridge 186:707f6e361f3e 602
Anna Bridge 186:707f6e361f3e 603 /* Configure Tx and Rx pins. */
AnnaBridge 187:0387e8f68319 604 if (uart_object->tx != NRF_UART_PSEL_DISCONNECTED) {
AnnaBridge 187:0387e8f68319 605
AnnaBridge 187:0387e8f68319 606 nrf_gpio_pin_set(uart_object->tx);
AnnaBridge 187:0387e8f68319 607 nrf_gpio_cfg_output(uart_object->tx);
AnnaBridge 187:0387e8f68319 608 }
AnnaBridge 187:0387e8f68319 609
AnnaBridge 187:0387e8f68319 610 if (uart_object->rx != NRF_UART_PSEL_DISCONNECTED) {
AnnaBridge 187:0387e8f68319 611
AnnaBridge 187:0387e8f68319 612 nrf_gpio_cfg_input(uart_object->rx, NRF_GPIO_PIN_NOPULL);
AnnaBridge 187:0387e8f68319 613 }
Anna Bridge 186:707f6e361f3e 614
Anna Bridge 186:707f6e361f3e 615 nrf_uarte_txrx_pins_set(nordic_nrf5_uart_register[uart_object->instance],
Anna Bridge 186:707f6e361f3e 616 uart_object->tx,
Anna Bridge 186:707f6e361f3e 617 uart_object->rx);
Anna Bridge 186:707f6e361f3e 618
Anna Bridge 186:707f6e361f3e 619 /* Set hardware flow control pins. */
Anna Bridge 186:707f6e361f3e 620 if (uart_object->hwfc == NRF_UART_HWFC_ENABLED) {
Anna Bridge 186:707f6e361f3e 621
Anna Bridge 186:707f6e361f3e 622 /* Check if pin is set before configuring it. */
Anna Bridge 186:707f6e361f3e 623 if (uart_object->cts != NRF_UART_PSEL_DISCONNECTED) {
Anna Bridge 186:707f6e361f3e 624
Anna Bridge 186:707f6e361f3e 625 nrf_gpio_cfg_input(uart_object->cts, NRF_GPIO_PIN_NOPULL);
Anna Bridge 186:707f6e361f3e 626 }
Anna Bridge 186:707f6e361f3e 627
AnnaBridge 188:bcfe06ba3d64 628 /* Only let UARTE module handle CTS, RTS is handled manually due to buggy UARTE logic. */
Anna Bridge 186:707f6e361f3e 629 nrf_uarte_hwfc_pins_set(nordic_nrf5_uart_register[uart_object->instance],
AnnaBridge 188:bcfe06ba3d64 630 NRF_UART_PSEL_DISCONNECTED,
Anna Bridge 186:707f6e361f3e 631 uart_object->cts);
Anna Bridge 186:707f6e361f3e 632 }
Anna Bridge 186:707f6e361f3e 633
AnnaBridge 189:f392fc9709a3 634 /* Check if the rts pin changed */
AnnaBridge 189:f392fc9709a3 635 if (uart_object->rts != nordic_nrf5_uart_state[uart_object->instance].rts) {
AnnaBridge 189:f392fc9709a3 636 uint32_t ret;
AnnaBridge 189:f392fc9709a3 637
AnnaBridge 189:f392fc9709a3 638 /* Disable the PPI interconnect */
AnnaBridge 189:f392fc9709a3 639 ret = nrf_drv_ppi_channel_disable(nordic_nrf5_uart_state[uart_object->instance].ppi_rts);
AnnaBridge 189:f392fc9709a3 640 MBED_ASSERT(ret == NRF_SUCCESS);
AnnaBridge 189:f392fc9709a3 641
AnnaBridge 189:f392fc9709a3 642 /* Free flow control gpiote pin if it was previously set */
AnnaBridge 189:f392fc9709a3 643 if (nordic_nrf5_uart_state[uart_object->instance].rts != NRF_UART_PSEL_DISCONNECTED) {
AnnaBridge 189:f392fc9709a3 644 nrf_drv_gpiote_out_uninit((nrf_drv_gpiote_pin_t)uart_object->rts);
AnnaBridge 189:f392fc9709a3 645 }
AnnaBridge 189:f392fc9709a3 646
AnnaBridge 189:f392fc9709a3 647 /* Allocate and enable flow control gpiote pin if it is being used */
AnnaBridge 189:f392fc9709a3 648 if (uart_object->rts != NRF_UART_PSEL_DISCONNECTED) {
AnnaBridge 189:f392fc9709a3 649
AnnaBridge 189:f392fc9709a3 650 static const nrf_drv_gpiote_out_config_t config = {
AnnaBridge 189:f392fc9709a3 651 .init_state = NRF_GPIOTE_INITIAL_VALUE_HIGH,
AnnaBridge 189:f392fc9709a3 652 .task_pin = true,
AnnaBridge 189:f392fc9709a3 653 .action = NRF_GPIOTE_POLARITY_LOTOHI
AnnaBridge 189:f392fc9709a3 654 };
AnnaBridge 189:f392fc9709a3 655
AnnaBridge 189:f392fc9709a3 656 /* Allocate gpiote channel */
AnnaBridge 189:f392fc9709a3 657 ret = nrf_drv_gpiote_out_init((nrf_drv_gpiote_pin_t)uart_object->rts, &config);
AnnaBridge 189:f392fc9709a3 658 if (ret == NRF_ERROR_INVALID_STATE) {
AnnaBridge 189:f392fc9709a3 659 /* Pin was previously set to GPIO so uninitialize it */
AnnaBridge 189:f392fc9709a3 660 nrf_drv_gpiote_out_uninit((nrf_drv_gpiote_pin_t)uart_object->rts);
AnnaBridge 189:f392fc9709a3 661 ret = nrf_drv_gpiote_out_init((nrf_drv_gpiote_pin_t)uart_object->rts, &config);
AnnaBridge 189:f392fc9709a3 662 }
AnnaBridge 189:f392fc9709a3 663 MBED_ASSERT(ret == NRF_SUCCESS);
AnnaBridge 189:f392fc9709a3 664
AnnaBridge 189:f392fc9709a3 665 /* Set RTS high on the ENDRX event */
AnnaBridge 189:f392fc9709a3 666 ret = nrf_drv_ppi_channel_assign(nordic_nrf5_uart_state[uart_object->instance].ppi_rts,
AnnaBridge 189:f392fc9709a3 667 nrf_uarte_event_address_get(nordic_nrf5_uart_register[uart_object->instance], NRF_UARTE_EVENT_ENDRX),
AnnaBridge 189:f392fc9709a3 668 nrf_drv_gpiote_out_task_addr_get(uart_object->rts));
AnnaBridge 189:f392fc9709a3 669 MBED_ASSERT(ret == NRF_SUCCESS);
AnnaBridge 189:f392fc9709a3 670
AnnaBridge 189:f392fc9709a3 671 ret = nrf_drv_ppi_channel_enable(nordic_nrf5_uart_state[uart_object->instance].ppi_rts);
AnnaBridge 189:f392fc9709a3 672 MBED_ASSERT(ret == NRF_SUCCESS);
AnnaBridge 189:f392fc9709a3 673
AnnaBridge 189:f392fc9709a3 674 /* Enable gpiote task - rts pin can no longer be used as GPIO at this point */
AnnaBridge 189:f392fc9709a3 675 nrf_drv_gpiote_out_task_enable((nrf_drv_gpiote_pin_t)uart_object->rts);
AnnaBridge 189:f392fc9709a3 676 }
AnnaBridge 189:f392fc9709a3 677
AnnaBridge 189:f392fc9709a3 678 nordic_nrf5_uart_state[uart_object->instance].rts = uart_object->rts;
AnnaBridge 189:f392fc9709a3 679 }
AnnaBridge 189:f392fc9709a3 680
Anna Bridge 186:707f6e361f3e 681 /* Enable flow control and parity. */
Anna Bridge 186:707f6e361f3e 682 nrf_uarte_configure(nordic_nrf5_uart_register[uart_object->instance],
Anna Bridge 186:707f6e361f3e 683 uart_object->parity,
Anna Bridge 186:707f6e361f3e 684 uart_object->hwfc);
Anna Bridge 186:707f6e361f3e 685
Anna Bridge 186:707f6e361f3e 686 /* Set baudrate. */
Anna Bridge 186:707f6e361f3e 687 nrf_uarte_baudrate_set(nordic_nrf5_uart_register[uart_object->instance],
Anna Bridge 186:707f6e361f3e 688 uart_object->baudrate);
Anna Bridge 186:707f6e361f3e 689 }
Anna Bridge 186:707f6e361f3e 690
Anna Bridge 186:707f6e361f3e 691 /**
Anna Bridge 186:707f6e361f3e 692 * @brief Setup non-asynchronous reception.
Anna Bridge 186:707f6e361f3e 693 *
Anna Bridge 186:707f6e361f3e 694 * @param[in] instance The instance
Anna Bridge 186:707f6e361f3e 695 */
Anna Bridge 186:707f6e361f3e 696 static void nordic_nrf5_uart_configure_rx(int instance)
Anna Bridge 186:707f6e361f3e 697 {
Anna Bridge 186:707f6e361f3e 698 /* Disable interrupts during confiration. */
AnnaBridge 187:0387e8f68319 699 nrf_uarte_int_disable(nordic_nrf5_uart_register[instance], NRF_UARTE_INT_RXSTARTED_MASK |
AnnaBridge 189:f392fc9709a3 700 NRF_UARTE_INT_ENDRX_MASK);
Anna Bridge 186:707f6e361f3e 701
Anna Bridge 186:707f6e361f3e 702 /* Clear FIFO buffer. */
Anna Bridge 186:707f6e361f3e 703 nrf_atfifo_clear(nordic_nrf5_uart_state[instance].fifo);
AnnaBridge 189:f392fc9709a3 704 nordic_nrf5_uart_state[instance].fifo_free_count = UART0_FIFO_BUFFER_SIZE;
Anna Bridge 186:707f6e361f3e 705
Anna Bridge 186:707f6e361f3e 706 /* Clear Rx related events. */
Anna Bridge 186:707f6e361f3e 707 nrf_uarte_event_clear(nordic_nrf5_uart_register[instance], NRF_UARTE_EVENT_RXSTARTED);
Anna Bridge 186:707f6e361f3e 708 nrf_uarte_event_clear(nordic_nrf5_uart_register[instance], NRF_UARTE_EVENT_ENDRX);
Anna Bridge 186:707f6e361f3e 709
Anna Bridge 186:707f6e361f3e 710 /* Enable shortcut between buffer full and begin reception on next buffer armed. */
Anna Bridge 186:707f6e361f3e 711 nrf_uarte_shorts_enable(nordic_nrf5_uart_register[instance], NRF_UARTE_SHORT_ENDRX_STARTRX);
Anna Bridge 186:707f6e361f3e 712
Anna Bridge 186:707f6e361f3e 713 /* Reset bank flag. */
Anna Bridge 186:707f6e361f3e 714 nordic_nrf5_uart_state[instance].active_bank = 0;
Anna Bridge 186:707f6e361f3e 715
Anna Bridge 186:707f6e361f3e 716 /* Arm first DMA buffer. */
Anna Bridge 186:707f6e361f3e 717 nrf_uarte_rx_buffer_set(nordic_nrf5_uart_register[instance],
Anna Bridge 186:707f6e361f3e 718 nordic_nrf5_uart_state[instance].buffer[0],
Anna Bridge 186:707f6e361f3e 719 DMA_BUFFER_SIZE);
Anna Bridge 186:707f6e361f3e 720
Anna Bridge 186:707f6e361f3e 721 /* Set non-asynchronous mode. */
Anna Bridge 186:707f6e361f3e 722 nordic_nrf5_uart_state[instance].rx_asynch = false;
Anna Bridge 186:707f6e361f3e 723
AnnaBridge 189:f392fc9709a3 724 /* Clear suspend condition */
AnnaBridge 189:f392fc9709a3 725 nordic_nrf5_uart_state[instance].rx_suspended = false;
AnnaBridge 189:f392fc9709a3 726
Anna Bridge 186:707f6e361f3e 727 /* Enable interrupts again. */
AnnaBridge 187:0387e8f68319 728 nrf_uarte_int_enable(nordic_nrf5_uart_register[instance], NRF_UARTE_INT_RXSTARTED_MASK |
AnnaBridge 189:f392fc9709a3 729 NRF_UARTE_INT_ENDRX_MASK);
Anna Bridge 186:707f6e361f3e 730 }
Anna Bridge 186:707f6e361f3e 731
Anna Bridge 186:707f6e361f3e 732 #if DEVICE_SERIAL_ASYNCH
Anna Bridge 186:707f6e361f3e 733 /**
Anna Bridge 186:707f6e361f3e 734 * @brief Setup asynchronous reception.
Anna Bridge 186:707f6e361f3e 735 *
Anna Bridge 186:707f6e361f3e 736 * @param[in] instance The instance
Anna Bridge 186:707f6e361f3e 737 */
Anna Bridge 186:707f6e361f3e 738 static void nordic_nrf5_uart_configure_rx_asynch(int instance)
Anna Bridge 186:707f6e361f3e 739 {
Anna Bridge 186:707f6e361f3e 740 /* Disable Rx related interrupts. */
AnnaBridge 187:0387e8f68319 741 nrf_uarte_int_disable(nordic_nrf5_uart_register[instance], NRF_UARTE_INT_RXSTARTED_MASK |
AnnaBridge 189:f392fc9709a3 742 NRF_UARTE_INT_ENDRX_MASK);
Anna Bridge 186:707f6e361f3e 743
Anna Bridge 186:707f6e361f3e 744 /* Clear Rx related events. */
Anna Bridge 186:707f6e361f3e 745 nrf_uarte_event_clear(nordic_nrf5_uart_register[instance], NRF_UARTE_EVENT_RXSTARTED);
Anna Bridge 186:707f6e361f3e 746 nrf_uarte_event_clear(nordic_nrf5_uart_register[instance], NRF_UARTE_EVENT_ENDRX);
Anna Bridge 186:707f6e361f3e 747
Anna Bridge 186:707f6e361f3e 748 /* Disable shortcut. Next Rx buffer must be manually started. */
Anna Bridge 186:707f6e361f3e 749 nrf_uarte_shorts_disable(nordic_nrf5_uart_register[instance], NRF_UARTE_SHORT_ENDRX_STARTRX);
Anna Bridge 186:707f6e361f3e 750
AnnaBridge 187:0387e8f68319 751 /* Set asynchronous mode. */
Anna Bridge 186:707f6e361f3e 752 nordic_nrf5_uart_state[instance].rx_asynch = true;
Anna Bridge 186:707f6e361f3e 753
AnnaBridge 189:f392fc9709a3 754 /* Clear suspend condition */
AnnaBridge 189:f392fc9709a3 755 nordic_nrf5_uart_state[instance].rx_suspended = false;
AnnaBridge 189:f392fc9709a3 756
Anna Bridge 186:707f6e361f3e 757 /* Enable Rx interrupt. */
AnnaBridge 187:0387e8f68319 758 nrf_uarte_int_enable(nordic_nrf5_uart_register[instance], NRF_UARTE_INT_ENDRX_MASK);
Anna Bridge 186:707f6e361f3e 759 }
Anna Bridge 186:707f6e361f3e 760 #endif
Anna Bridge 186:707f6e361f3e 761
Anna Bridge 186:707f6e361f3e 762 /**
Anna Bridge 186:707f6e361f3e 763 * @brief Main configuration function.
Anna Bridge 186:707f6e361f3e 764 *
Anna Bridge 186:707f6e361f3e 765 * @param obj The serial object
Anna Bridge 186:707f6e361f3e 766 */
Anna Bridge 186:707f6e361f3e 767 static void nordic_nrf5_serial_configure(serial_t *obj)
Anna Bridge 186:707f6e361f3e 768 {
Anna Bridge 186:707f6e361f3e 769 MBED_ASSERT(obj);
Anna Bridge 186:707f6e361f3e 770
Anna Bridge 186:707f6e361f3e 771 #if DEVICE_SERIAL_ASYNCH
Anna Bridge 186:707f6e361f3e 772 struct serial_s *uart_object = &obj->serial;
Anna Bridge 186:707f6e361f3e 773 #else
Anna Bridge 186:707f6e361f3e 774 struct serial_s *uart_object = obj;
Anna Bridge 186:707f6e361f3e 775 #endif
Anna Bridge 186:707f6e361f3e 776
Anna Bridge 186:707f6e361f3e 777 /* Get object instance. */
Anna Bridge 186:707f6e361f3e 778 int instance = uart_object->instance;
Anna Bridge 186:707f6e361f3e 779
Anna Bridge 186:707f6e361f3e 780 /* Only configure if instance owner has changed or an update is forced. */
Anna Bridge 186:707f6e361f3e 781 if ((uart_object != nordic_nrf5_uart_state[instance].owner) || (uart_object->update)) {
Anna Bridge 186:707f6e361f3e 782
Anna Bridge 186:707f6e361f3e 783 /* Configure common setting. */
Anna Bridge 186:707f6e361f3e 784 nordic_nrf5_uart_configure_object(obj);
Anna Bridge 186:707f6e361f3e 785
Anna Bridge 186:707f6e361f3e 786 /* Set new owner. */
Anna Bridge 186:707f6e361f3e 787 nordic_nrf5_uart_state[instance].owner = uart_object;
Anna Bridge 186:707f6e361f3e 788 uart_object->update = false;
Anna Bridge 186:707f6e361f3e 789
Anna Bridge 186:707f6e361f3e 790 #if DEVICE_SERIAL_ASYNCH
Anna Bridge 186:707f6e361f3e 791 /* Set asynchronous mode. */
Anna Bridge 186:707f6e361f3e 792 if (uart_object->rx_asynch == true) {
Anna Bridge 186:707f6e361f3e 793
Anna Bridge 186:707f6e361f3e 794 nordic_nrf5_uart_configure_rx_asynch(instance);
AnnaBridge 187:0387e8f68319 795 } else
AnnaBridge 187:0387e8f68319 796 #endif
Anna Bridge 186:707f6e361f3e 797 {
Anna Bridge 186:707f6e361f3e 798 /* Set non-asynchronous mode. */
Anna Bridge 186:707f6e361f3e 799 nordic_nrf5_uart_configure_rx(instance);
Anna Bridge 186:707f6e361f3e 800 nrf_uarte_task_trigger(nordic_nrf5_uart_register[instance],
Anna Bridge 186:707f6e361f3e 801 NRF_UARTE_TASK_STARTRX);
Anna Bridge 186:707f6e361f3e 802 }
AnnaBridge 187:0387e8f68319 803 }
Anna Bridge 186:707f6e361f3e 804 #if DEVICE_SERIAL_ASYNCH
Anna Bridge 186:707f6e361f3e 805 /* Owner hasn't changed but mode has. Reconfigure. */
Anna Bridge 186:707f6e361f3e 806 else if ((uart_object->rx_asynch == false) && (nordic_nrf5_uart_state[instance].rx_asynch == true)) {
Anna Bridge 186:707f6e361f3e 807
Anna Bridge 186:707f6e361f3e 808 nordic_nrf5_uart_configure_rx(instance);
Anna Bridge 186:707f6e361f3e 809 nrf_uarte_task_trigger(nordic_nrf5_uart_register[instance],
Anna Bridge 186:707f6e361f3e 810 NRF_UARTE_TASK_STARTRX);
Anna Bridge 186:707f6e361f3e 811
Anna Bridge 186:707f6e361f3e 812 /* Owner hasn't changed but mode has. Reconfigure. */
Anna Bridge 186:707f6e361f3e 813 } else if ((uart_object->rx_asynch == true) && (nordic_nrf5_uart_state[instance].rx_asynch == false)) {
Anna Bridge 186:707f6e361f3e 814
Anna Bridge 186:707f6e361f3e 815 nordic_nrf5_uart_configure_rx_asynch(instance);
Anna Bridge 186:707f6e361f3e 816 }
Anna Bridge 186:707f6e361f3e 817 #endif
Anna Bridge 186:707f6e361f3e 818 }
Anna Bridge 186:707f6e361f3e 819
Anna Bridge 186:707f6e361f3e 820 /***
AnnaBridge 187:0387e8f68319 821 * __ __ _ _ _ _ _ _____ _____
Anna Bridge 186:707f6e361f3e 822 * | \/ | | | | | | | | /\ | | /\ | __ \_ _|
AnnaBridge 187:0387e8f68319 823 * | \ / | |__ ___ __| | | |__| | / \ | | / \ | |__) || |
AnnaBridge 187:0387e8f68319 824 * | |\/| | '_ \ / _ \/ _` | | __ | / /\ \ | | / /\ \ | ___/ | |
AnnaBridge 187:0387e8f68319 825 * | | | | |_) | __/ (_| | | | | |/ ____ \| |____ / ____ \| | _| |_
Anna Bridge 186:707f6e361f3e 826 * |_| |_|_.__/ \___|\__,_| |_| |_/_/ \_\______| /_/ \_\_| |_____|
AnnaBridge 187:0387e8f68319 827 *
AnnaBridge 187:0387e8f68319 828 *
Anna Bridge 186:707f6e361f3e 829 */
Anna Bridge 186:707f6e361f3e 830
Anna Bridge 186:707f6e361f3e 831 /** Initialize the serial peripheral. It sets the default parameters for serial
Anna Bridge 186:707f6e361f3e 832 * peripheral, and configures its specifieds pins.
Anna Bridge 186:707f6e361f3e 833 *
Anna Bridge 186:707f6e361f3e 834 * Param obj The serial object
Anna Bridge 186:707f6e361f3e 835 * Param tx The TX pin name
Anna Bridge 186:707f6e361f3e 836 * Param rx The RX pin name
Anna Bridge 186:707f6e361f3e 837 */
Anna Bridge 186:707f6e361f3e 838 void serial_init(serial_t *obj, PinName tx, PinName rx)
Anna Bridge 186:707f6e361f3e 839 {
Anna Bridge 186:707f6e361f3e 840 MBED_ASSERT(obj);
Anna Bridge 186:707f6e361f3e 841
Anna Bridge 186:707f6e361f3e 842 #if DEVICE_SERIAL_ASYNCH
Anna Bridge 186:707f6e361f3e 843 struct serial_s *uart_object = &obj->serial;
Anna Bridge 186:707f6e361f3e 844 #else
Anna Bridge 186:707f6e361f3e 845 struct serial_s *uart_object = obj;
Anna Bridge 186:707f6e361f3e 846 #endif
Anna Bridge 186:707f6e361f3e 847
Anna Bridge 186:707f6e361f3e 848 /* Only initialize on first call. */
Anna Bridge 186:707f6e361f3e 849 static bool first_init = true;
Anna Bridge 186:707f6e361f3e 850 if (first_init) {
AnnaBridge 189:f392fc9709a3 851 uint32_t ret;
Anna Bridge 186:707f6e361f3e 852 first_init = false;
Anna Bridge 186:707f6e361f3e 853
AnnaBridge 189:f392fc9709a3 854 /* Initialize components that serial relies on. */
AnnaBridge 189:f392fc9709a3 855 nrf_drv_ppi_init();
AnnaBridge 189:f392fc9709a3 856 if (!nrf_drv_gpiote_is_init()) {
AnnaBridge 189:f392fc9709a3 857 nrf_drv_gpiote_init();
AnnaBridge 189:f392fc9709a3 858 }
Anna Bridge 186:707f6e361f3e 859
AnnaBridge 187:0387e8f68319 860 /* Enable interrupts for SWI. */
AnnaBridge 187:0387e8f68319 861 NVIC_SetVector(SWI0_EGU0_IRQn, (uint32_t) nordic_nrf5_uart_swi0);
AnnaBridge 187:0387e8f68319 862 nrf_drv_common_irq_enable(SWI0_EGU0_IRQn, APP_IRQ_PRIORITY_LOWEST);
AnnaBridge 187:0387e8f68319 863
Anna Bridge 186:707f6e361f3e 864 /* Initialize FIFO buffer for UARTE0. */
Anna Bridge 186:707f6e361f3e 865 NRF_ATFIFO_INIT(nordic_nrf5_uart_fifo_0);
Anna Bridge 186:707f6e361f3e 866 nordic_nrf5_uart_state[0].fifo = nordic_nrf5_uart_fifo_0;
Anna Bridge 186:707f6e361f3e 867
Anna Bridge 186:707f6e361f3e 868 /* Initialize owner to NULL. */
Anna Bridge 186:707f6e361f3e 869 nordic_nrf5_uart_state[0].owner = NULL;
Anna Bridge 186:707f6e361f3e 870
AnnaBridge 189:f392fc9709a3 871 /* Allocate a PPI channel for flow control */
AnnaBridge 189:f392fc9709a3 872 ret = nrf_drv_ppi_channel_alloc(&nordic_nrf5_uart_state[0].ppi_rts);
AnnaBridge 189:f392fc9709a3 873 MBED_ASSERT(ret == NRF_SUCCESS);
AnnaBridge 189:f392fc9709a3 874
AnnaBridge 189:f392fc9709a3 875 /* Clear RTS */
AnnaBridge 189:f392fc9709a3 876 nordic_nrf5_uart_state[0].rts = NRF_UART_PSEL_DISCONNECTED;
AnnaBridge 189:f392fc9709a3 877
AnnaBridge 187:0387e8f68319 878 /* Clear any old events and enable interrupts for UARTE0. */
AnnaBridge 189:f392fc9709a3 879 nrf_uarte_int_disable(nordic_nrf5_uart_register[0], 0xFFFFFFFF);
AnnaBridge 187:0387e8f68319 880
Anna Bridge 186:707f6e361f3e 881 NVIC_SetVector(UARTE0_UART0_IRQn, (uint32_t) nordic_nrf5_uart0_handler);
AnnaBridge 187:0387e8f68319 882 nrf_drv_common_irq_enable(UARTE0_UART0_IRQn, APP_IRQ_PRIORITY_HIGHEST);
Anna Bridge 186:707f6e361f3e 883
Anna Bridge 186:707f6e361f3e 884 #if UART1_ENABLED
Anna Bridge 186:707f6e361f3e 885 /* Initialize FIFO buffer for UARTE1. */
Anna Bridge 186:707f6e361f3e 886 NRF_ATFIFO_INIT(nordic_nrf5_uart_fifo_1);
Anna Bridge 186:707f6e361f3e 887 nordic_nrf5_uart_state[1].fifo = nordic_nrf5_uart_fifo_1;
Anna Bridge 186:707f6e361f3e 888
Anna Bridge 186:707f6e361f3e 889 /* Initialize owner to NULL. */
Anna Bridge 186:707f6e361f3e 890 nordic_nrf5_uart_state[1].owner = NULL;
Anna Bridge 186:707f6e361f3e 891
AnnaBridge 189:f392fc9709a3 892 /* Allocate a PPI channel for flow control */
AnnaBridge 189:f392fc9709a3 893 ret = nrf_drv_ppi_channel_alloc(&nordic_nrf5_uart_state[1].ppi_rts);
AnnaBridge 189:f392fc9709a3 894 MBED_ASSERT(ret == NRF_SUCCESS);
AnnaBridge 189:f392fc9709a3 895
AnnaBridge 189:f392fc9709a3 896 /* Clear RTS */
AnnaBridge 189:f392fc9709a3 897 nordic_nrf5_uart_state[1].rts = NRF_UART_PSEL_DISCONNECTED;
AnnaBridge 189:f392fc9709a3 898
AnnaBridge 187:0387e8f68319 899 /* Clear any old events and enable interrupts for UARTE1. */
AnnaBridge 189:f392fc9709a3 900 nrf_uarte_int_disable(nordic_nrf5_uart_register[1], 0xFFFFFFFF);
AnnaBridge 187:0387e8f68319 901
Anna Bridge 186:707f6e361f3e 902 NVIC_SetVector(UARTE1_IRQn, (uint32_t) nordic_nrf5_uart1_handler);
AnnaBridge 187:0387e8f68319 903 nrf_drv_common_irq_enable(UARTE1_IRQn, APP_IRQ_PRIORITY_HIGHEST);
Anna Bridge 186:707f6e361f3e 904 #endif
Anna Bridge 186:707f6e361f3e 905 }
Anna Bridge 186:707f6e361f3e 906
Anna Bridge 186:707f6e361f3e 907 /* Get instance ID based on provided pins. */
Anna Bridge 186:707f6e361f3e 908 int instance = pin_instance_uart(tx, rx);
Anna Bridge 186:707f6e361f3e 909
Anna Bridge 186:707f6e361f3e 910 uart_object->instance = instance;
Anna Bridge 186:707f6e361f3e 911
Anna Bridge 186:707f6e361f3e 912 /* Increment usage counter for this instance. */
Anna Bridge 186:707f6e361f3e 913 nordic_nrf5_uart_state[instance].usage_counter++;
Anna Bridge 186:707f6e361f3e 914
Anna Bridge 186:707f6e361f3e 915 /* Enable instance on first usage. */
Anna Bridge 186:707f6e361f3e 916 if (nordic_nrf5_uart_state[instance].usage_counter == 1) {
Anna Bridge 186:707f6e361f3e 917
Anna Bridge 186:707f6e361f3e 918 nrf_uarte_enable(nordic_nrf5_uart_register[instance]);
AnnaBridge 189:f392fc9709a3 919
AnnaBridge 189:f392fc9709a3 920 /* In order to support printing with interrupts disabled serial_putc
AnnaBridge 189:f392fc9709a3 921 * must busy wait on NRF_UARTE_EVENT_TXDRDY. This event cannot be set
AnnaBridge 189:f392fc9709a3 922 * manually but must be set by the UARTE module after a character has
AnnaBridge 189:f392fc9709a3 923 * been sent.
AnnaBridge 189:f392fc9709a3 924 *
AnnaBridge 189:f392fc9709a3 925 * The following code sends a dummy character into the void so that
AnnaBridge 189:f392fc9709a3 926 * NRF_UARTE_EVENT_TXDRDY is correctly set.
AnnaBridge 189:f392fc9709a3 927 */
AnnaBridge 189:f392fc9709a3 928
AnnaBridge 189:f392fc9709a3 929 /* Ensure pins are disconnected. */
AnnaBridge 189:f392fc9709a3 930 nrf_uarte_txrx_pins_set(nordic_nrf5_uart_register[instance],
AnnaBridge 189:f392fc9709a3 931 NRF_UART_PSEL_DISCONNECTED,
AnnaBridge 189:f392fc9709a3 932 NRF_UART_PSEL_DISCONNECTED);
AnnaBridge 189:f392fc9709a3 933
AnnaBridge 189:f392fc9709a3 934 /* Set maximum baud rate to minimize waiting. */
AnnaBridge 189:f392fc9709a3 935 nrf_uarte_baudrate_set(nordic_nrf5_uart_register[instance],
AnnaBridge 189:f392fc9709a3 936 NRF_UARTE_BAUDRATE_1000000);
AnnaBridge 189:f392fc9709a3 937
AnnaBridge 189:f392fc9709a3 938 /* Send character. */
AnnaBridge 189:f392fc9709a3 939 nrf_uarte_tx_buffer_set(nordic_nrf5_uart_register[instance],
AnnaBridge 189:f392fc9709a3 940 &nordic_nrf5_uart_state[instance].tx_data,
AnnaBridge 189:f392fc9709a3 941 1);
AnnaBridge 189:f392fc9709a3 942 nrf_uarte_event_clear(nordic_nrf5_uart_register[instance], NRF_UARTE_EVENT_ENDTX);
AnnaBridge 189:f392fc9709a3 943 nrf_uarte_task_trigger(nordic_nrf5_uart_register[instance], NRF_UARTE_TASK_STARTTX);
AnnaBridge 189:f392fc9709a3 944
AnnaBridge 189:f392fc9709a3 945 /* Wait until NRF_UARTE_EVENT_TXDRDY is set before proceeding. */
AnnaBridge 189:f392fc9709a3 946 bool done = false;
AnnaBridge 189:f392fc9709a3 947 do {
AnnaBridge 189:f392fc9709a3 948 done = nrf_uarte_event_extra_check(nordic_nrf5_uart_register[instance], NRF_UARTE_EVENT_TXDRDY);
AnnaBridge 189:f392fc9709a3 949 } while(done == false);
Anna Bridge 186:707f6e361f3e 950 }
Anna Bridge 186:707f6e361f3e 951
Anna Bridge 186:707f6e361f3e 952 /* Store pins in serial object. */
Anna Bridge 186:707f6e361f3e 953 if (tx == NC) {
Anna Bridge 186:707f6e361f3e 954
Anna Bridge 186:707f6e361f3e 955 uart_object->tx = NRF_UART_PSEL_DISCONNECTED;
Anna Bridge 186:707f6e361f3e 956 } else {
Anna Bridge 186:707f6e361f3e 957
Anna Bridge 186:707f6e361f3e 958 uart_object->tx = tx;
Anna Bridge 186:707f6e361f3e 959 }
Anna Bridge 186:707f6e361f3e 960
Anna Bridge 186:707f6e361f3e 961 if (rx == NC) {
Anna Bridge 186:707f6e361f3e 962
Anna Bridge 186:707f6e361f3e 963 uart_object->rx = NRF_UART_PSEL_DISCONNECTED;
Anna Bridge 186:707f6e361f3e 964 } else {
Anna Bridge 186:707f6e361f3e 965
Anna Bridge 186:707f6e361f3e 966 uart_object->rx = rx;
Anna Bridge 186:707f6e361f3e 967 }
Anna Bridge 186:707f6e361f3e 968
Anna Bridge 186:707f6e361f3e 969 /* Set default parity, baud rate, and callback handler. */
Anna Bridge 186:707f6e361f3e 970 uart_object->parity = NRF_UART_PARITY_EXCLUDED;
Anna Bridge 186:707f6e361f3e 971 uart_object->baudrate = NRF_UART_BAUDRATE_9600;
Anna Bridge 186:707f6e361f3e 972 uart_object->cts = NRF_UART_PSEL_DISCONNECTED;
Anna Bridge 186:707f6e361f3e 973 uart_object->rts = NRF_UART_PSEL_DISCONNECTED;
Anna Bridge 186:707f6e361f3e 974 uart_object->hwfc = NRF_UART_HWFC_DISABLED;
Anna Bridge 186:707f6e361f3e 975 uart_object->handler = 0;
Anna Bridge 186:707f6e361f3e 976
Anna Bridge 186:707f6e361f3e 977 /* The STDIO object is stored in this file. Set the flag once initialized. */
Anna Bridge 186:707f6e361f3e 978 if (obj == &stdio_uart) {
Anna Bridge 186:707f6e361f3e 979 stdio_uart_inited = 1;
Anna Bridge 186:707f6e361f3e 980 }
Anna Bridge 186:707f6e361f3e 981
Anna Bridge 186:707f6e361f3e 982 /* Take ownership and configure UART. */
Anna Bridge 186:707f6e361f3e 983 uart_object->update = true;
Anna Bridge 186:707f6e361f3e 984 nordic_nrf5_serial_configure(obj);
Anna Bridge 186:707f6e361f3e 985 }
Anna Bridge 186:707f6e361f3e 986
Anna Bridge 186:707f6e361f3e 987 /** Release the serial peripheral, not currently invoked. It requires further
Anna Bridge 186:707f6e361f3e 988 * resource management.
Anna Bridge 186:707f6e361f3e 989 *
Anna Bridge 186:707f6e361f3e 990 * Param obj The serial object
Anna Bridge 186:707f6e361f3e 991 */
Anna Bridge 186:707f6e361f3e 992 void serial_free(serial_t *obj)
Anna Bridge 186:707f6e361f3e 993 {
Anna Bridge 186:707f6e361f3e 994 MBED_ASSERT(obj);
Anna Bridge 186:707f6e361f3e 995
Anna Bridge 186:707f6e361f3e 996 #if DEVICE_SERIAL_ASYNCH
Anna Bridge 186:707f6e361f3e 997 struct serial_s *uart_object = &obj->serial;
Anna Bridge 186:707f6e361f3e 998 #else
Anna Bridge 186:707f6e361f3e 999 struct serial_s *uart_object = obj;
Anna Bridge 186:707f6e361f3e 1000 #endif
Anna Bridge 186:707f6e361f3e 1001
Anna Bridge 186:707f6e361f3e 1002 int instance = uart_object->instance;
Anna Bridge 186:707f6e361f3e 1003
Anna Bridge 186:707f6e361f3e 1004 /* Only consider disabling UARTE if number of users is not zero. */
Anna Bridge 186:707f6e361f3e 1005 if (nordic_nrf5_uart_state[instance].usage_counter > 0) {
Anna Bridge 186:707f6e361f3e 1006
Anna Bridge 186:707f6e361f3e 1007 /* Decrement usage counter for this instance. */
Anna Bridge 186:707f6e361f3e 1008 nordic_nrf5_uart_state[instance].usage_counter--;
Anna Bridge 186:707f6e361f3e 1009
Anna Bridge 186:707f6e361f3e 1010 /* Disable instance when not in use. */
Anna Bridge 186:707f6e361f3e 1011 if (nordic_nrf5_uart_state[instance].usage_counter == 0) {
Anna Bridge 186:707f6e361f3e 1012
Anna Bridge 186:707f6e361f3e 1013 nrf_uarte_disable(nordic_nrf5_uart_register[instance]);
Anna Bridge 186:707f6e361f3e 1014 }
Anna Bridge 186:707f6e361f3e 1015 }
Anna Bridge 186:707f6e361f3e 1016 }
Anna Bridge 186:707f6e361f3e 1017
Anna Bridge 186:707f6e361f3e 1018 /** Configure the baud rate
Anna Bridge 186:707f6e361f3e 1019 *
Anna Bridge 186:707f6e361f3e 1020 * Param obj The serial object
Anna Bridge 186:707f6e361f3e 1021 * Param baudrate The baud rate to be configured
Anna Bridge 186:707f6e361f3e 1022 */
Anna Bridge 186:707f6e361f3e 1023 void serial_baud(serial_t *obj, int baudrate)
Anna Bridge 186:707f6e361f3e 1024 {
Anna Bridge 186:707f6e361f3e 1025 MBED_ASSERT(obj);
Anna Bridge 186:707f6e361f3e 1026
Anna Bridge 186:707f6e361f3e 1027 #if DEVICE_SERIAL_ASYNCH
Anna Bridge 186:707f6e361f3e 1028 struct serial_s *uart_object = &obj->serial;
Anna Bridge 186:707f6e361f3e 1029 #else
Anna Bridge 186:707f6e361f3e 1030 struct serial_s *uart_object = obj;
Anna Bridge 186:707f6e361f3e 1031 #endif
Anna Bridge 186:707f6e361f3e 1032
Anna Bridge 186:707f6e361f3e 1033 nrf_uart_baudrate_t new_rate = NRF_UART_BAUDRATE_9600;
Anna Bridge 186:707f6e361f3e 1034
Anna Bridge 186:707f6e361f3e 1035 /* Round down to nearest supported baud rate. */
Anna Bridge 186:707f6e361f3e 1036 if (baudrate < 2400) {
Anna Bridge 186:707f6e361f3e 1037 new_rate = NRF_UARTE_BAUDRATE_1200;
Anna Bridge 186:707f6e361f3e 1038 } else if (baudrate < 4800) {
Anna Bridge 186:707f6e361f3e 1039 new_rate = NRF_UARTE_BAUDRATE_2400;
Anna Bridge 186:707f6e361f3e 1040 } else if (baudrate < 9600) {
Anna Bridge 186:707f6e361f3e 1041 new_rate = NRF_UARTE_BAUDRATE_4800;
Anna Bridge 186:707f6e361f3e 1042 } else if (baudrate < 14400) {
Anna Bridge 186:707f6e361f3e 1043 new_rate = NRF_UARTE_BAUDRATE_9600;
Anna Bridge 186:707f6e361f3e 1044 } else if (baudrate < 19200) {
Anna Bridge 186:707f6e361f3e 1045 new_rate = NRF_UARTE_BAUDRATE_14400;
Anna Bridge 186:707f6e361f3e 1046 } else if (baudrate < 28800) {
Anna Bridge 186:707f6e361f3e 1047 new_rate = NRF_UARTE_BAUDRATE_19200;
Anna Bridge 186:707f6e361f3e 1048 } else if (baudrate < 38400) {
Anna Bridge 186:707f6e361f3e 1049 new_rate = NRF_UARTE_BAUDRATE_28800;
Anna Bridge 186:707f6e361f3e 1050 } else if (baudrate < 57600) {
Anna Bridge 186:707f6e361f3e 1051 new_rate = NRF_UARTE_BAUDRATE_38400;
Anna Bridge 186:707f6e361f3e 1052 } else if (baudrate < 76800) {
Anna Bridge 186:707f6e361f3e 1053 new_rate = NRF_UARTE_BAUDRATE_57600;
Anna Bridge 186:707f6e361f3e 1054 } else if (baudrate < 115200) {
Anna Bridge 186:707f6e361f3e 1055 new_rate = NRF_UARTE_BAUDRATE_76800;
Anna Bridge 186:707f6e361f3e 1056 } else if (baudrate < 230400) {
Anna Bridge 186:707f6e361f3e 1057 new_rate = NRF_UARTE_BAUDRATE_115200;
Anna Bridge 186:707f6e361f3e 1058 } else if (baudrate < 250000) {
Anna Bridge 186:707f6e361f3e 1059 new_rate = NRF_UARTE_BAUDRATE_230400;
Anna Bridge 186:707f6e361f3e 1060 } else if (baudrate < 460800) {
Anna Bridge 186:707f6e361f3e 1061 new_rate = NRF_UARTE_BAUDRATE_250000;
Anna Bridge 186:707f6e361f3e 1062 } else if (baudrate < 921600) {
Anna Bridge 186:707f6e361f3e 1063 new_rate = NRF_UARTE_BAUDRATE_460800;
Anna Bridge 186:707f6e361f3e 1064 } else if (baudrate < 1000000) {
Anna Bridge 186:707f6e361f3e 1065 new_rate = NRF_UARTE_BAUDRATE_921600;
Anna Bridge 186:707f6e361f3e 1066 } else {
Anna Bridge 186:707f6e361f3e 1067 new_rate = NRF_UARTE_BAUDRATE_1000000;
Anna Bridge 186:707f6e361f3e 1068 }
Anna Bridge 186:707f6e361f3e 1069
Anna Bridge 186:707f6e361f3e 1070 /* Force reconfiguration next time serial object is owner if baud rate has changed. */
Anna Bridge 186:707f6e361f3e 1071 if (uart_object->baudrate != new_rate) {
Anna Bridge 186:707f6e361f3e 1072
Anna Bridge 186:707f6e361f3e 1073 uart_object->baudrate = new_rate;
Anna Bridge 186:707f6e361f3e 1074 uart_object->update = true;
Anna Bridge 186:707f6e361f3e 1075 }
Anna Bridge 186:707f6e361f3e 1076 }
Anna Bridge 186:707f6e361f3e 1077
Anna Bridge 186:707f6e361f3e 1078 /** Configure the format. Set the number of bits, parity and the number of stop bits
Anna Bridge 186:707f6e361f3e 1079 *
Anna Bridge 186:707f6e361f3e 1080 * Param obj The serial object
Anna Bridge 186:707f6e361f3e 1081 * Param data_bits The number of data bits
Anna Bridge 186:707f6e361f3e 1082 * Param parity The parity
Anna Bridge 186:707f6e361f3e 1083 * Param stop_bits The number of stop bits
Anna Bridge 186:707f6e361f3e 1084 */
Anna Bridge 186:707f6e361f3e 1085 void serial_format(serial_t *obj, int data_bits, SerialParity parity, int stop_bits)
Anna Bridge 186:707f6e361f3e 1086 {
Anna Bridge 186:707f6e361f3e 1087 MBED_ASSERT(obj);
Anna Bridge 186:707f6e361f3e 1088
Anna Bridge 186:707f6e361f3e 1089 /**
Anna Bridge 186:707f6e361f3e 1090 * Only 8-bit mode, None/Even parity, and 1 stop bit supported by hardware.
Anna Bridge 186:707f6e361f3e 1091 */
Anna Bridge 186:707f6e361f3e 1092 MBED_ASSERT(data_bits == 8);
Anna Bridge 186:707f6e361f3e 1093 MBED_ASSERT((parity == ParityNone) || (parity == ParityEven));
Anna Bridge 186:707f6e361f3e 1094 MBED_ASSERT(stop_bits == 1);
Anna Bridge 186:707f6e361f3e 1095
Anna Bridge 186:707f6e361f3e 1096 #if DEVICE_SERIAL_ASYNCH
Anna Bridge 186:707f6e361f3e 1097 struct serial_s *uart_object = &obj->serial;
Anna Bridge 186:707f6e361f3e 1098 #else
Anna Bridge 186:707f6e361f3e 1099 struct serial_s *uart_object = obj;
Anna Bridge 186:707f6e361f3e 1100 #endif
Anna Bridge 186:707f6e361f3e 1101
Anna Bridge 186:707f6e361f3e 1102 /**
Anna Bridge 186:707f6e361f3e 1103 * Only force change if parity has changed.
Anna Bridge 186:707f6e361f3e 1104 */
Anna Bridge 186:707f6e361f3e 1105 if ((uart_object->parity != NRF_UART_PARITY_EXCLUDED) && (parity == ParityNone)) {
Anna Bridge 186:707f6e361f3e 1106
Anna Bridge 186:707f6e361f3e 1107 uart_object->parity = NRF_UART_PARITY_EXCLUDED;
Anna Bridge 186:707f6e361f3e 1108 uart_object->update = true;
Anna Bridge 186:707f6e361f3e 1109
Anna Bridge 186:707f6e361f3e 1110 } else if ((uart_object->parity != NRF_UART_PARITY_INCLUDED) && (parity == ParityEven)) {
Anna Bridge 186:707f6e361f3e 1111
Anna Bridge 186:707f6e361f3e 1112 uart_object->parity = NRF_UART_PARITY_INCLUDED;
Anna Bridge 186:707f6e361f3e 1113 uart_object->update = true;
Anna Bridge 186:707f6e361f3e 1114 }
Anna Bridge 186:707f6e361f3e 1115 }
Anna Bridge 186:707f6e361f3e 1116
Anna Bridge 186:707f6e361f3e 1117 /** Configure the serial for the flow control. It sets flow control in the hardware
Anna Bridge 186:707f6e361f3e 1118 * if a serial peripheral supports it, otherwise software emulation is used.
Anna Bridge 186:707f6e361f3e 1119 *
Anna Bridge 186:707f6e361f3e 1120 * Param obj The serial object
Anna Bridge 186:707f6e361f3e 1121 * Param type The type of the flow control. Look at the available FlowControl types.
Anna Bridge 186:707f6e361f3e 1122 * Param rxflow The TX pin name
Anna Bridge 186:707f6e361f3e 1123 * Param txflow The RX pin name
Anna Bridge 186:707f6e361f3e 1124 */
Anna Bridge 186:707f6e361f3e 1125 void serial_set_flow_control(serial_t *obj, FlowControl type, PinName rxflow, PinName txflow)
Anna Bridge 186:707f6e361f3e 1126 {
Anna Bridge 186:707f6e361f3e 1127 MBED_ASSERT(obj);
Anna Bridge 186:707f6e361f3e 1128
Anna Bridge 186:707f6e361f3e 1129 #if DEVICE_SERIAL_ASYNCH
Anna Bridge 186:707f6e361f3e 1130 struct serial_s *uart_object = &obj->serial;
Anna Bridge 186:707f6e361f3e 1131 #else
Anna Bridge 186:707f6e361f3e 1132 struct serial_s *uart_object = obj;
Anna Bridge 186:707f6e361f3e 1133 #endif
Anna Bridge 186:707f6e361f3e 1134
Anna Bridge 186:707f6e361f3e 1135 /**
Anna Bridge 186:707f6e361f3e 1136 * Convert Mbed pin names to Nordic pin names.
Anna Bridge 186:707f6e361f3e 1137 */
Anna Bridge 186:707f6e361f3e 1138 uart_object->cts = ((txflow == NC) || (type == FlowControlRTS)) ? NRF_UART_PSEL_DISCONNECTED : (uint32_t) txflow;
Anna Bridge 186:707f6e361f3e 1139 uart_object->rts = ((rxflow == NC) || (type == FlowControlCTS)) ? NRF_UART_PSEL_DISCONNECTED : (uint32_t) rxflow;
Anna Bridge 186:707f6e361f3e 1140 uart_object->hwfc = (type == FlowControlNone) ? NRF_UART_HWFC_DISABLED : NRF_UART_HWFC_ENABLED;
Anna Bridge 186:707f6e361f3e 1141
Anna Bridge 186:707f6e361f3e 1142 /* Force reconfiguration next time object is owner. */
Anna Bridge 186:707f6e361f3e 1143 uart_object->update = true;
AnnaBridge 188:bcfe06ba3d64 1144 nordic_nrf5_serial_configure(obj);
Anna Bridge 186:707f6e361f3e 1145 }
Anna Bridge 186:707f6e361f3e 1146
Anna Bridge 186:707f6e361f3e 1147 /** Clear the serial peripheral
Anna Bridge 186:707f6e361f3e 1148 *
Anna Bridge 186:707f6e361f3e 1149 * Param obj The serial object
Anna Bridge 186:707f6e361f3e 1150 */
Anna Bridge 186:707f6e361f3e 1151 void serial_clear(serial_t *obj)
Anna Bridge 186:707f6e361f3e 1152 {
Anna Bridge 186:707f6e361f3e 1153 MBED_ASSERT(obj);
Anna Bridge 186:707f6e361f3e 1154
Anna Bridge 186:707f6e361f3e 1155 #if DEVICE_SERIAL_ASYNCH
Anna Bridge 186:707f6e361f3e 1156 struct serial_s *uart_object = &obj->serial;
Anna Bridge 186:707f6e361f3e 1157 #else
Anna Bridge 186:707f6e361f3e 1158 struct serial_s *uart_object = obj;
Anna Bridge 186:707f6e361f3e 1159 #endif
Anna Bridge 186:707f6e361f3e 1160
Anna Bridge 186:707f6e361f3e 1161 /**
Anna Bridge 186:707f6e361f3e 1162 * Reconfigure UART.
Anna Bridge 186:707f6e361f3e 1163 */
Anna Bridge 186:707f6e361f3e 1164 uart_object->update = true;
Anna Bridge 186:707f6e361f3e 1165 nordic_nrf5_uart_configure_object(obj);
Anna Bridge 186:707f6e361f3e 1166 }
Anna Bridge 186:707f6e361f3e 1167
Anna Bridge 186:707f6e361f3e 1168 /** Set the break
Anna Bridge 186:707f6e361f3e 1169 *
Anna Bridge 186:707f6e361f3e 1170 * Param obj The serial object
Anna Bridge 186:707f6e361f3e 1171 */
Anna Bridge 186:707f6e361f3e 1172 void serial_break_set(serial_t *obj)
Anna Bridge 186:707f6e361f3e 1173 {
Anna Bridge 186:707f6e361f3e 1174 MBED_ASSERT(obj);
Anna Bridge 186:707f6e361f3e 1175
Anna Bridge 186:707f6e361f3e 1176 #if DEVICE_SERIAL_ASYNCH
Anna Bridge 186:707f6e361f3e 1177 struct serial_s *uart_object = &obj->serial;
Anna Bridge 186:707f6e361f3e 1178 #else
Anna Bridge 186:707f6e361f3e 1179 struct serial_s *uart_object = obj;
Anna Bridge 186:707f6e361f3e 1180 #endif
Anna Bridge 186:707f6e361f3e 1181
Anna Bridge 186:707f6e361f3e 1182 /* Set Tx pin low. */
Anna Bridge 186:707f6e361f3e 1183 nrf_gpio_pin_clear(uart_object->tx);
Anna Bridge 186:707f6e361f3e 1184 }
Anna Bridge 186:707f6e361f3e 1185
Anna Bridge 186:707f6e361f3e 1186 /** Clear the break
Anna Bridge 186:707f6e361f3e 1187 *
Anna Bridge 186:707f6e361f3e 1188 * Param obj The serial object
Anna Bridge 186:707f6e361f3e 1189 */
Anna Bridge 186:707f6e361f3e 1190 void serial_break_clear(serial_t *obj)
Anna Bridge 186:707f6e361f3e 1191 {
Anna Bridge 186:707f6e361f3e 1192 MBED_ASSERT(obj);
Anna Bridge 186:707f6e361f3e 1193
Anna Bridge 186:707f6e361f3e 1194 #if DEVICE_SERIAL_ASYNCH
Anna Bridge 186:707f6e361f3e 1195 struct serial_s *uart_object = &obj->serial;
Anna Bridge 186:707f6e361f3e 1196 #else
Anna Bridge 186:707f6e361f3e 1197 struct serial_s *uart_object = obj;
Anna Bridge 186:707f6e361f3e 1198 #endif
Anna Bridge 186:707f6e361f3e 1199
Anna Bridge 186:707f6e361f3e 1200 /* Set Tx pin high (default). */
Anna Bridge 186:707f6e361f3e 1201 nrf_gpio_pin_set(uart_object->tx);
Anna Bridge 186:707f6e361f3e 1202 }
Anna Bridge 186:707f6e361f3e 1203
Anna Bridge 186:707f6e361f3e 1204 /** Configure the TX pin for UART function.
Anna Bridge 186:707f6e361f3e 1205 *
Anna Bridge 186:707f6e361f3e 1206 * Param tx The pin name used for TX
Anna Bridge 186:707f6e361f3e 1207 */
Anna Bridge 186:707f6e361f3e 1208 void serial_pinout_tx(PinName tx)
Anna Bridge 186:707f6e361f3e 1209 {
Anna Bridge 186:707f6e361f3e 1210 /**
Anna Bridge 186:707f6e361f3e 1211 * Legacy API. Not used by Mbed.
Anna Bridge 186:707f6e361f3e 1212 */
AnnaBridge 187:0387e8f68319 1213 MBED_ASSERT(0);
Anna Bridge 186:707f6e361f3e 1214 }
Anna Bridge 186:707f6e361f3e 1215
Anna Bridge 186:707f6e361f3e 1216 /***
AnnaBridge 187:0387e8f68319 1217 * _____ _ _ _____ _____
Anna Bridge 186:707f6e361f3e 1218 * / ____(_) | | /\ | __ \_ _|
AnnaBridge 187:0387e8f68319 1219 * | (___ _ _ __ ___ _ __ | | ___ / \ | |__) || |
AnnaBridge 187:0387e8f68319 1220 * \___ \| | '_ ` _ \| '_ \| |/ _ \ / /\ \ | ___/ | |
AnnaBridge 187:0387e8f68319 1221 * ____) | | | | | | | |_) | | __/ / ____ \| | _| |_
Anna Bridge 186:707f6e361f3e 1222 * |_____/|_|_| |_| |_| .__/|_|\___| /_/ \_\_| |_____|
AnnaBridge 187:0387e8f68319 1223 * | |
AnnaBridge 187:0387e8f68319 1224 * |_|
Anna Bridge 186:707f6e361f3e 1225 */
Anna Bridge 186:707f6e361f3e 1226
Anna Bridge 186:707f6e361f3e 1227 /** The serial interrupt handler registration
Anna Bridge 186:707f6e361f3e 1228 *
Anna Bridge 186:707f6e361f3e 1229 * Param obj The serial object
Anna Bridge 186:707f6e361f3e 1230 * Param handler The interrupt handler which will be invoked when the interrupt fires
Anna Bridge 186:707f6e361f3e 1231 * Param id The SerialBase object
Anna Bridge 186:707f6e361f3e 1232 */
Anna Bridge 186:707f6e361f3e 1233 void serial_irq_handler(serial_t *obj, uart_irq_handler handler, uint32_t id)
Anna Bridge 186:707f6e361f3e 1234 {
Anna Bridge 186:707f6e361f3e 1235 MBED_ASSERT(obj);
Anna Bridge 186:707f6e361f3e 1236
Anna Bridge 186:707f6e361f3e 1237 #if DEVICE_SERIAL_ASYNCH
Anna Bridge 186:707f6e361f3e 1238 struct serial_s *uart_object = &obj->serial;
Anna Bridge 186:707f6e361f3e 1239 #else
Anna Bridge 186:707f6e361f3e 1240 struct serial_s *uart_object = obj;
Anna Bridge 186:707f6e361f3e 1241 #endif
Anna Bridge 186:707f6e361f3e 1242
Anna Bridge 186:707f6e361f3e 1243 /* Store handler and ID in serial object. */
Anna Bridge 186:707f6e361f3e 1244 uart_object->handler = (uint32_t) handler;
Anna Bridge 186:707f6e361f3e 1245 uart_object->context = id;
Anna Bridge 186:707f6e361f3e 1246 }
Anna Bridge 186:707f6e361f3e 1247
Anna Bridge 186:707f6e361f3e 1248 /** Configure serial interrupt. This function is used for word-approach
Anna Bridge 186:707f6e361f3e 1249 *
Anna Bridge 186:707f6e361f3e 1250 * Param obj The serial object
Anna Bridge 186:707f6e361f3e 1251 * Param irq The serial IRQ type (RX or TX)
Anna Bridge 186:707f6e361f3e 1252 * Param enable Set to non-zero to enable events, or zero to disable them
Anna Bridge 186:707f6e361f3e 1253 */
Anna Bridge 186:707f6e361f3e 1254 void serial_irq_set(serial_t *obj, SerialIrq irq, uint32_t enable)
Anna Bridge 186:707f6e361f3e 1255 {
Anna Bridge 186:707f6e361f3e 1256 MBED_ASSERT(obj);
Anna Bridge 186:707f6e361f3e 1257
Anna Bridge 186:707f6e361f3e 1258 #if DEVICE_SERIAL_ASYNCH
Anna Bridge 186:707f6e361f3e 1259 struct serial_s *uart_object = &obj->serial;
Anna Bridge 186:707f6e361f3e 1260 #else
Anna Bridge 186:707f6e361f3e 1261 struct serial_s *uart_object = obj;
Anna Bridge 186:707f6e361f3e 1262 #endif
Anna Bridge 186:707f6e361f3e 1263
Anna Bridge 186:707f6e361f3e 1264 /* Convert Mbed type to Nordic IRQ mask. */
Anna Bridge 186:707f6e361f3e 1265 uint32_t type = (irq == TxIrq) ? NORDIC_TX_IRQ : NORDIC_RX_IRQ;
Anna Bridge 186:707f6e361f3e 1266
Anna Bridge 186:707f6e361f3e 1267 /* Enable/disable interrupt bit mask. */
Anna Bridge 186:707f6e361f3e 1268 if (enable) {
Anna Bridge 186:707f6e361f3e 1269
Anna Bridge 186:707f6e361f3e 1270 uart_object->mask |= type;
AnnaBridge 189:f392fc9709a3 1271 nordic_nrf5_serial_configure(obj);
Anna Bridge 186:707f6e361f3e 1272
Anna Bridge 186:707f6e361f3e 1273 } else {
Anna Bridge 186:707f6e361f3e 1274
Anna Bridge 186:707f6e361f3e 1275 uart_object->mask &= ~type;
Anna Bridge 186:707f6e361f3e 1276 }
Anna Bridge 186:707f6e361f3e 1277 }
Anna Bridge 186:707f6e361f3e 1278
Anna Bridge 186:707f6e361f3e 1279 /** Get character. This is a blocking call, waiting for a character
Anna Bridge 186:707f6e361f3e 1280 *
Anna Bridge 186:707f6e361f3e 1281 * Param obj The serial object
Anna Bridge 186:707f6e361f3e 1282 */
Anna Bridge 186:707f6e361f3e 1283 int serial_getc(serial_t *obj)
Anna Bridge 186:707f6e361f3e 1284 {
Anna Bridge 186:707f6e361f3e 1285 MBED_ASSERT(obj);
Anna Bridge 186:707f6e361f3e 1286
Anna Bridge 186:707f6e361f3e 1287 #if DEVICE_SERIAL_ASYNCH
Anna Bridge 186:707f6e361f3e 1288 struct serial_s *uart_object = &obj->serial;
Anna Bridge 186:707f6e361f3e 1289 uart_object->rx_asynch = false;
Anna Bridge 186:707f6e361f3e 1290 #else
Anna Bridge 186:707f6e361f3e 1291 struct serial_s *uart_object = obj;
Anna Bridge 186:707f6e361f3e 1292 #endif
Anna Bridge 186:707f6e361f3e 1293
Anna Bridge 186:707f6e361f3e 1294 int instance = uart_object->instance;
Anna Bridge 186:707f6e361f3e 1295
Anna Bridge 186:707f6e361f3e 1296 /* Take ownership and configure UART if necessary. */
Anna Bridge 186:707f6e361f3e 1297 nordic_nrf5_serial_configure(obj);
Anna Bridge 186:707f6e361f3e 1298
Anna Bridge 186:707f6e361f3e 1299 /**
Anna Bridge 186:707f6e361f3e 1300 * Use head and tail pointer in FIFO to determine whether there is data available.
Anna Bridge 186:707f6e361f3e 1301 */
Anna Bridge 186:707f6e361f3e 1302 nrf_atfifo_t *fifo = nordic_nrf5_uart_state[instance].fifo;
Anna Bridge 186:707f6e361f3e 1303
Anna Bridge 186:707f6e361f3e 1304 volatile uint16_t *head = &fifo->head.pos.rd;
Anna Bridge 186:707f6e361f3e 1305 volatile uint16_t *tail = &fifo->tail.pos.rd;
Anna Bridge 186:707f6e361f3e 1306
Anna Bridge 186:707f6e361f3e 1307 /* serial_getc is a blocking call. */
Anna Bridge 186:707f6e361f3e 1308 while (*head == *tail);
Anna Bridge 186:707f6e361f3e 1309
AnnaBridge 187:0387e8f68319 1310 /* Get 1 byte from FIFO buffer. The buffer is atomic
AnnaBridge 187:0387e8f68319 1311 * and doesn't need to be protected in a critical section.
Anna Bridge 186:707f6e361f3e 1312 */
Anna Bridge 186:707f6e361f3e 1313 nrf_atfifo_item_get_t context;
Anna Bridge 186:707f6e361f3e 1314 uint8_t *byte = (uint8_t *) nrf_atfifo_item_get(fifo, &context);
Anna Bridge 186:707f6e361f3e 1315 nrf_atfifo_item_free(fifo, &context);
AnnaBridge 189:f392fc9709a3 1316 core_util_atomic_incr_u32(&nordic_nrf5_uart_state[instance].fifo_free_count, 1);
AnnaBridge 189:f392fc9709a3 1317 if (nordic_nrf5_uart_state[instance].rx_suspended) {
AnnaBridge 189:f392fc9709a3 1318 nordic_nrf5_uart_state[instance].rx_suspended = false;
AnnaBridge 189:f392fc9709a3 1319 nrf_drv_gpiote_clr_task_trigger(nordic_nrf5_uart_state[instance].rts);
AnnaBridge 188:bcfe06ba3d64 1320 }
AnnaBridge 188:bcfe06ba3d64 1321
Anna Bridge 186:707f6e361f3e 1322 return *byte;
Anna Bridge 186:707f6e361f3e 1323 }
Anna Bridge 186:707f6e361f3e 1324
Anna Bridge 186:707f6e361f3e 1325 /** Send a character. This is a blocking call, waiting for a peripheral to be available
Anna Bridge 186:707f6e361f3e 1326 * for writing
Anna Bridge 186:707f6e361f3e 1327 *
Anna Bridge 186:707f6e361f3e 1328 * Param obj The serial object
Anna Bridge 186:707f6e361f3e 1329 * Param c The character to be sent
Anna Bridge 186:707f6e361f3e 1330 */
Anna Bridge 186:707f6e361f3e 1331 void serial_putc(serial_t *obj, int character)
Anna Bridge 186:707f6e361f3e 1332 {
AnnaBridge 188:bcfe06ba3d64 1333 bool done = false;
Anna Bridge 186:707f6e361f3e 1334 MBED_ASSERT(obj);
Anna Bridge 186:707f6e361f3e 1335
Anna Bridge 186:707f6e361f3e 1336 #if DEVICE_SERIAL_ASYNCH
Anna Bridge 186:707f6e361f3e 1337 struct serial_s *uart_object = &obj->serial;
Anna Bridge 186:707f6e361f3e 1338 #else
Anna Bridge 186:707f6e361f3e 1339 struct serial_s *uart_object = obj;
Anna Bridge 186:707f6e361f3e 1340 #endif
Anna Bridge 186:707f6e361f3e 1341
Anna Bridge 186:707f6e361f3e 1342 int instance = uart_object->instance;
Anna Bridge 186:707f6e361f3e 1343
Anna Bridge 186:707f6e361f3e 1344 nordic_nrf5_serial_configure(obj);
AnnaBridge 189:f392fc9709a3 1345
AnnaBridge 189:f392fc9709a3 1346 /* Wait until UART is ready to send next character. */
AnnaBridge 189:f392fc9709a3 1347 do {
AnnaBridge 189:f392fc9709a3 1348 done = nrf_uarte_event_extra_check(nordic_nrf5_uart_register[instance], NRF_UARTE_EVENT_TXDRDY);
AnnaBridge 189:f392fc9709a3 1349 } while(done == false);
AnnaBridge 189:f392fc9709a3 1350
AnnaBridge 189:f392fc9709a3 1351 nrf_uarte_event_extra_clear(nordic_nrf5_uart_register[instance], NRF_UARTE_EVENT_TXDRDY);
AnnaBridge 189:f392fc9709a3 1352
Anna Bridge 186:707f6e361f3e 1353 /* Arm Tx DMA buffer. */
Anna Bridge 186:707f6e361f3e 1354 nordic_nrf5_uart_state[instance].tx_data = character;
Anna Bridge 186:707f6e361f3e 1355 nrf_uarte_tx_buffer_set(nordic_nrf5_uart_register[instance],
Anna Bridge 186:707f6e361f3e 1356 &nordic_nrf5_uart_state[instance].tx_data,
Anna Bridge 186:707f6e361f3e 1357 1);
Anna Bridge 186:707f6e361f3e 1358
AnnaBridge 189:f392fc9709a3 1359 /* Clear Tx event and enable Tx interrupts. */
AnnaBridge 189:f392fc9709a3 1360 nrf_uarte_event_clear(nordic_nrf5_uart_register[instance], NRF_UARTE_EVENT_ENDTX);
AnnaBridge 189:f392fc9709a3 1361 nrf_uarte_int_enable(nordic_nrf5_uart_register[instance], NRF_UARTE_INT_ENDTX_MASK);
Anna Bridge 186:707f6e361f3e 1362
AnnaBridge 189:f392fc9709a3 1363 /* Start transfer. */
AnnaBridge 189:f392fc9709a3 1364 nrf_uarte_task_trigger(nordic_nrf5_uart_register[instance], NRF_UARTE_TASK_STARTTX);
Anna Bridge 186:707f6e361f3e 1365 }
Anna Bridge 186:707f6e361f3e 1366
Anna Bridge 186:707f6e361f3e 1367 /** Check if the serial peripheral is readable
Anna Bridge 186:707f6e361f3e 1368 *
Anna Bridge 186:707f6e361f3e 1369 * Param obj The serial object
Anna Bridge 186:707f6e361f3e 1370 * Return Non-zero value if a character can be read, 0 if nothing to read
Anna Bridge 186:707f6e361f3e 1371 */
Anna Bridge 186:707f6e361f3e 1372 int serial_readable(serial_t *obj)
Anna Bridge 186:707f6e361f3e 1373 {
Anna Bridge 186:707f6e361f3e 1374 MBED_ASSERT(obj);
Anna Bridge 186:707f6e361f3e 1375
Anna Bridge 186:707f6e361f3e 1376 #if DEVICE_SERIAL_ASYNCH
Anna Bridge 186:707f6e361f3e 1377 struct serial_s *uart_object = &obj->serial;
Anna Bridge 186:707f6e361f3e 1378 uart_object->rx_asynch = false;
Anna Bridge 186:707f6e361f3e 1379 #else
Anna Bridge 186:707f6e361f3e 1380 struct serial_s *uart_object = obj;
Anna Bridge 186:707f6e361f3e 1381 #endif
Anna Bridge 186:707f6e361f3e 1382
Anna Bridge 186:707f6e361f3e 1383 int instance = uart_object->instance;
Anna Bridge 186:707f6e361f3e 1384
Anna Bridge 186:707f6e361f3e 1385 /* Take ownership and configure UART if necessary. */
Anna Bridge 186:707f6e361f3e 1386 nordic_nrf5_serial_configure(obj);
Anna Bridge 186:707f6e361f3e 1387
Anna Bridge 186:707f6e361f3e 1388 /**
Anna Bridge 186:707f6e361f3e 1389 * Use head and tail pointer in FIFO to determine whether there is data available.
Anna Bridge 186:707f6e361f3e 1390 */
Anna Bridge 186:707f6e361f3e 1391 nrf_atfifo_t *fifo = nordic_nrf5_uart_state[instance].fifo;
Anna Bridge 186:707f6e361f3e 1392
Anna Bridge 186:707f6e361f3e 1393 return (fifo->head.pos.rd != fifo->tail.pos.rd);
Anna Bridge 186:707f6e361f3e 1394 }
Anna Bridge 186:707f6e361f3e 1395
Anna Bridge 186:707f6e361f3e 1396 /** Check if the serial peripheral is writable
Anna Bridge 186:707f6e361f3e 1397 *
Anna Bridge 186:707f6e361f3e 1398 * Param obj The serial object
Anna Bridge 186:707f6e361f3e 1399 * Return Non-zero value if a character can be written, 0 otherwise.
Anna Bridge 186:707f6e361f3e 1400 */
Anna Bridge 186:707f6e361f3e 1401 int serial_writable(serial_t *obj)
Anna Bridge 186:707f6e361f3e 1402 {
Anna Bridge 186:707f6e361f3e 1403 MBED_ASSERT(obj);
Anna Bridge 186:707f6e361f3e 1404
Anna Bridge 186:707f6e361f3e 1405 #if DEVICE_SERIAL_ASYNCH
Anna Bridge 186:707f6e361f3e 1406 struct serial_s *uart_object = &obj->serial;
Anna Bridge 186:707f6e361f3e 1407 #else
Anna Bridge 186:707f6e361f3e 1408 struct serial_s *uart_object = obj;
Anna Bridge 186:707f6e361f3e 1409 #endif
Anna Bridge 186:707f6e361f3e 1410
Anna Bridge 186:707f6e361f3e 1411 int instance = uart_object->instance;
Anna Bridge 186:707f6e361f3e 1412
AnnaBridge 189:f392fc9709a3 1413 return ((nordic_nrf5_uart_state[instance].tx_in_progress == 0) &&
AnnaBridge 189:f392fc9709a3 1414 (nrf_uarte_event_extra_check(nordic_nrf5_uart_register[instance], NRF_UARTE_EVENT_TXDRDY)));
Anna Bridge 186:707f6e361f3e 1415 }
Anna Bridge 186:707f6e361f3e 1416
Anna Bridge 186:707f6e361f3e 1417 /***
AnnaBridge 187:0387e8f68319 1418 * _ _____ _____
Anna Bridge 186:707f6e361f3e 1419 * /\ | | /\ | __ \_ _|
AnnaBridge 187:0387e8f68319 1420 * / \ ___ _ _ _ __ ___| |__ _ __ ___ _ __ ___ _ _ ___ / \ | |__) || |
AnnaBridge 187:0387e8f68319 1421 * / /\ \ / __| | | | '_ \ / __| '_ \| '__/ _ \| '_ \ / _ \| | | / __| / /\ \ | ___/ | |
AnnaBridge 187:0387e8f68319 1422 * / ____ \\__ \ |_| | | | | (__| | | | | | (_) | | | | (_) | |_| \__ \ / ____ \| | _| |_
Anna Bridge 186:707f6e361f3e 1423 * /_/ \_\___/\__, |_| |_|\___|_| |_|_| \___/|_| |_|\___/ \__,_|___/ /_/ \_\_| |_____|
AnnaBridge 187:0387e8f68319 1424 * __/ |
AnnaBridge 187:0387e8f68319 1425 * |___/
Anna Bridge 186:707f6e361f3e 1426 */
Anna Bridge 186:707f6e361f3e 1427
Anna Bridge 186:707f6e361f3e 1428 #if DEVICE_SERIAL_ASYNCH
Anna Bridge 186:707f6e361f3e 1429
Anna Bridge 186:707f6e361f3e 1430 /** Begin asynchronous TX transfer. The used buffer is specified in the serial object,
Anna Bridge 186:707f6e361f3e 1431 * tx_buff
Anna Bridge 186:707f6e361f3e 1432 *
Anna Bridge 186:707f6e361f3e 1433 * Param obj The serial object
Anna Bridge 186:707f6e361f3e 1434 * Param tx The transmit buffer
Anna Bridge 186:707f6e361f3e 1435 * Param tx_length The number of bytes to transmit
Anna Bridge 186:707f6e361f3e 1436 * Param tx_width Deprecated argument
Anna Bridge 186:707f6e361f3e 1437 * Param handler The serial handler
Anna Bridge 186:707f6e361f3e 1438 * Param event The logical OR of events to be registered
Anna Bridge 186:707f6e361f3e 1439 * Param hint A suggestion for how to use DMA with this transfer
Anna Bridge 186:707f6e361f3e 1440 * Return Returns number of data transfered, otherwise returns 0
Anna Bridge 186:707f6e361f3e 1441 */
Anna Bridge 186:707f6e361f3e 1442 int serial_tx_asynch(serial_t *obj, const void *tx, size_t tx_length, uint8_t tx_width, uint32_t handler, uint32_t mask, DMAUsage hint)
Anna Bridge 186:707f6e361f3e 1443 {
Anna Bridge 186:707f6e361f3e 1444 MBED_ASSERT(obj);
Anna Bridge 186:707f6e361f3e 1445 MBED_ASSERT(tx_width == 8);
Anna Bridge 186:707f6e361f3e 1446 MBED_ASSERT(tx_length < 256);
Anna Bridge 186:707f6e361f3e 1447
Anna Bridge 186:707f6e361f3e 1448 int instance = obj->serial.instance;
Anna Bridge 186:707f6e361f3e 1449
Anna Bridge 186:707f6e361f3e 1450 /**
Anna Bridge 186:707f6e361f3e 1451 * tx_in_progress acts like a mutex to ensure only one transmission can be active at a time.
Anna Bridge 186:707f6e361f3e 1452 * The flag is modified using the atomic compare-and-set function.
Anna Bridge 186:707f6e361f3e 1453 */
Anna Bridge 186:707f6e361f3e 1454 bool mutex = false;
Anna Bridge 186:707f6e361f3e 1455
Anna Bridge 186:707f6e361f3e 1456 do {
Anna Bridge 186:707f6e361f3e 1457 uint8_t expected = 0;
Anna Bridge 186:707f6e361f3e 1458 uint8_t desired = 1;
Anna Bridge 186:707f6e361f3e 1459
Anna Bridge 186:707f6e361f3e 1460 mutex = core_util_atomic_cas_u8((uint8_t *) &nordic_nrf5_uart_state[instance].tx_in_progress, &expected, desired);
Anna Bridge 186:707f6e361f3e 1461 } while (mutex == false);
Anna Bridge 186:707f6e361f3e 1462
Anna Bridge 186:707f6e361f3e 1463 /* State variables. */
Anna Bridge 186:707f6e361f3e 1464 int result = 0;
Anna Bridge 186:707f6e361f3e 1465 bool valid = false;
Anna Bridge 186:707f6e361f3e 1466
Anna Bridge 186:707f6e361f3e 1467 /**
Anna Bridge 186:707f6e361f3e 1468 * EasyDMA can only access RAM. Check if provided buffer is in RAM or flash.
Anna Bridge 186:707f6e361f3e 1469 * If the buffer is in flash, check if the FIFO buffer is large enough to store
Anna Bridge 186:707f6e361f3e 1470 * the Tx data.
Anna Bridge 186:707f6e361f3e 1471 */
Anna Bridge 186:707f6e361f3e 1472 if (instance == 0) {
Anna Bridge 186:707f6e361f3e 1473
Anna Bridge 186:707f6e361f3e 1474 if (nrf_drv_is_in_RAM(tx) || (tx_length <= UART0_FIFO_BUFFER_SIZE)) {
Anna Bridge 186:707f6e361f3e 1475 valid = true;
Anna Bridge 186:707f6e361f3e 1476 }
AnnaBridge 187:0387e8f68319 1477 }
Anna Bridge 186:707f6e361f3e 1478 #if UART1_ENABLED
Anna Bridge 186:707f6e361f3e 1479 else {
Anna Bridge 186:707f6e361f3e 1480 if (nrf_drv_is_in_RAM(tx) || (tx_length <= UART1_FIFO_BUFFER_SIZE)) {
Anna Bridge 186:707f6e361f3e 1481 valid = true;
Anna Bridge 186:707f6e361f3e 1482 }
Anna Bridge 186:707f6e361f3e 1483 }
Anna Bridge 186:707f6e361f3e 1484 #endif
Anna Bridge 186:707f6e361f3e 1485
Anna Bridge 186:707f6e361f3e 1486 if (valid) {
Anna Bridge 186:707f6e361f3e 1487
Anna Bridge 186:707f6e361f3e 1488 /* Setup buffers for transfer. */
Anna Bridge 186:707f6e361f3e 1489 uint8_t *buffer = NULL;
Anna Bridge 186:707f6e361f3e 1490
Anna Bridge 186:707f6e361f3e 1491 /* Tx buffer is in RAM. */
Anna Bridge 186:707f6e361f3e 1492 if (nrf_drv_is_in_RAM(tx)) {
Anna Bridge 186:707f6e361f3e 1493
Anna Bridge 186:707f6e361f3e 1494 buffer = (uint8_t *) tx;
Anna Bridge 186:707f6e361f3e 1495 } else {
Anna Bridge 186:707f6e361f3e 1496
Anna Bridge 186:707f6e361f3e 1497 /**
Anna Bridge 186:707f6e361f3e 1498 * Tx buffer is in flash. Copy Tx buffer to FIFO buffer.
Anna Bridge 186:707f6e361f3e 1499 * NOTE: this prevents simultaneous Rx using non-asynchronous API.
Anna Bridge 186:707f6e361f3e 1500 */
Anna Bridge 186:707f6e361f3e 1501 const uint8_t *pointer = (const uint8_t *) tx;
Anna Bridge 186:707f6e361f3e 1502
Anna Bridge 186:707f6e361f3e 1503 for (size_t index = 0; index < tx_length; index++) {
Anna Bridge 186:707f6e361f3e 1504 nordic_nrf5_uart_fifo_0_data[index] = pointer[index];
Anna Bridge 186:707f6e361f3e 1505 }
Anna Bridge 186:707f6e361f3e 1506
AnnaBridge 187:0387e8f68319 1507 buffer = (uint8_t *) nordic_nrf5_uart_fifo_0_data;
Anna Bridge 186:707f6e361f3e 1508 }
Anna Bridge 186:707f6e361f3e 1509
Anna Bridge 186:707f6e361f3e 1510 /* Store callback handler, mask and reset event value. */
Anna Bridge 186:707f6e361f3e 1511 obj->serial.tx_handler = handler;
Anna Bridge 186:707f6e361f3e 1512 obj->serial.tx_mask = mask;
Anna Bridge 186:707f6e361f3e 1513 obj->serial.tx_event = 0;
Anna Bridge 186:707f6e361f3e 1514
Anna Bridge 186:707f6e361f3e 1515 /* Enable asynchronous mode and configure UART. */
Anna Bridge 186:707f6e361f3e 1516 nordic_nrf5_uart_state[instance].tx_asynch = true;
Anna Bridge 186:707f6e361f3e 1517 nordic_nrf5_serial_configure(obj);
Anna Bridge 186:707f6e361f3e 1518
Anna Bridge 186:707f6e361f3e 1519 /* Clear Tx event and enable Tx interrupts. */
Anna Bridge 186:707f6e361f3e 1520 nrf_uarte_event_clear(nordic_nrf5_uart_register[instance], NRF_UARTE_EVENT_ENDTX);
AnnaBridge 187:0387e8f68319 1521 nrf_uarte_int_enable(nordic_nrf5_uart_register[instance], NRF_UARTE_INT_ENDTX_MASK);
Anna Bridge 186:707f6e361f3e 1522
Anna Bridge 186:707f6e361f3e 1523 /* Set Tx DMA buffer. */
Anna Bridge 186:707f6e361f3e 1524 nrf_uarte_tx_buffer_set(nordic_nrf5_uart_register[obj->serial.instance],
Anna Bridge 186:707f6e361f3e 1525 buffer,
Anna Bridge 186:707f6e361f3e 1526 tx_length);
Anna Bridge 186:707f6e361f3e 1527
Anna Bridge 186:707f6e361f3e 1528 /* Trigger DMA transfer. */
Anna Bridge 186:707f6e361f3e 1529 nrf_uarte_task_trigger(nordic_nrf5_uart_register[obj->serial.instance],
Anna Bridge 186:707f6e361f3e 1530 NRF_UARTE_TASK_STARTTX);
Anna Bridge 186:707f6e361f3e 1531
Anna Bridge 186:707f6e361f3e 1532 /* Setup complete, return length as sign of success. */
Anna Bridge 186:707f6e361f3e 1533 result = tx_length;
Anna Bridge 186:707f6e361f3e 1534
Anna Bridge 186:707f6e361f3e 1535 } else {
Anna Bridge 186:707f6e361f3e 1536
Anna Bridge 186:707f6e361f3e 1537 /* Signal error if event mask matches and event handler is set. */
Anna Bridge 186:707f6e361f3e 1538 if ((mask & SERIAL_EVENT_ERROR) && handler) {
Anna Bridge 186:707f6e361f3e 1539
Anna Bridge 186:707f6e361f3e 1540 /* Cast handler to callback function pointer. */
Anna Bridge 186:707f6e361f3e 1541 void (*callback)(void) = (void (*)(void)) handler;
Anna Bridge 186:707f6e361f3e 1542
Anna Bridge 186:707f6e361f3e 1543 /* Store event value so it can be read back. */
Anna Bridge 186:707f6e361f3e 1544 obj->serial.event = SERIAL_EVENT_ERROR;
Anna Bridge 186:707f6e361f3e 1545
Anna Bridge 186:707f6e361f3e 1546 /* Signal callback handler. */
Anna Bridge 186:707f6e361f3e 1547 callback();
Anna Bridge 186:707f6e361f3e 1548 }
Anna Bridge 186:707f6e361f3e 1549 }
Anna Bridge 186:707f6e361f3e 1550
Anna Bridge 186:707f6e361f3e 1551 return result;
Anna Bridge 186:707f6e361f3e 1552 }
Anna Bridge 186:707f6e361f3e 1553
Anna Bridge 186:707f6e361f3e 1554 /** Begin asynchronous RX transfer (enable interrupt for data collecting)
Anna Bridge 186:707f6e361f3e 1555 * The used buffer is specified in the serial object - rx_buff
Anna Bridge 186:707f6e361f3e 1556 *
Anna Bridge 186:707f6e361f3e 1557 * Param obj The serial object
Anna Bridge 186:707f6e361f3e 1558 * Param rx The receive buffer
Anna Bridge 186:707f6e361f3e 1559 * Param rx_length The number of bytes to receive
Anna Bridge 186:707f6e361f3e 1560 * Param rx_width Deprecated argument
Anna Bridge 186:707f6e361f3e 1561 * Param handler The serial handler
Anna Bridge 186:707f6e361f3e 1562 * Param event The logical OR of events to be registered
Anna Bridge 186:707f6e361f3e 1563 * Param handler The serial handler
Anna Bridge 186:707f6e361f3e 1564 * Param char_match A character in range 0-254 to be matched
Anna Bridge 186:707f6e361f3e 1565 * Param hint A suggestion for how to use DMA with this transfer
Anna Bridge 186:707f6e361f3e 1566 */
Anna Bridge 186:707f6e361f3e 1567 void serial_rx_asynch(serial_t *obj, void *rx, size_t rx_length, uint8_t rx_width, uint32_t handler, uint32_t mask, uint8_t char_match, DMAUsage hint)
Anna Bridge 186:707f6e361f3e 1568 {
Anna Bridge 186:707f6e361f3e 1569 MBED_ASSERT(obj);
Anna Bridge 186:707f6e361f3e 1570 MBED_ASSERT(rx_width == 8);
Anna Bridge 186:707f6e361f3e 1571 MBED_ASSERT(rx_length < 256);
Anna Bridge 186:707f6e361f3e 1572 MBED_ASSERT(char_match == SERIAL_RESERVED_CHAR_MATCH); // EasyDMA based UART handling does not support char_match
Anna Bridge 186:707f6e361f3e 1573
Anna Bridge 186:707f6e361f3e 1574 int instance = obj->serial.instance;
Anna Bridge 186:707f6e361f3e 1575
Anna Bridge 186:707f6e361f3e 1576 /**
Anna Bridge 186:707f6e361f3e 1577 * rx_in_progress acts like a mutex to ensure only one asynchronous reception can be active at a time.
Anna Bridge 186:707f6e361f3e 1578 * The flag is modified using the atomic compare-and-set function.
Anna Bridge 186:707f6e361f3e 1579 */
Anna Bridge 186:707f6e361f3e 1580 bool mutex = false;
Anna Bridge 186:707f6e361f3e 1581
Anna Bridge 186:707f6e361f3e 1582 do {
Anna Bridge 186:707f6e361f3e 1583 uint8_t expected = 0;
Anna Bridge 186:707f6e361f3e 1584 uint8_t desired = 1;
Anna Bridge 186:707f6e361f3e 1585
Anna Bridge 186:707f6e361f3e 1586 mutex = core_util_atomic_cas_u8((uint8_t *) &nordic_nrf5_uart_state[instance].rx_in_progress, &expected, desired);
Anna Bridge 186:707f6e361f3e 1587 } while (mutex == false);
Anna Bridge 186:707f6e361f3e 1588
Anna Bridge 186:707f6e361f3e 1589 /* Store callback handler, mask and reset event value. */
Anna Bridge 186:707f6e361f3e 1590 obj->serial.rx_handler = handler;
Anna Bridge 186:707f6e361f3e 1591 obj->serial.rx_mask = mask;
Anna Bridge 186:707f6e361f3e 1592 obj->serial.rx_event = 0;
Anna Bridge 186:707f6e361f3e 1593
Anna Bridge 186:707f6e361f3e 1594 /* Enable asynchronous mode and configure UART. */
Anna Bridge 186:707f6e361f3e 1595 obj->serial.rx_asynch = true;
Anna Bridge 186:707f6e361f3e 1596 nordic_nrf5_serial_configure(obj);
Anna Bridge 186:707f6e361f3e 1597
Anna Bridge 186:707f6e361f3e 1598 /* Set Rx DMA buffer. */
Anna Bridge 186:707f6e361f3e 1599 nrf_uarte_rx_buffer_set(nordic_nrf5_uart_register[instance],
Anna Bridge 186:707f6e361f3e 1600 (uint8_t *) rx,
Anna Bridge 186:707f6e361f3e 1601 rx_length);
Anna Bridge 186:707f6e361f3e 1602
Anna Bridge 186:707f6e361f3e 1603 /* Enable reception. */
Anna Bridge 186:707f6e361f3e 1604 nrf_uarte_task_trigger(nordic_nrf5_uart_register[instance],
Anna Bridge 186:707f6e361f3e 1605 NRF_UARTE_TASK_STARTRX);
Anna Bridge 186:707f6e361f3e 1606
Anna Bridge 186:707f6e361f3e 1607 }
Anna Bridge 186:707f6e361f3e 1608
Anna Bridge 186:707f6e361f3e 1609 /** Attempts to determine if the serial peripheral is already in use for TX
Anna Bridge 186:707f6e361f3e 1610 *
Anna Bridge 186:707f6e361f3e 1611 * Param obj The serial object
Anna Bridge 186:707f6e361f3e 1612 * Return Non-zero if the RX transaction is ongoing, 0 otherwise
Anna Bridge 186:707f6e361f3e 1613 */
Anna Bridge 186:707f6e361f3e 1614 uint8_t serial_tx_active(serial_t *obj)
Anna Bridge 186:707f6e361f3e 1615 {
Anna Bridge 186:707f6e361f3e 1616 MBED_ASSERT(obj);
Anna Bridge 186:707f6e361f3e 1617
Anna Bridge 186:707f6e361f3e 1618 return nordic_nrf5_uart_state[obj->serial.instance].tx_asynch;
Anna Bridge 186:707f6e361f3e 1619 }
Anna Bridge 186:707f6e361f3e 1620
Anna Bridge 186:707f6e361f3e 1621 /** Attempts to determine if the serial peripheral is already in use for RX
Anna Bridge 186:707f6e361f3e 1622 *
Anna Bridge 186:707f6e361f3e 1623 * Param obj The serial object
Anna Bridge 186:707f6e361f3e 1624 * Return Non-zero if the RX transaction is ongoing, 0 otherwise
Anna Bridge 186:707f6e361f3e 1625 */
Anna Bridge 186:707f6e361f3e 1626 uint8_t serial_rx_active(serial_t *obj)
Anna Bridge 186:707f6e361f3e 1627 {
Anna Bridge 186:707f6e361f3e 1628 MBED_ASSERT(obj);
Anna Bridge 186:707f6e361f3e 1629
Anna Bridge 186:707f6e361f3e 1630 return nordic_nrf5_uart_state[obj->serial.instance].rx_asynch;
Anna Bridge 186:707f6e361f3e 1631 }
Anna Bridge 186:707f6e361f3e 1632
Anna Bridge 186:707f6e361f3e 1633 /** The asynchronous TX and RX handler.
Anna Bridge 186:707f6e361f3e 1634 *
Anna Bridge 186:707f6e361f3e 1635 * Param obj The serial object
Anna Bridge 186:707f6e361f3e 1636 * Return Returns event flags if an RX transfer termination condition was met; otherwise returns 0
Anna Bridge 186:707f6e361f3e 1637 */
Anna Bridge 186:707f6e361f3e 1638 int serial_irq_handler_asynch(serial_t *obj)
Anna Bridge 186:707f6e361f3e 1639 {
Anna Bridge 186:707f6e361f3e 1640 MBED_ASSERT(obj);
Anna Bridge 186:707f6e361f3e 1641
Anna Bridge 186:707f6e361f3e 1642 return (obj->serial.tx_event | obj->serial.rx_event);
Anna Bridge 186:707f6e361f3e 1643 }
Anna Bridge 186:707f6e361f3e 1644
Anna Bridge 186:707f6e361f3e 1645 /** Abort the ongoing TX transaction. It disables the enabled interupt for TX and
Anna Bridge 186:707f6e361f3e 1646 * flushes the TX hardware buffer if TX FIFO is used
Anna Bridge 186:707f6e361f3e 1647 *
Anna Bridge 186:707f6e361f3e 1648 * Param obj The serial object
Anna Bridge 186:707f6e361f3e 1649 */
Anna Bridge 186:707f6e361f3e 1650 void serial_tx_abort_asynch(serial_t *obj)
Anna Bridge 186:707f6e361f3e 1651 {
Anna Bridge 186:707f6e361f3e 1652 MBED_ASSERT(obj);
Anna Bridge 186:707f6e361f3e 1653
Anna Bridge 186:707f6e361f3e 1654 /* Transmission might be in progress. Disable interrupts to prevent ISR from firing. */
Anna Bridge 186:707f6e361f3e 1655 core_util_critical_section_enter();
Anna Bridge 186:707f6e361f3e 1656
Anna Bridge 186:707f6e361f3e 1657 int instance = obj->serial.instance;
Anna Bridge 186:707f6e361f3e 1658
Anna Bridge 186:707f6e361f3e 1659 /* Disable ENDTX interrupts. */
AnnaBridge 187:0387e8f68319 1660 nrf_uarte_int_disable(nordic_nrf5_uart_register[instance], NRF_UARTE_INT_ENDTX_MASK);
Anna Bridge 186:707f6e361f3e 1661
Anna Bridge 186:707f6e361f3e 1662 /* Clear ENDTX event. */
Anna Bridge 186:707f6e361f3e 1663 nrf_uarte_event_clear(nordic_nrf5_uart_register[instance], NRF_UARTE_EVENT_ENDTX);
Anna Bridge 186:707f6e361f3e 1664
Anna Bridge 186:707f6e361f3e 1665 /* Reset Tx flags. */
Anna Bridge 186:707f6e361f3e 1666 nordic_nrf5_uart_state[instance].tx_in_progress = 0;
Anna Bridge 186:707f6e361f3e 1667 nordic_nrf5_uart_state[instance].tx_asynch = false;
Anna Bridge 186:707f6e361f3e 1668
Anna Bridge 186:707f6e361f3e 1669 /* Force reconfiguration. */
Anna Bridge 186:707f6e361f3e 1670 obj->serial.update = true;
Anna Bridge 186:707f6e361f3e 1671 nordic_nrf5_serial_configure(obj);
Anna Bridge 186:707f6e361f3e 1672
Anna Bridge 186:707f6e361f3e 1673 /* Trigger STOP task. */
Anna Bridge 186:707f6e361f3e 1674 nrf_uarte_task_trigger(nordic_nrf5_uart_register[instance],
Anna Bridge 186:707f6e361f3e 1675 NRF_UARTE_TASK_STOPTX);
Anna Bridge 186:707f6e361f3e 1676
Anna Bridge 186:707f6e361f3e 1677 /* Enable interrupts again. */
Anna Bridge 186:707f6e361f3e 1678 core_util_critical_section_exit();
Anna Bridge 186:707f6e361f3e 1679 }
Anna Bridge 186:707f6e361f3e 1680
Anna Bridge 186:707f6e361f3e 1681 /** Abort the ongoing RX transaction. It disables the enabled interrupt for RX and
Anna Bridge 186:707f6e361f3e 1682 * flushes the RX hardware buffer if RX FIFO is used
Anna Bridge 186:707f6e361f3e 1683 *
Anna Bridge 186:707f6e361f3e 1684 * Param obj The serial object
Anna Bridge 186:707f6e361f3e 1685 */
Anna Bridge 186:707f6e361f3e 1686 void serial_rx_abort_asynch(serial_t *obj)
Anna Bridge 186:707f6e361f3e 1687 {
Anna Bridge 186:707f6e361f3e 1688 MBED_ASSERT(obj);
Anna Bridge 186:707f6e361f3e 1689
Anna Bridge 186:707f6e361f3e 1690 /* Transmission might be in progress. Disable interrupts to prevent ISR from firing. */
Anna Bridge 186:707f6e361f3e 1691 core_util_critical_section_enter();
Anna Bridge 186:707f6e361f3e 1692
Anna Bridge 186:707f6e361f3e 1693 /* Reset Rx flags. */
Anna Bridge 186:707f6e361f3e 1694 nordic_nrf5_uart_state[obj->serial.instance].rx_in_progress = 0;
Anna Bridge 186:707f6e361f3e 1695 nordic_nrf5_uart_state[obj->serial.instance].rx_asynch = false;
Anna Bridge 186:707f6e361f3e 1696 obj->serial.rx_asynch = false;
Anna Bridge 186:707f6e361f3e 1697
Anna Bridge 186:707f6e361f3e 1698 /* Force reconfiguration. */
Anna Bridge 186:707f6e361f3e 1699 obj->serial.update = true;
Anna Bridge 186:707f6e361f3e 1700 nordic_nrf5_serial_configure(obj);
Anna Bridge 186:707f6e361f3e 1701
Anna Bridge 186:707f6e361f3e 1702 /* Enable interrupts again. */
Anna Bridge 186:707f6e361f3e 1703 core_util_critical_section_exit();
Anna Bridge 186:707f6e361f3e 1704 }
Anna Bridge 186:707f6e361f3e 1705
Anna Bridge 186:707f6e361f3e 1706 #endif // DEVICE_SERIAL_ASYNCH
Anna Bridge 186:707f6e361f3e 1707
Anna Bridge 186:707f6e361f3e 1708 #endif // DEVICE_SERIAL