diff --git a/include/ixsync.hpp b/include/ixsync.hpp index 54c2ba5..e831c18 100644 --- a/include/ixsync.hpp +++ b/include/ixsync.hpp @@ -52,22 +52,109 @@ class IXsync { * 输入组件 * ***********************************************************************************************/ + /** + * @brief + * + * 概述: 输入组件一共3组,对应着设备上的3组输入接口 + * TTLInputModule1_XXXXX: TTL1_IN + * TTLInputModule2_XXXXX: TTL2_IN + * TTLInputModule3_XXXXX: TTL3_IN + * TTLInputModule4_XXXXX: 隔离输入口 + * + * ExternalTimecode_XXXXX : BNC时码输入口 和 耳机时码输入口 + * + * ExternalGenlock_XXXXX : GENLOCK输入口 + * + * + * + * + * 使用注意事项: + * 除了外部时码使用前,需要先对其进行配置,其他输入组件均无需配置即可直接使用 + * + * ExternalTimecode_setSource + * 方法说明:设置时间码输入源 + * 参数范围: + * INPUT_IF_TIMECODE_BNC + * INPUT_IF_TIMECODE_HEADPHONE + * + * + * ExternalTimecode_setFormat + * 方法说明:设置时间码输入格式 + * 参数范围: + * TIMECODE_FPS2398 + * TIMECODE_FPS2400 + * TIMECODE_FPS2500 + * TIMECODE_FPS2997 + * TIMECODE_FPS2997Drop + * TIMECODE_FPS3000 + * + * + * TTLInputModuleX_detectFreq + * 方法说明:探测TTL输入频率 + * + * ExternalGenlock_detectFreq + * 方法说明:探测GENLOCK信号频率 + * + */ + virtual xs_error_code_t ExternalTimecode_setSource(InputInterface_t src) = 0; virtual xs_error_code_t ExternalTimecode_getSource(InputInterface_t &timecode_select) = 0; virtual xs_error_code_t ExternalTimecode_setFormat(TimecodeFormat_t format) = 0; virtual xs_error_code_t ExternalTimecode_getFormat(TimecodeFormat_t &format) = 0; virtual xs_error_code_t ExternalTimecode_readCode(XsyncTimecode_t &timecode) = 0; - virtual xs_error_code_t TTLInputModule1_detectFreq(uint32_t &freq) = 0; - virtual xs_error_code_t TTLInputModule2_detectFreq(uint32_t &freq) = 0; - virtual xs_error_code_t TTLInputModule3_detectFreq(uint32_t &freq) = 0; - virtual xs_error_code_t TTLInputModule4_detectFreq(uint32_t &freq) = 0; + virtual xs_error_code_t TTLInputModule1_detectFreq(float &freq) = 0; + virtual xs_error_code_t TTLInputModule2_detectFreq(float &freq) = 0; + virtual xs_error_code_t TTLInputModule3_detectFreq(float &freq) = 0; + virtual xs_error_code_t TTLInputModule4_detectFreq(float &freq) = 0; virtual xs_error_code_t ExternalGenlock_detectFreq(float &freq) = 0; /*********************************************************************************************** - * 内部组件 * + * 内部时钟源 * ***********************************************************************************************/ + /** + * @brief + * + * 概述: 内部组件一共7组 + * InternalTimecode_XXXXX : 内部时码 + * InternalGenlock_XXXXX : 内部同步信号 + * InternalClock_XXXXX : 内部时钟 + * + * SysTimecode_XXXXX : 系统时码 + * SysGenlock_XXXXX : 系统同步信号 + * SysClock_XXXXX : 系统时钟 + * + * + * + * 概念说明: + * Xsync系统中一共有三个比较重要概念,时码,Genlock,系统时钟。内部时码,内部Genlock,内部时钟是指 + * 设备内部自己产生的时码,Genlock,时钟。外部时码,外部Genlock,是指设备外部输入的时码,Genlock。 + * 系统时码,系统Genlock,系统时钟,和他们的关系如下。 + * + * + * 外部时码 ---|1 + * 内部时码 ---|0 ----> 系统时码 + * + * + * 外部Genlock ---|1 + * 内部Genlock ---|0 ----> 系统Genlock + * + * + * 系统时码的频率信号 ---| + * 系统Genlock ---| + * 内部时钟 ---| ----> 系统时钟 + * 外部TTL输入信号 ---| + * 外部隔离输入信号 ---| + * + * + * 注意事项: + * 1. 内部时码,内部Genlock,内部时钟,默认自启动无需配置。当需要修改其制式或者频率,调用相应的API进行修改。 + * 2. 系统时码,系统Genlock,系统时钟,其对应的输入源默认选择,内部时码,内部Genlock,内部时钟。所以无需配置,其默认也是生效的。 + * 3. 系统时钟支持,分频,倍频,触发边沿,输入输出频率控制。 + * + * + */ virtual xs_error_code_t InternalTimecode_setFormat(TimecodeFormat_t format) = 0; virtual xs_error_code_t InternalTimecode_getFormat(TimecodeFormat_t &format) = 0; @@ -100,6 +187,49 @@ class IXsync { virtual xs_error_code_t SysClock_readOutSigFreq(float &freq) = 0; virtual xs_error_code_t SysClock_readInSigFreq(float &freq) = 0; + /*********************************************************************************************** + * 录制信号发生器 * + ***********************************************************************************************/ + + /** + * @brief + * + * 概述: + * 录制信号发生器可以产生,录制使能信号,拍摄曝光信号,两种信号。其启动方式支持,手动启动, + * TimeCode启动,外部TTL触发启动三种方式。通过RecordSigGenerator_setContrlMode可以设置。 + * + * 手动控制: + * + * 如果是手动启动,先通过RecordSigGenerator_setContrlMode将模式配置成CONTROLMODE_MANUAL_TRIGGER, + * 然后直接调用下面两个方法即可 + * RecordSigGenerator_manualStart + * RecordSigGenerator_manualStop + * + * + * Timecode控制: + * + * 如果是Timecode控制启动,先通过RecordSigGenerator_setContrlMode将模式配置成CONTROLMODE_TIMECODE_TRIGGER。 + * 然后可以调用下面几个方法进行配置即可。可通过RecordSigGenerator_setTimecodeCtrlFlag方法,只使能Timecode自动控制 + * 启动,或者只使能Timecode自动控制停止。 + * RecordSigGenerator_setAutoStartTimecode :配置自动启动的时间点 + * RecordSigGenerator_setAutoStopTimecode :配置自动停止的时间点 + * RecordSigGenerator_setTimecodeCtrlFlag :配置是否使能自动启动,或者自动停止,默认配置是二者都使能的。 + * + * 外部TTL控制: + * + * 如果是外部TTL触发启动,先通过RecordSigGenerator_setContrlMode将模式配置成CONTROLMODE_EXTERNALTTL_TRIGGER。 + * 然后调用下面几个方法进行配置。 + * RecordSigGenerator_setExternalTTLTriggerSrc : 配置外部TTL触发源(输入范围INPUT_IF_TTL1->INPUT_IF_TTL4) + * RecordSigGenerator_setExternalTTLTriggerPolarity : 配置触发电平(0:低电平,1:高电平) + * + * + * 该模块输出的拍摄曝光信号,可以通过下面两个方法,设置曝光时间,曝光偏移时间。 + * RecordSigGenerator_setRecordExposureTime + * RecordSigGenerator_setRecordExposureOffsetTime + * + * + */ + virtual xs_error_code_t RecordSigGenerator_setContrlMode(ControlMode_t mode) = 0; virtual xs_error_code_t RecordSigGenerator_getContrlMode(ControlMode_t &mode) = 0; virtual xs_error_code_t RecordSigGenerator_manualStart() = 0; @@ -125,10 +255,43 @@ class IXsync { * 输出组件 * ***********************************************************************************************/ - virtual xs_error_code_t TimecodeOutputModule_setBncOutputLevel(int level) = 0; - virtual xs_error_code_t TimecodeOutputModule_getBncOutputLevel(int &level) = 0; - virtual xs_error_code_t TimecodeOutputModule_setHeadphoneOutputLevel(int level) = 0; - virtual xs_error_code_t TimecodeOutputModule_getHeadphoneOutputLevel(int &level) = 0; + + + + + + + + + + + + + /** + * @brief 输入组件一共有4组,TTL,Timecode,Genlock,网口,其中只有TTL输出(包含隔离输出)需要对齐进行配置。 + * + * + * TTL输出组件 + * 信号源选择范围: + * SIGNAL_LOGIC0 + * SIGNAL_LOGIC1 + * SIGNAL_TTLIN1 + * SIGNAL_TTLIN2 + * SIGNAL_TTLIN3 + * SIGNAL_TTLIN4 + * SIGNAL_SYS_CLK_OUTPUT + * SIGNAL_SYS_GENLOCK_OUTPUT + * SIGNAL_SYS_TIMECODE_FREQ_OUTPUT + * SIGNAL_BUSINESS_RECORD_SIG + * SIGNAL_BUSINESS_RECORD_EXPOSURE_SIG + * + * 分频倍频: + * 当信号源是 SIGNAL_BUSINESS_RECORD_SIG 或者 SIGNAL_BUSINESS_RECORD_EXPOSURE_SIG 分频倍频不启作用, + * 直接输出原始信号。当信号源是其他信号源时,分频倍频起作用。分频输入参数为0时,为不分频,1时,为2分频。倍频 + * 输入参数为0时,为不倍频,1时,为2倍频。 + * + * + */ virtual xs_error_code_t TTLOutputModule1_setSrcSigType(SignalType_t source) = 0; virtual xs_error_code_t TTLOutputModule1_getSrcSigType(SignalType_t &source) = 0; diff --git a/src/xsync_v2.cpp b/src/xsync_v2.cpp index 613402a..220b4f0 100644 --- a/src/xsync_v2.cpp +++ b/src/xsync_v2.cpp @@ -102,10 +102,10 @@ class Xsync : public IXsync { virtual xs_error_code_t ExternalTimecode_getFormat(TimecodeFormat_t &format) override; virtual xs_error_code_t ExternalTimecode_readCode(XsyncTimecode_t &timecode) override; - virtual xs_error_code_t TTLInputModule1_detectFreq(uint32_t &freq) override; - virtual xs_error_code_t TTLInputModule2_detectFreq(uint32_t &freq) override; - virtual xs_error_code_t TTLInputModule3_detectFreq(uint32_t &freq) override; - virtual xs_error_code_t TTLInputModule4_detectFreq(uint32_t &freq) override; + virtual xs_error_code_t TTLInputModule1_detectFreq(float &freq) override; + virtual xs_error_code_t TTLInputModule2_detectFreq(float &freq) override; + virtual xs_error_code_t TTLInputModule3_detectFreq(float &freq) override; + virtual xs_error_code_t TTLInputModule4_detectFreq(float &freq) override; virtual xs_error_code_t ExternalGenlock_detectFreq(float &freq) override; @@ -161,10 +161,10 @@ class Xsync : public IXsync { virtual xs_error_code_t RecordSigGenerator_getRecordState(uint32_t &state) override; virtual xs_error_code_t RecordSigGenerator_readTimecodeSnapshot(XsyncTimecode_t &timecode) override; - virtual xs_error_code_t TimecodeOutputModule_setBncOutputLevel(int level); // 0:line,1:mi overridec - virtual xs_error_code_t TimecodeOutputModule_getBncOutputLevel(int &level) override; - virtual xs_error_code_t TimecodeOutputModule_setHeadphoneOutputLevel(int level); // 0:line,1:mi overridec - virtual xs_error_code_t TimecodeOutputModule_getHeadphoneOutputLevel(int &level) override; + xs_error_code_t TimecodeOutputModule_setBncOutputLevel(int level); // 0:line,1:mi overridec + xs_error_code_t TimecodeOutputModule_getBncOutputLevel(int &level); + xs_error_code_t TimecodeOutputModule_setHeadphoneOutputLevel(int level); // 0:line,1:mi overridec + xs_error_code_t TimecodeOutputModule_getHeadphoneOutputLevel(int &level); virtual xs_error_code_t TTLOutputModule1_setSrcSigType(SignalType_t source) override; virtual xs_error_code_t TTLOutputModule1_getSrcSigType(SignalType_t &source) override; @@ -601,33 +601,10 @@ xs_error_code_t Xsync::doaction(uint32_t action, uint32_t actionval, uint32_t *a *******************************************************************************/ #define FREQ_CNT_TO_FREQ(cnt) ((cnt != 0) ? (uint32_t)(1.0 / (cnt * 1.0 / (10 * 1000 * 1000)) + 0.5) : 0) //+0.5是因为c++ 小数强转成整数时是取整,而非四舍五入 -xs_error_code_t Xsync::TTLInputModule1_detectFreq(uint32_t &freq) { - uint32_t freq_cnt = 0; - DO_XSYNC(reg_read(reg::k_ttlin1_freq_detector_reg, freq_cnt, 10)); - if (freq_cnt == 0) { - freq = 0; - } - freq = FREQ_CNT_TO_FREQ(freq_cnt); - return kxs_ec_success; -} -xs_error_code_t Xsync::TTLInputModule2_detectFreq(uint32_t &freq) { - uint32_t freq_cnt = 0; - DO_XSYNC(reg_read(reg::k_ttlin2_freq_detector_reg, freq_cnt, 10)); - freq = FREQ_CNT_TO_FREQ(freq_cnt); - return kxs_ec_success; -} -xs_error_code_t Xsync::TTLInputModule3_detectFreq(uint32_t &freq) { - uint32_t freq_cnt = 0; - DO_XSYNC(reg_read(reg::k_ttlin3_freq_detector_reg, freq_cnt, 10)); - freq = FREQ_CNT_TO_FREQ(freq_cnt); - return kxs_ec_success; -} -xs_error_code_t Xsync::TTLInputModule4_detectFreq(uint32_t &freq) { - uint32_t freq_cnt = 0; - DO_XSYNC(reg_read(reg::k_ttlin4_freq_detector_reg, freq_cnt, 10)); - freq = FREQ_CNT_TO_FREQ(freq_cnt); - return kxs_ec_success; -} +xs_error_code_t Xsync::TTLInputModule1_detectFreq(float &freq) { return readfreq(reg::k_ttlin1_freq_detector_reg, freq); } +xs_error_code_t Xsync::TTLInputModule2_detectFreq(float &freq) { return readfreq(reg::k_ttlin2_freq_detector_reg, freq); } +xs_error_code_t Xsync::TTLInputModule3_detectFreq(float &freq) { return readfreq(reg::k_ttlin3_freq_detector_reg, freq); } +xs_error_code_t Xsync::TTLInputModule4_detectFreq(float &freq) { return readfreq(reg::k_ttlin4_freq_detector_reg, freq); } /******************************************************************************* * TTLOutputModule * @@ -635,7 +612,29 @@ xs_error_code_t Xsync::TTLInputModule4_detectFreq(uint32_t &freq) { // 0:固定输出低电平,1:固定输出高电平,2:分频倍频模式,3:转发模式,4:测试模式 xs_error_code_t Xsync::TTLOutputModule1_setSrcSigType(SignalType_t source) { - if (source == SIGNAL_TTLIN1 || source == SIGNAL_TTLIN2 || source == SIGNAL_TTLIN3 || source == SIGNAL_TTLIN4) { + if (source != SIGNAL_LOGIC0 && // + source != SIGNAL_LOGIC1 && // + source != SIGNAL_TTLIN1 && // + source != SIGNAL_TTLIN2 && // + source != SIGNAL_TTLIN3 && // + source != SIGNAL_TTLIN4 && // + source != SIGNAL_SYS_CLK_OUTPUT && // + source != SIGNAL_SYS_GENLOCK_OUTPUT && // + source != SIGNAL_SYS_TIMECODE_FREQ_OUTPUT && // + source != SIGNAL_BUSINESS_RECORD_SIG && // + source != SIGNAL_BUSINESS_RECORD_EXPOSURE_SIG // + ) { + return kxs_ec_param_error; + } + + if (source == SIGNAL_TTLIN1 || // + source == SIGNAL_TTLIN2 || // + source == SIGNAL_TTLIN3 || // + source == SIGNAL_TTLIN4 || // + source == SIGNAL_SYS_CLK_OUTPUT || // + source == SIGNAL_SYS_GENLOCK_OUTPUT || // + source == SIGNAL_SYS_TIMECODE_FREQ_OUTPUT // + ) { DO_XSYNC(reg_write(reg::kreg_ttlout1_signal_process_mode, 2, 10)); // 分频倍频模式 } else { DO_XSYNC(reg_write(reg::kreg_ttlout1_signal_process_mode, 3, 10)); // 转发模式 @@ -643,7 +642,28 @@ xs_error_code_t Xsync::TTLOutputModule1_setSrcSigType(SignalType_t source) { REG_WRITE(reg::kreg_ttlout1_input_signal_select, source); } xs_error_code_t Xsync::TTLOutputModule2_setSrcSigType(SignalType_t source) { - if (source == SIGNAL_TTLIN1 || source == SIGNAL_TTLIN2 || source == SIGNAL_TTLIN3 || source == SIGNAL_TTLIN4) { + if (source != SIGNAL_LOGIC0 && // + source != SIGNAL_LOGIC1 && // + source != SIGNAL_TTLIN1 && // + source != SIGNAL_TTLIN2 && // + source != SIGNAL_TTLIN3 && // + source != SIGNAL_TTLIN4 && // + source != SIGNAL_SYS_CLK_OUTPUT && // + source != SIGNAL_SYS_GENLOCK_OUTPUT && // + source != SIGNAL_SYS_TIMECODE_FREQ_OUTPUT && // + source != SIGNAL_BUSINESS_RECORD_SIG && // + source != SIGNAL_BUSINESS_RECORD_EXPOSURE_SIG // + ) { + return kxs_ec_param_error; + } + if (source == SIGNAL_TTLIN1 || // + source == SIGNAL_TTLIN2 || // + source == SIGNAL_TTLIN3 || // + source == SIGNAL_TTLIN4 || // + source == SIGNAL_SYS_CLK_OUTPUT || // + source == SIGNAL_SYS_GENLOCK_OUTPUT || // + source == SIGNAL_SYS_TIMECODE_FREQ_OUTPUT // + ) { DO_XSYNC(reg_write(reg::kreg_ttlout2_signal_process_mode, 2, 10)); // 分频倍频模式 } else { DO_XSYNC(reg_write(reg::kreg_ttlout2_signal_process_mode, 3, 10)); // 转发模式 @@ -651,7 +671,28 @@ xs_error_code_t Xsync::TTLOutputModule2_setSrcSigType(SignalType_t source) { REG_WRITE(reg::kreg_ttlout2_input_signal_select, source); } xs_error_code_t Xsync::TTLOutputModule3_setSrcSigType(SignalType_t source) { - if (source == SIGNAL_TTLIN1 || source == SIGNAL_TTLIN2 || source == SIGNAL_TTLIN3 || source == SIGNAL_TTLIN4) { + if (source != SIGNAL_LOGIC0 && // + source != SIGNAL_LOGIC1 && // + source != SIGNAL_TTLIN1 && // + source != SIGNAL_TTLIN2 && // + source != SIGNAL_TTLIN3 && // + source != SIGNAL_TTLIN4 && // + source != SIGNAL_SYS_CLK_OUTPUT && // + source != SIGNAL_SYS_GENLOCK_OUTPUT && // + source != SIGNAL_SYS_TIMECODE_FREQ_OUTPUT && // + source != SIGNAL_BUSINESS_RECORD_SIG && // + source != SIGNAL_BUSINESS_RECORD_EXPOSURE_SIG // + ) { + return kxs_ec_param_error; + } + if (source == SIGNAL_TTLIN1 || // + source == SIGNAL_TTLIN2 || // + source == SIGNAL_TTLIN3 || // + source == SIGNAL_TTLIN4 || // + source == SIGNAL_SYS_CLK_OUTPUT || // + source == SIGNAL_SYS_GENLOCK_OUTPUT || // + source == SIGNAL_SYS_TIMECODE_FREQ_OUTPUT // + ) { DO_XSYNC(reg_write(reg::kreg_ttlout3_signal_process_mode, 2, 10)); // 分频倍频模式 } else { DO_XSYNC(reg_write(reg::kreg_ttlout3_signal_process_mode, 3, 10)); // 转发模式 @@ -659,6 +700,20 @@ xs_error_code_t Xsync::TTLOutputModule3_setSrcSigType(SignalType_t source) { REG_WRITE(reg::kreg_ttlout3_input_signal_select, source); } xs_error_code_t Xsync::TTLOutputModule4_setSrcSigType(SignalType_t source) { + if (source != SIGNAL_LOGIC0 && // + source != SIGNAL_LOGIC1 && // + source != SIGNAL_TTLIN1 && // + source != SIGNAL_TTLIN2 && // + source != SIGNAL_TTLIN3 && // + source != SIGNAL_TTLIN4 && // + source != SIGNAL_SYS_CLK_OUTPUT && // + source != SIGNAL_SYS_GENLOCK_OUTPUT && // + source != SIGNAL_SYS_TIMECODE_FREQ_OUTPUT && // + source != SIGNAL_BUSINESS_RECORD_SIG && // + source != SIGNAL_BUSINESS_RECORD_EXPOSURE_SIG // + ) { + return kxs_ec_param_error; + } if (source == SIGNAL_TTLIN1 || source == SIGNAL_TTLIN2 || source == SIGNAL_TTLIN3 || source == SIGNAL_TTLIN4) { DO_XSYNC(reg_write(reg::kreg_ttlout4_signal_process_mode, 2, 10)); // 分频倍频模式 } else { @@ -793,9 +848,25 @@ xs_error_code_t Xsync::InternalClock_getFreq(float &freq) { return readfreq(reg: /******************************************************************************* * SysClock * *******************************************************************************/ -xs_error_code_t Xsync::SysClock_setSrc(SignalType_t sig) { return reg_write(reg::sys_clock_source, sig); } +xs_error_code_t Xsync::SysClock_setSrc(SignalType_t sig) { + if (sig != SIGNAL_TTLIN1 && // + sig != SIGNAL_TTLIN2 && // + sig != SIGNAL_TTLIN3 && // + sig != SIGNAL_TTLIN4 && // + sig != SIGNAL_SYS_CLK_OUTPUT && // + sig != SIGNAL_SYS_GENLOCK_OUTPUT && // + sig != SIGNAL_SYS_TIMECODE_FREQ_OUTPUT) { + return kxs_ec_param_error; + } + return reg_write(reg::sys_clock_source, sig); +} xs_error_code_t Xsync::SysClock_getSrc(SignalType_t &sig) { REG_READ(reg::sys_clock_source, sig); } -xs_error_code_t Xsync::SysClock_setTriggerEdge(TriggerEdge_t edge) { return reg_write(reg::sys_clock_trigger_edge_select, edge); } +xs_error_code_t Xsync::SysClock_setTriggerEdge(TriggerEdge_t edge) { + if (edge != TRIGGER_EDGE_RISING && edge != TRIGGER_EDGE_FALLING) { + return kxs_ec_param_error; + } + return reg_write(reg::sys_clock_trigger_edge_select, edge); +} xs_error_code_t Xsync::SysClock_getTriggerEdge(TriggerEdge_t &edge) { return _reg_read(reg::sys_clock_trigger_edge_select, edge); } xs_error_code_t Xsync::SysClock_setFreqDivision(uint32_t div) { return reg_write(reg::sys_clock_freq_division_ctrl, div); } xs_error_code_t Xsync::SysClock_geFreqtDivision(uint32_t &div) { return _reg_read(reg::sys_clock_freq_division_ctrl, div); }