pcl818: bug fixes: For AI commands, the scan counter was being updated
authorIan Abbott <abbotti@mev.co.uk>
Mon, 18 Jan 2010 16:46:11 +0000 (16:46 +0000)
committerIan Abbott <abbotti@mev.co.uk>
Mon, 18 Jan 2010 16:46:11 +0000 (16:46 +0000)
after every sample, except for DMA mode where is was being updated after
each repeated segment of the channel list.  Keep track of current sample
and update the scan counter at the end of each scan.  Also, AI commands
with multiple channels were being terminated with an error incorrectly in
non-DMA mode.  This was because the current position within a repeated
segment of the channel list was not being updated, causing it to think
there was a "channel dropout" when comparing the assumed current channel
with the channel number read from the FIFO.

comedi/drivers/pcl818.c

index 32900bd86b1debf293b6be69f0c123c5ca100997..1f62cd51aa7bf601a17ec10a8faa6de07ff5950b 100644 (file)
@@ -544,8 +544,14 @@ static irqreturn_t interrupt_pcl818_ai_mode13_int(int irq, void *d)
                comedi_event(dev, s);
                return IRQ_HANDLED;
        }
-       if (s->async->cur_chan == 0) {
+       devpriv->act_chanlist_pos++;
+       if (devpriv->act_chanlist_pos >= devpriv->act_chanlist_len) {
+               devpriv->act_chanlist_pos = 0;
+       }
+       s->async->cur_chan++;
+       if (s->async->cur_chan >= devpriv->ai_n_chan) {
                // rt_printk("E");
+               s->async->cur_chan = 0;
                devpriv->ai_act_scan--;
        }
 
@@ -614,9 +620,13 @@ static irqreturn_t interrupt_pcl818_ai_mode13_dma(int irq, void *d)
 
                devpriv->act_chanlist_pos++;
                if (devpriv->act_chanlist_pos >= devpriv->act_chanlist_len) {
-                       devpriv->ai_act_scan--;
                        devpriv->act_chanlist_pos = 0;
                }
+               s->async->cur_chan++;
+               if (s->async->cur_chan >= devpriv->ai_n_chan) {
+                       s->async->cur_chan = 0;
+                       devpriv->ai_act_scan--;
+               }
 
                if (!devpriv->neverending_ai)
                        if (devpriv->ai_act_scan == 0) {        /* all data sampled */
@@ -704,7 +714,14 @@ static irqreturn_t interrupt_pcl818_ai_mode13_dma_rtc(int irq, void *d)
                        comedi_buf_put(s->async, dmabuf[bufptr++] >> 4);        // get one sample
                        bufptr &= (devpriv->dmasamplsize - 1);
 
-                       if (s->async->cur_chan == 0) {
+                       devpriv->act_chanlist_pos++;
+                       if (devpriv->act_chanlist_pos >=
+                                       devpriv->act_chanlist_len) {
+                               devpriv->act_chanlist_pos = 0;
+                       }
+                       s->async->cur_chan++;
+                       if (s->async->cur_chan >= devpriv->ai_n_chan) {
+                               s->async->cur_chan = 0;
                                devpriv->ai_act_scan--;
                        }
 
@@ -784,7 +801,13 @@ static irqreturn_t interrupt_pcl818_ai_mode13_fifo(int irq, void *d)
 
                comedi_buf_put(s->async, (lo >> 4) | (inb(dev->iobase + PCL818_FI_DATAHI) << 4));       // get one sample
 
-               if (s->async->cur_chan == 0) {
+               devpriv->act_chanlist_pos++;
+               if (devpriv->act_chanlist_pos >= devpriv->act_chanlist_len) {
+                       devpriv->act_chanlist_pos = 0;
+               }
+               s->async->cur_chan++;
+               if (s->async->cur_chan >= devpriv->ai_n_chan) {
+                       s->async->cur_chan = 0;
                        devpriv->ai_act_scan--;
                }