📄 das16.c
字号:
/* comedi/drivers/das16.c DAS16 driver COMEDI - Linux Control and Measurement Device Interface Copyright (C) 2000 David A. Schleef <ds@schleef.org> Copyright (C) 2000 Chris R. Baugher <baugher@enteract.com> Copyright (C) 2001,2002 Frank Mori Hess <fmhess@users.sourceforge.net> This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.*************************************************************************//*Driver: das16.oDescription: DAS16 compatible boardsAuthor: Sam Moore, Warren Jasper, ds, Chris Baugher, Frank Hess, Roman FietzeDevices: [Keithley Metrabyte] DAS-16 (das-16), DAS-16G (das-16g), DAS-16F (das-16f), DAS-1201 (das-1201), DAS-1202 (das-1202), DAS-1401 (das-1401), DAS-1402 (das-1402), DAS-1601 (das-1601), DAS-1602 (das-1602), [ComputerBoards] PC104-DAS16/JR (pc104-das16jr), PC104-DAS16JR/16 (pc104-das16jr/16), CIO-DAS16JR/16 (cio-das16jr/16), CIO-DAS16/JR (cio-das16/jr), CIO-DAS1401/12 (cio-das1401/12), CIO-DAS1402/12 (cio-das1402/12), CIO-DAS1402/16 (cio-das1402/16), CIO-DAS1601/12 (cio-das1601/12), CIO-DAS1602/12 (cio-das1602/12), CIO-DAS1602/16 (cio-das1602/16), CIO-DAS16/330 (cio-das16/330)Status: worksUpdated: 2002-09-30A rewrite of the das16 and das1600 drivers.Options: [0] - base io address [1] - irq (optional) [2] - dma (optional) [3] - master clock speed in MHz (optional, 1 or 10, ignored if board can probe clock, defaults to 1) [4] - analog input range lowest voltage in microvolts (optional, only useful if your board does not have software programmable gain) [5] - analog input range highest voltage in microvolts (optional, only useful if board does not have software programmable gain) [6] - analog output range lowest voltage in microvolts (optional) [7] - analog output range highest voltage in microvolts (optional) [8] - use timer mode for DMA, needed e.g. for buggy DMA controller in NS CS5530A (Geode Companion), and for 'jr' cards that lack a hardware fifo. If set, also allows comedi_command() to be run without an irq.Passing a zero for an option is the same as leaving it unspecified.Both a dma channel and an irq (or use of 'timer mode', option 8) are requiredfor timed or externally triggered conversions. The JR versions of the boardsshould use 'timer mode' instead of an irq, due to their lack of a hardwarefifo.*//*Testing and debugging help provided by Daniel Koch.Keithley Manuals: 2309.PDF (das16) 4919.PDF (das1400, 1600) 4922.PDF (das-1400) 4923.PDF (das1200, 1400, 1600)Computer boards manuals also available from their website www.measurementcomputing.com*/#include <linux/comedidev.h>#include <linux/pci.h>#include <asm/dma.h>#include "8253.h"#include "8255.h"#include "comedi_fc.h"#undef DEBUG//#define DEBUG#ifdef DEBUG#define DEBUG_PRINT(format, args...) rt_printk("das16: " format, ## args)#else#define DEBUG_PRINT(format, args...)#endif#define DAS16_SIZE 20 // number of ioports#define DAS16_DMA_SIZE 0xff00 // size in bytes of allocated dma buffer/* cio-das16.pdf "das16" "das16/f" 0 a/d bits 0-3 start 12 bit 1 a/d bits 4-11 unused 2 mux read mux set 3 di 4 bit do 4 bit 4 unused ao0_lsb 5 unused ao0_msb 6 unused ao1_lsb 7 unused ao1_msb 8 status eoc uni/bip interrupt reset 9 dma, int, trig ctrl set dma, int a pacer control unused b reserved reserved cdef 8254 0123 8255*//* cio-das16jr.pdf "das16jr" 0 a/d bits 0-3 start 12 bit 1 a/d bits 4-11 unused 2 mux read mux set 3 di 4 bit do 4 bit 4567 unused unused 8 status eoc uni/bip interrupt reset 9 dma, int, trig ctrl set dma, int a pacer control unused b gain status gain control cdef 8254*//* cio-das16jr_16.pdf "das16jr_16" 0 a/d bits 0-7 start 16 bit 1 a/d bits 8-15 unused 2 mux read mux set 3 di 4 bit do 4 bit 4567 unused unused 8 status eoc uni/bip interrupt reset 9 dma, int, trig ctrl set dma, int a pacer control unused b gain status gain control cdef 8254*//* cio-das160x-1x.pdf "das1601/12" "das1602/12" "das1602/16" 0 a/d bits 0-3 start 12 bit 1 a/d bits 4-11 unused 2 mux read mux set 3 di 4 bit do 4 bit 4 unused ao0_lsb 5 unused ao0_msb 6 unused ao1_lsb 7 unused ao1_msb 8 status eoc uni/bip interrupt reset 9 dma, int, trig ctrl set dma, int a pacer control unused b gain status gain control cdef 8254 400 8255 404 unused conversion enable 405 unused burst enable 406 unused das1600 enable 407 status*/static const int sample_size = 2; // size in bytes of a sample from board#define DAS16_TRIG 0#define DAS16_AI_LSB 0#define DAS16_AI_MSB 1#define DAS16_MUX 2#define DAS16_DIO 3#define DAS16_AO_LSB(x) ((x)?6:4)#define DAS16_AO_MSB(x) ((x)?7:5)#define DAS16_STATUS 8#define BUSY (1<<7)#define UNIPOLAR (1<<6)#define DAS16_MUXBIT (1<<5)#define DAS16_INT (1<<4)#define DAS16_CONTROL 9#define DAS16_INTE (1<<7)#define DAS16_IRQ(x) (((x) & 0x7) << 4)#define DMA_ENABLE (1<<2)#define PACING_MASK 0x3#define INT_PACER 0x03#define EXT_PACER 0x02#define DAS16_SOFT 0x00#define DAS16_PACER 0x0A#define DAS16_CTR0 (1<<1)#define DAS16_TRIG0 (1<<0)#define BURST_LEN_BITS(x) (((x) & 0xf) << 4)#define DAS16_GAIN 0x0B#define DAS16_CNTR0_DATA 0x0C#define DAS16_CNTR1_DATA 0x0D#define DAS16_CNTR2_DATA 0x0E#define DAS16_CNTR_CONTROL 0x0F#define DAS16_TERM_CNT 0x00#define DAS16_ONE_SHOT 0x02#define DAS16_RATE_GEN 0x04#define DAS16_CNTR_LSB_MSB 0x30#define DAS16_CNTR0 0x00#define DAS16_CNTR1 0x40#define DAS16_CNTR2 0x80#define DAS1600_CONV 0x404#define DAS1600_CONV_DISABLE 0x40#define DAS1600_BURST 0x405#define DAS1600_BURST_VAL 0x40#define DAS1600_ENABLE 0x406#define DAS1600_ENABLE_VAL 0x40#define DAS1600_STATUS_B 0x407#define DAS1600_BME 0x40#define DAS1600_ME 0x20#define DAS1600_CD 0x10#define DAS1600_WS 0x02#define DAS1600_CLK_10MHZ 0x01static comedi_lrange range_das1x01_bip = { 4, { BIP_RANGE( 10 ), BIP_RANGE( 1 ), BIP_RANGE( 0.1 ), BIP_RANGE( 0.01 ),}};static comedi_lrange range_das1x01_unip = { 4, { UNI_RANGE( 10 ), UNI_RANGE( 1 ), UNI_RANGE( 0.1 ), UNI_RANGE( 0.01 ),}};static comedi_lrange range_das1x02_bip = { 4, { BIP_RANGE( 10 ), BIP_RANGE( 5 ), BIP_RANGE( 2.5 ), BIP_RANGE( 1.25 ),}};static comedi_lrange range_das1x02_unip = { 4, { UNI_RANGE( 10 ), UNI_RANGE( 5 ), UNI_RANGE( 2.5 ), UNI_RANGE( 1.25 ),}};static comedi_lrange range_das16jr = { 9, { // also used by 16/330 BIP_RANGE( 10 ), BIP_RANGE( 5 ), BIP_RANGE( 2.5 ), BIP_RANGE( 1.25 ), BIP_RANGE( 0.625 ), UNI_RANGE( 10 ), UNI_RANGE( 5 ), UNI_RANGE( 2.5 ), UNI_RANGE( 1.25 ),}};static comedi_lrange range_das16jr_16 = { 8, { BIP_RANGE( 10 ), BIP_RANGE( 5 ), BIP_RANGE( 2.5 ), BIP_RANGE( 1.25 ), UNI_RANGE( 10 ), UNI_RANGE( 5 ), UNI_RANGE( 2.5 ), UNI_RANGE( 1.25 ),}};static int das16jr_gainlist[] = { 8, 0, 1, 2, 3, 4, 5, 6, 7 };static int das16jr_16_gainlist[] = { 0, 1, 2, 3, 4, 5, 6, 7 };static int das1600_gainlist[] = { 0, 1, 2, 3 };enum { das16_pg_none = 0, das16_pg_16jr, das16_pg_16jr_16, das16_pg_1601, das16_pg_1602,};static int *das16_gainlists[] = { NULL, das16jr_gainlist, das16jr_16_gainlist, das1600_gainlist, das1600_gainlist,};static comedi_lrange *das16_ai_uni_lranges[]={ &range_unknown, &range_das16jr, &range_das16jr_16, &range_das1x01_unip, &range_das1x02_unip,};static comedi_lrange *das16_ai_bip_lranges[]={ &range_unknown, &range_das16jr, &range_das16jr_16, &range_das1x01_bip, &range_das1x02_bip,};struct munge_info{ uint8_t byte; unsigned have_byte : 1;};static int das16_ao_winsn(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,lsampl_t *data);static int das16_do_wbits(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,lsampl_t *data);static int das16_di_rbits(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,lsampl_t *data);static int das16_ai_rinsn(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,lsampl_t *data);static int das16_cmd_test(comedi_device *dev,comedi_subdevice *s,comedi_cmd *cmd);static int das16_cmd_exec(comedi_device *dev,comedi_subdevice *s);static int das16_cancel(comedi_device *dev, comedi_subdevice *s);static void das16_reset(comedi_device *dev);static void das16_dma_interrupt(int irq, void *d, struct pt_regs *regs);static void das16_timer_interrupt(unsigned long arg);static void das16_interrupt(comedi_device *dev);static unsigned int das16_set_pacer(comedi_device *dev, unsigned int ns, int flags);static int das1600_mode_detect(comedi_device *dev);static unsigned int das16_suggest_transfer_size(comedi_device *dev, comedi_cmd cmd);static void init_munge_info( struct munge_info *info );static void write_byte_to_buffer( comedi_device *dev, comedi_subdevice *subd, uint8_t raw_byte );static void das16_write_array_to_buffer( comedi_device *dev, void *data, unsigned int num_bytes );static void reg_dump(comedi_device *dev);typedef struct das16_board_struct{ char *name; void *ai; unsigned int ai_nbits; unsigned int ai_speed; // max conversion speed in nanosec unsigned int ai_pg; void *ao; unsigned int ao_nbits; void *di; void *do_; unsigned int i8255_offset; unsigned int i8254_offset; unsigned int size; unsigned int id;} das16_board;static struct das16_board_struct das16_boards[]={ { name: "das-16", ai: das16_ai_rinsn, ai_nbits: 12, ai_speed: 15000, ai_pg: das16_pg_none, ao: das16_ao_winsn, ao_nbits: 12, di: das16_di_rbits, do_: das16_do_wbits, i8255_offset: 0x10, i8254_offset: 0x0c, size: 0x14, id: 0x00, }, { name: "das-16g", ai: das16_ai_rinsn, ai_nbits: 12, ai_speed: 15000, ai_pg: das16_pg_none, ao: das16_ao_winsn, ao_nbits: 12, di: das16_di_rbits, do_: das16_do_wbits, i8255_offset: 0x10, i8254_offset: 0x0c, size: 0x14, id: 0x00, }, { name: "das-16f", ai: das16_ai_rinsn, ai_nbits: 12, ai_speed: 8500, ai_pg: das16_pg_none, ao: das16_ao_winsn, ao_nbits: 12, di: das16_di_rbits, do_: das16_do_wbits, i8255_offset: 0x10, i8254_offset: 0x0c, size: 0x14, id: 0x00, }, { name: "cio-das16", // cio-das16.pdf ai: das16_ai_rinsn, ai_nbits: 12, ai_speed: 20000, ai_pg: das16_pg_none, ao: das16_ao_winsn, ao_nbits: 12, di: das16_di_rbits, do_: das16_do_wbits, i8255_offset: 0x10, i8254_offset: 0x0c, size: 0x14, id: 0x80, }, { name: "cio-das16/f", // das16.pdf ai: das16_ai_rinsn, ai_nbits: 12, ai_speed: 10000, ai_pg: das16_pg_none, ao: das16_ao_winsn, ao_nbits: 12, di: das16_di_rbits, do_: das16_do_wbits, i8255_offset: 0x10, i8254_offset: 0x0c, size: 0x14, id: 0x80, }, { name: "cio-das16/jr", // cio-das16jr.pdf ai: das16_ai_rinsn, ai_nbits: 12, ai_speed: 7692, ai_pg: das16_pg_16jr, ao: NULL, di: das16_di_rbits, do_: das16_do_wbits, i8255_offset: 0, i8254_offset: 0x0c, size: 0x10, id: 0x00, }, { name: "pc104-das16jr", // pc104-das16jr_xx.pdf ai: das16_ai_rinsn, ai_nbits: 12, ai_speed: 3300, ai_pg: das16_pg_16jr, ao: NULL, di: das16_di_rbits, do_: das16_do_wbits, i8255_offset: 0, i8254_offset: 0x0c, size: 0x10, id: 0x00, }, { name: "cio-das16jr/16", // cio-das16jr_16.pdf ai: das16_ai_rinsn, ai_nbits: 16, ai_speed: 10000, ai_pg: das16_pg_16jr_16, ao: NULL, di: das16_di_rbits, do_: das16_do_wbits, i8255_offset: 0, i8254_offset: 0x0c, size: 0x10, id: 0x00, }, { name: "pc104-das16jr/16", // pc104-das16jr_xx.pdf ai: das16_ai_rinsn, ai_nbits: 16, ai_speed: 10000, ai_pg: das16_pg_16jr_16, ao: NULL, di: das16_di_rbits, do_: das16_do_wbits, i8255_offset: 0, i8254_offset: 0x0c, size: 0x10, id: 0x00, }, { name: "das-1201", // 4924.pdf (keithley user's manual) ai: das16_ai_rinsn, ai_nbits: 12, ai_speed: 20000, ai_pg: das16_pg_none, ao: NULL, di: das16_di_rbits, do_: das16_do_wbits, i8255_offset: 0x400, i8254_offset: 0x0c, size: 0x408, id: 0x20, }, { name: "das-1202", // 4924.pdf (keithley user's manual) ai: das16_ai_rinsn, ai_nbits: 12, ai_speed: 10000, ai_pg: das16_pg_none, ao: NULL, di: das16_di_rbits, do_: das16_do_wbits, i8255_offset: 0x400, i8254_offset: 0x0c, size: 0x408, id: 0x20, }, { name: "das-1401", // 4919.pdf and 4922.pdf (keithley user's manual) ai: das16_ai_rinsn, ai_nbits: 12, ai_speed: 10000, ai_pg: das16_pg_1601, ao: NULL, di: das16_di_rbits, do_: das16_do_wbits, i8255_offset: 0x0, i8254_offset: 0x0c, size: 0x408, id: 0xc0 // 4919.pdf says id bits are 0xe0, 4922.pdf says 0xc0 }, { name: "das-1402", // 4919.pdf and 4922.pdf (keithley user's manual) ai: das16_ai_rinsn, ai_nbits: 12, ai_speed: 10000, ai_pg: das16_pg_1602, ao: NULL, di: das16_di_rbits, do_: das16_do_wbits, i8255_offset: 0x0, i8254_offset: 0x0c, size: 0x408, id: 0xc0 // 4919.pdf says id bits are 0xe0, 4922.pdf says 0xc0 }, { name: "das-1601", // 4919.pdf ai: das16_ai_rinsn, ai_nbits: 12, ai_speed: 10000, ai_pg: das16_pg_1601, ao: das16_ao_winsn, ao_nbits: 12, di: das16_di_rbits, do_: das16_do_wbits, i8255_offset: 0x400, i8254_offset: 0x0c, size: 0x408, id: 0xc0 }, { name: "das-1602", // 4919.pdf ai: das16_ai_rinsn, ai_nbits: 12, ai_speed: 10000, ai_pg: das16_pg_1602, ao: das16_ao_winsn, ao_nbits: 12, di: das16_di_rbits, do_: das16_do_wbits, i8255_offset: 0x400, i8254_offset: 0x0c, size: 0x408,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -