libpdv.c

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

Generated on 19 Jun 2015 by  doxygen 1.4.7