apfiffer@admin.ogi.edu (Andy Pfiffer) (06/01/90)
Problem: I have a dumb A/D converter plugged into a System V/386 system that requires some clever device-driver wizardry. (I love a challenge) It has no on-board interrupt or DMA capability. I need to sample it, within +/- 10%, at constant, super-HZ (ie: higher than clock tick) intervals; 8000 Hz would be ideal. Yes, this implies significant computrons may be required to accomplish this, but hey -- I didn't design the dang thing. It is not expected that samples will be taken for extended periods of time. In fact, it may only need samples for 10 seconds or so, often less. It is acceptable to "degrade system throughput" to accomplish the task. Obvious options: a) Write a tightly controlled software timing loop that runs at or near splhi() and pull in my samples, burning CPU cycles by the truckload. The drawback is that this driver may run on a variety of 386SX/386DX/486 systems of widely varying clock speeds, caches, etc. It doesn't thrill me to think of all the subtle tuning that might be needed... b) Say uncle and quit. Not-So-Obvious: Theoretically, before I start sampling, I could reprogram one of the 8253-ish interval timers with my desired frequency, swap out the existing clock interrupt vector with my own, calling it when appropriate so that the system has *some* chance of echoing characters. The advantage is that I get a reliable, albeit often, interrupt across all platforms. The disadvantage is that I am playing with the pulse of the system...and I've haven't yet seen "Flatliners*" to learn all of the tricks. :^) It might be far too easy to get something very, very wrong. Yes, I am aware of the fact that one can write a driver routine that is called at every clock tick, but 100 Hz isn't the same as 8000 Hz. Is there a less obtuse, sanctioned way of using one of those timers to my benefit? Any ideas, comments, or perhaps even insults will be appreciated. Quizzed, Andy Pfiffer -- *Yet another obscure reference.
mattc@ncr-sd.SanDiego.NCR.COM (Matt Costello) (06/02/90)
[Originally cross-posted to comp.unix.wizards] In article <9655@ogicse.ogi.edu> apfiffer@admin.ogi.edu (Andy Pfiffer) writes: >I have a dumb A/D converter plugged into a System V/386 system that requires >some clever device-driver wizardry. (I love a challenge) > >It has no on-board interrupt or DMA capability. I need to sample it, >within +/- 10%, at constant, super-HZ (ie: higher than clock tick) intervals; >8000 Hz would be ideal. It sounds as if you are trying to sample speech. If you write a 8 kHz timing routine then it will get called every 125us. Getting the sample within +/-10 percent requires that samples be taken within 12 microseconds of the expected time. This is tricky enough in a timing loop, but with interrupt latency there is no way you are going to do this in a Unix system. Remember that critical kernel sections of code do splhi() to disable interrupts. If serial characters can sometimes be lost because the tty interrupt routine are not called in 2 milliseconds, there is no way you can expect interrupt response within 12 microseconds. To get your sample rate you are going to have to disable all interrupts and go into a very tight polling loop. Any skew in taking samples will result in unexpected harmonics in the resultant data. This will stop the Unix system for 8 seconds, so you will need to advance the clock afterwards. The safest way to do this is to increase the clock interrupt rate 10% until the Unix clock catches up with real time. This will keep all the system timing routines happy at the expense of slight higher execution times for running processes. You would be better off by scrapping the existing A/D board and getting one that has an interval timer and lots (> 8kB) of dual-ported RAM. You could then just have your process do a big read() (80kB for 10 seconds) and then have a callout() routine copy data over every half second or so. As an aside I did something similar back in 1979 on a PDP-11. The information supplied by Digital for the AD-11 claimed that a PDP could not sample faster than 4 kHz in an interrupt driven routine; this on a board that included an interval timer that could automatically take samples every 'n' microseconds. I actually used interrupts since I was writing the data out to magnetic tape in real-time since I needed to take sample speech for 30 minutes. -- Matthew Costello <matt.costello@SanDiego.NCR.COM> (CSNET) +1 619 485 2926 uunet!ncrlnk!ncr-sd!mattc