/alps/pcitool

To get this branch, use:
bzr branch http://suren.me/webbzr/alps/pcitool

« back to all changes in this revision

Viewing changes to ipecamera/image.c

  • Committer: Suren A. Chilingaryan
  • Date: 2011-12-08 02:47:23 UTC
  • Revision ID: csa@dside.dyndns.org-20111208024723-ym9uf3uoll6ym2a9
new event architecture, first trial

Show diffs side-by-side

added added

removed removed

Lines of Context:
6
6
#include <unistd.h>
7
7
#include <string.h>
8
8
#include <sys/time.h>
 
9
#include <pthread.h>
9
10
#include <assert.h>
10
11
 
11
12
#include "../tools.h"
14
15
#include "pcilib.h"
15
16
 
16
17
#include "model.h"
 
18
#include "event.h"
17
19
#include "image.h"
18
20
 
19
21
#include "dma/nwl_dma.h"
23
25
#endif /* IPECAMERA_DEBUG */
24
26
 
25
27
 
26
 
#define IPECAMERA_SLEEP_TIME 250000 // Michele thinks 250 should be enough, but reset failing in this case
27
 
#define IPECAMERA_NEXT_FRAME_DELAY 30000 // please don't change this value --> sync between End Of Readout and next Frame Req, by Michele 
28
 
#define IPECAMERA_WAIT_FRAME_RCVD_TIME 0 /* by Uros ,wait 6 ms */
 
28
#define IPECAMERA_BUG_EXTRA_DATA
 
29
 
 
30
#define IPECAMERA_DEFAULT_BUFFER_SIZE 64        //**< should be power of 2 */
 
31
#define IPECAMERA_RESERVE_BUFFERS 2             //**< Return Frame is Lost error, if requested frame will be overwritten after specified number of frames
 
32
#define IPECAMERA_SLEEP_TIME 250000             //**< Michele thinks 250 should be enough, but reset failing in this case */
 
33
#define IPECAMERA_NEXT_FRAME_DELAY 1000         //**< Michele requires 30000 to sync between End Of Readout and next Frame Req */
 
34
#define IPECAMERA_WAIT_FRAME_RCVD_TIME 0        //**< by Uros ,wait 6 ms */
 
35
#define IPECAMERA_NOFRAME_SLEEP 100
 
36
 
29
37
#define IPECAMERA_MAX_LINES 1088
30
 
#define IPECAMERA_DEFAULT_BUFFER_SIZE 10
31
38
#define IPECAMERA_EXPECTED_STATUS 0x08409FFFF
32
39
#define IPECAMERA_END_OF_SEQUENCE 0x1F001001
33
40
 
34
41
#define IPECAMERA_MAX_CHANNELS 16
35
42
#define IPECAMERA_PIXELS_PER_CHANNEL 128
36
43
#define IPECAMERA_WIDTH (IPECAMERA_MAX_CHANNELS * IPECAMERA_PIXELS_PER_CHANNEL)
37
 
#define IPECAMERA_HEIGHT 1088 //1088
38
44
 
 
45
/*
 
46
#define IPECAMERA_HEIGHT 1088
39
47
#if IPECAMERA_HEIGHT < IPECAMERA_MAX_LINES
40
48
# undef IPECAMERA_MAX_LINES
41
49
# define IPECAMERA_MAX_LINES IPECAMERA_HEIGHT
42
50
#endif 
 
51
*/
43
52
 
44
53
//#define IPECAMERA_MEMORY 
45
54
 
46
55
#define IPECAMERA_FRAME_REQUEST                 0x1E9
 
56
#define IPECAMERA_READOUT_FLAG                  0x200
47
57
#define IPECAMERA_READOUT                       0x3E1
48
58
#define IPECAMERA_IDLE                          0x1E1
49
59
#define IPECAMERA_START_INTERNAL_STIMULI        0x1F1
60
70
 
61
71
typedef uint32_t ipecamera_payload_t;
62
72
 
 
73
typedef struct {
 
74
    pcilib_event_info_t info;
 
75
} ipecamera_event_info_t;
 
76
 
 
77
typedef struct {
 
78
    pcilib_event_id_t evid;
 
79
    struct timeval timestamp;
 
80
} ipecamera_autostop_t;
 
81
 
63
82
struct ipecamera_s {
64
 
    pcilib_t *pcilib;
 
83
    pcilib_context_t event;
65
84
 
66
85
#ifndef IPECAMERA_DMA_ADDRESS    
67
86
    char *data;
86
105
    pcilib_register_t exposure_reg;
87
106
    pcilib_register_t flip_reg;
88
107
 
89
 
    int started;
90
 
    int buffer_size;
91
 
    int buf_ptr;
 
108
    int started;                /**< Camera is in grabbing mode (start function is called) */
 
109
    int streaming;              /**< Camera is in streaming mode (we are within stream call) */
 
110
    int parse_data;             /**< Indicates if some processing of the data is required, otherwise only rawdata_callback will be called */
 
111
 
 
112
    int run_reader;             /**< Instructs the reader thread to stop processing */
 
113
    int run_streamer;           /**< Indicates request to stop streaming events and can be set by reader_thread upon exit or by user request */
 
114
    ipecamera_autostop_t autostop;
 
115
 
 
116
    struct timeval autostop_time;
 
117
//    int ready;                        /**< New frame is ready */
 
118
//    int check_time;           /**< Streaming is time-limited */
 
119
 
 
120
    size_t buffer_size;         /**< How many images to store */
 
121
    size_t buffer_pos;          /**< Current image offset in the buffer, due to synchronization reasons should not be used outside of reader_thread */
 
122
//    size_t stream_count;      /**< Number of images read so far */
 
123
//    size_t stream_max;                /**< Maximum number of images to read */
 
124
//    struct timeval stream_stop;       /**< Time to stop streaming */
 
125
    size_t cur_size;            /**< Already written part of data in bytes */
 
126
    size_t raw_size;            /**< Size of raw data in bytes */
 
127
    size_t full_size;           /**< Size of raw data including the padding */
 
128
    size_t padded_size;         /**< Size of buffer for raw data, including the padding for performance */
 
129
    
 
130
    size_t image_size;          /**< Size of a single image in bytes */
92
131
    
93
132
    int width, height;
94
133
 
95
 
    ipecamera_pixel_t *buffer;
 
134
    
 
135
//    void *raw_buffer;
 
136
    void *buffer;
96
137
    ipecamera_change_mask_t *cmask;
 
138
    ipecamera_event_info_t *frame_info;
 
139
    
97
140
 
98
141
    ipecamera_image_dimensions_t dim;
 
142
 
 
143
    pthread_t rthread;
99
144
};
100
145
 
101
146
 
156
201
    if (ctx) {
157
202
        memset(ctx, 0, sizeof(ipecamera_t));
158
203
        
159
 
        ctx->pcilib = pcilib;
160
 
 
161
204
        ctx->buffer_size = IPECAMERA_DEFAULT_BUFFER_SIZE;
162
205
        ctx->dim.bpp = sizeof(ipecamera_pixel_t) * 8;
163
206
 
181
224
        FIND_REG(line_reg, "cmosis", "start1");
182
225
        FIND_REG(exposure_reg, "cmosis", "exp_time");
183
226
        FIND_REG(flip_reg, "cmosis", "image_flipping");
184
 
        
 
227
 
185
228
        ctx->rdma = PCILIB_DMA_ENGINE_INVALID;
186
229
        ctx->wdma = PCILIB_DMA_ENGINE_INVALID;
187
230
 
198
241
void ipecamera_free(pcilib_context_t *vctx) {
199
242
    if (vctx) {
200
243
        ipecamera_t *ctx = (ipecamera_t*)vctx;
201
 
        ipecamera_stop(vctx);
 
244
        ipecamera_stop(vctx, PCILIB_EVENT_FLAGS_DEFAULT);
202
245
        free(ctx);
203
246
    }
204
247
}
206
249
pcilib_dma_context_t *ipecamera_init_dma(pcilib_context_t *vctx) {
207
250
    ipecamera_t *ctx = (ipecamera_t*)vctx;
208
251
    
209
 
    pcilib_model_description_t *model_info = pcilib_get_model_description(ctx->pcilib);
 
252
    pcilib_model_description_t *model_info = pcilib_get_model_description(vctx->pcilib);
210
253
    if ((!model_info->dma_api)||(!model_info->dma_api->init)) {
211
254
        pcilib_error("The DMA engine is not configured in model");
212
255
        return NULL;
214
257
 
215
258
 
216
259
#ifdef IPECAMERA_DMA_R3
217
 
    return model_info->dma_api->init(ctx->pcilib, PCILIB_NWL_MODIFICATION_IPECAMERA, NULL);
 
260
    return model_info->dma_api->init(vctx->pcilib, PCILIB_NWL_MODIFICATION_IPECAMERA, NULL);
218
261
#else
219
 
    return model_info->dma_api->init(ctx->pcilib, PCILIB_DMA_MODIFICATION_DEFAULT, NULL);
 
262
    return model_info->dma_api->init(vctx->pcilib, PCILIB_DMA_MODIFICATION_DEFAULT, NULL);
220
263
#endif
221
264
}
222
265
 
227
270
        return PCILIB_ERROR_INVALID_REQUEST;
228
271
    }
229
272
    
230
 
    if (ctx->size < 1) {
 
273
    if (size < 2) {
231
274
        pcilib_error("The buffer size is too small");
232
275
        return PCILIB_ERROR_INVALID_REQUEST;
233
276
    }
234
 
 
 
277
    
 
278
    if (((size^(size-1)) < size) < size) {
 
279
        pcilib_error("The buffer size is not power of 2");
 
280
    }
 
281
    
235
282
    ctx->buffer_size = size;
236
283
    
237
284
    return 0;
238
285
}
239
286
 
240
 
 
241
287
int ipecamera_reset(pcilib_context_t *vctx) {
242
 
    int err;
243
 
    pcilib_t *pcilib;
 
288
    int err = 0;
244
289
    ipecamera_t *ctx = (ipecamera_t*)vctx;
 
290
    pcilib_t *pcilib = vctx->pcilib;
245
291
 
246
292
    pcilib_register_t control, status;
247
293
    pcilib_register_value_t value;
251
297
        return PCILIB_ERROR_NOTINITIALIZED;
252
298
    }
253
299
 
254
 
    pcilib = ctx->pcilib;
 
300
    pcilib = vctx->pcilib;
255
301
    control = ctx->control_reg;
256
302
    status = ctx->status_reg;
257
303
 
258
304
        // Set Reset bit to CMOSIS
259
305
    err = pcilib_write_register_by_id(pcilib, control, 0x1e4);
260
306
    if (err) {
261
 
        pcilib_error("Error setting CMOSIS reset bit");
 
307
        pcilib_error("Error setting FPGA reset bit");
262
308
        return err;
263
309
    }
264
310
    usleep(IPECAMERA_SLEEP_TIME);
266
312
        // Remove Reset bit to CMOSIS
267
313
    err = pcilib_write_register_by_id(pcilib, control, 0x1e1);
268
314
    if (err) {
269
 
        pcilib_error("Error reseting CMOSIS reset bit");
 
315
        pcilib_error("Error reseting FPGA reset bit");
270
316
        return err;
271
317
    }
272
318
    usleep(IPECAMERA_SLEEP_TIME);
287
333
    usleep(IPECAMERA_SLEEP_TIME);
288
334
 
289
335
        // Set default parameters
290
 
    SET_REG(control_reg, IPECAMERA_IDLE);
291
 
    if (err) return err;
292
 
    
 
336
    err = pcilib_write_register_by_id(pcilib, control, IPECAMERA_IDLE);
 
337
    if (err) {
 
338
        pcilib_error("Error bringing FPGA in default mode");
 
339
        return err;
 
340
    }
 
341
 
293
342
    usleep(10000);
294
 
    
 
343
 
 
344
        
295
345
    err = pcilib_read_register_by_id(pcilib, status, &value);
296
346
    if (err) {
297
347
        pcilib_error("Error reading status register");
306
356
    return 0;    
307
357
}
308
358
 
309
 
int ipecamera_start(pcilib_context_t *vctx, pcilib_event_t event_mask, pcilib_event_callback_t cb, void *user) {
 
359
// DS: Currently, on event_id overflow we are assuming the buffer is lost
 
360
static int ipecamera_resolve_event_id(ipecamera_t *ctx, pcilib_event_id_t evid) {
 
361
    pcilib_event_id_t diff;
 
362
 
 
363
    if (evid > ctx->event_id) {
 
364
        diff = (((pcilib_event_id_t)-1) - ctx->event_id) + evid;
 
365
        if (diff >= ctx->buffer_size) return -1;
 
366
    } else {
 
367
        diff = ctx->event_id - evid;
 
368
        if (diff >= ctx->buffer_size) return -1;
 
369
    }
 
370
    
 
371
        // DS: Request buffer_size to be power of 2 and replace to shifts (just recompute in set_buffer_size)
 
372
    return (evid - 1) % ctx->buffer_size;
 
373
}
 
374
 
 
375
static inline void ipecamera_new_frame(ipecamera_t *ctx) {
 
376
    ctx->buffer_pos = (++ctx->event_id) % ctx->buffer_size;
 
377
    ctx->cur_size = 0;
 
378
 
 
379
    ctx->frame_info[ctx->buffer_pos].info.type = PCILIB_EVENT0;
 
380
//      memset(ctx->cmask + ctx->buffer_pos * ctx->dim.height, 0, ctx->dim.height * sizeof(ipecamera_change_mask_t));
 
381
}
 
382
 
 
383
static uint32_t frame_magic[6] = { 0x51111111, 0x52222222, 0x53333333, 0x54444444, 0x55555555, 0x56666666 };
 
384
 
 
385
static int ipecamera_data_callback(void *user, pcilib_dma_flags_t flags, size_t bufsize, void *buf) {
 
386
    int eof = 0;
 
387
    ipecamera_t *ctx = (ipecamera_t*)user;
 
388
 
 
389
 
 
390
    if ((bufsize >= 8)&&(!memcmp(buf, frame_magic, sizeof(frame_magic)))) {
 
391
        //if (ctx->cur_size) ipecamera_new_frame(ctx);
 
392
        ctx->frame_info[ctx->buffer_pos].info.seqnum = ((uint32_t*)buf)[6] & 0xF0000000;
 
393
        ctx->frame_info[ctx->buffer_pos].info.offset = ((uint32_t*)buf)[7] & 0xF0000000;
 
394
        gettimeofday(&ctx->frame_info[ctx->buffer_pos].info.timestamp, NULL);
 
395
    }
 
396
 
 
397
    if (ctx->parse_data) {
 
398
        if (ctx->cur_size + bufsize > ctx->full_size) {
 
399
            pcilib_error("Unexpected event data, we are expecting at maximum (%zu) bytes, but (%zu) already read", ctx->full_size, ctx->cur_size + bufsize);
 
400
            return -PCILIB_ERROR_TOOBIG;
 
401
        }
 
402
 
 
403
        memcpy(ctx->buffer + ctx->buffer_pos * ctx->padded_size +  ctx->cur_size, buf, bufsize);
 
404
    }
 
405
 
 
406
    ctx->cur_size += bufsize;
 
407
//    printf("%i: %i %i\n", ctx->buffer_pos, ctx->cur_size, bufsize);
 
408
 
 
409
    if (ctx->cur_size >= ctx->full_size) eof = 1;
 
410
 
 
411
    if (ctx->event.params.rawdata.callback) {
 
412
        ctx->event.params.rawdata.callback(ctx->event_id, (pcilib_event_info_t*)(ctx->frame_info + ctx->buffer_pos), (eof?PCILIB_EVENT_FLAG_EOF:PCILIB_EVENT_FLAGS_DEFAULT), bufsize, buf, ctx->event.params.rawdata.user);
 
413
    }
 
414
    
 
415
    if (eof) {
 
416
        ipecamera_new_frame(ctx);
 
417
        
 
418
        if ((ctx->event_id == ctx->autostop.evid)&&(ctx->event_id)) {
 
419
            ctx->run_reader = 0;
 
420
            return PCILIB_STREAMING_STOP;
 
421
        }
 
422
        
 
423
        if (check_deadline(&ctx->autostop.timestamp, PCILIB_DMA_TIMEOUT)) {
 
424
            ctx->run_reader = 0;
 
425
            return PCILIB_STREAMING_STOP;
 
426
        }
 
427
    }
 
428
 
 
429
    return PCILIB_STREAMING_REQ_FRAGMENT;
 
430
}
 
431
 
 
432
static void *ipecamera_reader_thread(void *user) {
 
433
    int err;
 
434
    ipecamera_t *ctx = (ipecamera_t*)user;
 
435
    
 
436
    while (ctx->run_reader) {
 
437
        err = pcilib_stream_dma(ctx->event.pcilib, ctx->rdma, 0, 0, PCILIB_DMA_FLAG_MULTIPACKET, PCILIB_DMA_TIMEOUT, &ipecamera_data_callback, user);
 
438
        if (err) {
 
439
            if (err == PCILIB_ERROR_TIMEOUT) {
 
440
                if (check_deadline(&ctx->autostop.timestamp, PCILIB_DMA_TIMEOUT)) {
 
441
                    ctx->run_reader = 0;
 
442
                    break;
 
443
                }
 
444
                usleep(IPECAMERA_NOFRAME_SLEEP);
 
445
            } else pcilib_error("DMA error while reading IPECamera frames, error: %i", err);
 
446
        }
 
447
 
 
448
        usleep(1000);
 
449
    }
 
450
    
 
451
    ctx->run_streamer = 0;
 
452
    
 
453
    if (ctx->cur_size) pcilib_error("partialy read frame after stop signal, %zu bytes in the buffer", ctx->cur_size);
 
454
 
 
455
    return NULL;
 
456
}
 
457
 
 
458
int ipecamera_start(pcilib_context_t *vctx, pcilib_event_t event_mask, pcilib_event_flags_t flags) {
310
459
    int err = 0;
311
460
    ipecamera_t *ctx = (ipecamera_t*)vctx;
312
 
    pcilib_t *pcilib = ctx->pcilib;
 
461
    pcilib_t *pcilib = vctx->pcilib;
313
462
    pcilib_register_value_t value;
314
 
 
 
463
    
 
464
    const size_t chan_size = (2 + IPECAMERA_PIXELS_PER_CHANNEL / 3) * sizeof(ipecamera_payload_t);
 
465
    const size_t line_size = (IPECAMERA_MAX_CHANNELS * chan_size);
 
466
    const size_t header_size = 8;
 
467
    const size_t footer_size = 8;
 
468
    size_t raw_size;
 
469
    size_t padded_blocks;
 
470
    
 
471
    pthread_attr_t attr;
 
472
    struct sched_param sched;
 
473
    
315
474
    if (!ctx) {
316
475
        pcilib_error("IPECamera imaging is not initialized");
317
476
        return PCILIB_ERROR_NOTINITIALIZED;
322
481
        return PCILIB_ERROR_INVALID_REQUEST;
323
482
    }
324
483
 
325
 
        // if left in FRAME_REQUEST mode
326
 
    SET_REG(control_reg, IPECAMERA_IDLE);
 
484
 
 
485
        // Allow readout and clean the FRAME_REQUEST mode if set for some reason
 
486
    SET_REG(control_reg, IPECAMERA_IDLE|IPECAMERA_READOUT_FLAG);
327
487
    usleep(IPECAMERA_SLEEP_TIME);
328
488
    CHECK_REG(status_reg, IPECAMERA_EXPECTED_STATUS);
329
489
    if (err) return err;
330
490
 
331
491
 
332
 
//#ifdef IPECAMERA_DMA_ADDRESS
333
 
//    SET_REG(packet_len_reg, IPECAMERA_DMA_PACKET_LENGTH);
334
 
//    if (err) return err;
335
 
//#endif /* IPECAMERA_DMA_ADDRESS */
336
 
    
337
 
    ctx->cb = cb;
338
 
    ctx->cb_user = user;
339
 
    
340
492
    ctx->event_id = 0;
341
493
    ctx->reported_id = 0;
342
 
    ctx->buf_ptr = 0;    
 
494
    ctx->buffer_pos = 0;
 
495
    ctx->parse_data = (flags&PCILIB_EVENT_FLAG_RAW_DATA_ONLY)?0:1;
 
496
    ctx->cur_size = 0;
343
497
 
344
498
    ctx->dim.width = IPECAMERA_WIDTH;
345
 
    ctx->dim.height = IPECAMERA_HEIGHT; //GET_REG(lines_reg, lines);
346
 
 
347
 
    ctx->buffer = malloc(ctx->dim.width * ctx->dim.height * ctx->buffer_size * sizeof(ipecamera_pixel_t));
 
499
    GET_REG(n_lines_reg, ctx->dim.height);
 
500
    
 
501
    raw_size = header_size + ctx->dim.height * line_size + footer_size;
 
502
    padded_blocks = raw_size / IPECAMERA_DMA_PACKET_LENGTH + ((raw_size % IPECAMERA_DMA_PACKET_LENGTH)?1:0);
 
503
    
 
504
    ctx->image_size = ctx->dim.width * ctx->dim.height * sizeof(ipecamera_pixel_t);
 
505
    ctx->raw_size = raw_size;
 
506
    ctx->full_size = padded_blocks * IPECAMERA_DMA_PACKET_LENGTH;
 
507
 
 
508
#ifdef IPECAMERA_BUG_EXTRA_DATA
 
509
    ctx->full_size += 8;
 
510
    padded_blocks ++;
 
511
#endif /* IPECAMERA_BUG_EXTRA_DATA */
 
512
 
 
513
    ctx->padded_size = padded_blocks * IPECAMERA_DMA_PACKET_LENGTH;
 
514
 
 
515
    ctx->buffer = malloc(ctx->padded_size * ctx->buffer_size);
348
516
    if (!ctx->buffer) {
349
517
        err = PCILIB_ERROR_MEMORY;
350
 
        pcilib_error("Unable to allocate ring buffer");
 
518
        pcilib_error("Unable to allocate ring buffer (%lu bytes)", ctx->padded_size * ctx->buffer_size);
 
519
        return err;
351
520
    }
352
521
 
353
522
    ctx->cmask = malloc(ctx->dim.height * ctx->buffer_size * sizeof(ipecamera_change_mask_t));
354
523
    if (!ctx->cmask) {
355
524
        err = PCILIB_ERROR_MEMORY;
356
525
        pcilib_error("Unable to allocate change-mask buffer");
 
526
        return err;
 
527
    }
 
528
 
 
529
    ctx->frame_info = malloc(ctx->buffer_size * sizeof(ipecamera_event_info_t));
 
530
    if (!ctx->frame_info) {
 
531
        err = PCILIB_ERROR_MEMORY;
 
532
        pcilib_error("Unable to allocate frame-info buffer");
 
533
        return err;
357
534
    }
358
535
 
359
536
#ifdef IPECAMERA_DMA_ADDRESS
360
537
    if (!err) {
361
 
        ctx->rdma = pcilib_find_dma_by_addr(ctx->pcilib, PCILIB_DMA_FROM_DEVICE, IPECAMERA_DMA_ADDRESS);
 
538
        ctx->rdma = pcilib_find_dma_by_addr(vctx->pcilib, PCILIB_DMA_FROM_DEVICE, IPECAMERA_DMA_ADDRESS);
362
539
        if (ctx->rdma == PCILIB_DMA_ENGINE_INVALID) {
363
540
            err = PCILIB_ERROR_NOTFOUND;
364
541
            pcilib_error("The C2S channel of IPECamera DMA Engine (%u) is not found", IPECAMERA_DMA_ADDRESS);
365
542
        } else {
366
 
            err = pcilib_start_dma(ctx->pcilib, ctx->rdma, PCILIB_DMA_FLAGS_DEFAULT);
 
543
            err = pcilib_start_dma(vctx->pcilib, ctx->rdma, PCILIB_DMA_FLAGS_DEFAULT);
367
544
            if (err) {
368
545
                ctx->rdma = PCILIB_DMA_ENGINE_INVALID;
369
546
                pcilib_error("Failed to initialize C2S channel of IPECamera DMA Engine (%u)", IPECAMERA_DMA_ADDRESS);
373
550
    
374
551
/*    
375
552
    if (!err) {
376
 
        ctx->wdma = pcilib_find_dma_by_addr(ctx->pcilib, PCILIB_DMA_TO_DEVICE, IPECAMERA_DMA_ADDRESS);
 
553
        ctx->wdma = pcilib_find_dma_by_addr(vctx->pcilib, PCILIB_DMA_TO_DEVICE, IPECAMERA_DMA_ADDRESS);
377
554
        if (ctx->wdma == PCILIB_DMA_ENGINE_INVALID) {
378
555
            err = PCILIB_ERROR_NOTFOUND;
379
556
            pcilib_error("The S2C channel of IPECamera DMA Engine (%u) is not found", IPECAMERA_DMA_ADDRESS);
380
557
        } else {
381
 
            err = pcilib_start_dma(ctx->pcilib, ctx->wdma, PCILIB_DMA_FLAGS_DEFAULT);
 
558
            err = pcilib_start_dma(vctx->pcilib, ctx->wdma, PCILIB_DMA_FLAGS_DEFAULT);
382
559
            if (err) {
383
560
                ctx->wdma = PCILIB_DMA_ENGINE_INVALID;
384
561
                pcilib_error("Failed to initialize S2C channel of IPECamera DMA Engine (%u)", IPECAMERA_DMA_ADDRESS);
386
563
        }
387
564
    }
388
565
*/    
 
566
 
 
567
/*
 
568
    SET_REG(packet_len_reg, IPECAMERA_DMA_PACKET_LENGTH);
 
569
    if (err) return err;
 
570
*/
 
571
 
 
572
        // Clean DMA
 
573
    err = pcilib_skip_dma(vctx->pcilib, ctx->rdma);
 
574
    if (err) {
 
575
        pcilib_error("Can't start grabbing, device continuously writes unexpected data using DMA engine");
 
576
        return err;
 
577
    }
 
578
 
389
579
#endif /* IPECAMERA_DMA_ADDRESS */
390
580
    
391
581
    if (err) {
392
 
        ipecamera_stop(vctx);
 
582
        ipecamera_stop(vctx, PCILIB_EVENT_FLAGS_DEFAULT);
393
583
        return err;
394
584
    }
 
585
 
 
586
    if (vctx->params.autostop.duration) {
 
587
        gettimeofday(&ctx->autostop.timestamp, NULL);
 
588
        ctx->autostop.timestamp.tv_usec += vctx->params.autostop.duration % 1000000;
 
589
        if (ctx->autostop.timestamp.tv_usec > 999999) {
 
590
            ctx->autostop.timestamp.tv_sec += 1 + vctx->params.autostop.duration / 1000000;
 
591
            ctx->autostop.timestamp.tv_usec -= 1000000;
 
592
        } else {
 
593
            ctx->autostop.timestamp.tv_sec += vctx->params.autostop.duration / 1000000;
 
594
        }
 
595
    }
 
596
    
 
597
    if (vctx->params.autostop.max_events) {
 
598
        ctx->autostop.evid = vctx->params.autostop.max_events;
 
599
    }
395
600
    
396
601
    ctx->started = 1;
397
 
    
398
 
    return 0;
 
602
    ctx->run_reader = 1;
 
603
    
 
604
    pthread_attr_init(&attr);
 
605
 
 
606
    if (pthread_attr_setschedpolicy(&attr, SCHED_FIFO)) {
 
607
        pcilib_warning("Can't schedule a real-time thread, you may consider running as root");
 
608
    } else {
 
609
        sched.sched_priority = sched_get_priority_max(SCHED_FIFO) - 1;  // Let 1 priority for something really critcial
 
610
        pthread_attr_setschedparam(&attr, &sched);
 
611
    }
 
612
    
 
613
    if (pthread_create(&ctx->rthread, &attr, &ipecamera_reader_thread, (void*)ctx)) {
 
614
        ctx->started = 0;
 
615
        ipecamera_stop(vctx, PCILIB_EVENT_FLAGS_DEFAULT);
 
616
        err = PCILIB_ERROR_THREAD;
 
617
    }
 
618
    
 
619
    pthread_attr_destroy(&attr);    
 
620
 
 
621
    return err;
399
622
}
400
623
 
401
624
 
402
 
int ipecamera_stop(pcilib_context_t *vctx) {
 
625
int ipecamera_stop(pcilib_context_t *vctx, pcilib_event_flags_t flags) {
 
626
    int err;
 
627
    void *retcode;
403
628
    ipecamera_t *ctx = (ipecamera_t*)vctx;
404
629
 
405
630
    if (!ctx) {
407
632
        return PCILIB_ERROR_NOTINITIALIZED;
408
633
    }
409
634
 
410
 
    ctx->started = 0;   
 
635
    if (ctx->started) {
 
636
        ctx->run_reader = 0;
 
637
        err = pthread_join(ctx->rthread, &retcode);
 
638
        if (err) pcilib_error("Error joining the reader thread");
 
639
    }
411
640
 
412
641
#ifdef IPECAMERA_DMA_ADDRESS
413
642
    if (ctx->wdma != PCILIB_DMA_ENGINE_INVALID) {
414
 
        pcilib_stop_dma(ctx->pcilib, ctx->wdma, PCILIB_DMA_FLAGS_DEFAULT);
 
643
        pcilib_stop_dma(vctx->pcilib, ctx->wdma, PCILIB_DMA_FLAGS_DEFAULT);
415
644
        ctx->wdma = PCILIB_DMA_ENGINE_INVALID;
416
645
    }
417
646
 
418
647
    if (ctx->rdma != PCILIB_DMA_ENGINE_INVALID) {
419
 
        pcilib_stop_dma(ctx->pcilib, ctx->rdma, PCILIB_DMA_FLAGS_DEFAULT);
 
648
        pcilib_stop_dma(vctx->pcilib, ctx->rdma, PCILIB_DMA_FLAGS_DEFAULT);
420
649
        ctx->rdma = PCILIB_DMA_ENGINE_INVALID;
421
650
    }
422
651
#endif /* IPECAMERA_DMA_ADDRESS */
423
652
 
 
653
    if (ctx->frame_info) {
 
654
        free(ctx->frame_info);
 
655
        ctx->frame_info = NULL;
 
656
    }
 
657
 
424
658
    if (ctx->buffer) {
425
659
        free(ctx->buffer);
426
660
        ctx->buffer = NULL;
431
665
        ctx->cmask = NULL;
432
666
    }
433
667
 
 
668
    memset(&ctx->autostop, 0, sizeof(ipecamera_autostop_t));
434
669
 
435
670
    ctx->event_id = 0;
436
671
    ctx->reported_id = 0;
437
 
    ctx->buf_ptr = 0; 
438
 
 
439
 
    return 0;
440
 
}
441
 
 
442
 
 
443
 
static int ipecamera_get_payload(ipecamera_t *ctx, ipecamera_pixel_t *pbuf, ipecamera_change_mask_t *cbuf, int line_req, pcilib_register_value_t size, ipecamera_payload_t *payload, pcilib_register_value_t *advance) {
444
 
    int i, j;
445
 
    int ppw;
446
 
    int err = 0;
447
 
 
448
 
    ipecamera_payload_t info = payload[0];
449
 
    int channel = info&0x0F;            // 4 bits
450
 
    const int line = (info>>4)&0x7FF;   // 11 bits
451
 
                                        // 1 bit is reserved
452
 
    const int bpp = (info>>16)&0x0F;    // 4 bits
453
 
    const int pixels = (info>>20)&0xFF; // 8 bits
454
 
                                        // 2 bits are reserved
455
 
    int header = (info>>30)&0x03;       // 2 bits
456
 
 
457
 
    int bytes;
458
 
    
459
 
    int pix;
460
 
    int pix_offset = 0;
461
 
    
462
 
    const int chan_offset = channel * IPECAMERA_PIXELS_PER_CHANNEL;
463
 
    
464
 
    ipecamera_payload_t data;
465
 
 
466
 
#ifdef IPECAMERA_REORDER_CHANNELS
467
 
    channel = ipecamera_channel_order[channel];
468
 
#endif 
469
 
//    printf("payload, channel: %i, magick: %i, all: %lx\n", channel, header, info);
470
 
 
471
 
    //printf("channel[%x] = %x (line: %i, pixels: %i)\n", info, channel, line_req, pixels);
472
 
    CHECK_FLAG("payload header magick", header == 2, header);
473
 
    CHECK_FLAG("pixel size, only 10 bits are supported", bpp == 10, bpp);
474
 
    CHECK_FLAG("row number, should be %li", line == line_req, line, line_req);
475
 
    CHECK_FLAG("channel, limited by %li output channels", channel < IPECAMERA_MAX_CHANNELS, channel, IPECAMERA_MAX_CHANNELS);
476
 
    CHECK_FLAG("channel, duplicate entry for channel", ((*cbuf)&(1<<channel)) == 0, channel);
477
 
 
478
 
        // Fixing first lines bug
479
 
        // Matthias: Using unlikely() saves 1ms 
480
 
    if ((line < 2)&&(pixels == (IPECAMERA_PIXELS_PER_CHANNEL - 1))) {
481
 
        pix_offset = 1;
482
 
        pbuf[chan_offset] = 0;
483
 
    } else {
484
 
        CHECK_FLAG("number of pixels, %li is expected", pixels == IPECAMERA_PIXELS_PER_CHANNEL, pixels, IPECAMERA_PIXELS_PER_CHANNEL);
485
 
    }
486
 
    
487
 
    bytes = pixels / 3;
488
 
    ppw = pixels - bytes * 3;
489
 
    if (ppw) ++bytes;
490
 
 
491
 
    CHECK_FLAG("payload data bytes, at least %i are expected", bytes < size, size, bytes);
492
 
 
493
 
    if (err) return err;
494
 
 
495
 
    for (i = 1, pix = pix_offset; i < bytes; i++) {
496
 
        data = payload[i];
497
 
        header = (data >> 30) & 0x03;   
498
 
 
499
 
        CHECK_FLAG("payload data magick", header == 3, header);
500
 
        if (err) return err;
501
 
 
502
 
            // DS: Unroll
503
 
        for (j = 0; j < 3; j++, pix++) {
504
 
            pbuf[chan_offset + pix] = (data >> (10 * (2 - j))) & 0x3FF;
505
 
        }
506
 
    }
507
 
 
508
 
    data = payload[bytes];
509
 
    header = (data >> 30) & 0x03;
510
 
 
511
 
    CHECK_FLAG("payload data magick", header == 3, header);
512
 
    CHECK_FLAG("payload footer magick", (data&0x3FF) == 0x55, (data&0x3FF));
513
 
    if (err) return err;
514
 
 
515
 
    ppw = pixels%3;
516
 
    assert(ppw < 3);
517
 
 
518
 
    for (j = 0; j < ppw; j++, pix++) {
519
 
//      pbuf[channel*IPECAMERA_PIXELS_PER_CHANNEL + pix] = (data >> (10 * (ppw - j - 1))) & 0x3FF;
520
 
        pbuf[chan_offset + pix] = (data >> (10 * (ppw - j))) & 0x3FF;
521
 
    }    
522
 
 
523
 
    *cbuf |= (1 << channel);
524
 
    *advance = bytes + 1;
525
 
 
526
 
    return 0;
527
 
}
528
 
 
529
 
static int ipecamera_parse_image(ipecamera_t *ctx, ipecamera_pixel_t *pbuf, ipecamera_change_mask_t *cbuf, int first_line, int n_lines, pcilib_register_value_t size, ipecamera_payload_t *linebuf) {
530
 
    int err = 0;
531
 
    pcilib_t *pcilib = ctx->pcilib;
532
 
 
533
 
    int line = first_line;
534
 
    pcilib_register_value_t pos, advance;
535
 
 
536
 
    if (size < 16) {
537
 
        pcilib_error("The payload is tool small, we should have at least 8 header dwords and 8 footer.");
538
 
        return PCILIB_ERROR_INVALID_DATA;
539
 
    }
540
 
    
541
 
    CHECK_VALUE(linebuf[0], 0x51111111);
542
 
    CHECK_VALUE(linebuf[1], 0x52222222);
543
 
    CHECK_VALUE(linebuf[2], 0x53333333);
544
 
    CHECK_VALUE(linebuf[3], 0x54444444);
545
 
    CHECK_VALUE(linebuf[4], 0x55555555);
546
 
    CHECK_VALUE(linebuf[5], 0x56666666);
547
 
    CHECK_VALUE(linebuf[6], 0x57777777);
548
 
    CHECK_VALUE(linebuf[7], 0x58888888);
549
 
    if (err) return err;
550
 
 
551
 
    pos = 8;
552
 
    size -= 16;
553
 
 
554
 
    while (size > 0) {
555
 
        err = ipecamera_get_payload(ctx, pbuf + line * ctx->dim.width, cbuf + line, line - first_line, size, linebuf + pos, &advance);
556
 
        if (err) return err;
557
 
            
558
 
        pos += advance;
559
 
        size -= advance;
560
 
        
561
 
        if (cbuf[line] == ((1<<IPECAMERA_MAX_CHANNELS)-1)) ++line;
562
 
    }
563
 
 
564
 
    CHECK_FLAG("lines read, we expect to read exactly %li lines", line == (first_line + n_lines), line - first_line, n_lines);
565
 
 
566
 
    CHECK_VALUE(linebuf[pos  ], 0x0AAAAAAA);
567
 
    CHECK_VALUE(linebuf[pos+1], 0x0BBBBBBB);
568
 
    CHECK_VALUE(linebuf[pos+2], 0x0CCCCCCC);
569
 
    CHECK_VALUE(linebuf[pos+3], 0x0DDDDDDD);
570
 
    CHECK_VALUE(linebuf[pos+4], 0x0EEEEEEE);
571
 
    CHECK_VALUE(linebuf[pos+5], 0x0FFFFFFF);
572
 
    CHECK_VALUE(linebuf[pos+6], 0x00000000);
573
 
    CHECK_VALUE(linebuf[pos+7], 0x01111111);
574
 
 
575
 
    return err;
576
 
}
577
 
 
578
 
static int ipecamera_get_image(ipecamera_t *ctx) {
579
 
    int err;
580
 
    int i;
581
 
    int buf_ptr;
582
 
    size_t bytes_read;
583
 
    pcilib_t *pcilib = ctx->pcilib;
584
 
 
585
 
    int num_lines;
586
 
    const int max_lines = IPECAMERA_MAX_LINES;
587
 
    const size_t line_size = (IPECAMERA_MAX_CHANNELS * (2 + IPECAMERA_PIXELS_PER_CHANNEL / 3));
588
 
    const size_t hf_size = 16;
589
 
    const size_t max_size = hf_size + max_lines * line_size;
590
 
    const size_t dma_packet_len = IPECAMERA_DMA_PACKET_LENGTH / sizeof(ipecamera_payload_t);
591
 
    size_t max_packet_size;
592
 
 
593
 
    pcilib_register_value_t ptr, size, pos, advance, value;
594
 
 
595
 
    ipecamera_payload_t *linebuf;
596
 
    
597
 
    if (max_size%dma_packet_len) max_packet_size = max_size + dma_packet_len - (max_size%dma_packet_len);
598
 
    else max_packet_size = max_size;
599
 
 
600
 
    max_packet_size += 4096;    // Some extra data?
601
 
    
602
 
    
603
 
    linebuf = (ipecamera_payload_t*)malloc(max_packet_size * sizeof(ipecamera_payload_t));
604
 
    if (!linebuf) return PCILIB_ERROR_MEMORY;
605
 
 
606
 
        // DS: test
607
 
    err = pcilib_skip_dma(ctx->pcilib, ctx->rdma);
608
 
    if (err) {
609
 
        pcilib_error("Can't start benchmark, devices continuously writes unexpected data using DMA engine");
610
 
        return err;
611
 
    }
612
 
 
613
 
 
614
 
#ifdef IPECAMERA_WRITE_RAW
615
 
    FILE *f = fopen("raw/image.raw", "w");
616
 
    if (f) fclose(f);
617
 
#endif
618
 
 
619
 
    //atomic    
620
 
    buf_ptr = ctx->buf_ptr;
621
 
    if (ctx->buf_ptr++ == ctx->buffer_size) ctx->buf_ptr = 0;
622
 
    if (ctx->event_id++ == 0) ctx->event_id = 1;
623
 
 
624
 
    //const size_t image_size = ctx->dim.width * ctx->dim.height;
625
 
    //memset(ctx->buffer + buf_ptr * image_size, 0, image_size * sizeof(ipecamera_pixel_t));
626
 
    memset(ctx->cmask + buf_ptr * ctx->dim.height, 0, ctx->dim.height * sizeof(ipecamera_change_mask_t));
627
 
 
628
 
 
629
 
    for (i = 0; i < ctx->dim.height; i += max_lines) {
630
 
        num_lines = ctx->dim.height - i;
631
 
        if (num_lines > max_lines)  num_lines = max_lines;
632
 
    
633
 
        SET_REG(n_lines_reg, num_lines);
634
 
        SET_REG(line_reg, i);
635
 
 
636
 
        SET_REG(control_reg, IPECAMERA_FRAME_REQUEST);
637
 
        usleep(IPECAMERA_WAIT_FRAME_RCVD_TIME);
638
 
        CHECK_REG(status_reg, IPECAMERA_EXPECTED_STATUS);
639
 
        SET_REG(control_reg, IPECAMERA_IDLE);
640
 
 
641
 
#ifndef IPECAMERA_DMA_ADDRESS   
642
 
        GET_REG(start_reg, ptr);
643
 
        GET_REG(end_reg, size);
644
 
 
645
 
        size -= ptr;
646
 
        size *= 2;
647
 
        
648
 
        CHECK_FLAG("data size", (size > 0)&&(size <= max_size), size);
649
 
#endif /* IPECAMERA_DMA_ADDRESS */
650
 
 
651
 
        
652
 
        if (err) break;
653
 
        
654
 
        SET_REG(control_reg, IPECAMERA_READOUT);
655
 
            // sync between End Of Readout and next Frame Req
656
 
        usleep(IPECAMERA_NEXT_FRAME_DELAY);  
657
 
 
658
 
//      usleep(1000000);
659
 
        
660
 
//      pcilib_start_dma(ctx->pcilib, ctx->rdma, PCILIB_DMA_FLAG_PERSISTENT);
661
 
//      pcilib_stop_dma(ctx->pcilib, ctx->rdma, PCILIB_DMA_FLAGS_DEFAULT);
662
 
//      pcilib_start_dma(ctx->pcilib, ctx->rdma, PCILIB_DMA_FLAGS_DEFAULT);
663
 
 
664
 
        
665
 
#ifdef IPECAMERA_DMA_ADDRESS
666
 
        size = 0;
667
 
        do {
668
 
            err = pcilib_read_dma(ctx->pcilib, ctx->rdma, 0, max_packet_size * sizeof(ipecamera_payload_t) - size, ((uint8_t*)linebuf) + size, &bytes_read);
669
 
            size += bytes_read;
670
 
//          printf("%lu %lu\n", bytes_read, size);
671
 
        } while ((err == 0)&&(size < max_packet_size * sizeof(ipecamera_payload_t)));
672
 
 
673
 
 
674
 
#ifdef DEBUG_HARDWARE
675
 
        uint32_t regval;
676
 
        printf("===========Lines: %i - %i =========================\n", i, i + num_lines - 1);
677
 
        err = pcilib_read_register(ctx->pcilib, NULL, "status", &regval);
678
 
        printf("Status1: %i 0x%lx\n", err, regval);
679
 
        err = pcilib_read_register(ctx->pcilib, NULL, "start_address", &regval);
680
 
        printf("Start address: %i 0x%lx\n", err,  regval);
681
 
        err = pcilib_read_register(ctx->pcilib, NULL, "end_address", &regval);
682
 
        printf("End address: %i 0x%lx\n", err,  regval);
683
 
        err = pcilib_read_register(ctx->pcilib, NULL, "last_write_address", &regval);
684
 
        printf("Status2: %i 0x%lx\n", err,  regval);
685
 
        err = pcilib_read_register(ctx->pcilib, NULL, "last_write_value", &regval);
686
 
        printf("Status3: %i 0x%lx\n", err,  regval);
687
 
        err = pcilib_read_register(ctx->pcilib, NULL, "reg9160", &regval);
688
 
        printf("Add_rd_ddr: %i 0x%lx\n", err, regval);
689
 
#endif /* DEBUG_HARDWARE */
690
 
 
691
 
        if (err) {
692
 
            if (err == PCILIB_ERROR_TIMEOUT) {
693
 
                if (size > 0) err = 0;
694
 
                else {
695
 
#ifdef IPECAMERA_DEBUG
696
 
                    pcilib_warning("There is no data received from IPE Camera for lines: %i to %i", i, i + num_lines - 1);
697
 
                    err = 0;
698
 
                    SET_REG(control_reg, IPECAMERA_IDLE);
699
 
                    continue;
700
 
#else /* IPECAMERA_DEBUG */
701
 
                    pcilib_error("There is no data received from IPE Camera");
702
 
                    return err;
703
 
#endif /* IPECAMERA_DEBUG */
704
 
                }
705
 
            } else pcilib_error("DMA read from IPE Camera have failed");
706
 
        } else if (!size) {
707
 
#ifdef IPECAMERA_DEBUG
708
 
                pcilib_warning("There is no data received from IPE Camera for lines: %i to %i", i, i + num_lines - 1);
709
 
                SET_REG(control_reg, IPECAMERA_IDLE);
710
 
                continue;
711
 
#else /* IPECAMERA_DEBUG */
712
 
                pcilib_warning("There is no data received from IPE Camera for lines: %i to %i", i, i + num_lines - 1);
713
 
                return err;
714
 
#endif /* IPECAMERA_DEBUG */
715
 
        }
716
 
 
717
 
        pcilib_warning("Reading lines %i to %i: got %i bytes from DMA", i, i + num_lines - 1, size);  
718
 
#else /* IPECAMERA_DMA_ADDRESS */
719
 
        pcilib_warning("Reading lines %i to %i: %i %i", i, i + num_lines - 1, ptr, size);  
720
 
        pcilib_datacpy(linebuf, ctx->data + ptr, sizeof(ipecamera_payload_t), size, pcilib_model[PCILIB_MODEL_IPECAMERA].endianess);
721
 
#endif /* IPECAMERA_DMA_ADDRESS */
722
 
 
723
 
        SET_REG(control_reg, IPECAMERA_IDLE);
724
 
//      usleep(IPECAMERA_SLEEP_TIME);
725
 
        CHECK_REG(status_reg, IPECAMERA_EXPECTED_STATUS);
726
 
 
727
 
        if (err) break;
728
 
 
729
 
#ifdef IPECAMERA_WRITE_RAW
730
 
        char fname[256];
731
 
        sprintf(fname, "raw/line%04i", i);
732
 
        FILE *f = fopen(fname, "w");
733
 
        if (f) {
734
 
#ifdef IPECAMERA_DMA_ADDRESS
735
 
            (void)fwrite(linebuf, sizeof(ipecamera_payload_t), size / sizeof(ipecamera_payload_t), f);
736
 
#else /* IPECAMERA_DMA_ADDRESS */
737
 
            (void)fwrite(linebuf, sizeof(ipecamera_payload_t), size, f);
738
 
#endif /* IPECAMERA_DMA_ADDRESS */
739
 
            fclose(f);
740
 
        }
741
 
#endif
742
 
 
743
 
#ifdef IPECAMERA_DMA_ADDRESS
744
 
        if (size < (hf_size + max_lines * line_size) * sizeof(ipecamera_payload_t)) {
745
 
            pcilib_error("We are expecting at least %zu bytes, but only %lu are read", (hf_size + num_lines * line_size)*sizeof(ipecamera_payload_t), size);
746
 
            err = PCILIB_ERROR_INVALID_DATA;
747
 
        }
748
 
 
749
 
        bytes_read = size;
750
 
        size = hf_size + max_lines * line_size;
751
 
#endif /* IPECAMERA_DMA_ADDRESS */
752
 
 
753
 
 
754
 
        err = ipecamera_parse_image(ctx, ctx->buffer + buf_ptr * ctx->dim.width * ctx->dim.height,  ctx->cmask + buf_ptr * ctx->dim.height, i, num_lines, size, linebuf);
755
 
        if (err) break;
756
 
        
757
 
#ifdef IPECAMERA_WRITE_RAW
758
 
        f = fopen("raw/image.raw", "a+");
759
 
        if (f) {
760
 
            fwrite(ctx->buffer + buf_ptr * ctx->dim.width * ctx->dim.height + i * ctx->dim.width, sizeof(ipecamera_pixel_t), num_lines * ctx->dim.width, f);
761
 
            fclose(f);
762
 
        }
763
 
#endif
764
 
    }
765
 
 
766
 
    free(linebuf);
767
 
 
768
 
    return err;
 
672
    ctx->buffer_pos = 0; 
 
673
    ctx->started = 0;
 
674
 
 
675
    return 0;
769
676
}
770
677
 
771
678
 
772
679
int ipecamera_trigger(pcilib_context_t *vctx, pcilib_event_t event, size_t trigger_size, void *trigger_data) {
773
 
    int err;
774
 
    pcilib_t *pcilib;
 
680
    int err = 0;
 
681
    pcilib_register_value_t value;
 
682
 
775
683
    ipecamera_t *ctx = (ipecamera_t*)vctx;
 
684
    pcilib_t *pcilib = vctx->pcilib;
776
685
 
777
686
    if (!ctx) {
778
687
        pcilib_error("IPECamera imaging is not initialized");
780
689
    }
781
690
 
782
691
    if (!ctx->started) {
783
 
        pcilib_error("Can't trigger while not grabbing is not started");
 
692
        pcilib_error("Can't trigger while grabbing is not started");
784
693
        return PCILIB_ERROR_INVALID_REQUEST;
785
694
    }
786
 
    
 
695
 
 
696
    SET_REG(control_reg, IPECAMERA_FRAME_REQUEST|IPECAMERA_READOUT_FLAG);
 
697
    usleep(IPECAMERA_WAIT_FRAME_RCVD_TIME);
 
698
    CHECK_REG(status_reg, IPECAMERA_EXPECTED_STATUS);
 
699
    SET_REG(control_reg, IPECAMERA_IDLE|IPECAMERA_READOUT_FLAG);
 
700
 
 
701
 
 
702
//    SET_REG(control_reg, IPECAMERA_READOUT);
 
703
    usleep(IPECAMERA_NEXT_FRAME_DELAY);  // minimum delay between End Of Readout and next Frame Req
 
704
 
 
705
        // DS: check for overflow    
 
706
/*
 
707
 
787
708
    err = ipecamera_get_image(ctx);
788
709
    if (!err) {
789
710
        if (ctx->cb) {
793
714
    }
794
715
 
795
716
    return err;
796
 
}
797
 
 
798
 
static int ipecamera_resolve_event_id(ipecamera_t *ctx, pcilib_event_id_t evid) {
799
 
    int buf_ptr, diff;
800
 
    
801
 
    if ((!evid)||(evid > ctx->event_id)) return -1;
802
 
    
803
 
    diff = ctx->event_id - evid;
804
 
    buf_ptr = ctx->buf_ptr - diff - 1;
805
 
    if (buf_ptr < 0) {
806
 
        buf_ptr += ctx->buffer_size;
807
 
        if (buf_ptr < 0) return -1;
808
 
    }
809
 
    
810
 
    return buf_ptr;
811
 
}
812
 
 
813
 
pcilib_event_id_t ipecamera_next_event(pcilib_context_t *vctx, pcilib_event_t event_mask, pcilib_timeout_t timeout) {
814
 
    int buf_ptr;
 
717
*/
 
718
}
 
719
 
 
720
int ipecamera_stream(pcilib_context_t *vctx, pcilib_event_callback_t callback, void *user) {
 
721
    int err = 0;
 
722
    int do_stop = 0;
815
723
    pcilib_event_id_t reported;
816
724
    ipecamera_t *ctx = (ipecamera_t*)vctx;
817
725
 
818
 
    if (!ctx) {
819
 
        pcilib_error("IPECamera imaging is not initialized");
820
 
        return PCILIB_EVENT_ID_INVALID;
821
 
    }
822
 
 
823
 
    if (!ctx->started) {
824
 
        pcilib_error("IPECamera is not in grabbing state");
825
 
        return PCILIB_EVENT_ID_INVALID;
826
 
    }
827
 
 
828
 
    if ((!ctx->event_id)||(ctx->reported_id == ctx->event_id)) {
 
726
    size_t events = 0;
 
727
 
 
728
    struct timeval stream_stop;
 
729
 
 
730
    if (!ctx) {
 
731
        pcilib_error("IPECamera imaging is not initialized");
 
732
        return PCILIB_ERROR_NOTINITIALIZED;
 
733
    }
 
734
 
 
735
    ctx->streaming = 1;
 
736
    ctx->run_streamer = 1;
 
737
 
 
738
    if (!ctx->started) {
 
739
        err = ipecamera_start(vctx, PCILIB_EVENTS_ALL, PCILIB_EVENT_FLAGS_DEFAULT);
 
740
        if (err) {
 
741
            ctx->streaming = 0;
 
742
            pcilib_error("IPECamera is not in grabbing state");
 
743
            return PCILIB_ERROR_INVALID_STATE;
 
744
        }
 
745
        
 
746
        do_stop = 1;
 
747
    }
 
748
    
 
749
        // This loop iterates while the generation
 
750
    while ((ctx->run_streamer)||(ctx->reported_id != ctx->event_id)) {
 
751
        while (ctx->reported_id != ctx->event_id) {
 
752
            if ((ctx->event_id - ctx->reported_id) > (ctx->buffer_size - IPECAMERA_RESERVE_BUFFERS)) ctx->reported_id = ctx->event_id - (ctx->buffer_size - 1) - IPECAMERA_RESERVE_BUFFERS;
 
753
            else ++ctx->reported_id;
 
754
 
 
755
            callback(ctx->reported_id, (pcilib_event_info_t*)(ctx->frame_info + (ctx->reported_id%ctx->buffer_size)), user);
 
756
        }
 
757
        usleep(IPECAMERA_NOFRAME_SLEEP);
 
758
    }
 
759
 
 
760
    ctx->streaming = 0;
 
761
 
 
762
    if (do_stop) {
 
763
        ipecamera_stop(vctx, PCILIB_EVENT_FLAGS_DEFAULT);
 
764
    }
 
765
    
 
766
    
 
767
    
 
768
    return err;
 
769
}
 
770
 
 
771
 
 
772
int ipecamera_next_event(pcilib_context_t *vctx, pcilib_event_t event_mask, pcilib_timeout_t timeout, pcilib_event_id_t *evid, pcilib_event_info_t **info) {
 
773
    struct timeval tv;
 
774
    ipecamera_t *ctx = (ipecamera_t*)vctx;
 
775
 
 
776
    if (!ctx) {
 
777
        pcilib_error("IPECamera imaging is not initialized");
 
778
        return PCILIB_ERROR_NOTINITIALIZED;
 
779
    }
 
780
 
 
781
    if (!ctx->started) {
 
782
        pcilib_error("IPECamera is not in grabbing mode");
 
783
        return PCILIB_ERROR_INVALID_REQUEST;
 
784
    }
 
785
 
 
786
    if (ctx->reported_id == ctx->event_id) {
829
787
        if (timeout) {
830
 
            // We should wait here for the specified timeout
 
788
            calc_deadline(&tv, timeout);
 
789
            
 
790
            while ((calc_time_to_deadline(&tv) > 0)&&(ctx->reported_id == ctx->event_id))
 
791
                usleep(IPECAMERA_NOFRAME_SLEEP);
831
792
        }
832
 
        return PCILIB_EVENT_ID_INVALID;
833
 
    }
834
 
 
835
 
        // We had an overflow in event counting
836
 
    if (ctx->reported_id > ctx->event_id) {
837
 
        do {
838
 
            if (++ctx->reported_id == 0) ctx->reported_id = 1;
839
 
        } while (ipecamera_resolve_event_id(ctx, ctx->reported_id) < 0);
840
 
    } else {
841
 
        if ((ctx->event_id - ctx->reported_id) > ctx->buffer_size) ctx->reported_id = ctx->event_id - (ctx->buffer_size - 1);
842
 
        else ++ctx->reported_id;
843
 
    }
844
 
    
 
793
        
 
794
        if (ctx->reported_id == ctx->event_id) return PCILIB_ERROR_TIMEOUT;
 
795
    }
 
796
 
 
797
    if ((ctx->event_id - ctx->reported_id) > (ctx->buffer_size - IPECAMERA_RESERVE_BUFFERS)) ctx->reported_id = ctx->event_id - (ctx->buffer_size - 1) - IPECAMERA_RESERVE_BUFFERS;
 
798
    else ++ctx->reported_id;
 
799
 
845
800
    return ctx->reported_id;
846
801
}
847
802
 
848
 
void* ipecamera_get(pcilib_context_t *vctx, pcilib_event_id_t event_id, pcilib_event_data_type_t data_type, size_t arg_size, void *arg, size_t *size) {
 
803
 
 
804
void* ipecamera_get(pcilib_context_t *vctx, pcilib_event_id_t event_id, pcilib_event_data_type_t data_type, size_t arg_size, void *arg, size_t *size, void *data) {
849
805
    int buf_ptr;
850
806
    ipecamera_t *ctx = (ipecamera_t*)vctx;
851
807
 
856
812
    
857
813
 
858
814
    buf_ptr = ipecamera_resolve_event_id(ctx, event_id);
859
 
 
860
 
    //printf("%i %i %i\n", ctx->event_id, event_id, buf_ptr);
861
 
 
862
815
    if (buf_ptr < 0) return NULL;
863
816
    
864
817
    switch ((ipecamera_data_type_t)data_type) {
886
839
 
887
840
 
888
841
 
889
 
int ipecamera_return(pcilib_context_t *vctx, pcilib_event_id_t event_id) {
 
842
int ipecamera_return(pcilib_context_t *vctx, pcilib_event_id_t event_id, void *data) {
890
843
    ipecamera_t *ctx = (ipecamera_t*)vctx;
891
844
 
892
845
    if (!ctx) {