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