00001
00002
00003
00277 #include "edtinc.h"
00278
00279 #include <math.h>
00280
00281 #include <assert.h>
00282
00283 #ifdef _NT_
00284 #define strncasecmp strnicmp
00285 #endif
00286
00287
00288 #define PDVWARN PDVLIB_MSG_WARNING
00289 #define PDVFATAL PDVLIB_MSG_FATAL
00290 #define DBG1 PDVLIB_MSG_INFO_1
00291 #define DBG2 PDVLIB_MSG_INFO_2
00292
00293 int Pdv_debug = 0;
00294 int Smd_type = NOT_SET;
00295 int Smd_rate = NOT_SET;
00296
00297
00298
00299
00300
00301
00302 #define PDV_DEPENDENT(pdv_p) ((pdv_p)->dd_p)
00303
00304 static void
00305 debug_print_serial_command(char *cmd);
00306 static void
00307 send_serial_binary_cmd(PdvDev * pdv_p, char *hexstr, int value);
00308
00309 static void pdv_trigger_specinst(PdvDev * pdv_p);
00310 static void pdv_posttrigger_specinst(PdvDev * pdv_p);
00311 static int pdv_specinst_setparam(PdvDev * pdv_p, char cmd, u_long offset, u_long value);
00312
00316 static int pdv_set_exposure_specinst(PdvDev * pdv_p, int value);
00317 static int pdv_set_gain_specinst(PdvDev * pdv_p, int value);
00318 static int pdv_set_exposure_adimec(PdvDev * pdv_p, int value);
00319 static int pdv_set_exposure_su320(PdvDev * pdv_p, int value);
00320 static int pdv_set_gain_adimec(PdvDev * pdv_p, int value);
00321 static int pdv_set_blacklevel_adimec(PdvDev * pdv_p, int value);
00322 static int pdv_set_exposure_smd(PdvDev * pdv_p, int value);
00323 static int pdv_set_exposure_timc1001pf(PdvDev * pdv_p, int value);
00324 static int pdv_set_exposure_ptm6710_1020(PdvDev * pdv_p, int value);
00325 static int pdv_set_gain_ptm6710_1020(PdvDev * pdv_p, int value);
00326 static int pdv_set_binning_generic(PdvDev * pdv_p, int value);
00327 static int pdv_set_gain_smd(PdvDev * pdv_p, int value);
00328 static int pdv_set_blacklevel_smd(PdvDev * pdv_p, int value);
00329 static int pdv_set_gain_hc8484(PdvDev * pdv_p, int value);
00332 static int pdv_specinst_serial_triggered(PdvDev * pdv_p);
00333 static void CheckSumMessage(unsigned char *msg);
00334 int pdv_auto_set_timeout(PdvDev * pdv_p);
00335 static int isafloat(char *str);
00336 static int isdigits(char *str);
00337 static int isxdigits(char *str);
00338 static int update_int_from_serial(char **stat, int nstat, char *str, int *value);
00339 static int update_string_from_serial(char **stat, int nstat, char *str, char *value, int maxlen);
00340 static void update_hex_from_serial(char **stat, int nstat, char *str, int *value);
00341 static void update_2dig_from_serial(char **stat, int nstat, char *str, int *val1, int *val2);
00342 int edt_get_rtimeout(PdvDev * pdv_p);
00343 static int pdv_update_from_kodak_i(PdvDev * pdv_p);
00344
00345 static int pdv_update_from_atmel(PdvDev * pdv_p);
00346 static int pdv_update_from_hamamatsu(PdvDev * pdv_p);
00347 static int pdv_set_mode_atmel(PdvDev * pdv_p, char *mode);
00348 static int pdv_set_mode_hamamatsu(PdvDev * pdv_p, char *mode);
00349
00350 static int pdv_set_exposure_timc1001pf(PdvDev * pdv_p, int value);
00351
00352 int pdv_query_serial(PdvDev * pdv_p, char *cmd, char **resp);
00353
00354
00355
00356 void pdv_dmy_data(void *buf, int width, int height, int depth);
00357 void pdv_alloc_tmpbuf(PdvDev * pdv_p);
00358 extern pdv_process_inplace(PdvDev *pdv_p);
00359 int pdv_update_size(PdvDev * pdv_p);
00360
00361 static char *hex_to_str(char *resp, int n);
00362
00363 #ifdef DOXYGEN_SHOW_UNDOC
00364
00369 #endif
00370
00430 PdvDev *
00431 pdv_open_channel(char *dev_name, int unit, int channel)
00432 {
00433 PdvDev *pdv_p;
00434 char tmpname[64];
00435 Dependent *dd_p;
00436 static char *debug_env = NULL;
00437 int level;
00438
00439 if ((debug_env == NULL)
00440 && ((debug_env = (char *) getenv("PDVDEBUG")) != NULL)
00441 && *debug_env != '0')
00442 {
00443 Pdv_debug = atoi(debug_env);
00444 level = edt_msg_default_level();
00445 if (Pdv_debug > 0)
00446 {
00447 level |= DBG1;
00448 level |= DBG2;
00449 }
00450 edt_msg_set_level(edt_msg_default_handle(), level);
00451
00452 edt_msg(DBG2, "environment DEBUG set to %d: enabling debug in pdvlib\n", Pdv_debug);
00453 }
00454
00455 edt_msg(DBG2, "pdv_open_channel('%s', %d, %d)\n", dev_name ? dev_name : "NULL",
00456 unit, channel);
00457
00458 if (dev_name == NULL)
00459 strcpy(tmpname, EDT_INTERFACE);
00460 else
00461 strcpy(tmpname, dev_name);
00462 if ((pdv_p = edt_open_channel(tmpname, unit, channel)) == NULL)
00463 return NULL;
00464
00465
00466 if (pdv_p->devid == PDVFOI_ID)
00467 {
00468 #ifdef _FOI_SUPPORTED
00469 edt_check_foi(pdv_p);
00470 #else
00471 edt_msg(PDVFATAL, "pdv_open_channel: FOI not supported after v4.1.5.9\n");
00472 return NULL;
00473 #endif
00474 }
00475 else
00476 {
00477 pdv_p->foi_unit = channel;
00478 }
00479
00480
00481
00482
00483
00484 if (sizeof(Dependent) > EDT_DEPSIZE)
00485 {
00486 edt_msg(PDVWARN, "pdv_open_channel: sizeof Dependent %d > DEPSIZE %d\n",
00487 sizeof(Dependent), EDT_DEPSIZE);
00488 }
00489 if ((dd_p = (Dependent *) malloc(EDT_DEPSIZE)) == NULL)
00490 {
00491 pdv_close(pdv_p);
00492 return NULL;
00493 }
00494 pdv_p->dd_p = dd_p;
00495
00496 if (edt_get_dependent(pdv_p, dd_p) < 0)
00497 {
00498 free(dd_p);
00499 dd_p = 0;
00500 pdv_p->dd_p = NULL;
00501 pdv_close(pdv_p);
00502 return NULL;
00503 }
00504
00505 if (pdv_p->devid == PDVFOI_ID)
00506 {
00507 pdv_p->foi_unit = edt_get_foiunit(pdv_p);
00508 }
00509
00510 pdv_p->tmpbufsize = 0;
00511
00512 pdv_p->dd_p->xilinx_rev = 2;
00513
00514 if (pdv_p->dd_p->swinterlace ||
00515 pdv_p->dd_p->interlace_module[0])
00516 pdv_setup_postproc(pdv_p, pdv_p->dd_p, NULL);
00517
00518 return pdv_p;
00519
00520 }
00521
00522
00523
00550 PdvDev *
00551 pdv_open(char *dev_name, int unit)
00552 {
00553 return pdv_open_channel(dev_name, unit, 0);
00554 }
00555
00556
00563 void
00564 pdv_setup_dma(PdvDev * pdv_p)
00565
00566 {
00567
00568
00569
00570 edt_set_continuous(pdv_p, 0);
00571 pdv_p->dd_p->started_continuous = 0;
00572
00573 edt_startdma_reg(pdv_p, PDV_CMD, PDV_ENABLE_GRAB);
00574 }
00575
00576
00577
00586 int
00587 pdv_close(PdvDev * pdv_p)
00588 {
00589 edt_msg(DBG2, "pdv_close()\n");
00590
00591 if (!pdv_p)
00592 return -1;
00593 if (pdv_p->dd_p)
00594 {
00595 free(pdv_p->dd_p);
00596 pdv_p->dd_p = 0;
00597 }
00598
00599 return edt_close(pdv_p);
00600 }
00601
00611 int
00612 pdv_bytes_per_line(int width, int depth)
00613
00614 {
00615 if (depth == 1)
00616 return width >> 3;
00617 else if (depth == 2)
00618 return width >> 2;
00619 else if (depth == 4)
00620 return width >> 1;
00621 else
00622 return width * bits2bytes(depth);
00623 }
00624
00631 int
00632 pdv_get_bytes_per_image(PdvDev *pdv_p)
00633
00634 {
00635 return pdv_p->dd_p->height *
00636 pdv_bytes_per_line(pdv_p->dd_p->width, pdv_p->dd_p->depth);
00637 }
00638
00639
00654 int
00655 pdv_get_width(PdvDev * pdv_p)
00656 {
00657 if (!pdv_p->dd_p)
00658 return (0);
00659
00660 edt_msg(DBG2, "pdv_get_width() %d\n", pdv_p->dd_p->width);
00661
00662
00663 return pdv_p->dd_p->width;
00664 }
00665
00674 int
00675 pdv_get_pitch(PdvDev * pdv_p)
00676 {
00677 int pitch;
00678
00679 if (!pdv_p->dd_p)
00680 return (0);
00681
00682 pitch = pdv_bytes_per_line(pdv_p->dd_p->width,
00683 pdv_p->dd_p->depth);
00684
00685 edt_msg(DBG2, "pdv_get_pitch() %d\n", pitch);
00686
00687
00688 return pitch ;
00689 }
00690
00711 int
00712 pdv_get_cam_width(PdvDev * pdv_p)
00713 {
00714 edt_msg(DBG2, "pdv_get_cam_width() %d\n", pdv_p->dd_p->cam_width);
00715
00716 return pdv_p->dd_p->cam_width;
00717 }
00718
00730 pdv_get_dmasize(PdvDev * pdv_p)
00731
00732 {
00733
00734 Dependent *dd_p = PDV_DEPENDENT(pdv_p);
00735
00736 int size;
00737
00738
00739 if (dd_p->swinterlace == PDV_INV_RT_INTLV_24_12)
00740 size = dd_p->width * dd_p->height * 3 / 2;
00741 else if (dd_p->depth > dd_p->extdepth)
00742 size = dd_p->height *
00743 pdv_bytes_per_line(pdv_p->dd_p->width, pdv_p->dd_p->extdepth);
00744 else
00745 size = dd_p->height *
00746 pdv_bytes_per_line(pdv_p->dd_p->width, pdv_p->dd_p->depth);
00747
00748
00749 return size;
00750 }
00751
00768 int
00769 pdv_setsize(PdvDev * pdv_p, int width, int height)
00770 {
00771 Dependent *dd_p = pdv_p->dd_p;
00772
00773 edt_msg(DBG2, "pdv_setsize(%d, %d)\n", width, height);
00774
00775 dd_p->width = width;
00776 dd_p->height = height;
00777
00778 return pdv_update_size(pdv_p);
00779
00780 }
00781
00801 int
00802 pdv_set_cam_width(PdvDev * pdv_p, int value)
00803 {
00804 int ret;
00805 Dependent *dd_p = pdv_p->dd_p;
00806
00807 edt_msg(DBG2, "pdv_set_cam_width(%d)\n", value);
00808
00809 dd_p->cam_width = value;
00810
00811 ret = edt_set_dependent(pdv_p, dd_p);
00812
00813 return ret;
00814 }
00815
00826 int
00827 pdv_get_imagesize(PdvDev * pdv_p)
00828 {
00829
00830 edt_msg(DBG2, "pdv_get_imagesize() %d\n", pdv_p->dd_p->imagesize);
00831
00832 return pdv_p->dd_p->imagesize;
00833 }
00834
00843 int
00844 pdv_get_allocated_size(PdvDev * pdv_p)
00845 {
00846 Dependent *dd_p = pdv_p->dd_p;
00847 int total = 0;
00848
00849 int width = dd_p->width;
00850 int height = dd_p->height;
00851
00852
00853 dd_p->imagesize = dd_p->width * dd_p->height * bits2bytes(dd_p->depth);
00854
00855 total = pdv_p->dd_p->imagesize + pdv_p->dd_p->slop;
00856
00857 if (pdv_p->dd_p->header_size &&
00858 (pdv_p->dd_p->header_position != PDV_HEADER_WITHIN))
00859 total += pdv_p->dd_p->header_size;
00860
00861 #ifdef _NT_
00862
00863 if (total % PAGESIZE)
00864 {
00865 total = ((total / PAGESIZE) + 1) * PAGESIZE;
00866 }
00867 #endif
00868
00869 edt_msg(DBG2, "pdv_get_allocated_size() %d\n", total);
00870
00871 return total;
00872
00873 }
00874
00894 int
00895 pdv_set_timeout(PdvDev * pdv_p, int value)
00896 {
00897 Dependent *dd_p = pdv_p->dd_p;
00898
00899 if (value < 0)
00900 {
00901 edt_msg(DBG2, "pdv_set_timeout(%d) (< 0, going back to auto)\n", value);
00902
00903 pdv_p->dd_p->user_timeout_set = 0;
00904 edt_set_dependent(pdv_p, dd_p);
00905 return pdv_auto_set_timeout(pdv_p);
00906 }
00907 else
00908 {
00909 edt_msg(DBG2, "pdv_set_timeout(%d) (user set, overriding auto)\n", value);
00910
00911 pdv_p->dd_p->user_timeout_set = 1;
00912 pdv_p->dd_p->user_timeout = value;
00913 edt_set_dependent(pdv_p, dd_p);
00914 return edt_set_rtimeout(pdv_p, value);
00915 }
00916 }
00917
00932 int
00933 pdv_get_timeout(PdvDev * pdv_p)
00934 {
00935
00936 edt_msg(DBG2, "pdv_get_timeout()\n");
00937
00938 return edt_get_rtimeout(pdv_p);
00939 }
00940
00953 int
00954 pdv_picture_timeout(PdvDev * pdv_p, int value)
00955 {
00956 return pdv_set_timeout(pdv_p, value);
00957 }
00958
00960
00961
01000 int
01001 pdv_timeouts(PdvDev * pdv_p)
01002 {
01003 int ret;
01004
01005 ret = edt_timeouts(pdv_p);
01006 edt_msg(DBG2, "pdv_timeouts(%d)\n", ret);
01007 return ret;
01008 }
01009
01010
01023 int
01024 pdv_timeout_cleanup(PdvDev * pdv_p)
01025 {
01026 int curdone, curtodo;
01027
01028 curdone = edt_done_count(pdv_p);
01029 curtodo = edt_get_todo(pdv_p);
01030 pdv_stop_continuous(pdv_p);
01031 edt_msleep(500);
01032 edt_set_buffer(pdv_p, curdone);
01033 edt_reg_write(pdv_p, PDV_CMD, PDV_RESET_INTFC);
01034 pdv_setup_continuous(pdv_p);
01035 return curtodo - curdone;
01036 }
01037
01039
01040
01058 int
01059 pdv_get_height(PdvDev * pdv_p)
01060 {
01061 if (!pdv_p->dd_p)
01062 return (0);
01063
01064 edt_msg(DBG2, "pdv_get_height() %d\n", pdv_p->dd_p->height);
01065
01066 return pdv_p->dd_p->height;
01067 }
01068
01088 int
01089 pdv_get_cam_height(PdvDev * pdv_p)
01090 {
01091
01092 edt_msg(DBG2, "pdv_get_cam_height() %d\n", pdv_p->dd_p->cam_height);
01093
01094 return pdv_p->dd_p->cam_height;
01095 }
01096
01097
01114 int
01115 pdv_get_frame_height(PdvDev * pdv_p)
01116 {
01117
01118 edt_msg(DBG2, "pdv_get_cam_height() %d\n", pdv_p->dd_p->cam_height);
01119
01120 return pdv_p->dd_p->frame_height;
01121 }
01122
01124
01134 int
01135 pdv_update_size(PdvDev *pdv_p)
01136
01137 {
01138 Dependent *dd_p = pdv_p->dd_p;
01139 int ret;
01140
01141 edt_msg(DBG2, "update_size\n");
01142
01143 dd_p->imagesize = dd_p->height * pdv_get_pitch(pdv_p);
01144
01145 ret = edt_set_dependent(pdv_p, dd_p);
01146
01147 if (pdv_p->ring_buffer_numbufs > 0)
01148 pdv_multibuf(pdv_p, pdv_p->ring_buffer_numbufs);
01149
01150 if (dd_p->swinterlace)
01151 {
01152 pdv_alloc_tmpbuf(pdv_p);
01153 }
01154
01155 return ret;
01156 }
01157
01169 int
01170 pdv_set_width(PdvDev * pdv_p, int value)
01171 {
01172 Dependent *dd_p = pdv_p->dd_p;
01173
01174 edt_msg(DBG2, "pdv_set_width(%d)\n", value);
01175
01176 dd_p->width = value;
01177
01178 return pdv_update_size(pdv_p);
01179
01180 }
01181
01190 int
01191 pdv_set_height(PdvDev * pdv_p, int value)
01192 {
01193 Dependent *dd_p = pdv_p->dd_p;
01194
01195 edt_msg(DBG2, "pdv_set_height(%d)\n", value);
01196
01197 dd_p->height = value;
01198
01199 return pdv_update_size(pdv_p);
01200
01201 }
01202
01220 int
01221 pdv_set_cam_height(PdvDev * pdv_p, int value)
01222 {
01223 int ret;
01224 Dependent *dd_p = pdv_p->dd_p;
01225
01226 edt_msg(DBG2, "pdv_set_cam_height(%d)\n", value);
01227
01228 dd_p->cam_height = value;
01229
01230 ret = edt_set_dependent(pdv_p, dd_p);
01231 return ret;
01232 }
01233
01234
01243 int
01244 pdv_get_depth(PdvDev * pdv_p)
01245 {
01246 if (!pdv_p->dd_p)
01247 return (0);
01248
01249 edt_msg(DBG2, "pdv_get_depth() %d\n", pdv_p->dd_p->depth);
01250
01251 return pdv_p->dd_p->depth;
01252 }
01253
01271 int
01272 pdv_get_extdepth(PdvDev * pdv_p)
01273 {
01274
01275 edt_msg(DBG2, "pdv_get_extdepth() %d\n", pdv_p->dd_p->extdepth);
01276
01277 return pdv_p->dd_p->extdepth;
01278 }
01279
01307 int
01308 pdv_set_depth(PdvDev * pdv_p, int value)
01309 {
01310 Dependent *dd_p = pdv_p->dd_p;
01311
01312 dd_p->depth = value;
01313
01314
01315
01316
01317
01318 if (pdv_is_cameralink(pdv_p))
01319 {
01320 int reg;
01321
01322 if ((value >= 8) && (value <= 16))
01323 reg = value-1;
01324 else if (value == 24 || value == 32)
01325 reg = 0x7;
01326 else if (value == 30)
01327 reg = 0x9;
01328 else reg = 0;
01329
01330 if (reg)
01331 {
01332 if (dd_p->dual_channel)
01333 reg |= 0x10;
01334 dd_p->dual_channel = reg;
01335 edt_reg_write(pdv_p, PDV_CL_DATA_PATH, dd_p->cl_data_path);
01336 }
01337 }
01338
01339 return pdv_update_size(pdv_p);
01340
01341 }
01342
01369 int
01370 pdv_set_extdepth(PdvDev * pdv_p, int value)
01371 {
01372 int ret;
01373 Dependent *dd_p = pdv_p->dd_p;
01374
01375 dd_p->extdepth = value;
01376
01377 edt_msg(DBG2, "pdv_set_extdepth(%d)\n", value);
01378
01379 ret = edt_set_dependent(pdv_p, dd_p);
01380
01381 return ret;
01382 }
01383
01395 int
01396 pdv_set_cameratype(PdvDev * pdv_p, char *model)
01397 {
01398 Dependent *dd_p = pdv_p->dd_p;
01399
01400 edt_msg(DBG2, "pdv_set_cameratype(%s)\n", model);
01401
01402 strcpy(dd_p->cameratype, model);
01403
01404 return edt_set_dependent(pdv_p, dd_p);
01405 }
01406
01407
01424 char *
01425 pdv_get_cameratype(PdvDev * pdv_p)
01426 {
01427 edt_msg(DBG2, "pdv_get_cameratype()\n");
01428
01429 return pdv_p->dd_p->cameratype;
01430 }
01431
01432
01449 char *
01450 pdv_get_camera_class(PdvDev * pdv_p)
01451 {
01452 edt_msg(DBG2, "pdv_get_camera_class()\n");
01453
01454 return pdv_p->dd_p->camera_class;
01455 }
01456
01457
01467 char *
01468 pdv_get_camera_model(PdvDev * pdv_p)
01469 {
01470 edt_msg(DBG2, "pdv_get_camera_model()\n");
01471
01472 return pdv_p->dd_p->camera_model;
01473 }
01474
01485 char *
01486 pdv_get_camera_info(PdvDev * pdv_p)
01487 {
01488 edt_msg(DBG2, "pdv_get_camera_info()\n");
01489
01490 return pdv_p->dd_p->camera_info;
01491 }
01492
01504 char *
01505 pdv_camera_type(PdvDev * pdv_p)
01506 {
01507 edt_msg(DBG2, "pdv_camera_type()\n");
01508
01509 return pdv_p->dd_p->cameratype;
01510 }
01511
01513
01514 static int
01515 smd_read_reg(PdvDev * pdv_p, int reg)
01516 {
01517 u_char buf[128];
01518 int ret;
01519
01520
01521 pdv_serial_read(pdv_p, (char *) buf, 64);
01522
01523
01524 buf[0] = (u_char) reg;
01525 pdv_serial_binary_command(pdv_p, (char *) buf, 1);
01526
01527 ret = pdv_serial_wait(pdv_p, pdv_p->dd_p->serial_timeout, pdv_p->dd_p->serial_respcnt);
01528 if (ret == 0)
01529 return -1;
01530 pdv_serial_read(pdv_p, (char *) buf, ret);
01531 return (int) buf[0];
01532 }
01533
01557 int
01558 pdv_set_exposure(PdvDev * pdv_p, int value)
01559 {
01560 int ret = -1;
01561 Dependent *dd_p = pdv_p->dd_p;
01562 char cmdstr[64];
01563 int n;
01564
01565 edt_msg(DBG2, "pdv_set_exposure(%d)\n", value);
01566
01567 dd_p->shutter_speed = value;
01568
01569 if (edt_set_dependent(pdv_p, dd_p) < 0)
01570 {
01571 edt_msg(DBG2, "pdv_set_exposure ret %d\n", ret);
01572 return -1;
01573 }
01574
01575 pdv_auto_set_timeout(pdv_p);
01576
01577 if ((dd_p->camera_shutter_timing == AIA_MCL)
01578 && (dd_p->mode_cntl_norm & 0xf0)
01579 && (!dd_p->trig_pulse))
01580 {
01581 ret = pdv_set_exposure_mcl(pdv_p, value);
01582 }
01583 else if (dd_p->camera_shutter_timing == AIA_MCL_100US)
01584 {
01585
01586 ret = pdv_set_exposure_mcl(pdv_p, value);
01587 }
01588 else if ((strlen(dd_p->serial_exposure) > 0)
01589 && (dd_p->serial_format == SERIAL_BINARY))
01590 {
01591 send_serial_binary_cmd(pdv_p, dd_p->serial_exposure, value);
01592 }
01593 else if ((strlen(dd_p->serial_exposure) > 0)
01594 && ((dd_p->serial_format == SERIAL_ASCII)
01595 || (dd_p->serial_format == SERIAL_ASCII_HEX)
01596 || (dd_p->serial_format == SERIAL_PULNIX_1010)))
01597 {
01598
01599
01600
01601 if (dd_p->camera_shutter_timing == HAM_4880_SER)
01602 {
01603 int minutes;
01604 int seconds;
01605 int useconds;
01606
01607 minutes = value / 60000;
01608 value -= minutes * 60000;
01609
01610 seconds = value / 1000;
01611 value -= seconds * 1000;
01612
01613 useconds = value;
01614
01615 sprintf(cmdstr, "%s %04d:%02d.%03d",
01616 dd_p->serial_exposure, minutes, seconds, useconds);
01617 }
01618 else
01619 {
01620 if (dd_p->serial_format == SERIAL_ASCII_HEX)
01621 sprintf(cmdstr, "%s %02x", dd_p->serial_exposure, value);
01622
01623 else if (dd_p->serial_format == SERIAL_PULNIX_1010)
01624 sprintf(cmdstr, "%s%d", dd_p->serial_exposure, value);
01625
01626 else if (dd_p->serial_exposure[0] == ':')
01627 {
01628
01629
01630
01631
01632 sprintf(cmdstr, "%s%x", dd_p->serial_exposure, value);
01633 dd_p->serial_respcnt = 3;
01634 }
01635 else if (dd_p->serial_exposure[1] == '=')
01636 {
01637 sprintf(cmdstr, "%s%d", dd_p->serial_exposure, value);
01638 }
01639 else
01640 {
01641 sprintf(cmdstr, "%s %d", dd_p->serial_exposure, value);
01642 }
01643 }
01644
01645 ret = pdv_serial_command_flagged(pdv_p, cmdstr, SCFLAG_NORESP);
01646 if (pdv_p->devid == PDVFOI_ID)
01647 n = pdv_serial_wait(pdv_p, pdv_p->dd_p->serial_timeout, 0);
01648 else
01649 n = pdv_serial_wait(pdv_p, pdv_p->dd_p->serial_timeout, pdv_p->dd_p->serial_respcnt);
01650 if (*pdv_p->dd_p->serial_response)
01651 if (n)
01652 pdv_serial_read(pdv_p, cmdstr, n);
01653
01654 }
01655 else if ((dd_p->camera_shutter_timing == SPECINST_SERIAL)
01656 || (dd_p->camera_shutter_speed == SPECINST_SERIAL))
01657 {
01658 ret = pdv_set_exposure_specinst(pdv_p, value);
01659 }
01660 else if (dd_p->camera_shutter_timing == SMD_SERIAL)
01661 {
01662 ret = pdv_set_exposure_smd(pdv_p, value);
01663 }
01664 else if (dd_p->camera_shutter_timing == PTM6710_SERIAL)
01665 {
01666 ret = pdv_set_exposure_ptm6710_1020(pdv_p, value);
01667 }
01668 else if (dd_p->camera_shutter_timing == PTM1020_SERIAL)
01669 {
01670 ret = pdv_set_exposure_ptm6710_1020(pdv_p, value);
01671 }
01672 else if (dd_p->camera_shutter_timing == TIMC1001_SERIAL)
01673 {
01674 ret = pdv_set_exposure_timc1001pf(pdv_p, value);
01675 }
01676 else if (dd_p->camera_shutter_timing == ADIMEC_SERIAL)
01677 {
01678 ret = pdv_set_exposure_adimec(pdv_p, value);
01679 }
01680 else if (dd_p->camera_shutter_timing == BASLER202K_SERIAL)
01681 {
01682 ret = pdv_set_exposure_basler202k(pdv_p, value);
01683 }
01684 else if (dd_p->camera_shutter_timing == SU320_SERIAL)
01685 {
01686 ret = pdv_set_exposure_su320(pdv_p, value);
01687 }
01688 else if (dd_p->camera_shutter_timing == HAM_4880_SER)
01689 {
01690
01691 }
01692 else if (dd_p->camera_shutter_timing == AIA_SERIAL)
01693 {
01694
01695 }
01696 else if (dd_p->camera_shutter_timing == AIA_SERIAL_ES40)
01697 {
01698
01699 }
01700 else if (dd_p->camera_shutter_timing == AIA_TRIG)
01701 {
01702 ret = pdv_set_exposure_mcl(pdv_p, value);
01703 }
01704 else if (!dd_p->trig_pulse)
01705 {
01706
01707 ret = pdv_set_exposure_mcl(pdv_p, value);
01708 }
01709
01710 edt_msg(DBG2, "pdv_set_exposure returns %d\n", ret);
01711 return (ret);
01712 }
01713
01730 int
01731 pdv_set_exposure_mcl(PdvDev * pdv_p, int value)
01732 {
01733 u_int data_path;
01734
01735 if (value < 0)
01736 value = 0;
01737 if (value > 25500)
01738 value = 25500;
01739
01740 pdv_p->dd_p->shutter_speed = value;
01741
01742 data_path = pdv_p->dd_p->datapath_reg;
01743 data_path &= ~PDV_MULTIPLIER_MASK;
01744
01745
01746
01747
01748
01749 if (pdv_p->dd_p->camera_shutter_timing == AIA_MCL_100US)
01750 {
01751 edt_msg(DBG2, "pdv_set_exposure_mcl(%d) (100US)\n", value);
01752
01753 if (value < 256)
01754 {
01755 data_path |= PDV_MULTIPLIER_100US;
01756 }
01757 else if (value < 2560)
01758 {
01759
01760 value = (value + 5) / 10;
01761 }
01762 else if (value < 25600)
01763 {
01764 data_path |= PDV_MULTIPLIER_10MS;
01765 value = (value + 50) / 100;
01766 }
01767 else if (value < 256000)
01768 {
01769 data_path |= PDV_MULTIPLIER_100MS;
01770 value = (value + 50) / 1000;
01771 }
01772 }
01773 else
01774 {
01775 edt_msg(DBG2, "pdv_set_exposure_mcl(%d)\n", value);
01776
01777 if (value < 256)
01778 {
01779
01780 }
01781 else if (value < 2560)
01782 {
01783 data_path |= PDV_MULTIPLIER_10MS;
01784 value = (value + 5) / 10;
01785 }
01786 else
01787 {
01788 data_path |= PDV_MULTIPLIER_100MS;
01789 value = (value + 50) / 100;
01790 }
01791 }
01792
01793 pdv_p->dd_p->datapath_reg = data_path;
01794 edt_reg_write(pdv_p, PDV_SHUTTER, value);
01795 edt_reg_write(pdv_p, PDV_DATA_PATH, data_path);
01796
01797 return 0;
01798 }
01799
01803 pdv_set_exposure_smd(PdvDev * pdv_p, int value)
01804 {
01805 int fp = 0;
01806 u_char buf[128];
01807 int n;
01808 int ret = 0;
01809 int smd_reg1, smd_reg3;
01810
01811
01812 if (Smd_type == NOT_SET)
01813 {
01814 Smd_type = smd_read_reg(pdv_p, SMD_READ_CAMTYPE);
01815 if ((Smd_type & 0xfff) == 0xfff)
01816
01817 Smd_type = smd_read_reg(pdv_p, SMD_READ_CAMTYPE);
01818 }
01819
01820
01821 switch (Smd_type)
01822 {
01823 case SMD_TYPE_4M4:
01824
01825
01826
01827
01828
01829 if (value == 0)
01830 buf[1] = 0x7d;
01831 else if (value == 1)
01832 buf[1] = 0x7b;
01833 else if (value == 2)
01834 buf[1] = 0x77;
01835 else if (value <= 4)
01836 buf[1] = 0x6f;
01837 else if (value <= 8)
01838 buf[1] = 0x5f;
01839 else if (value <= 16)
01840 buf[1] = 0x3f;
01841 else
01842 buf[1] = 0x00;
01843
01844
01845
01846 pdv_serial_binary_command(pdv_p, (char *) buf, 2);
01847 break;
01848
01849 case SMD_TYPE_BT25:
01850
01851
01852
01853 buf[0] = (u_char) SMD_BT25_WRITE_R2;
01854 if (Smd_rate == NOT_SET)
01855 {
01856 if ((Smd_rate = smd_read_reg(pdv_p, SMD_BT25_READ_FRAMERATE)) == -1)
01857 edt_msg(PDVWARN, "libpdv: no response from SMD camera rate reg read\n");
01858 if (pdv_p->dd_p->timeout_multiplier < Smd_rate)
01859 {
01860 pdv_p->dd_p->timeout_multiplier = Smd_rate;
01861 pdv_auto_set_timeout(pdv_p);
01862 }
01863 }
01864 buf[1] = (u_char) value;
01865
01866
01867
01868 pdv_serial_binary_command(pdv_p, (char *) buf, 2);
01869
01870
01871 pdv_serial_wait(pdv_p, 100, 64);
01872 break;
01873
01874 case SMD_TYPE_1M30P:
01875 case SMD_TYPE_6M3P:
01876 buf[0] = (u_char) SMD_1M30P_REG_W_INTEG0;
01877 buf[1] = value & 0xff;
01878 pdv_serial_binary_command(pdv_p, (char *) buf, 2);
01879
01880 buf[0] = (u_char) SMD_1M30P_REG_W_INTEG1;
01881 buf[1] = (value & 0xff00) >> 8;
01882 pdv_serial_binary_command(pdv_p, (char *) buf, 2);
01883
01884 buf[0] = (u_char) SMD_1M30P_REG_W_INTEG2;
01885 buf[1] = (value & 0xff0000) >> 16;
01886 pdv_serial_binary_command(pdv_p, (char *) buf, 2);
01887
01888
01889
01890
01891
01892
01893
01894
01895 pdv_p->dd_p->shutter_speed = value / 1000;
01896 pdv_auto_set_timeout(pdv_p);
01897 pdv_p->dd_p->shutter_speed = value;
01898 break;
01899
01900 case SMD_TYPE_1M15P:
01901 if ((smd_reg1 = smd_read_reg(pdv_p, SMD_1M15P_READ_R1)) == -1)
01902 {
01903 edt_msg(PDVWARN, "libpdv: no response from SMD R1 reg read\n");
01904 return -1;
01905 }
01906
01907
01908 buf[0] = (u_char) SMD_1M15P_WRITE_R1;
01909
01910
01911
01912
01913
01914 if (value == 0)
01915 {
01916 buf[1] = (smd_reg1 &~ SMD_1M15P_R1_INTMSK) | 0x0;
01917 fp = 65000;
01918 }
01919 else if (value == 1)
01920 {
01921 buf[1] = (smd_reg1 &~ SMD_1M15P_R1_INTMSK) | 0x7;
01922 fp = 65000;
01923 }
01924 else if (value < 4)
01925 {
01926 buf[1] = (smd_reg1 &~ SMD_1M15P_R1_INTMSK) | 0x6;
01927 fp = 64000;
01928 }
01929 else if (value < 7)
01930 {
01931 buf[1] = (smd_reg1 &~ SMD_1M15P_R1_INTMSK) | 0x5;
01932 fp = 62000;
01933 }
01934 else if (value == 8)
01935 {
01936 buf[1] = (smd_reg1 &~ SMD_1M15P_R1_INTMSK) | 0x4;
01937 fp = 58000;
01938 }
01939 else return -1;
01940
01941 if (smd_reg1 & SMD_1M15P_R1_TRIGMODE)
01942 {
01943
01944 smd_reg3 = smd_read_reg(pdv_p, SMD_1M15P_READ_R3);
01945 if (smd_reg3 & 0x40)
01946 fp /= 2;
01947 pdv_set_frame_period(pdv_p, fp, PDV_FVAL_ADJUST);
01948 }
01949
01950 pdv_p->dd_p->shutter_speed = value;
01951 pdv_serial_binary_command(pdv_p, (char *) buf, 2);
01952 break;
01953
01954 default:
01955 ret = -1;
01956 edt_msg(PDVWARN, "libpdv: unknown SMD camera type %02x\n", Smd_type);
01957 break;
01958 }
01959
01960 if (!ret)
01961 {
01962
01963 n = pdv_serial_wait(pdv_p, 100, 64);
01964 if (n > 127)
01965 n = 127;
01966 if (n)
01967 pdv_serial_read(pdv_p, (char *) buf, n);
01968 }
01969 return ret;
01970 }
01971
01980 static int
01981 pdv_set_exposure_timc1001pf(PdvDev * pdv_p, int value)
01982 {
01983 Dependent *dd_p = pdv_p->dd_p;
01984 u_int mcl = edt_reg_read(pdv_p, PDV_MODE_CNTL) & 0xf1;
01985
01986 if ((value >= 0) && (value <= 7))
01987 {
01988 dd_p->shutter_speed = value;
01989 mcl |= (value << 1);
01990 edt_reg_write(pdv_p, PDV_MODE_CNTL, mcl);
01991 return 0;
01992 }
01993 return -1;
01994 }
01995
01999 pdv_set_exposure_ptm6710_1020(PdvDev * pdv_p, int value)
02000 {
02001 char buf[128];
02002 int ret = 0;
02003
02004 if ((value < 0) || (value > 9))
02005 return -1;
02006
02007 sprintf(buf, ":SM%d", value);
02008 pdv_serial_command_flagged(pdv_p, buf, SCFLAG_NORESP);
02009
02010 return 0;
02011 }
02012
02016 pdv_set_gain_ptm6710_1020(PdvDev * pdv_p, int value)
02017 {
02018 char buf[128];
02019 int ret = 0;
02020
02021 if ((value < 0) || (value > 0xff))
02022 return -1;
02023
02024 sprintf(buf, ":GM%02X", value);
02025 pdv_serial_command_flagged(pdv_p, buf, SCFLAG_NORESP);
02026
02027 return 0;
02028 }
02029
02034 pdv_set_gain_hc8484(PdvDev * pdv_p, int value)
02035 {
02036 char buf[128];
02037 int ret = 0;
02038
02039 if ((value != 0) && (value != 1))
02040 return -1;
02041 sprintf(buf, "CEG %c", value ? 'H' : 'L');
02042 pdv_serial_command_flagged(pdv_p, buf, SCFLAG_NORESP);
02043
02044 return 0;
02045 }
02046
02051 static int
02052 pdv_set_exposure_adimec(PdvDev * pdv_p, int value)
02053 {
02054 Dependent *dd_p = pdv_p->dd_p;
02055 char cmdbuf[32];
02056
02057
02058 sprintf(cmdbuf, "@IT%d", value);
02059 pdv_serial_command(pdv_p, cmdbuf);
02060 return 0;
02061 }
02062
02063 static int
02064 pdv_set_gain_adimec(PdvDev * pdv_p, int value)
02065 {
02066 Dependent *dd_p = pdv_p->dd_p;
02067 char cmdbuf[32];
02068
02069
02070 sprintf(cmdbuf, "@GA%d", value);
02071 pdv_serial_command(pdv_p, cmdbuf);
02072 return 0;
02073 }
02074
02075 static int
02076 pdv_set_blacklevel_adimec(PdvDev * pdv_p, int value)
02077 {
02078 Dependent *dd_p = pdv_p->dd_p;
02079 char cmdbuf[32];
02080
02081
02082 sprintf(cmdbuf, "@BL%d;%d", value, value);
02083 pdv_serial_command(pdv_p, cmdbuf);
02084 return 0;
02085 }
02086
02087
02092 static int
02093 pdv_set_exposure_specinst(PdvDev * pdv_p, int value)
02094 {
02095 edt_msg(DBG2, "pdv_set_exposure_specinst(%d)\n", value);
02096
02097 if (pdv_specinst_setparam(pdv_p, 'G', 8, value) != 0)
02098 {
02099 edt_msg(DBG2, "pdv_set_exposure_specinst() apparently FAILED\n");
02100 return -1;
02101 }
02102 return 0;
02103 }
02104
02109 static int
02110 pdv_set_gain_specinst(PdvDev * pdv_p, int value)
02111 {
02112 edt_msg(DBG2, "pdv_set_gain_specinst(%d)\n", value);
02113
02114 if (pdv_specinst_setparam(pdv_p, 'G', 11, value) != 0)
02115 {
02116 edt_msg(DBG2, "pdv_set_gain_specinst() apparently FAILED\n");
02117 return -1;
02118 }
02119 return 0;
02120 }
02121
02127 static int
02128 pdv_set_exposure_su320(PdvDev * pdv_p, int value)
02129 {
02130 Dependent *dd_p = pdv_p->dd_p;
02131 char cmdbuf[32];
02132 char resp[1024];
02133 int n;
02134
02135 sprintf(cmdbuf, "INT%d", value);
02136 pdv_serial_command(pdv_p, cmdbuf);
02137 pdv_serial_wait(pdv_p, 100, 20);
02138 if ((n = pdv_serial_read(pdv_p, resp, 20)) != 20)
02139 return -1;
02140 return 0;
02141 }
02142
02143
02144 static int
02145 pdv_specinst_setparam(PdvDev * pdv_p, char cmd, u_long offset, u_long value)
02146 {
02147 int ret1, ret2, ret3;
02148 char resp1[32];
02149 char resp2[32];
02150 char buf[32];
02151 u_char cmdbuf[5];
02152 u_char offsetbuf[5];
02153 u_char parambuf[5];
02154 int si_wait = 200;
02155
02156 edt_msg(DBG2, "pdv_specinst_setparam(%c %04x %04x)\n", cmd, offset, value);
02157
02158 dvu_long_to_charbuf(offset, offsetbuf);
02159 dvu_long_to_charbuf(value, parambuf);
02160
02161 cmdbuf[0] = cmd;
02162
02163 pdv_serial_binary_command(pdv_p, (char *) cmdbuf, 1);
02164 pdv_serial_wait_next(pdv_p, si_wait, 31);
02165 ret1 = pdv_serial_read(pdv_p, resp1, 31);
02166
02167 pdv_serial_binary_command(pdv_p, (char *) offsetbuf, 4);
02168 pdv_serial_wait_next(pdv_p, si_wait, 31);
02169 ret2 = pdv_serial_read(pdv_p, buf, 31);
02170
02171 pdv_serial_binary_command(pdv_p, (char *) parambuf, 4);
02172 pdv_serial_wait_next(pdv_p, si_wait, 31);
02173 ret3 = pdv_serial_read(pdv_p, resp2, 31);
02174
02175 if ((ret1 != 1) || (ret3 != 1) || (resp1[0] != 'G') || (resp2[0] != 'Y'))
02176 {
02177 edt_msg(DBG1, "invalid or missing serial response from specinst\n");
02178 return -1;
02179 }
02180 return 0;
02181 }
02182
02196 int
02197 pdv_send_basler_command(PdvDev * pdv_p, int cmd, int rwflag, int len, int data)
02198 {
02199 int i;
02200 u_char frame[32];
02201 u_char rwbit = (rwflag & 0x1) << 7;
02202
02203 frame[0] = cmd;
02204 frame[1] = ((u_char)len & 0xef) | rwbit;
02205 for (i=0; i<len; i++)
02206 frame[i+2] = (data >> (8 * i)) & 0xff;
02207
02208 return pdv_send_basler_frame(pdv_p, frame, len+2);
02209 }
02210
02216 int
02217 pdv_set_exposure_basler202k(PdvDev * pdv_p, int value)
02218 {
02219 Dependent *dd_p = pdv_p->dd_p;
02220 u_char rframe[8];
02221
02222 memset(rframe, 0, 8);
02223 pdv_send_basler_command(pdv_p, 0xa6, 0, 3, value);
02224 pdv_read_basler_frame(pdv_p, rframe, 1);
02225 if (rframe[0] != 0x6)
02226 return -1;
02227 return 0;
02228 }
02229
02230 int
02231 pdv_set_gain_basler202k(PdvDev * pdv_p, int valuea, int valueb)
02232 {
02233 Dependent *dd_p = pdv_p->dd_p;
02234 u_char rframe[8];
02235
02236 memset(rframe, 0, 8);
02237 pdv_send_basler_command(pdv_p, 0x80, 0, 2, valuea);
02238 pdv_read_basler_frame(pdv_p, rframe, 1);
02239 if (rframe[0] != 0x6)
02240 return -1;
02241
02242 memset(rframe, 0, 8);
02243 pdv_send_basler_command(pdv_p, 0x82, 0, 2, valueb);
02244 pdv_read_basler_frame(pdv_p, rframe, 1);
02245 if (rframe[0] != 0x6)
02246 return -1;
02247
02248 return 0;
02249 }
02250
02251 int
02252 pdv_set_offset_basler202k(PdvDev * pdv_p, int valuea, int valueb)
02253 {
02254 Dependent *dd_p = pdv_p->dd_p;
02255 u_char rframe[8];
02256
02257 memset(rframe, 0, 8);
02258 pdv_send_basler_command(pdv_p, 0x81, 0, 2, valuea);
02259 pdv_read_basler_frame(pdv_p, rframe, 1);
02260 if (rframe[0] != 0x6)
02261 return -1;
02262
02263 memset(rframe, 0, 8);
02264 pdv_send_basler_command(pdv_p, 0x83, 0, 2, valueb);
02265 pdv_read_basler_frame(pdv_p, rframe, 1);
02266 if (rframe[0] != 0x6)
02267 return -1;
02268 return 0;
02269 }
02270
02287 int
02288 pdv_set_exposure_duncan_ch(PdvDev * pdv_p, int value, int ch)
02289 {
02290 Dependent *dd_p = pdv_p->dd_p;
02291
02292 u_char msg[8];
02293 u_char rmsg[16];
02294
02295 msg[0] = 0x04;
02296 msg[1] = 0x00;
02297 msg[2] = 0x14;
02298 msg[3] = (u_char)(ch & 0xff);
02299 msg[4] = (u_char)(value & 0xff);
02300 msg[5] = (u_char)((value >> 8) & 0xff);
02301 pdv_send_duncan_frame(pdv_p, msg, 6);
02302 pdv_read_duncan_frame(pdv_p, rmsg);
02303 return 0;
02304 }
02305
02322 int
02323 pdv_set_gain_duncan_ch(PdvDev * pdv_p, int value, int ch)
02324 {
02325 Dependent *dd_p = pdv_p->dd_p;
02326
02327 u_char msg[8];
02328 u_char rmsg[16];
02329
02330 msg[0] = 0x04;
02331 msg[1] = 0x00;
02332 msg[2] = 0x02;
02333 msg[3] = (u_char)(ch & 0xff);
02334 msg[4] = (u_char)(value & 0xff);
02335 msg[5] = (u_char)((value >> 8) & 0xff);
02336 pdv_send_duncan_frame(pdv_p, msg, 6);
02337 pdv_read_duncan_frame(pdv_p, rmsg);
02338 return 0;
02339 }
02340
02341
02346 static void
02347 send_serial_binary_cmd(PdvDev * pdv_p, char *hexstr, int value)
02348 {
02349 int nb;
02350 u_char hbuf[2];
02351 char resp[128];
02352 char bs[16][3];
02353 int ret;
02354
02355 edt_msg(DBG2, "send_serial_binary_cmd(\"%s\", %d)\n", hexstr, value);
02356
02357 nb = sscanf(hexstr, "%s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s",
02358 bs[0], bs[1], bs[2], bs[3], bs[4], bs[5], bs[6], bs[7],
02359 bs[8], bs[9], bs[10], bs[11], bs[12], bs[13], bs[14], bs[15]);
02360
02361 pdv_serial_binary_command(pdv_p, (char *) hbuf, nb);
02362 pdv_serial_wait(pdv_p, 100, 3);
02363
02364 if (*pdv_p->dd_p->serial_response)
02365 ret = pdv_serial_read(pdv_p, resp, 50);
02366
02367 {
02368
02369 edt_msg(DBG2, "serial response <%s> (%d)\n", hex_to_str(resp, ret), ret);
02370 }
02371 }
02372
02399 int
02400 pdv_auto_set_timeout(PdvDev * pdv_p)
02401 {
02402 Dependent *dd_p = pdv_p->dd_p;
02403 int user_timeout = dd_p->user_timeout;
02404 int user_set = dd_p->user_timeout_set;
02405 int tmult = dd_p->timeout_multiplier;
02406 int cur_timeout = edt_get_rtimeout(pdv_p);
02407 int timeout;
02408 int exposure;
02409 int pdiv = 1;
02410 int ret = 0;
02411 int xfersize;
02412
02413
02414
02415
02416 if (tmult < 1)
02417 tmult = 1;
02418
02419
02420 if (dd_p->pclock_speed < 5)
02421 dd_p->pclock_speed = 5;
02422 pdiv = dd_p->pclock_speed / 5;
02423
02424 if (((exposure = dd_p->shutter_speed)) < 500)
02425 exposure = 500;
02426
02427 xfersize = dd_p->cam_width * dd_p->cam_height * bits2bytes(dd_p->depth);
02428 timeout = (((xfersize * tmult) / 4000) / pdiv) + exposure;
02429
02430 edt_msg(DBG2, "pdv_auto_set_timeout(): current %d new %d exposure %d pclock %d pdiv %d mult %d user %d\n",
02431 cur_timeout, timeout, exposure, dd_p->pclock_speed, pdiv,
02432 tmult, user_timeout);
02433
02434
02435
02436
02437
02438 if (timeout < 500)
02439 timeout = 500;
02440
02441 if (user_set)
02442 {
02443 edt_msg(DBG2, " user set to %d - overriding auto\n", user_timeout);
02444
02445 if (timeout > user_timeout && user_timeout != 0)
02446 {
02447 edt_msg(DBG2, " Warning: exposure %d msecs user specified timeout %d msecs\n", dd_p->shutter_speed, user_timeout);
02448 edt_msg(DBG2, " not automatically increased since user specified\n");
02449 }
02450 }
02451 else
02452 {
02453 int targ;
02454
02455 edt_msg(DBG2, " setting picture timeout from %d to %d\n", cur_timeout, timeout);
02456 targ = timeout;
02457 ret = edt_set_rtimeout(pdv_p, targ);
02458 }
02459 return ret;
02460 }
02461
02481 int
02482 pdv_set_gain(PdvDev * pdv_p, int value)
02483 {
02484 int ret;
02485 char cmdstr[64];
02486 Dependent *dd_p = pdv_p->dd_p;
02487
02488 edt_msg(DBG2, "pdv_set_gain(%d)\n", value);
02489
02490 dd_p->gain = value;
02491 ret = edt_set_dependent(pdv_p, dd_p);
02492
02493 if ((strlen(dd_p->serial_gain) > 0)
02494 && (dd_p->serial_format == SERIAL_BINARY))
02495 {
02496 send_serial_binary_cmd(pdv_p, dd_p->serial_gain, value);
02497 }
02498
02499 else if ((strlen(dd_p->serial_gain) > 0)
02500 && ((dd_p->serial_format == SERIAL_ASCII)
02501 || (dd_p->serial_format == SERIAL_ASCII_HEX)))
02502 {
02503 if (dd_p->serial_gain[0] == ':')
02504 {
02505 sprintf(cmdstr, "%s%x", dd_p->serial_gain, value);
02506 dd_p->serial_respcnt = 3;
02507 }
02508 if (dd_p->serial_gain[1] == '=')
02509 {
02510 sprintf(cmdstr, "%s%x", dd_p->serial_gain, value);
02511 }
02512 else if (dd_p->serial_format == SERIAL_ASCII_HEX)
02513 {
02514 sprintf(cmdstr, "%s %02x", dd_p->serial_gain, value);
02515 }
02516 else
02517 sprintf(cmdstr, "%s %d", dd_p->serial_gain, value);
02518 ret = pdv_serial_command_flagged(pdv_p, cmdstr, SCFLAG_NORESP);
02519
02520
02521
02522
02523 pdv_serial_wait(pdv_p, pdv_p->dd_p->serial_timeout, 64);
02524 if (*pdv_p->dd_p->serial_response)
02525 pdv_serial_read(pdv_p, cmdstr, 63);
02526 }
02527
02528 else if ((strncasecmp(dd_p->camera_class, "Hamamatsu", 9) == 0)
02529 && ((strncasecmp(dd_p->camera_model, "C8484", 5) == 0)
02530 || (strncasecmp(dd_p->camera_model, "8484", 4) == 0)))
02531 {
02532 ret = pdv_set_gain_hc8484(pdv_p, value);
02533 }
02534
02535 else if ((dd_p->camera_shutter_timing == SPECINST_SERIAL)
02536 || (dd_p->camera_shutter_speed == SPECINST_SERIAL))
02537 {
02538 ret = pdv_set_gain_specinst(pdv_p, value);
02539 }
02540 else if (dd_p->set_gain == SMD_SERIAL)
02541 {
02542 ret = pdv_set_gain_smd(pdv_p, value);
02543 }
02544 else if ((strncasecmp(dd_p->camera_class, "Adimec", 6) == 0))
02545 {
02546 ret = pdv_set_gain_adimec(pdv_p, value);
02547 }
02548
02549 else if ((strncasecmp(dd_p->camera_class, "PULNiX", 6) == 0)
02550 && ((strncasecmp(dd_p->camera_model, "TM-6710", 7) == 0)
02551 || (strncasecmp(dd_p->camera_model, "TM-1020", 7) == 0)))
02552 {
02553 ret = pdv_set_gain_ptm6710_1020(pdv_p, value);
02554 }
02555
02556 else if ((dd_p->set_gain == AIA_MC4)
02557 && (dd_p->xilinx_rev >= 1 && dd_p->xilinx_rev <= 32))
02558 {
02559 u_int util2 = edt_reg_read(pdv_p, PDV_UTIL2);
02560 u_int mcl = edt_reg_read(pdv_p, PDV_MODE_CNTL);
02561
02562 edt_reg_write(pdv_p, PDV_UTIL2, util2 & ~PDV_MC4);
02563 edt_reg_write(pdv_p, PDV_MODE_CNTL, dd_p->gain);
02564 edt_reg_write(pdv_p, PDV_UTIL2, util2 | PDV_MC4);
02565 edt_reg_write(pdv_p, PDV_MODE_CNTL, mcl);
02566 }
02567
02568 edt_msg(DBG2, "pdv_set_gain returning %d\n", ret);
02569 return (ret);
02570 }
02571
02575 pdv_set_gain_smd(PdvDev * pdv_p, int value)
02576 {
02577 char buf[128];
02578 char smd_config;
02579 int smd_reg1;
02580 int ret = 0;
02581
02582 if (Smd_type == NOT_SET)
02583 {
02584 Smd_type = smd_read_reg(pdv_p, SMD_READ_CAMTYPE);
02585 if ((Smd_type & 0xfff) == 0xfff)
02586
02587 Smd_type = smd_read_reg(pdv_p, SMD_READ_CAMTYPE);
02588 }
02589
02590 switch (Smd_type)
02591 {
02592 case SMD_TYPE_4M4:
02593 buf[0] = (char) SMD_4M4_READ_R1;
02594 pdv_serial_binary_command(pdv_p, buf, 1);
02595 pdv_serial_wait(pdv_p, pdv_p->dd_p->serial_timeout,
02596 pdv_p->dd_p->serial_respcnt);
02597 if (pdv_serial_read(pdv_p, buf, 63) == 1)
02598 {
02599 smd_config = buf[0];
02600
02601 buf[0] = (char) SMD_4M4_WRITE_R1;
02602 pdv_serial_binary_command(pdv_p, buf, 1);
02603
02604 if (value == 0)
02605 smd_config &= ~SMD_4M4_R1_GAIN;
02606 else
02607 smd_config |= SMD_4M4_R1_GAIN;
02608 buf[0] = smd_config;
02609 pdv_serial_binary_command(pdv_p, buf, 1);
02610
02611 pdv_serial_wait(pdv_p, 100, 64);
02612 }
02613 else
02614 ret = -1;
02615 break;
02616
02617 case SMD_TYPE_1M30P:
02618 buf[0] = (u_char) SMD_1M30P_REG_W_LS_GAIN;
02619 buf[1] = value & 0xff;
02620 pdv_serial_binary_command(pdv_p, (char *) buf, 2);
02621
02622 buf[0] = (u_char) SMD_1M30P_REG_W_MS_GAIN;
02623 buf[1] = (value & 0xff00) >> 8;
02624 pdv_serial_binary_command(pdv_p, (char *) buf, 2);
02625
02626
02627 pdv_serial_wait(pdv_p, 100, 64);
02628 break;
02629
02630 case SMD_TYPE_1M15P:
02631 case SMD_TYPE_6M3P:
02632 if ((smd_reg1 = smd_read_reg(pdv_p, SMD_1M15P_READ_R1)) == -1)
02633 {
02634 edt_msg(PDVWARN, "libpdv: no response from SMD R1 reg read\n");
02635 return -1;
02636 }
02637
02638 buf[0] = (u_char) SMD_1M15P_WRITE_R1;
02639
02640
02641
02642
02643 if (value == 0)
02644 buf[1] = smd_reg1 &~ SMD_1M15P_R1_GAIN;
02645 else if (value == 1)
02646 buf[1] = smd_reg1 | SMD_1M15P_R1_GAIN;
02647 else return -1;
02648
02649 pdv_serial_binary_command(pdv_p, (char *) buf, 2);
02650 pdv_p->dd_p->gain = value;
02651
02652
02653 pdv_serial_wait(pdv_p, 100, 64);
02654 break;
02655 }
02656
02657 return ret;
02658 }
02659
02668 int
02669 pdv_set_gain_ch(PdvDev * pdv_p, int value, int chan)
02670 {
02671 int ret = -1;
02672
02673
02674 edt_msg(DBG2, "pdv_set_gain_ch(%d, [%c]) ret %d\n",
02675 value, (chan == 1) ? 'A' : (chan == 2) ? 'B' : '?', ret);
02676 return (ret);
02677 }
02678
02697 int
02698 pdv_set_blacklevel(PdvDev * pdv_p, int value)
02699 {
02700 Dependent *dd_p = pdv_p->dd_p;
02701 int ret;
02702
02703 edt_msg(DBG2, "pdv_set_blacklevel(%d)\n", value);
02704
02705 dd_p->level = value;
02706 ret = edt_set_dependent(pdv_p, dd_p);
02707
02708 if (dd_p->set_offset == SMD_SERIAL)
02709 ret = pdv_set_blacklevel_smd(pdv_p, value);
02710
02711 else if ((strncasecmp(dd_p->camera_class, "Adimec", 6) == 0))
02712 {
02713 ret = pdv_set_blacklevel_adimec(pdv_p, value);
02714 }
02715
02716 else if ((strlen(dd_p->serial_offset) > 0)
02717 && (dd_p->serial_format == SERIAL_BINARY))
02718 {
02719 send_serial_binary_cmd(pdv_p, dd_p->serial_offset, value);
02720 }
02721
02722 else if ((strlen(dd_p->serial_offset) > 0)
02723 && ((dd_p->serial_format == SERIAL_ASCII)
02724 || (dd_p->serial_format == SERIAL_ASCII_HEX)))
02725 {
02726 char cmdstr[128];
02727
02728 if (dd_p->serial_format == SERIAL_ASCII_HEX)
02729 sprintf(cmdstr, "%s %02x", dd_p->serial_offset, value);
02730 else
02731 sprintf(cmdstr, "%s %d", dd_p->serial_offset, value);
02732 ret = pdv_serial_command_flagged(pdv_p, cmdstr, SCFLAG_NORESP);
02733 pdv_serial_wait(pdv_p, pdv_p->dd_p->serial_timeout, pdv_p->dd_p->serial_respcnt);
02734 if (*pdv_p->dd_p->serial_response)
02735 pdv_serial_read(pdv_p, cmdstr, 63);
02736 }
02737 edt_msg(DBG2, "pdv_set_blacklevel() %d\n", ret);
02738 return (ret);
02739 }
02740
02741 int pdv_set_blacklevel_smd(PdvDev * pdv_p, int value)
02742 {
02743 char buf[128];
02744 int ret = 0;
02745 int tmpval = value & 0xfff;
02746 int smd_reg2, smd_reg3;
02747
02748 if (Smd_type == NOT_SET)
02749 {
02750 Smd_type = smd_read_reg(pdv_p, SMD_READ_CAMTYPE);
02751 if ((Smd_type & 0xfff) == 0xfff)
02752
02753 Smd_type = smd_read_reg(pdv_p, SMD_READ_CAMTYPE);
02754 }
02755
02756 switch (Smd_type)
02757 {
02758 case SMD_TYPE_4M4:
02759 case SMD_TYPE_BT25:
02760 break;
02761
02762 case SMD_TYPE_1M30P:
02763 buf[0] = (u_char) SMD_1M30P_REG_W_LS_OFFSET;
02764 buf[1] = value & 0xff;
02765 pdv_serial_binary_command(pdv_p, (char *) buf, 2);
02766
02767 buf[0] = (u_char) SMD_1M30P_REG_W_MS_OFFSET;
02768 buf[1] = (value & 0xff00) >> 8;
02769 pdv_serial_binary_command(pdv_p, (char *) buf, 2);
02770
02771
02772 pdv_serial_wait(pdv_p, 100, 64);
02773 break;
02774
02775 case SMD_TYPE_1M15P:
02776 if ((smd_reg3 = smd_read_reg(pdv_p, SMD_1M15P_READ_R3)) == -1)
02777 {
02778 edt_msg(PDVWARN, "libpdv: no response from Dalstar R3 reg read\n");
02779 ret = -1;
02780 }
02781
02782 smd_reg2 = tmpval >> 4;
02783 smd_reg3 = (smd_reg3 & ~0x0f) | tmpval & 0x0f;
02784
02785
02786 buf[0] = (u_char) SMD_1M15P_WRITE_R3;
02787 buf[1] = (u_char) smd_reg3;
02788 pdv_serial_binary_command(pdv_p, (char *) buf, 2);
02789
02790
02791 buf[0] = (u_char) SMD_1M15P_WRITE_R2;
02792 buf[1] = (u_char) smd_reg2;
02793 pdv_serial_binary_command(pdv_p, (char *) buf, 2);
02794
02795
02796 pdv_serial_wait(pdv_p, 100, 64);
02797 break;
02798
02799 default:
02800 ret = -1;
02801 }
02802
02803 return ret;
02804 }
02805
02814 int
02815 pdv_set_aperture(PdvDev * pdv_p, int value)
02816 {
02817 edt_msg(PDVWARN, "pdv_set_aperture is OBSOLETE\n");
02818 return (-1);
02819 }
02820
02862 int
02863 pdv_set_binning(PdvDev * pdv_p, int xval, int yval)
02864 {
02865 int ret = -1;
02866 int newvskip, newhskip, newwidth, newheight;
02867 Dependent *dd_p = pdv_p->dd_p;
02868
02869 if (((xval != 1) && (xval % 2)) || ((yval != 1) && (yval % 2)))
02870 {
02871 edt_msg(PDVWARN, "pdv_set_binning(%d, %d) -- invalid value\n", xval, yval);
02872 return -1;
02873 }
02874
02875 edt_msg(DBG2, "pdv_set_binning(%d, %d)\n", xval, yval);
02876
02877 if (strcmp(dd_p->serial_binning, "BIN") == 0)
02878 {
02879 ret = pdv_set_binning_dvc(pdv_p, xval, yval);
02880 }
02881 else if (strcmp(dd_p->serial_binning, "B=") == 0)
02882 {
02883 ret = pdv_set_binning_generic(pdv_p, xval - 1);
02884 }
02885 else if (*dd_p->serial_binning)
02886 {
02887
02888 ret = pdv_set_binning_generic(pdv_p, xval);
02889 }
02890 else
02891 return -1;
02892
02893 if (ret)
02894 return ret;
02895
02896 if (dd_p->binx < 1)
02897 dd_p->binx = 1;
02898 if (dd_p->biny < 1)
02899 dd_p->biny = 1;
02900
02901 newwidth = (((pdv_get_width(pdv_p) * dd_p->binx) / xval) / 4) * 4;
02902 newheight = (((pdv_get_height(pdv_p) * dd_p->biny) / yval)) ;
02903
02904 if (dd_p->roi_enabled)
02905 {
02906 newhskip = (dd_p->hskip * dd_p->binx) / xval;
02907 newvskip = (dd_p->vskip * dd_p->biny) / yval;
02908 ret = pdv_set_roi(pdv_p, newhskip, newwidth, newvskip, newheight);
02909 }
02910
02911 if (!ret)
02912 {
02913 dd_p->binx = xval;
02914 dd_p->biny = yval;
02915 }
02916
02917 return (ret);
02918 }
02919
02925 int
02926 pdv_set_binning_generic(PdvDev * pdv_p, int value)
02927 {
02928 int ret = 0;
02929 char cmdstr[64];
02930 Dependent *dd_p = pdv_p->dd_p;
02931
02932 if (dd_p->serial_binning[strlen(dd_p->serial_binning) - 1] == '=')
02933 sprintf(cmdstr, "%s%d", dd_p->serial_binning, value);
02934 else
02935 sprintf(cmdstr, "%s %d", dd_p->serial_binning, value);
02936 pdv_serial_command_flagged(pdv_p, cmdstr, SCFLAG_NORESP);
02937
02938 return (0);
02939 }
02940
02941
02954 int
02955 pdv_get_exposure(PdvDev * pdv_p)
02956 {
02957 edt_msg(DBG2, "pdv_get_exposure() %d\n", pdv_p->dd_p->shutter_speed);
02958
02959 return (pdv_p->dd_p->shutter_speed);
02960 }
02961
02962 void
02963 pdv_set_defaults(PdvDev * pdv_p)
02964 {
02965 Dependent *dd_p = pdv_p->dd_p;
02966
02967 if (dd_p->default_shutter_speed != NOT_SET)
02968 pdv_set_exposure(pdv_p, dd_p->default_shutter_speed);
02969 if (dd_p->default_gain != NOT_SET)
02970 pdv_set_gain(pdv_p, dd_p->default_gain);
02971 if (dd_p->default_offset != NOT_SET)
02972 pdv_set_blacklevel(pdv_p, dd_p->default_offset);
02973 }
02974
02986 pdv_read_response(PdvDev * pdv_p, char *buf)
02987 {
02988 int len;
02989
02990
02991
02992
02993 len = pdv_serial_wait(pdv_p, pdv_p->dd_p->serial_timeout, 2048);
02994 if (len)
02995 pdv_serial_read(pdv_p, buf, len);
02996 return len;
02997 }
02998
02999
03014 int
03015 pdv_get_gain(PdvDev * pdv_p)
03016 {
03017 edt_msg(DBG2, "pdv_get_gain() %d\n", pdv_p->dd_p->gain);
03018
03019 return (pdv_p->dd_p->gain);
03020 }
03021
03022
03035 int
03036 pdv_get_blacklevel(PdvDev * pdv_p)
03037 {
03038 edt_msg(DBG2, "pdv_get_blacklevel() %d\n", pdv_p->dd_p->level);
03039
03040 return (pdv_p->dd_p->level);
03041 }
03042
03051 int
03052 pdv_get_aperture(PdvDev * pdv_p)
03053 {
03054 edt_msg(PDVWARN, "pdv_get_aperture is OBSOLETE\n");
03055 return (-1);
03056 }
03057
03068 void
03069 pdv_invert(PdvDev * pdv_p, int val)
03070 {
03071 u_int data_path;
03072 int ret;
03073
03074 edt_msg(DBG2, "pdv_invert()\n");
03075
03076 if (pdv_p->devid == PDVFOI_ID)
03077 {
03078 char buf[64];
03079
03080 pdv_serial_wait(pdv_p, pdv_p->dd_p->serial_timeout, pdv_p->dd_p->serial_respcnt);
03081 if (*pdv_p->dd_p->serial_response)
03082 ret = pdv_serial_read(pdv_p, buf, 63);
03083 }
03084
03085
03086 data_path = pdv_p->dd_p->datapath_reg;
03087
03088 edt_msg(DBG2, "pdv_invert(%d)\n", val);
03089
03090 if (val)
03091 data_path |= PDV_INVERT;
03092 else
03093 data_path &= ~PDV_INVERT;
03094
03095 edt_reg_write(pdv_p, PDV_DATA_PATH, data_path);
03096 pdv_p->dd_p->datapath_reg = data_path;
03097 }
03098
03104 u_short
03105 pdv_get_interlaced(PdvDev * pdv_p)
03106
03107 {
03108 edt_msg(DBG2, "pdv_get_interlaced() %u\n", pdv_p->dd_p->interlace);
03109
03110 return (pdv_p->dd_p->interlace);
03111 }
03112
03135 int
03136 pdv_force_single(PdvDev * pdv_p)
03137 {
03138 return pdv_p->dd_p->force_single;
03139 }
03140
03148 int
03149 pdv_variable_size(PdvDev * pdv_p)
03150 {
03151 return pdv_p->dd_p->variable_size;
03152 }
03153
03154
03161 int
03162 pdv_enable_lock(PdvDev * pdv_p, int flag)
03163 {
03164 Dependent *dd_p = pdv_p->dd_p;
03165 int ret;
03166
03167 switch (dd_p->lock_shutter)
03168 {
03169 case KODAK_AIA_MCL:
03170 {
03171 int mcl = edt_reg_read(pdv_p, PDV_MODE_CNTL);
03172
03173 if (flag)
03174 mcl |= PDV_AIA_MC3;
03175 else
03176 mcl &= ~PDV_AIA_MC3;
03177
03178 edt_reg_write(pdv_p, PDV_MODE_CNTL, mcl);
03179 ret = 0;
03180 break;
03181 }
03182 case KODAK_AIA_SER:
03183 {
03184 if (flag)
03185 ret = pdv_serial_command(pdv_p, "SHE OF");
03186 else
03187 ret = pdv_serial_command(pdv_p, "SHE ON");
03188
03189 break;
03190 }
03191 case KODAK_SER_14I:
03192 {
03193 if (flag)
03194 ret = pdv_serial_command(pdv_p, "SHE FO");
03195 else
03196 ret = pdv_serial_command(pdv_p, "SHE ON");
03197 break;
03198 }
03199 case HAM_4880:
03200 {
03201 if (flag)
03202 ret = pdv_serial_command(pdv_p, "ASH O");
03203 else
03204 ret = pdv_serial_command(pdv_p, "ASH A");
03205 break;
03206 }
03207 }
03208 return (ret);
03209 }
03210
03211
03231 int
03232 pdv_serial_read_nullterm(PdvDev * pdv_p, char *buf, int size, int nullterm)
03233 {
03234 #define PKT_OVERHEAD 2
03235 #define PKT_SIZE_MAX 15
03236
03237 int bytesReturned;
03238 int total = 0;
03239 Dependent *dd_p;
03240
03241 if (pdv_p == NULL || pdv_p->dd_p == NULL)
03242 return 0;
03243
03244 dd_p = pdv_p->dd_p;
03245
03246 if (buf == NULL || pdv_p == NULL || size == 0)
03247 return (-1);
03248
03249 if (pdv_p->devid == PDVFOI_ID)
03250 {
03251 char tmpbuf[256];
03252
03253 bytesReturned = edt_get_msg(pdv_p, tmpbuf, 256);
03254 if (bytesReturned <= PKT_OVERHEAD)
03255 return (0);
03256 if (Pdv_debug)
03257 {
03258 int i, num = bytesReturned;
03259
03260 if (num > 16)
03261 num = 16;
03262 edt_msg(DBG2, "pdv_serial_read(<");
03263 for (i = 0; i < num; i++)
03264 {
03265 edt_msg(DBG2, "%02x", (u_char) tmpbuf[i]);
03266 if (i + 1 < num)
03267 edt_msg(DBG2, ", ");
03268 else
03269 break;
03270 }
03271 edt_msg(DBG2, ">, %d-%d\n", bytesReturned, size);
03272 }
03273 if (bytesReturned > size)
03274 {
03275 memcpy(buf, &tmpbuf[PKT_OVERHEAD], size);
03276 edt_msg(DBG2, "pdv_serial_read(%d) %d\n", size, bytesReturned);
03277 return (size);
03278 }
03279 else
03280 {
03281 bytesReturned -= PKT_OVERHEAD;
03282 memcpy(buf, &tmpbuf[PKT_OVERHEAD], bytesReturned);
03283 if (nullterm)
03284 buf[bytesReturned] = 0;
03285 edt_msg(DBG2, "pdv_serial_read(%d) %d\n", size, bytesReturned);
03286 return (bytesReturned);
03287 }
03288 }
03289
03290 #if 0
03291 if (!pdv_get_width(pdv_p))
03292 {
03293 edt_msg(DBG2, "warning - serial_read called with uninitialized camera\n");
03294 return (0);
03295 }
03296 #endif
03297
03298 bytesReturned = edt_get_msg(pdv_p, buf, size);
03299 assert(bytesReturned <= size);
03300
03301 if (nullterm)
03302 buf[bytesReturned] = 0;
03303
03304 if (Pdv_debug)
03305 {
03306 int i, num = bytesReturned;
03307
03308 if (num > 16)
03309 num = 16;
03310 edt_msg(DBG2, "pdv_serial_read(<");
03311 for (i = 0; i < num; i++)
03312 {
03313 edt_msg(DBG2, "%02x", (u_char) buf[i]);
03314 if (i + 1 < num)
03315 edt_msg(DBG2, ", ");
03316 else
03317 break;
03318 }
03319 edt_msg(DBG2, ">, %d)\n", size);
03320 }
03321 return bytesReturned;
03322 }
03323
03355 int
03356 pdv_serial_read(PdvDev * pdv_p, char *buf, int count)
03357 {
03358
03359 return pdv_serial_read_nullterm(pdv_p,buf,count,TRUE);
03360 }
03361
03368 int
03369 pdv_send_msg(PdvDev *ed, int chan, char *buf, int size)
03370 {
03371 int i, ret = 0;
03372 int pause = ed->dd_p->pause_for_serial;
03373 char bbuf[32];
03374
03375
03376 if (pause)
03377 {
03378 for (i=0; i<size; i++)
03379 {
03380 bbuf[0] = buf[i];
03381 edt_msleep(ed->dd_p->pause_for_serial);
03382 if ((ret = edt_send_msg(ed, chan, bbuf, 1)) != 0)
03383 return ret;
03384 }
03385 return ret;
03386 }
03387 else return edt_send_msg(ed, chan, buf, size);
03388 }
03389
03405 int
03406 pdv_serial_write_single_block(PdvDev * pdv_p, char *buf, int size)
03407 {
03408 int ret;
03409 Dependent *dd_p;
03410
03411 if (size == 0)
03412 return (-1);
03413
03414 if (Pdv_debug)
03415 {
03416 int i, num = size;
03417
03418 if (num > 16)
03419 num = 16;
03420 edt_msg(DBG2, "pdv_serial_write_single_block(<");
03421 for (i = 0; i < num; i++)
03422 {
03423 edt_msg(DBG2, "%02x", (u_char) buf[i]);
03424 if (i + 1 < num)
03425 edt_msg(DBG2, ", ");
03426 else
03427 break;
03428 }
03429 edt_msg(DBG2, ">, %d)\n", size);
03430 }
03431
03432 if (buf == NULL || pdv_p == NULL || pdv_p->dd_p == NULL)
03433 return (-1);
03434 dd_p = pdv_p->dd_p;
03435
03436 if (pdv_p->devid == PDVFOI_ID)
03437 {
03438 ret = pdv_send_msg(pdv_p, pdv_p->foi_unit, buf, size);
03439 return (ret);
03440 }
03441 else
03442 {
03443 ret = pdv_send_msg(pdv_p, pdv_p->channel_no, buf, size);
03444 return (ret);
03445 }
03446 }
03447
03456 int
03457 pdv_serial_write_available(PdvDev *pdv_p)
03458
03459 {
03460
03461 int avail;
03462
03463 edt_ioctl(pdv_p, EDTG_SERIAL_WRITE_AVAIL, &avail);
03464
03465 return avail;
03466
03467 }
03468
03469 static int pdv_serial_block_size = 512;
03470
03476 void pdv_set_serial_block_size(int newsize)
03477 {
03478 pdv_serial_block_size = newsize;
03479 }
03480
03487 int
03488 pdv_get_serial_block_size()
03489 {
03490 return pdv_serial_block_size;
03491 }
03492
03496 int
03497 pdv_serial_read_enable(PdvDev *pdv_p)
03498
03499 {
03500
03501 edt_reg_or(pdv_p, PDV_SERIAL_DATA_CNTL,
03502 PDV_EN_TX | PDV_EN_RX |
03503 PDV_EN_RX_INT | PDV_EN_DEV_INT);
03504
03505 edt_reg_or(pdv_p, EDT_DMA_INTCFG, EDT_RMT_EN_INTR | EDT_PCI_EN_INTR) ;
03506
03507 return 0;
03508 }
03509
03526 int
03527 pdv_serial_write(PdvDev *pdv_p, char *buf, int size)
03528
03529 {
03530 int avail;
03531 int left = size;
03532 int ret = 0;
03533 int offset = 0;
03534 int speed = pdv_get_baud(pdv_p);
03535 int sleepval;
03536 int chunk = pdv_serial_block_size;
03537
03538 if (speed != 0)
03539 sleepval = speed/10;
03540 else
03541 sleepval = 10;
03542
03543 sleepval = (chunk * 1000) / sleepval;
03544
03545 avail = pdv_serial_write_available(pdv_p);
03546 if (avail > size)
03547 {
03548 return pdv_serial_write_single_block(pdv_p, buf, size);
03549 }
03550 else
03551 {
03552 left -= avail;
03553 offset += avail;
03554
03555 #ifdef DBG_SERIAL
03556 printf("Writing %d chars\n", avail);
03557 #endif
03558
03559 ret = pdv_serial_write_single_block(pdv_p, buf, avail);
03560
03561 if (ret != 0)
03562 return ret;
03563 while (left > 0)
03564 {
03565 edt_msleep(sleepval);
03566 avail = pdv_serial_write_available(pdv_p);
03567 if (avail > 0)
03568 {
03569 if ( avail > left)
03570 {
03571 avail = left;
03572 left = 0;
03573 }
03574 else
03575 {
03576 left -= avail;
03577 }
03578
03579 #ifdef DBG_SERIAL
03580 printf("Writing %d chars\n", avail);
03581 #endif
03582 ret = pdv_serial_write_single_block(pdv_p, buf+offset, avail);
03583 if (ret != 0)
03584 return ret;
03585 offset += avail;
03586
03587 }
03588 }
03589 }
03590 return 0;
03591 }
03592
03609 int
03610 pdv_serial_read_blocking(PdvDev *pdv_p, char *buf, int size)
03611
03612 {
03613 int left = size;
03614 int ret = 0;
03615 int offset = 0;
03616
03617
03618 int avail = 1024;
03619 int speed = pdv_get_baud(pdv_p);
03620 int sleepval;
03621 int chunk = pdv_serial_block_size;
03622
03623 if (speed != 0)
03624 sleepval = speed/10;
03625 else
03626 sleepval = 10;
03627
03628 sleepval = (chunk * 1000) / sleepval;
03629
03630 if (avail > size)
03631 {
03632 sleepval = (size * 1000) / sleepval;
03633
03634 pdv_serial_wait(pdv_p, sleepval, size);
03635
03636 return pdv_serial_read(pdv_p, buf, size);
03637 }
03638 else
03639 {
03640
03641 while (left > 0)
03642 {
03643 avail = pdv_serial_wait(pdv_p, sleepval, chunk);
03644 if (avail)
03645 {
03646 if ( avail > left)
03647 {
03648 avail = left;
03649 left = 0;
03650 }
03651 else
03652 {
03653 left -= avail;
03654 }
03655
03656 #ifdef DBG_SERIAL
03657 printf("Reading %d chars total = %d\n", avail, offset + avail);
03658 #endif
03659 ret = pdv_serial_read(pdv_p, buf+offset, avail);
03660 offset += avail;
03661
03662 }
03663
03664
03665 }
03666
03667 }
03668
03669 return 0;
03670
03671 }
03672
03673
03717 int
03718 pdv_serial_command(PdvDev * pdv_p, char *cmd)
03719 {
03720
03721
03722
03723
03724
03725
03726
03727
03728
03729
03730
03731 return pdv_serial_command_flagged(pdv_p, cmd, 0);
03732 }
03733
03750 int
03751 pdv_serial_command_flagged(PdvDev * pdv_p, char *cmd, u_int flag)
03752 {
03753 char *buf;
03754 int ret;
03755 int i;
03756 size_t len=0;
03757 int bufsize=8;
03758 char *p = cmd;
03759
03760 if (pdv_p == NULL || pdv_p->dd_p == NULL)
03761 return -1;
03762
03763
03764 while (*p++)
03765 ++bufsize;
03766 buf = (char *)malloc(bufsize+16);
03767
03768
03769
03770 if (pdv_p->devid == PDVFOI_ID)
03771 {
03772 buf[len++] = 'c';
03773
03774
03775 if (flag & SCFLAG_NORESP)
03776 buf[len++] = 't';
03777 buf[len++] = ' ';
03778 }
03779
03780
03781 if (*pdv_p->dd_p->serial_prefix)
03782 {
03783 strcpy(&(buf[len]), pdv_p->dd_p->serial_prefix);
03784 len += strlen(pdv_p->dd_p->serial_prefix);
03785 }
03786
03787
03788 if (pdv_p->dd_p->serial_format == SERIAL_PULNIX_1010)
03789 {
03790 buf[len++] = 0x02;
03791 for (i = 0; i < bufsize; i++)
03792 if (cmd[i] == '\r' || cmd[i] == '\n' || cmd[i] == 0)
03793 break;
03794 else
03795 buf[len++] = cmd[i];
03796 buf[len++] = 0x03;
03797 }
03798 else
03799 {
03800
03801
03802 for (i = 0; i < bufsize; i++)
03803 {
03804 if (cmd[i] == '\r' || cmd[i] == '\n' || cmd[i] == 0)
03805 break;
03806 else
03807 buf[len++] = cmd[i];
03808 }
03809
03810 sprintf(&(buf[len]), "%s", pdv_serial_term(pdv_p));
03811 len += strlen(pdv_serial_term(pdv_p));
03812 }
03813
03814 if (Pdv_debug)
03815 debug_print_serial_command(buf);
03816 ret = pdv_serial_write(pdv_p, buf, len);
03817
03818 free(buf);
03819 return (ret);
03820 }
03821
03830 char *
03831 pdv_serial_term(PdvDev * pdv_p)
03832 {
03833 return pdv_p->dd_p->serial_term;
03834 }
03835
03844 char *
03845 pdv_serial_prefix(PdvDev * pdv_p)
03846 {
03847 return pdv_p->dd_p->serial_prefix;
03848 }
03849
03864 void
03865 pdv_set_serial_delimiters(PdvDev *pdv_p, char *prefix, char *term)
03866
03867 {
03868 if (prefix)
03869 strncpy(pdv_p->dd_p->serial_prefix,prefix, sizeof(pdv_p->dd_p->serial_prefix)-1);
03870 else
03871 pdv_p->dd_p->serial_prefix[0] = 0;
03872
03873 if (term)
03874 strncpy(pdv_p->dd_p->serial_term,term, sizeof(pdv_p->dd_p->serial_term)-1);
03875 else
03876 pdv_p->dd_p->serial_term[0] = 0;
03877
03878 edt_set_dependent(pdv_p,pdv_p->dd_p);
03879 }
03880
03881
03882
03883 static void
03884 debug_print_serial_command(char *cmd)
03885 {
03886 char tmpbuf[256];
03887 char *p = cmd;
03888 char *pp = tmpbuf;
03889 int len=0;
03890
03891 while (*p != '\0')
03892 {
03893 if (*p == 0x02)
03894 {
03895 sprintf(pp, "<0x2>");
03896 pp += 5;
03897 len += 5;
03898 ++p;
03899 }
03900 else if (*p == 0x03)
03901 {
03902 sprintf(pp, "<0x3>");
03903 pp += 5;
03904 len += 5;
03905 ++p;
03906 }
03907
03908 else if (*p == '\r')
03909 {
03910 sprintf(pp, "\\r");
03911 pp += 2;
03912 len += 2;
03913 ++p;
03914 }
03915 else if (*p == '\n')
03916 {
03917 sprintf(pp, "\\n");
03918 pp += 2;
03919 len += 2;
03920 ++p;
03921 }
03922 else
03923 {
03924 *(pp++) = *(p++);
03925 ++len ;
03926 }
03927 if (len > 250)
03928 break;
03929 }
03930 *pp = '\0';
03931 edt_msg(DBG2, "pdv_serial_command(\"%s\")\n", tmpbuf);
03932 }
03933
03964 int
03965 pdv_serial_binary_command(PdvDev * pdv_p, char *cmd, int len)
03966 {
03967 return pdv_serial_binary_command_flagged(pdv_p, cmd, len, 0);
03968 }
03969
03970
03977 int
03978 pdv_send_basler_frame(PdvDev * pdv_p, u_char *cmd, int len)
03979 {
03980 int i;
03981 u_char frame[128];
03982 u_char *p = frame;
03983 u_char bcc = 0;
03984
03985 *p++ = 0x02;
03986 for (i=0; i<len; i++)
03987 {
03988 bcc ^= cmd[i];
03989 *p++ = cmd[i];
03990 }
03991 *p++ = bcc;
03992 *p++ = 0x03;
03993
03994 return pdv_serial_binary_command_flagged(pdv_p, (char *)frame, len+3, 0);
03995 }
03996
04003 int
04004 pdv_read_basler_frame(PdvDev * pdv_p, u_char *frame, int len)
04005 {
04006 int n, nn;
04007 char tmpbuf[128];
04008 char *p;
04009
04010 n = pdv_serial_wait(pdv_p, 500, len);
04011 if (n < 1)
04012 return 0;
04013
04014 nn = pdv_serial_read(pdv_p, tmpbuf, n);
04015
04016 if (tmpbuf[0] == 0x06)
04017 {
04018 frame[0] = 0x06;
04019 return 1;
04020 }
04021
04022 if (tmpbuf[0] == 0x15)
04023 {
04024 frame[0] = 0x06;
04025 return 1;
04026 }
04027
04028 if (tmpbuf[0] == 0x02)
04029 {
04030 p = &tmpbuf[nn];
04031 n = pdv_serial_wait(pdv_p, 50, len);
04032 pdv_serial_read(pdv_p, p, n);
04033
04034 }
04035 return n;
04036 }
04037
04053 int
04054 pdv_send_duncan_frame(PdvDev * pdv_p, u_char *cmdbuf, int size)
04055 {
04056 int i;
04057 u_char frame[128];
04058 u_char *p = frame;
04059
04060 *p++ = 0x02;
04061 for (i=0; i<size; i++)
04062 *p++ = cmdbuf[i];
04063
04064 CheckSumMessage(frame);
04065
04066 return pdv_serial_binary_command_flagged(pdv_p, (char *)frame, size+2, 0);
04067 }
04068
04069 static void
04070 CheckSumMessage(unsigned char *msg)
04071 {
04072 unsigned short length;
04073 unsigned char csum = 0;
04074
04075 msg++;
04076 length = *msg++;
04077 length += *msg++ << 8;
04078 if (length > 0)
04079 {
04080 for (; length > 0; length--)
04081 csum += *msg++;
04082 *msg = -csum;
04083 }
04084 }
04085
04086
04099 int
04100 pdv_read_duncan_frame(PdvDev * pdv_p, u_char *frame)
04101 {
04102 int n, nn;
04103 u_short length;
04104
04105
04106 n = pdv_serial_wait(pdv_p, 500, 3);
04107 if (n < 3)
04108 return 0;
04109
04110 nn = pdv_serial_read(pdv_p, (char *)frame, 3);
04111
04112 length = (u_short)frame[1] + (u_short)(frame[2] << 8);
04113
04114 if (length)
04115 n = pdv_serial_wait(pdv_p, 1000, length+1);
04116
04117 if (n)
04118 pdv_serial_read(pdv_p, (char *)(&frame[3]), n);
04119
04120 return n+nn;
04121 }
04122
04146 int
04147 pdv_serial_binary_command_flagged(PdvDev * pdv_p, char *cmd, int len, u_int flag)
04148 {
04149 char *buf;
04150 int ret;
04151 int i;
04152 int tmplen = 0;
04153
04154 edt_msg(DBG2, "pdv_serial_binary_command()\n");
04155
04156 if (pdv_p == NULL || pdv_p->dd_p == NULL)
04157 return -1;
04158
04159 if ((buf = (char *)malloc(len)) == NULL)
04160 return -1;
04161
04162
04163 if (pdv_p->devid == PDVFOI_ID)
04164 {
04165 buf[tmplen++] = 'c';
04166 if (flag & SCFLAG_NORESP)
04167 buf[tmplen++] = 't';
04168 buf[tmplen++] = ' ';
04169 }
04170
04171
04172 for (i = 0; i < len; i++)
04173 {
04174 buf[tmplen++] = cmd[i];
04175 }
04176 ret = pdv_serial_write(pdv_p, buf, tmplen);
04177 return (ret);
04178 }
04179
04181
04209 int
04210 pdv_read(PdvDev * pdv_p, unsigned char *buf, unsigned long size)
04211 {
04212 Dependent *dd_p;
04213 unsigned long newsize;
04214 int readsize;
04215 int dosi = 0;
04216 unsigned char *tbuf;
04217
04218
04219 edt_msg(DBG2, "pdv_read()\n");
04220
04221 pdv_setup_dma(pdv_p);
04222
04223 if (pdv_p->dd_p->start_delay)
04224 edt_msleep(pdv_p->dd_p->start_delay);
04225
04226
04227 if (pdv_specinst_serial_triggered(pdv_p))
04228 {
04229 edt_msg(PDVWARN, "libpdv invalid combination: SPECINST_SERIAL/pdv_read/i/f trigger");
04230 edt_msg(PDVWARN, "should use pdv_start_image() or external trigger");
04231 }
04232
04233 if (pdv_p == NULL || pdv_p->dd_p == NULL)
04234 return -1;
04235
04236 dd_p = pdv_p->dd_p;
04237
04238 if (pdv_p->devid == DMY_ID)
04239 {
04240 pdv_dmy_data(buf, dd_p->width, dd_p->height, dd_p->depth);
04241 if (dd_p->markras)
04242 pdv_mark_ras(buf, dd_p->rascnt,
04243 dd_p->width, dd_p->height, dd_p->markrasx, dd_p->markrasy);
04244 if (dd_p->markbin)
04245 pdv_mark_bin(buf, dd_p->rascnt, dd_p->width, dd_p->height, 4, 0);
04246 if (dd_p->markbin || dd_p->markras) dd_p->rascnt++ ;
04247 printf("pdv_read rascnt %d\n",dd_p->rascnt) ;
04248 return (size);
04249 }
04250
04251 readsize = pdv_get_dmasize(pdv_p);
04252
04253 if (dd_p->swinterlace)
04254 {
04255 pdv_alloc_tmpbuf(pdv_p);
04256
04257 readsize = pdv_get_dmasize(pdv_p);
04258
04259 }
04260
04261
04262
04263
04264 edt_startdma_reg(pdv_p, PDV_CMD, PDV_ENABLE_GRAB);
04265 if (edt_get_firstflush(pdv_p) != EDT_ACT_KBS)
04266 edt_set_firstflush(pdv_p, EDT_ACT_ONCE);
04267
04268
04269 if (dd_p->slop)
04270 {
04271 edt_msg(DBG2, "adjusting readsize %x by slop %x to %x\n",
04272 readsize, dd_p->slop, readsize - dd_p->slop);
04273 readsize -= dd_p->slop;
04274 }
04275
04276 if (dd_p->header_size && dd_p->header_dma)
04277 {
04278 readsize += dd_p->header_size;
04279 }
04280
04281 if (dd_p->swinterlace)
04282 {
04283 if (pdv_process_inplace(pdv_p))
04284 tbuf = buf;
04285 else
04286 tbuf = pdv_p->tmpbuf;
04287
04288 newsize = edt_read(pdv_p, tbuf, readsize);
04289 dd_p->last_raw = tbuf;
04290 dd_p->last_image = buf;
04291 }
04292 else
04293 {
04294 tbuf = buf;
04295 newsize = edt_read(pdv_p, buf, readsize);
04296 dd_p->last_raw = buf;
04297 dd_p->last_image = buf;
04298 }
04299
04300 dd_p->rascnt = 1;
04301 if (dd_p->markras)
04302 pdv_mark_ras(buf, dd_p->rascnt++, dd_p->width, dd_p->height,
04303 dd_p->markrasx, dd_p->markrasy);
04304
04305 size = newsize;
04306
04307
04308
04309 edt_msg(DBG2, "swinterlace %d\n", dd_p->swinterlace);
04310
04311 pdv_deinterlace(pdv_p, dd_p, tbuf, buf);
04312
04313
04314
04315 return (size);
04316 }
04317
04318
04333 unsigned char *
04334 pdv_image(PdvDev * pdv_p)
04335 {
04336 edt_msg(DBG2, "pdv_image()\n");
04337
04338 pdv_start_images(pdv_p, 1);
04339 return pdv_wait_images(pdv_p, 1);
04340 }
04341
04342
04353 unsigned char *
04354 pdv_image_raw(PdvDev * pdv_p)
04355 {
04356 edt_msg(DBG2, "pdv_image()\n");
04357
04358 pdv_start_images(pdv_p, 1);
04359 return pdv_wait_images_raw(pdv_p, 1);
04360 }
04361
04370 void
04371 pdv_start_image(PdvDev * pdv_p)
04372 {
04373 edt_msg(DBG2, "pdv_start_image()\n");
04374
04375 pdv_start_images(pdv_p, 1);
04376 }
04377
04378
04391 void
04392 pdv_start_images(PdvDev * pdv_p, int count)
04393 {
04394
04395 edt_msg(DBG2, "pdv_start_images(%d) %d\n", count, pdv_p->dd_p->started_continuous);
04396
04397 if (pdv_p->dd_p->start_delay)
04398 edt_msleep(pdv_p->dd_p->start_delay);
04399
04400
04401 if (pdv_p->ring_buffer_numbufs < 1)
04402 pdv_multibuf(pdv_p, 1);
04403
04404
04405
04406
04407
04408
04409
04410
04411 if (!pdv_p->dd_p->started_continuous)
04412 {
04413 pdv_setup_continuous(pdv_p);
04414 }
04415 if (pdv_force_single(pdv_p) && (count > 1))
04416 {
04417 edt_msg(PDVWARN,
04418 "pdv_start_images(): %d buffers requested; should only\n", count);
04419 edt_msg(PDVWARN,
04420 "start one at a time when 'force_single' is set in config file\n");
04421 count = 1;
04422 }
04423
04424
04425 edt_start_buffers(pdv_p, count);
04426
04427 if (pdv_specinst_serial_triggered(pdv_p))
04428 pdv_trigger_specinst(pdv_p);
04429 }
04430
04431
04469 unsigned char *
04470 pdv_wait_image(PdvDev * pdv_p)
04471 {
04472 edt_msg(DBG2, "pdv_wait_image()\n");
04473
04474 return pdv_wait_images(pdv_p, 1);
04475 }
04476
04502 unsigned char *
04503 pdv_wait_image_raw(PdvDev * pdv_p)
04504 {
04505 edt_msg(DBG2, "pdv_wait_image()\n");
04506
04507 return pdv_wait_images_raw(pdv_p, 1);
04508 }
04509
04510
04542 unsigned char *
04543 pdv_wait_image_timed(PdvDev * pdv_p, u_int * timep)
04544 {
04545 return pdv_wait_image_timed_raw(pdv_p, timep, FALSE);
04546 }
04547
04580 unsigned char *
04581 pdv_wait_image_timed_raw(PdvDev * pdv_p, u_int * timep, int doRaw)
04582 {
04583 u_char *ret;
04584
04585 edt_msg(DBG2, "pdv_wait_image()\n");
04586
04587 if (doRaw)
04588 ret = pdv_wait_images_raw(pdv_p, 1);
04589 else
04590 ret = pdv_wait_images(pdv_p, 1);
04591
04592 edt_get_timestamp(pdv_p, timep, pdv_p->donecount - 1);
04593 return (ret);
04594 }
04595
04634 unsigned char *
04635 pdv_wait_images_timed_raw(PdvDev * pdv_p, int count, u_int * timep, int doRaw)
04636 {
04637 u_char *ret;
04638
04639 edt_msg(DBG2, "pdv_wait_images_timed_raw(count=%d, doRaw=%d)\n",
04640 count, doRaw);
04641
04642 if (doRaw)
04643 ret = pdv_wait_images_raw(pdv_p, count);
04644 else
04645 ret = pdv_wait_images(pdv_p, count);
04646
04647 edt_get_timestamp(pdv_p, timep, pdv_p->donecount - 1);
04648 return (ret);
04649 }
04650
04671 unsigned char *
04672 pdv_wait_images_timed(PdvDev * pdv_p, int count, u_int * timep)
04673 {
04674 return pdv_wait_images_timed_raw(pdv_p, count, timep, FALSE);
04675 }
04676
04681 unsigned char *
04682 pdv_last_image_timed_raw(PdvDev * pdv_p, u_int * timep, int doRaw)
04683 {
04684 return pdv_wait_last_image_timed_raw(pdv_p, timep, doRaw);
04685
04686 }
04687
04710 unsigned char *
04711 pdv_wait_last_image_timed_raw(PdvDev * pdv_p, u_int * timep, int doRaw)
04712 {
04713 u_char *ret;
04714 int donecount;
04715 int last_wait;
04716 int delta;
04717
04718 donecount = edt_done_count(pdv_p);
04719 last_wait = pdv_p->donecount;
04720
04721 edt_msg(DBG2, "pdv_wait_last_image_timed() last %d cur %d\n",
04722 last_wait, donecount);
04723
04724 delta = donecount - last_wait;
04725
04726 if (delta == 0)
04727 delta = 1;
04728
04729 if (doRaw)
04730 ret = pdv_wait_images_raw(pdv_p, delta);
04731 else
04732 ret = pdv_wait_images(pdv_p, delta);
04733
04734 edt_get_timestamp(pdv_p, timep, pdv_p->donecount - 1);
04735 return (ret);
04736 }
04737
04753 unsigned char *
04754 pdv_wait_last_image_timed(PdvDev * pdv_p, u_int * timep)
04755 {
04756 return pdv_wait_last_image_timed_raw(pdv_p, timep, FALSE);
04757 }
04758
04763 unsigned char *
04764 pdv_last_image_timed(PdvDev * pdv_p, u_int * timep)
04765 {
04766
04767 return pdv_last_image_timed_raw(pdv_p, timep, FALSE);
04768 }
04769
04790 unsigned char *
04791 pdv_wait_last_image_raw(PdvDev * pdv_p, int *nSkipped, int doRaw)
04792 {
04793 u_char *ret;
04794 int donecount;
04795 int last_wait;
04796 int delta;
04797
04798 donecount = edt_done_count(pdv_p);
04799 last_wait = pdv_p->donecount;
04800
04801 edt_msg(DBG2, "pdv_wait_last_image() last %d cur %d\n",
04802 last_wait, donecount);
04803
04804 delta = donecount - last_wait;
04805
04806 if (nSkipped)
04807 *nSkipped = (delta) ? delta - 1 : 0;
04808
04809 if (delta == 0)
04810 delta = 1;
04811
04812 if (doRaw)
04813 ret = pdv_wait_images_raw(pdv_p, delta);
04814 else
04815 ret = pdv_wait_images(pdv_p, delta);
04816
04817 return (ret);
04818 }
04819
04843 unsigned char *
04844 pdv_wait_last_image(PdvDev * pdv_p, int *nSkipped)
04845 {
04846 return pdv_wait_last_image_raw(pdv_p, nSkipped, FALSE);
04847 }
04848
04867 unsigned char *
04868 pdv_wait_next_image_raw(PdvDev * pdv_p, int *nSkipped, int doRaw)
04869 {
04870 u_char *ret;
04871 int donecount;
04872 int last_wait;
04873 int delta;
04874
04875 donecount = edt_done_count(pdv_p);
04876 last_wait = pdv_p->donecount;
04877
04878 edt_msg(DBG2, "pdv_wait_last_image() last %d cur %d\n",
04879 last_wait, donecount);
04880
04881 delta = donecount - last_wait;
04882
04883 if (*nSkipped)
04884 *nSkipped = (delta) ? delta - 1 : 0;
04885
04886
04887 if (delta == 0)
04888 delta = 1;
04889
04890 delta++;
04891
04892 if (doRaw)
04893 ret = pdv_wait_images_raw(pdv_p, delta);
04894 else
04895 ret = pdv_wait_images(pdv_p, delta);
04896
04897 return (ret);
04898 }
04899
04909 unsigned char *
04910 pdv_wait_next_image(PdvDev * pdv_p, int *nSkipped)
04911 {
04912
04913 return pdv_wait_next_image_raw(pdv_p, nSkipped, FALSE);
04914 }
04915
04916
04926 int
04927 pdv_in_continuous(PdvDev * pdv_p)
04928 {
04929 edt_msg(DBG2, "pdv_in_continuous() %x\n",
04930 pdv_p->dd_p->continuous);
04931 return pdv_p->dd_p->continuous;
04932 }
04933
04935
04936 void
04937 pdv_check(PdvDev * pdv_p)
04938 {
04939 int stat;
04940 int overrun;
04941
04942 stat = edt_reg_read(pdv_p, PDV_STAT);
04943 overrun = edt_ring_buffer_overrun(pdv_p);
04944 edt_msg(DBG2, "pdv_check() stat %x overrun %x\n",
04945 stat, overrun);
04946 if ((stat & PDV_OVERRUN) || overrun)
04947 {
04948 if (pdv_p->dd_p->continuous)
04949 pdv_stop_hardware_continuous(pdv_p);
04950
04951 pdv_flush_fifo(pdv_p);
04952
04953 pdv_multibuf(pdv_p, pdv_p->ring_buffer_numbufs);
04954
04955 if (pdv_p->dd_p->continuous)
04956 pdv_start_hardware_continuous(pdv_p);
04957 }
04958 }
04959
04960 void
04961 pdv_checkfrm(PdvDev * pdv_p, u_short * imagebuf, u_int imagesize, int verbose)
04962 {
04963 u_short *tmpp;
04964
04965 for (tmpp = (u_short *) imagebuf;
04966 tmpp < (u_short *) (&imagebuf[imagesize]); tmpp++)
04967 {
04968 if (*tmpp & 0xf000)
04969 {
04970 edt_msg(DBG2, "found start of image %x at %x %d\n",
04971 *tmpp >> 12,
04972 tmpp - (u_short *) imagebuf,
04973 tmpp - (u_short *) imagebuf);
04974 if (tmpp != imagebuf)
04975 {
04976 int curdone;
04977 int curtodo;
04978
04979 edt_reg_write(pdv_p, PDV_CMD, PDV_RESET_INTFC);
04980 pdv_flush_fifo(pdv_p);
04981 curdone = edt_done_count(pdv_p);
04982 curtodo = edt_get_todo(pdv_p);
04983 edt_msg(DBG2, "done %d todo %d\n", curdone, curtodo);
04984 {
04985 pdv_stop_continuous(pdv_p);
04986 edt_set_buffer(pdv_p, curdone);
04987 pdv_setup_continuous(pdv_p);
04988 pdv_start_images(pdv_p, pdv_p->ring_buffer_numbufs -
04989 (curtodo - curdone));
04990 }
04991 }
04992 break;
04993 }
04994 }
04995 }
04996
04997 u_char *
04998 pdv_get_interleave_data(PdvDev *pdv_p, u_char *buf)
04999
05000 {
05001 if (!pdv_process_inplace(pdv_p))
05002 {
05003 return buf + pdv_get_dmasize(pdv_p);
05004 }
05005 else
05006 return buf;
05007 }
05008
05009
05036 unsigned char *
05037 pdv_wait_images_raw(PdvDev * pdv_p, int count)
05038 {
05039 u_char *buf;
05040 Dependent *dd_p;
05041 static int last_timeout = 0;
05042
05043 edt_msg(DBG2, "pdv_wait_images_raw(%d)\n", count);
05044
05045 if (pdv_p == NULL || pdv_p->dd_p == NULL)
05046 return NULL;
05047
05048 dd_p = pdv_p->dd_p;
05049
05050 if (pdv_specinst_serial_triggered(pdv_p))
05051 pdv_posttrigger_specinst(pdv_p);
05052
05053 if (pdv_p->devid == DMY_ID)
05054 {
05055 u_char *buf;
05056 u_int *tmpp;
05057
05058 buf = edt_next_writebuf(pdv_p);
05059 tmpp = (u_int *) buf;
05060 if (*tmpp != 0xaabbccdd)
05061 {
05062 pdv_dmy_data(buf, dd_p->width, dd_p->height, dd_p->depth);
05063 }
05064 *tmpp = 0xaabbccdd;
05065 dd_p->last_image = buf;
05066 dd_p->last_raw = buf;
05067 if (dd_p->markras)
05068 pdv_mark_ras(buf, dd_p->rascnt, dd_p->width, dd_p->height,
05069 dd_p->markrasx, dd_p->markrasy);
05070 if (dd_p->markbin)
05071 pdv_mark_bin(buf, dd_p->rascnt, dd_p->width, dd_p->height, 4, 0);
05072
05073 if (dd_p->markbin || dd_p->markras) dd_p->rascnt++ ;
05074 return (buf);
05075 }
05076
05077
05078 last_timeout = edt_timeouts(pdv_p);
05079 buf = edt_wait_for_buffers(pdv_p, count);
05080
05081 return buf;
05082
05083
05084 }
05085
05086
05132 u_char *
05133 pdv_wait_images(PdvDev *pdv_p, int count)
05134
05135 {
05136 u_char *buf;
05137 u_char *retval;
05138 Dependent *dd_p;
05139
05140 edt_msg(DBG2, "pdv_wait_images(%d)\n", count);
05141
05142 if (pdv_p == NULL || pdv_p->dd_p == NULL)
05143 return NULL;
05144
05145 dd_p = pdv_p->dd_p;
05146
05147 if (dd_p->swinterlace)
05148 {
05149 pdv_alloc_tmpbuf(pdv_p);
05150 }
05151
05152 buf = pdv_wait_images_raw(pdv_p, count);
05153
05154 if (dd_p->swinterlace)
05155 {
05156
05157 if (!pdv_process_inplace(pdv_p))
05158 {
05159 retval = buf + pdv_get_dmasize(pdv_p);
05160 }
05161 else
05162 retval = buf;
05163
05164 pdv_deinterlace(pdv_p, dd_p, buf, retval);
05165
05166 dd_p->last_raw = buf;
05167 dd_p->last_image = retval;
05168 }
05169 else
05170 {
05171 retval = buf;
05172 dd_p->last_raw = buf;
05173 dd_p->last_image = buf;
05174 }
05175
05176
05177 if (pdv_p->devid != DMY_ID)
05178 {
05179 if (dd_p->markras)
05180 pdv_mark_ras(buf, dd_p->rascnt, dd_p->width, dd_p->height,
05181 dd_p->markrasx, dd_p->markrasy);
05182 if (dd_p->markbin)
05183 pdv_mark_bin(buf, dd_p->rascnt, dd_p->width, dd_p->height, 4, 0);
05184
05185 if (dd_p->markbin || dd_p->markras) dd_p->rascnt++ ;
05186 }
05187
05188
05189 return (retval);
05190 }
05191
05192 int
05193 pdv_slop(PdvDev * pdv_p)
05194 {
05195 return (pdv_p->dd_p->slop);
05196 }
05197
05198
05199 int
05200 pdv_set_slop(PdvDev * pdv_p, int slop)
05201 {
05202 edt_msg(DBG2, "pdv_set_slop()\n");
05203
05204 pdv_p->dd_p->slop = slop;
05205 return (0);
05206 }
05207
05208
05225 int
05226 pdv_get_header_size(PdvDev * pdv_p)
05227 {
05228 return (pdv_p->dd_p->header_size);
05229 }
05230
05253 int
05254 pdv_get_header_position(PdvDev * pdv_p)
05255 {
05256 return (pdv_p->dd_p->header_position);
05257 }
05258
05275 int
05276 pdv_get_header_offset(PdvDev * pdv_p)
05277 {
05278 switch (pdv_p->dd_p->header_position)
05279 {
05280 case PDV_HEADER_BEFORE:
05281 pdv_p->dd_p->header_offset = 0;
05282 break;
05283 case PDV_HEADER_AFTER:
05284 pdv_p->dd_p->header_offset = pdv_p->dd_p->imagesize;
05285 break;
05286
05287 }
05288
05289 return (pdv_p->dd_p->header_offset);
05290 }
05291
05300 int
05301 pdv_get_header_dma(PdvDev * pdv_p)
05302 {
05303 return (pdv_p->dd_p->header_dma);
05304 }
05305
05315 int
05316 pdv_extra_headersize(PdvDev * pdv_p)
05317
05318 {
05319 if (pdv_p->dd_p->header_size && (!pdv_p->dd_p->header_dma) &&
05320 (pdv_p->dd_p->header_position != PDV_HEADER_WITHIN))
05321 return pdv_p->dd_p->header_size;
05322
05323 return 0;
05324 }
05325
05335 void
05336 pdv_set_header_size(PdvDev * pdv_p, int header_size)
05337 {
05338 edt_msg(DBG2, "pdv_set_header_size()\n");
05339
05340 pdv_p->dd_p->header_size = header_size;
05341
05342 }
05343
05355 void
05356 pdv_set_header_position(PdvDev * pdv_p, int header_position)
05357
05358 {
05359 edt_msg(DBG2, "pdv_set_header_position(%d)\n", header_position);
05360
05361 pdv_p->dd_p->header_position = header_position;
05362 }
05363
05373 void
05374 pdv_set_header_dma(PdvDev * pdv_p, int header_dma)
05375 {
05376 edt_msg(DBG2, "pdv_set_header_dma(%d,%d)\n", header_dma);
05377
05378 pdv_p->dd_p->header_dma = header_dma;
05379 }
05380
05381
05388 void
05389 pdv_set_header_offset(PdvDev * pdv_p, int header_offset)
05390
05391 {
05392 edt_msg(DBG2, "pdv_set_header_offset(%d,%d)\n", header_offset);
05393
05394 pdv_p->dd_p->header_offset = header_offset;
05395 }
05396
05398
05423 int
05424 pdv_shutter_method(PdvDev * pdv_p)
05425 {
05426 edt_msg(DBG2, "pdv_shutter_method()\n");
05427
05428 return pdv_p->dd_p->camera_shutter_timing;
05429 }
05430
05438 void
05439 pdv_set_interlace(PdvDev * pdv_p, int interlace)
05440 {
05441 edt_msg(DBG2, "pdv_set_interlace()\n");
05442
05443 pdv_p->dd_p->swinterlace = interlace;
05444
05445 pdv_setup_postproc(pdv_p, pdv_p->dd_p, NULL);
05446
05447 }
05448
05506 pdv_interlace_method(PdvDev * pdv_p)
05507 {
05508 edt_msg(DBG2, "pdv_interlace_method()\n");
05509
05510 return pdv_p->dd_p->swinterlace;
05511 }
05512
05513
05530 int
05531 pdv_debug(int flag)
05532 {
05533 int oldval = Pdv_debug;
05534
05535 edt_msg(DBG2, "pdv_debug()\n");
05536
05537 Pdv_debug = flag;
05538 return (oldval);
05539 }
05540
05549 int
05550 pdv_debug_level()
05551 {
05552 return Pdv_debug;
05553 }
05554
05555
05567 int
05568 pdv_overrun(PdvDev * pdv_p)
05569 {
05570 int overrun;
05571
05572 edt_msg(DBG2, "pdv_overrun()\n");
05573
05574 if (pdv_p->devid == DMY_ID)
05575 return (0);
05576 edt_ioctl(pdv_p, EDTG_OVERFLOW, &overrun);
05577 return (overrun);
05578 }
05579
05598 int
05599 pdv_serial_wait(PdvDev * pdv_p, int msecs, int count)
05600 {
05601 edt_buf tmp;
05602 int ret;
05603
05604 if (msecs == 0)
05605 msecs = pdv_p->dd_p->serial_timeout;
05606
05607 tmp.desc = msecs;
05608 tmp.value = count;
05609 edt_ioctl(pdv_p, EDTS_SERIALWAIT, &tmp);
05610 ret = (int) tmp.value;
05611 edt_msg(DBG2, "pdv_serial_wait(%d, %d) %d\n", msecs, count, ret);
05612 return (ret);
05613 }
05614
05628 int
05629 pdv_serial_wait_next(EdtDev * pdv_p, int msecs, int count)
05630 {
05631 int ret;
05632 int newcount = count;
05633
05634 if (pdv_p->devid == PDVFOI_ID)
05635 {
05636 if (newcount)
05637 newcount += 2;
05638 ret = pdv_serial_wait(pdv_p, msecs, newcount);
05639 if (ret >= 2)
05640 ret -= 2;
05641 }
05642 else
05643 ret = pdv_serial_wait(pdv_p, msecs, count);
05644 return (ret);
05645 }
05646
05664 int
05665 pdv_set_waitchar(PdvDev * pdv_p, int enable, u_char wchar)
05666 {
05667 edt_buf tmp;
05668 int ret;
05669
05670
05671 tmp.desc = enable;
05672 tmp.value = wchar;
05673 ret = edt_ioctl(pdv_p, EDTS_WAITCHAR, &tmp);
05674 pdv_p->dd_p->serial_waitc = wchar;
05675 if (!enable)
05676 pdv_p->dd_p->serial_waitc |= 0x100;
05677 edt_msg(DBG2, "pdv_set_waitchar(%d, %02x) returns %d\n", enable, wchar, ret);
05678 return (ret);
05679 }
05680
05693 int
05694 pdv_get_waitchar(PdvDev * pdv_p, u_char *waitc)
05695 {
05696 int ret;
05697
05698 if (pdv_p->dd_p->serial_waitc & 0x100)
05699 {
05700 *waitc = pdv_p->dd_p->serial_waitc & 0xff;
05701 ret = 0;
05702 }
05703 else
05704 {
05705 *waitc = pdv_p->dd_p->serial_waitc;
05706 ret = 1;
05707 }
05708 return ret;
05709 }
05710
05711
05712 int
05713 pdv_get_fulldma_size(PdvDev *pdv_p, int *extrasizep)
05714
05715 {
05716 int size = pdv_get_imagesize(pdv_p);
05717
05718 int slop = pdv_slop(pdv_p);
05719 int extrasize;
05720 Dependent *dd_p = pdv_p->dd_p;
05721
05722 int header_before = (pdv_p->dd_p->header_position == PDV_HEADER_BEFORE);
05723
05724
05725 extrasize = slop + pdv_extra_headersize(pdv_p);
05726
05727 if (dd_p->swinterlace || size != pdv_get_dmasize(pdv_p))
05728 {
05729
05730
05731 if (!pdv_process_inplace(pdv_p) || size != pdv_get_dmasize(pdv_p))
05732 {
05733 int newsize = pdv_get_dmasize(pdv_p);
05734
05735 extrasize += size;
05736
05737
05738 size = newsize;
05739 }
05740 }
05741
05742 if (extrasizep)
05743 *extrasizep = extrasize;
05744
05745 return size;
05746 }
05747
05748 int
05749 pdv_total_block_size(PdvDev *pdv_p, int numbufs)
05750
05751 {
05752 int extrasize = 0;
05753 int size;
05754
05755 size = pdv_get_fulldma_size(pdv_p, &extrasize);
05756
05757
05758 size = edt_get_total_bufsize(pdv_p, size,extrasize) * numbufs;
05759
05760 return size;
05761
05762 }
05763
05764 int
05765 pdv_multibuf_block(PdvDev *pdv_p, int numbufs, u_char *block, int blocksize)
05766
05767 {
05768 int size;
05769
05770 int extrasize;
05771
05772 int ret;
05773 int header_before = (pdv_p->dd_p->header_position == PDV_HEADER_BEFORE);
05774
05775 size = pdv_get_fulldma_size(pdv_p, &extrasize);
05776
05777 pdv_setup_dma(pdv_p);
05778
05779 ret = edt_configure_block_buffers_mem(pdv_p,
05780 size,
05781 numbufs,
05782 EDT_READ,
05783 extrasize,
05784 header_before,
05785 block) ;
05786
05787
05788 return ret;
05789
05790 }
05791
05792 int
05793 pdv_multibuf_separate(PdvDev *pdv_p, int numbufs, u_char **buffers)
05794
05795 {
05796 int size = pdv_get_imagesize(pdv_p);
05797 int ret;
05798
05799 Dependent *dd_p = pdv_p->dd_p;
05800
05801 if (dd_p->swinterlace || size != pdv_get_dmasize(pdv_p))
05802 {
05803
05804
05805 if (!pdv_process_inplace(pdv_p) || size != pdv_get_dmasize(pdv_p))
05806 {
05807 edt_msg_perror(PDVFATAL,"Interlace not inplace fails for multibuf_separate\n");
05808 return -1;
05809 }
05810 }
05811
05812 size = pdv_get_fulldma_size(pdv_p, NULL);
05813
05814 pdv_setup_dma(pdv_p);
05815
05816 ret = edt_configure_ring_buffers(pdv_p, size, numbufs, EDT_READ, buffers) ;
05817
05818 return ret;
05819
05820 }
05821
05844 int
05845 pdv_multibuf(PdvDev * pdv_p, int numbufs)
05846 {
05847
05848
05849
05850
05851
05852 #if defined(XCALIBURCOMMON) || defined(VMIC)
05853 return pdv_multibuf_separate(pdv_p, numbufs,NULL);
05854 #else
05855 return pdv_multibuf_block(pdv_p, numbufs, NULL, 0);
05856 #endif
05857
05858 }
05859
05893 int
05894 pdv_set_buffers(PdvDev * pdv_p, int numbufs, unsigned char **bufarray)
05895 {
05896
05897 int size = pdv_get_dmasize(pdv_p);
05898
05899 edt_msg(DBG2, "pdv_set_buffers(%d %x) (size %d)\n", numbufs, bufarray, size);
05900
05901 pdv_setup_dma(pdv_p);
05902
05903 return (edt_configure_ring_buffers(pdv_p, size, numbufs, EDT_READ, bufarray));
05904 }
05905
05906
05907 int
05908 pdv_set_buffers_x(PdvDev * pdv_p, int numbufs, int size, unsigned char **bufs)
05909 {
05910
05911 edt_msg(DBG2, "pdv_set_buffers(%d %x) (size %d)\n", numbufs, bufs, size);
05912
05913 pdv_setup_dma(pdv_p);
05914
05915 return (edt_configure_ring_buffers(pdv_p, size, numbufs, EDT_READ, bufs));
05916 }
05917
05918
05933 int
05934 pdv_image_size(PdvDev * pdv_p)
05935 {
05936 int size;
05937
05938 size = pdv_p->dd_p->imagesize;
05939
05940 if (pdv_p->dd_p->slop)
05941 {
05942
05943 edt_msg(DBG2, "pdv_image_size: adjusting size %x by slop %x to %x\n",
05944 size, pdv_p->dd_p->slop, size - pdv_p->dd_p->slop);
05945
05946 size -= pdv_p->dd_p->slop;
05947
05948 }
05949
05950 if (pdv_p->dd_p->header_dma)
05951 size += pdv_p->dd_p->header_size;
05952
05953 edt_msg(DBG2, "pdv_image_size() %d\n", size);
05954
05955 return size;
05956
05957 }
05958
05959
05973 u_char *
05974 pdv_get_last_image(PdvDev * pdv_p)
05975 {
05976 edt_msg(DBG2, "pdv_get_last_image()\n");
05977
05978 return (pdv_p->dd_p->last_image);
05979 }
05980
05995 u_char *
05996 pdv_get_last_raw(PdvDev * pdv_p)
05997 {
05998 edt_msg(DBG2, "pdv_get_last_raw()\n");
05999
06000 return (pdv_p->dd_p->last_raw);
06001 }
06002
06015 u_char **
06016 pdv_buffer_addresses(PdvDev * pdv_p)
06017 {
06018
06019 return (pdv_p->ring_buffers);
06020 }
06021
06047 void
06048 pdv_start_hardware_continuous(PdvDev * pdv_p )
06049 {
06050 int data_path;
06051
06052
06053 data_path = pdv_p->dd_p->datapath_reg & ~PDV_CONTINUOUS;
06054
06055 edt_msg(DBG2, "pdv_start_hardware_continuous()\n");
06056
06057 if (pdv_p->devid == PDVFOI_ID)
06058 {
06059 char tmpbuf[10];
06060 int ret;
06061
06062 ret = pdv_serial_wait(pdv_p, 100, 0);
06063 if (ret > 10)
06064 pdv_reset_serial(pdv_p);
06065 else
06066 pdv_serial_read(pdv_p, tmpbuf, ret);
06067
06068 }
06069
06070 if (pdv_p->devid == PDVFOI_ID)
06071 {
06072 char tmpbuf[10];
06073 int ret;
06074
06075 ret = pdv_serial_wait(pdv_p, 100, 0);
06076 if (ret > 10)
06077 pdv_reset_serial(pdv_p);
06078 else
06079 pdv_serial_read(pdv_p, tmpbuf, ret);
06080
06081 }
06082 edt_reg_write(pdv_p, PDV_DATA_PATH, data_path | PDV_CONTINUOUS);
06083 pdv_p->dd_p->datapath_reg = data_path;
06084 }
06085
06086
06096 void
06097 pdv_stop_hardware_continuous(PdvDev * pdv_p)
06098 {
06099 int data_path;
06100
06101
06102 data_path = pdv_p->dd_p->datapath_reg;
06103 edt_msg(DBG2, "pdv_stop_hardware_continuous()\n");
06104 data_path &= ~PDV_CONTINUOUS;
06105 edt_reg_write(pdv_p, PDV_DATA_PATH, data_path);
06106 pdv_p->dd_p->datapath_reg = data_path;
06107
06108 if (pdv_p->devid == PDVFOI_ID)
06109 {
06110 edt_reg_write(pdv_p,FOI_WR_MSG_STAT, FOI_FIFO_FLUSH);
06111 }
06112
06113 }
06114
06125 int
06126 pdv_set_serial_parity(PdvDev * pdv_p, char parity)
06127 {
06128 if (pdv_p->devid == PDVAERO_ID)
06129 {
06130 int val = 0;
06131 switch(parity)
06132 {
06133
06134 case 'e':
06135 val = 1;
06136 break;
06137 case 'o':
06138 val = 3;
06139 break;
06140 case 'n':
06141 val = 0;
06142 break;
06143 default:
06144 edt_msg(DBG1, "parity must be e, o, or n");
06145 return -1;
06146 }
06147
06148 edt_reg_write(pdv_p,PDV_SERIAL_PARITY,val);
06149 return 0;
06150 }
06151 else
06152 {
06153 edt_msg(DBG1,"parity not an option for this board");
06154 }
06155 return -1;
06156 }
06157
06173 pdv_set_baud(PdvDev * pdv_p, int baud)
06174 {
06175 Dependent *dd_p = pdv_p->dd_p;
06176 u_int baudbits = 0;
06177 int id=pdv_p->devid;
06178 u_int new, baudreg;
06179 u_int cntl;
06180 int donew = 0;
06181 int ret = 0;
06182
06183 if (dd_p->xilinx_rev < 2 || dd_p->xilinx_rev > 32)
06184 {
06185 edt_msg(DBG2, "pdv_set_baud() warning: can't enable, N/A this xilinx (%x)\n",
06186 pdv_p->dd_p->xilinx_rev);
06187 return -1;
06188 }
06189
06190 if (edt_is_dvcl(pdv_p) || edt_is_dvfox(pdv_p) || (id == PDVA_ID))
06191 donew = 1;
06192
06193 switch (baud)
06194 {
06195 case 9600:
06196 baudbits = 0;
06197 baudreg = 0x80;
06198 break;
06199
06200 case 19200:
06201 baudbits = PDV_BAUD0;
06202 baudreg = 0x3f;
06203 break;
06204
06205 case 38400:
06206 baudbits = PDV_BAUD1;
06207 baudreg = 0x1f;
06208 break;
06209
06210 case 115200:
06211 baudbits = PDV_BAUD0 | PDV_BAUD1;
06212 baudreg = 0x09;
06213 break;
06214
06215 case 57600:
06216 baudbits = PDV_BAUD0 | PDV_BAUD1;
06217 donew = 1;
06218 baudreg = 0x014;
06219 break;
06220
06221 default:
06222 donew = 1;
06223 baudreg = (unsigned int)(((20000000.0 / (16.0 * (double)baud)) - 2.0) + 0.5) ;
06224 edt_msg(DBG2, "pdv_set_baud(%d) using new method, reg %02x\n", baud, baudreg);
06225 break;
06226 }
06227
06228 if (donew && (!dd_p->register_wrap))
06229 {
06230 if (baudreg > 0xff)
06231 {
06232 edt_msg(DBG2, "pdv_set_baud(%d) (baudreg %x) BAD VALUE not set\n", baud, baudreg);
06233 ret = -1;
06234 }
06235 else
06236 {
06237 edt_msg(DBG2, "pdv_set_baud(%d) (baudreg %x) using NEW baud reg\n", baud, baudreg);
06238 edt_reg_write(pdv_p, PDV_BRATE, baudreg);
06239 new = edt_reg_read(pdv_p, PDV_BRATE);
06240 if (new != baudreg)
06241 {
06242 edt_msg(DBG2, "pdv_set_baud(%d) (baudreg %x) readback ERROR\n", baud, baudreg);
06243 ret = -1;
06244 }
06245 }
06246 }
06247
06248 else
06249 {
06250 edt_msg(DBG2, "pdv_set_baud(%d) (baudbits %x) using OLD baud bits\n", baud, baudbits);
06251 cntl = edt_reg_read(pdv_p, PDV_SERIAL_DATA_CNTL);
06252 cntl &= ~PDV_BAUD_MASK;
06253 cntl |= baudbits;
06254 edt_reg_write(pdv_p, PDV_SERIAL_DATA_CNTL, cntl);
06255 }
06256
06257 return ret;
06258 }
06259
06268 int
06269 pdv_get_baud(PdvDev * pdv_p)
06270 {
06271 u_int baudbits;
06272 int ret = 0;
06273
06274 if (pdv_p->dd_p->xilinx_rev < 2 || pdv_p->dd_p->xilinx_rev > 32)
06275 {
06276 edt_msg(DBG2, "pdv_set_baud() WARNING: can't enable, N/A this xilinx (%x)\n",
06277 pdv_p->dd_p->xilinx_rev);
06278 return -1;
06279 }
06280
06281 baudbits = edt_reg_read(pdv_p, PDV_SERIAL_DATA_CNTL) & PDV_BAUD_MASK;
06282
06283 switch (baudbits)
06284 {
06285 case 0:
06286 return 9600;
06287
06288 case PDV_BAUD0:
06289 return 19200;
06290
06291 case PDV_BAUD1:
06292 return 38400;
06293
06294 case PDV_BAUD0 | PDV_BAUD1:
06295 return 115200;
06296
06297 default:
06298 edt_msg(DBG2, "ERROR: pdv_get_baud(%d) -- invalid bits???\n", baudbits);
06299 return 0;
06300 }
06301 }
06302
06318 void
06319 pdv_perror(char *err)
06320 {
06321 edt_perror(err);
06322 }
06323
06324 void
06325 pdv_setdebug(PdvDev * pdv_p, int debug)
06326 {
06327 Pdv_debug = debug;
06328 }
06329
06330
06331
06332
06333
06346 void
06347 pdv_reset_serial(PdvDev * pdv_p)
06348 {
06349 edt_reset_serial(pdv_p);
06350 }
06351
06352
06373 uchar_t *
06374 pdv_alloc(int size)
06375 {
06376 return edt_alloc(size);
06377 }
06378
06379
06386 void
06387 pdv_free(uchar_t * ptr)
06388 {
06389 edt_free(ptr);
06390 }
06391
06392
06393
06394 static u_short zero[] = {
06395 0x0F80,
06396 0x3FE0,
06397 0x38E0,
06398 0x7070,
06399 0x6030,
06400 0xE038,
06401 0xE038,
06402 0xE038,
06403 0xE038,
06404 0xE038,
06405 0xE038,
06406 0xE038,
06407 0x6030,
06408 0x7070,
06409 0x38E0,
06410 0x3FE0,
06411 0x0F80,
06412 };
06413 static u_short one[] = {
06414 0xFC00,
06415 0xFC00,
06416 0x1C00,
06417 0x1C00,
06418 0x1C00,
06419 0x1C00,
06420 0x1C00,
06421 0x1C00,
06422 0x1C00,
06423 0x1C00,
06424 0x1C00,
06425 0x1C00,
06426 0x1C00,
06427 0x1C00,
06428 0x1C00,
06429 0xFF80,
06430 0xFF80,
06431 };
06432 static u_short two[] = {
06433 0x7E00,
06434 0x7F80,
06435 0x4380,
06436 0x01C0,
06437 0x01C0,
06438 0x01C0,
06439 0x01C0,
06440 0x0380,
06441 0x0700,
06442 0x0E00,
06443 0x1C00,
06444 0x3800,
06445 0x3800,
06446 0x7000,
06447 0xE000,
06448 0xFFC0,
06449 0xFFC0,
06450 };
06451 static u_short three[] = {
06452 0x7E00,
06453 0xFF00,
06454 0x8780,
06455 0x0380,
06456 0x0380,
06457 0x0380,
06458 0x0F00,
06459 0x7C00,
06460 0x7E00,
06461 0x0F00,
06462 0x0380,
06463 0x0380,
06464 0x0380,
06465 0x0380,
06466 0x8700,
06467 0xFF00,
06468 0xFC00,
06469 };
06470 static u_short four[] = {
06471 0x0380,
06472 0x0780,
06473 0x0F80,
06474 0x0F80,
06475 0x1F80,
06476 0x1B80,
06477 0x3380,
06478 0x3380,
06479 0x6380,
06480 0xE380,
06481 0xFFE0,
06482 0xFFE0,
06483 0xFFE0,
06484 0x0380,
06485 0x0380,
06486 0x0380,
06487 0x0380,
06488 };
06489 static u_short five[] = {
06490 0xFF80,
06491 0xFF80,
06492 0xE000,
06493 0xE000,
06494 0xE000,
06495 0xC000,
06496 0xF800,
06497 0xFE00,
06498 0x0F00,
06499 0x0780,
06500 0x0380,
06501 0x0380,
06502 0x0380,
06503 0x0380,
06504 0x8700,
06505 0xFE00,
06506 0xFC00,
06507 };
06508 static u_short six[] = {
06509 0x07E0,
06510 0x1FE0,
06511 0x3C20,
06512 0x7000,
06513 0x7000,
06514 0xE000,
06515 0xE780,
06516 0xFFE0,
06517 0xF0E0,
06518 0xE070,
06519 0xE070,
06520 0xE070,
06521 0xE070,
06522 0x7070,
06523 0x70E0,
06524 0x3FC0,
06525 0x0F80,
06526 };
06527 static u_short seven[] = {
06528 0xFFC0,
06529 0xFFC0,
06530 0x01C0,
06531 0x0180,
06532 0x0380,
06533 0x0700,
06534 0x0700,
06535 0x0E00,
06536 0x0C00,
06537 0x1C00,
06538 0x1800,
06539 0x3800,
06540 0x3800,
06541 0x3000,
06542 0x7000,
06543 0x7000,
06544 0x7000,
06545 };
06546 static u_short eight[] = {
06547 0x0F80,
06548 0x3FC0,
06549 0x71E0,
06550 0x70E0,
06551 0x70E0,
06552 0x7DE0,
06553 0x3FC0,
06554 0x1F00,
06555 0x1FC0,
06556 0x7FE0,
06557 0xF1F0,
06558 0xE0F0,
06559 0xE070,
06560 0xE070,
06561 0xF0E0,
06562 0x7FE0,
06563 0x1F80,
06564 };
06565 static u_short nine[] = {
06566 0x1F00,
06567 0x3FC0,
06568 0x70E0,
06569 0xE0E0,
06570 0xE070,
06571 0xE070,
06572 0xE070,
06573 0xE070,
06574 0x70F0,
06575 0x7FF0,
06576 0x1E70,
06577 0x0070,
06578 0x00E0,
06579 0x00E0,
06580 0x43C0,
06581 0x7F80,
06582 0x7E00,
06583 };
06584
06585 static u_short *digits[] = {
06586 zero,
06587 one,
06588 two,
06589 three,
06590 four,
06591 five,
06592 six,
06593 seven,
06594 eight,
06595 nine,
06596 };
06597
06598
06599
06600 static void
06601 set_square(int sx, int sy, u_short * buf, u_char * addr, int stride)
06602 {
06603
06604
06605
06606 #define FG 200
06607 #define BG 0
06608
06609
06610
06611
06612 register u_char *svptr;
06613 register u_char *ptr;
06614 int i;
06615 int bit;
06616 u_short tmp;
06617 int val;
06618
06619 svptr = addr + (stride * sy) + (sx);
06620
06621 for (i = 0; i < 17; i++)
06622 {
06623 ptr = svptr;
06624 tmp = *buf++;
06625 for (bit = 15; bit >= 0; bit--)
06626 {
06627 if (tmp & (1 << bit))
06628 {
06629 val = FG;
06630 }
06631 else
06632 {
06633 val = BG;
06634 }
06635 *ptr++ = val;
06636 }
06637 svptr += stride;
06638 }
06639 }
06640
06641
06642 void
06643 pdv_mark_ras(u_char * addr, int n, int width, int height, int x, int y)
06644 {
06645 #define GAP 16
06646 set_square(x, y, digits[n / 1000000], addr, width);
06647 n %= 1000000;
06648 set_square(x + GAP, y, digits[n / 100000], addr, width);
06649 n %= 100000;
06650 set_square(x + (GAP * 2), y, digits[n / 10000], addr, width);
06651 n %= 10000;
06652 set_square(x + (GAP * 3), y, digits[n / 1000], addr, width);
06653 n %= 1000;
06654 set_square(x + (GAP * 4), y, digits[n / 100], addr, width);
06655 n %= 100;
06656 set_square(x + (GAP * 5), y, digits[n / 10], addr, width);
06657 n %= 10;
06658 set_square(x + (GAP * 6), y, digits[n], addr, width);
06659 }
06660
06661 void
06662 pdv_mark_bin(u_char * addr, int n, int width, int height, int x, int y)
06663 {
06664 u_int val = n;
06665 u_char *svptr;
06666
06667 svptr = (u_char *) addr + (width * y) + x;
06668 *svptr++ = (val >> 24) & 0xff;
06669 *svptr++ = (val >> 16) & 0xff;
06670 *svptr++ = (val >> 8) & 0xff;
06671 *svptr++ = val & 0xff;
06672 }
06673
06691 int
06692 pdv_serial_command_hex(PdvDev * pdv_p, char *str, int length)
06693 {
06694 char buf[2];
06695 char *p = &str[2];
06696 u_int lval;
06697
06698 sscanf(p, "%x", &lval);
06699 buf[0] = (char) (lval & 0xff);
06700 edt_msg(DBG2, "pdv_serial_command_hex(%s),0x%x\n", str, (u_char) (buf[0]));
06701
06702 return pdv_serial_binary_command(pdv_p, buf, 1);
06703 }
06704
06740 int
06741 pdv_set_roi(PdvDev * pdv_p, int hskip, int hactv, int vskip, int vactv)
06742 {
06743 Dependent *dd_p = pdv_p->dd_p;
06744 int cam_w, cam_h;
06745
06746 edt_msg(DBG2, "pdv_set_roi(hskip %d hactv %d vskip %d vactv %d)\n",
06747 hskip, hactv, vskip, vactv);
06748
06749
06750
06751
06752 if (dd_p->xilinx_rev < 2 || dd_p->xilinx_rev > 32)
06753 {
06754 edt_msg(DBG2, "pdv_set_roi(): WARNING: can't enable, N/A this xilinx (%x)\n",
06755 dd_p->xilinx_rev);
06756 return -1;
06757 }
06758
06759 cam_w = pdv_get_cam_width(pdv_p);
06760 cam_h = pdv_get_cam_height(pdv_p);
06761
06762
06763 if (!pdv_is_cameralink(pdv_p))
06764 {
06765 if ((cam_w && ((hskip + hactv) > cam_w)) || ((hskip + hactv) <= 0))
06766 {
06767 edt_msg(DBG2, "ROI: horiz. skip/actv out of range error\n");
06768 return -1;
06769 }
06770 if ((cam_h && ((vskip + vactv) > cam_h)) || ((vskip + vactv) <= 0))
06771 {
06772 edt_msg(DBG2, "ROI: vert. skip/actv out of range error\n");
06773 return -1;
06774 }
06775 }
06776
06777
06778 if (pdv_is_cameralink(pdv_p))
06779 {
06780
06781
06782
06783 if (dd_p->htaps > 0)
06784 {
06785 hactv = (hactv / dd_p->htaps) * dd_p->htaps;
06786 hskip = (hskip / dd_p->htaps) * dd_p->htaps;
06787 }
06788 vactv = (vactv / dd_p->vtaps) * dd_p->vtaps;
06789 vskip = (vskip / dd_p->vtaps) * dd_p->vtaps;
06790
06791
06792 if (dd_p->htaps > 0)
06793 {
06794
06795 edt_reg_write(pdv_p, PDV_HSKIP, (hskip / dd_p->htaps));
06796 edt_reg_write(pdv_p, PDV_HACTV, (hactv / dd_p->htaps) - 1);
06797 }
06798 else
06799 {
06800 edt_reg_write(pdv_p, PDV_HSKIP, (hskip * -dd_p->htaps));
06801 edt_reg_write(pdv_p, PDV_HACTV, (hactv * -dd_p->htaps) - 1);
06802 }
06803
06804 edt_reg_write(pdv_p, PDV_VSKIP, (vskip / dd_p->vtaps));
06805 edt_reg_write(pdv_p, PDV_VACTV, (vactv / dd_p->vtaps) - 1);
06806 }
06807 else if (dd_p->dual_channel)
06808 {
06809 vactv = (vactv / 2) * 2;
06810 vskip = (vskip / 2) * 2;
06811 edt_reg_write(pdv_p, PDV_VSKIP, (vskip / 2));
06812 edt_reg_write(pdv_p, PDV_HSKIP, hskip);
06813 edt_reg_write(pdv_p, PDV_VACTV, (vactv / 2) - 1);
06814 edt_reg_write(pdv_p, PDV_HACTV, hactv - 1);
06815 }
06816 else
06817 {
06818 edt_reg_write(pdv_p, PDV_HSKIP, hskip);
06819 edt_reg_write(pdv_p, PDV_VSKIP, vskip);
06820 edt_reg_write(pdv_p, PDV_HACTV, hactv - 1);
06821 edt_reg_write(pdv_p, PDV_VACTV, vactv - 1);
06822 }
06823
06824 dd_p->hactv = hactv;
06825 dd_p->hskip = hskip;
06826 dd_p->vactv = vactv;
06827 dd_p->vskip = vskip;
06828
06829 if (dd_p->roi_enabled)
06830 pdv_setsize(pdv_p, dd_p->hactv, dd_p->vactv);
06831
06832 edt_set_dependent(pdv_p, dd_p);
06833
06834 return 0;
06835
06836 }
06837
06838
06839 void
06840 pdv_cl_set_base_channels(PdvDev *pdv_p, int htaps, int vtaps)
06841
06842 {
06843 Dependent *dd_p = pdv_p->dd_p;
06844 int taps = (htaps > vtaps)? htaps : vtaps;
06845
06846 dd_p->cl_data_path = (taps - 1) << 4 | (dd_p->depth - 1);
06847
06848 dd_p->htaps = htaps;
06849 dd_p->vtaps = vtaps;
06850
06851 edt_reg_write(pdv_p, PDV_CL_DATA_PATH, dd_p->cl_data_path);
06852
06853 edt_set_dependent(pdv_p, dd_p);
06854
06855 pdv_set_roi(pdv_p, dd_p->hskip, dd_p->hactv, dd_p->vskip, dd_p->vactv);
06856 }
06857
06858
06859
06860
06861
06862
06863
06864
06865 int
06866 pdv_dalsa_ls_set_expose(PdvDev * pdv_p, int hskip, int hactv)
06867 {
06868 Dependent *dd_p = pdv_p->dd_p;
06869
06870 edt_msg(DBG2, "pdv_dalsa_ls_set_expose(hskip %d hactv %d)\n", hskip, hactv);
06871
06872
06873
06874
06875 if (dd_p->xilinx_rev < 2 || dd_p->xilinx_rev > 32)
06876 {
06877 edt_msg(DBG2, "pdv_dalsa_ls_set_expose(): WARNING: can't enable, N/A this xilinx (%x)\n", dd_p->xilinx_rev);
06878 return -1;
06879 }
06880
06881 edt_reg_write(pdv_p, PDV_HSKIP, hskip);
06882 edt_reg_write(pdv_p, PDV_HACTV, hactv - 1);
06883
06884 dd_p->hactv = hactv;
06885 dd_p->hskip = hskip;
06886
06887 edt_set_dependent(pdv_p, dd_p);
06888 pdv_enable_roi(pdv_p, 1);
06889
06890 return 0;
06891
06892 }
06893
06894
06903 int
06904 pdv_auto_set_roi(PdvDev * pdv_p)
06905 {
06906 int w = pdv_p->dd_p->width;
06907 int h = pdv_p->dd_p->height;
06908 int ret;
06909
06910 edt_msg(DBG2, "pdv_auto_set_roi()\n");
06911
06912 if ((ret = pdv_set_roi(pdv_p, 0, w, 0, h)) == 0)
06913 {
06914 if (pdv_is_cameralink(pdv_p))
06915 pdv_setsize(pdv_p, pdv_p->dd_p->hactv, pdv_p->dd_p->vactv);
06916 ret = pdv_enable_roi(pdv_p, 1);
06917 }
06918
06919 return ret;
06920 }
06921
06939 int
06940 pdv_enable_roi(PdvDev * pdv_p, int flag)
06941 {
06942 u_int roictl;
06943 Dependent *dd_p = pdv_p->dd_p;
06944
06945
06946 if (pdv_is_cameralink(pdv_p))
06947 {
06948 if (flag)
06949 {
06950 edt_reg_and(pdv_p, PDV_CL_CFG, ~0x08);
06951 pdv_setsize(pdv_p, dd_p->hactv, dd_p->vactv);
06952 }
06953 else
06954 {
06955 edt_reg_or(pdv_p, PDV_CL_CFG, 0x08);
06956 pdv_setsize(pdv_p, dd_p->cam_width, dd_p->cam_height);
06957 }
06958
06959 dd_p->roi_enabled = flag;
06960
06961 return 0;
06962 }
06963
06964 if (dd_p->xilinx_rev < 2 || dd_p->xilinx_rev > 32)
06965 {
06966 edt_msg(DBG2, "pdv_enable_roi(): can't enable, N/A this xilinx (%x)\n", dd_p->xilinx_rev);
06967 return -1;
06968 }
06969
06970 edt_msg(DBG2, "pdv_enable_roi(%d): %sabling\n", flag, flag ? "EN" : "DIS");
06971
06972
06973
06974 roictl = edt_reg_read(pdv_p, PDV_ROICTL);
06975
06976
06977 if (flag)
06978 {
06979 roictl |= PDV_ROICTL_ROI_EN;
06980 edt_reg_write(pdv_p, PDV_ROICTL, roictl);
06981 pdv_setsize(pdv_p, dd_p->hactv, dd_p->vactv);
06982 }
06983 else
06984 {
06985
06986 roictl &= ~PDV_ROICTL_ROI_EN;
06987 edt_reg_write(pdv_p, PDV_ROICTL, roictl);
06988 pdv_setsize(pdv_p, dd_p->cam_width, dd_p->cam_height);
06989 }
06990
06991 dd_p->roi_enabled = flag;
06992
06993 return 0;
06994 }
06995
07015 int
07016 pdv_access(char *fname, int perm)
07017 {
07018 return edt_access(fname, perm);
07019 }
07020
07021
07045 int
07046 pdv_strobe(PdvDev * pdv_p, int count, int delay)
07047 {
07048 Dependent *dd_p = pdv_p->dd_p;
07049
07050 if (pdv_strobe_method(pdv_p) != PDV_LHS_METHOD1)
07051 return -1;
07052
07053 edt_msg(DBG2, "pdv_strobe(%d %d)\n", count, delay);
07054
07055 edt_reg_write(pdv_p, PDV_SHUTTER, delay);
07056
07057
07058
07059
07060
07061 edt_reg_write(pdv_p, PDV_FIXEDLEN, count);
07062
07063 return 0;
07064 }
07065
07086 int
07087 pdv_set_strobe_counters(PdvDev * pdv_p, int count, int delay, int period)
07088 {
07089 Dependent *dd_p = pdv_p->dd_p;
07090
07091 if (pdv_strobe_method(pdv_p) != PDV_LHS_METHOD2)
07092 return -1;
07093
07094 if (count > 0xfff)
07095 {
07096 edt_msg(DBG1, "pdv_set_strobe_counters() ERROR -- count out of range\n");
07097 return -1;
07098 }
07099
07100 if (delay > 0xff)
07101 {
07102 edt_msg(PDVWARN, "pdv_set_strobe_counters() ERROR -- delay out of range\n");
07103 return -1;
07104 }
07105
07106 if (period > 0xff)
07107 {
07108 edt_msg(PDVWARN, "pdv_set_strobe_counters() ERROR -- period out of range\n");
07109 return -1;
07110 }
07111
07112 edt_msg(DBG2, "pdv_set_strobe_counters(%d %d %d)\n", count, delay, period);
07113
07114 edt_reg_write(pdv_p, PDV_LHS_DELAY, delay);
07115
07116 edt_reg_write(pdv_p, PDV_LHS_PERIOD, period);
07117
07118
07119
07120
07121 edt_reg_write(pdv_p, PDV_LHS_COUNT, count);
07122
07123 return 0;
07124 }
07125
07137 int
07138 pdv_enable_strobe(PdvDev * pdv_p, int ena)
07139 {
07140 int method = pdv_strobe_method(pdv_p);
07141
07142 if (pdv_p->devid == PDVFOI_ID)
07143 return -1;
07144
07145 if (method == 0)
07146 return -1;
07147
07148 if (method == PDV_LHS_METHOD1)
07149 {
07150 if (ena == 0)
07151 return -1;
07152 return 0;
07153 }
07154
07155 if (ena)
07156 edt_reg_write(pdv_p, PDV_LHS_CONTROL, PDV_LHS_ENABLE);
07157 else edt_reg_write(pdv_p, PDV_LHS_CONTROL, 0);
07158
07159 return 0;
07160 }
07161
07172 int
07173 pdv_strobe_method(PdvDev *pdv_p)
07174 {
07175 Dependent *dd_p = pdv_p->dd_p;
07176
07177 if (dd_p->strobe_enabled == NOT_SET)
07178 {
07179 int reg ;
07180
07181
07182 dd_p->strobe_enabled = 0;
07183
07184 if (pdv_p->devid == PDVFOI_ID)
07185 return 0;
07186
07187
07188
07189 if (pdv_p->devid == PDVCL_ID)
07190 {
07191 dd_p->strobe_enabled = PDV_LHS_METHOD2;
07192 return dd_p->strobe_enabled;
07193 }
07194
07195
07196 if (dd_p->xilinx_rev < 2 || dd_p->xilinx_rev > 32)
07197 return 0;
07198
07199
07200
07201
07202 if (!dd_p->register_wrap)
07203 {
07204 reg = edt_reg_read(pdv_p, PDV_LHS_COUNT_HI);
07205 edt_reg_write(pdv_p, PDV_LHS_COUNT_HI, 0x50);
07206 if (edt_reg_read(pdv_p, PDV_LHS_COUNT_HI) == 0x50)
07207 {
07208 edt_reg_write(pdv_p, PDV_LHS_COUNT_HI, reg);
07209 dd_p->strobe_enabled = PDV_LHS_METHOD2;
07210 return dd_p->strobe_enabled;
07211 }
07212 }
07213
07214
07215 if (pdv_p->devid != PDVFOI_ID)
07216 {
07217 int status = edt_reg_read(pdv_p, PDV_SERIAL_DATA_STAT);
07218
07219 if (status & LHS_DONE)
07220 dd_p->strobe_enabled = PDV_LHS_METHOD1;
07221 }
07222 }
07223
07224 return dd_p->strobe_enabled;
07225 }
07226
07227
07247 pdv_set_strobe_dac(PdvDev * pdv_p, u_int value)
07248 {
07249 int i;
07250 int reg;
07251 int method;
07252 u_int mcl, mask;
07253 u_char data;
07254 Dependent *dd_p = pdv_p->dd_p;
07255
07256 if ((method = pdv_strobe_method(pdv_p)) == 0)
07257 return -1;
07258
07259 if (method == PDV_LHS_METHOD2)
07260 reg = PDV_LHS_CONTROL;
07261 else reg = PDV_MODE_CNTL;
07262
07263 edt_msg(DBG2, "pdv_strobe(%d)\n", value);
07264
07265 mcl = edt_reg_read(pdv_p, reg) & 0x0f;
07266
07267
07268
07269
07270
07271 edt_reg_write(pdv_p, reg, mcl | PDV_LHS_DAC_LOAD);
07272
07273
07274
07275
07276 for (i = 0; i < 16; i++)
07277 {
07278 mask = (value & (1 << (15 - i)));
07279
07280 if (mask)
07281 data = PDV_LHS_DAC_DATA;
07282 else
07283 data = 0;
07284
07285 edt_reg_write(pdv_p, reg, mcl | PDV_LHS_DAC_LOAD | data);
07286 edt_reg_write(pdv_p, reg, mcl | PDV_LHS_DAC_LOAD | PDV_LHS_DAC_CLOCK | data);
07287 edt_reg_write(pdv_p, reg, mcl | PDV_LHS_DAC_LOAD | data);
07288 edt_reg_write(pdv_p, reg, mcl | PDV_LHS_DAC_LOAD);
07289 }
07290
07291 edt_reg_write(pdv_p, reg, mcl &~ PDV_LHS_DAC_LOAD);
07292 return 0;
07293 }
07294
07302 void
07303 pdv_flush_channel_fifo(PdvDev * pdv_p)
07304 {
07305
07306
07307
07308
07309 pdv_flush_fifo(pdv_p);
07310 }
07311
07318 void
07319 pdv_flush_fifo(PdvDev * pdv_p)
07320 {
07321
07322 if (pdv_p->devid == PDV_ID ||
07323 pdv_p->devid == PDVK_ID ||
07324 pdv_p->devid == PDVFOI_ID ||
07325 pdv_p->devid == PDVA_ID)
07326 {
07327 edt_flush_fifo(pdv_p);
07328 return;
07329 }
07330
07331 if (pdv_p->devid == PDVCL_ID)
07332 {
07333
07334
07335
07336 u_int cfg ;
07337 cfg = edt_intfc_read(pdv_p, PDV_CFG);
07338 cfg &= ~PDV_FIFO_RESET;
07339 edt_intfc_write(pdv_p, PDV_CFG, (u_char) (cfg | PDV_FIFO_RESET));
07340 edt_intfc_write(pdv_p, PDV_CMD, PDV_RESET_INTFC);
07341 edt_intfc_write(pdv_p, PDV_CFG, cfg);
07342 }
07343 else if (pdv_p->devid == PDVFOI_ID)
07344 {
07345 char tmpbuf[10];
07346 int ret;
07347
07348 ret = pdv_serial_wait(pdv_p, 100, 0);
07349 if (ret > 10)
07350 pdv_reset_serial(pdv_p);
07351 else
07352 pdv_serial_read(pdv_p, tmpbuf, ret);
07353 }
07354 else
07355 {
07356
07357
07358 u_int cfg ;
07359 cfg = edt_intfc_read(pdv_p, PDV_CFG);
07360 cfg &= ~PDV_FIFO_RESET;
07361 edt_intfc_write(pdv_p, PDV_CFG, (u_char) (cfg | PDV_FIFO_RESET));
07362 edt_flush_channel(pdv_p, pdv_p->channel_no);
07363 edt_intfc_write(pdv_p, PDV_CFG, cfg);
07364 }
07365 }
07366
07370 void
07371 pdv_setup_continuous_channel(PdvDev * pdv_p)
07372
07373 {
07374
07375
07376 pdv_setup_continuous(pdv_p);
07377 }
07378
07387 void
07388 pdv_setup_continuous(PdvDev * pdv_p)
07389 {
07390 pdv_flush_fifo(pdv_p);
07391
07392 if (pdv_p->devid == PDV_ID ||
07393 pdv_p->devid == PDVK_ID ||
07394 pdv_p->devid == PDVA_ID)
07395 {
07396
07397 if (edt_get_firstflush(pdv_p) != EDT_ACT_KBS)
07398 edt_set_firstflush(pdv_p, EDT_ACT_ONCE);
07399 }
07400 else
07401 {
07402 edt_set_firstflush(pdv_p,EDT_ACT_NEVER) ;
07403 edt_set_autodir(pdv_p, 0) ;
07404
07405 }
07406
07407 edt_startdma_reg(pdv_p, PDV_CMD, PDV_ENABLE_GRAB);
07408
07409 if (pdv_in_continuous(pdv_p))
07410 {
07411
07412 edt_set_continuous(pdv_p, 1);
07413 }
07414 else if (pdv_p->dd_p->fv_once)
07415 {
07416 pdv_start_hardware_continuous(pdv_p);
07417 }
07418 else
07419 edt_set_continuous(pdv_p, 0);
07420
07421 pdv_p->dd_p->started_continuous = 1;
07422
07423 }
07424
07432 void
07433 pdv_stop_continuous(PdvDev * pdv_p)
07434 {
07435
07436 if (pdv_in_continuous(pdv_p))
07437 {
07438 edt_set_continuous(pdv_p, 0);
07439 }
07440 else if (pdv_p->dd_p->fv_once)
07441 pdv_stop_hardware_continuous(pdv_p);
07442
07443 pdv_p->dd_p->started_continuous = 0;
07444
07445 if (pdv_p->devid == PDVFOI_ID)
07446 {
07447 char tmpbuf[10];
07448 int ret;
07449
07450 ret = pdv_serial_wait(pdv_p, 100, 0);
07451 if (ret > 10)
07452 pdv_reset_serial(pdv_p);
07453 else
07454 pdv_serial_read(pdv_p, tmpbuf, ret);
07455 }
07456 }
07457
07478 int
07479 pdv_timeout_restart(PdvDev * pdv_p, int restart)
07480 {
07481 int curdone, curtodo;
07482
07483 curdone = edt_done_count(pdv_p);
07484 curtodo = edt_get_todo(pdv_p);
07485
07486 edt_abort_dma(pdv_p);
07487 pdv_stop_continuous(pdv_p);
07488
07489 edt_set_buffer(pdv_p, curdone);
07490 edt_reg_write(pdv_p, PDV_CMD, PDV_RESET_INTFC);
07491 pdv_setup_continuous(pdv_p);
07492
07493 if (restart &&
07494 (curtodo - curdone))
07495 pdv_start_images(pdv_p, curtodo - curdone);
07496
07497 return curtodo - curdone;
07498 }
07499
07501
07502
07503 static char hs[128];
07504 static char *
07505 hex_to_str(char *resp, int n)
07506 {
07507
07508 int i;
07509 char *p = hs;
07510
07511 for (i = 0; i < n; i++)
07512 {
07513 sprintf(p, "%02x ", resp[i]);
07514 p += 3;
07515 }
07516 *p = '\0';
07517 return hs;
07518 }
07519
07520
07531 int
07532 pdv_get_min_shutter(PdvDev * pdv_p)
07533
07534 {
07535 return pdv_p->dd_p->shutter_speed_min;
07536 }
07537
07538
07547 int
07548 pdv_get_max_shutter(PdvDev * pdv_p)
07549
07550 {
07551 return pdv_p->dd_p->shutter_speed_max;
07552 }
07553
07554
07565 int
07566 pdv_get_min_gain(PdvDev * pdv_p)
07567
07568 {
07569 return pdv_p->dd_p->gain_min;
07570 }
07571
07572
07582 int
07583 pdv_get_max_gain(PdvDev * pdv_p)
07584
07585 {
07586 return pdv_p->dd_p->gain_max;
07587 }
07588
07589
07599 int
07600 pdv_get_min_offset(PdvDev * pdv_p)
07601
07602 {
07603 return pdv_p->dd_p->offset_min;
07604 }
07605
07606
07616 int
07617 pdv_get_max_offset(PdvDev * pdv_p)
07618
07619 {
07620 return pdv_p->dd_p->offset_max;
07621 }
07622
07627 void
07628 pdv_send_break(PdvDev * pdv_p)
07629 {
07630 u_int reg;
07631
07632 edt_msg(DBG2, "pdv_send_break()");
07633
07634 reg = edt_reg_read(pdv_p, PDV_UTIL2);
07635 edt_reg_write(pdv_p, PDV_UTIL2, reg & ~PDV_MC4);
07636 edt_reg_write(pdv_p, PDV_UTIL2, (reg | PDV_SEL_MC4) & ~PDV_MC4);
07637 edt_msleep(500);
07638 edt_reg_write(pdv_p, PDV_UTIL2, reg & ~PDV_SEL_MC4 & ~PDV_MC4);
07639 edt_reg_write(pdv_p, PDV_UTIL2, reg);
07640 }
07641
07642 static void
07643 pdv_trigger_specinst(PdvDev * pdv_p)
07644 {
07645 char cmd = pdv_p->dd_p->serial_trigger[0];
07646
07647 edt_msg(DBG2, "pdv_trigger_specinst('%c')\n", cmd);
07648
07649 pdv_serial_binary_command(pdv_p, &cmd, 1);
07650
07651 }
07652
07656 static void
07657 pdv_posttrigger_specinst(PdvDev * pdv_p)
07658 {
07659 char cmd = pdv_p->dd_p->serial_trigger[0];
07660 char resp[32];
07661 int ret;
07662 int waitcnt = 2;
07663
07664 resp[0] = resp[1] = resp[2] = 0;
07665
07666 #ifdef SPECINST_WAS
07667 if (pdv_p->devid == PDVFOI_ID)
07668 waitcnt += 2;
07669 if ((ret = pdv_serial_wait(pdv_p, 1500, waitcnt)) == waitcnt)
07670 pdv_serial_read(pdv_p, resp, ret);
07671 #else
07672 if (pdv_p->devid == PDVFOI_ID)
07673 pdv_serial_wait_next(pdv_p, 2000, 0);
07674 else
07675 pdv_serial_wait_next(pdv_p, 2000, 1);
07676 ret = pdv_serial_read(pdv_p, resp, 2);
07677 #endif
07678
07679 if ((ret != waitcnt)
07680 || (resp[0] != pdv_p->dd_p->serial_trigger[0])
07681 || (resp[1] != pdv_p->dd_p->serial_response[0]))
07682 {
07683 edt_msg(PDVWARN, "\npdv_posttrigger_specinst: invalid or missing serial\n");
07684 edt_msg(PDVWARN, "response (sent %c, ret %d s/b %d, resp <%s>)\n", cmd, ret, waitcnt, (ret > 0) ? resp : "");
07685 return;
07686 }
07687 }
07688
07689 static int
07690 pdv_specinst_serial_triggered(PdvDev * pdv_p)
07691 {
07692 if (((pdv_p->dd_p->camera_shutter_timing == SPECINST_SERIAL)
07693 || (pdv_p->dd_p->camera_shutter_speed == SPECINST_SERIAL))
07694 && (pdv_p->dd_p->serial_trigger[0]))
07695 return 1;
07696 return 0;
07697 }
07698
07699 int
07700 pdv_pause_for_serial(PdvDev * pdv_p)
07701 {
07702 return pdv_p->dd_p->pause_for_serial;
07703 }
07704
07705
07706 int
07707 isafloat(char *str)
07708 {
07709 unsigned int i;
07710 int numdots = 0;
07711 int numchars = 0;
07712
07713 for (i = 0; i < strlen(str); i++)
07714 {
07715 if (str[i] == '.')
07716 ++numdots;
07717 else if (isdigit(str[i]))
07718 ++numchars;
07719 else
07720 return 0;
07721 }
07722
07723 if (numdots == 1 && numchars > 0)
07724 return 1;
07725 return 0;
07726 }
07727
07728 int
07729 isdigits(char *str)
07730 {
07731 unsigned int i;
07732 int numchars = 0;
07733
07734 for (i = 0; i < strlen(str); i++)
07735 {
07736 if (isdigit(str[i]))
07737 ++numchars;
07738 else if ((str[i] == '-') && (i == 0))
07739 ;
07740 else
07741 return 0;
07742 }
07743
07744 if (numchars > 0)
07745 return 1;
07746 return 0;
07747 }
07748
07749 int
07750 isxdigits(char *str)
07751 {
07752 unsigned int i;
07753 int numchars = 0;
07754
07755 for (i = 0; i < strlen(str); i++)
07756 {
07757 if (isxdigit(str[i]))
07758 ++numchars;
07759 else
07760 return 0;
07761 }
07762
07763 if (numchars > 0)
07764 return 1;
07765 return 0;
07766 }
07767
07775 int
07776 pdv_is_kodak_i(PdvDev * pdv_p)
07777 {
07778 Dependent *dd_p = pdv_p->dd_p;
07779
07780 if ((strcmp(dd_p->serial_exposure, "EXE") == 0)
07781 || (strcmp(dd_p->serial_gain, "DGN") == 0)
07782 || (strcmp(dd_p->serial_offset, "GAE") == 0)
07783 || (strcmp(dd_p->serial_offset, "BKE") == 0))
07784 return 1;
07785 return 0;
07786 }
07787
07788
07799 int
07800 pdv_is_atmel(PdvDev * pdv_p)
07801 {
07802 Dependent *dd_p = pdv_p->dd_p;
07803
07804 if ((strncasecmp(dd_p->camera_class, "Atmel", 5) == 0)
07805 || (strncmp(dd_p->serial_exposure, "I=", 2) == 0))
07806 return 1;
07807 return 0;
07808 }
07809
07817 int
07818 pdv_is_hamamatsu(PdvDev * pdv_p)
07819 {
07820 Dependent *dd_p = pdv_p->dd_p;
07821
07822 if ((strncasecmp(dd_p->camera_class, "Hamamatsu", 9) == 0)
07823 || (strncmp(dd_p->serial_exposure, "SHT", 3) == 0)
07824 || (strncmp(dd_p->serial_exposure, "FBL", 3) == 0)
07825 || (strncmp(dd_p->serial_exposure, "AET", 3) == 0))
07826 return 1;
07827 return 0;
07828 }
07829
07830
07831
07832 pdv_update_values_from_camera(PdvDev * pdv_p)
07833 {
07834 int ret = 0;
07835
07836 if (pdv_is_kodak_i(pdv_p))
07837 ret = pdv_update_from_kodak_i(pdv_p);
07838 else if (pdv_is_dvc(pdv_p))
07839 ret = pdv_update_from_dvc(pdv_p);
07840 else if (pdv_is_atmel(pdv_p))
07841 ret = pdv_update_from_atmel(pdv_p);
07842 else if (pdv_is_hamamatsu(pdv_p))
07843 ret = pdv_update_from_hamamatsu(pdv_p);
07844
07845 else
07846 ret = -1;
07847
07848 return ret;
07849 }
07850
07851 int
07852 pdv_update_from_kodak_i(PdvDev * pdv_p)
07853 {
07854 int i, n, ret = 0;
07855 char *stat[64];
07856 char **stat_p = stat;
07857 Dependent *dd_p = pdv_p->dd_p;
07858
07859 for (i = 0; i < 64; i++)
07860 {
07861 *stat_p = (char *) malloc(64 * sizeof(char));
07862 **stat_p = '\0';
07863 ++stat_p;
07864 }
07865
07866 if ((n = pdv_query_serial(pdv_p, "STS?", stat)) < 1)
07867 ret = -1;
07868 else
07869 {
07870 update_int_from_serial(stat, n, "BKE", &dd_p->level);
07871 update_int_from_serial(stat, n, "GAE", &dd_p->gain);
07872 update_int_from_serial(stat, n, "DGN", &dd_p->gain);
07873 update_int_from_serial(stat, n, "EXE", &dd_p->shutter_speed);
07874 update_int_from_serial(stat, n, "BNS", &dd_p->binx);
07875 update_int_from_serial(stat, n, "BNS", &dd_p->biny);
07876 }
07877
07878 for (i = 0; i < 64; i++)
07879 free(stat[i]);
07880
07881 return ret;
07882 }
07883
07884 int
07885 pdv_update_from_hamamatsu(PdvDev * pdv_p)
07886 {
07887 int i, n, ret = 0;
07888 char *stat[64];
07889 char **stat_p = stat;
07890 Dependent *dd_p = pdv_p->dd_p;
07891
07892 for (i = 0; i < 64; i++)
07893 {
07894 *stat_p = (char *) malloc(64 * sizeof(char));
07895 **stat_p = '\0';
07896 ++stat_p;
07897 }
07898
07899 if ((n = pdv_query_serial(pdv_p, "?CEG", stat)) < 1)
07900 ret = -1;
07901 else
07902 update_int_from_serial(stat, n, "CEG", &dd_p->gain);
07903
07904 if ((n = pdv_query_serial(pdv_p, "?CEO", stat)) < 1)
07905 ret = -1;
07906 else
07907 update_int_from_serial(stat, n, "CEO", &dd_p->level);
07908
07909 if ((n = pdv_query_serial(pdv_p, "?SHT", stat)) < 1)
07910 ret = -1;
07911 else
07912 update_int_from_serial(stat, n, "SHT", &dd_p->shutter_speed);
07913
07914 for (i = 0; i < 64; i++)
07915 free(stat[i]);
07916
07917 return ret;
07918 }
07919
07920
07921 int
07922 pdv_update_from_atmel(PdvDev * pdv_p)
07923 {
07924 int i, n, ret = 0;
07925 int tmpval;
07926 char *stat[64];
07927 char **stat_p = stat;
07928 Dependent *dd_p = pdv_p->dd_p;
07929
07930 for (i = 0; i < 64; i++)
07931 {
07932 *stat_p = (char *) malloc(64 * sizeof(char));
07933 **stat_p = '\0';
07934 ++stat_p;
07935 }
07936
07937 if ((n = pdv_query_serial(pdv_p, "!=3", stat)) < 1)
07938 ret = -1;
07939 else
07940 {
07941 update_int_from_serial(stat, n, "G", &dd_p->gain);
07942 update_int_from_serial(stat, n, "I", &dd_p->shutter_speed);
07943 if (update_int_from_serial(stat, n, "B", &tmpval) == 0)
07944 dd_p->binx = dd_p->biny = tmpval + 1;
07945 }
07946
07947 for (i = 0; i < 64; i++)
07948 free(stat[i]);
07949
07950 return ret;
07951 }
07952
07959 int
07960 pdv_query_serial(PdvDev * pdv_p, char *cmd, char **resp)
07961 {
07962
07963 char *buf_p;
07964 char buf[2048];
07965 char *tmp_storage;
07966 int length;
07967 int ret;
07968 int i, j, l;
07969 int nfound = 0;
07970
07971 if ((tmp_storage = (char *)malloc(strlen(cmd)+1)) == NULL)
07972 return 0;
07973 sprintf(tmp_storage, "%s\r", cmd);
07974 edt_msg(DBG2, "pdv_query_serial: writing <%s>\n", cmd);
07975 pdv_serial_command(pdv_p, tmp_storage);
07976
07977
07978
07979
07980
07981 pdv_serial_wait(pdv_p, pdv_p->dd_p->serial_timeout, 64);
07982
07983
07984
07985
07986
07987 buf_p = buf;
07988 length = 0;
07989 do
07990 {
07991 ret = pdv_serial_read(pdv_p, buf_p, 2048 - length);
07992 edt_msg(DBG2, "read returned %d\n", ret);
07993
07994 if (ret != 0)
07995 {
07996 buf_p[ret + 1] = 0;
07997 buf_p += ret;
07998 length += ret;
07999 }
08000 if (pdv_p->devid == PDVFOI_ID)
08001 pdv_serial_wait(pdv_p, 500, 0);
08002 else
08003 pdv_serial_wait(pdv_p, 500, 64);
08004 } while (ret > 0);
08005
08006
08007
08008
08009 i = 0;
08010 j = 0;
08011 buf_p = buf;
08012 for (l = 0; l < length; l++)
08013 {
08014 if ((*buf_p == '\n') || (*buf_p == '\r'))
08015 {
08016 if (j != 0)
08017 {
08018 resp[i++][j] = '\0';
08019 j = 0;
08020 }
08021 }
08022 else
08023 {
08024 if (j == 0)
08025 ++nfound;
08026 resp[i][j++] = *buf_p;
08027 resp[i][j] = '\0';
08028 }
08029
08030 ++buf_p;
08031 }
08032 return nfound;
08033 }
08034
08039 static int
08040 update_int_from_serial(char **stat, int nstats, char *cmd, int *value)
08041 {
08042 int i, ret = -1;
08043 int len = (int) strlen(cmd);
08044 double tmpf;
08045 char *arg;
08046
08047
08048
08049
08050 for (i = 0; i < nstats; i++)
08051 {
08052 arg = &stat[i][len + 1];
08053 if ((strncmp(stat[i], cmd, len) == 0)
08054 && ((stat[i][len] == ' ') || (stat[i][len] == '=')))
08055 {
08056 if (isdigits(arg))
08057 {
08058 *value = atoi(arg);
08059 ret = 0;
08060 }
08061
08062 else if ((isafloat(arg) && strncmp(cmd, "EXE", 3) == 0))
08063 {
08064 tmpf = atof(arg);
08065 *value = (int) (tmpf / 0.063);
08066 ret = 0;
08067 }
08068 }
08069 }
08070 return ret;
08071 }
08072
08077 static int
08078 update_string_from_serial(char **stat, int nstats, char *cmd, char *value, int maxlen)
08079 {
08080 int i, ret = -1;
08081 int len = (int) strlen(cmd);
08082 char *arg;
08083
08084
08085
08086
08087 for (i = 0; i < nstats; i++)
08088 {
08089 arg = &stat[i][len + 1];
08090 if ((strncmp(stat[i], cmd, len) == 0)
08091 && ((stat[i][len] == ' ') || (stat[i][len] == '=')))
08092 {
08093 strncpy(value, stat[i] + len + 1, maxlen);
08094 }
08095 }
08096 return ret;
08097 }
08098
08103 static void
08104 update_2dig_from_serial(char **stat, int nstats, char *cmd, int *val1, int *val2)
08105 {
08106 int i;
08107 int len = (int) strlen(cmd);
08108 char *arg;
08109
08110
08111
08112
08113 for (i = 0; i < nstats; i++)
08114 {
08115 arg = &stat[i][len + 1];
08116 if ((strncmp(stat[i], cmd, len) == 0)
08117 && (stat[i][len] == ' '))
08118 {
08119 if (isdigits(arg) && strlen(arg) == 2)
08120 {
08121 *val1 = arg[0] - '0';
08122 *val2 = arg[1] - '0';
08123 }
08124 }
08125 }
08126 }
08127
08132 static void
08133 update_hex_from_serial(char **stat, int nstats, char *cmd, int *value)
08134 {
08135 int i;
08136 size_t len = strlen(cmd);
08137 char *arg;
08138
08139
08140
08141
08142 for (i = 0; i < nstats; i++)
08143 {
08144 arg = &stat[i][len + 1];
08145 if ((strncmp(stat[i], cmd, len) == 0)
08146 && (stat[i][len] == ' '))
08147 {
08148 if (isxdigits(arg))
08149 {
08150 *value = strtol(arg, NULL, 16);
08151 }
08152 }
08153 }
08154 }
08155
08156
08168 int
08169 pdv_set_mode(PdvDev * pdv_p, char *mode, int mcl)
08170 {
08171 edt_msg(PDVWARN, "pdv_set_aperture is OBSOLETE\n");
08172 return -1;
08173 }
08174
08175
08176 int
08177 pdv_set_mode_atmel(PdvDev * pdv_p, char *mode)
08178 {
08179 Dependent *dd_p = pdv_p->dd_p;
08180 int cfg = 0;
08181 int cont = 0;
08182
08183 if ((strcmp(mode, "T=0") == 0)
08184 || (strcmp(mode, "T=1") == 0))
08185 {
08186 if (strcmp(mode, "T=0") == 0)
08187 {
08188 dd_p->shutter_speed_min = 0;
08189 dd_p->shutter_speed_max = 0;
08190 }
08191 else
08192 {
08193 dd_p->shutter_speed_min = 1;
08194 dd_p->shutter_speed_max = 2000;
08195 }
08196 dd_p->camera_shutter_timing = AIA_SERIAL;
08197 dd_p->trig_pulse = 1;
08198
08199 dd_p->mode_cntl_norm = 0x0;
08200 edt_reg_write(pdv_p, PDV_MODE_CNTL, dd_p->mode_cntl_norm);
08201 cfg = edt_reg_read(pdv_p, PDV_CFG) | PDV_TRIG | PDV_INV_SHUTTER;
08202 edt_reg_write(pdv_p, PDV_CFG, cfg);
08203 pdv_serial_command(pdv_p, mode);
08204 strcpy(dd_p->serial_exposure, "I=");
08205 }
08206 else if (strcmp(mode, "T=2") == 0)
08207 {
08208 dd_p->timeout_multiplier = 1;
08209 dd_p->shutter_speed_min = 1;
08210 dd_p->shutter_speed_max = 0x414;
08211 dd_p->camera_shutter_timing = AIA_SERIAL;
08212 dd_p->trig_pulse = 1;
08213 dd_p->mode_cntl_norm = 0x10;
08214 edt_reg_write(pdv_p, PDV_MODE_CNTL, dd_p->mode_cntl_norm);
08215 cfg = edt_reg_read(pdv_p, PDV_CFG) | PDV_TRIG;
08216 edt_reg_write(pdv_p, PDV_CFG, cfg);
08217 pdv_serial_command(pdv_p, mode);
08218 strcpy(dd_p->serial_exposure, "I=");
08219 }
08220 else if (strcmp(mode, "T=3") == 0)
08221 {
08222 dd_p->timeout_multiplier = 1;
08223 dd_p->shutter_speed_min = 1;
08224 dd_p->shutter_speed_max = 25500;
08225 dd_p->camera_shutter_timing = AIA_MCL;
08226 dd_p->trig_pulse = 0;
08227 dd_p->mode_cntl_norm = 0x10;
08228 edt_reg_write(pdv_p, PDV_MODE_CNTL, dd_p->mode_cntl_norm);
08229 cfg = edt_reg_read(pdv_p, PDV_CFG) & ~PDV_TRIG;
08230 edt_reg_write(pdv_p, PDV_CFG, cfg);
08231 pdv_serial_command(pdv_p, mode);
08232 dd_p->serial_exposure[0] = '\0';
08233 }
08234 else
08235 {
08236 edt_msg(PDVWARN, "WARNING: unsupported ATMEL mode: %s\n", mode);
08237 return -1;
08238 }
08239 return 0;
08240 }
08241
08245 int
08246 pdv_set_mode_kodak(PdvDev * pdv_p, char *mode)
08247 {
08248 Dependent *dd_p = pdv_p->dd_p;
08249 char cmd[32];
08250 int cfg = 0;
08251 int cont = 0;
08252
08253 if (strcmp(mode, "CS") == 0)
08254 {
08255 dd_p->shutter_speed_min = 1;
08256 dd_p->shutter_speed_max = 512;
08257 dd_p->camera_shutter_timing = AIA_SERIAL;
08258 dd_p->trig_pulse = 1;
08259
08260 dd_p->mode_cntl_norm = 0x0;
08261 edt_reg_write(pdv_p, PDV_MODE_CNTL, dd_p->mode_cntl_norm);
08262 cfg = edt_reg_read(pdv_p, PDV_CFG) | PDV_TRIG | PDV_INV_SHUTTER;
08263 edt_reg_write(pdv_p, PDV_CFG, cfg);
08264 sprintf(cmd, "MDE %s", mode);
08265 pdv_serial_command(pdv_p, cmd);
08266 strcpy(dd_p->serial_exposure, "EXE");
08267 }
08268 else if (strcmp(mode, "TR") == 0)
08269 {
08270 dd_p->shutter_speed_min = 1;
08271 dd_p->shutter_speed_max = 255;
08272 dd_p->camera_shutter_timing = AIA_SERIAL;
08273 dd_p->trig_pulse = 1;
08274 dd_p->mode_cntl_norm = 0x10;
08275 edt_reg_write(pdv_p, PDV_MODE_CNTL, dd_p->mode_cntl_norm);
08276 cfg = edt_reg_read(pdv_p, PDV_CFG) | PDV_TRIG;
08277 edt_reg_write(pdv_p, PDV_CFG, cfg);
08278 sprintf(cmd, "MDE %s", mode);
08279 pdv_serial_command(pdv_p, cmd);
08280 strcpy(dd_p->serial_exposure, "EXE");
08281 }
08282 else if (strcmp(mode, "CD") == 0)
08283 {
08284 dd_p->shutter_speed_min = 1;
08285 dd_p->shutter_speed_max = 25500;
08286 dd_p->camera_shutter_timing = AIA_MCL;
08287 dd_p->trig_pulse = 0;
08288 dd_p->mode_cntl_norm = 0x10;
08289 edt_reg_write(pdv_p, PDV_MODE_CNTL, dd_p->mode_cntl_norm);
08290 cfg = edt_reg_read(pdv_p, PDV_CFG) & ~PDV_TRIG;
08291 edt_reg_write(pdv_p, PDV_CFG, cfg);
08292 sprintf(cmd, "MDE %s", mode);
08293 pdv_serial_command(pdv_p, cmd);
08294 dd_p->serial_exposure[0] = '\0';
08295 }
08296 else
08297 {
08298 edt_msg(PDVWARN, "WARNING: unsupported DVC mode: %s\n", mode);
08299 return -1;
08300 }
08301 return 0;
08302 }
08303
08304 int
08305 pdv_set_mode_hamamatsu(PdvDev * pdv_p, char *mode)
08306 {
08307 Dependent *dd_p = pdv_p->dd_p;
08308 int cfg = 0;
08309 int cont = 0;
08310
08311
08312
08313 return 0;
08314
08315 }
08316
08318
08319
08320
08321
08322
08323
08331 int
08332 pdv_is_dvc(PdvDev * pdv_p)
08333 {
08334 Dependent *dd_p = pdv_p->dd_p;
08335
08336 if ((strncasecmp(dd_p->camera_class, "DVC", 3) == 0)
08337 || (strncmp(dd_p->serial_exposure, "EXP", 3) == 0))
08338 return 1;
08339 return 0;
08340 }
08341
08350 int
08351 pdv_set_binning_dvc(PdvDev * pdv_p, int xval, int yval)
08352 {
08353 int ret = 0;
08354 char cmdstr[64];
08355 Dependent *dd_p = pdv_p->dd_p;
08356
08357 sprintf(cmdstr, "%s %d%d", dd_p->serial_binning, yval, xval);
08358
08359 pdv_serial_command(pdv_p, cmdstr);
08360
08361 return (ret);
08362 }
08363
08364 int
08365 pdv_update_from_dvc(PdvDev * pdv_p)
08366 {
08367 int i, n, ret = 0;
08368 char *stat[64];
08369 char **stat_p = stat;
08370 Dependent *dd_p = pdv_p->dd_p;
08371
08372 for (i = 0; i < 64; i++)
08373 {
08374 *stat_p = (char *) malloc(64 * sizeof(char));
08375 **stat_p = '\0';
08376 ++stat_p;
08377 }
08378
08379 if ((n = pdv_query_serial(pdv_p, "STA", stat)) < 1)
08380 ret = -1;
08381 else
08382 {
08383 update_hex_from_serial(stat, n, "OFS", &dd_p->level);
08384 update_hex_from_serial(stat, n, "GAI", &dd_p->gain);
08385 update_hex_from_serial(stat, n, "EXP", &dd_p->shutter_speed);
08386 update_2dig_from_serial(stat, n, "BIN", &dd_p->binx, &dd_p->biny);
08387 }
08388
08389 for (i = 0; i < 64; i++)
08390 free(stat[i]);
08391
08392 return ret;
08393 }
08394
08395
08396 int
08397 pdv_set_mode_dvc(PdvDev * pdv_p, char *mode)
08398 {
08399 Dependent *dd_p = pdv_p->dd_p;
08400 char cmd[32];
08401 int cfg = 0;
08402 int cont = 0;
08403
08404 if ((strcmp(mode, "NOR") == 0)
08405 || (strcmp(mode, "ULT") == 0)
08406 || (strcmp(mode, "HNL") == 0)
08407 || (strcmp(mode, "HDL") == 0)
08408 || (strcmp(mode, "NFR") == 0)
08409 || (strcmp(mode, "NRR") == 0))
08410 {
08411 if (mode[0] == 'H')
08412 {
08413 dd_p->shutter_speed_min = 1;
08414 dd_p->shutter_speed_max = 0x414;
08415 }
08416 else
08417 {
08418 if (strcmp(mode, "ULT") == 0)
08419 dd_p->timeout_multiplier = 10;
08420 else if (strcmp(mode, "NFR") == 0)