static void Main(string[] args) { // TODO: Select a board UInt32 systemId = 1; UInt32 boardId = 1; // Get a handle to the board IntPtr handle = AlazarAPI.AlazarGetBoardBySystemID(systemId, boardId); if (handle == IntPtr.Zero) { Console.WriteLine("Error: Open board {0}:{1} failed.", systemId, boardId); return; } // Configure sample rate, input, and trigger parameters if (!ConfigureBoard(handle)) { Console.WriteLine("Error: Configure board {0}:{1} failed", systemId, boardId); return; } // Acquire data from the board to an application buffer, // optionally saving the data to file if (!AcquireData(handle)) { Console.WriteLine("Error: Acquire from board {0}:{1} failed", systemId, boardId); return; } }
//--------------------------------------------------------------------------- // // Function : DisplaySystemInfo // // Description : Display information about this board system // //--------------------------------------------------------------------------- static public unsafe bool DisplaySystemInfo(UInt32 systemId) { UInt32 boardCount = AlazarAPI.AlazarBoardsInSystemBySystemID(systemId); if (boardCount == 0) { Console.WriteLine("Error: No boards found in system."); return(false); } IntPtr handle = AlazarAPI.AlazarGetSystemHandle(systemId); if (handle == IntPtr.Zero) { Console.WriteLine("Error: AlazarGetSystemHandle system failed."); return(false); } UInt32 boardType = AlazarAPI.AlazarGetBoardKind(handle); if (boardType == AlazarAPI.ATS_NONE || boardType >= AlazarAPI.ATS_LAST) { Console.WriteLine("Error: Unknown board type " + boardType); return(false); } byte driverMajor, driverMinor, driverRev; UInt32 retCode = AlazarAPI.AlazarGetDriverVersion(&driverMajor, &driverMinor, &driverRev); if (retCode != AlazarAPI.ApiSuccess) { Console.WriteLine("Error: AlazarGetDriverVersion failed -- " + AlazarAPI.AlazarErrorToText(retCode)); return(false); } Console.WriteLine("System ID = {0}", systemId); Console.WriteLine("Board type = {0}", BoardTypeToText(boardType)); Console.WriteLine("Board count = {0}", boardCount); Console.WriteLine("Driver version = {0}.{1}.{2}", driverMajor, driverMinor, driverRev); Console.WriteLine(""); // Display informataion about each board in this board system for (UInt32 boardId = 1; boardId <= boardCount; boardId++) { if (!DisplayBoardInfo(systemId, boardId)) { return(false); } } return(true); }
//--------------------------------------------------------------------------- // // Function : IsPcieDevice // // Description : Return TRUE if board has PCIe host bus interface // //--------------------------------------------------------------------------- static public bool IsPcieDevice(IntPtr handle) { UInt32 boardType = AlazarAPI.AlazarGetBoardKind(handle); if (boardType >= AlazarAPI.ATS9462) { return(true); } else { return(false); } }
static unsafe void Main(string[] args) { // TODO: Select a board UInt32 systemId = 1; UInt32 boardId = 1; // Get a handle to the board IntPtr boardHandle = AlazarAPI.AlazarGetBoardBySystemID(systemId, boardId); if (boardHandle == IntPtr.Zero) { Console.WriteLine("Error: Open board {0}:{1} failed.", systemId, boardId); return; } // Get a handle to the FFT module UInt32 retCode; UInt32 numModules; IntPtr fftHandle = IntPtr.Zero; retCode = AlazarAPI.AlazarDSPGetModules(boardHandle, 0, &fftHandle, &numModules); if (numModules < 1) { Console.WriteLine("This board does any DSP modules"); return; } retCode = AlazarAPI.AlazarDSPGetModules(boardHandle, 1, &fftHandle, &numModules); // TODO: Select the record length UInt32 recordLength_samples = 2048; // Configure sample rate, input, and trigger parameters if (!ConfigureBoard(boardHandle, fftHandle, recordLength_samples)) { Console.WriteLine("Error: Configure board {0}:{1} failed", systemId, boardId); return; } // Acquire data from the board to an application buffer, // optionally saving the data to file if (!AcquireData(boardHandle, fftHandle, recordLength_samples)) { Console.WriteLine("Error: Acquire from board {0}:{1} failed", systemId, boardId); return; } }
static unsafe void Main(string[] args) { // Display SDK version byte sdkMajor, sdkMinor, sdkRevision; UInt32 retCode = AlazarAPI.AlazarGetSDKVersion(&sdkMajor, &sdkMinor, &sdkRevision); if (retCode != AlazarAPI.ApiSuccess) { Console.WriteLine("Error: AlazarGetSDKVersion failed -- " + AlazarAPI.AlazarErrorToText(retCode)); return; } Console.WriteLine("SDK version = {0}.{1}.{2}", sdkMajor, sdkMinor, sdkRevision); // Display information about each board system UInt32 systemCount = AlazarAPI.AlazarNumOfSystems(); if (systemCount < 1) { Console.WriteLine("No systems found!"); return; } Console.WriteLine("System count = {0}", systemCount); for (UInt32 systemId = 1; systemId <= systemCount; systemId++) { if (!DisplaySystemInfo(systemId)) { return; } } return; }
//---------------------------------------------------------------------------- // // Function : ConfigureBoard // // Description : Configure sample rate, input, and trigger settings // //---------------------------------------------------------------------------- static public bool ConfigureBoard(IntPtr boardHandle) { UInt32 retCode; // TODO: Specify the sample rate (in samples per second), // and appropriate sample rate identifier double samplesPerSec = 500000000.0; UInt32 sampleRateId = AlazarAPI.SAMPLE_RATE_500MSPS; // TODO: Select clock parameters as required. retCode = AlazarAPI.AlazarSetCaptureClock( boardHandle, AlazarAPI.INTERNAL_CLOCK, AlazarAPI.SAMPLE_RATE_500MSPS, AlazarAPI.CLOCK_EDGE_RISING, 0 ); if (retCode != AlazarAPI.ApiSuccess) { Console.WriteLine("Error: AlazarSetCaptureClock failed -- " + AlazarAPI.AlazarErrorToText(retCode)); return(false); } // TODO: Select channel A input parameters as required retCode = AlazarAPI.AlazarInputControlEx( boardHandle, AlazarAPI.CHANNEL_A, AlazarAPI.AC_COUPLING, AlazarAPI.INPUT_RANGE_PM_400_MV, AlazarAPI.IMPEDANCE_50_OHM ); if (retCode != AlazarAPI.ApiSuccess) { Console.WriteLine("Error: AlazarInputControlEx failed -- " + AlazarAPI.AlazarErrorToText(retCode)); return(false); } // TODO: Select channel A bandwidth limit as required retCode = AlazarAPI.AlazarSetBWLimit(boardHandle, AlazarAPI.CHANNEL_A, 0); if (retCode != AlazarAPI.ApiSuccess) { Console.WriteLine("Error: AlazarSetBWLimit failed -- " + AlazarAPI.AlazarErrorToText(retCode)); return(false); } // TODO: Select channel B input parameters as required retCode = AlazarAPI.AlazarInputControlEx( boardHandle, AlazarAPI.CHANNEL_B, AlazarAPI.AC_COUPLING, AlazarAPI.INPUT_RANGE_PM_400_MV, AlazarAPI.IMPEDANCE_50_OHM ); if (retCode != AlazarAPI.ApiSuccess) { Console.WriteLine("Error: AlazarInputControlEx failed -- " + AlazarAPI.AlazarErrorToText(retCode)); return(false); } // TODO: Select channel B bandwidth limit as required retCode = AlazarAPI.AlazarSetBWLimit(boardHandle, AlazarAPI.CHANNEL_B, 0); if (retCode != AlazarAPI.ApiSuccess) { Console.WriteLine("Error: AlazarSetBWLimit failed -- " + AlazarAPI.AlazarErrorToText(retCode)); return(false); } // TODO: Select trigger inputs and levels as required retCode = AlazarAPI.AlazarSetTriggerOperation( boardHandle, AlazarAPI.TRIG_ENGINE_OP_J, AlazarAPI.TRIG_ENGINE_J, AlazarAPI.TRIG_CHAN_A, AlazarAPI.TRIGGER_SLOPE_POSITIVE, 150, AlazarAPI.TRIG_ENGINE_K, AlazarAPI.TRIG_DISABLE, AlazarAPI.TRIGGER_SLOPE_POSITIVE, 128); if (retCode != AlazarAPI.ApiSuccess) { Console.WriteLine("Error: AlazarSetTriggerOperation failed -- " + AlazarAPI.AlazarErrorToText(retCode)); return(false); } // TODO: Select external trigger parameters as required retCode = AlazarAPI.AlazarSetExternalTrigger( boardHandle, AlazarAPI.DC_COUPLING, AlazarAPI.ETR_5V); if (retCode != AlazarAPI.ApiSuccess) { Console.WriteLine("Error: AlazarSetExternalTrigger failed -- " + AlazarAPI.AlazarErrorToText(retCode)); return(false); } // TODO: Set trigger delay as required. double triggerDelay_sec = 0; UInt32 triggerDelay_samples = (UInt32)(triggerDelay_sec * samplesPerSec + 0.5); retCode = AlazarAPI.AlazarSetTriggerDelay( boardHandle, // HANDLE -- board handle triggerDelay_samples // U32 -- trigger delay in samples ); if (retCode != AlazarAPI.ApiSuccess) { Console.WriteLine("Error: AlazarSetTriggerDelay failed -- " + AlazarAPI.AlazarErrorToText(retCode)); return(false); } // TODO: Set trigger timeout as required. // NOTE: // The board will wait for a for this amount of time for a trigger event. // If a trigger event does not arrive, then the board will automatically // trigger. Set the trigger timeout value to 0 to force the board to wait // forever for a trigger event. // // IMPORTANT: // The trigger timeout value should be set to zero after appropriate // trigger parameters have been determined, otherwise the // board may trigger if the timeout interval expires before a // hardware trigger event arrives. double triggerTimeout_sec = 0; UInt32 triggerTimeout_clocks = (UInt32)(triggerTimeout_sec / 10E-6 + 0.5); retCode = AlazarAPI.AlazarSetTriggerTimeOut( boardHandle, // HANDLE -- board handle triggerTimeout_clocks // U32 -- timeout_sec / 10.e-6 (0 means wait forever) ); if (retCode != AlazarAPI.ApiSuccess) { Console.WriteLine("Error: AlazarSetTriggerTimeOut failed -- " + AlazarAPI.AlazarErrorToText(retCode)); return(false); } // TODO: Configure AUX I/O connector as required retCode = AlazarAPI.AlazarConfigureAuxIO( boardHandle, AlazarAPI.AUX_OUT_TRIGGER, 0); if (retCode != AlazarAPI.ApiSuccess) { Console.WriteLine("Error: AlazarConfigureAuxIO failed -- " + AlazarAPI.AlazarErrorToText(retCode)); return(false); } return(true); }
//---------------------------------------------------------------------------- // // Function : Acquire data // // Description : Acquire data from board, optionally saving data to file. // //---------------------------------------------------------------------------- static public unsafe bool AcquireData(IntPtr boardHandle) { // TODO: Select the number of pre-trigger samples per record UInt32 preTriggerSamples = 1024; // TODO: Select the number of post-trigger samples per record UInt32 postTriggerSamples = 1024; // TODO: Specify the number of records to acquire to on-board memory UInt32 recordsPerCapture = 100; // TODO: Select the amount of time, in seconds, to wait for the // acquisiton to complete to on-board memory. int timeout_ms = 10 * 1000; // TODO: Select which channels to capture (A, B, or both) 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; // Calculate the size of a record buffer in bytes // Note that the buffer must be at least 16 samples larger than the transfer size UInt32 bytesPerBuffer = bytesPerSample * (samplesPerRecord + 0); // Configure the record size retCode = AlazarAPI.AlazarSetRecordSize( boardHandle, preTriggerSamples, postTriggerSamples ); if (retCode != AlazarAPI.ApiSuccess) { Console.WriteLine("Error: AlazarSetRecordSize failed -- " + AlazarAPI.AlazarErrorToText(retCode)); return(false); } // Configure the number of records in the acquisition retCode = AlazarAPI.AlazarSetRecordCount(boardHandle, recordsPerCapture); if (retCode != AlazarAPI.ApiSuccess) { Console.WriteLine("Error: AlazarSetRecordCount failed -- " + AlazarAPI.AlazarErrorToText(retCode)); return(false); } // Arm the board to wait for a trigger event to begin the acquisition retCode = AlazarAPI.AlazarStartCapture(boardHandle); if (retCode != AlazarAPI.ApiSuccess) { Console.WriteLine("Error: AlazarStartCapture failed -- " + AlazarAPI.AlazarErrorToText(retCode)); return(false); } // Wait for the board to capture all records to on-board memory Console.WriteLine("Capturing {0} record ... press any key to abort", recordsPerCapture); int startTickCount = System.Environment.TickCount; int timeoutTickCount = startTickCount + timeout_ms; bool success = true; while (AlazarAPI.AlazarBusy(boardHandle) != 0 && success == true) { if (System.Environment.TickCount > timeoutTickCount) { Console.WriteLine("Error: Capture timeout after {0} ms", timeout_ms); success = false; } else if (System.Console.KeyAvailable == true) { Console.WriteLine("Acquisition aborted"); success = false; } else { System.Threading.Thread.Sleep(10); } } if (!success) { // Abort the acquisition retCode = AlazarAPI.AlazarAbortCapture(boardHandle); if (retCode != AlazarAPI.ApiSuccess) { Console.WriteLine("Error: AlazarAbortCapture failed -- " + AlazarAPI.AlazarErrorToText(retCode)); } return(false); } // The board captured all records to on-board memory double captureTime_sec = ((double)(System.Environment.TickCount - startTickCount)) / 1000; double recordsPerSec; if (captureTime_sec > 0) { recordsPerSec = recordsPerCapture / captureTime_sec; } else { recordsPerSec = 0; } Console.WriteLine("Captured {0} records in {1:N3} sec ({2:N3} records / sec)", recordsPerCapture, captureTime_sec, recordsPerSec); FileStream fs = null; startTickCount = System.Environment.TickCount; UInt64 bytesTransferred = 0; try { // Create a data file if required if (saveData) { fs = File.Create(@"data.bin"); } // Allocate memory for one record byte[] buffer = new byte[bytesPerBuffer + 16]; // Cast byte array to short array ByteToShortArray byteToShortArray = new ByteToShortArray(); byteToShortArray.bytes = buffer; fixed(short *pBuffer = byteToShortArray.shorts) { // Transfer the records from on-board memory to our buffer Console.WriteLine("Transferring {0} records ... press any key to cancel", recordsPerCapture); UInt32 record; for (record = 0; record < recordsPerCapture; record++) { for (int channel = 0; channel < channelCount; channel++) { // Find the current channel Id UInt32 channelId; if (channelCount == 1) { if ((channelMask & AlazarAPI.CHANNEL_A) != 0) { channelId = AlazarAPI.CHANNEL_A; } else { channelId = AlazarAPI.CHANNEL_B; } } else { if (channel == 0) { channelId = AlazarAPI.CHANNEL_A; } else { channelId = AlazarAPI.CHANNEL_B; } } // Transfer one full record from on-board memory to our buffer retCode = AlazarAPI.AlazarRead( boardHandle, channelId, pBuffer, (int)bytesPerSample, (int)record + 1, -((int)preTriggerSamples), samplesPerRecord ); if (retCode != AlazarAPI.ApiSuccess) { throw new System.Exception("Error: AlazarRead record -- " + AlazarAPI.AlazarErrorToText(retCode)); } bytesTransferred += bytesPerRecord; // TODO: Process record here. // // A 12-bit sample code is stored in the most significant bits // of // in each 16-bit sample value. // // 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 fs.Write(buffer, 0, (int)bytesPerRecord); } } // If a key was pressed, then stop processing records. if (Console.KeyAvailable == true) { throw new System.Exception("Error: Transfer aborted"); } } } } catch (Exception exception) { Console.WriteLine(exception.ToString()); success = false; } finally { // Close the data file if (fs != null) { fs.Close(); } } // Display results double transferTime_sec = ((double)(System.Environment.TickCount - startTickCount)) / 1000; double bytesPerSec; if (transferTime_sec > 0) { bytesPerSec = bytesTransferred / transferTime_sec; } else { bytesPerSec = 0; } Console.WriteLine("Transferred {0} bytes ({1:G4} bytes per sec)", bytesTransferred, bytesPerSec); return(success); }
//---------------------------------------------------------------------------- // // 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 : ConfigureBoard // // Description : Configure sample rate, input, and trigger settings // //---------------------------------------------------------------------------- static public unsafe bool ConfigureBoard(IntPtr boardHandle, IntPtr fftHandle, UInt32 recordLength_samples) { UInt32 retCode; // TODO: Specify the sample rate (in samples per second), // and appropriate sample rate identifier samplesPerSec = 4000000000.0; UInt32 sampleRateId = AlazarAPI.SAMPLE_RATE_4000MSPS; // TODO: Select clock parameters as required. retCode = AlazarAPI.AlazarSetCaptureClock( boardHandle, AlazarAPI.INTERNAL_CLOCK, sampleRateId, AlazarAPI.CLOCK_EDGE_RISING, 0 ); if (retCode != AlazarAPI.ApiSuccess) { Console.WriteLine("Error: AlazarSetCaptureClock failed -- " + AlazarAPI.AlazarErrorToText(retCode)); return(false); } // TODO: Select channel A input parameters as required retCode = AlazarAPI.AlazarInputControlEx( boardHandle, AlazarAPI.CHANNEL_A, AlazarAPI.DC_COUPLING, AlazarAPI.INPUT_RANGE_PM_400_MV, AlazarAPI.IMPEDANCE_50_OHM ); if (retCode != AlazarAPI.ApiSuccess) { Console.WriteLine("Error: AlazarInputControlEx failed -- " + AlazarAPI.AlazarErrorToText(retCode)); return(false); } // TODO: Select channel B input parameters as required retCode = AlazarAPI.AlazarInputControlEx( boardHandle, AlazarAPI.CHANNEL_B, AlazarAPI.DC_COUPLING, AlazarAPI.INPUT_RANGE_PM_400_MV, AlazarAPI.IMPEDANCE_50_OHM ); if (retCode != AlazarAPI.ApiSuccess) { Console.WriteLine("Error: AlazarInputControlEx failed -- " + AlazarAPI.AlazarErrorToText(retCode)); return(false); } // TODO: Select trigger inputs and levels as required retCode = AlazarAPI.AlazarSetTriggerOperation( boardHandle, AlazarAPI.TRIG_ENGINE_OP_J, AlazarAPI.TRIG_ENGINE_J, AlazarAPI.TRIG_CHAN_A, AlazarAPI.TRIGGER_SLOPE_POSITIVE, 150, AlazarAPI.TRIG_ENGINE_K, AlazarAPI.TRIG_DISABLE, AlazarAPI.TRIGGER_SLOPE_POSITIVE, 128 ); if (retCode != AlazarAPI.ApiSuccess) { Console.WriteLine("Error: AlazarSetTriggerOperation failed -- " + AlazarAPI.AlazarErrorToText(retCode)); return(false); } // TODO: Select external trigger parameters as required retCode = AlazarAPI.AlazarSetExternalTrigger( boardHandle, AlazarAPI.DC_COUPLING, AlazarAPI.ETR_TTL ); if (retCode != AlazarAPI.ApiSuccess) { Console.WriteLine("Error: AlazarSetExternalTrigger failed -- " + AlazarAPI.AlazarErrorToText(retCode)); return(false); } // TODO: Set trigger delay as required. double triggerDelay_sec = 0; UInt32 triggerDelay_samples = (UInt32)(triggerDelay_sec * samplesPerSec + 0.5); retCode = AlazarAPI.AlazarSetTriggerDelay( boardHandle, triggerDelay_samples ); if (retCode != AlazarAPI.ApiSuccess) { Console.WriteLine("Error: AlazarSetTriggerDelay failed -- " + AlazarAPI.AlazarErrorToText(retCode)); return(false); } // TODO: Set trigger timeout as required. // NOTE: // The board will wait for a for this amount of time for a trigger event. // If a trigger event does not arrive, then the board will automatically // trigger. Set the trigger timeout value to 0 to force the board to wait // forever for a trigger event. // // IMPORTANT: // The trigger timeout value should be set to zero after appropriate // trigger parameters have been determined, otherwise the // board may trigger if the timeout interval expires before a // hardware trigger event arrives. double triggerTimeout_sec = 0; UInt32 triggerTimeout_clocks = (UInt32)(triggerTimeout_sec / 10E-6 + 0.5); retCode = AlazarAPI.AlazarSetTriggerTimeOut( boardHandle, triggerTimeout_clocks ); if (retCode != AlazarAPI.ApiSuccess) { Console.WriteLine("Error: AlazarSetTriggerTimeOut failed -- " + AlazarAPI.AlazarErrorToText(retCode)); return(false); } // TODO: Configure AUX I/O connector as required retCode = AlazarAPI.AlazarConfigureAuxIO( boardHandle, AlazarAPI.AUX_OUT_TRIGGER, 0 ); if (retCode != AlazarAPI.ApiSuccess) { Console.WriteLine("Error: AlazarConfigureAuxIO failed -- " + AlazarAPI.AlazarErrorToText(retCode)); return(false); } // FFT Configuration UInt32 dspModuleId; UInt16 versionMajor; UInt16 versionMinor; UInt32 maxLength; UInt32 reserved0; UInt32 reserved1; retCode = AlazarAPI.AlazarDSPGetInfo( fftHandle, &dspModuleId, &versionMajor, &versionMinor, &maxLength, &reserved0, &reserved1 ); if ((AlazarAPI.DSP_MODULE_TYPE)dspModuleId != AlazarAPI.DSP_MODULE_TYPE.DSP_MODULE_FFT) { Console.WriteLine("Error: DSP module is not FFT"); return(false); } UInt32 fftLength_samples = 1; while (fftLength_samples < recordLength_samples) { fftLength_samples *= 2; } // TODO: Select the window function type AlazarAPI.DSP_WINDOW_ITEMS windowType = AlazarAPI.DSP_WINDOW_ITEMS.DSP_WINDOW_HANNING; // Create and fill the window function float[] window = new float[fftLength_samples]; fixed(float *pWindow = &window[0]) { retCode = AlazarAPI.AlazarDSPGenerateWindowFunction( (UInt32)windowType, pWindow, recordLength_samples, fftLength_samples - recordLength_samples ); if (retCode != AlazarAPI.ApiSuccess) { Console.WriteLine("Error: AlazarDSPGenerateWindowFunction failed -- " + AlazarAPI.AlazarErrorToText(retCode)); return(false); } // Set the window function retCode = AlazarAPI.AlazarFFTSetWindowFunction( fftHandle, fftLength_samples, pWindow, (float *)0 ); if (retCode != AlazarAPI.ApiSuccess) { Console.WriteLine("Error: AlazarFFTSetWindowFunction failed -- " + AlazarAPI.AlazarErrorToText(retCode)); return(false); } } // TODO: Select the background subtraction record Int16[] backgroundSubtractionRecord = new Int16[recordLength_samples]; // Background subtraction fixed(Int16 *pBackgroundSubtractionRecord = &backgroundSubtractionRecord[0]) { retCode = AlazarAPI.AlazarFFTBackgroundSubtractionSetRecordS16( fftHandle, pBackgroundSubtractionRecord, recordLength_samples ); if (retCode != AlazarAPI.ApiSuccess) { Console.WriteLine("Error: AlazarFFTBackgroundSubtractionSetRecordS16 failed -- " + AlazarAPI.AlazarErrorToText(retCode)); return(false); } } retCode = AlazarAPI.AlazarFFTBackgroundSubtractionSetEnabled( fftHandle, true ); if (retCode != AlazarAPI.ApiSuccess) { Console.WriteLine("Error: AlazarFFTBackgroundSubtractionSetEnabled failed -- " + AlazarAPI.AlazarErrorToText(retCode)); return(false); } return(true); }
//---------------------------------------------------------------------------- // // 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); }
//--------------------------------------------------------------------------- // // Function : DisplayBoardInfo // // Description : Display information about a board // //--------------------------------------------------------------------------- static public unsafe bool DisplayBoardInfo(UInt32 systemId, UInt32 boardId) { UInt32 retCode; IntPtr handle = AlazarAPI.AlazarGetBoardBySystemID(systemId, boardId); if (handle == IntPtr.Zero) { Console.WriteLine("Error: Open systemId {0} boardId {1} failed", systemId, boardId); return(false); } UInt32 samplesPerChannel; byte bitsPerSample; retCode = AlazarAPI.AlazarGetChannelInfo(handle, &samplesPerChannel, &bitsPerSample); if (retCode != AlazarAPI.ApiSuccess) { Console.WriteLine("Error: AlazarGetChannelInfo failed -- " + AlazarAPI.AlazarErrorToText(retCode)); return(false); } UInt32 aspocType; retCode = AlazarAPI.AlazarQueryCapability(handle, AlazarAPI.ASOPC_TYPE, 0, &aspocType); if (retCode != AlazarAPI.ApiSuccess) { Console.WriteLine("Error: AlazarQueryCapability failed -- " + AlazarAPI.AlazarErrorToText(retCode)); return(false); } byte cpldMajor; byte cpldMinor; retCode = AlazarAPI.AlazarGetCPLDVersion(handle, &cpldMajor, &cpldMinor); if (retCode != AlazarAPI.ApiSuccess) { Console.WriteLine("Error: AlazarGetCPLDVersion failed -- " + AlazarAPI.AlazarErrorToText(retCode)); return(false); } UInt32 serialNumber; retCode = AlazarAPI.AlazarQueryCapability(handle, AlazarAPI.GET_SERIAL_NUMBER, 0, &serialNumber); if (retCode != AlazarAPI.ApiSuccess) { Console.WriteLine("Error: AlazarQueryCapability failed -- " + AlazarAPI.AlazarErrorToText(retCode)); return(false); } UInt32 latestCalDate; retCode = AlazarAPI.AlazarQueryCapability(handle, AlazarAPI.GET_LATEST_CAL_DATE, 0, &latestCalDate); if (retCode != AlazarAPI.ApiSuccess) { Console.WriteLine("Error: AlazarQueryCapability failed -- " + AlazarAPI.AlazarErrorToText(retCode)); return(false); } Console.WriteLine("System ID = {0}", systemId); Console.WriteLine("Board ID = {0}", boardId); Console.WriteLine("Serial number = {0}", serialNumber); Console.WriteLine("Bits per sample = {0}", bitsPerSample); Console.WriteLine("Max samples per channel = {0}", samplesPerChannel); Console.WriteLine("CPLD version = {0}.{1}", cpldMajor, cpldMinor); Console.WriteLine("FPGA version = {0}", (aspocType >> 16) & 0xff, (aspocType >> 24) & 0xf); Console.WriteLine("ASoPC signature = {0}", aspocType); Console.WriteLine("Latest calibration date = {0}", latestCalDate); if (IsPcieDevice(handle)) { // Display PCI Express link information UInt32 linkSpeed; retCode = AlazarAPI.AlazarQueryCapability(handle, AlazarAPI.GET_PCIE_LINK_SPEED, 0, &linkSpeed); if (retCode != AlazarAPI.ApiSuccess) { Console.WriteLine("Error: AlazarQueryCapability failed -- " + AlazarAPI.AlazarErrorToText(retCode)); return(false); } UInt32 linkWidth; retCode = AlazarAPI.AlazarQueryCapability(handle, AlazarAPI.GET_PCIE_LINK_WIDTH, 0, &linkWidth); if (retCode != AlazarAPI.ApiSuccess) { Console.WriteLine("Error: AlazarQueryCapability failed -- " + AlazarAPI.AlazarErrorToText(retCode)); return(false); } Console.WriteLine("PCIe link speed = {0} Gbps", 2.5 * linkSpeed); Console.WriteLine("PCIe link width = {0} lanes", linkWidth); } Console.WriteLine(""); // Toggling the LED on the PCIe/PCIe mounting bracket of the board int cycleCount = 2; int cyclePeriod_ms = 200; if (!FlashLed(handle, cycleCount, cyclePeriod_ms)) { return(false); } return(true); }