#define PCI_MITE_SIZE 4096
#define PCI_DAQ_SIZE 4096
+#define PCI_DAQ_SIZE_660X 8192
MODULE_LICENSE("GPL");
mite->daq_phys_addr=addr;
offset = mite->daq_phys_addr & ~PAGE_MASK;
start = mite->daq_phys_addr & PAGE_MASK;
- length = PCI_DAQ_SIZE + offset;
+
+ // In case of a 660x board, DAQ size is 8k instead of 4k (see as shown by lspci output)
+ if ((mite->pcidev->device == 0x1310) || (mite->pcidev->device == 0x2c60)){
+ length = PCI_DAQ_SIZE_660X + offset;
+ printk("mite: detected NI660X board, using PCI DAQ SIZE of 8k\n");
+ }
+ else length = PCI_DAQ_SIZE + offset;
mite->daq_io_addr = ioremap(start, length) + offset;
printk("DAQ:0x%08lx mapped to %p\n",mite->daq_phys_addr,mite->daq_io_addr);
- writel(mite->daq_phys_addr | WENAB , mite->mite_io_addr + MITE_IODWBSR);
+ // The 6602 board needs different initalisation, see the
+ // _updated_ (nov 2002) reg. Level Manual (filename 370505b.pdf) p. 3.55
+ if (mite->pcidev->device == 0x1310 ){
+ printk("mite: detected NI6602, using other I/O Window Base Size register\n");
+ writel((mite->daq_phys_addr & 0xffffff00L) | WENAB_6602 , mite->mite_io_addr + MITE_IODWBSR_NI6602);
+ writel(0 , mite->mite_io_addr + MITE_IODWCR_NI6602);
+ }
+ else writel(mite->daq_phys_addr | WENAB , mite->mite_io_addr + MITE_IODWBSR);
for( i = 0; i < NUM_MITE_DMA_CHANNELS; i++ ) {
writel(CHOR_DMARESET, mite->mite_io_addr + MITE_CHOR(i));
s->insn_config = ni_660x_dio_insn_config;
s->io_bits = 0; /* all bits default to input */
+ // Enabling the second chip: This "hardcodes" the counter
+ // outputs 5 to 8 to use the second TIO in case of a NI6602
+ // board.
+ if (thisboard->name == "PCI-6602" )
+ {
+ printk("NI6602: Setting Counterswap on second TIO\n");
+ enable_chip(dev);
+ }
+
printk("attached\n");
/* What does this "return value" mean? Is this fixed by API??
}else if ( (channel >= CTRS_PER_CHIP) && (channel < thisboard->n_ctrs) )
{
chipset = 1;
- // DPRINTK("NI_660x: Moving to chipset 1\n");
}else
{
DPRINTK("NI_660x: Channel specification not between limits\n");
/* ============================================================ */
/* 1 subdevice with 8 channels, differentation based on channel */
- DPRINTK("NI_660x: INSN_READ on channel %d\n", subdev_channel);
-
// Check what Application of Counter this channel is configured for
switch(ni_660x_gpct_config[subdev_channel].App)
{
}
static void
-enable_chip(comedi_device *dev, int chipset)
+enable_chip(comedi_device *dev)
{
/* See P. 3.5 of the Register-Level Programming manual. This
bit has to be set, otherwise, you can't use the second chip.
*/
- if ( chipset == 1)
- {
- writel(CounterSwap,dev->iobase + GPCT_OFFSET[chipset]
- + registerData[ClockConfigRegister].offset);
- }else
- {
- writel(0x0,dev->iobase + GPCT_OFFSET[chipset]
- + registerData[ClockConfigRegister].offset);
- }
+ writel(CounterSwap,dev->iobase + GPCT_OFFSET[1]
+ + registerData[ClockConfigRegister].offset);
+ return 0;
}
-
-
static int
ni_660x_GPCT_insn_config(comedi_device *dev, comedi_subdevice *s,
comedi_insn *insn, lsampl_t *data)
int counter_channel = GPCT_check_counter_channel_from_subdev_channel(subdev_channel);
DPRINTK("NI_660x: INSN_CONFIG: Configuring Channel %d\n", subdev_channel);
- enable_chip(dev, chipset);
// Check what type of Counter the user requested, data[0] contains
// the Application type
// Load (latch) this value into the counter
writew(Load,dev->iobase + GPCT_OFFSET[chipset]
+ registerData[GxCommandRegister(counter_channel)].offset);
- /* - Set Counting Mode into GPCT_X1 / 2 / 4 (as set by user
- - Take into account Z pulse (index pulse) only when both
- channel A and B are high (arbitrary choice)
+ /* - Set Counting Mode into GPCT_X1 / 2 / 4 (as set by user)
+ - When to take into account index pulse (as set by user)
+ - Take into account index pulse (as set by user)
*/
writew(((ni_660x_gpct_config[subdev_channel]).data[0] |
(ni_660x_gpct_config[subdev_channel]).data[1] |
- (ni_660x_gpct_config[subdev_channel]).data[1] ),
+ (ni_660x_gpct_config[subdev_channel]).data[2] ),
dev->iobase + GPCT_OFFSET[chipset]
+ registerData[GxCountingModeRegister(counter_channel)].offset);
// Put counter in input mode
break;
case GPCT_SIMPLE_EVENT:
DPRINTK("NI_660x: INSN_CONFIG: Config Simple Event Counter\n");
- //printk("NI_660x: INSN_CONFIG: Config Simple Event Counter\n");
ni_660x_gpct_config[subdev_channel].App =
CountingAndTimeMeasurement;
// Reset the counter
int counter_channel = GPCT_check_counter_channel_from_subdev_channel(subdev_channel);
DPRINTK("Triggering channel %d\n", subdev_channel);
- enable_chip(dev, chipset);
// Reset the counter
writew(GxReset(counter_channel),dev->iobase + GPCT_OFFSET[chipset]