OpenCores
URL https://opencores.org/ocsvn/usb_ft232h_avalon-mm_interface/usb_ft232h_avalon-mm_interface/trunk

Subversion Repositories usb_ft232h_avalon-mm_interface

[/] [usb_ft232h_avalon-mm_interface/] [trunk/] [testbench/] [qt/] [test_usb_ft232h/] [main.cpp] - Blame information for rev 6

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 6 melman701
#include <iostream>
2
#include <iomanip>
3
#include <vector>
4
#include <algorithm>
5
#include <cmath>
6
#include <limits>
7
#include <chrono>
8
#include <unistd.h>
9
 
10
#include "ftd2xx.h"
11
 
12
 
13
using namespace std;
14
 
15
 
16
const int DEV_TYPE = 8;
17
const int DEV_VID = 0x0403;
18
const int DEV_PID = 0x75D8;
19
const int DEV_ID = (DEV_VID << 16) | DEV_PID;
20
 
21
const int BUFFER_SIZE = 524288;
22
const int MAX_TRANSACTION_SIZE = 65536 * 2;
23
 
24
 
25
enum TestMode {
26
    TM_READ = 1,
27
    TM_ECHO
28
};
29
 
30
 
31
FT_HANDLE ftHandle = 0;
32
FT_STATUS ftStatus = 0;
33
 
34
vector<int> devList;
35
 
36
uint8_t rxBuffer[BUFFER_SIZE] = {0};
37
uint8_t txBuffer[BUFFER_SIZE] = {0};
38
int txBufferHead = 0;
39
int rxBufferTail = 0;
40
 
41
DWORD readedBytesCount = 0;
42
DWORD writtenBytesCount = 0;
43
DWORD lastPortionSize = 0;
44
int errorsCount = 0;
45
 
46
DWORD targetSize = 524288 * 100;//262144;//524288;
47
int iterationCount = 5;
48
 
49
//DWORD startTime = 0, currentTime = 0, prevTime = 0;
50
double maxSpeed = 0, avgSpeed = 0, currentSpeed = 0;
51
double minSpeed = std::numeric_limits<DWORD>::max();
52
 
53
chrono::steady_clock::time_point timeBegin, timeCurrent, timePrev;
54
 
55
 
56
vector<int> errorsVector;
57
 
58
 
59
 
60
inline
61
void findDevice()
62
{
63
#ifdef linux
64
    ftStatus = FT_SetVIDPID(0x0403, 0x75d8);
65
#endif
66
    DWORD devCount = 0;
67
    devList.clear();
68
    ftStatus = FT_CreateDeviceInfoList(&devCount);
69
    if (!devCount)
70
        return;
71
    FT_DEVICE_LIST_INFO_NODE *ftDevInfo =
72
            (FT_DEVICE_LIST_INFO_NODE*)malloc(sizeof(FT_DEVICE_LIST_INFO_NODE)*devCount);
73
    FT_GetDeviceInfoList(ftDevInfo, &devCount);
74
    for (uint32_t i = 0; i < devCount; ++i) {
75
        if (ftDevInfo[i].ID == DEV_ID) {
76
            devList.push_back(i);
77
            cout << "Dev flags: " << ftDevInfo[i].Flags << endl;
78
        }
79
    }
80
    free(ftDevInfo);
81
}
82
 
83
inline
84
bool openDevice(int index)
85
{
86
    ftStatus = FT_Open(index, &ftHandle);
87
    if (!FT_SUCCESS(ftStatus)) {
88
        cout << "Unable to open USB device. " << ftStatus << endl;
89
        return false;
90
    }
91
    if (ftHandle == NULL) {
92
        cout << "No device found" << endl;
93
        return false;
94
    }
95
    //configure
96
    uint8_t mask=0xff, mode=0x0, latency=2;
97
    mode = 0x0; //reset mode
98
    ftStatus = FT_SetBitMode(ftHandle, mask, mode);
99
    usleep(1000000);
100
    mode = 0x40;
101
    ftStatus = FT_SetBitMode(ftHandle, mask, mode);
102
    if (!FT_SUCCESS(ftStatus)) {
103
        cout << "Set bit mode failed. " << ftStatus << endl;
104
        return false;
105
    }
106
    FT_SetLatencyTimer(ftHandle, latency);
107
    FT_SetUSBParameters(ftHandle, 0x10000, 0x10000);
108
    FT_SetFlowControl(ftHandle, FT_FLOW_RTS_CTS, 0x0, 0x0);
109
    FT_Purge(ftHandle, FT_PURGE_RX | FT_PURGE_TX);
110
    return true;
111
}
112
 
113
inline
114
void closeDevice()
115
{
116
    FT_Close(ftHandle);
117
}
118
 
119
 
120
inline
121
DWORD availableData()
122
{
123
    DWORD queue;
124
    ftStatus = FT_GetQueueStatus(ftHandle, &queue);
125
    if (!FT_SUCCESS(ftStatus)) {
126
        cout << "Get available data failed. " << ftStatus << endl;
127
        return 0;
128
    }
129
    return queue;
130
}
131
 
132
inline
133
bool readData(void *buffer, DWORD size, DWORD &bytesReaded)
134
{
135
    ftStatus = FT_Read(ftHandle, buffer, size, &bytesReaded);
136
    if (!FT_SUCCESS(ftStatus)) {
137
        cout << "Read data failed. " << ftStatus << endl;
138
        return false;
139
    }
140
    return true;
141
}
142
 
143
inline
144
bool writeData(void *data, DWORD size, DWORD &bytesWritten)
145
{
146
    ftStatus = FT_Write(ftHandle, data, size, &bytesWritten);
147
    if (!FT_SUCCESS(ftStatus)) {
148
        cout << "Write data failed. " << ftStatus << endl;
149
        return false;
150
    }
151
    return true;
152
}
153
 
154
 
155
void calcSpeed(bool force = false)
156
{
157
    timeCurrent = chrono::steady_clock::now();
158
    double time = chrono::duration_cast<chrono::milliseconds>(timeCurrent - timePrev).count();
159
    if (( time >= 500 ) || force) {
160
        double dataSize = lastPortionSize * 1.0 / 1000;
161
        time /= 1000;
162
        currentSpeed = dataSize / time;
163
        dataSize = (readedBytesCount + writtenBytesCount) * 1.0 / 1000;
164
        time = chrono::duration_cast<chrono::milliseconds>(timeCurrent - timeBegin).count();
165
        time /= 1000;
166
        avgSpeed = dataSize / time;
167
        if (currentSpeed > maxSpeed)
168
            maxSpeed = currentSpeed;
169
        if (currentSpeed < minSpeed)
170
            minSpeed = currentSpeed;
171
        timePrev = timeCurrent;
172
        lastPortionSize = 0;
173
 
174
        cout << "Time: " << floor(time) << " Size(w/r): " << fixed << setprecision(3)
175
             << writtenBytesCount * 1.0 / 1000 << "/"
176
             << readedBytesCount * 1.0 / 1000 << defaultfloat
177
             << " kB \tRate (min/max/avg/current): " << int(floor(minSpeed)) << "/"
178
             << int(floor(maxSpeed)) << "/" << int(floor(avgSpeed)) << "/"
179
             << int(floor(currentSpeed)) << " kB/s \tErrors: " << errorsCount << endl;
180
        flush(cout);
181
    }
182
}
183
 
184
inline
185
void checkData(int offset, int size)
186
{
187
    for (int i = offset; (i < BUFFER_SIZE) && (i < offset + size); ++i) {
188
        if (rxBuffer[i] != txBuffer[i]) {
189
            if (errorsCount == 0) {
190
                int pi = i - 1;
191
                if (pi < 0)
192
                    pi = targetSize - 1;
193
                while (pi > BUFFER_SIZE) {
194
                    pi -= BUFFER_SIZE;
195
                }
196
                int ni = i + 1;
197
                if (ni >= BUFFER_SIZE)
198
                    ni = 0;
199
 
200
                cout << i << " " << int(txBuffer[i]) << " - " << int(rxBuffer[i])
201
                     << " \t" << pi << " " << int(txBuffer[pi]) << " - "
202
                     << int(rxBuffer[pi]) << " \t" << ni << " "
203
                     << int(txBuffer[ni]) << " I: ";
204
 
205
                /*for (int j = 0; (j < targetSize) && (j < BUFFER_SIZE); ++j) {
206
                    if (txBuffer[j] == rxBuffer[i]) {
207
//                        cout << j << " ";
208
                        auto fit = find(begin(errorsVector), end(errorsVector), j);
209
                        if ( fit != errorsVector.end()) {
210
                            cout << j << " ";
211
                        }
212
                    }
213
                }*/
214
                cout << endl;
215
            }
216
            ++errorsCount;
217
        }
218
    }
219
}
220
 
221
 
222
inline
223
void readMode()
224
{
225
    DWORD available = 0;
226
    DWORD bytesRead = 0;
227
    uint8_t value = 0;
228
 
229
    readedBytesCount = 0;
230
    writtenBytesCount = 0;
231
    lastPortionSize = 0;
232
    txBufferHead = 0;
233
    rxBufferTail = 0;
234
    errorsCount = 0;
235
    maxSpeed = 0;
236
    minSpeed = std::numeric_limits<DWORD>::max();
237
    avgSpeed = 0;
238
    currentSpeed = 0;
239
 
240
    txBuffer[0] = TM_READ;
241
    if (!writeData(txBuffer, 1, bytesRead)) {
242
        return;
243
    }
244
    timePrev = timeCurrent = timeBegin = chrono::steady_clock::now();
245
    while (true) {
246
        available = availableData();
247
        if (!available)
248
            continue;
249
        if (available > BUFFER_SIZE)
250
            available = BUFFER_SIZE;
251
        if (!readData(rxBuffer, available, bytesRead)) {
252
            return;
253
        }
254
        if (!bytesRead)
255
            continue;
256
        if (!readedBytesCount) {
257
            value = rxBuffer[0];
258
        }
259
        for (DWORD i = 0; i < bytesRead; ++i) {
260
            if (value != rxBuffer[i]) {
261
                ++errorsCount;
262
                value = rxBuffer[i];
263
            }
264
            ++value &= 0xFF;
265
        }
266
        readedBytesCount += bytesRead;
267
        lastPortionSize += bytesRead;
268
 
269
        calcSpeed();
270
    }
271
}
272
 
273
inline
274
void echoMode()
275
{
276
    DWORD available = 0;
277
    DWORD bytesRead = 0;
278
    DWORD bytesWrite = 0;
279
    DWORD writeSize = 0;
280
 
281
    readedBytesCount = 0;
282
    writtenBytesCount = 0;
283
    lastPortionSize = 0;
284
    txBufferHead = 0;
285
    rxBufferTail = 0;
286
    errorsCount = 0;
287
    maxSpeed = 0;
288
    minSpeed = std::numeric_limits<DWORD>::max();
289
    avgSpeed = 0;
290
    currentSpeed = 0;
291
 
292
    uint8_t mode = TM_ECHO;
293
    /*if (!writeData(&mode, 1, bytesRead)) {
294
        return;
295
    }
296
    if (!writeData(&targetSize, 4, bytesRead)) {
297
        return;
298
    }*/
299
 
300
//    prevTime = currentTime = startTime = GetTickCount();
301
    timePrev = timeCurrent = timeBegin = chrono::steady_clock::now();
302
 
303
    cout << "Start loop" << endl;
304
    while ((writtenBytesCount < targetSize) || (readedBytesCount < targetSize)) {
305
        // send
306
        if ((writtenBytesCount < targetSize)
307
                && ((writtenBytesCount - readedBytesCount) < MAX_TRANSACTION_SIZE)) {
308
            writeSize = BUFFER_SIZE - txBufferHead;
309
            if (writeSize > (targetSize - writtenBytesCount))
310
                writeSize = targetSize - writtenBytesCount;
311
            if (writeSize > MAX_TRANSACTION_SIZE)
312
                writeSize = MAX_TRANSACTION_SIZE;
313
            if (!writeData(&txBuffer[txBufferHead], writeSize, bytesWrite)) {
314
                return;
315
            }
316
//            cout << "write " << txBufferHead << " " << int(txBuffer[txBufferHead])
317
//                 << " " << bytesWrite << endl;
318
            writtenBytesCount += bytesWrite;
319
            lastPortionSize += bytesWrite;
320
            txBufferHead += bytesWrite;
321
            if (txBufferHead == BUFFER_SIZE) {
322
                txBufferHead = 0;
323
            }
324
            else if (txBufferHead > BUFFER_SIZE) {
325
                cout << "Tx buffer range error" << endl;
326
                return;
327
            }
328
        }
329
 
330
        // read
331
        available = availableData();
332
        if ((readedBytesCount < targetSize) && available) {
333
            if (available > (BUFFER_SIZE - rxBufferTail))
334
                available = BUFFER_SIZE - rxBufferTail;
335
            if (available > (targetSize - readedBytesCount)) {
336
                cout << "More data then need " << available << "/"
337
                     << targetSize - readedBytesCount << endl;
338
                available = targetSize - readedBytesCount;
339
            }
340
            if (!readData(&rxBuffer[rxBufferTail], available, bytesRead)) {
341
                return;
342
            }
343
//            cout << "read " << rxBufferTail << " " << bytesRead
344
//                 << " " << rxBufferTail + bytesRead << endl;
345
            readedBytesCount += bytesRead;
346
            lastPortionSize += bytesRead;
347
            checkData(rxBufferTail, bytesRead);
348
            rxBufferTail += bytesRead;
349
            if (rxBufferTail == BUFFER_SIZE) {
350
                rxBufferTail = 0;
351
            }
352
            else if (rxBufferTail > BUFFER_SIZE) {
353
                cout << "Rx buffer range error" << endl;
354
                return;
355
            }
356
        }
357
 
358
        calcSpeed();
359
    }
360
    calcSpeed(true);
361
    cout << endl << availableData() << endl;
362
}
363
 
364
 
365
int main(int argc, char *argv[])
366
{
367
    cout << "Hello World!" << endl;
368
 
369
    for (int i = 0; i < BUFFER_SIZE; ++i) {
370
        txBuffer[i] = rand() & 0xFF;
371
        if (txBuffer[i] == 94) {
372
            errorsVector.push_back(i);
373
            --i;
374
        }
375
    }
376
 
377
    findDevice();
378
    cout << devList.size() << " devices found" << endl;
379
    if (!devList.size())
380
        return 0;
381
    DWORD index;
382
    cout << "Put device index (from 0 to devices count): ";
383
    cin >> index;
384
    cout << endl;
385
    if (index >= devList.size()) {
386
        cout << "You fool!" << endl;
387
        return 0;
388
    }
389
    cout << "Open device " << index << " ... ";
390
    if (!openDevice(index)) {
391
        cout << "[FAIL]" << endl;
392
        return 0;
393
    }
394
    cout << "[ OK ]" << endl;
395
 
396
    cout << "Select mode:\n\t" << TM_READ << " - read\n\t"
397
         << TM_ECHO << " - echo\n\t* - exit" << endl;
398
    cout<< "Enter your choice: ";
399
    cin >> index;
400
    cout << endl;
401
    switch (index) {
402
    case TM_READ:
403
        cout << "Start read mode" << endl;
404
        readMode();
405
        break;
406
    case TM_ECHO:
407
        cout << "Start echo mode" << endl;
408
        while (iterationCount-- && (errorsCount == 0)) {
409
            echoMode();
410
//            cout << "Data:" << endl;
411
//            for (int i = 0; i < targetSize; ++i) {
412
//                cout << int(txBuffer[i]) << " = " << int(rxBuffer[i]) << endl;
413
//            }
414
//            ++targetSize;
415
        }
416
        break;
417
    default:
418
        break;
419
    }
420
 
421
    closeDevice();
422
    cout << "Finish" << endl;
423
    return 0;
424
}

powered by: WebSVN 2.1.0

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