]> sigrok.org Git - libsigrok.git/blob - hardware/zeroplus-logic-cube/zeroplus.c
Start of code base layout restructuring.
[libsigrok.git] / hardware / zeroplus-logic-cube / zeroplus.c
1 /*
2  * This file is part of the sigrok project.
3  *
4  * Copyright (C) 2010 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 <stdio.h>
21 #include <stdlib.h>
22 #include <sys/time.h>
23 #include <inttypes.h>
24 #include <glib.h>
25 #include <libusb.h>
26 #include "config.h"
27 #include "sigrok.h"
28 #include "analyzer.h"
29
30 #define USB_VENDOR                              0x0c12
31 #define USB_VENDOR_NAME         "Zeroplus"
32 #define USB_MODEL_NAME                  "Logic Cube"
33 #define USB_MODEL_VERSION               ""
34
35 #define USB_INTERFACE                   0
36 #define USB_CONFIGURATION               1
37 #define NUM_TRIGGER_STAGES              4
38 #define TRIGGER_TYPES                   "01"
39
40 #define PACKET_SIZE                             2048 // ??
41
42 typedef struct {
43         unsigned short pid;
44         char model_name[64];
45         unsigned int channels;
46         unsigned int sample_depth; // in Ksamples/channel
47         unsigned int max_sampling_freq;
48 } model_t;
49
50 /* Note -- 16032, 16064 and 16128 *usually* -- but not always -- have the same 128K sample depth */
51 model_t zeroplus_models[] = {
52         {0x7009, "LAP-C(16064)",  16, 64,   100},
53         {0x700A, "LAP-C(16128)",  16, 128,  200},
54         {0x700B, "LAP-C(32128)",  32, 128,  200},
55         {0x700C, "LAP-C(321000)", 32, 1024, 200},
56         {0x700D, "LAP-C(322000)", 32, 2048, 200},
57         {0x700E, "LAP-C(16032)",  16, 32,   100},
58         {0x7016, "LAP-C(162000)", 16, 2048, 200},
59 };
60
61 static int capabilities[] = {
62         HWCAP_LOGIC_ANALYZER,
63         HWCAP_SAMPLERATE,
64         HWCAP_PROBECONFIG,
65         HWCAP_CAPTURE_RATIO,
66         /* these are really implemented in the driver, not the hardware */
67
68         HWCAP_LIMIT_SAMPLES,
69         0
70 };
71
72 /* list of struct sigrok_device_instance, maintained by opendev() and closedev() */
73 static GSList *device_instances = NULL;
74
75 static libusb_context *usb_context = NULL;
76
77 /* The hardware supports more sample rates than these, but these are the options
78    hardcoded into the vendor's Windows GUI */
79
80 // XXX we shouldn't support 150MHz and 200MHz on devices that don't go up that high
81 static uint64_t supported_samplerates[] = {
82         100,
83         500,
84         KHZ(1),
85         KHZ(5),
86         KHZ(25),
87         KHZ(50),
88         KHZ(100),
89         KHZ(200),
90         KHZ(400),
91         KHZ(800),
92         MHZ(1),
93         MHZ(10),
94         MHZ(25),
95         MHZ(50),
96         MHZ(80),
97         MHZ(100),
98         MHZ(150),
99         MHZ(200),
100         0
101 };
102
103 static struct samplerates samplerates = {
104         0,0,0,
105         supported_samplerates
106 };
107
108 /* TODO: all of these should go in a device-specific struct */
109 static uint64_t cur_samplerate = 0;
110 static uint64_t limit_samples = 0;
111 uint8_t num_channels = 32; // XXX this is not getting initialized before it is needed :(
112 uint64_t memory_size = 0;
113 static uint8_t probe_mask = 0, \
114                 trigger_mask[NUM_TRIGGER_STAGES] = {0}, \
115                 trigger_value[NUM_TRIGGER_STAGES] = {0}, \
116                 trigger_buffer[NUM_TRIGGER_STAGES] = {0};;
117
118
119 static int hw_set_configuration(int device_index, int capability, void *value);
120
121 static unsigned int get_memory_size(int type)
122 {
123         if (type == MEMORY_SIZE_8K)
124                 return 8*1024;
125         else if (type == MEMORY_SIZE_64K)
126                 return 64*1024;
127         else if (type == MEMORY_SIZE_128K)
128                 return 128*1024;
129         else if (type == MEMORY_SIZE_512K)
130                 return 512*1024;
131         else
132                 return 0;
133 }
134
135 struct sigrok_device_instance *zp_open_device(int device_index)
136 {
137         struct sigrok_device_instance *sdi;
138         libusb_device **devlist;
139         struct libusb_device_descriptor des;
140         int err, i, j;
141
142         if(!(sdi = get_sigrok_device_instance(device_instances, device_index)))
143                 return NULL;
144
145         libusb_get_device_list(usb_context, &devlist);
146         if(sdi->status == ST_INACTIVE) {
147                 /* find the device by vendor, product, bus and address */
148                 libusb_get_device_list(usb_context, &devlist);
149                 for(i = 0; devlist[i]; i++) {
150                         if( (err = libusb_get_device_descriptor(devlist[i], &des)) ) {
151                                 g_warning("failed to get device descriptor: %d", err);
152                                 continue;
153                         }
154
155                         if(des.idVendor == USB_VENDOR) {
156                                 if(libusb_get_bus_number(devlist[i]) == sdi->usb->bus &&
157                                                 libusb_get_device_address(devlist[i]) == sdi->usb->address) {
158                                                         for (j = 0; j < sizeof(zeroplus_models) / sizeof(zeroplus_models[0]); j++) {
159                                                                 if (des.idProduct == zeroplus_models[j].pid) {
160                                                                         g_message("Found PID=%04X (%s)", des.idProduct, zeroplus_models[j].model_name);
161                                                                         num_channels = zeroplus_models[j].channels;
162                                                                         memory_size = zeroplus_models[j].sample_depth * 1024;
163                                                                         break;
164                                                                 }
165                                                         }
166                                                         if (num_channels == 0) {
167                                                                 g_warning("Unknown ZeroPlus device %04X", des.idProduct);
168                                                                 continue;
169                                                         }
170                                         /* found it */
171                                         if( !(err = libusb_open(devlist[i], &(sdi->usb->devhdl))) ) {
172                                                 sdi->status = ST_ACTIVE;
173                                                 g_message("opened device %d on %d.%d interface %d", sdi->index,
174                                                                 sdi->usb->bus, sdi->usb->address, USB_INTERFACE);
175                                         }
176                                         else {
177                                                 g_warning("failed to open device: %d", err);
178                                                 sdi = NULL;
179                                         }
180                                 }
181                         }
182                 }
183         }
184         else {
185                 /* status must be ST_ACTIVE, i.e. already in use... */
186                 sdi = NULL;
187         }
188         libusb_free_device_list(devlist, 1);
189
190         if(sdi && sdi->status != ST_ACTIVE)
191                 sdi = NULL;
192
193         return sdi;
194 }
195
196
197 static void close_device(struct sigrok_device_instance *sdi)
198 {
199
200         if(sdi->usb->devhdl)
201         {
202                 g_message("closing device %d on %d.%d interface %d", sdi->index, sdi->usb->bus,
203                                 sdi->usb->address, USB_INTERFACE);
204                 libusb_release_interface(sdi->usb->devhdl, USB_INTERFACE);
205                 libusb_close(sdi->usb->devhdl);
206                 sdi->usb->devhdl = NULL;
207                 sdi->status = ST_INACTIVE;
208         }
209
210 }
211
212
213 static int configure_probes(GSList *probes)
214 {
215         struct probe *probe;
216         GSList *l;
217         int probe_bit, stage, i;
218         char *tc;
219
220         probe_mask = 0;
221         for(i = 0; i < NUM_TRIGGER_STAGES; i++)
222         {
223                 trigger_mask[i] = 0;
224                 trigger_value[i] = 0;
225         }
226
227         stage = -1;
228         for(l = probes; l; l = l->next)
229         {
230                 probe = (struct probe *) l->data;
231                 if(probe->enabled == FALSE)
232                         continue;
233                 probe_bit = 1 << (probe->index - 1);
234                 probe_mask |= probe_bit;
235                 if(probe->trigger)
236                 {
237                         stage = 0;
238                         for(tc = probe->trigger; *tc; tc++)
239                         {
240                                 trigger_mask[stage] |= probe_bit;
241                                 if(*tc == '1')
242                                         trigger_value[stage] |= probe_bit;
243                                 stage++;
244                                 if(stage > NUM_TRIGGER_STAGES)
245                                         return SIGROK_NOK;
246                         }
247                 }
248         }
249
250         return SIGROK_OK;
251 }
252
253
254
255 /*
256  * API callbacks
257  */
258
259 static int hw_init(char *deviceinfo)
260 {
261         struct sigrok_device_instance *sdi;
262         struct libusb_device_descriptor des;
263         libusb_device **devlist;
264         int err, devcnt, i;
265
266         if(libusb_init(&usb_context) != 0) {
267                 g_warning("Failed to initialize USB.");
268                 return 0;
269         }
270
271         /* find all ZeroPlus analyzers and add them to device list */
272         devcnt = 0;
273         libusb_get_device_list(usb_context, &devlist);
274         for(i = 0; devlist[i]; i++) {
275                 err = libusb_get_device_descriptor(devlist[i], &des);
276                 if(err != 0) {
277                         g_warning("failed to get device descriptor: %d", err);
278                         continue;
279                 }
280
281                 if(des.idVendor == USB_VENDOR) {
282                         /* definitely a Zeroplus */
283                         /* TODO: any way to detect specific model/version in the zeroplus range? */
284                         sdi = sigrok_device_instance_new(devcnt, ST_INACTIVE,
285                                         USB_VENDOR_NAME, USB_MODEL_NAME, USB_MODEL_VERSION);
286                         if(!sdi)
287                                 return 0;
288                         device_instances = g_slist_append(device_instances, sdi);
289                         sdi->usb = usb_device_instance_new(libusb_get_bus_number(devlist[i]),
290                                         libusb_get_device_address(devlist[i]), NULL);
291                         devcnt++;
292                 }
293         }
294         libusb_free_device_list(devlist, 1);
295
296         return devcnt;
297 }
298
299
300 static int hw_opendev(int device_index)
301 {
302         struct sigrok_device_instance *sdi;
303         int err;
304
305         if( !(sdi = zp_open_device(device_index)) ) {
306                 g_warning("unable to open device");
307                 return SIGROK_NOK;
308         }
309
310         err = libusb_claim_interface(sdi->usb->devhdl, USB_INTERFACE);
311         if(err != 0) {
312                 g_warning("Unable to claim interface: %d", err);
313                 return SIGROK_NOK;
314         }
315         analyzer_reset(sdi->usb->devhdl);
316         analyzer_initialize(sdi->usb->devhdl);
317         analyzer_configure(sdi->usb->devhdl);
318
319         analyzer_set_memory_size(MEMORY_SIZE_512K);
320 //      analyzer_set_freq(g_freq, g_freq_scale);
321         analyzer_set_trigger_count(1);
322 //      analyzer_set_ramsize_trigger_address((((100 - g_pre_trigger) * get_memory_size(g_memory_size)) / 100) >> 2);
323         analyzer_set_ramsize_trigger_address((100 * get_memory_size(MEMORY_SIZE_512K) / 100) >> 2);
324
325 /*      if (g_double_mode == 1)
326                 analyzer_set_compression(COMPRESSION_DOUBLE);
327         else if (g_compression == 1)
328                 analyzer_set_compression(COMPRESSION_ENABLE);
329         else */
330                 analyzer_set_compression(COMPRESSION_NONE);
331
332         if(cur_samplerate == 0) {
333                 /* sample rate hasn't been set; default to the slowest it has */
334                 if(hw_set_configuration(device_index, HWCAP_SAMPLERATE, &samplerates.low) == SIGROK_NOK)
335                         return SIGROK_NOK;
336         }
337
338         return SIGROK_OK;
339 }
340
341
342 static void hw_closedev(int device_index)
343 {
344         struct sigrok_device_instance *sdi;
345
346         if( (sdi = get_sigrok_device_instance(device_instances, device_index)) )
347                 close_device(sdi);
348
349 }
350
351
352 static void hw_cleanup(void)
353 {
354         GSList *l;
355
356         /* properly close all devices */
357         for(l = device_instances; l; l = l->next)
358                 close_device( (struct sigrok_device_instance *) l->data);
359
360         /* and free all their memory */
361         for(l = device_instances; l; l = l->next)
362                 g_free(l->data);
363         g_slist_free(device_instances);
364         device_instances = NULL;
365
366         if(usb_context)
367                 libusb_exit(usb_context);
368         usb_context = NULL;
369
370 }
371
372
373 static void *hw_get_device_info(int device_index, int device_info_id)
374 {
375         struct sigrok_device_instance *sdi;
376         void *info;
377
378         if( !(sdi = get_sigrok_device_instance(device_instances, device_index)) )
379                 return NULL;
380
381         info = NULL;
382         switch(device_info_id)
383         {
384         case DI_INSTANCE:
385                 info = sdi;
386                 break;
387         case DI_NUM_PROBES:
388                 info = GINT_TO_POINTER(num_channels);
389                 break;
390         case DI_SAMPLERATES:
391                 info = &samplerates;
392                 break;
393         case DI_TRIGGER_TYPES:
394                 info = TRIGGER_TYPES;
395                 break;
396         case DI_CUR_SAMPLE_RATE:
397                 info = &cur_samplerate;
398                 break;
399         }
400
401         return info;
402 }
403
404
405 static int hw_get_status(int device_index)
406 {
407         struct sigrok_device_instance *sdi;
408
409         sdi = get_sigrok_device_instance(device_instances, device_index);
410         if(sdi)
411                 return sdi->status;
412         else
413                 return ST_NOT_FOUND;
414 }
415
416
417 static int *hw_get_capabilities(void)
418 {
419
420         return capabilities;
421 }
422
423 // XXX this will set the same samplerate for all devices
424 int set_configuration_samplerate(struct sigrok_device_instance *sdi, uint64_t samplerate)
425 {
426         g_message("%s(%llu)", __FUNCTION__, samplerate);
427         if (samplerate > MHZ(1))
428                 analyzer_set_freq(samplerate / MHZ(1), FREQ_SCALE_MHZ);
429         else if (samplerate > KHZ(1))
430                 analyzer_set_freq(samplerate / KHZ(1), FREQ_SCALE_KHZ);
431         else
432                 analyzer_set_freq(samplerate , FREQ_SCALE_HZ);
433
434         cur_samplerate = samplerate;
435
436         return SIGROK_OK;
437 }
438
439 static int hw_set_configuration(int device_index, int capability, void *value)
440 {
441         struct sigrok_device_instance *sdi;
442         uint64_t *tmp_u64;
443
444         if( !(sdi = get_sigrok_device_instance(device_instances, device_index)) )
445                 return SIGROK_NOK;
446
447         switch (capability) {
448                 case HWCAP_SAMPLERATE:
449                         tmp_u64 = value;
450                         return set_configuration_samplerate(sdi, *tmp_u64);
451
452                 case HWCAP_PROBECONFIG:
453                         return configure_probes( (GSList *) value);
454
455                 case HWCAP_LIMIT_SAMPLES:
456                         limit_samples = strtoull(value, NULL, 10);
457                         return SIGROK_OK;
458
459                 default:
460                         return SIGROK_NOK;
461         }
462 }
463
464 static int hw_start_acquisition(int device_index, gpointer session_device_id)
465 {
466         struct sigrok_device_instance *sdi;
467         struct datafeed_packet packet;
468         struct datafeed_header header;
469         int res;
470         int packet_num;
471         unsigned char *buf;
472
473         if( !(sdi = get_sigrok_device_instance(device_instances, device_index)))
474                 return SIGROK_NOK;
475
476         analyzer_start(sdi->usb->devhdl);
477         g_message("Waiting for data");
478         analyzer_wait_data(sdi->usb->devhdl);
479
480         g_message("Stop address    = 0x%x", analyzer_get_stop_address(sdi->usb->devhdl));
481         g_message("Now address     = 0x%x", analyzer_get_now_address(sdi->usb->devhdl));
482         g_message("Trigger address = 0x%x", analyzer_get_trigger_address(sdi->usb->devhdl));
483
484         packet.type = DF_HEADER;
485         packet.length = sizeof(struct datafeed_header);
486         packet.payload = (unsigned char *) &header;
487         header.feed_version = 1;
488         gettimeofday(&header.starttime, NULL);
489         header.rate = cur_samplerate;
490         header.protocol_id = PROTO_RAW;
491         header.num_probes = num_channels;
492         session_bus(session_device_id, &packet);
493
494         buf = g_malloc(PACKET_SIZE);
495         if (!buf)
496                 return SIGROK_NOK;
497         analyzer_read_start(sdi->usb->devhdl);
498         /* send the incoming transfer to the session bus */
499         for(packet_num = 0; packet_num < (memory_size * 4 / PACKET_SIZE); packet_num++) {
500                 res = analyzer_read_data(sdi->usb->devhdl, buf, PACKET_SIZE);
501 //              g_message("Tried to read %llx bytes, actually read %x bytes", PACKET_SIZE, res);
502
503                 packet.type = DF_LOGIC32;
504                 packet.length = PACKET_SIZE;
505                 packet.payload = buf;
506                 session_bus(session_device_id, &packet);                
507         }
508         analyzer_read_stop(sdi->usb->devhdl);
509         g_free(buf);
510
511         packet.type = DF_END;
512         session_bus(session_device_id, &packet);
513
514         return SIGROK_OK;
515 }
516
517
518 /* this stops acquisition on ALL devices, ignoring device_index */
519 static void hw_stop_acquisition(int device_index, gpointer session_device_id)
520 {
521         struct datafeed_packet packet;
522         struct sigrok_device_instance *sdi;
523
524         packet.type = DF_END;
525         session_bus(session_device_id, &packet);
526
527         if( !(sdi = get_sigrok_device_instance(device_instances, device_index)))
528                 return; // XXX cry?
529
530         analyzer_reset(sdi->usb->devhdl);
531         /* TODO: need to cancel and free any queued up transfers */
532 }
533
534
535
536 struct device_plugin zeroplus_logic_cube_plugin_info = {
537         "zeroplus-logic-cube",
538         1,
539         hw_init,
540         hw_cleanup,
541
542         hw_opendev,
543         hw_closedev,
544         hw_get_device_info,
545         hw_get_status,
546         hw_get_capabilities,
547         hw_set_configuration,
548         hw_start_acquisition,
549         hw_stop_acquisition
550 };
551