]> sigrok.org Git - libsigrok.git/blob - src/hardware/hp-59306a/api.c
289274323e580009941f6a3cb0d30e57ac35f260
[libsigrok.git] / src / hardware / hp-59306a / api.c
1 /*
2  * This file is part of the libsigrok project.
3  *
4  * Copyright (C) 2021 Frank Stettner <frank-stettner@gmx.net>
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 "scpi.h"
22 #include "protocol.h"
23
24 static const uint32_t scanopts[] = {
25         SR_CONF_CONN,
26 };
27
28 static const uint32_t drvopts[] = {
29         SR_CONF_MULTIPLEXER,
30 };
31
32 static const uint32_t devopts[] = {
33         /*
34          * TODO Enable/disable multiple channel groups at once.
35          * SR_CONF_ENABLED | SR_CONF_SET,
36          */
37 };
38
39 static const uint32_t devopts_cg[] = {
40         SR_CONF_ENABLED | SR_CONF_SET,
41 };
42
43 static struct sr_dev_driver hp_59306a_driver_info;
44
45 static struct sr_dev_inst *probe_device(struct sr_scpi_dev_inst *scpi)
46 {
47         struct sr_dev_inst *sdi;
48         struct dev_context *devc;
49         struct channel_group_context *cgc;
50         size_t idx, nr;
51         struct sr_channel_group *cg;
52
53         /*
54          * The device cannot get identified by means of SCPI queries.
55          * Neither shall non-SCPI requests get emitted before reliable
56          * identification of the device. Assume that we only get here
57          * when user specs led us to believe it's safe to communicate
58          * to the expected kind of device.
59          */
60
61         sdi = g_malloc0(sizeof(*sdi));
62         sdi->vendor = g_strdup("Hewlett-Packard");
63         sdi->model = g_strdup("59306A");
64         sdi->conn = scpi;
65         sdi->driver = &hp_59306a_driver_info;
66         sdi->inst_type = SR_INST_SCPI;
67
68         devc = g_malloc0(sizeof(*devc));
69         sdi->priv = devc;
70
71         devc->channel_count = 6;
72         for (idx = 0; idx < devc->channel_count; idx++) {
73                 nr = idx + 1;
74
75                 cg = g_malloc0(sizeof(*cg));
76                 cg->name = g_strdup_printf("CH%zu", nr);
77
78                 cgc = g_malloc0(sizeof(*cgc));
79                 cgc->number = nr;
80                 cg->priv = cgc;
81
82                 sdi->channel_groups = g_slist_append(sdi->channel_groups, cg);
83         }
84
85         return sdi;
86 }
87
88 static GSList *scan(struct sr_dev_driver *di, GSList *options)
89 {
90         const char *conn;
91
92         /* Only scan for a device when conn= was specified. */
93         conn = NULL;
94         (void)sr_serial_extract_options(options, &conn, NULL);
95         if (!conn)
96                 return NULL;
97
98         return sr_scpi_scan(di->context, options, probe_device);
99 }
100
101 static int dev_open(struct sr_dev_inst *sdi)
102 {
103         return sr_scpi_open(sdi->conn);
104 }
105
106 static int dev_close(struct sr_dev_inst *sdi)
107 {
108         return sr_scpi_close(sdi->conn);
109 }
110
111 static int config_set(uint32_t key, GVariant *data,
112         const struct sr_dev_inst *sdi, const struct sr_channel_group *cg)
113 {
114         gboolean on;
115
116         if (!cg) {
117                 switch (key) {
118                 /* TODO: Enable/disbale multiple channel groups at once. */
119                 case SR_CONF_ENABLED:
120                 default:
121                         return SR_ERR_NA;
122                 }
123         } else {
124                 switch (key) {
125                 case SR_CONF_ENABLED:
126                         on = g_variant_get_boolean(data);
127                         return hp_59306a_switch_cg(sdi, cg, on);
128                 default:
129                         return SR_ERR_NA;
130                 }
131         }
132
133         return SR_OK;
134 }
135
136 static int config_list(uint32_t key, GVariant **data,
137         const struct sr_dev_inst *sdi, const struct sr_channel_group *cg)
138 {
139         if (!cg) {
140                 switch (key) {
141                 case SR_CONF_SCAN_OPTIONS:
142                 case SR_CONF_DEVICE_OPTIONS:
143                         return STD_CONFIG_LIST(key, data, sdi, cg,
144                                 scanopts, drvopts, devopts);
145                 default:
146                         return SR_ERR_NA;
147                 }
148         } else {
149                 switch (key) {
150                 case SR_CONF_DEVICE_OPTIONS:
151                         *data = std_gvar_array_u32(ARRAY_AND_SIZE(devopts_cg));
152                         break;
153                 default:
154                         return SR_ERR_NA;
155                 }
156         }
157
158         return SR_OK;
159 }
160
161 static struct sr_dev_driver hp_59306a_driver_info = {
162         .name = "hp-59306a",
163         .longname = "hp-59306a",
164         .api_version = 1,
165         .init = std_init,
166         .cleanup = std_cleanup,
167         .scan = scan,
168         .dev_list = std_dev_list,
169         .dev_clear = std_dev_clear,
170         .config_get = NULL,
171         .config_set = config_set,
172         .config_list = config_list,
173         .dev_open = dev_open,
174         .dev_close = dev_close,
175         .dev_acquisition_start = std_dummy_dev_acquisition_start,
176         .dev_acquisition_stop = std_dummy_dev_acquisition_stop,
177         .context = NULL,
178 };
179 SR_REGISTER_DEV_DRIVER(hp_59306a_driver_info);