]> sigrok.org Git - libsigrok.git/blob - src/hardware/baylibre-acme/api.c
baylibre-acme: Use SR_HZ_TO_NS() when configuring the timerfd.
[libsigrok.git] / src / hardware / baylibre-acme / api.c
1 /*
2  * This file is part of the libsigrok project.
3  *
4  * Copyright (C) 2015 Bartosz Golaszewski <bgolaszewski@baylibre.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 #include <time.h>
22 #include <sys/timerfd.h>
23
24 SR_PRIV struct sr_dev_driver baylibre_acme_driver_info;
25
26 static const uint32_t devopts[] = {
27         SR_CONF_CONTINUOUS | SR_CONF_SET,
28         SR_CONF_LIMIT_SAMPLES | SR_CONF_GET | SR_CONF_SET,
29         SR_CONF_LIMIT_MSEC | SR_CONF_GET | SR_CONF_SET,
30         SR_CONF_SAMPLERATE | SR_CONF_GET | SR_CONF_SET | SR_CONF_LIST,
31 };
32
33 /*
34  * Currently there are two channel-group/probe options for ACME:
35  *   - SR_CONF_PROBE_FACTOR - allows to modify current shunt resistance
36  *     calibration
37  *   - SR_CONF_POWER_OFF - allows to remotely cut-off/restore power to
38  *     measured devices
39  *
40  * They are not static - we have to check each probe's capabilities in
41  * config_list().
42  */
43 #define MAX_DEVOPTS_CG          2
44 #define HAS_PROBE_FACTOR        (SR_CONF_PROBE_FACTOR | SR_CONF_GET | SR_CONF_SET)
45 #define HAS_POWER_OFF           (SR_CONF_POWER_OFF | SR_CONF_GET | SR_CONF_SET)
46
47 #define MAX_SAMPLE_RATE 500 /* In Hz */
48
49 static const uint64_t samplerates[] = {
50         SR_HZ(1),
51         SR_HZ(MAX_SAMPLE_RATE),
52         SR_HZ(1),
53 };
54
55 static int init(struct sr_dev_driver *di, struct sr_context *sr_ctx)
56 {
57         return std_init(sr_ctx, di, LOG_PREFIX);
58 }
59
60 static GSList *scan(struct sr_dev_driver *di, GSList *options)
61 {
62         struct drv_context *drvc;
63         struct dev_context *devc;
64         struct sr_dev_inst *sdi;
65         GSList *devices;
66         gboolean status;
67         int i;
68
69         (void)options;
70
71         drvc = di->priv;
72         devices = NULL;
73
74         devc = g_malloc0(sizeof(struct dev_context));
75         devc->samplerate = SR_HZ(10);
76
77         sdi = g_malloc0(sizeof(struct sr_dev_inst));
78         sdi->status = SR_ST_INACTIVE;
79         sdi->vendor = g_strdup("BayLibre");
80         sdi->model = g_strdup("ACME");
81         sdi->driver = di;
82         sdi->priv = devc;
83
84         status = bl_acme_is_sane();
85         if (!status)
86                 goto err_out;
87
88         /*
89          * Iterate over all ACME connectors and check if any probes
90          * are present.
91          */
92         for (i = 0; i < MAX_PROBES; i++) {
93                 /*
94                  * First check if there's an energy probe on this connector. If
95                  * not, and we're already at the fifth probe - see if we can
96                  * detect a temperature probe.
97                  */
98                 status = bl_acme_detect_probe(bl_acme_get_enrg_addr(i),
99                                               PROBE_NUM(i), ENRG_PROBE_NAME);
100                 if (status) {
101                         /* Energy probe detected. */
102                         status = bl_acme_register_probe(sdi, PROBE_ENRG,
103                                         bl_acme_get_enrg_addr(i), PROBE_NUM(i));
104                         if (!status) {
105                                 sr_err("Error registering power probe %d",
106                                        PROBE_NUM(i));
107                                 continue;
108                         }
109                 } else if (i >= TEMP_PRB_START_INDEX) {
110                         status = bl_acme_detect_probe(bl_acme_get_temp_addr(i),
111                                               PROBE_NUM(i), TEMP_PROBE_NAME);
112                         if (status) {
113                                 /* Temperature probe detected. */
114                                 status = bl_acme_register_probe(sdi,PROBE_TEMP,
115                                         bl_acme_get_temp_addr(i), PROBE_NUM(i));
116                                 if (!status) {
117                                         sr_err("Error registering temp "
118                                                "probe %d", PROBE_NUM(i));
119                                         continue;
120                                 }
121                         }
122                 }
123         }
124
125         /*
126          * Let's assume there's no ACME device present if no probe
127          * has been registered.
128          */
129         if (!sdi->channel_groups)
130                 goto err_out;
131
132         devices = g_slist_append(devices, sdi);
133         drvc->instances = g_slist_append(drvc->instances, sdi);
134
135         return devices;
136
137 err_out:
138         g_free(devc);
139         sr_dev_inst_free(sdi);
140
141         return NULL;
142 }
143
144 static GSList *dev_list(const struct sr_dev_driver *di)
145 {
146         return ((struct drv_context *)(di->priv))->instances;
147 }
148
149 static int dev_clear(const struct sr_dev_driver *di)
150 {
151         return std_dev_clear(di, NULL);
152 }
153
154 static int dev_open(struct sr_dev_inst *sdi)
155 {
156         (void)sdi;
157
158         /* Nothing to do here. */
159         sdi->status = SR_ST_ACTIVE;
160
161         return SR_OK;
162 }
163
164 static int dev_close(struct sr_dev_inst *sdi)
165 {
166         (void)sdi;
167
168         /* Nothing to do here. */
169         sdi->status = SR_ST_INACTIVE;
170
171         return SR_OK;
172 }
173
174 static int cleanup(const struct sr_dev_driver *di)
175 {
176         dev_clear(di);
177
178         return SR_OK;
179 }
180
181 static int config_get(uint32_t key, GVariant **data,
182                       const struct sr_dev_inst *sdi,
183                       const struct sr_channel_group *cg)
184 {
185         struct dev_context *devc;
186         int ret;
187         uint64_t shunt;
188         gboolean power_off;
189
190         devc = sdi->priv;
191
192         ret = SR_OK;
193         switch (key) {
194         case SR_CONF_LIMIT_SAMPLES:
195                 *data = g_variant_new_uint64(devc->limit_samples);
196                 break;
197         case SR_CONF_LIMIT_MSEC:
198                 *data = g_variant_new_uint64(devc->limit_msec);
199                 break;
200         case SR_CONF_SAMPLERATE:
201                 *data = g_variant_new_uint64(devc->samplerate);
202                 break;
203         case SR_CONF_PROBE_FACTOR:
204                 if (!cg)
205                         return SR_ERR_CHANNEL_GROUP;
206                 ret = bl_acme_get_shunt(cg, &shunt);
207                 if (ret == SR_OK)
208                         *data = g_variant_new_uint64(shunt);
209                 break;
210         case SR_CONF_POWER_OFF:
211                 if (!cg)
212                         return SR_ERR_CHANNEL_GROUP;
213                 ret = bl_acme_read_power_state(cg, &power_off);
214                 if (ret == SR_OK)
215                         *data = g_variant_new_boolean(power_off);
216                 break;
217         default:
218                 return SR_ERR_NA;
219         }
220
221         return ret;
222 }
223
224 static int config_set(uint32_t key, GVariant *data,
225                       const struct sr_dev_inst *sdi,
226                       const struct sr_channel_group *cg)
227 {
228         struct dev_context *devc;
229         uint64_t samplerate;
230         int ret;
231
232         if (sdi->status != SR_ST_ACTIVE)
233                 return SR_ERR_DEV_CLOSED;
234
235         devc = sdi->priv;
236
237         ret = SR_OK;
238         switch (key) {
239         case SR_CONF_LIMIT_SAMPLES:
240                 devc->limit_samples = g_variant_get_uint64(data);
241                 devc->limit_msec = 0;
242                 break;
243         case SR_CONF_LIMIT_MSEC:
244                 devc->limit_msec = g_variant_get_uint64(data) * 1000;
245                 devc->limit_samples = 0;
246                 break;
247         case SR_CONF_SAMPLERATE:
248                 samplerate = g_variant_get_uint64(data);
249                 if (samplerate > MAX_SAMPLE_RATE) {
250                         sr_err("Maximum sample rate is %d", MAX_SAMPLE_RATE);
251                         ret = SR_ERR_SAMPLERATE;
252                         break;
253                 }
254                 devc->samplerate = samplerate;
255                 bl_acme_maybe_set_update_interval(sdi, samplerate);
256                 break;
257         case SR_CONF_PROBE_FACTOR:
258                 if (!cg)
259                         return SR_ERR_CHANNEL_GROUP;
260                 ret = bl_acme_set_shunt(cg, g_variant_get_uint64(data));
261                 break;
262         case SR_CONF_POWER_OFF:
263                 if (!cg)
264                         return SR_ERR_CHANNEL_GROUP;
265                 ret = bl_acme_set_power_off(cg, g_variant_get_boolean(data));
266                 break;
267         default:
268                 ret = SR_ERR_NA;
269         }
270
271         return ret;
272 }
273
274 static int config_list(uint32_t key, GVariant **data,
275                        const struct sr_dev_inst *sdi,
276                        const struct sr_channel_group *cg)
277 {
278         uint32_t devopts_cg[MAX_DEVOPTS_CG];
279         GVariant *gvar;
280         GVariantBuilder gvb;
281         int ret, num_devopts_cg = 0;
282
283         (void)sdi;
284         (void)cg;
285
286         ret = SR_OK;
287         if (!cg) {
288                 switch (key) {
289                 case SR_CONF_DEVICE_OPTIONS:
290                         *data = g_variant_new_fixed_array(G_VARIANT_TYPE_UINT32,
291                                 devopts, ARRAY_SIZE(devopts), sizeof(uint32_t));
292                         break;
293                 case SR_CONF_SAMPLERATE:
294                         g_variant_builder_init(&gvb, G_VARIANT_TYPE("a{sv}"));
295                         gvar = g_variant_new_fixed_array(G_VARIANT_TYPE("t"),
296                                 samplerates, ARRAY_SIZE(samplerates), sizeof(uint64_t));
297                         g_variant_builder_add(&gvb, "{sv}",
298                                               "samplerate-steps", gvar);
299                         *data = g_variant_builder_end(&gvb);
300                         break;
301                 default:
302                         return SR_ERR_NA;
303                 }
304         } else {
305                 switch (key) {
306                 case SR_CONF_DEVICE_OPTIONS:
307                         if (bl_acme_get_probe_type(cg) == PROBE_ENRG)
308                                 devopts_cg[num_devopts_cg++] = HAS_PROBE_FACTOR;
309                         if (bl_acme_probe_has_pws(cg))
310                                 devopts_cg[num_devopts_cg++] = HAS_POWER_OFF;
311
312                         *data = g_variant_new_fixed_array(G_VARIANT_TYPE_UINT32,
313                                 devopts_cg, num_devopts_cg, sizeof(uint32_t));
314                         break;
315                 default:
316                         return SR_ERR_NA;
317                 }
318         }
319
320         return ret;
321 }
322
323 static void dev_acquisition_close(const struct sr_dev_inst *sdi)
324 {
325         GSList *chl;
326         struct sr_channel *ch;
327
328         for (chl = sdi->channels; chl; chl = chl->next) {
329                 ch = chl->data;
330                 bl_acme_close_channel(ch);
331         }
332 }
333
334 static int dev_acquisition_open(const struct sr_dev_inst *sdi)
335 {
336         GSList *chl;
337         struct sr_channel *ch;
338
339         for (chl = sdi->channels; chl; chl = chl->next) {
340                 ch = chl->data;
341                 if (bl_acme_open_channel(ch)) {
342                         sr_err("Error opening channel %s", ch->name);
343                         dev_acquisition_close(sdi);
344                         return SR_ERR;
345                 }
346         }
347
348         return 0;
349 }
350
351 static int dev_acquisition_start(const struct sr_dev_inst *sdi, void *cb_data)
352 {
353         struct dev_context *devc;
354         struct itimerspec tspec = {
355                 .it_interval = { 0, 0 },
356                 .it_value = { 0, 0 }
357         };
358
359         (void)cb_data;
360
361         if (sdi->status != SR_ST_ACTIVE)
362                 return SR_ERR_DEV_CLOSED;
363
364         if (dev_acquisition_open(sdi))
365                 return SR_ERR;
366
367         devc = sdi->priv;
368         devc->samples_read = 0;
369         devc->samples_missed = 0;
370         devc->timer_fd = timerfd_create(CLOCK_MONOTONIC, 0);
371         if (devc->timer_fd < 0) {
372                 sr_err("Error creating timer fd");
373                 return SR_ERR;
374         }
375
376         tspec.it_interval.tv_sec = 0;
377         tspec.it_interval.tv_nsec = SR_HZ_TO_NS(devc->samplerate);
378         tspec.it_value = tspec.it_interval;
379
380         if (timerfd_settime(devc->timer_fd, 0, &tspec, NULL)) {
381                 sr_err("Failed to set timer");
382                 close(devc->timer_fd);
383                 return SR_ERR;
384         }
385
386         devc->channel = g_io_channel_unix_new(devc->timer_fd);
387         g_io_channel_set_flags(devc->channel, G_IO_FLAG_NONBLOCK, NULL);
388         g_io_channel_set_encoding(devc->channel, NULL, NULL);
389         g_io_channel_set_buffered(devc->channel, FALSE);
390
391         sr_session_source_add_channel(sdi->session, devc->channel,
392                 G_IO_IN | G_IO_ERR, 1000, bl_acme_receive_data, (void *)sdi);
393
394         /* Send header packet to the session bus. */
395         std_session_send_df_header(sdi, LOG_PREFIX);
396         devc->start_time = g_get_monotonic_time();
397
398         return SR_OK;
399 }
400
401 static int dev_acquisition_stop(struct sr_dev_inst *sdi, void *cb_data)
402 {
403         struct sr_datafeed_packet packet;
404         struct dev_context *devc;
405
406         (void)cb_data;
407
408         devc = sdi->priv;
409
410         if (sdi->status != SR_ST_ACTIVE)
411                 return SR_ERR_DEV_CLOSED;
412
413         dev_acquisition_close(sdi);
414         sr_session_source_remove_channel(sdi->session, devc->channel);
415         g_io_channel_shutdown(devc->channel, FALSE, NULL);
416         g_io_channel_unref(devc->channel);
417         devc->channel = NULL;
418         close(devc->timer_fd);
419
420         /* Send last packet. */
421         packet.type = SR_DF_END;
422         sr_session_send(sdi, &packet);
423
424         if (devc->samples_missed > 0)
425                 sr_warn("%d samples missed", devc->samples_missed);
426
427         return SR_OK;
428 }
429
430 SR_PRIV struct sr_dev_driver baylibre_acme_driver_info = {
431         .name = "baylibre-acme",
432         .longname = "BayLibre ACME (Another Cute Measurement Equipment)",
433         .api_version = 1,
434         .init = init,
435         .cleanup = cleanup,
436         .scan = scan,
437         .dev_list = dev_list,
438         .dev_clear = dev_clear,
439         .config_get = config_get,
440         .config_set = config_set,
441         .config_list = config_list,
442         .dev_open = dev_open,
443         .dev_close = dev_close,
444         .dev_acquisition_start = dev_acquisition_start,
445         .dev_acquisition_stop = dev_acquisition_stop,
446         .priv = NULL,
447 };