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
mbed library release version 165

Who changed what in which revision?

UserRevisionLine numberNew contents of line
AnnaBridge 189:f392fc9709a3 1 /* mbed Microcontroller Library
AnnaBridge 189:f392fc9709a3 2 * Copyright (c) 2006-2018 ARM Limited
AnnaBridge 189:f392fc9709a3 3 *
AnnaBridge 189:f392fc9709a3 4 * Licensed under the Apache License, Version 2.0 (the "License");
AnnaBridge 189:f392fc9709a3 5 * you may not use this file except in compliance with the License.
AnnaBridge 189:f392fc9709a3 6 * You may obtain a copy of the License at
AnnaBridge 189:f392fc9709a3 7 *
AnnaBridge 189:f392fc9709a3 8 * http://www.apache.org/licenses/LICENSE-2.0
AnnaBridge 189:f392fc9709a3 9 *
AnnaBridge 189:f392fc9709a3 10 * Unless required by applicable law or agreed to in writing, software
AnnaBridge 189:f392fc9709a3 11 * distributed under the License is distributed on an "AS IS" BASIS,
AnnaBridge 189:f392fc9709a3 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
AnnaBridge 189:f392fc9709a3 13 * See the License for the specific language governing permissions and
AnnaBridge 189:f392fc9709a3 14 * limitations under the License.
AnnaBridge 189:f392fc9709a3 15 */
AnnaBridge 189:f392fc9709a3 16 // math.h required for floating point operations for baud rate calculation
AnnaBridge 189:f392fc9709a3 17 #include "mbed_assert.h"
AnnaBridge 189:f392fc9709a3 18 #include <math.h>
AnnaBridge 189:f392fc9709a3 19 #include <string.h>
AnnaBridge 189:f392fc9709a3 20 #include <stdlib.h>
AnnaBridge 189:f392fc9709a3 21
AnnaBridge 189:f392fc9709a3 22 #include "serial_api.h"
AnnaBridge 189:f392fc9709a3 23 #include "cmsis.h"
AnnaBridge 189:f392fc9709a3 24 #include "pinmap.h"
AnnaBridge 189:f392fc9709a3 25 #include "gpio_api.h"
AnnaBridge 189:f392fc9709a3 26
AnnaBridge 189:f392fc9709a3 27 /******************************************************************************
AnnaBridge 189:f392fc9709a3 28 * INITIALIZATION
AnnaBridge 189:f392fc9709a3 29 ******************************************************************************/
AnnaBridge 189:f392fc9709a3 30 #define UART_NUM 2
AnnaBridge 189:f392fc9709a3 31
AnnaBridge 189:f392fc9709a3 32 #define UART_CLKGATE_REG (RDA_SCU->CLKGATE0)
AnnaBridge 189:f392fc9709a3 33
AnnaBridge 189:f392fc9709a3 34 #define UART1_CLKEN_MASK (0x01UL << 21)
AnnaBridge 189:f392fc9709a3 35 #define RXFIFO_EMPTY_MASK (0x01UL << 0)
AnnaBridge 189:f392fc9709a3 36 #define TXFIFO_FULL_MASK (0x01UL << 19)
AnnaBridge 189:f392fc9709a3 37 #define AFCE_MASK (0x01UL << 5)
AnnaBridge 189:f392fc9709a3 38
AnnaBridge 189:f392fc9709a3 39 static const PinMap PinMap_UART_TX[] = {
AnnaBridge 189:f392fc9709a3 40 {PA_1, UART_0, 0},
AnnaBridge 189:f392fc9709a3 41 {PB_2, UART_1, 5},
AnnaBridge 189:f392fc9709a3 42 {PD_3, UART_1, 2},
AnnaBridge 189:f392fc9709a3 43 {NC , NC , 0}
AnnaBridge 189:f392fc9709a3 44 };
AnnaBridge 189:f392fc9709a3 45
AnnaBridge 189:f392fc9709a3 46 static const PinMap PinMap_UART_RX[] = {
AnnaBridge 189:f392fc9709a3 47 {PA_0, UART_0, 0},
AnnaBridge 189:f392fc9709a3 48 {PB_1, UART_1, 5},
AnnaBridge 189:f392fc9709a3 49 {PD_2, UART_1, 2},
AnnaBridge 189:f392fc9709a3 50 {NC , NC , 0}
AnnaBridge 189:f392fc9709a3 51 };
AnnaBridge 189:f392fc9709a3 52
AnnaBridge 189:f392fc9709a3 53 static const PinMap PinMap_UART_RTS[] = {
AnnaBridge 189:f392fc9709a3 54 {PD_1, UART_1, 2},
AnnaBridge 189:f392fc9709a3 55 {NC, NC, 0}
AnnaBridge 189:f392fc9709a3 56 };
AnnaBridge 189:f392fc9709a3 57
AnnaBridge 189:f392fc9709a3 58 static const PinMap PinMap_UART_CTS[] = {
AnnaBridge 189:f392fc9709a3 59 {PD_0, UART_1, 2},
AnnaBridge 189:f392fc9709a3 60 {NC, NC, 0}
AnnaBridge 189:f392fc9709a3 61 };
AnnaBridge 189:f392fc9709a3 62
AnnaBridge 189:f392fc9709a3 63 static uart_irq_handler irq_handler[UART_NUM];
AnnaBridge 189:f392fc9709a3 64
AnnaBridge 189:f392fc9709a3 65 int stdio_uart_inited = 0;
AnnaBridge 189:f392fc9709a3 66 serial_t stdio_uart;
AnnaBridge 189:f392fc9709a3 67
AnnaBridge 189:f392fc9709a3 68 struct serial_global_data_s {
AnnaBridge 189:f392fc9709a3 69 uint32_t serial_irq_id;
AnnaBridge 189:f392fc9709a3 70 gpio_t sw_rts, sw_cts;
AnnaBridge 189:f392fc9709a3 71 uint8_t count, rx_irq_set_flow, rx_irq_set_api;
AnnaBridge 189:f392fc9709a3 72 };
AnnaBridge 189:f392fc9709a3 73
AnnaBridge 189:f392fc9709a3 74 static struct serial_global_data_s uart_data[UART_NUM];
AnnaBridge 189:f392fc9709a3 75
AnnaBridge 189:f392fc9709a3 76 void serial_init(serial_t *obj, PinName tx, PinName rx)
AnnaBridge 189:f392fc9709a3 77 {
AnnaBridge 189:f392fc9709a3 78 int is_stdio_uart = 0;
AnnaBridge 189:f392fc9709a3 79
AnnaBridge 189:f392fc9709a3 80 // determine the UART to use
AnnaBridge 189:f392fc9709a3 81 UARTName uart_tx = (UARTName)pinmap_peripheral(tx, PinMap_UART_TX);
AnnaBridge 189:f392fc9709a3 82 UARTName uart_rx = (UARTName)pinmap_peripheral(rx, PinMap_UART_RX);
AnnaBridge 189:f392fc9709a3 83 UARTName uart = (UARTName)pinmap_merge(uart_tx, uart_rx);
AnnaBridge 189:f392fc9709a3 84 MBED_ASSERT((int)uart != NC);
AnnaBridge 189:f392fc9709a3 85
AnnaBridge 189:f392fc9709a3 86 switch (uart) {
AnnaBridge 189:f392fc9709a3 87 case UART_0:
AnnaBridge 189:f392fc9709a3 88 obj->index = 0;
AnnaBridge 189:f392fc9709a3 89 break;
AnnaBridge 189:f392fc9709a3 90 case UART_1:
AnnaBridge 189:f392fc9709a3 91 obj->index = 1;
AnnaBridge 189:f392fc9709a3 92 /* Enable clock-gating */
AnnaBridge 189:f392fc9709a3 93 UART_CLKGATE_REG |= UART1_CLKEN_MASK;
AnnaBridge 189:f392fc9709a3 94 break;
AnnaBridge 189:f392fc9709a3 95 }
AnnaBridge 189:f392fc9709a3 96
AnnaBridge 189:f392fc9709a3 97 obj->uart = (RDA_UART_TypeDef *)uart;
AnnaBridge 189:f392fc9709a3 98
AnnaBridge 189:f392fc9709a3 99 // enable fifos and default rx trigger level
AnnaBridge 189:f392fc9709a3 100 obj->uart->FCR = 0 << 0 //FIFO Enable - 0 = Disables, 1 = Enabled
AnnaBridge 189:f392fc9709a3 101 | 0 << 1 // Rx Fifo Reset
AnnaBridge 189:f392fc9709a3 102 | 0 << 2 // Tx Fifo Reset
AnnaBridge 189:f392fc9709a3 103 | 0 << 6; // Rx irq trigger level - 0 = 1 char, 1 = 4 chars, 2 = 8 chars, 3 = 14 chars
AnnaBridge 189:f392fc9709a3 104
AnnaBridge 189:f392fc9709a3 105 // disable irqs
AnnaBridge 189:f392fc9709a3 106 obj->uart->IER = 0 << 0 // Rx Data available irq enable
AnnaBridge 189:f392fc9709a3 107 | 0 << 1 // Tx Fifo empty irq enable
AnnaBridge 189:f392fc9709a3 108 | 0 << 2; // Rx Line Status irq enable
AnnaBridge 189:f392fc9709a3 109
AnnaBridge 189:f392fc9709a3 110 obj->uart->MCR = 1 << 8; //select clock
AnnaBridge 189:f392fc9709a3 111 obj->uart->FRR = 0x2001; //tx_trigger = 0x10, rx_trigger = 0x01
AnnaBridge 189:f392fc9709a3 112
AnnaBridge 189:f392fc9709a3 113 serial_format(obj, 8, ParityNone, 1);
AnnaBridge 189:f392fc9709a3 114
AnnaBridge 189:f392fc9709a3 115 // pinout the chosen uart
AnnaBridge 189:f392fc9709a3 116 pinmap_pinout(tx, PinMap_UART_TX);
AnnaBridge 189:f392fc9709a3 117 pinmap_pinout(rx, PinMap_UART_RX);
AnnaBridge 189:f392fc9709a3 118
AnnaBridge 189:f392fc9709a3 119 // set rx/tx pins in PullUp mode
AnnaBridge 189:f392fc9709a3 120 if (tx != NC) {
AnnaBridge 189:f392fc9709a3 121 pin_mode(tx, PullUp);
AnnaBridge 189:f392fc9709a3 122 }
AnnaBridge 189:f392fc9709a3 123 if (rx != NC) {
AnnaBridge 189:f392fc9709a3 124 pin_mode(rx, PullUp);
AnnaBridge 189:f392fc9709a3 125 }
AnnaBridge 189:f392fc9709a3 126
AnnaBridge 189:f392fc9709a3 127 if ((rx != NC) && (tx != NC)) {
AnnaBridge 189:f392fc9709a3 128 obj->uart->FCR |= 1 << 0; //enable fifo
AnnaBridge 189:f392fc9709a3 129 }
AnnaBridge 189:f392fc9709a3 130
AnnaBridge 189:f392fc9709a3 131 uart_data[obj->index].sw_rts.pin = NC;
AnnaBridge 189:f392fc9709a3 132 uart_data[obj->index].sw_cts.pin = NC;
AnnaBridge 189:f392fc9709a3 133 serial_set_flow_control(obj, FlowControlNone, NC, NC);
AnnaBridge 189:f392fc9709a3 134
AnnaBridge 189:f392fc9709a3 135 is_stdio_uart = (uart == STDIO_UART) ? (1) : (0);
AnnaBridge 189:f392fc9709a3 136
AnnaBridge 189:f392fc9709a3 137 if (is_stdio_uart) {
AnnaBridge 189:f392fc9709a3 138 stdio_uart_inited = 1;
AnnaBridge 189:f392fc9709a3 139 memcpy(&stdio_uart, obj, sizeof(serial_t));
AnnaBridge 189:f392fc9709a3 140 }
AnnaBridge 189:f392fc9709a3 141 serial_clear(obj);
AnnaBridge 189:f392fc9709a3 142 }
AnnaBridge 189:f392fc9709a3 143
AnnaBridge 189:f392fc9709a3 144 void serial_free(serial_t *obj)
AnnaBridge 189:f392fc9709a3 145 {
AnnaBridge 189:f392fc9709a3 146 uart_data[obj->index].serial_irq_id = 0;
AnnaBridge 189:f392fc9709a3 147 }
AnnaBridge 189:f392fc9709a3 148
AnnaBridge 189:f392fc9709a3 149 // serial_baud
AnnaBridge 189:f392fc9709a3 150 // set the baud rate, taking in to account the current SystemFrequency
AnnaBridge 189:f392fc9709a3 151 void serial_baud(serial_t *obj, int baudrate)
AnnaBridge 189:f392fc9709a3 152 {
AnnaBridge 189:f392fc9709a3 153 MBED_ASSERT((int)obj->uart <= UART_1);
AnnaBridge 189:f392fc9709a3 154
AnnaBridge 189:f392fc9709a3 155 uint32_t baud_divisor;
AnnaBridge 189:f392fc9709a3 156 uint32_t baud_mod;
AnnaBridge 189:f392fc9709a3 157
AnnaBridge 189:f392fc9709a3 158 baud_divisor = (AHBBusClock / baudrate) >> 4;
AnnaBridge 189:f392fc9709a3 159 baud_mod = (AHBBusClock / baudrate) & 0x0F;
AnnaBridge 189:f392fc9709a3 160
AnnaBridge 189:f392fc9709a3 161 obj->uart->LCR |= (1 << 7); //enable load devisor register
AnnaBridge 189:f392fc9709a3 162
AnnaBridge 189:f392fc9709a3 163 obj->uart->DLL = (baud_divisor >> 0) & 0xFF;
AnnaBridge 189:f392fc9709a3 164 obj->uart->DLH = (baud_divisor >> 8) & 0xFF;
AnnaBridge 189:f392fc9709a3 165 obj->uart->DL2 = (baud_mod>>1) + ((baud_mod - (baud_mod>>1))<<4);
AnnaBridge 189:f392fc9709a3 166
AnnaBridge 189:f392fc9709a3 167 obj->uart->LCR &= ~(1 << 7);// after loading, disable load devisor register
AnnaBridge 189:f392fc9709a3 168
AnnaBridge 189:f392fc9709a3 169 }
AnnaBridge 189:f392fc9709a3 170
AnnaBridge 189:f392fc9709a3 171 void serial_format(serial_t *obj, int data_bits, SerialParity parity, int stop_bits)
AnnaBridge 189:f392fc9709a3 172 {
AnnaBridge 189:f392fc9709a3 173 MBED_ASSERT((stop_bits == 1) || (stop_bits == 2)); // 0: 1 stop bits, 1: 2 stop bits
AnnaBridge 189:f392fc9709a3 174 MBED_ASSERT((data_bits > 4) && (data_bits < 9)); // 0: 5 data bits ... 3: 8 data bits
AnnaBridge 189:f392fc9709a3 175 MBED_ASSERT((parity == ParityNone) || (parity == ParityOdd) || (parity == ParityEven) ||
AnnaBridge 189:f392fc9709a3 176 (parity == ParityForced1) || (parity == ParityForced0));
AnnaBridge 189:f392fc9709a3 177
AnnaBridge 189:f392fc9709a3 178 stop_bits -= 1;
AnnaBridge 189:f392fc9709a3 179 data_bits -= 5;
AnnaBridge 189:f392fc9709a3 180
AnnaBridge 189:f392fc9709a3 181 int parity_enable, parity_select;
AnnaBridge 189:f392fc9709a3 182 switch (parity) {
AnnaBridge 189:f392fc9709a3 183 case ParityNone:
AnnaBridge 189:f392fc9709a3 184 parity_enable = 0;
AnnaBridge 189:f392fc9709a3 185 parity_select = 0;
AnnaBridge 189:f392fc9709a3 186 break;
AnnaBridge 189:f392fc9709a3 187 case ParityOdd:
AnnaBridge 189:f392fc9709a3 188 parity_enable = 1;
AnnaBridge 189:f392fc9709a3 189 parity_select = 0;
AnnaBridge 189:f392fc9709a3 190 break;
AnnaBridge 189:f392fc9709a3 191 case ParityEven:
AnnaBridge 189:f392fc9709a3 192 parity_enable = 1;
AnnaBridge 189:f392fc9709a3 193 parity_select = 1;
AnnaBridge 189:f392fc9709a3 194 break;
AnnaBridge 189:f392fc9709a3 195 case ParityForced1:
AnnaBridge 189:f392fc9709a3 196 parity_enable = 1;
AnnaBridge 189:f392fc9709a3 197 parity_select = 2;
AnnaBridge 189:f392fc9709a3 198 break;
AnnaBridge 189:f392fc9709a3 199 case ParityForced0:
AnnaBridge 189:f392fc9709a3 200 parity_enable = 1;
AnnaBridge 189:f392fc9709a3 201 parity_select = 3;
AnnaBridge 189:f392fc9709a3 202 break;
AnnaBridge 189:f392fc9709a3 203 default:
AnnaBridge 189:f392fc9709a3 204 parity_enable = 0;
AnnaBridge 189:f392fc9709a3 205 parity_select = 0;
AnnaBridge 189:f392fc9709a3 206 break;
AnnaBridge 189:f392fc9709a3 207 }
AnnaBridge 189:f392fc9709a3 208
AnnaBridge 189:f392fc9709a3 209 obj->uart->LCR = (obj->uart->LCR) &
AnnaBridge 189:f392fc9709a3 210 ((~0x3FUL) |
AnnaBridge 189:f392fc9709a3 211 (data_bits << 0) |
AnnaBridge 189:f392fc9709a3 212 (stop_bits << 2) |
AnnaBridge 189:f392fc9709a3 213 (parity_enable << 3) |
AnnaBridge 189:f392fc9709a3 214 (parity_select << 4));
AnnaBridge 189:f392fc9709a3 215 }
AnnaBridge 189:f392fc9709a3 216
AnnaBridge 189:f392fc9709a3 217 /******************************************************************************
AnnaBridge 189:f392fc9709a3 218 * INTERRUPTS HANDLING
AnnaBridge 189:f392fc9709a3 219 ******************************************************************************/
AnnaBridge 189:f392fc9709a3 220 static inline void uart_irq(uint32_t iir, uint32_t index, RDA_UART_TypeDef *puart)
AnnaBridge 189:f392fc9709a3 221 {
AnnaBridge 189:f392fc9709a3 222 SerialIrq irq_type;
AnnaBridge 189:f392fc9709a3 223 switch (iir) {
AnnaBridge 189:f392fc9709a3 224 case 0x02UL: irq_type = TxIrq; break;
AnnaBridge 189:f392fc9709a3 225 case 0x04UL: irq_type = RxIrq; break;
AnnaBridge 189:f392fc9709a3 226 case 0x00UL: iir = puart->MSR;
AnnaBridge 189:f392fc9709a3 227 default: return;
AnnaBridge 189:f392fc9709a3 228 }
AnnaBridge 189:f392fc9709a3 229
AnnaBridge 189:f392fc9709a3 230 if ((RxIrq == irq_type) && ((NC != uart_data[index].sw_rts.pin) && ((puart->MCR & AFCE_MASK) == 0x00UL))) {
AnnaBridge 189:f392fc9709a3 231 gpio_write(&uart_data[index].sw_rts, 1);
AnnaBridge 189:f392fc9709a3 232 // Disable interrupt if it wasn't enabled by other part of the application
AnnaBridge 189:f392fc9709a3 233 if (!uart_data[index].rx_irq_set_api)
AnnaBridge 189:f392fc9709a3 234 puart->IER &= ~(1 << RxIrq);
AnnaBridge 189:f392fc9709a3 235 }
AnnaBridge 189:f392fc9709a3 236
AnnaBridge 189:f392fc9709a3 237 if (uart_data[index].serial_irq_id != 0)
AnnaBridge 189:f392fc9709a3 238 if ((irq_type != RxIrq) || (uart_data[index].rx_irq_set_api))
AnnaBridge 189:f392fc9709a3 239 (irq_handler[index])(uart_data[index].serial_irq_id, irq_type);
AnnaBridge 189:f392fc9709a3 240 }
AnnaBridge 189:f392fc9709a3 241
AnnaBridge 189:f392fc9709a3 242 void uart0_irq(void)
AnnaBridge 189:f392fc9709a3 243 {
AnnaBridge 189:f392fc9709a3 244 uart_irq((RDA_UART0->IIR & 0x0FUL), 0, (RDA_UART_TypeDef*)RDA_UART0);
AnnaBridge 189:f392fc9709a3 245 }
AnnaBridge 189:f392fc9709a3 246
AnnaBridge 189:f392fc9709a3 247 void uart1_irq(void)
AnnaBridge 189:f392fc9709a3 248 {
AnnaBridge 189:f392fc9709a3 249 uart_irq((RDA_UART1->IIR & 0x0FUL), 1, (RDA_UART_TypeDef*)RDA_UART1);
AnnaBridge 189:f392fc9709a3 250 }
AnnaBridge 189:f392fc9709a3 251
AnnaBridge 189:f392fc9709a3 252 void serial_irq_handler(serial_t *obj, uart_irq_handler handler, uint32_t id)
AnnaBridge 189:f392fc9709a3 253 {
AnnaBridge 189:f392fc9709a3 254 irq_handler[obj->index] = handler;
AnnaBridge 189:f392fc9709a3 255 uart_data[obj->index].serial_irq_id = id;
AnnaBridge 189:f392fc9709a3 256 }
AnnaBridge 189:f392fc9709a3 257
AnnaBridge 189:f392fc9709a3 258 static void serial_irq_set_internal(serial_t *obj, SerialIrq irq, uint32_t enable)
AnnaBridge 189:f392fc9709a3 259 {
AnnaBridge 189:f392fc9709a3 260 IRQn_Type irq_n = (IRQn_Type)0;
AnnaBridge 189:f392fc9709a3 261 uint32_t vector = 0;
AnnaBridge 189:f392fc9709a3 262 switch ((int)obj->uart) {
AnnaBridge 189:f392fc9709a3 263 case UART_0:
AnnaBridge 189:f392fc9709a3 264 irq_n=UART0_IRQn;
AnnaBridge 189:f392fc9709a3 265 vector = (uint32_t)&uart0_irq;
AnnaBridge 189:f392fc9709a3 266 break;
AnnaBridge 189:f392fc9709a3 267 case UART_1:
AnnaBridge 189:f392fc9709a3 268 irq_n=UART1_IRQn;
AnnaBridge 189:f392fc9709a3 269 vector = (uint32_t)&uart1_irq;
AnnaBridge 189:f392fc9709a3 270 break;
AnnaBridge 189:f392fc9709a3 271 default:
AnnaBridge 189:f392fc9709a3 272 break;
AnnaBridge 189:f392fc9709a3 273 }
AnnaBridge 189:f392fc9709a3 274
AnnaBridge 189:f392fc9709a3 275 if (enable) {
AnnaBridge 189:f392fc9709a3 276 obj->uart->IER |= 1 << irq;
AnnaBridge 189:f392fc9709a3 277 NVIC_SetVector(irq_n, vector);
AnnaBridge 189:f392fc9709a3 278 NVIC_SetPriority(irq_n, 0x1FUL);
AnnaBridge 189:f392fc9709a3 279 NVIC_EnableIRQ(irq_n);
AnnaBridge 189:f392fc9709a3 280 }
AnnaBridge 189:f392fc9709a3 281 else if ((TxIrq == irq) ||
AnnaBridge 189:f392fc9709a3 282 (uart_data[obj->index].rx_irq_set_api + uart_data[obj->index].rx_irq_set_flow == 0)) { // disable
AnnaBridge 189:f392fc9709a3 283 int all_disabled = 0;
AnnaBridge 189:f392fc9709a3 284 SerialIrq other_irq = (irq == RxIrq) ? (TxIrq) : (RxIrq);
AnnaBridge 189:f392fc9709a3 285 obj->uart->IER &= ~(1 << irq);
AnnaBridge 189:f392fc9709a3 286 all_disabled = (obj->uart->IER & (1 << other_irq)) == 0;
AnnaBridge 189:f392fc9709a3 287 if (all_disabled)
AnnaBridge 189:f392fc9709a3 288 NVIC_DisableIRQ(irq_n);
AnnaBridge 189:f392fc9709a3 289 }
AnnaBridge 189:f392fc9709a3 290
AnnaBridge 189:f392fc9709a3 291 }
AnnaBridge 189:f392fc9709a3 292
AnnaBridge 189:f392fc9709a3 293 void serial_irq_set(serial_t *obj, SerialIrq irq, uint32_t enable)
AnnaBridge 189:f392fc9709a3 294 {
AnnaBridge 189:f392fc9709a3 295 if (RxIrq == irq)
AnnaBridge 189:f392fc9709a3 296 uart_data[obj->index].rx_irq_set_api = enable;
AnnaBridge 189:f392fc9709a3 297 serial_irq_set_internal(obj, irq, enable);
AnnaBridge 189:f392fc9709a3 298 }
AnnaBridge 189:f392fc9709a3 299
AnnaBridge 189:f392fc9709a3 300 static void serial_flow_irq_set(serial_t *obj, uint32_t enable)
AnnaBridge 189:f392fc9709a3 301 {
AnnaBridge 189:f392fc9709a3 302 uart_data[obj->index].rx_irq_set_flow = enable;
AnnaBridge 189:f392fc9709a3 303 serial_irq_set_internal(obj, RxIrq, enable);
AnnaBridge 189:f392fc9709a3 304 }
AnnaBridge 189:f392fc9709a3 305
AnnaBridge 189:f392fc9709a3 306 /******************************************************************************
AnnaBridge 189:f392fc9709a3 307 * READ/WRITE
AnnaBridge 189:f392fc9709a3 308 ******************************************************************************/
AnnaBridge 189:f392fc9709a3 309 int serial_getc(serial_t *obj)
AnnaBridge 189:f392fc9709a3 310 {
AnnaBridge 189:f392fc9709a3 311 int data = 0;
AnnaBridge 189:f392fc9709a3 312 while (!serial_readable(obj));
AnnaBridge 189:f392fc9709a3 313 data = (int)(obj->uart->RBR & 0x00FFUL);
AnnaBridge 189:f392fc9709a3 314
AnnaBridge 189:f392fc9709a3 315 if (((obj->uart->MCR & AFCE_MASK) == 0x00UL) && (NC != uart_data[obj->index].sw_rts.pin)) { //enable flow control rx
AnnaBridge 189:f392fc9709a3 316 gpio_write(&uart_data[obj->index].sw_rts, 0);
AnnaBridge 189:f392fc9709a3 317 obj->uart->IER |= 1 << RxIrq;
AnnaBridge 189:f392fc9709a3 318 }
AnnaBridge 189:f392fc9709a3 319 return data;
AnnaBridge 189:f392fc9709a3 320 }
AnnaBridge 189:f392fc9709a3 321
AnnaBridge 189:f392fc9709a3 322 void serial_putc(serial_t *obj, int c)
AnnaBridge 189:f392fc9709a3 323 {
AnnaBridge 189:f392fc9709a3 324 while (serial_writable(obj));
AnnaBridge 189:f392fc9709a3 325 obj->uart->THR = c;
AnnaBridge 189:f392fc9709a3 326 }
AnnaBridge 189:f392fc9709a3 327
AnnaBridge 189:f392fc9709a3 328 int serial_readable(serial_t *obj)
AnnaBridge 189:f392fc9709a3 329 {
AnnaBridge 189:f392fc9709a3 330 return (obj->uart->LSR & RXFIFO_EMPTY_MASK);
AnnaBridge 189:f392fc9709a3 331 }
AnnaBridge 189:f392fc9709a3 332
AnnaBridge 189:f392fc9709a3 333 int serial_writable(serial_t *obj)
AnnaBridge 189:f392fc9709a3 334 {
AnnaBridge 189:f392fc9709a3 335 int isWritable = 1;
AnnaBridge 189:f392fc9709a3 336 if (obj->index == 0) {
AnnaBridge 189:f392fc9709a3 337 return (obj->uart->FSR & TXFIFO_FULL_MASK); // uart0 not have flow control
AnnaBridge 189:f392fc9709a3 338 } else {
AnnaBridge 189:f392fc9709a3 339 if (((obj->uart->MCR & AFCE_MASK) == 0x00UL) && (NC != uart_data[obj->index].sw_cts.pin)) //If flow control: writable if CTS low + UART done
AnnaBridge 189:f392fc9709a3 340 isWritable = (gpio_read(&uart_data[obj->index].sw_cts) == 0) && (obj->uart->FSR & TXFIFO_FULL_MASK);
AnnaBridge 189:f392fc9709a3 341 else
AnnaBridge 189:f392fc9709a3 342 isWritable = (obj->uart->FSR & TXFIFO_FULL_MASK);
AnnaBridge 189:f392fc9709a3 343 return isWritable;
AnnaBridge 189:f392fc9709a3 344 }
AnnaBridge 189:f392fc9709a3 345 }
AnnaBridge 189:f392fc9709a3 346
AnnaBridge 189:f392fc9709a3 347 void serial_clear(serial_t *obj)
AnnaBridge 189:f392fc9709a3 348 {
AnnaBridge 189:f392fc9709a3 349 obj->uart->FCR = 1 << 0 // FIFO Enable - 0 = Disables, 1 = Enabled
AnnaBridge 189:f392fc9709a3 350 | 1 << 1 // rx FIFO reset
AnnaBridge 189:f392fc9709a3 351 | 1 << 2; // tx FIFO reset
AnnaBridge 189:f392fc9709a3 352 }
AnnaBridge 189:f392fc9709a3 353
AnnaBridge 189:f392fc9709a3 354 void serial_pinout_tx(PinName tx)
AnnaBridge 189:f392fc9709a3 355 {
AnnaBridge 189:f392fc9709a3 356 pinmap_pinout(tx, PinMap_UART_TX);
AnnaBridge 189:f392fc9709a3 357 }
AnnaBridge 189:f392fc9709a3 358
AnnaBridge 189:f392fc9709a3 359 void serial_break_set(serial_t *obj)
AnnaBridge 189:f392fc9709a3 360 {
AnnaBridge 189:f392fc9709a3 361 obj->uart->LCR |= (1 << 6);
AnnaBridge 189:f392fc9709a3 362 }
AnnaBridge 189:f392fc9709a3 363
AnnaBridge 189:f392fc9709a3 364 void serial_break_clear(serial_t *obj)
AnnaBridge 189:f392fc9709a3 365 {
AnnaBridge 189:f392fc9709a3 366 obj->uart->LCR &= ~(1 << 6);
AnnaBridge 189:f392fc9709a3 367 }
AnnaBridge 189:f392fc9709a3 368
AnnaBridge 189:f392fc9709a3 369 void serial_set_flow_control(serial_t *obj, FlowControl type, PinName rxflow, PinName txflow)
AnnaBridge 189:f392fc9709a3 370 {
AnnaBridge 189:f392fc9709a3 371 // Only UART1 has hardware flow control on RDA5991H
AnnaBridge 189:f392fc9709a3 372 MBED_ASSERT((rxflow != UART0_RX) && (txflow != UART0_TX));
AnnaBridge 189:f392fc9709a3 373
AnnaBridge 189:f392fc9709a3 374 RDA_UART_TypeDef *uart1 = (uint32_t)obj->uart == (uint32_t)RDA_UART1 ? RDA_UART1 : NULL;
AnnaBridge 189:f392fc9709a3 375 int index = obj->index;
AnnaBridge 189:f392fc9709a3 376
AnnaBridge 189:f392fc9709a3 377 // First, disable flow control completely
AnnaBridge 189:f392fc9709a3 378 uart_data[index].sw_rts.pin = uart_data[index].sw_cts.pin = NC;
AnnaBridge 189:f392fc9709a3 379 serial_flow_irq_set(obj, 0);
AnnaBridge 189:f392fc9709a3 380 if (FlowControlNone == type) {
AnnaBridge 189:f392fc9709a3 381 RDA_GPIO->IFCTRL &= ~(0x01UL << 2); //disable flow control
AnnaBridge 189:f392fc9709a3 382 return;
AnnaBridge 189:f392fc9709a3 383 }
AnnaBridge 189:f392fc9709a3 384
AnnaBridge 189:f392fc9709a3 385 // Check type(s) of flow control to use
AnnaBridge 189:f392fc9709a3 386 UARTName uart_rts = (UARTName)pinmap_find_peripheral(rxflow, PinMap_UART_RTS);
AnnaBridge 189:f392fc9709a3 387 UARTName uart_cts = (UARTName)pinmap_find_peripheral(txflow, PinMap_UART_CTS);
AnnaBridge 189:f392fc9709a3 388
AnnaBridge 189:f392fc9709a3 389 if ((UART_1 == uart_cts) && (NULL != uart1)) {
AnnaBridge 189:f392fc9709a3 390 pinmap_pinout(txflow, PinMap_UART_CTS);
AnnaBridge 189:f392fc9709a3 391 gpio_init_in(&uart_data[index].sw_cts, txflow);
AnnaBridge 189:f392fc9709a3 392 }
AnnaBridge 189:f392fc9709a3 393
AnnaBridge 189:f392fc9709a3 394 if ((UART_1 == uart_rts) && (NULL != uart1)) {
AnnaBridge 189:f392fc9709a3 395 pinmap_pinout(rxflow, PinMap_UART_RTS);
AnnaBridge 189:f392fc9709a3 396 gpio_init_out(&uart_data[index].sw_rts, rxflow);
AnnaBridge 189:f392fc9709a3 397 serial_flow_irq_set(obj, 1);
AnnaBridge 189:f392fc9709a3 398 }
AnnaBridge 189:f392fc9709a3 399
AnnaBridge 189:f392fc9709a3 400 uart1->MCR = uart1->MCR | AFCE_MASK; //enable auto flow control, in this case we don't have to read and write sw_cts & sw_rts
AnnaBridge 189:f392fc9709a3 401 uart1->FRR = (0x3EUL << 0) | (0x3EUL << 9); //rts/cts fifo trigger
AnnaBridge 189:f392fc9709a3 402 RDA_GPIO->IFCTRL |= 0x01UL << 2; //enable flow control
AnnaBridge 189:f392fc9709a3 403 }