1 #include <GenericTypeDefs.h>
2 #include <plib.h>
3
4 #include <rtthread.h>
5
6 #include "uart.h"
7
8 #define GetSystemClock() (80000000ul)
9 #define GetPeripheralClock() (GetSystemClock()/(1 << OSCCONbits.PBDIV))
10 #define GetInstructionClock() (GetSystemClock())
11
12 struct rt_uart_pic32
13 {
14 struct rt_device parent;
15
16 int uart; /* UART Module ID. */
17
18 /* buffer for reception */
19 rt_uint8_t read_index, save_index;
20 rt_uint8_t rx_buffer[RT_UART_RX_BUFFER_SIZE];
21 };
22
23 #ifdef RT_USING_UART1
24 static struct rt_uart_pic32 uart1_device;
25 #endif
26
27 #ifdef RT_USING_UART2
28 static struct rt_uart_pic32 uart2_device;
29 #endif
30
rt_uart_init(rt_device_t dev)31 static rt_err_t rt_uart_init (rt_device_t dev)
32 {
33 struct rt_uart_pic32 *uart_device = (struct rt_uart_pic32*)dev;
34
35 UARTConfigure(uart_device->uart, UART_ENABLE_PINS_TX_RX_ONLY);
36 UARTSetFifoMode(uart_device->uart, UART_INTERRUPT_ON_TX_NOT_FULL | UART_INTERRUPT_ON_RX_NOT_EMPTY);
37 UARTSetLineControl(uart_device->uart, UART_DATA_SIZE_8_BITS | UART_PARITY_NONE | UART_STOP_BITS_1);
38 UARTSetDataRate(uart_device->uart, GetPeripheralClock(), 115200);
39 UARTEnable(uart_device->uart, UART_ENABLE_FLAGS(UART_PERIPHERAL | UART_RX | UART_TX));
40
41 // Configure UART RX Interrupt
42 INTEnable(INT_SOURCE_UART_RX(uart_device->uart), INT_ENABLED);
43 INTSetVectorPriority(INT_VECTOR_UART(uart_device->uart), INT_PRIORITY_LEVEL_2);
44 INTSetVectorSubPriority(INT_VECTOR_UART(uart_device->uart), INT_SUB_PRIORITY_LEVEL_0);
45
46 return RT_EOK;
47 }
48
rt_uart_open(rt_device_t dev,rt_uint16_t oflag)49 static rt_err_t rt_uart_open(rt_device_t dev, rt_uint16_t oflag)
50 {
51 return RT_EOK;
52 }
53
rt_uart_close(rt_device_t dev)54 static rt_err_t rt_uart_close(rt_device_t dev)
55 {
56 return RT_EOK;
57 }
58
rt_uart_read(rt_device_t dev,rt_off_t pos,void * buffer,rt_size_t size)59 static rt_ssize_t rt_uart_read(rt_device_t dev, rt_off_t pos, void* buffer, rt_size_t size)
60 {
61 rt_uint8_t* ptr;
62 struct rt_uart_pic32 *uart_device = (struct rt_uart_pic32*)dev;
63 RT_ASSERT(uart_device != RT_NULL);
64
65 /* point to buffer */
66 ptr = (rt_uint8_t*) buffer;
67 if (dev->flag & RT_DEVICE_FLAG_INT_RX)
68 {
69 while (size)
70 {
71 /* interrupt receive */
72 rt_base_t level;
73
74 /* disable interrupt */
75 level = rt_hw_interrupt_disable();
76 if (uart_device->read_index != uart_device->save_index)
77 {
78 *ptr = uart_device->rx_buffer[uart_device->read_index];
79
80 uart_device->read_index ++;
81 if (uart_device->read_index >= RT_UART_RX_BUFFER_SIZE)
82 uart_device->read_index = 0;
83 }
84 else
85 {
86 /* no data in rx buffer */
87
88 /* enable interrupt */
89 rt_hw_interrupt_enable(level);
90 break;
91 }
92
93 /* enable interrupt */
94 rt_hw_interrupt_enable(level);
95
96 ptr ++;
97 size --;
98 }
99
100 return (rt_uint32_t)ptr - (rt_uint32_t)buffer;
101 }
102
103 return 0;
104 }
105
rt_uart_write(rt_device_t dev,rt_off_t pos,const void * buffer,rt_size_t size)106 static rt_ssize_t rt_uart_write(rt_device_t dev, rt_off_t pos, const void* buffer, rt_size_t size)
107 {
108 struct rt_uart_pic32 *uart_device = (struct rt_uart_pic32*)dev;
109 char *ptr;
110 ptr = (char*)buffer;
111
112 if (dev->flag & RT_DEVICE_FLAG_STREAM)
113 {
114 /* stream mode */
115 while (size)
116 {
117 if (*ptr == '\n')
118 {
119 while(!UARTTransmitterIsReady(uart_device->uart));
120 UARTSendDataByte(uart_device->uart,'\r' );
121 while(!UARTTransmissionHasCompleted(uart_device->uart));
122 }
123 while(!UARTTransmitterIsReady(uart_device->uart));
124 UARTSendDataByte(uart_device->uart, *ptr);
125 while(!UARTTransmissionHasCompleted(uart_device->uart));
126
127 ptr ++;
128 size --;
129 }
130 }
131 else
132 {
133 while ( size != 0 )
134 {
135 while(!UARTTransmitterIsReady(uart_device->uart));
136 UARTSendDataByte(uart_device->uart, *ptr);
137 while(!UARTTransmissionHasCompleted(uart_device->uart));
138
139 ptr++;
140 size--;
141 }
142 }
143
144 return (rt_size_t) ptr - (rt_size_t) buffer;
145 }
146
147
148 #ifdef RT_USING_UART1
149 // UART 1 interrupt handler
150 // it is set at priority level 2
__ISR(_UART1_VECTOR,ipl2)151 void __ISR(_UART1_VECTOR, ipl2) IntUART1Handler(void)
152 {
153 struct rt_uart_pic32 *uart_device = &uart1_device;
154
155 // Is this an RX interrupt?
156 if(INTGetFlag(INT_SOURCE_UART_RX(uart_device->uart)))
157 {
158 while( U1STAbits.URXDA )
159 {
160 /* Receive Data Available */
161 uart_device->rx_buffer[uart_device->save_index] = UARTGetDataByte(uart_device->uart);//UARTGetDataByte(UART1);
162 uart_device->save_index ++;
163 if (uart_device->save_index >= RT_UART_RX_BUFFER_SIZE)
164 {
165 uart_device->save_index = 0;
166 }
167 }
168
169 /* invoke callback */
170 if(uart_device->parent.rx_indicate != RT_NULL)
171 {
172 rt_size_t length;
173 if (uart_device->read_index > uart_device->save_index)
174 {
175 length = RT_UART_RX_BUFFER_SIZE - uart_device->read_index + uart_device->save_index;
176 }
177 else
178 {
179 length = uart_device->save_index - uart_device->read_index;
180 }
181
182 if( length )
183 {
184 uart_device->parent.rx_indicate(&uart_device->parent, length);
185 }
186 }
187
188 // Clear the RX interrupt Flag
189 INTClearFlag(INT_SOURCE_UART_RX(uart_device->uart));
190 } // Is this an RX interrupt?
191
192 // We don't care about TX interrupt
193 if ( INTGetFlag(INT_SOURCE_UART_TX(uart_device->uart)) )
194 {
195 INTClearFlag(INT_SOURCE_UART_TX(uart_device->uart));
196 }
197 }
198 #endif
199
200 #ifdef RT_USING_UART2
201 // UART 2 interrupt handler
202 // it is set at priority level 2
__ISR(_UART2_VECTOR,ipl2)203 void __ISR(_UART2_VECTOR, ipl2) IntUART2Handler(void)
204 {
205 struct rt_uart_pic32 *uart_device = &uart2_device;
206
207 // Is this an RX interrupt?
208 if(INTGetFlag(INT_SOURCE_UART_RX(uart_device->uart)))
209 {
210 while( U2STAbits.URXDA )
211 {
212 /* Receive Data Available */
213 uart_device->rx_buffer[uart_device->save_index] = UARTGetDataByte(uart_device->uart);//UARTGetDataByte(UART1);
214 uart_device->save_index ++;
215 if (uart_device->save_index >= RT_UART_RX_BUFFER_SIZE)
216 {
217 uart_device->save_index = 0;
218 }
219 }
220
221 /* invoke callback */
222 if(uart_device->parent.rx_indicate != RT_NULL)
223 {
224 rt_size_t length;
225 if (uart_device->read_index > uart_device->save_index)
226 {
227 length = RT_UART_RX_BUFFER_SIZE - uart_device->read_index + uart_device->save_index;
228 }
229 else
230 {
231 length = uart_device->save_index - uart_device->read_index;
232 }
233
234 if( length )
235 {
236 uart_device->parent.rx_indicate(&uart_device->parent, length);
237 }
238 }
239
240 // Clear the RX interrupt Flag
241 INTClearFlag(INT_SOURCE_UART_RX(uart_device->uart));
242 } // Is this an RX interrupt?
243
244 // We don't care about TX interrupt
245 if ( INTGetFlag(INT_SOURCE_UART_TX(uart_device->uart)) )
246 {
247 INTClearFlag(INT_SOURCE_UART_TX(uart_device->uart));
248 }
249 }
250 #endif
251
rt_hw_usart_init(void)252 void rt_hw_usart_init(void)
253 {
254 struct rt_uart_pic32 *uart_device;
255
256 #ifdef RT_USING_UART1
257 /* device initialization */
258 uart_device = &uart1_device;
259 rt_memset(uart_device,0,sizeof(struct rt_uart_pic32));
260 uart_device->uart = UART1;
261 uart_device->parent.type = RT_Device_Class_Char;
262
263 /* device interface */
264 uart_device->parent.init = rt_uart_init;
265 uart_device->parent.open = rt_uart_open;
266 uart_device->parent.close = rt_uart_close;
267 uart_device->parent.read = rt_uart_read;
268 uart_device->parent.write = rt_uart_write;
269 uart_device->parent.control = RT_NULL;
270 uart_device->parent.user_data = RT_NULL;
271
272 rt_device_register(&uart_device->parent,
273 "uart1", RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_STREAM | RT_DEVICE_FLAG_INT_RX);
274 #endif
275
276 #ifdef RT_USING_UART2
277 /* device initialization */
278 uart_device = &uart2_device;
279 rt_memset(uart_device,0,sizeof(struct rt_uart_pic32));
280 uart_device->uart = UART2;
281 uart_device->parent.type = RT_Device_Class_Char;
282
283 /* device interface */
284 uart_device->parent.init = rt_uart_init;
285 uart_device->parent.open = rt_uart_open;
286 uart_device->parent.close = rt_uart_close;
287 uart_device->parent.read = rt_uart_read;
288 uart_device->parent.write = rt_uart_write;
289 uart_device->parent.control = RT_NULL;
290 uart_device->parent.user_data = RT_NULL;
291
292 rt_device_register(&uart_device->parent,
293 "uart2", RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_STREAM | RT_DEVICE_FLAG_INT_RX);
294 #endif
295 }
296