sranger_hwi_vectorgen.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 /* ignore this module for docuscan
00029 % PlugInModuleIgnore
00030 */
00031 
00032 
00033 
00034 #include <locale.h>
00035 #include <libintl.h>
00036 
00037 #include <time.h>
00038 
00039 #include "glbvars.h"
00040 #include "plug-ins/hard/modules/dsp.h"
00041 #include <fcntl.h>
00042 #include <sys/ioctl.h>
00043 
00044 #include "gxsm/action_id.h"
00045 
00046 #include "dsp-pci32/xsm/xsmcmd.h"
00047 
00048 #include "sranger_hwi_control.h"
00049 #include "sranger_hwi.h"
00050 #include "gtkspinbuttonsci.h"
00051 #include "../plug-ins/hard/modules/sranger_ioctl.h"
00052 
00053 
00054 extern GxsmPlugin sranger_hwi_pi;
00055 extern sranger_hwi_dev *sranger_hwi_hardware;
00056 
00057 
00058 
00059 #define CONV_16(X) X = sranger_hwi_hardware->int_2_sranger_int (X)
00060 #define CONV_32(X) X = sranger_hwi_hardware->long_2_sranger_long (X)
00061 
00062         
00063 void DSPControl::conv_dsp_probe (){
00064         CONV_16 (dsp_probe.start);
00065         CONV_16 (dsp_probe.AC_amp);
00066         CONV_16 (dsp_probe.AC_frq);
00067         CONV_16 (dsp_probe.AC_phaseA);
00068         CONV_16 (dsp_probe.AC_phaseB);
00069         CONV_16 (dsp_probe.AC_nAve);
00070         CONV_32 (dsp_probe.Zpos);
00071 //      CONV_16 (dsp_probe.);
00072 //      CONV_32 (dsp_probe.);
00073         CONV_16 (dsp_probe.vector_head);
00074 
00075 }
00076 
00077 void DSPControl::read_dsp_probe (){
00078         if (!sranger_hwi_hardware) return; 
00079 
00080         lseek (sranger_hwi_hardware->dsp, sranger_hwi_hardware->magic_data.probe, SRANGER_SEEK_DATA_SPACE);
00081         read  (sranger_hwi_hardware->dsp, &dsp_probe, sizeof (dsp_probe)); 
00082 
00083         // from DSP to PC
00084         conv_dsp_probe ();
00085 
00086         // update, reconvert
00087         AC_amp = gapp->xsm->Inst->Dig2VoltOut ((double)dsp_probe.AC_amp) / gapp->xsm->Inst->BiasV2V (1.);
00088         AC_frq = dsp_probe.AC_frq;
00089         if (AC_frq < 32)
00090                 AC_frq = 1.+22000.*AC_frq/128.;
00091 
00092         AC_phaseA = (double)dsp_probe.AC_phaseA/16.;
00093         AC_phaseB = (double)dsp_probe.AC_phaseB/16.;
00094         AC_lockin_avg_cycels = dsp_probe.AC_nAve;
00095 
00096         update ();
00097 }
00098 
00099 
00100 // some needfull macros to get some readable code
00101 #define CONST_DSP_F16 65536.
00102 #define VOLT2AIC(U)   (int)(gapp->xsm->Inst->VoltOut2Dig (gapp->xsm->Inst->BiasV2V (U)))
00103 
00104 
00105 // make automatic n and dnx from float number of steps, keep n below 1000.
00106 void DSPControl::make_auto_n_vector_elments (double fnum){
00107         dsp_vector.n = 1;
00108         dsp_vector.dnx = 0;
00109         if (fnum >= 1.){
00110                 if (fnum <= 1000.){ // automatic n ramp limiter
00111                         dsp_vector.n = (DSP_LONG)round (fnum);
00112                         dsp_vector.dnx = 0;
00113                 } else if (fnum <= 10000.){
00114                         dsp_vector.n = (DSP_LONG)round (fnum/10.);
00115                         dsp_vector.dnx = 10;
00116                 } else if (fnum <= 100000.){
00117                         dsp_vector.n = (DSP_LONG)round (fnum/100.);
00118                         dsp_vector.dnx = 100;
00119                 } else if (fnum <= 1000000.){
00120                         dsp_vector.n = (DSP_LONG)round (fnum/1000.);
00121                         dsp_vector.dnx = 1000;
00122                 } else{
00123                         dsp_vector.n = (DSP_LONG)round (fnum/10000.);
00124                         dsp_vector.dnx = 10000;
00125                 }
00126         }
00127         ++dsp_vector.n;
00128 }
00129 
00130 // make IV and dz (optional) vector from U_initial, U_final, dZ, n points and V-slope
00131 // Options:
00132 // Ramp-Mode: MAKE_VEC_FLAG_RAMP, auto n computation
00133 // FixV-Mode: MAKE_VEC_FLAG_VHOLD, fix bias, only compute "speed" by Ui,Uf,slope
00134 double DSPControl::make_Vdz_vector (double Ui, double Uf, double dZ, int n, double slope, int source, int options, double long &duration, make_vector_flags flags){
00135         double dv = fabs (Uf - Ui);
00136         if (flags & MAKE_VEC_FLAG_RAMP || n < 2)
00137                 make_auto_n_vector_elments (dv/slope*frq_ref);
00138         else {
00139                 dsp_vector.n = n; // number of steps to do
00140                 ++dsp_vector.n;
00141                 dsp_vector.dnx = abs((DSP_LONG)round ((Uf - Ui)*frq_ref/(slope*dsp_vector.n))); // distance of samples in steps  
00142         }
00143         double steps = (double)(dsp_vector.n-1) * (double)(dsp_vector.dnx+1);
00144 
00145         duration += (double long) steps;
00146         dsp_vector.srcs = source & 0xffff; // source channel coding
00147         dsp_vector.options = options;
00148         dsp_vector.ptr_final = flags & MAKE_VEC_FLAG_END ? 0:1; // VPC relative branch to next vector
00149         dsp_vector.f_du = flags & MAKE_VEC_FLAG_VHOLD ? 0 : (DSP_LONG)round (CONST_DSP_F16*gapp->xsm->Inst->VoltOut2Dig (gapp->xsm->Inst->BiasV2V (Uf-Ui))/steps);
00150         dsp_vector.f_dz = (DSP_LONG)round (CONST_DSP_F16*gapp->xsm->Inst->ZA2Dig (dZ/steps));
00151         dsp_vector.f_dx = 0;
00152         dsp_vector.f_dy = 0;
00153         dsp_vector.f_dx0 = 0;
00154         dsp_vector.f_dy0 = 0;
00155         dsp_vector.f_dphi = 0;
00156         return gapp->xsm->Inst->V2BiasV (gapp->xsm->Inst->Dig2VoltOut (VOLT2AIC(Ui) + (double)dsp_vector.f_du*steps/CONST_DSP_F16));
00157 }       
00158 
00159 // make dZ/dX/dY vector from n point (if > 2, else automatic n) and (dX,dY,dZ) slope
00160 double DSPControl::make_ZXYramp_vector (double dZ, double dX, double dY, int n, double slope, int source, int options, double long &duration, make_vector_flags flags){
00161         double dr = sqrt(dZ*dZ + dX*dX + dY*dY);
00162 
00163         if (flags & MAKE_VEC_FLAG_RAMP || n<2)
00164                 make_auto_n_vector_elments (dr/slope*frq_ref);
00165         else {
00166                 dsp_vector.n = n;
00167                 dsp_vector.dnx = (DSP_LONG)round ( fabs (dr*frq_ref/(slope*dsp_vector.n)));
00168                 ++dsp_vector.n;
00169         }
00170         double steps = (double)(dsp_vector.n-1) * (double)(dsp_vector.dnx+1);
00171 
00172         duration += (double long) steps;
00173         dsp_vector.srcs = source & 0xffff;
00174         dsp_vector.options = options;
00175         dsp_vector.ptr_fb = 0;
00176         dsp_vector.repetitions = 0;
00177         dsp_vector.ptr_next = 0x0;
00178         dsp_vector.ptr_final = flags & MAKE_VEC_FLAG_END ? 0:1; // VPC relative branch to next vector
00179         dsp_vector.f_du = 0;
00180         dsp_vector.f_dx = (DSP_LONG)round (dsp_vector.n > 1 ? (CONST_DSP_F16*gapp->xsm->Inst->XA2Dig (dX) / steps) : 0);
00181         dsp_vector.f_dy = (DSP_LONG)round (dsp_vector.n > 1 ? (CONST_DSP_F16*gapp->xsm->Inst->YA2Dig (dY) / steps) : 0);
00182         dsp_vector.f_dz = (DSP_LONG)round (dsp_vector.n > 1 ? (CONST_DSP_F16*gapp->xsm->Inst->ZA2Dig (dZ) / steps) : 0);
00183         dsp_vector.f_dx0 = 0;
00184         dsp_vector.f_dy0 = 0;
00185         dsp_vector.f_dphi = 0;
00186 
00187         return gapp->xsm->Inst->Dig2ZA ((long)round ((double)dsp_vector.f_dz*steps/CONST_DSP_F16));
00188 }
00189 
00190 // make dPhi vector from n point (if > 2, else automatic n) and dPhi slope
00191 double DSPControl::make_phase_vector (double dPhi, int n, double slope, int source, int options, double long &duration, make_vector_flags flags){
00192         double dr = dPhi*16.;
00193         slope *= 16.;
00194 
00195         if (flags & MAKE_VEC_FLAG_RAMP || n<2)
00196                 make_auto_n_vector_elments (dr/slope*frq_ref);
00197         else {
00198                 dsp_vector.n = n;
00199                 dsp_vector.dnx = (DSP_LONG)round ( fabs (dr*frq_ref/(slope*dsp_vector.n)));
00200                 ++dsp_vector.n;
00201         }
00202         double steps = (double)(dsp_vector.n-1) * (double)(dsp_vector.dnx+1);
00203 
00204         duration += (double long) steps;
00205         dsp_vector.srcs = source & 0xffff;
00206         dsp_vector.options = options;
00207         dsp_vector.ptr_fb = 0;
00208         dsp_vector.repetitions = 0;
00209         dsp_vector.ptr_next = 0x0;
00210         dsp_vector.ptr_final = flags & MAKE_VEC_FLAG_END ? 0:1; // VPC relative branch to next vector
00211         dsp_vector.f_du = 0;
00212         dsp_vector.f_dx = 0;
00213         dsp_vector.f_dy = 0;
00214         dsp_vector.f_dz = 0;
00215         dsp_vector.f_dx0 = 0;
00216         dsp_vector.f_dy0 = 0;
00217         dsp_vector.f_dphi = (DSP_LONG)round (dsp_vector.n > 1 ? (CONST_DSP_F16 * dr / steps) : 0);
00218 
00219         return round ((double)dsp_vector.f_dphi*steps/CONST_DSP_F16/16.);
00220 }
00221 
00222 // Make a delay Vector
00223 double DSPControl::make_delay_vector (double delay, int source, int options, double long &duration, make_vector_flags flags){
00224         make_auto_n_vector_elments (delay*frq_ref);
00225         duration += (double long) (dsp_vector.n-1)*(dsp_vector.dnx+1);
00226         dsp_vector.srcs = source & 0xffff;
00227         dsp_vector.options = options;
00228         dsp_vector.repetitions = 0; // number of repetitions, not used yet
00229         dsp_vector.ptr_next = 0x0;  // pointer to next vector -- not used, only for loops
00230         dsp_vector.ptr_final = flags & MAKE_VEC_FLAG_END ? 0:1;   // VPC relative branch to next vector
00231         dsp_vector.f_du = 0;
00232         dsp_vector.f_dz = 0;
00233         dsp_vector.f_dx = 0; // x stepwidth, not used for probing
00234         dsp_vector.f_dy = 0; // y stepwidth, not used for probing
00235         dsp_vector.f_dx0 = 0; // x0 stepwidth, not used for probing
00236         dsp_vector.f_dy0 = 0; // y0 stepwidth, not used for probing
00237         dsp_vector.f_dphi = 0; // z0 stepwidth, not used for probing
00238         return (double)((long)(dsp_vector.n-1)*(long)(dsp_vector.dnx+1))/frq_ref;
00239 }
00240 
00241 // Make Vector Table End
00242 void DSPControl::append_null_vector (int options, int index){
00243         // NULL vector -- just to clean vector table
00244         dsp_vector.n = 0;
00245         dsp_vector.dnx = 0;
00246         dsp_vector.srcs = 0x0000;
00247         dsp_vector.options = options;
00248         dsp_vector.repetitions = 0; // number of repetitions
00249         dsp_vector.ptr_next = 0;  // END
00250         dsp_vector.ptr_final= 0;  // END
00251         dsp_vector.f_dx = 0;
00252         dsp_vector.f_dy = 0;
00253         dsp_vector.f_dz = 0;
00254         // append 4 NULL-Vectors, just to clean up the end.
00255         write_dsp_vector (index);
00256         write_dsp_vector (index+1);
00257         write_dsp_vector (index+2);
00258         write_dsp_vector (index+3);
00259 }
00260 
00261 // Create Vector Table form Mode (pvm=PV_MODE_XXXXX) and Execute if requested (start=TRUE) or write only
00262 void DSPControl::write_dsp_probe (int start, pv_mode pvm){
00263         int options=0;
00264         int ramp_sources=0x000;
00265         int ramp_points;
00266         int recover_options=0;
00267         int vector_index = 0;
00268         double long vp_duration = 0;
00269         double dU_IV=0.;
00270         double dU_step=0.;
00271 
00272         if (!sranger_hwi_hardware) return; 
00273 
00274         if (!start) // reset 
00275                 probe_trigger_single_shot = 0;
00276 
00277         switch (pvm){
00278         case PV_MODE_NONE: // write dummy delay and NULL Vector
00279                 options      = (PL_option_flags & FLAG_FB_ON     ? 0      : VP_FEEDBACK_HOLD)
00280                              | (PL_option_flags & FLAG_INTEGRATE ? VP_AIC_INTEGRATE : 0);
00281                 ramp_sources = PL_option_flags & FLAG_SHOW_RAMP ? Source : 0x000;
00282                 recover_options = 0;
00283 
00284                 make_delay_vector (0.1, ramp_sources, options, vp_duration, MAKE_VEC_FLAG_NORMAL);
00285                 write_dsp_vector (vector_index++);
00286                 make_delay_vector (0.1, ramp_sources, options, vp_duration, MAKE_VEC_FLAG_END);
00287                 write_dsp_vector (vector_index++);
00288                 append_null_vector (options, vector_index);
00289                 sranger_hwi_hardware->probe_time_estimate = (int)vp_duration; // used for timeout check
00290                 break;
00291 
00292         case PV_MODE_IV: // ------------ Special Vector Setup for IV Probes "Probe ala STM"
00293                 options      = (IV_option_flags & FLAG_FB_ON     ? 0      : VP_FEEDBACK_HOLD)
00294                              | (IV_option_flags & FLAG_INTEGRATE ? VP_AIC_INTEGRATE : 0);
00295                 ramp_sources = IV_option_flags & FLAG_SHOW_RAMP ? Source : 0x000;
00296                 recover_options = 0; // FeedBack On for recovery!
00297 
00298                 // do we need to split up if crossing zero?
00299                 if (fabs (IV_dz) > 0.001 && ((IV_end < 0. && IV_start > 0.) || (IV_end > 0. && IV_start < 0.))){
00300                         int vpc=0;
00301                         // compute sections   
00302                         // z = z0 + dz * ( 1 - | U / Bias | )
00303                         // dz_bi := dz*(1-|Ui/Bias|) - 0
00304                         // dz_i0 := dz - dz_bi
00305                         // dz_0f := dz*(1-|Uf/Bias|) - (dz_bi + dz_i0)
00306                         double ui,u0,uf;
00307                         double dz_bi, dz_i0, dz_0f;
00308                         int n12, n23;
00309                         ui = IV_start; 
00310                         u0 = 0.;
00311                         uf = IV_end;
00312                         n12 = (int)(round ((double)IV_points*fabs (ui/(uf-ui))));
00313                         n23 = (int)(round ((double)IV_points*fabs (uf/(uf-ui))));
00314 
00315                         dz_bi = IV_dz*(1.-fabs (ui/bias));
00316                         dz_i0 = IV_dz - dz_bi;
00317                         dz_0f = IV_dz*(1.-fabs (uf/bias)) - (dz_bi + dz_i0);
00318 
00319                         make_Vdz_vector (bias, ui, dz_bi, -1, IV_slope_ramp, ramp_sources, options, vp_duration, MAKE_VEC_FLAG_RAMP);
00320                         write_dsp_vector (vector_index++);
00321 
00322                         make_Vdz_vector (ui, u0, dz_i0, n12, IV_slope, Source, options, vp_duration, MAKE_VEC_FLAG_NORMAL);
00323                         write_dsp_vector (vector_index++);
00324 
00325                         make_Vdz_vector (u0, uf, dz_0f, n23, IV_slope, Source, options, vp_duration, MAKE_VEC_FLAG_NORMAL);
00326                         write_dsp_vector (vector_index++);
00327 
00328                         dU_IV = uf-ui; dU_step = dU_IV/IV_points;
00329 
00330                         if (IV_option_flags & FLAG_DUAL) {
00331                                 // run also reverse probe ramp in dual mode
00332                                 make_Vdz_vector (uf, u0, -dz_0f, n23, IV_slope, Source, options, vp_duration, MAKE_VEC_FLAG_NORMAL);
00333                                 write_dsp_vector (vector_index++);
00334 
00335                                 make_Vdz_vector (u0, ui, -dz_i0, n12, IV_slope, Source, options, vp_duration, MAKE_VEC_FLAG_NORMAL);
00336                                 write_dsp_vector (vector_index++);
00337 
00338                                 // Ramp back to given bias voltage   
00339                                 make_Vdz_vector (ui, bias, -dz_bi, -1, IV_slope_ramp, ramp_sources, options, vp_duration, MAKE_VEC_FLAG_RAMP);
00340                                 write_dsp_vector (vector_index++);
00341 
00342                         } else {
00343                                 make_Vdz_vector (uf, bias, -(dz_bi+dz_i0+dz_0f), -1, IV_slope_ramp, ramp_sources, options, vp_duration, MAKE_VEC_FLAG_RAMP);
00344                                 write_dsp_vector (vector_index++);
00345                         }
00346 
00347                         if (IV_repetitions > 1){
00348                                 // Final vector, gives the IVC some time to recover   
00349                                 make_delay_vector (IV_final_delay, ramp_sources, options, vp_duration, MAKE_VEC_FLAG_NORMAL);
00350                                 write_dsp_vector (vector_index++);
00351 
00352                                 make_delay_vector (IV_recover_delay, ramp_sources, recover_options, vp_duration, MAKE_VEC_FLAG_NORMAL);
00353                                 dsp_vector.repetitions = IV_repetitions-1;
00354                                 dsp_vector.ptr_next = -vector_index; // go to start
00355                                 write_dsp_vector (vector_index++);
00356                         }
00357 
00358                         vpc = vector_index;
00359                         
00360                         // delay gives the IVC some time to recover   
00361                         make_delay_vector (IV_recover_delay, Source, options, vp_duration, MAKE_VEC_FLAG_NORMAL);
00362                         write_dsp_vector (vector_index++);
00363 
00364                         // add automatic conductivity measurement rho(Z) -- HOLD Bias fixed now!
00365                         make_Vdz_vector (bias, ui, dz_bi, -1, IV_slope_ramp, ramp_sources, options, vp_duration, (make_vector_flags)(MAKE_VEC_FLAG_RAMP | MAKE_VEC_FLAG_VHOLD));
00366                         write_dsp_vector (vector_index++);
00367 
00368                         make_Vdz_vector (ui, u0, dz_i0, n12, IV_slope, Source, options, vp_duration, MAKE_VEC_FLAG_VHOLD);
00369                         write_dsp_vector (vector_index++);
00370 
00371                         make_Vdz_vector (u0, uf, dz_0f, n23, IV_slope, Source, options, vp_duration, MAKE_VEC_FLAG_VHOLD);
00372                         write_dsp_vector (vector_index++);
00373 
00374                         if (IV_option_flags & FLAG_DUAL) {
00375                                 make_Vdz_vector (uf, u0, -dz_0f, n23, IV_slope, Source, options, vp_duration, MAKE_VEC_FLAG_VHOLD);
00376                                 write_dsp_vector (vector_index++);
00377 
00378                                 make_Vdz_vector (u0, ui, -dz_i0, n12, IV_slope, Source, options, vp_duration, MAKE_VEC_FLAG_VHOLD);
00379                                 write_dsp_vector (vector_index++);
00380 
00381                                 make_Vdz_vector (ui, bias, -dz_bi, -1, IV_slope_ramp, ramp_sources, options, vp_duration, (make_vector_flags)(MAKE_VEC_FLAG_RAMP | MAKE_VEC_FLAG_VHOLD));
00382                                 write_dsp_vector (vector_index++);
00383                         } else {
00384                                 make_Vdz_vector (uf, bias, -(dz_bi+dz_i0+dz_0f), -1, IV_slope_ramp, ramp_sources, options, vp_duration, (make_vector_flags)(MAKE_VEC_FLAG_RAMP | MAKE_VEC_FLAG_VHOLD));
00385                                 write_dsp_vector (vector_index++);
00386                         }
00387 
00388                         if (IVdz_repetitions > 1){
00389                                 // Final vector, gives the IVC some time to recover   
00390                                 make_delay_vector (IV_final_delay, ramp_sources, options, vp_duration, MAKE_VEC_FLAG_NORMAL);
00391                                 write_dsp_vector (vector_index++);
00392 
00393                                 make_delay_vector (IV_recover_delay, ramp_sources, recover_options, vp_duration, MAKE_VEC_FLAG_NORMAL);
00394                                 dsp_vector.repetitions = IVdz_repetitions-1;
00395                                 dsp_vector.ptr_next = -(vector_index-vpc); // go to rho start
00396                                 write_dsp_vector (vector_index++);
00397                         }
00398 
00399                 } else {
00400                         // compute sections   
00401                         // z = z0 + dz * ( 1 - | U / Bias | )
00402                         // dz_bi := dz*(1-|Ui/Bias|) - 0
00403                         double ui,uf;
00404                         double dz_bi, dz_if;
00405                         int vpc=0;
00406 
00407                         ui = IV_start; 
00408                         uf = IV_end;
00409                         dz_bi = IV_dz*(1.-fabs (ui/bias));
00410                         dz_if = IV_dz*(1.-fabs (uf/bias)) - dz_bi;
00411 
00412                         make_Vdz_vector (bias, ui, dz_bi, -1, IV_slope_ramp, ramp_sources, options, vp_duration, MAKE_VEC_FLAG_RAMP);
00413                         write_dsp_vector (vector_index++);
00414 
00415                         make_Vdz_vector (ui, uf, dz_if, IV_points, IV_slope, Source, options, vp_duration, MAKE_VEC_FLAG_NORMAL);
00416                         write_dsp_vector (vector_index++);
00417 
00418                         
00419                         dU_IV   = gapp->xsm->Inst->V2BiasV (gapp->xsm->Inst->Dig2VoltOut ((long double)dsp_vector.f_du*(long double)(dsp_vector.n-1)*(long double)(dsp_vector.dnx ? dsp_vector.dnx+1 : 1)/CONST_DSP_F16));
00420                         dU_step = gapp->xsm->Inst->V2BiasV (gapp->xsm->Inst->Dig2VoltOut ((long double)dsp_vector.f_du*(long double)(dsp_vector.dnx ? dsp_vector.dnx+1 : 1)/CONST_DSP_F16));
00421                         
00422                         // add vector for reverse return ramp? -- Force return path if dz != 0
00423                         if (IV_option_flags & FLAG_DUAL) {
00424                                 // run also reverse probe ramp in dual mode
00425                                 make_Vdz_vector (uf, ui, -dz_if, IV_points, IV_slope, Source, options, vp_duration, MAKE_VEC_FLAG_NORMAL);
00426                                 write_dsp_vector (vector_index++);
00427 
00428                                 // Ramp back to given bias voltage   
00429                                 make_Vdz_vector (ui, bias, -dz_bi, -1, IV_slope_ramp, ramp_sources, options, vp_duration, MAKE_VEC_FLAG_RAMP);
00430                                 write_dsp_vector (vector_index++);
00431                         } else {
00432                                 // Ramp back to given bias voltage   
00433                                 make_Vdz_vector (uf, bias, -(dz_if+dz_bi), -1, IV_slope_ramp, ramp_sources, options, vp_duration, MAKE_VEC_FLAG_RAMP);
00434                                 write_dsp_vector (vector_index++);
00435                         }
00436                         if (IV_repetitions > 1){
00437                                 // Final vector, gives the IVC some time to recover   
00438                                 make_delay_vector (IV_final_delay, ramp_sources, options, vp_duration, MAKE_VEC_FLAG_NORMAL);
00439                                 write_dsp_vector (vector_index++);
00440 
00441                                 make_delay_vector (IV_recover_delay, ramp_sources, recover_options, vp_duration, MAKE_VEC_FLAG_NORMAL);
00442                                 dsp_vector.repetitions = IV_repetitions-1;
00443                                 dsp_vector.ptr_next = -vector_index; // go to start
00444                                 write_dsp_vector (vector_index++);
00445                         }
00446                 }
00447 
00448 
00449                 // Final vector, gives the IVC some time to recover   
00450                 make_delay_vector (IV_final_delay, ramp_sources, options, vp_duration, MAKE_VEC_FLAG_END);
00451                 write_dsp_vector (vector_index++);
00452 
00453                 append_null_vector (options, vector_index);
00454 
00455                 sranger_hwi_hardware->probe_time_estimate = (int)vp_duration; // used for timeout check
00456 
00457 
00458                 {
00459                         gchar *info=NULL;
00460                         int warn_flag=FALSE;
00461                         if (probe_trigger_raster_points_user > 0 && write_vector_mode != PV_MODE_NONE){
00462                                 double T_probe_cycle   = 1e3 * (double)vp_duration/frq_ref; // Time of full probe cycle in ms
00463                                 double T_raster2raster = 1e3 * gapp->xsm->data.s.rx / (gapp->xsm->data.s.nx/probe_trigger_raster_points_user) / scan_speed_x; // Time inbetween raster points in ms
00464                                 info = g_strdup_printf ("Tp=%.2f ms, Tr=%.2f ms, Td=%.2f ms", T_probe_cycle, T_raster2raster, T_raster2raster - T_probe_cycle);
00465 
00466                                 if (T_raster2raster <= T_probe_cycle){
00467                                         warn_flag=TRUE;
00468                                         GtkWidget *dialog = gtk_message_dialog_new (NULL,
00469                                                                                     GTK_DIALOG_DESTROY_WITH_PARENT,
00470                                                                                     GTK_MESSAGE_WARNING,
00471                                                                                     GTK_BUTTONS_CLOSE,
00472                                                                                     "The probing at each raster point lasts to long:\n"
00473                                                                                     "Time of one probe cycle is %.2f ms\n"
00474                                                                                     "and\n"
00475                                                                                     "Time from raster to raster point is %.2f ms.\n\n --- FYI: ---\n"
00476                                                                                     "# Raster points per line: %d\n"
00477                                                                                     "Time inbetween single scan points: %.2f ms",
00478                                                                                     T_probe_cycle, T_raster2raster, 
00479                                                                                     gapp->xsm->data.s.nx/probe_trigger_raster_points_user,
00480                                                                                     1e3 * gapp->xsm->data.s.rx / gapp->xsm->data.s.nx / scan_speed_x
00481                                                                                     );
00482                                         g_signal_connect_swapped (GTK_OBJECT (dialog), "response",
00483                                                                   G_CALLBACK (gtk_widget_destroy),
00484                                                                   GTK_OBJECT (dialog));
00485                                         gtk_widget_show (dialog);
00486                                 }       
00487                         } else
00488                                 info = g_strdup_printf ("Tp=%.2f ms, dU=%.3f V, dUs=%.2f mV, O*0x%02x S*0x%06x", 
00489                                                         1e3*(double)vp_duration/frq_ref, dU_IV, dU_step*1e3, options, Source
00490                                         );
00491                         if (IV_status){
00492                                 GtkStyle *style;
00493                                 GdkColor ct, cbg;
00494                                 gtk_entry_set_text (GTK_ENTRY (IV_status), info);
00495                                 style = gtk_style_copy (gtk_widget_get_style(IV_status));
00496                                 if (warn_flag){
00497                                         ct.red = 0xffff;
00498                                         ct.green = 0x0;
00499                                         ct.blue = 0x0;
00500                                         cbg.red = 0xffff;
00501                                         cbg.green = 0x9999;
00502                                         cbg.blue = 0xffff;
00503                                 }else{
00504                                         ct.red = 0x0;
00505                                         ct.green = 0x0;
00506                                         ct.blue = 0x0;
00507                                         cbg.red = 0xeeee;
00508                                         cbg.green = 0xdddd;
00509                                         cbg.blue = 0xdddd;
00510                                 }
00511                                 gdk_color_alloc (gtk_widget_get_colormap(IV_status), &ct);
00512                                 gdk_color_alloc (gtk_widget_get_colormap(IV_status), &cbg);
00513                                 style->text[GTK_STATE_NORMAL] = ct;
00514                                 style->bg[GTK_STATE_NORMAL] = cbg;
00515                                 gtk_widget_set_style(IV_status, style);
00516                         }
00517                         g_free (info);
00518                 }
00519 
00520                 break;
00521 
00522 
00523         case PV_MODE_FZ: // ------------ Special Vector Setup for FZ (Force(or what ever!!)-Distance) "Probe ala AFM"
00524                 options      = (FZ_option_flags & FLAG_FB_ON     ? 0      : VP_FEEDBACK_HOLD)
00525                              | (FZ_option_flags & FLAG_INTEGRATE ? VP_AIC_INTEGRATE : 0);
00526                 ramp_sources = FZ_option_flags & FLAG_SHOW_RAMP ? Source : 0x000;
00527 
00528                 // Ramp to initial Z from "current Z"
00529                 make_ZXYramp_vector (FZ_start, 0., 0., -1, FZ_slope_ramp, ramp_sources, options, vp_duration, MAKE_VEC_FLAG_RAMP);
00530                 write_dsp_vector (vector_index++);
00531 
00532                 // Ramp to final Z
00533                 make_ZXYramp_vector (FZ_end - FZ_start, 0., 0., FZ_points, FZ_slope, Source, options, vp_duration, MAKE_VEC_FLAG_NORMAL);
00534                 write_dsp_vector (vector_index++);
00535 
00536                 // add vector for reverse return ramp?
00537                 if (FZ_option_flags & FLAG_DUAL) {
00538                         // Ramp to initil Z
00539                         make_ZXYramp_vector (FZ_start - FZ_end, 0., 0., FZ_points, FZ_slope, Source, options, vp_duration, MAKE_VEC_FLAG_NORMAL);
00540                         write_dsp_vector (vector_index++);
00541 
00542                         // Ramp back to "current Z"
00543                         make_ZXYramp_vector (-FZ_start, 0., 0., -1, FZ_slope_ramp, ramp_sources, options, vp_duration, MAKE_VEC_FLAG_RAMP);
00544                         write_dsp_vector (vector_index++);
00545                 } else {
00546                         // Ramp back to "current Z"
00547                         make_ZXYramp_vector (-FZ_end, 0., 0., -1, FZ_slope_ramp, ramp_sources, options, vp_duration, MAKE_VEC_FLAG_RAMP);
00548                         write_dsp_vector (vector_index++);
00549                 }
00550 
00551                 // Final vector, gives the IVC some time to recover   
00552                 make_delay_vector (FZ_final_delay, ramp_sources, options, vp_duration, MAKE_VEC_FLAG_END);
00553                 write_dsp_vector (vector_index++);
00554 
00555                 append_null_vector (options, vector_index);
00556 
00557                 sranger_hwi_hardware->probe_time_estimate = (int)vp_duration; // used for timeout check
00558 
00559                 {
00560                         gchar *info=NULL;
00561                         if (probe_trigger_raster_points_user > 0 && write_vector_mode != PV_MODE_NONE){
00562                                 double T_probe_cycle   = 1e3 * (double)vp_duration/frq_ref; // Time of full probe cycle in ms
00563                                 double T_raster2raster = 1e3 * gapp->xsm->data.s.rx / (gapp->xsm->data.s.nx/probe_trigger_raster_points_user) / scan_speed_x; // Time inbetween raster points in ms
00564                                 info = g_strdup_printf ("Tp=%.2f ms, Tr=%.2f ms, Td=%.2f ms", T_probe_cycle, T_raster2raster, T_raster2raster - T_probe_cycle);
00565 
00566                                 if (T_raster2raster <= T_probe_cycle){
00567                                         GtkWidget *dialog = gtk_message_dialog_new (NULL,
00568                                                                                     GTK_DIALOG_DESTROY_WITH_PARENT,
00569                                                                                     GTK_MESSAGE_WARNING,
00570                                                                                     GTK_BUTTONS_CLOSE,
00571                                                                                     "The probing a each raster point lasts to long:\n"
00572                                                                                     "T probe cycle is %.2f ms\n"
00573                                                                                     "and\n"
00574                                                                                     "T raster to raster point is %.2f ms.",
00575                                                                                     T_probe_cycle, T_raster2raster
00576                                                                                     );
00577                                         g_signal_connect_swapped (GTK_OBJECT (dialog), "response",
00578                                                                   G_CALLBACK (gtk_widget_destroy),
00579                                                                   GTK_OBJECT (dialog));
00580                                         gtk_widget_show (dialog);
00581                                 }
00582                         } else
00583                                 info = g_strdup_printf ("Tp=%.2f ms", 
00584                                                         1e3*(double)vp_duration/frq_ref
00585                                         );
00586                         if (FZ_status)
00587                                 gtk_entry_set_text (GTK_ENTRY (FZ_status), info);
00588                         g_free (info);
00589                 }
00590 
00591                 break;
00592 
00593 
00594 
00595         case PV_MODE_PL: // ------------ Special Vector Setup for PL (Puls)
00596                 options      = (PL_option_flags & FLAG_FB_ON     ? 0      : VP_FEEDBACK_HOLD)
00597                              | (PL_option_flags & FLAG_INTEGRATE ? VP_AIC_INTEGRATE : 0);
00598                 ramp_sources = PL_option_flags & FLAG_SHOW_RAMP ? Source : 0x000;
00599 
00600                 ramp_points = 10;
00601 
00602                 make_Vdz_vector (bias, bias+PL_volt, 0., ramp_points, PL_slope, Source, options, vp_duration, MAKE_VEC_FLAG_NORMAL);
00603                 write_dsp_vector (vector_index++);
00604 
00605                 make_delay_vector (PL_duration * 1e-3, Source, options, vp_duration, MAKE_VEC_FLAG_NORMAL);
00606                 write_dsp_vector (vector_index++);
00607 
00608                 make_Vdz_vector (bias+PL_volt, bias, 0., ramp_points, PL_slope, Source, options, vp_duration, MAKE_VEC_FLAG_NORMAL);
00609                 write_dsp_vector (vector_index++);
00610                         
00611                 make_delay_vector (PL_final_delay, ramp_sources, options, vp_duration, MAKE_VEC_FLAG_NORMAL);
00612                 dsp_vector.repetitions = PL_repetitions-1;
00613                 dsp_vector.ptr_next = -3; // go to start
00614                 write_dsp_vector (vector_index++);
00615 
00616                 make_delay_vector (PL_final_delay, ramp_sources, options, vp_duration, MAKE_VEC_FLAG_END);
00617                 write_dsp_vector (vector_index++);
00618                 append_null_vector (options, vector_index);
00619 
00620                 sranger_hwi_hardware->probe_time_estimate = (int)vp_duration; // used for timeout check
00621 
00622                 {
00623                         gchar *info=NULL;
00624                         info = g_strdup_printf ("T_total=%.2f ms, O*0x%02x S*0x%06x", 
00625                                                 1e3*(double)vp_duration/frq_ref, options, Source
00626                                 );
00627                         if (PL_status)
00628                                 gtk_entry_set_text (GTK_ENTRY (PL_status), info);
00629                         g_free (info);
00630                 }
00631                 break;
00632 
00633 
00634         case PV_MODE_LM: // ------------ Special Vector Setup for LM (lat manipulation)
00635                 options      = (LM_option_flags & FLAG_FB_ON     ? 0      : VP_FEEDBACK_HOLD)
00636                              | (LM_option_flags & FLAG_INTEGRATE ? VP_AIC_INTEGRATE : 0);
00637                 ramp_sources = LM_option_flags & FLAG_SHOW_RAMP ? Source : 0x000;
00638 
00639                 // Ramp to initial Z from "current Z"
00640                 make_ZXYramp_vector (LM_dz, LM_dx, LM_dy, LM_points, LM_slope, Source, options, vp_duration, MAKE_VEC_FLAG_NORMAL);
00641                 write_dsp_vector (vector_index++);
00642 
00643                 // add vector for reverse return path?
00644                 if (LM_option_flags & FLAG_DUAL) {
00645                         make_ZXYramp_vector (-LM_dz, -LM_dx, -LM_dy, LM_points, LM_slope, Source, options, vp_duration, MAKE_VEC_FLAG_NORMAL);
00646                         write_dsp_vector (vector_index++);
00647                 }
00648 
00649                 make_delay_vector (LM_final_delay, ramp_sources, options, vp_duration, MAKE_VEC_FLAG_END);
00650                 write_dsp_vector (vector_index++);
00651 
00652                 append_null_vector (options, vector_index);
00653 
00654                 sranger_hwi_hardware->probe_time_estimate = (int)vp_duration; // used for timeout check
00655 
00656                 {
00657                         gchar *info = g_strdup_printf ("T=%.2f ms", 1e3*(double)vp_duration/frq_ref);
00658                         if (LM_status)
00659                                 gtk_entry_set_text (GTK_ENTRY (LM_status), info);
00660                         g_free (info);
00661                 }
00662                 break;
00663 
00664         case PV_MODE_AC: // ------------ Special Vector Setup for AC (phase probe)
00665                 options      = (AC_option_flags & FLAG_FB_ON     ? 0      : VP_FEEDBACK_HOLD)
00666                              | (AC_option_flags & FLAG_INTEGRATE ? VP_AIC_INTEGRATE : 0);
00667                 ramp_sources = AC_option_flags & FLAG_SHOW_RAMP ? Source : 0x000;
00668 
00669                 if (AC_option_flags & FLAG_DUAL) {
00670                         make_phase_vector (AC_phase_span, AC_points, AC_phase_slope, Source, options, vp_duration, MAKE_VEC_FLAG_NORMAL);
00671                         write_dsp_vector (vector_index++);
00672 
00673                         make_delay_vector (AC_final_delay, ramp_sources, options, vp_duration, MAKE_VEC_FLAG_NORMAL);
00674                         write_dsp_vector (vector_index++);
00675 
00676                         make_phase_vector (-AC_phase_span, AC_points, AC_phase_slope, Source, options, vp_duration, MAKE_VEC_FLAG_NORMAL);
00677                         write_dsp_vector (vector_index++);
00678 
00679                         make_delay_vector (AC_final_delay, ramp_sources, options, vp_duration, MAKE_VEC_FLAG_NORMAL);
00680                         dsp_vector.repetitions = AC_repetitions-1;
00681                         dsp_vector.ptr_next = -3; // go to start
00682                         write_dsp_vector (vector_index++);
00683                 } else {
00684                         make_phase_vector (AC_phase_span, AC_points, AC_phase_slope, Source, options, vp_duration, MAKE_VEC_FLAG_NORMAL);
00685                         write_dsp_vector (vector_index++);
00686 
00687                         make_delay_vector (AC_final_delay, ramp_sources, options, vp_duration, MAKE_VEC_FLAG_NORMAL);
00688                         dsp_vector.repetitions = AC_repetitions-1;
00689                         dsp_vector.ptr_next = -1; // go to start
00690                         write_dsp_vector (vector_index++);
00691                 }
00692 
00693                 make_delay_vector (AC_final_delay, ramp_sources, options, vp_duration, MAKE_VEC_FLAG_END);
00694                 write_dsp_vector (vector_index++);
00695                 append_null_vector (options, vector_index);
00696 
00697                 sranger_hwi_hardware->probe_time_estimate = (int)vp_duration; // used for timeout check
00698 
00699                 {
00700                         gchar *info=NULL;
00701                         info = g_strdup_printf ("T_total=%.2f ms, O*0x%02x S*0x%06x", 
00702                                                 1e3*(double)vp_duration/frq_ref, options, Source
00703                                 );
00704                         if (AC_status)
00705                                 gtk_entry_set_text (GTK_ENTRY (AC_status), info);
00706                         g_free (info);
00707                 }
00708                 break;
00709         }
00710 
00711         if (start)
00712                 std::cout << "Exec Probe Now!!" << std::endl;
00713 
00714         // --------------------------------------------------
00715 
00716         // now write probe structure, this may starts probe if "start" is true
00717 
00718         // update all from DSP
00719         lseek (sranger_hwi_hardware->dsp, sranger_hwi_hardware->magic_data.probe, SRANGER_SEEK_DATA_SPACE);
00720         read  (sranger_hwi_hardware->dsp, &dsp_probe, sizeof (dsp_probe)); 
00721         // from DSP to PC
00722         conv_dsp_probe ();
00723         
00724         // update with changed user parameters
00725         dsp_probe.start = start ? 1:0;
00726         dsp_probe.AC_amp = VOLT2AIC (AC_amp);
00727         dsp_probe.AC_frq = (int) (AC_frq);
00728         dsp_probe.AC_phaseA = (int)round(AC_phaseA*16.);
00729         dsp_probe.AC_phaseB = (int)round(AC_phaseB*16.);
00730         dsp_probe.AC_nAve = AC_lockin_avg_cycels;
00731         dsp_probe.Zpos = 0;
00732 
00733         // from PC to DSP
00734         conv_dsp_probe ();
00735         lseek (sranger_hwi_hardware->dsp, sranger_hwi_hardware->magic_data.probe, SRANGER_SEEK_DATA_SPACE);
00736         write  (sranger_hwi_hardware->dsp, &dsp_probe,  MAX_WRITE_PROBE<<1); 
00737         // from DSP to PC
00738         conv_dsp_probe ();
00739 
00740         // read back
00741         read_dsp_probe ();
00742         // Update EC's
00743         update();
00744 }
00745 
00746 void DSPControl::conv_dsp_vector (){
00747         CONV_32 (dsp_vector.n);
00748         CONV_32 (dsp_vector.dnx);  
00749         CONV_32 (dsp_vector.srcs);
00750         CONV_32 (dsp_vector.options);
00751         CONV_16 (dsp_vector.ptr_fb);
00752         CONV_16 (dsp_vector.repetitions);
00753         CONV_16 (dsp_vector.i);
00754         CONV_16 (dsp_vector.j);
00755         CONV_16 (dsp_vector.ptr_next);
00756         CONV_16 (dsp_vector.ptr_final);
00757         CONV_32 (dsp_vector.f_du);
00758         CONV_32 (dsp_vector.f_dx);
00759         CONV_32 (dsp_vector.f_dy);
00760         CONV_32 (dsp_vector.f_dz);
00761         CONV_32 (dsp_vector.f_dx0);
00762         CONV_32 (dsp_vector.f_dy0);
00763         CONV_32 (dsp_vector.f_dphi);
00764 }
00765 
00766 void DSPControl::write_dsp_vector (int index){
00767         if (!sranger_hwi_hardware) return; 
00768 
00769         // update all from DSP
00770         lseek (sranger_hwi_hardware->dsp, sranger_hwi_hardware->magic_data.probe, SRANGER_SEEK_DATA_SPACE);
00771         read  (sranger_hwi_hardware->dsp, &dsp_probe, sizeof (dsp_probe)); 
00772         // from DSP to PC
00773         conv_dsp_probe ();
00774 
00775         if (dsp_probe.vector_head < EXTERN_PROBE_VECTOR_HEAD_DEFAULT || index > 40 || index < 0){
00776                 sranger_hwi_pi.app->message("Error writing Probe Vector:\n Bad vector address, aborting request.");
00777                 return;
00778         }
00779 
00780         // setup VPC essentials
00781         dsp_vector.i = dsp_vector.repetitions; // preload repetitions counter now! (if now already done)
00782         dsp_vector.j = 0; // not yet used -- XXXX
00783 
00784         // update GXSM's internal copy of vector list
00785         dsp_vector_list[index].n = dsp_vector.n;
00786         dsp_vector_list[index].dnx = dsp_vector.dnx;
00787         dsp_vector_list[index].srcs = dsp_vector.srcs;
00788         dsp_vector_list[index].options = dsp_vector.options;
00789         dsp_vector_list[index].ptr_fb = dsp_vector.ptr_fb;
00790         dsp_vector_list[index].repetitions = dsp_vector.repetitions;
00791         dsp_vector_list[index].i = dsp_vector.i;
00792         dsp_vector_list[index].j = dsp_vector.j;
00793         dsp_vector_list[index].ptr_next = dsp_vector.ptr_next;
00794         dsp_vector_list[index].ptr_final = dsp_vector.ptr_final;
00795         dsp_vector_list[index].f_du = dsp_vector.f_du;
00796         dsp_vector_list[index].f_dx = dsp_vector.f_dx;
00797         dsp_vector_list[index].f_dy = dsp_vector.f_dy;
00798         dsp_vector_list[index].f_dz = dsp_vector.f_dz;
00799         dsp_vector_list[index].f_dx0 = dsp_vector.f_dx0;
00800         dsp_vector_list[index].f_dy0 = dsp_vector.f_dy0;
00801         dsp_vector_list[index].f_dphi = dsp_vector.f_dphi;
00802 
00803         // from PC to to DSP format
00804         conv_dsp_vector();
00805         lseek (sranger_hwi_hardware->dsp, dsp_probe.vector_head + index*SIZE_OF_PROBE_VECTOR, SRANGER_SEEK_DATA_SPACE);
00806         write  (sranger_hwi_hardware->dsp, &dsp_vector, SIZE_OF_PROBE_VECTOR<<1);
00807 
00808         // from DSP to PC
00809         conv_dsp_vector();
00810 }
00811 
00812 void DSPControl::read_dsp_vector (int index){
00813         if (!sranger_hwi_hardware) return; 
00814 
00815         // update all from DSP
00816         lseek (sranger_hwi_hardware->dsp, sranger_hwi_hardware->magic_data.probe, SRANGER_SEEK_DATA_SPACE);
00817         read  (sranger_hwi_hardware->dsp, &dsp_probe, sizeof (dsp_probe)); 
00818         // from DSP to PC
00819         conv_dsp_probe ();
00820 
00821         if (dsp_probe.vector_head < EXTERN_PROBE_VECTOR_HEAD_DEFAULT || index > 40 || index < 0){
00822                 sranger_hwi_pi.app->message("Error reading Probe Vector:\n Bad vector address, aborting request.");
00823                 return;
00824         }
00825 
00826         lseek (sranger_hwi_hardware->dsp, dsp_probe.vector_head + index*SIZE_OF_PROBE_VECTOR, SRANGER_SEEK_DATA_SPACE);
00827         read  (sranger_hwi_hardware->dsp, &dsp_vector, SIZE_OF_PROBE_VECTOR<<1);
00828 
00829         // from DSP to PC
00830         conv_dsp_vector();
00831 }
00832 
00833 

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