]> sigrok.org Git - libsigrok.git/blob - src/hardware/ipdbg-logic-analyser/api.c
ipdbg-la: Remove SR_CONF_SERIALCOMM
[libsigrok.git] / src / hardware / ipdbg-logic-analyser / api.c
1 /*
2  * This file is part of the libsigrok project.
3  *
4  * Copyright (C) 2016 danselmi <da@da>
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 "protocol.h"
22
23 static const uint32_t ipdbg_org_la_drvopts[] = {
24         SR_CONF_LOGIC_ANALYZER,
25 };
26
27 static const uint32_t ipdbg_org_la_scanopts[] = {
28         SR_CONF_CONN,
29 };
30
31 static const uint32_t ipdbg_org_la_devopts[] = {
32         SR_CONF_TRIGGER_MATCH | SR_CONF_LIST | SR_CONF_SET,
33         SR_CONF_CAPTURE_RATIO | SR_CONF_GET | SR_CONF_SET,
34         SR_CONF_LIMIT_SAMPLES | SR_CONF_GET,
35 };
36
37 static const int32_t ipdbg_org_la_trigger_matches[] = {
38         SR_TRIGGER_ZERO,
39         SR_TRIGGER_ONE,
40         SR_TRIGGER_RISING,
41         SR_TRIGGER_FALLING,
42         SR_TRIGGER_EDGE,
43 };
44
45 SR_PRIV struct sr_dev_driver ipdbg_la_driver_info;
46
47 static void ipdbg_org_la_split_addr_port(const char *conn, char **addr,
48         char **port)
49 {
50         char **strs = g_strsplit(conn, "/", 3);
51
52         *addr = g_strdup(strs[1]);
53         *port = g_strdup(strs[2]);
54
55         g_strfreev(strs);
56 }
57
58 static GSList *scan(struct sr_dev_driver *di, GSList *options)
59 {
60         struct drv_context *drvc;
61         GSList *devices;
62
63         devices = NULL;
64         drvc = di->context;
65         drvc->instances = NULL;
66         const char *conn;
67         struct sr_config *src;
68         GSList *l;
69
70         conn = NULL;
71         for (l = options; l; l = l->next) {
72                 src = l->data;
73                 switch (src->key) {
74                 case SR_CONF_CONN:
75                         conn = g_variant_get_string(src->data, NULL);
76                         break;
77                 }
78         }
79
80         if (!conn)
81                 return NULL;
82
83         struct ipdbg_org_la_tcp *tcp = ipdbg_org_la_tcp_new();
84
85         ipdbg_org_la_split_addr_port(conn, &tcp->address, &tcp->port);
86
87         if (!tcp->address)
88                 return NULL;
89
90         if (ipdbg_org_la_tcp_open(tcp) != SR_OK)
91                 return NULL;
92
93         ipdbg_org_la_send_reset(tcp);
94         ipdbg_org_la_send_reset(tcp);
95         ipdbg_org_la_request_id(tcp);
96
97         struct sr_dev_inst *sdi = g_malloc0(sizeof(struct sr_dev_inst));
98         if (!sdi) {
99                 sr_err("no possible to allocate sr_dev_inst");
100                 return NULL;
101         }
102
103         sdi->status = SR_ST_INACTIVE;
104         sdi->vendor = g_strdup("ipdbg.org");
105         sdi->model = g_strdup("Logic Analyzer");
106         sdi->version = g_strdup("v1.0");
107         sdi->driver = di;
108
109         struct ipdbg_org_la_dev_context *devc = ipdbg_org_la_dev_new();
110         sdi->priv = devc;
111
112         ipdbg_org_la_get_addrwidth_and_datawidth(tcp, devc);
113
114         sr_dbg("addr_width = %d, data_width = %d\n", devc->ADDR_WIDTH,
115                 devc->DATA_WIDTH);
116         sr_dbg("limit samples = %" PRIu64 "\n", devc->limit_samples_max);
117
118         for (uint32_t i = 0; i < devc->DATA_WIDTH; i++) {
119                 const uint8_t buf_size = 16;
120                 char buf[buf_size];
121                 snprintf(buf, buf_size, "ch%d", i);
122                 sr_channel_new(sdi, i, SR_CHANNEL_LOGIC, TRUE, buf);
123         }
124
125         sdi->inst_type = SR_INST_USER;
126         sdi->conn = tcp;
127
128         ipdbg_org_la_tcp_close(tcp);
129
130         devices = g_slist_append(devices, sdi);
131
132         return std_scan_complete(di, devices);
133 }
134
135 static int dev_clear(const struct sr_dev_driver *di)
136 {
137         struct drv_context *drvc = di->context;
138         struct sr_dev_inst *sdi;
139         GSList *l;
140
141         if (drvc) {
142                 for (l = drvc->instances; l; l = l->next) {
143                         sdi = l->data;
144                         struct ipdbg_org_la_tcp *tcp = sdi->conn;
145                         if (tcp) {
146                                 ipdbg_org_la_tcp_close(tcp);
147                                 ipdbg_org_la_tcp_free(tcp);
148                                 g_free(tcp);
149                         }
150                         sdi->conn = NULL;
151                 }
152         }
153
154         return std_dev_clear(di);
155 }
156
157 static int dev_open(struct sr_dev_inst *sdi)
158 {
159         sdi->status = SR_ST_INACTIVE;
160
161         struct ipdbg_org_la_tcp *tcp = sdi->conn;
162
163         if (!tcp)
164                 return SR_ERR;
165
166         if (ipdbg_org_la_tcp_open(tcp) != SR_OK)
167                 return SR_ERR;
168
169         sdi->status = SR_ST_ACTIVE;
170
171         return SR_OK;
172 }
173
174 static int dev_close(struct sr_dev_inst *sdi)
175 {
176         // Should be called before a new call to scan()
177         struct ipdbg_org_la_tcp *tcp = sdi->conn;
178
179         if (tcp)
180                 ipdbg_org_la_tcp_close(tcp);
181
182         sdi->conn = NULL;
183         sdi->status = SR_ST_INACTIVE;
184
185         return SR_OK;
186 }
187
188 static int config_get(uint32_t key, GVariant **data,
189         const struct sr_dev_inst *sdi, const struct sr_channel_group *cg)
190 {
191         int ret = SR_OK;
192
193         (void)cg;
194
195         struct ipdbg_org_la_dev_context *devc = sdi->priv;
196
197         switch (key) {
198         case SR_CONF_CAPTURE_RATIO:
199                 *data = g_variant_new_uint64(devc->capture_ratio);
200                 break;
201         case SR_CONF_LIMIT_SAMPLES:
202                 *data = g_variant_new_uint64(devc->limit_samples);
203                 break;
204         default:
205                 ret = SR_ERR_NA;
206         }
207
208         return ret;
209 }
210
211 static int config_set(uint32_t key, GVariant *data,
212         const struct sr_dev_inst *sdi, const struct sr_channel_group *cg)
213 {
214         int ret = SR_OK;
215         uint64_t value;
216
217         (void)cg;
218
219         if (sdi->status != SR_ST_ACTIVE)
220                 return SR_ERR_DEV_CLOSED;
221
222         struct ipdbg_org_la_dev_context *devc = sdi->priv;
223
224         switch (key) {
225         case SR_CONF_CAPTURE_RATIO:
226                 value = g_variant_get_uint64(data);
227                 if (value <= 100)
228                         devc->capture_ratio = value;
229                 else
230                         ret = SR_ERR;
231                 break;
232         case SR_CONF_LIMIT_SAMPLES:
233                 value = g_variant_get_uint64(data);
234                 if (value <= devc->limit_samples_max)
235                         devc->limit_samples = value;
236                 else
237                         ret = SR_ERR;
238                 break;
239         default:
240                 ret = SR_ERR_NA;
241         }
242
243         return ret;
244 }
245
246 static int config_list(uint32_t key, GVariant **data,
247         const struct sr_dev_inst *sdi, const struct sr_channel_group *cg)
248 {
249         (void)cg;
250
251         switch (key) {
252         case SR_CONF_SCAN_OPTIONS:
253                 *data = g_variant_new_fixed_array(G_VARIANT_TYPE_UINT32,
254                         ipdbg_org_la_scanopts,
255                         ARRAY_SIZE
256                         (ipdbg_org_la_scanopts),
257                         sizeof(uint32_t));
258                 break;
259         case SR_CONF_DEVICE_OPTIONS:
260                 if (!sdi)
261                         *data = g_variant_new_fixed_array(G_VARIANT_TYPE_UINT32,
262                                 ipdbg_org_la_drvopts,
263                                 ARRAY_SIZE
264                                 (ipdbg_org_la_drvopts),
265                                 sizeof(uint32_t));
266                 else
267                         *data = g_variant_new_fixed_array(G_VARIANT_TYPE_UINT32,
268                                 ipdbg_org_la_devopts,
269                                 ARRAY_SIZE
270                                 (ipdbg_org_la_devopts),
271                                 sizeof(uint32_t));
272                 break;
273         case SR_CONF_TRIGGER_MATCH:
274                 *data = g_variant_new_fixed_array(G_VARIANT_TYPE_INT32,
275                         ipdbg_org_la_trigger_matches,
276                         ARRAY_SIZE
277                         (ipdbg_org_la_trigger_matches),
278                         sizeof(int32_t));
279                 break;
280         default:
281                 return SR_ERR_NA;
282         }
283
284         return SR_OK;
285 }
286
287 static int init(struct sr_dev_driver *di, struct sr_context *sr_ctx)
288 {
289         return std_init(di, sr_ctx);
290 }
291
292 static GSList *dev_list(const struct sr_dev_driver *di)
293 {
294         return ((struct drv_context *)(di->context))->instances;
295 }
296
297 static int dev_acquisition_start(const struct sr_dev_inst *sdi)
298 {
299         if (sdi->status != SR_ST_ACTIVE)
300                 return SR_ERR_DEV_CLOSED;
301
302         struct ipdbg_org_la_tcp *tcp = sdi->conn;
303         struct ipdbg_org_la_dev_context *devc = sdi->priv;
304
305         ipdbg_org_la_convert_trigger(sdi);
306         ipdbg_org_la_send_trigger(devc, tcp);
307         ipdbg_org_la_send_delay(devc, tcp);
308
309         /* If the device stops sending for longer than it takes to send a byte,
310          * that means it's finished. But wait at least 100 ms to be safe.
311          */
312         sr_session_source_add(sdi->session, tcp->socket, G_IO_IN, 100,
313                 ipdbg_org_la_receive_data, (struct sr_dev_inst *)sdi);
314
315         ipdbg_org_la_send_start(tcp);
316
317         return SR_OK;
318 }
319
320 static int dev_acquisition_stop(struct sr_dev_inst *sdi)
321 {
322         struct ipdbg_org_la_tcp *tcp = sdi->conn;
323         struct ipdbg_org_la_dev_context *devc = sdi->priv;
324
325         uint8_t byte;
326
327         if (devc->num_transfers > 0) {
328                 while (devc->num_transfers <
329                         (devc->limit_samples_max * devc->DATA_WIDTH_BYTES)) {
330                         ipdbg_org_la_tcp_receive(tcp, &byte);
331                         devc->num_transfers++;
332                 }
333         }
334
335         ipdbg_org_la_send_reset(tcp);
336         ipdbg_org_la_abort_acquisition(sdi);
337
338         return SR_OK;
339 }
340
341 SR_PRIV struct sr_dev_driver ipdbg_la_driver_info = {
342         .name = "ipdbg-org-la",
343         .longname = "ipdbg.org logic analyzer",
344         .api_version = 1,
345         .init = init,
346         .cleanup = std_cleanup,
347         .scan = scan,
348         .dev_list = dev_list,
349         .dev_clear = dev_clear,
350         .config_get = config_get,
351         .config_set = config_set,
352         .config_list = config_list,
353         .dev_open = dev_open,
354         .dev_close = dev_close,
355         .dev_acquisition_start = dev_acquisition_start,
356         .dev_acquisition_stop = dev_acquisition_stop,
357         .context = NULL,
358 };
359
360 SR_REGISTER_DEV_DRIVER(ipdbg_la_driver_info);