rhk_scancontrol.C

Go to the documentation of this file.
00001 /* Gnome gxsm - Gnome X Scanning Microscopy
00002  * universal STM/AFM/SARLS/SPALEED/... controlling and
00003  * data analysis software
00004  *
00005  * Gxsm Plugin Name: rhk_scancontrol.C
00006  * ========================================
00007  *
00008  * Copyright (C) 1999 The Free Software Foundation
00009  *
00010  * Authors: Percy Zahl <zahl@fkp.uni-hannover.de>
00011  * additional features: Farid El Gabaly <farid.elgabaly@uam.es> Juan de la Figuera <juan.delafiguera@uam.es>
00012  *
00013  * This program is free software; you can redistribute it and/or modify
00014  * it under the terms of the GNU General Public License as published by
00015  * the Free Software Foundation; either version 2 of the License, or
00016  * (at your option) any later version.
00017  *
00018  * This program is distributed in the hope that it will be useful,
00019  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00020  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00021  * GNU General Public License for more details.
00022  *
00023  * You should have received a copy of the GNU General Public License
00024  * along with this program; if not, write to the Free Software
00025  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
00026  */
00027 
00028 /* -*- Mode: C++; indent-tabs-mode: nil; c-basic-offset: 8 c-style: "K&R" -*- */
00029 
00030 /* Please do not change the Begin/End lines of this comment section!
00031  * this is a LaTeX style section used for auto generation of the PlugIn Manual
00032  * Chapter. Add a complete PlugIn documentation inbetween the Begin/End marks!
00033  * All "% PlugInXXX" commentary tags are mandatory
00034  * All "% OptPlugInXXX" tags are optional
00035  * --------------------------------------------------------------------------------
00036 % BeginPlugInDocuSection
00037 % PlugInDocuCaption: RHK Scan Control (to be ported)
00038 % PlugInName: rhk_scancontrol
00039 % PlugInAuthor: Farid El Gabaly, Juan de la Figuera
00040 % PlugInAuthorEmail: farid.elgabaly@uam.es, juan.delafiguera@uam.es
00041 % PlugInMenuPath: Windows/RHK Scan Control
00042 
00043 % PlugInDescription 
00044  
00045  
00046  Provides a Scan Control Window for the RHK STM
00047  100 electronics. It connects to the \Gxsm\ toolbar buttons
00048  \GxsmEmph{Scan, Movie, Stop} for quick access. The control panel
00049  offers in addition to \GxsmEmph{Scan, Movie, Stop} a \GxsmEmph{Pause}
00050  and \GxsmEmph{HS Capture} button. Use the \GxsmEmph{Pause} button to
00051  pause the scanning process and press it again for continuation.
00052  
00053  The RHK electronics is used through a stand-alone program (rhk\_controller)
00054  that has to be started before Gxsm. Use the computer and port in which that
00055  program is running as the Hardware/Device setting (localhost:5027 is the
00056  default).
00057  
00058  The \GxsmEmph{HS Capture} button starts a continous (movie) high
00059  speed (HS) frame capturing process, were a refresh is done after the
00060  whole scan data is received from the STM100 electronics. The scan
00061  size is limited by the available driver memory (currently 2Mb) on the
00062  rhk\_controller program. The \GxsmEmph{HS Capture} mode assures
00063  precise real time inter line timing and allows maximum frame rates
00064  due to minimized communication between Gxsm and the rhk\_controller
00065  program.
00066 
00067  This plugin is also the main RHK control panel. The RHK interface is slightly
00068  different from the rest of the SPM hardware supported by Gxsm. The
00069  difference is due to the fact that the scan generator is inside the
00070  RHK STM-100, so it is not under the control of Gxsm. The offset and
00071  scan size can only be read, as are the sample bias and the tunneling
00072  current. For now they are only updated when the "update" button is
00073  pressed, and before adquiring an image (the image size is also read from the
00074  RHK so this is a must).  An additional option is the automatic update of the
00075  parameters (every second or so), which can be turned on or off by a
00076  button.
00077 
00078  This RHK Gxsm PlugIn module actually provides not only the the
00079  scanning controls, it does the whole job of data adquisitation
00080  itself, and is a substitute for the standard Scan Control plugin.
00081 
00082  On the left side of the panel, there is a pixmap that shows the
00083  current scan area size and offset relative to the total range available.
00084 
00085 % EndPlugInDocuSection
00086  * --------------------------------------------------------------------------------
00087  */
00088 
00089 //#include <gdk>
00090 #include <gtk/gtk.h>
00091 #include "config.h"
00092 #include "gxsm/plugin.h"
00093 #include "gxsm/unit.h"
00094 #include "gxsm/pcs.h"
00095 #include "gxsm/xsmtypes.h"
00096 #include "gxsm/glbvars.h"
00097 #include "gxsm/action_id.h"
00098 #include "gxsm/instrument.h"
00099 #include "include/dsp-pci32/xsm/xsmcmd.h"
00100 
00101 typedef enum SCAN_DIR { SCAN_XY, SCAN_YX };
00102 typedef enum SCAN_FLAG { SCAN_FLAG_READY, SCAN_FLAG_STOP,  SCAN_FLAG_PAUSE,  SCAN_FLAG_RUN };
00103 typedef enum SCAN_DT_TYPE { SCAN_LINESCAN, SCAN_FRAMECAPTURE };
00104 
00105 static GdkPixmap *pixmap;
00106 static void rhk_scancontrol_StartScan_callback( gpointer );
00107 
00108 // Plugin Prototypes - default PlugIn functions
00109 static void rhk_scancontrol_init (void); // PlugIn init
00110 static void rhk_scancontrol_query (void); // PlugIn "self-install"
00111 static void rhk_scancontrol_about (void); // About
00112 static void rhk_scancontrol_configure (void); // Configure plugIn, called via PlugIn-Configurator
00113 static void rhk_scancontrol_cleanup (void); // called on PlugIn unload, should cleanup PlugIn rescources
00114 
00115 // other PlugIn Functions and Callbacks (connected to Buttons, Toolbar, Menu)
00116 static void rhk_scancontrol_show_callback (GtkWidget *w, void *data); // show ScanControl Window
00117 static void rhk_scancontrol_start_callback (GtkWidget *w, void *data); // called on start scan
00118 static void rhk_scancontrol_movie_callback (GtkWidget *w, void *data); // called on movie start
00119 static void rhk_scancontrol_hscapture_callback (GtkWidget *w, void *data); // called on high speed capture start
00120 static void rhk_scancontrol_pause_callback (GtkWidget *w, void *data); // called on pause/unpause
00121 static void rhk_scancontrol_stop_callback (GtkWidget *w, void *data); // called on scan stop
00122 
00123 static gint rhk_ScanControl_timed(void *dspc); // Autoupdate callback
00124 // Fill in the GxsmPlugin Description here -- see also: Gxsm/src/plugin.h
00125 GxsmPlugin rhk_scancontrol_pi = {
00126         NULL,                   // filled in and used by Gxsm, don't touch !
00127         NULL,                   // filled in and used by Gxsm, don't touch !
00128         0,                  // filled in and used by Gxsm, don't touch !
00129         NULL,                   // The Gxsm-App Class Ref.pointer (called "gapp" in Gxsm) is
00130         // filled in here by Gxsm on Plugin load,
00131         // just after init() is called !!!
00132         "rhk_ScanControl",
00133         "+STM +LAN_RHK:SPMHARD",
00134         // Description, is shown by PluginViewer (Plugin: listplugin, Tools->Plugin Details)
00135         "RHK scan control",
00136         "Farid El Gabaly, Juan de la Figuera",
00137         N_("_Windows/"),
00138         N_("RHK Scan Control"),
00139         N_("open RHK Scan Control Window"),
00140         "RHK Scan Control Window and Scan Generator PlugIn",
00141         NULL,          // error msg, plugin may put error status msg here later
00142 
00143         NULL,          // Plugin Status, managed by Gxsm, plugin may manipulate it too
00144         rhk_scancontrol_init,
00145         rhk_scancontrol_query,
00146         // about-function, can be "NULL"
00147         // can be called by "Plugin Details"
00148         rhk_scancontrol_about,
00149         // configure-function, can be "NULL"
00150         // can be called by "Plugin Details"
00151         rhk_scancontrol_configure,
00152         // run-function, can be "NULL", if non-Zero and no query defined,
00153         // it is called on menupath->"plugin"
00154         NULL,
00155         // cleanup-function, can be "NULL"
00156         // called if present at plugin removeal
00157         rhk_scancontrol_cleanup
00158 };
00159 
00160 // Text used in Aboutbox, please update!!
00161 static const char *about_text = N_("Gxsm RHK Scan Generator and Control Plugin\n\n"
00162                                    "This plugin manages the RHK scanning process\n"
00163                                    "and settings readings."
00164                                    );
00165 
00166 // Symbol "get_gxsm_plugin_info" is resolved by dlsym from Gxsm, used to get Plugin's info!!
00167 // Essential Plugin Function!!
00168 GxsmPlugin *get_gxsm_plugin_info ( void ){
00169         rhk_scancontrol_pi.description = g_strdup_printf(N_("Gxsm rhk_scancontrol plugin %s"), VERSION);
00170         return &rhk_scancontrol_pi;
00171 }
00172 
00173 // data passed to "idle" function call, used to refresh/draw while waiting for data
00174 typedef struct {
00175         GSList *scan_list; // scans to update
00176         GFunc  UpdateFunc; // function to call for background updating
00177         gpointer data; // additional data (here: reference to the current rhk_ScanControl object)
00178 } IdleRefreshFuncData;
00179 
00180 // Scan Control Class based on AppBase
00181 // -> AppBase provides a GtkWindow and some window handling basics used by Gxsm
00182 class rhk_ScanControl : public AppBase{
00183 public:
00184 
00185         rhk_ScanControl(); // create window and setup it contents, connect buttons, register cb's...
00186         virtual ~rhk_ScanControl(); // unregister cb's
00187 
00188         void updateRHK(void);
00189         static void ExecCmd(int cmd);
00190         static void ChangedNotify(GtkWidget *widget,rhk_ScanControl *dspc);
00191         static void ChangedAuto(GtkWidget *widget, rhk_ScanControl *dspc);
00192 
00193 
00194 
00195 
00196         void update(); // window update (inputs, etc. -- here currently not really necessary)
00197 
00198         int free_scan_lists (); // clean up all old/previous scan lists
00199 
00200         int initialize_scan_lists (); /* this scans the current channel list (Channelselector)
00201                                          and sets up a list of all scans used for data storage.
00202                                       */
00203         int initialize_default_pid_src (); // not jet exsistent (plans to split off initialize_scan_lists).
00204         int initialize_pid_src (); // not jet exsistent.
00205         int initialize_daq_srcs (); // not jet exsistent.
00206 
00207         int prepare_to_start_scan (SCAN_DT_TYPE st=SCAN_LINESCAN); /* prepare to start a scan:
00208                                                                       set common scan parameters,
00209                                                                       signal "scan start event" to hardware,
00210                                                                       setup basic scan parameters and put to hardware,
00211                                                                       initialize scan lists,
00212                                                                       check for invalid parameters -- cancel in case of bad settings (return -1 if fails, 0 if OK)
00213                                                                    */
00214 
00215         int setup_scan (int ch, const gchar *titleprefix,
00216                         const gchar *name,
00217                         const gchar *unit, const gchar *label,
00218                         const gchar *vunit = NULL, const gchar *vlabel = NULL,
00219                         const gchar *prbsrcs = NULL, int prboutp = 0);
00220         /* configure a scan -- gets settings from channelselector/configuration */
00221         void do_scanline (int init=FALSE); // execute a single scan line -- or if "line == -1" a HS 2D Area Capture/Scan
00222         void run_probe (int ipx, int ipy); // run a local probe
00223         int do_scan (); // do a full scan, line by line
00224         int do_hscapture (); // do a full frame capute
00225         void set_subscan (int ix0=0, int num=0); /* setup for partial/sub scan,
00226                                                     current line, start at x = ix0, num points = num
00227                                                  */
00228         void stop_scan () {
00229                 if (scan_flag == SCAN_FLAG_RUN || scan_flag == SCAN_FLAG_PAUSE)
00230                         scan_flag = SCAN_FLAG_STOP;
00231         }; // interrupt/cancel a scan in progress
00232         void pause_scan () {
00233                 if (scan_flag == SCAN_FLAG_RUN)
00234                         scan_flag = SCAN_FLAG_PAUSE;
00235                 else
00236                         if (scan_flag == SCAN_FLAG_PAUSE)
00237                                 scan_flag = SCAN_FLAG_RUN;
00238         }; // pause a scan in progress
00239         int scan_in_progress() {
00240                 return scan_flag == SCAN_FLAG_RUN || scan_flag == SCAN_FLAG_PAUSE
00241                         ? TRUE : FALSE;
00242         }; // check if a scan is in progress
00243         int finish_scan (); /* finish the scan:
00244                                return to origin (center of first line (SPM)),
00245                                add some log info,
00246                                free scan lists
00247                             */
00248 
00249         double update_status_info (int reset=FALSE); // compute and show some scan status info
00250         void autosave_check (double sec, int initvalue=0); // check of autosave if requested
00251 
00252         int set_x_lookup_value (int i, double lv); // not jet used (future plans for remote...)
00253         int set_y_lookup_value (int i, double lv); // not jet used
00254         int set_l_lookup_value (int i, double lv); // not jet used
00255 
00256         // some helpers
00257         static void call_scan_start (Scan* sc, gpointer data){ sc->start (); };
00258         static void call_scan_draw_line (Scan* sc, gpointer data){
00259                 sc->draw (((rhk_ScanControl*)data)->line2update, ((rhk_ScanControl*)data)->line2update+1);
00260         };
00261         static void call_scan_stop (Scan* sc, gpointer data){
00262                 sc->stop (((rhk_ScanControl*)data)->scan_flag == SCAN_FLAG_STOP
00263                           && ((rhk_ScanControl*)data)->last_scan_dir == SCAN_XY,
00264                           ((rhk_ScanControl*)data)->line);
00265         };
00266 
00267         void SetScanDir (GtkWidget *w) {
00268                 scan_dir = (SCAN_DIR) ((int) gtk_object_get_data ( GTK_OBJECT (w), "SCANDIR"));
00269                 if (scan_dir==SCAN_XY) gapp->xsm->hardware->ExecCmd(DSP_CMD_MOVETO_X);
00270                 if (scan_dir==SCAN_YX) gapp->xsm->hardware->ExecCmd(DSP_CMD_MOVETO_Y);
00271                 PI_DEBUG(DBG_L2, "SCM=" << scan_dir); };
00272         void ClrScanDir (GtkWidget *w) { };
00273 
00274 private:
00275 
00276         GtkWidget *drawingarea;
00277         /* Backing pixmap for drawing area */
00278 
00279         UnitObj *Unity, *Volt, *Current, *Force;
00280         SCAN_DATA *ScanData;
00281    //     DSP_Param *dsp;
00282         XSM_Instrument *instrument;
00283    //     Scan_Param *scan;
00284         Gtk_EntryControl *ec1;
00285         Gtk_EntryControl *ec2;
00286         Gtk_EntryControl *ec3;
00287         Gtk_EntryControl *ec4;
00288         Gtk_EntryControl *ec5;
00289         Gtk_EntryControl *ec6;
00290         Gtk_EntryControl *ec7;
00291         Gtk_EntryControl *ec8;
00292         gint    timer;
00293 
00294 
00295         Scan   *master_scan; // master "topo" scan -- needed as common parameter reference by probe
00296         Scan   *master_probescan; // master "probe" scan -- needed as common parameter reference by probe
00297 
00298         /* Scan and ProbeScan Lists: xp = X plus (-> dir), xm = X minus (<- dir) */
00299         GSList *xp_scan_list, *xp_prbscan_list;
00300         GSList *xm_scan_list, *xm_prbscan_list;
00301 
00302         /* xp/xm source mask (bit encoding of channels to aquire) */
00303         int    xp_srcs, xm_srcs;
00304 
00305         int YOriginTop; /* TRUE if the Y origin is the top (first) line (all SPM),
00306                            else FALSE (SPALEED uses the image center)
00307                         */
00308 
00309         int line, line2update; // current scan line and line to update in background
00310         int ix0off; // current X offset (in pixels) -- if in subscan mode
00311         SCAN_FLAG scan_flag; // scan status flag
00312         SCAN_DIR  scan_dir, last_scan_dir; // current and last scan direction
00313         gboolean  do_probe; // set if currently in probe mode
00314 };
00315 
00316 rhk_ScanControl *rhk_scancontrol = NULL;
00317 
00318 // Query Function, installs Plugin's in File/Import and Export Menupaths!
00319 // ----------------------------------------------------------------------
00320 // Import Menupath is "File/Import/abc import"
00321 // Export Menupath is "File/Export/abc import"
00322 // ----------------------------------------------------------------------
00323 // !!!! make sure the "rhk_scancontrol_cleanup()" function (see below) !!!!
00324 // !!!! removes the correct menuentries !!!!
00325 
00326 // Add Menu Entries:
00327 // Windows/SPM Scan Control
00328 // Action/SPM Scan Start/Pause/Stop + Toolbar
00329 
00330 static void rhk_scancontrol_query(void)
00331 {
00332         PI_DEBUG( DBG_L2, "rhk_scancontrol_query");
00333         static GnomeUIInfo menuinfo_windowcontrol[] = {
00334                 { GNOME_APP_UI_ITEM,
00335                   N_("RHK Scan Control"), N_("RHK Scan Control Window for advanced control"),
00336                   (gpointer) rhk_scancontrol_show_callback, NULL,
00337                   NULL, GNOME_APP_PIXMAP_STOCK, GNOME_STOCK_MENU_OPEN,
00338                   0, GDK_CONTROL_MASK, NULL },
00339                 GNOMEUIINFO_END
00340         };
00341 
00342         gnome_app_insert_menus (
00343                                 GNOME_APP(rhk_scancontrol_pi.app->getApp()),
00344                                 N_("_Windows/"),
00345                                 menuinfo_windowcontrol
00346                                 );
00347 
00348         if(rhk_scancontrol_pi.status) g_free(rhk_scancontrol_pi.status);
00349         rhk_scancontrol_pi.status = g_strconcat (
00350                                                  N_("Plugin query has attached "),
00351                                                  rhk_scancontrol_pi.name,
00352                                                  N_(": File IO Filters are ready to use"),
00353                                                  NULL);
00354 
00355         PI_DEBUG (DBG_L2, "rhk_scancontrol_query:new" );
00356         rhk_scancontrol = new rhk_ScanControl;
00357 
00358         PI_DEBUG (DBG_L2, "rhk_scancontrol_query:res" );
00359         rhk_scancontrol->SetResName ("WindowRHKScanControl", "false", xsmres.geomsave);
00360 
00361         PI_DEBUG (DBG_L2,"rhk_scancontrol_query:done");
00362 
00363 }
00364 
00365 
00366 
00367 // 5.) Start here with the plugins code, vars def., etc.... here.
00368 // ----------------------------------------------------------------------
00369 //
00370 
00371 
00372 // init-Function
00373 static void rhk_scancontrol_init(void)
00374 {
00375         PI_DEBUG (DBG_L2, "rhk_scancontrol Plugin Init");
00376 }
00377 
00378 // about-Function
00379 static void rhk_scancontrol_about(void)
00380 {
00381         const gchar *authors[] = {rhk_scancontrol_pi.authors, NULL};
00382         gtk_widget_show(gnome_about_new ( rhk_scancontrol_pi.name,
00383                                           VERSION,
00384                                           N_("(C) 2000 the Free Software Foundation"),
00385                                           about_text,
00386                                           authors,
00387                                           NULL,NULL, NULL
00388                                           ));
00389 }
00390 
00391 // configure-Function
00392 static void rhk_scancontrol_configure(void)
00393 {
00394         if(rhk_scancontrol_pi.app)
00395                 rhk_scancontrol_pi.app->message("rhk_scancontrol Plugin Configuration");
00396 }
00397 
00398 // cleanup-Function, make sure the Menustrings are matching those above!!!
00399 static void rhk_scancontrol_cleanup(void)
00400 {
00401         PI_DEBUG (DBG_L2,"rhk_scancontrol Plugin Cleanup");
00402         gnome_app_remove_menus (GNOME_APP (rhk_scancontrol_pi.app->getApp()),
00403                                 N_("_Windows/RHK Scan Control"), 1);
00404         // delete ...
00405         if( rhk_scancontrol )
00406                 delete rhk_scancontrol ;
00407 
00408         if(rhk_scancontrol_pi.status) g_free(rhk_scancontrol_pi.status);
00409 
00410 }
00411 
00412 static void rhk_scancontrol_StartScan_callback( gpointer ){
00413         rhk_scancontrol->update();
00414 }
00415 
00416 
00417 static void rhk_scancontrol_show_callback( GtkWidget* widget, void* data){
00418         if( rhk_scancontrol )
00419                 rhk_scancontrol->show();
00420 }
00421 
00422 static void cb_setscandir( GtkWidget *widget, rhk_ScanControl *scc ){
00423         if (GTK_TOGGLE_BUTTON (widget)->active)
00424                 scc->SetScanDir (widget);
00425         else
00426                 scc->ClrScanDir (widget);
00427 }
00428 
00429 static gint configure_event(GtkWidget *w, GdkEventConfigure *event)
00430 {
00431         if (pixmap) gdk_pixmap_unref(pixmap);
00432         pixmap= gdk_pixmap_new(w->window,w->allocation.width, w->allocation.height, -1);
00433                 gdk_draw_rectangle(pixmap, w->style->white_gc, TRUE, 0, 0,
00434                         w->allocation.width, w->allocation.height);
00435         return(TRUE);
00436 }
00437 
00438 static gint expose_event(GtkWidget *w, GdkEventExpose *e)
00439 {
00440         gdk_draw_pixmap(w->window, w->style->fg_gc[GTK_WIDGET_STATE(w)],
00441                 pixmap, e->area.x, e->area.y, e->area.x, e->area.y,
00442                 e->area.width, e->area.height);
00443         return(FALSE);
00444 }
00445 
00446 static gint rhk_ScanControl_timed(void *dspc)
00447 {
00448         printf("hola\n");
00449 
00450         ((rhk_ScanControl *)dspc)->updateRHK();
00451         return 1;
00452 }
00453 
00454 rhk_ScanControl::rhk_ScanControl ()
00455 {
00456         GtkWidget *box, *hbox;
00457         GtkWidget *vbox_settings, *frame_settings;
00458         GtkWidget *frame_actions, *vbox_actions, *hbox_act1, *hbox_act2;
00459         GtkWidget *frame_param, *vbox_param, *hbox_param;
00460         GtkWidget *frame_dwg, *vbox_dwg;
00461         GtkWidget *vbox_extra;
00462         GtkWidget *button;
00463 
00464         GSList *EC_list=NULL;
00465         GSList **RemoteEntryList = new GSList *;
00466         *RemoteEntryList = NULL;
00467 
00468         GtkWidget *input1;
00469         GtkWidget *input2;
00470         GtkWidget *input3;
00471         GtkWidget *input4;
00472         GtkWidget *input5;
00473         GtkWidget *input6;
00474         GtkWidget *input7;
00475         GtkWidget *input8;
00476 
00477         GtkWidget *button2;
00478 
00479 
00480         master_scan      = NULL;
00481         master_probescan = NULL;
00482 
00483         xp_scan_list    = NULL;
00484         xp_prbscan_list = NULL;
00485         xm_scan_list    = NULL;
00486         xm_prbscan_list = NULL;
00487         scan_flag     = SCAN_FLAG_READY;
00488         scan_dir      = SCAN_XY;
00489         last_scan_dir = SCAN_XY;
00490 
00491         do_probe = FALSE;
00492 
00493         Unity    = new UnitObj(" "," ");
00494         Volt     = new UnitObj("V","V");
00495         Current  = new UnitObj("nA","nA");
00496         Force    = new UnitObj("nN","nN");
00497 
00498         ScanData = &rhk_scancontrol_pi.app->xsm->data;
00499 //        dsp = &rhk_scancontrol_pi.app->xsm->data.hardpars;
00500         //dsp= &gapp->xsm->data.hardpars;
00501 //        scan = &rhk_scancontrol_pi.app->xsm->data.s;
00502         //scan=&gapp->xsm->data.s;
00503         instrument = gapp->xsm->Inst;
00504 
00505         AppWidgetInit("RHK Scan Control");
00506 
00507         box = gtk_vbox_new (FALSE, 0);
00508         gtk_widget_show (box);
00509         gtk_box_pack_start (GTK_BOX (vbox), box, TRUE, TRUE, 0);
00510 
00511         hbox = gtk_hbox_new (FALSE, 0);
00512         gtk_widget_show (hbox);
00513         gtk_box_pack_start (GTK_BOX (box), hbox, TRUE, TRUE, 0);
00514 
00515 #define MYGTK_INPUT(L)  mygtk_create_input(L, vbox_param, hbox_param, 50, 70);
00516 
00517         frame_settings = gtk_frame_new (N_("RHK Control"));
00518         gtk_widget_show (frame_settings);
00519         gtk_container_add (GTK_CONTAINER (hbox), frame_settings);
00520 
00521         vbox_settings = gtk_vbox_new (FALSE, 0);
00522         gtk_widget_show (vbox_settings);
00523         gtk_container_add (GTK_CONTAINER (frame_settings), vbox_settings);
00524 
00525         // Actions frame/vbox
00526 
00527         frame_actions = gtk_frame_new (N_("Actions"));
00528         gtk_widget_show (frame_actions);
00529         gtk_container_add (GTK_CONTAINER (vbox_settings),frame_actions);
00530 
00531         vbox_actions = gtk_vbox_new (TRUE, 0);
00532         gtk_widget_show (vbox_actions);
00533         gtk_container_add (GTK_CONTAINER (frame_actions), vbox_actions);
00534 
00535         // First, buttons (hbox_act1)
00536 
00537         hbox_act1 = gtk_hbox_new (TRUE, 0);
00538         gtk_widget_show (hbox_act1);
00539         gtk_box_pack_start (GTK_BOX (vbox_actions), hbox_act1, FALSE, FALSE, 0);
00540 
00541         button = gtk_button_new_with_label(N_("Start"));
00542         gtk_widget_show (button);
00543         gtk_box_pack_start (GTK_BOX (hbox_act1), button, TRUE, TRUE, 0);
00544         gtk_signal_connect ( GTK_OBJECT (button), "pressed",
00545                              GTK_SIGNAL_FUNC (rhk_scancontrol_start_callback),
00546                              this);
00547         gapp->RegisterPluginToolbarButton (GTK_OBJECT (button), "Toolbar_Scan_Start");
00548 
00549         button = gtk_button_new_with_label(N_("Movie"));
00550         gtk_widget_show (button);
00551         gtk_box_pack_start (GTK_BOX (hbox_act1), button, TRUE, TRUE, 0);
00552         gtk_signal_connect ( GTK_OBJECT (button), "pressed",
00553                              GTK_SIGNAL_FUNC (rhk_scancontrol_movie_callback),
00554                              this);
00555         gapp->RegisterPluginToolbarButton (GTK_OBJECT (button), "Toolbar_Scan_Movie");
00556 
00557         button = gtk_button_new_with_label(N_("HS Capture"));
00558         gtk_widget_show (button);
00559         gtk_box_pack_start (GTK_BOX (hbox_act1), button, TRUE, TRUE, 0);
00560         gtk_signal_connect ( GTK_OBJECT (button), "pressed",
00561                              GTK_SIGNAL_FUNC (rhk_scancontrol_hscapture_callback),
00562                              this);
00563         //      gapp->RegisterPluginToolbarButton (GTK_OBJECT (button), "Toolbar_Scan_HsCapture");
00564 
00565         button = gtk_button_new_with_label(N_("Pause"));
00566         gtk_widget_show (button);
00567         gtk_box_pack_start (GTK_BOX (hbox_act1), button, TRUE, TRUE, 0);
00568         gtk_signal_connect ( GTK_OBJECT (button), "pressed",
00569                              GTK_SIGNAL_FUNC (rhk_scancontrol_pause_callback),
00570                              this);
00571         gapp->RegisterPluginToolbarButton (GTK_OBJECT (button), "Toolbar_Scan_Pause");
00572 
00573         button = gtk_button_new_with_label(N_("Stop"));
00574         gtk_widget_show (button);
00575         gtk_box_pack_start (GTK_BOX (hbox_act1), button, TRUE, TRUE, 0);
00576         gtk_signal_connect ( GTK_OBJECT (button), "pressed",
00577                              GTK_SIGNAL_FUNC (rhk_scancontrol_stop_callback),
00578                              this);
00579         gapp->RegisterPluginToolbarButton (GTK_OBJECT (button), "Toolbar_Scan_Stop");
00580 
00581 
00582         //      Then, radio buttons, hbox_act2
00583 
00584         GtkWidget *radiobutton;
00585         GSList    *radiogroup;
00586 
00587         hbox_act2 = gtk_hbox_new (FALSE, 0);
00588         gtk_widget_show (hbox_act2);
00589         gtk_box_pack_start (GTK_BOX (vbox_actions), hbox_act2, FALSE, FALSE, 0);
00590 
00591         radiobutton = gtk_radio_button_new_with_label( NULL, "XY");
00592         gtk_box_pack_start (GTK_BOX (hbox_act2), radiobutton, TRUE, TRUE, 0);
00593         gtk_widget_show (radiobutton);
00594         gtk_object_set_data (GTK_OBJECT (radiobutton), "SCANDIR", (void*) SCAN_XY);
00595         gtk_signal_connect (GTK_OBJECT (radiobutton), "clicked",
00596                             GTK_SIGNAL_FUNC (cb_setscandir), this);
00597 
00598         radiogroup = gtk_radio_button_group (GTK_RADIO_BUTTON (radiobutton));
00599 
00600         radiobutton = gtk_radio_button_new_with_label (radiogroup, "YX");
00601         gtk_box_pack_start (GTK_BOX (hbox_act2), radiobutton, TRUE, TRUE, 0);
00602         gtk_widget_show (radiobutton);
00603         gtk_object_set_data (GTK_OBJECT (radiobutton), "SCANDIR", (void*) SCAN_YX);
00604         gtk_signal_connect (GTK_OBJECT (radiobutton), "clicked",
00605                             GTK_SIGNAL_FUNC (cb_setscandir), this);
00606 
00607 
00608         // Parameters frame/vbox
00609 
00610         frame_param = gtk_frame_new (N_("Parameters"));
00611         gtk_widget_show (frame_param);
00612         gtk_container_add (GTK_CONTAINER (vbox_settings), frame_param);
00613 
00614         vbox_param = gtk_vbox_new (TRUE, 0);
00615         gtk_widget_show (vbox_param);
00616         gtk_container_add (GTK_CONTAINER (frame_param), vbox_param);
00617 
00618         input1 = mygtk_create_input("Xoff:", vbox_param, hbox_param);
00619         ec1 = new Gtk_EntryControl (Unity, MLD_WERT_NICHT_OK, &ScanData->s.x0, -40000., 40000., "6.1f", input1);
00620         //ec1->Set_ChangeNoticeFkt(RHKControl::ChangedNotify, this);
00621         EC_list = g_slist_prepend( EC_list, ec1);
00622         *RemoteEntryList = ec1->AddEntry2RemoteList("RHK_Xoffset", *RemoteEntryList);
00623 
00624         input2 = mygtk_add_input("Xscan:", hbox_param);
00625         ec2 = new Gtk_EntryControl (Unity, MLD_WERT_NICHT_OK, &ScanData->s.rx, -40000., 40000., "6.1f", input2);
00626         EC_list = g_slist_prepend( EC_list, ec2);
00627         *RemoteEntryList = ec2->AddEntry2RemoteList("RHK_Xscan", *RemoteEntryList);
00628 
00629         input3 = mygtk_create_input("Yoff:", vbox_param, hbox_param);
00630         ec3 = new Gtk_EntryControl (Unity, MLD_WERT_NICHT_OK, &ScanData->s.y0, -40000., 40000., "6.1f", input3);
00631         EC_list = g_slist_prepend( EC_list, ec3);
00632         *RemoteEntryList = ec3->AddEntry2RemoteList("RHK_Yoffset", *RemoteEntryList);
00633 
00634         input4 = mygtk_add_input("Yscan", hbox_param);
00635         ec4 = new Gtk_EntryControl (Unity, MLD_WERT_NICHT_OK, &ScanData->s.ry, -40000., 40000., "6.1f", input4);
00636         EC_list = g_slist_prepend( EC_list, ec4);
00637         *RemoteEntryList = ec4->AddEntry2RemoteList("RHK_Yscan", *RemoteEntryList);
00638 
00639         input5 = mygtk_create_input("Z range", vbox_param, hbox_param);
00640         ec5 = new Gtk_EntryControl (Unity, MLD_WERT_NICHT_OK, &ScanData->s.rz, -40000., 40000., "6.1f", input5);
00641         EC_list = g_slist_prepend( EC_list, ec5);
00642         *RemoteEntryList = ec5->AddEntry2RemoteList("RHK_Z_range", *RemoteEntryList);
00643 
00644         input6 = mygtk_add_input("nx, ny", hbox_param);
00645         ec6 = new Gtk_EntryControl (Unity, MLD_WERT_NICHT_OK, &ScanData->s.nx, 128, 1024, "6.0f", input6);
00646         EC_list = g_slist_prepend( EC_list, ec6);
00647         *RemoteEntryList = ec6->AddEntry2RemoteList("RHK_nx", *RemoteEntryList);
00648 
00649         input7 = mygtk_create_input("UBias", vbox_param, hbox_param);
00650         ec7 = new Gtk_EntryControl (Unity, MLD_WERT_NICHT_OK, &ScanData->hardpars.UTunnel, -40000., 40000., "6.2f", input7);
00651         EC_list = g_slist_prepend( EC_list, ec7);
00652         *RemoteEntryList = ec7->AddEntry2RemoteList("RHK_bias", *RemoteEntryList);
00653 
00654         input8 = mygtk_add_input("Tunnel", hbox_param);
00655         ec8 = new Gtk_EntryControl (Unity, MLD_WERT_NICHT_OK, &ScanData->hardpars.ITunnelSoll, -40000., 40000., "6.2f", input8);
00656         EC_list = g_slist_prepend( EC_list, ec8);
00657         *RemoteEntryList = ec8->AddEntry2RemoteList("RHK_I", *RemoteEntryList);
00658 
00659         //----------------------- update params buttons
00660 
00661         hbox_param = gtk_hbox_new (FALSE, 0);
00662         gtk_widget_show (hbox_param);
00663         gtk_box_pack_start(GTK_BOX(vbox_param), hbox_param, FALSE, FALSE, 0);
00664 
00665         button = gtk_button_new_with_label (N_("Refresh"));
00666         gtk_widget_ref (button);
00667         // gtk_object_set_data_full (GTK_OBJECT (box), "button", button,
00668         //                          (GtkDestroyNotify) gtk_widget_unref);
00669         gtk_widget_show (button);
00670         gtk_box_pack_start (GTK_BOX (hbox_param), button, FALSE, FALSE, 0);
00671         gtk_signal_connect ( GTK_OBJECT (button), "pressed",
00672                              GTK_SIGNAL_FUNC (rhk_ScanControl::ChangedNotify),
00673                              this);
00674 
00675 
00676         button2 = gtk_button_new_with_label (N_("Autoupdate!"));
00677         gtk_widget_ref (button2);
00678         //gtk_object_set_data_full (GTK_OBJECT (box), "button2", button2,
00679         //                        (GtkDestroyNotify) gtk_widget_unref);
00680         gtk_widget_show (button2);
00681         gtk_box_pack_start (GTK_BOX (hbox_param), button2, FALSE, FALSE, 0);
00682         gtk_signal_connect ( GTK_OBJECT (button2), "pressed",
00683                              GTK_SIGNAL_FUNC (rhk_ScanControl::ChangedAuto),
00684                              this);
00685 
00686 
00687         // Empty box
00688 
00689         vbox_extra = gtk_vbox_new (FALSE, 0);
00690         gtk_widget_show (vbox_extra);
00691         gtk_box_pack_start(GTK_BOX(vbox_settings), vbox_extra, TRUE, TRUE, 0);
00692 
00693         //----------------------------TIP POSITION-------------------------------------------
00694 
00695         frame_dwg = gtk_frame_new ("Tip Position");
00696         gtk_widget_ref (frame_dwg);
00697         gtk_object_set_data_full (GTK_OBJECT (hbox), "frame_dwg", frame_dwg,
00698                                   (GtkDestroyNotify) gtk_widget_unref);
00699         gtk_widget_show (frame_dwg);
00700         gtk_container_add (GTK_CONTAINER (hbox), frame_dwg);
00701         vbox_dwg = gtk_vbox_new (FALSE, 0);
00702         gtk_widget_show (vbox_dwg);
00703         gtk_container_add (GTK_CONTAINER (frame_dwg), vbox_dwg);
00704 
00705         drawingarea = gtk_drawing_area_new ();
00706         gtk_drawing_area_size (GTK_DRAWING_AREA(drawingarea), 300, 300);
00707         gtk_widget_show (drawingarea);
00708         gtk_box_pack_start (GTK_BOX (vbox_dwg), drawingarea, TRUE, TRUE, 0);
00709 
00710 
00711         gtk_signal_connect (GTK_OBJECT (drawingarea), "expose_event",
00712                             (GtkSignalFunc) expose_event, NULL);
00713         gtk_signal_connect (GTK_OBJECT(drawingarea),"configure_event",
00714                             (GtkSignalFunc) configure_event, NULL);
00715         g_slist_prepend(EC_list, drawingarea);
00716 
00717         //                       -------- END tip position END ----------
00718 
00719         // save List away...
00720         gtk_object_set_data( GTK_OBJECT (widget), "RHKCONTROL_EC_list", EC_list);
00721 
00722         this->updateRHK();
00723         timer=0;
00724 }
00725 
00726 rhk_ScanControl::~rhk_ScanControl (){
00727 
00728         //  XsmRescourceManager xrm("RHKScanControl");
00729         //  xrm.Put("SPMScanControl.Xorg", Xorg);
00730 
00731         gapp->RegisterPluginToolbarButton (NULL, "Toolbar_Scan_Start");
00732  gapp->RegisterPluginToolbarButton (NULL, "Toolbar_Scan_Movie");
00733         gapp->RegisterPluginToolbarButton (NULL, "Toolbar_Scan_Pause");
00734         gapp->RegisterPluginToolbarButton (NULL, "Toolbar_Scan_Stop");
00735         // remove assigned memory
00736         line = -1;
00737         do_scanline (TRUE);
00738   delete Unity;
00739   delete Volt;
00740   delete Current;
00741   delete Force;
00742   if (timer)
00743         gtk_timeout_remove(timer);
00744 
00745 }
00746 
00747 //      gapp->xsm->hardware->SetScanMode(MEM_ADDTO);
00748 
00749 void rhk_ScanControl::update(){
00750         g_slist_foreach((GSList*)gtk_object_get_data( GTK_OBJECT (widget), "RHKCONTROL_EC_list"),
00751                         (GFunc) App::update_ec, NULL);
00752 }
00753 
00754 // Menu Call Back Fkte
00755 
00756 static void rhk_scancontrol_start_callback (GtkWidget *w, void *data){
00757         if (((rhk_ScanControl*)data) ->  scan_in_progress())
00758                 return;
00759         time_t t; // Scan - Startzeit eintragen
00760         time(&t);
00761         G_FREE_STRDUP_PRINTF(gapp->xsm->data.ui.dateofscan, ctime(&t));
00762         gapp->spm_update_all();
00763         gapp->xsm->hardware->SetScanMode();
00764 
00765         ((rhk_ScanControl*)data) -> do_scan();
00766         if(gapp->xsm->IsMode(MODE_AUTOSAVE))
00767                 gapp->xsm->save(1);
00768 }
00769 
00770 static void rhk_scancontrol_movie_callback (GtkWidget *w, void *data){
00771         int nostop;
00772         if (((rhk_ScanControl*)data) ->  scan_in_progress())
00773                 return;
00774         do {
00775                 time_t t; // Scan - Startzeit eintragen
00776                 time(&t);
00777                 G_FREE_STRDUP_PRINTF(gapp->xsm->data.ui.dateofscan, ctime(&t));
00778                 gapp->spm_update_all();
00779                 gapp->xsm->hardware->SetScanMode();
00780 
00781                 nostop = ((rhk_ScanControl*)data) -> do_scan();
00782 
00783                 if(gapp->xsm->IsMode(MODE_AUTOSAVE))
00784                         gapp->xsm->save(1);
00785         } while (nostop);
00786 }
00787 
00788 
00789 
00790 static void rhk_scancontrol_hscapture_callback (GtkWidget *w, void *data){
00791         int nostop;
00792         if (((rhk_ScanControl*)data) ->  scan_in_progress())
00793                 return;
00794         do {
00795                 time_t t; // Scan - Startzeit eintragen 
00796                 time(&t);
00797                 G_FREE_STRDUP_PRINTF(gapp->xsm->data.ui.dateofscan, ctime(&t));
00798                 gapp->spm_update_all();
00799                 gapp->xsm->hardware->SetScanMode();
00800 
00801                 nostop = ((rhk_ScanControl*)data) -> do_hscapture();
00802 
00803                 if(gapp->xsm->IsMode(MODE_AUTOSAVE))
00804                         gapp->xsm->save(1);
00805         } while (nostop);
00806 }
00807 
00808 static void rhk_scancontrol_pause_callback (GtkWidget *w, void *data){
00809         ((rhk_ScanControl*)data) -> pause_scan();
00810 }
00811 
00812 static void rhk_scancontrol_stop_callback (GtkWidget *w, void *data){
00813         ((rhk_ScanControl*)data) -> stop_scan();
00814 }
00815 
00816 
00817 // ==================================================
00818 // Scan Control Routines
00819 // ==================================================
00820 
00821 
00822 // ========================================
00823 // DoScan
00824 // ========================================
00825 //
00826 // aktiviert automatisch alle vorherigen / bzw. einen neuen Scan Channel
00827 // setzt Channel-Zuordnung
00828 // SRCS MODES:
00829 // bit 0 1 2 3:   PID (Z), ... (calculated stuff (Z=Topo))
00830 // bit 4 5 6 7:   MUXA select PIDSRC (Force, I, dF, ..)   (mux A bei PC31, bei PCI32 alle auf A)
00831 // bit 8,9,10,11: MUXB select Analog Value (Friction, ..) (mux B bei PC31)
00832 // bit 12,13,14,15: AUX select C,D
00833 #define MSK_PID(X)  (1<<((X)&3))
00834 #define MSK_MUXA(X) (1<<(((X)&3)+4))
00835 #define MSK_MUXB(X) (1<<(((X)&3)+8))
00836 #define MSK_AUX(X)  (1<<(((X)&3)+12))
00837 
00838 
00839 int rhk_ScanControl::free_scan_lists (){
00840         if (xp_scan_list){
00841                 g_slist_free (xp_scan_list);
00842                 xp_scan_list = NULL;
00843         }
00844         if (xp_prbscan_list){
00845                 g_slist_free (xp_prbscan_list);
00846                 xp_prbscan_list = NULL;
00847         }
00848         if (xm_scan_list){
00849                 g_slist_free (xm_scan_list);
00850                 xm_scan_list = NULL;
00851         }
00852         if (xm_prbscan_list){
00853                 g_slist_free (xm_prbscan_list);
00854                 xm_prbscan_list = NULL;
00855         }
00856 
00857         return 0;
00858 }
00859 
00860 // analyse channelselections and setup scanlists and scans
00861 int rhk_ScanControl::initialize_scan_lists (){
00862         int i,ipid,idaq,iprb,ch,sok,checks;
00863 
00864         if (xp_scan_list || xm_scan_list
00865             || xp_prbscan_list || xm_prbscan_list) // stop if scan lists are existing!
00866                 return -1;
00867 
00868         do_probe = FALSE;
00869         master_scan = NULL;
00870         master_probescan = NULL;
00871 
00872         sok=FALSE; // ScanOK = no
00873         checks=2;    // only one second try!
00874         xp_srcs = xm_srcs = 0; // reset srcs, take care of PID default, to do!!!!
00875 
00876         // analyze channel settings and create scan lists, and setup this scans
00877         do {
00878                 PI_DEBUG (DBG_L3, "rhk_SCANCONTROL::initialize_scan_lists : do");
00879 
00880                 // Find and init Xp-Scans
00881                 for (ipid=idaq=iprb=i=0; i < MAXSCANS; i++){
00882                         // PID src?  Find the first/next "Topo like" scan...
00883                         // (ipid counts until all PID type scans are checked)
00884                         for (ch = -1; (ipid < PIDCHMAX) && ((ch=gapp->xsm->FindChan(xsmres.pidchno[ipid++])) < 0););
00885 
00886                         if(ch >= 0){ // got one!
00887                                 PI_DEBUG (DBG_L3, "rhk_SCANCONTROL::initialize_scan_lists : Setting up XpScan - PID src found");
00888                                 // add bit to xp_srcs mask
00889                                 xp_srcs |= MSK_PID(ipid-1);
00890                                 // setup this scan
00891                                 setup_scan (ch, "X+",
00892                                             xsmres.pidsrc[ipid-1], 
00893                                             xsmres.pidsrcZunit[ipid-1], 
00894                                             xsmres.pidsrcZlabel[ipid-1]
00895                                         );
00896                                 // and add to list
00897                                 xp_scan_list = g_slist_prepend (xp_scan_list, gapp->xsm->scan[ch]);
00898                                 // got already a master? If not used this one!
00899                                 if (!master_scan) master_scan = gapp->xsm->scan[ch];
00900                                 // got one valid scan, so we could finish if no more... "Scan-OK"
00901                                 sok=TRUE;
00902                         }
00903                         else{
00904                                 // DAQ src? Find additional scans/channels to aquire...
00905                                 // (idaq counts until all checked)
00906                                 for(ch = -1; (idaq < DAQCHMAX) && ((ch=gapp->xsm->FindChan(xsmres.daqchno[idaq++])) < 0););
00907                                 if(ch >= 0){ // got one!
00908                                         // add to xp_srcs mask... use "MUXA" (DA0..3)
00909                                         if(idaq <= 4)
00910                                                 xp_srcs |= MSK_MUXA(idaq-1);
00911                                         else{
00912                                                 // add to xp_srcs mask... use "MUXB" (DA4..7)
00913                                                 if(idaq <= 8)
00914                                                         xp_srcs |= MSK_MUXB(idaq-5);
00915                                                 else
00916                                                         // add to xp_srcs mask... use "AUX" (Auxillary DSP-Data)
00917                                                         xp_srcs |= MSK_AUX(idaq-9);
00918                                         }
00919                                         PI_DEBUG (DBG_L3, "rhk_SCANCONTROL::initialize_scan_lists : Setting up XpScan - DAQ src found");
00920                                         // setup this scan
00921                                         setup_scan (ch, "X+",
00922                                                     xsmres.daqsrc[idaq-1],
00923                                                     xsmres.daqZunit[idaq-1], 
00924                                                     xsmres.daqZlabel[idaq-1]
00925                                                 );
00926                                         // add to list...
00927                                         xp_scan_list = g_slist_prepend (xp_scan_list, gapp->xsm->scan[ch]);
00928                                         if (!master_scan) master_scan = gapp->xsm->scan[ch];
00929                                         sok=TRUE;
00930                                 }
00931                                 else{
00932                                         // PRB src? Similar stuff for Probe type Scans...
00933                                         for(ch = -1; (iprb < PRBMODESMAX) && ((ch=gapp->xsm->FindChan(xsmres.prbchno[iprb++])) < 0););
00934                                         if(ch >= 0){
00935                                                 PI_DEBUG (DBG_L3, "rhk_SCANCONTROL::initialize_scan_lists : Setting up XpScan - PRB src found");
00936 
00937                                                 setup_scan (ch, "X+",
00938                                                             xsmres.prbid[iprb-1],
00939                                                             xsmres.prbYunit[iprb-1], 
00940                                                             xsmres.prbYlabel[iprb-1],
00941                                                             xsmres.prbXunit[iprb-1], 
00942                                                             xsmres.prbXlabel[iprb-1],
00943                                                             xsmres.prbsrcs[iprb-1], 
00944                                                             xsmres.prboutp[iprb-1]
00945                                                         );
00946                                                 xp_prbscan_list = g_slist_prepend (xp_prbscan_list, gapp->xsm->scan[ch]);
00947                                                 // if first probe scan found, use this as probe master
00948                                                 if (!master_probescan) master_probescan = gapp->xsm->scan[ch];
00949                                                 // note that we have to run in probe mode!
00950                                                 do_probe = TRUE;
00951                                                 sok=TRUE;
00952                                         }
00953                                 }
00954                         }
00955                 }
00956     
00957                 // Find and init Xm-Scans
00958                 // similar channel analysis for all XM (<-) scans... -- no probing in this direction!
00959                 for (ipid=idaq=i=0; i<MAXSCANS; i++){
00960                         // new PID src?
00961                         for(ch = -1; (ipid < PIDCHMAX) && ((ch=gapp->xsm->FindChan(-xsmres.pidchno[ipid++])) < 0););
00962 
00963                         if(ch >= 0){
00964                                 PI_DEBUG (DBG_L3, "rhk_SCANCONTROL::initialize_scan_lists : Setting up XmScan - PID src found");
00965                                 xm_srcs |= MSK_PID(ipid-1);
00966 
00967                                 setup_scan (ch, "X-", 
00968                                             xsmres.pidsrc[ipid-1],
00969                                             xsmres.pidsrcZunit[ipid-1], 
00970                                             xsmres.pidsrcZlabel[ipid-1]
00971                                         );
00972                                 xm_scan_list = g_slist_prepend (xm_scan_list, gapp->xsm->scan[ch]);
00973                                 if (!master_scan) master_scan = gapp->xsm->scan[ch];
00974                                 sok=TRUE;
00975                         }
00976                         else{
00977                                 for(ch = -1; (idaq < DAQCHMAX) && ((ch=gapp->xsm->FindChan(-xsmres.daqchno[idaq++])) < 0););
00978                                 if(ch >= 0){
00979                                         if(idaq <= 4)
00980                                                 xm_srcs |= MSK_MUXA(idaq-1);
00981                                         else{
00982                                                 if(idaq <= 8)
00983                                                         xm_srcs |= MSK_MUXB(idaq-5);
00984                                                 else
00985                                                         xm_srcs |= MSK_AUX(idaq-9);
00986                                         }
00987                                         
00988                                         PI_DEBUG (DBG_L3, "rhk_SCANCONTROL::initialize_scan_lists : Setting up XmScan - DAQ src found");
00989                                         setup_scan (ch, "X-",
00990                                                     xsmres.daqsrc[idaq-1], 
00991                                                     xsmres.daqZunit[idaq-1],
00992                                                     xsmres.daqZlabel[idaq-1]
00993                                                 );
00994                                         xm_scan_list = g_slist_prepend (xm_scan_list, gapp->xsm->scan[ch]);
00995                                         if (!master_scan) master_scan = gapp->xsm->scan[ch];
00996                                         sok=TRUE;
00997                                 }
00998                                 else{
00999                                         // PRB src?
01000                                         for(ch = -1; (iprb < PRBMODESMAX) && ((ch=gapp->xsm->FindChan(xsmres.prbchno[iprb++])) < 0););
01001                                         if(ch >= 0){
01002                                                 PI_DEBUG (DBG_L3, "rhk_SCANCONTROL::initialize_scan_lists : Setting up XmScan - PRB src found");
01003 #ifdef ____NO_PRB_IN_XM_DIR____
01004                                                 setup_scan (ch, "X-",
01005                                                             xsmres.prbid[iprb-1],
01006                                                             xsmres.prbYunit[iprb-1], 
01007                                                             xsmres.prbYlabel[iprb-1],
01008                                                             xsmres.prbXunit[iprb-1], 
01009                                                             xsmres.prbXlabel[iprb-1],
01010                                                             TRUE
01011                                                         );
01012                                                 xm_prbscan_list = g_slist_prepend (xm_prbscan_list, gapp->xsm->scan[ch]);
01013                                                 if (!master_probescan) master_probescan = gapp->xsm->scan[ch];
01014                                                 do_probe = FALSE; // not allowed jet!!!
01015                                                 sok=TRUE;
01016 #else
01017                                                 PI_DEBUG (DBG_L2, "Sorry: no Prb in X- direction!!!");
01018 #endif
01019                                         }
01020                                 }
01021                         }
01022                 }
01023                 
01024                 // Automatic mode:
01025                 // if no Scansrc specified -- find free channel and use pid-default ("Topo")
01026                 if(! sok){
01027                         PI_DEBUG (DBG_L3, "rhk_SCANCONTROL::initialize_scan_lists : No Srcs specified, setting up default!");
01028                         ch = gapp->xsm->FindChan(ID_CH_M_ACTIVE);
01029                         if(!(ch >= 0)){
01030                                 ch = gapp->xsm->FindChan(ID_CH_M_MATH);
01031                                 if(!(ch >= 0))
01032                                         ch = gapp->xsm->FindChan(ID_CH_M_OFF);
01033                                 else{
01034                                         scan_flag = SCAN_FLAG_RUN;
01035                                         XSM_SHOW_ALERT(ERR_SORRY, ERR_NOFREECHAN,"",1);
01036                                         return FALSE;
01037                                 }
01038                         }
01039                         gapp->channelselector->SetMode(ch, xsmres.piddefault);
01040                         gapp->xsm->ChannelMode[ch] =  xsmres.piddefault;
01041                         gapp->xsm->ChannelScanMode[ch] = gapp->xsm->ChannelScanMode[ch] < 0 ? -xsmres.piddefault : xsmres.piddefault;
01042                 }
01043         }while (! sok && --checks);
01044 
01045         // if sth, went wrong... (should never happen)
01046         if (!checks)
01047                 XSM_SHOW_ALERT (ERR_SORRY, ERR_NOSRCCHAN, "", 1);
01048 
01049         return 0;
01050 }
01051 
01052 int rhk_ScanControl::setup_scan (int ch, 
01053                                  const gchar *titleprefix, 
01054                                  const gchar *name,
01055                                  const gchar *unit,
01056                                  const gchar *label,
01057                                  const gchar *vunit,
01058                                  const gchar *vlabel,
01059                                  const gchar *prbsrcs,
01060                                  int prboutp
01061         ){
01062         PI_DEBUG (DBG_L2, "setup_scan");
01063         // did this scan already exists?
01064         if ( ! gapp->xsm->scan[ch]){ // make a new one ?
01065                 gapp->xsm->scan[ch] = gapp->xsm->NewScan (gapp->xsm->ChannelView[ch],
01066                                                           gapp->xsm->data.display.ViewFlg,
01067                                                           ch, 
01068                                                           &gapp->xsm->data);
01069                 // Error ?
01070                 if (!gapp->xsm->scan[ch]){
01071                         XSM_SHOW_ALERT (ERR_SORRY, ERR_NOMEM,"",1);
01072                         return FALSE;
01073                 }
01074         }
01075 
01076         // Setup correct Z unit
01077         UnitObj *u = gapp->xsm->MakeUnit (unit, label);
01078         gapp->xsm->scan[ch]->data.SetZUnit (u);
01079         delete u;
01080 
01081         // Probe stuff to do?
01082         if (prbsrcs){
01083                 PI_DEBUG (DBG_L2, "setup_scan: analyse prbsrcs=" << prbsrcs);
01084                 Mem2d *m=gapp->xsm->scan[ch]->mem2d;
01085                 m->Resize (m->GetNx (), m->GetNy (), m->GetNv (), ZD_FLOAT);
01086                 gapp->xsm->scan[ch]->create (TRUE, TRUE);
01087                 gapp->xsm->scan[ch]->data.lp.srcs  = 0;
01088                 gapp->xsm->scan[ch]->data.lp.nsrcs = 0;
01089                 gapp->xsm->scan[ch]->data.lp.outp  = prboutp;
01090                 for (int k = 0; k < (int)strlen (prbsrcs); ++k)
01091                         if (prbsrcs[k] == '1'){
01092                                 gapp->xsm->scan[ch]->data.lp.srcs |= 1<<k;
01093                                 gapp->xsm->scan[ch]->data.lp.nsrcs++;
01094                         }
01095                 UnitObj *u = gapp->xsm->MakeUnit (vunit, vlabel);
01096                 gapp->xsm->scan[ch]->data.SetVUnit (u);
01097                 delete u;
01098                 PI_DEBUG (DBG_L2, "PRB: nsrcs=" << gapp->xsm->scan[ch]->data.lp.nsrcs
01099                      << "  srcs=" << gapp->xsm->scan[ch]->data.lp.srcs
01100                      << "  outp=" << gapp->xsm->scan[ch]->data.lp.outp
01101                      << "  nvalues=" << gapp->xsm->scan[ch]->data.lp.nvalues);
01102         }
01103         else
01104                 gapp->xsm->scan[ch]->create (TRUE);
01105 
01106         // setup dz from instrument definition
01107         gapp->xsm->scan[ch]->data.s.dz = gapp->xsm->Inst->ZResolution (unit);
01108 
01109         // set scan title, name, ... and draw it!
01110         gchar *scantitle = g_strdup_printf ("%s %s", titleprefix, name);
01111         gapp->xsm->scan[ch]->data.ui.SetName (scantitle);
01112         gapp->xsm->scan[ch]->data.ui.SetOriginalName ("unknown");
01113         gapp->xsm->scan[ch]->data.ui.SetTitle (scantitle);
01114         gapp->xsm->scan[ch]->data.ui.SetType (scantitle);
01115         g_free (scantitle);
01116         gapp->xsm->scan[ch]->draw ();
01117 
01118         return 0;
01119 }
01120 
01121 int rhk_ScanControl::prepare_to_start_scan (SCAN_DT_TYPE st){
01122         // which origin mode?
01123         YOriginTop = IS_SPALEED_CTRL ? FALSE : TRUE;
01124 
01125         scan_flag = SCAN_FLAG_RUN;
01126 
01127         gapp->SetStatus ("Starting Scan: Ch.Setup");
01128         gapp->check_events ();
01129     
01130         // update hardware parameters
01131         this->updateRHK();
01132         gapp->xsm->data.s.dz = gapp->xsm->Inst->ZResolution ();
01133         gapp->xsm->data.hardpars.LS_dnx = R2INT (gapp->xsm->Inst->XA2Dig (gapp->xsm->data.s.dx));
01134         gapp->xsm->data.hardpars.LS_nx2scan = gapp->xsm->data.s.nx;
01135         gapp->xsm->data.hardpars.SPA_Length = R2INT (gapp->xsm->Inst->XA2Dig (gapp->xsm->data.s.rx));
01136 
01137         gapp->SignalStartScanEventToPlugins ();
01138 
01139 
01140         // Init Scanobjects, do Channelsetup... some complex stuff...
01141         int result = initialize_scan_lists ();;
01142 
01143         if (result){
01144                 XSM_SHOW_ALERT (ERR_SORRY, ERR_SCAN_CANCEL,
01145                                 "Channel setup failed.",
01146                                 1);
01147                 return result;
01148         }
01149 
01150         // count channels and check if total data amount fits into hardware/transferbuffer/etc. hard limits
01151         int ns_xp=0;
01152         int ns_xm=0;
01153         for (int i=0; i<16; ++i){
01154                 if (xp_srcs&(1<<i)) ++ns_xp;
01155                 if (xm_srcs&(1<<i)) ++ns_xm;
01156         }
01157 
01158         // Check Ranges/Sizes with Hardware/DSP Memory
01159         switch (st){
01160         case SCAN_LINESCAN:
01161                 if (gapp->xsm->data.s.nx*ns_xp >= gapp->xsm->hardware->GetMaxPointsPerLine ()){
01162                         gchar *maxtxt = g_strdup_printf ("Hardware limits points per line to\n"
01163                                                          "%ld in total for all channels (->)!",
01164                                                          gapp->xsm->hardware->GetMaxPointsPerLine());
01165                         XSM_SHOW_ALERT (ERR_SORRY,ERR_SCAN_CANCEL, maxtxt, 1);
01166                         g_free (maxtxt);
01167                         return -1;
01168                 }
01169                 if (gapp->xsm->data.s.nx*ns_xm >= gapp->xsm->hardware->GetMaxPointsPerLine ()){
01170                         gchar *maxtxt = g_strdup_printf ("Hardware limits points per line to\n"
01171                                                          "%ld in total for all channels (<-)!",
01172                                                          gapp->xsm->hardware->GetMaxPointsPerLine());
01173                         XSM_SHOW_ALERT (ERR_SORRY,ERR_SCAN_CANCEL, maxtxt, 1);
01174                         g_free (maxtxt);
01175                         return -1;
01176                 }
01177                 return 0;
01178         case SCAN_FRAMECAPTURE:
01179                 if (gapp->xsm->data.s.nx*gapp->xsm->data.s.ny*ns_xp >= gapp->xsm->hardware->GetMaxPointsPerLine ()){
01180                         gchar *maxtxt = g_strdup_printf ("Hardware limits points per frame to\n"
01181                                                          "%ld in total for all channels (->)!",
01182                                                          gapp->xsm->hardware->GetMaxPointsPerLine());
01183                         XSM_SHOW_ALERT (ERR_SORRY,ERR_SCAN_CANCEL, maxtxt, 1);
01184                         g_free (maxtxt);
01185                         return -1;
01186                 }
01187                 if (gapp->xsm->data.s.nx*gapp->xsm->data.s.ny*ns_xm >= gapp->xsm->hardware->GetMaxPointsPerLine ()){
01188                         gchar *maxtxt = g_strdup_printf ("Hardware limits points per frame to\n"
01189                                                          "%ld in total for all channels (<-)!",
01190                                                          gapp->xsm->hardware->GetMaxPointsPerLine());
01191                         XSM_SHOW_ALERT (ERR_SORRY,ERR_SCAN_CANCEL, maxtxt, 1);
01192                         g_free (maxtxt);
01193                         return -1;
01194                 }
01195                 return 0;
01196         default: return -1;
01197         }
01198 }
01199 
01200 // run "background" update function(s)
01201 void IdleRefreshFunc (gpointer data){
01202         g_slist_foreach ((GSList*) ((IdleRefreshFuncData*)data)->scan_list,
01203                          (GFunc) ((IdleRefreshFuncData*)data)->UpdateFunc,
01204                          ((IdleRefreshFuncData*)data)->data);
01205 }
01206 
01207 // execute a single scan line -- or if "line == -1" a HS 2D Area Capture/Scan
01208 void rhk_ScanControl::do_scanline (int init){
01209         static Mem2d **m2d_xp=NULL;
01210         static Mem2d **m2d_xm=NULL;
01211         static IdleRefreshFuncData idf_data;
01212 
01213         // if first time called/first line, do some local (static vars) initializations here!
01214         if (init){
01215                 int num;
01216                 PI_DEBUG (DBG_L2, "rhk_ScanControl::do_scanline : init");
01217                 if (m2d_xp){
01218                         g_free (m2d_xp);
01219                         m2d_xp = NULL;
01220                 }
01221                 if (m2d_xm){
01222                         g_free (m2d_xm);
01223                         m2d_xm = NULL;
01224                 }
01225                 if( line < 0)
01226                         return;
01227 
01228                 num = g_slist_length (xp_scan_list);
01229                 if (num>0){
01230                         Mem2d **m;
01231                         m = m2d_xp = (Mem2d**) g_new (Mem2d*, num+1);
01232                         GSList* tmp = g_slist_copy (xp_scan_list);
01233                         GSList* rev = tmp = g_slist_reverse(tmp);
01234                         while (tmp){
01235                                 *m++ = ((Scan*)tmp->data)->mem2d;
01236                                 tmp = g_slist_next (tmp);
01237                         }
01238                         *m = NULL;
01239                         g_slist_free (rev);
01240                 }
01241 
01242                 num = g_slist_length (xm_scan_list);
01243                 PI_DEBUG (DBG_L2, "rhk_ScanControl::do_scanline : init, num xm=" << num);
01244                 if (num > 0){
01245                         Mem2d **m;
01246                         m = m2d_xm = (Mem2d**) g_new (Mem2d*, num+1);
01247                         GSList* tmp = g_slist_copy (xm_scan_list);
01248                         GSList* rev = tmp = g_slist_reverse(tmp);
01249                         while (tmp){
01250                                 *m++ = ((Scan*)tmp->data)->mem2d;
01251                                 tmp = g_slist_next (tmp);
01252                         }
01253                         *m = NULL;
01254                         g_slist_free (rev);
01255                 }
01256                 idf_data.scan_list  = NULL;
01257                 idf_data.UpdateFunc = (GFunc) rhk_ScanControl::call_scan_draw_line;
01258                 idf_data.data = this;
01259                 PI_DEBUG (DBG_L2, "rhk_ScanControl::do_scanline : init done");
01260 
01261                 return;
01262         }
01263 
01264         if (line == -1){ // HS Capture -- Area Scan!!!
01265                 // do X+ Scan ?
01266                 if (m2d_xp)
01267                         gapp->xsm->hardware->ScanLineM (-1,  1, xp_srcs, m2d_xp, ix0off);
01268 
01269                 // do X- Scan ?
01270                 if (m2d_xm)
01271                         PI_DEBUG (DBG_L2,"Sorry -- not in HS Capture mode");
01272 
01273                 return;
01274         }
01275 
01276         // do Scanline (XP (+))
01277         // and display new Data
01278         
01279         if (do_probe){ // in probe mode?
01280 //              gapp->xsm->hardware->SetIdleFunc (NULL, NULL);
01281                 if ((line % master_probescan->data.lp.n_subsample) == 0){
01282                         PI_DEBUG (DBG_L2,"RHKScanPlugin: do_scanline, STS scan " << line << " SubSmp:" << master_probescan->data.lp.n_subsample);
01283                         // split line in segments and do each separate, then do probing, ...
01284                         // only in forward direction now...
01285                         for (int k = 0;
01286                              k < master_scan->data.s.nx && scan_flag != SCAN_FLAG_STOP;
01287                              k += master_probescan->data.lp.n_subsample){
01288 
01289                                 PI_DEBUG (DBG_L2,"RHKScanPlugin: do_scanline - SubSegment " << k);
01290                                 // do probe
01291                                 PI_DEBUG (DBG_L2,"RHKScanPlugin: do_scanline - SubSegment Probe here");
01292                                 gapp->xsm->hardware->PauseScan2D ();
01293                                 run_probe (k/master_probescan->data.lp.n_subsample,
01294                                            line/master_probescan->data.lp.n_subsample);
01295 
01296                                 // Enable sub line scan
01297                                 PI_DEBUG (DBG_L2,"RHKScanPlugin: do_scanline - SubSegment Scan...");
01298 
01299                                 if (k+master_probescan->data.lp.n_subsample >= master_scan->data.s.nx)
01300                                         set_subscan (k, master_scan->data.s.nx-k);
01301                                 else
01302                                         set_subscan (k, master_probescan->data.lp.n_subsample);
01303                                 gapp->xsm->hardware->ResumeScan2D ();
01304                                 
01305                                 // do X+ Scan segment?
01306                                 if (m2d_xp){
01307 
01308                                         gapp->xsm->hardware->ScanLineM(line,  1, xp_srcs, m2d_xp, k);
01309                                 }
01310                         }
01311 
01312                         PI_DEBUG (DBG_L2,"RHKScanPlugin: do_scanline, STS scan - update, draw");
01313 
01314                         line2update = line/master_probescan->data.lp.n_subsample;
01315                         idf_data.scan_list =  xp_prbscan_list;
01316                         gapp->xsm->hardware->SetIdleFunc (&IdleRefreshFunc, &idf_data);
01317                         
01318                         // Reset sub line scan
01319                         gapp->xsm->hardware->PauseScan2D ();
01320                         set_subscan ();
01321                         gapp->xsm->hardware->ResumeScan2D ();
01322                 }else{
01323                         // do full inter subgrid line
01324                         PI_DEBUG (DBG_L2, "RHKScanPlugin: do_scanline - SubScanmode, Scanning interline " << line);
01325                         // do X+ Scan?
01326                         if (m2d_xp){
01327                                 gapp->xsm->hardware->ScanLineM (line,  1, xp_srcs, m2d_xp, ix0off);
01328                                 line2update = line;
01329                                 idf_data.scan_list = xp_scan_list;
01330                                 gapp->xsm->hardware->SetIdleFunc (&IdleRefreshFunc, &idf_data);
01331                         }
01332                 }
01333         }else{ // usual scan, line by line
01334                 // do X+ Scan?
01335                 if (m2d_xp){
01336                         gapp->xsm->hardware->ScanLineM (line,  1, xp_srcs, m2d_xp, ix0off);
01337                         // setup idle func -- executed on next wait for data!
01338                         line2update = line;
01339                         idf_data.scan_list = xp_scan_list;
01340                         gapp->xsm->hardware->SetIdleFunc (&IdleRefreshFunc, &idf_data);
01341                 }
01342 
01343 
01344                 // do X- Scan ?
01345                 if (m2d_xm){
01346                         line2update = line;
01347                         gapp->xsm->hardware->ScanLineM(line, -1, xm_srcs, m2d_xm, ix0off);
01348                         idf_data.scan_list = xm_scan_list;
01349                         gapp->xsm->hardware->SetIdleFunc (&IdleRefreshFunc, &idf_data);
01350                 } 
01351         }
01352 
01353         autosave_check (update_status_info ());
01354 }
01355 
01356 void rhk_ScanControl::run_probe (int ipx, int ipy){
01357         if (!xp_prbscan_list) return;
01358 
01359         PI_DEBUG (DBG_L2,"RHKScanPlugin: run_probe " << ipx << " " << ipy);
01360         // for all probe scans...
01361         for (GSList* tmp = xp_prbscan_list; tmp; tmp = g_slist_next (tmp)){
01362                 Scan *ps = (Scan*)tmp->data;
01363 
01364                 // set probe parameters
01365                 PARAMETER_SET hardpar;
01366                 hardpar.N   = DSP_PRBNAVE+1;
01367                 hardpar.Cmd = DSP_CMD_PROBESCAN;
01368                 hardpar.hp[DSP_PRBSRCS    ].value = ps->data.lp.srcs; // Codierte MUX/Srcs Configuration
01369                 hardpar.hp[DSP_PRBOUTP    ].value = ps->data.lp.outp; // Channel to Probe
01370                 hardpar.hp[DSP_PRBNX      ].value = ps->data.lp.nvalues;
01371                 hardpar.hp[DSP_PRBXS      ].value = ps->data.lp.value_start; 
01372                 hardpar.hp[DSP_PRBXE      ].value = ps->data.lp.value_end; 
01373                 hardpar.hp[DSP_PRBACAMP   ].value = ps->data.lp.ac_amp;
01374                 hardpar.hp[DSP_PRBACFRQ   ].value = ps->data.lp.ac_frq;
01375                 hardpar.hp[DSP_PRBACPHASE ].value = ps->data.lp.ac_phase;
01376                 hardpar.hp[DSP_PRBACMULT  ].value = ps->data.lp.ac_mult = 1.0; // fixed to 1 for now.
01377                 hardpar.hp[DSP_PRBDELAY   ].value = 0.;
01378                 hardpar.hp[DSP_PRBCIVAL   ].value = 0.;
01379                 hardpar.hp[DSP_PRBNAVE    ].value = ps->data.lp.nAvg;
01380                 hardpar.hp[DSP_PRBGAPADJ  ].value = ps->data.lp.gap_adj/gapp->xsm->Inst->ZResolution(); // convert to DigUnits!!!!
01381                 PI_DEBUG (DBG_L2,"PRB scan: Start");
01382                 // set data and run probe...
01383                 gapp->xsm->hardware->SetParameter (hardpar, FALSE);
01384                 PI_DEBUG (DBG_L2,"PRB scan: ACAmp:" << ps->data.lp.ac_amp);
01385                 // get data
01386                 gapp->xsm->hardware->ReadProbeData (ps->data.lp.nsrcs, ps->data.lp.nvalues, ipx, ipy,
01387                                                     ps->mem2d, 1./ps->data.lp.ac_mult);
01388         }
01389 }
01390 
01391 void rhk_ScanControl::set_subscan (int ix0, int num){
01392         int n;
01393         ix0off = ix0;
01394         if(ix0 >= 0 && num > 0){ printf("Setting subscan!!!\n");
01395                 if (master_probescan){
01396                         gapp->xsm->hardware->PutParameter(&master_probescan->data, 1);
01397                         n = master_probescan->data.hardpars.LS_nx2scan = num;
01398                         master_probescan->data.hardpars.LS_nx_pre = 0;
01399                         master_probescan->data.hardpars.SPA_Length = R2INT(gapp->xsm->Inst->XA2Dig(master_scan->data.s.rx*num/master_scan->data.s.nx));
01400                         
01401                 } else { PI_DEBUG (DBG_L2,"ERROR not probing"); return; }
01402         } else {
01403                 gapp->xsm->hardware->PutParameter (&master_scan->data, 1);
01404                 n = master_scan->data.s.nx;
01405         }
01406 
01407         PI_DEBUG (DBG_L2, "rhk_ScanControl::set_subscan" << ix0off << ":" << n);
01408 
01409         // Setup Copy Mode in mem2d...
01410         for (GSList* tmp = xp_scan_list; tmp; tmp = g_slist_next (tmp))
01411                 ((Scan*)tmp->data) -> mem2d->data->ZPutDataSetDest (ix0off, n);
01412 
01413         for (GSList* tmp = xm_scan_list; tmp; tmp = g_slist_next (tmp))
01414                 ((Scan*)tmp->data) -> mem2d->data->ZPutDataSetDest (ix0off, n);
01415 }       
01416 
01417 int rhk_ScanControl::do_scan (){
01418         int yline;
01419 
01420         PI_DEBUG (DBG_L2, "do_scan");
01421 
01422         if (scan_in_progress ()){
01423                 PI_DEBUG (DBG_L2, "do_scan scan in progress, exiting.");
01424                 return FALSE;
01425         }
01426 
01427         if (prepare_to_start_scan ()){
01428                 PI_DEBUG (DBG_L2, "prepare scan failed, exiting.");
01429                 stop_scan ();
01430                 free_scan_lists ();
01431                 return FALSE;
01432         }
01433 
01434         PI_DEBUG (DBG_L2, "do_scan precheck done.");
01435 
01436         // now freeze all scanparameters
01437         gapp->spm_freeze_scanparam();
01438 
01439         // Set Start Time, notify scans about, initialisations...
01440         g_slist_foreach ((GSList*) xp_scan_list,
01441                         (GFunc) rhk_ScanControl::call_scan_start, this);
01442         g_slist_foreach ((GSList*) xm_scan_list,
01443                         (GFunc) rhk_ScanControl::call_scan_start, this);
01444 
01445         gapp->xsm->hardware->StartScan2D();
01446 
01447         line = 0;
01448         do_scanline (TRUE);
01449         update_status_info (TRUE);
01450         autosave_check (0., xsmres.AutosaveValue);
01451         set_subscan ();
01452 
01453         // copy muxsettings from other direction if not given
01454         // weird... to fix !!!
01455         if(!xm_srcs) xm_srcs = xp_srcs;
01456         if(!xp_srcs) xp_srcs = xm_srcs;
01457         
01458         PI_DEBUG (DBG_L2, "DoScan: Setup MUX");
01459     
01460         // MUX-Codierung:
01461 #ifdef XSM_DEBUG_OPTION
01462         PI_DEBUG (DBG_L2,  "xp_srcs: " << xp_srcs );
01463         for(int i=0; i<16; i++) PI_DEBUG (DBG_L3, (int)((xp_srcs&(1<<i))?1:0));
01464         PI_DEBUG (DBG_L2,  "xm_srcs: " << xm_srcs );
01465         for(int i=0; i<16; i++) PI_DEBUG (DBG_L3, (int)((xm_srcs&(1<<i))?1:0));
01466 #endif
01467 
01468         PI_DEBUG (DBG_L2, "DoScan: Start Scan now");
01469 
01470         {
01471                 gchar *muxcoding = g_strdup_printf ("xp_srcs: %2X  xm_srcs: %2X", xp_srcs, xm_srcs);
01472                 gapp->monitorcontrol->LogEvent ("*StartScan", muxcoding);
01473                 g_free (muxcoding);
01474         }
01475 
01476         // run scan now...
01477         for (line=0; (line<master_scan->data.s.ny) && scan_flag != SCAN_FLAG_STOP;){
01478 
01479                 if (scan_flag == SCAN_FLAG_RUN){
01480 //                      PI_DEBUG (DBG_L2, "Running Line" << line);
01481                         // execute scan line
01482                         do_scanline ();
01483                         ++line;
01484                 }
01485                 gapp->check_events();
01486         }
01487 
01488         // finish scan
01489         gapp->xsm->hardware->EndScan2D ();
01490         gapp->xsm->hardware->CallIdleFunc ();
01491         gapp->xsm->hardware->SetIdleFunc (NULL, NULL);
01492 
01493         if( line < master_scan->data.s.ny && line&1)
01494                 line++;
01495 
01496         // Set Scan End Time/trucate unfinished scans to save space
01497 
01498         g_slist_foreach ((GSList*) xp_scan_list,
01499                         (GFunc) rhk_ScanControl::call_scan_stop, this);
01500         g_slist_foreach ((GSList*) xm_scan_list,
01501                         (GFunc) rhk_ScanControl::call_scan_stop, this);
01502 
01503         return finish_scan ();
01504 }
01505 
01506 int rhk_ScanControl::do_hscapture (){
01507         if (scan_in_progress ()){
01508                 PI_DEBUG (DBG_L2, "do_scan scan in progress, exiting.");
01509                 return FALSE;
01510         }
01511 
01512         if (prepare_to_start_scan (SCAN_FRAMECAPTURE)){
01513                 PI_DEBUG (DBG_L2, "prepare scan failed, exiting.");
01514                 stop_scan ();
01515                 free_scan_lists ();
01516                 return FALSE;
01517         }
01518 
01519         // now freeze all scanparameters
01520         gapp->spm_freeze_scanparam();
01521 
01522         // Set Start Time, notify scans about, initialisations...
01523         g_slist_foreach ((GSList*) xp_scan_list,
01524                         (GFunc) rhk_ScanControl::call_scan_start, this);
01525         g_slist_foreach ((GSList*) xm_scan_list,
01526                         (GFunc) rhk_ScanControl::call_scan_start, this);
01527 
01528         gapp->xsm->hardware->StartScan2D();
01529 
01530         line = 0;
01531         do_scanline (TRUE);
01532         update_status_info (TRUE);
01533 
01534         // copy muxsettings from other direction if not given
01535         // weird... to fix !!!
01536         if(!xm_srcs) xm_srcs = xp_srcs;
01537         if(!xp_srcs) xp_srcs = xm_srcs;
01538         
01539         // MUX-Codierung:
01540         PI_DEBUG (DBG_L2,  "xp_srcs: " << xp_srcs );
01541         for(int i=0; i<16; i++) PI_DEBUG (DBG_L3,(int)((xp_srcs&(1<<i))?1:0));
01542         PI_DEBUG (DBG_L2,  "xm_srcs: " << xm_srcs );
01543         for(int i=0; i<16; i++) PI_DEBUG (DBG_L3, (int)((xm_srcs&(1<<i))?1:0));
01544 
01545         {
01546                 gchar *muxcoding = g_strdup_printf ("xp_srcs: %2X  xm_srcs: %2X", xp_srcs, xm_srcs);
01547                 gapp->monitorcontrol->LogEvent ("*StartHSCapture", muxcoding);
01548                 g_free (muxcoding);
01549         }
01550 
01551                 // execute high speed capture scan (line = -1 indicates this mode)
01552                 if (scan_flag!=SCAN_FLAG_STOP) {
01553                 line = -1;
01554                 do_scanline ();
01555                 gapp->check_events();
01556         }
01557 
01558         gapp->xsm->hardware->EndScan2D ();
01559         line = master_scan->data.s.ny;
01560         g_slist_foreach ((GSList*) xp_scan_list,
01561                         (GFunc) rhk_ScanControl::call_scan_stop, this);
01562         g_slist_foreach ((GSList*) xm_scan_list,
01563                         (GFunc) rhk_ScanControl::call_scan_stop, this);
01564 
01565         return finish_scan ();
01566 }
01567 
01568 int rhk_ScanControl::finish_scan (){
01569         int stopped;
01570         PI_DEBUG (DBG_L2, "finish_scan.");
01571 
01572         gapp->spm_thaw_scanparam();
01573 
01574         if ((stopped = scan_flag == SCAN_FLAG_STOP ? TRUE:FALSE)){
01575                 gapp->SetStatus("Scan interrupted");
01576                 gapp->monitorcontrol->LogEvent("*EndOfScan", "interrupted");
01577         }
01578         else{
01579                 gapp->SetStatus("Scan done, ready");
01580                 gapp->monitorcontrol->LogEvent("*EndOfScan", "OK");
01581         }
01582 
01583         free_scan_lists ();
01584         scan_flag = SCAN_FLAG_READY;
01585 
01586 
01587         return !stopped;
01588 }
01589 
01590 double rhk_ScanControl::update_status_info (int reset){
01591         static time_t tn, tnlog, t0;
01592         time_t t;
01593 
01594         if (reset){
01595                 time (&t0);
01596                 tnlog=tn=t0;
01597                 return 0.;
01598         }
01599 
01600         time (&t);
01601         // update only of more than 2s old
01602         if ((t-tn) > 2){
01603                 double ss,s,m,h, sse,se,me,he;
01604                 double n_by_lines_to_do;
01605                 gchar *tt;
01606                 tn=t;
01607                 ss = s = tn-t0;
01608                 h = floor (s/3600.);
01609                 m = floor ((s-h*3600.)/60.);
01610                 s-= h*3600.+m*60.;
01611 
01612                 n_by_lines_to_do = (double)master_scan->data.s.ny
01613                         / (double)(line+1);
01614                 sse = se = (double)(tn-t0)*n_by_lines_to_do;
01615                 he  = floor (se/3600.);
01616                 me  = floor ((se-he*3600.)/60.);
01617                 se -= he*3600.+me*60.;
01618                 // 0123456789012345678901234567890
01619                 // Mon Apr 17 09:10:17 2000
01620                 if ((sse+ss) > 600){
01621                         char *teos = ctime(&t);
01622                         teos[24]=0;
01623                         gapp->SetStatus ("ScanTime",
01624                                          tt=g_strdup_printf ("%.0f:%02.0f:%02.0f "
01625                                                              "| ETA:%.0f:%02.0f:%02.0f | %d%%\n"
01626                                                              "End of Scan: %s",
01627                                                              h,m,s, he,me,se,
01628                                                              (int)(100/n_by_lines_to_do), teos ));
01629                 }else
01630                         gapp->SetStatus ("ScanTime",
01631                                          tt=g_strdup_printf ("%.0f:%02.0f:%02.0f "
01632                                                              "| ETA:%.0f:%02.0f:%02.0f | %d%%",
01633                                                              h,m,s, he,me,se,
01634                                                              (int)(100/n_by_lines_to_do)));
01635 
01636                 if ((t-tnlog) > 60 || (sse+ss) < 600){
01637                         tnlog=t;
01638                         gchar *nl;
01639                         if ((nl=strchr (tt, '\n'))) *nl=' '; // remove \n for logfile
01640                         gchar *mt = g_strdup_printf ("Scan Progress [%d]", line);
01641                         gapp->monitorcontrol->LogEvent (mt, tt);
01642                         g_free(mt);
01643                 }
01644                 g_free(tt);
01645 
01646                 t=tn+(time_t)sse;
01647                 return ss;
01648         }
01649         return 0.;
01650 }
01651 
01652 void rhk_ScanControl::autosave_check (double sec, int initvalue){
01653         static int nextAutosaveEvent=0;
01654 
01655         if (initvalue > 0){
01656                 nextAutosaveEvent = initvalue;
01657                 return;
01658         }
01659 
01660         if ( (( !strncasecmp(xsmres.AutosaveUnit, "percent",2))
01661               && ((100*line/master_scan->data.s.ny) >= nextAutosaveEvent))
01662              ||
01663              (( !strncasecmp(xsmres.AutosaveUnit, "lines"  ,2))
01664               && (line >= nextAutosaveEvent))
01665              ||
01666              ((!strncasecmp(xsmres.AutosaveUnit, "seconds",2))
01667               && (sec >= nextAutosaveEvent)) ){
01668 
01669                 nextAutosaveEvent += xsmres.AutosaveValue;
01670                 if(gapp->xsm->IsMode(MODE_AUTOSAVE)){
01671                         PI_DEBUG (DBG_L2,  "Autosaveevent triggered.");
01672                         // check for overwritemode for autosave
01673                         if(!strncasecmp(xsmres.AutosaveOverwritemode, "true",2))
01674                                 gapp->xsm->save(2, NULL, -1, TRUE);
01675                         else
01676                                 gapp->xsm->save(2, NULL, -1, FALSE);
01677                 }
01678         }
01679 
01680 }
01681 
01682 
01683 void rhk_ScanControl::updateRHK(void){
01684           static GdkRectangle update_rect={0,0,300,300};
01685 
01686   gdk_draw_rectangle (pixmap,
01687                       widget->style->white_gc,
01688                       TRUE,
01689                       update_rect.x, update_rect.y,
01690                       update_rect.width, update_rect.height);
01691                       
01692 // This is a nasty kludge. The problem is that PutParameter returns the readings in Dig, not in Angstroms,
01693 // as it does not know about the calibration
01694 // So we translate from Dig readings to Angstroms before showing the settings anywhere
01695   gapp->xsm->hardware->PutParameter(ScanData, 1);
01696   
01697    update_rect.width = (gint)(150.0*ScanData->s.rx/32768.0);
01698   update_rect.height = (gint)(150.0*ScanData->s.ry/32768.0);
01699   update_rect.x = (gint)(150.0*ScanData->s.x0/32768.0+150-update_rect.width);
01700   update_rect.y = (gint)(150.0*ScanData->s.y0/32768.0+150-update_rect.height);
01701   update_rect.width*=2;
01702   update_rect.height*=2;
01703 
01704   gdk_draw_rectangle (pixmap,
01705                       widget->style->black_gc,
01706                       TRUE,
01707                       update_rect.x, update_rect.y,
01708                       update_rect.width, update_rect.height);
01709 
01710   update_rect.width=update_rect.height=300;
01711   update_rect.x=update_rect.y=0;
01712   gtk_widget_draw (drawingarea, &update_rect);
01713 
01714   ScanData->s.x0 = instrument->Dig2XA((gint)ScanData->s.x0);
01715   ScanData->s.rx = instrument->Dig2XA((gint)ScanData->s.rx);
01716   ScanData->s.y0 = instrument->Dig2YA((gint)ScanData->s.y0);
01717   ScanData->s.ry = instrument->Dig2YA((gint)ScanData->s.ry);
01718   ScanData->s.dz = ScanData->s.rz;
01719   ScanData->s.rz = instrument->Dig2ZA((gint)ScanData->s.rz);
01720   ScanData->s.dz = ScanData->s.rz/ScanData->s.dz;
01721   ScanData->hardpars.UTunnel = instrument->Dig2V((gint)ScanData->hardpars.UTunnel);
01722   //ScanData->hardpars.ITunnelSoll = instrument->Dig2nAmpere((gint)ScanData->hardpars.ITunnelSoll);
01723   ScanData->s.dx = ScanData->s.rx / ScanData->s.nx;
01724   ScanData->s.dy = ScanData->s.ry / ScanData->s.ny;
01725   
01726   gapp->spm_update_all();
01727   
01728   ec1->Set_FromValue(ScanData->s.x0);
01729   ec2->Set_FromValue(ScanData->s.rx);
01730   ec3->Set_FromValue(ScanData->s.y0);
01731   ec4->Set_FromValue(ScanData->s.ry);
01732   ec5->Set_FromValue(ScanData->s.rz);
01733   ec6->Set_FromValue(ScanData->s.nx);
01734   ec7->Set_FromValue(ScanData->hardpars.UTunnel);
01735   ec8->Set_FromValue(ScanData->hardpars.ITunnelSoll);
01736   
01737  
01738 }
01739 
01740 void rhk_ScanControl::ChangedNotify(GtkWidget *widget, rhk_ScanControl *dspc){
01741 dspc->updateRHK();
01742 }
01743 
01744 void rhk_ScanControl::ChangedAuto(GtkWidget *widget, rhk_ScanControl *dspc){
01745 if (!dspc->timer)
01746         dspc->timer=gtk_timeout_add(1000, &rhk_ScanControl_timed, dspc);
01747 else {
01748         gtk_timeout_remove(dspc->timer);
01749         dspc->timer=0;
01750         }
01751 }

Generated on Sat Apr 1 09:04:14 2006 for GXSM by  doxygen 1.4.6