if (it->options[0] || it->options[1]) {
if (pcidev->bus->number == it->options[0]
&& PCI_SLOT(pcidev->devfn) == it->options[1]) {
- printk("rtd520: found bus=%d slot=%d\n",
+ DPRINTK("rtd520: found bus=%d slot=%d\n",
it->options[0], it->options[1]);
break; /* found it */
}
static int rtd_detach (
comedi_device *dev)
{
- printk("comedi%d: rtd520: removing (%ld ints, %ld extra ai)\n(int status 0x%x, overrun status 0x%x, fifo status 0x%x)...\n",
+ DPRINTK("comedi%d: rtd520: removing (%ld ints, %ld extra ai)\n(int status 0x%x, overrun status 0x%x, fifo status 0x%x)...\n",
dev->minor, devpriv->intCount, devpriv->aiExtraInt,
0xffff & RtdInterruptStatus (dev),
0xffff & RtdInterruptOverrunStatus (dev),
0xffff & RtdFifoStatus (dev));
if (devpriv) {
- /* Shut down any board ops by reseting it */
+ /* Shut down any board ops by resetting it */
RtdResetBoard (dev);
RtdInterruptMask (dev, 0);
RtdInterruptClearMask (dev,~0);
RtdInterruptClear(dev); /* clears bits set by mask */
- RtdClearCGT (dev);
- RtdAdcClearFifo (dev);
/* release DMA */
{
int n, ii;
int stat;
- /* clear channel gain table */
- /* write channel to multiplexer */
+
+ /* write channel to multiplexer and clear channel gain table */
rtd_load_channelgain_list (dev, 1, &insn->chanspec);
/* set conversion source */
/* check and deal with buffer wrap */
if (s->async->buf_int_ptr >= s->async->data_len) {
s->async->buf_int_ptr = 0;
- comedi_eobuf(dev, s);
+ s->async->events |= COMEDI_CB_EOBUF;
}
/* write into buffer */
*((sampl_t *)((void *)s->async->data + s->async->buf_int_ptr))
/* check and deal with buffer wrap */
if (s->async->buf_int_ptr >= s->async->data_len) {
s->async->buf_int_ptr = 0;
- comedi_eobuf(dev, s);
+ s->async->events |= COMEDI_CB_EOBUF;
}
/* write into buffer */
*((sampl_t *)((void *)s->async->data + s->async->buf_int_ptr))
|| !(dev->attached)) {
return;
}
+
+ /* Check for analog in */
/* Either end if a sequence (about), or time to flush the fifo (sample) */
- /* You can only interrupt on fifo half full if doing DMA */
+ /* Future: process DMA transfer */
if (status & (IRQM_ADC_ABOUT_CNT | IRQM_ADC_SAMPLE_CNT)) {
comedi_subdevice *s = dev->subdevices + 0; /* analog in subdevice */
- /* only read in big chunks */
- if (RtdFifoStatus (dev) & FS_ADC_HEMPTY) {
+
+ /* Check for any ready data */
+ if (RtdFifoStatus (dev) & FS_ADC_HEMPTY) { /* read 1/2 fifo worth */
ai_read_half_fifo (dev, s);
- comedi_bufcheck (dev, s); /* signal something there */
+ /*comedi_bufcheck (dev, s); */
+ s->async->events |= COMEDI_CB_BLOCK; /* signal something there */
+ } else {
+ /* for slow transfers, we should read whatever is there */
+ /*s->async->events |= COMEDI_CB_EOS;*/
}
if (0 == devpriv->aiCount) { /* done! stop! */
- comedi_done (dev, s); /* signal end to comedi */
- goto transferDone;
- }
- if (status & IRQM_ADC_ABOUT_CNT) { /* about counter terminated */
+ RtdInterruptMask (dev, 0); /* mask out ABOUT and SAMPLE */
+ RtdPacerStop (dev); /* Stop PACER */
+ /*comedi_done (dev, s);*/
+ s->async->events |= COMEDI_CB_EOA;/* signal end to comedi */
+ } else if (status & IRQM_ADC_ABOUT_CNT) { /* about cnt terminated */
if (devpriv->aboutWrap) { /* multi-count wraps */
if (devpriv->aiCount < devpriv->aboutWrap) {
RtdAboutStopEnable (dev, 0); /* enable stop */
} else { /* done */
/* TODO: allow multiple interrupt sources */
RtdInterruptMask (dev, 0);/* mask out ABOUT and SAMPLE */
- ai_read_dregs (dev, s);
+ RtdPacerStop (dev); /* Stop PACER */
+ ai_read_dregs (dev, s); /* ready anything in FIFO */
- comedi_done (dev, s); /* signal end to comedi */
+ /*comedi_done (dev, s);*/
+ s->async->events |= COMEDI_CB_EOA;/* signal end to comedi */
}
}
+
+ /* check for fifo over-run */
+ if (s->async->events != 0) { /* signal any events */
+ comedi_event (dev, s, s->async->events);
+ s->async->events = 0;
+ }
}
- /* clear the interrupt */
- RtdInterruptClearMask (dev, status);
- RtdInterruptClear (dev);
- return;
-
- transferDone:
- RtdPacerStop (dev); /* Stop PACER */
- RtdInterruptMask (dev, 0); /* mask out ABOUT and SAMPLE */
+ /* clear the interrupt */
RtdInterruptClearMask (dev, status);
RtdInterruptClear (dev);
}
if (cmd->start_arg != 0) {
cmd->start_arg = 0;
- printk ("rtd520: cmdtest: start_arg not 0\n");
+ DPRINTK ("rtd520: cmdtest: start_arg not 0\n");
err++;
}
if (cmd->scan_begin_src == TRIG_TIMER){
if (cmd->scan_begin_arg < RTD_MAX_SPEED) {
cmd->scan_begin_arg = RTD_MAX_SPEED;
- printk ("rtd520: cmdtest: scan rate greater than max.\n");
+ DPRINTK ("rtd520: cmdtest: scan rate greater than max.\n");
err++;
}
if (cmd->scan_begin_arg > RTD_MIN_SPEED) {
cmd->scan_begin_arg = RTD_MIN_SPEED;
- printk ("rtd520: cmdtest: scan rate lower than min.\n");
+ DPRINTK ("rtd520: cmdtest: scan rate lower than min.\n");
err++;
}
} else {
/* should specify multiple external triggers */
if (cmd->scan_begin_arg > 9) {
cmd->scan_begin_arg = 9;
- printk ("rtd520: cmdtest: scan_begin_arg out of range\n");
+ DPRINTK ("rtd520: cmdtest: scan_begin_arg out of range\n");
err++;
}
}
if (cmd->convert_src==TRIG_TIMER) {
if (cmd->convert_arg < RTD_MAX_SPEED) {
cmd->convert_arg = RTD_MAX_SPEED;
- printk ("rtd520: cmdtest: convert rate greater than max.\n");
+ DPRINTK ("rtd520: cmdtest: convert rate greater than max.\n");
err++;
}
if (cmd->convert_arg > RTD_MIN_SPEED) {
cmd->convert_arg = RTD_MIN_SPEED;
- printk ("rtd520: cmdtest: convert rate lower than min.\n");
+ DPRINTK ("rtd520: cmdtest: convert rate lower than min.\n");
err++;
}
} else {
/* see above */
if (cmd->convert_arg > 9) {
cmd->convert_arg = 9;
- printk ("rtd520: cmdtest: convert_arg out of range\n");
+ DPRINTK ("rtd520: cmdtest: convert_arg out of range\n");
err++;
}
}
/* TRIG_NONE */
if (cmd->stop_arg!=0) {
cmd->stop_arg=0;
- printk ("rtd520: cmdtest: stop_arg not 0\n");
+ DPRINTK ("rtd520: cmdtest: stop_arg not 0\n");
err++;
}
}
if (err) {
- printk ("rtd520: cmdtest error! Some argument compatibility test failed.\n");
+ DPRINTK ("rtd520: cmdtest error! Some argument compatibility test failed.\n");
return 3;
}
}
if (err) {
- printk ("rtd520: cmdtest error! Some timer value was altered.\n");
+ DPRINTK ("rtd520: cmdtest error! Some timer value was altered.\n");
return 4;
}
RtdPacerStop (dev); /* Stop PACER */
/* start configuration */
+ /* load channel list and reset CGT */
rtd_load_channelgain_list (dev, cmd->chanlist_len, cmd->chanlist);
/* setup the common case and override if needed */
if (cmd->chanlist_len > 1) {
- /*printk ("rtd520: Multi channel setup\n");*/
+ /*DPRINTK ("rtd520: Multi channel setup\n");*/
RtdPacerStartSource (dev, 0); /* software triggers pacer */
RtdBurstStartSource (dev, 1); /* PACER triggers burst */
RtdAdcConversionSource (dev, 2); /* BURST triggers ADC */
} else { /* single channel */
- /*printk ("rtd520: single channel setup\n");*/
+ /*DPRINTK ("rtd520: single channel setup\n");*/
RtdPacerStartSource (dev, 0); /* software triggers pacer */
RtdAdcConversionSource (dev, 1); /* PACER triggers ADC */
}
RtdPacerClockSource (dev, 1); /* use INTERNAL 8Mhz clock source */
RtdAdcSampleCounterSource (dev, 1); /* count samples, not scans */
- /* BUG!!! these look like enumerated values, but they are bit fields */
+ /* BUG??? these look like enumerated values, but they are bit fields */
/* First, setup when to stop */
switch(cmd->stop_src){
devpriv->aiCount = n;
if (n <= 0x10000) {
/* Note: stop on underflow. Load with N-1 */
- printk ("rtd520: loading %d into about\n", n - 1);
+ DPRINTK ("rtd520: loading %d into about\n", n - 1);
devpriv->aboutWrap = 0;
RtdAboutCounter (dev, n - 1);
} else { /* multiple counter wraps */
int mm, dd, ii;
- /*printk ("rtd520: multi-wrap count %d = %d x %d \n",
+ /*DPRINTK ("rtd520: multi-wrap count %d = %d x %d \n",
n, cmd->chanlist_len, cmd->stop_arg);*/
/* interrupt on ABOUT wrap, until last wrap */
/* we can run long, aiCount handles the excess */
dd = (n + 0xffff-1) / 0xffff;/* find divisor, round up */
mm = n / dd;
/* dd * mm >= n, mm < 0xffff */
+
/* try to find good divisor */
- for (ii = 0; ((mm*dd) < n) && (ii < 8); ++ii) {
+ for (ii = 0; ((mm*dd) < n) && (ii < 6); ++ii) {
dd++;
mm = n / dd;
}
if ((mm*dd) < n) { /* just run long */
++mm;
+ /* test case: try asking for 3 x 65537 samples */
}
/* dd * mm >= n, mm < 0xffff */
- printk ("rtd520: multi-wrap count %d = (%d) x %d\n",
- mm*dd, mm, dd);
+ DPRINTK ("rtd520: multi-wrap count (%d) %d = (%d) x %d\n",
+ n, mm*dd, mm, dd);
devpriv->aboutWrap = mm;
RtdAboutCounter (dev, mm-1);
RtdAboutStopEnable (dev, 1); /* just interrupt */
break;
default:
- printk ("rtd520: Warning! ignoring stop_src mode %d\n",
+ DPRINTK ("rtd520: Warning! ignoring stop_src mode %d\n",
cmd->stop_src);
}
case TRIG_TIMER: /* periodic scanning */
timer=rtd_ns_to_timer(&cmd->scan_begin_arg,TRIG_ROUND_NEAREST);
/* set PACER clock */
- /*printk ("rtd520: loading %d into pacer\n", timer);*/
+ /*DPRINTK ("rtd520: loading %d into pacer\n", timer);*/
RtdPacerCounter (dev, timer);
break;
break;
default:
- printk ("rtd520: Warning! ignoring scan_begin_src mode %d\n",
+ DPRINTK ("rtd520: Warning! ignoring scan_begin_src mode %d\n",
cmd->scan_begin_src);
}
if (cmd->chanlist_len > 1) { /* only needed for multi-channel */
timer=rtd_ns_to_timer(&cmd->convert_arg,TRIG_ROUND_NEAREST);
/* setup BURST clock */
- /*printk ("rtd520: loading %d into burst\n", timer);*/
+ /*DPRINTK ("rtd520: loading %d into burst\n", timer);*/
RtdBurstCounter (dev, timer);
}
break;
default:
- printk ("rtd520: Warning! ignoring convert_src mode %d\n",
+ DPRINTK ("rtd520: Warning! ignoring convert_src mode %d\n",
cmd->convert_src);
}
/* DEBUG */
if (stat & FS_ADC_EMPTY) { /* 1 -> not empty */
- printk ("rtd520: ai_cmd Warning: fifo didn't seem to clear! FifoStatus=0x%x\n",
+ DPRINTK ("rtd520: ai_cmd Warning: fifo didn't seem to clear! FifoStatus=0x%x\n",
stat);
} else {
- printk ("rtd520: ai_cmd: polling for sample.\n");
+ DPRINTK ("rtd520: ai_cmd: polling for sample.\n");
}
/* trigger conversion */
break;
}
if (ii >= RTD_ADC_TIMEOUT) {
- printk ("rtd520: ai_cmd Error: Never got data in FIFO! FifoStatus=0x%x\n",
+ DPRINTK ("rtd520: ai_cmd Error: Never got data in FIFO! FifoStatus=0x%x\n",
stat);
return -ETIMEDOUT;
}
/* read data */
d = RtdAdcFifoGet (dev); /* get 2s comp value */
- /*printk ("rtd520: Got 0x%x after %d usec\n", d, ii+1);*/
+ /*DPRINTK ("rtd520: Got 0x%x after %d usec\n", d, ii+1);*/
d = d >> 3; /* low 3 bits are marker lines */
/* write into buffer */
} else {
/* interrupt setup */
if (! dev->irq) {
- printk ("rtd520: ERROR! No interrupt available!\n");
+ DPRINTK ("rtd520: ERROR! No interrupt available!\n");
return -ENXIO;
}
- printk("rtd520: using interrupts. (%ld ints, %ld extra ai)\n(int status 0x%x, overrun status 0x%x, fifo status 0x%x)\n",
+ DPRINTK("rtd520: using interrupts. (%ld ints, %ld extra ai)\n(int status 0x%x, overrun status 0x%x, fifo status 0x%x)\n",
devpriv->intCount, devpriv->aiExtraInt,
0xffff & RtdInterruptStatus (dev),
0xffff & RtdInterruptOverrunStatus (dev),
val = data[i] << 3;
}
- printk("comedi: rtd520 DAC chan=%d range=%d writing %d as 0x%x\n",
+ DPRINTK("comedi: rtd520 DAC chan=%d range=%d writing %d as 0x%x\n",
chan, range, data[i], val);
/* a typical programming sequence */
* input lines. */
data[1] = RtdDio0Read (dev);
- /*printk("rtd520:port_0 wrote: 0x%x read: 0x%x\n", s->state, data[1]);*/
+ /*DPRINTK("rtd520:port_0 wrote: 0x%x read: 0x%x\n", s->state, data[1]);*/
return 2;
}
s->io_bits &= ~(1<<chan);
}
- printk("rtd520: port_0_direction=0x%x (1 means out)\n", s->io_bits);
+ DPRINTK("rtd520: port_0_direction=0x%x (1 means out)\n", s->io_bits);
/* TODO support digital match interrupts and strobes */
RtdDioStatusWrite (dev, 0x01); /* make Dio0Ctrl point to direction */
RtdDio0CtrlWrite (dev, s->io_bits); /* set direction 1 means Out */