From ce5cc4a10d7a0fe734f705b1ea3e9be72d8b2857 Mon Sep 17 00:00:00 2001 From: Frank Mori Hess Date: Fri, 19 Apr 2002 06:24:21 +0000 Subject: [PATCH] added delay that seems to fix unreliable dma abort. Fixed selection of bnc inputs for adc converts on 4020. --- comedi/drivers/cb_pcidas64.c | 50 ++++++++++++------------------------ 1 file changed, 16 insertions(+), 34 deletions(-) diff --git a/comedi/drivers/cb_pcidas64.c b/comedi/drivers/cb_pcidas64.c index afbdf55a..d555c7fb 100644 --- a/comedi/drivers/cb_pcidas64.c +++ b/comedi/drivers/cb_pcidas64.c @@ -760,10 +760,6 @@ static void init_plx9080(comedi_device *dev) DEBUG_PRINT(" plx dma channel 0 command status 0x%x\n", readb(plx_iobase + PLX_DMA0_CS_REG)); DEBUG_PRINT(" plx dma channel 0 threshold 0x%x\n", readl(plx_iobase + PLX_DMA0_THRESHOLD_REG)); - // disable interrupts - private(dev)->plx_intcsr_bits = 0; - writel(private(dev)->plx_intcsr_bits, plx_iobase + PLX_INTRCS_REG); - // disable dma channels writeb(0, plx_iobase + PLX_DMA0_CS_REG); writeb(0, plx_iobase + PLX_DMA1_CS_REG); @@ -830,7 +826,7 @@ static int setup_subdevices(comedi_device *dev) unsigned int i; uint8_t data; // set adc to read from inputs (not internal calibration sources) - private(dev)->i2c_cal_range_bits = ADC_SRC_BITS(1); + private(dev)->i2c_cal_range_bits = ADC_SRC_BITS(4); // set channels to +-5 volt input ranges for( i = 0; i < s->n_chan; i++) private(dev)->i2c_cal_range_bits |= ATTENUATE_BIT(i); @@ -1187,10 +1183,6 @@ static int ai_rinsn(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,lsa range = CR_RANGE(insn->chanspec); aref = CR_AREF(insn->chanspec); - // disable interrupts on plx 9080 XXX - private(dev)->plx_intcsr_bits = 0; - writel(private(dev)->plx_intcsr_bits, private(dev)->plx9080_iobase + PLX_INTRCS_REG); - // disable card's analog input interrupt sources private(dev)->intr_enable_bits &= ~EN_ADC_INTR_SRC_BIT & ~EN_ADC_DONE_INTR_BIT & ~EN_ADC_ACTIVE_INTR_BIT & ~EN_ADC_STOP_INTR_BIT & ~EN_ADC_OVERRUN_BIT; @@ -1252,7 +1244,7 @@ static int ai_rinsn(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,lsa private(dev)->i2c_cal_range_bits |= ADC_SRC_BITS(private(dev)->calibration_source); } else { //select BNC inputs - private(dev)->i2c_cal_range_bits |= ADC_SRC_BITS(1); + private(dev)->i2c_cal_range_bits |= ADC_SRC_BITS(4); } // select range if(ai_range_bits_4020[range]) @@ -1504,7 +1496,6 @@ static int ai_cmd(comedi_device *dev,comedi_subdevice *s) // make sure internal calibration source is turned off writew(0, private(dev)->main_iobase + CALIBRATION_REG); - // set conversion pacing check_adc_timing(cmd); if(cmd->convert_src == TRIG_TIMER) @@ -1585,7 +1576,6 @@ static int ai_cmd(comedi_device *dev,comedi_subdevice *s) private(dev)->dma_index = 0; // enable interrupts on plx 9080 - // XXX enabling more interrupt sources than are actually used private(dev)->plx_intcsr_bits |= ICS_AERR | ICS_PERR | ICS_PIE | ICS_PLIE | ICS_PAIE | ICS_LIE | ICS_DMA1_E; writel(private(dev)->plx_intcsr_bits, private(dev)->plx9080_iobase + PLX_INTRCS_REG); @@ -1657,8 +1647,6 @@ static int ai_cmd(comedi_device *dev,comedi_subdevice *s) writew(0, private(dev)->main_iobase + ADC_START_REG); DEBUG_PRINT("soft trig\n"); - DEBUG_PRINT("trying to start, hw status is 0x%x\n", readw(private(dev)->main_iobase + HW_STATUS_REG)); - return 0; } @@ -1820,8 +1808,7 @@ static void handle_interrupt(int irq, void *d, struct pt_regs *regs) ICS_DMA1_A | ICS_LDIA | ICS_LIA | ICS_PAIA | ICS_PDIA | ICS_MBIA(0) | ICS_MBIA(1) |ICS_MBIA(2) | ICS_MBIA(3); uint32_t plx_bits; - uint8_t dma0_status = readb(private(dev)->plx9080_iobase + PLX_DMA0_CS_REG); - uint8_t dma1_status = readb(private(dev)->plx9080_iobase + PLX_DMA1_CS_REG); + uint8_t dma0_status, dma1_status; plx_status = readl(private(dev)->plx9080_iobase + PLX_INTRCS_REG); status = readw(private(dev)->main_iobase + HW_STATUS_REG); @@ -1847,20 +1834,22 @@ static void handle_interrupt(int irq, void *d, struct pt_regs *regs) comedi_error(dev, "fifo overrun"); } + dma0_status = readb(private(dev)->plx9080_iobase + PLX_DMA0_CS_REG); if(plx_status & ICS_DMA0_A) { // dma chan 0 interrupt - DEBUG_PRINT("dma0 status 0x%x\n", dma0_status); // XXX possible race writeb((dma0_status & PLX_DMA_EN_BIT) | PLX_CLEAR_DMA_INTR_BIT, private(dev)->plx9080_iobase + PLX_DMA0_CS_REG); + DEBUG_PRINT("dma0 status 0x%x\n", dma0_status); DEBUG_PRINT(" cleared dma ch0 interrupt\n"); } + dma1_status = readb(private(dev)->plx9080_iobase + PLX_DMA1_CS_REG); if(plx_status & ICS_DMA1_A) // XXX { // dma chan 1 interrupt - DEBUG_PRINT("dma1 status 0x%x\n", dma1_status); // XXX possible race writeb((dma1_status & PLX_DMA_EN_BIT) | PLX_CLEAR_DMA_INTR_BIT, private(dev)->plx9080_iobase + PLX_DMA1_CS_REG); + DEBUG_PRINT("dma1 status 0x%x\n", dma1_status); if(dma1_status & PLX_DMA_EN_BIT) { @@ -1870,7 +1859,7 @@ static void handle_interrupt(int irq, void *d, struct pt_regs *regs) } // pio transfer XXX - if((status & ADC_INTR_PENDING_BIT) && (dma0_status & PLX_DMA_EN_BIT) == 0 && (dma1_status & PLX_DMA_EN_BIT) == 0) + if((status & ADC_INTR_PENDING_BIT) && (dma1_status & PLX_DMA_EN_BIT) == 0) { pio_drain_ai_fifo(dev); } @@ -1895,15 +1884,7 @@ static void handle_interrupt(int irq, void *d, struct pt_regs *regs) comedi_event(dev, s, async->events); - // XXX - plx_status = readl(private(dev)->plx9080_iobase + PLX_INTRCS_REG); - if((plx_status & plx_interrupt_status_mask)) - { - comedi_error(dev, "interrupt didn't clear? Disabling interrupts!"); - rt_printk("plx status 0x%x\n", plx_status); - private(dev)->plx_intcsr_bits = 0; - writel(private(dev)->plx_intcsr_bits, private(dev)->plx9080_iobase + PLX_INTRCS_REG); - } + DEBUG_PRINT("exiting handler\n"); return; } @@ -1939,6 +1920,7 @@ void abort_dma(comedi_device *dev, unsigned int channel) } // disable channel writeb(0, dma_cs_addr); + udelay(1); // abort channel writeb(PLX_DMA_ABORT_BIT, dma_cs_addr); // wait for dma done bit @@ -1960,10 +1942,6 @@ static int ai_cancel(comedi_device *dev, comedi_subdevice *s) ~ADC_INTR_SRC_MASK; writew(private(dev)->intr_enable_bits, private(dev)->main_iobase + INTR_ENABLE_REG); - // disable dma ch 1 interrupt on plx - private(dev)->plx_intcsr_bits &= ~ICS_DMA1_E; - writel(private(dev)->plx_intcsr_bits, private(dev)->plx9080_iobase + PLX_INTRCS_REG); - abort_dma(dev, 1); /* disable pacing, triggering, etc */ @@ -2289,11 +2267,14 @@ static int caldac_8800_write(comedi_device *dev, unsigned int address, uint8_t v for(bit = 1 << (bitstream_length - 1); bit; bit >>= 1) { - register_bits = SERIAL_CLOCK_BIT; + register_bits = 0; if(bitstream & bit) register_bits |= SERIAL_DATA_IN_BIT; udelay(1); writew(register_bits, private(dev)->main_iobase + CALIBRATION_REG); + register_bits |= SERIAL_CLOCK_BIT; + udelay(1); + writew(register_bits, private(dev)->main_iobase + CALIBRATION_REG); } udelay(1); @@ -2361,7 +2342,8 @@ static int caldac_i2c_write(comedi_device *dev, unsigned int caldac_channel, uns return -1; break; } - serial_bytes[1] = NOT_CLEAR_REGISTERS | ((value >> 8) & 0xf); + serial_bytes[1] = NOT_CLEAR_REGISTERS | UPDATE_ADDRESSED_DAC_ONLY | + ((value >> 8) & 0xf); serial_bytes[2] = value & 0xff; i2c_write(dev, i2c_addr, serial_bytes, 3); return 0; -- 2.26.2