fixing end of scan events in some drivers
authorFrank Mori Hess <fmhess@speakeasy.net>
Sun, 14 Jul 2002 22:33:37 +0000 (22:33 +0000)
committerFrank Mori Hess <fmhess@speakeasy.net>
Sun, 14 Jul 2002 22:33:37 +0000 (22:33 +0000)
19 files changed:
comedi/Config.in
comedi/comedi_fops.c
comedi/comedi_ksyms.c
comedi/drivers.c
comedi/drivers/Makefile.in
comedi/drivers/cb_pcidas.c
comedi/drivers/cb_pcidas64.c
comedi/drivers/comedi_fc.c [new file with mode: 0644]
comedi/drivers/comedi_fc.h [new file with mode: 0644]
comedi/drivers/comedi_rt_timer.c
comedi/drivers/comedi_test.c
comedi/drivers/das16.c
comedi/drivers/das16m1.c
comedi/drivers/das1800.c
comedi/drivers/das800.c
comedi/drivers/ni_at_a2150.c
comedi/drivers/ni_labpc.c
comedi/kcomedilib/kcomedilib_main.c
include/linux/comedidev.h

index 9804895568ab28b6c89c9a44934d40f7a84d904c..cf155b147475224de156547fb1b186710c4abab3 100644 (file)
@@ -127,3 +127,4 @@ if [ "$CONFIG_COMEDI_RT" = "y" ];then
        dep_tristate 'Real-time command emulator (timer)' CONFIG_COMEDI_RT_TIMER $CONFIG_COMEDI
 fi
 
+define_bool CONFIG_COMEDI_FC m
index 03e8645ad98efed37c8b6fbe690717bcec47c6b0..e7eabfb9556deeb6e3e0c7dcb6b66a38a8fdff87 100644 (file)
@@ -882,8 +882,6 @@ static int do_cmd_ioctl(comedi_device *dev,void *arg,void *file)
 
        init_async_buf( async );
 
-       async->cur_chan = 0;
-
        async->data = async->prealloc_buf;
        async->data_len=async->prealloc_bufsz;
 
@@ -1839,5 +1837,8 @@ static void init_async_buf( comedi_async *async )
 
        async->buf_write_ptr = 0;
        async->buf_read_ptr = 0;
+
+       async->cur_chan = 0;
+       async->scan_progress = 0;
 }
 
index 219d894627a9cf6e0a26ff95f52419a88980f903..3d7ed16f0e91c92acd694b2fa74b0fc0b23fd39d 100644 (file)
@@ -71,7 +71,8 @@ EXPORT_SYMBOL(comedi_buf_copy_from);
 EXPORT_SYMBOL(comedi_buf_write_free);
 EXPORT_SYMBOL(comedi_buf_write_alloc);
 EXPORT_SYMBOL(comedi_buf_read_free);
-
+EXPORT_SYMBOL(comedi_buf_memcpy_to);
+EXPORT_SYMBOL(comedi_buf_memcpy_from);
 #endif
 
 
index f6d9c3c118d2c6fb488d6abbece5661b2e57df0c..9e627f5840795147a07e3b30db5577c85035b2af 100644 (file)
@@ -605,6 +605,59 @@ void comedi_buf_read_free(comedi_async *async, unsigned int nbytes)
        }
 }
 
+void comedi_buf_memcpy_to( comedi_async *async, unsigned int offset, const void *data,
+       unsigned int num_bytes )
+{
+       unsigned int write_ptr = async->buf_write_ptr + offset;
+
+       if( write_ptr > async->data_len )
+               write_ptr %= async->data_len;
+
+       while( num_bytes )
+       {
+               unsigned int block_size;
+
+               if( write_ptr + num_bytes > async->data_len)
+                       block_size = async->data_len - write_ptr;
+               else
+                       block_size = num_bytes;
+
+               memcpy( async->data + write_ptr, data, block_size );
+
+               data += block_size;
+               num_bytes -= block_size;
+
+               write_ptr = 0;
+       }
+}
+
+void comedi_buf_memcpy_from(comedi_async *async, unsigned int offset,
+       void *dest, unsigned int nbytes)
+{
+       void *src;
+       unsigned int read_ptr = async->buf_read_ptr + offset;
+
+       if( read_ptr > async->data_len )
+               read_ptr %= async->data_len;
+
+       while( nbytes )
+       {
+               unsigned int block_size;
+
+               src = async->data + read_ptr;
+
+               if( nbytes >= async->data_len - read_ptr )
+                       block_size = async->data_len - read_ptr;
+               else
+                       block_size = nbytes;
+
+               memcpy(dest, src, block_size );
+               nbytes -= block_size;
+               dest += block_size;
+               read_ptr = 0;
+       }
+}
+
 unsigned int comedi_buf_read_n_available(comedi_async *async)
 {
        unsigned int read_end = async->buf_write_count;
@@ -637,16 +690,5 @@ int comedi_buf_put(comedi_async *async, sampl_t x)
 
 void comedi_buf_copy_from(comedi_async *async, void *dest, int nbytes)
 {
-       void *src;
-
-       src = async->prealloc_buf + async->buf_read_ptr;
-       if(async->buf_read_ptr + nbytes >= async->prealloc_bufsz){
-               memcpy(dest, src,
-                       async->prealloc_bufsz - async->buf_read_ptr - nbytes);
-               nbytes -= async->prealloc_bufsz - async->buf_read_ptr;
-               src = async->prealloc_buf;
-               dest += async->prealloc_bufsz - async->buf_read_ptr;
-       }
-       memcpy(dest, src, nbytes);
+       comedi_buf_memcpy_from( async, 0, dest, nbytes );
 }
-
index c690ba48e2c3c8aec9f852bd5c8d46060f0a3ec7..f4989e6ca01e1de062f64883ed874bf806679c78 100644 (file)
@@ -1,5 +1,5 @@
 
-expsyms(mite.o 8255.o amcc_s5933.o)
+expsyms(mite.o 8255.o amcc_s5933.o comedi_fc.o)
 
 select(CONFIG_COMEDI_8255 8255.o)
 select(CONFIG_COMEDI_ADL_PCI9111 adl_pci9111.o)
@@ -10,6 +10,7 @@ select(CONFIG_COMEDI_CB_PCIDAS cb_pcidas.o)
 select(CONFIG_COMEDI_CB_PCIDAS64 cb_pcidas64.o)
 select(CONFIG_COMEDI_CB_PCIDDA cb_pcidda.o)
 select(CONFIG_COMEDI_CB_PCIMDDA cb_pcimdda.o)
+select(CONFIG_COMEDI_FC comedi_fc.o)
 select(CONFIG_COMEDI_CONTEC_PCI_DIO contec_pci_dio.o)
 select(CONFIG_COMEDI_DAQBOARD2000 daqboard2000.o)
 select(CONFIG_COMEDI_DAS08 das08.o)
index 5a607f72557f403772ed811b92ab7b30f93f7c0f..f24baa811ab9623bf165a7b8b0ef72faee46e39e 100644 (file)
@@ -96,6 +96,7 @@ analog triggering on 1602 series
 #include "8253.h"
 #include "8255.h"
 #include "amcc_s5933.h"
+#include "comedi_fc.h"
 
 #undef CB_PCIDAS_DEBUG // disable debugging code
 //#define CB_PCIDAS_DEBUG      // enable debugging code
@@ -103,6 +104,8 @@ analog triggering on 1602 series
 // PCI vendor number of ComputerBoards/MeasurementComputing
 #define PCI_VENDOR_ID_CB       0x1307
 #define TIMER_BASE 100 // 10MHz master clock
+#define AI_BUFFER_SIZE 1024    // maximum fifo size of any supported board
+#define AO_BUFFER_SIZE 1024    // maximum fifo size of any supported board
 #define NUM_CHANNELS_8800 8
 #define NUM_CHANNELS_7376 1
 #define NUM_CHANNELS_8402 2
@@ -425,6 +428,8 @@ typedef struct
        volatile unsigned int adc_fifo_bits;    // bits to write to interupt/adcfifo register
        volatile unsigned int s5933_intcsr_bits;        // bits to write to amcc s5933 interrupt control/status register
        volatile unsigned int ao_control_bits;  // bits to write to ao control and status register
+       sampl_t ai_buffer[ AI_BUFFER_SIZE ];
+       sampl_t ao_buffer[ AO_BUFFER_SIZE ];
        // divisors of master clock for analog output pacing
        unsigned int ao_divisor1;
        unsigned int ao_divisor2;
@@ -1439,8 +1444,7 @@ static int cb_pcidas_ao_cmd(comedi_device *dev,comedi_subdevice *s)
 
 static int cb_pcidas_ao_inttrig(comedi_device *dev, comedi_subdevice *s, unsigned int trig_num)
 {
-       unsigned int i, num_points = thisboard->fifo_size;
-       sampl_t d;
+       unsigned int num_bytes, num_points = thisboard->fifo_size;
        comedi_async *async = s->async;
        comedi_cmd *cmd = &s->async->cmd;
 
@@ -1448,19 +1452,21 @@ static int cb_pcidas_ao_inttrig(comedi_device *dev, comedi_subdevice *s, unsigne
                return -EINVAL;
 
        // load up fifo
-       if(cmd->stop_src == TRIG_COUNT &&
-               devpriv->ao_count < num_points)
+       if( cmd->stop_src == TRIG_COUNT &&
+               devpriv->ao_count < num_points
+       )
                num_points = devpriv->ao_count;
-       
-       // write data to board's fifo
-       for(i = 0; i < num_points; i++) {
-               /* XXX check return value */
-               comedi_buf_get(async, &d);
-               outw(devpriv->ao_registers + DACDATA, d);
-       }
-       if(cmd->stop_src == TRIG_COUNT) {
-               devpriv->ao_count -= i;
+
+       num_bytes = cfc_read_array_from_buffer( s, devpriv->ao_buffer,
+               num_points * sizeof( sampl_t ) );
+       num_points = num_bytes / sizeof( sampl_t );
+
+       if(cmd->stop_src == TRIG_COUNT)
+       {
+               devpriv->ao_count -= num_points;
        }
+       // write data to board's fifo
+       outsw( devpriv->ao_registers + DACDATA, devpriv->ao_buffer, num_bytes );
 
        // enable dac half-full and empty interrupts
        devpriv->adc_fifo_bits |= DAEMIE | DAHFIE;
@@ -1536,8 +1542,6 @@ static void cb_pcidas_interrupt(int irq, void *d, struct pt_regs *regs)
        // if fifo half-full
        if(status & ADHFI)
        {
-               int i;
-
                // read data
                num_samples = half_fifo;
                if(async->cmd.stop_src == TRIG_COUNT &&
@@ -1545,9 +1549,8 @@ static void cb_pcidas_interrupt(int irq, void *d, struct pt_regs *regs)
                {
                        num_samples = devpriv->count;
                }
-               for(i=0;i<num_samples;i++){
-                       comedi_buf_put(async, inw(devpriv->adc_fifo + ADCDATA));
-               }
+               insw(devpriv->adc_fifo + ADCDATA, devpriv->ai_buffer, num_samples);
+               cfc_write_array_to_buffer( s, devpriv->ai_buffer, num_samples * sizeof( sampl_t ) );
                devpriv->count -= num_samples;
                if(async->cmd.stop_src == TRIG_COUNT &&
                        devpriv->count == 0)
@@ -1565,7 +1568,7 @@ static void cb_pcidas_interrupt(int irq, void *d, struct pt_regs *regs)
                        // break if fifo is empty
                        if((ADNE & inw(devpriv->control_status + INT_ADCFIFO)) == 0)
                                break;
-                       comedi_buf_put(async, inw(devpriv->adc_fifo + ADCDATA));
+                       cfc_write_to_buffer( s, inw( devpriv->adc_fifo ) );
                        if(async->cmd.stop_src == TRIG_COUNT &&
                                --devpriv->count == 0)
                        {               /* end of acquisition */
@@ -1603,7 +1606,7 @@ static void handle_ao_interrupt(comedi_device *dev, unsigned int status)
        comedi_async *async = s->async;
        comedi_cmd *cmd = &async->cmd;
        unsigned int half_fifo = thisboard->fifo_size / 2;
-       unsigned int num_points, i;
+       unsigned int num_points;
 
        async->events = 0;
 
@@ -1624,24 +1627,22 @@ static void handle_ao_interrupt(comedi_device *dev, unsigned int status)
                }
        }else if(status & DAHFI)
        {
-               sampl_t d;
+               unsigned int num_bytes;
 
                // figure out how many points we are writing to fifo
                num_points = half_fifo;
                if(cmd->stop_src == TRIG_COUNT &&
                        devpriv->ao_count < num_points)
                        num_points = devpriv->ao_count;
-               // write data to board's fifo
-               for(i = 0; i < num_points; i++)
-               {
-                       comedi_buf_get(async, &d);
-                       outw(devpriv->ao_registers + DACDATA, d);
-               }
+               num_bytes = cfc_read_array_from_buffer( s, devpriv->ao_buffer, num_points * sizeof( sampl_t ) );
+               num_points = num_bytes / sizeof( sampl_t );
+
                if(async->cmd.stop_src == TRIG_COUNT)
                {
-                       devpriv->ao_count -= i;
+                       devpriv->ao_count -= num_points;
                }
-               async->events |= COMEDI_CB_BLOCK;
+               // write data to board's fifo
+               outsw(devpriv->ao_registers + DACDATA, devpriv->ao_buffer, num_points);
                // clear half-full interrupt latch
                outw(devpriv->adc_fifo_bits | DAHFI, devpriv->control_status + INT_ADCFIFO);
        }
index 4e898fd9156919b7d6eba8b3014de0019dedf648..1cb9e2696fe8b7ad70740bc51dee28682e6761db 100644 (file)
@@ -85,6 +85,7 @@ TODO:
 #include "8253.h"
 #include "8255.h"
 #include "plx9080.h"
+#include "comedi_fc.h"
 
 #undef PCIDAS64_DEBUG  // disable debugging code
 //#define PCIDAS64_DEBUG       // enable debugging code
@@ -1915,7 +1916,7 @@ static void pio_drain_ai_fifo_16(comedi_device *dev)
 
                for(i = 0; i < num_samples; i++)
                {
-                       comedi_buf_put(async, readw(priv(dev)->main_iobase + ADC_FIFO_REG));
+                       cfc_write_to_buffer( s, readw(priv(dev)->main_iobase + ADC_FIFO_REG));
                }
 
        } while (read_segment != write_segment);
@@ -1947,11 +1948,11 @@ static void pio_drain_ai_fifo_32(comedi_device *dev)
        for(i = 0; read_code != write_code && i < max_transfer; )
        {
                fifo_data = readl(priv(dev)->dio_counter_iobase + ADC_FIFO_REG);
-               comedi_buf_put(async, fifo_data & 0xffff);
+               cfc_write_to_buffer( s, fifo_data & 0xffff);
                i++;
                if(i < max_transfer)
                {
-                       comedi_buf_put(async, (fifo_data >> 16) & 0xffff);
+                       cfc_write_to_buffer( s, (fifo_data >> 16) & 0xffff);
                        i++;
                }
                read_code = readw(priv(dev)->main_iobase + ADC_READ_PNTR_REG) & 0x7fff;
@@ -1998,7 +1999,8 @@ static void drain_dma_buffers(comedi_device *dev, unsigned int channel)
                                num_samples = priv(dev)->ai_count;
                        priv(dev)->ai_count -= num_samples;
                }
-               comedi_buf_put_array(async, priv(dev)->ai_buffer[priv(dev)->dma_index], num_samples);
+               cfc_write_array_to_buffer( dev->read_subdev,
+                       priv(dev)->ai_buffer[ priv(dev)->dma_index ], num_samples * sizeof( sampl_t ) );
                priv(dev)->dma_index = (priv(dev)->dma_index + 1) % DMA_RING_COUNT;
 
                DEBUG_PRINT("next buffer addr 0x%lx\n", (unsigned long) priv(dev)->ai_buffer_phys_addr[priv(dev)->dma_index]);
diff --git a/comedi/drivers/comedi_fc.c b/comedi/drivers/comedi_fc.c
new file mode 100644 (file)
index 0000000..e3e964b
--- /dev/null
@@ -0,0 +1,120 @@
+/*
+    cfc.c
+
+    This is a place for code driver writers wish to share between
+    two or more drivers.  cfc is short
+    for comedi-frank-common.
+
+    Author:  Frank Mori Hess <fmhess@users.sourceforge.net>
+    Copyright (C) 2002 Frank Mori Hess
+
+    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.
+
+************************************************************************/
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include "comedi_fc.h"
+
+static inline unsigned int bytes_per_sample( comedi_subdevice *subd )
+{
+       if( subd->flags & SDF_LSAMPL )
+               return sizeof( lsampl_t );
+       else
+               return sizeof( sampl_t );
+}
+
+static inline unsigned int bytes_per_scan( comedi_subdevice *subd )
+{
+       return subd->async->cmd.chanlist_len * bytes_per_sample( subd );
+}
+
+static void increment_scan_progress( comedi_subdevice *subd, unsigned int num_bytes )
+{
+       comedi_async *async = subd->async;
+       unsigned int scan_length = bytes_per_scan( subd );
+
+       async->scan_progress += num_bytes;
+       if( async->scan_progress >= scan_length )
+       {
+               async->scan_progress %= scan_length;
+               async->events |= COMEDI_CB_EOS;
+       }
+}
+
+/* Writes an array of data points to comedi's buffer */
+unsigned int cfc_write_array_to_buffer( comedi_subdevice *subd, void *data,
+       unsigned int num_bytes )
+{
+       comedi_async *async = subd->async;
+       unsigned int retval;
+
+       retval = comedi_buf_write_alloc( async, num_bytes );
+       if( retval != num_bytes )
+       {
+               async->events |= COMEDI_CB_ERROR;
+               return 0;
+       }
+
+       comedi_buf_memcpy_to( async, 0, data, num_bytes);
+
+       comedi_buf_write_free( async, num_bytes );
+
+       increment_scan_progress( subd, num_bytes );
+
+       if( num_bytes ) async->events |= COMEDI_CB_BLOCK;
+
+       return num_bytes;
+}
+
+unsigned int cfc_read_array_from_buffer( comedi_subdevice *subd, void *data,
+       unsigned int num_bytes )
+{
+       comedi_async *async = subd->async;
+       unsigned int bytes_available;
+
+       bytes_available = comedi_buf_read_n_available( async );
+       if( bytes_available < num_bytes )
+       {
+               num_bytes = bytes_available;
+       }
+
+       comedi_buf_memcpy_from( async, 0, data, num_bytes);
+
+       comedi_buf_read_free( async, num_bytes );
+
+       increment_scan_progress( subd, num_bytes );
+
+       if( num_bytes ) async->events |= COMEDI_CB_BLOCK;
+
+       return num_bytes;
+}
+
+MODULE_AUTHOR("Frank Mori Hess <fmhess@users.sourceforge.net>");
+MODULE_DESCRIPTION("Shared functoins for Comedi low-level drivers");
+MODULE_LICENSE("GPL");
+
+static int __init comedi_fc_init_module(void)
+{
+       return 0;
+}
+static void __exit comedi_fc_cleanup_module(void)
+{
+}
+module_init(comedi_fc_init_module);
+module_exit(comedi_fc_cleanup_module);
+
+EXPORT_SYMBOL( cfc_write_array_to_buffer );
+EXPORT_SYMBOL( cfc_read_array_from_buffer );
diff --git a/comedi/drivers/comedi_fc.h b/comedi/drivers/comedi_fc.h
new file mode 100644 (file)
index 0000000..5e49c7c
--- /dev/null
@@ -0,0 +1,46 @@
+/*
+    cfc.h
+
+    This is a place for code driver writers wish to share between
+    two or more drivers.
+    If it ever grows beyond a couple inline functions, I'll make
+    a cfc.o module to go with this header file.  cfc is short
+    for comedi-frank-common.
+
+    Author:  Frank Mori Hess <fmhess@users.sourceforge.net>
+    Copyright (C) 2002 Frank Mori Hess
+
+    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.
+
+************************************************************************/
+
+#include "linux/comedidev.h"
+
+/* Writes an array of data points to comedi's buffer */
+unsigned int cfc_write_array_to_buffer( comedi_subdevice *subd, void *data,
+       unsigned int num_bytes );
+
+inline unsigned int cfc_write_to_buffer( comedi_subdevice *subd, sampl_t data )
+{
+       return cfc_write_array_to_buffer( subd, &data, sizeof( data ) );
+};
+
+inline unsigned int cfc_write_long_to_buffer( comedi_subdevice *subd, lsampl_t data )
+{
+       return cfc_write_array_to_buffer( subd, &data, sizeof( data ) );
+};
+
+unsigned int cfc_read_array_from_buffer( comedi_subdevice *subd, void *data,
+       unsigned int num_bytes );
index 20af4a4c1da98d5c9db3745957c6fccd80b59ee7..2b0195e51dd1fc3ea3d7a2262ec9f91e2d9099dd 100644 (file)
@@ -212,7 +212,10 @@ static int timer_data_read(comedi_device *dev, comedi_cmd *cmd,
                comedi_error(dev, "read error");
                return -EIO;
        }
-       comedi_buf_put(s->async, data);
+       if( s->flags % SDF_LSAMPL )
+               cfc_write_long_to_buffer( s, data );
+       else
+               cfc_write_to_buffer( s, data );
 
        return 0;
 }
@@ -222,11 +225,20 @@ static int timer_data_write(comedi_device *dev, comedi_cmd *cmd,
        unsigned int index)
 {
        comedi_subdevice *s = dev->write_subdev;
-       int ret;
+       unsigned int num_bytes;
        sampl_t data;
+       lsampl_t long_data;
+
+       if( s->flags & SDF_LSAMPL )
+       {
+               num_bytes = cfc_read_array_from_buffer( s, &long_data, sizeof( long_data ) );
+       }else
+               num_bytes = cfc_read_array_from_buffer( s, &data, sizeof( data ) );
+               long_data = data;
+       }
 
-       ret = comedi_buf_get(s->async, &data);
-       if(ret < 0) {
+       if(num_bytes == 0)
+       {
                comedi_error(dev, "buffer underrun");
                return -EAGAIN;
        }
@@ -234,7 +246,7 @@ static int timer_data_write(comedi_device *dev, comedi_cmd *cmd,
                CR_CHAN(cmd->chanlist[index]),
                CR_RANGE(cmd->chanlist[index]),
                CR_AREF(cmd->chanlist[index]),
-               data);
+               long_data);
        if(ret<0){
                comedi_error(dev, "write error");
                return -EIO;
@@ -256,7 +268,11 @@ static int timer_dio_read(comedi_device *dev, comedi_cmd *cmd,
                comedi_error(dev, "read error");
                return -EIO;
        }
-       comedi_buf_put(s->async, data);
+
+       if( s->flags % SDF_LSAMPL )
+               cfc_write_long_to_buffer( s, data );
+       else
+               cfc_write_to_buffer( s, data );
 
        return 0;
 }
index 627910efae4b822eef5a293593a9207eb839d86d..8c211322ad6d97b3d38bf2d7deb325db715c899d 100644 (file)
@@ -62,6 +62,7 @@ zero volts).
 #include <linux/init.h>
 #include <linux/comedidev.h>
 #include <asm/div64.h>
+#include "comedi_fc.h"
 
 /* Board descriptions */
 typedef struct waveform_board_struct{
@@ -159,7 +160,7 @@ static void waveform_ai_interrupt(unsigned long arg)
        {
                for( j = 0; j < cmd->chanlist_len; j++)
                {
-                       comedi_buf_put(async,
+                       cfc_write_to_buffer( dev->read_subdev,
                                fake_waveform(dev, CR_CHAN(cmd->chanlist[j]), CR_RANGE(cmd->chanlist[j]),
                                        devpriv->usec_current + i * devpriv->scan_period + j * devpriv->convert_period));
                }
@@ -174,8 +175,6 @@ static void waveform_ai_interrupt(unsigned long arg)
        devpriv->usec_current += elapsed_time;
        devpriv->usec_current %= devpriv->usec_period;
 
-       async->events |= COMEDI_CB_BLOCK;
-
        if((async->events & COMEDI_CB_EOA) == 0 && devpriv->timer_running)
                mod_timer(&devpriv->timer, jiffies + 1);
        else
index 986a9878403d0b170058c6ce5f8fc23486422eb9..b9edb8bea78cc4c90d4b87a8ade9ad8c5b6b088f 100644 (file)
@@ -56,13 +56,13 @@ Options:
                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).  If set, also allows 
+       [8] - use timer mode for DMA, needed e.g. for buggy DMA controller
+               in NS CS5530A (Geode Companion).  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 required 
+Both a dma channel and an irq (or use of 'timer mode', option 8) are required
 for timed or externally triggered conversions.
 */
 /*
@@ -90,6 +90,7 @@ Computer boards manuals also available from their website www.measurementcomputi
 #include <asm/dma.h>
 #include "8253.h"
 #include "8255.h"
+#include "comedi_fc.h"
 
 #undef DEBUG
 //#define DEBUG
@@ -1152,15 +1153,26 @@ static void das16_timer_interrupt(unsigned long arg)
                mod_timer(&devpriv->timer, jiffies + timer_period);
 }
 
+static void munge_ai_data( comedi_device *dev, sampl_t *data, unsigned int num_points)
+{
+       unsigned int i;
+
+       if( thisboard->ai_nbits == 12)
+       {
+               for(i = 0; i < num_points; i++)
+               {
+                       data[i] = ( data[i] >> 4 ) & 0xfff;
+               }
+       }
+}
+
 static void das16_interrupt( comedi_device *dev )
 {
-       int i;
        unsigned long flags;
        comedi_subdevice *s = dev->read_subdev;
        comedi_async *async;
        comedi_cmd *cmd;
        int num_points, num_bytes, residue;
-       sampl_t dpnt;
        unsigned int target_xfer;
 
        if(dev->attached == 0)
@@ -1203,15 +1215,9 @@ static void das16_interrupt( comedi_device *dev )
                async->events |= COMEDI_CB_EOA;
        }
 
-       for(i = 0; i < num_points; i++)
-       {
-               /* write data point to comedi buffer */
-               dpnt = devpriv->dma_buffer[i];
-               if(thisboard->ai_nbits == 12)
-                       dpnt = (dpnt >> 4) & 0xfff;
-               comedi_buf_put(async, dpnt);
-               devpriv->adc_count--;
-       }
+       munge_ai_data( dev, devpriv->dma_buffer, num_points );
+       cfc_write_array_to_buffer( s, devpriv->dma_buffer, num_points * sizeof( sampl_t ) );
+       devpriv->adc_count -= num_points;
 
        // figure out how many bytes for next transfer
        target_xfer = devpriv->target_transfer_size;
index 99dd324d8a38ae59dd44a9ed2af247bbf4f3f491..bb8a4985fe63c1472b1430fcef3f10cf2403e881 100644 (file)
@@ -68,6 +68,7 @@ irq can be omitted, although the cmd interface will not work without it.
 #include <linux/delay.h>
 #include "8255.h"
 #include "8253.h"
+#include "comedi_fc.h"
 
 #define DAS16M1_SIZE 16
 #define DAS16M1_SIZE2 8
@@ -98,7 +99,6 @@ irq can be omitted, although the cmd interface will not work without it.
 
 #define DAS16M1_AI             0       // 16-bit wide register
 #define   AI_CHAN(x)             ((x) & 0xf)
-#define   AI_DATA(x)             (((x) >> 4) & 0xfff)
 #define DAS16M1_CS             2
 #define   EXT_TRIG_BIT           0x1
 #define   OVRUN                  0x20
@@ -186,6 +186,7 @@ struct das16m1_private_struct {
         * needed to keep track of whether new count has been loaded into
         * counter yet (loaded by first sample conversion) */
        u16 initial_hw_count;
+       sampl_t ai_buffer[ FIFO_SIZE ];
        unsigned int do_bits;   // saves status of digital output bits
        unsigned int divisor1;  // divides master clock to obtain conversion speed
        unsigned int divisor2;  // divides master clock to obtain conversion speed
@@ -195,6 +196,11 @@ struct das16m1_private_struct {
 
 COMEDI_INITCLEANUP(driver_das16m1);
 
+static inline sampl_t munge_sample( sampl_t data )
+{
+       return ( data >> 4 ) & 0xfff;
+}
+
 static int das16m1_cmd_test(comedi_device *dev,comedi_subdevice *s, comedi_cmd *cmd)
 {
        unsigned int err=0, tmp, i;
@@ -413,7 +419,7 @@ static int das16m1_ai_rinsn(comedi_device *dev,comedi_subdevice *s,comedi_insn *
                        comedi_error(dev, "timeout");
                        return -ETIME;
                }
-               data[n] = AI_DATA(inw(dev->iobase));
+               data[n] = munge_sample( inw( dev->iobase ) );
        }
 
        return n;
@@ -494,9 +500,18 @@ static void das16m1_interrupt(int irq, void *d, struct pt_regs *regs)
        spin_unlock(&dev->spinlock);
 }
 
+static void munge_sample_array( sampl_t *array, unsigned int num_elements )
+{
+       unsigned int i;
+
+       for(i = 0; i < num_elements; i++)
+       {
+               array[i] = munge_sample( array[i] );
+       }
+}
+
 static void das16m1_handler(comedi_device *dev, unsigned int status)
 {
-       int i;
        comedi_subdevice *s;
        comedi_async *async;
        comedi_cmd *cmd;
@@ -534,13 +549,9 @@ static void das16m1_handler(comedi_device *dev, unsigned int status)
        // make sure we dont try to get too many points if fifo has overrun
        if(num_samples > FIFO_SIZE)
                num_samples = FIFO_SIZE;
-       for(i = 0; i < num_samples; i++) {
-               sampl_t d;
-
-               d = inw(dev->iobase);
-               /* XXX check return value */
-               comedi_buf_put(async, AI_DATA(d));
-       }
+       insw( dev->iobase, devpriv->ai_buffer, num_samples );
+       munge_sample_array( devpriv->ai_buffer, num_samples );
+       cfc_write_array_to_buffer( s, devpriv->ai_buffer, num_samples * sizeof( sampl_t ) );
        devpriv->adc_count += num_samples;
 
        if(cmd->stop_src == TRIG_COUNT)
index dfdef7fb03172a9773174b7aeaf395b102875cf4..59bf21f9676611523932b92bf96d1404ba41ef5f 100644 (file)
@@ -114,10 +114,11 @@ TODO:
 #include <asm/dma.h>
 #include <linux/comedidev.h>
 #include "8253.h"
+#include "comedi_fc.h"
 
 // misc. defines
 #define DAS1800_SIZE           16      //uses 16 io addresses
-#define HALF_FIFO              512     // 1024 sample fifo
+#define FIFO_SIZE              1024    // 1024 sample fifo
 #define TIMER_BASE             200     // 5 Mhz master clock
 #define UNIPOLAR               0x4     // bit that determines whether input range is uni/bipolar
 #define DMA_BUF_SIZE           0x1ff00 // size in bytes of dma buffers
@@ -195,7 +196,7 @@ static int das1800_ai_poll(comedi_device *dev,comedi_subdevice *s);
 static void das1800_ai_handler(comedi_device *dev);
 static void das1800_handle_dma(comedi_device *dev, comedi_subdevice *s, unsigned int status);
 static void das1800_flush_dma(comedi_device *dev, comedi_subdevice *s);
-static void das1800_flush_dma_channel(comedi_device *dev, comedi_subdevice *s, unsigned int channel, u16 *buffer);
+static void das1800_flush_dma_channel(comedi_device *dev, comedi_subdevice *s, unsigned int channel, uint16_t *buffer);
 static void das1800_handle_fifo_half_full(comedi_device *dev, comedi_subdevice *s);
 static void das1800_handle_fifo_not_empty(comedi_device *dev, comedi_subdevice *s);
 static int das1800_ai_do_cmdtest(comedi_device *dev,comedi_subdevice *s,comedi_cmd *cmd);
@@ -472,9 +473,9 @@ typedef struct{
        unsigned int dma0;      /* dma channels used */
        unsigned int dma1;
        volatile unsigned int dma_current;      /* dma channel currently in use */
-       u16 *dma_buf0;  /* pointers to dma buffers */
-       u16 *dma_buf1;
-       u16 *dma_current_buf;   /* pointer to dma buffer currently being used */
+       uint16_t *ai_buf0;      /* pointers to dma buffers */
+       uint16_t *ai_buf1;
+       uint16_t *dma_current_buf;      /* pointer to dma buffer currently being used */
        unsigned int dma_transfer_size; /* size of transfer currently used, in bytes */
        int iobase2;    /* secondary io address used for analog out on 'ao' boards */
        short ao_update_bits; /* remembers the last write to the 'update' dac */
@@ -517,16 +518,90 @@ static comedi_driver driver_das1800={
  */
 COMEDI_INITCLEANUP(driver_das1800);
 
+int das1800_init_dma( comedi_device *dev, unsigned int dma0, unsigned int dma1 )
+{
+       unsigned long flags;
+       
+       // need an irq to do dma
+       if( dev->irq && dma0 )
+       {
+               //encode dma0 and dma1 into 2 digit hexadecimal for switch
+               switch((dma0 & 0x7) | (dma1 << 4))
+               {
+                       case 0x5:       // dma0 == 5
+                               devpriv->dma_bits |= DMA_CH5;
+                               break;
+                       case 0x6:       // dma0 == 6
+                               devpriv->dma_bits |= DMA_CH6;
+                               break;
+                       case 0x7:       // dma0 == 7
+                               devpriv->dma_bits |= DMA_CH7;
+                               break;
+                       case 0x65:      // dma0 == 5, dma1 == 6
+                               devpriv->dma_bits |= DMA_CH5_CH6;
+                               break;
+                       case 0x76:      // dma0 == 6, dma1 == 7
+                               devpriv->dma_bits |= DMA_CH6_CH7;
+                               break;
+                       case 0x57:      // dma0 == 7, dma1 == 5
+                               devpriv->dma_bits |= DMA_CH7_CH5;
+                               break;
+                       default:
+                               printk(" only supports dma channels 5 through 7\n"
+                                       " Dual dma only allows the following combinations:\n"
+                                       " dma 5,6 / 6,7 / or 7,5\n");
+                               return -EINVAL;
+                               break;
+               }
+               if( request_dma( dma0, driver_das1800.driver_name ) )
+               {
+                       printk( " failed to allocate dma channel %i\n", dma0 );
+                       return -EINVAL;
+               }
+               devpriv->dma0 = dma0;
+               devpriv->dma_current = dma0;
+               if( dma1 )
+               {
+                       if( request_dma( dma1, driver_das1800.driver_name ) )
+                       {
+                               printk( " failed to allocate dma channel %i\n", dma1 );
+                               return -EINVAL;
+                       }
+                       devpriv->dma1 = dma1;
+               }
+               devpriv->ai_buf0 = kmalloc(DMA_BUF_SIZE, GFP_KERNEL | GFP_DMA);
+               if(devpriv->ai_buf0 == NULL)
+                       return -ENOMEM;
+               devpriv->dma_current_buf = devpriv->ai_buf0;
+               if( dma1 )
+               {
+                       devpriv->ai_buf1 = kmalloc(DMA_BUF_SIZE, GFP_KERNEL | GFP_DMA);
+                       if(devpriv->ai_buf1 == NULL)
+                               return -ENOMEM;
+               }
+               flags = claim_dma_lock();
+               disable_dma(devpriv->dma0);
+               set_dma_mode(devpriv->dma0, DMA_MODE_READ);
+               if( dma1 )
+               {
+                       disable_dma(devpriv->dma1);
+                       set_dma_mode(devpriv->dma1, DMA_MODE_READ);
+               }
+               release_dma_lock(flags);
+       }
+       return 0;
+}
+
 static int das1800_attach(comedi_device *dev, comedi_devconfig *it)
 {
        comedi_subdevice *s;
-       unsigned long flags;
        int iobase = it->options[0];
        int irq = it->options[1];
        int dma0 = it->options[2];
        int dma1 = it->options[3];
        int iobase2;
        int board;
+       int retval;
 
        /* allocate and initialize dev->private */
        if(alloc_private(dev, sizeof(das1800_private)) < 0)
@@ -624,76 +699,14 @@ static int das1800_attach(comedi_device *dev, comedi_devconfig *it)
                        break;
        }
 
-       //dma stuff
-       // need an irq to do dma
-       if(irq)
+       retval = das1800_init_dma( dev, dma0, dma1 );
+       if( retval < 0 ) return retval;
+
+       if( devpriv->ai_buf0 == NULL )
        {
-               if(dma0)
-               {
-                       //encode dma0 and dma1 into 2 digit hexadecimal for switch
-                       switch((dma0 & 0x7) | (dma1 << 4))
-                       {
-                               case 0x5:       // dma0 == 5
-                                       devpriv->dma_bits |= DMA_CH5;
-                                       break;
-                               case 0x6:       // dma0 == 6
-                                       devpriv->dma_bits |= DMA_CH6;
-                                       break;
-                               case 0x7:       // dma0 == 7
-                                       devpriv->dma_bits |= DMA_CH7;
-                                       break;
-                               case 0x65:      // dma0 == 5, dma1 == 6
-                                       devpriv->dma_bits |= DMA_CH5_CH6;
-                                       break;
-                               case 0x76:      // dma0 == 6, dma1 == 7
-                                       devpriv->dma_bits |= DMA_CH6_CH7;
-                                       break;
-                               case 0x57:      // dma0 == 7, dma1 == 5
-                                       devpriv->dma_bits |= DMA_CH7_CH5;
-                                       break;
-                               default:
-                                       printk(" only supports dma channels 5 through 7\n"
-                                               " Dual dma only allows the following combinations:\n"
-                                               " dma 5,6 / 6,7 / or 7,5\n");
-                                       return -EINVAL;
-                                       break;
-                       }
-                       if(request_dma(dma0, driver_das1800.driver_name))
-                       {
-                               printk(" failed to allocate dma channel %i\n", dma0);
-                               return -EINVAL;
-                       }
-                       devpriv->dma0 = dma0;
-                       devpriv->dma_current = dma0;
-                       if(dma1)
-                       {
-                               if(request_dma(dma1, driver_das1800.driver_name))
-                               {
-                                       printk(" failed to allocate dma channel %i\n", dma1);
-                                       return -EINVAL;
-                               }
-                               devpriv->dma1 = dma1;
-                       }
-                       devpriv->dma_buf0 = kmalloc(DMA_BUF_SIZE, GFP_KERNEL | GFP_DMA);
-                       if(devpriv->dma_buf0 == NULL)
-                               return -ENOMEM;
-                       devpriv->dma_current_buf = devpriv->dma_buf0;
-                       if(dma1)
-                       {
-                               devpriv->dma_buf1 = kmalloc(DMA_BUF_SIZE, GFP_KERNEL | GFP_DMA);
-                               if(devpriv->dma_buf1 == NULL)
-                                       return -ENOMEM;
-                       }
-                       flags = claim_dma_lock();
-                       disable_dma(devpriv->dma0);
-                       set_dma_mode(devpriv->dma0, DMA_MODE_READ);
-                       if(dma1)
-                       {
-                               disable_dma(devpriv->dma1);
-                               set_dma_mode(devpriv->dma1, DMA_MODE_READ);
-                       }
-                       release_dma_lock(flags);
-               }
+               devpriv->ai_buf0 = kmalloc( FIFO_SIZE * sizeof( uint16_t ), GFP_KERNEL );
+               if(devpriv->ai_buf0 == NULL)
+                       return -ENOMEM;
        }
 
        dev->n_subdevices = 4;
@@ -782,10 +795,10 @@ static int das1800_detach(comedi_device *dev)
                        free_dma(devpriv->dma0);
                if(devpriv->dma1)
                        free_dma(devpriv->dma1);
-               if(devpriv->dma_buf0)
-                       kfree(devpriv->dma_buf0);
-               if(devpriv->dma_buf1)
-                       kfree(devpriv->dma_buf1);
+               if(devpriv->ai_buf0)
+                       kfree(devpriv->ai_buf0);
+               if(devpriv->ai_buf1)
+                       kfree(devpriv->ai_buf1);
        }
 
        printk("comedi%d: %s: remove\n", dev->minor, driver_das1800.driver_name);
@@ -997,12 +1010,12 @@ static void das1800_handle_dma(comedi_device *dev, comedi_subdevice *s, unsigned
                        if(devpriv->dma_current == devpriv->dma0)
                        {
                                devpriv->dma_current = devpriv->dma1;
-                               devpriv->dma_current_buf = devpriv->dma_buf1;
+                               devpriv->dma_current_buf = devpriv->ai_buf1;
                        }
                        else
                        {
                                devpriv->dma_current = devpriv->dma0;
-                               devpriv->dma_current_buf = devpriv->dma_buf0;
+                               devpriv->dma_current_buf = devpriv->ai_buf0;
                        }
                }
        }
@@ -1010,14 +1023,35 @@ static void das1800_handle_dma(comedi_device *dev, comedi_subdevice *s, unsigned
        return;
 }
 
+static inline uint16_t munge_bipolar_sample( const comedi_device *dev, uint16_t sample )
+{
+       sample += 1 << ( thisboard->resolution - 1 );
+       return sample;
+}
+
+static void munge_data( comedi_device *dev, uint16_t *array, unsigned int num_elements )
+{
+       unsigned int i;
+       int unipolar;
+
+       /* see if card is using a unipolar or bipolar range so we can munge data correctly */
+       unipolar = inb( dev->iobase + DAS1800_CONTROL_C ) & UB;
+
+       /* convert to unsigned type if we are in a bipolar mode */
+       if( !unipolar )
+       {
+               for( i = 0; i < num_elements; i++ )
+               {
+                       array[i] = munge_bipolar_sample( dev, array[i] );
+               }
+       }
+}
+
 /* Utility function used by das1800_flush_dma() and das1800_handle_dma().
  * Assumes dma lock is held */
-static void das1800_flush_dma_channel(comedi_device *dev, comedi_subdevice *s, unsigned int channel, u16 *buffer)
+static void das1800_flush_dma_channel(comedi_device *dev, comedi_subdevice *s, unsigned int channel, uint16_t *buffer)
 {
-       unsigned int numPoints;
-       int unipolar;
-       int i;
-       const int bytes_per_sample = 2;
+       unsigned int num_bytes, num_samples;
        comedi_cmd *cmd = &s->async->cmd;
 
        disable_dma(channel);
@@ -1027,25 +1061,17 @@ static void das1800_flush_dma_channel(comedi_device *dev, comedi_subdevice *s, u
        clear_dma_ff(channel);
 
        // figure out how many points to read
-       numPoints = (devpriv->dma_transfer_size - get_dma_residue(channel)) /
-               bytes_per_sample;
-       /* if we only need some of the points */
-       if(cmd->stop_src == TRIG_COUNT && devpriv->count < numPoints)
-               numPoints = devpriv->count;
+       num_bytes = devpriv->dma_transfer_size - get_dma_residue( channel );
+       num_samples = num_bytes / sizeof( sampl_t );
 
-       /* see if card is using a unipolar or bipolar range so we can munge data correctly */
-       unipolar = inb(dev->iobase + DAS1800_CONTROL_C) & UB;
+       /* if we only need some of the points */
+       if( cmd->stop_src == TRIG_COUNT && devpriv->count < num_samples )
+               num_samples = devpriv->count;
 
-       // read data from dma buffer
-       for( i = 0; i < numPoints; i++)
-       {
-               /* convert to unsigned type if we are in a bipolar mode */
-               if(!unipolar);
-                       buffer[i] += 1 << (thisboard->resolution - 1);
-               comedi_buf_put(s->async, buffer[i]);
-               if(s->async->cmd.stop_src == TRIG_COUNT)
-                       devpriv->count--;
-       }
+       munge_data( dev, buffer, num_samples );
+       cfc_write_array_to_buffer( s, buffer, num_bytes );
+       if(s->async->cmd.stop_src == TRIG_COUNT)
+               devpriv->count -= num_samples;
 
        return;
 }
@@ -1066,12 +1092,12 @@ static void das1800_flush_dma(comedi_device *dev, comedi_subdevice *s)
                if(devpriv->dma_current == devpriv->dma0)
                {
                        devpriv->dma_current = devpriv->dma1;
-                       devpriv->dma_current_buf = devpriv->dma_buf1;
+                       devpriv->dma_current_buf = devpriv->ai_buf1;
                }
                else
                {
                        devpriv->dma_current = devpriv->dma0;
-                       devpriv->dma_current_buf = devpriv->dma_buf0;
+                       devpriv->dma_current_buf = devpriv->ai_buf0;
                }
                das1800_flush_dma_channel(dev, s, devpriv->dma_current, devpriv->dma_current_buf);
        }
@@ -1086,28 +1112,18 @@ static void das1800_flush_dma(comedi_device *dev, comedi_subdevice *s)
 
 static void das1800_handle_fifo_half_full(comedi_device *dev, comedi_subdevice *s)
 {
-       int i;          /* loop index */
        int numPoints = 0;      /* number of points to read */
-       u16 data[HALF_FIFO];
-       int unipolar;
        comedi_cmd *cmd = &s->async->cmd;
 
-       unipolar = inb(dev->iobase + DAS1800_CONTROL_C) & UB;
-
-       numPoints = HALF_FIFO;
+       numPoints = FIFO_SIZE / 2;
        /* if we only need some of the points */
        if(cmd->stop_src == TRIG_COUNT && devpriv->count < numPoints)
                numPoints = devpriv->count;
-       insw(dev->iobase + DAS1800_FIFO, data, numPoints);
-       for( i = 0; i < numPoints; i++)
-       {
-               /* write data point to buffer */
-               /* convert to unsigned type if we are in a bipolar mode */
-               if(!unipolar);
-                       data[i] += 1 << (thisboard->resolution - 1);
-               comedi_buf_put(s->async, data[i]);
-               if(cmd->stop_src == TRIG_COUNT) devpriv->count--;
-       }
+       insw(dev->iobase + DAS1800_FIFO, devpriv->ai_buf0, numPoints);
+       munge_data( dev, devpriv->ai_buf0, numPoints );
+       cfc_write_array_to_buffer( s, devpriv->ai_buf0, numPoints * sizeof( devpriv->ai_buf0[0] ) );
+       if( cmd->stop_src == TRIG_COUNT )
+               devpriv->count -= numPoints;
        return;
 }
 
@@ -1119,15 +1135,15 @@ static void das1800_handle_fifo_not_empty(comedi_device *dev, comedi_subdevice *
 
        unipolar = inb(dev->iobase + DAS1800_CONTROL_C) & UB;
 
-       while(inb(dev->iobase + DAS1800_STATUS) & FNE)
+       while( inb( dev->iobase + DAS1800_STATUS ) & FNE )
        {
                if(cmd->stop_src == TRIG_COUNT && devpriv->count == 0)
                        break;
-               dpnt = inw(dev->iobase + DAS1800_FIFO);
+               dpnt = inw( dev->iobase + DAS1800_FIFO );
                /* convert to unsigned type if we are in a bipolar mode */
                if(!unipolar);
-                       dpnt += 1 << (thisboard->resolution - 1);
-               comedi_buf_put(s->async, dpnt);
+                       dpnt = munge_bipolar_sample( dev, dpnt );
+               cfc_write_to_buffer( s, dpnt );
                if(cmd->stop_src == TRIG_COUNT) devpriv->count--;
        }
 
@@ -1438,11 +1454,11 @@ static void setup_dma(comedi_device *dev, comedi_cmd cmd)
        /* clear flip-flop to make sure 2-byte registers for
         * count and address get set correctly */
        clear_dma_ff(devpriv->dma0);
-       set_dma_addr(devpriv->dma0, virt_to_bus(devpriv->dma_buf0));
+       set_dma_addr(devpriv->dma0, virt_to_bus(devpriv->ai_buf0));
        // set appropriate size of transfer
        set_dma_count(devpriv->dma0, devpriv->dma_transfer_size);
        devpriv->dma_current = devpriv->dma0;
-       devpriv->dma_current_buf = devpriv->dma_buf0;
+       devpriv->dma_current_buf = devpriv->ai_buf0;
        enable_dma(devpriv->dma0);
        // set up dual dma if appropriate
        if(dual_dma)
@@ -1451,7 +1467,7 @@ static void setup_dma(comedi_device *dev, comedi_cmd cmd)
                /* clear flip-flop to make sure 2-byte registers for
                 * count and address get set correctly */
                clear_dma_ff(devpriv->dma1);
-               set_dma_addr(devpriv->dma1, virt_to_bus(devpriv->dma_buf1));
+               set_dma_addr(devpriv->dma1, virt_to_bus(devpriv->ai_buf1));
                // set appropriate size of transfer
                set_dma_count(devpriv->dma1, devpriv->dma_transfer_size);
                enable_dma(devpriv->dma1);
index bc0a317741118eb1872fd8ec2494ba53a3631010..b1980f5604ba4f1d17ef6ea8129b9c03279ace27 100644 (file)
@@ -75,6 +75,7 @@ cmd triggers supported:
 #include <asm/io.h>
 #include <linux/comedidev.h>
 #include "8253.h"
+#include "comedi_fc.h"
 
 #define DAS800_SIZE           8
 #define TIMER_BASE            1000
@@ -415,7 +416,7 @@ static void das800_interrupt(int irq, void *d, struct pt_regs *regs)
                if(devpriv->count > 0 || devpriv->forever == 1)
                {
                        /* write data point to buffer */
-                       comedi_buf_put(async, dataPoint);
+                       cfc_write_to_buffer( s, dataPoint);
                        if(devpriv->count > 0) devpriv->count--;
                }
        }
index 86ae6de02748faa7c8e8587c0f80171176fbac09..6cd12a1faeb8297fef49eae437ba92dd4f85bfe2 100644 (file)
@@ -1,6 +1,6 @@
 /*
     ni_at_a2150.c driver for National Instruments AT-A2150 boards
-    Copyright (C) 2001 Frank Mori Hess <fmhess@uiuc.edu>
+    Copyright (C) 2001, 2002 Frank Mori Hess <fmhess@users.sourceforge.net>
 
     COMEDI - Linux Control and Measurement Device Interface
     Copyright (C) 2000 David A. Schleef <ds@schleef.org>
@@ -78,6 +78,7 @@ TRIG_WAKE_EOS
 #include <asm/dma.h>
 #include <linux/comedidev.h>
 #include "8253.h"
+#include "comedi_fc.h"
 
 #define A2150_SIZE           28
 #define A2150_DMA_BUFFER_SIZE  0xff00  // size in bytes of dma buffer
@@ -299,7 +300,7 @@ static void a2150_interrupt(int irq, void *d, struct pt_regs *regs)
                dpnt = devpriv->dma_buffer[i];
                // convert from 2's complement to unsigned coding
                dpnt ^= 0x8000;
-               comedi_buf_put(async, dpnt);
+               cfc_write_to_buffer( s, dpnt );
                if(cmd->stop_src == TRIG_COUNT)
                {
                        if(--devpriv->count == 0)
index a20516d4a5d459b34d646de37b61673f605c0cff..e2c5ceaedb41bdc37a85918d07c5ac6a98a2960a 100644 (file)
@@ -67,8 +67,8 @@ NI manuals:
 
 */
 
-#define LABPC_DEBUG    // enable debugging messages
-//#undef LABPC_DEBUG
+#undef LABPC_DEBUG
+//#define LABPC_DEBUG  // enable debugging messages
 
 #include <linux/kernel.h>
 #include <linux/module.h>
@@ -88,6 +88,7 @@ NI manuals:
 #include "8253.h"
 #include "8255.h"
 #include "mite.h"
+#include "comedi_fc.h"
 
 #if defined(CONFIG_PCMCIA) || defined(CONFIG_PCMCIA_MODULE)
 
@@ -738,11 +739,14 @@ static int labpc_attach(comedi_device *dev, comedi_devconfig *it)
                s->insn_read = labpc_eeprom_read_insn;
                s->insn_write = labpc_eeprom_write_insn;
 
+               for(i = 0; i < EEPROM_SIZE; i++)
+               {
+                       devpriv->eeprom_data[i] = labpc_eeprom_read(dev, i);
+               }
 #ifdef LABPC_DEBUG
                printk(" eeprom:");
                for(i = 0; i < EEPROM_SIZE; i++)
                {
-                       devpriv->eeprom_data[i] = labpc_eeprom_read(dev, i);
                        printk(" %i:0x%x ", i, devpriv->eeprom_data[i]);
                }
                printk("\n");
@@ -1380,7 +1384,7 @@ static int labpc_drain_fifo(comedi_device *dev)
                lsb = thisboard->read_byte(dev->iobase + ADC_FIFO_REG);
                msb = thisboard->read_byte(dev->iobase + ADC_FIFO_REG);
                data = (msb << 8) | lsb;
-               comedi_buf_put(async, data);
+               cfc_write_to_buffer( dev->read_subdev, data );
                // quit if we have all the data we want
                if(async->cmd.stop_src == TRIG_COUNT)
                {
@@ -1443,9 +1447,9 @@ static void labpc_drain_dma(comedi_device *dev)
        }
 
        /* write data to comedi buffer */
-       for(i=0;i<num_points;i++){
-               /* XXX check for errors */
-               comedi_buf_put(async, devpriv->dma_buffer[i]);
+       for( i = 0; i < num_points; i++)
+       {
+               cfc_write_to_buffer( s, devpriv->dma_buffer[i] );
        }
        if(async->cmd.stop_src == TRIG_COUNT) devpriv->count -= num_points;
 
index d7627558bdceeff50b607974369f0f577a348d1f..0e4a2460092b9fb832ca44fe845445cf48008b25 100644 (file)
@@ -124,6 +124,8 @@ static void init_async_buf( comedi_async *async )
        async->buf_free_count = 0;
        async->buf_read_ptr = 0;
        async->buf_write_ptr = 0;
+       async->cur_chan = 0;
+       async->scan_progress = 0;
 }
 
 int comedi_command(comedi_t *d,comedi_cmd *cmd)
@@ -160,7 +162,6 @@ int comedi_command(comedi_t *d,comedi_cmd *cmd)
 
        async->data = cmd->data;
        async->data_len = cmd->data_len;
-       async->cur_chan = 0;
 
        return s->do_cmd(dev,s);
 }
index cfdd96bff8175e7287fe8cffff8e26f869b7aebe..b84729102e0a0790bb1c1e837718dc46a198144a 100644 (file)
@@ -139,6 +139,8 @@ struct comedi_async_struct{
        unsigned int buf_read_ptr;      /* buffer marker for reader */
 
        unsigned int cur_chan;          /* useless channel marker for interrupt */
+       /* number of bytes that have been received for current scan */
+       unsigned int scan_progress;
 
        void            *data;
        unsigned int    data_len;
@@ -335,6 +337,10 @@ void comedi_buf_write_free(comedi_async *async, unsigned int nbytes);
 void comedi_buf_read_free(comedi_async *async, unsigned int nbytes);
 unsigned int comedi_buf_read_n_available(comedi_async *async);
 void comedi_buf_copy_from(comedi_async *async, void *dest, int nbytes);
+void comedi_buf_memcpy_to( comedi_async *async, unsigned int offset, const void *source,
+       unsigned int num_bytes );
+void comedi_buf_memcpy_from( comedi_async *async, unsigned int offset, void *destination,
+       unsigned int num_bytes );
 
 
 //#ifdef CONFIG_COMEDI_RT