BitScope Library V2 API Guide
It provides off-the-shelf language bindings for the:
Other language bindings are available upon request.
The Library provides full programmed access to the BitScope Capture Engine. It is implemented using a small set of portable functions. Programming BitScope to capture waveforms and logic is simply a matter of calling the correct sequence of these functions from your program. There are no complicated data structures, parameter lists or callbacks.
Regardless of the device and library functions used, BitScope programming always follows a familiar sequence:
The library must first be (1) initialized and one or more devices opened. For each open device the required capture conditions must be (2) set up before a (3) trace is initiated to capture or generate the signals. When the trace completes the data may be (4) acquired to the host computer for display and analysis. Initialization and setup is normally only done once but the trace and acquire steps may be repeated as often as required. When finished the devices should be (5) closed which releases the resources allocated to them.
(1) Library and Device Initialization
Before use, the library must be initialized and one or more devices opened:
When the device is open, information about it may be obtained:
With the exception of BL_Count (see below), these functions are necessary only for reporting information to the application and identifying the device.
(2) Device Programming and Setup
After one or more devices have been opened they must be set up for use. This is the most detailed programming step but it is only needed once after opening the device unless recovering from an error. The first thing your program needs to know is how many devices, channels, ranges and other properties are available (they may not all be the same). The number of open devices may be obtained via BL_Count.
BL_Count is also used to report the number of analog channels, logic channels and analog input ranges (on each analog channel). Which entity it reports depends on its argument and which device, channel or source is selected a the time it is called. The device, channel and source are selected using BL_Select:
The first BL_Select argument specifies which type of entity to select. When the device is selected for the first time, its trace mode must also be selected:
It must be called after selecting the device but before selecting the channel. This is important because the number of channels available may be fewer than the physical number the device supports in some modes. For example, to select the BNC source on channel 1 on device 0:
Once the device and mode are selected, each channel may be selected in turn and configured to choose a source, input offset, voltage range, signal coupling and whether to enable it for capture:
For each channel enabled for capture, this process is repeated as required. When the channels are all configured, the trace may be programmed.
(3) Trace Programming and Capture
After the device, mode and channels are configured, trace settings are programmed. First the sample rate and capture size (specified in samples) are assigned:
This must be done first to establish the core trace settings. Choose values to ensure the duration required will be captured given the selected sample rate. Some modes use finite (device) buffers so your choice may be constrained. An alternative is to assign the duration directly:
In this case, the capture size and sample rate may be adjusted by the library automatically. Next the trigger, if required, is established:
This function accepts two arguments specifying the trigger level (which is applied to the currently selected channel) and the type of trigger. If signals are to be captured before the trigger, or a delay is required after the trigger, these parameters are specified next using two functions:
Both functions are optional (not required when tracing untriggered). At this point the device is ready to capture waveforms and logic data. All the preceding steps need not be repeated if the parameters for a series of captures remain unchanged. To commence the trace and capture signals call:
This function is the one that actually talks to BitScope and captures waveforms. This function may take an arbitrarily long time to complete. Indeed it may never complete, so to avoid locking your program, it may be called asynchronously or it may be called with a specified timeout. When called asynchronously BL_Trace always returns immediately, even if the trace has not yet completed. In this case call:
periodically after BL_Trace to monitor progress of the trace. BL_State returns a token reporting trace in progress, trace complete, timeout or an error code. When an asynchronous trace is in progress it may be manually stopped with:
An alternative is to call BL_Trace synchronously with a specified timeout. In this case BL_Trace is guaranteed to return within the time specified but the trace may or may not have completed in that time; it returns TRUE if it has, FALSE otherwise.
(4) Acquiring Data from the Device
Once the trace has completed, the data may be acquired:
BL_Acquire uploads data from the device one channel at a time. Before it is called each time, select the channel (and optionally the device) to be acquired with BL_Select. If acquiring from other than the first sample, the starting index may be specified:
If BL_Index is used it must be called before BL_Trace. In any case, the return value of BL_Acquire specifies how many sample are actually acquired. The return value will not be greater than the number requested but it may be fewer:
(5) Closing Devices and the Library
When you’re finished with the library, call BL_Close. This closes all open devices (it’s not possible to close only one). If you wish to close one of several devices, close them all and reopen those you wish to continue using.
Probe Files and Link Specifications
The Probe File is a configuration file on the host computer. It tells the Library where it can find the BitScopes and how to connect with them. The Probe File is a text file containing a list of Link Specifications defining connection protocols used via RS-232, USB or IP networks. It is also used by BitScope applications and is automatically created by these applications if it does not already exist. The Probe file may also be created manually with a text editor but it if does not exist when the library is used, built-in defaults are used instead.
Probe File Locations
There are two probe files on the host, one global and the other local. Both global and local Probe Files are named BitScope.prb (or bitscope.prb). The global probe file establishes system defaults and should not be modified. The local probe file is automatically created (from the global file, if the local file does not exist) and it may be manually or automatically modified, as required.
Windows Probe File Locations
On a Windows PC, the local probe file is located at:
or on older version of Windows:
where is your logged in user name on your PC. The global probe file is located at
where < BITSCOPE > is the location chosen when you installed the Library. The default (and recommended) location is:
Linux, Mac OS X and Raspberry Pi Probe File Locations
On a Linux or Mac OS X based system, the local probe file is located as:
which conforms to the XDG Specification. The global probe file is located at:
The global probe file will not exist if you have not installed the packaged version of the library but defaults apply in this case. On Linux and Mac systems, the probe file can also be located at:
but this location is depreciated and used for backward compatibility only.
Link Specification Syntax
Each line in the probe file is either blank, a comment or a link specification. A link specification defines a connection with a BitScope and has the same syntax when used directly with BL_Open as it does when it appears in a probe file. The following is an example probe file for a Linux system:
Windows systems are the same except the names used for serial and USB ports are COM1, COM2 … COM instead of /dev/ttyS0 or /dev/ttyUSB0 etc.
Probe File Defaults
If neither the local or global both probe files exist, built-in defaults are used. The library attempts to locate available BitScopes automatically in this case using an internal algorithm. Alternatively an explicit link specification can be provide to BL_Open when called (in which case the probe file is ignored). Defaults are also provided by the global probe file, if it exists. On Windows typical defaults are:
and on Linux based systems they are:
When using BL_Open with a probe file, links are probed in the order they appear in the local file, then the global file and finally the defaults are used. This is why the library can “magically open a BitScope”, only to find it’s not the BitScope you intended. Use BL_Open with an explicit link specification if you do not want this to happen.
There two special types of device supported by the library: NIL and SIM.
A NIL device is a minimal device simulation sufficient to open and configure but not synthesize capture data. It is useful when developing software with library for use with BitScope devices you may not have available because it allows you to use the Library API to test that your code works with any supported model. A NIL device link specification looks like:
where < DEVICE > is the device type identifier.
There are currently 26 device simulations supported by the library:
A SIM device is a more sophisticated device simulation that simulates the operation of some model BitScopes. In addition to a NIL device is synthesizes data as if captured by a real BitScope. It is available in some developer editions of the library only.
You may be interested to know what the library is doing as your program runs. The BL_Log function is available to provide access to this information. It tells you what the library does and how long execution takes in response to your API function calls. Example output of BL_Log looks like this:
A detailed description of these diagnostics is beyond the scope of this manual but several general points to note are the:
The BL_Log function may not be enabled in all editions of the library. For example, in optimized production releases it is usually disabled for performance reasons. By contrast, in developer editions more detailed diagnostics may available for specialized purposes. However using these generally requires a more advanced knowledge of the BitScope Capture Engine and its Virtual Machine Architecture. More information is available for OEM developers upon request.
In the real world, errors happen.
For example, the power can fail or network connections can drop out.
The Library handles many errors automatically, for example by reinitiating a device request. However, some errors are too significant to recover this way in which case the client program must take additional steps to recover normal operation.
Errors are generally detected one of three ways:
Take care with the third mechanism, BL_Acquire may return fewer samples than requested if you’ve made a set up programming error too!
In general, error recovery simply requires that you reprogram the BitScope the same way you did when you first opened it. That is, if an error is detected, re-execute your setup code before continuing as normal. If the error persists, one of the three error reporting mechanisms above will persist in which case you may wish to use BL_Error to determine the nature of the error (e.g. link down, power failure etc) and report it to the user to take appropriate action.
Most importantly, error detection and recovery is easy:
The last point simply means you can program BitScope via the library the same way repeatedly and it will always do the same thing in response.
Programming with library is very easy.
Here is a C example that captures a single analog channel:
and this is a Python example that dumps a report about a device:
There are other examples included with the packaged library for each platform.
The Library can’t find my BitScope!
Does the serial or USB port for the BitScope exist on your system when the BitScope is connected? Does your login name have permission to access it? If using a Network BitScope is the network address routable (does it “ping“) from your system?
Is your BitScope powered on and does it have a good quality power supply? Are the USB or Network and power cables you are using okay? Is your USB port working? Have you tried a different PC? Does other BitScope software connect okay?
Drop us a line any time at email@example.com if you still have problems!
Which BitScope am I really connected to?
Sometimes when opening a BitScope you get what looks like the wrong one. It probably is. This is likely due to the use of probe file defaults. Call BL_Open with an explicit link specification for the BitScope you want to avoid this possibility.
Why does it take so long to connect?
If the probe file specifies a lot of links which are invalid or the devices they refer to are not available, BL_Open may take a long time to work through them all (in the order they appear in the probe file) until it reaches the one that ultimate connects. Note: using probe file that has no correct value can result in the same thing due to defaults.
What parameter values does the library actually use?
For all such parameters you must check the return value of the parameter when you assign a new value because the return value is what the library will actually use.
Usually the requested and returned value will be the same but if you run up against the device constraints they may be different. Further, there are situations where changing one parameter (e.g. channel enable or trace mode) can alter the constraints that apply to others (e.g. sample rate or trace size).
Can I use the library in a multi-threaded environment?
Yes, but you need to know what you’re doing!
Access to the library functions is thread-safe but you need to be aware that many functions rely on the device, channel or input source being preselected by BL_Select and this can lead to a race condition in your code if you’re not careful.
To the extent we recommend you use multi-threaded programming we advise that all access to the library be confined to one thread with the call to the business end of the library (BL_Trace and BL_State) being available for use in another thread.
It’s safe to call BL_Trace synchronously in another thread and use BL_State in the main thread (or any other multi-threaded synchronization mechanism) to tell the main thread when the trace has completed.
However in general you don’t need to do this; instead, call BL_Trace asynchronously from the main thread and poll (e.g. in a timer handler) BL_State to check progress.
Help! I don’t understand how BL_xxxx works?
Email us any time at firstname.lastname@example.org for assistance.
This is not working, I’ve found a Bug!
You may well have done. Please email full details to email@example.com!
BL_Acquire - dump data from the device
This is the primary data acquisition function.
Call BL_Acquire to dump data from a channel to the host (Acquire) after the data has been captured by the device (BL_Trace). Data is dumped from the selected channel on the selected device (BL_Select). To dump data from multiple channels, possibly on multiple devices, loop through and select each channel on each device and call BL_Acquire at each iteration.
Acquired data is written to the array in memory pointed to by AData. The number of samples acquired is ASize. The size of the array provided must be at least ASize. The dump commences at the first sample in the channel buffer unless a different (positive) starting index is specified (BL_Index). The sum of the dump size and start index must be less than or equal to the total trace size (BL_Size).
The return value is the number of samples acquired. It equals the number of samples requested (ASize) unless:
If 3 occurs you may need to take steps to recover the error. Like BL_Trace (when called synchronously) this function may take a while to complete. How long it takes depends on the speed of the link between the host and the device.
BL_Close - close all open devices
Close all open device connections and free all resources.
If you wish to close only one of several devices, close them all and reopen those you wish to continue using. In most situations, retaining an open device for later use is not expensive.
BL_Count - count devices, channels, or ranges
Count available devices, channels and ranges.
When one or more devices have been opened (BL_Open) one usually needs to know how many opened successfully. For each device one may also need to know many channels and how many analog ranges are available.
BL_Count returns a count based on its AType argument:
When counting channels or ranges a device must first be selected (BL_Select).
BL_Coupling - select the channel source coupling
Choose DC, AC or RF coupling on the selected channel.
Many BitScope models offer software selectable DC or AC coupling for their BNC terminated inputs. Some others offer an RF coupling option.
BL_Coupling selects the coupling used via ACoupling argument:
BL_Coupling returns the newly selected coupling if successful or the prevailing coupling otherwise, so check the return value to determine if the requested coupling is available. Use BL_ASK to enquire the prevailing coupling without changing it.
BL_Delay - assign post-trigger delay
Apply an optional post-trigger delay the trace.
All BitScopes offer a facility to insert a precise delay after the trigger before waveform capture proceeds (in most trace modes).
BL_Delay establishes this post-trigger delay (ADelayTime, in seconds). It returns the same value if the device can support it, otherwise the nearest value is returned.
Always check the return value because it is the value that is actually used.
To specify that no post trigger delay should be used, specify BL_ZERO.
To specify a pre-trigger capture duration use BL_Intro.
BL_Enable - change channel enable status
Enable or disable a channel from participating in a trace.
Use BL_Enable to enable or disable the selected channel on the selected device from particpating in a trace. It’s generally good idea to disable channels you are not using because it frees up device buffers and other resources for the other channels.
If you change a channel’s enable state, it is recommended that you also reassign trace parameters such sample rate and size even if the intended values remain unchanged because constraints may apply.
BL_Error - return most recent error (if any)
Report the most recent error code (if any).
However, when encountering a FUBAR class error you may need to report to the user an error code which will tell them what to fix to recover from it (e.g. restore device power). In this case the return value of BL_Error provides this information.
BL_Halt - all any pending or prevailing device activity
Terminate all activity on the selected device.
Call BL_Halt to terminate any pending or prevailing device activity. Returns TRUE if successful, FALSE otherwise. BL_Halt returns FALSE only if an error occured when talking to the device; in this case you may need to recover the error. BL_Halt does not need to be called if the capture engine state is not BL_STATE_ACTIVE but it is safe to call it at any time.
BL_ID - return the selected device ID
Read the unique ID of the selected device.
Every BitScope device has a unique ID. BL_ID returns this ID.
This information is useful to record with captured data so as to keep a record of which device produced that data. It may also be used in a link specification to ensure one connects to a uniquely identified device.
BL_Index - assign the buffer offset (for dumps)
Assign an offset in the capture buffer from which to acquire data.
When dumping data from the device buffer using BL_Acquire is may be desirable to commence the dump from a sample other than the first. Use BL_Index to specify this offset.
BL_Initialize - initialize the library (optional)
Initialize the library infrastructure for use.
This function is optional; it is called implicitly when the first device is opened. It may be called explicit before any devices are opened if preferred.
BL_Intro - assign the pre-trigger size (intro region)
Apply an optional pre-trigger capture duration the trace.
BitScopes offer a facility to capture before the trigger (in most trace modes). BL_Intro establishes this pre-trigger capture duration (APreTrigger, in seconds). It returns the same value if the device can support it, otherwise the nearest value is returned.
Always check the return value because it is the value that is actually used.
To specify that no pre-trigger capture should be used, specify BL_ZERO.
To specify a post-trigger delay use BL_Intro.
BL_Log - dump the pending log
Dump the library diagnostic log.
In developer editions of the library the internal operation of the library is logged. BL_Log returns a dump of this information to assist with program development using the library. See Diagnostics for more information.
BL_Mode - select and trace mode
Choose the trace mode to be used for the next capture.
All BitScope models offer a range of trace modes. Trace modes define how the device captures the input signals:
All models offer BL_MODE_FAST and BL_MODE_MIXED. The other modes are available on some models and not others; it depends on the hardware design of each model. See the hardware guide for your device.
BL_MODE_FAST is recommended for analog waveform capture only and BL_MODE_MIXED when also capturing logic data. BL_MODE_DUAL is recommended for single A/D devices when sample synchronous analog waveform capture is required. BL_MODE_LOGIC is recommend when capturing logic only and BL_MODE_STREAM is used for continuous waveform capture.
BL_Name - return the device link name
Read the canonic link specification of the selected device.
The host connects to each BitScope device accorind to a link specification.
Call BL_Name to return the canonic link specification.
BL_Offset - assign channel offset
Apply a voltage offset to the selected channel
Most BitScope models allow an input offset to be applied to the signal captured on analog channels. BL_Offset assigns this offset (AValue, in volts) to the selected channel on the selected device. It returns the same value if the device can support it, otherwise the nearest value is returned.
Always check the return value because it is the value that is actually used.
To specify that no offset should be applied, specify BL_ZERO.
BL_Open - open one or more devices
Open one or more device according supplied link specifications.
Call BL_Open to open a device specified by AProbeStr. If the second argument (ACount) is provided it tells BL_Open how many devices to open (defaults to 1).
The first argument can be:
BL_Open attempts to open the devices using these techniques in the order listed.
It returns the number of devices sucessfully opened.
Each opened device may then be selected with an index from 0 to N-1 where N is the value returned by BL_Open or BL_Count (BL_COUNT_DEVICES).
BL_Range - select the channel range
Select the analog input range the selected source
All BitScope models provide a number of analog input ranges which scale the signal prior to capture and conversion to the digital domain.
Use BL_Range to assign the desired range (AIndex) to the selected source. The source index used must be between 0 and BL_Count (BL_COUNT_RANGE)-1;
BL_Range returns the full voltage span of the selected range.
BL_Rate - assign the sample rate
Assign the capture sample rate for the next trace.
The capture sample rate is a fundamentally important trace parameter.
It must always be specified and it should be the first parameter assigned when preparing a new trace (if different from the previous trace).
BL_Rate establishes the preferred sample rate (ASampleRate, in Hz). It returns the same value if the device can support it, otherwise the nearest value is returned.
To choose the highest sample rate supported by the selected device in the current mode, specify BL_MAX_RATE. To enquire what the prevailing sample rate is without changing it, specify BL_ASK. Regardless of how BL_Rate is called always check the return value because it is the value that is actually used.
BL_Select - select a device, channel or source
Select the a device, channel or source for subsequent use.
The library makes available multiple devices, channels and input sources. Most API functions operate on one of these at a time. Use BL_Select to choose which one.
BL_Selects chooses which entity type to select via its first (AType) argument:
The entity of that type is selected via the second (AIndex) argument.
BL_Select returns the index of the selected entity if the selection was successful. The prevailing selection is returned unchanged otherwise, so check the return value is the same as the AIndex argument to confirm the new selection was successful. Use BL_ASK to enquire the prevailing selection without changing it.
Devices enumerate from 0 to BL_Count (BL_COUNT_DEVICES)-1.
Analog channels enumerate from 0 to 3 and logic channels from 4 to 11.
Sources are selected from a pre-defined set of options:
Not all device types support all sources. Check the return index when attempting to select one to see if it’s available.
BL_Size - assign the capture size (samples)
Assign the capture size for the next trace.
The capture size is a fundamentally important trace parameter. It must always be specified and it should be the second parameter assigned (after BL_Rate) when preparing a new trace (if different from the previous trace).
BL_Size establishes the preferred trace size (ASize, in samples). It returns the same value if the device can support it, otherwise the nearest value is returned. To choose the largest size supported by the selected device in the current mode, specify BL_MAX_SIZE. To enquire what the prevailing size is without changing it, specify BL_ASK. Regardless of how BL_Size is called always check the return value because it is the value that is actually used.
BL_State - return capture engine state
Report capture engine state while tracing.
When a trace is initiated asynchronously the state of the capture engine is needed to be able to know when the trace has completed and acquisition can proceed. Use BL_State to obtain this information. BL_State always returns immediately reporting the capture engine is:
The only state in which it is valid to call BL_Acquire is BL_STATE_DONE. This state means the trace completed successfully, either because a trigger was seen or a timeout occured but in either case data may be acquired from the device.
If BL_STATE_ERROR is reported an error occured during the most recent trace. The trace has completed but the data (if any) cannot be relied upon as reliable. Call BL_Error to learn more about the error and what you may need to do to recover.
While BL_STATE_ACTIVE is reported you must not call any other function to access the device unless you halt it first. If BL_STATE_IDLE is reported you can program the device as required but data is not guaranteed to be available for BL_Acquire.
BL_State may be called at any time after the library has been initialized and device selected. If BL_Trace is called synchronously it reports the same information except in this case the BL_STATE_ACTIVE state will never be reported (because it prevails only for as long as the synchronous call to BL_Trace does).
BL_Time - assign the capture duration (seconds)
Enquire the capture duration for the next trace.
The capture duration is usually assigned implicitly (as a consequence of the prevailing BL_Rate and BL_Size). It may also be specified explicitly but if it is, the sample rate and trace size may also be modified their values should be rechecked.
The recommended use for this function is to enquire what the prevailing duration is without changing it by specifing BL_ASK. Regardless of how BL_Time is called always check the return value because it is the value that is actually used.
BL_Trace - initiate capture
Initiate data capture on the device:
The process of capturing data on BitScope is referred to as a trace. Call BL_Trace to initiate a trace after calling the other functions as required to setup the trace.
BL_Trace is unique because the time it takes to execute can be indeterminate (which depends on the trigger). You must take care to call it correctly, especially if called from your main application thread; it may never return if called synchronously without a timeout. It can be recovered in this case, but only from a different thread.
To avoid complications, BL_Trace offers two calling conventions:
The first argument (ATimeOut, in seconds) specifies the timeout used and the second (ASync) specifies the call is to be asynchronous. The return value indicates whether BL_Trace commenced successfully (in the asynchronous case) or commenced and completed successfully (in the synchronous case).
The simplest usage is a synchronous call with a non-zero timeout. In this case BL_Trace will block the caller and return when:
If the timeout is short (on a human timescale), this type of usage is compatible with single threaded programming for an interractive program. It is simple because the return value of BL_Trace may be used directly to detemine success (i.e. BL_State is not required) and all programming is synchronous.
If the timeout required is long or you need to specify infinite timeout (i.e. the trigger timing is unknown), an asynchronous call is recommended (unless you are calling BL_Trace from a different thread). In this case BL_Trace will always return to the caller immediately but the trace may not have completed. The return value in this case will always be TRUE unless an error occured when talking to the device.
When BL_Trace is called asynchronously you must poll the trace state (BL_State) to determine when the trace has completed; it is a programming error to use any other library function (except BL_Halt) before the trace has completed.
Two special values for the timeout are available:
Use the former if want a trace and you don’t care about the trigger condition (the trigger condition is ignored in this case). Use the latter if you want to wait for as long as it takes for a trigger. If the trigger condition is never met, the trace will never complete unless manually halted.
BL_Trigger - set up the trigger
Establish the trigger condition to apply to the selected channel.
If BL_Trace is used with a timeout or with BL_TRACE_FOREVER, a trigger condition is applied as a predicate to the completion of the trace. This means the trace will complete only when the trigger condition is satisfied.
Use BL_Trigger to establish a trigger condition on a selected channel. Call it multiple times, once for each channel, if a combinatorial condition is required to apply to more than one channel.
BL_Version - return the version
Enquire the device, library, bindings and other version information.
When using the library is may necessary to know the device, library or other version information. This functions provides access to this information as it applies to the selected device. There are several version types that may be requested:
In general you will likely be interested in the first two. The other versions are available to help diagnosis in the event that you discover problems when using a particular instance of the library or its language bindings.
This document may be copied and redistributed under the terms of the GNU Free Documentation License as published by the Free Software Foundation; either version 1.2, or (at your option) any later version.
BitScope Library V2.0 Build (FE26A) - User Programming Manual (EC21A)
Copyright (C) BitScope Designs, May 26, 2015
Copyright © 2023 BitScope Designs