added prescaler for 16 bit pwm in LPC1347 target

Fork of mbed-dev by mbed official

Committer:
JojoS
Date:
Sat Sep 10 15:32:04 2016 +0000
Revision:
147:ba84b7dc41a7
Parent:
144:ef7eb2e8f9f7
added prescaler for 16 bit timers (solution as in LPC11xx), default prescaler 31 for max 28 ms period time

Who changed what in which revision?

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