Sample Program Listing

/****************************************************************************

    FILE        : GxAoExampleC.cpp

 

    PURPOSE     : WIN32/Linux sample program for GX1642/GX1648/GX1649/

                  GX1649-1 boards using the GXAO driver.

 

    CREATED     : Aug. 2002

 

    COPYRIGHT   : Copyright (c) Marvin Test Solutions, Inc.

 

    COMMENTS    :

 

    To compile the example:

 

    1. Microsoft VC++

        Load GxAoExampleC.dsp, .vcproj or .mak, depends on

        the VC++ version from the Project\File/Open... menu

        Select Project/Rebuild all from the menu

 

    2. Borland C++ Builder

        Load GxAoExampleC.bpr from the Project/Open

            Project... menu

        Select Project/Build all from the menu

 

    3. Linux (GCC for CPP and Make must be available)

        make -fGxAoExampleC.mk [CFG=Release[64] | Debug[64]] [rebuild |

                clean]

 

****************************************************************************/

#ifndef __GNUC__

#include "windows.h"

#endif

#include "GxAo.h"

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

#include <ctype.h>

#include <math.h>

#ifdef __GNUC__

#include <unistd.h>

// under Linux sleep is in second and is called sleep (not Sleep)

#define Sleep(x)    sleep(x/1000)

#endif

 

#if defined(__BORLANDC__)

#pragma hdrstop

#include <condefs.h>

USELIB("GxAoBC.lib");

USERC("GxAoExampleC.rc");

#endif

 

//***************************************************************************

//        DisplayMsg

//***************************************************************************

void DisplayMsg(PCSTR lpszMsg)

{

#ifndef __GNUC__

    MessageBeep(0);

    MessageBox(0, lpszMsg, "GxAo example program", MB_OK);

#else

    printf("\r\nGxAo example program: %s\r\n", lpszMsg);

#endif

    return;

}

 

//***************************************************************************

//        __strupr

//***************************************************************************

char * __strupr(char * sz)

{

    int i;

 

    for (i=0; sz[i]; i++)

        sz[i] = toupper(sz[i]);

    return sz;

}

 

//***************************************************************************

//        DisplayUsage

//***************************************************************************

void DisplayUsage(void)

{

    DisplayMsg(

        "\r\nThis example shows how to use the GX1642/GX1648/GX1649"

        "/GX1649-1/GX1632:\r\n\r\n"

 

        "Usage:\r\n"

        "GxAoExampleC <slot|address> <operation> <group> <channel|range>"

        " <voltage|frequency> <test mode>"

 

        "\r\n\r\nWhere : \r\n"

        "<slot> - Under Windows: PCI/PXI slot number as shown by the PXI"

        " explorer\r\n"

        "<address> - Under Linux: Bus/device as displayed with lspci"

        " utility\r\n"

 

        "<operation> - one of the following:\r\n"

        "\tSCV=Set channel voltage\r\n"

        "\tGCV=Get channel value\r\n"

        "\tSVR=Set group voltage range\r\n"

        "\tGVR=Get group voltage range\r\n"

        "\tSUM=Print board summary\r\n"

        "\tARB=Output group arbitrary waveform (GX1649-1/1632e)\r\n"

        "\tSTREAM=Stream waveforms (GX1649-1/1632e)\r\n"

        "\tSPEEDTEST=Test domain running at fixed interval (GX1632e)\r\n"

        "<group> - group number 0 to 3\r\n"

        "<channel|range> - depends on the operation:\r\n"

        "\tchannel number :\t0-15 for SCV/GCV/STREAM operations\r\n"

        "\trange number :\t0-3 for SVR/GVR operations\r\n"

        "<voltage|frequency> - depends of the operation:\r\n"

        "\tvoltage: \t-5 to 5 for SCV operation\r\n"

        "\t\t-25 to 25 for GX1632e\r\n"

        "\tfrequency: Allows setting rate to test maximum\r\n"

        "\tbandwidth acheivable\r\n"

        "<test mode> - one of the following:\r\n"

        "\tPOLL=Check streaming buffer by polling the status\r\n"

        "\tregister (GX1649-1 only)\r\n"

        "\tINTR=Streaming buffer generates interrupt if half-empty \r\n"

        "\t(GX1649-1) or generates interrupt when the FIFO can handle\r\n"

        "\tmore data (GX1632e)\r\n"

 

        "\r\nThe example should be run from  the Windows command"

        " prompt/Linux terminal.\r\n"

        "\tExamples:\r\n"

        "\t./GxAoExampleC 7 SCV 0 1 2.5\r\n\t\t(group 0 chan 1, 2.5v)\r\n"

        "\t./GxAoExampleC 0x60c SCV 0 1 2.5\r\n\t\t (under Linux, "

            "bus 6 device 12)\r\n"

        "\t./GxAoExampleC 0x60c ARB 0 1 100000\r\n\t\t "

            "(ARB group A channel 1 "

            "sample rate 100K)\r\n"

        "\t./GxAoExampleC 0x60c STREAM 0 1 100000 INTR\r\n\t   "

            "(stream group A channel 1 sample rate 100K using interrupt)\r\n"

        "\t./GxAoExampleC 0x60c STREAM 0 1 100000 POLL\r\n\t   "

            "(stream group A channel 1 sample rate 100K using polling)\r\n"

        "\t./GxAoExampleC 6,7,8 SPEEDTEST 10 6\r\n\t   "

            "(output sinewave on cards at slots 6-8 for 10 seconds at\r\n\t"

            100MHz/2^(6+1)\r\n"

        "\r\n"

        );

    exit(1);

}

 

//***************************************************************************

//        CheckStatus

//***************************************************************************

void CheckStatus(SHORT nStatus)

{

    CHAR    sz[128];

 

    if (!nStatus) return;

    GxAoGetErrorString(nStatus, sz, sizeof sz, &nStatus);

    DisplayMsg(sz);

    DisplayMsg("Aborting the program...");

    exit(nStatus);

}

 

//***************************************************************************

//        Global variables

//***************************************************************************

#define PI 3.14159265

#define POINTS_PER_WAVEFORM     100

#define BUCKETS     2 // pow (2, GXAO_1632_BUCKET_COUNT_2)

 

// global array for streaming/arb modes

DOUBLE    g_adWaveformData[4][GXAO_1632_BUCKET_SAMPLE_COUNT*4];

WORD      g_awWaveformData[4][GXAO_1632_BUCKET_SAMPLE_COUNT*4];

INT       g_iFifoWritten=0; // Counts time FIFO written to

BOOL      g_bNoStreaming; // Set to TRUE to prevent writing while streaming

 

//***************************************************************************

//        InterruptCallback1649 - for streaming 1649-1

//***************************************************************************

LONG WINAPI InterruptCallback1649(SHORT nHandle, SHORT enEventType, PVOID pvUserData)

{

    short       nStatus;

    WORD        wStatus, wCount;

    INT         iGroup;

    BOOL        bEnable;

 

    // search all group for source of interrupt

    for (iGroup=GXAO_GROUPA ; iGroup<=GXAO_GROUPD ; iGroup++)

    {    // ignore group if streaming is not enabled

        GxAoArbIsGroupStreaming(nHandle, iGroup, &bEnable, &nStatus);

        CheckStatus(nStatus);

        if (!bEnable) continue;

        // retrieve streaming FIFO status

        GxAoArbGetGroupStreamingStatus(nHandle, iGroup, &wStatus, &wCount,

            &nStatus);

        CheckStatus(nStatus);

        // if FIFO is at least half empty

        if ((wStatus & GXAO_1649_ARB_STREAMING_STATUS_FULL)==0)

        {    GxAoArbWriteStreaming(nHandle, iGroup, &g_adWaveformData[0],

                POINTS_PER_WAVEFORM, GXAO_1649_WAVEFORM_TYPE_DOUBLE,

                &nStatus);

            CheckStatus(nStatus);

            g_iFifoWritten++;

        }

    }

 

    // resume streaming interrupt

    GxAoArbResumeStreamingInterrupt(nHandle, &nStatus);

 

    return 0;

}

 

//***************************************************************************

//        InterruptCallback1632 - for streaming 1632e

//***************************************************************************

LONG WINAPI InterruptCallback1632(SHORT nHandle, SHORT enEventType, PVOID pvUserData)

{

    SHORT       nGroup, nStatus;

 

    if (enEventType==0x1005)

    {   g_bNoStreaming=TRUE;

        printf("Error encountered.  Halting stream.\n");

        // Stop streaming and disable interrupt engine

        GxAoArbEnableGroupStreaming(nHandle, 0, FALSE, &nStatus);

        CheckStatus(nStatus);

    }

 

    if (g_bNoStreaming==FALSE)

    {   // MSI0-MSI3 has event ids of 0x1000 to 0x1003 and correspond to

        // Group A(0) to D(3)

        nGroup=enEventType-0x1000;

        // Send fresh data

        //GxAoArbWriteStreaming(nHandle, nGroup, g_adWaveformData[nGroup],

        //   GXAO_1632_BUCKET_SAMPLE_COUNT*BUCKETS,GXAO_WAVEFORM_TYPE_DOUBLE,

        //   &nStatus);

        GxAoArbWriteStreaming(nHandle, nGroup, g_awWaveformData[nGroup],

            GXAO_1632_BUCKET_SAMPLE_COUNT*BUCKETS, GXAO_WAVEFORM_TYPE_WORD,

            &nStatus);

        CheckStatus(nStatus);

        g_iFifoWritten++;

    }

    return 0;

}

 

//***************************************************************************

//        MAIN

//***************************************************************************

int main(int argc, char **argv)

{

    short    nSlotNum;       // board slot number

    char *   sOperation;     // board operation

    char *   sMode;          // test mode: 0=polling, 1=interrupt

    char *   sSlotNumbers;   // Holds the slot numbers argument

                             // before parsing

    short    nGroup=0;       // group number

    short    nChannel_Range; // channel or voltage Range

    short    nHandle;        // board handle

    short   nHandleTemp;    // temporary board handle

    short    nStatus;        // returned status

    long     lSampleRate;    // sample rate

    double   dVoltage;       // channel's voltage

    char     sz[512];        // board summary

    int      i;              // loop counter

    char *  sNextSlot;      // next slot #

    long     lSamples;       // # of samples

    DWORD    dwData;         // data     

    unsigned short wCount;   // counter

    unsigned short wStatus;   // status

    DOUBLE   adSineWave[2048]; // array to hold Sine wave

    WORD     awSineWave[2048]; // array to hold Sine wave

 

    // Check number of arguments recived

    if (argc<=2) DisplayUsage();

 

    // Parse command line parameters

    sSlotNumbers=*(++argv);

    nSlotNum=(SHORT)strtol(sSlotNumbers, &sNextSlot, 0);

    sOperation = __strupr(*(++argv));

    if (strcmp(sOperation, "SUM"))

    {   if (argc<=4) DisplayUsage();

        nGroup=(SHORT)strtol(*(++argv), NULL, 0);

        nChannel_Range =(SHORT)strtol(*(++argv), NULL, 0);

    }

    if (!strcmp(sOperation, "STREAM") || !strcmp(sOperation, "ARB"))

    {   if (argc<=5) DisplayUsage();

        lSampleRate=(LONG)strtol(*(++argv), NULL, 0);

        if (!strcmp(sOperation, "STREAM"))

        {   if (argc<=6) DisplayUsage();

            sMode=__strupr(*(++argv));

        }

    }

    if (nGroup<0 || nGroup>3)

        DisplayUsage();

 

    GxAoInitialize(nSlotNum, &nHandle, &nStatus);

    CheckStatus(nStatus);

 

    if (!strcmp(sOperation, "SCV"))

    {    // set channel voltage

        if (argc<=5) DisplayUsage();

        dVoltage=strtod(*(++argv), NULL);

        GxAoSetChannelVoltage(nHandle, nGroup, nChannel_Range, dVoltage,

            &nStatus);

        CheckStatus(nStatus);

        printf("Set Group %i Channel %i voltage to %f.\n", nGroup,

            nChannel_Range, dVoltage);

    }

    else if (!strcmp(sOperation, "GCV"))

    {    // get channel voltage

        GxAoGetChannelVoltage(nHandle, nGroup, nChannel_Range, &dVoltage,

            &nStatus);

        CheckStatus(nStatus);

        printf("Group %i Channel %i voltage is %f.\n", nGroup,

            nChannel_Range, dVoltage);

    }

    else if (!strcmp(sOperation, "SVR"))

    {    // set group voltage range

        GxAoSetGroupVoltageRange(nHandle, nGroup, nChannel_Range,

            &nStatus);

        CheckStatus(nStatus);

        printf("Group %i voltage range to %i.\n", nGroup,

            nChannel_Range);

    }

    else if (!strcmp(sOperation, "GVR"))

    {    // set group voltage range

        GxAoGetGroupVoltageRange(nHandle, nGroup, &nChannel_Range,

            &nStatus);

        CheckStatus(nStatus);

        printf("Group %i voltage range is %i.\n", nGroup,

            nChannel_Range);

    }

    else if (!strcmp(sOperation, "SUM"))

    {   // print board summary

        GxAoGetBoardSummary(nHandle, sz, sizeof sz, &nStatus);

        CheckStatus(nStatus);

        printf("Board Summary: %s.\n", sz);

    }

    else if (!strcmp(sOperation, "ARB"))

    {   GxAoGetBoardSummary(nHandle, sz, sizeof sz, &nStatus);

        CheckStatus(nStatus);

        if (strstr(sz, "GX1632e"))

        {

            // This is a non-streaming mode

            g_bNoStreaming=TRUE;

 

            // Set target group to use 100MHz/(2^11) as DAC clock,

            // and use 1 bucket each

            for (int iGroup=0; iGroup<4; iGroup++)

            {

                GxAoArbSetGroupClockEx(nHandle, iGroup,

                    GXAO_CLOCKSOURCE_DIVIDER, 11, &nStatus);

                CheckStatus(nStatus);

                GxAoArbSetGroupChannels(nHandle, iGroup, 0xFF,

                    GXAO_1632_BUCKET_COUNT_2, &nStatus);

                CheckStatus(nStatus);

            }

 

            // Enable interrupt, allocates data buckets based on previous

            // bucket size settings

            dwData=42;

            GxAoArbSetupStreamingInterrupt(nHandle, 0xF,

                InterruptCallback1632, &dwData, &nStatus);

            CheckStatus(nStatus);

 

            // Create sine wave in local memory (datatype DOUBLE)

            lSamples=GXAO_1632_BUCKET_SAMPLE_COUNT/8;

            for (int iSampleIndex=0; iSampleIndex<lSamples; iSampleIndex++)

            {   adSineWave[iSampleIndex]=5*sin(2*PI*((DOUBLE)iSampleIndex/

                    lSamples));

                if (adSineWave[iSampleIndex]<0)

                   awSineWave[iSampleIndex]=(WORD)((adSineWave[iSampleIndex]/

                        25.0)*32768);

                else

                    awSineWave[iSampleIndex]=(WORD)((

                        adSineWave[iSampleIndex]/25.0)*32767);

            }

            for (int iGroup=0; iGroup<4; iGroup++)

            {   for (int i=0; i<GXAO_1632_BUCKET_SAMPLE_COUNT*BUCKETS; i++)

                {   g_adWaveformData[iGroup][i]=adSineWave[((i/8)+

                         ((lSamples/16)*(i%8)))%lSamples];

                      g_awWaveformData[iGroup][i]=awSineWave[((i/8)+

                        ((lSamples/16)*(i%8)))%lSamples];

                }

            }

            for (int iGroup=0; iGroup<4; iGroup++)

            {   //GxAoArbWriteWaveform(nHandle, iGroup, 0xFF,

                //    g_adWaveformData[iGroup],

                //    BUCKETS*GXAO_BUCKET_SAMPLE_COUNT-50,

                //    GXAO_WAVEFORM_TYPE_DOUBLE, &nStatus);

                GxAoArbWriteWaveform(nHandle, iGroup, 0xFF,

                    g_awWaveformData[iGroup],

                    BUCKETS*GXAO_BUCKET_SAMPLE_COUNT-50,

                    GXAO_WAVEFORM_TYPE_WORD, &nStatus);

                CheckStatus(nStatus);

            }

 

            // Initiates streaming

            GxAoArbEnableGroupStreaming(nHandle, nGroup, TRUE, &nStatus);

            CheckStatus(nStatus);

 

            Sleep(10000);

 

            // Stop streaming and disable interrupt engine

            GxAoArbEnableGroupStreaming(nHandle, nGroup, FALSE, &nStatus);

            CheckStatus(nStatus);

            GxAoArbDisableStreamingInterrupt(nHandle, &nStatus);

            CheckStatus(nStatus);

        }

        else

        {

            // arb function

            // generate sine and square waves

            for (i=0 ; i<POINTS_PER_WAVEFORM ; i++)

                g_adWaveformData[0][i]=5.0*sin(2.0*PI*

                    (i/DOUBLE(POINTS_PER_WAVEFORM)));

            for (i=0 ; i<POINTS_PER_WAVEFORM ; i++)

                g_adWaveformData[0][i+POINTS_PER_WAVEFORM]=

                    i<(POINTS_PER_WAVEFORM/2) ? 5.0 : -5.0;

            // reset

            GxAoReset(nHandle, &nStatus);

            CheckStatus(nStatus);

            // disable streaming

            GxAoArbEnableGroupStreaming(nHandle, nGroup, FALSE, &nStatus);

            CheckStatus(nStatus);

            // set sample rate

            GxAoArbSetGroupClock(nHandle, nGroup,

                GXAO_1649_CLOCKSOURCE_INTERNAL, lSampleRate, &nStatus);

            CheckStatus(nStatus);

            // set channel

            GxAoArbSetGroupChannels(nHandle, nGroup, 1<<nChannel_Range,

                POINTS_PER_WAVEFORM, &nStatus);

            CheckStatus(nStatus);

            // write first waveform to buffer

            GxAoArbWriteWaveform(nHandle, nGroup, nChannel_Range,

                g_adWaveformData[0], POINTS_PER_WAVEFORM,

                GXAO_1649_WAVEFORM_TYPE_DOUBLE, &nStatus);

            CheckStatus(nStatus);

            // start streaming

            GxAoArbArmGroup(nHandle, nGroup, TRUE, TRUE, &nStatus);

            CheckStatus(nStatus);

            GxAoArbTrigGroup(nHandle, nGroup, &nStatus);

            CheckStatus(nStatus);

            // wait 10s

            Sleep(10000);

        }

    }

    else if (!strcmp(sOperation, "STREAM"))

    {   GxAoGetBoardSummary(nHandle, sz, sizeof sz, &nStatus);

        CheckStatus(nStatus);

        if (strstr(sz, "GX1632e"))

        {   // Set target group to use 100MHz/(2^11) as DAC clock,

            GxAoReset(nHandle, &nStatus);

            CheckStatus(nStatus);

            // Set target group to use 100MHz/(2^11) as DAC clock,

            // and use 1 bucket each

            for (int iGroup=0; iGroup<4; iGroup++)

            {

                GxAoArbSetGroupClockEx(nHandle, iGroup,

                    GXAO_CLOCKSOURCE_DIVIDER, 11, &nStatus);

                CheckStatus(nStatus);

                GxAoArbSetGroupChannels(nHandle, iGroup, 0xFF,

                    GXAO_1632_BUCKET_COUNT_2, &nStatus);

                CheckStatus(nStatus);

            }

 

            // Enable interrupt, allocates data buckets based on previous

            // bucket size settings

            dwData=42;

            GxAoArbSetupStreamingInterrupt(nHandle, 0xF,

                  InterruptCallback1632, &dwData, &nStatus);

            CheckStatus(nStatus);

 

            // Create sine wave in local memory (datatype DOUBLE)

            lSamples=GXAO_1632_BUCKET_SAMPLE_COUNT/8;

            for (int iSampleIndex=0; iSampleIndex<lSamples; iSampleIndex++)

            {   adSineWave[iSampleIndex]=5*sin(2*PI*((DOUBLE)iSampleIndex/

                    lSamples));

                if (adSineWave[iSampleIndex]<0)

                    awSineWave[iSampleIndex]=(WORD)((

                        adSineWave[iSampleIndex]/25.0)*32768);

                else

                    awSineWave[iSampleIndex]=(WORD)((

                        adSineWave[iSampleIndex]/ 25.0)*32767);

            }

            for (int iGroup=0; iGroup<4; iGroup++)

            {   for (int i=0; i<GXAO_1632_BUCKET_SAMPLE_COUNT*BUCKETS; i++)

                {   g_adWaveformData[iGroup][i]=adSineWave[((i/8)+

                         ((lSamples/16)*(i%8)))%lSamples];

                    g_awWaveformData[iGroup][i]=awSineWave[((i/8)+

                        ((lSamples/16)*(i%8)))%lSamples];

                }

            }

            for (int iGroup=0; iGroup<4; iGroup++)

            {    //GxAoArbWriteStreaming(nHandle, iGroup,

                //    g_adWaveformData[iGroup],

                //    GXAO_1632_BUCKET_SAMPLE_COUNT*BUCKETS,

                //    GXAO_WAVEFORM_TYPE_DOUBLE,

                //    &nStatus);

                GxAoArbWriteStreaming(nHandle, iGroup,

                    g_awWaveformData[iGroup],

                    GXAO_1632_BUCKET_SAMPLE_COUNT*BUCKETS,

                    GXAO_WAVEFORM_TYPE_WORD,

                    &nStatus);

                CheckStatus(nStatus);

            }

 

            // Initiates streaming

            GxAoArbEnableGroupStreaming(nHandle, nGroup, TRUE, &nStatus);

            CheckStatus(nStatus);

 

            Sleep(7500);

            g_bNoStreaming=TRUE;

            Sleep(2500);

 

            // Stop streaming and disable interrupt engine

            GxAoArbEnableGroupStreaming(nHandle, nGroup, FALSE, &nStatus);

            CheckStatus(nStatus);

            GxAoArbDisableStreamingInterrupt(nHandle, &nStatus);

            CheckStatus(nStatus);

 

            printf("GxAoArbWriteStreaming wrote to the FIFO %i times.\n",

                g_iFifoWritten);

            printf("A total of %i samples were written.",

                g_iFifoWritten*GXAO_1632_BUCKET_SAMPLE_COUNT);

        }

        else // GX1649-1

        {

            // streaming waveforms/ GX1649-1 only

            // generate sine and square waves

            for (i=0 ; i<POINTS_PER_WAVEFORM ; i++)

                g_adWaveformData[0][i]=5.0*sin(2.0*PI*

                    (i/DOUBLE(POINTS_PER_WAVEFORM)));

            for (i=0 ; i<POINTS_PER_WAVEFORM ; i++)

                g_adWaveformData[0][i+POINTS_PER_WAVEFORM]=

                    i<(POINTS_PER_WAVEFORM/2) ? 5.0 : -5.0;

            // reset

            GxAoReset(nHandle, &nStatus);

            CheckStatus(nStatus);

            // enable streaming

            GxAoArbEnableGroupStreaming(nHandle, nGroup, TRUE, &nStatus);

            CheckStatus(nStatus);

            // set streaming sample rate

            GxAoArbSetGroupClock(nHandle, nGroup, GXAO_CLOCKSOURCE_INTERNAL,

                lSampleRate, &nStatus);

            CheckStatus(nStatus);

            // set streaming channel

            GxAoArbSetGroupChannels(nHandle, nGroup, 1<<nChannel_Range, 500,

                &nStatus);

            CheckStatus(nStatus);

            // write first waveform to FIFO

            GxAoArbWriteStreaming(nHandle, nGroup, g_adWaveformData[0],

                POINTS_PER_WAVEFORM, GXAO_WAVEFORM_TYPE_DOUBLE, &nStatus);

            CheckStatus(nStatus);

            // start streaming

            GxAoArbArmGroup(nHandle, nGroup, TRUE, TRUE, &nStatus);

            CheckStatus(nStatus);

            GxAoArbTrigGroup(nHandle, nGroup, &nStatus);

            CheckStatus(nStatus);

            g_iFifoWritten=0;

            if (!strcmp(sMode, "INTR"))

            {

                // enable interrupt

                GxAoArbSetupStreamingInterrupt(nHandle, 0xFF,

                    InterruptCallback1649, NULL, &nStatus);

                CheckStatus(nStatus);

                GxAoArbResumeStreamingInterrupt(nHandle, &nStatus);

                CheckStatus(nStatus);

                // wait 10s

                Sleep(10000);

                // disable interrupt

                GxAoArbDisableStreamingInterrupt(nHandle, &nStatus);

            }

            else        //  !strcmp(sMode, "POLL")

            {   // begin polling

                // run for 1/15 sample rate times 1/2 FIFO size

                // i.e. 90K it will run 15K times 1/2 FIFO Size

                // (1024/2 samples) = 15Kx512= 7.68M samples

                while (g_iFifoWritten<(lSampleRate/15)) 

                {

                    // retrieve streaming FIFO status

                    GxAoArbGetGroupStreamingStatus(nHandle, nGroup,

                        &wStatus, &wCount, &nStatus);

                    CheckStatus(nStatus);

                    // if FIFO is at least half empty

                    if ((wStatus & GXAO_1649_ARB_STREAMING_STATUS_HALF_EMPTY)

                        ==1)

                    {

                        GxAoArbWriteStreaming(nHandle, nGroup,

                            &g_adWaveformData[0], POINTS_PER_WAVEFORM,

                            GXAO_1649_WAVEFORM_TYPE_DOUBLE, &nStatus);

                        g_iFifoWritten++;

                    }

                }

            }

            printf("GxAoArbWriteStreaming wrote to the FIFO %i times.\n",

                g_iFifoWritten);

            printf("A total of %i samples were written.\n",

                g_iFifoWritten*POINTS_PER_WAVEFORM);

        }

 

        // wait 2 seconds for any interrupt callback to finish

        Sleep(2000);

    }

    else if (!strcmp(sOperation, "SPEEDTEST"))

    {

        do {

            printf("Slot number 0x%x is preparing to stream.\n", nSlotNum);

            // Set target group to use 100MHz/(2^11) as DAC clock,

            // and use 1 bucket each

            for (int iGroup=0; iGroup<4; iGroup++)

            {

                GxAoArbSetGroupClockEx(nHandle, iGroup,

                    GXAO_CLOCKSOURCE_DIVIDER, nChannel_Range, &nStatus);

                CheckStatus(nStatus);

                GxAoArbSetGroupChannels(nHandle, iGroup, 0xFF,

                    GXAO_1632_BUCKET_COUNT_4, &nStatus);

                CheckStatus(nStatus);

            }

 

            // Enable interrupt, allocates data buckets based on previous

            //    bucket size settings

            dwData=42;

            GxAoArbSetupStreamingInterrupt(nHandle, 0xF,

                InterruptCallback1632, &dwData, &nStatus);

            CheckStatus(nStatus);

 

            // Create sine wave in local memory (datatype DOUBLE)

            lSamples=GXAO_1632_BUCKET_SAMPLE_COUNT/8;

            for (int iSampleIndex=0; iSampleIndex<lSamples; iSampleIndex++)

            {   adSineWave[iSampleIndex]=5*sin(2*PI*((DOUBLE)iSampleIndex

                    /lSamples));

                if (adSineWave[iSampleIndex]<0)

                    awSineWave[iSampleIndex]=(WORD)((adSineWave[iSampleIndex]

                        /25.0)*32768);

                else

                    awSineWave[iSampleIndex]=(WORD)((adSineWave[iSampleIndex]

                        /25.0)*32767);

            }

                        for (int iGroup=0; iGroup<4; iGroup++)

            {   for (int i=0; i<GXAO_1632_BUCKET_SAMPLE_COUNT; i++)

                {   g_adWaveformData[iGroup][i]=adSineWave[((i/8)+

                        ((lSamples/16)*(i%8)))%lSamples];

                    g_awWaveformData[iGroup][i]=awSineWave[((i/8)+

                        ((lSamples/16)*(i%8)))%lSamples];

                }

            }

 

            for (int iGroup=0; iGroup<4; iGroup++)

            {   //GxAoArbWriteStreaming(nHandle, iGroup,

                //    g_adWaveformData[iGroup],

                //    GXAO_1632_BUCKET_SAMPLE_COUNT*4,

                //    GXAO_WAVEFORM_TYPE_DOUBLE, &nStatus);

                GxAoArbWriteStreaming(nHandle, iGroup,

                    g_awWaveformData[iGroup],

                    GXAO_1632_BUCKET_SAMPLE_COUNT*4,

                    GXAO_WAVEFORM_TYPE_WORD, &nStatus);

                CheckStatus(nStatus);

            }

 

            // Initiates streaming

            GxAoArbEnableGroupStreaming(nHandle, 0, TRUE, &nStatus);

            CheckStatus(nStatus);

 

            // Check for additional slots

            sSlotNumbers=sNextSlot+1;

            nSlotNum=(SHORT)strtol(sSlotNumbers, &sNextSlot, 0);

            GxAoInitialize(nSlotNum, &nHandleTemp, &nStatus);

            if (nHandleTemp!=0)

                nHandle=nHandleTemp;

        } while (nStatus==0);

 

        // nGroup argument holds the time in seconds for SPEEDTEST

        printf("All cards are streaming for %d seconds.\n", nGroup);

        Sleep(nGroup*1000);

 

        g_bOneTime=TRUE;

        Sleep(2500);

 

        // Stop streaming and disable interrupt engine

        while (nHandle>=0x100) {   

            GxAoArbEnableGroupStreaming(nHandle, 0, FALSE, &nStatus);

            CheckStatus(nStatus);

            GxAoArbDisableStreamingInterrupt(nHandle, &nStatus);

            CheckStatus(nStatus);

            GxAoReset(nHandle, &nStatus);

            CheckStatus(nStatus);

            nHandle--;

        }

    }

    return 0;

}

 

//***************************************************************************

//        End Of File

//***************************************************************************