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/] [ZtexUsbWriter.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 write transfers.
36
  */
37
 
38
// *****************************************************************************
39
// ******* ZtexUsbWriter *******************************************************
40
// *****************************************************************************
41
public class ZtexUsbWriter {
42
    private Device dev;
43
    private DeviceHandle handle;
44
    private int ep;
45
    private int bufNum;
46
    private int bufSize;
47
    private boolean isInt;
48
 
49
    private ByteBuffer[] bufs;
50
    private Transfer[] transfers;
51
    private volatile boolean[] pending;
52
    private int transmitCount = 0;
53
    private volatile long byteCount = 0;
54
    private boolean cancelled = false;  // transfer.status() seem not to work under windows
55
 
56
    private final TransferCallback callback = new TransferCallback() {
57
        public void processTransfer(Transfer transfer) {
58
            byteCount += transfer.actualLength();
59
            if ( (transfer.actualLength()!=transfer.length()) && (!cancelled) && (transfer.status()!=LibUsb.TRANSFER_CANCELLED) ) System.err.println( ZtexDevice1.name(dev) + ": Invalid length of sent data: " + transfer.actualLength() + " bytes sent, expected " + transfer.length() );
60
            // find index
61
            int i=0;
62
            while ( (i<bufNum) && (!transfer.equals(transfers[i])) ) i++;
63
            if ( i < bufNum ) {
64
                pending[i] = false;
65
            }
66
            else System.err.println("Internal error: unknown transfer");
67
        }
68
    };
69
 
70
 
71
// ******* ZtexUsbWriter *********************************************************
72
/**
73
  * Creates the writer for a given USB device and endpoint number.
74
  * @param p_handle The device handle used for communication (must be opened).
75
  * @param p_ep The input endpoint.
76
  * @param p_isInt True if it is an interrupt transfer.
77
  * @param p_bufSize size of each buffer. Typical values are 64KByte to 512KByte
78
  * @param p_bufNum number of buffer. Recommended queue size are 2MByte to 8MByte.
79
  */
80
    public ZtexUsbWriter ( DeviceHandle p_handle, int p_ep, boolean p_isInt, int p_bufNum, int p_bufSize ) {
81
        dev = LibUsb.getDevice(p_handle);
82
        handle = p_handle;
83
        ep = p_ep;
84
        bufNum = p_bufNum;
85
        bufSize = p_bufSize;
86
        bufs = new ByteBuffer[bufNum];
87
        transfers = new Transfer[bufNum];
88
        pending = new boolean[bufNum];
89
        for (int i=0; i<bufNum; i++) {
90
            bufs[i] = BufferUtils.allocateByteBuffer(bufSize);
91
            transfers[i] = null;
92
            pending[i] = false;
93
        }
94
    }
95
 
96
/**
97
  * Creates the writer from a given ZTEX device and endpoint number.
98
  * @param ztex The ZTEX device.
99
  * @param p_ep The number of the input endpoint
100
  * @param p_isInt True if it is an interrupt transfer.
101
  * @param p_bufSize size of each buffer. Typical values are 64KByte to 512KByte
102
  * @param p_bufNum number of buffer. Recommended queue size is 2MByte to 8MByte.
103
  */
104
    public ZtexUsbWriter ( Ztex1 ztex, int p_ep, boolean p_isInt, int p_bufNum, int p_bufSize ) {
105
        this(ztex.handle(), 127 & p_ep, p_isInt, p_bufNum, p_bufSize);
106
    }
107
 
108
/**
109
  * Creates the writer for the input endpoint of the default interface of a ZTEX device.
110
  * @param ztex The ZTEX device.
111
  * @param p_bufSize size of each buffer. Typical values are 64KByte to 512KByte
112
  * @param p_bufNum number of buffer. Recommended queue size is 2MByte to 8MByte.
113
  */
114
    public ZtexUsbWriter ( Ztex1v1 ztex, int p_bufNum, int p_bufSize ) throws InvalidFirmwareException, UsbException, CapabilityException {
115
        this(ztex.handle(), ztex.defaultOutEP(), false, p_bufNum, p_bufSize);
116
    }
117
 
118
// ******* transmitBuffer ******************************************************
119
/**
120
  * Transmit the next buffer.
121
  * @param buf The byte array which contains the data.
122
  * @param maxLen Maximum amount of data to transmit. If it is larger than the buffer size the last bytes are ignored.
123
  * @param timeout Timeout in ms. If timeout occurs the function returns -1.
124
  * @return The number of bytes transmitted or -1 if timeout occurs.
125
  * @throws UsbExecption if an error occurred.
126
  */
127
    public int transmitBuffer(byte[] buf, int maxLen, int timeout) throws UsbException {
128
        int j = transmitCount % bufNum;
129
//      System.out.println("TB1 "+transmitCount);
130
        for (int i=0; pending[j] && (i<timeout); i++ ) {
131
            try { Thread.sleep(1); } catch ( InterruptedException e) { }
132
        }
133
        if ( pending[j] ) {
134
            return -1;
135
        }
136
//      System.out.println("TB2 "+transmitCount);
137
        if ( transfers[j] == null ) {
138
            transfers[j] = LibUsb.allocTransfer();
139
            if ( transfers[j] == null ) throw new UsbException(dev, "Error allocating transfer buffer " + transmitCount);
140
            if ( isInt ) LibUsb.fillInterruptTransfer(transfers[j], handle, (byte)ep, bufs[j], callback, this, 5000);
141
            else LibUsb.fillBulkTransfer(transfers[j], handle, (byte)ep, bufs[j], callback, this, 5000);
142
        }
143
//      System.out.println("TB "+transmitCount);
144
        final int k = Math.min(Math.min(bufSize, maxLen), buf.length);
145
        bufs[j].rewind();
146
        bufs[j].put(buf, 0, k);
147
        transfers[j].setLength(k);
148
//      System.out.println("TB3 "+k);
149
        int result = LibUsb.submitTransfer(transfers[j]);
150
        if ( result!=LibUsb.SUCCESS ) throw new UsbException(dev, "Error submitting buffer " + transmitCount, result);
151
        pending[j] = true;
152
        transmitCount++;
153
        cancelled = false;
154
//      System.out.println("TB4 "+transmitCount);
155
        return k;
156
    }
157
 
158
 
159
/**
160
  * Transmit the next buffer.
161
  * @param buf The byte array which contains the data. If the array is larger than the buffer size the last bytes are ignored.
162
  * @param timeout Timeout in ms. If timeout occurs the function returns -1.
163
  * @return The number of bytes transmitted or -1 if timeout occurs.
164
  * @throws UsbExecption if an error occurred.
165
  */
166
    public int transmitBuffer(byte[] buf, int timeout) throws UsbException {
167
        return transmitBuffer(buf, buf.length, timeout);
168
    }
169
 
170
// ******* byteCount ***********************************************************
171
/**
172
  * Return the number of bytes transmitted.
173
  * @return The number of bytes transmitted.
174
  */
175
    public long byteCount () {
176
        return byteCount;
177
    }
178
 
179
// ******* bufSize *************************************************************
180
/**
181
  * Return the buffer size.
182
  * @return The buffer size.
183
  */
184
    public int bufSize () {
185
        return bufSize;
186
    }
187
 
188
// ******* cancel **************************************************************
189
/**
190
  * Cancels all pending transfers, also see {@link #cancelWait(int)}.
191
  * @throws UsbExecption if an error occurred.
192
  */
193
    public void cancel() throws UsbException {
194
        cancelled = true;
195
        for (int i=0; i<bufNum; i++ ) {
196
            if ( (transfers[i] != null) && pending[i] ) {
197
                int result = LibUsb.cancelTransfer(transfers[i]);
198
                if ( (result!=LibUsb.SUCCESS) && (result!=LibUsb.ERROR_NOT_FOUND) ) throw new UsbException(dev, "Unable to cancel transfer", result);
199
            }
200
        }
201
    }
202
 
203
// ******* wait **********************************************************
204
/**
205
  * Waits until all pending transfers are finished or canceled.
206
  * @param timeout Timeout in ms
207
  * @return True if all transfers are finished or cancelled
208
  * @throws UsbExecption if an error occurred.
209
  */
210
    public boolean wait(int timeout) throws UsbException {
211
        boolean b = true;
212
        for (int i=0; b && i<=timeout; i+=20 ) {
213
            b = false;
214
            for (int j=0; j<bufNum; j++ ) {
215
                if ( transfers[j] != null ) {
216
                    b = b || pending[j];
217
                    if ( !pending[j] ) {
218
                        LibUsb.freeTransfer(transfers[j]);
219
                        transfers[j] = null;
220
                    }
221
                }
222
            }
223
            try { if ( b ) Thread.sleep(20); } catch ( InterruptedException e) { }
224
        }
225
        return !b;
226
    }
227
 
228
// ******* cancelWait **********************************************************
229
/**
230
  * Cancels all pending transfers and waits until transfers are canceled.
231
  * @param timeout Timeout in ms
232
  * @return True if all transfers or cancelled.
233
  * @throws UsbExecption if an error occurred.
234
  */
235
    public boolean cancelWait(int timeout) throws UsbException {
236
        cancel();
237
        return wait(timeout);
238
    }
239
 
240
 
241
}

powered by: WebSVN 2.1.0

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