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 00033 #include <locale.h> 00034 #include <libintl.h> 00035 00036 #include <fcntl.h> 00037 #include <sys/ioctl.h> 00038 00039 #include "glbvars.h" 00040 #include "plug-ins/hard/modules/dsp.h" 00041 00042 #include "dsp-pci32/xsm/xsmcmd.h" 00043 00044 #include "comedi_hwi.h" 00045 00046 // enable debug: 00047 #define COMEDI_DEBUG(S) XSM_DEBUG (DBG_L4, "comedi_hwi_spm: " << S ) 00048 00049 /* 00050 * Init things 00051 */ 00052 00053 comedi_hwi_spm::comedi_hwi_spm():comedi_hwi_dev(){ 00054 COMEDI_DEBUG("Init Comedi SPM"); 00055 ScanningFlg=0; 00056 } 00057 00058 /* 00059 * Clean up 00060 */ 00061 00062 comedi_hwi_spm::~comedi_hwi_spm(){ 00063 COMEDI_DEBUG("Finish Comedi SPM"); 00064 } 00065 00066 void comedi_hwi_spm::PutParameter(void *src, int grp){ // Parameterstruktur kopieren 00067 static double V=1; 00068 if(src) 00069 memcpy(&dspPar, src, sizeof(DSP_Param)); 00070 00071 /* handle this dspPar in some way: 00072 dspPar.UTunnel <- I guess you need only to set U (you may say V) here! 00073 dspPar.ITunnelSoll 00074 dspPar.CP 00075 dspPar.CI 00076 dspPar.SetPoint 00077 */ 00078 COMEDI_DEBUG("PutParameter: (only if changed!)"); 00079 00080 if (V != dspPar.UTunnel){ 00081 COMEDI_DEBUG(" new V=" << V); 00082 } 00083 } 00084 00085 // just note that we are scanning next... 00086 void comedi_hwi_spm::StartScan2D(){ 00087 ScanningFlg=1; 00088 KillFlg=FALSE; // if this gets TRUE while scanning, you should stopp it!! 00089 } 00090 00091 // and its done now! 00092 void comedi_hwi_spm::EndScan2D(){ 00093 ScanningFlg=0; 00094 } 00095 00096 // we are paused 00097 void comedi_hwi_spm::PauseScan2D(){ 00098 ScanningFlg=0; 00099 } 00100 00101 // and its going againg 00102 void comedi_hwi_spm::ResumeScan2D(){ 00103 ScanningFlg=1; 00104 } 00105 00106 // X position tip, relative to Offset, 00107 // but in rotated cooerd sys! 00108 // Note: X is always the fast scanning direction!! 00109 void comedi_hwi_spm::MovetoXY(long x, long y){ 00110 // this is how I pass params to the DSP 00111 // you could do sth. else here! 00112 // use the rot matrix (rotmxx/xy/yx/yy/rotoffx/rotoffy) !! 00113 /* 00114 PARAMETER_SET hardpar; 00115 rx=x; 00116 hardpar.N = DSP_MOVETOX+1; 00117 hardpar.Cmd = DSP_CMD_MOVETO_X; 00118 hardpar.hp[DSP_MOVETOX ].value = x; 00119 SetParameter(hardpar); 00120 */ 00121 COMEDI_DEBUG("MovetoX: " << x); rx=x; 00122 00123 // use the rot matrix (rotmxx/xy/yx/yy/rotoffx/rotoffy) !! 00124 /* 00125 PARAMETER_SET hardpar; 00126 ry=y; 00127 hardpar.N = DSP_MOVETOY+1; 00128 hardpar.Cmd = DSP_CMD_MOVETO_Y; 00129 hardpar.hp[DSP_MOVETOY ].value = y; 00130 SetParameter(hardpar); 00131 */ 00132 COMEDI_DEBUG("MovetoY: " << y); ry=y; 00133 } 00134 00135 // this does almost the same as the XSM_Hardware base class would do, 00136 // but you may want to do sth. yourself here 00137 void comedi_hwi_spm::SetDxDy(int dx, int dy){ 00138 Dx = dx; 00139 Dy = dy; 00140 dspPar.LS_dnx = dx; 00141 COMEDI_DEBUG("SetDxSy: " << dx << ", " << dy); 00142 } 00143 00144 // this does almost the same as the XSM_Hardware base class would do, 00145 // but you may want to do sth. yourself here 00146 void comedi_hwi_spm::SetOffset(long x, long y){ 00147 rotoffx = x; rotoffy = y; 00148 COMEDI_DEBUG("SetOffset: " << x << ", " << y); 00149 } 00150 00151 // this does almost the same as the XSM_Hardware base class would do, 00152 // but you may want to do sth. yourself here 00153 void comedi_hwi_spm::SetAlpha(double alpha){ 00154 // calculate rot matrix 00155 Alpha=M_PI*alpha/180.; 00156 rotmyy = rotmxx = cos(Alpha); 00157 rotmyx = -(rotmxy = sin(Alpha)); 00158 COMEDI_DEBUG("SetAlpha: " << alpha); 00159 } 00160 00161 // this does almost the same as the XSM_Hardware base class would do, 00162 // but you may want to do sth. yourself here 00163 void comedi_hwi_spm::SetNx(long nx){ 00164 Nx=nx; 00165 dspPar.LS_nx2scan = nx; 00166 COMEDI_DEBUG("Setnx: " << nx); 00167 } 00168 00169 00170 /* 00171 * Do ScanLine in multiple Channels Mode 00172 * 00173 * yindex: Index of Line 00174 * xdir: Scanning Direction (1:+X / -1:-X) eg. for/back scan 00175 * lsscrs: LineScan Sources, MUX/Channel Configuration 00176 * PC31 has can handle 2 Channels of 16bit data simultan, using 4-fold Mux each 00177 * additional the PID-Outputvalue can be used and the PID Src is set by MUXA 00178 * it may be possible to switch MUXB while scanning -- test it !!! 00179 * bit 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 ... 00180 * PC31: ==PID== =MUX-A= ==MUX-B== 00181 * PCI32: ==PID== A====== B======== C==== D==== 00182 * eg. Z-Value Fz/I Fric... 00183 * example: 00184 * value 1 0 0 0 1 0 0 0 1 0 0 0 0... 00185 * buffers B0 B1 B2 00186 * 3 buffers used for transfer (B0:Z, B1:Force, B2:Friction) 00187 * 00188 * Mob: List of MemObjs. to store Data 00189 * 00190 * with maximized DPRAM usage: [DPRAM] [DSPMEM1] [DSPMEM2] ... (Blocks of same size) 00191 * B0,B1, B2, B3, B4,.. 00192 * nach DSP_CMD_SWAPDPRAM: B2,B3, ------- B4,.. 00193 * nach DSP_CMD_SWAPDPRAM: B4,.. ------- ------- 00194 * ... 00195 * 00196 */ 00197 00198 void comedi_hwi_spm::ScanLineM(int yindex, int xdir, int lssrcs, Mem2d *Mob[MAX_SRCS_CHANNELS], int ix0 ){ 00199 00200 if (yindex < 0){ // HS capture (-1) / init (-2) ? 00201 if (yindex != -1) return; // XP/XM init cycle 00202 return; // ... or run 2D HS caprture 00203 } 00204 00205 // this is how I pass parameters to the DSP 00206 // you may use thoes otherwise 00207 /* 00208 PARAMETER_SET hardpar; 00209 00210 hardpar.N = DSP_LSYINDEX+1; 00211 hardpar.Cmd = DSP_CMD_LINESCAN; 00212 hardpar.hp[DSP_LSNX ].value = dspPar.LS_nx2scan; 00213 if(xdir<0) // Rück - Scan (-) 00214 hardpar.hp[DSP_LSDNX ].value = -dspPar.LS_dnx; 00215 else // Hin - Scan (+) 00216 hardpar.hp[DSP_LSDNX ].value = dspPar.LS_dnx; 00217 hardpar.hp[DSP_LSSTEPSZ ].value = dspPar.LS_stepsize; 00218 hardpar.hp[DSP_LSNREGEL ].value = dspPar.LS_nRegel; 00219 hardpar.hp[DSP_LSNAVE ].value = dspPar.LS_nAve; 00220 hardpar.hp[DSP_LSINTAVE ].value = dspPar.LS_IntAve; 00221 hardpar.hp[DSP_LSNXPRE ].value = dspPar.LS_nx_pre; 00222 hardpar.hp[DSP_LSSRCS ].value = lssrcs; // Codierte MUX/Srcs Configuration 00223 hardpar.hp[DSP_LSYINDEX ].value = yindex; // for verify only 00224 00225 // waits until done!!! But calls the check event func for non blocking! 00226 SetParameter(hardpar, TRUE); 00227 */ 00228 // call this while waiting for background data updates on screen... 00229 CallIdleFunc (); 00230 00231 // calc # of srcs 00232 int num_srcs = 0; 00233 int bi = 0; 00234 do{ 00235 if(lssrcs & (1<<bi++)) 00236 ++num_srcs; 00237 }while(bi<16); 00238 00239 ReadScanData (yindex, num_srcs, Mob); 00240 }