00001
00002
00003
00277 #include "edtinc.h"
00278
00279 #include <math.h>
00280
00281 #include <assert.h>
00282
00283 #include "libedt_timing.h"
00284
00285 #ifdef _NT_
00286 #define strncasecmp strnicmp
00287 #endif
00288
00289
00290 #define PDVWARN PDVLIB_MSG_WARNING
00291 #define PDVFATAL PDVLIB_MSG_FATAL
00292 #define DBG1 PDVLIB_MSG_INFO_1
00293 #define DBG2 PDVLIB_MSG_INFO_2
00294
00295 int Pdv_debug = 0;
00296 int Smd_type = NOT_SET;
00297 int Smd_rate = NOT_SET;
00298
00299
00300
00301
00302
00303
00304 #define PDV_DEPENDENT(pdv_p) ((pdv_p)->dd_p)
00305
00306 static void
00307 debug_print_serial_command(char *cmd);
00308 static void
00309 send_serial_binary_cmd(PdvDev * pdv_p, char *hexstr, int value);
00310
00311 static void pdv_trigger_specinst(PdvDev * pdv_p);
00312 static void pdv_posttrigger_specinst(PdvDev * pdv_p);
00313 static int pdv_specinst_setparam(PdvDev * pdv_p, char cmd, u_long offset, u_long value);
00314
00318 static int pdv_set_exposure_specinst(PdvDev * pdv_p, int value);
00319 static int pdv_set_gain_specinst(PdvDev * pdv_p, int value);
00320 static int pdv_set_exposure_adimec(PdvDev * pdv_p, int value);
00321 static int pdv_set_exposure_su320(PdvDev * pdv_p, int value);
00322 static int pdv_set_gain_adimec(PdvDev * pdv_p, int value);
00323 static int pdv_set_blacklevel_adimec(PdvDev * pdv_p, int value);
00324 static int pdv_set_exposure_smd(PdvDev * pdv_p, int value);
00325 static int pdv_set_exposure_timc1001pf(PdvDev * pdv_p, int value);
00326 static int pdv_set_exposure_ptm6710_1020(PdvDev * pdv_p, int value);
00327 static int pdv_set_gain_ptm6710_1020(PdvDev * pdv_p, int value);
00328 static int pdv_set_binning_generic(PdvDev * pdv_p, int value);
00329 static int pdv_set_gain_smd(PdvDev * pdv_p, int value);
00330 static int pdv_set_blacklevel_smd(PdvDev * pdv_p, int value);
00331 static int pdv_set_gain_hc8484(PdvDev * pdv_p, int value);
00332 static int pdv_set_exposure_toshiba(PdvDev * pdv_p, int value);
00333 static int pdv_set_gain_toshiba(PdvDev * pdv_p, int value);
00334 static int pdv_set_exposure_cohu(PdvDev * pdv_p, int value);
00335 static int pdv_set_gain_cohu(PdvDev * pdv_p, int value);
00336 static int pdv_set_blacklevel_cohu(PdvDev * pdv_p, int value);
00339 static int pdv_specinst_serial_triggered(PdvDev * pdv_p);
00340 static void CheckSumMessage(unsigned char *msg);
00341 int pdv_auto_set_timeout(PdvDev * pdv_p);
00342 static int isafloat(char *str);
00343 static int isdigits(char *str);
00344 static int isxdigits(char *str);
00345 static int update_int_from_serial(char **stat, int nstat, char *str, int *value);
00346 static int update_string_from_serial(char **stat, int nstat, char *str, char *value, int maxlen);
00347 static void update_hex_from_serial(char **stat, int nstat, char *str, int *value);
00348 static void update_2dig_from_serial(char **stat, int nstat, char *str, int *val1, int *val2);
00349 int edt_get_rtimeout(PdvDev * pdv_p);
00350 static int pdv_update_from_kodak_i(PdvDev * pdv_p);
00351
00352 static int pdv_update_from_atmel(PdvDev * pdv_p);
00353 static int pdv_update_from_hamamatsu(PdvDev * pdv_p);
00354 #ifdef IS_UNUSED
00355 static int pdv_set_mode_atmel(PdvDev * pdv_p, char *mode);
00356 static int pdv_set_mode_hamamatsu(PdvDev * pdv_p, char *mode);
00357 #endif
00358
00359 static int pdv_set_exposure_timc1001pf(PdvDev * pdv_p, int value);
00360
00361 int pdv_query_serial(PdvDev * pdv_p, char *cmd, char **resp);
00362
00363
00364
00365 void pdv_dmy_data(void *buf, int width, int height, int depth);
00366 void pdv_alloc_tmpbuf(PdvDev * pdv_p);
00367 extern int pdv_process_inplace(PdvDev *pdv_p);
00368 int pdv_update_size(PdvDev * pdv_p);
00369
00370 static char *hex_to_str(char *resp, int n);
00371
00372 #ifdef DOXYGEN_SHOW_UNDOC
00373
00378 #endif
00379
00439 PdvDev *
00440 pdv_open_channel(const char *dev_name, int unit, int channel)
00441 {
00442 PdvDev *pdv_p;
00443 char tmpname[64];
00444 Dependent *dd_p;
00445 static char *debug_env = NULL;
00446 int level;
00447
00448 if ((debug_env == NULL)
00449 && ((debug_env = (char *) getenv("PDVDEBUG")) != NULL)
00450 && *debug_env != '0')
00451 {
00452 Pdv_debug = atoi(debug_env);
00453 level = edt_msg_default_level();
00454 if (Pdv_debug > 0)
00455 {
00456 level |= DBG1;
00457 level |= DBG2;
00458 }
00459 edt_msg_set_level(edt_msg_default_handle(), level);
00460
00461 edt_msg(DBG2, "environment DEBUG set to %d: enabling debug in pdvlib\n", Pdv_debug);
00462 }
00463
00464 edt_msg(DBG2, "pdv_open_channel('%s', %d, %d)\n", dev_name ? dev_name : "NULL",
00465 unit, channel);
00466
00467 if (dev_name == NULL)
00468 strcpy(tmpname, EDT_INTERFACE);
00469 else
00470 strcpy(tmpname, dev_name);
00471 if ((pdv_p = edt_open_channel(tmpname, unit, channel)) == NULL)
00472 return NULL;
00473
00474
00475 if (pdv_p->devid == PDVFOI_ID)
00476 {
00477 #ifdef _FOI_SUPPORTED
00478 edt_check_foi(pdv_p);
00479 #else
00480 edt_msg(PDVFATAL, "pdv_open_channel: FOI not supported after v4.1.5.9\n");
00481 return NULL;
00482 #endif
00483 }
00484 else
00485 {
00486 pdv_p->foi_unit = channel;
00487 }
00488
00489
00490
00491
00492
00493 if (sizeof(Dependent) > EDT_DEPSIZE)
00494 {
00495 edt_msg(PDVWARN, "pdv_open_channel: sizeof Dependent %d > DEPSIZE %d\n",
00496 sizeof(Dependent), EDT_DEPSIZE);
00497 }
00498 if ((dd_p = (Dependent *) malloc(EDT_DEPSIZE)) == NULL)
00499 {
00500 pdv_close(pdv_p);
00501 return NULL;
00502 }
00503 pdv_p->dd_p = dd_p;
00504
00505 if (edt_get_dependent(pdv_p, dd_p) < 0)
00506 {
00507 free(dd_p);
00508 dd_p = 0;
00509 pdv_p->dd_p = NULL;
00510 pdv_close(pdv_p);
00511 return NULL;
00512 }
00513
00514 if (pdv_p->devid == PDVFOI_ID)
00515 {
00516 pdv_p->foi_unit = edt_get_foiunit(pdv_p);
00517 }
00518
00519 pdv_p->tmpbufsize = 0;
00520
00521 pdv_p->dd_p->xilinx_rev = 2;
00522
00523 if (pdv_p->dd_p->swinterlace ||
00524 pdv_p->dd_p->interlace_module[0])
00525 pdv_setup_postproc(pdv_p, pdv_p->dd_p, NULL);
00526
00527 return pdv_p;
00528
00529 }
00530
00531
00532
00559 PdvDev *
00560 pdv_open(char *dev_name, int unit)
00561 {
00562 return pdv_open_channel(dev_name, unit, 0);
00563 }
00564
00565
00572 void
00573 pdv_setup_dma(PdvDev * pdv_p)
00574
00575 {
00576
00577
00578
00579 edt_set_continuous(pdv_p, 0);
00580 pdv_p->dd_p->started_continuous = 0;
00581
00582 edt_startdma_reg(pdv_p, PDV_CMD, PDV_ENABLE_GRAB);
00583 }
00584
00585
00586
00595 int
00596 pdv_close(PdvDev * pdv_p)
00597 {
00598 edt_msg(DBG2, "pdv_close()\n");
00599
00600 if (!pdv_p)
00601 return -1;
00602 if (pdv_p->dd_p)
00603 {
00604 free(pdv_p->dd_p);
00605 pdv_p->dd_p = 0;
00606 }
00607
00608 return edt_close(pdv_p);
00609 }
00610
00620 int
00621 pdv_bytes_per_line(int width, int depth)
00622
00623 {
00624 if (depth == 1)
00625 return width >> 3;
00626 else if (depth == 2)
00627 return width >> 2;
00628 else if (depth == 4)
00629 return width >> 1;
00630 else
00631 return width * bits2bytes(depth);
00632 }
00633
00640 int
00641 pdv_get_bytes_per_image(PdvDev *pdv_p)
00642
00643 {
00644 return pdv_p->dd_p->height *
00645 pdv_bytes_per_line(pdv_p->dd_p->width, pdv_p->dd_p->depth);
00646 }
00647
00648
00663 int
00664 pdv_get_width(PdvDev * pdv_p)
00665 {
00666 if (!pdv_p->dd_p)
00667 return (0);
00668
00669 edt_msg(DBG2, "pdv_get_width() %d\n", pdv_p->dd_p->width);
00670
00671
00672 return pdv_p->dd_p->width;
00673 }
00674
00683 int
00684 pdv_get_pitch(PdvDev * pdv_p)
00685 {
00686 int pitch;
00687
00688 if (!pdv_p->dd_p)
00689 return (0);
00690
00691 pitch = pdv_bytes_per_line(pdv_p->dd_p->width,
00692 pdv_p->dd_p->depth);
00693
00694 edt_msg(DBG2, "pdv_get_pitch() %d\n", pitch);
00695
00696
00697 return pitch ;
00698 }
00699
00720 int
00721 pdv_get_cam_width(PdvDev * pdv_p)
00722 {
00723 edt_msg(DBG2, "pdv_get_cam_width() %d\n", pdv_p->dd_p->cam_width);
00724
00725 return pdv_p->dd_p->cam_width;
00726 }
00727
00743 int
00744 pdv_get_dmasize(PdvDev * pdv_p)
00745
00746 {
00747
00748 Dependent *dd_p = PDV_DEPENDENT(pdv_p);
00749
00750 int size;
00751 int extra_dma = 0;
00752
00753
00754 if (pdv_p->dd_p->header_position == HeaderBegin ||
00755 pdv_p->dd_p->header_position == HeaderMiddle ||
00756 pdv_p->dd_p->header_position == HeaderEnd)
00757 extra_dma = pdv_p->dd_p->header_size;
00758
00759 if (dd_p->swinterlace == PDV_INV_RT_INTLV_24_12)
00760 size = dd_p->width * dd_p->height * 3 / 2;
00761 else if (dd_p->depth > dd_p->extdepth)
00762 size = dd_p->height *
00763 pdv_bytes_per_line(pdv_p->dd_p->width, pdv_p->dd_p->extdepth);
00764 else
00765 size = dd_p->height *
00766 pdv_bytes_per_line(pdv_p->dd_p->width, pdv_p->dd_p->depth);
00767
00768 return size + extra_dma;
00769 }
00770
00787 int
00788 pdv_setsize(PdvDev * pdv_p, int width, int height)
00789 {
00790 Dependent *dd_p = pdv_p->dd_p;
00791
00792 edt_msg(DBG2, "pdv_setsize(%d, %d)\n", width, height);
00793
00794 dd_p->width = width;
00795 dd_p->height = height;
00796
00797 return pdv_update_size(pdv_p);
00798
00799 }
00800
00820 int
00821 pdv_set_cam_width(PdvDev * pdv_p, int value)
00822 {
00823 int ret;
00824 Dependent *dd_p = pdv_p->dd_p;
00825
00826 edt_msg(DBG2, "pdv_set_cam_width(%d)\n", value);
00827
00828 dd_p->cam_width = value;
00829
00830 ret = edt_set_dependent(pdv_p, dd_p);
00831
00832 return ret;
00833 }
00834
00845 int
00846 pdv_get_imagesize(PdvDev * pdv_p)
00847 {
00848
00849 edt_msg(DBG2, "pdv_get_imagesize() %d\n", pdv_p->dd_p->imagesize);
00850
00851 return pdv_p->dd_p->imagesize;
00852 }
00853
00862 int
00863 pdv_get_allocated_size(PdvDev * pdv_p)
00864 {
00865 Dependent *dd_p = pdv_p->dd_p;
00866 int total = 0;
00867
00868 dd_p->imagesize = dd_p->width * dd_p->height * bits2bytes(dd_p->depth);
00869
00870 total = pdv_p->dd_p->imagesize + pdv_p->dd_p->slop + pdv_p->dd_p->header_size;
00871
00872 #ifdef _NT_
00873
00874 if (total % PAGESIZE)
00875 {
00876 total = ((total / PAGESIZE) + 1) * PAGESIZE;
00877 }
00878 #endif
00879
00880 edt_msg(DBG2, "pdv_get_allocated_size() %d\n", total);
00881
00882 return total;
00883
00884 }
00885
00905 int
00906 pdv_set_timeout(PdvDev * pdv_p, int value)
00907 {
00908 Dependent *dd_p = pdv_p->dd_p;
00909
00910 if (value < 0)
00911 {
00912 edt_msg(DBG2, "pdv_set_timeout(%d) (< 0, going back to auto)\n", value);
00913
00914 pdv_p->dd_p->user_timeout_set = 0;
00915 edt_set_dependent(pdv_p, dd_p);
00916 return pdv_auto_set_timeout(pdv_p);
00917 }
00918 else
00919 {
00920 edt_msg(DBG2, "pdv_set_timeout(%d) (user set, overriding auto)\n", value);
00921
00922 pdv_p->dd_p->user_timeout_set = 1;
00923 pdv_p->dd_p->user_timeout = value;
00924 edt_set_dependent(pdv_p, dd_p);
00925 return edt_set_rtimeout(pdv_p, value);
00926 }
00927 }
00928
00943 int
00944 pdv_get_timeout(PdvDev * pdv_p)
00945 {
00946
00947 edt_msg(DBG2, "pdv_get_timeout()\n");
00948
00949 return edt_get_rtimeout(pdv_p);
00950 }
00951
00964 int
00965 pdv_picture_timeout(PdvDev * pdv_p, int value)
00966 {
00967 return pdv_set_timeout(pdv_p, value);
00968 }
00969
00971
00972
01011 int
01012 pdv_timeouts(PdvDev * pdv_p)
01013 {
01014 int ret;
01015
01016 ret = edt_timeouts(pdv_p);
01017 edt_msg(DBG2, "pdv_timeouts(%d)\n", ret);
01018 return ret;
01019 }
01020
01021
01034 int
01035 pdv_timeout_cleanup(PdvDev * pdv_p)
01036 {
01037 int curdone, curtodo;
01038
01039 curdone = edt_done_count(pdv_p);
01040 curtodo = edt_get_todo(pdv_p);
01041 pdv_stop_continuous(pdv_p);
01042 edt_msleep(500);
01043 edt_set_buffer(pdv_p, curdone);
01044 edt_reg_write(pdv_p, PDV_CMD, PDV_RESET_INTFC);
01045 pdv_setup_continuous(pdv_p);
01046 return curtodo - curdone;
01047 }
01048
01050
01051
01069 int
01070 pdv_get_height(PdvDev * pdv_p)
01071 {
01072 if (!pdv_p->dd_p)
01073 return (0);
01074
01075 edt_msg(DBG2, "pdv_get_height() %d\n", pdv_p->dd_p->height);
01076
01077 return pdv_p->dd_p->height;
01078 }
01079
01099 int
01100 pdv_get_cam_height(PdvDev * pdv_p)
01101 {
01102
01103 edt_msg(DBG2, "pdv_get_cam_height() %d\n", pdv_p->dd_p->cam_height);
01104
01105 return pdv_p->dd_p->cam_height;
01106 }
01107
01108
01125 int
01126 pdv_get_frame_height(PdvDev * pdv_p)
01127 {
01128
01129 edt_msg(DBG2, "pdv_get_cam_height() %d\n", pdv_p->dd_p->cam_height);
01130
01131 return pdv_p->dd_p->frame_height;
01132 }
01133
01135
01145 int
01146 pdv_update_size(PdvDev *pdv_p)
01147
01148 {
01149 Dependent *dd_p = pdv_p->dd_p;
01150 int ret;
01151
01152 edt_msg(DBG2, "update_size\n");
01153
01154 dd_p->imagesize = dd_p->height * pdv_get_pitch(pdv_p);
01155
01156 ret = edt_set_dependent(pdv_p, dd_p);
01157
01158 if (pdv_p->ring_buffer_numbufs > 0)
01159 pdv_multibuf(pdv_p, pdv_p->ring_buffer_numbufs);
01160
01161 if (dd_p->swinterlace)
01162 {
01163 pdv_alloc_tmpbuf(pdv_p);
01164 }
01165
01166 return ret;
01167 }
01168
01180 int
01181 pdv_set_width(PdvDev * pdv_p, int value)
01182 {
01183 Dependent *dd_p = pdv_p->dd_p;
01184
01185 edt_msg(DBG2, "pdv_set_width(%d)\n", value);
01186
01187 dd_p->width = value;
01188
01189 return pdv_update_size(pdv_p);
01190
01191 }
01192
01201 int
01202 pdv_set_height(PdvDev * pdv_p, int value)
01203 {
01204 Dependent *dd_p = pdv_p->dd_p;
01205
01206 edt_msg(DBG2, "pdv_set_height(%d)\n", value);
01207
01208 dd_p->height = value;
01209
01210 return pdv_update_size(pdv_p);
01211
01212 }
01213
01231 int
01232 pdv_set_cam_height(PdvDev * pdv_p, int value)
01233 {
01234 int ret;
01235 Dependent *dd_p = pdv_p->dd_p;
01236
01237 edt_msg(DBG2, "pdv_set_cam_height(%d)\n", value);
01238
01239 dd_p->cam_height = value;
01240
01241 ret = edt_set_dependent(pdv_p, dd_p);
01242 return ret;
01243 }
01244
01245
01254 int
01255 pdv_get_depth(PdvDev * pdv_p)
01256 {
01257 if (!pdv_p->dd_p)
01258 return (0);
01259
01260 edt_msg(DBG2, "pdv_get_depth() %d\n", pdv_p->dd_p->depth);
01261
01262 return pdv_p->dd_p->depth;
01263 }
01264
01282 int
01283 pdv_get_extdepth(PdvDev * pdv_p)
01284 {
01285
01286 edt_msg(DBG2, "pdv_get_extdepth() %d\n", pdv_p->dd_p->extdepth);
01287
01288 return pdv_p->dd_p->extdepth;
01289 }
01290
01316 int
01317 pdv_set_depth(PdvDev * pdv_p, int value)
01318 {
01319 Dependent *dd_p = pdv_p->dd_p;
01320
01321 dd_p->depth = value;
01322
01323
01324
01325
01326
01327 if (pdv_is_cameralink(pdv_p))
01328 {
01329 int reg;
01330
01331 if ((value >= 8) && (value <= 16))
01332 reg = value-1;
01333 else if (value == 24 || value == 32)
01334 reg = 0x7;
01335 else if (value == 30)
01336 reg = 0x9;
01337 else reg = 0;
01338
01339 if (reg)
01340 {
01341 if (dd_p->dual_channel)
01342 reg |= 0x10;
01343 dd_p->dual_channel = reg;
01344 edt_reg_write(pdv_p, PDV_CL_DATA_PATH, dd_p->cl_data_path);
01345 }
01346 }
01347
01348 return pdv_update_size(pdv_p);
01349
01350 }
01351
01376 int
01377 pdv_set_extdepth(PdvDev * pdv_p, int value)
01378 {
01379 int ret;
01380 Dependent *dd_p = pdv_p->dd_p;
01381
01382 dd_p->extdepth = value;
01383
01384 edt_msg(DBG2, "pdv_set_extdepth(%d)\n", value);
01385
01386 ret = edt_set_dependent(pdv_p, dd_p);
01387
01388 return ret;
01389 }
01390
01402 int
01403 pdv_set_cameratype(PdvDev * pdv_p, char *model)
01404 {
01405 Dependent *dd_p = pdv_p->dd_p;
01406
01407 edt_msg(DBG2, "pdv_set_cameratype(%s)\n", model);
01408
01409 strcpy(dd_p->cameratype, model);
01410
01411 return edt_set_dependent(pdv_p, dd_p);
01412 }
01413
01414
01431 char *
01432 pdv_get_cameratype(PdvDev * pdv_p)
01433 {
01434 edt_msg(DBG2, "pdv_get_cameratype()\n");
01435
01436 return pdv_p->dd_p->cameratype;
01437 }
01438
01439
01456 char *
01457 pdv_get_camera_class(PdvDev * pdv_p)
01458 {
01459 edt_msg(DBG2, "pdv_get_camera_class()\n");
01460
01461 return pdv_p->dd_p->camera_class;
01462 }
01463
01464
01474 char *
01475 pdv_get_camera_model(PdvDev * pdv_p)
01476 {
01477 edt_msg(DBG2, "pdv_get_camera_model()\n");
01478
01479 return pdv_p->dd_p->camera_model;
01480 }
01481
01492 char *
01493 pdv_get_camera_info(PdvDev * pdv_p)
01494 {
01495 edt_msg(DBG2, "pdv_get_camera_info()\n");
01496
01497 return pdv_p->dd_p->camera_info;
01498 }
01499
01511 char *
01512 pdv_camera_type(PdvDev * pdv_p)
01513 {
01514 edt_msg(DBG2, "pdv_camera_type()\n");
01515
01516 return pdv_p->dd_p->cameratype;
01517 }
01518
01520
01521 static int
01522 smd_read_reg(PdvDev * pdv_p, int reg)
01523 {
01524 u_char buf[128];
01525 int ret;
01526
01527
01528 pdv_serial_read(pdv_p, (char *) buf, 64);
01529
01530
01531 buf[0] = (u_char) reg;
01532 pdv_serial_binary_command(pdv_p, (char *) buf, 1);
01533
01534 ret = pdv_serial_wait(pdv_p, pdv_p->dd_p->serial_timeout, pdv_p->dd_p->serial_respcnt);
01535 if (ret == 0)
01536 return -1;
01537 pdv_serial_read(pdv_p, (char *) buf, ret);
01538 return (int) buf[0];
01539 }
01540
01541
01542
01543
01544
01545
01546
01547
01548 static int
01549 check_valid_formatstr(char *str)
01550 {
01551 int i, len = strlen(str);
01552 int ret = 0;
01553
01554 for (i=0; i<len; i++)
01555 {
01556 if (str[i] == '%')
01557 {
01558 if ((i > 0) && (str[i-1] != '\\'))
01559 ++ret;
01560 else if (i == len-1)
01561 {
01562 ret = -1;
01563 break;
01564 }
01565
01566 }
01567 }
01568 return ret;
01569 }
01570
01601 int
01602 pdv_set_exposure(PdvDev * pdv_p, int value)
01603 {
01604 int ret = -1;
01605 Dependent *dd_p = pdv_p->dd_p;
01606 char cmdstr[64];
01607 int n;
01608
01609 cmdstr[0] = '\0';
01610
01611 edt_msg(DBG2, "pdv_set_exposure(%d)\n", value);
01612
01613 dd_p->shutter_speed = value;
01614
01615 if (edt_set_dependent(pdv_p, dd_p) < 0)
01616 {
01617 edt_msg(DBG2, "pdv_set_exposure ret %d\n", ret);
01618 return -1;
01619 }
01620
01621 pdv_auto_set_timeout(pdv_p);
01622
01623 if ((dd_p->camera_shutter_timing == AIA_MCL)
01624 && (dd_p->mode_cntl_norm & 0xf0)
01625 && (!dd_p->trig_pulse))
01626 {
01627 ret = pdv_set_exposure_mcl(pdv_p, value);
01628 }
01629 else if (dd_p->camera_shutter_timing == AIA_MCL_100US)
01630 {
01631
01632 ret = pdv_set_exposure_mcl(pdv_p, value);
01633 }
01634 else if ((strlen(dd_p->serial_exposure) >= 0) && (dd_p->serial_format == SERIAL_BINARY))
01635 {
01636 send_serial_binary_cmd(pdv_p, dd_p->serial_exposure, value);
01637 }
01638 else if ((strlen(dd_p->serial_exposure) >= 0)
01639 && ((dd_p->serial_format == SERIAL_ASCII)
01640 || (dd_p->serial_format == SERIAL_ASCII_HEX)
01641 || (dd_p->serial_format == SERIAL_PULNIX_1010)))
01642 {
01643
01644
01645
01646 if (dd_p->camera_shutter_timing == HAM_4880_SER)
01647 {
01648 int minutes;
01649 int seconds;
01650 int useconds;
01651
01652 minutes = value / 60000;
01653 value -= minutes * 60000;
01654
01655 seconds = value / 1000;
01656 value -= seconds * 1000;
01657
01658 useconds = value;
01659
01660 sprintf(cmdstr, "%s %04d:%02d.%03d",
01661 dd_p->serial_exposure, minutes, seconds, useconds);
01662 }
01663
01664 else switch(dd_p->serial_format)
01665 {
01666
01667 case SERIAL_ASCII_HEX:
01668 sprintf(cmdstr, "%s %02x", dd_p->serial_exposure, value);
01669 break;
01670
01671 case SERIAL_PULNIX_1010:
01672 sprintf(cmdstr, "%s%d", dd_p->serial_exposure, value);
01673 break;
01674
01675 case SERIAL_ASCII:
01676 default:
01677 {
01678 int n = check_valid_formatstr(dd_p->serial_offset);
01679
01680 cmdstr[0] = '\0';
01681
01682 if (n == 0)
01683 sprintf(cmdstr, "%s %d", dd_p->serial_offset, value);
01684 else if ((n > 0) && (n < 5))
01685 sprintf(cmdstr, dd_p->serial_offset, value, value, value, value);
01686
01687 if (cmdstr[0])
01688 {
01689 ret = pdv_serial_command_flagged(pdv_p, cmdstr, SCFLAG_NORESP);
01690
01691 pdv_serial_wait(pdv_p, pdv_p->dd_p->serial_timeout, 64);
01692 if (*pdv_p->dd_p->serial_response)
01693 pdv_serial_read(pdv_p, cmdstr, 63);
01694 }
01695 }
01696
01697 if (check_valid_formatstr(dd_p->serial_exposure) >= 1)
01698 sprintf(cmdstr, dd_p->serial_exposure, value, value, value, value);
01699 else sprintf(cmdstr, "%s %d", dd_p->serial_exposure, value);
01700 break;
01701 }
01702
01703 if (cmdstr[0])
01704 {
01705 ret = pdv_serial_command_flagged(pdv_p, cmdstr, SCFLAG_NORESP);
01706 n = pdv_serial_wait(pdv_p, pdv_p->dd_p->serial_timeout, pdv_p->dd_p->serial_respcnt);
01707 if (*pdv_p->dd_p->serial_response)
01708 if (n)
01709 pdv_serial_read(pdv_p, cmdstr, n);
01710 }
01711 }
01712 else if ((dd_p->camera_shutter_timing == SPECINST_SERIAL)
01713 || (dd_p->camera_shutter_speed == SPECINST_SERIAL))
01714 {
01715 ret = pdv_set_exposure_specinst(pdv_p, value);
01716 }
01717 else if (dd_p->camera_shutter_timing == SMD_SERIAL)
01718 {
01719 ret = pdv_set_exposure_smd(pdv_p, value);
01720 }
01721 else if (dd_p->camera_shutter_timing == PTM6710_SERIAL)
01722 {
01723 ret = pdv_set_exposure_ptm6710_1020(pdv_p, value);
01724 }
01725 else if (dd_p->camera_shutter_timing == TOSHIBA_SERIAL)
01726 {
01727 ret = pdv_set_exposure_toshiba(pdv_p, value);
01728 }
01729 else if (dd_p->camera_shutter_timing == COHU_SERIAL)
01730 {
01731 ret = pdv_set_exposure_cohu(pdv_p, value);
01732 }
01733 else if (dd_p->camera_shutter_timing == PTM1020_SERIAL)
01734 {
01735 ret = pdv_set_exposure_ptm6710_1020(pdv_p, value);
01736 }
01737 else if (dd_p->camera_shutter_timing == TIMC1001_SERIAL)
01738 {
01739 ret = pdv_set_exposure_timc1001pf(pdv_p, value);
01740 }
01741 else if (dd_p->camera_shutter_timing == ADIMEC_SERIAL)
01742 {
01743 ret = pdv_set_exposure_adimec(pdv_p, value);
01744 }
01745 else if (dd_p->camera_shutter_timing == BASLER202K_SERIAL)
01746 {
01747 ret = pdv_set_exposure_basler202k(pdv_p, value);
01748 }
01749 else if (dd_p->camera_shutter_timing == SU320_SERIAL)
01750 {
01751 ret = pdv_set_exposure_su320(pdv_p, value);
01752 }
01753 else if (dd_p->camera_shutter_timing == HAM_4880_SER)
01754 {
01755
01756 }
01757 else if (dd_p->camera_shutter_timing == AIA_SERIAL)
01758 {
01759
01760 }
01761 else if (dd_p->camera_shutter_timing == AIA_SERIAL_ES40)
01762 {
01763
01764 }
01765 else if (dd_p->camera_shutter_timing == AIA_TRIG)
01766 {
01767 ret = pdv_set_exposure_mcl(pdv_p, value);
01768 }
01769 else if (!dd_p->trig_pulse)
01770 {
01771
01772 ret = pdv_set_exposure_mcl(pdv_p, value);
01773 }
01774
01775 edt_msg(DBG2, "pdv_set_exposure returns %d\n", ret);
01776 return (ret);
01777 }
01778
01795 int
01796 pdv_set_exposure_mcl(PdvDev * pdv_p, int value)
01797 {
01798 u_int data_path;
01799
01800 if (value < 0)
01801 value = 0;
01802 if (value > 25500)
01803 value = 25500;
01804
01805 pdv_p->dd_p->shutter_speed = value;
01806
01807 data_path = pdv_p->dd_p->datapath_reg;
01808 data_path &= ~PDV_MULTIPLIER_MASK;
01809
01810
01811
01812
01813
01814 if (pdv_p->dd_p->camera_shutter_timing == AIA_MCL_100US)
01815 {
01816 edt_msg(DBG2, "pdv_set_exposure_mcl(%d) (100US)\n", value);
01817
01818 if (value < 256)
01819 {
01820 data_path |= PDV_MULTIPLIER_100US;
01821 }
01822 else if (value < 2560)
01823 {
01824
01825 value = (value + 5) / 10;
01826 }
01827 else if (value < 25600)
01828 {
01829 data_path |= PDV_MULTIPLIER_10MS;
01830 value = (value + 50) / 100;
01831 }
01832 else if (value < 256000)
01833 {
01834 data_path |= PDV_MULTIPLIER_100MS;
01835 value = (value + 50) / 1000;
01836 }
01837 }
01838 else
01839 {
01840 edt_msg(DBG2, "pdv_set_exposure_mcl(%d)\n", value);
01841
01842 if (value < 256)
01843 {
01844
01845 }
01846 else if (value < 2560)
01847 {
01848 data_path |= PDV_MULTIPLIER_10MS;
01849 value = (value + 5) / 10;
01850 }
01851 else
01852 {
01853 data_path |= PDV_MULTIPLIER_100MS;
01854 value = (value + 50) / 100;
01855 }
01856 }
01857
01858 pdv_p->dd_p->datapath_reg = data_path;
01859 edt_reg_write(pdv_p, PDV_SHUTTER, value);
01860 edt_reg_write(pdv_p, PDV_DATA_PATH, data_path);
01861
01862 return 0;
01863 }
01864
01868 static int
01869 pdv_set_exposure_smd(PdvDev * pdv_p, int value)
01870 {
01871 int fp = 0;
01872 u_char buf[128];
01873 int n;
01874 int ret = 0;
01875 int smd_reg1, smd_reg3;
01876
01877
01878 if (Smd_type == NOT_SET)
01879 {
01880 Smd_type = smd_read_reg(pdv_p, SMD_READ_CAMTYPE);
01881 if ((Smd_type & 0xfff) == 0xfff)
01882
01883 Smd_type = smd_read_reg(pdv_p, SMD_READ_CAMTYPE);
01884 }
01885
01886
01887 switch (Smd_type)
01888 {
01889 case SMD_TYPE_4M4:
01890
01891
01892
01893
01894
01895 if (value == 0)
01896 buf[1] = 0x7d;
01897 else if (value == 1)
01898 buf[1] = 0x7b;
01899 else if (value == 2)
01900 buf[1] = 0x77;
01901 else if (value <= 4)
01902 buf[1] = 0x6f;
01903 else if (value <= 8)
01904 buf[1] = 0x5f;
01905 else if (value <= 16)
01906 buf[1] = 0x3f;
01907 else
01908 buf[1] = 0x00;
01909
01910
01911
01912 pdv_serial_binary_command(pdv_p, (char *) buf, 2);
01913 break;
01914
01915 case SMD_TYPE_BT25:
01916
01917
01918
01919 buf[0] = (u_char) SMD_BT25_WRITE_R2;
01920 if (Smd_rate == NOT_SET)
01921 {
01922 if ((Smd_rate = smd_read_reg(pdv_p, SMD_BT25_READ_FRAMERATE)) == -1)
01923 edt_msg(PDVWARN, "libpdv: no response from SMD camera rate reg read\n");
01924 if (pdv_p->dd_p->timeout_multiplier < Smd_rate)
01925 {
01926 pdv_p->dd_p->timeout_multiplier = Smd_rate;
01927 pdv_auto_set_timeout(pdv_p);
01928 }
01929 }
01930 buf[1] = (u_char) value;
01931
01932
01933
01934 pdv_serial_binary_command(pdv_p, (char *) buf, 2);
01935
01936
01937 pdv_serial_wait(pdv_p, 100, 64);
01938 break;
01939
01940 case SMD_TYPE_1M30P:
01941 case SMD_TYPE_6M3P:
01942 buf[0] = (u_char) SMD_1M30P_REG_W_INTEG0;
01943 buf[1] = value & 0xff;
01944 pdv_serial_binary_command(pdv_p, (char *) buf, 2);
01945
01946 buf[0] = (u_char) SMD_1M30P_REG_W_INTEG1;
01947 buf[1] = (value & 0xff00) >> 8;
01948 pdv_serial_binary_command(pdv_p, (char *) buf, 2);
01949
01950 buf[0] = (u_char) SMD_1M30P_REG_W_INTEG2;
01951 buf[1] = (value & 0xff0000) >> 16;
01952 pdv_serial_binary_command(pdv_p, (char *) buf, 2);
01953
01954
01955
01956
01957
01958
01959
01960
01961 pdv_p->dd_p->shutter_speed = value / 1000;
01962 pdv_auto_set_timeout(pdv_p);
01963 pdv_p->dd_p->shutter_speed = value;
01964 break;
01965
01966 case SMD_TYPE_1M15P:
01967 if ((smd_reg1 = smd_read_reg(pdv_p, SMD_1M15P_READ_R1)) == -1)
01968 {
01969 edt_msg(PDVWARN, "libpdv: no response from SMD R1 reg read\n");
01970 return -1;
01971 }
01972
01973
01974 buf[0] = (u_char) SMD_1M15P_WRITE_R1;
01975
01976
01977
01978
01979
01980 if (value == 0)
01981 {
01982 buf[1] = (smd_reg1 &~ SMD_1M15P_R1_INTMSK) | 0x0;
01983 fp = 65000;
01984 }
01985 else if (value == 1)
01986 {
01987 buf[1] = (smd_reg1 &~ SMD_1M15P_R1_INTMSK) | 0x7;
01988 fp = 65000;
01989 }
01990 else if (value < 4)
01991 {
01992 buf[1] = (smd_reg1 &~ SMD_1M15P_R1_INTMSK) | 0x6;
01993 fp = 64000;
01994 }
01995 else if (value < 7)
01996 {
01997 buf[1] = (smd_reg1 &~ SMD_1M15P_R1_INTMSK) | 0x5;
01998 fp = 62000;
01999 }
02000 else if (value == 8)
02001 {
02002 buf[1] = (smd_reg1 &~ SMD_1M15P_R1_INTMSK) | 0x4;
02003 fp = 58000;
02004 }
02005 else return -1;
02006
02007 if (smd_reg1 & SMD_1M15P_R1_TRIGMODE)
02008 {
02009
02010 smd_reg3 = smd_read_reg(pdv_p, SMD_1M15P_READ_R3);
02011 if (smd_reg3 & 0x40)
02012 fp /= 2;
02013 pdv_set_frame_period(pdv_p, fp, PDV_FVAL_ADJUST);
02014 }
02015
02016 pdv_p->dd_p->shutter_speed = value;
02017 pdv_serial_binary_command(pdv_p, (char *) buf, 2);
02018 break;
02019
02020 default:
02021 ret = -1;
02022 edt_msg(PDVWARN, "libpdv: unknown SMD camera type %02x\n", Smd_type);
02023 break;
02024 }
02025
02026 if (!ret)
02027 {
02028
02029 n = pdv_serial_wait(pdv_p, 100, 64);
02030 if (n > 127)
02031 n = 127;
02032 if (n)
02033 pdv_serial_read(pdv_p, (char *) buf, n);
02034 }
02035 return ret;
02036 }
02037
02046 static int
02047 pdv_set_exposure_timc1001pf(PdvDev * pdv_p, int value)
02048 {
02049 Dependent *dd_p = pdv_p->dd_p;
02050 u_int mcl = edt_reg_read(pdv_p, PDV_MODE_CNTL) & 0xf1;
02051
02052 if ((value >= 0) && (value <= 7))
02053 {
02054 dd_p->shutter_speed = value;
02055 mcl |= (value << 1);
02056 edt_reg_write(pdv_p, PDV_MODE_CNTL, mcl);
02057 return 0;
02058 }
02059 return -1;
02060 }
02061
02065 static int
02066 pdv_set_exposure_toshiba(PdvDev * pdv_p, int value)
02067 {
02068 char cmdbuf[128];
02069 int n;
02070
02071 if ((value < 0) || (value > 0xff))
02072 return -1;
02073
02074 cmdbuf[0] = 0x02;
02075 sprintf(cmdbuf+1, "68%02X", value);
02076 cmdbuf[5] = 0x03;
02077 pdv_serial_binary_command(pdv_p, (char *)cmdbuf, 6);
02078
02079
02080 if (n = pdv_serial_wait(pdv_p, 200, 3))
02081 pdv_serial_read(pdv_p, cmdbuf, n);
02082
02083 cmdbuf[0] = 0x02;
02084 sprintf(cmdbuf+1, "6E01");
02085 cmdbuf[5] = 0x03;
02086 pdv_serial_binary_command(pdv_p, (char *)cmdbuf, 6);
02087
02088
02089 if (n = pdv_serial_wait(pdv_p, 200, 3))
02090 pdv_serial_read(pdv_p, cmdbuf, n);
02091
02092 return 0;
02093 }
02094
02098 static int
02099 pdv_set_gain_toshiba(PdvDev * pdv_p, int value)
02100 {
02101 char cmdbuf[128];
02102 int n;
02103
02104 if ((value < 0) || (value > 0xff))
02105 return -1;
02106
02107 cmdbuf[0] = 0x02;
02108 sprintf(cmdbuf+1, "64%02X", value);
02109 cmdbuf[5] = 0x03;
02110 pdv_serial_binary_command(pdv_p, (char *)cmdbuf, 6);
02111
02112
02113 if (n = pdv_serial_wait(pdv_p, 200, 3))
02114 pdv_serial_read(pdv_p, cmdbuf, n);
02115
02116 cmdbuf[0] = 0x02;
02117 sprintf(cmdbuf+1, "6E01");
02118 cmdbuf[5] = 0x03;
02119 pdv_serial_binary_command(pdv_p, (char *)cmdbuf, 6);
02120
02121
02122 if (n = pdv_serial_wait(pdv_p, 200, 3))
02123 pdv_serial_read(pdv_p, cmdbuf, n);
02124
02125 return 0;
02126 }
02127
02131 static int
02132 pdv_set_exposure_cohu(PdvDev * pdv_p, int value)
02133 {
02134 char cmdbuf[128];
02135 int n, len;
02136
02137 if ((value < 0) || (value > 10))
02138 return -1;
02139
02140
02141 cmdbuf[0] = 0x02;
02142 cmdbuf[1] = 0x01;
02143 sprintf(cmdbuf+2, "cE2,%d", value);
02144 len = strlen(cmdbuf);
02145 cmdbuf[len++] = (char)0x81;
02146 cmdbuf[len++] = (char)0x03;
02147 cmdbuf[len] = 0;
02148 pdv_serial_binary_command(pdv_p, (char *)cmdbuf, len);
02149
02150
02151 if (n = pdv_serial_wait(pdv_p, 200, 7))
02152 pdv_serial_read(pdv_p, cmdbuf, n);
02153
02154
02155 cmdbuf[0] = (char)0x02;
02156 cmdbuf[1] = (char)0x01;
02157 cmdbuf[2] = 'c';
02158 cmdbuf[3] = 'T';
02159 cmdbuf[4] = '0';
02160 cmdbuf[5] = (char)0x81;
02161 cmdbuf[6] = (char)0x03;
02162 pdv_serial_binary_command(pdv_p, (char *)cmdbuf, 7);
02163
02164
02165 if (n = pdv_serial_wait(pdv_p, 200, 7))
02166 pdv_serial_read(pdv_p, cmdbuf, n);
02167
02168 return 0;
02169 }
02170
02174 static int
02175 pdv_set_gain_cohu(PdvDev * pdv_p, int value)
02176 {
02177 char cmdbuf[128];
02178 int n, len;
02179
02180 if ((value < 0) || (value > 320))
02181 return -1;
02182
02183
02184 cmdbuf[0] = (char)0x02;
02185 cmdbuf[1] = (char)0x01;
02186 sprintf(cmdbuf+2, "cB1,%d", value);
02187 len = strlen(cmdbuf);
02188 cmdbuf[len++] = (char)0x81;
02189 cmdbuf[len++] = (char)0x03;
02190 cmdbuf[len] = 0;
02191 pdv_serial_binary_command(pdv_p, (char *)cmdbuf, len);
02192
02193
02194 if (n = pdv_serial_wait(pdv_p, 200, 7))
02195 pdv_serial_read(pdv_p, cmdbuf, n);
02196
02197
02198 cmdbuf[0] = (char)0x02;
02199 cmdbuf[1] = (char)0x01;
02200 cmdbuf[2] = 'c';
02201 cmdbuf[3] = 'T';
02202 cmdbuf[4] = '0';
02203 cmdbuf[5] = (char)0x81;
02204 cmdbuf[6] = (char)0x03;
02205 pdv_serial_binary_command(pdv_p, (char *)cmdbuf, 7);
02206
02207
02208 if (n = pdv_serial_wait(pdv_p, 200, 7))
02209 pdv_serial_read(pdv_p, cmdbuf, n);
02210
02211 return 0;
02212 }
02213
02217 static int
02218 pdv_set_blacklevel_cohu(PdvDev * pdv_p, int value)
02219 {
02220 char cmdbuf[128];
02221 int n, len;
02222
02223 if ((value < 0) || (value > 1023))
02224 return -1;
02225
02226
02227 cmdbuf[0] = 0x02;
02228 cmdbuf[1] = 0x01;
02229 sprintf(cmdbuf+2, "cB0,%d", value);
02230 len = strlen(cmdbuf);
02231 cmdbuf[len++] = (char)0x81;
02232 cmdbuf[len++] = (char)0x03;
02233 cmdbuf[len] = 0;
02234 pdv_serial_binary_command(pdv_p, (char *)cmdbuf, len);
02235
02236
02237 if (n = pdv_serial_wait(pdv_p, 200, 7))
02238 pdv_serial_read(pdv_p, cmdbuf, n);
02239
02240
02241 cmdbuf[0] = (char)0x02;
02242 cmdbuf[1] = (char)0x01;
02243 cmdbuf[2] = 'c';
02244 cmdbuf[3] = 'T';
02245 cmdbuf[4] = '0';
02246 cmdbuf[5] = (char)0x81;
02247 cmdbuf[6] = (char)0x03;
02248 pdv_serial_binary_command(pdv_p, (char *)cmdbuf, 7);
02249
02250
02251 if (n = pdv_serial_wait(pdv_p, 200, 7))
02252 pdv_serial_read(pdv_p, cmdbuf, n);
02253
02254 return 0;
02255 }
02256
02260 static int
02261 pdv_set_exposure_ptm6710_1020(PdvDev * pdv_p, int value)
02262 {
02263 char buf[128];
02264
02265 if ((value < 0) || (value > 9))
02266 return -1;
02267
02268 sprintf(buf, ":SM%d", value);
02269 pdv_serial_command_flagged(pdv_p, buf, SCFLAG_NORESP);
02270
02271 return 0;
02272 }
02273
02277 static int
02278 pdv_set_gain_ptm6710_1020(PdvDev * pdv_p, int value)
02279 {
02280 char buf[128];
02281
02282 if ((value < 0) || (value > 0xff))
02283 return -1;
02284
02285 sprintf(buf, ":GM%02X", value);
02286 pdv_serial_command_flagged(pdv_p, buf, SCFLAG_NORESP);
02287
02288 return 0;
02289 }
02290
02295 static int
02296 pdv_set_gain_hc8484(PdvDev * pdv_p, int value)
02297 {
02298 char buf[128];
02299
02300 if ((value != 0) && (value != 1))
02301 return -1;
02302 sprintf(buf, "CEG %c", value ? 'H' : 'L');
02303 pdv_serial_command_flagged(pdv_p, buf, SCFLAG_NORESP);
02304
02305 return 0;
02306 }
02307
02312 static int
02313 pdv_set_exposure_adimec(PdvDev * pdv_p, int value)
02314 {
02315 char cmdbuf[32];
02316
02317 sprintf(cmdbuf, "@IT%d", value);
02318 pdv_serial_command(pdv_p, cmdbuf);
02319 return 0;
02320 }
02321
02322 static int
02323 pdv_set_gain_adimec(PdvDev * pdv_p, int value)
02324 {
02325 char cmdbuf[32];
02326
02327 sprintf(cmdbuf, "@GA%d", value);
02328 pdv_serial_command(pdv_p, cmdbuf);
02329 return 0;
02330 }
02331
02332 static int
02333 pdv_set_blacklevel_adimec(PdvDev * pdv_p, int value)
02334 {
02335 char cmdbuf[32];
02336
02337 sprintf(cmdbuf, "@BL%d;%d", value, value);
02338 pdv_serial_command(pdv_p, cmdbuf);
02339 return 0;
02340 }
02341
02342
02347 static int
02348 pdv_set_exposure_specinst(PdvDev * pdv_p, int value)
02349 {
02350 edt_msg(DBG2, "pdv_set_exposure_specinst(%d)\n", value);
02351
02352 if (pdv_specinst_setparam(pdv_p, 'G', 8, value) != 0)
02353 {
02354 edt_msg(DBG2, "pdv_set_exposure_specinst() apparently FAILED\n");
02355 return -1;
02356 }
02357 return 0;
02358 }
02359
02364 static int
02365 pdv_set_gain_specinst(PdvDev * pdv_p, int value)
02366 {
02367 edt_msg(DBG2, "pdv_set_gain_specinst(%d)\n", value);
02368
02369 if (pdv_specinst_setparam(pdv_p, 'G', 11, value) != 0)
02370 {
02371 edt_msg(DBG2, "pdv_set_gain_specinst() apparently FAILED\n");
02372 return -1;
02373 }
02374 return 0;
02375 }
02376
02382 static int
02383 pdv_set_exposure_su320(PdvDev * pdv_p, int value)
02384 {
02385 char cmdbuf[32];
02386 char resp[1024];
02387 int n;
02388
02389 sprintf(cmdbuf, "INT%d", value);
02390 pdv_serial_command(pdv_p, cmdbuf);
02391 pdv_serial_wait(pdv_p, 100, 20);
02392 if ((n = pdv_serial_read(pdv_p, resp, 20)) != 20)
02393 return -1;
02394 return 0;
02395 }
02396
02397
02398 static int
02399 pdv_specinst_setparam(PdvDev * pdv_p, char cmd, u_long offset, u_long value)
02400 {
02401 int ret1, ret2, ret3;
02402 char resp1[32];
02403 char resp2[32];
02404 char buf[32];
02405 u_char cmdbuf[5];
02406 u_char offsetbuf[5];
02407 u_char parambuf[5];
02408 int si_wait = 200;
02409
02410 edt_msg(DBG2, "pdv_specinst_setparam(%c %04x %04x)\n", cmd, offset, value);
02411
02412 dvu_long_to_charbuf(offset, offsetbuf);
02413 dvu_long_to_charbuf(value, parambuf);
02414
02415 cmdbuf[0] = cmd;
02416
02417 pdv_serial_binary_command(pdv_p, (char *) cmdbuf, 1);
02418 pdv_serial_wait_next(pdv_p, si_wait, 31);
02419 ret1 = pdv_serial_read(pdv_p, resp1, 31);
02420
02421 pdv_serial_binary_command(pdv_p, (char *) offsetbuf, 4);
02422 pdv_serial_wait_next(pdv_p, si_wait, 31);
02423 ret2 = pdv_serial_read(pdv_p, buf, 31);
02424
02425 pdv_serial_binary_command(pdv_p, (char *) parambuf, 4);
02426 pdv_serial_wait_next(pdv_p, si_wait, 31);
02427 ret3 = pdv_serial_read(pdv_p, resp2, 31);
02428
02429 if ((ret1 != 1) || (ret3 != 1) || (resp1[0] != 'G') || (resp2[0] != 'Y'))
02430 {
02431 edt_msg(DBG1, "invalid or missing serial response from specinst\n");
02432 return -1;
02433 }
02434 return 0;
02435 }
02436
02450 int
02451 pdv_send_basler_command(PdvDev * pdv_p, int cmd, int rwflag, int len, int data)
02452 {
02453 int i;
02454 u_char frame[32];
02455 u_char rwbit = (rwflag & 0x1) << 7;
02456
02457 frame[0] = cmd;
02458 frame[1] = ((u_char)len & 0xef) | rwbit;
02459 for (i=0; i<len; i++)
02460 frame[i+2] = (data >> (8 * i)) & 0xff;
02461
02462 return pdv_send_basler_frame(pdv_p, frame, len+2);
02463 }
02464
02470 int
02471 pdv_set_exposure_basler202k(PdvDev * pdv_p, int value)
02472 {
02473 u_char rframe[8];
02474
02475 memset(rframe, 0, 8);
02476 pdv_send_basler_command(pdv_p, 0xa6, 0, 3, value);
02477 pdv_read_basler_frame(pdv_p, rframe, 1);
02478 if (rframe[0] != 0x6)
02479 return -1;
02480 return 0;
02481 }
02482
02483 int
02484 pdv_set_gain_basler202k(PdvDev * pdv_p, int valuea, int valueb)
02485 {
02486 u_char rframe[8];
02487
02488 memset(rframe, 0, 8);
02489 pdv_send_basler_command(pdv_p, 0x80, 0, 2, valuea);
02490 pdv_read_basler_frame(pdv_p, rframe, 1);
02491 if (rframe[0] != 0x6)
02492 return -1;
02493
02494 memset(rframe, 0, 8);
02495 pdv_send_basler_command(pdv_p, 0x82, 0, 2, valueb);
02496 pdv_read_basler_frame(pdv_p, rframe, 1);
02497 if (rframe[0] != 0x6)
02498 return -1;
02499
02500 return 0;
02501 }
02502
02503 int
02504 pdv_set_offset_basler202k(PdvDev * pdv_p, int valuea, int valueb)
02505 {
02506 u_char rframe[8];
02507
02508 memset(rframe, 0, 8);
02509 pdv_send_basler_command(pdv_p, 0x81, 0, 2, valuea);
02510 pdv_read_basler_frame(pdv_p, rframe, 1);
02511 if (rframe[0] != 0x6)
02512 return -1;
02513
02514 memset(rframe, 0, 8);
02515 pdv_send_basler_command(pdv_p, 0x83, 0, 2, valueb);
02516 pdv_read_basler_frame(pdv_p, rframe, 1);
02517 if (rframe[0] != 0x6)
02518 return -1;
02519 return 0;
02520 }
02521
02538 int
02539 pdv_set_exposure_duncan_ch(PdvDev * pdv_p, int value, int ch)
02540 {
02541 u_char msg[8];
02542 u_char rmsg[16];
02543
02544 msg[0] = 0x04;
02545 msg[1] = 0x00;
02546 msg[2] = 0x14;
02547 msg[3] = (u_char)(ch & 0xff);
02548 msg[4] = (u_char)(value & 0xff);
02549 msg[5] = (u_char)((value >> 8) & 0xff);
02550 pdv_send_duncan_frame(pdv_p, msg, 6);
02551 pdv_read_duncan_frame(pdv_p, rmsg);
02552 return 0;
02553 }
02554
02571 int
02572 pdv_set_gain_duncan_ch(PdvDev * pdv_p, int value, int ch)
02573 {
02574 u_char msg[8];
02575 u_char rmsg[16];
02576
02577 msg[0] = 0x04;
02578 msg[1] = 0x00;
02579 msg[2] = 0x02;
02580 msg[3] = (u_char)(ch & 0xff);
02581 msg[4] = (u_char)(value & 0xff);
02582 msg[5] = (u_char)((value >> 8) & 0xff);
02583 pdv_send_duncan_frame(pdv_p, msg, 6);
02584 pdv_read_duncan_frame(pdv_p, rmsg);
02585 return 0;
02586 }
02587
02588
02593 static void
02594 send_serial_binary_cmd(PdvDev * pdv_p, char *hexstr, int value)
02595 {
02596 int nb;
02597 u_char hbuf[2];
02598 char resp[128];
02599 char bs[16][3];
02600 int ret;
02601
02602 edt_msg(DBG2, "send_serial_binary_cmd(\"%s\", %d)\n", hexstr, value);
02603
02604 nb = sscanf(hexstr, "%s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s",
02605 bs[0], bs[1], bs[2], bs[3], bs[4], bs[5], bs[6], bs[7],
02606 bs[8], bs[9], bs[10], bs[11], bs[12], bs[13], bs[14], bs[15]);
02607
02608 pdv_serial_binary_command(pdv_p, (char *) hbuf, nb);
02609 pdv_serial_wait(pdv_p, 100, 3);
02610
02611 if (*pdv_p->dd_p->serial_response)
02612 ret = pdv_serial_read(pdv_p, resp, 50);
02613
02614 {
02615
02616 edt_msg(DBG2, "serial response <%s> (%d)\n", hex_to_str(resp, ret), ret);
02617 }
02618 }
02619
02646 int
02647 pdv_auto_set_timeout(PdvDev * pdv_p)
02648 {
02649 Dependent *dd_p = pdv_p->dd_p;
02650 int user_timeout = dd_p->user_timeout;
02651 int user_set = dd_p->user_timeout_set;
02652 int tmult = dd_p->timeout_multiplier;
02653 int cur_timeout = edt_get_rtimeout(pdv_p);
02654 int timeout;
02655 int exposure;
02656 int pdiv = 1;
02657 int ret = 0;
02658 int xfersize;
02659
02660
02661
02662
02663 if (tmult < 1)
02664 tmult = 1;
02665
02666
02667 if (dd_p->pclock_speed < 5)
02668 dd_p->pclock_speed = 5;
02669 pdiv = dd_p->pclock_speed / 5;
02670
02671 if (((exposure = dd_p->shutter_speed)) < 500)
02672 exposure = 500;
02673
02674 xfersize = dd_p->cam_width * dd_p->cam_height * bits2bytes(dd_p->depth);
02675 timeout = (((xfersize * tmult) / 4000) / pdiv) + exposure;
02676
02677 edt_msg(DBG2, "pdv_auto_set_timeout(): current %d new %d exposure %d pclock %d pdiv %d mult %d user %d\n",
02678 cur_timeout, timeout, exposure, dd_p->pclock_speed, pdiv,
02679 tmult, user_timeout);
02680
02681
02682
02683
02684
02685 if (timeout < 500)
02686 timeout = 500;
02687
02688 if (user_set)
02689 {
02690 edt_msg(DBG2, " user set to %d - overriding auto\n", user_timeout);
02691
02692 if (timeout > user_timeout && user_timeout != 0)
02693 {
02694 edt_msg(DBG2, " Warning: exposure %d msecs user specified timeout %d msecs\n", dd_p->shutter_speed, user_timeout);
02695 edt_msg(DBG2, " not automatically increased since user specified\n");
02696 }
02697 }
02698 else
02699 {
02700 int targ;
02701
02702 edt_msg(DBG2, " setting picture timeout from %d to %d\n", cur_timeout, timeout);
02703 targ = timeout;
02704 ret = edt_set_rtimeout(pdv_p, targ);
02705 }
02706 return ret;
02707 }
02708
02728 int
02729 pdv_set_gain(PdvDev * pdv_p, int value)
02730 {
02731 int ret;
02732 Dependent *dd_p = pdv_p->dd_p;
02733
02734 edt_msg(DBG2, "pdv_set_gain(%d)\n", value);
02735
02736 dd_p->gain = value;
02737 ret = edt_set_dependent(pdv_p, dd_p);
02738
02739 if ((strlen(dd_p->serial_gain) > 0) && (dd_p->serial_format == SERIAL_BINARY))
02740 send_serial_binary_cmd(pdv_p, dd_p->serial_gain, value);
02741
02742 else if (dd_p->serial_format == SERIAL_ASCII)
02743 {
02744 char cmdstr[64] = {'\0'};
02745 int n = check_valid_formatstr(dd_p->serial_gain);
02746
02747 if (n == 0)
02748 sprintf(cmdstr, "%s %d", dd_p->serial_gain, value);
02749 else if ((n > 0) && (n < 5))
02750 sprintf(cmdstr, dd_p->serial_gain, value, value, value, value);
02751
02752 if (cmdstr)
02753 {
02754 ret = pdv_serial_command_flagged(pdv_p, cmdstr, SCFLAG_NORESP);
02755
02756 pdv_serial_wait(pdv_p, pdv_p->dd_p->serial_timeout, 64);
02757 if (*pdv_p->dd_p->serial_response)
02758 pdv_serial_read(pdv_p, cmdstr, 63);
02759 }
02760 }
02761
02762 else if ((strncasecmp(dd_p->camera_class, "Hamamatsu", 9) == 0)
02763 && ((strncasecmp(dd_p->camera_model, "C8484", 5) == 0)
02764 || (strncasecmp(dd_p->camera_model, "8484", 4) == 0)))
02765 {
02766 ret = pdv_set_gain_hc8484(pdv_p, value);
02767 }
02768
02769 else if ((dd_p->camera_shutter_timing == SPECINST_SERIAL)
02770 || (dd_p->camera_shutter_speed == SPECINST_SERIAL))
02771 {
02772 ret = pdv_set_gain_specinst(pdv_p, value);
02773 }
02774 else if (dd_p->camera_shutter_timing == TOSHIBA_SERIAL)
02775 {
02776 ret = pdv_set_gain_toshiba(pdv_p, value);
02777 }
02778 else if (dd_p->camera_shutter_timing == COHU_SERIAL)
02779 {
02780 ret = pdv_set_gain_cohu(pdv_p, value);
02781 }
02782 else if (dd_p->set_gain == SMD_SERIAL)
02783 {
02784 ret = pdv_set_gain_smd(pdv_p, value);
02785 }
02786 else if ((strncasecmp(dd_p->camera_class, "Adimec", 6) == 0))
02787 {
02788 ret = pdv_set_gain_adimec(pdv_p, value);
02789 }
02790
02791 else if ((strncasecmp(dd_p->camera_class, "PULNiX", 6) == 0)
02792 && ((strncasecmp(dd_p->camera_model, "TM-6710", 7) == 0)
02793 || (strncasecmp(dd_p->camera_model, "TM-1020", 7) == 0)))
02794 {
02795 ret = pdv_set_gain_ptm6710_1020(pdv_p, value);
02796 }
02797
02798 else if ((dd_p->set_gain == AIA_MC4)
02799 && (dd_p->xilinx_rev >= 1 && dd_p->xilinx_rev <= 32))
02800 {
02801 u_int util2 = edt_reg_read(pdv_p, PDV_UTIL2);
02802 u_int mcl = edt_reg_read(pdv_p, PDV_MODE_CNTL);
02803
02804 edt_reg_write(pdv_p, PDV_UTIL2, util2 & ~PDV_MC4);
02805 edt_reg_write(pdv_p, PDV_MODE_CNTL, dd_p->gain);
02806 edt_reg_write(pdv_p, PDV_UTIL2, util2 | PDV_MC4);
02807 edt_reg_write(pdv_p, PDV_MODE_CNTL, mcl);
02808 }
02809
02810 edt_msg(DBG2, "pdv_set_gain returning %d\n", ret);
02811 return (ret);
02812 }
02813
02817 static int
02818 pdv_set_gain_smd(PdvDev * pdv_p, int value)
02819 {
02820 char buf[128];
02821 char smd_config;
02822 int smd_reg1;
02823 int ret = 0;
02824
02825 if (Smd_type == NOT_SET)
02826 {
02827 Smd_type = smd_read_reg(pdv_p, SMD_READ_CAMTYPE);
02828 if ((Smd_type & 0xfff) == 0xfff)
02829
02830 Smd_type = smd_read_reg(pdv_p, SMD_READ_CAMTYPE);
02831 }
02832
02833 switch (Smd_type)
02834 {
02835 case SMD_TYPE_4M4:
02836 buf[0] = (char) SMD_4M4_READ_R1;
02837 pdv_serial_binary_command(pdv_p, buf, 1);
02838 pdv_serial_wait(pdv_p, pdv_p->dd_p->serial_timeout,
02839 pdv_p->dd_p->serial_respcnt);
02840 if (pdv_serial_read(pdv_p, buf, 63) == 1)
02841 {
02842 smd_config = buf[0];
02843
02844 buf[0] = (char) SMD_4M4_WRITE_R1;
02845 pdv_serial_binary_command(pdv_p, buf, 1);
02846
02847 if (value == 0)
02848 smd_config &= ~SMD_4M4_R1_GAIN;
02849 else
02850 smd_config |= SMD_4M4_R1_GAIN;
02851 buf[0] = smd_config;
02852 pdv_serial_binary_command(pdv_p, buf, 1);
02853
02854 pdv_serial_wait(pdv_p, 100, 64);
02855 }
02856 else
02857 ret = -1;
02858 break;
02859
02860 case SMD_TYPE_1M30P:
02861 buf[0] = (u_char) SMD_1M30P_REG_W_LS_GAIN;
02862 buf[1] = value & 0xff;
02863 pdv_serial_binary_command(pdv_p, (char *) buf, 2);
02864
02865 buf[0] = (u_char) SMD_1M30P_REG_W_MS_GAIN;
02866 buf[1] = (value & 0xff00) >> 8;
02867 pdv_serial_binary_command(pdv_p, (char *) buf, 2);
02868
02869
02870 pdv_serial_wait(pdv_p, 100, 64);
02871 break;
02872
02873 case SMD_TYPE_1M15P:
02874 case SMD_TYPE_6M3P:
02875 if ((smd_reg1 = smd_read_reg(pdv_p, SMD_1M15P_READ_R1)) == -1)
02876 {
02877 edt_msg(PDVWARN, "libpdv: no response from SMD R1 reg read\n");
02878 return -1;
02879 }
02880
02881 buf[0] = (u_char) SMD_1M15P_WRITE_R1;
02882
02883
02884
02885
02886 if (value == 0)
02887 buf[1] = smd_reg1 &~ SMD_1M15P_R1_GAIN;
02888 else if (value == 1)
02889 buf[1] = smd_reg1 | SMD_1M15P_R1_GAIN;
02890 else return -1;
02891
02892 pdv_serial_binary_command(pdv_p, (char *) buf, 2);
02893 pdv_p->dd_p->gain = value;
02894
02895
02896 pdv_serial_wait(pdv_p, 100, 64);
02897 break;
02898 }
02899
02900 return ret;
02901 }
02902
02911 int
02912 pdv_set_gain_ch(PdvDev * pdv_p, int value, int chan)
02913 {
02914 int ret = -1;
02915
02916
02917 edt_msg(DBG2, "pdv_set_gain_ch(%d, [%c]) ret %d\n",
02918 value, (chan == 1) ? 'A' : (chan == 2) ? 'B' : '?', ret);
02919 return (ret);
02920 }
02921
02939 int
02940 pdv_set_blacklevel(PdvDev * pdv_p, int value)
02941 {
02942 Dependent *dd_p = pdv_p->dd_p;
02943 int ret;
02944
02945 edt_msg(DBG2, "pdv_set_blacklevel(%d)\n", value);
02946
02947 dd_p->level = value;
02948 ret = edt_set_dependent(pdv_p, dd_p);
02949
02950 if (dd_p->set_offset == SMD_SERIAL)
02951 ret = pdv_set_blacklevel_smd(pdv_p, value);
02952
02953 else if (dd_p->camera_shutter_timing == COHU_SERIAL)
02954 {
02955 ret = pdv_set_blacklevel_cohu(pdv_p, value);
02956 }
02957
02958 else if ((strncasecmp(dd_p->camera_class, "Adimec", 6) == 0))
02959 {
02960 ret = pdv_set_blacklevel_adimec(pdv_p, value);
02961 }
02962
02963 else if ((strlen(dd_p->serial_offset) > 0) && (dd_p->serial_format == SERIAL_BINARY))
02964 {
02965 send_serial_binary_cmd(pdv_p, dd_p->serial_offset, value);
02966 }
02967
02968 else if (dd_p->serial_format == SERIAL_ASCII)
02969 {
02970 char cmdstr[64] = {'\0'};
02971 int n = check_valid_formatstr(dd_p->serial_offset);
02972
02973 if (n == 0)
02974 sprintf(cmdstr, "%s %d", dd_p->serial_offset, value);
02975 else if ((n > 0) && (n < 5))
02976 sprintf(cmdstr, dd_p->serial_offset, value, value, value, value);
02977
02978 if (cmdstr[0])
02979 {
02980 ret = pdv_serial_command_flagged(pdv_p, cmdstr, SCFLAG_NORESP);
02981
02982 pdv_serial_wait(pdv_p, pdv_p->dd_p->serial_timeout, 64);
02983 if (*pdv_p->dd_p->serial_response)
02984 pdv_serial_read(pdv_p, cmdstr, 63);
02985 }
02986 }
02987
02988 edt_msg(DBG2, "pdv_set_blacklevel() %d\n", ret);
02989 return (ret);
02990 }
02991
02992 static int
02993 pdv_set_blacklevel_smd(PdvDev * pdv_p, int value)
02994 {
02995 char buf[128];
02996 int ret = 0;
02997 int tmpval = value & 0xfff;
02998 int smd_reg2, smd_reg3;
02999
03000 if (Smd_type == NOT_SET)
03001 {
03002 Smd_type = smd_read_reg(pdv_p, SMD_READ_CAMTYPE);
03003 if ((Smd_type & 0xfff) == 0xfff)
03004
03005 Smd_type = smd_read_reg(pdv_p, SMD_READ_CAMTYPE);
03006 }
03007
03008 switch (Smd_type)
03009 {
03010 case SMD_TYPE_4M4:
03011 case SMD_TYPE_BT25:
03012 break;
03013
03014 case SMD_TYPE_1M30P:
03015 buf[0] = (u_char) SMD_1M30P_REG_W_LS_OFFSET;
03016 buf[1] = value & 0xff;
03017 pdv_serial_binary_command(pdv_p, (char *) buf, 2);
03018
03019 buf[0] = (u_char) SMD_1M30P_REG_W_MS_OFFSET;
03020 buf[1] = (value & 0xff00) >> 8;
03021 pdv_serial_binary_command(pdv_p, (char *) buf, 2);
03022
03023
03024 pdv_serial_wait(pdv_p, 100, 64);
03025 break;
03026
03027 case SMD_TYPE_1M15P:
03028 if ((smd_reg3 = smd_read_reg(pdv_p, SMD_1M15P_READ_R3)) == -1)
03029 {
03030 edt_msg(PDVWARN, "libpdv: no response from Dalstar R3 reg read\n");
03031 ret = -1;
03032 }
03033
03034 smd_reg2 = tmpval >> 4;
03035 smd_reg3 = (smd_reg3 & ~0x0f) | (tmpval & 0x0f);
03036
03037
03038 buf[0] = (u_char) SMD_1M15P_WRITE_R3;
03039 buf[1] = (u_char) smd_reg3;
03040 pdv_serial_binary_command(pdv_p, (char *) buf, 2);
03041
03042
03043 buf[0] = (u_char) SMD_1M15P_WRITE_R2;
03044 buf[1] = (u_char) smd_reg2;
03045 pdv_serial_binary_command(pdv_p, (char *) buf, 2);
03046
03047
03048 pdv_serial_wait(pdv_p, 100, 64);
03049 break;
03050
03051 default:
03052 ret = -1;
03053 }
03054
03055 return ret;
03056 }
03057
03066 int
03067 pdv_set_aperture(PdvDev * pdv_p, int value)
03068 {
03069 edt_msg(PDVWARN, "pdv_set_aperture is OBSOLETE\n");
03070 return (-1);
03071 }
03072
03114 int
03115 pdv_set_binning(PdvDev * pdv_p, int xval, int yval)
03116 {
03117 int ret = -1;
03118 int newvskip, newhskip, newwidth, newheight;
03119 Dependent *dd_p = pdv_p->dd_p;
03120
03121 if (((xval != 1) && (xval % 2)) || ((yval != 1) && (yval % 2)))
03122 {
03123 edt_msg(PDVWARN, "pdv_set_binning(%d, %d) -- invalid value\n", xval, yval);
03124 return -1;
03125 }
03126
03127 edt_msg(DBG2, "pdv_set_binning(%d, %d)\n", xval, yval);
03128
03129 if (strcmp(dd_p->serial_binning, "BIN") == 0)
03130 {
03131 ret = pdv_set_binning_dvc(pdv_p, xval, yval);
03132 }
03133 else if (strcmp(dd_p->serial_binning, "B=") == 0)
03134 {
03135 ret = pdv_set_binning_generic(pdv_p, xval - 1);
03136 }
03137 else if (*dd_p->serial_binning)
03138 {
03139
03140 ret = pdv_set_binning_generic(pdv_p, xval);
03141 }
03142 else
03143 return -1;
03144
03145 if (ret)
03146 return ret;
03147
03148 if (dd_p->binx < 1)
03149 dd_p->binx = 1;
03150 if (dd_p->biny < 1)
03151 dd_p->biny = 1;
03152
03153 newwidth = (((pdv_get_width(pdv_p) * dd_p->binx) / xval) / 4) * 4;
03154 newheight = (((pdv_get_height(pdv_p) * dd_p->biny) / yval)) ;
03155
03156 if (dd_p->roi_enabled)
03157 {
03158 newhskip = (dd_p->hskip * dd_p->binx) / xval;
03159 newvskip = (dd_p->vskip * dd_p->biny) / yval;
03160 ret = pdv_set_roi(pdv_p, newhskip, newwidth, newvskip, newheight);
03161 }
03162
03163 if (!ret)
03164 {
03165 dd_p->binx = xval;
03166 dd_p->biny = yval;
03167 }
03168
03169 return (ret);
03170 }
03171
03177 static int
03178 pdv_set_binning_generic(PdvDev * pdv_p, int value)
03179 {
03180 char cmdstr[64];
03181 Dependent *dd_p = pdv_p->dd_p;
03182
03183 if (dd_p->serial_binning[strlen(dd_p->serial_binning) - 1] == '=')
03184 sprintf(cmdstr, "%s%d", dd_p->serial_binning, value);
03185 else
03186 sprintf(cmdstr, "%s %d", dd_p->serial_binning, value);
03187 pdv_serial_command_flagged(pdv_p, cmdstr, SCFLAG_NORESP);
03188
03189 return (0);
03190 }
03191
03192
03205 int
03206 pdv_get_exposure(PdvDev * pdv_p)
03207 {
03208 edt_msg(DBG2, "pdv_get_exposure() %d\n", pdv_p->dd_p->shutter_speed);
03209
03210 return (pdv_p->dd_p->shutter_speed);
03211 }
03212
03213 void
03214 pdv_set_defaults(PdvDev * pdv_p)
03215 {
03216 Dependent *dd_p = pdv_p->dd_p;
03217
03218 if (dd_p->default_shutter_speed != NOT_SET)
03219 pdv_set_exposure(pdv_p, dd_p->default_shutter_speed);
03220 if (dd_p->default_gain != NOT_SET)
03221 pdv_set_gain(pdv_p, dd_p->default_gain);
03222 if (dd_p->default_offset != NOT_SET)
03223 pdv_set_blacklevel(pdv_p, dd_p->default_offset);
03224 }
03225
03237 int
03238 pdv_read_response(PdvDev * pdv_p, char *buf)
03239 {
03240 int len;
03241
03242
03243
03244
03245 len = pdv_serial_wait(pdv_p, pdv_p->dd_p->serial_timeout, 2048);
03246 if (len)
03247 pdv_serial_read(pdv_p, buf, len);
03248 return len;
03249 }
03250
03251
03265 int
03266 pdv_get_gain(PdvDev * pdv_p)
03267 {
03268 edt_msg(DBG2, "pdv_get_gain() %d\n", pdv_p->dd_p->gain);
03269
03270 return (pdv_p->dd_p->gain);
03271 }
03272
03273
03283 int
03284 pdv_get_blacklevel(PdvDev * pdv_p)
03285 {
03286 edt_msg(DBG2, "pdv_get_blacklevel() %d\n", pdv_p->dd_p->level);
03287
03288 return (pdv_p->dd_p->level);
03289 }
03290
03299 int
03300 pdv_get_aperture(PdvDev * pdv_p)
03301 {
03302 edt_msg(PDVWARN, "pdv_get_aperture is OBSOLETE\n");
03303 return (-1);
03304 }
03305
03316 void
03317 pdv_invert(PdvDev * pdv_p, int val)
03318 {
03319 u_int data_path;
03320 int ret;
03321
03322 edt_msg(DBG2, "pdv_invert()\n");
03323
03324 if (pdv_p->devid == PDVFOI_ID)
03325 {
03326 char buf[64];
03327
03328 pdv_serial_wait(pdv_p, pdv_p->dd_p->serial_timeout, pdv_p->dd_p->serial_respcnt);
03329 if (*pdv_p->dd_p->serial_response)
03330 ret = pdv_serial_read(pdv_p, buf, 63);
03331 }
03332
03333
03334 data_path = pdv_p->dd_p->datapath_reg;
03335
03336 edt_msg(DBG2, "pdv_invert(%d)\n", val);
03337
03338 if (val)
03339 data_path |= PDV_INVERT;
03340 else
03341 data_path &= ~PDV_INVERT;
03342
03343 edt_reg_write(pdv_p, PDV_DATA_PATH, data_path);
03344 pdv_p->dd_p->datapath_reg = data_path;
03345 }
03346
03352 u_short
03353 pdv_get_interlaced(PdvDev * pdv_p)
03354
03355 {
03356 edt_msg(DBG2, "pdv_get_interlaced() %u\n", pdv_p->dd_p->interlace);
03357
03358 return (pdv_p->dd_p->interlace);
03359 }
03360
03383 int
03384 pdv_force_single(PdvDev * pdv_p)
03385 {
03386 return pdv_p->dd_p->force_single;
03387 }
03388
03396 int
03397 pdv_variable_size(PdvDev * pdv_p)
03398 {
03399 return pdv_p->dd_p->variable_size;
03400 }
03401
03402
03403
03423 int
03424 pdv_serial_read_nullterm(PdvDev * pdv_p, char *buf, int size, int nullterm)
03425 {
03426 #define PKT_OVERHEAD 2
03427 #define PKT_SIZE_MAX 15
03428
03429 int bytesReturned;
03430 Dependent *dd_p;
03431
03432 if (pdv_p == NULL || pdv_p->dd_p == NULL)
03433 return 0;
03434
03435 dd_p = pdv_p->dd_p;
03436
03437 if (buf == NULL || pdv_p == NULL || size == 0)
03438 return (-1);
03439
03440 if (pdv_p->devid == PDVFOI_ID)
03441 {
03442 char tmpbuf[256];
03443
03444 bytesReturned = edt_get_msg(pdv_p, tmpbuf, 256);
03445 if (bytesReturned <= PKT_OVERHEAD)
03446 return (0);
03447 if (Pdv_debug)
03448 {
03449 int i, num = bytesReturned;
03450
03451 if (num > 16)
03452 num = 16;
03453 edt_msg(DBG2, "pdv_serial_read(<");
03454 for (i = 0; i < num; i++)
03455 {
03456 edt_msg(DBG2, "%02x", (u_char) tmpbuf[i]);
03457 if (i + 1 < num)
03458 edt_msg(DBG2, ", ");
03459 else
03460 break;
03461 }
03462 edt_msg(DBG2, ">, %d-%d\n", bytesReturned, size);
03463 }
03464 if (bytesReturned > size)
03465 {
03466 memcpy(buf, &tmpbuf[PKT_OVERHEAD], size);
03467 edt_msg(DBG2, "pdv_serial_read(%d) %d\n", size, bytesReturned);
03468 return (size);
03469 }
03470 else
03471 {
03472 bytesReturned -= PKT_OVERHEAD;
03473 memcpy(buf, &tmpbuf[PKT_OVERHEAD], bytesReturned);
03474 if (nullterm)
03475 buf[bytesReturned] = 0;
03476 edt_msg(DBG2, "pdv_serial_read(%d) %d\n", size, bytesReturned);
03477 return (bytesReturned);
03478 }
03479 }
03480
03481 #if 0
03482 if (!pdv_get_width(pdv_p))
03483 {
03484 edt_msg(DBG2, "warning - serial_read called with uninitialized camera\n");
03485 return (0);
03486 }
03487 #endif
03488
03489 bytesReturned = edt_get_msg(pdv_p, buf, size);
03490 assert(bytesReturned <= size);
03491
03492 if (nullterm)
03493 buf[bytesReturned] = 0;
03494
03495 if (Pdv_debug)
03496 {
03497 int i, num = bytesReturned;
03498
03499 if (num > 16)
03500 num = 16;
03501 edt_msg(DBG2, "pdv_serial_read(<");
03502 for (i = 0; i < num; i++)
03503 {
03504 edt_msg(DBG2, "%02x", (u_char) buf[i]);
03505 if (i + 1 < num)
03506 edt_msg(DBG2, ", ");
03507 else
03508 break;
03509 }
03510 edt_msg(DBG2, ">, %d)\n", size);
03511 }
03512 return bytesReturned;
03513 }
03514
03546 int
03547 pdv_serial_read(PdvDev * pdv_p, char *buf, int count)
03548 {
03549
03550 return pdv_serial_read_nullterm(pdv_p,buf,count,TRUE);
03551 }
03552
03559 int
03560 pdv_send_msg(PdvDev *ed, int chan, const char *buf, int size)
03561 {
03562 int i, ret = 0;
03563 int pause = ed->dd_p->pause_for_serial;
03564 char bbuf[32];
03565
03566
03567 if (pause)
03568 {
03569 for (i=0; i<size; i++)
03570 {
03571 bbuf[0] = buf[i];
03572 edt_msleep(ed->dd_p->pause_for_serial);
03573 if ((ret = edt_send_msg(ed, chan, bbuf, 1)) != 0)
03574 return ret;
03575 }
03576 return ret;
03577 }
03578 else return edt_send_msg(ed, chan, buf, size);
03579 }
03580
03596 int
03597 pdv_serial_write_single_block(PdvDev * pdv_p, const char *buf, int size)
03598 {
03599 int ret;
03600 Dependent *dd_p;
03601
03602 if (size == 0)
03603 return (-1);
03604
03605 if (Pdv_debug)
03606 {
03607 int i, num = size;
03608
03609 if (num > 16)
03610 num = 16;
03611 edt_msg(DBG2, "pdv_serial_write_single_block(<");
03612 for (i = 0; i < num; i++)
03613 {
03614 edt_msg(DBG2, "%02x", (u_char) buf[i]);
03615 if (i + 1 < num)
03616 edt_msg(DBG2, ", ");
03617 else
03618 break;
03619 }
03620 edt_msg(DBG2, ">, %d)\n", size);
03621 }
03622
03623 if (buf == NULL || pdv_p == NULL || pdv_p->dd_p == NULL)
03624 return (-1);
03625 dd_p = pdv_p->dd_p;
03626
03627 ret = pdv_send_msg(pdv_p, pdv_p->channel_no, buf, size);
03628 return (ret);
03629 }
03630
03639 int
03640 pdv_serial_write_available(PdvDev *pdv_p)
03641
03642 {
03643
03644 int avail;
03645
03646 edt_ioctl(pdv_p, EDTG_SERIAL_WRITE_AVAIL, &avail);
03647
03648 return avail;
03649
03650 }
03651
03652 static int pdv_serial_block_size = 512;
03653
03659 void pdv_set_serial_block_size(int newsize)
03660 {
03661 pdv_serial_block_size = newsize;
03662 }
03663
03670 int
03671 pdv_get_serial_block_size()
03672 {
03673 return pdv_serial_block_size;
03674 }
03675
03679 int
03680 pdv_serial_read_enable(PdvDev *pdv_p)
03681
03682 {
03683
03684 edt_reg_or(pdv_p, PDV_SERIAL_DATA_CNTL,
03685 PDV_EN_TX | PDV_EN_RX |
03686 PDV_EN_RX_INT | PDV_EN_DEV_INT);
03687
03688 edt_set_remote_intr(pdv_p, TRUE);
03689
03690 return 0;
03691 }
03692
03709 int
03710 pdv_serial_write(PdvDev *pdv_p, const char *buf, int size)
03711
03712 {
03713 int avail;
03714 int left = size;
03715 int ret = 0;
03716 int offset = 0;
03717 int speed = pdv_get_baud(pdv_p);
03718 int sleepval;
03719 int chunk = pdv_serial_block_size;
03720
03721 if (speed != 0)
03722 sleepval = speed/10;
03723 else
03724 sleepval = 10;
03725
03726 sleepval = (chunk * 1000) / sleepval;
03727
03728 avail = pdv_serial_write_available(pdv_p);
03729 if (avail > size)
03730 {
03731 return pdv_serial_write_single_block(pdv_p, buf, size);
03732 }
03733 else
03734 {
03735 left -= avail;
03736 offset += avail;
03737
03738 #ifdef DBG_SERIAL
03739 printf("Writing %d chars\n", avail);
03740 #endif
03741
03742 ret = pdv_serial_write_single_block(pdv_p, buf, avail);
03743
03744 if (ret != 0)
03745 return ret;
03746 while (left > 0)
03747 {
03748 edt_msleep(sleepval);
03749 avail = pdv_serial_write_available(pdv_p);
03750 if (avail > 0)
03751 {
03752 if ( avail > left)
03753 {
03754 avail = left;
03755 left = 0;
03756 }
03757 else
03758 {
03759 left -= avail;
03760 }
03761
03762 #ifdef DBG_SERIAL
03763 printf("Writing %d chars\n", avail);
03764 #endif
03765 ret = pdv_serial_write_single_block(pdv_p, buf+offset, avail);
03766 if (ret != 0)
03767 return ret;
03768 offset += avail;
03769
03770 }
03771 }
03772 }
03773 return 0;
03774 }
03775
03792 int
03793 pdv_serial_read_blocking(PdvDev *pdv_p, char *buf, int size)
03794
03795 {
03796 int left = size;
03797 int ret = 0;
03798 int offset = 0;
03799
03800
03801 int avail = 1024;
03802 int speed = pdv_get_baud(pdv_p);
03803 int sleepval;
03804 int chunk = pdv_serial_block_size;
03805
03806 if (speed != 0)
03807 sleepval = speed/10;
03808 else
03809 sleepval = 10;
03810
03811 sleepval = (chunk * 1000) / sleepval;
03812
03813 if (avail > size)
03814 {
03815 sleepval = (size * 1000) / sleepval;
03816
03817 pdv_serial_wait(pdv_p, sleepval, size);
03818
03819 return pdv_serial_read(pdv_p, buf, size);
03820 }
03821 else
03822 {
03823
03824 while (left > 0)
03825 {
03826 avail = pdv_serial_wait(pdv_p, sleepval, chunk);
03827 if (avail)
03828 {
03829 if ( avail > left)
03830 {
03831 avail = left;
03832 left = 0;
03833 }
03834 else
03835 {
03836 left -= avail;
03837 }
03838
03839 #ifdef DBG_SERIAL
03840 printf("Reading %d chars total = %d\n", avail, offset + avail);
03841 #endif
03842 ret = pdv_serial_read(pdv_p, buf+offset, avail);
03843 offset += avail;
03844
03845 }
03846
03847
03848 }
03849
03850 }
03851
03852 return 0;
03853
03854 }
03855
03856
03900 int
03901 pdv_serial_command(PdvDev * pdv_p, const char *cmd)
03902 {
03903
03904
03905
03906
03907
03908
03909
03910
03911
03912
03913
03914 return pdv_serial_command_flagged(pdv_p, cmd, 0);
03915 }
03916
03933 int
03934 pdv_serial_command_flagged(PdvDev * pdv_p, const char *cmd, u_int flag)
03935 {
03936 char *buf;
03937 int ret;
03938 int i;
03939 size_t len=0;
03940 int bufsize=8;
03941 const char *p = cmd;
03942
03943 if (pdv_p == NULL || pdv_p->dd_p == NULL)
03944 return -1;
03945
03946
03947 while (*p++)
03948 ++bufsize;
03949 buf = (char *)malloc(bufsize+16);
03950
03951
03952
03953 if (pdv_p->devid == PDVFOI_ID)
03954 {
03955 buf[len++] = 'c';
03956
03957
03958 if (flag & SCFLAG_NORESP)
03959 buf[len++] = 't';
03960 buf[len++] = ' ';
03961 }
03962
03963
03964 if (*pdv_p->dd_p->serial_prefix)
03965 {
03966 strcpy(&(buf[len]), pdv_p->dd_p->serial_prefix);
03967 len += strlen(pdv_p->dd_p->serial_prefix);
03968 }
03969
03970
03971 if (pdv_p->dd_p->serial_format == SERIAL_PULNIX_1010)
03972 {
03973 buf[len++] = 0x02;
03974 for (i = 0; i < bufsize; i++)
03975 if (cmd[i] == '\r' || cmd[i] == '\n' || cmd[i] == 0)
03976 break;
03977 else
03978 buf[len++] = cmd[i];
03979 buf[len++] = 0x03;
03980 }
03981 else
03982 {
03983
03984
03985 for (i = 0; i < bufsize; i++)
03986 {
03987 if (cmd[i] == '\r' || cmd[i] == '\n' || cmd[i] == 0)
03988 break;
03989 else
03990 buf[len++] = cmd[i];
03991 }
03992
03993 sprintf(&(buf[len]), "%s", pdv_serial_term(pdv_p));
03994 len += strlen(pdv_serial_term(pdv_p));
03995 }
03996
03997 if (Pdv_debug)
03998 debug_print_serial_command(buf);
03999 ret = pdv_serial_write(pdv_p, buf, len);
04000
04001 free(buf);
04002 return (ret);
04003 }
04004
04013 char *
04014 pdv_serial_term(PdvDev * pdv_p)
04015 {
04016 return pdv_p->dd_p->serial_term;
04017 }
04018
04027 char *
04028 pdv_serial_prefix(PdvDev * pdv_p)
04029 {
04030 return pdv_p->dd_p->serial_prefix;
04031 }
04032
04047 void
04048 pdv_set_serial_delimiters(PdvDev *pdv_p, char *prefix, char *term)
04049
04050 {
04051 if (prefix)
04052 strncpy(pdv_p->dd_p->serial_prefix,prefix, sizeof(pdv_p->dd_p->serial_prefix)-1);
04053 else
04054 pdv_p->dd_p->serial_prefix[0] = 0;
04055
04056 if (term)
04057 strncpy(pdv_p->dd_p->serial_term,term, sizeof(pdv_p->dd_p->serial_term)-1);
04058 else
04059 pdv_p->dd_p->serial_term[0] = 0;
04060
04061 edt_set_dependent(pdv_p,pdv_p->dd_p);
04062 }
04063
04064
04065
04066 static void
04067 debug_print_serial_command(char *cmd)
04068 {
04069 char tmpbuf[256];
04070 char *p = cmd;
04071 char *pp = tmpbuf;
04072 int len=0;
04073
04074 while (*p != '\0')
04075 {
04076 if (*p == '\r')
04077 {
04078 sprintf(pp, "\\r");
04079 pp += 2;
04080 len += 2;
04081 ++p;
04082 }
04083 else if (*p == '\n')
04084 {
04085 sprintf(pp, "\\n");
04086 pp += 2;
04087 len += 2;
04088 ++p;
04089 }
04090 else if (!isprint(*p))
04091 {
04092 sprintf(pp, "<%02x>", (*p) & 0xff);
04093 pp += 4;
04094 len += 4;
04095 ++p;
04096 }
04097 else
04098 {
04099 *(pp++) = *(p++);
04100 ++len ;
04101 }
04102 if (len > 250)
04103 break;
04104 }
04105 *pp = '\0';
04106 edt_msg(DBG2, "pdv_serial_command(\"%s\")\n", tmpbuf);
04107 }
04108
04139 int
04140 pdv_serial_binary_command(PdvDev * pdv_p, const char *cmd, int len)
04141 {
04142 return pdv_serial_binary_command_flagged(pdv_p, cmd, len, 0);
04143 }
04144
04145
04152 int
04153 pdv_send_basler_frame(PdvDev * pdv_p, u_char *cmd, int len)
04154 {
04155 int i;
04156 u_char frame[128];
04157 u_char *p = frame;
04158 u_char bcc = 0;
04159
04160 *p++ = 0x02;
04161 for (i=0; i<len; i++)
04162 {
04163 bcc ^= cmd[i];
04164 *p++ = cmd[i];
04165 }
04166 *p++ = bcc;
04167 *p++ = 0x03;
04168
04169 return pdv_serial_binary_command_flagged(pdv_p, (char *)frame, len+3, 0);
04170 }
04171
04178 int
04179 pdv_read_basler_frame(PdvDev * pdv_p, u_char *frame, int len)
04180 {
04181 int n, nn;
04182 char tmpbuf[128];
04183 char *p;
04184
04185 n = pdv_serial_wait(pdv_p, 500, len);
04186 if (n < 1)
04187 return 0;
04188
04189 nn = pdv_serial_read(pdv_p, tmpbuf, n);
04190
04191 if (tmpbuf[0] == 0x06)
04192 {
04193 frame[0] = 0x06;
04194 return 1;
04195 }
04196
04197 if (tmpbuf[0] == 0x15)
04198 {
04199 frame[0] = 0x06;
04200 return 1;
04201 }
04202
04203 if (tmpbuf[0] == 0x02)
04204 {
04205 p = &tmpbuf[nn];
04206 n = pdv_serial_wait(pdv_p, 50, len);
04207 pdv_serial_read(pdv_p, p, n);
04208
04209 }
04210 return n;
04211 }
04212
04228 int
04229 pdv_send_duncan_frame(PdvDev * pdv_p, u_char *cmdbuf, int size)
04230 {
04231 int i;
04232 u_char frame[128];
04233 u_char *p = frame;
04234
04235 *p++ = 0x02;
04236 for (i=0; i<size; i++)
04237 *p++ = cmdbuf[i];
04238
04239 CheckSumMessage(frame);
04240
04241 return pdv_serial_binary_command_flagged(pdv_p, (char *)frame, size+2, 0);
04242 }
04243
04244 static void
04245 CheckSumMessage(unsigned char *msg)
04246 {
04247 unsigned short length;
04248 unsigned char csum = 0;
04249
04250 msg++;
04251 length = *msg++;
04252 length += *msg++ << 8;
04253 if (length > 0)
04254 {
04255 for (; length > 0; length--)
04256 csum += *msg++;
04257 *msg = -csum;
04258 }
04259 }
04260
04261
04274 int
04275 pdv_read_duncan_frame(PdvDev * pdv_p, u_char *frame)
04276 {
04277 int n, nn;
04278 u_short length;
04279
04280
04281 n = pdv_serial_wait(pdv_p, 500, 3);
04282 if (n < 3)
04283 return 0;
04284
04285 nn = pdv_serial_read(pdv_p, (char *)frame, 3);
04286
04287 length = (u_short)frame[1] + (u_short)(frame[2] << 8);
04288
04289 if (length)
04290 n = pdv_serial_wait(pdv_p, 1000, length+1);
04291
04292 if (n)
04293 pdv_serial_read(pdv_p, (char *)(&frame[3]), n);
04294
04295 return n+nn;
04296 }
04297
04321 int
04322 pdv_serial_binary_command_flagged(PdvDev * pdv_p, const char *cmd, int len, u_int flag)
04323 {
04324 char *buf;
04325 int ret;
04326 int i;
04327 int tmplen = 0;
04328
04329 edt_msg(DBG2, "pdv_serial_binary_command()\n");
04330
04331 if (pdv_p == NULL || pdv_p->dd_p == NULL)
04332 return -1;
04333
04334 if ((buf = (char *)malloc(len)) == NULL)
04335 return -1;
04336
04337
04338 if (pdv_p->devid == PDVFOI_ID)
04339 {
04340 buf[tmplen++] = 'c';
04341 if (flag & SCFLAG_NORESP)
04342 buf[tmplen++] = 't';
04343 buf[tmplen++] = ' ';
04344 }
04345
04346
04347 for (i = 0; i < len; i++)
04348 {
04349 buf[tmplen++] = cmd[i];
04350 }
04351 ret = pdv_serial_write(pdv_p, buf, tmplen);
04352
04353 free(buf);
04354 return (ret);
04355 }
04356
04358
04387 int
04388 pdv_read(PdvDev * pdv_p, unsigned char *buf, unsigned long size)
04389 {
04390 Dependent *dd_p;
04391 unsigned long newsize;
04392 int readsize;
04393 unsigned char *tbuf;
04394
04395
04396 edt_msg(DBG2, "pdv_read(%d)\n", size);
04397
04398 pdv_setup_dma(pdv_p);
04399
04400 if (pdv_p->dd_p->start_delay)
04401 edt_msleep(pdv_p->dd_p->start_delay);
04402
04403
04404 if (pdv_specinst_serial_triggered(pdv_p))
04405 {
04406 edt_msg(PDVWARN, "libpdv invalid combination: SPECINST_SERIAL/pdv_read/i/f trigger");
04407 edt_msg(PDVWARN, "should use pdv_start_image() or external trigger");
04408 }
04409
04410 if (pdv_p == NULL || pdv_p->dd_p == NULL)
04411 return -1;
04412
04413 dd_p = pdv_p->dd_p;
04414
04415 if (pdv_p->devid == DMY_ID)
04416 {
04417 pdv_dmy_data(buf, dd_p->width, dd_p->height, dd_p->depth);
04418 if (dd_p->markras)
04419 pdv_mark_ras(buf, dd_p->rascnt,
04420 dd_p->width, dd_p->height, dd_p->markrasx, dd_p->markrasy);
04421 if (dd_p->markbin)
04422 pdv_mark_bin(buf, dd_p->rascnt, dd_p->width, dd_p->height, 4, 0);
04423 if (dd_p->markbin || dd_p->markras) dd_p->rascnt++ ;
04424 printf("pdv_read rascnt %d\n",dd_p->rascnt) ;
04425 return (size);
04426 }
04427
04428 readsize = pdv_get_dmasize(pdv_p);
04429
04430 if (dd_p->swinterlace)
04431 pdv_alloc_tmpbuf(pdv_p);
04432
04433
04434
04435
04436 edt_startdma_reg(pdv_p, PDV_CMD, PDV_ENABLE_GRAB);
04437 if (edt_get_firstflush(pdv_p) != EDT_ACT_KBS)
04438 edt_set_firstflush(pdv_p, EDT_ACT_ONCE);
04439
04440
04441 if (dd_p->slop)
04442 {
04443 edt_msg(DBG2, "adjusting readsize %x by slop %x to %x\n",
04444 readsize, dd_p->slop, readsize - dd_p->slop);
04445 readsize -= dd_p->slop;
04446 }
04447
04448 if (dd_p->swinterlace)
04449 {
04450 if (pdv_process_inplace(pdv_p))
04451 tbuf = buf;
04452 else
04453 tbuf = pdv_p->tmpbuf;
04454
04455 newsize = edt_read(pdv_p, tbuf, readsize);
04456 dd_p->last_raw = tbuf;
04457 dd_p->last_image = buf;
04458 }
04459 else
04460 {
04461 tbuf = buf;
04462 newsize = edt_read(pdv_p, buf, readsize);
04463 dd_p->last_raw = buf;
04464 dd_p->last_image = buf;
04465 }
04466
04467 dd_p->rascnt = 1;
04468 if (dd_p->markras)
04469 pdv_mark_ras(buf, dd_p->rascnt++, dd_p->width, dd_p->height,
04470 dd_p->markrasx, dd_p->markrasy);
04471
04472 size = newsize;
04473
04474
04475
04476 edt_msg(DBG2, "swinterlace %d\n", dd_p->swinterlace);
04477
04478 pdv_deinterlace(pdv_p, dd_p, tbuf, buf);
04479
04480 return (size);
04481 }
04482
04483
04502 unsigned char *
04503 pdv_image(PdvDev * pdv_p)
04504 {
04505 edt_msg(DBG2, "pdv_image()\n");
04506
04507 pdv_start_images(pdv_p, 1);
04508 return pdv_wait_images(pdv_p, 1);
04509 }
04510
04511
04522 unsigned char *
04523 pdv_image_raw(PdvDev * pdv_p)
04524 {
04525 edt_msg(DBG2, "pdv_image()\n");
04526
04527 pdv_start_images(pdv_p, 1);
04528 return pdv_wait_images_raw(pdv_p, 1);
04529 }
04530
04539 void
04540 pdv_start_image(PdvDev * pdv_p)
04541 {
04542 edt_msg(DBG2, "pdv_start_image()\n");
04543
04544 pdv_start_images(pdv_p, 1);
04545 }
04546
04547
04560 void
04561 pdv_start_images(PdvDev * pdv_p, int count)
04562 {
04563
04564 edt_msg(DBG2, "pdv_start_images(%d) %d\n", count, pdv_p->dd_p->started_continuous);
04565
04566 if (pdv_p->dd_p->start_delay)
04567 edt_msleep(pdv_p->dd_p->start_delay);
04568
04569
04570 if (pdv_p->ring_buffer_numbufs < 1)
04571 pdv_multibuf(pdv_p, 1);
04572
04573
04574
04575
04576
04577
04578
04579
04580 if (!pdv_p->dd_p->started_continuous)
04581 {
04582 pdv_setup_continuous(pdv_p);
04583 }
04584 if (pdv_force_single(pdv_p) && (count > 1))
04585 {
04586 edt_msg(PDVWARN,
04587 "pdv_start_images(): %d buffers requested; should only\n", count);
04588 edt_msg(PDVWARN,
04589 "start one at a time when 'force_single' is set in config file\n");
04590 count = 1;
04591 }
04592
04593
04594 edt_start_buffers(pdv_p, count);
04595
04596 if (pdv_specinst_serial_triggered(pdv_p))
04597 pdv_trigger_specinst(pdv_p);
04598 }
04599
04600
04642 unsigned char *
04643 pdv_wait_image(PdvDev * pdv_p)
04644 {
04645 edt_msg(DBG2, "pdv_wait_image()\n");
04646
04647 return pdv_wait_images(pdv_p, 1);
04648 }
04649
04681 unsigned char *
04682 pdv_wait_image_raw(PdvDev * pdv_p)
04683 {
04684 edt_msg(DBG2, "pdv_wait_image()\n");
04685
04686 return pdv_wait_images_raw(pdv_p, 1);
04687 }
04688
04689
04729 unsigned char *
04730 pdv_wait_image_timed(PdvDev * pdv_p, u_int * timep)
04731 {
04732 return pdv_wait_image_timed_raw(pdv_p, timep, FALSE);
04733 }
04734
04775 unsigned char *
04776 pdv_wait_image_timed_raw(PdvDev * pdv_p, u_int * timep, int doRaw)
04777 {
04778 u_char *ret;
04779
04780 edt_msg(DBG2, "pdv_wait_image()\n");
04781
04782 if (doRaw)
04783 ret = pdv_wait_images_raw(pdv_p, 1);
04784 else
04785 ret = pdv_wait_images(pdv_p, 1);
04786
04787 edt_get_timestamp(pdv_p, timep, pdv_p->donecount - 1);
04788 return (ret);
04789 }
04790
04837 unsigned char *
04838 pdv_wait_images_timed_raw(PdvDev * pdv_p, int count, u_int * timep, int doRaw)
04839 {
04840 u_char *ret;
04841
04842 edt_msg(DBG2, "pdv_wait_images_timed_raw(count=%d, doRaw=%d)\n", count, doRaw);
04843 if (doRaw)
04844 ret = pdv_wait_images_raw(pdv_p, count);
04845 else
04846 ret = pdv_wait_images(pdv_p, count);
04847
04848 edt_get_timestamp(pdv_p, timep, pdv_p->donecount - 1);
04849 return (ret);
04850 }
04851
04880 unsigned char *
04881 pdv_wait_images_timed(PdvDev * pdv_p, int count, u_int * timep)
04882 {
04883 return pdv_wait_images_timed_raw(pdv_p, count, timep, FALSE);
04884 }
04885
04890 unsigned char *
04891 pdv_last_image_timed_raw(PdvDev * pdv_p, u_int * timep, int doRaw)
04892 {
04893 return pdv_wait_last_image_timed_raw(pdv_p, timep, doRaw);
04894
04895 }
04896
04927 unsigned char *
04928 pdv_wait_last_image_timed_raw(PdvDev * pdv_p, u_int * timep, int doRaw)
04929 {
04930 u_char *ret;
04931 int donecount;
04932 int last_wait;
04933 int delta;
04934
04935 donecount = edt_done_count(pdv_p);
04936 last_wait = pdv_p->donecount;
04937
04938 edt_msg(DBG2, "pdv_wait_last_image_timed() last %d cur %d\n",
04939 last_wait, donecount);
04940
04941 delta = donecount - last_wait;
04942
04943 if (delta == 0)
04944 delta = 1;
04945
04946 if (doRaw)
04947 ret = pdv_wait_images_raw(pdv_p, delta);
04948 else
04949 ret = pdv_wait_images(pdv_p, delta);
04950
04951 edt_get_timestamp(pdv_p, timep, pdv_p->donecount - 1);
04952 return (ret);
04953 }
04954
04978 unsigned char *
04979 pdv_wait_last_image_timed(PdvDev * pdv_p, u_int * timep)
04980 {
04981 return pdv_wait_last_image_timed_raw(pdv_p, timep, FALSE);
04982 }
04983
04988 unsigned char *
04989 pdv_last_image_timed(PdvDev * pdv_p, u_int * timep)
04990 {
04991
04992 return pdv_last_image_timed_raw(pdv_p, timep, FALSE);
04993 }
04994
05015 unsigned char *
05016 pdv_wait_last_image_raw(PdvDev * pdv_p, int *nSkipped, int doRaw)
05017 {
05018 u_char *ret;
05019 int donecount;
05020 int last_wait;
05021 int delta;
05022
05023 donecount = edt_done_count(pdv_p);
05024 last_wait = pdv_p->donecount;
05025
05026 edt_msg(DBG2, "pdv_wait_last_image() last %d cur %d\n",
05027 last_wait, donecount);
05028
05029 delta = donecount - last_wait;
05030
05031 if (nSkipped)
05032 *nSkipped = (delta) ? delta - 1 : 0;
05033
05034 if (delta == 0)
05035 delta = 1;
05036
05037 if (doRaw)
05038 ret = pdv_wait_images_raw(pdv_p, delta);
05039 else
05040 ret = pdv_wait_images(pdv_p, delta);
05041
05042 return (ret);
05043 }
05044
05073 unsigned char *
05074 pdv_wait_last_image(PdvDev * pdv_p, int *nSkipped)
05075 {
05076 return pdv_wait_last_image_raw(pdv_p, nSkipped, FALSE);
05077 }
05078
05099 unsigned char *
05100 pdv_wait_next_image_raw(PdvDev * pdv_p, int *nSkipped, int doRaw)
05101 {
05102 u_char *ret;
05103 int donecount;
05104 int last_wait;
05105 int delta;
05106
05107 donecount = edt_done_count(pdv_p);
05108 last_wait = pdv_p->donecount;
05109
05110 edt_msg(DBG2, "pdv_wait_last_image() last %d cur %d\n",
05111 last_wait, donecount);
05112
05113 delta = donecount - last_wait;
05114
05115 if (*nSkipped)
05116 *nSkipped = (delta) ? delta - 1 : 0;
05117
05118
05119 if (delta == 0)
05120 delta = 1;
05121
05122 delta++;
05123
05124 if (doRaw)
05125 ret = pdv_wait_images_raw(pdv_p, delta);
05126 else
05127 ret = pdv_wait_images(pdv_p, delta);
05128
05129 return (ret);
05130 }
05131
05147 unsigned char *
05148 pdv_wait_next_image(PdvDev * pdv_p, int *nSkipped)
05149 {
05150
05151 return pdv_wait_next_image_raw(pdv_p, nSkipped, FALSE);
05152 }
05153
05154
05164 int
05165 pdv_in_continuous(PdvDev * pdv_p)
05166 {
05167 edt_msg(DBG2, "pdv_in_continuous() %x\n",
05168 pdv_p->dd_p->continuous);
05169 return pdv_p->dd_p->continuous;
05170 }
05171
05173
05174 void
05175 pdv_check(PdvDev * pdv_p)
05176 {
05177 int stat;
05178 int overrun;
05179
05180 stat = edt_reg_read(pdv_p, PDV_STAT);
05181 overrun = edt_ring_buffer_overrun(pdv_p);
05182 edt_msg(DBG2, "pdv_check() stat %x overrun %x\n",
05183 stat, overrun);
05184 if ((stat & PDV_OVERRUN) || overrun)
05185 {
05186 if (pdv_p->dd_p->continuous)
05187 pdv_stop_hardware_continuous(pdv_p);
05188
05189 pdv_flush_fifo(pdv_p);
05190
05191 pdv_multibuf(pdv_p, pdv_p->ring_buffer_numbufs);
05192
05193 if (pdv_p->dd_p->continuous)
05194 pdv_start_hardware_continuous(pdv_p);
05195 }
05196 }
05197
05198 void
05199 pdv_checkfrm(PdvDev * pdv_p, u_short * imagebuf, u_int imagesize, int verbose)
05200 {
05201 u_short *tmpp;
05202
05203 for (tmpp = (u_short *) imagebuf;
05204 tmpp < (u_short *) (&imagebuf[imagesize]); tmpp++)
05205 {
05206 if (*tmpp & 0xf000)
05207 {
05208 edt_msg(DBG2, "found start of image %x at %x %d\n",
05209 *tmpp >> 12,
05210 tmpp - (u_short *) imagebuf,
05211 tmpp - (u_short *) imagebuf);
05212 if (tmpp != imagebuf)
05213 {
05214 int curdone;
05215 int curtodo;
05216
05217 edt_reg_write(pdv_p, PDV_CMD, PDV_RESET_INTFC);
05218 pdv_flush_fifo(pdv_p);
05219 curdone = edt_done_count(pdv_p);
05220 curtodo = edt_get_todo(pdv_p);
05221 edt_msg(DBG2, "done %d todo %d\n", curdone, curtodo);
05222 {
05223 pdv_stop_continuous(pdv_p);
05224 edt_set_buffer(pdv_p, curdone);
05225 pdv_setup_continuous(pdv_p);
05226 pdv_start_images(pdv_p, pdv_p->ring_buffer_numbufs -
05227 (curtodo - curdone));
05228 }
05229 }
05230 break;
05231 }
05232 }
05233 }
05234
05235 u_char *
05236 pdv_get_interleave_data(PdvDev *pdv_p, u_char *buf)
05237
05238 {
05239 if (!pdv_process_inplace(pdv_p))
05240 {
05241 return buf + pdv_get_dmasize(pdv_p);
05242 }
05243 else
05244 return buf;
05245 }
05246
05247
05274 unsigned char *
05275 pdv_wait_images_raw(PdvDev * pdv_p, int count)
05276 {
05277 u_char *buf;
05278 Dependent *dd_p;
05279 static int last_timeout = 0;
05280
05281 edt_msg(DBG2, "pdv_wait_images_raw(%d)\n", count);
05282
05283 if (pdv_p == NULL || pdv_p->dd_p == NULL)
05284 return NULL;
05285
05286 dd_p = pdv_p->dd_p;
05287
05288 if (pdv_specinst_serial_triggered(pdv_p))
05289 pdv_posttrigger_specinst(pdv_p);
05290
05291 if (pdv_p->devid == DMY_ID)
05292 {
05293 u_char *buf;
05294 u_int *tmpp;
05295
05296 buf = edt_next_writebuf(pdv_p);
05297 tmpp = (u_int *) buf;
05298 if (*tmpp != 0xaabbccdd)
05299 {
05300 pdv_dmy_data(buf, dd_p->width, dd_p->height, dd_p->depth);
05301 }
05302 *tmpp = 0xaabbccdd;
05303 dd_p->last_image = buf;
05304 dd_p->last_raw = buf;
05305 if (dd_p->markras)
05306 pdv_mark_ras(buf, dd_p->rascnt, dd_p->width, dd_p->height,
05307 dd_p->markrasx, dd_p->markrasy);
05308 if (dd_p->markbin)
05309 pdv_mark_bin(buf, dd_p->rascnt, dd_p->width, dd_p->height, 4, 0);
05310
05311 if (dd_p->markbin || dd_p->markras) dd_p->rascnt++ ;
05312 return (buf);
05313 }
05314
05315
05316 last_timeout = edt_timeouts(pdv_p);
05317 buf = edt_wait_for_buffers(pdv_p, count);
05318
05319 return buf;
05320
05321
05322 }
05323
05324
05370 u_char *
05371 pdv_wait_images(PdvDev *pdv_p, int count)
05372
05373 {
05374 u_char *buf;
05375 u_char *retval;
05376 Dependent *dd_p;
05377
05378 edt_msg(DBG2, "pdv_wait_images(%d)\n", count);
05379
05380 if (pdv_p == NULL || pdv_p->dd_p == NULL)
05381 return NULL;
05382
05383 dd_p = pdv_p->dd_p;
05384
05385 if (dd_p->swinterlace)
05386 {
05387 pdv_alloc_tmpbuf(pdv_p);
05388 }
05389
05390 buf = pdv_wait_images_raw(pdv_p, count);
05391
05392 if (dd_p->swinterlace)
05393 {
05394
05395 if (!pdv_process_inplace(pdv_p))
05396 {
05397 retval = buf + pdv_get_dmasize(pdv_p);
05398 }
05399 else
05400 retval = buf;
05401
05402 pdv_deinterlace(pdv_p, dd_p, buf, retval);
05403
05404 dd_p->last_raw = buf;
05405 dd_p->last_image = retval;
05406 }
05407 else
05408 {
05409 retval = buf;
05410 dd_p->last_raw = buf;
05411 dd_p->last_image = buf;
05412 }
05413
05414
05415 if (pdv_p->devid != DMY_ID)
05416 {
05417 if (dd_p->markras)
05418 pdv_mark_ras(buf, dd_p->rascnt, dd_p->width, dd_p->height,
05419 dd_p->markrasx, dd_p->markrasy);
05420 if (dd_p->markbin)
05421 pdv_mark_bin(buf, dd_p->rascnt, dd_p->width, dd_p->height, 4, 0);
05422
05423 if (dd_p->markbin || dd_p->markras) dd_p->rascnt++ ;
05424 }
05425
05426
05427 return (retval);
05428 }
05429
05430 int
05431 pdv_slop(PdvDev * pdv_p)
05432 {
05433 return (pdv_p->dd_p->slop);
05434 }
05435
05436
05437 int
05438 pdv_set_slop(PdvDev * pdv_p, int slop)
05439 {
05440 edt_msg(DBG2, "pdv_set_slop()\n");
05441
05442 pdv_p->dd_p->slop = slop;
05443 return (0);
05444 }
05445
05446
05486 pdv_set_header_type(PdvDev *pdv_p, int header_type, int irig_slave, int irig_offset, int irig_raw)
05487 {
05488 if (!((pdv_p->devid == PE8DVCL_ID)
05489 || (pdv_p->devid == PE8DVFOX_ID)))
05490 return -1;
05491
05492 edt_reg_and(pdv_p, PDV_UTILITY, ~(PDV_ENFRMCNT|PDVCL_IRIG2));
05493
05494 switch(header_type)
05495 {
05496 case HDR_TYPE_IRIG2:
05497 pdv_p->dd_p->header_position = HeaderEnd;
05498 pdv_p->dd_p->header_size = 32;
05499 pdv_p->dd_p->header_dma = 1;
05500 edt_reg_or(pdv_p, PDV_UTILITY, PDVCL_IRIG2);
05501 pdv_p->spi_reg_base = PDV_IRIG_SPI_BASE;
05502
05503 pdv_irig_set_slave(pdv_p, irig_slave);
05504 if (!irig_slave)
05505 {
05506 pdv_irig_set_offset(pdv_p, irig_offset);
05507 pdv_irig_set_bcd(pdv_p, irig_raw);
05508 }
05509 pdv_p->dd_p->header_type = header_type;
05510
05511 break;
05512 default:
05513 return -1;
05514 }
05515
05516 edt_set_dependent(pdv_p, pdv_p->dd_p);
05517
05518 return 0;
05519 }
05520
05533 int
05534 pdv_get_header_size(PdvDev * pdv_p)
05535 {
05536 return (pdv_p->dd_p->header_size);
05537 }
05538
05564 HdrPosition
05565 pdv_get_header_position(PdvDev * pdv_p)
05566 {
05567 return (HdrPosition) (pdv_p->dd_p->header_position);
05568 }
05569
05586 int
05587 pdv_get_header_offset(PdvDev * pdv_p)
05588 {
05589 switch (pdv_p->dd_p->header_position)
05590 {
05591 case HeaderBefore:
05592 pdv_p->dd_p->header_offset = - (int) pdv_p->dd_p->header_size;
05593 break;
05594 case HeaderBegin:
05595 pdv_p->dd_p->header_offset = 0;
05596 break;
05597 case HeaderEnd:
05598 pdv_p->dd_p->header_offset = pdv_get_dmasize(pdv_p) - pdv_p->dd_p->header_size ;
05599 break;
05600 case HeaderAfter:
05601 pdv_p->dd_p->header_offset = pdv_p->dd_p->imagesize;
05602 break;
05603
05604 }
05605
05606 return (pdv_p->dd_p->header_offset);
05607 }
05608
05617 int
05618 pdv_get_header_dma(PdvDev * pdv_p)
05619 {
05620 return (pdv_p->dd_p->header_dma);
05621 }
05622
05623 int
05624 pdv_get_header_within(PdvDev *pdv_p)
05625
05626 {
05627 return (pdv_p->dd_p->header_position == HeaderBegin ||
05628 pdv_p->dd_p->header_position == HeaderMiddle ||
05629 pdv_p->dd_p->header_position == HeaderEnd);
05630 }
05631
05641 int
05642 pdv_extra_headersize(PdvDev * pdv_p)
05643
05644 {
05645 if (pdv_p->dd_p->header_size && (!pdv_p->dd_p->header_dma) &&
05646 (pdv_p->dd_p->header_position == HeaderBefore ||
05647 pdv_p->dd_p->header_position == HeaderAfter))
05648 return pdv_p->dd_p->header_size;
05649
05650 return 0;
05651 }
05652
05662 void
05663 pdv_set_header_size(PdvDev * pdv_p, int header_size)
05664 {
05665 edt_msg(DBG2, "pdv_set_header_size()\n");
05666
05667 pdv_p->dd_p->header_size = header_size;
05668
05669 }
05670
05690 void
05691 pdv_set_header_position(PdvDev * pdv_p, HdrPosition header_position)
05692
05693 {
05694 edt_msg(DBG2, "pdv_set_header_position(%d)\n", header_position);
05695
05696 pdv_p->dd_p->header_position = header_position;
05697 }
05698
05708 void
05709 pdv_set_header_dma(PdvDev * pdv_p, int header_dma)
05710 {
05711 edt_msg(DBG2, "pdv_set_header_dma(%d,%d)\n", header_dma);
05712
05713 pdv_p->dd_p->header_dma = header_dma;
05714 }
05715
05716
05723 void
05724 pdv_set_header_offset(PdvDev * pdv_p, int header_offset)
05725
05726 {
05727 edt_msg(DBG2, "pdv_set_header_offset(%d,%d)\n", header_offset);
05728
05729 pdv_p->dd_p->header_offset = header_offset;
05730 }
05731
05733
05758 int
05759 pdv_shutter_method(PdvDev * pdv_p)
05760 {
05761 edt_msg(DBG2, "pdv_shutter_method()\n");
05762
05763 return pdv_p->dd_p->camera_shutter_timing;
05764 }
05765
05773 void
05774 pdv_set_interlace(PdvDev * pdv_p, int interlace)
05775 {
05776 edt_msg(DBG2, "pdv_set_interlace()\n");
05777
05778 pdv_p->dd_p->swinterlace = interlace;
05779
05780 pdv_setup_postproc(pdv_p, pdv_p->dd_p, NULL);
05781
05782 }
05783
05841 int
05842 pdv_interlace_method(PdvDev * pdv_p)
05843 {
05844 edt_msg(DBG2, "pdv_interlace_method()\n");
05845
05846 return pdv_p->dd_p->swinterlace;
05847 }
05848
05849
05866 int
05867 pdv_debug(int flag)
05868 {
05869 int oldval = Pdv_debug;
05870
05871 edt_msg(DBG2, "pdv_debug()\n");
05872
05873 Pdv_debug = flag;
05874 return (oldval);
05875 }
05876
05885 int
05886 pdv_debug_level()
05887 {
05888 return Pdv_debug;
05889 }
05890
05891
05903 int
05904 pdv_overrun(PdvDev * pdv_p)
05905 {
05906 int overrun;
05907
05908 edt_msg(DBG2, "pdv_overrun()\n");
05909
05910 if (pdv_p->devid == DMY_ID)
05911 return (0);
05912 edt_ioctl(pdv_p, EDTG_OVERFLOW, &overrun);
05913 return (overrun);
05914 }
05915
05934 int
05935 pdv_serial_wait(PdvDev * pdv_p, int msecs, int count)
05936 {
05937 edt_buf tmp;
05938 int ret;
05939
05940 if (msecs == 0)
05941 msecs = pdv_p->dd_p->serial_timeout;
05942
05943 tmp.desc = msecs;
05944 tmp.value = count;
05945 edt_ioctl(pdv_p, EDTS_SERIALWAIT, &tmp);
05946 ret = (int) tmp.value;
05947 edt_msg(DBG2, "pdv_serial_wait(%d, %d) %d\n", msecs, count, ret);
05948 return (ret);
05949 }
05950
05963 int
05964 pdv_serial_get_numbytes(PdvDev * pdv_p)
05965 {
05966 edt_buf tmp;
05967 int ret;
05968
05969 tmp.desc = 0;
05970 tmp.value = 0;
05971 edt_ioctl(pdv_p, EDTS_SERIALWAIT, &tmp);
05972 ret = (int) tmp.value;
05973 edt_msg(DBG2, "pdv_serial_get_numbytes %d\n", ret);
05974 return (ret);
05975 }
05976
05990 int
05991 pdv_serial_wait_next(EdtDev * pdv_p, int msecs, int count)
05992 {
05993 int ret;
05994 int newcount = count;
05995
05996 if (pdv_p->devid == PDVFOI_ID)
05997 {
05998 if (newcount)
05999 newcount += 2;
06000 ret = pdv_serial_wait(pdv_p, msecs, newcount);
06001 if (ret >= 2)
06002 ret -= 2;
06003 }
06004 else
06005 ret = pdv_serial_wait(pdv_p, msecs, count);
06006 return (ret);
06007 }
06008
06026 int
06027 pdv_set_waitchar(PdvDev * pdv_p, int enable, u_char wchar)
06028 {
06029 edt_buf tmp;
06030 int ret;
06031
06032
06033 tmp.desc = enable;
06034 tmp.value = wchar;
06035 ret = edt_ioctl(pdv_p, EDTS_WAITCHAR, &tmp);
06036 pdv_p->dd_p->serial_waitc = wchar;
06037 if (!enable)
06038 pdv_p->dd_p->serial_waitc |= 0x100;
06039 edt_msg(DBG2, "pdv_set_waitchar(%d, %02x) returns %d\n", enable, wchar, ret);
06040 return (ret);
06041 }
06042
06055 int
06056 pdv_get_waitchar(PdvDev * pdv_p, u_char *waitc)
06057 {
06058 int ret;
06059
06060 if (pdv_p->dd_p->serial_waitc & 0x100)
06061 {
06062 *waitc = pdv_p->dd_p->serial_waitc & 0xff;
06063 ret = 0;
06064 }
06065 else
06066 {
06067 *waitc = pdv_p->dd_p->serial_waitc;
06068 ret = 1;
06069 }
06070 return ret;
06071 }
06072
06073
06074 int
06075 pdv_get_fulldma_size(PdvDev *pdv_p, int *extrasizep)
06076
06077 {
06078 int size = pdv_get_imagesize(pdv_p);
06079
06080 int slop = pdv_slop(pdv_p);
06081 int extrasize;
06082 Dependent *dd_p = pdv_p->dd_p;
06083
06084 extrasize = slop + pdv_extra_headersize(pdv_p);
06085
06086 if (pdv_get_header_dma(pdv_p) && (pdv_get_header_within(pdv_p)))
06087
06088 size += pdv_get_header_size(pdv_p);
06089
06090 if (dd_p->swinterlace || size != pdv_get_dmasize(pdv_p))
06091 {
06092
06093
06094 if (!pdv_process_inplace(pdv_p) || size != pdv_get_dmasize(pdv_p))
06095 {
06096 int newsize = pdv_get_dmasize(pdv_p);
06097
06098 extrasize += size;
06099 size = newsize;
06100 }
06101 }
06102
06103 if (extrasizep)
06104 *extrasizep = extrasize;
06105
06106 return size;
06107 }
06108
06109 int
06110 pdv_total_block_size(PdvDev *pdv_p, int numbufs)
06111
06112 {
06113 int extrasize = 0;
06114 int size;
06115
06116 size = pdv_get_fulldma_size(pdv_p, &extrasize);
06117
06118
06119 size = edt_get_total_bufsize(pdv_p, size,extrasize) * numbufs;
06120
06121 return size;
06122
06123 }
06124
06125 int
06126 pdv_multibuf_block(PdvDev *pdv_p, int numbufs, u_char *block, int blocksize)
06127
06128 {
06129 int size, extrasize;
06130 int ret;
06131 int header_before = (pdv_p->dd_p->header_position == HeaderBefore);
06132
06133 size = pdv_get_fulldma_size(pdv_p, &extrasize);
06134
06135 pdv_setup_dma(pdv_p);
06136
06137 ret = edt_configure_block_buffers_mem(pdv_p,
06138 size,
06139 numbufs,
06140 EDT_READ,
06141 extrasize,
06142 header_before,
06143 block) ;
06144
06145
06146 return ret;
06147
06148 }
06149
06150 int
06151 pdv_multibuf_separate(PdvDev *pdv_p, int numbufs, u_char **buffers)
06152
06153 {
06154 int size = pdv_get_imagesize(pdv_p);
06155 int ret;
06156
06157 Dependent *dd_p = pdv_p->dd_p;
06158
06159 if (dd_p->swinterlace || size != pdv_get_dmasize(pdv_p))
06160 {
06161
06162
06163 if (!pdv_process_inplace(pdv_p) || size != pdv_get_dmasize(pdv_p))
06164 {
06165 edt_msg_perror(PDVFATAL,"Interlace not inplace fails for multibuf_separate\n");
06166 return -1;
06167 }
06168 }
06169
06170 size = pdv_get_fulldma_size(pdv_p, NULL);
06171
06172 pdv_setup_dma(pdv_p);
06173
06174 ret = edt_configure_ring_buffers(pdv_p, size, numbufs, EDT_READ, buffers) ;
06175
06176 return ret;
06177
06178 }
06179
06204 int
06205 pdv_multibuf(PdvDev * pdv_p, int numbufs)
06206 {
06207
06208
06209
06210
06211
06212 #if defined(XCALIBURCOMMON) || defined(VMIC)
06213 return pdv_multibuf_separate(pdv_p, numbufs,NULL);
06214 #else
06215 return pdv_multibuf_block(pdv_p, numbufs, NULL, 0);
06216 #endif
06217
06218 }
06219
06260 int
06261 pdv_set_buffers(PdvDev * pdv_p, int numbufs, unsigned char **bufarray)
06262 {
06263
06264 int size = pdv_get_dmasize(pdv_p);
06265
06266 edt_msg(DBG2, "pdv_set_buffers(%d %x) (size %d)\n", numbufs, bufarray, size);
06267
06268 pdv_setup_dma(pdv_p);
06269
06270 return (edt_configure_ring_buffers(pdv_p, size, numbufs, EDT_READ, bufarray));
06271 }
06272
06273
06274 int
06275 pdv_set_buffers_x(PdvDev * pdv_p, int numbufs, int size, unsigned char **bufs)
06276 {
06277
06278 edt_msg(DBG2, "pdv_set_buffers(%d %x) (size %d)\n", numbufs, bufs, size);
06279
06280 pdv_setup_dma(pdv_p);
06281
06282 return (edt_configure_ring_buffers(pdv_p, size, numbufs, EDT_READ, bufs));
06283 }
06284
06285
06300 int
06301 pdv_image_size(PdvDev * pdv_p)
06302 {
06303 int size;
06304
06305 size = pdv_p->dd_p->imagesize;
06306
06307 if (pdv_p->dd_p->slop)
06308 {
06309
06310 edt_msg(DBG2, "pdv_image_size: adjusting size %x by slop %x to %x\n",
06311 size, pdv_p->dd_p->slop, size - pdv_p->dd_p->slop);
06312
06313 size -= pdv_p->dd_p->slop;
06314
06315 }
06316
06317 if (pdv_p->dd_p->header_dma)
06318 size += pdv_p->dd_p->header_size;
06319
06320 edt_msg(DBG2, "pdv_image_size() %d\n", size);
06321
06322 return size;
06323
06324 }
06325
06326
06340 u_char *
06341 pdv_get_last_image(PdvDev * pdv_p)
06342 {
06343 edt_msg(DBG2, "pdv_get_last_image()\n");
06344
06345 return (pdv_p->dd_p->last_image);
06346 }
06347
06362 u_char *
06363 pdv_get_last_raw(PdvDev * pdv_p)
06364 {
06365 edt_msg(DBG2, "pdv_get_last_raw()\n");
06366
06367 return (pdv_p->dd_p->last_raw);
06368 }
06369
06384 u_char **
06385 pdv_buffer_addresses(PdvDev * pdv_p)
06386 {
06387
06388 return (pdv_p->ring_buffers);
06389 }
06390
06416 void
06417 pdv_start_hardware_continuous(PdvDev * pdv_p )
06418 {
06419 int data_path;
06420
06421
06422 data_path = pdv_p->dd_p->datapath_reg & ~PDV_CONTINUOUS;
06423
06424 edt_msg(DBG2, "pdv_start_hardware_continuous()\n");
06425
06426 if (pdv_p->devid == PDVFOI_ID)
06427 {
06428 char tmpbuf[10];
06429 int ret;
06430
06431 ret = pdv_serial_wait(pdv_p, 100, 0);
06432 if (ret > 10)
06433 pdv_reset_serial(pdv_p);
06434 else
06435 pdv_serial_read(pdv_p, tmpbuf, ret);
06436
06437 }
06438
06439 if (pdv_p->devid == PDVFOI_ID)
06440 {
06441 char tmpbuf[10];
06442 int ret;
06443
06444 ret = pdv_serial_wait(pdv_p, 100, 0);
06445 if (ret > 10)
06446 pdv_reset_serial(pdv_p);
06447 else
06448 pdv_serial_read(pdv_p, tmpbuf, ret);
06449
06450 }
06451 edt_reg_write(pdv_p, PDV_DATA_PATH, data_path | PDV_CONTINUOUS);
06452 pdv_p->dd_p->datapath_reg = data_path;
06453 }
06454
06455
06465 void
06466 pdv_stop_hardware_continuous(PdvDev * pdv_p)
06467 {
06468 int data_path;
06469
06470
06471 data_path = pdv_p->dd_p->datapath_reg;
06472 edt_msg(DBG2, "pdv_stop_hardware_continuous()\n");
06473 data_path &= ~PDV_CONTINUOUS;
06474 edt_reg_write(pdv_p, PDV_DATA_PATH, data_path);
06475 pdv_p->dd_p->datapath_reg = data_path;
06476
06477 if (pdv_p->devid == PDVFOI_ID)
06478 {
06479 edt_reg_write(pdv_p,FOI_WR_MSG_STAT, FOI_FIFO_FLUSH);
06480 }
06481
06482 }
06483
06494 int
06495 pdv_set_serial_parity(PdvDev * pdv_p, char parity)
06496 {
06497 if (pdv_p->devid == PDVAERO_ID)
06498 {
06499 int val = 0;
06500 switch(parity)
06501 {
06502
06503 case 'e':
06504 val = 1;
06505 break;
06506 case 'o':
06507 val = 3;
06508 break;
06509 case 'n':
06510 val = 0;
06511 break;
06512 default:
06513 edt_msg(DBG1, "parity must be e, o, or n");
06514 return -1;
06515 }
06516
06517 edt_reg_write(pdv_p,PDV_SERIAL_PARITY,val);
06518 return 0;
06519 }
06520 else
06521 {
06522 edt_msg(DBG1,"parity not an option for this board");
06523 }
06524 return -1;
06525 }
06526
06542 int
06543 pdv_set_baud(PdvDev * pdv_p, int baud)
06544 {
06545 Dependent *dd_p = pdv_p->dd_p;
06546 u_int baudbits = 0;
06547 int id=pdv_p->devid;
06548 u_int new, baudreg;
06549 u_int cntl;
06550 int donew = 0;
06551 int ret = 0;
06552
06553 if (dd_p->xilinx_rev < 2 || dd_p->xilinx_rev > 32)
06554 {
06555 edt_msg(DBG2, "pdv_set_baud() warning: can't enable, N/A this xilinx (%x)\n",
06556 pdv_p->dd_p->xilinx_rev);
06557 return -1;
06558 }
06559
06560 if (edt_is_dvcl(pdv_p) || edt_is_dvfox(pdv_p) || (id == PDVA_ID))
06561 donew = 1;
06562
06563 switch (baud)
06564 {
06565 case 9600:
06566 baudbits = 0;
06567 baudreg = 0x80;
06568 break;
06569
06570 case 19200:
06571 baudbits = PDV_BAUD0;
06572 baudreg = 0x3f;
06573 break;
06574
06575 case 38400:
06576 baudbits = PDV_BAUD1;
06577 baudreg = 0x1f;
06578 break;
06579
06580 case 115200:
06581 baudbits = PDV_BAUD0 | PDV_BAUD1;
06582 baudreg = 0x09;
06583 break;
06584
06585 case 57600:
06586 baudbits = PDV_BAUD0 | PDV_BAUD1;
06587 donew = 1;
06588 baudreg = 0x014;
06589 break;
06590
06591 default:
06592 donew = 1;
06593 baudreg = (unsigned int)(((20000000.0 / (16.0 * (double)baud)) - 2.0) + 0.5) ;
06594 edt_msg(DBG2, "pdv_set_baud(%d) using new method, reg %02x\n", baud, baudreg);
06595 break;
06596 }
06597
06598 if (donew && (!dd_p->register_wrap))
06599 {
06600 if (baudreg > 0xff)
06601 {
06602 edt_msg(DBG2, "pdv_set_baud(%d) (baudreg %x) BAD VALUE not set\n", baud, baudreg);
06603 ret = -1;
06604 }
06605 else
06606 {
06607 edt_msg(DBG2, "pdv_set_baud(%d) (baudreg %x) using NEW baud reg\n", baud, baudreg);
06608 edt_reg_write(pdv_p, PDV_BRATE, baudreg);
06609 new = edt_reg_read(pdv_p, PDV_BRATE);
06610 if (new != baudreg)
06611 {
06612 edt_msg(DBG2, "pdv_set_baud(%d) wrote %x read %x) readback ERROR\n", baud, baudreg, new);
06613 ret = -1;
06614 }
06615 }
06616 }
06617
06618 else
06619 {
06620 edt_msg(DBG2, "pdv_set_baud(%d) (baudbits %x) using OLD baud bits\n", baud, baudbits);
06621 cntl = edt_reg_read(pdv_p, PDV_SERIAL_DATA_CNTL);
06622 cntl &= ~PDV_BAUD_MASK;
06623 cntl |= baudbits;
06624 edt_reg_write(pdv_p, PDV_SERIAL_DATA_CNTL, cntl);
06625 }
06626
06627 return ret;
06628 }
06629
06638 int
06639 pdv_get_baud(PdvDev * pdv_p)
06640 {
06641 if (pdv_p->dd_p->serial_baud == NOT_SET)
06642 return 9600;
06643 return pdv_p->dd_p->serial_baud;
06644 }
06645
06661 void
06662 pdv_perror(char *err)
06663 {
06664 edt_perror(err);
06665 }
06666
06667 void
06668 pdv_setdebug(PdvDev * pdv_p, int debug)
06669 {
06670 Pdv_debug = debug;
06671 }
06672
06673
06674
06675
06676
06689 void
06690 pdv_reset_serial(PdvDev * pdv_p)
06691 {
06692 edt_reset_serial(pdv_p);
06693 }
06694
06695
06716 uchar_t *
06717 pdv_alloc(int size)
06718 {
06719 return edt_alloc(size);
06720 }
06721
06722
06729 void
06730 pdv_free(uchar_t * ptr)
06731 {
06732 edt_free(ptr);
06733 }
06734
06735
06736
06737 static u_short zero[] = {
06738 0x0F80,
06739 0x3FE0,
06740 0x38E0,
06741 0x7070,
06742 0x6030,
06743 0xE038,
06744 0xE038,
06745 0xE038,
06746 0xE038,
06747 0xE038,
06748 0xE038,
06749 0xE038,
06750 0x6030,
06751 0x7070,
06752 0x38E0,
06753 0x3FE0,
06754 0x0F80,
06755 };
06756 static u_short one[] = {
06757 0xFC00,
06758 0xFC00,
06759 0x1C00,
06760 0x1C00,
06761 0x1C00,
06762 0x1C00,
06763 0x1C00,
06764 0x1C00,
06765 0x1C00,
06766 0x1C00,
06767 0x1C00,
06768 0x1C00,
06769 0x1C00,
06770 0x1C00,
06771 0x1C00,
06772 0xFF80,
06773 0xFF80,
06774 };
06775 static u_short two[] = {
06776 0x7E00,
06777 0x7F80,
06778 0x4380,
06779 0x01C0,
06780 0x01C0,
06781 0x01C0,
06782 0x01C0,
06783 0x0380,
06784 0x0700,
06785 0x0E00,
06786 0x1C00,
06787 0x3800,
06788 0x3800,
06789 0x7000,
06790 0xE000,
06791 0xFFC0,
06792 0xFFC0,
06793 };
06794 static u_short three[] = {
06795 0x7E00,
06796 0xFF00,
06797 0x8780,
06798 0x0380,
06799 0x0380,
06800 0x0380,
06801 0x0F00,
06802 0x7C00,
06803 0x7E00,
06804 0x0F00,
06805 0x0380,
06806 0x0380,
06807 0x0380,
06808 0x0380,
06809 0x8700,
06810 0xFF00,
06811 0xFC00,
06812 };
06813 static u_short four[] = {
06814 0x0380,
06815 0x0780,
06816 0x0F80,
06817 0x0F80,
06818 0x1F80,
06819 0x1B80,
06820 0x3380,
06821 0x3380,
06822 0x6380,
06823 0xE380,
06824 0xFFE0,
06825 0xFFE0,
06826 0xFFE0,
06827 0x0380,
06828 0x0380,
06829 0x0380,
06830 0x0380,
06831 };
06832 static u_short five[] = {
06833 0xFF80,
06834 0xFF80,
06835 0xE000,
06836 0xE000,
06837 0xE000,
06838 0xC000,
06839 0xF800,
06840 0xFE00,
06841 0x0F00,
06842 0x0780,
06843 0x0380,
06844 0x0380,
06845 0x0380,
06846 0x0380,
06847 0x8700,
06848 0xFE00,
06849 0xFC00,
06850 };
06851 static u_short six[] = {
06852 0x07E0,
06853 0x1FE0,
06854 0x3C20,
06855 0x7000,
06856 0x7000,
06857 0xE000,
06858 0xE780,
06859 0xFFE0,
06860 0xF0E0,
06861 0xE070,
06862 0xE070,
06863 0xE070,
06864 0xE070,
06865 0x7070,
06866 0x70E0,
06867 0x3FC0,
06868 0x0F80,
06869 };
06870 static u_short seven[] = {
06871 0xFFC0,
06872 0xFFC0,
06873 0x01C0,
06874 0x0180,
06875 0x0380,
06876 0x0700,
06877 0x0700,
06878 0x0E00,
06879 0x0C00,
06880 0x1C00,
06881 0x1800,
06882 0x3800,
06883 0x3800,
06884 0x3000,
06885 0x7000,
06886 0x7000,
06887 0x7000,
06888 };
06889 static u_short eight[] = {
06890 0x0F80,
06891 0x3FC0,
06892 0x71E0,
06893 0x70E0,
06894 0x70E0,
06895 0x7DE0,
06896 0x3FC0,
06897 0x1F00,
06898 0x1FC0,
06899 0x7FE0,
06900 0xF1F0,
06901 0xE0F0,
06902 0xE070,
06903 0xE070,
06904 0xF0E0,
06905 0x7FE0,
06906 0x1F80,
06907 };
06908 static u_short nine[] = {
06909 0x1F00,
06910 0x3FC0,
06911 0x70E0,
06912 0xE0E0,
06913 0xE070,
06914 0xE070,
06915 0xE070,
06916 0xE070,
06917 0x70F0,
06918 0x7FF0,
06919 0x1E70,
06920 0x0070,
06921 0x00E0,
06922 0x00E0,
06923 0x43C0,
06924 0x7F80,
06925 0x7E00,
06926 };
06927
06928 static u_short *digits[] = {
06929 zero,
06930 one,
06931 two,
06932 three,
06933 four,
06934 five,
06935 six,
06936 seven,
06937 eight,
06938 nine,
06939 };
06940
06941
06942 static void
06943 set_square_32(int sx, int sy, u_short * buf, u_int * addr, int stride, int fg)
06944 {
06945
06946
06947
06948
06949 #define BG16 0
06950
06951
06952
06953
06954 register u_int *svptr;
06955 register u_int *ptr;
06956 int i;
06957 int bit;
06958 u_short tmp;
06959 int val;
06960
06961 svptr = addr + (stride * sy) + (sx);
06962
06963 for (i = 0; i < 17; i++)
06964 {
06965 ptr = svptr;
06966 tmp = *buf++;
06967 for (bit = 15; bit >= 0; bit--)
06968 {
06969 if (tmp & (1 << bit))
06970 {
06971 val = fg;
06972 }
06973 else
06974 {
06975 val = BG16;
06976 }
06977 *ptr++ = val;
06978 }
06979 svptr += stride;
06980 }
06981 }
06982
06983
06984 static void
06985 set_square_16(int sx, int sy, u_short * buf, u_short * addr, int stride, int fg)
06986 {
06987
06988
06989
06990
06991 #define BG16 0
06992
06993
06994
06995
06996 register u_short *svptr;
06997 register u_short *ptr;
06998 int i;
06999 int bit;
07000 u_short tmp;
07001 int val;
07002
07003 svptr = addr + (stride * sy) + (sx);
07004
07005 for (i = 0; i < 17; i++)
07006 {
07007 ptr = svptr;
07008 tmp = *buf++;
07009 for (bit = 15; bit >= 0; bit--)
07010 {
07011 if (tmp & (1 << bit))
07012 {
07013 val = fg;
07014 }
07015 else
07016 {
07017 val = BG16;
07018 }
07019 *ptr++ = val;
07020 }
07021 svptr += stride;
07022 }
07023 }
07024
07025 static void
07026 set_square(int sx, int sy, u_short * buf, u_char * addr, int stride, int fg)
07027 {
07028
07029
07030
07031
07032 #define BG 0
07033
07034
07035
07036
07037 register u_char *svptr;
07038 register u_char *ptr;
07039 int i;
07040 int bit;
07041 u_short tmp;
07042 int val;
07043
07044 svptr = addr + (stride * sy) + (sx);
07045
07046 for (i = 0; i < 17; i++)
07047 {
07048 ptr = svptr;
07049 tmp = *buf++;
07050 for (bit = 15; bit >= 0; bit--)
07051 {
07052 if (tmp & (1 << bit))
07053 {
07054 val = fg;
07055 }
07056 else
07057 {
07058 val = BG;
07059 }
07060 *ptr++ = val;
07061 }
07062 svptr += stride;
07063 }
07064 }
07065
07066 void
07067 pdv_mark_digit_16(u_short * addr, int n, int width, int height, int x, int y,
07068 int mask, int fg)
07069
07070 {
07071 int dig = n % 10;
07072
07073 set_square_16(x, y, digits[dig], addr, width, fg);
07074
07075 }
07076
07077 void
07078 pdv_mark_digit_32(u_int * addr, int n, int width, int height, int x, int y,
07079 int mask, int fg)
07080
07081 {
07082 int dig = n % 10;
07083
07084 set_square_32(x, y, digits[dig], addr, width, fg);
07085
07086 }
07087
07088 void
07089 pdv_mark_digit_24(u_char * addr, int n, int width, int height, int x, int y,
07090 int mask, int fg)
07091
07092 {
07093 int dig = n % 10;
07094
07095 set_square(x, y, digits[dig], addr, width, fg);
07096
07097 }
07098
07099 void
07100 pdv_mark_digit_8(u_char * addr, int n, int width, int height, int x, int y,
07101 int mask, int fg)
07102
07103 {
07104 int dig = n % 10;
07105
07106 set_square(x, y, digits[dig], addr, width, fg);
07107
07108 }
07109
07110 void
07111 pdv_mark_ras_depth(void * addr, int n, int width, int height, int x, int y, int depth, int fg)
07112 {
07113 #define GAP 16
07114 int div = 1000000;
07115
07116 int i;
07117
07118 for (i=0;div>=1;i++)
07119 {
07120
07121 if (n > div)
07122 {
07123 int val = (n / div) % 10;
07124
07125 switch(depth)
07126 {
07127 case 8:
07128 pdv_mark_digit_8((u_char *) addr, val, width, height, x + (GAP * i), y, 1, fg);
07129 break;
07130 case 16:
07131 pdv_mark_digit_16((u_short *) addr, val, width, height, x + (GAP * i), y, 1, fg);
07132 break;
07133 case 24:
07134 pdv_mark_digit_24((u_char *) addr, val, width, height, x + (GAP * i), y, 1, fg);
07135 break;
07136 case 32:
07137 pdv_mark_digit_32((u_int *) addr, val, width, height, x + (GAP * i), y, 1, fg);
07138 break;
07139 }
07140 }
07141
07142 div /= 10;
07143 }
07144 }
07145
07146 void
07147 pdv_mark_bin_16(u_short * addr, int n, int width, int height, int x, int y)
07148 {
07149 u_int val = n;
07150 u_char *svptr;
07151
07152 svptr = (u_char *) addr + (width * y) + x;
07153 *svptr++ = (val >> 24) & 0xff;
07154 *svptr++ = (val >> 16) & 0xff;
07155 *svptr++ = (val >> 8) & 0xff;
07156 *svptr++ = val & 0xff;
07157 }
07158
07159
07160 void
07161 pdv_mark_ras(u_char * addr, int n, int width, int height, int x, int y)
07162 {
07163 #define GAP 16
07164 int div = 1000000;
07165 int i;
07166
07167 for (i=0;div;i++)
07168 {
07169 pdv_mark_digit_8(addr, n, width, height, x + (GAP * i), y, div, 200);
07170 div /= 10;
07171 }
07172 }
07173
07174 void
07175 pdv_mark_bin(u_char * addr, int n, int width, int height, int x, int y)
07176 {
07177 u_int val = n;
07178 u_char *svptr;
07179
07180 svptr = (u_char *) addr + (width * y) + x;
07181 *svptr++ = (val >> 24) & 0xff;
07182 *svptr++ = (val >> 16) & 0xff;
07183 *svptr++ = (val >> 8) & 0xff;
07184 *svptr++ = val & 0xff;
07185 }
07186
07204 int
07205 pdv_serial_command_hex(PdvDev * pdv_p, const char *str, int length)
07206 {
07207 char buf[2];
07208 const char *p = &str[2];
07209 u_int lval;
07210
07211 sscanf(p, "%x", &lval);
07212 buf[0] = (char) (lval & 0xff);
07213 edt_msg(DBG2, "pdv_serial_command_hex(%s),0x%x\n", str, (u_char) (buf[0]));
07214
07215 return pdv_serial_binary_command(pdv_p, buf, 1);
07216 }
07217
07261 int
07262 pdv_set_roi(PdvDev * pdv_p, int hskip, int hactv, int vskip, int vactv)
07263 {
07264 Dependent *dd_p = pdv_p->dd_p;
07265 int cam_w, cam_h;
07266
07267 edt_msg(DBG2, "pdv_set_roi(hskip %d hactv %d vskip %d vactv %d)\n",
07268 hskip, hactv, vskip, vactv);
07269
07270
07271
07272
07273 if (dd_p->xilinx_rev < 2 || dd_p->xilinx_rev > 32)
07274 {
07275 edt_msg(DBG2, "pdv_set_roi(): WARNING: can't enable, N/A this xilinx (%x)\n",
07276 dd_p->xilinx_rev);
07277 return -1;
07278 }
07279
07280 cam_w = pdv_get_cam_width(pdv_p);
07281 cam_h = pdv_get_cam_height(pdv_p);
07282
07283
07284 if (!pdv_is_cameralink(pdv_p))
07285 {
07286 if ((cam_w && ((hskip + hactv) > cam_w)) || ((hskip + hactv) <= 0))
07287 {
07288 edt_msg(DBG2, "ROI: horiz. skip/actv out of range error\n");
07289 return -1;
07290 }
07291 if ((cam_h && ((vskip + vactv) > cam_h)) || ((vskip + vactv) <= 0))
07292 {
07293 edt_msg(DBG2, "ROI: vert. skip/actv out of range error\n");
07294 return -1;
07295 }
07296 }
07297
07298
07299 if (pdv_is_cameralink(pdv_p))
07300 {
07301 if (dd_p->htaps > 0)
07302 {
07303 hactv = (hactv / dd_p->htaps) * dd_p->htaps;
07304 hskip = (hskip / dd_p->htaps) * dd_p->htaps;
07305
07306 edt_reg_write(pdv_p, PDV_HSKIP, (hskip / dd_p->htaps));
07307 edt_reg_write(pdv_p, PDV_HACTV, (hactv / dd_p->htaps) - 1);
07308 }
07309
07310 if (dd_p->vtaps > 0)
07311 {
07312 vactv = (vactv / dd_p->vtaps) * dd_p->vtaps;
07313 vskip = (vskip / dd_p->vtaps) * dd_p->vtaps;
07314
07315 edt_reg_write(pdv_p, PDV_VSKIP, (vskip / dd_p->vtaps));
07316 edt_reg_write(pdv_p, PDV_VACTV, (vactv / dd_p->vtaps) - 1);
07317 }
07318 }
07319 else if (dd_p->dual_channel)
07320 {
07321 vactv = (vactv / 2) * 2;
07322 vskip = (vskip / 2) * 2;
07323 edt_reg_write(pdv_p, PDV_VSKIP, (vskip / 2));
07324 edt_reg_write(pdv_p, PDV_HSKIP, hskip);
07325 edt_reg_write(pdv_p, PDV_VACTV, (vactv / 2) - 1);
07326 edt_reg_write(pdv_p, PDV_HACTV, hactv - 1);
07327 }
07328 else
07329 {
07330 edt_reg_write(pdv_p, PDV_HSKIP, hskip);
07331 edt_reg_write(pdv_p, PDV_VSKIP, vskip);
07332 edt_reg_write(pdv_p, PDV_HACTV, hactv - 1);
07333 edt_reg_write(pdv_p, PDV_VACTV, vactv - 1);
07334 }
07335
07336 dd_p->hactv = hactv;
07337 dd_p->hskip = hskip;
07338 dd_p->vactv = vactv;
07339 dd_p->vskip = vskip;
07340
07341 if (dd_p->roi_enabled)
07342 pdv_setsize(pdv_p, dd_p->hactv, dd_p->vactv);
07343
07344 edt_set_dependent(pdv_p, dd_p);
07345
07346 return 0;
07347
07348 }
07349
07350
07351 void
07352 pdv_cl_set_base_channels(PdvDev *pdv_p, int htaps, int vtaps)
07353
07354 {
07355 Dependent *dd_p = pdv_p->dd_p;
07356 int taps = (htaps > vtaps)? htaps : vtaps;
07357
07358 dd_p->cl_data_path = (taps - 1) << 4 | (dd_p->depth - 1);
07359
07360 dd_p->htaps = htaps;
07361 dd_p->vtaps = vtaps;
07362
07363 edt_reg_write(pdv_p, PDV_CL_DATA_PATH, dd_p->cl_data_path);
07364
07365 edt_set_dependent(pdv_p, dd_p);
07366
07367 pdv_set_roi(pdv_p, dd_p->hskip, dd_p->hactv, dd_p->vskip, dd_p->vactv);
07368 }
07369
07370
07371
07372
07373
07374
07375
07376
07377 int
07378 pdv_dalsa_ls_set_expose(PdvDev * pdv_p, int hskip, int hactv)
07379 {
07380 Dependent *dd_p = pdv_p->dd_p;
07381
07382 edt_msg(DBG2, "pdv_dalsa_ls_set_expose(hskip %d hactv %d)\n", hskip, hactv);
07383
07384
07385
07386
07387 if (dd_p->xilinx_rev < 2 || dd_p->xilinx_rev > 32)
07388 {
07389 edt_msg(DBG2, "pdv_dalsa_ls_set_expose(): WARNING: can't enable, N/A this xilinx (%x)\n", dd_p->xilinx_rev);
07390 return -1;
07391 }
07392
07393 edt_reg_write(pdv_p, PDV_HSKIP, hskip);
07394 edt_reg_write(pdv_p, PDV_HACTV, hactv - 1);
07395
07396 dd_p->hactv = hactv;
07397 dd_p->hskip = hskip;
07398
07399 edt_set_dependent(pdv_p, dd_p);
07400 pdv_enable_roi(pdv_p, 1);
07401
07402 return 0;
07403
07404 }
07405
07406
07415 int
07416 pdv_auto_set_roi(PdvDev * pdv_p)
07417 {
07418 int w = pdv_p->dd_p->width;
07419 int h = pdv_p->dd_p->height;
07420 int ret;
07421
07422 edt_msg(DBG2, "pdv_auto_set_roi()\n");
07423
07424 if ((ret = pdv_set_roi(pdv_p, 0, w, 0, h)) == 0)
07425 {
07426 if (pdv_is_cameralink(pdv_p))
07427 pdv_setsize(pdv_p, pdv_p->dd_p->hactv, pdv_p->dd_p->vactv);
07428 ret = pdv_enable_roi(pdv_p, 1);
07429 }
07430
07431 return ret;
07432 }
07433
07456 int
07457 pdv_enable_roi(PdvDev * pdv_p, int flag)
07458 {
07459 u_int roictl;
07460 Dependent *dd_p = pdv_p->dd_p;
07461
07462
07463 if (pdv_is_cameralink(pdv_p))
07464 {
07465 if (flag)
07466 {
07467 edt_reg_and(pdv_p, PDV_CL_CFG, ~0x08);
07468 pdv_setsize(pdv_p, dd_p->hactv, dd_p->vactv);
07469 }
07470 else
07471 {
07472 edt_reg_or(pdv_p, PDV_CL_CFG, 0x08);
07473 pdv_setsize(pdv_p, dd_p->cam_width, dd_p->cam_height);
07474 }
07475
07476 dd_p->roi_enabled = flag;
07477
07478 return 0;
07479 }
07480
07481 if (dd_p->xilinx_rev < 2 || dd_p->xilinx_rev > 32)
07482 {
07483 edt_msg(DBG2, "pdv_enable_roi(): can't enable, N/A this xilinx (%x)\n", dd_p->xilinx_rev);
07484 return -1;
07485 }
07486
07487 edt_msg(DBG2, "pdv_enable_roi(%d): %sabling\n", flag, flag ? "EN" : "DIS");
07488
07489
07490
07491 roictl = edt_reg_read(pdv_p, PDV_ROICTL);
07492
07493
07494 if (flag)
07495 {
07496 roictl |= PDV_ROICTL_ROI_EN;
07497 edt_reg_write(pdv_p, PDV_ROICTL, roictl);
07498 pdv_setsize(pdv_p, dd_p->hactv, dd_p->vactv);
07499 }
07500 else
07501 {
07502
07503 roictl &= ~PDV_ROICTL_ROI_EN;
07504 edt_reg_write(pdv_p, PDV_ROICTL, roictl);
07505 pdv_setsize(pdv_p, dd_p->cam_width, dd_p->cam_height);
07506 }
07507
07508 dd_p->roi_enabled = flag;
07509
07510 return 0;
07511 }
07512
07532 int
07533 pdv_access(char *fname, int perm)
07534 {
07535 return edt_access(fname, perm);
07536 }
07537
07538
07562 int
07563 pdv_strobe(PdvDev * pdv_p, int count, int delay)
07564 {
07565 if (pdv_strobe_method(pdv_p) != PDV_LHS_METHOD1)
07566 return -1;
07567
07568 edt_msg(DBG2, "pdv_strobe(%d %d)\n", count, delay);
07569
07570 edt_reg_write(pdv_p, PDV_SHUTTER, delay);
07571
07572
07573
07574
07575
07576 edt_reg_write(pdv_p, PDV_FIXEDLEN, count);
07577
07578 return 0;
07579 }
07580
07601 int
07602 pdv_set_strobe_counters(PdvDev * pdv_p, int count, int delay, int period)
07603 {
07604 if (pdv_strobe_method(pdv_p) != PDV_LHS_METHOD2)
07605 return -1;
07606
07607 if (count > 0xfff)
07608 {
07609 edt_msg(DBG1, "pdv_set_strobe_counters() ERROR -- count out of range\n");
07610 return -1;
07611 }
07612
07613 if (delay > 0xff)
07614 {
07615 edt_msg(PDVWARN, "pdv_set_strobe_counters() ERROR -- delay out of range\n");
07616 return -1;
07617 }
07618
07619 if (period > 0xff)
07620 {
07621 edt_msg(PDVWARN, "pdv_set_strobe_counters() ERROR -- period out of range\n");
07622 return -1;
07623 }
07624
07625 edt_msg(DBG2, "pdv_set_strobe_counters(%d %d %d)\n", count, delay, period);
07626
07627 edt_reg_write(pdv_p, PDV_LHS_DELAY, delay);
07628
07629 edt_reg_write(pdv_p, PDV_LHS_PERIOD, period);
07630
07631
07632
07633
07634 edt_reg_write(pdv_p, PDV_LHS_COUNT, count);
07635
07636 return 0;
07637 }
07638
07650 int
07651 pdv_enable_strobe(PdvDev * pdv_p, int ena)
07652 {
07653 int method = pdv_strobe_method(pdv_p);
07654
07655 if (pdv_p->devid == PDVFOI_ID)
07656 return -1;
07657
07658 if (method == 0)
07659 return -1;
07660
07661 if (method == PDV_LHS_METHOD1)
07662 {
07663 if (ena == 0)
07664 return -1;
07665 return 0;
07666 }
07667
07668 if (ena)
07669 edt_reg_write(pdv_p, PDV_LHS_CONTROL, PDV_LHS_ENABLE);
07670 else edt_reg_write(pdv_p, PDV_LHS_CONTROL, 0);
07671
07672 return 0;
07673 }
07674
07685 int
07686 pdv_strobe_method(PdvDev *pdv_p)
07687 {
07688 Dependent *dd_p = pdv_p->dd_p;
07689
07690 if (dd_p->strobe_enabled == NOT_SET)
07691 {
07692 int reg ;
07693
07694
07695 dd_p->strobe_enabled = 0;
07696
07697 if (pdv_p->devid == PDVFOI_ID)
07698 return 0;
07699
07700
07701
07702 if (pdv_p->devid == PDVCL_ID)
07703 {
07704 dd_p->strobe_enabled = PDV_LHS_METHOD2;
07705 return dd_p->strobe_enabled;
07706 }
07707
07708
07709 if (dd_p->xilinx_rev < 2 || dd_p->xilinx_rev > 32)
07710 return 0;
07711
07712
07713
07714
07715 if (!dd_p->register_wrap)
07716 {
07717 reg = edt_reg_read(pdv_p, PDV_LHS_COUNT_HI);
07718 edt_reg_write(pdv_p, PDV_LHS_COUNT_HI, 0x50);
07719 if (edt_reg_read(pdv_p, PDV_LHS_COUNT_HI) == 0x50)
07720 {
07721 edt_reg_write(pdv_p, PDV_LHS_COUNT_HI, reg);
07722 dd_p->strobe_enabled = PDV_LHS_METHOD2;
07723 return dd_p->strobe_enabled;
07724 }
07725 }
07726
07727
07728 if (pdv_p->devid != PDVFOI_ID)
07729 {
07730 int status = edt_reg_read(pdv_p, PDV_SERIAL_DATA_STAT);
07731
07732 if (status & LHS_DONE)
07733 dd_p->strobe_enabled = PDV_LHS_METHOD1;
07734 }
07735 }
07736
07737 return dd_p->strobe_enabled;
07738 }
07739
07740
07760 int
07761 pdv_set_strobe_dac(PdvDev * pdv_p, u_int value)
07762 {
07763 int i;
07764 int reg;
07765 int method;
07766 u_int mcl, mask;
07767 u_char data;
07768
07769 if ((method = pdv_strobe_method(pdv_p)) == 0)
07770 return -1;
07771
07772 if (method == PDV_LHS_METHOD2)
07773 reg = PDV_LHS_CONTROL;
07774 else reg = PDV_MODE_CNTL;
07775
07776 edt_msg(DBG2, "pdv_strobe(%d)\n", value);
07777
07778 mcl = edt_reg_read(pdv_p, reg) & 0x0f;
07779
07780
07781
07782
07783
07784 edt_reg_write(pdv_p, reg, mcl | PDV_LHS_DAC_LOAD);
07785
07786
07787
07788
07789 for (i = 0; i < 16; i++)
07790 {
07791 mask = (value & (1 << (15 - i)));
07792
07793 if (mask)
07794 data = PDV_LHS_DAC_DATA;
07795 else
07796 data = 0;
07797
07798 edt_reg_write(pdv_p, reg, mcl | PDV_LHS_DAC_LOAD | data);
07799 edt_reg_write(pdv_p, reg, mcl | PDV_LHS_DAC_LOAD | PDV_LHS_DAC_CLOCK | data);
07800 edt_reg_write(pdv_p, reg, mcl | PDV_LHS_DAC_LOAD | data);
07801 edt_reg_write(pdv_p, reg, mcl | PDV_LHS_DAC_LOAD);
07802 }
07803
07804 edt_reg_write(pdv_p, reg, mcl &~ PDV_LHS_DAC_LOAD);
07805 return 0;
07806 }
07807
07815 void
07816 pdv_flush_channel_fifo(PdvDev * pdv_p)
07817 {
07818
07819
07820
07821
07822 pdv_flush_fifo(pdv_p);
07823 }
07824
07843 void
07844 pdv_flush_fifo(PdvDev * pdv_p)
07845 {
07846
07847 if (pdv_p->devid == PDV_ID ||
07848 pdv_p->devid == PDVK_ID ||
07849 pdv_p->devid == PDVFOI_ID ||
07850 pdv_p->devid == PDVA_ID)
07851 {
07852 edt_flush_fifo(pdv_p);
07853 return;
07854 }
07855
07856 if (pdv_p->devid == PDVCL_ID ||
07857 pdv_p->devid == PE8DVCL_ID ||
07858 pdv_p->devid == PE8DVCLS_ID ||
07859 pdv_p->devid == PE4DVCL_ID)
07860 {
07861
07862
07863
07864 u_int cfg ;
07865
07866 cfg = edt_intfc_read(pdv_p, PDV_CFG);
07867 cfg &= ~PDV_FIFO_RESET;
07868 edt_intfc_write(pdv_p, PDV_CMD, PDV_RESET_INTFC);
07869 edt_intfc_write(pdv_p, PDV_CFG, (u_char) (cfg | PDV_FIFO_RESET));
07870 edt_intfc_write(pdv_p, PDV_CFG, cfg);
07871 edt_flush_channel(pdv_p, pdv_p->channel_no);
07872
07873 }
07874 else if (pdv_p->devid == PDVFOI_ID)
07875 {
07876 char tmpbuf[10];
07877 int ret;
07878
07879 ret = pdv_serial_wait(pdv_p, 100, 0);
07880 if (ret > 10)
07881 pdv_reset_serial(pdv_p);
07882 else
07883 pdv_serial_read(pdv_p, tmpbuf, ret);
07884 }
07885 else
07886 {
07887
07888
07889 u_int cfg ;
07890 cfg = edt_intfc_read(pdv_p, PDV_CFG);
07891 cfg &= ~PDV_FIFO_RESET;
07892 edt_intfc_write(pdv_p, PDV_CFG, (u_char) (cfg | PDV_FIFO_RESET));
07893 edt_flush_channel(pdv_p, pdv_p->channel_no);
07894 edt_intfc_write(pdv_p, PDV_CFG, cfg);
07895 }
07896 }
07897
07901 void
07902 pdv_setup_continuous_channel(PdvDev * pdv_p)
07903
07904 {
07905
07906
07907 pdv_setup_continuous(pdv_p);
07908 }
07909
07918 void
07919 pdv_setup_continuous(PdvDev * pdv_p)
07920 {
07921 pdv_flush_fifo(pdv_p);
07922
07923 if (pdv_p->devid == PDV_ID ||
07924 pdv_p->devid == PDVK_ID ||
07925 pdv_p->devid == PDVA_ID)
07926 {
07927
07928 if (edt_get_firstflush(pdv_p) != EDT_ACT_KBS)
07929 edt_set_firstflush(pdv_p, EDT_ACT_ONCE);
07930 }
07931 else
07932 {
07933 edt_set_firstflush(pdv_p,EDT_ACT_NEVER) ;
07934 edt_set_autodir(pdv_p, 0) ;
07935
07936 }
07937
07938 edt_startdma_reg(pdv_p, PDV_CMD, PDV_ENABLE_GRAB);
07939
07940 if (pdv_in_continuous(pdv_p))
07941 {
07942
07943 edt_set_continuous(pdv_p, 1);
07944 }
07945 else if (pdv_p->dd_p->fv_once)
07946 {
07947 pdv_start_hardware_continuous(pdv_p);
07948 }
07949 else
07950 edt_set_continuous(pdv_p, 0);
07951
07952 pdv_p->dd_p->started_continuous = 1;
07953
07954 }
07955
07963 void
07964 pdv_stop_continuous(PdvDev * pdv_p)
07965 {
07966
07967 if (pdv_in_continuous(pdv_p))
07968 {
07969 edt_set_continuous(pdv_p, 0);
07970 }
07971 else if (pdv_p->dd_p->fv_once)
07972 pdv_stop_hardware_continuous(pdv_p);
07973
07974 pdv_p->dd_p->started_continuous = 0;
07975
07976 if (pdv_p->devid == PDVFOI_ID)
07977 {
07978 char tmpbuf[10];
07979 int ret;
07980
07981 ret = pdv_serial_wait(pdv_p, 100, 0);
07982 if (ret > 10)
07983 pdv_reset_serial(pdv_p);
07984 else
07985 pdv_serial_read(pdv_p, tmpbuf, ret);
07986 }
07987 }
07988
08009 int
08010 pdv_timeout_restart(PdvDev * pdv_p, int restart)
08011 {
08012 int curdone, curtodo;
08013
08014 curdone = edt_done_count(pdv_p);
08015 curtodo = edt_get_todo(pdv_p);
08016
08017 edt_abort_dma(pdv_p);
08018 pdv_stop_continuous(pdv_p);
08019
08020 edt_set_buffer(pdv_p, curdone);
08021 edt_reg_write(pdv_p, PDV_CMD, PDV_RESET_INTFC);
08022 pdv_setup_continuous(pdv_p);
08023
08024 if (restart &&
08025 (curtodo - curdone))
08026 pdv_start_images(pdv_p, curtodo - curdone);
08027
08028 return curtodo - curdone;
08029 }
08030
08032
08033
08034 static char hs[128];
08035 static char *
08036 hex_to_str(char *resp, int n)
08037 {
08038
08039 int i;
08040 char *p = hs;
08041
08042 for (i = 0; i < n; i++)
08043 {
08044 sprintf(p, "%02x ", resp[i]);
08045 p += 3;
08046 }
08047 *p = '\0';
08048 return hs;
08049 }
08050
08051
08062 int
08063 pdv_get_min_shutter(PdvDev * pdv_p)
08064
08065 {
08066 return pdv_p->dd_p->shutter_speed_min;
08067 }
08068
08069
08078 int
08079 pdv_get_max_shutter(PdvDev * pdv_p)
08080
08081 {
08082 return pdv_p->dd_p->shutter_speed_max;
08083 }
08084
08085
08095 int
08096 pdv_get_min_gain(PdvDev * pdv_p)
08097
08098 {
08099 return pdv_p->dd_p->gain_min;
08100 }
08101
08102
08112 int
08113 pdv_get_max_gain(PdvDev * pdv_p)
08114
08115 {
08116 return pdv_p->dd_p->gain_max;
08117 }
08118
08119
08129 int
08130 pdv_get_min_offset(PdvDev * pdv_p)
08131
08132 {
08133 return pdv_p->dd_p->offset_min;
08134 }
08135
08136
08146 int
08147 pdv_get_max_offset(PdvDev * pdv_p)
08148
08149 {
08150 return pdv_p->dd_p->offset_max;
08151 }
08152
08159 int
08160 pdv_enable_lock(PdvDev * pdv_p, int flag)
08161 {
08162 Dependent *dd_p = pdv_p->dd_p;
08163 int ret;
08164
08165 switch (dd_p->lock_shutter)
08166 {
08167 case KODAK_AIA_MCL:
08168 {
08169 int mcl = edt_reg_read(pdv_p, PDV_MODE_CNTL);
08170
08171 if (flag)
08172 mcl |= PDV_AIA_MC3;
08173 else
08174 mcl &= ~PDV_AIA_MC3;
08175
08176 edt_reg_write(pdv_p, PDV_MODE_CNTL, mcl);
08177 ret = 0;
08178 break;
08179 }
08180 case KODAK_AIA_SER:
08181 {
08182 if (flag)
08183 ret = pdv_serial_command(pdv_p, "SHE OF");
08184 else
08185 ret = pdv_serial_command(pdv_p, "SHE ON");
08186
08187 break;
08188 }
08189 case KODAK_SER_14I:
08190 {
08191 if (flag)
08192 ret = pdv_serial_command(pdv_p, "SHE FO");
08193 else
08194 ret = pdv_serial_command(pdv_p, "SHE ON");
08195 break;
08196 }
08197 case HAM_4880:
08198 {
08199 if (flag)
08200 ret = pdv_serial_command(pdv_p, "ASH O");
08201 else
08202 ret = pdv_serial_command(pdv_p, "ASH A");
08203 break;
08204 }
08205 }
08206 return (ret);
08207 }
08208
08209
08214 void
08215 pdv_send_break(PdvDev * pdv_p)
08216 {
08217 u_int reg;
08218
08219 edt_msg(DBG2, "pdv_send_break()");
08220
08221 reg = edt_reg_read(pdv_p, PDV_UTIL2);
08222 edt_reg_write(pdv_p, PDV_UTIL2, reg & ~PDV_MC4);
08223 edt_reg_write(pdv_p, PDV_UTIL2, (reg | PDV_SEL_MC4) & ~PDV_MC4);
08224 edt_msleep(500);
08225 edt_reg_write(pdv_p, PDV_UTIL2, reg & ~PDV_SEL_MC4 & ~PDV_MC4);
08226 edt_reg_write(pdv_p, PDV_UTIL2, reg);
08227 }
08228
08229 static void
08230 pdv_trigger_specinst(PdvDev * pdv_p)
08231 {
08232 char cmd = pdv_p->dd_p->serial_trigger[0];
08233
08234 edt_msg(DBG2, "pdv_trigger_specinst('%c')\n", cmd);
08235
08236 pdv_serial_binary_command(pdv_p, &cmd, 1);
08237
08238 }
08239
08243 static void
08244 pdv_posttrigger_specinst(PdvDev * pdv_p)
08245 {
08246 char cmd = pdv_p->dd_p->serial_trigger[0];
08247 char resp[32];
08248 int ret;
08249 int waitcnt = 2;
08250
08251 resp[0] = resp[1] = resp[2] = 0;
08252
08253 #ifdef SPECINST_WAS
08254 if (pdv_p->devid == PDVFOI_ID)
08255 waitcnt += 2;
08256 if ((ret = pdv_serial_wait(pdv_p, 1500, waitcnt)) == waitcnt)
08257 pdv_serial_read(pdv_p, resp, ret);
08258 #else
08259 if (pdv_p->devid == PDVFOI_ID)
08260 pdv_serial_wait_next(pdv_p, 2000, 0);
08261 else
08262 pdv_serial_wait_next(pdv_p, 2000, 1);
08263 ret = pdv_serial_read(pdv_p, resp, 2);
08264 #endif
08265
08266 if ((ret != waitcnt)
08267 || (resp[0] != pdv_p->dd_p->serial_trigger[0])
08268 || (resp[1] != pdv_p->dd_p->serial_response[0]))
08269 {
08270 edt_msg(DBG2, "\npdv_posttrigger_specinst: invalid/missing serial?\n");
08271 edt_msg(DBG2, "response (sent %c, ret %d s/b %d, resp <%s>)\n", cmd, ret, waitcnt, (ret > 0) ? resp : "");
08272 return;
08273 }
08274 }
08275
08276 static int
08277 pdv_specinst_serial_triggered(PdvDev * pdv_p)
08278 {
08279 if (((pdv_p->dd_p->camera_shutter_timing == SPECINST_SERIAL)
08280 || (pdv_p->dd_p->camera_shutter_speed == SPECINST_SERIAL))
08281 && (pdv_p->dd_p->serial_trigger[0]))
08282 return 1;
08283 return 0;
08284 }
08285
08286 int
08287 pdv_pause_for_serial(PdvDev * pdv_p)
08288 {
08289 return pdv_p->dd_p->pause_for_serial;
08290 }
08291
08292
08293 static int
08294 isafloat(char *str)
08295 {
08296 unsigned int i;
08297 int numdots = 0;
08298 int numchars = 0;
08299
08300 for (i = 0; i < strlen(str); i++)
08301 {
08302 if (str[i] == '.')
08303 ++numdots;
08304 else if (isdigit(str[i]))
08305 ++numchars;
08306 else
08307 return 0;
08308 }
08309
08310 if (numdots == 1 && numchars > 0)
08311 return 1;
08312 return 0;
08313 }
08314
08315 static int
08316 isdigits(char *str)
08317 {
08318 unsigned int i;
08319 int numchars = 0;
08320
08321 for (i = 0; i < strlen(str); i++)
08322 {
08323 if (isdigit(str[i]))
08324 ++numchars;
08325 else if ((str[i] == '-') && (i == 0))
08326 ;
08327 else
08328 return 0;
08329 }
08330
08331 if (numchars > 0)
08332 return 1;
08333 return 0;
08334 }
08335
08336 static int
08337 isxdigits(char *str)
08338 {
08339 unsigned int i;
08340 int numchars = 0;
08341
08342 for (i = 0; i < strlen(str); i++)
08343 {
08344 if (isxdigit(str[i]))
08345 ++numchars;
08346 else
08347 return 0;
08348 }
08349
08350 if (numchars > 0)
08351 return 1;
08352 return 0;
08353 }
08354
08362 int
08363 pdv_is_kodak_i(PdvDev * pdv_p)
08364 {
08365 Dependent *dd_p = pdv_p->dd_p;
08366
08367 if ((strcmp(dd_p->serial_exposure, "EXE") == 0)
08368 || (strcmp(dd_p->serial_gain, "DGN") == 0)
08369 || (strcmp(dd_p->serial_offset, "GAE") == 0)
08370 || (strcmp(dd_p->serial_offset, "BKE") == 0))
08371 return 1;
08372 return 0;
08373 }
08374
08375
08386 int
08387 pdv_is_atmel(PdvDev * pdv_p)
08388 {
08389 Dependent *dd_p = pdv_p->dd_p;
08390
08391 if ((strncasecmp(dd_p->camera_class, "Atmel", 5) == 0)
08392 || (strncmp(dd_p->serial_exposure, "I=", 2) == 0))
08393 return 1;
08394 return 0;
08395 }
08396
08404 int
08405 pdv_is_hamamatsu(PdvDev * pdv_p)
08406 {
08407 Dependent *dd_p = pdv_p->dd_p;
08408
08409 if ((strncasecmp(dd_p->camera_class, "Hamamatsu", 9) == 0)
08410 || (strncmp(dd_p->serial_exposure, "SHT", 3) == 0)
08411 || (strncmp(dd_p->serial_exposure, "FBL", 3) == 0)
08412 || (strncmp(dd_p->serial_exposure, "AET", 3) == 0))
08413 return 1;
08414 return 0;
08415 }
08416
08417
08418
08419 int
08420 pdv_update_values_from_camera(PdvDev * pdv_p)
08421 {
08422 int ret = 0;
08423
08424 if (pdv_is_kodak_i(pdv_p))
08425 ret = pdv_update_from_kodak_i(pdv_p);
08426 else if (pdv_is_dvc(pdv_p))
08427 ret = pdv_update_from_dvc(pdv_p);
08428 else if (pdv_is_atmel(pdv_p))
08429 ret = pdv_update_from_atmel(pdv_p);
08430 else if (pdv_is_hamamatsu(pdv_p))
08431 ret = pdv_update_from_hamamatsu(pdv_p);
08432
08433 else
08434 ret = -1;
08435
08436 return ret;
08437 }
08438
08439 static int
08440 pdv_update_from_kodak_i(PdvDev * pdv_p)
08441 {
08442 int i, n, ret = 0;
08443 char *stat[64];
08444 char **stat_p = stat;
08445 Dependent *dd_p = pdv_p->dd_p;
08446
08447 for (i = 0; i < 64; i++)
08448 {
08449 *stat_p = (char *) malloc(64 * sizeof(char));
08450 **stat_p = '\0';
08451 ++stat_p;
08452 }
08453
08454 if ((n = pdv_query_serial(pdv_p, "STS?", stat)) < 1)
08455 ret = -1;
08456 else
08457 {
08458 update_int_from_serial(stat, n, "BKE", &dd_p->level);
08459 update_int_from_serial(stat, n, "GAE", &dd_p->gain);
08460 update_int_from_serial(stat, n, "DGN", &dd_p->gain);
08461 update_int_from_serial(stat, n, "EXE", &dd_p->shutter_speed);
08462 update_int_from_serial(stat, n, "BNS", &dd_p->binx);
08463 update_int_from_serial(stat, n, "BNS", &dd_p->biny);
08464 }
08465
08466 for (i = 0; i < 64; i++)
08467 free(stat[i]);
08468
08469 return ret;
08470 }
08471
08472 static int
08473 pdv_update_from_hamamatsu(PdvDev * pdv_p)
08474 {
08475 int i, n, ret = 0;
08476 char *stat[64];
08477 char **stat_p = stat;
08478 Dependent *dd_p = pdv_p->dd_p;
08479
08480 for (i = 0; i < 64; i++)
08481 {
08482 *stat_p = (char *) malloc(64 * sizeof(char));
08483 **stat_p = '\0';
08484 ++stat_p;
08485 }
08486
08487 if ((n = pdv_query_serial(pdv_p, "?CEG", stat)) < 1)
08488 ret = -1;
08489 else
08490 update_int_from_serial(stat, n, "CEG", &dd_p->gain);
08491
08492 if ((n = pdv_query_serial(pdv_p, "?CEO", stat)) < 1)
08493 ret = -1;
08494 else
08495 update_int_from_serial(stat, n, "CEO", &dd_p->level);
08496
08497 if ((n = pdv_query_serial(pdv_p, "?SHT", stat)) < 1)
08498 ret = -1;
08499 else
08500 update_int_from_serial(stat, n, "SHT", &dd_p->shutter_speed);
08501
08502 for (i = 0; i < 64; i++)
08503 free(stat[i]);
08504
08505 return ret;
08506 }
08507
08508
08509 static int
08510 pdv_update_from_atmel(PdvDev * pdv_p)
08511 {
08512 int i, n, ret = 0;
08513 int tmpval;
08514 char *stat[64];
08515 char **stat_p = stat;
08516 Dependent *dd_p = pdv_p->dd_p;
08517
08518 for (i = 0; i < 64; i++)
08519 {
08520 *stat_p = (char *) malloc(64 * sizeof(char));
08521 **stat_p = '\0';
08522 ++stat_p;
08523 }
08524
08525 if ((n = pdv_query_serial(pdv_p, "!=3", stat)) < 1)
08526 ret = -1;
08527 else
08528 {
08529 update_int_from_serial(stat, n, "G", &dd_p->gain);
08530 update_int_from_serial(stat, n, "I", &dd_p->shutter_speed);
08531 if (update_int_from_serial(stat, n, "B", &tmpval) == 0)
08532 dd_p->binx = dd_p->biny = tmpval + 1;
08533 }
08534
08535 for (i = 0; i < 64; i++)
08536 free(stat[i]);
08537
08538 return ret;
08539 }
08540
08547 int
08548 pdv_query_serial(PdvDev * pdv_p, char *cmd, char **resp)
08549 {
08550
08551 char *buf_p;
08552 char buf[2048];
08553 int length;
08554 int ret;
08555 int i, j, l;
08556 int nfound = 0;
08557
08558 {
08559 char *tmp_storage;
08560 if ((tmp_storage = (char *)malloc(strlen(cmd)+1)) == NULL)
08561 return 0;
08562 sprintf(tmp_storage, "%s\r", cmd);
08563 edt_msg(DBG2, "pdv_query_serial: writing <%s>\n", cmd);
08564 pdv_serial_command(pdv_p, tmp_storage);
08565 free(tmp_storage);
08566 }
08567
08568
08569
08570
08571 pdv_serial_wait(pdv_p, pdv_p->dd_p->serial_timeout, 64);
08572
08573
08574
08575
08576
08577 buf_p = buf;
08578 length = 0;
08579 do
08580 {
08581 ret = pdv_serial_read(pdv_p, buf_p, 2048 - length);
08582 edt_msg(DBG2, "read returned %d\n", ret);
08583
08584 if (ret != 0)
08585 {
08586 buf_p[ret + 1] = 0;
08587 buf_p += ret;
08588 length += ret;
08589 }
08590 if (pdv_p->devid == PDVFOI_ID)
08591 pdv_serial_wait(pdv_p, 500, 0);
08592 else
08593