Notation

Typographical Conventions

Command line examples are presented in {textbf{bold typewriter}}font. Responses from the computer will be in `typewriter` font. As of early 2006, there are no longer commands that require root privileges, so all examples will be preceded by the normal user prompt, {$}. Text inside square brackets {{[}like-this{]}}is optional. Text inside angle brackets `<like-this>` represents a field that can take on different values, and the adjacent paragraph will explain the appropriate values. Text items separated by a vertical bar means that one or the other, but not both, should be present. All command line examples assume that you are in the `emc2/` directory, and you configured/compiled emc2 for the run-in-place scenario. Paths will be shown accordingly when needed.

Names

All HAL entities are accessed and manipulated by their names, so documenting the names of pins, signals, parameters, etc, is very important. HAL names are a maximum of 41 characters long (as defined by HAL\_NAME\_LEN in hal.h). Many names will be presented in a general form, with text inside angle brackets `<like-this>` representing fields that can take on different values.

When pins, signals, or parameters are described for the first time, their names will be preceeded by their type in {(small caps)}and followed by a brief description. A typical pin definition will look something like these examples:

  • {noun{(bit) }}`parport.<portnum>.pin-<pinnum>-in` - The HAL pin associated with the physical input pin `<pinnum>` on the 25 pin D-shell connector.

  • {noun{(float)}}` pid.<loopnum>.output` - The output of the PID loop.

At times, a shortened version of a name may be used - for example the second pin above might be referred to simply as `.output` when it can be done without causing confusion.

General Naming Conventions

Consistent naming conventions would make HAL much easier to use. For example, if every encoder driver provided the same set of pins and named them the same way it would be easy to change from one type of encoder driver to another. Unfortunately, like many open-source projects, HAL is a combination of things that were designed, and things that simply evolved. As a result, there are many inconsistencies. This section attempts to address that problem by defining some conventions, but it will probably be a while before all the modules are converted to follow them.

Halcmd and other low-level HAL utilities treat HAL names as single entities, with no internal structure. However, most modules do have some implicit structure. For example, a board provides several functional blocks, each block might have several channels, and each channel has one or more pins. This results in a structure that resembles a directory tree. Even though halcmd doesn’t recognize the tree structure, proper choice of naming conventions will let it group related items together (since it sorts the names). In addition, higher level tools can be designed to recognize such structure, if the names provide the neccessary information. To do that, all HAL modules should follow these rules:

  • Dots (".") separate levels of the heirarchy. This is analogous to the slash ("/") in a filename.

  • Hypens ("-") separate words or fields in the same level of the heirarchy.

  • HAL modules should not use underscores or "MixedCase".

       footnote:[Underscores have all been removed, but there are still a
                 few instances of mixed case, for example "pid.0.Pgain" instead of
                 "pid.0.p-gain".
    ]
  • Use only lowercase letters and numbers in names.

\\footnote{Most drivers do not follow these conventions as of version 2.0. This chapter is really a guide for future development.% }} === Pin/Parameter names

Hardware drivers should use five fields (on three levels) to make up a pin or parameter name, as follows:

**<device-name>.<device-num>.<io-type>.<chan-num>.<specific-name>**

The individual fields are:

[{``<device-name>``}] The device that the driver is intended to
work with. This is most often an interface board of some type, but
there are other possibilities.
[{``<device-num>``}] It is possible to install more than one servo
board, parallel port, or other hardware device in a computer. The
device number identifies a specific device. Device numbers start at
0 and increment.
    footnote:[Some devices use jumpers or other hardware to attach a
              specific ID to each board. Ideally, the driver provides a way for
              the user to specifically say
              "device-num 0 is the board with ID XXX", and the device numbers
              always start at 0. However at present some drivers use the board ID
              directly as the device number. That means it is possible to have a
              device number 2, without a device 0. This is a bug and will be
              fixed in version 2.1.
]
[{``<io-type>``}] Most devices provide more than one type of I/O.
Even the simple parallel port has both digital inputs and digital
outputs. More complex boards can have digital inputs and outputs,
encoder counters, pwm or step pulse generators, analog-to-digital
converters, digital-to-analog converters, or other unique
capabilities. The I/O type is used to identify the kind of I/O that
a pin or parameter is associated with. Ideally, drivers that
implement the same I/O type, even if for very different devices,
should provide a consistent set of pins and parameters and
identical behavior. For example, all digital inputs should behave
the same when seen from inside the HAL, regardless of the device.
[{``<chan-num>``}] Virtually every I/O device has multiple
channels, and the channel number identifies one of them. Like
device numbers, channel numbers start at zero and increment.
    footnote:[One glaring exception to the
              "channel numbers start at zero" rule is the parallel port. Its
              HAL pins are numbered with the corresponding pin number on the
              DB-25 connector. This is convenient for wiring, but inconsistent
              with other drivers. There is some debate over whether this is a bug
              or a feature.
]
    If more than one device is installed, the channel numbers on
    additional devices start over at zero. If it is possible to have a
    channel number greater than 9, then channel numbers should be two
    digits, with a leading zero on numbers less than 10 to preserve
    sort ordering. Some modules have pins and/or parameters that affect
    more than one channel. For example a PWM generator might have four
    channels with four independent "duty-cycle" inputs, but one
    "frequency" parameter that controls all four channels (due to
    hardware limitations). The frequency parameter should use "0-3"
    as the channel number.
[{``<specific-name>``}] An individual I/O channel might have just a
single HAL pin associated with it, but most have more than one. For
example, a digital input has two pins, one is the state of the
physical pin, the other is the same thing inverted. That allows the
configurator to choose between active high and active low inputs.
For most io-types, there is a standard set of pins and parameters,
(referred to as the "canonical interface") that the driver should
implement. The canonical interfaces are described in chapter
<<cha:Canonical-Device-Interfaces>>.

Examples

[{``motenc.0.encoder.2.position``}] - the position output of the
third encoder channel on the first Motenc board.
[{``stg.0.din.03.in``}] - the state of the fourth digital input on
the first Servo-to-Go board.
[{``ppmc.0.pwm.00-03.frequency``}] - the carrier frequency used for
PWM channels 0 through 3.

Function Names

Hardware drivers usually only have two kinds of HAL functions, ones that read the hardware and update HAL pins, and ones that write to the hardware using data from HAL pins. They should be named as follows:

**<device-name>-<device-num>{[**.<io-type>{[}-<chan-num-range>{]}{]}.read\|write}
[{``<device-name>``}] The same as used for pins and parameters.
[{``<device-num>``}] The specific device that the function will
access.
[{``<io-type>``}] Optional. A function may access all of the I/O on
a board, or it may access only a certain type. For example, there
may be independent functions for reading encoder counters and
reading digital I/O. If such independent functions exist, the
<io-type> field identifies the type of I/O they access. If a single
function reads all I/O provided by the board, <io-type> is not
used.
    footnote:[Note to driver programmers: do NOT implement separate
              functions for different I/O types unless they are interruptable and
              can work in independent threads. If interrupting an encoder read,
              reading digital inputs, and then resuming the encoder read will
              cause problems, then implement a single function that does
              everything.
]
[{``<chan-num-range>``}] Optional. Used only if the <io-type> I/O
is broken into groups and accessed by different functions.
[{``read|write``}] Indicates whether the function reads the
hardware or writes to it.

Examples

[{``motenc.0.encoder.read``}] - reads all encoders on the first
motenc board
[{``generic8255.0.din.09-15.read``}] - reads the second 8 bit port
on the first generic 8255 based digital I/O board
[{``ppmc.0.write``}] - writes all outputs (step generators, pwm,
DACs, and digital) on the first ppmc board

\\footnote{As of version 2.0, most of the HAL drivers don’t quite match up to the canonical interfaces defined here. In version 2.1, the drivers will be changed to match these specs.% } }The following sections show the pins, parameters, and functions that are supplied by "canonical devices". All HAL device drivers should supply the same pins and parameters, and implement the same behavior.

Note that the only the `<io-type>` and `<specific-name>` fields are defined for a canonical device. The `<device-name>, `<device-num>`, and `<chan-num>`` fields are set based on the characteristics of the real device.

Digital Input

quite simple.

Pins

Parameters

  • None

Functions

Digital Output

is also very simple.

Pins

  • to the hardware output.

Parameters

  • before writing to the hardware.

Functions

Analog Input

expected to be used for analog to digital converters, which convert e.g. voltage to a continuous range of values.

Pins

  • the scale and offset parameters. Value = ((input reading, in hardware-dependent units) {*} scale) - offset

Parameters

  • multiplied by scale before being output to value.

  • input voltage (or current) after the scale multiplier has been applied.

  • bit (LSB). This is effectively the granularity of the input reading.

  • volts is applied to the input pin(s).

Functions

  • channel. This may be used for individual channel reads, or it may cause all channels to be read

Analog Output

intended for any kind of hardware that can output a more-or-less continuous range of values. Examples are digital to analog converters or PWM generators.

Pins

  • output to the hardware will depend on the scale and offset parameters.

  • regardless of the value pin.

Parameters

  • before the hardware is updated

  • on the value pin will cause 1V

  • value to output to the hardware, if value + offset is greater than high\_limit, then high\_limit will be used instead.

  • to output to the hardware, if value + offset is less than low\_limit, then low\_limit will be used instead.

  • significant bit (LSB), in volts (or mA, for current outputs)

  • current) that will be output if 0 is written to the hardware.

Functions

to the hardware. If enable is false, then the output will be 0, regardles of value, scale, and offset. The meaning of "0" is dependent on the hardware. For example, a bipolar 12-bit A/D may need to write 0x1FF (mid scale) to the D/A get 0 volts from the hardware pin. If enable is true, read scale, offset and value and output to the adc (scale {*} value) + offset. If enable is false, then output 0.