summaryrefslogtreecommitdiff
path: root/docs/src/hal/parallel_port.txt
blob: 3bc2d3b7211a902c0cc02a5c2d725f6744e3c9c7 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
= Parallel Port Driver

[[cha:Parport]] (((Parallel Port Driver)))

== Parport

Parport is a driver for the traditional PC parallel port. The port has
a total of 17 physical pins. The original parallel port divided those
pins into three groups: data, control, and status. The data group
consists of 8 output pins, the control group consists of 4 pins, and
the status group consists of 5 input pins.

In the early 1990's, the bidirectional parallel port was introduced,
which allows the data group to be used for output or input. The HAL
driver supports the bidirectional port, and allows the user to set the
data group as either input or output. If configured as output, a port
provides a total of 12 outputs and 5 inputs. If configured as input, it
provides 4 outputs and 13 inputs.

In some parallel ports, the control group pins are open collectors,
which may also be driven low by an external gate. On a board with open
collector control pins, the 'x' mode allows a more flexible mode with 8
outputs, and 9 inputs. In other parallel ports, the control group has
push-pull drivers and cannot be used as an input.

.HAL and Open Collectors
[NOTE]
===========================================================
HAL cannot automatically determine if the 'x' mode bidirectional pins
are actually open collectors (OC). If they are not, they cannot be used
as inputs, and attempting to drive them LOW from an external source can
damage the hardware.

To determine whether your port has 'open collector' pins, load
hal_parport in 'x' mode.  With no device attached, HAL should read the
pin as TRUE. Next, insert a 470 ohm resistor from one of the
control pins to GND. If the resulting voltage on the control pin is
close to 0V, and HAL now reads the pin as FALSE, then you have an OC
port. If the resulting voltage is far from 0V, or HAL does not read the
pin as FALSE, then your port cannot be used in 'x' mode.

The external hardware that drives the control pins should also use
open collector gates (e.g., 74LS05).

On some machines, BIOS settings may affect whether 'x' mode can be
used. 'SPP' mode is most likely to work.
===========================================================

No other combinations are supported, and a port cannot be changed from
input to output once the driver is installed. The
<<fig:Parport-block-diag,Parport Block Diagram>> shows two block diagrams,
one showing the driver when the data group is configured for output, and one
showing it configured for input.  For 'x' mode, refer to the pin listing of
'halcmd show pin' for pin direction assignment.

The parport driver can control up to 8 ports (defined by MAX_PORTS in
hal_parport.c). The ports are numbered starting at zero.

=== Installing

----
loadrt hal_parport cfg="<config-string>"
----

.Using the Port Index

I/O addresses below 16 are treated as port indexes. This is the
simplest way to install the parport driver and cooperates with the
Linux parport_pc driver if it is loaded. This will use the address
Linux has detected for parport 0.

----
loadrt hal_parport cfg="0"
----

.Using the Port Address

The configure string consists of a hex port address, followed by an
optional direction, repeated for each port. The direction is 'in',
'out', or 'x' and determines the direction of the physical pins 2
through 9, and whether to create input HAL pins for the physical
control pins. If the direction is not specified, the data group
defaults to output. For example:

----
loadrt hal_parport cfg="0x278 0x378 in 0x20A0 out"
----

This example installs drivers for one port at 0x0278, with pins 2-9 as
outputs (by default, since neither 'in' nor 'out' was specified), one
at 0x0378, with pins 2-9 as inputs, and one at 0x20A0, with pins 2-9
explicitly specified as outputs. Note that you must know the base
address of the parallel port to properly configure the driver. For ISA
bus ports, this is usually not a problem, since the port is almost
always at a 'well known' address, like 0278 or 0378 which is typically
configured in the system BIOS. The address for a PCI card is usually
shown in 'lspci -v' in an 'I/O ports' line, or in the kernel message
log after executing 'sudo modprobe -a parport_pc'. There is no
default address; if '<config-string>' does not contain at least one
address, it is an error.

[[fig:Parport-block-diag]]

.Parport Block Diagram

image::images/parport-block-diag.png[align="center"]

=== Pins

* 'parport.<p>.pin-<n>-out' (bit) Drives a physical output pin.

* 'parport.<p>.pin-<n>-in' (bit) Tracks a physical input pin.

* 'parport.<p>.pin-<n>-in-not' (bit) Tracks a physical input pin, but inverted.

For each pin, '<p>' is the port number, and '<n>' is the
physical pin number in the 25 pin D-shell connector.

For each physical output pin, the driver creates a single HAL pin, for example:
'parport.0.pin-14-out'.

Pins 2 through 9 are part of the data group and are output pins if
the port is defined as an output port. (Output is the default.) Pins 1,
14, 16, and 17 are outputs in all modes. These HAL pins control the
state of the corresponding physical pins.

For each physical input pin, the driver creates two HAL pins, for example:
'parport.0.pin-12-in' and 'parport.0.pin-12-in-not'.

Pins 10, 11, 12, 13, and 15 are always input pins. Pins 2 through 9 
are input pins only if the port is defined as an input port. The '-in'
HAL pin is TRUE if the physical pin is high, and FALSE if the 
physical pin is low. The '-in-not' HAL pin is inverted -- it is FALSE
if the physical pin is high. By 
connecting a signal to one or the other, the user can determine the
state of the input. In 'x' mode, pins 1, 14, 16, and 17 are also input
pins. 

=== Parameters

* 'parport.<p>.pin-<n>-out-invert' (bit) Inverts an output pin.

* 'parport.<p>.pin-<n>-out-reset' (bit) (only for 'out' pins) TRUE if this
pin should be reset when the '-reset' function is executed.

* parport.<p>.reset-time' (U32) The time (in nanoseconds)
between a pin is set by 'write' and reset by the 'reset' function if it
is enabled.

The '-invert'  parameter determines whether an output pin is active
high or active
low. If '-invert' is FALSE, setting the HAL '-out' pin TRUE drives the
physical pin high, and FALSE drives it low. If '-invert' is TRUE, then
setting the HAL '-out' pin TRUE will drive the physical pin low.

=== Functions[[sub:parport-functions]]

* 'parport.<p>.read' (funct) Reads physical input pins of port
   '<portnum>' and updates HAL '-in' and '-in-not' pins.

* 'parport.read-all' (funct) Reads physical input pins of all ports
   and updates HAL '-in' and '-in-not' pins.

* 'parport.<p>.write' (funct) Reads HAL '-out' pins of port
   '<p>' and updates that port's physical output pins.

* 'parport.write-all' (funct) Reads HAL '-out' pins of all ports
   and updates all physical output pins.

* 'parport.<p>.reset' (funct) Waits until 'reset-time' has
   elapsed since the associated 'write', then resets pins to values
   indicated by '-out-invert' and '-out-invert' settings. 'reset' must be
   later in the same thread as 'write. 'If '-reset' is TRUE, then the
   'reset' function will set the pin to the value of '-out-invert'. This
   can be used in conjunction with stepgen's 'doublefreq' to produce one
   step per period. The <<sub:stepgen-parameters,stepgen stepspace>> for that pin
   must be set to 0 to enable doublefreq.

The individual functions are provided for situations where one port
needs to be updated in a very fast thread, but other ports can be
updated in a slower thread to save CPU time. It is probably not a good
idea to use both an '-all' function and an individual function at the
same time.

=== Common problems

If loading the module reports

----
insmod: error inserting '/home/jepler/emc2/rtlib/hal_parport.ko':
-1 Device or resource busy
----

then ensure that the standard kernel module 'parport_pc'  is not
loadedfootnote:[In the LinuxCNC packages for Ubuntu, the file
/etc/modprobe.d/emc2
generally prevents 'parport_pc' from being automatically loaded.]
and that no other device in the system has claimed the I/O ports.

If the module loads but does not appear to function, then the port
address is incorrect or the 'probe_parport' module is required.

=== Using DoubleStep

To setup DoubleStep on the parallel port you must add the function
parport.n.reset after parport.n.write and configure stepspace to 0 and
the reset time wanted. So that step can be asserted on every period in
HAL and then toggled off by parport after being asserted for time
specificed by parport.n.reset-time.

For example:

----
loadrt hal_parport cfg="0x378 out"
setp parport.0.reset-time 5000
loadrt stepgen step_type=0,0,0
addf parport.0.read base-thread
addf stepgen.make-pulses base-thread
addf parport.0.write base-thread
addf parport.0.reset base-thread
addf stepgen.capture-position servo-thread
... 
setp stepgen.0.steplen 1
setp stepgen.0.stepspace 0
----

More information on DoubleStep can be found on the 
http://wiki.linuxcnc.org/cgi-bin/wiki.pl?TweakingSoftwareStepGeneration[wiki].

[[sec:probe_parport]]
== probe_parport

In modern PCs, the parallel port may require plug and play (PNP)
configuration before it can be used. The 'probe_parport'  module
performs configuration of any PNP ports present, and should be
loaded before 'hal_parport'. On machines without PNP ports, it may be
loaded but has no effect.

=== Installing

----
loadrt probe_parport

loadrt hal_parport ...
----

If the Linux kernel prints a message similar to

----
parport: PnPBIOS parport detected.
----

when the parport_pc module is loaded ('sudo modprobe -a parport_pc;
sudo rmmod parport_pc)' then use of this module is probably required.