1*10465441SEvalZero /*
2*10465441SEvalZero * File : serial.c
3*10465441SEvalZero * This file is part of RT-Thread RTOS
4*10465441SEvalZero * COPYRIGHT (C) 2006, RT-Thread Development Team
5*10465441SEvalZero *
6*10465441SEvalZero * The license and distribution terms for this file may be
7*10465441SEvalZero * found in the file LICENSE in this distribution or at
8*10465441SEvalZero * http://openlab.rt-thread.com/license/LICENSE
9*10465441SEvalZero *
10*10465441SEvalZero * Change Logs:
11*10465441SEvalZero * Date Author Notes
12*10465441SEvalZero * 2006-08-23 Bernard first version
13*10465441SEvalZero * 2009-05-14 Bernard add RT-THread device interface
14*10465441SEvalZero *
15*10465441SEvalZero * 2011-12-17 nl1031 MicroBlaze
16*10465441SEvalZero */
17*10465441SEvalZero
18*10465441SEvalZero #include <rthw.h>
19*10465441SEvalZero #include <rtthread.h>
20*10465441SEvalZero #include "serial.h"
21*10465441SEvalZero
22*10465441SEvalZero typedef volatile rt_uint32_t REG32;
23*10465441SEvalZero struct rt_mb_uart_lite_hw
24*10465441SEvalZero {
25*10465441SEvalZero REG32 Rx_FIFO; // Receiver Holding Register
26*10465441SEvalZero REG32 Tx_FIFO; // Transmitter Holding Register
27*10465441SEvalZero REG32 STAT_REG; // Channel Status Register
28*10465441SEvalZero REG32 CTRL_REG; // Control Register
29*10465441SEvalZero };
30*10465441SEvalZero
31*10465441SEvalZero struct rt_mb_uart_lite
32*10465441SEvalZero {
33*10465441SEvalZero struct rt_device parent;
34*10465441SEvalZero
35*10465441SEvalZero struct rt_mb_uart_lite_hw* hw_base;
36*10465441SEvalZero rt_uint16_t peripheral_id;
37*10465441SEvalZero rt_uint32_t baudrate;
38*10465441SEvalZero
39*10465441SEvalZero /* reception field */
40*10465441SEvalZero rt_uint16_t save_index, read_index;
41*10465441SEvalZero rt_uint8_t rx_buffer[RT_UART_RX_BUFFER_SIZE];
42*10465441SEvalZero };
43*10465441SEvalZero #ifdef RT_USING_UART1
44*10465441SEvalZero struct rt_mb_uart_lite serial1;
45*10465441SEvalZero #endif
46*10465441SEvalZero
rt_hw_serial_isr(void)47*10465441SEvalZero static void rt_hw_serial_isr(void)
48*10465441SEvalZero {
49*10465441SEvalZero unsigned int status;
50*10465441SEvalZero rt_base_t level;
51*10465441SEvalZero struct rt_device* device;
52*10465441SEvalZero struct rt_mb_uart_lite* serial = RT_NULL;
53*10465441SEvalZero
54*10465441SEvalZero #ifdef RT_USING_UART1
55*10465441SEvalZero /* serial 1 */
56*10465441SEvalZero serial = &serial1;
57*10465441SEvalZero #endif
58*10465441SEvalZero RT_ASSERT(serial != RT_NULL);
59*10465441SEvalZero
60*10465441SEvalZero /* get generic device object */
61*10465441SEvalZero device = (rt_device_t)serial;
62*10465441SEvalZero
63*10465441SEvalZero /* disable interrupt */
64*10465441SEvalZero level = rt_hw_interrupt_disable();
65*10465441SEvalZero
66*10465441SEvalZero /* get uart status register */
67*10465441SEvalZero status = serial->hw_base->STAT_REG;
68*10465441SEvalZero while (status & XUL_SR_RX_FIFO_VALID_DATA)
69*10465441SEvalZero {
70*10465441SEvalZero /* get received character */
71*10465441SEvalZero serial->rx_buffer[serial->save_index] = serial->hw_base->Rx_FIFO;
72*10465441SEvalZero
73*10465441SEvalZero /* move to next position */
74*10465441SEvalZero serial->save_index ++;
75*10465441SEvalZero if (serial->save_index >= RT_UART_RX_BUFFER_SIZE)
76*10465441SEvalZero serial->save_index = 0;
77*10465441SEvalZero
78*10465441SEvalZero /* if the next position is read index, discard this 'read char' */
79*10465441SEvalZero if (serial->save_index == serial->read_index)
80*10465441SEvalZero {
81*10465441SEvalZero serial->read_index ++;
82*10465441SEvalZero if (serial->read_index >= RT_UART_RX_BUFFER_SIZE)
83*10465441SEvalZero serial->read_index = 0;
84*10465441SEvalZero }
85*10465441SEvalZero status = serial->hw_base->STAT_REG;
86*10465441SEvalZero }
87*10465441SEvalZero /* enable interrupt */
88*10465441SEvalZero rt_hw_interrupt_enable(level);
89*10465441SEvalZero
90*10465441SEvalZero /* indicate to upper layer application */
91*10465441SEvalZero if (device->rx_indicate != RT_NULL)
92*10465441SEvalZero device->rx_indicate(device, 1);
93*10465441SEvalZero
94*10465441SEvalZero }
95*10465441SEvalZero
rt_serial_init(rt_device_t dev)96*10465441SEvalZero static rt_err_t rt_serial_init (rt_device_t dev)
97*10465441SEvalZero {
98*10465441SEvalZero struct rt_mb_uart_lite* serial = (struct rt_mb_uart_lite*) dev;
99*10465441SEvalZero
100*10465441SEvalZero RT_ASSERT(serial != RT_NULL);
101*10465441SEvalZero
102*10465441SEvalZero RT_ASSERT(serial->peripheral_id != XPAR_UARTLITE_1_DEVICE_ID);
103*10465441SEvalZero
104*10465441SEvalZero
105*10465441SEvalZero /* reset rx index */
106*10465441SEvalZero serial->save_index = 0;
107*10465441SEvalZero serial->read_index = 0;
108*10465441SEvalZero
109*10465441SEvalZero /* reset rx buffer */
110*10465441SEvalZero rt_memset(serial->rx_buffer, 0, RT_UART_RX_BUFFER_SIZE);
111*10465441SEvalZero
112*10465441SEvalZero return RT_EOK;
113*10465441SEvalZero }
114*10465441SEvalZero
rt_serial_open(rt_device_t dev,rt_uint16_t oflag)115*10465441SEvalZero static rt_err_t rt_serial_open(rt_device_t dev, rt_uint16_t oflag)
116*10465441SEvalZero {
117*10465441SEvalZero struct rt_mb_uart_lite *serial = (struct rt_mb_uart_lite*)dev;
118*10465441SEvalZero RT_ASSERT(serial != RT_NULL);
119*10465441SEvalZero
120*10465441SEvalZero if (dev->flag & RT_DEVICE_FLAG_INT_RX)
121*10465441SEvalZero {
122*10465441SEvalZero /* enable UART rx interrupt */
123*10465441SEvalZero serial->hw_base->CTRL_REG = XUL_CR_ENABLE_INTR; /* enable interrupt */
124*10465441SEvalZero
125*10465441SEvalZero /* install UART handler */
126*10465441SEvalZero rt_hw_interrupt_install(serial->peripheral_id, (rt_isr_handler_t)rt_hw_serial_isr, RT_NULL);
127*10465441SEvalZero rt_hw_interrupt_umask(serial->peripheral_id);
128*10465441SEvalZero }
129*10465441SEvalZero
130*10465441SEvalZero return RT_EOK;
131*10465441SEvalZero }
132*10465441SEvalZero
rt_serial_close(rt_device_t dev)133*10465441SEvalZero static rt_err_t rt_serial_close(rt_device_t dev)
134*10465441SEvalZero {
135*10465441SEvalZero struct rt_mb_uart_lite *serial = (struct rt_mb_uart_lite*)dev;
136*10465441SEvalZero RT_ASSERT(serial != RT_NULL);
137*10465441SEvalZero
138*10465441SEvalZero if (dev->flag & RT_DEVICE_FLAG_INT_RX)
139*10465441SEvalZero {
140*10465441SEvalZero /* disable interrupt */
141*10465441SEvalZero serial->hw_base->CTRL_REG = 0; /* RxReady interrupt */
142*10465441SEvalZero }
143*10465441SEvalZero
144*10465441SEvalZero return RT_EOK;
145*10465441SEvalZero }
146*10465441SEvalZero
rt_serial_read(rt_device_t dev,rt_off_t pos,void * buffer,rt_size_t size)147*10465441SEvalZero static rt_size_t rt_serial_read (rt_device_t dev, rt_off_t pos, void* buffer, rt_size_t size)
148*10465441SEvalZero {
149*10465441SEvalZero rt_uint8_t* ptr;
150*10465441SEvalZero struct rt_mb_uart_lite *serial = (struct rt_mb_uart_lite*)dev;
151*10465441SEvalZero RT_ASSERT(serial != RT_NULL);
152*10465441SEvalZero
153*10465441SEvalZero /* point to buffer */
154*10465441SEvalZero ptr = (rt_uint8_t*) buffer;
155*10465441SEvalZero
156*10465441SEvalZero if (dev->flag & RT_DEVICE_FLAG_INT_RX)
157*10465441SEvalZero {
158*10465441SEvalZero while (size)
159*10465441SEvalZero {
160*10465441SEvalZero /* interrupt receive */
161*10465441SEvalZero rt_base_t level;
162*10465441SEvalZero
163*10465441SEvalZero /* disable interrupt */
164*10465441SEvalZero level = rt_hw_interrupt_disable();
165*10465441SEvalZero if (serial->read_index != serial->save_index)
166*10465441SEvalZero {
167*10465441SEvalZero *ptr = serial->rx_buffer[serial->read_index];
168*10465441SEvalZero
169*10465441SEvalZero serial->read_index ++;
170*10465441SEvalZero if (serial->read_index >= RT_UART_RX_BUFFER_SIZE)
171*10465441SEvalZero serial->read_index = 0;
172*10465441SEvalZero }
173*10465441SEvalZero else
174*10465441SEvalZero {
175*10465441SEvalZero /* no data in rx buffer */
176*10465441SEvalZero
177*10465441SEvalZero /* enable interrupt */
178*10465441SEvalZero rt_hw_interrupt_enable(level);
179*10465441SEvalZero break;
180*10465441SEvalZero }
181*10465441SEvalZero
182*10465441SEvalZero /* enable interrupt */
183*10465441SEvalZero rt_hw_interrupt_enable(level);
184*10465441SEvalZero
185*10465441SEvalZero ptr ++; size --;
186*10465441SEvalZero }
187*10465441SEvalZero
188*10465441SEvalZero return (rt_uint32_t)ptr - (rt_uint32_t)buffer;
189*10465441SEvalZero }
190*10465441SEvalZero else if (dev->flag & RT_DEVICE_FLAG_DMA_RX)
191*10465441SEvalZero {
192*10465441SEvalZero /* not support right now */
193*10465441SEvalZero RT_ASSERT(0);
194*10465441SEvalZero }
195*10465441SEvalZero else
196*10465441SEvalZero {
197*10465441SEvalZero /* poll mode */
198*10465441SEvalZero while (size)
199*10465441SEvalZero {
200*10465441SEvalZero /* Wait for Full Rx Buffer */
201*10465441SEvalZero while (!(serial->hw_base->STAT_REG & XUL_SR_RX_FIFO_VALID_DATA));
202*10465441SEvalZero
203*10465441SEvalZero /* Read Character */
204*10465441SEvalZero *ptr = serial->hw_base->Rx_FIFO;
205*10465441SEvalZero ptr ++;
206*10465441SEvalZero size --;
207*10465441SEvalZero }
208*10465441SEvalZero
209*10465441SEvalZero return (rt_size_t)ptr - (rt_size_t)buffer;
210*10465441SEvalZero }
211*10465441SEvalZero
212*10465441SEvalZero return 0;
213*10465441SEvalZero }
214*10465441SEvalZero
rt_serial_write(rt_device_t dev,rt_off_t pos,const void * buffer,rt_size_t size)215*10465441SEvalZero static rt_size_t rt_serial_write (rt_device_t dev, rt_off_t pos, const void* buffer, rt_size_t size)
216*10465441SEvalZero {
217*10465441SEvalZero rt_uint8_t* ptr;
218*10465441SEvalZero struct rt_mb_uart_lite *serial = (struct rt_mb_uart_lite*)dev;
219*10465441SEvalZero RT_ASSERT(serial != RT_NULL);
220*10465441SEvalZero
221*10465441SEvalZero ptr = (rt_uint8_t*) buffer;
222*10465441SEvalZero if (dev->open_flag & RT_DEVICE_OFLAG_WRONLY)
223*10465441SEvalZero {
224*10465441SEvalZero if (dev->flag & RT_DEVICE_FLAG_STREAM)
225*10465441SEvalZero {
226*10465441SEvalZero /* it's a stream mode device */
227*10465441SEvalZero while (size)
228*10465441SEvalZero {
229*10465441SEvalZero /* stream mode */
230*10465441SEvalZero if (*ptr == '\n')
231*10465441SEvalZero {
232*10465441SEvalZero while (!(serial->hw_base->STAT_REG & XUL_SR_TX_FIFO_EMPTY));
233*10465441SEvalZero serial->hw_base->Tx_FIFO = '\r';
234*10465441SEvalZero }
235*10465441SEvalZero
236*10465441SEvalZero /* Wait for Empty Tx Buffer */
237*10465441SEvalZero while (!(serial->hw_base->STAT_REG & XUL_SR_TX_FIFO_EMPTY));
238*10465441SEvalZero
239*10465441SEvalZero /* Transmit Character */
240*10465441SEvalZero serial->hw_base->Tx_FIFO = *ptr;
241*10465441SEvalZero if (*ptr & 1)
242*10465441SEvalZero rt_hw_board_led_on(2);
243*10465441SEvalZero else
244*10465441SEvalZero rt_hw_board_led_off(2);
245*10465441SEvalZero ptr ++; size --;
246*10465441SEvalZero }
247*10465441SEvalZero }
248*10465441SEvalZero else
249*10465441SEvalZero {
250*10465441SEvalZero while (size)
251*10465441SEvalZero {
252*10465441SEvalZero /* Wait for Empty Tx Buffer */
253*10465441SEvalZero while (!(serial->hw_base->STAT_REG & XUL_SR_TX_FIFO_EMPTY));
254*10465441SEvalZero
255*10465441SEvalZero /* Transmit Character */
256*10465441SEvalZero serial->hw_base->Tx_FIFO = *ptr;
257*10465441SEvalZero if (*ptr & 1)
258*10465441SEvalZero rt_hw_board_led_on(2);
259*10465441SEvalZero else
260*10465441SEvalZero rt_hw_board_led_off(2);
261*10465441SEvalZero ptr ++; size --;
262*10465441SEvalZero }
263*10465441SEvalZero }
264*10465441SEvalZero }
265*10465441SEvalZero
266*10465441SEvalZero return (rt_size_t)ptr - (rt_size_t)buffer;
267*10465441SEvalZero }
268*10465441SEvalZero
rt_serial_control(rt_device_t dev,int cmd,void * args)269*10465441SEvalZero static rt_err_t rt_serial_control (rt_device_t dev, int cmd, void *args)
270*10465441SEvalZero {
271*10465441SEvalZero return RT_EOK;
272*10465441SEvalZero }
273*10465441SEvalZero
rt_hw_serial_init()274*10465441SEvalZero rt_err_t rt_hw_serial_init()
275*10465441SEvalZero {
276*10465441SEvalZero rt_device_t device;
277*10465441SEvalZero
278*10465441SEvalZero #ifndef RT_USING_CONSOLE
279*10465441SEvalZero int Status;
280*10465441SEvalZero
281*10465441SEvalZero /*
282*10465441SEvalZero * Initialize the UartLite driver so that it is ready to use.
283*10465441SEvalZero */
284*10465441SEvalZero Status = XUartLite_Initialize(&uart_lite, RS232_DEVICE_ID);
285*10465441SEvalZero if (Status != XST_SUCCESS)
286*10465441SEvalZero {
287*10465441SEvalZero return;
288*10465441SEvalZero }
289*10465441SEvalZero
290*10465441SEvalZero #endif
291*10465441SEvalZero
292*10465441SEvalZero #ifdef RT_USING_UART1
293*10465441SEvalZero device = (rt_device_t) &serial1;
294*10465441SEvalZero
295*10465441SEvalZero /* init serial device private data */
296*10465441SEvalZero serial1.hw_base = (struct rt_mb_uart_lite_hw*)XPAR_USB_UART_BASEADDR;
297*10465441SEvalZero serial1.peripheral_id = XPAR_UARTLITE_1_DEVICE_ID;
298*10465441SEvalZero serial1.baudrate = 115200;
299*10465441SEvalZero
300*10465441SEvalZero /* set device virtual interface */
301*10465441SEvalZero device->init = rt_serial_init;
302*10465441SEvalZero device->open = rt_serial_open;
303*10465441SEvalZero device->close = rt_serial_close;
304*10465441SEvalZero device->read = rt_serial_read;
305*10465441SEvalZero device->write = rt_serial_write;
306*10465441SEvalZero device->control = rt_serial_control;
307*10465441SEvalZero
308*10465441SEvalZero /* register uart1 on device subsystem */
309*10465441SEvalZero rt_device_register(device, "uart1", RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX);
310*10465441SEvalZero #endif
311*10465441SEvalZero
312*10465441SEvalZero
313*10465441SEvalZero return RT_EOK;
314*10465441SEvalZero }
315*10465441SEvalZero
316*10465441SEvalZero
317