innovative_dsp_hwi_spm.C

Go to the documentation of this file.
00001 /* Gxsm - Gnome X Scanning Microscopy
00002  * universal STM/AFM/SARLS/SPALEED/... controlling and
00003  * data analysis software
00004  * 
00005  * Copyright (C) 1999,2000,2001,2002,2003 Percy Zahl
00006  *
00007  * Authors: Percy Zahl <zahl@users.sf.net>
00008  * additional features: Andreas Klust <klust@users.sf.net>
00009  * WWW Home: http://gxsm.sf.net
00010  *
00011  * This program is free software; you can redistribute it and/or modify
00012  * it under the terms of the GNU General Public License as published by
00013  * the Free Software Foundation; either version 2 of the License, or
00014  * (at your option) any later version.
00015  *
00016  * This program is distributed in the hope that it will be useful,
00017  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00018  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00019  * GNU General Public License for more details.
00020  *
00021  * You should have received a copy of the GNU General Public License
00022  * along with this program; if not, write to the Free Software
00023  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
00024  */
00025 
00026 /* -*- Mode: C++; indent-tabs-mode: nil; c-basic-offset: 8 c-style: "K&R" -*- */
00027 
00028 /* irnore this module for docuscan
00029 % PlugInModuleIgnore
00030  */
00031 
00032 #include <locale.h>
00033 #include <libintl.h>
00034 
00035 
00036 #include "glbvars.h"
00037 #include "plug-ins/hard/modules/dsp.h"
00038 #include <fcntl.h>
00039 #include <sys/ioctl.h>
00040 
00041 #include "dsp-pci32/xsm/xsmcmd.h"
00042 //#include "dsp-pci32/xsm/xsmconst.h"
00043 
00044 #include "innovative_dsp_hwi.h"
00045 
00046 
00047 #define CHECKDIFF(A,B) (fabs((A)-(B)) > 1e-8)
00048 
00049 /* ============================================================
00050  * Hardwareimplementation hilevel DSP:
00051  * Virtuelle Funktionen der Basisklasse werden überschrieben
00052  * ============================================================ 
00053  */
00054 
00055 innovative_dsp_hwi_spm::innovative_dsp_hwi_spm():innovative_dsp_hwi_dev(){
00056  ScanningFlg=0;
00057 }
00058 
00059 innovative_dsp_hwi_spm::~innovative_dsp_hwi_spm(){
00060 }
00061 
00062 /* Übergeordnete Parameterübergabefunktionen PC => PC31/DSP
00063  * ========================================================
00064  * virtual !
00065  */
00066 void innovative_dsp_hwi_spm::PutParameter(void *src, int grp){ // Parameterstruktur kopieren
00067         if(src)
00068                 memcpy(&dspPar, src, sizeof(DSP_Param));
00069         switch(ScanningFlg){
00070         case 0:
00071                 DSP_FbWerte();
00072                 DSP_SetTransferFkt();
00073                 DSP_SetRotParam();
00074                 DSP_SetMoveParam();
00075                 DSP_SetAppWerte();
00076                 break;
00077         case 1:
00078                 {
00079                         gchar *mt = g_strdup_printf ("U=%.3fV I=%.4fnA", dspPar.UTunnel, dspPar.ITunnelSoll);
00080                         gapp->monitorcontrol->LogEvent ("DSP parameter changed", mt);
00081                         g_free (mt);
00082                 }
00083                 ScanningFlg=2;
00084                 break;
00085         case 3:
00086                 DSP_FbWerte();
00087                 DSP_SetMoveParam();
00088                 break;
00089         }
00090 }
00091 
00092 void innovative_dsp_hwi_spm::StartScan2D(){
00093   ScanningFlg=1; KillFlg=FALSE;
00094 }
00095 
00096 void innovative_dsp_hwi_spm::EndScan2D(){ 
00097   if(ScanningFlg>1){
00098     ScanningFlg=0; 
00099     PutParameter(NULL);
00100   }
00101   else
00102     ScanningFlg=0; 
00103 }
00104 
00105 void innovative_dsp_hwi_spm::PauseScan2D(){
00106         // sth to put to DSP?
00107         if(ScanningFlg>1){
00108                 ScanningFlg=3; 
00109                 PutParameter(NULL);
00110                 ScanningFlg=1;
00111         }
00112         ScanningFlg=0;
00113 }
00114 void innovative_dsp_hwi_spm::ResumeScan2D(){
00115         ScanningFlg=1;
00116 }
00117 
00118 void innovative_dsp_hwi_spm::MovetoXY(long x, long y){
00119         static long sxy=123456789;
00120         long newsum = x+y;
00121         if ( newsum != sxy){
00122                 PARAMETER_SET hardpar;
00123                 sxy = newsum;
00124                 rx=x;
00125                 ry=y;
00126                 hardpar.N   = DSP_MOVETOXY_Y+1;
00127                 hardpar.Cmd = DSP_CMD_MOVETO_XY;
00128                 hardpar.hp[DSP_MOVETOXY_X].value = x;
00129                 hardpar.hp[DSP_MOVETOXY_Y].value = y;
00130                 SetParameter (hardpar);
00131         }
00132 }
00133 
00134 void innovative_dsp_hwi_spm::SetDxDy(int dx, int dy){
00135         Dx = dx; 
00136         Dy = dy;
00137         dspPar.LS_dnx = dx;
00138 }
00139 void innovative_dsp_hwi_spm::SetOffset(long x, long y){
00140         rotoffx = x; rotoffy = y;
00141         DSP_SetRotParam();
00142 }
00143 void innovative_dsp_hwi_spm::SetAlpha(double alpha){ 
00144         Alpha=M_PI*alpha/180.;
00145         rotmyy = rotmxx = cos(Alpha);
00146         rotmyx = -(rotmxy = sin(Alpha));
00147         DSP_SetRotParam();
00148 }
00149 
00150 void innovative_dsp_hwi_spm::SetNx(long nx){ 
00151         Nx=nx; 
00152         dspPar.LS_nx2scan = nx;
00153 }
00154 
00155 /* Parameterübergabefunktionen PC => PC31/DSP
00156  * ==================================================
00157  *
00158  */
00159 
00160 void innovative_dsp_hwi_spm::DSP_FbWerte(){
00161   static double sum=1234e100;
00162   double nowsum;
00163   nowsum = dspPar.UTunnel+dspPar.ITunnelSoll
00164     +dspPar.CP+dspPar.CI+dspPar.CS+dspPar.fb_frq
00165     +dspPar.fir_fg+dspPar.SetPoint;
00166   if(CHECKDIFF(sum, nowsum)){
00167     PARAMETER_SET hardpar;
00168     XSM_DEBUG (DBG_L4, "DSP_FbWerte d:" << (sum - nowsum));
00169     sum = nowsum;
00170 
00171     hardpar.N   = DSP_CS+1;
00172     hardpar.Cmd = DSP_CMD_SET_WERTE;
00173     hardpar.hp[DSP_UTUNNEL].value = dspPar.UTunnel;
00174     hardpar.hp[DSP_ITUNNEL].value = gapp->xsm->Inst->nAmpere2V(dspPar.ITunnelSoll);
00175     hardpar.hp[DSP_CP     ].value = dspPar.CP;
00176     hardpar.hp[DSP_CI     ].value = dspPar.CI;
00177     hardpar.hp[DSP_CD     ].value = gapp->xsm->Inst->nNewton2V(dspPar.SetPoint);
00178     hardpar.hp[DSP_FB_FRQ ].value = dspPar.fb_frq;
00179     hardpar.hp[DSP_FIR_FG ].value = dspPar.fir_fg;
00180     hardpar.hp[DSP_CS     ].value = dspPar.CS;
00181     SetParameter(hardpar);
00182     SetParameter(hardpar); // some trouble with pc31, doing twice helps.. :=( !!
00183   }
00184 }
00185 
00186 void innovative_dsp_hwi_spm::DSP_SetTransferFkt(){
00187   static double sum=1234e100;
00188   double nowsum;
00189   nowsum = dspPar.LogOffset+dspPar.LogSkl+dspPar.LinLog;
00190   if(CHECKDIFF(sum ,nowsum)){
00191     PARAMETER_SET hardpar;
00192     XSM_DEBUG (DBG_L4, "DSP_SetTransferFkt");
00193     sum = nowsum;
00194     hardpar.N   = DSP_LIN_LOG+1;
00195     hardpar.Cmd = DSP_CMD_SET_TRANSFER_FKT;
00196     hardpar.hp[DSP_UTUNNEL].value = dspPar.UTunnel;
00197     hardpar.hp[DSP_LOGOFF ].value = dspPar.LogOffset;
00198     hardpar.hp[DSP_LOGSKL ].value = dspPar.LogSkl;
00199     hardpar.hp[DSP_LIN_LOG].value = dspPar.LinLog;
00200     SetParameter(hardpar);
00201   }
00202 }
00203 
00204 void innovative_dsp_hwi_spm::DSP_SetRotParam(){
00205   static double sum=1234e100;
00206   double nowsum;
00207   nowsum = Alpha+rotoffx+rotoffy;
00208   if(CHECKDIFF(sum ,nowsum)){
00209     PARAMETER_SET hardpar;
00210     XSM_DEBUG (DBG_L4, "DSP_SetRotParam d:" << (sum - nowsum));
00211     sum = nowsum;
00212     hardpar.N   = DSP_ROTOFFY+1;
00213     hardpar.Cmd = DSP_CMD_ROTPARAM;
00214     hardpar.hp[DSP_ROTXX  ].value = rotmxx;
00215     hardpar.hp[DSP_ROTXY  ].value = rotmxy;
00216     hardpar.hp[DSP_ROTYX  ].value = rotmyx;
00217     hardpar.hp[DSP_ROTYY  ].value = rotmyy;
00218     hardpar.hp[DSP_ROTOFFX].value = rotoffx;
00219     hardpar.hp[DSP_ROTOFFY].value = rotoffy;
00220     SetParameter(hardpar);
00221   }
00222 }
00223 
00224 void innovative_dsp_hwi_spm::DSP_SetMoveParam(){
00225   static double sum=1234e100;
00226   double nowsum;
00227   nowsum = dspPar.MV_stepsize+dspPar.MV_nRegel;
00228   if(CHECKDIFF(sum ,nowsum)){
00229     PARAMETER_SET hardpar;
00230     XSM_DEBUG (DBG_L4, "DSP_SetMoveParam");
00231     sum = nowsum;
00232     hardpar.N   = DSP_MVNREGEL+1;
00233     hardpar.Cmd = DSP_CMD_MOVETO_PARAM;
00234     hardpar.hp[DSP_MVSTEPSZ].value = dspPar.MV_stepsize;
00235     hardpar.hp[DSP_MVNREGEL].value = dspPar.MV_nRegel;
00236     SetParameter(hardpar);
00237   }
00238 }
00239 
00240 void innovative_dsp_hwi_spm::DSP_SetAppWerte(){
00241   static double sum=1234e100, sum2=1234e100;
00242   double nowsum, nowsum2;
00243   nowsum = dspPar.AFM_Amp+dspPar.AFM_Speed+dspPar.AFM_Steps;
00244   if(CHECKDIFF(sum, nowsum)){
00245     PARAMETER_SET hardpar;
00246     XSM_DEBUG (DBG_L4, "DSP_SetAppWerte AMP-SPEED-STEPS d:" << (sum - nowsum));
00247     sum = nowsum;
00248     XSM_DEBUG (DBG_L4, " Amp:" << dspPar.AFM_Amp << " Spd: " << dspPar.AFM_Speed << "#:" << dspPar.AFM_Steps);
00249     hardpar.N   = DSP_AFM_SLIDER_STEPS+1;
00250     hardpar.Cmd = DSP_CMD_AFM_SLIDER_PARAM;
00251     hardpar.hp[DSP_AFM_SLIDER_AMP  ].value = dspPar.AFM_Amp;
00252     hardpar.hp[DSP_AFM_SLIDER_SPEED].value = dspPar.AFM_Speed;
00253     hardpar.hp[DSP_AFM_SLIDER_STEPS].value = dspPar.AFM_Steps;
00254     SetParameter(hardpar);
00255   }
00256   nowsum2 = dspPar.TIP_nSteps+dspPar.TIP_Delay+dspPar.TIP_DUz+dspPar.TIP_DUzRev;
00257   if(CHECKDIFF(sum2, nowsum2)){
00258     PARAMETER_SET hardpar;
00259     XSM_DEBUG (DBG_L4, "DSP_SetAppWerte TIPAPPPARAM");
00260     sum2 = nowsum2;
00261     XSM_DEBUG (DBG_L4, " nSteps:" << dspPar.TIP_nSteps);
00262     hardpar.N   = DSP_TIPDUZREV+1;
00263     hardpar.Cmd = DSP_CMD_APPROCH_PARAM;
00264     hardpar.hp[DSP_TIPNSTEPS ].value = dspPar.TIP_nSteps;
00265     hardpar.hp[DSP_TIPNWARTE ].value = dspPar.TIP_Delay;
00266     hardpar.hp[DSP_TIPDUZ    ].value = dspPar.TIP_DUz;
00267     hardpar.hp[DSP_TIPDUZREV ].value = dspPar.TIP_DUzRev;
00268     SetParameter(hardpar);
00269   }
00270 }
00271 
00272 /*
00273  * Do ScanLine in multiple Channels Mode
00274  *
00275  * yindex:  Index of Line
00276  * xdir:    Scanning Direction (1:+X / -1:-X) eg. for/back scan
00277  * lsscrs:  LineScan Sources, MUX/Channel Configuration
00278  * PC31 has can handle 2 Channels of 16bit data simultan, using 4-fold Mux each
00279  *      additional the PID-Outputvalue can be used and the PID Src is set by MUXA
00280  *      it may be possible to switch MUXB while scanning -- test it !!!
00281  * bit     0 1 2 3  4 5 6 7  8 9 10 11  12 13 14 15 ...
00282  * PC31:   ==PID==  =MUX-A=  ==MUX-B==  
00283  * PCI32:  ==PID==  A======  B========  C==== D====
00284  *    eg.  Z-Value  Fz/I     Fric...
00285  * example:
00286  * value   1 0 0 0  1 0 0 0  1 0  0  0  0...
00287  * buffers B0       B1       B2
00288  * 3 buffers used for transfer (B0:Z, B1:Force, B2:Friction)
00289  *
00290  * Mob:     List of MemObjs. to store Data
00291  *
00292  * with maximized DPRAM usage: [DPRAM] [DSPMEM1] [DSPMEM2] ... (Blocks of same size)
00293  *                              B0,B1,  B2, B3,   B4,..
00294  * nach DSP_CMD_SWAPDPRAM:      B2,B3,  -------   B4,..
00295  * nach DSP_CMD_SWAPDPRAM:      B4,..   -------   -------
00296  * ...
00297  * 
00298  * if yindex == -1, then a HS Capture (DSP_CMD_2D_HS_AREASCAN) is requested!
00299  */
00300 void innovative_dsp_hwi_spm::ScanLineM(int yindex, int xdir, int lssrcs, Mem2d *Mob[MAX_SRCS_CHANNELS], int ix0 ){
00301   PARAMETER_SET hardpar;
00302 
00303   if(ScanningFlg>1){
00304     ScanningFlg=3; 
00305     PutParameter(NULL);
00306     ScanningFlg=1;
00307   }
00308 
00309   if (yindex >= 0){
00310           hardpar.N   = DSP_LSYINDEX+1;
00311           hardpar.Cmd = DSP_CMD_LINESCAN;
00312   } else {
00313           if (yindex != -1) return;
00314           hardpar.N   = DSP_AS_DNY+1;
00315           hardpar.Cmd = DSP_CMD_2D_HS_AREASCAN;
00316           hardpar.hp[DSP_AS_NY2SCAN ].value = Mob[0]->GetNy();
00317           hardpar.hp[DSP_AS_DNY     ].value = dspPar.LS_dnx; // only same step size!!!!!
00318   }
00319   hardpar.hp[DSP_LSNX       ].value = dspPar.LS_nx2scan;
00320   if(xdir<0) // Rück - Scan (-)
00321     hardpar.hp[DSP_LSDNX      ].value = -dspPar.LS_dnx;
00322   else    // Hin  - Scan (+)
00323     hardpar.hp[DSP_LSDNX      ].value = dspPar.LS_dnx;
00324   hardpar.hp[DSP_LSSTEPSZ   ].value = dspPar.LS_stepsize;
00325   hardpar.hp[DSP_LSNREGEL   ].value = dspPar.LS_nRegel;
00326   hardpar.hp[DSP_LSNAVE     ].value = dspPar.LS_nAve;
00327   hardpar.hp[DSP_LSINTAVE   ].value = dspPar.LS_IntAve;
00328   hardpar.hp[DSP_LSNXPRE    ].value = dspPar.LS_nx_pre;
00329   hardpar.hp[DSP_LSSRCS     ].value = lssrcs; // Codierte MUX/Srcs Configuration
00330   hardpar.hp[DSP_LSYINDEX   ].value = yindex; // for verify only
00331   SetParameter(hardpar, TRUE);
00332 
00333   // calc # of srcs
00334   int num_srcs = 0;
00335   int bi = 0;
00336   do{
00337           if(lssrcs & (1<<bi++))
00338                   ++num_srcs;
00339   }while(bi<16);
00340 
00341   ReadScanData (yindex, num_srcs, Mob);
00342 
00343   if(ScanningFlg>1){
00344     ScanningFlg=3; 
00345     PutParameter(NULL);
00346     ScanningFlg=1;
00347   }
00348 }

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