1 /*
2 * Copyright (c) 2006-2021, RT-Thread Development Team
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 *
6 * Change Logs:
7 * Date Author Notes
8 */
9
10 #include <rthw.h>
11 #include <rtthread.h>
12 #include <rtdevice.h>
13 #include "board.h"
14 #include "uart.h"
15 #include <stdint.h>
16 #include <stdbool.h>
17 #include "r_pdl_sci.h"
18 /* General RPDL function definitions */
19 #include "r_pdl_definitions.h"
20 #include "intrinsics.h"
21 #include "iorx62n.h"
22
23 //#include <string.h>
24
25
26 /* Clock selection control */
27 #define SCI_CKS_MIN 0
28 #define SCI_CKS_MAX 3
29 #define SCI_CKS_STEP 1
30
31
32 #define IPR_ADDRESS(a) ((volatile unsigned char *)&ICU.IPR[IPR_SCI0_ + a])
33 //#define IER_ADDRESS(a) ((volatile unsigned char *)&(ICU.IER[IER_SCI0_ERI0 + a])/sizeof(unsigned char))
34 #define ERI_ADDRESS(a) ((volatile unsigned char *)&ICU.IR[IR_SCI0_ERI0] + ((4 * a) / sizeof(unsigned char)) )
35 #define IER_ADDRESS(a) ((volatile unsigned char *)&ICU.IER[IER_SCI0_ERI0] + ((4 * a) / sizeof(unsigned char)) )
36 #define RXI_ADDRESS(a) ((volatile unsigned char *)&ICU.IR[IR_SCI0_RXI0] + ((4 * a) / sizeof(unsigned char)) )
37 #define TXI_ADDRESS(a) ((volatile unsigned char *)&ICU.IR[IR_SCI0_TXI0] + ((4 * a) / sizeof(unsigned char)) )
38 #define TEI_ADDRESS(a) ((volatile unsigned char *)&ICU.IR[IR_SCI0_TEI0] + ((4 * a) / sizeof(unsigned char)) )
39 #define RXI_DTCER_ADDRESS(a) (( volatile unsigned char *)&ICU.DTCER[IR_SCI0_RXI0]+ ((4*a)/sizeof(unsigned char)))
40 #define TXI_DTCER_ADDRESS(a) (( volatile unsigned char *)&ICU.DTCER[IR_SCI0_TXI0]+ ((4*a) / sizeof(unsigned char)))
41 //#define SCI1_USE_B
42 //#define SCI2_USE_B
43 //#define SCI3_USE_B
44 //#define SCI6_USE_B
45
46 #define SourceClk 12000000
47 #define rpdl_CGC_f_pclk SourceClk * 4
48 /* Idle output options */
49 #define SPACE 0
50 #define MARK 1
51
52 typedef int UART_ID_Type;
53 typedef int IRQn_Type;
54
55 #define SCI2_USE_B
56
57 struct rx_uart
58 {
59 UART_ID_Type UART;
60 volatile struct st_sci __sfr * sci;
61 };
62
rx_configure(struct rt_serial_device * serial,struct serial_configure * cfg)63 static rt_err_t rx_configure(struct rt_serial_device *serial, struct serial_configure *cfg)
64 {
65 #if 1
66 struct rx_uart *uart;
67
68 unsigned char smr_copy;
69 unsigned char semr_copy;
70 unsigned char scr_copy;
71 unsigned char scmr_copy;
72 unsigned long brr_divider;
73 unsigned long bit_interval_counter;
74 RT_ASSERT(serial != RT_NULL);
75 uart = (struct rx_uart *)serial->parent.user_data;
76
77 if (uart->UART > 6) {
78 return -RT_ERROR;
79 }
80 /* Initialise the working copies */
81 smr_copy = 0x00u;
82 scr_copy = 0x00u;
83 semr_copy = 0x00u;
84 scmr_copy = 0x72u;
85 brr_divider = 0;
86
87 switch (uart->UART) {
88 case 0:
89 SYSTEM.MSTPCRB.BIT.MSTPB31 = 0;
90 /* Enable the input buffer */
91 PORT2.ICR.BIT.B2 = 1;
92 /* Ensure the pin is set to input */
93 PORT2.DDR.BIT.B2 = 0;
94 /* Disable the USB0_DRPD output */
95 IOPORT.PFKUSB.BIT.USBE = 0;
96 /* Disable the MTIOC3B-A output */
97 MTU3.TIORH.BIT.IOB = 0;
98 /* Disable the TMO0 output */
99 TMR0.TCSR.BIT.OSA = 0;
100 TMR0.TCSR.BIT.OSB = 0;
101 /* Disable the MTIOC1A output */
102 MTU1.TIOR.BIT.IOA = 0;
103 /* Set the idle state direction */
104 PORT2.DDR.BIT.B0 = 1;
105 PORT2.DR.BIT.B0 = 1;
106 PORT2.ICR.BIT.B0 = 1;
107 PORT2.ICR.BIT.B1 = 1;
108 break;
109 case 1:
110 SYSTEM.MSTPCRB.BIT.MSTPB30 = 0;
111
112 /* Disable the CS6#-C output */
113 IOPORT.PF0CSE.BIT.CS6E = 0;
114 /* Disable the MOSIB-A output */
115 IOPORT.PFHSPI.BIT.MOSIE = 0;
116 /* Disable the MTIOC2A output */
117 MTU2.TIOR.BIT.IOA = 0;
118 /* Disable the TMO1 output */
119 TMR1.TCSR.BYTE = 0xF0u;
120 #ifdef SCI1_USE_B
121
122 IOPORT.PFFSCI.BIT.SCI1S = 1;
123 PORTF.DDR.BIT.B2 = 0;
124 PORTF.ICR.BIT.B2 = 1;
125 PORTF.DDR.BIT.B0 = 1;
126 PORTF.DR.BIT.B0 = 1;
127 #else
128 IOPORT.PFFSCI.BIT.SCI1S = 0;
129
130 /* Set the idle state direction */
131 PORT2.DDR.BIT.B6 = 1;
132 PORT2.DR.BIT.B6 = 1;
133 // PORT2.DR.BIT.B6 = 1;
134 /* Enable the input buffer */
135 //PORT3.ICR.BIT.B0 = 1;
136 /* Ensure the pin is set to input */
137 PORT3.DDR.BIT.B0 = 0;
138
139
140 #endif
141
142 break;
143 case 2:
144 SYSTEM.MSTPCRB.BIT.MSTPB29 = 0;
145 /* Disable the SSLB2-A output */
146 IOPORT.PFHSPI.BIT.SSL2E = 0;
147
148 #ifdef SCI2_USE_B
149 IOPORT.PFFSCI.BIT.SCI2S = 1;
150 PORT5.DDR.BIT.B0 = 1;
151 PORT5.DR.BIT.B0 = 1;
152 PORT5.DDR.BIT.B2 = 0;
153 PORT5.ICR.BIT.B2 = 1;
154 /* Disable the SSLB1-A output */
155 IOPORT.PFHSPI.BIT.SSL1E = 0;
156
157 #else
158 IOPORT.PFFSCI.BIT.SCI2S = 0;
159 /* Enable the input buffer */
160 PORT1.ICR.BIT.B2 = 1;
161 /* Ensure the pin is set to input */
162 PORT1.DDR.BIT.B2 = 0;
163 PORT1.DDR.BIT.B3 = 1;
164 PORT1.DR.BIT.B3 = 1;
165 /* Disable the TMO3 output */
166 TMR3.TCSR.BYTE = 0xF0u;
167 #endif
168 break;
169 case 3:
170 SYSTEM.MSTPCRB.BIT.MSTPB28 = 0;
171 #ifdef SCI3_USE_B
172 IOPORT.PFFSCI.BIT.SCI3S = 1;
173 PORT2.DDR.BIT.B5 = 0;
174 PORT2.ICR.BIT.B5 = 1;
175 PORT2.DDR.BIT.B3 = 1;
176 PORT2.DR.BIT.B3 = 1;
177 IOPORT.PF0CSE.BIT.CS4E = 0;
178 /* Disable the USB0_VBUSEN-A output */
179 IOPORT.PFKUSB.BIT.USBE = 0;
180 /* Disable the MTIOC4A-A output */
181 MTU4.TIORH.BIT.IOA = 0;
182 /* Disable the USB0_DPUPE-A output */
183 IOPORT.PFKUSB.BIT.USBE = 0;
184 /* Disable the EDACK0-B output */
185 EXDMAC0.EDMOMD.BIT.DACKE = 0;
186 /* Disable the MTIOC3D-A output */
187 MTU3.TIORL.BIT.IOD = 0;
188
189 #else
190
191 IOPORT.PFFSCI.BIT.SCI3S = 0;
192 /* Disable the MTIOC0B output */
193 MTU0.TIORH.BIT.IOB = 0;
194 PORT1.DDR.BIT.B6 = 0;
195 PORT1.ICR.BIT.B6 = 1;
196 PORT1.DDR.BIT.B7 = 1;
197 PORT1.DR.BIT.B7 = 1;
198 MTU3.TIORH.BIT.IOA = 0;
199 /* Set the idle state direction */
200 #endif
201 break;
202 //case UartPort4:
203 // SYSTEM.MSTPCRB.BIT.MSTPB27 = 0;
204 // break;
205 case 5:
206 SYSTEM.MSTPCRB.BIT.MSTPB26 = 0;
207 /* Enable the input buffer */
208 PORTC.ICR.BIT.B1 = 1;
209 /* Ensure the pin is set to input */
210 PORTC.DDR.BIT.B1 = 0;
211 PORTC.DDR.BIT.B3 = 1;
212 PORTC.DR.BIT.B3 = 1;
213 /* Disable the A17-A output */
214 IOPORT.PF3BUS.BIT.A17E = 0;
215 break;
216 case 6:
217
218
219 SYSTEM.MSTPCRB.BIT.MSTPB25 = 0;
220
221 #ifdef SCI6_USE_B
222 IOPORT.PFFSCI.BIT.SCI6S = 1;
223 PORT3.DDR.BIT.B3 = 0;
224 //PORT3.ICR.BIT.B3 = 1;
225 PORT3.DDR.BIT.B2 = 1;
226 PORT3.DR.BIT.B2 = 1;
227 /* Disable the MTIOC0A output */
228 MTU0.TIORH.BIT.IOA = 0;
229 /* Disable the CTX0 output */
230 IOPORT.PFJCAN.BIT.CAN0E = 0;
231 /* Disable the MTIOC0C output */
232 MTU0.TIORL.BIT.IOC = 0;
233 #else
234 IOPORT.PFFSCI.BIT.SCI6S = 0;
235 PORT0.DDR.BIT.B0 = 1;
236 PORT0.DR.BIT.B0 = 1;
237 PORT0.ICR.BIT.B1 = 1;
238 PORT0.DDR.BIT.B1 = 0;
239
240 #endif
241 break;
242 default:
243 break;
244 }
245
246
247 /*stop bit*/
248 if (cfg->stop_bits == STOP_BITS_2) {
249 smr_copy |= BIT_3;
250 } else if (cfg->stop_bits != STOP_BITS_1) {
251 return -RT_ERROR;
252 }
253
254 /*data bit*/
255 if (cfg->data_bits == 7) {
256 smr_copy |= BIT_6;
257 } else if (cfg->data_bits != DATA_BITS_8) {
258 return -RT_ERROR;
259 }
260
261 /*parity*/
262 if (cfg->parity == PARITY_ODD)
263 smr_copy |= BIT_5;
264 else if (cfg->parity == PARITY_EVEN)
265 smr_copy |= BIT_4 | BIT_5;
266
267
268
269 brr_divider = rpdl_CGC_f_pclk / cfg->baud_rate;
270 /* There is a fixed division by 2 */
271 brr_divider /= 16;
272
273 /* Select 8 base clock cycles (ABCS = 1) */
274 semr_copy |= (unsigned char)BIT_4;
275 //brr_divider /= 8;
276 /* More division required? */
277 if (brr_divider > 256) {
278 /* Select 16 base clock cycles (ABCS = 0) */
279 semr_copy &= (unsigned char)INV_BIT_4;
280 brr_divider /= 2;
281 }
282
283 /* Load the BRR reset value */
284 //brr_copy = 0xFFu;
285
286
287 /* Ensure bits TIE, RIE, TE, RE and TEIE in the SCR are 0 */
288 uart->sci->SCR.BYTE = 0x00;
289
290 /* Configure the CKE & MPIE bits */
291 uart->sci->SCR.BYTE = scr_copy & (BIT_0 | BIT_1 | BIT_3);
292
293 /* Configure the SMR register */
294 uart->sci->SMR.BYTE = smr_copy;
295 /* Configure the SCMR register */
296 uart->sci->SCMR.BYTE = scmr_copy;
297 /* Configure the SEMR register */
298 uart->sci->SEMR.BYTE = semr_copy;
299 /* Configure the BRR register */
300 uart->sci->BRR = brr_divider - 1;
301
302 bit_interval_counter = rpdl_CGC_f_pclk / cfg->baud_rate;
303 /* Wait for at least a 1-bit duration */
304 do {
305 bit_interval_counter--;
306 }while (bit_interval_counter != 0);
307
308 scr_copy = 0x00u;
309
310 /*enable rx an tx*/
311 scr_copy |= BIT_5 | BIT_4 ;
312
313 uart->sci->SCR.BYTE &= 0x5B;
314 uart->sci->SCR.BYTE |= scr_copy;
315
316 *(IPR_ADDRESS(uart->UART)) = 5;
317 uart->sci->SSR.BYTE = 0xC0;
318 uart->sci->SSR.BYTE &= INV_BIT_5;
319 while (uart->sci->SSR.BYTE & BIT_4);
320 uart->sci->SSR.BYTE &= INV_BIT_3;
321 #else
322 struct rx_uart *uart;
323 /* Declare error flag */
324 bool err = true;
325 uint32_t flag = 0;
326 RT_ASSERT(serial != RT_NULL);
327 uart = (struct rx_uart *)serial->parent.user_data;
328
329
330 /* Configure the pin selection of SCI channel */
331 err &= R_SCI_Set
332 (
333 PDL_SCI_PIN_SCI2_B
334 );
335
336 uart->sci->SCR.BYTE |= BIT_4 | BIT_5;
337 switch (cfg->parity) {
338 case PARITY_ODD:
339 flag |= PDL_SCI_PARITY_ODD;
340 break;
341 case PARITY_EVEN:
342 flag |= PDL_SCI_PARITY_EVEN;
343 break;
344 default:
345 flag |= PDL_SCI_PARITY_NONE;
346 break;
347
348 }
349
350 switch (cfg->data_bits) {
351 case DATA_BITS_7:
352 flag |= PDL_SCI_7_BIT_LENGTH;
353 break;
354 case DATA_BITS_8:
355 flag |= PDL_SCI_8_BIT_LENGTH;
356 break;
357 }
358
359 switch (cfg->stop_bits) {
360 case STOP_BITS_1:
361 flag |= PDL_SCI_STOP_1;
362 break;
363 case STOP_BITS_2:
364 flag |= PDL_SCI_STOP_2;
365 break;
366 }
367
368 flag |= PDL_SCI_ASYNC |
369 PDL_SCI_TX_CONNECTED |
370 PDL_SCI_RX_CONNECTED |
371 PDL_SCI_CLK_INT_IO ;
372 /* Configure the RS232 port */
373 err &= R_SCI_Create(
374 uart->UART,
375 flag,
376 cfg->baud_rate,
377 5);
378
379 uart->sci->SCR.BYTE |= BIT_4|BIT_5;
380
381 __enable_interrupt();
382 #endif
383
384 switch (uart->UART) {
385 case 0:
386
387 //ier_copy |= BIT_6 | BIT_7;
388 ICU.IER[IER_SCI0_ERI0].BIT.IEN_SCI0_ERI0 = 1;
389 ICU.IER[IER_SCI0_RXI0].BIT.IEN_SCI0_RXI0 = 1;
390 ICU.IER[IER_SCI0_TEI0].BIT.IEN_SCI0_TEI0 = 1;
391 ICU.IER[IER_SCI0_TXI0].BIT.IEN_SCI0_TXI0 = 1;
392
393 break;
394 case 1:
395
396 ICU.IER[IER_SCI1_ERI1].BIT.IEN_SCI1_ERI1 = 1;
397 ICU.IER[IER_SCI1_RXI1].BIT.IEN_SCI1_RXI1 = 1;
398 //ICU.IER[IER_SCI1_TEI1].BIT.IEN_SCI1_TEI1 = 1;
399 //ICU.IER[IER_SCI1_TXI1].BIT.IEN_SCI1_TXI1 = 1;
400
401 break;
402 case 2:
403
404 ICU.IER[IER_SCI2_ERI2].BIT.IEN_SCI2_ERI2 = 1;
405 ICU.IER[IER_SCI2_RXI2].BIT.IEN_SCI2_RXI2 = 1;
406 ICU.IER[IER_SCI2_RXI2].BIT.IEN_SCI2_TEI2 = 0;
407 ICU.IER[IER_SCI2_TXI2].BIT.IEN_SCI2_TXI2 = 0;
408
409 break;
410 case 3:
411
412 ICU.IER[IER_SCI3_ERI3].BIT.IEN_SCI3_ERI3 = 1;
413 ICU.IER[IER_SCI3_RXI3].BIT.IEN_SCI3_RXI3 = 1;
414 ICU.IER[IER_SCI3_TEI3].BIT.IEN_SCI3_TEI3 = 1;
415 ICU.IER[IER_SCI3_TXI3].BIT.IEN_SCI3_TXI3 = 1;
416
417 break;
418 case 5:
419
420 ICU.IER[IER_SCI5_ERI5].BIT.IEN_SCI5_ERI5 = 1;
421 ICU.IER[IER_SCI5_RXI5].BIT.IEN_SCI5_RXI5 = 1;
422 ICU.IER[IER_SCI5_TEI5].BIT.IEN_SCI5_TEI5 = 1;
423 ICU.IER[IER_SCI5_TXI5].BIT.IEN_SCI5_TXI5 = 1;
424
425 break;
426 case 6:
427
428 ICU.IER[IER_SCI6_ERI6].BIT.IEN_SCI6_ERI6 = 1;
429 ICU.IER[IER_SCI6_RXI6].BIT.IEN_SCI6_RXI6 = 1;
430 ICU.IER[IER_SCI6_TEI6].BIT.IEN_SCI6_TEI6 = 1;
431 ICU.IER[IER_SCI6_TXI6].BIT.IEN_SCI6_TXI6 = 1;
432
433 break;
434 }
435
436 return RT_EOK;
437 }
438
rx_control(struct rt_serial_device * serial,int cmd,void * arg)439 static rt_err_t rx_control(struct rt_serial_device *serial, int cmd, void *arg)
440 {
441 struct rx_uart *uart;
442
443 RT_ASSERT(serial != RT_NULL);
444 uart = (struct rx_uart *)serial->parent.user_data;
445
446 switch (cmd)
447 {
448 case RT_DEVICE_CTRL_CLR_INT:
449 /* disable rx irq */
450 uart->sci->SCR.BIT.RIE = 0;
451 break;
452 case RT_DEVICE_CTRL_SET_INT:
453 /* enable rx irq */
454 (void)(uart->sci->RDR);
455 uart->sci->SCR.BIT.RIE = 1;
456 break;
457 }
458
459 return RT_EOK;
460 }
461
rx_putc(struct rt_serial_device * serial,char c)462 static int rx_putc(struct rt_serial_device *serial, char c)
463 {
464 struct rx_uart *uart;
465
466 uart = (struct rx_uart *)serial->parent.user_data;
467 while (uart->sci->SSR.BIT.TDRE == 0);
468 uart->sci->TDR = c;
469 return 1;
470 }
471
rx_getc(struct rt_serial_device * serial)472 static int rx_getc(struct rt_serial_device *serial)
473 {
474
475 struct rx_uart *uart;
476
477 uart = (struct rx_uart *)serial->parent.user_data;
478 if (uart->sci->SSR.BIT.RDRF)
479 return (int) (uart->sci->RDR);
480
481 return -1;
482 }
483
484 static const struct rt_uart_ops rx_uart_ops =
485 {
486 rx_configure,
487 rx_control,
488 rx_putc,
489 rx_getc,
490 };
491
492 #if defined(RT_USING_UART2)
493 /* UART0 device driver structure */
494 struct rx_uart uart2 =
495 {
496 2,
497 &SCI2,
498 };
499 struct rt_serial_device serial2;
500
501
502 #pragma vector = VECT_SCI2_ERI2
Interrupt_SCI2_ERI2(void)503 __interrupt void Interrupt_SCI2_ERI2(void)
504 {
505 /* Will the user handle the errors? */
506 /* Clear the error flags */
507 SCI2.SSR.BYTE = (uint8_t)(BIT_7 | BIT_6);
508 }
509
510 #pragma vector = VECT_SCI2_RXI2
Interrupt_SCI2_RXI2(void)511 __interrupt void Interrupt_SCI2_RXI2(void)
512 {
513 rt_interrupt_enter();
514 rt_hw_serial_isr(&serial2, RT_SERIAL_EVENT_RX_IND);
515 rt_interrupt_leave();
516 }
517
518 #endif
519
rt_hw_uart_init(void)520 void rt_hw_uart_init(void)
521 {
522 struct rx_uart *uart;
523 struct serial_configure config;
524
525 #ifdef RT_USING_UART2
526 uart = &uart2;
527 config.baud_rate = BAUD_RATE_38400;
528 config.bit_order = BIT_ORDER_LSB;
529 config.data_bits = DATA_BITS_8;
530 config.parity = PARITY_NONE;
531 config.stop_bits = STOP_BITS_1;
532 config.invert = NRZ_NORMAL;
533 config.bufsz = RT_SERIAL_RB_BUFSZ;
534
535 serial2.ops = &rx_uart_ops;
536 serial2.config = config;
537
538 /* register UART1 device */
539 rt_hw_serial_register(&serial2, "uart2",
540 RT_DEVICE_FLAG_RDWR |
541 RT_DEVICE_FLAG_INT_RX |
542 RT_DEVICE_FLAG_STREAM,
543 uart);
544 #endif
545
546 }
547
548