/alps/ipecamera

To get this branch, use:
bzr branch http://darksoft.org/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
16 by Suren A. Chilingaryan
Prototype of IPECamera image protocol
293
	// Set default parameters
117 by Suren A. Chilingaryan
new event architecture, first trial
294
    err = pcilib_write_register_by_id(pcilib, control, IPECAMERA_IDLE);
295
    if (err) {
265 by Suren A. Chilingaryan
Use new locking subsystem to ensure integrity
296
	UNLOCK(run);
117 by Suren A. Chilingaryan
new event architecture, first trial
297
	pcilib_error("Error bringing FPGA in default mode");
298
	return err;
299
    }
300
39 by root
Move to new FPGA design
301
    usleep(10000);
117 by Suren A. Chilingaryan
new event architecture, first trial
302
245 by Suren A. Chilingaryan
First stand-alone ipecamera implementation
303
304
    CHECK_STATUS();
15 by Suren A. Chilingaryan
Infrastructure for event API
305
    if (err) {
245 by Suren A. Chilingaryan
First stand-alone ipecamera implementation
306
	err = pcilib_read_register_by_id(pcilib, status, &value);
307
265 by Suren A. Chilingaryan
Use new locking subsystem to ensure integrity
308
	UNLOCK(run);
245 by Suren A. Chilingaryan
First stand-alone ipecamera implementation
309
	if (err) pcilib_error("Error reading status register");
310
	else pcilib_error("Camera returns unexpected status (status: %lx)", value);
311
15 by Suren A. Chilingaryan
Infrastructure for event API
312
	return PCILIB_ERROR_VERIFY;
313
    }
314
265 by Suren A. Chilingaryan
Use new locking subsystem to ensure integrity
315
    err = pcilib_skip_dma(vctx->pcilib, ctx->rdma);
316
    UNLOCK(run);
317
318
    ipecamera_debug(API, "ipecamera: reset done");
319
    return err;
15 by Suren A. Chilingaryan
Infrastructure for event API
320
}
321
117 by Suren A. Chilingaryan
new event architecture, first trial
322
323
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
324
    int i;
16 by Suren A. Chilingaryan
Prototype of IPECamera image protocol
325
    int err = 0;
245 by Suren A. Chilingaryan
First stand-alone ipecamera implementation
326
15 by Suren A. Chilingaryan
Infrastructure for event API
327
    ipecamera_t *ctx = (ipecamera_t*)vctx;
117 by Suren A. Chilingaryan
new event architecture, first trial
328
    pcilib_t *pcilib = vctx->pcilib;
35 by Suren A. Chilingaryan
Multiline grabbing
329
    pcilib_register_value_t value;
117 by Suren A. Chilingaryan
new event architecture, first trial
330
    
245 by Suren A. Chilingaryan
First stand-alone ipecamera implementation
331
    const pcilib_model_description_t *model_info = pcilib_get_model_description(pcilib);
332
117 by Suren A. Chilingaryan
new event architecture, first trial
333
    pthread_attr_t attr;
334
    struct sched_param sched;
335
    
15 by Suren A. Chilingaryan
Infrastructure for event API
336
    if (!ctx) {
337
	pcilib_error("IPECamera imaging is not initialized");
338
	return PCILIB_ERROR_NOTINITIALIZED;
339
    }
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
340
17 by Suren A. Chilingaryan
Allow access to implementation context and provide call to set size of internal buffer for IPECamera
341
    if (ctx->started) {
342
	pcilib_error("IPECamera grabbing is already started");
343
	return PCILIB_ERROR_INVALID_REQUEST;
344
    }
35 by Suren A. Chilingaryan
Multiline grabbing
345
265 by Suren A. Chilingaryan
Use new locking subsystem to ensure integrity
346
    LOCK(run);
347
262 by Suren A. Chilingaryan
Introduce API debugging
348
    ipecamera_debug(API, "ipecamera: starting");
349
15 by Suren A. Chilingaryan
Infrastructure for event API
350
    ctx->event_id = 0;
126 by Suren A. Chilingaryan
multithread preprocessing of ipecamera frames and code reorganization
351
    ctx->preproc_id = 0;
29 by Suren A. Chilingaryan
Support non-callback way of getting events
352
    ctx->reported_id = 0;
117 by Suren A. Chilingaryan
new event architecture, first trial
353
    ctx->buffer_pos = 0;
354
    ctx->parse_data = (flags&PCILIB_EVENT_FLAG_RAW_DATA_ONLY)?0:1;
355
    ctx->cur_size = 0;
261 by Suren A. Chilingaryan
Support for new CMOSIS 20MPix camera
356
267 by Suren A. Chilingaryan
Handle frame headers split between 2 packets
357
#ifdef IPECAMERA_BUG_MULTIFRAME_HEADERS
358
    ctx->saved_header_size = 0;
359
#endif /* IPECAMERA_BUG_MULTIFRAME_HEADERS */
360
261 by Suren A. Chilingaryan
Support for new CMOSIS 20MPix camera
361
    switch (ctx->firmware) {
362
     case IPECAMERA_FIRMWARE_UFO5:
363
	ctx->dim.width = CMOSIS_WIDTH;
364
	ctx->dim.height = CMOSIS_MAX_LINES;
365
	break;
366
     case IPECAMERA_FIRMWARE_CMOSIS20:
367
	ctx->dim.width = CMOSIS20_WIDTH;
368
	ctx->dim.height = CMOSIS20_MAX_LINES;
369
	ctx->cmosis_outputs = CMOSIS20_MAX_CHANNELS;
370
	break;
168 by Suren A. Chilingaryan
Support 12-bit modes
371
     default:
265 by Suren A. Chilingaryan
Use new locking subsystem to ensure integrity
372
	UNLOCK(run);
261 by Suren A. Chilingaryan
Support for new CMOSIS 20MPix camera
373
	pcilib_error("Can't start undefined version (%lu) of IPECamera", ctx->firmware);
374
	return PCILIB_ERROR_INVALID_REQUEST;
375
    }
376
377
    if (ctx->firmware == IPECAMERA_FIRMWARE_UFO5) {
378
	GET_REG(output_mode_reg, value);
379
	switch (value) {
380
	 case IPECAMERA_MODE_16_CHAN_IO:
381
	    ctx->cmosis_outputs = 16;
382
	    break;
383
         case IPECAMERA_MODE_4_CHAN_IO:
384
	    ctx->cmosis_outputs = 4;
385
	    break;
386
	 default:
265 by Suren A. Chilingaryan
Use new locking subsystem to ensure integrity
387
	    UNLOCK(run);
261 by Suren A. Chilingaryan
Support for new CMOSIS 20MPix camera
388
	    pcilib_error("IPECamera reporting invalid output_mode 0x%lx", value);
389
	    return PCILIB_ERROR_INVALID_STATE;
390
	}
391
    }
392
393
	// We should be careful here (currently firmware matches format, but this may not be the case in future)
394
    ipecamera_compute_buffer_size(ctx, ctx->firmware, CMOSIS_FRAME_HEADER_SIZE, ctx->dim.height);
162 by Suren A. Chilingaryan
UFO5 size estimation
395
249 by Suren A. Chilingaryan
Simplify size tracking in the reader
396
    ctx->raw_size = ctx->roi_raw_size;
397
    ctx->padded_size = ctx->roi_padded_size;
162 by Suren A. Chilingaryan
UFO5 size estimation
398
124 by Suren A. Chilingaryan
Image frames decoding
399
    ctx->image_size = ctx->dim.width * ctx->dim.height;
117 by Suren A. Chilingaryan
new event architecture, first trial
400
174 by Suren A. Chilingaryan
Check for free space in camera DDR buffer before triggering event
401
    
402
    GET_REG(max_frames_reg, value);
403
    ctx->max_frames = value;
404
117 by Suren A. Chilingaryan
new event architecture, first trial
405
    ctx->buffer = malloc(ctx->padded_size * ctx->buffer_size);
16 by Suren A. Chilingaryan
Prototype of IPECamera image protocol
406
    if (!ctx->buffer) {
126 by Suren A. Chilingaryan
multithread preprocessing of ipecamera frames and code reorganization
407
	ipecamera_stop(vctx, PCILIB_EVENT_FLAGS_DEFAULT);
117 by Suren A. Chilingaryan
new event architecture, first trial
408
	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
409
	return PCILIB_ERROR_MEMORY;
16 by Suren A. Chilingaryan
Prototype of IPECamera image protocol
410
    }
411
124 by Suren A. Chilingaryan
Image frames decoding
412
    ctx->image = (ipecamera_pixel_t*)malloc(ctx->image_size * ctx->buffer_size * sizeof(ipecamera_pixel_t));
413
    if (!ctx->image) {
126 by Suren A. Chilingaryan
multithread preprocessing of ipecamera frames and code reorganization
414
	ipecamera_stop(vctx, PCILIB_EVENT_FLAGS_DEFAULT);
124 by Suren A. Chilingaryan
Image frames decoding
415
	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
416
	return PCILIB_ERROR_MEMORY;
124 by Suren A. Chilingaryan
Image frames decoding
417
    }
418
16 by Suren A. Chilingaryan
Prototype of IPECamera image protocol
419
    ctx->cmask = malloc(ctx->dim.height * ctx->buffer_size * sizeof(ipecamera_change_mask_t));
420
    if (!ctx->cmask) {
126 by Suren A. Chilingaryan
multithread preprocessing of ipecamera frames and code reorganization
421
	ipecamera_stop(vctx, PCILIB_EVENT_FLAGS_DEFAULT);
16 by Suren A. Chilingaryan
Prototype of IPECamera image protocol
422
	pcilib_error("Unable to allocate change-mask buffer");
126 by Suren A. Chilingaryan
multithread preprocessing of ipecamera frames and code reorganization
423
	return PCILIB_ERROR_MEMORY;
117 by Suren A. Chilingaryan
new event architecture, first trial
424
    }
425
126 by Suren A. Chilingaryan
multithread preprocessing of ipecamera frames and code reorganization
426
    ctx->frame = (ipecamera_frame_t*)malloc(ctx->buffer_size * sizeof(ipecamera_frame_t));
427
    if (!ctx->frame) {
428
	ipecamera_stop(vctx, PCILIB_EVENT_FLAGS_DEFAULT);
117 by Suren A. Chilingaryan
new event architecture, first trial
429
	pcilib_error("Unable to allocate frame-info buffer");
126 by Suren A. Chilingaryan
multithread preprocessing of ipecamera frames and code reorganization
430
	return PCILIB_ERROR_MEMORY;
431
    }
432
    
433
    memset(ctx->frame, 0, ctx->buffer_size * sizeof(ipecamera_frame_t));
434
    
435
    for (i = 0; i < ctx->buffer_size; i++) {
436
	err = pthread_rwlock_init(&ctx->frame[i].mutex, NULL);
437
	if (err) break;
438
    }
439
440
    ctx->frame_mutex_destroy = i;
441
442
    if (err) {
443
        ipecamera_stop(vctx, PCILIB_EVENT_FLAGS_DEFAULT);
444
	pcilib_error("Initialization of rwlock mutexes for frame synchronization has failed");
445
	return PCILIB_ERROR_FAILED;
16 by Suren A. Chilingaryan
Prototype of IPECamera image protocol
446
    }
124 by Suren A. Chilingaryan
Image frames decoding
447
    
448
    ctx->ipedec = ufo_decoder_new(ctx->dim.height, ctx->dim.width, NULL, 0);
449
    if (!ctx->ipedec) {
126 by Suren A. Chilingaryan
multithread preprocessing of ipecamera frames and code reorganization
450
        ipecamera_stop(vctx, PCILIB_EVENT_FLAGS_DEFAULT);
124 by Suren A. Chilingaryan
Image frames decoding
451
	pcilib_error("Unable to initialize IPECamera decoder library");
452
	return PCILIB_ERROR_FAILED;
453
    }
93 by root
DMA support in IPE Camera
454
455
    if (!err) {
117 by Suren A. Chilingaryan
new event architecture, first trial
456
	ctx->rdma = pcilib_find_dma_by_addr(vctx->pcilib, PCILIB_DMA_FROM_DEVICE, IPECAMERA_DMA_ADDRESS);
93 by root
DMA support in IPE Camera
457
	if (ctx->rdma == PCILIB_DMA_ENGINE_INVALID) {
458
	    err = PCILIB_ERROR_NOTFOUND;
459
	    pcilib_error("The C2S channel of IPECamera DMA Engine (%u) is not found", IPECAMERA_DMA_ADDRESS);
460
	} else {
117 by Suren A. Chilingaryan
new event architecture, first trial
461
	    err = pcilib_start_dma(vctx->pcilib, ctx->rdma, PCILIB_DMA_FLAGS_DEFAULT);
93 by root
DMA support in IPE Camera
462
	    if (err) {
463
		ctx->rdma = PCILIB_DMA_ENGINE_INVALID;
464
		pcilib_error("Failed to initialize C2S channel of IPECamera DMA Engine (%u)", IPECAMERA_DMA_ADDRESS);
465
	    }
466
	}
467
    }
468
    
126 by Suren A. Chilingaryan
multithread preprocessing of ipecamera frames and code reorganization
469
    if (err) {
470
        ipecamera_stop(vctx, PCILIB_EVENT_FLAGS_DEFAULT);
471
	return err;
472
    }
473
252 by Suren A. Chilingaryan
Cleanup
474
#ifdef IPECAMERA_CLEAN_ON_START
117 by Suren A. Chilingaryan
new event architecture, first trial
475
    err = pcilib_skip_dma(vctx->pcilib, ctx->rdma);
476
    if (err) {
126 by Suren A. Chilingaryan
multithread preprocessing of ipecamera frames and code reorganization
477
        ipecamera_stop(vctx, PCILIB_EVENT_FLAGS_DEFAULT);
117 by Suren A. Chilingaryan
new event architecture, first trial
478
	pcilib_error("Can't start grabbing, device continuously writes unexpected data using DMA engine");
479
	return err;
480
    }
252 by Suren A. Chilingaryan
Cleanup
481
#endif /* IPECAMERA_CLEAN_ON_START */
117 by Suren A. Chilingaryan
new event architecture, first trial
482
483
    if (vctx->params.autostop.duration) {
484
	gettimeofday(&ctx->autostop.timestamp, NULL);
485
	ctx->autostop.timestamp.tv_usec += vctx->params.autostop.duration % 1000000;
486
	if (ctx->autostop.timestamp.tv_usec > 999999) {
487
	    ctx->autostop.timestamp.tv_sec += 1 + vctx->params.autostop.duration / 1000000;
488
	    ctx->autostop.timestamp.tv_usec -= 1000000;
489
	} else {
490
	    ctx->autostop.timestamp.tv_sec += vctx->params.autostop.duration / 1000000;
491
	}
492
    }
493
    
494
    if (vctx->params.autostop.max_events) {
495
	ctx->autostop.evid = vctx->params.autostop.max_events;
496
    }
15 by Suren A. Chilingaryan
Infrastructure for event API
497
    
144 by Suren A. Chilingaryan
Do not call the normall callback in the raw-data-only mode
498
    if ((ctx->parse_data)&&(flags&PCILIB_EVENT_FLAG_PREPROCESS)) {
126 by Suren A. Chilingaryan
multithread preprocessing of ipecamera frames and code reorganization
499
	ctx->n_preproc = pcilib_get_cpu_count();
135 by Suren A. Chilingaryan
Allow to configure the number of preprocessing threads
500
	
501
	    // it would be greate to detect hyperthreading cores and ban them
126 by Suren A. Chilingaryan
multithread preprocessing of ipecamera frames and code reorganization
502
	switch (ctx->n_preproc) {
503
	    case 1: break;
208 by Suren A. Chilingaryan
I have no clue how to properly write switch statements.... Fixed.
504
	    case 2 ... 3: ctx->n_preproc -= 1; break;
126 by Suren A. Chilingaryan
multithread preprocessing of ipecamera frames and code reorganization
505
	    default: ctx->n_preproc -= 2; break;
506
	}
135 by Suren A. Chilingaryan
Allow to configure the number of preprocessing threads
507
508
	if ((vctx->params.parallel.max_threads)&&(vctx->params.parallel.max_threads < ctx->n_preproc))
509
	    ctx->n_preproc = vctx->params.parallel.max_threads;
510
126 by Suren A. Chilingaryan
multithread preprocessing of ipecamera frames and code reorganization
511
	ctx->preproc = (ipecamera_preprocessor_t*)malloc(ctx->n_preproc * sizeof(ipecamera_preprocessor_t));
512
	if (!ctx->preproc) {
513
	    ipecamera_stop(vctx, PCILIB_EVENT_FLAGS_DEFAULT);
514
	    pcilib_error("Unable to allocate memory for preprocessor contexts");
515
	    return PCILIB_ERROR_MEMORY;
516
	}
517
518
	memset(ctx->preproc, 0, ctx->n_preproc * sizeof(ipecamera_preprocessor_t));
519
520
	err = pthread_mutex_init(&ctx->preproc_mutex, NULL);
521
	if (err) {
522
	    ipecamera_stop(vctx, PCILIB_EVENT_FLAGS_DEFAULT);
523
	    pcilib_error("Failed to initialize event mutex");
524
	    return PCILIB_ERROR_FAILED;
525
	}
526
	ctx->preproc_mutex_destroy = 1;
527
	
528
529
	ctx->run_preprocessors = 1;
530
	for (i = 0; i < ctx->n_preproc; i++) {
531
	    ctx->preproc[i].i = i;
532
	    ctx->preproc[i].ipecamera = ctx;
533
	    err = pthread_create(&ctx->preproc[i].thread, NULL, ipecamera_preproc_thread, ctx->preproc + i);
534
	    if (err) {
535
		err = PCILIB_ERROR_FAILED;
536
		break;
537
	    } else {
538
		ctx->preproc[i].started = 1;
539
	    }
540
	}
541
	
542
	if (err) {
543
	    ipecamera_stop(vctx, PCILIB_EVENT_FLAGS_DEFAULT);
544
	    pcilib_error("Failed to schedule some of the preprocessor threads");
545
	    return err;
546
	}
547
    } else {
548
	ctx->n_preproc = 0;
549
    }
550
21 by Suren A. Chilingaryan
Small bug fix: forgot to set a flag indicating what we are started
551
    ctx->started = 1;
117 by Suren A. Chilingaryan
new event architecture, first trial
552
    ctx->run_reader = 1;
126 by Suren A. Chilingaryan
multithread preprocessing of ipecamera frames and code reorganization
553
117 by Suren A. Chilingaryan
new event architecture, first trial
554
    pthread_attr_init(&attr);
555
556
    if (pthread_attr_setschedpolicy(&attr, SCHED_FIFO)) {
557
	pcilib_warning("Can't schedule a real-time thread, you may consider running as root");
558
    } else {
559
	sched.sched_priority = sched_get_priority_max(SCHED_FIFO) - 1;	// Let 1 priority for something really critcial
560
	pthread_attr_setschedparam(&attr, &sched);
561
    }
171 by Suren A. Chilingaryan
Fix temperature register of ipecamera and prepend all cmosis registers with _cmosis prefix
562
117 by Suren A. Chilingaryan
new event architecture, first trial
563
    if (pthread_create(&ctx->rthread, &attr, &ipecamera_reader_thread, (void*)ctx)) {
564
	ctx->started = 0;
565
	ipecamera_stop(vctx, PCILIB_EVENT_FLAGS_DEFAULT);
126 by Suren A. Chilingaryan
multithread preprocessing of ipecamera frames and code reorganization
566
	err = PCILIB_ERROR_FAILED;
117 by Suren A. Chilingaryan
new event architecture, first trial
567
    }
568
    
569
    pthread_attr_destroy(&attr);    
570
262 by Suren A. Chilingaryan
Introduce API debugging
571
    ipecamera_debug(API, "ipecamera: started");
572
117 by Suren A. Chilingaryan
new event architecture, first trial
573
    return err;
15 by Suren A. Chilingaryan
Infrastructure for event API
574
}
575
576
117 by Suren A. Chilingaryan
new event architecture, first trial
577
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
578
    int i;
117 by Suren A. Chilingaryan
new event architecture, first trial
579
    int err;
580
    void *retcode;
15 by Suren A. Chilingaryan
Infrastructure for event API
581
    ipecamera_t *ctx = (ipecamera_t*)vctx;
582
583
    if (!ctx) {
584
	pcilib_error("IPECamera imaging is not initialized");
585
	return PCILIB_ERROR_NOTINITIALIZED;
586
    }
16 by Suren A. Chilingaryan
Prototype of IPECamera image protocol
587
119 by Suren A. Chilingaryan
Initial support of event streaming in cli
588
    if (flags&PCILIB_EVENT_FLAG_STOP_ONLY) {
589
	ctx->run_reader = 0;
590
	return 0;
591
    }
126 by Suren A. Chilingaryan
multithread preprocessing of ipecamera frames and code reorganization
592
262 by Suren A. Chilingaryan
Introduce API debugging
593
    ipecamera_debug(API, "ipecamera: stopping");
594
117 by Suren A. Chilingaryan
new event architecture, first trial
595
    if (ctx->started) {
596
	ctx->run_reader = 0;
597
	err = pthread_join(ctx->rthread, &retcode);
598
	if (err) pcilib_error("Error joining the reader thread");
599
    }
126 by Suren A. Chilingaryan
multithread preprocessing of ipecamera frames and code reorganization
600
    
601
    if (ctx->preproc) {
602
	ctx->run_preprocessors = 0;
603
	
604
	for (i = 0; i < ctx->n_preproc; i++) {
605
	    if (ctx->preproc[i].started) {
606
		pthread_join(ctx->preproc[i].thread, &retcode);
607
		ctx->preproc[i].started = 0;
608
	    }
609
	}
21 by Suren A. Chilingaryan
Small bug fix: forgot to set a flag indicating what we are started
610
126 by Suren A. Chilingaryan
multithread preprocessing of ipecamera frames and code reorganization
611
	if (ctx->preproc_mutex_destroy) {
612
	    pthread_mutex_destroy(&ctx->preproc_mutex);
613
	    ctx->preproc_mutex_destroy = 0;
614
	}
615
	
616
	free(ctx->preproc);
617
	ctx->preproc = NULL;
618
    }
619
    
620
    if (ctx->frame_mutex_destroy) {
621
	for (i = 0; i < ctx->frame_mutex_destroy; i++) {
622
	    pthread_rwlock_destroy(&ctx->frame[i].mutex);
623
	}
624
	ctx->frame_mutex_destroy = 0;
625
    }
93 by root
DMA support in IPE Camera
626
627
    if (ctx->rdma != PCILIB_DMA_ENGINE_INVALID) {
117 by Suren A. Chilingaryan
new event architecture, first trial
628
	pcilib_stop_dma(vctx->pcilib, ctx->rdma, PCILIB_DMA_FLAGS_DEFAULT);
93 by root
DMA support in IPE Camera
629
	ctx->rdma = PCILIB_DMA_ENGINE_INVALID;
630
    }
190.1.1 by Suren A. Chilingaryan
In ipecamera_stop wait until streaming user-thread is terminated
631
632
    while (ctx->streaming) {
633
        usleep(IPECAMERA_NOFRAME_SLEEP);
634
    }
635
124 by Suren A. Chilingaryan
Image frames decoding
636
    if (ctx->ipedec) {
637
	ufo_decoder_free(ctx->ipedec);
638
	ctx->ipedec = NULL;
639
    }
93 by root
DMA support in IPE Camera
640
126 by Suren A. Chilingaryan
multithread preprocessing of ipecamera frames and code reorganization
641
    if (ctx->frame) {
642
	free(ctx->frame);
643
	ctx->frame = NULL;
117 by Suren A. Chilingaryan
new event architecture, first trial
644
    }
645
124 by Suren A. Chilingaryan
Image frames decoding
646
    if (ctx->cmask) {
647
	free(ctx->cmask);
648
	ctx->cmask = NULL;
649
    }
650
651
    if (ctx->image) {
652
	free(ctx->image);
653
	ctx->image = NULL;
654
    }
655
16 by Suren A. Chilingaryan
Prototype of IPECamera image protocol
656
    if (ctx->buffer) {
657
	free(ctx->buffer);
658
	ctx->buffer = NULL;
659
    }
660
117 by Suren A. Chilingaryan
new event architecture, first trial
661
    memset(&ctx->autostop, 0, sizeof(ipecamera_autostop_t));
16 by Suren A. Chilingaryan
Prototype of IPECamera image protocol
662
663
    ctx->event_id = 0;
29 by Suren A. Chilingaryan
Support non-callback way of getting events
664
    ctx->reported_id = 0;
117 by Suren A. Chilingaryan
new event architecture, first trial
665
    ctx->buffer_pos = 0; 
666
    ctx->started = 0;
667
262 by Suren A. Chilingaryan
Introduce API debugging
668
    ipecamera_debug(API, "ipecamera: stopped");
265 by Suren A. Chilingaryan
Use new locking subsystem to ensure integrity
669
    UNLOCK(run);
670
117 by Suren A. Chilingaryan
new event architecture, first trial
671
    return 0;
15 by Suren A. Chilingaryan
Infrastructure for event API
672
}
673
674
31 by Suren A. Chilingaryan
Introduce pcilib_context_t type instead pointer to void
675
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
676
    int err = 0;
677
    pcilib_register_value_t value;
678
15 by Suren A. Chilingaryan
Infrastructure for event API
679
    ipecamera_t *ctx = (ipecamera_t*)vctx;
117 by Suren A. Chilingaryan
new event architecture, first trial
680
    pcilib_t *pcilib = vctx->pcilib;
15 by Suren A. Chilingaryan
Infrastructure for event API
681
245 by Suren A. Chilingaryan
First stand-alone ipecamera implementation
682
    const pcilib_model_description_t *model_info = pcilib_get_model_description(pcilib);
683
15 by Suren A. Chilingaryan
Infrastructure for event API
684
    if (!ctx) {
685
	pcilib_error("IPECamera imaging is not initialized");
686
	return PCILIB_ERROR_NOTINITIALIZED;
687
    }
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
688
265 by Suren A. Chilingaryan
Use new locking subsystem to ensure integrity
689
    ipecamera_debug(API, "ipecamera: trigger");
690
    LOCK(trigger);
691
132 by Suren A. Chilingaryan
Minor fixes and improvements
692
    pcilib_sleep_until_deadline(&ctx->next_trigger);
239 by Suren A. Chilingaryan
ipecamera hack
693
/*
174 by Suren A. Chilingaryan
Check for free space in camera DDR buffer before triggering event
694
    GET_REG(num_frames_reg, value);
695
    if (value == ctx->max_frames) {
696
	return PCILIB_ERROR_BUSY;
697
    }
239 by Suren A. Chilingaryan
ipecamera hack
698
*/
240 by Suren A. Chilingaryan
Fix frame size computation in ipecamera and few debuging options
699
700
    GET_REG(status2_reg, value);
701
    if (value&0x40000000) {
252 by Suren A. Chilingaryan
Cleanup
702
	if (value == 0xffffffff)
703
	    pcilib_info("Failed to read status2_reg while triggering");
240 by Suren A. Chilingaryan
Fix frame size computation in ipecamera and few debuging options
704
252 by Suren A. Chilingaryan
Cleanup
705
#ifdef IPECAMERA_TRIGGER_TIMEOUT
706
	if (IPECAMERA_TRIGGER_TIMEOUT) {
240 by Suren A. Chilingaryan
Fix frame size computation in ipecamera and few debuging options
707
	    struct timeval deadline;
252 by Suren A. Chilingaryan
Cleanup
708
	    pcilib_calc_deadline(&deadline, IPECAMERA_TRIGGER_TIMEOUT);
240 by Suren A. Chilingaryan
Fix frame size computation in ipecamera and few debuging options
709
	    do {
710
		usleep(IPECAMERA_READ_STATUS_DELAY);
711
		GET_REG(status2_reg, value);
712
	    } while ((value&0x40000000)&&(pcilib_calc_time_to_deadline(&deadline) > 0));
713
	}
265 by Suren A. Chilingaryan
Use new locking subsystem to ensure integrity
714
	if (value&0x40000000) {
240 by Suren A. Chilingaryan
Fix frame size computation in ipecamera and few debuging options
715
#endif /* IPECAMERA_TRIGGER_WAIT_IDLE */
265 by Suren A. Chilingaryan
Use new locking subsystem to ensure integrity
716
	    UNLOCK(trigger);
240 by Suren A. Chilingaryan
Fix frame size computation in ipecamera and few debuging options
717
	    return PCILIB_ERROR_BUSY;
265 by Suren A. Chilingaryan
Use new locking subsystem to ensure integrity
718
#ifdef IPECAMERA_TRIGGER_TIMEOUT
719
	}
720
#endif /* IPECAMERA_TRIGGER_WAIT_IDLE */
240 by Suren A. Chilingaryan
Fix frame size computation in ipecamera and few debuging options
721
    }
215 by Suren A. Chilingaryan
Properly support triggering with new revision of UFO camera
722
261 by Suren A. Chilingaryan
Support for new CMOSIS 20MPix camera
723
    GET_REG(control_reg, value);
215 by Suren A. Chilingaryan
Properly support triggering with new revision of UFO camera
724
    SET_REG(control_reg, value|IPECAMERA_FRAME_REQUEST);
252 by Suren A. Chilingaryan
Cleanup
725
    usleep(IPECAMERA_TRIGGER_DELAY);
215 by Suren A. Chilingaryan
Properly support triggering with new revision of UFO camera
726
    SET_REG(control_reg, value);
117 by Suren A. Chilingaryan
new event architecture, first trial
727
252 by Suren A. Chilingaryan
Cleanup
728
	// 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
729
    pcilib_calc_deadline(&ctx->next_trigger, IPECAMERA_NEXT_FRAME_DELAY);
265 by Suren A. Chilingaryan
Use new locking subsystem to ensure integrity
730
    
731
    UNLOCK(trigger);
117 by Suren A. Chilingaryan
new event architecture, first trial
732
119 by Suren A. Chilingaryan
Initial support of event streaming in cli
733
    return 0;
117 by Suren A. Chilingaryan
new event architecture, first trial
734
}