/alps/ipecamera

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

« back to all changes in this revision

Viewing changes to base.c

  • Committer: Suren A. Chilingaryan
  • Date: 2015-08-06 01:08:42 UTC
  • Revision ID: csa@suren.me-20150806010842-pdy8up1ro75gcd1a
Use new locking subsystem to ensure integrity

Show diffs side-by-side

added added

removed removed

Lines of Context:
75
75
        err = PCILIB_ERROR_INVALID_DATA; \
76
76
    }
77
77
 
 
78
#define LOCK(lock_name) \
 
79
    err = pcilib_try_lock(ctx->lock_name##_lock); \
 
80
    if (err) { \
 
81
        pcilib_error("IPECamera is busy"); \
 
82
        return PCILIB_ERROR_BUSY; \
 
83
    } \
 
84
    ctx->lock_name##_locked = 1;
 
85
 
 
86
#define UNLOCK(lock_name) \
 
87
    if (ctx->lock_name##_locked) { \
 
88
        pcilib_unlock(ctx->lock_name##_lock); \
 
89
        ctx->lock_name##_locked = 0; \
 
90
    }
78
91
 
79
92
pcilib_context_t *ipecamera_init(pcilib_t *pcilib) {
80
93
    int err = 0; 
88
101
        
89
102
        memset(ctx, 0, sizeof(ipecamera_t));
90
103
 
 
104
        ctx->run_lock = pcilib_get_lock(pcilib, PCILIB_LOCK_FLAGS_DEFAULT, "ipecamera");
 
105
        ctx->stream_lock = pcilib_get_lock(pcilib, PCILIB_LOCK_FLAGS_DEFAULT, "ipecamera/stream");
 
106
        ctx->trigger_lock = pcilib_get_lock(pcilib, PCILIB_LOCK_FLAGS_DEFAULT, "ipecamera/trigger");
 
107
 
 
108
        if (!ctx->run_lock||!ctx->stream_lock||!ctx->trigger_lock) {
 
109
            free(ctx);
 
110
            pcilib_error("Failed to initialize locks to protect ipecamera operation");
 
111
            return NULL;
 
112
        }
 
113
 
91
114
        ctx->buffer_size = IPECAMERA_DEFAULT_BUFFER_SIZE;
92
115
 
93
116
        ctx->dim.bpp = sizeof(ipecamera_pixel_t) * 8;
152
175
    if (vctx) {
153
176
        ipecamera_t *ctx = (ipecamera_t*)vctx;
154
177
        ipecamera_stop(vctx, PCILIB_EVENT_FLAGS_DEFAULT);
 
178
 
 
179
        if (ctx->trigger_lock)
 
180
            pcilib_return_lock(vctx->pcilib, PCILIB_LOCK_FLAGS_DEFAULT, ctx->trigger_lock);
 
181
 
 
182
        if (ctx->stream_lock)
 
183
            pcilib_return_lock(vctx->pcilib, PCILIB_LOCK_FLAGS_DEFAULT, ctx->stream_lock);
 
184
        
 
185
        if (ctx->run_lock)
 
186
            pcilib_return_lock(vctx->pcilib, PCILIB_LOCK_FLAGS_DEFAULT, ctx->run_lock);
 
187
 
155
188
        free(ctx);
156
189
    }
157
190
}
210
243
    control = ctx->control_reg;
211
244
    status = ctx->status_reg;
212
245
 
213
 
        // Set Reset bit to CMOSIS
214
 
    err = pcilib_write_register_by_id(pcilib, control, 0x1e4);
215
 
    if (err) {
216
 
        pcilib_error("Error setting FPGA reset bit");
217
 
        return err;
218
 
    }
219
 
    usleep(IPECAMERA_CMOSIS_RESET_DELAY);
 
246
    LOCK(run);
 
247
 
 
248
    ipecamera_debug(API, "ipecamera: starting");
 
249
 
 
250
    if (ctx->firmware == IPECAMERA_FIRMWARE_UFO5) {
 
251
            // Set Reset bit to CMOSIS
 
252
        err = pcilib_write_register_by_id(pcilib, control, 0x1e4);
 
253
        if (err) {
 
254
            UNLOCK(run);
 
255
            pcilib_error("Error setting FPGA reset bit");
 
256
            return err;
 
257
        }
 
258
        usleep(IPECAMERA_CMOSIS_RESET_DELAY);
220
259
 
221
260
        // Remove Reset bit to CMOSIS
222
 
    err = pcilib_write_register_by_id(pcilib, control, 0x1e1);
223
 
    if (err) {
224
 
        pcilib_error("Error reseting FPGA reset bit");
225
 
        return err;
226
 
    }
227
 
    usleep(IPECAMERA_CMOSIS_REGISTER_DELAY);
 
261
        err = pcilib_write_register_by_id(pcilib, control, 0x1e1);
 
262
        if (err) {
 
263
            UNLOCK(run);
 
264
            pcilib_error("Error reseting FPGA reset bit");
 
265
            return err;
 
266
        }
 
267
        usleep(IPECAMERA_CMOSIS_REGISTER_DELAY);
228
268
 
229
269
        // Special settings for CMOSIS v.2
230
 
    value = 01; err = pcilib_write_register_space(pcilib, "cmosis", 115, 1, &value);
231
 
    if (err) {
232
 
        pcilib_error("Error setting CMOSIS configuration");
233
 
        return err;
234
 
    }
235
 
    usleep(IPECAMERA_CMOSIS_REGISTER_DELAY);
 
270
        value = 01; err = pcilib_write_register_space(pcilib, "cmosis", 115, 1, &value);
 
271
        if (err) {
 
272
            UNLOCK(run);
 
273
            pcilib_error("Error setting CMOSIS configuration");
 
274
            return err;
 
275
        }
 
276
        usleep(IPECAMERA_CMOSIS_REGISTER_DELAY);
236
277
 
237
 
    value = 07; err = pcilib_write_register_space(pcilib, "cmosis", 82, 1, &value);
238
 
    if (err) {
239
 
        pcilib_error("Error setting CMOSIS configuration");
240
 
        return err;
 
278
        value = 07; err = pcilib_write_register_space(pcilib, "cmosis", 82, 1, &value);
 
279
        if (err) {
 
280
            UNLOCK(run);
 
281
            pcilib_error("Error setting CMOSIS configuration");
 
282
            return err;
 
283
        }
 
284
        usleep(IPECAMERA_CMOSIS_REGISTER_DELAY);
 
285
        pcilib_warning("Reset procedure is not complete");
 
286
    } else {
 
287
        pcilib_warning("Reset procedure is not implemented");
241
288
    }
242
 
    usleep(IPECAMERA_CMOSIS_REGISTER_DELAY);
243
289
 
244
290
        // Set default parameters
245
291
    err = pcilib_write_register_by_id(pcilib, control, IPECAMERA_IDLE);
246
292
    if (err) {
 
293
        UNLOCK(run);
247
294
        pcilib_error("Error bringing FPGA in default mode");
248
295
        return err;
249
296
    }
255
302
    if (err) {
256
303
        err = pcilib_read_register_by_id(pcilib, status, &value);
257
304
 
 
305
        UNLOCK(run);
258
306
        if (err) pcilib_error("Error reading status register");
259
307
        else pcilib_error("Camera returns unexpected status (status: %lx)", value);
260
308
 
261
309
        return PCILIB_ERROR_VERIFY;
262
310
    }
263
311
 
264
 
    return pcilib_skip_dma(vctx->pcilib, ctx->rdma);
 
312
    err = pcilib_skip_dma(vctx->pcilib, ctx->rdma);
 
313
    UNLOCK(run);
 
314
 
 
315
    ipecamera_debug(API, "ipecamera: reset done");
 
316
    return err;
265
317
}
266
318
 
267
319
 
288
340
        return PCILIB_ERROR_INVALID_REQUEST;
289
341
    }
290
342
 
 
343
    LOCK(run);
 
344
 
291
345
    ipecamera_debug(API, "ipecamera: starting");
292
346
 
293
347
    ctx->event_id = 0;
308
362
        ctx->cmosis_outputs = CMOSIS20_MAX_CHANNELS;
309
363
        break;
310
364
     default:
 
365
        UNLOCK(run);
311
366
        pcilib_error("Can't start undefined version (%lu) of IPECamera", ctx->firmware);
312
367
        return PCILIB_ERROR_INVALID_REQUEST;
313
368
    }
322
377
            ctx->cmosis_outputs = 4;
323
378
            break;
324
379
         default:
 
380
            UNLOCK(run);
325
381
            pcilib_error("IPECamera reporting invalid output_mode 0x%lx", value);
326
382
            return PCILIB_ERROR_INVALID_STATE;
327
383
        }
604
660
    ctx->started = 0;
605
661
 
606
662
    ipecamera_debug(API, "ipecamera: stopped");
607
 
    
 
663
    UNLOCK(run);
 
664
 
608
665
    return 0;
609
666
}
610
667
 
623
680
        return PCILIB_ERROR_NOTINITIALIZED;
624
681
    }
625
682
 
 
683
    ipecamera_debug(API, "ipecamera: trigger");
 
684
    LOCK(trigger);
 
685
 
626
686
    pcilib_sleep_until_deadline(&ctx->next_trigger);
627
687
/*
628
688
    GET_REG(num_frames_reg, value);
645
705
                GET_REG(status2_reg, value);
646
706
            } while ((value&0x40000000)&&(pcilib_calc_time_to_deadline(&deadline) > 0));
647
707
        }
648
 
        if (value&0x40000000)
 
708
        if (value&0x40000000) {
649
709
#endif /* IPECAMERA_TRIGGER_WAIT_IDLE */
 
710
            UNLOCK(trigger);
650
711
            return PCILIB_ERROR_BUSY;
 
712
#ifdef IPECAMERA_TRIGGER_TIMEOUT
 
713
        }
 
714
#endif /* IPECAMERA_TRIGGER_WAIT_IDLE */
651
715
    }
652
716
 
653
717
    GET_REG(control_reg, value);
657
721
 
658
722
        // DS: We need to compute it differently, on top of that add exposure time and the time FPGA takes to read frame from CMOSIS
659
723
    pcilib_calc_deadline(&ctx->next_trigger, IPECAMERA_NEXT_FRAME_DELAY);
 
724
    
 
725
    UNLOCK(trigger);
660
726
 
661
727
    return 0;
662
728
}