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-06-29 lgnq Modified for V850
10 */
11
12 #include <rthw.h>
13 #include <rtthread.h>
14 #include "io70f3454.h"
15 #include "uart.h"
16
17 #if defined(RT_USING_UART0) && defined(RT_USING_DEVICE)
18
19 struct rt_uart_v850
20 {
21 struct rt_device parent;
22
23 /* buffer for reception */
24 rt_uint8_t read_index, save_index;
25 rt_uint8_t rx_buffer[RT_UART_RX_BUFFER_SIZE];
26 }uart_device;
27
uarta1_receive_handler(void)28 void uarta1_receive_handler(void)
29 {
30 rt_ubase_t level;
31 rt_uint8_t c;
32
33 struct rt_uart_v850 *uart = &uart_device;
34
35 // while(ri_u0c1 == 0)
36 // ;
37 c = (char) UA1RX;
38
39 /* Receive Data Available */
40 uart->rx_buffer[uart->save_index] = c;
41
42 level = rt_hw_interrupt_disable();
43 uart->save_index ++;
44 if (uart->save_index >= RT_UART_RX_BUFFER_SIZE)
45 uart->save_index = 0;
46 rt_hw_interrupt_enable(level);
47
48 /* invoke callback */
49 if (uart->parent.rx_indicate != RT_NULL)
50 {
51 rt_size_t length;
52 if (uart->read_index > uart->save_index)
53 length = RT_UART_RX_BUFFER_SIZE - uart->read_index + uart->save_index;
54 else
55 length = uart->save_index - uart->read_index;
56
57 uart->parent.rx_indicate(&uart->parent, length);
58 }
59 }
60
rt_uart_init(rt_device_t dev)61 static rt_err_t rt_uart_init (rt_device_t dev)
62 {
63 UA1TXE = 0U; /* disable UARTA1 transmission operation */
64 UA1RXE = 0U; /* disable UARTA1 reception operation */
65 UA1PWR = 0U; /* disable UARTA1 operation */
66 UA1TMK = 1U; /* disable INTUA1T interrupt */
67 UA1TIF = 0U; /* clear INTUA1T interrupt flag */
68 UA1RMK = 1U; /* disable INTUA1R interrupt */
69 UA1RIF = 0U; /* clear INTUA1R interrupt flag */
70 /* Set INTUA1T level low priority */
71 UA1TIC |= 0x07U;
72 /* Set INTUA1R level low priority */
73 UA1RIC |= 0x07U;
74 //BAUDRATE = 9600
75 UA1CTL1 = _03_UARTA_BASECLK_FXX_16;
76 UA1CTL2 = _11_UARTA1_BASECLK_DIVISION;
77 UA1CTL0 = _10_UARTA_TRANSFDIR_LSB | _00_UARTA_PARITY_NONE | _02_UARTA_DATALENGTH_8BIT | _00_UARTA_STOPLENGTH_1BIT;
78 UA1OPT0 = _14_UARTA_UAnOPT0_INITIALVALUE | _00_UARTA_TRAN_DATALEVEL_NORMAL | _00_UARTA_REC_DATALEVEL_NORMAL;
79 UA1PWR = 1U; /* enable UARTA1 operation */
80 /* Set TXDA1 pin */
81 /* Set RXDA1 pin */
82 PFC3_bit.no0 = 0;
83 PFCE3_bit.no0 = 0;
84 PMC3_bit.no0 = 1;
85
86 PFC3_bit.no1 = 0;
87 PFCE3_bit.no1 = 0;
88 PMC3_bit.no1 = 1;
89
90 return RT_EOK;
91 }
92
rt_uart_open(rt_device_t dev,rt_uint16_t oflag)93 static rt_err_t rt_uart_open(rt_device_t dev, rt_uint16_t oflag)
94 {
95 RT_ASSERT(dev != RT_NULL);
96 if (dev->flag & RT_DEVICE_FLAG_INT_RX)
97 {
98 /* Enable the UART Interrupt */
99 UA1TIF = 0U; /* clear INTUA1T interrupt flag */
100 UA1TMK = 1U; /* disable INTUA1T interrupt */
101 UA1RIF = 0U; /* clear INTUA1R interrupt flag */
102 UA1RMK = 0U; /* enable INTUA1R interrupt */
103 UA1TXE = 1U; /* enable UARTA1 transmission operation */
104 UA1RXE = 1U; /* enable UARTA1 reception operation */
105 }
106
107 return RT_EOK;
108 }
109
rt_uart_close(rt_device_t dev)110 static rt_err_t rt_uart_close(rt_device_t dev)
111 {
112 RT_ASSERT(dev != RT_NULL);
113 if (dev->flag & RT_DEVICE_FLAG_INT_RX)
114 {
115 /* Disable the UART Interrupt */
116 UA1TXE = 0U; /* disable UARTA1 transmission operation */
117 UA1RXE = 0U; /* disable UARTA1 reception operation */
118 UA1TMK = 1U; /* disable INTUA1T interrupt */
119 UA1TIF = 0U; /* clear INTUA1T interrupt flag */
120 UA1RMK = 1U; /* disable INTUA1R interrupt */
121 UA1RIF = 0U; /* clear INTUA1R interrupt flag */
122 }
123
124 return RT_EOK;
125 }
126
rt_uart_read(rt_device_t dev,rt_off_t pos,void * buffer,rt_size_t size)127 static rt_ssize_t rt_uart_read(rt_device_t dev, rt_off_t pos, void *buffer, rt_size_t size)
128 {
129 rt_uint8_t *ptr;
130 struct rt_uart_v850 *uart = (struct rt_uart_v850 *)dev;
131 RT_ASSERT(uart != RT_NULL);
132
133 /* point to buffer */
134 ptr = (rt_uint8_t *)buffer;
135 if (dev->flag & RT_DEVICE_FLAG_INT_RX)
136 {
137 while (size)
138 {
139 /* interrupt receive */
140 rt_base_t level;
141
142 /* disable interrupt */
143 level = rt_hw_interrupt_disable();
144 if (uart->read_index != uart->save_index)
145 {
146 *ptr = uart->rx_buffer[uart->read_index];
147
148 uart->read_index ++;
149 if (uart->read_index >= RT_UART_RX_BUFFER_SIZE)
150 uart->read_index = 0;
151 }
152 else
153 {
154 /* no data in rx buffer */
155
156 /* enable interrupt */
157 rt_hw_interrupt_enable(level);
158 break;
159 }
160
161 /* enable interrupt */
162 rt_hw_interrupt_enable(level);
163
164 ptr ++;
165 size --;
166 }
167
168 return (rt_uint32_t)ptr - (rt_uint32_t)buffer;
169 }
170
171 return 0;
172 }
173
rt_uart_write(rt_device_t dev,rt_off_t pos,const void * buffer,rt_size_t size)174 static rt_ssize_t rt_uart_write(rt_device_t dev, rt_off_t pos, const void* buffer, rt_size_t size)
175 {
176 char *ptr;
177 ptr = (char*)buffer;
178
179 if (dev->flag & RT_DEVICE_FLAG_STREAM)
180 {
181 /* stream mode */
182 while (size)
183 {
184 if (*ptr == '\n')
185 {
186 while (UA1TSF == 1U)
187 ;
188 UA1TX = '\r';
189 }
190
191 /* THRE status, contain valid data */
192 while (UA1TSF == 1U)
193 ;
194 UA1TX = *ptr;
195
196 ptr ++;
197 size --;
198 }
199 }
200 else
201 {
202 while (size != 0)
203 {
204 /* THRE status, contain valid data */
205 while (UA1TSF == 1U)
206 ;
207 UA1TX = *ptr;
208
209 ptr ++;
210 size --;
211 }
212 }
213
214 return (rt_size_t)ptr - (rt_size_t)buffer;
215 }
216
rt_hw_uart_init(void)217 void rt_hw_uart_init(void)
218 {
219 struct rt_uart_v850 *uart;
220
221 /* get uart device */
222 uart = &uart_device;
223
224 /* device initialization */
225 uart->parent.type = RT_Device_Class_Char;
226 rt_memset(uart->rx_buffer, 0, sizeof(uart->rx_buffer));
227 uart->read_index = uart->save_index = 0;
228
229 /* device interface */
230 uart->parent.init = rt_uart_init;
231 uart->parent.open = rt_uart_open;
232 uart->parent.close = rt_uart_close;
233 uart->parent.read = rt_uart_read;
234 uart->parent.write = rt_uart_write;
235 uart->parent.control = RT_NULL;
236 uart->parent.user_data = RT_NULL;
237
238 rt_device_register(&uart->parent,
239 "uart0", RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_STREAM | RT_DEVICE_FLAG_INT_RX);
240 }
241 #endif /* end of UART */
242
243 /*@}*/
244