source: rtems/c/src/lib/libbsp/powerpc/virtex/console/consolelite.c @ c00b49f8

4.104.115
Last change on this file since c00b49f8 was 6771a9e7, checked in by Ralf Corsepius <ralf.corsepius@…>, on 08/20/08 at 09:00:11

Add missing prototypes.

  • Property mode set to 100644
File size: 10.0 KB
Line 
1/*
2 *  This file contains the console driver for the xilinx uart lite.
3 *
4 *  Author: Keith Robertson <kjrobert@alumni.uwaterloo.ca>
5 *  COPYRIGHT (c) 2005 by Linn Products Ltd, Scotland.
6 *
7 *  Derived from libbsp/no_cpu/no_bsp/console.c and therefore also:
8 *
9 *  COPYRIGHT (c) 1989-1999.
10 *  On-Line Applications Research Corporation (OAR).
11 *
12 *  The license and distribution terms for this file may be
13 *  found in the file LICENSE in this distribution or at
14 *  http://www.rtems.com/license/LICENSE.
15 *
16 */
17
18#include <rtems.h>
19#include <rtems/libio.h>
20#include <bsp/irq.h>
21
22#include <bsp.h>
23#include <libchip/serial.h>
24#include <libchip/sersupp.h>
25
26#include RTEMS_XPARAMETERS_H
27
28/* Status Register Masks */
29#define PARITY_ERROR       0x80 /* Parity Error */
30#define FRAME_ERROR        0x40 /* Frame Error */
31#define OVERRUN_ERROR      0x20 /* Overrun Error */
32#define STATUS_REG_ERROR_MASK ( PARITY_ERROR | FRAME_ERROR | OVERRUN_ERROR )
33
34#define INTR_ENABLED       0x10 /* Interrupts are enabled */
35#define TX_FIFO_FULL       0x08 /* Transmit FIFO is full */
36#define TX_FIFO_EMPTY      0x04 /* Transmit FIFO is empty */
37#define RX_FIFO_FULL       0x02 /* Receive FIFO is full */
38#define RX_FIFO_VALID_DATA 0x01 /* Receive FIFO has valid data */
39/* Control Register Masks*/
40#define ENABLE_INTR        0x10 /* Enable interrupts */
41#define RST_RX_FIFO        0x02 /* Reset and clear RX FIFO */
42#define RST_TX_FIFO        0x01 /* Reset and clear TX FIFO */
43
44/* General Defines */
45#define TX_FIFO_SIZE       16
46#define RX_FIFO_SIZE       16
47
48
49
50
51#define RECV_REG 0
52#define TRAN_REG 4
53#define STAT_REG 8
54#define CTRL_REG 12
55
56
57
58RTEMS_INLINE_ROUTINE uint32_t xlite_uart_control(uint32_t base)
59{
60  uint32_t c = *((volatile uint32_t*)(base+CTRL_REG));
61  return c;
62}
63
64
65RTEMS_INLINE_ROUTINE uint32_t xlite_uart_status(uint32_t base)
66{
67  uint32_t c = *((volatile uint32_t*)(base+STAT_REG));
68  return c;
69}
70
71
72RTEMS_INLINE_ROUTINE uint32_t xlite_uart_read(uint32_t base)
73{
74  uint32_t c = *((volatile uint32_t*)(base+RECV_REG));
75  return c;
76}
77
78
79RTEMS_INLINE_ROUTINE void xlite_uart_write(uint32_t base, char ch)
80{
81  *(volatile uint32_t*)(base+TRAN_REG) = (uint32_t)ch;
82  return;
83}
84
85
86
87int xlite_write_char(uint32_t base, char ch)
88{
89   uint32_t  retrycount= 0, idler, status;
90
91   while( ((status = xlite_uart_status(base)) & TX_FIFO_FULL) != 0 )
92   {
93      ++retrycount;
94
95      /* uart tx is busy */
96      if( retrycount == 0x4000 )
97      {
98         /* retrycount is arbitrary- just make it big enough so the uart is sure to be timed out before it trips */
99         return -1;
100      }
101
102      /* spin for a bit so we can sample the register rather than
103       * continually reading it */
104      for( idler= 0; idler < 0x2000; idler++);
105   }
106
107   xlite_uart_write(base, ch);
108
109   return 1;
110}
111
112
113
114
115
116
117
118
119
120
121
122void xlite_init (int minor )
123{
124   uint32_t base = Console_Port_Tbl[minor].ulCtrlPort1;
125
126   /* clear status register */
127   *((volatile uint32_t*)(base+STAT_REG)) = 0;
128
129   /* clear control register; reset fifos & interrupt enable */
130   *((volatile uint32_t*)(base+CTRL_REG)) = RST_RX_FIFO | RST_TX_FIFO;
131}
132
133
134int xlite_open(
135  int      major,
136  int      minor,
137  void    *arg
138)
139{
140   uint32_t base = Console_Port_Tbl[minor].ulCtrlPort1;
141
142   /* the lite uarts have hardcoded baud & serial parms so no port
143    * conditioning is needed.  We're running polled so no interrupt
144    * enables either */
145
146   /* clear status register */
147   *((volatile uint32_t*)(base+STAT_REG)) = 0;
148
149   /* clear control register; reset fifos & disable interrupts */
150   *((volatile uint32_t*)(base+CTRL_REG)) = RST_RX_FIFO | RST_TX_FIFO;
151
152   return RTEMS_SUCCESSFUL;
153}
154
155
156int xlite_close(
157  int      major,
158  int      minor,
159  void    *arg
160)
161{
162   /* no shutdown protocol necessary */
163   return RTEMS_SUCCESSFUL;
164}
165
166
167
168int xlite_read_polled (int minor )
169{
170   uint32_t base = Console_Port_Tbl[minor].ulCtrlPort1;
171
172   unsigned int status = xlite_uart_status(base);
173
174   if(status & RX_FIFO_VALID_DATA)
175      return (int)xlite_uart_read(base);
176   else
177      return -1;
178}
179
180
181
182
183int xlite_write_buffer_polled(
184  int         minor,
185  const char *buf,
186  int         len
187)
188{
189   uint32_t base = Console_Port_Tbl[minor].ulCtrlPort1;
190   int nwrite = 0;
191
192   /*
193    * poll each byte in the string out of the port.
194    */
195   while (nwrite < len)
196   {
197      if( xlite_write_char(base, *buf++) < 0 ) break;
198      nwrite++;
199   }
200
201   /*
202    * return the number of bytes written.
203    */
204   return nwrite;
205}
206
207
208void xlite_write_char_polled(
209  int   minor,
210  char  c
211)
212{
213   uint32_t base = Console_Port_Tbl[minor].ulCtrlPort1;
214   xlite_write_char(base, c);
215   return;
216}
217
218
219
220int xlite_set_attributes(int minor, const struct termios *t)
221{
222   return RTEMS_SUCCESSFUL;
223}
224
225
226
227
228
229
230
231console_fns xlite_fns_polled =
232{
233  libchip_serial_default_probe,        /* deviceProbe */
234  xlite_open,                          /* deviceFirstOpen */
235  xlite_close,                         /* deviceLastClose */
236  xlite_read_polled,                   /* deviceRead */
237  xlite_write_buffer_polled,           /* deviceWrite */
238  xlite_init,                          /* deviceInitialize */
239  xlite_write_char_polled,             /* deviceWritePolled */
240  xlite_set_attributes,                /* deviceSetAttributes */
241  FALSE,                               /* deviceOutputUsesInterrupts */
242};
243
244
245
246
247
248
249/*
250** Set ulCtrlPort1 to the base address of each UART Lite instance.  Set in vhdl model.
251*/
252
253
254console_tbl     Console_Port_Tbl[] = {
255{
256  "/dev/ttyS0",                             /* sDeviceName */
257   SERIAL_CUSTOM,                           /* deviceType */
258   &xlite_fns_polled,                      /* pDeviceFns */
259   NULL,                                   /* deviceProbe, assume it is there */
260   NULL,                                   /* pDeviceFlow */
261   16,                                     /* ulMargin */
262   8,                                      /* ulHysteresis */
263   (void *) NULL,               /* NULL */ /* pDeviceParams */
264   STDIN_BASEADDRESS,                      /* ulCtrlPort1 */
265   0,                                      /* ulCtrlPort2 */
266   0,                                      /* ulDataPort */
267   NULL,                                   /* getRegister */
268   NULL,                                   /* setRegister */
269   NULL, /* unused */                      /* getData */
270   NULL, /* unused */                      /* setData */
271   0,                                      /* ulClock */
272   0                                       /* ulIntVector -- base for port */
273},
274{
275  "/dev/ttyS1",                             /* sDeviceName */
276   SERIAL_CUSTOM,                           /* deviceType */
277   &xlite_fns_polled,                       /* pDeviceFns */
278   NULL,                                   /* deviceProbe, assume it is there */
279   NULL,                                   /* pDeviceFlow */
280   16,                                     /* ulMargin */
281   8,                                      /* ulHysteresis */
282   (void *) NULL,               /* NULL */ /* pDeviceParams */
283   0x40610000,                             /* ulCtrlPort1 */
284   0,                                      /* ulCtrlPort2 */
285   0,                                      /* ulDataPort */
286   NULL,                                   /* getRegister */
287   NULL,                                   /* setRegister */
288   NULL, /* unused */                      /* getData */
289   NULL, /* unused */                      /* setData */
290   0,                                      /* ulClock */
291   0                                       /* ulIntVector -- base for port */
292},
293{
294  "/dev/ttyS2",                             /* sDeviceName */
295   SERIAL_CUSTOM,                           /* deviceType */
296   &xlite_fns_polled,                       /* pDeviceFns */
297   NULL,                                   /* deviceProbe, assume it is there */
298   NULL,                                   /* pDeviceFlow */
299   16,                                     /* ulMargin */
300   8,                                      /* ulHysteresis */
301   (void *) NULL,               /* NULL */ /* pDeviceParams */
302   0x40620000,                             /* ulCtrlPort1 */
303   0,                                      /* ulCtrlPort2 */
304   0,                                      /* ulDataPort */
305   NULL,                                   /* getRegister */
306   NULL,                                   /* setRegister */
307   NULL, /* unused */                      /* getData */
308   NULL, /* unused */                      /* setData */
309   0,                                      /* ulClock */
310   0                                       /* ulIntVector -- base for port */
311},
312{
313  "/dev/ttyS3",                             /* sDeviceName */
314   SERIAL_CUSTOM,                           /* deviceType */
315   &xlite_fns_polled,                       /* pDeviceFns */
316   NULL,                                   /* deviceProbe, assume it is there */
317   NULL,                                   /* pDeviceFlow */
318   16,                                     /* ulMargin */
319   8,                                      /* ulHysteresis */
320   (void *) NULL,               /* NULL */ /* pDeviceParams */
321   0x40630000,                             /* ulCtrlPort1 */
322   0,                                      /* ulCtrlPort2 */
323   0,                                      /* ulDataPort */
324   NULL,                                   /* getRegister */
325   NULL,                                   /* setRegister */
326   NULL, /* unused */                      /* getData */
327   NULL, /* unused */                      /* setData */
328   0,                                      /* ulClock */
329   0                                       /* ulIntVector -- base for port */
330}
331};
332
333
334
335
336#define NUM_CONSOLE_PORTS (sizeof(Console_Port_Tbl)/sizeof(console_tbl))
337
338unsigned long                   Console_Port_Count = NUM_CONSOLE_PORTS;
339console_data                    Console_Port_Data[NUM_CONSOLE_PORTS];
340rtems_device_minor_number       Console_Port_Minor;
341
342
343
344
345
346
347
348
349#include <rtems/bspIo.h>
350
351void outputChar(char ch)
352{
353  if (ch == '\n') {
354    xlite_write_char_polled( 0, '\r' );
355  }
356   xlite_write_char_polled( 0, ch );
357}
358
359char inputChar(void)
360{
361   return (char)xlite_read_polled(0);
362}
363
364BSP_output_char_function_type BSP_output_char = outputChar;
365BSP_polling_getchar_function_type BSP_poll_char = inputChar;
366
367
Note: See TracBrowser for help on using the repository browser.