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,
216 static void shutdown_ai_command( comedi_device *dev );
218 static int ni_ao_inttrig(comedi_device *dev,comedi_subdevice *s,
219 unsigned int trignum);
221 static int ni_ao_reset(comedi_device *dev,comedi_subdevice *s);
223 static int ni_8255_callback(int dir,int port,int data,unsigned long arg);
225 static int ni_ns_to_timer(int *nanosec,int round_mode);
228 /*GPCT function def's*/
229 static int GPCT_G_Watch(comedi_device *dev, int chan);
231 static void GPCT_Reset(comedi_device *dev, int chan);
232 static void GPCT_Gen_Cont_Pulse(comedi_device *dev, int chan, unsigned int length);
233 static void GPCT_Gen_Single_Pulse(comedi_device *dev, int chan, unsigned int length);
234 static void GPCT_Period_Meas(comedi_device *dev, int chan);
235 static void GPCT_Pulse_Width_Meas(comedi_device *dev, int chan);
236 static void GPCT_Event_Counting(comedi_device *dev,int chan);
237 static int GPCT_Set_Direction(comedi_device *dev,int chan,int direction);
238 static int GPCT_Set_Gate(comedi_device *dev,int chan ,int gate);
239 static int GPCT_Set_Source(comedi_device *dev,int chan ,int source);
241 static int ni_gpct_insn_write(comedi_device *dev,comedi_subdevice *s,
242 comedi_insn *insn,lsampl_t *data);
243 static int ni_gpct_insn_read(comedi_device *dev,comedi_subdevice *s,
244 comedi_insn *insn,lsampl_t *data);
245 static int ni_gpct_insn_config(comedi_device *dev,comedi_subdevice *s,
246 comedi_insn *insn,lsampl_t *data);
248 static int init_cs5529(comedi_device *dev);
249 static int cs5529_do_conversion(comedi_device *dev, unsigned short *data);
250 static int cs5529_ai_insn_read(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,lsampl_t *data);
251 static unsigned int cs5529_config_read(comedi_device *dev, unsigned int reg_select_bits);
252 static void cs5529_config_write(comedi_device *dev, unsigned int value, unsigned int reg_select_bits);
257 AIMODE_HALF_FULL = 1,
262 #define SERIAL_DISABLED 0
263 #define SERIAL_600NS 600
264 #define SERIAL_1_2US 1200
265 #define SERIAL_10US 10000
267 static const int num_adc_stages_611x = 3;
269 static void handle_a_interrupt(comedi_device *dev,unsigned short status,
270 unsigned int m_status);
271 static void handle_b_interrupt(comedi_device *dev,unsigned short status,
272 unsigned int m_status);
273 static void get_last_sample_611x( comedi_device *dev );
275 //static void mite_handle_interrupt(comedi_device *dev,unsigned int status);
276 static int ni_ai_drain_dma(comedi_device *dev );
279 #define win_out2(data,addr) do{ \
280 win_out((data)>>16, (addr)); \
281 win_out((data)&0xffff, (addr)+1); \
285 #define ao_win_out(data,addr) ni_ao_win_outw(dev,data,addr)
286 static inline void ni_ao_win_outw( comedi_device *dev, uint16_t data, int addr )
290 comedi_spin_lock_irqsave(&devpriv->window_lock,flags);
291 ni_writew(addr,AO_Window_Address_611x);
292 ni_writew(data,AO_Window_Data_611x);
293 comedi_spin_unlock_irqrestore(&devpriv->window_lock,flags);
296 static inline void ni_ao_win_outl(comedi_device *dev, uint32_t data, int addr)
300 comedi_spin_lock_irqsave(&devpriv->window_lock,flags);
301 ni_writew(addr,AO_Window_Address_611x);
302 ni_writel(data,AO_Window_Data_611x);
303 comedi_spin_unlock_irqrestore(&devpriv->window_lock,flags);
306 static inline unsigned short ni_ao_win_inw( comedi_device *dev, int addr )
311 comedi_spin_lock_irqsave(&devpriv->window_lock,flags);
312 ni_writew(addr, AO_Window_Address_611x);
313 data = ni_readw(AO_Window_Data_611x);
314 comedi_spin_unlock_irqrestore(&devpriv->window_lock,flags);
318 /* ni_set_bits( ) allows different parts of the ni_mio_common driver to
319 * share registers (such as Interrupt_A_Register) without interfering with
322 * NOTE: the switch/case statements are optimized out for a constant argument
323 * so this is actually quite fast--- If you must wrap another function around this
324 * make it inline to avoid a large speed penalty.
326 * value should only be 1 or 0.
328 static inline void ni_set_bits(comedi_device *dev, int reg, int bits, int value)
332 comedi_spin_lock_irqsave( &devpriv->window_lock, flags );
334 case Interrupt_A_Enable_Register:
336 devpriv->int_a_enable_reg |= bits;
338 devpriv->int_a_enable_reg &= ~bits;
339 comedi_spin_unlock_irqrestore( &devpriv->window_lock, flags );
340 win_out(devpriv->int_a_enable_reg,Interrupt_A_Enable_Register);
342 case Interrupt_B_Enable_Register:
344 devpriv->int_b_enable_reg |= bits;
346 devpriv->int_b_enable_reg &= ~bits;
347 comedi_spin_unlock_irqrestore( &devpriv->window_lock, flags );
348 win_out(devpriv->int_b_enable_reg,Interrupt_B_Enable_Register);
350 case IO_Bidirection_Pin_Register:
352 devpriv->io_bidirection_pin_reg |= bits;
354 devpriv->io_bidirection_pin_reg &= ~bits;
355 comedi_spin_unlock_irqrestore( &devpriv->window_lock, flags );
356 win_out(devpriv->io_bidirection_pin_reg,IO_Bidirection_Pin_Register);
359 printk("Warning ni_set_bits() called with invalid arguments\n");
360 printk("reg is %d\n",reg);
361 comedi_spin_unlock_irqrestore( &devpriv->window_lock, flags );
367 static irqreturn_t ni_E_interrupt(int irq,void *d,struct pt_regs * regs)
369 comedi_device *dev=d;
370 unsigned short a_status;
371 unsigned short b_status;
372 unsigned int m0_status;
373 unsigned int m1_status;
376 struct mite_struct *mite = devpriv->mite;
379 if(dev->attached == 0) return IRQ_NONE;
380 // lock to avoid race with comedi_poll
381 comedi_spin_lock_irqsave(&dev->spinlock, flags);
382 a_status=win_in(AI_Status_1_Register);
383 b_status=win_in(AO_Status_1_Register);
385 m0_status=readl(mite->mite_io_addr + MITE_CHSR(AI_DMA_CHAN));
386 m1_status=readl(mite->mite_io_addr + MITE_CHSR(AO_DMA_CHAN));
392 if(a_status&Interrupt_A_St || m0_status & CHSR_INT )
393 handle_a_interrupt(dev, a_status, m0_status);
394 if(b_status&Interrupt_B_St || m1_status & CHSR_INT )
395 handle_b_interrupt(dev, b_status, m1_status);
396 comedi_spin_unlock_irqrestore(&dev->spinlock, flags);
401 static void ni_sync_ai_dma(struct mite_struct *mite, comedi_device *dev)
404 comedi_subdevice *s = dev->subdevices + 0;
405 comedi_async *async = s->async;
406 unsigned int nbytes, old_alloc_count;
407 unsigned int bytes_per_scan = 2 * async->cmd.chanlist_len;
409 old_alloc_count = async->buf_write_alloc_count;
410 // write alloc as much as we can
411 comedi_buf_write_alloc(s->async, s->async->prealloc_bufsz);
413 nbytes = mite_bytes_transferred(mite, AI_DMA_CHAN);
415 /* We use mite_bytes_read() for the overrun check
416 * because it returns an upper bound, and mite_bytes_transferred
417 * returns a lower bound on the number of bytes actually
419 if( (int)(mite_bytes_read(mite, AI_DMA_CHAN) - old_alloc_count) > 0 ){
420 printk("ni_mio_common: DMA overwrite of free area\n");
422 async->events |= COMEDI_CB_OVERFLOW;
426 count = nbytes - async->buf_write_count;
428 /* it's possible count will be negative due to
429 * conservative value returned by mite_bytes_transferred */
432 comedi_buf_write_free(async, count);
434 async->scan_progress += count;
435 if( async->scan_progress >= bytes_per_scan )
437 async->scan_progress %= bytes_per_scan;
438 async->events |= COMEDI_CB_EOS;
440 async->events |= COMEDI_CB_BLOCK;
443 static void mite_handle_b_linkc(struct mite_struct *mite, comedi_device *dev)
446 comedi_subdevice *s = dev->subdevices + 1;
447 comedi_async *async = s->async;
448 unsigned int nbytes, new_write_count;
450 writel(CHOR_CLRLC, mite->mite_io_addr + MITE_CHOR(AO_DMA_CHAN));
452 new_write_count = async->buf_write_count;
454 nbytes = mite_bytes_read(mite, AO_DMA_CHAN);
455 if( async->cmd.stop_src == TRIG_COUNT &&
456 (int) (nbytes - async->cmd.stop_arg * sizeof( sampl_t ) ) > 0 )
457 nbytes = async->cmd.stop_arg * sizeof( sampl_t );
458 if( (int)(nbytes - devpriv->last_buf_write_count) > 0 ){
459 rt_printk("ni_mio_common: DMA underrun\n");
461 async->events |= COMEDI_CB_OVERFLOW;
465 devpriv->last_buf_write_count = new_write_count;
467 count = nbytes - async->buf_read_count;
469 rt_printk("ni_mio_common: BUG: negative ao count\n");
472 comedi_buf_read_free(async, count);
474 async->events |= COMEDI_CB_BLOCK;
477 static int ni_ao_wait_for_dma_load( comedi_device *dev )
479 static const int timeout = 10000;
482 for(i = 0; i < timeout; i++)
484 unsigned short b_status;
486 b_status = win_in( AO_Status_1_Register );
487 if( b_status & AO_FIFO_Half_Full_St )
489 /* if we poll too often, the pci bus activity seems
490 to slow the dma transfer down */
495 comedi_error(dev, "timed out waiting for dma load");
502 static void ni_handle_eos(comedi_device *dev, comedi_subdevice *s)
504 if(devpriv->aimode == AIMODE_SCAN)
507 static const int timeout = 10;
510 for(i = 0; i < timeout; i++)
512 ni_sync_ai_dma(devpriv->mite, dev);
513 if((s->async->events & COMEDI_CB_EOS)) break;
517 ni_handle_fifo_dregs(dev);
518 s->async->events |= COMEDI_CB_EOS;
521 /* handle special case of single scan using AI_End_On_End_Of_Scan */
522 if( ( devpriv->ai_cmd2 & AI_End_On_End_Of_Scan ) ){
523 shutdown_ai_command( dev );
527 static void shutdown_ai_command( comedi_device *dev )
529 comedi_subdevice *s = dev->subdevices + 0;
532 ni_ai_drain_dma( dev );
533 mite_dma_disarm(devpriv->mite, AI_DMA_CHAN);
535 ni_handle_fifo_dregs(dev);
536 get_last_sample_611x(dev);
538 ni_set_bits(dev, Interrupt_A_Enable_Register,
539 AI_SC_TC_Interrupt_Enable | AI_START1_Interrupt_Enable|
540 AI_START2_Interrupt_Enable| AI_START_Interrupt_Enable|
541 AI_STOP_Interrupt_Enable| AI_Error_Interrupt_Enable|
542 AI_FIFO_Interrupt_Enable,0);
544 s->async->events |= COMEDI_CB_EOA;
547 static void handle_a_interrupt(comedi_device *dev,unsigned short status,
548 unsigned int m_status)
550 comedi_subdevice *s=dev->subdevices+0;
551 unsigned short ack=0;
553 s->async->events = 0;
555 #ifdef DEBUG_INTERRUPT
556 rt_printk("ni_mio_common: interrupt: a_status=%04x m0_status=%08x\n",
558 ni_mio_print_status_a(status);
563 /* Currently, mite.c requires us to handle LINKC and DONE */
564 if(m_status & CHSR_LINKC){
565 writel(CHOR_CLRLC, devpriv->mite->mite_io_addr + MITE_CHOR(AI_DMA_CHAN));
566 ni_sync_ai_dma(devpriv->mite, dev);
569 if(m_status & CHSR_DONE){
570 writel(CHOR_CLRDONE, devpriv->mite->mite_io_addr + MITE_CHOR(AI_DMA_CHAN));
573 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)){
574 printk("unknown mite interrupt, ack! (m_status=%08x)\n", m_status);
575 //mite_print_chsr(m_status);
576 mite_dma_disarm(devpriv->mite, AI_DMA_CHAN );
577 writel(CHOR_DMARESET, devpriv->mite->mite_io_addr + MITE_CHOR(AI_DMA_CHAN));
578 //disable_irq(dev->irq);
582 /* test for all uncommon interrupt events at the same time */
583 if(status&(AI_Overrun_St|AI_Overflow_St|AI_SC_TC_Error_St|AI_SC_TC_St|AI_START1_St)){
585 rt_printk("ni_mio_common: a_status=0xffff. Card removed?\n");
586 /* we probably aren't even running a command now,
587 * so it's a good idea to be careful. */
588 if(s->subdev_flags&SDF_RUNNING){
589 s->async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA;
590 //comedi_event(dev,s,s->async->events);
594 if(status&(AI_Overrun_St|AI_Overflow_St|AI_SC_TC_Error_St)){
595 rt_printk("ni_mio_common: ai error a_status=%04x\n",
597 ni_mio_print_status_a(status);
599 ni_ai_reset(dev,dev->subdevices);
602 shutdown_ai_command( dev );
604 s->async->events |= COMEDI_CB_ERROR;
605 comedi_event(dev,s,s->async->events);
609 if(status&AI_SC_TC_St){
610 #ifdef DEBUG_INTERRUPT
611 rt_printk("ni_mio_common: SC_TC interrupt\n");
613 if(!devpriv->ai_continuous){
614 shutdown_ai_command( dev );
616 ack|=AI_SC_TC_Interrupt_Ack;
618 if(status&AI_START1_St){
619 ack|=AI_START1_Interrupt_Ack;
623 if(status&AI_FIFO_Half_Full_St){
624 ni_handle_fifo_half_full(dev);
628 if( (status & AI_STOP_St) ){
629 ni_handle_eos(dev, s);
630 /* we need to ack the START, also */
631 ack |= AI_STOP_Interrupt_Ack|AI_START_Interrupt_Ack;
634 if(devpriv->aimode==AIMODE_SAMPLE){
635 ni_handle_fifo_dregs(dev);
637 //s->async->events |= COMEDI_CB_SAMPLE;
640 if(ack) win_out(ack,Interrupt_A_Ack_Register);
642 comedi_event(dev,s,s->async->events);
644 #ifdef DEBUG_INTERRUPT
645 status=win_in(AI_Status_1_Register);
646 if(status&Interrupt_A_St){
647 printk("handle_a_interrupt: BUG, didn't clear interrupt. disabling.\n");
648 win_out(0,Interrupt_Control_Register);
653 static void handle_b_interrupt(comedi_device *dev,unsigned short b_status, unsigned int m_status)
655 comedi_subdevice *s=dev->subdevices+1;
656 //unsigned short ack=0;
657 #ifdef DEBUG_INTERRUPT
658 rt_printk("ni_mio_common: interrupt: b_status=%04x m1_status=%08x\n",
660 ni_mio_print_status_b(b_status);
665 /* Currently, mite.c requires us to handle LINKC and DONE */
666 if(m_status & CHSR_LINKC){
667 mite_handle_b_linkc(devpriv->mite, dev);
670 if(m_status & CHSR_DONE){
671 writel(CHOR_CLRDONE, devpriv->mite->mite_io_addr + MITE_CHOR(AO_DMA_CHAN));
674 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)){
675 printk("unknown mite interrupt, ack! (m_status=%08x)\n", m_status);
676 //mite_print_chsr(m_status);
677 mite_dma_disarm(devpriv->mite, AO_DMA_CHAN );
678 writel(CHOR_DMARESET, devpriv->mite->mite_io_addr + MITE_CHOR(AO_DMA_CHAN));
682 if(b_status==0xffff)return;
683 if(b_status&AO_Overrun_St){
684 rt_printk("ni_mio_common: AO FIFO underrun status=0x%04x status2=0x%04x\n",b_status,win_in(AO_Status_2_Register));
686 s->async->events |= COMEDI_CB_OVERFLOW;
689 if(b_status&AO_BC_TC_St){
690 MDPRINTK("ni_mio_common: AO BC_TC status=0x%04x status2=0x%04x\n",b_status,win_in(AO_Status_2_Register));
692 s->async->events |= COMEDI_CB_EOA;
696 if(b_status&AO_FIFO_Request_St){
699 ret = ni_ao_fifo_half_empty(dev,s);
701 rt_printk("ni_mio_common: AO buffer underrun\n");
702 ni_set_bits(dev, Interrupt_B_Enable_Register,
703 AO_FIFO_Interrupt_Enable|AO_Error_Interrupt_Enable, 0);
704 s->async->events |= COMEDI_CB_OVERFLOW;
709 b_status=win_in(AO_Status_1_Register);
710 if(b_status&Interrupt_B_St){
711 if(b_status&AO_FIFO_Request_St){
712 rt_printk("ni_mio_common: AO buffer underrun\n");
714 rt_printk("Ack! didn't clear AO interrupt. b_status=0x%04x\n",b_status);
715 ni_set_bits(dev,Interrupt_B_Enable_Register,~0,0);
717 s->async->events |= COMEDI_CB_OVERFLOW;
720 comedi_event(dev,s,s->async->events);
723 #ifdef DEBUG_STATUS_A
724 static char *status_a_strings[]={
725 "passthru0","fifo","G0_gate","G0_TC",
726 "stop","start","sc_tc","start1",
727 "start2","sc_tc_error","overflow","overrun",
728 "fifo_empty","fifo_half_full","fifo_full","interrupt_a"
731 static void ni_mio_print_status_a(int status)
735 rt_printk("A status:");
738 rt_printk(" %s",status_a_strings[i]);
745 #ifdef DEBUG_STATUS_B
746 static char *status_b_strings[]={
747 "passthru1","fifo","G1_gate","G1_TC",
748 "UI2_TC","UPDATE","UC_TC","BC_TC",
749 "start1","overrun","start","bc_tc_error",
750 "fifo_empty","fifo_half_full","fifo_full","interrupt_b"
753 static void ni_mio_print_status_b(int status)
757 rt_printk("B status:");
760 rt_printk(" %s",status_b_strings[i]);
769 static void ni_ao_fifo_load(comedi_device *dev,comedi_subdevice *s, int n)
771 comedi_async *async = s->async;
772 comedi_cmd *cmd = &async->cmd;
780 chan = async->cur_chan;
782 err &= comedi_buf_get(async, &d);
785 range = CR_RANGE(cmd->chanlist[chan]);
787 if(boardtype.reg_type & ni_reg_6xxx_mask)
789 packed_data = d & 0xffff;
790 /* 6711 only has 16 bit wide ao fifo */
791 if(boardtype.reg_type != ni_reg_6711)
793 err &= comedi_buf_get(async, &d);
797 packed_data |= ( d << 16 ) & 0xffff0000;
799 ni_writel( packed_data, DAC_FIFO_Data_611x );
801 ni_writew(d, DAC_FIFO_Data);
804 chan %= cmd->chanlist_len;
806 async->cur_chan = chan;
808 async->events |= COMEDI_CB_OVERFLOW;
813 * There's a small problem if the FIFO gets really low and we
814 * don't have the data to fill it. Basically, if after we fill
815 * the FIFO with all the data available, the FIFO is _still_
816 * less than half full, we never clear the interrupt. If the
817 * IRQ is in edge mode, we never get another interrupt, because
818 * this one wasn't cleared. If in level mode, we get flooded
819 * with interrupts that we can't fulfill, because nothing ever
820 * gets put into the buffer.
822 * This kind of situation is recoverable, but it is easier to
823 * just pretend we had a FIFO underrun, since there is a good
824 * chance it will happen anyway. This is _not_ the case for
825 * RT code, as RT code might purposely be running close to the
826 * metal. Needs to be fixed eventually.
828 static int ni_ao_fifo_half_empty(comedi_device *dev,comedi_subdevice *s)
832 n = comedi_buf_read_n_available(s);
834 s->async->events |= COMEDI_CB_OVERFLOW;
838 n /= sizeof(sampl_t);
839 if(n > boardtype.ao_fifo_depth / 2)
840 n = boardtype.ao_fifo_depth / 2;
842 ni_ao_fifo_load(dev,s,n);
844 s->async->events |= COMEDI_CB_BLOCK;
849 static int ni_ao_prep_fifo(comedi_device *dev,comedi_subdevice *s)
854 win_out(0,DAC_FIFO_Clear);
855 if(boardtype.reg_type & ni_reg_6xxx_mask)
856 ni_ao_win_outl(dev, 0x6, AO_FIFO_Offset_Load_611x);
859 n = comedi_buf_read_n_available(s);
862 n /= sizeof(sampl_t);
863 if(n > boardtype.ao_fifo_depth)
864 n = boardtype.ao_fifo_depth;
866 ni_ao_fifo_load(dev,s,n);
871 static void ni_ai_fifo_read(comedi_device *dev,comedi_subdevice *s,
874 comedi_async *async = s->async;
877 if(boardtype.reg_type == ni_reg_611x){
881 for( i = 0; i < n / 2; i++ ){
882 dl=ni_readl(ADC_FIFO_Data_611x);
883 /* This may get the hi/lo data in the wrong order */
884 data[0] = (dl>>16) & 0xffff;
885 data[1] = dl & 0xffff;
886 cfc_write_array_to_buffer(s, data, sizeof(data));
888 /* Check if there's a single sample stuck in the FIFO */
890 dl=ni_readl(ADC_FIFO_Data_611x);
891 data[0] = dl & 0xffff;
892 cfc_write_to_buffer(s, data[0]);
895 if( n > sizeof(devpriv->ai_fifo_buffer) / sizeof(devpriv->ai_fifo_buffer[0]))
897 comedi_error( dev, "bug! ai_fifo_buffer too small" );
898 async->events |= COMEDI_CB_ERROR;
901 for(i = 0; i < n; i++){
902 devpriv->ai_fifo_buffer[i] = ni_readw(ADC_FIFO_Data_Register);
904 cfc_write_array_to_buffer( s, devpriv->ai_fifo_buffer,
905 n * sizeof(devpriv->ai_fifo_buffer[0]) );
909 static void ni_handle_fifo_half_full(comedi_device *dev)
912 comedi_subdevice *s=dev->subdevices+0;
914 n=boardtype.ai_fifo_depth/2;
916 ni_ai_fifo_read(dev,s,n);
921 static int ni_ai_drain_dma(comedi_device *dev )
923 struct mite_struct *mite = devpriv->mite;
925 static const int timeout = 10000;
927 for( i = 0; i < timeout; i++ )
929 if( ( win_in( AI_Status_1_Register ) & AI_FIFO_Empty_St ) &&
930 mite_bytes_in_transit( mite, AI_DMA_CHAN ) == 0 )
936 rt_printk( "ni_mio_common: wait for dma drain timed out\n" );
940 ni_sync_ai_dma( mite, dev );
948 static void ni_handle_fifo_dregs(comedi_device *dev)
950 comedi_subdevice *s=dev->subdevices+0;
956 if(boardtype.reg_type == ni_reg_611x){
957 while((win_in(AI_Status_1_Register)&AI_FIFO_Empty_St) == 0){
958 dl=ni_readl(ADC_FIFO_Data_611x);
960 /* This may get the hi/lo data in the wrong order */
962 data[1] = (dl&0xffff);
963 cfc_write_array_to_buffer(s, data, sizeof(data));
966 fifo_empty = win_in(AI_Status_1_Register) & AI_FIFO_Empty_St;
967 while(fifo_empty == 0)
969 for(i = 0; i < sizeof(devpriv->ai_fifo_buffer) / sizeof(devpriv->ai_fifo_buffer[0]); i++)
971 fifo_empty = win_in(AI_Status_1_Register) & AI_FIFO_Empty_St;
972 if(fifo_empty) break;
973 devpriv->ai_fifo_buffer[i] = ni_readw(ADC_FIFO_Data_Register);
975 cfc_write_array_to_buffer( s, devpriv->ai_fifo_buffer,
976 i * sizeof(devpriv->ai_fifo_buffer[0]) );
981 static void get_last_sample_611x( comedi_device *dev )
983 comedi_subdevice *s=dev->subdevices+0;
987 if(boardtype.reg_type != ni_reg_611x) return;
989 /* Check if there's a single sample stuck in the FIFO */
990 if(ni_readb(XXX_Status)&0x80){
991 dl=ni_readl(ADC_FIFO_Data_611x);
993 cfc_write_to_buffer(s, data);
997 static void ni_ai_munge(comedi_device *dev, comedi_subdevice *s,
998 void *data, unsigned int num_bytes, unsigned int chan_index )
1000 comedi_async *async = s->async;
1002 unsigned int length = num_bytes / sizeof( sampl_t );
1003 sampl_t *array = data;
1005 for(i = 0; i < length; i++)
1008 array[i] = le16_to_cpu(array[i]);
1010 array[i] += devpriv->ai_offset[ chan_index ];
1012 chan_index %= async->cmd.chanlist_len;
1018 static void ni_ai_setup_MITE_dma(comedi_device *dev,comedi_cmd *cmd)
1020 struct mite_struct *mite = devpriv->mite;
1021 struct mite_channel *mite_chan = &mite->channels[ AI_DMA_CHAN ];
1022 comedi_subdevice *s = dev->subdevices + 0;
1024 /* write alloc the entire buffer */
1025 comedi_buf_write_alloc(s->async, s->async->prealloc_bufsz);
1027 mite_chan->current_link = 0;
1028 mite_chan->dir = COMEDI_INPUT;
1029 if(boardtype.reg_type == ni_reg_611x)
1030 mite_prep_dma(mite, AI_DMA_CHAN, 32, 16);
1032 mite_prep_dma(mite, AI_DMA_CHAN, 16, 16);
1035 mite_dma_arm(mite, AI_DMA_CHAN);
1038 static void ni_ao_setup_MITE_dma(comedi_device *dev,comedi_cmd *cmd)
1040 struct mite_struct *mite = devpriv->mite;
1041 struct mite_channel *mite_chan = &mite->channels[ AO_DMA_CHAN ];
1042 comedi_subdevice *s = dev->subdevices + 1;
1044 devpriv->last_buf_write_count = s->async->buf_write_count;
1046 mite_chan->current_link = 0;
1047 mite_chan->dir = COMEDI_OUTPUT;
1048 if(boardtype.reg_type & (ni_reg_611x | ni_reg_6713))
1049 mite_prep_dma(mite, AO_DMA_CHAN, 32, 32);
1051 mite_prep_dma(mite, AO_DMA_CHAN, 16, 16);
1054 mite_dma_arm(mite, AO_DMA_CHAN);
1060 used for both cancel ioctl and board initialization
1062 this is pretty harsh for a cancel, but it works...
1065 static int ni_ai_reset(comedi_device *dev,comedi_subdevice *s)
1068 mite_dma_disarm(devpriv->mite, AI_DMA_CHAN);
1070 /* ai configuration */
1071 win_out(AI_Configuration_Start | AI_Reset, Joint_Reset_Register);
1073 ni_set_bits(dev, Interrupt_A_Enable_Register,
1074 AI_SC_TC_Interrupt_Enable | AI_START1_Interrupt_Enable|
1075 AI_START2_Interrupt_Enable| AI_START_Interrupt_Enable|
1076 AI_STOP_Interrupt_Enable| AI_Error_Interrupt_Enable|
1077 AI_FIFO_Interrupt_Enable,0);
1079 win_out(1,ADC_FIFO_Clear);
1081 ni_writeb(0, Misc_Command);
1083 win_out(AI_Disarm, AI_Command_1_Register); /* reset pulses */
1084 win_out(AI_Start_Stop | AI_Mode_1_Reserved /*| AI_Trigger_Once */,
1085 AI_Mode_1_Register);
1086 win_out(0x0000,AI_Mode_2_Register);
1087 /* generate FIFO interrupts on non-empty */
1088 win_out((0<<6)|0x0000,AI_Mode_3_Register);
1089 if(boardtype.reg_type == ni_reg_normal){
1090 win_out(AI_SHIFTIN_Pulse_Width |
1092 AI_CONVERT_Pulse_Width |
1093 AI_LOCALMUX_CLK_Pulse_Width, AI_Personal_Register);
1094 win_out(AI_SCAN_IN_PROG_Output_Select(3) |
1095 AI_EXTMUX_CLK_Output_Select(0) |
1096 AI_LOCALMUX_CLK_Output_Select(2) |
1097 AI_SC_TC_Output_Select(3) |
1098 AI_CONVERT_Output_Select(2),AI_Output_Control_Register);
1099 }else{/* 611x boards */
1100 win_out(AI_SHIFTIN_Pulse_Width |
1102 AI_LOCALMUX_CLK_Pulse_Width, AI_Personal_Register);
1103 win_out(AI_SCAN_IN_PROG_Output_Select(3) |
1104 AI_EXTMUX_CLK_Output_Select(0) |
1105 AI_LOCALMUX_CLK_Output_Select(2) |
1106 AI_SC_TC_Output_Select(3) |
1107 AI_CONVERT_Output_Select(3),AI_Output_Control_Register);
1110 /* the following registers should not be changed, because there
1111 * are no backup registers in devpriv. If you want to change
1112 * any of these, add a backup register and other appropriate code:
1113 * AI_Mode_1_Register
1114 * AI_Mode_3_Register
1115 * AI_Personal_Register
1116 * AI_Output_Control_Register
1118 win_out(AI_SC_TC_Error_Confirm | AI_START_Interrupt_Ack |
1119 AI_START2_Interrupt_Ack | AI_START1_Interrupt_Ack |
1120 AI_SC_TC_Interrupt_Ack | AI_Error_Interrupt_Ack |
1121 AI_STOP_Interrupt_Ack, Interrupt_A_Ack_Register); /* clear interrupts */
1123 win_out(AI_Configuration_End,Joint_Reset_Register);
1128 static int ni_ai_poll(comedi_device *dev,comedi_subdevice *s)
1130 unsigned long flags = 0;
1133 // lock to avoid race with interrupt handler
1134 if(in_interrupt() == 0)
1135 comedi_spin_lock_irqsave(&dev->spinlock, flags);
1137 ni_handle_fifo_dregs(dev);
1139 ni_sync_ai_dma(devpriv->mite, dev);
1141 count = s->async->buf_write_count - s->async->buf_read_count;
1142 if(in_interrupt() == 0)
1143 comedi_spin_unlock_irqrestore(&dev->spinlock, flags);
1149 static int ni_ai_insn_read(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,lsampl_t *data)
1153 unsigned short signbits;
1156 ni_load_channelgain_list(dev,1,&insn->chanspec);
1158 win_out(1,ADC_FIFO_Clear);
1160 mask=(1<<boardtype.adbits)-1;
1161 signbits=devpriv->ai_offset[0];
1162 if(boardtype.reg_type == ni_reg_611x){
1163 for(n=0; n < num_adc_stages_611x; n++){
1164 win_out(AI_CONVERT_Pulse, AI_Command_1_Register);
1167 for(n=0; n<insn->n; n++){
1168 win_out(AI_CONVERT_Pulse, AI_Command_1_Register);
1169 /* The 611x has screwy 32-bit FIFOs. */
1171 for(i=0; i<NI_TIMEOUT; i++){
1172 if(ni_readb(XXX_Status)&0x80)
1174 d = ( ni_readl(ADC_FIFO_Data_611x) >> 16 ) & 0xffff;
1177 if(!(win_in(AI_Status_1_Register)&AI_FIFO_Empty_St))
1179 d = ni_readl(ADC_FIFO_Data_611x) & 0xffff;
1184 rt_printk("ni_mio_common: timeout in 611x ni_ai_insn_read\n");
1187 d += signbits; /* subtle: needs to be short addition */
1191 for(n=0;n<insn->n;n++){
1192 win_out(AI_CONVERT_Pulse, AI_Command_1_Register);
1193 for(i=0;i<NI_TIMEOUT;i++){
1194 if(!(win_in(AI_Status_1_Register)&AI_FIFO_Empty_St))
1198 rt_printk("ni_mio_common: timeout in ni_ai_insn_read\n");
1201 d = ni_readw(ADC_FIFO_Data_Register);
1202 d += signbits; /* subtle: needs to be short addition */
1210 * Notes on the 6110 and 6111:
1211 * These boards a slightly different than the rest of the series, since
1212 * they have multiple A/D converters.
1213 * From the driver side, the configuration memory is a
1215 * Configuration Memory Low:
1217 * bit 8: unipolar/bipolar (should be 0 for bipolar)
1218 * bits 0-3: gain. This is 4 bits instead of 3 for the other boards
1219 * 1001 gain=0.1 (+/- 50)
1228 * Configuration Memory High:
1229 * bits 12-14: Channel Type
1230 * 001 for differential
1231 * 000 for calibration
1232 * bit 11: coupling (this is not currently handled)
1236 * valid channels are 0-3
1238 static void ni_load_channelgain_list(comedi_device *dev,unsigned int n_chan,
1241 unsigned int chan,range,aref;
1244 unsigned short offset;
1245 unsigned int dither;
1247 if(n_chan == 1 && boardtype.reg_type == ni_reg_normal){
1248 if(devpriv->changain_state && devpriv->changain_spec==list[0]){
1252 devpriv->changain_state=1;
1253 devpriv->changain_spec=list[0];
1255 devpriv->changain_state=0;
1258 win_out(1,Configuration_Memory_Clear);
1260 offset=1<<(boardtype.adbits-1);
1261 for(i=0;i<n_chan;i++){
1262 if(list[i]&CR_ALT_SOURCE){
1263 chan=devpriv->ai_calib_source;
1265 chan=CR_CHAN(list[i]);
1267 aref=CR_AREF(list[i]);
1268 range=CR_RANGE(list[i]);
1269 dither=((list[i]&CR_ALT_FILTER)!=0);
1271 /* fix the external/internal range differences */
1272 range = ni_gainlkup[boardtype.gainlkup][range];
1273 if(boardtype.reg_type == ni_reg_611x)
1274 devpriv->ai_offset[i] = offset;
1276 devpriv->ai_offset[i] = (range&0x100)?0:offset;
1279 if( ( list[i] & CR_ALT_SOURCE ) )
1281 if(boardtype.reg_type == ni_reg_611x)
1282 ni_writew(CR_CHAN(list[i])&0x0003, Calibration_Channel_Select_611x);
1285 if(boardtype.reg_type == ni_reg_611x)
1290 hi |= AI_DIFFERENTIAL;
1302 hi |= AI_CONFIG_CHANNEL( chan );
1304 ni_writew(hi,Configuration_Memory_High);
1307 if(i == n_chan - 1) lo |= AI_LAST_CHANNEL;
1308 if( dither ) lo |= AI_DITHER;
1310 ni_writew(lo,Configuration_Memory_Low);
1313 /* prime the channel/gain list */
1314 if(boardtype.reg_type == ni_reg_normal){
1315 win_out(AI_CONVERT_Pulse, AI_Command_1_Register);
1316 for(i=0;i<NI_TIMEOUT;i++){
1317 if(!(win_in(AI_Status_1_Register)&AI_FIFO_Empty_St)){
1318 win_out(1,ADC_FIFO_Clear);
1323 rt_printk("ni_mio_common: timeout loading channel/gain list\n");
1327 #define TIMER_BASE 50 /* 20 Mhz base */
1329 static int ni_ns_to_timer(int *nanosec,int round_mode)
1336 case TRIG_ROUND_NEAREST:
1338 divider=(*nanosec+base/2)/base;
1340 case TRIG_ROUND_DOWN:
1341 divider=(*nanosec)/base;
1344 divider=(*nanosec+base-1)/base;
1348 *nanosec=base*divider;
1352 static int ni_ai_cmdtest(comedi_device *dev,comedi_subdevice *s,comedi_cmd *cmd)
1358 /* step 1: make sure trigger sources are trivially valid */
1361 cmd->start_src &= TRIG_NOW|TRIG_INT|TRIG_EXT;
1362 if(!cmd->start_src || tmp!=cmd->start_src)err++;
1364 tmp=cmd->scan_begin_src;
1365 cmd->scan_begin_src &= TRIG_TIMER|TRIG_EXT;
1366 if(!cmd->scan_begin_src || tmp!=cmd->scan_begin_src)err++;
1368 tmp=cmd->convert_src;
1369 sources = TRIG_TIMER | TRIG_EXT;
1370 if(boardtype.reg_type == ni_reg_611x) sources |= TRIG_NOW;
1371 cmd->convert_src &= sources;
1372 if(!cmd->convert_src || tmp!=cmd->convert_src)err++;
1374 tmp=cmd->scan_end_src;
1375 cmd->scan_end_src &= TRIG_COUNT;
1376 if(!cmd->scan_end_src || tmp!=cmd->scan_end_src)err++;
1379 cmd->stop_src &= TRIG_COUNT|TRIG_NONE;
1380 if(!cmd->stop_src || tmp!=cmd->stop_src)err++;
1384 /* step 2: make sure trigger sources are unique and mutually compatible */
1386 /* note that mutual compatiblity is not an issue here */
1387 if(cmd->start_src!=TRIG_NOW &&
1388 cmd->start_src!=TRIG_INT &&
1389 cmd->start_src!=TRIG_EXT)err++;
1390 if(cmd->scan_begin_src!=TRIG_TIMER &&
1391 cmd->scan_begin_src!=TRIG_EXT &&
1392 cmd->scan_begin_src!=TRIG_OTHER)err++;
1393 if(cmd->convert_src!=TRIG_TIMER &&
1394 cmd->convert_src!=TRIG_EXT &&
1395 cmd->convert_src!=TRIG_NOW)err++;
1396 if(cmd->stop_src!=TRIG_COUNT &&
1397 cmd->stop_src!=TRIG_NONE)err++;
1401 /* step 3: make sure arguments are trivially compatible */
1403 if(cmd->start_src==TRIG_EXT){
1404 /* external trigger */
1405 unsigned int tmp = CR_CHAN(cmd->start_arg);
1407 if(tmp > 9) tmp = 9;
1408 tmp |= (cmd->start_arg & (CR_INVERT | CR_EDGE));
1409 if(cmd->start_arg != tmp){
1410 cmd->start_arg = tmp;
1414 if(cmd->start_arg!=0){
1415 /* true for both TRIG_NOW and TRIG_INT */
1420 if(cmd->scan_begin_src==TRIG_TIMER){
1421 if(cmd->scan_begin_arg<boardtype.ai_speed){
1422 cmd->scan_begin_arg=boardtype.ai_speed;
1425 if(cmd->scan_begin_arg>TIMER_BASE*0xffffff){
1426 cmd->scan_begin_arg=TIMER_BASE*0xffffff;
1429 }else if(cmd->scan_begin_src==TRIG_EXT){
1430 /* external trigger */
1431 unsigned int tmp = CR_CHAN(cmd->scan_begin_arg);
1434 tmp |= (cmd->scan_begin_arg & (CR_INVERT | CR_EDGE));
1435 if(cmd->scan_begin_arg!=tmp){
1436 cmd->scan_begin_arg = tmp;
1439 }else{ /* TRIG_OTHER */
1440 if(cmd->scan_begin_arg){
1441 cmd->scan_begin_arg=0;
1445 if(cmd->convert_src==TRIG_TIMER){
1446 if(boardtype.reg_type == ni_reg_611x){
1447 if(cmd->convert_arg != 0){
1448 cmd->convert_arg = 0;
1452 if(cmd->convert_arg<boardtype.ai_speed){
1453 cmd->convert_arg=boardtype.ai_speed;
1456 if(cmd->convert_arg>TIMER_BASE*0xffffff){
1457 cmd->convert_arg=TIMER_BASE*0xffffff;
1461 }else if(cmd->convert_src == TRIG_EXT){
1462 /* external trigger */
1463 unsigned int tmp = CR_CHAN(cmd->convert_arg);
1466 tmp |= (cmd->convert_arg&(CR_ALT_FILTER|CR_INVERT));
1467 if(cmd->convert_arg!=tmp){
1468 cmd->convert_arg = tmp;
1471 }else if(cmd->convert_src == TRIG_NOW){
1472 if(cmd->convert_arg != 0){
1473 cmd->convert_arg = 0;
1478 if(cmd->scan_end_arg!=cmd->chanlist_len){
1479 cmd->scan_end_arg=cmd->chanlist_len;
1482 if(cmd->stop_src==TRIG_COUNT){
1483 unsigned int max_count = 0x01000000;
1485 if(boardtype.reg_type == ni_reg_611x )
1486 max_count -= num_adc_stages_611x;
1487 if(cmd->stop_arg > max_count){
1488 cmd->stop_arg = max_count;
1493 if(cmd->stop_arg!=0){
1501 /* step 4: fix up any arguments */
1503 if(cmd->scan_begin_src==TRIG_TIMER){
1504 tmp=cmd->scan_begin_arg;
1505 ni_ns_to_timer(&cmd->scan_begin_arg,cmd->flags&TRIG_ROUND_MASK);
1506 if(tmp!=cmd->scan_begin_arg)err++;
1508 if(cmd->convert_src==TRIG_TIMER){
1509 if(boardtype.reg_type == ni_reg_normal){
1510 tmp=cmd->convert_arg;
1511 ni_ns_to_timer(&cmd->convert_arg,cmd->flags&TRIG_ROUND_MASK);
1512 if(tmp!=cmd->convert_arg)err++;
1513 if(cmd->scan_begin_src==TRIG_TIMER &&
1514 cmd->scan_begin_arg<cmd->convert_arg*cmd->scan_end_arg){
1515 cmd->scan_begin_arg=cmd->convert_arg*cmd->scan_end_arg;
1526 static int ni_ai_cmd(comedi_device *dev,comedi_subdevice *s)
1528 comedi_cmd *cmd=&s->async->cmd;
1530 int mode1=0; /* mode1 is needed for both stop and convert */
1532 int start_stop_select=0;
1533 unsigned int stop_count;
1534 int interrupt_a_enable=0;
1536 MDPRINTK("ni_ai_cmd\n");
1539 comedi_error(dev, "cannot run command without an irq");
1542 win_out(1,ADC_FIFO_Clear);
1544 ni_load_channelgain_list(dev,cmd->chanlist_len,cmd->chanlist);
1546 /* start configuration */
1547 win_out(AI_Configuration_Start,Joint_Reset_Register);
1549 /* disable analog triggering for now, since it
1550 * interferes with the use of pfi0 */
1551 devpriv->an_trig_etc_reg &= ~Analog_Trigger_Enable;
1552 win_out(devpriv->an_trig_etc_reg, Analog_Trigger_Etc_Register);
1554 switch(cmd->start_src){
1557 win_out(AI_START2_Select(0)|
1558 AI_START1_Sync|AI_START1_Edge|AI_START1_Select(0),
1559 AI_Trigger_Select_Register);
1563 int chan = CR_CHAN(cmd->start_arg);
1564 unsigned int bits = AI_START2_Select(0)|
1566 AI_START1_Select(chan + 1);
1568 if(cmd->start_arg & CR_INVERT)
1569 bits |= AI_START1_Polarity;
1570 if(cmd->start_arg & CR_EDGE)
1571 bits |= AI_START1_Edge;
1572 win_out(bits, AI_Trigger_Select_Register);
1577 mode2 &= ~AI_Pre_Trigger;
1578 mode2 &= ~AI_SC_Initial_Load_Source;
1579 mode2 &= ~AI_SC_Reload_Mode;
1580 win_out(mode2, AI_Mode_2_Register);
1582 start_stop_select |= AI_STOP_Sync;
1583 if(boardtype.reg_type == ni_reg_611x){
1584 start_stop_select |= AI_STOP_Polarity;
1585 start_stop_select |= AI_STOP_Select( 31 );
1587 start_stop_select |= AI_STOP_Select( 19 );
1589 win_out(start_stop_select, AI_START_STOP_Select_Register);
1591 devpriv->ai_cmd2 = 0;
1592 switch(cmd->stop_src){
1594 stop_count = cmd->stop_arg - 1;
1596 if(boardtype.reg_type == ni_reg_611x){
1597 // have to take 3 stage adc pipeline into account
1598 stop_count += num_adc_stages_611x;
1600 /* stage number of scans */
1601 win_out2( stop_count, AI_SC_Load_A_Registers);
1603 mode1 |= AI_Start_Stop | AI_Mode_1_Reserved | AI_Trigger_Once;
1604 win_out(mode1,AI_Mode_1_Register);
1605 /* load SC (Scan Count) */
1606 win_out(AI_SC_Load,AI_Command_1_Register);
1608 devpriv->ai_continuous = 0;
1609 if( stop_count == 0 ){
1610 devpriv->ai_cmd2 |= AI_End_On_End_Of_Scan;
1611 interrupt_a_enable |= AI_STOP_Interrupt_Enable;
1615 /* stage number of scans */
1616 win_out(0,AI_SC_Load_A_Registers);
1617 win_out(0,AI_SC_Load_A_Registers+1);
1619 mode1 |= AI_Start_Stop | AI_Mode_1_Reserved | AI_Continuous;
1620 win_out(mode1,AI_Mode_1_Register);
1622 /* load SC (Scan Count) */
1623 win_out(AI_SC_Load,AI_Command_1_Register);
1625 devpriv->ai_continuous = 1;
1630 switch(cmd->scan_begin_src){
1633 stop bits for non 611x boards
1634 AI_SI_Special_Trigger_Delay=0
1636 AI_START_STOP_Select_Register:
1637 AI_START_Polarity=0 (?) rising edge
1638 AI_START_Edge=1 edge triggered
1640 AI_START_Select=0 SI_TC
1641 AI_STOP_Polarity=0 rising edge
1642 AI_STOP_Edge=0 level
1644 AI_STOP_Select=19 external pin (configuration mem)
1646 start_stop_select |= AI_START_Edge | AI_START_Sync;
1647 win_out(start_stop_select, AI_START_STOP_Select_Register);
1649 mode2 |= AI_SI_Reload_Mode(0);
1650 /* AI_SI_Initial_Load_Source=A */
1651 mode2 &= ~AI_SI_Initial_Load_Source;
1652 //mode2 |= AI_SC_Reload_Mode;
1653 win_out(mode2, AI_Mode_2_Register);
1656 timer=ni_ns_to_timer(&cmd->scan_begin_arg,TRIG_ROUND_NEAREST);
1657 win_out2(timer,AI_SI_Load_A_Registers);
1658 win_out(AI_SI_Load,AI_Command_1_Register);
1661 if( cmd->scan_begin_arg & CR_EDGE )
1662 start_stop_select |= AI_START_Edge;
1663 /* AI_START_Polarity==1 is falling edge */
1664 if( cmd->scan_begin_arg & CR_INVERT )
1665 start_stop_select |= AI_START_Polarity;
1666 if( cmd->scan_begin_src != cmd->convert_src ||
1667 ( cmd->scan_begin_arg & ~CR_EDGE ) != ( cmd->convert_arg & ~CR_EDGE ) )
1668 start_stop_select |= AI_START_Sync;
1669 start_stop_select |= AI_START_Select(1 + CR_CHAN(cmd->scan_begin_arg));
1670 win_out(start_stop_select, AI_START_STOP_Select_Register);
1674 switch(cmd->convert_src){
1677 if( cmd->convert_arg == 0 || cmd->convert_src == TRIG_NOW )
1680 timer=ni_ns_to_timer(&cmd->convert_arg, TRIG_ROUND_NEAREST);
1681 win_out(1,AI_SI2_Load_A_Register); /* 0,0 does not work. */
1682 win_out(timer,AI_SI2_Load_B_Register);
1684 /* AI_SI2_Reload_Mode = alternate */
1685 /* AI_SI2_Initial_Load_Source = A */
1686 mode2 &= ~AI_SI2_Initial_Load_Source;
1687 mode2 |= AI_SI2_Reload_Mode;
1688 win_out( mode2, AI_Mode_2_Register);
1691 win_out(AI_SI2_Load,AI_Command_1_Register);
1693 mode2 |= AI_SI2_Reload_Mode; // alternate
1694 mode2 |= AI_SI2_Initial_Load_Source; // B
1696 win_out(mode2,AI_Mode_2_Register);
1699 mode1 |= AI_CONVERT_Source_Select(1+cmd->convert_arg);
1700 if( ( cmd->convert_arg & CR_INVERT ) == 0 )
1701 mode1 |= AI_CONVERT_Source_Polarity;
1702 win_out(mode1,AI_Mode_1_Register);
1704 mode2 |= AI_Start_Stop_Gate_Enable | AI_SC_Gate_Enable;
1705 win_out(mode2, AI_Mode_2_Register);
1712 /* interrupt on FIFO, errors, SC_TC */
1713 interrupt_a_enable |= AI_Error_Interrupt_Enable|
1714 AI_SC_TC_Interrupt_Enable;
1717 interrupt_a_enable|=AI_FIFO_Interrupt_Enable;
1720 if(cmd->flags & TRIG_WAKE_EOS){
1721 /* wake on end-of-scan */
1722 devpriv->aimode=AIMODE_SCAN;
1724 devpriv->aimode=AIMODE_HALF_FULL;
1727 switch(devpriv->aimode){
1728 case AIMODE_HALF_FULL:
1729 /*generate FIFO interrupts and DMA requests on half-full */
1731 win_out(AI_FIFO_Mode_HF_to_E, AI_Mode_3_Register);
1733 win_out(AI_FIFO_Mode_HF, AI_Mode_3_Register);
1737 /*generate FIFO interrupts on non-empty */
1738 win_out(AI_FIFO_Mode_NE, AI_Mode_3_Register);
1742 win_out(AI_FIFO_Mode_NE, AI_Mode_3_Register);
1744 win_out(AI_FIFO_Mode_HF, AI_Mode_3_Register);
1746 interrupt_a_enable |= AI_STOP_Interrupt_Enable;
1752 win_out(0x3f80,Interrupt_A_Ack_Register); /* clear interrupts */
1754 ni_set_bits(dev, Interrupt_A_Enable_Register, interrupt_a_enable, 1);
1756 MDPRINTK("Interrupt_A_Enable_Register = 0x%04x\n",devpriv->int_a_enable_reg);
1758 /* interrupt on nothing */
1759 ni_set_bits(dev, Interrupt_A_Enable_Register, ~0, 0);
1761 /* XXX start polling if necessary */
1762 MDPRINTK("interrupting on nothing\n");
1765 /* end configuration */
1766 win_out(AI_Configuration_End,Joint_Reset_Register);
1768 switch(cmd->scan_begin_src){
1770 win_out(AI_SI2_Arm | AI_SI_Arm | AI_DIV_Arm | AI_SC_Arm,
1771 AI_Command_1_Register);
1774 /* XXX AI_SI_Arm? */
1775 win_out(AI_SI2_Arm | AI_SI_Arm | AI_DIV_Arm | AI_SC_Arm,
1776 AI_Command_1_Register);
1781 ni_ai_setup_MITE_dma(dev,cmd);
1782 //mite_dump_regs(devpriv->mite);
1785 switch(cmd->start_src){
1787 /* AI_START1_Pulse */
1788 win_out( AI_START1_Pulse | devpriv->ai_cmd2, AI_Command_2_Register );
1789 s->async->inttrig=NULL;
1792 s->async->inttrig=NULL;
1795 s->async->inttrig=ni_ai_inttrig;
1799 MDPRINTK("exit ni_ai_cmd\n");
1804 static int ni_ai_inttrig(comedi_device *dev,comedi_subdevice *s,
1805 unsigned int trignum)
1807 if(trignum!=0)return -EINVAL;
1809 win_out( AI_START1_Pulse | devpriv->ai_cmd2, AI_Command_2_Register );
1810 s->async->inttrig=NULL;
1815 static int ni_ai_config_analog_trig(comedi_device *dev,comedi_subdevice *s,
1816 comedi_insn *insn, lsampl_t *data);
1818 static int ni_ai_insn_config(comedi_device *dev,comedi_subdevice *s,
1819 comedi_insn *insn, lsampl_t *data)
1821 if(insn->n<1)return -EINVAL;
1824 case INSN_CONFIG_ANALOG_TRIG:
1825 return ni_ai_config_analog_trig(dev,s,insn,data);
1826 case INSN_CONFIG_ALT_SOURCE:
1828 unsigned int calib_source;
1829 unsigned int calib_source_adjust;
1831 calib_source = data[1] & 0xf;
1832 calib_source_adjust = ( data[1] >> 4 ) & 0xff;
1834 if(calib_source >= 8)
1836 devpriv->ai_calib_source = calib_source;
1837 if(boardtype.reg_type == ni_reg_611x){
1838 ni_writeb( calib_source_adjust, Cal_Gain_Select_611x );
1849 static int ni_ai_config_analog_trig(comedi_device *dev,comedi_subdevice *s,
1850 comedi_insn *insn, lsampl_t *data)
1852 unsigned int a,b,modebits;
1856 * data[2] is analog line
1857 * data[3] is set level
1858 * data[4] is reset level */
1859 if(!boardtype.has_analog_trig)return -EINVAL;
1860 if(insn->n!=5)return -EINVAL;
1861 if((data[1]&0xffff0000) != COMEDI_EV_SCAN_BEGIN){
1862 data[1]&=~(COMEDI_EV_SCAN_BEGIN&0xffff);
1865 if(data[2]>=boardtype.n_adchan){
1866 data[2]=boardtype.n_adchan-1;
1869 if(data[3]>255){ /* a */
1873 if(data[4]>255){ /* b */
1884 * high mode 00 00 01 10
1885 * low mode 00 00 10 01
1887 * hysteresis low mode 10 00 00 01
1888 * hysteresis high mode 01 00 00 10
1889 * middle mode 10 01 01 10
1894 modebits=data[1]&0xff;
1896 /* two level mode */
1901 modebits=((data[1]&0xf)<<4)|((data[1]&0xf0)>>4);
1903 devpriv->atrig_low = a;
1904 devpriv->atrig_high = b;
1906 case 0x81: /* low hysteresis mode */
1907 devpriv->atrig_mode = 6;
1909 case 0x42: /* high hysteresis mode */
1910 devpriv->atrig_mode = 3;
1912 case 0x96: /* middle window mode */
1913 devpriv->atrig_mode = 2;
1920 /* one level mode */
1926 case 0x06: /* high window mode */
1927 devpriv->atrig_high = a;
1928 devpriv->atrig_mode = 0;
1930 case 0x09: /* low window mode */
1931 devpriv->atrig_low = a;
1932 devpriv->atrig_mode = 1;
1939 if(err)return -EAGAIN;
1943 /* munge data from unsigned to 2's complement for analog output bipolar modes */
1944 static void ni_ao_munge(comedi_device *dev, comedi_subdevice *s,
1945 void *data, unsigned int num_bytes, unsigned int chan_index )
1947 comedi_async *async = s->async;
1950 unsigned int offset;
1951 unsigned int length = num_bytes / sizeof( sampl_t );
1952 sampl_t *array = data;
1954 offset = 1 << (boardtype.aobits - 1);
1955 for(i = 0; i < length; i++)
1957 range = CR_RANGE( async->cmd.chanlist[ chan_index ] );
1958 if(boardtype.ao_unipolar == 0 || (range & 1) == 0 )
1961 array[i] = cpu_to_le16( array[i] );
1964 chan_index %= async->cmd.chanlist_len;
1968 static int ni_ao_config_chanlist(comedi_device *dev, comedi_subdevice *s,
1969 unsigned int chanspec[], unsigned int n_chans)
1977 for(i=0;i<n_chans;i++){
1978 chan = CR_CHAN(chanspec[i]);
1979 range = CR_RANGE(chanspec[i]);
1981 conf = AO_Channel(chan);
1983 if(boardtype.ao_unipolar){
1986 invert = (1<<(boardtype.aobits-1));
1994 invert = (1<<(boardtype.aobits-1));
1997 /* not all boards can deglitch, but this shouldn't hurt */
1998 if(chanspec[i] & CR_DEGLITCH)
1999 conf |= AO_Deglitch;
2001 /* analog reference */
2002 /* AREF_OTHER connects AO ground to AI ground, i think */
2003 conf |= (CR_AREF(chanspec[i])==AREF_OTHER)? AO_Ground_Ref : 0;
2005 devpriv->ao_conf[chan] = conf;
2007 ni_writew(conf,AO_Configuration);
2012 static int ni_ao_insn_read(comedi_device *dev,comedi_subdevice *s,
2013 comedi_insn *insn,lsampl_t *data)
2015 data[0] = devpriv->ao[CR_CHAN(insn->chanspec)];
2020 static int ni_ao_insn_write(comedi_device *dev,comedi_subdevice *s,
2021 comedi_insn *insn,lsampl_t *data)
2023 unsigned int chan = CR_CHAN(insn->chanspec);
2024 unsigned int invert;
2026 invert = ni_ao_config_chanlist(dev,s,&insn->chanspec,1);
2028 devpriv->ao[chan] = data[0];
2030 ni_writew(data[0] ^ invert,(chan)? DAC1_Direct_Data : DAC0_Direct_Data);
2035 static int ni_ao_insn_write_671x(comedi_device *dev,comedi_subdevice *s,
2036 comedi_insn *insn,lsampl_t *data)
2038 unsigned int chan = CR_CHAN(insn->chanspec);
2039 unsigned int invert;
2041 ao_win_out(1 << chan, AO_Immediate_671x);
2042 invert = 1 << (boardtype.aobits - 1);
2044 ni_ao_config_chanlist(dev,s,&insn->chanspec,1);
2046 devpriv->ao[chan] = data[0];
2047 ao_win_out(data[0] ^ invert, DACx_Direct_Data_671x(chan));
2052 static int ni_ao_inttrig(comedi_device *dev,comedi_subdevice *s,
2053 unsigned int trignum)
2056 int interrupt_b_bits;
2058 static const int timeout = 1000;
2060 if(trignum!=0)return -EINVAL;
2062 ni_set_bits(dev, Interrupt_B_Enable_Register, AO_FIFO_Interrupt_Enable | AO_Error_Interrupt_Enable, 0);
2063 interrupt_b_bits = AO_Error_Interrupt_Enable;
2065 win_out(0, DAC_FIFO_Clear);
2066 if(boardtype.reg_type & ni_reg_6xxx_mask)
2067 ni_ao_win_outl(dev, 0x6, AO_FIFO_Offset_Load_611x);
2068 ni_ao_setup_MITE_dma(dev, &s->async->cmd);
2069 ret = ni_ao_wait_for_dma_load(dev);
2070 if(ret < 0) return ret;
2073 ret = ni_ao_prep_fifo(dev,s);
2074 if(ret==0)return -EPIPE;
2076 interrupt_b_bits |= AO_FIFO_Interrupt_Enable;
2079 win_out(devpriv->ao_mode3|AO_Not_An_UPDATE,AO_Mode_3_Register);
2080 win_out(devpriv->ao_mode3,AO_Mode_3_Register);
2081 /* wait for DACs to be loaded */
2082 for(i = 0; i < timeout; i++)
2085 if((win_in(Joint_Status_2_Register) & AO_TMRDACWRs_In_Progress_St) == 0)
2090 comedi_error(dev, "timed out waiting for AO_TMRDACWRs_In_Progress_St to clear");
2093 // stc manual says we are need to clear error interrupt after AO_TMRDACWRs_In_Progress_St clears
2094 win_out(AO_Error_Interrupt_Ack, Interrupt_B_Ack_Register);
2096 ni_set_bits(dev, Interrupt_B_Enable_Register, interrupt_b_bits, 1);
2098 win_out(devpriv->ao_cmd1|AO_UI_Arm|AO_UC_Arm|AO_BC_Arm|AO_DAC1_Update_Mode|AO_DAC0_Update_Mode,
2099 AO_Command_1_Register);
2101 win_out(devpriv->ao_cmd2|AO_START1_Pulse,AO_Command_2_Register);
2103 s->async->inttrig=NULL;
2108 static int ni_ao_cmd(comedi_device *dev,comedi_subdevice *s)
2110 comedi_cmd *cmd = &s->async->cmd;
2117 comedi_error(dev, "cannot run command without an irq");
2120 trigvar = ni_ns_to_timer(&cmd->scan_begin_arg,TRIG_ROUND_NEAREST);
2122 win_out(AO_Configuration_Start,Joint_Reset_Register);
2124 win_out(AO_Disarm,AO_Command_1_Register);
2126 if(boardtype.reg_type & ni_reg_6xxx_mask)
2128 ao_win_out(CLEAR_WG, AO_Misc_611x);
2131 for(i = 0; i < cmd->chanlist_len; i++)
2135 chan = CR_CHAN(cmd->chanlist[i]);
2137 ao_win_out(chan, AO_Waveform_Generation_611x);
2139 ao_win_out(bits, AO_Timed_611x);
2142 ni_ao_config_chanlist(dev,s,cmd->chanlist,cmd->chanlist_len);
2144 if(cmd->stop_src==TRIG_NONE){
2145 devpriv->ao_mode1|=AO_Continuous;
2146 devpriv->ao_mode1&=~AO_Trigger_Once;
2148 devpriv->ao_mode1&=~AO_Continuous;
2149 devpriv->ao_mode1|=AO_Trigger_Once;
2151 win_out(devpriv->ao_mode1,AO_Mode_1_Register);
2152 devpriv->ao_trigger_select&=~(AO_START1_Polarity|AO_START1_Select(-1));
2153 devpriv->ao_trigger_select|=AO_START1_Edge|AO_START1_Sync;
2154 win_out(devpriv->ao_trigger_select,AO_Trigger_Select_Register);
2155 devpriv->ao_mode3&=~AO_Trigger_Length;
2156 win_out(devpriv->ao_mode3,AO_Mode_3_Register);
2158 win_out(devpriv->ao_mode1,AO_Mode_1_Register);
2159 devpriv->ao_mode2&=~AO_BC_Initial_Load_Source;
2160 win_out(devpriv->ao_mode2,AO_Mode_2_Register);
2161 if(cmd->stop_src==TRIG_NONE){
2162 win_out2(0xffffff,AO_BC_Load_A_Register);
2164 win_out2(0,AO_BC_Load_A_Register);
2166 win_out(AO_BC_Load,AO_Command_1_Register);
2167 devpriv->ao_mode2&=~AO_UC_Initial_Load_Source;
2168 win_out(devpriv->ao_mode2,AO_Mode_2_Register);
2169 switch(cmd->stop_src){
2171 win_out2(cmd->stop_arg,AO_UC_Load_A_Register);
2172 win_out(AO_UC_Load,AO_Command_1_Register);
2173 win_out2(cmd->stop_arg - 1,AO_UC_Load_A_Register);
2176 win_out2(0xffffff,AO_UC_Load_A_Register);
2177 win_out(AO_UC_Load,AO_Command_1_Register);
2178 win_out2(0xffffff,AO_UC_Load_A_Register);
2181 win_out2(0,AO_UC_Load_A_Register);
2182 win_out(AO_UC_Load,AO_Command_1_Register);
2183 win_out2(cmd->stop_arg,AO_UC_Load_A_Register);
2186 devpriv->ao_cmd2&=~AO_BC_Gate_Enable;
2187 win_out(devpriv->ao_cmd2,AO_Command_2_Register);
2188 devpriv->ao_mode1&=~(AO_UI_Source_Select(0x1f)|AO_UI_Source_Polarity);
2189 win_out(devpriv->ao_mode1,AO_Mode_1_Register);
2190 devpriv->ao_mode2&=~(AO_UI_Reload_Mode(3)|AO_UI_Initial_Load_Source);
2191 win_out(devpriv->ao_mode2,AO_Mode_2_Register);
2192 win_out2(1,AO_UI_Load_A_Register);
2193 win_out(AO_UI_Load,AO_Command_1_Register);
2194 win_out2(trigvar,AO_UI_Load_A_Register);
2196 if(boardtype.reg_type == ni_reg_normal){
2197 if(cmd->scan_end_arg>1){
2198 devpriv->ao_mode1|=AO_Multiple_Channels;
2199 win_out(AO_Number_Of_Channels(cmd->scan_end_arg-1)|
2200 AO_UPDATE_Output_Select(1),
2201 AO_Output_Control_Register);
2203 devpriv->ao_mode1&=~AO_Multiple_Channels;
2204 win_out(AO_Number_Of_Channels(CR_CHAN(cmd->chanlist[0]))|
2205 AO_UPDATE_Output_Select(1),
2206 AO_Output_Control_Register);
2208 win_out(devpriv->ao_mode1,AO_Mode_1_Register);
2211 win_out(AO_DAC0_Update_Mode|AO_DAC1_Update_Mode,AO_Command_1_Register);
2213 devpriv->ao_mode3|=AO_Stop_On_Overrun_Error;
2214 win_out(devpriv->ao_mode3,AO_Mode_3_Register);
2216 devpriv->ao_mode2 &= AO_FIFO_Mode_Mask;
2218 devpriv->ao_mode2 |= AO_FIFO_Mode_HF_to_F;
2220 devpriv->ao_mode2 |= AO_FIFO_Mode_HF;
2222 devpriv->ao_mode2 &= ~AO_FIFO_Retransmit_Enable;
2223 win_out(devpriv->ao_mode2,AO_Mode_2_Register);
2225 bits = AO_BC_Source_Select | AO_UPDATE_Pulse_Width |
2226 AO_TMRDACWR_Pulse_Width;
2227 if( boardtype.ao_fifo_depth )
2228 bits |= AO_FIFO_Enable;
2229 win_out(bits, AO_Personal_Register);
2230 // enable sending of ao dma requests
2231 win_out(AO_AOFREQ_Enable, AO_Start_Select_Register);
2233 win_out(AO_Configuration_End,Joint_Reset_Register);
2235 if(cmd->stop_src==TRIG_COUNT) {
2236 win_out(AO_BC_TC_Interrupt_Ack,Interrupt_B_Ack_Register);
2237 ni_set_bits(dev, Interrupt_B_Enable_Register,
2238 AO_BC_TC_Interrupt_Enable, 1);
2241 s->async->inttrig=ni_ao_inttrig;
2246 static int ni_ao_cmdtest(comedi_device *dev,comedi_subdevice *s,comedi_cmd *cmd)
2251 /* step 1: make sure trigger sources are trivially valid */
2254 cmd->start_src &= TRIG_INT;
2255 if(!cmd->start_src || tmp!=cmd->start_src)err++;
2257 tmp=cmd->scan_begin_src;
2258 cmd->scan_begin_src &= TRIG_TIMER;
2259 if(!cmd->scan_begin_src || tmp!=cmd->scan_begin_src)err++;
2261 tmp=cmd->convert_src;
2262 cmd->convert_src &= TRIG_NOW;
2263 if(!cmd->convert_src || tmp!=cmd->convert_src)err++;
2265 tmp=cmd->scan_end_src;
2266 cmd->scan_end_src &= TRIG_COUNT;
2267 if(!cmd->scan_end_src || tmp!=cmd->scan_end_src)err++;
2270 cmd->stop_src &= TRIG_COUNT|TRIG_NONE;
2271 if(!cmd->stop_src || tmp!=cmd->stop_src)err++;
2275 /* step 2: make sure trigger sources are unique and mutually compatible */
2277 if(cmd->stop_src!=TRIG_COUNT &&
2278 cmd->stop_src!=TRIG_NONE)err++;
2282 /* step 3: make sure arguments are trivially compatible */
2284 if(cmd->start_arg!=0){
2289 /* XXX need ao_speed */
2290 if(cmd->scan_begin_arg<boardtype.ao_speed){
2291 cmd->scan_begin_arg=boardtype.ao_speed;
2295 if(cmd->scan_begin_arg>TIMER_BASE*0xffffff){ /* XXX check */
2296 cmd->scan_begin_arg=TIMER_BASE*0xffffff;
2299 if(cmd->convert_arg!=0){
2303 if(cmd->scan_end_arg!=cmd->chanlist_len){
2304 cmd->scan_end_arg=cmd->chanlist_len;
2307 if(cmd->stop_src==TRIG_COUNT){ /* XXX check */
2308 if(cmd->stop_arg>0x00ffffff){
2309 cmd->stop_arg=0x00ffffff;
2314 if(cmd->stop_arg!=0){
2322 /* step 4: fix up any arguments */
2324 tmp = cmd->scan_begin_arg;
2325 ni_ns_to_timer(&cmd->scan_begin_arg,cmd->flags&TRIG_ROUND_MASK);
2326 if(tmp!=cmd->scan_begin_arg)err++;
2330 /* step 5: fix up chanlist */
2338 static int ni_ao_reset(comedi_device *dev,comedi_subdevice *s)
2340 //devpriv->ao0p=0x0000;
2341 //ni_writew(devpriv->ao0p,AO_Configuration);
2343 //devpriv->ao1p=AO_Channel(1);
2344 //ni_writew(devpriv->ao1p,AO_Configuration);
2347 mite_dma_disarm(devpriv->mite, AO_DMA_CHAN);
2348 writel(CHOR_DMARESET | CHOR_FRESET, devpriv->mite->mite_io_addr + MITE_CHOR(AO_DMA_CHAN));
2351 win_out(AO_Configuration_Start,Joint_Reset_Register);
2352 win_out(AO_Disarm,AO_Command_1_Register);
2353 ni_set_bits(dev,Interrupt_B_Enable_Register,~0,0);
2354 win_out(0x0010,AO_Personal_Register);
2355 win_out(0x3f98,Interrupt_B_Ack_Register);
2356 win_out(AO_BC_Source_Select | AO_UPDATE_Pulse_Width |
2357 AO_TMRDACWR_Pulse_Width, AO_Personal_Register);
2358 win_out(0,AO_Output_Control_Register);
2359 win_out(0,AO_Start_Select_Register);
2361 win_out(devpriv->ao_cmd1,AO_Command_1_Register);
2363 devpriv->ao_mode1=0;
2364 devpriv->ao_mode2=0;
2365 devpriv->ao_mode3=0;
2366 devpriv->ao_trigger_select=0;
2367 if(boardtype.reg_type & ni_reg_6xxx_mask){
2368 ao_win_out(0x3, AO_Immediate_671x);
2369 ao_win_out(CLEAR_WG, AO_Misc_611x);
2375 static int ni_dio_insn_config(comedi_device *dev,comedi_subdevice *s,
2376 comedi_insn *insn,lsampl_t *data)
2379 printk("ni_dio_insn_config() chan=%d io=%d\n",
2380 CR_CHAN(insn->chanspec),data[0]);
2382 if(insn->n!=1)return -EINVAL;
2385 s->io_bits |= 1<<CR_CHAN(insn->chanspec);
2388 s->io_bits &= ~(1<<CR_CHAN(insn->chanspec));
2394 devpriv->dio_control &= ~DIO_Pins_Dir_Mask;
2395 devpriv->dio_control |= DIO_Pins_Dir(s->io_bits);
2396 win_out(devpriv->dio_control,DIO_Control_Register);
2401 static int ni_dio_insn_bits(comedi_device *dev,comedi_subdevice *s,
2402 comedi_insn *insn,lsampl_t *data)
2405 printk("ni_dio_insn_bits() mask=0x%x bits=0x%x\n",data[0],data[1]);
2407 if(insn->n!=2)return -EINVAL;
2409 /* Perform check to make sure we're not using the
2410 serial part of the dio */
2411 if((data[0] & (DIO_SDIN | DIO_SDOUT)) && devpriv->serial_interval_ns)
2414 s->state &= ~data[0];
2415 s->state |= (data[0]&data[1]);
2416 devpriv->dio_output &= ~DIO_Parallel_Data_Mask;
2417 devpriv->dio_output |= DIO_Parallel_Data_Out(s->state);
2418 win_out(devpriv->dio_output,DIO_Output_Register);
2420 data[1] = win_in(DIO_Parallel_Input_Register);
2425 static int ni_serial_insn_config(comedi_device *dev,comedi_subdevice *s,
2426 comedi_insn *insn,lsampl_t *data)
2429 unsigned char byte_out, byte_in;
2431 if(insn->n!=2)return -EINVAL;
2434 case INSN_CONFIG_SERIAL_CLOCK:
2437 printk("SPI serial clock Config cd\n", data[1]);
2439 devpriv->serial_hw_mode = 1;
2440 devpriv->dio_control |= DIO_HW_Serial_Enable;
2442 if(data[1] == SERIAL_DISABLED) {
2443 devpriv->serial_hw_mode = 0;
2444 devpriv->dio_control &= ~(DIO_HW_Serial_Enable |
2445 DIO_Software_Serial_Control);
2446 data[1] = SERIAL_DISABLED;
2447 devpriv->serial_interval_ns = data[1];
2449 else if(data[1] <= SERIAL_600NS) {
2450 /* Warning: this clock speed is too fast to reliably
2452 devpriv->dio_control &= ~DIO_HW_Serial_Timebase;
2453 devpriv->clock_and_fout |= Slow_Internal_Timebase;
2454 devpriv->clock_and_fout &= ~DIO_Serial_Out_Divide_By_2;
2455 data[1] = SERIAL_600NS;
2456 devpriv->serial_interval_ns = data[1];
2458 else if(data[1] <= SERIAL_1_2US) {
2459 devpriv->dio_control &= ~DIO_HW_Serial_Timebase;
2460 devpriv->clock_and_fout |= Slow_Internal_Timebase |
2461 DIO_Serial_Out_Divide_By_2;
2462 data[1] = SERIAL_1_2US;
2463 devpriv->serial_interval_ns = data[1];
2465 else if(data[1] <= SERIAL_10US) {
2466 devpriv->dio_control |= DIO_HW_Serial_Timebase;
2467 devpriv->clock_and_fout |= Slow_Internal_Timebase |
2468 DIO_Serial_Out_Divide_By_2;
2469 /* Note: DIO_Serial_Out_Divide_By_2 only affects
2470 600ns/1.2us. If you turn divide_by_2 off with the
2471 slow clock, you will still get 10us, except then
2472 all your delays are wrong. */
2473 data[1] = SERIAL_10US;
2474 devpriv->serial_interval_ns = data[1];
2477 devpriv->dio_control &= ~(DIO_HW_Serial_Enable |
2478 DIO_Software_Serial_Control);
2479 devpriv->serial_hw_mode = 0;
2480 data[1] = (data[1] / 1000) * 1000;
2481 devpriv->serial_interval_ns = data[1];
2484 win_out(devpriv->dio_control,DIO_Control_Register);
2485 win_out(devpriv->clock_and_fout,Clock_and_FOUT_Register);
2490 case INSN_CONFIG_BIDIRECTIONAL_DATA:
2492 if(devpriv->serial_interval_ns == 0) {
2496 byte_out = data[1] & 0xFF;
2498 if(devpriv->serial_hw_mode) {
2499 err = ni_serial_hw_readwrite8(dev,s,byte_out,&byte_in);
2500 } else if(devpriv->serial_interval_ns > 0) {
2501 err = ni_serial_sw_readwrite8(dev,s,byte_out,&byte_in);
2503 printk("ni_serial_insn_config: serial disabled!\n");
2506 if(err < 0) return err;
2507 data[1] = byte_in & 0xFF;
2517 static int ni_serial_hw_readwrite8(comedi_device *dev,comedi_subdevice *s,
2518 unsigned char data_out,
2519 unsigned char *data_in)
2521 unsigned int status1;
2522 int err = 0, count = 20;
2525 printk("ni_serial_hw_readwrite8: outputting 0x%x\n", data_out);
2528 devpriv->dio_output &= ~DIO_Serial_Data_Mask;
2529 devpriv->dio_output |= DIO_Serial_Data_Out(data_out);
2530 win_out(devpriv->dio_output,DIO_Output_Register);
2532 status1 = win_in(Joint_Status_1_Register);
2533 if(status1 & DIO_Serial_IO_In_Progress_St) {
2538 devpriv->dio_control |= DIO_HW_Serial_Start;
2539 win_out(devpriv->dio_control,DIO_Control_Register);
2540 devpriv->dio_control &= ~DIO_HW_Serial_Start;
2542 /* Wait until STC says we're done, but don't loop infinitely. */
2543 while((status1 = win_in(Joint_Status_1_Register)) & DIO_Serial_IO_In_Progress_St) {
2544 /* Delay one bit per loop */
2545 comedi_udelay((devpriv->serial_interval_ns + 999) / 1000);
2547 printk("ni_serial_hw_readwrite8: SPI serial I/O didn't finish in time!\n");
2553 /* Delay for last bit. This delay is absolutely necessary, because
2554 DIO_Serial_IO_In_Progress_St goes high one bit too early. */
2555 comedi_udelay((devpriv->serial_interval_ns + 999) / 1000);
2557 if(data_in != NULL) {
2558 *data_in = win_in(DIO_Serial_Input_Register);
2560 printk("ni_serial_hw_readwrite8: inputted 0x%x\n", *data_in);
2565 win_out(devpriv->dio_control,DIO_Control_Register);
2570 static int ni_serial_sw_readwrite8(comedi_device *dev,comedi_subdevice *s,
2571 unsigned char data_out,
2572 unsigned char *data_in)
2574 unsigned char mask, input = 0;
2577 printk("ni_serial_sw_readwrite8: outputting 0x%x\n", data_out);
2580 /* Wait for one bit before transfer */
2581 comedi_udelay((devpriv->serial_interval_ns + 999) / 1000);
2583 for(mask = 0x80; mask; mask >>= 1) {
2584 /* Output current bit; note that we cannot touch s->state
2585 because it is a per-subdevice field, and serial is
2586 a separate subdevice from DIO. */
2587 devpriv->dio_output &= ~DIO_SDOUT;
2588 if(data_out & mask) {
2589 devpriv->dio_output |= DIO_SDOUT;
2591 win_out(devpriv->dio_output,DIO_Output_Register);
2593 /* Assert SDCLK (active low, inverted), wait for half of
2594 the delay, deassert SDCLK, and wait for the other half. */
2595 devpriv->dio_control |= DIO_Software_Serial_Control;
2596 win_out(devpriv->dio_control,DIO_Control_Register);
2598 comedi_udelay((devpriv->serial_interval_ns + 999) / 2000);
2600 devpriv->dio_control &= ~DIO_Software_Serial_Control;
2601 win_out(devpriv->dio_control,DIO_Control_Register);
2603 comedi_udelay((devpriv->serial_interval_ns + 999) / 2000);
2605 /* Input current bit */
2606 if(win_in(DIO_Parallel_Input_Register) & DIO_SDIN) {
2607 /* printk("DIO_P_I_R: 0x%x\n", win_in(DIO_Parallel_Input_Register)); */
2612 printk("ni_serial_sw_readwrite8: inputted 0x%x\n", input);
2614 if(data_in) *data_in = input;
2619 static void mio_common_detach(comedi_device *dev)
2621 if(dev->subdevices && boardtype.has_8255)
2622 subdev_8255_cleanup(dev,dev->subdevices+3);
2625 static void init_ao_67xx(comedi_device *dev, comedi_subdevice *s)
2629 for(i = 0; i < s->n_chan; i++)
2630 ni_ao_win_outw(dev, AO_Channel(i) | 0x0, AO_Configuration_2_67xx);
2633 static int ni_alloc_private(comedi_device *dev)
2637 ret = alloc_private(dev, sizeof(ni_private));
2638 if(ret < 0) return ret;
2640 spin_lock_init(&devpriv->window_lock);
2645 static int ni_E_init(comedi_device *dev,comedi_devconfig *it)
2647 comedi_subdevice *s;
2650 if(alloc_subdevices(dev, 10) < 0)
2653 /* analog input subdevice */
2655 s=dev->subdevices+0;
2657 if(boardtype.n_adchan){
2658 s->type=COMEDI_SUBD_AI;
2659 s->subdev_flags=SDF_READABLE|SDF_DIFF;
2660 if(boardtype.reg_type == ni_reg_normal)
2661 s->subdev_flags |= SDF_GROUND | SDF_COMMON | SDF_OTHER;
2662 s->subdev_flags|=SDF_DITHER;
2663 s->n_chan=boardtype.n_adchan;
2664 s->len_chanlist=512;
2665 s->maxdata=(1<<boardtype.adbits)-1;
2666 s->range_table=ni_range_lkup[boardtype.gainlkup];
2667 s->insn_read=ni_ai_insn_read;
2668 s->insn_config=ni_ai_insn_config;
2669 s->do_cmdtest=ni_ai_cmdtest;
2670 s->do_cmd=ni_ai_cmd;
2671 s->cancel=ni_ai_reset;
2673 s->munge=ni_ai_munge;
2675 s->type=COMEDI_SUBD_UNUSED;
2678 /* analog output subdevice */
2680 s=dev->subdevices+1;
2681 if(boardtype.n_aochan){
2682 dev->write_subdev=s;
2683 s->type=COMEDI_SUBD_AO;
2684 s->subdev_flags=SDF_WRITABLE|SDF_DEGLITCH|SDF_GROUND;
2685 s->n_chan=boardtype.n_aochan;
2686 s->maxdata=(1<<boardtype.aobits)-1;
2687 if(boardtype.ao_unipolar){
2688 s->range_table=&range_ni_E_ao_ext; /* XXX wrong for some boards */
2690 s->range_table=&range_bipolar10;
2692 s->insn_read=ni_ao_insn_read;
2693 if(boardtype.reg_type & ni_reg_6xxx_mask){
2694 s->insn_write=ni_ao_insn_write_671x;
2696 s->insn_write=ni_ao_insn_write;
2698 if(boardtype.ao_fifo_depth){
2699 s->do_cmd=ni_ao_cmd;
2700 s->do_cmdtest=ni_ao_cmdtest;
2701 s->len_chanlist = boardtype.n_aochan;
2702 s->munge=ni_ao_munge;
2704 s->cancel=ni_ao_reset;
2706 s->type=COMEDI_SUBD_UNUSED;
2708 if((boardtype.reg_type & ni_reg_67xx_mask))
2709 init_ao_67xx(dev, s);
2711 /* digital i/o subdevice */
2713 s=dev->subdevices+2;
2714 s->type=COMEDI_SUBD_DIO;
2715 s->subdev_flags=SDF_WRITABLE|SDF_READABLE;
2718 s->range_table=&range_digital;
2719 s->io_bits=0; /* all bits input */
2720 s->insn_bits=ni_dio_insn_bits;
2721 s->insn_config=ni_dio_insn_config;
2724 devpriv->dio_control = DIO_Pins_Dir(s->io_bits);
2725 win_out(devpriv->dio_control,DIO_Control_Register);
2728 s=dev->subdevices+3;
2729 if(boardtype.has_8255){
2730 subdev_8255_init(dev,s,ni_8255_callback,(unsigned long)dev);
2732 s->type=COMEDI_SUBD_UNUSED;
2735 /* general purpose counter/timer device */
2736 s=dev->subdevices+4;
2737 s->type=COMEDI_SUBD_COUNTER;
2738 s->subdev_flags=SDF_READABLE|SDF_WRITABLE;
2739 s->insn_read= ni_gpct_insn_read;
2740 s->insn_write= ni_gpct_insn_write;
2741 s->insn_config=ni_gpct_insn_config;
2744 devpriv->an_trig_etc_reg = 0;
2748 /* calibration subdevice -- ai and ao */
2749 s=dev->subdevices+5;
2750 s->type=COMEDI_SUBD_CALIB;
2751 s->subdev_flags=SDF_WRITABLE|SDF_INTERNAL;
2752 s->insn_read=ni_calib_insn_read;
2753 s->insn_write=ni_calib_insn_write;
2754 caldac_setup(dev,s);
2757 s=dev->subdevices+6;
2758 s->type=COMEDI_SUBD_MEMORY;
2759 s->subdev_flags=SDF_READABLE|SDF_INTERNAL;
2762 s->insn_read=ni_eeprom_insn_read;
2765 s=dev->subdevices+7;
2766 s->type=COMEDI_SUBD_DIO;
2767 s->subdev_flags=SDF_READABLE|SDF_WRITABLE|SDF_INTERNAL;
2770 s->insn_bits = ni_pfi_insn_bits;
2771 s->insn_config = ni_pfi_insn_config;
2772 ni_set_bits(dev, IO_Bidirection_Pin_Register, ~0, 0);
2774 /* cs5529 calibration adc */
2775 s = dev->subdevices + 8;
2776 if(boardtype.reg_type & ni_reg_67xx_mask)
2778 s->type = COMEDI_SUBD_AI;
2779 s->subdev_flags = SDF_READABLE | SDF_DIFF | SDF_INTERNAL;
2780 // one channel for each analog output channel
2781 s->n_chan = boardtype.n_aochan;
2782 s->maxdata = (1 << 16) - 1;
2783 s->range_table = &range_unknown; /* XXX */
2784 s->insn_read=cs5529_ai_insn_read;
2785 s->insn_config=NULL;
2789 s->type=COMEDI_SUBD_UNUSED;
2793 s=dev->subdevices+9;
2794 s->type=COMEDI_SUBD_SERIAL;
2795 s->subdev_flags=SDF_READABLE|SDF_WRITABLE|SDF_INTERNAL;
2798 s->insn_config = ni_serial_insn_config;
2799 devpriv->serial_interval_ns = 0;
2800 devpriv->serial_hw_mode = 0;
2802 /* ai configuration */
2803 ni_ai_reset(dev,dev->subdevices+0);
2804 if(boardtype.reg_type == ni_reg_normal){
2805 devpriv->clock_and_fout =
2806 Slow_Internal_Time_Divide_By_2 |
2807 Slow_Internal_Timebase |
2808 Clock_To_Board_Divide_By_2 |
2810 AI_Output_Divide_By_2 |
2811 AO_Output_Divide_By_2;
2813 devpriv->clock_and_fout =
2814 Slow_Internal_Time_Divide_By_2 |
2815 Slow_Internal_Timebase |
2816 Clock_To_Board_Divide_By_2 |
2819 win_out(devpriv->clock_and_fout, Clock_and_FOUT_Register);
2821 /* analog output configuration */
2822 ni_ao_reset(dev,dev->subdevices + 1);
2825 win_out((IRQ_POLARITY?Interrupt_Output_Polarity:0) |
2826 (Interrupt_Output_On_3_Pins&0) |
2827 Interrupt_A_Enable |
2828 Interrupt_B_Enable |
2829 Interrupt_A_Output_Select(interrupt_pin(dev->irq)) |
2830 Interrupt_B_Output_Select(interrupt_pin(dev->irq)),
2831 Interrupt_Control_Register
2836 /* tell the STC which dma channels to use for AI and AO */
2837 bits = 1 << ( AI_DMA_CHAN );
2838 bits |= 1 << ( AO_DMA_CHAN + 4 );
2839 ni_writeb( bits, AI_AO_Select);
2840 /* tell the STC which dma channels to use for
2841 * General purpose counters 0 and 1 */
2842 bits = 1 << ( GPC0_DMA_CHAN );
2843 bits |= 1 << ( GPC1_DMA_CHAN + 4 );
2844 ni_writeb( bits, G0_G1_Select);
2847 if(boardtype.reg_type != ni_reg_normal)
2849 ni_writeb( 0, Magic_611x );
2859 static int ni_8255_callback(int dir,int port,int data,unsigned long arg)
2861 comedi_device *dev=(comedi_device *)arg;
2864 ni_writeb(data,Port_A+2*port);
2867 return ni_readb(Port_A+2*port);
2872 presents the EEPROM as a subdevice
2875 static int ni_eeprom_insn_read(comedi_device *dev,comedi_subdevice *s,
2876 comedi_insn *insn,lsampl_t *data)
2878 data[0]=ni_read_eeprom(dev,CR_CHAN(insn->chanspec));
2884 reads bytes out of eeprom
2887 static int ni_read_eeprom(comedi_device *dev,int addr)
2892 bitstring=0x0300|((addr&0x100)<<3)|(addr&0xff);
2893 ni_writeb(0x04,Serial_Command);
2894 for(bit=0x8000;bit;bit>>=1){
2895 ni_writeb(0x04|((bit&bitstring)?0x02:0),Serial_Command);
2896 ni_writeb(0x05|((bit&bitstring)?0x02:0),Serial_Command);
2899 for(bit=0x80;bit;bit>>=1){
2900 ni_writeb(0x04,Serial_Command);
2901 ni_writeb(0x05,Serial_Command);
2902 bitstring|=((ni_readb(XXX_Status)&PROMOUT)?bit:0);
2904 ni_writeb(0x00,Serial_Command);
2909 static void ni_write_caldac(comedi_device *dev,int addr,int val);
2911 calibration subdevice
2913 static int ni_calib_insn_write(comedi_device *dev,comedi_subdevice *s,
2914 comedi_insn *insn,lsampl_t *data)
2916 ni_write_caldac(dev,CR_CHAN(insn->chanspec),data[0]);
2921 static int ni_calib_insn_read(comedi_device *dev,comedi_subdevice *s,
2922 comedi_insn *insn,lsampl_t *data)
2924 data[0] = devpriv->caldacs[CR_CHAN(insn->chanspec)];
2929 static int pack_mb88341(int addr,int val,int *bitstring);
2930 static int pack_dac8800(int addr,int val,int *bitstring);
2931 static int pack_dac8043(int addr,int val,int *bitstring);
2932 static int pack_ad8522(int addr,int val,int *bitstring);
2933 static int pack_ad8804(int addr,int val,int *bitstring);
2934 static int pack_ad8842(int addr,int val,int *bitstring);
2936 struct caldac_struct{
2939 int (*packbits)(int,int,int *);
2942 static struct caldac_struct caldacs[] = {
2943 [mb88341] = { 12, 8, pack_mb88341 },
2944 [dac8800] = { 8, 8, pack_dac8800 },
2945 [dac8043] = { 1, 12, pack_dac8043 },
2946 [ad8522] = { 2, 12, pack_ad8522 },
2947 [ad8804] = { 12, 8, pack_ad8804 },
2948 [ad8842] = { 8, 8, pack_ad8842 },
2949 [ad8804_debug] = { 16, 8, pack_ad8804 },
2952 static void caldac_setup(comedi_device *dev,comedi_subdevice *s)
2962 type = boardtype.caldac[0];
2963 if(type==caldac_none)return;
2964 n_bits=caldacs[type].n_bits;
2966 type = boardtype.caldac[i];
2967 if(type==caldac_none)break;
2968 if(caldacs[type].n_bits!=n_bits)diffbits=1;
2969 n_chans+=caldacs[type].n_chans;
2976 if(n_chans>MAX_N_CALDACS){
2977 printk("BUG! MAX_N_CALDACS too small\n");
2979 s->maxdata_list=devpriv->caldac_maxdata_list;
2981 for(i=0;i<n_dacs;i++){
2982 type = boardtype.caldac[i];
2983 for(j=0;j<caldacs[type].n_chans;j++){
2984 s->maxdata_list[chan]=
2985 (1<<caldacs[type].n_bits)-1;
2990 for( chan = 0; chan < s->n_chan; chan++ )
2991 ni_write_caldac( dev, i, s->maxdata_list[ i ] / 2 );
2993 type = boardtype.caldac[0];
2994 s->maxdata=(1<<caldacs[type].n_bits)-1;
2996 for( chan = 0; chan < s->n_chan; chan++ )
2997 ni_write_caldac( dev, i, s->maxdata / 2 );
3001 static void ni_write_caldac(comedi_device *dev,int addr,int val)
3003 unsigned int loadbit=0,bits=0,bit,bitstring=0;
3007 //printk("ni_write_caldac: chan=%d val=%d\n",addr,val);
3008 if( devpriv->caldacs[ addr ] == val ) return;
3009 devpriv->caldacs[ addr ] = val;
3012 type = boardtype.caldac[i];
3013 if(type==caldac_none)break;
3014 if(addr<caldacs[type].n_chans){
3015 bits=caldacs[type].packbits(addr,val,&bitstring);
3016 loadbit=SerDacLd(i);
3017 //printk("caldac: using i=%d addr=%d %x\n",i,addr,bitstring);
3020 addr-=caldacs[type].n_chans;
3023 for(bit=1<<(bits-1);bit;bit>>=1){
3024 ni_writeb(((bit&bitstring)?0x02:0),Serial_Command);
3026 ni_writeb(1|((bit&bitstring)?0x02:0),Serial_Command);
3029 ni_writeb(loadbit,Serial_Command);
3031 ni_writeb(0,Serial_Command);
3036 static int pack_mb88341(int addr,int val,int *bitstring)
3040 Note that address bits are reversed. Thanks to
3041 Ingo Keen for noticing this.
3043 Note also that the 88341 expects address values from
3044 1-12, whereas we use channel numbers 0-11. The NI
3045 docs use 1-12, also, so be careful here.
3048 *bitstring=((addr&0x1)<<11) |
3056 static int pack_dac8800(int addr,int val,int *bitstring)
3058 *bitstring=((addr&0x7)<<8)|(val&0xff);
3062 static int pack_dac8043(int addr,int val,int *bitstring)
3064 *bitstring=val&0xfff;
3068 static int pack_ad8522(int addr,int val,int *bitstring)
3070 *bitstring=(val&0xfff)|(addr ? 0xc000:0xa000);
3074 static int pack_ad8804(int addr,int val,int *bitstring)
3076 *bitstring=((addr&0xf)<<8) | (val&0xff);
3080 static int pack_ad8842(int addr,int val,int *bitstring)
3082 *bitstring=((addr+1)<<8) | (val&0xff);
3092 * General Purpose Counter/Timer section
3097 * Low level stuff...Each STC counter has two 24 bit load registers
3098 * (A&B). Just make it easier to access them.
3100 * These are inlined _only_ because they are used once in subsequent
3101 * code. Otherwise they should not be inlined.
3103 static inline void GPCT_Load_A(comedi_device *dev, int chan, unsigned int value)
3105 win_out2( value & 0x00ffffff, G_Load_A_Register(chan));
3108 static inline void GPCT_Load_B(comedi_device *dev, int chan, unsigned int value)
3110 win_out2( value & 0x00ffffff, G_Load_B_Register(chan));
3113 /* Load a value into the counter, using register A as the intermediate step.
3114 * You might use GPCT_Load_Using_A to load a 0x000000 into a counter
3117 static void GPCT_Load_Using_A(comedi_device *dev, int chan, unsigned int value)
3119 devpriv->gpct_mode[chan] &= (~G_Load_Source_Select);
3120 win_out( devpriv->gpct_mode[chan],G_Mode_Register(chan));
3121 GPCT_Load_A(dev,chan,value);
3122 win_out( devpriv->gpct_command[chan]|G_Load,G_Command_Register(chan));
3126 * Read the GPCTs current value.
3128 static int GPCT_G_Watch(comedi_device *dev, int chan)
3130 unsigned int hi1,hi2,lo;
3132 devpriv->gpct_command[chan] &= ~G_Save_Trace;
3133 win_out( devpriv->gpct_command[chan],G_Command_Register(chan));
3135 devpriv->gpct_command[chan] |= G_Save_Trace;
3136 win_out( devpriv->gpct_command[chan], G_Command_Register(chan));
3138 /* This procedure is used because the two registers cannot
3139 * be read atomically. */
3141 hi1 = win_in( G_Save_Register_High(chan));
3142 lo = win_in(G_Save_Register_Low(chan));
3143 hi2 = win_in( G_Save_Register_High(chan));
3146 return (hi1<<16)|lo;
3150 static int GPCT_Disarm(comedi_device *dev, int chan)
3152 win_out( devpriv->gpct_command[chan] | G_Disarm,G_Command_Register(chan));
3157 static int GPCT_Arm(comedi_device *dev, int chan)
3159 win_out( devpriv->gpct_command[chan] | G_Arm,G_Command_Register(chan));
3160 /* If the counter is doing pulse width measurement, then make
3161 sure that the counter did not start counting right away. This would
3162 indicate that we started acquiring the pulse after it had already
3163 started and our measurement would be inaccurate */
3164 if(devpriv->gpct_cur_operation[chan] == GPCT_SINGLE_PW){
3167 g_status=win_in(G_Status_Register);
3170 //TIM 5/2/01 possible error with very short pulses
3171 if((G0_Counting_St & g_status)|| !(G0_Armed_St&g_status)) {
3172 //error: we missed the beginning of the pulse
3173 return -EINVAL; //there is probably a more accurate error code...
3176 if((G1_Counting_St & g_status)|| !(G1_Armed_St&g_status)) {
3177 //error: we missed the beginning of the pulse
3185 static int GPCT_Set_Source(comedi_device *dev,int chan ,int source)
3187 //printk("GPCT_Set_Source...");
3188 devpriv->gpct_input_select[chan] &= ~G_Source_Select(0x1f);//reset gate to 0
3190 case GPCT_INT_CLOCK:
3191 devpriv->gpct_input_select[chan] |= G_Source_Select(0);//INT_TIMEBASE
3195 devpriv->gpct_input_select[chan] |= G_Source_Select(9);//PFI8
3197 devpriv->gpct_input_select[chan] |= G_Source_Select(4);//PFI3
3202 win_out(devpriv->gpct_input_select[chan], G_Input_Select_Register(chan));
3203 //printk("exit GPCT_Set_Source\n");
3207 static int GPCT_Set_Gate(comedi_device *dev,int chan ,int gate)
3209 //printk("GPCT_Set_Gate...");
3210 devpriv->gpct_input_select[chan] &= ~G_Gate_Select(0x1f);//reset gate to 0
3213 devpriv->gpct_input_select[chan] |= G_Gate_Select(31);//Low
3214 devpriv->gpct_mode[chan] |= G_Gate_Polarity;
3217 devpriv->gpct_mode[chan] &= ~G_Gate_Polarity;
3219 devpriv->gpct_input_select[chan] |= G_Gate_Select(10);//PFI9
3221 devpriv->gpct_input_select[chan] |= G_Gate_Select(5);//PFI4
3227 win_out(devpriv->gpct_input_select[chan], G_Input_Select_Register(chan));
3228 win_out(devpriv->gpct_mode[chan], G_Mode_Register(chan));
3229 //printk("exit GPCT_Set_Gate\n");
3233 static int GPCT_Set_Direction(comedi_device *dev,int chan,int direction)
3235 //printk("GPCT_Set_Direction...");
3237 devpriv->gpct_command[chan] &= ~G_Up_Down(0x3);
3238 switch (direction) {
3240 devpriv->gpct_command[chan] |= G_Up_Down(1);
3243 devpriv->gpct_command[chan] |= G_Up_Down(0);
3246 devpriv->gpct_command[chan] |= G_Up_Down(2);
3249 printk("Error direction=0x%08x..",direction);
3252 win_out(devpriv->gpct_command[chan], G_Command_Register(chan));
3253 //TIM 4/23/01 win_out(devpriv->gpct_mode[chan], G_Mode_Register(chan));
3254 //printk("exit GPCT_Set_Direction\n");
3258 static void GPCT_Event_Counting(comedi_device *dev,int chan)
3261 //NOTE: possible residual bits from multibit masks can corrupt
3262 //If you config for several measurements between Resets, watch out!
3264 //printk("GPCT_Event_Counting...");
3266 devpriv->gpct_cur_operation[chan] = GPCT_SIMPLE_EVENT;
3269 devpriv->gpct_mode[chan] &= ~(G_Gating_Mode(0x3));
3270 devpriv->gpct_mode[chan] |= G_Gating_Mode(1);
3272 // Trigger_Mode_For_Edge_Gate = 1
3273 devpriv->gpct_mode[chan] &= ~(G_Trigger_Mode_For_Edge_Gate(0x3));
3274 devpriv->gpct_mode[chan] |= G_Trigger_Mode_For_Edge_Gate(2);
3276 win_out( devpriv->gpct_mode[chan],G_Mode_Register(chan));
3277 //printk("exit GPCT_Event_Counting\n");
3280 static void GPCT_Period_Meas(comedi_device *dev, int chan)
3282 //printk("GPCT_Period_Meas...");
3284 devpriv->gpct_cur_operation[chan] = GPCT_SINGLE_PERIOD;
3287 //NOTE: possible residual bits from multibit masks can corrupt
3288 //If you config for several measurements between Resets, watch out!
3289 devpriv->gpct_mode[chan] &= ~G_OR_Gate;
3290 devpriv->gpct_mode[chan] &= ~G_Gate_Select_Load_Source;
3293 devpriv->gpct_mode[chan] &= ~(G_Output_Mode(0x3));
3294 devpriv->gpct_mode[chan] |= G_Output_Mode(3);
3298 devpriv->gpct_mode[chan] &= ~(G_Gating_Mode(0x3));
3299 devpriv->gpct_mode[chan] |= G_Gating_Mode(2);
3301 // Trigger_Mode_For_Edge_Gate=0
3302 devpriv->gpct_mode[chan] &= ~(G_Trigger_Mode_For_Edge_Gate(0x3));
3303 devpriv->gpct_mode[chan] |= G_Trigger_Mode_For_Edge_Gate(0);
3305 devpriv->gpct_mode[chan] |= G_Reload_Source_Switching;
3306 devpriv->gpct_mode[chan] &= ~G_Loading_On_Gate;
3307 devpriv->gpct_mode[chan] &= ~G_Loading_On_TC;
3308 devpriv->gpct_mode[chan] &= ~G_Gate_On_Both_Edges;
3311 devpriv->gpct_mode[chan] &= ~(G_Stop_Mode(0x3));
3312 devpriv->gpct_mode[chan] |= G_Stop_Mode(0);
3314 // Counting_Once = 2
3315 devpriv->gpct_mode[chan] &= ~(G_Counting_Once(0x3));
3316 devpriv->gpct_mode[chan] |= G_Counting_Once(2);
3319 devpriv->gpct_command[chan] &= ~(G_Up_Down(0x3));
3320 devpriv->gpct_command[chan] |= G_Up_Down(1);
3322 win_out( devpriv->gpct_mode[chan],G_Mode_Register(chan));
3323 win_out( devpriv->gpct_command[chan],G_Command_Register(chan));
3324 //printk("exit GPCT_Period_Meas\n");
3327 static void GPCT_Pulse_Width_Meas(comedi_device *dev, int chan)
3329 //printk("GPCT_Pulse_Width_Meas...");
3331 devpriv->gpct_cur_operation[chan] = GPCT_SINGLE_PW;
3333 devpriv->gpct_mode[chan] &= ~G_OR_Gate;
3334 devpriv->gpct_mode[chan] &= ~G_Gate_Select_Load_Source;
3337 devpriv->gpct_mode[chan] &= ~(G_Output_Mode(0x3));
3338 devpriv->gpct_mode[chan] |= G_Output_Mode(3);
3341 devpriv->gpct_mode[chan] &= ~(G_Gating_Mode(0x3));
3342 devpriv->gpct_mode[chan] |= G_Gating_Mode(1);//TIM 4/24/01 was 2
3344 // Trigger_Mode_For_Edge_Gate=2
3345 devpriv->gpct_mode[chan] &= ~(G_Trigger_Mode_For_Edge_Gate(0x3));
3346 devpriv->gpct_mode[chan] |= G_Trigger_Mode_For_Edge_Gate(2);//TIM 4/24/01 was 0
3349 devpriv->gpct_mode[chan] |= G_Reload_Source_Switching;//TIM 4/24/01 was 1
3350 devpriv->gpct_mode[chan] &= ~G_Loading_On_Gate;//TIM 4/24/01 was 0
3352 devpriv->gpct_mode[chan] &= ~G_Loading_On_TC;
3353 devpriv->gpct_mode[chan] &= ~G_Gate_On_Both_Edges;
3356 devpriv->gpct_mode[chan] &= ~(G_Stop_Mode(0x3));
3357 devpriv->gpct_mode[chan] |= G_Stop_Mode(0);
3359 // Counting_Once = 2
3360 devpriv->gpct_mode[chan] &= ~(G_Counting_Once(0x3));
3361 devpriv->gpct_mode[chan] |= G_Counting_Once(2);
3364 devpriv->gpct_command[chan] &= ~(G_Up_Down(0x3));
3365 devpriv->gpct_command[chan] |= G_Up_Down(1);
3367 win_out( devpriv->gpct_mode[chan],G_Mode_Register(chan));
3368 win_out( devpriv->gpct_command[chan],G_Command_Register(chan));
3370 //printk("exit GPCT_Pulse_Width_Meas\n");
3373 /* GPCT_Gen_Single_Pulse() creates pulse of length pulsewidth which starts after the Arm
3374 signal is sent. The pulse is delayed by the value already in the counter. This function could
3375 be modified to send a pulse in response to a trigger event at its gate.*/
3376 static void GPCT_Gen_Single_Pulse(comedi_device *dev, int chan, unsigned int length)
3378 //printk("GPCT_Gen_Cont...");
3380 devpriv->gpct_cur_operation[chan] = GPCT_SINGLE_PULSE_OUT;
3382 // Set length of the pulse
3383 GPCT_Load_B(dev,chan, length-1);
3385 //Load next time using B, This is reset by GPCT_Load_Using_A()
3386 devpriv->gpct_mode[chan] |= G_Load_Source_Select;
3388 devpriv->gpct_mode[chan] &= ~G_OR_Gate;
3389 devpriv->gpct_mode[chan] &= ~G_Gate_Select_Load_Source;
3392 devpriv->gpct_mode[chan] &= ~(G_Output_Mode(0x3));
3393 devpriv->gpct_mode[chan] |= G_Output_Mode(2); //TIM 4/26/01 was 3
3395 //Gating Mode=0 for untriggered single pulse
3396 devpriv->gpct_mode[chan] &= ~(G_Gating_Mode(0x3));
3397 devpriv->gpct_mode[chan] |= G_Gating_Mode(0); //TIM 4/25/01 was 1
3399 // Trigger_Mode_For_Edge_Gate=0
3400 devpriv->gpct_mode[chan] &= ~(G_Trigger_Mode_For_Edge_Gate(0x3));
3401 devpriv->gpct_mode[chan] |= G_Trigger_Mode_For_Edge_Gate(2);
3404 devpriv->gpct_mode[chan] |= G_Reload_Source_Switching;
3405 devpriv->gpct_mode[chan] &= ~G_Loading_On_Gate;
3406 devpriv->gpct_mode[chan] |= G_Loading_On_TC; //TIM 4/25/01
3407 devpriv->gpct_mode[chan] &= ~G_Gate_On_Both_Edges;
3410 devpriv->gpct_mode[chan] &= ~(G_Stop_Mode(0x3));
3411 devpriv->gpct_mode[chan] |= G_Stop_Mode(2); //TIM 4/25/01
3413 // Counting_Once = 2
3414 devpriv->gpct_mode[chan] &= ~(G_Counting_Once(0x3));
3415 devpriv->gpct_mode[chan] |= G_Counting_Once(1); //TIM 4/25/01
3418 devpriv->gpct_command[chan] &= ~(G_Up_Down(0x3));
3419 devpriv->gpct_command[chan] |= G_Up_Down(0); //TIM 4/25/01 was 1
3421 win_out( devpriv->gpct_mode[chan],G_Mode_Register(chan));
3422 win_out( devpriv->gpct_command[chan],G_Command_Register(chan));
3424 //printk("exit GPCT_Gen_Cont\n");
3427 static void GPCT_Gen_Cont_Pulse(comedi_device *dev, int chan, unsigned int length)
3429 //printk("GPCT_Gen_Cont...");
3431 devpriv->gpct_cur_operation[chan] = GPCT_CONT_PULSE_OUT;
3433 // Set length of the pulse
3434 GPCT_Load_B(dev,chan, length-1);
3436 //Load next time using B, This is reset by GPCT_Load_Using_A()
3437 devpriv->gpct_mode[chan] |= G_Load_Source_Select;
3439 devpriv->gpct_mode[chan] &= ~G_OR_Gate;
3440 devpriv->gpct_mode[chan] &= ~G_Gate_Select_Load_Source;
3443 devpriv->gpct_mode[chan] &= ~(G_Output_Mode(0x3));
3444 devpriv->gpct_mode[chan] |= G_Output_Mode(2); //TIM 4/26/01 was 3
3446 //Gating Mode=0 for untriggered single pulse
3447 devpriv->gpct_mode[chan] &= ~(G_Gating_Mode(0x3));
3448 devpriv->gpct_mode[chan] |= G_Gating_Mode(0); //TIM 4/26/01 was 0
3450 // Trigger_Mode_For_Edge_Gate=0
3451 devpriv->gpct_mode[chan] &= ~(G_Trigger_Mode_For_Edge_Gate(0x3));
3452 devpriv->gpct_mode[chan] |= G_Trigger_Mode_For_Edge_Gate(2);
3455 devpriv->gpct_mode[chan] |= G_Reload_Source_Switching;
3456 devpriv->gpct_mode[chan] &= ~G_Loading_On_Gate;
3457 devpriv->gpct_mode[chan] |= G_Loading_On_TC;
3458 devpriv->gpct_mode[chan] &= ~G_Gate_On_Both_Edges;
3461 devpriv->gpct_mode[chan] &= ~(G_Stop_Mode(0x3));
3462 devpriv->gpct_mode[chan] |= G_Stop_Mode(0); //TIM 4/26/01
3464 // Counting_Once = 2
3465 devpriv->gpct_mode[chan] &= ~(G_Counting_Once(0x3));
3466 devpriv->gpct_mode[chan] |= G_Counting_Once(0); //TIM 4/26/01
3469 devpriv->gpct_command[chan] &= ~(G_Up_Down(0x3));
3470 devpriv->gpct_command[chan] |= G_Up_Down(0);
3473 //This seems pretty unsafe since I don't think it is cleared anywhere.
3474 //I don't think this is working
3475 //devpriv->gpct_command[chan] &= ~G_Bank_Switch_Enable;
3476 //devpriv->gpct_command[chan] &= ~G_Bank_Switch_Mode;
3479 win_out( devpriv->gpct_mode[chan],G_Mode_Register(chan));
3480 win_out( devpriv->gpct_command[chan],G_Command_Register(chan));
3482 //printk("exit GPCT_Gen_Cont\n");
3485 static void GPCT_Reset(comedi_device *dev, int chan)
3489 //printk("GPCT_Reset...");
3490 devpriv->gpct_cur_operation[chan] = GPCT_RESET;
3494 win_out(G0_Reset,Joint_Reset_Register);
3495 ni_set_bits(dev,Interrupt_A_Enable_Register,G0_TC_Interrupt_Enable, 0);
3496 ni_set_bits(dev,Interrupt_A_Enable_Register,G0_Gate_Interrupt_Enable,0);
3497 temp_ack_reg |= G0_Gate_Error_Confirm;
3498 temp_ack_reg |= G0_TC_Error_Confirm;
3499 temp_ack_reg |= G0_TC_Interrupt_Ack;
3500 temp_ack_reg |= G0_Gate_Interrupt_Ack;
3501 win_out(temp_ack_reg,Interrupt_A_Ack_Register);
3503 //problem...this interferes with the other ctr...
3504 devpriv->an_trig_etc_reg |= GPFO_0_Output_Enable;
3505 win_out(devpriv->an_trig_etc_reg, Analog_Trigger_Etc_Register);
3508 win_out(G1_Reset,Joint_Reset_Register);
3509 ni_set_bits(dev,Interrupt_B_Enable_Register,G1_TC_Interrupt_Enable, 0);
3510 ni_set_bits(dev,Interrupt_B_Enable_Register,G0_Gate_Interrupt_Enable,0);
3511 temp_ack_reg |= G1_Gate_Error_Confirm;
3512 temp_ack_reg |= G1_TC_Error_Confirm;
3513 temp_ack_reg |= G1_TC_Interrupt_Ack;
3514 temp_ack_reg |= G1_Gate_Interrupt_Ack;
3515 win_out(temp_ack_reg,Interrupt_B_Ack_Register);
3517 devpriv->an_trig_etc_reg |= GPFO_1_Output_Enable;
3518 win_out(devpriv->an_trig_etc_reg, Analog_Trigger_Etc_Register);
3522 devpriv->gpct_mode[chan] = 0;
3523 devpriv->gpct_input_select[chan] = 0;
3524 devpriv->gpct_command[chan] = 0;
3526 devpriv->gpct_command[chan] |= G_Synchronized_Gate;
3528 win_out( devpriv->gpct_mode[chan],G_Mode_Register(chan));
3529 win_out( devpriv->gpct_input_select[chan],G_Input_Select_Register(chan));
3530 win_out( 0,G_Autoincrement_Register(chan));
3532 //printk("exit GPCT_Reset\n");
3535 static int ni_gpct_insn_config(comedi_device *dev,comedi_subdevice *s,
3536 comedi_insn *insn,lsampl_t *data)
3539 //printk("data[0] is 0x%08x, data[1] is 0x%08x\n",data[0],data[1]);
3542 if(insn->n!=1)return -EINVAL;
3543 GPCT_Reset(dev,insn->chanspec);
3545 case GPCT_SET_SOURCE:
3546 if(insn->n!=2)return -EINVAL;
3547 retval=GPCT_Set_Source(dev,insn->chanspec,data[1]);
3550 if(insn->n!=2)return -EINVAL;
3551 retval=GPCT_Set_Gate(dev,insn->chanspec,data[1]);
3553 case GPCT_SET_DIRECTION:
3554 if(insn->n!=2) return -EINVAL;
3555 retval=GPCT_Set_Direction(dev,insn->chanspec,data[1]);
3557 case GPCT_GET_INT_CLK_FRQ:
3558 if(insn->n!=2) return -EINVAL;
3559 //There are actually 2 internal clocks on the STC, we always
3560 //use the fast 20MHz one at this time. Tim Ousley 5/1/01
3561 //NOTE: This is not the final interface, ideally the user
3562 //will never need to know the int. clk. freq.
3563 data[1]=50;//50ns = 20MHz = internal timebase of STC
3565 case GPCT_SET_OPERATION:
3566 //TIM 5/1/01 if((insn->n<2)||(insn->n>3))return -EINVAL;
3568 case GPCT_SIMPLE_EVENT:
3569 GPCT_Event_Counting(dev,insn->chanspec);
3571 case GPCT_SINGLE_PERIOD:
3572 GPCT_Period_Meas(dev,insn->chanspec);
3574 case GPCT_SINGLE_PW:
3575 GPCT_Pulse_Width_Meas(dev,insn->chanspec);
3577 case GPCT_SINGLE_PULSE_OUT:
3578 GPCT_Gen_Single_Pulse(dev,insn->chanspec,data[2]);
3580 case GPCT_CONT_PULSE_OUT:
3581 GPCT_Gen_Cont_Pulse(dev,insn->chanspec,data[2]);
3584 printk("unsupported GPCT operation!\n");
3589 if(insn->n!=1)return -EINVAL;
3590 retval=GPCT_Arm(dev,insn->chanspec);
3593 if(insn->n!=1)return -EINVAL;
3594 retval=GPCT_Disarm(dev,insn->chanspec);
3600 //catch any errors from return values
3604 if(data[0]!=GPCT_ARM){
3605 printk("error: retval was %d\n",retval);
3606 printk("data[0] is 0x%08x, data[1] is 0x%08x\n",data[0],data[1]);
3613 static int ni_gpct_insn_read(comedi_device *dev,comedi_subdevice *s,
3614 comedi_insn *insn,lsampl_t *data) {
3616 int chan=insn->chanspec;
3617 int cur_op = devpriv->gpct_cur_operation[chan];
3619 //printk("in ni_gpct_insn_read, n=%d, data[0]=%d\n",insn->chanspec,data[0]);
3620 if(insn->n!=1)return -EINVAL;
3622 data[0] = GPCT_G_Watch(dev,insn->chanspec);
3624 /* for certain modes (period and pulse width measurment), the value
3625 in the counter is not valid until the counter stops. If the value is
3626 invalid, return a 0 */
3627 if((cur_op == GPCT_SINGLE_PERIOD) || (cur_op == GPCT_SINGLE_PW)){
3628 /* is the counter still running? */
3629 if(win_in(G_Status_Register) & (chan?G1_Counting_St:G0_Counting_St))
3635 static int ni_gpct_insn_write(comedi_device *dev,comedi_subdevice *s,
3636 comedi_insn *insn,lsampl_t *data) {
3638 //printk("in ni_gpct_insn_write");
3639 if(insn->n!=1)return -EINVAL;
3640 GPCT_Load_Using_A(dev,insn->chanspec,data[0]);
3647 * Programmable Function Inputs
3651 static int ni_pfi_insn_bits(comedi_device *dev,comedi_subdevice *s,
3652 comedi_insn *insn,lsampl_t *data)
3654 if(insn->n!=2)return -EINVAL;
3661 static int ni_pfi_insn_config(comedi_device *dev,comedi_subdevice *s,
3662 comedi_insn *insn,lsampl_t *data)
3666 if(insn->n!=1)return -EINVAL;
3668 chan = CR_CHAN(insn->chanspec);
3669 if(chan>10)return -EINVAL;
3673 ni_set_bits(dev, IO_Bidirection_Pin_Register, 1<<chan, 1);
3676 ni_set_bits(dev, IO_Bidirection_Pin_Register, 1<<chan, 0);
3685 static int cs5529_wait_for_idle(comedi_device *dev)
3687 unsigned short status;
3688 const int timeout = HZ;
3691 for(i = 0; i < timeout; i++)
3693 status = ni_ao_win_inw(dev, CAL_ADC_Status_67xx);
3694 if((status & CSS_ADC_BUSY) == 0)
3698 set_current_state(TASK_INTERRUPTIBLE);
3699 if(schedule_timeout(1))
3704 //printk("looped %i times waiting for idle\n", i);
3707 rt_printk("%s: %s: timeout\n", __FILE__, __FUNCTION__);
3713 static void cs5529_command(comedi_device *dev, unsigned short value)
3715 static const int timeout = 100;
3718 ni_ao_win_outw(dev, value, CAL_ADC_Command_67xx);
3719 /* give time for command to start being serially clocked into cs5529.
3720 * this insures that the CSS_ADC_BUSY bit will get properly
3721 * set before we exit this function.
3723 for(i = 0; i < timeout; i++)
3725 if((ni_ao_win_inw(dev, CAL_ADC_Status_67xx) & CSS_ADC_BUSY))
3729 //printk("looped %i times writing command to cs5529\n", i);
3732 comedi_error(dev, "possible problem - never saw adc go busy?");
3736 /* write to cs5529 register */
3737 static void cs5529_config_write(comedi_device *dev, unsigned int value, unsigned int reg_select_bits)
3739 ni_ao_win_outw(dev, ((value >> 16) & 0xff), CAL_ADC_Config_Data_High_Word_67xx);
3740 ni_ao_win_outw(dev, (value & 0xffff), CAL_ADC_Config_Data_Low_Word_67xx);
3741 reg_select_bits &= CSCMD_REGISTER_SELECT_MASK;
3742 cs5529_command(dev, CSCMD_COMMAND | reg_select_bits);
3743 if(cs5529_wait_for_idle(dev))
3744 comedi_error(dev, "time or signal in cs5529_config_write()");
3747 /* read from cs5529 register */
3748 static unsigned int cs5529_config_read(comedi_device *dev, unsigned int reg_select_bits)
3752 reg_select_bits &= CSCMD_REGISTER_SELECT_MASK;
3753 cs5529_command(dev, CSCMD_COMMAND | CSCMD_READ | reg_select_bits);
3754 if(cs5529_wait_for_idle(dev))
3755 comedi_error(dev, "timeout or signal in cs5529_config_read()");
3756 value = (ni_ao_win_inw(dev, CAL_ADC_Config_Data_High_Word_67xx) << 16) & 0xff0000;
3757 value |= ni_ao_win_inw(dev, CAL_ADC_Config_Data_Low_Word_67xx) & 0xffff;
3761 static int cs5529_do_conversion(comedi_device *dev, unsigned short *data)
3764 unsigned short status;
3766 cs5529_command(dev, CSCMD_COMMAND | CSCMD_SINGLE_CONVERSION);
3767 retval = cs5529_wait_for_idle(dev);
3770 comedi_error(dev, "timeout or signal in cs5529_do_conversion()");
3773 status = ni_ao_win_inw(dev, CAL_ADC_Status_67xx);
3774 if(status & CSS_OSC_DETECT)
3776 rt_printk("ni_mio_common: cs5529 conversion error, status CSS_OSC_DETECT\n");
3779 if(status & CSS_OVERRANGE)
3781 rt_printk("ni_mio_common: cs5529 conversion error, overrange (ignoring)\n");
3785 *data = ni_ao_win_inw(dev, CAL_ADC_Data_67xx);
3786 /* cs5529 returns 16 bit signed data in bipolar mode */
3792 static int cs5529_ai_insn_read(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,lsampl_t *data)
3795 unsigned short sample;
3796 unsigned int channel_select;
3797 const unsigned int INTERNAL_REF = 0x1000;
3799 /* Set calibration adc source. Docs lie, reference select bits 8 to 11
3800 * do nothing. bit 12 seems to chooses internal reference voltage, bit
3801 * 13 causes the adc input to go overrange (maybe reads external reference?) */
3802 if(insn->chanspec & CR_ALT_SOURCE)
3803 channel_select = INTERNAL_REF;
3805 channel_select = CR_CHAN(insn->chanspec);
3806 ni_ao_win_outw(dev, channel_select, AO_Calibration_Channel_Select_67xx);
3808 for(n = 0; n < insn->n; n++)
3810 retval = cs5529_do_conversion(dev, &sample);
3811 if(retval < 0) return retval;
3817 static int init_cs5529(comedi_device *dev)
3819 unsigned int config_bits = CSCFG_PORT_MODE | CSCFG_WORD_RATE_2180_CYCLES;
3822 /* do self-calibration */
3823 cs5529_config_write(dev, config_bits | CSCFG_SELF_CAL_OFFSET_GAIN, CSCMD_CONFIG_REGISTER);
3824 /* need to force a conversion for calibration to run */
3825 cs5529_do_conversion(dev, NULL);
3827 /* force gain calibration to 1 */
3828 cs5529_config_write(dev, 0x400000, CSCMD_GAIN_REGISTER);
3829 cs5529_config_write(dev, config_bits | CSCFG_SELF_CAL_OFFSET, CSCMD_CONFIG_REGISTER);
3830 if(cs5529_wait_for_idle(dev))
3831 comedi_error(dev, "timeout or signal in init_cs5529()\n");
3835 rt_printk("config: 0x%x\n", cs5529_config_read(dev, CSCMD_CONFIG_REGISTER));
3836 rt_printk("gain: 0x%x\n", cs5529_config_read(dev, CSCMD_GAIN_REGISTER));
3837 rt_printk("offset: 0x%x\n", cs5529_config_read(dev, CSCMD_OFFSET_REGISTER));