OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [tags/] [rel-0-3-0-rc1/] [or1ksim/] [peripheral/] [channels/] [tty.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1127 sfurman
/* 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 1748 jeremybenn
   Copyright (C) 2008 Embecosm Limited
6 1127 sfurman
 
7 1748 jeremybenn
   Contributor Jeremy Bennett <jeremy.bennett@embecosm.com>
8 1127 sfurman
 
9 1748 jeremybenn
   This file is part of Or1ksim, the OpenRISC 1000 Architectural Simulator.
10 1127 sfurman
 
11 1748 jeremybenn
   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 1127 sfurman
 
16 1748 jeremybenn
   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 1127 sfurman
 
21 1748 jeremybenn
   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 1127 sfurman
#include <stdio.h>
37 1128 sfurman
#include <fcntl.h>
38 1127 sfurman
 
39 1748 jeremybenn
/* Package includes */
40 1127 sfurman
#include "channel.h"
41
#include "generic.h"
42
#include "fd.h"
43
 
44 1748 jeremybenn
/* Default parameters if not specified in config file */
45
#define DEFAULT_BAUD        B19200
46
#define DEFAULT_TTY_DEVICE  "/dev/ttyS0"
47 1127 sfurman
 
48 1748 jeremybenn
/*! Data structure representing a TTY channel */
49 1127 sfurman
struct tty_channel
50
{
51 1748 jeremybenn
  struct fd_channel fds;
52 1127 sfurman
};
53
 
54 1748 jeremybenn
/*! 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 1127 sfurman
};
80
 
81 1748 jeremybenn
/* 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 1127 sfurman
{
100 1748 jeremybenn
  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 1127 sfurman
 
107 1748 jeremybenn
  fprintf (stderr, "Error: unknown baud rate: %s\n", baud_string);
108
  fprintf (stderr, "       Known baud rates: ");
109 1127 sfurman
 
110 1748 jeremybenn
  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 1127 sfurman
}
117
 
118 1748 jeremybenn
static void *
119
tty_init (const char *input)
120 1127 sfurman
{
121 1748 jeremybenn
  int fd = 0, baud;
122
  char *param_name, *param_value, *device;
123
  struct termios options;
124
  struct tty_channel *channel;
125 1127 sfurman
 
126 1748 jeremybenn
  channel = (struct tty_channel *) malloc (sizeof (struct tty_channel));
127
  if (!channel)
128
    return NULL;
129 1127 sfurman
 
130 1748 jeremybenn
  /* Make a copy of config string, because we're about to mutate it */
131
  input = strdup (input);
132
  if (!input)
133
    goto error;
134 1127 sfurman
 
135 1748 jeremybenn
  baud = DEFAULT_BAUD;
136
  device = DEFAULT_TTY_DEVICE;
137 1127 sfurman
 
138 1748 jeremybenn
  /* Parse command-line parameters
139
     Command line looks like name1=value1,name2,name3=value3,... */
140
  while ((param_name = strtok ((char *) input, ",")))
141
    {
142 1127 sfurman
 
143 1748 jeremybenn
      input = NULL;
144 1127 sfurman
 
145 1748 jeremybenn
      /* 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 1127 sfurman
 
153 1748 jeremybenn
      if (!strcmp (param_name, "baud") && param_value)
154
        {
155
          baud = parse_baud (param_value);
156
          if (baud == B0)
157
            {
158
              goto error;
159
            }
160 1127 sfurman
        }
161 1748 jeremybenn
      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 1127 sfurman
 
173 1748 jeremybenn
  fd = open (device, O_RDWR);
174
  if (fd < 0)
175
    goto error;
176 1127 sfurman
 
177 1748 jeremybenn
  /* Get the current options for the port... */
178
  if (tcgetattr (fd, &options) < 0)
179
    goto error;
180 1127 sfurman
 
181 1748 jeremybenn
  /* Set the serial baud rate */
182
  cfsetispeed (&options, baud);
183
  cfsetospeed (&options, baud);
184 1127 sfurman
 
185 1748 jeremybenn
  /* Enable the receiver and set local mode... */
186 1222 phoenix
 
187 1748 jeremybenn
  /* 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 1127 sfurman
 
198 1748 jeremybenn
  options.c_cflag |= (CLOCAL | CREAD);
199 1154 sfurman
 
200 1127 sfurman
 
201 1748 jeremybenn
  /* 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 1127 sfurman
error:
210 1748 jeremybenn
  if (fd > 0)
211
    close (fd);
212
  free (channel);
213
  if (input)
214
    free ((void *) input);
215
  return NULL;
216 1127 sfurman
}
217
 
218 1748 jeremybenn
static int
219
tty_open (void *data)
220 1127 sfurman
{
221 1748 jeremybenn
  return 0;
222 1127 sfurman
}

powered by: WebSVN 2.1.0

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