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