/alps/ipecamera

To get this branch, use:
bzr branch http://suren.me/webbzr/alps/ipecamera
277 by Suren A. Chilingaryan
Build RPM
1
#define _DEFAULT_SOURCE
126 by Suren A. Chilingaryan
multithread preprocessing of ipecamera frames and code reorganization
2
#define _BSD_SOURCE
3
#define _GNU_SOURCE
4
5
#include <stdio.h>
6
#include <stdlib.h>
7
#include <unistd.h>
8
#include <string.h>
9
#include <sys/time.h>
185 by Suren A. Chilingaryan
More fixes to frame separation in multiframe mode; debugging mode
10
#include <sys/stat.h>
11
#include <sys/types.h>
126 by Suren A. Chilingaryan
multithread preprocessing of ipecamera frames and code reorganization
12
#include <pthread.h>
13
#include <assert.h>
14
15
#include <ufodecode.h>
16
245 by Suren A. Chilingaryan
First stand-alone ipecamera implementation
17
#include <pcilib.h>
18
#include <pcilib/tools.h>
19
#include <pcilib/error.h>
276 by Suren A. Chilingaryan
Update to new version of pcitool
20
#include <pcilib/timing.h>
126 by Suren A. Chilingaryan
multithread preprocessing of ipecamera frames and code reorganization
21
162 by Suren A. Chilingaryan
UFO5 size estimation
22
#include "model.h"
126 by Suren A. Chilingaryan
multithread preprocessing of ipecamera frames and code reorganization
23
#include "private.h"
24
#include "reader.h"
25
274 by Suren A. Chilingaryan
Add another workaround to handle cameras stuck in busy (disabled and untested)
26
27
#define GET_REG(reg, var) \
28
    if (!err) { \
29
	err = pcilib_read_register_by_id(pcilib, ctx->reg, &var); \
30
	if (err) { \
31
	    pcilib_error("Error reading %s register", model_info->registers[ctx->reg].name); \
32
	} \
33
    }
34
35
#define SET_REG(reg, val) \
36
    if (!err) { \
37
	err = pcilib_write_register_by_id(pcilib, ctx->reg, val); \
38
	if (err) { \
39
	    pcilib_error("Error writting %s register", model_info->registers[ctx->reg].name); \
40
	} \
41
    }
42
275 by Suren A. Chilingaryan
Fix some warnings and add debugging information into the build
43
/*
44
#define CHECK_FRAME_MAGIC(buf) \
45
	memcmp(buf, ((void*)frame_magic) + 1, sizeof(frame_magic) - 1)
46
*/
261 by Suren A. Chilingaryan
Support for new CMOSIS 20MPix camera
47
48
#define CHECK_FRAME_MAGIC(buf) \
49
	memcmp(((ipecamera_payload_t*)(buf)) + 1, &frame_magic[1], sizeof(frame_magic) - sizeof(ipecamera_payload_t))
50
51
static ipecamera_payload_t frame_magic[3] = { 0x51111111, 0x52222222, 0x53333333 };
52
53
54
55
int ipecamera_compute_buffer_size(ipecamera_t *ctx, ipecamera_format_t format, size_t header_size, size_t lines) {
56
//    const size_t header_size = 8 * sizeof(ipecamera_payload_t);
57
    const size_t footer_size = CMOSIS_FRAME_TAIL_SIZE;
58
59
    size_t max_channels;
175 by Suren A. Chilingaryan
Support both UFO4 and UFO5 frame formats
60
    size_t line_size, raw_size, padded_blocks;
61
261 by Suren A. Chilingaryan
Support for new CMOSIS 20MPix camera
62
    switch (format) {
63
     case IPECAMERA_FORMAT_CMOSIS:
282 by Suren A. Chilingaryan
Support HighFlex-based ipecamera
64
     case IPECAMERA_FORMAT_CMOSIS20:
261 by Suren A. Chilingaryan
Support for new CMOSIS 20MPix camera
65
	max_channels = CMOSIS_MAX_CHANNELS;
282 by Suren A. Chilingaryan
Support HighFlex-based ipecamera
66
	line_size = ctx->data_line_size;
261 by Suren A. Chilingaryan
Support for new CMOSIS 20MPix camera
67
	break;
175 by Suren A. Chilingaryan
Support both UFO4 and UFO5 frame formats
68
     default:
261 by Suren A. Chilingaryan
Support for new CMOSIS 20MPix camera
69
	pcilib_warning("Unsupported version (%u) of frame format...", format);
70
	return PCILIB_ERROR_NOTSUPPORTED;
71
    }
72
73
    raw_size = lines * line_size;
74
    raw_size *= max_channels / ctx->cmosis_outputs;
75
    raw_size += header_size + footer_size;
248 by Suren A. Chilingaryan
Support CMOSIS bug resulting in missing payload
76
77
#ifdef IPECAMERA_BUG_MISSING_PAYLOAD
261 by Suren A. Chilingaryan
Support for new CMOSIS 20MPix camera
78
        // As I understand, the first 32-byte packet is missing, so we need to substract 32 (both CMOSIS and CMOSIS20)
79
    raw_size -= 32;
248 by Suren A. Chilingaryan
Support CMOSIS bug resulting in missing payload
80
#endif /* IPECAMERA_BUG_MISSING_PAYLOAD */
168 by Suren A. Chilingaryan
Support 12-bit modes
81
82
    padded_blocks = raw_size / IPECAMERA_DMA_PACKET_LENGTH + ((raw_size % IPECAMERA_DMA_PACKET_LENGTH)?1:0);
261 by Suren A. Chilingaryan
Support for new CMOSIS 20MPix camera
83
249 by Suren A. Chilingaryan
Simplify size tracking in the reader
84
    ctx->roi_raw_size = raw_size;
85
    ctx->roi_padded_size = padded_blocks * IPECAMERA_DMA_PACKET_LENGTH;
168 by Suren A. Chilingaryan
Support 12-bit modes
86
162 by Suren A. Chilingaryan
UFO5 size estimation
87
    return 0;
88
}
89
261 by Suren A. Chilingaryan
Support for new CMOSIS 20MPix camera
90
91
static int ipecamera_parse_header(ipecamera_t *ctx, ipecamera_payload_t *buf, size_t buf_size) {
282 by Suren A. Chilingaryan
Support HighFlex-based ipecamera
92
    int err;
261 by Suren A. Chilingaryan
Support for new CMOSIS 20MPix camera
93
    int last = buf[0] & 1;
94
    int version = (buf[0] >> 1) & 7;
95
    size_t size = 0, n_lines;
96
    ipecamera_format_t format = IPECAMERA_FORMAT_CMOSIS;
97
98
    switch (version) {
99
     case 0:
100
	n_lines = ((uint32_t*)buf)[5] & 0x7FF;
101
	ctx->frame[ctx->buffer_pos].event.info.seqnum = buf[6] & 0xFFFFFF;
102
	ctx->frame[ctx->buffer_pos].event.info.offset = (buf[7] & 0xFFFFFF) * 80;
103
	break;
104
     case 1:
105
	n_lines = ((uint32_t*)buf)[5] & 0xFFFF;
106
	if (!n_lines) {
107
	    pcilib_error("The frame header claims 0 lines in the data");
108
	    return 0;
109
	}
110
111
	ctx->frame[ctx->buffer_pos].event.info.seqnum = buf[6] & 0xFFFFFF;
112
	ctx->frame[ctx->buffer_pos].event.info.offset = (buf[7] & 0xFFFFFF) * 80;
113
	format = (buf[6] >> 24)&0x0F;
114
        break;
115
     default:
116
	ipecamera_debug(HARDWARE, "Incorrect version of the frame header, ignoring broken data...");
117
	return 0;
118
    }
119
    gettimeofday(&ctx->frame[ctx->buffer_pos].event.info.timestamp, NULL);
120
121
    ipecamera_debug(FRAME_HEADERS, "frame %lu: %x %x %x %x", ctx->frame[ctx->buffer_pos].event.info.seqnum, buf[0], buf[1], buf[2], buf[3]);
122
    ipecamera_debug(FRAME_HEADERS, "frame %lu: %x %x %x %x", ctx->frame[ctx->buffer_pos].event.info.seqnum, buf[4], buf[5], buf[6], buf[7]);
123
124
    while ((!last)&&((size + CMOSIS_FRAME_HEADER_SIZE) <= buf_size)) {
125
	size += CMOSIS_FRAME_HEADER_SIZE;
126
	last = buf[size] & 1;
127
    }
128
129
    size += CMOSIS_FRAME_HEADER_SIZE;
282 by Suren A. Chilingaryan
Support HighFlex-based ipecamera
130
131
    err = ipecamera_compute_buffer_size(ctx, format, size, n_lines);
132
    if (err) return 0;
261 by Suren A. Chilingaryan
Support for new CMOSIS 20MPix camera
133
134
	// Returns total size of found headers or 0 on the error
135
    return size;
136
}
137
138
126 by Suren A. Chilingaryan
multithread preprocessing of ipecamera frames and code reorganization
139
static inline int ipecamera_new_frame(ipecamera_t *ctx) {
140
    ctx->frame[ctx->buffer_pos].event.raw_size = ctx->cur_size;
141
249 by Suren A. Chilingaryan
Simplify size tracking in the reader
142
    if (ctx->cur_size < ctx->roi_raw_size) {
165 by Suren A. Chilingaryan
Minor fix for frame partitioning
143
	ctx->frame[ctx->buffer_pos].event.info.flags |= PCILIB_EVENT_INFO_FLAG_BROKEN;
144
    }
126 by Suren A. Chilingaryan
multithread preprocessing of ipecamera frames and code reorganization
145
    
146
    ctx->buffer_pos = (++ctx->event_id) % ctx->buffer_size;
147
    ctx->cur_size = 0;
148
149
    ctx->frame[ctx->buffer_pos].event.info.type = PCILIB_EVENT0;
150
    ctx->frame[ctx->buffer_pos].event.info.flags = 0;
151
    ctx->frame[ctx->buffer_pos].event.image_ready = 0;
152
153
    if ((ctx->event_id == ctx->autostop.evid)&&(ctx->event_id)) {
154
	ctx->run_reader = 0;
155
	return 1;
156
    }
157
	
245 by Suren A. Chilingaryan
First stand-alone ipecamera implementation
158
    if (pcilib_check_deadline(&ctx->autostop.timestamp, 0)) {
126 by Suren A. Chilingaryan
multithread preprocessing of ipecamera frames and code reorganization
159
	ctx->run_reader = 0;
160
	return 1;
161
    }
162
    
163
    return 0;
164
}
165
166
static int ipecamera_data_callback(void *user, pcilib_dma_flags_t flags, size_t bufsize, void *buf) {
167
    int res;
168
    int eof = 0;
251 by Suren A. Chilingaryan
Use pcitool debugging API
169
    
170
    static unsigned long packet_id = 0;
126 by Suren A. Chilingaryan
multithread preprocessing of ipecamera frames and code reorganization
171
172
#ifdef IPECAMERA_BUG_MULTIFRAME_PACKETS
143 by Suren A. Chilingaryan
Send padding data to rawdata_callback
173
    size_t real_size;
126 by Suren A. Chilingaryan
multithread preprocessing of ipecamera frames and code reorganization
174
    size_t extra_data = 0;
175
#endif /* IPECAMERA_BUG_MULTIFRAME_PACKETS */
240 by Suren A. Chilingaryan
Fix frame size computation in ipecamera and few debuging options
176
    
126 by Suren A. Chilingaryan
multithread preprocessing of ipecamera frames and code reorganization
177
    ipecamera_t *ctx = (ipecamera_t*)user;
178
184 by Suren A. Chilingaryan
Fix splitting of frames in case of MULTIFRAME_PACKETS camera bug
179
#if defined(IPECAMERA_BUG_INCOMPLETE_PACKETS)||defined(IPECAMERA_BUG_MULTIFRAME_PACKETS)
180
    static  pcilib_event_id_t invalid_frame_id = (pcilib_event_id_t)-1;
181
#endif
185 by Suren A. Chilingaryan
More fixes to frame separation in multiframe mode; debugging mode
182
251 by Suren A. Chilingaryan
Use pcitool debugging API
183
    packet_id++;
184
    ipecamera_debug_buffer(RAW_PACKETS, bufsize, buf, PCILIB_DEBUG_BUFFER_MKDIR, "frame%4lu/frame%9lu", ctx->event_id, packet_id);
185
126 by Suren A. Chilingaryan
multithread preprocessing of ipecamera frames and code reorganization
186
    if (!ctx->cur_size) {
267 by Suren A. Chilingaryan
Handle frame headers split between 2 packets
187
#ifdef IPECAMERA_BUG_MULTIFRAME_HEADERS
188
	if (ctx->saved_header_size) {
189
	    void *buf2 = alloca(ctx->saved_header_size + bufsize);
190
	    if (!buf2) {
191
		pcilib_error("Error allocating %zu bytes of memory in stack", ctx->saved_header_size + bufsize);
192
		return -PCILIB_ERROR_MEMORY;
193
	    }
194
	    memcpy(buf2, ctx->saved_header, ctx->saved_header_size);
195
	    memcpy(buf2 + ctx->saved_header_size, buf, bufsize);
196
197
	    buf = buf2;
198
	    bufsize += ctx->saved_header_size;
199
200
	    ctx->saved_header_size = 0;
201
	}
202
#endif /* IPECAMERA_BUG_MULTIFRAME_HEADERS */
203
126 by Suren A. Chilingaryan
multithread preprocessing of ipecamera frames and code reorganization
204
#if defined(IPECAMERA_BUG_INCOMPLETE_PACKETS)||defined(IPECAMERA_BUG_MULTIFRAME_PACKETS)
205
	size_t startpos;
267 by Suren A. Chilingaryan
Handle frame headers split between 2 packets
206
	for (startpos = 0; (startpos + CMOSIS_ENTITY_SIZE) <= bufsize; startpos += sizeof(ipecamera_payload_t)) {
261 by Suren A. Chilingaryan
Support for new CMOSIS 20MPix camera
207
	    if (!CHECK_FRAME_MAGIC(buf + startpos)) break;
182 by Suren A. Chilingaryan
Skip non-informative packets on DMA
208
	}
209
	
267 by Suren A. Chilingaryan
Handle frame headers split between 2 packets
210
	if ((startpos +  CMOSIS_ENTITY_SIZE) > bufsize) {
251 by Suren A. Chilingaryan
Use pcitool debugging API
211
	    ipecamera_debug_buffer(RAW_PACKETS, bufsize, NULL, 0, "frame%4lu/frame%9lu.invalid", ctx->event_id, packet_id);
184 by Suren A. Chilingaryan
Fix splitting of frames in case of MULTIFRAME_PACKETS camera bug
212
	    
213
	    if (invalid_frame_id != ctx->event_id) {
254 by Suren A. Chilingaryan
Report extra padding only if IPECAMERA_DEBUG_HARDWARE is set
214
		ipecamera_debug(HARDWARE, "No frame magic in DMA packet of %u bytes, current event %lu", bufsize, ctx->event_id);
184 by Suren A. Chilingaryan
Fix splitting of frames in case of MULTIFRAME_PACKETS camera bug
215
		invalid_frame_id = ctx->event_id;
216
	    }
217
218
	    return PCILIB_STREAMING_CONTINUE;
126 by Suren A. Chilingaryan
multithread preprocessing of ipecamera frames and code reorganization
219
	}
220
	
221
	if (startpos) {
143 by Suren A. Chilingaryan
Send padding data to rawdata_callback
222
		// pass padding to rawdata callback
223
	    if (ctx->event.params.rawdata.callback) {
224
		res = ctx->event.params.rawdata.callback(0, NULL, PCILIB_EVENT_FLAG_RAW_DATA_ONLY, startpos, buf, ctx->event.params.rawdata.user);
225
		if (res <= 0) {
226
		    if (res < 0) return res;
227
		    ctx->run_reader = 0;
228
		}
229
	    }
230
231
126 by Suren A. Chilingaryan
multithread preprocessing of ipecamera frames and code reorganization
232
	    buf += startpos;
233
	    bufsize -= startpos;
234
	}
235
#endif /* IPECAMERA_BUG_INCOMPLETE_PACKETS */
236
261 by Suren A. Chilingaryan
Support for new CMOSIS 20MPix camera
237
	if ((bufsize >= CMOSIS_FRAME_HEADER_SIZE)&&(!CHECK_FRAME_MAGIC(buf))) {
238
		// We should handle the case when multi-header is split between multiple DMA packets
239
	    if (!ipecamera_parse_header(ctx, buf, bufsize))
240
		return PCILIB_STREAMING_CONTINUE;
267 by Suren A. Chilingaryan
Handle frame headers split between 2 packets
241
242
#ifdef IPECAMERA_BUG_MULTIFRAME_HEADERS
243
	} else if ((bufsize >= CMOSIS_ENTITY_SIZE)&&(!CHECK_FRAME_MAGIC(buf))) {
244
	    memcpy(ctx->saved_header, buf, bufsize);
245
	    ctx->saved_header_size = bufsize;
246
	    return PCILIB_STREAMING_REQ_FRAGMENT;
247
#endif /* IPECAMERA_BUG_MULTIFRAME_HEADERS */
126 by Suren A. Chilingaryan
multithread preprocessing of ipecamera frames and code reorganization
248
	} else {
267 by Suren A. Chilingaryan
Handle frame headers split between 2 packets
249
	    ipecamera_debug(HARDWARE, "Frame magic is not found in the remaining DMA packet consisting of %u bytes, ignoring broken data...", bufsize);
126 by Suren A. Chilingaryan
multithread preprocessing of ipecamera frames and code reorganization
250
	    return PCILIB_STREAMING_CONTINUE;
251
	}
252
    }
253
254
#ifdef IPECAMERA_BUG_MULTIFRAME_PACKETS
143 by Suren A. Chilingaryan
Send padding data to rawdata_callback
255
	// for rawdata_callback with complete padding
256
    real_size = bufsize;
257
    
249 by Suren A. Chilingaryan
Simplify size tracking in the reader
258
    if (ctx->cur_size + bufsize > ctx->roi_raw_size) {
126 by Suren A. Chilingaryan
multithread preprocessing of ipecamera frames and code reorganization
259
        size_t need;
260
	
267 by Suren A. Chilingaryan
Handle frame headers split between 2 packets
261
	for (need = ctx->roi_raw_size - ctx->cur_size; (need + CMOSIS_ENTITY_SIZE) <= bufsize; need += sizeof(uint32_t)) {
261 by Suren A. Chilingaryan
Support for new CMOSIS 20MPix camera
262
	    if (!CHECK_FRAME_MAGIC(buf + need)) break;
126 by Suren A. Chilingaryan
multithread preprocessing of ipecamera frames and code reorganization
263
	}
264
	
267 by Suren A. Chilingaryan
Handle frame headers split between 2 packets
265
	if ((need + CMOSIS_ENTITY_SIZE) <= bufsize) {
126 by Suren A. Chilingaryan
multithread preprocessing of ipecamera frames and code reorganization
266
	    extra_data = bufsize - need;
267
	    eof = 1;
268
	}
240 by Suren A. Chilingaryan
Fix frame size computation in ipecamera and few debuging options
269
126 by Suren A. Chilingaryan
multithread preprocessing of ipecamera frames and code reorganization
270
	    // just rip of padding
249 by Suren A. Chilingaryan
Simplify size tracking in the reader
271
	bufsize = ctx->roi_raw_size - ctx->cur_size;
251 by Suren A. Chilingaryan
Use pcitool debugging API
272
	ipecamera_debug_buffer(RAW_PACKETS, bufsize, buf, 0, "frame%4lu/frame%9lu.partial", ctx->event_id, packet_id);
126 by Suren A. Chilingaryan
multithread preprocessing of ipecamera frames and code reorganization
273
    }
274
#endif /* IPECAMERA_BUG_MULTIFRAME_PACKETS */
275
276
    if (ctx->parse_data) {
249 by Suren A. Chilingaryan
Simplify size tracking in the reader
277
	if (ctx->cur_size + bufsize > ctx->padded_size) {
278
    	    pcilib_error("Unexpected event data, we are expecting at maximum (%zu) bytes, but (%zu) already read", ctx->padded_size, ctx->cur_size + bufsize);
126 by Suren A. Chilingaryan
multithread preprocessing of ipecamera frames and code reorganization
279
	    return -PCILIB_ERROR_TOOBIG;
280
	}
281
263 by Suren A. Chilingaryan
Add handling of a bug when IPECamera producing a dublicate 16 bytes at 4096 offset
282
	if (bufsize) {
283
#ifdef IPECAMERA_BUG_REPEATING_DATA
284
	    if ((bufsize > 16)&&(ctx->cur_size > 16)) {
285
		if (!memcmp(ctx->buffer + ctx->buffer_pos * ctx->padded_size +  ctx->cur_size - 16, buf, 16)) {
286
		    pcilib_warning("Skipping repeating bytes at offset %zu of frame %zu", ctx->cur_size, ctx->event_id);
287
		    buf += 16;
288
		    bufsize -=16;
289
		}
290
	    }
291
#endif /* IPECAMERA_BUG_REPEATING_DATA */
245 by Suren A. Chilingaryan
First stand-alone ipecamera implementation
292
	    memcpy(ctx->buffer + ctx->buffer_pos * ctx->padded_size +  ctx->cur_size, buf, bufsize);
263 by Suren A. Chilingaryan
Add handling of a bug when IPECamera producing a dublicate 16 bytes at 4096 offset
293
	}
126 by Suren A. Chilingaryan
multithread preprocessing of ipecamera frames and code reorganization
294
    }
295
296
    ctx->cur_size += bufsize;
297
249 by Suren A. Chilingaryan
Simplify size tracking in the reader
298
    if (ctx->cur_size >= ctx->roi_raw_size) {
239 by Suren A. Chilingaryan
ipecamera hack
299
	eof = 1;
300
    }
126 by Suren A. Chilingaryan
multithread preprocessing of ipecamera frames and code reorganization
301
302
    if (ctx->event.params.rawdata.callback) {
303
	res = ctx->event.params.rawdata.callback(ctx->event_id, (pcilib_event_info_t*)(ctx->frame + ctx->buffer_pos), (eof?PCILIB_EVENT_FLAG_EOF:PCILIB_EVENT_FLAGS_DEFAULT), bufsize, buf, ctx->event.params.rawdata.user);
304
	if (res <= 0) {
305
	    if (res < 0) return res;
306
	    ctx->run_reader = 0;
307
	}
308
    }
309
    
310
    if (eof) {
137 by Suren A. Chilingaryan
Stop reader thread on pcilib_stop
311
	if ((ipecamera_new_frame(ctx))||(!ctx->run_reader)) {
126 by Suren A. Chilingaryan
multithread preprocessing of ipecamera frames and code reorganization
312
	    return PCILIB_STREAMING_STOP;
313
	}
314
	
315
#ifdef IPECAMERA_BUG_MULTIFRAME_PACKETS
316
	if (extra_data) {
185 by Suren A. Chilingaryan
More fixes to frame separation in multiframe mode; debugging mode
317
	    return ipecamera_data_callback(user, flags, extra_data, buf + (real_size - extra_data));
126 by Suren A. Chilingaryan
multithread preprocessing of ipecamera frames and code reorganization
318
	}
319
#endif /* IPECAMERA_BUG_MULTIFRAME_PACKETS */
320
    }
321
322
    return PCILIB_STREAMING_REQ_FRAGMENT;
323
}
324
325
void *ipecamera_reader_thread(void *user) {
326
    int err;
327
    ipecamera_t *ctx = (ipecamera_t*)user;
274 by Suren A. Chilingaryan
Add another workaround to handle cameras stuck in busy (disabled and untested)
328
#ifdef IPECAMERA_BUG_STUCKED_BUSY
329
    pcilib_register_value_t saved, value;
330
    pcilib_t *pcilib = ctx->event.pcilib;
331
    const pcilib_model_description_t *model_info = pcilib_get_model_description(pcilib);
332
#endif /* IPECAMERA_BUG_STUCKED_BUSY */
333
126 by Suren A. Chilingaryan
multithread preprocessing of ipecamera frames and code reorganization
334
    while (ctx->run_reader) {
245 by Suren A. Chilingaryan
First stand-alone ipecamera implementation
335
	err = pcilib_stream_dma(ctx->event.pcilib, ctx->rdma, 0, 0, PCILIB_DMA_FLAG_MULTIPACKET, IPECAMERA_DMA_TIMEOUT, &ipecamera_data_callback, user);
126 by Suren A. Chilingaryan
multithread preprocessing of ipecamera frames and code reorganization
336
	if (err) {
337
	    if (err == PCILIB_ERROR_TIMEOUT) {
249 by Suren A. Chilingaryan
Simplify size tracking in the reader
338
		if (ctx->cur_size >= ctx->roi_raw_size) ipecamera_new_frame(ctx);
126 by Suren A. Chilingaryan
multithread preprocessing of ipecamera frames and code reorganization
339
#ifdef IPECAMERA_BUG_INCOMPLETE_PACKETS
340
		else if (ctx->cur_size > 0) ipecamera_new_frame(ctx);
341
#endif /* IPECAMERA_BUG_INCOMPLETE_PACKETS */
245 by Suren A. Chilingaryan
First stand-alone ipecamera implementation
342
		if (pcilib_check_deadline(&ctx->autostop.timestamp, 0)) {
126 by Suren A. Chilingaryan
multithread preprocessing of ipecamera frames and code reorganization
343
		    ctx->run_reader = 0;
344
		    break;
345
		}
274 by Suren A. Chilingaryan
Add another workaround to handle cameras stuck in busy (disabled and untested)
346
#ifdef IPECAMERA_BUG_STUCKED_BUSY
347
		GET_REG(status2_reg, value);
275 by Suren A. Chilingaryan
Fix some warnings and add debugging information into the build
348
		if ((!err)&&(value&0x2FFFFFFF)) {
274 by Suren A. Chilingaryan
Add another workaround to handle cameras stuck in busy (disabled and untested)
349
		    pcilib_warning("Camera stuck in busy, trying to recover...");
350
		    GET_REG(control_reg, saved);
282 by Suren A. Chilingaryan
Support HighFlex-based ipecamera
351
		    SET_REG(control_reg, IPECAMERA_IDLE|(saved&0xFFFF0000));
274 by Suren A. Chilingaryan
Add another workaround to handle cameras stuck in busy (disabled and untested)
352
		    while ((value&0x2FFFFFFF)&&(ctx->run_reader)) {
353
			usleep(IPECAMERA_NOFRAME_SLEEP);
354
		    }
355
		}
356
#endif /* IPECAMERA_BUG_STUCKED_BUSY */
126 by Suren A. Chilingaryan
multithread preprocessing of ipecamera frames and code reorganization
357
		usleep(IPECAMERA_NOFRAME_SLEEP);
358
	    } else pcilib_error("DMA error while reading IPECamera frames, error: %i", err);
252 by Suren A. Chilingaryan
Cleanup
359
	} 
126 by Suren A. Chilingaryan
multithread preprocessing of ipecamera frames and code reorganization
360
    }
361
    
362
    ctx->run_streamer = 0;
363
    
252 by Suren A. Chilingaryan
Cleanup
364
    if (ctx->cur_size)
365
	pcilib_info("partialy read frame after stop signal, %zu bytes in the buffer", ctx->cur_size);
126 by Suren A. Chilingaryan
multithread preprocessing of ipecamera frames and code reorganization
366
367
    return NULL;
368
}