AlazarDSP API Documentation =========================== .. highlight:: c This document presents the AlazarDSP API that allows accessing the on-board digital signal processing (DSP) features provided with some AlazarTech digitizers. Knowledge of the ATS-SDK API is required to take full advantage of the information presented here. Introduction ------------ On-FPGA FFT Overview ~~~~~~~~~~~~~~~~~~~~ The first DSP module to make it into AlazarDSP is a Fast Fourier Transform (FFT) block implemented in ``ATS9350``, ``ATS9351``, ``ATS9352``, ``ATS9360``, ``ATS9370``, ``ATS9371`` and ``ATS9373``. This is a very versatile module that allows its users to compute the Fourier Transform of the input signal acquired on channel A, and to retrieve the processed data in a variety of output formats. The acquired records can be padded then mutiplied with a complex window function before going in the FFT processing block. The resulting data can optionaly be scaled to get its logarithm. The nature of the output data can be chosen (amplitude, real, imaginary), and it is then possible to set the output format from a variety of combinations (floating point, 32-bit unsigned integer, etc.). Lastly, it is possible to get at the output either FFT data, raw (time domain) data or both. The following diagram is a high-level overview of the FFT processing module. .. image:: ../res/fft_block_diagram-250dpi.png General Programming Concepts ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ All the functions from the AlazarDSP module are defined in ``AlazarDSP.h``, and are implemented in the usual ``ATSApi`` library (``ATSApi.dll`` under Windows, and ``libATSApi.so`` under Linux). Function are prefixed either with ``AlazarDSP`` if they apply to any DSP block, or by ``AlazarFFT`` if they are specific to fast Fourier transform modules. The AlazarDSP API introduces a new type called ``dsp_module_handle``, which represents a DSP module within a digitizer. Depending on their scope, function calls either require a board or a DSP module handle to be passed. .. note:: The AlazarDSP functions *must* be used in the context of AutoDMA NPT applications. Transition From Time-Domain Acquisitions ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ This section details all the steps that are required to take a working AutoDMA NPT program and turn it into a FFT program. These code samples can be found in AlazarTech's ATS-SDK_ Function calls to the AlazarTech API are usually split into two categories: board configuration and data acquisition. This is best seen in the code samples provided with the ATS-SDK, where this separation is shown by sub-routines. Most of the AlazarDSP function calls fall into the second category. This means that the board configuration routine of the existing code samples is left mostly untouched. Programs that use the AlazarDSP API need to get the handle of the DSP module they want to use. This is done by calling :cpp:func:`AlazarDSPGetModules()`. Information about the DSP module can be retrieved at any time using :cpp:func:`AlazarDSPGetInfo()`. The board configuration section is left untouched when compared to a standard AutoDMA NPT acquisition. In the data acquisition section, the following changes must be made: 1. :cpp:func:`AlazarSetRecordSize()` is not called. This function is called internally by :cpp:func:`AlazarFFTSetup()`. 2. :cpp:func:`AlazarFFTSetup()` is called before :cpp:func:`AlazarBeforeAsyncRead()` and *before* allocating the DMA buffers. This is due to the fact that the number of bytes of data returned by the FFT engine may vary from one mode to the next, e.g. U16 log of amplitude output, U32 real part, etc. :cpp:func:`AlazarFFTSetup()` returns the effective number of bytes per record that need to be allocated and passed to :cpp:func:`AlazarBeforeAsyncRead()` 3. :cpp:func:`AlazarBeforeAsyncRead()` is called by passing: a. The number of *bytes* per record to the fourth parameter (`SamplesPerRecord`) b. ``0x7FFFFFFF`` to `RecordsPerAcquisition` 4. :cpp:func:`AlazarWaitAsyncBufferComplete()` is replaced with :cpp:func:`AlazarDSPGetBuffer()`. 5. :cpp:func:`AlazarAbortAsyncRead()` is replaced with :cpp:func:`AlazarDSPAbortCapture()`. Detailed Description -------------------- DSP Module Variations ~~~~~~~~~~~~~~~~~~~~~ Features offered by DSP processing modules can vary from one board to another. An example of such variation is the maximum record size, which is generally lower on ATS9350 than on other board models. In order to query these information at runtime, AlazarDSP offers the :cpp:func:`AlazarDSPGetInfo()` function. A generic interface to retrieve parameters has also been added with :cpp:func:`AlazarDSPGetParameterU32()`. Each call to this function allows to retrieve one attribute of a DSP module. Available attributes to query are listed in :cpp:type:`DSP_PARAMETERS`. In addition, FFT module have specific parameters that are not indicated by :cpp:func:`AlazarDSPGetInfo()`. For these modules, another introspection method is :cpp:func:`AlazarFFTGetMaxTriggerRepeatRate()`. The maximum FFT input length can be read from the ``maxLength`` output parameter of :cpp:func:`AlazarDSPGetInfo()`. FFT Module Output Data ~~~~~~~~~~~~~~~~~~~~~~ The output data format of the FFT module is determined by the ``outputFormat`` parameter to :cpp:func:`AlazarFFTSetup()`. This parameter can be any element of the :cpp:type:`FFT_OUTPUT_FORMAT` enumeration except ``FFT_OUTPUT_FORMAT_RAW_PLUS_FFT``, optionnaly OR'ed with ``FFT_OUTPUT_FORMAT_RAW_PLUS_FFT``. The meaning of each element is described in :cpp:type:`FFT_OUTPUT_FORMAT`. If the RAW + FFT mode is selected, a number of samples that correspond to the FFT length is prepended to each record during the output. These samples contain the acquired time-domain data in U16 format, followed with padding to bring the number of samples to the FFT input length. On the board, the Fourier Transform output is a 53-bit unsigned integer that gets converted in various blocks to match the requested output format. Along the conversion, it is possible to set a scaling a slicing parameter. These values are set to sane default in :cpp:func:`AlazarFFTSetup()`. It is possible however for users to change these values manually, using the :cpp:func:`AlazarFFTSetScalingAndSlicing()` function. The block diagram below shows where the conversions happen. .. image:: ../res/post-fft-module-250dpi.png Background Subtraction ~~~~~~~~~~~~~~~~~~~~~~ Starting with version 4.6, the on-FPGA FFT module offers a background subtraction feature. A record to subtract is downloaded on the board with :cpp:func:`AlazarFFTBackgroundSubtractionSetRecordS16()`, and the feature is activated by :cpp:func:`AlazarFFTBackgroundSubtractionSetEnabled()`. Once background subtraction is enabled, the background is subtracted to all acquired time-domain records before they are sent in the FFT processing module. It is not necessary to re-download the background record in between multiple acquisitions in the same program. The dowloaded record remains on the board. On the other hand, the default background record should not be assumed to be made of zeros. As the values *can* remain in the board, even after a reboot of the computer. For 12-bit digitizers, the record is downloaded at 16 bits per sample, but only the 12 most significant bits are actually used. The 4 least significant bits are discarded. This behaviour is consistent with the way the boards acquire and send data back to user applications. .. _ATS-SDK: ftp://release@ftp.alazartech.com/Outgoing/Windows/ATS-SDK