]> sigrok.org Git - libsigrok.git/blob - hardware/openbench-logic-sniffer/api.c
63c98821d7de00ad6a7b56b4d3c9420249d986f9
[libsigrok.git] / hardware / openbench-logic-sniffer / api.c
1 /*
2  * This file is part of the libsigrok project.
3  *
4  * Copyright (C) 2013 Bert Vermeulen <bert@biot.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
22 #define SERIALCOMM "115200/8n1"
23
24 static const int32_t hwopts[] = {
25         SR_CONF_CONN,
26         SR_CONF_SERIALCOMM,
27 };
28
29 static const int32_t hwcaps[] = {
30         SR_CONF_LOGIC_ANALYZER,
31         SR_CONF_SAMPLERATE,
32         SR_CONF_TRIGGER_TYPE,
33         SR_CONF_CAPTURE_RATIO,
34         SR_CONF_LIMIT_SAMPLES,
35         SR_CONF_RLE,
36 };
37
38 /* Probes are numbered 0-31 (on the PCB silkscreen). */
39 SR_PRIV const char *ols_probe_names[NUM_PROBES + 1] = {
40         "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12",
41         "13", "14", "15", "16", "17", "18", "19", "20", "21", "22", "23",
42         "24", "25", "26", "27", "28", "29", "30", "31",
43         NULL,
44 };
45
46 /* Default supported samplerates, can be overridden by device metadata. */
47 static const uint64_t samplerates[] = {
48         SR_HZ(10),
49         SR_MHZ(200),
50         SR_HZ(1),
51 };
52
53 SR_PRIV struct sr_dev_driver ols_driver_info;
54 static struct sr_dev_driver *di = &ols_driver_info;
55
56 static int dev_clear(void)
57 {
58         return std_dev_clear(di, NULL);
59 }
60
61 static int init(struct sr_context *sr_ctx)
62 {
63         return std_init(sr_ctx, di, LOG_PREFIX);
64 }
65
66 static GSList *scan(GSList *options)
67 {
68         struct sr_config *src;
69         struct sr_dev_inst *sdi;
70         struct drv_context *drvc;
71         struct dev_context *devc;
72         struct sr_probe *probe;
73         struct sr_serial_dev_inst *serial;
74         GPollFD probefd;
75         GSList *l, *devices;
76         int ret, i;
77         const char *conn, *serialcomm;
78         char buf[8];
79
80         drvc = di->priv;
81
82         devices = NULL;
83
84         conn = serialcomm = NULL;
85         for (l = options; l; l = l->next) {
86                 src = l->data;
87                 switch (src->key) {
88                 case SR_CONF_CONN:
89                         conn = g_variant_get_string(src->data, NULL);
90                         break;
91                 case SR_CONF_SERIALCOMM:
92                         serialcomm = g_variant_get_string(src->data, NULL);
93                         break;
94                 }
95         }
96         if (!conn)
97                 return NULL;
98
99         if (serialcomm == NULL)
100                 serialcomm = SERIALCOMM;
101
102         if (!(serial = sr_serial_dev_inst_new(conn, serialcomm)))
103                 return NULL;
104
105         /* The discovery procedure is like this: first send the Reset
106          * command (0x00) 5 times, since the device could be anywhere
107          * in a 5-byte command. Then send the ID command (0x02).
108          * If the device responds with 4 bytes ("OLS1" or "SLA1"), we
109          * have a match.
110          */
111         sr_info("Probing %s.", conn);
112         if (serial_open(serial, SERIAL_RDWR | SERIAL_NONBLOCK) != SR_OK)
113                 return NULL;
114
115         ret = SR_OK;
116         for (i = 0; i < 5; i++) {
117                 if ((ret = send_shortcommand(serial, CMD_RESET)) != SR_OK) {
118                         sr_err("Port %s is not writable.", conn);
119                         break;
120                 }
121         }
122         if (ret != SR_OK) {
123                 serial_close(serial);
124                 sr_err("Could not use port %s. Quitting.", conn);
125                 return NULL;
126         }
127         send_shortcommand(serial, CMD_ID);
128
129         /* Wait 10ms for a response. */
130         g_usleep(10000);
131
132         probefd.fd = serial->fd;
133         probefd.events = G_IO_IN;
134         g_poll(&probefd, 1, 1);
135
136         if (probefd.revents != G_IO_IN)
137                 return NULL;
138         if (serial_read(serial, buf, 4) != 4)
139                 return NULL;
140         if (strncmp(buf, "1SLO", 4) && strncmp(buf, "1ALS", 4))
141                 return NULL;
142
143         /* Definitely using the OLS protocol, check if it supports
144          * the metadata command.
145          */
146         send_shortcommand(serial, CMD_METADATA);
147         if (g_poll(&probefd, 1, 10) > 0) {
148                 /* Got metadata. */
149                 sdi = get_metadata(serial);
150                 sdi->index = 0;
151                 devc = sdi->priv;
152         } else {
153                 /* Not an OLS -- some other board that uses the sump protocol. */
154                 sr_info("Device does not support metadata.");
155                 sdi = sr_dev_inst_new(0, SR_ST_INACTIVE,
156                                 "Sump", "Logic Analyzer", "v1.0");
157                 sdi->driver = di;
158                 for (i = 0; i < 32; i++) {
159                         if (!(probe = sr_probe_new(i, SR_PROBE_LOGIC, TRUE,
160                                         ols_probe_names[i])))
161                                 return 0;
162                         sdi->probes = g_slist_append(sdi->probes, probe);
163                 }
164                 devc = ols_dev_new();
165                 sdi->priv = devc;
166         }
167         /* Configure samplerate and divider. */
168         if (ols_set_samplerate(sdi, DEFAULT_SAMPLERATE) != SR_OK)
169                 sr_dbg("Failed to set default samplerate (%"PRIu64").",
170                                 DEFAULT_SAMPLERATE);
171         /* Clear trigger masks, values and stages. */
172         ols_configure_probes(sdi);
173         sdi->inst_type = SR_INST_SERIAL;
174         sdi->conn = serial;
175
176         drvc->instances = g_slist_append(drvc->instances, sdi);
177         devices = g_slist_append(devices, sdi);
178
179         serial_close(serial);
180
181         return devices;
182 }
183
184 static GSList *dev_list(void)
185 {
186         return ((struct drv_context *)(di->priv))->instances;
187 }
188
189 static int dev_open(struct sr_dev_inst *sdi)
190 {
191         struct sr_serial_dev_inst *serial;
192
193         serial = sdi->conn;
194         if (serial_open(serial, SERIAL_RDWR) != SR_OK)
195                 return SR_ERR;
196
197         sdi->status = SR_ST_ACTIVE;
198
199         return SR_OK;
200 }
201
202 static int dev_close(struct sr_dev_inst *sdi)
203 {
204         struct sr_serial_dev_inst *serial;
205
206         serial = sdi->conn;
207         if (serial && serial->fd != -1) {
208                 serial_close(serial);
209                 sdi->status = SR_ST_INACTIVE;
210         }
211
212         return SR_OK;
213 }
214
215 static int cleanup(void)
216 {
217         return dev_clear();
218 }
219
220 static int config_get(int id, GVariant **data, const struct sr_dev_inst *sdi)
221 {
222         struct dev_context *devc;
223
224         if (!sdi)
225                 return SR_ERR_ARG;
226
227         devc = sdi->priv;
228         switch (id) {
229         case SR_CONF_SAMPLERATE:
230                 *data = g_variant_new_uint64(devc->cur_samplerate);
231                 break;
232         case SR_CONF_CAPTURE_RATIO:
233                 *data = g_variant_new_uint64(devc->capture_ratio);
234                 break;
235         case SR_CONF_LIMIT_SAMPLES:
236                 *data = g_variant_new_uint64(devc->limit_samples);
237                 break;
238         case SR_CONF_RLE:
239                 *data = g_variant_new_boolean(devc->flag_reg & FLAG_RLE ? TRUE : FALSE);
240                 break;
241         default:
242                 return SR_ERR_NA;
243         }
244
245         return SR_OK;
246 }
247
248 static int config_set(int id, GVariant *data, const struct sr_dev_inst *sdi)
249 {
250         struct dev_context *devc;
251         int ret;
252         uint64_t tmp_u64;
253
254         if (sdi->status != SR_ST_ACTIVE)
255                 return SR_ERR_DEV_CLOSED;
256
257         devc = sdi->priv;
258
259         switch (id) {
260         case SR_CONF_SAMPLERATE:
261                 tmp_u64 = g_variant_get_uint64(data);
262                 if (tmp_u64 < samplerates[0] || tmp_u64 > samplerates[1])
263                         return SR_ERR_SAMPLERATE;
264                 ret = ols_set_samplerate(sdi, g_variant_get_uint64(data));
265                 break;
266         case SR_CONF_LIMIT_SAMPLES:
267                 tmp_u64 = g_variant_get_uint64(data);
268                 if (tmp_u64 < MIN_NUM_SAMPLES)
269                         return SR_ERR;
270                 devc->limit_samples = tmp_u64;
271                 ret = SR_OK;
272                 break;
273         case SR_CONF_CAPTURE_RATIO:
274                 devc->capture_ratio = g_variant_get_uint64(data);
275                 if (devc->capture_ratio < 0 || devc->capture_ratio > 100) {
276                         devc->capture_ratio = 0;
277                         ret = SR_ERR;
278                 } else
279                         ret = SR_OK;
280                 break;
281         case SR_CONF_RLE:
282                 if (g_variant_get_boolean(data)) {
283                         sr_info("Enabling RLE.");
284                         devc->flag_reg |= FLAG_RLE;
285                 } else {
286                         sr_info("Disabling RLE.");
287                         devc->flag_reg &= ~FLAG_RLE;
288                 }
289                 ret = SR_OK;
290                 break;
291         default:
292                 ret = SR_ERR_NA;
293         }
294
295         return ret;
296 }
297
298 static int config_list(int key, GVariant **data, const struct sr_dev_inst *sdi)
299 {
300         GVariant *gvar;
301         GVariantBuilder gvb;
302
303         (void)sdi;
304
305         switch (key) {
306         case SR_CONF_SCAN_OPTIONS:
307                 *data = g_variant_new_fixed_array(G_VARIANT_TYPE_INT32,
308                                 hwopts, ARRAY_SIZE(hwopts), sizeof(int32_t));
309                 break;
310         case SR_CONF_DEVICE_OPTIONS:
311                 *data = g_variant_new_fixed_array(G_VARIANT_TYPE_INT32,
312                                 hwcaps, ARRAY_SIZE(hwcaps), sizeof(int32_t));
313                 break;
314         case SR_CONF_SAMPLERATE:
315                 g_variant_builder_init(&gvb, G_VARIANT_TYPE("a{sv}"));
316                 gvar = g_variant_new_fixed_array(G_VARIANT_TYPE("t"), samplerates,
317                                 ARRAY_SIZE(samplerates), sizeof(uint64_t));
318                 g_variant_builder_add(&gvb, "{sv}", "samplerate-steps", gvar);
319                 *data = g_variant_builder_end(&gvb);
320                 break;
321         case SR_CONF_TRIGGER_TYPE:
322                 *data = g_variant_new_string(TRIGGER_TYPE);
323                 break;
324         default:
325                 return SR_ERR_NA;
326         }
327
328         return SR_OK;
329 }
330
331 static int dev_acquisition_start(const struct sr_dev_inst *sdi,
332                 void *cb_data)
333 {
334         struct dev_context *devc;
335         struct sr_serial_dev_inst *serial;
336         uint32_t trigger_config[4];
337         uint32_t data;
338         uint16_t readcount, delaycount;
339         uint8_t changrp_mask;
340         int num_channels;
341         int i;
342
343         if (sdi->status != SR_ST_ACTIVE)
344                 return SR_ERR_DEV_CLOSED;
345
346         devc = sdi->priv;
347         serial = sdi->conn;
348
349         if (ols_configure_probes(sdi) != SR_OK) {
350                 sr_err("Failed to configure probes.");
351                 return SR_ERR;
352         }
353
354         /*
355          * Enable/disable channel groups in the flag register according to the
356          * probe mask. Calculate this here, because num_channels is needed
357          * to limit readcount.
358          */
359         changrp_mask = 0;
360         num_channels = 0;
361         for (i = 0; i < 4; i++) {
362                 if (devc->probe_mask & (0xff << (i * 8))) {
363                         changrp_mask |= (1 << i);
364                         num_channels++;
365                 }
366         }
367
368         /*
369          * Limit readcount to prevent reading past the end of the hardware
370          * buffer.
371          */
372         readcount = MIN(devc->max_samples / num_channels, devc->limit_samples) / 4;
373
374         memset(trigger_config, 0, 16);
375         trigger_config[devc->num_stages] |= 0x08;
376         if (devc->trigger_mask[0]) {
377                 delaycount = readcount * (1 - devc->capture_ratio / 100.0);
378                 devc->trigger_at = (readcount - delaycount) * 4 - devc->num_stages;
379
380                 if (send_longcommand(serial, CMD_SET_TRIGGER_MASK_0,
381                         reverse32(devc->trigger_mask[0])) != SR_OK)
382                         return SR_ERR;
383                 if (send_longcommand(serial, CMD_SET_TRIGGER_VALUE_0,
384                         reverse32(devc->trigger_value[0])) != SR_OK)
385                         return SR_ERR;
386                 if (send_longcommand(serial, CMD_SET_TRIGGER_CONFIG_0,
387                         trigger_config[0]) != SR_OK)
388                         return SR_ERR;
389
390                 if (send_longcommand(serial, CMD_SET_TRIGGER_MASK_1,
391                         reverse32(devc->trigger_mask[1])) != SR_OK)
392                         return SR_ERR;
393                 if (send_longcommand(serial, CMD_SET_TRIGGER_VALUE_1,
394                         reverse32(devc->trigger_value[1])) != SR_OK)
395                         return SR_ERR;
396                 if (send_longcommand(serial, CMD_SET_TRIGGER_CONFIG_1,
397                         trigger_config[1]) != SR_OK)
398                         return SR_ERR;
399
400                 if (send_longcommand(serial, CMD_SET_TRIGGER_MASK_2,
401                         reverse32(devc->trigger_mask[2])) != SR_OK)
402                         return SR_ERR;
403                 if (send_longcommand(serial, CMD_SET_TRIGGER_VALUE_2,
404                         reverse32(devc->trigger_value[2])) != SR_OK)
405                         return SR_ERR;
406                 if (send_longcommand(serial, CMD_SET_TRIGGER_CONFIG_2,
407                         trigger_config[2]) != SR_OK)
408                         return SR_ERR;
409
410                 if (send_longcommand(serial, CMD_SET_TRIGGER_MASK_3,
411                         reverse32(devc->trigger_mask[3])) != SR_OK)
412                         return SR_ERR;
413                 if (send_longcommand(serial, CMD_SET_TRIGGER_VALUE_3,
414                         reverse32(devc->trigger_value[3])) != SR_OK)
415                         return SR_ERR;
416                 if (send_longcommand(serial, CMD_SET_TRIGGER_CONFIG_3,
417                         trigger_config[3]) != SR_OK)
418                         return SR_ERR;
419         } else {
420                 if (send_longcommand(serial, CMD_SET_TRIGGER_MASK_0,
421                                 devc->trigger_mask[0]) != SR_OK)
422                         return SR_ERR;
423                 if (send_longcommand(serial, CMD_SET_TRIGGER_VALUE_0,
424                                 devc->trigger_value[0]) != SR_OK)
425                         return SR_ERR;
426                 if (send_longcommand(serial, CMD_SET_TRIGGER_CONFIG_0,
427                      0x00000008) != SR_OK)
428                         return SR_ERR;
429                 delaycount = readcount;
430         }
431
432         sr_info("Setting samplerate to %" PRIu64 "Hz (divider %u, "
433                 "demux %s)", devc->cur_samplerate, devc->cur_samplerate_divider,
434                 devc->flag_reg & FLAG_DEMUX ? "on" : "off");
435         if (send_longcommand(serial, CMD_SET_DIVIDER,
436                         reverse32(devc->cur_samplerate_divider)) != SR_OK)
437                 return SR_ERR;
438
439         /* Send sample limit and pre/post-trigger capture ratio. */
440         data = ((readcount - 1) & 0xffff) << 16;
441         data |= (delaycount - 1) & 0xffff;
442         if (send_longcommand(serial, CMD_CAPTURE_SIZE, reverse16(data)) != SR_OK)
443                 return SR_ERR;
444
445         /* The flag register wants them here, and 1 means "disable channel". */
446         devc->flag_reg |= ~(changrp_mask << 2) & 0x3c;
447         devc->flag_reg |= FLAG_FILTER;
448         devc->rle_count = 0;
449         data = (devc->flag_reg << 24) | ((devc->flag_reg << 8) & 0xff0000);
450         if (send_longcommand(serial, CMD_SET_FLAGS, data) != SR_OK)
451                 return SR_ERR;
452
453         /* Start acquisition on the device. */
454         if (send_shortcommand(serial, CMD_RUN) != SR_OK)
455                 return SR_ERR;
456
457         /* Reset all operational states. */
458         devc->num_transfers = devc->num_samples = devc->num_bytes = 0;
459
460         /* Send header packet to the session bus. */
461         std_session_send_df_header(cb_data, LOG_PREFIX);
462
463         sr_source_add(serial->fd, G_IO_IN, -1, ols_receive_data, cb_data);
464
465         return SR_OK;
466 }
467
468 static int dev_acquisition_stop(struct sr_dev_inst *sdi, void *cb_data)
469 {
470         (void)cb_data;
471
472         abort_acquisition(sdi);
473
474         return SR_OK;
475 }
476
477 SR_PRIV struct sr_dev_driver ols_driver_info = {
478         .name = "ols",
479         .longname = "Openbench Logic Sniffer",
480         .api_version = 1,
481         .init = init,
482         .cleanup = cleanup,
483         .scan = scan,
484         .dev_list = dev_list,
485         .dev_clear = dev_clear,
486         .config_get = config_get,
487         .config_set = config_set,
488         .config_list = config_list,
489         .dev_open = dev_open,
490         .dev_close = dev_close,
491         .dev_acquisition_start = dev_acquisition_start,
492         .dev_acquisition_stop = dev_acquisition_stop,
493         .priv = NULL,
494 };