Advanced DAQ Features

Selecting the Image_sync Input

The DAQ is compatible with both single-ended (LVCMOS) or differential (LVDS) Image_Sync trigger inputs. The single-ended input is provided for ease of setup during initial integration or in a laboratory environment (e.g. trigger provided directly by a benchtop waveform generator sync output). The DAQ is also capable of generating an Image_sync trigger internally for simulation purposes.

Hardware Control Tool
AxsunOCTControl API

Select the desired Image_sync trigger input from the associated menu on the DAQ Timing Settings control of the “Miscellaneous” tab.

If an internal Image_sync is selected for simulation purposes, its frequency is also configurable from this control.

WriteDAQRegisterBit(2,11,0); // clearing Register 2 bit 11
WriteDAQRegisterBit(2,9,1); // setting register 2 bit 9 for LVCMOS input
WriteDAQRegisterBit(2,9,0); // clearing register 2 bit 9 for LVDS input

or

WriteDAQRegister(2,11,1); // setting register 2 bit 11 for internal Imag_sync

Selecting which ADC Channel to Transmit

A Channel Mixer is provided to calculate the vector sum (i.e. square-root of the sum of the squares) of the H and V channels for optical interferometers employing polarization diverse detection. For a non-polarization diverse (i.e. single-channel) setup, it is advantageous to disable the Channel Mixer and transmit captured data from the connected channel only. The DAQ provides the ability to transmit data from either H, or V, or the combined channels. It is not possible to concurrently transmit data from both channels 1 and 2 separately.

Hardware Control Tool
AxsunOCTControl API

On the “Pipeline Modes & Subsampling” tab, select the desired channel:

  • Channel 1 using the BLUE blocks

  • Channel 2 using the RED blocks

  • Both (the vector sum of both channels for polarization diverse detection) using the PURPLE blocks

WriteDAQRegisterBit(20,13,1); // setting register 20 bit 13
WriteDAQRegisterBit(20,5,1); // setting register 20 bit 5 for channel 1
WriteDAQRegisterBit(20,5,0); // clearing register 20 bit 5 for channel 2

or

WriteDAQRegisterBit(20,13,0); // clearing register 20 bit 13 for channels 1&2

Systems which do not support the optional Raw Data / Bypass Mode functionality must use only the JPEG blocks on the right of the block diagram. These JPEG blocks will NOT be functional for systems connected using the PCIe interface.

The selected channel will persist in the FPGA until a new channel is selected, or the DAQ board is power cycled. A selected channel can be configured to persist as the DAQ’s power-on default using the FPGA Configuration Script functionality.

Setting the Apodization Window Function

The apodization window function is downloaded to the FPGA in the form of a 2048-point lookup-table (LUT) which is subsequently multiplied by the sampled spectral data (length = Nsamp, depending on laser and K-clock parameters) to shape it and zero-pad it to 2048 points. The FPGA can apply separate window functions for H and V channels if desired. The Hardware Control Tool provides a limited set of common window function types, but the user is free to load an arbitrary custom window function via the API if desired.

Hardware Control Tool
AxsunOCTControl API
  1. On the “Pipeline Modes & Subsampling” tab, select the desired channel for which to load a Windowing LUT.

  2. On the “Windowing & Dispersion Compensation” tab, select a window Type, enter the window Width (= Nsamp from laser test report), and press Update DAQ (real only)*.

To load the same LUT for both channels, repeat these instructions for each channel separately; the Both setting for channel selection will not automatically load the LUT for both channels.

You can observe the effects on the image if you are watching the live image display when downloading the new Windowing LUT.

  1. Select the desired channel per instructions above

  • PC: Create a 1D array of length = 2048 consisting of the desired window function of length Nsamp concatenated to (2048 – Nsamp) zeros. Use a signed (two’s complement) 16-bit integer data type scaled so the maximum representable value (32767 = 215 – 1) represents unity (i.e. application of LUT is a multiplication by 1).

  • DAQ: send the 2048-element 1D array to Register 25 using SendFPGAData(…)

    or perform 2048 consecutive writes to Register 25 with SetFPGARegister(25,…)and the written value in each iteration equal to the next element in the window function array.

The loaded Windowing LUT will persist in the FPGA until overwritten with a new Windowing LUT, or the DAQ board is power cycled. A Windowing LUT can be configured to persist as the DAQ’s power-on default using the FPGA Configuration Script functionality.

Setting GAIN and OFFSET for Dynamic Range Compression

The DAQ performs dynamic range reduction by converting 16-bit data to 8-bit data by truncating the least significant byte. User-configurable GAIN and OFFSET values allow adjustment of the desired intensity range before truncation.

Hardware Control Tool
AxsunOCTControl API

Select the desired GAIN and OFFSET on the “Pipeline Modes & Subsampling” tab:

Example of setting GAIN and OFFSET. Hexadecimal values shown above are for informational purposes. These can also be set directly on the FPGA Registers tab.

OFFSET is a 16-bit signed fixed-point integer with 8 integer bits and 8 fractional bits:

  • 0x0000 is zero offset.

  • 0x8000 to 0xFFFF are negative offset and

  • 0x0001 to 0x7FFF are positive offset.

  • e.g. 01.00 (signed '8.8' representation) represents an offset of +1.0, written to the FPGA as 0x0100 (hexidecimal) or 256 (decimal)

GAIN is a 16-bit unsigned fixed-point integer with 4 integer bits and 12 fractional bits:

  • 0x1000 is unity gain,

  • Can be set from 0x0000 to 0xFFFF (0.0 to 15.999).

  • e.g. 3.02A (unsigned '4.12' representation) represents a gain factor of 3.0103, written to the FPGA as 0x302A (hexidecimal) or 12330 (decimal)

The selected GAIN & OFFSET will persist in the FPGA until new values are selected, or the DAQ board is power-cycled. GAIN & OFFSET can be configured to persist as the DAQ’s power-on default using the FPGA Configuration Script functionality.

SetFPGARegister(23,55296);//set register 23 to the desired OFFSET value, 55296 is an example here
SetFPGARegister(24,28672);//set register 24 to the desired GAIN value, 28672 is an example here

Saving FPGA Register Power-On Defaults

Power-on default register values can be set via a script stored in non-volatile memory on the DAQ board. The FPGA Configuration Script is a list of simple “register-number / register-value” pairs written automatically in a consecutive fashion during initialization of the board. Single register controls such as the default Channel Selection (Reg 20), GAIN (Reg 24), or OFFSET (Reg 23) each occupy one line in the FGPA Configuration Script. Arrays such as a default Windowing LUT (Reg 25), which are loaded as multiple consecutive writes to the same register, are loaded via multiple consecutive lines in the FPGA Configuration Script.

Do NOT change the default values of any register for which you are not instructed here or by Axsun Technical Support!

OCT Host
Hardware Control Tool
AxsunOCTControl API

Refer to this section for more information

  1. Go to “Board Settings & Defaults” tab.

  2. Press READ from board to read the current defaults from the board into the FPGA Power-On Config Script Workspace. Register numbers are listed in the left column and their associated default values are listed in the right column (in hexadecimal representation).

  3. Manipulate the register-number / register-value combinations as needed in the Workspace

    (right-click to Insert or Delete array Elements as needed).

  4. Press WRITE to board… to write the modified configuration script in the Workspace to the board’s non-volatile memory. This process will take several seconds, during which the Workspace indicator will be greyed-out.

  1. DAQ: Call RequestFPGAConfig(…) to read the current FPGA default configuration script.

  2. Manipulate the array of registernumber / register-value combinations as needed within your program.

  3. DAQ: Call SendFPGAConfig(…) to write the modified configuration script to the board’s non-volatile memory.

Writing the modified configuration script to non-volatile memory will not immediately update the value of any FPGA registers. This script is applied only at power-on initialization and thus requires a DAQ board restart to change actual FPGA register values to those in the current configuration script.

Read back the configuration script from the DAQ to insure the desired modifications were written successfully. To further validate the modified power-on defaults, restart the DAQ hardware from the power-off state and confirm the register values match those configured in the modified default configuration script.

Dispersion Compensation

Dispersion (spectrally-dependent phase delay) is compensated using a complex valued apodization window function such that a phase correction can be applied across sampled spectral data. The Hardware Control Tool generates a Windowing LUT for apodization and dispersion compensation based on a Taylor series polynomial expansion, for which the user can adjust the coefficients in the square and cubic terms as necessary. The process of loading an arbitrary complex valued Windowing LUT via the API is similar to that described above for a real-valued window function, with the loading of an additional 2048 points (the imaginary components of the LUT) for a total of 4096 points.

Hardware Control Tool
AxsunOCTControl API
  1. Configure the desired channel for which to load a Windowing LUT as described above.

  2. On the “Windowing & Dispersion Compensation” tab, select a window Type, enter the window Width (= Nsamp from laser test report), enter a square term coefficient (a2) and cubic term coefficient (a3), and press UPDATE DAQ.

If Auto Update is ON, changes to the type, width, or coefficients will be sent automatically and the UPDATE DAQ button press is thus not required.

You can observe the effects on the image if you are watching the live image display while loading a new Windowing LUT.

  1. Select the desired channel per instructions above

  • PC: Create two 1D arrays each as described previously, one with the REAL parts and one with the IMAGINARY parts of the desired complex valued Windowing LUT.

  • DAQ:

    1. Use WriteDAQRegisterBit(20,14,0) to clear Register 20 bit 14

    2. Send the 2048-element 1D array of REAL components to Register 25 using SendFPGAData(…) or perform 2048 consecutive writes to Register 25 with SetFPGARegister(25,…) and the written value in each iteration equal to the next element in the window function array.

    3. Use WriteDAQRegisterBit(20,14,1) to set Register 20 bit 14

    4. Send the 2048-element 1D array of IMAGINARY components to Register 25 using SendFPGAData(…) or perform 2048 consecutive writes to Register 25 with SetFPGARegister(25,…) and the written value in each iteration equal to the next element in the window function array.

The loaded Windowing LUT will persist in the FPGA until overwritten with a new Windowing LUT, or the DAQ board is power cycled. A Windowing LUT can be configured to persist as the DAQ’s power-on default using the FPGA Configuration Script functionality.

Saving a Default Windowing LUT

Hardware Control Tool
AxsunOCTControl API

The Hardware Control Tool provides simple updating of the Windowing LUT in the FPGA Configuration Script. This avoids the need to manually copy & paste rows of register values via a spreadsheet editor in order to configure the power-on default Windowing LUT.

  1. Under “Windowing & Dispersion Compensation” tab, configure the desired Windowing LUT (including Dispersion Compensation coefficients) and send them to the DAQ.

  2. Switch to the “Board Settings & Defaults” tab and press READ from board to read the current FPGA default configuration script into the Workspace.

  3. OPTIONAL: To view the Windowing LUT currently in the Workspace, press PLOT Workspace

  4. Press CLEAR Workspace and then SET New Window. This removes any existing Windowing LUT from the Workspace and copies a new Windowing LUT from the parameters currently configured on the “Windowing & Dispersion Compensation” tab.

  5. Press WRITE to board… to write the modified Workspace (including the new Windowing LUT) to the DAQ board’s non-volatile memory.

  6. OPTIONAL: Restart the DAQ hardware from the power-off state and confirm the new Windowing LUT was loaded.

Raw Data / Bypass Modes and A-line Subsampling

Transmission of raw (unprocessed) ADC data or processed data from intermediate locations in the image processing pipeline is achieved by configuring the FPGA to “bypass” all downstream pipeline blocks between the desired location of data access and the Ethernet or PCIe transmission interface. Available locations for raw or intermediate data access are shown in the below figure as numbered green points.

Image processing blocks implemented in the FPGA processing pipeline with available raw or intermediate data access locations indicated by numbered green points.

To maintain the transmitted data bandwidth within the practical limits of the Gigabit Ethernet interface (100 MB/sec), the effective A-line rate of the system may need to be reduced below its native rate. This is achieved by discarding A-lines according to a programmable Subsampling Factor (M), a positive integer indicating the desired bandwidth reduction factor. M = 1 is the native system A-line rate, M = 2 reduces the bandwidth by 2x, M = 10 reduces it by 10x, and so on. When connected via the Ethernet interface, the Networking tab of the Windows Task Manager or Resource Monitor (or Linux equivalent) is a useful tool to view the effects of the Subsampling Factor as shown in the below figure. Subsampling is not needed when using the PCIe interface (Gen 1, x8 = 2 GB/sec).

Networking tab of Windows Task Manager showing the bandwidth utilization as the Subsampling Factor was changed from M = 2 to M = 1 (doubling the network bandwidth from ≈400Mbps to ≈800Mbps on Local Area Connection 3).
Hardware Control Tool
AxsunOCTControl API
  1. Under “Pipeline Modes & Subsampling” tab, choose a subsampling approach (manually or automatically) from the menu. If using Set Manually, enter the desired subsampling factor and press SET.

  2. Select a Bypass Mode for the desired channel by pressing the appropriate block diagram button.

  3. Once a Bypass Mode is selected, the AxsunOCTCapture.dll library and the Image Capture Tool will automatically adapt to the transmitted data type (U8, U16, U32, or Complex). OCT images which span the reconfiguration of a Bypass Mode will be discarded by the driver; each image must have a consistent data type for all member A-scans.

  1. The Subsampling Factor is configured by writing a value of M – 1 (M minus one) to FPGA Register 60 using SetFPGARegister(60,M – 1)

  2. Once an appropriate Subsampling Factor (Register 60) and ADC Channel (Register 20) is configured, selecting the desired Bypass Mode is achieved by two consecutive writes to Register 61 according to the values in below table using SetFPGARegister(61,value1) SetFPGARegister(61,value2)

  3. Once a Bypass Mode is selected, the AxsunOCTCapture.dll library and the Image Capture Tool will automatically adapt to the transmitted data type (U8, U16, U32, or Complex). OCT images which span the reconfiguration of a Bypass Mode will be discarded by the driver; each image must have a consistent data type for all member A-scans.

The selected Bypass Mode and Subsampling Factor will not persist if the DAQ board is power cycled. A Bypass Mode and Subsampling Factor can be configured to persist as the DAQ’s power-on default using the FPGA Configuration Script functionality.

For each Bypass Mode, the transmitted data type and range, A-line vector length, required native data bandwidth, and associated minimum Subsampling Factor are also shown for a system with 100 kHz A-line rate.

Background Subtraction

Configuring the real-time background subtraction functionality on the DAQ is accomplished in two primary parts: 1) Capturing a background signature and 2) Loading a captured signature onto the FPGA for subsequent subtraction from streamed image data. The individual steps described below are for connections using the Ethernet interface and can be achieved by either pressing buttons in the Image Capture Tool and Hardware Control Tool GUI applications, or by integrating the AxsunOCTControl and AxsunOCTCapture API methods into your own application. Equivalent methods for the PCIe interface can be substituted where applicable. Prior to executing the instructions below, launch the Image Capture Tool and the Hardware Control Tool applications and insure that they are effectively communicating with the DAQ & laser hardware and able to capture streamed images.

GUI Tools
AxsunOCTControl API
  1. To capture a background image, follow the steps below:

    1. Turn Live Imaging ON by pressing LASER: ON in the Hardware Control Tool and press either EDAQ: LIVE in the Hardware Control Tool (for Ethernet connection) or DAQ: LIVE in the Image Capture Tool (for PCIe connection).

    2. Stop the sample arm scanning (galvos, catheter rotation, etc) so that no Image_sync trigger is generated for the DAQ. The driver will transition to force trigger mode and display asynchronous frames, each with 256 A-scans/frame.

    3. Block the sample arm optical path or remove objects from the sample beam which are not part of the background you intend to subtract. The frames displayed should consist only of the background and there should be no motion in the frames as a result of scanner motion.

    4. Set the A-line Subsampling approach to Automatic (Aggressive) on the “Pipeline Modes & Subsampling” tab on the Hardware Control Tool.

    5. Depending on which channel configuration you are using, select the Square Root & Bkg Subtract Bypass Mode on the “Pipeline Modes and Subsampling” tab on the Hardware Control Tool.

    6. If a background subtraction signature has been previously uploaded, clear it by pressing DISABLE on the “Background Subtraction” tab in the Hardware Control Tool.

    7. Turn live imaging OFF by pressing either EDAQ: OFF in the Hardware Control Tool (for Ethernet connection) or DAQ: OFF in the Image Capture Tool (for PCIe connection)

    8. A single frame containing the background will be paused on the image display in the Image Capture Tool (16-bit tab). Save it to a .csv file by pressing Save Bkgnd (.csv) button next to the image display and using the Windows dialog to name the file and save in the directory of your choice.

    9. Reconfigure the DAQ to the desired downstream Bypass Mode used for normal imaging operation.

    10. Restart the sample scanner and its frame sync trigger, and turn Live Imaging back ON in a similar fashion as described above.

  2. To load a background signature to the DAQ FPGA, follow the steps below:

    1. Press LOAD FROM FILE… on the “Background Subtraction” tab in the Hardware Control Tool.

    2. Navigate to the directory of the desired background signature file (saved in the previous section) and open it. This will load the background signature from the file and send it to the FPGA for application to all subsequent A-scans. (You will see the background subtraction become enabled if you are watching the live image display after selecting the file to open).

  1. Follow the code below and use either the EDAQ or the PCIeDAQ code lines:

StartScan(); // to turn ON laser emission
WriteDAQRegisterBit(19,15,1); // for EDAQ only
WriteDAQRegisterBit(2,2,1); // for EDAQ only
axImagingCntrlPCIe(-1); // for PCIeDAQ only
axStartSession(…); // to start the main capture thread

2. Perform live capture and display with axRequestImage(…) called in a programmatic loop

3. Stop the sample arm scanning (galvos, catheter rotation, etc) so that no Image_sync trigger is generated for the DAQ. The driver will transition to force trigger mode and display asynchronous frames, each with 256 A-scans/frame.

4. Block the sample arm optical path or remove objects from the sample beam which are not part of the background you intend to subtract. The frames displayed should consist only of the background and there should be no motion in the frames as a result of scanner motion.

5. Follow the code below and use either the EDAQ or the PCIeDAQ code lines:

SetFGPARegister(60,9); // for DAQ: to set Register 60 to 0x009
SetFPGARegister(61,28); // for DAQ: to set Register 61 to 0x001C
SetFPGARegister(61,29); // for DAQ: to set Register 61 to 0x001D
SendFPGAData(...); // to send to Register 37 a 1024- element array of U16 type with all elements = 0
WriteDAQRegisterBit(2,2,0); // for EDAQ only: to clear Register 2 bit 2
WriteDAQRegisterBit(19,15,0); // for EDAQ only: to clear Register 19 bit 15
axImagingCntrlPCIe(0); // for PCIeDAQ only

6. PC: for the last frame retrieved by the axRequestImage(…) function, calculate the mean across all 256 A-lines and store the result as a 1024-element array of U16 data type for use in a later step

7. Follow the code below and use either the EDAQ or the PCIeDAQ code lines:

SetFPGARegister(61, 0); // for DAQ
SetFPGARegister(61,1);// for DAQ
SetFPGARegister(60,0);// for DAQ
WriteDAQRegisterBit(19,15,1); // for EDAQ only
WriteDAQRegisterBit(2,2,1); // for EDAQ only
axImagingCntrlPCIe(-1); // for PCIe DAQ only

8. DAQ: send the background signature to Register 37 as a 1024-element array of U16 type using SendFPGAData(…)

The loaded background signature will persist in the FPGA until explicitly cleared (see above), or overwritten with a new loaded background signature, or the DAQ board is power cycled. A background signature can be configured to persist as the DAQ’s power-on default using the FPGA Configuration Script functionality.

Using the Application Programming Interfaces (APIs)

Software developers have access to the Axsun libraries (AxsunOCTCapture.dll, AxsunOCTControl_LW.dll, and AxsunOCTControl.dll) for integration into custom client applications. Library binaries, documentation, and example source code projects in LabVIEW and C/C++ are available for download.