rt_printk("comedi%d: %s: %s\n", dev->minor, dev->driver->driver_name, s);
}
-void comedi_event(comedi_device *dev, comedi_subdevice *s, unsigned useless)
+void comedi_event(comedi_device *dev, comedi_subdevice *s)
{
comedi_async *async = s->async;
comedi_buf_put(s->async, d);
s->async->events |= COMEDI_CB_EOS;
- comedi_event(dev,s,s->async->events);
+ comedi_event(dev, s);
}
static int subdev_8255_cb(int dir,int port,int data,unsigned long arg)
pci9111_interrupt_clear();
pci9111_ai_cancel (dev, subdevice);
async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA;
- comedi_event (dev, subdevice, async->events);
+ comedi_event (dev, subdevice);
return IRQ_HANDLED;
}
comedi_spin_unlock_irqrestore (&dev->spinlock, irq_flags);
- comedi_event (dev, subdevice, async->events);
+ comedi_event (dev, subdevice);
return IRQ_HANDLED;
}
if (m & devpriv->ai_maskharderr) {
s->async->events|=COMEDI_CB_ERROR|COMEDI_CB_EOA;
pci9118_ai_cancel(dev,s);
- comedi_event(dev,s,s->async->events);
+ comedi_event(dev, s);
return 1;
}
rt_printk("comedi: A/D SAMPL - data dropout: received channel %d, expected %d!\n",sampl & 0x000f, devpriv->chanlist[s->async->cur_chan]);
s->async->events|=COMEDI_CB_ERROR|COMEDI_CB_EOA;
pci9118_ai_cancel(dev,s);
- comedi_event(dev,s,s->async->events);
+ comedi_event(dev, s);
return;
}
}
}
if (s->async->events)
- comedi_event(dev,s,s->async->events);
+ comedi_event(dev, s);
}
/*
comedi_error(dev,"AMCC IRQ - MASTER DMA ABORT!");
s->async->events|=COMEDI_CB_ERROR|COMEDI_CB_EOA;
pci9118_ai_cancel(dev,s);
- comedi_event(dev,s,s->async->events);
+ comedi_event(dev, s);
return;
}
comedi_error(dev,"AMCC IRQ - TARGET DMA ABORT!");
s->async->events|=COMEDI_CB_ERROR|COMEDI_CB_EOA;
pci9118_ai_cancel(dev,s);
- comedi_event(dev,s,s->async->events);
+ comedi_event(dev, s);
return;
}
interrupt_pci9118_ai_mode4_switch(dev);
}
- comedi_event(dev,s,s->async->events);
+ comedi_event(dev, s);
}
/*
rt_printk("comedi%d: A/D FIFO empty (%4x)\n", dev->minor, m);
pci171x_ai_cancel(dev,s);
s->async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR;
- comedi_event(dev,s,s->async->events);
+ comedi_event(dev, s);
return;
}
if (m & Status_FF) {
rt_printk("comedi%d: A/D FIFO Full status (Fatal Error!) (%4x)\n", dev->minor, m);
pci171x_ai_cancel(dev,s);
s->async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR;
- comedi_event(dev,s,s->async->events);
+ comedi_event(dev, s);
return;
}
rt_printk("comedi: A/D data dropout: received data from channel %d, expected %d!\n",(sampl & 0xf000)>>12,(devpriv->act_chanlist[s->async->cur_chan] & 0xf000)>>12);
pci171x_ai_cancel(dev,s);
s->async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR;
- comedi_event(dev,s,s->async->events);
+ comedi_event(dev, s);
return;
}
DPRINTK("%8d %2d %8d~",s->async->buf_int_ptr,s->async->cur_chan,s->async->buf_int_count);
if ((!devpriv->neverending_ai)&&(devpriv->ai_act_scan>=devpriv->ai_scans)) { // all data sampled
pci171x_ai_cancel(dev,s);
s->async->events |= COMEDI_CB_EOA;
- comedi_event(dev,s,s->async->events);
+ comedi_event(dev, s);
return;
}
}
outb(0, dev->iobase + PCI171x_CLRINT); // clear our INT request
DPRINTK("adv_pci1710 EDBG: END: interrupt_pci1710_every_sample(...)\n");
- comedi_event(dev,s,s->async->events);
+ comedi_event(dev, s);
}
/*
dev->minor, (sampl & 0xf000)>>12,(devpriv->act_chanlist[j] & 0xf000)>>12, i, j, devpriv->ai_act_scan, n, turn, sampl);
pci171x_ai_cancel(dev,s);
s->async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR;
- comedi_event(dev,s,s->async->events);
+ comedi_event(dev, s);
return 1;
}
comedi_buf_put( s->async, sampl & 0x0fff );
rt_printk("comedi%d: A/D FIFO not half full! (%4x)\n", dev->minor, m);
pci171x_ai_cancel(dev,s);
s->async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR;
- comedi_event(dev,s,s->async->events);
+ comedi_event(dev, s);
return;
}
if (m & Status_FF) {
rt_printk("comedi%d: A/D FIFO Full status (Fatal Error!) (%4x)\n", dev->minor, m);
pci171x_ai_cancel(dev,s);
s->async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR;
- comedi_event(dev,s,s->async->events);
+ comedi_event(dev, s);
return;
}
if ( devpriv->ai_act_scan>=devpriv->ai_scans ) { /* all data sampled */
pci171x_ai_cancel(dev,s);
s->async->events |= COMEDI_CB_EOA;
- comedi_event(dev,s,s->async->events);
+ comedi_event(dev, s);
return;
}
outb(0, dev->iobase + PCI171x_CLRINT); // clear our INT request
DPRINTK("adv_pci1710 EDBG: END: interrupt_pci1710_half_fifo(...)\n");
- comedi_event(dev,s,s->async->events);
+ comedi_event(dev, s);
}
/*
comedi_spin_unlock_irqrestore(&subpriv->spinlock, flags);
if (event) {
- comedi_event(dev, s, s->async->events);
+ comedi_event(dev, s);
}
return 1;
comedi_spin_unlock_irqrestore(&subpriv->spinlock, flags);
if (oldevents != s->async->events) {
- comedi_event(dev, s, s->async->events);
+ comedi_event(dev, s);
}
return (triggered != 0);
comedi_spin_unlock_irqrestore(&subpriv->spinlock, flags);
if (event) {
- comedi_event(dev, s, s->async->events);
+ comedi_event(dev, s);
}
return 0;
if (handled) {
comedi_buf_put(s->async,0);
s->async->events |= COMEDI_CB_BLOCK | COMEDI_CB_EOS;
- comedi_event(dev,s,s->async->events);
+ comedi_event(dev, s);
}
return IRQ_RETVAL(handled);
}
/* An empty acquisition! */
pci224_ao_stop(dev, s);
s->async->events |= COMEDI_CB_EOA;
- comedi_event(dev, s, s->async->events);
+ comedi_event(dev, s);
} else {
/* Enable interrupts. */
comedi_spin_lock_irqsave(&devpriv->ao_spinlock, flags);
}
}
if (s->async->events) {
- comedi_event(dev, s, s->async->events);
+ comedi_event(dev, s);
}
}
s = dev->write_subdev;
s->async->events = 0;
pci230_handle_ao(dev, s);
- comedi_event(dev, s, s->async->events);
+ comedi_event(dev, s);
s->async->events = 0;
}
s = dev->read_subdev;
s->async->events = 0;
pci230_handle_ai(dev, s);
- comedi_event(dev, s, s->async->events);
+ comedi_event(dev, s);
s->async->events = 0;
}
async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR;
}
- comedi_event(dev, s, async->events);
+ comedi_event(dev, s);
return IRQ_HANDLED;
}
comedi_spin_unlock_irqrestore( &dev->spinlock, flags );
}
- comedi_event(dev, s, async->events);
+ comedi_event(dev, s);
}
// cancel analog input command
if( events & ( COMEDI_CB_EOA | COMEDI_CB_ERROR | COMEDI_CB_OVERFLOW ) )
subd->cancel( dev, subd );
- comedi_event( dev, subd, events );
+ comedi_event(dev, subd);
return events;
}
comedi_buf_put( s->async, 0 );
s->async->events |= COMEDI_CB_BLOCK | COMEDI_CB_EOS;
- comedi_event(dev,s,s->async->events);
+ comedi_event(dev, s);
return IRQ_HANDLED;
}
else
del_timer(&devpriv->timer);
- comedi_event(dev, dev->read_subdev, async->events);
+ comedi_event(dev, dev->read_subdev);
}
static int waveform_attach(comedi_device *dev,comedi_devconfig *it)
comedi_error(dev, "fifo overflow");
}
- comedi_event(dev, s, async->events);
+ comedi_event(dev, s);
}
comedi_error(dev, "DAS1800 FIFO overflow");
das1800_cancel(dev, s);
async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA;
- comedi_event(dev, s, async->events);
+ comedi_event(dev, s);
return;
}
async->events |= COMEDI_CB_EOA;
}
- comedi_event(dev, s, async->events);
+ comedi_event(dev, s);
return;
}
printk("das6402: Got %i samples\n\n",devpriv->das6402_wordsread-diff);
#endif
s->async->events |= COMEDI_CB_EOA;
- comedi_event(dev,s,s->async->events);
+ comedi_event(dev, s);
}
outb(0x01,dev->iobase+8); /* clear only the interrupt flip-flop */
- comedi_event(dev,s,s->async->events);
+ comedi_event(dev, s);
return IRQ_HANDLED;
}
comedi_error(dev, "DAS800 FIFO overflow");
das800_cancel(dev, dev->subdevices + 0);
async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA;
- comedi_event(dev, s, async->events);
+ comedi_event(dev, s);
async->events = 0;
return IRQ_HANDLED;
}
disable_das800(dev); /* diable hardware triggered conversions */
async->events |= COMEDI_CB_EOA;
}
- comedi_event(dev, s, async->events);
+ comedi_event(dev, s);
async->events = 0;
return IRQ_HANDLED;
}
/* comedi_buf_put(s->async,i*100); */
/* s->async->events |= COMEDI_CB_EOA; */
-/* comedi_event(dev,s,s->async->events); */
+/* comedi_event(dev, s); */
return 0;
}
/* flush the buffer */
- comedi_event(dev,s,s->async->events);
+ comedi_event(dev, s);
}
/* reset the interrupt */
s->async->events |= COMEDI_CB_EOA;
}
- comedi_event(dev,s,s->async->events);
+ comedi_event(dev, s);
return IRQ_HANDLED;
}
handled = 1;
}
#endif
- comedi_event(dev, s, s->async->events);
+ comedi_event(dev, s);
/* printk("adcsr=0x%02x dacsr-0x%02x supcsr=0x%02x\n", adcsr, dacsr, supcsr); */
return IRQ_RETVAL(handled);
}
s->async->events |= COMEDI_CB_EOA;
}
- comedi_event(dev,s,s->async->events);
+ comedi_event(dev, s);
return IRQ_HANDLED;
}
ISR_PDEBUG("me4000_ai_isr(): Events = 0x%X\n", s->async->events);
if(s->async->events)
- comedi_event(dev, s, s->async->events);
+ comedi_event(dev, s);
return IRQ_HANDLED;
}
comedi_buf_put(s->async, 0);
s->async->events |= COMEDI_CB_EOS;
- comedi_event(dev,s,s->async->events);
+ comedi_event(dev, s);
return IRQ_HANDLED;
}
comedi_buf_put(s->async, 0);
s->async->events |= COMEDI_CB_EOS;
- comedi_event(dev,s,s->async->events);
+ comedi_event(dev, s);
return IRQ_HANDLED;
}
comedi_error(dev, "caught non-dma interrupt? Aborting.");
a2150_cancel(dev, s);
async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA;
- comedi_event(dev, s, async->events);
+ comedi_event(dev, s);
return IRQ_HANDLED;
}
async->events |= COMEDI_CB_BLOCK;
- comedi_event(dev, s, async->events);
+ comedi_event(dev, s);
/* clear interrupt */
outw(0x00, dev->iobase + DMA_TC_CLEAR_REG);
comedi_buf_put( s->async, inw(dev->iobase+AD_FIFO_REG) );
- comedi_event(dev, s, s->async->events);
+ comedi_event(dev, s);
return IRQ_HANDLED;
}
// clear error interrupt
devpriv->write_byte(0x1, dev->iobase + ADC_CLEAR_REG);
async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA;
- comedi_event(dev, s, async->events);
+ comedi_event(dev, s);
comedi_error(dev, "overrun");
return IRQ_HANDLED;
}
// clear error interrupt
devpriv->write_byte(0x1, dev->iobase + ADC_CLEAR_REG);
async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA;
- comedi_event(dev, s, async->events);
+ comedi_event(dev, s);
comedi_error(dev, "overflow");
return IRQ_HANDLED;
}
}
}
- comedi_event(dev, s, async->events);
+ comedi_event(dev, s);
return IRQ_HANDLED;
}
s->async->events |= COMEDI_CB_EOA;
}
-static void ni_event(comedi_device *dev, comedi_subdevice *s, unsigned events)
+static void ni_event(comedi_device *dev, comedi_subdevice *s)
{
- if(events & (COMEDI_CB_ERROR | COMEDI_CB_OVERFLOW | COMEDI_CB_EOA))
+ if(s->async->events & (COMEDI_CB_ERROR | COMEDI_CB_OVERFLOW | COMEDI_CB_EOA))
{
switch(dev->subdevices - s)
{
break;
}
}
- comedi_event(dev, s, events);
+ comedi_event(dev, s);
}
static void handle_gpct_interrupt(comedi_device *dev, unsigned short counter_index)
ni_tio_handle_interrupt(&devpriv->counter_dev->counters[counter_index], s);
if(s->async->events)
- ni_event(dev, s, s->async->events);
+ ni_event(dev, s);
}
static void ack_a_interrupt(comedi_device *dev, unsigned short a_status)
* so it's a good idea to be careful. */
if(comedi_get_subdevice_runflags(s) & SRF_RUNNING){
s->async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA;
- ni_event(dev, s, s->async->events);
+ ni_event(dev, s);
}
return;
}
if(status & (AI_Overrun_St | AI_Overflow_St))
s->async->events |= COMEDI_CB_OVERFLOW;
- ni_event(dev, s, s->async->events);
+ ni_event(dev, s);
return;
}
ni_handle_eos(dev, s);
}
- ni_event(dev,s,s->async->events);
+ ni_event(dev, s);
#ifdef DEBUG_INTERRUPT
status=devpriv->stc_readw(dev, AI_Status_1_Register);
}
#endif
- ni_event(dev,s,s->async->events);
+ ni_event(dev, s);
}
#ifdef DEBUG_STATUS_A
}
}
-void ni_pcidio_event(comedi_device *dev, comedi_subdevice *s, unsigned events)
+void ni_pcidio_event(comedi_device *dev, comedi_subdevice *s)
{
- if(events & (COMEDI_CB_EOA | COMEDI_CB_ERROR | COMEDI_CB_OVERFLOW))
+ if(s->async->events & (COMEDI_CB_EOA | COMEDI_CB_ERROR | COMEDI_CB_OVERFLOW))
{
ni_pcidio_cancel(dev, s);
}
- comedi_event(dev, s, events);
+ comedi_event(dev, s);
}
static irqreturn_t nidio_interrupt(int irq, void *d PT_REGS_ARG)
}
out:
- ni_pcidio_event(dev, s, async->events);
+ ni_pcidio_event(dev, s);
#if 0
if(!tag){
writeb(0x03,devpriv->mite->daq_io_addr+Master_DMA_And_Interrupt_Control);
s->async->events |= COMEDI_CB_EOA;
}
- comedi_event(dev, s, s->async->events);
+ comedi_event(dev, s);
return IRQ_HANDLED;
}
rt_printk("comedi%d: pcl812: (%s at 0x%lx) A/D cmd IRQ without DRDY!\n", dev->minor, dev->board_name, dev->iobase);
pcl812_ai_cancel(dev,s);
s->async->events |= COMEDI_CB_EOA|COMEDI_CB_ERROR;
- comedi_event(dev,s,s->async->events);
+ comedi_event(dev, s);
return IRQ_HANDLED;
}
}
}
- comedi_event(dev,s,s->async->events);
+ comedi_event(dev, s);
return IRQ_HANDLED;
}
}
}
- comedi_event(dev,s,s->async->events);
+ comedi_event(dev, s);
}
/*
comedi_error (dev, "A/D mode1/3 IRQ without DRDY!");
pcl816_ai_cancel (dev, s);
s->async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR;
- comedi_event(dev, s, s->async->events);
+ comedi_event(dev, s);
return IRQ_HANDLED;
}
pcl816_ai_cancel (dev, s);
s->async->events |= COMEDI_CB_EOA;
}
- comedi_event(dev, s, s->async->events);
+ comedi_event(dev, s);
return IRQ_HANDLED;
}
}
}
- comedi_event(dev,s,s->async->events);
+ comedi_event(dev, s);
}
comedi_error(dev,"A/D mode1/3 IRQ without DRDY!");
pcl818_ai_cancel(dev,s);
s->async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR;
- comedi_event(dev, s, s->async->events);
+ comedi_event(dev, s);
return IRQ_HANDLED;
conv_finish:
rt_printk("comedi: A/D mode1/3 IRQ - channel dropout %x!=%x !\n",(low & 0xf),devpriv->act_chanlist[devpriv->act_chanlist_pos]);
pcl818_ai_cancel(dev,s);
s->async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR;
- comedi_event(dev, s, s->async->events);
+ comedi_event(dev, s);
return IRQ_HANDLED;
}
if (s->async->cur_chan == 0) {
s->async->events |= COMEDI_CB_EOA;
}
}
- comedi_event(dev, s, s->async->events);
+ comedi_event(dev, s);
return IRQ_HANDLED;
}
rt_printk("comedi: A/D mode1/3 DMA - channel dropout %d(card)!=%d(chanlist) at %d !\n",(ptr[bufptr] & 0xf),devpriv->act_chanlist[devpriv->act_chanlist_pos], devpriv->act_chanlist_pos);
pcl818_ai_cancel(dev,s);
s->async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR;
- comedi_event(dev, s, s->async->events);
+ comedi_event(dev, s);
return IRQ_HANDLED;
}
if ( devpriv->ai_act_scan == 0 ) { /* all data sampled */
pcl818_ai_cancel(dev,s);
s->async->events |= COMEDI_CB_EOA;
- comedi_event(dev, s, s->async->events);
+ comedi_event(dev, s);
// printk("done int ai13 dma\n");
return IRQ_HANDLED;
}
}
- if (len>0) comedi_event(dev, s, s->async->events);
+ if (len>0) comedi_event(dev, s);
return IRQ_HANDLED;
}
//rt_printk("I %d dmabuf[i] %d %d\n",i,dmabuf[i],devpriv->dmasamplsize);
pcl818_ai_cancel(dev,s);
s->async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR;
- comedi_event(dev, s, s->async->events);
+ comedi_event(dev, s);
return IRQ_HANDLED;
}
//rt_printk("r %ld ",ofs_dats);
rt_printk("comedi: A/D mode1/3 DMA - channel dropout %d!=%d !\n",(dmabuf[bufptr] & 0xf),devpriv->act_chanlist[devpriv->act_chanlist_pos]);
pcl818_ai_cancel(dev,s);
s->async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR;
- comedi_event(dev, s, s->async->events);
+ comedi_event(dev, s);
return IRQ_HANDLED;
}
if ( devpriv->ai_act_scan == 0 ) { /* all data sampled */
pcl818_ai_cancel(dev,s);
s->async->events |= COMEDI_CB_EOA;
- comedi_event(dev, s, s->async->events);
+ comedi_event(dev, s);
//printk("done int ai13 dma\n");
return IRQ_HANDLED;
}
bufptr--;
bufptr&=(devpriv->dmasamplsize-1);
dmabuf[bufptr]=MAGIC_DMA_WORD;
- comedi_event(dev, s, s->async->events);
+ comedi_event(dev, s);
//outb(0,0x378);
return IRQ_HANDLED;
}
comedi_error(dev,"A/D mode1/3 FIFO overflow!");
pcl818_ai_cancel(dev,s);
s->async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR;
- comedi_event(dev, s, s->async->events);
+ comedi_event(dev, s);
return IRQ_HANDLED;
}
comedi_error(dev,"A/D mode1/3 FIFO interrupt without data!");
pcl818_ai_cancel(dev,s);
s->async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR;
- comedi_event(dev, s, s->async->events);
+ comedi_event(dev, s);
return IRQ_HANDLED;
}
rt_printk("comedi: A/D mode1/3 FIFO - channel dropout %d!=%d !\n",(lo & 0xf),devpriv->act_chanlist[devpriv->act_chanlist_pos]);
pcl818_ai_cancel(dev,s);
s->async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR;
- comedi_event(dev, s, s->async->events);
+ comedi_event(dev, s);
return IRQ_HANDLED;
}
if ( devpriv->ai_act_scan == 0 ) { /* all data sampled */
pcl818_ai_cancel(dev,s);
s->async->events |= COMEDI_CB_EOA;
- comedi_event(dev, s, s->async->events);
+ comedi_event(dev, s);
return IRQ_HANDLED;
}
}
- if (len>0) comedi_event(dev, s, s->async->events);
+ if (len>0) comedi_event(dev, s);
return IRQ_HANDLED;
}
A driver for the relatively new PCM-MIO multifunction board from
Winsystems. This board is a PC-104 based I/O board. It contains
-four subdevices:
+four subdevices:
subdevice 0 - 16 channels of 16-bit AI
subdevice 1 - 8 channels of 16-bit AO
subdevice 2 - first 24 channels of the 48 channel of DIO (with edge-triggered interrupt support)
Some notes:
- Synchronous reads and writes are the only things implemented for AI and AO,
+ Synchronous reads and writes are the only things implemented for AI and AO,
even though the hardware itself can do streaming acquisition, etc. Anyone
want to add asynchronous I/O for AI/AO as a feature? Be my guest...
- Asynchronous I/O for the DIO subdevices *is* implemented, however! They are
- basically edge-triggered interrupts for any configuration of the first
+ Asynchronous I/O for the DIO subdevices *is* implemented, however! They are
+ basically edge-triggered interrupts for any configuration of the first
24 DIO-lines.
Also note that this interrupt support is untested.
A few words about edge-detection IRQ support (commands on DIO):
* To use edge-detection IRQ support for the DIO subdevice, pass the IRQ
- of the board to the comedi_config command. The board IRQ is not jumpered
+ of the board to the comedi_config command. The board IRQ is not jumpered
but rather configured through software, so any IRQ from 1-15 is OK.
-
- * Due to the genericity of the comedi API, you need to create a special
+
+ * Due to the genericity of the comedi API, you need to create a special
comedi_command in order to use edge-triggered interrupts for DIO.
-
- * Use comedi_commands with TRIG_NOW. Your callback will be called each
+
+ * Use comedi_commands with TRIG_NOW. Your callback will be called each
time an edge is detected on the specified DIO line(s), and the data
values will be two sample_t's, which should be concatenated to form
one 32-bit unsigned int. This value is the mask of channels that had
edges detected from your channel list. Note that the bits positions
in the mask correspond to positions in your chanlist when you
specified the command and *not* channel id's!
-
- * To set the polarity of the edge-detection interrupts pass a nonzero value
- for either CR_RANGE or CR_AREF for edge-up polarity, or a zero
+
+ * To set the polarity of the edge-detection interrupts pass a nonzero value
+ for either CR_RANGE or CR_AREF for edge-up polarity, or a zero
value for both CR_RANGE and CR_AREF if you want edge-down polarity.
-
+
Configuration Options:
[0] - I/O port base address
--------------------------------------------------------------
REG_PORTx All R/W Read/Write/Configure IO
REG_INT_PENDING All ReadOnly Quickly see which INT_IDx has int.
- REG_PAGELOCK All WriteOnly Select a page
+ REG_PAGELOCK All WriteOnly Select a page
REG_POLx Pg. 1 only WriteOnly Select edge-detection polarity
REG_ENABx Pg. 2 only WriteOnly Enable/Disable edge-detect. int.
REG_INT_IDx Pg. 3 only R/W See which ports/bits have ints.
#define REG_PAGELOCK 0x7 /* page selector register, upper 2 bits select a page
and bits 0-5 are used to 'lock down' a particular
port above to make it readonly. */
-#define REG_POL0 0x8
+#define REG_POL0 0x8
#define REG_POL1 0x9
#define REG_POL2 0xA
-#define REG_ENAB0 0x8
+#define REG_ENAB0 0x8
#define REG_ENAB1 0x9
#define REG_ENAB2 0xA
#define REG_INT_ID0 0x8
static const comedi_lrange ranges_ao =
{ 6, { RANGE(0.,5.), RANGE(0.,10.) , RANGE(-5.,5.), RANGE(-10.,10.), RANGE(-2.5, 2.5), RANGE(-2.5, 7.5) } };
-static const pcmmio_board pcmmio_boards[] =
+static const pcmmio_board pcmmio_boards[] =
{
{
name: "pcmmio",
dio_num_asics: 1,
dio_num_ports: 6,
- total_iosize: 32,
+ total_iosize: 32,
ai_bits: 16,
ao_bits: 16,
n_ai_chans: 16,
#define thisboard ((const pcmmio_board *)dev->board_ptr)
/* this structure is for data unique to this subdevice. */
-typedef struct
+typedef struct
{
-
+
union {
/* for DIO: mapping of halfwords (bytes) in port/chanarray to iobase */
unsigned long iobases[PORTS_PER_SUBDEV];
-
+
/* for AI/AO */
unsigned long iobase;
};
union {
struct {
-
+
/* The below is only used for intr subdevices */
struct {
int asic; /* if non-negative, this subdev has an interrupt asic */
- int first_chan; /* if nonnegative, the first channel id for
+ int first_chan; /* if nonnegative, the first channel id for
interrupts. */
int num_asic_chans; /* the number of asic channels in this subdev
that have interrutps */
several hardware drivers keep similar information in this structure,
feel free to suggest moving the variable to the comedi_device struct. */
typedef struct
-{
+{
/* stuff for DIO */
- struct
+ struct
{
unsigned char pagelock; /* current page and lock*/
unsigned char pol [NUM_PAGED_REGS]; /* shadow of POLx registers */
unsigned long iobase;
unsigned int irq;
spinlock_t spinlock;
- } asics[MAX_ASICS];
+ } asics[MAX_ASICS];
pcmmio_subdev_private *sprivs;
} pcmmio_private;
static int pcmmio_attach(comedi_device *dev, comedi_devconfig *it);
static int pcmmio_detach(comedi_device *dev);
-static comedi_driver driver =
+static comedi_driver driver =
{
driver_name: "pcmmio",
module: THIS_MODULE,
irq[0] = it->options[1];
printk("comedi%d: %s: io: %lx ", dev->minor, driver.driver_name, iobase);
-
+
dev->iobase = iobase;
-
- if ( !iobase || !request_region(iobase,
- thisboard->total_iosize,
+
+ if ( !iobase || !request_region(iobase,
+ thisboard->total_iosize,
driver.driver_name) ) {
printk("I/O port conflict\n");
return -EIO;
}
-
+
/*
* Initialize dev->board_name. Note that we can use the "thisboard"
* macro now, since we just initialized it in the last line.
for (asic = 0; asic < MAX_ASICS; ++asic) {
devpriv->asics[asic].num = asic;
devpriv->asics[asic].iobase = dev->iobase + 16 + asic*ASIC_IOSIZE;
- devpriv->asics[asic].irq = 0; /* this gets actually set at the end of
- this function when we
+ devpriv->asics[asic].irq = 0; /* this gets actually set at the end of
+ this function when we
comedi_request_irqs */
spin_lock_init(&devpriv->asics[asic].spinlock);
}
-
- chans_left = CHANS_PER_ASIC * thisboard->dio_num_asics;
+
+ chans_left = CHANS_PER_ASIC * thisboard->dio_num_asics;
n_dio_subdevs = CALC_N_DIO_SUBDEVS(chans_left);
n_subdevs = n_dio_subdevs + 2;
devpriv->sprivs = (pcmmio_subdev_private *)kmalloc(sizeof(pcmmio_subdev_private) * n_subdevs, GFP_KERNEL);
}
memset(dev->subdevices, 0, sizeof(*dev->subdevices) * n_subdevs);
-
+
/* First, AI */
sdev_no = 0;
s = dev->subdevices + sdev_no;
outb(0, subpriv->iobase + 3);
outb(0, subpriv->iobase+4 + 3);
- ++sdev_no;
+ ++sdev_no;
port = 0;
- asic = 0;
+ asic = 0;
for (; sdev_no < (int)dev->n_subdevices; ++sdev_no)
- {
+ {
int byte_no;
s = dev->subdevices + sdev_no;
s->private = devpriv->sprivs + sdev_no;
s->maxdata = 1;
- s->range_table = &range_digital;
+ s->range_table = &range_digital;
s->subdev_flags = SDF_READABLE|SDF_WRITABLE;
s->type = COMEDI_SUBD_DIO;
s->insn_bits = pcmmio_dio_insn_bits;
subpriv->dio.intr.asic_chan = -1;
subpriv->dio.intr.num_asic_chans = -1;
subpriv->dio.intr.active = 0;
- s->len_chanlist = 1;
+ s->len_chanlist = 1;
- /* save the ioport address for each 'port' of 8 channels in the
- subdevice */
+ /* save the ioport address for each 'port' of 8 channels in the
+ subdevice */
for (byte_no = 0; byte_no < PORTS_PER_SUBDEV; ++byte_no, ++port) {
if (port >= PORTS_PER_ASIC) {
port = 0;
s->cancel = pcmmio_cancel;
s->do_cmd = pcmmio_cmd;
s->do_cmdtest = pcmmio_cmdtest;
- s->len_chanlist = subpriv->dio.intr.num_asic_chans;
+ s->len_chanlist = subpriv->dio.intr.num_asic_chans;
}
thisasic_chanct += CHANS_PER_PORT;
}
asic = 0; /* reset the asic to our first asic, to do intr subdevs */
port = 0;
}
-
+
}
init_asics(dev); /* clear out all the registers, basically */
int i;
/* unroll the allocated irqs.. */
for (i = asic-1; i >= 0; --i) {
- comedi_free_irq(irq[i], dev);
+ comedi_free_irq(irq[i], dev);
devpriv->asics[i].irq = irq[i] = 0;
}
irq[asic] = 0;
}
devpriv->asics[asic].irq = irq[asic];
}
-
- dev->irq = irq[0]; /* grr.. wish comedi dev struct supported multiple
+
+ dev->irq = irq[0]; /* grr.. wish comedi dev struct supported multiple
irqs.. */
if (irq[0]) {
printk("irq: %u ", irq[0]);
- if (irq[1] && thisboard->dio_num_asics == 2)
+ if (irq[1] && thisboard->dio_num_asics == 2)
printk("second ASIC irq: %u ", irq[1]);
} else {
printk("(IRQ mode disabled) ");
}
printk("attached\n");
-
+
return 1;
}
/*
* _detach is called to deconfigure a device. It should deallocate
- * resources.
+ * resources.
* This function is also called when _attach() fails, so it should be
* careful not to release resources that were not necessarily
* allocated by _attach(). dev->private and dev->subdevices are
release_region(dev->iobase, thisboard->total_iosize);
for (i = 0; i < MAX_ASICS; ++i) {
- if (devpriv && devpriv->asics[i].irq)
+ if (devpriv && devpriv->asics[i].irq)
comedi_free_irq(devpriv->asics[i].irq, dev);
}
-
+
if (devpriv && devpriv->sprivs)
kfree(devpriv->sprivs);
if (insn->n != 2) return -EINVAL;
/* NOTE:
- reading a 0 means this channel was high
+ reading a 0 means this channel was high
writine a 0 sets the channel high
- reading a 1 means this channel was low
+ reading a 1 means this channel was low
writing a 1 means set this channel low
Therefore everything is always inverted. */
for (byte_no = 0; byte_no < s->n_chan/CHANS_PER_PORT; ++byte_no) {
/* address of 8-bit port */
- unsigned long ioaddr = subpriv->iobases[byte_no],
+ unsigned long ioaddr = subpriv->iobases[byte_no],
/* bit offset of port in 32-bit doubleword */
- offset = byte_no * 8;
+ offset = byte_no * 8;
/* this 8-bit port's data */
- unsigned char byte = 0,
+ unsigned char byte = 0,
/* The write mask for this port (if any) */
- write_mask_byte = (data[0] >> offset) & 0xff,
+ write_mask_byte = (data[0] >> offset) & 0xff,
/* The data byte for this port */
data_byte = (data[1] >> offset) & 0xff;
printk("byte %d wmb %02x db %02x offset %02d io %04x, data_in %02x ", byte_no, (unsigned)write_mask_byte, (unsigned)data_byte, offset, ioaddr, (unsigned)byte);
#endif
- if ( write_mask_byte ) {
+ if ( write_mask_byte ) {
/* this byte has some write_bits -- so set the output lines */
byte &= ~write_mask_byte; /* clear bits for write mask */
byte |= ~data_byte & write_mask_byte; /* set to inverted data_byte */
printk("data_out_byte %02x\n", (unsigned)byte);
#endif
/* save the digital input lines for this byte.. */
- s->state |= ((unsigned int)byte) << offset;
+ s->state |= ((unsigned int)byte) << offset;
}
/* now return the DIO lines to data[1] - note they came inverted! */
- data[1] = ~s->state;
+ data[1] = ~s->state;
#ifdef DAMMIT_ITS_BROKEN
/* DEBUG */
printk("s->state %08x data_out %08x\n", s->state, data[1]);
#endif
-
+
return 2;
}
/* Compute ioaddr for this channel */
ioaddr = subpriv->iobases[byte_no];
-
+
/* NOTE:
- writing a 0 an IO channel's bit sets the channel to INPUT
+ writing a 0 an IO channel's bit sets the channel to INPUT
and pulls the line high as well
-
+
writing a 1 to an IO channel's bit pulls the line low
- All channels are implicitly always in OUTPUT mode -- but when
+ All channels are implicitly always in OUTPUT mode -- but when
they are high they can be considered to be in INPUT mode..
- Thus, we only force channels low if the config request was INPUT,
+ Thus, we only force channels low if the config request was INPUT,
otherwise we do nothing to the hardware. */
switch(data[0])
{
case INSN_CONFIG_DIO_OUTPUT:
- /* save to io_bits -- don't actually do anything since
+ /* save to io_bits -- don't actually do anything since
all input channels are also output channels... */
s->io_bits |= 1<<chan;
break;
byte = inb(ioaddr);
byte &= ~(1<<bit_no); /**< set input channel to '0' */
- /* write out byte -- this is the only time we actually affect the
- hardware as all channels are implicitly output -- but input
+ /* write out byte -- this is the only time we actually affect the
+ hardware as all channels are implicitly output -- but input
channels are set to float-high */
outb(byte, ioaddr);
-
+
/* save to io_bits */
s->io_bits &= ~(1<<chan);
break;
default:
return -EINVAL;
break;
- }
+ }
- return insn->n;
+ return insn->n;
}
-static void init_asics(comedi_device *dev) /* sets up an
+static void init_asics(comedi_device *dev) /* sets up an
ASIC chip to defaults */
{
int asic;
-
+
for (asic = 0; asic < thisboard->dio_num_asics; ++asic)
{
int port, page;
switch_page(dev, asic, 0); /* switch back to page 0 */
/* first, clear all the DIO port bits */
- for (port = 0; port < PORTS_PER_ASIC; ++port)
+ for (port = 0; port < PORTS_PER_ASIC; ++port)
outb(0, baseaddr + REG_PORT0 + port);
/* Next, clear all the paged registers for each page */
/* END DEBUG */
switch_page(dev, asic, 0); /* switch back to default page 0 */
-
+
}
}
devpriv->asics[asic].pagelock |= page<<REG_PAGE_BITOFFSET;
/* now write out the shadow register */
- outb(devpriv->asics[asic].pagelock,
+ outb(devpriv->asics[asic].pagelock,
devpriv->asics[asic].iobase + REG_PAGELOCK);
}
if (asic < 0 || asic >= thisboard->dio_num_asics) return; /* paranoia */
if (port < 0 || port >= PORTS_PER_ASIC) return; /* more paranoia */
- devpriv->asics[asic].pagelock |= 0x1<<port;
+ devpriv->asics[asic].pagelock |= 0x1<<port;
/* now write out the shadow register */
outb(devpriv->asics[asic].pagelock, devpriv->asics[asic].iobase + REG_PAGELOCK);
return;
{
if (asic < 0 || asic >= thisboard->dio_num_asics) return; /* paranoia */
if (port < 0 || port >= PORTS_PER_ASIC) return; /* more paranoia */
- devpriv->asics[asic].pagelock &= ~(0x1<<port) | REG_LOCK_MASK;
+ devpriv->asics[asic].pagelock &= ~(0x1<<port) | REG_LOCK_MASK;
/* now write out the shadow register */
outb(devpriv->asics[asic].pagelock, devpriv->asics[asic].iobase + REG_PAGELOCK);
(void)unlock_port(dev, asic, port); /* not reached, suppress compiler warnings*/
{
int asic, got1 = 0;
comedi_device *dev = (comedi_device *)d;
-
+
for (asic = 0; asic < MAX_ASICS; ++asic) {
if (irq == devpriv->asics[asic].irq) {
- unsigned long flags;
+ unsigned long flags;
unsigned triggered = 0;
unsigned long iobase = devpriv->asics[asic].iobase;
/* it is an interrupt for ASIC #asic */
unsigned char io_lines_with_edges = 0;
switch_page(dev, asic, PAGE_INT_ID);
io_lines_with_edges = inb(iobase + REG_INT_ID0 + port);
-
- if (io_lines_with_edges)
+
+ if (io_lines_with_edges)
/* clear pending interrupt */
outb(0, iobase + REG_INT_ID0 + port);
comedi_spin_unlock_irqrestore(&devpriv->asics[asic].spinlock, flags);
- if (triggered) {
+ if (triggered) {
comedi_subdevice *s;
/* TODO here: dispatch io lines to subdevs with commands.. */
printk("PCMMIO DEBUG: got edge detect interrupt %d asic %d which_chans: %06x\n", irq, asic, triggered);
if (subpriv->dio.intr.asic == asic) { /* this is an interrupt subdev, and it matches this asic! */
unsigned long flags;
unsigned oldevents;
-
+
comedi_spin_lock_irqsave(&subpriv->dio.intr.spinlock, flags);
-
+
oldevents = s->async->events;
if (subpriv->dio.intr.active) {
if (mytrig & subpriv->dio.intr.enabled_mask) {
lsampl_t val = 0;
unsigned int n, ch, len;
-
+
len = s->async->cmd.chanlist_len;
for (n = 0; n < len; n++) {
ch = CR_CHAN(s->async->cmd.chanlist[n]);
} else {
/* Overflow! Stop acquisition!! */
/* TODO: STOP_ACQUISITION_CALL_HERE!! */
- pcmmio_stop_intr(dev, s);
+ pcmmio_stop_intr(dev, s);
}
-
+
/* Check for end of acquisition. */
if (!subpriv->dio.intr.continuous) {
/* stop_src == TRIG_COUNT */
if (subpriv->dio.intr.stop_count == 0) {
s->async->events |= COMEDI_CB_EOA;
/* TODO: STOP_ACQUISITION_CALL_HERE!! */
- pcmmio_stop_intr(dev, s);
+ pcmmio_stop_intr(dev, s);
}
}
}
}
comedi_spin_unlock_irqrestore(&subpriv->dio.intr.spinlock, flags);
-
+
if (oldevents != s->async->events) {
- comedi_event(dev, s, s->async->events);
+ comedi_event(dev, s);
}
}
-
+
}
}
static void pcmmio_stop_intr(comedi_device *dev, comedi_subdevice *s)
{
int nports, firstport, asic, port;
-
+
if ( (asic = subpriv->dio.intr.asic) < 0 ) return; /* not an interrupt subdev */
-
+
subpriv->dio.intr.enabled_mask = 0;
subpriv->dio.intr.active = 0;
s->async->inttrig = 0;
} else {
unsigned bits = 0, pol_bits = 0, n;
int nports, firstport, asic, port;
- comedi_cmd *cmd = &s->async->cmd;
-
- if ( (asic = subpriv->dio.intr.asic) < 0 ) return 1; /* not an interrupt
+ comedi_cmd *cmd = &s->async->cmd;
+
+ if ( (asic = subpriv->dio.intr.asic) < 0 ) return 1; /* not an interrupt
subdev */
subpriv->dio.intr.enabled_mask = 0;
subpriv->dio.intr.active = 1;
if (cmd->chanlist) {
for (n = 0; n < cmd->chanlist_len; n++) {
bits |= (1U << CR_CHAN(cmd->chanlist[n]));
- pol_bits |=
+ pol_bits |=
(CR_AREF(cmd->chanlist[n]) || CR_RANGE(cmd->chanlist[n]) ? 1U : 0U)
<< CR_CHAN(cmd->chanlist[n]);
}
/* set resource enable register to enable IRQ operation */
outb(1<<4, dev->iobase+3);
/* set bits 0-3 of b to the irq number from 0-15 */
- b = dev->irq & ((1<<4)-1);
+ b = dev->irq & ((1<<4)-1);
outb(b, dev->iobase+2);
/* done, we told the board what irq to use */
}
switch_page(dev, asic, PAGE_ENAB);
for (port = firstport; port < firstport+nports; ++port) {
- unsigned enab = bits >> (subpriv->dio.intr.first_chan + (port-firstport)*8) & 0xff,
+ unsigned enab = bits >> (subpriv->dio.intr.first_chan + (port-firstport)*8) & 0xff,
pol = pol_bits >> (subpriv->dio.intr.first_chan + (port-firstport)*8) & 0xff ;
/* set enab intrs for this subdev.. */
outb(enab, devpriv->asics[asic].iobase + REG_ENAB0 + port);
if (subpriv->dio.intr.active) pcmmio_stop_intr(dev, s);
comedi_spin_unlock_irqrestore(&subpriv->dio.intr.spinlock, flags);
- return 0;
+ return 0;
}
/*
comedi_spin_unlock_irqrestore(&subpriv->dio.intr.spinlock, flags);
if (event) {
- comedi_event(dev, s, s->async->events);
+ comedi_event(dev, s);
}
return 1;
comedi_spin_unlock_irqrestore(&subpriv->dio.intr.spinlock, flags);
if (event) {
- comedi_event(dev, s, s->async->events);
+ comedi_event(dev, s);
}
return 0;
if (!cmd->convert_src || tmp != cmd->convert_src) err++;
tmp = cmd->scan_end_src;
- cmd->scan_end_src &= TRIG_COUNT;
+ cmd->scan_end_src &= TRIG_COUNT;
if (!cmd->scan_end_src || tmp != cmd->scan_end_src) err++;
tmp = cmd->stop_src;
{
int n;
unsigned long iobase = subpriv->iobase;
-
- /*
+
+ /*
1. write the CMD byte (to BASE+2)
2. read junk lo byte (BASE+0)
3. read junk hi byte (BASE+1)
5. read valid lo byte(BASE+0)
6. read valid hi byte(BASE+1)
- Additionally note that the BASE += 4 if the channel >= 8
+ Additionally note that the BASE += 4 if the channel >= 8
*/
-
+
/* convert n samples */
for(n = 0; n < insn->n; n++) {
unsigned chan = CR_CHAN(insn->chanspec), range = CR_RANGE(insn->chanspec), aref = CR_AREF(insn->chanspec);
unsigned char command_byte = 0;
unsigned iooffset = 0;
- sampl_t sample, adc_adjust = 0;
-
+ sampl_t sample, adc_adjust = 0;
+
if (chan > 7) chan -= 8, iooffset = 4; /* use the second dword for channels > 7 */
-
+
if (aref != AREF_DIFF) {
aref = AREF_GROUND;
- command_byte |= 1<<7; /* set bit 7 to indicate single-ended */
+ command_byte |= 1<<7; /* set bit 7 to indicate single-ended */
}
if (range < 2) adc_adjust = 0x8000; /* bipolar ranges (-5,5 .. -10,10 need to be adjusted -- that is.. they need to wrap around by adding 0x8000 */
if (chan % 2) {
command_byte |= 1<<6; /* odd-numbered channels have bit 6 set */
}
-
+
/* select the channel, bits 4-5 == chan/2 */
command_byte |= ((chan/2) & 0x3)<<4;
-
+
/* set the range, bits 2-3 */
command_byte |= (range & 0x3) << 2;
/* need to do this twice to make sure mux settled */
outb(command_byte, iobase + iooffset + 2); /* chan/range/aref select */
-
+
adc_wait_ready(iobase + iooffset); /* wait for the adc to say it finised the conversion */
-
+
outb(command_byte, iobase + iooffset + 2); /* select the chan/range/aref AGAIN */
adc_wait_ready(iobase + iooffset);
unsigned long retry = 100000L;
/* This may seem like an absurd way to handle waiting and violates the
- "no busy waiting" policy. The fact is that the hardware is
- normally so fast that we usually only need one time through the loop
- anyway. The longer timeout is for rare occasions and for detecting
+ "no busy waiting" policy. The fact is that the hardware is
+ normally so fast that we usually only need one time through the loop
+ anyway. The longer timeout is for rare occasions and for detecting
non-existant hardware. */
-
+
while(retry--)
{
if (inb(iobase+3) & 0x80)
return 0;
-
+
}
return 1;
}
{
int n;
unsigned iobase = subpriv->iobase, iooffset = 0;
-
+
for(n = 0; n < insn->n; n++) {
unsigned chan = CR_CHAN(insn->chanspec), range = CR_RANGE(insn->chanspec);
if (chan < s->n_chan) {
unsigned char command_byte = 0, range_byte = range&((1<<4)-1);
if (chan >= 4) chan -=4, iooffset += 4;
/* set the range.. */
- outb(range_byte, iobase+iooffset+0);
+ outb(range_byte, iobase+iooffset+0);
outb(0, iobase+iooffset+1);
/* tell it to begin */
command_byte = (chan << 1) | 0x60;
outb(command_byte, iobase+iooffset+2);
-
+
wait_dac_ready(iobase+iooffset);
outb(data[n] & 0xff, iobase+iooffset+0); /* low order byte */
outb((data[n]>>8) & 0xff, iobase+iooffset+1); /* high order byte */
command_byte = 0x70 | (chan<<1); /* set bit 4 of command byte to indicate data is loaded and trigger conversion */
/* trigger converion */
- outb(command_byte, iobase+iooffset+2);
+ outb(command_byte, iobase+iooffset+2);
wait_dac_ready(iobase+iooffset);
-
+
subpriv->ao.shadow_samples[chan] = data[n]; /* save to shadow register for ao_rinsn */
}
}
comedi_spin_unlock_irqrestore(&subpriv->intr.spinlock, flags);
if (oldevents != s->async->events) {
- comedi_event(dev, s, s->async->events);
+ comedi_event(dev, s);
}
}
comedi_spin_unlock_irqrestore(&subpriv->intr.spinlock, flags);
if (event) {
- comedi_event(dev, s, s->async->events);
+ comedi_event(dev, s);
}
return 1;
comedi_spin_unlock_irqrestore(&subpriv->intr.spinlock, flags);
if (event) {
- comedi_event(dev, s, s->async->events);
+ comedi_event(dev, s);
}
return 0;
DPRINTK("rtd520: Samples Done (DMA).\n");
goto transferDone;
}
- comedi_event (dev, s, s->async->events);
+ comedi_event (dev, s);
} else {
/*DPRINTK ("rtd520: No DMA ready: istatus %x\n", istatus);*/
}
(fifoStatus ^ 0x6666) & 0x7777); /* should be all 0s */
goto transferDone;
}
- comedi_event (dev, s, s->async->events);
+ comedi_event (dev, s);
} else if (devpriv->transCount > 0) { /* read often */
/*DPRINTK("rtd520: Sample int, reading %d fifo_status 0x%x\n",
devpriv->transCount, (fifoStatus ^ 0x6666) & 0x7777);*/
(fifoStatus ^ 0x6666) & 0x7777);
goto transferDone;
}
- comedi_event (dev, s, s->async->events);
+ comedi_event (dev, s);
}
} else { /* wait for 1/2 FIFO (old)*/
DPRINTK("rtd520: Sample int. Wait for 1/2. fifo_status 0x%x\n",
}
s->async->events |= COMEDI_CB_EOA;/* signal end to comedi */
- comedi_event (dev, s, s->async->events);
+ comedi_event (dev, s);
/* clear the interrupt */
status = RtdInterruptStatus (dev);
// tell comedi that data is there
DEBUG("s626_irq_handler: events %d\n",s->async->events);
- comedi_event(dev, s, s->async->events);
+ comedi_event(dev, s);
break;
case IRQ_GPIO3: //check dio and conter interrupt
s->async->events |= COMEDI_CB_EOA;
s->async->events |= COMEDI_CB_ERROR;
comedi_event(this_usbduxsub->comedidev,
- s,
- s->async->events);
+ s);
// stop the transfer w/o unlink
usbdux_ai_stop(this_usbduxsub,0);
}
s->async->events |= COMEDI_CB_EOA;
s->async->events |= COMEDI_CB_ERROR;
comedi_event(this_usbduxsub->comedidev,
- s,
- s->async->events);
+ s);
// don't do an unlink here
usbdux_ai_stop(this_usbduxsub,0);
}
s->async->events |= COMEDI_CB_EOA;
s->async->events |= COMEDI_CB_ERROR;
comedi_event(this_usbduxsub->comedidev,
- s,
- s->async->events);
+ s);
// don't do an unlink here
usbdux_ai_stop(this_usbduxsub,0);
return;
// say comedi that the acquistion is over
s->async->events |= COMEDI_CB_EOA;
comedi_event(this_usbduxsub->comedidev,
- s,
- s->async->events);
+ s);
return;
}
}
}
// tell comedi that data is there
comedi_event(this_usbduxsub->comedidev,
- s,
- s->async->events);
+ s);
}
if (this_usbduxsub->ao_cmd_running) {
s->async->events |= COMEDI_CB_EOA;
comedi_event(this_usbduxsub->comedidev,
- s,
- s->async->events);
+ s);
usbdux_ao_stop(this_usbduxsub,0);
}
return;
s->async->events |= COMEDI_CB_ERROR;
s->async->events |= COMEDI_CB_EOA;
comedi_event(this_usbduxsub->comedidev,
- s,
- s->async->events);
+ s);
// we do an unlink if we are in the high speed mode
usbdux_ao_stop(this_usbduxsub,0);
}
0);
s->async->events |= COMEDI_CB_EOA;
comedi_event(this_usbduxsub->comedidev,
- s,
- s->async->events);
+ s);
// no resubmit of the urb
return;
}
// transmit data to comedi
s->async->events |= COMEDI_CB_BLOCK;
comedi_event(this_usbduxsub->comedidev,
- s,
- s->async->events);
+ s);
}
}
urb->transfer_buffer_length = SIZEOUTBUF;
s->async->events |= COMEDI_CB_EOA;
s->async->events |= COMEDI_CB_ERROR;
comedi_event(this_usbduxsub->comedidev,
- s,
- s->async->events);
+ s);
// don't do an unlink here
usbdux_ao_stop(this_usbduxsub,0);
}
CHANNELLISTEP),
this_usbduxfastsub->dux_commands,
SIZEOFDUXBUFFER,
- &nsent,
+ &nsent,
10000);
if (result<0) {
printk("comedi%d: could not transmit dux_commands to the usb-device, err=%d\n",
#endif
- this_usbduxfastsub->ai_cmd_running=0;
+ this_usbduxfastsub->ai_cmd_running=0;
if (do_unlink) {
// stop aquistion
// unlink
res=usbduxfast_ai_stop(this_usbduxfastsub,1);
up(&this_usbduxfastsub->sem);
-
+
return res;
}
// tell this comedi
s->async->events |= COMEDI_CB_EOA;
s->async->events |= COMEDI_CB_ERROR;
- comedi_event(this_usbduxfastsub->comedidev,
- s,
- s->async->events);
+ comedi_event(this_usbduxfastsub->comedidev,
+ s);
// stop the transfer w/o unlink
usbduxfast_ai_stop(this_usbduxfastsub,0);
return;
urb->status);
s->async->events |= COMEDI_CB_EOA;
s->async->events |= COMEDI_CB_ERROR;
- comedi_event(this_usbduxfastsub->comedidev,
- s,
- s->async->events);
+ comedi_event(this_usbduxfastsub->comedidev,
+ s);
usbduxfast_ai_stop(this_usbduxfastsub,0);
return;
}
0);
// say comedi that the acquistion is over
s->async->events |= COMEDI_CB_EOA;
- comedi_event(this_usbduxfastsub->comedidev,
- s,
- s->async->events);
+ comedi_event(this_usbduxfastsub->comedidev,
+ s);
return;
}
this_usbduxfastsub->ai_sample_count-=n;
}
-
+
// write the full buffer to comedi
cfc_write_array_to_buffer(s,
urb->transfer_buffer,
urb->actual_length);
-
+
// tell comedi that data is there
- comedi_event(this_usbduxfastsub->comedidev,
- s,
- s->async->events);
+ comedi_event(this_usbduxfastsub->comedidev,
+ s);
} else {
// ignore this packet
err);
s->async->events |= COMEDI_CB_EOA;
s->async->events |= COMEDI_CB_ERROR;
- comedi_event(this_usbduxfastsub->comedidev,
- s,
- s->async->events);
+ comedi_event(this_usbduxfastsub->comedidev,
+ s);
usbduxfast_ai_stop(this_usbduxfastsub,0);
}
}
if (usbduxfastsub->probed) {
// 7f92 to zero
- local_transfer_buffer[0]=0;
+ local_transfer_buffer[0]=0;
errcode=USB_CONTROL_MSG
(usbduxfastsub->usbdev,
// create a pipe for a control transfer
usb_sndctrlpipe(usbduxfastsub->usbdev,0),
// bRequest, "Firmware"
- USBDUXFASTSUB_FIRMWARE,
+ USBDUXFASTSUB_FIRMWARE,
// bmRequestType
- VENDOR_DIR_OUT,
+ VENDOR_DIR_OUT,
// Value
- USBDUXFASTSUB_CPUCS,
+ USBDUXFASTSUB_CPUCS,
// Index
0x0000,
// address of the transfer buffer
// Length
1,
// Timeout
- EZTIMEOUT
+ EZTIMEOUT
);
if (errcode<0) {
printk("comedi_: usbduxfast_: control msg failed (start)\n");
unsigned char local_transfer_buffer[16];
if (usbduxfastsub->probed) {
// 7f92 to one
- local_transfer_buffer[0]=1;
+ local_transfer_buffer[0]=1;
errcode=USB_CONTROL_MSG
(usbduxfastsub->usbdev,
usb_sndctrlpipe(usbduxfastsub->usbdev,0),
// bRequest, "Firmware"
- USBDUXFASTSUB_FIRMWARE,
+ USBDUXFASTSUB_FIRMWARE,
// bmRequestType
VENDOR_DIR_OUT,
// Value
USBDUXFASTSUB_CPUCS,
// Index
- 0x0000,
+ 0x0000,
local_transfer_buffer,
// Length
1,
// Timeout
- EZTIMEOUT
+ EZTIMEOUT
);
if (errcode<0) {
printk("comedi_: usbduxfast: control msg failed (stop)\n");
}
return 0;
}
-
+
-int firmwareUpload(usbduxfastsub_t* usbduxfastsub,
+int firmwareUpload(usbduxfastsub_t* usbduxfastsub,
unsigned char* firmwareBinary,
int sizeFirmware) {
int ret;
}
return 0;
}
-
+
int usbduxfastsub_submit_InURBs(usbduxfastsub_t* usbduxfastsub) {
-static int usbduxfast_ai_cmdtest(comedi_device *dev,
- comedi_subdevice *s,
+static int usbduxfast_ai_cmdtest(comedi_device *dev,
+ comedi_subdevice *s,
comedi_cmd *cmd)
{
int err=0, stop_mask=0;
}
steps=0;
if(cmd->scan_begin_src == TRIG_TIMER) {
- printk("comedi%d: usbduxfast: scan_begin_src==TRIG_TIMER not valid.\n",
+ printk("comedi%d: usbduxfast: scan_begin_src==TRIG_TIMER not valid.\n",
dev->minor);
up(&this_usbduxfastsub->sem);
return -EINVAL;
steps=(cmd->convert_arg*30)/1000;
}
if ((steps<MIN_SAMPLING_PERIOD)&&(cmd->chanlist_len!=1)) {
- printk("comedi%d: usbduxfast: ai_cmd: steps=%ld, scan_begin_arg=%d. Not properly tested by cmdtest?\n",
- dev->minor,
+ printk("comedi%d: usbduxfast: ai_cmd: steps=%ld, scan_begin_arg=%d. Not properly tested by cmdtest?\n",
+ dev->minor,
steps,
cmd->scan_begin_arg);
up(&this_usbduxfastsub->sem);
this_usbduxfastsub->dux_commands[OPBASE+0]=0;
this_usbduxfastsub->dux_commands[OUTBASE+0]=0xFF & rngmask;
this_usbduxfastsub->dux_commands[LOGBASE+0]=0;
- }
+ }
if (steps<MIN_SAMPLING_PERIOD) {
// for fast single channel aqu without mux
// we have 1 state with duration 1
steps=steps-1;
-
+
// do the first part of the delay
this_usbduxfastsub->dux_commands[LENBASE+1]=steps/2;
this_usbduxfastsub->dux_commands[OPBASE+1]=0;
this_usbduxfastsub->dux_commands[OUTBASE+1]=0xFF & rngmask;
this_usbduxfastsub->dux_commands[LOGBASE+1]=0;
-
+
// and the second part
this_usbduxfastsub->dux_commands[LENBASE+2]=steps-steps/2;
this_usbduxfastsub->dux_commands[OPBASE+2]=0;
this_usbduxfastsub->dux_commands[OUTBASE+2]=0xFF & rngmask;
this_usbduxfastsub->dux_commands[LOGBASE+2]=0;
-
+
// get the data and branch back
this_usbduxfastsub->dux_commands[LENBASE+3]=0x09; // branch back to state 1
this_usbduxfastsub->dux_commands[OPBASE+3]=0x03; // deceision state w data
this_usbduxfastsub->dux_commands[OPBASE+2]=0;
this_usbduxfastsub->dux_commands[OUTBASE+2]=0xFF & rngmask;
this_usbduxfastsub->dux_commands[LOGBASE+2]=0;
-
+
this_usbduxfastsub->dux_commands[LENBASE+3]=1;
this_usbduxfastsub->dux_commands[OPBASE+3]=0x02; // data
this_usbduxfastsub->dux_commands[OUTBASE+3]=0xFF & rngmask;
this_usbduxfastsub->dux_commands[OPBASE+5]=0;
this_usbduxfastsub->dux_commands[OUTBASE+5]=0xFF & rngmask;
this_usbduxfastsub->dux_commands[LOGBASE+5]=0;
-
+
this_usbduxfastsub->dux_commands[LENBASE+6]=1;
this_usbduxfastsub->dux_commands[OPBASE+6]=0;
this_usbduxfastsub->dux_commands[OUTBASE+6]=0xFF & rngmask;
this_usbduxfastsub->dux_commands[OUTBASE+j*2+1]=0xFE & rngmask; //count
this_usbduxfastsub->dux_commands[LOGBASE+j*2+1]=0;
}
-
+
// 2 steps with duration 1: the idele step and step 6:
steps_tmp=steps-2;
// commit data to the FIFO and do the first part of the delay
this_usbduxfastsub->dux_commands[OPBASE+4]=0x02; // data
this_usbduxfastsub->dux_commands[OUTBASE+4]=0xFF & rngmask; // no change
this_usbduxfastsub->dux_commands[LOGBASE+4]=0;
-
+
if (CR_RANGE(cmd->chanlist[0])>0) rngmask=0xff-0x04; else rngmask=0xff;
// do the second part of the delay
this_usbduxfastsub->dux_commands[LENBASE+5]=steps_tmp-steps_tmp/2;
this_usbduxfastsub->dux_commands[OPBASE+6]=0;
this_usbduxfastsub->dux_commands[OUTBASE+6]=0xFF & rngmask;
this_usbduxfastsub->dux_commands[LOGBASE+6]=0;
-
+
case 16:
if (CR_RANGE(cmd->chanlist[0])>0) rngmask=0xff-0x04; else rngmask=0xff;
if(cmd->start_src == TRIG_EXT) { // we loop here until ready has been set
this_usbduxfastsub->dux_commands[OPBASE+0]=0;
this_usbduxfastsub->dux_commands[OUTBASE+0]=(0xFF-0x02) & rngmask; // reset
this_usbduxfastsub->dux_commands[LOGBASE+0]=0;
- }
+ }
// commit data to the FIFO
this_usbduxfastsub->dux_commands[LENBASE+1]=1;
up(&this_usbduxfastsub->sem);
return -EFAULT;
}
-
+
#ifdef CONFIG_COMEDI_DEBUG
printk("comedi %d: sending commands to the usb device\n",
up(&this_usbduxfastsub->sem);
return -EFAULT;
}
- this_usbduxfastsub->ai_continous=0;
+ this_usbduxfastsub->ai_continous=0;
} else {
// continous aquisition
this_usbduxfastsub->ai_continous=1;
usbduxfastsub->dux_commands[OPBASE+0]=0x02; // data
usbduxfastsub->dux_commands[OUTBASE+0]=0xFF & rngmask;
usbduxfastsub->dux_commands[LOGBASE+0]=0;
-
+
// do the first part of the delay
usbduxfastsub->dux_commands[LENBASE+1]=12;
usbduxfastsub->dux_commands[OPBASE+1]=0;
usbduxfastsub->dux_commands[OUTBASE+1]=0xFE & rngmask;
usbduxfastsub->dux_commands[LOGBASE+1]=0;
-
+
usbduxfastsub->dux_commands[LENBASE+2]=1;
usbduxfastsub->dux_commands[OPBASE+2]=0;
usbduxfastsub->dux_commands[OUTBASE+2]=0xFE & rngmask;
usbduxfastsub->dux_commands[LOGBASE+2]=0;
-
+
usbduxfastsub->dux_commands[LENBASE+3]=1;
usbduxfastsub->dux_commands[OPBASE+3]=0;
usbduxfastsub->dux_commands[OUTBASE+3]=0xFE & rngmask;
usbduxfastsub->dux_commands[LOGBASE+3]=0;
-
+
usbduxfastsub->dux_commands[LENBASE+4]=1;
usbduxfastsub->dux_commands[OPBASE+4]=0;
usbduxfastsub->dux_commands[OUTBASE+4]=0xFE & rngmask;
usbduxfastsub->dux_commands[LOGBASE+4]=0;
-
+
// second part
usbduxfastsub->dux_commands[LENBASE+5]=12;
usbduxfastsub->dux_commands[OPBASE+5]=0;
(int)(usbduxfastsub->urbIn->dev));
#endif
for(i=0;i<PACKETS_TO_IGNORE;i++) {
- err=USB_BULK_MSG(usbduxfastsub->usbdev,
+ err=USB_BULK_MSG(usbduxfastsub->usbdev,
usb_rcvbulkpipe(usbduxfastsub->usbdev,BULKINEP),
usbduxfastsub->transfer_buffer,
SIZEINBUF,
}
// data points
for(i=0;i<insn->n;) {
- err=USB_BULK_MSG(usbduxfastsub->usbdev,
+ err=USB_BULK_MSG(usbduxfastsub->usbdev,
usb_rcvbulkpipe(usbduxfastsub->usbdev,BULKINEP),
usbduxfastsub->transfer_buffer,
SIZEINBUF,
dev->minor);
up(&usbduxfastsub->sem);
return -EINVAL;
- }
+ }
for(j=chan;(j<n)&&(i<insn->n);j=j+16) {
data[i]=((uint16_t*)(usbduxfastsub->transfer_buffer))[j];
i++;
);
return -ENOMEM;
}
-
+
for (;;) {
char buf[256],*cp;
char type;
printk("comedi_: usbduxfast: firmware upload goes beyond FX2 RAM boundaries.");
return -EFAULT;
}
-
+
//printk("comedi_: usbduxfast: off=%x, len=%x:",off,len);
/* Read the record type */
// allocate memory for the urbs and initialise them
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
-static void* usbduxfastsub_probe(struct usb_device *udev,
+static void* usbduxfastsub_probe(struct usb_device *udev,
unsigned int interfnum,
const struct usb_device_id *id) {
#else
-static int usbduxfastsub_probe(struct usb_interface *uinterf,
+static int usbduxfastsub_probe(struct usb_interface *uinterf,
const struct usb_device_id *id) {
struct usb_device *udev = interface_to_usbdev(uinterf);
#endif
tidy_up(&(usbduxfastsub[index]));
up(&start_stop_sem);
return PROBE_ERR_RETURN( -ENOMEM);
- }
+ }
usbduxfastsub[index].transfer_buffer=
kmalloc(SIZEINBUF,GFP_KERNEL);
if (!(usbduxfastsub[index].transfer_buffer)) {
}
// we've reached the bottom of the function
usbduxfastsub[index].probed=1;
- up(&start_stop_sem);
+ up(&start_stop_sem);
printk("comedi_: usbduxfast%d has been successfully initialized.\n",index);
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
return (void*)(&usbduxfastsub[index]);
if (!usbduxfastsub_tmp) {
printk("comedi_: usbduxfast: disconnect called with null pointer.\n");
return;
- }
+ }
if (usbduxfastsub_tmp->usbdev!=udev) {
printk("comedi_: usbduxfast: BUG! called with wrong ptr!!!\n");
return;
usbduxfastsub[index].comedidev=dev;
// trying to upload the firmware into the chip
- if(comedi_aux_data(it->options, 0) &&
+ if(comedi_aux_data(it->options, 0) &&
it->options[COMEDI_DEVCONF_AUX_DATA_LENGTH]){
read_firmware(usbduxfastsub,
comedi_aux_data(it->options, 0),
it->options[COMEDI_DEVCONF_AUX_DATA_LENGTH]);
- }
+ }
dev->board_name = BOARDNAME;
-
+
/* set number of subdevices */
dev->n_subdevices=N_SUBDEVICES;
module_init(init_usbduxfast);
-module_exit(exit_usbduxfast);
+module_exit(exit_usbduxfast);
MODULE_AUTHOR( DRIVER_AUTHOR );
MODULE_DESCRIPTION( DRIVER_DESC );
* function prototypes
*/
-void comedi_event(comedi_device *dev,comedi_subdevice *s,unsigned int mask);
+void comedi_event(comedi_device *dev, comedi_subdevice *s);
void comedi_error(const comedi_device *dev,const char *s);
/* we can expand the number of bits used to encode devices/subdevices into