About the DWF C Library
Digilent provides the Digilent Waveforms library to control their line of line of electronic test and measurement devices. The library is available as a DLL on Microsoft Windows, a shared object (“so”) library on Linux, and a framework on Apple’s macOS. The provided library is accompanied by a C header file; together with the shared library file itself, this allows access to the functionality provided from the C and C++ programming languages.
Accessing the DWF library from Python
Most popular programming languages provide a mechanism to access functions in shared libraries. In Python, such a mechanism is provided by the ctypes
module that is part of the standard Python library.
The pydwf package is a binding to the functionality provided by the DWF library, using the ctypes
module. It makes all types and functions provided by the DWF library available for use in Python programs, wrapping them in a small set of classes that makes them easy to use.
Overview of the C API
The DWF library comes with a C header file that (for version 3.20.1) defines the 27 enumeration types and 478 function calls that together make up the DWF API. Of the 478 function calls provided, 33 are labeled obsolete. Their functionality is usually superseded by newer, more general functions.
The API functions are organized in 16 sub-categories, each providing access to a subset of the DWF functionality — for example, a specific type of instrument, or functions to send and receive messages using a certain protocol.
The function counts for each of the sub-categories of functionality are listed below, to give some idea of the complexity of the different areas of the API.
C API category |
pydwf equivalent |
active |
obsolete |
total |
(miscellaneous) |
5 |
0 |
5 |
|
FDwfEnum |
11 |
4 |
15 |
|
FDwfDevice |
16 |
0 |
16 |
|
FDwfSpectrum |
3 |
0 |
3 |
|
FDwfAnalogIn |
100 |
1 |
101 |
|
FDwfAnalogOut |
58 |
25 |
83 |
|
FDwfAnalogIO |
17 |
0 |
17 |
|
FDwfAnalogImpedance |
23 |
0 |
23 |
|
FDwfDigitalIn |
60 |
2 |
62 |
|
FDwfDigitalOut |
52 |
1 |
53 |
|
FDwfDigitalIO |
25 |
0 |
25 |
|
FDwfDigitalUart |
10 |
0 |
10 |
|
FDwfDigitalSpi |
32 |
0 |
32 |
|
FDwfDigitalI2c |
14 |
0 |
14 |
|
FDwfDigitalCan |
7 |
0 |
7 |
|
FDwfDigitalSwd |
12 |
0 |
12 |
|
TOTAL |
445 |
33 |
478 |
From this table, it is clear that the most complex parts of the API are the AnalogIn (“oscilloscope”) and AnalogOut (“waveform generator”) instruments, followed by the DigitalIn (“logic analyzer”) and DigitalOut (“pattern generator”) instruments. About 60% of all the functions provided by the DWF library are directly related to control of these four powerful instruments.
Error handling in the C API
Each function in the C API returns an integer, indicating its success or error status. A value of 0 indicates an error, while a value of 1 indicates success.
- Note:
This is different from the convention used in most C libraries, where a 0 return value indicates success.
In earlier versions of libdwf the return value of operations was specified to be of type bool, with true (1) indicating success and false (0) indicating failure. The return type was changed to int at some point, but the values for success and failure remained the same for reasons of backward compatibility.
In case a function returns 0, indicating some kind of failure, the C API provides two functions to inquire the reason of the failure. The FDwfGetLastError function returns a value of C enumeration type DWFERC (represented in Python by the enumeration type DwfErrorCode
), indicating the cause of the last error, while function FDwfGetLastErrorMsg returns a string describing the error.
In pydwf, the low-level error reporting provided by the C API is handled by checking the return value of any C API call, and raising a DwfLibraryError
whenever a failure is detected.