/alps/pcitool

To get this branch, use:
bzr branch http://suren.me/webbzr/alps/pcitool
119 by Suren A. Chilingaryan
Initial support of event streaming in cli
1
#define _POSIX_C_SOURCE 200112L
126 by Suren A. Chilingaryan
multithread preprocessing of ipecamera frames and code reorganization
2
#define _GNU_SOURCE
119 by Suren A. Chilingaryan
Initial support of event streaming in cli
3
1 by Suren A. Chilingaryan
Initial import
4
#include <stdio.h>
5
#include <string.h>
6
#include <unistd.h>
7
#include <stdint.h>
7.1.1 by Suren A. Chilingaryan
Initial support of IPECamera protocol
8
#include <assert.h>
7.1.5 by Suren A. Chilingaryan
Support for FPGA registers
9
#include <ctype.h>
119 by Suren A. Chilingaryan
Initial support of event streaming in cli
10
#include <time.h>
126 by Suren A. Chilingaryan
multithread preprocessing of ipecamera frames and code reorganization
11
#include <sched.h>
7.1.1 by Suren A. Chilingaryan
Initial support of IPECamera protocol
12
#include <arpa/inet.h>
117 by Suren A. Chilingaryan
new event architecture, first trial
13
#include <sys/time.h>
7.1.1 by Suren A. Chilingaryan
Initial support of IPECamera protocol
14
236 by Suren A. Chilingaryan
Big redign of model structures
15
#include "pci.h"
7.1.1 by Suren A. Chilingaryan
Initial support of IPECamera protocol
16
#include "tools.h"
126 by Suren A. Chilingaryan
multithread preprocessing of ipecamera frames and code reorganization
17
#include "error.h"
7.1.1 by Suren A. Chilingaryan
Initial support of IPECamera protocol
18
7.1.5 by Suren A. Chilingaryan
Support for FPGA registers
19
int pcilib_isnumber(const char *str) {
20
    int i = 0;
21
    for (i = 0; str[i]; i++) 
22
	if (!isdigit(str[i])) return 0;
23
    return 1;
24
}
25
26
int pcilib_isxnumber(const char *str) {
27
    int i = 0;
12 by Suren A. Chilingaryan
Correctly detect hex numbers starting from 0x
28
    
29
    if ((str[0] == '0')&&((str[1] == 'x')||(str[1] == 'X'))) i += 2;
30
    
31
    for (; str[i]; i++) 
7.1.5 by Suren A. Chilingaryan
Support for FPGA registers
32
	if (!isxdigit(str[i])) return 0;
12 by Suren A. Chilingaryan
Correctly detect hex numbers starting from 0x
33
7.1.5 by Suren A. Chilingaryan
Support for FPGA registers
34
    return 1;
35
}
36
62 by Suren A. Chilingaryan
Suppport DMA modes in console application (not functional yet)
37
int pcilib_isnumber_n(const char *str, size_t len) {
38
    int i = 0;
39
    for (i = 0; (str[i])&&(i < len); i++) 
40
	if (!isdigit(str[i])) return 0;
41
    return 1;
42
}
43
44
int pcilib_isxnumber_n(const char *str, size_t len) {
45
    int i = 0;
46
    
47
    if ((len > 1)&&(str[0] == '0')&&((str[1] == 'x')||(str[1] == 'X'))) i += 2;
48
    
49
    for (; (str[i])&&(i < len); i++) 
50
	if (!isxdigit(str[i])) return 0;
51
52
    return 1;
53
}
54
7.1.5 by Suren A. Chilingaryan
Support for FPGA registers
55
7.1.1 by Suren A. Chilingaryan
Initial support of IPECamera protocol
56
uint16_t pcilib_swap16(uint16_t x) {
57
    return (((x<<8)&0xFFFF) | ((x>>8)&0xFFFF));
58
}
59
60
uint32_t pcilib_swap32(uint32_t x) {
61
    return ((x & 0xFF) << 24) | \
62
	((x & 0xFF00) << 8) | \
63
	((x & 0xFF0000) >> 8) | \
64
        ((x & 0xFF000000) >> 24); 
65
}
66
 
67
uint64_t pcilib_swap64(uint64_t x) {
68
    return (((uint64_t)(x) << 56) | \
69
        (((uint64_t)(x) << 40) & 0xff000000000000ULL) | \
70
        (((uint64_t)(x) << 24) & 0xff0000000000ULL) | \
71
        (((uint64_t)(x) << 8)  & 0xff00000000ULL) | \
72
        (((uint64_t)(x) >> 8)  & 0xff000000ULL) | \
73
        (((uint64_t)(x) >> 24) & 0xff0000ULL) | \
74
        (((uint64_t)(x) >> 40) & 0xff00ULL) | \
75
        ((uint64_t)(x)  >> 56));
76
}
77
78
void pcilib_swap(void *dst, void *src, size_t size, size_t n) {
79
    int i;
80
    switch (size) {
81
	case 1:
82
	    if (src != dst) memcpy(dst, src, n);
83
	break;
84
	case 2:
85
	    for (i = 0; i < n; i++) {
86
		((uint16_t*)dst)[i] = pcilib_swap16(((uint16_t*)src)[i]);
87
	    }    
88
	break;
89
	case 4:
90
	    for (i = 0; i < n; i++) {
91
		((uint32_t*)dst)[i] = pcilib_swap32(((uint32_t*)src)[i]);
92
	    }    
93
	break;
94
	case 8:
95
	    for (i = 0; i < n; i++) {
96
		((uint64_t*)dst)[i] = pcilib_swap64(((uint64_t*)src)[i]);
97
	    }    
98
	break;
99
	default:
100
	    pcilib_error("Invalid word size: %i", size);
101
    }
102
}
103
104
void *pcilib_memcpy8(void * dst, void const * src, size_t len) {
1 by Suren A. Chilingaryan
Initial import
105
    int i;
106
    for (i = 0; i < len; i++) ((char*)dst)[i] = ((char*)src)[i];
107
    return dst;
108
}
109
7.1.1 by Suren A. Chilingaryan
Initial support of IPECamera protocol
110
void *pcilib_memcpy32(void * dst, void const * src, size_t len) {
1 by Suren A. Chilingaryan
Initial import
111
    uint32_t * plDst = (uint32_t *) dst;
112
    uint32_t const * plSrc = (uint32_t const *) src;
113
114
    while (len >= 4) {
7.1.1 by Suren A. Chilingaryan
Initial support of IPECamera protocol
115
//        *plDst = ntohl(*plSrc);
116
	*plDst = *plSrc;
7 by Matthias Vogelgesang
Write LSB first and fix memory allocation bug
117
        plSrc++;
118
        plDst++;
1 by Suren A. Chilingaryan
Initial import
119
        len -= 4;
120
    }
121
122
    char * pcDst = (char *) plDst;
123
    char const * pcSrc = (char const *) plSrc;
124
125
    while (len--) {
126
        *pcDst++ = *pcSrc++;
127
    }
128
129
    return (dst);
130
} 
131
7.1.1 by Suren A. Chilingaryan
Initial support of IPECamera protocol
132
133
void *pcilib_memcpy64(void * dst, void const * src, size_t len) {
3 by Suren A. Chilingaryan
Print a bit more details
134
    uint64_t * plDst = (uint64_t *) dst;
135
    uint64_t const * plSrc = (uint64_t const *) src;
136
137
    while (len >= 8) {
138
        *plDst++ = *plSrc++;
4 by Suren A. Chilingaryan
Commented out unsuccesfull attempts to make 64 bit transfers
139
        len -= 8;
140
    }
141
142
    char * pcDst = (char *) plDst;
143
    char const * pcSrc = (char const *) plSrc;
144
145
    while (len--) {
146
        *pcDst++ = *pcSrc++;
147
    }
148
149
    return (dst);
150
} 
151
152
/*
153
void *memcpy128(void * dst, void const * src, size_t len) {
154
155
    long pos = - (len>>2);
156
    char * plDst = (char *) dst - 4 * pos;
157
    char const * plSrc = (char const *) src - 4 * pos;
158
159
    if (pos) {
160
        __asm__ __volatile__ (
161
            "1:						\n\t"
162
            "mov	(%0,%2,4), %%edi		\n\t"
163
            "mov	%%edi, (%1,%2,4)		\n\t"
164
            "inc	%2				\n\t"
165
            "jnz 	1b				\n\t"
166
	: 
167
	: "r" (plSrc), "r" (plDst), "r" (pos)
168
	: "%edi"
169
        );
170
    }
171
172
173
174
    long pos = - ((len>>4)<<4);
175
    char * plDst = (char *) dst - pos;
176
    char const * plSrc = (char const *) src - pos;
177
178
    if (pos) {
179
        __asm__ __volatile__ (
180
            "1:						\n\t"
181
//            "movdqa	(%0,%2), %%xmm0			\n\t"
182
            "mov	(%0,%2), %%esi			\n\t"
183
            "movd	%%esi, %%xmm0			\n\t"
184
            "mov	4(%0,%2), %%esi			\n\t"
185
            "movd	%%esi, %%xmm1			\n\t"
186
            "mov	8(%0,%2), %%esi			\n\t"
187
            "movd	%%esi, %%xmm2			\n\t"
188
            "mov	12(%0,%2), %%esi		\n\t"
189
            "movd	%%esi, %%xmm3			\n\t"
190
	    "pslldq	$4, %%xmm1			\n\t"
191
	    "por	%%xmm1, %%xmm0			\n\t"
192
	    "pslldq	$8, %%xmm2			\n\t"
193
	    "por	%%xmm2, %%xmm0			\n\t"
194
	    "pslldq	$12, %%xmm3			\n\t"
195
	    "por	%%xmm3, %%xmm0			\n\t"
196
	    
197
            "movntdq	%%xmm0, (%1,%2)			\n\t"
198
            "add	$16, %2				\n\t"
199
            "jnz 	1b				\n\t"
200
	: 
201
	: "r" (plSrc), "r" (plDst), "r" (pos)
202
	: "%rsi"
203
        );
204
    }
205
206
207
208
    len &= 0x3;
209
210
    char * pcDst = (char *) plDst;
211
    char const * pcSrc = (char const *) plSrc;
212
213
    while (len--) {
214
        *pcDst++ = *pcSrc++;
215
    }
216
217
    return (dst);
218
} 
219
*/
3 by Suren A. Chilingaryan
Print a bit more details
220
7.1.1 by Suren A. Chilingaryan
Initial support of IPECamera protocol
221
void *pcilib_datacpy32(void * dst, void const * src, uint8_t size, size_t n, pcilib_endianess_t endianess) {
222
    uint32_t * plDst = (uint32_t *) dst;
223
    uint32_t const * plSrc = (uint32_t const *) src;
224
16 by Suren A. Chilingaryan
Prototype of IPECamera image protocol
225
    int swap = 0;
34 by Suren A. Chilingaryan
A bit faster datacpy
226
227
    if (endianess) 
228
        swap = (endianess == PCILIB_BIG_ENDIAN)?(ntohs(1)!=1):(ntohs(1)==1);
7.1.1 by Suren A. Chilingaryan
Initial support of IPECamera protocol
229
230
    assert(size == 4);	// only 32 bit at the moment
231
34 by Suren A. Chilingaryan
A bit faster datacpy
232
    if (swap) {
233
        while (n > 0) {
234
            *plDst = ntohl(*plSrc);
235
            ++plSrc;
236
            ++plDst;
237
            --n;
238
        }
239
    } else {
240
        while (n > 0) {
241
            *plDst = *plSrc;
242
            ++plSrc;
243
            ++plDst;
244
            --n;
245
        }
7.1.1 by Suren A. Chilingaryan
Initial support of IPECamera protocol
246
    }
126 by Suren A. Chilingaryan
multithread preprocessing of ipecamera frames and code reorganization
247
248
    return dst;
7.1.1 by Suren A. Chilingaryan
Initial support of IPECamera protocol
249
} 
250
251
int pcilib_get_page_mask() {
1 by Suren A. Chilingaryan
Initial import
252
    int pagesize,pagemask,temp;
253
7.1.1 by Suren A. Chilingaryan
Initial support of IPECamera protocol
254
    pagesize = sysconf(_SC_PAGESIZE);
1 by Suren A. Chilingaryan
Initial import
255
256
    for( pagemask=0, temp = pagesize; temp != 1; ) {
257
	temp = (temp >> 1);
258
	pagemask = (pagemask << 1)+1;
259
    }
260
    return pagemask;
261
}
117 by Suren A. Chilingaryan
new event architecture, first trial
262
126 by Suren A. Chilingaryan
multithread preprocessing of ipecamera frames and code reorganization
263
int pcilib_get_cpu_count() {
264
    int err;
265
266
    int cpu_count;
267
    cpu_set_t mask;
268
269
    err = sched_getaffinity(getpid(), sizeof(mask), &mask);
270
    if (err) return 1;
271
272
#ifdef CPU_COUNT
273
    cpu_count = CPU_COUNT(&mask);
274
#else
275
    for (cpu_count = 0; cpu_count < CPU_SETSIZE; cpu_count++) {
276
	if (!CPU_ISSET(cpu_count, &mask)) break;
277
    }
278
#endif
279
280
    if (!cpu_count) cpu_count = PCILIB_DEFAULT_CPU_COUNT;
281
    return cpu_count;    
282
}
283
284
119 by Suren A. Chilingaryan
Initial support of event streaming in cli
285
int pcilib_add_timeout(struct timeval *tv, pcilib_timeout_t timeout) {
117 by Suren A. Chilingaryan
new event architecture, first trial
286
    tv->tv_usec += timeout%1000000;
287
    if (tv->tv_usec > 999999) {
288
	tv->tv_usec -= 1000000;
119 by Suren A. Chilingaryan
Initial support of event streaming in cli
289
	tv->tv_sec += 1 + timeout/1000000;
117 by Suren A. Chilingaryan
new event architecture, first trial
290
    } else {
119 by Suren A. Chilingaryan
Initial support of event streaming in cli
291
	tv->tv_sec += timeout/1000000;
117 by Suren A. Chilingaryan
new event architecture, first trial
292
    }
126 by Suren A. Chilingaryan
multithread preprocessing of ipecamera frames and code reorganization
293
294
    return 0;
119 by Suren A. Chilingaryan
Initial support of event streaming in cli
295
}
296
297
int pcilib_calc_deadline(struct timeval *tv, pcilib_timeout_t timeout) {
298
    gettimeofday(tv, NULL);
299
    pcilib_add_timeout(tv, timeout);
126 by Suren A. Chilingaryan
multithread preprocessing of ipecamera frames and code reorganization
300
117 by Suren A. Chilingaryan
new event architecture, first trial
301
    return 0;
302
}
303
119 by Suren A. Chilingaryan
Initial support of event streaming in cli
304
int pcilib_check_deadline(struct timeval *tve, pcilib_timeout_t timeout) {
117 by Suren A. Chilingaryan
new event architecture, first trial
305
    int64_t res;
306
    struct timeval tvs;
126 by Suren A. Chilingaryan
multithread preprocessing of ipecamera frames and code reorganization
307
117 by Suren A. Chilingaryan
new event architecture, first trial
308
    if (!tve->tv_sec) return 0;
126 by Suren A. Chilingaryan
multithread preprocessing of ipecamera frames and code reorganization
309
117 by Suren A. Chilingaryan
new event architecture, first trial
310
    gettimeofday(&tvs, NULL);
311
    res = ((tve->tv_sec - tvs.tv_sec)*1000000 + (tve->tv_usec - tvs.tv_usec));
119 by Suren A. Chilingaryan
Initial support of event streaming in cli
312
	// Hm... Some problems comparing signed and unsigned. So, sign check first
313
    if ((res < 0)||(res < timeout)) {
314
	return 1;
315
    }
117 by Suren A. Chilingaryan
new event architecture, first trial
316
317
    return 0;
318
}
319
119 by Suren A. Chilingaryan
Initial support of event streaming in cli
320
pcilib_timeout_t pcilib_calc_time_to_deadline(struct timeval *tve) {
117 by Suren A. Chilingaryan
new event architecture, first trial
321
    int64_t res;
322
    struct timeval tvs;
323
    
324
    gettimeofday(&tvs, NULL);
325
    res = ((tve->tv_sec - tvs.tv_sec)*1000000 + (tve->tv_usec - tvs.tv_usec));
326
    
327
    if (res < 0) return 0;
328
    return res;
329
}
119 by Suren A. Chilingaryan
Initial support of event streaming in cli
330
331
int pcilib_sleep_until_deadline(struct timeval *tv) {
332
    struct timespec wait;
333
    pcilib_timeout_t duration;
334
335
    duration = pcilib_calc_time_to_deadline(tv);
132 by Suren A. Chilingaryan
Minor fixes and improvements
336
    if (duration > 0) {
337
	wait.tv_sec = duration / 1000000;
338
	wait.tv_nsec = 1000 * (duration % 1000000);
339
	nanosleep(&wait, NULL);
340
    }
119 by Suren A. Chilingaryan
Initial support of event streaming in cli
341
342
    return 0;
343
}
344
122 by Suren A. Chilingaryan
Gathering a bit of statistics
345
pcilib_timeout_t pcilib_timediff(struct timeval *tvs, struct timeval *tve) {
346
    return ((tve->tv_sec - tvs->tv_sec)*1000000 + (tve->tv_usec - tvs->tv_usec));
347
}
348
119 by Suren A. Chilingaryan
Initial support of event streaming in cli
349
int pcilib_timecmp(struct timeval *tv1, struct timeval *tv2) {
350
    if (tv1->tv_sec > tv2->tv_sec) return 1;
139 by Suren A. Chilingaryan
Fix errors preventing time-limited grabbing
351
    else if (tv1->tv_sec < tv2->tv_sec) return -1;
119 by Suren A. Chilingaryan
Initial support of event streaming in cli
352
    else if (tv1->tv_usec > tv2->tv_usec) return 1;
353
    else if (tv1->tv_usec < tv2->tv_usec) return -1;
354
    return 0;
355
}