Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 10 Nov 1997 20:09:17 -0500 (EST)
From:      Peter Dufault <dufault@hda.com>
To:        jamil@trojanhorse.ml.org (Jamil J. Weatherbee)
Cc:        hackers@freebsd.org
Subject:   Re: LabPC+ Driver Specifics
Message-ID:  <199711110109.UAA20154@hda.hda.com>
In-Reply-To: <Pine.BSF.3.96.971108210324.1073A-100000@trojanhorse.ml.org> from "Jamil J. Weatherbee" at "Nov 8, 97 09:20:15 pm"

next in thread | previous in thread | raw e-mail | index | archive | help
> I am currently in the process of writing a driver for an analog input
> board and am using your labpc driver as an example (I have a labpc also).
> I am kind of curious about your buffer management. It appears that you are
> using the onboard fifo for buffering and depending on the user to make
> bio buffers available for writing out the fifo once they open the device.
> If they don't make buffers available frequently enough through read() then
> you have a problem.

Yes, and you'll get an error from the hardware when the FIFO overruns.

> Here are some questions I have, because I think your driver is good
> example and I don't feel a need to make any unnecessary mistakes in design
> that conversing with you could save me.
> 
> One thing is the AD_MICRO_PERIOD_SET, does that change the frequency for
> the entire board or just one channel. Is that general enough? In my case I
> have 128 channels so It is going to get pretty complex managing 128
> channels at 128 different frequencies (with one clock).

There is only one clock on that board.

If you have (or are implementing) independent clocks you probably have
(or are implementing) independent FIFOs or other memory channels
and you should handle it as separate instances of the driver, i.e.,
as if each is a separate board.

> Secondly, I don't have a fifo, however I have interrupts driven through a
> 8253 chain. I assume than the best thing is for me to pick a decent fifo
> size and manage it like the labpc hardware manages its fifo. Would that be
> like 512*(128/8) = 8kb? The particular board is not capable of more than
> 30000 samples/s.

The best solution is to implement a FIFO in software and run it at
a restrictive interrupt level, as Bruce has done in the SIO driver.
That is the typical and most appropriate solution for that problem.
Then the FIFO size can be a config (or even ioctl) time setting.

> I was thinking of implementing an AD_START and AD_STOP ioctls(), or am I
> missing something? 

I think an AD_TRIGGER is needed and you can put it in the dataacq header.

That would describe what will begin the acquisition,
and the default would be AD_TRIG_IMMEDIATE (that is, as soon as read).
Another would be AD_TRIG_EXTERNAL (external TTL start), and a scope-like
structure for trigger level and slope.  I assume this is what you
mean for AD_START?

I see less of a need for an AD_STOP, but maybe you can describe what it
would do.

I see advantages to a frame description ioctl (describe the size
of a frame independent of user I/O transfer size) so you could do:

open ... describe frame ... set trigger ... read a real big chunk of data
in a frame with multiple reads and it stops automatically ... set trigger
read frame ... etc.

> 
> I noticed , it looks like your chaining together buffers passed to your
> strategy routine. Can you breifly explain what is going on there with
> tqe.next (b_actf), I realize this is part of the queue management MACROS,
> but I
> don't think you are actually using those.  I just want a qualitative
> description since I am pretty unclear on the hardware level stuff of the
> labpc.

I should be using the queue macros.  This is a basic start chain -
the I/O requests are enqueued in the chain and then the done interrupt
can kick off the next transfer within the interrupt.  You can now
use "team" or fork a process and get double buffered transfers and
soak up the overhead of resuming a user process.  If you do:

	while (read(0, buff, N) == N)
		;

the system must resume your process before each read whereas if two
of these processes are running the next buffer will be ready to
receive the data in the done interrupt, reducing the required
FIFO elasticity.

> If your ad channels just start spewing when you open, then why don't you
> implement readselect, why just leave it to seltrue?  If your trying to
> read all 8 channels this just might be useful to determine which order.

Specifically, they start spewing data when you issue a read.

To answer your question: the typical A-D card has a single channel
list, gain list, timer, etc, and so you know the order the data
will arrive in since you specified the frame.  A trickier board
with multiple resources or a home brew system is best handled as
multiple simple boards.

I've begged the question, though:  If a trigger ioctl is added then
there should be a read select.  Then you can open multiple boards
and process the one that triggers first.  Any system with
multiple "boards" (physical or in software as I believe you plan)
with independent timers per channel will also benefit from the select.

Peter

-- 
Peter Dufault (dufault@hda.com)   Realtime development, Machine control,
HD Associates, Inc.               Safety critical systems, Agency approval



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199711110109.UAA20154>