- From: Herman Bruyninckx <Herman.Bruyninckx_at_mech.kuleuven.ac.be>
- Date: Fri, 11 Apr 2003 10:36:59 +0200 (CEST)
We are working on a device driver to integrate the NI 6602
counter/timer card into Comedi.
Our priority is to use the card as an encoder, but we also
want to do the effort to use a "correct" interface which is more general
than just encoders. So, below are my suggestions for integrating
General Purpose Counter/Timer (GPCT) cards into the _EXISTING_
instruction/command infrastructure.
Herman Bruyninckx
==================================
David has written a design document in
Documentation/comedi/counter-spec
which calls for an new data structure. In fact, I am in favor of such
a change because it is a much "cleaner" solution, but it's up to David
to decide which way to follow: a new GPCT data structure, or new
INSN_CONFIG flags and arguments. Anyway, I attach some comments on
that counter-spec document at the end of this message.
There exists already one driver that has a GPCT subdevice: the
ni_mio_common.c (Other drivers have defined a COMEDI_SUBD_COUNTER
subdevice, but do not really implement much functionality...)
The counter subdevice of the ni_mio_common doesn't have all the GPCT
functionalities that the 6602 has, _and_ it doesn't follow the clean
and generic Comedi approach of instruction/command, so it has
some superfluous things:
- GPCT_RESET
What is the generic meaning of a reset???? I think this should not
be a Comedi function.
- this driver has a configuration flag for outputting one single pulse
(GPCT_SINGLE_PULSE_OUT), and another one for a continuous stream of
pulses (GPCT_CONT_PULSE_OUT). I think this distinction is not
appropriate in Comedi, because Comedi already has "instructions"
(single execution) and "commands" (continuous execution).
My suggestion below consists of:
- reusing what is already there from the ni_mio_common.c driver,
- extending it with some more GPCT functionality, and
- incorporating all functionality in the instruction/command model of
Comedi.
The result does probably not cover all possible counter card
functionalities...
The full documentation of a COMEDI_SUBD_COUNTER is as follows. I use
the name "counter" both for input GPCT (counter) as output GPCT
(timer).
1. General operations:
- comedi_data_read: read current value of the counter.
- comedi_data_read_n: read n times the counter value.
- comedi_data_read_delayed: read the counter value after a delay of a
given number of nanoseconds.
- comedi_data_write: fill in a given value ("latch" value in counter)
(this function will have no effect in some counter configurations)
- insn_read: read current value of the counter
- insn_write: fill in given value ("latch" value in counter)
- insn_bits: not applicable
- insn_config: see next paragraph
2. Configuration
The "insn" flag of the instruction data structure is INSN_CONFIG;
the "data" field contains the configuration arguments.
- Pulse counter (alias: "event counter")
Configuration arguments:
- data[0]: indicates which signal serves as the pulse train
- data[1]: GPCT_UP (counter counts up at each pulse), GPCT_DOWN
- data[2]: indicate the GATE source, i.e., the counter only counts
when the signal on the GATE source is high.
- data[3]: specification of which edge of the pulse triggers the
counter (still to be defined how this is encoded).
- data[4]: delay in nanoseconds before counter starts counting
Constraints:
- channel has type SDF_READABLE
Notes:
- the "signal" above is NOT a Comedi channel, but a hardware signal
on the interface card. These numbers will be card-specific.
- Pulse generator
Configuration arguments:
- data[0]: indicates which signal serves as the pulse train
- data[1]: pulse shape = time during which pulse is high
- data[2]: delay in nanoseconds before pulse is generated
- data[3]: indicate the GATE source, i.e., the counter only
generates pulses when the signal on the GATE source is
high.
Constraints:
- channel has type SDF_WRITEABLE
Notes:
- the configuration of the frequency of a continous pulse train
should be programmed by means of a Comedi command
- Pulse width counter
(counter counts the number of internal clock ticks that a pulse is high)
Configuration arguments:
- data[0]: indicates which signal serves as the clock
- data[1]: indicates which signal serves as the pulse train
- data[2]: delay in nanoseconds before counter starts
- data[3]: indicate the GATE source, i.e., the counter only
counts the clock pulses when the signal on the GATE
source is high.
Constraints:
- channel has type SDF_READABLE?
- Frequency/Period counter
(counter returns the number of clock ticks between two same
edges of a pulse train)
Configuration arguments:
- data[0]: indicates which signal serves as the clock
- data[1]: indicates which signal serves as the pulse train
- data[2]: delay in nanoseconds before counter starts
- data[3]: indicate the GATE source, i.e., the counter only
counts the clocj pulses when the signal on the GATE source
is high.
- Two-signal separation counter
(counts the number of clock ticks between the active edges on two
signals)
Configuration arguments:
- data[0]: indicates which signal serves as the clock
- data[1]: indicates which signal serves as the first signal
- data[2]: indicates which signal serves as the second signal
- data[3]: indicates what is active edge: RISING_EDGE or FALLING_EDGE
- data[4]: delay in nanoseconds before counter starts
- data[5]: indicate the GATE source, i.e., the counter only
generates pulses when the signal on the GATE source is
high.
- Incremental ("AB") encoder
Configuration arguments:
- data[0]:
GPCT_X1: count on one of the four edges in the A or B pulse trains
(which edge is taken is device dependent)
GPCT_X2: count on two of the edges
GPCT_X4: count on all four edges
- data[1]: delay in nanoseconds before counter starts
- Two-pulse encoder
(the counter counts up when a pulse on signal "A" is received, and
down when a pulse on signal "B" is received)
Configuration arguments:
- data[0]: indicates which signal serves as the A signal
- data[1]: indicates which signal serves as the B signal
- data[2]: indicates what is active edge: RISING_EDGE or FALLING_EDGE
- data[3]: delay in nanoseconds before counter starts
- data[4]: indicate the GATE source, i.e., the counter only
counts pulses when the signal on the GATE source is
high.
- Arm/disarm
(only an armed counter counts/generates pulses)
Configuration arguments:
- data[0]: GPCT_ARM, GPCT_DISARM
- data[1]: delay in nanoseconds before action is performed
Constraints:
- delay > 0
- counter must already have been configured as a counter
Notes:
- Arm/Disarm is a _software_ enabling/disabling. It's complementary
to the _hardware_ enabling/disabling done through the GATE
signals.
Comments on the counter-spec document:
- the "Interval timing" example uses "event_src", "event_arg" and
"flags" fields that are not part of the data structure given in the
beginning of the document.
- quadrature encoding needs X1, X2 and X3 flags. Or can this be
specified with an OR of FALLING_EDGE and RISING_EDGE on the src_arg
field?
- this design introduces a new data structure, but doesn't this impose
the need to extend the instruction/command API to include a counter
data structure argument?
- the second half of the document (about the "000->010" like
transitions) is not too clear :-)
Received on 2003-04-11Z07:36:59