diff --git a/Cpp/CMakeLists.txt b/Cpp/CMakeLists.txt index 4de2e10c50b8e05b4ff127016b85077d3313934d..1636af2e7fcdd05d8afaf00cda7df63a20978bf7 100644 --- a/Cpp/CMakeLists.txt +++ b/Cpp/CMakeLists.txt @@ -4,10 +4,10 @@ cmake_minimum_required (VERSION 3.20) # 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() +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) diff --git a/Cpp/lib/AWG.cpp b/Cpp/lib/AWG.cpp index 2e9803431650ba0f399dc0c61c441949bbd8b8b3..44c76b78e1caffef24d9112e896207e4ed34bfbe 100644 --- a/Cpp/lib/AWG.cpp +++ b/Cpp/lib/AWG.cpp @@ -4,36 +4,32 @@ #include <vector> AWG::AWG() noexcept { - this->pCardHandle = nullptr; - this->cardIdx = -1; - this->serialNumber = -1; - this->instMemSize = -1; - this->bytesPerSample = -1; - this->maxSampleRate = -1; + 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; + if (this->isOpen()) { this->close(); } + this->pCardHandle = nullptr; + return; } void AWG::checkError() { - /** - * throw error if detected. - * - */ - 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"; - this->close(); - throw CardException(errorMsg); - } + 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"; + this->close(); + throw CardException(errorMsg); + } } //void* AWG::getPageAlignedMem(uint64 memSize) { @@ -71,469 +67,364 @@ void AWG::checkError() { //} // void AWG::open(int openIndex) { - /** - * opens a connection to AWG by index. - * - * @param openIndex card index, 0 or 1 - */ - 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(); + 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() { - /** - * check if a connection to AWG exists. - * - * @return true or false - */ - if (this->pCardHandle == nullptr) { return false; } - return true; - this->checkError(); + if (this->pCardHandle == nullptr) { return false; } + return true; + this->checkError(); } void AWG::close() { - /** - * close the connection to AWG. - * - */ - if (!this->isOpen()) { return; } - spcm_vClose(this->pCardHandle); - this->pCardHandle = nullptr; + if (!this->isOpen()) { return; } + spcm_vClose(this->pCardHandle); + this->pCardHandle = nullptr; } void AWG::reset() { - /** - * resets the AWG card, equivalent to a power reset. - * - */ - if (!this->isOpen()) { return; } - spcm_dwSetParam_i32( - this->pCardHandle, - SPC_M2CMD, - M2CMD_CARD_RESET - ); - this->checkError(); + if (!this->isOpen()) { return; } + spcm_dwSetParam_i32( + this->pCardHandle, + SPC_M2CMD, + M2CMD_CARD_RESET + ); + this->checkError(); } int AWG::getCardIdx() { - return this->cardIdx; + return this->cardIdx; } int AWG::getSerialNumber() { - return this->serialNumber; + return this->serialNumber; } int64 AWG::getInstMemSize() { - return this->instMemSize; + return this->instMemSize; } int AWG::getBytesPerSample() { - return this->bytesPerSample; + return this->bytesPerSample; } int64 AWG::getMaxSampleRate() { - return this->maxSampleRate; + 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 - ); + 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; + 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) { - /** - * activate channels for next run, resets last set. - * - * @param channels vector of channel index (0-3) - */ - 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; + 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) { - /** - * set channel amplitude. - * - * @param ch channel index - * @param amp amplitude (mV) - */ - if (!this->isOpen()) { return; } - const auto regStep = SPC_AMP1 - SPC_AMP0; - spcm_dwSetParam_i32( - this->pCardHandle, - SPC_AMP0 + ch * regStep, - amp - ); - this->checkError(); + 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) { - /** - * set channel stop level. - * - * @param ch channel index - * @param stopLvl options: ZERO,LOW,HIGH,HOLDLAST - */ - 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(); + 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) { - /** - * toggle channel output. - * - * @param ch channel index - * @param enable true or false - */ - 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(); + 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) { - /** - * channel macro set amplitude, stop level, and enables output. - * - * @param ch channel index - * @param amp amplitude (mV) - * @param stopLvl options: ZERO, LOW, HIGH, HOLDLAST - */ - this->setChannelAmp(ch, amp); - this->setChannelStopLvl(ch, stopLvl); - this->toggleChannelOutput(ch, 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; + 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; + return this->activeChannels; } void AWG::setChannelDiffMode(int chPair, bool enable) { - /** - * 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 - */ - 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.contains(1)) { - std::cout << "channel 1 must disabled for chPair=0" - "in differential output mode" << std::endl; - return; - } - 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(); + 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.contains(1)) { + std::cout << "channel 1 must disabled for chPair=0" + "in differential output mode" << std::endl; + return; + } + 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) { - /** - * 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 - */ - 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.contains(1)) { - std::cout << "channel 1 must disabled for chPair=0" - "in double output mode" << std::endl; - return; - } - 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(); + 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.contains(1)) { + std::cout << "channel 1 must disabled for chPair=0" + "in double output mode" << std::endl; + return; + } + 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() { - /** - * write current setup to card without starting hardware, - * some settings may not be changed while card is running. - * - */ - if (!this->isOpen()) { return; } - spcm_dwSetParam_i32( - this->pCardHandle, - SPC_M2CMD, - M2CMD_CARD_WRITESETUP - ); - this->checkError(); + if (!this->isOpen()) { return; } + spcm_dwSetParam_i32( + this->pCardHandle, + SPC_M2CMD, + M2CMD_CARD_WRITESETUP + ); + this->checkError(); } void AWG::cardRun() { - /** - * starts the card with all selected settings. - * - */ - if (!this->isOpen()) { return; } - spcm_dwSetParam_i32( - this->pCardHandle, - SPC_M2CMD, - M2CMD_CARD_START - ); - this->checkError(); + if (!this->isOpen()) { return; } + spcm_dwSetParam_i32( + this->pCardHandle, + SPC_M2CMD, + M2CMD_CARD_START + ); + this->checkError(); } void AWG::cardStop() { - /** - * stops the card, no effect if not running. - * - */ - if (!this->isOpen()) { return; } - spcm_dwSetParam_i32( - this->pCardHandle, - SPC_M2CMD, - M2CMD_CARD_STOP - ); - this->checkError(); + if (!this->isOpen()) { return; } + spcm_dwSetParam_i32( + this->pCardHandle, + SPC_M2CMD, + M2CMD_CARD_STOP + ); + this->checkError(); } void AWG::waitReady() { - /** - * wait until card finished current output run. - * TODO: check if this blocks. - */ - if (!this->isOpen()) { return; } - spcm_dwSetParam_i32( - this->pCardHandle, - SPC_M2CMD, - M2CMD_CARD_WAITREADY - ); - this->checkError(); + if (!this->isOpen()) { return; } + spcm_dwSetParam_i32( + this->pCardHandle, + SPC_M2CMD, + M2CMD_CARD_WAITREADY + ); + this->checkError(); } void AWG::setTimeOut(int time) { - /** - * set a timeout time in ms, 0 to disable. - * - * @param 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(); + 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; + if (!this->isOpen()) { return 0; } + int32 time; + spcm_dwGetParam_i32( + this->pCardHandle, + SPC_TIMEOUT, + &time + ); + return time; } void AWG::printCardStatus() { - if (!this->isOpen()) { return; } - int32 status; - spcm_dwGetParam_i32( - this->pCardHandle, - SPC_M2STATUS, - &status - ); - std::cout << STATUS_NAMES.at(status) << std::endl; + if (!this->isOpen()) { return; } + int32 status; + spcm_dwGetParam_i32( + this->pCardHandle, + SPC_M2STATUS, + &status + ); + std::cout << STATUS_NAMES.at(status) << std::endl; } void AWG::toggleTrigger(bool enable) { - /** - * toggle the trigger detection. - * - * @param enable - */ - if (!this->isOpen()) { return; } - auto command = enable - ? M2CMD_CARD_ENABLETRIGGER - : M2CMD_CARD_DISABLETRIGGER; - spcm_dwSetParam_i32( - this->pCardHandle, - SPC_M2CMD, - command - ); - this->checkError(); + 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() { - /** - * sends a software trigger, equivalent to an actual trigger. - * - */ - if (!this->isOpen()) { return; } - spcm_dwSetParam_i32( - this->pCardHandle, - SPC_M2CMD, - M2CMD_CARD_FORCETRIGGER - ); - this->checkError(); + if (!this->isOpen()) { return; } + spcm_dwSetParam_i32( + this->pCardHandle, + SPC_M2CMD, + M2CMD_CARD_FORCETRIGGER + ); + this->checkError(); } void AWG::waitTrigger() { - /** - * wait until trigger event. - * TODO: check if this blocks. - */ - if (!this->isOpen()) { return; } - spcm_dwSetParam_i32( - this->pCardHandle, - SPC_M2CMD, - M2CMD_CARD_WAITTRIGGER - ); - this->checkError(); + 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) { - /** - * program the OR trigger mask. - * - * @param trigMasks 1 or more TRIGGER_MASK - */ - 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(); + 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) { - /** - * program the OR trigger mask. - * - * @param trigMasks 1 or more TRIGGER_MASK - */ if (!this->isOpen()) { return; } auto mask = 0; for (auto m : trigMasks) { @@ -548,202 +439,164 @@ void AWG::setTrigMaskOr(std::vector<TRIGGER_MASK> trigMasks) { } void AWG::setTrigMaskAnd(std::initializer_list<TRIGGER_MASK> trigMasks) { - /** - * program the AND trigger mask. - * - * @param trigMasks 1 or more TRIGGER_MASK - */ - 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(); + 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) { - /** - * program the AND trigger mask. - * - * @param trigMasks 1 or more TRIGGER_MASK - */ - 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(); + 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) { - /** - * sets the trigger mode of trigger channel. - * - * @param trigChannel 0 or 1 (labeled EXT0 and EXT1 on board) - * @param trigMode see TRIGGER_MODE for options - */ - 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(); + 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) { - /** - * sets the trigger input termination. - * - * \param term 0 for high impedance, 1 for 50 Ohm. - */ - - 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(); + + 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; + 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) { - /** - * sets trigger coupling to DC or AC. - * - * @param coupling 1 for AC, 0 for DC - */ - 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(); + 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; + 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) { - /** - * set trigger level. - * - * @param channel trigger channel - * @param level -10000mV to 10000mV - */ - 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(); + 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; + 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) { - /** - * sets rearm trigger level. - * - * @param channel trigger channel - * @param level -10000mV to +10000mV - */ - if (!this->isOpen()) { return; } - auto trigChannelReg = channel ? - SPC_TRIG_EXT1_LEVEL1 : SPC_TRIG_EXT0_LEVEL1; - spcm_dwSetParam_i64( - this->pCardHandle, - trigChannelReg, - level - ); - this->checkError(); + 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; + 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) { @@ -832,233 +685,170 @@ int64 AWG::getTrigRearmLvl(int channel) { //} void AWG::initReplayModeSeq(int nSeg) { - /** - * initialize sequence replay mode. - * - * @param nSeg number of segments memory is divided into - */ - 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(); + 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) { - /** - * 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 condition end loop 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 - ); + 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( - void* pDataBuffer, - int size, - int segment) { - /** - * write buffered data into a memory segment in sequence replay mode. - * - * @param pDataBuffer pointer to data memory, must be page aligned - * @param size size of data buffer in number of samples - * @param segment memory segment to write to - */ - 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* pDataBuffer, + int size, + int segment) { + 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 + void* dataBuffer, + uint64 bufferLen, + BUFFER_TYPE bufType, + TRANSFER_DIR dir, + uint32 notifySize, + uint64 brdMemOffs ) { - /** - * 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 - */ - if (!this->isOpen()) { return; } - spcm_dwDefTransfer_i64( - this->pCardHandle, - int32(bufType), - int32(dir), - notifySize, - dataBuffer, - brdMemOffs, - bufferLen - ); - this->checkError(); + if (!this->isOpen()) { return; } + spcm_dwDefTransfer_i64( + this->pCardHandle, + int32(bufType), + int32(dir), + notifySize, + dataBuffer, + brdMemOffs, + bufferLen + ); + this->checkError(); } void AWG::startDataTransfer() { - /** - * starts data transfer for a defined buffer. - * - */ - if (!this->isOpen()) { return; } - spcm_dwSetParam_i32( - this->pCardHandle, - SPC_M2CMD, - M2CMD_DATA_STARTDMA - ); - this->checkError(); + if (!this->isOpen()) { return; } + spcm_dwSetParam_i32( + this->pCardHandle, + SPC_M2CMD, + M2CMD_DATA_STARTDMA + ); + this->checkError(); } void AWG::waitDataTransfer() { - /** - * wait for data transfer to complete, blocks, - * timeout is considered. - * - */ - if (!this->isOpen()) { return; } - spcm_dwSetParam_i32( - this->pCardHandle, - SPC_M2CMD, - M2CMD_DATA_WAITDMA - ); - this->checkError(); + if (!this->isOpen()) { return; } + spcm_dwSetParam_i32( + this->pCardHandle, + SPC_M2CMD, + M2CMD_DATA_WAITDMA + ); + this->checkError(); } void AWG::stopDataTransfer() { - /** - * stops a running data transfer. - * - */ - if (!this->isOpen()) { return; } - spcm_dwSetParam_i32( - this->pCardHandle, - SPC_M2CMD, - M2CMD_DATA_STOPDMA - ); - this->checkError(); + if (!this->isOpen()) { return; } + spcm_dwSetParam_i32( + this->pCardHandle, + SPC_M2CMD, + M2CMD_DATA_STOPDMA + ); + this->checkError(); } void AWG::setClockMode(CLOCK_MODE cm) { - /** - * set the clock mode. - * - * @param cm INTPLL or EXTREFCLK - */ - if (!this->isOpen()) { return; } - spcm_dwSetParam_i32( - this->pCardHandle, - SPC_CLOCKMODE, - int32(cm) - ); - this->checkError(); + 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; + 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 using EXTREFCLK mode, set the external clock frequency. - * - * @param frequency Hz - */ - if (!this->isOpen()) { return; } - spcm_dwSetParam_i64( - this->pCardHandle, - SPC_REFERENCECLOCK, - frequency - ); - this->checkError(); + if (!this->isOpen()) { return; } + spcm_dwSetParam_i64( + this->pCardHandle, + SPC_REFERENCECLOCK, + frequency + ); + this->checkError(); } void AWG::setClockOut(bool enable) { - /** - * enable/disable clock output. - * - * @param enable true/false - */ - if (!this->isOpen()) { return; } - spcm_dwSetParam_i32( - this->pCardHandle, - SPC_CLOCKOUT, - enable - ); - this->checkError(); + if (!this->isOpen()) { return; } + spcm_dwSetParam_i32( + this->pCardHandle, + SPC_CLOCKOUT, + enable + ); + this->checkError(); } int64 AWG::getClockOutFreq() { - /** - * Read out frequency of internally synthesized clock. - * - * @return frequency (Hz) - */ - if (!this->isOpen()) { return -1; } - int64 freq; - spcm_dwGetParam_i64( - this->pCardHandle, - SPC_CLOCKOUTFREQUENCY, - &freq - ); - this->checkError(); - return freq; + if (!this->isOpen()) { return -1; } + int64 freq; + spcm_dwGetParam_i64( + this->pCardHandle, + SPC_CLOCKOUTFREQUENCY, + &freq + ); + this->checkError(); + return freq; } diff --git a/Cpp/lib/AWG.h b/Cpp/lib/AWG.h index ee0a1e0b0f30bcf9f03408e4853b513088a03a8f..4a21a207d56ac3b04cdf929e3b89ae1bf0271677 100644 --- a/Cpp/lib/AWG.h +++ b/Cpp/lib/AWG.h @@ -9,199 +9,541 @@ #include <vector> class AWG { - /** - * Class for handling AWG M4i.6622-x8 . - * Manual can be found at - * https://spectrum-instrumentation.com/products/details/M4i6622-x8.php - */ - - // 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"}, - }; + /** + * Class for handling AWG M4i.6622-x8 . + * Manual can be found at + * https://spectrum-instrumentation.com/products/details/M4i6622-x8.php + */ + + // 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; - int32 cardIdx; - int32 serialNumber; - int64 instMemSize; - int32 bytesPerSample; - int64 maxSampleRate; - - // setting information - std::set<int> activeChannels; - void checkError(); + // ---------------------card information--------------------- + drv_handle pCardHandle; + int32 cardIdx; + int32 serialNumber; + int64 instMemSize; + int32 bytesPerSample; + int64 maxSampleRate; + + // ---------------------setting information--------------------- + std::set<int> activeChannels; + + /** + * throw error if detected. + * + */ + void checkError(); public: - class CardException : std::exception { - private: - char* exceptionMsg; - public: - CardException(char* msg) : exceptionMsg(msg) {} - const char* what() const throw() { return exceptionMsg; } - }; + class CardException : std::exception { + private: + char* exceptionMsg; + public: + CardException(char* msg) : exceptionMsg(msg) {} + const char* what() const throw() { return exceptionMsg; } + }; // collection of special constants to help with setting options - enum class CHANNEL_STOPLVL : int32 { - ZERO = SPCM_STOPLVL_ZERO, - LOW = SPCM_STOPLVL_LOW, - HIGH = SPCM_STOPLVL_HIGH, - HOLDLAST = SPCM_STOPLVL_HOLDLAST, - }; - enum class REPLAY_MODE : int32 { - SINGLE = SPC_REP_STD_SINGLE, - MULTI = SPC_REP_STD_MULTI, - GATE = SPC_REP_STD_GATE, - SINGLERESTART = SPC_REP_STD_SINGLERESTART, - SEQUENCE = SPC_REP_STD_SEQUENCE, - FIFO_SINGLE = SPC_REP_FIFO_SINGLE, - FIFO_MULTI = SPC_REP_FIFO_MULTI, - FIFO_GATE = SPC_REP_FIFO_GATE, - }; - enum class BUFFER_TYPE : int32 { - DATA = SPCM_BUF_DATA, - ABA = SPCM_BUF_ABA, - TIMESTAMP = SPCM_BUF_TIMESTAMP, - }; - enum class TRANSFER_DIR : int32 { - PCTOCARD = SPCM_DIR_PCTOCARD, - CARDTOPC = SPCM_DIR_CARDTOPC, - CARDTOGPU = SPCM_DIR_CARDTOGPU, - GPUTOCARD = SPCM_DIR_GPUTOCARD, - }; - enum class CLOCK_MODE : int32 { - INTPLL = SPC_CM_INTPLL, - EXTREFCLK = SPC_CM_EXTREFCLOCK, - }; - enum class TRIGGER_MASK : int32 { - NONE = SPC_TMASK_NONE, - SOFTWARE = SPC_TMASK_SOFTWARE, - EXT0 = SPC_TMASK_EXT0, - EXT1 = SPC_TMASK_EXT1, - }; - enum class TRIGGER_MODE : int32 { - NONE = SPC_TM_NONE, - POS = SPC_TM_POS, - NEG = SPC_TM_NEG, - POS_REARM = SPC_TM_POS | SPC_TM_REARM, - NEG_REARM = SPC_TM_NEG | SPC_TM_REARM, - BOTH = SPC_TM_BOTH, - HIGH = SPC_TM_HIGH, - LOW = SPC_TM_LOW, - WINENTER = SPC_TM_WINENTER, - WINLEAVE = SPC_TM_WINLEAVE, - INWIN = SPC_TM_INWIN, - OUTSIDEWIN = SPC_TM_OUTSIDEWIN, - }; - enum class SEQ_LOOPCONDITION : int64 { - ALWAYS = SPCSEQ_ENDLOOPALWAYS, - ONTRIG = SPCSEQ_ENDLOOPONTRIG, - END = SPCSEQ_END, - }; - - // functions - AWG() noexcept; - ~AWG(); - - // basic card setting - void open(int openIndex); - bool isOpen(); - void close(); - void reset(); - int getCardIdx(); - int getSerialNumber(); - int64 getInstMemSize(); - int getBytesPerSample(); - int64 getMaxSampleRate(); - void setSampleRate(int64 sampleRate); - int64 getSampleRate(); - - // channel output control - void setActiveChannels(std::set<int> channels); - void setChannelAmp(int ch, int amp); - void setChannelStopLvl(int ch, CHANNEL_STOPLVL stopLvl); - void toggleChannelOutput(int ch, bool enable); - void setChannel(int ch, int amp, CHANNEL_STOPLVL stopLvl, bool enable); - int getChannelCount(); - std::set<int> getChannelActivated(); - void setChannelDiffMode(int chPair, bool enable); - void setChannelDoubleMode(int chPair, bool enable); - - // card status control - void writeSetup(); - void cardRun(); - void cardStop(); - void waitReady(); - void setTimeOut(int time); // ms - int getTimeOut(); - void printCardStatus(); - - // card trigger control - void toggleTrigger(bool enable); - void forceTrigger(); - void waitTrigger(); - void setTrigMaskOr(std::initializer_list<TRIGGER_MASK> trigMasks); - void setTrigMaskOr(std::vector<TRIGGER_MASK> trigMasks); - void setTrigMaskAnd(std::initializer_list<TRIGGER_MASK> trigMasks); - void setTrigMaskAnd(std::vector<TRIGGER_MASK> trigMasks); - void setTrigMode(int trigChannel, TRIGGER_MODE trigMode); - void setTrigTerm(int term); - int getTrigTerm(); - void setTrigCoupling(int channel, int coupling); - int getTrigCoupling(int channel); - void setTrigLvl(int channel, int level); - int getTrigLvl(int channel); - void setTrigRearmLvl(int channel, int level); - int64 getTrigRearmLvl(int channel); - - // replay mode control - //void setReplayMode(REPLAY_MODE mode); - //void setMemSize(int64 sampleSize); - //int64 getMemsize(); - //void setLoop(int nLoop); - //int64 getLoop(); - void initReplayModeSeq(int nSeg); - void setSeqModeStep( - uint32 step, - uint64 segment, - uint64 nextStep, - uint64 nLoop, - SEQ_LOOPCONDITION condition - ); - void writeSeqModeSegment( - void* pDataBuffer, - int size, - int segment - ); - - // data transfer - void prepDataTransfer( - void* dataBuffer, - uint64 bufferLen, - BUFFER_TYPE bufType = BUFFER_TYPE::DATA, - TRANSFER_DIR dir = TRANSFER_DIR::PCTOCARD, - uint32 notifySize = 0, - uint64 brdMemOffs = 0 - ); - void startDataTransfer(); - void waitDataTransfer(); - void stopDataTransfer(); - - // clock control - void setClockMode(CLOCK_MODE cm); - int32 getClockMode(); - void setRefClkFreq(int64 frequency); - void setClockOut(bool enable); - int64 getClockOutFreq(); + enum class CHANNEL_STOPLVL : int32 { + ZERO = SPCM_STOPLVL_ZERO, + LOW = SPCM_STOPLVL_LOW, + HIGH = SPCM_STOPLVL_HIGH, + HOLDLAST = SPCM_STOPLVL_HOLDLAST, + }; + enum class REPLAY_MODE : int32 { + SINGLE = SPC_REP_STD_SINGLE, + MULTI = SPC_REP_STD_MULTI, + GATE = SPC_REP_STD_GATE, + SINGLERESTART = SPC_REP_STD_SINGLERESTART, + SEQUENCE = SPC_REP_STD_SEQUENCE, + FIFO_SINGLE = SPC_REP_FIFO_SINGLE, + FIFO_MULTI = SPC_REP_FIFO_MULTI, + FIFO_GATE = SPC_REP_FIFO_GATE, + }; + enum class BUFFER_TYPE : int32 { + DATA = SPCM_BUF_DATA, + ABA = SPCM_BUF_ABA, + TIMESTAMP = SPCM_BUF_TIMESTAMP, + }; + enum class TRANSFER_DIR : int32 { + PCTOCARD = SPCM_DIR_PCTOCARD, + CARDTOPC = SPCM_DIR_CARDTOPC, + CARDTOGPU = SPCM_DIR_CARDTOGPU, + GPUTOCARD = SPCM_DIR_GPUTOCARD, + }; + enum class CLOCK_MODE : int32 { + INTPLL = SPC_CM_INTPLL, + EXTREFCLK = SPC_CM_EXTREFCLOCK, + }; + enum class TRIGGER_MASK : int32 { + NONE = SPC_TMASK_NONE, + SOFTWARE = SPC_TMASK_SOFTWARE, + EXT0 = SPC_TMASK_EXT0, + EXT1 = SPC_TMASK_EXT1, + }; + enum class TRIGGER_MODE : int32 { + NONE = SPC_TM_NONE, + POS = SPC_TM_POS, + NEG = SPC_TM_NEG, + POS_REARM = SPC_TM_POS | SPC_TM_REARM, + NEG_REARM = SPC_TM_NEG | SPC_TM_REARM, + BOTH = SPC_TM_BOTH, + HIGH = SPC_TM_HIGH, + LOW = SPC_TM_LOW, + WINENTER = SPC_TM_WINENTER, + WINLEAVE = SPC_TM_WINLEAVE, + INWIN = SPC_TM_INWIN, + OUTSIDEWIN = SPC_TM_OUTSIDEWIN, + }; + enum class SEQ_LOOPCONDITION : int64 { + ALWAYS = SPCSEQ_ENDLOOPALWAYS, + ONTRIG = SPCSEQ_ENDLOOPONTRIG, + END = SPCSEQ_END, + }; + + // 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 + */ + 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 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 pDataBuffer pointer to data memory, must be page aligned + * @param size size of data buffer in number of samples + * @param segment memory segment to write to + */ + void writeSeqModeSegment( + void* pDataBuffer, + int size, + int segment + ); + + // ---------------------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(); // memory management functions - //void* getPageAlignedMem(uint64 memSize); - //void freePageAlignedMem(void* pMem, uint64 memSize); + //void* getPageAlignedMem(uint64 memSize); + //void freePageAlignedMem(void* pMem, uint64 memSize); }; diff --git a/Cpp/lib/CMakeLists.txt b/Cpp/lib/CMakeLists.txt index 34a7876ffc9c76a544ef5e56dc581041f3fdadb5..f1c7210ee25bf8c0f9370b9053cfd1436bc32ece 100644 --- a/Cpp/lib/CMakeLists.txt +++ b/Cpp/lib/CMakeLists.txt @@ -1,11 +1,16 @@ +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 Eigen3::Eigen) # target_link_libraries(wfmLib helperLib) target_sources(AWGLib @@ -19,6 +24,5 @@ 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 PUBLIC driverLib) diff --git a/Cpp/lib/helper.hpp b/Cpp/lib/CSVhelper.hpp similarity index 100% rename from Cpp/lib/helper.hpp rename to Cpp/lib/CSVhelper.hpp diff --git a/Cpp/lib/external/CMakeLists.txt b/Cpp/lib/external/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..da2c4dbf14c1c1aa5f0a1b926cb8bbdb5e5057ea --- /dev/null +++ b/Cpp/lib/external/CMakeLists.txt @@ -0,0 +1,8 @@ +# target_sources(tomlLib +# PRIVATE +# toml.cpp +# PUBLIC +# toml.hpp +# ) + +# target_include_directories(tomlLib PUBLIC ${CMAKE_CURRENT_LIST_DIR}) \ No newline at end of file diff --git a/Cpp/lib/waveform.cpp b/Cpp/lib/waveform.cpp index 8f5422e834480aa3f17a0c21e12172c75e73c7a6..ac50e0fa17e66d5c9a3aa4b38e9f96dc78d580b1 100644 --- a/Cpp/lib/waveform.cpp +++ b/Cpp/lib/waveform.cpp @@ -1,5 +1,5 @@ #include "waveform.h" -#include "helper.hpp" +#include "CSVhelper.hpp" #include <iostream> #include <fstream> #include <vector>