source: asp3_tinet_ecnl_arm/trunk/asp3_dcre/mbed/targets/TARGET_RENESAS/TARGET_RZA1XX/serial_api.c@ 387

Last change on this file since 387 was 387, checked in by coas-nagasima, 5 years ago

ファイルディスクリプタ処理を更新

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