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

Subversion Repositories s6soc

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

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 45 dgisselq
FILE    *dbgfp = stderr;
56
 
57
DEPPI::DEPPI(const char *szSel) {
58
        if ((!szSel)||(szSel[0] == '\0')) {
59
                // Number of digilent devcies on a system
60
                int     pcdvc;
61
 
62
                // Go fish and try to find the device
63
                DmgrEnumDevices(&pcdvc);
64
 
65
                if (pcdvc < 0) {
66
                        depperr();
67
                        exit(EXIT_FAILURE);
68
                }
69
 
70
                //
71
                int     found = 0; // Number of devices found mtg our criteria
72
                DVC     dvcinfo; // A structure to receive device info
73
                int     foundid=-1; // The id number of the device we found
74
 
75
                //
76
                for(int devid=0; devid < pcdvc; devid++) {
77
                        DmgrGetDvc(devid, &dvcinfo);
78
                        // fprintf(dbgfp, "DEVICE NAME: %s\n", dvcinfo.szName);
79
                        if (strcmp(dvcinfo.szName, "CmodS6")==0) {
80
                                found++;
81
                                // fprintf(dbgfp, "Found a CMOD!\n");
82
                                foundid = devid;
83
                        }
84
                }
85
 
86
                if (found == 0) {
87
                        fprintf(stderr, "No CModS6 devices found\n");
88
                        exit(EXIT_FAILURE);
89
                } else if (found > 1) {
90
                        fprintf(stderr, "More than one CModS6 device found.  Please consider opening your\n");
91
                        fprintf(stderr, "device with a valid serial number instead.\n");
92
                        exit(EXIT_FAILURE);
93
                }
94
 
95
                DmgrGetDvc(foundid, &dvcinfo);
96
                if (!DmgrOpen(&m_dev, dvcinfo.szConn)) {
97
                        fprintf(stderr, "Could not open device!\n");
98
                        depperr();
99
                        exit(EXIT_FAILURE);
100
                }
101
 
102
                //
103
                DmgrFreeDvcEnum();
104
        } else if (!DmgrOpen(&m_dev, (char *)szSel)) {
105
                // We know the device serial number, so go open that particular
106
                // device
107
                fprintf(stderr, "Named device open (DmgrOpen) failed!\n");
108
                depperr();
109 11 dgisselq
                exit(EXIT_FAILURE);
110
        }
111
 
112
        if (!DeppEnable(m_dev)) {
113 45 dgisselq
                fprintf(stderr, "Could not enable DEPP interface to (opened) device\n");
114
 
115
                depperr();
116 11 dgisselq
                exit(EXIT_FAILURE);
117
        }
118
 
119
        m_int = false, m_err = false;
120
 
121
        // fprintf(stdout, "Flushing **************\n");
122
        flush_read();
123
        // fprintf(stdout, "Flushed! **************\n");
124
}
125
 
126
DEPPI::~DEPPI(void) {
127 52 dgisselq
        DEPPI::close();
128 11 dgisselq
}
129
 
130
void    DEPPI::close(void) {
131
        if (m_dev)
132
                DmgrClose(m_dev);
133
        m_dev = 0;
134 52 dgisselq
        LLCOMMSI::close();
135 11 dgisselq
}
136
 
137
void    DEPPI::depperr(void) {
138
        ERC     erc = DmgrGetLastError();
139
        if(erc != ercNoErc) {
140 45 dgisselq
                char scode[cchErcMax], smsg[cchErcMsgMax];
141
                DmgrSzFromErc(erc, scode, smsg);
142
                fprintf(stderr, "ErrCode(%d): %s\n", erc, scode);
143
                fprintf(stderr, "ErrMessage: %s\n", smsg);
144
 
145
                if (erc == ercCapabilityConflict) {
146
                        fprintf(stderr, "Do you have the hardware manager in Vivado open?\n");
147
                        fprintf(stderr, "That could cause this conflict.\n");
148
                }
149 11 dgisselq
                close();
150
                exit(EXIT_FAILURE);
151
        }
152
}
153
 
154
void    DEPPI::write(char *buf, int len) {
155
        bool    good = true;
156 45 dgisselq
        const bool      dbg = false;
157 11 dgisselq
 
158 45 dgisselq
        if (dbg) {
159 11 dgisselq
                // Debug code--write one at a time
160
                fputs("WR: ", stdout);
161
                for(int i=0; i<len; i++) {
162
                        good = good && DeppPutReg(m_dev, 0, (unsigned char)buf[i], false);
163
                        fputc(buf[i], stdout);
164
                } fputc('\n', stdout);
165
        } else
166
                good = DeppPutRegRepeat(m_dev, 0, (unsigned char *)buf, len, false);
167
        if (!good)
168
                depperr();
169
}
170
 
171
int     DEPPI::read(char *buf, int len) {
172
        return read(buf, len, 4);
173
}
174
 
175
int     DEPPI::read(char *buf, int len, int timeout_ms) {
176
        int     left = len, nr=0;
177
        struct  timespec        now, later;
178 45 dgisselq
        const   bool    dbg = false;
179 11 dgisselq
 
180
        clock_gettime(CLOCK_MONOTONIC, &now);
181
 
182 45 dgisselq
        if (dbg) fprintf(dbgfp, "USBI::read(%d) (FIFO is %d-%d)\n", len, m_rend, m_rbeg);
183 11 dgisselq
        nr = pop_fifo(buf, left);
184
        left -= nr;
185
 
186
        while(left > 0) {
187
                raw_read(left, timeout_ms);
188
                nr = pop_fifo(&buf[len-left], left);
189
                left -= nr;
190
 
191 45 dgisselq
                if (dbg) fprintf(dbgfp, "\tWHILE (nr = %d, LEFT = %d, len=%d)\n", nr, left, len);
192 11 dgisselq
                if (nr == 0)
193
                        break;
194
#define TIMEOUT
195
#ifdef  TIMEOUT
196
                if (timeout_ms == 0)
197
                        break;
198
                else if (timeout_ms > 0) {
199
                        clock_gettime(CLOCK_MONOTONIC, &later);
200
 
201
                        long    num_ns = later.tv_nsec - now.tv_nsec, num_ms;
202
                        if (num_ns < 0) {
203
                                num_ns += 1000000000;
204
                                later.tv_sec--;
205
                        } num_ms = num_ns / 1000000;
206
                        if (later.tv_sec > now.tv_sec)
207
                                num_ms += (later.tv_sec - now.tv_sec)*1000;
208
 
209
                        if (num_ms > timeout_ms)
210
                                break;
211
                }
212
#endif
213
        }
214
 
215 45 dgisselq
        if(dbg) fprintf(dbgfp, "READ %d characters (%d req, %d left)\n", len-left, len, left);
216 11 dgisselq
        return len-left;
217
}
218
 
219
void    DEPPI::raw_read(const int clen, int timeout_ms) {
220
        int     empty = RCV_BUFMASK - ((m_rbeg - m_rend)&(RCV_BUFMASK));
221
        int     len = clen;
222
        bool    good = true;
223 45 dgisselq
        const   bool    dbg = false;
224 11 dgisselq
 
225 45 dgisselq
 
226
        if (dbg) fprintf(dbgfp, "DEPPI::raw_read(len=%d)\n", clen);
227 11 dgisselq
        if (len > empty)
228
                len = empty;
229
        if (len > 0) {
230
                // Fill the tail of our buffer
231
                int ln = len;
232
                if (ln > PKTLEN)
233
                        ln = PKTLEN;
234
 
235
                // fprintf(stdout, "RAW-READ(%d)\n", ln);
236
                if (false) {
237
                        // Debug code--read one word at a time
238
                        for(int i=0; i<ln; i++) {
239
                                good = good && DeppGetReg(m_dev, 0, (unsigned char *)&m_rxbuf[i], false);
240
                                usleep(1);
241
                        }
242
                } else
243
                        good = good && DeppGetRegRepeat(m_dev, 0, (unsigned char *)m_rxbuf, ln, false);
244 45 dgisselq
                if(dbg) fprintf(dbgfp, "DEPP: Pushing to FIFO\n");
245 11 dgisselq
                push_fifo(m_rxbuf, ln);
246
                len -= ln;
247
        }
248
 
249
        if (!good)
250
                depperr();
251
}
252
 
253
void    DEPPI::flush_read(void) {
254 45 dgisselq
        const   bool    dbg = false;
255
 
256
        if (dbg)        fprintf(dbgfp, "DEPPI::FLUSH-READ()\n");
257
 
258
        do {
259 11 dgisselq
                m_rbeg = m_rend = 0;
260 45 dgisselq
        } while(poll(4));
261
 
262
        if (dbg)        fprintf(dbgfp, "DEPPI::FLUSH-READ() -- COMPLETE\n");
263 11 dgisselq
}
264
 
265
void    DEPPI::push_fifo(char *buf, int len) {
266
        char    last = 0;
267
        char    *sptr = buf;
268 45 dgisselq
        const   bool    dbg = false;
269 11 dgisselq
 
270 45 dgisselq
        if (dbg)  fprintf(dbgfp, "DEPP::PUSH(%d)\n", len);
271 11 dgisselq
 
272
        if (m_rbeg != m_rend)
273
                last = m_rbuf[(m_rbeg-1)&RCV_BUFMASK];
274 45 dgisselq
        if (dbg)        fprintf(dbgfp, "DEPPI::PUSH() last=%d, rbeg=%d, rend=%d\n", last, m_rbeg, m_rend);
275 11 dgisselq
        for(int i=0; i<len; i++) {
276
                char v = *sptr++;
277
                if (((v & 0x80)||((unsigned char)v < 0x10))&&(v == last)) {
278
                        // Skipp any stuff bytes
279 45 dgisselq
                        if (dbg)  fprintf(dbgfp, "SKIPPING-1: %02x\n", v & 0x0ff);
280 11 dgisselq
                } else if ((unsigned char)v == 0x0ff) {
281
                        // Skipp any not-yet-ready bytes
282 45 dgisselq
                        if (dbg)  fprintf(dbgfp, "SKIPPING-2: %02x\n", 0x0ff);
283 11 dgisselq
                } else {
284
                        m_rbuf[m_rbeg] = v;
285 45 dgisselq
                        if (dbg) fprintf(dbgfp, "PUSHING: 0x%02x \'%c\'\n",
286
                                v&0x0ff, isprint(v)?v:'.');
287 11 dgisselq
                        m_rbeg = (m_rbeg+1)&(RCV_BUFMASK);
288
                } last = v;
289
        }
290
}
291
 
292
int     DEPPI::pop_fifo(char *buf, int len) {
293
        int     avail = (m_rbeg - m_rend)&(RCV_BUFMASK);
294
        int     left = len;
295
        int     nr = 0;
296 45 dgisselq
        const   bool    dbg = false;
297 11 dgisselq
 
298 45 dgisselq
        if (dbg) fprintf(dbgfp, "Attempting to pop %d items from FIFO (%d - %d)\n",
299
                        len, m_rend, m_rbeg);
300 11 dgisselq
        while((avail > 0)&&(left > 0)) {
301
                int ln = RCV_BUFLEN-m_rend;
302
                if (ln > left)
303
                        ln = left;
304
                if (ln > avail)
305
                        ln = avail;
306
                memcpy(&buf[len-left], &m_rbuf[m_rend], ln);
307
                left   -= ln;
308
                avail  -= ln;
309
                m_rend  = (m_rend + ln)&(RCV_BUFMASK);
310
                nr     += ln;
311
 
312
        }
313
 
314
        return nr;
315
}
316
 
317
bool    DEPPI::poll(unsigned ms) {
318
        int     avail = (m_rbeg-m_rend)&(RCV_BUFMASK);
319
        bool    r = true;
320 45 dgisselq
        const   bool    dbg = false;
321 11 dgisselq
 
322 45 dgisselq
        if (dbg) fprintf(dbgfp, "POLL\n");
323 11 dgisselq
        if ((avail < 2)&&((avail<1)||(m_rbuf[m_rend]&0x80)||(m_rbuf[m_rend]<0x10))) {
324 45 dgisselq
                if (dbg) fprintf(dbgfp, "POLL -- CALLS RAW READ\n");
325 11 dgisselq
                raw_read(4,ms);
326
                avail = (m_rbeg-m_rend)&(RCV_BUFMASK);
327
 
328
                if (avail != 0) {
329
                        // Read 'til there's nothing more to be read
330
                        char    v = (m_rbuf[(m_rbeg-1)&(RCV_BUFMASK)]);
331
                        while(((v&0x80)==0)&&((unsigned)v>=0x10)&&(avail < RCV_BUFMASK-32)) {
332
                                raw_read(26,ms);
333
                                if (avail == ((m_rbeg-m_rend)&(RCV_BUFMASK)))
334
                                        break; // We didn't read anything more
335
                                avail = (m_rbeg-m_rend)&(RCV_BUFMASK);
336 45 dgisselq
                                if (dbg) fprintf(dbgfp, "POLL/LOOP -- %d available\n", avail);
337 11 dgisselq
                        }
338
                        if (avail < 1)
339
                                r = false;
340
                        else if ((avail==1)&&((m_rbuf[m_rend]&0x80)||(m_rbuf[m_rend]<0x10)))
341
                                r = false;
342
                } else r = false;
343
        }
344 45 dgisselq
        if (dbg) fprintf(dbgfp, "POLL -- is %s\n", (r)?"true":"false");
345 11 dgisselq
 
346
        return r;
347
}

powered by: WebSVN 2.1.0

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