Example AWGUpload#

  1// Copyright [2016] Zurich Instruments AG
  2//
  3// LabOne C API Example
  4//
  5// This Example demonstrates how to compile an AWG sequencer program and upload
  6// it to an instrument using the LabOne API's AWG Module.
  7//
  8// Prerequisites:
  9//
 10// The AWG source file specified by the awgSourceFile variable should be a .seqc
 11// file and located in the awg/src sub-folder of your Zurich Instruments user
 12// folder. The awg/src folder is located on Windows at:
 13//   C:\Users\danielw\Documents\Zurich Instruments\LabOne\WebServer\awg\src
 14// and on Linux at:
 15//   ~/Zurich\ Instruments/LabOne/WebServer/awg/src/
 16//
 17// If no AWG source files are available at this location, please start the
 18// LabOne User Interface, open the AWG Tab and open and save one of the example
 19// files. It will then be saved to the awg/src directory.
 20#include <stdlib.h>
 21
 22#include "ziAPI.h"
 23#include "ziUtils.hpp"
 24
 25
 26int main()
 27{
 28  // Define the device address of the device to run the example on.
 29  const char* deviceAddress = ziUtilsGetEnv("LABONE_DEVICE", "dev2123");
 30  printf("ENV LABONE_DEVICE=%s\n", deviceAddress);
 31
 32  // Address of the data server.
 33  const char* dataServer = ziUtilsGetEnv("LABONE_SERVER", "localhost");
 34
 35  // Port of the data server.
 36  const uint16_t port = 8004;
 37
 38  // Over which interface the connection to the
 39  // device should be established. Can be either
 40  // - 1: "1GbE" - Ethernet
 41  // - 2: "USB" - USB
 42  // - 3: "PCIe" - PCIe
 43  const char* deviceInterface = "1GbE";
 44
 45  // The filename of the AWG sequencer program to compile and load, see the
 46  // comments at the top of this file to see where this file is located.
 47  const char* awgSourceFile = "ziAWG_functional_for.seqc";
 48
 49  ZIConnection conn = nullptr;
 50
 51  if (isError(ziAPIInit(&conn)))
 52  {
 53    return 1;
 54  }
 55
 56  ziAPISetDebugLevel(0);
 57  ziAPIWriteDebugLog(0, "Logging enabled.");
 58
 59  try
 60  {
 61    checkError(
 62        ziAPIConnectEx(conn, dataServer, port, ZI_API_VERSION_6, nullptr));
 63    checkError(
 64        ziAPIConnectDevice(conn, deviceAddress, deviceInterface, nullptr));
 65    ziApiServerVersionCheck(conn);
 66    int awgIndex = 0;
 67
 68    // Disable the AWG.
 69    char path[1024];
 70    ziAPIWriteDebugLog(0, "Disabling AWG.");
 71    snprintf(path, sizeof(path), "/%s/awgs/%d/enable", deviceAddress, awgIndex);
 72    checkError(ziAPISetValueI(conn, path, 0));
 73    ziAPISync(conn);
 74
 75    char message[1024];
 76    ZIModuleHandle awgModule;
 77    checkError(ziAPIModCreate(conn, &awgModule, "awgModule"));
 78    snprintf(
 79        message,
 80        sizeof(message),
 81        "Module created, handle: %" PRIu64 ".",
 82        awgModule);
 83    ziAPIWriteDebugLog(0, message);
 84    checkError(ziAPIModSetString(conn, awgModule, "device", deviceAddress));
 85
 86    /* Start the module thread. */
 87    checkError(ziAPIModExecute(conn, awgModule));
 88    ziAPIWriteDebugLog(0, "Executing the module.");
 89    checkError(ziAPIModSetString(
 90        conn, awgModule, "compiler/sourcefile", awgSourceFile));
 91
 92    // Note: When transferring the AWG sequence program as a 'sourcestring'
 93    // compilation starts automatically. When specifying the AWG from a source
 94    // file the compiler needs to be started explicitly.
 95    checkError(ziAPIModSetIntegerData(conn, awgModule, "compiler/start", 1));
 96
 97    ZIIntegerData compilerStatus = -1;
 98    while (compilerStatus == -1)
 99    {
100      sleep(500);  // [ms]
101      checkError(ziAPIModGetInteger(
102          conn, awgModule, "compiler/status", &compilerStatus));
103    }
104    unsigned int compilerStatusstringLength = 0;
105    char compilerStatusstring[1024] = "";
106    checkError(ziAPIModGetString(
107        conn,
108        awgModule,
109        "compiler/statusstring",
110        compilerStatusstring,
111        &compilerStatusstringLength,
112        (unsigned int)1024));
113    if (compilerStatusstringLength == 0)
114    {
115      ziAPIWriteDebugLog(
116          3,
117          "ziAPIModGetString returned string length 0 whilst getting "
118          "compiler/statusstring: "
119          "Either an error occurred or the provided buffer was not large "
120          "enough.");
121    }
122    else if (compilerStatus == 1)
123    {
124      snprintf(
125          message,
126          sizeof(message),
127          "Compilation failed; compiler returned status string: %s.",
128          compilerStatusstring);
129      ziAPIWriteDebugLog(0, message);
130      return 1;
131    }
132    else
133    {
134      // Success: Upload the waveform.
135      if (compilerStatus == 0)
136      {
137        snprintf(
138            message,
139            sizeof(message),
140            "Compilation successful with no warnings, compiler status string: "
141            "%s.",
142            compilerStatusstring);
143        ziAPIWriteDebugLog(0, message);
144      }
145      else if (compilerStatus == 2)
146      {
147        snprintf(
148            message,
149            sizeof(message),
150            "Compilation successful, but with warnings: %s.",
151            compilerStatusstring);
152        ziAPIWriteDebugLog(0, message);
153      }
154      // Ensure that the upload of the waveform to the device has finished.
155      ZIDoubleData progress = 0.0;
156      while (progress < 1.0)
157      {
158        sleep(200);  // [ms]
159        checkError(ziAPIModGetDouble(conn, awgModule, "progress", &progress));
160      }
161      ziAPIWriteDebugLog(0, "Uploading waveform to the device finished.");
162
163      snprintf(
164          path, sizeof(path), "/%s/awgs/%d/enable", deviceAddress, awgIndex);
165      checkError(ziAPISetValueI(conn, path, 1));
166      ziAPIWriteDebugLog(0, "Enabled the AWG.");
167    }
168    // Release module resources. Especially important if modules are created
169    // inside a loop to prevent excessive resource consumption.
170    checkError(ziAPIModClear(conn, awgModule));
171    ziAPIDisconnect(conn);
172  }
173  catch (std::runtime_error& e)
174  {
175    char extErrorMessage[1024] = "";
176    ziAPIGetLastError(conn, extErrorMessage, 1024);
177    fprintf(stderr, "Error: %s\ndetails: %s\n", e.what(), extErrorMessage);
178    return 1;
179  }
180  ziAPIDestroy(conn);
181
182  return 0;
183}