*** Daqcard700 Real-Time Linux Driver *** This release is: daqcard700.c (daq700pcs.c) v1.04 9-30-1999 These source files are subject to the Mozilla Public License Version 1.0 (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. Originally written by Oleg Subbotin as "daqcard700.c" (oleg@cs.nmt.edu) v1.01 Revised by Steve Rosenbluth, JHCS 10-18-98 v1.02 Revised by Steve Rosenbluth, JHCS 3-17-99 v1.03 Revised by Steve Rosenbluth, JHCS 8-20-99 v1.04 Revised by Steve Rosenbluth, JHCS 9-30-1999 Copyright(C) 1998, 1999 Jim Henson's Creature Shop. Except original daqcard700_interrupt() function - Copyright(C) 1998, Oleg Subbotin. Note that the source files are also known by their internal JHCS names: daq700pcs.c , daq700pcs.h , daq700pcs-config.h For correspondence write to : stever@silicon.net / stever@la.creatureshop.henson.com ------------------------------------------------------------------------- Some Installation Notes: This revision (1.04) is tested on kernel 2.2.12 with pcmcia-cs 3.1.0 . This revision reflects major changes in the way the card is programmed, which seem to eliminate the channel-shifting bug. Use of older revisions is discouraged. In order to compile the daqcard driver: You must run a real time linux kernel and have the rtlinux sources on your system. The rtlinux include paths in the daqcard sources may need to be changed for your system. Insert the daqcard source files into a pcmcia-cs source tree. We do it this way: Put daqcard700.c, daqcard700-config.h, daqcard700.h into /usr/src/pcmcia-cs-3.1.0/clients/ Modify the makefile in there by adding: SRCS := ${SRCS} daqcard700.c EXTRA := ${EXTRA} daqcard700.o Doing a make there or at top level should compile the daqcard module. (a sample makefile is in this distribution) The pcmcia install won't install the daqcard driver module. Install it manually by copying it to /lib/modules/linux-x.x.xx/pcmcia In order for card services to load the driver when it finds the card, you must add the following to /etc/pcmcia/config : device "daqcard700" class "daq" module "misc/rtl_fifo", "daqcard700" Also add: card "National Instruments DaqCard700" version "National Instruments", "DAQCard-700" bind "daqcard700" (a sample 'config' file is in this distribution) You must also have present the file /etc/pcmcia/daq or bad things may happen, like the module getting loaded but data structures not getting allocated, causing segfaults. This file is included in the distribution. You may need to modify /etc/pcmcia/config.opts to exclude or specify some irq levels. (a sample config.opts file is in this distribution) You might need to create the rtfifo devices in /dev, though the rtlinux install tries to do this automatically. See the rtlinux documentation. Mine have links with intuitive names and look like this: lrwxrwxrwx 1 root root 4 Jan 4 1999 /dev/daq -> rtf0 lrwxrwxrwx 1 root root 4 Jan 4 1999 /dev/daqctl -> rtf1 lrwxrwxrwx 1 root root 4 Mar 12 11:48 /dev/daqdio -> rtf2 Use the "daq-config" sample app to configure and test burst mode, digital IO, and continuous mode. Look at it's options (type "daq-config"). It is very useful for testing in conjunction with the "rtfraw" app which prints the results from the daqcard rtfifos (type "rtfraw --help"). Note that the sample scope app requires qt. It has a sampling delay which I never bothered to debug. ------------------------------------------------------------------------- Revision Notes: Revision Notes v1.01 : driver is now runtime configurable by writing a config struct to an "incoming" rt-fifo. struct and necessary constants are defined in daqcard700-config.h. configurable options include: burst-mode acq, variable start-conversion timer period, variable banks (num samples per chan), choice of voltage range, result number-system choice, option to not use calib constants, acquisition can be stopped and started by user, etc... Driver still operates as 1.0 did if you just load it and do a 'cardctl reset' A sample configuration app 'daq-config' is included in source form. Lots of commenting was done. Many identifiers have been re-named, constants capitalized, variables introduced, etc (you probably can't 'diff' 1.0 and 1.01). D. Hinds' redefine of the X macro has been adopted because we couldn't compile without it on 2.0.35 with modversions. Bug fix: input_mode is ANDed when used (to clear unwanted bits). Bug fix: gain_error math parenthesis have been fixed. Some other logical bugs are fixed..., maybe 'diff' will tell you what they are. Many things are left undone - check the source, and use at your own risk. Revisions Notes v1.02 : * Drivers 1.01 and 1.02 successfuly compile with kernel 2.0.35 and pcmcia-cs-3.0.7 Driver 1.02 successfuly compiles with pcmcia-cs-3.0.12 also * Now supports digital output: Send a byte to daqcard driver through the config fifo and the 5 MSB's of it will appear on the digital output lines of the card when the next interrupt occurs (3 LSB's are reserved for multiplexing analog and digital inputs). see the daqcard700-config.h file for config struct format, and try "daq-config" sample app. * Now supports digital input: Any change in the logic levels on the digital input byte of the card is written to a digital input result rt-fifo on the next interrupt. A new config field specifies one or two banks of digital input. Try the "daq-config" sample app and do "cat /dev/rtf2" . * Known bug: on some systems, the first conversion is sometimes missing from a multi-channel, multi-bank sample burst. * Known bug: 'cardctl reset' might permanently disable burst mode ... Revision Notes v1.03 : * Digital output access is changed. Now all 8 bits are available if not using multiple banks of ADC or DIO. Otherwise, 6 MSBs available for digital output. * Change in config structure and daqcard700_dev_t variable names, new vars too. * Major changes were made to daqcard700_interrupt() function. It now addresses up to 4 banks of analog and up to 4 banks of digital inputs. "Global" vars were taken out of handler and given to device-specific structure for support of multiple daqcards. daqcard_config() now inits some of those vars. * Digital input banks use the same 2 digital out LSBs to switch an external mux. * Fixed data buffer dereferencing bug and a non-static variable bug in handler. * Added & revised many comments in irq handler. * Added a work-around for the "banks bug", where chan15 comes back as chan14, etc in multi-bank mode. Users can set this with insmod if they need it: insmod need_banks_delay=1, or put in /etc/pcmcia/config.opts: module "daqcard700" opts "need_banks_delay=1" * Removed redundant channel-scan disabling when we disable interrupts in handler * Hot-swapping appears to work OK now, with k2.0.35 and pcmcia-cs 3.0.12 * Digital IO was broken in 1.03, don't use this revision ! use 1.02 for kernel 2.0 and 1.04 for kernel 2.2 Revision Notes v1.04 : * Ported to kernel 2.2.12 , RTlinuxbeta15, card services 3.1.0, gcc 2.95.1 All previous revisions were only tested on k2.0.35 w/ pcmcia 3.0.12 * Check and report errors on all rtlinux API calls in init_module() and daqcard700_config() * Print errors when kmallocs fail in daqcard700_attach() * Use CardServices() return constants in daqcard700_attach() * daqcard700_detach(): changed error message, still not done w/ locking issue. * Had to add "daq" class file to /etc/pcmcia for cs to succeed in loading this driver * fixed messed up _release() stuff in _detach(). now _detach() sets stale_link flag and returns, allowing cleanup_module() to call it later. * added (crude) error-checking for data errors * irq handler: fixed missing reentry_stat reset when devlist == NULL * Finally fixed the "banks bug" ! This is a major change: we no longer disable irqs on adc chipset. Now, bursts are started/stopped by en/disabling the timer chip which paces conversions. * Fixed bug where switching between continuous and burst mode caused conversions to be out of order. 'Stop' resets chan_cnt and mux now. * Reimplemented 'burst_done" flag in dev_info and irq handler. * Probably fixed the "channel shift" bug where conversions got out of order. Each irq handler now resets ADC channel_scan and clears adc/fifo at end of a bank, also 'Start' now resets ADC channel_scan and clears adc/fifo. 'Start' now also avoids doing this if in continuous mode. ------------------------------------------------------------------------- Some informative snippets from an email conversation: > 1) Are their any "gotchas" that your aware of with the > existing driver or is it pretty stable? Its stable for my purposes - but remember I use the thing in "burst mode" always, so I haven't fully tested all the features. The driver has no catastrophic problems, but there are some known bugs: Bug 1: I havent seen it in several months and can't reproduce it: I installed on a second laptop once and found that in burst mode, the first sample (of 4 banks) was missing occasionally. So all the samples slid down one: 1 became 0, 2->1...14->13, I think 0 becomes 15. I debugged the driver some when this was happening, I couldn't produce an adequate test which would show what was causing these results. Its the kind of thing that only happens when running at full speed. Its as if the hardware FIFO on the card skipped a conversion or something. I also saw this on my primary laptop once when I did a re-install of Linux, then it dissappeared when I re-loaded from a backup. Bug 2: Occasionally, after you request a burst of samples through the "config-fifo" they never get sent down the "results fifo". this might happen a few times an hour. If you look in the driver you'll see some preliminary debugging code which is commented out. notably the "conversion ID", which makes packets bigger but can help keep track of whether the results you're getting are from your last request. Bug 3: After performing a 'cardctl reset', configuration packets mysteriously fail to take effect. So - don't do it and you'll have a continuously configurable driver (cardctl is a very basic interface, and it's not available to user apps - use the configuration fifo!). Bug 4: Hot-swapping the card doesn't work yet. I always boot with the card in. Ejecting the card will generate errors, but is not fatal. > 2) Do you have any general advice about using RTL side > by side with the PCMCIA utils? Nope, works great. I have used the RT-Daqcard driver in both slots (Gateway 9100LS) with modem and 16-bit ethernet cards running in the other slot, and now I use a Cardbus 10/100bT ethernet alongside the Daqcard. I use k2.0.35 and pcmcia-cs 3.0.12. Some PCMCIA programming advice: get to know everything about the interrupts in use on your laptop. look at /proc/pci and the BIOS settings, and try several interrupts when you install your driver. Also make sure there are descriptions of your driver in the /etc/pcmcia/config and config.opts files or it won't autoload. Read David Hinds' PCMCIA Howto. When you boot, the first high beep means a recognised card, the second high beep means pcmcia loaded the driver (low beeps mean failure). When coding, use kprintf a lot and look at 'dmesg' output a lot. --------------------------------------------------------------- Note: the daqcard700 driver v 1.01 has been hacked to work with a daqcard500 also. Contact me or the RTLinux mailing list for details. - Steve Rosenbluth 10-28-1999 stever@silicon.net stever@la.creatureshop.henson.com