mbed library sources. Supersedes mbed-src. Fixed broken STM32F1xx RTC on rtc_api.c

Dependents:   Nucleo_F103RB_RTC_battery_bkup_pwr_off_okay

Fork of mbed-dev by mbed official

Committer:
maxxir
Date:
Tue Nov 07 16:46:29 2017 +0000
Revision:
177:619788de047e
Parent:
165:e614a9f1c9e2
To fix broken RTC on Nucleo_F103RB / STM32F103 BluePill etc..;  Used direct RTC register manipulation for STM32F1xx;  rtc_read() && rtc_write()  (native rtc_init() - works good);  also added stub for non-working on STM32F1xx rtc_read_subseconds().

Who changed what in which revision?

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