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 * 2011-01-13 weety first version
9 */
10
11 #include <rtthread.h>
12 #include <rthw.h>
13 #include <dm36x.h>
14 #include <rtdevice.h>
15
16 static struct rt_serial_device davinci_serial_dev0;
17
18 static struct rt_serial_device davinci_serial_dev1;
19
20
21 #define LSR_DR 0x01 /* Data ready */
22 #define LSR_THRE 0x20 /* Xmit holding register empty */
23 //#define USTAT_TXB_EMPTY 0x02 /* tx buffer empty */
24 #define BPS 115200 /* serial baudrate */
25
26 typedef struct uartport
27 {
28 volatile rt_uint32_t rbr;
29 volatile rt_uint32_t ier;
30 volatile rt_uint32_t fcr;
31 volatile rt_uint32_t lcr;
32 volatile rt_uint32_t mcr;
33 volatile rt_uint32_t lsr;
34 volatile rt_uint32_t msr;
35 volatile rt_uint32_t scr;
36 volatile rt_uint32_t dll;
37 volatile rt_uint32_t dlh;
38
39 volatile rt_uint32_t res[2];
40 volatile rt_uint32_t pwremu_mgmt;
41 volatile rt_uint32_t mdr;
42 }uartport;
43
44 #define thr rbr
45 #define iir fcr
46
47 #define UART0 ((struct uartport *)DAVINCI_UART0_BASE)
48
49 #define UART1 ((struct uartport *)DM365_UART1_BASE)
50
51
52 /**
53 * This function will handle serial
54 */
rt_davinci_serial_handler(int vector,void * param)55 void rt_davinci_serial_handler(int vector, void *param)
56 {
57 struct rt_serial_device *dev = (struct rt_serial_device *)param;
58 rt_hw_serial_isr(dev, RT_SERIAL_EVENT_RX_IND);
59 }
60
61 /**
62 * UART device in RT-Thread
63 */
davinci_uart_configure(struct rt_serial_device * serial,struct serial_configure * cfg)64 static rt_err_t davinci_uart_configure(struct rt_serial_device *serial,
65 struct serial_configure *cfg)
66 {
67 return RT_EOK;
68 }
69
davinci_uart_control(struct rt_serial_device * serial,int cmd,void * arg)70 static rt_err_t davinci_uart_control(struct rt_serial_device *serial,
71 int cmd, void *arg)
72 {
73 uartport *uart = serial->parent.user_data;
74
75 switch (cmd)
76 {
77 case RT_DEVICE_CTRL_CLR_INT:
78 /* disable rx irq */
79 if (uart == UART0)
80 rt_hw_interrupt_mask(IRQ_UARTINT0);
81 else if (uart == UART1)
82 rt_hw_interrupt_mask(IRQ_UARTINT1);
83 break;
84 case RT_DEVICE_CTRL_SET_INT:
85 /* enable rx irq */
86 if (uart == UART0)
87 rt_hw_interrupt_umask(IRQ_UARTINT0);
88 else if (uart == UART1)
89 rt_hw_interrupt_umask(IRQ_UARTINT1);
90 break;
91 }
92
93 return RT_EOK;
94 }
95
davinci_uart_putc(struct rt_serial_device * serial,char c)96 static int davinci_uart_putc(struct rt_serial_device *serial, char c)
97 {
98 rt_uint32_t level;
99 uartport *uart = serial->parent.user_data;
100
101 while (!(uart->lsr & LSR_THRE));
102 uart->thr = c;
103
104 return 1;
105 }
106
davinci_uart_getc(struct rt_serial_device * serial)107 static int davinci_uart_getc(struct rt_serial_device *serial)
108 {
109 int result;
110 uartport *uart = serial->parent.user_data;
111
112 if (uart->lsr & LSR_DR)
113 {
114 result = uart->rbr & 0xff;
115 }
116 else
117 {
118 result = -1;
119 }
120
121 return result;
122 }
123
124 static const struct rt_uart_ops davinci_uart_ops =
125 {
126 davinci_uart_configure,
127 davinci_uart_control,
128 davinci_uart_putc,
129 davinci_uart_getc,
130 };
131
davinci_uart0_init(void)132 void davinci_uart0_init(void)
133 {
134 rt_uint32_t divisor;
135
136 divisor = (24000000 + (115200 * (16 / 2))) / (16 * 115200);
137 UART0->ier = 0;
138 UART0->lcr = 0x83; //8N1
139 UART0->dll = 0;
140 UART0->dlh = 0;
141 UART0->lcr = 0x03;
142 UART0->mcr = 0x03; //RTS,CTS
143 UART0->fcr = 0x07; //FIFO
144 UART0->lcr = 0x83;
145 UART0->dll = divisor & 0xff;
146 UART0->dlh = (divisor >> 8) & 0xff;
147 UART0->lcr = 0x03;
148 UART0->mdr = 0; //16x over-sampling
149 UART0->pwremu_mgmt = 0x6000;
150 rt_hw_interrupt_install(IRQ_UARTINT0, rt_davinci_serial_handler,
151 (void *)&davinci_serial_dev0, "UART0");
152 rt_hw_interrupt_mask(IRQ_UARTINT0);
153 UART0->ier = 0x05;
154 }
155
davinci_uart_gpio_init()156 void davinci_uart_gpio_init()
157 {
158 rt_uint32_t val;
159
160 val = davinci_readl(PINMUX3);
161 val &= 0xf3ffffff; /* gio23 RS485_CTRL */
162 val |= 0x60000000; /*UART1_TXD (gio25)*/
163 davinci_writel(val, PINMUX3);
164 val = davinci_readl(PINMUX4);
165 val |= 0x0000c000; /* UART1_RXD (gio34) */
166 davinci_writel(val, PINMUX4);
167
168 val = davinci_readl(DAVINCI_GPIO_BASE + 0x10);
169 val &= ~(1 << 23);
170 davinci_writel(val, DAVINCI_GPIO_BASE + 0x10);
171 davinci_writel((1<<23), DAVINCI_GPIO_BASE + 0x1C);
172 }
173
davinci_uart1_init(void)174 void davinci_uart1_init(void)
175 {
176 rt_uint32_t divisor;
177 rt_uint32_t freq;
178 rt_uint32_t baudrate;
179 struct clk *clk;
180
181 davinci_uart_gpio_init();
182 psc_change_state(DAVINCI_DM365_LPSC_UART1, PSC_ENABLE);
183 clk = clk_get("UART1");
184 freq = clk_get_rate(clk);
185
186 baudrate = 9600;
187 divisor = (freq + (baudrate * (16 / 2))) / (16 * baudrate);
188 UART1->ier = 0;
189 UART1->lcr = 0x87; //8N2, 0x83 8N1
190 UART1->dll = 0;
191 UART1->dlh = 0;
192 UART1->lcr = 0x07;
193 UART1->mcr = 0x03; //RTS,CTS
194 UART1->fcr = 0x07; //FIFO
195 UART1->lcr = 0x87;
196 UART1->dll = divisor & 0xff;
197 UART1->dlh = (divisor >> 8) & 0xff;
198 UART1->lcr = 0x07;
199 UART1->mdr = 0; //16x over-sampling
200 UART1->pwremu_mgmt = 0x6000;
201
202 rt_hw_interrupt_install(IRQ_UARTINT1, rt_davinci_serial_handler,
203 (void *)&davinci_serial_dev1, "UART1");
204 rt_hw_interrupt_mask(IRQ_UARTINT1);
205 UART1->ier = 0x05;
206 }
207
208
209 /**
210 * This function will handle init uart
211 */
rt_hw_uart_init(void)212 int rt_hw_uart_init(void)
213 {
214 davinci_serial_dev0.ops = &davinci_uart_ops;
215 //davinci_serial_dev0.config = RT_SERIAL_CONFIG_DEFAULT;
216 davinci_serial_dev0.config.baud_rate = BAUD_RATE_115200;
217 davinci_serial_dev0.config.bit_order = BIT_ORDER_LSB;
218 davinci_serial_dev0.config.data_bits = DATA_BITS_8;
219 davinci_serial_dev0.config.parity = PARITY_NONE;
220 davinci_serial_dev0.config.stop_bits = STOP_BITS_1;
221 davinci_serial_dev0.config.invert = NRZ_NORMAL;
222 davinci_serial_dev0.config.bufsz = RT_SERIAL_RB_BUFSZ;
223
224 /* register vcom device */
225 rt_hw_serial_register(&davinci_serial_dev0, "uart0",
226 RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX | RT_DEVICE_FLAG_STREAM,
227 UART0);
228 davinci_uart0_init();
229
230 davinci_serial_dev1.ops = &davinci_uart_ops;
231 //davinci_serial_dev1.config = RT_SERIAL_CONFIG_DEFAULT;
232 davinci_serial_dev1.config.baud_rate = BAUD_RATE_115200;
233 davinci_serial_dev1.config.bit_order = BIT_ORDER_LSB;
234 davinci_serial_dev1.config.data_bits = DATA_BITS_8;
235 davinci_serial_dev1.config.parity = PARITY_NONE;
236 davinci_serial_dev1.config.stop_bits = STOP_BITS_1;
237 davinci_serial_dev1.config.invert = NRZ_NORMAL;
238 davinci_serial_dev1.config.bufsz = RT_SERIAL_RB_BUFSZ;
239
240 /* register vcom device */
241 rt_hw_serial_register(&davinci_serial_dev1, "uart1",
242 RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX | RT_DEVICE_FLAG_STREAM,
243 UART1);
244 davinci_uart1_init();
245
246 return 0;
247 }
248
249 INIT_BOARD_EXPORT(rt_hw_uart_init);
250
251