2 comedi/drivers/ni_mio_common.c
3 Hardware driver for DAQ-STC based boards
5 COMEDI - Linux Control and Measurement Device Interface
6 Copyright (C) 1997-2001 David A. Schleef <ds@schleef.org>
7 Copyright (C) 2002, 2003 Frank Mori Hess <fmhess@users.sourceforge.net
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
26 This file is meant to be included by another file, e.g.,
27 ni_atmio.c or ni_pcimio.c.
29 Interrupt support originally added by Truxton Fulton
32 References (from ftp://ftp.natinst.com/support/manuals):
34 340747b.pdf AT-MIO E series Register Level Programmer Manual
35 341079b.pdf PCI E Series RLPM
36 340934b.pdf DAQ-STC reference manual
37 67xx and 611x registers (from http://www.ni.com/pdf/daq/us)
40 Other possibly relevant info:
42 320517c.pdf User manual (obsolete)
43 320517f.pdf User manual (new)
45 320906c.pdf maximum signal ratings
47 321791a.pdf discontinuation of at-mio-16e-10 rev. c
48 321808a.pdf about at-mio-16e-10 rev P
49 321837a.pdf discontinuation of at-mio-16de-10 rev d
50 321838a.pdf about at-mio-16de-10 rev N
54 - the interrupt routine needs to be cleaned up
55 - many printk's need to be changed to rt_printk()
58 //#define DEBUG_INTERRUPT
59 //#define DEBUG_STATUS_A
60 //#define DEBUG_STATUS_B
64 #include "comedi_fc.h"
67 #define MDPRINTK(format,args...)
72 #define NI_TIMEOUT 1000
74 /* Note: this table must match the ai_gain_* definitions */
75 static short ni_gainlkup[][16]={
77 { 0, 1, 2, 3, 4, 5, 6, 7, 0x100, 0x101, 0x102, 0x103, 0x104, 0x105,
80 { 1, 2, 4, 7, 0x101, 0x102, 0x104, 0x107 },
82 { 1, 2, 3, 4, 5, 6, 7, 0x101, 0x102, 0x103, 0x104, 0x105, 0x106,
87 { 0x00a, 0x00b, 0x001, 0x002, 0x003, 0x004, 0x005, 0x006 }
90 static comedi_lrange range_ni_E_ai={ 16, {
108 static comedi_lrange range_ni_E_ai_limited={ 8, {
118 static comedi_lrange range_ni_E_ai_limited14={ 14, {
134 static comedi_lrange range_ni_E_ai_bipolar4={ 4, {
138 RANGE( -0.05, 0.05 ),
140 static comedi_lrange range_ni_E_ai_611x={ 8, {
150 static comedi_lrange range_ni_E_ao_ext = { 4, {
157 static comedi_lrange *ni_range_lkup[]={
159 &range_ni_E_ai_limited,
160 &range_ni_E_ai_limited14,
161 &range_ni_E_ai_bipolar4,
167 static int ni_dio_insn_config(comedi_device *dev,comedi_subdevice *s,
168 comedi_insn *insn,lsampl_t *data);
169 static int ni_dio_insn_bits(comedi_device *dev,comedi_subdevice *s,
170 comedi_insn *insn,lsampl_t *data);
172 static int ni_serial_insn_config(comedi_device *dev,comedi_subdevice *s,
173 comedi_insn *insn,lsampl_t *data);
174 static int ni_serial_hw_readwrite8(comedi_device *dev,comedi_subdevice *s,
175 unsigned char data_out, unsigned char *data_in);
176 static int ni_serial_sw_readwrite8(comedi_device *dev,comedi_subdevice *s,
177 unsigned char data_out, unsigned char *data_in);
179 static int ni_calib_insn_read(comedi_device *dev,comedi_subdevice *s,
180 comedi_insn *insn,lsampl_t *data);
181 static int ni_calib_insn_write(comedi_device *dev,comedi_subdevice *s,
182 comedi_insn *insn,lsampl_t *data);
184 static int ni_eeprom_insn_read(comedi_device *dev,comedi_subdevice *s,
185 comedi_insn *insn,lsampl_t *data);
187 static int ni_pfi_insn_bits(comedi_device *dev,comedi_subdevice *s,
188 comedi_insn *insn,lsampl_t *data);
189 static int ni_pfi_insn_config(comedi_device *dev,comedi_subdevice *s,
190 comedi_insn *insn,lsampl_t *data);
192 static void caldac_setup(comedi_device *dev,comedi_subdevice *s);
193 static int ni_read_eeprom(comedi_device *dev,int addr);
195 #ifdef DEBUG_STATUS_A
196 static void ni_mio_print_status_a(int status);
198 #define ni_mio_print_status_a(a)
200 #ifdef DEBUG_STATUS_B
201 static void ni_mio_print_status_b(int status);
203 #define ni_mio_print_status_b(a)
206 static int ni_ai_reset(comedi_device *dev,comedi_subdevice *s);
208 static void ni_handle_fifo_half_full(comedi_device *dev);
209 static int ni_ao_fifo_half_empty(comedi_device *dev,comedi_subdevice *s);
211 static void ni_handle_fifo_dregs(comedi_device *dev);
212 static int ni_ai_inttrig(comedi_device *dev,comedi_subdevice *s,
213 unsigned int trignum);
214 static void ni_load_channelgain_list(comedi_device *dev,unsigned int n_chan,
217 static int ni_ao_inttrig(comedi_device *dev,comedi_subdevice *s,
218 unsigned int trignum);
220 static int ni_ao_reset(comedi_device *dev,comedi_subdevice *s);
222 static int ni_8255_callback(int dir,int port,int data,unsigned long arg);
224 static int ni_ns_to_timer(int *nanosec,int round_mode);
227 /*GPCT function def's*/
228 static int GPCT_G_Watch(comedi_device *dev, int chan);
230 static void GPCT_Reset(comedi_device *dev, int chan);
231 static void GPCT_Gen_Cont_Pulse(comedi_device *dev, int chan, unsigned int length);
232 static void GPCT_Gen_Single_Pulse(comedi_device *dev, int chan, unsigned int length);
233 static void GPCT_Period_Meas(comedi_device *dev, int chan);
234 static void GPCT_Pulse_Width_Meas(comedi_device *dev, int chan);
235 static void GPCT_Event_Counting(comedi_device *dev,int chan);
236 static int GPCT_Set_Direction(comedi_device *dev,int chan,int direction);
237 static int GPCT_Set_Gate(comedi_device *dev,int chan ,int gate);
238 static int GPCT_Set_Source(comedi_device *dev,int chan ,int source);
240 static int ni_gpct_insn_write(comedi_device *dev,comedi_subdevice *s,
241 comedi_insn *insn,lsampl_t *data);
242 static int ni_gpct_insn_read(comedi_device *dev,comedi_subdevice *s,
243 comedi_insn *insn,lsampl_t *data);
244 static int ni_gpct_insn_config(comedi_device *dev,comedi_subdevice *s,
245 comedi_insn *insn,lsampl_t *data);
247 static int init_cs5529(comedi_device *dev);
248 static int cs5529_do_conversion(comedi_device *dev, unsigned short *data);
249 static int cs5529_ai_insn_read(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,lsampl_t *data);
250 static unsigned int cs5529_config_read(comedi_device *dev, unsigned int reg_select_bits);
251 static void cs5529_config_write(comedi_device *dev, unsigned int value, unsigned int reg_select_bits);
256 AIMODE_HALF_FULL = 1,
261 #define SERIAL_DISABLED 0
262 #define SERIAL_600NS 600
263 #define SERIAL_1_2US 1200
264 #define SERIAL_10US 10000
266 static const int num_adc_stages_611x = 3;
268 static void handle_a_interrupt(comedi_device *dev,unsigned short status,
269 unsigned int m_status);
270 static void handle_b_interrupt(comedi_device *dev,unsigned short status,
271 unsigned int m_status);
272 static void get_last_sample_611x( comedi_device *dev );
274 //static void mite_handle_interrupt(comedi_device *dev,unsigned int status);
275 static int ni_ai_drain_dma(comedi_device *dev );
278 #define win_out2(data,addr) do{ \
279 win_out((data)>>16, (addr)); \
280 win_out((data)&0xffff, (addr)+1); \
284 #define ao_win_out(data,addr) ni_ao_win_outw(dev,data,addr)
285 static inline void ni_ao_win_outw( comedi_device *dev, uint16_t data, int addr )
289 comedi_spin_lock_irqsave(&dev->spinlock,flags);
290 ni_writew(addr,AO_Window_Address_611x);
291 ni_writew(data,AO_Window_Data_611x);
292 comedi_spin_unlock_irqrestore(&dev->spinlock,flags);
295 static inline void ni_ao_win_outl(comedi_device *dev, uint32_t data, int addr)
299 comedi_spin_lock_irqsave(&dev->spinlock,flags);
300 ni_writew(addr,AO_Window_Address_611x);
301 ni_writel(data,AO_Window_Data_611x);
302 comedi_spin_unlock_irqrestore(&dev->spinlock,flags);
305 static inline unsigned short ni_ao_win_inw( comedi_device *dev, int addr )
310 comedi_spin_lock_irqsave(&dev->spinlock,flags);
311 ni_writew(addr, AO_Window_Address_611x);
312 data = ni_readw(AO_Window_Data_611x);
313 comedi_spin_unlock_irqrestore(&dev->spinlock,flags);
317 /* ni_set_bits( ) allows different parts of the ni_mio_common driver to
318 * share registers (such as Interrupt_A_Register) without interfering with
321 * NOTE: the switch/case statements are optimized out for a constant argument
322 * so this is actually quite fast--- If you must wrap another function around this
323 * make it inline to avoid a large speed penalty.
325 * value should only be 1 or 0.
327 static inline void ni_set_bits(comedi_device *dev, int reg, int bits, int value)
331 comedi_spin_lock_irqsave( &dev->spinlock, flags );
333 case Interrupt_A_Enable_Register:
335 devpriv->int_a_enable_reg |= bits;
337 devpriv->int_a_enable_reg &= ~bits;
338 comedi_spin_unlock_irqrestore( &dev->spinlock, flags );
339 win_out(devpriv->int_a_enable_reg,Interrupt_A_Enable_Register);
341 case Interrupt_B_Enable_Register:
343 devpriv->int_b_enable_reg |= bits;
345 devpriv->int_b_enable_reg &= ~bits;
346 comedi_spin_unlock_irqrestore( &dev->spinlock, flags );
347 win_out(devpriv->int_b_enable_reg,Interrupt_B_Enable_Register);
349 case IO_Bidirection_Pin_Register:
351 devpriv->io_bidirection_pin_reg |= bits;
353 devpriv->io_bidirection_pin_reg &= ~bits;
354 comedi_spin_unlock_irqrestore( &dev->spinlock, flags );
355 win_out(devpriv->io_bidirection_pin_reg,IO_Bidirection_Pin_Register);
358 printk("Warning ni_set_bits() called with invalid arguments\n");
359 printk("reg is %d\n",reg);
360 comedi_spin_unlock_irqrestore( &dev->spinlock, flags );
366 static irqreturn_t ni_E_interrupt(int irq,void *d,struct pt_regs * regs)
368 comedi_device *dev=d;
369 unsigned short a_status;
370 unsigned short b_status;
371 unsigned int m0_status;
372 unsigned int m1_status;
374 struct mite_struct *mite = devpriv->mite;
377 a_status=win_in(AI_Status_1_Register);
378 b_status=win_in(AO_Status_1_Register);
380 m0_status=readl(mite->mite_io_addr+MITE_CHSR+CHAN_OFFSET(AI_DMA_CHAN));
381 m1_status=readl(mite->mite_io_addr+MITE_CHSR+CHAN_OFFSET(AO_DMA_CHAN));
387 if(a_status&Interrupt_A_St || m0_status & CHSR_INT )
388 handle_a_interrupt(dev, a_status, m0_status);
389 if(b_status&Interrupt_B_St || m1_status & CHSR_INT )
390 handle_b_interrupt(dev, b_status, m1_status);
395 static void ni_sync_ai_dma(struct mite_struct *mite, comedi_device *dev)
398 comedi_subdevice *s = dev->subdevices + 0;
399 comedi_async *async = s->async;
400 unsigned int nbytes, old_alloc_count;
401 unsigned int bytes_per_scan = 2 * async->cmd.chanlist_len;
403 writel(CHOR_CLRLC, mite->mite_io_addr + MITE_CHOR + CHAN_OFFSET(AI_DMA_CHAN));
405 old_alloc_count = async->buf_write_alloc_count;
406 // write alloc as much as we can
407 comedi_buf_write_alloc(s->async, s->async->prealloc_bufsz);
409 nbytes = mite_bytes_transferred(mite, AI_DMA_CHAN);
410 if( (int)(nbytes - old_alloc_count) > 0 ){
411 printk("ni_mio_common: DMA overwrite of free area\n");
413 async->events |= COMEDI_CB_OVERFLOW;
417 count = nbytes - async->buf_write_count;
419 rt_printk("ni_mio_common: BUG: negative ai count\n");
423 comedi_buf_write_free(async, count);
425 async->scan_progress += count;
426 if( async->scan_progress >= bytes_per_scan )
428 async->scan_progress %= bytes_per_scan;
429 async->events |= COMEDI_CB_EOS;
431 async->events |= COMEDI_CB_BLOCK;
434 static void mite_handle_b_linkc(struct mite_struct *mite, comedi_device *dev)
437 comedi_subdevice *s = dev->subdevices + 1;
438 comedi_async *async = s->async;
439 unsigned int nbytes, new_write_count;
441 writel(CHOR_CLRLC, mite->mite_io_addr + MITE_CHOR + CHAN_OFFSET(AO_DMA_CHAN));
443 new_write_count = async->buf_write_count;
445 nbytes = mite_bytes_read(mite, AO_DMA_CHAN);
446 if( async->cmd.stop_src == TRIG_COUNT &&
447 (int) (nbytes - async->cmd.stop_arg * sizeof( sampl_t ) ) > 0 )
448 nbytes = async->cmd.stop_arg * sizeof( sampl_t );
449 if( (int)(nbytes - devpriv->last_buf_write_count) > 0 ){
450 rt_printk("ni_mio_common: DMA underrun\n");
452 async->events |= COMEDI_CB_OVERFLOW;
456 devpriv->last_buf_write_count = new_write_count;
458 count = nbytes - async->buf_read_count;
460 rt_printk("ni_mio_common: BUG: negative ao count\n");
463 comedi_buf_read_free(async, count);
465 async->events |= COMEDI_CB_BLOCK;
469 static void mite_handle_interrupt(comedi_device *dev,unsigned int m_status)
472 comedi_subdevice *s = dev->subdevices+0;
473 comedi_async *async = s->async;
474 struct mite_struct *mite = devpriv->mite;
476 async->events |= COMEDI_CB_BLOCK;
478 MDPRINTK("mite_handle_interrupt: m_status=%08x\n",m_status);
479 if(m_status & CHSR_DONE){
480 writel(CHOR_CLRDONE, mite->mite_io_addr + MITE_CHOR +
485 len = sizeof(sampl_t)*async->cmd.stop_arg*async->cmd.scan_end_arg;
486 if((devpriv->mite->DMA_CheckNearEnd) &&
487 (s->async->buf_int_count > (len - s->async->prealloc_bufsz))) {
491 offset = len % async->prealloc_bufsz;
492 if(offset < mite->ring[0].count) {
493 mite->ring[0].count = offset;
494 mite->ring[1].count = 0;
496 offset -= mite->ring[0].count;
497 i = offset >> PAGE_SHIFT;
498 mite->ring[i].count = offset & ~PAGE_MASK;
499 mite->ring[(i+1)%mite->n_links].count = 0;
501 mite->DMA_CheckNearEnd = 0;
506 MDPRINTK("CHSR is 0x%08x, count is %d\n",m_status,async->buf_int_count);
507 if(m_status&CHSR_DONE){
508 writel(CHOR_CLRDONE, mite->mite_io_addr+MITE_CHOR+CHAN_OFFSET(mite->chan));
509 //printk("buf_int_count is %d, buf_int_ptr is %d\n",
510 // s->async->buf_int_count,s->async->buf_int_ptr);
511 ni_handle_block_dma(dev);
513 MDPRINTK("exit mite_handle_interrupt\n");
516 //comedi_event(dev,s,async->events);
520 static int ni_ao_wait_for_dma_load( comedi_device *dev )
522 static const int timeout = 10000;
525 for(i = 0; i < timeout; i++)
527 unsigned short b_status;
529 b_status = win_in( AO_Status_1_Register );
530 if( b_status & AO_FIFO_Half_Full_St )
536 comedi_error(dev, "timed out waiting for dma load");
544 static void shutdown_ai_command( comedi_device *dev )
546 comedi_subdevice *s = dev->subdevices + 0;
549 ni_ai_drain_dma( dev );
550 mite_dma_disarm(devpriv->mite, AI_DMA_CHAN);
552 ni_handle_fifo_dregs(dev);
553 get_last_sample_611x(dev);
555 ni_set_bits(dev, Interrupt_A_Enable_Register,
556 AI_SC_TC_Interrupt_Enable | AI_START1_Interrupt_Enable|
557 AI_START2_Interrupt_Enable| AI_START_Interrupt_Enable|
558 AI_STOP_Interrupt_Enable| AI_Error_Interrupt_Enable|
559 AI_FIFO_Interrupt_Enable,0);
561 s->async->events |= COMEDI_CB_EOA;
564 static void handle_a_interrupt(comedi_device *dev,unsigned short status,
565 unsigned int m_status)
567 comedi_subdevice *s=dev->subdevices+0;
568 //comedi_async *async = s->async;
569 unsigned short ack=0;
571 s->async->events = 0;
573 #ifdef DEBUG_INTERRUPT
574 rt_printk("ni_mio_common: interrupt: a_status=%04x m0_status=%08x\n",
576 ni_mio_print_status_a(status);
581 /* Currently, mite.c requires us to handle LINKC and DONE */
582 if(m_status & CHSR_LINKC){
583 ni_sync_ai_dma(devpriv->mite, dev);
586 if(m_status & CHSR_DONE){
587 writel(CHOR_CLRDONE, devpriv->mite->mite_io_addr + MITE_CHOR +
588 CHAN_OFFSET(AI_DMA_CHAN));
591 if(m_status & ~(CHSR_INT | CHSR_LINKC | CHSR_DONE | CHSR_MRDY | CHSR_DRDY | CHSR_DRQ1 | CHSR_DRQ0 | CHSR_ERROR | CHSR_SABORT | CHSR_XFERR | CHSR_LxERR_mask)){
592 printk("unknown mite interrupt, ack! (m_status=%08x)\n", m_status);
593 //mite_print_chsr(m_status);
594 mite_dma_disarm(devpriv->mite, AI_DMA_CHAN );
595 writel(CHOR_DMARESET, devpriv->mite->mite_io_addr + MITE_CHOR +
596 CHAN_OFFSET(AI_DMA_CHAN));
597 //disable_irq(dev->irq);
601 /* test for all uncommon interrupt events at the same time */
602 if(status&(AI_Overrun_St|AI_Overflow_St|AI_SC_TC_Error_St|AI_SC_TC_St|AI_START1_St)){
604 rt_printk("ni_mio_common: a_status=0xffff. Card removed?\n");
605 /* we probably aren't even running a command now,
606 * so it's a good idea to be careful. */
607 if(s->subdev_flags&SDF_RUNNING){
608 s->async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA;
609 //comedi_event(dev,s,s->async->events);
613 if(status&(AI_Overrun_St|AI_Overflow_St|AI_SC_TC_Error_St)){
614 rt_printk("ni_mio_common: ai error a_status=%04x\n",
616 ni_mio_print_status_a(status);
618 ni_ai_reset(dev,dev->subdevices);
620 win_out(AI_Error_Interrupt_Ack, Interrupt_A_Ack_Register);
622 shutdown_ai_command( dev );
624 s->async->events |= COMEDI_CB_ERROR;
625 comedi_event(dev,s,s->async->events);
629 if(status&AI_SC_TC_St){
630 #ifdef DEBUG_INTERRUPT
631 rt_printk("ni_mio_common: SC_TC interrupt\n");
633 if(!devpriv->ai_continuous){
634 shutdown_ai_command( dev );
636 ack|=AI_SC_TC_Interrupt_Ack;
638 if(status&AI_START1_St){
639 ack|=AI_START1_Interrupt_Ack;
643 if(status&AI_FIFO_Half_Full_St){
644 ni_handle_fifo_half_full(dev);
648 if( (status & AI_STOP_St) ){
649 if(devpriv->aimode==AIMODE_SCAN){
651 ni_sync_ai_dma(devpriv->mite, dev);
653 ni_handle_fifo_dregs(dev);
654 s->async->events |= COMEDI_CB_EOS;
657 /* handle special case of single scan using AI_End_On_End_Of_Scan */
658 if( ( devpriv->ai_cmd2 & AI_End_On_End_Of_Scan ) ){
659 shutdown_ai_command( dev );
662 /* we need to ack the START, also */
663 ack|=AI_STOP_Interrupt_Ack|AI_START_Interrupt_Ack;
665 if(devpriv->aimode==AIMODE_SAMPLE){
666 ni_handle_fifo_dregs(dev);
668 //s->async->events |= COMEDI_CB_SAMPLE;
671 if(ack) win_out(ack,Interrupt_A_Ack_Register);
673 comedi_event(dev,s,s->async->events);
675 #ifdef DEBUG_INTERRUPT
676 status=win_in(AI_Status_1_Register);
677 if(status&Interrupt_A_St){
678 printk("handle_a_interrupt: BUG, didn't clear interrupt. disabling.\n");
679 win_out(0,Interrupt_Control_Register);
684 static void handle_b_interrupt(comedi_device *dev,unsigned short b_status, unsigned int m_status)
686 comedi_subdevice *s=dev->subdevices+1;
687 //unsigned short ack=0;
688 #ifdef DEBUG_INTERRUPT
689 rt_printk("ni_mio_common: interrupt: b_status=%04x m1_status=%08x\n",
691 ni_mio_print_status_b(b_status);
696 /* Currently, mite.c requires us to handle LINKC and DONE */
697 if(m_status & CHSR_LINKC){
698 mite_handle_b_linkc(devpriv->mite, dev);
701 if(m_status & CHSR_DONE){
702 writel(CHOR_CLRDONE, devpriv->mite->mite_io_addr + MITE_CHOR +
703 CHAN_OFFSET(AO_DMA_CHAN));
706 if(m_status & ~(CHSR_INT | CHSR_LINKC | CHSR_DONE | CHSR_MRDY | CHSR_DRDY | CHSR_DRQ1 | CHSR_DRQ0 | CHSR_ERROR | CHSR_SABORT | CHSR_XFERR | CHSR_LxERR_mask)){
707 printk("unknown mite interrupt, ack! (m_status=%08x)\n", m_status);
708 //mite_print_chsr(m_status);
709 mite_dma_disarm(devpriv->mite, AO_DMA_CHAN );
710 writel(CHOR_DMARESET, devpriv->mite->mite_io_addr + MITE_CHOR +
711 CHAN_OFFSET(AO_DMA_CHAN));
715 if(b_status==0xffff)return;
716 if(b_status&AO_Overrun_St){
717 rt_printk("ni_mio_common: AO FIFO underrun status=0x%04x status2=0x%04x\n",b_status,win_in(AO_Status_2_Register));
719 s->async->events |= COMEDI_CB_OVERFLOW;
722 if(b_status&AO_BC_TC_St){
723 MDPRINTK("ni_mio_common: AO BC_TC status=0x%04x status2=0x%04x\n",b_status,win_in(AO_Status_2_Register));
725 s->async->events |= COMEDI_CB_EOA;
729 if(b_status&AO_FIFO_Request_St){
732 ret = ni_ao_fifo_half_empty(dev,s);
734 rt_printk("ni_mio_common: AO buffer underrun\n");
735 ni_set_bits(dev, Interrupt_B_Enable_Register,
736 AO_FIFO_Interrupt_Enable|AO_Error_Interrupt_Enable, 0);
737 s->async->events |= COMEDI_CB_OVERFLOW;
742 b_status=win_in(AO_Status_1_Register);
743 if(b_status&Interrupt_B_St){
744 if(b_status&AO_FIFO_Request_St){
745 rt_printk("ni_mio_common: AO buffer underrun\n");
747 rt_printk("Ack! didn't clear AO interrupt. b_status=0x%04x\n",b_status);
748 ni_set_bits(dev,Interrupt_B_Enable_Register,~0,0);
750 s->async->events |= COMEDI_CB_OVERFLOW;
753 comedi_event(dev,s,s->async->events);
756 #ifdef DEBUG_STATUS_A
757 static char *status_a_strings[]={
758 "passthru0","fifo","G0_gate","G0_TC",
759 "stop","start","sc_tc","start1",
760 "start2","sc_tc_error","overflow","overrun",
761 "fifo_empty","fifo_half_full","fifo_full","interrupt_a"
764 static void ni_mio_print_status_a(int status)
768 rt_printk("A status:");
771 rt_printk(" %s",status_a_strings[i]);
778 #ifdef DEBUG_STATUS_B
779 static char *status_b_strings[]={
780 "passthru1","fifo","G1_gate","G1_TC",
781 "UI2_TC","UPDATE","UC_TC","BC_TC",
782 "start1","overrun","start","bc_tc_error",
783 "fifo_empty","fifo_half_full","fifo_full","interrupt_b"
786 static void ni_mio_print_status_b(int status)
790 rt_printk("B status:");
793 rt_printk(" %s",status_b_strings[i]);
802 static void ni_ao_fifo_load(comedi_device *dev,comedi_subdevice *s, int n)
804 comedi_async *async = s->async;
805 comedi_cmd *cmd = &async->cmd;
813 chan = async->cur_chan;
815 err &= comedi_buf_get(async, &d);
818 range = CR_RANGE(cmd->chanlist[chan]);
820 if(boardtype.reg_type & ni_reg_6xxx_mask)
822 packed_data = d & 0xffff;
823 /* 6711 only has 16 bit wide ao fifo */
824 if(boardtype.reg_type != ni_reg_6711)
826 err &= comedi_buf_get(async, &d);
830 packed_data |= ( d << 16 ) & 0xffff0000;
832 ni_writel( packed_data, DAC_FIFO_Data_611x );
834 ni_writew(d, DAC_FIFO_Data);
837 chan %= cmd->chanlist_len;
839 async->cur_chan = chan;
841 async->events |= COMEDI_CB_OVERFLOW;
846 * There's a small problem if the FIFO gets really low and we
847 * don't have the data to fill it. Basically, if after we fill
848 * the FIFO with all the data available, the FIFO is _still_
849 * less than half full, we never clear the interrupt. If the
850 * IRQ is in edge mode, we never get another interrupt, because
851 * this one wasn't cleared. If in level mode, we get flooded
852 * with interrupts that we can't fulfill, because nothing ever
853 * gets put into the buffer.
855 * This kind of situation is recoverable, but it is easier to
856 * just pretend we had a FIFO underrun, since there is a good
857 * chance it will happen anyway. This is _not_ the case for
858 * RT code, as RT code might purposely be running close to the
859 * metal. Needs to be fixed eventually.
861 static int ni_ao_fifo_half_empty(comedi_device *dev,comedi_subdevice *s)
865 n = comedi_buf_read_n_available(s);
867 s->async->events |= COMEDI_CB_OVERFLOW;
871 n /= sizeof(sampl_t);
872 if(n > boardtype.ao_fifo_depth / 2)
873 n = boardtype.ao_fifo_depth / 2;
875 ni_ao_fifo_load(dev,s,n);
877 s->async->events |= COMEDI_CB_BLOCK;
882 static int ni_ao_prep_fifo(comedi_device *dev,comedi_subdevice *s)
887 win_out(0,DAC_FIFO_Clear);
888 ni_ao_win_outl(dev, 0x6, AO_FIFO_Offset_Load_611x);
891 n = comedi_buf_read_n_available(s);
894 n /= sizeof(sampl_t);
895 if(n > boardtype.ao_fifo_depth)
896 n = boardtype.ao_fifo_depth;
898 ni_ao_fifo_load(dev,s,n);
903 static void ni_ai_fifo_read(comedi_device *dev,comedi_subdevice *s,
906 comedi_async *async = s->async;
909 if(boardtype.reg_type == ni_reg_611x){
913 for( i = 0; i < n / 2; i++ ){
914 dl=ni_readl(ADC_FIFO_Data_611x);
915 /* This may get the hi/lo data in the wrong order */
916 data[0] = (dl>>16) & 0xffff;
917 data[1] = dl & 0xffff;
918 cfc_write_array_to_buffer(s, data, sizeof(data));
920 /* Check if there's a single sample stuck in the FIFO */
922 dl=ni_readl(ADC_FIFO_Data_611x);
923 data[0] = dl & 0xffff;
924 cfc_write_to_buffer(s, data[0]);
927 if( n > sizeof(devpriv->ai_fifo_buffer) / sizeof(devpriv->ai_fifo_buffer[0]))
929 comedi_error( dev, "bug! ai_fifo_buffer too small" );
930 async->events |= COMEDI_CB_ERROR;
933 for(i = 0; i < n; i++){
934 devpriv->ai_fifo_buffer[i] = ni_readw(ADC_FIFO_Data_Register);
936 cfc_write_array_to_buffer( s, devpriv->ai_fifo_buffer,
937 n * sizeof(devpriv->ai_fifo_buffer[0]) );
941 static void ni_handle_fifo_half_full(comedi_device *dev)
944 comedi_subdevice *s=dev->subdevices+0;
946 n=boardtype.ai_fifo_depth/2;
948 ni_ai_fifo_read(dev,s,n);
953 static int ni_ai_drain_dma(comedi_device *dev )
955 struct mite_struct *mite = devpriv->mite;
957 static const int timeout = 10000;
959 for( i = 0; i < timeout; i++ )
961 if( ( win_in( AI_Status_1_Register ) & AI_FIFO_Empty_St ) &&
962 mite_bytes_in_transit( mite, AI_DMA_CHAN ) == 0 )
968 rt_printk( "ni_mio_common: wait for dma drain timed out\n" );
972 ni_sync_ai_dma( mite, dev );
980 static void ni_handle_fifo_dregs(comedi_device *dev)
982 comedi_subdevice *s=dev->subdevices+0;
986 if(boardtype.reg_type == ni_reg_611x){
987 while((win_in(AI_Status_1_Register)&AI_FIFO_Empty_St) == 0){
988 dl=ni_readl(ADC_FIFO_Data_611x);
990 /* This may get the hi/lo data in the wrong order */
992 data[1] = (dl&0xffff);
993 cfc_write_array_to_buffer(s, data, sizeof(data));
996 while((win_in(AI_Status_1_Register)&AI_FIFO_Empty_St) == 0){
997 data[0]=ni_readw(ADC_FIFO_Data_Register);
998 cfc_write_to_buffer(s, data[0]);
1003 static void get_last_sample_611x( comedi_device *dev )
1005 comedi_subdevice *s=dev->subdevices+0;
1009 if(boardtype.reg_type != ni_reg_611x) return;
1011 /* Check if there's a single sample stuck in the FIFO */
1012 if(ni_readb(XXX_Status)&0x80){
1013 dl=ni_readl(ADC_FIFO_Data_611x);
1015 cfc_write_to_buffer(s, data);
1019 static void ni_ai_munge(comedi_device *dev, comedi_subdevice *s,
1020 void *data, unsigned int num_bytes, unsigned int chan_index )
1022 comedi_async *async = s->async;
1024 unsigned int length = num_bytes / sizeof( sampl_t );
1025 sampl_t *array = data;
1027 for(i = 0; i < length; i++)
1030 array[i] = le16_to_cpu(array[i]);
1032 array[i] += devpriv->ai_offset[ chan_index ];
1034 chan_index %= async->cmd.chanlist_len;
1040 static void ni_ai_setup_MITE_dma(comedi_device *dev,comedi_cmd *cmd)
1042 struct mite_struct *mite = devpriv->mite;
1043 struct mite_channel *mite_chan = &mite->channels[ AI_DMA_CHAN ];
1044 comedi_subdevice *s = dev->subdevices + 0;
1046 /* write alloc the entire buffer */
1047 comedi_buf_write_alloc(s->async, s->async->prealloc_bufsz);
1049 mite_chan->current_link = 0;
1050 mite_chan->dir = COMEDI_INPUT;
1051 if(boardtype.reg_type == ni_reg_611x)
1052 mite_prep_dma(mite, AI_DMA_CHAN, 32, 16);
1054 mite_prep_dma(mite, AI_DMA_CHAN, 16, 16);
1057 mite_dma_arm(mite, AI_DMA_CHAN);
1060 static void ni_ao_setup_MITE_dma(comedi_device *dev,comedi_cmd *cmd)
1062 struct mite_struct *mite = devpriv->mite;
1063 struct mite_channel *mite_chan = &mite->channels[ AO_DMA_CHAN ];
1064 comedi_subdevice *s = dev->subdevices + 1;
1066 devpriv->last_buf_write_count = s->async->buf_write_count;
1068 mite_chan->current_link = 0;
1069 mite_chan->dir = COMEDI_OUTPUT;
1070 if(boardtype.reg_type & (ni_reg_611x | ni_reg_6713))
1071 mite_prep_dma(mite, AO_DMA_CHAN, 32, 32);
1073 mite_prep_dma(mite, AO_DMA_CHAN, 16, 16);
1076 mite_dma_arm(mite, AO_DMA_CHAN);
1082 used for both cancel ioctl and board initialization
1084 this is pretty harsh for a cancel, but it works...
1087 static int ni_ai_reset(comedi_device *dev,comedi_subdevice *s)
1090 mite_dma_disarm(devpriv->mite, AI_DMA_CHAN);
1092 /* ai configuration */
1093 win_out(AI_Configuration_Start | AI_Reset, Joint_Reset_Register);
1095 ni_set_bits(dev, Interrupt_A_Enable_Register,
1096 AI_SC_TC_Interrupt_Enable | AI_START1_Interrupt_Enable|
1097 AI_START2_Interrupt_Enable| AI_START_Interrupt_Enable|
1098 AI_STOP_Interrupt_Enable| AI_Error_Interrupt_Enable|
1099 AI_FIFO_Interrupt_Enable,0);
1101 win_out(1,ADC_FIFO_Clear);
1103 ni_writeb(0, Misc_Command);
1105 win_out(AI_Disarm, AI_Command_1_Register); /* reset pulses */
1106 win_out(AI_Start_Stop | AI_Mode_1_Reserved /*| AI_Trigger_Once */,
1107 AI_Mode_1_Register);
1108 win_out(0x0000,AI_Mode_2_Register);
1109 /* generate FIFO interrupts on non-empty */
1110 win_out((0<<6)|0x0000,AI_Mode_3_Register);
1111 if(boardtype.reg_type == ni_reg_normal){
1112 win_out(AI_SHIFTIN_Pulse_Width |
1114 AI_CONVERT_Pulse_Width |
1115 AI_LOCALMUX_CLK_Pulse_Width, AI_Personal_Register);
1116 win_out(AI_SCAN_IN_PROG_Output_Select(3) |
1117 AI_EXTMUX_CLK_Output_Select(0) |
1118 AI_LOCALMUX_CLK_Output_Select(2) |
1119 AI_SC_TC_Output_Select(3) |
1120 AI_CONVERT_Output_Select(2),AI_Output_Control_Register);
1121 }else{/* 611x boards */
1122 win_out(AI_SHIFTIN_Pulse_Width |
1124 AI_LOCALMUX_CLK_Pulse_Width, AI_Personal_Register);
1125 win_out(AI_SCAN_IN_PROG_Output_Select(3) |
1126 AI_EXTMUX_CLK_Output_Select(0) |
1127 AI_LOCALMUX_CLK_Output_Select(2) |
1128 AI_SC_TC_Output_Select(3) |
1129 AI_CONVERT_Output_Select(3),AI_Output_Control_Register);
1132 /* the following registers should not be changed, because there
1133 * are no backup registers in devpriv. If you want to change
1134 * any of these, add a backup register and other appropriate code:
1135 * AI_Mode_1_Register
1136 * AI_Mode_3_Register
1137 * AI_Personal_Register
1138 * AI_Output_Control_Register
1140 win_out(AI_SC_TC_Error_Confirm | AI_START_Interrupt_Ack |
1141 AI_START2_Interrupt_Ack | AI_START1_Interrupt_Ack |
1142 AI_SC_TC_Interrupt_Ack | AI_Error_Interrupt_Ack |
1143 AI_STOP_Interrupt_Ack, Interrupt_A_Ack_Register); /* clear interrupts */
1145 win_out(AI_Configuration_End,Joint_Reset_Register);
1150 static int ni_ai_poll(comedi_device *dev,comedi_subdevice *s)
1153 ni_handle_fifo_dregs(dev);
1155 //comedi_event(dev,s,s->async->events);
1157 return s->async->buf_write_count - s->async->buf_read_count;
1159 /* XXX we don't support this yet. */
1165 static int ni_ai_insn_read(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,lsampl_t *data)
1169 unsigned short signbits;
1172 ni_load_channelgain_list(dev,1,&insn->chanspec);
1174 win_out(1,ADC_FIFO_Clear);
1176 mask=(1<<boardtype.adbits)-1;
1177 signbits=devpriv->ai_offset[0];
1178 if(boardtype.reg_type == ni_reg_611x){
1179 for(n=0; n < num_adc_stages_611x; n++){
1180 win_out(AI_CONVERT_Pulse, AI_Command_1_Register);
1183 for(n=0; n<insn->n; n++){
1184 win_out(AI_CONVERT_Pulse, AI_Command_1_Register);
1185 /* The 611x has screwy 32-bit FIFOs. */
1187 for(i=0; i<NI_TIMEOUT; i++){
1188 if(ni_readb(XXX_Status)&0x80)
1190 d = ( ni_readl(ADC_FIFO_Data_611x) >> 16 ) & 0xffff;
1193 if(!(win_in(AI_Status_1_Register)&AI_FIFO_Empty_St))
1195 d = ni_readl(ADC_FIFO_Data_611x) & 0xffff;
1200 rt_printk("ni_mio_common: timeout in 611x ni_ai_insn_read\n");
1203 d += signbits; /* subtle: needs to be short addition */
1207 for(n=0;n<insn->n;n++){
1208 win_out(AI_CONVERT_Pulse, AI_Command_1_Register);
1209 for(i=0;i<NI_TIMEOUT;i++){
1210 if(!(win_in(AI_Status_1_Register)&AI_FIFO_Empty_St))
1214 rt_printk("ni_mio_common: timeout in ni_ai_insn_read\n");
1217 d = ni_readw(ADC_FIFO_Data_Register);
1218 d += signbits; /* subtle: needs to be short addition */
1226 * Notes on the 6110 and 6111:
1227 * These boards a slightly different than the rest of the series, since
1228 * they have multiple A/D converters.
1229 * From the driver side, the configuration memory is a
1231 * Configuration Memory Low:
1233 * bit 8: unipolar/bipolar (should be 0 for bipolar)
1234 * bits 0-3: gain. This is 4 bits instead of 3 for the other boards
1235 * 1001 gain=0.1 (+/- 50)
1244 * Configuration Memory High:
1245 * bits 12-14: Channel Type
1246 * 001 for differential
1247 * 000 for calibration
1248 * bit 11: coupling (this is not currently handled)
1252 * valid channels are 0-3
1254 static void ni_load_channelgain_list(comedi_device *dev,unsigned int n_chan,
1257 unsigned int chan,range,aref;
1260 unsigned short offset;
1261 unsigned int dither;
1263 if(n_chan == 1 && boardtype.reg_type == ni_reg_normal){
1264 if(devpriv->changain_state && devpriv->changain_spec==list[0]){
1268 devpriv->changain_state=1;
1269 devpriv->changain_spec=list[0];
1271 devpriv->changain_state=0;
1274 win_out(1,Configuration_Memory_Clear);
1276 offset=1<<(boardtype.adbits-1);
1277 for(i=0;i<n_chan;i++){
1278 if(list[i]&CR_ALT_SOURCE){
1279 chan=devpriv->ai_calib_source;
1281 chan=CR_CHAN(list[i]);
1283 aref=CR_AREF(list[i]);
1284 range=CR_RANGE(list[i]);
1285 dither=((list[i]&CR_ALT_FILTER)!=0);
1287 /* fix the external/internal range differences */
1288 range = ni_gainlkup[boardtype.gainlkup][range];
1289 if(boardtype.reg_type == ni_reg_611x)
1290 devpriv->ai_offset[i] = offset;
1292 devpriv->ai_offset[i] = (range&0x100)?0:offset;
1295 if( ( list[i] & CR_ALT_SOURCE ) )
1297 if(boardtype.reg_type == ni_reg_611x)
1298 ni_writew(CR_CHAN(list[i])&0x0003, Calibration_Channel_Select_611x);
1301 if(boardtype.reg_type == ni_reg_611x)
1306 hi |= AI_DIFFERENTIAL;
1318 hi |= AI_CONFIG_CHANNEL( chan );
1320 ni_writew(hi,Configuration_Memory_High);
1323 if(i == n_chan - 1) lo |= AI_LAST_CHANNEL;
1324 if( dither ) lo |= AI_DITHER;
1326 ni_writew(lo,Configuration_Memory_Low);
1329 /* prime the channel/gain list */
1330 if(boardtype.reg_type == ni_reg_normal){
1331 win_out(AI_CONVERT_Pulse, AI_Command_1_Register);
1332 for(i=0;i<NI_TIMEOUT;i++){
1333 if(!(win_in(AI_Status_1_Register)&AI_FIFO_Empty_St)){
1334 win_out(1,ADC_FIFO_Clear);
1339 rt_printk("ni_mio_common: timeout loading channel/gain list\n");
1343 #define TIMER_BASE 50 /* 20 Mhz base */
1345 static int ni_ns_to_timer(int *nanosec,int round_mode)
1352 case TRIG_ROUND_NEAREST:
1354 divider=(*nanosec+base/2)/base;
1356 case TRIG_ROUND_DOWN:
1357 divider=(*nanosec)/base;
1360 divider=(*nanosec+base-1)/base;
1364 *nanosec=base*divider;
1368 static int ni_ai_cmdtest(comedi_device *dev,comedi_subdevice *s,comedi_cmd *cmd)
1374 /* step 1: make sure trigger sources are trivially valid */
1377 cmd->start_src &= TRIG_NOW|TRIG_INT|TRIG_EXT;
1378 if(!cmd->start_src || tmp!=cmd->start_src)err++;
1380 tmp=cmd->scan_begin_src;
1381 cmd->scan_begin_src &= TRIG_TIMER|TRIG_EXT;
1382 if(!cmd->scan_begin_src || tmp!=cmd->scan_begin_src)err++;
1384 tmp=cmd->convert_src;
1385 sources = TRIG_TIMER | TRIG_EXT;
1386 if(boardtype.reg_type == ni_reg_611x) sources |= TRIG_NOW;
1387 cmd->convert_src &= sources;
1388 if(!cmd->convert_src || tmp!=cmd->convert_src)err++;
1390 tmp=cmd->scan_end_src;
1391 cmd->scan_end_src &= TRIG_COUNT;
1392 if(!cmd->scan_end_src || tmp!=cmd->scan_end_src)err++;
1395 cmd->stop_src &= TRIG_COUNT|TRIG_NONE;
1396 if(!cmd->stop_src || tmp!=cmd->stop_src)err++;
1400 /* step 2: make sure trigger sources are unique and mutually compatible */
1402 /* note that mutual compatiblity is not an issue here */
1403 if(cmd->start_src!=TRIG_NOW &&
1404 cmd->start_src!=TRIG_INT &&
1405 cmd->start_src!=TRIG_EXT)err++;
1406 if(cmd->scan_begin_src!=TRIG_TIMER &&
1407 cmd->scan_begin_src!=TRIG_EXT &&
1408 cmd->scan_begin_src!=TRIG_OTHER)err++;
1409 if(cmd->convert_src!=TRIG_TIMER &&
1410 cmd->convert_src!=TRIG_EXT &&
1411 cmd->convert_src!=TRIG_NOW)err++;
1412 if(cmd->stop_src!=TRIG_COUNT &&
1413 cmd->stop_src!=TRIG_NONE)err++;
1417 /* step 3: make sure arguments are trivially compatible */
1419 if(cmd->start_src==TRIG_EXT){
1420 /* external trigger */
1421 unsigned int tmp = CR_CHAN(cmd->start_arg);
1424 /* XXX for now, use the top bit to invert the signal */
1425 tmp |= (cmd->start_arg&0x80000000);
1426 if(cmd->start_arg!=tmp){
1427 cmd->start_arg = tmp;
1431 if(cmd->start_arg!=0){
1432 /* true for both TRIG_NOW and TRIG_INT */
1437 if(cmd->scan_begin_src==TRIG_TIMER){
1438 if(cmd->scan_begin_arg<boardtype.ai_speed){
1439 cmd->scan_begin_arg=boardtype.ai_speed;
1442 if(cmd->scan_begin_arg>TIMER_BASE*0xffffff){
1443 cmd->scan_begin_arg=TIMER_BASE*0xffffff;
1446 }else if(cmd->scan_begin_src==TRIG_EXT){
1447 /* external trigger */
1448 unsigned int tmp = CR_CHAN(cmd->scan_begin_arg);
1451 /* XXX for now, use the top bit to invert the signal */
1452 tmp |= (cmd->scan_begin_arg&0x80000000);
1453 if(cmd->scan_begin_arg!=tmp){
1454 cmd->scan_begin_arg = tmp;
1457 }else{ /* TRIG_OTHER */
1458 if(cmd->scan_begin_arg){
1459 cmd->scan_begin_arg=0;
1463 if(cmd->convert_src==TRIG_TIMER){
1464 if(boardtype.reg_type == ni_reg_611x){
1465 if(cmd->convert_arg != 0){
1466 cmd->convert_arg = 0;
1470 if(cmd->convert_arg<boardtype.ai_speed){
1471 cmd->convert_arg=boardtype.ai_speed;
1474 if(cmd->convert_arg>TIMER_BASE*0xffff){
1475 cmd->convert_arg=TIMER_BASE*0xffff;
1479 }else if(cmd->convert_src == TRIG_EXT){
1480 /* external trigger */
1481 unsigned int tmp = CR_CHAN(cmd->convert_arg);
1484 tmp |= (cmd->convert_arg&(CR_ALT_FILTER|CR_INVERT));
1485 if(cmd->convert_arg!=tmp){
1486 cmd->convert_arg = tmp;
1489 }else if(cmd->convert_src == TRIG_NOW){
1490 if(cmd->convert_arg != 0){
1491 cmd->convert_arg = 0;
1496 if(cmd->scan_end_arg!=cmd->chanlist_len){
1497 cmd->scan_end_arg=cmd->chanlist_len;
1500 if(cmd->stop_src==TRIG_COUNT){
1501 unsigned int max_count = 0x01000000;
1503 if(boardtype.reg_type == ni_reg_611x )
1504 max_count -= num_adc_stages_611x;
1505 if(cmd->stop_arg > max_count){
1506 cmd->stop_arg = max_count;
1511 if(cmd->stop_arg!=0){
1519 /* step 4: fix up any arguments */
1521 if(cmd->scan_begin_src==TRIG_TIMER){
1522 tmp=cmd->scan_begin_arg;
1523 ni_ns_to_timer(&cmd->scan_begin_arg,cmd->flags&TRIG_ROUND_MASK);
1524 if(tmp!=cmd->scan_begin_arg)err++;
1526 if(cmd->convert_src==TRIG_TIMER){
1527 if(boardtype.reg_type == ni_reg_normal){
1528 tmp=cmd->convert_arg;
1529 ni_ns_to_timer(&cmd->convert_arg,cmd->flags&TRIG_ROUND_MASK);
1530 if(tmp!=cmd->convert_arg)err++;
1531 if(cmd->scan_begin_src==TRIG_TIMER &&
1532 cmd->scan_begin_arg<cmd->convert_arg*cmd->scan_end_arg){
1533 cmd->scan_begin_arg=cmd->convert_arg*cmd->scan_end_arg;
1544 static int ni_ai_cmd(comedi_device *dev,comedi_subdevice *s)
1546 comedi_cmd *cmd=&s->async->cmd;
1548 int mode1=0; /* mode1 is needed for both stop and convert */
1550 int start_stop_select=0;
1551 unsigned int stop_count;
1552 int interrupt_a_enable=0;
1554 MDPRINTK("ni_ai_cmd\n");
1556 win_out(1,ADC_FIFO_Clear);
1558 ni_load_channelgain_list(dev,cmd->chanlist_len,cmd->chanlist);
1560 /* start configuration */
1561 win_out(AI_Configuration_Start,Joint_Reset_Register);
1563 /* disable analog triggering for now, since it
1564 * interferes with the use of pfi0 */
1565 devpriv->an_trig_etc_reg &= ~Analog_Trigger_Enable;
1566 win_out(devpriv->an_trig_etc_reg, Analog_Trigger_Etc_Register);
1568 switch(cmd->start_src){
1571 win_out(AI_START2_Select(0)|
1572 AI_START1_Sync|AI_START1_Edge|AI_START1_Select(0),
1573 AI_Trigger_Select_Register);
1577 int chan = CR_CHAN(cmd->start_arg);
1579 win_out(AI_START2_Select(0)|
1580 AI_START1_Sync | AI_START1_Edge |
1581 AI_START1_Select(chan + 1),
1582 AI_Trigger_Select_Register);
1587 mode2 &= ~AI_Pre_Trigger;
1588 mode2 &= ~AI_SC_Initial_Load_Source;
1589 mode2 &= ~AI_SC_Reload_Mode;
1590 win_out(mode2, AI_Mode_2_Register);
1592 start_stop_select |= AI_STOP_Sync;
1593 if(boardtype.reg_type == ni_reg_611x){
1594 start_stop_select |= AI_STOP_Polarity;
1595 start_stop_select |= AI_STOP_Select( 31 );
1597 start_stop_select |= AI_STOP_Select( 19 );
1599 win_out(start_stop_select, AI_START_STOP_Select_Register);
1601 devpriv->ai_cmd2 = 0;
1602 switch(cmd->stop_src){
1604 stop_count = cmd->stop_arg - 1;
1606 if(boardtype.reg_type == ni_reg_611x){
1607 // have to take 3 stage adc pipeline into account
1608 stop_count += num_adc_stages_611x;
1610 /* stage number of scans */
1611 win_out2( stop_count, AI_SC_Load_A_Registers);
1613 mode1 |= AI_Start_Stop | AI_Mode_1_Reserved | AI_Trigger_Once;
1614 win_out(mode1,AI_Mode_1_Register);
1615 /* load SC (Scan Count) */
1616 win_out(AI_SC_Load,AI_Command_1_Register);
1618 devpriv->ai_continuous = 0;
1619 if( stop_count == 0 ){
1620 devpriv->ai_cmd2 |= AI_End_On_End_Of_Scan;
1621 interrupt_a_enable|=AI_STOP_Interrupt_Enable;
1625 /* stage number of scans */
1626 win_out(0,AI_SC_Load_A_Registers);
1627 win_out(0,AI_SC_Load_A_Registers+1);
1629 mode1 |= AI_Start_Stop | AI_Mode_1_Reserved | AI_Continuous;
1630 win_out(mode1,AI_Mode_1_Register);
1632 /* load SC (Scan Count) */
1633 win_out(AI_SC_Load,AI_Command_1_Register);
1635 devpriv->ai_continuous = 1;
1640 switch(cmd->scan_begin_src){
1643 stop bits for non 611x boards
1644 AI_SI_Special_Trigger_Delay=0
1646 AI_START_STOP_Select_Register:
1647 AI_START_Polarity=0 (?) rising edge
1648 AI_START_Edge=1 edge triggered
1650 AI_START_Select=0 SI_TC
1651 AI_STOP_Polarity=0 rising edge
1652 AI_STOP_Edge=0 level
1654 AI_STOP_Select=19 external pin (configuration mem)
1656 start_stop_select |= AI_START_Edge | AI_START_Sync;
1657 win_out(start_stop_select, AI_START_STOP_Select_Register);
1659 mode2 |= AI_SI_Reload_Mode(0);
1660 /* AI_SI_Initial_Load_Source=A */
1661 mode2 &= ~AI_SI_Initial_Load_Source;
1662 //mode2 |= AI_SC_Reload_Mode;
1663 win_out(mode2, AI_Mode_2_Register);
1666 timer=ni_ns_to_timer(&cmd->scan_begin_arg,TRIG_ROUND_NEAREST);
1667 win_out2(timer,AI_SI_Load_A_Registers);
1668 win_out(AI_SI_Load,AI_Command_1_Register);
1672 /* Level trigger usually doesn't work, making it the default
1673 * doesn't make sense. Disabling it. */
1674 /* if( cmd->scan_begin_arg & CR_EDGE ) */
1675 start_stop_select |= AI_START_Edge;
1676 /* AI_START_Polarity==1 is falling edge */
1677 if( cmd->scan_begin_arg & CR_INVERT )
1678 start_stop_select |= AI_START_Polarity;
1679 if( cmd->scan_begin_src != cmd->convert_src ||
1680 ( cmd->scan_begin_arg & ~CR_EDGE ) != ( cmd->convert_arg & ~CR_EDGE ) )
1681 start_stop_select |= AI_START_Sync;
1682 start_stop_select |= AI_START_Select(1+(cmd->scan_begin_arg&0xf));
1683 win_out(start_stop_select, AI_START_STOP_Select_Register);
1687 switch(cmd->convert_src){
1690 if( cmd->convert_arg == 0 || cmd->convert_src == TRIG_NOW )
1693 timer=ni_ns_to_timer(&cmd->convert_arg, TRIG_ROUND_NEAREST);
1694 win_out(1,AI_SI2_Load_A_Register); /* 0,0 does not work. */
1695 win_out(timer,AI_SI2_Load_B_Register);
1697 /* AI_SI2_Reload_Mode = alternate */
1698 /* AI_SI2_Initial_Load_Source = A */
1699 mode2 &= ~AI_SI2_Initial_Load_Source;
1700 mode2 |= AI_SI2_Reload_Mode;
1701 win_out( mode2, AI_Mode_2_Register);
1704 win_out(AI_SI2_Load,AI_Command_1_Register);
1706 mode2 |= AI_SI2_Reload_Mode; // alternate
1707 mode2 |= AI_SI2_Initial_Load_Source; // B
1709 win_out(mode2,AI_Mode_2_Register);
1712 mode1 |= AI_CONVERT_Source_Select(1+cmd->convert_arg);
1713 if( ( cmd->convert_arg & CR_INVERT ) == 0 )
1714 mode1 |= AI_CONVERT_Source_Polarity;
1715 win_out(mode1,AI_Mode_1_Register);
1717 mode2 |= AI_Start_Stop_Gate_Enable | AI_SC_Gate_Enable;
1718 win_out(mode2, AI_Mode_2_Register);
1725 /* interrupt on FIFO, errors, SC_TC */
1726 interrupt_a_enable |= AI_Error_Interrupt_Enable|
1727 AI_SC_TC_Interrupt_Enable;
1730 interrupt_a_enable|=AI_FIFO_Interrupt_Enable;
1733 if(s->async->cb_mask&COMEDI_CB_EOS){
1734 /* wake on end-of-scan */
1735 devpriv->aimode=AIMODE_SCAN;
1737 devpriv->aimode=AIMODE_HALF_FULL;
1740 switch(devpriv->aimode){
1741 case AIMODE_HALF_FULL:
1742 /*generate FIFO interrupts and DMA requests on half-full */
1744 win_out(AI_FIFO_Mode_HF_to_E, AI_Mode_3_Register);
1746 win_out(AI_FIFO_Mode_HF, AI_Mode_3_Register);
1750 /*generate FIFO interrupts on non-empty */
1751 win_out(AI_FIFO_Mode_NE, AI_Mode_3_Register);
1755 win_out(AI_FIFO_Mode_NE, AI_Mode_3_Register);
1757 win_out(AI_FIFO_Mode_HF, AI_Mode_3_Register);
1759 interrupt_a_enable|=AI_STOP_Interrupt_Enable;
1765 win_out(0x3f80,Interrupt_A_Ack_Register); /* clear interrupts */
1767 ni_set_bits(dev, Interrupt_A_Enable_Register, interrupt_a_enable, 1);
1769 MDPRINTK("Interrupt_A_Enable_Register = 0x%04x\n",devpriv->int_a_enable_reg);
1771 /* interrupt on nothing */
1772 ni_set_bits(dev, Interrupt_A_Enable_Register, ~0, 0);
1774 /* XXX start polling if necessary */
1775 MDPRINTK("interrupting on nothing\n");
1778 /* end configuration */
1779 win_out(AI_Configuration_End,Joint_Reset_Register);
1781 switch(cmd->scan_begin_src){
1783 win_out(AI_SI2_Arm | AI_SI_Arm | AI_DIV_Arm | AI_SC_Arm,
1784 AI_Command_1_Register);
1787 /* XXX AI_SI_Arm? */
1788 win_out(AI_SI2_Arm | AI_SI_Arm | AI_DIV_Arm | AI_SC_Arm,
1789 AI_Command_1_Register);
1794 ni_ai_setup_MITE_dma(dev,cmd);
1795 //mite_dump_regs(devpriv->mite);
1798 switch(cmd->start_src){
1800 /* AI_START1_Pulse */
1801 win_out( AI_START1_Pulse | devpriv->ai_cmd2, AI_Command_2_Register );
1802 s->async->inttrig=NULL;
1805 s->async->inttrig=NULL;
1808 s->async->inttrig=ni_ai_inttrig;
1812 MDPRINTK("exit ni_ai_cmd\n");
1817 static int ni_ai_inttrig(comedi_device *dev,comedi_subdevice *s,
1818 unsigned int trignum)
1820 if(trignum!=0)return -EINVAL;
1822 win_out( AI_START1_Pulse | devpriv->ai_cmd2, AI_Command_2_Register );
1823 s->async->inttrig=NULL;
1828 static int ni_ai_config_analog_trig(comedi_device *dev,comedi_subdevice *s,
1829 comedi_insn *insn, lsampl_t *data);
1831 static int ni_ai_insn_config(comedi_device *dev,comedi_subdevice *s,
1832 comedi_insn *insn, lsampl_t *data)
1834 if(insn->n<1)return -EINVAL;
1837 case INSN_CONFIG_ANALOG_TRIG:
1838 return ni_ai_config_analog_trig(dev,s,insn,data);
1839 case INSN_CONFIG_ALT_SOURCE:
1841 unsigned int calib_source;
1842 unsigned int calib_source_adjust;
1844 calib_source = data[1] & 0xf;
1845 calib_source_adjust = ( data[1] >> 4 ) & 0xff;
1847 if(calib_source >= 8)
1849 devpriv->ai_calib_source = calib_source;
1850 if(boardtype.reg_type == ni_reg_611x){
1851 ni_writeb( calib_source_adjust, Cal_Gain_Select_611x );
1862 static int ni_ai_config_analog_trig(comedi_device *dev,comedi_subdevice *s,
1863 comedi_insn *insn, lsampl_t *data)
1865 unsigned int a,b,modebits;
1869 * data[2] is analog line
1870 * data[3] is set level
1871 * data[4] is reset level */
1872 if(!boardtype.has_analog_trig)return -EINVAL;
1873 if(insn->n!=5)return -EINVAL;
1874 if((data[1]&0xffff0000) != COMEDI_EV_SCAN_BEGIN){
1875 data[1]&=~(COMEDI_EV_SCAN_BEGIN&0xffff);
1878 if(data[2]>=boardtype.n_adchan){
1879 data[2]=boardtype.n_adchan-1;
1882 if(data[3]>255){ /* a */
1886 if(data[4]>255){ /* b */
1897 * high mode 00 00 01 10
1898 * low mode 00 00 10 01
1900 * hysteresis low mode 10 00 00 01
1901 * hysteresis high mode 01 00 00 10
1902 * middle mode 10 01 01 10
1907 modebits=data[1]&0xff;
1909 /* two level mode */
1914 modebits=((data[1]&0xf)<<4)|((data[1]&0xf0)>>4);
1916 devpriv->atrig_low = a;
1917 devpriv->atrig_high = b;
1919 case 0x81: /* low hysteresis mode */
1920 devpriv->atrig_mode = 6;
1922 case 0x42: /* high hysteresis mode */
1923 devpriv->atrig_mode = 3;
1925 case 0x96: /* middle window mode */
1926 devpriv->atrig_mode = 2;
1933 /* one level mode */
1939 case 0x06: /* high window mode */
1940 devpriv->atrig_high = a;
1941 devpriv->atrig_mode = 0;
1943 case 0x09: /* low window mode */
1944 devpriv->atrig_low = a;
1945 devpriv->atrig_mode = 1;
1952 if(err)return -EAGAIN;
1956 /* munge data from unsigned to 2's complement for analog output bipolar modes */
1957 static void ni_ao_munge(comedi_device *dev, comedi_subdevice *s,
1958 void *data, unsigned int num_bytes, unsigned int chan_index )
1960 comedi_async *async = s->async;
1963 unsigned int offset;
1964 unsigned int length = num_bytes / sizeof( sampl_t );
1965 sampl_t *array = data;
1967 offset = 1 << (boardtype.aobits - 1);
1968 for(i = 0; i < length; i++)
1970 range = CR_RANGE( async->cmd.chanlist[ chan_index ] );
1971 if(boardtype.ao_unipolar == 0 || (range & 1) == 0 )
1974 array[i] = cpu_to_le16( array[i] );
1977 chan_index %= async->cmd.chanlist_len;
1981 static int ni_ao_config_chanlist(comedi_device *dev, comedi_subdevice *s,
1982 unsigned int chanspec[], unsigned int n_chans)
1990 for(i=0;i<n_chans;i++){
1991 chan = CR_CHAN(chanspec[i]);
1992 range = CR_RANGE(chanspec[i]);
1994 conf = AO_Channel(chan);
1996 if(boardtype.ao_unipolar){
1999 invert = (1<<(boardtype.aobits-1));
2007 invert = (1<<(boardtype.aobits-1));
2010 /* not all boards can deglitch, but this shouldn't hurt */
2011 if(chanspec[i] & CR_DEGLITCH)
2012 conf |= AO_Deglitch;
2014 /* analog reference */
2015 /* AREF_OTHER connects AO ground to AI ground, i think */
2016 conf |= (CR_AREF(chanspec[i])==AREF_OTHER)? AO_Ground_Ref : 0;
2018 devpriv->ao_conf[chan] = conf;
2020 ni_writew(conf,AO_Configuration);
2025 static int ni_ao_insn_read(comedi_device *dev,comedi_subdevice *s,
2026 comedi_insn *insn,lsampl_t *data)
2028 data[0] = devpriv->ao[CR_CHAN(insn->chanspec)];
2033 static int ni_ao_insn_write(comedi_device *dev,comedi_subdevice *s,
2034 comedi_insn *insn,lsampl_t *data)
2036 unsigned int chan = CR_CHAN(insn->chanspec);
2037 unsigned int invert;
2039 invert = ni_ao_config_chanlist(dev,s,&insn->chanspec,1);
2041 devpriv->ao[chan] = data[0];
2043 ni_writew(data[0] ^ invert,(chan)? DAC1_Direct_Data : DAC0_Direct_Data);
2048 static int ni_ao_insn_write_671x(comedi_device *dev,comedi_subdevice *s,
2049 comedi_insn *insn,lsampl_t *data)
2051 unsigned int chan = CR_CHAN(insn->chanspec);
2052 unsigned int invert;
2054 ao_win_out(1 << chan, AO_Immediate_671x);
2055 invert = 1 << (boardtype.aobits - 1);
2057 ni_ao_config_chanlist(dev,s,&insn->chanspec,1);
2059 devpriv->ao[chan] = data[0];
2060 ao_win_out(data[0] ^ invert, DACx_Direct_Data_671x(chan));
2065 static int ni_ao_inttrig(comedi_device *dev,comedi_subdevice *s,
2066 unsigned int trignum)
2071 if(trignum!=0)return -EINVAL;
2073 win_out(devpriv->ao_mode3|AO_Not_An_UPDATE,AO_Mode_3_Register);
2074 win_out(devpriv->ao_mode3,AO_Mode_3_Register);
2076 /* wait for DACs to be loaded */
2079 win_out(devpriv->ao_cmd1|AO_UI_Arm|AO_UC_Arm|AO_BC_Arm|AO_DAC1_Update_Mode|AO_DAC0_Update_Mode,
2080 AO_Command_1_Register);
2082 bits = AO_Error_Interrupt_Enable;
2084 win_out(0, DAC_FIFO_Clear);
2085 ni_ao_win_outl(dev, 0x6, AO_FIFO_Offset_Load_611x);
2086 ni_ao_setup_MITE_dma(dev, &s->async->cmd);
2087 ret = ni_ao_wait_for_dma_load(dev);
2088 if(ret < 0) return ret;
2090 ni_set_bits(dev, Interrupt_B_Enable_Register, AO_FIFO_Interrupt_Enable, 0);
2092 ret = ni_ao_prep_fifo(dev,s);
2093 if(ret==0)return -EPIPE;
2095 bits |= AO_FIFO_Interrupt_Enable;
2097 ni_set_bits(dev, Interrupt_B_Enable_Register, bits, 1);
2099 win_out(devpriv->ao_cmd2|AO_START1_Pulse,AO_Command_2_Register);
2101 s->async->inttrig=NULL;
2106 static int ni_ao_cmd(comedi_device *dev,comedi_subdevice *s)
2108 comedi_cmd *cmd = &s->async->cmd;
2113 trigvar = ni_ns_to_timer(&cmd->scan_begin_arg,TRIG_ROUND_NEAREST);
2115 win_out(AO_Configuration_Start,Joint_Reset_Register);
2117 win_out(AO_Disarm,AO_Command_1_Register);
2119 if(boardtype.reg_type & ni_reg_6xxx_mask)
2121 ao_win_out(CLEAR_WG, AO_Misc_611x);
2124 for(i = 0; i < cmd->chanlist_len; i++)
2128 chan = CR_CHAN(cmd->chanlist[i]);
2130 ao_win_out(chan, AO_Waveform_Generation_611x);
2132 ao_win_out(bits, AO_Timed_611x);
2135 ni_ao_config_chanlist(dev,s,cmd->chanlist,cmd->chanlist_len);
2137 if(cmd->stop_src==TRIG_NONE){
2138 devpriv->ao_mode1|=AO_Continuous;
2139 devpriv->ao_mode1&=~AO_Trigger_Once;
2141 devpriv->ao_mode1&=~AO_Continuous;
2142 devpriv->ao_mode1|=AO_Trigger_Once;
2144 win_out(devpriv->ao_mode1,AO_Mode_1_Register);
2145 devpriv->ao_trigger_select&=~(AO_START1_Polarity|AO_START1_Select(-1));
2146 devpriv->ao_trigger_select|=AO_START1_Edge|AO_START1_Sync;
2147 win_out(devpriv->ao_trigger_select,AO_Trigger_Select_Register);
2148 devpriv->ao_mode3&=~AO_Trigger_Length;
2149 win_out(devpriv->ao_mode3,AO_Mode_3_Register);
2151 win_out(devpriv->ao_mode1,AO_Mode_1_Register);
2152 devpriv->ao_mode2&=~AO_BC_Initial_Load_Source;
2153 win_out(devpriv->ao_mode2,AO_Mode_2_Register);
2154 if(cmd->stop_src==TRIG_NONE){
2155 win_out2(0xffffff,AO_BC_Load_A_Register);
2157 win_out2(0,AO_BC_Load_A_Register);
2159 win_out(AO_BC_Load,AO_Command_1_Register);
2160 devpriv->ao_mode2&=~AO_UC_Initial_Load_Source;
2161 win_out(devpriv->ao_mode2,AO_Mode_2_Register);
2162 switch(cmd->stop_src){
2164 win_out2(cmd->stop_arg,AO_UC_Load_A_Register);
2165 win_out(AO_UC_Load,AO_Command_1_Register);
2166 win_out2(cmd->stop_arg - 1,AO_UC_Load_A_Register);
2169 win_out2(0xffffff,AO_UC_Load_A_Register);
2170 win_out(AO_UC_Load,AO_Command_1_Register);
2171 win_out2(0xffffff,AO_UC_Load_A_Register);
2174 win_out2(0,AO_UC_Load_A_Register);
2175 win_out(AO_UC_Load,AO_Command_1_Register);
2176 win_out2(cmd->stop_arg,AO_UC_Load_A_Register);
2179 devpriv->ao_cmd2&=~AO_BC_Gate_Enable;
2180 win_out(devpriv->ao_cmd2,AO_Command_2_Register);
2181 devpriv->ao_mode1&=~(AO_UI_Source_Select(0x1f)|AO_UI_Source_Polarity);
2182 win_out(devpriv->ao_mode1,AO_Mode_1_Register);
2183 devpriv->ao_mode2&=~(AO_UI_Reload_Mode(3)|AO_UI_Initial_Load_Source);
2184 win_out(devpriv->ao_mode2,AO_Mode_2_Register);
2185 win_out2(1,AO_UI_Load_A_Register);
2186 win_out(AO_UI_Load,AO_Command_1_Register);
2187 win_out2(trigvar,AO_UI_Load_A_Register);
2189 if(boardtype.reg_type == ni_reg_normal){
2190 if(cmd->scan_end_arg>1){
2191 devpriv->ao_mode1|=AO_Multiple_Channels;
2192 win_out(AO_Number_Of_Channels(cmd->scan_end_arg-1)|
2193 AO_UPDATE_Output_Select(1),
2194 AO_Output_Control_Register);
2196 devpriv->ao_mode1&=~AO_Multiple_Channels;
2197 win_out(AO_Number_Of_Channels(CR_CHAN(cmd->chanlist[0]))|
2198 AO_UPDATE_Output_Select(1),
2199 AO_Output_Control_Register);
2201 win_out(devpriv->ao_mode1,AO_Mode_1_Register);
2204 win_out(AO_DAC0_Update_Mode|AO_DAC1_Update_Mode,AO_Command_1_Register);
2206 devpriv->ao_mode3|=AO_Stop_On_Overrun_Error;
2207 win_out(devpriv->ao_mode3,AO_Mode_3_Register);
2209 devpriv->ao_mode2 &= AO_FIFO_Mode_Mask;
2211 devpriv->ao_mode2 |= AO_FIFO_Mode_HF_to_F;
2213 devpriv->ao_mode2 |= AO_FIFO_Mode_HF;
2215 devpriv->ao_mode2 &= ~AO_FIFO_Retransmit_Enable;
2216 win_out(devpriv->ao_mode2,AO_Mode_2_Register);
2218 bits = AO_BC_Source_Select | AO_UPDATE_Pulse_Width |
2219 AO_TMRDACWR_Pulse_Width;
2220 if( boardtype.ao_fifo_depth )
2221 bits |= AO_FIFO_Enable;
2222 win_out(bits, AO_Personal_Register);
2223 // enable sending of ao dma requests
2224 win_out(AO_AOFREQ_Enable, AO_Start_Select_Register);
2226 win_out(AO_Configuration_End,Joint_Reset_Register);
2228 if(cmd->stop_src==TRIG_COUNT) {
2229 win_out(AO_BC_TC_Interrupt_Ack,Interrupt_B_Ack_Register);
2230 ni_set_bits(dev, Interrupt_B_Enable_Register,
2231 AO_BC_TC_Interrupt_Enable, 1);
2234 s->async->inttrig=ni_ao_inttrig;
2239 static int ni_ao_cmdtest(comedi_device *dev,comedi_subdevice *s,comedi_cmd *cmd)
2244 /* step 1: make sure trigger sources are trivially valid */
2247 cmd->start_src &= TRIG_INT;
2248 if(!cmd->start_src || tmp!=cmd->start_src)err++;
2250 tmp=cmd->scan_begin_src;
2251 cmd->scan_begin_src &= TRIG_TIMER;
2252 if(!cmd->scan_begin_src || tmp!=cmd->scan_begin_src)err++;
2254 tmp=cmd->convert_src;
2255 cmd->convert_src &= TRIG_NOW;
2256 if(!cmd->convert_src || tmp!=cmd->convert_src)err++;
2258 tmp=cmd->scan_end_src;
2259 cmd->scan_end_src &= TRIG_COUNT;
2260 if(!cmd->scan_end_src || tmp!=cmd->scan_end_src)err++;
2263 cmd->stop_src &= TRIG_COUNT|TRIG_NONE;
2264 if(!cmd->stop_src || tmp!=cmd->stop_src)err++;
2268 /* step 2: make sure trigger sources are unique and mutually compatible */
2270 if(cmd->stop_src!=TRIG_COUNT &&
2271 cmd->stop_src!=TRIG_NONE)err++;
2275 /* step 3: make sure arguments are trivially compatible */
2277 if(cmd->start_arg!=0){
2282 /* XXX need ao_speed */
2283 if(cmd->scan_begin_arg<boardtype.ao_speed){
2284 cmd->scan_begin_arg=boardtype.ao_speed;
2288 if(cmd->scan_begin_arg>TIMER_BASE*0xffffff){ /* XXX check */
2289 cmd->scan_begin_arg=TIMER_BASE*0xffffff;
2292 if(cmd->convert_arg!=0){
2296 if(cmd->scan_end_arg!=cmd->chanlist_len){
2297 cmd->scan_end_arg=cmd->chanlist_len;
2300 if(cmd->stop_src==TRIG_COUNT){ /* XXX check */
2301 if(cmd->stop_arg>0x00ffffff){
2302 cmd->stop_arg=0x00ffffff;
2307 if(cmd->stop_arg!=0){
2315 /* step 4: fix up any arguments */
2317 tmp = cmd->scan_begin_arg;
2318 ni_ns_to_timer(&cmd->scan_begin_arg,cmd->flags&TRIG_ROUND_MASK);
2319 if(tmp!=cmd->scan_begin_arg)err++;
2323 /* step 5: fix up chanlist */
2325 if(cmd->chanlist_len != cmd->scan_end_arg){
2326 cmd->chanlist_len = cmd->scan_end_arg;
2336 static int ni_ao_reset(comedi_device *dev,comedi_subdevice *s)
2338 //devpriv->ao0p=0x0000;
2339 //ni_writew(devpriv->ao0p,AO_Configuration);
2341 //devpriv->ao1p=AO_Channel(1);
2342 //ni_writew(devpriv->ao1p,AO_Configuration);
2345 mite_dma_disarm(devpriv->mite, AO_DMA_CHAN);
2346 writel(CHOR_DMARESET | CHOR_FRESET, devpriv->mite->mite_io_addr + MITE_CHOR +
2347 CHAN_OFFSET(AO_DMA_CHAN));
2350 win_out(AO_Configuration_Start,Joint_Reset_Register);
2351 win_out(AO_Disarm,AO_Command_1_Register);
2352 ni_set_bits(dev,Interrupt_B_Enable_Register,~0,0);
2353 win_out(0x0010,AO_Personal_Register);
2354 win_out(0x3f98,Interrupt_B_Ack_Register);
2355 win_out(AO_BC_Source_Select | AO_UPDATE_Pulse_Width |
2356 AO_TMRDACWR_Pulse_Width, AO_Personal_Register);
2357 win_out(0,AO_Output_Control_Register);
2358 win_out(0,AO_Start_Select_Register);
2360 win_out(devpriv->ao_cmd1,AO_Command_1_Register);
2362 devpriv->ao_mode1=0;
2363 devpriv->ao_mode2=0;
2364 devpriv->ao_mode3=0;
2365 devpriv->ao_trigger_select=0;
2366 if(boardtype.reg_type & ni_reg_6xxx_mask){
2367 ao_win_out(0x3, AO_Immediate_671x);
2368 ao_win_out(CLEAR_WG, AO_Misc_611x);
2374 static int ni_dio_insn_config(comedi_device *dev,comedi_subdevice *s,
2375 comedi_insn *insn,lsampl_t *data)
2378 printk("ni_dio_insn_config() chan=%d io=%d\n",
2379 CR_CHAN(insn->chanspec),data[0]);
2381 if(insn->n!=1)return -EINVAL;
2384 s->io_bits |= 1<<CR_CHAN(insn->chanspec);
2387 s->io_bits &= ~(1<<CR_CHAN(insn->chanspec));
2393 devpriv->dio_control &= ~DIO_Pins_Dir_Mask;
2394 devpriv->dio_control |= DIO_Pins_Dir(s->io_bits);
2395 win_out(devpriv->dio_control,DIO_Control_Register);
2400 static int ni_dio_insn_bits(comedi_device *dev,comedi_subdevice *s,
2401 comedi_insn *insn,lsampl_t *data)
2404 printk("ni_dio_insn_bits() mask=0x%x bits=0x%x\n",data[0],data[1]);
2406 if(insn->n!=2)return -EINVAL;
2408 /* Perform check to make sure we're not using the
2409 serial part of the dio */
2410 if((data[0] & (DIO_SDIN | DIO_SDOUT)) && devpriv->serial_interval_ns)
2413 s->state &= ~data[0];
2414 s->state |= (data[0]&data[1]);
2415 devpriv->dio_output &= ~DIO_Parallel_Data_Mask;
2416 devpriv->dio_output |= DIO_Parallel_Data_Out(s->state);
2417 win_out(devpriv->dio_output,DIO_Output_Register);
2419 data[1] = win_in(DIO_Parallel_Input_Register);
2424 static int ni_serial_insn_config(comedi_device *dev,comedi_subdevice *s,
2425 comedi_insn *insn,lsampl_t *data)
2428 unsigned char byte_out, byte_in;
2430 if(insn->n!=2)return -EINVAL;
2433 case INSN_CONFIG_SERIAL_CLOCK:
2436 printk("SPI serial clock Config cd\n", data[1]);
2438 devpriv->serial_hw_mode = 1;
2439 devpriv->dio_control |= DIO_HW_Serial_Enable;
2441 if(data[1] == SERIAL_DISABLED) {
2442 devpriv->serial_hw_mode = 0;
2443 devpriv->dio_control &= ~(DIO_HW_Serial_Enable |
2444 DIO_Software_Serial_Control);
2445 data[1] = SERIAL_DISABLED;
2446 devpriv->serial_interval_ns = data[1];
2448 else if(data[1] <= SERIAL_600NS) {
2449 /* Warning: this clock speed is too fast to reliably
2451 devpriv->dio_control &= ~DIO_HW_Serial_Timebase;
2452 devpriv->clock_and_fout |= Slow_Internal_Timebase;
2453 devpriv->clock_and_fout &= ~DIO_Serial_Out_Divide_By_2;
2454 data[1] = SERIAL_600NS;
2455 devpriv->serial_interval_ns = data[1];
2457 else if(data[1] <= SERIAL_1_2US) {
2458 devpriv->dio_control &= ~DIO_HW_Serial_Timebase;
2459 devpriv->clock_and_fout |= Slow_Internal_Timebase |
2460 DIO_Serial_Out_Divide_By_2;
2461 data[1] = SERIAL_1_2US;
2462 devpriv->serial_interval_ns = data[1];
2464 else if(data[1] <= SERIAL_10US) {
2465 devpriv->dio_control |= DIO_HW_Serial_Timebase;
2466 devpriv->clock_and_fout |= Slow_Internal_Timebase |
2467 DIO_Serial_Out_Divide_By_2;
2468 /* Note: DIO_Serial_Out_Divide_By_2 only affects
2469 600ns/1.2us. If you turn divide_by_2 off with the
2470 slow clock, you will still get 10us, except then
2471 all your delays are wrong. */
2472 data[1] = SERIAL_10US;
2473 devpriv->serial_interval_ns = data[1];
2476 devpriv->dio_control &= ~(DIO_HW_Serial_Enable |
2477 DIO_Software_Serial_Control);
2478 devpriv->serial_hw_mode = 0;
2479 data[1] = (data[1] / 1000) * 1000;
2480 devpriv->serial_interval_ns = data[1];
2483 win_out(devpriv->dio_control,DIO_Control_Register);
2484 win_out(devpriv->clock_and_fout,Clock_and_FOUT_Register);
2489 case INSN_CONFIG_BIDIRECTIONAL_DATA:
2491 if(devpriv->serial_interval_ns == 0) {
2495 byte_out = data[1] & 0xFF;
2497 if(devpriv->serial_hw_mode) {
2498 err = ni_serial_hw_readwrite8(dev,s,byte_out,&byte_in);
2499 } else if(devpriv->serial_interval_ns > 0) {
2500 err = ni_serial_sw_readwrite8(dev,s,byte_out,&byte_in);
2502 printk("ni_serial_insn_config: serial disabled!\n");
2505 if(err < 0) return err;
2506 data[1] = byte_in & 0xFF;
2516 static int ni_serial_hw_readwrite8(comedi_device *dev,comedi_subdevice *s,
2517 unsigned char data_out,
2518 unsigned char *data_in)
2520 unsigned int status1;
2521 int err = 0, count = 20;
2524 printk("ni_serial_hw_readwrite8: outputting 0x%x\n", data_out);
2527 devpriv->dio_output &= ~DIO_Serial_Data_Mask;
2528 devpriv->dio_output |= DIO_Serial_Data_Out(data_out);
2529 win_out(devpriv->dio_output,DIO_Output_Register);
2531 status1 = win_in(Joint_Status_1_Register);
2532 if(status1 & DIO_Serial_IO_In_Progress_St) {
2537 devpriv->dio_control |= DIO_HW_Serial_Start;
2538 win_out(devpriv->dio_control,DIO_Control_Register);
2539 devpriv->dio_control &= ~DIO_HW_Serial_Start;
2541 /* Wait until STC says we're done, but don't loop infinitely. Also,
2542 we don't have to keep updating the window address for this. */
2544 while((status1 = win_in(Joint_Status_1_Register)) & DIO_Serial_IO_In_Progress_St) {
2545 /* Delay one bit per loop */
2546 comedi_udelay((devpriv->serial_interval_ns + 999) / 1000);
2548 printk("ni_serial_hw_readwrite8: SPI serial I/O didn't finish in time!\n");
2554 /* Delay for last bit. This delay is absolutely necessary, because
2555 DIO_Serial_IO_In_Progress_St goes high one bit too early. */
2556 comedi_udelay((devpriv->serial_interval_ns + 999) / 1000);
2558 if(data_in != NULL) {
2559 *data_in = win_in(DIO_Serial_Input_Register);
2561 printk("ni_serial_hw_readwrite8: inputted 0x%x\n", *data_in);
2566 win_out(devpriv->dio_control,DIO_Control_Register);
2571 static int ni_serial_sw_readwrite8(comedi_device *dev,comedi_subdevice *s,
2572 unsigned char data_out,
2573 unsigned char *data_in)
2575 unsigned char mask, input = 0;
2578 printk("ni_serial_sw_readwrite8: outputting 0x%x\n", data_out);
2581 /* Wait for one bit before transfer */
2582 comedi_udelay((devpriv->serial_interval_ns + 999) / 1000);
2584 for(mask = 0x80; mask; mask >>= 1) {
2585 /* Output current bit; note that we cannot touch s->state
2586 because it is a per-subdevice field, and serial is
2587 a separate subdevice from DIO. */
2588 devpriv->dio_output &= ~DIO_SDOUT;
2589 if(data_out & mask) {
2590 devpriv->dio_output |= DIO_SDOUT;
2592 win_out(devpriv->dio_output,DIO_Output_Register);
2594 /* Assert SDCLK (active low, inverted), wait for half of
2595 the delay, deassert SDCLK, and wait for the other half. */
2596 devpriv->dio_control |= DIO_Software_Serial_Control;
2597 win_out(devpriv->dio_control,DIO_Control_Register);
2599 comedi_udelay((devpriv->serial_interval_ns + 999) / 2000);
2601 devpriv->dio_control &= ~DIO_Software_Serial_Control;
2602 win_out(devpriv->dio_control,DIO_Control_Register);
2604 comedi_udelay((devpriv->serial_interval_ns + 999) / 2000);
2606 /* Input current bit */
2607 if(win_in(DIO_Parallel_Input_Register) & DIO_SDIN) {
2608 /* printk("DIO_P_I_R: 0x%x\n", win_in(DIO_Parallel_Input_Register)); */
2613 printk("ni_serial_sw_readwrite8: inputted 0x%x\n", input);
2615 if(data_in) *data_in = input;
2620 static void mio_common_detach(comedi_device *dev)
2622 if(dev->subdevices && boardtype.has_8255)
2623 subdev_8255_cleanup(dev,dev->subdevices+3);
2626 static void init_ao_67xx(comedi_device *dev, comedi_subdevice *s)
2630 for(i = 0; i < s->n_chan; i++)
2631 ni_ao_win_outw(dev, AO_Channel(i) | 0x0, AO_Configuration_2_67xx);
2634 static int ni_E_init(comedi_device *dev,comedi_devconfig *it)
2636 comedi_subdevice *s;
2639 if(alloc_subdevices(dev, 10) < 0)
2642 /* analog input subdevice */
2644 s=dev->subdevices+0;
2646 if(boardtype.n_adchan){
2647 s->type=COMEDI_SUBD_AI;
2648 s->subdev_flags=SDF_READABLE|SDF_DIFF;
2649 if(boardtype.reg_type == ni_reg_normal)
2650 s->subdev_flags |= SDF_GROUND | SDF_COMMON | SDF_OTHER;
2651 s->subdev_flags|=SDF_DITHER;
2652 s->n_chan=boardtype.n_adchan;
2653 s->len_chanlist=512;
2654 s->maxdata=(1<<boardtype.adbits)-1;
2655 s->range_table=ni_range_lkup[boardtype.gainlkup];
2656 s->insn_read=ni_ai_insn_read;
2657 s->insn_config=ni_ai_insn_config;
2658 s->do_cmdtest=ni_ai_cmdtest;
2659 s->do_cmd=ni_ai_cmd;
2660 s->cancel=ni_ai_reset;
2662 s->munge=ni_ai_munge;
2664 s->type=COMEDI_SUBD_UNUSED;
2667 /* analog output subdevice */
2669 s=dev->subdevices+1;
2670 if(boardtype.n_aochan){
2671 dev->write_subdev=s;
2672 s->type=COMEDI_SUBD_AO;
2673 s->subdev_flags=SDF_WRITABLE|SDF_DEGLITCH|SDF_GROUND;
2674 s->n_chan=boardtype.n_aochan;
2675 s->maxdata=(1<<boardtype.aobits)-1;
2676 if(boardtype.ao_unipolar){
2677 s->range_table=&range_ni_E_ao_ext; /* XXX wrong for some boards */
2679 s->range_table=&range_bipolar10;
2681 s->insn_read=ni_ao_insn_read;
2682 if(boardtype.reg_type & ni_reg_6xxx_mask){
2683 s->insn_write=ni_ao_insn_write_671x;
2685 s->insn_write=ni_ao_insn_write;
2687 if(boardtype.ao_fifo_depth){
2688 s->do_cmd=ni_ao_cmd;
2689 s->do_cmdtest=ni_ao_cmdtest;
2690 s->len_chanlist = 2;
2691 s->munge=ni_ao_munge;
2693 s->cancel=ni_ao_reset;
2695 s->type=COMEDI_SUBD_UNUSED;
2697 if((boardtype.reg_type & ni_reg_67xx_mask))
2698 init_ao_67xx(dev, s);
2700 /* digital i/o subdevice */
2702 s=dev->subdevices+2;
2703 s->type=COMEDI_SUBD_DIO;
2704 s->subdev_flags=SDF_WRITABLE|SDF_READABLE;
2707 s->range_table=&range_digital;
2708 s->io_bits=0; /* all bits input */
2709 s->insn_bits=ni_dio_insn_bits;
2710 s->insn_config=ni_dio_insn_config;
2713 devpriv->dio_control = DIO_Pins_Dir(s->io_bits);
2714 win_out(devpriv->dio_control,DIO_Control_Register);
2717 s=dev->subdevices+3;
2718 if(boardtype.has_8255){
2719 subdev_8255_init(dev,s,ni_8255_callback,(unsigned long)dev);
2721 s->type=COMEDI_SUBD_UNUSED;
2724 /* general purpose counter/timer device */
2725 s=dev->subdevices+4;
2726 s->type=COMEDI_SUBD_COUNTER;
2727 s->subdev_flags=SDF_READABLE|SDF_WRITABLE;
2728 s->insn_read= ni_gpct_insn_read;
2729 s->insn_write= ni_gpct_insn_write;
2730 s->insn_config=ni_gpct_insn_config;
2733 devpriv->an_trig_etc_reg = 0;
2737 /* calibration subdevice -- ai and ao */
2738 s=dev->subdevices+5;
2739 s->type=COMEDI_SUBD_CALIB;
2740 s->subdev_flags=SDF_WRITABLE|SDF_INTERNAL;
2741 s->insn_read=ni_calib_insn_read;
2742 s->insn_write=ni_calib_insn_write;
2743 caldac_setup(dev,s);
2746 s=dev->subdevices+6;
2747 s->type=COMEDI_SUBD_MEMORY;
2748 s->subdev_flags=SDF_READABLE|SDF_INTERNAL;
2751 s->insn_read=ni_eeprom_insn_read;
2754 s=dev->subdevices+7;
2755 s->type=COMEDI_SUBD_DIO;
2756 s->subdev_flags=SDF_READABLE|SDF_WRITABLE|SDF_INTERNAL;
2759 s->insn_bits = ni_pfi_insn_bits;
2760 s->insn_config = ni_pfi_insn_config;
2761 ni_set_bits(dev, IO_Bidirection_Pin_Register, ~0, 0);
2763 /* cs5529 calibration adc */
2764 s = dev->subdevices + 8;
2765 if(boardtype.reg_type & ni_reg_67xx_mask)
2767 s->type = COMEDI_SUBD_AI;
2768 s->subdev_flags = SDF_READABLE | SDF_DIFF | SDF_INTERNAL;
2769 // one channel for each analog output channel
2770 s->n_chan = boardtype.n_aochan;
2771 s->maxdata = (1 << 16) - 1;
2772 s->range_table = &range_unknown; /* XXX */
2773 s->insn_read=cs5529_ai_insn_read;
2774 s->insn_config=NULL;
2778 s->type=COMEDI_SUBD_UNUSED;
2782 s=dev->subdevices+9;
2783 s->type=COMEDI_SUBD_SERIAL;
2784 s->subdev_flags=SDF_READABLE|SDF_WRITABLE|SDF_INTERNAL;
2787 s->insn_config = ni_serial_insn_config;
2788 devpriv->serial_interval_ns = 0;
2789 devpriv->serial_hw_mode = 0;
2791 /* ai configuration */
2792 ni_ai_reset(dev,dev->subdevices+0);
2793 if(boardtype.reg_type == ni_reg_normal){
2794 devpriv->clock_and_fout =
2795 Slow_Internal_Time_Divide_By_2 |
2796 Slow_Internal_Timebase |
2797 Clock_To_Board_Divide_By_2 |
2799 AI_Output_Divide_By_2 |
2800 AO_Output_Divide_By_2;
2802 devpriv->clock_and_fout =
2803 Slow_Internal_Time_Divide_By_2 |
2804 Slow_Internal_Timebase |
2805 Clock_To_Board_Divide_By_2 |
2808 win_out(devpriv->clock_and_fout, Clock_and_FOUT_Register);
2810 /* analog output configuration */
2811 ni_ao_reset(dev,dev->subdevices + 1);
2814 win_out((IRQ_POLARITY?Interrupt_Output_Polarity:0) |
2815 (Interrupt_Output_On_3_Pins&0) |
2816 Interrupt_A_Enable |
2817 Interrupt_B_Enable |
2818 Interrupt_A_Output_Select(interrupt_pin(dev->irq)) |
2819 Interrupt_B_Output_Select(interrupt_pin(dev->irq)),
2820 Interrupt_Control_Register
2825 /* tell the STC which dma channels to use for AI and AO */
2826 bits = 1 << ( AI_DMA_CHAN );
2827 bits |= 1 << ( AO_DMA_CHAN + 4 );
2828 ni_writeb( bits, AI_AO_Select);
2829 /* tell the STC which dma channels to use for
2830 * General purpose counters 0 and 1 */
2831 bits = 1 << ( GPC0_DMA_CHAN );
2832 bits |= 1 << ( GPC1_DMA_CHAN + 4 );
2833 ni_writeb( bits, G0_G1_Select);
2836 if(boardtype.reg_type != ni_reg_normal)
2838 ni_writeb( 0, Magic_611x );
2848 static int ni_8255_callback(int dir,int port,int data,unsigned long arg)
2850 comedi_device *dev=(comedi_device *)arg;
2853 ni_writeb(data,Port_A+2*port);
2856 return ni_readb(Port_A+2*port);
2861 presents the EEPROM as a subdevice
2864 static int ni_eeprom_insn_read(comedi_device *dev,comedi_subdevice *s,
2865 comedi_insn *insn,lsampl_t *data)
2867 data[0]=ni_read_eeprom(dev,CR_CHAN(insn->chanspec));
2873 reads bytes out of eeprom
2876 static int ni_read_eeprom(comedi_device *dev,int addr)
2881 bitstring=0x0300|((addr&0x100)<<3)|(addr&0xff);
2882 ni_writeb(0x04,Serial_Command);
2883 for(bit=0x8000;bit;bit>>=1){
2884 ni_writeb(0x04|((bit&bitstring)?0x02:0),Serial_Command);
2885 ni_writeb(0x05|((bit&bitstring)?0x02:0),Serial_Command);
2888 for(bit=0x80;bit;bit>>=1){
2889 ni_writeb(0x04,Serial_Command);
2890 ni_writeb(0x05,Serial_Command);
2891 bitstring|=((ni_readb(XXX_Status)&PROMOUT)?bit:0);
2893 ni_writeb(0x00,Serial_Command);
2898 static void ni_write_caldac(comedi_device *dev,int addr,int val);
2900 calibration subdevice
2902 static int ni_calib_insn_write(comedi_device *dev,comedi_subdevice *s,
2903 comedi_insn *insn,lsampl_t *data)
2905 ni_write_caldac(dev,CR_CHAN(insn->chanspec),data[0]);
2910 static int ni_calib_insn_read(comedi_device *dev,comedi_subdevice *s,
2911 comedi_insn *insn,lsampl_t *data)
2913 data[0] = devpriv->caldacs[CR_CHAN(insn->chanspec)];
2918 static int pack_mb88341(int addr,int val,int *bitstring);
2919 static int pack_dac8800(int addr,int val,int *bitstring);
2920 static int pack_dac8043(int addr,int val,int *bitstring);
2921 static int pack_ad8522(int addr,int val,int *bitstring);
2922 static int pack_ad8804(int addr,int val,int *bitstring);
2923 static int pack_ad8842(int addr,int val,int *bitstring);
2925 struct caldac_struct{
2928 int (*packbits)(int,int,int *);
2931 static struct caldac_struct caldacs[] = {
2932 [mb88341] = { 12, 8, pack_mb88341 },
2933 [dac8800] = { 8, 8, pack_dac8800 },
2934 [dac8043] = { 1, 12, pack_dac8043 },
2935 [ad8522] = { 2, 12, pack_ad8522 },
2936 [ad8804] = { 12, 8, pack_ad8804 },
2937 [ad8842] = { 8, 8, pack_ad8842 },
2938 [ad8804_debug] = { 16, 8, pack_ad8804 },
2941 static void caldac_setup(comedi_device *dev,comedi_subdevice *s)
2951 type = boardtype.caldac[0];
2952 if(type==caldac_none)return;
2953 n_bits=caldacs[type].n_bits;
2955 type = boardtype.caldac[i];
2956 if(type==caldac_none)break;
2957 if(caldacs[type].n_bits!=n_bits)diffbits=1;
2958 n_chans+=caldacs[type].n_chans;
2965 if(n_chans>MAX_N_CALDACS){
2966 printk("BUG! MAX_N_CALDACS too small\n");
2968 s->maxdata_list=devpriv->caldac_maxdata_list;
2970 for(i=0;i<n_dacs;i++){
2971 type = boardtype.caldac[i];
2972 for(j=0;j<caldacs[type].n_chans;j++){
2973 s->maxdata_list[chan]=
2974 (1<<caldacs[type].n_bits)-1;
2979 for( chan = 0; chan < s->n_chan; chan++ )
2980 ni_write_caldac( dev, i, s->maxdata_list[ i ] / 2 );
2982 type = boardtype.caldac[0];
2983 s->maxdata=(1<<caldacs[type].n_bits)-1;
2985 for( chan = 0; chan < s->n_chan; chan++ )
2986 ni_write_caldac( dev, i, s->maxdata / 2 );
2990 static void ni_write_caldac(comedi_device *dev,int addr,int val)
2992 unsigned int loadbit=0,bits=0,bit,bitstring=0;
2996 //printk("ni_write_caldac: chan=%d val=%d\n",addr,val);
2997 if( devpriv->caldacs[ addr ] == val ) return;
2998 devpriv->caldacs[ addr ] = val;
3001 type = boardtype.caldac[i];
3002 if(type==caldac_none)break;
3003 if(addr<caldacs[type].n_chans){
3004 bits=caldacs[type].packbits(addr,val,&bitstring);
3005 loadbit=SerDacLd(i);
3006 //printk("caldac: using i=%d addr=%d %x\n",i,addr,bitstring);
3009 addr-=caldacs[type].n_chans;
3012 for(bit=1<<(bits-1);bit;bit>>=1){
3013 ni_writeb(((bit&bitstring)?0x02:0),Serial_Command);
3015 ni_writeb(1|((bit&bitstring)?0x02:0),Serial_Command);
3018 ni_writeb(loadbit,Serial_Command);
3020 ni_writeb(0,Serial_Command);
3025 static int pack_mb88341(int addr,int val,int *bitstring)
3029 Note that address bits are reversed. Thanks to
3030 Ingo Keen for noticing this.
3032 Note also that the 88341 expects address values from
3033 1-12, whereas we use channel numbers 0-11. The NI
3034 docs use 1-12, also, so be careful here.
3037 *bitstring=((addr&0x1)<<11) |
3045 static int pack_dac8800(int addr,int val,int *bitstring)
3047 *bitstring=((addr&0x7)<<8)|(val&0xff);
3051 static int pack_dac8043(int addr,int val,int *bitstring)
3053 *bitstring=val&0xfff;
3057 static int pack_ad8522(int addr,int val,int *bitstring)
3059 *bitstring=(val&0xfff)|(addr ? 0xc000:0xa000);
3063 static int pack_ad8804(int addr,int val,int *bitstring)
3065 *bitstring=((addr&0xf)<<8) | (val&0xff);
3069 static int pack_ad8842(int addr,int val,int *bitstring)
3071 *bitstring=((addr+1)<<8) | (val&0xff);
3081 * General Purpose Counter/Timer section
3086 * Low level stuff...Each STC counter has two 24 bit load registers
3087 * (A&B). Just make it easier to access them.
3089 * These are inlined _only_ because they are used once in subsequent
3090 * code. Otherwise they should not be inlined.
3092 static inline void GPCT_Load_A(comedi_device *dev, int chan, unsigned int value)
3094 win_out2( value & 0x00ffffff, G_Load_A_Register(chan));
3097 static inline void GPCT_Load_B(comedi_device *dev, int chan, unsigned int value)
3099 win_out2( value & 0x00ffffff, G_Load_B_Register(chan));
3102 /* Load a value into the counter, using register A as the intermediate step.
3103 * You might use GPCT_Load_Using_A to load a 0x000000 into a counter
3106 static void GPCT_Load_Using_A(comedi_device *dev, int chan, unsigned int value)
3108 devpriv->gpct_mode[chan] &= (~G_Load_Source_Select);
3109 win_out( devpriv->gpct_mode[chan],G_Mode_Register(chan));
3110 GPCT_Load_A(dev,chan,value);
3111 win_out( devpriv->gpct_command[chan]|G_Load,G_Command_Register(chan));
3115 * Read the GPCTs current value.
3117 static int GPCT_G_Watch(comedi_device *dev, int chan)
3119 unsigned int hi1,hi2,lo;
3121 devpriv->gpct_command[chan] &= ~G_Save_Trace;
3122 win_out( devpriv->gpct_command[chan],G_Command_Register(chan));
3124 devpriv->gpct_command[chan] |= G_Save_Trace;
3125 win_out( devpriv->gpct_command[chan], G_Command_Register(chan));
3127 /* This procedure is used because the two registers cannot
3128 * be read atomically. */
3130 hi1 = win_in( G_Save_Register_High(chan));
3131 lo = win_in(G_Save_Register_Low(chan));
3132 hi2 = win_in( G_Save_Register_High(chan));
3135 return (hi1<<16)|lo;
3139 static int GPCT_Disarm(comedi_device *dev, int chan)
3141 win_out( devpriv->gpct_command[chan] | G_Disarm,G_Command_Register(chan));
3146 static int GPCT_Arm(comedi_device *dev, int chan)
3148 win_out( devpriv->gpct_command[chan] | G_Arm,G_Command_Register(chan));
3149 /* If the counter is doing pulse width measurement, then make
3150 sure that the counter did not start counting right away. This would
3151 indicate that we started acquiring the pulse after it had already
3152 started and our measurement would be inaccurate */
3153 if(devpriv->gpct_cur_operation[chan] == GPCT_SINGLE_PW){
3156 g_status=win_in(G_Status_Register);
3159 //TIM 5/2/01 possible error with very short pulses
3160 if((G0_Counting_St & g_status)|| !(G0_Armed_St&g_status)) {
3161 //error: we missed the beginning of the pulse
3162 return -EINVAL; //there is probably a more accurate error code...
3165 if((G1_Counting_St & g_status)|| !(G1_Armed_St&g_status)) {
3166 //error: we missed the beginning of the pulse
3174 static int GPCT_Set_Source(comedi_device *dev,int chan ,int source)
3176 //printk("GPCT_Set_Source...");
3177 devpriv->gpct_input_select[chan] &= ~G_Source_Select(0x1f);//reset gate to 0
3179 case GPCT_INT_CLOCK:
3180 devpriv->gpct_input_select[chan] |= G_Source_Select(0);//INT_TIMEBASE
3184 devpriv->gpct_input_select[chan] |= G_Source_Select(9);//PFI8
3186 devpriv->gpct_input_select[chan] |= G_Source_Select(4);//PFI3
3191 win_out(devpriv->gpct_input_select[chan], G_Input_Select_Register(chan));
3192 //printk("exit GPCT_Set_Source\n");
3196 static int GPCT_Set_Gate(comedi_device *dev,int chan ,int gate)
3198 //printk("GPCT_Set_Gate...");
3199 devpriv->gpct_input_select[chan] &= ~G_Gate_Select(0x1f);//reset gate to 0
3202 devpriv->gpct_input_select[chan] |= G_Gate_Select(31);//Low
3203 devpriv->gpct_mode[chan] |= G_Gate_Polarity;
3206 devpriv->gpct_mode[chan] &= ~G_Gate_Polarity;
3208 devpriv->gpct_input_select[chan] |= G_Gate_Select(10);//PFI9
3210 devpriv->gpct_input_select[chan] |= G_Gate_Select(5);//PFI4
3216 win_out(devpriv->gpct_input_select[chan], G_Input_Select_Register(chan));
3217 win_out(devpriv->gpct_mode[chan], G_Mode_Register(chan));
3218 //printk("exit GPCT_Set_Gate\n");
3222 static int GPCT_Set_Direction(comedi_device *dev,int chan,int direction)
3224 //printk("GPCT_Set_Direction...");
3226 devpriv->gpct_command[chan] &= ~G_Up_Down(0x3);
3227 switch (direction) {
3229 devpriv->gpct_command[chan] |= G_Up_Down(1);
3232 devpriv->gpct_command[chan] |= G_Up_Down(0);
3235 devpriv->gpct_command[chan] |= G_Up_Down(2);
3238 printk("Error direction=0x%08x..",direction);
3241 win_out(devpriv->gpct_command[chan], G_Command_Register(chan));
3242 //TIM 4/23/01 win_out(devpriv->gpct_mode[chan], G_Mode_Register(chan));
3243 //printk("exit GPCT_Set_Direction\n");
3247 static void GPCT_Event_Counting(comedi_device *dev,int chan)
3250 //NOTE: possible residual bits from multibit masks can corrupt
3251 //If you config for several measurements between Resets, watch out!
3253 //printk("GPCT_Event_Counting...");
3255 devpriv->gpct_cur_operation[chan] = GPCT_SIMPLE_EVENT;
3258 devpriv->gpct_mode[chan] &= ~(G_Gating_Mode(0x3));
3259 devpriv->gpct_mode[chan] |= G_Gating_Mode(1);
3261 // Trigger_Mode_For_Edge_Gate = 1
3262 devpriv->gpct_mode[chan] &= ~(G_Trigger_Mode_For_Edge_Gate(0x3));
3263 devpriv->gpct_mode[chan] |= G_Trigger_Mode_For_Edge_Gate(2);
3265 win_out( devpriv->gpct_mode[chan],G_Mode_Register(chan));
3266 //printk("exit GPCT_Event_Counting\n");
3269 static void GPCT_Period_Meas(comedi_device *dev, int chan)
3271 //printk("GPCT_Period_Meas...");
3273 devpriv->gpct_cur_operation[chan] = GPCT_SINGLE_PERIOD;
3276 //NOTE: possible residual bits from multibit masks can corrupt
3277 //If you config for several measurements between Resets, watch out!
3278 devpriv->gpct_mode[chan] &= ~G_OR_Gate;
3279 devpriv->gpct_mode[chan] &= ~G_Gate_Select_Load_Source;
3282 devpriv->gpct_mode[chan] &= ~(G_Output_Mode(0x3));
3283 devpriv->gpct_mode[chan] |= G_Output_Mode(3);
3287 devpriv->gpct_mode[chan] &= ~(G_Gating_Mode(0x3));
3288 devpriv->gpct_mode[chan] |= G_Gating_Mode(2);
3290 // Trigger_Mode_For_Edge_Gate=0
3291 devpriv->gpct_mode[chan] &= ~(G_Trigger_Mode_For_Edge_Gate(0x3));
3292 devpriv->gpct_mode[chan] |= G_Trigger_Mode_For_Edge_Gate(0);
3294 devpriv->gpct_mode[chan] |= G_Reload_Source_Switching;
3295 devpriv->gpct_mode[chan] &= ~G_Loading_On_Gate;
3296 devpriv->gpct_mode[chan] &= ~G_Loading_On_TC;
3297 devpriv->gpct_mode[chan] &= ~G_Gate_On_Both_Edges;
3300 devpriv->gpct_mode[chan] &= ~(G_Stop_Mode(0x3));
3301 devpriv->gpct_mode[chan] |= G_Stop_Mode(0);
3303 // Counting_Once = 2
3304 devpriv->gpct_mode[chan] &= ~(G_Counting_Once(0x3));
3305 devpriv->gpct_mode[chan] |= G_Counting_Once(2);
3308 devpriv->gpct_command[chan] &= ~(G_Up_Down(0x3));
3309 devpriv->gpct_command[chan] |= G_Up_Down(1);
3311 win_out( devpriv->gpct_mode[chan],G_Mode_Register(chan));
3312 win_out( devpriv->gpct_command[chan],G_Command_Register(chan));
3313 //printk("exit GPCT_Period_Meas\n");
3316 static void GPCT_Pulse_Width_Meas(comedi_device *dev, int chan)
3318 //printk("GPCT_Pulse_Width_Meas...");
3320 devpriv->gpct_cur_operation[chan] = GPCT_SINGLE_PW;
3322 devpriv->gpct_mode[chan] &= ~G_OR_Gate;
3323 devpriv->gpct_mode[chan] &= ~G_Gate_Select_Load_Source;
3326 devpriv->gpct_mode[chan] &= ~(G_Output_Mode(0x3));
3327 devpriv->gpct_mode[chan] |= G_Output_Mode(3);
3330 devpriv->gpct_mode[chan] &= ~(G_Gating_Mode(0x3));
3331 devpriv->gpct_mode[chan] |= G_Gating_Mode(1);//TIM 4/24/01 was 2
3333 // Trigger_Mode_For_Edge_Gate=2
3334 devpriv->gpct_mode[chan] &= ~(G_Trigger_Mode_For_Edge_Gate(0x3));
3335 devpriv->gpct_mode[chan] |= G_Trigger_Mode_For_Edge_Gate(2);//TIM 4/24/01 was 0
3338 devpriv->gpct_mode[chan] |= G_Reload_Source_Switching;//TIM 4/24/01 was 1
3339 devpriv->gpct_mode[chan] &= ~G_Loading_On_Gate;//TIM 4/24/01 was 0
3341 devpriv->gpct_mode[chan] &= ~G_Loading_On_TC;
3342 devpriv->gpct_mode[chan] &= ~G_Gate_On_Both_Edges;
3345 devpriv->gpct_mode[chan] &= ~(G_Stop_Mode(0x3));
3346 devpriv->gpct_mode[chan] |= G_Stop_Mode(0);
3348 // Counting_Once = 2
3349 devpriv->gpct_mode[chan] &= ~(G_Counting_Once(0x3));
3350 devpriv->gpct_mode[chan] |= G_Counting_Once(2);
3353 devpriv->gpct_command[chan] &= ~(G_Up_Down(0x3));
3354 devpriv->gpct_command[chan] |= G_Up_Down(1);
3356 win_out( devpriv->gpct_mode[chan],G_Mode_Register(chan));
3357 win_out( devpriv->gpct_command[chan],G_Command_Register(chan));
3359 //printk("exit GPCT_Pulse_Width_Meas\n");
3362 /* GPCT_Gen_Single_Pulse() creates pulse of length pulsewidth which starts after the Arm
3363 signal is sent. The pulse is delayed by the value already in the counter. This function could
3364 be modified to send a pulse in response to a trigger event at its gate.*/
3365 static void GPCT_Gen_Single_Pulse(comedi_device *dev, int chan, unsigned int length)
3367 //printk("GPCT_Gen_Cont...");
3369 devpriv->gpct_cur_operation[chan] = GPCT_SINGLE_PULSE_OUT;
3371 // Set length of the pulse
3372 GPCT_Load_B(dev,chan, length-1);
3374 //Load next time using B, This is reset by GPCT_Load_Using_A()
3375 devpriv->gpct_mode[chan] |= G_Load_Source_Select;
3377 devpriv->gpct_mode[chan] &= ~G_OR_Gate;
3378 devpriv->gpct_mode[chan] &= ~G_Gate_Select_Load_Source;
3381 devpriv->gpct_mode[chan] &= ~(G_Output_Mode(0x3));
3382 devpriv->gpct_mode[chan] |= G_Output_Mode(2); //TIM 4/26/01 was 3
3384 //Gating Mode=0 for untriggered single pulse
3385 devpriv->gpct_mode[chan] &= ~(G_Gating_Mode(0x3));
3386 devpriv->gpct_mode[chan] |= G_Gating_Mode(0); //TIM 4/25/01 was 1
3388 // Trigger_Mode_For_Edge_Gate=0
3389 devpriv->gpct_mode[chan] &= ~(G_Trigger_Mode_For_Edge_Gate(0x3));
3390 devpriv->gpct_mode[chan] |= G_Trigger_Mode_For_Edge_Gate(2);
3393 devpriv->gpct_mode[chan] |= G_Reload_Source_Switching;
3394 devpriv->gpct_mode[chan] &= ~G_Loading_On_Gate;
3395 devpriv->gpct_mode[chan] |= G_Loading_On_TC; //TIM 4/25/01
3396 devpriv->gpct_mode[chan] &= ~G_Gate_On_Both_Edges;
3399 devpriv->gpct_mode[chan] &= ~(G_Stop_Mode(0x3));
3400 devpriv->gpct_mode[chan] |= G_Stop_Mode(2); //TIM 4/25/01
3402 // Counting_Once = 2
3403 devpriv->gpct_mode[chan] &= ~(G_Counting_Once(0x3));
3404 devpriv->gpct_mode[chan] |= G_Counting_Once(1); //TIM 4/25/01
3407 devpriv->gpct_command[chan] &= ~(G_Up_Down(0x3));
3408 devpriv->gpct_command[chan] |= G_Up_Down(0); //TIM 4/25/01 was 1
3410 win_out( devpriv->gpct_mode[chan],G_Mode_Register(chan));
3411 win_out( devpriv->gpct_command[chan],G_Command_Register(chan));
3413 //printk("exit GPCT_Gen_Cont\n");
3416 static void GPCT_Gen_Cont_Pulse(comedi_device *dev, int chan, unsigned int length)
3418 //printk("GPCT_Gen_Cont...");
3420 devpriv->gpct_cur_operation[chan] = GPCT_CONT_PULSE_OUT;
3422 // Set length of the pulse
3423 GPCT_Load_B(dev,chan, length-1);
3425 //Load next time using B, This is reset by GPCT_Load_Using_A()
3426 devpriv->gpct_mode[chan] |= G_Load_Source_Select;
3428 devpriv->gpct_mode[chan] &= ~G_OR_Gate;
3429 devpriv->gpct_mode[chan] &= ~G_Gate_Select_Load_Source;
3432 devpriv->gpct_mode[chan] &= ~(G_Output_Mode(0x3));
3433 devpriv->gpct_mode[chan] |= G_Output_Mode(2); //TIM 4/26/01 was 3
3435 //Gating Mode=0 for untriggered single pulse
3436 devpriv->gpct_mode[chan] &= ~(G_Gating_Mode(0x3));
3437 devpriv->gpct_mode[chan] |= G_Gating_Mode(0); //TIM 4/26/01 was 0
3439 // Trigger_Mode_For_Edge_Gate=0
3440 devpriv->gpct_mode[chan] &= ~(G_Trigger_Mode_For_Edge_Gate(0x3));
3441 devpriv->gpct_mode[chan] |= G_Trigger_Mode_For_Edge_Gate(2);
3444 devpriv->gpct_mode[chan] |= G_Reload_Source_Switching;
3445 devpriv->gpct_mode[chan] &= ~G_Loading_On_Gate;
3446 devpriv->gpct_mode[chan] |= G_Loading_On_TC;
3447 devpriv->gpct_mode[chan] &= ~G_Gate_On_Both_Edges;
3450 devpriv->gpct_mode[chan] &= ~(G_Stop_Mode(0x3));
3451 devpriv->gpct_mode[chan] |= G_Stop_Mode(0); //TIM 4/26/01
3453 // Counting_Once = 2
3454 devpriv->gpct_mode[chan] &= ~(G_Counting_Once(0x3));
3455 devpriv->gpct_mode[chan] |= G_Counting_Once(0); //TIM 4/26/01
3458 devpriv->gpct_command[chan] &= ~(G_Up_Down(0x3));
3459 devpriv->gpct_command[chan] |= G_Up_Down(0);
3462 //This seems pretty unsafe since I don't think it is cleared anywhere.
3463 //I don't think this is working
3464 //devpriv->gpct_command[chan] &= ~G_Bank_Switch_Enable;
3465 //devpriv->gpct_command[chan] &= ~G_Bank_Switch_Mode;
3468 win_out( devpriv->gpct_mode[chan],G_Mode_Register(chan));
3469 win_out( devpriv->gpct_command[chan],G_Command_Register(chan));
3471 //printk("exit GPCT_Gen_Cont\n");
3474 static void GPCT_Reset(comedi_device *dev, int chan)
3478 //printk("GPCT_Reset...");
3479 devpriv->gpct_cur_operation[chan] = GPCT_RESET;
3483 win_out(G0_Reset,Joint_Reset_Register);
3484 ni_set_bits(dev,Interrupt_A_Enable_Register,G0_TC_Interrupt_Enable, 0);
3485 ni_set_bits(dev,Interrupt_A_Enable_Register,G0_Gate_Interrupt_Enable,0);
3486 temp_ack_reg |= G0_Gate_Error_Confirm;
3487 temp_ack_reg |= G0_TC_Error_Confirm;
3488 temp_ack_reg |= G0_TC_Interrupt_Ack;
3489 temp_ack_reg |= G0_Gate_Interrupt_Ack;
3490 win_out(temp_ack_reg,Interrupt_A_Ack_Register);
3492 //problem...this interferes with the other ctr...
3493 devpriv->an_trig_etc_reg |= GPFO_0_Output_Enable;
3494 win_out(devpriv->an_trig_etc_reg, Analog_Trigger_Etc_Register);
3497 win_out(G1_Reset,Joint_Reset_Register);
3498 ni_set_bits(dev,Interrupt_B_Enable_Register,G1_TC_Interrupt_Enable, 0);
3499 ni_set_bits(dev,Interrupt_B_Enable_Register,G0_Gate_Interrupt_Enable,0);
3500 temp_ack_reg |= G1_Gate_Error_Confirm;
3501 temp_ack_reg |= G1_TC_Error_Confirm;
3502 temp_ack_reg |= G1_TC_Interrupt_Ack;
3503 temp_ack_reg |= G1_Gate_Interrupt_Ack;
3504 win_out(temp_ack_reg,Interrupt_B_Ack_Register);
3506 devpriv->an_trig_etc_reg |= GPFO_1_Output_Enable;
3507 win_out(devpriv->an_trig_etc_reg, Analog_Trigger_Etc_Register);
3511 devpriv->gpct_mode[chan] = 0;
3512 devpriv->gpct_input_select[chan] = 0;
3513 devpriv->gpct_command[chan] = 0;
3515 devpriv->gpct_command[chan] |= G_Synchronized_Gate;
3517 win_out( devpriv->gpct_mode[chan],G_Mode_Register(chan));
3518 win_out( devpriv->gpct_input_select[chan],G_Input_Select_Register(chan));
3519 win_out( 0,G_Autoincrement_Register(chan));
3521 //printk("exit GPCT_Reset\n");
3524 static int ni_gpct_insn_config(comedi_device *dev,comedi_subdevice *s,
3525 comedi_insn *insn,lsampl_t *data)
3528 //printk("data[0] is 0x%08x, data[1] is 0x%08x\n",data[0],data[1]);
3531 if(insn->n!=1)return -EINVAL;
3532 GPCT_Reset(dev,insn->chanspec);
3534 case GPCT_SET_SOURCE:
3535 if(insn->n!=2)return -EINVAL;
3536 retval=GPCT_Set_Source(dev,insn->chanspec,data[1]);
3539 if(insn->n!=2)return -EINVAL;
3540 retval=GPCT_Set_Gate(dev,insn->chanspec,data[1]);
3542 case GPCT_SET_DIRECTION:
3543 if(insn->n!=2) return -EINVAL;
3544 retval=GPCT_Set_Direction(dev,insn->chanspec,data[1]);
3546 case GPCT_GET_INT_CLK_FRQ:
3547 if(insn->n!=2) return -EINVAL;
3548 //There are actually 2 internal clocks on the STC, we always
3549 //use the fast 20MHz one at this time. Tim Ousley 5/1/01
3550 //NOTE: This is not the final interface, ideally the user
3551 //will never need to know the int. clk. freq.
3552 data[1]=50;//50ns = 20MHz = internal timebase of STC
3554 case GPCT_SET_OPERATION:
3555 //TIM 5/1/01 if((insn->n<2)||(insn->n>3))return -EINVAL;
3557 case GPCT_SIMPLE_EVENT:
3558 GPCT_Event_Counting(dev,insn->chanspec);
3560 case GPCT_SINGLE_PERIOD:
3561 GPCT_Period_Meas(dev,insn->chanspec);
3563 case GPCT_SINGLE_PW:
3564 GPCT_Pulse_Width_Meas(dev,insn->chanspec);
3566 case GPCT_SINGLE_PULSE_OUT:
3567 GPCT_Gen_Single_Pulse(dev,insn->chanspec,data[2]);
3569 case GPCT_CONT_PULSE_OUT:
3570 GPCT_Gen_Cont_Pulse(dev,insn->chanspec,data[2]);
3573 printk("unsupported GPCT operation!\n");
3578 if(insn->n!=1)return -EINVAL;
3579 retval=GPCT_Arm(dev,insn->chanspec);
3582 if(insn->n!=1)return -EINVAL;
3583 retval=GPCT_Disarm(dev,insn->chanspec);
3589 //catch any errors from return values
3593 if(data[0]!=GPCT_ARM){
3594 printk("error: retval was %d\n",retval);
3595 printk("data[0] is 0x%08x, data[1] is 0x%08x\n",data[0],data[1]);
3602 static int ni_gpct_insn_read(comedi_device *dev,comedi_subdevice *s,
3603 comedi_insn *insn,lsampl_t *data) {
3605 int chan=insn->chanspec;
3606 int cur_op = devpriv->gpct_cur_operation[chan];
3608 //printk("in ni_gpct_insn_read, n=%d, data[0]=%d\n",insn->chanspec,data[0]);
3609 if(insn->n!=1)return -EINVAL;
3611 data[0] = GPCT_G_Watch(dev,insn->chanspec);
3613 /* for certain modes (period and pulse width measurment), the value
3614 in the counter is not valid until the counter stops. If the value is
3615 invalid, return a 0 */
3616 if((cur_op == GPCT_SINGLE_PERIOD) || (cur_op == GPCT_SINGLE_PW)){
3617 /* is the counter still running? */
3618 if(win_in(G_Status_Register) & (chan?G1_Counting_St:G0_Counting_St))
3624 static int ni_gpct_insn_write(comedi_device *dev,comedi_subdevice *s,
3625 comedi_insn *insn,lsampl_t *data) {
3627 //printk("in ni_gpct_insn_write");
3628 if(insn->n!=1)return -EINVAL;
3629 GPCT_Load_Using_A(dev,insn->chanspec,data[0]);
3636 * Programmable Function Inputs
3640 static int ni_pfi_insn_bits(comedi_device *dev,comedi_subdevice *s,
3641 comedi_insn *insn,lsampl_t *data)
3643 if(insn->n!=2)return -EINVAL;
3650 static int ni_pfi_insn_config(comedi_device *dev,comedi_subdevice *s,
3651 comedi_insn *insn,lsampl_t *data)
3655 if(insn->n!=1)return -EINVAL;
3657 chan = CR_CHAN(insn->chanspec);
3658 if(chan>10)return -EINVAL;
3662 ni_set_bits(dev, IO_Bidirection_Pin_Register, 1<<chan, 1);
3665 ni_set_bits(dev, IO_Bidirection_Pin_Register, 1<<chan, 0);
3674 static int cs5529_wait_for_idle(comedi_device *dev)
3676 unsigned short status;
3677 const int timeout = HZ;
3680 for(i = 0; i < timeout; i++)
3682 status = ni_ao_win_inw(dev, CAL_ADC_Status_67xx);
3683 if((status & CSS_ADC_BUSY) == 0)
3687 set_current_state(TASK_INTERRUPTIBLE);
3688 if(schedule_timeout(1))
3693 //printk("looped %i times waiting for idle\n", i);
3696 rt_printk("%s: %s: timeout\n", __FILE__, __FUNCTION__);
3702 static void cs5529_command(comedi_device *dev, unsigned short value)
3704 static const int timeout = 100;
3707 ni_ao_win_outw(dev, value, CAL_ADC_Command_67xx);
3708 /* give time for command to start being serially clocked into cs5529.
3709 * this insures that the CSS_ADC_BUSY bit will get properly
3710 * set before we exit this function.
3712 for(i = 0; i < timeout; i++)
3714 if((ni_ao_win_inw(dev, CAL_ADC_Status_67xx) & CSS_ADC_BUSY))
3718 //printk("looped %i times writing command to cs5529\n", i);
3721 comedi_error(dev, "possible problem - never saw adc go busy?");
3725 /* write to cs5529 register */
3726 static void cs5529_config_write(comedi_device *dev, unsigned int value, unsigned int reg_select_bits)
3728 ni_ao_win_outw(dev, ((value >> 16) & 0xff), CAL_ADC_Config_Data_High_Word_67xx);
3729 ni_ao_win_outw(dev, (value & 0xffff), CAL_ADC_Config_Data_Low_Word_67xx);
3730 reg_select_bits &= CSCMD_REGISTER_SELECT_MASK;
3731 cs5529_command(dev, CSCMD_COMMAND | reg_select_bits);
3732 if(cs5529_wait_for_idle(dev))
3733 comedi_error(dev, "time or signal in cs5529_config_write()");
3736 /* read from cs5529 register */
3737 static unsigned int cs5529_config_read(comedi_device *dev, unsigned int reg_select_bits)
3741 reg_select_bits &= CSCMD_REGISTER_SELECT_MASK;
3742 cs5529_command(dev, CSCMD_COMMAND | CSCMD_READ | reg_select_bits);
3743 if(cs5529_wait_for_idle(dev))
3744 comedi_error(dev, "timeout or signal in cs5529_config_read()");
3745 value = (ni_ao_win_inw(dev, CAL_ADC_Config_Data_High_Word_67xx) << 16) & 0xff0000;
3746 value |= ni_ao_win_inw(dev, CAL_ADC_Config_Data_Low_Word_67xx) & 0xffff;
3750 static int cs5529_do_conversion(comedi_device *dev, unsigned short *data)
3753 unsigned short status;
3755 cs5529_command(dev, CSCMD_COMMAND | CSCMD_SINGLE_CONVERSION);
3756 retval = cs5529_wait_for_idle(dev);
3759 comedi_error(dev, "timeout or signal in cs5529_do_conversion()");
3762 status = ni_ao_win_inw(dev, CAL_ADC_Status_67xx);
3763 if(status & CSS_OSC_DETECT)
3765 rt_printk("ni_mio_common: cs5529 conversion error, status CSS_OSC_DETECT\n");
3768 if(status & CSS_OVERRANGE)
3770 rt_printk("ni_mio_common: cs5529 conversion error, overrange (ignoring)\n");
3774 *data = ni_ao_win_inw(dev, CAL_ADC_Data_67xx);
3775 /* cs5529 returns 16 bit signed data in bipolar mode */
3781 static int cs5529_ai_insn_read(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,lsampl_t *data)
3784 unsigned short sample;
3785 unsigned int channel_select;
3786 const unsigned int INTERNAL_REF = 0x1000;
3788 /* Set calibration adc source. Docs lie, reference select bits 8 to 11
3789 * do nothing. bit 12 seems to chooses internal reference voltage, bit
3790 * 13 causes the adc input to go overrange (maybe reads external reference?) */
3791 if(insn->chanspec & CR_ALT_SOURCE)
3792 channel_select = INTERNAL_REF;
3794 channel_select = CR_CHAN(insn->chanspec);
3795 ni_ao_win_outw(dev, channel_select, AO_Calibration_Channel_Select_67xx);
3797 for(n = 0; n < insn->n; n++)
3799 retval = cs5529_do_conversion(dev, &sample);
3800 if(retval < 0) return retval;
3806 static int init_cs5529(comedi_device *dev)
3808 unsigned int config_bits = CSCFG_PORT_MODE | CSCFG_WORD_RATE_2180_CYCLES;
3811 /* do self-calibration */
3812 cs5529_config_write(dev, config_bits | CSCFG_SELF_CAL_OFFSET_GAIN, CSCMD_CONFIG_REGISTER);
3813 /* need to force a conversion for calibration to run */
3814 cs5529_do_conversion(dev, NULL);
3816 /* force gain calibration to 1 */
3817 cs5529_config_write(dev, 0x400000, CSCMD_GAIN_REGISTER);
3818 cs5529_config_write(dev, config_bits | CSCFG_SELF_CAL_OFFSET, CSCMD_CONFIG_REGISTER);
3819 if(cs5529_wait_for_idle(dev))
3820 comedi_error(dev, "timeout or signal in init_cs5529()\n");
3824 rt_printk("config: 0x%x\n", cs5529_config_read(dev, CSCMD_CONFIG_REGISTER));
3825 rt_printk("gain: 0x%x\n", cs5529_config_read(dev, CSCMD_GAIN_REGISTER));
3826 rt_printk("offset: 0x%x\n", cs5529_config_read(dev, CSCMD_OFFSET_REGISTER));