ATS-SDK Software Manual



Similar documents
AlazarTech SDK Programmer s Guide. Version May 28, 2010

AlazarTech SDK Programmer s Guide. Version June 16, 2011

Application Note. Introduction AN2471/D 3/2003. PC Master Software Communication Protocol Specification

Illustration 1: Diagram of program function and data flow

Programming Interface. for. Bus Master IDE Controller. Revision 1.0

Programing the Microprocessor in C Microprocessor System Design and Interfacing ECE 362

RS-485 Protocol Manual

Last Class: OS and Computer Architecture. Last Class: OS and Computer Architecture

Using NSM for Event Notification. Abstract. with DM3, R4, and Win32 Devices

Have both hardware and software. Want to hide the details from the programmer (user).

Software Development to Control the Scorbot ER VII Robot With a PC

Gigabit Ethernet Packet Capture. User s Guide

Computer Systems Structure Input/Output

Embedded Programming in C/C++: Lesson-1: Programming Elements and Programming in C

AN1754 APPLICATION NOTE

1. Computer System Structure and Components

Beam Loss Monitor Software Guide

Linux Driver Devices. Why, When, Which, How?

APPLICATION NOTE GaGe CompuScope based Lightning Monitoring System

AN141 SMBUS COMMUNICATION FOR SMALL FORM FACTOR DEVICE FAMILIES. 1. Introduction. 2. Overview of the SMBus Specification. 2.1.

SRF08 Ultra sonic range finder Technical Specification

BillQuick Agent 2010 Getting Started Guide

White Paper. Real-time Capabilities for Linux SGI REACT Real-Time for Linux

Communication Protocol

Serial Communications

SMTP-32 Library. Simple Mail Transfer Protocol Dynamic Link Library for Microsoft Windows. Version 5.2

Freescale Semiconductor, I

Informatica e Sistemi in Tempo Reale

Computer Organization & Architecture Lecture #19

Virtuozzo Virtualization SDK

PicoScope 5000 Series (A API)

Getting Started with IntelleView POS Administrator Software

UniFinger Engine SDK Manual (sample) Version 3.0.0

Modbus and ION Technology

(Cat. No SI) Product Data

Eight Ways to Increase GPIB System Performance

CANnes PC CAN Interface Manual

Compute Cluster Server Lab 3: Debugging the parallel MPI programs in Microsoft Visual Studio 2005

Device Management API for Windows* and Linux* Operating Systems

Embedded Software Development

An Introduction To Simple Scheduling (Primarily targeted at Arduino Platform)

Channel Access Client Programming. Andrew Johnson Computer Scientist, AES-SSG

Introduction to Operating Systems. Perspective of the Computer. System Software. Indiana University Chen Yu

SUDT AccessPort TM Advanced Terminal / Monitor / Debugger Version 1.37 User Manual

RecoveryVault Express Client User Manual

Introduction. What is an Operating System?

EPM2000 LabVIEW Building Applications Instructions

Q N X S O F T W A R E D E V E L O P M E N T P L A T F O R M v Steps to Developing a QNX Program Quickstart Guide

Chapter 11 I/O Management and Disk Scheduling

E-Blocks Easy RFID Bundle

Chapter 5 Real time clock by John Leung

Leak Check Version 2.1 for Linux TM

Accurate Measurement of the Mains Electricity Frequency

Using the CoreSight ITM for debug and testing in RTX applications

Online Backup Client User Manual

XMOS Programming Guide

Keil C51 Cross Compiler

Global Monitoring + Support

Eureka Technology. Understanding SD, SDIO and MMC Interface. by Eureka Technology Inc. May 26th, Copyright (C) All Rights Reserved

Getting Started Guide

An Introduction to MPLAB Integrated Development Environment

Parallelization: Binary Tree Traversal

Expedite for Windows Software Development Kit Programming Guide

MetroPro Remote Access OMP-0476F. Zygo Corporation Laurel Brook Road P.O. Box 448 Middlefield, Connecticut 06455

Trigger-to-Image Reliability (T2IR)

Last Class: OS and Computer Architecture. Last Class: OS and Computer Architecture

Caml Virtual Machine File & data formats Document version: 1.4

Device Management API for Windows* and Linux* Operating Systems

AKD EtherNet/IP Communication

APPLICATION PROGRAMMING INTERFACE

Mutual Exclusion using Monitors

MeshBee Open Source ZigBee RF Module CookBook

Copley Camming User Guide

Best Practises for LabVIEW FPGA Design Flow. uk.ni.com ireland.ni.com

Online Backup Linux Client User Manual

ebus Player Quick Start Guide

ARM Thumb Microcontrollers. Application Note. Software ISO 7816 I/O Line Implementation. Features. Introduction

1. Product Information

How to design and implement firmware for embedded systems

EcgSoft. Software Developer s Guide to RestEcg. Innovative ECG Software info@ecg-soft.com

CSC 2405: Computer Systems II

Online Backup Client User Manual Linux

MODULE BOUSSOLE ÉLECTRONIQUE CMPS03 Référence :

Sensors and the Zaurus S Hardware

Process Control and Automation using Modbus Protocol

Online Backup Client User Manual

SYSTEM REQUIREMENTS...

GlobalSCAPE DMZ Gateway, v1. User Guide

EXTENDED FILE SYSTEM FOR FMD AND NANO-10 PLC

Overview. Lecture 1: an introduction to CUDA. Hardware view. Hardware view. hardware view software view CUDA programming

KofaxExpress. Installation Guide

µtasker Document FTP Client

eztcp Technical Document Modbus/TCP of eztcp Caution: Specifications of this document may be changed without prior notice for improvement.

Fast Arithmetic Coding (FastAC) Implementations

EPICS VME Crate Monitor Software Design Note Rev. 0 Date:

Operating System Manual. Realtime Communication System for netx. Kernel API Function Reference.

AQA GCSE in Computer Science Computer Science Microsoft IT Academy Mapping

GEVPlayer. Quick Start Guide

How To Write A Profibus Dpl (Profibus) Program

ASSEMBLY PROGRAMMING ON A VIRTUAL COMPUTER

Transcription:

ATS-SDK Software Manual Supports C/C++ & Visual BASIC Also Applicable to ATS-Linux Version: 5.6.0 June, 2008

Copyright 2003-2008 AlazarTech, Inc. All rights reserved. AlazarTech Contact Information AlazarTech, Inc. 3551 St-Charles, Unit 640 Kirkland, Quebec Canada H9H 3C4 Telephone: (514) 633-0001 Fax: (514) 633-0021 E-mail: info@alazartech.com Web site: www.alazartech.com www.pci-digitizers.com To comment on the documentation for ATS-SDK, send e-mail to support@alazartech.com. Information required when contacting AlazarTech for technical support: Owned by: Serial Number: Purchase Date: Purchased From: Software Driver Version: SDK Version: AlazarDSO Version: Operating System: Compiler Type: Compiler Version:

Table of Contents Introduction...3 Installing ATS-SDK...4 Understanding How to Program Using ATS-SDK...5 Data Size Returned by ATS Digitizers...7 Data Structures Used by ATS-SDK...12 API Groups...18 Reviewing A Traditional C Sample Program...26 Reviewing SynchronousAutoDMA C Sample Programs...32 Reviewing An AsyncDMA C Sample Program...41 Reviewing An AsyncDMA VB Sample Program...50 Reviewing A Traditional VB Sample Program...60 Traditional API Description...63 AlazarAbortCapture...64 AlazarAutoCalibrate...65 AlazarBoardsFound...66 AlazarBoardsInSystemByHandle...67 AlazarBoardsInSystemBySystemID...68 AlazarBusy...69 AlazarClose...70 AlazarForceTrigger...71 AlazarGetBoardBySystemHandle...72 AlazarGetBoardBySystemID...73 AlazarGetBoardKind...74 AlazarGetChannelInfo...75 AlazarGetCPLDVersion...76 AlazarGetDriverVersion...77 AlazarGetMaxRecordsCapable...78 AlazarGetParameter...79 AlazarGetParameterUL (for future use)...81 AlazarGetSDKVersion...82 AlazarGetStatus...83 AlazarGetSystemHandle...84 AlazarGetTriggerAddress...85 AlazarGetWhoTriggeredBySystemHandle...86 AlazarGetWhoTriggeredBySystemID...87 AlazarHyperDisp...88 AlazarInputControl...90 AlazarNumOfSystems...92 AlazarOEMDownLoadFPGA...93 AlazarOpen...94 AlazarParseFPGAName...95 AlazarQueryCapability...96 AlazarRead...99 AlazarResetTimeStamp... 100 AlazarSetBWLimit... 101 AlazarSetCaptureClock... 102 AlazarSetExternalTrigger... 105 AlazarSetLED... 106 AlazarSetParameter... 107 ATS-SDK Software Manual v5.6.0 1

AlazarSetParamaterUL (for future use)... 108 AlazarSetRecordCount... 109 AlazarSetRecordSize... 111 AlazarSetTriggerDelay... 114 AlazarSetTriggerOperation... 115 AlazarSetTriggerTimeOut... 117 AlazarSleepDevice... 118 AlazarStartCapture... 119 AlazarTriggered... 120 Asynchronous DMA API Description... 121 Asynchronous Dma Operating Modes & Data Organization... 122 Traditional Asynchronous DMA... 123 Continuous Asynchronous DMA... 126 Triggered Continuous Streaming Asynchronous DMA... 129 No-PreTrigger Asynchronous DMA... 130 AlazarAbortAsyncRead... 136 AlazarAsyncRead... 137 AlazarBeforeAsyncRead... 140 AlazarPostAsyncBuffer... 144 AlazarWaitAsyncBufferComplete... 146 AlazarWaitNextAsyncBufferComplete... 148 Synchronous AutoDMA API Description... 150 Synchronous AutoDma Operating Modes & Data Organization... 151 Traditional Synchronous AutoDMA... 151 Continuous Streaming Synchronous AutoDMA... 154 Triggered Continuous Streaming Synchronous AutoDMA... 155 No-PreTrigger Synchronous AutoDMA... 156 AlazarAbortAutoDma... 159 AlazarCloseAUTODma... 161 AlazarEvents... 162 AlazarFlushAutoDMA... 163 AlazarGetAutoDMAHeaderTimeStamp... 164 AlazarGetAutoDMAHeaderValue... 166 AlazarGetAutoDMAPtr... 168 AlazarGetNextAutoDMABuffer / AlazarGetNextBuffer... 170 AlazarStartAutoDMA... 173 AlazarStopAutoDMA... 176 AlazarWaitForBufferReady... 177 API Return Code Values... 179 2 ATS-SDK Software Manual v5.6.0

Introduction This manual is designed to explain the Application Programming Interface (API) that must be used to integrate ATS class digitizers in a C/C++ or Visual BASIC application for 32-bit and 64-bit Windows. While this manual has not specifically been written for Linux, Linux programmers can still use it as a reference manual for AlazarTech API calls, which are common between Windows and Linux. It is assumed that the reader is familiar with the C/C++ or Visual BASIC programming language and the application development environment. It is further assumed that the reader is fully familiar with the concepts of data acquisition and sampling theorem. ATS-SDK Software Manual v5.6.0 3

Installing ATS-SDK Install from CD ATS-SDK is shipped with an installation CD that will copy all the necessary files to your hard disk. Note that this CD has the auto-run feature enabled, so all you should have to do is insert the disk into your CD drive. In case the installation does not start automatically, use Explorer to navigate to the CD and run the ATS-SDK_V*_Setup.exe program on the CD, where * is the version number. For example, for version 5.6.0, the file name will be ATS-SDK_V5_6_0_Setup.exe. Follow the instructions on the screen. By default, all files will be installed to C:\AlazarTech\ATS- SDK\5.6.0 folder. Future versions of the SDK will be installed in their own sub-folder within the ATS-SDK folder. Install from Download You can also install ATS-SDK by downloading the installation file from AlazarTech web site. The installation file you download from AlazarTech web will be Zipped. You need WinZip or equivalent utility as well as a password from AlazarTech to uncompress this file. Note that WinRar cannot properly extract a password protected Zip file created by WinZip and should not be used. The uncompressed file will be called ATS-SDK_V*_Setup.exe, where * refers to the version number of the ATS-SDK release. For example, for version 5.6.0, the file name will be ATS- SDK_V5_6_0_Setup.exe. Simply run this uncompressed file and follow the instructions on the screen. By default, all files will be installed to C:\AlazarTech\ATS- SDK\5.6.0 folder. Future versions of the SDK will be installed in their own sub-folder within the ATS-SDK folder. 4 ATS-SDK Software Manual v5.6.0

Understanding How to Program Using ATS-SDK ATS class digitizers, such as the ATS9462, ATS860, ATS660, ATS460, ATS330, ATS310 and ATS850, are designed for ease of integration into user programs. As such, the ATS-SDK features a very simple and easy-to-use API. C Language and C++ For C programmers, all you have to do to access all the capabilities of the ATS-SDK is described below: Make sure the software driver for the digitizer you are programming is properly installed and is working. You can use API Panel software to prove this to yourself. Include AlazarAPI.h file in your project Include AlazarCmd.h file in your project Include AlazarError.h file in your project Include ATSApi.LIB file in your project. Files AlazarAPI.h, AlazarCmd.h and AlazarError.h are installed in the C:\AlazarTech\ATS-SDK\V5_6_0\Include\C\ folder. File ATSApi.lib is installed in two places: C:\AlazarTech\ATS-SDK\ V5_6_0\Include\lib\x86 and C:\AlazarTech\ATS-SDK\ V5_6_0\Include\lib\x64. For Win32 development on a WinXP, Windows Vista 32, Win2k, or Win98SE system the file in \lib\x86 should be used. For WinXP 64 or Windows Vista 64, the file in \lib\x64 should be used when building a 64bit application. If you are creating a 32bit application in a 64bit environment, then you must use the file in \lib\x86. C Sharp For C# programmers, all you have to do to access all the capabilities of the ATS-SDK is described below: ATS-SDK Software Manual v5.6.0 5

Make sure the software driver for the digitizer you are programming is properly installed and is working. You can use API Panel software to prove this to yourself. Include AlazarWrapper.cs file as an existing element in your project. File AlazarWrapper.cs is installed in the C:\AlazarTech\ATS-SDK\ V5_6_0\Include\C sharp\ folder. This file is a Class wrapper that contains all the function imports and constants required for programming the ATS digitizer. It exports the AlazarTech namespace. Visual Basic 6.0 For Visual BASIC programmers, all you have to do to access all the capabilities of the ATS-SDK is described below: Make sure the software driver for the digitizer you are programming is properly installed and is working. You can use API Panel software to prove this to yourself. Include ATSApiVB.BAS file as a module in your project. This file contains all the function prototypes and constants required for programming the ATS digitizer. By default, this file is installed in the C:\AlazarTech\ATS-SDK\ V5_6_0\Include\Visual BASIC\ folder. 6 ATS-SDK Software Manual v5.6.0

Data Size Returned by ATS Digitizers ATS class digitizers feature 8 bit to 16 bit vertical resolution. This section provides the programmer with the data format returned by each of the various digitizers. ATS-SDK Software Manual v5.6.0 7

ATS850 & ATS860 8 Bit Digitizers The ATS850 returns one 8-bit data sample per byte (type U8) In other words, there are four (4) samples per 32-bit dword. Bit 7 Bit 6 Bit 5 Bit 4 Bit 3 Bit 2 Bit 1 Bit 0 D7 D6 D5 D4 D3 D2 D1 D0 8 ATS-SDK Software Manual v5.6.0

ATS310 & ATS330 12 Bit Digitizers ATS310 and ATS330 return one 12-bit sample per 16-bit word (type U16). In other words, there are two (2) samples per 32-bit dword. It should be noted that the returned data is MSB-justified, i.e. the least significant four (4) bits of the data are zero, as show below: Bit 15 Bit 14 Bit 13 Bit 12 Bit 11 Bit 10 Bit 9 Bit 8 Bit 7 Bit 6 Bit 5 Bit 4 Bit 3 Bit 2 Bit 1 Bit 0 D11 D10 D9 D8 D7 D6 D5 D4 D3 D2 D1 D0 0 0 0 0 A corollary of this is that return values range from 0 (negative-most value) to 65,535 (positive-most value) with a resolution of 16 LSBs. ATS-SDK Software Manual v5.6.0 9

ATS460 14 Bit Digitizer The ATS460 returns one 14-bit sample per 16-bit word (type U16). In other words, there are two (2) samples per 32-bit dword. It should be noted that the returned data is MSB-justified, i.e. the least significant two (2) bits of the data are zero, as show below: Bit 15 Bit 14 Bit 13 Bit 12 Bit 11 Bit 10 Bit 9 Bit 8 Bit 7 Bit 6 Bit 5 Bit 4 Bit 3 Bit 2 Bit 1 Bit 0 D13 D12 D11 D10 D9 D8 D7 D6 D5 D4 D3 D2 D1 D0 0 0 A corollary of this is that return values range from 0 (negative-most value) to 65,535 (positive-most value) with a resolution of 4 LSBs. Note: If the signal input is such that the digitizer input becomes saturated, then bit 0 will be set to 1, i.e. bit 0 of the input contains the Overflow bit from the ATS460 ADC. 10 ATS-SDK Software Manual v5.6.0

ATS660 & ATS9462 16 Bit Digitizers ATS660 and ATS9462 return one 16-bit sample per 16-bit word (type U16). In other words, there are two (2) samples per 32-bit dword. Each 16-bit sample is packed into a 16 bit unsigned word as show below: Bit 15 Bit 14 Bit 13 Bit 12 Bit 11 Bit 10 Bit 9 Bit 8 Bit 7 Bit 6 Bit 5 Bit 4 Bit 3 Bit 2 Bit 1 Bit 0 D15 D14 D13 D12 D11 D10 D9 D8 D7 D6 D5 D4 D3 D2 D1 D0 A corollary of this is that return values range from 0 (negative-most value) to 65,535 (positive-most value) with a resolution of 1 LSBs. ATS-SDK Software Manual v5.6.0 11

Data Structures Used by ATS-SDK ATS-SDK uses a few data structures that you should be aware of. Proper understanding of these data structures will make it even simpler for you to use the ATS-SDK and help you finish faster. Board Structure The first data structure we should review is the board structure. This structure defines all the controls and features of the digitizer board being used. The following is the actual declaration of board: typedef struct _BoardDef { U32 RecordCount; U32 RecLength; U32 PreDepth; U32 ClockSource; U32 ClockEdge; U32 SampleRate; U32 CouplingChanA; U32 InputRangeChanA; U32 InputImpedChanA; U32 CouplingChanB; U32 InputRangeChanB; U32 InputImpedChanB; U32 TriEngOperation; U32 TriggerEngine1; U32 TrigEngSource1; U32 TrigEngSlope1; U32 TrigEngLevel1; U32 TriggerEngine2; U32 TrigEngSource2; U32 TrigEngSlope2; U32 TrigEngLevel2; }BoardDef, *pboarddef; Note that AlazarTech reserves the right to add fields to this structure without prior notice. 12 ATS-SDK Software Manual v5.6.0

AutoDMA Header Structure If UseHeader parameter for AlazarStartAutoDMA call is set to 1 (or any other non-zero value), AutoDMA buffers will have a 16-byte header that contains the record number, timestamp value and other acquisition parameters. The Header can only be used in the Traditional AutoDMA mode. That is, AutoDMA with PreTrigger data. It can not be used when either Continuous AutoDMA, Triggered Streaming AutoDMA or Non-PreTrigger AutoDMA (also known as NPT mode) is used. The following figure shows what is the record format: UseHeader = 0 Array of TransferLength sample values (U16 or U8) UseHeader = 1 16 byte Header Array of TransferLength sample values (U16 or U8) The 16-byte header is divided up into four (4) 32 bit dwords or U32. Using The Header: A user may or may not choose to use the header. Whether or not to use the header is a design choice that the software engineer needs to make at the inception of the program. To enable the header, the UseHeader parameter in API function AlazarStartAutoDMA must be set to 1. Care must be taken such that the record buffers that are allocated need to be 4 DWORDs (16 bytes) larger than the programmed RecordLength. Provided that UseHeader is set, each time a call to Api function AlazarGetNextAutoDMABuffer returns a buffer, the first 4 DWORDs of each record in the buffer will contain the header. Header Description: The header is defined as 4 DWORDs (16 bytes) that precede each AutoDMA record captured. Data Structure, ALAZAR_HEADER, is made of 4 sub-structures, one for each DWORD. The structures are defined as follows: ATS-SDK Software Manual v5.6.0 13

struct _HEADER0 { unsigned int SerialNumber:18; // bits 17..0 unsigned int SystemNumber:4; // bits 21..18 unsigned int WhichChannel:1; // bit 22 unsigned int BoardNumber:4; // bits 26..23 unsigned int SampleResolution:3; // bits 29..27 unsigned int DataFormat:2; // bits 31..30 }; struct _HEADER1 { unsigned int RecordNumber:24; // bits 23..0 unsigned int BoardType:8; // bits 31..24 }; struct _HEADER2 { U32 TimeStampLowPart; //bits 31..0 }; struct _HEADER3 { unsigned int TimeStampHighPart:8; // bits 7..0 unsigned int ClockSource:2; // bits 9..8 unsigned int ClockEdge:1; // bit 10 unsigned int SampleRate:7; // bits 17..11 unsigned int InputRange:5; // bits 22..18 unsigned int InputCoupling:2; // bits 24..23 unsigned int InputImpedence:2; // bits 26..25 unsigned int ExternalTriggered:1; // bit 27 unsigned int ChannelBTriggered:1; // bit 28 unsigned int ChannelATriggered:1; // bit 29 unsigned int TimeOutOccurred:1; // bit 30 unsigned int ThisChannelTriggered:1; // bit 31 }; typedef struct _ALAZAR_HEADER { struct _HEADER0 hdr0; struct _HEADER1 hdr1; struct _HEADER2 hdr2; struct _HEADER3 hdr3; } ALAZAR_HEADER, *PALAZAR_HEADER; The sub-structures that make up ALAZAR_HEADER, depict various Board specific, and acquisition specific parameters. The Board specific parameters define both, how the board is configured into the system and details about the board itself. Board specific parameters include the board serial number, board type, system number, board number, data format, and sample resolution. The Data format must be interpreted as follows: 00 = Straight Binary, 01 = Twos complement, 10 = Signed Binary, and 11 = Gray Code The Acquisition specific parameters define the configuration variables that were used to setup the board as well as dynamic information of 14 ATS-SDK Software Manual v5.6.0

how a particular record was captured. For example, suppose we configured the board with a sample rate of 125MHz, using an internal clock and a positive edge clocking scheme. When we query the header (i.e. the header information of a particular record), the constants in AlazarCmd.h may be used to test against. For the previous example, a user would test p.samplerate with SAMPLE_RATE_125MSPS, p.clockedge with CLOCK_EDGE_RISING and p.clocksource with INTERNAL_CLOCK. The same can be said for InputRange, InputCoupling, and InputImpedence. Of course, p must be defined as type ALAZAR_HEADER. While the board is performing the AutoDMA acquisition, it populates portions of the header dynamically. The dynamic variables include, TimeStampHighPart, TimeStampLowPart, ExternalTriggered, ChannelBTriggered, ChannelATriggered, TimeOutOccurred, ThischannelTriggered and WhichChannel. A description of the dynamic variables follows: WhichChannel - signifies the channel for the current record. (0 is used for Channel A and 1 is used for Channel B) TimeStampHighPart, TimeStampLowPart - A 40 bit time stamp for the record (described later) ExternalTriggered - The data for this record resulted from an External trigger. (0 is used for False and 1 is used for True) ChannelBTriggered - The data for this record resulted from Channel B triggering. (0 is used for False and 1 is used for True) ChannelATriggered - The data for this record resulted from Channel A triggering. (0 is used for False and 1 is used for True) TimeOutOccurred - A trigger timeout occurred. (0 is used for False and 1 is used for True) ThischannelTriggered - The data for this record resulted from WhichChannel. If ThisChannelTriggered is 0, then the channel described by WhichChannel did not trigger the system. If ThisChannelTriggered is 1 then the channel described by WhichChannel did trigger the system. ATS-SDK Software Manual v5.6.0 15

AutoDMA Header Specific Api Functions: For ease of use, a set of Api Functions have been developed so that a user can easily access any parts of the header. By setting the Parameter variable in AlazarGetAutoDMAHeaderValue a user can retrieve any part of the header information. For example if Parameter is set to ADMA_SAMPLERATE as per the previous example. The function will return SAMPLE_RATE 125MSPS. Note: WhichChannel, ExternalTriggered, ChannelBTriggered, ChannelATriggered, TimeOutOccurred, and ThischannelTriggered are treated as boolean values and can only be tested against True (1) or False (0). 16 ATS-SDK Software Manual v5.6.0

Here is a list of the Parameter values that can be used: // ******************************************************************** // Header Constants and Structures that need to be used // when dealing with ADMA captures that use the header. // ******************************************************************** #define ADMA_CLOCKSOURCE 0x00000001 #define ADMA_CLOCKEDGE 0x00000002 #define ADMA_SAMPLERATE 0x00000003 #define ADMA_INPUTRANGE 0x00000004 #define ADMA_INPUTCOUPLING 0x00000005 #define ADMA_IMPUTIMPEDENCE 0x00000006 #define ADMA_EXTTRIGGERED 0x00000007 #define ADMA_CHA_TRIGGERED 0x00000008 #define ADMA_CHB_TRIGGERED 0x00000009 #define ADMA_TIMEOUT 0x0000000A #define ADMA_THISCHANTRIGGERED 0x0000000B #define ADMA_SERIALNUMBER 0x0000000C #define ADMA_SYSTEMNUMBER 0x0000000D #define ADMA_BOARDNUMBER 0x0000000E #define ADMA_WHICHCHANNEL 0x0000000F #define ADMA_SAMPLERESOLUTION 0x00000010 #define ADMA_DATAFORMAT 0x00000011 AutoDMA Header TimeStamp: The 40 bit TimeStamp defining the sequence in time of a particular record capture can be extracted from the header using the following Api Function: AlazarGetAutoDMAHeaderTimeStamp. The resulting number is composed of both the TimeStampHighPart and TimeStampLowPart thus alleviating the user from calculating the time stamp using the header values. Please refer to the ApiManual for a detailed description AlazarGetAutoDMAHeaderTimeStamp. Accessing The Captured Data: The captured data of a particular record can be accessed by use of a data pointer. For ease of use, api function AlazarGetAutoDMAPtr was created. This ApiFunction can also be used when UseHeader is not selected. When UseHeader is set to 0 in AlazarStartAutoDMA the data pointer calculations ignores the space that the header would have occupied. ATS-SDK Software Manual v5.6.0 17

API Groups AlazarTech API can be divided into the following groups: Initialization and Control API In previous versions of this manual, this API was also referred to as Traditional API Single-port DMA API In previous versions of this manual, this API was included in Traditional API Synchronous DMA (Previously called AutoDMA) This API is used for dual port memory data access using synchronous IO. Not recommended for new designs. Use Asynchronous API instead. Asynchronous DMA API This API is used for dual port memory data access using overlapped IO. This is the highest performance data access methodology. Initialization and Control API Initialization and Control API allows the programmer to initialize AlazarTech hardware, setup acquisition and triggering parameters, start and stop acquisitions and interrogate the hardware. This API group is an essential part of all programs that use AlazarTech boards. As a minimum, API calls from this group must be made to initialize and set up the hardware and start acquisitions before data can be accessed using one of the other API groups. 18 ATS-SDK Software Manual v5.6.0

Single Port DMA API In previous versions of this manual, this API was grouped together with Traditional API. Single Port DMA API is available for all AlazarTech PCI digitizers. This API is equivalent to the API of most other PCI digitizer manufacturers. Single Port DMA API assumes that the on-board acquisition memory is single-ported, i.e. the board must have finished the acquisition before the data is offloaded to the PC Memory. A typical sequence of API calls for Single Port DMA API is: // Issue Start Capture Command AlazarStartCapture( h ); // Wait until acquisition is finished while(alazarbusy(h)); // Read data from one or both channels AlazarRead( h, CHANNEL_A, Data[0], 1, RecordToRead, 0,bd.RecLength); AlazarRead( h, CHANNEL_B, Data[1], 1, RecordToRead, 0,bd.RecLength); The advantage of using Single Port DMA API is that it is very simple to use and fits in very well with linear programming for experiments in which everything happens one after the other. The disadvantage of using Single Port DMA API is that it slows down data acquisition if the measurement involves acquiring many short records at a high trigger repeat rate. Typical examples of such applications are ultrasonic testing, OCT, radar, imaging etc. The Single Port DMA API works with digitizers that have on-board memory. At present, only the ATS850, ATS310, ATS330, ATS860, ATS460 and ATS660 have on-board memory. ATS-SDK Software Manual v5.6.0 19

Synchronous DMA API Not recommended for new designs. Use Asynchronous DMA API. Note that in previous versions of this manual, Synchronous DMA was referred to as AutoDMA. Synchronous DMA API assumes that the waveform digitizer being used has dual-port acquisition memory. If the digitizer does not support dual-port memory, an error will be returned by the AutoDMA API functions. As shown below, the user program consumes data synchronously with the acquisition loop. Hence the name Synchronous DMA. A typical sequence of API calls for Synchronous DMA API is shown below. For readability purposes, the following is pseudo-code. Please refer to the sample programs provided for exact syntax and details of what the various parameters passed to these routines mean: // Set up two AutoDMA buffers and start the DMA engine // Data will be captured in the two buffers in a ping-pong // mode. You will be able to process the first buffer while // data is being captured into the second buffer and // vice-versa AlazarStartAutoDMA(h, UserData[0], UseHeader, mode, -(long)bd.predepth, transferlength, RecsPerBuffer, bd.recordcount, &error, CFlags, in1, &r3, &r4); // Issue Start Capture Command. No data transfer happens before this AlazarStartCapture( h ); 20 ATS-SDK Software Manual v5.6.0

// Wait until all required records have been captured while (looping == 1) { // Check if one of the AutoDMA buffers has been // fully populated or not AlazarGetNextAutoDMABuffer(h, UserData[0], UserData[1], &WhichOne, &RecsTransferred, &error, in1, in1, &TriggersOccurred, &r4); } // If WhichOne is equal to 0 or 1, that particular buffer // has been populated and hardware is DMAing // into the other buffer if ((WhichOne == 0) (WhichOne == 1)) { } // Process Your Data here // Note that while you process data, // new data is still being captured into // on-board dual port memory and transferred into // the other AutoDMA buffer SaveToChannelFiles(UserData[WhichOne]); // Check if all records have been captured if (RecsTransferred == (long)recordcount) { } // If all records have been captured, stop the while loop looping = 0; ATS-SDK Software Manual v5.6.0 21

Asynchronous DMA API There are three types, also referred to as mechanisms of usage for Asynchronous DMA, (AsyncDMA). They are defined as follows: AsyncRead PostBuffer SequentialBuffers The AsyncRead mechanism is the most advanced and required a user to both manage a list (or queue) of buffers and respond to the Overlapped IO structures' requirements and the associated timeouts. In PostBuffer, the user defines the number of buffers to Post to the device driver. The number of buffers and size of each buffer is limited by the amount of memory installed in the PC. As the application executes, data buffers are presented back to the application as the acquisition continues. The user can then re-post the buffers until the acquisition completes. In this mechanism, the user does not have to manage any Overlapped IO structures. In SequentialBuffers, the device driver manages a list of buffers in a circular queue and copies the data to a user-supplied buffer once the data is available. This is the simplest mechanism to use because the user does not need to manage the posting of buffers and Overlapped IO. However, this mechanism can be as considerably slower than the PostBuffer technique. For C-language applications, the recommended mechanism of use is PostBuffer. For simplified applications a user may choose the SequentialBuffers mechanism. Advance users that are familiar with the Overlapped IO paradigm in Windows can use the AsyncRead mechanism. Note that the performance that can be achieved using PostBuffer is virtually the same as with AsyncRead. 22 ATS-SDK Software Manual v5.6.0

For Visual Basic applications, the recommended mechanism of use is PostBuffer. For simplified applications a user may choose the SequentialBuffers mechanism. ATS-SDK Software Manual v5.6.0 23

Overview of AsyncDMA API Functions The AlazarTech API has been updated to add functions that allow asynchronous data transfers from AlazarTech PCI digitizer boards. These new functions allow you to queue several transfer buffers to each board before you start an acquisition. Once the acquisition is started, a board fills the buffers one at a time in the order that they were queued. You can wait asynchronously or poll for the buffers to be filled. The asynchronous API has three layers: AlazarWaitNextAsyncBufferComplete: This is the highest-level asynchronous API layer. It uses an internally allocated and managed list of transfer buffers, and calls lower level functions to transfer data from dual-ported memory to these buffers. When you call this function, it copies data from an internal buffer into a user-supplied buffer, waiting for the buffer to fill if necessary. This function does not require that you allocate or manage an array of transfer buffers, or use overlapped IO functions. AlazarPostAsyncBuffer / AlazarWaitAsyncBufferComplete: These functions allow you to allocate and manage your own transfer buffer lists. They transfer data directly into your buffers, but do not require you to use overlapped IO functions. AlazarAsyncRead: This is the lowest level asynchronous API layer. It transfers data directly into your transfer buffer. However you must allocate and manage your own transfer buffer lists, and use overlapped IO functions These asynchronous API functions offer some advantages over the AlazarStartAutoDMA / AlazarGetNextBuffer API functions: They use less CPU resources since they are interrupt-driven rather than polled. If you post two or more buffers to a board, they minimize the time between the end of one DMA transfer and the start of the next, which results in higher average transfer rates. 24 ATS-SDK Software Manual v5.6.0

The AlazarAsyncRead, AlazarPostAsyncBuffer, and AlazarWaitAsyncBufferComplete functions transfer data directly into your buffers without making any intermediate copies in memory. ATS-SDK Software Manual v5.6.0 25

Reviewing A Traditional C Sample Program Let us review the ACQ2DISK sample program that is supplied with ATS-SDK as an example of Single-Port Memory data access. ACQ2DISK is a C/C++ program that performs the following tasks: 1. Find out how many AlazarTech boards are there in the computer and if they are configured as a Master/Slave system. If no boards are found, exit gracefully. 2. For each one of the boards in the first system: a. ATS driver will return a unique handle for each board, thereby making it simple to use multiple boards. i. If no boards are found, do nothing. ii. If boards are found, allocate a buffer large enough to hold the acquired data. This is the buffer that ATS- SDK will DMA into. Note that this buffer MUST be larger than the amount to be transferred by at least 16 samples, i.e. 32 bytes for 12 and 14 bit digitizers and 16 bytes for 8 bit digitizers. b. Use the handle to set up each board in a known condition c. Start a data acquisition session by issuing a StartCapture command on the Master (first) board of System 1 d. Wait until data acquisition is finished e. Read the data captured on each of the channels f. Save the data captured to disk 3. Exit the application While this is a very simple application, it shows how you can use the ATS-SDK to acquire signals and process them in your own environment. The following pages show the source code for this simple, yet powerful sample program. 26 ATS-SDK Software Manual v5.6.0

// Acq2Disk.cpp : Defines the entry point for the console application. // //============================================================================= // // Alazar Technologies Inc // // File Name: // // Acq2Disk.cpp // // Copyright (c) 2006 Alazar Technologies Inc. All Rights Reserved. // Unpublished - rights reserved under the Copyright laws of the // United States And Canada. // // This product contains confidential information and trade secrets // of Alazar Technologies Inc. Use, disclosure, or reproduction is // prohibited without the prior express written permission of Alazar // Technologies Inc // //============================================================================= #include "stdafx.h" #include "windows.h" #include "stdio.h" #include "conio.h" #include "AlazarApi.h" #include "AlazarCmd.h" #define CHECK_ERROR if (status!= ApiSuccess){free(Data[0]);free(Data[1]);return -1;} void Purpose() { } printf("program Name: Acq2Disk.exe\n\n"); printf("purpose:\n"); printf("this sample application demonstrates the use of the AlazarTech API.\n"); printf("it is meant to be used as a model for writing application programs\n"); printf("that perform an acquisition on a single AlazarTech device.\n\n"); printf("output:\n"); printf("this sample produces binary data files that contain the captured\n"); printf("data for each channel.\n"); printf("------------------------------------------------------------------\n"); int getboardtypebyhandle(handle h) { U32 temp=0; AlazarQueryCapability(h, BOARD_TYPE, 0, &temp); temp = (int)temp; return temp; } U32 getasopctype(int system, int boardnum) { U32 temp=0; AlazarQueryCapability(AlazarGetBoardBySystemID(system, boardnum), ASOPC_TYPE, 0, &temp); return temp; } ATS-SDK Software Manual v5.6.0 27

int BoardsFound( int numofboards ) { U8 mj1,mj2,mn1,mn2,r1,r2; int retval=0; U32 MemSize; U8 SampleSize; if (numofboards==0) { printf("no AlazarTech devices were detected.\n"); retval=0; } else { printf("this sample program will operate on the first AlazarTech device.\n"); for (int i=0; i<numofboards; i++) { printf("\nboard No. %i \n",i+1); AlazarGetSDKVersion(&mj1,&mn1,&r1); AlazarGetDriverVersion(&mj2,&mn2,&r2); printf(" - SDK Version: %i.%i.%i\n",mj1,mn1,r1); printf(" - Driver Version: %i.%i.%i\n",mj2,mn2,r2); printf(" - ASOPC: %08XL\n",getASOPCType(1,i+1)); AlazarGetChannelInfo( AlazarGetBoardBySystemID(1, i+1), & MemSize, &SampleSize); printf(" - Memory Size: %i\n - Sample Size: %i\n", MemSize, SampleSize); if (getboardtypebyhandle(alazargetboardbysystemid(1, i+1))==ats460) { if (retval==0) retval=i+1; } } } if (retval!=0) printf("\npress any key to perform acquisition."); else printf("\npress any key to exit."); } getch(); return retval; 28 ATS-SDK Software Manual v5.6.0

int main(int argc, char* argv[]) { FILE *f; U32 i = 0; U32 k = 0; HANDLE h=null; U32 NumOfBoards; U16 *Data[2] = {NULL,NULL}; RETURN_CODE status=apisuccess; U32 MemSize; U8 SampleSize; BoardDef bd; char fna[] = "ChanA1.csv"; char fnb[] = "ChanB1.csv"; U32 RecordToRead = 1; bd.recordcount = 1; bd.reclength = 4*1024; bd.predepth = 0; bd.clocksource = INTERNAL_CLOCK; bd.clockedge = CLOCK_EDGE_RISING; bd.samplerate = SAMPLE_RATE_125MSPS; bd.couplingchana = DC_COUPLING; bd.inputrangechana = INPUT_RANGE_PM_1_V; bd.inputimpedchana = IMPEDANCE_50_OHM; bd.couplingchanb = DC_COUPLING; bd.inputrangechanb = INPUT_RANGE_PM_1_V; bd.inputimpedchanb = IMPEDANCE_50_OHM; bd.triengoperation = TRIG_ENGINE_OP_J_OR_K; bd.triggerengine1 = TRIG_ENGINE_J; bd.trigengsource1 = TRIG_CHAN_A; bd.trigengslope1 = TRIGGER_SLOPE_POSITIVE; bd.trigenglevel1 = 128; bd.triggerengine2 = TRIG_ENGINE_K; bd.trigengsource2 = TRIG_DISABLE; bd.trigengslope2 = TRIGGER_SLOPE_POSITIVE; bd.trigenglevel2 = 128; Purpose(); NumOfBoards = AlazarBoardsInSystemBySystemID(1); if (BoardsFound(NumOfBoards)!=0) { /* ********************************************************************* Allocate the data buffer in which the device will DMA transfer the captured data. NOTE: Each data buffer must be a minimum of 16 samples larger than the Record Length setting of the board. For example, if your Record Length is 1024 samples, your buffer must be at least 1040 samples long. If you do not allocate this additional space, your application may crash when you issue an AlazarRead command to DMA data from the digitizer to host memory, ********************************************************************* */ Data[0] = (U16 *) malloc(( bd.reclength + 16 )*sizeof(u16)); if (Data[0]==NULL) { CHECK_ERROR; } ATS-SDK Software Manual v5.6.0 29

Data[1] = (U16 *) malloc(( bd.reclength + 16 )*sizeof(u16)); if (Data[1]==NULL) { CHECK_ERROR; } h = AlazarGetBoardBySystemID(1, 1); AlazarSetLED(h,0); status = AlazarGetChannelInfo( h, &MemSize, &SampleSize); status = AlazarSetRecordCount( h, bd.recordcount); CHECK_ERROR status = AlazarSetRecordSize( h, bd.predepth, bd.reclength-bd.predepth); CHECK_ERROR status = AlazarSetCaptureClock( h,bd.clocksource,bd.samplerate,bd.clockedge,0); CHECK_ERROR status = AlazarInputControl( h,channel_a,bd.couplingchana,bd.inputrangechana,bd.inputimpedchana); CHECK_ERROR status = AlazarInputControl( h,channel_b,bd.couplingchanb,bd.inputrangechanb,bd.inputimpedchanb); CHECK_ERROR status = AlazarSetTriggerOperation( h,bd.triengoperation,bd.triggerengine1,bd.trigengsource1,bd.trigengslope1,bd.trigenglevel1,bd.triggerengine2,bd.trigengsource2,bd.trigengslope2,bd.trigenglevel2); CHECK_ERROR //Create a 5 Second timeout delay AlazarSetTriggerTimeOut( h, 500000); status = AlazarStartCapture( h ); CHECK_ERROR while(alazarbusy(h)); // Read the acquired data from the device AlazarRead( h, CHANNEL_A, Data[0], 2, RecordToRead, -(long)bd.predepth, bd.reclength); AlazarRead( h, CHANNEL_B, Data[1], 2, RecordToRead, -(long)bd.predepth, bd.reclength); 30 ATS-SDK Software Manual v5.6.0

} // Store the acquired data to disk // Store Channel A data if ((f = fopen(fna,"w+"))!=null) { for (i=0; i<bd.reclength; i++) { fprintf(f,"%i\n",(int)data[0][i]); } } fclose(f); // Store Channel B data if ((f = fopen(fnb,"w+"))!=null) { for (i=0; i<bd.reclength; i++) { fprintf(f,"%i\n",(int)data[1][i]); } } fclose(f); free(data[0]); free(data[1]); return 0; } ATS-SDK Software Manual v5.6.0 31

Reviewing SynchronousAutoDMA C Sample Program Let us review the AcqADMA_SingleChannel sample program that is supplied with ATS-SDK as an example of Dual Ported Synchonous AutoDMA access. AcqADMA_SingleChannel is a C/C++ program that performs the following tasks: 1. Find out how many AlazarTech boards are there in the computer and if they are configured as a Master/Slave system. If no boards are found, exit gracefully. 2. This sample program is designed for an independent board. If you have a Master/Slave system, this program will operate on the Master board only. a. If no boards are found, do nothing. b. If a board is found, allocate two buffers that can each hold RecsPerBuf records, where RecsPerBuf is a user-settable parameter. If you are going to use AutoDMA headers, the size of these buffers must be larger by a corresponding amount, i.e. 32 bytes of additional buffer space per trigger. 3. Set up the board in a known condition a. Note that RecordCount MUST be an exact multiple of RecsPerBuf. Alternatively, RecordCount can be set as Infinite (hex value of 0x7FFFFFFF) in order to do data capture until a user-generated abort command. b. If external trigger is being used, set it up for +/- 5V input range and DC coupling to allow triggering by a TTL trigger input. 32 ATS-SDK Software Manual v5.6.0

c. Note that the trigger level must be set to 160 for TTL triggering to be successful. Trigger Level values have the following scaling: 255 = + Full Scale, e.g. +5V for +/-5V range 128 = Zero Volt 0 = - Full Scale, e.g. -5V for +/-5V range 4. Initialize the DMA engine by calling AlazarStartAutoDMA 5. Start a dual-ported data acquisition and transfer session by issuing an AlazarStartCapture command 6. Continuously check if a new buffer is available by calling AlazarGetNextBuffer. Alternatively, set up an event using AlazarEvents API call, which will cause your thread to be suspended until the buffer is fully populated. a. A buffer will become available only when all RecsPerBuf records have been successfully DMA d into that buffer and the driver has switched to the other AutoDMA buffer for subsequent data transfers. b. Note that, unless you have set up events, it is ESSENTIAL that you continuously call AlazarGetNextBuffer. If you do not continuously call AlazarGetNextBuffer, you will most probably see a DMA overflow, as AlazarGetNextBuffer routine is the one that senses that, say, Buffer[0] is full and then starts a new DMA into Buffer[1]. c. If a buffer is available, process it. In this sample program, the data is saved to a file. Note that while you are processing Buffer[0], new data is being acquired and transferred into Buffer[1], and viceversa. ATS-SDK Software Manual v5.6.0 33

7. Stop calling AlazarGetNextBuffer if all triggers have been captured or if an error was encountered a. A software timeout is included in this sample program to protect against cases where triggers stop arriving. If you have called AlazarGetNextBuffer a specific number of times, e.g. 50000, and the buffer is still not available, the sample program aborts the DMA engine as well as the acquisition. This arbitrary number should be adjusted to reflect the trigger repeat rate in your experiment as well as the speed of your computer. 8. Free all the buffers and close all files 9. Exit the application 34 ATS-SDK Software Manual v5.6.0

// AcqADMA_SingleChannel.cpp : Defines the entry point for the console application. // //============================================================================= // // Alazar Technologies Inc // // File Name: // // AcqADMA_SingleChannel.cpp // // Copyright (c) 2006 Alazar Technologies Inc. All Rights Reserved. // Unpublished - rights reserved under the Copyright laws of the // United States and Canada. // // This product contains confidential information and trade secrets // of Alazar Technologies Inc. Use, disclosure, or reproduction is // prohibited without the prior express written permission of Alazar // Technologies Inc // //============================================================================= #include "stdafx.h" #include "windows.h" #include "stdio.h" #include "conio.h" #include "AlazarApi.h" #include "AlazarCmd.h" #define CHECK_ERROR if (status!= ApiSuccess){free(UserData[0]);free(UserData[1]);return -1;} U32 r3=0; U32 r4=0; BoardDef bd; U16 *UserData[2] = {NULL,NULL}; U32 UseHeader = 0; HANDLE h=null; AUTODMA_STATUS error; // The following variables may be reassigned new values // however they have been initialized with the values // required to perform the following acquisition // // Record Count as 512 // Record Length as 1024 samples - u16 type each // Mode of operation single channel A // Sample rate as 125MS/s // U32 RecsPerBuffer = 64; // This is the number of sequences in one cycle U32 mode = CHANNEL_A; // Specify whether to capture, // CHANNEL_A or CHANNEL_B U32 SampleRate = SAMPLE_RATE_125MSPS; // Specify the sample rate at which to capture data U32 RecordCount = 512; // Specify how many sequences to capture. // Note this number must be an exact // multiple of RecsPerBuffer U32 RecordLength = 1024; // Specify how many points to capture per trigger long RecsTransferred = 0; long TriggersOccurred = 0; U32 loop_count = 0; int looping = 0; int errorcount = 0; U32 transferlength=0; ATS-SDK Software Manual v5.6.0 35

int getboardtypebyhandle(handle h) { U32 temp=0; AlazarQueryCapability(h, BOARD_TYPE, 0, &temp); temp = (int)temp; return temp; } U32 getasopctype(int system, int boardnum) { U32 temp=0; AlazarQueryCapability(AlazarGetBoardBySystemID(system, boardnum), ASOPC_TYPE, 0, &temp); return temp; } void Purpose() { } printf("program Name: AcqADMA_SingleChannel.exe\n\n"); printf("purpose:\n"); printf("this sample application demonstrates the use of the AlazarTech API.\n"); printf("it is meant to be used as a model for writing application programs\n"); printf("that perform an AutoDMA acquisition on a single AlazarTech device.\n\n"); printf("output:\n"); printf("this sample produces a binary data file that contains the captured\n"); printf("data for a single channel.\n"); printf("------------------------------------------------------------------\n"); int BoardsFound( int numofboards ) { U8 mj1,mj2,mn1,mn2,r1,r2; int retval=0; U32 MemSize; U8 SampleSize; if (numofboards==0) { printf("no AlazarTech devices were detected.\n"); retval=0; } else { printf("this sample program will operate on the first AlazarTech device.\n"); for (int i=0; i<numofboards; i++) { printf("\nboard No. %i \n",i+1); AlazarGetSDKVersion(&mj1,&mn1,&r1); AlazarGetDriverVersion(&mj2,&mn2,&r2); printf(" - SDK Version: %i.%i.%i\n",mj1,mn1,r1); printf(" - Driver Version: %i.%i.%i\n",mj2,mn2,r2); printf(" - ASOPC: %08XL\n",getASOPCType(1,i+1)); AlazarGetChannelInfo( AlazarGetBoardBySystemID(1, i+1), &MemSize, &SampleSize); printf(" - Memory Size: %i\n - Sample Size: %i\n", MemSize, SampleSize); if (getboardtypebyhandle(alazargetboardbysystemid(1, i+1))==ats460) { if (retval==0) retval=i+1; } } } 36 ATS-SDK Software Manual v5.6.0

if (retval!=0) printf("\npress any key to perform acquisition."); else printf("\npress any key to exit."); } getch(); return retval; //File handles FILE *DataFile; int SaveToChannelFiles(U16 *UserData) { for (U32 RecordInBuffer=1; RecordInBuffer <= RecsPerBuffer; RecordInBuffer++) { PALAZAR_HEADER pah; pah = (PALAZAR_HEADER)AlazarGetAutoDMAPtr(h, 1, CHANNEL_A, UserData, RecordInBuffer, &error); U16 *pa = (U16 *)AlazarGetAutoDMAPtr(h, 0, CHANNEL_A, UserData, RecordInBuffer, &error); fwrite(pa,1,transferlength<<1,datafile); } printf("."); return 0; } int main(int argc, char* argv[]) { U32 in = 0; long in1 = 0; U32 i = 0; U32 k = 0; long WhichOne; U32 NumOfBoards; RETURN_CODE status=apisuccess; int returnvalue=0; bd.recordcount = RecordCount; bd.reclength = RecordLength; bd.predepth = 64; bd.clocksource = INTERNAL_CLOCK; bd.clockedge = CLOCK_EDGE_RISING; bd.samplerate = SampleRate; bd.couplingchana = DC_COUPLING; bd.inputrangechana = INPUT_RANGE_PM_1_V; bd.inputimpedchana = IMPEDANCE_1M_OHM; bd.couplingchanb = DC_COUPLING; bd.inputrangechanb = INPUT_RANGE_PM_1_V; bd.inputimpedchanb = IMPEDANCE_1M_OHM; bd.triengoperation = TRIG_ENGINE_OP_J; bd.triggerengine1 = TRIG_ENGINE_J; bd.trigengsource1 = TRIG_CHAN_A; bd.trigengslope1 = TRIGGER_SLOPE_POSITIVE; bd.trigenglevel1 = 160; bd.triggerengine2 = TRIG_ENGINE_K; bd.trigengsource2 = TRIG_DISABLE; bd.trigengslope2 = TRIGGER_SLOPE_POSITIVE; bd.trigenglevel2 = 128; Purpose(); ATS-SDK Software Manual v5.6.0 37

NumOfBoards = AlazarBoardsInSystemBySystemID(1); BoardsFound(NumOfBoards); if (NumOfBoards==0) { return -3; } else { if ((DataFile = fopen("channel.dat","wb+"))==null) return -2; int sizeperchannel = RecsPerBuffer * bd.reclength *(sizeof(u16)+16*(useheader!=0)); UserData[0] = (U16 *) malloc(sizeperchannel); if (UserData[0]==NULL) CHECK_ERROR; UserData[1] = (U16 *) malloc(sizeperchannel); if (UserData[1]==NULL) CHECK_ERROR; h = AlazarGetBoardBySystemID(1, 1); status = AlazarSetRecordSize( h, bd.predepth, bd.reclength-bd.predepth); CHECK_ERROR status = AlazarSetCaptureClock( h,bd.clocksource,bd.samplerate,bd.clockedge,0); CHECK_ERROR status = AlazarInputControl( h,channel_a,bd.couplingchana,bd.inputrangechana,bd.inputimpedchana); CHECK_ERROR status = AlazarInputControl( h,channel_b,bd.couplingchanb,bd.inputrangechanb,bd.inputimpedchanb); CHECK_ERROR status = AlazarSetTriggerOperation( h,bd.triengoperation,bd.triggerengine1,bd.trigengsource1,bd.trigengslope1,bd.trigenglevel1,bd.triggerengine2,bd.trigengsource2,bd.trigengslope2,bd.trigenglevel2); CHECK_ERROR if ((bd.trigengsource1 == TRIG_EXTERNAL) bd.trigengsource2 == TRIG_EXTERNAL)) { // Set External Trigger to be 5V range, DC coupling AlazarSetExternalTrigger( h, DC_COUPLING, ETR_DIV5); } 38 ATS-SDK Software Manual v5.6.0

// Create a 5 Second timeout delay. // You can remove this line if you are sure that you will // always have a trigger signal AlazarSetTriggerTimeOut( h, 500000); transferlength = bd.reclength; status = AlazarStartAutoDMA(h, UserData[0], UseHeader, mode, -(long)bd.predepth, transferlength, RecsPerBuffer, bd.recordcount, &error, in1, in1, &r3, &r4); if (error == ADMA_InvalidRecsPerBuffer) { printf("err: RecordCount must be a multiple of RecordsPerBuffer.\n"); return -6; } loop_count = 0; looping = 1; RecsTransferred = 0; while (looping == 1) { AlazarGetNextAutoDMABuffer(h, UserData[0], UserData[1], &WhichOne, &RecsTransferred, &error, in1, in1, &TriggersOccurred, &r4); //-------------------------------------------------------------- //All records have been transferred and none are left if (RecsTransferred == (long)recordcount) { looping = 0; } //-------------------------------------------------------------- //Valid data exists in either UserData[0] or UserData[1] if ((WhichOne == 0) (WhichOne == 1)) { //Process Your Data here SaveToChannelFiles(UserData[WhichOne]); loop_count = 0; printf("."); } ATS-SDK Software Manual v5.6.0 39

//-------------------------------------------------------------- // Abort the DMA if the system is locked up waiting for triggers. // // This is a delay that you may want to signify that too much // time has expired so you choose to abort. The loop_count limit // chosen is arbitrary and may be changed to suite your needs. loop_count = loop_count + 1; if (loop_count > 50000) { if ((TriggersOccurred>0) && ((U32)TriggersOccurred<RecsPerBuffer)) { AlazarAbortAutoDMA(h, UserData[0], &error, in1, in1, &r3, &r4); } looping = 0; printf("."); errorcount = errorcount + 1; } //-------------------------------------------------------------- //An AUTODMA error has happened so abort the current acquisitiion if (error == ADMA_OverFlow) { looping = 0; returnvalue = -4; } } AlazarCloseAUTODma(h); fclose(datafile); free(userdata[0]); free(userdata[1]); } printf("\npress any key to exit."); getch(); } return returnvalue; 40 ATS-SDK Software Manual v5.6.0

Reviewing An AsyncDMA C Sample Program Let us review the AcqPostBufferNPTInfinite sample program that is supplied with ATS-SDK as an example of Dual Ported Asynchronous AutoDMA (AsyncDMA) access. This acquisition mechanism has been adopted by many ultrasonic, OCT and other imaging and scanning customers. AcqPostBufferNPTInfinite uses the NPT (No Pre Trigger) mode and infinite number of records, so the acquisition can go on forever. This is a typical usage of the PostBuffer mechanism in order to post several data buffers, perform an AsyncDMA acquisition, and consume data in real-time Also, it can be used to perform Single Channel or Dual Channel acquisitions based on the setting of the mode variable. AcqPostBufferNPTInfinite is a C/C++ program that performs the following tasks: 1. Find out how many AlazarTech boards are there in the computer and if they are configured as a Master/Slave system. If no boards are found, exit gracefully. 2. This sample program is designed for an independent board. If you have a Master/Slave system, this program will operate on the Master board only. a. If no boards are found, do nothing. b. If a board is found, allocate the data buffers that will be used to hold the captured data. 3. Set up the board in a known condition a. RecordCount is set as Infinite (hex value of 0x7FFFFFFF) in order to do data capture until a user-generated abort command occurs. b. If external trigger is being used, set it up for +/- 5V input range and DC coupling to allow triggering by a TTL trigger input. ATS-SDK Software Manual v5.6.0 41

c. Also note that the trigger level must be set to 160 for TTL triggering to be successful. Trigger Level values have the following scaling: 255 = + Full Scale, e.g. +5V for +/-5V range 128 = Zero Volt 0 = - Full Scale, e.g. -5V for +/-5V range 4. Initialize the DMA engine by calling AlazarBeforeAsyncRead. 5. Post the number of buffers as indicated by the BuffersPosted variable. 6. Start the Acquisition. 7. Enter the acquisition loop and use Alazar Api AlazarWaitAsyncBufferComplete to wait for the DMA ed buffers. Note that this call interrogates the overlapped IO structures and does not eat up too manu CPU cycles 8. The acquisition loop details are as follows: a. If a data buffer has been received and a timeout has not occurred, Re-Post the buffer after the data has been consumed. In this case we are simply saving the data to a file. b. If no data buffer has been received and a timeout has occurred at least five (5) times, indicate the error and abort the acquisition. i. Note that a timeout does not necessarily indicate an error condition. It is perfectly legitimate for the program to call AlazarWaitAsyncBufferComplete as many times as required. In our sample program, we decided to abort the acquisition after five timeouts, but this is an arbitrary number chosen for demonstration purposes. c. If sufficient number of records have been received simply exit acquisition loop. Note that the program uses a kbhit() input to simulate a stop request indicating that the sufficient number of records have been received 42 ATS-SDK Software Manual v5.6.0

9. Call AlazarAbortAsyncRead in order to close all DMA channels, flush the queue of buffers and stop any further arming of the dma engines. a. Note that if you do not call AlazarAbortAsyncRead upon exit, you can get yourself into a lock-up situation, which can only be resolved with a hard re-boot. b. Close the output file(s), free the allocated buffers, and exit the program. ATS-SDK Software Manual v5.6.0 43

// AcqPostBufferNPTInfinite.cpp : Defines the entry point for the console application. // //============================================================================= // // Alazar Technologies Inc // // File Name: // // AcqPostBufferNPTInfinite.cpp // // Copyright (c) 2006 Alazar Technologies Inc. All Rights Reserved. // Unpublished - rights reserved under the Copyright laws of the // United States And Canada. // // This product contains confidential information and trade secrets // of Alazar Technologies Inc. Use, disclosure, or reproduction is // prohibited without the prior express written permission of Alazar // Technologies Inc // //============================================================================= #include "stdafx.h" #include "windows.h" #include "stdio.h" #include "conio.h" #include "AlazarApi.h" #include "AlazarCmd.h" #define CHECK_ERROR if (status!= ApiSuccess){return -1;} U32 r3=0; U32 r4=0; BoardDef bd; U16 *UserData[16] = {NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL}; U16 *SaveBuffers[2] = {NULL, NULL}; HANDLE h=null; AUTODMA_STATUS error; // Specify whether to capture, CHANNEL_A or CHANNEL_B //U32 mode = CHANNEL_A; U32 mode = CHANNEL_A CHANNEL_B; U32 SampleRate = SAMPLE_RATE_125MSPS; // Specify the sample rate at which to capture data U32 RecordCount = 0x7FFFFFFF; int RecordLength = 4*1024; int BuffersPosted = 16; int RecsPerBuffer = 16; int getboardtypebyhandle(handle h) { U32 temp=0; AlazarQueryCapability(h, BOARD_TYPE, 0, &temp); temp = (int)temp; return temp; } U32 getasopctype(int system, int boardnum) { U32 temp=0; AlazarQueryCapability(AlazarGetBoardBySystemID(system, boardnum), ASOPC_TYPE, 0, &temp); return temp; } void Purpose() { 44 ATS-SDK Software Manual v5.6.0

printf("program Name: AcqPostBufferNPTInfinite.exe\n\n"); printf("purpose:\n"); printf("this program can be used as a model for writing application programs\n"); printf("that perform a NonPreTrigger acquisition with Infinite RecordCount \n"); printf("(using AsyncDMA API)on a single AlazarTech device.\n\n"); printf("\noutput:\n"); printf("this sample produces a binary data file that contains the captured\n"); printf("data for a single channel.\n"); printf("\nnote:"); printf("\nyou will need to remove the printf statements in order to improve "); printf("\nperformance.\n"); printf("\n"); printf("stopping is done by pressing any key while the program is running\n"); printf("\n"); printf("------------------------------------------------------------------\n"); } int BoardsFound( int numofboards ) { U8 mj1,mj2,mn1,mn2,r1,r2; int retval=0; U32 MemSize; U8 SampleSize; if (numofboards==0) { printf("no AlazarTech devices were detected.\n"); retval=0; } else { printf("this sample program will operate on the first AlazarTech device.\n"); for (int i=0; i<numofboards; i++) { printf("\nboard No. %i \n",i+1); AlazarGetSDKVersion(&mj1,&mn1,&r1); AlazarGetDriverVersion(&mj2,&mn2,&r2); printf(" - SDK Version: %i.%i.%i\n",mj1,mn1,r1); printf(" - Driver Version: %i.%i.%i\n",mj2,mn2,r2); printf(" - ASOPC: %08XL\n",getASOPCType(1,i+1)); AlazarGetChannelInfo( AlazarGetBoardBySystemID(1, i+1), &MemSize, &SampleSize); printf(" - Memory Size: %i\n - Sample Size: %i\n", MemSize, SampleSize); if (getboardtypebyhandle(alazargetboardbysystemid(1, i+1))==ats460) { if (retval==0) retval=i+1; } } } if (retval!=0) printf("\npress any key to perform acquisition."); else printf("\npress any key to exit."); } getch(); return retval; //File handles FILE *DataFileA; FILE *DataFileB; int SaveToChannelAFiles(U16 *Data, int nbytes) { int k=0; U16 *p=savebuffers[0]; ATS-SDK Software Manual v5.6.0 45

} if (mode==channel_a) { fwrite(data,2,nbytes/2,datafilea); } else { for (int i=0; i<(nbytes/4); i++) { p[k] = Data[i]; k++; } fwrite((void*)p,1,nbytes/2,datafilea); } return 0; int SaveToChannelBFiles(U16 *Data, int nbytes) { int k=0; U16 *p=savebuffers[1]; } if (mode==channel_a) { return -1; } else { for (int i=0; i<(nbytes/4); i++) { p[k] = Data[nBytes/4+i]; k++; } fwrite((void*)p,1,nbytes/2,datafileb); } return 0; int main(int argc, char* argv[]) { U32 in = 0; long in1 = 0; U32 i = 0; U32 k = 0; U32 NumOfBoards; RETURN_CODE status=apisuccess; RETURN_CODE status1=apisuccess; int returnvalue=0; U32 CFLAGS = 0; int BytesPerBuffer = 0; int BuffersCompleted = 0; int BufferIndex = 0; bool ErrorFlag = false; bd.recordcount = RecordCount; bd.reclength = RecordLength; bd.predepth = 0; bd.clocksource = INTERNAL_CLOCK; bd.clockedge = CLOCK_EDGE_RISING; bd.samplerate = SampleRate; bd.couplingchana = DC_COUPLING; bd.inputrangechana = INPUT_RANGE_PM_800_MV; bd.inputimpedchana = IMPEDANCE_1M_OHM; bd.couplingchanb = DC_COUPLING; bd.inputrangechanb = INPUT_RANGE_PM_800_MV; bd.inputimpedchanb = IMPEDANCE_1M_OHM; bd.triengoperation = TRIG_ENGINE_OP_J; bd.triggerengine1 = TRIG_ENGINE_J; bd.trigengsource1 = TRIG_CHAN_A; 46 ATS-SDK Software Manual v5.6.0

bd.trigengslope1 = TRIGGER_SLOPE_POSITIVE; bd.trigenglevel1 = 160; bd.triggerengine2 = TRIG_ENGINE_K; bd.trigengsource2 = TRIG_DISABLE; bd.trigengslope2 = TRIGGER_SLOPE_POSITIVE; bd.trigenglevel2 = 128; Purpose(); NumOfBoards = AlazarBoardsInSystemBySystemID(1); if (BoardsFound(NumOfBoards)==0) { return -3; } else { if ((DataFileA = fopen("channela.dat","wb+"))==null) return -2; if ((DataFileB = fopen("channelb.dat","wb+"))==null) return -2; //sizeperchannel calculation in Bytes int sizeperchannel = (2 * RecsPerBuffer * RecordLength * ( 1 + (mode==(channel_a CHANNEL_B))) ); for (int m=0; m<buffersposted; m++) { UserData[m] = (U16 *) malloc(sizeperchannel); if (UserData[0]==NULL) { return -1; } } SaveBuffers[0] =(U16 *) malloc(sizeperchannel/2); SaveBuffers[1] =(U16 *) malloc(sizeperchannel/2); h = AlazarGetBoardBySystemID(1, 1); status = AlazarSetRecordSize( h, bd.predepth, bd.reclength-bd.predepth); CHECK_ERROR status = AlazarSetCaptureClock( h,bd.clocksource,bd.samplerate,bd.clockedge,0); CHECK_ERROR status = AlazarInputControl( h,channel_a,bd.couplingchana,bd.inputrangechana,bd.inputimpedchana); CHECK_ERROR status = AlazarInputControl( h,channel_b,bd.couplingchanb,bd.inputrangechanb,bd.inputimpedchanb); CHECK_ERROR status = AlazarSetTriggerOperation( h,bd.triengoperation,bd.triggerengine1,bd.trigengsource1,bd.trigengslope1,bd.trigenglevel1,bd.triggerengine2,bd.trigengsource2 ATS-SDK Software Manual v5.6.0 47

,bd.trigengslope2,bd.trigenglevel2); CHECK_ERROR if ((bd.trigengsource1 == TRIG_EXTERNAL) (bd.trigengsource2 == TRIG_EXTERNAL)) { AlazarSetExternalTrigger( h, DC_COUPLING, ETR_5V); // Set External Trigger to be 5V range, DC coupling } //Create a 5 Second timeout delay. //You can remove this line if you are sure that you will always have a trigger signal AlazarSetTriggerTimeOut( h, 500000); BytesPerBuffer = sizeperchannel; CFLAGS = ADMA_NPT ADMA_EXTERNAL_STARTCAPTURE; status = AlazarBeforeAsyncRead(h, mode, 0, bd.reclength, RecsPerBuffer, bd.recordcount, CFLAGS); for (m=0; m<buffersposted; m++) { status = AlazarPostAsyncBuffer(h, UserData[m], BytesPerBuffer); } BuffersCompleted = 0; BufferIndex = 0; status = AlazarStartCapture(h); void *pbuffer; ErrorFlag = false; while(1) { status = ApiSuccess; BufferIndex = BuffersCompleted % BuffersPosted; pbuffer = UserData[BufferIndex]; acquisition int passes = 5; while (passes--) { status = AlazarWaitAsyncBufferComplete(h, pbuffer, 2000); if (status==apisuccess) { break; } if ((status==apiwaittimeout) && (passes > -1)) { printf("\nstatus = ApiWaitTimeout"); } } //Pseudo exit criteria to stop the if (kbhit()) { break; } if ((status!= ApiSuccess) && (status!=apitransfercomplete)) { //error out ErrorFlag = true; status1 = AlazarAbortAsyncRead(h); break; } if (status == ApiTransferComplete) 48 ATS-SDK Software Manual v5.6.0

{ } break; BuffersCompleted = BuffersCompleted + 1; #if 0 #endif //Process the buffer here if (mode == (CHANNEL_A CHANNEL_B)) { SaveToChannelAFiles((U16*)pBuffer,BytesPerBuffer); SaveToChannelBFiles((U16*)pBuffer,BytesPerBuffer); } else { SaveToChannelAFiles((U16*)pBuffer,BytesPerBuffer); } if (status==apisuccess) { if ((BufferIndex%1000)==0) { printf(".");//index = %i",bufferindex); } status = AlazarPostAsyncBuffer(h, pbuffer, BytesPerBuffer); if (status!= ApiSuccess) { ErrorFlag = true; status1 = AlazarAbortAsyncRead(h); break; } BufferIndex = BufferIndex + 1; } else { break; } } } status1 = AlazarAbortAsyncRead(h); fclose(datafilea); fclose(datafileb); for (int m=0; m<buffersposted; m++) { free(userdata[m]); } free(savebuffers[0]); free(savebuffers[1]); if (ErrorFlag) { printf("\nerror %i was encountered.\n", status); } else { printf("\nacquisition succeeded.\n"); } printf("\npress any key to exit."); getch(); } return returnvalue; ATS-SDK Software Manual v5.6.0 49

Reviewing An AsyncDMA VB Sample Program Let us review the AcqPostBuffNPTInfinite sample program that is supplied with ATS-SDK as an example of Dual Ported Asynchronous AutoDMA (AsyncDMA) access. It uses the NPT mode and infinite many records. This is a typical usage of the PostBuffer mechanism in order to post several data buffers and perform an AsyncDMA acquisition. Also, it can be used to perform Single Channel or Dual Channel acquisitions based on the setting of the mode variable. AcqPostBuffNPTInfinite is a VisualBasic program that performs the following tasks: 1. Set the global values of RecordLength, mode (i.e. Single or Dual channel), RecordsPerBuffer so that the program can dimension the appropriate statis buffer sizes. It should be noted that the buffer size in this example is always calculated for a dual channel acquisition. 2. The program uses a VB form so all processing is performed on the OnClick event of the StartAquisition button. On pressing the button, the AcquireButton_Click() function is called to perform the acquisition. 3. This sample program is designed for an independent board. If you have a Master/Slave system, this program will operate on the Master board only. c. If no boards are found, do nothing and stop. d. If a board is found, continue. 4. Set up the board in a known condition a. RecordCount is set as Infinite (hex value of 0x7FFFFFFF) in order to do data capture until a user-generated abort command occurs. b. If external trigger is being used, set it up for +/- 5V input range and DC coupling to allow triggering by a TTL trigger input. 50 ATS-SDK Software Manual v5.6.0

c. Also note that the trigger level must be set to 160 for TTL triggering to be successful. d. Trigger Level values have the following scaling: 255 = + Full Scale, e.g. +5V for +/-5V range 128 = Zero Volt 0 = - Full Scale, e.g. -5V for +/-5V range 5. Initialize the DMA engine by calling AlazarBeforeAsyncRead. 6. Post the number of buffers as indicated by the BuffersPosted variable. 7. Start the Acquisition. 8. Enter the acquisition loop and use Alazar Api AlazarWaitAsyncBufferComplete to wait for the DMA ed buffers. Note that this call interrogates the overlapped IO structures and does not eat up too manu CPU cycles 9. The acquisition loop details are as follows: a. If a data buffer has been received and a timeout has not occurred, Re-Post the buffer after the data has been consumed. In this example, data consummation is done by: calculating the average for each record in the buffer and saving the values to file(s). b. If no data buffer has been received and a timeout has occurred indicate the error and abort the acquisition. c. Note that a timeout does not necessarily indicate an error condition. It is perfectly legitimate for the program to call AlazarWaitAsyncBufferComplete again. d. If the sufficient number of records have been received simply exit acquisition loop. e. Note that the program uses a VB button on the form, called Stop to simulate a stop request thus indicating that the sufficient number of records have been received ATS-SDK Software Manual v5.6.0 51

10. Call AlazarAbortAsyncRead in order to close all DMA channels, flush the queue of buffers and stop any further arming of the dma engines. a. Note that if you do not call AlazarAbortAsyncRead upon exit, you can get yourself into a lock-up situation, which can only be resolved with a hard re-boot. 52 ATS-SDK Software Manual v5.6.0

'============================================================================= ' ' AlazarTech Inc ' ' File Name: ' ' AcqPostBuffNPTInfinite ' ' Copyright (c) 2006 AlazarTech Inc. All Rights Reserved. ' Unpublished - rights reserved under the Copyright laws of the ' United States And Canada. ' ' This product contains confidential information and trade secrets ' of AlazarTech Inc. Use, disclosure, or reproduction is ' prohibited without the prior express written permission of AlazarTech ' Inc ' ' Description: ' ' Sample Application that shows how to perform an AUTO DMA acquisition. ' ' This program serves as a sample that can be used to create a data ' acquisition console unit. '============================================================================= Dim stopflag As Boolean 'Const mode As Long = CHANNEL_A Const mode As Long = CHANNEL_A + CHANNEL_B Const RecordLength As Long = 16384 Const BUFFER_COUNT As Long = 8 Const RPerBuff As Long = 16 Const BUFFER_SIZE = RPerBuff * RecordLength * 2 'for now assume dual channel Dim UserData1(BUFFER_SIZE) As Integer Dim UserData2(BUFFER_SIZE) As Integer Dim UserData3(BUFFER_SIZE) As Integer Dim UserData4(BUFFER_SIZE) As Integer Dim UserData5(BUFFER_SIZE) As Integer Dim UserData6(BUFFER_SIZE) As Integer Dim UserData7(BUFFER_SIZE) As Integer Dim UserData8(BUFFER_SIZE) As Integer Private Sub AcquireButton_Click() Dim h As Variant Dim status As Long Dim Major As Byte Dim Minor As Byte Dim Rev As Byte Dim MemSize As Long Dim SampleSize As Byte Dim Channel As Byte Dim NumOfBoards As Integer Dim NumOfSystems As Integer Dim RecordToRead As Long Dim i As Long Dim j As Long Dim x As Long Dim Sum As Double Dim bd As BoardDef Dim error As Long Dim ErrorFlag As Boolean Dim CFLAG As Long Dim BytesPerBuffer As Long Dim BufferIndex As Integer Dim BuffersPosted As Integer Dim BuffersCompleted As Long ATS-SDK Software Manual v5.6.0 53

Dim f1 As Integer Dim f2 As Integer Dim FA As String Dim FB As String If (mode = CHANNEL_A) Then FA = "ChannelA.txt" ElseIf (mode = CHANNEL_B) Then FA = "ChannelB.txt" ElseIf (mode = CHANNEL_A + CHANNEL_B) Then FA = "ChannelA.txt" FB = "ChannelB.txt" f1 = FreeFile Open FB For Output As #f1 Close #f1 End If 'Always clear the first file output files f1 = FreeFile Open FA For Output As #f1 Close #f1 NumOfBoards = AlazarBoardsInSystemBySystemID(1) If NumOfBoards < 1 Then Stop End If status = AlazarGetCPLDVersion(h, Major, Minor) status = AlazarGetSDKVersion(Major, Minor, Rev) status = AlazarGetDriverVersion(Major, Minor, Rev) BuffersPosted = 0 BuffersCompleted = 0 BuffersPerAcquisition = 0 Command1.Caption = "Acquisition Started" Text1.Text = " " bd.predepth = 0 bd.clocksource = INTERNAL_CLOCK bd.clockedge = CLOCK_EDGE_RISING bd.samplerate = SAMPLE_RATE_180MSPS bd.couplingchana = AC_COUPLING bd.inputrangechana = INPUT_RANGE_PM_1_V bd.inputimpedchana = IMPEDANCE_1M_OHM bd.couplingchanb = AC_COUPLING bd.inputrangechanb = INPUT_RANGE_PM_1_V bd.inputimpedchanb = IMPEDANCE_1M_OHM bd.triengoperation = TRIG_ENGINE_OP_J_OR_K bd.triggerengine1 = TRIG_ENGINE_J bd.trigengsource1 = TRIG_CHAN_A bd.trigengslope1 = TRIGGER_SLOPE_POSITIVE bd.trigenglevel1 = 128 bd.triggerengine2 = TRIG_ENGINE_K bd.trigengsource2 = TRIG_DISABLE bd.trigengslope2 = TRIGGER_SLOPE_POSITIVE bd.trigenglevel2 = 128 h = AlazarGetSystemHandle(1) status = AlazarSetRecordSize(h, bd.predepth, bd.reclength - bd.predepth) status = AlazarSetCaptureClock(h, bd.clocksource, bd.samplerate, bd.clockedge, 0) Channel = CHANNEL_A status = AlazarInputControl(h, Channel, bd.couplingchana, bd.inputrangechana, bd.inputimpedchana) Channel = CHANNEL_B status = AlazarInputControl(h, Channel, bd.couplingchanb, bd.inputrangechanb, bd.inputimpedchanb) status = AlazarSetTriggerOperation(h, bd.triengoperation, bd.triggerengine1, bd.trigengsource1, bd.trigengslope1, bd.trigenglevel1, bd.triggerengine2, bd.trigengsource2, bd.trigengslope2, bd.trigenglevel2) 54 ATS-SDK Software Manual v5.6.0

'create a 5 second time out delay status = AlazarSetTriggerTimeOut(h, 0) '// NOTE: '// For this sample the Record Count is always set to Infinite '// bd.recordcount = &H7FFFFFFF bd.reclength = RecordLength Text4.Text = bd.reclength RecordsPerBuffer = RPerBuff Text6.Text = RecordsPerBuffer status = AlazarSetRecordCount(h, bd.recordcount) status = AlazarSetRecordSize(h, bd.predepth, bd.reclength - bd.predepth) BytesPerBuffer = 2 * BUFFER_SIZE stopflag = False error_cnt = 0 Do 'Configured as a Single channel system and we are only interested in Channel A data CFLAGS = ADMA_NPT_MODE Or ADMA_FIFO_ONLY_STREAMING Or ADMA_EXTERNAL_STARTCAPTURE status = AlazarBeforeAsyncRead(h, mode, 0, bd.reclength, RecordsPerBuffer, bd.recordcount, CFLAGS) status = AlazarPostAsyncBuffer(h, UserData1(0), BytesPerBuffer) status = AlazarPostAsyncBuffer(h, UserData2(0), BytesPerBuffer) status = AlazarPostAsyncBuffer(h, UserData3(0), BytesPerBuffer) status = AlazarPostAsyncBuffer(h, UserData4(0), BytesPerBuffer) status = AlazarPostAsyncBuffer(h, UserData5(0), BytesPerBuffer) status = AlazarPostAsyncBuffer(h, UserData6(0), BytesPerBuffer) status = AlazarPostAsyncBuffer(h, UserData7(0), BytesPerBuffer) status = AlazarPostAsyncBuffer(h, UserData8(0), BytesPerBuffer) BuffersPosted = BUFFER_COUNT BuffersCompleted = 0 TransfersCompleted = 0 BufferIndex = 0 status = AlazarStartCapture(h) loop_count = 0 ErrorFlag = False Do status = 0 BufferIndex = BuffersCompleted Mod BuffersPosted If BufferIndex = 0 Then status = AlazarWaitAsyncBufferComplete(h, UserData1(0), 50000) ElseIf BufferIndex = 1 Then status = AlazarWaitAsyncBufferComplete(h, UserData2(0), 50000) ElseIf BufferIndex = 2 Then status = AlazarWaitAsyncBufferComplete(h, UserData3(0), 50000) ElseIf BufferIndex = 3 Then status = AlazarWaitAsyncBufferComplete(h, UserData4(0), 50000) ElseIf BufferIndex = 4 Then status = AlazarWaitAsyncBufferComplete(h, UserData5(0), 50000) ElseIf BufferIndex = 5 Then status = AlazarWaitAsyncBufferComplete(h, UserData6(0), 50000) ElseIf BufferIndex = 6 Then status = AlazarWaitAsyncBufferComplete(h, UserData7(0), 50000) ElseIf BufferIndex = 7 Then status = AlazarWaitAsyncBufferComplete(h, UserData8(0), 50000) End If If stopflag = True Then Exit Do End If ATS-SDK Software Manual v5.6.0 55

If status <> 512 And status <> 589 Then 'error out ErrorFlag = True stopflag = True Exit Do End If If status = 589 Then stopflag = True Exit Do End If BuffersCompleted = BuffersCompleted + 1 ' Process the buffer here ' ' ' If ((mode = CHANNEL_A) Or (mode = CHANNEL_B)) And status = 512 Then ' Single channel only f1 = FreeFile Open FA For Append As #f1 j = 0 For i = 1 To RecordsPerBuffer Sum = 0 For k = 1 To bd.reclength If BufferIndex = 0 Then x = UserData1(j) ElseIf BufferIndex = 1 Then x = UserData2(j) ElseIf BufferIndex = 2 Then x = UserData3(j) ElseIf BufferIndex = 3 Then x = UserData4(j) ElseIf BufferIndex = 4 Then x = UserData5(j) ElseIf BufferIndex = 5 Then x = UserData6(j) ElseIf BufferIndex = 6 Then x = UserData7(j) ElseIf BufferIndex = 7 Then x = UserData8(j) End If j = j + 1 If x < 0 Then x = 65535 + x End If Sum = Sum + x Next k Sum = Sum / bd.reclength Print #f1, Sum Next i Close #f1 Stop ElseIf ((mode = CHANNEL_A + CHANNEL_B) And status = 512) Then ' Dual channel only ' Average Channel A f1 = FreeFile Open FA For Append As #f1 j = 0 For i = 1 To RecordsPerBuffer Sum = 0 For k = 1 To bd.reclength If BufferIndex = 0 Then x = UserData1(j) ElseIf BufferIndex = 1 Then 56 ATS-SDK Software Manual v5.6.0

End If x = UserData2(j) ElseIf BufferIndex = 2 Then x = UserData3(j) ElseIf BufferIndex = 3 Then x = UserData4(j) ElseIf BufferIndex = 4 Then x = UserData5(j) ElseIf BufferIndex = 5 Then x = UserData6(j) ElseIf BufferIndex = 6 Then x = UserData7(j) ElseIf BufferIndex = 7 Then x = UserData8(j) End If j = j + 2 If x < 0 Then x = 65535 + x End If Sum = Sum + x Next k Sum = Sum / bd.reclength Print #f1, Sum Next i Close #f1 ' Average Channel B Sum = 0 f1 = FreeFile Open FB For Append As #f1 j = 1 For i = 1 To RecordsPerBuffer Sum = 0 For k = 1 To bd.reclength If BufferIndex = 0 Then x = UserData1(j) ElseIf BufferIndex = 1 Then x = UserData2(j) ElseIf BufferIndex = 2 Then x = UserData3(j) ElseIf BufferIndex = 3 Then x = UserData4(j) ElseIf BufferIndex = 4 Then x = UserData5(j) ElseIf BufferIndex = 5 Then x = UserData6(j) ElseIf BufferIndex = 6 Then x = UserData7(j) ElseIf BufferIndex = 7 Then x = UserData8(j) End If j = j + 2 If x < 0 Then x = 65535 + x End If Sum = Sum + x Next k Sum = Sum / bd.reclength Print #f1, Sum Next i Close #f1 If status = 512 Then If BufferIndex = 0 Then status = AlazarPostAsyncBuffer(h, UserData1(0), BytesPerBuffer) ElseIf BufferIndex = 1 Then status = AlazarPostAsyncBuffer(h, UserData2(0), BytesPerBuffer) ElseIf BufferIndex = 2 Then ATS-SDK Software Manual v5.6.0 57

Else End If status = AlazarPostAsyncBuffer(h, UserData3(0), BytesPerBuffer) ElseIf BufferIndex = 3 Then status = AlazarPostAsyncBuffer(h, UserData4(0), BytesPerBuffer) ElseIf BufferIndex = 4 Then status = AlazarPostAsyncBuffer(h, UserData5(0), BytesPerBuffer) ElseIf BufferIndex = 5 Then status = AlazarPostAsyncBuffer(h, UserData6(0), BytesPerBuffer) ElseIf BufferIndex = 6 Then status = AlazarPostAsyncBuffer(h, UserData7(0), BytesPerBuffer) ElseIf BufferIndex = 7 Then status = AlazarPostAsyncBuffer(h, UserData8(0), BytesPerBuffer) End If If status <> 512 Then stopflag = True ErrorFlag = True GoTo GetOut End If Command1.Caption = Format(BuffersCompleted + 1) + " times completed" BufferIndex = BufferIndex + 1 Exit Do DoEvents Loop GetOut: LoopNumber = LoopNumber + 1 DoEvents If Not ErrorFlag Then Command1.Caption = "Completed without error" Else Command1.Caption = "Completed with error" Text1.Text = status status = AlazarAbortAsyncRead(h) End If Loop While (stopflag <> True) status = AlazarAbortAsyncRead(h) End Sub Private Sub Form_Unload(Cancel As Integer) Dim h As Variant h = AlazarGetSystemHandle(1) status = AlazarAbortAsyncRead(h) stopflag = True End Sub Private Sub Form_Load() Text1.Text = " " End Sub Private Sub StopButton_Click() 58 ATS-SDK Software Manual v5.6.0

stopflag = True End Sub ATS-SDK Software Manual v5.6.0 59

Reviewing A Traditional VB Sample Program Let us review the AC2DISKVB sample program that is supplied with ATS-SDK. AC2DISKVB is a Visual BASIC program that performs the following tasks: 1. Find out how many AlazarTech boards are there in the computer and if any of them are configured as a Master/Slave system. If no boards are found, exit gracefully. 2. For the first board found, open the board. a. ATS driver will return a unique handle for each board. i. If no boards are found, do nothing. ii. If boards are found, allocate a buffer large enough to hold the acquired data. This is the buffer that ATS-SDK will DMA into. Note that this buffer MUST be larger than the amount to be transferred by at least 16 samples, i.e. 32 bytes for 12 and 14 bit digitizers and 16 bytes for 8 bit digitizers. b. Use the handle to set up the board in a known condition c. Start a data acquisition session by calling the StartCapture routine on the Master (first) board of System 1 d. Wait until data acquisition is finished e. Read the data captured on each of the two channels f. Save the data captured to a disk file 3. Exit the application While this is a very simple application, it shows how you can use the ATS-SDK to acquire signals and process them in your own environment. The following pages show the source code for this simple, yet powerful sample program. 60 ATS-SDK Software Manual v5.6.0

'============================================================================= ' ' AlazarTech Inc ' ' File Name: ' ' Ac2DskVB ' ' Copyright (c) 2003 AlazarTech Inc. All Rights Reserved. ' Unpublished - rights reserved under the Copyright laws of the ' United States And Canada. ' ' This product contains confidential information and trade secrets ' of AlazarTech Inc. Use, disclosure, or reproduction is ' prohibited without the prior express written permission of AlazarTech ' Inc ' ' Description: ' ' Sample Application that shows how to perform a sample acquisition ' and view the data in the application development environment (ADE). ' ' This program serves as a sample that can be used to create a data ' acquisition console unit. '============================================================================= Private Sub C_Click() Dim h As Variant Dim status As Long Dim b As Long Dim Major As Byte Dim Minor As Byte Dim Rev As Byte Dim MemSize As Long Dim SampleSize As Byte Dim Channel As Byte Dim NumOfBoards As Integer Dim NumOfSystems As Integer Dim RecordToRead As Long Dim i As Integer Dim j As Integer Dim ChanA_Data(4096) As Byte Dim ChanB_Data(4096) As Byte Dim bd As BoardDef RecordToRead = 1 NumOfBoards = AlazarBoardsInSystemBySystemID(1) If NumOfBoards < 1 Then Stop End If status = AlazarGetCPLDVersion(h, Major, Minor) status = AlazarGetSDKVersion(Major, Minor, Rev) status = AlazarGetDriverVersion(Major, Minor, Rev) Command1.Caption = "Acquisition Started" bd.recordcount = 1 bd.reclength = 4096 bd.predepth = 512 bd.clocksource = INTERNAL_CLOCK bd.clockedge = CLOCK_EDGE_RISING bd.samplerate = SAMPLE_RATE_50MSPS bd.couplingchana = AC_COUPLING bd.inputrangechana = INPUT_RANGE_PM_1_V bd.inputimpedchana = IMPEDANCE_1M_OHM bd.couplingchanb = AC_COUPLING bd.inputrangechanb = INPUT_RANGE_PM_1_V ATS-SDK Software Manual v5.6.0 61

bd.inputimpedchanb = IMPEDANCE_1M_OHM bd.triengoperation = TRIG_ENGINE_OP_J_OR_K bd.triggerengine1 = TRIG_ENGINE_J bd.trigengsource1 = TRIG_CHAN_A bd.trigengslope1 = TRIGGER_SLOPE_POSITIVE bd.trigenglevel1 = 128 bd.triggerengine2 = TRIG_ENGINE_K bd.trigengsource2 = TRIG_DISABLE bd.trigengslope2 = TRIGGER_SLOPE_POSITIVE bd.trigenglevel2 = 128 For i = 1 To NumOfBoards h = AlazarGetBoardBySystemID(1, i) status = AlazarSetRecordCount(h, bd.recordcount) status = AlazarSetRecordSize(h, bd.predepth, bd.reclength - bd.predepth) status = AlazarSetCaptureClock(h, bd.clocksource, bd.samplerate, bd.clockedge, 0) Channel = CHANNEL_A status = AlazarInputControl(h, Channel, bd.couplingchana, bd.inputrangechana, bd.inputimpedchana) Channel = CHANNEL_B status = AlazarInputControl(h, Channel, bd.couplingchanb, bd.inputrangechanb, bd.inputimpedchanb) status = AlazarSetTriggerOperation(h, bd.triengoperation, bd.triggerengine1, bd.trigengsource1, bd.trigengslope1, bd.trigenglevel1, bd.triggerengine2, bd.trigengsource2, bd.trigengslope2, bd.trigenglevel2) 'create a 5 second time out delay status = AlazarSetTriggerTimeOut(h, 500000) Next i h = AlazarGetBoardBySystemID(1, 1) status = AlazarStartCapture(h) While (AlazarBusy(h)) Wend Command1.Caption = "Saving captured data to files" For board = 1 To NumOfBoards h = AlazarGetBoardBySystemID(1, board) status = AlazarRead(h, CHANNEL_A, ChanA_Data(0), 1, RecordToRead, 0, bd.reclength) status = AlazarRead(h, CHANNEL_B, ChanB_Data(0), 1, RecordToRead, 0, bd.reclength) FileName = "ChanA" + LTrim$(Str$(board)) + ".csv" j = FreeFile Open FileName For Output As #j For i = 1 To bd.reclength Print #j, Str$(ChanA_Data(i)) + "," Next i Close #j FileName = "ChanB" + LTrim$(Str$(board)) + ".csv" j = FreeFile Open FileName For Output As #j For i = 1 To bd.reclength Print #j, Str$(ChanB_Data(i)) + "," Next i Close #j Next board Command1.Caption = "Acquisition Completed" End Sub 62 ATS-SDK Software Manual v5.6.0

Traditional API Description The following pages describe each of the Traditional API functions used by ATS-SDK. Calling conventions and return codes are listed and dependencies are explained. ATS-SDK Software Manual v5.6.0 63

AlazarAbortCapture C/C++ Prototype RETURN_CODE AlazarAbortCapture ( HANDLE h); Visual BASIC Prototype Public Declare Function AlazarAbortCapture Lib "ATSApiVB.dll" (ByVal h As Integer) As Long Description: Force the device to abort the current capture. Input: H A handle to the device. Output: None. Return: Refer to Return code values listed in API RETURN CODE VALUES 64 ATS-SDK Software Manual v5.6.0

AlazarAutoCalibrate C/C++ Prototype RETURN_CODE AlazarAutoCalibrate ( HANDLE h); Visual BASIC Prototype Public Declare Function AlazarAutoCalibrate Lib "ATSApiVB.dll" (ByVal h As Integer) As Long Description: Perform a board specific calibration. Note that it is possible that the digitizer you are using does not support auto-calibration. In that case, an appropriate message will be returned. Input: h A handle to the device. Output: None. Return: Refer to Return code values listed in API RETURN CODE VALUES ATS-SDK Software Manual v5.6.0 65

AlazarBoardsFound C/C++ Prototype U32 AlazarBoardsFound (); Visual BASIC Prototype Public Declare Function AlazarBoardsFound Lib "ATSApiVB.dll" () As Long Description: Determine the total number of boards that are installed. Input: None. Output: None. Return: U32 The number of boards found 66 ATS-SDK Software Manual v5.6.0

AlazarBoardsInSystemByHandle C/C++ Prototype U32 AlazarBoardsInSystemByHandle (HANDLE h); Visual BASIC Prototype Public Declare Function AlazarBoardsInSystemByHandle Lib "ATSApiVB.dll" (ByVal h As Integer) As Integer Description: Retrieve the number of boards in a system identified by its System handle. For independent boards, the value returned would be 1, whereas for Master/Slave systems, the return value will be equal to the number of boards in that system. Input: h System identification handle Output: None Return: U32 The number of boards found in a particular system ATS-SDK Software Manual v5.6.0 67

AlazarBoardsInSystemBySystemID C/C++ Prototype U32 AlazarBoardsInSystemBySystemID (U32 sid); Visual BASIC Prototype Public Declare Function AlazarBoardsInSystemBySystemID Lib "ATSApiVB.dll" (ByVal sid As Integer) As Integer Description: Retrieve the number of boards in a system identified by its System ID. For independent boards, the value returned would be 1, whereas for Master/Slave systems, the return value will be equal to the number of boards in that system. Input: Sid System identification number Output: None Return: U32 The number of boards found in a particular system 68 ATS-SDK Software Manual v5.6.0

AlazarBusy C/C++ Prototype U32 AlazarBusy (HANDLE h); Visual BASIC Prototype Public Declare Function AlazarBusy Lib "ATSApiVB.dll" (ByVal h As Integer) As Long Description: Query the device s busy status. This is usually used in a while loop after a call to AlazarStartCapture to check if the acquisition is finished. Note that AlazarBusy will not return a 0 (not busy) until all records have been captured. Input: H A handle to the device. Output: None. Return: 1 The board is busy. 0 The board is not busy. ATS-SDK Software Manual v5.6.0 69

AlazarClose NOT RECOMMENDED FOR USE IN NEW DESIGNS C/C++ Prototype void AlazarClose ( HANDLE h); Visual BASIC Prototype Public Declare Sub AlazarClose Lib "ATSApiVB.dll" (ByVal h As Integer) Description: Relinquish the handle for the device. This function may only be used in applications that are written for single board digitizer systems and will never need to handle multiple digitizers. Input: h A handle to the device that was previously opened. Output: None. Return: None. 70 ATS-SDK Software Manual v5.6.0

AlazarForceTrigger C/C++ Prototype RETURN_CODE AlazarForceTrigger ( HANDLE h); Visual BASIC Prototype Public Declare Function AlazarForceTrigger Lib "ATSApiVB.dll" (ByVal h As Integer) As Long Description: Force the device to perform a software trigger. Input: H A handle to the device. Output: None. Return: Refer to Return code values listed in API RETURN CODE VALUES ATS-SDK Software Manual v5.6.0 71

AlazarGetBoardBySystemHandle C/C++ Prototype HANDLE AlazarGetBoardBySystemHandle (HANDLE h, U32 brdnum); Visual BASIC Prototype Public Declare Function AlazarGetBoardBySystemHandle Lib "ATSApiVB.dll" (ByVal h As Integer, ByVal brdnum as Integer) As Integer Description: Retrieve the board handle of a given board in one of the systems. Input: h System identification handle brdnum Board identification number within the system. Master is always board number 1 in a Master/Slave system Output: None Return: HANDLE The handle of the given board 72 ATS-SDK Software Manual v5.6.0

AlazarGetBoardBySystemID C/C++ Prototype HANDLE AlazarGetBoardBySystemID (U32 sid, U32 brdnum); Visual BASIC Prototype Public Declare Function AlazarGetBoardBySystemID Lib "ATSApiVB.dll" (ByVal sid As Integer, ByVal brdnum as Integer) As Integer Description: Retrieve the board handle of a given board in one of the systems. Input: sid System identification number brdnum Board identification number within the system. Master is always board number 1 in a Master/Slave system Output: None Return: HANDLE The handle of the given board ATS-SDK Software Manual v5.6.0 73

AlazarGetBoardKind C/C++ Prototype U32 AlazarGetBoardKind (HANDLE h); Visual BASIC Prototype Public Declare Function AlazarGetBoardKind Lib "ATSApiVB.dll" (ByVal h As Integer) As Integer Description: This function allows a user application to determine the type of device associated with a board handle. Input: h - Board identification handle Output: None Return: Return the ALAZAR_BOARDTYPES of the device. ATS850 = 1, ATS310 = 2, ATS330 = 3, ATS460 = 7, ATS860 = 8, ATS660 = 9, ATS9462 = 11. typedef enum BoardTypes { ATS_NONE, // NO BOARD WAS FOUND ATS850, ATS310, ATS330, ATS855, ATS315, ATS335, ATS460, ATS860, ATS660, ATS665, ATS9462, ATS_LAST } ALAZAR_BOARDTYPES; 74 ATS-SDK Software Manual v5.6.0

AlazarGetChannelInfo C/C++ Prototype RETURN_CODE AlazarGetChannelInfo ( HANDLE h, U32 *MemSize, U8 *SampleSize); Visual BASIC Prototype Public Declare Function AlazarGetChannelInfo Lib "ATSApiVB.dll" ( ByVal h As Integer, ByRef MemSize As Long, ByRef SampleSize As Byte) As Long Description: This routine can be used to determine then memory size per channel and sample size. Input: h - Board identification handle MemSize - Pointer to get the acquisition memory size per channel of the device SampleSize - Pointer to get the number of bits that comprises one sample Output: None. Return: This routine will return ApiSuccess unless an invalid board handle was provided. ATS-SDK Software Manual v5.6.0 75

AlazarGetCPLDVersion C/C++ Prototype RETURN_CODE AlazarGetCPLDVersion ( HANDLE h, U8 *Major, U8 *Minor); Visual BASIC Prototype Public Declare Function AlazarGetCPLDVersion Lib "ATSApiVB.dll" ( ByVal h As Integer, ByRef Major As Byte, ByRef Minor As Byte) As Long Description: Retrieve the version number of the on-board CPLD. Unless you are working on an extremely advanced application that uses custom FPGAs, you will not have to use this routine. Input: h A handle to the device. Major Pointer to an unsigned char to hold the major number. Minor Pointer to an unsigned char to hold he minor number. Output: None. Return: Refer to Return code values listed in API RETURN CODE VALUES 76 ATS-SDK Software Manual v5.6.0

AlazarGetDriverVersion C/C++ Prototype RETURN_CODE AlazarGetDriverVersion ( U8 *Major, U8 *Minor, U8 *Revision); Visual BASIC Prototype Public Declare Function AlazarGetDriverVersion Lib "ATSApiVB.dll" ( ByRef Major As Byte, ByRef Minor As Byte, ByRef Revision As Byte) As Long Description: Used to obtain the Driver version. (Very useful for troubleshooting purposes) Input: Major - Pointer to an unsigned byte to hold the major version number. Minor Pointer to an unsigned byte to hold the minor version number. Revision - Pointer to an unsigned byte to hold the revision number. Output: None. Return: Refer to Return code values listed in API RETURN CODE VALUES ATS-SDK Software Manual v5.6.0 77

AlazarGetMaxRecordsCapable C/C++ Prototype RETURN_CODE AlazarGetMaxRecordsCapable( HANDLE h, U32 RecordLength, U32 *num); Visual BASIC Prototype Public Declare Function AlazarGetMaxRecordsCapable Lib "ATSApiVB.dll" ( ByVal h As Integer, ByVal RecordLength As Long, ByRef num As Long) As Long Description: This API is used to calculate the number of records that can be captured on the devices on board memory. Input: Output: Return: h - Handle to the device. RecordLength Record Size in Samples. num - Pointer to the maximum number of records that the device is capable of handling. ApiSuccessful or 512 signifies that the calculation is valid. ApiFailed or 513 signifies that at least on parameter is wrong. Note: This Api should not be used when operating in Auto DMA mode. 78 ATS-SDK Software Manual v5.6.0

AlazarGetParameter C/C++ Prototype RETURN_CODE AlazarGetParameter ( HANDLE h, U8 Channel, U32 Parameter, long *Value); Visual BASIC Prototype Public Declare Function AlazarGetParameter Lib "ATSApiVB.dll" ( ByVal h As Integer, ByVal Channel As Byte, ByVal Parameter As Long, ByRef Value As Long) As Long Description: This Api can be used to retrieve individual attributes and variables from the device. It is only used for signed values. Input: h A handle to the device. Channel CHANNEL_A, CHANNEL_B, or 0. Parameter defined constant for the attribute Output: Value the driver or dll attributes value. Return: Refer to Return code values listed in API RETURN CODE VALUES Parameter Constants to be used in this API routine: #define GET_ASYNC_BUFFERS_PENDING 0x10000050UL This parameter is particularly useful for SequentialBuffers AsyncDMA mechanism (used by LabVIEW, for example), in which the DLL manages all buffers internally. This call returns the total number of DMA buffers currently managed by the DLL. It is the difference between the number of buffers started by calling AlazarPostAsyncBuffer, and the number of buffers completed by calling AlazarWaitAsyncBufferComplete. The buffers can either be the "empty" state if they are waiting to be filled with data, or the "full" state once they have been filled with sample data. Note that if the AlazarBeforeAsyncRead is called with the ADMA_ALLOC_BUFFERS flag (SequentialBuffers mechanism), then the total number of buffers managed by the DLL should always be equal ATS-SDK Software Manual v5.6.0 79

to the BUFFER_COUNT value, which is 64 by default, or the number of buffers remaining in the acquisition, whichever is less. Channel variable must be set to 0. #define GET_ASYNC_BUFFERS_PENDING_FULL 0x10000051UL This parameter is particularly useful for SequentialBuffers AsyncDMA mechanism (used by LabVIEW, for example), in which the DLL manages all buffers internally. This call returns the number of DMA buffers where the DMA transfer into the buffer is complete. The value should be zero before calling AlazarStartCapture, and equal to the total number of DMA buffers currently managed by the DLL if an ApiBufferOverflow error occurs. Channel variable must be set to 0. #define GET_ASYNC_BUFFERS_PENDING_EMPTY 0x10000052UL This parameter is particularly useful for SequentialBuffers AsyncDMA mechanism (used by LabVIEW, for example), in which the DLL manages all buffers internally. This call returns the number of DMA buffers where the DMA transfer into the buffer is not complete. The value should be equal to the total number of DMA buffers before calling AlazarStartCapture, and zero if an ApiBufferOverflow error occurs. Channel variable must be set to 0. #define SETGET_ASYNC_BUFFCOUNT 0x10000040UL This parameter is particularly useful for SequentialBuffers AsyncDMA mechanism (used by LabVIEW, for example), in which the DLL manages all buffers internally. This call allows the user to retrieve the number of internal buffers used by the DLL when using the Asychronous AutoDMA methodologies. A default value of 64 is used however the user may choose to lower it. Channel variable must be set to 0. 80 ATS-SDK Software Manual v5.6.0

AlazarGetParameterUL (for future use) C/C++ Prototype RETURN_CODE AlazarGetParameterUL ( HANDLE h, U8 Channel, U32 Parameter, U32 *Value); Visual BASIC Prototype Public Declare Function AlazarGetParameterUL Lib "ATSApiVB.dll" ( ByVal h As Integer, ByVal Channel As Byte, ByVal Parameter As Long, ByRef Value As Long) As Long Description: This Api can be used to get individual attributes and variables from the device. It is only used for unsigned values. Input: h A handle to the device. Channel CHANNEL_A, CHANNEL_B, or 0. Output: Value the driver or dll attributes value. Return: Refer to Return code values listed in API RETURN CODE VALUES Parameter Constants to be used in this API routine: (AT PRESENT NONE AVAILABLE) ATS-SDK Software Manual v5.6.0 81

AlazarGetSDKVersion C/C++ Prototype RETURN_CODE AlazarGetSDKVersion( U8 *Major, U8 *Minor, U8 *Revision); Visual BASIC Prototype Public Declare Function AlazarGetSDKVersion Lib "ATSApiVB.dll" ( ByRef Major As Byte, ByRef Minor As Byte, ByRef Revision As Byte) As Long Description: Used to obtain the SDK (DLL) version. (Very useful for troubleshooting purposes) Input: Major - Pointer to an unsigned byte to hold the major version number. Minor Pointer to an unsigned byte to hold the minor version number. Revision - Pointer to an unsigned byte to hold the revision number Output: None. Return: Refer to Return code values listed in API RETURN CODE VALUES 82 ATS-SDK Software Manual v5.6.0

AlazarGetStatus C/C++ Prototype U32 AlazarGetStatus(HANDLE h); Visual BASIC Prototype Public Declare Function AlazarGetStatus Lib "ATSApiVB.dll" ( ByVal h As Integer) As Long Description: Used to obtain the channel status, in a bit wise OR ed manner. Input: Return: h - Handle to the device. 0x00000001 - At least 1 trigger occurred. 0x00000002 - Channel A input went beyond the limits of its input range for at least one sample during the acquisition. 0x00000004 - Channel B input went beyond the limits of its input range for at least one sample during the acquisition 0x00000008 PLL locked (ATS660 and ATS9462 Only) 0xFFFFFFFF Error No value is valid. Note: This functionality is only present on the ATS460, ATS660, ATS9462 and ATS860 devices. ATS-SDK Software Manual v5.6.0 83

AlazarGetSystemHandle C/C++ Prototype HANDLE AlazarGetSystemHandle (U32 sid); Visual BASIC Prototype Public Declare Function AlazarGetSystemHandle Lib "ATSApiVB.dll" (ByVal sid As Integer) As Integer Description: Retrieve the handle of the primary board in the system. For Master/Slave systems, this would be the Master board, whereas for independent boards, it would be the handle of the board itself. Input: Sid System identification number Output: None Return: HANDLE The handle of the primary board in the system 84 ATS-SDK Software Manual v5.6.0

AlazarGetTriggerAddress C/C++ Prototype RETURN_CODE AlazarGetTriggerAddress ( HANDLE h, U32 Record, U32 *TriggerAddress, U32 *TimeStampHighPart, U32 *TimeStampLowPart); Visual BASIC Prototype Public Declare Function AlazarGetTriggerAddress Lib "ATSApiVB.dll" ( ByVal h As Integer, ByVal Record As Long, ByRef TriggerAddress As Long, ByRef TimeStampHighPart As Long, ByRef TimeStampLowPart As Long) As Long Description: Retrieve the trigger address and timestamp for a given captured record. Note that while trigger address has very little value for a user application, this API routine is important in that it retrieves the 40-bit time stamp for a particular trigger event. Input: h A handle to the device. Record The record of interest. The first record is 1. TriggerAddress - Pointer to an unsigned long to hold the trigger address. This value is used internally and has very little use for user applications. TimeStampHighPart Pointer to an unsigned long to hold the top 32 bits of the TimeStamp. TimeStampLowPart - Pointer to an unsigned long to hold the lower 8 bits of the TimeStamp. Output: None. Return: Refer to Return code values listed in API RETURN CODE VALUES ATS-SDK Software Manual v5.6.0 85

AlazarGetWhoTriggeredBySystemHandle C/C++ Prototype U32 AlazarGetWhoTriggeredBySystemHandle (HANDLE systemhandle, U32 brdnum, U32 recnum); Visual BASIC Prototype Public Declare Function AlazarGetWhoTriggeredBySystemHandle Lib "ATSApiVB.dll" (ByVal systemhandle As Integer, ByVal brdnum as Integer, ByVal recnum as Integer) As Integer Description: This API function is used to determine the device and channel that had triggered a system to capture. Note that this API routine will not work with ATS850 version 1.2 hardware. Version 1.3 and higher version number of ATS850 are fully supported, as are all versions of ATS330 and ATS310. Input: HANDLE systemhandle - Handle used to identify the system U32 brdnum Board number within the system U32 recnum - record number for which the query is being made Output: None Return: NEITHER = 0, This board did not cause the system to trigger Channel A = 1, Channel A on this board caused the system to trigger Channel B = 2, Channel B on this board caused the system to trigger External = 3, EXTernal Trigger input on this board caused the system to trigger A AND B = 4, Both Channel A and Channel B on this board caused the system to trigger A AND Ext = 5, Both Channel A and EXTernal Trigger input on this board caused the system to trigger B And Ext = 6, Both Channel B and EXTernal Trigger input on this board caused the system to trigger Timeout = 7, A timeout event caused the system to trigger 86 ATS-SDK Software Manual v5.6.0

AlazarGetWhoTriggeredBySystemID C/C++ Prototype U32 AlazarGetWhoTriggeredBySystemID (U32 sid, U32 brdnum, U32 recnum); Visual BASIC Prototype Public Declare Function AlazarGetWhoTriggeredBySystemID Lib "ATSApiVB.dll" (ByVal sid As Integer, ByVal brdnum as Integer, ByVal recnum as Integer) As Integer Description: This API function is used to determine the device and channel that had triggered a system to capture. Note that this API routine will not work with ATS850 version 1.2 hardware. Version 1.3 and higher version number of ATS850 are fully supported, as are all versions of ATS330 and ATS310. Input: U32 sid System Identification number U32 brdnum Board number within the system U32 recnum - record number for which the query is being made Output: None Return: NEITHER = 0, This board did not cause the system to trigger Channel A = 1, Channel A on this board caused the system to trigger Channel B = 2, Channel B on this board caused the system to trigger External = 3, EXTernal Trigger input on this board caused the system to trigger A AND B = 4, Both Channel A and Channel B on this board caused the system to trigger A AND Ext = 5, Both Channel A and EXTernal Trigger input on this board caused the system to trigger B And Ext = 6, Both Channel B and EXTernal Trigger input on this board caused the system to trigger Timeout = 7, A timeout event caused the system to trigger ATS-SDK Software Manual v5.6.0 87

AlazarHyperDisp C/C++ Prototype RETURN_CODE AlazarHyperDisp ( HANDLE h, void *Buffer, U32 BufferSize, U8 *ViewBuffer, U32 ViewBufferSize, U32 NumOfPixels, U32 Option, U32 ChannelSelect, U32 Record, long TransferOffset, U32 *error ); Visual BASIC Prototype - NOT SUPPORTED Description: This routine is used to calculate the envelope of the signal captured in on-board memory using the ATS460 data processing engine. When Option is set to 1, then the HyperDisp processing is performed on the data contained in the acquisition memory of the device. The results are returned in ViewBuffer. At present only Option 1 is defined. Input: h - Board identification handle BufferSize RESERVED for future use. ViewBufferSize Number of U16 elements that makeup ViewBuffer. NumOfPixels The number of HyperDisp data points that will be contained in ViewBuffer. Option 1: Perform HyperDisp operation using the data in the acquisition memory. 2: RESERVED for future use. ChannelSelect CHANNEL_A or CHANNEL_B for single channel operation. Record Record number to retrieve TransferOffset Transfer offset relative to the Trigger point for each record. Output: Buffer RESERVED for future use. ViewBuffer Pointer to a buffer that will contain the HyperDisp data points. 88 ATS-SDK Software Manual v5.6.0

error RESERVED for future use. Return: Refer to the Return code values listed in API RETURN CODES VALUES ATS-SDK Software Manual v5.6.0 89

AlazarInputControl C/C++ Prototype RETURN_CODE AlazarInputControl ( HANDLE h, U8 Channel, U32 Coupling, U32 InputRange, U32 Impedance); Visual BASIC Prototype Public Declare Function AlazarInputControl Lib "ATSApiVB.dll" ( ByVal h As Integer, ByVal Channel As Byte, ByVal Coupling As Long, ByVal InputRange As Long, ByVal Impedance As Long) As Long Description: Configure an input channel for acquisition. Input: h A handle to the device. Channel Refer to table below. Coupling Refer to table below. InputRange Refer to table below. Impedance Refer to table below. Output: None. Return: Refer to Return code values listed in API RETURN CODE VALUES Constants to be used in this API routine: Impedance Values #define IMPEDANCE_1M_OHM #define IMPEDANCE_50_OHM 0x00000001UL 0x00000002UL Input Ranges #define INPUT_RANGE_PM_20_MV 0x00000001UL #define INPUT_RANGE_PM_40_MV 0x00000002UL #define INPUT_RANGE_PM_50_MV 0x00000003UL #define INPUT_RANGE_PM_80_MV 0x00000004UL #define INPUT_RANGE_PM_100_MV 0x00000005UL #define INPUT_RANGE_PM_200_MV 0x00000006UL #define INPUT_RANGE_PM_400_MV 0x00000007UL #define INPUT_RANGE_PM_500_MV 0x00000008UL #define INPUT_RANGE_PM_800_MV 0x00000009UL #define INPUT_RANGE_PM_1_V 0x0000000AUL 90 ATS-SDK Software Manual v5.6.0

#define INPUT_RANGE_PM_2_V #define INPUT_RANGE_PM_4_V #define INPUT_RANGE_PM_5_V #define INPUT_RANGE_PM_8_V #define INPUT_RANGE_PM_10_V #define INPUT_RANGE_PM_20_V #define INPUT_RANGE_PM_40_V #define INPUT_RANGE_PM_16_V #define INPUT_RANGE_HIFI Coupling Values #define AC_COUPLING #define DC_COUPLING Channel Selection #define CHANNEL_A #define CHANNEL_B 0x0000000BUL 0x0000000CUL 0x0000000DUL 0x0000000EUL 0x0000000FUL 0x00000010UL 0x00000011UL 0x00000012UL 0x00000020UL 0x00000001UL 0x00000002UL 0x00000001UL 0x00000002UL ATS-SDK Software Manual v5.6.0 91

AlazarNumOfSystems C/C++ Prototype U32 AlazarNumOfSystems (); Visual BASIC Prototype Public Declare Function AlazarNumOfSystems Lib "ATSApiVB.dll" () As Integer Description: Retrieve the number of ATS class systems in the computer. A system is defined as a set of boards that are guaranteed to trigger together. For example, a set of Master/Slave boards is considered to be one system. Similarly, an Independent digitizer is also a system. Input: None Output: None Return: U32 Total number of systems configured in the computer 92 ATS-SDK Software Manual v5.6.0

AlazarOEMDownLoadFPGA C/C++ Prototype RETURN_CODE AlazarOEMDownLoadFPGA( HANDLE h, char *FileName, U32 *error); Visual BASIC Prototype Public Declare Function AlazarOEMDownLoadFPGA Lib "ATSApiVB.dll" ( ByVal h As Integer, ByRef FileName As Any, ByRef error As Long) As Integer Description: This routine can be used to download a custom FPGA image. The full path and file name is expected. Input: h Handle of the device FileName Full path and filename of Custom FPGA image Output: error This routine will return ApiSuccess if the download was successful otherwise it will return ApiFailed. Return: Refer to the Return code values listed in API RETURN CODES VALUES ATS-SDK Software Manual v5.6.0 93

AlazarOpen NOT RECOMMENDED FOR USE IN NEW DESIGNS C/C++ Prototype HANDLE AlazarOpen (char *BoardNameID); Visual BASIC Prototype Public Declare Function AlazarOpen Lib "ATSApiVB.dll" (ByVal name As String) As Integer Description: Retrieve a handle to an existing board. This routine also initializes the device. This function may only be used in applications that are written for single board digitizer systems and will never need to handle multiple digitizers. Input: BoardNameID - The name of the device. Use the following format: ATS850-0, ATS850-1 Output: None. Return: h A handle to the device that will be used as an input parameter to all the API functions. 94 ATS-SDK Software Manual v5.6.0

AlazarParseFPGAName C/C++ Prototype RETURN_CODE AlazarParseFPGAName ( const char *FullName, char *Name, U32 *Type, U32 *MemSize, U32 *MajVer, U32 *MinVer, U32 *MajRev, U32 *MinRev, U32 *error); Visual BASIC Prototype Public Declare Function AlazarParseFPGAName Lib "ATSApiVB.dll" ( ByRef FullPath As Any, ByRef Name As Any, ByRef Type As Long, ByRef MemSize As Long, ByRef MajVer As Long, ByRef MinVer As Long, ByRef MajRev As Long, ByRef MinRev As Long, ByRef error As Long) As Long Description: This routine is a helper function that can be used to decipher an FPGA name. The FullName may or may not include the complete directory path. If this routine fails it will return error=626, indicating that the filename is invalid. Input: FullName The complete filename. Output: Name FPGA name without the complete path Type Type of board that this image supports MemSize Amount of memory that the board must be populated with MajVer Hardware major revision number MinVer Hardware minimum revision number MajRev Image major revision number MinRev Image minimum revision number error - If the image does not exist the API will return ApiFailed and error will be set to 626. Otherwise, the API will return ApiSuccess. Return: Refer to the Return code values listed in API RETURN CODES VALUES ATS-SDK Software Manual v5.6.0 95

AlazarQueryCapability C/C++ Prototype RETURN_CODE AlazarQueryCapability ( HANDLE h, U32 Request, U32 Value, U32 *retvalue); Visual BASIC Prototype Public Declare Function AlazarQueryCapability Lib "ATSApiVB.dll" ( ByVal h As Integer, ByVal Request As Long, ByVal Value As Long, ByRef retvalue As Long) As Long Description: This API is used to query some of the device parameters. The supported parameters include: the device serial number, the latest calibration date, the on-board memory per channel in samples, the FPGA ASoPC, the number of data bits for one sample and the various calibration dates. At present a user cannot set the Value parameter; only the retvalue parameter is valid. Input: h A handle to the device. Request can be set to any of the Request Constant values listed below. Value FOR FUTURE USE. Output: retvalue a pointer to a U32 variable to which the driver populates the queried response. The date is returned in the DDMMYY format; where each digit represents a number. Example 41207 is 2007,December 04. Note that only 5 digits are present when the day is less than 10. Return: Refer to Return code values listed in API RETURN CODE VALUES Request Constants to be used in this API routine: #define GET_SERIAL_NUMBER 0x10000024UL Variable retvalue is populated with the device s serial number. For example, the serial number for an ATS9462 may be returned, as 900121.This feature exists for all AlazarTech devices. 96 ATS-SDK Software Manual v5.6.0

#define GET_FIRST_CAL_DATE 0x10000025UL The U32 pointed to by retvalue is populated with the first date the device was calibrated. The full date is returned in a numerical format as YYMMDD. #define GET_LATEST_CAL_DATE 0x10000026UL Variable retvalue is populated with the most recent date the device was calibrated. The full date is returned in a numerical format as YYMMDD. #define GET_LATEST_TEST_DATE 0x10000027UL Variable retvalue is populated with the most recent date the device was tested. The full date is returned in a numerical format as YYMMDD. #define GET_LATEST_CAL_DATE_MONTH 0x1000002DUL Variable retvalue is populated with the month field of the most recent date that the device was calibrated. The value is returned in a numerical format as MM. #define GET_LATEST_CAL_DATE_DAY 0x1000002EUL Variable retvalue is populated with the day field of the most recent date that the device was calibrated. The value is returned in a numerical format as DD. #define GET_LATEST_CAL_DATE_YEAR 0x1000002FUL Variable retvalue is populated with the year field of the most recent date that the device was calibrated. The value is returned in a numerical format as YY. #define MEMORY_SIZE 0x1000002AUL Variable retvalue is populated with the memory size as number of samples per channel. For example, for a board with 128Ms/channel, the value 134217728 is returned. This feature exists for all AlazarTech devices. #define BOARD_TYPE 0x1000002BUL Variable retvalue is populated with one of the board type constants, ALAZAR_BOARDTYPES, which are defined in AlazarApi.h. For example, for an ATS9462 device, the value 11 (ATS9462) is returned. This feature exists for all AlazarTech devices. ATS-SDK Software Manual v5.6.0 97

#define ASOPC_TYPE 0x1000002CUL Variable retvalue is populated with the FPGA signature for the device. This feature exists for all AlazarTech devices. A typical signature may be in the form 0xC024C460. #define GET_PCIE_LINK_SPEED 0x10000030UL Variable retvalue is populated with the PCIe bus speed. This feature only applies to ATS9462 and all future PCIExpress boards #define GET_PCIE_LINK_WIDTH 0x10000031UL Variable retvalue is populated with the PCIe buswidth that the AlazarTech device is connected to. This feature only applies to ATS9462 and all future PCIExpress boards 98 ATS-SDK Software Manual v5.6.0

AlazarRead C/C++ Prototype U32 AlazarRead ( HANDLE h, U32 Channel, void *Buffer, int ElementSize, long Record, long TransferOffset, U32 TransferLength); Visual BASIC Prototype Public Declare Function AlazarRead Lib "ATSApiVB.dll" ( ByVal h As Integer, ByVal Channel As Long, ByRef Buffer As Any, ByVal ElementSize As Integer, ByVal Record As Long, ByVal TransferOffset As Long, ByVal TransferLength As Long) As Long Description: This routine will read one record s data from the device. This routine uses scatter-gather DMA to transfer data from on-board acquisition memory to a logical buffer that can be used in a Windows program. It is the calling program s responsibility to allocate and declare an appropriate buffer. For 8-bit digitizers such as ATS850, the buffer should be declared as U8 or unsigned char or byte, whereas for 12, 14 and 16 bit digitizers, the buffer should be declared as U16 or unsigned short. Input: h A handle to the device. Channel Channel to retrieve data from. ElementSize 1 for 8 bit digitizers such as ATS850 and 2 for 12, 14 and 16 bit digitizers Record Record number to retrieve TransferOffset Reserved for future use TransferLength The record size in number of samples Output: Buffer Data retrieved from the device. Return: Refer to Return code values listed in API Return Code Values ATS-SDK Software Manual v5.6.0 99

AlazarResetTimeStamp C/C++ Prototype RETURN_CODE AlazarResetTimeStamp (HANDLE h, U32 resetflag); Visual BASIC Prototype Public Declare Function AlazarResetTimeStamp Lib "ATSApiVB.dll" ( ByVal h As Integer, ByVal resetflag As Long) As Integer Description: This API allows a user to manage the operation of the device's time-stamping circuitry. When this API is called prior to calling AlazarStartCapture( ) with TIMESTAMP_RESET_FIRSTTIME_ONLY, the acquisition circuitry will reset the timestamp counter on the first call to AlazarStartCapture but never again until AlazarResetTimeStamp is called again. Any additional calls made to API AlazarStartCapture( ) will not reset the timestamp counter. If this function is called with TIMESTAMP_RESET_ALWAYS, each call to API AlazarStartCapture( ) will reset the time-stamping circuitry to a value of 0. This is the default condition. In a multiple record acquisition setting, each record's time stamp will be relative to the first record captured after AlazarStartCapture( ) was called. Input: h - handle to the device resetflag - 0 or TIMESTAMP_RESET_FIRSTTIME_ONLY - 1 or TIMESTAMP_REST_ALWAYS Return: Note: ApiSuccessFul or 512 signifies success in setting the feature ApiFailed or 513 signifies that a wrong board type is being used. This functionality is only present on the ATS460, ATS660 and ATSS860 devices. 100 ATS-SDK Software Manual v5.6.0

AlazarSetBWLimit C/C++ Prototype RETURN_CODE AlazarSetBWLimit ( HANDLE h, U32 Channel, U32 enable); Visual BASIC Prototype Public Declare Function AlazarSetBWLimit Lib "ATSApiVB.dll" ( ByVal h As Integer, ByVal Channel As Long, ByVal enable As Long) As Long Description: Set the bandwidth for a given channel to either its maximum value or the reduced value. Only the ATS460, ATS660, ATS860 and ATS9462 support this functionality reduced bandwidth is approximately 20 MHz. Input: Output: None h - Board identification handle Channel - CHANNEL_A or CHANNEL_B enable - 0 = Maximum Bandwidth 1 = Bandwidth Limit active Return: Refer to the Return code values listed in API RETURN CODES VALUES ATS-SDK Software Manual v5.6.0 101

AlazarSetCaptureClock C/C++ Prototype RETURN_CODE AlazarSetCaptureClock ( HANDLE h, U32 Source, U32 Rate, U32 Edge, U32 Decimation); Visual BASIC Prototype Public Declare Function AlazarSetCaptureClock Lib "ATSApiVB.dll" ( ByVal h As Integer, ByVal Source As Long, ByVal Rate As Long, ByVal Edge As Long, ByVal Decimation As Long) As Long Description: Configure the capture clock circuitry. On the ATS660 and ATS9462, when the clock source is EXTERNAL_CLOCK_10MHz_REF, the summed value of (PLL_10MHZ_REF_100MSPS_BASE + Actual Frequency) must be used for the Rate parameter. Please view the examples listed below in the Sample Rate Values section. Input: h A handle to the device. Source Refer to table below (Clock Source). Rate Refer to table below (Sample Rate values). Edge Refer to table below (Clock Edge). Decimation Reserved for future use Output: None. Return: Refer to Return code values listed in API RETURN CODE VALUES Constants to be used in this API routine: Clock Source #define INTERNAL_CLOCK #define EXTERNAL_CLOCK #define FAST_EXTERNAL_CLOCK #define MEDIMUM_EXTERNAL_CLOCK #define MEDIUM_EXTERNAL_CLOCK #define SLOW_EXTERNAL_CLOCK 0x00000001UL 0x00000002UL 0x00000002UL 0x00000003UL //TYPO 0x00000003UL 0x00000004UL 102 ATS-SDK Software Manual v5.6.0

#define EXTERNAL_CLOCK_AC #define EXTERNAL_CLOCK_DC #define EXTERNAL_CLOCK_10MHz_REF 0x00000005UL //ATS660 0x00000006UL //ATS660 0x00000007UL //ATS660 Clock Edge #define CLOCK_EDGE_RISING #define CLOCK_EDGE_FALLING 0x00000000UL 0x00000001UL Sample Rate Values #define SAMPLE_RATE_1KSPS 0X00000001UL #define SAMPLE_RATE_2KSPS 0X00000002UL #define SAMPLE_RATE_5KSPS 0X00000004UL #define SAMPLE_RATE_10KSPS 0X00000008UL #define SAMPLE_RATE_20KSPS 0X0000000AUL #define SAMPLE_RATE_50KSPS 0X0000000CUL #define SAMPLE_RATE_100KSPS 0X0000000EUL #define SAMPLE_RATE_200KSPS 0X00000010UL #define SAMPLE_RATE_500KSPS 0X00000012UL #define SAMPLE_RATE_1MSPS 0X00000014UL #define SAMPLE_RATE_2MSPS 0X00000018UL #define SAMPLE_RATE_5MSPS 0X0000001AUL #define SAMPLE_RATE_10MSPS 0X0000001CUL #define SAMPLE_RATE_20MSPS 0X0000001EUL #define SAMPLE_RATE_25MSPS 0X00000021UL #define SAMPLE_RATE_50MSPS 0X00000022UL #define SAMPLE_RATE_100MSPS 0X00000024UL #define SAMPLE_RATE_125MSPS 0x00000025UL #define SAMPLE_RATE_160MSPS 0x00000026UL #define SAMPLE_RATE_180MSPS 0x00000027UL #define SAMPLE_RATE_200MSPS 0X00000028UL #define SAMPLE_RATE_250MSPS 0X0000002BUL #define SAMPLE_RATE_500MSPS 0X00000030UL #define SAMPLE_RATE_1GSPS 0x00000035UL // user define sample rate - used with External Clock #define SAMPLE_RATE_USER_DEF 0x00000040UL // ATS660 Specific Setting for using the PLL // // The base value can be used to create a PLL frequency // in a simple manner (from 105 MHz to 125 MHz) // // Ex. // 105 MHz = PLL_10MHZ_REF_100MSPS_BASE + 5000000 // 120 MHz = PLL_10MHZ_REF_100MSPS_BASE + 20000000 #define PLL_10MHZ_REF_100MSPS_BASE 0x05F5E100UL // ATS9462 Specific Setting for using the PLL // // The base value can be used to create a PLL frequency // in a simple manner (from 150 MHz to 180 MHz) // // Ex. // 150 MHz = PLL_10MHZ_REF_100MSPS_BASE + 50000000 // 175 MHz = PLL_10MHZ_REF_100MSPS_BASE + 75000000 ATS-SDK Software Manual v5.6.0 103

#define PLL_10MHZ_REF_100MSPS_BASE 0x05F5E100UL 104 ATS-SDK Software Manual v5.6.0

AlazarSetExternalTrigger C/C++ Prototype RETURN_CODE AlazarSetExternalTrigger ( HANDLE h, U32 Coupling, U32 Range); Visual BASIC Prototype Public Declare Function AlazarSetExternalTrigger Lib "ATSApiVB.dll" ( ByVal h As Integer, ByVal Coupling As Long, ByVal Range As Long) As Long Description: Configure the external trigger circuitry for full scale input range and coupling. Input: h A handle to the device. Coupling - Refer to table below (Coupling Values). Range - Refer to table below (External Trigger Range). Output: None. Return: Refer to Return code values listed in API RETURN CODE VALUES Constants to be used in this API routine: Coupling Values #define AC_COUPLING #define DC_COUPLING External Trigger Range #define ETR_DIV5 #define ETR_X1 #define ETR_5V #define ETR_1V 0x00000001UL 0x00000002UL 0x00000000UL 0x00000001UL 0x00000000UL 0x00000001UL ATS-SDK Software Manual v5.6.0 105

AlazarSetLED C/C++ Prototype U32 AlazarSetLED (HANDLE h, U32 state); Visual BASIC Prototype Public Declare Function AlazarSetLED Lib "ATSApiVB.dll" (ByVal h As Integer, ByVal state as Integer) As Integer Description: Turn the front panel LED on ATS class digitizers on or off. Input: Output: None h Board identification handle state A value of 0 turns the LED off and 1 turns it on. Return: ApiSuccess 106 ATS-SDK Software Manual v5.6.0

AlazarSetParameter C/C++ Prototype RETURN_CODE AlazarSetParameter ( HANDLE h, U8 Channel, U32 Parameter, long Value); Visual BASIC Prototype Public Declare Function AlazarInputControl Lib "ATSApiVB.dll" ( ByVal h As Integer, ByVal Channel As Byte, ByVal Parameter As Long, ByVal Value As Long) As Long Description: This Api can be used to set individual attributes and variables from the device. It is only used for signed values. Input: h A handle to the device. Channel CHANNEL_A, CHANNEL_B, or 0. Parameter defined constant for the attribute Value attribute setting for the Parameter Output: None. Return: Refer to Return code values listed in API RETURN CODE VALUES Parameter Constants to be used in this API routine: #define SETGET_ASYNC_BUFFCOUNT 0x10000040UL This parameter is particularly useful for SequentialBuffers AsyncDMA mechanism (used by LabVIEW, for example), in which the DLL manages all buffers internally. This call allows the user to modify the number of internal buffers used by the DLL when using the Asychronous AutoDMA methodologies. A default value of 64 is used however the user may choose to lower it. Channel variable must be set to 0. ATS-SDK Software Manual v5.6.0 107

AlazarSetParamaterUL (for future use) C/C++ Prototype RETURN_CODE AlazarSetParameterUL ( HANDLE h, U8 Channel, U32 Parameter, U32 Value); Visual BASIC Prototype Public Declare Function AlazarInputControl Lib "ATSApiVB.dll" ( ByVal h As Integer, ByVal Channel As Byte, ByVal Parameter As Long, ByVal Value As Long) As Long Description: This Api can be used to set individual attributes and variables from the device. It is only used for unsigned values. Input: h A handle to the device. Channel CHANNEL_A, CHANNEL_B, or 0. Output: None. Return: Refer to Return code values listed in API RETURN CODE VALUES Parameter Constants to be used in this API routine: (AT PRESENT NONE AVAILABLE) 108 ATS-SDK Software Manual v5.6.0

AlazarSetRecordCount C/C++ Prototype RETURN_CODE AlazarSetRecordCount ( HANDLE h, U32 Count); Visual BASIC Prototype Public Declare Function AlazarSetRecordCount Lib "ATSApiVB.dll" ( ByVal h As Integer, ByVal Count As Long) As Long Description: Configure the number of records for the device to capture. Board Limits: ATS850, ATS310, ATS330 The smaller of the following two: 1000 or (MaxMem / (RecordLength + 16)). ATS460, ATS660 For Single-Port memory acquisition: The smaller of the following two: 256000 or (MaxMem / (RecordLength + 16)) For Dual-Port memory acquisition: Unlimited. Refer to XXXX For infinite record length, use the value 0x7FFFFFFF. ATS860 For Single-Port memory acquisition: The smaller of the following two: 256000 or (MaxMem / (RecordLength + 32)) For Dual-Port memory acquisition: Unlimited. Refer to XXXX For infinite record length, use the value 0x7FFFFFFF. ATS9462 Unlimited. Refer to XXXX For infinite record length, use the value 0x7FFFFFFF. Input: Note: MaxMem is the number of Samples Per Channel on the device. h A handle to the device. Count Indicates the total number of records to capture. ATS-SDK Software Manual v5.6.0 109

Output: None. Return: Refer to Return code values listed in API RETURN CODE VALUES 110 ATS-SDK Software Manual v5.6.0

AlazarSetRecordSize C/C++ Prototype RETURN_CODE AlazarSetRecordSize ( HANDLE h, U32 PreSize, U32 PostSize); Visual BASIC Prototype Public Declare Function AlazarSetRecordSize Lib "ATSApiVB.dll" ( ByVal h As Integer, ByVal PreSize As Long, ByVal PostSize As Long) As Long Description: Configure the record size information. ATS850 Note that (PreSize + PostSize) must be a multiple of 4. (PreSize + PostSize) must not exceed (MaxMemory 4) and must be a minimum of 256. Note that PreSize must be a multiple of 64 and must not exceed (PreSize + PostSize 64). PreSize can also be set to 0 for a post-trigger-only acquisition. ATS310, ATS330 Note that (PreSize + PostSize) must be a multiple of 4. (PreSize + PostSize) must not exceed (MaxMemory 4) and must be a minimum of 256. Note that PreSize must be a multiple of 64 and must not exceed (PreSize + PostSize 64). PreSize can also be set to 0 for a post-trigger-only acquisition. ATS460, ATS660 For Single Port acquisition: Note that (PreSize + PostSize) must be a multiple of 16. (PreSize + PostSize) must not exceed (MaxMemory 16) and must be a minimum of 128. Note that PreSize must be a multiple of 64 and must not exceed (PreSize + PostSize 64). PreSize can also be set to 0 for a post-trigger-only acquisition. For Dual Port acquisitions: Traditional AutoDMA (Synchronous and Asynchronous) ATS-SDK Software Manual v5.6.0 111

Note that (PreSize + PostSize) must be a multiple of 16 for ATS460 and ATS660. (PreSize + PostSize) must not exceed (MaxMemory / 4) and must be a minimum of 128. Note that PreSize must be a multiple of 64 and must not exceed (PreSize + PostSize 64). PreSize can also be set to 0 for a posttrigger-only acquisition. NPT AutoDMA (Synchronous and Asynchronous) Note that PreSize MUST be zero. PostSize must be a multiple of 64. PostSize must not exceed (MaxMemory / 4) and must be a minimum of 128. ATS860 For Single Port acquisition: Note that (PreSize + PostSize) must be a multiple of 32. (PreSize + PostSize) must not exceed (MaxMemory 32) and must be a minimum of 256. Note that PreSize must be a multiple of 128 and must not exceed (PreSize + PostSize 128). PreSize can also be set to 0 for a post-trigger-only acquisition. For Dual Port acquisitions: Traditional AutoDMA (Synchronous and Asynchronous) Note that (PreSize + PostSize) must be a multiple of 32. (PreSize + PostSize) must not exceed (MaxMemory / 4) and must be a minimum of 256. Note that PreSize must be a multiple of 128 and must not exceed (PreSize + PostSize 128). PreSize can also be set to 0 for a posttrigger-only acquisition. NPT AutoDMA (Synchronous and Asynchronous) Note that PreSize MUST be zero. PostSize must be a multiple of 128. PostSize must not exceed (MaxMemory / 4) and must be a minimum of 256. ATS9462 For Dual Port acquisitions: Traditional AutoDMA (Synchronous and Asynchronous) Not applicable NPT AutoDMA (Synchronous and Asynchronous) Note that PreSize MUST be zero. PostSize must be a multiple of 128. PostSize must not exceed 8 Meg and must be a minimum of 256. 112 ATS-SDK Software Manual v5.6.0

Input: h A handle to the device. PreSize Number of Pre-trigger samples PostSize Number of Post-trigger samples Output: None. Return: Refer to Return code values listed in API RETURN CODE VALUES ATS-SDK Software Manual v5.6.0 113

AlazarSetTriggerDelay C/C++ Prototype RETURN_CODE AlazarSetTriggerDelay ( HANDLE h, U32 Delay); Visual BASIC Prototype Public Declare Function AlazarSetTriggerDelay Lib "ATSApiVB.dll" ( ByVal h As Integer, ByVal Delay As Long) As Long Description: Sets the trigger delay value for the trigger system. Trigger delay value is the number of clock cycles by which the trigger will be delayed relative to the occurrence of the actual trigger. Note that this value must be a multiple of 4 for the ATS850. If the value loaded is not a multiple of 4, the least two significant bits will be ignored. In other words, the value will be rounded down to the closest multiple of 4. For ATS460, ATS660 and ATS9462, the trigger delay value can be any integer number up to the maximum value of 9,999,999. For ATS860, the trigger delay value must be a multiple of 4, up to the maximum value of 9,999,999. If a Delay is set to be 0, there will be no trigger delay and the original trigger will be used. Input: The maximum value allowed for trigger delay is 9,999,999 decimal. h A handle to the device. Delay Delay in number of sampling clock cycles. Output: None. Return: Refer to Return code values listed in API RETURN CODE VALUES 114 ATS-SDK Software Manual v5.6.0

AlazarSetTriggerOperation C/C++ Prototype RETURN_CODE AlazarSetTriggerOperation ( HANDLE h, U32 TriggerOperation, U32 TriggerEngine1, U32 Source1, U32 Slope1, U32 Level1, U32 TriggerEngine2, U32 Source2, U32 Slope2, U32 Level2); Visual BASIC Prototype Public Declare Function AlazarSetTriggerOperation Lib "ATSApiVB.dll" ( ByVal h As Integer, ByVal TriggerOperation As Long, ByVal TriggerEngine1 As Long, ByVal Source1 As Long, ByVal Slope1 As Long, ByVal Level1 As Long, ByVal TriggerEngine2 As Long, ByVal Source2 As Long, ByVal Slope2 As Long, ByVal Level2 As Long) As Long Description: Configure the trigger circuitry. Note that there are two trigger engines, each capable of having one trigger source, trigger level and trigger slope. There are no dependencies between the two engines, i.e. both of them can trigger off the same source or from different sources. Both can have the same slope of different slope. Both can use the same level or different level. Input: h A handle to the device. TriggerOperation - Refer to table below (Trigger Engine Operation). TriggerEngine1 - Refer to table below (Trigger Engines). Source1 - Refer to table below (Trigger Engine Sources). Slope1 - Refer to table below (Trigger Slope). Level1 The trigger level value (0 255) for trigger engine one. 128 is zero percent, 255 is +100% and 0 is 100% TriggerEngine2 - Refer to table below (Trigger Engines). Source2 - Refer to table below (Trigger Engine Sources). Slope2 - Refer to table below (Trigger Slope). Level2 - The trigger level value (0 255) for trigger engine two. 128 is zero percent, 255 is +100% and 0 is 100% ATS-SDK Software Manual v5.6.0 115

Output: None. Return: Refer to Return code values listed in API RETURN CODE VALUES Constants to be used in this API routine: Trigger Engines #define TRIG_ENGINE_J #define TRIG_ENGINE_K 0x00000000UL 0x00000001UL Trigger Engine Operation #define TRIG_ENGINE_OP_J 0x00000000UL #define TRIG_ENGINE_OP_K 0x00000001UL #define TRIG_ENGINE_OP_J_OR_K 0x00000002UL #define TRIG_ENGINE_OP_J_AND_K 0x00000003UL #define TRIG_ENGINE_OP_J_XOR_K 0x00000004UL #define TRIG_ENGINE_OP_J_AND_NOT_K 0x00000005UL #define TRIG_ENGINE_OP_NOT_J_AND_K 0x00000006UL Trigger Engine Sources #define TRIG_CHAN_A #define TRIG_CHAN_B #define TRIG_EXTERNAL #define TRIG_DISABLE 0x00000000UL 0x00000001UL 0x00000002UL 0x00000003UL Trigger Slope #define TRIGGER_SLOPE_POSITIVE 0x00000001UL #define TRIGGER_SLOPE_NEGATIVE 0x00000002UL 116 ATS-SDK Software Manual v5.6.0

AlazarSetTriggerTimeOut C/C++ Prototype RETURN_CODE AlazarSetTriggerTimeOut ( HANDLE h, U32 to_us); Visual BASIC Prototype Public Declare Function AlazarSetTriggerTimeOut Lib "ATSApiVB.dll" ( ByVal h As Integer, ByVal to_ns As Long) As Long Description: Used to specify a timeout for a trigger event. If no trigger occurs in the specified amount of time, the board automatically forces a trigger. If this value is set to zero, timeout function is disabled and the hardware will wait forever for a trigger event to occur. Input: h A handle to the device. to_us Time out in Tens of microseconds. Ex. 500000 is equal to 5 seconds Output: None. Return: Refer to Return code values listed in API RETURN CODE VALUES ATS-SDK Software Manual v5.6.0 117

AlazarSleepDevice C/C++ Prototype RETURN_CODE AlazarSleepDevice ( HANDLE h, U32 state); Visual BASIC Prototype Public Declare Function AlazarSleepDevice Lib "ATSApiVB.dll" ( ByVal h As Integer, ByVal state As Long) As Long Description: This routine gives an application the ability to turn the power to the ATS460 ADC chips ON or OFF. Input: Output: None h - Board identification handle state - POWER_OFF = 0 or POWER_ON = 1 Return: Refer to the Return code values listed in API RETURN CODES VALUES Note: The device is automatically awakened when either the ATSApi or ATSApiVB DLL is loaded 118 ATS-SDK Software Manual v5.6.0

AlazarStartCapture C/C++ Prototype RETURN_CODE AlazarStartCapture ( HANDLE h); Visual BASIC Prototype Public Declare Function AlazarStartCapture Lib "ATSApiVB.dll" (ByVal h As Integer) As Long Description: Arm the device to initiate an acquisition and start waiting for one or more trigger events. Input: H A handle to the device. Output: None. Return: Refer to Return code values listed in API RETURN CODE VALUES ATS-SDK Software Manual v5.6.0 119

AlazarTriggered C/C++ Prototype U32 AlazarTriggered (HANDLE h); Visual BASIC Prototype Public Declare Function AlazarTriggered Lib "ATSApiVB.dll" (ByVal h As Integer) As Long Description: Query the device s triggered status. A return value of 1 signifies that AT LEAST one trigger event has occurred since the last AlazarStartCapture call. Input: h A handle to the device. Output: None. Return: 1 The board triggered at least once 0 The board did not triggered 120 ATS-SDK Software Manual v5.6.0

Asynchronous DMA API Description The following pages describe each of the AsyncDMA API functions used by ATS-SDK. Calling conventions and return codes are listed and dependencies are explained ATS-SDK Software Manual v5.6.0 121

Asynchronous Dma Operating Modes & Data Organization There are four modes of operation for Asynchronous AutoDMA. They are: Traditional Continuous Streaming Triggered Continuous Streaming No-Pre-Trigger (NPT) A user uses the uflags parameter in the AlazarBeforeAsyncRead API to set the appropriate mode. Each mode is described below. Please refer to the API descriptions for AlazarBeforeAsyncRead for details. Notes: All modes are supported on the ATS460, ATS660 and ATS860. ATS9462 does not support the Traditional mode. ATS9462 interlaces the data in dual channel mode. 122 ATS-SDK Software Manual v5.6.0

Traditional Asynchronous DMA Overview This mode is used when the user expects to have captured data before and after the trigger event for each Record. Guidelines for RecsPerBuffer, RecordLength and Buffer Sizes ATS460, ATS660 RecordCount must be a multiple of RecsPerBuffer or 0x7FFFFFFF (Infinite). RecordLength must be a multiple of 16. The size of one AutoDMA buffer must be less than 4Mbytes. (i.e. RecordLength*RecsPerBuffer < 4MBytes) ATS860 RecordCount must be a multiple of RecsPerBuffer or 0x7FFFFFFF (Infinite). RecordLength must be a multiple of 32. The size of one AutoDMA buffer must be less than 4Mbytes. (i.e. RecordLength*RecsPerBuffer < 4MBytes) ATS9462 Traditional Asynchronous AutoDMA automatically reverts to NPT Asynchronous AutoDMA. Please refer to the appropriate section. ATS-SDK Software Manual v5.6.0 123

Buffer Organization Variations exist based on the type of device. Below is a detailed outline that shows how buffers are organized for each mode of operation on different types of devices. Mode Single Channel A Single Channel B Dual Channel ATS9462 AsyncDMA Buffer Organization Buffer Layout Record 1 Record 2 Record N A1,0 A1,1 A1,2 A1,P A2,0 A21 A2,2 A2,P AN,0 AN,1 AN,2 AN,P B1,0 B1,1 B1,2 B1,P B2,0 B2,1 B2,2 B2,P BN,0 BN,1 BN,2 BN,P A1,0 B1,0 A1,1 B1,1 A1,p B1,P A2,0 B2,0 A2,1 B2,1 A2,p B2,P AN,0 BN,0 AN,1 BN,1 AN,P BN,P Where : P is the number of samples transferred per trigger (typically same as record length) N is Records Per Buffer. 124 ATS-SDK Software Manual v5.6.0

Mode Single Channel A Single Channel B Dual Channel Traditional Dual Channel NPT ATS460, ATS660, ATS860 AsyncDMA Buffer Organization Buffer Layout Record 1 Record 2 Record N A1,0 A1,1 A1,2 A1,P A2,0 A21 A2,2 A2,P AN,0 AN,1 AN,2 AN,P B1,0 B1,1 B1,2 B1,P B2,0 B2,1 B2,2 B2,P BN,0 BN,1 BN,2 BN,P Channel A Record 1 Channel B Record 1 Channel A Record N Channel B Record N A1,0 A1,1 A1,P B1,0 B1,1 B1,P AN,0 AN,1 AN,P BN,0 BN,1 BN,P Channel A Record 1 Channel A Record N Channel B Record 1 Channel B Record N A1,0 A1,1 A1,P AN,0 AN,1 AN,P B1,0 B1,1 B1,P BN,0 BN,1 BN,P Where : P is the number of samples transferred per trigger (typically same as record length) N is Records Per Buffer. ATS-SDK Software Manual v5.6.0 125

Continuous Asynchronous DMA Overview This mode is used when the user wants a gapless data capture without any PreTrigger Data or even a trigger event. Buffer Organization Since RecsPerBuffer is always set to 1, each user buffer may look as follows: ATS460, ATS660, ATS860 AsyncDMA Continuous Mode Buffer Layout Data Stream Single Channel A A 1A 2A 3 A P Single Channel B Dual Channel B 1 B 2 B 3 B P A 1 A 2 A 3 A P B 1 B 2 B 3 B P Where P is the buffer length (A and B are Samples) ATS9462 AsyncDMA Continuous Mode Buffer Layout Data Stream Single Channel A A 1 A 2 A 3 A P Single Channel B Dual Channel B 1 B 2 B 3 B P A 1 B 1 A 2 B 2 A x B x. A PB P Where P is the buffer length (A and B are Samples)- 126 ATS-SDK Software Manual v5.6.0

Guidelines for RecsPerBuffer, RecordLength and Buffer Sizes ATS460, ATS660 ATS860 RecordCount can be any number, as triggering is disabled in this mode. RecordCount can also be set to 0x7FFFFFFF (Infinite). For best performance, RecordLength should be set as close to the maximum memory on the board, e.g. 7 * 1024 * 1024 for an ATS460-8M and 127 * 1024 * 1024 for an ATS460-128M. In any case, Record Length must be a multiple of 16. The size of one AutoDMA buffer must be less than 4 Mbytes. (i.e. Buffer Size < 4MB). For best performance at higher sample rates, the size of each AutoDMA buffer must be at least 2 Mbytes (1 Megasample for ATS460 and ATS660) RecordCount can be any number, as triggering is disabled in this mode. RecordCount can also be set to 0x7FFFFFFF (Infinite). For best performance, RecordLength should be set as close to the maximum memory on the board, e.g. 15 * 1024 * 1024 for an ATS860-16M and 255 * 1024 * 1024 for an ATS860-256M. In any case, Record Length must be a multiple of 32. The size of one AutoDMA buffer must be less than 4 Mbytes. (i.e. Buffer Size < 4MB). o For best performance at higher sample rates, the size of each AutoDMA buffer must be at least 2 Mbytes. ATS9462 RecordCount can be any number, as triggering is disabled in this mode. RecordCount can also be set to 0x7FFFFFFF (Infinite). ATS-SDK Software Manual v5.6.0 127

PCI Express sustained data throughput of the computer must be greater than the Input Data Rate, where Input Data Rate = 2 * fs, where fs is the sample rate If and only if this condition is satisfied, then Latency Protection must be greater than approx. 250 milliseconds, where Latency Protection = (1/fs) * BufferCount * BufferSize / 2, where Buffer size is in bytes The size of each buffer must be at least 512 KB and less than 16 Mbytes. 128 ATS-SDK Software Manual v5.6.0

Triggered Continuous Streaming Asynchronous DMA This mode is identical in almost all regards to Continuous Streaming with the exception that data streaming starts only after receiving a trigger. Please refer to the Continuous Streaming details for the buffer organization. ATS-SDK Software Manual v5.6.0 129

No-PreTrigger Asynchronous DMA Overview This mode is used when the user does not expect to have captured data before the trigger event. Data captured after each trigger event is stored and transferred to the user buffers. Therefore, each user buffer will contain RecsPerBuffer many records of PostTrigger data. In NPT mode, when you issue triggers for the (N + 1) th buffer, you will receive the N th buffer, i.e. there is always going to be a latency of 1 buffer. This is due to the nature of the FIFO design of the device (the next trigger is needed to flush the FIFO). Therefore, you have to generate (N * RecsPerBuffer +1) triggers to capture N buffers. 130 ATS-SDK Software Manual v5.6.0

Buffer Organization Variations exist based on the type of device. Below is a detailed outline that shows how buffers are organized for each mode of operation on different types of devices. Mode Single Channel A Single Channel B Dual Channel ATS9462 NPT AsyncDMA Buffer Organization Buffer Layout Record 1 Record 2 Record N A1,0 A1,1 A1,2 A1,P A2,0 A21 A2,2 A2,P AN,0 AN,1 AN,2 AN,P B1,0 B1,1 B1,2 B1,P B2,0 B2,1 B2,2 B2,P BN,0 BN,1 BN,2 BN,P A1,0 B1,0 A1,1 B1,1 A1,P B1,P A2,0 B2,0 A2,1 B2,1 A2,P B2,P AN,0 BN,0 AN,1 BN,1 AN,P BN,P Where : P is the number of samples transferred per trigger (typically same as record length) N is Records Per Buffer. ATS-SDK Software Manual v5.6.0 131

Mode Single Channel A Single Channel B Dual Channel Traditional Dual Channel NPT ATS460, ATS660, ATS860 NPT AsyncDMA Buffer Organization Buffer Layout Record 1 Record 2 Record N A1,0 A1,1 A1,2 A1,P A2,0 A21 A2,2 A2,P AN,0 AN,1 AN,2 AN,P B1,0 B1,1 B1,2 B1,P B2,0 B2,1 B2,2 B2,P BN,0 BN,1 BN,2 BN,P Channel A Record 1 Channel B Record 1 Channel A Record N Channel B Record N A1,0 A1,1 A1,P B1,0 B1,1 B1,P AN,0 AN,1 AN,P BN,0 BN,1 BN,P Channel A Record 1 Channel A Record N Channel B Record 1 Channel B Record N A1,0 A1,1 A1,P AN,0 AN,1 AN,P B1,0 B1,1 B1,P BN,0 BN,1 BN,P Where : P is the number of samples transferred per trigger (typically same as record length) N is Records Per Buffer. 132 ATS-SDK Software Manual v5.6.0

Guidelines for RecsPerBuffer, RecordLength and Buffer Sizes ATS460, ATS660 The following guidelines must be respected: RecordCount must be a multiple of RecsPerBuffer or 0x7FFFFFFF (Infinite). RecordLength must be a multiple of 64. The size of one AutoDMA buffer must be less than 4Mbytes. (i.e. RecordLength*RecsPerBuffer < 4MBytes) ATS860 The following guidelines must be respected: RecordCount must be a multiple of RecsPerBuffer or 0x7FFFFFFF (Infinite). RecordLength must be a multiple of 128. The size of one AutoDMA buffer must be less than 4Mbytes. (i.e. RecordLength*RecsPerBuffer < 4MBytes) ATS9462 The following guidelines must be respected: RecordCount can be any number, as triggering is disabled in this mode. RecordCount can also be set to 0x7FFFFFFF (Infinite). PCI Express sustained data throughput of the computer must be greater than the Input Data Rate, where Input Data Rate = fs * RecordLength * ChannelCount * PRF * 2 bytes, where fs is the sample rate, RecordLength is number of samples per trigger, Channel Count is number of channels to be read and PRF is the trigger repeat frequency ATS-SDK Software Manual v5.6.0 133

If and only if this condition is satisfied, then Latency Protection must be greater than approx. 250 milliseconds, where Latency Protection = (1 / Input Data Rate) * BufferCount * BufferSize / 2, where Buffer size is in bytes Note: o The size of each buffer must be at least 512 KB and less than 16 Mbytes. o The 250 millisecond is an arbitrary number based on our experience in the laboratory. Each individual computer can have vastly different limits. 134 ATS-SDK Software Manual v5.6.0

ATS-SDK Software Manual v5.6.0 135

AlazarAbortAsyncRead C/C++ Prototype RETURN_CODE AlazarAbortAsyncRead ( HANDLE h ); Visual Basic Prototype Description: Public Declare Function AlazarAbortAsyncRead Lib "ATSApiVB.dll" ( ByVal h As Integer) As Long The AlazarAbortAsyncRead function aborts any in-progress transfers, and cancels any pending transfers on the board. Input: Output: None. Return: h A handle to the device. If the function succeeds, then it returns ApiSuccess. If the function fails, the return value may be one of the following: Value ApiInvalidHandle ApiFailed Meaning The h Parameter not valid, or the board does not support the requested operation. The Win32 CancelIo system call failed. Call GetLastError for more information. 136 ATS-SDK Software Manual v5.6.0

AlazarAsyncRead C/C++ Prototype RETURN_CODE AlazarAsyncRead ( HANDLE h, void *pbuffer, U32 ubytestoread, OVERLAPPED *poverlapped, ); Visual Basic Prototype Description: NOT SUPPORTED The AlazarAsyncRead function allows you to queue host memory buffers to the board to receive data from on-board memory. This allows the board to begin the next transfer from on-board to host memory as soon as the previous transfer completes. This function returns immediately after adding the buffer to the end of the list of buffers available to the board. An event in the OVERLAPPED structure will be set to the signaled state to indicate when the transfer from on-board to the host memory buffer actually completes. Input: Return: h - Handle to the board. pbuffer - Pointer to the buffer that receives the data transferred from the board. ubytestoread - Specifies the number of bytes to read in this transfer. poverlapped - Pointer to an OVERLAPPED structure. If the function succeeds, it returns ApiPending. This return value means that the buffer was successfully added to the list of buffers for the board. If the function fails, the return value may be one of the following: ATS-SDK Software Manual v5.6.0 137

Value ApiInvalidHandle ApiNotInitialized ApiInvalidBuffer ApiBufferTooSmall ApiBufferOverflow ApiInvalidSize ApiInsufficientResources ApiLockAndProbePagesFailed Other values Meaning The h Parameter not valid, or the board does not support the requested operation. AlazarBeforeAsyncRead not called or failed The pbuffer parameter is NULL. The ubytestoread parameter is less than the number of bytes in a transfer. The board filled its on-board memory faster than it was transferred from onboard memory to host memory, and overflowed. The number of bytes to read was zero. The system was not able to allocate memory to describe the buffer. The system was not able to lock the memory for a DMA transfer. The buffer is probably too big. Internal errors Remarks: The ubytestoread parameter must be equal to the size of the AutoDMA transfer in bytes, which can be calculated as follows: If the ADMA_ENABLE_HEADERS flag was set, then the size the record header in samples is: record_header_size_samples = 16 bytes / bytes_per_sample; If the ADMA_ENABLE_HEADERS flag was not set, then the size of the record the size of the record header in samples is zero. record_header_size_samples = 0; The number of bytes per record is given by: bytes_per_record = bytes_per_sample * (record_header_size_samples + samples_per_record); The number of bytes per transfer is given by: 138 ATS-SDK Software Manual v5.6.0

bytes_per_transfer = number_of_enabled_channels * bytes_per_record * records_per_transfer; ATS-SDK Software Manual v5.6.0 139

AlazarBeforeAsyncRead C/C++ Prototype RETURN_CODE AlazarBeforeAsyncRead ( HANDLE h, U32 uchannelmode, long lfirstsample, U32 usamplesperrecord, U32 urecordsperbuffer, U32 urecordsperacquisition, U32 uflags ); Visual Basic Prototype Public Declare Function AlazarBeforeAsyncRead Lib "ATSApiVB.dll" ( ByVal h As Integer, ByVal uchannelselect As Long, ByVal ltransferoffset As Long, ByVal usamplesperrecord As Long, ByVal urecordsperbuffer As Long, ByVal urecordsperacquisition As Long, ByVal uflags As Long) As Long Description: The AlazarBeforeAsyncRead function configures a board for asynchronous AutoDMA transfers from on-board to host memory. It is an alternative to the AlazarStartAutoDMA / AlazarGetNextBuffer API functions that provides higher transfer rates, lower CPU usage, and better operation with master-slave board systems. AlazarBeforeAsyncRead must be called before calling AlazarAsyncRead or AlazarPostAsyncBuffer. Input: h - Handle to the board to be configured. uchannelmode - Specifies the channels whose data will be transferred from the on-board to host memory. This parameter can have one of the following values: Value CHANNEL_A Meaning Transfer samples from Ch A only 140 ATS-SDK Software Manual v5.6.0

CHANNEL_B CHANNEL_A CHANNEL_B Transfer samples from Ch B only Transfer samples from both channels lfirstsample - Specifies the first sample from each on-board record to transfer from on-board to host memory. This value is a sample relative to the trigger position in an on-board record. usamplesperrecord - Specifies the number of samples from each record to transfer from on-board to host memory. Note this value can be less the number of samples per record acquired to on-board memory. If you transfer only a portion of a record from on-board to host memory, use the lfirstsample parameter to specify the first sample from the record in on-board memory. urecordsperbuffer - Specifies the number of records in each transfer. urecordsperacquisition - Specifies the number of records in the entire acquisition. uflags - Specifies AutoDMA transfer mode and options. The transfer mode can have one of the following values: Value Meaning ADMA_TRADITIONAL_MODE Wait for a trigger event before each record in the acquisition. ADMA_CONTINUOUS_MODE Acquire a continuous stream of samples. See remarks below. ADMA_NPT Transfer data without pre-trigger samples. See remarks below. The options can be a combination of the following flags: Value ADMA_EXTERNAL_START_CAPTURE ADMA_ENABLE_RECORD_HEADERS Meaning If this flag is set, you must call AlazarStartCapture to start the acquisition. If this flag is not set, then AlazarBeforeAsyncRead calls AlazarStartCapture before it returns. This flag may be used with any AutoDMA mode. If this flag is set, then the board precedes each record with header information. This flag must only be used in traditional AutoDMA mode. See the remarks below. ATS-SDK Software Manual v5.6.0 141

ADMA_TRIGGERED_STREAMING ADMA_FIFO_ONLY_STREAMING ADMA_ALLOC_BUFFERS If this flag is set, the board will for a trigger event before streaming data in continuous AutoDMA mode. If this flag not set, then the board automatically starts streaming when you call AlazarStartCapture. This flag can only be used in continuous AutoDMA mode. This flag must be set when devices without memory are used. For example, if the device is an ATS9462 (without any memory), then this flag instructs the device driver to program the harware such that all captured data is stored directly to the user supplied buffers in PC memory. This flag must be set to use the AlazarWaitNextAsyncBufferComplete function. Output: None. Return: If the function succeeds, then it returns ApiSuccess. If it fails, then it may return one of the following return codes: Value ApiInvalidHandle ApiInvalidRecordsPerBuffer ApiInvalidOffset ApiInsufficientResources ApiUnsupportedFunction Meaning The h Parameter not valid, or the board does not support the requested operation. The urecordsperacquisition parameter is not an integer multiple of urecordspertransfer parameter. The ltransferoffset parameter is incorrect. The system was not able to allocate transfer buffers. This error occurs when an attempts is made to program a functionality to a devices that does not exist. It can also be manifested when the CFLAGS parameter has an invalid control bit. 142 ATS-SDK Software Manual v5.6.0

ApiFailed or other value AlazarStartCapture failed and returned this value Remarks: If you specify the ADMA_CONTINOUS_MODE flag to enable streaming, you must also ensure that: The ltransferoffset parameter is 0. The urecordspertransfer parameter is 1. The urecordsperacquisition parameter is 0x7fffffff. The ADMA_ENABLE_HEADERS flag is not set. The pre-trigger sample parameter in the call to AlazarSetRecordSize is 0. If you specify the ADMA_NPT flag to enable no-pretrigger mode, then you must also ensure that: The usamplesperrecord parameter is evenly divisible by 32. The ltransferoffset parameter is 0. The ADMA_ENABLE_HEADERS flag is not set. The number of pre-trigger samples in the call to AlazarSetRecordSize is 0. ATS-SDK Software Manual v5.6.0 143

AlazarPostAsyncBuffer C/C++ Prototype RETURN_CODE AlazarPostAsyncBuffer ( HANDLE h, void *pbuffer, U32 ubufferlength_bytes ); Visual Basic Prototype Public Declare Function AlazarPostAsyncBuffer Lib "ATSApiVB.dll" ( ByVal h As Integer, ByRef Buffer As Any, ByVal BytesPerBuffer As Long) As Long Description: The AlazarPostAsyncBuffer function allows you to start a transfer from on-board to host memory. This function adds buffer to a list of buffers available to the board to receive sample data, but does not wait for the transfer to complete. The AlazarPostAsyncBuffer function is used with the AlazarWaitAsyncBufferComplete function to make asynchronous transfers from on-board to host memory. See AlazarWaitAsyncBufferComplete for more information. Input: h - Handle to the board to be configured. pbuffer - Pointer to the buffer that receives the data transferred from the board. Output: ubufferlength_bytes - Specifies the number of bytes to read in this transfer. None. Return: 144 ATS-SDK Software Manual v5.6.0

If the function succeeds, then it returns ApiSuccess. If the function fails, the return value may be one of the following: Value ApiInvalidHandle ApiNullParam ApiInvalidSize ApiDmaInProgress ApiNotInitialized ApiFailed/other value Meaning The h Parameter is invalid, or the board does not support the requested operation. The pbuffer parameter is invalid. The ubufferlength_bytes parameter is invalid. AlazarPostAsyncBuffer has already queued this buffer, but the transfer has not completed. AlazarBeforeAsyncRead was not called or failed Internal error. See error code for details. Remarks: For best performance, call AlazarPostAsyncBuffer at least two times before starting an acquisition. This will allow the board start the next DMA transfer as soon as the previous DMA transfer completes. ATS-SDK Software Manual v5.6.0 145

AlazarWaitAsyncBufferComplete C/C++ Prototype RETURN_CODE AlazarWaitAsyncBufferComplete ( HANDLE h, void *pbuffer, U32 utimeout_ms ); Visual Basic Prototype Public Declare Function AlazarWaitAsyncBufferComplete Lib "ATSApiVB.dll" ( ByVal h As Integer, ByRef Buffer As Any, ByVal utimeout_ms As Long) As Long Description: The AlazarWaitAsyncBufferComplete function allows you to wait for an asynchronous transfer from on-board to host memory to complete. Input: Output: h - Handle to the board. utimeout_ms - Specifies the amount of time in milliseconds to wait for the transfer to complete. pbuffer - Pointer to the buffer that receives the data transferred from the board. Return: If the function succeeds, then it returns ApiSuccess. If the function fails, the return value may be one of the following: Value ApiInvalidHandle Meaning The h Parameter is invalid, or the board does not support the requested operation. 146 ATS-SDK Software Manual v5.6.0

ApiNullParam ApiBufferNotReady ApiDmaInProgress ApiWaitTimeout Other value The pbuffer parameter is invalid. The pbuffer parameter was not queued with AlazarPostAsyncBuffer. The pbuffer parameter is not the next buffer to be completed. The timeout expired before the transfer completed. Internal error. See error code for details. Remark: Transfers complete in the order that they are posted. As a result, you must call the AlazarWaitAsyncBufferComplete function with the same sequence of buffers that you used to call AlazarPostAsyncBuffer. For example, if you allocate three transfer buffers (pbuffer1, pbuffer2, and pbuffer3), and call AlazarPostAsyncBuffer three times as follows: AlazarPostAsyncBuffer (hboard, pbuffer1, ubytesperbuffer); AlazarPostAsyncBuffer (hboard, pbuffer2, ubytesperbuffer); AlazarPostAsyncBuffer (hboard, pbuffer3, ubytesperbuffer); Then you must call AlazarWaitAsyncBufferComplete with the buffers in the same sequence. AlazarWaitAsyncBufferComplete (hboard, pbuffer1, utimeout_ms); AlazarWaitAsyncBufferComplete (hboard, pbuffer2, utimeout_ms); AlazarWaitAsyncBufferComplete (hboard, pbuffer3, utimeout_ms); ATS-SDK Software Manual v5.6.0 147

AlazarWaitNextAsyncBufferComplete C/C++ Prototype RETURN_CODE AlazarWaitNextAsyncBufferComplete ( HANDLE h, void *pbuffer, U32 ubufferlength_bytes, U32 utimeout_ms ); Visual Basic Prototype Description: Public Declare Function AlazarWaitNextAsyncBufferComplete Lib "ATSApiVB.dll" ( ByVal h As Integer, ByRef Buffer As Any, ByVal ubufferlength_bytes As Long, ByVal utimeout_ms As Long) As Long The AlazarWaitNextAsyncBufferComplete function copies the data from an internal buffer to the user-supplied buffer, waiting for the buffer to fill if necessary. Note that in order to use this function, you must call AlazarBeforeAsyncRead with uflags that includes ADMA_ALLOC_BUFFERS. This function is primarily used by ATS-VI vis for LabVIEW. To find out how many buffers are in the DLL s internal queue, refer to the AlazarGetParameter function. If you call AlazarWaitNextAsyncBufferComplete with a NULL pointer for pbuffer, it will remove the next buffer from the internal buffers. This is useful for preventing an overflow situation. A user can find out the number of buffers in the internal queue (as stated above) and selectively remove as many as he chooses. Input: h - Handle to the board. ubufferlength_bytes - Size of the buffer pointed to by pbuffer in bytes. utimeout_ms - Specifies the amount of time in milliseconds to wait for the transfer to complete. Output: 148 ATS-SDK Software Manual v5.6.0

pbuffer Pointer to the buffer that receives the data transferred from the board. NULL for overflow protection Return: If the function succeeds, then it returns ApiSuccess. If the function fails, the return value may be one of the following: Value ApiInvalidHandle ApiNullParam ApiWaitTimeout Other value Meaning The h Parameter is invalid, or the board does not support the requested operation. The pbuffer parameter is invalid. The timeout expired before the transfer completed. Internal error. See error code for details. ATS-SDK Software Manual v5.6.0 149

Synchronous AutoDMA API Description The following pages describe each of the AutoDMA API functions used by ATS-SDK. Calling conventions and return codes are listed and dependencies are explained 150 ATS-SDK Software Manual v5.6.0

Synchronous AutoDma Operating Modes & Data Organization There are four modes of operation for AutoDMA. They are Traditional, Continuous Streaming, Triggered Continuous Streaming and No-Pre- Trigger (NPT). A user uses the CFlags parameter in the AlazarStartAutoDMA API to set the correct mode. Each mode is described below. Please refer to the API descriptions for AlazarStartAutoDMA and AlazarGetNextAutoDMABuffer for details. Synchronous AutoDMA is not available on the ATS9462. Traditional Synchronous AutoDMA Overview This mode is used when the user expects to have captured data before and after the trigger event for each Record. ATS-SDK Software Manual v5.6.0 151

Buffer Organization Depending on the RecsPerBuffer setting and channel(s) selected each user buffer may look as follows: Mode Single Channel A Single Channel B Dual Channel Traditional Dual Channel NPT ATS460, ATS660, ATS860 AutoDMA Buffer Organization Buffer Layout Record 1 Record 2 Record N A1,0 A1,1 A1,2 A1,P A2,0 A21 A2,2 A2,P AN,0 AN,1 AN,2 AN,P B1,0 B1,1 B1,2 B1,P B2,0 B2,1 B2,2 B2,P BN,0 BN,1 BN,2 BN,P Channel A Record 1 Channel B Record 1 Channel A Record N Channel B Record N A1,0 A1,1 A1,P B1,0 B1,1 B1,P AN,0 AN,1 AN,P BN,0 BN,1 BN,P Channel A Record 1 Channel A Record N Channel B Record 1 Channel B Record N A1,0 A1,1 A1,P AN,0 AN,1 AN,P B1,0 B1,1 B1,P BN,0 BN,1 BN,P Where : P is the number of samples transferred per trigger (typically same as record length) N is Records Per Buffer. 152 ATS-SDK Software Manual v5.6.0

Guidelines for RecsPerBuffer, RecordLength and Buffer Sizes The following guidelines must be respected: a. RecordCount must be a multiple of RecsPerBuffer or 0x7FFFFFFF (Infinite). b. RecordLength must be a multiple of 16. c. The size of one AutoDMA buffer must be less than 4Mbytes. (i.e. RecordLength*RecsPerBuffer < 4Mb.) ATS-SDK Software Manual v5.6.0 153

Continuous Streaming Synchronous AutoDMA Overview This mode is used when the user wants a streamed data capture without any PreTrigger Data or Trigger Event. Buffer Organization Since RecsPerBuffer is always set to 1, each user buffer may look as follows: ATS460, ATS660, ATS860 Synchronous AutoDMA Continuous Mode Buffer Layout Data Stream Single Channel A A 1A 2A 3 A P Single Channel B B 1 B 2 B 3 B P Dual Channel A 1 A 2 A 3 A P B 1 B 2 B 3 B P Where P is the buffer length (A and B are Samples) Guidelines for RecsPerBuffer, RecordLength and Buffer Sizes The following guidelines must be respected: a. RecordCount can be any number, as triggering is disabled in this mode. RecordCount can also be set to 0x7FFFFFFF (Infinite). b. For best performance, RecordLength should be set as close to the maximum memory on the board, e.g. 7 * 1024 * 1024 for an ATS460-8M and 127 * 1024 * 1024 for an ATS460-128M. In any case, Record Length must be a multiple of 16. c. The size of one AutoDMA buffer must be less than 4 Mbytes. (i.e. Buffer Size < 4MB.) d. For best performance at higher sample rates, the size of each AutoDMA buffer must be at least 2 Mbytes (1 Megasample for ATS460 and ATS660 and 2 Megasamples for ATS860). 154 ATS-SDK Software Manual v5.6.0

Triggered Continuous Streaming Synchronous AutoDMA This mode is identical in almost all regards to Continuous Streaming with the exception that a trigger source is expected to start the acquisition. Please refer to the Continuous Streaming details for the buffer organization. ATS-SDK Software Manual v5.6.0 155

No-PreTrigger Synchronous AutoDMA Overview This mode is used when the user does not expect to have captured data before the trigger event. Data captured after each trigger event is stored and transferred to the user buffers. Therefore, each user buffer will contain RecsPerBuffer many records of PostTrigger data. In NPT mode, when you issue triggers for the (N + 1) th buffer, you will receive the N th buffer, i.e. there is always going to be a latency of 1 buffer. This is due to the nature of the FIFO design of the device (the next trigger is needed to flush the FIFO). Using Traditional Synchronous AutoDMA: StartAutoDMA While scanning { Issue trigger(s) externally GetNextBuffer } Using NPT Synchronous AutoDMA: StartAutoDMA Issue triggers externally While scanning { Issue trigger(s) externally GetNextBuffer } Therefore, you have to generate (N * RecsPerBuffer +1) triggers to capture N buffers. 156 ATS-SDK Software Manual v5.6.0

Buffer Organization Depending on the RecsPerBuffer setting and channel(s) selected each user buffer may look as follows: Mode Single Channel A Single Channel B Dual Channel Traditional Dual Channel NPT ATS460, ATS660, ATS860 NPT AutoDMA Buffer Organization Buffer Layout Record 1 Record 2 Record N A1,0 A1,1 A1,2 A1,P A2,0 A21 A2,2 A2,P AN,0 AN,1 AN,2 AN,P B1,0 B1,1 B1,2 B1,P B2,0 B2,1 B2,2 B2,P BN,0 BN,1 BN,2 BN,P Channel A Record 1 Channel B Record 1 Channel A Record N Channel B Record N A1,0 A1,1 A1,P B1,0 B1,1 B1,P AN,0 AN,1 AN,P BN,0 BN,1 BN,P Channel A Record 1 Channel A Record N Channel B Record 1 Channel B Record N A1,0 A1,1 A1,P AN,0 AN,1 AN,P B1,0 B1,1 B1,P BN,0 BN,1 BN,P Where : P is the number of samples transferred per trigger (typically same as record length) N is Records Per Buffer. ATS-SDK Software Manual v5.6.0 157

Guidelines for RecsPerBuffer, RecordLength and Buffer Sizes The following guidelines must be respected: RecordCount must be a multiple of RecsPerBuffer or 0x7FFFFFFF (Infinite). RecordLength must be a multiple of 16. The size of one AutoDMA buffer must be less than 4Mbytes. (i.e. RecordLength*RecsPerBuffer < 4Mb.) 158 ATS-SDK Software Manual v5.6.0

AlazarAbortAutoDma C/C++ Prototype RETURN_CODE AlazarAbortAutoDMA( HANDLE h, void* Buffer, AUTODMA_STATUS* error, U32 r1, U32 r2, U32 *r3, U32 *r4); Visual BASIC Prototype Public Declare Function AlazarAbortAutoDMA Lib "ATSApiVB.dll" ( ByVal h As Integer, ByRef Buffer1 As Any, ByRef error As Long, ByVal r1 As Long, ByVal r2 As Long, ByRef r3 As Long, ByRef r4 As Long) As Long Description: This routine is used to terminate the AutoDma capture in cases where the trigger system stopped generating triggers before the buffer was filled by the AutoDMA engine. The routine will populate the buffer with the appropriate number of records that have been successfully captured. Input: h - Board identification handle Buffer - This Buffer is used to transfer a set of Records from the Device back to the user application. Output: r1 - RESERVED r2 - RESERVED error ADMA_Completed - No errors occurred ADMA_Buffer1Invalid - Buffer1 is not a suitable buffer ADMA_Buffer2Invalid - Buffer2 is not a suitable buffer ADMA_BoardHandleInvalid Board handle is not valid ADMA_InternalBuffer1Invalid - The routine cannot allocate enough memory because system resources are low ADMA_InternalBuffer2Invalid - The routine cannot allocate enough memory because system resources are low ADMA_OverFlow A hardware overflow occurred ADMA_InvalidChannel - The channel selected is invalid ADMA_DMAInProgress - A memory transfer is in progress ATS-SDK Software Manual v5.6.0 159

ADMA_UseHeaderNotSet UseHeader must be set ADMA_HeaderNotValid An invalid header was encountered ADMA_InvalidRecsPerBuffer RecordCount must be a perfect multiple of RecsPerBuffer ADMA_Success is equivalent to ADMA_Completed TriggersOccurred - This is the total number of triggers that have been captured since the last start capture. r3 - RESERVED r4 - RESERVED Return: Refer to the Return code values listed in API RETURN CODES VALUES 160 ATS-SDK Software Manual v5.6.0

AlazarCloseAUTODma C/C++ Prototype RETURN_CODE AlazarCloseAUTODma (HANDLE h); Visual BASIC Prototype Public Declare Function AlazarCloseAUTODma Lib "ATSApiVB.dll" (ByVal h As Integer) As Integer Description: This routine will close the AUTODMA capabilities of the device. Only call this upon exit or error. Input: h - Board identification handle Output: None Return: Refer to the Return code values listed in API RETURN CODES VALUES ATS-SDK Software Manual v5.6.0 161

AlazarEvents C/C++ Prototype RETURN_CODE AlazarEvents (HANDLE h, U32 enable); Visual BASIC Prototype Public Declare Function AlazarEvents Lib "ATSApiVB.dll" ( ByVal h As Integer, ByVal enable As Integer) As Integer Description: This function allows a user to enable or disable usage of software events in AutoDMA mode. The driver manages the event processing and a user can only use an event in conjunction with the API AlazarWaitForBufferReady (...). When the events are enabled AlazarWaitForBufferReady (...) will wait until an AutoDMA buffer is available to the users application. For a complete understanding of the Usage of the API AlazarEvents (...) refer to the pseudo-code example provided in the API AlazarWaitForBufferReady (...). Input: h - handle to the device enable - SW_EVENTS_ON or 1 will enable event usage SW_EVENTS_OFF or 0 will disable events usage Return: ApiSuccessFul or 512 signifies that the API was able to enable the events ApiFailed or 513 signifies that the current driver does not support this feature Note: This functionality is only present on the ATS460, ATS660 and ATSS860 devices. It must be called before calling AlazarStartAutoDMA(). If AlazarEvents(h,1) was not used, calling AlazarWaitForBuffer( ) will return 672 and will not disrupt any ongoing signal captures. 162 ATS-SDK Software Manual v5.6.0

AlazarFlushAutoDMA C/C++ Prototype long AlazarFlushAutoDMA( HANDLE h ); Visual Basic Prototype Public Declare Function AlazarFlushAutoDMA Lib "ATSApiVB.dll" ( ByVal h As Integer ) As Long Description: The primary use of the API is to stop a Synchronous NPT acquisition. Scanning type applications are usually configured such that the data capture is ongoing and stopping is done by an external event. In this case trigger events have stopped and this API permits the last buffer to be returned to the application. This API can also be used to stop a non-responding Synchronous AutoDMA acquisition. This will occur when an aquisition was started but not all triggers have been received. Input: h - Handle to the board. Return: The number of valid triggers in the last buffer. Example of usage: Suppose an acquisition is running and all of the sudden, triggers stop coming in. Once the software has determined that the aquisition is to be aborted, API AlazarFlushAutoDMA should be called. The routine will automatically generate the missing triggers in order to complete the last buffer. A last call to AlazarGetNextAutoDMABuffer is needed to read the LAST buffer. You will get ApiFailed as a return value from AlazarGetNextBuffer indicating a successful last buffer. At this point, depending on your design, you may terminate the program or start a new acquisition. NOTE: Internally, this routine calls AlazarStopAutoDMA so as not to allow the software to re-arm any new DMA requests. Only a call to AlazarStartAutoDMA will reset this action. ATS-SDK Software Manual v5.6.0 163

AlazarGetAutoDMAHeaderTimeStamp C/C++ Prototype float AlazarGetAutoDMAHeaderTimeStamp ( HANDLE h, U32 Channel, void* DataBuffer, U32 Record, AUTODMA_STATUS *error); Visual BASIC Prototype Public Declare Function AlazarGetAutoDMAHeaderTimeStamp Lib "ATSApiVB.dll" ( ByVal h As Integer, ByVal Channel As Long, ByRef DataBuffer As Any, ByVal Record As Long, ByRef error As Long) As Double Description: This routine is a helper function, which can be used to retrieve the 40-bit TimeStamp from the header of a particular record. The resulting number is composed of both the TimeStampHighPart and TimeStampLowPart thus alleviating the user from calculating the time stamp using the header values. Input: h - Board identification handle Channel This argument can only have on of the following values: CHANNEL_A, or CHANNEL_B. DataBuffer The data buffer as returned from AlazarGetNextAutoDMABuffer. Record Signifies the record number of interest for the given Data Buffer. Output: error- ADMA_Completed - No errors occurred ADMA_Buffer1Invalid - Buffer1 is not a suitable buffer ADMA_Buffer2Invalid - Buffer2 is not a suitable buffer ADMA_BoardHandleInvalid Board handle is not valid ADMA_InternalBuffer1Invalid - The routine cannot allocate enough memory because system resources are low ADMA_InternalBuffer2Invalid - The routine cannot allocate enough memory because system resources are low ADMA_OverFlow A hardware overflow occurred ADMA_InvalidChannel - The channel selected is invalid ADMA_DMAInProgress - A memory transfer is in progress ADMA_UseHeaderNotSet UseHeader must be set 164 ATS-SDK Software Manual v5.6.0

ADMA_HeaderNotValid An invalid header was encountered ADMA_InvalidRecsPerBuffer RecordCount must be a perfect multiple of RecsPerBuffer ADMA_Success is equivalent to ADMA_Completed Return: Upon success, i.e. error==adma_success, the TimeStamp will be returned in a floating-point format. If an error has occurred then 0 will be returned. ATS-SDK Software Manual v5.6.0 165

AlazarGetAutoDMAHeaderValue C/C++ Prototype U32 AlazarGetAutoDMAHeaderValue( HANDLE h, U32 Channel, void* DataBuffer, U32 Record, U32 Parameter, AUTODMA_STATUS *error); Visual BASIC Prototype Public Declare Function AlazarGetAutoDMAHeaderValue Lib "ATSApiVB.dll" ( ByVal h As Integer, ByVal Channel As Long, ByRef DataBuffer As Any, ByVal Record As Long, ByVal Parameter As Long, ByRef error As Long) As Long Description: This routine is a helper function that can be used to retrieve all the various elements available in the header of an AutoDMA record. It will only operate on records that were captured when the Use Header variable in AlazarStartAutoDMA was set to a 1. Input: h - Board identification handle Channel This argument can only have on of the following values: CHANNEL_A, or CHANNEL_B. DataBuffer The data buffer as returned from AlazarGetNextAutoDMABuffer. Record Signifies the record number of interest for the provided Data Buffer. Parameter Signifies which element the routine should extract from the record s header. This variable can be anyone of the following constants: #define ADMA_CLOCKSOURCE #define ADMA_CLOCKEDGE #define ADMA_SAMPLERATE #define ADMA_INPUTRANGE #define ADMA_INPUTCOUPLING #define ADMA_IMPUTIMPEDENCE #define ADMA_EXTTRIGGERED #define ADMA_CHA_TRIGGERED 0x00000001 0x00000002 0x00000003 0x00000004 0x00000005 0x00000006 0x00000007 0x00000008 166 ATS-SDK Software Manual v5.6.0

#define ADMA_CHB_TRIGGERED #define ADMA_TIMEOUT #define ADMA_THISCHANTRIGGERED #define ADMA_SERIALNUMBER #define ADMA_SYSTEMNUMBER #define ADMA_BOARDNUMBER #define ADMA_WHICHCHANNEL #define ADMA_SAMPLERESOLUTION #define ADMA_DATAFORMAT 0x00000009 0x0000000A 0x0000000B 0x0000000C 0x0000000D 0x0000000E 0x0000000F 0x00000010 0x00000011 Output: error - ADMA_Completed - No errors occurred ADMA_Buffer1Invalid - Buffer1 is not a suitable buffer ADMA_Buffer2Invalid - Buffer2 is not a suitable buffer ADMA_BoardHandleInvalid Board handle is not valid ADMA_InternalBuffer1Invalid - The routine cannot allocate enough memory because system resources are low ADMA_InternalBuffer2Invalid - The routine cannot allocate enough memory because system resources are low ADMA_OverFlow A hardware overflow occurred ADMA_InvalidChannel - The channel selected is invalid ADMA_DMAInProgress - A memory transfer is in progress ADMA_UseHeaderNotSet UseHeader must be set ADMA_HeaderNotValid An invalid header was encountered ADMA_InvalidRecsPerBuffer RecordCount must be a perfect multiple of RecsPerBuffer ADMA_Success is equivalent to ADMA_Completed Return: IF error==adma_success, then the value of the asked Parameter is returned. ATS-SDK Software Manual v5.6.0 167

AlazarGetAutoDMAPtr C/C++ Prototype void *AlazarGetAutoDMAPtr( HANDLE h, U32 DataOrHeader, U32 Channel, void* DataBuffer, U32 Record, AUTODMA_STATUS *error); Visual BASIC Prototype - NOT SUPPORTED Description: This routine is a helper function used to retrieve a pointer to the first data element or first header element of a particular record. If DataOrHeader is set to 1, then the resulting pointer must be cast to PALAZAR_HEADER type. The user can then use the pointer to access any of the header variables. Ex. PALAZAR_HEADER p = (PALAZAR_HEADER) AlazarGetAutoDMAPtr ( ); Input: h - Board identification handle DataOrHeader Instruct the routine to either return the pointer for the header portion (i.e. DataOrHeader=1) or the Data portion (i.e. DataOrHeader=0). Channel This argument can only have on of the following values: CHANNEL_A, or CHANNEL_B. DataBuffer The data buffer as returned from AlazarGetNextAutoDMABuffer. Record Signifies the record number of interest for the given Data Buffer. Output: error - ADMA_Completed - No errors occurred ADMA_Buffer1Invalid - Buffer1 is not a suitable buffer ADMA_Buffer2Invalid - Buffer2 is not a suitable buffer ADMA_BoardHandleInvalid Board handle is not valid ADMA_InternalBuffer1Invalid - The routine cannot allocate enough memory because system resources are low ADMA_InternalBuffer2Invalid - The routine cannot allocate enough memory because system resources are low ADMA_OverFlow A hardware overflow occurred ADMA_InvalidChannel - The channel selected is invalid 168 ATS-SDK Software Manual v5.6.0

ADMA_DMAInProgress - A memory transfer is in progress ADMA_UseHeaderNotSet UseHeader must be set ADMA_HeaderNotValid An invalid header was encountered ADMA_InvalidRecsPerBuffer RecordCount must be a perfect multiple of RecsPerBuffer ADMA_Success is equivalent to ADMA_Completed Return: Refer to the Return code values listed in API RETURN CODES VALUES ATS-SDK Software Manual v5.6.0 169

AlazarGetNextAutoDMABuffer / AlazarGetNextBuffer C/C++ Prototype RETURN_CODE AlazarGetNextBuffer ( HANDLE h, void* Buffer1, void* Buffer2, long* WhichOne, long* RecordsTransferred, AUTODMA_STATUS* error, U32 r1, U32 r2, long *TriggersOccurred, U32 * r4); RETURN_CODE AlazarGetNextAutoDMABuffer ( HANDLE h, void* Buffer1, void* Buffer2, long* WhichOne, long* RecordsTransferred, AUTODMA_STATUS* error, U32 r1, U32 r2, long *TriggersOccurred, U32 * r4); OR Visual BASIC Prototype Public Declare Function AlazarGetNextBuffer Lib "ATSApiVB.dll" ( ByVal h As Integer, ByRef Buffer1 As Any, ByRef Buffer2 As Any, ByRef WhichOne As Long, ByRef RecordsTransferred As Long, ByRef error As Long, ByVal r1 As Long, ByVal r2 As Long, ByRef TriggersOccurred As Long, ByRef r4 As Long) As Long Public Declare Function AlazarGetNextAutoDMABuffer Lib "ATSApiVB.dll" ( ByVal h As Integer, ByRef Buffer1 As Any, ByRef Buffer2 As Any, ByRef WhichOne As Long, ByRef RecordsTransferred As Long, OR 170 ATS-SDK Software Manual v5.6.0

ByRef error As Long, ByVal r1 As Long, ByVal r2 As Long, ByRef TriggersOccurred As Long, ByRef r4 As Long) As Long Description: After an application has called AlazarStartAutoDma the application must call AlazarGetNextAutoDMABuffer to retrieve the data buffers. Because of the nature of Auto Dma, two buffers are required. The device driver dll will arbitrate to which buffer the data will be returned. After a buffer has been filled, variable WhichOne equals the buffer id, thus if the id is 0 then Buffer1 was used and likewise if the id is 1 then Buffer2 was used. In the case where data is not available WhichOne will equal -1. This routine will always return ApiSuccess = 512 when either data has been transferred or when WhichOne = -1. A return value of ApiFailed indicates that all the Records Per Buffer has been transferred. Input: h - Board identification handle UseHeader - If equal to 1 then the AUTODMA record header will precede each record in the Buffer. RecordsTransferred - Indicates how many records have been transferred. This value will always be a multiple of RecordsPerBuffer. It is the application's responsibility to initialize the variable to 0 prior to the first call. TransferLength - This signifies the amount to transfer for each record Output: r1, r2 - RESERVED Buffer1 - This Buffer is used to transfer a complete set of Records from the Device back to the user application. It is one of two buffers that are alternated between. The second buffer is Buffer2. Buffer1 should be large enough to contain (RecordsPerBuffer*TransferLength) many 16-bit values (VB-Integer, C&C++-short). If the Record header is selected (UseHeader = 1) then Buffer1 should be large enough to hold (RecordsPerBuffer*(TransferLength+sizeof(ALAZAR_HEADER)) many 16bit values. Buffer2 - This Buffer is used to transfer a complete set of Records from the Device back to the user. It is one of two buffers that are alternated between. The other buffer is Buffer1. Buffer2 should be large enough to contain (RecordsPerBuffer*TransferLength) many 16-bit values (VB-Integer, C&C++-short). If the Record header is selected (UseHeader = 1) then Buffer2 should be large enough to hold ATS-SDK Software Manual v5.6.0 171

(RecordsPerBuffer*(TransferLength+sizeof(ALAZAR_HEADER)) many 16bit values. WhichOne - This is a return value that indicates to the user which of the two Buffers (Buffer1 or Buffer2) the data was transferred into. error - ADMA_Completed - No errors occurred ADMA_Buffer1Invalid - Buffer1 is not a suitable buffer ADMA_Buffer2Invalid - Buffer2 is not a suitable buffer ADMA_BoardHandleInvalid Board handle is not valid ADMA_InternalBuffer1Invalid - The routine cannot allocate enough memory because system resources are low ADMA_InternalBuffer2Invalid - The routine cannot allocate enough memory because system resources are low ADMA_OverFlow A hardware overflow occurred ADMA_InvalidChannel - The channel selected is invalid ADMA_DMAInProgress - A memory transfer is in progress ADMA_UseHeaderNotSet UseHeader must be set ADMA_HeaderNotValid An invalid header was encountered ADMA_InvalidRecsPerBuffer RecordCount must be a perfect multiple of RecsPerBuffer ADMA_Success is equivalent to ADMA_Completed TriggersOccurred - This is the total number of triggers that have been captured since the last start capture. r4 - RESERVED Return: Refer to the Return code values listed in API RETURN CODES VALUES Notes: Both Buffer1 and Buffer2 will be used in transferring the data from the device back to the user application. However, if the RecordsPerBuffer is set in conjunction with TransferLength such that all the data will fit in only one Buffer, then Only Buffer1 will be used and the WhichOne variable will equal 0. Only one transaction will take place. RecordsTransferred will be modified by the routine and is used to accumulate the number of record that has been transferred. Always set the variable to 0 before calling this routine and never modify its contents between repeating calls. The user must ensure that Buffer1 and Buffer2 are valid buffers. Buffer1 and Buffer2 should be large enough to contain (RecordsPerBuffer*TransferLength) many 16-bit values (VB-Integer, C&C++-short). If the Record header is selected (UseHeader = 1) then Buffer1 and Buffer2 should be large enough to hold (RecordsPerBuffer*(TransferLength+sizeof(ALAZAR_HEADER)) many 16bit values (VB-Integer, C&C++-short). 172 ATS-SDK Software Manual v5.6.0

AlazarStartAutoDMA C/C++ Prototype RETURN_CODE AlazarStartAutoDMA ( HANDLE h, void* Buffer1, U32 UseHeader, U32 ChannelSelect, long TransferOffset, U32 TransferLength, U32 RecordsPerBuffer, U32 RecordCount, AUTODMA_STATUS* error, U32 cflags, U32 r2, U32 *r3, U32 *r4); Visual BASIC Prototype Public Declare Function AlazarStartAutoDMA Lib "ATSApiVB.dll" ( ByVal h As Integer, ByRef Buffer1 As Any, ByVal UseHeader As Long, ByVal ChannelSelect As Long, ByVal TransferOffset As Integer, ByVal TransferLength As Long, ByVal RecordsPerBuffer As Long, ByVal RecordCount As Long, ByRef error As Long, ByVal cflags As Long, ByVal r2 As Long, ByRef r3 As Long, ByRef r4 As Long) As Long Description: This routine is used to enable the AUTODMA functionalities of the device. It must be called prior to calling AlazarGetNextBuffer(...). Input: h - Board identification handle UseHeader - If equal to 1 then the AUTODMA record header will precede each record in the Buffer. ChannelSelect - CHANNEL_A (single channel mode) - CHANNEL_B (single channel mode) - CHANNEL_A CHANNEL_B (dual channel mode) TransferOffset - Transfer offset relative to the Trigger point for each record. TransferLength - The amount to transfer for each record. ATS-SDK Software Manual v5.6.0 173

RecordsPerBuffer - The number of records that will be transferred into Buffer1. (Please note the size information in Buffer1 description) RecordCount - The number of records to be captured during this acquisition. Infinite Record Count can be used to create an endless capture for any AutoDMA mode. To use Inifinite records, set the RecordCount parameter of AlazarStartAutoDMA( ) to 0x7FFFFFFF. It is the user's responsibility to set the criteria for stopping an acquisition. Note that AlazarStartAutoDMA routine will overwrite any previous settings for this parameter with the value passed in the RecordCount parameter (Please note the size information in Buffer1 description) cflags - Control Flags,{0 = The routine will automatically start the acquisition, 1 = The user application must call AlazarStartCapture to start the acquisition}. The constants available are as follows: // Control Flags for AutoDMA used in AlazarStartAutoDMA #define ADMA_EXTERNAL_STARTCAPTURE 0x00000001 #define ADMA_TRADITIONAL_MODE 0x00000000 #define ADMA_CONTINUOUS_MODE 0x00000100 #define ADMA_NPT 0x00000200 Detailed breakdown of the bit field controls bit 0: 0x00000000 - The routine will automatically start the acquisition 0x00000001 - The User must call AlazarStartCapture to start the acquisition bits 7..1: (For future use) bits 11...8: 0x00000000 = Traditional Auto Dma mode captures 0x00000100 = Continuous Streaming mode without trigger 0x00000200 - No-Pre-Trigger Auto Dma mode captures. bits 31..12: (For future use) r2 - RESERVED Output: Buffer1 - Data buffer for the first set of transferred records. Buffer1 should be large enough to contain (RecordsPerBuffer*TransferLength) many 16-bit values (VB-Integer, C&C++-short). If the Record header is selected (UseHeader = 1) then Buffer1 should be large enough to hold (RecordsPerBuffer*(TransferLength+sizeof(ALAZAR_HEADER)) many 16bit values. error - ADMA_Completed - No errors occurred 174 ATS-SDK Software Manual v5.6.0

ADMA_Buffer1Invalid - Buffer1 is not a suitable buffer ADMA_Buffer2Invalid - Buffer2 is not a suitable buffer ADMA_BoardHandleInvalid Board handle is not valid ADMA_InternalBuffer1Invalid - The routine cannot allocate enough memory because system resources are low ADMA_InternalBuffer2Invalid - The routine cannot allocate enough memory because system resources are low ADMA_OverFlow A hardware overflow occurred ADMA_InvalidChannel - The channel selected is invalid ADMA_DMAInProgress - A memory transfer is in progress ADMA_UseHeaderNotSet UseHeader must be set ADMA_HeaderNotValid An invalid header was encountered ADMA_InvalidRecsPerBuffer RecordCount must be a perfect multiple of RecsPerBuffer ADMA_Success is equivalent to ADMA_Completed r3 - RESERVED r4 - RESERVED Return: Refer to the Return code values listed in API RETURN CODES VALUES Notes: The user must ensure that Buffer1 is a valid buffer of the appropriate size. Buffer1 should be large enough to contain (RecordsPerBuffer*TransferLength) many 16-bit values (VB-Integer, C&C++-short). If the Record header is selected (UseHeader = 1) then Buffer1 should be large enough to hold (RecordsPerBuffer*(TransferLength+sizeof(ALAZAR_HEADER)) many 16bit values. ATS-SDK Software Manual v5.6.0 175

AlazarStopAutoDMA C/C++ Prototype void AlazarStopAutoDMA ( HANDLE h ); Visual Basic Prototype Public Declare Function AlazarStopAutoDMA Lib "ATSApiVB.dll" ( ByVal h As Integer ) Description: This API is used to inhibit the software from issuing any new DMA request to the device. It is meant as a helper function for the AlazarFlushAutoDMA API function. It is useful in situations where the application software has multiple threads. The software can call this routine to stop the device from issuing DMA requests in preparation for calling API AlazarFlushAutoDMA. Input: Return: None. h - Handle to the board. 176 ATS-SDK Software Manual v5.6.0

AlazarWaitForBufferReady C/C++ Prototype RETURN_CODE AlazarWaitForBufferReady (HANDLE h, U32 tms); Visual BASIC Prototype Public Declare Function AlazarWaitForBufferReady Lib "ATSApiVB.dll" ( ByVal h As Integer, ByVal tms As Long, ) As Long This function will stall the current thread of execution for tms number milliseconds or until a buffer has been successfully transferred to a user space AutoDMA buffer. The function must be called after API AlazarEvents(h,1) and before API AlazarGetNextAutoDMABuffer( ). It will wait on the driver to signal the Driver's Internal registered event for up to tms number of milliseconds. When the DMA completes, the signaling event will wake up the Api. Below is a pseudo-code fragment that shows the operations of API AlazarEvents( ) and API AlazarWaitForBufferReady( ). Input: Return: h - handle to the device tms - time in milliseconds 670 - signifies that a NULL was used for the handle 671 - signifies that the current device driver does not support events. 672 Events were not activated using API AlazarEvents. ApiSuccessFul or 512 signifies that the internal wait event was successfully registered and signaled by the ISR. ApiFailed or 513 signifies that the internal wait event did not register. ApiWaitTimeOut or 579 signifies that the internal wait event was not signaled by the ISR. Pseudo-code: // //Configure the devices operating parameters. // ATS-SDK Software Manual v5.6.0 177

AlazarSetRecordSize(...); AlazarSetCaptureClock(...); AlazarInputControl(...); AlazarInputControl(...); AlazarSetTriggerOperation(...) // AlazarEvents(h,1); // AlazarStartAutoDMA(...); while (looping == 1) { AlazarWaitForBufferReady(h, 10); status = AlazarGetNextAutoDMABuffer(); if (status == 513) { looping = 0; } //Valid data exists in either UserData[0] or UserData[1] if ((WhichOne == 0) (WhichOne == 1)) { //Process Your Data here... } if (error == ADMA_OverFlow) { looping = 0; returnvalue = -4; } } AlazarCloseAUTODma(...); // AlazarEvents(h,0); // Note: This functionality is only present on the ATS460, ATS660 and ATSS860 devices. If AlazarEvents(h,1) was not used, calling AlazarWaitForBuffer(...) will return ApiFailed and will not disrupt any ongoing signal captures. 178 ATS-SDK Software Manual v5.6.0

API Return Code Values The following return codes are used by various API routines: Value Meaning 512 ApiSuccess 513 ApiFailed 514 ApiAccessDenied 515 ApiDmaChannelUnavailable 516 ApiDmaChannelInvalid 517 ApiDmaChannelTypeError 518 ApiDmaInProgress 519 ApiDmaDone 520 ApiDmaPaused 521 ApiDmaNotPaused 522 ApiDmaCommandInvalid 523 ApiDmaManReady 524 ApiDmaManNotReady 525 ApiDmaInvalidChannelPriority 526 ApiDmaManCorrupted 527 ApiDmaInvalidElementIndex 528 ApiDmaNoMoreElements 529 ApiDmaSglInvalid 530 ApiDmaSglQueueFull 531 ApiNullParam 532 ApiInvalidBsIndex, 533 ApiUnsupportedFunction 534 ApiInvalidPciSpace 535 ApiInvalidIopSpace 536 ApiInvalidSize 537 ApiInvalidAddress 538 ApiInvalidAccessType 539 ApiInvalidIndex ATS-SDK Software Manual v5.6.0 179

540 ApiMuNotReady 541 ApiMuFifoEmpty 542 ApiMuFifoFull 543 ApiInvalidRegister 544 ApiDoorbellClearFailed 545 ApiInvalidUserPin 546 ApiInvalidUserState 547 ApiEepromNotPresent 548 ApiEepromTypeNotSupported 549 ApiEepromBlank 550 ApiConfigAccessFailed 551 ApiInvalidDeviceInfo 552 ApiNoActiveDriver 553 ApiInsufficientResources 554 ApiObjectAlreadyAllocated 555 ApiAlreadyInitialized 556 ApiNotInitialized 557 ApiBadConfigRegEndianMode 558 ApiInvalidPowerState 559 ApiPowerDown 560 ApiFlybyNotSupported 561 ApiNotSupportThisChannel 562 ApiNoAction 563 ApiHSNotSupported 564 ApiVPDNotSupported 565 ApiVpdNotEnabled 566 ApiNoMoreCap 567 ApiInvalidOffset 568 ApiBadPinDirection 569 ApiPciTimeout 570 ApiDmaChannelClosed 571 ApiDmaChannelError 572 ApiInvalidHandle 573 ApiBufferNotReady 574 ApiInvalidData 575 ApiDoNothing 576 ApiDmaSglBuildFailed 577 ApiPMNotSupported 578 ApiInvalidDriverVersion 579 ApiWaitTimeout, 580 ApiWaitCanceled, 581 ApiLastError 180 ATS-SDK Software Manual v5.6.0

The Following Error are retuned by the Relevant API in their error pointer parameter, Value Description Relevant API 603 Internal DMA trigger buffer was AlazarGetTriggerAddress not allocated. 604 AutoDMA mode is active AlazarGetTriggerAddress 606 The RecordNumber is invalid AlazarRead 607 RecordCount is too large AlazarSetRecordCount 620 Failed to find the first image AlazarGetOEMFPGAName 621 Failed to Find an image AlazarGetOEMFPGAName 622 No other FPGA exists AlazarGetOEMFPGAName 624 Invalid working directory AlazarGetOEMFPGAName, AlazarSetWorkingDirectory 626 Invalid File Name AlazarParseFPGAName 630 NULL pointer for Path AlazarGetOEMFPGAName 670 NULL pointer for handle AlazarWaitForBufferReady 671 Events are not supported AlazarWaitForBufferReady 672 Events are not active AlazarWaitForBufferReady ATS-SDK Software Manual v5.6.0 181

ALAZAR TECHNOLOGIES INC. 3551 St-Charles, Unit 640 Kirkland, QC CANADA H9H 3C4 Tel: (514) 633-0001 Fax: (514) 633-0021 E-mail: info@alazartech.com Web: www.alazartech.com www.pci-digitizers.com