OpenCores
URL https://opencores.org/ocsvn/openrisc_2011-10-31/openrisc_2011-10-31/trunk

Subversion Repositories openrisc_2011-10-31

[/] [openrisc/] [trunk/] [or1ksim/] [peripheral/] [channels/] [tty.c] - Blame information for rev 159

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 19 jeremybenn
/* tty.c -- Definition of functions for peripheral to
2
 * communicate with host via a tty.
3
 
4
   Copyright (C) 2002 Richard Prescott <rip@step.polymtl.ca>
5
   Copyright (C) 2008 Embecosm Limited
6
 
7
   Contributor Jeremy Bennett <jeremy.bennett@embecosm.com>
8
 
9
   This file is part of Or1ksim, the OpenRISC 1000 Architectural Simulator.
10
 
11
   This program is free software; you can redistribute it and/or modify it
12
   under the terms of the GNU General Public License as published by the Free
13
   Software Foundation; either version 3 of the License, or (at your option)
14
   any later version.
15
 
16
   This program is distributed in the hope that it will be useful, but WITHOUT
17
   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
18
   FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
19
   more details.
20
 
21
   You should have received a copy of the GNU General Public License along
22
   with this program.  If not, see <http://www.gnu.org/licenses/>.  */
23
 
24
/* This program is commented throughout in a fashion suitable for processing
25
   with Doxygen. */
26
 
27
 
28
/* Autoconf and/or portability configuration */
29
#include "config.h"
30
#include "port.h"
31
 
32
/* System includes */
33
#include <stdlib.h>
34
#include <unistd.h>
35
#include <termios.h>
36
#include <stdio.h>
37
#include <fcntl.h>
38
 
39
/* Package includes */
40
#include "channel.h"
41
#include "generic.h"
42
#include "fd.h"
43
 
44
/* Default parameters if not specified in config file */
45
#define DEFAULT_BAUD        B19200
46
#define DEFAULT_TTY_DEVICE  "/dev/ttyS0"
47
 
48
/*! Data structure representing a TTY channel */
49
struct tty_channel
50
{
51
  struct fd_channel fds;
52
};
53
 
54
/*! Table of Baud rates */
55
static const struct
56
{
57
  char *name;
58
  int value;
59
} baud_table[] =
60
{
61
  {
62
  "50", B50},
63
  {
64
  "2400", B2400},
65
  {
66
  "4800", B4800},
67
  {
68
  "9600", B9600},
69
  {
70
  "19200", B19200},
71
  {
72
  "38400", B38400},
73
  {
74
  "115200", B115200},
75
  {
76
  "230400", B230400},
77
  {
78
  0, 0}
79
};
80
 
81
/* Forward declaration of static functions */
82
static void *tty_init (const char *input);
83
static int   tty_open (void *data);
84
 
85
/*! Global data structure representing the operations on a TTY channel */
86
struct channel_ops tty_channel_ops = {
87
        .init  = tty_init,
88
        .open  = tty_open,
89
        .close = generic_close,
90
        .read  = fd_read,
91
        .write = fd_write,
92
        .free  = generic_free,
93
};
94
 
95
 
96
/* Convert baud rate string to termio baud rate constant */
97
static int
98
parse_baud (char *baud_string)
99
{
100
  int i;
101
  for (i = 0; baud_table[i].name; i++)
102
    {
103
      if (!strcmp (baud_table[i].name, baud_string))
104
        return baud_table[i].value;
105
    }
106
 
107
  fprintf (stderr, "Error: unknown baud rate: %s\n", baud_string);
108
  fprintf (stderr, "       Known baud rates: ");
109
 
110
  for (i = 0; baud_table[i].name; i++)
111
    {
112
      fprintf (stderr, "%s%s", baud_table[i].name,
113
               baud_table[i + 1].name ? ", " : "\n");
114
    }
115
  return B0;
116
}
117
 
118
static void *
119
tty_init (const char *input)
120
{
121
  int fd = 0, baud;
122
  char *param_name, *param_value, *device;
123
  struct termios options;
124
  struct tty_channel *channel;
125
 
126
  channel = (struct tty_channel *) malloc (sizeof (struct tty_channel));
127
  if (!channel)
128
    return NULL;
129
 
130
  /* Make a copy of config string, because we're about to mutate it */
131
  input = strdup (input);
132
  if (!input)
133
    goto error;
134
 
135
  baud = DEFAULT_BAUD;
136
  device = DEFAULT_TTY_DEVICE;
137
 
138
  /* Parse command-line parameters
139
     Command line looks like name1=value1,name2,name3=value3,... */
140
  while ((param_name = strtok ((char *) input, ",")))
141
    {
142
 
143
      input = NULL;
144
 
145
      /* Parse a parameter's name and value */
146
      param_value = strchr (param_name, '=');
147
      if (param_value != NULL)
148
        {
149
          *param_value = '\0';
150
          param_value++;        /* Advance past '=' character */
151
        }
152
 
153
      if (!strcmp (param_name, "baud") && param_value)
154
        {
155
          baud = parse_baud (param_value);
156
          if (baud == B0)
157
            {
158
              goto error;
159
            }
160
        }
161
      else if (!strcmp (param_name, "device"))
162
        {
163
          device = param_value;
164
        }
165
      else
166
        {
167
          fprintf (stderr, "error: unknown tty channel parameter \"%s\"\n",
168
                   param_name);
169
          goto error;
170
        }
171
    }
172
 
173
  fd = open (device, O_RDWR);
174
  if (fd < 0)
175
    goto error;
176
 
177
  /* Get the current options for the port... */
178
  if (tcgetattr (fd, &options) < 0)
179
    goto error;
180
 
181
  /* Set the serial baud rate */
182
  cfsetispeed (&options, baud);
183
  cfsetospeed (&options, baud);
184
 
185
  /* Enable the receiver and set local mode... */
186
 
187
  /* cfmakeraw(&options);
188
   *
189
   * cygwin lacks cfmakeraw(), just do it explicitly
190
   */
191
  options.c_iflag &= ~(IGNBRK | BRKINT | PARMRK | ISTRIP
192
                       | INLCR | IGNCR | ICRNL | IXON);
193
  options.c_oflag &= ~OPOST;
194
  options.c_lflag &= ~(ECHO | ECHONL | ICANON | ISIG | IEXTEN);
195
  options.c_cflag &= ~(CSIZE | PARENB);
196
  options.c_cflag |= CS8;
197
 
198
  options.c_cflag |= (CLOCAL | CREAD);
199
 
200
 
201
  /* Set the new options for the port... */
202
  if (tcsetattr (fd, TCSANOW, &options) < 0)
203
    goto error;
204
 
205
  channel->fds.fdin = channel->fds.fdout = fd;
206
  free ((void *) input);
207
  return channel;
208
 
209
error:
210
  if (fd > 0)
211
    close (fd);
212
  free (channel);
213
  if (input)
214
    free ((void *) input);
215
  return NULL;
216
}
217
 
218
static int
219
tty_open (void *data)
220
{
221
  return 0;
222
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.