📄 adv_pci_dio.c
字号:
#define devpriv ((pci_dio_private *)dev->private)#define this_board ((boardtype *)dev->board_ptr)/*==============================================================================*/static int pci_dio_insn_bits_di_b(comedi_device *dev, comedi_subdevice *s, comedi_insn *insn, lsampl_t *data){ diosubd_data *d=(diosubd_data *)s->private; int i; data[1]=0; for (i=0; i<d->regs;i++) { data[1]|=inb(dev->iobase+d->addr+i)<<(8*i); } return 2;}/*==============================================================================*/static int pci_dio_insn_bits_di_w(comedi_device *dev, comedi_subdevice *s, comedi_insn *insn, lsampl_t *data){ diosubd_data *d=(diosubd_data *)s->private; int i; data[1]=0; for (i=0; i<d->regs; i++) data[1]|=inw(dev->iobase+d->addr+2*i)<<(16*i); return 2;}/*==============================================================================*/static int pci_dio_insn_bits_do_b(comedi_device *dev, comedi_subdevice *s, comedi_insn *insn, lsampl_t *data){ diosubd_data *d=(diosubd_data *)s->private; int i; if (data[0]) { s->state &= ~data[0]; s->state |= (data[0]&data[1]); for (i=0; i<d->regs; i++) outb((s->state>>(8*i))&0xff, dev->iobase+d->addr+i); } data[1] = s->state; return 2;}/*==============================================================================*/static int pci_dio_insn_bits_do_w(comedi_device *dev, comedi_subdevice *s, comedi_insn *insn,lsampl_t *data){ diosubd_data *d=(diosubd_data *)s->private; int i; if (data[0]) { s->state &= ~data[0]; s->state |= (data[0]&data[1]); for (i=0; i<d->regs; i++) outw((s->state>>(16*i))&0xffff, dev->iobase+d->addr+2*i); } data[1] = s->state; return 2;}/*==============================================================================*/static int pci1760_mbxrequest(comedi_device *dev, comedi_subdevice *s, unsigned char *omb, unsigned char *imb, int repeats){ int cnt, tout, ok=0; for (cnt=0; cnt<repeats; cnt++) { outb(omb[0], dev->iobase+OMB0); outb(omb[1], dev->iobase+OMB1); outb(omb[2], dev->iobase+OMB2); outb(omb[3], dev->iobase+OMB3); for(tout=0; tout<251; tout++) { if ((imb[2]=inb(dev->iobase+IMB2))==omb[2]) { imb[0]=inb(dev->iobase+IMB0); imb[1]=inb(dev->iobase+IMB1); imb[3]=inb(dev->iobase+IMB3); ok=1; break; } comedi_udelay(1); } if (ok) return 0; } comedi_error(dev, "PCI-1760 mailbox request timeout!"); return -ETIME;}/*==============================================================================*/static int pci1760_insn_bits_di(comedi_device *dev, comedi_subdevice *s, comedi_insn *insn, lsampl_t *data){ int ret; unsigned char omb[4]={ 0x00, 0x00, CMD_ClearIMB2, 0x00}; unsigned char imb[4]; if (!(ret=pci1760_mbxrequest(dev, s, omb, imb, OMBCMD_RETRY))) return ret; data[1]=imb[3]; return 2;}/*==============================================================================*/static int pci1760_insn_read_di(comedi_device *dev, comedi_subdevice *s, comedi_insn *insn, lsampl_t *data){ int ret, n; unsigned char omb[4]={ 0x00, 0x00, CMD_ClearIMB2, 0x00}; unsigned char imb[4]; for (n=0; n<insn->n; n++) { if (!(ret=pci1760_mbxrequest(dev, s, omb, imb, OMBCMD_RETRY))) return ret; data[n] = imb[3]; } return n;}/*==============================================================================*/static int pci1760_insn_bits_do(comedi_device *dev, comedi_subdevice *s, comedi_insn *insn, lsampl_t *data){ int ret; unsigned char omb[4]={ 0x00, 0x00, CMD_SetRelaysOutput, 0x00}; unsigned char imb[4]; if (data[0]) { s->state &= ~data[0]; s->state |= (data[0]&data[1]); omb[0] = s->state; if (!(ret=pci1760_mbxrequest(dev, s, omb, imb, OMBCMD_RETRY))) return ret; } data[1] = s->state; return 2;}/*==============================================================================*/static int pci1760_insn_cnt_read(comedi_device *dev, comedi_subdevice *s, comedi_insn *insn, lsampl_t *data){ int ret, n; unsigned char omb[4]={ CR_CHAN(insn->chanspec)&0x07, 0x00, CMD_GetIDICntCurValue, 0x00}; unsigned char imb[4]; for (n=0; n<insn->n; n++) { if (!(ret=pci1760_mbxrequest(dev, s, omb, imb, OMBCMD_RETRY))) return ret; data[n] = (imb[1]<<8) + imb[0]; } return n;}/*==============================================================================*/static int pci1760_insn_cnt_write(comedi_device *dev, comedi_subdevice *s, comedi_insn *insn, lsampl_t *data){ int ret; unsigned char chan=CR_CHAN(insn->chanspec)&0x07; unsigned char bitmask=1<<chan; unsigned char omb[4]={ data[0]&0xff, (data[0]>>8)&0xff, CMD_SetIDI0CntResetValue+chan, 0x00}; unsigned char imb[4]; if (devpriv->CntResValue[chan] != (data[0]&0xffff)) { // Set reset value if different if (!(ret=pci1760_mbxrequest(dev, s, omb, imb, OMBCMD_RETRY))) return ret; devpriv->CntResValue[chan] = data[0]&0xffff; } omb[0] = bitmask; // reset counter to it reset value omb[2] = CMD_ResetIDICounters; if (!(ret=pci1760_mbxrequest(dev, s, omb, imb, OMBCMD_RETRY))) return ret; if (!(bitmask & devpriv->IDICntEnable)) { // start counter if it don't run omb[0] = bitmask; omb[2] = CMD_EnableIDICounters; if (!(ret=pci1760_mbxrequest(dev, s, omb, imb, OMBCMD_RETRY))) return ret; devpriv->IDICntEnable |= bitmask; } return 1;}/*==============================================================================*/static int pci1760_reset(comedi_device *dev){ int i; unsigned char omb[4]={0x00, 0x00, 0x00, 0x00 }; unsigned char imb[4]; outb(0, dev->iobase+INTCSR0); // disable IRQ outb(0, dev->iobase+INTCSR1); outb(0, dev->iobase+INTCSR2); outb(0, dev->iobase+INTCSR3); devpriv->GlobalIrqEnabled = 0; omb[0] = 0x00; omb[2] = CMD_SetRelaysOutput; // reset relay outputs pci1760_mbxrequest(dev, NULL, omb, imb, OMBCMD_RETRY); omb[0] = 0x00; omb[2] = CMD_EnableIDICounters; // disable IDI up counters pci1760_mbxrequest(dev, NULL, omb, imb, OMBCMD_RETRY); devpriv->IDICntEnable = 0; omb[0] = 0x00; omb[2] = CMD_OverflowIDICounters; // disable counters overflow interrupts pci1760_mbxrequest(dev, NULL, omb, imb, OMBCMD_RETRY); devpriv->IDICntOverEnable = 0; omb[0] = 0x00; omb[2] = CMD_MatchIntIDICounters; // disable counters match value interrupts pci1760_mbxrequest(dev, NULL, omb, imb, OMBCMD_RETRY); devpriv->IDICntMatchEnable = 0; omb[0] = 0x00; omb[1] = 0x80; for (i=0; i<8; i++) { // set IDI up counters match value omb[2] = CMD_SetIDI0CntMatchValue+i; pci1760_mbxrequest(dev, NULL, omb, imb, OMBCMD_RETRY); devpriv->CntMatchValue[i] = 0x8000; } omb[0] = 0x00; omb[1] = 0x00; for (i=0; i<8; i++) { // set IDI up counters reset value omb[2] = CMD_SetIDI0CntResetValue+i; pci1760_mbxrequest(dev, NULL, omb, imb, OMBCMD_RETRY); devpriv->CntResValue[i] = 0x0000; } omb[0] = 0xff; omb[2] = CMD_ResetIDICounters; // reset IDI up counters to reset values pci1760_mbxrequest(dev, NULL, omb, imb, OMBCMD_RETRY); omb[0] = 0x00; omb[2] = CMD_EdgeIDICounters; // set IDI up counters count edge pci1760_mbxrequest(dev, NULL, omb, imb, OMBCMD_RETRY); devpriv->IDICntEdge = 0x00; omb[0] = 0x00; omb[2] = CMD_EnableIDIFilters; // disable all digital in filters pci1760_mbxrequest(dev, NULL, omb, imb, OMBCMD_RETRY); devpriv->IDIFiltersEn = 0x00; omb[0] = 0x00; omb[2] = CMD_EnableIDIPatternMatch; // disable pattern matching pci1760_mbxrequest(dev, NULL, omb, imb, OMBCMD_RETRY); devpriv->IDIPatMatchEn = 0x00; omb[0] = 0x00; omb[2] = CMD_SetIDIPatternMatch; // set pattern match value pci1760_mbxrequest(dev, NULL, omb, imb, OMBCMD_RETRY); devpriv->IDIPatMatchValue = 0x00; return 0;}/* ==============================================================================*/static int pci_dio_reset(comedi_device *dev){ DPRINTK("adv_pci_dio EDBG: BGN: pci171x_reset(...)\n"); switch (this_board->cardtype) { case TYPE_PCI1730: outb(0, dev->iobase+PCI1730_DO); // clear outputs outb(0, dev->iobase+PCI1730_DO+1); outb(0, dev->iobase+PCI1730_IDO); outb(0, dev->iobase+PCI1730_IDO+1); /* NO break there! */ case TYPE_PCI1733: outb(0, dev->iobase+PCI1730_3_INT_EN); // disable interrupts outb(0x0f, dev->iobase+PCI1730_3_INT_CLR);// clear interrupts outb(0, dev->iobase+PCI1730_3_INT_RF); // set rising edge trigger break; case TYPE_PCI1734: outb(0, dev->iobase+PCI1734_IDO); // clear outputs outb(0, dev->iobase+PCI1734_IDO+1); outb(0, dev->iobase+PCI1734_IDO+2); outb(0, dev->iobase+PCI1734_IDO+3); break; case TYPE_PCI1750: case TYPE_PCI1751: outb(0x88, dev->iobase+PCI1750_ICR); // disable & clear interrupts break; case TYPE_PCI1752: outw(0, dev->iobase+PCI1752_6_CFC); // disable channel freeze function outw(0, dev->iobase+PCI1752_IDO); // clear outputs
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -