Commit a8b77430 authored by David Schleef's avatar David Schleef Committed by Greg Kroah-Hartman

Staging: comedi: add nt_atmio driver

Hardware driver for NI AT-MIO E series cards
Supports the AT-MIO-16E-2, AT-MIO-16E-10, AT-MIO-16DE-10,
AT-MIO-64E-3, AT-MIO-16XE-50, AT-MIO-16XE-10, AT-AI-16XE-10 cards

From: David Schleef <ds@schleef.org>
Cc: Frank Mori Hess <fmhess@users.sourceforge.net>
Cc: Ian Abbott <abbotti@mev.co.uk>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@suse.de>
parent 124b13b2
/*
comedi/drivers/ni_atmio.c
Hardware driver for NI AT-MIO E series cards
COMEDI - Linux Control and Measurement Device Interface
Copyright (C) 1997-2001 David A. Schleef <ds@schleef.org>
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.
*/
/*
Driver: ni_atmio
Description: National Instruments AT-MIO-E series
Author: ds
Devices: [National Instruments] AT-MIO-16E-1 (ni_atmio),
AT-MIO-16E-2, AT-MIO-16E-10, AT-MIO-16DE-10, AT-MIO-64E-3,
AT-MIO-16XE-50, AT-MIO-16XE-10, AT-AI-16XE-10
Status: works
Updated: Thu May 1 20:03:02 CDT 2003
The driver has 2.6 kernel isapnp support, and
will automatically probe for a supported board if the
I/O base is left unspecified with comedi_config.
However, many of
the isapnp id numbers are unknown. If your board is not
recognized, please send the output of 'cat /proc/isapnp'
(you may need to modprobe the isa-pnp module for
/proc/isapnp to exist) so the
id numbers for your board can be added to the driver.
Otherwise, you can use the isapnptools package to configure
your board. Use isapnp to
configure the I/O base and IRQ for the board, and then pass
the same values as
parameters in comedi_config. A sample isapnp.conf file is included
in the etc/ directory of Comedilib.
Comedilib includes a utility to autocalibrate these boards. The
boards seem to boot into a state where the all calibration DACs
are at one extreme of their range, thus the default calibration
is terrible. Calibration at boot is strongly encouraged.
To use the extended digital I/O on some of the boards, enable the
8255 driver when configuring the Comedi source tree.
External triggering is supported for some events. The channel index
(scan_begin_arg, etc.) maps to PFI0 - PFI9.
Some of the more esoteric triggering possibilities of these boards
are not supported.
*/
/*
The real guts of the driver is in ni_mio_common.c, which is included
both here and in ni_pcimio.c
Interrupt support added by Truxton Fulton <trux@truxton.com>
References for specifications:
340747b.pdf Register Level Programmer Manual (obsolete)
340747c.pdf Register Level Programmer Manual (new)
DAQ-STC reference manual
Other possibly relevant info:
320517c.pdf User manual (obsolete)
320517f.pdf User manual (new)
320889a.pdf delete
320906c.pdf maximum signal ratings
321066a.pdf about 16x
321791a.pdf discontinuation of at-mio-16e-10 rev. c
321808a.pdf about at-mio-16e-10 rev P
321837a.pdf discontinuation of at-mio-16de-10 rev d
321838a.pdf about at-mio-16de-10 rev N
ISSUES:
need to deal with external reference for DAC, and other DAC
properties in board properties
deal with at-mio-16de-10 revision D to N changes, etc.
*/
#include "../comedidev.h"
#include <linux/delay.h>
#include <linux/isapnp.h>
#include "ni_stc.h"
#include "8255.h"
#undef DEBUG
#define ATMIO 1
#undef PCIMIO
/*
* AT specific setup
*/
#define NI_SIZE 0x20
#define MAX_N_CALDACS 32
static const ni_board ni_boards[] = {
{device_id:44,
isapnp_id:0x0000,/* XXX unknown */
name: "at-mio-16e-1",
n_adchan:16,
adbits: 12,
ai_fifo_depth:8192,
alwaysdither:0,
gainlkup:ai_gain_16,
ai_speed:800,
n_aochan:2,
aobits: 12,
ao_fifo_depth:2048,
.ao_range_table = &range_ni_E_ao_ext,
ao_unipolar:1,
ao_speed:1000,
has_8255:0,
.num_p0_dio_channels = 8,
caldac: {mb88341},
},
{device_id:25,
isapnp_id:0x1900,
name: "at-mio-16e-2",
n_adchan:16,
adbits: 12,
ai_fifo_depth:2048,
alwaysdither:0,
gainlkup:ai_gain_16,
ai_speed:2000,
n_aochan:2,
aobits: 12,
ao_fifo_depth:2048,
.ao_range_table = &range_ni_E_ao_ext,
ao_unipolar:1,
ao_speed:1000,
has_8255:0,
.num_p0_dio_channels = 8,
caldac: {mb88341},
},
{device_id:36,
isapnp_id:0x2400,
name: "at-mio-16e-10",
n_adchan:16,
adbits: 12,
ai_fifo_depth:512,
alwaysdither:0,
gainlkup:ai_gain_16,
ai_speed:10000,
n_aochan:2,
aobits: 12,
ao_fifo_depth:0,
.ao_range_table = &range_ni_E_ao_ext,
ao_unipolar:1,
ao_speed:10000,
.num_p0_dio_channels = 8,
caldac: {ad8804_debug},
has_8255:0,
},
{device_id:37,
isapnp_id:0x2500,
name: "at-mio-16de-10",
n_adchan:16,
adbits: 12,
ai_fifo_depth:512,
alwaysdither:0,
gainlkup:ai_gain_16,
ai_speed:10000,
n_aochan:2,
aobits: 12,
ao_fifo_depth:0,
.ao_range_table = &range_ni_E_ao_ext,
ao_unipolar:1,
ao_speed:10000,
.num_p0_dio_channels = 8,
caldac: {ad8804_debug},
has_8255:1,
},
{device_id:38,
isapnp_id:0x2600,
name: "at-mio-64e-3",
n_adchan:64,
adbits: 12,
ai_fifo_depth:2048,
alwaysdither:0,
gainlkup:ai_gain_16,
ai_speed:2000,
n_aochan:2,
aobits: 12,
ao_fifo_depth:2048,
.ao_range_table = &range_ni_E_ao_ext,
ao_unipolar:1,
ao_speed:1000,
has_8255:0,
.num_p0_dio_channels = 8,
caldac: {ad8804_debug},
},
{device_id:39,
isapnp_id:0x2700,
name: "at-mio-16xe-50",
n_adchan:16,
adbits: 16,
ai_fifo_depth:512,
alwaysdither:1,
gainlkup:ai_gain_8,
ai_speed:50000,
n_aochan:2,
aobits: 12,
ao_fifo_depth:0,
.ao_range_table = &range_bipolar10,
ao_unipolar:0,
ao_speed:50000,
.num_p0_dio_channels = 8,
caldac: {dac8800, dac8043},
has_8255:0,
},
{device_id:50,
isapnp_id:0x0000,/* XXX unknown */
name: "at-mio-16xe-10",
n_adchan:16,
adbits: 16,
ai_fifo_depth:512,
alwaysdither:1,
gainlkup:ai_gain_14,
ai_speed:10000,
n_aochan:2,
aobits: 16,
ao_fifo_depth:2048,
.ao_range_table = &range_ni_E_ao_ext,
ao_unipolar:1,
ao_speed:1000,
.num_p0_dio_channels = 8,
caldac: {dac8800, dac8043, ad8522},
has_8255:0,
},
{device_id:51,
isapnp_id:0x0000,/* XXX unknown */
name: "at-ai-16xe-10",
n_adchan:16,
adbits: 16,
ai_fifo_depth:512,
alwaysdither:1, /* unknown */
gainlkup:ai_gain_14,
ai_speed:10000,
n_aochan:0,
aobits: 0,
ao_fifo_depth:0,
ao_unipolar:0,
.num_p0_dio_channels = 8,
caldac: {dac8800, dac8043, ad8522},
has_8255:0,
}
};
static const int ni_irqpin[] =
{ -1, -1, -1, 0, 1, 2, -1, 3, -1, -1, 4, 5, 6, -1, -1, 7 };
#define interrupt_pin(a) (ni_irqpin[(a)])
#define IRQ_POLARITY 0
#define NI_E_IRQ_FLAGS 0
typedef struct {
struct pnp_dev *isapnp_dev;
NI_PRIVATE_COMMON} ni_private;
#define devpriv ((ni_private *)dev->private)
/* How we access registers */
#define ni_writel(a,b) (outl((a),(b)+dev->iobase))
#define ni_readl(a) (inl((a)+dev->iobase))
#define ni_writew(a,b) (outw((a),(b)+dev->iobase))
#define ni_readw(a) (inw((a)+dev->iobase))
#define ni_writeb(a,b) (outb((a),(b)+dev->iobase))
#define ni_readb(a) (inb((a)+dev->iobase))
/* How we access windowed registers */
/* We automatically take advantage of STC registers that can be
* read/written directly in the I/O space of the board. The
* AT-MIO devices map the low 8 STC registers to iobase+addr*2. */
static void ni_atmio_win_out(comedi_device * dev, uint16_t data, int addr)
{
unsigned long flags;
comedi_spin_lock_irqsave(&devpriv->window_lock, flags);
if ((addr) < 8) {
ni_writew(data, addr * 2);
} else {
ni_writew(addr, Window_Address);
ni_writew(data, Window_Data);
}
comedi_spin_unlock_irqrestore(&devpriv->window_lock, flags);
}
static uint16_t ni_atmio_win_in(comedi_device * dev, int addr)
{
unsigned long flags;
uint16_t ret;
comedi_spin_lock_irqsave(&devpriv->window_lock, flags);
if (addr < 8) {
ret = ni_readw(addr * 2);
} else {
ni_writew(addr, Window_Address);
ret = ni_readw(Window_Data);
}
comedi_spin_unlock_irqrestore(&devpriv->window_lock, flags);
return ret;
}
static struct pnp_device_id device_ids[] = {
{.id = "NIC1900",.driver_data = 0},
{.id = "NIC2400",.driver_data = 0},
{.id = "NIC2500",.driver_data = 0},
{.id = "NIC2600",.driver_data = 0},
{.id = "NIC2700",.driver_data = 0},
{.id = ""}
};
MODULE_DEVICE_TABLE(pnp, device_ids);
static int ni_atmio_attach(comedi_device * dev, comedi_devconfig * it);
static int ni_atmio_detach(comedi_device * dev);
static comedi_driver driver_atmio = {
driver_name:"ni_atmio",
module:THIS_MODULE,
attach:ni_atmio_attach,
detach:ni_atmio_detach,
};
COMEDI_INITCLEANUP(driver_atmio);
#include "ni_mio_common.c"
static int ni_getboardtype(comedi_device * dev);
/* clean up allocated resources */
static int ni_atmio_detach(comedi_device * dev)
{
mio_common_detach(dev);
if (dev->iobase)
release_region(dev->iobase, NI_SIZE);
if (dev->irq) {
comedi_free_irq(dev->irq, dev);
}
if (devpriv->isapnp_dev)
pnp_device_detach(devpriv->isapnp_dev);
return 0;
}
static int ni_isapnp_find_board(struct pnp_dev **dev)
{
struct pnp_dev *isapnp_dev = NULL;
int i;
for (i = 0; i < n_ni_boards; i++) {
isapnp_dev = pnp_find_dev(NULL,
ISAPNP_VENDOR('N', 'I', 'C'),
ISAPNP_FUNCTION(ni_boards[i].isapnp_id), NULL);
if (isapnp_dev == NULL || isapnp_dev->card == NULL)
continue;
if (pnp_device_attach(isapnp_dev) < 0) {
printk("ni_atmio: %s found but already active, skipping.\n", ni_boards[i].name);
continue;
}
if (pnp_activate_dev(isapnp_dev) < 0) {
pnp_device_detach(isapnp_dev);
return -EAGAIN;
}
if (!pnp_port_valid(isapnp_dev, 0)
|| !pnp_irq_valid(isapnp_dev, 0)) {
pnp_device_detach(isapnp_dev);
printk("ni_atmio: pnp invalid port or irq, aborting\n");
return -ENOMEM;
}
break;
}
if (i == n_ni_boards)
return -ENODEV;
*dev = isapnp_dev;
return 0;
}
static int ni_atmio_attach(comedi_device * dev, comedi_devconfig * it)
{
struct pnp_dev *isapnp_dev;
int ret;
unsigned long iobase;
int board;
unsigned int irq;
/* allocate private area */
if ((ret = ni_alloc_private(dev)) < 0)
return ret;
devpriv->stc_writew = &ni_atmio_win_out;
devpriv->stc_readw = &ni_atmio_win_in;
devpriv->stc_writel = &win_out2;
devpriv->stc_readl = &win_in2;
iobase = it->options[0];
irq = it->options[1];
isapnp_dev = NULL;
if (iobase == 0) {
ret = ni_isapnp_find_board(&isapnp_dev);
if (ret < 0)
return ret;
iobase = pnp_port_start(isapnp_dev, 0);
irq = pnp_irq(isapnp_dev, 0);
devpriv->isapnp_dev = isapnp_dev;
}
/* reserve our I/O region */
printk("comedi%d: ni_atmio: 0x%04lx", dev->minor, iobase);
if (!request_region(iobase, NI_SIZE, "ni_atmio")) {
printk(" I/O port conflict\n");
return -EIO;
}
dev->iobase = iobase;
#ifdef DEBUG
/* board existence sanity check */
{
int i;
printk(" board fingerprint:");
for (i = 0; i < 16; i += 2) {
printk(" %04x %02x", inw(dev->iobase + i),
inb(dev->iobase + i + 1));
}
}
#endif
/* get board type */
board = ni_getboardtype(dev);
if (board < 0)
return -EIO;
dev->board_ptr = ni_boards + board;
printk(" %s", boardtype.name);
dev->board_name = boardtype.name;
/* irq stuff */
if (irq != 0) {
if (irq > 15 || ni_irqpin[irq] == -1) {
printk(" invalid irq %u\n", irq);
return -EINVAL;
}
printk(" ( irq = %u )", irq);
if ((ret = comedi_request_irq(irq, ni_E_interrupt,
NI_E_IRQ_FLAGS, "ni_atmio", dev)) < 0) {
printk(" irq not available\n");
return -EINVAL;
}
dev->irq = irq;
}
/* generic E series stuff in ni_mio_common.c */
if ((ret = ni_E_init(dev, it)) < 0) {
return ret;
}
return 0;
}
static int ni_getboardtype(comedi_device * dev)
{
int device_id = ni_read_eeprom(dev, 511);
int i;
for (i = 0; i < n_ni_boards; i++) {
if (ni_boards[i].device_id == device_id) {
return i;
}
}
if (device_id == 255) {
printk(" can't find board\n");
} else if (device_id == 0) {
printk(" EEPROM read error (?) or device not found\n");
} else {
printk(" unknown device ID %d -- contact author\n", device_id);
}
return -1;
}
/*
module/ni_stc.h
Register descriptions for NI DAQ-STC chip
COMEDI - Linux Control and Measurement Device Interface
Copyright (C) 1998-9 David A. Schleef <ds@schleef.org>
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.
*/
/*
References:
DAQ-STC Technical Reference Manual
*/
#ifndef _COMEDI_NI_STC_H
#define _COMEDI_NI_STC_H
#include "ni_tio.h"
#define _bit15 0x8000
#define _bit14 0x4000
#define _bit13 0x2000
#define _bit12 0x1000
#define _bit11 0x0800
#define _bit10 0x0400
#define _bit9 0x0200
#define _bit8 0x0100
#define _bit7 0x0080
#define _bit6 0x0040
#define _bit5 0x0020
#define _bit4 0x0010
#define _bit3 0x0008
#define _bit2 0x0004
#define _bit1 0x0002
#define _bit0 0x0001
#define NUM_PFI_OUTPUT_SELECT_REGS 6
/* Registers in the National Instruments DAQ-STC chip */
#define Interrupt_A_Ack_Register 2
#define G0_Gate_Interrupt_Ack _bit15
#define G0_TC_Interrupt_Ack _bit14
#define AI_Error_Interrupt_Ack _bit13
#define AI_STOP_Interrupt_Ack _bit12
#define AI_START_Interrupt_Ack _bit11
#define AI_START2_Interrupt_Ack _bit10
#define AI_START1_Interrupt_Ack _bit9
#define AI_SC_TC_Interrupt_Ack _bit8
#define AI_SC_TC_Error_Confirm _bit7
#define G0_TC_Error_Confirm _bit6
#define G0_Gate_Error_Confirm _bit5
#define AI_Status_1_Register 2
#define Interrupt_A_St 0x8000
#define AI_FIFO_Full_St 0x4000
#define AI_FIFO_Half_Full_St 0x2000
#define AI_FIFO_Empty_St 0x1000
#define AI_Overrun_St 0x0800
#define AI_Overflow_St 0x0400
#define AI_SC_TC_Error_St 0x0200
#define AI_START2_St 0x0100
#define AI_START1_St 0x0080
#define AI_SC_TC_St 0x0040
#define AI_START_St 0x0020
#define AI_STOP_St 0x0010
#define G0_TC_St 0x0008
#define G0_Gate_Interrupt_St 0x0004
#define AI_FIFO_Request_St 0x0002
#define Pass_Thru_0_Interrupt_St 0x0001
#define AI_Status_2_Register 5
#define Interrupt_B_Ack_Register 3
enum Interrupt_B_Ack_Bits {
G1_Gate_Error_Confirm = _bit1,
G1_TC_Error_Confirm = _bit2,
AO_BC_TC_Trigger_Error_Confirm = _bit3,
AO_BC_TC_Error_Confirm = _bit4,
AO_UI2_TC_Error_Confrim = _bit5,
AO_UI2_TC_Interrupt_Ack = _bit6,
AO_UC_TC_Interrupt_Ack = _bit7,
AO_BC_TC_Interrupt_Ack = _bit8,
AO_START1_Interrupt_Ack = _bit9,
AO_UPDATE_Interrupt_Ack = _bit10,
AO_START_Interrupt_Ack = _bit11,
AO_STOP_Interrupt_Ack = _bit12,
AO_Error_Interrupt_Ack = _bit13,
G1_TC_Interrupt_Ack = _bit14,
G1_Gate_Interrupt_Ack = _bit15
};
#define AO_Status_1_Register 3
#define Interrupt_B_St _bit15
#define AO_FIFO_Full_St _bit14
#define AO_FIFO_Half_Full_St _bit13
#define AO_FIFO_Empty_St _bit12
#define AO_BC_TC_Error_St _bit11
#define AO_START_St _bit10
#define AO_Overrun_St _bit9
#define AO_START1_St _bit8
#define AO_BC_TC_St _bit7
#define AO_UC_TC_St _bit6
#define AO_UPDATE_St _bit5
#define AO_UI2_TC_St _bit4
#define G1_TC_St _bit3
#define G1_Gate_Interrupt_St _bit2
#define AO_FIFO_Request_St _bit1
#define Pass_Thru_1_Interrupt_St _bit0
#define AI_Command_2_Register 4
#define AI_End_On_SC_TC _bit15
#define AI_End_On_End_Of_Scan _bit14
#define AI_START1_Disable _bit11
#define AI_SC_Save_Trace _bit10
#define AI_SI_Switch_Load_On_SC_TC _bit9
#define AI_SI_Switch_Load_On_STOP _bit8
#define AI_SI_Switch_Load_On_TC _bit7
#define AI_SC_Switch_Load_On_TC _bit4
#define AI_STOP_Pulse _bit3
#define AI_START_Pulse _bit2
#define AI_START2_Pulse _bit1
#define AI_START1_Pulse _bit0
#define AO_Command_2_Register 5
#define AO_End_On_BC_TC(x) (((x) & 0x3) << 14)
#define AO_Start_Stop_Gate_Enable _bit13
#define AO_UC_Save_Trace _bit12
#define AO_BC_Gate_Enable _bit11
#define AO_BC_Save_Trace _bit10
#define AO_UI_Switch_Load_On_BC_TC _bit9
#define AO_UI_Switch_Load_On_Stop _bit8
#define AO_UI_Switch_Load_On_TC _bit7
#define AO_UC_Switch_Load_On_BC_TC _bit6
#define AO_UC_Switch_Load_On_TC _bit5
#define AO_BC_Switch_Load_On_TC _bit4
#define AO_Mute_B _bit3
#define AO_Mute_A _bit2
#define AO_UPDATE2_Pulse _bit1
#define AO_START1_Pulse _bit0
#define AO_Status_2_Register 6
#define DIO_Parallel_Input_Register 7
#define AI_Command_1_Register 8
#define AI_Analog_Trigger_Reset _bit14
#define AI_Disarm _bit13
#define AI_SI2_Arm _bit12
#define AI_SI2_Load _bit11
#define AI_SI_Arm _bit10
#define AI_SI_Load _bit9
#define AI_DIV_Arm _bit8
#define AI_DIV_Load _bit7
#define AI_SC_Arm _bit6
#define AI_SC_Load _bit5
#define AI_SCAN_IN_PROG_Pulse _bit4
#define AI_EXTMUX_CLK_Pulse _bit3
#define AI_LOCALMUX_CLK_Pulse _bit2
#define AI_SC_TC_Pulse _bit1
#define AI_CONVERT_Pulse _bit0
#define AO_Command_1_Register 9
#define AO_Analog_Trigger_Reset _bit15
#define AO_START_Pulse _bit14
#define AO_Disarm _bit13
#define AO_UI2_Arm_Disarm _bit12
#define AO_UI2_Load _bit11
#define AO_UI_Arm _bit10
#define AO_UI_Load _bit9
#define AO_UC_Arm _bit8
#define AO_UC_Load _bit7
#define AO_BC_Arm _bit6
#define AO_BC_Load _bit5
#define AO_DAC1_Update_Mode _bit4
#define AO_LDAC1_Source_Select _bit3
#define AO_DAC0_Update_Mode _bit2
#define AO_LDAC0_Source_Select _bit1
#define AO_UPDATE_Pulse _bit0
#define DIO_Output_Register 10
#define DIO_Parallel_Data_Out(a) ((a)&0xff)
#define DIO_Parallel_Data_Mask 0xff
#define DIO_SDOUT _bit0
#define DIO_SDIN _bit4
#define DIO_Serial_Data_Out(a) (((a)&0xff)<<8)
#define DIO_Serial_Data_Mask 0xff00
#define DIO_Control_Register 11
#define DIO_Software_Serial_Control _bit11
#define DIO_HW_Serial_Timebase _bit10
#define DIO_HW_Serial_Enable _bit9
#define DIO_HW_Serial_Start _bit8
#define DIO_Pins_Dir(a) ((a)&0xff)
#define DIO_Pins_Dir_Mask 0xff
#define AI_Mode_1_Register 12
#define AI_CONVERT_Source_Select(a) (((a) & 0x1f) << 11)
#define AI_SI_Source_select(a) (((a) & 0x1f) << 6)
#define AI_CONVERT_Source_Polarity _bit5
#define AI_SI_Source_Polarity _bit4
#define AI_Start_Stop _bit3
#define AI_Mode_1_Reserved _bit2
#define AI_Continuous _bit1
#define AI_Trigger_Once _bit0
#define AI_Mode_2_Register 13
#define AI_SC_Gate_Enable _bit15
#define AI_Start_Stop_Gate_Enable _bit14
#define AI_Pre_Trigger _bit13
#define AI_External_MUX_Present _bit12
#define AI_SI2_Initial_Load_Source _bit9
#define AI_SI2_Reload_Mode _bit8
#define AI_SI_Initial_Load_Source _bit7
#define AI_SI_Reload_Mode(a) (((a) & 0x7)<<4)
#define AI_SI_Write_Switch _bit3
#define AI_SC_Initial_Load_Source _bit2
#define AI_SC_Reload_Mode _bit1
#define AI_SC_Write_Switch _bit0
#define AI_SI_Load_A_Registers 14
#define AI_SI_Load_B_Registers 16
#define AI_SC_Load_A_Registers 18
#define AI_SC_Load_B_Registers 20
#define AI_SI_Save_Registers 64
#define AI_SC_Save_Registers 66
#define AI_SI2_Load_A_Register 23
#define AI_SI2_Load_B_Register 25
#define Joint_Status_1_Register 27
#define DIO_Serial_IO_In_Progress_St _bit12
#define DIO_Serial_Input_Register 28
#define Joint_Status_2_Register 29
enum Joint_Status_2_Bits {
AO_TMRDACWRs_In_Progress_St = 0x20,
};
#define AO_Mode_1_Register 38
#define AO_UPDATE_Source_Select(x) (((x)&0x1f)<<11)
#define AO_UI_Source_Select(x) (((x)&0x1f)<<6)
#define AO_Multiple_Channels _bit5
#define AO_UPDATE_Source_Polarity _bit4
#define AO_UI_Source_Polarity _bit3
#define AO_UC_Switch_Load_Every_TC _bit2
#define AO_Continuous _bit1
#define AO_Trigger_Once _bit0
#define AO_Mode_2_Register 39
#define AO_FIFO_Mode_Mask ( 0x3 << 14 )
enum AO_FIFO_Mode_Bits {
AO_FIFO_Mode_HF_to_F = (3 << 14),
AO_FIFO_Mode_F = (2 << 14),
AO_FIFO_Mode_HF = (1 << 14),
AO_FIFO_Mode_E = (0 << 14),
};
#define AO_FIFO_Retransmit_Enable _bit13
#define AO_START1_Disable _bit12
#define AO_UC_Initial_Load_Source _bit11
#define AO_UC_Write_Switch _bit10
#define AO_UI2_Initial_Load_Source _bit9
#define AO_UI2_Reload_Mode _bit8
#define AO_UI_Initial_Load_Source _bit7
#define AO_UI_Reload_Mode(x) (((x) & 0x7) << 4)
#define AO_UI_Write_Switch _bit3
#define AO_BC_Initial_Load_Source _bit2
#define AO_BC_Reload_Mode _bit1
#define AO_BC_Write_Switch _bit0
#define AO_UI_Load_A_Register 40
#define AO_UI_Load_A_Register_High 40
#define AO_UI_Load_A_Register_Low 41
#define AO_UI_Load_B_Register 42
#define AO_UI_Save_Registers 16
#define AO_BC_Load_A_Register 44
#define AO_BC_Load_A_Register_High 44
#define AO_BC_Load_A_Register_Low 45
#define AO_BC_Load_B_Register 46
#define AO_BC_Load_B_Register_High 46
#define AO_BC_Load_B_Register_Low 47
#define AO_BC_Save_Registers 18
#define AO_UC_Load_A_Register 48
#define AO_UC_Load_A_Register_High 48
#define AO_UC_Load_A_Register_Low 49
#define AO_UC_Load_B_Register 50
#define AO_UC_Save_Registers 20
#define Clock_and_FOUT_Register 56
enum Clock_and_FOUT_bits {
FOUT_Enable = _bit15,
FOUT_Timebase_Select = _bit14,
DIO_Serial_Out_Divide_By_2 = _bit13,
Slow_Internal_Time_Divide_By_2 = _bit12,
Slow_Internal_Timebase = _bit11,
G_Source_Divide_By_2 = _bit10,
Clock_To_Board_Divide_By_2 = _bit9,
Clock_To_Board = _bit8,
AI_Output_Divide_By_2 = _bit7,
AI_Source_Divide_By_2 = _bit6,
AO_Output_Divide_By_2 = _bit5,
AO_Source_Divide_By_2 = _bit4,
FOUT_Divider_mask = 0xf
};
static inline unsigned FOUT_Divider(unsigned divider)
{
return (divider & FOUT_Divider_mask);
}
#define IO_Bidirection_Pin_Register 57
#define RTSI_Trig_Direction_Register 58
enum RTSI_Trig_Direction_Bits {
Drive_RTSI_Clock_Bit = 0x1,
Use_RTSI_Clock_Bit = 0x2,
};
static inline unsigned RTSI_Output_Bit(unsigned channel, int is_mseries)
{
unsigned max_channel;
unsigned base_bit_shift;
if (is_mseries) {
base_bit_shift = 8;
max_channel = 7;
} else {
base_bit_shift = 9;
max_channel = 6;
}
if (channel > max_channel) {
rt_printk("%s: bug, invalid RTSI_channel=%i\n", __FUNCTION__,
channel);
return 0;
}
return 1 << (base_bit_shift + channel);
}
#define Interrupt_Control_Register 59
#define Interrupt_B_Enable _bit15
#define Interrupt_B_Output_Select(x) ((x)<<12)
#define Interrupt_A_Enable _bit11
#define Interrupt_A_Output_Select(x) ((x)<<8)
#define Pass_Thru_0_Interrupt_Polarity _bit3
#define Pass_Thru_1_Interrupt_Polarity _bit2
#define Interrupt_Output_On_3_Pins _bit1
#define Interrupt_Output_Polarity _bit0
#define AI_Output_Control_Register 60
#define AI_START_Output_Select _bit10
#define AI_SCAN_IN_PROG_Output_Select(x) (((x) & 0x3) << 8)
#define AI_EXTMUX_CLK_Output_Select(x) (((x) & 0x3) << 6)
#define AI_LOCALMUX_CLK_Output_Select(x) ((x)<<4)
#define AI_SC_TC_Output_Select(x) ((x)<<2)
enum ai_convert_output_selection {
AI_CONVERT_Output_High_Z = 0,
AI_CONVERT_Output_Ground = 1,
AI_CONVERT_Output_Enable_Low = 2,
AI_CONVERT_Output_Enable_High = 3
};
static unsigned AI_CONVERT_Output_Select(enum ai_convert_output_selection
selection)
{
return selection & 0x3;
}
#define AI_START_STOP_Select_Register 62
#define AI_START_Polarity _bit15
#define AI_STOP_Polarity _bit14
#define AI_STOP_Sync _bit13
#define AI_STOP_Edge _bit12
#define AI_STOP_Select(a) (((a) & 0x1f)<<7)
#define AI_START_Sync _bit6
#define AI_START_Edge _bit5
#define AI_START_Select(a) ((a) & 0x1f)
#define AI_Trigger_Select_Register 63
#define AI_START1_Polarity _bit15
#define AI_START2_Polarity _bit14
#define AI_START2_Sync _bit13
#define AI_START2_Edge _bit12
#define AI_START2_Select(a) (((a) & 0x1f) << 7)
#define AI_START1_Sync _bit6
#define AI_START1_Edge _bit5
#define AI_START1_Select(a) ((a) & 0x1f)
#define AI_DIV_Load_A_Register 64
#define AO_Start_Select_Register 66
#define AO_UI2_Software_Gate _bit15
#define AO_UI2_External_Gate_Polarity _bit14
#define AO_START_Polarity _bit13
#define AO_AOFREQ_Enable _bit12
#define AO_UI2_External_Gate_Select(a) (((a) & 0x1f) << 7)
#define AO_START_Sync _bit6
#define AO_START_Edge _bit5
#define AO_START_Select(a) ((a) & 0x1f)
#define AO_Trigger_Select_Register 67
#define AO_UI2_External_Gate_Enable _bit15
#define AO_Delayed_START1 _bit14
#define AO_START1_Polarity _bit13
#define AO_UI2_Source_Polarity _bit12
#define AO_UI2_Source_Select(x) (((x)&0x1f)<<7)
#define AO_START1_Sync _bit6
#define AO_START1_Edge _bit5
#define AO_START1_Select(x) (((x)&0x1f)<<0)
#define AO_Mode_3_Register 70
#define AO_UI2_Switch_Load_Next_TC _bit13
#define AO_UC_Switch_Load_Every_BC_TC _bit12
#define AO_Trigger_Length _bit11
#define AO_Stop_On_Overrun_Error _bit5
#define AO_Stop_On_BC_TC_Trigger_Error _bit4
#define AO_Stop_On_BC_TC_Error _bit3
#define AO_Not_An_UPDATE _bit2
#define AO_Software_Gate _bit1
#define AO_Last_Gate_Disable _bit0 /* M Series only */
#define Joint_Reset_Register 72
#define Software_Reset _bit11
#define AO_Configuration_End _bit9
#define AI_Configuration_End _bit8
#define AO_Configuration_Start _bit5
#define AI_Configuration_Start _bit4
#define G1_Reset _bit3
#define G0_Reset _bit2
#define AO_Reset _bit1
#define AI_Reset _bit0
#define Interrupt_A_Enable_Register 73
#define Pass_Thru_0_Interrupt_Enable _bit9
#define G0_Gate_Interrupt_Enable _bit8
#define AI_FIFO_Interrupt_Enable _bit7
#define G0_TC_Interrupt_Enable _bit6
#define AI_Error_Interrupt_Enable _bit5
#define AI_STOP_Interrupt_Enable _bit4
#define AI_START_Interrupt_Enable _bit3
#define AI_START2_Interrupt_Enable _bit2
#define AI_START1_Interrupt_Enable _bit1
#define AI_SC_TC_Interrupt_Enable _bit0
#define Interrupt_B_Enable_Register 75
#define Pass_Thru_1_Interrupt_Enable _bit11
#define G1_Gate_Interrupt_Enable _bit10
#define G1_TC_Interrupt_Enable _bit9
#define AO_FIFO_Interrupt_Enable _bit8
#define AO_UI2_TC_Interrupt_Enable _bit7
#define AO_UC_TC_Interrupt_Enable _bit6
#define AO_Error_Interrupt_Enable _bit5
#define AO_STOP_Interrupt_Enable _bit4
#define AO_START_Interrupt_Enable _bit3
#define AO_UPDATE_Interrupt_Enable _bit2
#define AO_START1_Interrupt_Enable _bit1
#define AO_BC_TC_Interrupt_Enable _bit0
#define Second_IRQ_A_Enable_Register 74
enum Second_IRQ_A_Enable_Bits {
AI_SC_TC_Second_Irq_Enable = _bit0,
AI_START1_Second_Irq_Enable = _bit1,
AI_START2_Second_Irq_Enable = _bit2,
AI_START_Second_Irq_Enable = _bit3,
AI_STOP_Second_Irq_Enable = _bit4,
AI_Error_Second_Irq_Enable = _bit5,
G0_TC_Second_Irq_Enable = _bit6,
AI_FIFO_Second_Irq_Enable = _bit7,
G0_Gate_Second_Irq_Enable = _bit8,
Pass_Thru_0_Second_Irq_Enable = _bit9
};
#define Second_IRQ_B_Enable_Register 76
enum Second_IRQ_B_Enable_Bits {
AO_BC_TC_Second_Irq_Enable = _bit0,
AO_START1_Second_Irq_Enable = _bit1,
AO_UPDATE_Second_Irq_Enable = _bit2,
AO_START_Second_Irq_Enable = _bit3,
AO_STOP_Second_Irq_Enable = _bit4,
AO_Error_Second_Irq_Enable = _bit5,
AO_UC_TC_Second_Irq_Enable = _bit6,
AO_UI2_TC_Second_Irq_Enable = _bit7,
AO_FIFO_Second_Irq_Enable = _bit8,
G1_TC_Second_Irq_Enable = _bit9,
G1_Gate_Second_Irq_Enable = _bit10,
Pass_Thru_1_Second_Irq_Enable = _bit11
};
#define AI_Personal_Register 77
#define AI_SHIFTIN_Pulse_Width _bit15
#define AI_EOC_Polarity _bit14
#define AI_SOC_Polarity _bit13
#define AI_SHIFTIN_Polarity _bit12
#define AI_CONVERT_Pulse_Timebase _bit11
#define AI_CONVERT_Pulse_Width _bit10
#define AI_CONVERT_Original_Pulse _bit9
#define AI_FIFO_Flags_Polarity _bit8
#define AI_Overrun_Mode _bit7
#define AI_EXTMUX_CLK_Pulse_Width _bit6
#define AI_LOCALMUX_CLK_Pulse_Width _bit5
#define AI_AIFREQ_Polarity _bit4
#define AO_Personal_Register 78
enum AO_Personal_Bits {
AO_Interval_Buffer_Mode = 1 << 3,
AO_BC_Source_Select = 1 << 4,
AO_UPDATE_Pulse_Width = 1 << 5,
AO_UPDATE_Pulse_Timebase = 1 << 6,
AO_UPDATE_Original_Pulse = 1 << 7,
AO_DMA_PIO_Control = 1 << 8, /* M Series: reserved */
AO_AOFREQ_Polarity = 1 << 9, /* M Series: reserved */
AO_FIFO_Enable = 1 << 10,
AO_FIFO_Flags_Polarity = 1 << 11, /* M Series: reserved */
AO_TMRDACWR_Pulse_Width = 1 << 12,
AO_Fast_CPU = 1 << 13, /* M Series: reserved */
AO_Number_Of_DAC_Packages = 1 << 14, // 1 for "single" mode, 0 for "dual"
AO_Multiple_DACS_Per_Package = 1 << 15 // m-series only
};
#define RTSI_Trig_A_Output_Register 79
#define RTSI_Trig_B_Output_Register 80
enum RTSI_Trig_B_Output_Bits {
RTSI_Sub_Selection_1_Bit = 0x8000 // not for m-series
};
static inline unsigned RTSI_Trig_Output_Bits(unsigned rtsi_channel,
unsigned source)
{
return (source & 0xf) << ((rtsi_channel % 4) * 4);
};
static inline unsigned RTSI_Trig_Output_Mask(unsigned rtsi_channel)
{
return 0xf << ((rtsi_channel % 4) * 4);
};
// inverse to RTSI_Trig_Output_Bits()
static inline unsigned RTSI_Trig_Output_Source(unsigned rtsi_channel,
unsigned bits)
{
return (bits >> ((rtsi_channel % 4) * 4)) & 0xf;
};
#define RTSI_Board_Register 81
#define Write_Strobe_0_Register 82
#define Write_Strobe_1_Register 83
#define Write_Strobe_2_Register 84
#define Write_Strobe_3_Register 85
#define AO_Output_Control_Register 86
#define AO_External_Gate_Enable _bit15
#define AO_External_Gate_Select(x) (((x)&0x1f)<<10)
#define AO_Number_Of_Channels(x) (((x)&0xf)<<6)
#define AO_UPDATE2_Output_Select(x) (((x)&0x3)<<4)
#define AO_External_Gate_Polarity _bit3
#define AO_UPDATE2_Output_Toggle _bit2
enum ao_update_output_selection {
AO_Update_Output_High_Z = 0,
AO_Update_Output_Ground = 1,
AO_Update_Output_Enable_Low = 2,
AO_Update_Output_Enable_High = 3
};
static unsigned AO_UPDATE_Output_Select(enum ao_update_output_selection
selection)
{
return selection & 0x3;
}
#define AI_Mode_3_Register 87
#define AI_Trigger_Length _bit15
#define AI_Delay_START _bit14
#define AI_Software_Gate _bit13
#define AI_SI_Special_Trigger_Delay _bit12
#define AI_SI2_Source_Select _bit11
#define AI_Delayed_START2 _bit10
#define AI_Delayed_START1 _bit9
#define AI_External_Gate_Mode _bit8
#define AI_FIFO_Mode_HF_to_E (3<<6)
#define AI_FIFO_Mode_F (2<<6)
#define AI_FIFO_Mode_HF (1<<6)
#define AI_FIFO_Mode_NE (0<<6)
#define AI_External_Gate_Polarity _bit5
#define AI_External_Gate_Select(a) ((a) & 0x1f)
#define G_Autoincrement_Register(a) (68+(a))
#define G_Command_Register(a) (6+(a))
#define G_HW_Save_Register(a) (8+(a)*2)
#define G_HW_Save_Register_High(a) (8+(a)*2)
#define G_HW_Save_Register_Low(a) (9+(a)*2)
#define G_Input_Select_Register(a) (36+(a))
#define G_Load_A_Register(a) (28+(a)*4)
#define G_Load_A_Register_High(a) (28+(a)*4)
#define G_Load_A_Register_Low(a) (29+(a)*4)
#define G_Load_B_Register(a) (30+(a)*4)
#define G_Load_B_Register_High(a) (30+(a)*4)
#define G_Load_B_Register_Low(a) (31+(a)*4)
#define G_Mode_Register(a) (26+(a))
#define G_Save_Register(a) (12+(a)*2)
#define G_Save_Register_High(a) (12+(a)*2)
#define G_Save_Register_Low(a) (13+(a)*2)
#define G_Status_Register 4
#define Analog_Trigger_Etc_Register 61
/* command register */
#define G_Disarm_Copy _bit15 /* strobe */
#define G_Save_Trace_Copy _bit14
#define G_Arm_Copy _bit13 /* strobe */
#define G_Bank_Switch_Start _bit10 /* strobe */
#define G_Little_Big_Endian _bit9
#define G_Synchronized_Gate _bit8
#define G_Write_Switch _bit7
#define G_Up_Down(a) (((a)&0x03)<<5)
#define G_Disarm _bit4 /* strobe */
#define G_Analog_Trigger_Reset _bit3 /* strobe */
#define G_Save_Trace _bit1
#define G_Arm _bit0 /* strobe */
/*channel agnostic names for the command register #defines */
#define G_Bank_Switch_Enable _bit12
#define G_Bank_Switch_Mode _bit11
#define G_Load _bit2 /* strobe */
/* input select register */
#define G_Gate_Select(a) (((a)&0x1f)<<7)
#define G_Source_Select(a) (((a)&0x1f)<<2)
#define G_Write_Acknowledges_Irq _bit1
#define G_Read_Acknowledges_Irq _bit0
/* same input select register, but with channel agnostic names */
#define G_Source_Polarity _bit15
#define G_Output_Polarity _bit14
#define G_OR_Gate _bit13
#define G_Gate_Select_Load_Source _bit12
/* mode register */
#define G_Loading_On_TC _bit12
#define G_Output_Mode(a) (((a)&0x03)<<8)
#define G_Trigger_Mode_For_Edge_Gate(a) (((a)&0x03)<<3)
#define G_Gating_Mode(a) (((a)&0x03)<<0)
/* same input mode register, but with channel agnostic names */
#define G_Load_Source_Select _bit7
#define G_Reload_Source_Switching _bit15
#define G_Loading_On_Gate _bit14
#define G_Gate_Polarity _bit13
#define G_Counting_Once(a) (((a)&0x03)<<10)
#define G_Stop_Mode(a) (((a)&0x03)<<5)
#define G_Gate_On_Both_Edges _bit2
/* G_Status_Register */
#define G1_Gate_Error_St _bit15
#define G0_Gate_Error_St _bit14
#define G1_TC_Error_St _bit13
#define G0_TC_Error_St _bit12
#define G1_No_Load_Between_Gates_St _bit11
#define G0_No_Load_Between_Gates_St _bit10
#define G1_Armed_St _bit9
#define G0_Armed_St _bit8
#define G1_Stale_Data_St _bit7
#define G0_Stale_Data_St _bit6
#define G1_Next_Load_Source_St _bit5
#define G0_Next_Load_Source_St _bit4
#define G1_Counting_St _bit3
#define G0_Counting_St _bit2
#define G1_Save_St _bit1
#define G0_Save_St _bit0
/* general purpose counter timer */
#define G_Autoincrement(a) ((a)<<0)
/*Analog_Trigger_Etc_Register*/
#define Analog_Trigger_Mode(x) ((x) & 0x7)
#define Analog_Trigger_Enable _bit3
#define Analog_Trigger_Drive _bit4
#define GPFO_1_Output_Select _bit7
#define GPFO_0_Output_Select(a) ((a)<<11)
#define GPFO_0_Output_Enable _bit14
#define GPFO_1_Output_Enable _bit15
/* Additional windowed registers unique to E series */
/* 16 bit registers shadowed from DAQ-STC */
#define Window_Address 0x00
#define Window_Data 0x02
#define Configuration_Memory_Clear 82
#define ADC_FIFO_Clear 83
#define DAC_FIFO_Clear 84
/* i/o port offsets */
/* 8 bit registers */
#define XXX_Status 0x01
enum XXX_Status_Bits {
PROMOUT = 0x1,
AI_FIFO_LOWER_NOT_EMPTY = 0x8,
};
#define Serial_Command 0x0d
#define Misc_Command 0x0f
#define Port_A 0x19
#define Port_B 0x1b
#define Port_C 0x1d
#define Configuration 0x1f
#define Strobes 0x01
#define Channel_A_Mode 0x03
#define Channel_B_Mode 0x05
#define Channel_C_Mode 0x07
#define AI_AO_Select 0x09
enum AI_AO_Select_Bits {
AI_DMA_Select_Shift = 0,
AI_DMA_Select_Mask = 0xf,
AO_DMA_Select_Shift = 4,
AO_DMA_Select_Mask = 0xf << AO_DMA_Select_Shift
};
#define G0_G1_Select 0x0b
static inline unsigned ni_stc_dma_channel_select_bitfield(unsigned channel)
{
if (channel < 4)
return 1 << channel;
if (channel == 4)
return 0x3;
if (channel == 5)
return 0x5;
BUG();
return 0;
}
static inline unsigned GPCT_DMA_Select_Bits(unsigned gpct_index,
unsigned mite_channel)
{
BUG_ON(gpct_index > 1);
return ni_stc_dma_channel_select_bitfield(mite_channel) << (4 *
gpct_index);
}
static inline unsigned GPCT_DMA_Select_Mask(unsigned gpct_index)
{
BUG_ON(gpct_index > 1);
return 0xf << (4 * gpct_index);
}
/* 16 bit registers */
#define Configuration_Memory_Low 0x10
enum Configuration_Memory_Low_Bits {
AI_DITHER = 0x200,
AI_LAST_CHANNEL = 0x8000,
};
#define Configuration_Memory_High 0x12
enum Configuration_Memory_High_Bits {
AI_AC_COUPLE = 0x800,
AI_DIFFERENTIAL = 0x1000,
AI_COMMON = 0x2000,
AI_GROUND = 0x3000,
};
static inline unsigned int AI_CONFIG_CHANNEL(unsigned int channel)
{
return (channel & 0x3f);
}
#define ADC_FIFO_Data_Register 0x1c
#define AO_Configuration 0x16
#define AO_Bipolar _bit0
#define AO_Deglitch _bit1
#define AO_Ext_Ref _bit2
#define AO_Ground_Ref _bit3
#define AO_Channel(x) ((x) << 8)
#define DAC_FIFO_Data 0x1e
#define DAC0_Direct_Data 0x18
#define DAC1_Direct_Data 0x1a
/* 611x registers (these boards differ from the e-series) */
#define Magic_611x 0x19 /* w8 (new) */
#define Calibration_Channel_Select_611x 0x1a /* w16 (new) */
#define ADC_FIFO_Data_611x 0x1c /* r32 (incompatible) */
#define AI_FIFO_Offset_Load_611x 0x05 /* r8 (new) */
#define DAC_FIFO_Data_611x 0x14 /* w32 (incompatible) */
#define Cal_Gain_Select_611x 0x05 /* w8 (new) */
#define AO_Window_Address_611x 0x18
#define AO_Window_Data_611x 0x1e
/* 6143 registers */
#define Magic_6143 0x19 /* w8 */
#define G0G1_DMA_Select_6143 0x0B /* w8 */
#define PipelineDelay_6143 0x1f /* w8 */
#define EOC_Set_6143 0x1D /* w8 */
#define AIDMA_Select_6143 0x09 /* w8 */
#define AIFIFO_Data_6143 0x8C /* w32 */
#define AIFIFO_Flag_6143 0x84 /* w32 */
#define AIFIFO_Control_6143 0x88 /* w32 */
#define AIFIFO_Status_6143 0x88 /* w32 */
#define AIFIFO_DMAThreshold_6143 0x90 /* w32 */
#define AIFIFO_Words_Available_6143 0x94 /* w32 */
#define Calibration_Channel_6143 0x42 /* w16 */
#define Calibration_LowTime_6143 0x20 /* w16 */
#define Calibration_HighTime_6143 0x22 /* w16 */
#define Relay_Counter_Load_Val__6143 0x4C /* w32 */
#define Signature_6143 0x50 /* w32 */
#define Release_Date_6143 0x54 /* w32 */
#define Release_Oldest_Date_6143 0x58 /* w32 */
#define Calibration_Channel_6143_RelayOn 0x8000 /* Calibration relay switch On */
#define Calibration_Channel_6143_RelayOff 0x4000 /* Calibration relay switch Off */
#define Calibration_Channel_Gnd_Gnd 0x00 /* Offset Calibration */
#define Calibration_Channel_2v5_Gnd 0x02 /* 2.5V Reference */
#define Calibration_Channel_Pwm_Gnd 0x05 /* +/- 5V Self Cal */
#define Calibration_Channel_2v5_Pwm 0x0a /* PWM Calibration */
#define Calibration_Channel_Pwm_Pwm 0x0d /* CMRR */
#define Calibration_Channel_Gnd_Pwm 0x0e /* PWM Calibration */
/* 671x, 611x registers */
/* 671xi, 611x windowed ao registers */
enum windowed_regs_67xx_61xx {
AO_Immediate_671x = 0x11, /* W 16 */
AO_Timed_611x = 0x10, /* W 16 */
AO_FIFO_Offset_Load_611x = 0x13, /* W32 */
AO_Later_Single_Point_Updates = 0x14, /* W 16 */
AO_Waveform_Generation_611x = 0x15, /* W 16 */
AO_Misc_611x = 0x16, /* W 16 */
AO_Calibration_Channel_Select_67xx = 0x17, /* W 16 */
AO_Configuration_2_67xx = 0x18, /* W 16 */
CAL_ADC_Command_67xx = 0x19, /* W 8 */
CAL_ADC_Status_67xx = 0x1a, /* R 8 */
CAL_ADC_Data_67xx = 0x1b, /* R 16 */
CAL_ADC_Config_Data_High_Word_67xx = 0x1c, /* RW 16 */
CAL_ADC_Config_Data_Low_Word_67xx = 0x1d, /* RW 16 */
};
static inline unsigned int DACx_Direct_Data_671x(int channel)
{
return channel;
}
enum AO_Misc_611x_Bits {
CLEAR_WG = 1,
};
enum cs5529_configuration_bits {
CSCFG_CAL_CONTROL_MASK = 0x7,
CSCFG_SELF_CAL_OFFSET = 0x1,
CSCFG_SELF_CAL_GAIN = 0x2,
CSCFG_SELF_CAL_OFFSET_GAIN = 0x3,
CSCFG_SYSTEM_CAL_OFFSET = 0x5,
CSCFG_SYSTEM_CAL_GAIN = 0x6,
CSCFG_DONE = 1 << 3,
CSCFG_POWER_SAVE_SELECT = 1 << 4,
CSCFG_PORT_MODE = 1 << 5,
CSCFG_RESET_VALID = 1 << 6,
CSCFG_RESET = 1 << 7,
CSCFG_UNIPOLAR = 1 << 12,
CSCFG_WORD_RATE_2180_CYCLES = 0x0 << 13,
CSCFG_WORD_RATE_1092_CYCLES = 0x1 << 13,
CSCFG_WORD_RATE_532_CYCLES = 0x2 << 13,
CSCFG_WORD_RATE_388_CYCLES = 0x3 << 13,
CSCFG_WORD_RATE_324_CYCLES = 0x4 << 13,
CSCFG_WORD_RATE_17444_CYCLES = 0x5 << 13,
CSCFG_WORD_RATE_8724_CYCLES = 0x6 << 13,
CSCFG_WORD_RATE_4364_CYCLES = 0x7 << 13,
CSCFG_WORD_RATE_MASK = 0x7 << 13,
CSCFG_LOW_POWER = 1 << 16,
};
static inline unsigned int CS5529_CONFIG_DOUT(int output)
{
return 1 << (18 + output);
}
static inline unsigned int CS5529_CONFIG_AOUT(int output)
{
return 1 << (22 + output);
}
enum cs5529_command_bits {
CSCMD_POWER_SAVE = 0x1,
CSCMD_REGISTER_SELECT_MASK = 0xe,
CSCMD_OFFSET_REGISTER = 0x0,
CSCMD_GAIN_REGISTER = 0x2,
CSCMD_CONFIG_REGISTER = 0x4,
CSCMD_READ = 0x10,
CSCMD_CONTINUOUS_CONVERSIONS = 0x20,
CSCMD_SINGLE_CONVERSION = 0x40,
CSCMD_COMMAND = 0x80,
};
enum cs5529_status_bits {
CSS_ADC_BUSY = 0x1,
CSS_OSC_DETECT = 0x2, /* indicates adc error */
CSS_OVERRANGE = 0x4,
};
#define SerDacLd(x) (0x08<<(x))
/*
This is stuff unique to the NI E series drivers,
but I thought I'd put it here anyway.
*/
enum { ai_gain_16 =
0, ai_gain_8, ai_gain_14, ai_gain_4, ai_gain_611x, ai_gain_622x,
ai_gain_628x, ai_gain_6143 };
enum caldac_enum { caldac_none = 0, mb88341, dac8800, dac8043, ad8522,
ad8804, ad8842, ad8804_debug
};
enum ni_reg_type {
ni_reg_normal = 0x0,
ni_reg_611x = 0x1,
ni_reg_6711 = 0x2,
ni_reg_6713 = 0x4,
ni_reg_67xx_mask = 0x6,
ni_reg_6xxx_mask = 0x7,
ni_reg_622x = 0x8,
ni_reg_625x = 0x10,
ni_reg_628x = 0x18,
ni_reg_m_series_mask = 0x18,
ni_reg_6143 = 0x20
};
static const comedi_lrange range_ni_E_ao_ext;
enum m_series_register_offsets {
M_Offset_CDIO_DMA_Select = 0x7, // write
M_Offset_SCXI_Status = 0x7, // read
M_Offset_AI_AO_Select = 0x9, // write, same offset as e-series
M_Offset_SCXI_Serial_Data_In = 0x9, // read
M_Offset_G0_G1_Select = 0xb, // write, same offset as e-series
M_Offset_Misc_Command = 0xf,
M_Offset_SCXI_Serial_Data_Out = 0x11,
M_Offset_SCXI_Control = 0x13,
M_Offset_SCXI_Output_Enable = 0x15,
M_Offset_AI_FIFO_Data = 0x1c,
M_Offset_Static_Digital_Output = 0x24, // write
M_Offset_Static_Digital_Input = 0x24, // read
M_Offset_DIO_Direction = 0x28,
M_Offset_Cal_PWM = 0x40,
M_Offset_AI_Config_FIFO_Data = 0x5e,
M_Offset_Interrupt_C_Enable = 0x88, // write
M_Offset_Interrupt_C_Status = 0x88, // read
M_Offset_Analog_Trigger_Control = 0x8c,
M_Offset_AO_Serial_Interrupt_Enable = 0xa0,
M_Offset_AO_Serial_Interrupt_Ack = 0xa1, // write
M_Offset_AO_Serial_Interrupt_Status = 0xa1, // read
M_Offset_AO_Calibration = 0xa3,
M_Offset_AO_FIFO_Data = 0xa4,
M_Offset_PFI_Filter = 0xb0,
M_Offset_RTSI_Filter = 0xb4,
M_Offset_SCXI_Legacy_Compatibility = 0xbc,
M_Offset_Interrupt_A_Ack = 0x104, // write
M_Offset_AI_Status_1 = 0x104, // read
M_Offset_Interrupt_B_Ack = 0x106, // write
M_Offset_AO_Status_1 = 0x106, // read
M_Offset_AI_Command_2 = 0x108, // write
M_Offset_G01_Status = 0x108, // read
M_Offset_AO_Command_2 = 0x10a,
M_Offset_AO_Status_2 = 0x10c, // read
M_Offset_G0_Command = 0x10c, // write
M_Offset_G1_Command = 0x10e, // write
M_Offset_G0_HW_Save = 0x110,
M_Offset_G0_HW_Save_High = 0x110,
M_Offset_AI_Command_1 = 0x110,
M_Offset_G0_HW_Save_Low = 0x112,
M_Offset_AO_Command_1 = 0x112,
M_Offset_G1_HW_Save = 0x114,
M_Offset_G1_HW_Save_High = 0x114,
M_Offset_G1_HW_Save_Low = 0x116,
M_Offset_AI_Mode_1 = 0x118,
M_Offset_G0_Save = 0x118,
M_Offset_G0_Save_High = 0x118,
M_Offset_AI_Mode_2 = 0x11a,
M_Offset_G0_Save_Low = 0x11a,
M_Offset_AI_SI_Load_A = 0x11c,
M_Offset_G1_Save = 0x11c,
M_Offset_G1_Save_High = 0x11c,
M_Offset_G1_Save_Low = 0x11e,
M_Offset_AI_SI_Load_B = 0x120, // write
M_Offset_AO_UI_Save = 0x120, // read
M_Offset_AI_SC_Load_A = 0x124, // write
M_Offset_AO_BC_Save = 0x124, // read
M_Offset_AI_SC_Load_B = 0x128, // write
M_Offset_AO_UC_Save = 0x128, //read
M_Offset_AI_SI2_Load_A = 0x12c,
M_Offset_AI_SI2_Load_B = 0x130,
M_Offset_G0_Mode = 0x134,
M_Offset_G1_Mode = 0x136, // write
M_Offset_Joint_Status_1 = 0x136, // read
M_Offset_G0_Load_A = 0x138,
M_Offset_Joint_Status_2 = 0x13a,
M_Offset_G0_Load_B = 0x13c,
M_Offset_G1_Load_A = 0x140,
M_Offset_G1_Load_B = 0x144,
M_Offset_G0_Input_Select = 0x148,
M_Offset_G1_Input_Select = 0x14a,
M_Offset_AO_Mode_1 = 0x14c,
M_Offset_AO_Mode_2 = 0x14e,
M_Offset_AO_UI_Load_A = 0x150,
M_Offset_AO_UI_Load_B = 0x154,
M_Offset_AO_BC_Load_A = 0x158,
M_Offset_AO_BC_Load_B = 0x15c,
M_Offset_AO_UC_Load_A = 0x160,
M_Offset_AO_UC_Load_B = 0x164,
M_Offset_Clock_and_FOUT = 0x170,
M_Offset_IO_Bidirection_Pin = 0x172,
M_Offset_RTSI_Trig_Direction = 0x174,
M_Offset_Interrupt_Control = 0x176,
M_Offset_AI_Output_Control = 0x178,
M_Offset_Analog_Trigger_Etc = 0x17a,
M_Offset_AI_START_STOP_Select = 0x17c,
M_Offset_AI_Trigger_Select = 0x17e,
M_Offset_AI_SI_Save = 0x180, // read
M_Offset_AI_DIV_Load_A = 0x180, // write
M_Offset_AI_SC_Save = 0x184, // read
M_Offset_AO_Start_Select = 0x184, // write
M_Offset_AO_Trigger_Select = 0x186,
M_Offset_AO_Mode_3 = 0x18c,
M_Offset_G0_Autoincrement = 0x188,
M_Offset_G1_Autoincrement = 0x18a,
M_Offset_Joint_Reset = 0x190,
M_Offset_Interrupt_A_Enable = 0x192,
M_Offset_Interrupt_B_Enable = 0x196,
M_Offset_AI_Personal = 0x19a,
M_Offset_AO_Personal = 0x19c,
M_Offset_RTSI_Trig_A_Output = 0x19e,
M_Offset_RTSI_Trig_B_Output = 0x1a0,
M_Offset_RTSI_Shared_MUX = 0x1a2,
M_Offset_AO_Output_Control = 0x1ac,
M_Offset_AI_Mode_3 = 0x1ae,
M_Offset_Configuration_Memory_Clear = 0x1a4,
M_Offset_AI_FIFO_Clear = 0x1a6,
M_Offset_AO_FIFO_Clear = 0x1a8,
M_Offset_G0_Counting_Mode = 0x1b0,
M_Offset_G1_Counting_Mode = 0x1b2,
M_Offset_G0_Second_Gate = 0x1b4,
M_Offset_G1_Second_Gate = 0x1b6,
M_Offset_G0_DMA_Config = 0x1b8, // write
M_Offset_G0_DMA_Status = 0x1b8, // read
M_Offset_G1_DMA_Config = 0x1ba, // write
M_Offset_G1_DMA_Status = 0x1ba, // read
M_Offset_G0_MSeries_ABZ = 0x1c0,
M_Offset_G1_MSeries_ABZ = 0x1c2,
M_Offset_Clock_and_Fout2 = 0x1c4,
M_Offset_PLL_Control = 0x1c6,
M_Offset_PLL_Status = 0x1c8,
M_Offset_PFI_Output_Select_1 = 0x1d0,
M_Offset_PFI_Output_Select_2 = 0x1d2,
M_Offset_PFI_Output_Select_3 = 0x1d4,
M_Offset_PFI_Output_Select_4 = 0x1d6,
M_Offset_PFI_Output_Select_5 = 0x1d8,
M_Offset_PFI_Output_Select_6 = 0x1da,
M_Offset_PFI_DI = 0x1dc,
M_Offset_PFI_DO = 0x1de,
M_Offset_AI_Config_FIFO_Bypass = 0x218,
M_Offset_SCXI_DIO_Enable = 0x21c,
M_Offset_CDI_FIFO_Data = 0x220, // read
M_Offset_CDO_FIFO_Data = 0x220, // write
M_Offset_CDIO_Status = 0x224, // read
M_Offset_CDIO_Command = 0x224, // write
M_Offset_CDI_Mode = 0x228,
M_Offset_CDO_Mode = 0x22c,
M_Offset_CDI_Mask_Enable = 0x230,
M_Offset_CDO_Mask_Enable = 0x234,
};
static inline int M_Offset_AO_Waveform_Order(int channel)
{
return 0xc2 + 0x4 * channel;
};
static inline int M_Offset_AO_Config_Bank(int channel)
{
return 0xc3 + 0x4 * channel;
};
static inline int M_Offset_DAC_Direct_Data(int channel)
{
return 0xc0 + 0x4 * channel;
}
static inline int M_Offset_Gen_PWM(int channel)
{
return 0x44 + 0x2 * channel;
}
static inline int M_Offset_Static_AI_Control(int i)
{
int offset[] = {
0x64,
0x261,
0x262,
0x263,
};
if (((unsigned)i) >= sizeof(offset) / sizeof(offset[0])) {
rt_printk("%s: invalid channel=%i\n", __FUNCTION__, i);
return offset[0];
}
return offset[i];
};
static inline int M_Offset_AO_Reference_Attenuation(int channel)
{
int offset[] = {
0x264,
0x265,
0x266,
0x267
};
if (((unsigned)channel) >= sizeof(offset) / sizeof(offset[0])) {
rt_printk("%s: invalid channel=%i\n", __FUNCTION__, channel);
return offset[0];
}
return offset[channel];
};
static inline unsigned M_Offset_PFI_Output_Select(unsigned n)
{
if (n < 1 || n > NUM_PFI_OUTPUT_SELECT_REGS) {
rt_printk("%s: invalid pfi output select register=%i\n",
__FUNCTION__, n);
return M_Offset_PFI_Output_Select_1;
}
return M_Offset_PFI_Output_Select_1 + (n - 1) * 2;
}
enum MSeries_AI_Config_FIFO_Data_Bits {
MSeries_AI_Config_Channel_Type_Mask = 0x7 << 6,
MSeries_AI_Config_Channel_Type_Calibration_Bits = 0x0,
MSeries_AI_Config_Channel_Type_Differential_Bits = 0x1 << 6,
MSeries_AI_Config_Channel_Type_Common_Ref_Bits = 0x2 << 6,
MSeries_AI_Config_Channel_Type_Ground_Ref_Bits = 0x3 << 6,
MSeries_AI_Config_Channel_Type_Aux_Bits = 0x5 << 6,
MSeries_AI_Config_Channel_Type_Ghost_Bits = 0x7 << 6,
MSeries_AI_Config_Polarity_Bit = 0x1000, // 0 for 2's complement encoding
MSeries_AI_Config_Dither_Bit = 0x2000,
MSeries_AI_Config_Last_Channel_Bit = 0x4000,
};
static inline unsigned MSeries_AI_Config_Channel_Bits(unsigned channel)
{
return channel & 0xf;
}
static inline unsigned MSeries_AI_Config_Bank_Bits(enum ni_reg_type reg_type,
unsigned channel)
{
unsigned bits = channel & 0x30;
if (reg_type == ni_reg_622x) {
if (channel & 0x40)
bits |= 0x400;
}
return bits;
}
static inline unsigned MSeries_AI_Config_Gain_Bits(unsigned range)
{
return (range & 0x7) << 9;
}
enum MSeries_Clock_and_Fout2_Bits {
MSeries_PLL_In_Source_Select_RTSI0_Bits = 0xb,
MSeries_PLL_In_Source_Select_Star_Trigger_Bits = 0x14,
MSeries_PLL_In_Source_Select_RTSI7_Bits = 0x1b,
MSeries_PLL_In_Source_Select_PXI_Clock10 = 0x1d,
MSeries_PLL_In_Source_Select_Mask = 0x1f,
MSeries_Timebase1_Select_Bit = 0x20, // use PLL for timebase 1
MSeries_Timebase3_Select_Bit = 0x40, // use PLL for timebase 3
/* use 10MHz instead of 20MHz for RTSI clock frequency. Appears
to have no effect, at least on pxi-6281, which always uses
20MHz rtsi clock frequency */
MSeries_RTSI_10MHz_Bit = 0x80
};
static inline unsigned MSeries_PLL_In_Source_Select_RTSI_Bits(unsigned
RTSI_channel)
{
if (RTSI_channel > 7) {
rt_printk("%s: bug, invalid RTSI_channel=%i\n", __FUNCTION__,
RTSI_channel);
return 0;
}
if (RTSI_channel == 7)
return MSeries_PLL_In_Source_Select_RTSI7_Bits;
else
return MSeries_PLL_In_Source_Select_RTSI0_Bits + RTSI_channel;
}
enum MSeries_PLL_Control_Bits {
MSeries_PLL_Enable_Bit = 0x1000,
MSeries_PLL_VCO_Mode_200_325MHz_Bits = 0x0,
MSeries_PLL_VCO_Mode_175_225MHz_Bits = 0x2000,
MSeries_PLL_VCO_Mode_100_225MHz_Bits = 0x4000,
MSeries_PLL_VCO_Mode_75_150MHz_Bits = 0x6000,
};
static inline unsigned MSeries_PLL_Divisor_Bits(unsigned divisor)
{
static const unsigned max_divisor = 0x10;
if (divisor < 1 || divisor > max_divisor) {
rt_printk("%s: bug, invalid divisor=%i\n", __FUNCTION__,
divisor);
return 0;
}
return (divisor & 0xf) << 8;
}
static inline unsigned MSeries_PLL_Multiplier_Bits(unsigned multiplier)
{
static const unsigned max_multiplier = 0x100;
if (multiplier < 1 || multiplier > max_multiplier) {
rt_printk("%s: bug, invalid multiplier=%i\n", __FUNCTION__,
multiplier);
return 0;
}
return multiplier & 0xff;
}
enum MSeries_PLL_Status {
MSeries_PLL_Locked_Bit = 0x1
};
enum MSeries_AI_Config_FIFO_Bypass_Bits {
MSeries_AI_Bypass_Channel_Mask = 0x7,
MSeries_AI_Bypass_Bank_Mask = 0x78,
MSeries_AI_Bypass_Cal_Sel_Pos_Mask = 0x380,
MSeries_AI_Bypass_Cal_Sel_Neg_Mask = 0x1c00,
MSeries_AI_Bypass_Mode_Mux_Mask = 0x6000,
MSeries_AO_Bypass_AO_Cal_Sel_Mask = 0x38000,
MSeries_AI_Bypass_Gain_Mask = 0x1c0000,
MSeries_AI_Bypass_Dither_Bit = 0x200000,
MSeries_AI_Bypass_Polarity_Bit = 0x400000, // 0 for 2's complement encoding
MSeries_AI_Bypass_Config_FIFO_Bit = 0x80000000
};
static inline unsigned MSeries_AI_Bypass_Cal_Sel_Pos_Bits(int
calibration_source)
{
return (calibration_source << 7) & MSeries_AI_Bypass_Cal_Sel_Pos_Mask;
}
static inline unsigned MSeries_AI_Bypass_Cal_Sel_Neg_Bits(int
calibration_source)
{
return (calibration_source << 10) & MSeries_AI_Bypass_Cal_Sel_Pos_Mask;
}
static inline unsigned MSeries_AI_Bypass_Gain_Bits(int gain)
{
return (gain << 18) & MSeries_AI_Bypass_Gain_Mask;
}
enum MSeries_AO_Config_Bank_Bits {
MSeries_AO_DAC_Offset_Select_Mask = 0x7,
MSeries_AO_DAC_Offset_0V_Bits = 0x0,
MSeries_AO_DAC_Offset_5V_Bits = 0x1,
MSeries_AO_DAC_Reference_Mask = 0x38,
MSeries_AO_DAC_Reference_10V_Internal_Bits = 0x0,
MSeries_AO_DAC_Reference_5V_Internal_Bits = 0x8,
MSeries_AO_Update_Timed_Bit = 0x40,
MSeries_AO_Bipolar_Bit = 0x80 // turns on 2's complement encoding
};
enum MSeries_AO_Reference_Attenuation_Bits {
MSeries_Attenuate_x5_Bit = 0x1
};
static inline unsigned MSeries_Cal_PWM_High_Time_Bits(unsigned count)
{
return (count << 16) & 0xffff0000;
}
static inline unsigned MSeries_Cal_PWM_Low_Time_Bits(unsigned count)
{
return count & 0xffff;
}
static inline unsigned MSeries_PFI_Output_Select_Mask(unsigned channel)
{
return 0x1f << (channel % 3) * 5;
};
static inline unsigned MSeries_PFI_Output_Select_Bits(unsigned channel,
unsigned source)
{
return (source & 0x1f) << ((channel % 3) * 5);
};
// inverse to MSeries_PFI_Output_Select_Bits
static inline unsigned MSeries_PFI_Output_Select_Source(unsigned channel,
unsigned bits)
{
return (bits >> ((channel % 3) * 5)) & 0x1f;
};
enum MSeries_Gi_DMA_Config_Bits {
Gi_DMA_BankSW_Error_Bit = 0x10,
Gi_DMA_Reset_Bit = 0x8,
Gi_DMA_Int_Enable_Bit = 0x4,
Gi_DMA_Write_Bit = 0x2,
Gi_DMA_Enable_Bit = 0x1,
};
static inline unsigned MSeries_PFI_Filter_Select_Mask(unsigned channel)
{
return 0x3 << (channel * 2);
}
static inline unsigned MSeries_PFI_Filter_Select_Bits(unsigned channel,
unsigned filter)
{
return (filter << (channel *
2)) & MSeries_PFI_Filter_Select_Mask(channel);
}
enum CDIO_DMA_Select_Bits {
CDI_DMA_Select_Shift = 0,
CDI_DMA_Select_Mask = 0xf,
CDO_DMA_Select_Shift = 4,
CDO_DMA_Select_Mask = 0xf << CDO_DMA_Select_Shift
};
enum CDIO_Status_Bits {
CDO_FIFO_Empty_Bit = 0x1,
CDO_FIFO_Full_Bit = 0x2,
CDO_FIFO_Request_Bit = 0x4,
CDO_Overrun_Bit = 0x8,
CDO_Underflow_Bit = 0x10,
CDI_FIFO_Empty_Bit = 0x10000,
CDI_FIFO_Full_Bit = 0x20000,
CDI_FIFO_Request_Bit = 0x40000,
CDI_Overrun_Bit = 0x80000,
CDI_Overflow_Bit = 0x100000
};
enum CDIO_Command_Bits {
CDO_Disarm_Bit = 0x1,
CDO_Arm_Bit = 0x2,
CDI_Disarm_Bit = 0x4,
CDI_Arm_Bit = 0x8,
CDO_Reset_Bit = 0x10,
CDI_Reset_Bit = 0x20,
CDO_Error_Interrupt_Enable_Set_Bit = 0x40,
CDO_Error_Interrupt_Enable_Clear_Bit = 0x80,
CDI_Error_Interrupt_Enable_Set_Bit = 0x100,
CDI_Error_Interrupt_Enable_Clear_Bit = 0x200,
CDO_FIFO_Request_Interrupt_Enable_Set_Bit = 0x400,
CDO_FIFO_Request_Interrupt_Enable_Clear_Bit = 0x800,
CDI_FIFO_Request_Interrupt_Enable_Set_Bit = 0x1000,
CDI_FIFO_Request_Interrupt_Enable_Clear_Bit = 0x2000,
CDO_Error_Interrupt_Confirm_Bit = 0x4000,
CDI_Error_Interrupt_Confirm_Bit = 0x8000,
CDO_Empty_FIFO_Interrupt_Enable_Set_Bit = 0x10000,
CDO_Empty_FIFO_Interrupt_Enable_Clear_Bit = 0x20000,
CDO_SW_Update_Bit = 0x80000,
CDI_SW_Update_Bit = 0x100000
};
enum CDI_Mode_Bits {
CDI_Sample_Source_Select_Mask = 0x3f,
CDI_Halt_On_Error_Bit = 0x200,
CDI_Polarity_Bit = 0x400, // sample clock on falling edge
CDI_FIFO_Mode_Bit = 0x800, // set for half full mode, clear for not empty mode
CDI_Data_Lane_Mask = 0x3000, // data lanes specify which dio channels map to byte or word accesses to the dio fifos
CDI_Data_Lane_0_15_Bits = 0x0,
CDI_Data_Lane_16_31_Bits = 0x1000,
CDI_Data_Lane_0_7_Bits = 0x0,
CDI_Data_Lane_8_15_Bits = 0x1000,
CDI_Data_Lane_16_23_Bits = 0x2000,
CDI_Data_Lane_24_31_Bits = 0x3000
};
enum CDO_Mode_Bits {
CDO_Sample_Source_Select_Mask = 0x3f,
CDO_Retransmit_Bit = 0x100,
CDO_Halt_On_Error_Bit = 0x200,
CDO_Polarity_Bit = 0x400, // sample clock on falling edge
CDO_FIFO_Mode_Bit = 0x800, // set for half full mode, clear for not full mode
CDO_Data_Lane_Mask = 0x3000, // data lanes specify which dio channels map to byte or word accesses to the dio fifos
CDO_Data_Lane_0_15_Bits = 0x0,
CDO_Data_Lane_16_31_Bits = 0x1000,
CDO_Data_Lane_0_7_Bits = 0x0,
CDO_Data_Lane_8_15_Bits = 0x1000,
CDO_Data_Lane_16_23_Bits = 0x2000,
CDO_Data_Lane_24_31_Bits = 0x3000
};
enum Interrupt_C_Enable_Bits {
Interrupt_Group_C_Enable_Bit = 0x1
};
enum Interrupt_C_Status_Bits {
Interrupt_Group_C_Status_Bit = 0x1
};
#define M_SERIES_EEPROM_SIZE 1024
typedef struct ni_board_struct {
int device_id;
int isapnp_id;
char *name;
int n_adchan;
int adbits;
int ai_fifo_depth;
unsigned int alwaysdither:1;
int gainlkup;
int ai_speed;
int n_aochan;
int aobits;
int ao_fifo_depth;
const comedi_lrange *ao_range_table;
unsigned ao_speed;
unsigned num_p0_dio_channels;
int reg_type;
unsigned int ao_unipolar:1;
unsigned int has_8255:1;
unsigned int has_analog_trig:1;
enum caldac_enum caldac[3];
} ni_board;
#define n_ni_boards (sizeof(ni_boards)/sizeof(ni_board))
#define boardtype (*(ni_board *)dev->board_ptr)
#define MAX_N_AO_CHAN 8
#define NUM_GPCT 2
#define NI_PRIVATE_COMMON \
uint16_t (*stc_readw)(comedi_device *dev, int register); \
uint32_t (*stc_readl)(comedi_device *dev, int register); \
void (*stc_writew)(comedi_device *dev, uint16_t value, int register); \
void (*stc_writel)(comedi_device *dev, uint32_t value, int register); \
\
unsigned short dio_output; \
unsigned short dio_control; \
int ao0p,ao1p; \
int lastchan; \
int last_do; \
int rt_irq; \
int irqmask; \
int aimode; \
int ai_continuous; \
int blocksize; \
int n_left; \
unsigned int ai_calib_source; \
unsigned int ai_calib_source_enabled; \
spinlock_t window_lock; \
spinlock_t soft_reg_copy_lock; \
spinlock_t mite_channel_lock; \
\
int changain_state; \
unsigned int changain_spec; \
\
unsigned int caldac_maxdata_list[MAX_N_CALDACS]; \
unsigned short ao[MAX_N_AO_CHAN]; \
unsigned short caldacs[MAX_N_CALDACS]; \
\
unsigned short ai_cmd2; \
\
unsigned short ao_conf[MAX_N_AO_CHAN]; \
unsigned short ao_mode1; \
unsigned short ao_mode2; \
unsigned short ao_mode3; \
unsigned short ao_cmd1; \
unsigned short ao_cmd2; \
unsigned short ao_cmd3; \
unsigned short ao_trigger_select; \
\
struct ni_gpct_device *counter_dev; \
unsigned short an_trig_etc_reg; \
\
unsigned ai_offset[512]; \
\
unsigned long serial_interval_ns; \
unsigned char serial_hw_mode; \
unsigned short clock_and_fout; \
unsigned short clock_and_fout2; \
\
unsigned short int_a_enable_reg; \
unsigned short int_b_enable_reg; \
unsigned short io_bidirection_pin_reg; \
unsigned short rtsi_trig_direction_reg; \
unsigned short rtsi_trig_a_output_reg; \
unsigned short rtsi_trig_b_output_reg; \
unsigned short pfi_output_select_reg[NUM_PFI_OUTPUT_SELECT_REGS]; \
unsigned short ai_ao_select_reg; \
unsigned short g0_g1_select_reg; \
unsigned short cdio_dma_select_reg; \
\
unsigned clock_ns; \
unsigned clock_source; \
\
unsigned short atrig_mode; \
unsigned short atrig_high; \
unsigned short atrig_low; \
\
unsigned short pwm_up_count; \
unsigned short pwm_down_count; \
\
sampl_t ai_fifo_buffer[0x2000]; \
uint8_t eeprom_buffer[M_SERIES_EEPROM_SIZE]; \
\
struct mite_struct *mite; \
struct mite_channel *ai_mite_chan; \
struct mite_channel *ao_mite_chan;\
struct mite_channel *cdo_mite_chan;\
struct mite_dma_descriptor_ring *ai_mite_ring; \
struct mite_dma_descriptor_ring *ao_mite_ring; \
struct mite_dma_descriptor_ring *cdo_mite_ring; \
struct mite_dma_descriptor_ring *gpct_mite_ring[NUM_GPCT];
#endif /* _COMEDI_NI_STC_H */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment