mbed library sources. Supersedes mbed-src.

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

Committer:
AnnaBridge
Date:
Wed Feb 20 22:31:08 2019 +0000
Revision:
189:f392fc9709a3
Parent:
181:57724642e740
mbed library release version 165

Who changed what in which revision?

UserRevisionLine numberNew contents of line
AnnaBridge 181:57724642e740 1 /* mbed Microcontroller Library
AnnaBridge 181:57724642e740 2 * Copyright (c) 2006-2015 ARM Limited
AnnaBridge 181:57724642e740 3 *
AnnaBridge 181:57724642e740 4 * Licensed under the Apache License, Version 2.0 (the "License");
AnnaBridge 181:57724642e740 5 * you may not use this file except in compliance with the License.
AnnaBridge 181:57724642e740 6 * You may obtain a copy of the License at
AnnaBridge 181:57724642e740 7 *
AnnaBridge 181:57724642e740 8 * http://www.apache.org/licenses/LICENSE-2.0
AnnaBridge 181:57724642e740 9 *
AnnaBridge 181:57724642e740 10 * Unless required by applicable law or agreed to in writing, software
AnnaBridge 181:57724642e740 11 * distributed under the License is distributed on an "AS IS" BASIS,
AnnaBridge 181:57724642e740 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
AnnaBridge 181:57724642e740 13 * See the License for the specific language governing permissions and
AnnaBridge 181:57724642e740 14 * limitations under the License.
AnnaBridge 181:57724642e740 15 */
AnnaBridge 181:57724642e740 16 // math.h required for floating point operations for baud rate calculation
AnnaBridge 181:57724642e740 17 #include "mbed_assert.h"
AnnaBridge 181:57724642e740 18 #include <math.h>
AnnaBridge 181:57724642e740 19 #include <string.h>
AnnaBridge 181:57724642e740 20 #include <stdlib.h>
AnnaBridge 181:57724642e740 21
AnnaBridge 181:57724642e740 22 #include "serial_api.h"
AnnaBridge 181:57724642e740 23 #include "cmsis.h"
AnnaBridge 181:57724642e740 24 #include "PeripheralPins.h"
AnnaBridge 181:57724642e740 25 #include "gpio_api.h"
AnnaBridge 181:57724642e740 26 #include "RZ_A1_Init.h"
AnnaBridge 181:57724642e740 27
AnnaBridge 181:57724642e740 28 #include "iodefine.h"
AnnaBridge 181:57724642e740 29 #include "mbed_drv_cfg.h"
AnnaBridge 181:57724642e740 30 #include "mbed_critical.h"
AnnaBridge 181:57724642e740 31
AnnaBridge 181:57724642e740 32 /******************************************************************************
AnnaBridge 181:57724642e740 33 * INITIALIZATION
AnnaBridge 181:57724642e740 34 ******************************************************************************/
AnnaBridge 181:57724642e740 35 #if defined(TARGET_RZA1H)
AnnaBridge 181:57724642e740 36 #define UART_NUM 8
AnnaBridge 181:57724642e740 37 #else
AnnaBridge 181:57724642e740 38 #define UART_NUM 5
AnnaBridge 181:57724642e740 39 #endif
AnnaBridge 181:57724642e740 40 #define IRQ_NUM 4
AnnaBridge 181:57724642e740 41
AnnaBridge 181:57724642e740 42 static void uart0_tx_irq(void);
AnnaBridge 181:57724642e740 43 static void uart0_rx_irq(void);
AnnaBridge 181:57724642e740 44 static void uart0_er_irq(void);
AnnaBridge 181:57724642e740 45 static void uart1_tx_irq(void);
AnnaBridge 181:57724642e740 46 static void uart1_rx_irq(void);
AnnaBridge 181:57724642e740 47 static void uart1_er_irq(void);
AnnaBridge 181:57724642e740 48 static void uart2_tx_irq(void);
AnnaBridge 181:57724642e740 49 static void uart2_rx_irq(void);
AnnaBridge 181:57724642e740 50 static void uart2_er_irq(void);
AnnaBridge 181:57724642e740 51 static void uart3_tx_irq(void);
AnnaBridge 181:57724642e740 52 static void uart3_rx_irq(void);
AnnaBridge 181:57724642e740 53 static void uart3_er_irq(void);
AnnaBridge 181:57724642e740 54 static void uart4_tx_irq(void);
AnnaBridge 181:57724642e740 55 static void uart4_rx_irq(void);
AnnaBridge 181:57724642e740 56 static void uart4_er_irq(void);
AnnaBridge 181:57724642e740 57 #if defined(TARGET_RZA1H)
AnnaBridge 181:57724642e740 58 static void uart5_tx_irq(void);
AnnaBridge 181:57724642e740 59 static void uart5_rx_irq(void);
AnnaBridge 181:57724642e740 60 static void uart5_er_irq(void);
AnnaBridge 181:57724642e740 61 static void uart6_tx_irq(void);
AnnaBridge 181:57724642e740 62 static void uart6_rx_irq(void);
AnnaBridge 181:57724642e740 63 static void uart6_er_irq(void);
AnnaBridge 181:57724642e740 64 static void uart7_tx_irq(void);
AnnaBridge 181:57724642e740 65 static void uart7_rx_irq(void);
AnnaBridge 181:57724642e740 66 static void uart7_er_irq(void);
AnnaBridge 181:57724642e740 67 #endif
AnnaBridge 181:57724642e740 68
AnnaBridge 181:57724642e740 69 static void serial_put_done(serial_t *obj);
AnnaBridge 181:57724642e740 70 static uint8_t serial_available_buffer(serial_t *obj);
AnnaBridge 181:57724642e740 71 static void serial_irq_err_set(serial_t *obj, uint32_t enable);
AnnaBridge 181:57724642e740 72
AnnaBridge 181:57724642e740 73 static const struct st_scif *SCIF[] = SCIF_ADDRESS_LIST;
AnnaBridge 181:57724642e740 74 static uart_irq_handler irq_handler;
AnnaBridge 181:57724642e740 75
AnnaBridge 181:57724642e740 76 int stdio_uart_inited = 0;
AnnaBridge 181:57724642e740 77 serial_t stdio_uart;
AnnaBridge 181:57724642e740 78
AnnaBridge 181:57724642e740 79 struct serial_global_data_s {
AnnaBridge 181:57724642e740 80 uint32_t serial_irq_id;
AnnaBridge 181:57724642e740 81 gpio_t sw_rts, sw_cts;
AnnaBridge 181:57724642e740 82 serial_t *tranferring_obj, *receiving_obj;
AnnaBridge 181:57724642e740 83 uint32_t async_tx_callback, async_rx_callback;
AnnaBridge 181:57724642e740 84 int event, wanted_rx_events;
AnnaBridge 181:57724642e740 85 };
AnnaBridge 181:57724642e740 86
AnnaBridge 181:57724642e740 87 static struct serial_global_data_s uart_data[UART_NUM];
AnnaBridge 181:57724642e740 88
AnnaBridge 181:57724642e740 89 static const IRQn_Type irq_set_tbl[UART_NUM][IRQ_NUM] = {
AnnaBridge 181:57724642e740 90 {SCIFRXI0_IRQn, SCIFTXI0_IRQn, SCIFBRI0_IRQn, SCIFERI0_IRQn},
AnnaBridge 181:57724642e740 91 {SCIFRXI1_IRQn, SCIFTXI1_IRQn, SCIFBRI1_IRQn, SCIFERI1_IRQn},
AnnaBridge 181:57724642e740 92 {SCIFRXI2_IRQn, SCIFTXI2_IRQn, SCIFBRI2_IRQn, SCIFERI2_IRQn},
AnnaBridge 181:57724642e740 93 {SCIFRXI3_IRQn, SCIFTXI3_IRQn, SCIFBRI3_IRQn, SCIFERI3_IRQn},
AnnaBridge 181:57724642e740 94 {SCIFRXI4_IRQn, SCIFTXI4_IRQn, SCIFBRI4_IRQn, SCIFERI4_IRQn},
AnnaBridge 181:57724642e740 95 #if defined(TARGET_RZA1H)
AnnaBridge 181:57724642e740 96 {SCIFRXI5_IRQn, SCIFTXI5_IRQn, SCIFBRI5_IRQn, SCIFERI5_IRQn},
AnnaBridge 181:57724642e740 97 {SCIFRXI6_IRQn, SCIFTXI6_IRQn, SCIFBRI6_IRQn, SCIFERI6_IRQn},
AnnaBridge 181:57724642e740 98 {SCIFRXI7_IRQn, SCIFTXI7_IRQn, SCIFBRI7_IRQn, SCIFERI7_IRQn},
AnnaBridge 181:57724642e740 99 #endif
AnnaBridge 181:57724642e740 100 };
AnnaBridge 181:57724642e740 101
AnnaBridge 181:57724642e740 102 static const IRQHandler hander_set_tbl[UART_NUM][IRQ_NUM] = {
AnnaBridge 181:57724642e740 103 {uart0_rx_irq, uart0_tx_irq, uart0_er_irq, uart0_er_irq},
AnnaBridge 181:57724642e740 104 {uart1_rx_irq, uart1_tx_irq, uart1_er_irq, uart1_er_irq},
AnnaBridge 181:57724642e740 105 {uart2_rx_irq, uart2_tx_irq, uart2_er_irq, uart2_er_irq},
AnnaBridge 181:57724642e740 106 {uart3_rx_irq, uart3_tx_irq, uart3_er_irq, uart3_er_irq},
AnnaBridge 181:57724642e740 107 {uart4_rx_irq, uart4_tx_irq, uart4_er_irq, uart4_er_irq},
AnnaBridge 181:57724642e740 108 #if defined(TARGET_RZA1H)
AnnaBridge 181:57724642e740 109 {uart5_rx_irq, uart5_tx_irq, uart5_er_irq, uart5_er_irq},
AnnaBridge 181:57724642e740 110 {uart6_rx_irq, uart6_tx_irq, uart6_er_irq, uart6_er_irq},
AnnaBridge 181:57724642e740 111 {uart7_rx_irq, uart7_tx_irq, uart7_er_irq, uart7_er_irq},
AnnaBridge 181:57724642e740 112 #endif
AnnaBridge 181:57724642e740 113 };
AnnaBridge 181:57724642e740 114
AnnaBridge 181:57724642e740 115 static __IO uint16_t *SCSCR_MATCH[] = {
AnnaBridge 181:57724642e740 116 &SCSCR_0,
AnnaBridge 181:57724642e740 117 &SCSCR_1,
AnnaBridge 181:57724642e740 118 &SCSCR_2,
AnnaBridge 181:57724642e740 119 &SCSCR_3,
AnnaBridge 181:57724642e740 120 &SCSCR_4,
AnnaBridge 181:57724642e740 121 #if defined(TARGET_RZA1H)
AnnaBridge 181:57724642e740 122 &SCSCR_5,
AnnaBridge 181:57724642e740 123 &SCSCR_6,
AnnaBridge 181:57724642e740 124 &SCSCR_7,
AnnaBridge 181:57724642e740 125 #endif
AnnaBridge 181:57724642e740 126 };
AnnaBridge 181:57724642e740 127
AnnaBridge 181:57724642e740 128 static __IO uint16_t *SCFSR_MATCH[] = {
AnnaBridge 181:57724642e740 129 &SCFSR_0,
AnnaBridge 181:57724642e740 130 &SCFSR_1,
AnnaBridge 181:57724642e740 131 &SCFSR_2,
AnnaBridge 181:57724642e740 132 &SCFSR_3,
AnnaBridge 181:57724642e740 133 &SCFSR_4,
AnnaBridge 181:57724642e740 134 #if defined(TARGET_RZA1H)
AnnaBridge 181:57724642e740 135 &SCFSR_5,
AnnaBridge 181:57724642e740 136 &SCFSR_6,
AnnaBridge 181:57724642e740 137 &SCFSR_7,
AnnaBridge 181:57724642e740 138 #endif
AnnaBridge 181:57724642e740 139 };
AnnaBridge 181:57724642e740 140
AnnaBridge 181:57724642e740 141
AnnaBridge 181:57724642e740 142 void serial_init(serial_t *obj, PinName tx, PinName rx) {
AnnaBridge 181:57724642e740 143 volatile uint8_t dummy ;
AnnaBridge 181:57724642e740 144 int is_stdio_uart = 0;
AnnaBridge 181:57724642e740 145 // determine the UART to use
AnnaBridge 181:57724642e740 146 uint32_t uart_tx = pinmap_peripheral(tx, PinMap_UART_TX);
AnnaBridge 181:57724642e740 147 uint32_t uart_rx = pinmap_peripheral(rx, PinMap_UART_RX);
AnnaBridge 181:57724642e740 148 uint32_t uart = pinmap_merge(uart_tx, uart_rx);
AnnaBridge 181:57724642e740 149
AnnaBridge 181:57724642e740 150 MBED_ASSERT((int)uart != NC);
AnnaBridge 181:57724642e740 151
AnnaBridge 181:57724642e740 152 obj->serial.uart = (struct st_scif *)SCIF[uart];
AnnaBridge 181:57724642e740 153 // enable power
AnnaBridge 181:57724642e740 154 CPG.STBCR4 &= ~(1 << (7 - uart));
AnnaBridge 181:57724642e740 155 dummy = CPG.STBCR4;
AnnaBridge 181:57724642e740 156
AnnaBridge 181:57724642e740 157 /* ==== SCIF initial setting ==== */
AnnaBridge 181:57724642e740 158 /* ---- Serial control register (SCSCR) setting ---- */
AnnaBridge 181:57724642e740 159 /* B'00 : Internal CLK */
AnnaBridge 181:57724642e740 160 obj->serial.uart->SCSCR = 0x0000u; /* SCIF transmitting and receiving operations stop */
AnnaBridge 181:57724642e740 161
AnnaBridge 181:57724642e740 162 /* ---- FIFO control register (SCFCR) setting ---- */
AnnaBridge 181:57724642e740 163 /* Transmit FIFO reset & Receive FIFO data register reset */
AnnaBridge 181:57724642e740 164 obj->serial.uart->SCFCR = 0x0006u;
AnnaBridge 181:57724642e740 165
AnnaBridge 181:57724642e740 166 /* ---- Serial status register (SCFSR) setting ---- */
AnnaBridge 181:57724642e740 167 dummy = obj->serial.uart->SCFSR;
AnnaBridge 181:57724642e740 168 obj->serial.uart->SCFSR = (dummy & 0xFF6Cu); /* ER,BRK,DR bit clear */
AnnaBridge 181:57724642e740 169
AnnaBridge 181:57724642e740 170 /* ---- Line status register (SCLSR) setting ---- */
AnnaBridge 181:57724642e740 171 /* ORER bit clear */
AnnaBridge 181:57724642e740 172 obj->serial.uart->SCLSR = 0;
AnnaBridge 181:57724642e740 173
AnnaBridge 181:57724642e740 174 /* ---- Serial extension mode register (SCEMR) setting ----
AnnaBridge 181:57724642e740 175 b7 BGDM - Baud rate generator double-speed mode : Normal mode
AnnaBridge 181:57724642e740 176 b0 ABCS - Base clock select in asynchronous mode : Base clock is 16 times the bit rate */
AnnaBridge 181:57724642e740 177 obj->serial.uart->SCEMR = 0x0000u;
AnnaBridge 181:57724642e740 178
AnnaBridge 181:57724642e740 179 /* ---- Bit rate register (SCBRR) setting ---- */
AnnaBridge 181:57724642e740 180 serial_baud (obj, 9600);
AnnaBridge 181:57724642e740 181 serial_format(obj, 8, ParityNone, 1);
AnnaBridge 181:57724642e740 182
AnnaBridge 181:57724642e740 183 /* ---- FIFO control register (SCFCR) setting ---- */
AnnaBridge 181:57724642e740 184 obj->serial.uart->SCFCR = 0x0030u;
AnnaBridge 181:57724642e740 185
AnnaBridge 181:57724642e740 186 /* ---- Serial port register (SCSPTR) setting ----
AnnaBridge 181:57724642e740 187 b1 SPB2IO - Serial port break output : disabled
AnnaBridge 181:57724642e740 188 b0 SPB2DT - Serial port break data : High-level */
AnnaBridge 181:57724642e740 189 obj->serial.uart->SCSPTR = 0x0003u; // SPB2IO = 1, SPB2DT = 1
AnnaBridge 181:57724642e740 190
AnnaBridge 181:57724642e740 191 /* ---- Line status register (SCLSR) setting ----
AnnaBridge 181:57724642e740 192 b0 ORER - Overrun error detect : clear */
AnnaBridge 181:57724642e740 193
AnnaBridge 181:57724642e740 194 if (obj->serial.uart->SCLSR & 0x0001) {
AnnaBridge 181:57724642e740 195 obj->serial.uart->SCLSR = 0u; // ORER clear
AnnaBridge 181:57724642e740 196 }
AnnaBridge 181:57724642e740 197
AnnaBridge 181:57724642e740 198 // pinout the chosen uart
AnnaBridge 181:57724642e740 199 pinmap_pinout(tx, PinMap_UART_TX);
AnnaBridge 181:57724642e740 200 pinmap_pinout(rx, PinMap_UART_RX);
AnnaBridge 181:57724642e740 201
AnnaBridge 181:57724642e740 202 obj->serial.index = uart;
AnnaBridge 181:57724642e740 203
AnnaBridge 181:57724642e740 204 uart_data[obj->serial.index].sw_rts.pin = NC;
AnnaBridge 181:57724642e740 205 uart_data[obj->serial.index].sw_cts.pin = NC;
AnnaBridge 181:57724642e740 206
AnnaBridge 181:57724642e740 207 /* ---- Serial control register (SCSCR) setting ---- */
AnnaBridge 181:57724642e740 208 /* Setting the TE and RE bits enables the TxD and RxD pins to be used. */
AnnaBridge 181:57724642e740 209 obj->serial.uart->SCSCR = 0x0070;
AnnaBridge 181:57724642e740 210
AnnaBridge 181:57724642e740 211 is_stdio_uart = (uart == STDIO_UART) ? (1) : (0);
AnnaBridge 181:57724642e740 212
AnnaBridge 181:57724642e740 213 if (is_stdio_uart) {
AnnaBridge 181:57724642e740 214 stdio_uart_inited = 1;
AnnaBridge 181:57724642e740 215 memcpy(&stdio_uart, obj, sizeof(serial_t));
AnnaBridge 181:57724642e740 216 }
AnnaBridge 181:57724642e740 217 }
AnnaBridge 181:57724642e740 218
AnnaBridge 181:57724642e740 219 void serial_free(serial_t *obj) {
AnnaBridge 181:57724642e740 220 uart_data[obj->serial.index].serial_irq_id = 0;
AnnaBridge 181:57724642e740 221 }
AnnaBridge 181:57724642e740 222
AnnaBridge 181:57724642e740 223 // serial_baud
AnnaBridge 181:57724642e740 224 // set the baud rate, taking in to account the current SystemFrequency
AnnaBridge 181:57724642e740 225 void serial_baud(serial_t *obj, int baudrate) {
AnnaBridge 181:57724642e740 226 uint32_t pclk_base;
AnnaBridge 181:57724642e740 227 uint32_t bgdm = 1;
AnnaBridge 181:57724642e740 228 uint32_t cks = 0;
AnnaBridge 181:57724642e740 229 uint32_t DL;
AnnaBridge 181:57724642e740 230
AnnaBridge 181:57724642e740 231 if (RZ_A1_IsClockMode0() == false) {
AnnaBridge 181:57724642e740 232 pclk_base = CM1_RENESAS_RZ_A1_P1_CLK;
AnnaBridge 181:57724642e740 233 } else {
AnnaBridge 181:57724642e740 234 pclk_base = CM0_RENESAS_RZ_A1_P1_CLK;
AnnaBridge 181:57724642e740 235 }
AnnaBridge 181:57724642e740 236
AnnaBridge 181:57724642e740 237 if (baudrate > (int)(pclk_base / 0x800)) {
AnnaBridge 181:57724642e740 238 obj->serial.uart->SCSMR &= ~0x0003;
AnnaBridge 181:57724642e740 239 obj->serial.uart->SCEMR = 0x0081; // BGDM = 1, ABCS = 1
AnnaBridge 181:57724642e740 240 DL = (pclk_base + (4 * baudrate)) / (8 * baudrate); // Rounding
AnnaBridge 181:57724642e740 241 if (DL > 0) {
AnnaBridge 181:57724642e740 242 DL--;
AnnaBridge 181:57724642e740 243 }
AnnaBridge 181:57724642e740 244 obj->serial.uart->SCBRR = (uint8_t)DL;
AnnaBridge 181:57724642e740 245 } else if (baudrate < (int)(pclk_base / 0x80000)) {
AnnaBridge 181:57724642e740 246 obj->serial.uart->SCSMR |= 0x0003;
AnnaBridge 181:57724642e740 247 obj->serial.uart->SCEMR = 0x0000;
AnnaBridge 181:57724642e740 248 obj->serial.uart->SCBRR = 0xFFu;
AnnaBridge 181:57724642e740 249 } else {
AnnaBridge 181:57724642e740 250 DL = (pclk_base + (8 * baudrate)) / (16 * baudrate); // Rounding
AnnaBridge 181:57724642e740 251 while (DL > 256) {
AnnaBridge 181:57724642e740 252 DL >>= 1;
AnnaBridge 181:57724642e740 253 if (bgdm == 1) {
AnnaBridge 181:57724642e740 254 bgdm = 0;
AnnaBridge 181:57724642e740 255 } else {
AnnaBridge 181:57724642e740 256 bgdm = 1;
AnnaBridge 181:57724642e740 257 cks++;
AnnaBridge 181:57724642e740 258 }
AnnaBridge 181:57724642e740 259 }
AnnaBridge 181:57724642e740 260 obj->serial.uart->SCSMR = (obj->serial.uart->SCSMR & ~0x0003) | (uint8_t)cks;
AnnaBridge 181:57724642e740 261 obj->serial.uart->SCEMR = (uint8_t)(bgdm << 7);
AnnaBridge 181:57724642e740 262 obj->serial.uart->SCBRR = (uint8_t)(DL - 1);
AnnaBridge 181:57724642e740 263 }
AnnaBridge 181:57724642e740 264 }
AnnaBridge 181:57724642e740 265
AnnaBridge 181:57724642e740 266 void serial_format(serial_t *obj, int data_bits, SerialParity parity, int stop_bits) {
AnnaBridge 181:57724642e740 267 int parity_enable;
AnnaBridge 181:57724642e740 268 int parity_select;
AnnaBridge 181:57724642e740 269
AnnaBridge 181:57724642e740 270 MBED_ASSERT((stop_bits == 1) || (stop_bits == 2)); // 0: 1 stop bits, 1: 2 stop bits
AnnaBridge 181:57724642e740 271 MBED_ASSERT((data_bits > 4) && (data_bits < 9)); // 5: 5 data bits ... 3: 8 data bits
AnnaBridge 181:57724642e740 272 MBED_ASSERT((parity == ParityNone) || (parity == ParityOdd) || (parity == ParityEven) ||
AnnaBridge 181:57724642e740 273 (parity == ParityForced1) || (parity == ParityForced0));
AnnaBridge 181:57724642e740 274
AnnaBridge 181:57724642e740 275 stop_bits = (stop_bits == 1)? 0:
AnnaBridge 181:57724642e740 276 (stop_bits == 2)? 1:
AnnaBridge 181:57724642e740 277 0; // must not to be
AnnaBridge 181:57724642e740 278
AnnaBridge 181:57724642e740 279 data_bits = (data_bits == 8)? 0:
AnnaBridge 181:57724642e740 280 (data_bits == 7)? 1:
AnnaBridge 181:57724642e740 281 0; // must not to be
AnnaBridge 181:57724642e740 282
AnnaBridge 181:57724642e740 283 switch (parity) {
AnnaBridge 181:57724642e740 284 case ParityNone:
AnnaBridge 181:57724642e740 285 parity_enable = 0;
AnnaBridge 181:57724642e740 286 parity_select = 0;
AnnaBridge 181:57724642e740 287 break;
AnnaBridge 181:57724642e740 288 case ParityOdd:
AnnaBridge 181:57724642e740 289 parity_enable = 1;
AnnaBridge 181:57724642e740 290 parity_select = 1;
AnnaBridge 181:57724642e740 291 break;
AnnaBridge 181:57724642e740 292 case ParityEven:
AnnaBridge 181:57724642e740 293 parity_enable = 1;
AnnaBridge 181:57724642e740 294 parity_select = 0;
AnnaBridge 181:57724642e740 295 break;
AnnaBridge 181:57724642e740 296 case ParityForced1:
AnnaBridge 181:57724642e740 297 case ParityForced0:
AnnaBridge 181:57724642e740 298 default:
AnnaBridge 181:57724642e740 299 parity_enable = 0;
AnnaBridge 181:57724642e740 300 parity_select = 0;
AnnaBridge 181:57724642e740 301 break;
AnnaBridge 181:57724642e740 302 }
AnnaBridge 181:57724642e740 303
AnnaBridge 181:57724642e740 304 obj->serial.uart->SCSMR = data_bits << 6
AnnaBridge 181:57724642e740 305 | parity_enable << 5
AnnaBridge 181:57724642e740 306 | parity_select << 4
AnnaBridge 181:57724642e740 307 | stop_bits << 3;
AnnaBridge 181:57724642e740 308 }
AnnaBridge 181:57724642e740 309
AnnaBridge 181:57724642e740 310 /******************************************************************************
AnnaBridge 181:57724642e740 311 * INTERRUPTS HANDLING
AnnaBridge 181:57724642e740 312 ******************************************************************************/
AnnaBridge 181:57724642e740 313
AnnaBridge 181:57724642e740 314 static void uart_tx_irq(IRQn_Type irq_num, uint32_t index) {
AnnaBridge 181:57724642e740 315 __IO uint16_t *dmy_rd_scscr;
AnnaBridge 181:57724642e740 316 __IO uint16_t *dmy_rd_scfsr;
AnnaBridge 181:57724642e740 317 serial_t *obj;
AnnaBridge 181:57724642e740 318 int i;
AnnaBridge 181:57724642e740 319
AnnaBridge 181:57724642e740 320 dmy_rd_scscr = SCSCR_MATCH[index];
AnnaBridge 181:57724642e740 321 *dmy_rd_scscr &= 0x007B; // Clear TIE and Write to bit15~8,2 is always 0
AnnaBridge 181:57724642e740 322 dmy_rd_scfsr = SCFSR_MATCH[index];
AnnaBridge 181:57724642e740 323 *dmy_rd_scfsr = (*dmy_rd_scfsr & ~0x0020); // Set TEND
AnnaBridge 181:57724642e740 324
AnnaBridge 181:57724642e740 325 obj = uart_data[index].tranferring_obj;
AnnaBridge 181:57724642e740 326 if (obj) {
AnnaBridge 181:57724642e740 327 i = obj->tx_buff.length - obj->tx_buff.pos;
AnnaBridge 181:57724642e740 328 if (0 < i) {
AnnaBridge 181:57724642e740 329 if (serial_available_buffer(obj) < i) {
AnnaBridge 181:57724642e740 330 i = serial_available_buffer(obj);
AnnaBridge 181:57724642e740 331 }
AnnaBridge 181:57724642e740 332 do {
AnnaBridge 181:57724642e740 333 uint8_t c = *(uint8_t *)obj->tx_buff.buffer;
AnnaBridge 181:57724642e740 334 obj->tx_buff.buffer = (uint8_t *)obj->tx_buff.buffer + 1;
AnnaBridge 181:57724642e740 335 ++obj->tx_buff.pos;
AnnaBridge 181:57724642e740 336 obj->serial.uart->SCFTDR = c;
AnnaBridge 181:57724642e740 337 } while (--i);
AnnaBridge 181:57724642e740 338 serial_put_done(obj);
AnnaBridge 181:57724642e740 339 } else {
AnnaBridge 181:57724642e740 340 uart_data[index].tranferring_obj = NULL;
AnnaBridge 181:57724642e740 341 uart_data[index].event = SERIAL_EVENT_TX_COMPLETE;
AnnaBridge 181:57724642e740 342 ((void (*)())uart_data[index].async_tx_callback)();
AnnaBridge 181:57724642e740 343 }
AnnaBridge 181:57724642e740 344 }
AnnaBridge 181:57724642e740 345
AnnaBridge 181:57724642e740 346 irq_handler(uart_data[index].serial_irq_id, TxIrq);
AnnaBridge 181:57724642e740 347 }
AnnaBridge 181:57724642e740 348
AnnaBridge 181:57724642e740 349 static void uart_rx_irq(IRQn_Type irq_num, uint32_t index) {
AnnaBridge 181:57724642e740 350 __IO uint16_t *dmy_rd_scscr;
AnnaBridge 181:57724642e740 351 __IO uint16_t *dmy_rd_scfsr;
AnnaBridge 181:57724642e740 352 serial_t *obj;
AnnaBridge 181:57724642e740 353 int c;
AnnaBridge 181:57724642e740 354
AnnaBridge 181:57724642e740 355 dmy_rd_scscr = SCSCR_MATCH[index];
AnnaBridge 181:57724642e740 356 *dmy_rd_scscr &= 0x00B3; // Clear RIE,REIE and Write to bit15~8,2 is always 0
AnnaBridge 181:57724642e740 357 dmy_rd_scfsr = SCFSR_MATCH[index];
AnnaBridge 181:57724642e740 358 *dmy_rd_scfsr = (*dmy_rd_scfsr & ~0x0003); // Clear RDF,DR
AnnaBridge 181:57724642e740 359
AnnaBridge 181:57724642e740 360 obj = uart_data[index].receiving_obj;
AnnaBridge 181:57724642e740 361 if (obj) {
AnnaBridge 181:57724642e740 362 if (obj->serial.uart->SCLSR & 1) {
AnnaBridge 181:57724642e740 363 if (uart_data[index].wanted_rx_events & SERIAL_EVENT_RX_OVERRUN_ERROR) {
AnnaBridge 181:57724642e740 364 serial_rx_abort_asynch(obj);
AnnaBridge 181:57724642e740 365 uart_data[index].event = SERIAL_EVENT_RX_OVERRUN_ERROR;
AnnaBridge 181:57724642e740 366 ((void (*)())uart_data[index].async_rx_callback)();
AnnaBridge 181:57724642e740 367 }
AnnaBridge 181:57724642e740 368 return;
AnnaBridge 181:57724642e740 369 }
AnnaBridge 181:57724642e740 370 c = serial_getc(obj);
AnnaBridge 181:57724642e740 371 if (c != -1) {
AnnaBridge 181:57724642e740 372 ((uint8_t *)obj->rx_buff.buffer)[obj->rx_buff.pos] = c;
AnnaBridge 181:57724642e740 373 ++obj->rx_buff.pos;
AnnaBridge 181:57724642e740 374 if (c == obj->char_match && ! obj->char_found) {
AnnaBridge 181:57724642e740 375 obj->char_found = 1;
AnnaBridge 181:57724642e740 376 if (obj->rx_buff.pos == obj->rx_buff.length) {
AnnaBridge 181:57724642e740 377 if (uart_data[index].wanted_rx_events & SERIAL_EVENT_RX_COMPLETE) {
AnnaBridge 181:57724642e740 378 uart_data[index].event = SERIAL_EVENT_RX_COMPLETE;
AnnaBridge 181:57724642e740 379 }
AnnaBridge 181:57724642e740 380 }
AnnaBridge 181:57724642e740 381 if (uart_data[index].wanted_rx_events & SERIAL_EVENT_RX_CHARACTER_MATCH) {
AnnaBridge 181:57724642e740 382 uart_data[index].event |= SERIAL_EVENT_RX_CHARACTER_MATCH;
AnnaBridge 181:57724642e740 383 }
AnnaBridge 181:57724642e740 384 if (uart_data[index].event) {
AnnaBridge 181:57724642e740 385 uart_data[index].receiving_obj = NULL;
AnnaBridge 181:57724642e740 386 ((void (*)())uart_data[index].async_rx_callback)();
AnnaBridge 181:57724642e740 387 }
AnnaBridge 181:57724642e740 388 } else if (obj->rx_buff.pos == obj->rx_buff.length) {
AnnaBridge 181:57724642e740 389 uart_data[index].receiving_obj = NULL;
AnnaBridge 181:57724642e740 390 if (uart_data[index].wanted_rx_events & SERIAL_EVENT_RX_COMPLETE) {
AnnaBridge 181:57724642e740 391 uart_data[index].event = SERIAL_EVENT_RX_COMPLETE;
AnnaBridge 181:57724642e740 392 ((void (*)())uart_data[index].async_rx_callback)();
AnnaBridge 181:57724642e740 393 }
AnnaBridge 181:57724642e740 394 }
AnnaBridge 181:57724642e740 395 } else {
AnnaBridge 181:57724642e740 396 serial_rx_abort_asynch(obj);
AnnaBridge 181:57724642e740 397 if (uart_data[index].wanted_rx_events & (SERIAL_EVENT_RX_PARITY_ERROR | SERIAL_EVENT_RX_FRAMING_ERROR)) {
AnnaBridge 181:57724642e740 398 uart_data[index].event = SERIAL_EVENT_RX_PARITY_ERROR | SERIAL_EVENT_RX_FRAMING_ERROR;
AnnaBridge 181:57724642e740 399 if (obj->serial.uart->SCFSR & 1 << 2) {
AnnaBridge 181:57724642e740 400 uart_data[index].event = SERIAL_EVENT_RX_PARITY_ERROR;
AnnaBridge 181:57724642e740 401 } else if (obj->serial.uart->SCFSR & 1 << 3) {
AnnaBridge 181:57724642e740 402 uart_data[index].event = SERIAL_EVENT_RX_FRAMING_ERROR;
AnnaBridge 181:57724642e740 403 }
AnnaBridge 181:57724642e740 404 ((void (*)())uart_data[index].async_rx_callback)();
AnnaBridge 181:57724642e740 405 }
AnnaBridge 181:57724642e740 406 return;
AnnaBridge 181:57724642e740 407 }
AnnaBridge 181:57724642e740 408 }
AnnaBridge 181:57724642e740 409
AnnaBridge 181:57724642e740 410 irq_handler(uart_data[index].serial_irq_id, RxIrq);
AnnaBridge 181:57724642e740 411 }
AnnaBridge 181:57724642e740 412
AnnaBridge 181:57724642e740 413 static void uart_err_irq(IRQn_Type irq_num, uint32_t index) {
AnnaBridge 181:57724642e740 414 serial_t *obj = uart_data[index].receiving_obj;
AnnaBridge 181:57724642e740 415 int err_read;
AnnaBridge 181:57724642e740 416
AnnaBridge 181:57724642e740 417 if (obj) {
AnnaBridge 181:57724642e740 418 serial_irq_err_set(obj, 0);
AnnaBridge 181:57724642e740 419 if (uart_data[index].wanted_rx_events & (SERIAL_EVENT_RX_PARITY_ERROR | SERIAL_EVENT_RX_FRAMING_ERROR)) {
AnnaBridge 181:57724642e740 420 uart_data[index].event = SERIAL_EVENT_RX_PARITY_ERROR | SERIAL_EVENT_RX_FRAMING_ERROR;
AnnaBridge 181:57724642e740 421 if (obj->serial.uart->SCFSR & 1 << 2) {
AnnaBridge 181:57724642e740 422 uart_data[index].event = SERIAL_EVENT_RX_PARITY_ERROR;
AnnaBridge 181:57724642e740 423 } else if (obj->serial.uart->SCFSR & 1 << 3) {
AnnaBridge 181:57724642e740 424 uart_data[index].event = SERIAL_EVENT_RX_FRAMING_ERROR;
AnnaBridge 181:57724642e740 425 }
AnnaBridge 181:57724642e740 426 ((void (*)())uart_data[index].async_rx_callback)();
AnnaBridge 181:57724642e740 427 }
AnnaBridge 181:57724642e740 428 serial_rx_abort_asynch(obj);
AnnaBridge 181:57724642e740 429
AnnaBridge 181:57724642e740 430 core_util_critical_section_enter();
AnnaBridge 181:57724642e740 431 if (obj->serial.uart->SCFSR & 0x93) {
AnnaBridge 181:57724642e740 432 err_read = obj->serial.uart->SCFSR;
AnnaBridge 181:57724642e740 433 obj->serial.uart->SCFSR = (err_read & ~0x93);
AnnaBridge 181:57724642e740 434 }
AnnaBridge 181:57724642e740 435 if (obj->serial.uart->SCLSR & 1) {
AnnaBridge 181:57724642e740 436 obj->serial.uart->SCLSR = 0;
AnnaBridge 181:57724642e740 437 }
AnnaBridge 181:57724642e740 438 core_util_critical_section_exit();
AnnaBridge 181:57724642e740 439 }
AnnaBridge 181:57724642e740 440 }
AnnaBridge 181:57724642e740 441
AnnaBridge 181:57724642e740 442 static void uart0_tx_irq(void) {
AnnaBridge 181:57724642e740 443 uart_tx_irq(SCIFTXI0_IRQn, 0);
AnnaBridge 181:57724642e740 444 }
AnnaBridge 181:57724642e740 445 static void uart0_rx_irq(void) {
AnnaBridge 181:57724642e740 446 uart_rx_irq(SCIFRXI0_IRQn, 0);
AnnaBridge 181:57724642e740 447 }
AnnaBridge 181:57724642e740 448 static void uart0_er_irq(void) {
AnnaBridge 181:57724642e740 449 uart_err_irq(SCIFERI0_IRQn, 0);
AnnaBridge 181:57724642e740 450 }
AnnaBridge 181:57724642e740 451
AnnaBridge 181:57724642e740 452 static void uart1_tx_irq(void) {
AnnaBridge 181:57724642e740 453 uart_tx_irq(SCIFTXI1_IRQn, 1);
AnnaBridge 181:57724642e740 454 }
AnnaBridge 181:57724642e740 455 static void uart1_rx_irq(void) {
AnnaBridge 181:57724642e740 456 uart_rx_irq(SCIFRXI1_IRQn, 1);
AnnaBridge 181:57724642e740 457 }
AnnaBridge 181:57724642e740 458 static void uart1_er_irq(void) {
AnnaBridge 181:57724642e740 459 uart_err_irq(SCIFERI1_IRQn, 1);
AnnaBridge 181:57724642e740 460 }
AnnaBridge 181:57724642e740 461
AnnaBridge 181:57724642e740 462 static void uart2_tx_irq(void) {
AnnaBridge 181:57724642e740 463 uart_tx_irq(SCIFTXI2_IRQn, 2);
AnnaBridge 181:57724642e740 464 }
AnnaBridge 181:57724642e740 465 static void uart2_rx_irq(void) {
AnnaBridge 181:57724642e740 466 uart_rx_irq(SCIFRXI2_IRQn, 2);
AnnaBridge 181:57724642e740 467 }
AnnaBridge 181:57724642e740 468 static void uart2_er_irq(void) {
AnnaBridge 181:57724642e740 469 uart_err_irq(SCIFERI2_IRQn, 2);
AnnaBridge 181:57724642e740 470 }
AnnaBridge 181:57724642e740 471
AnnaBridge 181:57724642e740 472 static void uart3_tx_irq(void) {
AnnaBridge 181:57724642e740 473 uart_tx_irq(SCIFTXI3_IRQn, 3);
AnnaBridge 181:57724642e740 474 }
AnnaBridge 181:57724642e740 475 static void uart3_rx_irq(void) {
AnnaBridge 181:57724642e740 476 uart_rx_irq(SCIFRXI3_IRQn, 3);
AnnaBridge 181:57724642e740 477 }
AnnaBridge 181:57724642e740 478 static void uart3_er_irq(void) {
AnnaBridge 181:57724642e740 479 uart_err_irq(SCIFERI3_IRQn, 3);
AnnaBridge 181:57724642e740 480 }
AnnaBridge 181:57724642e740 481
AnnaBridge 181:57724642e740 482 static void uart4_tx_irq(void) {
AnnaBridge 181:57724642e740 483 uart_tx_irq(SCIFTXI4_IRQn, 4);
AnnaBridge 181:57724642e740 484 }
AnnaBridge 181:57724642e740 485 static void uart4_rx_irq(void) {
AnnaBridge 181:57724642e740 486 uart_rx_irq(SCIFRXI4_IRQn, 4);
AnnaBridge 181:57724642e740 487 }
AnnaBridge 181:57724642e740 488 static void uart4_er_irq(void) {
AnnaBridge 181:57724642e740 489 uart_err_irq(SCIFERI4_IRQn, 4);
AnnaBridge 181:57724642e740 490 }
AnnaBridge 181:57724642e740 491
AnnaBridge 181:57724642e740 492 #if defined(TARGET_RZA1H)
AnnaBridge 181:57724642e740 493 static void uart5_tx_irq(void) {
AnnaBridge 181:57724642e740 494 uart_tx_irq(SCIFTXI5_IRQn, 5);
AnnaBridge 181:57724642e740 495 }
AnnaBridge 181:57724642e740 496 static void uart5_rx_irq(void) {
AnnaBridge 181:57724642e740 497 uart_rx_irq(SCIFRXI5_IRQn, 5);
AnnaBridge 181:57724642e740 498 }
AnnaBridge 181:57724642e740 499 static void uart5_er_irq(void) {
AnnaBridge 181:57724642e740 500 uart_err_irq(SCIFERI5_IRQn, 5);
AnnaBridge 181:57724642e740 501 }
AnnaBridge 181:57724642e740 502
AnnaBridge 181:57724642e740 503 static void uart6_tx_irq(void) {
AnnaBridge 181:57724642e740 504 uart_tx_irq(SCIFTXI6_IRQn, 6);
AnnaBridge 181:57724642e740 505 }
AnnaBridge 181:57724642e740 506 static void uart6_rx_irq(void) {
AnnaBridge 181:57724642e740 507 uart_rx_irq(SCIFRXI6_IRQn, 6);
AnnaBridge 181:57724642e740 508 }
AnnaBridge 181:57724642e740 509 static void uart6_er_irq(void) {
AnnaBridge 181:57724642e740 510 uart_err_irq(SCIFERI6_IRQn, 6);
AnnaBridge 181:57724642e740 511 }
AnnaBridge 181:57724642e740 512
AnnaBridge 181:57724642e740 513 static void uart7_tx_irq(void) {
AnnaBridge 181:57724642e740 514 uart_tx_irq(SCIFTXI7_IRQn, 7);
AnnaBridge 181:57724642e740 515 }
AnnaBridge 181:57724642e740 516 static void uart7_rx_irq(void) {
AnnaBridge 181:57724642e740 517 uart_rx_irq(SCIFRXI7_IRQn, 7);
AnnaBridge 181:57724642e740 518 }
AnnaBridge 181:57724642e740 519 static void uart7_er_irq(void) {
AnnaBridge 181:57724642e740 520 uart_err_irq(SCIFERI7_IRQn, 7);
AnnaBridge 181:57724642e740 521 }
AnnaBridge 181:57724642e740 522 #endif
AnnaBridge 181:57724642e740 523
AnnaBridge 181:57724642e740 524 void serial_irq_handler(serial_t *obj, uart_irq_handler handler, uint32_t id) {
AnnaBridge 181:57724642e740 525 irq_handler = handler;
AnnaBridge 181:57724642e740 526 uart_data[obj->serial.index].serial_irq_id = id;
AnnaBridge 181:57724642e740 527 }
AnnaBridge 181:57724642e740 528
AnnaBridge 181:57724642e740 529 static void serial_irq_set_irq(IRQn_Type IRQn, IRQHandler handler, uint32_t enable)
AnnaBridge 181:57724642e740 530 {
AnnaBridge 181:57724642e740 531 if (enable) {
AnnaBridge 181:57724642e740 532 InterruptHandlerRegister(IRQn, (void (*)(uint32_t))handler);
AnnaBridge 181:57724642e740 533 GIC_SetPriority(IRQn, 5);
AnnaBridge 181:57724642e740 534 GIC_EnableIRQ(IRQn);
AnnaBridge 181:57724642e740 535 } else {
AnnaBridge 181:57724642e740 536 GIC_DisableIRQ(IRQn);
AnnaBridge 181:57724642e740 537 }
AnnaBridge 181:57724642e740 538 }
AnnaBridge 181:57724642e740 539
AnnaBridge 181:57724642e740 540 static void serial_irq_err_set(serial_t *obj, uint32_t enable)
AnnaBridge 181:57724642e740 541 {
AnnaBridge 181:57724642e740 542 serial_irq_set_irq(irq_set_tbl[obj->serial.index][2], hander_set_tbl[obj->serial.index][2], enable);
AnnaBridge 181:57724642e740 543 serial_irq_set_irq(irq_set_tbl[obj->serial.index][3], hander_set_tbl[obj->serial.index][3], enable);
AnnaBridge 181:57724642e740 544 }
AnnaBridge 181:57724642e740 545
AnnaBridge 181:57724642e740 546 void serial_irq_set(serial_t *obj, SerialIrq irq, uint32_t enable) {
AnnaBridge 181:57724642e740 547 IRQn_Type IRQn;
AnnaBridge 181:57724642e740 548 IRQHandler handler;
AnnaBridge 181:57724642e740 549
AnnaBridge 181:57724642e740 550 IRQn = irq_set_tbl[obj->serial.index][irq];
AnnaBridge 181:57724642e740 551 handler = hander_set_tbl[obj->serial.index][irq];
AnnaBridge 181:57724642e740 552
AnnaBridge 181:57724642e740 553 if ((obj->serial.index >= 0) && (obj->serial.index <= 7)) {
AnnaBridge 181:57724642e740 554 serial_irq_set_irq(IRQn, handler, enable);
AnnaBridge 181:57724642e740 555 }
AnnaBridge 181:57724642e740 556 }
AnnaBridge 181:57724642e740 557
AnnaBridge 181:57724642e740 558 /******************************************************************************
AnnaBridge 181:57724642e740 559 * READ/WRITE
AnnaBridge 181:57724642e740 560 ******************************************************************************/
AnnaBridge 181:57724642e740 561 int serial_getc(serial_t *obj) {
AnnaBridge 181:57724642e740 562 uint16_t err_read;
AnnaBridge 181:57724642e740 563 int data;
AnnaBridge 181:57724642e740 564
AnnaBridge 181:57724642e740 565 core_util_critical_section_enter();
AnnaBridge 181:57724642e740 566 if (obj->serial.uart->SCFSR & 0x93) {
AnnaBridge 181:57724642e740 567 err_read = obj->serial.uart->SCFSR;
AnnaBridge 181:57724642e740 568 obj->serial.uart->SCFSR = (err_read & ~0x93);
AnnaBridge 181:57724642e740 569 }
AnnaBridge 181:57724642e740 570 obj->serial.uart->SCSCR |= 0x0040; // Set RIE
AnnaBridge 181:57724642e740 571 core_util_critical_section_exit();
AnnaBridge 181:57724642e740 572
AnnaBridge 181:57724642e740 573 if (obj->serial.uart->SCLSR & 0x0001) {
AnnaBridge 181:57724642e740 574 obj->serial.uart->SCLSR = 0u; // ORER clear
AnnaBridge 181:57724642e740 575 }
AnnaBridge 181:57724642e740 576
AnnaBridge 181:57724642e740 577 while (!serial_readable(obj));
AnnaBridge 181:57724642e740 578 data = obj->serial.uart->SCFRDR & 0xff;
AnnaBridge 181:57724642e740 579
AnnaBridge 181:57724642e740 580 core_util_critical_section_enter();
AnnaBridge 181:57724642e740 581 err_read = obj->serial.uart->SCFSR;
AnnaBridge 181:57724642e740 582 obj->serial.uart->SCFSR = (err_read & 0xfffD); // Clear RDF
AnnaBridge 181:57724642e740 583 core_util_critical_section_exit();
AnnaBridge 181:57724642e740 584
AnnaBridge 181:57724642e740 585 if (err_read & 0x80) {
AnnaBridge 181:57724642e740 586 data = -1; //err
AnnaBridge 181:57724642e740 587 }
AnnaBridge 181:57724642e740 588 return data;
AnnaBridge 181:57724642e740 589 }
AnnaBridge 181:57724642e740 590
AnnaBridge 181:57724642e740 591 void serial_putc(serial_t *obj, int c) {
AnnaBridge 181:57724642e740 592 while (!serial_writable(obj));
AnnaBridge 181:57724642e740 593 obj->serial.uart->SCFTDR = c;
AnnaBridge 181:57724642e740 594 serial_put_done(obj);
AnnaBridge 181:57724642e740 595 }
AnnaBridge 181:57724642e740 596
AnnaBridge 181:57724642e740 597 static void serial_put_done(serial_t *obj)
AnnaBridge 181:57724642e740 598 {
AnnaBridge 181:57724642e740 599 volatile uint16_t dummy_read;
AnnaBridge 181:57724642e740 600
AnnaBridge 181:57724642e740 601 core_util_critical_section_enter();
AnnaBridge 181:57724642e740 602 dummy_read = obj->serial.uart->SCFSR;
AnnaBridge 181:57724642e740 603 obj->serial.uart->SCFSR = (dummy_read & 0xff9f); // Clear TEND/TDFE
AnnaBridge 181:57724642e740 604 obj->serial.uart->SCSCR |= 0x0080; // Set TIE
AnnaBridge 181:57724642e740 605 core_util_critical_section_exit();
AnnaBridge 181:57724642e740 606 }
AnnaBridge 181:57724642e740 607
AnnaBridge 181:57724642e740 608 int serial_readable(serial_t *obj) {
AnnaBridge 181:57724642e740 609 return ((obj->serial.uart->SCFSR & 0x02) != 0); // RDF
AnnaBridge 181:57724642e740 610 }
AnnaBridge 181:57724642e740 611
AnnaBridge 181:57724642e740 612 int serial_writable(serial_t *obj) {
AnnaBridge 181:57724642e740 613 return ((obj->serial.uart->SCFSR & 0x20) != 0); // TDFE
AnnaBridge 181:57724642e740 614 }
AnnaBridge 181:57724642e740 615
AnnaBridge 181:57724642e740 616 void serial_clear(serial_t *obj) {
AnnaBridge 181:57724642e740 617 core_util_critical_section_enter();
AnnaBridge 181:57724642e740 618
AnnaBridge 181:57724642e740 619 obj->serial.uart->SCFCR |= 0x0006u; // TFRST = 1, RFRST = 1
AnnaBridge 181:57724642e740 620 obj->serial.uart->SCFCR &= ~0x0006u; // TFRST = 0, RFRST = 0
AnnaBridge 181:57724642e740 621 obj->serial.uart->SCFSR &= ~0x0093u; // ER, BRK, RDF, DR = 0
AnnaBridge 181:57724642e740 622
AnnaBridge 181:57724642e740 623 core_util_critical_section_exit();
AnnaBridge 181:57724642e740 624 }
AnnaBridge 181:57724642e740 625
AnnaBridge 181:57724642e740 626 void serial_pinout_tx(PinName tx) {
AnnaBridge 181:57724642e740 627 pinmap_pinout(tx, PinMap_UART_TX);
AnnaBridge 181:57724642e740 628 }
AnnaBridge 181:57724642e740 629
AnnaBridge 181:57724642e740 630 void serial_break_set(serial_t *obj) {
AnnaBridge 181:57724642e740 631 core_util_critical_section_enter();
AnnaBridge 181:57724642e740 632 // TxD Output(L)
AnnaBridge 181:57724642e740 633 obj->serial.uart->SCSPTR &= ~0x0001u; // SPB2DT = 0
AnnaBridge 181:57724642e740 634 obj->serial.uart->SCSCR &= ~0x0020u; // TE = 0 (Output disable)
AnnaBridge 181:57724642e740 635 core_util_critical_section_exit();
AnnaBridge 181:57724642e740 636 }
AnnaBridge 181:57724642e740 637
AnnaBridge 181:57724642e740 638 void serial_break_clear(serial_t *obj) {
AnnaBridge 181:57724642e740 639 core_util_critical_section_enter();
AnnaBridge 181:57724642e740 640 obj->serial.uart->SCSCR |= 0x0020u; // TE = 1 (Output enable)
AnnaBridge 181:57724642e740 641 obj->serial.uart->SCSPTR |= 0x0001u; // SPB2DT = 1
AnnaBridge 181:57724642e740 642 core_util_critical_section_exit();
AnnaBridge 181:57724642e740 643 }
AnnaBridge 181:57724642e740 644
AnnaBridge 181:57724642e740 645 #if DEVICE_SERIAL_FC
AnnaBridge 181:57724642e740 646 void serial_set_flow_control(serial_t *obj, FlowControl type, PinName rxflow, PinName txflow) {
AnnaBridge 181:57724642e740 647 // determine the UART to use
AnnaBridge 181:57724642e740 648
AnnaBridge 181:57724642e740 649 if (type == FlowControlRTSCTS) {
AnnaBridge 181:57724642e740 650 core_util_critical_section_enter();
AnnaBridge 181:57724642e740 651 obj->serial.uart->SCFCR |= 0x0008u; // CTS/RTS enable
AnnaBridge 181:57724642e740 652 core_util_critical_section_exit();
AnnaBridge 181:57724642e740 653 pinmap_pinout(rxflow, PinMap_UART_RTS);
AnnaBridge 181:57724642e740 654 pinmap_pinout(txflow, PinMap_UART_CTS);
AnnaBridge 181:57724642e740 655 } else {
AnnaBridge 181:57724642e740 656 core_util_critical_section_enter();
AnnaBridge 181:57724642e740 657 obj->serial.uart->SCFCR &= ~0x0008u; // CTS/RTS diable
AnnaBridge 181:57724642e740 658 core_util_critical_section_exit();
AnnaBridge 181:57724642e740 659 }
AnnaBridge 181:57724642e740 660 }
AnnaBridge 181:57724642e740 661 #endif
AnnaBridge 181:57724642e740 662
AnnaBridge 181:57724642e740 663 static uint8_t serial_available_buffer(serial_t *obj)
AnnaBridge 181:57724642e740 664 {
AnnaBridge 181:57724642e740 665 return 1;
AnnaBridge 181:57724642e740 666 /* Faster but unstable way */
AnnaBridge 181:57724642e740 667 /*
AnnaBridge 181:57724642e740 668 uint16_t ret = 16 - ((obj->serial.uart->SCFDR >> 8) & 0x1F);
AnnaBridge 181:57724642e740 669 while (ret == 0) {
AnnaBridge 181:57724642e740 670 ret = 16 - ((obj->serial.uart->SCFDR >> 8) & 0x1F);
AnnaBridge 181:57724642e740 671 }
AnnaBridge 181:57724642e740 672 MBED_ASSERT(0 < ret && ret <= 16);
AnnaBridge 181:57724642e740 673 return ret;
AnnaBridge 181:57724642e740 674 */
AnnaBridge 181:57724642e740 675 }
AnnaBridge 181:57724642e740 676
AnnaBridge 181:57724642e740 677 #if DEVICE_SERIAL_ASYNCH
AnnaBridge 181:57724642e740 678
AnnaBridge 181:57724642e740 679 /******************************************************************************
AnnaBridge 181:57724642e740 680 * ASYNCHRONOUS HAL
AnnaBridge 181:57724642e740 681 ******************************************************************************/
AnnaBridge 181:57724642e740 682
AnnaBridge 181:57724642e740 683 int serial_tx_asynch(serial_t *obj, const void *tx, size_t tx_length, uint8_t tx_width, uint32_t handler, uint32_t event, DMAUsage hint)
AnnaBridge 181:57724642e740 684 {
AnnaBridge 181:57724642e740 685 int i;
AnnaBridge 181:57724642e740 686 buffer_t *buf = &obj->tx_buff;
AnnaBridge 181:57724642e740 687 struct serial_global_data_s *data = uart_data + obj->serial.index;
AnnaBridge 181:57724642e740 688
AnnaBridge 181:57724642e740 689 if (tx_length == 0) {
AnnaBridge 181:57724642e740 690 return 0;
AnnaBridge 181:57724642e740 691 }
AnnaBridge 181:57724642e740 692
AnnaBridge 181:57724642e740 693 buf->buffer = (void *)tx;
AnnaBridge 181:57724642e740 694 buf->length = tx_length * tx_width / 8;
AnnaBridge 181:57724642e740 695 buf->pos = 0;
AnnaBridge 181:57724642e740 696 buf->width = tx_width;
AnnaBridge 181:57724642e740 697 data->tranferring_obj = obj;
AnnaBridge 181:57724642e740 698 data->async_tx_callback = handler;
AnnaBridge 181:57724642e740 699 serial_irq_set(obj, TxIrq, 1);
AnnaBridge 181:57724642e740 700
AnnaBridge 181:57724642e740 701 while (!serial_writable(obj));
AnnaBridge 181:57724642e740 702 i = buf->length;
AnnaBridge 181:57724642e740 703 if (serial_available_buffer(obj) < i) {
AnnaBridge 181:57724642e740 704 i = serial_available_buffer(obj);
AnnaBridge 181:57724642e740 705 }
AnnaBridge 181:57724642e740 706 do {
AnnaBridge 181:57724642e740 707 uint8_t c = *(uint8_t *)buf->buffer;
AnnaBridge 181:57724642e740 708 obj->tx_buff.buffer = (uint8_t *)obj->tx_buff.buffer + 1;
AnnaBridge 181:57724642e740 709 ++buf->pos;
AnnaBridge 181:57724642e740 710 obj->serial.uart->SCFTDR = c;
AnnaBridge 181:57724642e740 711 } while (--i);
AnnaBridge 181:57724642e740 712 serial_put_done(obj);
AnnaBridge 181:57724642e740 713
AnnaBridge 181:57724642e740 714 return buf->length;
AnnaBridge 181:57724642e740 715 }
AnnaBridge 181:57724642e740 716
AnnaBridge 181:57724642e740 717 void serial_rx_asynch(serial_t *obj, void *rx, size_t rx_length, uint8_t rx_width, uint32_t handler, uint32_t event, uint8_t char_match, DMAUsage hint)
AnnaBridge 181:57724642e740 718 {
AnnaBridge 181:57724642e740 719 buffer_t *buf = &obj->rx_buff;
AnnaBridge 181:57724642e740 720 struct serial_global_data_s *data = uart_data + obj->serial.index;
AnnaBridge 181:57724642e740 721
AnnaBridge 181:57724642e740 722 if (rx_length == 0) {
AnnaBridge 181:57724642e740 723 return;
AnnaBridge 181:57724642e740 724 }
AnnaBridge 181:57724642e740 725
AnnaBridge 181:57724642e740 726 buf->buffer = rx;
AnnaBridge 181:57724642e740 727 buf->length = rx_length * rx_width / 8;
AnnaBridge 181:57724642e740 728 buf->pos = 0;
AnnaBridge 181:57724642e740 729 buf->width = rx_width;
AnnaBridge 181:57724642e740 730 obj->char_match = char_match;
AnnaBridge 181:57724642e740 731 obj->char_found = 0;
AnnaBridge 181:57724642e740 732 data->receiving_obj = obj;
AnnaBridge 181:57724642e740 733 data->async_rx_callback = handler;
AnnaBridge 181:57724642e740 734 data->event = 0;
AnnaBridge 181:57724642e740 735 data->wanted_rx_events = event;
AnnaBridge 181:57724642e740 736
AnnaBridge 181:57724642e740 737 serial_irq_set(obj, RxIrq, 1);
AnnaBridge 181:57724642e740 738 serial_irq_err_set(obj, 1);
AnnaBridge 181:57724642e740 739 }
AnnaBridge 181:57724642e740 740
AnnaBridge 181:57724642e740 741 uint8_t serial_tx_active(serial_t *obj)
AnnaBridge 181:57724642e740 742 {
AnnaBridge 181:57724642e740 743 return uart_data[obj->serial.index].tranferring_obj != NULL;
AnnaBridge 181:57724642e740 744 }
AnnaBridge 181:57724642e740 745
AnnaBridge 181:57724642e740 746 uint8_t serial_rx_active(serial_t *obj)
AnnaBridge 181:57724642e740 747 {
AnnaBridge 181:57724642e740 748 return uart_data[obj->serial.index].receiving_obj != NULL;
AnnaBridge 181:57724642e740 749 }
AnnaBridge 181:57724642e740 750
AnnaBridge 181:57724642e740 751 int serial_irq_handler_asynch(serial_t *obj)
AnnaBridge 181:57724642e740 752 {
AnnaBridge 181:57724642e740 753 return uart_data[obj->serial.index].event;
AnnaBridge 181:57724642e740 754 }
AnnaBridge 181:57724642e740 755
AnnaBridge 181:57724642e740 756 void serial_tx_abort_asynch(serial_t *obj)
AnnaBridge 181:57724642e740 757 {
AnnaBridge 181:57724642e740 758 uart_data[obj->serial.index].tranferring_obj = NULL;
AnnaBridge 181:57724642e740 759 obj->serial.uart->SCFCR |= 1 << 2;
AnnaBridge 181:57724642e740 760 obj->serial.uart->SCFCR &= ~(1 << 2);
AnnaBridge 181:57724642e740 761 }
AnnaBridge 181:57724642e740 762
AnnaBridge 181:57724642e740 763 void serial_rx_abort_asynch(serial_t *obj)
AnnaBridge 181:57724642e740 764 {
AnnaBridge 181:57724642e740 765 uart_data[obj->serial.index].receiving_obj = NULL;
AnnaBridge 181:57724642e740 766 obj->serial.uart->SCFCR |= 1 << 1;
AnnaBridge 181:57724642e740 767 obj->serial.uart->SCFCR &= ~(1 << 1);
AnnaBridge 181:57724642e740 768 }
AnnaBridge 181:57724642e740 769
AnnaBridge 181:57724642e740 770 #endif