]> sigrok.org Git - libsigrok.git/blob - src/hardware/hp-59306a/api.c
output/csv: use intermediate time_t var, silence compiler warning
[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         SR_CONF_CONN | SR_CONF_GET,
34         SR_CONF_ENABLED | SR_CONF_SET,
35 };
36
37 static const uint32_t devopts_cg[] = {
38         SR_CONF_ENABLED | SR_CONF_SET,
39 };
40
41 static struct sr_dev_driver hp_59306a_driver_info;
42
43 static struct sr_dev_inst *probe_device(struct sr_scpi_dev_inst *scpi)
44 {
45         struct sr_dev_inst *sdi;
46         struct dev_context *devc;
47         struct channel_group_context *cgc;
48         size_t idx, nr;
49         struct sr_channel_group *cg;
50         char cg_name[24];
51
52         /*
53          * The device cannot get identified by means of SCPI queries.
54          * Neither shall non-SCPI requests get emitted before reliable
55          * identification of the device. Assume that we only get here
56          * when user specs led us to believe it's safe to communicate
57          * to the expected kind of device.
58          */
59
60         sdi = g_malloc0(sizeof(*sdi));
61         sdi->vendor = g_strdup("Hewlett-Packard");
62         sdi->model = g_strdup("59306A");
63         sdi->conn = scpi;
64         sdi->driver = &hp_59306a_driver_info;
65         sdi->inst_type = SR_INST_SCPI;
66         if (sr_scpi_connection_id(scpi, &sdi->connection_id) != SR_OK) {
67                 g_free(sdi->connection_id);
68                 sdi->connection_id = NULL;
69         }
70
71         devc = g_malloc0(sizeof(*devc));
72         sdi->priv = devc;
73
74         devc->channel_count = 6;
75         for (idx = 0; idx < devc->channel_count; idx++) {
76                 nr = idx + 1;
77                 snprintf(cg_name, sizeof(cg_name), "R%zu", nr);
78                 cgc = g_malloc0(sizeof(*cgc));
79                 cgc->number = nr;
80                 cg = sr_channel_group_new(sdi, cg_name, cgc);
81                 (void)cg;
82         }
83
84         return sdi;
85 }
86
87 static GSList *scan(struct sr_dev_driver *di, GSList *options)
88 {
89         const char *conn;
90
91         /* Only scan for a device when conn= was specified. */
92         conn = NULL;
93         (void)sr_serial_extract_options(options, &conn, NULL);
94         if (!conn)
95                 return NULL;
96
97         return sr_scpi_scan(di->context, options, probe_device);
98 }
99
100 static int dev_open(struct sr_dev_inst *sdi)
101 {
102         return sr_scpi_open(sdi->conn);
103 }
104
105 static int dev_close(struct sr_dev_inst *sdi)
106 {
107         return sr_scpi_close(sdi->conn);
108 }
109
110 static int config_get(uint32_t key, GVariant **data,
111         const struct sr_dev_inst *sdi, const struct sr_channel_group *cg)
112 {
113         (void)cg;
114
115         if (!sdi || !data)
116                 return SR_ERR_ARG;
117
118         switch (key) {
119         case SR_CONF_CONN:
120                 *data = g_variant_new_string(sdi->connection_id);
121                 break;
122         default:
123                 return SR_ERR_NA;
124         }
125
126         return SR_OK;
127 }
128
129 static int config_set(uint32_t key, GVariant *data,
130         const struct sr_dev_inst *sdi, const struct sr_channel_group *cg)
131 {
132         gboolean on;
133
134         if (!cg) {
135                 switch (key) {
136                 case SR_CONF_ENABLED:
137                         /* Enable/disable all channels at the same time. */
138                         on = g_variant_get_boolean(data);
139                         return hp_59306a_switch_cg(sdi, cg, on);
140                 default:
141                         return SR_ERR_NA;
142                 }
143         } else {
144                 switch (key) {
145                 case SR_CONF_ENABLED:
146                         on = g_variant_get_boolean(data);
147                         return hp_59306a_switch_cg(sdi, cg, on);
148                 default:
149                         return SR_ERR_NA;
150                 }
151         }
152
153         return SR_OK;
154 }
155
156 static int config_list(uint32_t key, GVariant **data,
157         const struct sr_dev_inst *sdi, const struct sr_channel_group *cg)
158 {
159         if (!cg) {
160                 switch (key) {
161                 case SR_CONF_SCAN_OPTIONS:
162                 case SR_CONF_DEVICE_OPTIONS:
163                         return STD_CONFIG_LIST(key, data, sdi, cg,
164                                 scanopts, drvopts, devopts);
165                 default:
166                         return SR_ERR_NA;
167                 }
168         } else {
169                 switch (key) {
170                 case SR_CONF_DEVICE_OPTIONS:
171                         *data = std_gvar_array_u32(ARRAY_AND_SIZE(devopts_cg));
172                         break;
173                 default:
174                         return SR_ERR_NA;
175                 }
176         }
177
178         return SR_OK;
179 }
180
181 static struct sr_dev_driver hp_59306a_driver_info = {
182         .name = "hp-59306a",
183         .longname = "HP 59306A",
184         .api_version = 1,
185         .init = std_init,
186         .cleanup = std_cleanup,
187         .scan = scan,
188         .dev_list = std_dev_list,
189         .dev_clear = std_dev_clear,
190         .config_get = config_get,
191         .config_set = config_set,
192         .config_list = config_list,
193         .dev_open = dev_open,
194         .dev_close = dev_close,
195         .dev_acquisition_start = std_dummy_dev_acquisition_start,
196         .dev_acquisition_stop = std_dummy_dev_acquisition_stop,
197         .context = NULL,
198 };
199 SR_REGISTER_DEV_DRIVER(hp_59306a_driver_info);