protocol.c 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299
  1. /*
  2. * This file is part of the libsigrok project.
  3. *
  4. * Copyright (C) 2012 Bert Vermeulen <bert@biot.com>
  5. *
  6. * This program is free software: you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License as published by
  8. * the Free Software Foundation, either version 3 of the License, or
  9. * (at your option) any later version.
  10. *
  11. * This program is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License
  17. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  18. */
  19. #include <glib.h>
  20. #include <string.h>
  21. #include <math.h>
  22. #include "libsigrok.h"
  23. #include "libsigrok-internal.h"
  24. #include "protocol.h"
  25. /* Reverse the high nibble into the low nibble */
  26. static uint8_t decode_digit(uint8_t in)
  27. {
  28. uint8_t out, i;
  29. out = 0;
  30. in >>= 4;
  31. for (i = 0x08; i; i >>= 1) {
  32. out >>= 1;
  33. if (in & i)
  34. out |= 0x08;
  35. }
  36. return out;
  37. }
  38. static void decode_buf(struct sr_dev_inst *sdi, unsigned char *data)
  39. {
  40. struct sr_datafeed_packet packet;
  41. struct sr_datafeed_analog analog;
  42. struct dev_context *devc;
  43. long factor, ivalue;
  44. uint8_t digits[4];
  45. gboolean is_duty, is_continuity, is_diode, is_ac, is_dc, is_auto;
  46. gboolean is_hold, is_max, is_min, is_relative, minus;
  47. float fvalue;
  48. devc = sdi->priv;
  49. digits[0] = decode_digit(data[12]);
  50. digits[1] = decode_digit(data[11]);
  51. digits[2] = decode_digit(data[10]);
  52. digits[3] = decode_digit(data[9]);
  53. if (digits[0] == 0x0f && digits[1] == 0x00 && digits[2] == 0x0a &&
  54. digits[3] == 0x0f)
  55. /* The "over limit" (OL) display comes through like this */
  56. ivalue = -1;
  57. else if (digits[0] > 9 || digits[1] > 9 || digits[2] > 9 || digits[3] > 9)
  58. /* An invalid digit in any position denotes no value. */
  59. ivalue = -2;
  60. else {
  61. ivalue = digits[0] * 1000;
  62. ivalue += digits[1] * 100;
  63. ivalue += digits[2] * 10;
  64. ivalue += digits[3];
  65. }
  66. /* Decimal point position */
  67. factor = 0;
  68. switch (data[7] >> 4) {
  69. case 0x00:
  70. factor = 0;
  71. break;
  72. case 0x02:
  73. factor = 1;
  74. break;
  75. case 0x04:
  76. factor = 2;
  77. break;
  78. case 0x08:
  79. factor = 3;
  80. break;
  81. default:
  82. sr_err("Unknown decimal point byte: 0x%.2x.", data[7]);
  83. break;
  84. }
  85. /* Minus flag */
  86. minus = data[2] & 0x01;
  87. /* Mode detail symbols on the right side of the digits */
  88. is_duty = is_continuity = is_diode = FALSE;
  89. switch (data[4]) {
  90. case 0x00:
  91. /* None. */
  92. break;
  93. case 0x01:
  94. /* Micro */
  95. factor += 6;
  96. break;
  97. case 0x02:
  98. /* Milli */
  99. factor += 3;
  100. break;
  101. case 0x04:
  102. /* Kilo */
  103. ivalue *= 1000;
  104. break;
  105. case 0x08:
  106. /* Mega */
  107. ivalue *= 1000000;
  108. break;
  109. case 0x10:
  110. /* Continuity shows up as Ohm + this bit */
  111. is_continuity = TRUE;
  112. break;
  113. case 0x20:
  114. /* Diode tester is Volt + this bit */
  115. is_diode = TRUE;
  116. break;
  117. case 0x40:
  118. is_duty = TRUE;
  119. break;
  120. case 0x80:
  121. /* Never seen */
  122. sr_dbg("Unknown mode right detail: 0x%.2x.", data[4]);
  123. break;
  124. default:
  125. sr_dbg("Unknown/invalid mode right detail: 0x%.2x.", data[4]);
  126. break;
  127. }
  128. /* Scale flags on the right, continued */
  129. is_max = is_min = FALSE;
  130. if (data[5] & 0x04)
  131. is_max = TRUE;
  132. if (data[5] & 0x08)
  133. is_min = TRUE;
  134. if (data[5] & 0x40)
  135. /* Nano */
  136. factor += 9;
  137. /* Mode detail symbols on the left side of the digits */
  138. is_auto = is_dc = is_ac = is_hold = is_relative = FALSE;
  139. if (data[6] & 0x04)
  140. is_auto = TRUE;
  141. if (data[6] & 0x08)
  142. is_dc = TRUE;
  143. if (data[6] & 0x10)
  144. is_ac = TRUE;
  145. if (data[6] & 0x20)
  146. is_relative = TRUE;
  147. if (data[6] & 0x40)
  148. is_hold = TRUE;
  149. fvalue = (float)ivalue / pow(10, factor);
  150. if (minus)
  151. fvalue = -fvalue;
  152. memset(&analog, 0, sizeof(struct sr_datafeed_analog));
  153. /* Measurement mode */
  154. analog.mq = -1;
  155. switch (data[3]) {
  156. case 0x00:
  157. if (is_duty) {
  158. analog.mq = SR_MQ_DUTY_CYCLE;
  159. analog.unit = SR_UNIT_PERCENTAGE;
  160. } else
  161. sr_dbg("Unknown measurement mode: %.2x.", data[3]);
  162. break;
  163. case 0x01:
  164. if (is_diode) {
  165. analog.mq = SR_MQ_VOLTAGE;
  166. analog.unit = SR_UNIT_VOLT;
  167. analog.mqflags |= SR_MQFLAG_DIODE;
  168. if (ivalue < 0)
  169. fvalue = NAN;
  170. } else {
  171. if (ivalue < 0)
  172. break;
  173. analog.mq = SR_MQ_VOLTAGE;
  174. analog.unit = SR_UNIT_VOLT;
  175. if (is_ac)
  176. analog.mqflags |= SR_MQFLAG_AC;
  177. if (is_dc)
  178. analog.mqflags |= SR_MQFLAG_DC;
  179. }
  180. break;
  181. case 0x02:
  182. analog.mq = SR_MQ_CURRENT;
  183. analog.unit = SR_UNIT_AMPERE;
  184. if (is_ac)
  185. analog.mqflags |= SR_MQFLAG_AC;
  186. if (is_dc)
  187. analog.mqflags |= SR_MQFLAG_DC;
  188. break;
  189. case 0x04:
  190. if (is_continuity) {
  191. analog.mq = SR_MQ_CONTINUITY;
  192. analog.unit = SR_UNIT_BOOLEAN;
  193. fvalue = ivalue < 0 ? 0.0 : 1.0;
  194. } else {
  195. analog.mq = SR_MQ_RESISTANCE;
  196. analog.unit = SR_UNIT_OHM;
  197. if (ivalue < 0)
  198. fvalue = INFINITY;
  199. }
  200. break;
  201. case 0x08:
  202. /* Never seen */
  203. sr_dbg("Unknown measurement mode: 0x%.2x.", data[3]);
  204. break;
  205. case 0x10:
  206. analog.mq = SR_MQ_FREQUENCY;
  207. analog.unit = SR_UNIT_HERTZ;
  208. break;
  209. case 0x20:
  210. analog.mq = SR_MQ_CAPACITANCE;
  211. analog.unit = SR_UNIT_FARAD;
  212. break;
  213. case 0x40:
  214. analog.mq = SR_MQ_TEMPERATURE;
  215. analog.unit = SR_UNIT_CELSIUS;
  216. break;
  217. case 0x80:
  218. analog.mq = SR_MQ_TEMPERATURE;
  219. analog.unit = SR_UNIT_FAHRENHEIT;
  220. break;
  221. default:
  222. sr_dbg("Unknown/invalid measurement mode: 0x%.2x.", data[3]);
  223. break;
  224. }
  225. if (analog.mq == -1)
  226. return;
  227. if (is_auto)
  228. analog.mqflags |= SR_MQFLAG_AUTORANGE;
  229. if (is_hold)
  230. analog.mqflags |= SR_MQFLAG_HOLD;
  231. if (is_max)
  232. analog.mqflags |= SR_MQFLAG_MAX;
  233. if (is_min)
  234. analog.mqflags |= SR_MQFLAG_MIN;
  235. if (is_relative)
  236. analog.mqflags |= SR_MQFLAG_RELATIVE;
  237. analog.channels = sdi->channels;
  238. analog.num_samples = 1;
  239. analog.data = &fvalue;
  240. packet.type = SR_DF_ANALOG;
  241. packet.payload = &analog;
  242. sr_session_send(devc->cb_data, &packet);
  243. devc->num_samples++;
  244. }
  245. SR_PRIV int victor_dmm_receive_data(struct sr_dev_inst *sdi, unsigned char *buf)
  246. {
  247. GString *dbg;
  248. int i;
  249. unsigned char data[DMM_DATA_SIZE];
  250. unsigned char obfuscation[DMM_DATA_SIZE] = "jodenxunickxia";
  251. unsigned char shuffle[DMM_DATA_SIZE] = {
  252. 6, 13, 5, 11, 2, 7, 9, 8, 3, 10, 12, 0, 4, 1
  253. };
  254. for (i = 0; i < DMM_DATA_SIZE && buf[i] == 0; i++);
  255. if (i == DMM_DATA_SIZE) {
  256. /* This DMM outputs all zeroes from time to time, just ignore it. */
  257. sr_dbg("Received all zeroes.");
  258. return SR_OK;
  259. }
  260. /* Deobfuscate and reorder data. */
  261. for (i = 0; i < DMM_DATA_SIZE; i++)
  262. data[shuffle[i]] = (buf[i] - obfuscation[i]) & 0xff;
  263. if (sr_log_loglevel_get() >= SR_LOG_SPEW) {
  264. dbg = g_string_sized_new(128);
  265. g_string_printf(dbg, "Deobfuscated.");
  266. for (i = 0; i < DMM_DATA_SIZE; i++)
  267. g_string_append_printf(dbg, " %.2x", data[i]);
  268. sr_spew("%s", dbg->str);
  269. g_string_free(dbg, TRUE);
  270. }
  271. decode_buf(sdi, data);
  272. return SR_OK;
  273. }