- I've started marking spots with [[[ ]]] where more work is needed
- In general, Note should be merged into Purpose. "Assume that code is non-communicative." All kinds of important stuff has been tucked away in notes people don't read.
- How to start Purpose? "Use this function to [Verb]"? "This function [Verbs]"? "[Verbs]"?
- Add javascript that scans all body text for "foo()" that match H3 text and converts to link-to-H3 ID
- Add javascript that scans all body text for acces-defined types and TBoardIndex for <definition> or something to get popup core types
- The hastag / table-of-contents interacts poorly with javascript-generated data-lang duplicates such that Firefox needs a "refresh / F5" to get it right

Top ↑

# Introduction

This manual acts as a reference for the M.2- / mPCIe-AIO Family's Application Programming Interface, “AIOAIO.dll”, which provides convenient, high-level functions for using the Analog Inputs and Outputs of these cards from any programming language or environment.

Note: | This manual allows you to select a programming language (C#, Python, C/C++, or Delphi) and the manual content changes to reflect your choice. Content that is specific to a particular language is highlighted. Use the buttons at the top left to select your preferred reference language. The currently selected language is Python Delphi CPP CSharp.

Three primary types of functions are provided: Board-level functions that operate on the card as a whole, such as "BRD_GetName()", ADC-specific functions, such as "ADC_GetImmediate()", and DAC-specific functions, such as "DAC_Output()"

In addition to these a fourth group of functions is provided to support very low-level operation of the device, in a manner similar to our AIOWDM.dll-provided API. These functions include register transactions, buffer/register transactions, and IRQ-handling functions.

## How To Use This Reference

First, read the entirety of this introduction.

Next, read the source code of one of our sample programs in the programming language of your choice, and refer to this manual for the description of each API used, if needed.

Note: | Not all of the API functions described in this manual will apply to your specific hardware. For example, not all models include Analog Outputs, thus the DAC_* functions will not apply to those cards.

## API Overview

The AIOAIO API (application programming interface) is designed to be convenient to use. There are no required initialization steps, no device handles, no de-init code to run. Functions are provided in a variety of forms specific to each programming language, allowing the API to match the expectations of programmers, regardless of language. We've also provided various "overloaded" versions for many functions, allowing you to switch between 16-bit count values and voltage values, for example, just by changing your variable types from integers to floating-point. Or control multiple DACs simultaneously by passing an array of values instead of a single variable — in either counts or volts.

### Important Terms

Board Index

  Instead of presenting you with using device files, handles, or other low-level hardware-control mechanisms AIOAIO maintains an internal list of all detected devices, exposed via the BoardIndex TBoardIndex parameter, iBoard. The first detected device will be zero (0), and additional detected cards are assigned sequential indices.

Sequencer Index

  The two onboard ADC circuits run completely independently and are referred to as "ADC Sequencer" and selected via the SequencerIndex TSequencerIndex parameter, iSequencer. Each sequencer is configured independently for speed, channels to acquire, etc.

Range Code

  Each of the ADC channels can be acquired at any of 8 bipolar ranges, and each DAC channel can be configured for any of four bipolar and four unipolar ranges. AIOAIO uses the RangeCode TRangeCode to represent the available ranges, both as "FourCC" values, like "B±10" (0x3031E142) for the bipolar 10V range (-10 to +10V), and by register-level code specific to the chips involved.

  We highly recommend using the mnemonic, hardware-independent, "FourCC" values for all development. To support this we provide constants like Range.Bipolar10 TRange.Bipolar10 for your use.

  However, because RangeCode TRangeCode supports both ADC and DAC ranges, and is consistent with other hardwares' APIs, you will find more FourCC constants in our API than your ADC or DAC can use. Refer to the ADC_SetRange() and DAC_SetRange() functions for the constant available to each function.

Channel Index

  Channel Index is an alias for "Channel Number" or just "Channel", starting from zero (0) and incrementing consecutively. Each ADC Sequencer has its own Channels, starting at zero (0) and incrementing through seven (7). The DAC provides Channels zero (0) through three (3).

### Analog Inputs (ADC)

Using the Analog Inputs can be as simple as calling ADC_GetImmediate() in a loop. You should be able to achieve tens or even hundreds of kilohertz sampling rate using this technique.

On the other hand, the card is quite powerful, capable of running two, up-to 1MHz, acquisition streams simultaneously, one per ADC. Handling this much data could be complex, but AIOAIO provides a variety of acqusition methods to satisfy all application types:

ADC Immediate mode

  As mentioned, this is a very simple way to take data, but not capable of the fastest speeds and doesn't support simultaneous acquisition from both ADC Sequencers without your application implementing relatively complex multi-threading.

ADC Polling mode

  ADC Polling requires your application to occasionally call ADC_PollData() and ADC_GetData() to collect the samples that have accumulated in the onboard FIFOs. Top speed is limited by your application's worst-case polling interval.

ADC Callback mode

  In ADC Callback mode you accept data from the card via our driver suite calling your function every once in a while. Configure the callback using ADC_SetCallback(). We offer two primary callback function signatures, one that provides the data as an array of double-precision floating point Voltages, and one that provides the low-level "counts" straight from the ADC chip. Both callbacks include an optional array of "status" information, one status per conversion datapoint.

In Polling and Callback modes you can choose how often you want data / callbacks, expressed as either "number of samples per callback" or "number of callbacks per second". AIOAIO calls these "Chunking Types", as in "what type of chunks do you want the data sent in, buffer length or duration?". Select the Chunking Type using ADC_ConfigureAcquire().

### Analog Outputs (DAC)

The (optional) onboard DAC provides four voltage output channels. You can output data as either double-precision volts or 16-bit counts (two's-complement in bipolar ranges; straight binary in unipolar ranges).

To output data to a single DAC channel call DAC_Output(). By using the ciAll sentinel value you can also use DAC_Output() to write the same value to all DACs

To output data to multiple DAC channels simultaneously use the DAC_OutputAll() function.

## AIOAIO Defined Types

We recommend copying these type-aliases into your source files, as C# doesn't support the concept between modules.

    using TWinErrCode     = UInt32;
    using TBoardIndex     = UInt64;
    using TChannelIndex   = UInt32;

#### Specific bit-width types

These types alias existing simple types with language-agnostic explicit-precision names. Convenient "pointer-to" types are provided for each.

    TUInt8          = Byte      ;  TPUInt8        = ^TUInt8   ;
    TUInt16         = Word      ;  TPUInt16       = ^TUInt16  ;
    TUInt32         = LongWord  ;  TPUInt32       = ^TUInt32  ;
    TUInt64         = Int64     ;  TPUInt64       = ^TUInt64  ;
    TUNative        = Cardinal  ;  TPUNative      = ^TUNative ;
    TSingle         = Single    ;  TPSingle       = ^TSingle  ;
    TDouble         = Double    ;  TPDouble       = ^TDouble  ;
    TAnsiChar       = AnsiChar  ;  TPAnsiChar     = ^TAnsiChar;
    TWideChar       = WideChar  ;  TPWideChar     = ^TWideChar;

    Python doesn't use "types".
    AIOAIO.py makes use of the enum module's IntEnum class and uses the ctypes module internally.

#### Enum base types

    TWinErrCode     = TUInt32   ;  TPWinErrCode   = ^TWinErrCode;  // Standard Win32 error codes
    TRangeCode      = TUInt32   ;  TPRangeCode    = ^TRangeCode;
    TSerialNumber   = TUInt64   ;  TPSerialNumber = ^TSerialNumber;
    TBoardIndex     = TUInt64;  // iBoard: which card to control.  Cards are numbered consecutively from 0
    TSequencerIndex = TUInt32;  // iSequencer: which ADC Sequencer to read/control
    TChannelIndex   = TUInt32;  // Channels are numbered consecutively from 0
    TIRQIndex       = TUint32;  // reserved, use iiOnly (0)
    TChunkingType   = TUInt32;  // chunk data by amount or by duration
    TCallbackType   = TUInt32;

## AIOAIO Defined Enums / Constants

    ctRaw    = TCallbackType($00776152);    // FourCC('Raw'#0);
    ctCounts = TCallbackType($6E756F43);    // FourCC('Coun');
    ctV      = TCallbackType($746C6F56);    // FourCC('Volt');
    ctNone   = TCallbackType($FFFFFFFF);

    ctAuto = TChunkingType(0);
    ctSize = TChunkingType(1);
    ctRate = TChunkingType(2);

    siFirst = TSequencerIndex(0);
    siSecond = TSequencerIndex(1);
    siBoth = TSequenceryIndex(-1);

    rcNoChange   = TRangeCode(-1);
    rcUnipolar10 = TRangeCode($30313055); // FourCC('U010');
    rcUnipolar5  = TRangeCode($35303055); // FourCC('U005');
    rcBipolar10  = TRangeCode($3031E142); // FourCC('B±10');
    rcBipolar5   = TRangeCode($3530E142); // FourCC('B±05');
    rcBipolar2_5 = TRangeCode($BD32E142); // FourCC('B±2½');
    rcCurrent420 = TRangeCode($30323449); // FourCC('I420');  mA current
    rcRangeCode0 = TRangeCode(0);
    rcRangeCode1 = TRangeCode(1);
    rcRangeCode2 = TRangeCode(2);
    rcRangeCode3 = TRangeCode(3);
    rcRangeCode4 = TRangeCode(4);

    ciAll = TChannelIndex(-1);

    biAuto = TBoardIndex(0);
    biNone = TBoardIndex(-1);

    iiOnly = TIRQIndex(0);

    [[[ tbd ]]]

    public const TWinErrCode ERROR_SUCCESS = 0;
    public const TBoardIndex biAuto = 0;
    public const TBoardIndex biNone = 0xFFFFFFFF_FFFFFFFF;
    public const TChannelIndex ciAll = 0xFFFF_FFFF;

    public enum Range : UInt32
    {
    	NoChange   = 0xFFFFFFFF,
    	Unipolar10 = 0x30313055, // FourCC("U010");
    	Unipolar5  = 0x35303055, // FourCC("U005");
    	Bipolar10  = 0x3031E142, // FourCC("B±10");
    	Bipolar5   = 0x3530E142, // FourCC("B±05");
    	Bipolar2_5 = 0xBD32E142, // FourCC("B±2½");
    	Current420 = 0x30323449, // FourCC("I420"); // 4-20mA
    	Code0 = 0,
    	Code1 = 1,
    	Code2 = 2,
    	Code3 = 3,
    	Code4 = 4,
    	Code5 = 5,
    	Code6 = 6,
    	Code7 = 7,
    }

    public enum Sequencer : UInt32 { First = 0, Second = 1 }
    public enum IRQIndex : UInt32 { Only = 0 }
    public enum ChunkingType : UInt32 { Auto = 0, Size = 1, Rate = 1}
    public enum CallbackType : UInt32 { Raw = 0, Volts = 1, Current = 2}

    ERROR_SUCCESS = 0
    biAuto = 0		# board index
    biNone = -1		# board index
    ciAll = 0xFFFF_FFFF 	# channel index

    class Range(IntEnum):
    	NoChange   = 0xFFFFFFFF,
    	Unipolar10 = 0x30313055, # FourCC("U010")
    	Unipolar5  = 0x35303055, # FourCC("U005")
    	Bipolar10  = 0x3031E142, # FourCC("B±10")
    	Bipolar5   = 0x3530E142, # FourCC("B±05")
    	Bipolar2_5 = 0xBD32E142, # FourCC("B±2½")
    	Current420 = 0x30323449, # FourCC("I420") # 4-20mA
    	Code0 = 0
    	Code1 = 1
    	Code2 = 2
    	Code3 = 3
    	Code4 = 4
    	Code5 = 5
    	Code6 = 6
    	Code7 = 7

    class Sequencer(IntEnum):
    	Both = -1
    	First = 0
    	Second = 1

    class IRQIndex(IntEnum):
    	Only = 0

    class ChunkingType(IntEnum):
    	Auto = 0
    	Size = 1
    	Rate = 1

    class CallbackType(IntEnum):
    	Raw    = 0x00776152	# FourCC('Raw'#0)
    	Volts  = 746C6F56	# FourCC('Volt')
    	Counts = 0x6E756F43	# FourCC('Coun')
    	None   = 0xFFFFFFFF

Use these enums as "Sequencer.First" or "CallbackType.Volts"

### Error/Status Return Values

Unless otherwise documented all return values are Microsoft defined “Win32” error codes (see BRD_GetHighestBoardIndex() for the exception to this rule).
A return of “ERROR_SUCCESS” (equal to 0) means no error occurred.

Unless otherwise documented all functions return a tuple containing an error/status value in the first position. This status is a Microsoft defined “Win32” error code (see BRD_GetHighestBoardIndex() for the exception to this rule).
A return of “ERROR_SUCCESS” (equal to 0) means no error occurred.

The set of error codes AIOAIO.dll can produce is the combined set called out in our AIOAIO.dll source code (provided) plus anything the OS's lower-level code decides to throw our way.

Refer to each function description for an explanation of the other values returned in the tuple.

# Card-level functions

## Functions You Call At Initialization

These functions provide plug-and-play compatibility, allowing your application to determine at runtime how many cards are detected, and the model of each card.

In addition, BRD_Reset() allow you to return the card to the known power-up / reset condition at any time.

### BRD_GetHighestBoardIndex()

Purpose
  Returns the Board Index of the last compatible device that is detected.
Signature
  BRD_GetHighestBoardIndex() -> (highest (BoardIndex))
  function BRD_GetHighestBoardIndex: TBoardIndex;
  BoardIndex BRD_GetHighestBoardIndex();
  unsigned long BRD_GetHighestBoardIndex(void);
Arguments
  None
Returns
  The highest numbered Board Index detected.
Example
  for iBoard := 0 to BRD_GetHighestBoardIndex() do begin
  …
  end;
  foreach ( TBoardIndex iBoard in Enumerable.Range(0, AIOAIO.BRD_GetHighestBoardIndex()+1).ToArray() )
  {
  …
  }
  for iBoard in range(AIOAIO.BRD_GetHighestBoardIndex()+1)
  …
  for ( iBoard = 0; iBoard <= BRD_GetHighestBoardIndex(); ++iBoard )
  {
  …
  }

### BRD_GetName()

Purpose
  Fetches the model name as a string.
Signature
  function BRD_GetName(iBoard: TBoardIndex; BufLen: TUInt32; pNameBuf: TPAnsiChar = nil; pNameLen: TPUInt32 = nil): TWinErrCode; overload; name 'BRD_GetNameA';
  function BRD_GetName(iBoard: TBoardIndex; BufLen: TUInt32; pNameBuf: TPWideChar = nil; pNameLen: TPUInt32 = nil): TWinErrCode; overload; name 'BRD_GetNameW';
  function BRD_GetNameA(iBoard: TBoardIndex; BufLen: TUInt32; pNameBuf: TPAnsiChar = nil; pNameLen: TPUInt32 = nil): TWinErrCode;
  function BRD_GetNameW(iBoard: TBoardIndex; BufLen: TUInt32; pNameBuf: TPWideChar = nil; pNameLen: TPUInt32 = nil): TWinErrCode;
  BRD_GetName(iBoard (BoardIndex)) -> (status (WinError), name (str));
  BRD_GetNameW(iBoard (BoardIndex)) -> (status (WinError), name (str));
  BRD_GetNameA(iBoard (BoardIndex)) -> (status (WinError), name (str));
  WinError BRD_GetName(Byte Data);
  WinError BRD_GetName(unsigned char Data);
Arguments
  iBoard
    The index of the device to query; generally either biAuto or a specific card's Board Index.
  BufLen
    The available size of the buffer passed via pNameBuf.
  pNameBuf
    a buffer to hold the name string (passed via the array pointer).
  pNameLen
    The actual length of the string stored in the buffer passed via pNameBuf.
  iBoard
    The index of the device to query; generally either biAuto or a specific card's Board Index.
Returns
  Windows standard “Win32” error codes. ERROR_SUCCESS (0) means “Success”.
  Tuple containing a Windows standard “Win32” error code, and the name string: (status, name). A status of ERROR_SUCCESS (0) means “Success”
Example
  status, name = BRD_GetName(biAuto)

### BRD_Reset()

Purpose
  (Re-)Start from a known state: Causes the hardware to reset to the power-on / reset "defaults" condition.
Signature
  BRD_Reset(iBoard (BoardIndex)) -> (status (WinError))
  function BRD_Reset(iBoard: TBoardIndex): TWinErrCode;
Arguments
  iBoard
    The index of the device to query; generally either biAuto or a specific card's Board Index.
Returns
  Windows standard “Win32” error codes. ERROR_SUCCESS (0) means “Success”.

# Analog To Digital (ADC)

## Overview

The card has two Analog-to-Digital converter chips and associated circuitry, referred to as "ADC Sequencers", herein. These ADC Sequencers operate independently, each with its own end-of-scan-channel, sample rate divisor, gains per channel, and ADC Data FIFO.

Each of the ADC Sequencers on the card can acquire analog data from a single channel or a scan of channels. The API allows samples to be taken singly or periodically. Periodic data can be acquired as a block (of specified length), or as a continuous stream of data flowing through the device into your application until stopped.

Each scan starts from channel zero (0) of that ADC Sequencer and continues to the specified last channel. Data is sampled at the sample-rate configured, up to 1 million samples per second (per sequencer). Therefore, if you acquire data only from channel 0 (of a sequencer), that channel can be sampled as often as once per microsecond. An ADC Sequencer configured to acquire all 8 of its inputs at 1MHz would sample any given channel once every 8µs.

Use the iSequencer parameter of the ADC_ functions to control or read data associated with a specific ADC Sequencer. The constants Sequencer.First TSequencerIndex.First and Sequencer.Second TSequencerIndex.Second are provided to improve code readability and portability.

[[[ Discuss the use of overloaded functions, ciAll, and default parameters ]]]

## Easy Read One Input Now

### ADC_GetImmediate()

Purpose
  Acquire a single conversion result from the specified input, optionally overriding the configured range.
Note
  This is the only function call necessary to operate the Analog Inputs — If you don't need to acquire data faster than a few thousand readings per second, and don't need the data to be periodic.
  No setup calls, no init, nothing but this single API Function is necessary. Just call ADC_GetImmediate() whenever you need an input channel's value and a few microseconds later ADC_GetImmediate() will finish and provide the data.
  For periodic or faster data, use ADC_AcquireBlock() or ADC_AcquireStream()
Signature
  ADC_GetImmediateV( iBoard, ADC, bdifferential, ch, range = Range.NoChange) -> (status, Volts)
  ADC_GetImmediateRaw( iBoard, ADC, bdifferential, ch, range = Range.NoChange) -> (status, Volts)
  function ADC_GetImmediate(iBoard: TBoardIndex; iSequencer: TSequencerIndex; out V: TDouble; bDifferential: TBool; Ch: TChannelIndex; Range: TRangeCode = rcNoChange): TWinErrCode; overload; name 'ADC_GetImmediateV';
  function ADC_GetImmediate(iBoard: TBoardIndex; iSequencer: TSequencerIndex; out Data: TUInt32; bDifferential: TBool; Ch: TChannelIndex; Range: TRangeCode = rcNoChange): TWinErrCode; overload; name 'ADC_GetImmediateRaw';
  function ADC_GetImmediateV(iBoard: TBoardIndex; iSequencer: TSequencerIndex; out V: TDouble; bDifferential: TBool; Ch: TChannelIndex; Range: TRangeCode = rcNoChange): TWinErrCode;
  function ADC_GetImmediateRaw(iBoard: TBoardIndex; iSequencer: TSequencerIndex; out Data: TUInt32; bDifferential: TBool; Ch: TChannelIndex; Range: TRangeCode = rcNoChange): TWinErrCode;
  TWinErrCode ADC_GetImmediateV(TBoardIndex iBoard, Sequencer ADC, out double V, TBool bDifferential, TChannelIndex ch, Range range = Range.NoChange);
Arguments
  iBoard
    The index of the device to get a sample from; generally either biAuto or a specific device's Board Index.
  iSequencer
    Which ADC Sequencer to take data from.
  bDifferential
    True to acquire this channel as differential, False to acquire as single-ended.
  V
    output parameter where the conversion result is stored (ADC_GetImmediateV)
  Data
    output parameter where the conversion result is stored (ADC_GetImmediateRaw)
  range
    optional: take data at the specified range, overriding the range configured via ADC_SetRange()
  ch
    The channel to take data from.
Returns
  Windows standard “Win32” error codes. ERROR_SUCCESS (0) means “Success”.
  (status, volts) or (status, counts): a tuple containing a Windows standard “Win32” error code, and the conversion result in volts or counts. A status of ERROR_SUCCESS (0) means “Success”

## Functions You Call At Initialization

In order to optimize throughput, and because each access of registers takes time (including round-trip Ring3-0-3 kernel transitions!), as many operations as possible should be moved out of the acquisition-loop into init-time code that only occurs once, regardless of how much data is being collected.

Thus, the following functions are suitable for calling at init, and usually only need to be issued once per program execution.

### ADC_SetRange()

Purpose
  Configures the Analog Input range for one channel, all channels, or for a list of range per channel.
Signature
  ADC_SetRange1( iBoard, iSequencer, channel = ciAll, range = Range.Bipolar10 ) -> (status)
  ADC_SetRangeAll( iBoard, ADC, rangeCt, ranges ) -> (status)
  function ADC_SetRange(iBoard: TBoardIndex; iSequencer: TSequencerIndex; Ch: TChannelIndex = ciAll; RangeCode: TRangeCode = rcBipolar10): TWinErrCode; overload; name 'ADC_SetRange1';
  function ADC_SetRange(iBoard: TBoardIndex; iSequencer: TSequencerIndex; RangeCt: TUInt32; pRangeCodes: TPRangeCode): TWinErrCode; overload; name 'ADC_SetRangeAll';
  function ADC_SetRange1(iBoard: TBoardIndex; iSequencer: TSequencerIndex; Ch: TChannelIndex = ciAll; RangeCode: TRangeCode = rcBipolar10): TWinErrCode;
  function ADC_SetRangeAll(iBoard: TBoardIndex; iSequencer: TSequencerIndex; RangeCt: TUInt32; pRangeCodes: TPRangeCode): TWinErrCode;
Arguments
  iBoard
    The index of the device to configure; generally either biAuto or a specific device's Board Index.
  iSequencer
    Which ADC Sequencer(s) to configure the range(s) of.
  ch
    The channel(s) to configure. To configure all channels (of the specified ADC Sequencer(s)) for the same range, use ChannelIndex.ciAll
  range
    optional: the range to configure on the specified channels. Defaults to ±10V (Range.Bipolar10).
Returns
  Windows standard “Win32” error codes. ERROR_SUCCESS (0) means “Success”.

### ADC_SetRate()

Purpose
  Configures the ADC Sequencer sampling rate for one or both ADC Sequencers, in Hz.
Note
  Not all possible frequencies can be achieved by the onboard ADC Sequencer timing circuit, as it is based on the integer division of a high-frequency clock. Confirm your actual vs requested frequency using ADC_GetRate() (or this function). For example, requesting rates higher than 1MHz will result in an Actual Hz of 1MHz.
Signature
  ADC_SetRate( iBoard, iSequencer, targetHz) -> (status, ActualHz)
  function ADC_SetRate(iBoard: TBoardIndex; iSequencer: TSequencerIndex; Hz: TDouble): TWinErrCode;
Arguments
  iBoard
    The index of the device to configure; generally either biAuto or a specific device's Board Index.
  iSequencer
    Which ADC Sequencer(s) to configure the sample rate for. To configure both ADC Sequencers for the same rate, use siBoth Sequencer.Both.
  targetHz
    The desired sample rate for the specified ADC Sequencer(s).
Returns
  Windows standard “Win32” error codes. ERROR_SUCCESS (0) means “Success”.
  (status, actualHz): a tuple containing a Windows standard “Win32” error code, and the actual Hz. A status of ERROR_SUCCESS (0) means “Success”

### ADC_GetRate()

Purpose
  Provides the configured sample rate for the selected ADC Sequencer, in Hz.
Note
  Not all possible frequencies can be achieved by the onboard ADC Sequencer timing circuit, as it is based on the integer division of a high-frequency clock. Confirm your actual vs requested frequency using this function.
  For example, requesting rates higher than 1MHz will result in an Actual Hz of 1MHz.
Signature
  ADC_GetRate( iBoard, iSequencer ) -> (status, actualHz)
  function ADC_GetRate(iBoard: TBoardIndex; iSequencer: TSequencerIndex; pHz: TPDouble): TWinErrCode;
Arguments
  iBoard
    The index of the device to query; generally either biAuto or a specific device's Board Index.
  iSequencer
    Which ADC Sequencer to query the actual sample rate of.
  actualHz
    out parameter where the actual Hz is returned.
Returns
  Windows standard “Win32” error codes. ERROR_SUCCESS (0) means “Success”.
  (status, actualHz): a tuple containing a Windows standard “Win32” error code, and the actual Hz. A status of ERROR_SUCCESS (0) means “Success”

### ADC_SetChannelCount()

Purpose
  Configure the number of channels per scan.
  ADC_AcquireBlock() and ADC_AcquireStream() acquire multiple data points, starting from channel zero (0) and continuing with sequential channels, up to the number of channels configured by this function, then start over at channel zero (0). You can dwell on channel zero (0) by setting this "channel count" to 1.
Signature
  ADC_SetChannelCount( iBoard, iSequencer, numChannels ) -> status
  function ADC_SetChannelCount(iBoard: TBoardIndex; iSequencer: TSequencerIndex; ChCt: TChannelIndex = ciAll): TWinErrCode;
Arguments
  iBoard
    The index of the device to query; generally either biAuto or a specific device's Board Index.
  iSequencer
    Which ADC Sequencer(s) to configure. To configure both ADC Sequencers for the same number of channels per scan, use siBoth Sequencer.Both.
  numChannels
    The number of channels per scan for the specified ADC Sequencer(s). E.g. "1" to dwell on channel zero (0), or "8" to sample all channels consecutively.
Returns
  Windows standard “Win32” error codes. ERROR_SUCCESS (0) means “Success”.

### ADC_ConfigureAcquire()

Purpose
  Configures the type and size of chunk data should be acquired in. Chunks of ADC Data can be made available at a specific Hz rate (using ChunkingType.Rate), or based on number of samples per chunk (using Chunkingtype.Size).
Signature
  ADC_ConfigureAcquire( iBoard, iSequencer, chunkingType, chunkAmount ) -> (status (WinError))
  function ADC_ConfigureAcquire(iBoard: TBoardIndex; iSequencer: TSequencerIndex; ChunkingType: TChunkingType; Chunk: TUInt32): TWinErrCode;
Arguments
  iBoard
    The index of the device to query; generally either biAuto or a specific device's Board Index.
  iSequencer
    Which ADC Sequencer(s) to configure. To configure both ADC Sequencers for the same number of chunking type, use siBoth Sequencer.Both.
  chunkingType
    Specify data should be chunked by time (ChunkingType.Rate) or amount of data (ChunkingType.Size).
  chunkAmount
    The length of chunks desired, in seconds (ChunkingType.Rate) or number of samples (ChunkingType.Size).
Returns
  Windows standard “Win32” error codes. ERROR_SUCCESS (0) means “Success”.

### ADC_SetCallback()

Purpose
  Configure the data acquisition to use callbacks, and set the callback function pointer to use.
  If you do not call ADC_SetCallback(), or if the callback function pointer is 0/null/None/nil, then AIOAIO.dll will assume you will gather the data using ADC_GetData() instead of via callbacks.
Signature
  ADC_SetCallback( iBoard, iSequencer, callbackType, callback ) -> (status (WinError))
  function ADC_SetCallback(iBoard: TBoardIndex; iSequencer: TSequencerIndex; callbackType: TCallbackType; pCallback: Pointer = nil): TWinErrCode;
Arguments
  iBoard
    The index of the device to query; generally either biAuto or a specific device's Board Index.
  iSequencer
    Which ADC Sequencer(s) to configure. To configure both ADC Sequencers for the same callback function use siBoth Sequencer.Both.
  callbackType
    Data can be provided in TCallbackType.Volts or TCallbackType.Counts (or TCallbackType.Raw) as specified here.
  callback
    function to be called for each chunk of data, as the chunks become available. Verify your function's signature matches the callback type specified.
Returns
  Windows standard “Win32” error codes. ERROR_SUCCESS (0) means “Success”.

#### myADCCallback()

Purpose
  This represents the callback to be provided in your own code. Pass a pointer to this callback as the callback parameter to ADC_SetCallback().
Signature
  myADCCallback_or_whatever_name_you_want([[[ etc ]]])
Arguments
  pBuf
    A pointer to the first of an array of words. Each word is a sample of A/D data. Note that the buffer doesn't necessarily begin or end on scan boundaries, or even channel boundaries; the callback may need to buffer this data, to deal with it once it also has the next buffer.
  BufSize
    The size, in bytes, of the buffer pointed to by pBuf.
  Flags
    A bitmask with only two bits defined; the rest are reserved for future expansion. You should mask out reserved bits when checking bits in Flags. Meanings(and masks) are given below.
  Context
    The same value passed as a context to ADC_BulkContinuousCallback or a similar function.
Returns
  Zero (0) for success. non-zero values get passed upstream.

Flags Bits
Bit | Mask | Meaning
--- | --- | ---
1 | Flags & 2 | End of stream; this is the last buffer. Typically one last zero-size buffer will be passed, in order to set this flag.
2 | Flags & 4 | The BaseBufCount was too small; this buffer was added to the pool, which may interrupt the data stream afterwards. At sampling rates of a hundred Hz, a BaseBufCount of 2 is plenty. On a fast computer, a BaseBufCount of 64 can handle up to 500kHz sampling rate. High sampling rates on a slow computer may require higher BaseBufCount values.

## Start periodically timed ADC

A single sample from any single channel at any range can be acquired with ADC_GetImmediate()

To acquire multiple samples, including from more than single channel, you must start a periodic sequence of conversions using one of the functions described in this section.

### ADC_AcquireBlock()

Purpose
  Acquires a specified number of analog input samples. Can be stopped early by calling ADC_AcquireEnd().
Signature
  ADC_AcquireBlock( iBoard, iSequencer, sampleCount ) -> (status)
  function ADC_AcquireBlock(iBoard: TBoardIndex; iSequencer: TSequencerIndex; SampleCt: TUNative): TWinErrCode;
Arguments
  iBoard
    The index of the device on which to start ADC Bulk Acquisition; generally either biAuto or a specific device's Board Index.
  iSequencer
    Which ADC Sequencer(s) to start. To start both ADC Sequencers use siBoth Sequencer.Both.
  sampleCount
    How many samples of data to acquire.
Returns
  Windows standard “Win32” error codes. ERROR_SUCCESS (0) means “Success”.

### ADC_AcquireStream()

Purpose
  Starts the ADC Sequencer(s) sampling data, continuously, until ADC_AcquireEnd() is called.
Signature
  ADC_AcquireStream( iBoard, iSequencer ) -> (status)
  function ADC_AcquireStream(iBoard: TBoardIndex; iSequencer: TSequencerIndex): TWinErrCode;
Arguments
  iBoard
    The index of the device to halt Bulk ADC acquisition; generally either biAuto or a specific device's Board Index.
  iSequencer
    Which ADC Sequencer(s) to start. To start both ADC Sequencers use siBoth Sequencer.Both.
Returns
  Windows standard “Win32” error codes. ERROR_SUCCESS (0) means “Success”.

## Reading the ADC FIFO

[[[about data read methods, polling vs callbacks]]]

### ADC_PollData()

Purpose
  Efficiently determines if ADC data is available (for ADC_GetData() to gather).
Signature
  ADC_PollData( iBoard, iSequencer ) -> (status)
  function ADC_PollData(iBoard: TBoardIndex; iSequencer: TSequencerIndex): TWinErrCode;
Arguments
  iBoard
    The index of the device to begin background ADC Ring-mode acquisition; generally either biAuto or a specific device's Board Index.
  iSequencer
    The ADC Sequencer to query
Returns
  Windows standard “Win32” error codes. ERROR_SUCCESS (0) means “Data is available”.

### ADC_GetData()

Purpose
  Gathers data acquired via the ADC_AcquireBlock() or ADC_AcquireStream() functions.
Signature
  ADC_GetDataV( iBoard, iSequencer, dataCount ) -> (status, data (volts), statuses, gotDataCount)
  ADC_GetDataCounts( iBoard, iSequencer, dataCount ) -> (status, data (counts), statuses, gotDataCount)
  function ADC_GetData(iBoard: TBoardIndex; iSequencer: TSequencerIndex; DataCt: TUInt32; var GotDataCt: TUInt32; pData: TPDouble = nil; pStatus: TPUInt16 = nil; pTimestamp: TPUInt16 = nil): TWinErrCode; overload; name 'ADC_GetDataV';
  function ADC_GetData(iBoard: TBoardIndex; iSequencer: TSequencerIndex; DataCt: TUInt32; var GotDataCt: TUInt32; pData: TPUInt16 = nil; pStatus: TPUInt16 = nil; pTimestamp: TPUInt16 = nil): TWinErrCode; overload; name 'ADC_GetDataCounts';
  function ADC_GetData(iBoard: TBoardIndex; iSequencer: TSequencerIndex; DataCt: TUInt32; var GotDataCt: TUInt32; pDataRaw: TPUInt32 = nil): TWinErrCode; overload; name 'ADC_GetDataRaw';
  function ADC_GetDataV(iBoard: TBoardIndex; iSequencer: TSequencerIndex; DataCt: TUInt32; var GotDataCt: TUInt32; pData: TPDouble = nil; pStatus: TPUInt16 = nil; pTimestamp: TPUInt16 = nil): TWinErrCode;
  function ADC_GetDataCounts(iBoard: TBoardIndex; iSequencer: TSequencerIndex; DataCt: TUInt32; var GotDataCt: TUInt32; pData: TPUInt16 = nil; pStatus: TPUInt16 = nil; pTimestamp: TPUInt16 = nil): TWinErrCode;
  function ADC_GetDataRaw(iBoard: TBoardIndex; iSequencer: TSequencerIndex; DataCt: TUInt32; var GotDataCt: TUInt32; pDataRaw: TPUInt32 = nil): TWinErrCode;
Arguments
  iBoard
    The index of the card to stop read from; generally either biAuto or a specific device's Board Index.
  iSequencer
    The sequencer from which to gather ADC FIFO Data.
  dataCount
    The amount of data to read. [[[should be somehow related to the chunk type and chunkAmount ? ]]]
  out GotDataCount
    How much data was actually returned. [[[ should be somehow related to the chunk type and chunkAmount ? ]]]
  out pData
    The array of retrieved data, as volts (TDoubles) or counts (TUInt16)
  out pStatus
    An array of TUInt16 status values, one per sample. Pass nil null and the API won't bother passing the status data to you.
Returns
  Windows standard “Win32” error codes. ERROR_SUCCESS (0) means “Success”.
  (status, data, statuses, count): a tuple containing a Windows standard “Win32” error code, an array of ADC data, an array of status values (one per sample), and how many samples were actually returned.

### ADC_ClearData()

Purpose
  Throw away all ADC Data in the specified ADC Sequencer(s) FIFO.
Signature
  ADC_ClearData( iBoard, iSequencer ) -> (status (WinError))
  function ADC_ClearData(iBoard: TBoardIndex; iSequencer: TSequencerIndex): TWinErrCode;
Arguments
  iBoard
    The index of the device to control; generally either biAuto or a specific device's Board Index.
  iSequencer
    Which ADC FIFO to clear. To empty both ADC Data FIFOs use siBoth Sequencer.Both.
Returns
  Windows standard “Win32” error codes. ERROR_SUCCESS (0) means “Success”.

## Stop Acquiring Timed Data

### ADC_AcquireEnd()

Purpose
  This function serves to gracefully cease background acquisition of ADC readings. Calling ADC_AcquireEnd() is how a well-behaved application should close ADC operations started using ADC_AcquireBlock() or ADC_AcquireStream()
Signature
  ADC_AcquireEnd( iBoard, iSequencer ) -> (status (WinError))
  function ADC_AcquireEnd(iBoard: TBoardIndex; iSequencer: TSequencerIndex): TWinErrCode;
Arguments
  iBoard
    The card to control.
  iSequencer
    The sequencer to halt.
Returns
  Windows standard “Win32” error codes. ERROR_SUCCESS (0) means “Success”.

# Digital To Analog (DAC)

## Overview

[[[ about DACs, contrast with ADC as in NO SEQUENCERs ]]]

## DAC Init Functions

The following function must be called one time before the DAC can output commanded values. This is to ensure no DAC outputs any potentially dangerous voltages before the application has configured a known state.

### DAC_SetRange()

Purpose
  Configures the Analog output range for one DAC, all DACs, or for a list of range per DAC, and enables DAC outputs to generate values other than “zero volts”.
Signature
  DAC_SetRange1( iBoard, ch = ciAll, range = Range.NoChange ) -> (status)
  DAC_SetRangeAll( iBoard, rangeCodes ) -> (status)
  function DAC_SetRange(iBoard: TBoardIndex; Ch: TChannelIndex = ciAll; Range: TRangeCode = rcBipolar10): TWinErrCode; overload; name 'DAC_SetRange1';
  function DAC_SetRange(iBoard: TBoardIndex; RangeCt: TUInt32; pRange: TPRangeCode): TWinErrCode; overload; name 'DAC_SetRangeAll';
  function DAC_SetRange1(iBoard: TBoardIndex; Ch: TChannelIndex = ciAll; Range: TRangeCode = rcBipolar10): TWinErrCode;
  function DAC_SetRangeAll(iBoard: TBoardIndex; RangeCt: TUInt32; pRange: TPRangeCode): TWinErrCode;
Arguments
  iBoard
    The index of the device to initialize; generally either biAuto or a specific device's Board Index.
  ch
    The DAC to configure the range for. To configure all DACs to the same range use ciAll.
  RangeCode
    The range to configure on the selected DAC channel(s). We recommend the provided sentinel constants Range.Bipolar10, etc.
Returns
  Windows standard “Win32” error codes. ERROR_SUCCESS (0) means “Success”.
Example
  You can call “DAC_SetRange1( biAuto )”, leaving other parameters default, and all DACs will be configured to the current range, generally the power-on default range.

## Analog Output Functions

about DAC output functions

### DAC_Output()

Purpose
  Output one value to one or all DAC outputs.
Note
  DAC_SetRange() must be called before DAC_Output() for any specific DAC or you will get an error.
Signature
  DAC_OutputCounts( iBoard, ch, counts ) -> (status (WinError))
  DAC_OutputV( iBoard, ch, volts ) -> (status (WinError))
  function DAC_Output(iBoard: TBoardIndex; Ch: TChannelIndex {= ciAll}; V: TDouble): TWinErrCode; overload; name 'DAC_OutputV';
  function DAC_Output(iBoard: TBoardIndex; Ch: TChannelIndex {= ciAll}; Counts: TUInt64): TWinErrCode; overload; name 'DAC_OutputCounts';
  function DAC_OutputV(iBoard: TBoardIndex; Ch: TChannelIndex {= ciAll}; V: TDouble): TWinErrCode;
  function DAC_OutputCounts(iBoard: TBoardIndex; Ch: TChannelIndex {= ciAll}; Counts: TUInt64): TWinErrCode;
Arguments
  iBoard
    The index of the device to control; generally either biAuto or a specific device's Board Index.
  ch
    The DAC channel(s) to output on. Use ciAll to write the same value to all DAC outputs
  V
    The voltage to write
  Counts
    The counts to write
Returns
  Windows standard “Win32” error codes. ERROR_SUCCESS (0) means “Success”.

### DAC_OutputAll()

Purpose
  DAC_OutputVAll, DAC_OutputCountsAll -> DAC_OutputAll quad overload discussion
Signature
  DAC_OutputCountsAll( iBoard, counts ) -> (status (WinError))
  DAC_OutputVAll( iBoard, volts ) -> (status (WinError))
  [[[ function DAC_OutputAll( iboard, count, pdata ); ]]]
Arguments
  iBoard
    The index of the device to initialize; generally either biAuto or a specific device's Board Index.
  counts
    Array of count values to output. If too few values are in the array the last value is duplicated across the remainder of DAC outputs.
  volts
    Array of voltage values to output. If too few values are in the array the last value is duplicated across the remainder of DAC outputs.
Returns
  Windows standard “Win32” error codes. ERROR_SUCCESS (0) means “Success”.

# Raw / Lowest-level Functions

## Overview

## Register-Access Functions

### PIO_In8()

Purpose

  Performs a low-level “control read” transaction. Other functions in this API result in control read, control write, bulk read, and/or bulk write transactions. The lowest-level functions (GenericVendorRead, GenericVendorWrite, AWU_GenericBulkIn, and AWU_GenericBulkOut) exist to bypass the API's logic and algorithms, generating those transactions directly as your application directs.

Signature
  PIO_In8(cardNum, offset) -> data
  function PIO_In8(iBoard: TBoardIndex; Offset: TUInt32): TUInt8;
Arguments
  iBoard
    The index of the device to control; generally either biAuto or a specific device's Board Index.
  Request
    The USB request number associated with the desired transaction. Note that the request type will be "vendor read".
  Value
    The Value word in the USB setup data packet.
  Index
    The Index word in the USB setup data packet.
  pDataSize
    A pointer to the size, in bytes, of the buffer pointed to by pData. Upon exit, this value will be changed to the size, in bytes, of the data read from the device.
  pData
    A pointer to the first of an array of bytes. USB data packet(s) will be read into the array. If DataSize is zero, then pData can be “null”.
Returns
  Windows standard “Win32” error codes. ERROR_SUCCESS (0) means “Success”.

### PIO_In16()

Purpose

  Performs a low-level “control read” transaction. Other functions in this API result in control read, control write, bulk read, and/or bulk write transactions. The lowest-level functions (GenericVendorRead, GenericVendorWrite, AWU_GenericBulkIn, and AWU_GenericBulkOut) exist to bypass the API's logic and algorithms, generating those transactions directly as your application directs.

Signature
  PIO_In16(cardNum, offset) -> data
  function PIO_In16(iBoard: TBoardIndex; Offset: TUInt32): TUInt16;
Arguments
  iBoard
    The index of the device to control; generally either biAuto or a specific device's Board Index.
  Request
    The USB request number associated with the desired transaction. Note that the request type will be "vendor read".
  Value
    The Value word in the USB setup data packet.
  Index
    The Index word in the USB setup data packet.
  pDataSize
    A pointer to the size, in bytes, of the buffer pointed to by pData. Upon exit, this value will be changed to the size, in bytes, of the data read from the device.
  pData
    A pointer to the first of an array of bytes. USB data packet(s) will be read into the array. If DataSize is zero, then pData can be “null”.
Returns
  Windows standard “Win32” error codes. ERROR_SUCCESS (0) means “Success”.

### PIO_In32()

Purpose

  Performs a low-level “control read” transaction. Other functions in this API result in control read, control write, bulk read, and/or bulk write transactions. The lowest-level functions (GenericVendorRead, GenericVendorWrite, AWU_GenericBulkIn, and AWU_GenericBulkOut) exist to bypass the API's logic and algorithms, generating those transactions directly as your application directs.

Signature
  PIO_In32(cardNum, offset) -> data
  function PIO_In32(iBoard: TBoardIndex; Offset: TUInt32): TUInt32;
Arguments
  iBoard
    The index of the device to control; generally either biAuto or a specific device's Board Index.
  Request
    The USB request number associated with the desired transaction. Note that the request type will be "vendor read".
  Value
    The Value word in the USB setup data packet.
  Index
    The Index word in the USB setup data packet.
  pDataSize
    A pointer to the size, in bytes, of the buffer pointed to by pData. Upon exit, this value will be changed to the size, in bytes, of the data read from the device.
  pData
    A pointer to the first of an array of bytes. USB data packet(s) will be read into the array. If DataSize is zero, then pData can be “null”.
Returns
  Windows standard “Win32” error codes. ERROR_SUCCESS (0) means “Success”.

### PIO_Out8()

Purpose

  Performs a low-level “control read” transaction. Other functions in this API result in control read, control write, bulk read, and/or bulk write transactions. The lowest-level functions (GenericVendorRead, GenericVendorWrite, AWU_GenericBulkIn, and AWU_GenericBulkOut) exist to bypass the API's logic and algorithms, generating those transactions directly as your application directs.

Signature
  PIO_Out8(cardNum, offset, data) -> (status (WinError))
  function PIO_Out8(iBoard: TBoardIndex; Offset: TUInt32; Data: TUInt8): TWinErrCode;
Arguments
  iBoard
    The index of the device to control; generally either biAuto or a specific device's Board Index.
  Request
    The USB request number associated with the desired transaction. Note that the request type will be "vendor read".
  Value
    The Value word in the USB setup data packet.
  Index
    The Index word in the USB setup data packet.
  pDataSize
    A pointer to the size, in bytes, of the buffer pointed to by pData. Upon exit, this value will be changed to the size, in bytes, of the data read from the device.
  pData
    A pointer to the first of an array of bytes. USB data packet(s) will be read into the array. If DataSize is zero, then pData can be “null”.
Returns
  Windows standard “Win32” error codes. ERROR_SUCCESS (0) means “Success”.

### PIO_Out16()

Purpose

  Performs a low-level “control read” transaction. Other functions in this API result in control read, control write, bulk read, and/or bulk write transactions. The lowest-level functions (GenericVendorRead, GenericVendorWrite, AWU_GenericBulkIn, and AWU_GenericBulkOut) exist to bypass the API's logic and algorithms, generating those transactions directly as your application directs.

Signature
  PIO_Out16(cardNum, offset, data) -> (status (WinError))
  function PIO_Out16(iBoard: TBoardIndex; Offset: TUInt32; Data: TUInt16): TWinErrCode;
Arguments
  iBoard
    The index of the device to control; generally either biAuto or a specific device's Board Index.
  Request
    The USB request number associated with the desired transaction. Note that the request type will be "vendor read".
  Value
    The Value word in the USB setup data packet.
  Index
    The Index word in the USB setup data packet.
  pDataSize
    A pointer to the size, in bytes, of the buffer pointed to by pData. Upon exit, this value will be changed to the size, in bytes, of the data read from the device.
  pData
    A pointer to the first of an array of bytes. USB data packet(s) will be read into the array. If DataSize is zero, then pData can be “null”.
Returns
  Windows standard “Win32” error codes. ERROR_SUCCESS (0) means “Success”.

### PIO_Out32()

Purpose

  Performs a low-level “control read” transaction. Other functions in this API result in control read, control write, bulk read, and/or bulk write transactions. The lowest-level functions (GenericVendorRead, GenericVendorWrite, AWU_GenericBulkIn, and AWU_GenericBulkOut) exist to bypass the API's logic and algorithms, generating those transactions directly as your application directs.

Signature
  PIO_Out32(cardNum, offset, data) -> (status (WinError))
  function PIO_Out32(iBoard: TBoardIndex; Offset: TUInt32; Data: TUInt32): TWinErrCode;
Arguments
  iBoard
    The index of the device to control; generally either biAuto or a specific device's Board Index.
  Request
    The USB request number associated with the desired transaction. Note that the request type will be "vendor read".
  Value
    The Value word in the USB setup data packet.
  Index
    The Index word in the USB setup data packet.
  pDataSize
    A pointer to the size, in bytes, of the buffer pointed to by pData. Upon exit, this value will be changed to the size, in bytes, of the data read from the device.
  pData
    A pointer to the first of an array of bytes. USB data packet(s) will be read into the array. If DataSize is zero, then pData can be “null”.
Returns
  Windows standard “Win32” error codes. ERROR_SUCCESS (0) means “Success”.

## Bulk Register-Access Functions

Each call to any AIOAIO.dll function that touches hardware requires passing down through the userland->kernel->userland Ring3-0-3 transition, and thus consumes many extra microseconds.

The Bulk register-access functions allow a single call to read multiple times from the hardware's registers with a single kernel transition's overhead.

AIOAIO.dll exports both input and output bulk register-access functions (in 8-, 16-, and 32-bit widths). Only the bulk register read function at 32-bits, PIO_INS32(), is documented here as only the ADC FIFOs are suitable for this kind of read, and must be read at 32-bits wide.

### PIO_INS32()

Purpose

  Performs a low-level “control read” transaction. Other functions in this API result in control read, control write, bulk read, and/or bulk write transactions. The lowest-level functions (GenericVendorRead, GenericVendorWrite, AWU_GenericBulkIn, and AWU_GenericBulkOut) exist to bypass the API's logic and algorithms, generating those transactions directly as your application directs.

Signature
  PIO_INS32(cardNum, offset, dataCt) -> (status (WinError), data)
  function PIO_INS32(iBoard: TBoardIndex; Offset: TUInt32; DataCt: TUInt32; pData: TPUInt32): TWinErrCode;
Arguments
  iBoard
    The index of the device to control; generally either biAuto or a specific device's Board Index.
  Request
    The USB request number associated with the desired transaction. Note that the request type will be "vendor read".
  Value
    The Value word in the USB setup data packet.
  Index
    The Index word in the USB setup data packet.
  pDataSize
    A pointer to the size, in bytes, of the buffer pointed to by pData. Upon exit, this value will be changed to the size, in bytes, of the data read from the device.
  pData
    A pointer to the first of an array of bytes. USB data packet(s) will be read into the array. If DataSize is zero, then pData can be “null”.
Returns
  Windows standard “Win32” error codes. ERROR_SUCCESS (0) means “Success”.

## IRQ Handling Functions

### PIO_PollForIRQ()

Purpose

  Performs a low-level “control read” transaction. Other functions in this API result in control read, control write, bulk read, and/or bulk write transactions. The lowest-level functions (GenericVendorRead, GenericVendorWrite, AWU_GenericBulkIn, and AWU_GenericBulkOut) exist to bypass the API's logic and algorithms, generating those transactions directly as your application directs.

Signature
  PIO_PollForIRQ( iBoard, irq=IRQIndex.Only ) -> (status (WinError))
  function PIO_PollForIRQ(iBoard: TBoardIndex; IRQIndex: TIRQIndex = iiOnly): TWinErrCode;
Arguments
  iBoard
    The index of the device to control; generally either biAuto or a specific device's Board Index.
  Request
    The USB request number associated with the desired transaction. Note that the request type will be "vendor read".
  Value
    The Value word in the USB setup data packet.
  Index
    The Index word in the USB setup data packet.
  pDataSize
    A pointer to the size, in bytes, of the buffer pointed to by pData. Upon exit, this value will be changed to the size, in bytes, of the data read from the device.
  pData
    A pointer to the first of an array of bytes. USB data packet(s) will be read into the array. If DataSize is zero, then pData can be “null”.
Returns
  Windows standard “Win32” error codes. ERROR_SUCCESS (0) means “Success”.

### PIO_WaitForIRQ()

Purpose

  Performs a low-level “control read” transaction. Other functions in this API result in control read, control write, bulk read, and/or bulk write transactions. The lowest-level functions (GenericVendorRead, GenericVendorWrite, AWU_GenericBulkIn, and AWU_GenericBulkOut) exist to bypass the API's logic and algorithms, generating those transactions directly as your application directs.

Signature
  PIO_WaitForIRQ( iBoard, irq=IRQIndex.Only ) -> (status (WinError))
  function PIO_WaitForIRQ(iBoard: TBoardIndex; IRQIndex: TIRQIndex = iiOnly): TWinErrCode;
Arguments
  iBoard
    The index of the device to control; generally either biAuto or a specific device's Board Index.
  Request
    The USB request number associated with the desired transaction. Note that the request type will be "vendor read".
  Value
    The Value word in the USB setup data packet.
  Index
    The Index word in the USB setup data packet.
  pDataSize
    A pointer to the size, in bytes, of the buffer pointed to by pData. Upon exit, this value will be changed to the size, in bytes, of the data read from the device.
  pData
    A pointer to the first of an array of bytes. USB data packet(s) will be read into the array. If DataSize is zero, then pData can be “null”.
Returns
  Windows standard “Win32” error codes. ERROR_SUCCESS (0) means “Success”.

### PIO_AbortIRQWait()

Purpose

  Performs a low-level “control read” transaction. Other functions in this API result in control read, control write, bulk read, and/or bulk write transactions. The lowest-level functions (GenericVendorRead, GenericVendorWrite, AWU_GenericBulkIn, and AWU_GenericBulkOut) exist to bypass the API's logic and algorithms, generating those transactions directly as your application directs.

Signature
  function PIO_AbortIRQWait(iBoard: TBoardIndex; IRQIndex: TIRQIndex = iiOnly): TWinErrCode;
Arguments
  iBoard
    The index of the device to control; generally either biAuto or a specific device's Board Index.
  Request
    The USB request number associated with the desired transaction. Note that the request type will be "vendor read".
  Value
    The Value word in the USB setup data packet.
  Index
    The Index word in the USB setup data packet.
  pDataSize
    A pointer to the size, in bytes, of the buffer pointed to by pData. Upon exit, this value will be changed to the size, in bytes, of the data read from the device.
  pData
    A pointer to the first of an array of bytes. USB data packet(s) will be read into the array. If DataSize is zero, then pData can be “null”.
Returns
  Windows standard “Win32” error codes. ERROR_SUCCESS (0) means “Success”.