source: EcnlProtoTool/trunk/asp3_dcre/mbed/targets/hal/TARGET_RENESAS/TARGET_RZ_A1H/serial_api.c@ 270

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

mruby版ECNLプロトタイピング・ツールを追加

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
  • Property svn:mime-type set to text/x-csrc
File size: 17.1 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 "pinmap.h"
25#include "gpio_api.h"
26
27#include "scif_iodefine.h"
28#include "cpg_iodefine.h"
29
30/******************************************************************************
31 * INITIALIZATION
32 ******************************************************************************/
33#define PCLK (66666666) // Define the peripheral clock P1 frequency.
34
35#define UART_NUM 8
36#define IRQ_NUM 2
37
38static void uart0_tx_irq(void);
39static void uart1_tx_irq(void);
40static void uart2_tx_irq(void);
41static void uart3_tx_irq(void);
42static void uart4_tx_irq(void);
43static void uart5_tx_irq(void);
44static void uart6_tx_irq(void);
45static void uart7_tx_irq(void);
46static void uart0_rx_irq(void);
47static void uart1_rx_irq(void);
48static void uart2_rx_irq(void);
49static void uart3_rx_irq(void);
50static void uart4_rx_irq(void);
51static void uart5_rx_irq(void);
52static void uart6_rx_irq(void);
53static void uart7_rx_irq(void);
54
55
56static const PinMap PinMap_UART_TX[] = {
57 {P2_14 , UART0, 6},
58 {P2_5 , UART1, 6},
59 {P4_12 , UART1, 7},
60 {P6_3 , UART2, 7},
61 {P4_14 , UART2, 7},
62 {P5_3 , UART3, 5},
63 {P8_8 , UART3, 7},
64 {P5_0 , UART4, 5},
65 {P8_14 , UART4, 7},
66 {P8_13 , UART5, 5},
67 {P11_10, UART5, 3},
68 {P6_6 , UART5, 5},
69 {P5_6 , UART6, 5},
70 {P11_1 , UART6, 4},
71 {P7_4 , UART7, 4},
72 {NC , NC , 0}
73};
74
75static const PinMap PinMap_UART_RX[] = {
76 {P2_15 , UART0, 6},
77 {P2_6 , UART1, 6},
78 {P4_13 , UART1, 7},
79 {P6_2 , UART2, 7},
80 {P4_15 , UART2, 7},
81 {P5_4 , UART3, 5},
82 {P8_9 , UART3, 7},
83 {P5_1 , UART4, 5},
84 {P8_15 , UART4, 7},
85 {P8_11 , UART5, 5},
86 {P11_11, UART5, 3},
87 {P6_7 , UART5, 5},
88 {P5_7 , UART6, 5},
89 {P11_2 , UART6, 4},
90 {P7_5 , UART7, 4},
91 {NC , NC , 0}
92};
93
94static const PinMap PinMap_UART_CTS[] = {
95 {P2_3 , UART1, 6},
96 {P11_7 , UART5, 3},
97 {P7_6 , UART7, 4},
98 {NC , NC , 0}
99};
100static const PinMap PinMap_UART_RTS[] = {
101 {P2_7 , UART1, 6},
102 {P11_8 , UART5, 3},
103 {P7_7 , UART7, 4},
104 {NC , NC , 0}
105};
106
107
108
109static const struct st_scif *SCIF[] = SCIF_ADDRESS_LIST;
110static uart_irq_handler irq_handler;
111
112int stdio_uart_inited = 0;
113serial_t stdio_uart;
114
115struct serial_global_data_s {
116 uint32_t serial_irq_id;
117 gpio_t sw_rts, sw_cts;
118 uint8_t count, rx_irq_set_flow, rx_irq_set_api;
119};
120
121static struct serial_global_data_s uart_data[UART_NUM];
122
123static const IRQn_Type irq_set_tbl[UART_NUM][IRQ_NUM] = {
124 {SCIFRXI0_IRQn, SCIFTXI0_IRQn},
125 {SCIFRXI1_IRQn, SCIFTXI1_IRQn},
126 {SCIFRXI2_IRQn, SCIFTXI2_IRQn},
127 {SCIFRXI3_IRQn, SCIFTXI3_IRQn},
128 {SCIFRXI4_IRQn, SCIFTXI4_IRQn},
129 {SCIFRXI5_IRQn, SCIFTXI5_IRQn},
130 {SCIFRXI6_IRQn, SCIFTXI6_IRQn},
131 {SCIFRXI7_IRQn, SCIFTXI7_IRQn}
132};
133
134static const IRQHandler hander_set_tbl[UART_NUM][IRQ_NUM] = {
135 {uart0_rx_irq, uart0_tx_irq},
136 {uart1_rx_irq, uart1_tx_irq},
137 {uart2_rx_irq, uart2_tx_irq},
138 {uart3_rx_irq, uart3_tx_irq},
139 {uart4_rx_irq, uart4_tx_irq},
140 {uart5_rx_irq, uart5_tx_irq},
141 {uart6_rx_irq, uart6_tx_irq},
142 {uart7_rx_irq, uart7_tx_irq}
143};
144
145static __IO uint16_t *SCSCR_MATCH[] = {
146 &SCSCR_0,
147 &SCSCR_1,
148 &SCSCR_2,
149 &SCSCR_3,
150 &SCSCR_4,
151 &SCSCR_5,
152 &SCSCR_6,
153 &SCSCR_7,
154};
155
156static __IO uint16_t *SCFSR_MATCH[] = {
157 &SCFSR_0,
158 &SCFSR_1,
159 &SCFSR_2,
160 &SCFSR_3,
161 &SCFSR_4,
162 &SCFSR_5,
163 &SCFSR_6,
164 &SCFSR_7,
165};
166
167
168void serial_init(serial_t *obj, PinName tx, PinName rx) {
169 volatile uint8_t dummy ;
170 int is_stdio_uart = 0;
171 // determine the UART to use
172 uint32_t uart_tx = pinmap_peripheral(tx, PinMap_UART_TX);
173 uint32_t uart_rx = pinmap_peripheral(rx, PinMap_UART_RX);
174 uint32_t uart = pinmap_merge(uart_tx, uart_rx);
175
176 MBED_ASSERT((int)uart != NC);
177
178 obj->uart = (struct st_scif *)SCIF[uart];
179 // enable power
180 switch (uart) {
181 case UART0:
182 CPG.STBCR4 &= ~(1 << 7);
183 break;
184 case UART1:
185 CPG.STBCR4 &= ~(1 << 6);
186 break;
187 case UART2:
188 CPG.STBCR4 &= ~(1 << 5);
189 break;
190 case UART3:
191 CPG.STBCR4 &= ~(1 << 4);
192 break;
193 case UART4:
194 CPG.STBCR4 &= ~(1 << 3);
195 break;
196 case UART5:
197 CPG.STBCR4 &= ~(1 << 2);
198 break;
199 case UART6:
200 CPG.STBCR4 &= ~(1 << 1);
201 break;
202 case UART7:
203 CPG.STBCR4 &= ~(1 << 0);
204 break;
205 }
206 dummy = CPG.STBCR4;
207
208 /* ==== SCIF initial setting ==== */
209 /* ---- Serial control register (SCSCR) setting ---- */
210 /* B'00 : Internal CLK */
211 obj->uart->SCSCR = 0x0000u; /* SCIF transmitting and receiving operations stop */
212
213 /* ---- FIFO control register (SCFCR) setting ---- */
214 /* Transmit FIFO reset & Receive FIFO data register reset */
215 obj->uart->SCFCR = 0x0006;
216
217 /* ---- Serial status register (SCFSR) setting ---- */
218 dummy = obj->uart->SCFSR;
219 obj->uart->SCFSR = (dummy & 0xFF6Cu); /* ER,BRK,DR bit clear */
220
221 /* ---- Line status register (SCLSR) setting ---- */
222 /* ORER bit clear */
223 obj->uart->SCLSR = 0;
224
225 /* ---- Serial extension mode register (SCEMR) setting ----
226 b7 BGDM - Baud rate generator double-speed mode : Normal mode
227 b0 ABCS - Base clock select in asynchronous mode : Base clock is 16 times the bit rate */
228 obj->uart->SCEMR = 0x0000u;
229
230 /* ---- Bit rate register (SCBRR) setting ---- */
231 serial_baud (obj, 9600);
232 serial_format(obj, 8, ParityNone, 1);
233
234 /* ---- FIFO control register (SCFCR) setting ---- */
235 obj->uart->SCFCR = 0x0030u;
236
237 /* ---- Serial port register (SCSPTR) setting ----
238 b1 SPB2IO - Serial port break output : disabled
239 b0 SPB2DT - Serial port break data : High-level */
240 obj->uart->SCSPTR = 0x0003u; // SPB2IO = 1, SPB2DT = 1
241
242 /* ---- Line status register (SCLSR) setting ----
243 b0 ORER - Overrun error detect : clear */
244
245 if (obj->uart->SCLSR & 0x0001) {
246 obj->uart->SCLSR = 0u; // ORER clear
247 }
248
249 // pinout the chosen uart
250 pinmap_pinout(tx, PinMap_UART_TX);
251 pinmap_pinout(rx, PinMap_UART_RX);
252
253 switch (uart) {
254 case UART0:
255 obj->index = 0;
256 break;
257 case UART1:
258 obj->index = 1;
259 break;
260 case UART2:
261 obj->index = 2;
262 break;
263 case UART3:
264 obj->index = 3;
265 break;
266 case UART4:
267 obj->index = 4;
268 break;
269 case UART5:
270 obj->index = 5;
271 break;
272 case UART6:
273 obj->index = 6;
274 break;
275 case UART7:
276 obj->index = 7;
277 break;
278 }
279 uart_data[obj->index].sw_rts.pin = NC;
280 uart_data[obj->index].sw_cts.pin = NC;
281
282 /* ---- Serial control register (SCSCR) setting ---- */
283 /* Setting the TE and RE bits enables the TxD and RxD pins to be used. */
284 obj->uart->SCSCR = 0x00F0;
285
286 is_stdio_uart = (uart == STDIO_UART) ? (1) : (0);
287
288 if (is_stdio_uart) {
289 stdio_uart_inited = 1;
290 memcpy(&stdio_uart, obj, sizeof(serial_t));
291 }
292}
293
294void serial_free(serial_t *obj) {
295 uart_data[obj->index].serial_irq_id = 0;
296}
297
298// serial_baud
299// set the baud rate, taking in to account the current SystemFrequency
300void serial_baud(serial_t *obj, int baudrate) {
301 uint16_t DL;
302
303 obj->uart->SCSMR &= ~0x0003;
304
305 if (baudrate > 32552) {
306 obj->uart->SCEMR = 0x0081; // BGDM = 1, ABCS = 1
307 DL = PCLK / (8 * baudrate);
308 if (DL > 0) {
309 DL--;
310 }
311 obj->uart->SCBRR = (uint8_t)DL;
312 } else if (baudrate > 16276) {
313 obj->uart->SCEMR = 0x0080; // BGDM = 1
314 obj->uart->SCBRR = PCLK / (16 * baudrate) - 1;
315 } else if (baudrate > 8138) {
316 obj->uart->SCEMR = 0x0000;
317 obj->uart->SCBRR = PCLK / (32 * baudrate) - 1;
318 } else if (baudrate > 4169) {
319 obj->uart->SCSMR |= 0x0001;
320 obj->uart->SCEMR = 0x0080; // BGDM = 1
321 obj->uart->SCBRR = PCLK / (64 * baudrate) - 1;
322 } else if (baudrate > 2034) {
323 obj->uart->SCSMR |= 0x0001;
324 obj->uart->SCEMR = 0x0000;
325 obj->uart->SCBRR = PCLK / (128 * baudrate) - 1;
326 } else if (baudrate > 1017) {
327 obj->uart->SCSMR |= 0x0002;
328 obj->uart->SCEMR = 0x0080; // BGDM = 1
329 obj->uart->SCBRR = PCLK / (256 * baudrate) - 1;
330 } else if (baudrate > 508) {
331 obj->uart->SCSMR |= 0x0002;
332 obj->uart->SCEMR = 0x0000;
333 obj->uart->SCBRR = PCLK / (512 * baudrate) - 1;
334 } else if (baudrate > 254) {
335 obj->uart->SCSMR |= 0x0003;
336 obj->uart->SCEMR = 0x0080; // BGDM = 1
337 obj->uart->SCBRR = PCLK / (1024 * baudrate) - 1;
338 } else if (baudrate > 127) {
339 obj->uart->SCSMR |= 0x0003;
340 obj->uart->SCEMR = 0x0000;
341 obj->uart->SCBRR = PCLK / (2048 * baudrate) - 1;
342 } else {
343 obj->uart->SCSMR |= 0x0003;
344 obj->uart->SCEMR = 0x0000;
345 obj->uart->SCBRR = 0xFFu;
346 }
347}
348
349void serial_format(serial_t *obj, int data_bits, SerialParity parity, int stop_bits) {
350 int parity_enable;
351 int parity_select;
352
353 MBED_ASSERT((stop_bits == 1) || (stop_bits == 2)); // 0: 1 stop bits, 1: 2 stop bits
354 MBED_ASSERT((data_bits > 4) && (data_bits < 9)); // 5: 5 data bits ... 3: 8 data bits
355 MBED_ASSERT((parity == ParityNone) || (parity == ParityOdd) || (parity == ParityEven) ||
356 (parity == ParityForced1) || (parity == ParityForced0));
357
358 stop_bits = (stop_bits == 1)? 0:
359 (stop_bits == 2)? 1:
360 0; // must not to be
361
362 data_bits = (data_bits == 8)? 0:
363 (data_bits == 7)? 1:
364 0; // must not to be
365
366 switch (parity) {
367 case ParityNone:
368 parity_enable = 0;
369 parity_select = 0;
370 break;
371 case ParityOdd:
372 parity_enable = 1;
373 parity_select = 1;
374 break;
375 case ParityEven:
376 parity_enable = 1;
377 parity_select = 0;
378 break;
379 case ParityForced1:
380 case ParityForced0:
381 default:
382 parity_enable = 0;
383 parity_select = 0;
384 break;
385 }
386
387 obj->uart->SCSMR = data_bits << 6
388 | parity_enable << 5
389 | parity_select << 4
390 | stop_bits << 3;
391}
392
393/******************************************************************************
394 * INTERRUPTS HANDLING
395 ******************************************************************************/
396
397static void uart_tx_irq(IRQn_Type irq_num, uint32_t index) {
398 __IO uint16_t *dmy_rd_scscr;
399 __IO uint16_t *dmy_rd_scfsr;
400
401 dmy_rd_scscr = SCSCR_MATCH[index];
402 *dmy_rd_scscr &= 0x007B; // Clear TIE and Write to bit15~8,2 is always 0
403 dmy_rd_scfsr = SCFSR_MATCH[index];
404 *dmy_rd_scfsr = (*dmy_rd_scfsr & ~0x0020); // Clear TDFE
405
406 irq_handler(uart_data[index].serial_irq_id, TxIrq);
407}
408
409static void uart_rx_irq(IRQn_Type irq_num, uint32_t index) {
410 __IO uint16_t *dmy_rd_scscr;
411 __IO uint16_t *dmy_rd_scfsr;
412
413 dmy_rd_scscr = SCSCR_MATCH[index];
414 *dmy_rd_scscr &= 0x00B3; // Clear RIE,REIE and Write to bit15~8,2 is always 0
415 dmy_rd_scfsr = SCFSR_MATCH[index];
416 *dmy_rd_scfsr = (*dmy_rd_scfsr & ~0x0003); // Clear RDF,DR
417
418 irq_handler(uart_data[index].serial_irq_id, RxIrq);
419}
420
421/* TX handler */
422static void uart0_tx_irq(void) {
423 uart_tx_irq(SCIFTXI0_IRQn, 0);
424}
425static void uart1_tx_irq(void) {
426 uart_tx_irq(SCIFTXI1_IRQn, 1);
427}
428static void uart2_tx_irq(void) {
429 uart_tx_irq(SCIFTXI2_IRQn, 2);
430}
431static void uart3_tx_irq(void) {
432 uart_tx_irq(SCIFTXI3_IRQn, 3);
433}
434static void uart4_tx_irq(void) {
435 uart_tx_irq(SCIFTXI4_IRQn, 4);
436}
437static void uart5_tx_irq(void) {
438 uart_tx_irq(SCIFTXI5_IRQn, 5);
439}
440static void uart6_tx_irq(void) {
441 uart_tx_irq(SCIFTXI6_IRQn, 6);
442}
443static void uart7_tx_irq(void) {
444 uart_tx_irq(SCIFTXI7_IRQn, 7);
445}
446/* RX handler */
447static void uart0_rx_irq(void) {
448 uart_rx_irq(SCIFRXI0_IRQn, 0);
449}
450static void uart1_rx_irq(void) {
451 uart_rx_irq(SCIFRXI1_IRQn, 1);
452}
453static void uart2_rx_irq(void) {
454 uart_rx_irq(SCIFRXI2_IRQn, 2);
455}
456static void uart3_rx_irq(void) {
457 uart_rx_irq(SCIFRXI3_IRQn, 3);
458}
459static void uart4_rx_irq(void) {
460 uart_rx_irq(SCIFRXI4_IRQn, 4);
461}
462static void uart5_rx_irq(void) {
463 uart_rx_irq(SCIFRXI5_IRQn, 5);
464}
465static void uart6_rx_irq(void) {
466 uart_rx_irq(SCIFRXI6_IRQn, 6);
467}
468static void uart7_rx_irq(void) {
469 uart_rx_irq(SCIFRXI7_IRQn, 7);
470}
471
472void serial_irq_handler(serial_t *obj, uart_irq_handler handler, uint32_t id) {
473 irq_handler = handler;
474 uart_data[obj->index].serial_irq_id = id;
475}
476
477static void serial_irq_set_internal(serial_t *obj, SerialIrq irq, uint32_t enable) {
478 IRQn_Type IRQn;
479 IRQHandler handler;
480
481 IRQn = irq_set_tbl[obj->index][irq];
482 handler = hander_set_tbl[obj->index][irq];
483
484 if ((obj->index >= 0) && (obj->index <= 7)) {
485 if (enable) {
486 InterruptHandlerRegister(IRQn, (void (*)(uint32_t))handler);
487 GIC_SetPriority(IRQn, 5);
488 GIC_EnableIRQ(IRQn);
489 } else {
490 GIC_DisableIRQ(IRQn);
491 }
492 }
493}
494
495void serial_irq_set(serial_t *obj, SerialIrq irq, uint32_t enable) {
496 if (RxIrq == irq) {
497 uart_data[obj->index].rx_irq_set_api = enable;
498 }
499 serial_irq_set_internal(obj, irq, enable);
500}
501
502static void serial_flow_irq_set(serial_t *obj, uint32_t enable) {
503 uart_data[obj->index].rx_irq_set_flow = enable;
504 serial_irq_set_internal(obj, RxIrq, enable);
505}
506
507/******************************************************************************
508 * READ/WRITE
509 ******************************************************************************/
510int serial_getc(serial_t *obj) {
511 uint16_t err_read;
512 int data;
513 int was_masked;
514
515 was_masked = __disable_irq();
516 if (obj->uart->SCFSR & 0x93) {
517 err_read = obj->uart->SCFSR;
518 obj->uart->SCFSR = (err_read & ~0x93);
519 }
520 obj->uart->SCSCR |= 0x0040; // Set RIE
521 if (!was_masked) {
522 __enable_irq();
523 }
524
525 if (obj->uart->SCLSR & 0x0001) {
526 obj->uart->SCLSR = 0u; // ORER clear
527 }
528
529 while (!serial_readable(obj));
530 data = obj->uart->SCFRDR & 0xff;
531
532 was_masked = __disable_irq();
533 err_read = obj->uart->SCFSR;
534 obj->uart->SCFSR = (err_read & 0xfffD); // Clear RDF
535 if (!was_masked) {
536 __enable_irq();
537 }
538
539 if (err_read & 0x80) {
540 data = -1; //err
541 }
542 return data;
543}
544
545void serial_putc(serial_t *obj, int c) {
546 uint16_t dummy_read;
547 int was_masked;
548
549 was_masked = __disable_irq();
550 obj->uart->SCSCR |= 0x0080; // Set TIE
551 if (!was_masked) {
552 __enable_irq();
553 }
554 while (!serial_writable(obj));
555 obj->uart->SCFTDR = c;
556 was_masked = __disable_irq();
557 dummy_read = obj->uart->SCFSR;
558 obj->uart->SCFSR = (dummy_read & 0xff9f); // Clear TEND/TDFE
559 if (!was_masked) {
560 __enable_irq();
561 }
562 uart_data[obj->index].count++;
563}
564
565int serial_readable(serial_t *obj) {
566 return ((obj->uart->SCFSR & 0x02) != 0); // RDF
567}
568
569int serial_writable(serial_t *obj) {
570 return ((obj->uart->SCFSR & 0x20) != 0); // TDFE
571}
572
573void serial_clear(serial_t *obj) {
574 int was_masked;
575 was_masked = __disable_irq();
576
577 obj->uart->SCFCR |= 0x06; // TFRST = 1, RFRST = 1
578 obj->uart->SCFCR &= ~0x06; // TFRST = 0, RFRST = 0
579 obj->uart->SCFSR &= ~0x0093u; // ER, BRK, RDF, DR = 0
580
581 if (!was_masked) {
582 __enable_irq();
583 }
584}
585
586void serial_pinout_tx(PinName tx) {
587 pinmap_pinout(tx, PinMap_UART_TX);
588}
589
590void serial_break_set(serial_t *obj) {
591 int was_masked;
592 was_masked = __disable_irq();
593 // TxD Output(L)
594 obj->uart->SCSPTR &= ~0x0001u; // SPB2DT = 0
595 obj->uart->SCSCR &= ~0x0020u; // TE = 0 (Output disable)
596 if (!was_masked) {
597 __enable_irq();
598 }
599}
600
601void serial_break_clear(serial_t *obj) {
602 int was_masked;
603 was_masked = __disable_irq();
604 obj->uart->SCSCR |= 0x0020u; // TE = 1 (Output enable)
605 obj->uart->SCSPTR |= 0x0001u; // SPB2DT = 1
606 if (!was_masked) {
607 __enable_irq();
608 }
609}
610
611void serial_set_flow_control(serial_t *obj, FlowControl type, PinName rxflow, PinName txflow) {
612 // determine the UART to use
613 int was_masked;
614
615 serial_flow_irq_set(obj, 0);
616
617 if (type == FlowControlRTSCTS) {
618 was_masked = __disable_irq();
619 obj->uart->SCFCR = 0x0008u; // CTS/RTS enable
620 if (!was_masked) {
621 __enable_irq();
622 }
623 pinmap_pinout(rxflow, PinMap_UART_RTS);
624 pinmap_pinout(txflow, PinMap_UART_CTS);
625 } else {
626 was_masked = __disable_irq();
627 obj->uart->SCFCR = 0x0000u; // CTS/RTS diable
628 if (!was_masked) {
629 __enable_irq();
630 }
631 }
632}
633
634
635
636
Note: See TracBrowser for help on using the repository browser.