/alps/ipecamera

To get this branch, use:
bzr branch http://suren.me/webbzr/alps/ipecamera
15 by Suren A. Chilingaryan
Infrastructure for event API
1
#define _IPECAMERA_IMAGE_C
277 by Suren A. Chilingaryan
Build RPM
2
#define _DEFAULT_SOURCE
15 by Suren A. Chilingaryan
Infrastructure for event API
3
#define _BSD_SOURCE
126 by Suren A. Chilingaryan
multithread preprocessing of ipecamera frames and code reorganization
4
#define _GNU_SOURCE
15 by Suren A. Chilingaryan
Infrastructure for event API
5
6
#include <stdio.h>
7
#include <stdlib.h>
8
#include <unistd.h>
9
#include <string.h>
10
#include <sys/time.h>
117 by Suren A. Chilingaryan
new event architecture, first trial
11
#include <pthread.h>
15 by Suren A. Chilingaryan
Infrastructure for event API
12
#include <assert.h>
13
124 by Suren A. Chilingaryan
Image frames decoding
14
#include <ufodecode.h>
15
245 by Suren A. Chilingaryan
First stand-alone ipecamera implementation
16
#include <pcilib.h>
17
#include <pcilib/tools.h>
18
#include <pcilib/error.h>
19
#include <pcilib/event.h>
276 by Suren A. Chilingaryan
Update to new version of pcitool
20
#include <pcilib/cpu.h>
21
#include <pcilib/timing.h>
15 by Suren A. Chilingaryan
Infrastructure for event API
22
126 by Suren A. Chilingaryan
multithread preprocessing of ipecamera frames and code reorganization
23
#include "private.h"
15 by Suren A. Chilingaryan
Infrastructure for event API
24
#include "model.h"
126 by Suren A. Chilingaryan
multithread preprocessing of ipecamera frames and code reorganization
25
#include "reader.h"
26
#include "events.h"
27
#include "data.h"
15 by Suren A. Chilingaryan
Infrastructure for event API
28
70 by Suren A. Chilingaryan
Support modifications of DMA engine and allow DMA customizations by Event engine
29
15 by Suren A. Chilingaryan
Infrastructure for event API
30
#define FIND_REG(var, bank, name)  \
31
        ctx->var = pcilib_find_register(pcilib, bank, name); \
32
	if (ctx->var ==  PCILIB_REGISTER_INVALID) { \
16 by Suren A. Chilingaryan
Prototype of IPECamera image protocol
33
	    err = PCILIB_ERROR_NOTFOUND; \
15 by Suren A. Chilingaryan
Infrastructure for event API
34
	    pcilib_error("Unable to find a %s register", name); \
35
	}
36
    
37
38
#define GET_REG(reg, var) \
93 by root
DMA support in IPE Camera
39
    if (!err) { \
40
	err = pcilib_read_register_by_id(pcilib, ctx->reg, &var); \
41
	if (err) { \
245 by Suren A. Chilingaryan
First stand-alone ipecamera implementation
42
	    pcilib_error("Error reading %s register", model_info->registers[ctx->reg].name); \
93 by root
DMA support in IPE Camera
43
	} \
15 by Suren A. Chilingaryan
Infrastructure for event API
44
    }
45
46
#define SET_REG(reg, val) \
93 by root
DMA support in IPE Camera
47
    if (!err) { \
48
	err = pcilib_write_register_by_id(pcilib, ctx->reg, val); \
49
	if (err) { \
245 by Suren A. Chilingaryan
First stand-alone ipecamera implementation
50
	    pcilib_error("Error writting %s register", model_info->registers[ctx->reg].name); \
93 by root
DMA support in IPE Camera
51
	} \
52
    }
15 by Suren A. Chilingaryan
Infrastructure for event API
53
54
#define CHECK_REG(reg, check) \
16 by Suren A. Chilingaryan
Prototype of IPECamera image protocol
55
    if (!err) { \
56
	err = pcilib_read_register_by_id(pcilib, ctx->reg, &value); \
57
	if (err) { \
245 by Suren A. Chilingaryan
First stand-alone ipecamera implementation
58
	    pcilib_error("Error reading %s register", model_info->registers[ctx->reg].name); \
16 by Suren A. Chilingaryan
Prototype of IPECamera image protocol
59
	} \
171 by Suren A. Chilingaryan
Fix temperature register of ipecamera and prepend all cmosis registers with _cmosis prefix
60
	if (value != check) { \
245 by Suren A. Chilingaryan
First stand-alone ipecamera implementation
61
	    pcilib_error("Unexpected value (0x%lx) of register %s", value, model_info->registers[ctx->reg].name); \
16 by Suren A. Chilingaryan
Prototype of IPECamera image protocol
62
	    err = PCILIB_ERROR_INVALID_DATA; \
63
	} \
64
    }
65
245 by Suren A. Chilingaryan
First stand-alone ipecamera implementation
66
#define CHECK_STATUS()
67
	    //CHECK_REG(status_reg, IPECAMERA_GET_EXPECTED_STATUS(ctx))
175 by Suren A. Chilingaryan
Support both UFO4 and UFO5 frame formats
68
16 by Suren A. Chilingaryan
Prototype of IPECamera image protocol
69
#define CHECK_VALUE(value, val) \
70
    if ((!err)&&(value != val)) { \
35 by Suren A. Chilingaryan
Multiline grabbing
71
	pcilib_error("Unexpected value (0x%x) in data stream (0x%x is expected)", value, val); \
16 by Suren A. Chilingaryan
Prototype of IPECamera image protocol
72
	err = PCILIB_ERROR_INVALID_DATA; \
73
    }
74
75
#define CHECK_FLAG(flag, check, ...) \
76
    if ((!err)&&(!(check))) { \
35 by Suren A. Chilingaryan
Multiline grabbing
77
	pcilib_error("Unexpected value (0x%x) of " flag,  __VA_ARGS__); \
16 by Suren A. Chilingaryan
Prototype of IPECamera image protocol
78
	err = PCILIB_ERROR_INVALID_DATA; \
15 by Suren A. Chilingaryan
Infrastructure for event API
79
    }
80
265 by Suren A. Chilingaryan
Use new locking subsystem to ensure integrity
81
#define LOCK(lock_name) \
82
    err = pcilib_try_lock(ctx->lock_name##_lock); \
83
    if (err) { \
84
	pcilib_error("IPECamera is busy"); \
85
	return PCILIB_ERROR_BUSY; \
86
    } \
87
    ctx->lock_name##_locked = 1;
88
89
#define UNLOCK(lock_name) \
90
    if (ctx->lock_name##_locked) { \
91
	pcilib_unlock(ctx->lock_name##_lock); \
92
	ctx->lock_name##_locked = 0; \
93
    }
15 by Suren A. Chilingaryan
Infrastructure for event API
94
31 by Suren A. Chilingaryan
Introduce pcilib_context_t type instead pointer to void
95
pcilib_context_t *ipecamera_init(pcilib_t *pcilib) {
15 by Suren A. Chilingaryan
Infrastructure for event API
96
    int err = 0; 
97
    
245 by Suren A. Chilingaryan
First stand-alone ipecamera implementation
98
    const pcilib_model_description_t *model_info = pcilib_get_model_description(pcilib);
99
15 by Suren A. Chilingaryan
Infrastructure for event API
100
    ipecamera_t *ctx = malloc(sizeof(ipecamera_t));
101
102
    if (ctx) {
178 by Suren A. Chilingaryan
Detect firmware version during initialization
103
	pcilib_register_value_t value;
104
	
16 by Suren A. Chilingaryan
Prototype of IPECamera image protocol
105
	memset(ctx, 0, sizeof(ipecamera_t));
178 by Suren A. Chilingaryan
Detect firmware version during initialization
106
265 by Suren A. Chilingaryan
Use new locking subsystem to ensure integrity
107
	ctx->run_lock = pcilib_get_lock(pcilib, PCILIB_LOCK_FLAGS_DEFAULT, "ipecamera");
108
	ctx->stream_lock = pcilib_get_lock(pcilib, PCILIB_LOCK_FLAGS_DEFAULT, "ipecamera/stream");
109
	ctx->trigger_lock = pcilib_get_lock(pcilib, PCILIB_LOCK_FLAGS_DEFAULT, "ipecamera/trigger");
110
111
	if (!ctx->run_lock||!ctx->stream_lock||!ctx->trigger_lock) {
112
	    free(ctx);
113
	    pcilib_error("Failed to initialize locks to protect ipecamera operation");
114
	    return NULL;
115
	}
116
272 by Suren A. Chilingaryan
Adjust buffer sizes to reduce memory consumption with CMOSIS20 camera
117
	ctx->dim.bpp = sizeof(ipecamera_pixel_t) * 8;
16 by Suren A. Chilingaryan
Prototype of IPECamera image protocol
118
	ctx->buffer_size = IPECAMERA_DEFAULT_BUFFER_SIZE;
252 by Suren A. Chilingaryan
Cleanup
119
15 by Suren A. Chilingaryan
Infrastructure for event API
120
	FIND_REG(status_reg, "fpga", "status");
121
	FIND_REG(control_reg, "fpga", "control");
132 by Suren A. Chilingaryan
Minor fixes and improvements
122
240 by Suren A. Chilingaryan
Fix frame size computation in ipecamera and few debuging options
123
	FIND_REG(status2_reg, "fpga", "status2");
132 by Suren A. Chilingaryan
Minor fixes and improvements
124
	FIND_REG(status3_reg, "fpga", "status3");
15 by Suren A. Chilingaryan
Infrastructure for event API
125
175 by Suren A. Chilingaryan
Support both UFO4 and UFO5 frame formats
126
	FIND_REG(firmware_version_reg, "fpga", "firmware_version");
168 by Suren A. Chilingaryan
Support 12-bit modes
127
	FIND_REG(adc_resolution_reg, "fpga", "adc_resolution");
128
	FIND_REG(output_mode_reg, "fpga", "output_mode");
174 by Suren A. Chilingaryan
Check for free space in camera DDR buffer before triggering event
129
	
130
	FIND_REG(max_frames_reg, "fpga", "ddr_max_frames");
131
	FIND_REG(num_frames_reg, "fpga", "ddr_num_frames");
117 by Suren A. Chilingaryan
new event architecture, first trial
132
178 by Suren A. Chilingaryan
Detect firmware version during initialization
133
	GET_REG(firmware_version_reg, value);
134
	switch (value) {
261 by Suren A. Chilingaryan
Support for new CMOSIS 20MPix camera
135
	 case IPECAMERA_FIRMWARE_UFO5:
178 by Suren A. Chilingaryan
Detect firmware version during initialization
136
	    ctx->firmware = value;
276 by Suren A. Chilingaryan
Update to new version of pcitool
137
	    err = pcilib_add_registers(pcilib, 0, 0, cmosis_registers, NULL);
260 by Suren A. Chilingaryan
Support registers of CMOSIS20000 camera
138
	    break;
261 by Suren A. Chilingaryan
Support for new CMOSIS 20MPix camera
139
	 case IPECAMERA_FIRMWARE_CMOSIS20:
260 by Suren A. Chilingaryan
Support registers of CMOSIS20000 camera
140
	    ctx->firmware = value;
272 by Suren A. Chilingaryan
Adjust buffer sizes to reduce memory consumption with CMOSIS20 camera
141
	    ctx->buffer_size = IPECAMERA_DEFAULT_CMOSIS20_BUFFER_SIZE;
276 by Suren A. Chilingaryan
Update to new version of pcitool
142
	    err = pcilib_add_registers(pcilib, 0, 0, cmosis20000_registers, NULL);
178 by Suren A. Chilingaryan
Detect firmware version during initialization
143
	    break;
144
	 default:
261 by Suren A. Chilingaryan
Support for new CMOSIS 20MPix camera
145
	    ctx->firmware = IPECAMERA_FIRMWARE_UNKNOWN;
245 by Suren A. Chilingaryan
First stand-alone ipecamera implementation
146
    	    pcilib_warning("Unsupported version of firmware (%lu)", value);
178 by Suren A. Chilingaryan
Detect firmware version during initialization
147
	}
148
260 by Suren A. Chilingaryan
Support registers of CMOSIS20000 camera
149
//	FIND_REG(n_lines_reg, "cmosis", "cmosis_number_lines"); // cmosis_number_lines_single v.6 ?
150
//	FIND_REG(line_reg, "cmosis", "cmosis_start1"); // cmosis_start_single v.6 ?
151
//	FIND_REG(exposure_reg, "cmosis", "cmosis_exp_time");
152
//	FIND_REG(flip_reg, "cmosis", "cmosis_image_flipping");
153
154
252 by Suren A. Chilingaryan
Cleanup
155
#ifdef IPECAMERA_ADJUST_BUFFER_SIZE 
185 by Suren A. Chilingaryan
More fixes to frame separation in multiframe mode; debugging mode
156
	GET_REG(max_frames_reg, value);
187 by Suren A. Chilingaryan
Consider RESERVE_BUFFERS while computing buffer size required for ipecamera fast reject
157
	if ((value + IPECAMERA_RESERVE_BUFFERS + 3) > ctx->buffer_size) {
252 by Suren A. Chilingaryan
Cleanup
158
	    int val, bits = 0;
187 by Suren A. Chilingaryan
Consider RESERVE_BUFFERS while computing buffer size required for ipecamera fast reject
159
	    ctx->buffer_size = (value + 1) + IPECAMERA_RESERVE_BUFFERS + 2;
252 by Suren A. Chilingaryan
Cleanup
160
	    for (val = ctx->buffer_size; val; val = val >> 1) bits++;
161
	    ctx->buffer_size = 1 << bits; 
185 by Suren A. Chilingaryan
More fixes to frame separation in multiframe mode; debugging mode
162
	}
252 by Suren A. Chilingaryan
Cleanup
163
#endif /* IPECAMERA_ADJUST_BUFFER_SIZE */
185 by Suren A. Chilingaryan
More fixes to frame separation in multiframe mode; debugging mode
164
165
93 by root
DMA support in IPE Camera
166
	ctx->rdma = PCILIB_DMA_ENGINE_INVALID;
167
15 by Suren A. Chilingaryan
Infrastructure for event API
168
	if (err) {
169
	    free(ctx);
170
	    return NULL;
171
	}
172
    }
173
    
43 by root
Enumerate DMA engines
174
    return (pcilib_context_t*)ctx;
15 by Suren A. Chilingaryan
Infrastructure for event API
175
}
176
31 by Suren A. Chilingaryan
Introduce pcilib_context_t type instead pointer to void
177
void ipecamera_free(pcilib_context_t *vctx) {
15 by Suren A. Chilingaryan
Infrastructure for event API
178
    if (vctx) {
179
	ipecamera_t *ctx = (ipecamera_t*)vctx;
117 by Suren A. Chilingaryan
new event architecture, first trial
180
	ipecamera_stop(vctx, PCILIB_EVENT_FLAGS_DEFAULT);
265 by Suren A. Chilingaryan
Use new locking subsystem to ensure integrity
181
182
	if (ctx->trigger_lock)
183
	    pcilib_return_lock(vctx->pcilib, PCILIB_LOCK_FLAGS_DEFAULT, ctx->trigger_lock);
184
185
	if (ctx->stream_lock)
186
	    pcilib_return_lock(vctx->pcilib, PCILIB_LOCK_FLAGS_DEFAULT, ctx->stream_lock);
187
	
188
	if (ctx->run_lock)
189
	    pcilib_return_lock(vctx->pcilib, PCILIB_LOCK_FLAGS_DEFAULT, ctx->run_lock);
190
15 by Suren A. Chilingaryan
Infrastructure for event API
191
	free(ctx);
192
    }
193
}
194
70 by Suren A. Chilingaryan
Support modifications of DMA engine and allow DMA customizations by Event engine
195
pcilib_dma_context_t *ipecamera_init_dma(pcilib_context_t *vctx) {
223 by Suren A. Chilingaryan
Merge changes from xilinx_dma branch providing support of multipage kmem allocations and mapping memory regions reserved with memmap boot option
196
    ipecamera_t *ctx = (ipecamera_t*)vctx;
70 by Suren A. Chilingaryan
Support modifications of DMA engine and allow DMA customizations by Event engine
197
    
245 by Suren A. Chilingaryan
First stand-alone ipecamera implementation
198
    const pcilib_model_description_t *model_info = pcilib_get_model_description(vctx->pcilib);
199
    if ((!model_info->dma)||(!model_info->dma->api)||(!model_info->dma->api->init)) {
70 by Suren A. Chilingaryan
Support modifications of DMA engine and allow DMA customizations by Event engine
200
	pcilib_error("The DMA engine is not configured in model");
201
	return NULL;
202
    }
89 by Suren A. Chilingaryan
Few fixes for IPE Camera modification
203
223 by Suren A. Chilingaryan
Merge changes from xilinx_dma branch providing support of multipage kmem allocations and mapping memory regions reserved with memmap boot option
204
    if (ctx->firmware) {
276 by Suren A. Chilingaryan
Update to new version of pcitool
205
	return model_info->dma->api->init(vctx->pcilib, "ipecamera", NULL);
223 by Suren A. Chilingaryan
Merge changes from xilinx_dma branch providing support of multipage kmem allocations and mapping memory regions reserved with memmap boot option
206
    } else {
245 by Suren A. Chilingaryan
First stand-alone ipecamera implementation
207
	return model_info->dma->api->init(vctx->pcilib, "pci", NULL);
223 by Suren A. Chilingaryan
Merge changes from xilinx_dma branch providing support of multipage kmem allocations and mapping memory regions reserved with memmap boot option
208
    }
70 by Suren A. Chilingaryan
Support modifications of DMA engine and allow DMA customizations by Event engine
209
}
210
211
17 by Suren A. Chilingaryan
Allow access to implementation context and provide call to set size of internal buffer for IPECamera
212
int ipecamera_set_buffer_size(ipecamera_t *ctx, int size) {
213
    if (ctx->started) {
214
	pcilib_error("Can't change buffer size while grabbing");
215
	return PCILIB_ERROR_INVALID_REQUEST;
216
    }
217
    
117 by Suren A. Chilingaryan
new event architecture, first trial
218
    if (size < 2) {
17 by Suren A. Chilingaryan
Allow access to implementation context and provide call to set size of internal buffer for IPECamera
219
	pcilib_error("The buffer size is too small");
220
	return PCILIB_ERROR_INVALID_REQUEST;
221
    }
117 by Suren A. Chilingaryan
new event architecture, first trial
222
    
250 by Suren A. Chilingaryan
Added a small grabbing example
223
    if ((size^(size-1)) < size) {
117 by Suren A. Chilingaryan
new event architecture, first trial
224
	pcilib_error("The buffer size is not power of 2");
225
    }
226
    
17 by Suren A. Chilingaryan
Allow access to implementation context and provide call to set size of internal buffer for IPECamera
227
    ctx->buffer_size = size;
228
    
229
    return 0;
230
}
231
31 by Suren A. Chilingaryan
Introduce pcilib_context_t type instead pointer to void
232
int ipecamera_reset(pcilib_context_t *vctx) {
117 by Suren A. Chilingaryan
new event architecture, first trial
233
    int err = 0;
15 by Suren A. Chilingaryan
Infrastructure for event API
234
    ipecamera_t *ctx = (ipecamera_t*)vctx;
117 by Suren A. Chilingaryan
new event architecture, first trial
235
    pcilib_t *pcilib = vctx->pcilib;
15 by Suren A. Chilingaryan
Infrastructure for event API
236
237
    pcilib_register_t control, status;
238
    pcilib_register_value_t value;
27 by Suren A. Chilingaryan
Set correct hexdecimal values of registers during IPECamera reset and readout (I was setting them as decimals before)
239
15 by Suren A. Chilingaryan
Infrastructure for event API
240
    if (!ctx) {
241
	pcilib_error("IPECamera imaging is not initialized");
242
	return PCILIB_ERROR_NOTINITIALIZED;
243
    }
223 by Suren A. Chilingaryan
Merge changes from xilinx_dma branch providing support of multipage kmem allocations and mapping memory regions reserved with memmap boot option
244
    
117 by Suren A. Chilingaryan
new event architecture, first trial
245
    pcilib = vctx->pcilib;
15 by Suren A. Chilingaryan
Infrastructure for event API
246
    control = ctx->control_reg;
247
    status = ctx->status_reg;
248
265 by Suren A. Chilingaryan
Use new locking subsystem to ensure integrity
249
    LOCK(run);
250
251
    ipecamera_debug(API, "ipecamera: starting");
252
253
    if (ctx->firmware == IPECAMERA_FIRMWARE_UFO5) {
254
	    // Set Reset bit to CMOSIS
255
	err = pcilib_write_register_by_id(pcilib, control, 0x1e4);
256
	if (err) {
257
	    UNLOCK(run);
258
	    pcilib_error("Error setting FPGA reset bit");
259
	    return err;
260
	}
261
	usleep(IPECAMERA_CMOSIS_RESET_DELAY);
15 by Suren A. Chilingaryan
Infrastructure for event API
262
263
	// Remove Reset bit to CMOSIS
265 by Suren A. Chilingaryan
Use new locking subsystem to ensure integrity
264
	err = pcilib_write_register_by_id(pcilib, control, 0x1e1);
265
	if (err) {
266
	    UNLOCK(run);
267
	    pcilib_error("Error reseting FPGA reset bit");
268
	    return err;
269
	}
270
	usleep(IPECAMERA_CMOSIS_REGISTER_DELAY);
15 by Suren A. Chilingaryan
Infrastructure for event API
271
272
	// Special settings for CMOSIS v.2
265 by Suren A. Chilingaryan
Use new locking subsystem to ensure integrity
273
	value = 01; err = pcilib_write_register_space(pcilib, "cmosis", 115, 1, &value);
274
	if (err) {
275
	    UNLOCK(run);
276
	    pcilib_error("Error setting CMOSIS configuration");
277
	    return err;
278
	}
279
	usleep(IPECAMERA_CMOSIS_REGISTER_DELAY);
27 by Suren A. Chilingaryan
Set correct hexdecimal values of registers during IPECamera reset and readout (I was setting them as decimals before)
280
265 by Suren A. Chilingaryan
Use new locking subsystem to ensure integrity
281
	value = 07; err = pcilib_write_register_space(pcilib, "cmosis", 82, 1, &value);
282
	if (err) {
283
	    UNLOCK(run);
284
	    pcilib_error("Error setting CMOSIS configuration");
285
	    return err;
286
	}
287
	usleep(IPECAMERA_CMOSIS_REGISTER_DELAY);
288
	pcilib_warning("Reset procedure is not complete");
289
    } else {
290
	pcilib_warning("Reset procedure is not implemented");
15 by Suren A. Chilingaryan
Infrastructure for event API
291
    }
292
39 by root
Move to new FPGA design
293
    usleep(10000);
117 by Suren A. Chilingaryan
new event architecture, first trial
294
245 by Suren A. Chilingaryan
First stand-alone ipecamera implementation
295
296
    CHECK_STATUS();
15 by Suren A. Chilingaryan
Infrastructure for event API
297
    if (err) {
245 by Suren A. Chilingaryan
First stand-alone ipecamera implementation
298
	err = pcilib_read_register_by_id(pcilib, status, &value);
299
265 by Suren A. Chilingaryan
Use new locking subsystem to ensure integrity
300
	UNLOCK(run);
245 by Suren A. Chilingaryan
First stand-alone ipecamera implementation
301
	if (err) pcilib_error("Error reading status register");
302
	else pcilib_error("Camera returns unexpected status (status: %lx)", value);
303
15 by Suren A. Chilingaryan
Infrastructure for event API
304
	return PCILIB_ERROR_VERIFY;
305
    }
306
265 by Suren A. Chilingaryan
Use new locking subsystem to ensure integrity
307
    err = pcilib_skip_dma(vctx->pcilib, ctx->rdma);
308
    UNLOCK(run);
309
310
    ipecamera_debug(API, "ipecamera: reset done");
311
    return err;
15 by Suren A. Chilingaryan
Infrastructure for event API
312
}
313
117 by Suren A. Chilingaryan
new event architecture, first trial
314
315
int ipecamera_start(pcilib_context_t *vctx, pcilib_event_t event_mask, pcilib_event_flags_t flags) {
126 by Suren A. Chilingaryan
multithread preprocessing of ipecamera frames and code reorganization
316
    int i;
16 by Suren A. Chilingaryan
Prototype of IPECamera image protocol
317
    int err = 0;
245 by Suren A. Chilingaryan
First stand-alone ipecamera implementation
318
15 by Suren A. Chilingaryan
Infrastructure for event API
319
    ipecamera_t *ctx = (ipecamera_t*)vctx;
117 by Suren A. Chilingaryan
new event architecture, first trial
320
    pcilib_t *pcilib = vctx->pcilib;
35 by Suren A. Chilingaryan
Multiline grabbing
321
    pcilib_register_value_t value;
117 by Suren A. Chilingaryan
new event architecture, first trial
322
    
245 by Suren A. Chilingaryan
First stand-alone ipecamera implementation
323
    const pcilib_model_description_t *model_info = pcilib_get_model_description(pcilib);
324
117 by Suren A. Chilingaryan
new event architecture, first trial
325
    pthread_attr_t attr;
326
    struct sched_param sched;
327
    
15 by Suren A. Chilingaryan
Infrastructure for event API
328
    if (!ctx) {
329
	pcilib_error("IPECamera imaging is not initialized");
330
	return PCILIB_ERROR_NOTINITIALIZED;
331
    }
223 by Suren A. Chilingaryan
Merge changes from xilinx_dma branch providing support of multipage kmem allocations and mapping memory regions reserved with memmap boot option
332
17 by Suren A. Chilingaryan
Allow access to implementation context and provide call to set size of internal buffer for IPECamera
333
    if (ctx->started) {
334
	pcilib_error("IPECamera grabbing is already started");
335
	return PCILIB_ERROR_INVALID_REQUEST;
336
    }
35 by Suren A. Chilingaryan
Multiline grabbing
337
265 by Suren A. Chilingaryan
Use new locking subsystem to ensure integrity
338
    LOCK(run);
339
262 by Suren A. Chilingaryan
Introduce API debugging
340
    ipecamera_debug(API, "ipecamera: starting");
341
15 by Suren A. Chilingaryan
Infrastructure for event API
342
    ctx->event_id = 0;
126 by Suren A. Chilingaryan
multithread preprocessing of ipecamera frames and code reorganization
343
    ctx->preproc_id = 0;
29 by Suren A. Chilingaryan
Support non-callback way of getting events
344
    ctx->reported_id = 0;
117 by Suren A. Chilingaryan
new event architecture, first trial
345
    ctx->buffer_pos = 0;
346
    ctx->parse_data = (flags&PCILIB_EVENT_FLAG_RAW_DATA_ONLY)?0:1;
347
    ctx->cur_size = 0;
261 by Suren A. Chilingaryan
Support for new CMOSIS 20MPix camera
348
267 by Suren A. Chilingaryan
Handle frame headers split between 2 packets
349
#ifdef IPECAMERA_BUG_MULTIFRAME_HEADERS
350
    ctx->saved_header_size = 0;
351
#endif /* IPECAMERA_BUG_MULTIFRAME_HEADERS */
352
261 by Suren A. Chilingaryan
Support for new CMOSIS 20MPix camera
353
    switch (ctx->firmware) {
354
     case IPECAMERA_FIRMWARE_UFO5:
355
	ctx->dim.width = CMOSIS_WIDTH;
356
	ctx->dim.height = CMOSIS_MAX_LINES;
282 by Suren A. Chilingaryan
Support HighFlex-based ipecamera
357
358
	ctx->data_line_size = (1 + CMOSIS_PIXELS_PER_CHANNEL) * 32; 
261 by Suren A. Chilingaryan
Support for new CMOSIS 20MPix camera
359
	break;
360
     case IPECAMERA_FIRMWARE_CMOSIS20:
361
	ctx->dim.width = CMOSIS20_WIDTH;
362
	ctx->dim.height = CMOSIS20_MAX_LINES;
282 by Suren A. Chilingaryan
Support HighFlex-based ipecamera
363
364
	ctx->data_line_size = (2 + CMOSIS20_PIXELS_PER_CHANNEL) * 32;
261 by Suren A. Chilingaryan
Support for new CMOSIS 20MPix camera
365
	break;
168 by Suren A. Chilingaryan
Support 12-bit modes
366
     default:
265 by Suren A. Chilingaryan
Use new locking subsystem to ensure integrity
367
	UNLOCK(run);
261 by Suren A. Chilingaryan
Support for new CMOSIS 20MPix camera
368
	pcilib_error("Can't start undefined version (%lu) of IPECamera", ctx->firmware);
369
	return PCILIB_ERROR_INVALID_REQUEST;
370
    }
371
282 by Suren A. Chilingaryan
Support HighFlex-based ipecamera
372
    if ((1)||(ctx->firmware == IPECAMERA_FIRMWARE_UFO5)) {
261 by Suren A. Chilingaryan
Support for new CMOSIS 20MPix camera
373
	GET_REG(output_mode_reg, value);
374
	switch (value) {
375
	 case IPECAMERA_MODE_16_CHAN_IO:
376
	    ctx->cmosis_outputs = 16;
377
	    break;
378
         case IPECAMERA_MODE_4_CHAN_IO:
379
	    ctx->cmosis_outputs = 4;
380
	    break;
381
	 default:
265 by Suren A. Chilingaryan
Use new locking subsystem to ensure integrity
382
	    UNLOCK(run);
261 by Suren A. Chilingaryan
Support for new CMOSIS 20MPix camera
383
	    pcilib_error("IPECamera reporting invalid output_mode 0x%lx", value);
384
	    return PCILIB_ERROR_INVALID_STATE;
385
	}
282 by Suren A. Chilingaryan
Support HighFlex-based ipecamera
386
    } 
261 by Suren A. Chilingaryan
Support for new CMOSIS 20MPix camera
387
388
	// We should be careful here (currently firmware matches format, but this may not be the case in future)
389
    ipecamera_compute_buffer_size(ctx, ctx->firmware, CMOSIS_FRAME_HEADER_SIZE, ctx->dim.height);
162 by Suren A. Chilingaryan
UFO5 size estimation
390
249 by Suren A. Chilingaryan
Simplify size tracking in the reader
391
    ctx->raw_size = ctx->roi_raw_size;
392
    ctx->padded_size = ctx->roi_padded_size;
162 by Suren A. Chilingaryan
UFO5 size estimation
393
124 by Suren A. Chilingaryan
Image frames decoding
394
    ctx->image_size = ctx->dim.width * ctx->dim.height;
117 by Suren A. Chilingaryan
new event architecture, first trial
395
174 by Suren A. Chilingaryan
Check for free space in camera DDR buffer before triggering event
396
    
397
    GET_REG(max_frames_reg, value);
398
    ctx->max_frames = value;
399
117 by Suren A. Chilingaryan
new event architecture, first trial
400
    ctx->buffer = malloc(ctx->padded_size * ctx->buffer_size);
16 by Suren A. Chilingaryan
Prototype of IPECamera image protocol
401
    if (!ctx->buffer) {
126 by Suren A. Chilingaryan
multithread preprocessing of ipecamera frames and code reorganization
402
	ipecamera_stop(vctx, PCILIB_EVENT_FLAGS_DEFAULT);
117 by Suren A. Chilingaryan
new event architecture, first trial
403
	pcilib_error("Unable to allocate ring buffer (%lu bytes)", ctx->padded_size * ctx->buffer_size);
126 by Suren A. Chilingaryan
multithread preprocessing of ipecamera frames and code reorganization
404
	return PCILIB_ERROR_MEMORY;
16 by Suren A. Chilingaryan
Prototype of IPECamera image protocol
405
    }
406
124 by Suren A. Chilingaryan
Image frames decoding
407
    ctx->image = (ipecamera_pixel_t*)malloc(ctx->image_size * ctx->buffer_size * sizeof(ipecamera_pixel_t));
408
    if (!ctx->image) {
126 by Suren A. Chilingaryan
multithread preprocessing of ipecamera frames and code reorganization
409
	ipecamera_stop(vctx, PCILIB_EVENT_FLAGS_DEFAULT);
124 by Suren A. Chilingaryan
Image frames decoding
410
	pcilib_error("Unable to allocate image buffer (%lu bytes)", ctx->image_size * ctx->buffer_size * sizeof(ipecamera_pixel_t));
126 by Suren A. Chilingaryan
multithread preprocessing of ipecamera frames and code reorganization
411
	return PCILIB_ERROR_MEMORY;
124 by Suren A. Chilingaryan
Image frames decoding
412
    }
413
16 by Suren A. Chilingaryan
Prototype of IPECamera image protocol
414
    ctx->cmask = malloc(ctx->dim.height * ctx->buffer_size * sizeof(ipecamera_change_mask_t));
415
    if (!ctx->cmask) {
126 by Suren A. Chilingaryan
multithread preprocessing of ipecamera frames and code reorganization
416
	ipecamera_stop(vctx, PCILIB_EVENT_FLAGS_DEFAULT);
16 by Suren A. Chilingaryan
Prototype of IPECamera image protocol
417
	pcilib_error("Unable to allocate change-mask buffer");
126 by Suren A. Chilingaryan
multithread preprocessing of ipecamera frames and code reorganization
418
	return PCILIB_ERROR_MEMORY;
117 by Suren A. Chilingaryan
new event architecture, first trial
419
    }
420
126 by Suren A. Chilingaryan
multithread preprocessing of ipecamera frames and code reorganization
421
    ctx->frame = (ipecamera_frame_t*)malloc(ctx->buffer_size * sizeof(ipecamera_frame_t));
422
    if (!ctx->frame) {
423
	ipecamera_stop(vctx, PCILIB_EVENT_FLAGS_DEFAULT);
117 by Suren A. Chilingaryan
new event architecture, first trial
424
	pcilib_error("Unable to allocate frame-info buffer");
126 by Suren A. Chilingaryan
multithread preprocessing of ipecamera frames and code reorganization
425
	return PCILIB_ERROR_MEMORY;
426
    }
427
    
428
    memset(ctx->frame, 0, ctx->buffer_size * sizeof(ipecamera_frame_t));
429
    
430
    for (i = 0; i < ctx->buffer_size; i++) {
431
	err = pthread_rwlock_init(&ctx->frame[i].mutex, NULL);
432
	if (err) break;
433
    }
434
435
    ctx->frame_mutex_destroy = i;
436
437
    if (err) {
438
        ipecamera_stop(vctx, PCILIB_EVENT_FLAGS_DEFAULT);
439
	pcilib_error("Initialization of rwlock mutexes for frame synchronization has failed");
440
	return PCILIB_ERROR_FAILED;
16 by Suren A. Chilingaryan
Prototype of IPECamera image protocol
441
    }
124 by Suren A. Chilingaryan
Image frames decoding
442
    
443
    ctx->ipedec = ufo_decoder_new(ctx->dim.height, ctx->dim.width, NULL, 0);
444
    if (!ctx->ipedec) {
126 by Suren A. Chilingaryan
multithread preprocessing of ipecamera frames and code reorganization
445
        ipecamera_stop(vctx, PCILIB_EVENT_FLAGS_DEFAULT);
124 by Suren A. Chilingaryan
Image frames decoding
446
	pcilib_error("Unable to initialize IPECamera decoder library");
447
	return PCILIB_ERROR_FAILED;
448
    }
93 by root
DMA support in IPE Camera
449
450
    if (!err) {
117 by Suren A. Chilingaryan
new event architecture, first trial
451
	ctx->rdma = pcilib_find_dma_by_addr(vctx->pcilib, PCILIB_DMA_FROM_DEVICE, IPECAMERA_DMA_ADDRESS);
93 by root
DMA support in IPE Camera
452
	if (ctx->rdma == PCILIB_DMA_ENGINE_INVALID) {
453
	    err = PCILIB_ERROR_NOTFOUND;
454
	    pcilib_error("The C2S channel of IPECamera DMA Engine (%u) is not found", IPECAMERA_DMA_ADDRESS);
455
	} else {
117 by Suren A. Chilingaryan
new event architecture, first trial
456
	    err = pcilib_start_dma(vctx->pcilib, ctx->rdma, PCILIB_DMA_FLAGS_DEFAULT);
93 by root
DMA support in IPE Camera
457
	    if (err) {
458
		ctx->rdma = PCILIB_DMA_ENGINE_INVALID;
459
		pcilib_error("Failed to initialize C2S channel of IPECamera DMA Engine (%u)", IPECAMERA_DMA_ADDRESS);
460
	    }
461
	}
462
    }
463
    
126 by Suren A. Chilingaryan
multithread preprocessing of ipecamera frames and code reorganization
464
    if (err) {
465
        ipecamera_stop(vctx, PCILIB_EVENT_FLAGS_DEFAULT);
466
	return err;
467
    }
468
252 by Suren A. Chilingaryan
Cleanup
469
#ifdef IPECAMERA_CLEAN_ON_START
117 by Suren A. Chilingaryan
new event architecture, first trial
470
    err = pcilib_skip_dma(vctx->pcilib, ctx->rdma);
471
    if (err) {
126 by Suren A. Chilingaryan
multithread preprocessing of ipecamera frames and code reorganization
472
        ipecamera_stop(vctx, PCILIB_EVENT_FLAGS_DEFAULT);
117 by Suren A. Chilingaryan
new event architecture, first trial
473
	pcilib_error("Can't start grabbing, device continuously writes unexpected data using DMA engine");
474
	return err;
475
    }
252 by Suren A. Chilingaryan
Cleanup
476
#endif /* IPECAMERA_CLEAN_ON_START */
117 by Suren A. Chilingaryan
new event architecture, first trial
477
478
    if (vctx->params.autostop.duration) {
479
	gettimeofday(&ctx->autostop.timestamp, NULL);
480
	ctx->autostop.timestamp.tv_usec += vctx->params.autostop.duration % 1000000;
481
	if (ctx->autostop.timestamp.tv_usec > 999999) {
482
	    ctx->autostop.timestamp.tv_sec += 1 + vctx->params.autostop.duration / 1000000;
483
	    ctx->autostop.timestamp.tv_usec -= 1000000;
484
	} else {
485
	    ctx->autostop.timestamp.tv_sec += vctx->params.autostop.duration / 1000000;
486
	}
487
    }
488
    
489
    if (vctx->params.autostop.max_events) {
490
	ctx->autostop.evid = vctx->params.autostop.max_events;
491
    }
15 by Suren A. Chilingaryan
Infrastructure for event API
492
    
144 by Suren A. Chilingaryan
Do not call the normall callback in the raw-data-only mode
493
    if ((ctx->parse_data)&&(flags&PCILIB_EVENT_FLAG_PREPROCESS)) {
126 by Suren A. Chilingaryan
multithread preprocessing of ipecamera frames and code reorganization
494
	ctx->n_preproc = pcilib_get_cpu_count();
135 by Suren A. Chilingaryan
Allow to configure the number of preprocessing threads
495
	
496
	    // it would be greate to detect hyperthreading cores and ban them
126 by Suren A. Chilingaryan
multithread preprocessing of ipecamera frames and code reorganization
497
	switch (ctx->n_preproc) {
498
	    case 1: break;
208 by Suren A. Chilingaryan
I have no clue how to properly write switch statements.... Fixed.
499
	    case 2 ... 3: ctx->n_preproc -= 1; break;
126 by Suren A. Chilingaryan
multithread preprocessing of ipecamera frames and code reorganization
500
	    default: ctx->n_preproc -= 2; break;
501
	}
135 by Suren A. Chilingaryan
Allow to configure the number of preprocessing threads
502
503
	if ((vctx->params.parallel.max_threads)&&(vctx->params.parallel.max_threads < ctx->n_preproc))
504
	    ctx->n_preproc = vctx->params.parallel.max_threads;
505
126 by Suren A. Chilingaryan
multithread preprocessing of ipecamera frames and code reorganization
506
	ctx->preproc = (ipecamera_preprocessor_t*)malloc(ctx->n_preproc * sizeof(ipecamera_preprocessor_t));
507
	if (!ctx->preproc) {
508
	    ipecamera_stop(vctx, PCILIB_EVENT_FLAGS_DEFAULT);
509
	    pcilib_error("Unable to allocate memory for preprocessor contexts");
510
	    return PCILIB_ERROR_MEMORY;
511
	}
512
513
	memset(ctx->preproc, 0, ctx->n_preproc * sizeof(ipecamera_preprocessor_t));
514
515
	err = pthread_mutex_init(&ctx->preproc_mutex, NULL);
516
	if (err) {
517
	    ipecamera_stop(vctx, PCILIB_EVENT_FLAGS_DEFAULT);
518
	    pcilib_error("Failed to initialize event mutex");
519
	    return PCILIB_ERROR_FAILED;
520
	}
521
	ctx->preproc_mutex_destroy = 1;
522
	
523
524
	ctx->run_preprocessors = 1;
525
	for (i = 0; i < ctx->n_preproc; i++) {
526
	    ctx->preproc[i].i = i;
527
	    ctx->preproc[i].ipecamera = ctx;
528
	    err = pthread_create(&ctx->preproc[i].thread, NULL, ipecamera_preproc_thread, ctx->preproc + i);
529
	    if (err) {
530
		err = PCILIB_ERROR_FAILED;
531
		break;
532
	    } else {
533
		ctx->preproc[i].started = 1;
534
	    }
535
	}
536
	
537
	if (err) {
538
	    ipecamera_stop(vctx, PCILIB_EVENT_FLAGS_DEFAULT);
539
	    pcilib_error("Failed to schedule some of the preprocessor threads");
540
	    return err;
541
	}
542
    } else {
543
	ctx->n_preproc = 0;
544
    }
545
21 by Suren A. Chilingaryan
Small bug fix: forgot to set a flag indicating what we are started
546
    ctx->started = 1;
117 by Suren A. Chilingaryan
new event architecture, first trial
547
    ctx->run_reader = 1;
126 by Suren A. Chilingaryan
multithread preprocessing of ipecamera frames and code reorganization
548
117 by Suren A. Chilingaryan
new event architecture, first trial
549
    pthread_attr_init(&attr);
550
551
    if (pthread_attr_setschedpolicy(&attr, SCHED_FIFO)) {
552
	pcilib_warning("Can't schedule a real-time thread, you may consider running as root");
553
    } else {
554
	sched.sched_priority = sched_get_priority_max(SCHED_FIFO) - 1;	// Let 1 priority for something really critcial
555
	pthread_attr_setschedparam(&attr, &sched);
556
    }
171 by Suren A. Chilingaryan
Fix temperature register of ipecamera and prepend all cmosis registers with _cmosis prefix
557
117 by Suren A. Chilingaryan
new event architecture, first trial
558
    if (pthread_create(&ctx->rthread, &attr, &ipecamera_reader_thread, (void*)ctx)) {
559
	ctx->started = 0;
560
	ipecamera_stop(vctx, PCILIB_EVENT_FLAGS_DEFAULT);
126 by Suren A. Chilingaryan
multithread preprocessing of ipecamera frames and code reorganization
561
	err = PCILIB_ERROR_FAILED;
117 by Suren A. Chilingaryan
new event architecture, first trial
562
    }
563
    
564
    pthread_attr_destroy(&attr);    
565
262 by Suren A. Chilingaryan
Introduce API debugging
566
    ipecamera_debug(API, "ipecamera: started");
567
117 by Suren A. Chilingaryan
new event architecture, first trial
568
    return err;
15 by Suren A. Chilingaryan
Infrastructure for event API
569
}
570
571
117 by Suren A. Chilingaryan
new event architecture, first trial
572
int ipecamera_stop(pcilib_context_t *vctx, pcilib_event_flags_t flags) {
126 by Suren A. Chilingaryan
multithread preprocessing of ipecamera frames and code reorganization
573
    int i;
117 by Suren A. Chilingaryan
new event architecture, first trial
574
    int err;
575
    void *retcode;
15 by Suren A. Chilingaryan
Infrastructure for event API
576
    ipecamera_t *ctx = (ipecamera_t*)vctx;
577
578
    if (!ctx) {
579
	pcilib_error("IPECamera imaging is not initialized");
580
	return PCILIB_ERROR_NOTINITIALIZED;
581
    }
16 by Suren A. Chilingaryan
Prototype of IPECamera image protocol
582
119 by Suren A. Chilingaryan
Initial support of event streaming in cli
583
    if (flags&PCILIB_EVENT_FLAG_STOP_ONLY) {
584
	ctx->run_reader = 0;
585
	return 0;
586
    }
126 by Suren A. Chilingaryan
multithread preprocessing of ipecamera frames and code reorganization
587
262 by Suren A. Chilingaryan
Introduce API debugging
588
    ipecamera_debug(API, "ipecamera: stopping");
589
117 by Suren A. Chilingaryan
new event architecture, first trial
590
    if (ctx->started) {
591
	ctx->run_reader = 0;
592
	err = pthread_join(ctx->rthread, &retcode);
593
	if (err) pcilib_error("Error joining the reader thread");
594
    }
126 by Suren A. Chilingaryan
multithread preprocessing of ipecamera frames and code reorganization
595
    
596
    if (ctx->preproc) {
597
	ctx->run_preprocessors = 0;
598
	
599
	for (i = 0; i < ctx->n_preproc; i++) {
600
	    if (ctx->preproc[i].started) {
601
		pthread_join(ctx->preproc[i].thread, &retcode);
602
		ctx->preproc[i].started = 0;
603
	    }
604
	}
21 by Suren A. Chilingaryan
Small bug fix: forgot to set a flag indicating what we are started
605
126 by Suren A. Chilingaryan
multithread preprocessing of ipecamera frames and code reorganization
606
	if (ctx->preproc_mutex_destroy) {
607
	    pthread_mutex_destroy(&ctx->preproc_mutex);
608
	    ctx->preproc_mutex_destroy = 0;
609
	}
610
	
611
	free(ctx->preproc);
612
	ctx->preproc = NULL;
613
    }
614
    
615
    if (ctx->frame_mutex_destroy) {
616
	for (i = 0; i < ctx->frame_mutex_destroy; i++) {
617
	    pthread_rwlock_destroy(&ctx->frame[i].mutex);
618
	}
619
	ctx->frame_mutex_destroy = 0;
620
    }
93 by root
DMA support in IPE Camera
621
622
    if (ctx->rdma != PCILIB_DMA_ENGINE_INVALID) {
117 by Suren A. Chilingaryan
new event architecture, first trial
623
	pcilib_stop_dma(vctx->pcilib, ctx->rdma, PCILIB_DMA_FLAGS_DEFAULT);
93 by root
DMA support in IPE Camera
624
	ctx->rdma = PCILIB_DMA_ENGINE_INVALID;
625
    }
190.1.1 by Suren A. Chilingaryan
In ipecamera_stop wait until streaming user-thread is terminated
626
627
    while (ctx->streaming) {
628
        usleep(IPECAMERA_NOFRAME_SLEEP);
629
    }
630
124 by Suren A. Chilingaryan
Image frames decoding
631
    if (ctx->ipedec) {
632
	ufo_decoder_free(ctx->ipedec);
633
	ctx->ipedec = NULL;
634
    }
93 by root
DMA support in IPE Camera
635
126 by Suren A. Chilingaryan
multithread preprocessing of ipecamera frames and code reorganization
636
    if (ctx->frame) {
637
	free(ctx->frame);
638
	ctx->frame = NULL;
117 by Suren A. Chilingaryan
new event architecture, first trial
639
    }
640
124 by Suren A. Chilingaryan
Image frames decoding
641
    if (ctx->cmask) {
642
	free(ctx->cmask);
643
	ctx->cmask = NULL;
644
    }
645
646
    if (ctx->image) {
647
	free(ctx->image);
648
	ctx->image = NULL;
649
    }
650
16 by Suren A. Chilingaryan
Prototype of IPECamera image protocol
651
    if (ctx->buffer) {
652
	free(ctx->buffer);
653
	ctx->buffer = NULL;
654
    }
655
117 by Suren A. Chilingaryan
new event architecture, first trial
656
    memset(&ctx->autostop, 0, sizeof(ipecamera_autostop_t));
16 by Suren A. Chilingaryan
Prototype of IPECamera image protocol
657
658
    ctx->event_id = 0;
29 by Suren A. Chilingaryan
Support non-callback way of getting events
659
    ctx->reported_id = 0;
117 by Suren A. Chilingaryan
new event architecture, first trial
660
    ctx->buffer_pos = 0; 
661
    ctx->started = 0;
662
262 by Suren A. Chilingaryan
Introduce API debugging
663
    ipecamera_debug(API, "ipecamera: stopped");
265 by Suren A. Chilingaryan
Use new locking subsystem to ensure integrity
664
    UNLOCK(run);
665
117 by Suren A. Chilingaryan
new event architecture, first trial
666
    return 0;
15 by Suren A. Chilingaryan
Infrastructure for event API
667
}
668
669
31 by Suren A. Chilingaryan
Introduce pcilib_context_t type instead pointer to void
670
int ipecamera_trigger(pcilib_context_t *vctx, pcilib_event_t event, size_t trigger_size, void *trigger_data) {
117 by Suren A. Chilingaryan
new event architecture, first trial
671
    int err = 0;
672
    pcilib_register_value_t value;
673
15 by Suren A. Chilingaryan
Infrastructure for event API
674
    ipecamera_t *ctx = (ipecamera_t*)vctx;
117 by Suren A. Chilingaryan
new event architecture, first trial
675
    pcilib_t *pcilib = vctx->pcilib;
15 by Suren A. Chilingaryan
Infrastructure for event API
676
245 by Suren A. Chilingaryan
First stand-alone ipecamera implementation
677
    const pcilib_model_description_t *model_info = pcilib_get_model_description(pcilib);
678
15 by Suren A. Chilingaryan
Infrastructure for event API
679
    if (!ctx) {
680
	pcilib_error("IPECamera imaging is not initialized");
681
	return PCILIB_ERROR_NOTINITIALIZED;
682
    }
223 by Suren A. Chilingaryan
Merge changes from xilinx_dma branch providing support of multipage kmem allocations and mapping memory regions reserved with memmap boot option
683
265 by Suren A. Chilingaryan
Use new locking subsystem to ensure integrity
684
    ipecamera_debug(API, "ipecamera: trigger");
685
    LOCK(trigger);
686
132 by Suren A. Chilingaryan
Minor fixes and improvements
687
    pcilib_sleep_until_deadline(&ctx->next_trigger);
239 by Suren A. Chilingaryan
ipecamera hack
688
/*
174 by Suren A. Chilingaryan
Check for free space in camera DDR buffer before triggering event
689
    GET_REG(num_frames_reg, value);
690
    if (value == ctx->max_frames) {
691
	return PCILIB_ERROR_BUSY;
692
    }
239 by Suren A. Chilingaryan
ipecamera hack
693
*/
240 by Suren A. Chilingaryan
Fix frame size computation in ipecamera and few debuging options
694
695
    GET_REG(status2_reg, value);
696
    if (value&0x40000000) {
252 by Suren A. Chilingaryan
Cleanup
697
	if (value == 0xffffffff)
698
	    pcilib_info("Failed to read status2_reg while triggering");
240 by Suren A. Chilingaryan
Fix frame size computation in ipecamera and few debuging options
699
252 by Suren A. Chilingaryan
Cleanup
700
#ifdef IPECAMERA_TRIGGER_TIMEOUT
701
	if (IPECAMERA_TRIGGER_TIMEOUT) {
240 by Suren A. Chilingaryan
Fix frame size computation in ipecamera and few debuging options
702
	    struct timeval deadline;
252 by Suren A. Chilingaryan
Cleanup
703
	    pcilib_calc_deadline(&deadline, IPECAMERA_TRIGGER_TIMEOUT);
240 by Suren A. Chilingaryan
Fix frame size computation in ipecamera and few debuging options
704
	    do {
705
		usleep(IPECAMERA_READ_STATUS_DELAY);
706
		GET_REG(status2_reg, value);
707
	    } while ((value&0x40000000)&&(pcilib_calc_time_to_deadline(&deadline) > 0));
708
	}
265 by Suren A. Chilingaryan
Use new locking subsystem to ensure integrity
709
	if (value&0x40000000) {
240 by Suren A. Chilingaryan
Fix frame size computation in ipecamera and few debuging options
710
#endif /* IPECAMERA_TRIGGER_WAIT_IDLE */
265 by Suren A. Chilingaryan
Use new locking subsystem to ensure integrity
711
	    UNLOCK(trigger);
240 by Suren A. Chilingaryan
Fix frame size computation in ipecamera and few debuging options
712
	    return PCILIB_ERROR_BUSY;
265 by Suren A. Chilingaryan
Use new locking subsystem to ensure integrity
713
#ifdef IPECAMERA_TRIGGER_TIMEOUT
714
	}
715
#endif /* IPECAMERA_TRIGGER_WAIT_IDLE */
240 by Suren A. Chilingaryan
Fix frame size computation in ipecamera and few debuging options
716
    }
215 by Suren A. Chilingaryan
Properly support triggering with new revision of UFO camera
717
261 by Suren A. Chilingaryan
Support for new CMOSIS 20MPix camera
718
    GET_REG(control_reg, value);
215 by Suren A. Chilingaryan
Properly support triggering with new revision of UFO camera
719
    SET_REG(control_reg, value|IPECAMERA_FRAME_REQUEST);
252 by Suren A. Chilingaryan
Cleanup
720
    usleep(IPECAMERA_TRIGGER_DELAY);
215 by Suren A. Chilingaryan
Properly support triggering with new revision of UFO camera
721
    SET_REG(control_reg, value);
117 by Suren A. Chilingaryan
new event architecture, first trial
722
252 by Suren A. Chilingaryan
Cleanup
723
	// DS: We need to compute it differently, on top of that add exposure time and the time FPGA takes to read frame from CMOSIS
132 by Suren A. Chilingaryan
Minor fixes and improvements
724
    pcilib_calc_deadline(&ctx->next_trigger, IPECAMERA_NEXT_FRAME_DELAY);
265 by Suren A. Chilingaryan
Use new locking subsystem to ensure integrity
725
    
726
    UNLOCK(trigger);
117 by Suren A. Chilingaryan
new event architecture, first trial
727
119 by Suren A. Chilingaryan
Initial support of event streaming in cli
728
    return 0;
117 by Suren A. Chilingaryan
new event architecture, first trial
729
}