void AIOP_PWM_Out::set_frequency(uint8_t ch, uint16_t hz) { QASSERT(m_is_initialized); uint16_t icr = timer_period(hz); switch(ch) { case 0: case 1: case 2: ICR3 = icr; break; case 6: case 7: ICR1 = icr; break; case 3: case 4: case 5: ICR4 = icr; break; } }
static int das16_cmd_exec(struct comedi_device *dev, struct comedi_subdevice *s) { const struct das16_board *board = comedi_board(dev); struct comedi_async *async = s->async; struct comedi_cmd *cmd = &async->cmd; unsigned int byte; unsigned long flags; int range; if (devpriv->dma_chan == 0 || (dev->irq == 0 && devpriv->timer_mode == 0)) { comedi_error(dev, "irq (or use of 'timer mode') dma required to " "execute comedi_cmd"); return -1; } if (cmd->flags & TRIG_RT) { comedi_error(dev, "isa dma transfers cannot be performed with " "TRIG_RT, aborting"); return -1; } devpriv->adc_byte_count = cmd->stop_arg * cmd->chanlist_len * sizeof(uint16_t); /* disable conversions for das1600 mode */ if (board->size > 0x400) outb(DAS1600_CONV_DISABLE, dev->iobase + DAS1600_CONV); /* set scan limits */ byte = CR_CHAN(cmd->chanlist[0]); byte |= CR_CHAN(cmd->chanlist[cmd->chanlist_len - 1]) << 4; outb(byte, dev->iobase + DAS16_MUX); /* set gain (this is also burst rate register but according to * computer boards manual, burst rate does nothing, even on * keithley cards) */ if (board->ai_pg != das16_pg_none) { range = CR_RANGE(cmd->chanlist[0]); outb((das16_gainlists[board->ai_pg])[range], dev->iobase + DAS16_GAIN); } /* set counter mode and counts */ cmd->convert_arg = das16_set_pacer(dev, cmd->convert_arg, cmd->flags & TRIG_ROUND_MASK); DEBUG_PRINT("pacer period: %d ns\n", cmd->convert_arg); /* enable counters */ byte = 0; /* Enable burst mode if appropriate. */ if (board->size > 0x400) { if (cmd->convert_src == TRIG_NOW) { outb(DAS1600_BURST_VAL, dev->iobase + DAS1600_BURST); /* set burst length */ byte |= BURST_LEN_BITS(cmd->chanlist_len - 1); } else { outb(0, dev->iobase + DAS1600_BURST); } } outb(byte, dev->iobase + DAS16_PACER); /* set up dma transfer */ flags = claim_dma_lock(); disable_dma(devpriv->dma_chan); /* clear flip-flop to make sure 2-byte registers for * count and address get set correctly */ clear_dma_ff(devpriv->dma_chan); devpriv->current_buffer = 0; set_dma_addr(devpriv->dma_chan, devpriv->dma_buffer_addr[devpriv->current_buffer]); /* set appropriate size of transfer */ devpriv->dma_transfer_size = das16_suggest_transfer_size(dev, *cmd); set_dma_count(devpriv->dma_chan, devpriv->dma_transfer_size); enable_dma(devpriv->dma_chan); release_dma_lock(flags); /* set up interrupt */ if (devpriv->timer_mode) { devpriv->timer_running = 1; devpriv->timer.expires = jiffies + timer_period(); add_timer(&devpriv->timer); devpriv->control_state &= ~DAS16_INTE; } else { /* clear interrupt bit */ outb(0x00, dev->iobase + DAS16_STATUS); /* enable interrupts */ devpriv->control_state |= DAS16_INTE; } devpriv->control_state |= DMA_ENABLE; devpriv->control_state &= ~PACING_MASK; if (cmd->convert_src == TRIG_EXT) devpriv->control_state |= EXT_PACER; else devpriv->control_state |= INT_PACER; outb(devpriv->control_state, dev->iobase + DAS16_CONTROL); /* Enable conversions if using das1600 mode */ if (board->size > 0x400) outb(0, dev->iobase + DAS1600_CONV); return 0; }