file: README /*====================================================================== das16s.c v0.05 July 11, 2003 (v0.01 Feb 17 2000) PCM-DAS16s/16 and PC-CARD-DAS16/16 PCMCIA card driver For both Linux and RTLinux kernels. for RTLinux info, see http://www.FSMLabs.com by Steve Rosenbluth (stever8@earthlink.net, stever8@linuxmail.org) PC-CARD-DAS16/16 code Copyright (C) 2003 Steve Rosenbluth. Original PCM-DAS16s/16 code is Copyright (C) 2000,2001 Jim Henson's Creature Shop LA. Version 0.04b mods for 2.4.18 by Michael Babcock michael@kanji.com . The contents of this file are subject to the Mozilla Public License Version 1.1 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.mozilla.org/MPL/ Software distributed under the License is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for the specific language governing rights and limitations under the License. The Original Code is das16s.c rev 0.05 The Initial Developer of the Original Code is Steve Rosenbluth. Portions created by David A. Hinds are Copyright (C) 1999 David A. Hinds. All Rights Reserved. Portions created by Michael Babcock are Copyright (C) 2002 Michael Babcock. All Rights Reserved. ======================================================================*/ INTRODUCTION: ------------ Welcome to the documentation of the driver for the Measurement Computing (Computer Boards) PCM-DAS16s/16 and the PC-CARD-DAS16/16 (16bit, 16 channel, 100Ksps PCMCIA ADC card). This is a beta release - use at your own risk. This release features support for the new version of the card, the PC-CARD-DAS16/16, (the original PCM-DAS16s/16 was discontinued). This release also features non-RTLinux support for normal kernels/interrupts. The das16s driver was developed on RTLinux 3.2-pre1 for Linux kernel 2.4.19 and its kernel pcmcia support. It has not been tested on anything newer. This driver will also compile with the standalone PCMCIA package (tested with pcmcia 3.1.31), though it is now intended is to compile with kernel pcmcia. GCC 2.95.3 was used for all development and testing, it also compiles with gcc-3.2.2 . das16s implements a typical 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, so for this and other reasons multiple cards are not supported yet. The drier can also be acceds through similar function calls in kernelspace, so another module (or RTL-thread) can control the card and obtain ADC samples. Note that the ioctl interface from previous driver versions up to 0.04b is not compatible with this revision, so old apps should be recompiled with the new das16s-config.h (please read the ctl_msg_struct_t definition). Eight-channel differential mode works well on the PC-CARD-DAS16/16. Unfortunately the code supporting this card broke support for single-ended mode of both the old and the new cards. For this reason, a previous release, 0.04b has been included with this source which has been used successfully on the original PCM-DAS16s/16 but with the feature set of rev 0.03 (RTLinux only). Note that to date, single-ended mode has never been used successfully on the new PC-CARD-DAS16/16. Hopefully enough eyes on this code will make the bug trivial, and someone will contribute a patch which fixes the problem. 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 oversampling. Note that Acquisition stops at the end of a burst. Use this mode for software-triggered channel 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. This should be useful enough 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 only been tested a little (by specifying a scan of 1 channel). Because of the channel-scan 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 (see das-16s-config.h). HOW TO BUILD AND LOAD THE DAS16S MODULE : --------------------------------------- Do this: make To use with a RTLinux kernel, You must first uncomment the following line in the Makefile : RTFLAGS = -DUSING_RTLINUX You must have compiled and installed the RTLinux 3.1 (or similar) modules for all RTLinux dependencies to resolve correctly. See http://www.fsmlabs.com/products/openrtlinux To create module dependencies do: depmod -ea To load the driver, you must modify the "config" file in /etc/pcmcia to add card identification bindings : make install-config does this for you by appending definitions for the cards to the end of the /etc/pcmcia/config file. It makes a backup of the original file just in case. The file config.add contains the new defs. Warning: card services only scans the config file when it loads, so you must restart card sevices for "config" changes to take effect : /etc/rc.d/init.d/pcmcia restart make install-config also adds a "daq" file in the /etc/pcmcia directory which creates the device node when the card is detected. The module will fail to load at insertion if this is not done. A device will be created which looks something like this: crw-r--r-- 1 root root 253, 0 Aug 18 14:09 /dev/das16s If you want to create it yourself, check the major number after insmod (use dmesg) and do (assuming major num is 253) : mknod /dev/das16s c 253 0 Insert the card, or, if already inserted, do : cardctl eject which does a logical eject so you don't have to physically remove it, then: cardctl insert 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/das16s to make sure it was created. You may want to change the file permissions or group on this device node if non-root user will use the device. To see if the module loaded OK: cat /proc/modules cat /proc/ioports (Note that an RTLinux irq level will NOT show up in /proc/interrupts) Do this: dmesg you should see something similar this if all went well: das16s.c v0.05 July 11, 2003 (by Steve Rosenbluth ) das16s: device major number is 253 das16s: index 0x20: Vcc 5.0, irq 11, io 0x0300-0x031f das16s: found a PC-CARD-DAS16/16 HOW TO USE DAS16S: ----------------- * Note: single-ended mode is broken int rev 0.05 To test the device, use the "das16s-config" app. This is not meant to be an all-purpose tool, just a coding example. das16s-config basically loads a struct with configuration constants, opens the device, and sends the struct to the driver with an ioctl(). Always include the "das16s-config.h" header to make your 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 (its value is 0xAD, defined in das16s-config.h). Here's how to use das16s-config with the sample apps: for help, do: das16s-config for burst mode, +/- 10 Volts, do: das16s-config b 5 This configures the driver to convert 4 banks in a "burst" using the bipolar 5 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 a "go": das16s-config g Note that now the card is configured now to use DIO bits 0-3 as input, 4,5 as outputs to switch an external multiplexer, and 6,7 are now the two LSbits of any digital output word you send to the card. For continuous mode do: das16s-config c 5 This configures the driver to convert one bank of 16 samples continuously, using the 5 volt gain. Note that differential input is only available on the newer PC-CARD-das16s. Conversions start immediately when you configure the acquisition mode. Continuous conversions will stop when you do a "stop" : das16s-config s To restart conversions, do a "go": das16s-config g The card is configured for 8 digital outputs now, to write them 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. 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. 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 readdas16 will also tell you when the device is empty. test_ui ------- This directory contains a pair of test apps, one does continuous periodic data acquisition (soft real time), the other shows graphical sliders representing channel values. You must build it from within the subdirectories. See the README. rtl_adc_test ------------ This test app demonstrates the kernelspace API. It triggers and get samples inside a RTLinux periodic thread. DIO NOTES: --------- Availability: Note that the driver will reserve the 2 LSBs of the upper DIO nibble (to switch an external multiplexer) if multiple banks are selected. Thats means bits 4-5 are unavailable if you select an acquisition sequence mode of more than 1 bank. If you want all DIO bits available you can simply select one bank in either burst mode or continuous mode. Direction: 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. 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. The user has 4 output bits TIMER NOTES: ----------- These cards support a max sample rate of 100KHz The timer is configured with the following divisors (in ctl_msg_struct_t) : "aux_adc_rate_divisor " Generates clock for adc_rate_divisor. Divides down from 10MHz. "adc_rate_divisor" Configures ADC rate. Divides down from 1MHz if aux_adc_rate_divisor is 10. DEVELOPMENT "TO DOs": ------------------ . 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 once but took the workarounds out in the current handler. . 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 may not support 8 bits of input yet, just banks of 4 bits ? . Optimised single channel sampling must be implemented in the IRQ handler. . Ioctl MAGIC isn't safe ... . support multiple cards by minor device. FOR DEVELOPERS : --------------- Revision Notes for all revisions are in the source code of das16s.c 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. ------------------------------------------------------------------------ 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 or suggestions. -Steve Rosenbluth (stever8@earthlink.net , stever8@linuxmail.org)