You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

568 lines
18 KiB

2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
  1. #include "xsync.hpp"
  2. #include <map>
  3. #define ENABLE_LOG
  4. #ifdef ENABLE_LOG
  5. #include "../src/logger.hpp"
  6. #endif
  7. #define TAG "XSYNC"
  8. using namespace xsync;
  9. using namespace std;
  10. static uint32_t ipToUint32(const std::string &ipAddress, bool &suc) {
  11. uint32_t result = 0;
  12. std::istringstream iss(ipAddress);
  13. std::string segment;
  14. int i = 0;
  15. while (std::getline(iss, segment, '.')) {
  16. uint32_t octet = std::stoi(segment);
  17. if (octet > 255) {
  18. suc = false;
  19. return 0;
  20. }
  21. result |= (octet << ((3 - i) * 8));
  22. i++;
  23. }
  24. if (i != 4) {
  25. suc = false;
  26. return 0;
  27. }
  28. suc = true;
  29. uint32_t result_n = 0;
  30. result_n |= ((result & 0xff000000) >> 24);
  31. result_n |= ((result & 0x00ff0000) >> 8);
  32. result_n |= ((result & 0x0000ff00) << 8);
  33. result_n |= ((result & 0x000000ff) << 24);
  34. return result_n;
  35. }
  36. namespace xsync {
  37. namespace ttlout_module {
  38. static map<string, TriggerSigType_t> TriggerSigType2StrMap = {
  39. {"logic0", tri_logic0},
  40. {"logic1", tri_logic1},
  41. {"ttlin1_module_ext", tri_ttlin1_module_ext},
  42. {"ttlin1_module_divide", tri_ttlin1_module_divide},
  43. {"ttlin2_module_ext", tri_ttlin2_module_ext},
  44. {"ttlin2_module_divide", tri_ttlin2_module_divide},
  45. {"ttlin3_module_ext", tri_ttlin3_module_ext},
  46. {"ttlin3_module_divide", tri_ttlin3_module_divide},
  47. {"ttlin4_module_ext", tri_ttlin4_module_ext},
  48. {"ttlin4_module_divide", tri_ttlin4_module_divide},
  49. {"internal_en_flag", tri_internal_en_flag},
  50. {"genlock_frame_sync_ext", tri_genlock_frame_sync_ext},
  51. {"genlock_frame_sync_internal", tri_genlock_frame_sync_internal},
  52. {"timecode_frame_sync_ext", tri_timecode_frame_sync_ext},
  53. {"timecode_frame_sync_internal", tri_timecode_frame_sync_internal},
  54. {"timecode_serial_data_ext", tri_timecode_serial_data_ext},
  55. {"timecode_serial_data_internal", tri_timecode_serial_data_internal},
  56. {"internal_100hz", tri_internal_100hz},
  57. };
  58. static map<string, OutputSigType_t> Str2TriggerSigTypeMap = {
  59. {"ot_logic0", ot_logic0}, //
  60. {"ot_logic1", ot_logic1}, //
  61. {"ot_test_signal", ot_test_signal}, //
  62. {"ot_input_signal", ot_input_signal}, //
  63. {"ot_input_signal_mirror", ot_input_signal_mirror}, //
  64. {"ot_trigger_mode_signal", ot_trigger_mode_signal}, //
  65. {"ot_trigger_mode_signal_mirror", ot_trigger_mode_signal_mirror},
  66. };
  67. string TriggerSigType2Str(TriggerSigType_t type) {
  68. for (auto &item : TriggerSigType2StrMap) {
  69. if (item.second == type) return item.first;
  70. }
  71. return "unkown";
  72. }
  73. TriggerSigType_t Str2TriggerSigType(string type) {
  74. auto it = TriggerSigType2StrMap.find(type);
  75. if (it != TriggerSigType2StrMap.end()) {
  76. return it->second;
  77. }
  78. return tri_logic0;
  79. }
  80. string OutputSigType2Str(OutputSigType_t type) {
  81. for (auto &item : Str2TriggerSigTypeMap) {
  82. if (item.second == type) return item.first;
  83. }
  84. return "unkown";
  85. }
  86. OutputSigType_t Str2OutputSigType(string type) {
  87. auto it = Str2TriggerSigTypeMap.find(type);
  88. if (it != Str2TriggerSigTypeMap.end()) {
  89. return it->second;
  90. }
  91. return ot_logic0;
  92. }
  93. list<string> TriggerSigTypeStrSet() {
  94. list<string> ret;
  95. for (auto &item : TriggerSigType2StrMap) {
  96. ret.push_back(item.first);
  97. }
  98. return ret;
  99. }
  100. list<string> OutputSigTypeStrSet() {
  101. list<string> ret;
  102. for (auto &item : Str2TriggerSigTypeMap) {
  103. ret.push_back(item.first);
  104. }
  105. return ret;
  106. }
  107. } // namespace ttlout_module
  108. } // namespace xsync
  109. Xsync::Xsync(/* args */) {}
  110. Xsync &Xsync::Ins() {
  111. static Xsync xsync;
  112. return xsync;
  113. }
  114. void Xsync::initialize(I_XSUDPFactory *xsync_udp_factory) { m_xsync_udp_factory = xsync_udp_factory; }
  115. xs_error_code_t Xsync::connect(string xsync_ip) {
  116. lock_guard<recursive_mutex> lock(lock_);
  117. m_xsync_ip = xsync_ip;
  118. disConnect();
  119. /**
  120. * @brief m_xsync_reg_udp
  121. */
  122. xs_error_code_t ecode = kxs_ec_success;
  123. auto xsync_reg_udp = m_xsync_udp_factory->createXSUDP();
  124. ecode = xsync_reg_udp->initialize("0.0.0.0", IFLYTOP_XSYNC_SERVICE_PC_PORT);
  125. if (ecode != kxs_ec_success) {
  126. return ecode;
  127. }
  128. /**
  129. * @brief m_xsync_timecode_udp_listener
  130. */
  131. auto xsync_timecode_udp_listener = m_xsync_udp_factory->createXSUDP();
  132. ecode = xsync_timecode_udp_listener->initialize("0.0.0.0", IFLYTOP_XSYNC_TIMECODE_REPORT_PC_PORT);
  133. if (ecode != kxs_ec_success) {
  134. return ecode;
  135. }
  136. ecode = xsync_timecode_udp_listener->startReceive([this](XsyncNetAdd &from, uint8_t *data, size_t length) { parseTimecodeMsgAndReport(from, data, length); });
  137. if (ecode != kxs_ec_success) {
  138. return ecode;
  139. }
  140. /**
  141. * @brief m_xsync_camera_sync_udp_listener
  142. */
  143. auto xsync_camera_sync_udp_listener = m_xsync_udp_factory->createXSUDP();
  144. ecode = xsync_camera_sync_udp_listener->initialize("0.0.0.0", IFLYTOP_XSYNC_CAMERA_SYNC_PACKET_PC_PORT);
  145. if (ecode != kxs_ec_success) {
  146. return ecode;
  147. }
  148. ecode = xsync_camera_sync_udp_listener->startReceive([this](XsyncNetAdd &from, uint8_t *data, size_t length) { parseCameraSyncMsgAndReport(from, data, length); });
  149. if (ecode != kxs_ec_success) {
  150. return ecode;
  151. }
  152. m_xsync_reg_udp = xsync_reg_udp;
  153. m_xsync_timecode_udp_listener = xsync_timecode_udp_listener;
  154. m_xsync_camera_sync_udp_listener = xsync_camera_sync_udp_listener;
  155. m_net_state = kxsync_net_state_connected;
  156. return ecode;
  157. }
  158. xs_error_code_t Xsync::disConnect() {
  159. lock_guard<recursive_mutex> lock(lock_);
  160. if (m_xsync_reg_udp != nullptr) {
  161. m_xsync_reg_udp->stopReceive();
  162. m_xsync_reg_udp = nullptr;
  163. }
  164. if (m_xsync_timecode_udp_listener != nullptr) {
  165. m_xsync_timecode_udp_listener->stopReceive();
  166. m_xsync_timecode_udp_listener = nullptr;
  167. }
  168. if (m_xsync_camera_sync_udp_listener != nullptr) {
  169. m_xsync_camera_sync_udp_listener->stopReceive();
  170. m_xsync_camera_sync_udp_listener = nullptr;
  171. }
  172. m_net_state = kxsync_net_state_disconnect;
  173. return kxs_ec_success;
  174. }
  175. xsync_net_state_t Xsync::getNetState() { return m_net_state; }
  176. void Xsync::Basic_registerOnTimecodeMsgCallback(xsync_on_timecode_msg_t on_timecode_msg_cb) { m_on_timecode_msg_cb = on_timecode_msg_cb; }
  177. void Xsync::Basic_registerOnCameraSyncMsgCallback(xsync_on_camera_sync_msg_t on_camera_sync_msg_cb) { m_on_camera_sync_msg_cb = on_camera_sync_msg_cb; }
  178. xs_error_code_t Xsync::xsync_send_cmd_block(iflytop_xsync_packet_header_t *cmd, iflytop_xsync_packet_header_t *rx_data, int32_t buffersize, int32_t overtime_ms) {
  179. lock_guard<recursive_mutex> lock(lock_);
  180. if (!m_xsync_reg_udp) return kxs_ec_lose_connect;
  181. m_xsync_reg_udp->clearRxBuffer();
  182. cmd->index = txpacket_index++;
  183. XsyncNetAdd toadd = {m_xsync_ip, IFLYTOP_XSYNC_SERVICE_XSYNC_PORT};
  184. xs_error_code_t ecode = //
  185. m_xsync_reg_udp->sendto(toadd, (const char *)cmd, sizeof(iflytop_xsync_packet_header_t) + cmd->ndata * 4, nullptr);
  186. if (ecode != kxs_ec_success) {
  187. return ecode;
  188. }
  189. XsyncNetAdd fromadd;
  190. while (true) {
  191. // ZLOGI(TAG, "start rx wait for rxdata");
  192. ecode = m_xsync_reg_udp->receive((char *)rx_data, buffersize, fromadd, overtime_ms);
  193. // ZLOGI(TAG, "end rx wait for rxdata");
  194. if (ecode != kxs_ec_success) {
  195. return ecode;
  196. }
  197. if (rx_data->index != cmd->index) {
  198. // ZLOGI(TAG, "packet index error %d %d", cmd->index, rx_data->index);
  199. continue;
  200. }
  201. break;
  202. }
  203. return (xs_error_code_t)rx_data->data[0];
  204. }
  205. xs_error_code_t Xsync::reg_write(uint32_t regadd, uint32_t regvalue, uint32_t &regbackvalue, int32_t overtime_ms) {
  206. /**
  207. * @brief
  208. *
  209. *
  210. * kxsync_packet_type_reg_write
  211. * tx: regadd,regdata
  212. * rx: ecode,regdata
  213. */
  214. uint8_t txdata[128] = {0};
  215. uint8_t rxdata[128] = {0};
  216. iflytop_xsync_packet_header_t *txpacket = (iflytop_xsync_packet_header_t *)txdata;
  217. iflytop_xsync_packet_header_t *rxpacket = (iflytop_xsync_packet_header_t *)rxdata;
  218. txpacket->type = kxsync_packet_type_cmd;
  219. txpacket->index = txpacket_index++;
  220. txpacket->cmd = kxsync_packet_type_reg_write;
  221. txpacket->ndata = 2;
  222. txpacket->data[0] = regadd;
  223. txpacket->data[1] = regvalue;
  224. auto ecode = xsync_send_cmd_block(txpacket, rxpacket, sizeof(rxdata), overtime_ms);
  225. if (ecode != kxs_ec_success) {
  226. return ecode;
  227. }
  228. regbackvalue = rxpacket->data[1];
  229. return ecode;
  230. }
  231. xs_error_code_t Xsync::reg_read(uint32_t regadd, uint32_t &regvalue, int32_t overtime_ms) {
  232. /**
  233. * @brief
  234. *
  235. *
  236. * kxsync_packet_type_reg_write
  237. * tx: regadd,regdata
  238. * rx: ecode,regdata
  239. */
  240. uint8_t txdata[128] = {0};
  241. uint8_t rxdata[128] = {0};
  242. iflytop_xsync_packet_header_t *txpacket = (iflytop_xsync_packet_header_t *)txdata;
  243. iflytop_xsync_packet_header_t *rxpacket = (iflytop_xsync_packet_header_t *)rxdata;
  244. txpacket->type = kxsync_packet_type_cmd;
  245. txpacket->index = txpacket_index++;
  246. txpacket->cmd = kxsync_packet_type_reg_read;
  247. txpacket->ndata = 2;
  248. txpacket->data[0] = regadd;
  249. txpacket->data[1] = regvalue;
  250. auto ecode = xsync_send_cmd_block(txpacket, rxpacket, sizeof(rxdata), overtime_ms);
  251. if (ecode != kxs_ec_success) {
  252. return ecode;
  253. }
  254. regvalue = rxpacket->data[1];
  255. return ecode;
  256. }
  257. xs_error_code_t Xsync::reg_read_muti(uint32_t regadd, uint32_t nreg, vector<uint32_t> &regvalues, int32_t overtime_ms) {
  258. /**
  259. * @brief
  260. *
  261. *
  262. * kxsync_packet_type_reg_read_regs
  263. * tx: regstartadd,nreg
  264. * rx: ecode,regdatas
  265. */
  266. uint8_t txdata[128] = {0};
  267. uint8_t rxdata[1280] = {0};
  268. iflytop_xsync_packet_header_t *txpacket = (iflytop_xsync_packet_header_t *)txdata;
  269. iflytop_xsync_packet_header_t *rxpacket = (iflytop_xsync_packet_header_t *)rxdata;
  270. txpacket->type = kxsync_packet_type_cmd;
  271. txpacket->index = txpacket_index++;
  272. txpacket->cmd = kxsync_packet_type_reg_read_regs;
  273. txpacket->ndata = 2;
  274. txpacket->data[0] = regadd;
  275. txpacket->data[1] = nreg;
  276. auto ecode = xsync_send_cmd_block(txpacket, rxpacket, sizeof(rxdata), overtime_ms);
  277. if (ecode != kxs_ec_success) {
  278. return ecode;
  279. }
  280. if (rxpacket->ndata > 0) {
  281. for (int i = 0; i < rxpacket->ndata - 1; i++) {
  282. regvalues.push_back(rxpacket->data[i + 1]);
  283. }
  284. }
  285. return ecode;
  286. }
  287. void Xsync::parseTimecodeMsgAndReport(XsyncNetAdd &from, uint8_t *data, size_t length) {
  288. //
  289. iflytop_timecode_report_packet_t *packet = (iflytop_timecode_report_packet_t *)data;
  290. xysnc_timecode_t timecode;
  291. /**
  292. * @brief
  293. *
  294. * 01 02 03 04 01 02 03 04
  295. *
  296. */
  297. uint8_t frameuints = packet->timecode0 & 0x0f;
  298. uint8_t frame10s = (packet->timecode0 >> 8) & 0x3;
  299. uint8_t seconduints = (packet->timecode0 >> 16) & 0x0f;
  300. uint8_t second10s = (packet->timecode0 >> 24) & 0x03;
  301. uint8_t minuteuints = packet->timecode1 & 0x0f;
  302. uint8_t minute10s = (packet->timecode1 >> 8) & 0x03;
  303. uint8_t houruints = (packet->timecode1 >> 16) & 0x0f;
  304. uint8_t hour10s = (packet->timecode1 >> 24) & 0x03;
  305. timecode.hour = hour10s * 10 + houruints;
  306. timecode.minute = minute10s * 10 + minuteuints;
  307. timecode.second = second10s * 10 + seconduints;
  308. timecode.frame = frame10s * 10 + frameuints;
  309. if (m_on_timecode_msg_cb) m_on_timecode_msg_cb(&timecode);
  310. }
  311. void Xsync::parseCameraSyncMsgAndReport(XsyncNetAdd &from, uint8_t *data, size_t length) {
  312. uint32_t count = 0;
  313. uint32_t data0 = data[7];
  314. uint32_t data1 = data[6];
  315. uint32_t data2 = data[5];
  316. uint32_t data3 = data[4];
  317. count = data0 + (data1 << 8) + (data2 << 16) + (data3 << 24);
  318. xysnc_camera_sync_data_t camera_sync_data;
  319. camera_sync_data.frameIndex = count;
  320. if (m_on_camera_sync_msg_cb) m_on_camera_sync_msg_cb(&camera_sync_data);
  321. }
  322. // xsync_stm32_action_generator_new_mac, //
  323. // xsync_stm32_action_factory_reset, //
  324. // xsync_stm32_action_Basic_reboot, //
  325. // xsync_stm32_action_storage_cfg,
  326. xs_error_code_t Xsync::Basic_generatorNewMac() { return doaction(xsync_stm32_action_generator_new_mac, 0, nullptr, 2000); }
  327. xs_error_code_t Xsync::Basic_factoryReset() { return doaction(xsync_stm32_action_factory_reset, 0, nullptr, 1000); }
  328. xs_error_code_t Xsync::Basic_reboot() { return doaction(xsync_stm32_action_Basic_reboot, 0, nullptr); }
  329. xs_error_code_t Xsync::storageConfig() { return doaction(xsync_stm32_action_storage_cfg, 0, nullptr, 1000); }
  330. xs_error_code_t Xsync::Basic_changeNetworkConfig(string ip, string mask, string gateway) {
  331. uint32_t ip32 = 0;
  332. uint32_t mask32 = 0;
  333. uint32_t gateway32 = 0;
  334. xs_error_code_t ecode;
  335. bool suc = false;
  336. ip32 = (uint32_t)ipToUint32(ip.c_str(), suc);
  337. if (!suc) return kxs_ec_param_error;
  338. mask32 = (uint32_t)ipToUint32(mask.c_str(), suc);
  339. if (!suc) return kxs_ec_param_error;
  340. gateway32 = (uint32_t)ipToUint32(gateway.c_str(), suc);
  341. if (!suc) return kxs_ec_param_error;
  342. uint32_t readbak = 0;
  343. ecode = reg_write(kxsync_reg_stm32_ip, ip32, readbak);
  344. if (ecode != kxs_ec_success) return ecode;
  345. ecode = reg_write(kxsync_reg_stm32_netmask, mask32, readbak);
  346. if (ecode != kxs_ec_success) return ecode;
  347. ecode = reg_write(kxsync_reg_stm32_gw, gateway32, readbak);
  348. if (ecode != kxs_ec_success) return ecode;
  349. ecode = storageConfig();
  350. if (ecode != kxs_ec_success) return ecode;
  351. return kxs_ec_success;
  352. }
  353. xs_error_code_t Xsync::Basic_clearXsyncCameraSyncIndexCount() {
  354. uint32_t readbak = 0;
  355. return reg_write(kxsync_reg_stm32_camera_sync_signal_count, 0, readbak);
  356. }
  357. xs_error_code_t Xsync::doaction(uint32_t action, uint32_t actionval, uint32_t *ackreturn, int32_t overtime_ms) {
  358. //
  359. uint32_t readbak = 0;
  360. xs_error_code_t ecode;
  361. ecode = reg_write(kxsync_reg_stm32_action_val0, actionval, readbak);
  362. if (ecode != kxs_ec_success) return ecode;
  363. ecode = reg_write(kxsync_reg_stm32_action0, action, readbak, overtime_ms);
  364. if (ecode != kxs_ec_success) return ecode;
  365. if (ackreturn) *ackreturn = readbak;
  366. return ecode;
  367. }
  368. /*******************************************************************************
  369. * TTLOutputModule *
  370. *******************************************************************************/
  371. // .reg0(reg_input_signal_select),
  372. // .reg1(reg_output_signal_select),
  373. // .reg2(reg_config),
  374. // .reg3(reg_pulse_mode_valid_len),
  375. // .reg4(reg_pulse_mode_trigger_delay)
  376. xs_error_code_t Xsync::TTLOutputModule_getRegOff(int32_t index, uint32_t &regadd) {
  377. switch (index) {
  378. case 1:
  379. regadd = REG_ADD_OFF_TTLOUT1;
  380. break;
  381. case 2:
  382. regadd = REG_ADD_OFF_TTLOUT2;
  383. break;
  384. case 3:
  385. regadd = REG_ADD_OFF_TTLOUT3;
  386. break;
  387. case 4:
  388. regadd = REG_ADD_OFF_TTLOUT4;
  389. break;
  390. default:
  391. return kxs_ec_param_error;
  392. }
  393. return kxs_ec_success;
  394. }
  395. xs_error_code_t Xsync::TTLOutputModule_setInputSigType(int32_t index, ttlout_module::TriggerSigType_t source) {
  396. uint32_t regadd = REG_ADD_OFF_TTLOUT1;
  397. xs_error_code_t ecode = kxs_ec_success;
  398. uint32_t readbak = 0;
  399. ecode = TTLOutputModule_getRegOff(index, regadd);
  400. if (ecode != kxs_ec_success) return ecode;
  401. return reg_write(regadd + 0, source, readbak, 10);
  402. }
  403. xs_error_code_t Xsync::TTLOutputModule_getInputSigType(int32_t index, ttlout_module::TriggerSigType_t &source) {
  404. uint32_t regadd = REG_ADD_OFF_TTLOUT1;
  405. xs_error_code_t ecode = kxs_ec_success;
  406. uint32_t readbak = 0;
  407. ecode = TTLOutputModule_getRegOff(index, regadd);
  408. if (ecode != kxs_ec_success) return ecode;
  409. ecode = reg_read(regadd + 0, readbak, 10);
  410. if (ecode != kxs_ec_success) return ecode;
  411. source = (ttlout_module::TriggerSigType_t)readbak;
  412. return ecode;
  413. }
  414. xs_error_code_t Xsync::TTLOutputModule_setOutputSigType(int32_t index, ttlout_module::OutputSigType_t output_type) {
  415. uint32_t regadd = REG_ADD_OFF_TTLOUT1;
  416. xs_error_code_t ecode = kxs_ec_success;
  417. uint32_t readbak = 0;
  418. ecode = TTLOutputModule_getRegOff(index, regadd);
  419. if (ecode != kxs_ec_success) return ecode;
  420. return reg_write(regadd + 1, output_type, readbak, 10);
  421. }
  422. xs_error_code_t Xsync::TTLOutputModule_getOutputSigType(int32_t index, ttlout_module::OutputSigType_t &output_type) {
  423. uint32_t regadd = REG_ADD_OFF_TTLOUT1;
  424. xs_error_code_t ecode = kxs_ec_success;
  425. uint32_t readbak = 0;
  426. ecode = TTLOutputModule_getRegOff(index, regadd);
  427. if (ecode != kxs_ec_success) return ecode;
  428. ecode = reg_read(regadd + 1, readbak, 10);
  429. if (ecode != kxs_ec_success) return ecode;
  430. output_type = (ttlout_module::OutputSigType_t)readbak;
  431. return ecode;
  432. }
  433. xs_error_code_t Xsync::TTLOutputModule_setTriggerModePulseWidth(int32_t index, uint32_t pulse_width_ms) {
  434. uint32_t regadd = REG_ADD_OFF_TTLOUT1;
  435. xs_error_code_t ecode = kxs_ec_success;
  436. uint32_t readbak = 0;
  437. ecode = TTLOutputModule_getRegOff(index, regadd);
  438. if (ecode != kxs_ec_success) return ecode;
  439. uint32_t pluse_width = pulse_width_ms * 1000; // 1MHZ计数
  440. return reg_write(regadd + 3, pluse_width, readbak, 10);
  441. }
  442. xs_error_code_t Xsync::TTLOutputModule_getTriggerModePulseWidth(int32_t index, uint32_t &pulse_width_ms) {
  443. uint32_t regadd = REG_ADD_OFF_TTLOUT1;
  444. xs_error_code_t ecode = kxs_ec_success;
  445. uint32_t readbak = 0;
  446. ecode = TTLOutputModule_getRegOff(index, regadd);
  447. if (ecode != kxs_ec_success) return ecode;
  448. ecode = reg_read(regadd + 3, readbak, 10);
  449. if (ecode != kxs_ec_success) return ecode;
  450. pulse_width_ms = readbak / 1000;
  451. return ecode;
  452. }
  453. xs_error_code_t Xsync::TTLOutputModule_setTriggerModePulseDelay(int32_t index, uint32_t pulse_delay_ms) {
  454. uint32_t regadd = REG_ADD_OFF_TTLOUT1;
  455. xs_error_code_t ecode = kxs_ec_success;
  456. uint32_t readbak = 0;
  457. ecode = TTLOutputModule_getRegOff(index, regadd);
  458. if (ecode != kxs_ec_success) return ecode;
  459. uint32_t pulse_delay = pulse_delay_ms * 1000; // 1MHZ计数
  460. return reg_write(regadd + 4, pulse_delay, readbak, 10);
  461. }
  462. xs_error_code_t Xsync::TTLOutputModule_getTriggerModePulseDelay(int32_t index, uint32_t &pulse_delay_ms) {
  463. uint32_t regadd = REG_ADD_OFF_TTLOUT1;
  464. xs_error_code_t ecode = kxs_ec_success;
  465. uint32_t readbak = 0;
  466. ecode = TTLOutputModule_getRegOff(index, regadd);
  467. if (ecode != kxs_ec_success) return ecode;
  468. ecode = reg_read(regadd + 4, readbak, 10);
  469. if (ecode != kxs_ec_success) return ecode;
  470. pulse_delay_ms = readbak / 1000;
  471. return ecode;
  472. }