From e10da86d47ec4bfb5283dba2a03beef5f92a9fe7 Mon Sep 17 00:00:00 2001 From: Yury Rodzikau Date: Mon, 27 Oct 2025 11:51:57 +0100 Subject: [PATCH] LibMCCore/scanlabsmc: add digital output control API and integrate into job execution lifecycle - SDK bindings (`libmcdriver_scanlabsmc_sdk.*`): - Added bindings for `slsc_ctrl_write_digital_x`, `slsc_ctrl_write_digital_mask_x`, `slsc_job_write_digital_x` and `slsc_job_write_digital_mask_x`. - Introduced new enum `slsc_DigitalOutput` to address digital output channels. - Added wrapper functions with logging support for journaling/tracing. - Job instance (`libmcdriver_scanlabsmc_smcjobinstance.cpp`): - Digital output is now explicitly initialized to `0` before a job starts. - Output is set to `1` immediately after `slsc_job_begin` to signal job activation. - On finalization, output is set back to `0` before stopping the recorder. - Recording start/stop has been fully enabled to capture digital transitions. Signed-off-by: Yury Rodzikau --- .../libmcdriver_scanlabsmc_sdk.cpp | 38 +++++++++++++++++++ .../libmcdriver_scanlabsmc_sdk.hpp | 19 ++++++++++ .../libmcdriver_scanlabsmc_smcjobinstance.cpp | 15 +++++++- 3 files changed, 70 insertions(+), 2 deletions(-) diff --git a/Drivers/ScanLabSMC/Implementation/libmcdriver_scanlabsmc_sdk.cpp b/Drivers/ScanLabSMC/Implementation/libmcdriver_scanlabsmc_sdk.cpp index a2971f01..493ea62f 100644 --- a/Drivers/ScanLabSMC/Implementation/libmcdriver_scanlabsmc_sdk.cpp +++ b/Drivers/ScanLabSMC/Implementation/libmcdriver_scanlabsmc_sdk.cpp @@ -245,6 +245,12 @@ CScanLabSMCSDK::CScanLabSMCSDK(const std::string& sDLLNameUTF8, const std::strin this->ptr_slsc_ctrl_exec_init_laser_sequence = (PScanLabSMCPtr_slsc_ctrl_exec_init_laser_sequence)_loadScanLabSMCAddress(hLibrary, "slsc_ctrl_exec_init_laser_sequence"); this->ptr_slsc_ctrl_exec_shutdown_laser_sequence = (PScanLabSMCPtr_slsc_ctrl_exec_shutdown_laser_sequence)_loadScanLabSMCAddress(hLibrary, "slsc_ctrl_exec_shutdown_laser_sequence"); this->ptr_slsc_job_write_analog_x = (PScanLabSMCPtr_slsc_job_write_analog_x)_loadScanLabSMCAddress(hLibrary, "slsc_job_write_analog_x"); + + this->ptr_slsc_ctrl_write_digital_x = (PScanLabSMCPtr_slsc_ctrl_write_digital_x)_loadScanLabSMCAddress(hLibrary, "slsc_ctrl_write_digital_x"); + this->ptr_slsc_ctrl_write_digital_mask_x = (PScanLabSMCPtr_slsc_ctrl_write_digital_mask_x)_loadScanLabSMCAddress(hLibrary, "slsc_ctrl_write_digital_mask_x"); + + this->ptr_slsc_job_write_digital_x = (PScanLabSMCPtr_slsc_job_write_digital_x)_loadScanLabSMCAddress(hLibrary, "slsc_job_write_digital_x"); + this->ptr_slsc_job_write_digital_mask_x = (PScanLabSMCPtr_slsc_job_write_digital_mask_x)_loadScanLabSMCAddress(hLibrary, "slsc_job_write_digital_mask_x"); m_LibraryHandle = (void*) hLibrary; } @@ -657,6 +663,38 @@ slscReturnValue CScanLabSMCSDK::slsc_job_write_analog_x(size_t Handle, slsc_Anal return this->ptr_slsc_job_write_analog_x(Handle, Channel, Value, TimeDelay); } +slscReturnValue CScanLabSMCSDK::slsc_ctrl_write_digital_x(size_t Handle, slsc_DigitalOutput Channel, uint16_t Value) +{ + if (m_pLogJournal.get() != nullptr) + m_pLogJournal->logCall("slsc_ctrl_write_digital_x", std::to_string(Handle) + ", " + std::to_string((uint32_t)Channel) + ", " + std::to_string(Value)); + + return this->ptr_slsc_ctrl_write_digital_x(Handle, Channel, Value); +} + +slscReturnValue CScanLabSMCSDK::slsc_ctrl_write_digital_mask_x(size_t Handle, slsc_DigitalOutput Channel, uint16_t Mask, uint16_t Value) +{ + if (m_pLogJournal.get() != nullptr) + m_pLogJournal->logCall("slsc_ctrl_write_digital_mask_x", std::to_string(Handle) + ", " + std::to_string((uint32_t)Channel) + ", " + std::to_string(Mask) + ", " + std::to_string(Value)); + + return this->ptr_slsc_ctrl_write_digital_mask_x(Handle, Channel, Mask, Value); +} + +slscReturnValue CScanLabSMCSDK::slsc_job_write_digital_x(size_t Handle, slsc_DigitalOutput Channel, uint16_t Value, double TimeDelay) +{ + if (m_pLogJournal.get() != nullptr) + m_pLogJournal->logCall("slsc_job_write_digital_x", std::to_string(Handle) + ", " + std::to_string((uint32_t)Channel) + ", " + std::to_string(Value) + ", " + std::to_string(TimeDelay)); + + return this->ptr_slsc_job_write_digital_x(Handle, Channel, Value, TimeDelay); +} + +slscReturnValue CScanLabSMCSDK::slsc_job_write_digital_mask_x(size_t Handle, slsc_DigitalOutput Channel, uint16_t Mask, uint16_t Value, double TimeDelay) +{ + if (m_pLogJournal.get() != nullptr) + m_pLogJournal->logCall("slsc_job_write_digital_mask_x", std::to_string(Handle) + ", " + std::to_string((uint32_t)Channel) + ", " + std::to_string(Mask) + ", " + std::to_string(Value) + ", " + std::to_string(TimeDelay)); + + return this->ptr_slsc_job_write_digital_mask_x(Handle, Channel, Mask, Value, TimeDelay); +} + void CScanLabSMCSDK::setJournal(PScanLabSMCSDKJournal pLogJournal) { m_pLogJournal = pLogJournal; diff --git a/Drivers/ScanLabSMC/Implementation/libmcdriver_scanlabsmc_sdk.hpp b/Drivers/ScanLabSMC/Implementation/libmcdriver_scanlabsmc_sdk.hpp index afb8d14c..1da7abf1 100644 --- a/Drivers/ScanLabSMC/Implementation/libmcdriver_scanlabsmc_sdk.hpp +++ b/Drivers/ScanLabSMC/Implementation/libmcdriver_scanlabsmc_sdk.hpp @@ -202,6 +202,11 @@ namespace LibMCDriver_ScanLabSMC { slsc_AnalogOutput_2 = 1 }; + enum class slsc_DigitalOutput : uint8_t + { + slsc_DigitalOutput_1 = 0, + slsc_DigitalOutput_2 = 1, + }; typedef struct _slsc_PolylineOptions slsc_PolylineOptions; typedef struct _slsc_VersionInfo slsc_VersionInfo; @@ -250,6 +255,11 @@ namespace LibMCDriver_ScanLabSMC { typedef slscReturnValue(SCANLABSMC_CALLINGCONVENTION* PScanLabSMCPtr_slsc_job_write_analog_x) (size_t Handle, slsc_AnalogOutput Channel, double Value, double TimeDelay); + typedef slscReturnValue(SCANLABSMC_CALLINGCONVENTION* PScanLabSMCPtr_slsc_ctrl_write_digital_x) (size_t Handle, slsc_DigitalOutput Channel, uint16_t Value); + typedef slscReturnValue(SCANLABSMC_CALLINGCONVENTION* PScanLabSMCPtr_slsc_ctrl_write_digital_mask_x) (size_t Handle, slsc_DigitalOutput Channel, uint16_t Mask, uint16_t Value); + typedef slscReturnValue(SCANLABSMC_CALLINGCONVENTION* PScanLabSMCPtr_slsc_job_write_digital_x) (size_t Handle, slsc_DigitalOutput Channel, uint16_t Value, double TimeDelay); + typedef slscReturnValue(SCANLABSMC_CALLINGCONVENTION* PScanLabSMCPtr_slsc_job_write_digital_mask_x) (size_t Handle, slsc_DigitalOutput Channel, uint16_t Mask, uint16_t Value, double TimeDelay); + class CScanLabSMCSDKJournal { private: std::map m_DefinedVariables; @@ -336,6 +346,10 @@ namespace LibMCDriver_ScanLabSMC { PScanLabSMCPtr_slsc_ctrl_exec_init_laser_sequence ptr_slsc_ctrl_exec_init_laser_sequence = nullptr; PScanLabSMCPtr_slsc_ctrl_exec_shutdown_laser_sequence ptr_slsc_ctrl_exec_shutdown_laser_sequence = nullptr; PScanLabSMCPtr_slsc_job_write_analog_x ptr_slsc_job_write_analog_x = nullptr; + PScanLabSMCPtr_slsc_ctrl_write_digital_x ptr_slsc_ctrl_write_digital_x = nullptr; + PScanLabSMCPtr_slsc_ctrl_write_digital_mask_x ptr_slsc_ctrl_write_digital_mask_x = nullptr; + PScanLabSMCPtr_slsc_job_write_digital_x ptr_slsc_job_write_digital_x = nullptr; + PScanLabSMCPtr_slsc_job_write_digital_mask_x ptr_slsc_job_write_digital_mask_x = nullptr; public: @@ -393,6 +407,11 @@ namespace LibMCDriver_ScanLabSMC { slscReturnValue slsc_job_write_analog_x(size_t Handle, slsc_AnalogOutput Channel, double Value, double TimeDelay); + slscReturnValue slsc_ctrl_write_digital_x(size_t Handle, slsc_DigitalOutput Channel, uint16_t Value); + slscReturnValue slsc_ctrl_write_digital_mask_x(size_t Handle, slsc_DigitalOutput Channel, uint16_t Mask, uint16_t Value); + + slscReturnValue slsc_job_write_digital_x(size_t Handle, slsc_DigitalOutput Channel, uint16_t Value, double TimeDelay); + slscReturnValue slsc_job_write_digital_mask_x(size_t Handle, slsc_DigitalOutput Channel, uint16_t Mask, uint16_t Value, double TimeDelay); }; diff --git a/Drivers/ScanLabSMC/Implementation/libmcdriver_scanlabsmc_smcjobinstance.cpp b/Drivers/ScanLabSMC/Implementation/libmcdriver_scanlabsmc_smcjobinstance.cpp index 4a950a37..22c47ba2 100644 --- a/Drivers/ScanLabSMC/Implementation/libmcdriver_scanlabsmc_smcjobinstance.cpp +++ b/Drivers/ScanLabSMC/Implementation/libmcdriver_scanlabsmc_smcjobinstance.cpp @@ -77,13 +77,20 @@ CSMCJobInstance::CSMCJobInstance(PSMCContextHandle pContextHandle, double dStart m_pSDK = m_pContextHandle->getSDK(); auto contextHandle = m_pContextHandle->getHandle(); + + // Initialize digital output to 0 + m_pSDK->checkError(contextHandle, m_pSDK->slsc_ctrl_write_digital_x(contextHandle, slsc_DigitalOutput::slsc_DigitalOutput_1, 0)); + + // Begin job m_pSDK->checkError(contextHandle, m_pSDK->slsc_job_begin(contextHandle, &m_JobID)); + // Set digital output to 1 + m_pSDK->checkError(contextHandle, m_pSDK->slsc_job_write_digital_x(contextHandle, slsc_DigitalOutput::slsc_DigitalOutput_1, 1, 0 ) ); slsc_RecordSet eRecordSetA = slsc_RecordSet::slsc_RecordSet_SetPositions; slsc_RecordSet eRecordSetB = slsc_RecordSet::slsc_RecordSet_LaserSwitches; - //m_pSDK->checkError(contextHandle, m_pSDK->slsc_job_start_record(contextHandle, eRecordSetA, eRecordSetB)); + m_pSDK->checkError(contextHandle, m_pSDK->slsc_job_start_record(contextHandle, eRecordSetA, eRecordSetB)); if (dMaxPowerInWatts < SCANLABSMC_MIN_MAXPOWERINWATTS || dMaxPowerInWatts > SCANLABSMC_MAX_MAXPOWERINWATTS) throw ELibMCDriver_ScanLabSMCInterfaceException(LIBMCDRIVER_SCANLABSMC_ERROR_INVALIDMAXPOWERVALUE); @@ -106,7 +113,11 @@ void CSMCJobInstance::Finalize() auto contextHandle = m_pContextHandle->getHandle(); - //m_pSDK->checkError(contextHandle, m_pSDK->slsc_job_stop_record(contextHandle)); + // Set digital output to 0 + m_pSDK->checkError(contextHandle, m_pSDK->slsc_job_write_digital_x(contextHandle, slsc_DigitalOutput::slsc_DigitalOutput_1, 0, 0)); + + // Stop recording + m_pSDK->checkError(contextHandle, m_pSDK->slsc_job_stop_record(contextHandle)); m_pSDK->checkError(contextHandle, m_pSDK->slsc_job_end(contextHandle)); m_bIsFinalized = true;