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