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

Subversion Repositories s6soc

[/] [s6soc/] [trunk/] [sw/] [host/] [deppi.cpp] - Blame information for rev 21

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

Line No. Rev Author Line
1 11 dgisselq
////////////////////////////////////////////////////////////////////////////////
2
//
3
// Filename:    deppi.cpp
4
//
5
// Project:     CMod S6 System on a Chip, ZipCPU demonstration project
6
//
7
// Purpose:     Creates a DEPP interface pseudo-character device, similar to
8
//              what you might get from a serial port or other character device,
9
//      from the DEPP interface to a CMOD S6 board.
10
//
11
// Creator:     Dan Gisselquist, Ph.D.
12
//              Gisselquist Technology, LLC
13
//
14
////////////////////////////////////////////////////////////////////////////////
15
//
16
// Copyright (C) 2015-2016, Gisselquist Technology, LLC
17
//
18
// This program is free software (firmware): you can redistribute it and/or
19
// modify it under the terms of  the GNU General Public License as published
20
// by the Free Software Foundation, either version 3 of the License, or (at
21
// your option) any later version.
22
//
23
// This program is distributed in the hope that it will be useful, but WITHOUT
24
// ANY WARRANTY; without even the implied warranty of MERCHANTIBILITY or
25
// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
26
// for more details.
27
//
28
// You should have received a copy of the GNU General Public License along
29
// with this program.  (It's in the $(ROOT)/doc directory, run make with no
30
// target there if the PDF file isn't present.)  If not, see
31
// <http://www.gnu.org/licenses/> for a copy.
32
//
33
// License:     GPL, v3, as defined and found on www.gnu.org,
34
//              http://www.gnu.org/licenses/gpl.html
35
//
36
//
37
////////////////////////////////////////////////////////////////////////////////
38
//
39
//
40
#include <stdio.h>
41
#include <stdlib.h>
42
#include <unistd.h>
43
#include <string.h>
44
#include <ctype.h>
45
#include <time.h>
46
// From Digilent's Adept Library
47
#include "dpcdecl.h"
48
#include "dmgr.h"
49
#include "depp.h"
50
 
51
// From my own library
52
#include "llcomms.h"
53
#include "deppi.h"
54
 
55
DEPPI::DEPPI(char *szSel) {
56
        if (!DmgrOpen(&m_dev, szSel)) {
57
                fprintf(stderr, "Open failed!\n");
58
                exit(EXIT_FAILURE);
59
        }
60
 
61
        if (!DeppEnable(m_dev)) {
62
                fprintf(stderr, "Could not enable DEPP interface\n");
63
                exit(EXIT_FAILURE);
64
        }
65
 
66
        m_int = false, m_err = false;
67
 
68
        // fprintf(stdout, "Flushing **************\n");
69
        flush_read();
70
        // fprintf(stdout, "Flushed! **************\n");
71
}
72
 
73
DEPPI::~DEPPI(void) {
74
        close();
75
}
76
 
77
void    DEPPI::close(void) {
78
        if (m_dev)
79
                DmgrClose(m_dev);
80
        m_dev = 0;
81
}
82
 
83
void    DEPPI::depperr(void) {
84
        ERC     erc = DmgrGetLastError();
85
        if(erc != ercNoErc) {
86
                char scode[cchErcMax], msg[cchErcMsgMax];
87
                DmgrSzFromErc(erc, scode, msg);
88
                fprintf(stderr, "ErrCode   : %s\n", scode);
89
                fprintf(stderr, "ErrMessage: %s\n", msg);
90
                close();
91
                exit(EXIT_FAILURE);
92
        }
93
}
94
 
95
void    DEPPI::write(char *buf, int len) {
96
        bool    good = true;
97
 
98
        if (false) {
99
                // Debug code--write one at a time
100
                fputs("WR: ", stdout);
101
                for(int i=0; i<len; i++) {
102
                        good = good && DeppPutReg(m_dev, 0, (unsigned char)buf[i], false);
103
                        fputc(buf[i], stdout);
104
                } fputc('\n', stdout);
105
        } else
106
                good = DeppPutRegRepeat(m_dev, 0, (unsigned char *)buf, len, false);
107
        if (!good)
108
                depperr();
109
}
110
 
111
int     DEPPI::read(char *buf, int len) {
112
        return read(buf, len, 4);
113
}
114
 
115
int     DEPPI::read(char *buf, int len, int timeout_ms) {
116
        int     left = len, nr=0;
117
        struct  timespec        now, later;
118
 
119
        clock_gettime(CLOCK_MONOTONIC, &now);
120
 
121
        // printf("USBI::read(%d) (FIFO is %d-%d)\n", len, m_rend, m_rbeg);
122
        nr = pop_fifo(buf, left);
123
        left -= nr;
124
 
125
        while(left > 0) {
126
                raw_read(left, timeout_ms);
127
                nr = pop_fifo(&buf[len-left], left);
128
                left -= nr;
129
 
130
                // printf("\tWHILE (nr = %d, LEFT = %d, len=%d)\n", nr, left, len);
131
                if (nr == 0)
132
                        break;
133
#define TIMEOUT
134
#ifdef  TIMEOUT
135
                if (timeout_ms == 0)
136
                        break;
137
                else if (timeout_ms > 0) {
138
                        clock_gettime(CLOCK_MONOTONIC, &later);
139
 
140
                        long    num_ns = later.tv_nsec - now.tv_nsec, num_ms;
141
                        if (num_ns < 0) {
142
                                num_ns += 1000000000;
143
                                later.tv_sec--;
144
                        } num_ms = num_ns / 1000000;
145
                        if (later.tv_sec > now.tv_sec)
146
                                num_ms += (later.tv_sec - now.tv_sec)*1000;
147
 
148
                        if (num_ms > timeout_ms)
149
                                break;
150
                }
151
#endif
152
        }
153
 
154
        // printf("READ %d characters (%d req, %d left)\n", len-left, len, left);
155
        return len-left;
156
}
157
 
158
void    DEPPI::raw_read(const int clen, int timeout_ms) {
159
        int     empty = RCV_BUFMASK - ((m_rbeg - m_rend)&(RCV_BUFMASK));
160
        int     len = clen;
161
        bool    good = true;
162
 
163
        if (len > empty)
164
                len = empty;
165
        if (len > 0) {
166
                // Fill the tail of our buffer
167
                int ln = len;
168
                if (ln > PKTLEN)
169
                        ln = PKTLEN;
170
 
171
                // fprintf(stdout, "RAW-READ(%d)\n", ln);
172
                if (false) {
173
                        // Debug code--read one word at a time
174
                        for(int i=0; i<ln; i++) {
175
                                good = good && DeppGetReg(m_dev, 0, (unsigned char *)&m_rxbuf[i], false);
176
                                usleep(1);
177
                        }
178
                } else
179
                        good = good && DeppGetRegRepeat(m_dev, 0, (unsigned char *)m_rxbuf, ln, false);
180
                // fprintf(stdout, "Pushing to FIFO\n");
181
                push_fifo(m_rxbuf, ln);
182
                len -= ln;
183
        }
184
 
185
        if (!good)
186
                depperr();
187
}
188
 
189
void    DEPPI::flush_read(void) {
190
        while(poll(4)) {
191
                m_rbeg = m_rend = 0;
192
        }
193
}
194
 
195
void    DEPPI::push_fifo(char *buf, int len) {
196
        char    last = 0;
197
        char    *sptr = buf;
198
 
199
        // fprintf(stdout, "PUSH(%d)\n", len);
200
 
201
        if (m_rbeg != m_rend)
202
                last = m_rbuf[(m_rbeg-1)&RCV_BUFMASK];
203
        for(int i=0; i<len; i++) {
204
                char v = *sptr++;
205
                if (((v & 0x80)||((unsigned char)v < 0x10))&&(v == last)) {
206
                        // Skipp any stuff bytes
207
                        // fprintf(stderr, "SKIPPING-1: %02x\n", v & 0x0ff);
208
                } else if ((unsigned char)v == 0x0ff) {
209
                        // Skipp any not-yet-ready bytes
210
                        // fprintf(stdout, "SKIPPING-2: %02x\n", 0x0ff);
211
                } else {
212
                        m_rbuf[m_rbeg] = v;
213
                        // fprintf(stdout, "PUSHING: %02x %c\n", v&0x0ff,
214
                        //      isprint(v)?v:'.');
215
                        m_rbeg = (m_rbeg+1)&(RCV_BUFMASK);
216
                } last = v;
217
        }
218
}
219
 
220
int     DEPPI::pop_fifo(char *buf, int len) {
221
        int     avail = (m_rbeg - m_rend)&(RCV_BUFMASK);
222
        int     left = len;
223
        int     nr = 0;
224
 
225
        // printf("Attempting to pop %d items from FIFO (%d - %d)\n",
226
        //              len, m_rend, m_rbeg);
227
        while((avail > 0)&&(left > 0)) {
228
                int ln = RCV_BUFLEN-m_rend;
229
                if (ln > left)
230
                        ln = left;
231
                if (ln > avail)
232
                        ln = avail;
233
                memcpy(&buf[len-left], &m_rbuf[m_rend], ln);
234
                left   -= ln;
235
                avail  -= ln;
236
                m_rend  = (m_rend + ln)&(RCV_BUFMASK);
237
                nr     += ln;
238
 
239
        }
240
 
241
        return nr;
242
}
243
 
244
bool    DEPPI::poll(unsigned ms) {
245
        int     avail = (m_rbeg-m_rend)&(RCV_BUFMASK);
246
        bool    r = true;
247
 
248
        // printf("POLL\n");
249
        if ((avail < 2)&&((avail<1)||(m_rbuf[m_rend]&0x80)||(m_rbuf[m_rend]<0x10))) {
250
                // printf("POLL -- CALLS RAW READ\n");
251
                raw_read(4,ms);
252
                avail = (m_rbeg-m_rend)&(RCV_BUFMASK);
253
 
254
                if (avail != 0) {
255
                        // Read 'til there's nothing more to be read
256
                        char    v = (m_rbuf[(m_rbeg-1)&(RCV_BUFMASK)]);
257
                        while(((v&0x80)==0)&&((unsigned)v>=0x10)&&(avail < RCV_BUFMASK-32)) {
258
                                raw_read(26,ms);
259
                                if (avail == ((m_rbeg-m_rend)&(RCV_BUFMASK)))
260
                                        break; // We didn't read anything more
261
                                avail = (m_rbeg-m_rend)&(RCV_BUFMASK);
262
                                // printf("POLL/LOOP -- %d available\n", avail);
263
                        }
264
                        if (avail < 1)
265
                                r = false;
266
                        else if ((avail==1)&&((m_rbuf[m_rend]&0x80)||(m_rbuf[m_rend]<0x10)))
267
                                r = false;
268
                } else r = false;
269
        }
270
        // printf("POLL -- is %s\n", (r)?"true":"false");
271
 
272
        return r;
273
}

powered by: WebSVN 2.1.0

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