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