]> sigrok.org Git - libsigrok.git/blob - src/hardware/rohde-schwarz-sme-0x/api.c
rohde-schwarz-sme-0x: Coding style fixes
[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 devopts[] = {
75         SR_CONF_OUTPUT_FREQUENCY | SR_CONF_GET | SR_CONF_SET | SR_CONF_LIST,
76         SR_CONF_AMPLITUDE | SR_CONF_GET | SR_CONF_SET | SR_CONF_LIST,
77 };
78
79 static int rs_init_device(struct sr_dev_inst *sdi)
80 {
81         struct dev_context *devc;
82         uint8_t model_found;
83
84         devc = sdi->priv;
85         model_found = 0;
86
87         for (size_t i = 0; i < ARRAY_SIZE(device_models); i++) {
88                 if (!strcmp(device_models[i].model_str, sdi->model)) {
89                         model_found = 1;
90                         devc->model_config = &device_models[i];
91                         break;
92                 }
93         }
94
95         if (!model_found) {
96                 sr_dbg("Device %s %s is not supported by this driver", manufacturer, sdi->model);
97                 return SR_ERR_NA;
98         }
99
100         return SR_OK;
101 }
102
103 static struct sr_dev_inst *rs_probe_serial_device(struct sr_scpi_dev_inst *scpi)
104 {
105         struct sr_dev_inst *sdi;
106         struct dev_context *devc;
107         struct sr_scpi_hw_info *hw_info;
108
109         sdi = NULL;
110         devc = NULL;
111         hw_info = NULL;
112
113         rs_sme0x_mode_remote(scpi);
114
115         if (sr_scpi_get_hw_id(scpi, &hw_info) != SR_OK) {
116                 goto fail;
117         }
118
119         if (strcmp(hw_info->manufacturer, manufacturer) != 0) {
120                 goto fail;
121         }
122
123         sdi = g_malloc0(sizeof(struct sr_dev_inst));
124         sdi->vendor = g_strdup(hw_info->manufacturer);
125         sdi->model = g_strdup(hw_info->model);
126         sdi->version = g_strdup(hw_info->firmware_version);
127         sdi->serial_num = g_strdup(hw_info->serial_number);
128         sdi->driver = &rohde_schwarz_sme_0x_driver_info;
129         sdi->inst_type = SR_INST_SCPI;
130         sdi->conn = scpi;
131
132         sr_scpi_hw_info_free(hw_info);
133         hw_info = NULL;
134
135         devc = g_malloc0(sizeof(struct dev_context));
136         sdi->priv = devc;
137
138         if (rs_init_device(sdi) != SR_OK) {
139                 goto fail;
140         }
141
142         return sdi;
143
144 fail:
145         if (hw_info) {
146                 sr_scpi_hw_info_free(hw_info);
147         }
148
149         if (sdi) {
150                 sr_dev_inst_free(sdi);
151         }
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
173         sdi->status = SR_ST_ACTIVE;
174
175         return SR_OK;
176 }
177
178 static int dev_close(struct sr_dev_inst *sdi)
179 {
180         if (sdi->status == SR_ST_INACTIVE) {
181                 return SR_OK;
182         }
183
184         sr_scpi_close(sdi->conn);
185
186         sdi->status = SR_ST_INACTIVE;
187
188         return SR_OK;
189 }
190
191 static int config_get(uint32_t key, GVariant **data,
192         const struct sr_dev_inst *sdi, const struct sr_channel_group *cg)
193 {
194         double value_f;
195
196         (void) cg;
197
198         switch (key) {
199         case SR_CONF_OUTPUT_FREQUENCY:
200                 rs_sme0x_get_freq(sdi, &value_f);
201                 *data = g_variant_new_double(value_f);
202                 break;
203         case SR_CONF_AMPLITUDE:
204                 rs_sme0x_get_power(sdi, &value_f);
205                 *data = g_variant_new_double(value_f);
206                 break;
207         default:
208                 return SR_ERR_NA;
209         }
210
211         return SR_OK;
212 }
213
214 static int config_set(uint32_t key, GVariant *data,
215         const struct sr_dev_inst *sdi, const struct sr_channel_group *cg)
216 {
217         double value_f;
218
219         (void)cg;
220
221         if (!sdi) {
222                 return SR_ERR_ARG;
223         }
224
225         if (sdi->status != SR_ST_ACTIVE) {
226                 return SR_ERR_DEV_CLOSED;
227         }
228
229         switch (key) {
230         case SR_CONF_OUTPUT_FREQUENCY:
231                 value_f = g_variant_get_double(data);
232                 rs_sme0x_set_freq(sdi, value_f);
233                 break;
234         case SR_CONF_AMPLITUDE:
235                 value_f = g_variant_get_double(data);
236                 rs_sme0x_set_power(sdi, value_f);
237                 break;
238         default:
239                 return SR_ERR_NA;
240         }
241
242         return SR_OK;
243 }
244
245 static int config_list(uint32_t key, GVariant **data,
246         const struct sr_dev_inst *sdi, const struct sr_channel_group *cg)
247 {
248         (void)sdi;
249         (void)cg;
250
251         switch (key) {
252         case SR_CONF_SCAN_OPTIONS:
253                 *data = g_variant_new_fixed_array(G_VARIANT_TYPE_UINT32, scanopts, ARRAY_SIZE(scanopts), sizeof(uint32_t));
254                 break;
255         case SR_CONF_DEVICE_OPTIONS:
256                 *data = g_variant_new_fixed_array(G_VARIANT_TYPE_UINT32, devopts, ARRAY_SIZE(devopts), sizeof(uint32_t));
257                 break;
258         default:
259                 return SR_ERR_NA;
260         }
261
262         return SR_OK;
263 }
264
265 static int dev_acquisition_start(const struct sr_dev_inst *sdi)
266 {
267         if (sdi->status != SR_ST_ACTIVE) {
268                 return SR_ERR_DEV_CLOSED;
269         }
270
271         return SR_OK;
272 }
273
274 SR_PRIV struct sr_dev_driver rohde_schwarz_sme_0x_driver_info = {
275         .name = "rohde-schwarz-sme-0x",
276         .longname = "Rohde&Schwarz SME-0x",
277         .api_version = 1,
278         .init = std_init,
279         .cleanup = std_cleanup,
280         .scan = scan,
281         .dev_list = std_dev_list,
282         .dev_clear = dev_clear,
283         .config_get = config_get,
284         .config_set = config_set,
285         .config_list = config_list,
286         .dev_open = dev_open,
287         .dev_close = dev_close,
288         .dev_acquisition_start = dev_acquisition_start,
289         .dev_acquisition_stop = std_serial_dev_acquisition_stop,
290         .context = NULL,
291 };
292
293 SR_REGISTER_DEV_DRIVER(rohde_schwarz_sme_0x_driver_info);