Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 24 Feb 1997 12:49:04 +1030 (CST)
From:      Michael Smith <msmith@atrad.adelaide.edu.au>
To:        pc012@seqeb.gov.au (patrick collins)
Cc:        mcgovern@spoon.beta.com, hackers@FreeBSD.org
Subject:   Re: Device driver cookbook.
Message-ID:  <199702240219.MAA04053@genesis.atrad.adelaide.edu.au>
In-Reply-To: <Pine.3.89.9702241008.A14703-0100000@svbyo4.seqeb.gov.au> from patrick collins at "Feb 24, 97 10:58:14 am"

next in thread | previous in thread | raw e-mail | index | archive | help
patrick collins stands accused of saying:
> 
> I am particularly interested in writing a device driver for a 
> digital I/O card I have. This card consists of a couple of 8255 PIO's. I 
> would like my device driver to be able to configure one 8255 for input 
> and the other for output. I would like the device driver to be able to 
> read the inputs every n milliseconds in order to be able to count a 2 Hz 
> pulse train on these inputs.
> 
> I have a fairly general idea on how to go about this but would appreciate
> any pointers you might have, especially in the area of how to get the device 
> driver to continually read the input ports without the intervention of the 
> application software.

You want a polling routine that looks something like this :

void
zog_poller(void *what)
{
	zog_softc	*sc = (zog_softc *)what;
	static int	initted = 0;
	u_char		curr;
	int		bit;
	
	/* get port value */
	curr = inb(sc->base + PORTA);

	/* have valid state? */
	if (initted) {
		/* check bits */
		for (bit = 0; bit < 8; bit++) {
			/* bit is set, and was clear? */
			if ((curr & (1<<bit)) && !(sc->state & (1<<bit))) {
				sc->count[bit]++;
			}
		}
	}
	sc->state = curr;	/* update state */
	initted = 1;		/* definitely initted now */
		
	timeout(zog_poller, what, hz/ZOG_TIMEOUT);
}

Then you can start the poller when you want with 

	timeout(zog_poller, sc, hz/ZOG_TIMEOUT);

where 'sc' is the softc structure for the device in question.  The
last argument to timeout() is the number of timer ticks between
invocations of the routine; 'hz' is the number of ticks per second.
In the above example if your pulse train is coming in every two
seconds, you'd want to sample at least four times per second
(ZOG_TIMEOUT = 4), but you might want to sample faster to compensate
for possible periods where interrupt activity makes you lag.  You might
want to do this in your open routine.

You can kill the timeout routine with

	untimeout(zog_poller, sc)l

for eg. in your close() routine.

Then you could write a read() handler that uses printf() into a buffer
to return the current counter values, or you could just copy them out
to the caller as-is.

> Patrick Collins - Load Survey Technician           email : pc012@seqeb.gov.au

-- 
]] Mike Smith, Software Engineer        msmith@gsoft.com.au             [[
]] Genesis Software                     genesis@gsoft.com.au            [[
]] High-speed data acquisition and      (GSM mobile)     0411-222-496   [[
]] realtime instrument control.         (ph)          +61-8-8267-3493   [[
]] Unix hardware collector.             "Where are your PEZ?" The Tick  [[



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