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

Subversion Repositories w11

[/] [w11/] [tags/] [w11a_V0.61/] [rtl/] [vlib/] [rlink/] [tb/] [rlink_cext.c] - Blame information for rev 26

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 25 wfjm
/* $Id: rlink_cext.c 575 2014-07-27 20:55:41Z mueller $
2 2 wfjm
 *
3 25 wfjm
 * Copyright 2007-2014 by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
4 2 wfjm
 *
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 25 wfjm
 * 2014-07-27   575   1.3.2  add ssize_t -> int casts to avoid warnings
17
 *                           add fflush(stdout) after standart open/close msgs
18 10 wfjm
 * 2011-03-05   366   1.3.1  add RLINK_CEXT_TRACE=2 trace level
19 9 wfjm
 * 2010-12-29   351   1.3    rename cext_rriext -> rlink_cext; rename functions
20
 *                           cext_* -> rlink_cext_* and fifo file names
21
 *                           tb_cext_* -> rlink_cext_*
22 2 wfjm
 * 2007-11-18    96   1.2    add 'read before write' logic to avoid deadlocks
23
 *                           under cygwin broken fifo (size=1 !) implementation
24
 * 2007-10-19    90   1.1    add trace option, controlled by setting an
25
 *                           the environment variable CEXT_RRIEXT_TRACE=1
26
 * 2007-09-23    84   1.0    Initial version
27
 */
28
 
29
#include <unistd.h>
30
#include <errno.h>
31
#include <sys/types.h>
32
#include <sys/stat.h>
33
#include <fcntl.h>
34
#include <stdio.h>
35
#include <sched.h>
36
#include <stdlib.h>
37
#include <string.h>
38
 
39
#define CPREF 0x80
40
#define CESC  (CPREF|0x0f)
41
#define QRBUFSIZE 1024
42
 
43
static int fd_rx = -1;
44
static int fd_tx = -1;
45
 
46
static int io_trace = 0;
47
 
48
static char qr_buf[QRBUFSIZE];
49
static int  qr_pr  = 0;
50
static int  qr_pw  = 0;
51
static int  qr_nb  = 0;
52
static int  qr_eof = 0;
53
static int  qr_err = EAGAIN;
54
 
55
/* returns:
56
 *   <0          if error
57
 *   >=0 <=0xff  normal data
58
 *   == 0x100    idle
59
 *   0x1aahhll   if side band message seen
60
 *
61
 */
62
 
63
/* returns
64
 
65
 */
66
 
67 9 wfjm
static void rlink_cext_dotrace(const char *text, int dat)
68 2 wfjm
{
69
  int i;
70
  int mask = 0x80;
71 9 wfjm
  printf("rlink_cext-I: %s   ", text);
72 2 wfjm
  for (i=0; i<8; i++) {
73
    printf("%c", (dat&mask)?'1':'0' );
74
    mask >>= 1;
75
  }
76
  printf("\n");
77
}
78
 
79 9 wfjm
static void rlink_cext_doread()
80 2 wfjm
{
81
  char buf[1];
82
  ssize_t nbyte;
83
  nbyte = read(fd_rx, buf, 1);
84 10 wfjm
  if (io_trace > 1) {
85 25 wfjm
    printf("rlink_cext-I: read   rc=%d", (int)nbyte);
86 10 wfjm
    if (nbyte < 0) printf(" errno=%d %s", errno, strerror(errno));
87
    printf("\n");
88
  }
89
 
90 2 wfjm
  if (nbyte < 0) {
91
    qr_err = errno;
92
  } else if (nbyte == 0) {
93
    qr_err = EAGAIN;
94
    qr_eof = 1;
95
  } else {
96
    qr_err = EAGAIN;
97
    if (qr_nb < QRBUFSIZE) {
98 9 wfjm
      if (io_trace) rlink_cext_dotrace("rcv8", (unsigned char) buf[0]);
99 2 wfjm
      qr_buf[qr_pw++] = buf[0];
100
      if (qr_pw >= QRBUFSIZE) qr_pw = 0;
101
      qr_nb += 1;
102
    } else {
103
      printf("Buffer overflow\n"); /* FIXME: better error handling */
104
    }
105
  }
106
}
107
 
108 9 wfjm
int rlink_cext_getbyte(int clk)
109 2 wfjm
{
110
  char buf[1];
111
  ssize_t nbyte;
112
  int irc;
113
  int tdat;
114
  char* env_val;
115
 
116
  static int odat;
117
  static int nidle = 0;
118
  static int ncesc = 0;
119
  static int nside = -1;
120
 
121
  if (fd_rx < 0) {               /* fifo's not yet opened */
122 9 wfjm
    fd_rx = open("rlink_cext_fifo_rx", O_RDONLY|O_NONBLOCK);
123 2 wfjm
    if (fd_rx <= 0) {
124 9 wfjm
      perror("rlink_cext-E: failed to open rlink_cext_fifo_rx");
125 2 wfjm
      return -2;
126
    }
127 9 wfjm
    printf("rlink_cext-I: connected to rlink_cext_fifo_rx\n");
128 25 wfjm
    fflush(stdout);
129
 
130 9 wfjm
    fd_tx = open("rlink_cext_fifo_tx", O_WRONLY);
131 2 wfjm
    if (fd_tx <= 0) {
132 9 wfjm
      perror("rlink_cext-E: failed to open rlink_cext_fifo_tx");
133 2 wfjm
      return -2;
134
    }
135 9 wfjm
    printf("rlink_cext-I: connected to rlink_cext_fifo_tx\n");
136 25 wfjm
    fflush(stdout);
137
 
138 2 wfjm
    nidle = 0;
139
    ncesc = 0;
140
    nside = -1;
141
 
142
    io_trace = 0;
143 9 wfjm
    env_val = getenv("RLINK_CEXT_TRACE");
144 10 wfjm
    if (env_val) {
145
      printf("rlink_cext-I: seen RLINK_CEXT_TRACE=%s\n", env_val);
146
      if (strcmp(env_val, "1") == 0) {
147
        printf("rlink_cext-I: set trace level to 1\n");
148
        io_trace = 1;
149
      } else if (strcmp(env_val, "2") == 0) {
150
        printf("rlink_cext-I: set trace level to 2\n");
151
        io_trace = 2;
152
      }
153 2 wfjm
    }
154
 
155
  }
156
 
157 9 wfjm
  rlink_cext_doread();
158 2 wfjm
 
159
  if (qr_nb == 0) {                          /* no character to be processed */
160
    if (qr_eof != 0) {                       /* EOF seen */
161
      if (ncesc >= 2) {                     /*  two+ CESC seen  ? */
162 9 wfjm
        printf("rlink_cext-I: seen EOF, wait for reconnect\n");
163 25 wfjm
        fflush(stdout);
164 2 wfjm
        close(fd_rx);
165
        close(fd_tx);
166
        fd_rx = -1;
167
        fd_tx = -1;
168
        usleep(500000);                     /* wait 0.5 sec */
169
        return 0x100;                       /* return idle, will reconnect */
170
      }
171
 
172 9 wfjm
      printf("rlink_cext-I: seen EOF, schedule clock stop and exit\n");
173 25 wfjm
      fflush(stdout);
174 2 wfjm
      return -1;                            /* signal EOF seen */
175 25 wfjm
 
176 2 wfjm
    } else if (qr_err == EAGAIN) {          /* nothing read, return idle */
177
      if (nidle < 8 || (nidle%1024)==0) {
178
        irc = sched_yield();
179 9 wfjm
        if (irc < 0) perror("rlink_cext-W: sched_yield failed");
180 2 wfjm
      }
181
      nidle += 1;
182
      return 0x100;
183
    } else {                                /* must be a read error */
184
      errno = qr_err;
185 9 wfjm
      perror("rlink_cext-E: read error on rlink_cext_fifo_rx");
186 2 wfjm
      return -3;
187
    }
188
  }
189
 
190
  nidle = 0;
191
  tdat = (unsigned char) qr_buf[qr_pr++];
192
  if (qr_pr >= QRBUFSIZE) qr_pr = 0;
193
  qr_nb -= 1;
194
 
195
  if (tdat == CESC) {
196
    ncesc += 1;
197
    if (ncesc == 2) nside = 0;
198
  } else {
199
    ncesc = 0;
200
  }
201
 
202
  switch (nside) {
203
  case -1:                                  /* normal data */
204
    return tdat;
205
  case 0:                                    /* 2nd CESC, return it */
206
    nside += 1;
207
    return tdat;
208
  case 1:                                   /* get ADDR byte */
209
    nside += 1;
210
    odat = 0x1000000 | (tdat<<16);
211
    return 0x100;
212
  case 2:                                   /* get DL byte */
213
    nside += 1;
214
    odat |= tdat;
215
    return 0x100;
216
  case 3:                                   /* get DH byte */
217
    nside = -1;
218
    odat |= tdat<<8;
219
    return odat;
220
  }
221
}
222
 
223 9 wfjm
int rlink_cext_putbyte(int dat)
224 2 wfjm
{
225
  char buf[1];
226
  ssize_t nbyte;
227
 
228 9 wfjm
  rlink_cext_doread();
229 2 wfjm
 
230 9 wfjm
  if (io_trace) rlink_cext_dotrace("snd8", dat);
231 2 wfjm
 
232
  buf[0] = (unsigned char) dat;
233
  nbyte = write(fd_tx, buf, 1);
234 10 wfjm
  if (io_trace > 1) {
235 25 wfjm
    printf("rlink_cext-I: write  rc=%d", (int)nbyte);
236 10 wfjm
    if (nbyte < 0) printf(" errno=%d %s", errno, strerror(errno));
237
    printf("\n");
238
  }
239 2 wfjm
 
240
  if (nbyte < 0) {
241 9 wfjm
    perror("rlink_cext-E: write error on rlink_cext_fifo_tx");
242 2 wfjm
    return -3;
243
  }
244
 
245
  return 0;
246
}

powered by: WebSVN 2.1.0

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