2 das1800.c driver for Keitley das1700/das1800 series boards
3 Copyright (C) 2000 Frank Mori Hess <fmhess@users.sourceforge.net>
5 COMEDI - Linux Control and Measurement Device Interface
6 Copyright (C) 2000 David A. Schleef <ds@schleef.org>
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 ************************************************************************
26 Description: Keithley Metrabyte DAS1800 (& compatibles)
27 Author: Frank Mori Hess <fmhess@users.sourceforge.net>
28 Devices: [Keithley Metrabyte] DAS-1701ST (das-1701st),
29 DAS-1701ST-DA (das-1701st-da), DAS-1701/AO (das-1701ao),
30 DAS-1702ST (das-1702st), DAS-1702ST-DA (das-1702st-da),
31 DAS-1702HR (das-1702hr), DAS-1702HR-DA (das-1702hr-da),
32 DAS-1702/AO (das-1702ao), DAS-1801ST (das-1801st),
33 DAS-1801ST-DA (das-1801st-da), DAS-1801HC (das-1801hc),
34 DAS-1801AO (das-1801ao), DAS-1802ST (das-1802st),
35 DAS-1802ST-DA (das-1802st-da), DAS-1802HR (das-1802hr),
36 DAS-1802HR-DA (das-1802hr-da), DAS-1802HC (das-1802hc),
37 DAS-1802AO (das-1802ao)
40 The waveform analog output on the 'ao' cards is not supported.
41 If you need it, send me (Frank Hess) an email.
43 Configuration options:
44 [0] - I/O port base address
45 [1] - IRQ (optional, required for timed or externally triggered conversions)
46 [2] - DMA0 (optional, requires irq)
47 [3] - DMA1 (optional, requires irq and dma0)
51 This driver supports the following Keithley boards:
74 [1] - irq (optional, required for timed or externally triggered conversions)
75 [2] - dma0 (optional, requires irq)
76 [3] - dma1 (optional, requires irq and dma0)
78 irq can be omitted, although the cmd interface will not work without it.
80 analog input cmd triggers supported:
81 start_src: TRIG_NOW | TRIG_EXT
82 scan_begin_src: TRIG_FOLLOW | TRIG_TIMER | TRIG_EXT
83 scan_end_src: TRIG_COUNT
84 convert_src: TRIG_TIMER | TRIG_EXT (TRIG_EXT requires scan_begin_src == TRIG_FOLLOW)
85 stop_src: TRIG_COUNT | TRIG_EXT | TRIG_NONE
87 scan_begin_src triggers TRIG_TIMER and TRIG_EXT use the card's
88 'burst mode' which limits the valid conversion time to 64 microseconds
89 (convert_arg <= 64000). This limitation does not apply if scan_begin_src
93 Only the DAS-1801ST has been tested by me.
94 Unipolar and bipolar ranges cannot be mixed in the channel/gain list.
97 Make it automatically allocate irq and dma channels if they are not specified
98 Add support for analog out on 'ao' cards
99 read insn for analog out
102 #include <linux/comedidev.h>
104 #include <linux/ioport.h>
108 #include "comedi_fc.h"
111 #define DAS1800_SIZE 16 //uses 16 io addresses
112 #define FIFO_SIZE 1024 // 1024 sample fifo
113 #define TIMER_BASE 200 // 5 Mhz master clock
114 #define UNIPOLAR 0x4 // bit that determines whether input range is uni/bipolar
115 #define DMA_BUF_SIZE 0x1ff00 // size in bytes of dma buffers
117 /* Registers for the das1800 */
118 #define DAS1800_FIFO 0x0
119 #define DAS1800_QRAM 0x0
120 #define DAS1800_DAC 0x0
121 #define DAS1800_SELECT 0x2
124 #define DAC(a) (0x2 + a)
125 #define DAS1800_DIGITAL 0x3
126 #define DAS1800_CONTROL_A 0x4
133 #define DAS1800_CONTROL_B 0x5
137 #define DMA_CH5_CH6 0x5
138 #define DMA_CH6_CH7 0x6
139 #define DMA_CH7_CH5 0x7
140 #define DMA_ENABLED 0x3 //mask used to determine if dma is enabled
149 #define DAS1800_CONTROL_C 0X6
157 #define DAS1800_STATUS 0x7
158 // bits that prevent interrupt status bits (and CVEN) from being cleared on write
159 #define CLEAR_INTR_MASK (CVEN_MASK | 0x1f)
166 #define CVEN_MASK 0x40 // masks CVEN on write
168 #define DAS1800_BURST_LENGTH 0x8
169 #define DAS1800_BURST_RATE 0x9
170 #define DAS1800_QRAM_ADDRESS 0xa
171 #define DAS1800_COUNTER 0xc
173 #define IOBASE2 0x400 //offset of additional ioports used on 'ao' cards
176 das1701st, das1701st_da, das1702st, das1702st_da, das1702hr, das1702hr_da,
177 das1701ao, das1702ao, das1801st, das1801st_da, das1802st, das1802st_da,
178 das1802hr, das1802hr_da, das1801hc, das1802hc, das1801ao, das1802ao
181 static int das1800_attach(comedi_device *dev, comedi_devconfig *it);
182 static int das1800_detach(comedi_device *dev);
183 static int das1800_probe(comedi_device *dev);
184 static int das1800_cancel(comedi_device *dev, comedi_subdevice *s);
185 static irqreturn_t das1800_interrupt(int irq, void *d PT_REGS_ARG);
186 static int das1800_ai_poll(comedi_device *dev,comedi_subdevice *s);
187 static void das1800_ai_handler(comedi_device *dev);
188 static void das1800_handle_dma(comedi_device *dev, comedi_subdevice *s, unsigned int status);
189 static void das1800_flush_dma(comedi_device *dev, comedi_subdevice *s);
190 static void das1800_flush_dma_channel(comedi_device *dev, comedi_subdevice *s, unsigned int channel, uint16_t *buffer);
191 static void das1800_handle_fifo_half_full(comedi_device *dev, comedi_subdevice *s);
192 static void das1800_handle_fifo_not_empty(comedi_device *dev, comedi_subdevice *s);
193 static int das1800_ai_do_cmdtest(comedi_device *dev,comedi_subdevice *s,comedi_cmd *cmd);
194 static int das1800_ai_do_cmd(comedi_device *dev, comedi_subdevice *s);
195 static int das1800_ai_rinsn(comedi_device *dev, comedi_subdevice *s, comedi_insn *insn, lsampl_t *data);
196 static int das1800_ao_winsn(comedi_device *dev, comedi_subdevice *s, comedi_insn *insn, lsampl_t *data);
197 static int das1800_di_rbits(comedi_device *dev, comedi_subdevice *s, comedi_insn *insn, lsampl_t *data);
198 static int das1800_do_wbits(comedi_device *dev, comedi_subdevice *s, comedi_insn *insn, lsampl_t *data);
200 static int das1800_set_frequency(comedi_device *dev);
201 static unsigned int burst_convert_arg(unsigned int convert_arg, int round_mode);
202 static unsigned int suggest_transfer_size(comedi_cmd *cmd);
204 // analog input ranges
205 static const comedi_lrange range_ai_das1801 = {
211 RANGE( -0.02, 0.02 ),
219 static const comedi_lrange range_ai_das1802 = {
233 typedef struct das1800_board_struct{
235 int ai_speed; /* max conversion period in nanoseconds */
236 int resolution; /* bits of ai resolution */
237 int qram_len; /* length of card's channel / gain queue */
238 int common; /* supports AREF_COMMON flag */
239 int do_n_chan; /* number of digital output channels */
240 int ao_ability; /* 0 == no analog out, 1 == basic analog out, 2 == waveform analog out */
241 int ao_n_chan; /* number of analog out channels */
242 const comedi_lrange *range_ai; /* available input ranges */
245 /* Warning: the maximum conversion speeds listed below are
246 * not always achievable depending on board setup (see
249 static const das1800_board das1800_boards[] =
260 range_ai: &range_ai_das1801,
263 name: "das-1701st-da",
271 range_ai: &range_ai_das1801,
282 range_ai: &range_ai_das1802,
285 name: "das-1702st-da",
293 range_ai: &range_ai_das1802,
304 range_ai: &range_ai_das1802,
307 name: "das-1702hr-da",
315 range_ai: &range_ai_das1802,
326 range_ai: &range_ai_das1801,
337 range_ai: &range_ai_das1802,
348 range_ai: &range_ai_das1801,
351 name: "das-1801st-da",
359 range_ai: &range_ai_das1801,
370 range_ai: &range_ai_das1802,
373 name: "das-1802st-da",
381 range_ai: &range_ai_das1802,
392 range_ai: &range_ai_das1802,
395 name: "das-1802hr-da",
403 range_ai: &range_ai_das1802,
414 range_ai: &range_ai_das1801,
425 range_ai: &range_ai_das1802,
436 range_ai: &range_ai_das1801,
447 range_ai: &range_ai_das1802,
451 * Useful for shorthand access to the particular board structure
453 #define thisboard ((const das1800_board *)dev->board_ptr)
456 volatile unsigned int count; /* number of data points left to be taken */
457 unsigned int divisor1; /* value to load into board's counter 1 for timed conversions */
458 unsigned int divisor2; /* value to load into board's counter 2 for timed conversions */
459 int do_bits; /* digital output bits */
460 int irq_dma_bits; /* bits for control register b */
461 /* dma bits for control register b, stored so that dma can be
462 * turned on and off */
464 unsigned int dma0; /* dma channels used */
466 volatile unsigned int dma_current; /* dma channel currently in use */
467 uint16_t *ai_buf0; /* pointers to dma buffers */
469 uint16_t *dma_current_buf; /* pointer to dma buffer currently being used */
470 unsigned int dma_transfer_size; /* size of transfer currently used, in bytes */
471 unsigned long iobase2; /* secondary io address used for analog out on 'ao' boards */
472 short ao_update_bits; /* remembers the last write to the 'update' dac */
475 #define devpriv ((das1800_private *)dev->private)
477 // analog out range for boards with basic analog out
478 static const comedi_lrange range_ao_1 = {
485 // analog out range for 'ao' boards
487 static const comedi_lrange range_ao_2 = {
496 static comedi_driver driver_das1800={
497 driver_name: "das1800",
499 attach: das1800_attach,
500 detach: das1800_detach,
501 num_names: sizeof(das1800_boards) / sizeof(das1800_board),
502 board_name: &das1800_boards[0].name,
503 offset: sizeof(das1800_board),
507 * A convenient macro that defines init_module() and cleanup_module(),
510 COMEDI_INITCLEANUP(driver_das1800);
512 static int das1800_init_dma( comedi_device *dev, unsigned int dma0, unsigned int dma1 )
516 // need an irq to do dma
517 if( dev->irq && dma0 )
519 //encode dma0 and dma1 into 2 digit hexadecimal for switch
520 switch((dma0 & 0x7) | (dma1 << 4))
522 case 0x5: // dma0 == 5
523 devpriv->dma_bits |= DMA_CH5;
525 case 0x6: // dma0 == 6
526 devpriv->dma_bits |= DMA_CH6;
528 case 0x7: // dma0 == 7
529 devpriv->dma_bits |= DMA_CH7;
531 case 0x65: // dma0 == 5, dma1 == 6
532 devpriv->dma_bits |= DMA_CH5_CH6;
534 case 0x76: // dma0 == 6, dma1 == 7
535 devpriv->dma_bits |= DMA_CH6_CH7;
537 case 0x57: // dma0 == 7, dma1 == 5
538 devpriv->dma_bits |= DMA_CH7_CH5;
541 printk(" only supports dma channels 5 through 7\n"
542 " Dual dma only allows the following combinations:\n"
543 " dma 5,6 / 6,7 / or 7,5\n");
547 if( request_dma( dma0, driver_das1800.driver_name ) )
549 printk( " failed to allocate dma channel %i\n", dma0 );
552 devpriv->dma0 = dma0;
553 devpriv->dma_current = dma0;
556 if( request_dma( dma1, driver_das1800.driver_name ) )
558 printk( " failed to allocate dma channel %i\n", dma1 );
561 devpriv->dma1 = dma1;
563 devpriv->ai_buf0 = kmalloc(DMA_BUF_SIZE, GFP_KERNEL | GFP_DMA);
564 if(devpriv->ai_buf0 == NULL)
566 devpriv->dma_current_buf = devpriv->ai_buf0;
569 devpriv->ai_buf1 = kmalloc(DMA_BUF_SIZE, GFP_KERNEL | GFP_DMA);
570 if(devpriv->ai_buf1 == NULL)
573 flags = claim_dma_lock();
574 disable_dma(devpriv->dma0);
575 set_dma_mode(devpriv->dma0, DMA_MODE_READ);
578 disable_dma(devpriv->dma1);
579 set_dma_mode(devpriv->dma1, DMA_MODE_READ);
581 release_dma_lock(flags);
586 static int das1800_attach(comedi_device *dev, comedi_devconfig *it)
589 unsigned long iobase = it->options[0];
590 unsigned int irq = it->options[1];
591 unsigned int dma0 = it->options[2];
592 unsigned int dma1 = it->options[3];
593 unsigned long iobase2;
597 /* allocate and initialize dev->private */
598 if(alloc_private(dev, sizeof(das1800_private)) < 0)
601 printk("comedi%d: %s: io 0x%lx", dev->minor, driver_das1800.driver_name, iobase);
604 printk(", irq %u", irq);
607 printk(", dma %u", dma0);
608 if(dma1) printk(" and %u", dma1);
615 printk(" io base address required\n");
619 /* check if io addresses are available */
620 if(!request_region(iobase, DAS1800_SIZE, driver_das1800.driver_name))
622 printk(" I/O port conflict: failed to allocate ports 0x%lx to 0x%lx\n",
623 iobase, iobase + DAS1800_SIZE - 1);
626 dev->iobase = iobase;
628 board = das1800_probe(dev);
631 printk(" unable to determine board type\n");
635 dev->board_ptr = das1800_boards + board;
636 dev->board_name = thisboard->name;
638 // if it is an 'ao' board with fancy analog out then we need extra io ports
639 if(thisboard->ao_ability == 2)
641 iobase2 = iobase + IOBASE2;
642 if(!request_region(iobase2, DAS1800_SIZE, driver_das1800.driver_name))
644 printk(" I/O port conflict: failed to allocate ports 0x%lx to 0x%lx\n",
645 iobase2, iobase2 + DAS1800_SIZE - 1);
648 devpriv->iobase2 = iobase2;
654 if(comedi_request_irq( irq, das1800_interrupt, 0, driver_das1800.driver_name, dev ))
656 printk(" unable to allocate irq %u\n", irq);
662 // set bits that tell card which irq to use
668 devpriv->irq_dma_bits |= 0x8;
671 devpriv->irq_dma_bits |= 0x10;
674 devpriv->irq_dma_bits |= 0x18;
677 devpriv->irq_dma_bits |= 0x28;
680 devpriv->irq_dma_bits |= 0x30;
683 devpriv->irq_dma_bits |= 0x38;
686 printk(" irq out of range\n");
691 retval = das1800_init_dma( dev, dma0, dma1 );
692 if( retval < 0 ) return retval;
694 if( devpriv->ai_buf0 == NULL )
696 devpriv->ai_buf0 = kmalloc( FIFO_SIZE * sizeof( uint16_t ), GFP_KERNEL );
697 if(devpriv->ai_buf0 == NULL)
701 if(alloc_subdevices(dev, 4) < 0)
704 /* analog input subdevice */
705 s = dev->subdevices + 0;
706 dev->read_subdev = s;
707 s->type = COMEDI_SUBD_AI;
708 s->subdev_flags = SDF_READABLE | SDF_DIFF | SDF_GROUND | SDF_CMD_READ;
709 if(thisboard->common)
710 s->subdev_flags |= SDF_COMMON;
711 s->n_chan = thisboard->qram_len;
712 s->len_chanlist = thisboard->qram_len;
713 s->maxdata = (1 << thisboard->resolution) - 1;
714 s->range_table = thisboard->range_ai;
715 s->do_cmd = das1800_ai_do_cmd;
716 s->do_cmdtest = das1800_ai_do_cmdtest;
717 s->insn_read = das1800_ai_rinsn;
718 s->poll = das1800_ai_poll;
719 s->cancel = das1800_cancel;
722 s = dev->subdevices + 1;
723 if(thisboard->ao_ability == 1)
725 s->type = COMEDI_SUBD_AO;
726 s->subdev_flags = SDF_WRITABLE;
727 s->n_chan = thisboard->ao_n_chan;
728 s->maxdata = (1 << thisboard->resolution) - 1;
729 s->range_table = &range_ao_1;
730 s->insn_write = das1800_ao_winsn;
734 s->type = COMEDI_SUBD_UNUSED;
738 s = dev->subdevices + 2;
739 s->type = COMEDI_SUBD_DI;
740 s->subdev_flags = SDF_READABLE;
743 s->range_table = &range_digital;
744 s->insn_bits = das1800_di_rbits;
747 s = dev->subdevices + 3;
748 s->type = COMEDI_SUBD_DO;
749 s->subdev_flags = SDF_WRITABLE | SDF_READABLE;
750 s->n_chan = thisboard->do_n_chan;
752 s->range_table = &range_digital;
753 s->insn_bits = das1800_do_wbits;
755 das1800_cancel(dev, dev->read_subdev);
757 // initialize digital out channels
758 outb(devpriv->do_bits, dev->iobase + DAS1800_DIGITAL);
760 // initialize analog out channels
761 if(thisboard->ao_ability == 1)
763 // select 'update' dac channel for baseAddress + 0x0
764 outb(DAC(thisboard->ao_n_chan - 1), dev->iobase + DAS1800_SELECT);
765 outw(devpriv->ao_update_bits, dev->iobase + DAS1800_DAC);
771 static int das1800_detach(comedi_device *dev)
773 /* only free stuff if it has been allocated by _attach */
775 release_region(dev->iobase, DAS1800_SIZE);
777 comedi_free_irq(dev->irq, dev);
781 release_region(devpriv->iobase2, DAS1800_SIZE);
783 free_dma(devpriv->dma0);
785 free_dma(devpriv->dma1);
787 kfree(devpriv->ai_buf0);
789 kfree(devpriv->ai_buf1);
792 printk("comedi%d: %s: remove\n", dev->minor, driver_das1800.driver_name);
797 /* probes and checks das-1800 series board type
799 static int das1800_probe(comedi_device *dev)
804 id = (inb(dev->iobase + DAS1800_DIGITAL) >> 4) & 0xf; /* get id bits */
805 board = ((das1800_board *)dev->board_ptr) - das1800_boards;
810 if(board == das1801st_da || board == das1802st_da ||
811 board == das1701st_da || board == das1702st_da)
813 printk(" Board model: %s\n", das1800_boards[board].name);
816 printk(" Board model (probed, not recommended): das-1800st-da series\n");
820 if(board == das1802hr_da || board == das1702hr_da)
822 printk(" Board model: %s\n", das1800_boards[board].name);
825 printk(" Board model (probed, not recommended): das-1802hr-da\n");
829 if(board == das1801ao || board == das1802ao ||
830 board == das1701ao || board == das1702ao)
832 printk(" Board model: %s\n", das1800_boards[board].name);
835 printk(" Board model (probed, not recommended): das-1800ao series\n");
839 if(board == das1802hr || board == das1702hr)
841 printk(" Board model: %s\n", das1800_boards[board].name);
844 printk(" Board model (probed, not recommended): das-1802hr\n");
848 if(board == das1801st || board == das1802st ||
849 board == das1701st || board == das1702st)
851 printk(" Board model: %s\n", das1800_boards[board].name);
854 printk(" Board model (probed, not recommended): das-1800st series\n");
858 if(board == das1801hc || board == das1802hc)
860 printk(" Board model: %s\n", das1800_boards[board].name);
863 printk(" Board model (probed, not recommended): das-1800hc series\n");
867 printk(" Board model: probe returned 0x%x (unknown, please report)\n", id);
874 static int das1800_ai_poll(comedi_device *dev,comedi_subdevice *s)
878 // prevent race with interrupt handler
879 comedi_spin_lock_irqsave(&dev->spinlock, flags);
880 das1800_ai_handler(dev);
881 comedi_spin_unlock_irqrestore(&dev->spinlock, flags);
883 return s->async->buf_write_count - s->async->buf_read_count;
886 static irqreturn_t das1800_interrupt(int irq, void *d PT_REGS_ARG)
888 comedi_device *dev = d;
891 if(dev->attached == 0)
893 comedi_error(dev, "premature interrupt");
897 /* Prevent race with das1800_ai_poll() on multi processor systems.
898 * Also protects indirect addressing in das1800_ai_handler */
899 spin_lock(&dev->spinlock);
900 status = inb(dev->iobase + DAS1800_STATUS);
902 /* if interrupt was not caused by das-1800 */
905 spin_unlock(&dev->spinlock);
908 /* clear the interrupt status bit INT*/
909 outb(CLEAR_INTR_MASK & ~INT, dev->iobase + DAS1800_STATUS);
911 das1800_ai_handler(dev);
913 spin_unlock(&dev->spinlock);
917 // the guts of the interrupt handler, that is shared with das1800_ai_poll
918 static void das1800_ai_handler(comedi_device *dev)
920 comedi_subdevice *s = dev->subdevices + 0; /* analog input subdevice */
921 comedi_async *async = s->async;
922 comedi_cmd *cmd = &async->cmd;
923 unsigned int status = inb(dev->iobase + DAS1800_STATUS);
926 // select adc for base address + 0
927 outb(ADC, dev->iobase + DAS1800_SELECT);
929 if(devpriv->irq_dma_bits & DMA_ENABLED)
931 // look for data from dma transfer even if dma terminal count hasn't happened yet
932 das1800_handle_dma(dev, s, status);
933 }else if(status & FHF)
934 { // if fifo half full
935 das1800_handle_fifo_half_full(dev, s);
936 }else if(status & FNE)
937 { // if fifo not empty
938 das1800_handle_fifo_not_empty(dev, s);
941 async->events |= COMEDI_CB_BLOCK;
942 /* if the card's fifo has overflowed */
945 // clear OVF interrupt bit
946 outb(CLEAR_INTR_MASK & ~OVF, dev->iobase + DAS1800_STATUS);
947 comedi_error(dev, "DAS1800 FIFO overflow");
948 das1800_cancel(dev, s);
949 async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA;
950 comedi_event(dev, s, async->events);
954 // stop taking data if appropriate
955 /* stop_src TRIG_EXT */
958 // clear CT0TC interrupt bit
959 outb(CLEAR_INTR_MASK & ~CT0TC, dev->iobase + DAS1800_STATUS);
960 // make sure we get all remaining data from board before quitting
961 if(devpriv->irq_dma_bits & DMA_ENABLED)
962 das1800_flush_dma(dev, s);
964 das1800_handle_fifo_not_empty(dev, s);
965 das1800_cancel(dev, s); /* disable hardware conversions */
966 async->events |= COMEDI_CB_EOA;
967 }else if(cmd->stop_src == TRIG_COUNT && devpriv->count == 0)
968 { // stop_src TRIG_COUNT
969 das1800_cancel(dev, s); /* disable hardware conversions */
970 async->events |= COMEDI_CB_EOA;
973 comedi_event(dev, s, async->events);
978 static void das1800_handle_dma(comedi_device *dev, comedi_subdevice *s, unsigned int status)
981 const int dual_dma = devpriv->irq_dma_bits & DMA_DUAL;
983 flags = claim_dma_lock();
984 das1800_flush_dma_channel(dev, s, devpriv->dma_current, devpriv->dma_current_buf);
985 // re-enable dma channel
986 set_dma_addr(devpriv->dma_current, virt_to_bus(devpriv->dma_current_buf));
987 set_dma_count(devpriv->dma_current, devpriv->dma_transfer_size);
988 enable_dma(devpriv->dma_current);
989 release_dma_lock(flags);
993 // clear DMATC interrupt bit
994 outb(CLEAR_INTR_MASK & ~DMATC, dev->iobase + DAS1800_STATUS);
995 // switch dma channels for next time, if appropriate
998 // read data from the other channel next time
999 if(devpriv->dma_current == devpriv->dma0)
1001 devpriv->dma_current = devpriv->dma1;
1002 devpriv->dma_current_buf = devpriv->ai_buf1;
1006 devpriv->dma_current = devpriv->dma0;
1007 devpriv->dma_current_buf = devpriv->ai_buf0;
1015 static inline uint16_t munge_bipolar_sample( const comedi_device *dev, uint16_t sample )
1017 sample += 1 << ( thisboard->resolution - 1 );
1021 static void munge_data( comedi_device *dev, uint16_t *array, unsigned int num_elements )
1026 /* see if card is using a unipolar or bipolar range so we can munge data correctly */
1027 unipolar = inb( dev->iobase + DAS1800_CONTROL_C ) & UB;
1029 /* convert to unsigned type if we are in a bipolar mode */
1032 for( i = 0; i < num_elements; i++ )
1034 array[i] = munge_bipolar_sample( dev, array[i] );
1039 /* Utility function used by das1800_flush_dma() and das1800_handle_dma().
1040 * Assumes dma lock is held */
1041 static void das1800_flush_dma_channel(comedi_device *dev, comedi_subdevice *s, unsigned int channel, uint16_t *buffer)
1043 unsigned int num_bytes, num_samples;
1044 comedi_cmd *cmd = &s->async->cmd;
1046 disable_dma(channel);
1048 /* clear flip-flop to make sure 2-byte registers
1049 * get set correctly */
1050 clear_dma_ff(channel);
1052 // figure out how many points to read
1053 num_bytes = devpriv->dma_transfer_size - get_dma_residue( channel );
1054 num_samples = num_bytes / sizeof( sampl_t );
1056 /* if we only need some of the points */
1057 if( cmd->stop_src == TRIG_COUNT && devpriv->count < num_samples )
1058 num_samples = devpriv->count;
1060 munge_data( dev, buffer, num_samples );
1061 cfc_write_array_to_buffer( s, buffer, num_bytes );
1062 if(s->async->cmd.stop_src == TRIG_COUNT)
1063 devpriv->count -= num_samples;
1068 /* flushes remaining data from board when external trigger has stopped aquisition
1069 * and we are using dma transfers */
1070 static void das1800_flush_dma(comedi_device *dev, comedi_subdevice *s)
1072 unsigned long flags;
1073 const int dual_dma = devpriv->irq_dma_bits & DMA_DUAL;
1075 flags = claim_dma_lock();
1076 das1800_flush_dma_channel(dev, s, devpriv->dma_current, devpriv->dma_current_buf);
1080 // switch to other channel and flush it
1081 if(devpriv->dma_current == devpriv->dma0)
1083 devpriv->dma_current = devpriv->dma1;
1084 devpriv->dma_current_buf = devpriv->ai_buf1;
1088 devpriv->dma_current = devpriv->dma0;
1089 devpriv->dma_current_buf = devpriv->ai_buf0;
1091 das1800_flush_dma_channel(dev, s, devpriv->dma_current, devpriv->dma_current_buf);
1094 release_dma_lock(flags);
1096 // get any remaining samples in fifo
1097 das1800_handle_fifo_not_empty(dev, s);
1102 static void das1800_handle_fifo_half_full(comedi_device *dev, comedi_subdevice *s)
1104 int numPoints = 0; /* number of points to read */
1105 comedi_cmd *cmd = &s->async->cmd;
1107 numPoints = FIFO_SIZE / 2;
1108 /* if we only need some of the points */
1109 if(cmd->stop_src == TRIG_COUNT && devpriv->count < numPoints)
1110 numPoints = devpriv->count;
1111 insw(dev->iobase + DAS1800_FIFO, devpriv->ai_buf0, numPoints);
1112 munge_data( dev, devpriv->ai_buf0, numPoints );
1113 cfc_write_array_to_buffer( s, devpriv->ai_buf0, numPoints * sizeof( devpriv->ai_buf0[0] ) );
1114 if( cmd->stop_src == TRIG_COUNT )
1115 devpriv->count -= numPoints;
1119 static void das1800_handle_fifo_not_empty(comedi_device *dev, comedi_subdevice *s)
1123 comedi_cmd *cmd = &s->async->cmd;
1125 unipolar = inb(dev->iobase + DAS1800_CONTROL_C) & UB;
1127 while( inb( dev->iobase + DAS1800_STATUS ) & FNE )
1129 if(cmd->stop_src == TRIG_COUNT && devpriv->count == 0)
1131 dpnt = inw( dev->iobase + DAS1800_FIFO );
1132 /* convert to unsigned type if we are in a bipolar mode */
1134 dpnt = munge_bipolar_sample( dev, dpnt );
1135 cfc_write_to_buffer( s, dpnt );
1136 if(cmd->stop_src == TRIG_COUNT) devpriv->count--;
1142 static int das1800_cancel(comedi_device *dev, comedi_subdevice *s)
1144 outb(0x0, dev->iobase + DAS1800_STATUS); /* disable conversions */
1145 outb(0x0, dev->iobase + DAS1800_CONTROL_B); /* disable interrupts and dma */
1146 outb(0x0, dev->iobase + DAS1800_CONTROL_A); /* disable and clear fifo and stop triggering */
1147 if(devpriv->dma0) disable_dma(devpriv->dma0);
1148 if(devpriv->dma1) disable_dma(devpriv->dma1);
1152 /* test analog input cmd */
1153 static int das1800_ai_do_cmdtest(comedi_device *dev,comedi_subdevice *s,comedi_cmd *cmd)
1157 unsigned int tmp_arg;
1161 /* step 1: make sure trigger sources are trivially valid */
1163 tmp = cmd->start_src;
1164 cmd->start_src &= TRIG_NOW | TRIG_EXT;
1165 if(!cmd->start_src || tmp != cmd->start_src) err++;
1167 tmp = cmd->scan_begin_src;
1168 cmd->scan_begin_src &= TRIG_FOLLOW | TRIG_TIMER | TRIG_EXT;
1169 if(!cmd->scan_begin_src || tmp != cmd->scan_begin_src) err++;
1171 tmp = cmd->convert_src;
1172 cmd->convert_src &= TRIG_TIMER | TRIG_EXT;
1173 if(!cmd->convert_src || tmp != cmd->convert_src) err++;
1175 tmp = cmd->scan_end_src;
1176 cmd->scan_end_src &= TRIG_COUNT;
1177 if(!cmd->scan_end_src || tmp != cmd->scan_end_src) err++;
1180 cmd->stop_src &= TRIG_COUNT | TRIG_EXT | TRIG_NONE;
1181 if(!cmd->stop_src || tmp != cmd->stop_src) err++;
1185 /* step 2: make sure trigger sources are unique and mutually compatible */
1188 if(cmd->start_src != TRIG_NOW &&
1189 cmd->start_src != TRIG_EXT) err++;
1190 if(cmd->scan_begin_src != TRIG_FOLLOW &&
1191 cmd->scan_begin_src != TRIG_TIMER &&
1192 cmd->scan_begin_src != TRIG_EXT) err++;
1193 if(cmd->convert_src != TRIG_TIMER &&
1194 cmd->convert_src != TRIG_EXT) err++;
1195 if(cmd->stop_src != TRIG_COUNT &&
1196 cmd->stop_src != TRIG_NONE &&
1197 cmd->stop_src != TRIG_EXT) err++;
1198 //compatibility check
1199 if(cmd->scan_begin_src != TRIG_FOLLOW &&
1200 cmd->convert_src != TRIG_TIMER) err++;
1204 /* step 3: make sure arguments are trivially compatible */
1206 if(cmd->start_arg != 0)
1211 if(cmd->convert_src == TRIG_TIMER)
1213 if(cmd->convert_arg < thisboard->ai_speed)
1215 cmd->convert_arg = thisboard->ai_speed;
1219 if(!cmd->chanlist_len)
1221 cmd->chanlist_len = 1;
1224 if(cmd->scan_end_arg != cmd->chanlist_len)
1226 cmd->scan_end_arg = cmd->chanlist_len;
1230 switch(cmd->stop_src)
1240 if(cmd->stop_arg != 0)
1252 /* step 4: fix up any arguments */
1254 if(cmd->convert_src == TRIG_TIMER)
1256 // if we are not in burst mode
1257 if(cmd->scan_begin_src == TRIG_FOLLOW)
1259 tmp_arg = cmd->convert_arg;
1260 /* calculate counter values that give desired timing */
1261 i8253_cascade_ns_to_timer_2div(TIMER_BASE, &(devpriv->divisor1), &(devpriv->divisor2), &(cmd->convert_arg), cmd->flags & TRIG_ROUND_MASK);
1262 if(tmp_arg != cmd->convert_arg) err++;
1264 // if we are in burst mode
1267 // check that convert_arg is compatible
1268 tmp_arg = cmd->convert_arg;
1269 cmd->convert_arg = burst_convert_arg(cmd->convert_arg, cmd->flags & TRIG_ROUND_MASK);
1270 if(tmp_arg != cmd->convert_arg) err++;
1272 if(cmd->scan_begin_src == TRIG_TIMER)
1274 // if scans are timed faster than conversion rate allows
1275 if(cmd->convert_arg * cmd->chanlist_len > cmd->scan_begin_arg)
1277 cmd->scan_begin_arg = cmd->convert_arg * cmd->chanlist_len;
1280 tmp_arg = cmd->scan_begin_arg;
1281 /* calculate counter values that give desired timing */
1282 i8253_cascade_ns_to_timer_2div(TIMER_BASE, &(devpriv->divisor1), &(devpriv->divisor2), &(cmd->scan_begin_arg), cmd->flags & TRIG_ROUND_MASK);
1283 if(tmp_arg != cmd->scan_begin_arg) err++;
1290 // make sure user is not trying to mix unipolar and bipolar ranges
1293 unipolar = CR_RANGE(cmd->chanlist[0]) & UNIPOLAR;
1294 for(i = 1; i < cmd->chanlist_len; i++)
1296 if(unipolar != (CR_RANGE(cmd->chanlist[i]) & UNIPOLAR))
1298 comedi_error(dev, "unipolar and bipolar ranges cannot be mixed in the chanlist");
1310 /* analog input cmd interface */
1312 // first, some utility functions used in the main ai_do_cmd()
1314 // returns appropriate bits for control register a, depending on command
1315 static int control_a_bits(comedi_cmd cmd)
1319 control_a = FFEN; //enable fifo
1320 if(cmd.stop_src == TRIG_EXT)
1324 switch(cmd.start_src)
1327 control_a |= TGEN | CGSL;
1339 // returns appropriate bits for control register c, depending on command
1340 static int control_c_bits(comedi_cmd cmd)
1345 /* set clock source to internal or external, select analog reference,
1346 * select unipolar / bipolar
1348 aref = CR_AREF(cmd.chanlist[0]);
1349 control_c = UQEN; //enable upper qram addresses
1350 if(aref != AREF_DIFF)
1352 if(aref == AREF_COMMON)
1354 /* if a unipolar range was selected */
1355 if(CR_RANGE(cmd.chanlist[0]) & UNIPOLAR)
1357 switch(cmd.scan_begin_src)
1359 case TRIG_FOLLOW: // not in burst mode
1360 switch(cmd.convert_src)
1363 /* trig on cascaded counters */
1367 /* trig on falling edge of external trigger */
1375 // burst mode with internal pacer clock
1376 control_c |= BMDE | IPCLK;
1379 // burst mode with external trigger
1380 control_c |= BMDE | XPCLK;
1390 static int setup_counters(comedi_device *dev, comedi_cmd cmd)
1392 // setup cascaded counters for conversion/scan frequency
1393 switch(cmd.scan_begin_src)
1395 case TRIG_FOLLOW: // not in burst mode
1396 if(cmd.convert_src == TRIG_TIMER)
1398 /* set conversion frequency */
1399 i8253_cascade_ns_to_timer_2div(TIMER_BASE, &(devpriv->divisor1), &(devpriv->divisor2),
1400 &(cmd.convert_arg), cmd.flags & TRIG_ROUND_MASK);
1401 if(das1800_set_frequency(dev) < 0)
1407 case TRIG_TIMER: // in burst mode
1408 /* set scan frequency */
1409 i8253_cascade_ns_to_timer_2div(TIMER_BASE, &(devpriv->divisor1), &(devpriv->divisor2),
1410 &(cmd.scan_begin_arg), cmd.flags & TRIG_ROUND_MASK);
1411 if(das1800_set_frequency(dev) < 0)
1420 // setup counter 0 for 'about triggering'
1421 if(cmd.stop_src == TRIG_EXT)
1423 // load counter 0 in mode 0
1424 i8254_load(dev->iobase + DAS1800_COUNTER, 0, 1, 0);
1431 static void setup_dma(comedi_device *dev, comedi_cmd cmd)
1433 unsigned long lock_flags;
1434 const int dual_dma = devpriv->irq_dma_bits & DMA_DUAL;
1436 if((devpriv->irq_dma_bits & DMA_ENABLED) == 0)
1439 /* determine a reasonable dma transfer size */
1440 devpriv->dma_transfer_size = suggest_transfer_size(&cmd);
1441 lock_flags = claim_dma_lock();
1442 disable_dma(devpriv->dma0);
1443 /* clear flip-flop to make sure 2-byte registers for
1444 * count and address get set correctly */
1445 clear_dma_ff(devpriv->dma0);
1446 set_dma_addr(devpriv->dma0, virt_to_bus(devpriv->ai_buf0));
1447 // set appropriate size of transfer
1448 set_dma_count(devpriv->dma0, devpriv->dma_transfer_size);
1449 devpriv->dma_current = devpriv->dma0;
1450 devpriv->dma_current_buf = devpriv->ai_buf0;
1451 enable_dma(devpriv->dma0);
1452 // set up dual dma if appropriate
1455 disable_dma(devpriv->dma1);
1456 /* clear flip-flop to make sure 2-byte registers for
1457 * count and address get set correctly */
1458 clear_dma_ff(devpriv->dma1);
1459 set_dma_addr(devpriv->dma1, virt_to_bus(devpriv->ai_buf1));
1460 // set appropriate size of transfer
1461 set_dma_count(devpriv->dma1, devpriv->dma_transfer_size);
1462 enable_dma(devpriv->dma1);
1464 release_dma_lock(lock_flags);
1469 // programs channel/gain list into card
1470 static void program_chanlist(comedi_device *dev, comedi_cmd cmd)
1472 int i, n, chan_range;
1473 unsigned long irq_flags;
1474 const int range_mask = 0x3; //masks unipolar/bipolar bit off range
1475 const int range_bitshift = 8;
1477 n = cmd.chanlist_len;
1478 // spinlock protects indirect addressing
1479 comedi_spin_lock_irqsave(&dev->spinlock, irq_flags);
1480 outb(QRAM, dev->iobase + DAS1800_SELECT); /* select QRAM for baseAddress + 0x0 */
1481 outb(n - 1, dev->iobase + DAS1800_QRAM_ADDRESS); /*set QRAM address start */
1482 /* make channel / gain list */
1483 for(i = 0; i < n; i++)
1485 chan_range = CR_CHAN(cmd.chanlist[i]) | ((CR_RANGE(cmd.chanlist[i]) & range_mask) << range_bitshift);
1486 outw(chan_range, dev->iobase + DAS1800_QRAM);
1488 outb(n - 1, dev->iobase + DAS1800_QRAM_ADDRESS); /*finish write to QRAM */
1489 comedi_spin_unlock_irqrestore(&dev->spinlock, irq_flags);
1494 // analog input do_cmd
1495 static int das1800_ai_do_cmd(comedi_device *dev, comedi_subdevice *s)
1498 int control_a, control_c;
1499 comedi_async *async = s->async;
1500 comedi_cmd cmd = async->cmd;
1504 comedi_error(dev, "no irq assigned for das-1800, cannot do hardware conversions");
1508 /* disable dma on TRIG_WAKE_EOS, or TRIG_RT
1509 * (because dma in handler is unsafe at hard real-time priority) */
1510 if(cmd.flags & (TRIG_WAKE_EOS | TRIG_RT))
1512 devpriv->irq_dma_bits &= ~DMA_ENABLED;
1515 devpriv->irq_dma_bits |= devpriv->dma_bits;
1517 // interrupt on end of conversion for TRIG_WAKE_EOS
1518 if(cmd.flags & TRIG_WAKE_EOS)
1520 // interrupt fifo not empty
1521 devpriv->irq_dma_bits &= ~FIMD;
1524 // interrupt fifo half full
1525 devpriv->irq_dma_bits |= FIMD;
1527 // determine how many conversions we need
1528 if(cmd.stop_src == TRIG_COUNT)
1530 devpriv->count = cmd.stop_arg * cmd.chanlist_len;
1533 das1800_cancel(dev, s);
1535 // determine proper bits for control registers
1536 control_a = control_a_bits(cmd);
1537 control_c = control_c_bits(cmd);
1539 /* setup card and start */
1540 program_chanlist(dev, cmd);
1541 ret = setup_counters(dev, cmd);
1544 comedi_error(dev, "Error setting up counters");
1547 setup_dma(dev, cmd);
1548 outb(control_c, dev->iobase + DAS1800_CONTROL_C);
1549 // set conversion rate and length for burst mode
1550 if(control_c & BMDE)
1552 // program conversion period with number of microseconds minus 1
1553 outb(cmd.convert_arg / 1000 - 1, dev->iobase + DAS1800_BURST_RATE);
1554 outb(cmd.chanlist_len - 1, dev->iobase + DAS1800_BURST_LENGTH);
1556 outb(devpriv->irq_dma_bits, dev->iobase + DAS1800_CONTROL_B); // enable irq/dma
1557 outb(control_a, dev->iobase + DAS1800_CONTROL_A); /* enable fifo and triggering */
1558 outb(CVEN, dev->iobase + DAS1800_STATUS); /* enable conversions */
1563 /* read analog input */
1564 static int das1800_ai_rinsn(comedi_device *dev, comedi_subdevice *s, comedi_insn *insn, lsampl_t *data)
1567 int chan, range, aref, chan_range;
1571 unsigned long irq_flags;
1573 /* set up analog reference and unipolar / bipolar mode */
1574 aref = CR_AREF(insn->chanspec);
1576 if(aref != AREF_DIFF)
1578 if(aref == AREF_COMMON)
1580 /* if a unipolar range was selected */
1581 if(CR_RANGE(insn->chanspec) & UNIPOLAR)
1584 outb(conv_flags, dev->iobase + DAS1800_CONTROL_C); /* software conversion enabled */
1585 outb(CVEN, dev->iobase + DAS1800_STATUS); /* enable conversions */
1586 outb(0x0, dev->iobase + DAS1800_CONTROL_A); /* reset fifo */
1587 outb(FFEN, dev->iobase + DAS1800_CONTROL_A);
1590 chan = CR_CHAN(insn->chanspec);
1591 /* mask of unipolar/bipolar bit from range */
1592 range = CR_RANGE(insn->chanspec) & 0x3;
1593 chan_range = chan | (range << 8);
1594 comedi_spin_lock_irqsave(&dev->spinlock, irq_flags);
1595 outb(QRAM, dev->iobase + DAS1800_SELECT); /* select QRAM for baseAddress + 0x0 */
1596 outb(0x0, dev->iobase + DAS1800_QRAM_ADDRESS); /* set QRAM address start */
1597 outw(chan_range, dev->iobase + DAS1800_QRAM);
1598 outb(0x0, dev->iobase + DAS1800_QRAM_ADDRESS); /*finish write to QRAM */
1599 outb(ADC, dev->iobase + DAS1800_SELECT); /* select ADC for baseAddress + 0x0 */
1601 for(n = 0; n < insn->n; n++)
1603 /* trigger conversion */
1604 outb(0, dev->iobase + DAS1800_FIFO);
1605 for(i = 0; i < timeout; i++)
1607 if(inb(dev->iobase + DAS1800_STATUS) & FNE)
1612 comedi_error(dev, "timeout");
1615 dpnt = inw(dev->iobase + DAS1800_FIFO);
1616 /* shift data to offset binary for bipolar ranges */
1617 if((conv_flags & UB) == 0)
1618 dpnt += 1 << (thisboard->resolution - 1);
1621 comedi_spin_unlock_irqrestore(&dev->spinlock, irq_flags);
1626 /* writes to an analog output channel */
1627 static int das1800_ao_winsn(comedi_device *dev, comedi_subdevice *s, comedi_insn *insn, lsampl_t *data)
1629 int chan = CR_CHAN(insn->chanspec);
1630 // int range = CR_RANGE(insn->chanspec);
1631 int update_chan = thisboard->ao_n_chan - 1;
1633 unsigned long irq_flags;
1635 // card expects two's complement data
1636 output = data[0] - (1 << (thisboard->resolution - 1));
1637 // if the write is to the 'update' channel, we need to remember its value
1638 if(chan == update_chan)
1639 devpriv->ao_update_bits = output;
1641 comedi_spin_lock_irqsave(&dev->spinlock, irq_flags);
1642 outb(DAC(chan), dev->iobase + DAS1800_SELECT); /* select dac channel for baseAddress + 0x0 */
1643 outw(output, dev->iobase + DAS1800_DAC);
1644 // now we need to write to 'update' channel to update all dac channels
1645 if(chan != update_chan)
1647 outb(DAC(update_chan), dev->iobase + DAS1800_SELECT); /* select 'update' channel for baseAddress + 0x0 */
1648 outw(devpriv->ao_update_bits, dev->iobase + DAS1800_DAC);
1650 comedi_spin_unlock_irqrestore(&dev->spinlock, irq_flags);
1655 /* reads from digital input channels */
1656 static int das1800_di_rbits(comedi_device *dev, comedi_subdevice *s, comedi_insn *insn, lsampl_t *data)
1659 data[1] = inb(dev->iobase + DAS1800_DIGITAL) & 0xf;
1665 /* writes to digital output channels */
1666 static int das1800_do_wbits(comedi_device *dev, comedi_subdevice *s, comedi_insn *insn, lsampl_t *data)
1670 // only set bits that have been masked
1671 data[0] &= (1 << s->n_chan) - 1;
1672 wbits = devpriv->do_bits;
1674 wbits |= data[0] & data[1];
1675 devpriv->do_bits = wbits;
1677 outb(devpriv->do_bits, dev->iobase + DAS1800_DIGITAL);
1679 data[1] = devpriv->do_bits;
1684 /* loads counters with divisor1, divisor2 from private structure */
1685 static int das1800_set_frequency(comedi_device *dev)
1689 // counter 1, mode 2
1690 if(i8254_load(dev->iobase + DAS1800_COUNTER, 1, devpriv->divisor1, 2)) err++;
1691 // counter 2, mode 2
1692 if(i8254_load(dev->iobase + DAS1800_COUNTER, 2, devpriv->divisor2, 2)) err++;
1699 /* converts requested conversion timing to timing compatible with
1700 * hardware, used only when card is in 'burst mode'
1702 static unsigned int burst_convert_arg(unsigned int convert_arg, int round_mode)
1704 unsigned int micro_sec;
1706 // in burst mode, the maximum conversion time is 64 microseconds
1707 if(convert_arg > 64000)
1708 convert_arg = 64000;
1710 // the conversion time must be an integral number of microseconds
1713 case TRIG_ROUND_NEAREST:
1715 micro_sec = (convert_arg + 500) / 1000;
1717 case TRIG_ROUND_DOWN:
1718 micro_sec = convert_arg / 1000;
1721 micro_sec = (convert_arg - 1) / 1000 + 1;
1725 // return number of nanoseconds
1726 return micro_sec * 1000;
1729 // utility function that suggests a dma transfer size based on the conversion period 'ns'
1730 static unsigned int suggest_transfer_size(comedi_cmd *cmd)
1732 unsigned int size = DMA_BUF_SIZE;
1733 static const int sample_size = 2; // size in bytes of one sample from board
1734 unsigned int fill_time = 300000000; // target time in nanoseconds for filling dma buffer
1735 unsigned int max_size; // maximum size we will allow for a transfer
1737 // make dma buffer fill in 0.3 seconds for timed modes
1738 switch(cmd->scan_begin_src)
1740 case TRIG_FOLLOW: // not in burst mode
1741 if(cmd->convert_src == TRIG_TIMER)
1742 size = (fill_time / cmd->convert_arg) * sample_size;
1745 size = (fill_time / (cmd->scan_begin_arg * cmd->chanlist_len)) * sample_size;
1748 size = DMA_BUF_SIZE;
1752 // set a minimum and maximum size allowed
1753 max_size = DMA_BUF_SIZE;
1754 // if we are taking limited number of conversions, limit transfer size to that
1755 if(cmd->stop_src == TRIG_COUNT &&
1756 cmd->stop_arg * cmd->chanlist_len * sample_size < max_size)
1757 max_size = cmd->stop_arg * cmd->chanlist_len * sample_size;
1761 if(size < sample_size)