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