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