]> sigrok.org Git - libsigrok.git/blame - src/hardware/uni-t-ut181a/protocol.h
scpi-pps: don't break SCPI devices when scanning for HP-IB devices
[libsigrok.git] / src / hardware / uni-t-ut181a / protocol.h
CommitLineData
3094e9d8
GS
1/*
2 * This file is part of the libsigrok project.
3 *
ebc51109 4 * Copyright (C) 2019-2020 Gerhard Sittig <gerhard.sittig@gmx.net>
3094e9d8
GS
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
20#ifndef LIBSIGROK_HARDWARE_UNI_T_UT181A_PROTOCOL_H
21#define LIBSIGROK_HARDWARE_UNI_T_UT181A_PROTOCOL_H
22
3094e9d8
GS
23#include <glib.h>
24#include <libsigrok/libsigrok.h>
ebc51109
GS
25#include <stdint.h>
26
3094e9d8
GS
27#include "libsigrok-internal.h"
28
29#define LOG_PREFIX "uni-t-ut181a"
30
ebc51109
GS
31/*
32 * Optional features. Tunables.
33 */
34#define UT181A_WITH_TIMESTAMP 0
35#define UT181A_WITH_SER_ECHO 0
36
37/*
38 * The largest frame we expect to receive is chunked record data. Which
39 * can span up to 256 items which each occupy 9 bytes, plus some header
40 * before the items array. Be generous and prepare to receive several
41 * frames in a row, e.g. when synchronizing to the packet stream at the
42 * start of a session or after communication failure.
43 *
44 * The largest frame we expect to transmit is a "start record" command.
45 * Which contains 18 bytes of payload (plus 6 bytes of frame envelope).
46 */
47#define RECV_BUFF_SIZE 4096
48#define SEND_BUFF_SIZE 32
49#define SEND_TO_MS 100
50
51/*
52 * The device can hold several recordings, their number is under the
53 * user's control and dynamic at runtime. It's assumed that there is an
54 * absolute upper bound of 20 recordings at any time. Names are under
55 * user control, too (auto-preset, then editable), and a maximum label
56 * length is assumed from the protocol description.
57 *
58 * Update 2020-03-17
59 * Turns out that 20 is *not* the limit on the number of recordings.
60 * Nor do I believe that 20K or 10K is the limit. It may be the total
61 * of the number of recordings and their sample counts which may not
62 * exceed 10K, while saved measurements can be up to 20K? This is just
63 * a guess though, the "Operating Manual" does not specify a limit,
64 * nor does it discuss a dependency beyond mentioning the 10K/20K
65 * figures.
66 */
67#define MAX_REC_COUNT 20
68#define MAX_REC_NAMELEN 12
69
70#define MAX_RANGE_INDEX 8
71
72/* Literals look weird as numbers. LE format makes them readable on the wire. */
73#define FRAME_MAGIC 0xcdab /* Becomes the AB CD byte sequence. */
74#define REPLY_CODE_OK 0x4b4f /* Becomes the "OK" text. */
75#define REPLY_CODE_ERR 0x5245 /* Becomes the "ER" text. */
76
77enum ut181a_channel_idx {
78 UT181A_CH_MAIN,
79 UT181A_CH_AUX1,
80 UT181A_CH_AUX2,
81 UT181A_CH_AUX3,
82 UT181A_CH_BAR,
83#if UT181A_WITH_TIMESTAMP
84 UT181A_CH_TIME,
85#endif
86};
87
88enum ut181_cmd_code {
89 CMD_CODE_INVALID = 0x00,
90 CMD_CODE_SET_MODE = 0x01,
91 CMD_CODE_SET_RANGE = 0x02,
92 CMD_CODE_SET_REFERENCE = 0x03,
93 CMD_CODE_SET_MIN_MAX = 0x04,
94 CMD_CODE_SET_MONITOR = 0x05,
95 CMD_CODE_SAVE_MEAS = 0x06,
96 CMD_CODE_GET_SAVED_MEAS = 0x07,
97 CMD_CODE_GET_SAVED_COUNT = 0x08,
98 CMD_CODE_DEL_SAVED_MEAS = 0x09,
99 CMD_CODE_START_REC = 0x0a,
100 CMD_CODE_STOP_REC = 0x0b,
101 CMD_CODE_GET_REC_INFO = 0x0c,
102 CMD_CODE_GET_REC_SAMPLES = 0x0d,
103 CMD_CODE_GET_RECS_COUNT = 0x0e,
104 CMD_CODE_BTN_PRESS = 0x12,
105};
106
107enum ut181_rsp_type {
108 RSP_TYPE_REPLY_CODE = 0x01,
109 RSP_TYPE_MEASUREMENT = 0x02,
110 RSP_TYPE_SAVE = 0x03,
111 RSP_TYPE_REC_INFO = 0x04,
112 RSP_TYPE_REC_DATA = 0x05,
113 RSP_TYPE_REPLY_DATA = 0x72, /* 'r' */
114};
115
116/*
117 * TODO
118 * - See if there is a pattern to these number codes.
119 * - [3:0] == 2 relative mode (when available)
120 * - [7:4] == 3 peak mode aka max/min (when available)
121 * (but there is command 4 set max/min on/off too)
122 */
123
124enum ut181a_mode_code {
125 /* V AC */
126 MODE_V_AC = 0x1111,
127 MODE_V_AC_REL = 0x1112,
128 MODE_V_AC_Hz = 0x1121,
129 MODE_V_AC_PEAK = 0x1131,
130 MODE_V_AC_LOWPASS = 0x1141,
131 MODE_V_AC_LOWPASS_REL = 0x1142,
132 MODE_V_AC_dBV = 0x1151,
133 MODE_V_AC_dBV_REL = 0x1152,
134 MODE_V_AC_dBm = 0x1161,
135 MODE_V_AC_dBm_REL = 0x1162,
136 /* mV AC */
137 MODE_mV_AC = 0x2111,
138 MODE_mV_AC_REL = 0x2112,
139 MODE_mV_AC_Hz = 0x2121,
140 MODE_mV_AC_PEAK = 0x2131,
141 MODE_mV_AC_ACDC = 0x2141,
142 MODE_mV_AC_ACDC_REL = 0x2142,
143 /* V DC */
144 MODE_V_DC = 0x3111,
145 MODE_V_DC_REL = 0x3112,
146 MODE_V_DC_ACDC = 0x3121,
147 MODE_V_DC_ACDC_REL = 0x3122,
148 MODE_V_DC_PEAK = 0x3131,
149 /* mV DC */
150 MODE_mV_DC = 0x4111,
151 MODE_mV_DC_REL = 0x4112,
152 MODE_mV_DC_PEAK = 0x4121, /* TODO Check number code, is it 0x4131? */
153 /* temperature Celsius */
154 MODE_TEMP_C_T1_and_T2 = 0x4211,
155 MODE_TEMP_C_T1_and_T2_REL = 0x4212,
156 MODE_TEMP_C_T2_and_T1 = 0x4221,
157 MODE_TEMP_C_T2_and_T1_REL = 0x4222,
158 MODE_TEMP_C_T1_minus_T2 = 0x4231, /* XXX exception, not PEAK */
159 MODE_TEMP_C_T2_minus_T1 = 0x4241,
160 /* temperature Farenheit */
161 MODE_TEMP_F_T1_and_T2 = 0x4311,
162 MODE_TEMP_F_T1_and_T2_REL = 0x4312,
163 MODE_TEMP_F_T2_and_T1 = 0x4321,
164 MODE_TEMP_F_T2_and_T1_REL = 0x4322,
165 MODE_TEMP_F_T1_minus_T2 = 0x4331,
166 MODE_TEMP_F_T2_minus_T1 = 0x4341, /* XXX exception, not PEAK */
167 /* resistance, continuity, conductivity */
168 MODE_RES = 0x5111,
169 MODE_RES_REL = 0x5112,
170 MODE_CONT_SHORT = 0x5211,
171 MODE_CONT_OPEN = 0x5212,
172 MODE_COND = 0x5311,
173 MODE_COND_REL = 0x5312,
174 /* diode, capacitance */
175 MODE_DIODE = 0x6111,
176 MODE_DIODE_ALARM = 0x6112, /* XXX exception, not REL */
177 MODE_CAP = 0x6211,
178 MODE_CAP_REL = 0x6212,
179 /* frequency, duty cycle, pulse width */
180 MODE_FREQ = 0x7111,
181 MODE_FREQ_REL = 0x7112,
182 MODE_DUTY = 0x7211,
183 MODE_DUTY_REL = 0x7212,
184 MODE_PULSEWIDTH = 0x7311,
185 MODE_PULSEWIDTH_REL = 0x7312,
186 /* uA DC */
187 MODE_uA_DC = 0x8111,
188 MODE_uA_DC_REL = 0x8112,
189 MODE_uA_DC_ACDC = 0x8121,
190 MODE_uA_DC_ACDC_REL = 0x8122,
191 MODE_uA_DC_PEAK = 0x8131,
192 /* uA AC */
193 MODE_uA_AC = 0x8211,
194 MODE_uA_AC_REL = 0x8212,
195 MODE_uA_AC_Hz = 0x8221,
196 MODE_uA_AC_PEAK = 0x8231,
197 /* mA DC */
198 MODE_mA_DC = 0x9111,
199 MODE_mA_DC_REL = 0x9112,
200 MODE_mA_DC_ACDC = 0x9121,
201 MODE_mA_DC_ACDC_REL = 0x9122,
202 MODE_mA_DC_ACDC_PEAK = 0x9131,
203 /* mA AC */
204 MODE_mA_AC = 0x9211,
205 MODE_mA_AC_REL = 0x9212,
206 MODE_mA_AC_Hz = 0x9221,
207 MODE_mA_AC_PEAK = 0x9231,
208 /* A DC */
209 MODE_A_DC = 0xa111,
210 MODE_A_DC_REL = 0xa112,
211 MODE_A_DC_ACDC = 0xa121,
212 MODE_A_DC_ACDC_REL = 0xa122,
213 MODE_A_DC_PEAK = 0xa131,
214 /* A AC */
215 MODE_A_AC = 0xa211,
216 MODE_A_AC_REL = 0xa212,
217 MODE_A_AC_Hz = 0xa221,
218 MODE_A_AC_PEAK = 0xa231,
219};
220
221/* Maximum number of UT181A modes which map to one MQ item. */
222#define MODE_COUNT_PER_MQ_MQF 15
223
224struct mqopt_item {
225 enum sr_mq mq;
226 enum sr_mqflag mqflags;
227 enum ut181a_mode_code modes[MODE_COUNT_PER_MQ_MQF];
228};
229
230struct mq_scale_params {
231 int scale;
232 enum sr_mq mq;
233 enum sr_mqflag mqflags;
234 enum sr_unit unit;
235};
236
237struct value_params {
238 float value;
239 int digits;
240 gboolean ol_neg, ol_pos;
241};
242
243struct feed_buffer {
244 struct sr_datafeed_packet packet;
245 struct sr_datafeed_analog analog;
246 struct sr_analog_encoding encoding;
247 struct sr_analog_meaning meaning;
248 struct sr_analog_spec spec;
249 int scale;
250 float main_value; /* TODO double, for epoch timestamps */
251};
252
253struct ut181a_info {
254 struct {
255 enum ut181_rsp_type rsp_type;
256 } rsp_head;
257 struct {
258 uint16_t code;
259 gboolean ok;
260 } reply_code;
261 struct {
262 uint32_t stamp;
263 time_t epoch;
264 } save_time;
265 struct {
266 uint8_t misc1, misc2, range;
267 uint16_t mode;
268 uint8_t is_type;
269 gboolean is_norm, is_rel, is_minmax, is_peak;
270 gboolean has_hold, has_aux1, has_aux2, has_bar;
271 gboolean is_rec, is_comp, is_auto_range;
272 gboolean has_lead_err, has_high_volt;
273 } meas_head;
274 union {
275 struct {
276 float main_value;
277 uint8_t main_prec;
278 char main_unit[8];
279 float aux1_value;
280 uint8_t aux1_prec;
281 char aux1_unit[8];
282 float aux2_value;
283 uint8_t aux2_prec;
284 char aux2_unit[8];
285 float bar_value;
286 char bar_unit[8];
287 } norm;
288 struct {
289 enum {
290 COMP_MODE_INNER = 0,
291 COMP_MODE_OUTER = 1,
292 COMP_MODE_BELOW = 2,
293 COMP_MODE_ABOVE = 3,
294 } mode;
295 gboolean fail;
296 int digits;
297 float limit_high;
298 float limit_low;
299 } comp;
300 struct {
301 float rel_value;
302 uint8_t rel_prec;
303 char rel_unit[8];
304 float ref_value;
305 uint8_t ref_prec;
306 char ref_unit[8];
307 float abs_value;
308 uint8_t abs_prec;
309 char abs_unit[8];
310 float bar_value;
311 char bar_unit[8];
312 } rel;
313 struct {
314 float curr_value;
315 uint8_t curr_prec;
316 float max_value;
317 uint8_t max_prec;
318 uint32_t max_stamp;
319 float avg_value;
320 uint8_t avg_prec;
321 uint32_t avg_stamp;
322 float min_value;
323 uint8_t min_prec;
324 uint32_t min_stamp;
325 char all_unit[8];
326 } minmax;
327 struct {
328 float max_value;
329 uint8_t max_prec;
330 char max_unit[8];
331 float min_value;
332 uint8_t min_prec;
333 char min_unit[8];
334 } peak;
335 } meas_data;
336 struct {
337 size_t save_idx;
338 size_t save_count;
339 } save_info;
340 struct {
341 size_t rec_count;
342 size_t rec_idx;
343 gboolean auto_feed;
344 gboolean auto_next;
345 char name[12];
346 char unit[8];
347 uint16_t interval;
348 uint32_t duration;
349 uint32_t samples;
350 float max_value, avg_value, min_value;
351 uint8_t max_prec, avg_prec, min_prec;
352 uint32_t start_stamp;
353 } rec_info;
354 struct {
355 size_t rec_idx;
356 size_t samples_total;
357 size_t samples_curr;
358 uint8_t samples_chunk;
359 } rec_data;
360 struct {
361 enum ut181_cmd_code code;
362 uint16_t data;
363 } reply_data;
364};
365
366enum ut181a_data_source {
367 DATA_SOURCE_LIVE,
368 DATA_SOURCE_SAVE,
369 DATA_SOURCE_REC_FIRST,
370 DATA_SOURCE_MAX = DATA_SOURCE_REC_FIRST + MAX_REC_COUNT,
371};
372
3094e9d8 373struct dev_context {
ebc51109
GS
374 struct sr_sw_limits limits;
375 enum ut181a_data_source data_source;
376 size_t data_source_count;
377 const char *data_source_names[DATA_SOURCE_MAX + 1];
378 size_t record_count;
379 char record_names[MAX_REC_COUNT][MAX_REC_NAMELEN];
380 gboolean is_monitoring;
381 gboolean is_recording;
382
383 /* Reception of serial communication data. */
384 uint8_t recv_buff[RECV_BUFF_SIZE];
385 size_t recv_count;
386
387 /* Meter's internal state tracking. */
388 int disable_feed;
389 gboolean frame_started;
390 struct ut181a_info info;
391
392 /* Management for request/response pairs. */
393 struct wait_state {
394 gboolean want_code, got_code;
395 enum ut181_cmd_code want_data; gboolean got_data;
396 enum ut181_rsp_type want_rsp_type;
397 gboolean got_rsp_type;
398 gboolean want_measure, got_measure;
399 gboolean got_rec_count;
400 gboolean got_save_count;
401 gboolean got_sample_count;
402 size_t response_count;
403 gboolean code_ok;
404 size_t data_value;
405 } wait_state;
406 struct {
407 char unit_text[12];
408 } last_data;
3094e9d8
GS
409};
410
ebc51109
GS
411SR_PRIV const struct mqopt_item *ut181a_get_mqitem_from_mode(uint16_t mode);
412SR_PRIV uint16_t ut181a_get_mode_from_mq_flags(enum sr_mq mq, enum sr_mqflag mqflags);
413SR_PRIV GVariant *ut181a_get_mq_flags_list_item(enum sr_mq mq, enum sr_mqflag mqflag);
414SR_PRIV GVariant *ut181a_get_mq_flags_list(void);
415
416SR_PRIV int ut181a_send_cmd_monitor(struct sr_serial_dev_inst *serial, gboolean on);
417SR_PRIV int ut181a_send_cmd_setmode(struct sr_serial_dev_inst *serial, uint16_t mode);
418SR_PRIV int ut181a_send_cmd_setrange(struct sr_serial_dev_inst *serial, uint8_t range);
419SR_PRIV int ut181a_send_cmd_get_save_count(struct sr_serial_dev_inst *serial);
420SR_PRIV int ut181a_send_cmd_get_saved_value(struct sr_serial_dev_inst *serial, size_t idx);
421SR_PRIV int ut181a_send_cmd_get_recs_count(struct sr_serial_dev_inst *serial);
422SR_PRIV int ut181a_send_cmd_get_rec_info(struct sr_serial_dev_inst *serial, size_t idx);
423SR_PRIV int ut181a_send_cmd_get_rec_samples(struct sr_serial_dev_inst *serial, size_t idx, size_t off);
424
425SR_PRIV int ut181a_configure_waitfor(struct dev_context *devc,
426 gboolean want_code, enum ut181_cmd_code want_data,
427 enum ut181_rsp_type want_rsp_type,
428 gboolean want_measure, gboolean want_rec_count,
429 gboolean want_save_count, gboolean want_sample_count);
430SR_PRIV int ut181a_waitfor_response(const struct sr_dev_inst *sdi, int timeout_ms);
431
432SR_PRIV int ut181a_handle_events(int fd, int revents, void *cb_data);
433
434SR_PRIV GVariant *ut181a_get_ranges_list(void);
435SR_PRIV const char *ut181a_get_range_from_packet_bytes(struct dev_context *devc);
436SR_PRIV int ut181a_set_range_from_text(const struct sr_dev_inst *sdi, const char *text);
3094e9d8
GS
437
438#endif