I am releasing a new revision of the RTLinux driver for the
Computerboards PCM-DAS16s/16 PCMCIA ADC card.
This is a 100kHz, 16 bit, 16 channel card. The README from the package
is attached.
The driver is available either on the FSMLabs ftp site :
ftp://fsmlabs.com/pub/rtlinux/drivers/
or at the main pcmcia ftp site :
ftp://sourceforge.org/pcmcia/contrib/
By the way, if anyone is interested in helping write a driver for the
National Instruments 200kHz 16 bit pcmcia ADC, there is someone starting
a driver in Australia: [EMAIL PROTECTED]
-- Steve Rosenbluth
file: README
/*======================================================================
das16s.c v0.03 Apr 26 2000 (v0.01 Feb 17 2000)
PCM-DAS16s/16 real-time PCMCIA client driver
for RTLinux (Real Time Linux) kernels only, at present.
see http://www.rtlinux.org/rtlinux
by Steve Rosenbluth ([EMAIL PROTECTED],
[EMAIL PROTECTED])
Copyright (C) 2000 Jim Henson's Creature Shop (Los Angeles)
all code subject to the Mozilla Public license version 1.0
======================================================================*/
This package should contain the following files:
README
Makefile
config
daq
das16s.c
das16s.h
das16s-config.h
das16s-config.c
readdas16.c
INTRODUCTION:
------------
Welcome to the documentation of the driver for the Computer Boards
PCM-DAS16s/16 (16bit, 16 channel, 100Ksps PCMCIA ADC card) This is an
alpha release - use at your own risk. This second release contains
major bug-fixes, and the driver exhibits different behavior than the
previous release.
ComputerBoards now sells both the original "PCM-DAS16s/16" and a new
version with improved connectors and a slightly different register set.
The newer card is not yet supported by this driver.
das16s was developed on RTLinux 2.0 for Linux kernel 2.2.13 and
pcmcia-cs 3.1.8 . It has not been tested on anything else.
das16s is a standalone device, open() a file descriptor to it, use
ioctl() to configure it and read() to get data out of it. It obtains a
dynamic device major number at load time, at present the device minor is
always 0.
The card is currently operational in continuous and "burst" mode. Note
that "burst mode" was designed for the use of an external analog
multiplexer and an external digital multiplexer (which you probably
don't have) each of which can switch into one of four "banks". A "burst"
lasts from 1 to 4 channel-scans(banks), at present. To those without an
external multiplexer, multiple banks may be useful for filtering analog
data, etc. Acquisition STOPS at the end of a burst. Use this mode for
software-triggered scans.
Continuous mode has been tested, but not extensively. A user space app
might miss samples in this mode due to the lack of blocking IO unless it
busy loops on the device read. But this should be useful for
oscilloscope apps, etc. Note that the driver implements a ring buffer
for conversion results. If this buffer overflows in continuous mode,
the oldest result packet gets thrown out to make space for a new result
packet. A read of the device will always return the oldest sample packet
available, somewhat like a FIFO.
The driver is geared toward "channel-scans", or "banks", of ADC
channels. Single channel conversions have not been tested (try
specifying a scan of 1 channel). Also because of this bias, the driver
always delivers a packet large enough to contain 16 analog conversion
results when its device is read. Digital input bits are also in this
packet.
HOW TO LOAD DAS16S:
------------------
To compile, the "das16s*" sources should be put into the pcmcia
distribution's "clients" directory. Then modify the Makefile in the
clients directory to include the following near the top of the file :
SRCS := ${SRCS} das16s.c
EXTRA := ${EXTRA} das16s.o
A sample Makefile is supplied here, You can diff it with the original to
see what is changed. After a make, copy the das16s.o module to
/lib/modules/2.2.13xx/pcmcia/
You must be running a RTLinux kernel to use this driver. You must also
have compiled and installed the RTLinux 2.0 modules for all dependencies
to resolve correctly. See http://www.rtlinux.org/rtlinux
To create module dependencies do:
'depmod -a'
To load the driver, you must modify the "config" file in /etc/pcmcia to
add bindings. add the following near the top of the file:
device "das16s"
class "daq" module "misc/rtl_fifo", "das16s"
Then add the following near the bottom of the file:
card "Computer Boards PCM-DAS16S/16"
version "ComputerBoards, Inc.", "PCM-DAS16S/16", "(c)1996", "Rev2.0"
bind "das16s"
A sample "config" is supplied here, diff it with the original...
You must also add a "daq" file in the /etc/pcmcia directory to create
the device node. A sample file is supplied here - make sure it has
execute permissions ! The module will fail to load at insertion if this
is not done.
Insert the card, or, if already inserted, do :
'cardctl eject <socketnum>'
which does a logical eject, then:
'cardctl insert <socketnum>'
which does a logical insert.
to check the sockets, do:
'cardctl status'
The device will be "/dev/das16s" when created by the "daq" script, which
is run when card services sees the card insertion. Do:
'ls -l /dev/das*'
to make sure it was created. The ownership and permissions on this
device node matter if non-root users apps will use the device.
To see if the module loaded OK:
'cat /proc/modules'
'cat /proc/ioports'
(the RTLinux irq level will NOT show up in /proc/interrupts)
Do 'dmesg', you should see something similar this if all went well:
das16s.c v0.03 April 24, 2000 (by Steve Rosenbluth)
das16s: device major number is 253
das16s: index 0x20: Vcc 5.0, irq 3, io 0x0300-0x030f
HOW TO USE DAS16S:
-----------------
To configure the device, use "das16s-config". This is not meant to be
an all-purpose tool, just a coding example. To compile it, use the
command line in the comment at the beginning of the source file.
das16s-config basically loads a struct with configuration constants,
opens the device, and sends the struct to the driver with an ioctl().
Include the "das16s-config.h" header to make your configuration code
interface with the driver, it contains all configuration definitions.
Note that the driver uses an unregistered magic "DAS16S_IOC_MAGIC" so
use of this could conflict with another driver at some point in the
future.
Here's how to use das16s-config with the sample apps:
for help, do:
'das16s-config'
for burst mode do:
'das16s-config b 10'
This configures the driver to convert 4 banks in a "burst" using the
bipolar 10 volt gain. A single burst will occur when this configuration
is received (discard it by reading it out of the device if necessary).
>From then on, to trigger another burst, do:
'das16s-config g'
For continuous mode do:
'das16s-config c 5'
This configures the driver to convert (as many banks as the struct
requested) continuously, using the bipolar 5 volt gain.
In continuous mode, conversions will not start until you do:
'das16s-config g'
Continuous conversions will stop when you do:
'das16s-config s'
To write the digital outputs do:
'das16s-config o 85'
This will write the digital word 85 (01010101) to the DIO port (see
notes below on DIO port auto-configuration).
Use "readdas16" to read the device. This is not meant to be an all-
purpose tool, just a coding example. To compile it, use the command line
in the comment at the beginning of the source file. readdas16 is
hard-coded to read one "result packet" at a time (RESULT_PACK_SIZE_B
bytes). Currently, the device MUST be read in multiples of "result
packets" up to a total of 32, which reflects the capacity of the card's
fifo. Include the das16s-config.h header in your code to make it
interface with the driver, it contains all configuration definitions.
To read the das16s device, do
'readdas16'
The app will show you the multiplexer address (bank number), like "m:0",
the packed digital input value, then the value of the 16 analog samples
it finds in the result packet, Like this:
m:0 d:8448 27254 27050 27385 27234 29111 31781 34957 32151 35344 36237
35317 33442 31823 29905 29679 27791
readdass will also tell you when the device is empty.
DIO NOTES:
---------
The driver does auto-configuration on the DIO port direction. If no
digital inputs are requested, the port is all output. A digital output
byte appears as expected, with the user's LSB at bit 0 of the DIO port.
Likewise, If no digital output is requested, the DIO port is all input.
If digital inputs are wanted at the same time as digital outputs and
only 1 bank of samples is requested, the driver will behave in the
following way:
Input is on the lower nibble, output on the high nibble of the DIO port.
a digital output byte appears with the user's LSB at bit 4 of the DIO
port.
If user requests digital inputs, digital outputs, and multiple analog
banks or multiple digital input banks, the 2 LSB's of the digital
output nibble (DIO bits 4 and 5) are reserved for addressing an external
multiplexer, so the LSB of the users digital out byte appears at bit 6.
DEVELOPMENT "TO DOs":
------------------
. This is a RTLinux only driver, though I plan on revising it so it can
be used under regular Linux as well.
. The data is raw, calibration constants are not yet used to correct
gain and offset errors.
. The driver isn't yet optimised for samples on a single channel only,
but it does do variable length channel scans.
. The configuration is hard-coded to a single name, and it makes the
driver minor number 0, so multiple cards won't work yet.
. The driver doesn't yet handle blocking IO, you must read w/ the
O_NONBLOCK flag set.
. At very low counter frequencies (like 30 Hz) the end of channel scan
IRQ comes before the end of the scan. I worked around this but took the
workarounds out in the current handler.
. The RTLinux posix_io API will be implemented so that a hard real time
periodic task can pace conversion bursts.
. Have driver load-time configurable so users without an external
multiplexer have use of the 2 Digital output LSBs taken by the mux
address.
. Expand bursts to any quantity up to fifo limit, sampling same channels
together.
. The driver probably doesn't support 8 bits of input yet, just banks of
4 bits - this should be fixed.
. Optimised single channel sampling must be implemented in the IRQ
handler.
. Ioctl MAGIC isn't implemented...
. Support new ComputerBoards card.
. support multiple cards by minor device.
DEVELOPER RELEASE NOTES:
-----------------------
- Revision Notes rev0.03 from the source code -
* added support for digital inputs
* Tried to fix bug where a timer restart in burst mode had out-of-order
samples in first bank - added a channel scan reset to START fop, now
restarts work OK ?
* Fixed bug where we didn't OR w/ mux when writing digital output byte
in fop_ioctl()
* Added "truth table" in fop_ioctl() to set DIO direction based on
number of banks of analog or digital inputs requested: If either > 1 :
upper nibble is output (2 LSBs reserved for external MUX), and if any
dig ins wanted lower is input. If neither > 1 : if no dig ins wanted
upper and lower are output, else when one bank of each wanted lower is
input and upper is output.
* This revision does not use same nibbles of DIO port as 1st rev 0.02 !
* Added support for digital input during burst mode (high nibble only)
* Fixed "missing conversion bug". Driver is much more reliable now. At
begin of burst we start pacer and enable irqs, and at end we stop pacer
and disable irqs. Timeouts are now done by port 0x80 writes.
* Still have 2 known bugs: an "extra conversion" bug where beginning of
a channel scan has errant sample. "bad sample" bug where first channel
value is wrong. One of these might occur 3 or 4 times in a 24 hour
period of continuous sampling.
* Fixed bug where starting a burst in middle of previous burst corrupted
data. Now we ignore the second start. This seems to solve the "extra
conversion" bug above, and it seems to prevent driver lockup.
* Made digital outputs shift left by 2 when an external MUX is in use.
FOR HACKERS:
----------------
The diagnostic verbosity is set to 2 by default. By setting pc_debug to
a number like 5, you can get a lot more info from the driver during
configuration and operation from the DEBUG statements. I wouldn't do
this in continuous mode.
All my initial card programming tests are still in das16s_reset()
(#ifdef'd out) - try them.
Please feel free to send me modified code, or a patch, which advances
the functionality of the driver. I'll do my best to integrate these
promptly.
------------------------------------------------------------------------
email me if you have questions, suggestions.
-Steve
([EMAIL PROTECTED] , [EMAIL PROTECTED])