]> sigrok.org Git - libsigrok.git/blob - src/hardware/rohde-schwarz-sme-0x/api.c
rohde-schwarz-sme-0x: Add support for SR_CONF_SIGNAL_GENERATOR.
[libsigrok.git] / src / hardware / rohde-schwarz-sme-0x / api.c
1 /*
2  * This file is part of the libsigrok project.
3  *
4  * Copyright (C) 2016 Vlad Ivanov <vlad.ivanov@lab-systems.ru>
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 <libserialport.h>
22 #include <scpi.h>
23 #include <string.h>
24
25 #include "protocol.h"
26
27 SR_PRIV struct sr_dev_driver rohde_schwarz_sme_0x_driver_info;
28
29 static const char *manufacturer = "Rohde&Schwarz";
30
31 static const struct rs_device_model device_models[] = {
32         {
33                 .model_str = "SME02",
34                 .freq_max = SR_GHZ(1.5),
35                 .freq_min = SR_KHZ(5),
36                 .power_max = 16,
37                 .power_min = -144,
38         },
39         {
40                 .model_str = "SME03E",
41                 .freq_max = SR_GHZ(2.2),
42                 .freq_min = SR_KHZ(5),
43                 .power_max = 16,
44                 .power_min = -144,
45         },
46         {
47                 .model_str = "SME03A",
48                 .freq_max = SR_GHZ(3),
49                 .freq_min = SR_KHZ(5),
50                 .power_max = 16,
51                 .power_min = -144,
52         },
53         {
54                 .model_str = "SME03",
55                 .freq_max = SR_GHZ(3),
56                 .freq_min = SR_KHZ(5),
57                 .power_max = 16,
58                 .power_min = -144,
59         },
60         {
61                 .model_str = "SME06",
62                 .freq_max = SR_GHZ(1.5),
63                 .freq_min = SR_KHZ(5),
64                 .power_max = 16,
65                 .power_min = -144,
66         }
67 };
68
69 static const uint32_t scanopts[] = {
70         SR_CONF_CONN,
71         SR_CONF_SERIALCOMM,
72 };
73
74 static const uint32_t drvopts[] = {
75         SR_CONF_SIGNAL_GENERATOR,
76 };
77
78 static const uint32_t devopts[] = {
79         SR_CONF_OUTPUT_FREQUENCY | SR_CONF_GET | SR_CONF_SET | SR_CONF_LIST,
80         SR_CONF_AMPLITUDE | SR_CONF_GET | SR_CONF_SET | SR_CONF_LIST,
81 };
82
83 static int rs_init_device(struct sr_dev_inst *sdi)
84 {
85         struct dev_context *devc;
86         uint8_t model_found;
87
88         devc = sdi->priv;
89         model_found = 0;
90
91         for (size_t i = 0; i < ARRAY_SIZE(device_models); i++) {
92                 if (!strcmp(device_models[i].model_str, sdi->model)) {
93                         model_found = 1;
94                         devc->model_config = &device_models[i];
95                         break;
96                 }
97         }
98
99         if (!model_found) {
100                 sr_dbg("Device %s %s is not supported by this driver.",
101                         manufacturer, sdi->model);
102                 return SR_ERR_NA;
103         }
104
105         return SR_OK;
106 }
107
108 static struct sr_dev_inst *rs_probe_serial_device(struct sr_scpi_dev_inst *scpi)
109 {
110         struct sr_dev_inst *sdi;
111         struct dev_context *devc;
112         struct sr_scpi_hw_info *hw_info;
113
114         sdi = NULL;
115         devc = NULL;
116         hw_info = NULL;
117
118         rs_sme0x_mode_remote(scpi);
119
120         if (sr_scpi_get_hw_id(scpi, &hw_info) != SR_OK)
121                 goto fail;
122
123         if (strcmp(hw_info->manufacturer, manufacturer) != 0)
124                 goto fail;
125
126         sdi = g_malloc0(sizeof(struct sr_dev_inst));
127         sdi->vendor = g_strdup(hw_info->manufacturer);
128         sdi->model = g_strdup(hw_info->model);
129         sdi->version = g_strdup(hw_info->firmware_version);
130         sdi->serial_num = g_strdup(hw_info->serial_number);
131         sdi->driver = &rohde_schwarz_sme_0x_driver_info;
132         sdi->inst_type = SR_INST_SCPI;
133         sdi->conn = scpi;
134
135         sr_scpi_hw_info_free(hw_info);
136         hw_info = NULL;
137
138         devc = g_malloc0(sizeof(struct dev_context));
139         sdi->priv = devc;
140
141         if (rs_init_device(sdi) != SR_OK)
142                 goto fail;
143
144         return sdi;
145
146 fail:
147         if (hw_info)
148                 sr_scpi_hw_info_free(hw_info);
149
150         if (sdi)
151                 sr_dev_inst_free(sdi);
152
153         g_free(devc);
154         return NULL;
155 }
156
157 static GSList *scan(struct sr_dev_driver *di, GSList *options)
158 {
159         return sr_scpi_scan(di->context, options, rs_probe_serial_device);
160 }
161
162 static int dev_clear(const struct sr_dev_driver *di)
163 {
164         return std_dev_clear(di, NULL);
165 }
166
167 static int dev_open(struct sr_dev_inst *sdi)
168 {
169         if ((sdi->status != SR_ST_ACTIVE) && (sr_scpi_open(sdi->conn) != SR_OK))
170                 return SR_ERR;
171
172         sdi->status = SR_ST_ACTIVE;
173
174         return SR_OK;
175 }
176
177 static int dev_close(struct sr_dev_inst *sdi)
178 {
179         if (sdi->status == SR_ST_INACTIVE)
180                 return SR_OK;
181
182         sr_scpi_close(sdi->conn);
183
184         sdi->status = SR_ST_INACTIVE;
185
186         return SR_OK;
187 }
188
189 static int config_get(uint32_t key, GVariant **data,
190         const struct sr_dev_inst *sdi, const struct sr_channel_group *cg)
191 {
192         double value_f;
193
194         (void) cg;
195
196         switch (key) {
197         case SR_CONF_OUTPUT_FREQUENCY:
198                 rs_sme0x_get_freq(sdi, &value_f);
199                 *data = g_variant_new_double(value_f);
200                 break;
201         case SR_CONF_AMPLITUDE:
202                 rs_sme0x_get_power(sdi, &value_f);
203                 *data = g_variant_new_double(value_f);
204                 break;
205         default:
206                 return SR_ERR_NA;
207         }
208
209         return SR_OK;
210 }
211
212 static int config_set(uint32_t key, GVariant *data,
213         const struct sr_dev_inst *sdi, const struct sr_channel_group *cg)
214 {
215         double value_f;
216
217         (void)cg;
218
219         if (!sdi)
220                 return SR_ERR_ARG;
221
222         if (sdi->status != SR_ST_ACTIVE)
223                 return SR_ERR_DEV_CLOSED;
224
225         switch (key) {
226         case SR_CONF_OUTPUT_FREQUENCY:
227                 value_f = g_variant_get_double(data);
228                 rs_sme0x_set_freq(sdi, value_f);
229                 break;
230         case SR_CONF_AMPLITUDE:
231                 value_f = g_variant_get_double(data);
232                 rs_sme0x_set_power(sdi, value_f);
233                 break;
234         default:
235                 return SR_ERR_NA;
236         }
237
238         return SR_OK;
239 }
240
241 static int config_list(uint32_t key, GVariant **data,
242         const struct sr_dev_inst *sdi, const struct sr_channel_group *cg)
243 {
244         (void)sdi;
245         (void)cg;
246
247         /* Return drvopts without sdi (and devopts with sdi, see below). */
248         if (key == SR_CONF_DEVICE_OPTIONS && !sdi) {
249                 *data = g_variant_new_fixed_array(G_VARIANT_TYPE_UINT32,
250                                 drvopts, ARRAY_SIZE(drvopts), sizeof(uint32_t));
251                 return SR_OK;
252         }
253
254         switch (key) {
255         case SR_CONF_SCAN_OPTIONS:
256                 *data = g_variant_new_fixed_array(G_VARIANT_TYPE_UINT32,
257                         scanopts, ARRAY_SIZE(scanopts), sizeof(uint32_t));
258                 break;
259         case SR_CONF_DEVICE_OPTIONS:
260                 *data = g_variant_new_fixed_array(G_VARIANT_TYPE_UINT32,
261                         devopts, ARRAY_SIZE(devopts), sizeof(uint32_t));
262                 break;
263         default:
264                 return SR_ERR_NA;
265         }
266
267         return SR_OK;
268 }
269
270 static int dev_acquisition_start(const struct sr_dev_inst *sdi)
271 {
272         if (sdi->status != SR_ST_ACTIVE)
273                 return SR_ERR_DEV_CLOSED;
274
275         return SR_OK;
276 }
277
278 SR_PRIV struct sr_dev_driver rohde_schwarz_sme_0x_driver_info = {
279         .name = "rohde-schwarz-sme-0x",
280         .longname = "Rohde&Schwarz SME-0x",
281         .api_version = 1,
282         .init = std_init,
283         .cleanup = std_cleanup,
284         .scan = scan,
285         .dev_list = std_dev_list,
286         .dev_clear = dev_clear,
287         .config_get = config_get,
288         .config_set = config_set,
289         .config_list = config_list,
290         .dev_open = dev_open,
291         .dev_close = dev_close,
292         .dev_acquisition_start = dev_acquisition_start,
293         .dev_acquisition_stop = std_serial_dev_acquisition_stop,
294         .context = NULL,
295 };
296
297 SR_REGISTER_DEV_DRIVER(rohde_schwarz_sme_0x_driver_info);