api.c 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633
  1. /*
  2. * This file is part of the libsigrok project.
  3. *
  4. * Copyright (C) 2012 Bert Vermeulen <bert@biot.com>
  5. * Copyright (C) 2012 Alexandru Gagniuc <mr.nuke.me@gmail.com>
  6. * Copyright (C) 2012 Uwe Hermann <uwe@hermann-uwe.de>
  7. *
  8. * This program is free software: you can redistribute it and/or modify
  9. * it under the terms of the GNU General Public License as published by
  10. * the Free Software Foundation, either version 3 of the License, or
  11. * (at your option) any later version.
  12. *
  13. * This program is distributed in the hope that it will be useful,
  14. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. * GNU General Public License for more details.
  17. *
  18. * You should have received a copy of the GNU General Public License
  19. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  20. */
  21. #include <sys/types.h>
  22. #include <sys/stat.h>
  23. #include <fcntl.h>
  24. #include <string.h>
  25. #include <errno.h>
  26. #include <glib.h>
  27. #include "libsigrok.h"
  28. #include "libsigrok-internal.h"
  29. #include "protocol.h"
  30. static const int32_t hwopts[] = {
  31. SR_CONF_CONN,
  32. SR_CONF_SERIALCOMM,
  33. };
  34. static const int32_t hwcaps[] = {
  35. SR_CONF_MULTIMETER,
  36. SR_CONF_LIMIT_SAMPLES,
  37. SR_CONF_LIMIT_MSEC,
  38. SR_CONF_CONTINUOUS,
  39. };
  40. SR_PRIV struct sr_dev_driver bbcgm_m2110_driver_info;
  41. SR_PRIV struct sr_dev_driver digitek_dt4000zc_driver_info;
  42. SR_PRIV struct sr_dev_driver tekpower_tp4000zc_driver_info;
  43. SR_PRIV struct sr_dev_driver metex_me31_driver_info;
  44. SR_PRIV struct sr_dev_driver peaktech_3410_driver_info;
  45. SR_PRIV struct sr_dev_driver mastech_mas345_driver_info;
  46. SR_PRIV struct sr_dev_driver va_va18b_driver_info;
  47. SR_PRIV struct sr_dev_driver va_va40b_driver_info;
  48. SR_PRIV struct sr_dev_driver metex_m3640d_driver_info;
  49. SR_PRIV struct sr_dev_driver metex_m4650cr_driver_info;
  50. SR_PRIV struct sr_dev_driver peaktech_4370_driver_info;
  51. SR_PRIV struct sr_dev_driver pce_pce_dm32_driver_info;
  52. SR_PRIV struct sr_dev_driver radioshack_22_168_driver_info;
  53. SR_PRIV struct sr_dev_driver radioshack_22_805_driver_info;
  54. SR_PRIV struct sr_dev_driver radioshack_22_812_driver_info;
  55. SR_PRIV struct sr_dev_driver tecpel_dmm_8061_ser_driver_info;
  56. SR_PRIV struct sr_dev_driver voltcraft_m3650cr_driver_info;
  57. SR_PRIV struct sr_dev_driver voltcraft_m3650d_driver_info;
  58. SR_PRIV struct sr_dev_driver voltcraft_m4650cr_driver_info;
  59. SR_PRIV struct sr_dev_driver voltcraft_me42_driver_info;
  60. SR_PRIV struct sr_dev_driver voltcraft_vc820_ser_driver_info;
  61. SR_PRIV struct sr_dev_driver voltcraft_vc830_ser_driver_info;
  62. SR_PRIV struct sr_dev_driver voltcraft_vc840_ser_driver_info;
  63. SR_PRIV struct sr_dev_driver uni_t_ut60a_ser_driver_info;
  64. SR_PRIV struct sr_dev_driver uni_t_ut60e_ser_driver_info;
  65. SR_PRIV struct sr_dev_driver uni_t_ut60g_ser_driver_info;
  66. SR_PRIV struct sr_dev_driver uni_t_ut61b_ser_driver_info;
  67. SR_PRIV struct sr_dev_driver uni_t_ut61c_ser_driver_info;
  68. SR_PRIV struct sr_dev_driver uni_t_ut61d_ser_driver_info;
  69. SR_PRIV struct sr_dev_driver uni_t_ut61e_ser_driver_info;
  70. SR_PRIV struct sr_dev_driver iso_tech_idm103n_driver_info;
  71. SR_PRIV struct sr_dev_driver tenma_72_7745_ser_driver_info;
  72. SR_PRIV struct sr_dev_driver tenma_72_7750_ser_driver_info;
  73. SR_PRIV struct dmm_info dmms[] = {
  74. {
  75. "BBC Goertz Metrawatt", "M2110", "1200/7n2", 1200,
  76. BBCGM_M2110_PACKET_SIZE, NULL,
  77. sr_m2110_packet_valid, sr_m2110_parse,
  78. NULL,
  79. &bbcgm_m2110_driver_info, receive_data_BBCGM_M2110,
  80. },
  81. {
  82. "Digitek", "DT4000ZC", "2400/8n1/dtr=1", 2400,
  83. FS9721_PACKET_SIZE, NULL,
  84. sr_fs9721_packet_valid, sr_fs9721_parse,
  85. sr_fs9721_10_temp_c,
  86. &digitek_dt4000zc_driver_info, receive_data_DIGITEK_DT4000ZC,
  87. },
  88. {
  89. "TekPower", "TP4000ZC", "2400/8n1/dtr=1", 2400,
  90. FS9721_PACKET_SIZE, NULL,
  91. sr_fs9721_packet_valid, sr_fs9721_parse,
  92. sr_fs9721_10_temp_c,
  93. &tekpower_tp4000zc_driver_info, receive_data_TEKPOWER_TP4000ZC,
  94. },
  95. {
  96. "Metex", "ME-31", "600/7n2/rts=0/dtr=1", 600,
  97. METEX14_PACKET_SIZE, sr_metex14_packet_request,
  98. sr_metex14_packet_valid, sr_metex14_parse,
  99. NULL,
  100. &metex_me31_driver_info, receive_data_METEX_ME31,
  101. },
  102. {
  103. "Peaktech", "3410", "600/7n2/rts=0/dtr=1", 600,
  104. METEX14_PACKET_SIZE, sr_metex14_packet_request,
  105. sr_metex14_packet_valid, sr_metex14_parse,
  106. NULL,
  107. &peaktech_3410_driver_info, receive_data_PEAKTECH_3410,
  108. },
  109. {
  110. "MASTECH", "MAS345", "600/7n2/rts=0/dtr=1", 600,
  111. METEX14_PACKET_SIZE, sr_metex14_packet_request,
  112. sr_metex14_packet_valid, sr_metex14_parse,
  113. NULL,
  114. &mastech_mas345_driver_info, receive_data_MASTECH_MAS345,
  115. },
  116. {
  117. "V&A", "VA18B", "2400/8n1", 2400,
  118. FS9721_PACKET_SIZE, NULL,
  119. sr_fs9721_packet_valid, sr_fs9721_parse,
  120. sr_fs9721_01_temp_c,
  121. &va_va18b_driver_info, receive_data_VA_VA18B,
  122. },
  123. {
  124. "V&A", "VA40B", "2400/8n1", 2400,
  125. FS9721_PACKET_SIZE, NULL,
  126. sr_fs9721_packet_valid, sr_fs9721_parse,
  127. sr_fs9721_max_c_min,
  128. &va_va40b_driver_info, receive_data_VA_VA40B,
  129. },
  130. {
  131. "Metex", "M-3640D", "1200/7n2/rts=0/dtr=1", 1200,
  132. METEX14_PACKET_SIZE, sr_metex14_packet_request,
  133. sr_metex14_packet_valid, sr_metex14_parse,
  134. NULL,
  135. &metex_m3640d_driver_info, receive_data_METEX_M3640D,
  136. },
  137. {
  138. "Metex", "M-4650CR", "1200/7n2/rts=0/dtr=1", 1200,
  139. METEX14_PACKET_SIZE, sr_metex14_packet_request,
  140. sr_metex14_packet_valid, sr_metex14_parse,
  141. NULL,
  142. &metex_m4650cr_driver_info, receive_data_METEX_M4650CR,
  143. },
  144. {
  145. "PeakTech", "4370", "1200/7n2/rts=0/dtr=1", 1200,
  146. METEX14_PACKET_SIZE, sr_metex14_packet_request,
  147. sr_metex14_packet_valid, sr_metex14_parse,
  148. NULL,
  149. &peaktech_4370_driver_info, receive_data_PEAKTECH_4370,
  150. },
  151. {
  152. "PCE", "PCE-DM32", "2400/8n1", 2400,
  153. FS9721_PACKET_SIZE, NULL,
  154. sr_fs9721_packet_valid, sr_fs9721_parse,
  155. sr_fs9721_01_10_temp_f_c,
  156. &pce_pce_dm32_driver_info, receive_data_PCE_PCE_DM32,
  157. },
  158. {
  159. "RadioShack", "22-168", "1200/7n2/rts=0/dtr=1", 1200,
  160. METEX14_PACKET_SIZE, sr_metex14_packet_request,
  161. sr_metex14_packet_valid, sr_metex14_parse,
  162. NULL,
  163. &radioshack_22_168_driver_info, receive_data_RADIOSHACK_22_168,
  164. },
  165. {
  166. "RadioShack", "22-805", "600/7n2/rts=0/dtr=1", 600,
  167. METEX14_PACKET_SIZE, sr_metex14_packet_request,
  168. sr_metex14_packet_valid, sr_metex14_parse,
  169. NULL,
  170. &radioshack_22_805_driver_info, receive_data_RADIOSHACK_22_805,
  171. },
  172. {
  173. "RadioShack", "22-812", "4800/8n1/rts=0/dtr=1", 4800,
  174. RS9LCD_PACKET_SIZE, NULL,
  175. sr_rs9lcd_packet_valid, sr_rs9lcd_parse,
  176. NULL,
  177. &radioshack_22_812_driver_info, receive_data_RADIOSHACK_22_812,
  178. },
  179. {
  180. "Tecpel", "DMM-8061 (UT-D02 cable)", "2400/8n1/rts=0/dtr=1",
  181. 2400, FS9721_PACKET_SIZE, NULL,
  182. sr_fs9721_packet_valid, sr_fs9721_parse,
  183. sr_fs9721_00_temp_c,
  184. &tecpel_dmm_8061_ser_driver_info,
  185. receive_data_TECPEL_DMM_8061_SER,
  186. },
  187. {
  188. "Voltcraft", "M-3650CR", "1200/7n2/rts=0/dtr=1", 1200,
  189. METEX14_PACKET_SIZE, sr_metex14_packet_request,
  190. sr_metex14_packet_valid, sr_metex14_parse,
  191. NULL,
  192. &voltcraft_m3650cr_driver_info, receive_data_VOLTCRAFT_M3650CR,
  193. },
  194. {
  195. "Voltcraft", "M-3650D", "1200/7n2/rts=0/dtr=1", 1200,
  196. METEX14_PACKET_SIZE, sr_metex14_packet_request,
  197. sr_metex14_packet_valid, sr_metex14_parse,
  198. NULL,
  199. &voltcraft_m3650d_driver_info, receive_data_VOLTCRAFT_M3650D,
  200. },
  201. {
  202. "Voltcraft", "M-4650CR", "1200/7n2/rts=0/dtr=1", 1200,
  203. METEX14_PACKET_SIZE, sr_metex14_packet_request,
  204. sr_metex14_packet_valid, sr_metex14_parse,
  205. NULL,
  206. &voltcraft_m4650cr_driver_info, receive_data_VOLTCRAFT_M4650CR,
  207. },
  208. {
  209. "Voltcraft", "ME-42", "600/7n2/rts=0/dtr=1", 600,
  210. METEX14_PACKET_SIZE, sr_metex14_packet_request,
  211. sr_metex14_packet_valid, sr_metex14_parse,
  212. NULL,
  213. &voltcraft_me42_driver_info, receive_data_VOLTCRAFT_ME42,
  214. },
  215. {
  216. "Voltcraft", "VC-820 (UT-D02 cable)", "2400/8n1/rts=0/dtr=1",
  217. 2400, FS9721_PACKET_SIZE, NULL,
  218. sr_fs9721_packet_valid, sr_fs9721_parse,
  219. NULL,
  220. &voltcraft_vc820_ser_driver_info,
  221. receive_data_VOLTCRAFT_VC820_SER,
  222. },
  223. {
  224. /*
  225. * Note: The VC830 doesn't set the 'volt' and 'diode' bits of
  226. * the FS9922 protocol. Instead, it only sets the user-defined
  227. * bit "z1" to indicate "diode mode" and "voltage".
  228. */
  229. "Voltcraft", "VC-830 (UT-D02 cable)", "2400/8n1/rts=0/dtr=1",
  230. 2400, FS9922_PACKET_SIZE, NULL,
  231. sr_fs9922_packet_valid, sr_fs9922_parse,
  232. &sr_fs9922_z1_diode,
  233. &voltcraft_vc830_ser_driver_info,
  234. receive_data_VOLTCRAFT_VC830_SER,
  235. },
  236. {
  237. "Voltcraft", "VC-840 (UT-D02 cable)", "2400/8n1/rts=0/dtr=1",
  238. 2400, FS9721_PACKET_SIZE, NULL,
  239. sr_fs9721_packet_valid, sr_fs9721_parse,
  240. sr_fs9721_00_temp_c,
  241. &voltcraft_vc840_ser_driver_info,
  242. receive_data_VOLTCRAFT_VC840_SER,
  243. },
  244. {
  245. "UNI-T", "UT60A (UT-D02 cable)", "2400/8n1/rts=0/dtr=1",
  246. 2400, FS9721_PACKET_SIZE, NULL,
  247. sr_fs9721_packet_valid, sr_fs9721_parse,
  248. NULL,
  249. &uni_t_ut60a_ser_driver_info,
  250. receive_data_UNI_T_UT60A_SER,
  251. },
  252. {
  253. "UNI-T", "UT60E (UT-D02 cable)", "2400/8n1/rts=0/dtr=1",
  254. 2400, FS9721_PACKET_SIZE, NULL,
  255. sr_fs9721_packet_valid, sr_fs9721_parse,
  256. sr_fs9721_00_temp_c,
  257. &uni_t_ut60e_ser_driver_info,
  258. receive_data_UNI_T_UT60E_SER,
  259. },
  260. {
  261. /* Note: ES51986 baudrate is actually 19230! */
  262. "UNI-T", "UT60G (UT-D02 cable)", "19200/7o1/rts=0/dtr=1",
  263. 19200, ES519XX_11B_PACKET_SIZE, NULL,
  264. sr_es519xx_19200_11b_packet_valid, sr_es519xx_19200_11b_parse,
  265. NULL,
  266. &uni_t_ut60g_ser_driver_info, receive_data_UNI_T_UT60G_SER,
  267. },
  268. {
  269. "UNI-T", "UT61B (UT-D02 cable)", "2400/8n1/rts=0/dtr=1",
  270. 2400, FS9922_PACKET_SIZE, NULL,
  271. sr_fs9922_packet_valid, sr_fs9922_parse, NULL,
  272. &uni_t_ut61b_ser_driver_info, receive_data_UNI_T_UT61B_SER,
  273. },
  274. {
  275. "UNI-T", "UT61C (UT-D02 cable)", "2400/8n1/rts=0/dtr=1",
  276. 2400, FS9922_PACKET_SIZE, NULL,
  277. sr_fs9922_packet_valid, sr_fs9922_parse, NULL,
  278. &uni_t_ut61c_ser_driver_info, receive_data_UNI_T_UT61C_SER,
  279. },
  280. {
  281. "UNI-T", "UT61D (UT-D02 cable)", "2400/8n1/rts=0/dtr=1",
  282. 2400, FS9922_PACKET_SIZE, NULL,
  283. sr_fs9922_packet_valid, sr_fs9922_parse, NULL,
  284. &uni_t_ut61d_ser_driver_info, receive_data_UNI_T_UT61D_SER,
  285. },
  286. {
  287. /* Note: ES51922 baudrate is actually 19230! */
  288. "UNI-T", "UT61E (UT-D02 cable)", "19200/7o1/rts=0/dtr=1",
  289. 19200, ES519XX_14B_PACKET_SIZE, NULL,
  290. sr_es519xx_19200_14b_packet_valid, sr_es519xx_19200_14b_parse,
  291. NULL,
  292. &uni_t_ut61e_ser_driver_info, receive_data_UNI_T_UT61E_SER,
  293. },
  294. {
  295. "ISO-TECH", "IDM103N", "2400/7o1/rts=0/dtr=1",
  296. 2400, ES519XX_11B_PACKET_SIZE, NULL,
  297. sr_es519xx_2400_11b_packet_valid, sr_es519xx_2400_11b_parse,
  298. NULL,
  299. &iso_tech_idm103n_driver_info, receive_data_ISO_TECH_IDM103N,
  300. },
  301. {
  302. "Tenma", "72-7745 (UT-D02 cable)", "2400/8n1/rts=0/dtr=1",
  303. 2400, FS9721_PACKET_SIZE, NULL,
  304. sr_fs9721_packet_valid, sr_fs9721_parse,
  305. sr_fs9721_00_temp_c,
  306. &tenma_72_7745_ser_driver_info, receive_data_TENMA_72_7745_SER,
  307. },
  308. {
  309. /* Note: ES51986 baudrate is actually 19230! */
  310. "Tenma", "72-7750 (UT-D02 cable)", "19200/7o1/rts=0/dtr=1",
  311. 19200, ES519XX_11B_PACKET_SIZE, NULL,
  312. sr_es519xx_19200_11b_packet_valid, sr_es519xx_19200_11b_parse,
  313. NULL,
  314. &tenma_72_7750_ser_driver_info, receive_data_TENMA_72_7750_SER,
  315. },
  316. };
  317. static int dev_clear(int dmm)
  318. {
  319. return std_dev_clear(dmms[dmm].di, NULL);
  320. }
  321. static int init(struct sr_context *sr_ctx, int dmm)
  322. {
  323. sr_dbg("Selected '%s' subdriver.", dmms[dmm].di->name);
  324. return std_init(sr_ctx, dmms[dmm].di, LOG_PREFIX);
  325. }
  326. static GSList *sdmm_scan(const char *conn, const char *serialcomm, int dmm)
  327. {
  328. struct sr_dev_inst *sdi;
  329. struct drv_context *drvc;
  330. struct dev_context *devc;
  331. struct sr_channel *ch;
  332. struct sr_serial_dev_inst *serial;
  333. GSList *devices;
  334. int dropped, ret;
  335. size_t len;
  336. uint8_t buf[128];
  337. if (!(serial = sr_serial_dev_inst_new(conn, serialcomm)))
  338. return NULL;
  339. if (serial_open(serial, SERIAL_RDWR | SERIAL_NONBLOCK) != SR_OK)
  340. return NULL;
  341. sr_info("Probing serial port %s.", conn);
  342. drvc = dmms[dmm].di->priv;
  343. devices = NULL;
  344. serial_flush(serial);
  345. /* Request a packet if the DMM requires this. */
  346. if (dmms[dmm].packet_request) {
  347. if ((ret = dmms[dmm].packet_request(serial)) < 0) {
  348. sr_err("Failed to request packet: %d.", ret);
  349. return FALSE;
  350. }
  351. }
  352. /*
  353. * There's no way to get an ID from the multimeter. It just sends data
  354. * periodically (or upon request), so the best we can do is check if
  355. * the packets match the expected format.
  356. */
  357. /* Let's get a bit of data and see if we can find a packet. */
  358. len = sizeof(buf);
  359. ret = serial_stream_detect(serial, buf, &len, dmms[dmm].packet_size,
  360. dmms[dmm].packet_valid, 3000,
  361. dmms[dmm].baudrate);
  362. if (ret != SR_OK)
  363. goto scan_cleanup;
  364. /*
  365. * If we dropped more than two packets worth of data, something is
  366. * wrong. We shouldn't quit however, since the dropped bytes might be
  367. * just zeroes at the beginning of the stream. Those can occur as a
  368. * combination of the nonstandard cable that ships with some devices
  369. * and the serial port or USB to serial adapter.
  370. */
  371. dropped = len - dmms[dmm].packet_size;
  372. if (dropped > 2 * dmms[dmm].packet_size)
  373. sr_warn("Had to drop too much data.");
  374. sr_info("Found device on port %s.", conn);
  375. if (!(sdi = sr_dev_inst_new(0, SR_ST_INACTIVE, dmms[dmm].vendor,
  376. dmms[dmm].device, NULL)))
  377. goto scan_cleanup;
  378. if (!(devc = g_try_malloc0(sizeof(struct dev_context)))) {
  379. sr_err("Device context malloc failed.");
  380. goto scan_cleanup;
  381. }
  382. sdi->inst_type = SR_INST_SERIAL;
  383. sdi->conn = serial;
  384. sdi->priv = devc;
  385. sdi->driver = dmms[dmm].di;
  386. if (!(ch = sr_channel_new(0, SR_CHANNEL_ANALOG, TRUE, "P1")))
  387. goto scan_cleanup;
  388. sdi->channels = g_slist_append(sdi->channels, ch);
  389. drvc->instances = g_slist_append(drvc->instances, sdi);
  390. devices = g_slist_append(devices, sdi);
  391. scan_cleanup:
  392. serial_close(serial);
  393. return devices;
  394. }
  395. static GSList *scan(GSList *options, int dmm)
  396. {
  397. struct sr_config *src;
  398. GSList *l, *devices;
  399. const char *conn, *serialcomm;
  400. conn = serialcomm = NULL;
  401. for (l = options; l; l = l->next) {
  402. src = l->data;
  403. switch (src->key) {
  404. case SR_CONF_CONN:
  405. conn = g_variant_get_string(src->data, NULL);
  406. break;
  407. case SR_CONF_SERIALCOMM:
  408. serialcomm = g_variant_get_string(src->data, NULL);
  409. break;
  410. }
  411. }
  412. if (!conn)
  413. return NULL;
  414. if (serialcomm) {
  415. /* Use the provided comm specs. */
  416. devices = sdmm_scan(conn, serialcomm, dmm);
  417. } else {
  418. /* Try the default. */
  419. devices = sdmm_scan(conn, dmms[dmm].conn, dmm);
  420. }
  421. return devices;
  422. }
  423. static GSList *dev_list(int dmm)
  424. {
  425. return ((struct drv_context *)(dmms[dmm].di->priv))->instances;
  426. }
  427. static int cleanup(int dmm)
  428. {
  429. return dev_clear(dmm);
  430. }
  431. static int config_set(int id, GVariant *data, const struct sr_dev_inst *sdi,
  432. const struct sr_channel_group *cg)
  433. {
  434. struct dev_context *devc;
  435. (void)cg;
  436. if (sdi->status != SR_ST_ACTIVE)
  437. return SR_ERR_DEV_CLOSED;
  438. if (!(devc = sdi->priv)) {
  439. sr_err("sdi->priv was NULL.");
  440. return SR_ERR_BUG;
  441. }
  442. switch (id) {
  443. case SR_CONF_LIMIT_SAMPLES:
  444. devc->limit_samples = g_variant_get_uint64(data);
  445. sr_dbg("Setting sample limit to %" PRIu64 ".",
  446. devc->limit_samples);
  447. break;
  448. case SR_CONF_LIMIT_MSEC:
  449. devc->limit_msec = g_variant_get_uint64(data);
  450. sr_dbg("Setting time limit to %" PRIu64 "ms.",
  451. devc->limit_msec);
  452. break;
  453. default:
  454. return SR_ERR_NA;
  455. }
  456. return SR_OK;
  457. }
  458. static int config_list(int key, GVariant **data, const struct sr_dev_inst *sdi,
  459. const struct sr_channel_group *cg)
  460. {
  461. (void)sdi;
  462. (void)cg;
  463. switch (key) {
  464. case SR_CONF_SCAN_OPTIONS:
  465. *data = g_variant_new_fixed_array(G_VARIANT_TYPE_INT32,
  466. hwopts, ARRAY_SIZE(hwopts), sizeof(int32_t));
  467. break;
  468. case SR_CONF_DEVICE_OPTIONS:
  469. *data = g_variant_new_fixed_array(G_VARIANT_TYPE_INT32,
  470. hwcaps, ARRAY_SIZE(hwcaps), sizeof(int32_t));
  471. break;
  472. default:
  473. return SR_ERR_NA;
  474. }
  475. return SR_OK;
  476. }
  477. static int dev_acquisition_start(const struct sr_dev_inst *sdi,
  478. void *cb_data, int dmm)
  479. {
  480. struct dev_context *devc;
  481. struct sr_serial_dev_inst *serial;
  482. if (sdi->status != SR_ST_ACTIVE)
  483. return SR_ERR_DEV_CLOSED;
  484. if (!(devc = sdi->priv)) {
  485. sr_err("sdi->priv was NULL.");
  486. return SR_ERR_BUG;
  487. }
  488. devc->cb_data = cb_data;
  489. /*
  490. * Reset the number of samples to take. If we've already collected our
  491. * quota, but we start a new session, and don't reset this, we'll just
  492. * quit without acquiring any new samples.
  493. */
  494. devc->num_samples = 0;
  495. devc->starttime = g_get_monotonic_time();
  496. /* Send header packet to the session bus. */
  497. std_session_send_df_header(cb_data, LOG_PREFIX);
  498. /* Poll every 50ms, or whenever some data comes in. */
  499. serial = sdi->conn;
  500. serial_source_add(serial, G_IO_IN, 50,
  501. dmms[dmm].receive_data, (void *)sdi);
  502. return SR_OK;
  503. }
  504. static int dev_acquisition_stop(struct sr_dev_inst *sdi, void *cb_data)
  505. {
  506. return std_serial_dev_acquisition_stop(sdi, cb_data, std_serial_dev_close,
  507. sdi->conn, LOG_PREFIX);
  508. }
  509. /* Driver-specific API function wrappers */
  510. #define HW_INIT(X) \
  511. static int init_##X(struct sr_context *sr_ctx) { return init(sr_ctx, X); }
  512. #define HW_CLEANUP(X) \
  513. static int cleanup_##X(void) { return cleanup(X); }
  514. #define HW_SCAN(X) \
  515. static GSList *scan_##X(GSList *options) { return scan(options, X); }
  516. #define HW_DEV_LIST(X) \
  517. static GSList *dev_list_##X(void) { return dev_list(X); }
  518. #define HW_DEV_CLEAR(X) \
  519. static int dev_clear_##X(void) { return dev_clear(X); }
  520. #define HW_DEV_ACQUISITION_START(X) \
  521. static int dev_acquisition_start_##X(const struct sr_dev_inst *sdi, \
  522. void *cb_data) { return dev_acquisition_start(sdi, cb_data, X); }
  523. /* Driver structs and API function wrappers */
  524. #define DRV(ID, ID_UPPER, NAME, LONGNAME) \
  525. HW_INIT(ID_UPPER) \
  526. HW_CLEANUP(ID_UPPER) \
  527. HW_SCAN(ID_UPPER) \
  528. HW_DEV_LIST(ID_UPPER) \
  529. HW_DEV_CLEAR(ID_UPPER) \
  530. HW_DEV_ACQUISITION_START(ID_UPPER) \
  531. SR_PRIV struct sr_dev_driver ID##_driver_info = { \
  532. .name = NAME, \
  533. .longname = LONGNAME, \
  534. .api_version = 1, \
  535. .init = init_##ID_UPPER, \
  536. .cleanup = cleanup_##ID_UPPER, \
  537. .scan = scan_##ID_UPPER, \
  538. .dev_list = dev_list_##ID_UPPER, \
  539. .dev_clear = dev_clear_##ID_UPPER, \
  540. .config_get = NULL, \
  541. .config_set = config_set, \
  542. .config_list = config_list, \
  543. .dev_open = std_serial_dev_open, \
  544. .dev_close = std_serial_dev_close, \
  545. .dev_acquisition_start = dev_acquisition_start_##ID_UPPER, \
  546. .dev_acquisition_stop = dev_acquisition_stop, \
  547. .priv = NULL, \
  548. };
  549. DRV(bbcgm_m2110, BBCGM_M2110, "bbcgm-m2110", "BBC Goertz Metrawatt M2110")
  550. DRV(digitek_dt4000zc, DIGITEK_DT4000ZC, "digitek-dt4000zc", "Digitek DT4000ZC")
  551. DRV(tekpower_tp4000zc, TEKPOWER_TP4000ZC, "tekpower-tp4000zc", "TekPower TP4000ZC")
  552. DRV(metex_me31, METEX_ME31, "metex-me31", "Metex ME-31")
  553. DRV(peaktech_3410, PEAKTECH_3410, "peaktech-3410", "PeakTech 3410")
  554. DRV(mastech_mas345, MASTECH_MAS345, "mastech-mas345", "MASTECH MAS345")
  555. DRV(va_va18b, VA_VA18B, "va-va18b", "V&A VA18B")
  556. DRV(va_va40b, VA_VA40B, "va-va40b", "V&A VA40B")
  557. DRV(metex_m3640d, METEX_M3640D, "metex-m3640d", "Metex M-3640D")
  558. DRV(metex_m4650cr, METEX_M4650CR, "metex-m4650cr", "Metex M-4650CR")
  559. DRV(peaktech_4370, PEAKTECH_4370, "peaktech-4370", "PeakTech 4370")
  560. DRV(pce_pce_dm32, PCE_PCE_DM32, "pce-pce-dm32", "PCE PCE-DM32")
  561. DRV(radioshack_22_168, RADIOSHACK_22_168, "radioshack-22-168", "RadioShack 22-168")
  562. DRV(radioshack_22_805, RADIOSHACK_22_805, "radioshack-22-805", "RadioShack 22-805")
  563. DRV(radioshack_22_812, RADIOSHACK_22_812, "radioshack-22-812", "RadioShack 22-812")
  564. DRV(tecpel_dmm_8061_ser, TECPEL_DMM_8061_SER, "tecpel-dmm-8061-ser", "Tecpel DMM-8061 (UT-D02 cable)")
  565. DRV(voltcraft_m3650cr, VOLTCRAFT_M3650CR, "voltcraft-m3650cr", "Voltcraft M-3650CR")
  566. DRV(voltcraft_m3650d, VOLTCRAFT_M3650D, "voltcraft-m3650d", "Voltcraft M-3650D")
  567. DRV(voltcraft_m4650cr, VOLTCRAFT_M4650CR, "voltcraft-m4650cr", "Voltcraft M-4650CR")
  568. DRV(voltcraft_me42, VOLTCRAFT_ME42, "voltcraft-me42", "Voltcraft ME-42")
  569. DRV(voltcraft_vc820_ser, VOLTCRAFT_VC820_SER, "voltcraft-vc820-ser", "Voltcraft VC-820 (UT-D02 cable)")
  570. DRV(voltcraft_vc830_ser, VOLTCRAFT_VC830_SER, "voltcraft-vc830-ser", "Voltcraft VC-830 (UT-D02 cable)")
  571. DRV(voltcraft_vc840_ser, VOLTCRAFT_VC840_SER, "voltcraft-vc840-ser", "Voltcraft VC-840 (UT-D02 cable)")
  572. DRV(uni_t_ut60a_ser, UNI_T_UT60A_SER, "uni-t-ut60a-ser", "UNI-T UT60A (UT-D02 cable)")
  573. DRV(uni_t_ut60e_ser, UNI_T_UT60E_SER, "uni-t-ut60e-ser", "UNI-T UT60E (UT-D02 cable)")
  574. DRV(uni_t_ut60g_ser, UNI_T_UT60G_SER, "uni-t-ut60g-ser", "UNI-T UT60G (UT-D02 cable)")
  575. DRV(uni_t_ut61b_ser, UNI_T_UT61B_SER, "uni-t-ut61b-ser", "UNI-T UT61B (UT-D02 cable)")
  576. DRV(uni_t_ut61c_ser, UNI_T_UT61C_SER, "uni-t-ut61c-ser", "UNI-T UT61C (UT-D02 cable)")
  577. DRV(uni_t_ut61d_ser, UNI_T_UT61D_SER, "uni-t-ut61d-ser", "UNI-T UT61D (UT-D02 cable)")
  578. DRV(uni_t_ut61e_ser, UNI_T_UT61E_SER, "uni-t-ut61e-ser", "UNI-T UT61E (UT-D02 cable)")
  579. DRV(iso_tech_idm103n, ISO_TECH_IDM103N, "iso-tech-idm103n", "ISO-TECH IDM103N")
  580. DRV(tenma_72_7745_ser, TENMA_72_7745_SER, "tenma-72-7745-ser", "Tenma 72-7745 (UT-D02 cable)")
  581. DRV(tenma_72_7750_ser, TENMA_72_7750_SER, "tenma-72-7750-ser", "Tenma 72-7750 (UT-D02 cable)")