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