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

Subversion Repositories or1k

[/] [or1k/] [branches/] [stable_0_1_x/] [or1ksim/] [peripheral/] [channels/] [tty.c] - Blame information for rev 1768

Go to most recent revision | 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
 
6
This file is part of OpenRISC 1000 Architectural Simulator.
7
 
8
This program is free software; you can redistribute it and/or modify
9
it under the terms of the GNU General Public License as published by
10
the Free Software Foundation; either version 2 of the License, or
11
(at your option) any later version.
12
 
13
This program is distributed in the hope that it will be useful,
14
but WITHOUT ANY WARRANTY; without even the implied warranty of
15
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
GNU General Public License for more details.
17
 
18
You should have received a copy of the GNU General Public License
19
along with this program; if not, write to the Free Software
20
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
21
 
22
#include <stdio.h>
23
#include <termios.h>
24
#include <unistd.h>
25
#include <string.h>
26 1128 sfurman
#include <fcntl.h>
27 1308 phoenix
#include <stdlib.h>
28 1127 sfurman
 
29
#include "channel.h"
30
#include "generic.h"
31
#include "fd.h"
32
 
33
// Default parameters if not specified in config file
34
#define DEFAULT_BAUD B19200
35
#define DEFAULT_TTY_DEVICE "/dev/ttyS0"
36
 
37
struct tty_channel
38
{
39
    struct fd_channel fds;
40
};
41
 
42
static struct {
43
        char* name;
44
        int value;
45
} baud_table[] = {
46
        {"50", B50},
47
        {"2400",   B2400},
48
        {"4800",   B4800},
49
        {"9600",   B9600},
50
        {"19200",  B19200},
51
        {"38400",  B38400},
52
        {"115200", B115200},
53
        {"230400", B230400},
54
        {0,        0}
55
};
56
 
57
// Convert baud rate string to termio baud rate constant
58
int
59
parse_baud(char* baud_string)
60
{
61
        int i;
62
        for (i = 0; baud_table[i].name; i++) {
63
                if (!strcmp(baud_table[i].name, baud_string))
64
                        return baud_table[i].value;
65
        }
66
 
67
        fprintf(stderr, "Error: unknown baud rate: %s\n", baud_string);
68
        fprintf(stderr, "       Known baud rates: ");
69
 
70
        for (i = 0; baud_table[i].name; i++) {
71
                fprintf(stderr, "%s%s", baud_table[i].name, baud_table[i+1].name ? ", " : "\n");
72
        }
73
        return B0;
74
}
75
 
76
static void * tty_init(const char * input)
77
{
78
        int fd, baud;
79
        char *param_name, *param_value, *device;
80
    struct termios options;
81
    struct tty_channel* channel;
82
 
83
        channel = (struct tty_channel*)malloc(sizeof(struct tty_channel));
84
    if (!channel)
85
                return NULL;
86
 
87
        // Make a copy of config string, because we're about to mutate it
88
        input = strdup(input);
89
        if (!input)
90
                goto error;
91
 
92
        baud = DEFAULT_BAUD;
93
        device = DEFAULT_TTY_DEVICE;
94
 
95
        // Parse command-line parameters
96
        // Command line looks like name1=value1,name2,name3=value3,...
97 1308 phoenix
        while ((param_name = strtok((char*)input, ","))) {
98 1127 sfurman
 
99
                input = NULL;
100
 
101
                // Parse a parameter's name and value
102
                param_value = strchr(param_name,'=');
103
                if (param_value != NULL) {
104
                        *param_value = '\0';
105
                        param_value++;          // Advance past '=' character
106
                }
107
 
108
                if (!strcmp(param_name, "baud") && param_value) {
109
                        baud = parse_baud(param_value);
110
                        if (baud == B0) {
111
                                goto error;
112
                        }
113
                } else if (!strcmp(param_name, "device")) {
114
                        device = param_value;
115
                } else {
116
                        fprintf(stderr, "error: unknown tty channel parameter \"%s\"\n", param_name);
117
                        goto error;
118
                }
119
        }
120
 
121 1128 sfurman
        fd = open(device, O_RDWR);
122 1127 sfurman
        if (fd < 0)
123
                goto error;
124
 
125
    // Get the current options for the port...
126
    if (tcgetattr(fd, &options) < 0)
127
                goto error;
128
 
129
    // Set the serial baud rate
130
    cfsetispeed(&options, baud);
131
    cfsetospeed(&options, baud);
132
 
133
    // Enable the receiver and set local mode...
134 1222 phoenix
 
135
    /* cfmakeraw(&options);
136
     *
137
     * cygwin lacks cfmakeraw(), just do it explicitly
138
     */
139
    options.c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP
140
                               |INLCR|IGNCR|ICRNL|IXON);
141
    options.c_oflag &= ~OPOST;
142
    options.c_lflag &= ~(ECHO|ECHONL|ICANON|ISIG|IEXTEN);
143
    options.c_cflag &= ~(CSIZE|PARENB);
144
    options.c_cflag |= CS8;
145
 
146 1127 sfurman
    options.c_cflag |= (CLOCAL | CREAD);
147
 
148 1154 sfurman
 
149 1127 sfurman
    // Set the new options for the port...
150
    if (tcsetattr(fd, TCSANOW, &options) < 0)
151
                goto error;
152
 
153
    channel->fds.fdin = channel->fds.fdout = fd;
154 1308 phoenix
        free((void *)input);
155 1127 sfurman
    return channel;
156
 
157
error:
158
    if (fd > 0)
159
                close(fd);
160
    free(channel);
161
        if (input)
162 1308 phoenix
                free((void *)input);
163 1127 sfurman
    return NULL;
164
}
165
 
166
static int tty_open(void * data)
167
{
168
    return 0;
169
}
170
 
171
static int tty_read(void * data, char * buffer, int size)
172
{
173
    return fd_read(data, buffer, size);
174
}
175
 
176
static int tty_write(void * data, const char * buffer, int size)
177
{
178
    return fd_write(data, buffer, size);
179
}
180
 
181
struct channel_ops tty_channel_ops =
182
{
183
    init:   tty_init,
184
    open:   tty_open,
185
    close:  generic_close,
186
    read:   fd_read,
187
    write:  fd_write,
188
    free:   generic_free,
189
};
190
 
191
/*
192
 * Local variables:
193
 * c-file-style: "linux"
194
 * End:
195
 */
196
 

powered by: WebSVN 2.1.0

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