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

Subversion Repositories usb_fpga_2_14

[/] [usb_fpga_2_14/] [trunk/] [java/] [ztex/] [ZtexUsbReader.java] - Blame information for rev 2

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 ZTEX
/*%
2
   Java host software API of ZTEX SDK
3
   Copyright (C) 2009-2017 ZTEX GmbH.
4
   http://www.ztex.de
5
 
6
   This Source Code Form is subject to the terms of the Mozilla Public
7
   License, v. 2.0. If a copy of the MPL was not distributed with this file,
8
   You can obtain one at http://mozilla.org/MPL/2.0/.
9
 
10
   Alternatively, the contents of this file may be used under the terms
11
   of the GNU General Public License Version 3, as described below:
12
 
13
   This program is free software; you can redistribute it and/or modify
14
   it under the terms of the GNU General Public License version 3 as
15
   published by the Free Software Foundation.
16
 
17
   This program is distributed in the hope that it will be useful, but
18
   WITHOUT ANY WARRANTY; without even the implied warranty of
19
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20
   General Public License for more details.
21
 
22
   You should have received a copy of the GNU General Public License
23
   along with this program; if not, see http://www.gnu.org/licenses/.
24
%*/
25
 
26
package ztex;
27
 
28
import java.io.*;
29
import java.util.*;
30
import java.nio.*;
31
 
32
import org.usb4java.*;
33
 
34
/**
35
  * A helper class to implement asynchronous bulk and interrupt read transfers. This class also has a speed test mode.
36
  */
37
 
38
// *****************************************************************************
39
// ******* ZtexUsbReader *******************************************************
40
// *****************************************************************************
41
public class ZtexUsbReader {
42
    private Device dev;
43
    private DeviceHandle handle;
44
    private int ep;
45
    private boolean isInt;
46
    private int bufNum;
47
    private int bufSize;
48
 
49
    private ByteBuffer[] bufs;
50
    private Transfer[] transfers;
51
    private volatile boolean[] pending;
52
    private long getCount = 0;
53
    private volatile long byteCount = 0;
54
 
55
    private volatile boolean speedTest = false;
56
    private volatile long remaining;
57
 
58
    /*
59
     * Timeout for USB transfers in ms. Default value is 5000.
60
     */
61
    public int usbTimeOut = 5000;
62
 
63
    private final TransferCallback callback = new TransferCallback() {
64
        public void processTransfer(Transfer transfer) {
65
        byteCount += transfer.actualLength();
66
        // find index
67
        int i=0;
68
        while ( (i<bufNum) && (!transfer.equals(transfers[i])) ) i++;
69
        if ( i < bufNum ) {
70
            if ( speedTest ) {
71
                try {
72
                    submit(i);
73
                }
74
                catch (Exception e) {
75
                    System.err.println(e);
76
                }
77
            }
78
            else pending[i] = false;
79
        }
80
        else System.err.println("Internal error: unknown transfer");
81
        }
82
    };
83
 
84
 
85
// ******* ZtexUsbReader *******************************************************
86
/**
87
  * Creates the reader for a given USB device and endpoint number.
88
  * @param p_handle The device handle used for communication (must be opened).
89
  * @param p_ep The input endpoint.
90
  * @param p_isInt True if it is an interrupt transfer.
91
  * @param p_bufSize size of each buffer. Typical values are 64KByte to 512KByte
92
  * @param p_bufNum number of buffers. Recommended queue size is 2MByte to 8MByte.
93
  */
94
    public ZtexUsbReader ( DeviceHandle p_handle, int p_ep, boolean p_isInt, int p_bufNum, int p_bufSize ) {
95
        dev = LibUsb.getDevice(p_handle);
96
        handle = p_handle;
97
        ep = p_ep;
98
        isInt = p_isInt;
99
        bufNum = p_bufNum;
100
        bufSize = p_bufSize;
101
        bufs = new ByteBuffer[bufNum];
102
        transfers = new Transfer[bufNum];
103
        pending = new boolean[bufNum];
104
        for (int i=0; i<bufNum; i++) {
105
            bufs[i] = BufferUtils.allocateByteBuffer(bufSize);
106
            transfers[i] = null;
107
            pending[i] = false;
108
        }
109
    }
110
 
111
/**
112
  * Creates the reader from a given ZTEX device and endpoint number.
113
  * @param ztex The ZTEX device.
114
  * @param p_ep The number of the input endpoint
115
  * @param p_isInt True if it is an interrupt transfer.
116
  * @param p_bufSize size of each buffer. Typical values are 64KByte to 512KByte
117
  * @param p_bufNum number of buffer. Recommended queue size is 2MByte to 8MByte.
118
  */
119
    public ZtexUsbReader ( Ztex1 ztex, int p_ep, boolean p_isInt, int p_bufNum, int p_bufSize ) {
120
        this(ztex.handle(), 128 | p_ep, p_isInt, p_bufNum, p_bufSize);
121
    }
122
 
123
/**
124
  * Creates the reader for the input endpoint of the default interface of a ZTEX device.
125
  * @param ztex The ZTEX device.
126
  * @param p_bufSize size of each buffer. Typical values are 64KByte to 512KByte
127
  * @param p_bufNum number of buffer. Recommended queue size is 2MByte to 8MByte.
128
  * @throws InvalidFirmwareException if interface 1 is not supported.
129
  * @throws CapabilityException if default interface if not present or version number is lower than required
130
  * @throws UsbExcption if a communication error occurred.
131
  */
132
    public ZtexUsbReader ( Ztex1v1 ztex, int p_bufNum, int p_bufSize ) throws InvalidFirmwareException, UsbException, CapabilityException {
133
        this(ztex.handle(), ztex.defaultInEP(), false, p_bufNum, p_bufSize);
134
    }
135
 
136
// ******* submit **************************************************************
137
    private void submit(int i) throws UsbException {
138
        if ( transfers[i] == null ) return;
139
        if ( remaining <=0 ) {
140
            LibUsb.freeTransfer(transfers[i]);
141
            transfers[i] = null;
142
            return;
143
        }
144
        remaining--;
145
        int result = LibUsb.submitTransfer(transfers[i]);
146
        if ( (result!=LibUsb.SUCCESS) && (result!=LibUsb.ERROR_BUSY) ) throw new UsbException(dev, "Error submitting buffer " + i, result);
147
        pending[i] = true;
148
    }
149
 
150
// ******* getBuffer ***********************************************************
151
/**
152
  * Get the next buffer. This does not work in speed test mode, see see {@link #start(long)}.
153
  * @param buf The byte array where to store the data.
154
  * @param timeout Timeout in ms. If timeout occurs the function returns -1.
155
  * @return The number of bytes read or -1 if timeout occurs.
156
  * @throws UsbExecption if an error occurred.
157
  */
158
    public int getBuffer(byte[] buf, int timeout) throws UsbException {
159
        if ( speedTest ) throw new UsbException(dev, "Unable to get buffer: Device is in speed test mode");
160
        int j = (int)(getCount % bufNum);
161
        for (int i=0; pending[j] && (i<timeout); i++ ) {
162
            try { Thread.sleep(1); } catch ( InterruptedException e) { }
163
        }
164
        if ( pending[j] ) return -1;
165
        else if ( transfers[j] == null ) {
166
            getCount++;
167
            return 0;
168
        }
169
        else if ( transfers[j].status() != LibUsb.TRANSFER_COMPLETED ) throw new UsbException(dev, "Error receving buffer " + getCount + ": " + transfers[j].status());
170
 
171
        final int k = Math.min(transfers[j].actualLength(), buf.length);
172
        bufs[j].rewind();
173
        bufs[j].get(buf, 0, k);
174
        submit(j);
175
        getCount++;
176
        return k;
177
    }
178
 
179
// ******* transferStatus ******************************************************
180
/**
181
  * Return status of current transfer (see LibUsb.TRANSFER_*), -1 if transfer is pending or -2 if transfer has not been started.
182
  * @return Transfer status.
183
  */
184
    public int transferStatus() {
185
        int j = (int)(getCount % bufNum);
186
        return transfers[j] == null ? -2 : pending[j] ? -1 : transfers[j].status();
187
    }
188
 
189
// ******* byteCount ***********************************************************
190
/**
191
  * Return the number of bytes read since last {@link #start(long)}.
192
  * @return The number of bytes read since last {@link #start(long)}.
193
  */
194
    public long byteCount () {
195
        return byteCount;
196
    }
197
 
198
// ******* bufSize *************************************************************
199
/**
200
  * Return the buffer size.
201
  * @return The buffer size.
202
  */
203
    public int bufSize () {
204
        return bufSize;
205
    }
206
 
207
// ******* cancel **************************************************************
208
/**
209
  * Cancels all pending transfers, also see {@link #cancelWait(int)},
210
  * @throws UsbExecption if an error occurred.
211
  */
212
    public void cancel() throws UsbException {
213
        speedTest = false;
214
        remaining = 0;
215
        for (int i=0; i<bufNum; i++ ) {
216
            if ( (transfers[i] != null) && pending[i] ) {
217
                int result = LibUsb.cancelTransfer(transfers[i]);
218
                if ( (result!=LibUsb.SUCCESS) && (result!=LibUsb.ERROR_NOT_FOUND) ) throw new UsbException(dev, "Unable to cancel transfer", result);
219
            }
220
        }
221
    }
222
 
223
// ******* cancelWait **********************************************************
224
/**
225
  * Cancels all pending transfers and waits until transfers are canceled.
226
  * @param timeout Timeout in ms
227
  * @return True if all transfers are finished or cancelled
228
  * @throws UsbExecption if an error occurred.
229
  */
230
    public boolean cancelWait(int timeout) throws UsbException {
231
        cancel();
232
 
233
        boolean b = true;
234
        for (int i=0; b && i<=timeout; i+=20 ) {
235
            b = false;
236
            for (int j=0; j<bufNum; j++ ) {
237
                if ( transfers[j] != null ) {
238
                    b = b || pending[j];
239
                    if ( !pending[j] ) {
240
                        LibUsb.freeTransfer(transfers[j]);
241
                        transfers[j] = null;
242
                    }
243
                }
244
            }
245
            try { if ( b ) Thread.sleep(20); } catch ( InterruptedException e) { }
246
        }
247
        return !b;
248
    }
249
 
250
// ******* start ***************************************************************
251
/**
252
  * Start the reader.
253
  * The amount of buffers to be read is defined using the parameter maxCount.
254
  * A value of 0 starts infinite reads, a value of -1 starts the reader in speed test mode.
255
  * In this mode the buffer content is ignored and new read transfer are initiated immediately.
256
  * @param maxCount Maximum amount of bytes to read or 0 for infinite transfers or <0 for speed test mode.
257
  * @throws UsbExecption if an error occurred.
258
  */
259
    public void start(long maxCount) throws UsbException {
260
        byteCount = 0;
261
        speedTest = maxCount < 0;
262
        remaining = maxCount < 1 ? Long.MAX_VALUE : maxCount;
263
        for (int i=0; i<bufNum && remaining>0; i++) {
264
            int j = (int)((getCount+i) % bufNum);
265
            if ( transfers[j] == null ) {
266
                transfers[j] = LibUsb.allocTransfer();
267
                if ( transfers[j] == null ) throw new UsbException(dev, "Error allocating transfer buffer "+j);
268
                if ( isInt ) LibUsb.fillInterruptTransfer(transfers[j], handle, (byte)ep, bufs[j], callback, this, usbTimeOut);
269
                else LibUsb.fillBulkTransfer(transfers[j], handle, (byte)ep, bufs[j], callback, this, usbTimeOut);
270
            }
271
            submit(j);
272
        }
273
    }
274
}

powered by: WebSVN 2.1.0

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