next up previous contents
Next: About this document ... Up: Gxsm and Xxsm User/Referenz Previous: AFM-HOWTO (allgemein)   Contents

Subsections


Internals: Xxsm and Gxsm Hacker Guide

Software Requirements

Xxsm and its descendant Gxsm were developed using ``Debian/GNU Linux 2.2''. Though all included software should be portable to any fairly recent distribution.

Compiler

For compilation any ANSI C++ Compiler should be vaild. Program development was done using the GNU C++ compiler, Gnome, the GTK+ toolset together with the Helixcode (now Ximian)-extensions (see http://www.ximian.com) in the following versions.

g++ -version
2.95.2

gtk-config -version
1.2.8

gnome-config -version
gnome-libs 1.2.8

If you use Debian, too, you may use this entry in your /etc/apt/sources.list to obtain the necessary development packages:

deb http://spidermonkey.helixcode.com/distributions/debian unstable main

Libraries

The old and old-fashioned Xxsm version uses the following libraries:

libX11 (tested with version 6.1 XFree86), libXext (tested with version 6.3 XFree86) and the ANSI C math-libraries libm (tested with version 5.0.9). Both common C-libraries libc5 and libc6 (glibc2) can be used. So far no special libc6 functions are used.

The graphical user interface uses the XForms-library in version 0.88. For creation of the interface is done with the accompanied form designer 'fdesign'.

Gxsm needs the complete Gnome/Gtk+ development packages. Right now (2001) we are using the Helixcode/Ximian-Gnome-development-packages.

With Xxsm a new dataformat was introduced, known as NetCDF. As a consequence, we need its libraries newer or equal to version 3.4 (libnetcdf and libnetcdf_c++ for the C++-frontend). Documentation can be found at http://unidata.ucar.edu /packages/netcdf/index.html.

Math routines, which use Fourier transforms, additionally neet the fftw-libraries libfftw and librfftw (>=2.0). These routines provide algorithms for the fast calculation of complex and real Fourier-transforms. Xxsm can be compiled with fftw-support disabled. If you compile without the preprocessor directive HAS_LIBFFTW, all functions using fftws functions will not be executed. More documentation about fftw can be found at http://theory.lcs.mit.edu/~ fftw/.

\fbox{Hint: All development-packages and sources for successful Gxsm-compilation
are available as Debian-packages!}

The so called rem Remote-Control-Option (see below) needs the the PThread Libary (Linux-threads) for background tasks; Debian has this packed with the standard C-libraries.

For control of external devices which have a GPIB-bus (IEEE-488) the libgpib Libary (linux-GPIB) is needed (Xspa, goszi):

Title = The Linux GPIB-Package
Version = 2.02
Desc1 = Driver Module for National Instruments GPIB (IEEE488) boards,
Desc2 = pcIIa (alpha), and HP82335 HPIB boards, C-Interface library,
Desc3 = Tcl/Tk frontend.
Author = Claus Schroeter
AuthorEmail = clausi@chemie.fu-berlin.de
Maintainer = Claus Schroeter
MaintEmail = clausi@chemie.fu-berlin.de
Site1 = ftp.llp.fu-berlin.de

(Hint: Not yet available for 2.2.X kernel!? Please check.)

For three dimensional display the OpenGL library, resp. its free clone MesaGL is used. This is also part of the standard Debian distribution.

Internal structure of Gxsm/Xxsm

Several objects are defined globally, you can access them from any part of the program. Those objects are defined in glbvars.h.

XSM_Instrument class

The XSM_Instrument class provides some instrument-specific functions.

There is only one object of this class (XSM_Intrument *Inst, see glbvars.h) which can be accessed globally.

The main purpose of XSM_Instrument is the definition of unit conversion from internal units to SI-units. Examples are conversion from digital to Ångstrom (fct. double Dig2XA(long dig)) or vice versa (fct. double XA2Dig(double ang)). Another task is the calculation of D/A-resolutions (fct. double XResolution()).

Gxsm Klassenhirarchie

handy Application Base Class and Tools
gapp_service.h: class MyGnomeTools    
gapp_service.h: class AppBase : public MyGnomeTools
gapp_service.h: class DlgBase : public MyGnomeTools
gapp_service.h: class GnomeAppService : public AppBase
Main Internal Class and derivation
xsm.h: class Xsm    
surface.h: class Surface : public Xsm
Instrument properties, holded by main object
instrument.h: class XSM_Instrument    
instrument.h: class STM_Instrument : public XSM_Instrument
instrument.h: class AFM_Instrument : public XSM_Instrument
instrument.h: class SPALEED_Instrument : public XSM_Instrument
Strucured Data Classes
xsmtypes.h: class XsmRescourceManager    
xsmtypes.h: class Display_Param    
xsmtypes.h: class Scan_UserInfo    
xsmtypes.h: class SCAN_DATA    
xsmtypes.h: class MkIconsData    
xsmtypes.h: class PrintPSData    
Main Scan Object and specializings
scan.h: class Scan    
scan.h: class TopoGraphicScan : public Scan
scan.h: class SpaScan : public Scan

Main Application Object, holds ``surface'' object
gxsm_app.h: class App : public GnomeAppService
sub GUI Objects, holded by App
gxsm_app.h: class ChannelSelector : public AppBase
gxsm_app.h: class SpaLeedControl : public AppBase
gxsm_app.h: class DSPControl : public AppBase
gxsm_app.h: class GrOffsetControl : public AppBase
gxsm_app.h: class MoverControl : public AppBase
gxsm_app.h: class DriftControl : public AppBase
gxsm_app.h: class MonitorControl : public AppBase, Monitor
gxsm_app.h: class HistogrammControl : public AppBase
gxsm_app.h: class OptiControl : public AppBase
gxsm_app.h: class OsziControl : public AppBase
app_mkicons.h: class MkIconsControl : public DlgBase
app_print.h: class PrintControl : public DlgBase
app_profile.h: class ProfileElement    
app_profile.h: class ProfileControl : public AppBase, LineProfile1D
app_remote.h: class RemoteControl : public DlgBase, public remote_crtl
app_view.h: class ViewControl : public AppBase
app_vobj.h: class ViewInfo    
app_vobj.h: class VObject    
app_vobj.h: class VObPoint : public VObject
app_vobj.h: class VObLine : public VObject
app_vobj.h: class VObParabel : public VObject
app_vobj.h: class VObRectangle : public VObject
app_vobj.h: class VObCircle : public VObject

File IO
dataio.h: class Dataio    
dataio.h: class DatFile : public Dataio
dataio.h: class GnuFile : public Dataio
dataio.h: class NetCDF : public Dataio
dataio.h: class PsiHDF : public Dataio
dataio.h: class DumpableNcFile : public NcFile
epsfutils.h: class EpsfTools    
epsfutils.h: class SPM_epsftools : public EpsfTools
epsfutils.h: class SPA_epsftools : public EpsfTools
Units and Input management
unit.h: class UnitObj    
unit.h: class LinUnit : public UnitObj
unit.h: class BZUnit : public UnitObj
unit.h: class SUnit : public UnitObj
unit.h: class CPSCNTUnit : public UnitObj
pcs.h: class Param_Control    
pcs.h: class Gtk_EntryControl : public Param_Control
Math
regress.h: class Zeile    
regress.h: class LGSys    
regress.h: class StatInp    
bench.h: class bench    
xsmmath.h: plain C all filters    
xsmmath.h: class Filter    
xsmmath.h: class F2D_Conv3x3 : public Filter
xsmmath.h: class F2D_HistoHOP : public Filter
lineprofile.h: class LineProfile1D    
histogramm.h: class Histogramm   in progess

Event Logging
monitor.h: class Monitor    
2D Memory Management
mem2d.h: class LineInfo    
mem2d.h: class ZData    
mem2d.h: template $<$class ZTYP$>$ class TZData : public ZData
mem2d.h: class Mem2d    
mem2d.h: class MemDigiFilter : public Mem2d
mem2d.h: class MemSmoothKrn : public MemDigiFilter
mem2d.h: class MemLclhtKrn : public MemDigiFilter
mem2d.h: class MemDeriveXKrn : public MemDigiFilter
mem2d.h: class MemCurvatureKrn : public MemDigiFilter
mem2d.h: class MemTderiveKrn : public MemDigiFilter
Remote Control
remote.h: class remote    
remote.h: class remote_crtl : public remote
Data Representation/non GUI
view.h: class View    
view.h: class Grey2D : public View
view.h: class Profiles : public View
view.h: class Surf3d : public View
xshmimg.h: class ShmImage2D    
Hardware Abstractation
xsmhard.h: class XSM_Hardware    
xsmhard.h: class dspobj : public XSM_Hardware
xsmhard.h: class dspdev : public XSM_Hardware
xsmhard.h: class dspspm : public dspdev
xsmhard.h: class dspspa : public dspdev
xsmhard.h: class ccdobj : public XSM_Hardware

2D data management

General Information

With the extension of the data aquisition for SPA-LEED and the demand for more universal 2D data management the need for more datatypes than 16bit-short arised.

To meet this, a class-structure (see mem2d.h) was created which offers:

Details of several classes

The class LineInfo stores and managed the line regression data cache.

class ZData $\rightarrow$ class TZData[Typ] uses the template class TZdata to provides the type independet data handling used by the Mem2d class, which is used externally to hold the 2D data.

Description of classes

Class LineInfo

Storage of statistical information on every line. (Offset and gradient for line regression: $Y=ax+b$)

Class ZData

Base class, with only virtuel members.

Members:

constructor: ZData(int Nx=1, int Ny=1)

int GetNx() returns number of points in X.

int GetNy() returns number of points in Y.

size_t Zsize() returns the size of the elements: sizeof(element-TYPE)

double Z(int x, int y) returns the value at position (x,y).

double Z(double z, int x, int y) sets the value at position (x,y) and returns it.

void Zadd(double z, int x, int y) adds z to the value at position (x,y).

void Zmul(double z, int x, int y) multiplies with z.

void Zdiv(double z, int x, int y) divides by z.

int Resize(int Nx, int Ny) (???)

void ZPutDataLine(int y, void *src) copies an array of data from src to line y (Warning: care for the datatype!).

void ZPutDataLine(int y, void *src, int mode)

void ZGetDataLine(int y, void *dest) copies a line of data from y to src (Warning: care for the datatype!).

efficient Datamanipulation:

void SetPtr(int x, int y) Set internal pointer to position (x,y). Warning: there is no range check!, increasing x++ may never cross the border of the set!

double GetNext() Returns the value of the internal position, then the pointer jumps to the next datapoint (x++).

double GetThis(double x=0.) Returns the internal position.

long GetThis(long x), unsigned long GetThis(unsigned long x), SHT GetThis(SHT x), unsigned char GetThis(unsigned char x) for special (internal) use.

Hint: Neighbouring points can be addressed! See also mem2d.h.

void SetNext(double z) Sets the value at the current position to z, then moves on (x++).

int CopyFrom(ZData *src, int x, int y, int tox, int toy, int nx, int ny=1) Copies data from source *src to itself in a rectangular fashion. (x,y) is the upper left corner, (nx,ny) is the size, (tox,toy) is the upper left of the target position.

void* GetPtr(int x, int y) Warning: Not for external use!

Overloaded Operators: Warning: All following operations are related to the current position pointer (x,y).

void operator = (ZData &rhs)

void operator += (ZData &rhs)

void operator -= (ZData &rhs)

void operator *= (ZData &rhs)

void operator /= (ZData &rhs)

void operator ++ () increase internal position x++

void operator - () decrease internal position x-

double operator [] (int idx) returns value of (internal x-position + idx).

Warning: the resulting index must be valid!

Class TZData : public ZData

template class, derived from ZData. See ZData !

Class Mem2d

Control class, keeps an instance of class ZData[currentType].

Constructors:

Mem2d(int Nx, int Ny, ZD_TYPE type=ZD_SHORT)

Mem2d(Mem2d *m, MEM2D_CREATE_MODE Option=M2D_ZERO)

size_t GetEsz() Returns size of element (sizeof(\dots)).

ZD_TYPE     GetTyp() Returns type of element (see enum ZD_TYPE).

const char* GetEname() Returns name of element as string.

int GetNx(), int GetNy() Returns the Arraysize.

void Modus(int mod) See Ablagemode (*)???

int  Resize(int Nx, int Ny, ZD_TYPE type=ZD_IDENT)

void PutDataLine(int y, void *src)

int CopyFrom(Mem2d *src, int x, int y, int tox, int toy, int nx, int ny=1)

int ConvertFrom(Mem2d *src, int x, int y, int tox, int toy, int nx, int ny=1){

void PutDataLine(int y, void *src, int mode)

void   GetDataLine(int y, void *dest)

double GetDataPkt(int x, int y)

void   PutDataPkt(double value, int x, int y)

double GetDataPktInterpol(double x, double y)

double GetDataPktLineReg(int x, int y)

double GetDataPktHorizont(int x, int y)

ZVIEW_TYPE GetDataVMode(int x, int y) Value in displaymode.

double GetDataMode(int x, int y) Value in datamode.

ZVIEW_TYPE ZQuick(int &x, int &y), ZDirect(\dots), ZLog(\dots), ZPeriodic(\dots),
ZHorizontal(\dots) Functions for display.

void SetDataPktMode(int mode)
See Displaymode.

void SetDataRange(ZVIEW_TYPE Min, ZVIEW_TYPE Max) 
Set area of valid display.

void SetDataSkl(double contrast, double bright) 
Sets display parameters.

void AutoDataSkl(double *contrast, double *bright) 
Calculates displayparameters from min and max.

void CalcLinRegress(int yfirst, int ylast)

int  GetDataLineFrom(Point2D *start, Point2D *end, Mem2d *Mob, SCAN_DATA *ScDat)

void HiLoMod(Point2D *p1=NULL, Point2D *p2=NULL, int Delta=4)

void HiLo(double *hi, double *lo, int LinReg=FALSE, Point2D *p1=0, Point2D *p2=0)

void DataRead(ifstream &f)

void DataD2DRead(ifstream &f, double gate)

void DataWrite(ofstream &f)

int  DataValid()

int  SetDataValid()

Objects: rectangles, circles, etc.

The Gxsm user can mark arbitrary areas within 2D views using objects such as rectangles, circles, and lines. These objects can be accessed from the Gxsm core or plug-ins using the interface classes/methods described below.

To get the number of objects attached to a Scan object use the memberfunction unsigned int number_of_object () of the Scan class. Scan also provides the function scan_object_data* get_object_data (int i) to get the i-th object represented by the class scan_object_data.

The scan_object_data class is defined in scan.h. It offers several member functions to access the represented objects. Only the most important are described below:
gchar* scan_object_data::*get_name () returns the type/name of the object. int scan_object_data::get_num_points () returns the number of points the object is containing. For instance, rectangles are represented by two corner points. The coordinates $x,y$ of the point $i$ can be retrieved by void scan_object_data::get_xy (int i, double &x, double &y).
The coordinates used here are in ``real world'' units, i.e. in Å and inclusive scan offsets.

For further details, see scan.h and scan.C of the Gxsm core source-code. An application example can be found in the spectrocut plug-in source-code.

Data Input and Output

In- and Output of aquired data is implemented in dataio.C. The interface is defined by the baseclass dataio (see dataio.h).


Files in dat-format

The ancient dat-format from PMSTM (or even older?) was replaced by the more flexible and easier extendable NetCDF-format (see [*]). The input and output of the old format is defined in datio.C

The dat-format consists of a header which contains for example the scansize and the data. The body follows without further introduction after the header and contains the information on every datapoint as 16 value line by line. There exist three different versions of dat-files, which can be distinguished by their header-ids (see DatFILE::Read() in datio.C). Die different headers have the same length, so that the body of data always begins at the same place.


``GNU'' Files

The in- and output of ``GNU''-files is implemented in the GnuFile class in datio.C. The files of this group are listed in table ([*])


Table: ``GNU''-formats
ID description
d2d D2D format from SPA-LEED program
byt byte format: raw 8 Bit data
sht Short format: raw 16 Bit data
flt Float format: floats, single precision
dbl Double format: floats, double precision
pgm Portable Greymap (P5) format
tga TARGA bitmap format (8, 16 and 24 Bit colordepth)


As time of this writing only the d2d-format was importable (???), all other formats (except d2d which is read-only) can be exported.


NetCDF Files

To reach better portability and extensibility on 3.8.1998 the NetCDF-file format was introduced into the project. (See http://unidata.ucar.edu/packages/netcdf) All needed routines for handling NetCDF-files are stored in dataio.C. NetCDF is the default data-format for storage of data collected with Gxsm.

To pervent the loss of the primary filename of your data (through renaming) the original filename is stored within the NetCDF file since dataio.C v. 1.24 with the name 'basename'. The variable 'basename' is declared in the class SCAN_DATA in xsmtypes.h On start-up basename is set to 'unknown' (???) (this happens in function Surface::DoScan() in Surface.C). Upon your first save this variable is set to the given filename and no more changed. If Gxsm reads a file without basename information it is set to ``No basename information available.'' (See NetCDF::read() in dataio.C)


PSI HDF Files

Our institue has access to a Park Scientific Instruments (PSI) Atomic Force Microscope. [*] This leads to the need for import-ability of Gxsm for the data format used by this device. The PSI/AFM data format is compatible to NCSA HDF 3.3 format for which development libraries are freely available. (See ???)

Implementation of the PSI HDF in Xxsm was difficult because of the following obstacles:

  1. The NCSA HDF lib includes parts of the NetCDF (see [*]) format. Compatibility is compromised.
  2. PSI used a format which is basically HDF compatible but contains several hooks: Several ``TAGs'' were redefined, so that generic read functions from the HDF libraries do not work correctly.
For this reason, PSI HDF files are read directly without interference of the accompagnied librariy. This is accomplished through the ``dump'' of data into the PsiHEADER data structure, as defined in psihdf.h. The implementation can be found in dataio.C and dataio.h.

The current (???) implementation of the PsiHDF class of course depends on the version of the software used for writing the files and is tested only with version 1.1

Autosave

The Autosave-feature[*] used the internal counter counter for automatically naming the files in AUTOSAVE_MODE.

To allow the automatic naming of backup (intermediate) scans a second counter subcounter was defined (see xsm.h, xsm.C).

In xsmtype.h the gchar *AutosaveUnit and gchar *AutosaveOverwritemode and gint AutosaveValue were added.

The most interesting parts happen in surface.C.

At the beginning of a scan (Surface::DoScan) the nextAutosaveEvent is set to AutosaveValue. During the scan, the runtime conditions of seconds, percentage or lines are checked. If the appropriate variable overtook the nextAutosaveEvent, the file is saved with the special parameter '2' and with overwrite permissions set or unset, depending on AutosaveOverwritemode. In Surface::save we read, that 'autoon == 2' is the identifier for autoscans. Here the additional naming strings are attached and the counters are increased (if counter is increased, subcounter is set to zero).

Note: Almost all changes done for this new autosave modes can be found when grepping for 'utosave'.


Defaultvalues for parameters

Several parameters have to be adjusted for correct performance of an instrument (e.g. scansize). To simplify software-setup default Xxsm can store values for many parameters in .xsmvalues in the users home-directory which will be read and set on program launch.

Gxsm saves all parameters using a ``recource manager'' in the ``/.gnome/gxsm'' file. Have a look at it.


Defaultvalues at programm statup (Xxsm only)

When Xxsm starts, the function Xsm::loaddefaults() is executed (see xsm_main.C). Default parameters can be inserted and added there, preferably at the end.


Storing defaultvalues in .xsmvalues (Xxsm only)

Individual parameter-sets are stored in .xsmvalues in your home-directory. Those are determined after static default values are assigned to all parameters (see Xsm::loaddefaults()) to prevent an uncertain state if .xsmvalues is missing. Reading and writing of these parameters s implemented in Xsm::loadvalues() and Xsm::savevalues() in xsm_main.C.

The fileformat for .xsmvalues is straightforward. Key-Values pairs are dupmped commentless into the file. For correct rereading the succession is important. This implies, that new parameters have to be added at the end of the file.

Warning: There is no error detection. Wrong insertions in this file may leave Xxsm in an undefined state.

Inserting a new dialog (Xxsm only)

This section describes how a new dialog can be introduced to Xxsm after being designed with fdesign.

The arguments of the individual forms of the dialog must be inserted in actionid.h. The obligate use of the enum structure ensures the correct assignment of values to arguments.

The dialog must be inserted in xsm_main.h with an entry of the form FD_<name of dialog in fdesign> and a second entry with FD_<name of fialogs in fdesign>Cpy.

The dialogs is created with a constructor in xsm_main.C. The memory allocated for the copy Cpy must be freed in the destructor.

The dialog is now inserted into the program but has no functionality. To add this, a callback function must be inserted in xsm_cb.C. The name of the function must be equal to that used in fdesign. To open and close the dialog at appropriate places the xforms functions fl_show_form() and fl_hide_form() are used. (Examples see xsm_menu_cb.C) Alternatively use the macros FL_SHOW_FORM() and FL_HIDE_FORM() if a definit placement is recommended.


Add X Resources (Xxsm only)

X resources (see XSm.ad and .Xdefaults) provide a convinient method for configuration of Xxsm. This section describes how to add a new resource.

First of all, the new resource has to be created in xsmtypes.h. Simply add it into the XSMRESOURCES struct.

Next, the resource must be prepared. Insert the resource in xsm_main.C in xsm_res_def. Every resource is defined with five parameters.

  1. The name, as it is entered in X resource database. (See XSm.ad.)
  2. The class name (unused?).
  3. The datatype of the resource (int, float or string).
  4. A pointer to the variable carrying the value.
  5. A default value.

Just in front of xsm_res_def the preprocessing constant XRES_COUNT must be set to the number of resources.

The resources may be set using command line options. To make use of this functionality, an entry has to be added to xsm_cmd_opts. Like in xsm_res_def the maximum number of command line parameters must be set in CMD_COUNT.

DSP-Card PC31 and PCI32 - TMS320

Kernel Module for PC31 and PCI32

Hint: The device information is valid for versions using kernel 2.2, the newer versions use the new devfs!

[XG]xsm and the DSP tools use the device /dev/pcdsp (???) for communication with the signal processor. A kernel module was developed to handle this communication.

Depending on the available card the appropriate modules pc31.o or pci32 are inserted into the running kernel using insmod. This can be done at system startup (place a simple script in /etc/re.boot for Debian systems). The root user may insert the module at any time if you don't like this. check correct insertion with lsmod. Remove the module with rmmod pc31 or rmmod pci32 respectivly.

If the device /dev/pcdsp does not exist the insmod will fail. Root has to create the device with

``mknod -m 666 /dev/pcdsp c 127 0''

A very quick intro 'how it works' by PZ

The PC31/PCI32 DSP maschine is booted in some multistep way:

  1. the kernelmodule should be loaded by "insmod pc31 or pci32" have a look at /var/log/messages ! $\longrightarrow$ now /dev/pcdsp should be aktive
  2. the program "loadpci" starts and openes /dev/pcdsp
  3. a small loader is transfered to the dsp and started (some differencies PC31/PCI32 !!)
  4. the xafm.out (COFF-File) is interpreted and uploaded section by section using the loader
  5. the loaded program is launched via reset / jump
  6. now DSP bootes up via int_00
    $\longrightarrow$ look at $\longrightarrow$ "boot.asm" (boot31/32.lib) for _c_int_00 [pci32/dspC32/periph31/rts/]
  7. some initialisations, call _ii_init, call _main, call _exit (ii_bo31.c/ii_boot.c)
  8. if main() returns _exit is called. - bye

xafm.c

After uploading and starting ``xafm.out'' we are here in _main() after exec of ii_init() !

1. Setup Hardware

2. install Interrupt

3. start main dsploop

...that's it - easy ? :=)

OLD: DSP-Kommunikation

stmdspos.c

Compile with the special DSP compiler. It initializes the hardware and sets interrupt 09, then enters the infininite loop 'dsploop'. The feedback is controled by an interrupt routine 'c_int09()'. The control frequency depends on the timer 0 and must leave enough processing time for the main 'dsploop'.

The gouverning variable is 'STMMode'. It contains a bitcode, which determines the current processing mode of the STM system.

All constants MD_XXX are bitmasks for these modes. If a bit is set the according mode is active.

Example: if(STMMode & MD_CMD) printf(''Modus CMD ist aktiv'');
This variable is instantanously mapped to port PIA_A and can be used for status control with a number of leds. That way a full control of the program flow can be obtained.

MD_CMD:
Command evaluation mode, the SRQ-register is read and the given command evaluated.
MD_PID:
Feed-Back-Control runs.
MD_MOVE:
A MoveTo(Xnew, Ynew) is executed.
MD_SCAN:
Linescan is exectued.
MD_BLK:
Blinking of blinker, for administrative program control.
MD_TIPDN:
Automatic/manual tip approach.
MD_ITU:
Tunnel current detected.
MD_CRASH:
Tunnelcurrent cannot be driven to desired value. The current is higher than the desired values: risk of tip crash!

The single modes interact, e.g. the start of a linescan disables MD_CMD, the end reenables it.

A quick calculation of the logarithm is vital for the tip control, because of the exponential dependency between distance and tunnel current. Math-libraries log function is to slow, so a replacement 'MyLog()' using a table and linear approximation is used.

dspcom.c (old non Objective Version - similar)

Provides service functions DSP $\leftrightarrow$ PC. Additional dialog procedures (for DSP-menu) implemented.

struct DspParam
Mirrors all important parameters, which are used for the DSP program.
PC31memput(Adr, Dlow, Dhigh)
Transmit 32-bit data (2*16bit Dlow, Dhigh) to the dsp memory beginning with adresse Adr.
PC31Fmemput(Adr, Value)
Transmit a float to the dsp memory. A special format is used (32 bit).
PC31memget(Adr, *Dlow, *Dhigh)
Transmit 32-bit data (2*16bit Dlow, Dhigh) from the dsp memory beginning with adress Adr to the PC.
PC31reset()
Reset for PC31.
int PC31acked()
True, if DSP completed last command. (PC31 acknowledged)
int PC31sqred()
True, if DSP sent a request to the PC. (PC31 Service Request to PC)
PC31srq(value)
value = 1
Commandrequest to DSP. (Post Service Request to PC31)
value = 2
Simulated DSP request at PC. (not used)
PC31ack()
Answer to DSP request. (acknowledges a PC31 service request.
i.e. says to PC31 that service has been completed)
WaitDSPacked()
Wait until completion of DSP's last command.

If no is DSP available or the DSP program is not running the request is terminated after DSP_TIMEOUT seconds (20s).

Hint: During scan have some patience if response is not immediate. Long timeouts are necessary, because lengthy linescans may not be interrupted with DSP commands.

WaitDSPsrqed()
Waits for DSP message to PC (not used).

DSP_SetWerte()
Transmit all control parameters on DSP.

DSP_SetLogWerte()
Transmit parameters for the logarithmic control characteristic to the DSP.

DSP_SetRotParam()
Transmit parameter for image rotation.
(???) ToDo: Move-Offset PM-Programm und Rotationsoffset im DSP-Programm sinnvoll einsetzten. (jetzt: Drehung um Ursprung bezogen auf U_X/Y , nicht um Bildmitte !)

DSP_SetMoveParam()
Transmit the dynamic parameters for Moveto-movements.

DSP_SetLineScanParam()
Transmit the dynamik parameters for Linescan-movements and data collection.

DSP_SetLSP(nx, dx)
Set Linescanlength (nx) and dotdistance (dx). Calls DSP_SetLineScanParam().

DSP_SetAppWerte()
Set parameters for tip approach mechanism.

LoadDSPParameter()
Load DSP parameter set from file.

SaveDSPParameter()
Save DSP parameter set to file.

DSP_Par_DlgProc(...)
Dialogbox control function for generic parameters
(Control, Log., Move, Scan)

DSP_Cmd_DlgProc(...)
Dialogbox Control function for DSP commands.

DSP_APPParam_DlgProc(...)
Dialogbox control function for tip approach parameters.
(Control, Log., Move, Scan)

Wirings - Quantum

 *
 *      Hardware Connections:
 *
 *      Digital IO      82C55
 *      ===================================================================
 *   *) PIA_A: Status (Variable == STMMode)     (IOPA0..7)
 *      Bit     0       1       2       3       4       5       6       7
 *      MD_...  CMD     PID     MOVE    SCAN    Blink   TIPDN   ITU     CRASH
 *      Description at #define MD_XXXX
 *      For Display with LED's, using driver-circuit ULN2003 o...
 *
 *   *) PIA_B:  Controlbox, release of X,Y,Z +/-, speed (IOPB0..7)
 *      Bit     0       1       2       3       4       5       6       7
 *              X+      X-      Y+      Y-      Z-      Z+      R1      R2
 *      release of R1,R2: fixed resistors for (???) Raupen-Schrittweite,
 *      sonst Potiwert
 *
 *   *) PIA_C:  Diverses        (IOPC0..7)
 *      Bit     0       1       2       3       4       5       6       7
 *              Test    Test    Gate    Oszi-   -       -       -       -
 *                              Trigger Trigger
 *                                      for approach control
 *      Analog IO
 *      ===================================================================
 *      DA0:    Z-Piezo (control variable)
 *      DA1:    tunnel current          (bauer BNC plugin (Omicrom))
 *      DA2:    X-Piezo
 *      DA3:    Y-Piezo
 *      AD0:    tunnel current (control variable)  (red BNC Stecker (Omicron))
 *


Plug-in interface

How it works

PlugIns are ``on the fly'' loadable add on libs, simply using the shared object libary format. But there is a special design, which allows Gxsm to make automatically use of there libs. Gxsm doese not know of the lib itself, but it first searches at predefined locations for Gxsm-PlugIns libs trys to open it dynamically and looks for the PlugIns Descriptor Function

GxsmPlugin *get_gxsm_plugin_info ( void )
.

If it the Symbol ``get_gxsm_plugin'' is resolved, gxsm calls this function. The return value is a pointer to the static PlugIn-Descripto Table as defined below. Then Gxsm evaluates the Type of the PlugIn and installs it in the desired way and adds it's Descriptor to a List for future use - e.g. to remove it again.

First play a bit with the PlugIn ``Plugin Details'' found at Tools Submenu. Expand the box pressing ``Details''! This will show the PlugIn Control Structure of eatch Plugin currently loaded, found and inspected by Gxsm.

There are three main types of Plugins: Run-Cb, Math-Plugin, and Query-Selfinstall.

Additionally there is a Category mechanism, which allow to autoselect Plugins to load. E.g. we will no need a Mover-Control Plugin, if we are running without hardware.

Lets have a look at the PlugIns Descriptor Table (defined in Gxsm/src/plugin.h):

/*
 * Gxsm PlugIn Infostruct:
 *
 * PlugIn Function Call: 
 *   (void*) get_plugin_info( void )
 * should return a valid Pointer to "struct GxsmPlugin" as defined here:
 *
 */

typedef struct
{
  void *handle;           /* Filled in by Gxsm */
  char *filename;         /* Filled in by Gxsm */
  int  Gxsm_session;      /* The session ID for attaching to the control socket */
  App *app;               /* Calling Application Object */
  char *name;             /* unique Plugin name */
  char *category;         /* Plugin's Category - used to autodecide on Pluginloading or ignoring */
  char *description;      /* The description that is shown in the preferences box */
  char *authors;          /* Plugins author */
  char *menupath;         /* The plugins menuposition to append to */
  char *menuentry;        /* The plugins menuentry */
  char *help;             /* The plugins help text */
  char *info;             /* Additional info about Plugin */
  char *errormsg;         /* Plugin Status Message */
  char *status;           /* Plugin Status, managed by Gxsm */
  void (*init) (void);    /* Called when the plugin is enabled */
  void (*query) (void);   /* Called after init and app is set. */
  void (*about) (void);   /* Show the about box */
  void (*configure) (void); /* User Configuration */
  void (*run) (GtkWidget *, void *); /* if run != NULL this handler is installed at menupath as 
                                      default, else for special Gxsm-Plugins is searched! */
  void (*cleanup) (void); /* Called when the plugin is disabled or when Gxsm exits */
}
GxsmPlugin;


/*
 * Gxsm special PlugIns...
 */

/* Math Plugins */

/* returned by
 * (void*) get_gxsm_math_one_src_plugin_info( void ) 
 */
typedef struct
{
  BOOL (*run) (Scan *Src, Scan *Dest);
}
GxsmMathOneSrcPlugin;

/* returned by
 * (void*) get_gxsm_math_two_src_plugin_info( void ) 
 */
typedef struct
{
  BOOL (*run) (Scan *Src1, Scan *Src2, Scan *Dest);
}
GxsmMathTwoSrcPlugin;

/* returned by
 * (void*) get_gxsm_math_one_src_no_dest_plugin_info( void ) 
 */
typedef struct
{
  BOOL (*run) (Scan *Src);
}
GxsmMathOneSrcNoDestPlugin;

HowTo make a new PlugIn

A simple way to start a new math plug-in is to use the shell script generate_math_plugin.sh from the plugins directory in the Gxsm source code. This script will prompt you for some information and then generates a ready-to-compile source code template for you.

If you prefer doing the stuff by hand, follow the steps below:

first:

cd Gxsm/plug-ins/math/

the file HACKING is here:

Plugin Hacking Guide          20001124PZ
----------------------------------------

Step One:
Have a look at ./statistik/vorlage.C,
and copy it into the best matching subdir, one of

background  filter1d  filter2d  misc  statistik  transform

using a new plugin name. (here: "myplugin.C")
The file "myplugin.C" includes a quick GxsmPlugin Guide, please follow...


This is found at top of vorlage.C:
--- snip ---
 * Quick nine points Gxsm Plugin GUIDE by PZ:
 * ------------------------------------------------------------
 * 1.) Make a copy of this "vorlage.C" to "your_plugins_name.C"!
 * 2.) Replace all "vorlage" by "your_plugins_name" 
 *     --> please do a search and replace starting here NOW!! (Emacs doese preserve caps!)
 * 3.) Decide: One or Two Source Math: see line 54
 * 4.) Fill in GxsmPlugin Structure, see below
 * 5.) Replace the "about_text" below a desired
 * 6.) * Optional: Start your Code/Vars definition below (if needed more than the run-fkt itself!), 
 *       Goto Line 155 ff. please, and see comment there!!
 * 7.) Fill in math code in vorlage_run(), 
 *     have a look at the Data-Access methods infos at end
 * 8.) Add vorlage.C to the Makefile.am in analogy to others
 * 9.) Make a "make; make install"
 * A.) Call Gxsm->Tools->reload Plugins, be happy!
 * ... That's it!
--- snip ---

Change into the subdir!

Step Two:
Adding your myplugin.C to the Makefile.am, located in the same directory:

1.) The Makefile.am has a list of all libs to build, add "libmyplugin.la":

lib_LTLIBRARIES = \
        libhistogram.la \
        libhistoHOP.la \
        libspasim.la \          <=== the line before should end with "\" !!
        libmyplugin.la          <=== add "myplugin" as here

2.) add the compiler instructions like:

libmyplugin_la_SOURCES = myplugin.C [mypluginhelp.C, ...]  <=== here you cann add more .C sources !!
libmyplugin_la_LDFLAGS = -export-dynamic -avoid-version

That's all to do for Makefile.am.


Step Three:
Build:

make
make install

Test:
Start gxsm   or call   Gxsm->Tools->Reload Plugins
Check Plugins Description, [About, Configure] using the "Gxsm->Tools->Plugin Details" Viewer
Test Plugins action


Step Four:
please publish!

If you are a SF-Gxsm project member:
sfcvs update
sfcvs add myplugin.C ...
sfcvf commit

or send Plugin-Srcs to zahl@users.sourceforge.net

Probe Modes (PlugIn)

Implementation of a generic ``Probe-Method'' with regard to the specialties of AFM, STM, SPA-LEED. No 2D data-ccollection, but ``Probing'' at one point/small area.

Probing: Force-Distance-Curves

For AFM...

Probing: Spectroskopie, STS

For AFM and STM...

Peak fit and find algortithms, ``aka Beam-Find'' (PlugIn)

For SPA-LEED and perhaps SARLS.

Parabel least Squares Fit

XY-scans, parable fit.

Gauss Fit

Log. transformation, parable fit.

Lorenz Fit

Inv. transformation, parable fit.


next up previous contents
Next: About this document ... Up: Gxsm and Xxsm User/Referenz Previous: AFM-HOWTO (allgemein)   Contents
Percy Zahl 2002-05-08