Driver Development Kit (DDK)

cancel
Showing results for 
Search instead for 
Did you mean: 

Setting up continuous data acquisition with interrupts, no DMA on E-Series

Hi, I am trying to set-up the following model for a PCI-MIO-16E-1 under DDK:
First, a function start() is invoked to start a continuous acquisition at a certain data transfer rate. Next, a read() function is called to acquire one or more samples from the device. Finally, a stop() function requests the end of continous acquisition. The second step can be executed an arbitrary number of times before an end of acquisition is requested.
 
Calling the read() function causes my ISR to run. My problem is how to detect that the acquisition has completed before calling the read() again and also leaving the device in a state after each read(), so that I can call read() again. In my particular example (corresponding to ex. 3 in ch.4 in the PCI-E-series Register Level Prog. Manual), I am acquiring 5 scans from 4 channels with each read().
 
My current implementation would cause the ISR to run twice, once, or not at all. When the ISR runs
twice, it returns the same scan values even though I change the voltage. Please, find the code attached in temo.txt.
 
Thank you.
0 Kudos
Message 1 of 9
(9,254 Views)

After analyzing my problem, it seems to boil down to clearing the interrupt condition. Does anyone know what "external action" the snippet below refers to (taken from the DAQ-STC technical reference manual)?

If (Soft_Copy(AO_FIFO_Interrupt_Enable) is 1) then
{
If (AO_FIFO_Request_St is 1) then
{
/*AO FIFO caused the interrupt*/
Service AO FIFO interrupt;
/*You cannot explicitly acknowledge a FIFO interrupt. You must perform
an action external to the DAQ-STC in order to clear this interrupt
condition*/
}

0 Kudos
Message 2 of 9
(9,229 Views)
Hi,

I believe the "external action" refers to, for example, emptying the FIFO.  The STC does not have a FIFO, it just manages an external FIFO.  If the FIFO is requesting service because is 'not empty', the STC can interrupt the CPU to service the FIFO, but it cannot empty the FIFO itself to clear the interrupt condition.  If you don't want any more FIFO interrupts, you can disable the FIFO interrupt in the STC, but the FIFO remains 'not-empty'.

In the example below, you check the register soft-copy because you have no way to read from the device which interrupts are enabled.  If the interrupt was not enabled there's no need to poll the device.  It's a way to avoid unnecessary bus traffic.  If the AO FIFO interrupt is enabled, check the Status bit to determine if the device is interrupting and if it's actually the FIFO (there could be other interrupts).  If the AO FIFO is configured to interrupt if empty, the isr (or a secondary?) would fill the fifo.

Page 2-88 talks about the STC's FIFO control signals.

Hope this helps,
Diego.
Message 3 of 9
(9,226 Views)

Thanks, Diego. Although your feedback shed light, I have not fully resolved my issue. I am doing AI and have the AI FIFO configured to interrupt if full. When the FIFO interrupts, in my ISR i read the data. Now, what should I do to empty the FIFO so that the STC can push new data in? 2-88 you refer me to mentions a "FIFO reset".  How  do  I  achieve this so that I can acquire more data in a new call to my ISR?

Thank you.

0 Kudos
Message 4 of 9
(9,186 Views)
To clarify, let's say that in my ISR I acquire 20 samples:
 
do
  {
   uStatus = ReadRegister16(pDevExt,AI_Status_1_Register);
   if (!((uStatus & 0x1000) == 0x1000))
   {
    uValues[Samples_Acquired] = (ULONG) ReadRegister16(pDevExt,ADC_FIFO_Data_Register);
    Samples_Acquired++;
   }
  } while(Samples_Acquired<Total_Number_of_Samples);
  for(int uCount=0;uCount<Total_Number_of_Samples;uCount++) {
   DbgPrint("Value %d equals %d \n",uCount,uValues[uCount]);
  }
 
Now what do I to allow another dispatchRead() from a user application for 20 more samples (which will execute this ISR again)?
 
 
0 Kudos
Message 5 of 9
(9,183 Views)
The FIFO reset is not exposed in any failed.  At least I couldn't find it in the STC register map or the ESeries register map.  This is probably an external (to the STC) signal not available thru any register and depend on the hardware implementation.

You make room for new data by reading data.  If you need to empty the FIFO just read until the FIFO signals it's empty.  If the FIFO is full and you read 20 samples, the device can write 20 more samples.  If there's no room when the device tries to write the overflow flag is asserted and the AI is stopped (if configured to do so on error).

In the example above, to receive another interrupt you would re-enable (or leave enabled) the FIFO interrupt. 

From the function names you are using it seems to me you are trying to write a Windows WDM driver.  Is that right?. 

Diego


0 Kudos
Message 6 of 9
(9,160 Views)
Yes, I am writing a Windows WDM driver by using the examples in Chapter 4 of DAQ-STC Technical Manual and the sample code for these examples in the NI DDK. In particular, I am translating example 3 from VISA to Windows DDK (pg 4-15). There are some comments in the code on how to include your ISR which I am following.  Also, I believe I am consistent with your comments, but currently my driver crashes or the ISR gets repeatedly called without having time to service the request. Would you take a look at my ISR (look for "isr" in driver.cpp)? I am not sure what I am doing wrong. Thank you.
 
 
Download All
0 Kudos
Message 7 of 9
(9,138 Views)
Hi,

i couldn't find in your driver the configuration of the FIFO mode.  Using the AI_Mode_3 register you configure the FIFO condition (AI_FIFO_mode) that will generate a FIFO request signal.  By default (0) the FIFO is configured for Not_empty.  This would explain why the interrupt is continuously generated:  as long as there a sample in the buffer you'll get an interrrupt.  Even after removing some sample the interrupt continues becuase is not empty. Other FIFO modes available are:

Not_Empty                       0
Half_Full                           1
Full                                   2
Half_Full_Until_Empty     3

My guess is that Half_Full would work for you.  If you use Full and the acquisition is fast enough, the isr might not get a chance to service the FIFO before the board writes to the FIFO and you get an overflow error.  With Half_Full you have some time before the FIFO overflows and you know for sure you can read half-fifo number of samples without even checking the FIFO state.

Diego


0 Kudos
Message 8 of 9
(9,100 Views)
Hi, I implemented your suggestion, but I still get the same problem: the ISR is called over and over again and prints the same data.
Would that suggest that there are more samples in the FIFO after the Half_Full condition and my interrupt run? That wouldn't make sense as I loop in my ISR until the FIFO is empty. The only way I coulde prevent the  ISR from being called is to inline AI_End_of_Scan in the ISR: as a result, the ISR gets called once, but then when the user calls read(), the same data is acquired again.
 
 
My goal is to "reset" the device, "pause" it, or stop acquiring samples, so that the driver only gets a new interrupt when the user calls read() again to acquire exactly the number of requested samples. I am not sure if the ISR is the place to so.
Download All
0 Kudos
Message 9 of 9
(9,073 Views)