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 * 2010-03-08 Bernard The first version for LPC17xx
9 * 2010-04-10 fify Modified for M16C
10 */
11
12 #include <rthw.h>
13 #include <rtthread.h>
14 #include "iom16c62p.h"
15 #include "bsp.h"
16 #include "uart.h"
17
18 #if defined(RT_USING_UART0) && defined(RT_USING_DEVICE)
19
20 struct rt_uart_m16c
21 {
22 struct rt_device parent;
23
24 /* buffer for reception */
25 rt_uint8_t read_index, save_index;
26 rt_uint8_t rx_buffer[RT_UART_RX_BUFFER_SIZE];
27 }uart_device;
28
u0rec_handler(void)29 void u0rec_handler(void)
30 {
31 rt_ubase_t level;
32 rt_uint8_t c;
33
34 struct rt_uart_m16c *uart = &uart_device;
35
36 while (U0C1.BIT.RI == 0)
37 ;
38 c = U0RB.BYTE.U0RBL;
39
40 /* Receive Data Available */
41 uart->rx_buffer[uart->save_index] = c;
42
43 level = rt_hw_interrupt_disable();
44 uart->save_index ++;
45 if (uart->save_index >= RT_UART_RX_BUFFER_SIZE)
46 uart->save_index = 0;
47 rt_hw_interrupt_enable(level);
48
49 /* invoke callback */
50 if (uart->parent.rx_indicate != RT_NULL)
51 {
52 rt_size_t length;
53 if (uart->read_index > uart->save_index)
54 length = RT_UART_RX_BUFFER_SIZE - uart->read_index + uart->save_index;
55 else
56 length = uart->save_index - uart->read_index;
57
58 uart->parent.rx_indicate(&uart->parent, length);
59 }
60 }
61
rt_uart_init(rt_device_t dev)62 static rt_err_t rt_uart_init (rt_device_t dev)
63 {
64 rt_uint32_t level;
65 /* set UART0 bit rate generator bit rate can be calculated by:
66 bit rate = ((BRG count source / 16)/baud rate) - 1
67 Baud rate is based on main crystal or PLL not CPU core clock */
68 //pclk1 = 1; /// seleck F1SIO
69 U0BRG = (unsigned char)(((CPU_CLK_FREQ/16)/BAUD_RATE)-1); //(N+1)
70
71 /* UART Transmit/Receive Control Register 2 */
72 UCON.BYTE = 0x00;
73 /* 00000000
74 b0 U0IRS UART0 transmit irq cause select bit, 0 = transmit buffer empty
75 b1 U1IRS UART1 transmit irq cause select bit, 0 = transmit buffer empty
76 b2 U0RRM UART0 continuous receive mode enable bit, set to 0 in UART mode
77 b3 U1RRM UART1 continuous receive mode enable bit, set to 0 in UART mode
78 b4 CLKMD0 CLK/CLKS select bit 0, set to 0 in UART mode
79 b5 CLKMD1 CLK/CLKS select bit 1, set to 0 in UART mode
80 b6 RCSP Separate CTS/RTS bit,
81 b7 Reserved, set to 0 */
82
83 /* UART0 transmit/receive control register 0 */
84 /* f1 count source, CTS/RTS disabled, CMOS output */
85 U0C0.BYTE = 0x10;
86 /* 00010000
87 b1:b0 CLK01:CLK0 BRG count source select bits //01 F8SIO
88 b2 CRS CTS/RTS function select bit
89 b3 TXEPT Transmit register empty flag
90 b4 CRD CTS/RTS disable bit
91 b5 NCH Data output select bit
92 b6 CKPOL CLK polarity select bit,set to 0 in UART mode
93 b7 UFORM Transfer format select bit,set to 0 in UART mode */
94
95 /* UART0 transmit/receive control register 1 */
96 /* disable transmit and receive, no error output pin, data not inverted */
97 U0C1.BYTE = 0x00;
98 /* 00000000
99 b0 TE Transmit enable bit
100 b1 TI Transmit buffer empty flag
101 b2 RE Receive enable bit
102 b3 RI Receive complete flag
103 b5:b4 Reserved, set to 0
104 b6 UOLCH Data logic select bit
105 b7 UOERE Error signal output enable bit */
106
107 /* UART0 transmit/receive mode register */
108 /* 8-bit data,asynch mode, internal clock, 1 stop bit, no parity */
109 U0MR.BYTE = 0x05;
110 /* 00000101
111 b2:b0 SMD12:SMD1 Serial I/O Mode select bits
112 b3 CKDIR Internal/External clock select bit, CKDIR
113 b4 STPS Stop bit length select bit, STPS
114 b5 PRY Odd/even parity select bit, PRY
115 b6 PRYE Parity enable bit, PRYE
116 b7 IOPOL TxD, RxD I/O polarity reverse bit */
117
118 /* clear UART0 receive buffer by reading */
119 U0TB.WORD = U0RB.WORD;
120 /* clear UART0 transmit buffer */
121 U0TB.WORD = 0;
122
123 /* disable irqs before setting irq registers */
124 level = rt_hw_interrupt_disable();
125 /* Enable UART0 receive interrupt, priority level 4 */
126 S0RIC.BYTE = 0x04;
127 /* Enable all interrupts */
128 rt_hw_interrupt_enable(level);
129
130 /* UART0 transmit/receive control register 1 */
131 /* enable transmit and receive */
132 U0C1.BYTE = 0x05;
133 /* 00000101 enable transmit and receive
134 b0 TE Transmit enable bit
135 b1 TI Transmit buffer empty flag
136 b2 RE Receive enable bit
137 b3 RI Receive complete flag
138 b5:b4 Reserved, set to 0
139 b6 UOLCH Data logic select bit
140 b7 UOERE Error signal output enable bit */
141
142 return RT_EOK;
143 }
144
rt_uart_open(rt_device_t dev,rt_uint16_t oflag)145 static rt_err_t rt_uart_open(rt_device_t dev, rt_uint16_t oflag)
146 {
147 RT_ASSERT(dev != RT_NULL);
148 if (dev->flag & RT_DEVICE_FLAG_INT_RX)
149 {
150 /* Enable the UART Interrupt */
151 }
152
153 return RT_EOK;
154 }
155
rt_uart_close(rt_device_t dev)156 static rt_err_t rt_uart_close(rt_device_t dev)
157 {
158 RT_ASSERT(dev != RT_NULL);
159 if (dev->flag & RT_DEVICE_FLAG_INT_RX)
160 {
161 /* Disable the UART Interrupt */
162 }
163
164 return RT_EOK;
165 }
166
rt_uart_read(rt_device_t dev,rt_off_t pos,void * buffer,rt_size_t size)167 static rt_ssize_t rt_uart_read(rt_device_t dev, rt_off_t pos, void* buffer, rt_size_t size)
168 {
169 rt_uint8_t *ptr;
170 struct rt_uart_m16c *uart = (struct rt_uart_m16c *)dev;
171 RT_ASSERT(uart != RT_NULL);
172
173 /* point to buffer */
174 ptr = (rt_uint8_t *)buffer;
175 if (dev->flag & RT_DEVICE_FLAG_INT_RX)
176 {
177 while (size)
178 {
179 /* interrupt receive */
180 rt_base_t level;
181
182 /* disable interrupt */
183 level = rt_hw_interrupt_disable();
184 if (uart->read_index != uart->save_index)
185 {
186 *ptr = uart->rx_buffer[uart->read_index];
187
188 uart->read_index ++;
189 if (uart->read_index >= RT_UART_RX_BUFFER_SIZE)
190 uart->read_index = 0;
191 }
192 else
193 {
194 /* no data in rx buffer */
195
196 /* enable interrupt */
197 rt_hw_interrupt_enable(level);
198 break;
199 }
200
201 /* enable interrupt */
202 rt_hw_interrupt_enable(level);
203
204 ptr ++;
205 size --;
206 }
207
208 return (rt_uint32_t)ptr - (rt_uint32_t)buffer;
209 }
210
211 return 0;
212 }
213
rt_uart_write(rt_device_t dev,rt_off_t pos,const void * buffer,rt_size_t size)214 static rt_ssize_t rt_uart_write(rt_device_t dev, rt_off_t pos, const void *buffer, rt_size_t size)
215 {
216 char *ptr;
217 ptr = (char *)buffer;
218
219 if (dev->flag & RT_DEVICE_FLAG_STREAM)
220 {
221 /* stream mode */
222 while (size)
223 {
224 if (*ptr == '\n')
225 {
226 while (U0C1.BIT.TI == 0)
227 ;
228 U0TB.BYTE.U0TBL = '\r';
229 }
230
231 /* THRE status, contain valid data */
232 while (U0C1.BIT.TI == 0)
233 ;
234 U0TB.BYTE.U0TBL = *ptr;
235
236 ptr ++;
237 size --;
238 }
239 }
240 else
241 {
242 while (size != 0)
243 {
244 /* THRE status, contain valid data */
245 while (U0C1.BIT.TI == 0)
246 ;
247 U0TB.BYTE.U0TBL = *ptr;
248
249 ptr ++;
250 size --;
251 }
252 }
253
254 return (rt_size_t)ptr - (rt_size_t)buffer;
255 }
256
rt_hw_uart_init(void)257 void rt_hw_uart_init(void)
258 {
259 struct rt_uart_m16c *uart;
260
261 /* get uart device */
262 uart = &uart_device;
263
264 /* device initialization */
265 uart->parent.type = RT_Device_Class_Char;
266 rt_memset(uart->rx_buffer, 0, sizeof(uart->rx_buffer));
267 uart->read_index = uart->save_index = 0;
268
269 /* device interface */
270 uart->parent.init = rt_uart_init;
271 uart->parent.open = rt_uart_open;
272 uart->parent.close = rt_uart_close;
273 uart->parent.read = rt_uart_read;
274 uart->parent.write = rt_uart_write;
275 uart->parent.control = RT_NULL;
276 uart->parent.user_data = RT_NULL;
277
278 rt_device_register(&uart->parent,
279 "uart0", RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_STREAM | RT_DEVICE_FLAG_INT_RX);
280 }
281 #endif /* end of UART */
282
283 /*@}*/
284