Sunteți pe pagina 1din 45

07dd0a100834020164020f2151003cde

07dd0a100834020164020f2151003cde

07dd0a100834020164020f2151003cde

MEGA-FABS
07dd0a100834020164020f2151003cde

07dd0a100834020164020f2151003cde

PDL
07dd0a100834020164020f2151003cde

Process description language


07dd0a100834020164020f2151003cde

07dd0a100834020164020f2151003cde

20/JAN/2009
07dd0a100834020164020f2151003cde

07dd0a100834020164020f2151003cde

07dd0a100834020164020f2151003cde

07dd0a100834020164020f2151003cde

07dd0a100834020164020f2151003cde

07dd0a100834020164020f2151003cde

07dd0a100834020164020f2151003cde

07dd0a100834020164020f2151003cde

07dd0a100834020164020f2151003cde

07dd0a100834020164020f2151003cde

07dd0a100834020164020f2151003cde

07dd0a100834020164020f2151003cde

07dd0a100834020164020f2151003cde
07dd0a100834020164020f2151003cde

MEGA-FAB
07dd0a100834020164020f2151003cde Number: 0000 0000 0001

Sheet 2nd of 45
PDL
07dd0a100834020164020f2151003cde

1 PREFACE.................................................................................................................................. 4
1.1 TERMS ........................................................................................................................... 5
07dd0a100834020164020f2151003cde
1.2 EXAMPLES ...................................................................................................................... 5
1.3 MULTITASKING ............................................................................................................... 7
1.3.1 define task priority................................................................................................... 9
07dd0a100834020164020f2151003cde
1.4 VARIABLES TYPES........................................................................................................... 9
1.4.1 Pointers ................................................................................................................10
1.5 PROCEDURES ................................................................................................................11
1.5.1 Example of use procedures and pointers ..................................................................13
07dd0a100834020164020f2151003cde
1.6 READ ONLY, LEVEL PROTECTED ATTRIBUTES ..................................................................13
2 COMMANDS........................................................................................................................... 14
2.1 ASSIGNMENT COMMANDS ..............................................................................................14
07dd0a100834020164020f2151003cde
2.1.1 Index auto increment .............................................................................................16
2.1.2 Auto increment/decrement .....................................................................................16
2.1.2 String assignment ..................................................................................................
07dd0a100834020164020f2151003cde
16
2.1.3 State address assignment ........................................................................................17
2.1.4 State assignment ....................................................................................................18
2.1.4.1 state assignment to variable ............................................................................................ 18
2.1.5 Label address assignment .......................................................................................
07dd0a100834020164020f2151003cde 18
2.2 PROGRAM FLOW COMMANDS .........................................................................................19
2.2.1 Halt ......................................................................................................................19
2.2.2 Wait/Sleep ............................................................................................................
07dd0a100834020164020f2151003cde
19
2.2.3 Goto .....................................................................................................................20
2.2.4 Indirect Goto .........................................................................................................20
2.2.5 Call and Ret ..........................................................................................................20
2.2.6 exitproc ................................................................................................................
07dd0a100834020164020f2151003cde 21
2.2.7 Task commands.....................................................................................................21
2.2.7.1 Run .............................................................................................................................. 21
2.2.7.2 Kill, stop, cont ............................................................................................................... 22
07dd0a100834020164020f2151003cde
2.2.7.3 Lock / unlock ................................................................................................................ 22
2.2.8 Loop.....................................................................................................................23
2.2.9 IF and Else ............................................................................................................24
2.2.10 While ...................................................................................................................26
07dd0a100834020164020f2151003cde
2.2.11 Till .......................................................................................................................26
2.2.12 TOUT condition ....................................................................................................27
2.3 INTERRUPTS ..................................................................................................................29
07dd0a100834020164020f2151003cde
2.3.1 intrpmake .............................................................................................................30
2.3.2 intrpon/intrpoff ......................................................................................................30
2.3.3 intrpremove ..........................................................................................................30
2.4 BUILD IN FUNCTIONS .....................................................................................................32
07dd0a100834020164020f2151003cde
2.4.1 Max and Min ........................................................................................................32
2.4.2 Abs ......................................................................................................................32
2.4.3 Unsign ..................................................................................................................32
07dd0a100834020164020f2151003cde
2.4.4 Sign......................................................................................................................33
2.3.5 sin, cos .................................................................................................................33
2.3.6 sqrt .......................................................................................................................33
2.3.7 divi.......................................................................................................................
07dd0a100834020164020f2151003cde 33
2.3.8 shift ......................................................................................................................33
2.3.9 bitset, bitclr, bittog.................................................................................................34
2.3.10 gettask ..................................................................................................................
07dd0a100834020164020f2151003cde
34
2.3.11 bytesep .................................................................................................................35
2.3.12 bytecomb ..............................................................................................................36
2.3.13 memcpy ................................................................................................................37
2.3.14 memset .................................................................................................................
07dd0a100834020164020f2151003cde 38
2.3.15 memmin, memmax ................................................................................................38
2.3.16 memsum ...............................................................................................................39
2.5 SPECIALS COMMANDS ...................................................................................................
07dd0a100834020164020f2151003cde 39

2
07dd0a100834020164020f2151003cde
07dd0a100834020164020f2151003cde

MEGA-FAB
07dd0a100834020164020f2151003cde Number: 0000 0000 0001

Sheet 3rd of 45
PDL
07dd0a100834020164020f2151003cde

2.5.1 Prints/ printl/ retprintl ............................................................................................39


2.5.2 prinl/retprintl + parameters .....................................................................................40
07dd0a100834020164020f2151003cde
2.5.2.1 Example ....................................................................................................................... 41
2.4.2 event/ retevent .......................................................................................................42
2.5.6 Set, Clear, Toggle State ..........................................................................................42
2.6 DIRECTIVES ..................................................................................................................42
07dd0a100834020164020f2151003cde
2.6.1 Task .....................................................................................................................42
2.6.2 Long /Short/Float ..................................................................................................43
2.6.3 define ...................................................................................................................43
2.6.4 undef 07dd0a100834020164020f2151003cde
....................................................................................................................44
2.6.5 ifdef ifndef else elifdef elifndef endif ......................................................................45
2.6.6 include..................................................................................................................45
07dd0a100834020164020f2151003cde

07dd0a100834020164020f2151003cde

07dd0a100834020164020f2151003cde

07dd0a100834020164020f2151003cde

07dd0a100834020164020f2151003cde

07dd0a100834020164020f2151003cde

07dd0a100834020164020f2151003cde

07dd0a100834020164020f2151003cde

07dd0a100834020164020f2151003cde

07dd0a100834020164020f2151003cde

07dd0a100834020164020f2151003cde

07dd0a100834020164020f2151003cde

07dd0a100834020164020f2151003cde

07dd0a100834020164020f2151003cde

3
07dd0a100834020164020f2151003cde
07dd0a100834020164020f2151003cde

MEGA-FAB
07dd0a100834020164020f2151003cde Number: 0000 0000 0001

Sheet 4th of 45
PDL
07dd0a100834020164020f2151003cde

07dd0a100834020164020f2151003cde
1 PREFACE
07dd0a100834020164020f2151003cde
PDL (Process Description Language) is a simple program language used to write PDL programs
that runs on MEGA-FAB D series drive .
The PDL program is written in the host (PC) by any standard editor as *.pdl file (text file). This *.pdl
07dd0a100834020164020f2151003cde
file is compiled (to output file *.txt) and send to the controller. The DSP processor software (MDP)
-handle all controller missions (motor control, I/O, communication and so on), also interpret the
compiled PDL program stored in flash memory.
07dd0a100834020164020f2151003cde
The main features of the PDL are:
Multitasking the ability to run several tasks in parallel up to 4 tasks.
User variables are defined (name,07dd0a100834020164020f2151003cde
type, size) inside the program.
Supporting arrays and pointers.
Procedures with parameters. 07dd0a100834020164020f2151003cde
Loop, while, if, else, till, goto commands to control the program flow
Mathematics function.
07dd0a100834020164020f2151003cde
Lock, Unlock commands to perform task synchronization.
Memory size for code is up to 128 Kbytes.
07dd0a100834020164020f2151003cde
Memory size for User variable is up to 400 long words.

07dd0a100834020164020f2151003cde

07dd0a100834020164020f2151003cde

07dd0a100834020164020f2151003cde

07dd0a100834020164020f2151003cde

07dd0a100834020164020f2151003cde

07dd0a100834020164020f2151003cde

07dd0a100834020164020f2151003cde

07dd0a100834020164020f2151003cde

07dd0a100834020164020f2151003cde

4
07dd0a100834020164020f2151003cde
07dd0a100834020164020f2151003cde

MEGA-FAB
07dd0a100834020164020f2151003cde Number: 0000 0000 0001

Sheet 5th of 45
PDL
07dd0a100834020164020f2151003cde

1.1 Terms
07dd0a100834020164020f2151003cde
DCE Distributed Control Electronics. Another name for a controller(s) system
Single Slave a controller in one controller system. Some time it may be called simply slave
MDP Main 07dd0a100834020164020f2151003cde
DSP Program. The main firmware software running on the DSP which do all controller
tasks such as axes close loop, i/o handling. The base timing of it is usually the phase=66.67usec
(1/samp rate). each phase the MDP interpret one(or several) PDL command from the next active
task and execute it.07dd0a100834020164020f2151003cde
All system variables are defined by this software. The exe file relate to MDP is
the <slave name>.edb.
MPI a name for PC library which application may include in order to communicate with control-
ler(s). Contain methods for07dd0a100834020164020f2151003cde
accessing any variable/state, running PDL functions ( see definition ),
getting events triggered by printl commands or states toggling, and more. available in several types:
DLL , static library, ActiveX.
Variables relate to all type of variables (user and system, long ,short, float, states) . See below full
07dd0a100834020164020f2151003cde
detail description.
states Special one bit variables located in the status short type array. see below full detail de-
scription. 07dd0a100834020164020f2151003cde
PDL functions Some time we call to PDL section code start with a label a PDL function. This is
relevant when the label mark a start of subroutine ( which end with ret/halt). This label can be called
or be run internally or externally ( if the label name07dd0a100834020164020f2151003cde
start with _ then it recognized by host.)
Dont confuse with built in functions which are part of the language syntax such as abs, min, max,
sqrt, sin, cos
07dd0a100834020164020f2151003cde
Procedure user defined subroutine that can accept parameters
fclk a name of 32 bit system variable use as time reference . It count at DSP sample rate ( which
is 20000Hz usually but can be more according to application).
07dd0a100834020164020f2151003cde
Samp_rate a name of 32 bit system float variable that define the sample rate ( tick time) of the
DSP usably it is 15KHz. Usually it value is predefined and constant but it can be (according to ap-
plication requirement) change able on the fly between defined range and user can increase de-
07dd0a100834020164020f2151003cde
crease the sample rate. Changing the sample rate effect the PDL running rate/close loop algorithm
rate DSP overload and more.

07dd0a100834020164020f2151003cde
1.2 Examples

Example 1
07dd0a100834020164020f2151003cde

The following example demonstrates the use of three tasks in the program. Task 0 moves step motor
number 1 repeated point to point between -15000 and 15000 micro steps. Task1 - start/stop motor1
movement according to input number 0.
07dd0a100834020164020f2151003cde

Task 21 is generating square wave.


Also there is program start from label _func1 which not run after reset. but any free task can run it if
07dd0a100834020164020f2151003cde
other task will execute run command, or externally by host.

07dd0a100834020164020f2151003cde
_runp2p: // a label to be recognized by host
#long posx; // declare long (32 bit) user variable
#short delay; //07dd0a100834020164020f2151003cde
declare short (16 bit) user variable
x_vel_max=20000; // set vel_max to 20000 step/sec
x_acc=100000; // set acc to 100000 step/sec^2
07dd0a100834020164020f2151003cde

5
07dd0a100834020164020f2151003cde
07dd0a100834020164020f2151003cde

MEGA-FAB
07dd0a100834020164020f2151003cde Number: 0000 0000 0001

Sheet 6th of 45
PDL
07dd0a100834020164020f2151003cde

x_dcc=100000; // set dcc to 100000 step/sec^2


x_new_sm_fac=100; // set smooth_factor to 100
07dd0a100834020164020f2151003cde

x_dcc_kill=500000; // set kill dcc to 500000 step/sec^2


posx=15000; delay 1000;
07dd0a100834020164020f2151003cde
again:
x_trg=posx; // move motor x to posx steps
07dd0a100834020164020f2151003cde
till(~x_run | x_en=0); // wait till end of motor x movement or axis fail
if(x_en=0) reprintl/101("X axis fail");
sleep delay; 07dd0a100834020164020f2151003cde
// wait 1 sec
posx=-posx; // next time move to opposite direction
goto again 07dd0a100834020164020f2151003cde

;
//************* Task 1: Control start/stop motor x *******
07dd0a100834020164020f2151003cde
#task/1; // Task 1 will start run from here after reset
loop:
07dd0a100834020164020f2151003cde
till(IN0); // wait till state of input 0 is active
stop 0; // hold execute task 0
x_stop=1; // stop step motor x 07dd0a100834020164020f2151003cde

wait 100; // wait 100 phases


till(~IN0); // wait till state
07dd0a100834020164020f2151003cde of input 0 is inactive
cont 0; // continue execute task 0
Sleep 100; // wait 100 msec
07dd0a100834020164020f2151003cde
goto loop;

07dd0a100834020164020f2151003cde

//** The 'sqout' user variable will swing between 0 and 1 with the
//** 07dd0a100834020164020f2151003cde
Delays of delay_0, delay_1 respectively
_SQRWAV: // this label may be run internally or externally
#short sqout,delay_0,delay_1;
07dd0a100834020164020f2151003cde
delay_0=200; delay_1=400;
loopo:
07dd0a100834020164020f2151003cde
sqout=0;
sleep delay_0;
sqout=1; 07dd0a100834020164020f2151003cde

sleep delay_1;
goto loopo; 07dd0a100834020164020f2151003cde
//=======================
#long count;
07dd0a100834020164020f2151003cde

6
07dd0a100834020164020f2151003cde
07dd0a100834020164020f2151003cde

MEGA-FAB
07dd0a100834020164020f2151003cde Number: 0000 0000 0001

Sheet 7th of 45
PDL
07dd0a100834020164020f2151003cde

_COUNT1: // this label may be run internally or externally


count++;
07dd0a100834020164020f2151003cde

printl/103(The count is %ld ,count); // send message to host


ret; // task termination
07dd0a100834020164020f2151003cde

07dd0a100834020164020f2151003cde
example 2

// the following procedure 07dd0a100834020164020f2151003cde


move the axis defined by the pointer trg to relative
// distance target ( given in mm) the axis scale is the parameter 'scale' (count/mm)
// the function return after 'axisrunst' state is not active ( i.e. the axis stop)
07dd0a100834020164020f2151003cde

proc moveaxis(long *trg, float target, float scale, long axisrunst) do


07dd0a100834020164020f2151003cde
#long tmp; // declare temporary variable
tmp=target*scale;
07dd0a100834020164020f2151003cde
*trg=*trg+tmp; // assigning to trg variable trigger the move
till(~<axisrunst>); // wait till the state ( which is stored in variable axisrunst) not active
07dd0a100834020164020f2151003cde

end; // procedure end

07dd0a100834020164020f2151003cde
#task/1;
moveaxis( &x_trg, 4.5, 20000, <x_run>); // move x axis 4.5 mm.
07dd0a100834020164020f2151003cde
sleep 1000;
moveaxis( &t_trg, -9, 10000, <t_run>); // move t axis -9 mm
07dd0a100834020164020f2151003cde
halt;

1.3 Multitasking
07dd0a100834020164020f2151003cde

The PDL support the ability to run several tasks in parallel. Each task has in the DSP memory its own
program counter (pp), stack pointer (sp), flags, and stack. In each phase (66.67 sec usually) one
07dd0a100834020164020f2151003cde
command from task in turn is executed (in PDL ver 12+ several commands can run in each phase).
Only tasks that are not in idle and not sleep/stop (tmask[n]<0) are running in turn. The maximum
tasks that can run are 3. By default all tasks has the same priority, that is If n tasks are running and
are not in sleep/stop07dd0a100834020164020f2151003cde
state, then each task will be executed once to n phases, i.e. the execution rate
of each task will be as the DSP sample rate (15000/n Hz usually). To change task priority see below.
The program is written as a one body, The user has the option to define for any task 03 if it will run
07dd0a100834020164020f2151003cde
after reset and the location in the program in which it will start to run from . This is done by putting the
directive #task/n. Putting the directive #task/n inside the code make task number n to start to run
from this location after reset, (Not all task mast run after reset, probably you may need only one task
to run after reset to do the initialization ). See also the detail description of the #task directive below.
07dd0a100834020164020f2151003cde
All global variables are common to all tasks. The same commands may be executed by different
tasks (i.e. common subroutines, procedures). Lock Unlock commands may used to protect global
code/variables or any other resources from07dd0a100834020164020f2151003cde
accessing with more then one task. Implementation of

7
07dd0a100834020164020f2151003cde
07dd0a100834020164020f2151003cde

MEGA-FAB
07dd0a100834020164020f2151003cde Number: 0000 0000 0001

Sheet 8th of 45
PDL
07dd0a100834020164020f2151003cde

multi tasks synchronization (semaphores, events, mutex) can be done using lock, unlock com-
mands.
07dd0a100834020164020f2151003cde
Task can be run by means of one of 4 ways:
When putting the directive #task/n anywhere in the program then task number n will start to run
from this point (after controller reset). It may be terminate (if needed) by execute halt command (in
07dd0a100834020164020f2151003cde
older PDL version dont use ret in this case)
One task may run other task using run command. See description below. The first new idle task
07dd0a100834020164020f2151003cde
will start to run from the label specified in the command. This task may be terminated by ret/halt
command. (Note that task can be killed/stop/continue by other tasks as well).
The host can create new task running by sending run command (see RunFuncPdlN,
SetArrayRunFuncN in mpi.dll). 07dd0a100834020164020f2151003cde
This run command includes label address from which the new task
will start to run from. Labels name that recognized externally, (i.e. by the host) start with _. The
first new idle task will start to run from this label. This task may be terminated by ret/halt command.
The same label can run only once07dd0a100834020164020f2151003cde
from the host.
From interrupt , a state toggle event trigger new task to run. See interrupts section for details.

07dd0a100834020164020f2151003cde
Tasks may be terminated by means of one of 3 ways:
Execute halt/ret/retprintl command (for tasks running from #task/n use only halt in old PDL
version) 07dd0a100834020164020f2151003cde

Killed by kill command executed by other task


Killed by host ( see killTask in mpi.dll ) 07dd0a100834020164020f2151003cde

07dd0a100834020164020f2151003cde

07dd0a100834020164020f2151003cde

07dd0a100834020164020f2151003cde

07dd0a100834020164020f2151003cde

07dd0a100834020164020f2151003cde

07dd0a100834020164020f2151003cde

07dd0a100834020164020f2151003cde

07dd0a100834020164020f2151003cde

07dd0a100834020164020f2151003cde

8
07dd0a100834020164020f2151003cde
07dd0a100834020164020f2151003cde

MEGA-FAB
07dd0a100834020164020f2151003cde Number: 0000 0000 0001

Sheet 9th of 45
PDL
07dd0a100834020164020f2151003cde

1.3.1 define task priority


07dd0a100834020164020f2151003cde
There is a system array called task_prior[03] which defines for each task its priority. if
task_prior[n] = k then for task n it will execute k phases before switching to the next active task
(if k<=0 then consider as k=1). so define:
T = total execute cycle = task_prior[n].
07dd0a100834020164020f2151003cde
where n go from 0 to 39 only for active tasks ( tasks that are running and not in sleep/stop state),
and also if task_prior[n]<=0 then consider task_prior[n]=1. We get the total execute cycle (T) in
phases. In each such cycle, task n will execute task_prior[n] phases, and the rate for task n will be:
07dd0a100834020164020f2151003cde
rate = samp_rate * task_prior[n] /T
By default the task_prior array is cleared so all tasks has same priority.
07dd0a100834020164020f2151003cde
Example how to change task priority by the active task itself:

_my_critical_task: // label 07dd0a100834020164020f2151003cde


start

task_prior[task_num]=5; // change the current task priority
. 07dd0a100834020164020f2151003cde

..
task_prior[task_num]=0; // return current task priority to default
07dd0a100834020164020f2151003cde
.
Notes:
Tasks that are in sleep/stop state are skipped no meter there priority
07dd0a100834020164020f2151003cde
task which is in lock state, is the only one that execute (until it unlocked) no meter the contain of the
priority table (task_prior[] array contain)
07dd0a100834020164020f2151003cde
In PDL ver 12+ each task can run several commands in each phase.

07dd0a100834020164020f2151003cde
1.4 Variables Types

07dd0a100834020164020f2151003cde
Any variable has five types of attributes:
1. Defined by: system or user variables.
2. Type: long, float (32 bit), short (16 bit), state (1 bit). Float pointer, long pointer (32 bit)
07dd0a100834020164020f2151003cde

3. Size: All variables can be considered as arrays with a minimum size of 1.


4. Scope: (long and float) user variables can be temporary(procedure local variables) if they are
07dd0a100834020164020f2151003cde
declared in the header and within a procedure

System variables are predefined variables (name, length, location), each one performing a certain
07dd0a100834020164020f2151003cde
function. For example, the system slave variables 'X_vel_max, X_acc X_dcc X_new_sm_fac' define
the velocity trapeze profile, and setting the variable 'X_trg' in the slave to a new value causes the X
axis to move at this profile velocity. System variables are global (not temporary). Slave system
07dd0a100834020164020f2151003cde
variables are listed in <slave_name>.vrs file (one for each slave).
User variables are variables defined in the *.PDL file with #long and #short #float directives
commands. User variables are listed in USER_$.VRS file after PDL compilation ($ stand for slave
07dd0a100834020164020f2151003cde
number which is 0 by default). User variables can be defined as long or float pointers (long pointer
contain an address of another long/short variable, and float pointer contain an address of another

07dd0a100834020164020f2151003cde

9
07dd0a100834020164020f2151003cde
07dd0a100834020164020f2151003cde

MEGA-FAB
07dd0a100834020164020f2151003cde Number: 0000 0000 0001

Sheet 10th of 45
PDL
07dd0a100834020164020f2151003cde

float variable). if user variable is declared in the header or within a procedure then it is temporary
(local procedure variable).
07dd0a100834020164020f2151003cde
Pointers and temporary user variables are described next sections.
Variables may have 16 (short) or 32 (long/float/pointers) bit lengths.
07dd0a100834020164020f2151003cde
States being always system variables are special 1bit variables used in conditional statements.
States can be modified using the seton/setoff/toggle/state assignment commands. States may
be represent inputs/outputs digital signal or any internal states (axis run/not run for example). All
the states are the bits of the status array variable. The states are listed in *.STT files. When state is
07dd0a100834020164020f2151003cde
toggled a notify message is send to host.
A short or a long variable may be interpreted as a signed or unsigned number depending on its
function. 07dd0a100834020164020f2151003cde

The size attribute is relevant to arrays. Access to an item in array is done by using the square
breakers [ ] , for example:
07dd0a100834020164020f2151003cde
vel_max[2]=20000;
abspos[n]=50000; // n is a short local variable
The size of system variables are defined 07dd0a100834020164020f2151003cde
in *.vrs and for user variables in the #short #long/float
directives. The size of each variable can be retrieved form mpi.dll. The minimum size of each
variable is 1.
07dd0a100834020164020f2151003cde
A variable can be indexed by a constant or a short/long variable.
Any variable can be indexed no meter its size. When indexed with a constant, the compiler doesnt
check size overflow.
07dd0a100834020164020f2151003cde
Example:

07dd0a100834020164020f2151003cde
#short Eli, Rafi, Benny ,
My_array[100], N; // declare short user variables/arrays
Eli[0]=15; // equivalent to Eli=15
07dd0a100834020164020f2151003cde

Eli[1]=100; // equivalent to Rafi=100


Eli[2]=500; // equivalent to Benny=500
07dd0a100834020164020f2151003cde
N=55;
My_array[N]=Benny; // equivalent to My_array[55]=500
07dd0a100834020164020f2151003cde

1.4.1 Pointers
Pointers are 32 bit variables, which used to store address to other variable, example:
07dd0a100834020164020f2151003cde
#long v, *pv; // pv is defined as pointer to long or short variable.
pv=&v; // pv is assigned with the address of v;
07dd0a100834020164020f2151003cde
*pv=55; // i.e. v=55;
The indirection * is allowed only for variables that declared as pointers. It means that the
variable value is an address of another stored value that should be taken.
07dd0a100834020164020f2151003cde
The operator & when precede variable name means that the address of the variable should
be taken (and not its value).
Pointers can be declared as long or07dd0a100834020164020f2151003cde
float according to the variable type that they are going to point
to.
Example:
07dd0a100834020164020f2151003cde

10
07dd0a100834020164020f2151003cde
07dd0a100834020164020f2151003cde

MEGA-FAB
07dd0a100834020164020f2151003cde Number: 0000 0000 0001

Sheet 11th of 45
PDL
07dd0a100834020164020f2151003cde

#float f, *pf; // pf is defined as pointer to float variable.


pf=07dd0a100834020164020f2151003cde
&f;
*pf=5.4; // i.e. f=5.4
No short type pointers. Pointers for long may also use for short as well.
07dd0a100834020164020f2151003cde
Pointers may be indexed in several ways, example
#long v[6],n, *pv;
07dd0a100834020164020f2151003cde
pv=&v;
*pv=0; // v[0]=0
*pv[1]=10; //v[1]=10; 07dd0a100834020164020f2151003cde

pv=pv+2;
*pv=20; // v[2]=20 07dd0a100834020164020f2151003cde
pv=&v[3];
*pv=30; // v[3]=30
07dd0a100834020164020f2151003cde
n=4;
pv=&v[n];
07dd0a100834020164020f2151003cde
*pv=40; // v[4]=40;
n=1;
*pv[n]=50; // v[5]=50, note that operator * perform before 07dd0a100834020164020f2151003cde
operator []
*pv[1]=50; // v[5]=50;

07dd0a100834020164020f2151003cde
Pointers must be initialized to any variable address before using them with the indirection operator
*, otherwise results are unpredictable (including software fail).
Pointers may be defined for integer(long/short)
07dd0a100834020164020f2151003cde or float, you should use the correct pointer type
when access variable otherwise an incorrect value will be read/written
Pointers may used to pass output parameters (by reference) to procedures
07dd0a100834020164020f2151003cde

1.5 Procedures
Procedures are similar to functions in C/C++. Not like C, they dont return value directly. Return
07dd0a100834020164020f2151003cde
value can be achieved by pointers parameters.
Syntax of procedure:
proc <procedure name>(<type> name, <type> name,..) do
07dd0a100834020164020f2151003cde

..
Procedure body
07dd0a100834020164020f2151003cde
end; // procedure end

07dd0a100834020164020f2151003cde
Example:
// the following procedure compute the sum of 3 values (a,b,c parameters) and return result to //
sum parameter 07dd0a100834020164020f2151003cde
proc add3( long a, long b, long c, long * sum) do
#long tmp; // defined temporary user variable
07dd0a100834020164020f2151003cde

11
07dd0a100834020164020f2151003cde
07dd0a100834020164020f2151003cde

MEGA-FAB
07dd0a100834020164020f2151003cde Number: 0000 0000 0001

Sheet 12th of 45
PDL
07dd0a100834020164020f2151003cde

tmp=a+b;
*sum=tmp+c;
07dd0a100834020164020f2151003cde

end; // return from procedure


.
07dd0a100834020164020f2151003cde
#long v1,v2, s; // defined global user variable
add3(4,5,6,&s); // result s=15;
07dd0a100834020164020f2151003cde
v1=10;
v2=100
add3(v1,v2,1,&s); // result 07dd0a100834020164020f2151003cde
s=111;
notes:
Procedure deceleration start with the key word proc
07dd0a100834020164020f2151003cde
The procedure body start with do and closed with end
All parameters variables and internal declared variables are temporary, i.e. they are not
07dd0a100834020164020f2151003cde
recognized outside the procedure. Temporary variables are allocated in the stack, there for
theres scope lifetime is only when procedure is executed. Non-temporary variables are
global variables, which are declared outside any procedure, or system variables. Tempo-
rary variables are called also local variables in07dd0a100834020164020f2151003cde
standards languages like C/C++. The
procedure can access also all global variables.
Labels that are within the procedure are recognized only in the procedure, And global labels
or labels in other procedures are not recognized by the07dd0a100834020164020f2151003cde
procedure.
Because each task has its own stack area more then one task may run the same procedure
without interfering each other, (unless they access global variable(s)).
07dd0a100834020164020f2151003cde
Temporary variables can be long or float and can be pointers, not allowed short type.
Calling to procedure syntax is similar as in C/C++, i.e. specified the procedure name fol-
lowed by the arguments list enclosed in
07dd0a100834020164020f2151003cde (). Each argument can be a constant or a variable,
if argument is constant the compiler is automatically convert it to the correct type if needed
(float/long)
When calling to procedure, the compiler check
07dd0a100834020164020f2151003cde matching type of the parameters in the
parameter list again the parameter list declared in the procedure. It also check the correct
number of parameters (unlike C++, no default values is allowed, and no overload proce-
dures)
07dd0a100834020164020f2151003cde
Temporary variables can be given the same name as global user variables (but not system
variables) or the same name as in other procedure temporary variables. The same is ap-
plied to07dd0a100834020164020f2151003cde
labels.
The user should be aware not to exceed stack size. Note that each procedure call increase stack
deep by 2+ number of local variables. Each nesting loop command also add one to the stack deep.
Also multi level expression of assignment to state or multi level expression in condition statement
07dd0a100834020164020f2151003cde
consume stack deep according to the nesting level of the expression. You may run in single step
the PDL in suspected sections and test if stack overflow ( using the PDL debugger window of the
KMI )
07dd0a100834020164020f2151003cde
When procedure is declared below the line where using it, you may put a prototype of it to avoid
compile error, example
07dd0a100834020164020f2151003cde
proc mul( float a, long b, float * res); // procedure prototype

07dd0a100834020164020f2151003cde

12
07dd0a100834020164020f2151003cde
07dd0a100834020164020f2151003cde

MEGA-FAB
07dd0a100834020164020f2151003cde Number: 0000 0000 0001

Sheet 13th of 45
PDL
07dd0a100834020164020f2151003cde

#float f1, m; // global user variable


f1=44.2;
07dd0a100834020164020f2151003cde

mul(f1, 20, &m); // result m=884; // the mul is now recognized

07dd0a100834020164020f2151003cde
proc mul( float a, long b, float * res) do // procedure implementation
*res=a*b;
07dd0a100834020164020f2151003cde
end; // return from procedure
.
07dd0a100834020164020f2151003cde
1.5.1 Example of use procedures and pointers

07dd0a100834020164020f2151003cde
The following example demonstrates the use of procedures with pointers to axis.

#include defprf.h // contain all constants offset for axis variable pointer
07dd0a100834020164020f2151003cde
#define MASKFLOAT 0xdfffffff; // used to convert float pointer to integer type pointers

07dd0a100834020164020f2151003cde
// This procedure move axis to target wait till end move and return
// parameters:
// paxf -pointer to axis variables (point to variable p_i_g which mark axis variables block start)
// tar -target 07dd0a100834020164020f2151003cde
// runst- run state ( true when axis move , false when stop)
// vel -velocity
// accel -acc,dcc
07dd0a100834020164020f2151003cde
// Note that the offset constants vel_max,acc,dcc,trg are declared in defprf.h, and p_i_g=0
proc moveaxis(float *paxf ,long tar, long runst, long vel,long accel) do
07dd0a100834020164020f2151003cde
#long *paxi; // use to point to integer variables type, while paxf point to float types
paxi=paxf & MASKFLOAT; // casting paxf(float *) to paxi (long*)
*paxf[vel_max]=vel; // set velocity
07dd0a100834020164020f2151003cde
*paxf[acc]=accel; // set acceleration
*paxf[dcc]=accel; // set deceleration
*paxi[trg]=tar; // move to tar
till ( ~<runst> ); // wait till end move
07dd0a100834020164020f2151003cde

end;
//...............................
07dd0a100834020164020f2151003cde
_move_x_y:
x_en=1;
sleep 10;
07dd0a100834020164020f2151003cde
moveAxis(&x_p_i_g, 100000, <x_run>, 25000, 120000); // move x to 100000
moveAxis(&y_p_i_g, 200000, <y_run>, 35000, 90000); // move y to 200000
sleep 500;
ret; 07dd0a100834020164020f2151003cde

1.6 Read Only, Level Protected Attributes


07dd0a100834020164020f2151003cde
The RO and LP attributes are applied only to access to variables from host (by KMI
for example). This Attributes are set in #long, #short, #Float directives. For more
details see the description of this directives, and the section describes *.vrs files.
07dd0a100834020164020f2151003cde

13
07dd0a100834020164020f2151003cde
07dd0a100834020164020f2151003cde

MEGA-FAB
07dd0a100834020164020f2151003cde Number: 0000 0000 0001

Sheet 14th of 45
PDL
07dd0a100834020164020f2151003cde

07dd0a100834020164020f2151003cde
2 COMMANDS
07dd0a100834020164020f2151003cde
Commands can be divide to 4 main groups
1. Assignment - includes mathematics operations and functions.
2. Program 07dd0a100834020164020f2151003cde
flow - Goto, call, run, ret, exitproc,if, else, while, till, loop, wait and halt.
3. Directives - Commands that effect compilation.
4. Specials command - printl/prints/retprintl
07dd0a100834020164020f2151003cde
Every command is ended with semicolon ; .
Labels are ended with colon :.
07dd0a100834020164020f2151003cde
Comments can start with double slash // or enclose in /*. */

2.1 Assignment commands 07dd0a100834020164020f2151003cde

An assignment statement can take one of the following formats:


07dd0a100834020164020f2151003cde

1. var = var/constant;
2. var = {const_0 , const_1 , const_2, ...... , const_n};07dd0a100834020164020f2151003cde
3. var =string;
4. var = - var;
07dd0a100834020164020f2151003cde
5. var = <state_name> ; var = <label_name> ;
6. var = var op var/constant;
07dd0a100834020164020f2151003cde
7. var = func_name(arg_1,arg_2,...arg_n);
8. state = condition expression
07dd0a100834020164020f2151003cde
9. var op= var/constant

Unless other specified in the functions descriptions any variable can be short or long or 32 bit float.
07dd0a100834020164020f2151003cde
You may mix a short and long and float variables in the same statement.
arg_1arg_n in case (7) stand for variables where the last argument in any function is allowed to
be also a constant.
07dd0a100834020164020f2151003cde

When assign to short variable a long data the MSB word will be lost. When assign to long variable
a short data the data is sign extended (except for the function unsigned).
07dd0a100834020164020f2151003cde
Assignment form float to long/short will be incorrect if the value of the float variable is outside of the
range of the long/short variable.
A constant can be interpreted as a character code, see example.
07dd0a100834020164020f2151003cde
The special case of using functions (case (7)) is discussed in more details letter in this chapter.
Notes:
07dd0a100834020164020f2151003cde
In case (1) no more than one side of the equation is allowed to be a slave variable.
In cases (4), (5), (6) (7) only the left side of the equation is allowed to be a slave variable.
07dd0a100834020164020f2151003cde

14
07dd0a100834020164020f2151003cde
07dd0a100834020164020f2151003cde

MEGA-FAB
07dd0a100834020164020f2151003cde Number: 0000 0000 0001

Sheet 15th of 45
PDL
07dd0a100834020164020f2151003cde

Assignment to/from a slave variable takes is performed with the delay of 2 frames (20 phases).
07dd0a100834020164020f2151003cde
State assignment (case 8) is described below
operation Assignment (case 9) support only in PDL version 18 and latter
<op> can 07dd0a100834020164020f2151003cde
be one of the following operators:
+ add
- subtract
07dd0a100834020164020f2151003cde
* signed multiplied
/ divide
& logic and 07dd0a100834020164020f2151003cde

| logic or
@ logic xor 07dd0a100834020164020f2151003cde

% mode ( take reminder of divide )


operation Assignment are:
07dd0a100834020164020f2151003cde
+= -= *= /= &= |= @= %=
that is instead of writing for example var1=var1+var2 you may write var1+=var2, operation As-
signments are shorter in code, execute faster and 07dd0a100834020164020f2151003cde
more convenient .
Example :
#short x,y,ar[100],YS,DN,EL; // declare short user vars/ arrays
07dd0a100834020164020f2151003cde
#long p1,p2,pr[60]; // defined long user vars/arrays
#float f1,f2;
07dd0a100834020164020f2151003cde

f1=0,5;
07dd0a100834020164020f2151003cde
f2=f1*4000;
p1=600000;
p2=p1;
07dd0a100834020164020f2151003cde
pr[5]=p1;
pr=400; // equivalent to pr[0]=400;
07dd0a100834020164020f2151003cde
pr=0x02FC; // constant written in Hex format
x=7; y=5;
07dd0a100834020164020f2151003cde
pr[x]=pr[y]+400000;
x=x & y;
ar[x]=ar[2] * ar[y]; 07dd0a100834020164020f2151003cde
ar[x]=ar[x] * ar[y];
wait 20; // wait 2.5 frames07dd0a100834020164020f2151003cde
till p1 to be updated with ref_pos of axis 2
p2=p1+100000; // now you can use p1 variable
ar={1,3,5,6,900,-8000}; //init first 6 variables in array
07dd0a100834020164020f2151003cde
ar[2]={1,3,5,6,900,-8000}; // init 6 first items in array start from 2
x=3;
07dd0a100834020164020f2151003cde

15
07dd0a100834020164020f2151003cde
07dd0a100834020164020f2151003cde

MEGA-FAB
07dd0a100834020164020f2151003cde Number: 0000 0000 0001

Sheet 16th of 45
PDL
07dd0a100834020164020f2151003cde

ar[x]={1,3,5,6,900,-8000}; // init 6 variables in array start from 3


YS={100,200,300}; // i.e. YS=100; DN=200; EL=300;
07dd0a100834020164020f2151003cde

x+=y; // x=x+y Operation Assignment


x*=0.5; //x=x*0.5 Operation Assignment
07dd0a100834020164020f2151003cde

2.1.1 Index auto increment


07dd0a100834020164020f2151003cde
Index to array can be auto increment, example:
#short n,p;
07dd0a100834020164020f2151003cde
#long myar1[10],myar2[10];
.
n=0; p=0; 07dd0a100834020164020f2151003cde
loop (10) do
myar1[n+]=myar2[p+];
07dd0a100834020164020f2151003cde
end;
Notes:
the index to array is increment after getting the value
07dd0a100834020164020f2151003cde
The destination variable index is incremented after the source variable(s) index
incremented, so if you want to use the one index (say n) for both destination and
source you should replace in the example the assignment statement by:
07dd0a100834020164020f2151003cde
myar1[n+]=myar2[n]; // ok, the increment is on the destination variable index

2.1.2 Auto increment/decrement


07dd0a100834020164020f2151003cde
To increment/decrement long/short variable you can use ++ or operator, example:

#long *po, myvar[10]; // define pointer, and


07dd0a100834020164020f2151003cde array

myvar ++; // the same as:. myvar = myvar +1;


myvar --; // the same as:. myvar = myvar -1;
07dd0a100834020164020f2151003cde
myvar [4]++;
myvar [n]++;
07dd0a100834020164020f2151003cde
po=&myvar;
*po++; // i.e. myvar++;
*po[1]++; 07dd0a100834020164020f2151003cde
// i.e. myvar[1]++;
*po[n]++; // i.e. myvar[n]++;
07dd0a100834020164020f2151003cde

2.1.2 String assignment


07dd0a100834020164020f2151003cde

In case (3) a string can be assigned to array for example:


ar = this is a 07dd0a100834020164020f2151003cde
In this case every 4 characters will fill every word in the ar array, starting from the LSB byte in every
word. The string length is limited so you may use more then one command to put a long string in
array. The destination operand should be long type variable.
07dd0a100834020164020f2151003cde

16
07dd0a100834020164020f2151003cde
07dd0a100834020164020f2151003cde

MEGA-FAB
07dd0a100834020164020f2151003cde Number: 0000 0000 0001

Sheet 17th of 45
PDL
07dd0a100834020164020f2151003cde

The following example set to array a long string and output it through lcdout variable, which rep-
resent output port of LCD; the string length limitation is 12 (6 words).
07dd0a100834020164020f2151003cde

#long str[50], n,len;


07dd0a100834020164020f2151003cde

str = This is a lo;


str[6] = ng07dd0a100834020164020f2151003cde
string
len=6; // the total string length is 24 characters (6 long words)
call out_lcd; 07dd0a100834020164020f2151003cde

07dd0a100834020164020f2151003cde
// this subroutine output a string pointed by str with length len
out_lcd:
n=0; 07dd0a100834020164020f2151003cde

loop(len) do
lcdout = str[n]; // output the LSB byte 07dd0a100834020164020f2151003cde
lcdout = str[n]/256; // output the byte 2
lcdout = str[n]/65536; // output the byte 3
07dd0a100834020164020f2151003cde
lcdout = str[n]/16777216; // output the MSB byte

07dd0a100834020164020f2151003cde
n= n+1;
end;
ret
07dd0a100834020164020f2151003cde

2.1.3 State address assignment


07dd0a100834020164020f2151003cde
To assign state address (also called state bit number) put it in <>.
Example:
a1=<x_run> ; // a1 is stored with the state number of x_run
07dd0a100834020164020f2151003cde

The <x_run> is treated like a constant


The a1 variable may use later in seton/setoff/toggle state commands (when x_run represents
07dd0a100834020164020f2151003cde
output state), or in conditions statements.
Example:
#long a1; 07dd0a100834020164020f2151003cde

a1=<y1_run>;
till ( <a1>); 07dd0a100834020164020f2151003cde
a1= <anysensor>;
seton <anysensor>;
07dd0a100834020164020f2151003cde

07dd0a100834020164020f2151003cde

17
07dd0a100834020164020f2151003cde
07dd0a100834020164020f2151003cde

MEGA-FAB
07dd0a100834020164020f2151003cde Number: 0000 0000 0001

Sheet 18th of 45
PDL
07dd0a100834020164020f2151003cde

2.1.4 State assignment


In07dd0a100834020164020f2151003cde
state assignment you assign to state other states or conditions combined in condition ex-
pression. The conditions expression has the standard format (see if else commands).
Example (s1, s2, s3, s4, s5 represent states name, v1 v2 are variables):
s1=s2; // 07dd0a100834020164020f2151003cde
simple state assignment
s1=~s2; // s1= not s2
s1= (s2 & ~s3) | (~s2 &s3); // s1= s2 xor s3
07dd0a100834020164020f2151003cde
v1=<s2>; // assign to variable v1 the address (state bit number) of state s2
s1= (<v1> & ~s3) | (~<v1> &s3); // i.e. s1= s2 xor s3
s1=v2>1000; // s1will be07dd0a100834020164020f2151003cde
TRUE if v2>1000
<v1>= s1 | ( s3 & v2>1000 ) ; // <v1> represent s2
Expression may be complicated:
07dd0a100834020164020f2151003cde
s1=s2 | ( s3 & ( (s4 | v1<>100 ) & ~(s5 & ~(v2<200) ) );
condition can include single bit tests
s1= (v1->0 & ~(v1->1)) | ( ~(v1->0) & v1->1 )); // s1= xor of bits 0,1 in v1
07dd0a100834020164020f2151003cde

07dd0a100834020164020f2151003cde
2.1.4.1 state assignment to variable
Assignment states/conditions expression to variable (float/long/short) is also possible using the
keyword sttovar, example: 07dd0a100834020164020f2151003cde

#long var1[5],var2;
#float f1;
07dd0a100834020164020f2151003cde
var1= sttovar s2; // simple state assignment
var1[var2]= sttovar ~s2;
var1[3]= sttovar (s2 & ~s3) | (~s2 &s3);
07dd0a100834020164020f2151003cde

f1 = sttovar s1 | ( s3 & v2>1000 ) ;


var1 = s1 & var2->3 & var2->10
07dd0a100834020164020f2151003cde
The variable is set to 1 if the logic expression is true and to 0 if it false.

2.1.5 Label address assignment


07dd0a100834020164020f2151003cde

To assign Label address put it in <>.


07dd0a100834020164020f2151003cde
Example:
a1=<_y1_init> ; // a1 is stored with the address of label y1_init
The <_y1_init > is treated like a constant
07dd0a100834020164020f2151003cde

The a1 variable may use later in run commands.


Example: 07dd0a100834020164020f2151003cde
#long a1;
a1=<_y1_init>;
07dd0a100834020164020f2151003cde
run <a1> a2; // see run command

07dd0a100834020164020f2151003cde

18
07dd0a100834020164020f2151003cde
07dd0a100834020164020f2151003cde

MEGA-FAB
07dd0a100834020164020f2151003cde Number: 0000 0000 0001

Sheet 19th of 45
PDL
07dd0a100834020164020f2151003cde

2.2 Program Flow Commands


07dd0a100834020164020f2151003cde
2.2.1 Halt
Format: halt;
07dd0a100834020164020f2151003cde
When a task arrives to halt command it stops execution. The task is now in idle and available for run
commands (internally or externally).

07dd0a100834020164020f2151003cde
2.2.2 Wait/Sleep
The format of wait command is:
wait <local variable | constant >
07dd0a100834020164020f2151003cde
Sleep <local variable | constant >

07dd0a100834020164020f2151003cde
The wait command holds execution of the task for a time period specified by the
argument.
The time delay is: 07dd0a100834020164020f2151003cde

Sleep: value * 0.001sec = 20 phases


wait: value * 0.00005 sec = 1phase
07dd0a100834020164020f2151003cde
The important different between wait and Sleep commands is that sleep com-
mand put the task in state that it is not consuming slots time (phases), so other
tasks may run more quickly. 07dd0a100834020164020f2151003cde
Examples:

07dd0a100834020164020f2151003cde
#short dd,x,ar[20];
Sleep 1000; % wait for 1 sec
07dd0a100834020164020f2151003cde
dd=2000;
Sleep dd; % wait for 2 sec
ar[4]=5000; ar[5]=7000;
07dd0a100834020164020f2151003cde
x=5;
wait ar[4]; % wait for 0.25 sec ( 5000* 0.05 msec )
07dd0a100834020164020f2151003cde
Sleeep ar[x]; % wait for 7 sec
NOTES:
07dd0a100834020164020f2151003cde
Sleep/wait command doesnt work well with pointers, for example if you want to
do
#long *ps,t07dd0a100834020164020f2151003cde
ps=&anyvar;
Sleep *ps;
07dd0a100834020164020f2151003cde
Instead use this format
t=*ps;
sleep t; 07dd0a100834020164020f2151003cde

Dont use sleep command between lock/unlock commands instead use wait.
07dd0a100834020164020f2151003cde

19
07dd0a100834020164020f2151003cde
07dd0a100834020164020f2151003cde

MEGA-FAB
07dd0a100834020164020f2151003cde Number: 0000 0000 0001

Sheet 20th of 45
PDL
07dd0a100834020164020f2151003cde

2.2.3 Goto
Format:
07dd0a100834020164020f2151003cde

goto <label>;

07dd0a100834020164020f2151003cde
Goto transfer execution to the location marked by this label.
A label is any string (25 character maximum length), which marks a location in the
program. A 07dd0a100834020164020f2151003cde
label should end with :.
Example:
. 07dd0a100834020164020f2151003cde
goto loca1;
.
07dd0a100834020164020f2151003cde
.
loca1:
07dd0a100834020164020f2151003cde
2.2.4 Indirect Goto
Format:
07dd0a100834020164020f2151003cde
goto <label>[ <var/constant>];
Example:
#short indx 07dd0a100834020164020f2151003cde


goto label_tab[2]; // relevant
07dd0a100834020164020f2151003cde to jump func2

indx=3;
07dd0a100834020164020f2151003cde
goto label_tab[indx]; // relevant to jump func3

07dd0a100834020164020f2151003cde
label_tab:
goto func0;
goto func1;
07dd0a100834020164020f2151003cde

goto func2;
goto func3;
07dd0a100834020164020f2151003cde
goto func4;

07dd0a100834020164020f2151003cde

. 07dd0a100834020164020f2151003cde

2.2.5 Call and Ret


07dd0a100834020164020f2151003cde
Format:
call <label>;
07dd0a100834020164020f2151003cde

20
07dd0a100834020164020f2151003cde
07dd0a100834020164020f2151003cde

MEGA-FAB
07dd0a100834020164020f2151003cde Number: 0000 0000 0001

Sheet 21st of 45
PDL
07dd0a100834020164020f2151003cde

Call transfers execution to the location marked by this label, and pushes to stack
the current location. Ret command is a return from subroutine (i.e. pops back the
07dd0a100834020164020f2151003cde
location from stack and returns to this location).
Example:
07dd0a100834020164020f2151003cde

call subr1;

07dd0a100834020164020f2151003cde

subr1:
07dd0a100834020164020f2151003cde


ret; 07dd0a100834020164020f2151003cde

The maximum number of nested calls (together with loop commands) depends
on the stack size. Note that each call use one stack location, procedure call take
07dd0a100834020164020f2151003cde
more (depend on number of parameters and temporary variables it use).
Notes :
task that run externally (from host) also can ended by ret command. task that run
07dd0a100834020164020f2151003cde
after reset (by using the directive #task/n) should not ended by ret (only by halt)
If you want to pass parameters to subroutine you should use procedures instead
of using the call/ret mechanism 07dd0a100834020164020f2151003cde

2.2.6 exitproc
Format:
07dd0a100834020164020f2151003cde

exitproc;
Exit from procedure. Normally program exit
07dd0a100834020164020f2151003cde from procedure when arrive to the end that
close the do after the procedure header. Use this to exit in the middle of the procedure,
example:
proc func1( long flag) do
07dd0a100834020164020f2151003cde

if(flag=-1) exitproc; // exit func1 procedure in the middle
07dd0a100834020164020f2151003cde

end; // exit from procedure in the end
07dd0a100834020164020f2151003cde

2.2.7 Task commands


07dd0a100834020164020f2151003cde

2.2.7.1 Run
Run is similar to call but the call is executed by other task then the one that exe-
07dd0a100834020164020f2151003cde
cuted the run command. The run command allow one task to order other task to
execute subroutine
1. run <label> <var>
07dd0a100834020164020f2151003cde
2. run < <var> > <var>
The var is variable that get the task number that will run the function label this var
is the parameter that should supplied to kill, cont, stop, command.
07dd0a100834020164020f2151003cde

21
07dd0a100834020164020f2151003cde
07dd0a100834020164020f2151003cde

MEGA-FAB
07dd0a100834020164020f2151003cde Number: 0000 0000 0001

Sheet 22nd of 45
PDL
07dd0a100834020164020f2151003cde

Run can used indirect addresses (case 3), example


v1= <lable>;
07dd0a100834020164020f2151003cde

run <label> v2;


A label name start with _ is listed in *.lbl file and so recognized by host, and
07dd0a100834020164020f2151003cde
therefore task can created by host to start from this label.
Running task can retrieved its own task number from the system variable
tasknum
07dd0a100834020164020f2151003cde

2.2.7.2 Kill, stop, cont


07dd0a100834020164020f2151003cde
kill <var/constant > // the task will go to idle mode
stop <var/constant > // the task will stop till cont command
07dd0a100834020164020f2151003cde
cont<var/constant > // the task will continue to run
The <var/constant> is the task number and may be retrieved from the run command
Example : 07dd0a100834020164020f2151003cde

#task/0
run subr1 v1; // subr1 will be executed by the first idle task, its
07dd0a100834020164020f2151003cde
// task number will stored in v1
call t0func1; // t0funac1 will be executed by task 0 immediately after the run
07dd0a100834020164020f2151003cde

kill v1 // kill the running function subr1
07dd0a100834020164020f2151003cde
Notes:
For kill command the task number is checked that is in the range 0...39
The argument for stop and cont
07dd0a100834020164020f2151003cde should be constant or simple variable. I.e. the variable
should not be indexed or indirect, for example:
stop var[5] - will generate compile error .
07dd0a100834020164020f2151003cde
2.2.7.3 Lock / unlock
Syntax:
07dd0a100834020164020f2151003cde
lock;
unlock;
07dd0a100834020164020f2151003cde
The locks command increment the task lock variable by 1. The unlock decrement task_lock by 1
(and clipped it to 0). When the task manager in the DSP interpreter see that variable task_lock is
not equal to zero the next task that will be execute is the same task. In other words, the section
between lock and unlock is executed by one task without interrupting by other active tasks
07dd0a100834020164020f2151003cde
Example:
The following procedure allow only one task to return, all other are killed when enter till v go back to
0. This procedure prevents07dd0a100834020164020f2151003cde
more then one task run the function that calls it in the beginning. Note
that in any case the host cannot run the same label more then once.
Proc mutex (long *v) do
07dd0a100834020164020f2151003cde
Lock; // use lock to avoid to more then one tasks enters here
If(*v<>0) do
07dd0a100834020164020f2151003cde

22
07dd0a100834020164020f2151003cde
07dd0a100834020164020f2151003cde

MEGA-FAB
07dd0a100834020164020f2151003cde Number: 0000 0000 0001

Sheet 23rd of 45
PDL
07dd0a100834020164020f2151003cde

Unlock;
Halt; // if *v<>0 the resource represent by
07dd0a100834020164020f2151003cde *v is busy, so kill the task
End;
*v=1
07dd0a100834020164020f2151003cde
unlock;
end
07dd0a100834020164020f2151003cde
//===============================
#short flag;
flag=0; 07dd0a100834020164020f2151003cde

..
_func1: // this code should not executes by more then one task in the same time
07dd0a100834020164020f2151003cde
mutex(&flag); // inshore only one task to run _func1
. // function body
07dd0a100834020164020f2151003cde
flag=0; // Now other tasks allowed to enter to this function
ret;
07dd0a100834020164020f2151003cde
Note that in this example lock/unlock protect the section where flag is tested and set if it found zero.
If there was not lock and unlock then if 2 tasks happen to enter in the same time to the function then
the protection was not worked.
Locked/unlocked may used to protect global variables from07dd0a100834020164020f2151003cde
accessed in the same time by more then
one task (as in this example the global variable flag). However temporary variables (these which
declared within procedure) not need any multi access protection, because each task has its own
temporary variables (which are stack variables).
07dd0a100834020164020f2151003cde

Notes:
07dd0a100834020164020f2151003cde
Nested locks are allowed, where each lock should be satisfy by unlock.
Dont put sleep commands in protected sections by lock/unlock
07dd0a100834020164020f2151003cde

2.2.8 Loop
07dd0a100834020164020f2151003cde
Format:
loop( <local variable|constant> ) do
07dd0a100834020164020f2151003cde
.
.
end; 07dd0a100834020164020f2151003cde
The loop command executes the block commands (from 'do' to 'end') n times,
where n is specified by a local short variable or a constant; n is interpreted as
unsigned number 07dd0a100834020164020f2151003cde
and if n=0 the block will be executed 65536 times.
If the argument is long, only the LSB word is taken.
Example: 07dd0a100834020164020f2151003cde
nk=20;
loop(nk) do // execute block 20 times
07dd0a100834020164020f2151003cde

23
07dd0a100834020164020f2151003cde
07dd0a100834020164020f2151003cde

MEGA-FAB
07dd0a100834020164020f2151003cde Number: 0000 0000 0001

Sheet 24th of 45
PDL
07dd0a100834020164020f2151003cde

.
pos1=pos2;
07dd0a100834020164020f2151003cde

loop(100) do // execute block 100 times


.
07dd0a100834020164020f2151003cde
.
end;
07dd0a100834020164020f2151003cde
end;

The maximum number07dd0a100834020164020f2151003cde


of nested loop (together with call commands) is defined by
stack size for each task.

07dd0a100834020164020f2151003cde

2.2.9 IF and Else


If and else commands take one of the following formats:
07dd0a100834020164020f2151003cde
1. if (conditions expression ) command;
2. if (conditions expression) do
07dd0a100834020164020f2151003cde
.
end;
3. if (conditions expression) do 07dd0a100834020164020f2151003cde

.
else do
07dd0a100834020164020f2151003cde
.
end;
07dd0a100834020164020f2151003cde
Where conditions expression is logic combination of several conditions or only
one condition i.e. the condition has the following format:
(Condition1 [&/| contidion2] [&/| contidion3]....)
07dd0a100834020164020f2151003cde
The conditions expressions may be nested using ( ). And can be inverted using ~
Only the line length limits the number of conditions.
07dd0a100834020164020f2151003cde
In case 1 not allowed wait or state assignment or another if, while, till, loop
command.
Condition takes one of the following formats:
07dd0a100834020164020f2151003cde

1. <state>
2. ~<state> (i.e. Not state )
07dd0a100834020164020f2151003cde
3. < <var> > var is variable that contain state number
4. < ~<var> >
07dd0a100834020164020f2151003cde
5. <var> <relation> <constant>
6. <var> <relation> <var>
07dd0a100834020164020f2151003cde
7 . ~(conditions expression)

07dd0a100834020164020f2151003cde

24
07dd0a100834020164020f2151003cde
07dd0a100834020164020f2151003cde

MEGA-FAB
07dd0a100834020164020f2151003cde Number: 0000 0000 0001

Sheet 25th of 45
PDL
07dd0a100834020164020f2151003cde

In cases (5) and (6) variables must be local variables.


In cases (3) and (4) variables assume to store state
07dd0a100834020164020f2151003cde address (bit number).

Relation can be one of the following:


07dd0a100834020164020f2151003cde
= ( equal )
> ( greater than)
07dd0a100834020164020f2151003cde
< ( less than )
>= ( greater or equal than)
<= ( less or 07dd0a100834020164020f2151003cde
equal than )
<> ( not equal)
-> single bit test 07dd0a100834020164020f2151003cde

TOUT ( time out detection, see below a full description of this operator )
07dd0a100834020164020f2151003cde

The maximum level of nested if or else (together with loop, while, commands) is
limit by the compiler to 200. The '&' is for logic 'and' of the conditions, the '|' is for
07dd0a100834020164020f2151003cde
logic 'or', the ~ is for logic inverting.
Example:
07dd0a100834020164020f2151003cde

pos2=-100000;
if(pos1>100000 | pos1<pos2)
07dd0a100834020164020f2151003cde do
if (pos1>1000000) do
abspos=pos2;
07dd0a100834020164020f2151003cde
else do
abspos=-pos2;
07dd0a100834020164020f2151003cde
end;
if(LEFT_LIM) call sub1;
07dd0a100834020164020f2151003cde
end;
#short st;;
st=07dd0a100834020164020f2151003cde
<LEFT_LIM>;
if ( <st> ) pos2=pos2+100; // if condition assignment
if(~<st> ) pos2=pos2-100
07dd0a100834020164020f2151003cde
if (pos>1000) call func1; // if condition call
if (pos>1000) goto label1; // if condition jump
07dd0a100834020164020f2151003cde
if (pos>1000) func1(pos,300); // if condition call procedure
if (pos>1000) sleep 100 ; // if condition sleep
. 07dd0a100834020164020f2151003cde

if (pos>1000) ret; // if condition ret


if(pos>1000 & ( pos2<900 |~<st>)07dd0a100834020164020f2151003cde
) sleep 1000; // nesting conditions

25
07dd0a100834020164020f2151003cde
07dd0a100834020164020f2151003cde

MEGA-FAB
07dd0a100834020164020f2151003cde Number: 0000 0000 0001

Sheet 26th of 45
PDL
07dd0a100834020164020f2151003cde

if( ~(pos>1000 & ( pos2<900 |~<st>)) ) sleep 1000; // all expression is inverted
if( (st1 &~st2) | ( ~st1 & st2) ) call sub1; // i.e st1
07dd0a100834020164020f2151003cde xor st2
if( ~((st1 &~st2) | ( ~st1 & st2)) ) call sub1; // i.e st1 not xor st2
if( var1->5) // test bit 5 of variable var1
07dd0a100834020164020f2151003cde
if( var1->var2) // test bit number define by var2 of variable var1

07dd0a100834020164020f2151003cde
Notes:
The 'else' replaces the 'end' closes the 'do' block of 'if ' command, and it has the
same nesting level07dd0a100834020164020f2151003cde
as the 'if'.
In case 1 (if (conditions) command;) not allowed else.
In case 1 the all sentence (the condition and the command) may be executed in
07dd0a100834020164020f2151003cde
one phase if the total length of the sentence is less then command buffer length.

07dd0a100834020164020f2151003cde

2.2.10 While
Format: 07dd0a100834020164020f2151003cde

While (conditions expression) do


. 07dd0a100834020164020f2151003cde
.
end;
07dd0a100834020164020f2151003cde
The conditions expression has the standard format (see if else commands). The
block from do to end is executed while the conditions are satisfied. The maximum
level of nested while (together with loop, if-else commands) is limited by the
07dd0a100834020164020f2151003cde
compiler to 200.

2.2.11 Till
07dd0a100834020164020f2151003cde
Format:
till (conditions expression);
07dd0a100834020164020f2151003cde
In this command task holds execution until the conditions are met. Example:
till(x_ref_pos[0]>20000 & ~x_run); // wait till ref_pos of motor x is grater then
20000 steps and profile of axis x not active, and then execute the next com-
07dd0a100834020164020f2151003cde
mand.

07dd0a100834020164020f2151003cde

07dd0a100834020164020f2151003cde

07dd0a100834020164020f2151003cde

07dd0a100834020164020f2151003cde

26
07dd0a100834020164020f2151003cde
07dd0a100834020164020f2151003cde

MEGA-FAB
07dd0a100834020164020f2151003cde Number: 0000 0000 0001

Sheet 27th of 45
PDL
07dd0a100834020164020f2151003cde

2.2.12 TOUT condition


07dd0a100834020164020f2151003cde
Format
if(.. v1 TOUT v2/constant)
till(.. v1 TOUT v2/constant)
07dd0a100834020164020f2151003cde
while(.. v1 TOUT v2/constant)
v1, v2 should be integer variables. Beside this TOUT condition has the same syntax has other
condition operators 07dd0a100834020164020f2151003cde
( =, >, <, <=, >=, <> ). This condition is TRUE if the following condition satisfy:
fclk-v1 >=v2
Where fclk is a 32bit integer system variable that count at 20000Hz. to invert the
07dd0a100834020164020f2151003cde
condition use the ~ (as in other condition statements ) for example:
till( ~(v1 TOUT v2) ); // wait till fclk-v1<v2
To understand the motivation of using this operator lets look at the following
07dd0a100834020164020f2151003cde
example:
#long timeout,tend;
timeout=60000; 07dd0a100834020164020f2151003cde

x_jvl=2000; // move axis in infinite move


tend=fclk+timeout; // calculate end time 07dd0a100834020164020f2151003cde
till ( x_home | fclk>=tend ); //wait till arrived home limit or pass 3 seconds
x_stop_m=1; // stop axis
07dd0a100834020164020f2151003cde
if (fclk>=tend ) do
printl/101(ERROR time out when search home limit);
07dd0a100834020164020f2151003cde
else do
printl/101(OK, found home limit);
end;
07dd0a100834020164020f2151003cde

This code work ok till the fclk counter wrap around from the biggest 32bit integer value (2^31-1) to the
smaller negative 32bit integer value (-2^31). fclk wrapping around happen first time after about 30
07dd0a100834020164020f2151003cde
hours and every next 60 hours. When fclk wrap around there is a risk that the till command will not
execute properly. One way to overcome this problem is to replace the till command by if command
and a loop:
07dd0a100834020164020f2151003cde
#long timeout,t0, tmp;
timeout=60000;
x_jvl=2000;07dd0a100834020164020f2151003cde
// move axis in infinite move
t0=fclk; // save start time
waitloop
07dd0a100834020164020f2151003cde
tmp=fclk-t0; // calculate how mach time pass from t0
if ( ~x_home & tmp < timeout ) goto waitloop; // if not home and no time out goto loop
x_stop_m=1; // stop axis 07dd0a100834020164020f2151003cde
if (tmp>=timeout ) do
printl/101(ERROR time out when search home limit);
07dd0a100834020164020f2151003cde

else do
printl/101(OK, found home limit);
07dd0a100834020164020f2151003cde

27
07dd0a100834020164020f2151003cde
07dd0a100834020164020f2151003cde

MEGA-FAB
07dd0a100834020164020f2151003cde Number: 0000 0000 0001

Sheet 28th of 45
PDL
07dd0a100834020164020f2151003cde

end;
This07dd0a100834020164020f2151003cde
code will work ok even when fclk wrap around, but it need 2 commands to execute in a con-
tinues loop. so the home state is tested only every 2 commands ( and not each commands as in
till ).
So it is recommended to use the TOUT operator as follow
07dd0a100834020164020f2151003cde

#long timeout, t0;


07dd0a100834020164020f2151003cde
timeout=60000;
x_jvl=2000; // move axis in infinite move
07dd0a100834020164020f2151003cde
t0=fclk; // save start time
till ( x_home | t0 TOUT timeout ); //wait till arrived home limit or pass 3 seconds
x_stop_m=1; // stop axis 07dd0a100834020164020f2151003cde
if ( t0 TOUT timeout ) do
printl/101(ERROR time out when search home limit);
07dd0a100834020164020f2151003cde
else do
printl/101(OK, found home limit);
07dd0a100834020164020f2151003cde
end;

07dd0a100834020164020f2151003cde

07dd0a100834020164020f2151003cde

07dd0a100834020164020f2151003cde

07dd0a100834020164020f2151003cde

07dd0a100834020164020f2151003cde

07dd0a100834020164020f2151003cde

07dd0a100834020164020f2151003cde

07dd0a100834020164020f2151003cde

07dd0a100834020164020f2151003cde

07dd0a100834020164020f2151003cde

28
07dd0a100834020164020f2151003cde
07dd0a100834020164020f2151003cde

MEGA-FAB
07dd0a100834020164020f2151003cde Number: 0000 0000 0001

Sheet 29th of 45
PDL
07dd0a100834020164020f2151003cde

2.3 Interrupts
In PDL it can implement Interrupts, that is, a state toggle event trigger new task to run. Example:
07dd0a100834020164020f2151003cde

assume that need to run a piece of program as a response of any state go on. Then you may write
something like this ( without using Interrupts):
07dd0a100834020164020f2151003cde
_handle_in1:
till( in1); // wait till in1 turn on
.. do something07dd0a100834020164020f2151003cde
here as a response to in1 go active
till(~in1); // wait till in1 turn off
goto _handle_in1; 07dd0a100834020164020f2151003cde
note that _handle_in1 is trigger to run from the initialization or from Host and run all the time.
The disadvantages of this method are:
07dd0a100834020164020f2151003cde
1. You spend a task that poll the state
2. The till(in1) sample the state in1 in rate of 20000/N where N is the number of total tasks that
are running ( and not sleep/stop). So in1 is sampled slower then the maximum DSP algo-
07dd0a100834020164020f2151003cde
rithm rate
3. The task which run _handle_in1 slow all other tasks running speed.
07dd0a100834020164020f2151003cde
4. The response (i.e. execute the command follow till ) to in1 go on, may be delayed up to
N*phase
Now implement this with interrupt.
07dd0a100834020164020f2151003cde
#task/0; // one of the initialization tasks that run after reset

07dd0a100834020164020f2151003cde
intrpmake in1 _handle_in1 ; // create interrupt, _handle_in1 will run only when in1 go on

07dd0a100834020164020f2151003cde
halt; // end of initialization
_handle_in1: // a new task will start to run from here 2 phases after in1 go on
.. do something here as a response to in1 go
07dd0a100834020164020f2151003cde active
till(~in1); // wait till in1 turn off
intrpon in1 // the in1 interrupt is disabled automatically when interrupt handler execute, so
07dd0a100834020164020f2151003cde
enable it again to be ready for next time
ret; // task termination
07dd0a100834020164020f2151003cde
The advantages of interrupt method are:
1. handler task run only when needed. So no slow the other tasks with extra task that only do
polling on a07dd0a100834020164020f2151003cde
state. Note that in1 is sampled with the maximum rate (20000Hz) and this is
done efficiency in the MDP.
2. The response to the state is only 2 phases, no meter how many tasks are running in the
same time. If critical then the first command may be lock (or high priority set to this task)
07dd0a100834020164020f2151003cde

07dd0a100834020164020f2151003cde

07dd0a100834020164020f2151003cde

29
07dd0a100834020164020f2151003cde
07dd0a100834020164020f2151003cde

MEGA-FAB
07dd0a100834020164020f2151003cde Number: 0000 0000 0001

Sheet 30th of 45
PDL
07dd0a100834020164020f2151003cde

2.3.1 intrpmake
07dd0a100834020164020f2151003cde
syntax:
intrpmake <state name> <label>;
This command create new interrupt. So when the state define will go on a new task will run from the
07dd0a100834020164020f2151003cde
label specified.
Examples:
intrpmake in1 _in1_hndl; // task will start to run from _in1_hndl when in1 state go on
07dd0a100834020164020f2151003cde
You can define opposite polarity to state:
intrpmake ~in1 _in1_hndl; // task will start to run from _in1_hndl when in1 state go off
07dd0a100834020164020f2151003cde
The state can be define indirectly:
v1=<in1>;
intrpmake ~<v1> _in1_off; // task will start to run from _in1_off when in1 state go off
07dd0a100834020164020f2151003cde
Notes
-Number of interrupts are limited by the size of the intrp_table array . each 2 items in this array are
allocate for each interrupt , so 07dd0a100834020164020f2151003cde
maximum number of interrupts = sizeof ( intrp_table )/2
If you try to add more by interrupts while the table is full nothing will happen and the intrpmake will
not create new interrupt. You can test the number of interrupts already created by reading the
07dd0a100834020164020f2151003cde
variable intrp_num
- When interrupt happen it become disabled automatically ( to avoid multi interrupts when the state
is in constant in the active level. You can enable it again by07dd0a100834020164020f2151003cde
using the command intrpon.
- When any task is in lock state no interrupt will execute. It will be delayed after the task that is
locked will unlocked.
07dd0a100834020164020f2151003cde
2.3.2 intrpon/intrpoff
syntax:
07dd0a100834020164020f2151003cde
intrpon <state name>;
intrpoff <state name>;
intrpon/ intrpoff enable/disable interrupts already created. You may use intrpon in the end of in-
07dd0a100834020164020f2151003cde
terrupt handler to enable it again for the next event.
If the state define not exist as an interrupt state, then nothing happen. The state here use as iden-
tifier of the interrupt .
07dd0a100834020164020f2151003cde
examples:
intrpon in1;
intrpoff in1;
07dd0a100834020164020f2151003cde
v1=<in1>;
intrpon <v1>;
07dd0a100834020164020f2151003cde

2.3.3 intrpremove
07dd0a100834020164020f2151003cde
syntax:
intrpremove <state name>;
intrpremove delete a interrupt from the intrp_table. Use it when no need it and to free place for
07dd0a100834020164020f2151003cde
other interrupt
If the state define not exist as an interrupt state, then nothing happen. The state here use as iden-
tifier of the interrupt . 07dd0a100834020164020f2151003cde

30
07dd0a100834020164020f2151003cde
07dd0a100834020164020f2151003cde

MEGA-FAB
07dd0a100834020164020f2151003cde Number: 0000 0000 0001

Sheet 31st of 45
PDL
07dd0a100834020164020f2151003cde

examples:
intrpremove in1;
07dd0a100834020164020f2151003cde
v1=<in1>;
intrpremove <v1>;
07dd0a100834020164020f2151003cde

07dd0a100834020164020f2151003cde

07dd0a100834020164020f2151003cde

07dd0a100834020164020f2151003cde

07dd0a100834020164020f2151003cde

07dd0a100834020164020f2151003cde

07dd0a100834020164020f2151003cde

07dd0a100834020164020f2151003cde

07dd0a100834020164020f2151003cde

07dd0a100834020164020f2151003cde

07dd0a100834020164020f2151003cde

07dd0a100834020164020f2151003cde

07dd0a100834020164020f2151003cde

07dd0a100834020164020f2151003cde

07dd0a100834020164020f2151003cde

07dd0a100834020164020f2151003cde

31
07dd0a100834020164020f2151003cde
07dd0a100834020164020f2151003cde

MEGA-FAB
07dd0a100834020164020f2151003cde Number: 0000 0000 0001

Sheet 32nd of 45
PDL
07dd0a100834020164020f2151003cde

2.4 Build in Functions


Functions are built-in routines, which get arguments,
07dd0a100834020164020f2151003cde do some process on them
and store the result in variable. Function may be considered as another type of
assignment statement (not like procedures that are user defined and not return
value). The general format of it is:
07dd0a100834020164020f2151003cde
<var>=func_name(arg_1,arg_2,...arg_n);
arg_1... arg_n must be local variables where the last argument can be also a
constant. 07dd0a100834020164020f2151003cde
Unless other specified variables can be short or long length. The
number of the arguments depends on the function definition.

2.4.1 Max and Min07dd0a100834020164020f2151003cde


The max and min function have the following format:
<var>=max(<var>,<var/constant>);
07dd0a100834020164020f2151003cde
<var>=min(<var>,<var/constant>);
The max and min functions may replace an if, else statement, for example the
statement 07dd0a100834020164020f2151003cde

if(var1>var2) do var3=var1; else do var3=var2; end;


Can be replaced by 07dd0a100834020164020f2151003cde
var3=max(var1,var2);
And the statement
07dd0a100834020164020f2151003cde
if(var1>var2) do var3=var2; else do var3=var1; end;
Can be replaced by
07dd0a100834020164020f2151003cde
var3=min(var1,var2);

2.4.2 Abs
07dd0a100834020164020f2151003cde
Format:
<var>=abs(<var/constant>);
This function takes the absolute value of the argument for example the statement:
07dd0a100834020164020f2151003cde

if (var2>0) do var1=var2; else do var1=-var2; end;


Can be replace by:
07dd0a100834020164020f2151003cde
var1=abs(var2);

2.4.3 Unsign
07dd0a100834020164020f2151003cde
Format:
<var1>=unsign(<var2/constant>);
07dd0a100834020164020f2151003cde
This function assign to the destination variable var1 the source variable
(var2/constant) without sign extended. This command is useful to assign to long
variable a short unsigned variable. The following example illustrate the different of
07dd0a100834020164020f2151003cde
using this function from simple assignment:
#long lng1;
#short srt1; 07dd0a100834020164020f2151003cde

srt1= -1;
lng1= srt1; // lng1 is assign to -1
07dd0a100834020164020f2151003cde

32
07dd0a100834020164020f2151003cde
07dd0a100834020164020f2151003cde

MEGA-FAB
07dd0a100834020164020f2151003cde Number: 0000 0000 0001

Sheet 33rd of 45
PDL
07dd0a100834020164020f2151003cde

lng1= unseen(srt1); // lng1 is assign to 65535


07dd0a100834020164020f2151003cde
2.4.4 Sign
Format:
07dd0a100834020164020f2151003cde
<var1>=sign(<var2/constant>);
If the argument positive the result is 1, if the argument negative the result is 1 and if the argument
equal zero the result is 0.
07dd0a100834020164020f2151003cde

2.3.5 sin, cos


Format:
07dd0a100834020164020f2151003cde
<var1>=sin(<var2/constant>);
<var1>=cos(<var2/constant>);
The argument is in radian units. 07dd0a100834020164020f2151003cde

2.3.6 sqrt
07dd0a100834020164020f2151003cde
Format:
<var1>=sqrt(<var2/constant>);
var1 get the square root of var2. If the argument is07dd0a100834020164020f2151003cde
negative also the result will be negative.

2.3.7 divi
Format: 07dd0a100834020164020f2151003cde

<var1>=divi(<var2>, <var3/constant>);
var1 get the integer part ( not rounded ) of var2/var3
07dd0a100834020164020f2151003cde
The following example illustrate the different of divi from standard divide operation.
#long r, p;
#float f;
07dd0a100834020164020f2151003cde
p=11;
f=p/4; // f=3.75
07dd0a100834020164020f2151003cde
r=p/4; // r=4 ( after rounding )
f=divi(p,4); // f=3
r=divi(p,4); // r=3
07dd0a100834020164020f2151003cde

2.3.8 shift
Format: 07dd0a100834020164020f2151003cde

<var1>=shift(<var2>, <var3/constant>);
this command take07dd0a100834020164020f2151003cde
var2 as integer and shift it n bits where the value n is specified by the last ar-
gument (var3/constant ). if n>0 then shift left, if n<0 then shift right.
Example:
#long r1,r2,rs1, rs2; 07dd0a100834020164020f2151003cde

r1=0x000000F0;
rs1=1; rs2=-2 07dd0a100834020164020f2151003cde
r2=shift(r1, rs1); // r2 will be set to 0x000001E0
r2=shift(r1, rs2); // r2 will be set to 0x0000003C
07dd0a100834020164020f2151003cde

33
07dd0a100834020164020f2151003cde
07dd0a100834020164020f2151003cde

MEGA-FAB
07dd0a100834020164020f2151003cde Number: 0000 0000 0001

Sheet 34th of 45
PDL
07dd0a100834020164020f2151003cde

r2=shift(r1, -8); // r2 will be set to 0x00000000


r2=shift(r1, -4); // r2 will be set to 0x0000000F
07dd0a100834020164020f2151003cde

r2=shift(r1, 0); // r2 will be set to 0x000000F0 (r2=r1)


r2=shift(r1, 4); // r2 will be set to 0x00000F00
07dd0a100834020164020f2151003cde
r2=shift(r1, 8); // r2 will be set to 0x0000F000
r2=shift(r1,12); // r2 will be set to 0x000F0000
07dd0a100834020164020f2151003cde
r2=shift(r1, 24); // r2 will be set to 0xF0000000
r2=shift(r1, 27); // r2 will be set to 0x80000000
07dd0a100834020164020f2151003cde
2.3.9 bitset, bitclr, bittog
Format:
07dd0a100834020164020f2151003cde
<var1>=bitset(<var2>, <var3/constant>);
<var1>=bitclr(<var2>, <var3/constant>);
<var1>=bittog(<var2>, <var3/constant>);07dd0a100834020164020f2151003cde
bitset set specific bit in variable (bit number specified by the last argument var3/constant).
bitclr clear specific bit in variable.
07dd0a100834020164020f2151003cde
bittog toggle specific bit in variable.
Example:
07dd0a100834020164020f2151003cde
#Long v1,v2
v1= bitset (v1, 0); // v1=0x00000001
07dd0a100834020164020f2151003cde
v1= bitset (v1, 1); // v1=0x00000003
v1= bitclr (v1, 0); // v1=0x00000002
v2=31;
07dd0a100834020164020f2151003cde
v1= bitset (v1, v2); // v1=0x80000002
v1= bittog (v1, 4); // v1=0x80000012
07dd0a100834020164020f2151003cde
v1= bittog (v1, 4); // v1=0x80000002
v1= bittog (v1, v2); // v1=0x00000002
07dd0a100834020164020f2151003cde
2.3.10 gettask
Format:
07dd0a100834020164020f2151003cde
<var1>=gettask(< <var2/constant>);
this command get variable/constant which its value is interpreted as label address, and return the
task id ( 039) which run from this label. If no task run this label then it return -1. The use of the
07dd0a100834020164020f2151003cde
label should be after it declared.
Example1:
#long taskid, var; 07dd0a100834020164020f2151003cde

_f1: // task may start run from here, by Host or by run command , or by #task directive
. 07dd0a100834020164020f2151003cde
_f2: // another label that task may start run from
.
07dd0a100834020164020f2151003cde

34
07dd0a100834020164020f2151003cde
07dd0a100834020164020f2151003cde

MEGA-FAB
07dd0a100834020164020f2151003cde Number: 0000 0000 0001

Sheet 35th of 45
PDL
07dd0a100834020164020f2151003cde

taskid = gettask( <_f1> ); // note that if put label it should be in < >
if(taskid<> -1) printl/103( task number %ld run _f1 ,taskid);
07dd0a100834020164020f2151003cde

if(taskid= -1) printl/103( no task run _f1 );


var= <_f2>; // assign label to variable
07dd0a100834020164020f2151003cde
taskid = gettask( var );
printl/103( task number %ld run _f2 ,taskid);
07dd0a100834020164020f2151003cde

Example2 ( with procedure )


proc printtaskid( long label 07dd0a100834020164020f2151003cde
) do
#long id;
id=gettask(label); 07dd0a100834020164020f2151003cde
printl/103( task number %ld label %08x,id, label);
end;
07dd0a100834020164020f2151003cde
..
printtaskid( <_f1> );
07dd0a100834020164020f2151003cde
printtaskid( <_f2> );

If you use the id return from gettask to kill/stop/cont this task it is recommended to use lock unlock
07dd0a100834020164020f2151003cde
to avoid task terminated ( and maybe run other label ) after run gettask but before call kill, ex-
ample:
lock;
07dd0a100834020164020f2151003cde

taskid= gettask( <_f1> );


kill taskid;
07dd0a100834020164020f2151003cde
unlock;

07dd0a100834020164020f2151003cde
Notes:
If the return value from gettask is -1 ( so no task is running this label ) then doing kill/cont/stop to -1
value will do nothing. So it is not necessary to test that return value is not -1 before execute
07dd0a100834020164020f2151003cde
kill/stop/cont.
If more then one task execute the same label then the smallest task number is returned.
07dd0a100834020164020f2151003cde

2.3.11 bytesep
07dd0a100834020164020f2151003cde
Format:
<var1>=bytesep(<var2>, <var3/constant>);
var1 destination variable/array
07dd0a100834020164020f2151003cde
var2 source variable/array
var3 n =number of bytes to convert (must be long/short type)
07dd0a100834020164020f2151003cde

07dd0a100834020164020f2151003cde

35
07dd0a100834020164020f2151003cde
07dd0a100834020164020f2151003cde

MEGA-FAB
07dd0a100834020164020f2151003cde Number: 0000 0000 0001

Sheet 36th of 45
PDL
07dd0a100834020164020f2151003cde

This function takes the variable var2 and converts it to bytes into variable var1. More then one
variable may be converting in one command. Number of variables (nv) that will be converting is:
07dd0a100834020164020f2151003cde
nv=n/2 if var2 is short type (16 bit )
nv=n/4 if var2 is long/float type (32 bit )
I.e. to convert only one variable, set var3=4 if var2 is long/float type, and set var3=2 if var2 is short
07dd0a100834020164020f2151003cde
type
Example:
#long l1[3]; 07dd0a100834020164020f2151003cde

#short s1[12];
l1={0x01020304,0x11223344,0xaabbccdd}; // init array l1
07dd0a100834020164020f2151003cde
s1=bytesep(l1,12);
halt;
The contain of s1[011] array after07dd0a100834020164020f2151003cde
the execute bytesep command will be:
01, 02, 03, 04, 11, 22, 33, 44, aa, bb, cc, dd
The time execution for this command depend on number of bytes according to:
07dd0a100834020164020f2151003cde
np=1+var3/16; (np=number of phases )
So if number of bytes less equal to 16 then only one phase need to complete the command.
Notes: 07dd0a100834020164020f2151003cde
var2 (the source) can be long/short or float type, however for var1 it prefer to choose as a short type
as only bytes will be store there.
Var3 value is not limited but you should be aware to the array size of the source and the destination
07dd0a100834020164020f2151003cde
to avoid memory exceed. If var3<=0 then no effect to this command. var3 value should be even. If
var3 is odd then it will decrement by one.
07dd0a100834020164020f2151003cde

2.3.12 bytecomb
Format:
07dd0a100834020164020f2151003cde

<var1>=bytecomb(<var2>, <var3/constant>);
var1 destination variable/array
07dd0a100834020164020f2151003cde
var2 source variable/array
var3 n =number of bytes to combined (must be long/short type)
07dd0a100834020164020f2151003cde

07dd0a100834020164020f2151003cde

07dd0a100834020164020f2151003cde

07dd0a100834020164020f2151003cde

07dd0a100834020164020f2151003cde

07dd0a100834020164020f2151003cde

36
07dd0a100834020164020f2151003cde
07dd0a100834020164020f2151003cde

MEGA-FAB
07dd0a100834020164020f2151003cde Number: 0000 0000 0001

Sheet 37th of 45
PDL
07dd0a100834020164020f2151003cde

This function do the opposite operation of bytesep i.e. take the source var2 witch contain bytes and
combined them back to variables. Number of variables (nv) that will be combined is:
07dd0a100834020164020f2151003cde
nv=n/2 if var1 is short type (16 bit )
nv=n/4 if var1 is long/float type (32 bit )
I.e. to combine only one variable, set var3=4 if var1 is long/float type, and set var1=2 if var2 is short
07dd0a100834020164020f2151003cde
type

07dd0a100834020164020f2151003cde
Example (copy l1 array into l2 array via s1 byte array using: bytesep bytecomb):
#long l1[3],l2[3];
#short s1[12];
07dd0a100834020164020f2151003cde
l1={0x01020304,0x11223344,0xaabbccdd}; // init array l1
s1=bytesep(l1,12); // convert l1 into bytes in s1
l2=bytecomb(s1,12); // convert s107dd0a100834020164020f2151003cde
bytes back to variables into l2 array, so now l2[0...2]=l1[02]
halt;
The time execution for this command depends on number of bytes according to: (as in bytesep)
07dd0a100834020164020f2151003cde
np=1+var3/16; (np=number of phases )
Notes:
var2 (the source) probably will be short type, var1 07dd0a100834020164020f2151003cde
can be short/long/float type
Var3 value is not limited but you should be aware to the array size of the source and the destination
to avoid memory exceed. If var3<=0 then no effect to this command. var3 value should be even. If
var3 is odd then it will decrement by one. 07dd0a100834020164020f2151003cde

2.3.13 memcpy
Format:
07dd0a100834020164020f2151003cde
<var1>=memcpy(<var2>, <var3/constant>);
var1 destination variable/array
07dd0a100834020164020f2151003cde
var2 source variable/array
var3 n =number variables to copy (must be long/short type)
07dd0a100834020164020f2151003cde
This function copy one array to other array. It is mach faster to copy arrays with memcpy then
perform a loop of assignments. This function does not do type casting between float to long/short.
i.e. var1 and var2 should be both float or long/short
07dd0a100834020164020f2151003cde

Example (copy l1 array into l2):


07dd0a100834020164020f2151003cde
#long l1[3],l2[3];

07dd0a100834020164020f2151003cde

07dd0a100834020164020f2151003cde

07dd0a100834020164020f2151003cde

07dd0a100834020164020f2151003cde

37
07dd0a100834020164020f2151003cde
07dd0a100834020164020f2151003cde

MEGA-FAB
07dd0a100834020164020f2151003cde Number: 0000 0000 0001

Sheet 38th of 45
PDL
07dd0a100834020164020f2151003cde

l1={0x01020304,0x11223344,0xaabbccdd}; // init array l1


l2=memcpy(l1,3); // copy l1 array to l2
07dd0a100834020164020f2151003cde
halt;
The time execution for this command depend on number of variables to be copy according to:
07dd0a100834020164020f2151003cde
np=1+var3/20; (np=number of phases )
Notes:
Var3 value is not limited but you should be aware to the array size of the source and the destination
07dd0a100834020164020f2151003cde
to avoid memory exceed. If var3<=0 then no effect to this command.

2.3.14 memset 07dd0a100834020164020f2151003cde


Format:
<var1>=memset(<var2>, <var3/constant>);
var1 destination variable/array 07dd0a100834020164020f2151003cde

var2 source variable value


var3 n =number variables to set (must be07dd0a100834020164020f2151003cde
long/short type)
This function set all array to one value var2. It is mach faster to set arrays with memset then perform
a loop of assignments. This function does not do type casting between float to long/short. i.e. var1
and var2 should be both float or long/short 07dd0a100834020164020f2151003cde

Example (clear array l1):


07dd0a100834020164020f2151003cde
#long l1[3],t;
t=0;
07dd0a100834020164020f2151003cde
l1=memset( t ,3); // clear array l1
halt;
The time execution for this command depend
07dd0a100834020164020f2151003cde on number of variables to be set according to:
np=1+var3/40; (np=number of phases )
Notes:
07dd0a100834020164020f2151003cde
Var3 value is not limited but you should be aware to the array size of the source to avoid memory
exceed. If var3<=0 then no effect to this command.

2.3.15 memmin, memmax


07dd0a100834020164020f2151003cde

Format:
<var1>=memmin(<var2>, <var3/constant>);
07dd0a100834020164020f2151003cde
<var1>=memmax(<var2>, <var3/constant>);

07dd0a100834020164020f2151003cde
var1 destination variable
var2 source array
var3 n =number variables07dd0a100834020164020f2151003cde
in the array (must be long/short type)
These functions find minimum/maximum of array. It is mach faster use these functions then per-
forms a loop. These functions do type casting between float to long/short, i.e. var1 and var2 may not
be the same type 07dd0a100834020164020f2151003cde

Example
#long l1[3],mina,maxa; 07dd0a100834020164020f2151003cde

38
07dd0a100834020164020f2151003cde
07dd0a100834020164020f2151003cde

MEGA-FAB
07dd0a100834020164020f2151003cde Number: 0000 0000 0001

Sheet 39th of 45
PDL
07dd0a100834020164020f2151003cde

l1={4,11,8};
mina=memmin( l1 ,3); // mina=4
07dd0a100834020164020f2151003cde
maxa=memmax( l1 ,3); // maxa=11
halt;
07dd0a100834020164020f2151003cde
The time execution for this command depend on array size (var3):
np=1+var3/40; (np=number of phases )
Notes: 07dd0a100834020164020f2151003cde
Var3 value is not limited but you should be aware to the array size of the source to avoid memory
exceed. If var3<=0 then no effect to this command.
07dd0a100834020164020f2151003cde
2.3.16 memsum
Format:
07dd0a100834020164020f2151003cde
<var1>=memsum(<var2>, <var3/constant>);
var1 destination variable
var2 source array 07dd0a100834020164020f2151003cde
var3 n =number variables in the array (must be long/short type)
This function calculate array sum. It is mach faster use this function then performs a loop. This
07dd0a100834020164020f2151003cde
function do type casting between float to long/short. i.e. var1 and var2 may not be the same type
Example (find average):
#long l1[3], avr; 07dd0a100834020164020f2151003cde

l1={2,11,8};
avr=memsum( l1 ,3); // avr=21
07dd0a100834020164020f2151003cde
avr=avr/3; // avr=7
halt;
07dd0a100834020164020f2151003cde
The time execution for this command depend on array size (var3):
np=1+var3/40; (np=number of phases )
07dd0a100834020164020f2151003cde
Notes:
Var3 value is not limited but you should be aware to the array size of the source to avoid memory
exceed. If var3<=0 then no effect to this command.
07dd0a100834020164020f2151003cde

2.5 Specials Commands


07dd0a100834020164020f2151003cde

2.5.1 Prints/ printl/ retprintl


The format of printl/prints/retprintl command is:
07dd0a100834020164020f2151003cde
prints / mode1 /mode2 ( . String..,var1,varN); // in rs485 mode
printl / mode1 /mode2 ( . String..,var1,varN);
07dd0a100834020164020f2151003cde
retprintl / mode1 /mode2 ( . String..,var1,varN); // printl and ret

07dd0a100834020164020f2151003cde
mode1 - 8 characters hex parameter which define color ,beep, print format
mode2 - 8 characters hex parameter that define event information
The following action is taken for prints (used in RS485 mode):
07dd0a100834020164020f2151003cde

39
07dd0a100834020164020f2151003cde
07dd0a100834020164020f2151003cde

MEGA-FAB
07dd0a100834020164020f2151003cde Number: 0000 0000 0001

Sheet 40th of 45
PDL
07dd0a100834020164020f2151003cde

till (s_msgnum=0); s_msgnum=K;


Where K is a running number define the massage
07dd0a100834020164020f2151003cde number starting from 1. Also the
compiler put in USER_$.MSG file a formatted line for each printl/prints command.
In RS485mode The host should poll the s_msgnum variable of each slave and if
not07dd0a100834020164020f2151003cde
equal to zero, then process the massage from the USER_$.MSG file ($ stand
for slave number) written in the line K, and after it clear the s_msgnum variable in
the slave.
The expression in the ( ) bracts has a similar format as in standard C language.
07dd0a100834020164020f2151003cde

The retprintl combine 2 commands ret and printl which executed in the same
phase. This is useful when ret terminate the task which trigger by the host, and the
printl send event to07dd0a100834020164020f2151003cde
the host about the task end. It ensure that when PC will get the
event, task already terminated (because no delay from printl to ret in retprintl, which
may be more then one phase (when printl and ret are separated) if another tasks
are running and/or other task will enter to lock state exactly after this task execute
07dd0a100834020164020f2151003cde
printl and before execute ret)
Notes:
Maximum variables allowed are 8, 07dd0a100834020164020f2151003cde
Minimum 0.
For the exact format of mode1 and mode2 parameters see the *.msg file
structure section below. The parameters are in Hex (dont put the 0x prefix here)
07dd0a100834020164020f2151003cde
Examples:
printl / 00000103 / 00000001 ( This is a test);
printl / 00000103 / 00000002( position of axis 2 is:07dd0a100834020164020f2151003cde
%g ,ref_pos[2]);
printl / 00000103 / 00000003( position of axis 2 is: %g ,ref_pos[2]);
07dd0a100834020164020f2151003cde
2.5.2 prinl/retprintl + parameters
PDL version 2+ support improved printl which send the optional parameters in real time. This printl
support:
07dd0a100834020164020f2151003cde
1. any variable/state can be printed and also variable and states that are indirected by pointer or
array index. Also local variable can be printed. Examples
#long *pn , n, ar[10];
07dd0a100834020164020f2151003cde
pnn=&pnn;
n=2;
07dd0a100834020164020f2151003cde
..
printl/103(*pnn=%08x , n=%ld , n address is %08x , ar[2]=%ld ,*pnn, n, &n, ar[n]);
printl/103(state IN1=%d , IN1);
07dd0a100834020164020f2151003cde
proc func(long v1, float f2 , instate run) do
printl/103(local variables: v1=%ld, f1=%g , state=%ld ,v1,f1, <run>);
07dd0a100834020164020f2151003cde
end;
ar="this is a test"; //assign string of 14 characters to array
printl/103(" the string is: %s ",ar[0],ar[1],ar[2],ar[3]); // print the string
07dd0a100834020164020f2151003cde
Note that to print string stored in array you should supply the exact amount of the relevant variables
contain the string where each long contain up to 4 characters.
2. From the example you can07dd0a100834020164020f2151003cde
see that values can be printed in various formats ( not only
as double float with %g). Use %g (as well as %G, %f, %e %E ) only for float values. Use %x to
print integer in Hex format and %d %u to print integer in decimal format (signed/unsigned), and
07dd0a100834020164020f2151003cde

40
07dd0a100834020164020f2151003cde
07dd0a100834020164020f2151003cde

MEGA-FAB
07dd0a100834020164020f2151003cde Number: 0000 0000 0001

Sheet 41st of 45
PDL
07dd0a100834020164020f2151003cde

%s to print a string. The convention print format is the same as for the command printf use in C
C++ Language.
07dd0a100834020164020f2151003cde
Important: You must put a space after each format identifier in order to format the value
correctly.
3. The07dd0a100834020164020f2151003cde
parameter are send in real time (To KMI or any application include MEGA-F li-
braries). In the previous PDL, parameters were read with some delay and therefore the values
read was not the same as was during printl execute.
4. The syntax of printl/retprintl in the improved version is the same as before, except that
07dd0a100834020164020f2151003cde
the user should be aware to use %g only for float variables ( variable are no more treated as all
are double type ).
5. The code length for printl/retprintl is effected from number of parameters. If no pa-
07dd0a100834020164020f2151003cde
rameter then it is 1 long word. If at list one parameter then the length is 2+k. k is sum of each
parameter length code, were if simple then 1 and if indirect then 2

2.5.2.1 Example 07dd0a100834020164020f2151003cde


Procedure that get a flag which select the appropriate printl message from a jump table:
proc printMsg(long flag, long p1, float p2) do
07dd0a100834020164020f2151003cde
if(flag<0 | flag>=5 )do
printl/101("flag=%ld out of orange 0...4",flag);
07dd0a100834020164020f2151003cde
exitproc;
end;
flag=flag*5; // length of printl+2 parameters +exitproc is 5
07dd0a100834020164020f2151003cde

goto prlabel[flag]; // indirect goto


prlabel:
07dd0a100834020164020f2151003cde
printl/103("MSG A, p1=%ld p2=%g ",p1,p2); exitproc;
printl/103("MSG B, p1=%ld p2=%g ",p1,p2); exitproc;
07dd0a100834020164020f2151003cde
printl/103("MSG C, p1=%ld p2=%g ",p1,p2); exitproc;
printl/103("MSG D, p1=%ld p2=%g ",p1,p2); exitproc;
07dd0a100834020164020f2151003cde
printl/103("MSG E, p1=%ld p2=%g ",p1,p2); exitproc;
end;
Note that flag is multiply with the printl +2 direct parameters +exitproc code length = 5 in this case,
07dd0a100834020164020f2151003cde
and all lines should be equal code length. Examples of call the procedure :
_a1:
07dd0a100834020164020f2151003cde
printMsg(0,17,4.2);
ret;
_a2: 07dd0a100834020164020f2151003cde

printMsg(1,ltest1,ff1);
ret; 07dd0a100834020164020f2151003cde
_a3:
printMsg(ltest2,ltest1,ff1);
07dd0a100834020164020f2151003cde
ret;

07dd0a100834020164020f2151003cde

41
07dd0a100834020164020f2151003cde
07dd0a100834020164020f2151003cde

MEGA-FAB
07dd0a100834020164020f2151003cde Number: 0000 0000 0001

Sheet 42nd of 45
PDL
07dd0a100834020164020f2151003cde

07dd0a100834020164020f2151003cde
2.4.2 event/ retevent
The format of event/retvent command is:
07dd0a100834020164020f2151003cde
event <constant code>;
retevent <constant code>;
This commands are07dd0a100834020164020f2151003cde
exactly as
printl/0/<constant code>();
retprintl/0/<constant code>();
07dd0a100834020164020f2151003cde
When need only to send event code you can use event / retevent instead of printl /retprintl with
mode1=0 and empty string.
Note that retevent send event like event command, and perform ret command ( as retprintl) in the
07dd0a100834020164020f2151003cde
same phase. The constant code is in Hex format. examples
event 00000001;
07dd0a100834020164020f2151003cde
event 1000000a;
retevent 00000001;
retevent 1000000a; 07dd0a100834020164020f2151003cde

2.5.3 Set, Clear, Toggle State


Syntax: 07dd0a100834020164020f2151003cde

seton <state_name | <var> >


setoff <state_name | <var> >
07dd0a100834020164020f2151003cde
toggle <state_name | <var> >
These commands modify the state specified. If the state represent an input bit or internal state (i.e.
states that are update every frame from the
07dd0a100834020164020f2151003cde DSP software) then modify the state will be only for
short time till the next internal updating. These commands used mainly for states that represent
outputs.
Example
07dd0a100834020164020f2151003cde
seton vacum_sl // turn on the vacuum solenoid
sleep 1000
07dd0a100834020164020f2151003cde
setoff vacum_sl // turn off the vacuum solenoid

07dd0a100834020164020f2151003cde
2.6 Directives
Directives are commands executed in compilation time. All directives begin with the
character ' # .
07dd0a100834020164020f2151003cde

2.6.1 Task
Format:
07dd0a100834020164020f2151003cde
#task/<n>;
This command initialized the task with the specified number to the location in the
program where this command appears. n is the task number range: 0maximum
07dd0a100834020164020f2151003cde
number of tasks -1.
Example:
07dd0a100834020164020f2151003cde

42
07dd0a100834020164020f2151003cde
07dd0a100834020164020f2151003cde

MEGA-FAB
07dd0a100834020164020f2151003cde Number: 0000 0000 0001

Sheet 43rd of 45
PDL
07dd0a100834020164020f2151003cde

.
p1=p2;
07dd0a100834020164020f2151003cde

halt;
#task/2; // task2 will start to run from this point after slave reset
07dd0a100834020164020f2151003cde
call initt2;

07dd0a100834020164020f2151003cde
Task, which is not initialized by this command, will be in idle after reset. Tasks,
which are in idling, can be operating by other tasks, which execute run command,
or externally by host. Tasks cannot be initialized more than once. Task that oper-
ates with task directive start to run from slave reset, and may be terminated by halt
07dd0a100834020164020f2151003cde
command (dont use ret for old PDL version).

2.6.2 Long /Short/Float 07dd0a100834020164020f2151003cde


Format:
#short [_ro] [_lp(v1,v2)] str_1,str_2,....str_n;
07dd0a100834020164020f2151003cde
#long [_ro] [_lp(v1,v2)] str_1,atr_2,....str_n;
#float [_ro] [_lp(v1,v2)] str_1,atr_2,....str_n;
07dd0a100834020164020f2151003cde

Where str_1...str_n can be any string (up to 15 characters, key characters are not
allowed). To declare array use the [] brackets to put the array size within them.
07dd0a100834020164020f2151003cde
Example:
#long u,k,yosi,my_array[200],tmp_array[800];
07dd0a100834020164020f2151003cde
#float _ro v1; // v1 is Read Only
#float _lp(0.5, 0.5) pgain; // pgain is level protected in the range -0.50.5
07dd0a100834020164020f2151003cde
The _ro and _lp are optional and use to define Read Only and/or Level Protected
attributes. This attributes are applied only to access to variables from host (by KMI
for example).
07dd0a100834020164020f2151003cde
These commands are used to declare user variables (long and short lengths). For
every user variable the compiler allocates an address in the user data memory in
the slave. The variable name is recognized from the point it was declared. #long,
#float and #short can appear more than once in the program. After successful
07dd0a100834020164020f2151003cde
compiling the file USER_n.VRS Float variables used 32 bit length (as long variable).
For float variables the compiler set the bit 29 to 1 in the address.
Also pointers may be declared by putting * before the variable name.
07dd0a100834020164020f2151003cde
Example:
#long v1, *pvv;
07dd0a100834020164020f2151003cde
#float ff, *pff, *pfp;
No short type pointers. Use long type pointers also to point to short type variables.
07dd0a100834020164020f2151003cde
2.6.3 define
Format:
07dd0a100834020164020f2151003cde
This command has 2 forms syntax
#define str_a str_b
07dd0a100834020164020f2151003cde

43
07dd0a100834020164020f2151003cde
07dd0a100834020164020f2151003cde

MEGA-FAB
07dd0a100834020164020f2151003cde Number: 0000 0000 0001

Sheet 44th of 45
PDL
07dd0a100834020164020f2151003cde

#define str_a(arg1,arg2argn) longstring


In the first form The compiler will replace the string
07dd0a100834020164020f2151003cde str_a with the string str_b anywhere.
This command is useful to define constants.
The second form ( Support PDL compile version 25+) allows the creation of function-like
macros. This form accepts an optional list of parameters that must appear in parentheses.
07dd0a100834020164020f2151003cde
References to the argument after the original definition replace each occurrence of
str_a( arg1,arg2argn ) with a version of the token-string argument that has actual ar-
guments substituted for formal parameters. Macro can use other already defined macros.
07dd0a100834020164020f2151003cde
Example 1:
#define ADD2(r,a,b) r = a+b;
07dd0a100834020164020f2151003cde
#define ADD3(r,a,b,c) ADD2(r,a,b) r += c;
#define ADD4(r,a,b,c,d) ADD3(r,a,b,c) r += d;
.. 07dd0a100834020164020f2151003cde

ADD4(result,var1,var2,var3,var4) // result=var1+var2+var3+var4
Macro can be written in more then one line , you should use the '\' in end of each line but the
07dd0a100834020164020f2151003cde
last line.
Example 2:
#define LONGCODE var1=var2+var3;\ 07dd0a100834020164020f2151003cde

ff1=ff2*ff3;\
someproc(var1,varb)\ 07dd0a100834020164020f2151003cde
call somelabel;\
var++;
07dd0a100834020164020f2151003cde
.
LONGCODE // execute the commands grouped by the macro LONGCODE
07dd0a100834020164020f2151003cde
Notes:
-If the macro ended with ';' then the ';' consider as part of the str_b,
Example
07dd0a100834020164020f2151003cde

#define size 10;


#long array[size]
07dd0a100834020164020f2151003cde
the array definition will replace by array[10;] which will fail in compilation so in this case you
should avoid ended the macro with ';' , that is
07dd0a100834020164020f2151003cde
#define size 10
- The syntax of the #define and #undef, #ifdef, #ifndef, #else, #endif is similar to high/low
level languages such as C,C++, Assembler .
07dd0a100834020164020f2151003cde

2.6.4 undef
Format:
07dd0a100834020164020f2151003cde
#undef string
Use to remove macro previously define by #define, example
07dd0a100834020164020f2151003cde
#define KEY STRING1

07dd0a100834020164020f2151003cde

44
07dd0a100834020164020f2151003cde
07dd0a100834020164020f2151003cde

MEGA-FAB
07dd0a100834020164020f2151003cde Number: 0000 0000 0001

Sheet 45th of 45
PDL
07dd0a100834020164020f2151003cde

#undef KEY
#define KEY STRING2
07dd0a100834020164020f2151003cde

2.6.5 ifdef ifndef else elifdef elifndef endif


07dd0a100834020164020f2151003cde
format:
#ifdef KEY
code a
07dd0a100834020164020f2151003cde
#endif
If the KEY is defined code a is compiled otherwise it ignored
#ifdef KEY 07dd0a100834020164020f2151003cde
code a
#else
07dd0a100834020164020f2151003cde
code b
#endif
If the KEY is defined code a is compiled else code b is compiled
07dd0a100834020164020f2151003cde
#ifndef KEY
code a
07dd0a100834020164020f2151003cde
#else
code b
#endif 07dd0a100834020164020f2151003cde
If the KEY is not defined code a is compiled else code b is compiled
You can use #elifdef or #elifndef to make sequence of conditions follow the starting #ifdef /
#ifndef example
07dd0a100834020164020f2151003cde
#ifdef KEY1
code a
07dd0a100834020164020f2151003cde
#elifdef KEY2
code b
#endif
07dd0a100834020164020f2151003cde
if key1 is defined only code a will be compiled, else code b will be compiled if KEY2 is de-
fined.
Every stating #ifdef/ifndef block should ended with
07dd0a100834020164020f2151003cde #endif, nested ifdef is allowed, that is the
code a and code b may composed also with other source directives/macros such as #define,
#undef, #ifdef as well as normal commands/
07dd0a100834020164020f2151003cde

2.6.6 include
Format: 07dd0a100834020164020f2151003cde

#include <filename>
When the compiler arrives to this command it begin to compile the file, which
07dd0a100834020164020f2151003cde
specified by filename. When the file compiling is finish, the compiler returns to the
original file. Up to 20 nesting includes are allowed.
Example:
07dd0a100834020164020f2151003cde
#include ..\common.h

07dd0a100834020164020f2151003cde

45
07dd0a100834020164020f2151003cde

S-ar putea să vă placă și