Tim Ousley 4/10/01: MITE DMA now works correctly for finite acquisitions
authorTim Ousley <tim.ousley@ni.com>
Tue, 10 Apr 2001 16:45:58 +0000 (16:45 +0000)
committerTim Ousley <tim.ousley@ni.com>
Tue, 10 Apr 2001 16:45:58 +0000 (16:45 +0000)
smaller than the prealloc bufsz.  uncomment #define PCIDMA in ni_pcimio.c

comedi/drivers/mite.c
comedi/drivers/mite.h
comedi/drivers/ni_mio_common.c

index 00a1145e1da25332d6234ffec0013cbe4e5c09c3..7f17c122019dbfad2b18dfbbc27728ada3c91eb3 100644 (file)
@@ -296,7 +296,7 @@ unsigned long mite_ll_from_kvmem(struct mite_struct *mite,comedi_async *async,in
 {
        int i,size_so_far;
        unsigned long nup;
-       //unsigned long prealloc_buf,prealloc_bufsz; 
+       unsigned long prealloc_buf,prealloc_bufsz; 
        //comedi_subdevice *s;
        //struct mite_struct *mite=NULL;
        //comedi_async *async=NULL;
@@ -305,8 +305,8 @@ unsigned long mite_ll_from_kvmem(struct mite_struct *mite,comedi_async *async,in
        MDPRINTK("mite_ll_from_kvmem\n");
        //s=dev->subdevices+cmd->subdev;
        //mite=devpriv->mite;
-       //prealloc_buf=(unsigned long)s->async->prealloc_buf;
-       //prealloc_bufsz=s->async->prealloc_bufsz;
+       prealloc_buf=(unsigned long)async->prealloc_buf;
+       prealloc_bufsz=async->prealloc_bufsz;
        
        //len = min(cmd->scan_end_arg*cmd->stop_arg*sizeof(sampl_t), async->data_len);
        if(async->data_len<len) {
@@ -316,7 +316,7 @@ unsigned long mite_ll_from_kvmem(struct mite_struct *mite,comedi_async *async,in
        nup = (unsigned long)async->data;
        i=0;
        size_so_far=0;
-       MDPRINTK("buf=0x%08lx bufsz=0x%08x\n",
+       MDPRINTK("buf=0x%08lx bufsz=0x%08lx\n",
                (unsigned long)prealloc_buf,prealloc_bufsz);
        
        while(((void*)nup < (async->data+len))&&(i<(MITE_RING_SIZE-1))) {
@@ -342,6 +342,8 @@ unsigned long mite_ll_from_kvmem(struct mite_struct *mite,comedi_async *async,in
        return virt_to_bus(&(mite->ring[0]));
 }
 
+/* This function would be used to DMA directly into user memory.
+Since Comedi won't support that for a while, this should probably be removed. --Tim Ousley
 unsigned long mite_ll_from_user(comedi_device *dev, comedi_cmd *cmd)
 {
        int i,size_so_far,len;
@@ -384,6 +386,7 @@ unsigned long mite_ll_from_user(comedi_device *dev, comedi_cmd *cmd)
        MDPRINTK("exit mite_ll_from_user\n");
        return virt_to_bus(&(mite->ring[0]));
 }
+*/
 
 void mite_dma_arm(struct mite_struct *mite)
 {
@@ -480,7 +483,7 @@ void mite_dma_disarm(struct mite_struct *mite)
 
 void mite_dump_regs(struct mite_struct *mite)
 {
-       unsigned long mite_io_addr = mite->mite_io_addr;
+       unsigned long mite_io_addr = (unsigned long) mite->mite_io_addr;
        unsigned long addr=0;
        unsigned long temp=0;
 
@@ -566,7 +569,7 @@ EXPORT_SYMBOL(mite_list_devices);
 
 //Tim's debugging function
 EXPORT_SYMBOL(mite_dump_regs);
-EXPORT_SYMBOL(mite_ll_from_user);
+//EXPORT_SYMBOL(mite_ll_from_user); //obsolete
 EXPORT_SYMBOL(mite_ll_from_kvmem);
 EXPORT_SYMBOL(mite_setregs);
 EXPORT_SYMBOL(mite_bytes_transferred);
index 5383638ab2738ac75aaab31f2db6f2573c2da892..61a06f8cd3660690e93afabd43951b6140d16b33 100644 (file)
@@ -41,8 +41,7 @@
 #define MDPRINTK(format,args...)
 #endif
 
-#define MITE_RING_SIZE 3000 
-
+#define MITE_RING_SIZE 3000
 struct mite_dma_chain{
        u32 count;
        u32 addr;
@@ -95,7 +94,7 @@ int mite_dma_tcr(struct mite_struct *mite);
 void mite_dma_arm(struct mite_struct *mite);
 void mite_dma_disarm(struct mite_struct *mite);
        
-unsigned long mite_ll_from_user(comedi_device *dev, comedi_cmd *cmd);
+//unsigned long mite_ll_from_user(comedi_device *dev, comedi_cmd *cmd);//obsolete
 unsigned long mite_ll_from_kvmem(struct mite_struct *mite,comedi_async *async,int len);
 void mite_dump_regs(struct mite_struct *mite);
 void mite_setregs(struct mite_struct *mite,unsigned long ll_start,int chan, int dir);
index 6e54f4b0272378adddf50fac52b7efa246b4d2e6..37818e59d785ad50d291804e8b8b9d82326b5ae0 100644 (file)
@@ -54,7 +54,7 @@
 
 //#define DEBUG_INTERRUPT
 //#define TRY_BLOCK
-//#define DEBUG_STATUS_A
+#define DEBUG_STATUS_A
 //#define DEBUG_STATUS_B
 
 #include <8255.h>
@@ -219,7 +219,9 @@ static void pfi_setup(comedi_device *dev);
 static void handle_a_interrupt(comedi_device *dev,unsigned short status);
 static void handle_b_interrupt(comedi_device *dev,unsigned short status);
 #ifdef PCIDMA
-static void mite_handle_interrupt(comedi_device *dev,unsigned short status);
+/*status must be long because the CHSR is 32 bits and the high bits
+are important to us */
+static void mite_handle_interrupt(comedi_device *dev,unsigned long status);
 #endif
 
 static
@@ -230,7 +232,9 @@ void ni_E_interrupt(int irq,void *d,struct pt_regs * regs)
        unsigned short b_status;
        int wsave;
 #ifdef PCIDMA
-       unsigned short m_status;
+       /* m_status must be long because the CHSR is a 32 bit register and we are
+       interested in several high bits */
+       unsigned long m_status;
 #endif
 
        MDPRINTK("ni_E_Interrupt\n");
@@ -254,21 +258,18 @@ void ni_E_interrupt(int irq,void *d,struct pt_regs * regs)
        ni_mio_print_status_b(b_status);
 #endif
 #ifdef PCIDMA
-       rt_printk("mite status=0x%08x\n",readw(devpriv->mite->mite_io_addr+0x14));
-#endif
-
-#ifdef PCIDMA
+       //rt_printk("mite status=0x%08lx\n",m_status);
        if(m_status&CHSR_INT)mite_handle_interrupt(dev,m_status);
 #endif
        if(a_status&Interrupt_A_St)handle_a_interrupt(dev,a_status);
        if(b_status&Interrupt_B_St)handle_b_interrupt(dev,b_status);
-
+       
        win_restore(wsave);
        MDPRINTK("exit ni_E_Interrupt\n");
 }
 
 #ifdef PCIDMA
-static void mite_handle_interrupt(comedi_device *dev,unsigned short m_status)
+static void mite_handle_interrupt(comedi_device *dev,unsigned long m_status)
 {
        comedi_subdevice *s=dev->subdevices+0;
        
@@ -277,19 +278,15 @@ static void mite_handle_interrupt(comedi_device *dev,unsigned short m_status)
        MDPRINTK("MITE generated an int!!\n");
        writel(CHOR_CLRLC, devpriv->mite->mite_io_addr+MITE_CHOR+CHAN_OFFSET(0));
        s->async->buf_int_count=mite_bytes_transferred(devpriv->mite, 0);
-       if (s->async->cmd.data ==NULL) {
-               s->async->buf_int_ptr= s->async->buf_int_count % s->async->prealloc_bufsz;
-       } else {
-               s->async->buf_int_ptr= s->async->buf_int_count % s->async->cmd.data_len;
-       }       
-       MDPRINTK("CHSR is 0x%08X, count is %d\n",m_status,s->async->buf_int_count);
+       s->async->buf_int_ptr= s->async->buf_int_count % s->async->prealloc_bufsz;     
+       MDPRINTK("CHSR is 0x%08lx, count is %d\n",m_status,s->async->buf_int_count);
        if(m_status&CHSR_DONE){
 #ifdef DEBUG_MITE
-               /*mite_printk(devpriv->mite->mite_io_addr);*/
+               mite_dump_regs(devpriv->mite);
 #endif  
                writel(CHOR_CLRDONE, devpriv->mite->mite_io_addr+MITE_CHOR+CHAN_OFFSET(0));
-               printk("buf_int_count is %d, buf_int_ptr is %d\n",
-                               s->async->buf_int_count,s->async->buf_int_ptr);
+               //printk("buf_int_count is %d, buf_int_ptr is %d\n",
+               //              s->async->buf_int_count,s->async->buf_int_ptr);
                ni_handle_block_dma(dev);
        }       
        MDPRINTK("exit mite_handle_interrupt\n");
@@ -319,6 +316,7 @@ static void handle_a_interrupt(comedi_device *dev,unsigned short status)
                        ni_mio_print_status_a(status);
                        ni_handle_fifo_dregs(dev);
                        win_out(0x0000,Interrupt_A_Enable_Register);
+                       ni_ai_reset(dev,dev->subdevices);//added by tim
                        comedi_done(dev,s);
                        return;
                }
@@ -328,7 +326,9 @@ static void handle_a_interrupt(comedi_device *dev,unsigned short status)
 #endif
 #ifdef TRY_BLOCK
 #ifdef PCIDMA
-                       ni_handle_block_dma(dev);
+                       //just ignore the terminal count from the STC
+                       //instead finish up when the MITE asserts DONE
+                       //ni_handle_block_dma(dev);
 #else
                        ni_handle_block(dev);
 #endif
@@ -465,13 +465,13 @@ static void ni_ai_fifo_read(comedi_device *dev,comedi_subdevice *s,
 #ifdef PCIDMA
 static void ni_handle_block_dma(comedi_device *dev)
 {
-       MDPRINTK("ni_handle_block\n");
-       mite_dump_regs(devpriv->mite);
+       MDPRINTK("ni_handle_block_dma\n");
+       //mite_dump_regs(devpriv->mite);
        mite_dma_disarm(devpriv->mite);
        win_out(0x0000,Interrupt_A_Enable_Register);
        ni_ai_reset(dev,dev->subdevices);
        comedi_done(dev,dev->subdevices);
-       MDPRINTK("exit ni_handle_block\n");
+       MDPRINTK("exit ni_handle_block_dma\n");
 }
 #endif
 
@@ -700,6 +700,40 @@ printk("n_left = %d\n",devpriv->n_left);
 }
 #endif
 
+#ifdef PCIDMA
+int ni_ai_setup_MITE_dma(comedi_device *dev,comedi_cmd *cmd,int mode1)
+{
+       int n;
+       unsigned long ll_start;
+       comedi_async *async_mite;
+               
+       async_mite=dev->subdevices[cmd->subdev].async;
+       ll_start = mite_ll_from_kvmem(devpriv->mite, async_mite,cmd->stop_arg);
+       mite_setregs(devpriv->mite, ll_start,0,COMEDI_INPUT);
+
+       /*tell the STC to use DMA0 for AI.
+       Select the MITE DMA channel to use, 0x01=A*/
+       ni_writeb(0x01,AI_AO_Select);
+
+       /* stage number of scans */
+       n = cmd->stop_arg;
+       win_out((n-1)>>16,AI_SC_Load_A_Registers);
+       win_out((n-1)&0xffff,AI_SC_Load_A_Registers+1);
+       win_out((n-1)>>16,AI_SC_Load_B_Registers);
+       win_out((n-1)&0xffff,AI_SC_Load_B_Registers+1);
+       
+       /* load SC (Scan Count) */
+       win_out(AI_SC_Load,AI_Command_1_Register);
+
+       mode1 |= AI_Start_Stop | AI_Mode_1_Reserved | AI_Continuous;
+       win_out(mode1,AI_Mode_1_Register);
+       
+       /*start the MITE*/
+       mite_dma_arm(devpriv->mite);
+       return mode1;
+}
+#endif
+
 /*
    used for both cancel ioctl and board initialization
 
@@ -1024,6 +1058,9 @@ static int ni_ai_cmd(comedi_device *dev,comedi_subdevice *s)
        win_out(AI_Configuration_Start,Joint_Reset_Register);
 
 #ifndef TRY_BLOCK
+       #ifdef PCIDMA
+       ni_ai_setup_MITE_dma(dev,cmd,mode1);    
+       #else
        switch(cmd->stop_src){
        case TRIG_COUNT:
                /* stage number of scans */
@@ -1054,8 +1091,8 @@ static int ni_ai_cmd(comedi_device *dev,comedi_subdevice *s)
 
                break;
        }
+       #endif
 #else
-
        devpriv->blocksize = 0x4000;
        switch(cmd->stop_src){
        case TRIG_COUNT: