pdv_initcam.c

Go to the documentation of this file.
00001 
00008 #include "edtinc.h"
00009 
00010 #include "libedt_timing.h"
00011 #include "pdv_irig.h"
00012 
00013 /* shorthand debug level */
00014 #define INITCAM_MSG_ALWAYS EDT_MSG_FATAL
00015 
00016 /*
00017  * static prototypes
00018  */
00019 int     is_hex_byte_command(char *str);
00020 void    check_terminator(char *str);
00021 void    dir_from_path(char *dirstr, const char *pathstr);
00022 void    fname_from_path(char *fname, char *pathstr);
00023 int     async_bitfile(EdtDev *edt_p);
00024 char   *grepit(char *buf, char *pat);
00025 int     is_hex_byte_command(char *str);
00026 int     findid(char *str, char *idstr);
00027 char   *strip_crlf(char *str);
00028 void    propeller_sleep(int n);
00029 char   *search_for_bitfile(char *rbtfile, const char *cfgfname, char *bitpath);
00030 int     serial_init(EdtDev * edt_p, Dependent * dd_p);
00031 int     serial_init_basler_binary(EdtDev * edt_p, Dependent * dd_p);
00032 int     serial_init_duncan_binary(EdtDev * edt_p, Dependent * dd_p);
00033 int     send_xilinx_commands(EdtDev * edt_p, char *str);
00034 int     send_foi_commands(EdtDev * edt_p, char *str);
00035 int     check_roi(EdtDev * edt_p, Dependent * dd_p);
00036 void    check_camera_values(EdtDev * ed, Dependent * dd_p);
00037 int     kodak_query_serial(EdtDev * edt_p, char *cmd, int *val);
00038 int     specinst_download(EdtDev * edt_p, char *fname);
00039 int     specinst_setparams(EdtDev * edt_p, char *fname);
00040 void    setup_cl2_simulator(EdtDev *edt_p, Dependent *dd_p);
00041 int     check_register_wrap(EdtDev * edt_p);
00042 char   *serial_tx_rx(PdvDev * pdv_p, char *command, int hexin);
00043 void    do_xregwrites(EdtDev *edt_p, Dependent *dd_p);
00044 int serial_init_binary(EdtDev * edt_p, Dependent * dd_p);
00045 static int set_rci = 0;
00046 static int rci_set_unit = 0;
00047 static long    isascii_str(u_char * buf, int n);
00048 
00049 void
00050 pdv_initcam_set_rci(EdtDev * edt_p, int rci_unit)
00051 {
00052     rci_set_unit = rci_unit;
00053     set_rci = 1;
00054 }
00055 
00056 /*
00057  * initcam internal function -- assumes dependent struct has already been loaded from
00058  * pdv_readcfg() or equivalent.
00059  */
00060 
00061 int
00062 pdv_channel_initialized(int unit, int channel)
00063 
00064 {
00065         PdvDev *pdv_p;
00066 
00067         pdv_p = pdv_open_channel(EDT_INTERFACE,unit, channel);
00068 
00069         if (pdv_p && pdv_get_width(pdv_p) && pdv_get_height(pdv_p))
00070         {
00071                 return 1;
00072         }
00073 
00074         return 0;
00075 }
00076 
00132 int
00133 pdv_initcam(EdtDev * pdv_p, Dependent * dd_p, int unit, Edtinfo * edtinfo,
00134             const char *cfgfname, char *bitdir, int pdv_debug)
00135 {
00136 
00137     char errmsg[256];
00138 
00139     /* make sure the device is open and valid */
00140     if ((pdv_p == NULL) || (dd_p == NULL) || (pdv_p->fd == (HANDLE) NULL))
00141     {
00142         edt_msg(EDT_MSG_FATAL, "ERROR: invalid dependent struct pointer\n");
00143         return -1;
00144     }
00145 
00146 #if 0 /* this doesn't work since is_dvcl2 includes PCIe8 and PCIe4 even if they're not configured as a simulator -- need a way to detect that!!! */
00147     if (edt_is_dvcl2(pdv_p))
00148     {
00149         edt_msg(EDT_MSG_FATAL, "ERROR: this is a simulator (output) board -- use clsimit to initialize\n");
00150         return -1;
00151     }
00152 #endif
00153 
00154     /*
00155      * reality check on some critical input variables
00156      */
00157     if ((dd_p->camera_class[0] == '\0')
00158      || (dd_p->width == 0)
00159      || (dd_p->height == 0)
00160      || (dd_p->depth < 8)
00161      || (dd_p->depth > 32)
00162      || (dd_p->extdepth < 8)
00163      || (dd_p->extdepth > 32)
00164      || (dd_p->depth & 1)
00165      || (dd_p->extdepth & 1))
00166      {
00167         edt_msg(PDVLIB_MSG_WARNING, "WARNING: one or more critical config values appear invalid\n");
00168         sprintf(errmsg, "check readcfg/dependent struct and camera_class, width, height, depth, extdepth\n");
00169         edt_msg(DEBUG2, errmsg);
00170      }
00171 
00172     /*
00173      * pdv_p->dd_p is not necessarily used here, and is normally set by
00174      * pdv_open, but initcam is a special case
00175      */
00176     if (pdv_p->dd_p == 0) /* must've been opened with edt_open (or separately freed?) */
00177         pdv_p->dd_p = dd_p;
00178     else if (pdv_p->dd_p != dd_p)
00179         memcpy(pdv_p->dd_p, dd_p, sizeof(Dependent));
00180 
00181     /* IMPORTANT: use pdv_p->dd_p not just dd_p from here on out in this function */
00182 
00183     if (pdv_p->devid == PDVFOI_ID)
00184     {
00185 #ifdef _FOI_SUPPORTED 
00186         pdv_initcam_checkfoi(pdv_p, edtinfo, unit);
00187 #else
00188         edt_msg(EDT_MSG_FATAL, "FOI not supported beyond v4.1.5.9\n");
00189         return -1;
00190 #endif
00191     }
00192     else
00193     {
00194         edt_reset_serial(pdv_p);
00195 
00196         if (pdv_p->dd_p->rbtfile[0])
00197         {
00198             if (edt_is_dvcl(pdv_p))
00199             {
00200                 edt_msg(DEBUG1, "DV C-Link, skipping xilinx load\n");
00201             }
00202             else if (strcmp(pdv_p->dd_p->rbtfile, "_SKIPPED_") == 0)
00203                 edt_msg(INITCAM_MSG_ALWAYS, "skipping bitload\n");
00204             else if (edt_is_dvfox(pdv_p) && pdv_p->channel_no > 0)
00205             {
00206                 edt_msg(DEBUG1, "DV FOX channel %d skipping bit load\n",
00207                         pdv_p->channel_no);
00208 
00209                 if (!pdv_channel_initialized(pdv_p->unit_no,
00210                                                 0))
00211                 {
00212                     edt_msg(EDT_MSG_FATAL, "You must initialize channel 0 before initializing any other channels on the DV-FOX\n");
00213                 }
00214             }
00215             else if (pdv_initcam_load_bitfile(pdv_p, pdv_p->dd_p, unit, bitdir, cfgfname))
00216                 {
00217                     edt_msg(EDT_MSG_FATAL, "ERROR: Failed bitload\n");
00218                     return -1;
00219                 }
00220         }
00221         else edt_msg(DEBUG1, "No bitfile specified, skipping xilinx load\n");
00222         if (pdv_initcam_reset_camera(pdv_p, pdv_p->dd_p, edtinfo))
00223         {
00224             edt_msg(EDT_MSG_FATAL, "ERROR: Failed camera reset\n");
00225             return -1;
00226         }
00227     }
00228 
00229     return 0;
00230 }
00231 
00232 
00233 
00241 Dependent *
00242 pdv_alloc_dependent()
00243 {
00244     int     dsize = sizeof(Dependent);
00245 
00246     /*
00247      * check dependent size, not over limit allocated for it
00248      */
00249     if (dsize > EDT_DEPSIZE)
00250     {
00251         edt_msg(EDT_MSG_FATAL, "libpdv internal error: bad dependent struct size (%d) s/b %d\n", dsize, EDT_DEPSIZE);
00252         return NULL;
00253     }
00254 
00255     return (Dependent *) calloc(EDT_DEPSIZE, 1);
00256 }
00257 
00258 
00259 #ifdef _FOI_SUPPORTED
00260 /*
00261  * the fiber optic interface has special needs
00262  */
00263 int
00264 pdv_initcam_checkfoi(EdtDev * edt_p, Edtinfo * p_edtinfo, int unit)
00265 {
00266     int     ncameras, camera;
00267     int     ret = 0;
00268 
00269     if (set_rci)
00270     {
00271         ncameras = edt_get_foicount(edt_p);
00272         edt_msg(DEBUG1, "sees %d cameras\n", ncameras);
00273         if (ncameras == 0)
00274         {
00275             edt_check_foi(edt_p);
00276         }
00277         edt_p->dd_p->serial_respcnt = 4;
00278         edt_set_foiunit(edt_p, rci_set_unit);
00279         edt_set_rci_dma(edt_p, rci_set_unit, edt_p->channel_no);
00280         ret = pdv_initcam_reset_camera(edt_p, edt_p->dd_p, p_edtinfo);
00281     }
00282     else
00283     {
00284         edt_set_foicount(edt_p, 0);     /* to force config */
00285         edt_check_foi(edt_p);
00286         edt_p->dd_p->serial_respcnt = 4;
00287         ncameras = edt_get_foicount(edt_p);
00288 
00289         for (camera = 0; (camera < ncameras) && ret == 0; camera++)
00290         {
00291             edt_msg(DEBUG1, "Initializing FOI Unit %d\n", camera);
00292             edt_set_foiunit(edt_p, camera);
00293             edt_set_rci_dma(edt_p, camera, edt_p->channel_no);
00294             ret = pdv_initcam_reset_camera(edt_p, edt_p->dd_p, p_edtinfo);
00295         }
00296     }
00297     return ret;
00298 }
00299 #endif
00300 
00301 
00302 void
00303 dep_wait(EdtDev * edt_p)
00304 {
00305     if (edt_p->devid == PDVFOI_ID)
00306     {
00307 #ifdef _FOI_SUPPORTED 
00308         char    dmy[256];
00309         int ret = pdv_serial_wait(edt_p, 200, 0);
00310         if (ret)
00311             pdv_serial_read(edt_p, dmy, ret);
00312 #endif
00313     }
00314 
00315 }
00316 
00317 /*
00318  * isapromaddress -- must be XXXXX.mmmm-YYYYY.mmmmo, where
00319  * XXXXX and YYYYY are 5-digit (or more) hex addresses, and mmmm and nnnnn
00320  * are the respective sizes in decimal  to download
00321  */
00322 int
00323 get_prom_addrs(char *str, u_int *addr1, int *size1, u_int *addr2, int *size2)
00324 {
00325 
00326     if (str == NULL)
00327         return 0;
00328 
00329     if (sscanf(str, "%x.%d-%x.%d", addr1, size1, addr2, size2) != 4)
00330     {
00331         *addr1 = 0;
00332         *addr2 = 0;
00333         *size1 = 0;
00334         *size2 = 0;
00335         return -1;
00336     }
00337     return 0;
00338 }
00339 
00340 int
00341 pdv_initcam_load_bitfile(EdtDev * edt_p,
00342                          Dependent * dd_p,
00343                          int unit,
00344                          char *bitdir,
00345                          const char *cfgfname)
00346 {
00347     char    dir_arg[256];
00348     char    cfgdir[256];
00349     int     emb = 0;
00350     int     ret, flags=0;
00351 #ifdef NO_FS
00352     char bitname[128];
00353     int  len;
00354 #endif
00355 
00356     cfgdir[0] = '\0';
00357 
00358     edt_msg(DEBUG2, "pdv_initcam_load_bitfile('%s')\n", dd_p->rbtfile);
00359 
00360     if (strcmp(bitdir, "_NOFS_") == 0)
00361     {
00362         emb = 1;
00363         flags = BITLOAD_FLAGS_NOFS;
00364     }
00365 
00366 
00367     if (edt_p->devid == PDVFOI_ID || edt_p->devid == DMY_ID)
00368     {
00369 #if 0
00370         edt_flush_fifo(edt_p);
00371 #endif
00372         dd_p->serial_respcnt = 4;
00373     }
00374     else
00375     {
00376         u_int addr1, addr2;
00377         int size1, size2;
00378 
00379         dd_p->serial_respcnt = 2;
00380         /*
00381          * if -b flag specified, send "-b dirname". if not, strip off leading
00382          * dir from filename and if that exists, send -d dirname otheriwise
00383          * just send "-d camera_config" and hope there's a
00384          * camera_config/bitfiles
00385          */
00386 
00387         if (get_prom_addrs(dd_p->rbtfile, &addr1, &size1, &addr2, &size2) == 0)
00388         {
00389 
00390             edt_msg(DEBUG1, "loading camera xilinx from PROM @ %x %d / %x %d", addr1, size1, addr2, size2);
00391             ret = edt_bitload_from_prom(edt_p, addr1, size1, addr2, size2, flags);
00392             printf("\n");
00393         }
00394         else
00395         {
00396     #ifdef NO_FS
00397             if (emb)
00398             {
00399                 /* strip off .bit from name if nofs (embedded) xilinx */
00400                 strcpy(bitname, dd_p->rbtfile);
00401                 len = strlen(bitname);
00402                 if ((len >= 4) && (strcasecmp(&bitname[len-4], ".bit") == 0))
00403                     bitname[len-4] = '\0';
00404                 edt_msg(EDT_MSG_INFO_1, "loading embedded camera xilinx %s....\n", bitname);
00405                 ret = edt_bitload(edt_p, bitdir, bitname, 1, 0);
00406                 if (edt_is_dvfox(edt_p))
00407                     edt_msleep(500);
00408                 edt_flush_fifo(edt_p);
00409                 return ret;
00410             }
00411     #endif
00412             if (!emb)
00413             {
00414                 if (*bitdir)
00415                     strcpy(dir_arg, bitdir);
00416                 else
00417                 {
00418                     dir_from_path(cfgdir, cfgfname);
00419                     sprintf(bitdir, "%s/bitfiles", cfgdir);
00420 
00421                     if ((!(*cfgdir)) || (pdv_access(bitdir, 0) != 0))
00422                         strcpy(cfgdir, "camera_config");
00423 
00424                     strcpy(dir_arg, cfgdir);
00425                 }
00426             }
00427 
00428             edt_msg(DEBUG1, "loading camera xilinx %s....\n", dd_p->rbtfile);
00429 
00430             if ((ret = edt_bitload(edt_p, dir_arg, dd_p->rbtfile, 0, 0)) != 0)
00431                 return ret;
00432         }
00433 
00434         if (edt_is_dvfox(edt_p))
00435             edt_msleep(500);
00436 
00437         edt_flush_fifo(edt_p);
00438     }
00439 
00440     return 0;
00441 }
00442 
00443 
00444 
00445 /*
00446  * setup registers on the board and send camera setup serial if indicated
00447  */
00448 int
00449 pdv_initcam_reset_camera(EdtDev * edt_p, Dependent * dd_p, Edtinfo * p_edtinfo)
00450 {
00451     int     ret = 0;
00452     int     data_path = 0;
00453 
00454     if (edt_p->devid == PDVFOI_ID)
00455         edt_reset_serial(edt_p);
00456 
00457     if (dd_p->xilinx_rev == NOT_SET)
00458     {
00459         int     rev;
00460 
00461         edt_msg(DEBUG2, "checking for new rev xilinx\n");
00462         dep_wait(edt_p);
00463         edt_reg_write(edt_p, PDV_STAT, 0xff);
00464         rev = edt_reg_read(edt_p, PDV_REV);
00465         if (rev >= 1 && rev <= 32)
00466         {
00467             edt_msg(DEBUG2, "xilinx rev set to %d (0x%x)\n", rev, rev);
00468             dd_p->xilinx_rev = rev;
00469         }
00470         else
00471         {
00472             dd_p->xilinx_rev = 0;
00473             edt_msg(DEBUG2, "no xilinx rev from IOCTL, setting to 0\n");
00474         }
00475 
00476 #ifdef NOT_DONE
00477         /* xilinx rev 2 we got option flag register */
00478         if ((dd_p->xilinx_rev >= 2) && (dd_p->xilinx_rev != 0xff))
00479             dd_p->xilinx_opt = edt_reg_read(edt_p, PDV_XILINX_OPT);
00480 #endif
00481         dd_p->register_wrap = check_register_wrap(edt_p);
00482 
00483         /*
00484          * need to let the driver know the rev in dep_set/get since register
00485          * offsets changed in rev 2
00486          */
00487         edt_set_dependent(edt_p, dd_p);
00488     }
00489 
00490     /*
00491      * default baud is 9600; USED TO only set if explicitly in config
00492      * file, but why? on DVFOX that is a problem, and really no reason
00493      * not to (?), so jus' do it (as of 4.9.0.4.)
00494      */
00495     if (dd_p->serial_baud == NOT_SET)
00496         dd_p->serial_baud = 9600;
00497     pdv_set_baud(edt_p, dd_p->serial_baud);
00498 
00499 
00500     /*
00501      * infer dual channel from other flags
00502      */
00503     if (pdv_is_cameralink(edt_p)
00504      && (dd_p->cl_data_path & 0x10)
00505      && (!(dd_p->cl_cfg & PDV_CL_CFG_RGB)))
00506         dd_p->dual_channel = 1;
00507 
00508     if (!(edt_is_dvcl2(edt_p) && dd_p->sim_enable))
00509     {
00510         /*
00511          * set width/height.  Width and height as set in config file should be
00512          * actual camera width and height, before any ROI changes. ROI changes
00513          * will change dd_p->width/height but not dd_p->cam_width/height.
00514          */
00515         edt_msg(DEBUG1, "setting device defaults....\n");
00516         pdv_set_width(edt_p, dd_p->width);
00517         pdv_set_height(edt_p, dd_p->height);
00518         pdv_set_depth(edt_p, dd_p->depth);
00519 
00520         pdv_set_cam_width(edt_p, dd_p->width);
00521         pdv_set_cam_height(edt_p, dd_p->height);
00522 
00523         check_roi(edt_p, dd_p);
00524 
00525         if (dd_p->sim_enable) /* old simulator */
00526         {
00527             u_int   roictl;
00528 
00529             roictl = edt_reg_read(edt_p, PDV_ROICTL);
00530             /* default to simulated not from camera */
00531             if (!dd_p->sim_ctl)
00532                 roictl |= (PDV_ROICTL_SIM_DAT | PDV_ROICTL_SIM_SYNC);
00533             else
00534                 roictl |= dd_p->sim_ctl | PDV_ROICTL_SIM_DAT;
00535             edt_msg(DEBUG1, "setting simulator bits in roictl %x\n", roictl);
00536             edt_reg_write(edt_p, PDV_ROICTL, roictl);
00537         }
00538     }
00539 
00540     edt_set_dependent(edt_p, dd_p);
00541 
00542     edt_msg(DEBUG1, "setting registers....\n");
00543     if (edt_p->devid != PDVFOI_ID &&
00544         dd_p->genericsim)
00545     {
00546         edt_msg(DEBUG1, "setting up for simulator....\n");
00547         edt_reg_write(edt_p, SIM_LDELAY, dd_p->line_delay);
00548         edt_reg_write(edt_p, SIM_FDELAY, dd_p->frame_delay);
00549         edt_reg_write(edt_p, SIM_WIDTH, dd_p->sim_width - 1);
00550         edt_reg_write(edt_p, SIM_HEIGHT, dd_p->sim_height - 1);
00551         edt_reg_write(edt_p, SIM_CFG, dd_p->genericsim);
00552 
00553 
00554         edt_msg(DEBUG2, "SIM_CFG %x\n", dd_p->genericsim);
00555         switch (dd_p->sim_speed)
00556         {
00557         case 0:
00558             edt_msg(DEBUG2, "starting pixel clock at 5Mhz\n");
00559             edt_reg_write(edt_p, SIM_SPEED, 0);
00560             break;
00561         case 1:
00562             edt_msg(DEBUG2, "starting pixel clock at 10Mhz\n");
00563             edt_reg_write(edt_p, SIM_SPEED, 1);
00564             break;
00565         case 2:
00566             edt_msg(DEBUG2, "starting pixel clock at 20Mhz\n");
00567             edt_reg_write(edt_p, SIM_SPEED, 2);
00568             break;
00569         }
00570     }
00571 
00572 
00573     /* Configuration register settings (except CL2 simulator */
00574     if (!(edt_is_dvcl2(edt_p) && dd_p->sim_enable))
00575     {
00576         int     configuration = 0;
00577 
00578         if (dd_p->inv_shutter)
00579             configuration |= PDV_INV_SHUTTER;
00580         else
00581             configuration &= ~PDV_INV_SHUTTER;
00582 
00583         /*
00584          * if MODE_CNTL_NORM is not set, set default based on value
00585          * of camera_shutter timing
00586          */
00587         if (dd_p->mode_cntl_norm == NOT_SET)
00588         {
00589             if ((dd_p->camera_shutter_timing == AIA_MCL)
00590              || (dd_p->camera_shutter_timing == AIA_MCL_100US)
00591              || (dd_p->camera_shutter_timing == AIA_TRIG))
00592                 dd_p->mode_cntl_norm = 0x10;
00593             else dd_p->mode_cntl_norm = 0;
00594         }
00595 
00596         /*
00597          * set default values for shutter_speed_min/max if using board shutter
00598          * timer and no min/max specified
00599          */
00600         if ((dd_p->camera_shutter_timing == AIA_MCL)
00601          || (dd_p->camera_shutter_timing == AIA_MCL_100US))
00602         {
00603             int exp;
00604 
00605             if ((dd_p->shutter_speed_min == 0) && (dd_p->shutter_speed_max == 0))
00606             {
00607                 dd_p->shutter_speed_min = 0;
00608                 dd_p->shutter_speed_max = 25500;
00609             }
00610 
00611             exp = pdv_get_exposure(edt_p);
00612             if (exp < dd_p->shutter_speed_min || exp > dd_p->shutter_speed_max)
00613                 pdv_set_exposure(edt_p, dd_p->shutter_speed_min);
00614         }
00615 
00616         if (dd_p->camera_shutter_timing == AIA_SERIAL)
00617             dd_p->trig_pulse = 1;
00618 
00619         if (dd_p->trig_pulse || dd_p->camera_shutter_timing == AIA_SERIAL)
00620             configuration |= PDV_TRIG;
00621         else
00622             configuration &= ~PDV_TRIG;
00623 
00624         if (dd_p->dis_shutter)
00625             configuration |= PDV_DIS_SHUTTER;
00626         else
00627             configuration &= ~PDV_DIS_SHUTTER;
00628 
00629         if (dd_p->enable_dalsa)
00630             configuration |= PDV_EN_DALSA;
00631         else
00632             configuration &= ~PDV_EN_DALSA;
00633 
00634         edt_msg(DEBUG2, "CONFIG %x\n", configuration);
00635         dep_wait(edt_p);
00636         edt_reg_write(edt_p, PDV_CFG, configuration);
00637     }
00638 
00639     /* util3 register settings */
00640     {
00641         int     util3 = 0;
00642 
00643         if (dd_p->inv_ptrig)
00644             util3 |= PDV_LV_INVERT;
00645         else
00646             util3 &= ~PDV_LV_INVERT;
00647 
00648         if (dd_p->inv_fvalid)
00649             util3 |= PDV_FV_INVERT;
00650         else
00651             util3 &= ~PDV_FV_INVERT;
00652 
00653         /*
00654          * set dvfox mode16 automatically (ON if 8 bits single or dual channel
00655          * or 8-16 bits single channel, otherwise off), unless specifically set
00656          * in the config file
00657          */
00658         if (edt_is_dvfox(edt_p))
00659         {
00660             if (dd_p->mode16 == NOT_SET)
00661             {
00662                 if ((!(dd_p->cl_cfg & PDV_CL_CFG_RGB))
00663                  && (((dd_p->cl_data_path & 0x0f) == 0x07)
00664                  || (dd_p->cl_data_path <= 0x0f)))
00665                     util3 |= PDV_MODE16;
00666             }
00667             else if (dd_p->mode16)
00668                 util3 |= PDV_MODE16;
00669         }
00670 
00671 
00672         edt_msg(DEBUG2, "UTIL3 %x\n", util3);
00673         dep_wait(edt_p);
00674 
00675         edt_reg_write(edt_p, PDV_UTIL3, util3);
00676     }
00677 
00678     if (edt_p->devid != PDVFOI_ID)
00679         pdv_set_fval_done(edt_p, dd_p->fval_done);
00680 
00681         /* old initcam for irc was this */
00682     if (dd_p->camera_download == IRC_160)
00683     {
00684         int     tmp;
00685 
00686         edt_msg(DEBUG1, "doing old initcam method for IRC160");
00687 #if 0
00688         tmp = edt_reg_read(edt_p, PDV_CFG);     /* inverse shutter, not
00689                                                  * trigger */
00690         tmp &= ~(PDV_INV_SHUTTER | PDV_TRIG);
00691 #endif
00692         tmp = 0;
00693         if (dd_p->inv_shutter)
00694             tmp |= PDV_INV_SHUTTER;
00695         if (dd_p->camera_shutter_timing != AIA_MCL)
00696             tmp |= PDV_TRIG;
00697         dep_wait(edt_p);
00698         edt_reg_write(edt_p, PDV_CFG, tmp);
00699         edt_msg(DEBUG2, "CONFIG %x", tmp);
00700     }
00701 
00702     /* Data Path register settings (and camera link config/cntl) */
00703     if (pdv_is_cameralink(edt_p))
00704     {
00705         edt_msg(DEBUG2, "camera link cfg register %x\n", dd_p->cl_cfg);
00706         edt_reg_write(edt_p, PDV_CL_CFG, dd_p->cl_cfg);
00707 
00708         edt_msg(DEBUG2, "camera link cfg2 register %x\n", dd_p->cl_cfg2);
00709         edt_reg_write(edt_p, PDV_CL_CFG2, dd_p->cl_cfg2);
00710 
00711         edt_msg(DEBUG2, "camera link data_path register %x\n", dd_p->cl_data_path);
00712         edt_reg_write(edt_p, PDV_CL_DATA_PATH, dd_p->cl_data_path);
00713 
00714         if (dd_p->cl_hmax != 0x0)
00715         {
00716             edt_msg(DEBUG2, "camera link hmax register %x\n", dd_p->cl_hmax);
00717             edt_reg_write(edt_p, PDV_CL_HMAX, dd_p->cl_hmax);
00718         }
00719 
00720         if (dd_p->swinterlace == PDV_BGGR
00721                 || dd_p->swinterlace == PDV_ILLUNIS_BGGR)
00722         {
00723                 /* kludge for now */
00724         }
00725         else if (dd_p->depth > 8)
00726                 data_path |= PDV_EXT_DEPTH;
00727 
00728         if (dd_p->camera_shutter_timing == AIA_MCL_100US)
00729                 data_path |= PDV_MULTIPLIER_100US;
00730 
00731         if (dd_p->fv_once)
00732                 data_path |= PDV_CONTINUOUS;
00733 
00734         if (dd_p->trigdiv)
00735             edt_reg_write(edt_p, PDV_TRIGDIV, dd_p->trigdiv);
00736 
00737         /* used hwpad to set 30-bit RGB in PDV and maybe PCIe4 medium mode FW but
00738          * not PCIe8 or any future boards (better not!) */
00739         if (dd_p->rgb30)
00740             if (edt_p->devid < PE8DVCL_ID)
00741                 dd_p->hwpad = dd_p->rgb30;
00742 
00743         dep_wait(edt_p);
00744         edt_reg_write(edt_p, PDV_DATA_PATH, data_path);
00745         dd_p->datapath_reg = data_path;
00746         edt_set_dependent(edt_p, dd_p);
00747     }
00748     else
00749     {
00750         if (dd_p->camera_shutter_timing == DALSA_CONTINUOUS)
00751             dd_p->continuous = 1;
00752 #if 0
00753         /* don't turn on until in driver */
00754         if (dd_p->continuous)
00755             data_path |= PDV_CONTINUOUS;
00756         else
00757             data_path &= ~PDV_CONTINUOUS;
00758 #endif
00759 
00760         if (dd_p->fv_once)
00761                 data_path |= PDV_CONTINUOUS;
00762 
00763         if (dd_p->interlace)
00764             data_path |= PDV_INTERLACED;
00765         else
00766             data_path &= ~PDV_INTERLACED;
00767 
00768         edt_msg(DEBUG2, "data_path register %x\n", data_path);
00769 
00770         /*
00771          * if async we set the board generated pixel clock speed in
00772          * roictl register (added async check so we can use pclock_speed
00773          * for auto timeout and other stuff 08/06 rwh)
00774          */
00775         if (async_bitfile(edt_p))
00776         {
00777             u_int bits = 0;
00778             u_int roictl = edt_reg_read(edt_p, PDV_ROICTL);
00779 
00780             if (dd_p->pclock_speed < 5)
00781                     dd_p->pclock_speed = 5;
00782 
00783             switch(dd_p->pclock_speed)
00784             {
00785                 case 20: bits = 0x04; break;
00786                 case 10: bits = 0x05; break;
00787                 case 5: bits = 0x06; break;
00788                 default: edt_msg(PDVLIB_MSG_WARNING, "invalid pclock_speed value for async\n");
00789             }
00790 
00791             if (bits)
00792                 edt_reg_write(edt_p, PDV_ROICTL, roictl | bits);
00793                 
00794         }
00795         else if (dd_p->pclock_speed < 1)
00796         {
00797             if (pdv_is_cameralink(edt_p))
00798                     dd_p->pclock_speed = 20;
00799             else dd_p->pclock_speed = 5;
00800         }
00801 
00802         if (dd_p->double_rate)
00803         {
00804             u_int   roictl = edt_reg_read(edt_p, PDV_ROICTL) | PDV_RIOCTL_PCLKSEL_DBL_CAM;
00805 
00806             edt_reg_write(edt_p, PDV_ROICTL,
00807                           roictl);
00808 
00809         }
00810 
00811         if (dd_p->camera_shutter_timing == PDV_DALSA_LS)
00812         {
00813             u_int   roictl = edt_reg_read(edt_p, PDV_ROICTL);
00814 
00815             roictl |= PDV_ROICTL_DALSA_LS;
00816 
00817             edt_reg_write(edt_p, PDV_ROICTL,
00818                           roictl);
00819 
00820         }
00821 
00822         /*
00823          * 'different' dual channel
00824          */
00825         if (dd_p->dual_channel)
00826         {
00827             edt_msg(DEBUG1, "setting dual channel\n");
00828             data_path &= ~PDV_RES0;
00829             data_path |= PDV_RES1;
00830 #if 0                           /* wha...? this seems to BREAK Dalsa
00831                                  * (ca-d4-1024A anyway), so skip it! */
00832             if (dd_p->enable_dalsa)
00833             {
00834                 if (dd_p->extdepth > 8)
00835                     data_path |= PDV_EXT_DEPTH;
00836             }
00837             else
00838 #endif
00839                 data_path |= PDV_EXT_DEPTH;
00840         }
00841         else if (dd_p->swinterlace == PDV_BGGR)
00842         {
00843             /* set for 10 bit ext - 8 bit first pass kludge */
00844             data_path |= PDV_RES0;
00845             data_path &= ~PDV_RES1;
00846         }
00847         else if (dd_p->swinterlace == PDV_BGGR_WORD
00848                  || dd_p->swinterlace == PDV_BGGR_DUAL)
00849         {
00850             /* set for 10 bit ext */
00851             data_path |= PDV_EXT_DEPTH;
00852             data_path |= PDV_RES0;
00853             data_path &= ~PDV_RES1;
00854         }
00855         else
00856         {
00857             if (dd_p->depth > 8)
00858                 data_path |= PDV_EXT_DEPTH;
00859             switch (dd_p->extdepth)
00860             {
00861             case 8:
00862                 data_path &= ~PDV_EXT_DEPTH;
00863                 break;
00864             case 10:
00865                 data_path |= PDV_RES0;
00866                 data_path &= ~PDV_RES1;
00867                 break;
00868             case 12:
00869                 data_path &= ~PDV_RES0;
00870                 data_path &= ~PDV_RES1;
00871                 break;
00872             case 14:
00873                 data_path |= PDV_RES0;
00874                 data_path |= PDV_RES1;
00875                 break;
00876             case 16:
00877                 data_path &= ~PDV_RES0;
00878                 data_path |= PDV_RES1;
00879                 break;
00880             }
00881         }
00882 
00883         if (dd_p->camera_shutter_timing == AIA_MCL_100US)
00884             data_path |= PDV_MULTIPLIER_100US;
00885 
00886         edt_msg(DEBUG2, "DATA_PATH %x\n", data_path);
00887         dep_wait(edt_p);
00888         edt_reg_write(edt_p, PDV_DATA_PATH, data_path);
00889         dd_p->datapath_reg = data_path;
00890         edt_set_dependent(edt_p, dd_p);
00891     }
00892 
00893     /* new aia */
00894     if (dd_p->xilinx_rev >= 1 && dd_p->xilinx_rev <= 32)
00895     {
00896         int util2 = dd_p->util2;
00897 
00898         /*
00899          * set shift/mask (except n/a on cameralink)
00900          */
00901         if (!pdv_is_cameralink(edt_p))
00902         {
00903             if (dd_p->shift == NOT_SET)
00904             {
00905                 int     tmpdepth;
00906 
00907                 if (dd_p->depth == 24)
00908                     tmpdepth = 8;
00909                 else
00910                     tmpdepth = dd_p->depth;
00911 
00912                 /*
00913                  * shift gets a bit weird for DVC -- the DVK and DV44 cables are
00914                  * wired differently, and the older DVK is yet a third case --
00915                  * punt on that one and try to handle the first two as best we we
00916                  * can. Worst case will be that someone will need to use explicit
00917                  * shift in the in the config file if they have a specific cable.
00918                  */
00919                 if (pdv_is_dvc(edt_p))
00920                 {
00921                     edt_msg(DEBUG1, "auto-setting shift for dvc\n");
00922 
00923                     if (edt_p->devid == PDV44_ID)
00924                         dd_p->shift = (16 - dd_p->extdepth) | PDV_AIA_SWAP;
00925                     else if (dd_p->extdepth == 12)      /* dvk 12-bit cable */
00926                     {
00927                         dd_p->shift = 2;
00928                     }
00929                     else
00930                         dd_p->shift = 0;
00931                 }
00932                 /*
00933                  * not set in config so calculate default for non-cameralink
00934                  */
00935                 else
00936                 {
00937                     dd_p->shift = 16 - dd_p->extdepth;
00938                     dd_p->shift |= PDV_AIA_SWAP;
00939                 }
00940 
00941                 /*
00942                  * since shift was not set, check mask as well to see if it
00943                  * appears not to have been set either (0xffff) and set it too
00944                  */
00945                 if (dd_p->mask == 0xffff)
00946                 {
00947                     dd_p->mask = (u_int) (0x0000ffff >> (16 - tmpdepth));
00948                     if (pdv_is_dvc(edt_p))
00949                         edt_msg(DEBUG1, "auto-setting mask for dvc\n");
00950                     else
00951                         edt_msg(DEBUG1, "auto-set shift/mask to %02x/%02x (AIA/swap)\n", dd_p->shift, dd_p->mask);
00952                 }
00953                 else
00954                     edt_msg(DEBUG1, "auto-set shift to %02x (AIA/swap)\n", dd_p->shift);
00955             }
00956 
00957             edt_msg(DEBUG2, "PDV_SHIFT %x\n", dd_p->shift);
00958             dep_wait(edt_p);
00959             edt_reg_write(edt_p, PDV_SHIFT, dd_p->shift);
00960             edt_msg(DEBUG2, "PDV_MASK %x\n", dd_p->mask);
00961             dep_wait(edt_p);
00962             edt_reg_write(edt_p, PDV_MASK, dd_p->mask);
00963         }
00964 #if 0
00965         edt_reg_write(edt_p, PDV_LINERATE, dd_p->linerate);
00966         /* Note dd_p->prin has been retired from dependent struct */
00967         edt_reg_write(edt_p, PDV_PRIN, dd_p->prin);
00968 #endif
00969         if (dd_p->photo_trig)
00970             util2 |= PDV_PHOTO_TRIGGER;
00971         if (dd_p->fieldid_trig)
00972             util2 |= PDV_FLDID_TRIGGER;
00973         if (dd_p->acquire_mult)
00974             util2 |= PDV_AQUIRE_MULTIPLE;
00975 
00976         /*
00977          * RS-232 bit -- overloaded on MC4, only applicable to PCI
00978          * DVA or 3v RCI (LVDS or RS422)
00979          */
00980         if ((dd_p->serial_mode == PDV_SERIAL_RS232)
00981          && ((edt_p->devid == PDVA_ID) || (edt_p->devid == PDVFOI_ID) || (edt_is_dvfox(edt_p))))
00982             util2 |= PDV_RX232;
00983 
00984         else if (dd_p->sel_mc4)
00985             util2 |= PDV_SEL_MC4;
00986 
00987         /*
00988          * mc4 is EXPEXSYNC on camera link, so do it whether or not (the nearly obsolete)
00989          * SEL_MC4 is specified
00990          */
00991         if (dd_p->mc4) /* alias EXPEXSYNC on pcidv c-link */
00992             util2 |= PDV_MC4;
00993 
00994 #if 0
00995         if (dd_p->sim_enable)
00996             util2 |= PDV_SIMEN;
00997         if (dd_p->xilinx_clk)
00998             util2 |= PDV_XOSCSEL;
00999         if (dd_p->linerate)
01000             util2 |= PDV_LINESCAN;
01001 #endif
01002 
01003         if (dd_p->dbl_trig)
01004             util2 |= PDV_DBL_TRIG;
01005         if (dd_p->pulnix)
01006             util2 |= PDV_PULNIX;
01007 
01008 
01009         dd_p->util2 = util2;
01010         edt_msg(DEBUG2, "PDV_UTIL2 %x\n", util2);
01011         dep_wait(edt_p);
01012         edt_reg_write(edt_p, PDV_UTIL2, util2);
01013     }
01014 
01015     if (dd_p->byteswap == NOT_SET)
01016     {
01017         if (edt_little_endian())
01018             dd_p->byteswap = 0;
01019         else
01020             dd_p->byteswap = 1;
01021     }
01022     else edt_msg(DEBUG2, "byteswap %d, forcing %s\n",
01023                             dd_p->byteswap? "ON":"OFF");
01024 
01025     /* set Byteswap/ Hwpad */
01026     {
01027         int     padword = 0;
01028 
01029         padword = dd_p->hwpad << 1;
01030 
01031         if (dd_p->byteswap)
01032             padword |= PDV_BSWAP;
01033         if (dd_p->shortswap)
01034             padword |= PDV_SSWAP;
01035         if (dd_p->disable_mdout)
01036             padword |= PDV_DISABLEMD;
01037         if (dd_p->gendata)
01038             padword |= PDV_GENDATA;
01039         if (dd_p->skip)
01040             padword |= PDV_SKIP;
01041 
01042         edt_msg(DEBUG2, "PAD_SWAP %x\n", padword);
01043         dep_wait(edt_p);
01044         edt_reg_write(edt_p, PDV_BYTESWAP, padword);
01045     }
01046 
01047 
01048     /* xybion only (for now) uses fixedlen */
01049     if (dd_p->fixedlen)
01050     {
01051         /* #define SWAPEM 1 */
01052 #if SWAPEM
01053         unsigned short val = dd_p->fixedlen;
01054         unsigned short tmp = ((val & 0xff) << 8) | ((val & 0xff00) >> 8);
01055 
01056         edt_msg(DEBUG2, "FIXEDLEN %x\n", tmp);
01057         dep_wait(edt_p);
01058         edt_reg_write(edt_p, PDV_FIXEDLEN, tmp);
01059 #else
01060 
01061         edt_msg(DEBUG2, "FIXEDLEN %x\n", dd_p->fixedlen);
01062         dep_wait(edt_p);
01063         edt_reg_write(edt_p, PDV_FIXEDLEN, dd_p->fixedlen);
01064 #endif
01065     }
01066 
01067 
01068     edt_msg(DEBUG2, "MODE_CNTL %x\n", dd_p->mode_cntl_norm);
01069     dep_wait(edt_p);
01070     edt_reg_write(edt_p, PDV_MODE_CNTL, dd_p->mode_cntl_norm);
01071     dep_wait(edt_p);
01072 
01073 
01074     if (edt_p->devid == PDVFOI_ID)
01075     {
01076         if (strlen(dd_p->foi_init) > 0)
01077         {
01078             edt_msg(DEBUG1, "sending foi init commands....");
01079             send_foi_commands(edt_p, dd_p->foi_init);
01080         }
01081     }
01082     else
01083         edt_reset_serial(edt_p);
01084 
01085     /* set waitc */
01086     if (dd_p->serial_waitc == NOT_SET)
01087         pdv_set_waitchar(edt_p, 0, 0);
01088     else
01089         pdv_set_waitchar(edt_p, 1, (u_char)dd_p->serial_waitc);
01090 
01091     if (dd_p->user_timeout == NOT_SET && edt_p->devid != PDVFOI_ID)
01092     {
01093         dd_p->user_timeout = 0; /* user_set will be the real flag */
01094         pdv_auto_set_timeout(edt_p);
01095     }
01096     else
01097         pdv_set_timeout(edt_p, dd_p->user_timeout);
01098 
01099     if (dd_p->timeout != NOT_SET)
01100         edt_set_rtimeout(edt_p, dd_p->timeout);
01101 
01102     pdv_set_defaults(edt_p);
01103     check_camera_values(edt_p, dd_p);
01104 
01105     do_xregwrites(edt_p, dd_p);
01106 
01107     /*
01108      * final stuff (none applicable to CL2 sim) 
01109      */
01110     if (!(edt_is_dvcl2(edt_p) && dd_p->sim_enable))
01111     {
01112         check_terminator(dd_p->serial_term);
01113 
01114         if ((dd_p->camera_shutter_timing == SPECINST_SERIAL)
01115             || (dd_p->camera_shutter_speed == SPECINST_SERIAL)
01116             || (dd_p->camera_download == SPECINST_SERIAL))
01117             dd_p->force_single = 1;
01118 
01119         if (dd_p->camera_download == SPECINST_SERIAL)
01120         {
01121             if ((DD_P_CAMERA_DOWNLOAD_FILE[0])
01122                 && ((ret = specinst_download(edt_p, DD_P_CAMERA_DOWNLOAD_FILE)) == 0))
01123                 if (DD_P_CAMERA_COMMAND_FILE[0])
01124                     ret = specinst_setparams(edt_p, DD_P_CAMERA_COMMAND_FILE);
01125             if (ret != 0)
01126                 return ret;
01127         }
01128 
01129         if (strlen(dd_p->serial_init) > 0)
01130             serial_init(edt_p, dd_p);
01131 
01132         if (strlen(dd_p->xilinx_init) > 0)
01133             send_xilinx_commands(edt_p, dd_p->xilinx_init);
01134 
01135         if (dd_p->frame_timing != 0)
01136             pdv_set_frame_period(edt_p, dd_p->frame_period, dd_p->frame_timing);
01137 
01138         if (p_edtinfo->startdma != NOT_SET)
01139             edt_startdma_action(edt_p, p_edtinfo->startdma);
01140         else
01141             edt_startdma_action(edt_p, EDT_ACT_ALWAYS);
01142         if (p_edtinfo->enddma != NOT_SET)
01143             edt_enddma_action(edt_p, p_edtinfo->enddma);
01144         if (p_edtinfo->flushdma != NOT_SET)
01145             edt_set_firstflush(edt_p, p_edtinfo->flushdma);
01146         else
01147             edt_set_firstflush(edt_p, EDT_ACT_ONCE);
01148     }
01149 
01150     if (dd_p->header_type)
01151         pdv_set_header_type(edt_p, dd_p->header_type, dd_p->irig_slave, dd_p->irig_offset, dd_p->irig_raw);
01152 
01153     return 0;
01154 }
01155 
01156 
01157 
01158 #ifdef _NT_
01159 #define popen(cmd, mode) _popen(cmd, mode)
01160 #define pclose(cmd) _pclose(cmd)
01161 #define BITLOAD "bitload"
01162 #else
01163 #define BITLOAD "./bitload"
01164 #endif
01165 
01166 /* find id string, starting with "id:". If found return 1, else 0 */
01167 int
01168 findid(char *buf, char *idstr)
01169 {
01170     if (strncmp(buf, "id:", 3) == 0)
01171     {
01172 #if 0
01173         char   *dp = idstr;
01174         char   *p = strchr(buf, '"');
01175         char   *pp = strrchr(p, '"');
01176 
01177         for (; p != pp; p++)
01178             *dp++ = *p;
01179 #endif
01180         return (sscanf(&buf[4], " \"%[^\"]\"", idstr));
01181     }
01182     return 0;
01183 }
01184 
01185 void
01186 dir_from_path(char *dirstr, const char *pathstr)
01187 {
01188     char   *bsp = strrchr(pathstr, '\\');
01189     char   *fsp = strrchr(pathstr, '/');
01190     char   *sp;
01191 
01192     if (bsp > fsp)
01193         sp = bsp;
01194     else
01195         sp = fsp;
01196 
01197     if (sp != NULL)
01198     {
01199         strncpy(dirstr, pathstr, sp - pathstr);
01200         dirstr[sp - pathstr] = '\0';
01201     }
01202     else
01203         *dirstr = '\0';
01204 }
01205 
01206 /*
01207  * return 1 if async bitfile (from name); so that we set roictl
01208  * from pclock speed ONLY if async bitfile
01209  */
01210 int
01211 async_bitfile(EdtDev *edt_p)
01212 {
01213     edt_bitpath  pathbuf;
01214 
01215     edt_get_bitname(edt_p, pathbuf, sizeof(edt_bitpath)) ;
01216     if (pathbuf[0] && (strstr(pathbuf, "async") != NULL))
01217         return 1;
01218     return 0;
01219 }
01220 
01221 void
01222 fname_from_path(char *fname, char *pathstr)
01223 {
01224     char   *bsp = strrchr(pathstr, '\\');
01225     char   *fsp = strrchr(pathstr, '/');
01226     char   *sp;
01227 
01228     if (bsp > fsp)
01229         sp = bsp;
01230     else
01231         sp = fsp;
01232 
01233     if (sp == NULL)
01234         strcpy(fname, pathstr);
01235     else
01236         strcpy(fname, sp + 1);
01237 }
01238 
01239 /*
01240  * check serial_exe to see if it's  Kodak 'i' type, if found then flush the
01241  * serial with a TRM command, and get the idn. Then send serial init string,
01242  * one command at a time.
01243  */
01244 int
01245 serial_init(EdtDev * edt_p, Dependent * dd_p)
01246 {
01247     int     ret;
01248     int     foi = 0;
01249     int     hamamatsu = 0;
01250     int     skip_init = 0;
01251     char    cmdstr[32];
01252     char    resp[257];
01253 
01254     edt_msg(DEBUG1, "sending serial init....\n");
01255 
01256     if (dd_p->serial_format == SERIAL_BINARY)
01257         return serial_init_binary(edt_p, dd_p);
01258 
01259     else if (dd_p->serial_format == SERIAL_BASLER_FRAMING)
01260         return serial_init_basler_binary(edt_p, dd_p);
01261 
01262     else if (dd_p->serial_format == SERIAL_DUNCAN_FRAMING)
01263         return serial_init_duncan_binary(edt_p, dd_p);
01264 
01265     if (edt_p->devid == PDVFOI_ID)
01266         foi = 1;
01267 
01268     if (grepit(dd_p->cameratype, "Hamamatsu") != NULL)
01269         hamamatsu = 1;
01270 
01271     /* first flush any pending/garbage serial */
01272     resp[0] = '\0';
01273     ret = pdv_serial_wait(edt_p, 500, 256);
01274     pdv_serial_read(edt_p, resp, 256);
01275 
01276     /*
01277      * Hamamatsu 4880-8X needs some space after power cycle and also comes
01278      * back before it's really done, so...
01279      */
01280     if (hamamatsu)
01281         propeller_sleep(5);
01282 
01283     edt_msg(DEBUG1, "sending serial init commands to camera....\n");
01284 
01285     /*
01286      * if kodak 'i' camera, send a couple of "TRM?"s just to flush out the
01287      * serial, and send the IDN string to get the camera firmware ID
01288      */
01289     if (pdv_is_kodak_i(edt_p))
01290     {
01291         /* first send a couple of TRM?s to flush and sync */
01292         pdv_serial_command(edt_p, "TRM?");
01293         pdv_serial_wait(edt_p, 500, 40);
01294         pdv_serial_command(edt_p, "TRM?");
01295         pdv_serial_wait(edt_p, 500, 40);
01296         ret = pdv_serial_read(edt_p, resp, 256);
01297 
01298         pdv_serial_command(edt_p, "IDN?");
01299         edt_msg(DEBUG1, "IDN? ");
01300         pdv_serial_wait(edt_p, 1000, 60);
01301         ret = pdv_serial_read(edt_p, resp, 256);
01302         if (ret > 20)
01303             edt_msg(DEBUG1, "%s\n", resp);
01304         else if (ret > 0)
01305             edt_msg(DEBUG1, "%s (unexpected response!)\n", resp);
01306         else
01307         {
01308             edt_msg(DEBUG1, "<no response from camera -- check cables and connections>\n");
01309             skip_init = 1;
01310         }
01311     }
01312 
01313 
01314     if (!skip_init)
01315     {
01316         int    i = 0, ms;
01317         char   *lastp = NULL;
01318         char   *p = dd_p->serial_init;
01319 
01320         if (dd_p->serial_init_delay == NOT_SET)
01321             ms = 500;
01322         else ms = dd_p->serial_init_delay;
01323 
01324         /*
01325          * send serial init string
01326          */
01327         cmdstr[0] = '\0';
01328         while (*p)
01329         {
01330             if (i > 31)
01331             {
01332                 edt_msg(EDT_MSG_FATAL, "ERROR: serial command too long\n");
01333                 return -1;
01334             }
01335             if (*p == ':' && lastp && *lastp != '\\')
01336             {
01337                 cmdstr[i] = '\0';
01338                 i = 0;
01339 
01340                 memset(resp, '\0', 257);
01341 
01342                 if (cmdstr[0])
01343                 {
01344                     if (is_hex_byte_command(cmdstr))
01345                     {
01346                         if (dd_p->serial_init_delay == NOT_SET)
01347                             ms = 10;
01348                         edt_msg(DEBUG2, "%s\n", cmdstr);
01349                         pdv_serial_command_hex(edt_p, cmdstr, 1);
01350 
01351                         /* flush out junk */
01352                         if (foi)
01353                             ret = pdv_serial_wait(edt_p, dd_p->serial_timeout, 0);
01354                         else
01355                             ret = pdv_serial_wait(edt_p, dd_p->serial_timeout, 128);
01356                         pdv_serial_read(edt_p, resp, ret);
01357                     }
01358                     else if (hamamatsu && !foi)
01359                     {
01360                         char   *resp_str;
01361 
01362                         edt_msg(DEBUG2, "%s", strip_crlf(cmdstr));
01363                         fflush(stdout);
01364                         resp_str = serial_tx_rx(edt_p, cmdstr, 0);
01365                         edt_msg(DEBUG2, " <%s>\n", strip_crlf(resp_str));
01366                     }
01367                     else                        /* FUTURE: expand and test serial_tx_rx under
01368                                              * FOI and replace
01369                                              * pdv_serial_command/wait/read with that for
01370                                              * all */
01371                     {
01372                         /* edt_msg(DEBUG1, ".", cmdstr); */
01373                         edt_msg(DEBUG2, "%s ", cmdstr);
01374                         pdv_serial_command(edt_p, cmdstr);
01375 
01376                         if (foi)
01377                             ret = pdv_serial_wait(edt_p, dd_p->serial_timeout, 0);
01378                         else
01379                             ret = pdv_serial_wait(edt_p, dd_p->serial_timeout, 16);
01380                         pdv_serial_read(edt_p, resp, 256);
01381                         edt_msg(DEBUG2, " <%s>", strip_crlf(resp));
01382                         edt_msg(DEBUG2, "\n");
01383                     }
01384                     /* edt_msg(DEBUG1, ".", cmdstr); */
01385                     edt_msleep(ms);
01386                 }
01387             }
01388             else if (*p != '\\')
01389                 cmdstr[i++] = *p;
01390             lastp = p;
01391             ++p;
01392         }
01393     }
01394 
01395     pdv_update_values_from_camera(edt_p);
01396     edt_set_dependent(edt_p, dd_p);
01397 
01398     if (hamamatsu)
01399         propeller_sleep(5);
01400 
01401     return 0;
01402 }
01403 
01404 u_char
01405 atoxdigit(char ch)
01406 {
01407     if (ch >= '0' && ch <= '9')
01408         return (ch - '0');
01409 
01410     if (ch >= 'a' && ch <= 'f')
01411         return (ch - 'a') + 10;
01412 
01413     if (ch >= 'A' && ch <= 'F')
01414         return (ch - 'A') + 10;
01415 
01416     return 0;
01417 }
01418 
01419 /*
01420  * binary initialization: serial_binit specified, interpret as string of
01421  * hex bytes only
01422  * update 7/10/07: now sends adjacent bytes as a single command (string of
01423  * bytes); does a * wait/read on whitespace only
01424  */
01425 int
01426 serial_init_binary(EdtDev * edt_p, Dependent * dd_p)
01427 {
01428     int ret, i;
01429     int buflen = (int)strlen(dd_p->serial_binit);
01430     int cmdlen = 0, nibble_index = 0;
01431     u_char hbuf[256];
01432     char    resp[257];
01433     u_char ch;
01434 
01435 
01436     /* flush junk */
01437     ret = pdv_serial_wait(edt_p, dd_p->serial_timeout, 128);
01438 
01439     hbuf[0] = 0;
01440     nibble_index = 0;
01441     for (i = 0; i < buflen+1; i++)
01442     {
01443         if (i < buflen)
01444             ch = dd_p->serial_binit[i];
01445 
01446         if ((i == buflen) || (ch == '\t' || ch == ' '))
01447         {
01448             cmdlen = (nibble_index+1) / 2;
01449                 
01450             if (cmdlen)
01451             {
01452                 /* send command, wait for response */
01453                 pdv_serial_binary_command(edt_p, (char *) hbuf, cmdlen);
01454                 if ((ret = pdv_serial_wait(edt_p, dd_p->serial_timeout, 256)))
01455                     pdv_serial_read(edt_p, resp, ret);
01456             }
01457 
01458             nibble_index = 0;
01459             hbuf[0] = 0;
01460         }
01461         else if (isxdigit(ch))
01462         {
01463             hbuf[nibble_index/2] = (hbuf[nibble_index/2] << 4) | atoxdigit(ch);
01464             if ((nibble_index++) % 2)
01465                 hbuf[nibble_index/2] = 0;
01466         }
01467         else
01468         {
01469             edt_msg(PDVLIB_MSG_WARNING, "serial_binit: hex string format error\n");
01470             return -1;
01471         }
01472     }
01473 
01474     pdv_update_values_from_camera(edt_p);
01475     edt_set_dependent(edt_p, dd_p);
01476 
01477     return 0;
01478 }
01479 
01480 /*
01481  * basler A202k binary only initialization -- expects serial_init to contain
01482  * colon-separated strings of hex bytes WITHOUT framing information; add
01483  * basler A202k style framing and send the commands to the camera
01484  */
01485 int
01486 serial_init_basler_binary(EdtDev * edt_p, Dependent * dd_p)
01487 {
01488     int    i, j;
01489     char   *p;
01490     int    ms = 50;
01491     char   *nextp;
01492     int     len;
01493     int     ret;
01494     int     foi = 0;
01495     char    cmdstr[32];
01496     char    bytestr[3];
01497     char    resp[257];
01498 
01499     if (edt_p->devid == PDVFOI_ID)
01500         foi = 1;
01501 
01502     if (dd_p->serial_init_delay != NOT_SET)
01503         ms = dd_p->serial_init_delay;
01504 
01505     /* first flush any pending/garbage serial */
01506     resp[0] = '\0';
01507     ret = pdv_serial_wait(edt_p, 500, 256);
01508     pdv_serial_read(edt_p, resp, 256);
01509 
01510     edt_msg(DEBUG1, "sending Basler A202k framed commands to camera:\n");
01511 
01512     /*
01513      * send serial init string (first stick on a trailing ':' for parser)
01514      */
01515     p = dd_p->serial_init;
01516     len = (int)strlen(dd_p->serial_init);
01517     if (dd_p->serial_init[len-1] != ':')
01518     {
01519         dd_p->serial_init[len] = ':';
01520         dd_p->serial_init[len+1] = '\0';
01521     }
01522 
01523     while ((nextp = strchr(p, ':')))
01524     {
01525         int     ms = 50;
01526         u_char bytebuf[32];
01527         u_char *bp = bytebuf;
01528 
01529         len = (int)(nextp - p);
01530         if (len > 31)
01531         {
01532             edt_msg(EDT_MSG_FATAL, "ERROR: serial command too long\n");
01533             return -1;
01534         }
01535 
01536         strncpy(cmdstr, p, len);
01537         cmdstr[len] = 0;
01538         memset(resp, '\0', 257);
01539 
01540         if (len % 2)
01541         {
01542             edt_msg(EDT_MSG_FATAL, "serial_binary format string error: odd nibble count\n");
01543             return -1;
01544         }
01545 
01546         for (i=0; i<len; i++)
01547         {
01548             if (!isxdigit(cmdstr[i]))
01549             {
01550                 edt_msg(EDT_MSG_FATAL, "serial_binrary format string error: odd nibble count\n");
01551                 return -1;
01552             }
01553         }
01554 
01555         for (i=0, j=0; i<len; i+=2, j++)
01556         {
01557             u_int bint;
01558             bytestr[0] = cmdstr[i];
01559             bytestr[1] = cmdstr[i+1];
01560             bytestr[2] = '\0';
01561             sscanf(bytestr, "%x", &bint);
01562             *(bp++) = (u_char)(bint & 0xff);
01563         }
01564         pdv_send_basler_frame(edt_p, bytebuf, len/2);
01565 
01566         /* flush out junk */
01567         if (foi)
01568             ret = pdv_serial_wait(edt_p, dd_p->serial_timeout, 0);
01569         else
01570             ret = pdv_serial_wait(edt_p, dd_p->serial_timeout, 128);
01571         pdv_serial_read(edt_p, resp, ret);
01572 
01573         p = nextp + 1;
01574         edt_msleep(ms);
01575     }
01576 
01577     pdv_update_values_from_camera(edt_p);
01578     edt_set_dependent(edt_p, dd_p);
01579 
01580     return 0;
01581 }
01582 
01583 /*
01584  * duncantech MS2100, 2150, 3100, 4100 binary only initialization -- expects
01585  * serial_init to contain colon-separated strings of hex bytes WITHOUT
01586  * framing information; add duncan framing and send the commands to the
01587  * camera
01588  */
01589 int
01590 serial_init_duncan_binary(EdtDev * edt_p, Dependent * dd_p)
01591 {
01592     int    i, j;
01593     char   *p;
01594     int    ms = 50;
01595     char   *nextp;
01596     int     len;
01597     int     ret;
01598     int     foi = 0;
01599     char    cmdstr[32];
01600     char    bytestr[3];
01601     char    resp[257];
01602 
01603     if (edt_p->devid == PDVFOI_ID)
01604         foi = 1;
01605 
01606     if (dd_p->serial_init_delay != NOT_SET)
01607         ms = dd_p->serial_init_delay;
01608 
01609     /* first flush any pending/garbage serial */
01610     resp[0] = '\0';
01611     ret = pdv_serial_wait(edt_p, 500, 256);
01612     pdv_serial_read(edt_p, resp, 256);
01613 
01614     edt_msg(DEBUG1, "sending DuncanTech framed commands to camera:\n");
01615 
01616     /*
01617      * send serial init string (first stick on a trailing ':' for parser)
01618      */
01619     p = dd_p->serial_init;
01620     len = strlen(dd_p->serial_init);
01621     if (dd_p->serial_init[len-1] != ':')
01622     {
01623         dd_p->serial_init[len] = ':';
01624         dd_p->serial_init[len+1] = '\0';
01625     }
01626     while ((nextp = strchr(p, ':')))
01627     {
01628         int     ms = 50;
01629         u_char bytebuf[32];
01630         u_char *bp = bytebuf;
01631 
01632         len = nextp - p;
01633         if (len > 31)
01634         {
01635             edt_msg(EDT_MSG_FATAL, "ERROR: serial command too long\n");
01636             return -1;
01637         }
01638 
01639         strncpy(cmdstr, p, len);
01640         cmdstr[len] = 0;
01641         memset(resp, '\0', 257);
01642 
01643         if (len % 2)
01644         {
01645             edt_msg(EDT_MSG_FATAL, "serial_binrary format string error: odd nibble count\n");
01646             return -1;
01647         }
01648 
01649         for (i=0; i<len; i++)
01650         {
01651             if (!isxdigit(cmdstr[i]))
01652             {
01653                 edt_msg(EDT_MSG_FATAL, "serial_binrary format string error: odd nibble count\n");
01654                 return -1;
01655             }
01656         }
01657 
01658         for (i=0, j=0; i<len; i+=2, j++)
01659         {
01660             u_int bint;
01661             bytestr[0] = cmdstr[i];
01662             bytestr[1] = cmdstr[i+1];
01663             bytestr[2] = '\0';
01664             sscanf(bytestr, "%x", &bint);
01665             *(bp++) = (u_char)(bint & 0xff);
01666         }
01667         pdv_send_duncan_frame(edt_p, bytebuf, len/2);
01668 
01669         /* flush out junk */
01670         if (foi)
01671             ret = pdv_serial_wait(edt_p, dd_p->serial_timeout, 0);
01672         else
01673             ret = pdv_serial_wait(edt_p, dd_p->serial_timeout, 128);
01674         pdv_serial_read(edt_p, resp, ret);
01675 
01676         p = nextp + 1;
01677         edt_msleep(ms);
01678     }
01679 
01680 
01681     pdv_update_values_from_camera(edt_p);
01682     edt_set_dependent(edt_p, dd_p);
01683 
01684     return 0;
01685 }
01686 
01687 /*
01688  * multi-purpose ROI check/set. Cases include:
01689  * 
01690  * - xilinx rev doesn't support ROI: return without setting - dalsa line scan:
01691  * check hskip/hactv for valid values (no need to enable tho) - hactv/vactv
01692  * set: set and enable ROI - camera link board: auto set to width (or 4 byte
01693  * aligned), full height - otherwise disable
01694  */
01695 int
01696 check_roi(EdtDev * edt_p, Dependent * dd_p)
01697 {
01698     int     ret = 0;
01699 
01700     if ((dd_p->xilinx_rev < 2) || (dd_p->xilinx_rev > 32))
01701         return 0;
01702 
01703     /*
01704      * NEW 10/30/2008: htaps / vtaps now get set automatically (htaps = #taps as set by
01705      * CL_DATA_PATH_NORM left nibble) unless set explicitly via htaps / vtaps directives
01706      */
01707     if (dd_p->htaps == NOT_SET)
01708     {
01709         if (dd_p->vtaps == NOT_SET)
01710         {
01711             if ((dd_p->cl_data_path == 0)               /* special case, datapath is 00 */
01712              || ((dd_p->cl_data_path & 0xf0) == 0x20))  /* special case RGB */
01713                 dd_p->htaps = 1;
01714             else dd_p->htaps = ((dd_p->cl_data_path & 0xf0) >> 4) + 1;
01715             dd_p->vtaps = 1;
01716         }
01717         else dd_p->htaps = 1;
01718     }
01719     else if (dd_p->vtaps == NOT_SET)
01720         dd_p->vtaps = 1;
01721 
01722     if (dd_p->hactv && dd_p->camera_shutter_timing == PDV_DALSA_LS)
01723     {
01724         if (pdv_dalsa_ls_set_expose(edt_p, dd_p->hskip, dd_p->hactv) != 0)
01725         {
01726             edt_msg(EDT_MSG_FATAL, "Error setting DALSA LS parameters!\n");
01727             ret = -1;
01728         }
01729     }
01730     else if (dd_p->hactv || dd_p->vactv)
01731     {
01732         if (dd_p->hactv == 0)   /* only vactv given; set hactv to a mult. of
01733                                  * 4 */
01734             dd_p->hactv = ((pdv_get_width(edt_p) / 4) * 4);
01735         else if (dd_p->vactv == 0)      /* only hactv given; set hactv to
01736                                          * height */
01737             dd_p->vactv = pdv_get_height(edt_p);
01738 
01739         if ((ret = (pdv_set_roi(edt_p, dd_p->hskip, dd_p->hactv,
01740                                dd_p->vskip, dd_p->vactv) == 0)))
01741             ret = pdv_enable_roi(edt_p, 1);
01742 
01743         if (ret != 0)
01744             edt_msg(EDT_MSG_FATAL, "Error setting or enabling ROI!\n");
01745     }
01746     else if (pdv_is_cameralink(edt_p))
01747         ret = pdv_auto_set_roi(edt_p);  /* also enables */
01748 
01749     else
01750         ret = pdv_enable_roi(edt_p, 0); /* DISable */
01751 
01752     /* new 6/20/06 -- set up pingpong stuff in initcam */
01753     if (edt_p->dd_p->pingpong_varsize)
01754     {
01755         int util3;
01756 
01757         pdv_enable_roi(edt_p, 0); /* disable ROI */
01758 
01759         /* 
01760          * set frame valid done flag and enable ping pong bit (0x02) in
01761          * utility 3 register (NOTE: special FW required, might want to
01762          * check for that here)
01763          */
01764         pdv_set_fval_done(edt_p, 0);
01765         util3 = edt_reg_read(edt_p, PDV_UTIL3);
01766         edt_reg_write(edt_p, PDV_UTIL3, util3 & ~PDV_PPENB);
01767         edt_reg_write(edt_p, PDV_UTIL3, util3 | PDV_PPENB);
01768 
01769         /* reset pingpong to channel 0 */
01770         util3 = edt_reg_read(edt_p, PDV_UTIL3);
01771         edt_reg_write(edt_p, PDV_UTIL3, util3 | PDV_PPRST);
01772         edt_reg_write(edt_p, PDV_UTIL3, util3 & ~PDV_PPRST);
01773         pdv_set_fval_done(edt_p, 1);
01774     }
01775 
01776     return ret;
01777 }
01778 
01779 
01780 void
01781 check_camera_values(EdtDev * ed, Dependent * dd_p)
01782 {
01783     if ((dd_p->shutter_speed_min != NOT_SET)
01784         && ((dd_p->shutter_speed < dd_p->shutter_speed_min)
01785             || (dd_p->shutter_speed > dd_p->shutter_speed_max)))
01786         dd_p->shutter_speed = dd_p->shutter_speed_min;
01787 
01788     if ((dd_p->gain_min != NOT_SET)
01789         && ((dd_p->gain < dd_p->gain_min)
01790             || (dd_p->gain > dd_p->gain_max)))
01791         dd_p->gain = dd_p->gain_min;
01792 
01793     if ((dd_p->offset_min != NOT_SET)
01794         && ((dd_p->level < dd_p->offset_min)
01795             || (dd_p->level > dd_p->offset_max)))
01796         dd_p->level = dd_p->offset_min;
01797 
01798     edt_set_dependent(ed, dd_p);
01799 }
01800 
01801 
01802 int
01803 kodak_query_serial(EdtDev * ed, char *cmd, int *val)
01804 {
01805     char    cmdstr[32];
01806     char    resp[256];
01807     char   *p, *pp;
01808     int     ret;
01809 
01810     if (!(*cmd))
01811         return 0;
01812 
01813     sprintf(cmdstr, "%s?", cmd);
01814     pdv_serial_command(ed, cmdstr);
01815     ret = pdv_read_response(ed, resp);
01816 
01817     if ((ret < 5) || (ret > 15))
01818         return 0;
01819 
01820     p = strchr(resp, ' ');
01821     pp = p + 1;
01822 
01823     if ((p == NULL) || (*pp == '\0') || ((*pp != '-') && !isdigit(*pp)))
01824         return 0;
01825 
01826     /* check for Kodak ES (and ES 4.0) format */
01827     if (strchr(pp, '.') != NULL)
01828     {
01829         /*
01830          * ES 4.0 -- uses fractions for both in and out, we punt and stick
01831          * with positive integers only
01832          */
01833         if (ed->dd_p->camera_shutter_timing == AIA_SERIAL_ES40)
01834         {
01835             *val = (int) (atof(pp) + 0.5);
01836             if (*val < 1)
01837                 *val = 1;
01838         }
01839         /* ES 1.0 -- uses fractions out, ints in */
01840         else
01841             *val = (int) ((atof(pp) / .0636) + 0.5);
01842     }
01843     else
01844         *val = atoi(pp);
01845     return (ret);
01846 }
01847 
01848 
01849 /*
01850  * looking for "0xNN". If so, return 1, else return 0
01851  */
01852 int
01853 is_hex_byte_command(char *str)
01854 {
01855     int     i;
01856 
01857     if (strlen(str) != 4)
01858         return 0;
01859 
01860     if ((strncmp(str, "0x", 2) != 0)
01861         && (strncmp(str, "0X", 2) != 0))
01862         return 0;
01863 
01864     for (i = 2; i < (int) strlen(str); i++)
01865     {
01866         if ((str[i] < '0') && (str[i] > '9')
01867             && (str[i] < 'a') && (str[i] > 'z')
01868             && (str[i] < 'A') && (str[i] > 'Z'))
01869             return 0;
01870     }
01871     return 1;
01872 }
01873 
01874 
01875 /*
01876  * takes a colon separated string of xilinx commands, parses them into
01877  * individual commands, and sends one at a time to the interface xilinx
01878  */
01879 int
01880 send_xilinx_commands(EdtDev * edt_p, char *str)
01881 {
01882     char   *p;
01883     char   *nextp;
01884     int     len;
01885     char    cmdstr[32];
01886     char    cmd[32];
01887     u_int   addr;
01888     unsigned long lvalue;
01889     u_char  value;
01890 
01891     edt_msg(DEBUG1, "sending xilinx commands....\n");
01892 
01893     p = str;
01894 
01895     while ((nextp = strchr(p, ':')))
01896     {
01897         len = nextp - p;
01898         if (len > 31)
01899         {
01900             edt_msg(EDT_MSG_FATAL, "ERROR: xilinx cmd too long\n");
01901             return -1;
01902         }
01903 
01904         strncpy(cmdstr, p, len);
01905         cmdstr[len] = 0;
01906 
01907         sscanf(cmdstr, "%s %x %lx", cmd, &addr, &lvalue);
01908         if (addr < 0xffff)
01909             addr |= 0x01010000;
01910         value = (unsigned char) (lvalue & 0xff);
01911         edt_msg(DEBUG1, "%s %08x %02x\n", cmd, addr, value);
01912 
01913         if (strcmp(cmd, "w") == 0)
01914         {
01915 #if 0
01916             edt_intfc_write(edt_p, addr, value);
01917 #else
01918             edt_msg(PDVLIB_MSG_WARNING, "ALERT: edt_intfc_write commented out for testing only\n");
01919 #endif
01920         }
01921         /* else other commands here */
01922         else
01923         {
01924             edt_msg(PDVLIB_MSG_WARNING, "unknown xilinx command %s\n", cmd);
01925         }
01926 
01927         p = nextp + 1;
01928     }
01929     return 1;
01930 }
01931 
01932 /*
01933  * send raw non/escaped commands to rci foi
01934  */
01935 int
01936 send_foi_commands(EdtDev * edt_p, char *str)
01937 {
01938     char   *p;
01939     char    cmdstr[32];
01940     char    resp[256];
01941     int     len;
01942     int     ret;
01943     char   *nextp;
01944 
01945     p = str;
01946 
01947     edt_msg(DEBUG1, "sending foi commands\n");
01948     while ((nextp = strchr(p, ':')))
01949     {
01950         len = nextp - p;
01951         if (len > 31)
01952         {
01953             edt_msg(EDT_MSG_FATAL, "ERROR: serial command too long\n");
01954             return -1;
01955         }
01956 
01957         strncpy(cmdstr, p, len);
01958         cmdstr[len] = 0;
01959 
01960         edt_send_msg(edt_p, edt_p->foi_unit, cmdstr, strlen(cmdstr));
01961         edt_msg(DEBUG1, "send %s\n", cmdstr);
01962         pdv_serial_wait(edt_p, 100, 10);
01963         edt_msleep(100);
01964         ret = edt_get_msg(edt_p, resp, sizeof(resp));
01965 
01966         p = nextp + 1;
01967     }
01968     return 1;
01969 }
01970 
01971 
01972 
01973 /*
01974  * search for a pattern in a char buffer, return pointer to next char if
01975  * found, NULL if not
01976  */
01977 char   *
01978 grepit(char *buf, char *pat)
01979 {
01980     int     i;
01981 
01982     for (i = 0; i < (int) strlen(buf); i++)
01983     {
01984         if (buf[i] == pat[0])
01985         {
01986             if (strncmp(&buf[i], pat, strlen(pat)) == 0)
01987                 return &buf[i + strlen(pat)];
01988         }
01989     }
01990     return NULL;
01991 }
01992 
01993 /*
01994  * config file takes "\r" and "\n" which need to be converted from strings to
01995  * chars
01996  */
01997 void
01998 check_terminator(char *str)
01999 {
02000     int     i, j = 0;
02001     char    tmpstr[MAXSER];
02002 
02003     for (i = 0; i < (int) strlen(str); i += 2)
02004     {
02005         if (str[i] == '\\')
02006         {
02007             if (str[i + 1] == 'r')
02008                 tmpstr[j++] = '\r';
02009             else if (str[i + 1] == 'n')
02010                 tmpstr[j++] = '\n';
02011             else if (str[i + 1] == '0')
02012                 tmpstr[j++] = '\0';
02013         }
02014     }
02015     tmpstr[j] = '\0';
02016     if (*tmpstr)
02017         strcpy(str, tmpstr);
02018 }
02019 
02020 int
02021 specinst_download(EdtDev * edt_p, char *fname)
02022 {
02023     int     i, n, nb = 0, extras = 0, ena;
02024     char    dmy[32];
02025     int     ret, resp = 0;
02026     u_char  buf[1024];
02027     u_char  savechar;
02028     FILE   *fd;
02029 
02030     edt_msg(DEBUG1, "SpecInst download <%s>", fname);
02031     fflush(stdout);
02032 
02033     if (pdv_access(fname, 0) != 0)
02034     {
02035         edt_msg(EDT_MSG_FATAL, "ERROR: Failed camera download (%s)\n", fname);
02036         return -1;
02037     }
02038 
02039     if ((fd = fopen(fname, "rb")) == NULL)
02040     {
02041         edt_perror(fname);
02042         edt_msg(EDT_MSG_FATAL, "\nERROR: couldn't open camera download file <%s>", fname);
02043         return -1;
02044     }
02045 
02046     pdv_send_break(edt_p);
02047     edt_msleep(500);
02048     if (edt_p->devid == PDVFOI_ID)
02049     {
02050         edt_send_msg(edt_p, 0, "e 0", 3);
02051         edt_msleep(500);
02052         edt_send_msg(edt_p, 0, "cf", 2);
02053         edt_msleep(500);
02054 #if 0
02055         edt_send_msg(edt_p, 0, "cb 19200", 8);
02056         edt_msleep(500);
02057 #endif
02058         edt_send_msg(edt_p, 0, "cw 100", 6);
02059         edt_msleep(500);
02060         edt_flush_fifo(edt_p);
02061     }
02062     /* flush any pending/garbage serial */
02063     ret = pdv_serial_wait_next(edt_p, 500, 256);
02064     if (ret == 0)
02065         ret = 3;
02066     if (ret)
02067         pdv_serial_read(edt_p, (char *) buf, ret);
02068 
02069     ena = pdv_get_waitchar(edt_p, &savechar);
02070     while ((n = fread(buf, 1, 1, fd)))
02071         {
02072                 buf[n] = '\0';
02073                 nb += n;
02074                 if (!(nb % 200))
02075                 {
02076                         edt_msg(DEBUG1, ".");
02077                         fflush(stdout);
02078                 }
02079                 pdv_set_waitchar(edt_p, 1, buf[0]);
02080                 pdv_serial_binary_command(edt_p, (char *) buf, n);
02081 
02082                 if ((ret = pdv_serial_wait_next(edt_p, 50, n)))
02083                 {
02084                         pdv_serial_read(edt_p, dmy, ret);
02085                         /* DEBUG */ dmy[ret] = '\0';
02086                         if (ret > 1)
02087                         {
02088                                 edt_msg(PDVLIB_MSG_WARNING, "specinst_download wrote %x read %x ret %d! \n", buf[0], dmy[0], ret);
02089                         }
02090                 }
02091 
02092                 if (ret > 1)
02093                 {
02094                         ++extras;
02095 
02096                         edt_msg(PDVLIB_MSG_WARNING, "specinst_download: ret %d s/b 1, read <", ret);
02097                         for (i = 0; i < ret; i++);
02098                         edt_msg(PDVLIB_MSG_WARNING, "%c", dmy[i]);
02099                         edt_msg(PDVLIB_MSG_WARNING, ">\n");
02100                         edt_msleep(2000);
02101                 }
02102                 resp += ret;
02103         }
02104     edt_msg(DEBUG1, "done\n");
02105 
02106     /*
02107      * restore old waitchar (if any)
02108      */
02109     pdv_set_waitchar(edt_p, ena, savechar);
02110 
02111     if (extras)
02112         edt_msg(DEBUG1, "Spectral Instruments program download got extra bytes...???\n");
02113     else if (nb > resp)
02114     {
02115         edt_msg(EDT_MSG_FATAL, "Spectral Instruments program download apparently FAILED\n");
02116         edt_msg(EDT_MSG_FATAL, "Wrote %d bytes, got %d responses (continuing anyway)\n", nb, resp);
02117     }
02118 
02119     fclose(fd);
02120     edt_msleep(500);
02121     return 0;
02122 }
02123 
02124 int
02125 specinst_setparams(EdtDev * edt_p, char *fname)
02126 {
02127     char    cmd;
02128     char    resp[256];
02129     u_char  savechar;
02130     int     ret, ena;
02131     char    buf[1024];
02132     u_long  offset;
02133     u_long  param;
02134     u_char  cmdbuf[8];
02135     u_char  offsetbuf[8];
02136     u_char  parambuf[8];
02137     FILE   *fd;
02138     int     si_wait = 150;      /* needs to be more for FOI */
02139 
02140 
02141     edt_msg(DEBUG1, "SpecInst setparams <%s>", fname);
02142     fflush(stdout);
02143 
02144     if (edt_p->devid == PDVFOI_ID)
02145         {
02146                 si_wait = 500;
02147                 ret = pdv_serial_read(edt_p, buf, 64);
02148                 edt_send_msg(edt_p, 0, "cb 19200", 8);
02149                 pdv_set_baud(edt_p, 19200);
02150                 edt_msleep(500);
02151                 ret = pdv_serial_read(edt_p, buf, 64);
02152                 edt_send_msg(edt_p, 0, "cw 8000", 7);
02153                 edt_msleep(500);
02154                 ret = pdv_serial_read(edt_p, buf, 64);
02155         }
02156     if (edt_p->devid == PDVFOI_ID)
02157                 pdv_serial_wait_next(edt_p, si_wait, 0);
02158     else
02159                 pdv_serial_wait_next(edt_p, si_wait, 2);
02160 
02161     ret = pdv_serial_read(edt_p, buf, 64);
02162 
02163 
02164     resp[0] = resp[1] = resp[2] = 0;
02165 
02166     if (pdv_access(fname, 0) != 0)
02167         {
02168                 edt_msg(EDT_MSG_FATAL, "\nERROR: Failed camera setparams (%s) - aborting\n", fname);
02169                 return -1;
02170         }
02171 
02172     if ((fd = fopen(fname, "rb")) == NULL)
02173         {
02174                 edt_perror(fname);
02175                 edt_msg(EDT_MSG_FATAL, "\ncouldn't open camera parameter file <%s> - aborting", fname);
02176                 return -1;
02177         }
02178     if (edt_p->devid == PDVFOI_ID)
02179                 pdv_serial_wait_next(edt_p, 1000, 0);
02180     else
02181                 pdv_serial_wait_next(edt_p, 1000, 64);
02182     ret = pdv_serial_read(edt_p, buf, 64);
02183 
02184     ena = pdv_get_waitchar(edt_p, &savechar);
02185     while (fgets(buf, 1024, fd))
02186     {
02187         if ((buf[0] == '#') || (strlen(buf) < 1))
02188             continue;
02189 
02190         if (sscanf(buf, "%c %lu %lu", &cmd, &offset, &param) != 3)
02191         {
02192             edt_msg(PDVLIB_MSG_WARNING, "\ninvalid format in parameter file <%s> '%s' -- ignored\n", fname, buf);
02193             return -1;
02194         }
02195 
02196         edt_msg(DEBUG1, ".");
02197         fflush(stdout);
02198 
02199         /* edt_msg(DEBUG1, "cmd %c %04x %04x\n",cmd,offset,param) ; */
02200         dvu_long_to_charbuf(offset, offsetbuf);
02201         dvu_long_to_charbuf(param, parambuf);
02202 
02203 
02204         /*
02205          * specinst echoes the the command
02206          */
02207         cmdbuf[0] = cmd;
02208         pdv_set_waitchar(edt_p, 1, cmd);
02209 
02210         pdv_serial_binary_command(edt_p, (char *) cmdbuf, 1);
02211         /* pdv_serial_binary_command(edt_p, &cmd, 1); */
02212         if (edt_p->devid == PDVFOI_ID)
02213             pdv_serial_wait_next(edt_p, 500, 0);
02214         else
02215             pdv_serial_wait_next(edt_p, 500, 2);
02216         ret = pdv_serial_read(edt_p, resp, 2);
02217         if ((ret != 1) || (resp[0] != cmd))
02218         {
02219             edt_msg(EDT_MSG_FATAL, "specinst_setparams: invalid or missing serial response (sent %c, ret %d resp %02x), aborting\n", cmd, ret, (ret > 0) ? cmd : 0);
02220             return -1;
02221         }
02222 
02223         pdv_set_waitchar(edt_p, 1, 'Y');
02224 
02225         pdv_serial_binary_command(edt_p, (char *) offsetbuf, 4);
02226 #if 0
02227         if (edt_p->devid == PDVFOI_ID)
02228             pdv_serial_wait_next(edt_p, si_wait, 0);
02229         else
02230             pdv_serial_wait_next(edt_p, si_wait, 2);
02231         ret = pdv_serial_read(edt_p, buf, 2);
02232 #endif
02233         pdv_serial_binary_command(edt_p, (char *) parambuf, 4);
02234         if (edt_p->devid == PDVFOI_ID)
02235             pdv_serial_wait_next(edt_p, si_wait, 0);
02236         else
02237             pdv_serial_wait_next(edt_p, si_wait, 2);
02238         ret = pdv_serial_read(edt_p, resp, 2);
02239 
02240         if ((ret != 1) || (resp[0] != 'Y'))
02241         {
02242             edt_msg(EDT_MSG_FATAL, "invalid or missing serial response (sent %04x %04x ret %d resp %02x), aborting\n", offset, param, ret, (ret > 0) ? cmd : 0);
02243             return -1;
02244         }
02245     }
02246 
02247     /*
02248      * restore old waitchar (if any)
02249      */
02250     pdv_set_waitchar(edt_p, ena, savechar);
02251 
02252     edt_msg(DEBUG1, "done\n");
02253     fclose(fd);
02254     return 0;
02255 }
02256 
02257 
02258 /*
02259  * serial send AND recieve -- send a command and wait for the response
02260  */
02261 static char stRetstr[256];
02262 char   *
02263 serial_tx_rx(PdvDev * pdv_p, char *getbuf, int hexin)
02264 {
02265     int     i;
02266     int     ret;
02267     int     nbytes;
02268     int     length;
02269     u_char  hbuf[2], waitc, lastbyte;
02270     char    tmpbuf[256];
02271     char   *buf_p, *ibuf_p;
02272     char    buf[2048];
02273     char    bs[32][3];
02274     long    stx_etx_str(u_char * buf, int n);
02275 
02276     ibuf_p = getbuf;
02277     stRetstr[0] = '\0';
02278 
02279     /* flush any junk */
02280     (void) pdv_serial_read(pdv_p, buf, 2048);
02281 
02282     if (hexin)
02283     {
02284         nbytes = sscanf(ibuf_p, "%s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s",
02285                      bs[0], bs[1], bs[2], bs[3], bs[4], bs[5], bs[6], bs[7],
02286               bs[8], bs[9], bs[10], bs[11], bs[12], bs[13], bs[14], bs[15]);
02287 
02288         /*
02289          * change 5/28/99 one serial_binary_command for the whole thing --
02290          * before it did one write per byte which was dumb and didn't work on
02291          * FOI anyway
02292          */
02293         for (i = 0; i < nbytes; i++)
02294         {
02295             if (strlen(bs[i]) > 2)
02296             {
02297                 edt_msg(EDT_MSG_FATAL, "hex string format error\n");
02298                 break;
02299             }
02300             hbuf[i] = (u_char) (strtoul(bs[i], NULL, 16) & 0xff);
02301 
02302         }
02303 
02304         /*
02305          * using pdv_serial_binary_command instead of pdv_serial_write
02306          * because it prepends a 'c' if FOI
02307          */
02308         pdv_serial_binary_command(pdv_p, (char *) hbuf, nbytes);
02309         /* edt_msleep(10000); */
02310     }
02311     else
02312     {
02313         sprintf(tmpbuf, "%s\r", ibuf_p);
02314         edt_msg(DEBUG2, "writing <%s>\n", ibuf_p);
02315         pdv_serial_command(pdv_p, tmpbuf);
02316     }
02317 
02318     /*
02319      * serial_timeout comes from the config file (or -t override flag in this
02320      * app), or if not present defaults to 500
02321      */
02322     pdv_serial_wait(pdv_p, pdv_p->dd_p->serial_timeout, 64);
02323 
02324     /*
02325      * get the return string. How it gets printed depends on whether (1
02326      * ASCII, 2) HEX, or 3) Pulnix STX/ETX format
02327      */
02328     buf_p = buf;
02329     length = 0;
02330     do
02331     {
02332         ret = pdv_serial_read(pdv_p, buf_p, 2048 - length);
02333         edt_msg(DEBUG2, "\nread returned %d\n", ret);
02334 
02335         if (*buf_p)
02336             lastbyte = (u_char)buf_p[strlen(buf_p)-1];
02337 
02338         if (ret != 0)
02339         {
02340             buf_p[ret + 1] = 0;
02341             if (!hexin && (stx_etx_str((u_char *) buf, ret)))
02342                 /* PULNIX TM-1010 fmt */
02343             {
02344                 for (i = 0; i < ret; i++)
02345                 {
02346                     switch (buf_p[i])
02347                     {
02348                     case 0x02:
02349                         sprintf(&stRetstr[strlen(stRetstr)], "[STX]");
02350                         break;
02351 
02352                     case 0x03:
02353                         sprintf(&stRetstr[strlen(stRetstr)], "[ETX]");
02354                         break;
02355 
02356                     case 0x06:
02357                         sprintf(&stRetstr[strlen(stRetstr)], "[ACK]");
02358                         break;
02359                     case 0x15:
02360                         sprintf(&stRetstr[strlen(stRetstr)], "[NAK]");
02361                         break;
02362                     default:
02363                         sprintf(&stRetstr[strlen(stRetstr)], "%c", buf_p[i]);
02364                     }
02365                     edt_msg(DEBUG2, "");
02366                 }
02367             }
02368             /* Hex (or other non-ASCII */
02369             else if (hexin || (!isascii_str((u_char *) buf_p, ret)))
02370             {
02371                 int     i;
02372 
02373                 if (ret)
02374                 {
02375                     for (i = 0; i < ret; i++)
02376                         sprintf(&stRetstr[strlen(stRetstr)], "%s%02x", i ? " " : "", (u_char) buf_p[i]);
02377                 }
02378             }
02379             else                /* simple ASCII */
02380             {
02381                 sprintf(&stRetstr[strlen(stRetstr)], "%s", strip_crlf(buf_p));
02382             }
02383             buf_p += ret;
02384             length += ret;
02385         }
02386         if (pdv_p->devid == PDVFOI_ID)
02387             pdv_serial_wait(pdv_p, 500, 0);
02388         else if (pdv_get_waitchar(pdv_p, &waitc) && (lastbyte == waitc))
02389             ret = 0; /* jump out if waitchar is enabled/received */
02390         else pdv_serial_wait(pdv_p, 500, 64);
02391     } while (ret > 0);
02392 
02393     return stRetstr;
02394 }
02395 
02396 static long
02397 isascii_str(u_char * buf, int n)
02398 {
02399     int     i;
02400 
02401     for (i = 0; i < n; i++)
02402         if ((buf[i] < ' ' || buf[i] > '~')
02403             && (buf[i] != '\n')
02404             && (buf[i] != '\r'))
02405             return 0;
02406     return 1;
02407 }
02408 
02409 long
02410 stx_etx_str(u_char * buf, int n)
02411 {
02412     int     i;
02413 
02414     if ((buf[0] != 0x02) || (buf[n - 1] != 0x03))
02415         return 0;
02416 
02417     for (i = 1; i < n - 1; i++)
02418         if ((buf[i] < ' ' || buf[i] > '~')      /* any ASCII */
02419             && (buf[i] != 0x6)  /* ACK */
02420             && (buf[i] != 0x15))/* NAK */
02421             return 0;
02422     return 1;
02423 }
02424 
02425 void
02426 propeller_sleep(int n)
02427 {
02428     int     i;
02429     char    prop_position[5] = "-\\|/";
02430 
02431     for (i = 0; i < n * 2; i++)
02432     {
02433         edt_msg(DEBUG1, "%c\r", prop_position[i % 4]);
02434         fflush(stdout);
02435         edt_msleep(500);
02436     }
02437 }
02438 
02439 char    scRetStr[256];
02440 char   *
02441 strip_crlf(char *str)
02442 {
02443     char   *p = str;
02444 
02445     scRetStr[0] = '\0';
02446 
02447     while (*p)
02448     {
02449         if (*p == '\r')
02450             sprintf(&scRetStr[strlen(scRetStr)], "\\r");
02451         else if (*p == '\n')
02452             sprintf(&scRetStr[strlen(scRetStr)], "\\n");
02453         else
02454             sprintf(&scRetStr[strlen(scRetStr)], "%c", *p);
02455         ++p;
02456     }
02457 
02458     return scRetStr;
02459 }
02460 
02461 /*
02462  * this code checks for register wrap. Since newer xilinxs have larger
02463  * register space, there's a possibility that we can read/write registers
02464  * but they're actually wrapping by 32. So read/write the low register
02465  * and check if it wraps to high. Uses MASK register and writes back
02466  * when done
02467  *
02468  * RETURNS 1 if wrap, 0 if not
02469  */
02470 int
02471 check_register_wrap(EdtDev *pdv_p)
02472 {
02473     int wrapped = 0;
02474     int r;
02475     int mask_lo, mask_lo_wrap;
02476 
02477     /* definately not in and OLD xilinx.... */
02478     if (pdv_p->dd_p->xilinx_rev < 2 || pdv_p->dd_p->xilinx_rev > 32)
02479         return 1;
02480 
02481     /* made it this far; check for wrap */
02482     mask_lo = edt_reg_read(pdv_p, PDV_MASK_LO);
02483     mask_lo_wrap = edt_reg_read(pdv_p, PDV_MASK_LO+32) ;
02484     edt_reg_write(pdv_p, PDV_MASK_LO+32, 0);
02485     edt_reg_write(pdv_p, PDV_MASK_LO, 0xa5);
02486     if ((r = edt_reg_read(pdv_p, PDV_MASK_LO+32)) == 0xa5)
02487         wrapped = 1;
02488 
02489     /* restore the register */
02490     edt_reg_write(pdv_p, PDV_MASK_LO, mask_lo);
02491     if (!wrapped)
02492         edt_reg_write(pdv_p, PDV_MASK_LO, mask_lo_wrap);
02493 
02494     edt_msg(DEBUG2, "registers %s\n", wrapped? "WRAPPING":"not wrapping");
02495     return wrapped;
02496 }
02497 
02498 void
02499 do_xregwrites(EdtDev *edt_p, Dependent *dd_p)
02500 {
02501     int i;
02502 
02503     /*
02504      * set any registers specifically called out with xregwrite
02505      * xilinx_flag used to be just a flag 0 or 1 to write, now 
02506      * holds the actual address of the register (unless 0xff)
02507      */
02508     for (i = 0; i < 32; i++)
02509     {
02510         if (dd_p->xilinx_flag[i] == 0xff)
02511             break;
02512 
02513         edt_intfc_write(edt_p, dd_p->xilinx_flag[i], dd_p->xilinx_value[i]);
02514         edt_msg(DEBUG2, "xregwrite_%d writing reg 0x%02x value 0x%02x\n",
02515                         dd_p->xilinx_flag[i], dd_p->xilinx_flag[i],
02516                         dd_p->xilinx_value[i]);
02517         dep_wait(edt_p);
02518     }
02519 }
02520 
02521 /*
02522  * special setup for CL2 Camera Link simulator
02523  */
02524 void
02525 setup_cl2_simulator(EdtDev *edt_p, Dependent *dd_p)
02526 {
02527     edt_msg(DEBUG1, "STUB setting up camera link simulator...\n");
02528 }
02529 

Generated on Mon Mar 21 14:14:52 2011 by  doxygen 1.4.7