spm_emu.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 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 // SPM Emu by kernel
00029 
00030 #include <linux/kernel.h>
00031 #include <math.h>
00032 #include "include/dsp-pci32/xsm/xsmcmd.h"
00033 #include "include/dsp-pci32/xsm/mover.h"
00034 
00035 //------------ begin instrument definition ---------------
00036 
00037 #define TITLE "** STM-SIM **"
00038 
00039 #define TYP_STM
00040 #define OSZI_ENABLE
00041 
00042 #define MAXDA_XVAL 32763L
00043 #define MAXDA_YVAL 32763L
00044 #define MAXDAVAL   32763L
00045 
00046 #define ZSIGNUM(Z)          (Z)  /* Vorzeichenanpassung Z Signal, ggf. -(Z) füt CI > 0 */
00047 #define ZDATASIGNUM(Z)      (-(Z))  /* Vorzeichenanpassung Z Daten, bei neg. war Contrast falsch !! positiv 31.8.1999 PZ */
00048 /****** Funktion  ........  IO-Belegung Stress/AFM: ***********/
00049 #define OSZI_bit(X,Y)       ;
00050 #define SL_OFF              3
00051 #define SLZ_P               2
00052 #define SLZ_M               1
00053 #define SLIDERPORT(X)       ;
00054 #define SLIDERPORT_bit(X,Y) ;
00055 // MB Test Mode Bit0: Trigger Bit1: Z--, Bit2 Z++
00056 #define ZSLIDER_ON          
00057 #define ZSLIDER_OFF         
00058 /* Trigger: 0     = disable
00059  * Trigger: 0-1-0 = Step
00060  * ----TRIG_ON-OFF-ON------
00061  */
00062 #define SLIDERTRIGGER_ON    
00063 #define SLIDERTRIGGER_OFF   
00064 /* Bits 5,6 Gain-Reeds */
00065 
00066 /* DSP-Kernel-Programm Modes
00067  * - Int09 ist globale Zeitbasis
00068  * Modes (Bitcodiert):
00069  * 0 1 2 3  4  5  6  7
00070  * 1 2 4 8 10 20 40 80
00071  * - - - 
00072  *  LCD
00073  */
00074 #define MD_CMD          0x0004  /* Komando (SRQ) abfragen, ausführen aktiv */
00075 #define MD_PID          0x0008  /* PID-Regler aktiv */
00076 #define MD_MOVE         0x0100  /* MoveTo Xnew, Ynew wird ausgeführt */
00077 #define MD_MOVEOFF      0x0300  /* MoveTo new Offset */
00078 #define MD_SCAN         0x0010  /* Linescan ausführen */
00079 #define MD_BLK          0x0080  /* Blinken zur Kontrolle */
00080 #define MD_TIPDN        0x1000  /* Spitze annähern starten */
00081 #define MD_ITU          0x0020  /* I Tunnel ~> Sollwert, Flag 1 wenn Tunnelstrom detektiert und im Regelbereich */
00082 #define MD_CRASH        0x0040  /* I Tunnel >> Sollwert, Flag 1 wenn Tunnelstrom nicht mehr im Regelbereich */
00083 #define MD_PROBE        0x2000  /* Probe control (spectroscopy etc.) */
00084 
00085 //#define USE_MOVER_APP
00086 #define USE_IO_APP
00087 
00088 #define AFM_MOVER
00089 #define AFM_MOVER_NO_Q
00090 
00091 //------------ end instrument definition ---------------
00092 #define REGEL_DT (1./(float)50000.)
00093 #define  TIP_ZPiezoMax   3
00094 
00095 /* Konstanten für DSP  */
00096 #define AD_MAX_VOLT 10.     /* Max Spannung bei Wert DA_MAX_VAL */
00097 #define DA_MAX_VOLT 10.     /* Max Spannung bei Wert DA_MAX_VAL */
00098 #define DA_MAX_VAL  0x7ffe  /* Max Wert für signed 16 Bit Wandler */
00099 #define UDA_MAX_VAL  0xffff  /* Max Wert für unsigend 16 Bit Wandler */
00100 
00101 /* Spannung <==> Int-Wert Umrechenfaktoren */
00102 /* Bipolar */
00103 #define         U2FLT(X) ((X)*(float)(DA_MAX_VAL)/AD_MAX_VOLT)
00104 #define         U2INT(X) (int)((X)*(float)(DA_MAX_VAL)/AD_MAX_VOLT+.5)
00105 #define         INT2U(X) ((float)(X)/DA_MAX_VAL*AD_MAX_VOLT)
00106 
00107 /* Uinpolar */
00108 #define         UNI_U2FLT(X) ((X)*(float)(UDA_MAX_VAL)/AD_MAX_VOLT)
00109 #define         UNI_U2INT(X) (int)((X)*(float)(UDA_MAX_VAL)/AD_MAX_VOLT+.5)
00110 #define         UNI_INT2U(X) ((float)(X)/UDA_MAX_VAL*AD_MAX_VOLT)
00111 
00112 
00113 #define  DPRAMBASE     (volatile int*)  (spm.dsp->virtual_dpram)
00114 
00115 #define  CMD_BUFFER    (volatile int*)  (DPRAMBASE+0x00)   /* cmd buffer */
00116 #define  CMD_PARM      (volatile int*)  (DPRAMBASE+0x01)   /* */
00117 #define  BUFFER        (volatile int*)  (DPRAMBASE+DSP_BUFFER_START)   /* */
00118 #define  BUFFERL       (volatile unsigned long*)  (DPRAMBASE+DSP_BUFFER_START)   /* */
00119 #define  BUFFERS       (volatile short*)          (DPRAMBASE+DSP_BUFFER_START)
00120 #define  DPRAML        (volatile unsigned long*)  (DPRAMBASE)   /* */
00121 #define  LCDBUFFER     (volatile unsigned long*)  (DPRAMBASE+DSP_LCDBUFFER)
00122 #define  MAXSCANPOINTS (DSP_DATA_REG_LEN)
00123 
00124 #define  DSPack  spm.dsp->SrvReqAck=TRUE
00125 
00126 #define LEDPORT(X)       *((unsigned long*)(DPRAMBASE+DSP_USR_DIO))=X
00127 
00128 void LCDclear(void);
00129 int LCDprintf(const char *format, ...);
00130 
00131 int GetParamI(unsigned int N);
00132 float GetParamF(unsigned int N);
00133 
00134 #define SURFSIZE 64
00135 
00136 int surftab[SURFSIZE];
00137 
00138 #define MAXCHANNELS 10
00139 #define MAXDATABUFFERS 5
00140 
00141 const float maxval = +3.2765e4;
00142 const float minval = -3.2765e4;
00143 
00144 typedef struct{
00145         int     MV_Xnew;
00146         int     MV_Ynew;
00147         int     MV_XPos;
00148         int     MV_YPos;
00149         int     MV_stepsize;    /* max. Schrittweite */
00150         unsigned int    MV_nRegel;      /* Anzahl Reglerdurchläufe je Schritt */
00151         int     LS_nx2scan;     /* Scanlinelänge */
00152         int     LS_nx_pre;      /* Scan-Vorlauf in Me punkten */
00153         int     LS_srcs;        /* Source Channels */
00154         int     LS_dnx;         /* Me punktabstand */
00155         int     LS_stepsize;    /* max. Schrittweite */
00156         unsigned int    LS_nRegel;      /* Anzahl Reglerdurchläufe je Schritt */
00157         int     LS_nAve;        /* Anzahl durchzuführender Mittelungen */
00158         int     LS_IntAve;      /* =0: kein IntAve, =1: Aufsummieren von Punkte zu Punkt */
00159         int     LS_LastVal;     /* vorhergehender Wert für 32bit DPRAM Mode */
00160         long    LS_xE, LS_xnext; /* Für interne Verwendung */
00161         int     LS_AveCount;    /* Mittelungszähler */
00162         int     LS_SmpFlg;      /* Sample Flag */
00163         int     LS_Xindex, LS_Xinc;     /* LS_BUFFER Index */
00164         int     LS_ChPID;
00165 
00166         int     PRB_nx;
00167         int     PRB_xS;
00168         int     PRB_xE;
00169         double  PRB_ACAmp;
00170         double  PRB_ACFrq;
00171         double  PRB_ACPhase;
00172         double  PRB_GapAdj;
00173         int     PRB_ACdelay;
00174         int     PRB_CIval;
00175         int     PRB_AveCount;
00176         int     PRB_srcs;
00177         int     PRB_outp;
00178         int     PRB_nAve;
00179         int     PRB_ChAnz;
00180         int     PRB_ChAkt;
00181         int     PRB_Xindex;
00182         int     PRB_XPos;
00183         int     PRB_delay;
00184         int     PRB_dnx;
00185         int     PRB_CPIS[3];
00186         int     PRB_oldU;
00187         int     PRB_oldZ;
00188         float   PRB_ChSum[MAXCHANNELS];   /* Summierungsvariable für ChXX */
00189 
00190         int     TIP_nWarte;
00191         int     TIP_nSteps;
00192         int     TIP_DUzRev;
00193         int     TIP_DUz;
00194         int     TIP_Zdn;
00195         int     TIP_Mode;
00196         int     afm_piezo_amp;
00197         int     afm_u_piezomax;
00198         int     afm_piezo_speed;
00199         int     afm_piezo_steps;
00200         int     afm_mover_mode;
00201         int     afm_mover_app;
00202         int     AFM_MV_count;
00203         int     AFM_MV_Scount;
00204         
00205 /* PID-Regler Variable */
00206         int   U_tunnel;     /* Vorgabetunnelspannung */
00207         long  I_tunnel_soll;/* Tunnelsollstrom */
00208 
00209         float Spg;
00210         float I_ist_alt, I_ist, I_soll, I_delta;   /* PI-Reglerparameter */
00211         float U_z;          /* Z-Spannungswert vom Regler vorgegeben */
00212         float Const_P;      /* Regler P Konstante */
00213         float Const_I;      /* Regler I Konstante */
00214         float Const_S;      /* Regler Slope Konstante */
00215         float SetPoint;     /* Regler D Konstante */
00216         float I_sum;       /* I-Integral */
00217         
00218         int   LogOffset;  /* für log. Regler */
00219         float LogFaktor;  /* für log. Regler */
00220         float LogSkl;
00221         float LogSklNeu;
00222         
00223         unsigned long *databuffer[MAXDATABUFFERS];
00224         unsigned long *channelptr[MAXCHANNELS];
00225         int     LS_ChAnz, LS_ChAkt;
00226         float   LS_ChSum[MAXCHANNELS];   /* Summierungsvariable für ChXX */
00227         float   *ChPtr[MAXCHANNELS];     /* Pointer to Channel Source */  
00228         
00229         float adc_values[MAXCHANNELS];
00230         long  dacbufferZ;
00231         long  dacbufferU;
00232 
00233         long  dacXval, dacYval, dacUval, dacZval;
00234 
00235         double rotmxx, rotmyy, rotmxy, rotmyx, rotoffx, rotoffy;
00236 } SCANP;
00237 
00238 SCANP scanp;
00239 
00240 typedef struct{
00241     struct dspsim_thread_data *dsp;
00242     SCANP scanp;
00243     int LastSPMMode;
00244     int SPMMode;
00245 } SPM;
00246 
00247 SPM spm;
00248 
00249 void calc_xy( void );
00250 void DACoutXY(long ix, long iy);
00251 void DACoutX(long value);
00252 void DACoutY(long value);
00253 void DACoutZ(long value);
00254 void DACoutU(long value);
00255 
00256 void run_testscan( void );
00257 void run_testprbscan( void );
00258 
00259 void run_dspsim_loop( void );
00260 
00261 
00262 #ifdef __PPC__
00263 #include "mathemu.c"
00264 #endif
00265 
00266 int InitEmu(struct dspsim_thread_data *dsp){
00267         int i;
00268         spm.dsp    = dsp;
00269         *CMD_BUFFER=0;
00270         spm.LastSPMMode = spm.SPMMode = MD_CMD;
00271         LCDclear();
00272         LCDprintf("Welcome to the SPM/DSP Emu");
00273         LEDPORT(spm.SPMMode);  
00274         
00275         spm.scanp.MV_XPos = 0;
00276         spm.scanp.MV_YPos = 0;
00277         spm.scanp.rotmxx = spm.scanp.rotmyy = 1.;
00278         spm.scanp.rotmxy = spm.scanp.rotmyx = spm.scanp.rotoffx = spm.scanp.rotoffy = 0.;
00279 // ... more
00280         
00281 #define SURFCORR 20
00282         for(i=0; i<SURFSIZE; ++i){
00283                 if (i<SURFSIZE/4){
00284                         surftab[i] = -SURFCORR;
00285                         continue;
00286                 }
00287                 if (i<SURFSIZE/2){
00288                         surftab[i] = -SURFCORR+(i-SURFSIZE/4)*SURFCORR*2/(SURFSIZE/4);
00289                         continue;
00290                 }
00291                 if (i<3*SURFSIZE/4){
00292                         surftab[i] = SURFCORR;
00293                         continue;
00294                 }
00295                 surftab[i] = SURFCORR-(i-3*SURFSIZE/4)*SURFCORR*2/(SURFSIZE/4);
00296         }
00297 
00298         return 0;
00299 }
00300 
00301 void ExitEmu(void){
00302     ;
00303 }
00304 
00305 int GetParamI(unsigned int N){ 
00306         float *ptr = (float*)(CMD_PARM + N);
00307         return (int)(*ptr);
00308         //    union { int i; float f; unsigned int u;} u; u.i = *(CMD_PARM + N); return u.i; 
00309 }
00310 
00311 float GetParamF(unsigned int N){ 
00312         float *ptr = (float*)(CMD_PARM + N);
00313         return *ptr;
00314 }
00315 
00316 void LCDclear(void){
00317         int n;
00318         for(n=0; n < DSP_LCDBUFFERLEN;)
00319                 *(LCDBUFFER+n++) = ' ';
00320 }
00321 
00322 int LCDprintf(const char *format, ...){
00323         va_list ap;                                                                 
00324         int nr_of_chars;                                                            
00325         va_start (ap, format);
00326         nr_of_chars = vsprintf ((char*)LCDBUFFER, format, ap);
00327         va_end (ap);
00328         return (nr_of_chars);
00329 }                                                                             
00330    
00331 void ServiceRequest(struct dspsim_thread_data *dsp){
00332         double XYflt;
00333         switch(*CMD_BUFFER & 0xff){
00334 
00335         case DSP_CMD_SET_WERTE:
00336                 spm.scanp.U_tunnel = U2INT (GetParamF (DSP_UTUNNEL));
00337                 spm.scanp.Spg = (spm.scanp.I_ist_alt = GetParamF (DSP_ITUNNEL));
00338                 if(spm.scanp.Spg > AD_MAX_VOLT) spm.scanp.Spg = AD_MAX_VOLT;
00339                 if(spm.scanp.Spg < -AD_MAX_VOLT) spm.scanp.Spg = -AD_MAX_VOLT;
00340                 spm.scanp.Const_P = GetParamF (DSP_CP);
00341                 spm.scanp.Const_I = GetParamF (DSP_CI);
00342                 spm.scanp.SetPoint = GetParamF (DSP_CD);
00343                 spm.scanp.Const_S = GetParamF (DSP_CS);
00344                 
00345                 if(spm.scanp.Const_S > 2. || spm.scanp.Const_S < 0.) spm.scanp.Const_S=1.; // for savety
00346                 
00347                 DACoutU (spm.scanp.U_tunnel);   /* Tunnelspg. setzen */
00348                 
00349                 DSPack;
00350                 break;
00351                 
00352         case DSP_CMD_SET_LOG_WERTE:
00353                 DSPack;
00354                 break;
00355 
00356         case DSP_CMD_ROTPARAM:
00357                 /* Moveto absolute */
00358                 spm.scanp.rotmxx = GetParamF (DSP_ROTXX);
00359                 spm.scanp.rotmxy = GetParamF (DSP_ROTXY);
00360                 spm.scanp.rotmyx = GetParamF (DSP_ROTYX);
00361                 spm.scanp.rotmyy = GetParamF (DSP_ROTYY);
00362                 XYflt  = GetParamF (DSP_ROTOFFX);
00363                 spm.scanp.MV_Xnew = (XYflt>maxval?maxval:(XYflt<minval?minval:XYflt)); 
00364                 spm.scanp.MV_Xnew -= spm.scanp.rotoffx;
00365                 XYflt   = GetParamF (DSP_ROTOFFY);
00366                 spm.scanp.MV_Ynew = (XYflt>maxval?maxval:(XYflt<minval?minval:XYflt));
00367                 spm.scanp.MV_Ynew -= spm.scanp.rotoffy;
00368                 
00369                 spm.LastSPMMode = spm.SPMMode; /* [12.04.1996] PZ: keine anderen Komandos zulassen !! */
00370                 spm.SPMMode = (spm.SPMMode & ~(MD_SCAN | MD_CMD)) | MD_MOVEOFF;
00371                 /* in Move-To-Offset-Modus übergehen */
00372                 /* DSPack: Acknowledge erst, wenn MoveTo beendet !! */          
00373                 break;
00374     
00375         case DSP_CMD_MOVETO_X:
00376                 /* Moveto bezüglich Origin = rotoffx,y ! */
00377                 spm.scanp.MV_Xnew = GetParamI (DSP_MOVETOX);
00378                 spm.LastSPMMode = spm.SPMMode; /* [12.04.1996] PZ: keine anderen Komandos zulassen !! */
00379                 spm.SPMMode = (spm.SPMMode & ~(MD_SCAN | MD_CMD)) | MD_MOVE;
00380                 /* in Move-Modus übergehen */
00381                 spm.scanp.MV_XPos = spm.scanp.MV_Xnew;
00382                 /* DSPack: Acknowledge erst, wenn MoveTo beendet !! */
00383                 DSPack;
00384                 break;
00385     
00386         case DSP_CMD_MOVETO_Y:
00387                 /* Moveto bezüglich Origin = rotoffx,y ! */
00388                 spm.scanp.MV_Ynew = GetParamI (DSP_MOVETOY);
00389                 spm.LastSPMMode = spm.SPMMode; /* [12.04.1996] PZ: keine anderen Komandos zulassen !! */
00390                 spm.SPMMode = (spm.SPMMode & ~(MD_SCAN | MD_CMD)) | MD_MOVE;
00391                 /* in Move-Modus übergehen */
00392                 spm.scanp.MV_YPos = spm.scanp.MV_Ynew;
00393                 /* DSPack: Acknowledge erst, wenn MoveTo beendet !! */    
00394                 DSPack;
00395                 break;
00396                 
00397         case DSP_CMD_MOVETO_PARAM:
00398                 
00399                 spm.scanp.MV_stepsize = GetParamI (DSP_MVSTEPSZ);
00400                 spm.scanp.MV_nRegel   = GetParamI (DSP_MVNREGEL);
00401                 DSPack;
00402                 break;
00403                 
00404         case DSP_CMD_HALT:                      /* Regler stoppen ! */
00405                 LCDclear();
00406                 LCDprintf(" FB off");
00407                 spm.SPMMode &= ~MD_PID;
00408                 DSPack;
00409                 break;
00410                 
00411         case DSP_CMD_START:             /* Regler starten ! */
00412                 LCDclear();
00413                 LCDprintf(" FB on");
00414                 if(!(spm.SPMMode & MD_PID)) spm.SPMMode |= MD_PID;
00415                 DSPack;
00416                 break;
00417                 
00418         case DSP_CMD_SWAPDPRAM:
00419                 DSPack;
00420                 break;
00421                 
00422         case DSP_CMD_LINESCAN:
00423                 
00424                 spm.scanp.LS_nx2scan = GetParamI (DSP_LSNX);
00425                 if( spm.scanp.LS_nx2scan > MAXSCANPOINTS ) spm.scanp.LS_nx2scan = MAXSCANPOINTS;
00426                 if( spm.scanp.LS_nx2scan & 1 ) ++spm.scanp.LS_nx2scan; /* Gerade Anzahl (nur in 32bit DPRAM Mode wichtig ! */
00427                 spm.scanp.LS_dnx     = GetParamI (DSP_LSDNX);
00428                 spm.scanp.LS_stepsize= GetParamI (DSP_LSSTEPSZ);
00429                 spm.scanp.LS_nRegel  = GetParamI (DSP_LSNREGEL);
00430                 spm.scanp.LS_nAve    = GetParamI (DSP_LSNAVE);
00431                 spm.scanp.LS_IntAve  = GetParamI (DSP_LSINTAVE);
00432                 spm.scanp.LS_nx_pre  = GetParamI (DSP_LSNXPRE);
00433                 spm.scanp.LS_srcs    = GetParamI (DSP_LSSRCS);
00434                 
00435                 LCDclear();
00436                 LCDprintf("LS dnx: %d %x ", spm.scanp.LS_dnx, spm.scanp.LS_srcs);
00437                 
00438 #define MSK_PID(X)  (1<<((X)&3))
00439 #define MSK_MUXA(X) (1<<(((X)&3)+4))
00440 #define MSK_MUXB(X) (1<<(((X)&3)+8))
00441 #define MSK_AUX(X)  (1<<(((X)&3)+12))
00442                 
00443 #define CHECK_PID(N) if(spm.scanp.LS_srcs & MSK_PID(N)){ if(spm.scanp.LS_ChAnz<MAXCHANNELS) { spm.scanp.ChPtr[spm.scanp.LS_ChAnz]=&spm.scanp.U_z; spm.scanp.LS_ChPID=N; spm.scanp.LS_ChAnz++; }}
00444 
00445 #define CHECK_SRCA(N) if(spm.scanp.LS_srcs & MSK_MUXA(N)){ if(spm.scanp.LS_ChAnz<MAXCHANNELS) { spm.scanp.ChPtr[spm.scanp.LS_ChAnz]=&spm.scanp.adc_values[N]; spm.scanp.LS_ChAnz++; }}
00446 
00447 #define CHECK_SRCB(N) if(spm.scanp.LS_srcs & MSK_MUXB(N)){ if(spm.scanp.LS_ChAnz<MAXCHANNELS) { spm.scanp.ChPtr[spm.scanp.LS_ChAnz]=&spm.scanp.adc_values[N+4]; spm.scanp.LS_ChAnz++; }}
00448 
00449 #define CHECK_AUX(N) if(spm.scanp.LS_srcs & MSK_AUX(N)){ if(spm.scanp.LS_ChAnz<MAXCHANNELS) { spm.scanp.ChPtr[spm.scanp.LS_ChAnz]=&spm.scanp.adc_values[N+8]; spm.scanp.LS_ChAnz++; }}
00450 
00451                 // setup channel-table
00452                 spm.scanp.LS_ChAnz=0; spm.scanp.LS_ChAkt=0;
00453                 // PID-(Z)Wert (no AD Port), PID Src (I,F,dF,..)
00454                 CHECK_PID(0)
00455                 else CHECK_PID(1)
00456                 else CHECK_PID(2)
00457                 else CHECK_PID(3)
00458                 else { spm.scanp.LS_ChPID=-1; }
00459                 
00460                 // AD SRC "A" Ch0..3 
00461                 CHECK_SRCA(0)
00462                 CHECK_SRCA(1)
00463                 CHECK_SRCA(2)
00464                 CHECK_SRCA(3)
00465                 
00466                 // AD SRC "B" Ch0..3 
00467                 CHECK_SRCB(0)
00468                 CHECK_SRCB(1)
00469                 CHECK_SRCB(2)
00470                 CHECK_SRCB(3)
00471                 
00472                 // auxillary SRC "AUX", Soft. gen. data
00473                 CHECK_AUX(0)
00474                 CHECK_AUX(1)
00475                 CHECK_AUX(2)
00476                 CHECK_AUX(3)
00477                 
00478                 spm.scanp.LS_xnext = spm.scanp.MV_XPos;         /* nächste X Position zum Werteaufnahme */
00479                 spm.scanp.LS_xE = spm.scanp.MV_XPos + (long)spm.scanp.LS_dnx*(long)(spm.scanp.LS_nx2scan + 2*spm.scanp.LS_nx_pre);      /* X-Endposition */
00480                 spm.scanp.LS_SmpFlg = 0;                /* gleich ersten Me wert aufnehemen */
00481                 spm.scanp.LS_AveCount = 0;              /* Mittelungszähler löschen */
00482                 /* LS_BUFFER Index auf Start Wert 
00483                  * LS_Xinc = +1 : X+ Scan
00484                  * LS_Xinc = -1 : X- Scan
00485                  */
00486                 if(spm.scanp.LS_dnx > 0){
00487                         spm.scanp.LS_Xinc = 1;   /* Index increment */
00488                         spm.scanp.LS_Xindex = -spm.scanp.LS_nx_pre; /* first Index */
00489                 }
00490                 else{
00491                         spm.scanp.LS_Xinc = -1;   /* Index decrement */
00492                         spm.scanp.LS_Xindex = spm.scanp.LS_nx2scan+spm.scanp.LS_nx_pre; /* last Index */
00493                 }
00494                 
00495                 spm.LastSPMMode = spm.SPMMode;
00496                 spm.SPMMode = (spm.SPMMode & ~(MD_SCAN | MD_CMD)) | MD_SCAN;
00497 //              wakeup run_dspsim_loop;
00498                 run_testscan();
00499                 DSPack;
00500                 /* DSPack: Acknowledge erst, wenn LineScan beendet !! */
00501                 break;
00502                 
00503         case DSP_CMD_PROBESCAN:
00504                 
00505                 spm.scanp.PRB_nx = GetParamI (DSP_PRBNX);
00506                 if( spm.scanp.PRB_nx > MAXSCANPOINTS ) spm.scanp.PRB_nx = MAXSCANPOINTS;
00507                 if( spm.scanp.PRB_nx & 1 ) ++spm.scanp.PRB_nx; /* Gerade Anzahl (nur in 32bit DPRAM Mode wichtig ! */
00508                 spm.scanp.PRB_xS     = U2INT (GetParamF (DSP_PRBXS));
00509                 spm.scanp.PRB_xE     = U2INT (GetParamF (DSP_PRBXE));
00510                 spm.scanp.PRB_ACAmp  = U2INT (GetParamF (DSP_PRBACAMP));
00511                 spm.scanp.PRB_ACFrq  = GetParamI (DSP_PRBACFRQ);
00512                 spm.scanp.PRB_ACPhase= GetParamI (DSP_PRBACPHASE);
00513                 spm.scanp.PRB_GapAdj = GetParamI (DSP_PRBGAPADJ);
00514                 spm.scanp.PRB_delay  = GetParamI (DSP_PRBDELAY);
00515                 spm.scanp.PRB_CIval  = GetParamF (DSP_PRBCIVAL);
00516                 spm.scanp.PRB_srcs   = GetParamI (DSP_PRBSRCS);
00517                 spm.scanp.PRB_outp   = GetParamI (DSP_PRBOUTP);
00518                 spm.scanp.PRB_nAve   = GetParamI (DSP_PRBNAVE);
00519                 
00520                 LCDclear();
00521                 LCDprintf("PRB nx: %d %04x ", spm.scanp.PRB_nx, spm.scanp.PRB_srcs);
00522 #define MSK_PID(X)  (1<<((X)&3))
00523 #define MSK_MUXA(X) (1<<(((X)&3)+4))
00524 #define MSK_MUXB(X) (1<<(((X)&3)+8))
00525 #define MSK_OUTP(X)  (1<<(((X)&3)+12))
00526                 
00527 #define CHECK_PRBSRCA(N) if(spm.scanp.PRB_srcs & MSK_MUXA(N)){ if(spm.scanp.PRB_ChAnz<MAXCHANNELS) { spm.scanp.ChPtr[spm.scanp.PRB_ChAnz]=&spm.scanp.adc_values[N]; spm.scanp.PRB_ChAnz++; }}
00528 
00529                 /* setup channel-table
00530                    
00531                 Einstellung der Meßwertaufnahme nach demselben Prinzip wie beim linescan:
00532                 PRB_srcs ist eine Bitmaske für die einzelnen Wandler.  In den 16Bit sind mit je
00533                 4Bit kodiert: PIDsrc, MuxA, MuxB, Aux
00534                 Ist z.B. das 6. Bit gesetzt wird der 2. Kanal von MuxA aufgenommen.
00535                 */
00536                 spm.scanp.PRB_ChAnz=1; spm.scanp.PRB_ChAkt=0;
00537                 
00538                 // PCI32: AD Ch0..3 
00539                 CHECK_PRBSRCA(0)
00540                 CHECK_PRBSRCA(1)
00541                 CHECK_PRBSRCA(2)
00542                 CHECK_PRBSRCA(3)
00543                 
00544                 spm.scanp.PRB_dnx = ((float)spm.scanp.PRB_xE - (float)spm.scanp.PRB_xS) / (float)spm.scanp.PRB_nx;  /* Schrittweite berechnen */
00545                 spm.scanp.PRB_Xindex = 0;
00546                 
00547                 spm.scanp.PRB_AveCount = 0;             /* Mittelungszähler zurücksetzen */
00548                 { 
00549                         int i;
00550                         for(i=0; i<spm.scanp.PRB_ChAnz; ++i)  /* Kanalsummen zurücksetzen */
00551                                 spm.scanp.PRB_ChSum[i] = 0.;
00552                 }
00553                 spm.LastSPMMode = spm.SPMMode;
00554                 
00555                 /* Regler adjust, first store old values */
00556                 if(spm.scanp.PRB_CIval >= 0.){
00557                         spm.scanp.PRB_CPIS[0] = spm.scanp.Const_I;
00558                         spm.scanp.PRB_CPIS[1] = spm.scanp.Const_P;
00559                         spm.scanp.PRB_CPIS[2] = spm.scanp.Const_S;
00560                         spm.scanp.Const_S = spm.scanp.Const_P = 0.; 
00561                         spm.scanp.Const_I = spm.scanp.PRB_CIval; // disable/slowdown Feedback by this !
00562                 }
00563                 
00564                 spm.SPMMode = (spm.SPMMode & ~(MD_PROBE | MD_CMD)) | MD_PROBE;
00565                 
00566                 spm.scanp.dacbufferZ = ZSIGNUM((int)(spm.scanp.U_z));
00567                 spm.scanp.PRB_oldU = spm.scanp.dacbufferU;
00568                 spm.scanp.PRB_oldZ = spm.scanp.dacbufferZ;
00569                 
00570                 /* Startposition anfahren */
00571                 spm.scanp.PRB_XPos = spm.scanp.PRB_xS;
00572                 switch(spm.scanp.PRB_outp){
00573                 case 0: DACoutX((long)spm.scanp.PRB_XPos); break;
00574                 case 1: DACoutY((long)spm.scanp.PRB_XPos); break;
00575                 case 2: DACoutZ((long)spm.scanp.PRB_XPos); break;
00576                 case 3: DACoutU((long)spm.scanp.PRB_XPos); break;
00577                 }
00578                 
00579                 /* DSPack: Acknowledge erst, wenn ProbeScan beendet !! */               
00580                 run_testprbscan();
00581                 
00582                 DSPack;
00583                 break;  /* Ende Probe Scan */
00584                 
00585                 
00586                 
00587         case DSP_CMD_APPROCH_PARAM:
00588                 
00589                 spm.scanp.TIP_nSteps = GetParamI (DSP_TIPNSTEPS);
00590                 spm.scanp.TIP_nWarte = GetParamI (DSP_TIPNWARTE)/REGEL_DT;
00591                 spm.scanp.TIP_DUz    = GetParamI (DSP_TIPDUZ);
00592                 spm.scanp.TIP_DUzRev = GetParamI (DSP_TIPDUZREV);
00593                 DSPack;
00594                 break;
00595                 
00596 #ifdef AFM_MOVER
00597         case DSP_CMD_AFM_SLIDER_PARAM:
00598                 
00599                 spm.scanp.afm_piezo_amp   = (long) U2INT (GetParamF (DSP_AFM_SLIDER_AMP));
00600                 spm.scanp.afm_u_piezomax  = spm.scanp.afm_piezo_amp/2;
00601                 spm.scanp.afm_piezo_speed = GetParamI (DSP_AFM_SLIDER_SPEED);
00602                 spm.scanp.afm_piezo_steps = GetParamI (DSP_AFM_SLIDER_STEPS);
00603                 LCDclear();
00604                 LCDprintf(" Slider #: %ld",afm_piezo_steps);
00605                 DSPack;
00606                 break;
00607                 
00608         case DSP_CMD_AFM_MOV_XP:
00609                 spm.scanp.AFM_MV_count = 0L;
00610                 spm.scanp.AFM_MV_Scount = 0L;
00611 # ifdef USE_MOVER_APP
00612                 spm.scanp.afm_mover_mode = AFM_MOV_XP;
00613 # else
00614 #  ifdef CARD_PCI32
00615 #   ifdef TYP_STM
00616                 spm.scanp.afm_mover_mode = AFM_MOV_XP;
00617 #   else
00618                 spm.scanp.afm_mover_mode = AFM_MOV_QP;
00619 #   endif
00620 #  else
00621                 spm.scanp.afm_mover_mode = AFM_MOV_XP;
00622 #  endif
00623 # endif
00624                 spm.LastSPMMode = spm.SPMMode; /* [12.04.1996] PZ: keine anderen Komandos zulassen !! */
00625                 spm.SPMMode = (spm.SPMMode & ~(MD_CMD | MD_PID)) | MD__AFMADJ;
00626                 DSPack;
00627                 break;  
00628         case DSP_CMD_AFM_MOV_XM:
00629                 spm.scanp.AFM_MV_count = 0L;
00630                 spm.scanp.AFM_MV_Scount = 0L;
00631 # ifdef USE_MOVER_APP
00632                 spm.scanp.afm_mover_mode = AFM_MOV_XM;
00633 # else
00634 #  ifdef CARD_PCI32
00635 #   ifdef TYP_STM
00636                 spm.scanp.afm_mover_mode = AFM_MOV_XM;
00637 #   else
00638                 spm.scanp.afm_mover_mode = AFM_MOV_QM;
00639 #   endif
00640 #  else
00641                 spm.scanp.afm_mover_mode = AFM_MOV_XM;
00642 #  endif
00643 # endif
00644                 spm.LastSPMMode = spm.SPMMode; /* [12.04.1996] PZ: keine anderen Komandos zulassen !! */
00645                 spm.SPMMode = (spm.SPMMode & ~(MD_CMD | MD_PID)) | MD__AFMADJ;
00646                 DSPack;
00647                 break;  
00648         case DSP_CMD_AFM_MOV_YP:
00649                 spm.scanp.AFM_MV_count = 0L;
00650                 spm.scanp.AFM_MV_Scount = 0L;
00651                 spm.scanp.afm_mover_mode = AFM_MOV_YP;
00652                 spm.LastSPMMode = spm.SPMMode; /* [12.04.1996] PZ: keine anderen Komandos zulassen !! */
00653                 spm.SPMMode = (spm.SPMMode & ~(MD_CMD | MD_PID)) | MD__AFMADJ;
00654                 DSPack;
00655                 break;
00656         case DSP_CMD_AFM_MOV_YM:
00657                 spm.scanp.AFM_MV_count = 0L;
00658                 spm.scanp.AFM_MV_Scount = 0L;
00659                 spm.scanp.afm_mover_mode = AFM_MOV_YM;
00660                 spm.LastSPMMode = spm.SPMMode; /* [12.04.1996] PZ: keine anderen Komandos zulassen !! */
00661                 spm.SPMMode = (spm.SPMMode & ~(MD_CMD | MD_PID)) | MD__AFMADJ;
00662                 DSPack;
00663                 break;
00664 #endif    
00665                 
00666         case DSP_CMD_APPROCH: /* start Auto Approch with Z Slider */
00667                 LCDclear();
00668                 LCDprintf(" Auto App Go");
00669 #ifdef AFM_MOVER
00670                 spm.scanp.afm_mover_app=0;
00671 #endif
00672                 
00673 #ifdef TYP_STM
00674                 if(! (spm.SPMMode & MD_SCAN || spm.SPMMode & MD_MOVE 
00675                       || spm.SPMMode & MD_TIPDN || spm.SPMMode & MD_ITU))
00676 #else
00677                         if(! (SPMMode & MD_SCAN || spm.SPMMode & MD_MOVE 
00678                               || spm.SPMMode & MD_TIPDN))
00679 #endif
00680                         {
00681                                 SLIDERPORT(SL_OFF);
00682                                 SLIDERTRIGGER_OFF;      /* Trigger=0 */
00683                                 ZSLIDER_ON;             /* Z-- Aktivieren */
00684                                 spm.scanp.TIP_Mode = TIP_ZPiezoMax;
00685                                 spm.scanp.TIP_Zdn = 1;
00686                                 spm.SPMMode |= MD_TIPDN;
00687                                 /* 29.04.96 PZ: Regler wird jetzt verwendet */
00688                         }
00689                 DSPack;
00690                 break;
00691                 
00692         case DSP_CMD_APPROCH_MOV_XP: /* start Auto Approch with Besock Rotator */
00693 #ifdef AFM_MOVER
00694                 LCDclear();
00695                 LCDprintf(" Auto AppXp Go");
00696                 spm.scanp.afm_mover_app=1;
00697 # ifdef TYP_STM
00698                 if(! (spm.SPMMode & MD_SCAN || spm.SPMMode & MD_MOVE 
00699                       || spm.SPMMode & MD_TIPDN || spm.SPMMode & MD_ITU))
00700 # else
00701                         if(! (spm.SPMMode & MD_SCAN || spm.SPMMode & MD_MOVE 
00702                               || spm.SPMMode & MD_TIPDN))
00703 # endif
00704                         {
00705                                 spm.scanp.TIP_Mode = TIP_ZPiezoMax;
00706                                 spm.scanp.TIP_Zdn = 1;
00707                                 spm.SPMMode |= MD_TIPDN;
00708                         }
00709 #else
00710                 LCDclear();
00711                 LCDprintf(" no mover support !");
00712 #endif
00713                 DSPack;
00714                 break;
00715                 
00716         case DSP_CMD_CLR_PA: //clears all params e.g. reacts on pressing the STOP-button at the slider control window
00717 #ifdef MD__AFMADJ
00718                 spm.scanp.AFM_MV_Scount = spm.scanp.afm_piezo_steps;
00719 #endif
00720                 LCDclear();
00721                 LCDprintf(" clear all pa");
00722                 
00723                 //LCDclear();
00724                 //LCDprintf(" stop app!");
00725                 spm.SPMMode &= ~MD_TIPDN;
00726                 ZSLIDER_OFF;
00727                 SLIDERPORT(SL_OFF);
00728                 
00729                 /* XXXXX */
00730                 //for(i=10; i--;)     /* little delay to avoid trigger low while z-- aktive ... */
00731                 //  ZSLIDER_OFF;        /* Z-- release */
00732                 
00733                 SLIDERTRIGGER_OFF;              /* Trigger high: no further approach of slider;  O.Brunke 05.01.01 */ 
00734                 
00735                 DSPack;
00736                 break;
00737                 
00738         case DSP_CMD_ALL_PA:  //Was passiert hier?? Percy fragen!!!
00739                 
00740                 LCDclear();
00741                 LCDprintf(" stop clear");
00742                 spm.SPMMode &= ~MD_TIPDN;
00743                 SLIDERPORT(SL_OFF);
00744                 DSPack;
00745                 break;
00746                 
00747 // report some DSP software information
00748         case DSP_CMD_GETINFO:  /* is the same as the old "DSP_CMD_READY" Dummy-Komando */
00749                 sprintf ((char*)BUFFERL, 
00750                          "*123-567-9abXdefS   M   -   D   S   P   -   S   O   F   T   -   I   N   F   O   -   -   *xxx\n"
00751                          "*--KERNEL-DSP-SPM-EMU-SOFT-INFO--*\n"
00752                          "XSM-EMU-Version: >1.5\n"
00753                          "CVS-Version: >1.5\n"
00754                          "StartMessage: " TITLE "\n"
00755                          "SRAM: 0 kW -- only linux kernel limited\n"
00756                          "*--Features--*\n"
00757                          "INSTRUMENT-TYPE: SPM\n"
00758                          "SCAN: Yes\n"
00759                          "MOVE: Yes\n"
00760                          "PROBE: Yes\n"
00761                          "ACPROBE: No\n"
00762                          "*--PROBE-CONFIG--*\n"
00763                          "ProbeDataMode: short\n"
00764                          "*--EOF--*\n"
00765                          "@@@@END@@@@\n"
00766                          );
00767                 DSPack;
00768                 break;
00769         default: 
00770                 LCDclear();
00771                 LCDprintf("unkownd CMD=0x%2x", *CMD_BUFFER & 0xff);
00772                 break;
00773         }
00774         REQD_DSP = FALSE;
00775 }
00776 
00777 void calc_xy( void ){
00778         long valuexi,valueyi;
00779         float valuex,valuey;
00780         
00781         valuex= (float) spm.scanp.MV_XPos;
00782         valuey= (float) spm.scanp.MV_YPos;
00783   
00784         valuexi= (long)(valuex*spm.scanp.rotmxx + valuey*spm.scanp.rotmxy) 
00785                 - spm.scanp.rotoffx;
00786         valueyi= (long)(valuex*spm.scanp.rotmyx + valuey*spm.scanp.rotmyy) 
00787                 - spm.scanp.rotoffy;
00788 
00789         /* Range check */
00790         if(valuexi > MAXDA_XVAL)
00791                 valuexi = MAXDA_XVAL;
00792         else
00793                 if(valuexi < -MAXDA_XVAL)
00794                         valuexi = -MAXDA_XVAL;
00795         
00796         if(valueyi > MAXDA_YVAL)
00797                 valueyi = MAXDA_YVAL;
00798         else
00799                 if(valueyi < -MAXDA_YVAL)
00800                         valueyi = -MAXDA_YVAL;
00801 
00802         DACoutXY(valuexi, valueyi);
00803 }
00804 
00805 void DACoutXY(long ix, long iy){
00806         spm.scanp.dacXval = ix;
00807         spm.scanp.dacYval = iy;
00808 }
00809 
00810 void DACoutX(long value){
00811         spm.scanp.dacXval = value;
00812 }
00813 void DACoutY(long value){
00814         spm.scanp.dacYval = value;
00815 }
00816 
00817 void DACoutZ(long value){
00818         spm.scanp.dacZval = value;
00819 }
00820 void DACoutU(long value){
00821         spm.scanp.dacUval = value;
00822 }
00823 
00824 
00825 
00826 void run_testscan( void ){
00827         int n,i;
00828         for(n=0; n<spm.scanp.LS_nx2scan; n++){
00829                 calc_xy ();
00830                 for (i=0; i<spm.scanp.LS_ChAnz; ++i)
00831                         *(BUFFERS + i*spm.scanp.LS_nx2scan + n ) = n/10
00832                                 + spm.scanp.U_tunnel * i
00833                                 + (spm.scanp.LS_dnx > 0 ? 1:-1)
00834                                 * (   surftab[(32767+spm.scanp.dacXval) % SURFSIZE]
00835                                       * surftab[(32767+spm.scanp.dacYval) % SURFSIZE] );
00836                 spm.scanp.MV_XPos += spm.scanp.LS_dnx;
00837         }
00838 }
00839 
00840 void run_testprbscan( void ){
00841         int n,i,sv;
00842         float pv, dv;
00843         calc_xy ();
00844         
00845         sv = surftab[(32767+spm.scanp.dacXval) % SURFSIZE]
00846                 * surftab[(32767+spm.scanp.dacYval) % SURFSIZE];
00847 
00848         pv = spm.scanp.PRB_xS;
00849         dv = (spm.scanp.PRB_xE - spm.scanp.PRB_xS)/spm.scanp.PRB_nx;
00850         for (n=0; n<spm.scanp.PRB_nx; ++n, pv += dv)
00851                 for (i=0; i<spm.scanp.LS_ChAnz; ++i)
00852                         *(BUFFERS + n) = (int) (pv) + sv;
00853 }
00854 
00855 void run_dspsim_loop( void ){
00856         for(;;){
00857                 if(0){
00858                 }
00859                 else break;
00860         }
00861 }

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