]> sigrok.org Git - libsigrok.git/blob - src/hardware/hameg-hmo/protocol.c
hameg-hmo: Add PATTern and BUS1/BUS2 trigger sources
[libsigrok.git] / src / hardware / hameg-hmo / protocol.c
1 /*
2  * This file is part of the libsigrok project.
3  *
4  * Copyright (C) 2013 poljar (Damir Jelić) <poljarinho@gmail.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
20 #include <config.h>
21 #include <math.h>
22 #include <stdlib.h>
23 #include "scpi.h"
24 #include "protocol.h"
25
26 static const char *hameg_scpi_dialect[] = {
27         [SCPI_CMD_GET_DIG_DATA]             = ":POD%d:DATA?",
28         [SCPI_CMD_GET_TIMEBASE]             = ":TIM:SCAL?",
29         [SCPI_CMD_SET_TIMEBASE]             = ":TIM:SCAL %s",
30         [SCPI_CMD_GET_COUPLING]             = ":CHAN%d:COUP?",
31         [SCPI_CMD_SET_COUPLING]             = ":CHAN%d:COUP %s",
32         [SCPI_CMD_GET_SAMPLE_RATE]          = ":ACQ:SRAT?",
33         [SCPI_CMD_GET_SAMPLE_RATE_LIVE]     = ":%s:DATA:POINTS?",
34         [SCPI_CMD_GET_ANALOG_DATA]          = ":CHAN%d:DATA?",
35         [SCPI_CMD_GET_VERTICAL_DIV]         = ":CHAN%d:SCAL?",
36         [SCPI_CMD_SET_VERTICAL_DIV]         = ":CHAN%d:SCAL %s",
37         [SCPI_CMD_GET_DIG_POD_STATE]        = ":POD%d:STAT?",
38         [SCPI_CMD_SET_DIG_POD_STATE]        = ":POD%d:STAT %d",
39         [SCPI_CMD_GET_TRIGGER_SLOPE]        = ":TRIG:A:EDGE:SLOP?",
40         [SCPI_CMD_SET_TRIGGER_SLOPE]        = ":TRIG:A:EDGE:SLOP %s",
41         [SCPI_CMD_GET_TRIGGER_SOURCE]       = ":TRIG:A:SOUR?",
42         [SCPI_CMD_SET_TRIGGER_SOURCE]       = ":TRIG:A:SOUR %s",
43         [SCPI_CMD_GET_DIG_CHAN_STATE]       = ":LOG%d:STAT?",
44         [SCPI_CMD_SET_DIG_CHAN_STATE]       = ":LOG%d:STAT %d",
45         [SCPI_CMD_GET_VERTICAL_OFFSET]      = ":CHAN%d:POS?",
46         [SCPI_CMD_GET_HORIZ_TRIGGERPOS]     = ":TIM:POS?",
47         [SCPI_CMD_SET_HORIZ_TRIGGERPOS]     = ":TIM:POS %s",
48         [SCPI_CMD_GET_ANALOG_CHAN_STATE]    = ":CHAN%d:STAT?",
49         [SCPI_CMD_SET_ANALOG_CHAN_STATE]    = ":CHAN%d:STAT %d",
50 };
51
52 static const uint32_t hmo_devopts[] = {
53         SR_CONF_OSCILLOSCOPE,
54         SR_CONF_LIMIT_FRAMES | SR_CONF_GET | SR_CONF_SET,
55         SR_CONF_TRIGGER_SOURCE | SR_CONF_GET | SR_CONF_SET | SR_CONF_LIST,
56         SR_CONF_TIMEBASE | SR_CONF_GET | SR_CONF_SET | SR_CONF_LIST,
57         SR_CONF_NUM_HDIV | SR_CONF_GET,
58         SR_CONF_TRIGGER_SLOPE | SR_CONF_GET | SR_CONF_SET | SR_CONF_LIST,
59         SR_CONF_HORIZ_TRIGGERPOS | SR_CONF_GET | SR_CONF_SET,
60         SR_CONF_SAMPLERATE | SR_CONF_GET,
61 };
62
63 static const uint32_t hmo_analog_devopts[] = {
64         SR_CONF_NUM_VDIV | SR_CONF_GET,
65         SR_CONF_COUPLING | SR_CONF_GET | SR_CONF_SET | SR_CONF_LIST,
66         SR_CONF_VDIV | SR_CONF_GET | SR_CONF_SET | SR_CONF_LIST,
67 };
68
69 static const char *hmo_coupling_options[] = {
70         "AC",
71         "ACL",
72         "DC",
73         "DCL",
74         "GND",
75         NULL,
76 };
77
78 static const char *scope_trigger_slopes[] = {
79         "POS",
80         "NEG",
81         "EITH",
82         NULL,
83 };
84
85 static const char *hmo_compact2_trigger_sources[] = {
86         "CH1",
87         "CH2",
88         "LINE",
89         "EXT",
90         "PATT",
91         "BUS1",
92         "BUS2",
93         "D0",
94         "D1",
95         "D2",
96         "D3",
97         "D4",
98         "D5",
99         "D6",
100         "D7",
101         NULL,
102 };
103
104 static const char *hmo_compact4_trigger_sources[] = {
105         "CH1",
106         "CH2",
107         "CH3",
108         "CH4",
109         "LINE",
110         "EXT",
111         "PATT",
112         "BUS1",
113         "BUS2",
114         "D0",
115         "D1",
116         "D2",
117         "D3",
118         "D4",
119         "D5",
120         "D6",
121         "D7",
122         NULL,
123 };
124
125 static const uint64_t hmo_timebases[][2] = {
126         /* nanoseconds */
127         { 2, 1000000000 },
128         { 5, 1000000000 },
129         { 10, 1000000000 },
130         { 20, 1000000000 },
131         { 50, 1000000000 },
132         { 100, 1000000000 },
133         { 200, 1000000000 },
134         { 500, 1000000000 },
135         /* microseconds */
136         { 1, 1000000 },
137         { 2, 1000000 },
138         { 5, 1000000 },
139         { 10, 1000000 },
140         { 20, 1000000 },
141         { 50, 1000000 },
142         { 100, 1000000 },
143         { 200, 1000000 },
144         { 500, 1000000 },
145         /* milliseconds */
146         { 1, 1000 },
147         { 2, 1000 },
148         { 5, 1000 },
149         { 10, 1000 },
150         { 20, 1000 },
151         { 50, 1000 },
152         { 100, 1000 },
153         { 200, 1000 },
154         { 500, 1000 },
155         /* seconds */
156         { 1, 1 },
157         { 2, 1 },
158         { 5, 1 },
159         { 10, 1 },
160         { 20, 1 },
161         { 50, 1 },
162 };
163
164 static const uint64_t hmo_vdivs[][2] = {
165         /* millivolts */
166         { 1, 1000 },
167         { 2, 1000 },
168         { 5, 1000 },
169         { 10, 1000 },
170         { 20, 1000 },
171         { 50, 1000 },
172         { 100, 1000 },
173         { 200, 1000 },
174         { 500, 1000 },
175         /* volts */
176         { 1, 1 },
177         { 2, 1 },
178         { 5, 1 },
179         { 10, 1 },
180         { 20, 1 },
181         { 50, 1 },
182 };
183
184 static const char *scope_analog_channel_names[] = {
185         "CH1",
186         "CH2",
187         "CH3",
188         "CH4",
189 };
190
191 static const char *scope_digital_channel_names[] = {
192         "D0",
193         "D1",
194         "D2",
195         "D3",
196         "D4",
197         "D5",
198         "D6",
199         "D7",
200         "D8",
201         "D9",
202         "D10",
203         "D11",
204         "D12",
205         "D13",
206         "D14",
207         "D15",
208 };
209
210 static const struct scope_config scope_models[] = {
211         {
212                 /* HMO2522/3032/3042/3052 support 16 digital channels but they're not supported yet. */
213                 .name = {"HMO1002", "HMO722", "HMO1022", "HMO1522", "HMO2022", "HMO2522",
214                                 "HMO3032", "HMO3042", "HMO3052", NULL},
215                 .analog_channels = 2,
216                 .digital_channels = 8,
217                 .digital_pods = 1,
218
219                 .analog_names = &scope_analog_channel_names,
220                 .digital_names = &scope_digital_channel_names,
221
222                 .devopts = &hmo_devopts,
223                 .num_devopts = ARRAY_SIZE(hmo_devopts),
224
225                 .analog_devopts = &hmo_analog_devopts,
226                 .num_analog_devopts = ARRAY_SIZE(hmo_analog_devopts),
227
228                 .coupling_options = &hmo_coupling_options,
229                 .trigger_sources = &hmo_compact2_trigger_sources,
230                 .trigger_slopes = &scope_trigger_slopes,
231
232                 .timebases = &hmo_timebases,
233                 .num_timebases = ARRAY_SIZE(hmo_timebases),
234
235                 .vdivs = &hmo_vdivs,
236                 .num_vdivs = ARRAY_SIZE(hmo_vdivs),
237
238                 .num_xdivs = 12,
239                 .num_ydivs = 8,
240
241                 .scpi_dialect = &hameg_scpi_dialect,
242         },
243         {
244                 /* HMO2524/3034/3044/3054 support 16 digital channels but they're not supported yet. */
245                 .name = {"HMO724", "HMO1024", "HMO1524", "HMO2024", "HMO2524",
246                                 "HMO3034", "HMO3044", "HMO3054", NULL},
247                 .analog_channels = 4,
248                 .digital_channels = 8,
249                 .digital_pods = 1,
250
251                 .analog_names = &scope_analog_channel_names,
252                 .digital_names = &scope_digital_channel_names,
253
254                 .devopts = &hmo_devopts,
255                 .num_devopts = ARRAY_SIZE(hmo_devopts),
256
257                 .analog_devopts = &hmo_analog_devopts,
258                 .num_analog_devopts = ARRAY_SIZE(hmo_analog_devopts),
259
260                 .coupling_options = &hmo_coupling_options,
261                 .trigger_sources = &hmo_compact4_trigger_sources,
262                 .trigger_slopes = &scope_trigger_slopes,
263
264                 .timebases = &hmo_timebases,
265                 .num_timebases = ARRAY_SIZE(hmo_timebases),
266
267                 .vdivs = &hmo_vdivs,
268                 .num_vdivs = ARRAY_SIZE(hmo_vdivs),
269
270                 .num_xdivs = 12,
271                 .num_ydivs = 8,
272
273                 .scpi_dialect = &hameg_scpi_dialect,
274         },
275 };
276
277 static void scope_state_dump(const struct scope_config *config,
278                              struct scope_state *state)
279 {
280         unsigned int i;
281         char *tmp;
282
283         for (i = 0; i < config->analog_channels; i++) {
284                 tmp = sr_voltage_string((*config->vdivs)[state->analog_channels[i].vdiv][0],
285                                              (*config->vdivs)[state->analog_channels[i].vdiv][1]);
286                 sr_info("State of analog channel  %d -> %s : %s (coupling) %s (vdiv) %2.2e (offset)",
287                         i + 1, state->analog_channels[i].state ? "On" : "Off",
288                         (*config->coupling_options)[state->analog_channels[i].coupling],
289                         tmp, state->analog_channels[i].vertical_offset);
290         }
291
292         for (i = 0; i < config->digital_channels; i++) {
293                 sr_info("State of digital channel %d -> %s", i,
294                         state->digital_channels[i] ? "On" : "Off");
295         }
296
297         for (i = 0; i < config->digital_pods; i++) {
298                 sr_info("State of digital POD %d -> %s", i,
299                         state->digital_pods[i] ? "On" : "Off");
300         }
301
302         tmp = sr_period_string((*config->timebases)[state->timebase][0] *
303                                (*config->timebases)[state->timebase][1]);
304         sr_info("Current timebase: %s", tmp);
305         g_free(tmp);
306
307         tmp = sr_samplerate_string(state->sample_rate);
308         sr_info("Current samplerate: %s", tmp);
309         g_free(tmp);
310
311         sr_info("Current trigger: %s (source), %s (slope) %.2f (offset)",
312                 (*config->trigger_sources)[state->trigger_source],
313                 (*config->trigger_slopes)[state->trigger_slope],
314                 state->horiz_triggerpos);
315 }
316
317 static int scope_state_get_array_option(struct sr_scpi_dev_inst *scpi,
318                 const char *command, const char *(*array)[], int *result)
319 {
320         char *tmp;
321         unsigned int i;
322
323         if (sr_scpi_get_string(scpi, command, &tmp) != SR_OK) {
324                 g_free(tmp);
325                 return SR_ERR;
326         }
327
328         for (i = 0; (*array)[i]; i++) {
329                 if (!g_strcmp0(tmp, (*array)[i])) {
330                         *result = i;
331                         g_free(tmp);
332                         tmp = NULL;
333                         break;
334                 }
335         }
336
337         if (tmp) {
338                 g_free(tmp);
339                 return SR_ERR;
340         }
341
342         return SR_OK;
343 }
344
345 /**
346  * This function takes a value of the form "2.000E-03", converts it to a
347  * significand / factor pair and returns the index of an array where
348  * a matching pair was found.
349  *
350  * It's a bit convoluted because of floating-point issues. The value "10.00E-09"
351  * is parsed by g_ascii_strtod() as 0.000000009999999939, for example.
352  * Therefore it's easier to break the number up into two strings and handle
353  * them separately.
354  *
355  * @param value The string to be parsed.
356  * @param array The array of s/f pairs.
357  * @param array_len The number of pairs in the array.
358  * @param result The index at which a matching pair was found.
359  *
360  * @return SR_ERR on any parsing error, SR_OK otherwise.
361  */
362 static int array_float_get(gchar *value, const uint64_t array[][2],
363                 int array_len, unsigned int *result)
364 {
365         int i, e;
366         size_t pos;
367         uint64_t f;
368         float s;
369         unsigned int s_int;
370         gchar ss[10], es[10];
371
372         memset(ss, 0, sizeof(ss));
373         memset(es, 0, sizeof(es));
374
375         /* Get index of the separating 'E' character and break up the string. */
376         pos = strcspn(value, "E");
377
378         strncpy(ss, value, pos);
379         strncpy(es, &(value[pos+1]), 3);
380
381         if (sr_atof_ascii(ss, &s) != SR_OK)
382                 return SR_ERR;
383         if (sr_atoi(es, &e) != SR_OK)
384                 return SR_ERR;
385
386         /* Transform e.g. 10^-03 to 1000 as the array stores the inverse. */
387         f = pow(10, abs(e));
388
389         /*
390          * Adjust the significand/factor pair to make sure
391          * that f is a multiple of 1000.
392          */
393         while ((int)fmod(log10(f), 3) > 0) {
394                 s *= 10;
395
396                 if (e < 0)
397                         f *= 10;
398                 else
399                         f /= 10;
400         }
401
402         /* Truncate s to circumvent rounding errors. */
403         s_int = (unsigned int)s;
404
405         for (i = 0; i < array_len; i++) {
406                 if ((s_int == array[i][0]) && (f == array[i][1])) {
407                         *result = i;
408                         return SR_OK;
409                 }
410         }
411
412         return SR_ERR;
413 }
414
415 static int analog_channel_state_get(struct sr_scpi_dev_inst *scpi,
416                                     const struct scope_config *config,
417                                     struct scope_state *state)
418 {
419         unsigned int i, j;
420         char command[MAX_COMMAND_SIZE];
421         char *tmp_str;
422
423         for (i = 0; i < config->analog_channels; i++) {
424                 g_snprintf(command, sizeof(command),
425                            (*config->scpi_dialect)[SCPI_CMD_GET_ANALOG_CHAN_STATE],
426                            i + 1);
427
428                 if (sr_scpi_get_bool(scpi, command,
429                                      &state->analog_channels[i].state) != SR_OK)
430                         return SR_ERR;
431
432                 g_snprintf(command, sizeof(command),
433                            (*config->scpi_dialect)[SCPI_CMD_GET_VERTICAL_DIV],
434                            i + 1);
435
436                 if (sr_scpi_get_string(scpi, command, &tmp_str) != SR_OK)
437                         return SR_ERR;
438
439                 if (array_float_get(tmp_str, hmo_vdivs, ARRAY_SIZE(hmo_vdivs),
440                                 &j) != SR_OK) {
441                         g_free(tmp_str);
442                         sr_err("Could not determine array index for vertical div scale.");
443                         return SR_ERR;
444                 }
445
446                 g_free(tmp_str);
447                 state->analog_channels[i].vdiv = j;
448
449                 g_snprintf(command, sizeof(command),
450                            (*config->scpi_dialect)[SCPI_CMD_GET_VERTICAL_OFFSET],
451                            i + 1);
452
453                 if (sr_scpi_get_float(scpi, command,
454                                      &state->analog_channels[i].vertical_offset) != SR_OK)
455                         return SR_ERR;
456
457                 g_snprintf(command, sizeof(command),
458                            (*config->scpi_dialect)[SCPI_CMD_GET_COUPLING],
459                            i + 1);
460
461                 if (scope_state_get_array_option(scpi, command, config->coupling_options,
462                                          &state->analog_channels[i].coupling) != SR_OK)
463                         return SR_ERR;
464         }
465
466         return SR_OK;
467 }
468
469 static int digital_channel_state_get(struct sr_scpi_dev_inst *scpi,
470                                      const struct scope_config *config,
471                                      struct scope_state *state)
472 {
473         unsigned int i;
474         char command[MAX_COMMAND_SIZE];
475
476         for (i = 0; i < config->digital_channels; i++) {
477                 g_snprintf(command, sizeof(command),
478                            (*config->scpi_dialect)[SCPI_CMD_GET_DIG_CHAN_STATE],
479                            i);
480
481                 if (sr_scpi_get_bool(scpi, command,
482                                      &state->digital_channels[i]) != SR_OK)
483                         return SR_ERR;
484         }
485
486         for (i = 0; i < config->digital_pods; i++) {
487                 g_snprintf(command, sizeof(command),
488                            (*config->scpi_dialect)[SCPI_CMD_GET_DIG_POD_STATE],
489                            i + 1);
490
491                 if (sr_scpi_get_bool(scpi, command,
492                                      &state->digital_pods[i]) != SR_OK)
493                         return SR_ERR;
494         }
495
496         return SR_OK;
497 }
498
499 SR_PRIV int hmo_update_sample_rate(const struct sr_dev_inst *sdi)
500 {
501         struct dev_context *devc;
502         struct scope_state *state;
503         const struct scope_config *config;
504
505         int tmp;
506         unsigned int i;
507         float tmp_float;
508         gboolean channel_found;
509         char tmp_str[MAX_COMMAND_SIZE];
510         char chan_name[20];
511
512         devc = sdi->priv;
513         config = devc->model_config;
514         state = devc->model_state;
515         channel_found = FALSE;
516
517         for (i = 0; i < config->analog_channels; i++) {
518                 if (state->analog_channels[i].state) {
519                         g_snprintf(chan_name, sizeof(chan_name), "CHAN%d", i + 1);
520                         g_snprintf(tmp_str, sizeof(tmp_str),
521                                    (*config->scpi_dialect)[SCPI_CMD_GET_SAMPLE_RATE_LIVE],
522                                    chan_name);
523                         channel_found = TRUE;
524                         break;
525                 }
526         }
527
528         if (!channel_found) {
529                 for (i = 0; i < config->digital_pods; i++) {
530                         if (state->digital_pods[i]) {
531                                 g_snprintf(chan_name, sizeof(chan_name), "POD%d", i);
532                                 g_snprintf(tmp_str, sizeof(tmp_str),
533                                            (*config->scpi_dialect)[SCPI_CMD_GET_SAMPLE_RATE_LIVE],
534                                            chan_name);
535                                 channel_found = TRUE;
536                                 break;
537                         }
538                 }
539         }
540
541         /* No channel is active, ask the instrument for the sample rate
542          * in single shot mode */
543         if (!channel_found) {
544                 if (sr_scpi_get_float(sdi->conn,
545                                       (*config->scpi_dialect)[SCPI_CMD_GET_SAMPLE_RATE],
546                                       &tmp_float) != SR_OK)
547                         return SR_ERR;
548
549                 state->sample_rate = tmp_float;
550         } else {
551                 if (sr_scpi_get_int(sdi->conn, tmp_str, &tmp) != SR_OK)
552                         return SR_ERR;
553                 state->sample_rate = tmp / (((float) (*config->timebases)[state->timebase][0] /
554                                              (*config->timebases)[state->timebase][1]) *
555                                             config->num_xdivs);
556         }
557
558         return SR_OK;
559 }
560
561 SR_PRIV int hmo_scope_state_get(struct sr_dev_inst *sdi)
562 {
563         struct dev_context *devc;
564         struct scope_state *state;
565         const struct scope_config *config;
566         float tmp_float;
567         unsigned int i;
568         char *tmp_str;
569
570         devc = sdi->priv;
571         config = devc->model_config;
572         state = devc->model_state;
573
574         sr_info("Fetching scope state");
575
576         if (analog_channel_state_get(sdi->conn, config, state) != SR_OK)
577                 return SR_ERR;
578
579         if (digital_channel_state_get(sdi->conn, config, state) != SR_OK)
580                 return SR_ERR;
581
582         if (sr_scpi_get_float(sdi->conn,
583                         (*config->scpi_dialect)[SCPI_CMD_GET_TIMEBASE],
584                         &tmp_float) != SR_OK)
585                 return SR_ERR;
586
587         if (sr_scpi_get_string(sdi->conn,
588                         (*config->scpi_dialect)[SCPI_CMD_GET_TIMEBASE],
589                         &tmp_str) != SR_OK)
590                 return SR_ERR;
591
592         if (array_float_get(tmp_str, hmo_timebases, ARRAY_SIZE(hmo_timebases),
593                         &i) != SR_OK) {
594                 g_free(tmp_str);
595                 sr_err("Could not determine array index for time base.");
596                 return SR_ERR;
597         }
598
599         state->timebase = i;
600
601         if (sr_scpi_get_float(sdi->conn,
602                         (*config->scpi_dialect)[SCPI_CMD_GET_HORIZ_TRIGGERPOS],
603                         &tmp_float) != SR_OK)
604                 return SR_ERR;
605         state->horiz_triggerpos = tmp_float /
606                 (((double) (*config->timebases)[state->timebase][0] /
607                   (*config->timebases)[state->timebase][1]) * config->num_xdivs);
608         state->horiz_triggerpos -= 0.5;
609         state->horiz_triggerpos *= -1;
610
611         if (scope_state_get_array_option(sdi->conn,
612                         (*config->scpi_dialect)[SCPI_CMD_GET_TRIGGER_SOURCE],
613                         config->trigger_sources, &state->trigger_source) != SR_OK)
614                 return SR_ERR;
615
616         if (scope_state_get_array_option(sdi->conn,
617                 (*config->scpi_dialect)[SCPI_CMD_GET_TRIGGER_SLOPE],
618                 config->trigger_slopes, &state->trigger_slope) != SR_OK)
619                 return SR_ERR;
620
621         if (hmo_update_sample_rate(sdi) != SR_OK)
622                 return SR_ERR;
623
624         sr_info("Fetching finished.");
625
626         scope_state_dump(config, state);
627
628         return SR_OK;
629 }
630
631 static struct scope_state *scope_state_new(const struct scope_config *config)
632 {
633         struct scope_state *state;
634
635         state = g_malloc0(sizeof(struct scope_state));
636         state->analog_channels = g_malloc0_n(config->analog_channels,
637                         sizeof(struct analog_channel_state));
638         state->digital_channels = g_malloc0_n(
639                         config->digital_channels, sizeof(gboolean));
640         state->digital_pods = g_malloc0_n(config->digital_pods,
641                         sizeof(gboolean));
642
643         return state;
644 }
645
646 SR_PRIV void hmo_scope_state_free(struct scope_state *state)
647 {
648         g_free(state->analog_channels);
649         g_free(state->digital_channels);
650         g_free(state->digital_pods);
651         g_free(state);
652 }
653
654 SR_PRIV int hmo_init_device(struct sr_dev_inst *sdi)
655 {
656         char tmp[25];
657         int model_index;
658         unsigned int i, j;
659         struct sr_channel *ch;
660         struct dev_context *devc;
661
662         devc = sdi->priv;
663         model_index = -1;
664
665         /* Find the exact model. */
666         for (i = 0; i < ARRAY_SIZE(scope_models); i++) {
667                 for (j = 0; scope_models[i].name[j]; j++) {
668                         if (!strcmp(sdi->model, scope_models[i].name[j])) {
669                                 model_index = i;
670                                 break;
671                         }
672                 }
673                 if (model_index != -1)
674                         break;
675         }
676
677         if (model_index == -1) {
678                 sr_dbg("Unsupported HMO device.");
679                 return SR_ERR_NA;
680         }
681
682         devc->analog_groups = g_malloc0(sizeof(struct sr_channel_group*) *
683                                         scope_models[model_index].analog_channels);
684
685         devc->digital_groups = g_malloc0(sizeof(struct sr_channel_group*) *
686                                          scope_models[model_index].digital_pods);
687
688         /* Add analog channels. */
689         for (i = 0; i < scope_models[model_index].analog_channels; i++) {
690                 ch = sr_channel_new(sdi, i, SR_CHANNEL_ANALOG, TRUE,
691                            (*scope_models[model_index].analog_names)[i]);
692
693                 devc->analog_groups[i] = g_malloc0(sizeof(struct sr_channel_group));
694
695                 devc->analog_groups[i]->name = g_strdup(
696                         (char *)(*scope_models[model_index].analog_names)[i]);
697                 devc->analog_groups[i]->channels = g_slist_append(NULL, ch);
698
699                 sdi->channel_groups = g_slist_append(sdi->channel_groups,
700                                                    devc->analog_groups[i]);
701         }
702
703         /* Add digital channel groups. */
704         for (i = 0; i < scope_models[model_index].digital_pods; i++) {
705                 g_snprintf(tmp, 25, "POD%d", i);
706
707                 devc->digital_groups[i] = g_malloc0(sizeof(struct sr_channel_group));
708
709                 devc->digital_groups[i]->name = g_strdup(tmp);
710                 sdi->channel_groups = g_slist_append(sdi->channel_groups,
711                                    devc->digital_groups[i < 8 ? 0 : 1]);
712         }
713
714         /* Add digital channels. */
715         for (i = 0; i < scope_models[model_index].digital_channels; i++) {
716                 ch = sr_channel_new(sdi, i, SR_CHANNEL_LOGIC, TRUE,
717                            (*scope_models[model_index].digital_names)[i]);
718
719                 devc->digital_groups[i < 8 ? 0 : 1]->channels = g_slist_append(
720                         devc->digital_groups[i < 8 ? 0 : 1]->channels, ch);
721         }
722
723         devc->model_config = &scope_models[model_index];
724         devc->frame_limit = 0;
725
726         if (!(devc->model_state = scope_state_new(devc->model_config)))
727                 return SR_ERR_MALLOC;
728
729         return SR_OK;
730 }
731
732 SR_PRIV int hmo_receive_data(int fd, int revents, void *cb_data)
733 {
734         struct sr_channel *ch;
735         struct sr_dev_inst *sdi;
736         struct dev_context *devc;
737         struct sr_datafeed_packet packet;
738         GArray *data;
739         struct sr_datafeed_analog_old analog;
740         struct sr_datafeed_logic logic;
741
742         (void)fd;
743         (void)revents;
744
745         data = NULL;
746
747         if (!(sdi = cb_data))
748                 return TRUE;
749
750         if (!(devc = sdi->priv))
751                 return TRUE;
752
753         /* Although this is correct in general, the USBTMC libusb implementation
754          * currently does not generate an event prior to the first read. Often
755          * it is ok to start reading just after the 50ms timeout. See bug #785.
756         if (revents != G_IO_IN)
757                 return TRUE;
758         */
759
760         ch = devc->current_channel->data;
761
762         switch (ch->type) {
763         case SR_CHANNEL_ANALOG:
764                 if (sr_scpi_get_floatv(sdi->conn, NULL, &data) != SR_OK) {
765                         if (data)
766                                 g_array_free(data, TRUE);
767
768                         return TRUE;
769                 }
770
771                 packet.type = SR_DF_FRAME_BEGIN;
772                 sr_session_send(sdi, &packet);
773
774                 analog.channels = g_slist_append(NULL, ch);
775                 analog.num_samples = data->len;
776                 analog.data = (float *) data->data;
777                 analog.mq = SR_MQ_VOLTAGE;
778                 analog.unit = SR_UNIT_VOLT;
779                 analog.mqflags = 0;
780                 packet.type = SR_DF_ANALOG_OLD;
781                 packet.payload = &analog;
782                 sr_session_send(sdi, &packet);
783                 g_slist_free(analog.channels);
784                 g_array_free(data, TRUE);
785                 data = NULL;
786                 break;
787         case SR_CHANNEL_LOGIC:
788                 if (sr_scpi_get_uint8v(sdi->conn, NULL, &data) != SR_OK) {
789                         g_free(data);
790                         return TRUE;
791                 }
792
793                 packet.type = SR_DF_FRAME_BEGIN;
794                 sr_session_send(sdi, &packet);
795
796                 logic.length = data->len;
797                 logic.unitsize = 1;
798                 logic.data = data->data;
799                 packet.type = SR_DF_LOGIC;
800                 packet.payload = &logic;
801                 sr_session_send(sdi, &packet);
802                 g_array_free(data, TRUE);
803                 data = NULL;
804                 break;
805         default:
806                 sr_err("Invalid channel type.");
807                 break;
808         }
809
810         packet.type = SR_DF_FRAME_END;
811         sr_session_send(sdi, &packet);
812
813         if (devc->current_channel->next) {
814                 devc->current_channel = devc->current_channel->next;
815                 hmo_request_data(sdi);
816         } else if (++devc->num_frames == devc->frame_limit) {
817                 sdi->driver->dev_acquisition_stop(sdi);
818         } else {
819                 devc->current_channel = devc->enabled_channels;
820                 hmo_request_data(sdi);
821         }
822
823         return TRUE;
824 }