00001
00002
00307 #include "edtinc.h"
00308
00309 #include <math.h>
00310
00311 #include <assert.h>
00312
00313 #include "libedt_timing.h"
00314
00315 #ifdef _NT_
00316 #define strncasecmp strnicmp
00317 #endif
00318
00319
00320 #define PDVWARN PDVLIB_MSG_WARNING
00321 #define PDVFATAL PDVLIB_MSG_FATAL
00322 #define DBG1 PDVLIB_MSG_INFO_1
00323 #define DBG2 PDVLIB_MSG_INFO_2
00324
00325 int Pdv_debug = 0;
00326 int Smd_type = NOT_SET;
00327 int Smd_rate = NOT_SET;
00328
00329
00330
00331
00332
00333
00334 #define PDV_DEPENDENT(pdv_p) ((pdv_p)->dd_p)
00335
00336 int check_register_wrap(EdtDev * edt_p);
00337 static void debug_print_serial_command(char *cmd);
00338 static void send_serial_binary_cmd(PdvDev * pdv_p, char *hexstr, int value);
00339 static void pdv_trigger_specinst(PdvDev * pdv_p);
00340 static void pdv_posttrigger_specinst(PdvDev * pdv_p);
00341 static int pdv_specinst_setparam(PdvDev * pdv_p, char cmd, u_long offset, u_long value);
00342
00346 static int pdv_set_exposure_specinst(PdvDev * pdv_p, int value);
00347 static int pdv_set_gain_specinst(PdvDev * pdv_p, int value);
00348 static int pdv_set_exposure_adimec(PdvDev * pdv_p, int value);
00349 static int pdv_set_exposure_su320(PdvDev * pdv_p, int value);
00350 static int pdv_set_gain_adimec(PdvDev * pdv_p, int value);
00351 static int pdv_set_blacklevel_adimec(PdvDev * pdv_p, int value);
00352 static int pdv_set_exposure_smd(PdvDev * pdv_p, int value);
00353 static int pdv_set_exposure_timc1001pf(PdvDev * pdv_p, int value);
00354 static int pdv_set_exposure_ptm6710_1020(PdvDev * pdv_p, int value);
00355 static int pdv_set_gain_ptm6710_1020(PdvDev * pdv_p, int value);
00356 static int pdv_set_binning_generic(PdvDev * pdv_p, int value);
00357 static int pdv_set_gain_smd(PdvDev * pdv_p, int value);
00358 static int pdv_set_blacklevel_smd(PdvDev * pdv_p, int value);
00359 static int pdv_set_gain_hc8484(PdvDev * pdv_p, int value);
00360 static int pdv_set_exposure_toshiba(PdvDev * pdv_p, int value);
00361 static int pdv_set_gain_toshiba(PdvDev * pdv_p, int value);
00362 static int pdv_set_exposure_cohu(PdvDev * pdv_p, int value);
00363 static int pdv_set_gain_cohu(PdvDev * pdv_p, int value);
00364 static int pdv_set_blacklevel_cohu(PdvDev * pdv_p, int value);
00365 static int pdv_total_block_size(PdvDev *pdv_p, int numbufs);
00366 static void pdv_allocate_output_buffers(PdvDev *pdv_p);
00367 static void pdv_free_output_buffers(PdvDev *pdv_p);
00368 static int pdv_multibuf_block(PdvDev *pdv_p, int numbufs, u_char *block, int blocksize);
00369 static int pdv_multibuf_separate(PdvDev *pdv_p, int numbufs, u_char **buffers);
00370 static int pdv_set_roi_internal(PdvDev *pdv_p, int hskip, int hactv, int vskip, int vactv, int call_setsize) ;
00373 static int pdv_specinst_serial_triggered(PdvDev * pdv_p);
00374 static void CheckSumMessage(unsigned char *msg);
00375 int pdv_auto_set_timeout(PdvDev * pdv_p);
00376 static int isafloat(char *str);
00377 static int isdigits(char *str);
00378 static int isxdigits(char *str);
00379 static int update_int_from_serial(char **stat, int nstat, char *str, int *value);
00380 static int update_string_from_serial(char **stat, int nstat, char *str, char *value, int maxlen);
00381 static void update_hex_from_serial(char **stat, int nstat, char *str, int *value);
00382 static void update_2dig_from_serial(char **stat, int nstat, char *str, int *val1, int *val2);
00383 int edt_get_rtimeout(PdvDev * pdv_p);
00384 static int pdv_update_from_kodak_i(PdvDev * pdv_p);
00385
00386 static int pdv_update_from_atmel(PdvDev * pdv_p);
00387 static int pdv_update_from_hamamatsu(PdvDev * pdv_p);
00388 #ifdef IS_UNUSED
00389 static int pdv_set_mode_atmel(PdvDev * pdv_p, char *mode);
00390 static int pdv_set_mode_hamamatsu(PdvDev * pdv_p, char *mode);
00391 #endif
00392
00393 static int pdv_set_exposure_timc1001pf(PdvDev * pdv_p, int value);
00394
00395 int pdv_query_serial(PdvDev * pdv_p, char *cmd, char **resp);
00396
00397
00398
00399 void pdv_dmy_data(void *buf, int width, int height, int depth);
00400 void pdv_alloc_tmpbuf(PdvDev * pdv_p);
00401 extern int pdv_process_inplace(PdvDev *pdv_p);
00402 int pdv_update_size(PdvDev * pdv_p);
00403
00404 static char *hex_to_str(char *resp, int n);
00405
00406 #ifdef DOXYGEN_SHOW_UNDOC
00407
00412 #endif
00413
00472 PdvDev *
00473 pdv_open_channel(const char *dev_name, int unit, int channel)
00474 {
00475 return pdv_open_device(dev_name, unit, channel, 1);
00476 }
00477
00494 PdvDev *
00495 pdv_open_device(const char *dev_name, int unit, int channel, int verbose)
00496 {
00497 PdvDev *pdv_p;
00498 char tmpname[64];
00499 Dependent *dd_p;
00500 static char *debug_env = NULL;
00501 int level;
00502
00503 if ((debug_env == NULL)
00504 && ((debug_env = (char *) getenv("PDVDEBUG")) != NULL)
00505 && *debug_env != '0')
00506 {
00507 Pdv_debug = atoi(debug_env);
00508 level = edt_msg_default_level();
00509 if (Pdv_debug > 0)
00510 {
00511 level |= DBG1;
00512 level |= DBG2;
00513 }
00514 edt_msg_set_level(edt_msg_default_handle(), level);
00515
00516 edt_msg(DBG2, "environment DEBUG set to %d: enabling debug in pdvlib\n", Pdv_debug);
00517 }
00518
00519 edt_msg(DBG2, "pdv_open_channel('%s', %d, %d)\n", dev_name ? dev_name : "NULL",
00520 unit, channel);
00521
00522 if (dev_name == NULL)
00523 strcpy(tmpname, EDT_INTERFACE);
00524 else
00525 strcpy(tmpname, dev_name);
00526 if ((pdv_p = edt_open_device(tmpname, unit, channel, verbose)) == NULL)
00527 return NULL;
00528
00529
00530
00531
00532
00533
00534 if (sizeof(Dependent) > EDT_DEPSIZE)
00535 {
00536 edt_msg(PDVWARN, "pdv_open_channel: sizeof Dependent %d > DEPSIZE %d\n",
00537 sizeof(Dependent), EDT_DEPSIZE);
00538 }
00539 if ((dd_p = (Dependent *) malloc(EDT_DEPSIZE)) == NULL)
00540 {
00541 pdv_close(pdv_p);
00542 return NULL;
00543 }
00544 pdv_p->dd_p = dd_p;
00545
00546 if (edt_get_dependent(pdv_p, dd_p) < 0)
00547 {
00548 free(dd_p);
00549 dd_p = 0;
00550 pdv_p->dd_p = NULL;
00551 pdv_close(pdv_p);
00552 return NULL;
00553 }
00554
00555 pdv_p->tmpbufsize = 0;
00556
00557 pdv_p->dd_p->xilinx_rev = 2;
00558
00559 if (pdv_p->dd_p->swinterlace ||
00560 pdv_p->dd_p->interlace_module[0])
00561 pdv_setup_postproc(pdv_p, pdv_p->dd_p, NULL);
00562
00563 return pdv_p;
00564
00565 }
00566
00567
00568
00595 PdvDev *
00596 pdv_open(char *dev_name, int unit)
00597 {
00598 return pdv_open_channel(dev_name, unit, 0);
00599 }
00600
00601
00608 void
00609 pdv_setup_dma(PdvDev * pdv_p)
00610
00611 {
00612
00613
00614
00615 edt_set_continuous(pdv_p, 0);
00616 pdv_p->dd_p->started_continuous = 0;
00617
00618 edt_startdma_reg(pdv_p, PDV_CMD, PDV_ENABLE_GRAB);
00619 }
00620
00621
00630 int
00631 pdv_close(PdvDev * pdv_p)
00632 {
00633 edt_msg(DBG2, "pdv_close()\n");
00634
00635 if (!pdv_p)
00636 return -1;
00637 if (pdv_p->dd_p)
00638 {
00639 free(pdv_p->dd_p);
00640 pdv_p->dd_p = 0;
00641 }
00642
00643 pdv_free_output_buffers(pdv_p);
00644
00645 return edt_close(pdv_p);
00646 }
00647
00657 int
00658 pdv_bytes_per_line(int width, int depth)
00659
00660 {
00661 if (depth == 1)
00662 return width >> 3;
00663 else if (depth == 2)
00664 return width >> 2;
00665 else if (depth == 4)
00666 return width >> 1;
00667 else if (depth == 80)
00668 return width + (width/4);
00669 else
00670 return width * bits2bytes(depth);
00671 }
00672
00679 int
00680 pdv_get_bytes_per_image(PdvDev *pdv_p)
00681
00682 {
00683 return pdv_p->dd_p->height *
00684 pdv_bytes_per_line(pdv_p->dd_p->width, pdv_p->dd_p->depth);
00685 }
00686
00687
00702 int
00703 pdv_get_width(PdvDev * pdv_p)
00704 {
00705 if (!pdv_p->dd_p)
00706 return (0);
00707
00708 edt_msg(DBG2, "pdv_get_width() %d\n", pdv_p->dd_p->width);
00709
00710
00711 return pdv_p->dd_p->width;
00712 }
00713
00722 int
00723 pdv_get_pitch(PdvDev * pdv_p)
00724 {
00725 int pitch;
00726
00727 if (!pdv_p->dd_p)
00728 return (0);
00729
00730 pitch = pdv_bytes_per_line(pdv_p->dd_p->width,
00731 pdv_p->dd_p->depth);
00732
00733 edt_msg(DBG2, "pdv_get_pitch() %d\n", pitch);
00734
00735
00736 return pitch ;
00737 }
00738
00759 int
00760 pdv_get_cam_width(PdvDev * pdv_p)
00761 {
00762 edt_msg(DBG2, "pdv_get_cam_width() %d\n", pdv_p->dd_p->cam_width);
00763
00764 return pdv_p->dd_p->cam_width;
00765 }
00766
00785 int
00786 pdv_get_dmasize(PdvDev * pdv_p)
00787 {
00788 Dependent *dd_p = PDV_DEPENDENT(pdv_p);
00789
00790 int size;
00791 int extra_dma = 0;
00792
00793
00794 if (pdv_p->dd_p->header_position == HeaderBegin ||
00795 pdv_p->dd_p->header_position == HeaderMiddle ||
00796 pdv_p->dd_p->header_position == HeaderEnd)
00797 extra_dma = pdv_p->dd_p->header_size;
00798
00799 if (dd_p->swinterlace == PDV_INV_RT_INTLV_24_12)
00800 size = dd_p->width * dd_p->height * 3 / 2;
00801 else if (dd_p->swinterlace == PDV_INTLV_10BIT_8TAP_PACKED
00802 || dd_p->swinterlace == PDV_INTLV_10BIT_8TAP_TO_8BIT)
00803 size = dd_p->height * pdv_bytes_per_line(pdv_p->dd_p->width, 80);
00804 else if (dd_p->depth > dd_p->extdepth)
00805 size = dd_p->height * pdv_bytes_per_line(pdv_p->dd_p->width, pdv_p->dd_p->extdepth);
00806 else size = dd_p->height * pdv_bytes_per_line(pdv_p->dd_p->width, pdv_p->dd_p->depth);
00807
00808 return size + extra_dma;
00809 }
00810
00831 int
00832 pdv_setsize(PdvDev * pdv_p, int width, int height)
00833 {
00834 Dependent *dd_p = pdv_p->dd_p;
00835 int wuz_enabled = dd_p->roi_enabled;
00836
00837 edt_msg(DBG2, "pdv_setsize(%d, %d)\n", width, height);
00838
00839 dd_p->width = width;
00840 dd_p->height = height;
00841 pdv_set_roi_internal(pdv_p, dd_p->hskip, width, dd_p->vskip, height, 0);
00842
00843 return pdv_update_size(pdv_p);
00844
00845 }
00846
00866 int
00867 pdv_set_cam_width(PdvDev * pdv_p, int value)
00868 {
00869 int ret;
00870 Dependent *dd_p = pdv_p->dd_p;
00871
00872 edt_msg(DBG2, "pdv_set_cam_width(%d)\n", value);
00873
00874 dd_p->cam_width = value;
00875
00876 ret = edt_set_dependent(pdv_p, dd_p);
00877
00878 return ret;
00879 }
00880
00891 int
00892 pdv_get_imagesize(PdvDev * pdv_p)
00893 {
00894
00895 edt_msg(DBG2, "pdv_get_imagesize() %d\n", pdv_p->dd_p->imagesize);
00896
00897 return pdv_p->dd_p->imagesize;
00898 }
00899
00908 int
00909 pdv_get_allocated_size(PdvDev * pdv_p)
00910 {
00911 Dependent *dd_p = pdv_p->dd_p;
00912 int total = 0;
00913
00914 dd_p->imagesize = dd_p->width * dd_p->height * bits2bytes(dd_p->depth);
00915
00916 total = pdv_p->dd_p->imagesize + pdv_p->dd_p->slop + pdv_p->dd_p->header_size;
00917
00918 #ifdef _NT_
00919
00920 if (total % PAGESIZE)
00921 {
00922 total = ((total / PAGESIZE) + 1) * PAGESIZE;
00923 }
00924 #endif
00925
00926 edt_msg(DBG2, "pdv_get_allocated_size() %d\n", total);
00927
00928 return total;
00929
00930 }
00931
00951 int
00952 pdv_set_timeout(PdvDev * pdv_p, int value)
00953 {
00954 Dependent *dd_p = pdv_p->dd_p;
00955
00956 if (value < 0)
00957 {
00958 edt_msg(DBG2, "pdv_set_timeout(%d) (< 0, going back to auto)\n", value);
00959
00960 pdv_p->dd_p->user_timeout_set = 0;
00961 edt_set_dependent(pdv_p, dd_p);
00962 return pdv_auto_set_timeout(pdv_p);
00963 }
00964 else
00965 {
00966 edt_msg(DBG2, "pdv_set_timeout(%d) (user set, overriding auto)\n", value);
00967
00968 pdv_p->dd_p->user_timeout_set = 1;
00969 pdv_p->dd_p->user_timeout = value;
00970 edt_set_dependent(pdv_p, dd_p);
00971 return edt_set_rtimeout(pdv_p, value);
00972 }
00973 }
00974
00989 int
00990 pdv_get_timeout(PdvDev * pdv_p)
00991 {
00992
00993 edt_msg(DBG2, "pdv_get_timeout()\n");
00994
00995 return edt_get_rtimeout(pdv_p);
00996 }
00997
01010 int
01011 pdv_picture_timeout(PdvDev * pdv_p, int value)
01012 {
01013 return pdv_set_timeout(pdv_p, value);
01014 }
01015
01017
01018
01086 int
01087 pdv_timeouts(PdvDev * pdv_p)
01088 {
01089 int ret;
01090
01091 ret = edt_timeouts(pdv_p);
01092 edt_msg(DBG2, "pdv_timeouts(%d)\n", ret);
01093
01094 return ret;
01095 }
01096
01097
01110 int
01111 pdv_timeout_cleanup(PdvDev * pdv_p)
01112 {
01113 int curdone, curtodo;
01114
01115 curdone = edt_done_count(pdv_p);
01116 curtodo = edt_get_todo(pdv_p);
01117 pdv_stop_continuous(pdv_p);
01118 edt_msleep(500);
01119 edt_set_buffer(pdv_p, curdone);
01120 edt_reg_write(pdv_p, PDV_CMD, PDV_RESET_INTFC);
01121 pdv_setup_continuous(pdv_p);
01122 return curtodo - curdone;
01123 }
01124
01126
01127
01145 int
01146 pdv_get_height(PdvDev * pdv_p)
01147 {
01148 if (!pdv_p->dd_p)
01149 return (0);
01150
01151 edt_msg(DBG2, "pdv_get_height() %d\n", pdv_p->dd_p->height);
01152
01153 return pdv_p->dd_p->height;
01154 }
01155
01175 int
01176 pdv_get_cam_height(PdvDev * pdv_p)
01177 {
01178
01179 edt_msg(DBG2, "pdv_get_cam_height() %d\n", pdv_p->dd_p->cam_height);
01180
01181 return pdv_p->dd_p->cam_height;
01182 }
01183
01184
01201 int
01202 pdv_get_frame_height(PdvDev * pdv_p)
01203 {
01204
01205 edt_msg(DBG2, "pdv_get_cam_height() %d\n", pdv_p->dd_p->cam_height);
01206
01207 return pdv_p->dd_p->frame_height;
01208 }
01209
01211
01221 int
01222 pdv_update_size(PdvDev *pdv_p)
01223
01224 {
01225 Dependent *dd_p = pdv_p->dd_p;
01226 int ret;
01227
01228 edt_msg(DBG2, "update_size\n");
01229
01230 dd_p->imagesize = dd_p->height * pdv_get_pitch(pdv_p);
01231
01232 ret = edt_set_dependent(pdv_p, dd_p);
01233
01234 if (pdv_p->ring_buffer_numbufs > 0)
01235 pdv_multibuf(pdv_p, pdv_p->ring_buffer_numbufs);
01236
01237 if (dd_p->swinterlace)
01238 {
01239 pdv_alloc_tmpbuf(pdv_p);
01240 }
01241
01242 return ret;
01243 }
01244
01259 int
01260 pdv_set_width(PdvDev * pdv_p, int value)
01261 {
01262 Dependent *dd_p = pdv_p->dd_p;
01263
01264 edt_msg(DBG2, "pdv_set_width(%d)\n", value);
01265
01266 dd_p->width = value;
01267
01268 pdv_set_roi(pdv_p, dd_p->hskip, dd_p->width, dd_p->vskip, dd_p->height);
01269 return pdv_update_size(pdv_p);
01270
01271 }
01272
01283 int
01284 pdv_set_height(PdvDev * pdv_p, int value)
01285 {
01286 Dependent *dd_p = pdv_p->dd_p;
01287
01288 edt_msg(DBG2, "pdv_set_height(%d)\n", value);
01289
01290 dd_p->height = value;
01291
01292 pdv_set_roi(pdv_p, dd_p->hskip, dd_p->width, dd_p->vskip, dd_p->height);
01293
01294 return pdv_update_size(pdv_p);
01295
01296 }
01297
01315 int
01316 pdv_set_cam_height(PdvDev * pdv_p, int value)
01317 {
01318 int ret;
01319 Dependent *dd_p = pdv_p->dd_p;
01320
01321 edt_msg(DBG2, "pdv_set_cam_height(%d)\n", value);
01322
01323 dd_p->cam_height = value;
01324
01325 ret = edt_set_dependent(pdv_p, dd_p);
01326 return ret;
01327 }
01328
01329
01338 int
01339 pdv_get_depth(PdvDev * pdv_p)
01340 {
01341 if (!pdv_p->dd_p)
01342 return (0);
01343
01344 edt_msg(DBG2, "pdv_get_depth() %d\n", pdv_p->dd_p->depth);
01345
01346 return pdv_p->dd_p->depth;
01347 }
01348
01366 int
01367 pdv_get_extdepth(PdvDev * pdv_p)
01368 {
01369
01370 edt_msg(DBG2, "pdv_get_extdepth() %d\n", pdv_p->dd_p->extdepth);
01371
01372 return pdv_p->dd_p->extdepth;
01373 }
01374
01398 int
01399 pdv_set_depth_extdepth(PdvDev * pdv_p, int depth, int extdepth)
01400 {
01401
01402 return pdv_set_depth_extdepth_dpath(pdv_p, depth, extdepth, 0);
01403 }
01404
01440 int
01441 pdv_set_depth_extdepth_dpath(PdvDev * pdv_p, int depth, int extdepth, u_int dpath)
01442 {
01443 Dependent *dd_p = pdv_p->dd_p;
01444
01445 dd_p->depth = depth;
01446 dd_p->extdepth = extdepth;
01447
01448
01449
01450
01451
01452 if (pdv_is_cameralink(pdv_p))
01453 {
01454 if (dpath)
01455 {
01456 edt_reg_write(pdv_p, PDV_CL_DATA_PATH, dpath);
01457 dd_p->cl_data_path = dpath;
01458 }
01459 else
01460 {
01461 int reg;
01462
01463 if ((depth == 10) && (extdepth == 80))
01464 reg = 0x79;
01465
01466 else if (depth == 24)
01467 {
01468 reg = 0x7;
01469 if (extdepth == 24)
01470 reg = 0x27;
01471
01472 }
01473
01474 else if (depth == 32)
01475 reg = 0x07;
01476
01477 else if (depth == 30)
01478 reg = 0x09;
01479
01480 else if ((depth >= 8) && (depth <= 16))
01481 reg = depth-1;
01482
01483 else reg = 0;
01484
01485 if (reg)
01486 {
01487 if ((dd_p->dual_channel) && ((reg & 0xf0) == 0))
01488 reg |= 0x10;
01489 dd_p->cl_data_path = reg;
01490 edt_reg_write(pdv_p, PDV_CL_DATA_PATH, dd_p->cl_data_path);
01491 }
01492 }
01493 }
01494
01495 edt_msg(DBG2, "pdv_set_depth_extdepth_dpath(%d, %d, %02x (%02x))\n", depth, extdepth, dpath, dd_p->cl_data_path);
01496
01497 return pdv_update_size(pdv_p);
01498
01499 }
01500
01501
01526 int
01527 pdv_set_depth(PdvDev * pdv_p, int value)
01528 {
01529 Dependent *dd_p = pdv_p->dd_p;
01530
01531 dd_p->depth = value;
01532
01533
01534
01535
01536
01537 if (pdv_is_cameralink(pdv_p))
01538 {
01539 int reg;
01540
01541 if ((value >= 8) && (value <= 16))
01542 reg = value-1;
01543 else if (value == 24 || value == 32)
01544 reg = 0x7;
01545 else if (value == 30)
01546 reg = 0x9;
01547 else reg = 0;
01548
01549 if (reg)
01550 {
01551 if ((dd_p->dual_channel) && ((reg & 0xf0) == 0))
01552 reg |= 0x10;
01553 dd_p->cl_data_path = reg;
01554 edt_reg_write(pdv_p, PDV_CL_DATA_PATH, dd_p->cl_data_path);
01555 }
01556 }
01557
01558 edt_msg(DBG2, "pdv_set_depth(%d)\n", value);
01559 return pdv_update_size(pdv_p);
01560
01561 }
01562
01588 int
01589 pdv_set_extdepth(PdvDev * pdv_p, int value)
01590 {
01591 int ret;
01592 Dependent *dd_p = pdv_p->dd_p;
01593
01594 dd_p->extdepth = value;
01595
01596 edt_msg(DBG2, "pdv_set_extdepth(%d)\n", value);
01597
01598 ret = edt_set_dependent(pdv_p, dd_p);
01599
01600 return ret;
01601 }
01602
01614 int
01615 pdv_set_cameratype(PdvDev * pdv_p, char *model)
01616 {
01617 Dependent *dd_p = pdv_p->dd_p;
01618
01619 edt_msg(DBG2, "pdv_set_cameratype(%s)\n", model);
01620
01621 strcpy(dd_p->cameratype, model);
01622
01623 return edt_set_dependent(pdv_p, dd_p);
01624 }
01625
01626
01643 char *
01644 pdv_get_cameratype(PdvDev * pdv_p)
01645 {
01646 edt_msg(DBG2, "pdv_get_cameratype()\n");
01647
01648 return pdv_p->dd_p->cameratype;
01649 }
01650
01651
01668 char *
01669 pdv_get_camera_class(PdvDev * pdv_p)
01670 {
01671 edt_msg(DBG2, "pdv_get_camera_class()\n");
01672
01673 return pdv_p->dd_p->camera_class;
01674 }
01675
01676
01686 char *
01687 pdv_get_camera_model(PdvDev * pdv_p)
01688 {
01689 edt_msg(DBG2, "pdv_get_camera_model()\n");
01690
01691 return pdv_p->dd_p->camera_model;
01692 }
01693
01704 char *
01705 pdv_get_camera_info(PdvDev * pdv_p)
01706 {
01707 edt_msg(DBG2, "pdv_get_camera_info()\n");
01708
01709 return pdv_p->dd_p->camera_info;
01710 }
01711
01723 char *
01724 pdv_camera_type(PdvDev * pdv_p)
01725 {
01726 edt_msg(DBG2, "pdv_camera_type()\n");
01727
01728 return pdv_p->dd_p->cameratype;
01729 }
01730
01732
01733 static int
01734 smd_read_reg(PdvDev * pdv_p, int reg)
01735 {
01736 u_char buf[128];
01737 int ret;
01738
01739
01740 pdv_serial_read(pdv_p, (char *) buf, 64);
01741
01742
01743 buf[0] = (u_char) reg;
01744 pdv_serial_binary_command(pdv_p, (char *) buf, 1);
01745
01746 ret = pdv_serial_wait(pdv_p, pdv_p->dd_p->serial_timeout, pdv_p->dd_p->serial_respcnt);
01747 if (ret == 0)
01748 return -1;
01749 pdv_serial_read(pdv_p, (char *) buf, ret);
01750 return (int) buf[0];
01751 }
01752
01753
01754
01755
01756
01757
01758
01759
01760 static int
01761 check_valid_formatstr(char *str)
01762 {
01763 int i, len = (int)strlen(str);
01764 int ret = 0;
01765
01766 for (i=0; i<len; i++)
01767 {
01768 if (str[i] == '%')
01769 {
01770 if ((i > 0) && (str[i-1] != '\\'))
01771 ++ret;
01772 else if (i == len-1)
01773 {
01774 ret = -1;
01775 break;
01776 }
01777
01778 }
01779 }
01780 return ret;
01781 }
01782
01822 int
01823 pdv_set_exposure(PdvDev * pdv_p, int value)
01824 {
01825 int ret = -1;
01826 Dependent *dd_p = pdv_p->dd_p;
01827 char cmdstr[64];
01828 int n;
01829
01830 cmdstr[0] = '\0';
01831
01832 edt_msg(DBG2, "pdv_set_exposure(%d)\n", value);
01833
01834 dd_p->shutter_speed = value;
01835
01836 if (edt_set_dependent(pdv_p, dd_p) < 0)
01837 {
01838 edt_msg(DBG2, "pdv_set_exposure ret %d\n", ret);
01839 return -1;
01840 }
01841
01842 pdv_auto_set_timeout(pdv_p);
01843
01844 if ((dd_p->camera_shutter_timing == AIA_MCL)
01845 && (dd_p->mode_cntl_norm & 0xf0)
01846 && (!dd_p->trig_pulse))
01847 {
01848 ret = pdv_set_exposure_mcl(pdv_p, value);
01849 }
01850 else if (dd_p->camera_shutter_timing == AIA_MCL_100US)
01851 {
01852
01853 ret = pdv_set_exposure_mcl(pdv_p, value);
01854 }
01855 else if ((strlen(dd_p->serial_exposure) >= 0) && (dd_p->serial_format == SERIAL_BINARY))
01856 {
01857 send_serial_binary_cmd(pdv_p, dd_p->serial_exposure, value);
01858 }
01859 else if ((strlen(dd_p->serial_exposure) >= 0)
01860 && ((dd_p->serial_format == SERIAL_ASCII)
01861 || (dd_p->serial_format == SERIAL_ASCII_HEX)
01862 || (dd_p->serial_format == SERIAL_PULNIX_1010)))
01863 {
01864
01865
01866
01867 if (dd_p->camera_shutter_timing == HAM_4880_SER)
01868 {
01869 int minutes;
01870 int seconds;
01871 int useconds;
01872
01873 minutes = value / 60000;
01874 value -= minutes * 60000;
01875
01876 seconds = value / 1000;
01877 value -= seconds * 1000;
01878
01879 useconds = value;
01880
01881 sprintf(cmdstr, "%s %04d:%02d.%03d",
01882 dd_p->serial_exposure, minutes, seconds, useconds);
01883 }
01884
01885 else switch(dd_p->serial_format)
01886 {
01887
01888 case SERIAL_ASCII_HEX:
01889 sprintf(cmdstr, "%s %02x", dd_p->serial_exposure, value);
01890 break;
01891
01892 case SERIAL_PULNIX_1010:
01893 sprintf(cmdstr, "%s%d", dd_p->serial_exposure, value);
01894 break;
01895
01896 case SERIAL_ASCII:
01897 default:
01898 {
01899 int n = check_valid_formatstr(dd_p->serial_exposure);
01900
01901 cmdstr[0] = '\0';
01902
01903 if (n == 0)
01904 {
01905 if (dd_p->serial_exposure[0])
01906 sprintf(cmdstr, "%s %d", dd_p->serial_exposure, value);
01907 }
01908 else if ((n > 0) && (n < 5))
01909 sprintf(cmdstr, dd_p->serial_exposure, value, value, value, value);
01910
01911 if (cmdstr[0])
01912 {
01913 ret = pdv_serial_command_flagged(pdv_p, cmdstr, SCFLAG_NORESP);
01914
01915 pdv_serial_wait(pdv_p, pdv_p->dd_p->serial_timeout, 64);
01916 if (*pdv_p->dd_p->serial_response)
01917 pdv_serial_read(pdv_p, cmdstr, 63);
01918 }
01919 }
01920
01921 if (check_valid_formatstr(dd_p->serial_exposure) >= 1)
01922 sprintf(cmdstr, dd_p->serial_exposure, value, value, value, value);
01923 else sprintf(cmdstr, "%s %d", dd_p->serial_exposure, value);
01924 break;
01925 }
01926
01927 if (cmdstr[0])
01928 {
01929 ret = pdv_serial_command_flagged(pdv_p, cmdstr, SCFLAG_NORESP);
01930 n = pdv_serial_wait(pdv_p, pdv_p->dd_p->serial_timeout, pdv_p->dd_p->serial_respcnt);
01931 if (*pdv_p->dd_p->serial_response)
01932 if (n)
01933 pdv_serial_read(pdv_p, cmdstr, n);
01934 }
01935 }
01936 else if ((dd_p->camera_shutter_timing == SPECINST_SERIAL)
01937 || (dd_p->camera_shutter_speed == SPECINST_SERIAL))
01938 {
01939 ret = pdv_set_exposure_specinst(pdv_p, value);
01940 }
01941 else if (dd_p->camera_shutter_timing == SMD_SERIAL)
01942 {
01943 ret = pdv_set_exposure_smd(pdv_p, value);
01944 }
01945 else if (dd_p->camera_shutter_timing == PTM6710_SERIAL)
01946 {
01947 ret = pdv_set_exposure_ptm6710_1020(pdv_p, value);
01948 }
01949 else if (dd_p->camera_shutter_timing == TOSHIBA_SERIAL)
01950 {
01951 ret = pdv_set_exposure_toshiba(pdv_p, value);
01952 }
01953 else if (dd_p->camera_shutter_timing == COHU_SERIAL)
01954 {
01955 ret = pdv_set_exposure_cohu(pdv_p, value);
01956 }
01957 else if (dd_p->camera_shutter_timing == PTM1020_SERIAL)
01958 {
01959 ret = pdv_set_exposure_ptm6710_1020(pdv_p, value);
01960 }
01961 else if (dd_p->camera_shutter_timing == TIMC1001_SERIAL)
01962 {
01963 ret = pdv_set_exposure_timc1001pf(pdv_p, value);
01964 }
01965 else if (dd_p->camera_shutter_timing == ADIMEC_SERIAL)
01966 {
01967 ret = pdv_set_exposure_adimec(pdv_p, value);
01968 }
01969 else if (dd_p->camera_shutter_timing == BASLER202K_SERIAL)
01970 {
01971 ret = pdv_set_exposure_basler202k(pdv_p, value);
01972 }
01973 else if (dd_p->camera_shutter_timing == SU320_SERIAL)
01974 {
01975 ret = pdv_set_exposure_su320(pdv_p, value);
01976 }
01977 else if (dd_p->camera_shutter_timing == HAM_4880_SER)
01978 {
01979
01980 }
01981 else if (dd_p->camera_shutter_timing == AIA_SERIAL)
01982 {
01983
01984 }
01985 else if (dd_p->camera_shutter_timing == AIA_SERIAL_ES40)
01986 {
01987
01988 }
01989 else if (dd_p->camera_shutter_timing == AIA_TRIG)
01990 {
01991 ret = pdv_set_exposure_mcl(pdv_p, value);
01992 }
01993 else if (!dd_p->trig_pulse)
01994 {
01995
01996 ret = pdv_set_exposure_mcl(pdv_p, value);
01997 }
01998
01999 edt_msg(DBG2, "pdv_set_exposure returns %d\n", ret);
02000 return (ret);
02001 }
02002
02019 int
02020 pdv_set_exposure_mcl(PdvDev * pdv_p, int value)
02021 {
02022 u_int data_path;
02023
02024 if (value < 0)
02025 value = 0;
02026 if (value > 25500)
02027 value = 25500;
02028
02029 pdv_p->dd_p->shutter_speed = value;
02030
02031 data_path = pdv_p->dd_p->datapath_reg;
02032 data_path &= ~PDV_MULTIPLIER_MASK;
02033
02034
02035
02036
02037
02038 if (pdv_p->dd_p->camera_shutter_timing == AIA_MCL_100US)
02039 {
02040 edt_msg(DBG2, "pdv_set_exposure_mcl(%d) (100US)\n", value);
02041
02042 if (value < 256)
02043 {
02044 data_path |= PDV_MULTIPLIER_100US;
02045 }
02046 else if (value < 2560)
02047 {
02048
02049 value = (value + 5) / 10;
02050 }
02051 else if (value < 25600)
02052 {
02053 data_path |= PDV_MULTIPLIER_10MS;
02054 value = (value + 50) / 100;
02055 }
02056 else if (value < 256000)
02057 {
02058 data_path |= PDV_MULTIPLIER_100MS;
02059 value = (value + 50) / 1000;
02060 }
02061 }
02062 else
02063 {
02064 edt_msg(DBG2, "pdv_set_exposure_mcl(%d)\n", value);
02065
02066 if (value < 256)
02067 {
02068
02069 }
02070 else if (value < 2560)
02071 {
02072 data_path |= PDV_MULTIPLIER_10MS;
02073 value = (value + 5) / 10;
02074 }
02075 else
02076 {
02077 data_path |= PDV_MULTIPLIER_100MS;
02078 value = (value + 50) / 100;
02079 }
02080 }
02081
02082 pdv_p->dd_p->datapath_reg = data_path;
02083 edt_reg_write(pdv_p, PDV_SHUTTER, value);
02084 edt_reg_write(pdv_p, PDV_DATA_PATH, data_path);
02085
02086 return 0;
02087 }
02088
02092 static int
02093 pdv_set_exposure_smd(PdvDev * pdv_p, int value)
02094 {
02095 int fp = 0;
02096 u_char buf[128];
02097 int n;
02098 int ret = 0;
02099 int smd_reg1, smd_reg3;
02100
02101
02102 if (Smd_type == NOT_SET)
02103 {
02104 Smd_type = smd_read_reg(pdv_p, SMD_READ_CAMTYPE);
02105 if ((Smd_type & 0xfff) == 0xfff)
02106
02107 Smd_type = smd_read_reg(pdv_p, SMD_READ_CAMTYPE);
02108 }
02109
02110
02111 switch (Smd_type)
02112 {
02113 case SMD_TYPE_4M4:
02114
02115
02116
02117
02118
02119 if (value == 0)
02120 buf[1] = 0x7d;
02121 else if (value == 1)
02122 buf[1] = 0x7b;
02123 else if (value == 2)
02124 buf[1] = 0x77;
02125 else if (value <= 4)
02126 buf[1] = 0x6f;
02127 else if (value <= 8)
02128 buf[1] = 0x5f;
02129 else if (value <= 16)
02130 buf[1] = 0x3f;
02131 else
02132 buf[1] = 0x00;
02133
02134
02135
02136 pdv_serial_binary_command(pdv_p, (char *) buf, 2);
02137 break;
02138
02139 case SMD_TYPE_BT25:
02140
02141
02142
02143 buf[0] = (u_char) SMD_BT25_WRITE_R2;
02144 if (Smd_rate == NOT_SET)
02145 {
02146 if ((Smd_rate = smd_read_reg(pdv_p, SMD_BT25_READ_FRAMERATE)) == -1)
02147 edt_msg(PDVWARN, "libpdv: no response from SMD camera rate reg read\n");
02148 if (pdv_p->dd_p->timeout_multiplier < Smd_rate)
02149 {
02150 pdv_p->dd_p->timeout_multiplier = Smd_rate;
02151 pdv_auto_set_timeout(pdv_p);
02152 }
02153 }
02154 buf[1] = (u_char) value;
02155
02156
02157
02158 pdv_serial_binary_command(pdv_p, (char *) buf, 2);
02159
02160
02161 pdv_serial_wait(pdv_p, 100, 64);
02162 break;
02163
02164 case SMD_TYPE_1M30P:
02165 case SMD_TYPE_6M3P:
02166 buf[0] = (u_char) SMD_1M30P_REG_W_INTEG0;
02167 buf[1] = value & 0xff;
02168 pdv_serial_binary_command(pdv_p, (char *) buf, 2);
02169
02170 buf[0] = (u_char) SMD_1M30P_REG_W_INTEG1;
02171 buf[1] = (value & 0xff00) >> 8;
02172 pdv_serial_binary_command(pdv_p, (char *) buf, 2);
02173
02174 buf[0] = (u_char) SMD_1M30P_REG_W_INTEG2;
02175 buf[1] = (value & 0xff0000) >> 16;
02176 pdv_serial_binary_command(pdv_p, (char *) buf, 2);
02177
02178
02179
02180
02181
02182
02183
02184
02185 pdv_p->dd_p->shutter_speed = value / 1000;
02186 pdv_auto_set_timeout(pdv_p);
02187 pdv_p->dd_p->shutter_speed = value;
02188 break;
02189
02190 case SMD_TYPE_1M15P:
02191 if ((smd_reg1 = smd_read_reg(pdv_p, SMD_1M15P_READ_R1)) == -1)
02192 {
02193 edt_msg(PDVWARN, "libpdv: no response from SMD R1 reg read\n");
02194 return -1;
02195 }
02196
02197
02198 buf[0] = (u_char) SMD_1M15P_WRITE_R1;
02199
02200
02201
02202
02203
02204 if (value == 0)
02205 {
02206 buf[1] = (smd_reg1 &~ SMD_1M15P_R1_INTMSK) | 0x0;
02207 fp = 65000;
02208 }
02209 else if (value == 1)
02210 {
02211 buf[1] = (smd_reg1 &~ SMD_1M15P_R1_INTMSK) | 0x7;
02212 fp = 65000;
02213 }
02214 else if (value < 4)
02215 {
02216 buf[1] = (smd_reg1 &~ SMD_1M15P_R1_INTMSK) | 0x6;
02217 fp = 64000;
02218 }
02219 else if (value < 7)
02220 {
02221 buf[1] = (smd_reg1 &~ SMD_1M15P_R1_INTMSK) | 0x5;
02222 fp = 62000;
02223 }
02224 else if (value == 8)
02225 {
02226 buf[1] = (smd_reg1 &~ SMD_1M15P_R1_INTMSK) | 0x4;
02227 fp = 58000;
02228 }
02229 else return -1;
02230
02231 if (smd_reg1 & SMD_1M15P_R1_TRIGMODE)
02232 {
02233
02234 smd_reg3 = smd_read_reg(pdv_p, SMD_1M15P_READ_R3);
02235 if (smd_reg3 & 0x40)
02236 fp /= 2;
02237 pdv_set_frame_period(pdv_p, fp, PDV_FVAL_ADJUST);
02238 }
02239
02240 pdv_p->dd_p->shutter_speed = value;
02241 pdv_serial_binary_command(pdv_p, (char *) buf, 2);
02242 break;
02243
02244 default:
02245 ret = -1;
02246 edt_msg(PDVWARN, "libpdv: unknown SMD camera type %02x\n", Smd_type);
02247 break;
02248 }
02249
02250 if (!ret)
02251 {
02252
02253 n = pdv_serial_wait(pdv_p, 100, 64);
02254 if (n > 127)
02255 n = 127;
02256 if (n)
02257 pdv_serial_read(pdv_p, (char *) buf, n);
02258 }
02259 return ret;
02260 }
02261
02270 static int
02271 pdv_set_exposure_timc1001pf(PdvDev * pdv_p, int value)
02272 {
02273 Dependent *dd_p = pdv_p->dd_p;
02274 u_int mcl = edt_reg_read(pdv_p, PDV_MODE_CNTL) & 0xf1;
02275
02276 if ((value >= 0) && (value <= 7))
02277 {
02278 dd_p->shutter_speed = value;
02279 mcl |= (value << 1);
02280 edt_reg_write(pdv_p, PDV_MODE_CNTL, mcl);
02281 return 0;
02282 }
02283 return -1;
02284 }
02285
02289 static int
02290 pdv_set_exposure_toshiba(PdvDev * pdv_p, int value)
02291 {
02292 char cmdbuf[128];
02293 int n;
02294
02295 if ((value < 0) || (value > 0xff))
02296 return -1;
02297
02298 cmdbuf[0] = 0x02;
02299 sprintf(cmdbuf+1, "68%02X", value);
02300 cmdbuf[5] = 0x03;
02301 pdv_serial_binary_command(pdv_p, (char *)cmdbuf, 6);
02302
02303
02304 if (n = pdv_serial_wait(pdv_p, 200, 3))
02305 pdv_serial_read(pdv_p, cmdbuf, n);
02306
02307 cmdbuf[0] = 0x02;
02308 sprintf(cmdbuf+1, "6E01");
02309 cmdbuf[5] = 0x03;
02310 pdv_serial_binary_command(pdv_p, (char *)cmdbuf, 6);
02311
02312
02313 if (n = pdv_serial_wait(pdv_p, 200, 3))
02314 pdv_serial_read(pdv_p, cmdbuf, n);
02315
02316 return 0;
02317 }
02318
02322 static int
02323 pdv_set_gain_toshiba(PdvDev * pdv_p, int value)
02324 {
02325 char cmdbuf[128];
02326 int n;
02327
02328 if ((value < 0) || (value > 0xff))
02329 return -1;
02330
02331 cmdbuf[0] = 0x02;
02332 sprintf(cmdbuf+1, "64%02X", value);
02333 cmdbuf[5] = 0x03;
02334 pdv_serial_binary_command(pdv_p, (char *)cmdbuf, 6);
02335
02336
02337 if (n = pdv_serial_wait(pdv_p, 200, 3))
02338 pdv_serial_read(pdv_p, cmdbuf, n);
02339
02340 cmdbuf[0] = 0x02;
02341 sprintf(cmdbuf+1, "6E01");
02342 cmdbuf[5] = 0x03;
02343 pdv_serial_binary_command(pdv_p, (char *)cmdbuf, 6);
02344
02345
02346 if (n = pdv_serial_wait(pdv_p, 200, 3))
02347 pdv_serial_read(pdv_p, cmdbuf, n);
02348
02349 return 0;
02350 }
02351
02355 static int
02356 pdv_set_exposure_cohu(PdvDev * pdv_p, int value)
02357 {
02358 char cmdbuf[128];
02359 int n, len;
02360
02361 if ((value < 0) || (value > 10))
02362 return -1;
02363
02364
02365 cmdbuf[0] = 0x02;
02366 cmdbuf[1] = 0x01;
02367 sprintf(cmdbuf+2, "cE2,%d", value);
02368 len = (int)strlen(cmdbuf);
02369 cmdbuf[len++] = (char)0x81;
02370 cmdbuf[len++] = (char)0x03;
02371 cmdbuf[len] = 0;
02372 pdv_serial_binary_command(pdv_p, (char *)cmdbuf, len);
02373
02374
02375 if (n = pdv_serial_wait(pdv_p, 200, 7))
02376 pdv_serial_read(pdv_p, cmdbuf, n);
02377
02378
02379 cmdbuf[0] = (char)0x02;
02380 cmdbuf[1] = (char)0x01;
02381 cmdbuf[2] = 'c';
02382 cmdbuf[3] = 'T';
02383 cmdbuf[4] = '0';
02384 cmdbuf[5] = (char)0x81;
02385 cmdbuf[6] = (char)0x03;
02386 pdv_serial_binary_command(pdv_p, (char *)cmdbuf, 7);
02387
02388
02389 if (n = pdv_serial_wait(pdv_p, 200, 7))
02390 pdv_serial_read(pdv_p, cmdbuf, n);
02391
02392 return 0;
02393 }
02394
02398 static int
02399 pdv_set_gain_cohu(PdvDev * pdv_p, int value)
02400 {
02401 char cmdbuf[128];
02402 int n, len;
02403
02404 if ((value < 0) || (value > 320))
02405 return -1;
02406
02407
02408 cmdbuf[0] = (char)0x02;
02409 cmdbuf[1] = (char)0x01;
02410 sprintf(cmdbuf+2, "cB1,%d", value);
02411 len = (int)strlen(cmdbuf);
02412 cmdbuf[len++] = (char)0x81;
02413 cmdbuf[len++] = (char)0x03;
02414 cmdbuf[len] = 0;
02415 pdv_serial_binary_command(pdv_p, (char *)cmdbuf, len);
02416
02417
02418 if (n = pdv_serial_wait(pdv_p, 200, 7))
02419 pdv_serial_read(pdv_p, cmdbuf, n);
02420
02421
02422 cmdbuf[0] = (char)0x02;
02423 cmdbuf[1] = (char)0x01;
02424 cmdbuf[2] = 'c';
02425 cmdbuf[3] = 'T';
02426 cmdbuf[4] = '0';
02427 cmdbuf[5] = (char)0x81;
02428 cmdbuf[6] = (char)0x03;
02429 pdv_serial_binary_command(pdv_p, (char *)cmdbuf, 7);
02430
02431
02432 if (n = pdv_serial_wait(pdv_p, 200, 7))
02433 pdv_serial_read(pdv_p, cmdbuf, n);
02434
02435 return 0;
02436 }
02437
02441 static int
02442 pdv_set_blacklevel_cohu(PdvDev * pdv_p, int value)
02443 {
02444 char cmdbuf[128];
02445 int n, len;
02446
02447 if ((value < 0) || (value > 1023))
02448 return -1;
02449
02450
02451 cmdbuf[0] = 0x02;
02452 cmdbuf[1] = 0x01;
02453 sprintf(cmdbuf+2, "cB0,%d", value);
02454 len = (int)strlen(cmdbuf);
02455 cmdbuf[len++] = (char)0x81;
02456 cmdbuf[len++] = (char)0x03;
02457 cmdbuf[len] = 0;
02458 pdv_serial_binary_command(pdv_p, (char *)cmdbuf, len);
02459
02460
02461 if (n = pdv_serial_wait(pdv_p, 200, 7))
02462 pdv_serial_read(pdv_p, cmdbuf, n);
02463
02464
02465 cmdbuf[0] = (char)0x02;
02466 cmdbuf[1] = (char)0x01;
02467 cmdbuf[2] = 'c';
02468 cmdbuf[3] = 'T';
02469 cmdbuf[4] = '0';
02470 cmdbuf[5] = (char)0x81;
02471 cmdbuf[6] = (char)0x03;
02472 pdv_serial_binary_command(pdv_p, (char *)cmdbuf, 7);
02473
02474
02475 if (n = pdv_serial_wait(pdv_p, 200, 7))
02476 pdv_serial_read(pdv_p, cmdbuf, n);
02477
02478 return 0;
02479 }
02480
02484 static int
02485 pdv_set_exposure_ptm6710_1020(PdvDev * pdv_p, int value)
02486 {
02487 char buf[128];
02488
02489 if ((value < 0) || (value > 9))
02490 return -1;
02491
02492 sprintf(buf, ":SM%d", value);
02493 pdv_serial_command_flagged(pdv_p, buf, SCFLAG_NORESP);
02494
02495 return 0;
02496 }
02497
02501 static int
02502 pdv_set_gain_ptm6710_1020(PdvDev * pdv_p, int value)
02503 {
02504 char buf[128];
02505
02506 if ((value < 0) || (value > 0xff))
02507 return -1;
02508
02509 sprintf(buf, ":GM%02X", value);
02510 pdv_serial_command_flagged(pdv_p, buf, SCFLAG_NORESP);
02511
02512 return 0;
02513 }
02514
02519 static int
02520 pdv_set_gain_hc8484(PdvDev * pdv_p, int value)
02521 {
02522 char buf[128];
02523
02524 if ((value != 0) && (value != 1))
02525 return -1;
02526 sprintf(buf, "CEG %c", value ? 'H' : 'L');
02527 pdv_serial_command_flagged(pdv_p, buf, SCFLAG_NORESP);
02528
02529 return 0;
02530 }
02531
02536 static int
02537 pdv_set_exposure_adimec(PdvDev * pdv_p, int value)
02538 {
02539 char cmdbuf[32];
02540
02541 sprintf(cmdbuf, "@IT%d", value);
02542 pdv_serial_command(pdv_p, cmdbuf);
02543 return 0;
02544 }
02545
02546 static int
02547 pdv_set_gain_adimec(PdvDev * pdv_p, int value)
02548 {
02549 char cmdbuf[32];
02550
02551 sprintf(cmdbuf, "@GA%d", value);
02552 pdv_serial_command(pdv_p, cmdbuf);
02553 return 0;
02554 }
02555
02556 static int
02557 pdv_set_blacklevel_adimec(PdvDev * pdv_p, int value)
02558 {
02559 char cmdbuf[32];
02560
02561 sprintf(cmdbuf, "@BL%d;%d", value, value);
02562 pdv_serial_command(pdv_p, cmdbuf);
02563 return 0;
02564 }
02565
02566
02571 static int
02572 pdv_set_exposure_specinst(PdvDev * pdv_p, int value)
02573 {
02574 edt_msg(DBG2, "pdv_set_exposure_specinst(%d)\n", value);
02575
02576 if (pdv_specinst_setparam(pdv_p, 'G', 8, value) != 0)
02577 {
02578 edt_msg(DBG2, "pdv_set_exposure_specinst() apparently FAILED\n");
02579 return -1;
02580 }
02581 return 0;
02582 }
02583
02588 static int
02589 pdv_set_gain_specinst(PdvDev * pdv_p, int value)
02590 {
02591 edt_msg(DBG2, "pdv_set_gain_specinst(%d)\n", value);
02592
02593 if (pdv_specinst_setparam(pdv_p, 'G', 11, value) != 0)
02594 {
02595 edt_msg(DBG2, "pdv_set_gain_specinst() apparently FAILED\n");
02596 return -1;
02597 }
02598 return 0;
02599 }
02600
02606 static int
02607 pdv_set_exposure_su320(PdvDev * pdv_p, int value)
02608 {
02609 char cmdbuf[32];
02610 char resp[1024];
02611 int n;
02612
02613 sprintf(cmdbuf, "INT%d", value);
02614 pdv_serial_command(pdv_p, cmdbuf);
02615 pdv_serial_wait(pdv_p, 100, 20);
02616 if ((n = pdv_serial_read(pdv_p, resp, 20)) != 20)
02617 return -1;
02618 return 0;
02619 }
02620
02621
02622 static int
02623 pdv_specinst_setparam(PdvDev * pdv_p, char cmd, u_long offset, u_long value)
02624 {
02625 int ret1, ret2, ret3;
02626 char resp1[32];
02627 char resp2[32];
02628 char buf[32];
02629 u_char cmdbuf[5];
02630 u_char offsetbuf[5];
02631 u_char parambuf[5];
02632 int si_wait = 200;
02633
02634 edt_msg(DBG2, "pdv_specinst_setparam(%c %04x %04x)\n", cmd, offset, value);
02635
02636 dvu_long_to_charbuf(offset, offsetbuf);
02637 dvu_long_to_charbuf(value, parambuf);
02638
02639 cmdbuf[0] = cmd;
02640
02641 pdv_serial_binary_command(pdv_p, (char *) cmdbuf, 1);
02642 pdv_serial_wait_next(pdv_p, si_wait, 31);
02643 ret1 = pdv_serial_read(pdv_p, resp1, 31);
02644
02645 pdv_serial_binary_command(pdv_p, (char *) offsetbuf, 4);
02646 pdv_serial_wait_next(pdv_p, si_wait, 31);
02647 ret2 = pdv_serial_read(pdv_p, buf, 31);
02648
02649 pdv_serial_binary_command(pdv_p, (char *) parambuf, 4);
02650 pdv_serial_wait_next(pdv_p, si_wait, 31);
02651 ret3 = pdv_serial_read(pdv_p, resp2, 31);
02652
02653 if ((ret1 != 1) || (ret3 != 1) || (resp1[0] != 'G') || (resp2[0] != 'Y'))
02654 {
02655 edt_msg(DBG1, "invalid or missing serial response from specinst\n");
02656 return -1;
02657 }
02658 return 0;
02659 }
02660
02674 int
02675 pdv_send_basler_command(PdvDev * pdv_p, int cmd, int rwflag, int len, int data)
02676 {
02677 int i;
02678 u_char frame[32];
02679 u_char rwbit = (rwflag & 0x1) << 7;
02680
02681 frame[0] = cmd;
02682 frame[1] = ((u_char)len & 0xef) | rwbit;
02683 for (i=0; i<len; i++)
02684 frame[i+2] = (data >> (8 * i)) & 0xff;
02685
02686 return pdv_send_basler_frame(pdv_p, frame, len+2);
02687 }
02688
02694 int
02695 pdv_set_exposure_basler202k(PdvDev * pdv_p, int value)
02696 {
02697 u_char rframe[8];
02698
02699 memset(rframe, 0, 8);
02700 pdv_send_basler_command(pdv_p, 0xa6, 0, 3, value);
02701 pdv_read_basler_frame(pdv_p, rframe, 1);
02702 if (rframe[0] != 0x6)
02703 return -1;
02704 return 0;
02705 }
02706
02707 int
02708 pdv_set_gain_basler202k(PdvDev * pdv_p, int valuea, int valueb)
02709 {
02710 u_char rframe[8];
02711
02712 memset(rframe, 0, 8);
02713 pdv_send_basler_command(pdv_p, 0x80, 0, 2, valuea);
02714 pdv_read_basler_frame(pdv_p, rframe, 1);
02715 if (rframe[0] != 0x6)
02716 return -1;
02717
02718 memset(rframe, 0, 8);
02719 pdv_send_basler_command(pdv_p, 0x82, 0, 2, valueb);
02720 pdv_read_basler_frame(pdv_p, rframe, 1);
02721 if (rframe[0] != 0x6)
02722 return -1;
02723
02724 return 0;
02725 }
02726
02727 int
02728 pdv_set_offset_basler202k(PdvDev * pdv_p, int valuea, int valueb)
02729 {
02730 u_char rframe[8];
02731
02732 memset(rframe, 0, 8);
02733 pdv_send_basler_command(pdv_p, 0x81, 0, 2, valuea);
02734 pdv_read_basler_frame(pdv_p, rframe, 1);
02735 if (rframe[0] != 0x6)
02736 return -1;
02737
02738 memset(rframe, 0, 8);
02739 pdv_send_basler_command(pdv_p, 0x83, 0, 2, valueb);
02740 pdv_read_basler_frame(pdv_p, rframe, 1);
02741 if (rframe[0] != 0x6)
02742 return -1;
02743 return 0;
02744 }
02745
02762 int
02763 pdv_set_exposure_duncan_ch(PdvDev * pdv_p, int value, int ch)
02764 {
02765 u_char msg[8];
02766 u_char rmsg[16];
02767
02768 msg[0] = 0x04;
02769 msg[1] = 0x00;
02770 msg[2] = 0x14;
02771 msg[3] = (u_char)(ch & 0xff);
02772 msg[4] = (u_char)(value & 0xff);
02773 msg[5] = (u_char)((value >> 8) & 0xff);
02774 pdv_send_duncan_frame(pdv_p, msg, 6);
02775 pdv_read_duncan_frame(pdv_p, rmsg);
02776 return 0;
02777 }
02778
02795 int
02796 pdv_set_gain_duncan_ch(PdvDev * pdv_p, int value, int ch)
02797 {
02798 u_char msg[8];
02799 u_char rmsg[16];
02800
02801 msg[0] = 0x04;
02802 msg[1] = 0x00;
02803 msg[2] = 0x02;
02804 msg[3] = (u_char)(ch & 0xff);
02805 msg[4] = (u_char)(value & 0xff);
02806 msg[5] = (u_char)((value >> 8) & 0xff);
02807 pdv_send_duncan_frame(pdv_p, msg, 6);
02808 pdv_read_duncan_frame(pdv_p, rmsg);
02809 return 0;
02810 }
02811
02812
02817 static void
02818 send_serial_binary_cmd(PdvDev * pdv_p, char *hexstr, int value)
02819 {
02820 int nb;
02821 u_char hbuf[2];
02822 char resp[128];
02823 char bs[16][3];
02824 int ret;
02825
02826 edt_msg(DBG2, "send_serial_binary_cmd(\"%s\", %d)\n", hexstr, value);
02827
02828 nb = sscanf(hexstr, "%s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s",
02829 bs[0], bs[1], bs[2], bs[3], bs[4], bs[5], bs[6], bs[7],
02830 bs[8], bs[9], bs[10], bs[11], bs[12], bs[13], bs[14], bs[15]);
02831
02832 pdv_serial_binary_command(pdv_p, (char *) hbuf, nb);
02833 pdv_serial_wait(pdv_p, 100, 3);
02834
02835 if (*pdv_p->dd_p->serial_response)
02836 ret = pdv_serial_read(pdv_p, resp, 50);
02837
02838 {
02839
02840 edt_msg(DBG2, "serial response <%s> (%d)\n", hex_to_str(resp, ret), ret);
02841 }
02842 }
02843
02870 int
02871 pdv_auto_set_timeout(PdvDev * pdv_p)
02872 {
02873 Dependent *dd_p = pdv_p->dd_p;
02874 int user_timeout = dd_p->user_timeout;
02875 int user_set = dd_p->user_timeout_set;
02876 int tmult = dd_p->timeout_multiplier;
02877 int cur_timeout = edt_get_rtimeout(pdv_p);
02878 int timeout;
02879 int exposure;
02880 int pdiv = 1;
02881 int ret = 0;
02882 int xfersize;
02883
02884
02885
02886
02887 if (tmult < 1)
02888 tmult = 1;
02889
02890
02891 if (dd_p->pclock_speed < 5)
02892 dd_p->pclock_speed = 5;
02893 pdiv = dd_p->pclock_speed / 5;
02894
02895 if (((exposure = dd_p->shutter_speed)) < 500)
02896 exposure = 500;
02897
02898 xfersize = dd_p->cam_width * dd_p->cam_height * bits2bytes(dd_p->depth);
02899 timeout = (((xfersize * tmult) / 4000) / pdiv) + exposure;
02900
02901 edt_msg(DBG2, "pdv_auto_set_timeout(): current %d new %d exposure %d pclock %d pdiv %d mult %d user %d\n",
02902 cur_timeout, timeout, exposure, dd_p->pclock_speed, pdiv,
02903 tmult, user_timeout);
02904
02905
02906
02907
02908
02909 if (timeout < 500)
02910 timeout = 500;
02911
02912 if (user_set)
02913 {
02914 edt_msg(DBG2, " user set to %d - overriding auto\n", user_timeout);
02915
02916 if (timeout > user_timeout && user_timeout != 0)
02917 {
02918 edt_msg(DBG2, " Warning: exposure %d msecs user specified timeout %d msecs\n", dd_p->shutter_speed, user_timeout);
02919 edt_msg(DBG2, " not automatically increased since user specified\n");
02920 }
02921 }
02922 else
02923 {
02924 int targ;
02925
02926 edt_msg(DBG2, " setting picture timeout from %d to %d\n", cur_timeout, timeout);
02927 targ = timeout;
02928 ret = edt_set_rtimeout(pdv_p, targ);
02929 }
02930 return ret;
02931 }
02932
02952 int
02953 pdv_set_gain(PdvDev * pdv_p, int value)
02954 {
02955 int ret;
02956 Dependent *dd_p = pdv_p->dd_p;
02957
02958 edt_msg(DBG2, "pdv_set_gain(%d)\n", value);
02959
02960 dd_p->gain = value;
02961 ret = edt_set_dependent(pdv_p, dd_p);
02962
02963 if ((strlen(dd_p->serial_gain) > 0) && (dd_p->serial_format == SERIAL_BINARY))
02964 send_serial_binary_cmd(pdv_p, dd_p->serial_gain, value);
02965
02966 else if (dd_p->serial_format == SERIAL_ASCII)
02967 {
02968 char cmdstr[64] = {'\0'};
02969 int n = check_valid_formatstr(dd_p->serial_gain);
02970
02971 if (n == 0)
02972 {
02973 if (dd_p->serial_gain[0])
02974 sprintf(cmdstr, "%s %d", dd_p->serial_gain, value);
02975 }
02976 else if ((n > 0) && (n < 5))
02977 sprintf(cmdstr, dd_p->serial_gain, value, value, value, value);
02978
02979 if (cmdstr[0])
02980 {
02981 ret = pdv_serial_command_flagged(pdv_p, cmdstr, SCFLAG_NORESP);
02982
02983 pdv_serial_wait(pdv_p, pdv_p->dd_p->serial_timeout, 64);
02984 if (*pdv_p->dd_p->serial_response)
02985 pdv_serial_read(pdv_p, cmdstr, 63);
02986 }
02987 }
02988
02989 else if ((strncasecmp(dd_p->camera_class, "Hamamatsu", 9) == 0)
02990 && ((strncasecmp(dd_p->camera_model, "C8484", 5) == 0)
02991 || (strncasecmp(dd_p->camera_model, "8484", 4) == 0)))
02992 {
02993 ret = pdv_set_gain_hc8484(pdv_p, value);
02994 }
02995
02996 else if ((dd_p->camera_shutter_timing == SPECINST_SERIAL)
02997 || (dd_p->camera_shutter_speed == SPECINST_SERIAL))
02998 {
02999 ret = pdv_set_gain_specinst(pdv_p, value);
03000 }
03001 else if (dd_p->camera_shutter_timing == TOSHIBA_SERIAL)
03002 {
03003 ret = pdv_set_gain_toshiba(pdv_p, value);
03004 }
03005 else if (dd_p->camera_shutter_timing == COHU_SERIAL)
03006 {
03007 ret = pdv_set_gain_cohu(pdv_p, value);
03008 }
03009 else if (dd_p->set_gain == SMD_SERIAL)
03010 {
03011 ret = pdv_set_gain_smd(pdv_p, value);
03012 }
03013 else if ((strncasecmp(dd_p->camera_class, "Adimec", 6) == 0))
03014 {
03015 ret = pdv_set_gain_adimec(pdv_p, value);
03016 }
03017
03018 else if ((strncasecmp(dd_p->camera_class, "PULNiX", 6) == 0)
03019 && ((strncasecmp(dd_p->camera_model, "TM-6710", 7) == 0)
03020 || (strncasecmp(dd_p->camera_model, "TM-1020", 7) == 0)))
03021 {
03022 ret = pdv_set_gain_ptm6710_1020(pdv_p, value);
03023 }
03024
03025 else if ((dd_p->set_gain == AIA_MC4)
03026 && (dd_p->xilinx_rev >= 1 && dd_p->xilinx_rev <= 32))
03027 {
03028 u_int util2 = edt_reg_read(pdv_p, PDV_UTIL2);
03029 u_int mcl = edt_reg_read(pdv_p, PDV_MODE_CNTL);
03030
03031 edt_reg_write(pdv_p, PDV_UTIL2, util2 & ~PDV_MC4);
03032 edt_reg_write(pdv_p, PDV_MODE_CNTL, dd_p->gain);
03033 edt_reg_write(pdv_p, PDV_UTIL2, util2 | PDV_MC4);
03034 edt_reg_write(pdv_p, PDV_MODE_CNTL, mcl);
03035 }
03036
03037 edt_msg(DBG2, "pdv_set_gain returning %d\n", ret);
03038 return (ret);
03039 }
03040
03044 static int
03045 pdv_set_gain_smd(PdvDev * pdv_p, int value)
03046 {
03047 char buf[128];
03048 char smd_config;
03049 int smd_reg1;
03050 int ret = 0;
03051
03052 if (Smd_type == NOT_SET)
03053 {
03054 Smd_type = smd_read_reg(pdv_p, SMD_READ_CAMTYPE);
03055 if ((Smd_type & 0xfff) == 0xfff)
03056
03057 Smd_type = smd_read_reg(pdv_p, SMD_READ_CAMTYPE);
03058 }
03059
03060 switch (Smd_type)
03061 {
03062 case SMD_TYPE_4M4:
03063 buf[0] = (char) SMD_4M4_READ_R1;
03064 pdv_serial_binary_command(pdv_p, buf, 1);
03065 pdv_serial_wait(pdv_p, pdv_p->dd_p->serial_timeout,
03066 pdv_p->dd_p->serial_respcnt);
03067 if (pdv_serial_read(pdv_p, buf, 63) == 1)
03068 {
03069 smd_config = buf[0];
03070
03071 buf[0] = (char) SMD_4M4_WRITE_R1;
03072 pdv_serial_binary_command(pdv_p, buf, 1);
03073
03074 if (value == 0)
03075 smd_config &= ~SMD_4M4_R1_GAIN;
03076 else
03077 smd_config |= SMD_4M4_R1_GAIN;
03078 buf[0] = smd_config;
03079 pdv_serial_binary_command(pdv_p, buf, 1);
03080
03081 pdv_serial_wait(pdv_p, 100, 64);
03082 }
03083 else
03084 ret = -1;
03085 break;
03086
03087 case SMD_TYPE_1M30P:
03088 buf[0] = (u_char) SMD_1M30P_REG_W_LS_GAIN;
03089 buf[1] = value & 0xff;
03090 pdv_serial_binary_command(pdv_p, (char *) buf, 2);
03091
03092 buf[0] = (u_char) SMD_1M30P_REG_W_MS_GAIN;
03093 buf[1] = (value & 0xff00) >> 8;
03094 pdv_serial_binary_command(pdv_p, (char *) buf, 2);
03095
03096
03097 pdv_serial_wait(pdv_p, 100, 64);
03098 break;
03099
03100 case SMD_TYPE_1M15P:
03101 case SMD_TYPE_6M3P:
03102 if ((smd_reg1 = smd_read_reg(pdv_p, SMD_1M15P_READ_R1)) == -1)
03103 {
03104 edt_msg(PDVWARN, "libpdv: no response from SMD R1 reg read\n");
03105 return -1;
03106 }
03107
03108 buf[0] = (u_char) SMD_1M15P_WRITE_R1;
03109
03110
03111
03112
03113 if (value == 0)
03114 buf[1] = smd_reg1 &~ SMD_1M15P_R1_GAIN;
03115 else if (value == 1)
03116 buf[1] = smd_reg1 | SMD_1M15P_R1_GAIN;
03117 else return -1;
03118
03119 pdv_serial_binary_command(pdv_p, (char *) buf, 2);
03120 pdv_p->dd_p->gain = value;
03121
03122
03123 pdv_serial_wait(pdv_p, 100, 64);
03124 break;
03125 }
03126
03127 return ret;
03128 }
03129
03138 int
03139 pdv_set_gain_ch(PdvDev * pdv_p, int value, int chan)
03140 {
03141 int ret = -1;
03142
03143
03144 edt_msg(DBG2, "pdv_set_gain_ch(%d, [%c]) ret %d\n",
03145 value, (chan == 1) ? 'A' : (chan == 2) ? 'B' : '?', ret);
03146 return (ret);
03147 }
03148
03166 int
03167 pdv_set_blacklevel(PdvDev * pdv_p, int value)
03168 {
03169 Dependent *dd_p = pdv_p->dd_p;
03170 int ret;
03171
03172 edt_msg(DBG2, "pdv_set_blacklevel(%d)\n", value);
03173
03174 dd_p->level = value;
03175 ret = edt_set_dependent(pdv_p, dd_p);
03176
03177 if (dd_p->set_offset == SMD_SERIAL)
03178 ret = pdv_set_blacklevel_smd(pdv_p, value);
03179
03180 else if (dd_p->camera_shutter_timing == COHU_SERIAL)
03181 {
03182 ret = pdv_set_blacklevel_cohu(pdv_p, value);
03183 }
03184
03185 else if ((strncasecmp(dd_p->camera_class, "Adimec", 6) == 0))
03186 {
03187 ret = pdv_set_blacklevel_adimec(pdv_p, value);
03188 }
03189
03190 else if ((strlen(dd_p->serial_offset) > 0) && (dd_p->serial_format == SERIAL_BINARY))
03191 {
03192 send_serial_binary_cmd(pdv_p, dd_p->serial_offset, value);
03193 }
03194
03195 else if (dd_p->serial_format == SERIAL_ASCII)
03196 {
03197 char cmdstr[64] = {'\0'};
03198 int n = check_valid_formatstr(dd_p->serial_offset);
03199
03200 if (n == 0)
03201 {
03202 if (dd_p->serial_offset[0])
03203 sprintf(cmdstr, "%s %d", dd_p->serial_offset, value);
03204 }
03205 else if ((n > 0) && (n < 5))
03206 sprintf(cmdstr, dd_p->serial_offset, value, value, value, value);
03207
03208 if (cmdstr[0])
03209 {
03210 ret = pdv_serial_command_flagged(pdv_p, cmdstr, SCFLAG_NORESP);
03211
03212 pdv_serial_wait(pdv_p, pdv_p->dd_p->serial_timeout, 64);
03213 if (*pdv_p->dd_p->serial_response)
03214 pdv_serial_read(pdv_p, cmdstr, 63);
03215 }
03216 }
03217
03218 edt_msg(DBG2, "pdv_set_blacklevel() %d\n", ret);
03219 return (ret);
03220 }
03221
03222 static int
03223 pdv_set_blacklevel_smd(PdvDev * pdv_p, int value)
03224 {
03225 char buf[128];
03226 int ret = 0;
03227 int tmpval = value & 0xfff;
03228 int smd_reg2, smd_reg3;
03229
03230 if (Smd_type == NOT_SET)
03231 {
03232 Smd_type = smd_read_reg(pdv_p, SMD_READ_CAMTYPE);
03233 if ((Smd_type & 0xfff) == 0xfff)
03234
03235 Smd_type = smd_read_reg(pdv_p, SMD_READ_CAMTYPE);
03236 }
03237
03238 switch (Smd_type)
03239 {
03240 case SMD_TYPE_4M4:
03241 case SMD_TYPE_BT25:
03242 break;
03243
03244 case SMD_TYPE_1M30P:
03245 buf[0] = (u_char) SMD_1M30P_REG_W_LS_OFFSET;
03246 buf[1] = value & 0xff;
03247 pdv_serial_binary_command(pdv_p, (char *) buf, 2);
03248
03249 buf[0] = (u_char) SMD_1M30P_REG_W_MS_OFFSET;
03250 buf[1] = (value & 0xff00) >> 8;
03251 pdv_serial_binary_command(pdv_p, (char *) buf, 2);
03252
03253
03254 pdv_serial_wait(pdv_p, 100, 64);
03255 break;
03256
03257 case SMD_TYPE_1M15P:
03258 if ((smd_reg3 = smd_read_reg(pdv_p, SMD_1M15P_READ_R3)) == -1)
03259 {
03260 edt_msg(PDVWARN, "libpdv: no response from Dalstar R3 reg read\n");
03261 ret = -1;
03262 }
03263
03264 smd_reg2 = tmpval >> 4;
03265 smd_reg3 = (smd_reg3 & ~0x0f) | (tmpval & 0x0f);
03266
03267
03268 buf[0] = (u_char) SMD_1M15P_WRITE_R3;
03269 buf[1] = (u_char) smd_reg3;
03270 pdv_serial_binary_command(pdv_p, (char *) buf, 2);
03271
03272
03273 buf[0] = (u_char) SMD_1M15P_WRITE_R2;
03274 buf[1] = (u_char) smd_reg2;
03275 pdv_serial_binary_command(pdv_p, (char *) buf, 2);
03276
03277
03278 pdv_serial_wait(pdv_p, 100, 64);
03279 break;
03280
03281 default:
03282 ret = -1;
03283 }
03284
03285 return ret;
03286 }
03287
03296 int
03297 pdv_set_aperture(PdvDev * pdv_p, int value)
03298 {
03299 edt_msg(PDVWARN, "pdv_set_aperture is OBSOLETE\n");
03300 return (-1);
03301 }
03302
03344 int
03345 pdv_set_binning(PdvDev * pdv_p, int xval, int yval)
03346 {
03347 int ret = -1;
03348 int newvskip, newhskip, newwidth, newheight;
03349 Dependent *dd_p = pdv_p->dd_p;
03350
03351 if (((xval != 1) && (xval % 2)) || ((yval != 1) && (yval % 2)))
03352 {
03353 edt_msg(PDVWARN, "pdv_set_binning(%d, %d) -- invalid value\n", xval, yval);
03354 return -1;
03355 }
03356
03357 edt_msg(DBG2, "pdv_set_binning(%d, %d)\n", xval, yval);
03358
03359 if (strcmp(dd_p->serial_binning, "BIN") == 0)
03360 {
03361 ret = pdv_set_binning_dvc(pdv_p, xval, yval);
03362 }
03363 else if (strcmp(dd_p->serial_binning, "B=") == 0)
03364 {
03365 ret = pdv_set_binning_generic(pdv_p, xval - 1);
03366 }
03367 else if (*dd_p->serial_binning)
03368 {
03369
03370 ret = pdv_set_binning_generic(pdv_p, xval);
03371 }
03372 else
03373 return -1;
03374
03375 if (ret)
03376 return ret;
03377
03378 if (dd_p->binx < 1)
03379 dd_p->binx = 1;
03380 if (dd_p->biny < 1)
03381 dd_p->biny = 1;
03382
03383 newwidth = (((pdv_get_width(pdv_p) * dd_p->binx) / xval) / 4) * 4;
03384 newheight = (((pdv_get_height(pdv_p) * dd_p->biny) / yval)) ;
03385
03386 if (dd_p->roi_enabled)
03387 {
03388 newhskip = (dd_p->hskip * dd_p->binx) / xval;
03389 newvskip = (dd_p->vskip * dd_p->biny) / yval;
03390 ret = pdv_set_roi(pdv_p, newhskip, newwidth, newvskip, newheight);
03391 }
03392
03393 if (!ret)
03394 {
03395 dd_p->binx = xval;
03396 dd_p->biny = yval;
03397 }
03398
03399 return (ret);
03400 }
03401
03407 static int
03408 pdv_set_binning_generic(PdvDev * pdv_p, int value)
03409 {
03410 char cmdstr[64];
03411 Dependent *dd_p = pdv_p->dd_p;
03412
03413 if (dd_p->serial_binning[strlen(dd_p->serial_binning) - 1] == '=')
03414 sprintf(cmdstr, "%s%d", dd_p->serial_binning, value);
03415 else
03416 sprintf(cmdstr, "%s %d", dd_p->serial_binning, value);
03417 pdv_serial_command_flagged(pdv_p, cmdstr, SCFLAG_NORESP);
03418
03419 return (0);
03420 }
03421
03422
03435 int
03436 pdv_get_exposure(PdvDev * pdv_p)
03437 {
03438 edt_msg(DBG2, "pdv_get_exposure() %d\n", pdv_p->dd_p->shutter_speed);
03439
03440 return (pdv_p->dd_p->shutter_speed);
03441 }
03442
03443 void
03444 pdv_set_defaults(PdvDev * pdv_p)
03445 {
03446 Dependent *dd_p = pdv_p->dd_p;
03447
03448 if (dd_p->default_shutter_speed != NOT_SET)
03449 pdv_set_exposure(pdv_p, dd_p->default_shutter_speed);
03450 if (dd_p->default_gain != NOT_SET)
03451 pdv_set_gain(pdv_p, dd_p->default_gain);
03452 if (dd_p->default_offset != NOT_SET)
03453 pdv_set_blacklevel(pdv_p, dd_p->default_offset);
03454 }
03455
03467 int
03468 pdv_read_response(PdvDev * pdv_p, char *buf)
03469 {
03470 int len;
03471
03472
03473
03474
03475 len = pdv_serial_wait(pdv_p, pdv_p->dd_p->serial_timeout, 2048);
03476 if (len)
03477 pdv_serial_read(pdv_p, buf, len);
03478 return len;
03479 }
03480
03481
03495 int
03496 pdv_get_gain(PdvDev * pdv_p)
03497 {
03498 edt_msg(DBG2, "pdv_get_gain() %d\n", pdv_p->dd_p->gain);
03499
03500 return (pdv_p->dd_p->gain);
03501 }
03502
03503
03513 int
03514 pdv_get_blacklevel(PdvDev * pdv_p)
03515 {
03516 edt_msg(DBG2, "pdv_get_blacklevel() %d\n", pdv_p->dd_p->level);
03517
03518 return (pdv_p->dd_p->level);
03519 }
03520
03529 int
03530 pdv_get_aperture(PdvDev * pdv_p)
03531 {
03532 edt_msg(PDVWARN, "pdv_get_aperture is OBSOLETE\n");
03533 return (-1);
03534 }
03535
03546 void
03547 pdv_invert(PdvDev * pdv_p, int val)
03548 {
03549 u_int data_path;
03550
03551
03552 data_path = pdv_p->dd_p->datapath_reg;
03553
03554 edt_msg(DBG2, "pdv_invert(%d)\n", val);
03555
03556 if (val)
03557 data_path |= PDV_INVERT;
03558 else
03559 data_path &= ~PDV_INVERT;
03560
03561 edt_reg_write(pdv_p, PDV_DATA_PATH, data_path);
03562 pdv_p->dd_p->datapath_reg = data_path;
03563 }
03564
03574 int
03575 pdv_get_invert(PdvDev * pdv_p)
03576 {
03577 u_int data_path;
03578
03579 return (int)((edt_reg_read(pdv_p, PDV_DATA_PATH) & PDV_INVERT) != 0);
03580 }
03581
03582
03596 void
03597 pdv_set_firstpixel_counter(PdvDev * pdv_p, int ena)
03598 {
03599 if (pdv_p->devid >= PE8DVCL_ID)
03600 {
03601 u_int reg = edt_reg_read(pdv_p, PDV_CL_CFG2);
03602 if (ena)
03603 edt_reg_write(pdv_p, PDV_CL_CFG2, reg | PDV_CL_CFG2_PE8_FRMTAG2);
03604 else edt_reg_write(pdv_p, PDV_CL_CFG2, reg & ~PDV_CL_CFG2_PE8_FRMTAG2);
03605 }
03606 }
03607
03619 int
03620 pdv_get_firstpixel_counter(PdvDev * pdv_p)
03621 {
03622 if (pdv_p->devid >= PE8DVCL_ID)
03623 {
03624 int reg = edt_reg_read(pdv_p, PDV_CL_CFG2);
03625
03626 return (int)((edt_reg_read(pdv_p, PDV_CL_CFG2) & PDV_CL_CFG2_PE8_FRMTAG2) != 0);
03627 }
03628
03629 return 0;
03630 }
03631
03632
03638 u_short
03639 pdv_get_interlaced(PdvDev * pdv_p)
03640
03641 {
03642 edt_msg(DBG2, "pdv_get_interlaced() %u\n", pdv_p->dd_p->interlace);
03643
03644 return (pdv_p->dd_p->interlace);
03645 }
03646
03669 int
03670 pdv_force_single(PdvDev * pdv_p)
03671 {
03672 return pdv_p->dd_p->force_single;
03673 }
03674
03682 int
03683 pdv_variable_size(PdvDev * pdv_p)
03684 {
03685 return pdv_p->dd_p->variable_size;
03686 }
03687
03688
03689
03709 int
03710 pdv_serial_read_nullterm(PdvDev * pdv_p, char *buf, int size, int nullterm)
03711 {
03712 #define PKT_OVERHEAD 2
03713 #define PKT_SIZE_MAX 15
03714
03715 int bytesReturned;
03716 Dependent *dd_p;
03717
03718 if (pdv_p == NULL || pdv_p->dd_p == NULL)
03719 return 0;
03720
03721 pdv_serial_check_enabled(pdv_p);
03722
03723 dd_p = pdv_p->dd_p;
03724
03725 if (buf == NULL || pdv_p == NULL || size == 0)
03726 return (-1);
03727
03728 bytesReturned = edt_get_msg(pdv_p, buf, size);
03729 assert(bytesReturned <= size);
03730
03731 if (nullterm)
03732 buf[bytesReturned] = 0;
03733
03734 if (Pdv_debug)
03735 {
03736 int i, num = bytesReturned;
03737 int is_ascii = 1;
03738
03739 if (num > 32)
03740 num = 32;
03741
03742 for (i=0;i<num; i++)
03743 {
03744 if (!isascii(buf[i]))
03745 is_ascii = 0;
03746 }
03747 edt_msg(DBG2, "pdv_serial_read(<");
03748 for (i = 0; i < num; i++)
03749 {
03750 if (is_ascii)
03751 edt_msg(DBG2, "%c", (char) buf[i]);
03752 else edt_msg(DBG2, "%02x%s", (u_char) buf[i], i < num-1?", ":"");
03753 }
03754 edt_msg(DBG2, ">, %d)\n", size);
03755 }
03756 return bytesReturned;
03757 }
03758
03790 int
03791 pdv_serial_read(PdvDev * pdv_p, char *buf, int count)
03792 {
03793
03794 return pdv_serial_read_nullterm(pdv_p,buf,count,TRUE);
03795 }
03796
03803 int
03804 pdv_send_msg(PdvDev *ed, int chan, const char *buf, int size)
03805 {
03806 int i, ret = 0;
03807 int pause = ed->dd_p->pause_for_serial;
03808 char bbuf[32];
03809
03810 pdv_serial_check_enabled(ed);
03811
03812
03813 if (pause)
03814 {
03815 for (i=0; i<size; i++)
03816 {
03817 bbuf[0] = buf[i];
03818 edt_msleep(ed->dd_p->pause_for_serial);
03819 if ((ret = edt_send_msg(ed, chan, bbuf, 1)) != 0)
03820 return ret;
03821 }
03822 return ret;
03823 }
03824 else return edt_send_msg(ed, chan, buf, size);
03825 }
03826
03842 int
03843 pdv_serial_write_single_block(PdvDev * pdv_p, const char *buf, int size)
03844 {
03845 int ret;
03846 Dependent *dd_p;
03847
03848 if (size == 0)
03849 return (-1);
03850
03851 if (Pdv_debug)
03852 {
03853 int i, num = size;
03854
03855 if (num > 16)
03856 num = 16;
03857 edt_msg(DBG2, "pdv_serial_write_single_block(<");
03858 for (i = 0; i < num; i++)
03859 {
03860 edt_msg(DBG2, "%02x", (u_char) buf[i]);
03861 if (i + 1 < num)
03862 edt_msg(DBG2, ", ");
03863 else
03864 break;
03865 }
03866 edt_msg(DBG2, ">, %d)\n", size);
03867 }
03868
03869 if (buf == NULL || pdv_p == NULL || pdv_p->dd_p == NULL)
03870 return (-1);
03871 dd_p = pdv_p->dd_p;
03872
03873 ret = pdv_send_msg(pdv_p, pdv_p->channel_no, buf, size);
03874 return (ret);
03875 }
03876
03885 int
03886 pdv_serial_write_available(PdvDev *pdv_p)
03887
03888 {
03889
03890 int avail;
03891
03892 edt_ioctl(pdv_p, EDTG_SERIAL_WRITE_AVAIL, &avail);
03893
03894 return avail;
03895
03896 }
03897
03898 static int pdv_serial_block_size = 1024;
03899
03905 void pdv_set_serial_block_size(int newsize)
03906 {
03907 pdv_serial_block_size = newsize;
03908 }
03909
03916 int
03917 pdv_get_serial_block_size()
03918 {
03919 return pdv_serial_block_size;
03920 }
03921
03926 #define SERIAL_ENABLED_FLAGS (PDV_EN_TX | PDV_EN_RX | PDV_EN_RX_INT | PDV_EN_DEV_INT)
03927
03928 int
03929 pdv_serial_read_enable(PdvDev *pdv_p)
03930
03931 {
03932
03933 edt_reg_or(pdv_p, PDV_SERIAL_DATA_CNTL, SERIAL_ENABLED_FLAGS);
03934
03935 edt_set_remote_intr(pdv_p, TRUE);
03936
03937 pdv_p->is_serial_enabled = 1;
03938
03939 return 0;
03940 }
03941
03942
03943 int
03944 pdv_serial_read_disable(PdvDev *pdv_p)
03945
03946 {
03947 edt_set_remote_intr(pdv_p, FALSE);
03948 edt_reg_and(pdv_p, PDV_SERIAL_DATA_CNTL, ~SERIAL_ENABLED_FLAGS);
03949 pdv_p->is_serial_enabled = 0;
03950
03951 return 0;
03952 }
03953
03954 int
03955 pdv_serial_check_enabled(PdvDev *pdv_p)
03956
03957 {
03958 if (!pdv_p->is_serial_enabled)
03959 return pdv_serial_read_enable(pdv_p);
03960
03961 return 0;
03962 }
03963
03964
03965
03982 int
03983 pdv_serial_write(PdvDev *pdv_p, const char *buf, int size)
03984
03985 {
03986 int avail;
03987 int left = size;
03988 int ret = 0;
03989 int offset = 0;
03990 int speed = pdv_get_baud(pdv_p);
03991 int sleepval;
03992 int chunk = pdv_serial_block_size;
03993
03994 pdv_serial_check_enabled(pdv_p);
03995
03996 if (speed != 0)
03997 sleepval = speed/10;
03998 else
03999 sleepval = 10;
04000
04001 sleepval = (chunk * 1000) / sleepval;
04002
04003 avail = pdv_serial_write_available(pdv_p);
04004 if (avail > size)
04005 {
04006 return pdv_serial_write_single_block(pdv_p, buf, size);
04007 }
04008 else
04009 {
04010 left -= avail;
04011 offset += avail;
04012
04013 #ifdef DBG_SERIAL_IO
04014 printf("Writing %d chars\n", avail);
04015 #endif
04016
04017 ret = pdv_serial_write_single_block(pdv_p, buf, avail);
04018
04019 if (ret != 0)
04020 return ret;
04021 while (left > 0)
04022 {
04023 edt_msleep(sleepval);
04024 avail = pdv_serial_write_available(pdv_p);
04025 if (avail > 0)
04026 {
04027 if ( avail > left)
04028 {
04029 avail = left;
04030 left = 0;
04031 }
04032 else
04033 {
04034 left -= avail;
04035 }
04036
04037 #ifdef DBG_SERIAL_IO
04038 printf("Writing %d chars\n", avail);
04039 #endif
04040 ret = pdv_serial_write_single_block(pdv_p, buf+offset, avail);
04041 if (ret != 0)
04042 return ret;
04043 offset += avail;
04044
04045 }
04046 }
04047 }
04048 return 0;
04049 }
04050
04067 int
04068 pdv_serial_read_blocking(PdvDev *pdv_p, char *buf, int size)
04069
04070 {
04071 int left = size;
04072 int ret = 0;
04073 int offset = 0;
04074 int total = 0;
04075
04076
04077 int avail = 1024;
04078 int speed = pdv_get_baud(pdv_p);
04079 int sleepval;
04080 int chunk = pdv_serial_block_size;
04081
04082
04083 if (speed != 0)
04084 sleepval = speed/10;
04085 else
04086 sleepval = 10;
04087
04088 sleepval = (chunk * 1000) / sleepval;
04089
04090
04091 while (left > 0)
04092 {
04093 avail = pdv_serial_wait(pdv_p, sleepval, chunk);
04094 if (avail)
04095 {
04096 if ( avail > left)
04097 {
04098 avail = left;
04099 left = 0;
04100 }
04101 else
04102 {
04103 left -= avail;
04104 }
04105
04106 #ifdef DBG_SERIAL_IO
04107 printf("Reading %d chars total = %d\n", avail, offset + avail);
04108 #endif
04109 ret = pdv_serial_read(pdv_p, buf+offset, avail);
04110 offset += avail;
04111
04112 total += ret;
04113
04114 }
04115
04116
04117 }
04118
04119
04120
04121 return total;
04122
04123 }
04124
04125
04169 int
04170 pdv_serial_command(PdvDev * pdv_p, const char *cmd)
04171 {
04172
04173
04174
04175
04176
04177
04178
04179
04180
04181
04182
04183 return pdv_serial_command_flagged(pdv_p, cmd, 0);
04184 }
04185
04202 int
04203 pdv_serial_command_flagged(PdvDev * pdv_p, const char *cmd, u_int flag)
04204 {
04205 char *buf;
04206 int ret;
04207 int i;
04208 int len=0;
04209 int bufsize=8;
04210 const char *p = cmd;
04211
04212 if (pdv_p == NULL || pdv_p->dd_p == NULL)
04213 return -1;
04214
04215
04216 while (*p++)
04217 ++bufsize;
04218 buf = (char *)malloc(bufsize+16);
04219
04220
04221
04222
04223 if (*pdv_p->dd_p->serial_prefix)
04224 {
04225 strcpy(&(buf[len]), pdv_p->dd_p->serial_prefix);
04226 len += (int)strlen(pdv_p->dd_p->serial_prefix);
04227 }
04228
04229
04230 if (pdv_p->dd_p->serial_format == SERIAL_PULNIX_1010)
04231 {
04232 buf[len++] = 0x02;
04233 for (i = 0; i < bufsize; i++)
04234 if (cmd[i] == '\r' || cmd[i] == '\n' || cmd[i] == 0)
04235 break;
04236 else
04237 buf[len++] = cmd[i];
04238 buf[len++] = 0x03;
04239 }
04240 else
04241 {
04242
04243
04244 for (i = 0; i < bufsize; i++)
04245 {
04246 if (cmd[i] == '\r' || cmd[i] == '\n' || cmd[i] == 0)
04247 break;
04248 else
04249 buf[len++] = cmd[i];
04250 }
04251
04252 sprintf(&(buf[len]), "%s", pdv_serial_term(pdv_p));
04253 len += (int)strlen(pdv_serial_term(pdv_p));
04254 }
04255
04256 if (Pdv_debug)
04257 debug_print_serial_command(buf);
04258 ret = pdv_serial_write(pdv_p, buf, len);
04259
04260 free(buf);
04261 return (ret);
04262 }
04263
04272 char *
04273 pdv_serial_term(PdvDev * pdv_p)
04274 {
04275 return pdv_p->dd_p->serial_term;
04276 }
04277
04286 char *
04287 pdv_serial_prefix(PdvDev * pdv_p)
04288 {
04289 return pdv_p->dd_p->serial_prefix;
04290 }
04291
04306 void
04307 pdv_set_serial_delimiters(PdvDev *pdv_p, char *prefix, char *term)
04308
04309 {
04310 if (prefix)
04311 strncpy(pdv_p->dd_p->serial_prefix,prefix, sizeof(pdv_p->dd_p->serial_prefix)-1);
04312 else
04313 pdv_p->dd_p->serial_prefix[0] = 0;
04314
04315 if (term)
04316 strncpy(pdv_p->dd_p->serial_term,term, sizeof(pdv_p->dd_p->serial_term)-1);
04317 else
04318 pdv_p->dd_p->serial_term[0] = 0;
04319
04320 edt_set_dependent(pdv_p,pdv_p->dd_p);
04321 }
04322
04323
04324
04325 static void
04326 debug_print_serial_command(char *cmd)
04327 {
04328 char tmpbuf[256];
04329 char *p = cmd;
04330 char *pp = tmpbuf;
04331 int len=0;
04332
04333 while (*p != '\0')
04334 {
04335 if (*p == '\r')
04336 {
04337 sprintf(pp, "\\r");
04338 pp += 2;
04339 len += 2;
04340 ++p;
04341 }
04342 else if (*p == '\n')
04343 {
04344 sprintf(pp, "\\n");
04345 pp += 2;
04346 len += 2;
04347 ++p;
04348 }
04349 else if (!isprint(*p))
04350 {
04351 sprintf(pp, "<%02x>", (*p) & 0xff);
04352 pp += 4;
04353 len += 4;
04354 ++p;
04355 }
04356 else
04357 {
04358 *(pp++) = *(p++);
04359 ++len ;
04360 }
04361 if (len > 250)
04362 break;
04363 }
04364 *pp = '\0';
04365 edt_msg(DBG2, "pdv_serial_command(\"%s\")\n", tmpbuf);
04366 }
04367
04398 int
04399 pdv_serial_binary_command(PdvDev * pdv_p, const char *cmd, int len)
04400 {
04401 return pdv_serial_binary_command_flagged(pdv_p, cmd, len, 0);
04402 }
04403
04404
04411 int
04412 pdv_send_basler_frame(PdvDev * pdv_p, u_char *cmd, int len)
04413 {
04414 int i;
04415 u_char frame[128];
04416 u_char *p = frame;
04417 u_char bcc = 0;
04418
04419 *p++ = 0x02;
04420 for (i=0; i<len; i++)
04421 {
04422 bcc ^= cmd[i];
04423 *p++ = cmd[i];
04424 }
04425 *p++ = bcc;
04426 *p++ = 0x03;
04427
04428 return pdv_serial_binary_command_flagged(pdv_p, (char *)frame, len+3, 0);
04429 }
04430
04437 int
04438 pdv_read_basler_frame(PdvDev * pdv_p, u_char *frame, int len)
04439 {
04440 int n, nn;
04441 char tmpbuf[128];
04442 char *p;
04443
04444 n = pdv_serial_wait(pdv_p, 500, len);
04445 if (n < 1)
04446 return 0;
04447
04448 nn = pdv_serial_read(pdv_p, tmpbuf, n);
04449
04450 if (tmpbuf[0] == 0x06)
04451 {
04452 frame[0] = 0x06;
04453 return 1;
04454 }
04455
04456 if (tmpbuf[0] == 0x15)
04457 {
04458 frame[0] = 0x06;
04459 return 1;
04460 }
04461
04462 if (tmpbuf[0] == 0x02)
04463 {
04464 p = &tmpbuf[nn];
04465 n = pdv_serial_wait(pdv_p, 50, len);
04466 pdv_serial_read(pdv_p, p, n);
04467
04468 }
04469 return n;
04470 }
04471
04487 int
04488 pdv_send_duncan_frame(PdvDev * pdv_p, u_char *cmdbuf, int size)
04489 {
04490 int i;
04491 u_char frame[128];
04492 u_char *p = frame;
04493
04494 *p++ = 0x02;
04495 for (i=0; i<size; i++)
04496 *p++ = cmdbuf[i];
04497
04498 CheckSumMessage(frame);
04499
04500 return pdv_serial_binary_command_flagged(pdv_p, (char *)frame, size+2, 0);
04501 }
04502
04503 static void
04504 CheckSumMessage(unsigned char *msg)
04505 {
04506 unsigned short length;
04507 unsigned char csum = 0;
04508
04509 msg++;
04510 length = *msg++;
04511 length += *msg++ << 8;
04512 if (length > 0)
04513 {
04514 for (; length > 0; length--)
04515 csum += *msg++;
04516 *msg = -csum;
04517 }
04518 }
04519
04520
04533 int
04534 pdv_read_duncan_frame(PdvDev * pdv_p, u_char *frame)
04535 {
04536 int n, nn;
04537 u_short length;
04538
04539
04540 n = pdv_serial_wait(pdv_p, 500, 3);
04541 if (n < 3)
04542 return 0;
04543
04544 nn = pdv_serial_read(pdv_p, (char *)frame, 3);
04545
04546 length = (u_short)frame[1] + (u_short)(frame[2] << 8);
04547
04548 if (length)
04549 n = pdv_serial_wait(pdv_p, 1000, length+1);
04550
04551 if (n)
04552 pdv_serial_read(pdv_p, (char *)(&frame[3]), n);
04553
04554 return n+nn;
04555 }
04556
04580 int
04581 pdv_serial_binary_command_flagged(PdvDev * pdv_p, const char *cmd, int len, u_int flag)
04582 {
04583 char *buf;
04584 int ret;
04585 int i;
04586 int tmplen = 0;
04587
04588 edt_msg(DBG2, "pdv_serial_binary_command()\n");
04589
04590 if (pdv_p == NULL || pdv_p->dd_p == NULL)
04591 return -1;
04592
04593 if ((buf = (char *)malloc(len)) == NULL)
04594 return -1;
04595
04596
04597 for (i = 0; i < len; i++)
04598 {
04599 buf[tmplen++] = cmd[i];
04600 }
04601 ret = pdv_serial_write(pdv_p, buf, tmplen);
04602
04603 free(buf);
04604 return (ret);
04605 }
04606
04608
04637 int
04638 pdv_read(PdvDev * pdv_p, unsigned char *buf, unsigned long size)
04639 {
04640 Dependent *dd_p;
04641 unsigned long newsize;
04642 int readsize;
04643 unsigned char *tbuf;
04644 u_int fc;
04645 int last_timeouts;
04646
04647 if (pdv_p == NULL || pdv_p->dd_p == NULL)
04648 return 0;
04649
04650 edt_msg(DBG2, "pdv_read(%d)\n", size);
04651
04652 pdv_setup_dma(pdv_p);
04653
04654 last_timeouts = edt_timeouts(pdv_p);
04655
04656 if (pdv_p->dd_p->start_delay)
04657 edt_msleep(pdv_p->dd_p->start_delay);
04658
04659
04660 if (pdv_specinst_serial_triggered(pdv_p))
04661 {
04662 edt_msg(PDVWARN, "libpdv invalid combination: SPECINST_SERIAL/pdv_read/i/f trigger");
04663 edt_msg(PDVWARN, "should use pdv_start_image() or external trigger");
04664 }
04665
04666 if (pdv_p == NULL || pdv_p->dd_p == NULL)
04667 return -1;
04668
04669 dd_p = pdv_p->dd_p;
04670
04671 if (pdv_p->devid == DMY_ID)
04672 {
04673 pdv_dmy_data(buf, dd_p->width, dd_p->height, dd_p->depth);
04674 if (dd_p->markras)
04675 pdv_mark_ras(buf, dd_p->rascnt,
04676 dd_p->width, dd_p->height, dd_p->markrasx, dd_p->markrasy);
04677 if (dd_p->markbin)
04678 pdv_mark_bin(buf, dd_p->rascnt, dd_p->width, dd_p->height, 4, 0);
04679 if (dd_p->markbin || dd_p->markras) dd_p->rascnt++ ;
04680 printf("pdv_read rascnt %d\n",dd_p->rascnt) ;
04681 return (size);
04682 }
04683
04684 readsize = pdv_get_dmasize(pdv_p);
04685
04686 if (dd_p->swinterlace)
04687 pdv_alloc_tmpbuf(pdv_p);
04688
04689
04690
04691
04692 edt_startdma_reg(pdv_p, PDV_CMD, PDV_ENABLE_GRAB);
04693 if (edt_get_firstflush(pdv_p) != EDT_ACT_KBS)
04694 edt_set_firstflush(pdv_p, EDT_ACT_ONCE);
04695
04696
04697 if (dd_p->slop)
04698 {
04699 edt_msg(DBG2, "adjusting readsize %x by slop %x to %x\n",
04700 readsize, dd_p->slop, readsize - dd_p->slop);
04701 readsize -= dd_p->slop;
04702 }
04703
04704 if (dd_p->swinterlace)
04705 {
04706 if (pdv_process_inplace(pdv_p))
04707 tbuf = buf;
04708 else
04709 tbuf = pdv_p->tmpbuf;
04710
04711 newsize = edt_read(pdv_p, tbuf, readsize);
04712 dd_p->last_raw = tbuf;
04713 dd_p->last_image = buf;
04714 }
04715 else
04716 {
04717 tbuf = buf;
04718 newsize = edt_read(pdv_p, buf, readsize);
04719 dd_p->last_raw = buf;
04720 dd_p->last_image = buf;
04721 }
04722
04723 dd_p->rascnt = 1;
04724 if (dd_p->markras)
04725 pdv_mark_ras(buf, dd_p->rascnt++, dd_p->width, dd_p->height,
04726 dd_p->markrasx, dd_p->markrasy);
04727
04728 size = newsize;
04729
04730
04731
04732 edt_msg(DBG2, "swinterlace %d\n", dd_p->swinterlace);
04733
04734 pdv_deinterlace(pdv_p, dd_p, tbuf, buf);
04735
04736 if ((pdv_framesync_mode(pdv_p) == PDV_FRAMESYNC_EMULATE_TIMEOUT)
04737 && (pdv_check_framesync(pdv_p, buf, &fc) > 0)
04738 && (last_timeouts == edt_timeouts(pdv_p)))
04739 edt_do_timeout(pdv_p);
04740
04741 return (size);
04742 }
04743
04744
04763 unsigned char *
04764 pdv_image(PdvDev * pdv_p)
04765 {
04766 edt_msg(DBG2, "pdv_image()\n");
04767
04768 pdv_start_images(pdv_p, 1);
04769 return pdv_wait_images(pdv_p, 1);
04770 }
04771
04772
04783 unsigned char *
04784 pdv_image_raw(PdvDev * pdv_p)
04785 {
04786 edt_msg(DBG2, "pdv_image()\n");
04787
04788 pdv_start_images(pdv_p, 1);
04789 return pdv_wait_images_raw(pdv_p, 1);
04790 }
04791
04800 void
04801 pdv_start_image(PdvDev * pdv_p)
04802 {
04803 edt_msg(DBG2, "pdv_start_image()\n");
04804
04805 pdv_start_images(pdv_p, 1);
04806 }
04807
04808
04821 void
04822 pdv_start_images(PdvDev * pdv_p, int count)
04823 {
04824
04825 edt_msg(DBG2, "pdv_start_images(%d) %d\n", count, pdv_p->dd_p->started_continuous);
04826
04827 if (pdv_p->dd_p->start_delay)
04828 edt_msleep(pdv_p->dd_p->start_delay);
04829
04830
04831 if (pdv_p->ring_buffer_numbufs < 1)
04832 pdv_multibuf(pdv_p, 1);
04833
04834
04835
04836
04837
04838
04839
04840
04841 if (!pdv_p->dd_p->started_continuous)
04842 {
04843 pdv_setup_continuous(pdv_p);
04844 }
04845 if (pdv_force_single(pdv_p) && (count > 1))
04846 {
04847 edt_msg(PDVWARN,
04848 "pdv_start_images(): %d buffers requested; should only\n", count);
04849 edt_msg(PDVWARN,
04850 "start one at a time when 'force_single' is set in config file\n");
04851 count = 1;
04852 }
04853
04854
04855 edt_start_buffers(pdv_p, count);
04856
04857 if (pdv_specinst_serial_triggered(pdv_p))
04858 pdv_trigger_specinst(pdv_p);
04859 else if (strlen(pdv_p->dd_p->serial_trigger) > 0)
04860 pdv_serial_command(pdv_p, pdv_p->dd_p->serial_trigger);
04861 }
04862
04863
04905 unsigned char *
04906 pdv_wait_image(PdvDev * pdv_p)
04907 {
04908 edt_msg(DBG2, "pdv_wait_image()\n");
04909
04910 return pdv_wait_images(pdv_p, 1);
04911 }
04912
04944 unsigned char *
04945 pdv_wait_image_raw(PdvDev * pdv_p)
04946 {
04947 edt_msg(DBG2, "pdv_wait_image()\n");
04948
04949 return pdv_wait_images_raw(pdv_p, 1);
04950 }
04951
04952
04992 unsigned char *
04993 pdv_wait_image_timed(PdvDev * pdv_p, u_int * timep)
04994 {
04995 return pdv_wait_image_timed_raw(pdv_p, timep, FALSE);
04996 }
04997
05038 unsigned char *
05039 pdv_wait_image_timed_raw(PdvDev * pdv_p, u_int * timep, int doRaw)
05040 {
05041 u_char *ret;
05042
05043 edt_msg(DBG2, "pdv_wait_image()\n");
05044
05045 if (doRaw)
05046 ret = pdv_wait_images_raw(pdv_p, 1);
05047 else
05048 ret = pdv_wait_images(pdv_p, 1);
05049
05050 edt_get_timestamp(pdv_p, timep, pdv_p->donecount - 1);
05051 return (ret);
05052 }
05053
05099 unsigned char *
05100 pdv_wait_images_timed_raw(PdvDev * pdv_p, int count, u_int * timep, int doRaw)
05101 {
05102 u_char *ret;
05103
05104 edt_msg(DBG2, "pdv_wait_images_timed_raw(count=%d, doRaw=%d)\n", count, doRaw);
05105 if (doRaw)
05106 ret = pdv_wait_images_raw(pdv_p, count);
05107 else
05108 ret = pdv_wait_images(pdv_p, count);
05109
05110 edt_get_timestamp(pdv_p, timep, pdv_p->donecount - 1);
05111 return (ret);
05112 }
05113
05142 unsigned char *
05143 pdv_wait_images_timed(PdvDev * pdv_p, int count, u_int * timep)
05144 {
05145 return pdv_wait_images_timed_raw(pdv_p, count, timep, FALSE);
05146 }
05147
05152 unsigned char *
05153 pdv_last_image_timed_raw(PdvDev * pdv_p, u_int * timep, int doRaw)
05154 {
05155 return pdv_wait_last_image_timed_raw(pdv_p, timep, doRaw);
05156
05157 }
05158
05189 unsigned char *
05190 pdv_wait_last_image_timed_raw(PdvDev * pdv_p, u_int * timep, int doRaw)
05191 {
05192 u_char *ret;
05193 int donecount;
05194 int last_wait;
05195 int delta;
05196
05197 donecount = edt_done_count(pdv_p);
05198 last_wait = pdv_p->donecount;
05199
05200 edt_msg(DBG2, "pdv_wait_last_image_timed() last %d cur %d\n",
05201 last_wait, donecount);
05202
05203 delta = donecount - last_wait;
05204
05205 if (delta == 0)
05206 delta = 1;
05207
05208 if (doRaw)
05209 ret = pdv_wait_images_raw(pdv_p, delta);
05210 else
05211 ret = pdv_wait_images(pdv_p, delta);
05212
05213 edt_get_timestamp(pdv_p, timep, pdv_p->donecount - 1);
05214 return (ret);
05215 }
05216
05240 unsigned char *
05241 pdv_wait_last_image_timed(PdvDev * pdv_p, u_int * timep)
05242 {
05243 return pdv_wait_last_image_timed_raw(pdv_p, timep, FALSE);
05244 }
05245
05250 unsigned char *
05251 pdv_last_image_timed(PdvDev * pdv_p, u_int * timep)
05252 {
05253
05254 return pdv_last_image_timed_raw(pdv_p, timep, FALSE);
05255 }
05256
05277 unsigned char *
05278 pdv_wait_last_image_raw(PdvDev * pdv_p, int *nSkipped, int doRaw)
05279 {
05280 u_char *ret;
05281 int donecount;
05282 int last_wait;
05283 int delta;
05284
05285 donecount = edt_done_count(pdv_p);
05286 last_wait = pdv_p->donecount;
05287
05288 edt_msg(DBG2, "pdv_wait_last_image() last %d cur %d\n",
05289 last_wait, donecount);
05290
05291 delta = donecount - last_wait;
05292
05293 if (nSkipped)
05294 *nSkipped = (delta) ? delta - 1 : 0;
05295
05296 if (delta == 0)
05297 delta = 1;
05298
05299 if (doRaw)
05300 ret = pdv_wait_images_raw(pdv_p, delta);
05301 else
05302 ret = pdv_wait_images(pdv_p, delta);
05303
05304 return (ret);
05305 }
05306
05335 unsigned char *
05336 pdv_wait_last_image(PdvDev * pdv_p, int *nSkipped)
05337 {
05338 return pdv_wait_last_image_raw(pdv_p, nSkipped, FALSE);
05339 }
05340
05361 unsigned char *
05362 pdv_wait_next_image_raw(PdvDev * pdv_p, int *nSkipped, int doRaw)
05363 {
05364 u_char *ret;
05365 int donecount;
05366 int last_wait;
05367 int delta;
05368
05369 donecount = edt_done_count(pdv_p);
05370 last_wait = pdv_p->donecount;
05371
05372 edt_msg(DBG2, "pdv_wait_last_image() last %d cur %d\n",
05373 last_wait, donecount);
05374
05375 delta = donecount - last_wait;
05376
05377 if (*nSkipped)
05378 *nSkipped = (delta) ? delta - 1 : 0;
05379
05380
05381 if (delta == 0)
05382 delta = 1;
05383
05384 delta++;
05385
05386 if (doRaw)
05387 ret = pdv_wait_images_raw(pdv_p, delta);
05388 else
05389 ret = pdv_wait_images(pdv_p, delta);
05390
05391 return (ret);
05392 }
05393
05409 unsigned char *
05410 pdv_wait_next_image(PdvDev * pdv_p, int *nSkipped)
05411 {
05412
05413 return pdv_wait_next_image_raw(pdv_p, nSkipped, FALSE);
05414 }
05415
05416
05426 int
05427 pdv_in_continuous(PdvDev * pdv_p)
05428 {
05429 edt_msg(DBG2, "pdv_in_continuous() %x\n",
05430 pdv_p->dd_p->continuous);
05431 return pdv_p->dd_p->continuous;
05432 }
05433
05435
05436 void
05437 pdv_check(PdvDev * pdv_p)
05438 {
05439 int stat;
05440 int overrun;
05441
05442 stat = edt_reg_read(pdv_p, PDV_STAT);
05443 overrun = edt_ring_buffer_overrun(pdv_p);
05444 edt_msg(DBG2, "pdv_check() stat %x overrun %x\n",
05445 stat, overrun);
05446 if ((stat & PDV_OVERRUN) || overrun)
05447 {
05448 if (pdv_p->dd_p->continuous)
05449 pdv_stop_hardware_continuous(pdv_p);
05450
05451 pdv_flush_fifo(pdv_p);
05452
05453 pdv_multibuf(pdv_p, pdv_p->ring_buffer_numbufs);
05454
05455 if (pdv_p->dd_p->continuous)
05456 pdv_start_hardware_continuous(pdv_p);
05457 }
05458 }
05459
05460 void
05461 pdv_checkfrm(PdvDev * pdv_p, u_short * imagebuf, u_int imagesize, int verbose)
05462 {
05463 u_short *tmpp;
05464
05465 for (tmpp = (u_short *) imagebuf;
05466 tmpp < (u_short *) (&imagebuf[imagesize]); tmpp++)
05467 {
05468 if (*tmpp & 0xf000)
05469 {
05470 edt_msg(DBG2, "found start of image %x at %x %d\n",
05471 *tmpp >> 12,
05472 tmpp - (u_short *) imagebuf,
05473 tmpp - (u_short *) imagebuf);
05474 if (tmpp != imagebuf)
05475 {
05476 int curdone;
05477 int curtodo;
05478
05479 edt_reg_write(pdv_p, PDV_CMD, PDV_RESET_INTFC);
05480 pdv_flush_fifo(pdv_p);
05481 curdone = edt_done_count(pdv_p);
05482 curtodo = edt_get_todo(pdv_p);
05483 edt_msg(DBG2, "done %d todo %d\n", curdone, curtodo);
05484 {
05485 pdv_stop_continuous(pdv_p);
05486 edt_set_buffer(pdv_p, curdone);
05487 pdv_setup_continuous(pdv_p);
05488 pdv_start_images(pdv_p, pdv_p->ring_buffer_numbufs -
05489 (curtodo - curdone));
05490 }
05491 }
05492 break;
05493 }
05494 }
05495 }
05496
05497 u_char *
05498 pdv_get_interleave_data(PdvDev *pdv_p, u_char * buf, int bufnum)
05499
05500 {
05501 if (!pdv_process_inplace(pdv_p))
05502 {
05503 return pdv_p->output_buffers[bufnum];
05504 }
05505 else
05506 return buf;
05507 }
05508
05509
05536 unsigned char *
05537 pdv_wait_images_raw(PdvDev * pdv_p, int count)
05538 {
05539 u_char *buf;
05540 Dependent *dd_p;
05541 u_int fc;
05542 int last_timeouts;
05543
05544 edt_msg(DBG2, "pdv_wait_images_raw(%d)\n", count);
05545
05546 if (pdv_p == NULL || pdv_p->dd_p == NULL)
05547 return NULL;
05548
05549 dd_p = pdv_p->dd_p;
05550
05551 last_timeouts = edt_timeouts(pdv_p);
05552
05553 if (pdv_specinst_serial_triggered(pdv_p))
05554 pdv_posttrigger_specinst(pdv_p);
05555
05556 if (pdv_p->devid == DMY_ID)
05557 {
05558 u_char *buf;
05559 u_int *tmpp;
05560
05561 buf = edt_next_writebuf(pdv_p);
05562 tmpp = (u_int *) buf;
05563 if (*tmpp != 0xaabbccdd)
05564 {
05565 pdv_dmy_data(buf, dd_p->width, dd_p->height, dd_p->depth);
05566 }
05567 *tmpp = 0xaabbccdd;
05568 dd_p->last_raw = buf;
05569 dd_p->last_image = buf;
05570
05571 if (dd_p->markras)
05572 pdv_mark_ras(buf, dd_p->rascnt, dd_p->width, dd_p->height,
05573 dd_p->markrasx, dd_p->markrasy);
05574 if (dd_p->markbin)
05575 pdv_mark_bin(buf, dd_p->rascnt, dd_p->width, dd_p->height, 4, 0);
05576
05577 if (dd_p->markbin || dd_p->markras) dd_p->rascnt++ ;
05578 return (buf);
05579 }
05580
05581 buf = edt_wait_for_buffers(pdv_p, count);
05582
05583 dd_p->last_raw = buf;
05584 dd_p->last_image = buf;
05585
05586 if ((pdv_framesync_mode(pdv_p) == PDV_FRAMESYNC_EMULATE_TIMEOUT)
05587 && (pdv_check_framesync(pdv_p, buf, &fc) > 0)
05588 && (last_timeouts == edt_timeouts(pdv_p)))
05589 edt_do_timeout(pdv_p);
05590
05591 return buf;
05592 }
05593
05594
05640 u_char *
05641 pdv_wait_images(PdvDev *pdv_p, int count)
05642
05643 {
05644 u_char *buf;
05645 u_char *retval;
05646 Dependent *dd_p;
05647 u_int fc;
05648 int last_timeouts;
05649
05650 edt_msg(DBG2, "pdv_wait_images(%d)\n", count);
05651
05652 if (pdv_p == NULL || pdv_p->dd_p == NULL)
05653 return NULL;
05654
05655 dd_p = pdv_p->dd_p;
05656
05657 last_timeouts = edt_timeouts(pdv_p);
05658
05659 if (dd_p->swinterlace)
05660 {
05661 pdv_alloc_tmpbuf(pdv_p);
05662 }
05663
05664 buf = pdv_wait_images_raw(pdv_p, count);
05665
05666
05667 if (dd_p->swinterlace)
05668 {
05669
05670 if (!pdv_process_inplace(pdv_p))
05671 {
05672
05673 int buf_index = pdv_p->donecount % pdv_p->ring_buffer_numbufs;
05674
05675
05676 retval = pdv_p->output_buffers[buf_index];
05677
05678
05679 }
05680 else
05681 retval = buf;
05682
05683 pdv_deinterlace(pdv_p, dd_p, buf, retval);
05684
05685 dd_p->last_raw = buf;
05686 dd_p->last_image = retval;
05687 }
05688 else
05689 {
05690 retval = buf;
05691 dd_p->last_raw = buf;
05692 dd_p->last_image = buf;
05693 }
05694
05695
05696
05697 if (pdv_p->devid != DMY_ID)
05698 {
05699 if (dd_p->markras)
05700 pdv_mark_ras(buf, dd_p->rascnt, dd_p->width, dd_p->height,
05701 dd_p->markrasx, dd_p->markrasy);
05702 if (dd_p->markbin)
05703 pdv_mark_bin(buf, dd_p->rascnt, dd_p->width, dd_p->height, 4, 0);
05704
05705 if (dd_p->markbin || dd_p->markras) dd_p->rascnt++ ;
05706 }
05707
05708 #if 0
05709 if ((pdv_framesync_mode(pdv_p) == PDV_FRAMESYNC_EMULATE_TIMEOUT)
05710 && (pdv_check_framesync(pdv_p, buf, &fc) > 0)
05711 && (last_timeouts == edt_timeouts(pdv_p)))
05712 edt_do_timeout(pdv_p);
05713 #endif
05714
05715 return (retval);
05716 }
05717
05718 int
05719 pdv_slop(PdvDev * pdv_p)
05720 {
05721 return (pdv_p->dd_p->slop);
05722 }
05723
05724
05725 int
05726 pdv_set_slop(PdvDev * pdv_p, int slop)
05727 {
05728 edt_msg(DBG2, "pdv_set_slop()\n");
05729
05730 pdv_p->dd_p->slop = slop;
05731 return (0);
05732 }
05733
05734
05775 pdv_set_header_type(PdvDev *pdv_p, int header_type, int irig_slave, int irig_offset, int irig_raw)
05776 {
05777
05778 switch(header_type)
05779 {
05780 case HDR_TYPE_NONE:
05781 if (edt_has_irigb(pdv_p))
05782 {
05783 edt_reg_and(pdv_p, PDV_UTILITY, ~(PDV_ENFRMCNT|PDVCL_IRIG2));
05784 pdv_p->dd_p->header_position = HeaderNone;
05785 pdv_p->dd_p->header_size = 0;
05786 pdv_p->dd_p->header_dma = 0;
05787 pdv_p->dd_p->header_type = 0;
05788 }
05789 break;
05790 case HDR_TYPE_IRIG2:
05791 if (!edt_has_irigb(pdv_p))
05792 return -1;
05793
05794 edt_reg_and(pdv_p, PDV_UTILITY, ~(PDV_ENFRMCNT|PDVCL_IRIG2));
05795 pdv_p->dd_p->header_position = HeaderEnd;
05796 pdv_p->dd_p->header_size = 32;
05797 pdv_p->dd_p->header_dma = 1;
05798 edt_reg_or(pdv_p, PDV_UTILITY, PDVCL_IRIG2);
05799 pdv_p->spi_reg_base = PDV_IRIG_SPI_BASE;
05800 if (pdv_p->channel_no == 1)
05801 pdv_p->spi_reg_base -= 0x40;
05802
05803 pdv_irig_set_slave(pdv_p, irig_slave);
05804 if (!irig_slave)
05805 {
05806 pdv_irig_set_offset(pdv_p, irig_offset);
05807 pdv_irig_set_bcd(pdv_p, irig_raw);
05808 }
05809 pdv_p->dd_p->header_type = header_type;
05810
05811 break;
05812
05813 default:
05814 return -1;
05815 }
05816
05817 edt_set_dependent(pdv_p, pdv_p->dd_p);
05818
05819 return 0;
05820 }
05821
05834 int
05835 pdv_get_header_size(PdvDev * pdv_p)
05836 {
05837 return (pdv_p->dd_p->header_size);
05838 }
05839
05863 HdrPosition
05864 pdv_get_header_position(PdvDev * pdv_p)
05865 {
05866 return (HdrPosition) (pdv_p->dd_p->header_position);
05867 }
05868
05885 int
05886 pdv_get_header_offset(PdvDev * pdv_p)
05887 {
05888 switch (pdv_p->dd_p->header_position)
05889 {
05890 case HeaderBefore:
05891 pdv_p->dd_p->header_offset = - (int) pdv_p->dd_p->header_size;
05892 break;
05893 case HeaderBegin:
05894 pdv_p->dd_p->header_offset = 0;
05895 break;
05896 case HeaderEnd:
05897 pdv_p->dd_p->header_offset = pdv_get_dmasize(pdv_p) - pdv_p->dd_p->header_size ;
05898 break;
05899 case HeaderAfter:
05900 pdv_p->dd_p->header_offset = pdv_p->dd_p->imagesize;
05901 break;
05902
05903 }
05904
05905 return (pdv_p->dd_p->header_offset);
05906 }
05907
05916 int
05917 pdv_get_header_dma(PdvDev * pdv_p)
05918 {
05919 return (pdv_p->dd_p->header_dma);
05920 }
05921
05931 int
05932 pdv_get_header_within(PdvDev *pdv_p)
05933
05934 {
05935 return (pdv_p->dd_p->header_position == HeaderBegin ||
05936 pdv_p->dd_p->header_position == HeaderMiddle ||
05937 pdv_p->dd_p->header_position == HeaderEnd);
05938 }
05939
05949 int
05950 pdv_extra_headersize(PdvDev * pdv_p)
05951
05952 {
05953 if (pdv_p->dd_p->header_size && (!pdv_p->dd_p->header_dma) &&
05954 (pdv_p->dd_p->header_position == HeaderBefore ||
05955 pdv_p->dd_p->header_position == HeaderAfter))
05956 return pdv_p->dd_p->header_size;
05957
05958 return 0;
05959 }
05960
05970 void
05971 pdv_set_header_size(PdvDev * pdv_p, int header_size)
05972 {
05973 edt_msg(DBG2, "pdv_set_header_size()\n");
05974
05975 pdv_p->dd_p->header_size = header_size;
05976
05977 }
05978
05998 void
05999 pdv_set_header_position(PdvDev * pdv_p, HdrPosition header_position)
06000
06001 {
06002 edt_msg(DBG2, "pdv_set_header_position(%d)\n", header_position);
06003
06004 pdv_p->dd_p->header_position = header_position;
06005 }
06006
06016 void
06017 pdv_set_header_dma(PdvDev * pdv_p, int header_dma)
06018 {
06019 edt_msg(DBG2, "pdv_set_header_dma(%d,%d)\n", header_dma);
06020
06021 pdv_p->dd_p->header_dma = header_dma;
06022 }
06023
06024
06031 void
06032 pdv_set_header_offset(PdvDev * pdv_p, int header_offset)
06033
06034 {
06035 edt_msg(DBG2, "pdv_set_header_offset(%d,%d)\n", header_offset);
06036
06037 pdv_p->dd_p->header_offset = header_offset;
06038 }
06039
06068 int
06069 pdv_check_framesync(PdvDev *pdv_p, u_char *image_p, u_int *framecnt)
06070 {
06071 Irig2Record *irp;
06072
06073 if ((image_p == NULL) || (pdv_framesync_mode(pdv_p) == 0))
06074 return -1;
06075
06076 irp = (Irig2Record *)(image_p + pdv_get_header_offset(pdv_p));
06077 edt_msg(DBG2, "pdv_framesync(): magic %s framecnt %d\n", irp->magic == IRIG2_MAGIC? "OK ": "BAD", irp->framecnt);
06078 if (irp->magic == IRIG2_MAGIC)
06079 {
06080 *framecnt = irp->framecnt;
06081 return 0;
06082 }
06083 else *framecnt = 0;
06084
06085 return 1;
06086 }
06087
06108 int
06109 pdv_enable_framesync(PdvDev *pdv_p, int mode)
06110 {
06111 int ret = 0;
06112
06113
06114 pdv_p->dd_p->framesync_mode = 0;
06115
06116 if (!edt_has_irigb(pdv_p))
06117 {
06118 ret = -1;
06119 }
06120 else
06121 {
06122 if (mode)
06123 {
06124 if (pdv_set_header_type(pdv_p, HDR_TYPE_IRIG2, 1, 2, 0) < 0)
06125 {
06126 edt_msg(DBG2, "pdv_enable_framesync() FAIL\n");
06127 ret = -1;
06128 }
06129 else
06130 {
06131 pdv_p->dd_p->framesync_mode = mode;
06132 edt_msg(DBG2, "pdv_enable_framesync() OK\n");
06133 }
06134 }
06135 else
06136 {
06137 if (pdv_p->dd_p->header_type == HDR_TYPE_NONE)
06138 pdv_set_header_type(pdv_p, HDR_TYPE_NONE, 0, 0, 0);
06139 }
06140 }
06141
06142 return ret;
06143 }
06144
06157 int
06158 pdv_framesync_mode(PdvDev *pdv_p)
06159 {
06160 return pdv_p->dd_p->framesync_mode;
06161 }
06162
06163
06165
06178 int
06179 pdv_get_shutter_method(PdvDev * pdv_p, u_int *mcl)
06180 {
06181 edt_msg(DBG2, "pdv_get_shutter_method()\n");
06182
06183 *mcl = edt_reg_read(pdv_p, PDV_MODE_CNTL);
06184
06185 return pdv_p->dd_p->camera_shutter_timing;
06186 }
06187
06200 int
06201 pdv_shutter_method(PdvDev * pdv_p)
06202 {
06203 edt_msg(DBG2, "pdv_shutter_method()\n");
06204
06205 return pdv_p->dd_p->camera_shutter_timing;
06206 }
06207
06255 int
06256 pdv_set_shutter_method(PdvDev *pdv_p, int method, unsigned int mcl)
06257 {
06258 if (!pdv_p)
06259 return -1;
06260
06261 edt_msg(DBG2, "pdv_set_shutter_method (%d, %02x)\n", method);
06262
06263 pdv_p->dd_p->camera_shutter_timing = method;
06264 pdv_p->dd_p->mode_cntl_norm = mcl;
06265
06266 edt_reg_write(pdv_p, PDV_MODE_CNTL, mcl);
06267
06268 return 0;
06269 }
06270
06278 void
06279 pdv_set_interlace(PdvDev * pdv_p, int interlace)
06280 {
06281 edt_msg(DBG2, "pdv_set_interlace()\n");
06282
06283 pdv_p->dd_p->swinterlace = interlace;
06284
06285 pdv_setup_postproc(pdv_p, pdv_p->dd_p, NULL);
06286
06287 }
06288
06346 int
06347 pdv_interlace_method(PdvDev * pdv_p)
06348 {
06349 edt_msg(DBG2, "pdv_interlace_method()\n");
06350
06351 return pdv_p->dd_p->swinterlace;
06352 }
06353
06354
06371 int
06372 pdv_debug(int flag)
06373 {
06374 int oldval = Pdv_debug;
06375
06376 edt_msg(DBG2, "pdv_debug()\n");
06377
06378 Pdv_debug = flag;
06379 return (oldval);
06380 }
06381
06390 int
06391 pdv_debug_level()
06392 {
06393 return Pdv_debug;
06394 }
06395
06396
06408 int
06409 pdv_overrun(PdvDev * pdv_p)
06410 {
06411 int overrun;
06412
06413 edt_msg(DBG2, "pdv_overrun()\n");
06414
06415 if (pdv_p->devid == DMY_ID)
06416 return (0);
06417 edt_ioctl(pdv_p, EDTG_OVERFLOW, &overrun);
06418 return (overrun);
06419 }
06420
06439 int
06440 pdv_serial_wait(PdvDev * pdv_p, int msecs, int count)
06441 {
06442 edt_buf tmp;
06443 int ret;
06444
06445 pdv_serial_check_enabled(pdv_p);
06446
06447 if (msecs == 0)
06448 msecs = pdv_p->dd_p->serial_timeout;
06449
06450 tmp.desc = msecs;
06451 tmp.value = count;
06452 edt_ioctl(pdv_p, EDTS_SERIALWAIT, &tmp);
06453 ret = (int) tmp.value;
06454 edt_msg(DBG2, "pdv_serial_wait(%d, %d) ret %d\n", msecs, count, ret);
06455 return (ret);
06456 }
06457
06470 int
06471 pdv_serial_get_numbytes(PdvDev * pdv_p)
06472 {
06473 edt_buf tmp;
06474 int ret;
06475
06476 tmp.desc = 0;
06477 tmp.value = 0;
06478 edt_ioctl(pdv_p, EDTS_SERIALWAIT, &tmp);
06479 ret = (int) tmp.value;
06480 edt_msg(DBG2, "pdv_serial_get_numbytes %d\n", ret);
06481 return (ret);
06482 }
06483
06497 int
06498 pdv_serial_wait_next(EdtDev * pdv_p, int msecs, int count)
06499 {
06500 int ret;
06501 int newcount = count;
06502
06503 ret = pdv_serial_wait(pdv_p, msecs, count);
06504 return (ret);
06505 }
06506
06524 int
06525 pdv_set_waitchar(PdvDev * pdv_p, int enable, u_char wchar)
06526 {
06527 edt_buf tmp;
06528 int ret;
06529
06530
06531 tmp.desc = enable;
06532 tmp.value = wchar;
06533 ret = edt_ioctl(pdv_p, EDTS_WAITCHAR, &tmp);
06534 pdv_p->dd_p->serial_waitc = wchar;
06535 if (!enable)
06536 pdv_p->dd_p->serial_waitc |= 0x100;
06537 edt_msg(DBG2, "pdv_set_waitchar(%d, %02x) returns %d\n", enable, wchar, ret);
06538 return (ret);
06539 }
06540
06553 int
06554 pdv_get_waitchar(PdvDev * pdv_p, u_char *waitc)
06555 {
06556 int ret;
06557
06558 if (pdv_p->dd_p->serial_waitc & 0x100)
06559 {
06560 *waitc = pdv_p->dd_p->serial_waitc & 0xff;
06561 ret = 0;
06562 }
06563 else
06564 {
06565 *waitc = pdv_p->dd_p->serial_waitc;
06566 ret = 1;
06567 }
06568 return ret;
06569 }
06570
06571
06572 int
06573 pdv_get_fulldma_size(PdvDev *pdv_p, int *extrasizep)
06574
06575 {
06576 int size = pdv_get_imagesize(pdv_p);
06577
06578 int slop = pdv_slop(pdv_p);
06579 int extrasize;
06580 Dependent *dd_p = pdv_p->dd_p;
06581
06582 extrasize = slop + pdv_extra_headersize(pdv_p);
06583
06584 if (pdv_get_header_dma(pdv_p) && (pdv_get_header_within(pdv_p)))
06585 size += pdv_get_header_size(pdv_p);
06586
06587 if (dd_p->swinterlace || size != pdv_get_dmasize(pdv_p))
06588 {
06589
06590
06591 if (!pdv_process_inplace(pdv_p) || size != pdv_get_dmasize(pdv_p))
06592 {
06593 int newsize = pdv_get_dmasize(pdv_p);
06594
06595 extrasize += size;
06596 size = newsize;
06597 }
06598 }
06599
06600 if (extrasizep)
06601 *extrasizep = extrasize;
06602
06603 return size;
06604 }
06605
06606 int
06607 pdv_total_block_size(PdvDev *pdv_p, int numbufs)
06608
06609 {
06610 int extrasize = 0;
06611 int size;
06612
06613 size = pdv_get_fulldma_size(pdv_p, &extrasize);
06614
06615
06616 size = edt_get_total_bufsize(pdv_p, size, 0) * numbufs;
06617
06618 return size;
06619
06620 }
06621
06622
06623 void
06624 pdv_free_output_buffers(PdvDev *pdv_p)
06625
06626 {
06627 if (pdv_p->output_buffers)
06628 {
06629 edt_free((uchar_t *)pdv_p->output_buffers);
06630
06631 if (pdv_p->output_base)
06632 edt_free(pdv_p->output_base);
06633
06634 pdv_p->output_base = NULL;
06635 pdv_p->output_buffers = NULL;
06636 }
06637 }
06638
06639
06640 void
06641 pdv_allocate_output_buffers(PdvDev *pdv_p)
06642
06643 {
06644
06645
06646 if (pdv_p->output_buffers)
06647 {
06648 pdv_free_output_buffers(pdv_p);
06649 }
06650
06651 if (pdv_p->dd_p->swinterlace)
06652 {
06653 int size = pdv_get_imagesize(pdv_p);
06654
06655 u_int totalsize = size * pdv_p->ring_buffer_numbufs;
06656
06657 if (totalsize > 0)
06658 {
06659 pdv_p->output_base = edt_alloc(totalsize);
06660
06661 pdv_p->output_buffers = (unsigned char **)edt_alloc(sizeof(u_char *) * pdv_p->ring_buffer_numbufs);
06662
06663 if (pdv_p->output_base && pdv_p->output_buffers)
06664 {
06665 int i;
06666 for (i=0;i<(int)pdv_p->ring_buffer_numbufs;i++)
06667 pdv_p->output_buffers[i] = pdv_p->output_base + (size * i);
06668 }
06669 }
06670 }
06671
06672 }
06673
06674 int
06675 pdv_multibuf_block(PdvDev *pdv_p, int numbufs, u_char *block, int blocksize)
06676
06677 {
06678 int size, extrasize = 0;
06679 int ret;
06680 int header_before = (pdv_p->dd_p->header_position == HeaderBefore);
06681
06682 edt_msg(DBG2, "pdv_multibuf_block(%d, %d, %x)\n", numbufs, block, blocksize);
06683
06684
06685
06686 size = pdv_get_fulldma_size(pdv_p, &extrasize);
06687
06688
06689 pdv_setup_dma(pdv_p);
06690
06691 ret = edt_configure_block_buffers_mem(pdv_p,
06692 size,
06693 numbufs,
06694 EDT_READ,
06695 0,
06696 header_before,
06697 block) ;
06698
06699 pdv_allocate_output_buffers(pdv_p);
06700
06701 return ret;
06702
06703 }
06704
06705 int
06706 pdv_multibuf_separate(PdvDev *pdv_p, int numbufs, u_char **buffers)
06707
06708 {
06709 int size = pdv_get_imagesize(pdv_p);
06710 int ret;
06711
06712 Dependent *dd_p = pdv_p->dd_p;
06713
06714 edt_msg(DBG2, "pdv_multibuf_separate(%d, %x)\n", numbufs, buffers);
06715
06716 if (dd_p->swinterlace || size != pdv_get_dmasize(pdv_p))
06717 {
06718
06719
06720 if (!pdv_process_inplace(pdv_p) || size != pdv_get_dmasize(pdv_p))
06721 {
06722 edt_msg_perror(PDVFATAL,"Interlace not inplace fails for multibuf_separate\n");
06723 return -1;
06724 }
06725 }
06726
06727 size = pdv_get_fulldma_size(pdv_p, NULL);
06728
06729 pdv_setup_dma(pdv_p);
06730
06731 ret = edt_configure_ring_buffers(pdv_p, size, numbufs, EDT_READ, buffers) ;
06732
06733 return ret;
06734
06735 }
06736
06768 int
06769 pdv_multibuf(PdvDev * pdv_p, int numbufs)
06770 {
06771
06772
06773
06774
06775
06776 #if defined(XCALIBURCOMMON) || defined(VMIC)
06777 return pdv_multibuf_separate(pdv_p, numbufs,NULL);
06778 #else
06779 return pdv_multibuf_block(pdv_p, numbufs, NULL, 0);
06780 #endif
06781
06782 }
06783
06822 int
06823 pdv_set_buffers(PdvDev * pdv_p, int numbufs, unsigned char **bufarray)
06824 {
06825
06826 int size = pdv_get_dmasize(pdv_p);
06827
06828 edt_msg(DBG2, "pdv_set_buffers(%d %x) (size %d)\n", numbufs, bufarray, size);
06829
06830 pdv_setup_dma(pdv_p);
06831
06832 return (edt_configure_ring_buffers(pdv_p, size, numbufs, EDT_READ, bufarray));
06833 }
06834
06835
06836 int
06837 pdv_set_buffers_x(PdvDev * pdv_p, int numbufs, int size, unsigned char **bufs)
06838 {
06839
06840 edt_msg(DBG2, "pdv_set_buffers(%d %x) (size %d)\n", numbufs, bufs, size);
06841
06842 pdv_setup_dma(pdv_p);
06843
06844 return (edt_configure_ring_buffers(pdv_p, size, numbufs, EDT_READ, bufs));
06845 }
06846
06847
06862 int
06863 pdv_image_size(PdvDev * pdv_p)
06864 {
06865 int size;
06866
06867 size = pdv_p->dd_p->imagesize;
06868
06869 if (pdv_p->dd_p->slop)
06870 {
06871
06872 edt_msg(DBG2, "pdv_image_size: adjusting size %x by slop %x to %x\n",
06873 size, pdv_p->dd_p->slop, size - pdv_p->dd_p->slop);
06874
06875 size -= pdv_p->dd_p->slop;
06876
06877 }
06878
06879 if (pdv_p->dd_p->header_dma)
06880 size += pdv_p->dd_p->header_size;
06881
06882 edt_msg(DBG2, "pdv_image_size() %d\n", size);
06883
06884 return size;
06885
06886 }
06887
06888
06902 u_char *
06903 pdv_get_last_image(PdvDev * pdv_p)
06904 {
06905 edt_msg(DBG2, "pdv_get_last_image()\n");
06906
06907 return (pdv_p->dd_p->last_image);
06908 }
06909
06924 u_char *
06925 pdv_get_last_raw(PdvDev * pdv_p)
06926 {
06927 edt_msg(DBG2, "pdv_get_last_raw()\n");
06928
06929 return (pdv_p->dd_p->last_raw);
06930 }
06931
06946 u_char **
06947 pdv_buffer_addresses(PdvDev * pdv_p)
06948 {
06949
06950 return (pdv_p->ring_buffers);
06951 }
06952
06978 void
06979 pdv_start_hardware_continuous(PdvDev * pdv_p )
06980 {
06981 int data_path;
06982
06983
06984 data_path = pdv_p->dd_p->datapath_reg & ~PDV_CONTINUOUS;
06985
06986 edt_msg(DBG2, "pdv_start_hardware_continuous()\n");
06987
06988
06989 edt_reg_write(pdv_p, PDV_DATA_PATH, data_path | PDV_CONTINUOUS);
06990 pdv_p->dd_p->datapath_reg = data_path;
06991 }
06992
06993
07003 void
07004 pdv_stop_hardware_continuous(PdvDev * pdv_p)
07005 {
07006 int data_path;
07007
07008
07009 data_path = pdv_p->dd_p->datapath_reg;
07010 edt_msg(DBG2, "pdv_stop_hardware_continuous()\n");
07011 data_path &= ~PDV_CONTINUOUS;
07012 edt_reg_write(pdv_p, PDV_DATA_PATH, data_path);
07013 pdv_p->dd_p->datapath_reg = data_path;
07014
07015 }
07016
07027 int
07028 pdv_set_serial_parity(PdvDev * pdv_p, char parity)
07029 {
07030 if (pdv_p->devid == PDVAERO_ID)
07031 {
07032 int val = 0;
07033 switch(parity)
07034 {
07035
07036 case 'e':
07037 val = 1;
07038 break;
07039 case 'o':
07040 val = 3;
07041 break;
07042 case 'n':
07043 val = 0;
07044 break;
07045 default:
07046 edt_msg(DBG1, "parity must be e, o, or n");
07047 return -1;
07048 }
07049
07050 edt_reg_write(pdv_p,PDV_SERIAL_PARITY,val);
07051 return 0;
07052 }
07053 else
07054 {
07055 edt_msg(DBG1,"parity not an option for this board");
07056 }
07057 return -1;
07058 }
07059
07075 int
07076 pdv_set_baud(PdvDev * pdv_p, int baud)
07077 {
07078 Dependent *dd_p = pdv_p->dd_p;
07079 u_int baudbits = 0;
07080 int id=pdv_p->devid;
07081 u_int new, baudreg;
07082 u_int cntl;
07083 int donew = 0;
07084 int ret = 0;
07085
07086 if (edt_is_dvcl(pdv_p) || edt_is_dvfox(pdv_p) || (id == PDVA_ID) || edt_is_dvcl2(pdv_p))
07087 donew = 1;
07088
07089 switch (baud)
07090 {
07091 case 9600:
07092 baudbits = 0;
07093 baudreg = 0x80;
07094 break;
07095
07096 case 19200:
07097 baudbits = PDV_BAUD0;
07098 baudreg = 0x3f;
07099 break;
07100
07101 case 38400:
07102 baudbits = PDV_BAUD1;
07103 baudreg = 0x1f;
07104 break;
07105
07106 case 115200:
07107 baudbits = PDV_BAUD0 | PDV_BAUD1;
07108 baudreg = 0x09;
07109 break;
07110
07111 case 57600:
07112 baudbits = PDV_BAUD0 | PDV_BAUD1;
07113 donew = 1;
07114 baudreg = 0x014;
07115 break;
07116
07117 default:
07118 donew = 1;
07119 baudreg = (unsigned int)(((20000000.0 / (16.0 * (double)baud)) - 2.0) + 0.5) ;
07120 edt_msg(DBG2, "pdv_set_baud(%d) using new method, reg %02x\n", baud, baudreg);
07121 break;
07122 }
07123
07124 if (donew && (!dd_p->register_wrap))
07125 {
07126 if (baudreg > 0xff)
07127 {
07128 edt_msg(DBG2, "pdv_set_baud(%d) (baudreg %x) BAD VALUE not set\n", baud, baudreg);
07129 ret = -1;
07130 }
07131 else
07132 {
07133 edt_msg(DBG2, "pdv_set_baud(%d) (baudreg %x) using NEW baud reg\n", baud, baudreg);
07134 edt_reg_write(pdv_p, PDV_BRATE, baudreg);
07135 new = edt_reg_read(pdv_p, PDV_BRATE);
07136 if (new != baudreg)
07137 {
07138 edt_msg(DBG2, "pdv_set_baud(%d) wrote %x read %x) readback ERROR\n", baud, baudreg, new);
07139 ret = -1;
07140 }
07141 }
07142 }
07143
07144 else
07145 {
07146 edt_msg(DBG2, "pdv_set_baud(%d) (baudbits %x) using OLD baud bits\n", baud, baudbits);
07147 cntl = edt_reg_read(pdv_p, PDV_SERIAL_DATA_CNTL);
07148 cntl &= ~PDV_BAUD_MASK;
07149 cntl |= baudbits;
07150 edt_reg_write(pdv_p, PDV_SERIAL_DATA_CNTL, cntl);
07151 }
07152
07153 if (ret == 0)
07154 {
07155 pdv_p->dd_p->serial_baud = baud;
07156 edt_set_dependent(pdv_p, pdv_p->dd_p);
07157 }
07158
07159 return ret;
07160 }
07161
07170 int
07171 pdv_get_baud(PdvDev * pdv_p)
07172 {
07173 if (pdv_p->dd_p->serial_baud == NOT_SET)
07174 return 9600;
07175 return pdv_p->dd_p->serial_baud;
07176 }
07177
07193 void
07194 pdv_perror(char *err)
07195 {
07196 edt_perror(err);
07197 }
07198
07199 void
07200 pdv_setdebug(PdvDev * pdv_p, int debug)
07201 {
07202 Pdv_debug = debug;
07203 }
07204
07205
07206
07207
07208
07221 void
07222 pdv_reset_serial(PdvDev * pdv_p)
07223 {
07224 edt_reset_serial(pdv_p);
07225 }
07226
07227
07248 uchar_t *
07249 pdv_alloc(int size)
07250 {
07251 return edt_alloc(size);
07252 }
07253
07254
07261 void
07262 pdv_free(uchar_t * ptr)
07263 {
07264 edt_free(ptr);
07265 }
07266
07267
07268
07269 static u_short zero[] = {
07270 0x0F80,
07271 0x3FE0,
07272 0x38E0,
07273 0x7070,
07274 0x6030,
07275 0xE038,
07276 0xE038,
07277 0xE038,
07278 0xE038,
07279 0xE038,
07280 0xE038,
07281 0xE038,
07282 0x6030,
07283 0x7070,
07284 0x38E0,
07285 0x3FE0,
07286 0x0F80,
07287 };
07288 static u_short one[] = {
07289 0xFC00,
07290 0xFC00,
07291 0x1C00,
07292 0x1C00,
07293 0x1C00,
07294 0x1C00,
07295 0x1C00,
07296 0x1C00,
07297 0x1C00,
07298 0x1C00,
07299 0x1C00,
07300 0x1C00,
07301 0x1C00,
07302 0x1C00,
07303 0x1C00,
07304 0xFF80,
07305 0xFF80,
07306 };
07307 static u_short two[] = {
07308 0x7E00,
07309 0x7F80,
07310 0x4380,
07311 0x01C0,
07312 0x01C0,
07313 0x01C0,
07314 0x01C0,
07315 0x0380,
07316 0x0700,
07317 0x0E00,
07318 0x1C00,
07319 0x3800,
07320 0x3800,
07321 0x7000,
07322 0xE000,
07323 0xFFC0,
07324 0xFFC0,
07325 };
07326 static u_short three[] = {
07327 0x7E00,
07328 0xFF00,
07329 0x8780,
07330 0x0380,
07331 0x0380,
07332 0x0380,
07333 0x0F00,
07334 0x7C00,
07335 0x7E00,
07336 0x0F00,
07337 0x0380,
07338 0x0380,
07339 0x0380,
07340 0x0380,
07341 0x8700,
07342 0xFF00,
07343 0xFC00,
07344 };
07345 static u_short four[] = {
07346 0x0380,
07347 0x0780,
07348 0x0F80,
07349 0x0F80,
07350 0x1F80,
07351 0x1B80,
07352 0x3380,
07353 0x3380,
07354 0x6380,
07355 0xE380,
07356 0xFFE0,
07357 0xFFE0,
07358 0xFFE0,
07359 0x0380,
07360 0x0380,
07361 0x0380,
07362 0x0380,
07363 };
07364 static u_short five[] = {
07365 0xFF80,
07366 0xFF80,
07367 0xE000,
07368 0xE000,
07369 0xE000,
07370 0xC000,
07371 0xF800,
07372 0xFE00,
07373 0x0F00,
07374 0x0780,
07375 0x0380,
07376 0x0380,
07377 0x0380,
07378 0x0380,
07379 0x8700,
07380 0xFE00,
07381 0xFC00,
07382 };
07383 static u_short six[] = {
07384 0x07E0,
07385 0x1FE0,
07386 0x3C20,
07387 0x7000,
07388 0x7000,
07389 0xE000,
07390 0xE780,
07391 0xFFE0,
07392 0xF0E0,
07393 0xE070,
07394 0xE070,
07395 0xE070,
07396 0xE070,
07397 0x7070,
07398 0x70E0,
07399 0x3FC0,
07400 0x0F80,
07401 };
07402 static u_short seven[] = {
07403 0xFFC0,
07404 0xFFC0,
07405 0x01C0,
07406 0x0180,
07407 0x0380,
07408 0x0700,
07409 0x0700,
07410 0x0E00,
07411 0x0C00,
07412 0x1C00,
07413 0x1800,
07414 0x3800,
07415 0x3800,
07416 0x3000,
07417 0x7000,
07418 0x7000,
07419 0x7000,
07420 };
07421 static u_short eight[] = {
07422 0x0F80,
07423 0x3FC0,
07424 0x71E0,
07425 0x70E0,
07426 0x70E0,
07427 0x7DE0,
07428 0x3FC0,
07429 0x1F00,
07430 0x1FC0,
07431 0x7FE0,
07432 0xF1F0,
07433 0xE0F0,
07434 0xE070,
07435 0xE070,
07436 0xF0E0,
07437 0x7FE0,
07438 0x1F80,
07439 };
07440 static u_short nine[] = {
07441 0x1F00,
07442 0x3FC0,
07443 0x70E0,
07444 0xE0E0,
07445 0xE070,
07446 0xE070,
07447 0xE070,
07448 0xE070,
07449 0x70F0,
07450 0x7FF0,
07451 0x1E70,
07452 0x0070,
07453 0x00E0,
07454 0x00E0,
07455 0x43C0,
07456 0x7F80,
07457 0x7E00,
07458 };
07459
07460 static u_short *digits[] = {
07461 zero,
07462 one,
07463 two,
07464 three,
07465 four,
07466 five,
07467 six,
07468 seven,
07469 eight,
07470 nine,
07471 };
07472
07473
07474 static void
07475 set_square_32(int sx, int sy, u_short * buf, u_int * addr, int stride, int fg)
07476 {
07477
07478
07479
07480
07481 #define BG16 0
07482
07483
07484
07485
07486 register u_int *svptr;
07487 register u_int *ptr;
07488 int i;
07489 int bit;
07490 u_short tmp;
07491 int val;
07492
07493 svptr = addr + (stride * sy) + (sx);
07494
07495 for (i = 0; i < 17; i++)
07496 {
07497 ptr = svptr;
07498 tmp = *buf++;
07499 for (bit = 15; bit >= 0; bit--)
07500 {
07501 if (tmp & (1 << bit))
07502 {
07503 val = fg;
07504 }
07505 else
07506 {
07507 val = BG16;
07508 }
07509 *ptr++ = val;
07510 }
07511 svptr += stride;
07512 }
07513 }
07514
07515
07516 static void
07517 set_square_16(int sx, int sy, u_short * buf, u_short * addr, int stride, int fg)
07518 {
07519
07520
07521
07522
07523 #define BG16 0
07524
07525
07526
07527
07528 register u_short *svptr;
07529 register u_short *ptr;
07530 int i;
07531 int bit;
07532 u_short tmp;
07533 int val;
07534
07535 svptr = addr + (stride * sy) + (sx);
07536
07537 for (i = 0; i < 17; i++)
07538 {
07539 ptr = svptr;
07540 tmp = *buf++;
07541 for (bit = 15; bit >= 0; bit--)
07542 {
07543 if (tmp & (1 << bit))
07544 {
07545 val = fg;
07546 }
07547 else
07548 {
07549 val = BG16;
07550 }
07551 *ptr++ = val;
07552 }
07553 svptr += stride;
07554 }
07555 }
07556
07557 static void
07558 set_square(int sx, int sy, u_short * buf, u_char * addr, int stride, int fg)
07559 {
07560
07561
07562
07563
07564 #define BG 0
07565
07566
07567
07568
07569 register u_char *svptr;
07570 register u_char *ptr;
07571 int i;
07572 int bit;
07573 u_short tmp;
07574 int val;
07575
07576 svptr = addr + (stride * sy) + (sx);
07577
07578 for (i = 0; i < 17; i++)
07579 {
07580 ptr = svptr;
07581 tmp = *buf++;
07582 for (bit = 15; bit >= 0; bit--)
07583 {
07584 if (tmp & (1 << bit))
07585 {
07586 val = fg;
07587 }
07588 else
07589 {
07590 val = BG;
07591 }
07592 *ptr++ = val;
07593 }
07594 svptr += stride;
07595 }
07596 }
07597
07598 void
07599 pdv_mark_digit_16(u_short * addr, int n, int width, int height, int x, int y,
07600 int mask, int fg)
07601
07602 {
07603 int dig = n % 10;
07604
07605 set_square_16(x, y, digits[dig], addr, width, fg);
07606
07607 }
07608
07609 void
07610 pdv_mark_digit_32(u_int * addr, int n, int width, int height, int x, int y,
07611 int mask, int fg)
07612
07613 {
07614 int dig = n % 10;
07615
07616 set_square_32(x, y, digits[dig], addr, width, fg);
07617
07618 }
07619
07620 void
07621 pdv_mark_digit_24(u_char * addr, int n, int width, int height, int x, int y,
07622 int mask, int fg)
07623
07624 {
07625 int dig = n % 10;
07626
07627 set_square(x, y, digits[dig], addr, width, fg);
07628
07629 }
07630
07631 void
07632 pdv_mark_digit_8(u_char * addr, int n, int width, int height, int x, int y,
07633 int mask, int fg)
07634
07635 {
07636 int dig = n % 10;
07637
07638 set_square(x, y, digits[dig], addr, width, fg);
07639
07640 }
07641
07642 void
07643 pdv_mark_ras_depth(void * addr, int n, int width, int height, int x, int y, int depth, int fg)
07644 {
07645 #define GAP 16
07646 int div = 1000000;
07647
07648 int i;
07649
07650 for (i=0;div>=1;i++)
07651 {
07652
07653 if (n > div)
07654 {
07655 int val = (n / div) % 10;
07656
07657 switch(depth)
07658 {
07659 case 8:
07660 pdv_mark_digit_8((u_char *) addr, val, width, height, x + (GAP * i), y, 1, fg);
07661 break;
07662 case 16:
07663 pdv_mark_digit_16((u_short *) addr, val, width, height, x + (GAP * i), y, 1, fg);
07664 break;
07665 case 24:
07666 pdv_mark_digit_24((u_char *) addr, val, width, height, x + (GAP * i), y, 1, fg);
07667 break;
07668 case 32:
07669 pdv_mark_digit_32((u_int *) addr, val, width, height, x + (GAP * i), y, 1, fg);
07670 break;
07671 }
07672 }
07673
07674 div /= 10;
07675 }
07676 }
07677
07678 void
07679 pdv_mark_bin_16(u_short * addr, int n, int width, int height, int x, int y)
07680 {
07681 u_int val = n;
07682 u_char *svptr;
07683
07684 svptr = (u_char *) addr + (width * y) + x;
07685 *svptr++ = (val >> 24) & 0xff;
07686 *svptr++ = (val >> 16) & 0xff;
07687 *svptr++ = (val >> 8) & 0xff;
07688 *svptr++ = val & 0xff;
07689 }
07690
07691
07692 void
07693 pdv_mark_ras(u_char * addr, int n, int width, int height, int x, int y)
07694 {
07695 #define GAP 16
07696 int div = 1000000;
07697 int i;
07698
07699 for (i=0;div;i++)
07700 {
07701 pdv_mark_digit_8(addr, n, width, height, x + (GAP * i), y, div, 200);
07702 div /= 10;
07703 }
07704 }
07705
07706 void
07707 pdv_mark_bin(u_char * addr, int n, int width, int height, int x, int y)
07708 {
07709 u_int val = n;
07710 u_char *svptr;
07711
07712 svptr = (u_char *) addr + (width * y) + x;
07713 *svptr++ = (val >> 24) & 0xff;
07714 *svptr++ = (val >> 16) & 0xff;
07715 *svptr++ = (val >> 8) & 0xff;
07716 *svptr++ = val & 0xff;
07717 }
07718
07736 int
07737 pdv_serial_command_hex(PdvDev * pdv_p, const char *str, int length)
07738 {
07739 char buf[2];
07740 const char *p = &str[2];
07741 u_int lval;
07742
07743 sscanf(p, "%x", &lval);
07744 buf[0] = (char) (lval & 0xff);
07745 edt_msg(DBG2, "pdv_serial_command_hex(%s),0x%x\n", str, (u_char) (buf[0]));
07746
07747 return pdv_serial_binary_command(pdv_p, buf, 1);
07748 }
07749
07793 int
07794 pdv_set_roi(PdvDev * pdv_p, int hskip, int hactv, int vskip, int vactv)
07795 {
07796 return pdv_set_roi_internal(pdv_p, hskip, hactv, vskip, vactv, 1);
07797 }
07798
07799
07810 int
07811 pdv_set_roi_internal(PdvDev * pdv_p, int hskip, int hactv, int vskip, int vactv, int call_setsize)
07812 {
07813 Dependent *dd_p = pdv_p->dd_p;
07814 int cam_w, cam_h;
07815
07816 edt_msg(DBG2, "pdv_set_roi(hskip %d hactv %d vskip %d vactv %d)\n",
07817 hskip, hactv, vskip, vactv);
07818
07819 cam_w = pdv_get_cam_width(pdv_p);
07820 cam_h = pdv_get_cam_height(pdv_p);
07821
07822
07823 if (!pdv_is_cameralink(pdv_p))
07824 {
07825 if ((cam_w && ((hskip + hactv) > cam_w)) || ((hskip + hactv) <= 0))
07826 {
07827 edt_msg(DBG2, "ROI: horiz. skip/actv out of range error\n");
07828 return -1;
07829 }
07830 if ((cam_h && ((vskip + vactv) > cam_h)) || ((vskip + vactv) <= 0))
07831 {
07832 edt_msg(DBG2, "ROI: vert. skip/actv out of range error\n");
07833 return -1;
07834 }
07835 }
07836
07837
07838 if (pdv_is_cameralink(pdv_p))
07839 {
07840 if (dd_p->htaps > 0)
07841 {
07842 hactv = (hactv / dd_p->htaps) * dd_p->htaps;
07843 hskip = (hskip / dd_p->htaps) * dd_p->htaps;
07844
07845 edt_reg_write(pdv_p, PDV_HSKIP, (hskip / dd_p->htaps));
07846 edt_reg_write(pdv_p, PDV_HACTV, (hactv / dd_p->htaps) - 1);
07847 }
07848
07849 if (dd_p->vtaps > 0)
07850 {
07851 vactv = (vactv / dd_p->vtaps) * dd_p->vtaps;
07852 vskip = (vskip / dd_p->vtaps) * dd_p->vtaps;
07853
07854 edt_reg_write(pdv_p, PDV_VSKIP, (vskip / dd_p->vtaps));
07855 edt_reg_write(pdv_p, PDV_VACTV, (vactv / dd_p->vtaps) - 1);
07856 }
07857 }
07858 else if (dd_p->dual_channel)
07859 {
07860 vactv = (vactv / 2) * 2;
07861 vskip = (vskip / 2) * 2;
07862 edt_reg_write(pdv_p, PDV_VSKIP, (vskip / 2));
07863 edt_reg_write(pdv_p, PDV_HSKIP, hskip);
07864 edt_reg_write(pdv_p, PDV_VACTV, (vactv / 2) - 1);
07865 edt_reg_write(pdv_p, PDV_HACTV, hactv - 1);
07866 }
07867 else
07868 {
07869 edt_reg_write(pdv_p, PDV_HSKIP, hskip);
07870 edt_reg_write(pdv_p, PDV_VSKIP, vskip);
07871 edt_reg_write(pdv_p, PDV_HACTV, hactv - 1);
07872 edt_reg_write(pdv_p, PDV_VACTV, vactv - 1);
07873 }
07874
07875 dd_p->hactv = hactv;
07876 dd_p->hskip = hskip;
07877 dd_p->vactv = vactv;
07878 dd_p->vskip = vskip;
07879
07880 if (call_setsize && dd_p->roi_enabled)
07881 pdv_setsize(pdv_p, dd_p->hactv, dd_p->vactv);
07882
07883 edt_set_dependent(pdv_p, dd_p);
07884
07885 return 0;
07886
07887 }
07888
07889
07913 void
07914 pdv_cl_set_base_channels(PdvDev *pdv_p, int htaps, int vtaps)
07915
07916 {
07917 Dependent *dd_p = pdv_p->dd_p;
07918 int taps;
07919
07920 if ((htaps > 1) && (vtaps > 1))
07921 taps = htaps + vtaps;
07922 else if (htaps > 1)
07923 taps = htaps;
07924 else if (vtaps > 1)
07925 taps = vtaps;
07926 else taps = 1;
07927
07928 dd_p->cl_data_path = (taps - 1) << 4 | (dd_p->depth - 1);
07929
07930 dd_p->htaps = htaps;
07931 dd_p->vtaps = vtaps;
07932
07933 edt_reg_write(pdv_p, PDV_CL_DATA_PATH, dd_p->cl_data_path);
07934
07935 edt_set_dependent(pdv_p, dd_p);
07936
07937 pdv_set_roi(pdv_p, dd_p->hskip, dd_p->hactv, dd_p->vskip, dd_p->vactv);
07938 }
07939
07940
07941
07942
07943
07944
07945
07946
07947 int
07948 pdv_dalsa_ls_set_expose(PdvDev * pdv_p, int hskip, int hactv)
07949 {
07950 Dependent *dd_p = pdv_p->dd_p;
07951
07952 edt_msg(DBG2, "pdv_dalsa_ls_set_expose(hskip %d hactv %d)\n", hskip, hactv);
07953
07954 edt_reg_write(pdv_p, PDV_HSKIP, hskip);
07955 edt_reg_write(pdv_p, PDV_HACTV, hactv - 1);
07956
07957 dd_p->hactv = hactv;
07958 dd_p->hskip = hskip;
07959
07960 edt_set_dependent(pdv_p, dd_p);
07961 pdv_enable_roi(pdv_p, 1);
07962
07963 return 0;
07964
07965 }
07966
07967
07976 int
07977 pdv_auto_set_roi(PdvDev * pdv_p)
07978 {
07979 int w = pdv_p->dd_p->width;
07980 int h = pdv_p->dd_p->height;
07981 int ret;
07982
07983 edt_msg(DBG2, "pdv_auto_set_roi()\n");
07984
07985 if ((ret = pdv_set_roi(pdv_p, 0, w, 0, h)) == 0)
07986 {
07987 if (pdv_is_cameralink(pdv_p))
07988 pdv_setsize(pdv_p, pdv_p->dd_p->hactv, pdv_p->dd_p->vactv);
07989 ret = pdv_enable_roi(pdv_p, 1);
07990 }
07991
07992 return ret;
07993 }
07994
08017 int
08018 pdv_enable_roi(PdvDev * pdv_p, int flag)
08019 {
08020 u_int roictl;
08021 Dependent *dd_p = pdv_p->dd_p;
08022
08023
08024 if (pdv_is_cameralink(pdv_p))
08025 {
08026 if (flag)
08027 {
08028 edt_reg_and(pdv_p, PDV_CL_CFG, ~PDV_CL_CFG_ROIDIS);
08029 pdv_setsize(pdv_p, dd_p->hactv, dd_p->vactv);
08030 }
08031 else
08032 {
08033 edt_reg_or(pdv_p, PDV_CL_CFG, PDV_CL_CFG_ROIDIS);
08034 pdv_setsize(pdv_p, dd_p->cam_width, dd_p->cam_height);
08035 }
08036
08037 dd_p->roi_enabled = flag;
08038
08039 return 0;
08040 }
08041
08042 edt_msg(DBG2, "pdv_enable_roi(%d): %sabling\n", flag, flag ? "EN" : "DIS");
08043
08044
08045
08046 roictl = edt_reg_read(pdv_p, PDV_ROICTL);
08047
08048
08049 if (flag)
08050 {
08051 roictl |= PDV_ROICTL_ROI_EN;
08052 edt_reg_write(pdv_p, PDV_ROICTL, roictl);
08053 pdv_setsize(pdv_p, dd_p->hactv, dd_p->vactv);
08054 }
08055 else
08056 {
08057
08058 roictl &= ~PDV_ROICTL_ROI_EN;
08059 edt_reg_write(pdv_p, PDV_ROICTL, roictl);
08060 pdv_setsize(pdv_p, dd_p->cam_width, dd_p->cam_height);
08061 }
08062
08063 dd_p->roi_enabled = flag;
08064
08065 return 0;
08066 }
08067
08068 int
08069 pdv_get_roi_enabled(PdvDev *pdv_p)
08070
08071 {
08072 Dependent *dd_p = pdv_p->dd_p;
08073
08074 if (pdv_is_cameralink(pdv_p))
08075 {
08076 dd_p->roi_enabled = (edt_reg_read(pdv_p, PDV_CL_CFG) & 0x08) != 0;
08077 }
08078 else
08079 {
08080 dd_p->roi_enabled = (edt_reg_read(pdv_p, PDV_ROICTL) & PDV_ROICTL_ROI_EN) != 0;
08081 }
08082
08083 return dd_p->roi_enabled;
08084 }
08085
08105 int
08106 pdv_access(char *fname, int perm)
08107 {
08108 return edt_access(fname, perm);
08109 }
08110
08111
08135 int
08136 pdv_strobe(PdvDev * pdv_p, int count, int delay)
08137 {
08138 if (pdv_strobe_method(pdv_p) != PDV_LHS_METHOD1)
08139 return -1;
08140
08141 edt_msg(DBG2, "pdv_strobe(%d %d)\n", count, delay);
08142
08143 edt_reg_write(pdv_p, PDV_SHUTTER, delay);
08144
08145
08146
08147
08148
08149 edt_reg_write(pdv_p, PDV_FIXEDLEN, count);
08150
08151 return 0;
08152 }
08153
08174 int
08175 pdv_set_strobe_counters(PdvDev * pdv_p, int count, int delay, int period)
08176 {
08177 if (pdv_strobe_method(pdv_p) != PDV_LHS_METHOD2)
08178 return -1;
08179
08180 if (count > 0xfff)
08181 {
08182 edt_msg(DBG1, "pdv_set_strobe_counters() ERROR -- count out of range\n");
08183 return -1;
08184 }
08185
08186 if (delay > 0xff)
08187 {
08188 edt_msg(PDVWARN, "pdv_set_strobe_counters() ERROR -- delay out of range\n");
08189 return -1;
08190 }
08191
08192 if (period > 0xff)
08193 {
08194 edt_msg(PDVWARN, "pdv_set_strobe_counters() ERROR -- period out of range\n");
08195 return -1;
08196 }
08197
08198 edt_msg(DBG2, "pdv_set_strobe_counters(%d %d %d)\n", count, delay, period);
08199
08200 edt_reg_write(pdv_p, PDV_LHS_DELAY, delay);
08201
08202 edt_reg_write(pdv_p, PDV_LHS_PERIOD, period);
08203
08204
08205
08206
08207 edt_reg_write(pdv_p, PDV_LHS_COUNT, count);
08208
08209 return 0;
08210 }
08211
08223 int
08224 pdv_enable_strobe(PdvDev * pdv_p, int ena)
08225 {
08226 int method = pdv_strobe_method(pdv_p);
08227
08228 if (method == 0)
08229 return -1;
08230
08231 if (method == PDV_LHS_METHOD1)
08232 {
08233 if (ena == 0)
08234 return -1;
08235 return 0;
08236 }
08237
08238 if (ena)
08239 edt_reg_write(pdv_p, PDV_LHS_CONTROL, PDV_LHS_ENABLE);
08240 else edt_reg_write(pdv_p, PDV_LHS_CONTROL, 0);
08241
08242 return 0;
08243 }
08244
08255 int
08256 pdv_strobe_method(PdvDev *pdv_p)
08257 {
08258 Dependent *dd_p = pdv_p->dd_p;
08259 int status;
08260
08261 if (dd_p->strobe_enabled == NOT_SET)
08262 {
08263 int reg ;
08264
08265
08266 dd_p->strobe_enabled = 0;
08267
08268
08269
08270
08271 if (pdv_p->devid == PDVCL_ID)
08272 {
08273 dd_p->strobe_enabled = PDV_LHS_METHOD2;
08274 return dd_p->strobe_enabled;
08275 }
08276
08277
08278 if (dd_p->xilinx_rev < 2 || dd_p->xilinx_rev > 32)
08279 return 0;
08280
08281
08282
08283
08284 if (!dd_p->register_wrap)
08285 {
08286 reg = edt_reg_read(pdv_p, PDV_LHS_COUNT_HI);
08287 edt_reg_write(pdv_p, PDV_LHS_COUNT_HI, 0x50);
08288 if (edt_reg_read(pdv_p, PDV_LHS_COUNT_HI) == 0x50)
08289 {
08290 edt_reg_write(pdv_p, PDV_LHS_COUNT_HI, reg);
08291 dd_p->strobe_enabled = PDV_LHS_METHOD2;
08292 return dd_p->strobe_enabled;
08293 }
08294 }
08295
08296
08297
08298 status = edt_reg_read(pdv_p, PDV_SERIAL_DATA_STAT);
08299
08300 if (status & LHS_DONE)
08301 dd_p->strobe_enabled = PDV_LHS_METHOD1;
08302
08303 }
08304
08305 return dd_p->strobe_enabled;
08306 }
08307
08308
08328 int
08329 pdv_set_strobe_dac(PdvDev * pdv_p, u_int value)
08330 {
08331 int i;
08332 int reg;
08333 int method;
08334 u_int mcl, mask;
08335 u_char data;
08336
08337 if ((method = pdv_strobe_method(pdv_p)) == 0)
08338 return -1;
08339
08340 if (method == PDV_LHS_METHOD2)
08341 reg = PDV_LHS_CONTROL;
08342 else reg = PDV_MODE_CNTL;
08343
08344 edt_msg(DBG2, "pdv_strobe(%d)\n", value);
08345
08346 mcl = edt_reg_read(pdv_p, reg) & 0x0f;
08347
08348
08349
08350
08351
08352 edt_reg_write(pdv_p, reg, mcl | PDV_LHS_DAC_LOAD);
08353
08354
08355
08356
08357 for (i = 0; i < 16; i++)
08358 {
08359 mask = (value & (1 << (15 - i)));
08360
08361 if (mask)
08362 data = PDV_LHS_DAC_DATA;
08363 else
08364 data = 0;
08365
08366 edt_reg_write(pdv_p, reg, mcl | PDV_LHS_DAC_LOAD | data);
08367 edt_reg_write(pdv_p, reg, mcl | PDV_LHS_DAC_LOAD | PDV_LHS_DAC_CLOCK | data);
08368 edt_reg_write(pdv_p, reg, mcl | PDV_LHS_DAC_LOAD | data);
08369 edt_reg_write(pdv_p, reg, mcl | PDV_LHS_DAC_LOAD);
08370 }
08371
08372 edt_reg_write(pdv_p, reg, mcl &~ PDV_LHS_DAC_LOAD);
08373 return 0;
08374 }
08375
08383 void
08384 pdv_flush_channel_fifo(PdvDev * pdv_p)
08385 {
08386
08387
08388
08389
08390 pdv_flush_fifo(pdv_p);
08391 }
08392
08411 void
08412 pdv_flush_fifo(PdvDev * pdv_p)
08413 {
08414
08415 if (pdv_p->devid == PDV_ID ||
08416 pdv_p->devid == PDVK_ID ||
08417 pdv_p->devid == PDVFOI_ID ||
08418 pdv_p->devid == PDVA_ID)
08419 {
08420 edt_msg(DBG2, "pdv_flush_fifo() [PCI]\n");
08421 edt_flush_fifo(pdv_p);
08422 return;
08423 }
08424
08425 if (pdv_p->devid == PDVCL_ID ||
08426 pdv_p->devid == PE1DVVL_ID ||
08427 pdv_p->devid == PE4DVVL_ID ||
08428 pdv_p->devid == PE4DVCL_ID ||
08429 pdv_p->devid == PE8DVCL_ID ||
08430 pdv_p->devid == PE4DVVLSIM_ID ||
08431 pdv_p->devid == PE8DVCLS_ID)
08432 {
08433
08434
08435
08436 u_int cfg ;
08437
08438 edt_msg(DBG2, "pdv_flush_fifo() [cameralink]\n");
08439 cfg = edt_intfc_read(pdv_p, PDV_CFG);
08440 cfg &= ~PDV_FIFO_RESET;
08441 edt_intfc_write(pdv_p, PDV_CMD, PDV_RESET_INTFC);
08442 edt_intfc_write(pdv_p, PDV_CFG, (u_char) (cfg | PDV_FIFO_RESET));
08443 edt_intfc_write(pdv_p, PDV_CFG, cfg);
08444 edt_flush_channel(pdv_p, pdv_p->channel_no);
08445
08446 }
08447 else
08448 {
08449
08450
08451 u_int cfg ;
08452
08453 edt_msg(DBG2, "pdv_flush_fifo() [DVFOX, PCIe4/8]");
08454 cfg = edt_intfc_read(pdv_p, PDV_CFG);
08455 cfg &= ~PDV_FIFO_RESET;
08456 edt_intfc_write(pdv_p, PDV_CFG, (u_char) (cfg | PDV_FIFO_RESET));
08457 edt_flush_channel(pdv_p, pdv_p->channel_no);
08458 edt_intfc_write(pdv_p, PDV_CFG, cfg);
08459 }
08460 }
08461
08465 void
08466 pdv_setup_continuous_channel(PdvDev * pdv_p)
08467
08468 {
08469
08470
08471 pdv_setup_continuous(pdv_p);
08472 }
08473
08482 void
08483 pdv_setup_continuous(PdvDev * pdv_p)
08484 {
08485 pdv_flush_fifo(pdv_p);
08486
08487 if (pdv_p->devid == PDV_ID ||
08488 pdv_p->devid == PDVK_ID ||
08489 pdv_p->devid == PDVA_ID)
08490 {
08491
08492 if (edt_get_firstflush(pdv_p) != EDT_ACT_KBS)
08493 edt_set_firstflush(pdv_p, EDT_ACT_ONCE);
08494 }
08495 else
08496 {
08497 edt_set_firstflush(pdv_p,EDT_ACT_NEVER) ;
08498 edt_set_autodir(pdv_p, 0) ;
08499
08500 }
08501
08502 edt_startdma_reg(pdv_p, PDV_CMD, PDV_ENABLE_GRAB);
08503
08504 if (pdv_in_continuous(pdv_p))
08505 {
08506
08507 edt_set_continuous(pdv_p, 1);
08508 }
08509 else if (pdv_p->dd_p->fv_once)
08510 {
08511 pdv_start_hardware_continuous(pdv_p);
08512 }
08513 else
08514 edt_set_continuous(pdv_p, 0);
08515
08516 pdv_p->dd_p->started_continuous = 1;
08517
08518 }
08519
08527 void
08528 pdv_stop_continuous(PdvDev * pdv_p)
08529 {
08530
08531 if (pdv_in_continuous(pdv_p))
08532 {
08533 edt_set_continuous(pdv_p, 0);
08534 }
08535 else if (pdv_p->dd_p->fv_once)
08536 pdv_stop_hardware_continuous(pdv_p);
08537
08538 pdv_p->dd_p->started_continuous = 0;
08539
08540
08541 }
08542
08563 int
08564 pdv_timeout_restart(PdvDev * pdv_p, int restart)
08565 {
08566 int curdone, curtodo;
08567
08568 curdone = edt_done_count(pdv_p);
08569 curtodo = edt_get_todo(pdv_p);
08570
08571 edt_abort_dma(pdv_p);
08572 pdv_stop_continuous(pdv_p);
08573
08574 edt_set_buffer(pdv_p, curdone);
08575 edt_reg_write(pdv_p, PDV_CMD, PDV_RESET_INTFC);
08576 pdv_setup_continuous(pdv_p);
08577
08578 if (restart &&
08579 (curtodo - curdone))
08580 pdv_start_images(pdv_p, curtodo - curdone);
08581
08582 return curtodo - curdone;
08583 }
08584
08586
08587
08588 static char hs[128];
08589 static char *
08590 hex_to_str(char *resp, int n)
08591 {
08592
08593 int i;
08594 char *p = hs;
08595
08596 for (i = 0; i < n; i++)
08597 {
08598 sprintf(p, "%02x ", resp[i]);
08599 p += 3;
08600 }
08601 *p = '\0';
08602 return hs;
08603 }
08604
08605
08616 int
08617 pdv_get_min_shutter(PdvDev * pdv_p)
08618
08619 {
08620 return pdv_p->dd_p->shutter_speed_min;
08621 }
08622
08623
08632 int
08633 pdv_get_max_shutter(PdvDev * pdv_p)
08634
08635 {
08636 return pdv_p->dd_p->shutter_speed_max;
08637 }
08638
08639
08649 int
08650 pdv_get_min_gain(PdvDev * pdv_p)
08651
08652 {
08653 return pdv_p->dd_p->gain_min;
08654 }
08655
08656
08666 int
08667 pdv_get_max_gain(PdvDev * pdv_p)
08668
08669 {
08670 return pdv_p->dd_p->gain_max;
08671 }
08672
08673
08683 int
08684 pdv_get_min_offset(PdvDev * pdv_p)
08685
08686 {
08687 return pdv_p->dd_p->offset_min;
08688 }
08689
08690
08700 int
08701 pdv_get_max_offset(PdvDev * pdv_p)
08702
08703 {
08704 return pdv_p->dd_p->offset_max;
08705 }
08706
08713 int
08714 pdv_enable_lock(PdvDev * pdv_p, int flag)
08715 {
08716 Dependent *dd_p = pdv_p->dd_p;
08717 int ret;
08718
08719 switch (dd_p->lock_shutter)
08720 {
08721 case KODAK_AIA_MCL:
08722 {
08723 int mcl = edt_reg_read(pdv_p, PDV_MODE_CNTL);
08724
08725 if (flag)
08726 mcl |= PDV_AIA_MC3;
08727 else
08728 mcl &= ~PDV_AIA_MC3;
08729
08730 edt_reg_write(pdv_p, PDV_MODE_CNTL, mcl);
08731 ret = 0;
08732 break;
08733 }
08734 case KODAK_AIA_SER:
08735 {
08736 if (flag)
08737 ret = pdv_serial_command(pdv_p, "SHE OF");
08738 else
08739 ret = pdv_serial_command(pdv_p, "SHE ON");
08740
08741 break;
08742 }
08743 case KODAK_SER_14I:
08744 {
08745 if (flag)
08746 ret = pdv_serial_command(pdv_p, "SHE FO");
08747 else
08748 ret = pdv_serial_command(pdv_p, "SHE ON");
08749 break;
08750 }
08751 case HAM_4880:
08752 {
08753 if (flag)
08754 ret = pdv_serial_command(pdv_p, "ASH O");
08755 else
08756 ret = pdv_serial_command(pdv_p, "ASH A");
08757 break;
08758 }
08759 }
08760 return (ret);
08761 }
08762
08763
08768 void
08769 pdv_send_break(PdvDev * pdv_p)
08770 {
08771 u_int reg;
08772
08773 edt_msg(DBG2, "pdv_send_break()");
08774
08775 reg = edt_reg_read(pdv_p, PDV_UTIL2);
08776 edt_reg_write(pdv_p, PDV_UTIL2, reg & ~PDV_MC4);
08777 edt_reg_write(pdv_p, PDV_UTIL2, (reg | PDV_SEL_MC4) & ~PDV_MC4);
08778 edt_msleep(500);
08779 edt_reg_write(pdv_p, PDV_UTIL2, reg & ~PDV_SEL_MC4 & ~PDV_MC4);
08780 edt_reg_write(pdv_p, PDV_UTIL2, reg);
08781 }
08782
08783 static void
08784 pdv_trigger_specinst(PdvDev * pdv_p)
08785 {
08786 char cmd = pdv_p->dd_p->serial_trigger[0];
08787
08788 edt_msg(DBG2, "pdv_trigger_specinst('%c')\n", cmd);
08789
08790 pdv_serial_binary_command(pdv_p, &cmd, 1);
08791
08792 }
08793
08797 static void
08798 pdv_posttrigger_specinst(PdvDev * pdv_p)
08799 {
08800 char cmd = pdv_p->dd_p->serial_trigger[0];
08801 char resp[32];
08802 int ret;
08803 int waitcnt = 2;
08804
08805 resp[0] = resp[1] = resp[2] = 0;
08806
08807 #ifdef SPECINST_WAS
08808 if (pdv_p->devid == PDVFOI_ID)
08809 waitcnt += 2;
08810 if ((ret = pdv_serial_wait(pdv_p, 1500, waitcnt)) == waitcnt)
08811 pdv_serial_read(pdv_p, resp, ret);
08812 #else
08813 if (pdv_p->devid == PDVFOI_ID)
08814 pdv_serial_wait_next(pdv_p, 2000, 0);
08815 else
08816 pdv_serial_wait_next(pdv_p, 2000, 1);
08817 ret = pdv_serial_read(pdv_p, resp, 2);
08818 #endif
08819
08820 if ((ret != waitcnt)
08821 || (resp[0] != pdv_p->dd_p->serial_trigger[0])
08822 || (resp[1] != pdv_p->dd_p->serial_response[0]))
08823 {
08824 edt_msg(DBG2, "\npdv_posttrigger_specinst: invalid/missing serial?\n");
08825 edt_msg(DBG2, "response (sent %c, ret %d s/b %d, resp <%s>)\n", cmd, ret, waitcnt, (ret > 0) ? resp : "");
08826 return;
08827 }
08828 }
08829
08830 static int
08831 pdv_specinst_serial_triggered(PdvDev * pdv_p)
08832 {
08833 if (((pdv_p->dd_p->camera_shutter_timing == SPECINST_SERIAL)
08834 || (pdv_p->dd_p->camera_shutter_speed == SPECINST_SERIAL))
08835 && (pdv_p->dd_p->serial_trigger[0]))
08836 return 1;
08837 return 0;
08838 }
08839
08840 int
08841 pdv_pause_for_serial(PdvDev * pdv_p)
08842 {
08843 return pdv_p->dd_p->pause_for_serial;
08844 }
08845
08846
08847 static int
08848 isafloat(char *str)
08849 {
08850 unsigned int i;
08851 int numdots = 0;
08852 int numchars = 0;
08853
08854 for (i = 0; i < strlen(str); i++)
08855 {
08856 if (str[i] == '.')
08857 ++numdots;
08858 else if (isdigit(str[i]))
08859 ++numchars;
08860 else
08861 return 0;
08862 }
08863
08864 if (numdots == 1 && numchars > 0)
08865 return 1;
08866 return 0;
08867 }
08868
08869 static int
08870 isdigits(char *str)
08871 {
08872 unsigned int i;
08873 int numchars = 0;
08874
08875 for (i = 0; i < strlen(str); i++)
08876 {
08877 if (isdigit(str[i]))
08878 ++numchars;
08879 else if ((str[i] == '-') && (i == 0))
08880 ;
08881 else
08882 return 0;
08883 }
08884
08885 if (numchars > 0)
08886 return 1;
08887 return 0;
08888 }
08889
08890 static int
08891 isxdigits(char *str)
08892 {
08893 unsigned int i;
08894 int numchars = 0;
08895
08896 for (i = 0; i < strlen(str); i++)
08897 {
08898 if (isxdigit(str[i]))
08899 ++numchars;
08900 else
08901 return 0;
08902 }
08903
08904 if (numchars > 0)
08905 return 1;
08906 return 0;
08907 }
08908
08918 int
08919 pdv_is_kodak_i(PdvDev * pdv_p)
08920 {
08921 Dependent *dd_p = pdv_p->dd_p;
08922
08923 if ((strcmp(dd_p->serial_exposure, "EXE") == 0)
08924 || (strcmp(dd_p->serial_gain, "DGN") == 0)
08925 || (strcmp(dd_p->serial_offset, "GAE") == 0)
08926 || (strcmp(dd_p->serial_offset, "BKE") == 0))
08927 return 1;
08928 return 0;
08929 }
08930
08931
08942 int
08943 pdv_is_atmel(PdvDev * pdv_p)
08944 {
08945 Dependent *dd_p = pdv_p->dd_p;
08946
08947 if ((strncasecmp(dd_p->camera_class, "Atmel", 5) == 0)
08948 || (strncmp(dd_p->serial_exposure, "I=", 2) == 0))
08949 return 1;
08950 return 0;
08951 }
08952
08960 int
08961 pdv_is_hamamatsu(PdvDev * pdv_p)
08962 {
08963 Dependent *dd_p = pdv_p->dd_p;
08964
08965 if ((strncasecmp(dd_p->camera_class, "Hamamatsu", 9) == 0))
08966 return 1;
08967 return 0;
08968 }
08969
08970
08982 int
08983 pdv_update_values_from_camera(PdvDev * pdv_p)
08984 {
08985 int ret = 0;
08986
08987 if (pdv_is_kodak_i(pdv_p))
08988 ret = pdv_update_from_kodak_i(pdv_p);
08989 else if (pdv_is_dvc(pdv_p))
08990 ret = pdv_update_from_dvc(pdv_p);
08991 else if (pdv_is_atmel(pdv_p))
08992 ret = pdv_update_from_atmel(pdv_p);
08993 else if (pdv_is_hamamatsu(pdv_p))
08994 ret = pdv_update_from_hamamatsu(pdv_p);
08995
08996 else
08997 ret = -1;
08998
08999 return ret;
09000 }
09001
09011 static int
09012 pdv_update_from_kodak_i(PdvDev * pdv_p)
09013 {
09014 int i, n, ret = 0;
09015 char *stat[64];
09016 char **stat_p = stat;
09017 Dependent *dd_p = pdv_p->dd_p;
09018
09019 for (i = 0; i < 64; i++)
09020 {
09021 *stat_p = (char *) malloc(64 * sizeof(char));
09022 **stat_p = '\0';
09023 ++stat_p;
09024 }
09025
09026 if ((n = pdv_query_serial(pdv_p, "STS?", stat)) < 1)
09027 ret = -1;
09028 else
09029 {
09030 update_int_from_serial(stat, n, "BKE", &dd_p->level);
09031 update_int_from_serial(stat, n, "GAE", &dd_p->gain);
09032 update_int_from_serial(stat, n, "DGN", &dd_p->gain);
09033 update_int_from_serial(stat, n, "EXE", &dd_p->shutter_speed);
09034 update_int_from_serial(stat, n, "BNS", &dd_p->binx);
09035 update_int_from_serial(stat, n, "BNS", &dd_p->biny);
09036 }
09037
09038 for (i = 0; i < 64; i++)
09039 free(stat[i]);
09040
09041 return ret;
09042 }
09043
09053 static int
09054 pdv_update_from_hamamatsu(PdvDev * pdv_p)
09055 {
09056 int i, n, ret = 0;
09057 char *stat[64];
09058 char **stat_p = stat;
09059 Dependent *dd_p = pdv_p->dd_p;
09060
09061 for (i = 0; i < 64; i++)
09062 {
09063 *stat_p = (char *) malloc(64 * sizeof(char));
09064 **stat_p = '\0';
09065 ++stat_p;
09066 }
09067
09068 if ((n = pdv_query_serial(pdv_p, "?CEG", stat)) < 1)
09069 ret = -1;
09070 else
09071 update_int_from_serial(stat, n, "CEG", &dd_p->gain);
09072
09073 if ((n = pdv_query_serial(pdv_p, "?CEO", stat)) < 1)
09074 ret = -1;
09075 else
09076 update_int_from_serial(stat, n, "CEO", &dd_p->level);
09077
09078 if ((n = pdv_query_serial(pdv_p, "?SHT", stat)) < 1)
09079 ret = -1;
09080 else
09081 update_int_from_serial(stat, n, "SHT", &dd_p->shutter_speed);
09082
09083 for (i = 0; i < 64; i++)
09084 free(stat[i]);
09085
09086 return ret;
09087 }
09088
09089
09099 static int
09100 pdv_update_from_atmel(PdvDev * pdv_p)
09101 {
09102 int i, n, ret = 0;
09103 int tmpval;
09104 char *stat[64];
09105 char **stat_p = stat;
09106 Dependent *dd_p = pdv_p->dd_p;
09107
09108 for (i = 0; i < 64; i++)
09109 {
09110 *stat_p = (char *) malloc(64 * sizeof(char));
09111 **stat_p = '\0';
09112 ++stat_p;
09113 }
09114
09115 if ((n = pdv_query_serial(pdv_p, "!=3", stat)) < 1)
09116 ret = -1;
09117 else
09118 {
09119 update_int_from_serial(stat, n, "G", &dd_p->gain);
09120 update_int_from_serial(stat, n, "I", &dd_p->shutter_speed);
09121 if (update_int_from_serial(stat, n, "B", &tmpval) == 0)
09122 dd_p->binx = dd_p->biny = tmpval + 1;
09123 }
09124
09125 for (i = 0; i < 64; i++)
09126 free(stat[i]);
09127
09128 return ret;
09129 }
09130
09137 int
09138 pdv_query_serial(PdvDev * pdv_p, char *cmd, char **resp)
09139 {
09140
09141 char *buf_p;
09142 char buf[2048];
09143 int length;
09144 int ret;
09145 int i, j, l;
09146 int nfound = 0;
09147
09148 {
09149 char *tmp_storage;
09150 if ((tmp_storage = (char *)malloc(strlen(cmd)+1)) == NULL)
09151 return 0;
09152 sprintf(tmp_storage, "%s\r", cmd);
09153 edt_msg(DBG2, "pdv_query_serial: writing <%s>\n", cmd);
09154 pdv_serial_command(pdv_p, tmp_storage);
09155 free(tmp_storage);
09156 }
09157
09158
09159
09160
09161 pdv_serial_wait(pdv_p, pdv_p->dd_p->serial_timeout, 64);
09162
09163
09164
09165
09166
09167 buf_p = buf;
09168 length = 0;
09169 do
09170 {
09171 ret = pdv_serial_read(pdv_p, buf_p, 2048 - length);
09172 edt_msg(DBG2, "read returned %d\n", ret);
09173
09174 if (ret != 0)
09175 {
09176 buf_p[ret + 1] = 0;
09177 buf_p += ret;
09178 length += ret;
09179 }
09180 pdv_serial_wait(pdv_p, 500, 64);
09181 } while (ret > 0);
09182
09183
09184
09185
09186 i = 0;
09187 j = 0;
09188 buf_p = buf;
09189 for (l = 0; l < length; l++)
09190 {
09191 if ((*buf_p == '\n') || (*buf_p == '\r'))
09192 {
09193 if (j != 0)
09194 {
09195 resp[i++][j] = '\0';
09196 j = 0;
09197 }
09198 }
09199 else
09200 {
09201 if (j == 0)
09202 ++nfound;
09203 resp[i][j++] = *buf_p;
09204 resp[i][j] = '\0';
09205 }
09206
09207 ++buf_p;
09208 }
09209
09210
09211 return nfound;
09212 }
09213
09218 static int
09219 update_int_from_serial(char **stat, int nstats, char *cmd, int *value)
09220 {
09221 int i, ret = -1;
09222 int len = (int) strlen(cmd);
09223 double tmpf;
09224 char *arg;
09225
09226
09227
09228
09229 for (i = 0; i < nstats; i++)
09230 {
09231 arg = &stat[i][len + 1];
09232 if ((strncmp(stat[i], cmd, len) == 0)
09233 && ((stat[i][len] == ' ') || (stat[i][len] == '=')))
09234 {
09235 if (isdigits(arg))
09236 {
09237 *value = atoi(arg);
09238 ret = 0;
09239 }
09240
09241 else if ((isafloat(arg) && strncmp(cmd, "EXE", 3) == 0))
09242 {
09243 tmpf = atof(arg);
09244 *value = (int) (tmpf / 0.063);
09245 ret = 0;
09246 }
09247 }
09248 }
09249 return ret;
09250 }
09251
09256 static int
09257 update_string_from_serial(char **stat, int nstats, char *cmd, char *value, int maxlen)
09258 {
09259 int i, ret = -1;
09260 int len = (int) strlen(cmd);
09261 char *arg;
09262
09263
09264
09265
09266 for (i = 0; i < nstats; i++)
09267 {
09268 arg = &stat[i][len + 1];
09269 if ((strncmp(stat[i], cmd, len) == 0)
09270 && ((stat[i][len] == ' ') || (stat[i][len] == '=')))
09271 {
09272 strncpy(value, stat[i] + len + 1, maxlen);
09273 }
09274 }
09275 return ret;
09276 }
09277
09282 static void
09283 update_2dig_from_serial(char **stat, int nstats, char *cmd, int *val1, int *val2)
09284 {
09285 int i;
09286 int len = (int) strlen(cmd);
09287 char *arg;
09288
09289
09290
09291
09292 for (i = 0; i < nstats; i++)
09293 {
09294 arg = &stat[i][len + 1];
09295 if ((strncmp(stat[i], cmd, len) == 0)
09296 && (stat[i][len] == ' '))
09297 {
09298 if (isdigits(arg) && strlen(arg) == 2)
09299 {
09300 *val1 = arg[0] - '0';
09301 *val2 = arg[1] - '0';
09302 }
09303 }
09304 }
09305 }
09306
09311 static void
09312 update_hex_from_serial(char **stat, int nstats, char *cmd, int *value)
09313 {
09314 int i;
09315 size_t len = strlen(cmd);
09316 char *arg;
09317
09318
09319
09320
09321 for (i = 0; i < nstats; i++)
09322 {
09323 arg = &stat[i][len + 1];
09324 if ((strncmp(stat[i], cmd, len) == 0)
09325 && (stat[i][len] == ' '))
09326 {
09327 if (isxdigits(arg))
09328 {
09329 *value = strtol(arg, NULL, 16);
09330 }
09331 }
09332 }
09333 }
09334
09335
09347 int
09348 pdv_set_mode(PdvDev * pdv_p, char *mode, int mcl)
09349 {
09350 edt_msg(PDVWARN, "pdv_set_aperture is OBSOLETE\n");
09351 return -1;
09352 }
09353
09354
09355 int
09356 pdv_set_mode_atmel(PdvDev * pdv_p, char *mode)
09357 {
09358 Dependent *dd_p = pdv_p->dd_p;
09359 int cfg = 0;
09360
09361 if ((strcmp(mode, "T=0") == 0)
09362 || (strcmp(mode, "T=1") == 0))
09363 {
09364 if (strcmp(mode, "T=0") == 0)
09365 {
09366 dd_p->shutter_speed_min = 0;
09367 dd_p->shutter_speed_max = 0;
09368 }
09369 else
09370 {
09371 dd_p->shutter_speed_min = 1;
09372 dd_p->shutter_speed_max = 2000;
09373 }
09374 dd_p->camera_shutter_timing = AIA_SERIAL;
09375 dd_p->trig_pulse = 1;
09376
09377 dd_p->mode_cntl_norm = 0x0;
09378 edt_reg_write(pdv_p, PDV_MODE_CNTL, dd_p->mode_cntl_norm);
09379 cfg = edt_reg_read(pdv_p, PDV_CFG) | PDV_TRIG | PDV_INV_SHUTTER;
09380 edt_reg_write(pdv_p, PDV_CFG, cfg);
09381 pdv_serial_command(pdv_p, mode);
09382 strcpy(dd_p->serial_exposure, "I=");
09383 }
09384 else if (strcmp(mode, "T=2") == 0)
09385 {
09386 dd_p->timeout_multiplier = 1;
09387 dd_p->shutter_speed_min = 1;
09388 dd_p->shutter_speed_max = 0x414;
09389 dd_p->camera_shutter_timing = AIA_SERIAL;
09390 dd_p->trig_pulse = 1;
09391 dd_p->mode_cntl_norm = 0x10;
09392 edt_reg_write(pdv_p, PDV_MODE_CNTL, dd_p->mode_cntl_norm);
09393 cfg = edt_reg_read(pdv_p, PDV_CFG) | PDV_TRIG;
09394 edt_reg_write(pdv_p, PDV_CFG, cfg);
09395 pdv_serial_command(pdv_p, mode);
09396 strcpy(dd_p->serial_exposure, "I=");
09397 }
09398 else if (strcmp(mode, "T=3") == 0)
09399 {
09400 dd_p->timeout_multiplier = 1;
09401 dd_p->shutter_speed_min = 1;
09402 dd_p->shutter_speed_max = 25500;
09403 dd_p->camera_shutter_timing = AIA_MCL;
09404 dd_p->trig_pulse = 0;
09405 dd_p->mode_cntl_norm = 0x10;
09406 edt_reg_write(pdv_p, PDV_MODE_CNTL, dd_p->mode_cntl_norm);
09407 cfg = edt_reg_read(pdv_p, PDV_CFG) & ~PDV_TRIG;
09408 edt_reg_write(pdv_p, PDV_CFG, cfg);
09409 pdv_serial_command(pdv_p, mode);
09410 dd_p->serial_exposure[0] = '\0';
09411 }
09412 else
09413 {
09414 edt_msg(PDVWARN, "WARNING: unsupported ATMEL mode: %s\n", mode);
09415 return -1;
09416 }
09417 return 0;
09418 }
09419
09423 int
09424 pdv_set_mode_kodak(PdvDev * pdv_p, char *mode)
09425 {
09426 Dependent *dd_p = pdv_p->dd_p;
09427 char cmd[32];
09428 int cfg = 0;
09429
09430 if (strcmp(mode, "CS") == 0)
09431 {
09432 dd_p->shutter_speed_min = 1;
09433 dd_p->shutter_speed_max = 512;
09434 dd_p->camera_shutter_timing = AIA_SERIAL;
09435 dd_p->trig_pulse = 1;
09436
09437 dd_p->mode_cntl_norm = 0x0;
09438 edt_reg_write(pdv_p, PDV_MODE_CNTL, dd_p->mode_cntl_norm);
09439 cfg = edt_reg_read(pdv_p, PDV_CFG) | PDV_TRIG | PDV_INV_SHUTTER;
09440 edt_reg_write(pdv_p, PDV_CFG, cfg);
09441 sprintf(cmd, "MDE %s", mode);
09442 pdv_serial_command(pdv_p, cmd);
09443 strcpy(dd_p->serial_exposure, "EXE");
09444 }
09445 else if (strcmp(mode, "TR") == 0)
09446 {
09447 dd_p->shutter_speed_min = 1;
09448 dd_p->shutter_speed_max = 255;
09449 dd_p->camera_shutter_timing = AIA_SERIAL;
09450 dd_p->trig_pulse = 1;
09451 dd_p->mode_cntl_norm = 0x10;
09452 edt_reg_write(pdv_p, PDV_MODE_CNTL, dd_p->mode_cntl_norm);
09453 cfg = edt_reg_read(pdv_p, PDV_CFG) | PDV_TRIG;
09454 edt_reg_write(pdv_p, PDV_CFG, cfg);
09455 sprintf(cmd, "MDE %s", mode);
09456 pdv_serial_command(pdv_p, cmd);
09457 strcpy(dd_p->serial_exposure, "EXE");
09458 }
09459 else if (strcmp(mode, "CD") == 0)
09460 {
09461 dd_p->shutter_speed_min = 1;
09462 dd_p->shutter_speed_max = 25500;
09463 dd_p->camera_shutter_timing = AIA_MCL;
09464 dd_p->trig_pulse = 0;
09465 dd_p->mode_cntl_norm = 0x10;
09466 edt_reg_write(pdv_p, PDV_MODE_CNTL, dd_p->mode_cntl_norm);
09467 cfg = edt_reg_read(pdv_p, PDV_CFG) & ~PDV_TRIG;
09468 edt_reg_write(pdv_p, PDV_CFG, cfg);
09469 sprintf(cmd, "MDE %s", mode);
09470 pdv_serial_command(pdv_p, cmd);
09471 dd_p->serial_exposure[0] = '\0';
09472 }
09473 else
09474 {
09475 edt_msg(PDVWARN, "WARNING: unsupported DVC mode: %s\n", mode);
09476 return -1;
09477 }
09478 return 0;
09479 }
09480
09481 int
09482 pdv_set_mode_hamamatsu(PdvDev * pdv_p, char *mode)
09483 {
09484 #if 0
09485 Dependent *dd_p = pdv_p->dd_p;
09486 int cfg = 0;
09487 int cont = 0;
09488 #endif
09489
09490
09491
09492 return 0;
09493
09494 }
09495
09497
09498
09499
09500
09501
09502
09510 int
09511 pdv_is_dvc(PdvDev * pdv_p)
09512 {
09513 Dependent *dd_p = pdv_p->dd_p;
09514
09515 if ((strncasecmp(dd_p->camera_class, "DVC", 3) == 0)
09516 || (strncmp(dd_p->serial_exposure, "EXP", 3) == 0))
09517 return 1;
09518 return 0;
09519 }
09520
09529 int
09530 pdv_set_binning_dvc(PdvDev * pdv_p, int xval, int yval)
09531 {
09532 int ret = 0;
09533 char cmdstr[64];
09534 Dependent *dd_p = pdv_p->dd_p;
09535
09536 sprintf(cmdstr, "%s %d%d", dd_p->serial_binning, yval, xval);
09537
09538 pdv_serial_command(pdv_p, cmdstr);
09539
09540 return (ret);
09541 }
09542
09543 int
09544 pdv_update_from_dvc(PdvDev * pdv_p)
09545 {
09546 int i, n, ret = 0;
09547 char *stat[64];
09548 char **stat_p = stat;
09549 Dependent *dd_p = pdv_p->dd_p;
09550
09551 for (i = 0; i < 64; i++)
09552 {
09553 *stat_p = (char *) malloc(64 * sizeof(char));
09554 **stat_p = '\0';
09555 ++stat_p;
09556 }
09557
09558 if ((n = pdv_query_serial(pdv_p, "STA", stat)) < 1)
09559 ret = -1;
09560 else
09561 {
09562 update_hex_from_serial(stat, n, "OFS", &dd_p->level);
09563 update_hex_from_serial(stat, n, "GAI", &dd_p->gain);
09564 update_hex_from_serial(stat, n, "EXP", &dd_p->shutter_speed);
09565 update_2dig_from_serial(stat, n, "BIN", &dd_p->binx, &dd_p->biny);
09566 }
09567
09568 for (i = 0; i < 64; i++)
09569 free(stat[i]);
09570
09571 return ret;
09572 }
09573
09574
09575 int
09576 pdv_set_mode_dvc(PdvDev * pdv_p, char *mode)
09577 {
09578 Dependent *dd_p = pdv_p->dd_p;
09579 char cmd[32];
09580 int cfg = 0;
09581
09582 if ((strcmp(mode, "NOR") == 0)
09583 || (strcmp(mode, "ULT") == 0)
09584 || (strcmp(mode, "HNL") == 0)
09585 || (strcmp(mode, "HDL") == 0)
09586 || (strcmp(mode, "NFR") == 0)
09587 || (strcmp(mode, "NRR") == 0))
09588 {
09589 if (mode[0] == 'H')
09590 {
09591 dd_p->shutter_speed_min = 1;
09592 dd_p->shutter_speed_max = 0x414;
09593 }
09594 else
09595 {
09596 if (strcmp(mode, "ULT") == 0)
09597 dd_p->timeout_multiplier = 10;
09598 else if (strcmp(mode, "NFR") == 0)
09599 dd_p->timeout_multiplier = 5;
09600 else
09601 dd_p->timeout_multiplier = 1;
09602
09603 dd_p->shutter_speed_min = 1;
09604 dd_p->shutter_speed_max = 0x7ff;
09605 }
09606 dd_p->camera_shutter_timing = AIA_SERIAL;
09607 dd_p->trig_pulse = 1;
09608
09609 dd_p->mode_cntl_norm = 0x0;
09610 edt_reg_write(pdv_p, PDV_MODE_CNTL, dd_p->mode_cntl_norm);
09611 cfg = edt_reg_read(pdv_p, PDV_CFG) | PDV_TRIG | PDV_INV_SHUTTER;
09612 edt_reg_write(pdv_p, PDV_CFG, cfg);
09613 sprintf(cmd, "MDE %s", mode);
09614 pdv_serial_command(pdv_p, cmd);
09615 strcpy(dd_p->serial_exposure, "EXP");
09616 }
09617 else if (strcmp(mode, "HDO") == 0)
09618 {
09619 dd_p->timeout_multiplier = 1;
09620 dd_p->shutter_speed_min = 1;
09621 dd_p->shutter_speed_max = 0x414;
09622 dd_p->camera_shutter_timing = AIA_SERIAL;
09623 dd_p->trig_pulse = 1;
09624 dd_p->mode_cntl_norm = 0x10;
09625 edt_reg_write(pdv_p, PDV_MODE_CNTL, dd_p->mode_cntl_norm);
09626 cfg = edt_reg_read(pdv_p, PDV_CFG) | PDV_TRIG;
09627 edt_reg_write(pdv_p, PDV_CFG, cfg);
09628 sprintf(cmd, "MDE %s", mode);
09629 pdv_serial_command(pdv_p, cmd);
09630 strcpy(dd_p->serial_exposure, "EXP");
09631 }
09632 else if (strcmp(mode, "PDX") == 0)
09633 {
09634 dd_p->timeout_multiplier = 1;
09635 dd_p->shutter_speed_min = 1;
09636 dd_p->shutter_speed_max = 25500;
09637 dd_p->camera_shutter_timing = AIA_MCL;
09638 dd_p->trig_pulse = 0;
09639 dd_p->mode_cntl_norm = 0x10;
09640 edt_reg_write(pdv_p, PDV_MODE_CNTL, dd_p->mode_cntl_norm);
09641 cfg = edt_reg_read(pdv_p, PDV_CFG) & ~PDV_TRIG;
09642 edt_reg_write(pdv_p, PDV_CFG, cfg);
09643 sprintf(cmd, "MDE %s", mode);
09644 pdv_serial_command(pdv_p, cmd);
09645 dd_p->serial_exposure[0] = '\0';
09646 }
09647 else
09648 {
09649 edt_msg(PDVWARN, "WARNING: unsupported DVC mode: %s\n", mode);
09650 return -1;
09651 }
09652 return 0;
09653 }
09654
09655 int
09656 pdv_get_dvc_state(PdvDev * pdv_p, DVCState * pState)
09657
09658 {
09659 int i, n, ret = 0;
09660 char *stat[64];
09661 char **stat_p = stat;
09662 Dependent *dd_p = pdv_p->dd_p;
09663
09664 for (i = 0; i < 64; i++)
09665 {
09666 *stat_p = (char *) malloc(64 * sizeof(char));
09667 **stat_p = '\0';
09668 ++stat_p;
09669 }
09670
09671 if ((n = pdv_query_serial(pdv_p, "STA", stat)) < 1)
09672 ret = -1;
09673 else
09674 {
09675 update_hex_from_serial(stat, n, "OFS", &dd_p->level);
09676 update_hex_from_serial(stat, n, "GAI", &dd_p->gain);
09677 update_hex_from_serial(stat, n, "EXP", &dd_p->shutter_speed);
09678 update_2dig_from_serial(stat, n, "BIN", &dd_p->binx, &dd_p->biny);
09679 }
09680
09681 pState->binx = dd_p->binx;
09682 pState->biny = dd_p->biny;
09683 pState->blackoffset = dd_p->level;
09684 pState->exposure = dd_p->shutter_speed;
09685 pState->gain = dd_p->gain;
09686
09687 update_string_from_serial(stat, n, "MDE", pState->mode, 3);
09688
09689 for (i = 0; i < 64; i++)
09690 free(stat[i]);
09691
09692 return ret;
09693
09694
09695 }
09696
09697
09718 void
09719 pdv_enable_external_trigger(PdvDev * pdv_p, int flag)
09720 {
09721 int mask = PDV_PHOTO_TRIGGER | PDV_FLDID_TRIGGER;
09722 int util2 = edt_reg_read(pdv_p, PDV_UTIL2);
09723 int bit = 0;
09724
09725 if (flag & 1)
09726 bit &= PDV_PHOTO_TRIGGER;
09727 if (flag & 2)
09728 bit &= PDV_FLDID_TRIGGER;
09729
09730 if (flag)
09731 edt_reg_write(pdv_p, PDV_UTIL2, util2 | flag);
09732 else
09733 edt_reg_write(pdv_p, PDV_UTIL2, util2 & ~mask);
09734 }
09735
09736
09737
09744 void
09745 pdv_start_expose(PdvDev * pdv_p)
09746
09747 {
09748 edt_reg_write(pdv_p, PDV_CMD, PDV_EXP_STROBE);
09749 }
09750
09751
09759 void
09760 pdv_invert_fval_interrupt(PdvDev * pdv_p)
09761
09762 {
09763
09764 edt_reg_or(pdv_p, PDV_UTIL3, PDV_FV_INT_INVERT);
09765 }
09766
09800 int
09801 pdv_set_frame_period(PdvDev *pdv_p, int period, int method)
09802 {
09803 u_int util3 = edt_reg_read(pdv_p, PDV_UTIL3);
09804
09805 if (pdv_p->dd_p->register_wrap)
09806 return -1;
09807
09808 edt_reg_write(pdv_p, PDV_FRAME_PERIOD0, period & 0xff);
09809 edt_reg_write(pdv_p, PDV_FRAME_PERIOD1, (period >> 8) & 0xff);
09810 edt_reg_write(pdv_p, PDV_FRAME_PERIOD2, (period >> 16) & 0xff);
09811
09812 if (method == 0)
09813 edt_reg_write(pdv_p, PDV_UTIL3, util3 & ~(PDV_FRENA | PDV_FVADJ));
09814 else if (method == PDV_FMRATE_ENABLE)
09815 edt_reg_write(pdv_p, PDV_UTIL3, (util3 | PDV_FRENA) & ~PDV_FVADJ);
09816 else if (method == PDV_FVAL_ADJUST)
09817 edt_reg_write(pdv_p, PDV_UTIL3, (util3 | PDV_FVADJ) & ~PDV_FRENA);
09818
09819 return 0;
09820 }
09821
09840 int
09841 pdv_get_frame_period(PdvDev *pdv_p)
09842 {
09843 int period;
09844
09845 period = edt_reg_read(pdv_p, PDV_FRAME_PERIOD0);
09846 period |= (edt_reg_read(pdv_p, PDV_FRAME_PERIOD1) & 0xff) << 8;
09847 period |= (edt_reg_read(pdv_p, PDV_FRAME_PERIOD2) & 0xff) << 16;
09848
09849 return period;
09850 }
09851
09870 void
09871 pdv_serial_txrx(PdvDev * pdv_p, char *txbuf, int txcount, char *rxbuf, int rxcount, int timeout, u_char *wchar)
09872 {
09873 int n, ena;
09874 u_char savec;
09875 int respflag = 0;
09876 char dmybuf[1024];
09877
09878 if (rxcount == 0)
09879 respflag = SCFLAG_NORESP;
09880
09881 ena = pdv_get_waitchar(pdv_p, &savec);
09882
09883
09884
09885
09886 if ((n = pdv_serial_wait(pdv_p, 1, 1024)) != 0)
09887 pdv_serial_read(pdv_p, dmybuf, n);
09888
09889 if (*wchar)
09890 pdv_set_waitchar(pdv_p, 1, *wchar);
09891
09892 pdv_serial_binary_command_flagged(pdv_p, txbuf, txcount, respflag);
09893
09894 if ((n = pdv_serial_wait(pdv_p, timeout, rxcount)) != 0)
09895 pdv_serial_read(pdv_p, rxbuf, n);
09896
09897
09898 pdv_set_waitchar(pdv_p, ena, savec);
09899 }
09900
09901
09916 int
09917 pdv_is_cameralink(PdvDev *pdv_p)
09918 {
09919 if (edt_is_dvcl(pdv_p))
09920 return 1;
09921
09922
09923
09924
09925
09926
09927
09928
09929
09930 if (pdv_p->dd_p->cameralink)
09931 return 1;
09932
09933 return 0;
09934 }
09935
09946 int
09947 pdv_is_simulator(PdvDev *pdv_p)
09948 {
09949 char xilinx_name[256];
09950
09951 edt_flash_get_fname_auto(pdv_p, xilinx_name);
09952
09953
09954 if (edt_is_dvcl2(pdv_p))
09955 return 1;
09956
09957
09958
09959
09960
09961 if (pdv_p->devid == PE4DVCL_ID)
09962 {
09963 if ((strncmp(xilinx_name, "pedvclsim", 9) == 0)
09964 || (strncmp(xilinx_name, "pe4dvcls", 8) == 0))
09965 return 1;
09966 }
09967
09968 return 0;
09969 }
09970
09971
10004 void
10005 pdv_set_fval_done(PdvDev *pdv_p, int enable)
10006
10007 {
10008 u_int i = (enable != 0);
10009
10010 edt_ioctl(pdv_p, EDTS_FVAL_DONE, &i);
10011
10012 if (enable != PDV_TRIGINT)
10013 {
10014 edt_reg_and(pdv_p, PDV_UTIL3, ~PDV_TRIGINT);
10015 }
10016
10017 pdv_p->dd_p->fval_done = enable;
10018 edt_set_dependent(pdv_p, pdv_p->dd_p);
10019
10020 }
10021
10022 int
10023 pdv_get_fval_done(PdvDev *pdv_p)
10024
10025 {
10026 return pdv_p->dd_p->fval_done;
10027
10028 }
10029
10030
10047 int
10048 pdv_get_lines_xferred(PdvDev *pdv_p)
10049
10050 {
10051 u_int rasterlines = 0;
10052
10053 if (pdv_p->ring_buffer_numbufs)
10054 rasterlines = (pdv_p->donecount-1) % pdv_p->ring_buffer_numbufs;
10055
10056 edt_ioctl(pdv_p, EDTG_LINES_XFERRED, &rasterlines);
10057
10058 return (rasterlines & 0xffff);
10059
10060 }
10061
10077 int
10078 pdv_get_width_xferred(PdvDev *pdv_p)
10079
10080 {
10081 u_int rasterlines = (pdv_p->donecount-1) % pdv_p->ring_buffer_numbufs;
10082
10083 edt_ioctl(pdv_p, EDTG_LINES_XFERRED, &rasterlines);
10084
10085 return ((rasterlines >> 16) & 0xffff);
10086
10087 }
10088
10105 int
10106 pdv_cl_get_fv_counter(PdvDev *pdv_p)
10107
10108 {
10109 return edt_reg_read(pdv_p, PDV_CL_FRMCNT);
10110 }
10111
10112
10121 void
10122 pdv_cl_reset_fv_counter(PdvDev *pdv_p)
10123
10124 {
10125 edt_reg_write(pdv_p, PDV_CL_FRMCNT_RESET, 1);
10126 edt_reg_write(pdv_p, PDV_CL_FRMCNT_RESET, 0);
10127 }
10128
10145 int
10146 pdv_cl_camera_connected(PdvDev *pdv_p)
10147
10148 {
10149 int i, reg, ppl=0, changed=0;
10150
10151 if (!pdv_is_cameralink(pdv_p))
10152 return 0;
10153
10154 reg = edt_reg_read(pdv_p, PDV_UTILITY);
10155
10156
10157 edt_reg_or(pdv_p, PDV_CL_CFG2, PDV_CL_CFG2_PCLVFREE);
10158 for (i=0; i<5; i++)
10159 {
10160 int p;
10161
10162 if ((p = edt_reg_read(pdv_p, PDV_CL_PIXELSPERLINE)) != ppl)
10163 ++changed;
10164 ppl = p;
10165 edt_msleep(1);
10166 }
10167
10168 edt_reg_write(pdv_p, PDV_UTILITY, reg);
10169
10170 if (changed < 2)
10171 return 0;
10172 return 1;
10173 }
10174
10176 void
10177 pdv_new_debug(int val)
10178 {
10179 int level ;
10180 Pdv_debug = val ;
10181 level = edt_msg_default_level();
10182 if (Pdv_debug > 0)
10183 {
10184 level |= DBG1;
10185 level |= DBG2;
10186 }
10187 edt_msg_set_level(edt_msg_default_handle(), level);
10188 }
10189
10190 #ifdef DOXYGEN_SHOW_UNDOC
10191
10192 #endif
10193
10194
10195 int
10196 pdv_get_rawio_size(PdvDev *pdv_p)
10197
10198 {
10199 int size = pdv_get_dmasize(pdv_p);
10200
10201 if (size % 512)
10202 size = (((size/512)+1)*512);
10203
10204 return size;
10205
10206 }
10207
10208
10209
10210
10211 void
10212 checkfpga_dep_wait(pdv_p)
10213 {
10214 }
10215
10216 void
10217 pdv_check_fpga_rev(PdvDev *pdv_p)
10218 {
10219 PdvDependent *dd_p = pdv_p->dd_p;
10220
10221 if (dd_p->xilinx_rev == NOT_SET)
10222 {
10223 int rev;
10224
10225 edt_msg(DEBUG2, "checking for new rev xilinx\n");
10226 checkfpga_dep_wait(pdv_p);
10227
10228 pdv_flush_fifo(pdv_p);
10229
10230 edt_reg_write(pdv_p, PDV_STAT, 0xff);
10231 rev = edt_reg_read(pdv_p, PDV_REV);
10232 if (rev >= 1 && rev <= 32)
10233 {
10234 edt_msg(DEBUG2, "xilinx rev set to %d (0x%x)\n", rev, rev);
10235 dd_p->xilinx_rev = rev;
10236 }
10237 else
10238 {
10239 dd_p->xilinx_rev = 0;
10240 edt_msg(DEBUG2, "no xilinx rev from IOCTL, setting to 0\n");
10241 }
10242
10243 #ifdef NOT_DONE
10244
10245 if ((dd_p->xilinx_rev >= 2) && (dd_p->xilinx_rev != 0xff))
10246 dd_p->xilinx_opt = edt_reg_read(pdv_p, PDV_XILINX_OPT);
10247 #endif
10248 dd_p->register_wrap = check_register_wrap(pdv_p);
10249 }
10250 }
10251
10252
10253
10254
10255
10256
10257
10258
10259
10260
10261
10262 int
10263 check_register_wrap(EdtDev *pdv_p)
10264 {
10265 int wrapped = 0;
10266 int r;
10267 int mask_lo, mask_lo_wrap;
10268
10269
10270 if (pdv_p->dd_p->xilinx_rev < 2 || pdv_p->dd_p->xilinx_rev > 32)
10271 return 1;
10272
10273
10274 mask_lo = edt_reg_read(pdv_p, PDV_MASK_LO);
10275 mask_lo_wrap = edt_reg_read(pdv_p, PDV_MASK_LO+32) ;
10276 edt_reg_write(pdv_p, PDV_MASK_LO+32, 0);
10277 edt_reg_write(pdv_p, PDV_MASK_LO, 0xa5);
10278 if ((r = edt_reg_read(pdv_p, PDV_MASK_LO+32)) == 0xa5)
10279 wrapped = 1;
10280
10281
10282 edt_reg_write(pdv_p, PDV_MASK_LO, mask_lo);
10283 if (!wrapped)
10284 edt_reg_write(pdv_p, PDV_MASK_LO, mask_lo_wrap);
10285
10286 edt_msg(DEBUG2, "registers %s\n", wrapped? "WRAPPING":"not wrapping");
10287 return wrapped;
10288 }