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  * 2017-09-19     Quintin.Z    the first version
9  */
10 
11 #include <rtdevice.h>
12 #include <board.h>
13 #include "drv_uart.h"
14 #include "nv32.h"
15 #include "uart.h"
16 #include "sim.h"
17 
18 /* NV32 uart driver */
19 struct nv32_uart
20 {
21     UART_Type* uart_device;
22     IRQn_Type irq;
23 };
24 
nv32_configure(struct rt_serial_device * serial,struct serial_configure * cfg)25 static rt_err_t nv32_configure(struct rt_serial_device *serial, struct serial_configure *cfg)
26 {
27     struct nv32_uart* uart;
28 
29     UART_ConfigBaudrateType uart_config;
30 
31     RT_ASSERT(serial != RT_NULL);
32     RT_ASSERT(cfg != RT_NULL);
33 
34     uart = (struct nv32_uart *)serial->parent.user_data;
35 
36     uart_config.u32SysClkHz = BUS_CLK_HZ;
37     uart_config.u32Baudrate = cfg->baud_rate;
38 
39     UART_SetBaudrate(uart->uart_device, &uart_config);
40 
41 
42     if (cfg->data_bits == DATA_BITS_8)
43     {
44         UART_Set8BitMode(uart->uart_device);
45     }
46     else if(cfg->data_bits == DATA_BITS_9)
47     {
48         UART_Set9BitMode(uart->uart_device);
49     }
50 
51     if (cfg->stop_bits == STOP_BITS_1)
52     {
53         uart->uart_device->BDH  &= (~UART_BDH_SBNS_MASK);
54     }
55     else if (cfg->stop_bits == STOP_BITS_2)
56     {
57         uart->uart_device->BDH  |= UART_BDH_SBNS_MASK;
58     }
59 
60     /* Enable receiver and transmitter */
61     uart->uart_device->C2 |= (UART_C2_TE_MASK | UART_C2_RE_MASK );
62 
63 
64     UART_EnableInterrupt(UART0, UART_RxBuffFullInt);
65     NVIC_EnableIRQ(UART0_IRQn);
66 
67 
68     return RT_EOK;
69 }
70 
nv32_control(struct rt_serial_device * serial,int cmd,void * arg)71 static rt_err_t nv32_control(struct rt_serial_device *serial, int cmd, void *arg)
72 {
73     struct nv32_uart* uart;
74 
75     RT_ASSERT(serial != RT_NULL);
76     uart = (struct nv32_uart *)serial->parent.user_data;
77 
78     switch (cmd)
79     {
80         case RT_DEVICE_CTRL_CLR_INT:
81             /* disable rx irq */
82             NVIC_DisableIRQ(uart->irq);
83             break;
84         case RT_DEVICE_CTRL_SET_INT:
85             /* enable rx irq */
86             NVIC_EnableIRQ(uart->irq);
87             break;
88     }
89 
90     return RT_EOK;
91 }
92 
nv32_putc(struct rt_serial_device * serial,char c)93 static int nv32_putc(struct rt_serial_device *serial, char c)
94 {
95     struct nv32_uart* uart;
96 
97     RT_ASSERT(serial != RT_NULL);
98     uart = (struct nv32_uart *)serial->parent.user_data;
99 
100     while (!(uart->uart_device->S1 & UART_S1_TDRE_MASK));
101 
102     uart->uart_device->D = (uint8_t)c;
103 
104     return 1;
105 }
106 
107 
nv32_getc(struct rt_serial_device * serial)108 static int nv32_getc(struct rt_serial_device *serial)
109 {
110     int ch;
111     struct nv32_uart* uart;
112 
113     RT_ASSERT(serial != RT_NULL);
114     uart = (struct nv32_uart *)serial->parent.user_data;
115 
116     ch = -1;
117     if (uart->uart_device->S1 & UART_S1_RDRF_MASK)
118     {
119         ch = uart->uart_device->D;
120     }
121 
122     return ch;
123 }
124 
125 static const struct rt_uart_ops nv32_uart_ops =
126 {
127     nv32_configure,
128     nv32_control,
129     nv32_putc,
130     nv32_getc,
131 };
132 
133 #ifdef RT_USING_UART0
134 
135 struct nv32_uart uart0 =
136 {
137     UART0,
138     UART0_IRQn,
139 };
140 
141 struct rt_serial_device serial0;
142 
UART0_IRQHandler(void)143 void UART0_IRQHandler(void)
144 {
145     /* enter interrupt */
146     rt_interrupt_enter();
147 
148     if(UART0->S1 & UART_S1_RDRF_MASK)
149     {
150         rt_hw_serial_isr(&serial0, RT_SERIAL_EVENT_RX_IND);
151     }
152 
153     /* leave interrupt */
154     rt_interrupt_leave();
155 }
156 
157 #endif
158 
159 
rt_hw_uart_init(void)160 void rt_hw_uart_init(void)
161 {
162     struct nv32_uart* uart;
163     struct serial_configure config = RT_SERIAL_CONFIG_DEFAULT;
164 
165 #ifdef RT_USING_UART0
166     uart = &uart0;
167 
168     serial0.ops    = &nv32_uart_ops;
169     serial0.config = config;
170 
171 
172     SIM->PINSEL |= SIM_PINSEL_UART0PS_MASK;
173 
174     SIM->SCGC |= SIM_SCGC_UART0_MASK;
175 
176     uart->uart_device->C2 &= ~(UART_C2_TE_MASK | UART_C2_RE_MASK );
177 
178     /* Configure the UART for 8-bit mode, no parity */
179     uart->uart_device->C1 = 0;
180 
181     rt_hw_serial_register(&serial0, "uart0", RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX, uart);
182 #endif
183 
184 }
185 
186