libsmu  1.0.4
Library for interfacing with ADALM1000 devices
libsmu.hpp
Go to the documentation of this file.
1 // Released under the terms of the BSD License
2 // (C) 2014-2016
3 // Analog Devices, Inc.
4 // Kevin Mehall <km@kevinmehall.net>
5 // Ian Daniher <itdaniher@gmail.com>
6 
9 
10 #pragma once
11 
12 #include <cstdint>
13 #include <array>
14 #include <atomic>
15 #include <condition_variable>
16 #include <functional>
17 #include <mutex>
18 #include <set>
19 #include <string>
20 #include <thread>
21 #include <vector>
22 #include <map>
23 
24 #include <libusb.h>
25 
26 #include <libsmu/version.hpp>
27 
31 const std::vector<std::vector<uint16_t>> SUPPORTED_DEVICES = {
32  {0x0456, 0xcee2}, // old
33  {0x064b, 0x784c}, // new
34 };
35 
39 const std::vector<std::vector<uint16_t>> SAMBA_DEVICES = {
40  {0x03eb, 0x6124}, // shows up as a CDC device by default
41 };
42 
44 typedef struct sl_signal_info {
46  const char* label;
47 
49  uint32_t inputModes;
50 
52  uint32_t outputModes;
53 
55  double min;
56 
58  double max;
59 
61  double resolution;
63 
65 typedef struct sl_channel_info {
66  const char* label;
67  size_t mode_count;
68  size_t signal_count;
70 
72 typedef struct sl_device_info {
73  const char* label;
74  size_t channel_count;
76 
78 enum Src {
83  SINE,
85 };
86 
88 enum Mode {
89  HI_Z,
90  SVMI,
91  SIMV,
95 };
96 
98 enum LED{
99  RED = 47,
100  GREEN = 29,
101  BLUE = 28,
102  ALL = 0
103 };
104 
105 namespace smu {
106  class Device;
107  class Signal;
108 
110  class Session {
111  public:
112  Session();
113  ~Session();
114 
116  void set_off(Device*);
117 
123  std::vector<Device*> m_available_devices;
124 
128  std::set<Device*> m_devices;
129 
132 
134  std::map<libusb_device*, libusb_device_handle*> m_deviceHandles;
135 
141  unsigned m_queue_size = 100000;
142 
144  unsigned m_samples;
145 
151  int scan();
152 
158  int add(Device* device);
159 
164  int add_all();
165 
173  int remove(Device* device, bool detached = false);
174 
182  int destroy(Device* device);
183 
191  int configure(uint32_t sampleRate = 0);
192 
198  int run(uint64_t samples);
199 
213  int start(uint64_t samples);
214 
220  int cancel();
221 
227  bool cancelled() { return m_cancellation != 0; }
228 
230  void flush();
231 
236  int scan_samba_devs(std::vector<libusb_device*>& samba_devs);
237 
244  int flash_firmware(std::string file, std::vector<Device*> devices = {});
245 
247  void completion();
249  void handle_error(int status, const char * tag);
251  void attached(libusb_device* usb_dev);
253  void detached(libusb_device* usb_dev);
254 
260  int end();
261 
266  std::function<void(unsigned)> m_completion_callback;
267 
269  uint64_t m_sample_rate = 0;
270 
272  bool m_continuous = false;
273 
274  protected:
276  unsigned m_cancellation = 0;
277 
280  std::atomic<bool> m_usb_thread_loop;
282  std::thread m_usb_thread;
283 
285  std::mutex m_lock;
289  std::mutex m_lock_devlist;
291  std::condition_variable m_completion;
292 
296  libusb_context* m_usb_ctx;
297 
299  libusb_hotplug_callback_handle m_usb_cb;
300 
302  std::vector<std::function<void(Device* device)>> m_hotplug_attach_callbacks;
304  std::vector<std::function<void(Device* device)>> m_hotplug_detach_callbacks;
305 
310  Device* probe_device(libusb_device* usb_dev);
311 
317  Device* find_existing_device(libusb_device* usb_dev);
318  };
319 
321  class Device {
322  public:
323  virtual ~Device() {};
324 
326  virtual const sl_device_info* info() const = 0;
327 
330  virtual const sl_channel_info* channel_info(unsigned channel) const = 0;
331 
336  virtual Signal* signal(unsigned channel, unsigned signal) = 0;
337 
339  const std::string m_hwver;
341  const std::string m_fwver;
343  const std::string m_serial;
344 
346  std::pair<uint8_t, uint8_t> m_usb_addr;
347 
351  virtual int fwver_sem(std::array<unsigned, 3>& components) = 0;
352 
359  virtual int set_serial(std::string serial = "") = 0;
360 
365  // set in order to restore it for the next data acquisition, defaults to true.
369  virtual int set_mode(unsigned channel, unsigned mode, bool restore = true) = 0;
370 
372  void set_usb(libusb_device_handle* usb) {m_usb = usb;}
373 
378  virtual int get_mode(unsigned channel) = 0;
379 
390  virtual ssize_t read(std::vector<std::array<float, 4>>& buf, size_t samples, int timeout = 0, bool skipsamples = false) = 0;
391 
399  virtual int write(std::vector<float>& buf, unsigned channel, bool cyclic = false) = 0;
400 
404  virtual void flush(int channel, bool read = false) = 0;
405 
409  int ctrl_transfer(unsigned bmRequestType, unsigned bRequest, unsigned wValue, unsigned wIndex,
410  unsigned char *data, unsigned wLength, unsigned timeout);
411 
415  virtual int samba_mode() = 0;
416 
418  virtual int get_default_rate() { return 100000; }
419 
424  virtual int sync() = 0;
425 
429  virtual void lock() { m_state.lock(); }
430 
433  virtual void unlock() { m_state.unlock(); }
434 
441  virtual int write_calibration(const char* cal_file_name) { return 0; }
442 
444  virtual int read_calibration() = 0;
445 
448  virtual void calibration(std::vector<std::vector<float>>* cal) = 0;
449 
453  int m_overcurrent = 0;
454 
457  virtual int set_led(unsigned leds) = 0;
459  virtual int set_adc_mux(unsigned adc_mux) = 0;
460 
462  virtual void set_usb_device_addr(std::pair<uint8_t, uint8_t> usb_addr) = 0;
463 
464  protected:
466  Device(Session* s, libusb_device* usb_dev, libusb_device_handle* usb_handle,
467  const char* hw_version, const char* fw_version, const char* serial);
468 
472  virtual int claim() { return 0; }
473 
477  virtual int release() { return 0; }
478 
483  virtual int configure(uint32_t sampleRate) = 0;
484 
488  virtual int on() = 0;
489 
493  virtual int off() = 0;
494 
500  virtual int run(uint64_t samples) = 0;
501 
505  virtual int cancel() = 0;
506 
509 
511  libusb_device* const m_usb_dev = NULL;
513  libusb_device_handle* m_usb = NULL;
514 
516  uint64_t m_requested_sampleno = 0;
518  uint64_t m_in_sampleno = 0;
520  uint64_t m_out_sampleno = 0;
521 
524  double m_write_timeout = 100;
525 
527  std::recursive_mutex m_state;
528 
529  friend class Session;
530  };
531 
533  class Signal {
534  public:
536  Signal(const sl_signal_info* info = NULL):
537  m_info(info)
538  {}
539 
542  const sl_signal_info* info() const { return m_info; }
544  const sl_signal_info* const m_info;
545 
550  void constant(std::vector<float>& buf, uint64_t samples, float val);
551 
560  void square(std::vector<float>& buf, uint64_t samples, float midpoint, float peak, double period, double phase, double duty);
561 
569  void sawtooth(std::vector<float>& buf, uint64_t samples, float midpoint, float peak, double period, double phase);
570 
578  void stairstep(std::vector<float>& buf, uint64_t samples, float midpoint, float peak, double period, double phase);
579 
587  void sine(std::vector<float>& buf, uint64_t samples, float midpoint, float peak, double period, double phase);
588 
596  void triangle(std::vector<float>& buf, uint64_t samples, float midpoint, float peak, double period, double phase);
597 
598  protected:
600  Src m_src;
601 
603  float m_src_v1;
604 
606  float m_src_v2;
607 
609  double m_src_period;
610 
612  double m_src_duty;
613 
615  double m_src_phase;
616 
618  float get_sample();
619  };
620 }
double resolution
Signal resolution.
Definition: libsmu.hpp:61
void handle_error(int status, const char *tag)
internal: Called by devices on the USB thread when a device encounters an error.
virtual int read_calibration()=0
Read device calibration data from the EEPROM.
virtual ssize_t read(std::vector< std::array< float, 4 >> &buf, size_t samples, int timeout=0, bool skipsamples=false)=0
Get all signal samples from a device.
Mode
Supported channel modes.
Definition: libsmu.hpp:88
std::mutex m_lock_devlist
Lock for the available device list. All code that references m_available_devices needs to acquire thi...
Definition: libsmu.hpp:289
int cancel()
Cancel capture and block waiting for it to complete.
uint64_t m_in_sampleno
Current sample number being handled for input.
Definition: libsmu.hpp:518
void sine(std::vector< float > &buf, uint64_t samples, float midpoint, float peak, double period, double phase)
Generate a sinusoidal waveform.
Source voltage, measure current.
Definition: libsmu.hpp:90
virtual int off()=0
Stop any current sample writes and stop capturing samples.
size_t signal_count
Number of available signals.
Definition: libsmu.hpp:68
virtual int run(uint64_t samples)=0
Make the device start sampling.
int remove(Device *device, bool detached=false)
Remove a device from the session.
int run(uint64_t samples)
Run the currently configured capture and wait for it to complete.
virtual int sync()=0
Prepare multi-device synchronization. Get current microframe index, set m_sof_start to be time in the...
const char * label
Device label.
Definition: libsmu.hpp:73
SIMV with enabled switch for the input only pin added in Rev F.
Definition: libsmu.hpp:94
const std::vector< std::vector< uint16_t > > SAMBA_DEVICES
List of supported devices in SAM-BA bootloader mode. The list uses the vendor and project IDs from US...
Definition: libsmu.hpp:39
uint64_t m_requested_sampleno
Cumulative sample number being handled for input.
Definition: libsmu.hpp:516
std::vector< std::function< void(Device *device)> > m_hotplug_detach_callbacks
Callbacks called on the USB thread when a device is plugged into the system.
Definition: libsmu.hpp:304
virtual void unlock()
Unlock the device's mutex. Allows this device's transfers to be processed.
Definition: libsmu.hpp:433
Src
Supported signal sources.
Definition: libsmu.hpp:78
std::condition_variable m_completion
Blocks on m_lock until session completion is finished.
Definition: libsmu.hpp:291
uint32_t inputModes
Bitmask of modes for which this signal is enabled as input.
Definition: libsmu.hpp:49
Stairstep wave output.
Definition: libsmu.hpp:82
int scan_samba_devs(std::vector< libusb_device * > &samba_devs)
Scan system for devices in SAM-BA mode.
virtual int set_adc_mux(unsigned adc_mux)=0
set adc mux mode
std::recursive_mutex m_state
Lock for transfer state.
Definition: libsmu.hpp:527
virtual int cancel()=0
Cancel all pending libusb transactions.
virtual const sl_channel_info * channel_info(unsigned channel) const =0
Get the descriptor for the specified channel.
int add_all()
Shim to scan and add all available devices to a session. This method may not be called while the sess...
Source current, measure voltage.
Definition: libsmu.hpp:91
std::vector< Device * > m_available_devices
Devices that are present on the system. Note that these devices consist of all supported devices curr...
Definition: libsmu.hpp:123
Device(Session *s, libusb_device *usb_dev, libusb_device_handle *usb_handle, const char *hw_version, const char *fw_version, const char *serial)
Device constructor.
virtual const sl_device_info * info() const =0
Get the descriptor for the device.
struct sl_signal_info sl_signal_info
Signal information.
libusb_device *const m_usb_dev
Underlying libusb device.
Definition: libsmu.hpp:511
libusb_context * m_usb_ctx
libusb context related with a session. This allows for segregating libusb usage so external users can...
Definition: libsmu.hpp:296
Device info.
Definition: libsmu.hpp:72
virtual int get_default_rate()
Get the default sample rate.
Definition: libsmu.hpp:418
void stairstep(std::vector< float > &buf, uint64_t samples, float midpoint, float peak, double period, double phase)
Generate a stairstep waveform.
Signal(const sl_signal_info *info=NULL)
internal: Do not call the constructor directly; obtain a Signal from a Device.
Definition: libsmu.hpp:536
virtual int claim()
Device claiming and initialization when a session adds this device.
Definition: libsmu.hpp:472
void constant(std::vector< float > &buf, uint64_t samples, float val)
Generate a constant waveform.
const char * label
Signal label.
Definition: libsmu.hpp:46
int ctrl_transfer(unsigned bmRequestType, unsigned bRequest, unsigned wValue, unsigned wIndex, unsigned char *data, unsigned wLength, unsigned timeout)
Perform a raw USB control transfer on the underlying USB device.
Generic signal class.
Definition: libsmu.hpp:533
double max
Maximum possible value for the signal.
Definition: libsmu.hpp:58
double min
Minimum possible value for the signal.
Definition: libsmu.hpp:55
uint64_t m_sample_rate
Session sample rate.
Definition: libsmu.hpp:269
virtual int configure(uint32_t sampleRate)=0
Configurization and initialization for device sampling.
void square(std::vector< float > &buf, uint64_t samples, float midpoint, float peak, double period, double phase, double duty)
Generate a square waveform.
void triangle(std::vector< float > &buf, uint64_t samples, float midpoint, float peak, double period, double phase)
Generate a triangle waveform.
Square wave output.
Definition: libsmu.hpp:80
virtual int fwver_sem(std::array< unsigned, 3 > &components)=0
Get the array of firmware version components (major, minor, patch). Note that this method assumes sem...
virtual int get_mode(unsigned channel)=0
Get the mode of the specified channel.
virtual int write(std::vector< float > &buf, unsigned channel, bool cyclic=false)=0
Write data to a specified channel of the device.
Channel info.
Definition: libsmu.hpp:65
struct sl_channel_info sl_channel_info
Channel info.
int scan()
Scan system for all supported devices. Updates the list of available, supported devices for the sessi...
virtual Signal * signal(unsigned channel, unsigned signal)=0
Get the specified signal.
struct sl_device_info sl_device_info
Device info.
virtual void flush(int channel, bool read=false)=0
Flush the read and selected channel write queue for a device.
const std::string m_serial
serial number
Definition: libsmu.hpp:343
HI_Z with enabled switch for the input only pin added in Rev F.
Definition: libsmu.hpp:92
int start(uint64_t samples)
Start the currently configured capture, but do not wait for it to complete.
const sl_signal_info *const m_info
Signal information.
Definition: libsmu.hpp:544
bool m_continuous
Flag used to determine if a session is in continuous mode or not.
Definition: libsmu.hpp:272
virtual int release()
Device releasing when a session removes this device.
Definition: libsmu.hpp:477
Generic device class.
Definition: libsmu.hpp:321
virtual int set_mode(unsigned channel, unsigned mode, bool restore=true)=0
Set the mode of the specified channel.
std::vector< std::function< void(Device *device)> > m_hotplug_attach_callbacks
Callbacks called on the USB thread when a device is removed from the system.
Definition: libsmu.hpp:302
void completion()
internal: Called by devices on the USB thread when they are complete.
virtual void calibration(std::vector< std::vector< float >> *cal)=0
Get the device calibration data from the EEPROM.
int destroy(Device *device)
Remove a device from the list of available devices.
std::thread m_usb_thread
USB thread handling pending events in blocking mode.
Definition: libsmu.hpp:282
size_t mode_count
Number of available modes.
Definition: libsmu.hpp:67
double m_write_timeout
Amount of time in milliseconds to wait before timing out write operations, defaults to 100 ms and is ...
Definition: libsmu.hpp:524
virtual int write_calibration(const char *cal_file_name)
Write the device calibration data into the EEPROM.
Definition: libsmu.hpp:441
unsigned m_active_devices
Number of devices currently streaming samples.
Definition: libsmu.hpp:131
std::atomic< bool > m_usb_thread_loop
Flag for controlling USB event handling. USB event handling loop will be run while m_usb_thread_loop ...
Definition: libsmu.hpp:280
unsigned m_cancellation
Flag used to cancel all pending USB transactions for devices in a session.
Definition: libsmu.hpp:276
Constant value output.
Definition: libsmu.hpp:79
int m_overcurrent
Session this device is associated with.
Definition: libsmu.hpp:453
SVMI with enabled switch for the input only pin added in Rev F.
Definition: libsmu.hpp:93
Generic session class.
Definition: libsmu.hpp:110
virtual int set_led(unsigned leds)=0
Set the leds states for device.
void attached(libusb_device *usb_dev)
internal: Called by device attach events on the USB thread.
Sine wave output.
Definition: libsmu.hpp:83
void detached(libusb_device *usb_dev)
internal: Called by device detach events on the USB thread.
unsigned m_queue_size
Size of input/output sample queues for every device. Alter this if necessary to make continuous data ...
Definition: libsmu.hpp:141
const std::vector< std::vector< uint16_t > > SUPPORTED_DEVICES
List of supported devices. The list uses the vendor and project IDs from USB information formatted as...
Definition: libsmu.hpp:31
uint32_t outputModes
Bitmask of modes for which this signal is enabled as output.
Definition: libsmu.hpp:52
virtual void lock()
Lock the device's mutex. This prevents this device's transfers from being processed....
Definition: libsmu.hpp:429
int add(Device *device)
Add a device to the session. This method may not be called while the session is active.
std::map< libusb_device *, libusb_device_handle * > m_deviceHandles
Map for the workaround described in session.cpp -> probe_device().
Definition: libsmu.hpp:134
int end()
For noncontinuous sessions, block until all devices have completed, then turn off the devices....
std::mutex m_lock
Lock for session completion.
Definition: libsmu.hpp:285
virtual int samba_mode()=0
Force the device into SAM-BA bootloader mode.
void flush()
Flush the read and write queues for all devices in a session.
virtual int set_serial(std::string serial="")=0
Set a custom serial number for the device.
Channel is floating.
Definition: libsmu.hpp:89
libusb_hotplug_callback_handle m_usb_cb
libusb hotplug callback handle.
Definition: libsmu.hpp:299
Session *const m_session
Session this device is associated with.
Definition: libsmu.hpp:508
const char * label
Channel label.
Definition: libsmu.hpp:66
size_t channel_count
Number of available channels.
Definition: libsmu.hpp:74
Signal information.
Definition: libsmu.hpp:44
void sawtooth(std::vector< float > &buf, uint64_t samples, float midpoint, float peak, double period, double phase)
Generate a sawtooth waveform.
std::set< Device * > m_devices
Devices that are part of this session. These devices will be started when start() is called....
Definition: libsmu.hpp:128
libusb_device_handle * m_usb
Underlying libusb device handle.
Definition: libsmu.hpp:513
const sl_signal_info * info() const
Get the descriptor struct of the Signal. Pointed-to memory is valid for the lifetime of the Device.
Definition: libsmu.hpp:542
const std::string m_fwver
firmware version
Definition: libsmu.hpp:341
Triangle wave output.
Definition: libsmu.hpp:84
Library versioning support. Versioning for libsmu follows the guidelines of semantic versioning for s...
Sawtooth wave output.
Definition: libsmu.hpp:81
float get_sample()
Generate value for currently selected waveform.
int flash_firmware(std::string file, std::vector< Device * > devices={})
Update firmware for the target device(s).
bool cancelled()
Determine the cancellation status of a session.
Definition: libsmu.hpp:227
int configure(uint32_t sampleRate=0)
Configure the session's sample rate.
Device * probe_device(libusb_device *usb_dev)
Identify devices supported by libsmu.
Device * find_existing_device(libusb_device *usb_dev)
Find an existing, available device.
std::function< void(unsigned)> m_completion_callback
Callback run via the USB thread on session completion. Called with the current value of m_cancellatio...
Definition: libsmu.hpp:266
const std::string m_hwver
hardware version
Definition: libsmu.hpp:339
virtual int on()=0
Turn on power supplies and clear sampling state.
uint64_t m_out_sampleno
Current sample number being submitted for output.
Definition: libsmu.hpp:520