]> sigrok.org Git - libsigrok.git/blob - hardware/hameg-hmo/protocol.c
change a bunch of functions from SR_PRIV to static
[libsigrok.git] / 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 "protocol.h"
21
22 static const char *hameg_scpi_dialect[] = {
23         [SCPI_CMD_GET_DIG_DATA]             = ":POD%d:DATA?",
24         [SCPI_CMD_GET_TIMEBASE]             = ":TIM:SCAL?",
25         [SCPI_CMD_SET_TIMEBASE]             = ":TIM:SCAL %E",
26         [SCPI_CMD_GET_COUPLING]             = ":CHAN%d:COUP?",
27         [SCPI_CMD_SET_COUPLING]             = ":CHAN%d:COUP %s",
28         [SCPI_CMD_GET_ANALOG_DATA]          = ":CHAN%d:DATA?",
29         [SCPI_CMD_GET_VERTICAL_DIV]         = ":CHAN%d:SCAL?",
30         [SCPI_CMD_SET_VERTICAL_DIV]         = ":CHAN%d:SCAL %E",
31         [SCPI_CMD_GET_DIG_POD_STATE]        = ":POD%d:STAT?",
32         [SCPI_CMD_SET_DIG_POD_STATE]        = ":POD%d:STAT %d",
33         [SCPI_CMD_GET_TRIGGER_SLOPE]        = ":TRIG:A:EDGE:SLOP?",
34         [SCPI_CMD_SET_TRIGGER_SLOPE]        = ":TRIG:A:EDGE:SLOP %s",
35         [SCPI_CMD_GET_TRIGGER_SOURCE]       = ":TRIG:A:SOUR?",
36         [SCPI_CMD_SET_TRIGGER_SOURCE]       = ":TRIG:A:SOUR %s",
37         [SCPI_CMD_GET_DIG_CHAN_STATE]       = ":LOG%d:STAT?",
38         [SCPI_CMD_SET_DIG_CHAN_STATE]       = ":LOG%d:STAT %d",
39         [SCPI_CMD_GET_VERTICAL_OFFSET]      = ":CHAN%d:POS?",
40         [SCPI_CMD_GET_HORIZ_TRIGGERPOS]     = ":TIM:POS?",
41         [SCPI_CMD_SET_HORIZ_TRIGGERPOS]     = ":TIM:POS %E",
42         [SCPI_CMD_GET_ANALOG_CHAN_STATE]    = ":CHAN%d:STAT?",
43         [SCPI_CMD_SET_ANALOG_CHAN_STATE]    = ":CHAN%d:STAT %d",
44 };
45
46 static const int32_t hmo_hwcaps[] = {
47         SR_CONF_OSCILLOSCOPE,
48         SR_CONF_TRIGGER_SOURCE,
49         SR_CONF_TIMEBASE,
50         SR_CONF_NUM_TIMEBASE,
51         SR_CONF_TRIGGER_SLOPE,
52         SR_CONF_HORIZ_TRIGGERPOS,
53 };
54
55 static const int32_t hmo_analog_caps[] = {
56         SR_CONF_NUM_VDIV,
57         SR_CONF_COUPLING,
58         SR_CONF_VDIV,
59 };
60
61 static const char *hmo_coupling_options[] = {
62         "AC",
63         "ACL",
64         "DC",
65         "DCL",
66         "GND",
67         NULL,
68 };
69
70 static const char *scope_trigger_slopes[] = {
71         "POS",
72         "NEG",
73         NULL,
74 };
75
76 static const char *hmo_compact2_trigger_sources[] = {
77         "CH1",
78         "CH2",
79         "LINE",
80         "EXT",
81         "D0",
82         "D1",
83         "D2",
84         "D3",
85         "D4",
86         "D5",
87         "D6",
88         "D7",
89         NULL,
90 };
91
92 static const char *hmo_compact4_trigger_sources[] = {
93         "CH1",
94         "CH2",
95         "CH3",
96         "CH4",
97         "LINE",
98         "EXT",
99         "D0",
100         "D1",
101         "D2",
102         "D3",
103         "D4",
104         "D5",
105         "D6",
106         "D7",
107         NULL,
108 };
109
110 static const uint64_t hmo_timebases[][2] = {
111         /* nanoseconds */
112         { 2, 1000000000 },
113         { 5, 1000000000 },
114         { 10, 1000000000 },
115         { 20, 1000000000 },
116         { 50, 1000000000 },
117         { 100, 1000000000 },
118         { 200, 1000000000 },
119         { 500, 1000000000 },
120         /* microseconds */
121         { 1, 1000000 },
122         { 2, 1000000 },
123         { 5, 1000000 },
124         { 10, 1000000 },
125         { 20, 1000000 },
126         { 50, 1000000 },
127         { 100, 1000000 },
128         { 200, 1000000 },
129         { 500, 1000000 },
130         /* milliseconds */
131         { 1, 1000 },
132         { 2, 1000 },
133         { 5, 1000 },
134         { 10, 1000 },
135         { 20, 1000 },
136         { 50, 1000 },
137         { 100, 1000 },
138         { 200, 1000 },
139         { 500, 1000 },
140         /* seconds */
141         { 1, 1 },
142         { 2, 1 },
143         { 5, 1 },
144         { 10, 1 },
145         { 20, 1 },
146         { 50, 1 },
147 };
148
149 static const uint64_t hmo_vdivs[][2] = {
150         /* millivolts */
151         { 1, 1000 },
152         { 2, 1000 },
153         { 5, 1000 },
154         { 10, 1000 },
155         { 20, 1000 },
156         { 50, 1000 },
157         { 100, 1000 },
158         { 200, 1000 },
159         { 500, 1000 },
160         /* volts */
161         { 1, 1 },
162         { 2, 1 },
163         { 5, 1 },
164         { 10, 1 },
165 };
166
167 static const char *scope_analog_probe_names[] = {
168         "CH1",
169         "CH2",
170         "CH3",
171         "CH4",
172 };
173
174 static const char *scope_digital_probe_names[] = {
175         "D0",
176         "D1",
177         "D2",
178         "D3",
179         "D4",
180         "D5",
181         "D6",
182         "D7",
183         "D8",
184         "D9",
185         "D10",
186         "D11",
187         "D12",
188         "D13",
189         "D14",
190         "D15",
191 };
192
193 static struct scope_config scope_models[] = {
194         {
195                 .name = {"HMO722", "HMO1022", "HMO1522", "HMO2022", NULL},
196                 .analog_channels = 2,
197                 .digital_channels = 8,
198                 .digital_pods = 1,
199
200                 .analog_names = &scope_analog_probe_names,
201                 .digital_names = &scope_digital_probe_names,
202
203                 .hw_caps = &hmo_hwcaps,
204                 .num_hwcaps = ARRAY_SIZE(hmo_hwcaps),
205
206                 .analog_hwcaps = &hmo_analog_caps,
207                 .num_analog_hwcaps = ARRAY_SIZE(hmo_analog_caps),
208
209                 .coupling_options = &hmo_coupling_options,
210                 .trigger_sources = &hmo_compact2_trigger_sources,
211                 .trigger_slopes = &scope_trigger_slopes,
212
213                 .timebases = &hmo_timebases,
214                 .num_timebases = ARRAY_SIZE(hmo_timebases),
215
216                 .vdivs = &hmo_vdivs,
217                 .num_vdivs = ARRAY_SIZE(hmo_vdivs),
218
219                 .num_xdivs = 12,
220                 .num_ydivs = 8,
221
222                 .scpi_dialect = &hameg_scpi_dialect,
223         },
224         {
225                 .name = {"HMO724", "HMO1024", "HMO1524", "HMO2024", NULL},
226                 .analog_channels = 4,
227                 .digital_channels = 8,
228                 .digital_pods = 1,
229
230                 .analog_names = &scope_analog_probe_names,
231                 .digital_names = &scope_digital_probe_names,
232
233                 .hw_caps = &hmo_hwcaps,
234                 .num_hwcaps = ARRAY_SIZE(hmo_hwcaps),
235
236                 .analog_hwcaps = &hmo_analog_caps,
237                 .num_analog_hwcaps = ARRAY_SIZE(hmo_analog_caps),
238
239                 .coupling_options = &hmo_coupling_options,
240                 .trigger_sources = &hmo_compact4_trigger_sources,
241                 .trigger_slopes = &scope_trigger_slopes,
242
243                 .timebases = &hmo_timebases,
244                 .num_timebases = ARRAY_SIZE(hmo_timebases),
245
246                 .vdivs = &hmo_vdivs,
247                 .num_vdivs = ARRAY_SIZE(hmo_vdivs),
248
249                 .num_xdivs = 12,
250                 .num_ydivs = 8,
251
252                 .scpi_dialect = &hameg_scpi_dialect,
253         },
254 };
255
256 static void scope_state_dump(struct scope_config *config,
257                              struct scope_state *state)
258 {
259         unsigned int i;
260
261         for (i = 0; i < config->analog_channels; ++i) {
262                 sr_info("State of analog channel %d -> %s : %s %.3eV %.3e offset", i + 1,
263                         state->analog_channels[i].state ? "On" : "Off",
264                         (*config->coupling_options)[state->analog_channels[i].coupling],
265                         state->analog_channels[i].vdiv, state->analog_channels[i].vertical_offset);
266         }
267
268         for (i = 0; i < config->digital_channels; ++i) {
269                 sr_info("State of digital channel %d -> %s", i,
270                         state->digital_channels[i] ? "On" : "Off");
271         }
272
273         for (i = 0; i < config->digital_pods; ++i) {
274                 sr_info("State of digital POD %d -> %s", i,
275                         state->digital_pods[i] ? "On" : "Off");
276         }
277
278         sr_info("Current timebase: %.2es", state->timebase);
279         sr_info("Current trigger: %s (source), %s (slope) %.2e (offset)",
280                 (*config->trigger_sources)[state->trigger_source],
281                 (*config->trigger_slopes)[state->trigger_slope],
282                 state->horiz_triggerpos);
283 }
284
285 static int scope_state_get_array_option(struct sr_scpi_dev_inst *scpi,
286                 const char *command, const char *(*array)[], int *result)
287 {
288         char *tmp;
289         unsigned int i;
290
291         if (sr_scpi_get_string(scpi, command, &tmp) != SR_OK) {
292                 g_free(tmp);
293                 return SR_ERR;
294         }
295
296         for (i = 0; (*array)[i]; ++i) {
297                 if (!g_strcmp0(tmp, (*array)[i])) {
298                         *result = i;
299                         g_free(tmp);
300                         tmp = NULL;
301                         break;
302                 }
303         }
304
305         if (tmp) {
306                 g_free(tmp);
307                 return SR_ERR;
308         }
309
310         return SR_OK;
311 }
312
313 static int analog_channel_state_get(struct sr_scpi_dev_inst *scpi,
314                                     struct scope_config *config,
315                                     struct scope_state *state)
316 {
317         unsigned int i;
318         char command[MAX_COMMAND_SIZE];
319
320         for (i = 0; i < config->analog_channels; ++i) {
321                 g_snprintf(command, sizeof(command),
322                            (*config->scpi_dialect)[SCPI_CMD_GET_ANALOG_CHAN_STATE],
323                            i + 1);
324
325                 if (sr_scpi_get_bool(scpi, command,
326                                      &state->analog_channels[i].state) != SR_OK)
327                         return SR_ERR;
328
329                 g_snprintf(command, sizeof(command),
330                            (*config->scpi_dialect)[SCPI_CMD_GET_VERTICAL_DIV],
331                            i + 1);
332
333                 if (sr_scpi_get_float(scpi, command,
334                                      &state->analog_channels[i].vdiv) != SR_OK)
335                         return SR_ERR;
336
337                 g_snprintf(command, sizeof(command),
338                            (*config->scpi_dialect)[SCPI_CMD_GET_VERTICAL_OFFSET],
339                            i + 1);
340
341                 if (sr_scpi_get_float(scpi, command,
342                                      &state->analog_channels[i].vertical_offset) != SR_OK)
343                         return SR_ERR;
344
345                 g_snprintf(command, sizeof(command),
346                            (*config->scpi_dialect)[SCPI_CMD_GET_COUPLING],
347                            i + 1);
348
349                 if (scope_state_get_array_option(scpi, command, config->coupling_options,
350                                          &state->analog_channels[i].coupling) != SR_OK)
351                         return SR_ERR;
352         }
353
354         return SR_OK;
355 }
356
357 static int digital_channel_state_get(struct sr_scpi_dev_inst *scpi,
358                                      struct scope_config *config,
359                                      struct scope_state *state)
360 {
361         unsigned int i;
362         char command[MAX_COMMAND_SIZE];
363
364         for (i = 0; i < config->digital_channels; ++i) {
365                 g_snprintf(command, sizeof(command),
366                            (*config->scpi_dialect)[SCPI_CMD_GET_DIG_CHAN_STATE],
367                            i);
368
369                 if (sr_scpi_get_bool(scpi, command,
370                                      &state->digital_channels[i]) != SR_OK)
371                         return SR_ERR;
372         }
373
374         for (i = 0; i < config->digital_pods; ++i) {
375                 g_snprintf(command, sizeof(command),
376                            (*config->scpi_dialect)[SCPI_CMD_GET_DIG_POD_STATE],
377                            i + 1);
378
379                 if (sr_scpi_get_bool(scpi, command,
380                                      &state->digital_pods[i]) != SR_OK)
381                         return SR_ERR;
382         }
383
384         return SR_OK;
385 }
386
387 SR_PRIV int hmo_scope_state_get(struct sr_dev_inst *sdi)
388 {
389         struct dev_context *devc;
390         struct scope_state *state;
391         struct scope_config *config;
392
393         devc = sdi->priv;
394         config = devc->model_config;
395         state = devc->model_state;
396
397         if (analog_channel_state_get(sdi->conn, config, state) != SR_OK)
398                 return SR_ERR;
399
400         if (digital_channel_state_get(sdi->conn, config, state) != SR_OK)
401                 return SR_ERR;
402
403         /* TODO: Check if value is sensible. */
404         if (sr_scpi_get_float(sdi->conn,
405                         (*config->scpi_dialect)[SCPI_CMD_GET_TIMEBASE],
406                         &state->timebase) != SR_OK)
407                 return SR_ERR;
408
409         if (sr_scpi_get_float(sdi->conn,
410                         (*config->scpi_dialect)[SCPI_CMD_GET_HORIZ_TRIGGERPOS],
411                         &state->horiz_triggerpos) != SR_OK)
412                 return SR_ERR;
413
414         if (scope_state_get_array_option(sdi->conn,
415                         (*config->scpi_dialect)[SCPI_CMD_GET_TRIGGER_SOURCE],
416                         config->trigger_sources, &state->trigger_source) != SR_OK)
417                 return SR_ERR;
418
419         if (scope_state_get_array_option(sdi->conn,
420                 (*config->scpi_dialect)[SCPI_CMD_GET_TRIGGER_SLOPE],
421                 config->trigger_slopes, &state->trigger_slope) != SR_OK)
422                 return SR_ERR;
423
424         scope_state_dump(config, state);
425
426         return SR_OK;
427 }
428
429 static struct scope_state *scope_state_new(struct scope_config *config)
430 {
431         struct scope_state *state;
432
433         if (!(state = g_try_malloc0(sizeof(struct scope_state))))
434                 return NULL;
435
436         if (!(state->analog_channels = g_try_malloc0_n(config->analog_channels,
437                                     sizeof(struct analog_channel_state))))
438             goto fail;
439
440         if (!(state->digital_channels = g_try_malloc0_n(
441                         config->digital_channels, sizeof(gboolean))))
442             goto fail;
443
444         if (!(state->digital_pods = g_try_malloc0_n(config->digital_pods,
445                                                      sizeof(gboolean))))
446             goto fail;
447
448         return state;
449
450 fail:
451         if (state->analog_channels)
452                 g_free(state->analog_channels);
453         if (state->digital_channels)
454                 g_free(state->digital_channels);
455         if (state->digital_pods)
456                 g_free(state->digital_pods);
457         g_free(state);
458
459         return NULL;
460 }
461
462 SR_PRIV void hmo_scope_state_free(struct scope_state *state)
463 {
464         g_free(state->analog_channels);
465         g_free(state->digital_channels);
466         g_free(state->digital_pods);
467         g_free(state);
468 }
469
470 SR_PRIV int hmo_init_device(struct sr_dev_inst *sdi)
471 {
472         char tmp[25];
473         int model_index;
474         unsigned int i, j;
475         struct sr_probe *probe;
476         struct dev_context *devc;
477
478         devc = sdi->priv;
479         model_index = -1;
480
481         /* Find the exact model. */
482         for (i = 0; i < ARRAY_SIZE(scope_models); i++) {
483                 for (j = 0; scope_models[i].name[j]; j++) {
484                         if (!strcmp(sdi->model, scope_models[i].name[j])) {
485                                 model_index = i;
486                                 break;
487                         }
488                 }
489                 if (model_index != -1)
490                         break;
491         }
492
493         if (model_index == -1) {
494                 sr_dbg("Unsupported HMO device.");
495                 return SR_ERR_NA;
496         }
497
498         if (!(devc->analog_groups = g_try_malloc0(sizeof(struct sr_probe_group) *
499                                                   scope_models[model_index].analog_channels)))
500                         return SR_ERR_MALLOC;
501
502         if (!(devc->digital_groups = g_try_malloc0(sizeof(struct sr_probe_group) *
503                                                    scope_models[model_index].digital_pods)))
504                         return SR_ERR_MALLOC;
505
506         /* Add analog channels. */
507         for (i = 0; i < scope_models[model_index].analog_channels; i++) {
508                 if (!(probe = sr_probe_new(i, SR_PROBE_ANALOG, TRUE,
509                            (*scope_models[model_index].analog_names)[i])))
510                         return SR_ERR_MALLOC;
511                 sdi->probes = g_slist_append(sdi->probes, probe);
512
513                 devc->analog_groups[i].name =
514                         (char *)(*scope_models[model_index].analog_names)[i];
515                 devc->analog_groups[i].probes = g_slist_append(NULL, probe);
516
517                 sdi->probe_groups = g_slist_append(sdi->probe_groups,
518                                                    &devc->analog_groups[i]);
519         }
520
521         /* Add digital probe groups. */
522         for (i = 0; i < scope_models[model_index].digital_pods; ++i) {
523                 g_snprintf(tmp, 25, "POD%d", i);
524                 devc->digital_groups[i].name = g_strdup(tmp);
525                 sdi->probe_groups = g_slist_append(sdi->probe_groups,
526                                    &devc->digital_groups[i < 8 ? 0 : 1]);
527         }
528
529         /* Add digital channels. */
530         for (i = 0; i < scope_models[model_index].digital_channels; i++) {
531                 if (!(probe = sr_probe_new(i, SR_PROBE_LOGIC, TRUE,
532                            (*scope_models[model_index].digital_names)[i])))
533                         return SR_ERR_MALLOC;
534                 sdi->probes = g_slist_append(sdi->probes, probe);
535
536                 devc->digital_groups[i < 8 ? 0 : 1].probes = g_slist_append(
537                         devc->digital_groups[i < 8 ? 0 : 1].probes, probe);
538         }
539
540         devc->model_config = &scope_models[model_index];
541         devc->frame_limit = 0;
542
543         if (!(devc->model_state = scope_state_new(devc->model_config)))
544                 return SR_ERR_MALLOC;
545
546         return SR_OK;
547 }
548
549 SR_PRIV int hmo_receive_data(int fd, int revents, void *cb_data)
550 {
551         struct sr_probe *probe;
552         struct sr_dev_inst *sdi;
553         struct dev_context *devc;
554         struct sr_datafeed_packet packet;
555         GArray *data;
556         struct sr_datafeed_analog analog;
557         struct sr_datafeed_logic logic;
558
559         (void)fd;
560
561         if (!(sdi = cb_data))
562                 return TRUE;
563
564         if (!(devc = sdi->priv))
565                 return TRUE;
566
567         if (revents == G_IO_IN) {
568                 probe = devc->current_probe->data;
569
570                 switch (probe->type) {
571                 case SR_PROBE_ANALOG:
572                         if (sr_scpi_get_floatv(sdi->conn, NULL, &data) != SR_OK) {
573                                 if (data)
574                                         g_array_free(data, TRUE);
575
576                                 return TRUE;
577                         }
578
579                         packet.type = SR_DF_FRAME_BEGIN;
580                         sr_session_send(sdi, &packet);
581
582                         analog.probes = g_slist_append(NULL, probe);
583                         analog.num_samples = data->len;
584                         analog.data = (float *) data->data;
585                         analog.mq = SR_MQ_VOLTAGE;
586                         analog.unit = SR_UNIT_VOLT;
587                         analog.mqflags = 0;
588                         packet.type = SR_DF_ANALOG;
589                         packet.payload = &analog;
590                         sr_session_send(cb_data, &packet);
591                         g_slist_free(analog.probes);
592                         g_array_free(data, TRUE);
593                         break;
594                 case SR_PROBE_LOGIC:
595                         if (sr_scpi_get_uint8v(sdi->conn, NULL, &data) != SR_OK) {
596                                 if (data)
597                                         g_free(data);
598                                 return TRUE;
599                         }
600
601                         packet.type = SR_DF_FRAME_BEGIN;
602                         sr_session_send(sdi, &packet);
603
604                         logic.length = data->len;
605                         logic.unitsize = 1;
606                         logic.data = data->data;
607                         packet.type = SR_DF_LOGIC;
608                         packet.payload = &logic;
609                         sr_session_send(cb_data, &packet);
610                         g_array_free(data, TRUE);
611                         break;
612                 default:
613                         sr_err("Invalid probe type.");
614                         break;
615                 }
616
617                 packet.type = SR_DF_FRAME_END;
618                 sr_session_send(sdi, &packet);
619
620                 if (devc->current_probe->next) {
621                         devc->current_probe = devc->current_probe->next;
622                         hmo_request_data(sdi);
623                 } else if (++devc->num_frames == devc->frame_limit) {
624                         packet.type = SR_DF_END;
625                         sr_session_send(sdi, &packet);
626                         sdi->driver->dev_acquisition_stop(sdi, cb_data);
627                 } else {
628                         devc->current_probe = devc->enabled_probes;
629                         hmo_request_data(sdi);
630                 }
631         }
632
633         return TRUE;
634 }