Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • whuie2/awg-control
  • xiyehu2/awg-control
2 results
Show changes
Commits on Source (146)
Showing
with 4739 additions and 58 deletions
Python/test.ipynb
__pycache__/
*.pyc
*.png
*.npz
**.swp
## Ignore Visual Studio temporary files, build results, and
## files generated by popular Visual Studio add-ons.
# User-specific files
*.suo
*.user
*.userosscache
*.sln.docstates
# Build results
[Dd]ebug/
[Dd]ebugPublic/
[Rr]elease/
[Rr]eleases/
x64/
x86/
bld/
[Bb]in/
[Oo]bj/
[Ll]og/
# Visual Studio 2015 cache/options directory
.vs/
*_i.c
*_p.c
*_i.h
*.ilk
*.meta
*.obj
*.pch
*.pdb
*.pgc
*.pgd
*.rsp
*.sbr
*.tlb
*.tli
*.tlh
*.tmp
*.tmp_proj
*.log
*.vspscc
*.vssscc
.builds
*.pidb
*.svclog
*.scc
# Visual C++ cache files
ipch/
*.aps
*.ncb
*.opendb
*.opensdf
*.sdf
*.cachefile
# Visual Studio profiler
*.psess
*.vsp
*.vspx
*.sap
# Installshield output folder
[Ee]xpress/
# DocProject is a documentation generator add-in
DocProject/buildhelp/
DocProject/Help/*.HxT
DocProject/Help/*.HxC
DocProject/Help/*.hhc
DocProject/Help/*.hhk
DocProject/Help/*.hhp
DocProject/Help/Html2
DocProject/Help/html
# Visual Studio cache files
# files ending in .cache can be ignored
*.[Cc]ache
# but keep track of directories ending in .cache
!*.[Cc]ache/
# Others
ClientBin/
~$*
*~
*.dbmdl
*.dbproj.schemaview
*.pfx
*.publishsettings
node_modules/
orleans.codegen.cs
# Since there are multiple workflows, uncomment next line to ignore bower_components
# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
#bower_components/
# RIA/Silverlight projects
Generated_Code/
# Backup & report files from converting an old project file
# to a newer Visual Studio version. Backup files are not needed,
# because we have git ;-)
_UpgradeReport_Files/
Backup*/
UpgradeLog*.XML
UpgradeLog*.htm
# SQL Server files
*.mdf
*.ldf
# Business Intelligence projects
*.rdl.data
*.bim.layout
*.bim_*.settings
# Microsoft Fakes
FakesAssemblies/
# Visual Studio 6 build log
*.plg
# Visual Studio 6 workspace options file
*.opt
# Visual Studio LightSwitch build output
**/*.HTMLClient/GeneratedArtifacts
**/*.DesktopClient/GeneratedArtifacts
**/*.DesktopClient/ModelManifest.xml
**/*.Server/GeneratedArtifacts
**/*.Server/ModelManifest.xml
**/__pycache__/*
_Pvt_Extensions
/Cpp/.vscode
/Cpp/test.cpp
/Cpp/test.exe
/Cpp/lib/driver_header/spcm_win64_msvcpp_symbols.txt
/Cpp/doc
/Cpp/lib/spcm_win64_msvcpp_symbols.txt
/Cpp/out
/Cpp/build/
/Python/data
README.md
Python/*.ipynb
Python/*.xml
*.ipynb
Python/control.py
.vscode/settings.json
*/data/*
*.json
# Default ignored files
/shelf/
/workspace.xml
<?xml version="1.0" encoding="UTF-8"?>
<module type="PYTHON_MODULE" version="4">
<component name="NewModuleRootManager">
<content url="file://$MODULE_DIR$" />
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>
\ No newline at end of file
<component name="InspectionProjectProfileManager">
<profile version="1.0">
<option name="myName" value="Project Default" />
<inspection_tool class="PyPep8Inspection" enabled="true" level="WEAK WARNING" enabled_by_default="true">
<option name="ignoredErrors">
<list>
<option value="E265" />
<option value="E501" />
<option value="E231" />
</list>
</option>
</inspection_tool>
<inspection_tool class="PyPep8NamingInspection" enabled="true" level="WEAK WARNING" enabled_by_default="true">
<option name="ignoredErrors">
<list>
<option value="N802" />
<option value="N806" />
<option value="N803" />
</list>
</option>
</inspection_tool>
</profile>
</component>
\ No newline at end of file
<component name="InspectionProjectProfileManager">
<settings>
<option name="USE_PROJECT_PROFILE" value="false" />
<version value="1.0" />
</settings>
</component>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectRootManager" version="2" project-jdk-name="Python 3.9" project-jdk-type="Python SDK" />
</project>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/.idea/awg-control.iml" filepath="$PROJECT_DIR$/.idea/awg-control.iml" />
</modules>
</component>
</project>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$" vcs="Git" />
</component>
</project>
\ No newline at end of file
Comments_Adam.png

22.4 KiB

# CMakeList.txt : CMake project for Cpp, include source and define
# project specific logic here.
#
cmake_minimum_required (VERSION 3.20)
# respect <PACKAGE>_ROOT variables in
# Enable Hot Reload for MSVC compilers if supported.
if (POLICY CMP0141)
cmake_policy(SET CMP0141 NEW)
set(CMAKE_MSVC_DEBUG_INFORMATION_FORMAT "$<IF:$<AND:$<C_COMPILER_ID:MSVC>,$<CXX_COMPILER_ID:MSVC>>,$<$<CONFIG:Debug,RelWithDebInfo>:EditAndContinue>,$<$<CONFIG:Debug,RelWithDebInfo>:ProgramDatabase>>")
endif()
set(CMAKE_CXX_STANDARD 20)
# Non "standard" but common install prefixes
list(APPEND CMAKE_SYSTEM_PREFIX_PATH
# /usr/X11R6
# /usr/pkg
/opt/
)
project ("main")
# add libraries
add_library(wfmLib "")
add_library(AWGLib "")
add_library(baslerLib "")
add_library(imageProcLib "")
add_library(uniformLib "")
add_subdirectory(lib)
include_directories(lib/driver_header)
set(LIBS
wfmLib
AWGLib
baslerLib
imageProcLib
uniformLib
)
# executables
add_subdirectory(src)
{
"version": 3,
"configurePresets": [
{
"name": "windows-base",
"hidden": true,
"generator": "Ninja",
"binaryDir": "${sourceDir}/out/build/${presetName}",
"installDir": "${sourceDir}/out/install/${presetName}",
"cacheVariables": {
"CMAKE_C_COMPILER": "cl.exe",
"CMAKE_CXX_COMPILER": "cl.exe"
},
"condition": {
"type": "equals",
"lhs": "${hostSystemName}",
"rhs": "Windows"
}
},
{
"name": "x64-debug",
"displayName": "x64 Debug",
"inherits": "windows-base",
"architecture": {
"value": "x64",
"strategy": "external"
},
"cacheVariables": {
"CMAKE_BUILD_TYPE": "Debug"
}
},
{
"name": "x64-release",
"displayName": "x64 Release",
"inherits": "x64-debug",
"cacheVariables": {
"CMAKE_BUILD_TYPE": "Release"
}
},
{
"name": "x86-debug",
"displayName": "x86 Debug",
"inherits": "windows-base",
"architecture": {
"value": "x86",
"strategy": "external"
},
"cacheVariables": {
"CMAKE_BUILD_TYPE": "Debug"
}
},
{
"name": "x86-release",
"displayName": "x86 Release",
"inherits": "x86-debug",
"cacheVariables": {
"CMAKE_BUILD_TYPE": "Release"
}
},
{
"name": "linux-debug",
"displayName": "Linux Debug",
"generator": "Ninja",
"binaryDir": "${sourceDir}/out/build/${presetName}",
"installDir": "${sourceDir}/out/install/${presetName}",
"cacheVariables": {
"CMAKE_BUILD_TYPE": "Debug"
},
"condition": {
"type": "equals",
"lhs": "${hostSystemName}",
"rhs": "Linux"
},
"vendor": {
"microsoft.com/VisualStudioRemoteSettings/CMake/1.0": {
"sourceDir": "$env{HOME}/.vs/$ms{projectDirName}"
}
}
},
{
"name": "macos-debug",
"displayName": "macOS Debug",
"generator": "Ninja",
"binaryDir": "${sourceDir}/out/build/${presetName}",
"installDir": "${sourceDir}/out/install/${presetName}",
"cacheVariables": {
"CMAKE_BUILD_TYPE": "Debug"
},
"condition": {
"type": "equals",
"lhs": "${hostSystemName}",
"rhs": "Darwin"
},
"vendor": {
"microsoft.com/VisualStudioRemoteSettings/CMake/1.0": {
"sourceDir": "$env{HOME}/.vs/$ms{projectDirName}"
}
}
}
]
}
This diff is collapsed.
[connection]
cardIndex = 0
[output.general]
sampling_rate = 614.4e6
output_amplitude = 2500 # mV
[output.channel]
active_channels = [0]
stop_level = ["ZERO"] # ZERO, LOW, HIGH, HOLDLAST
diff_output_mode = [[]] # [[int, bool]]
double_output_mode = [[]] # [[int, bool]]
[BalserCam]
index = 0 # camera index, think 0 is default, needs testing
exposure = 1200 # ms
gain = 0.0 # not sure range
acquisition_mode = "Continuous" # not sure what's available, Continuous works
frame_rate = 10 # not sure range, preferrably use BaslerCam::setFrameRateMax()
[uniformization]
probeScanPath = "/home/user/Documents/.../probe-scan/" # absolute path
# polarizability = -1.24e-3 # kHz/uk H-polar tweezers, measured 8.8.23
polarizability = -5.6e-3 # kHz/uk V-polar tweezers, measured 8.8.23
mean_depth = 575 # uk, estimate of average depth, this affects the accuracy of correction
step_size = 50 # (0 - 2^15-1) arbitrary units, tune this for convergence
error_threshold = 0.003 # iteration termination threshold
max_loop = 50 # maximum number of iterations
num_imaging_avg = 10 # number of images to average over for power measurements
num_tweezer = 20 # number of tweezers to locate
add_subdirectory(devices)
add_subdirectory(external)
# find_package(Eigen3 3.4 REQUIRED)
target_sources(wfmLib
PRIVATE
waveform.cpp
PUBLIC
waveform.h
CSVhelper.hpp
)
# target_link_libraries(wfmLib
# Eigen3::Eigen
# )
# target_link_libraries(wfmLib helperLib)
target_sources(imageProcLib
PRIVATE
image_process.cpp
PUBLIC
image_process.h
)
find_package(OpenCV REQUIRED)
include_directories(${OpenCV_INCLUDE_DIRS})
target_link_libraries(imageProcLib ${OpenCV_LIBS})
target_sources(uniformLib
PRIVATE
uniformization.cpp
PUBLIC
uniformization.h
)
set(UNILIBS
wfmLib
AWGLib
baslerLib
imageProcLib
)
target_link_libraries(uniformLib ${UNILIBS})
#pragma once
#include <string>
#include <iostream>
#include <iterator>
#include <fstream>
#include <sstream>
#include <vector>
#include <string>
class CSVRow {
private:
std::string m_line;
std::vector<int> m_data;
public:
std::string_view operator[](std::size_t index) const {
return std::string_view(
&m_line[m_data[index] + 1],
m_data[index + 1] - (m_data[index] + 1)
);
}
std::size_t size() const {
return m_data.size() - 1;
}
void readNextRow(std::istream& str) {
std::getline(str, m_line);
m_data.clear();
m_data.emplace_back(-1);
std::string::size_type pos = 0;
while(
(pos = m_line.find(',', pos)) !=
std::string::npos
) {
m_data.emplace_back(pos);
++pos;
}
pos = m_line.size();
m_data.emplace_back(pos);
}
};
std::istream& operator>>(std::istream& str, CSVRow& data) {
data.readNextRow(str);
return str;
}
class CSVIterator {
private:
std::istream* m_str;
CSVRow m_row;
public:
typedef std::input_iterator_tag iterator_category;
typedef CSVRow value_type;
typedef std::size_t difference_type;
typedef CSVRow* pointer;
typedef CSVRow& reference;
CSVIterator(std::istream& str) :m_str(str.good()?&str:nullptr) {++(*this);}
CSVIterator() :m_str(nullptr) {}
// Pre Increment
CSVIterator& operator++() {
if (m_str) {
if (!((*m_str) >> m_row)) { m_str = nullptr; }
}
return *this;
}
// Post increment
CSVIterator operator++(int) {CSVIterator tmp(*this);++(*this);return tmp;}
CSVRow const& operator*() const {return m_row;}
CSVRow const* operator->() const {return &m_row;}
bool operator==(CSVIterator const& rhs) {
return ((this == &rhs)
|| ((this->m_str == nullptr)
&& (rhs.m_str == nullptr)));
}
bool operator!=(CSVIterator const& rhs) {return !((*this) == rhs);}
};
class CSVRange {
std::istream& stream;
public:
CSVRange(std::istream& str) : stream(str) {}
CSVIterator begin() const {return CSVIterator{stream};}
CSVIterator end() const {return CSVIterator{};}
};
\ No newline at end of file
#pragma once
class ConfigReader {
public:
int dum = 0;
};
\ No newline at end of file
#include "AWG.h"
#include <iostream>
#include <cmath>
#include <vector>
AWG::AWG() noexcept {
this->pCardHandle = nullptr;
this->cardIdx = -1;
this->serialNumber = -1;
this->instMemSize = -1;
this->bytesPerSample = -1;
this->maxSampleRate = -1;
}
AWG::~AWG() {
if (this->isOpen()) { this->close(); }
this->pCardHandle = nullptr;
return;
}
void AWG::checkError() {
if (this->pCardHandle == nullptr) { return; }
char errorMsg[ERRORTEXTLEN];
if (
spcm_dwGetErrorInfo_i32(this->pCardHandle, NULL, NULL, errorMsg)
!= ERR_OK
) {
//std::cout << "AWG error" << std::string(errorMsg)
// << "\ncard closed\n";
std::cout << std::string(errorMsg) << std::endl;
this->close();
throw CardException(errorMsg);
}
}
void AWG::open(int openIndex) {
if (this->isOpen()) {
std::cout << "card already opened" << std::endl;
return;
}
auto openMsg = "/dev/spcm" + std::to_string(openIndex);
this->pCardHandle = spcm_hOpen(openMsg.c_str());
if (pCardHandle == nullptr) {
std::cout << "card open failed" << std::endl;
return;
}
this->cardIdx = openIndex;
spcm_dwGetParam_i32(
this->pCardHandle,
SPC_PCISERIALNO,
&this->serialNumber
);
spcm_dwGetParam_i64(
this->pCardHandle,
SPC_PCISAMPLERATE,
&this->maxSampleRate
);
spcm_dwGetParam_i64(
this->pCardHandle,
SPC_PCIMEMSIZE,
&this->instMemSize
);
spcm_dwGetParam_i32(
this->pCardHandle,
SPC_MIINST_BYTESPERSAMPLE,
&this->bytesPerSample
);
this->checkError();
}
bool AWG::isOpen() {
if (this->pCardHandle == nullptr) { return false; }
return true;
this->checkError();
}
void AWG::close() {
if (!this->isOpen()) { return; }
spcm_vClose(this->pCardHandle);
this->pCardHandle = nullptr;
}
void AWG::reset() {
if (!this->isOpen()) { return; }
spcm_dwSetParam_i32(
this->pCardHandle,
SPC_M2CMD,
M2CMD_CARD_RESET
);
this->checkError();
}
int AWG::getCardIdx() {
return this->cardIdx;
}
int AWG::getSerialNumber() {
return this->serialNumber;
}
int64 AWG::getInstMemSize() {
return this->instMemSize;
}
int AWG::getBytesPerSample() {
return this->bytesPerSample;
}
int64 AWG::getMaxSampleRate() {
return this->maxSampleRate;
}
void AWG::setSampleRate(int64 sampleRate) {
if (!this->isOpen()) { return; }
if (sampleRate < 0 or sampleRate > this->maxSampleRate) {
std::cout << sampleRate << "exceeds max sample rate" << std::endl;
return;
}
spcm_dwSetParam_i64(
this->pCardHandle,
SPC_SAMPLERATE,
sampleRate
);
}
int64 AWG::getSampleRate() {
if (!this->isOpen()) { return 0; }
int64 sr;
spcm_dwGetParam_i64(
this->pCardHandle,
SPC_SAMPLERATE,
&sr
);
this->checkError();
return sr;
}
void AWG::setActiveChannels(std::set<int> channels) {
if (!this->isOpen()) { return; }
int64 chMask = 0;
for (auto ch : channels) {
chMask = chMask | int64(pow(2,ch));
}
spcm_dwSetParam_i64(
this->pCardHandle,
SPC_CHENABLE,
chMask
);
this->checkError();
this->activeChannels = channels;
}
void AWG::setChannelAmp(int ch, int amp) {
if (!this->isOpen()) { return; }
const auto regStep = SPC_AMP1 - SPC_AMP0;
spcm_dwSetParam_i32(
this->pCardHandle,
SPC_AMP0 + ch * regStep,
amp
);
this->checkError();
}
void AWG::setChannelStopLvl(int ch, CHANNEL_STOPLVL stopLvl) {
if (!this->isOpen()) { return; }
const auto regStep = SPC_CH1_STOPLEVEL - SPC_CH0_STOPLEVEL;
spcm_dwSetParam_i32(
this->pCardHandle,
SPC_CH0_STOPLEVEL + ch * regStep,
int32(stopLvl)
);
this->checkError();
}
void AWG::toggleChannelOutput(int ch, bool enable) {
if (!this->isOpen()) { return; }
if (ch < 0 or ch > 3) {
std::cout << ch << "is not an allowed channel index"
<< std::endl;
return;
}
const auto regStep = SPC_ENABLEOUT1 - SPC_ENABLEOUT0;
spcm_dwSetParam_i32(
this->pCardHandle,
SPC_ENABLEOUT0 + ch * regStep,
enable
);
this->checkError();
}
void AWG::setChannel(int ch, int amp, CHANNEL_STOPLVL stopLvl, bool enable) {
this->setChannelAmp(ch, amp);
this->setChannelStopLvl(ch, stopLvl);
this->toggleChannelOutput(ch, enable);
}
int AWG::getChannelCount() {
if (!this->isOpen()) { return 0; }
int32 numCh;
spcm_dwGetParam_i32(
this->pCardHandle,
SPC_CHCOUNT,
&numCh
);
this->checkError();
return numCh;
}
std::set<int> AWG::getChannelActivated() {
return this->activeChannels;
}
void AWG::setChannelDiffMode(int chPair, bool enable) {
if (!this->isOpen()) { return; }
if (chPair != 0 && chPair != 1) {
std::cout << "unable to parse input chPair: "
<< chPair << std::endl;
return;
}
if (enable) {
if (chPair == 0 && this->activeChannels.count(1) > 0) {
// if (chPair == 0 && this->activeChannels.contains(1)) {
std::cout << "channel 1 must disabled for chPair=0"
"in differential output mode" << std::endl;
return;
}
if (chPair == 1 && this->activeChannels.count(3) > 0) {
// if (chPair == 1 && this->activeChannels.contains(3)) {
std::cout << "channel 3 must disabled for chPair=1"
"in differential output mode" << std::endl;
return;
}
}
const auto regStep = SPC_DIFF2 - SPC_DIFF0;
spcm_dwSetParam_i32(
this->pCardHandle,
SPC_DIFF0 + chPair * regStep,
enable
);
this->checkError();
}
void AWG::setChannelDoubleMode(int chPair, bool enable) {
if (!this->isOpen()) { return; }
if (chPair != 0 && chPair != 1) {
std::cout << "unable to parse input chPair: "
<< chPair << std::endl;
return;
}
if (enable) {
if (chPair == 0 && this->activeChannels.count(1) > 0) {
// if (chPair == 0 && this->activeChannels.contains(1)) {
std::cout << "channel 1 must disabled for chPair=0"
"in double output mode" << std::endl;
return;
}
if (chPair == 1 && this->activeChannels.count(3) > 0) {
// if (chPair == 1 && this->activeChannels.contains(3)) {
std::cout << "channel 3 must disabled for chPair=1"
"in double output mode" << std::endl;
return;
}
}
const auto regStep = SPC_DOUBLEOUT2 - SPC_DOUBLEOUT0;
spcm_dwSetParam_i32(
this->pCardHandle,
SPC_DOUBLEOUT0 + chPair * regStep,
enable
);
this->checkError();
}
void AWG::writeSetup() {
if (!this->isOpen()) { return; }
spcm_dwSetParam_i32(
this->pCardHandle,
SPC_M2CMD,
M2CMD_CARD_WRITESETUP
);
this->checkError();
}
void AWG::cardRun() {
if (!this->isOpen()) { return; }
spcm_dwSetParam_i32(
this->pCardHandle,
SPC_M2CMD,
M2CMD_CARD_START
);
this->checkError();
}
void AWG::cardStop() {
if (!this->isOpen()) { return; }
spcm_dwSetParam_i32(
this->pCardHandle,
SPC_M2CMD,
M2CMD_CARD_STOP
);
this->checkError();
}
void AWG::waitReady() {
if (!this->isOpen()) { return; }
spcm_dwSetParam_i32(
this->pCardHandle,
SPC_M2CMD,
M2CMD_CARD_WAITREADY
);
this->checkError();
}
void AWG::setTimeOut(int time) {
if (!this->isOpen()) { return; }
if (time < 0) {
std::cout << time << "is an invalid timeout time" << std::endl;
}
spcm_dwSetParam_i32(
this->pCardHandle,
SPC_TIMEOUT,
time
);
this->checkError();
}
int AWG::getTimeOut() {
if (!this->isOpen()) { return 0; }
int32 time;
spcm_dwGetParam_i32(
this->pCardHandle,
SPC_TIMEOUT,
&time
);
return time;
}
void AWG::printCardStatus() {
if (!this->isOpen()) { return; }
this->checkError();
int32 status;
spcm_dwGetParam_i32(
this->pCardHandle,
SPC_M2STATUS,
&status
);
if (STATUS_NAMES.count(status)) {
std::cout << "status code: " << status << ", " << STATUS_NAMES.at(status) << std::endl;
} else {
std::cout << "status code: " << status << ", see manual for details" << std::endl;
}
}
void AWG::toggleTrigger(bool enable) {
if (!this->isOpen()) { return; }
auto command = enable
? M2CMD_CARD_ENABLETRIGGER
: M2CMD_CARD_DISABLETRIGGER;
spcm_dwSetParam_i32(
this->pCardHandle,
SPC_M2CMD,
command
);
this->checkError();
}
void AWG::forceTrigger() {
if (!this->isOpen()) { return; }
spcm_dwSetParam_i32(
this->pCardHandle,
SPC_M2CMD,
M2CMD_CARD_FORCETRIGGER
);
this->checkError();
}
void AWG::waitTrigger() {
if (!this->isOpen()) { return; }
spcm_dwSetParam_i32(
this->pCardHandle,
SPC_M2CMD,
M2CMD_CARD_WAITTRIGGER
);
this->checkError();
}
void AWG::setTrigMaskOr(std::initializer_list<TRIGGER_MASK> trigMasks) {
if (!this->isOpen()) { return; }
auto mask = 0;
for (auto m : trigMasks) {
mask = mask | int32(m);
}
spcm_dwSetParam_i32(
this->pCardHandle,
SPC_TRIG_ORMASK,
mask
);
this->checkError();
}
void AWG::setTrigMaskOr(std::vector<TRIGGER_MASK> trigMasks) {
if (!this->isOpen()) { return; }
auto mask = 0;
for (auto m : trigMasks) {
mask = mask | int32(m);
}
spcm_dwSetParam_i32(
this->pCardHandle,
SPC_TRIG_ORMASK,
mask
);
this->checkError();
}
void AWG::setTrigMaskAnd(std::initializer_list<TRIGGER_MASK> trigMasks) {
if (!this->isOpen()) { return; }
int mask = 0;
for (auto m : trigMasks) {
mask = mask | int32(m);
}
spcm_dwSetParam_i32(
this->pCardHandle,
SPC_TRIG_ANDMASK,
mask
);
this->checkError();
}
void AWG::setTrigMaskAnd(std::vector<TRIGGER_MASK> trigMasks) {
if (!this->isOpen()) { return; }
int mask = 0;
for (auto m : trigMasks) {
mask = mask | int32(m);
}
spcm_dwSetParam_i32(
this->pCardHandle,
SPC_TRIG_ANDMASK,
mask
);
this->checkError();
}
void AWG::setTrigMode(int trigChannel, TRIGGER_MODE trigMode) {
if (!this->isOpen()) { return; }
if (trigChannel != 0 and trigChannel != 1) {
std::cout << "invalid trigger channel: "
<< trigChannel << std::endl;
return;
}
auto trigRegister = trigChannel
? SPC_TRIG_EXT1_MODE
: SPC_TRIG_EXT0_MODE;
spcm_dwSetParam_i32(
this->pCardHandle,
trigRegister,
int32(trigMode)
);
this->checkError();
}
void AWG::setTrigTerm(int term) {
if (!this->isOpen()) { return; }
if (term != 0) {
std::cout << "invalid trigger input termination setting: "
<< term << std::endl;
return;
}
spcm_dwSetParam_i32(
this->pCardHandle,
SPC_TRIG_TERM,
term
);
this->checkError();
}
int AWG::getTrigTerm() {
if (!this->isOpen()) { return -1; }
int32 term;
spcm_dwGetParam_i32(
this->pCardHandle,
SPC_TRIG_TERM,
&term
);
this->checkError();
return term;
}
void AWG::setTrigCoupling(int channel, int coupling) {
if (!this->isOpen()) { return; }
if (coupling != 0 and coupling != 1) {
std::cout << "invalid trigger coupling setting :" << coupling
<< std::endl;
return;
}
auto trigChannelReg = channel ?
SPC_TRIG_EXT1_ACDC : SPC_TRIG_EXT0_ACDC;
spcm_dwSetParam_i32(
this->pCardHandle,
trigChannelReg,
coupling
);
this->checkError();
}
int AWG::getTrigCoupling(int channel) {
if (!this->isOpen()) { return -1; }
auto trigChannelReg = channel ?
SPC_TRIG_EXT1_ACDC : SPC_TRIG_EXT0_ACDC;
int32 coupling;
spcm_dwGetParam_i32(
this->pCardHandle,
trigChannelReg,
&coupling
);
this->checkError();
return coupling;
}
void AWG::setTrigLvl(int channel, int level) {
if (!this->isOpen()) { return; }
if (level < -10000 or level > 10000) {
std::cout << "invalid trigger level: " << level << std::endl;
return;
}
auto trigChannelReg = channel ?
SPC_TRIG_EXT1_LEVEL0 : SPC_TRIG_EXT0_LEVEL0;
spcm_dwSetParam_i64(
this->pCardHandle,
trigChannelReg,
level
);
this->checkError();
}
int AWG::getTrigLvl(int channel) {
if (!this->isOpen()) { return 0; }
auto trigChannelReg = channel ?
SPC_TRIG_EXT1_LEVEL0 : SPC_TRIG_EXT0_LEVEL0;
int32 level;
spcm_dwGetParam_i32(
this->pCardHandle,
trigChannelReg,
&level
);
this->checkError();
return level;
}
void AWG::setTrigRearmLvl(int channel, int level) {
if (!this->isOpen()) { return; }
auto trigChannelReg = channel ?
SPC_TRIG_EXT1_LEVEL1 : SPC_TRIG_EXT0_LEVEL1;
spcm_dwSetParam_i64(
this->pCardHandle,
trigChannelReg,
level
);
this->checkError();
}
int64 AWG::getTrigRearmLvl(int channel) {
if (!this->isOpen()) { return 0; }
auto trigChannelReg = channel ?
SPC_TRIG_EXT1_LEVEL1 : SPC_TRIG_EXT0_LEVEL1;
int64 level;
spcm_dwGetParam_i64(
this->pCardHandle,
trigChannelReg,
&level
);
return level;
}
//void AWG::setReplayMode(REPLAY_MODE mode) {
// /**
// * set the data replay mode.
// *
// * a macro for sequence replay mode is setup in
// * initReplayModeSeq(), if you wish to use other modes, you must
// * consult the manual for mode specific settings.
// *
// * @param mode SINGLE, MULTI, GATE, SINGLERESTART, SEQUENCE,
// * FIFO_{SINGLE, MULTI, GATE}.
// *
// */
// if (!this->isOpen()) { return; }
// spcm_dwSetParam_i32(
// this->pCardHandle,
// SPC_CARDMODE,
// mode
// );
// this->checkError();
//}
//
//void AWG::setMemSize(int64 sampleSize) {
// /**
// * set memory size in samples in SINGLE, SINGLE_RESTART,
// * MULTI, and GATE mode.
// * Please consult the manual for # of channel dependent
// * minimum/maximum sample size considerations.
// *
// * @param sampleSize size of sample
// *
// */
// if (!this->isOpen()) { return; }
// if (sampleSize < 0 or sampleSize > 2e9) {
// std::cout << "invalid sampleSize: " << sampleSize << std::endl;
// return;
// }
// spcm_dwSetParam_i64(
// this->pCardHandle,
// SPC_MEMSIZE,
// sampleSize
// );
// this->checkError();
//}
//
//int64 AWG::getMemsize() {
// int64 ms;
// spcm_dwGetParam_i64(
// this->pCardHandle,
// SPC_MEMSIZE,
// &ms
// );
// this->checkError();
// return ms;
//}
//
//void AWG::setLoop(int nLoop) {
// /**
// * set number of replay loops in SINGLE, SINGLE_RESTART,
// * MULTI, and GATE mode.
// *
// * @param nLoop
// */
// if (!this->isOpen()) { return; }
// if (nLoop < 0) {
// std::cout << "invalid number of loop: " << nLoop << std::endl;
// return;
// }
// spcm_dwSetParam_i32(
// this->pCardHandle,
// SPC_LOOPS,
// nLoop
// );
//}
//
//int64 AWG::getLoop() {
// if (!this->isOpen()) { return -1; }
// int64 nl;
// spcm_dwGetParam_i64(
// this->pCardHandle,
// SPC_LOOPS,
// &nl
// );
// return nl;
//}
void AWG::initReplayModeSeq(int nSeg) {
if (!this->isOpen()) { return; }
if (nSeg % 2 != 0) {
std::cout << "invalid number of segments for SEQUENCE mode: "
<< nSeg << std::endl;
return;
}
spcm_dwSetParam_i32(
this->pCardHandle,
SPC_CARDMODE,
int32(REPLAY_MODE::SEQUENCE)
);
spcm_dwSetParam_i32(
this->pCardHandle,
SPC_SEQMODE_MAXSEGMENTS,
nSeg
);
spcm_dwSetParam_i32(
this->pCardHandle,
SPC_SEQMODE_STARTSTEP,
0
);
this->checkError();
}
void AWG::setSeqModeStep(
uint32 step,
uint64 segment,
uint64 nextStep,
uint64 nLoop,
SEQ_LOOPCONDITION condition
) {
if (!this->isOpen()) { return; }
int64 mask =
(uint64(condition) << 32)
| (nLoop << 32)
| (nextStep << 16)
| segment;
spcm_dwSetParam_i64(
this->pCardHandle,
SPC_SEQMODE_STEPMEM0 + step,
mask
);
}
void AWG::writeSeqModeSegment(
int segment,
void* pDataBuffer,
int size
) {
if (!this->isOpen()) { return; }
spcm_dwSetParam_i32(
this->pCardHandle,
SPC_SEQMODE_WRITESEGMENT,
segment
);
spcm_dwSetParam_i32(
this->pCardHandle,
SPC_SEQMODE_SEGMENTSIZE,
size
);
this->prepDataTransfer(pDataBuffer, size);
this->startDataTransfer();
this->checkError();
}
void AWG::prepDataTransfer(
void* dataBuffer,
uint64 bufferLen,
BUFFER_TYPE bufType,
TRANSFER_DIR dir,
uint32 notifySize,
uint64 brdMemOffs
) {
if (!this->isOpen()) { return; }
spcm_dwDefTransfer_i64(
this->pCardHandle,
int32(bufType),
int32(dir),
notifySize,
dataBuffer,
brdMemOffs,
bufferLen
);
this->checkError();
}
void AWG::startDataTransfer() {
if (!this->isOpen()) { return; }
spcm_dwSetParam_i32(
this->pCardHandle,
SPC_M2CMD,
M2CMD_DATA_STARTDMA
);
this->checkError();
}
void AWG::waitDataTransfer() {
if (!this->isOpen()) { return; }
spcm_dwSetParam_i32(
this->pCardHandle,
SPC_M2CMD,
M2CMD_DATA_WAITDMA
);
this->checkError();
}
void AWG::stopDataTransfer() {
if (!this->isOpen()) { return; }
spcm_dwSetParam_i32(
this->pCardHandle,
SPC_M2CMD,
M2CMD_DATA_STOPDMA
);
this->checkError();
}
void AWG::setClockMode(CLOCK_MODE cm) {
if (!this->isOpen()) { return; }
spcm_dwSetParam_i32(
this->pCardHandle,
SPC_CLOCKMODE,
int32(cm)
);
this->checkError();
}
int32 AWG::getClockMode() {
if (!this->isOpen()) { return -1; }
int32 cm;
spcm_dwGetParam_i32(
this->pCardHandle,
SPC_CLOCKMODE,
&cm
);
this->checkError();
return cm;
}
void AWG::setRefClkFreq(int64 frequency) {
if (!this->isOpen()) { return; }
spcm_dwSetParam_i64(
this->pCardHandle,
SPC_REFERENCECLOCK,
frequency
);
this->checkError();
}
void AWG::setClockOut(bool enable) {
if (!this->isOpen()) { return; }
spcm_dwSetParam_i32(
this->pCardHandle,
SPC_CLOCKOUT,
enable
);
this->checkError();
}
int64 AWG::getClockOutFreq() {
if (!this->isOpen()) { return -1; }
int64 freq;
spcm_dwGetParam_i64(
this->pCardHandle,
SPC_CLOCKOUTFREQUENCY,
&freq
);
this->checkError();
return freq;
}
#pragma once
#include "driver_header/dlltyp.h"
#include "driver_header/regs.h"
#include "driver_header/spcerr.h"
#include "driver_header/spcm_drv.h"
#include <string>
#include <set>
#include <map>
#include <vector>
/**
* @brief Class for handling AWG M4i.6622-x8.
* Manual can be found at
* https://spectrum-instrumentation.com/products/details/M4i6622-x8.php
*/
class AWG {
// collection of card status for printouts
const std::map<int, std::string> STATUS_NAMES = {
{M2STAT_CARD_TRIGGER, "card received trigger"},
{M2STAT_CARD_READY, "card ready"},
{M2STAT_DATA_BLOCKREADY, "data block ready"},
{M2STAT_DATA_END, "data transfer ended"},
{M2STAT_DATA_OVERRUN, "data transfer overrun"},
{M2STAT_DATA_ERROR, "data transfer error"},
};
private:
// ---------------------card information---------------------
drv_handle pCardHandle; // card handle for lib calls
int32 cardIdx; // card index
int32 serialNumber; // card serial number
int64 instMemSize; // card installed memory size
int32 bytesPerSample; // available number of bytes per sample
int64 maxSampleRate; // maximum sampling rate
// ---------------------setting information---------------------
std::set<int> activeChannels;
/**
* @brief throw error if detected.
*/
void checkError();
public:
/**
* @brief exception overload to retrieve error msg from AWG
*/
class CardException : std::exception {
private:
char* exceptionMsg;
public:
CardException(char* msg) : exceptionMsg(msg) {}
const char* what() const throw() { return exceptionMsg; }
};
/**
* @brief defines analog output state when idling
*/
enum class CHANNEL_STOPLVL : int32 {
ZERO = SPCM_STOPLVL_ZERO, ///< 0 mV
LOW = SPCM_STOPLVL_LOW, ///< -2500 mV
HIGH = SPCM_STOPLVL_HIGH, ///< +2500 mV
HOLDLAST = SPCM_STOPLVL_HOLDLAST, ///< last replaed sample amplitude
};
/**
* @brief defines card replay mode
*/
enum class REPLAY_MODE : int32 {
SINGLE = SPC_REP_STD_SINGLE, ///< data generation from memory with programmed loop number of times after each triger event
MULTI = SPC_REP_STD_MULTI, ///< data generation from memory after multiple trigger events
GATE = SPC_REP_STD_GATE, ///< data generation from memory using external gate signal
SINGLERESTART = SPC_REP_STD_SINGLERESTART, ///< data generation from memory once after each trigger event
SEQUENCE = SPC_REP_STD_SEQUENCE, ///< data generation from memory with a specially programmed memory sequence
FIFO_SINGLE = SPC_REP_FIFO_SINGLE, ///< continuous data generation after single trigger event, memory used as FIFO buffer
FIFO_MULTI = SPC_REP_FIFO_MULTI, ///< continuous data generation after multiple trigger events, memory used as FIFO buffer
FIFO_GATE = SPC_REP_FIFO_GATE, ///< continuous data geeneration using external gatesignal, memory used as FIFO buffer
};
enum class BUFFER_TYPE : int32 {
DATA = SPCM_BUF_DATA, ///< buffer is used to transfer standard sample data
ABA = SPCM_BUF_ABA, ///< buffer is used to readout ABA data
TIMESTAMP = SPCM_BUF_TIMESTAMP, ///< buffer is used to readout timestep info
};
enum class TRANSFER_DIR : int32 {
PCTOCARD = SPCM_DIR_PCTOCARD, ///< transfer from PC to card
CARDTOPC = SPCM_DIR_CARDTOPC, ///< transfer from card to PC
CARDTOGPU = SPCM_DIR_CARDTOGPU, ///< transfer from card to GPU
GPUTOCARD = SPCM_DIR_GPUTOCARD, ///< transfer from GPU to card
};
enum class CLOCK_MODE : int32 {
INTPLL = SPC_CM_INTPLL, ///< enables internal programmable high precision Quartz 1 for sample clock generation
EXTREFCLK = SPC_CM_EXTREFCLOCK, ///< enables internal PLL with external reference for sample clock generation
};
enum class TRIGGER_MASK : int32 {
NONE = SPC_TMASK_NONE, ///< no trigger source selected
SOFTWARE = SPC_TMASK_SOFTWARE, ///< enable software trigger, not applicable to and mask
EXT0 = SPC_TMASK_EXT0, ///< enable external trigger 0
EXT1 = SPC_TMASK_EXT1, ///< enable external trigger 1
};
enum class TRIGGER_MODE : int32 {
NONE = SPC_TM_NONE, ///< no trigger source selected
POS = SPC_TM_POS, ///< trigger detection on positive edge
NEG = SPC_TM_NEG, ///< trigger detection on negative edge
POS_REARM = SPC_TM_POS | SPC_TM_REARM, ///< trigger detection on positive edge, trigger is armed when trigger level 1 is crossed
NEG_REARM = SPC_TM_NEG | SPC_TM_REARM, ///< trigger detection on negative edge, trigger is armed when trigger level 1 is crossed
BOTH = SPC_TM_BOTH, ///< trigger detection on positive and negative edges
HIGH = SPC_TM_HIGH, ///< trigger detection on HIGH levels (above trigger level 0)
LOW = SPC_TM_LOW, ///< trigger detection on LOW levels (below trigger level 0)
WINENTER = SPC_TM_WINENTER, ///< window trigger for entering area between level 0 and level 1
WINLEAVE = SPC_TM_WINLEAVE, ///< window trigger for leaving area between level 0 and 1
INWIN = SPC_TM_INWIN, ///< window trigger for signal inside window between level 0 and level 1
OUTSIDEWIN = SPC_TM_OUTSIDEWIN, ///< window trigger for signal outside window between level 0 and level 1
};
enum class SEQ_LOOPCONDITION : int64 {
ALWAYS = SPCSEQ_ENDLOOPALWAYS, ///< unconditionally change to the next step, if defined loops for the current segment have been replayed
ONTRIG = SPCSEQ_ENDLOOPONTRIG, ///< conditionally change to the next step on trigger detection, after a defined number of loops have been played
END = SPCSEQ_END, ///< marks current step to be the last step in the sequence, card is stopped afterwards
};
// functions
AWG() noexcept;
~AWG();
// ---------------------basic card setting---------------------
/**
* @brief opens a connection to AWG by index.
*
* @param openIndex card index, 0 or 1
*/
void open(int openIndex);
/**
* @brief check if a connection to AWG exists.
*
* @return true or false
*/
bool isOpen();
/**
* @brief close the connection to AWG.
*
*/
void close();
/**
* @brief resets the AWG card, equivalent to a power reset.
*
*/
void reset();
/**
* @brief get card idx
*
* @return index
*/
int getCardIdx();
/**
* @brief get car serial number
*
* @return int
*/
int getSerialNumber();
/**
* @brief get installed memory size
*
* @return memory size
*/
int64 getInstMemSize();
/**
* @brief get sample byte length
*
* @return int
*/
int getBytesPerSample();
/**
* @brief get the maximum sampling rate
*
* @return maximum sampling rate
*/
int64 getMaxSampleRate();
/**
* @brief set the card sampling rate
*
* @param sampleRate value range: [0, getMaxSampleRate()]
*/
void setSampleRate(int64 sampleRate);
/**
* @brief get current sampling rate
*
* @return sampling rate
*/
int64 getSampleRate();
// ---------------------channel output control---------------------
/**
* @brief set channels for next run, resets last set.
*
* @param channels set of channel index (0-3)
*/
void setActiveChannels(std::set<int> channels);
/**
* @brief set channel amplitude.
*
* @param ch channel index
* @param amp amplitude (mV)
*/
void setChannelAmp(int ch, int amp);
/**
* @brief set channel stop level.
*
* @param ch channel index
* @param stopLvl options: ZERO,LOW,HIGH,HOLDLAST
*/
void setChannelStopLvl(int ch, CHANNEL_STOPLVL stopLvl);
/**
* @brief toggle channel output.
*
* @param ch channel index
* @param enable true or false
*/
void toggleChannelOutput(int ch, bool enable);
/**
* @brief channel macro set amplitude, stop level, and enables output.
*
* @param ch channel index
* @param amp amplitude (mV)
* @param stopLvl enum CHANNEL_STOPLVL: ZERO, LOW, HIGH, HOLDLAST
* @param enable enable/disable channel output
*/
void setChannel(int ch, int amp, CHANNEL_STOPLVL stopLvl, bool enable);
/**
* @brief get number of channels available on card
*
* @return number of available channels
*/
int getChannelCount();
/**
* @brief get currently activated channels
*
* @return set of activated channels
*/
std::set<int> getChannelActivated();
/**
* @brief set channel 0(2) and channel 1(3) to differential output mode.
*
* @param chPair 0 for channel 0,1, 1 for channel 2,3
* @param enable true or false
*/
void setChannelDiffMode(int chPair, bool enable);
/**
* @brief set channel 0(2) and channel 1(3) to differential output mode.
*
* @param chPair 0 for channel 0,1, 1 for channel 2,3
* @param enable true or false
*/
void setChannelDoubleMode(int chPair, bool enable);
// ---------------------card status control---------------------
/**
* @brief write current setup to card without starting hardware,
* some settings may not be changed while card is running.
*
*/
void writeSetup();
/**
* @brief start the card with all selected settings.
*/
void cardRun();
/**
* @brief stop the card, no effect if not running.
*/
void cardStop();
/**
* @brief wait until card finished current output run.
* TODO: check if this blocks.
*/
void waitReady();
/**
* @brief set a timeout time in ms, 0 to disable.
*
* @param time timeout (ms)
*/
void setTimeOut(int time); // ms
/**
* @brief get current timeout time
*
* @return timeout (ms)
*/
int getTimeOut();
/**
* @brief print current card status
*/
void printCardStatus();
// ---------------------card trigger control---------------------
/**
* @brief toggle the trigger detection.
*
* @param enable
*/
void toggleTrigger(bool enable);
/**
* @brief send a software trigger equivalent to a physical trigger event.
*/
void forceTrigger();
/**
* @brief wait until trigger event.
* TODO: check if this blocks.
*/
void waitTrigger();
/**
* @brief program the OR trigger mask.
*
* @param trigMasks 1 or more enum TRIGGER_MASK
*/
void setTrigMaskOr(std::initializer_list<TRIGGER_MASK> trigMasks);
/**
* @brief program the OR trigger mask.
*
* @param trigMasks vector of 1 or more enum TRIGGER_MASK
*/
void setTrigMaskOr(std::vector<TRIGGER_MASK> trigMasks);
/**
* @brief program the AND trigger mask.
*
* @param trigMasks 1 or more enum TRIGGER_MASK
*/
void setTrigMaskAnd(std::initializer_list<TRIGGER_MASK> trigMasks);
/**
* @brief program the AND trigger mask.
*
* @param trigMasks vector of 1 or more enum TRIGGER_MASK
*/
void setTrigMaskAnd(std::vector<TRIGGER_MASK> trigMasks);
/**
* @brief set the trigger mode of trigger channel.
*
* @param trigChannel 0 or 1 (labeled EXT0 and EXT1 on board)
* @param trigMode enum TRIGGER_MODE
*/
void setTrigMode(int trigChannel, TRIGGER_MODE trigMode);
/**
* @brief set the trigger input termination.
*
* @param term 0 (high impedance), 1 (50 Ohm).
*/
void setTrigTerm(int term);
/**
* @brief get the trigger input termination
*
* @return 0 (high impedance), 1 (50 Ohm)
*/
int getTrigTerm();
/**
* @brief set trigger channel's coupling to DC or AC.
*
* @param channel trigger channel index
* @param coupling 0 (DC), 1 (AC)
*/
void setTrigCoupling(int channel, int coupling);
/**
* @brief get trigger channel's coupling mode
*
* @param channel trigger channel index
* @return coupling mode, 0 (DC), 1 (AC)
*/
int getTrigCoupling(int channel);
/**
* @brief set trigger level.
*
* @param channel trigger channel index
* @param level -10000mV to +10000mV
*/
void setTrigLvl(int channel, int level);
/**
* @brief Get trigger level
*
* @param channel trigger channel index
* @return trigger level (mV)
*/
int getTrigLvl(int channel);
/**
* @brief set trigger channel rearm level.
*
* @param channel trigger channel index
* @param level -10000mV to +10000mV
*/
void setTrigRearmLvl(int channel, int level);
/**
* @brief get trigger channel rearm level
*
* @param channel trigger channel index
* @return rearm level (mV)
*/
int64 getTrigRearmLvl(int channel);
// ---------------------replay mode control---------------------
//void setReplayMode(REPLAY_MODE mode);
//void setMemSize(int64 sampleSize);
//int64 getMemsize();
//void setLoop(int nLoop);
//int64 getLoop();
/**
* @brief initialize sequence replay mode.
*
* @param nSeg number of segments memory is divided into
*/
void initReplayModeSeq(int nSeg);
/**
* @brief configure a step in sequence replay mode.
*
* @param step step to configure
* @param segment memory segment step is associated with
* @param nextStep index of next step after end loop condition is met
* @param nLoop number of loop the memory segment is replayed
* @param condition end loop condition, enum SEQ_LOOPCONDITION
*/
void setSeqModeStep(
uint32 step,
uint64 segment,
uint64 nextStep,
uint64 nLoop,
SEQ_LOOPCONDITION condition
);
/**
* @brief write buffered data into a memory segment in sequence replay mode.
*
* @param segment memory segment to write to
* @param pDataBuffer pointer to data memory, must be page aligned
* @param size size of data buffer in number of samples
*/
void writeSeqModeSegment(
int segment,
void* pDataBuffer,
int size
);
// ---------------------data transfer---------------------
/**
* @brief prepares the board for data transfer.
*
* @param dataBuffer pointer to the data buffer
* @param bufferLen length of data buffer, bytes
* @param bufType buffer type, use only DATA for replay
* @param dir direction of data transfer
* @param notifySize number of bytes after which an event is sent
* @param brdMemOffs offset for transfer in board memory
*/
void prepDataTransfer(
void* dataBuffer,
uint64 bufferLen,
BUFFER_TYPE bufType = BUFFER_TYPE::DATA,
TRANSFER_DIR dir = TRANSFER_DIR::PCTOCARD,
uint32 notifySize = 0,
uint64 brdMemOffs = 0
);
/**
* @brief starts data transfer for a defined buffer.
*/
void startDataTransfer();
/**
* @brief wait for data transfer to complete, blocks;
* timeout is considered.
*/
void waitDataTransfer();
/**
* @brief stops a running data transfer.
*/
void stopDataTransfer();
// ---------------------clock control---------------------
/**
* @brief set the clock mode.
*
* @param cm enum CLOCK_MODE
*/
void setClockMode(CLOCK_MODE cm);
/**
* @brief get clock mode
* @return clock mode, check enum CLOCK_MODE
*/
int32 getClockMode();
/**
* @brief if using EXTREFCLK mode, set the external clock frequency.
*
* @param frequency Hz
*/
void setRefClkFreq(int64 frequency);
/**
* @brief enable/disable clock output.
*
* @param enable true/false
*/
void setClockOut(bool enable);
/**
* @brief Read out frequency of internally synthesized clock.
*
* @return frequency (Hz)
*/
int64 getClockOutFreq();
};
target_sources(AWGLib
PRIVATE
AWG.cpp
PUBLIC
AWG.h
)
add_library(driverLib SHARED IMPORTED)
set_target_properties(driverLib PROPERTIES
IMPORTED_LOCATION "/usr/lib/x86_64-linux-gnu/libspcm_linux.so"
INTERFACE_INCLUDE_DIRECTORIES "${CMAKE_CURRENT_LIST_DIR}/driver_header"
)
# set_target_properties(driverLib PROPERTIES
# IMPORTED_LOCATION "${CMAKE_CURRENT_LIST_DIR}/driver_header/spcm_win64_msvcpp.lib"
# INTERFACE_INCLUDE_DIRECTORIES "${CMAKE_CURRENT_LIST_DIR}/driver_header"
# )
target_link_libraries(AWGLib driverLib)
target_sources(baslerLib
PRIVATE
basler.cpp
PUBLIC
basler.h
)
find_package(pylon 7.4.0 REQUIRED)
target_link_libraries(baslerLib PUBLIC pylon::pylon)