/alps/ipecamera

To get this branch, use:
bzr branch http://darksoft.org/webbzr/alps/ipecamera

« back to all changes in this revision

Viewing changes to apps/lorenzo_ipedma_test.c

  • Committer: Suren A. Chilingaryan
  • Date: 2015-04-27 00:28:57 UTC
  • Revision ID: csa@suren.me-20150427002857-82fk6r3e8rfgy4wr
First stand-alone ipecamera implementation

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
#define _POSIX_C_SOURCE 199309L
2
 
#include <stdio.h>
3
 
#include <stdlib.h>
4
 
#include <string.h>
5
 
#include <unistd.h>
6
 
#include <stdarg.h>
7
 
#include <time.h>
8
 
#include <sched.h>
9
 
#include <sys/time.h>
10
 
#include <sys/types.h>
11
 
#include <arpa/inet.h>
12
 
#include <sched.h>
13
 
#include <errno.h>
14
 
 
15
 
#include "pcilib.h"
16
 
#include "irq.h"
17
 
#include "kmem.h"
18
 
 
19
 
//#include <sys/ipc.h>
20
 
//#include <sys/shm.h>
21
 
 
22
 
 
23
 
#define DEVICE "/dev/fpga0"
24
 
 
25
 
#define BAR PCILIB_BAR0
26
 
#define USE_RING PCILIB_KMEM_USE(PCILIB_KMEM_USE_USER, 1)
27
 
#define USE PCILIB_KMEM_USE(PCILIB_KMEM_USE_USER, 2)
28
 
//#define STATIC_REGION 0x80000000 //  to reserve 512 MB at the specified address, add "memmap=512M$2G" to kernel parameters
29
 
 
30
 
#define BUFFERS         128
31
 
#define ITERATIONS      1000
32
 
#define DESC_THRESHOLD  BUFFERS/8   // Lorenzo: after how many desc the FPGA must update the "written descriptor counter" in PC mem
33
 
                                    // if set to 0, the update only happens when INT is received
34
 
 
35
 
#define HUGE_PAGE       1           // number of pages per huge page
36
 
#define TLP_SIZE        32          // TLP SIZE = 64 for 256B payload, 32 for 128B payload
37
 
#define PAGE_SIZE       4096        // other values are not supported in the kernel
38
 
 
39
 
//#define USE_64                    // Lorenzo: use 64bit addressing
40
 
 
41
 
//#define DUAL_CORE                 // Lorenzo: DUAL Core
42
 
 
43
 
//#define SHARED_MEMORY               // Lorenzo: Test for fast GUI
44
 
 
45
 
#define CHECK_READY                 // Lorenzo: Check if PCI-Express is ready by reading 0x0
46
 
#define CHECK_RESULTS               // Lorenzo: Check if data received is ok (only for counter!)
47
 
//#define PRINT_RESULTS               // Lorenzo: Save the received data in "data.out"
48
 
//#define EXIT_ON_EMPTY               // Lorenzo: Exit if an "empty_detected" signal is received
49
 
 
50
 
//#define HEB                       // Lorenzo: Testing HEB
51
 
//#define SWITCH_GENERATOR          // Lorenzo: Testing HEB -> Turn data gen on/off
52
 
 
53
 
//#define TEST_DDR                    // Lorenzo: Testing DDR
54
 
 
55
 
#define TIMEOUT         1000000
56
 
 
57
 
 
58
 
 
59
 
/* IRQs are slow for some reason. REALTIME mode is slower. Adding delays does not really help,
60
 
   otherall we have only 3 checks in average. Check ready seems to be not needed and adds quite 
61
 
   much extra time */
62
 
 
63
 
//#define USE_IRQ
64
 
//#define REALTIME
65
 
//#define ADD_DELAYS
66
 
 
67
 
 
68
 
#define FPGA_CLOCK 250 // Lorenzo: in MHz !
69
 
 
70
 
 
71
 
 
72
 
//#define WR(addr, value) { val = value; pcilib_write(pci, BAR, addr, sizeof(val), &val); }
73
 
//#define RD(addr, value) { pcilib_read(pci, BAR, addr, sizeof(val), &val); value = val; }
74
 
#define WR(addr, value) { *(uint32_t*)(bar + addr + offset) = value; }
75
 
#define RD(addr, value) { value = *(uint32_t*)(bar + addr + offset); }
76
 
 
77
 
// **************************************************************************************
78
 
// Progress BAR
79
 
// Process has done x out of n rounds,
80
 
// and we want a bar of width w and resolution r.
81
 
   static inline void loadBar(int x, int n, int r, int w)
82
 
   {
83
 
    // Only update r times.
84
 
    if ( x % (n/r +1) != 0 ) return;
85
 
 
86
 
    // Calculuate the ratio of complete-to-incomplete.
87
 
    float ratio = x/(float)n;
88
 
    int   c     = ratio * w;
89
 
 
90
 
    // Show the percentage complete.
91
 
    printf("%3d%% [", (int)(ratio*100) );
92
 
 
93
 
    // Show the load bar.
94
 
        for (x=0; x<c; x++)
95
 
           printf("=");
96
 
 
97
 
       for (x=c; x<w; x++)
98
 
           printf(" ");
99
 
 
100
 
    // ANSI Control codes to go back to the
101
 
    // previous line and clear it.
102
 
       printf("]\n\033[F\033[J");
103
 
   }
104
 
// **************************************************************************************
105
 
 
106
 
 
107
 
   static void fail(const char *msg, ...) {
108
 
    va_list va;
109
 
 
110
 
    va_start(va, msg);
111
 
    vprintf(msg, va);
112
 
    va_end(va);
113
 
    printf("\n");
114
 
 
115
 
    exit(-1);
116
 
}
117
 
 
118
 
void hpsleep(size_t ns) {
119
 
    struct timespec wait, tv;
120
 
 
121
 
    clock_gettime(CLOCK_REALTIME, &wait);
122
 
 
123
 
    wait.tv_nsec += ns;
124
 
    if (wait.tv_nsec > 999999999) {
125
 
        wait.tv_sec += 1;
126
 
        wait.tv_nsec = 1000000000 - wait.tv_nsec;
127
 
    }
128
 
 
129
 
    do {
130
 
        clock_gettime(CLOCK_REALTIME, &tv);
131
 
    } while ((wait.tv_sec > tv.tv_sec)||((wait.tv_sec == tv.tv_sec)&&(wait.tv_nsec > tv.tv_nsec)));
132
 
}
133
 
 
134
 
 
135
 
// **************************************************************************************
136
 
int main() {
137
 
 
138
 
 
139
 
 
140
 
    int err;
141
 
    long i, j, k;
142
 
    int mem_diff;
143
 
    pcilib_t *pci;
144
 
    pcilib_kmem_handle_t *kdesc;
145
 
    pcilib_kmem_handle_t *kbuf;
146
 
    struct timeval start, end;
147
 
    size_t run_time, size;
148
 
    long long int size_mb;
149
 
    void* volatile bar;
150
 
    uintptr_t bus_addr[BUFFERS];
151
 
    uintptr_t kdesc_bus;
152
 
    volatile uint32_t *desc;
153
 
    typedef volatile uint32_t *Tbuf;
154
 
    Tbuf ptr[BUFFERS];
155
 
    int switch_generator = 0;
156
 
   
157
 
    float performance, perf_counter; 
158
 
    pcilib_bar_t bar_tmp = BAR; 
159
 
    uintptr_t offset = 0;
160
 
 
161
 
    unsigned int temp;
162
 
    int iterations_completed, buffers_filled;
163
 
 
164
 
 
165
 
//    int shmid;
166
 
    
167
 
 
168
 
    printf("\n\n**** **** **** KIT-DMA TEST **** **** ****\n\n");
169
 
 
170
 
    size = ITERATIONS * BUFFERS * HUGE_PAGE * PAGE_SIZE;
171
 
    size_mb = ITERATIONS * BUFFERS * HUGE_PAGE * 4 / 1024;
172
 
    printf("Total size of memory buffer: \t %.3lf GBytes\n", (float)size_mb/1024 );
173
 
    printf("Using %d Buffers with %d iterations\n\n", BUFFERS, ITERATIONS );
174
 
 
175
 
#ifdef ADD_DELAYS
176
 
    long rpt = 0, rpt2 = 0;
177
 
    size_t best_time;
178
 
    best_time = 1000000000L * HUGE_PAGE * PAGE_SIZE / (4L * 1024 * 1024 * 1024);
179
 
#endif /* ADD_DELAYS */
180
 
 
181
 
 
182
 
    pcilib_kmem_flags_t flags = PCILIB_KMEM_FLAG_HARDWARE|PCILIB_KMEM_FLAG_PERSISTENT|PCILIB_KMEM_FLAG_EXCLUSIVE/*|PCILIB_KMEM_FLAG_REUSE*/; // Lorenzo: if REUSE = 1, the re-allocation fails!
183
 
    pcilib_kmem_flags_t free_flags = PCILIB_KMEM_FLAG_HARDWARE/*|PCILIB_KMEM_FLAG_EXCLUSIVE|PCILIB_KMEM_FLAG_REUSE*/;
184
 
    pcilib_kmem_flags_t clean_flags = PCILIB_KMEM_FLAG_HARDWARE|PCILIB_KMEM_FLAG_PERSISTENT|PCILIB_KMEM_FLAG_EXCLUSIVE;
185
 
 
186
 
    pci = pcilib_open(DEVICE, PCILIB_MODEL_DETECT);
187
 
    if (!pci) fail("pcilib_open");
188
 
 
189
 
    bar = pcilib_map_bar(pci, BAR);
190
 
    if (!bar) {
191
 
        pcilib_close(pci);
192
 
        fail("map bar");
193
 
    }
194
 
 
195
 
    pcilib_detect_address(pci, &bar_tmp, &offset, 1);
196
 
 
197
 
    pcilib_enable_irq(pci, PCILIB_IRQ_TYPE_ALL, 0);
198
 
    pcilib_clear_irq(pci, PCILIB_IRQ_SOURCE_DEFAULT);
199
 
 
200
 
    pcilib_clean_kernel_memory(pci, USE, clean_flags);
201
 
    pcilib_clean_kernel_memory(pci, USE_RING, clean_flags);
202
 
 
203
 
    kdesc = pcilib_alloc_kernel_memory(pci, PCILIB_KMEM_TYPE_CONSISTENT, 1, 128, 4096, USE_RING, flags);
204
 
    kdesc_bus = pcilib_kmem_get_block_ba(pci, kdesc, 0);
205
 
    desc = (uint32_t*)pcilib_kmem_get_block_ua(pci, kdesc, 0);
206
 
    memset((void*)desc, 0, 5*sizeof(uint32_t));
207
 
 
208
 
#ifdef REALTIME
209
 
    pid_t pid;
210
 
    struct sched_param sched = {0};
211
 
 
212
 
    pid = getpid();
213
 
    sched.sched_priority = sched_get_priority_min(SCHED_FIFO);
214
 
    if (sched_setscheduler(pid, SCHED_FIFO, &sched))
215
 
        printf("Warning: not able to get real-time priority\n");
216
 
#endif /* REALTIME */
217
 
 
218
 
    // ******************************************************************
219
 
    // ****      MEM: check 4k boundary                             ***** 
220
 
    // ******************************************************************
221
 
 
222
 
    do  {
223
 
        printf("* Allocating KMem, ");
224
 
#ifdef STATIC_REGION
225
 
        kbuf = pcilib_alloc_kernel_memory(pci, PCILIB_KMEM_TYPE_REGION_C2S, BUFFERS, HUGE_PAGE * PAGE_SIZE, STATIC_REGION, USE, flags);
226
 
#else
227
 
        kbuf = pcilib_alloc_kernel_memory(pci, PCILIB_KMEM_TYPE_DMA_C2S_PAGE, BUFFERS, HUGE_PAGE * PAGE_SIZE, 4096, USE, flags);
228
 
#endif
229
 
 
230
 
        if (!kbuf) {
231
 
            printf("KMem allocation failed\n");
232
 
            exit(0);
233
 
        }
234
 
 
235
 
        // Pointers for Virtualized Mem
236
 
        for (j = 0; j < BUFFERS; j++) {
237
 
            ptr[j] = (volatile uint32_t*)pcilib_kmem_get_block_ua(pci, kbuf, j);
238
 
            memset((ptr[j]), 0, HUGE_PAGE * PAGE_SIZE);
239
 
        }
240
 
 
241
 
        err = 0;
242
 
 
243
 
        // Check if HW addresses satisfy 4k boundary condition, if not -> free (!!) and reallocate memory
244
 
        printf("4k boundary test: ");
245
 
        for (j = 0; j < BUFFERS; j++) {
246
 
            temp = (((unsigned int)pcilib_kmem_get_block_ba(pci, kbuf, j)) % 4096);
247
 
            //printf("%u", temp);
248
 
            if (temp  != 0) {
249
 
                err = 1;
250
 
            }
251
 
        }
252
 
        if (err == 1) {
253
 
            pcilib_clean_kernel_memory(pci, USE, clean_flags);
254
 
            pcilib_clean_kernel_memory(pci, USE_RING, clean_flags);
255
 
            pcilib_free_kernel_memory(pci, kbuf,  free_flags);
256
 
            printf("failed \xE2\x9C\x98\n");
257
 
        }
258
 
        else printf("passed \xE2\x9C\x93\n");
259
 
 
260
 
    } while (err == 1);
261
 
 
262
 
 
263
 
    // ******************************************************************
264
 
    // ****      Allocate RAM buffer Memory                         ***** 
265
 
    // ******************************************************************
266
 
    
267
 
    FILE * Output;
268
 
    FILE * error_log;
269
 
 
270
 
#ifdef CHECK_RESULTS
271
 
 
272
 
    uint32_t *temp_data[ITERATIONS][BUFFERS];
273
 
 
274
 
    for (j=0; j < ITERATIONS; j++) {
275
 
        for (i=0; i < BUFFERS; i++) {
276
 
            temp_data[j][i] = (uint32_t *)malloc(HUGE_PAGE*PAGE_SIZE);
277
 
            if (temp_data[j][i] == 0) {
278
 
                printf("******* Error: could not allocate memory! ********\n");
279
 
                exit(0);
280
 
            }
281
 
            memset((void*)(temp_data[j][i]), 0, HUGE_PAGE * PAGE_SIZE);
282
 
        }
283
 
    }
284
 
#endif
285
 
 
286
 
#ifdef SHARED_MEMORY
287
 
    // give your shared memory an id, anything will do
288
 
    key_t key = 123456;
289
 
    char *shared_memory;
290
 
 
291
 
    // Setup shared memory, 11 is the size
292
 
/*    if ((shmid = shmget(key, HUGE_PAGE*PAGE_SIZE, IPC_CREAT | 0666)) < 0)
293
 
    {
294
 
      printf("Error getting shared memory id");
295
 
      exit(1);
296
 
    }
297
 
 
298
 
    // Attached shared memory
299
 
    if ((shared_memory = shmat(shmid, NULL, 0)) == (char *) -1)
300
 
    {
301
 
      printf("Error attaching shared memory id");
302
 
      exit(1);
303
 
    }
304
 
    printf("* Shared memory created... Id:\t %d\n", key);
305
 
    //////////////// SHARED MEMORY TEST */
306
 
#endif
307
 
 
308
 
    Output = fopen ("data.out", "w");
309
 
    fclose(Output);
310
 
 
311
 
    error_log = fopen ("error_log.txt", "w");
312
 
    fclose(error_log);
313
 
   
314
 
   // *************************************
315
 
    Output = fopen("data.txt", "w");
316
 
    fclose(Output);
317
 
 
318
 
    // ******************************************************************
319
 
    // ****      PCIe TEST                                          ***** 
320
 
    // ******************************************************************
321
 
 
322
 
    // Reset DMA
323
 
    printf("* DMA: Reset...\n");
324
 
    WR(0x00, 0x1);
325
 
    usleep(100000);
326
 
    WR(0x00, 0x0);
327
 
    usleep(100000);
328
 
 
329
 
#ifdef CHECK_READY       
330
 
    printf("* PCIe: Testing...");
331
 
    RD(0x0, err);
332
 
    if (err != 335746816) {
333
 
        printf("\xE2\x9C\x98\n PCIe not ready!\n");
334
 
        exit(0);
335
 
    } else {
336
 
        printf("\xE2\x9C\x93 \n");
337
 
    }
338
 
#endif
339
 
    
340
 
 
341
 
    // ******************************************************************
342
 
    // ****      DMA CONFIGURATION                                  ***** 
343
 
    // ******************************************************************
344
 
 
345
 
    
346
 
    printf("* DMA: Start Data Generator...\n");
347
 
    WR(0x04, 0x10) // Start data generator
348
 
 
349
 
    printf("* DMA: Send Data Fill Pattern 55aa55aa\n");
350
 
    WR(0x14, 0xbeef);
351
 
 
352
 
    printf("* DMA: Send Data Amount\n");
353
 
#ifdef DUAL_CORE
354
 
    WR(0x10, (HUGE_PAGE * (PAGE_SIZE / (4 * TLP_SIZE)))/2);
355
 
#else  
356
 
    WR(0x10, (HUGE_PAGE * (PAGE_SIZE / (4 * TLP_SIZE))));
357
 
#endif   
358
 
 
359
 
    printf("* DMA: Running mode: ");
360
 
#ifdef USE_64   
361
 
    if (TLP_SIZE == 64) 
362
 
    {
363
 
        WR(0x0C, 0x80040);
364
 
        printf ("64bit - 256B Payload\n");
365
 
    }
366
 
    else if (TLP_SIZE == 32) 
367
 
    {
368
 
        WR(0x0C, 0x80020);
369
 
        printf ("64bit - 128B Payload\n");
370
 
    }
371
 
#else  
372
 
    if (TLP_SIZE == 64) 
373
 
    {
374
 
        WR(0x0C, 0x0040);
375
 
        printf ("32bit - 256B Payload\n");
376
 
    }
377
 
    else if (TLP_SIZE == 32) 
378
 
    {
379
 
        WR(0x0C, 0x0020);
380
 
        printf ("32bit - 128B Payload\n");
381
 
    }
382
 
#endif
383
 
    
384
 
    printf("* DMA: Reset Desc Memory...\n");
385
 
    WR(0x5C, 0x00); // RST Desc Memory
386
 
 
387
 
    //printf("Writing SW Read Descriptor\n");
388
 
    WR(0x58, BUFFERS-1);
389
 
    //WR(0x58, 0x01);
390
 
 
391
 
    //printf("Writing the Descriptor Threshold\n");
392
 
    WR(0x60, DESC_THRESHOLD);
393
 
 
394
 
    //printf("Writing HW write Descriptor Address: %lx\n", kdesc_bus);
395
 
    WR(0x54, kdesc_bus);
396
 
    usleep(100000);
397
 
 
398
 
    printf("* DMA: Writing Descriptors\n");
399
 
    for (j = 0; j < BUFFERS; j++ ) {
400
 
        bus_addr[j] = pcilib_kmem_get_block_ba(pci, kbuf, j);
401
 
        // LEAVE THIS DELAY???!?!?!?!
402
 
        usleep(1000);
403
 
        printf("Writing descriptor num. %ld: \t %08lx \r", j, bus_addr[j]);
404
 
        WR(0x50, bus_addr[j]);
405
 
    }
406
 
 
407
 
    // ******************************************************************
408
 
    // ****      HEB CONFIGURATION                                  ***** 
409
 
    // ******************************************************************
410
 
#ifdef HEB
411
 
 
412
 
 
413
 
    printf("* DDR REGISTERS: AXI_BUF_SIZE \n");
414
 
    WR(0x9130, 0x1000);
415
 
 
416
 
    usleep(100000);
417
 
 
418
 
    printf("* HEB: Control \n");
419
 
    WR(0x9040, 0x00000001);
420
 
 
421
 
    usleep(100000);
422
 
 
423
 
    printf("* HEB: Control \n");
424
 
    WR(0x9040, 0x00000004);
425
 
 
426
 
    usleep(100000);
427
 
 
428
 
    printf("* HEB: Control \n");
429
 
    WR(0x9040, 0x00000000);
430
 
 
431
 
    usleep(100000);
432
 
 
433
 
    printf("* HEB: Writing Total Orbit Num\n");
434
 
    WR(0x9020, 0x2000);
435
 
 
436
 
    printf("* HEB: Orbit Skip Num h9028\n");
437
 
    WR(0x9028, 0x4);
438
 
 
439
 
    //printf("* HEB: LVDS_DELAY h9080\n");
440
 
    //WR(0x9080, 0x10101010);
441
 
 
442
 
    //printf("* HEB: Delay ADCs \n");
443
 
    //WR(0x9088, 0x001);
444
 
    //WR(0x9090, 0x001);
445
 
    //WR(0x9094, 0x001);
446
 
    //WR(0x9098, 0x001);
447
 
 
448
 
    //printf("* HEB: Delay TH \n");
449
 
    //WR(0x90a0, 0x005);
450
 
 
451
 
    //printf("* HEB: Delay_FPGA_reg \n");
452
 
    //WR(0x90a8, 0x006);
453
 
 
454
 
    //printf("* HEB: Control \n");
455
 
    //WR(0x9040, 0x40000000);
456
 
 
457
 
    //usleep(1000000);
458
 
 
459
 
    printf("* HEB: Control \n");
460
 
    WR(0x9040, 0x40000bf0);
461
 
 
462
 
    usleep(100000);
463
 
 
464
 
    printf("* HEB: Control \n");
465
 
    WR(0x9040, 0x400003f0);
466
 
 
467
 
    usleep(100000);
468
 
 
469
 
    printf("* HEB: Control \n");
470
 
    WR(0x9040, 0x480007F0);
471
 
 
472
 
    usleep(100000);
473
 
 
474
 
    printf("* HEB: Control \n");
475
 
    WR(0x9040, 0x48000FF0);
476
 
 
477
 
 
478
 
#endif
479
 
 
480
 
    // ******************************************************************
481
 
    // ****      TEST DDR conf                                      ***** 
482
 
    // ******************************************************************
483
 
#ifdef TEST_DDR
484
 
 
485
 
 
486
 
    printf("* DDR: AXI_BUF_SIZE_ADDR: 4k\n");
487
 
    WR(0x9010, 0x04000);
488
 
 
489
 
    printf("* DDR: Control \n");
490
 
    WR(0x9000, 0x000000F);
491
 
 
492
 
    usleep(100000);
493
 
    WR(0x9000, 0x00000008);
494
 
    usleep(100000);
495
 
    WR(0x9000, 0x08000008);
496
 
 
497
 
    usleep(50000);
498
 
 
499
 
    printf("* DDR: Control \n");
500
 
    WR(0x9000, 0x08000208);
501
 
 
502
 
 
503
 
#endif
504
 
 
505
 
    // ******************************************************************
506
 
    // ****     START DMA                                           *****
507
 
    // ******************************************************************
508
 
 
509
 
    //printf ("\n ---- Press ENTER to start DMA ---- \n");
510
 
    //getchar();
511
 
 
512
 
    printf("* DMA: Start \n");
513
 
    WR(0x04, 0x1f);
514
 
    gettimeofday(&start, NULL);
515
 
 
516
 
    // ******************************************************************
517
 
    // ****     Handshaking DMA                                     *****
518
 
    // ******************************************************************
519
 
 
520
 
    uint32_t curptr = 0, hwptr;
521
 
    uint32_t curbuf = 0;
522
 
    int empty = 0;
523
 
    i = 0;
524
 
 
525
 
 
526
 
    while (i < ITERATIONS) {
527
 
        j = 0;
528
 
        // printf("\ndesc0: %lx", htonl(desc[0])); 
529
 
        // printf("\ndesc1: %lx", htonl(desc[1])); 
530
 
        // printf("\ndesc2: %lx", htonl(desc[2])); 
531
 
        // printf("\ndesc3: %lx", htonl(desc[3])); 
532
 
        // printf("\ndesc4: %lx", htonl(desc[4]));
533
 
        // printf("\ndesc5: %lx", htonl(desc[5]));
534
 
        //printf("Iteration: %li of %li \r", i+1, ITERATIONS); 
535
 
        //loadBar(i+1, ITERATIONS, ITERATIONS, 30);
536
 
        // printf("\nhwptr: %zu", hwptr);  
537
 
        // printf("\ncurptr: %zu", curptr); 
538
 
 
539
 
        do {
540
 
#ifdef USE_64   
541
 
                hwptr = htonl(desc[3]);
542
 
#else // 32-bit
543
 
                hwptr = htonl(desc[4]);
544
 
#endif
545
 
        j++;    
546
 
        //printf("\rcurptr: %lx \t \t hwptr: %lx", curptr, hwptr);
547
 
        } while (hwptr == curptr);
548
 
 
549
 
        do {    
550
 
            pcilib_kmem_sync_block(pci, kbuf, PCILIB_KMEM_SYNC_FROMDEVICE, curbuf);
551
 
#ifdef CHECK_RESULTS   
552
 
            memcpy(temp_data[i][curbuf], ptr[curbuf], 4096);
553
 
#endif
554
 
#ifdef SHARED_MEMORY
555
 
            memcpy(shared_memory, ptr[curbuf], 4096); 
556
 
#endif            
557
 
            //printf("\ncurbuf: %08x", curbuf); 
558
 
            //printf("\nbus_addr[curbuf]\n: %08x",bus_addr[curbuf]);
559
 
            // for (k = 0; k < 63; k++){
560
 
            // if (k%16 == 0) printf("\n# %d # :", k);
561
 
            // printf(" %08x", ptr[curbuf][k]);
562
 
            // }
563
 
            //pcilib_kmem_sync_block(pci, kbuf, PCILIB_KMEM_SYNC_TODEVICE, curbuf);
564
 
            curbuf++;
565
 
            if (curbuf == BUFFERS) {
566
 
                i++;
567
 
                curbuf = 0;
568
 
#ifdef SWITCH_GENERATOR                 
569
 
                if (switch_generator == 1) {
570
 
                    switch_generator = 0;
571
 
                    WR(0x9040, 0x100007F0);
572
 
                } else {
573
 
                    WR(0x9040, 0x180007F0);
574
 
                    switch_generator = 1;
575
 
                }
576
 
#endif
577
 
                if (i >= ITERATIONS) break;
578
 
                //if (i >= (ITERATIONS - 4) ) WR(0x04, 0x0f); 
579
 
            }
580
 
        } while (bus_addr[curbuf] != hwptr);
581
 
 
582
 
#ifdef EXIT_ON_EMPTY
583
 
#ifdef USE_64                 
584
 
        if (desc[1] != 0) 
585
 
#else // 32bit  
586
 
        if (desc[2] != 0)  
587
 
#endif                                 
588
 
        {
589
 
            if (bus_addr[curbuf] == hwptr) {
590
 
                empty = 1;
591
 
                break;
592
 
            }
593
 
        }
594
 
#endif  
595
 
 
596
 
        WR(0x58, curbuf + 1); 
597
 
        //printf("WR %d\n", curbuf + 1); 
598
 
        //printf("%u (%lu)\n", curbuf, j);
599
 
        curptr = hwptr;
600
 
 
601
 
    }
602
 
    
603
 
 
604
 
 
605
 
    // ******************************************************************
606
 
    // **** Read performance and stop DMA                         *******
607
 
    // ******************************************************************
608
 
 
609
 
    gettimeofday(&end, NULL);
610
 
    WR(0x04, 0x00);
611
 
    WR(0x01, 0x00);
612
 
    RD(0x28, perf_counter);
613
 
 
614
 
 
615
 
 
616
 
    iterations_completed   = i;
617
 
    buffers_filled      = curbuf;
618
 
    if (empty) printf("* DMA: Empty FIFO! Last iteration: %li of %li\n", i+1, ITERATIONS);
619
 
    printf ("* DMA: Stop\n\n");
620
 
 
621
 
#ifdef CHECK_RESULTS
622
 
    printf ("First value:\t %08x\n", temp_data[0][0][0]);
623
 
    printf ("Last value:\t %08x\n\n", temp_data[ITERATIONS-1][BUFFERS-1][(PAGE_SIZE/4)-4]);
624
 
#endif
625
 
    
626
 
    // ******************************************************************
627
 
    // **** Performance                                           *******
628
 
    // ******************************************************************
629
 
    printf("Iterations done: %d\n", iterations_completed);
630
 
    printf("Buffers filled on last iteration: %d\n", buffers_filled);
631
 
 
632
 
 
633
 
    run_time = (end.tv_sec - start.tv_sec) * 1000000 + (end.tv_usec - start.tv_usec);
634
 
    size = (long long int) (( BUFFERS * (iterations_completed)  + buffers_filled) * HUGE_PAGE * PAGE_SIZE);
635
 
    size_mb = (long long int) (( BUFFERS * (iterations_completed)  + buffers_filled) * HUGE_PAGE * 4 / 1024);
636
 
    printf("Performance: transfered %zu Mbytes in %zu us using %d buffers\n", (size_mb), run_time, BUFFERS);
637
 
    //printf("Buffers: \t %d \n", BUFFERS);
638
 
    //printf("Buf_Size: \t %d \n", PAGE_SIZE);
639
 
    //printf("Perf_counter: \t %f \n", perf_counter);
640
 
    performance = ((size_mb * FPGA_CLOCK * 1000000)/(perf_counter*256));
641
 
    printf("DMA perf counter:\t%d\n", (int)perf_counter); 
642
 
    printf("DMA side:\t\t%.3lf MB/s\n", performance);  
643
 
    printf("PC side:\t\t%.3lf MB/s\n\n", 1000000. * size_mb / run_time );
644
 
 
645
 
    // ******************************************************************
646
 
    // **** Read Data                                             *******
647
 
    // ******************************************************************
648
 
 
649
 
 
650
 
    #ifdef PRINT_RESULTS
651
 
    printf("Writing Data to HDD... \n");
652
 
    for (i=0; i < iterations_completed; i++) {
653
 
        for (j=0; j < BUFFERS; j++)
654
 
        {
655
 
            Output = fopen("data.out", "a");
656
 
            fwrite(temp_data[i][j], 4096, 1, Output);
657
 
            fclose(Output);
658
 
        }   
659
 
        loadBar(i+1, ITERATIONS, ITERATIONS, 30);
660
 
    }
661
 
    // Save last partially filled iteration
662
 
    for (j=0; j < buffers_filled; j++)
663
 
    {
664
 
        Output = fopen("data.out", "a");
665
 
        fwrite(temp_data[iterations_completed][j], 4096, 1, Output);
666
 
        fclose(Output);
667
 
    }   
668
 
    printf("Data saved in data.out. \n");
669
 
    #endif
670
 
 
671
 
   #ifdef CHECK_RESULTS
672
 
    err = 0;
673
 
    error_log = fopen ("error_log.txt", "a");
674
 
    printf("\nChecking data ...\n");
675
 
    for (i=0; i < iterations_completed; i++) {
676
 
        for (j = 0; j < BUFFERS; j++) {
677
 
            for (k = 0; k < 1024 ; k++) 
678
 
            {
679
 
                mem_diff = ((uint32_t)temp_data[i][j][k] - (uint32_t)temp_data[i][j][k+1]);
680
 
                //if ((mem_diff == 1) || (mem_diff == (-7)) || (k == 1023) ) 
681
 
                if ((mem_diff == -1) || (k == 1023) ) 
682
 
                    {;}
683
 
                else {
684
 
                    fprintf(error_log, "Error in: \t IT %li \t BUF : %li \t OFFSET: %li \t | %08x --> %08x - DIFF: %d \n", i, j, k, temp_data[i][j][k], temp_data[i][j][k+1], mem_diff);
685
 
                    err++;
686
 
                }
687
 
            }
688
 
            if (j != BUFFERS-1) {
689
 
            // Check first and Last
690
 
                mem_diff = (uint32_t)(temp_data[i][j+1][0] - temp_data[i][j][1023]);
691
 
                if (mem_diff == (1)) 
692
 
                    {;}
693
 
                else {
694
 
                    fprintf(error_log, "Error_2 in: \t IT %li \t BUF : %li \t OFFSET: %li \t | %08x --> %08x - DIFF: %d \n", i, j, k, temp_data[i][j+1][0], temp_data[i][j][1023], mem_diff);
695
 
                    err++;
696
 
                }
697
 
            }
698
 
 
699
 
        }
700
 
        loadBar(i+1, ITERATIONS, ITERATIONS, 30);
701
 
    }
702
 
    for (j = 0; j < buffers_filled; j++) {
703
 
        for (k = 0; k < 1024 ; k++) 
704
 
        {
705
 
            mem_diff = ((uint32_t)temp_data[iterations_completed][j][k] - (uint32_t)temp_data[iterations_completed][j][k+1]);
706
 
                if ((mem_diff == -1) || (k == 1023) ) 
707
 
                {;}
708
 
            else {
709
 
                fprintf(error_log, "Error in: \t IT %li \t BUF : %li \t OFFSET: %li \t | %08x --> %08x - DIFF: %d \n", iterations_completed, j, k, temp_data[iterations_completed][j][k], temp_data[iterations_completed][j][k+1], mem_diff);
710
 
                err++;
711
 
            }
712
 
        }
713
 
        if (j != buffers_filled-1) {
714
 
        // Check first and Last
715
 
            mem_diff = (uint32_t)(temp_data[i][j+1][0] - temp_data[i][j][1023]);
716
 
            if (mem_diff == (1)) 
717
 
                {;}
718
 
            else {
719
 
                fprintf(error_log, "Error_2 in: \t IT %li \t BUF : %li \t OFFSET: %li \t | %08x --> %08x - DIFF: %d \n", iterations_completed, j, k, temp_data[iterations_completed][j+1][0], temp_data[iterations_completed][j][1023], mem_diff);
720
 
                err++;
721
 
            }
722
 
        }
723
 
    }
724
 
    if (err != 0) printf("\rChecking data: \xE2\x9C\x98 %d errors found  \n See \"error_log.txt\" for details \n\n", err);
725
 
    else printf("\rChecking data: \xE2\x9C\x93 no errors found  \n\n");
726
 
    fclose(error_log);
727
 
    #endif
728
 
 
729
 
 
730
 
    // *********** Free Memory
731
 
#ifdef CHECK_RESULTS
732
 
    for (i=0; i < ITERATIONS; i++) {
733
 
        for (j=0; j < BUFFERS; j++)
734
 
        {
735
 
            free(temp_data[i][j]);
736
 
        }
737
 
    }
738
 
#endif CHECK_RESULTS
739
 
 
740
 
    pcilib_free_kernel_memory(pci, kbuf,  free_flags);
741
 
    pcilib_free_kernel_memory(pci, kdesc,  free_flags);
742
 
    pcilib_disable_irq(pci, 0);
743
 
    pcilib_unmap_bar(pci, BAR, bar);
744
 
    pcilib_close(pci);
745
 
 
746
 
//    shmdt(shmid);
747
 
//    shmctl(shmid, IPC_RMID, NULL);
748
 
 
749
 
}