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

Subversion Repositories w11

[/] [w11/] [tags/] [w11a_V0.5/] [rtl/] [vlib/] [rri/] [tb/] [cext_rriext.c] - Blame information for rev 37

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

Line No. Rev Author Line
1 2 wfjm
/* $Id: cext_rriext.c 314 2010-07-09 17:38:41Z mueller $
2
 *
3
 * Copyright 2007- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
4
 *
5
 * This program is free software; you may redistribute and/or modify it under
6
 * the terms of the GNU General Public License as published by the Free
7
 * Software Foundation, either version 2, or at your option any later version.
8
 *
9
 * This program is distributed in the hope that it will be useful, but
10
 * WITHOUT ANY WARRANTY, without even the implied warranty of MERCHANTABILITY
11
 * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12
 * for complete details.
13
 *
14
 *  Revision History:
15
 * Date         Rev  Vers    Comment
16
 * 2007-11-18    96   1.2    add 'read before write' logic to avoid deadlocks
17
 *                           under cygwin broken fifo (size=1 !) implementation
18
 * 2007-10-19    90   1.1    add trace option, controlled by setting an
19
 *                           the environment variable CEXT_RRIEXT_TRACE=1
20
 * 2007-09-23    84   1.0    Initial version
21
 */
22
 
23
#include <unistd.h>
24
#include <errno.h>
25
#include <sys/types.h>
26
#include <sys/stat.h>
27
#include <fcntl.h>
28
#include <stdio.h>
29
#include <sched.h>
30
#include <stdlib.h>
31
#include <string.h>
32
 
33
#define CPREF 0x80
34
#define CESC  (CPREF|0x0f)
35
#define QRBUFSIZE 1024
36
 
37
static int fd_rx = -1;
38
static int fd_tx = -1;
39
 
40
static int io_trace = 0;
41
 
42
static char qr_buf[QRBUFSIZE];
43
static int  qr_pr  = 0;
44
static int  qr_pw  = 0;
45
static int  qr_nb  = 0;
46
static int  qr_eof = 0;
47
static int  qr_err = EAGAIN;
48
 
49
/* returns:
50
 *   <0          if error
51
 *   >=0 <=0xff  normal data
52
 *   == 0x100    idle
53
 *   0x1aahhll   if side band message seen
54
 *
55
 */
56
 
57
/* returns
58
 
59
 */
60
 
61
static void cext_dotrace(const char *text, int dat)
62
{
63
  int i;
64
  int mask = 0x80;
65
  printf("cext_rriext-I: %s   ", text);
66
  for (i=0; i<8; i++) {
67
    printf("%c", (dat&mask)?'1':'0' );
68
    mask >>= 1;
69
  }
70
  printf("\n");
71
}
72
 
73
static void cext_doread()
74
{
75
  char buf[1];
76
  ssize_t nbyte;
77
  nbyte = read(fd_rx, buf, 1);
78
  if (nbyte < 0) {
79
    qr_err = errno;
80
  } else if (nbyte == 0) {
81
    qr_err = EAGAIN;
82
    qr_eof = 1;
83
  } else {
84
    qr_err = EAGAIN;
85
    if (qr_nb < QRBUFSIZE) {
86
      if (io_trace) cext_dotrace("rcv8", (unsigned char) buf[0]);
87
      qr_buf[qr_pw++] = buf[0];
88
      if (qr_pw >= QRBUFSIZE) qr_pw = 0;
89
      qr_nb += 1;
90
    } else {
91
      printf("Buffer overflow\n"); /* FIXME: better error handling */
92
    }
93
  }
94
}
95
 
96
int cext_getbyte(int clk)
97
{
98
  char buf[1];
99
  ssize_t nbyte;
100
  int irc;
101
  int tdat;
102
  char* env_val;
103
 
104
  static int odat;
105
  static int nidle = 0;
106
  static int ncesc = 0;
107
  static int nside = -1;
108
 
109
  if (fd_rx < 0) {               /* fifo's not yet opened */
110
    fd_rx = open("tb_rriext_fifo_rx", O_RDONLY|O_NONBLOCK);
111
    if (fd_rx <= 0) {
112
      perror("cext_rriext-E: failed to open tb_rriext_fifo_rx");
113
      return -2;
114
    }
115
    printf("cext_rriext-I: connected to tb_rriext_fifo_rx\n");
116
    fd_tx = open("tb_rriext_fifo_tx", O_WRONLY);
117
    if (fd_tx <= 0) {
118
      perror("cext_rriext-E: failed to open tb_rriext_fifo_tx");
119
      return -2;
120
    }
121
    printf("cext_rriext-I: connected to tb_rriext_fifo_tx\n");
122
    nidle = 0;
123
    ncesc = 0;
124
    nside = -1;
125
 
126
    io_trace = 0;
127
    env_val = getenv("CEXT_RRIEXT_TRACE");
128
    if (env_val && strcmp(env_val, "1") == 0) {
129
      io_trace = 1;
130
    }
131
 
132
  }
133
 
134
  cext_doread();
135
 
136
  if (qr_nb == 0) {                          /* no character to be processed */
137
    if (qr_eof != 0) {                       /* EOF seen */
138
      if (ncesc >= 2) {                     /*  two+ CESC seen  ? */
139
        printf("cext_rriext-I: seen EOF, wait for reconnect\n");
140
        close(fd_rx);
141
        close(fd_tx);
142
        fd_rx = -1;
143
        fd_tx = -1;
144
        usleep(500000);                     /* wait 0.5 sec */
145
        return 0x100;                       /* return idle, will reconnect */
146
      }
147
 
148
      printf("cext_rriext-I: seen EOF, schedule clock stop and exit\n");
149
      return -1;                            /* signal EOF seen */
150
    } else if (qr_err == EAGAIN) {          /* nothing read, return idle */
151
      if (nidle < 8 || (nidle%1024)==0) {
152
        irc = sched_yield();
153
        if (irc < 0) perror("cext_rriext-W: sched_yield failed");
154
      }
155
      nidle += 1;
156
      return 0x100;
157
    } else {                                /* must be a read error */
158
      errno = qr_err;
159
      perror("cext_rriext-E: read error on tb_rriext_fifo_rx");
160
      return -3;
161
    }
162
  }
163
 
164
  nidle = 0;
165
  tdat = (unsigned char) qr_buf[qr_pr++];
166
  if (qr_pr >= QRBUFSIZE) qr_pr = 0;
167
  qr_nb -= 1;
168
 
169
  if (tdat == CESC) {
170
    ncesc += 1;
171
    if (ncesc == 2) nside = 0;
172
  } else {
173
    ncesc = 0;
174
  }
175
 
176
  switch (nside) {
177
  case -1:                                  /* normal data */
178
    return tdat;
179
  case 0:                                    /* 2nd CESC, return it */
180
    nside += 1;
181
    return tdat;
182
  case 1:                                   /* get ADDR byte */
183
    nside += 1;
184
    odat = 0x1000000 | (tdat<<16);
185
    return 0x100;
186
  case 2:                                   /* get DL byte */
187
    nside += 1;
188
    odat |= tdat;
189
    return 0x100;
190
  case 3:                                   /* get DH byte */
191
    nside = -1;
192
    odat |= tdat<<8;
193
    return odat;
194
  }
195
}
196
 
197
int cext_putbyte(int dat)
198
{
199
  char buf[1];
200
  ssize_t nbyte;
201
 
202
  cext_doread();
203
 
204
  if (io_trace) cext_dotrace("snd8", dat);
205
 
206
  buf[0] = (unsigned char) dat;
207
  nbyte = write(fd_tx, buf, 1);
208
 
209
  if (nbyte < 0) {
210
    perror("cext_rriext-E: write error on tb_rriext_fifo_tx");
211
    return -3;
212
  }
213
 
214
  return 0;
215
}

powered by: WebSVN 2.1.0

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