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

4.104.114.84.95
Last change on this file since 862c2317 was 862c2317, checked in by Thomas Doerfler <Thomas.Doerfler@…>, on 07/04/07 at 12:37:36

added virtex BSP support and some missing files for common PPC
exception handling

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