MOSERV - Design Specification

Rev. 2, May 12th 1997

Götz Pfeiffer

Table of contents

  1. Scope    1

  1.1. System objectives    1

  1.2. Hardware- and Software Interfaces    2

  1.3. Major Software Functions    2

  1.4. Major Design Constraints, limitations    3

  2. Reference Documents    4

  2.1. Existing software documentation    4

  2.2. Vendor Documents    4

  3. Design Description    4

  3.1. Data Description    4

  3.2. Derived Program Structure    11

  3.3. Interfaces within structure    13

  4. Modules    14

  4.1. The Main Module    14

  4.2. The Motor Utility Module    16

  4.3. The Motor Movement Module    18

  4.4. The CAN Module    19

  5. Test Provisions    20

  6. Packaging    21

  7. Special Notes    21

  7.1. Execution Time Estimations    21

  1.   Scope

  1.1.   System objectives

This document describes the MOSERV program. MOSERV is a server-type program that controls the movement of the Insertion Devices at BESSY II. It gets it's movement-commands and -parameters from the Insertion Device Control Program (IDCP).

  1.2.   Hardware- and Software Interfaces

  1.2.1.   Hardware Interfaces

MOSERV has to access the following hardware interfaces:

  1. The motor-interface

  2. MOSERV is a program that is executed on the MOCON device. This is a steering-computer that controls the movement of the Insertion Device motors. The MOCON device is connected to power electronic devices that drive the insertion device's servo-motors.
  3. The CAN bus interface

  4. The MOCON device has an interface to a CAN bus that is connected to the IOC (I/O Controller) which is the computer that runs the Insertion Device Control Program.
  5. The serial interface

  6. The MOCON device has a serial interface (parameters: 9600bd, 8N1) that is used to download software and for debug-messages printed from the software.

  1.2.2.   Software Interfaces

MOSERV has to access the following software interfaces:

  1. The MOCON programming environment:

  2. The MOCON device is programmed in the MOCON programming language. This language is similar to BASIC but provides special extensions in order to access the motors and the CAN bus. The programs are created as ASCII texts on a PC and are downloaded and executed via a special PC program, APOS. The MOCON device can also store programs in a non-volatile memory that are executed immediately after power-up.
  3. The IDCP CAN bus interface:

  4. The IDCP (Insertion Device Control Program) is a program that runs on a 2nd computer, the IOC (I/O Controller). The MOCON device, which runs MOSERV, is connected with the IOC via the CAN bus. The IDCP uses the LowCAL protocol (a BESSY development) in order to transmit data via the CAN bus. For this reason, MOSERV has to use a LowCAL compatible data format in order to communicate with the IDCP. Due to programming restrictions on the MOCON, it cannot use LowCAL itself, but a variant of this protocol, LowCAL-BE8. On side of the IOC, a small software module, a plug-in, is used to convert LowCAL to LowCAL-BE8.

  1.3.   Major Software Functions

  1.3.1.   Basic Operation

MOSERV has to control the motor-movements of the insertion device and it has to communicate with the Insertion Device Control Program (IDCP). MOSERV acts as a server. It waits for commands from the IDCP and executes them.

MOSERV also has to ensure, that the motors are never moved in a way that could damage the insertion device hardware, regardless of the commands it gets from the IDCP.

It must be able to perform an emergency stop out of a motor movement when such a command is received from the IDCP.

During the motor-movement, MOSERV has to provide the current motor-positions for the IDCP at least 10 times a second. A rate of up to 50 times per second is desirable.

  1.3.2.   Communication to the IDCP

In most cases, MOSERV receives a number of parameters followed by a `START'command from the IDCP. It will then start the movement of the motors and, while they are being moved, send their current positions as fast as possible back to the IDCP. While the motors are moved, the parameters cannot be changed, new commands are accepted but the movement will be stopped immediately before any new command is executed.

This means that MOSERV must be provided with all parameters that are needed for the movement before the movement is started.

The described concept covers all 3 kinds of required movements of the insertion devices:

  1.4.   Major Design Constraints, limitations

There are some limitations for the MOSERV program, mainly caused by the hardware that is used:

  1. Limitations of structured programming

  2. The MOCON language is related to BASIC, this limits the ability of structured programming. While WHILE and REPEAT-UNTIL can be used, a CASE statement is missing. The only way to use sub-routines is by using GOSUB-RETURN. There are no function-parameters or local variables. The number of variables that can be defined is limited to 93. Variables can only be of the type integer (32 bits) or character (8 bits).
  3. Speed limitations

  4. Each program line takes roughly 5 to 10 milliseconds (precise measurements are further down in this documentation). This in particular limits the speed at which the current motor positions can be send to the IDCP.
  5. Memory limitations

  6. The memory is limited to 32kBytes. This memory, however, does not have to store the pure ASCII text of the program but a kind of pre-compiled code. In this code, each command consists roughly of 1 up to 5 bytes. It is not probable that MOSERV will come near this limits, but it is mentioned here for completeness.
  7. CAN bus limitations

  8. The CAN bus can (at maximum speed) transfer one 8-byte data frame in about 140microseconds. This is, due to the slowness of the MOCON, no constraint for this application. The CAN bus can also only transmit up to 8 data-bytes at a time. Since the main purpose of the CAN bus in this application is to transmit integers, this is also not a major constraint.
  9. IDCP limitations

  10. IDCP is an EPICS (Experimental Physics Industrial Control System) application. EPICS is usually not programmed with an ordinary programming language but in a record model: A record usually holds an integer, it has an input and an output that are connected to other records or hardware-links. This makes it difficult (but not impossible) to program traditional algorithms with loops or sub-programs. For this reason, the communication between IDCP and MOSERV should be "flat". It should be mostly independent on the data that has been sent before. The sequence in which the CAN data frames are sent shouldn't matter in any case. Each deviation from that principle makes IDCP much more complicated.

  2.   Reference Documents

  2.1.   Existing software documentation

The following software documentation that is relevant for the MOSERV development is available:

  2.2.   Vendor Documents

The following documentation for the MOCON device is available and is used for the MOSERV development:

  3.   Design Description

  3.1.   Data Description

  3.1.1.   Review of Data Flow

The following diagram shows the principle data flow of the MOSERV program:
Extracted pic [1]

The MOSERV program gets movement parameters and movement commands from the IDCP. It may then, depending on the command received, start the motor-movement and use the motor actors. During movement, MOSERV receives the current motor positions from the motor sensors and passes this information to the IDCP.

  3.1.2.   Review of Data Structure: The MOTOR Interface

The access of the motor sensors and actors is done by the built-in commands of the MOCON language. This language provides simple commands for the control of the motors and the reading of the motor positions. Motor-positions are always 32-bit integers.

  3.1.3.   Review of Data Structure: The IDCP Interface (MOP v.5)

MOP is the MOSERV CAN-bus protocol that is used for the communication between MOSERV and the IDCP. The protocol described in the following section is version 5.

Note that MOP v.5 covers only the positioning mode of the Insertion-Device movement.

  3.1.3.1.   IDCP Communication Basics and Protocols

The IDCP runs on a separate hardware, the IOC, that is connected with the MOCON device with a single CAN-bus cable that is reserved for the IOC - MOCON communication. The CAN-bus data-rate is 1 Mbit.

The protocol that is used for the IOC - MOCON communication is the LowCAL-BE8 protocol. LowCAL has already been implemented on the IOC and LowCAL-BE8 is a variant of this protocol. The difference between LowCAL and LowCAL-BE8 is in the way the data bytes are put to the CAN bus:.

  1. Numbers are sent in big-endian format, since the MOCON can, due to hardware restrictions, only use a big-endian format for numbers. LowCAL specifies a little-endian format.
  2. The MOCON can, due to hardware restrictions, not access single bytes of a CAN data frame. Instead it supports 8-byte CAN objects that consist of two 4-byte integers. LowCAL CAN objects have a length of the size of the integer (1, 2 or 4) plus 1, the first data byte is the index-byte. With LowCAL-BE8, the first byte, the index-byte, is sent as a 4-byte integer. By this, the CAN objects used in LowCAL-BE8 always have a length of 8 bytes.

Due to the above mentioned restrictions, the MOCON always uses 8-byte CAN objects. The index-byte of the LowCAL protocol is transmitted (in big-endian format) via the first to the 4th data-byte of the CAN frame. The 5th to the 8th data-byte contain (in big-endian format) the data itself. For 1-byte and 2-byte integers, the unused data-bytes are set to 0.

This LowCAL-BE8 format is converted to the standard LowCAL data-format via a set of 3 functions, the MOPLUG module. This is a sci-plug-in (see sci documentation) that enables sci to convert LowCAL-BE8 to LowCAL. The upper layers of the protocol-software on the IOC remain unchanged. To them, the MOCON is a fully LowCAL compatible device.

There are limits for the values that may be written to some LowCAL multiplex variables. Also there are some states of MOSERV when it is not allowed for the IDCP to write to certain fields of LowCAL multiplex variables. In all these cases, a LowCAL compliant error-message is sent to the IDCP.

  3.1.3.2.   IDCP Communication: CAN-Bus IDs

The CAN bus id's are given according to the BESSY-II MLT specification:


Each CAN participant has a (on that segment unique) node id (NID). Each channel (e.g. each LowCAL-variable) has a (for the connected participants unique) channel-id (CID). A read-object has a direction-flag (d) of 1, a write object has a direction flag of 0. LowCAL defines a server and a client for each LowCAL-variable. For the calculation of d and NID, the server is deciding. Each CAN bus id is calculated as follows:

CID*128 + d*64 + NID.

The ID-IOC is assigned with NID 10 (convention: a multiple of 10 for each IOC), the mocon is assigned with NID 1. The parameter variable is assigned with CID 0, the message variable is assigned with NID 0.

The following table shows CID, NID, d and the corresponding CAN-Ids for each variable (note that read- or write access is seen from the server's side):

Var-Name

direction

CID

NID

d

CAN-Id

Message

(msg)

read

1

10

1

202

Parameter

(par)

read

0

1

1

65

Parameter

(par)

write

0

1

0

1

  3.1.3.3.   IDCP Communication: Variables and Constants

For the IOC - MOCON communication, the following LowCAL variables are defined:

  1. The MOCON parameter variable (type multiplex R/W, MOCON is server, CID 0) with the following fields:
  2. Index

    Name

    Function

    0

    CMD

    command to the MOCON

    1

    VER

    mocon protocol version number, recent version number: 5

    2

    PPOS

    destination position for the positioning mode

    3

    RES1

    Reserved

    4

    RES2

    Reserved

    5

    ROFF1

    reference offset of axle 1

    6

    ROFF1

    reference offset of axle 2

    7

    ROFF1

    reference offset of axle 3

    8

    ROFF1

    reference offset of axle 4

    9

    VEL

    motor velocity, 1000= max. velocity

    10

    AXMODE

    moved axles and position difference monitor specification

    11

    GAPMODE

    specification of the axles, whose current positions are transmitted during movement

    12

    BRAKES

    specification which brakes are aktivated and which axles are set to "free movement"state

    13

    SWITCHES

    state of the end-position switches


    Notes on the fields of the parameter variable:


    1. CMD:

    2. The command field receives the next command from the IDCP for MOSERV. The following commands are defined for that field:

      symbolic name

      number

      function

      RESET

      1

      reset the MOCON unit, go to power-on state, perform reference-procedure. The definition of the zero-positions takes account of the ROFF-fields !

      F_RESET

      2

      reset the MOCON unit, go to power-on state

      STOP

      10

      stop all motor-movement

      This is also the content of the CMD-field after power-on.

      START

      11

      start motor-movement

      GOTOREF

      12

      Move all axles to the end-position switches but do not define the zero-positions new (as RESET would do).

      SETBRAKE

      20

      set brakes to a defined state according to the BRAKES field in the parameter variable

      GETSWITCHES

      21

      get state of the end-position switches and write it to the SWITCHES field of the parameter variable

      GETPOS

      22

      get current motor positions and write them to the CPOS1 to CPOS4 fields of the message variable (regardless of GAPMODE, all 4 positions are returned)

    3. VER:

    4. The version (VER)-field contains a protocol version number. This field is used by the IOC for compatibility checks. The protocol described in this document is version 4.
    5. PPOS:

    6. The destination (PPOS) field receives the destination position for the 4 motors. All 4 motors are then moved synchronous to the same new position.
    7. ROFF1 .. ROFF4

    8. These fields contain the reference offsets for each axle. This is the difference between the logical 0-position and the position where the end-position switch is just activated. If the zero-position is towards the gap-close direction in relation to the end-position switch, the corresponding ROFF-value is negative. In other words, the position of the reference-switch for a single axle is at -1*ROFF.
    9. AXMODE:

    10. This (settable) field contains the axles that are to be moved and the configuration of the position difference monitor. The position difference monitor checks wether the difference of the positions of axle 1 and 2, 2 and 3 or 3 and 4 exceed a certain limit. All motor movement is stopped in this case. AXMODE is bit-field, the following table shows the meaning of the bits::

      bit-no

      name

      meaning

      0

      AX1

      movement mode of axle 1. 1: move axle, 0: don't

      1

      AX2

      movement mode of axle 2. 1: move axle, 0: don't

      2

      AX3

      movement mode of axle 3. 1: move axle, 0: don't

      3

      AX4

      movement mode of axle 4. 1: move axle, 0: don't

      4..7

      R4..R7

      reserved

      8

      CHK12

      1: check position difference between axle 1 and 2

      9

      CHK23

      1: check position difference between axle 2 and 3

      10

      CHK34

      1: check position difference between axle 3 and 4

      11..31

      R11..R31

      reserved

    11. GAPMODE:

    12. This settable field contains the specification of the axles whose positions are transmitted to the ID-IOC while the motors are moved. GAPMODE is a bit-field, the following table shows the meaning of the bits:

      bit-no

      name

      meaning

      0

      GAP1

      1: transmit position of axle 1;

      0: don't

      1

      GAP2

      1: transmit position of axle 2;

      0: don't

      2

      GAP3

      1: transmit position of axle 3;

      0: don't

      3

      GAP4

      1: transmit position of axle 4;

      0: don't

      4..31

      R4..R31

      reserved

    13. BRAKES:

    14. This field specifies, which brakes are switched on or off, when the next SETBRAKE command is executed. It also contains a specification wether the motor of an axle shall be switched off when the brake is released. By this, an axle can be set to a free-moveable state. BRAKES is a bit field, the following table shows the meaning of the bits:

      bit-no

      name

      meaning

      0

      BRK1

      0: switch brake 1 off

      1: switch brake 1 on

      1

      BRK2

      0: switch brake 2 off

      1: switch brake 2 on

      2

      BRK3

      0: switch brake 3 off

      1: switch brake 3 on

      3

      BRK4

      0: switch brake 4 off

      1: switch brake 4 on

      4..7

      R4..R7

      reserved

      8

      ST1

      1: set axle 1 to free-moveable state when brake 1 is released at the same time

      0: don't

      9

      ST2

      1: set axle 2 to free-moveable state when brake 1 is released at the same time

      0: don't

      10

      ST3

      1: set axle 3 to free-moveable state when brake 1 is released at the same time

      0: don't

      11

      ST4

      1: set axle 4 to free-moveable state when brake 1 is released at the same time

      0: don't

    15. SWITCHES:

    16. This variable contains the current state of the end-position switches when the GETSWITCHES command was issued before. SWITCHES is a bit-field, the following table shows the meaning of the bits:

      bit-no

      name

      meaning

      0

      SWO1

      stat of the gap-open software end-position switch of axle 1

      0: open

      1: closed

      1

      SWC

      stat of the all gap-close software end-position switches

      0: all open

      1: at least one is closed

      2

      SWO2

      stat of the gap-open software end-position switch of axle 2

      0: open

      1: closed

      3

      R3

      reserved

      4

      SWO3

      stat of the gap-open software end-position switch of axle 3

      0: open

      1: closed

      5

      R5

      reserved

      6

      SWO4

      stat of the gap-open software end-position switch of axle 4

      0: open

      1: closed

      7..31

      R7..R31

      reserved



  3. The MOCON message variable (type multiplex W/O, IOC is server, CID 1) has the following fields defined:
  4. Index

    Name

    Function

    0

    STAT

    status of the MOCON

    1

    ERR

    error-code of the MOCON

    2

    CPOS1

    current position of motor 1

    3

    CPOS2

    current position of motor 2

    4

    CPOS3

    current position of motor 3

    5

    CPOS4

    current position of motor 4

    6..9

    R6..R9

    reserved


    Notes on the fields of the message variable:

    1. STAT

    2. The following constants are defined for the status field of the MOCON message variable:

      symbolic name

      number

      meaning

      STOP

      0

      MOCON is ready and waiting

      PWON

      1

      MOCON is in power-on state

      REF

      2

      motors are being referenced

      RUN

      3

      motors are being moved

      WAIT

      4

      MOCON is busy for a short time; a command is still executing

    3. ERR

    4. The following constants are defined for the error field of the MOCON message variable:

      symbolic name

      number

      meaning

      NONE

      0

      no error

      PAR_INIT

      1

      some parameters needed for motor-movement are still uninitialized

      PAR_VAL

      2

      some movement parameters have a wrong value

      SWITCH

      3

      a switch was released showing that the motors were moved to a limit

      HW

      4

      Hardware-error, the motors cannot be moved!

      DECL

      5

      declination error; the difference of 2 axles that are monitored exceeds the maximum allowed difference

    5. CPOS1... CPOS4:

    6. These fields contain the current position of the motors. Note that for the positioning mode, where all 4 motors are moved synchronous, only the first position is valid (CPOS1). The contents of the other fields are undefined in this case.

  3.2.   Derived Program Structure

  3.2.1.   State Transition Diagram

The following diagram shows the internal states of MOSERV and the conditions that lead to a state transition:
Extracted pic [2]

Note that conditions written in capital letters represent commands received from the IDCP. New parameters from the IDCP are only accepted in the stop - state.

  3.2.2.   Module structure

First there are some restrictions that limit the possibilities on how a program for the MOCON device can be written:

These facts lead to the following conclusions:

The programs will be divided into several software modules that are placed into one separate file for each module. These files are then included in the main program file. The limitations of the MOCON language make it impossible for the module-files to be completely stand-alone, they will use program parts (especially variable definitions) that are placed in the main program-file. The following software modules are defined:

The following scheme shows the relationship of the software modules with respect to the call-hierarchy:
Extracted pic [3]

The structure of the program should allow a step- by step implementation. MOSERV will be implemented in 3 stages corresponding to the 3 kinds of movements of the Insertion Device structures:

  3.3.   Interfaces within structure

The internal software interfaces of MOSERV are the module interfaces of the modules MM/MU, UTIL and CAN. Since there is no mechanism for passing parameters to functions in the MOCON language, global variables are used instead. Some global variables however, are used to mimic parameters since they only pass data to sub-programs. The text gives only a short description of the module's internal interfaces, do also look at the next chapter that has detailed module descriptions.

  4.   Modules

  4.1.   The Main Module

  4.1.1.   Processing narrative

The main-module contains only one function, the main-program. It also contains global variables that are used by the other modules of MOSERV.

Since MOSERV is a server program with no interactive user-interface, it runs in an endless loop. The first sequence of commands after power-up essentially waits for a RESET command from the IDCP. After that command is received, all global variables are initialized. Then the motors are moved to their reference positions by a call to MU_ref. When MU_ref receives a STOP command during movement, the motors are stopped, STOP is written to the M_cmd variable and M_ref returns. Only after the motors have been moved to the reference positions by MU_ref, their positions are known to MOSERV.

A variable, looplevel, is used in order to avoid GOTO statements. 3 loop-levels, 0, 1 and 2 are used in order to branch to different places in the program. Level 0 leads by the outmost program loop to power-up initialization, level 1 leads to the middle loop, the main command loop where MOSERV waits for a new command. Level 2 leads to the innermost loop, the command execution loop. In this loop it is assumed that a new command has already been loaded to M_cmd.

The IDCP's access to the command and parameter fields is managed by the sub-program CAN_handler. This sub-program implements a LowCAL conform read/write multiplex server variable. It waits until new data is received from the CAN bus. If a parameter is read or written, CAN_handler goes again to the waiting-state. If a new command is received, the CAN_handler returns.

After a call to CAN_handler, the following CASE structure (simulated with IF THEN ELSE ENDIF and GOTO since there is no CASE statement in the MOCON language) examines the new command. In case of RESET looplevel is set to 0, which causes the program to go to the power-on state. In case of STOP, all motors receive a stop command, although they shouldn't be moving anyway. In case of START, the sub-program MM_pos is started. This moves the motors until they reach their destination position or a new command is received from the IDCP. If, after execution of MM_pos, the command is still START, there was no new command received while the motors were moved and the program goes to the wait-for-new-command state. If there was a new command received, that command is executed without calling CAN_handler before.

  4.1.2.   Interface Description

The external interface (to the IDCP) has already been described in the section "Review of Data Structure". The internal interface of the Main Module consists of global variables that are accessed by other modules:

  1. M_cmd:

  2. This is the global command variable. It contains the latest command from the IDCP. This variable is read only within the MAIN module. It is written by the CAN module when a new command is received.
  3. M_param:

  4. This is the global parameter variable. It largely contains parameters that define the kind of the wanted motor-movement. This variable is read and written by the CAN module, when a corresponding request from the IDCP is received.

  4.1.3.   Design Language Description

The following text describes the algorithm of the Main-Module. Since diagrams are difficult to handle when changes have to be applied, a PASCAL-like language is used in this place. Note that the definitions of variables and constants are omitted as well as some program details.

M_cmd:= STOP
CanInit;
InitGlobalVariables;
WHILE (TRUE) DO
  BEGIN
    REPEAT
      InitServerVariables;
      IF (M_cmd<>RESET) THEN 
        CanGetCommand( wait, accept only a RESET command );
      InitClientVariables
      MuPerformReference;
    UNTIL M_cmd<>STOP;
    M_cmd:= STOP;
    looplevel:=1;
    REPEAT
      M_cmd= STOP;
      CanHandler( wait for a new command );
      looplevel:=2;
      REPEAT
        CASE M_cmd OF
          RESET: BEGIN
                 MuStopAllMotors;
                 looplevel:= 0;
                 END;
          STOP:  BEGIN
                 MuStopAllMotors;
                 looplevel:= 1;
                 END;
          START: BEGIN
                 MmGotoPosition;
                 IF (M_cmd=START) THEN
                   looplevel:= 1;
                 END;
          ELSE
                 CanSignalUnknownCommand;
        END;
      UNTIL looplevel<2;
    UNTIL looplevel<1;
  END;             

  4.1.4.    Modules used

The main module makes use of the following modules:

  1. MM/MU (Motor Movement and Motor-Utility Module):

  2. Sub-program MMGotoPosition and MuPerformReference are called
  3. CAN (CAN bus access module):

  4. Sub-programs CanHandler and CanGetCommand are called

  4.1.5.   Data Organization

The main module has 3 major variables.

  1. The loop-level variable (looplevel):

  2. This is an integer that is used to control the program flow. By usage of this variable, a GOTO statement can be avoided.
  3. The command variable (M_cmd):

  4. This integer variable holds the latest command that was received by the IDCP. It is also used during start-up to control program flow and set initially to STOP.
  5. The parameter variable (M_param):

  6. This is an array of integers that is used to hold all kinds of movement parameters. The whole array can be read or written to by the IDCP, but only when MOSERV is in the STOP state (see state transition diagram some chapters before). The parameter variable can only be read or written to when one the the function CanGetCommand or CanHandler is currently executed. The parameter variable can be expanded if further program improvements require additional movement parameters.

  4.2.   The Motor Utility Module

  4.2.1.   Processing narrative

The Motor Utility Module provides, in the first stage of the implementation of MOSERV, only one function, MuPerformReference (or MuRef for short).

This function moves the motors to the reference position. If there is a new command received from the CAN bus and this command is STOP, the motor movement is stopped immediately. The command is written to the global command variable M_cmd and MuRef returns.

The "referencing"of the motors is a bit complicated. Before the motors have been moved to their reference positions, nothing is known about their current positions. For this reason, they are moved in the direction of the stop-position switches while the program constantly checks whether the switches are triggered. There is one switch for each motor. A motor is stopped when the corresponding switch is triggered. This algorithm is not safe when the magnetic structures are declined, in this case the magnectic structures can collide during referencing. For the time being we can assume that the magnetic structures are always in a horizontal position. When in the 3rd implementation stage tapering mode is implemented in MOSERV, we can no longer make this assumption. It must then be found a way to measure the declination and move the structures to a horizontal position first.

It must be stressed that the following algorithm presumes that the magnetic structures are NOT in a declined position !

  4.2.2.   Interface Description

The only variable that is accessed by MuRef is M_cmd. M_cmd must be RESET when MuRef is started, otherwise the function is aborted and the motors are stopped. MuRef scans for new data from the CAN bus while it is running and accepts a STOP command when it is sent by the IDCP. In this case all motor movement is stopped and MuRef returns.

  4.2.3.   Design Language Description

The following text shows the logical structure of the function MuRef. The words "up"and "down"refer to the lower pair of magnetic structures. The upper pair of magnetic structures mirrors the movement of the lower pair. The stop-position switches have the state FALSE (not triggered) or TRUE (triggered).

PROCEDURE MuPerformReference;
  BEGIN
    CanSetStatus( set Status to REFERENCE );
    MuLiftBrakesAndEnableMotors;
    MuSetVelocity( 1/4 of max. velocity );
    MuReferenceLoop( move to gap-open direction );
    IF (MuRefenceLoopStatus=ABORTED) THEN
      GOTO MuRefEnd;

    MuSetVelocity( 1/20 of max. velocity );
    MuReferenceLoop( move to gap-close direction );
    IF (MuRefenceLoopStatus=ABORTED) THEN
      GOTO MuRefEnd;
    MuSetOriginAtCurrentPosition;
    MuSetVelocity( max. velocity );
    CanSetStatus( set Status to REFERENCE );
  LABEL MuRefEnd:
  END;

PROCEDURE MuReferenceLoop;
  BEGIN
    i:= MuNumberOfMotorsToMove;
    WHILE (i>0) AND (M_cmd<>STOP) DO
      BEGIN
        CanHandler( do not wait );
        The following construct for each of the 4 motors:
        IF ( (direction=GAP_OPEN ) AND (UpperSwitchActive) ) OR
             (direction=GAP_CLOSE) AND (NOT UpperSwitchActive) ) THEN
          BEGIN
            StopThisMotor;
            i:= i-1;
          END;
        Until Here !
      END;
    IF (M_cmd=STOP) THEN
      BEGIN
        MuStopAllMovements;
        CanSetStatus( this status is given as parameter to MuReferenceLoop );
      END;
  END;

  4.2.4.   Modules used

The MU module makes use of the following modules:

  1. CAN (CAN bus access module):

  2. The Sub program CanHandler is called

  4.2.5.   Data Organization

The MU module needs some local variables. Since the MOCON language has not local variables, global variables are used instead. All variables that are not directly accessed by other modules start with "mu_", variables that are directly accessed (currently there are none) start with "MU_".

  4.2.6.   Comments

The above description of the module MU is preliminary since it does only cover the so called positioning mode. The following changes may have to be made to this module:

  4.3.   The Motor Movement Module

  4.3.1.   Processing narrative

The Motor Movement Module provides, in the first stage of the implementation of MOSERV, only one function, MmGotoPosition.

This function is used for the positioning mode and moves the motors fixed positions. The details of the motor movement are not specified and all 4 motors are moved in parallel to the same position.

During movement, the current motor position is constantly written to the IDCP to the LowCAL write-only multiplex variable within the IDCP.

If there is a new command received from the CAN bus, the motor movement is stopped immediately. The command is written to the global command variable M_cmd and MM_pos returns.

  4.3.2.   Design Language Description

The following text shows the logical structure of the function MmGotoPosition.

PROCEDURE MmGotoPosition
  BEGIN
    MuSetVelocity( user-defnd velocity from M_param variable );
    p= M_param [ index of destination position ];
    IF (p=INITIAL) THEN
      BEGIN
        CanSignalPositionError;
        GOTO MmGotoPositionEnd;
      END;
    CanSetStatus( set Status to RUN );
    MuMoveLoop;
    IF MuMoveLoopStatus=SUCCESS THEN
    CanSetStatus( set Status to STOP );
  LABEL MmGotoPositionEnd;
  END;

PROCEDURE MmMoveLoop
  BEGIN
    MuLiftBrakesAndEnableMotors;
    loop= TRUE;
    WHILE (loop=TRUE) DO
      BEGIN
        The following construct for each of the 4 motors:
        IF (transmission-flag for motor set; a parameter to MuMoveLoop) THEN
          CanSendCurrentPosition( this motor);
        Until Here !
        IF MuMovementStopped( axle with the longest way to go ) THEN
          loop:= FALSE;
        ELSE
          BEGIN
            CanHandler( do not wait );
            IF (M_cmd=STOP) THEN
              BEGIN
                MuEmergencyStop;
                CanSetStatus( status is given as parameter to MuMoveLoop);
                loop:= FALSE;
              END;
          END;
      END; /* while */

  4.3.3.   Modules used

The MM module makes use of the following modules:

  1. CAN (CAN bus access module):

  2. The Sub program CanGetCommand is called

  4.3.4.   Data Organization

The MM module needs some local variables. Since the MOCON language has no local variables, global variables are used instead. All variables that are not directly accessed by other modules start with "mm_", variables that are directly accessed (currently there are none) start with "MM_".

  4.4.   The CAN Module

  4.4.1.   Processing narrative

The CAN module provides higher-level function in order to transmit data via the CAN bus. There are, however, some places where data is sent directly to the CAN bus for performance reasons.

The 2 major functions of this module, CanGetMessage and Canhandler are conform to the LowCAL protcol as it is implemented at BESSY II with the exception, that the byte-order and the CAN-Object Length is different. This incompability is due to performance reasons resolved on the IOC.

  4.4.2.   Design Language Description

The following text shows the logical structure of the functions CanGetCommand and CanHandler. Note that the 2 CAN-Object Ids are named as CANIN_ID and CANOUT_ID:

PROCEDURE CanGetCommand
  BEGIN
    loop:= TRUE;
    WHILE (loop=TRUE) DO 
      BEGIN
        REPEAT
          CanRead(a,b, CANIN_ID, no timeout)
        UNTIL (data read from CAN bus without error)
        IF (a>127) THEN
          BEGIN
            n:=1;
            a:= a - 128;
          END
        ELSE
          n:= 0;
        IF (a<0) OR (a>LastValidIndex) THEN
          CanWrite(a+128, 1 , CANOUT_ID);
        ELSE 
          IF (n=1) THEN /* read request */
            IF (a=0) THEN
              CanWrite(a, M_cmd, CANOUT_ID);
            ELSE
              CanWrite(a, M_param[a], CANOUT_ID);
          ELSE /* write request */
            IF (a=0) THEN
              IF ( b in spec. command-range, a param. to CanGetCommand) THEN
                BEGIN
                  M_cmd= b;
                  loop:= FALSE;
                END
              ELSE
                CanWrite(a+128, 2, CANOUT_ID); 
            ELSE
              BEGIN
                M_param[a]:= b;
                CanWrite(a, b, CANOUT_ID); 

              END
      END; /* while */
  END;

PROCEDURE CanHandler
  BEGIN
    loop:= TRUE;
    WHILE (loop=TRUE) DO
      BEGIN
        IF (CanHandler was called with WAIT-Parameter) THEN
          CanRead(a,b, CANIN_ID, no timeout with wait);
        ELSE
          BEGIN
            CanRead(a,b, CANIN_ID, no timeout without wait);
            loop:= FALSE;
          END;
        IF (data received without error) THEN
          BEGIN
            IF (a>127) THEN
              BEGIN
                n:=1; /* mark read request */
                a:= a-128;
              END
            ELSE
              n:=0; /* mark write req. */
            IF (a<0) OR (a>LastValidIndex) THEN 
              CanWrite( a+128, 1 CANOUT_ID);
            ELSE
              IF (n=1) THEN /* read req. */
                IF (a=0) THEN /* MCMD-Access */
                  CanWrite( a, M_cmd, CANOUT_ID);
                ELSE
                  CanWRite( a, M_param[a], CANOUT_ID);
              ELSE          /* write req. */
                BEGIN
                  IF (a=0) THEN /* MCMD-Access */
                    M_cmd:=b;
                    loop:=FALSE; /* return from this function */
                  ELSE
                    M_param[a]= b;
                  CanWrite( a, b, CANOUT_ID);
                END;
          END; /* IF (received w/o error) */
      END; /* while */
  END;

  4.4.3.   Modules used

The CAN Module makes no use of other modules.

  4.4.4.   Data Organization

The Can module needs some local variables. Since the MOCON language has no local variables, global variables are used instead. All variables that are not directly accessed by other modules start with "C_", variables that are directly accessed start with "Can_".

  5.   Test Provisions

MOSERV is a part of IDCS, the Insertion Device Control System. It has to be tested that MOSERV works as described in this documentation. The second major part of IDCS is IDCP, the Insertion Device Control Program. This program runs on a IOC, a VME-bus based computer. It is connected to the MOCON device with a separate CAN bus line and is based on EPICS. EPICS is a software-packet that runs on all IOC's and forms (together with System-Operator workstations) the control system of the storage ring.

In order to be able to test MOSERV before integrating it with the IDCP, a test program is developed together with the MOSERV program. This test program, MOSERV, runs on a simple PC equipped with with DOS and a CAN-PC CAN bus interface card (a BESSY development). MOTEST enables the user to give interactive commands to MOSERV by using the same protocol as it is used by IDCP.

The MOTEST program also SCI, the Simple CAN Interface. This is a library to access the CAN bus in a hardware-independent way. Currently, SCI is implemented for the VME-CAN2 and the CAN-PC card. The later is a BESSY development. The CAN-PC card is a PC-compatible ISA bus card. This card is recommended to be used with MOTEST.

  6.   Packaging

MOSERV comes as a plain ASCII text. A PC with a serial interface is needed in order to load MOSERV to the MOCON device. The MOCON device must be connected to the PC by a serial line and the PC must be equipped with the APOS v.3.9 (or later) program. MOSERV has to be loaded by the APOS program which then can transmit the program to the MOCON device. The MOCON device can be set up in a way that MOSERV is stored in non-volatile RAM and is started automagically at power-on.

  7.   Special Notes

  7.1.   Execution Time Estimations

This chapters gives some estimations on program execution times. These estimations can be used in order to calculate how often MOSERV can provide the current motor-positions while they are moved.

The following execution times were measured on the MOCON device (note that there is a new MOCON device in use since Jan.97 that is 2 to 5 times faster!):

Operation

MOCON Keyword or example

Execution time [ms]

loop

LOOP

4.8

goto

GOTO

1.8

assignment

A=0

4.1

addition

A=A+1

8.7

indexing (additional)

A[0]

3.6

conditional (TRUE)

IF (A==0) THEN...ENDIF

10.6

conditional (FALSE)

IF (A==0) THEN...ENDIF

8.9

sub-program call

GOSUB...RETURN

4.7

CAN bus read

CANIN

13.8

CAN bus write

CANOUT

11.2

Using the timings show in the table above, the following estimations for execution times can be made:

CAN_getcmd: (when no data is received):

 

command

time [ms]

 

GOSUB & RETURN

4.7

 

CAN bus read

13.8

 

IF, condition FALSE

8.9

sum

 

27.4

MM_pos:

 

command

time [ms]

 

REPEAT & UNTIL

8 (e)

 

get position

10 (e)

 

CAN bus write

11.2

 

IF, condition FALSE

8.9

 

GOSUB CAN_getcmd

27.4

 

IF, condition FALSE

8.9

sum

 

74.4 (e)

This leads to the conclusion that a new motor position can be supplied about every 75-80ms in positioning mode.


Generated by fmtoweb written by Peter G. Martin <peterm@zeta.org.au> Last modified: 26 May 1997