示例#1
0
        //----------------------------------------------------------------------------
        //
        // Function    :  Acquire data
        //
        // Description :  Acquire data from board, optionally saving data to file.
        //
        //----------------------------------------------------------------------------

        static public unsafe bool AcquireData(IntPtr boardHandle)
        {
            // There are no pre-trigger samples in NPT mode
            UInt32 preTriggerSamples = 0;

            // TODO: Select the number of post-trigger samples per record
            UInt32 postTriggerSamples = 2048;

            // TODO: Specify the number of records per DMA buffer
            UInt32 recordsPerBuffer      = 10;
            UInt32 buffersPerAcquisition = 10;

            UInt32 channelMask = AlazarAPI.CHANNEL_A | AlazarAPI.CHANNEL_B;

            // TODO: Select if you wish to save the sample data to a file
            bool saveData = false;

            // Calculate the number of enabled channels from the channel mask
            UInt32 channelCount = 0;

            switch (channelMask)
            {
            case AlazarAPI.CHANNEL_A:
            case AlazarAPI.CHANNEL_B:
                channelCount = 1;
                break;

            case AlazarAPI.CHANNEL_A | AlazarAPI.CHANNEL_B:
                channelCount = 2;
                break;

            default:
                Console.WriteLine("Error: Invalid channel mask -- {0}", channelMask);
                return(false);
            }

            // Get the sample size in bits, and the on-board memory size in samples per channel

            Byte   bitsPerSample;
            UInt32 maxSamplesPerChannel;
            UInt32 retCode = AlazarAPI.AlazarGetChannelInfo(boardHandle, &maxSamplesPerChannel, &bitsPerSample);

            if (retCode != AlazarAPI.ApiSuccess)
            {
                Console.WriteLine("Error: AlazarGetChannelInfo failed -- " +
                                  AlazarAPI.AlazarErrorToText(retCode));
                return(false);
            }

            // Calculate the size of each DMA buffer in bytes

            UInt32 bytesPerSample   = ((UInt32)bitsPerSample + 7) / 8;
            UInt32 samplesPerRecord = preTriggerSamples + postTriggerSamples;
            UInt32 bytesPerRecord   = (bytesPerSample * samplesPerRecord);
            UInt32 bytesPerBuffer   = bytesPerRecord * recordsPerBuffer * channelCount;

            FileStream fileStream = null;
            bool       success    = true;

            try
            {
                // Create a data file if required

                if (saveData)
                {
                    fileStream = File.Create(@"data.bin");
                }

                // Allocate memory for sample buffer

                byte[] buffer = new byte[bytesPerBuffer];

                // Cast byte array to short array

                ByteToShortArray byteToShortArray = new ByteToShortArray();
                byteToShortArray.bytes = buffer;

                fixed(short *pBuffer = byteToShortArray.shorts)
                {
                    // Configure the record size

                    retCode =
                        AlazarAPI.AlazarSetRecordSize(
                            boardHandle,
                            preTriggerSamples,
                            postTriggerSamples
                            );
                    if (retCode != AlazarAPI.ApiSuccess)
                    {
                        throw new System.Exception("Error: AlazarSetRecordSize failed -- " + AlazarAPI.AlazarErrorToText(retCode));
                    }

                    // Configure the board to make an NPT AutoDMA acquisition

                    UInt32 recordsPerAcquisition = recordsPerBuffer * buffersPerAcquisition;

                    retCode =
                        AlazarAPI.AlazarBeforeAsyncRead(
                            boardHandle,
                            channelMask,
                            -(int)preTriggerSamples,
                            samplesPerRecord,
                            recordsPerBuffer,
                            recordsPerAcquisition,
                            AlazarAPI.ADMA_EXTERNAL_STARTCAPTURE | AlazarAPI.ADMA_NPT | AlazarAPI.ADMA_ALLOC_BUFFERS
                            );
                    if (retCode != AlazarAPI.ApiSuccess)
                    {
                        throw new System.Exception("Error: AlazarBeforeAsyncRead failed -- " + AlazarAPI.AlazarErrorToText(retCode));
                    }

                    // Arm the board to begin the acquisition

                    retCode = AlazarAPI.AlazarStartCapture(boardHandle);
                    if (retCode != AlazarAPI.ApiSuccess)
                    {
                        throw new System.Exception("Error: AlazarStartCapture failed -- " +
                                                   AlazarAPI.AlazarErrorToText(retCode));
                    }

                    // Wait for each buffer to be filled, then process the buffer

                    Console.WriteLine("Capturing {0} buffers ... press any key to abort",
                                      buffersPerAcquisition);

                    int startTickCount = System.Environment.TickCount;

                    UInt32 buffersCompleted = 0;
                    Int64  bytesTransferred = 0;

                    bool done = false;

                    while (!done)
                    {
                        // TODO: Set a buffer timeout that is longer than the time
                        //       required to capture all the records in one buffer.

                        UInt32 timeout_ms = 5000;

                        // Wait for a buffer to be filled by the board.

                        retCode = AlazarAPI.AlazarWaitNextAsyncBufferComplete(boardHandle, pBuffer, bytesPerBuffer, timeout_ms);
                        if (retCode == AlazarAPI.ApiSuccess)
                        {
                            // This buffer is full, but there are more buffers in the acquisition.
                        }
                        else if (retCode == AlazarAPI.ApiTransferComplete)
                        {
                            // This buffer is full, and it's the last buffer of the acqusition.
                            done = true;
                        }
                        else
                        {
                            throw new System.Exception("Error: AlazarWaitNextAsyncBufferComplete failed -- " +
                                                       AlazarAPI.AlazarErrorToText(retCode));
                        }

                        buffersCompleted++;
                        bytesTransferred += bytesPerBuffer;

                        // TODO: Process sample data in this buffer.

                        // NOTE:
                        //
                        // While you are processing this buffer, the board is already
                        // filling the next available buffer(s).
                        //
                        // You MUST finish processing this buffer and post it back to the
                        // board before the board fills all of the available DMA buffers,
                        // and its on-board memory.
                        //
                        // Samples are arranged in the buffer as follows: S0A, S0B, ..., S1A, S1B, ...
                        // with SXY the sample number X of channel Y.
                        //
                        //
                        // Sample codes are unsigned by default. As a result:
                        // - a sample code of 0x0000 represents a negative full scale
                        // input signal.
                        // - a sample code of 0x8000 represents a ~0V signal.
                        // - a sample code of 0xFFFF represents a positive full scale
                        // input signal.
                        if (saveData)
                        {
                            // Write record to file
                            fileStream.Write(buffer, 0, (int)bytesPerBuffer);
                        }
                        // If a key was pressed, exit the acquisition loop
                        if (Console.KeyAvailable == true)
                        {
                            Console.WriteLine("Aborted...");
                            done = true;
                        }

                        if (buffersCompleted >= buffersPerAcquisition)
                        {
                            done = true;
                        }

                        // Display progress
                        Console.Write("Completed {0} buffers\r", buffersCompleted);
                    }
                    // Display results

                    double transferTime_sec = ((double)(System.Environment.TickCount - startTickCount)) / 1000;

                    Console.WriteLine("Capture completed in {0:N3} sec", transferTime_sec);

                    UInt32 recordsTransferred = recordsPerBuffer * buffersCompleted;

                    double buffersPerSec;
                    double bytesPerSec;
                    double recordsPerSec;

                    if (transferTime_sec > 0)
                    {
                        buffersPerSec = buffersCompleted / transferTime_sec;
                        bytesPerSec   = bytesTransferred / transferTime_sec;
                        recordsPerSec = recordsTransferred / transferTime_sec;
                    }
                    else
                    {
                        buffersPerSec = 0;
                        bytesPerSec   = 0;
                        recordsPerSec = 0;
                    }

                    Console.WriteLine("Captured {0} buffers ({1:G4} buffers per sec)", buffersCompleted, buffersPerSec);
                    Console.WriteLine("Captured {0} records ({1:G4} records per sec)", recordsTransferred, recordsPerSec);
                    Console.WriteLine("Transferred {0} bytes ({1:G4} bytes per sec)", bytesTransferred, bytesPerSec);
                }
            }
            catch (Exception exception)
            {
                Console.WriteLine(exception.ToString());
                success = false;
            }
            finally
            {
                // Close the data file
                if (fileStream != null)
                {
                    fileStream.Close();
                }

                // Abort the acquisition
                retCode = AlazarAPI.AlazarAbortAsyncRead(boardHandle);
                if (retCode != AlazarAPI.ApiSuccess)
                {
                    Console.WriteLine("Error: AlazarAbortAsyncRead failed -- " +
                                      AlazarAPI.AlazarErrorToText(retCode));
                }
            }

            return(success);
        }
        //----------------------------------------------------------------------------
        //
        // Function    :  Acquire data
        //
        // Description :  Acquire data from board, optionally saving data to file.
        //
        //----------------------------------------------------------------------------

        static public unsafe bool AcquireData(IntPtr boardHandle, IntPtr fftHandle, UInt32 recordLength_samples)
        {
            UInt32 retCode;

            // TODO: Specify the number of records per DMA buffer
            UInt32 recordsPerBuffer = 10;

            // TODO: Specify the total number of buffers to capture
            UInt32 buffersPerAcquisition = 10;

            // Acquiring from a single channel
            UInt32 channelMask = AlazarAPI.CHANNEL_A;

            // TODO: Select if you wish to save the sample data to a file
            bool saveData = false;

            // TODO: Select the FFT output format
            AlazarAPI.FFT_OUTPUT_FORMAT outputFormat = AlazarAPI.FFT_OUTPUT_FORMAT.FFT_OUTPUT_FORMAT_U16_LOG;

            // TODO: Select the presence of NPT footers
            AlazarAPI.FFT_FOOTER footer = AlazarAPI.FFT_FOOTER.FFT_FOOTER_NONE;

            // Get the sample size in bits, and the on-board memory size in samples per channel
            Byte   bitsPerSample;
            UInt32 maxSamplesPerChannel;

            retCode = AlazarAPI.AlazarGetChannelInfo(
                boardHandle,
                &maxSamplesPerChannel,
                &bitsPerSample
                );
            if (retCode != AlazarAPI.ApiSuccess)
            {
                Console.WriteLine("Error: AlazarGetChannelInfo failed -- " +
                                  AlazarAPI.AlazarErrorToText(retCode));
                return(false);
            }

            FileStream fileStream = null;
            bool       success    = true;

            try
            {
                // Create a data file if required
                if (saveData)
                {
                    fileStream = File.Create(@"data.bin");
                }

                // Configure the FFT
                UInt32 fftLength_samples = 1;
                while (fftLength_samples < recordLength_samples)
                {
                    fftLength_samples *= 2;
                }

                UInt32 bytesPerOutputRecord;
                retCode = AlazarAPI.AlazarFFTSetup(
                    fftHandle,
                    (UInt16)channelMask,
                    recordLength_samples,
                    fftLength_samples,
                    (UInt32)outputFormat,
                    (UInt32)footer,
                    0,
                    &bytesPerOutputRecord
                    );
                if (retCode != AlazarAPI.ApiSuccess)
                {
                    throw new System.Exception("Error: AlazarFFTSetup failed -- " +
                                               AlazarAPI.AlazarErrorToText(retCode));
                }

                UInt32 bytesPerBuffer = bytesPerOutputRecord * recordsPerBuffer;

                // Allocate memory for sample buffer
                byte[] buffer = new byte[bytesPerBuffer];

                // Cast byte array to short array
                ByteToShortArray byteToShortArray = new ByteToShortArray();
                byteToShortArray.bytes = buffer;

                fixed(short *pBuffer = byteToShortArray.shorts)
                {
                    // Configure the board to make an NPT_onFPGA_FFT acquisition
                    UInt32 recordsPerAcquisition = recordsPerBuffer * buffersPerAcquisition;

                    UInt32 admaFlags = AlazarAPI.ADMA_EXTERNAL_STARTCAPTURE | AlazarAPI.ADMA_NPT | AlazarAPI.ADMA_DSP | AlazarAPI.ADMA_FIFO_ONLY_STREAMING | AlazarAPI.ADMA_ALLOC_BUFFERS;

                    retCode = AlazarAPI.AlazarBeforeAsyncRead(
                        boardHandle,
                        channelMask,
                        0,
                        bytesPerOutputRecord,
                        recordsPerBuffer,
                        0x7FFFFFFF,
                        admaFlags
                        );
                    if (retCode != AlazarAPI.ApiSuccess)
                    {
                        throw new System.Exception("Error: AlazarBeforeAsyncRead failed -- " +
                                                   AlazarAPI.AlazarErrorToText(retCode));
                    }

                    // Arm the board to begin the acquisition
                    retCode = AlazarAPI.AlazarStartCapture(boardHandle);
                    if (retCode != AlazarAPI.ApiSuccess)
                    {
                        throw new System.Exception("Error: AlazarStartCapture failed -- " +
                                                   AlazarAPI.AlazarErrorToText(retCode));
                    }

                    // Wait for each buffer to be filled, then process the buffer

                    Console.WriteLine("Capturing {0} buffers ... press any key to abort",
                                      buffersPerAcquisition);

                    int startTickCount = System.Environment.TickCount;

                    UInt32 buffersCompleted = 0;
                    Int64  bytesTransferred = 0;

                    bool done = false;

                    while (!done)
                    {
                        // TODO: Set a buffer timeout that is longer than the time
                        //       required to capture all the records in one buffer.
                        UInt32 timeout_ms = 5000;

                        // Wait for a buffer to be filled by the board.
                        retCode = AlazarAPI.AlazarWaitNextAsyncBufferComplete(
                            boardHandle,
                            pBuffer,
                            bytesPerBuffer,
                            timeout_ms
                            );
                        if (retCode == AlazarAPI.ApiSuccess)
                        {
                            // This buffer is full, but there are more buffers in the acquisition.
                        }
                        else if (retCode == AlazarAPI.ApiTransferComplete)
                        {
                            // This buffer is full, and it's the last buffer of the acqusition.
                            done = true;
                        }
                        else
                        {
                            throw new System.Exception("Error: AlazarWaitNextAsyncBufferComplete failed -- " +
                                                       AlazarAPI.AlazarErrorToText(retCode));
                        }

                        buffersCompleted++;
                        bytesTransferred += bytesPerBuffer;

                        // TODO: Process sample data in this buffer.

                        // NOTE:
                        //
                        // While you are processing this buffer, the board is already
                        // filling the next available buffer(s).
                        //

                        if (saveData)
                        {
                            // Write record to file
                            fileStream.Write(buffer, 0, (int)bytesPerBuffer);
                        }

                        // If a key was pressed, exit the acquisition loop
                        if (Console.KeyAvailable == true)
                        {
                            Console.WriteLine("Aborted...");
                            done = true;
                        }

                        if (buffersCompleted >= buffersPerAcquisition)
                        {
                            done = true;
                        }

                        // Display progress
                        Console.Write("Completed {0} buffers\r", buffersCompleted);
                    }

                    // Display results
                    double transferTime_sec = ((double)(System.Environment.TickCount - startTickCount)) / 1000;

                    Console.WriteLine("Capture completed in {0:N3} sec", transferTime_sec);

                    UInt32 recordsTransferred = recordsPerBuffer * buffersCompleted;

                    double buffersPerSec;
                    double bytesPerSec;
                    double recordsPerSec;

                    if (transferTime_sec > 0)
                    {
                        buffersPerSec = buffersCompleted / transferTime_sec;
                        bytesPerSec   = bytesTransferred / transferTime_sec;
                        recordsPerSec = recordsTransferred / transferTime_sec;
                    }
                    else
                    {
                        buffersPerSec = 0;
                        bytesPerSec   = 0;
                        recordsPerSec = 0;
                    }

                    Console.WriteLine("Captured {0} buffers ({1:G4} buffers per sec)", buffersCompleted, buffersPerSec);
                    Console.WriteLine("Captured {0} records ({1:G4} records per sec)", recordsTransferred, recordsPerSec);
                    Console.WriteLine("Transferred {0} bytes ({1:G4} bytes per sec)", bytesTransferred, bytesPerSec);
                }
            }
            catch (Exception exception)
            {
                Console.WriteLine(exception.ToString());
                success = false;
            }
            finally
            {
                // Close the data file
                if (fileStream != null)
                {
                    fileStream.Close();
                }

                // Abort the acquisition
                retCode = AlazarAPI.AlazarAbortAsyncRead(boardHandle);
                if (retCode != AlazarAPI.ApiSuccess)
                {
                    Console.WriteLine("Error: AlazarAbortAsyncRead failed -- " +
                                      AlazarAPI.AlazarErrorToText(retCode));
                }
            }

            return(success);
        }