]> sigrok.org Git - libsigrok.git/blob - hardware/zeroplus-logic-cube/zeroplus.c
Add ARRAY_SIZE helper.
[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 samplerates 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 int 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 static uint8_t trigger_mask[NUM_TRIGGER_STAGES] = {0};
115 static uint8_t trigger_value[NUM_TRIGGER_STAGES] = {0};
116 // static uint8_t 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         unsigned int j;
141         int err, i;
142
143         if(!(sdi = get_sigrok_device_instance(device_instances, device_index)))
144                 return NULL;
145
146         libusb_get_device_list(usb_context, &devlist);
147         if(sdi->status == ST_INACTIVE) {
148                 /* find the device by vendor, product, bus and address */
149                 libusb_get_device_list(usb_context, &devlist);
150                 for(i = 0; devlist[i]; i++) {
151                         if( (err = libusb_get_device_descriptor(devlist[i], &des)) ) {
152                                 g_warning("failed to get device descriptor: %d", err);
153                                 continue;
154                         }
155
156                         if(des.idVendor == USB_VENDOR) {
157                                 if(libusb_get_bus_number(devlist[i]) == sdi->usb->bus &&
158                                                 libusb_get_device_address(devlist[i]) == sdi->usb->address) {
159                                                         for (j = 0; j < ARRAY_SIZE(zeroplus_models); j++) {
160                                                                 if (des.idProduct == zeroplus_models[j].pid) {
161                                                                         g_message("Found PID=%04X (%s)", des.idProduct, zeroplus_models[j].model_name);
162                                                                         num_channels = zeroplus_models[j].channels;
163                                                                         memory_size = zeroplus_models[j].sample_depth * 1024;
164                                                                         break;
165                                                                 }
166                                                         }
167                                                         if (num_channels == 0) {
168                                                                 g_warning("Unknown ZeroPlus device %04X", des.idProduct);
169                                                                 continue;
170                                                         }
171                                         /* found it */
172                                         if( !(err = libusb_open(devlist[i], &(sdi->usb->devhdl))) ) {
173                                                 sdi->status = ST_ACTIVE;
174                                                 g_message("opened device %d on %d.%d interface %d", sdi->index,
175                                                                 sdi->usb->bus, sdi->usb->address, USB_INTERFACE);
176                                         }
177                                         else {
178                                                 g_warning("failed to open device: %d", err);
179                                                 sdi = NULL;
180                                         }
181                                 }
182                         }
183                 }
184         }
185         else {
186                 /* status must be ST_ACTIVE, i.e. already in use... */
187                 sdi = NULL;
188         }
189         libusb_free_device_list(devlist, 1);
190
191         if(sdi && sdi->status != ST_ACTIVE)
192                 sdi = NULL;
193
194         return sdi;
195 }
196
197
198 static void close_device(struct sigrok_device_instance *sdi)
199 {
200
201         if(sdi->usb->devhdl)
202         {
203                 g_message("closing device %d on %d.%d interface %d", sdi->index, sdi->usb->bus,
204                                 sdi->usb->address, USB_INTERFACE);
205                 libusb_release_interface(sdi->usb->devhdl, USB_INTERFACE);
206                 libusb_close(sdi->usb->devhdl);
207                 sdi->usb->devhdl = NULL;
208                 sdi->status = ST_INACTIVE;
209         }
210
211 }
212
213
214 static int configure_probes(GSList *probes)
215 {
216         struct probe *probe;
217         GSList *l;
218         int probe_bit, stage, i;
219         char *tc;
220
221         probe_mask = 0;
222         for(i = 0; i < NUM_TRIGGER_STAGES; i++)
223         {
224                 trigger_mask[i] = 0;
225                 trigger_value[i] = 0;
226         }
227
228         stage = -1;
229         for(l = probes; l; l = l->next)
230         {
231                 probe = (struct probe *) l->data;
232                 if(probe->enabled == FALSE)
233                         continue;
234                 probe_bit = 1 << (probe->index - 1);
235                 probe_mask |= probe_bit;
236                 if(probe->trigger)
237                 {
238                         stage = 0;
239                         for(tc = probe->trigger; *tc; tc++)
240                         {
241                                 trigger_mask[stage] |= probe_bit;
242                                 if(*tc == '1')
243                                         trigger_value[stage] |= probe_bit;
244                                 stage++;
245                                 if(stage > NUM_TRIGGER_STAGES)
246                                         return SIGROK_ERR;
247                         }
248                 }
249         }
250
251         return SIGROK_OK;
252 }
253
254
255
256 /*
257  * API callbacks
258  */
259
260 static int hw_init(char *deviceinfo)
261 {
262         struct sigrok_device_instance *sdi;
263         struct libusb_device_descriptor des;
264         libusb_device **devlist;
265         int err, devcnt, i;
266
267         /* QUICK HACK */
268         deviceinfo = deviceinfo;
269
270         if(libusb_init(&usb_context) != 0) {
271                 g_warning("Failed to initialize USB.");
272                 return 0;
273         }
274
275         /* find all ZeroPlus analyzers and add them to device list */
276         devcnt = 0;
277         libusb_get_device_list(usb_context, &devlist);
278         for(i = 0; devlist[i]; i++) {
279                 err = libusb_get_device_descriptor(devlist[i], &des);
280                 if(err != 0) {
281                         g_warning("failed to get device descriptor: %d", err);
282                         continue;
283                 }
284
285                 if(des.idVendor == USB_VENDOR) {
286                         /* definitely a Zeroplus */
287                         /* TODO: any way to detect specific model/version in the zeroplus range? */
288                         sdi = sigrok_device_instance_new(devcnt, ST_INACTIVE,
289                                         USB_VENDOR_NAME, USB_MODEL_NAME, USB_MODEL_VERSION);
290                         if(!sdi)
291                                 return 0;
292                         device_instances = g_slist_append(device_instances, sdi);
293                         sdi->usb = usb_device_instance_new(libusb_get_bus_number(devlist[i]),
294                                         libusb_get_device_address(devlist[i]), NULL);
295                         devcnt++;
296                 }
297         }
298         libusb_free_device_list(devlist, 1);
299
300         return devcnt;
301 }
302
303
304 static int hw_opendev(int device_index)
305 {
306         struct sigrok_device_instance *sdi;
307         int err;
308
309         if( !(sdi = zp_open_device(device_index)) ) {
310                 g_warning("unable to open device");
311                 return SIGROK_ERR;
312         }
313
314         err = libusb_claim_interface(sdi->usb->devhdl, USB_INTERFACE);
315         if(err != 0) {
316                 g_warning("Unable to claim interface: %d", err);
317                 return SIGROK_ERR;
318         }
319         analyzer_reset(sdi->usb->devhdl);
320         analyzer_initialize(sdi->usb->devhdl);
321         analyzer_configure(sdi->usb->devhdl);
322
323         analyzer_set_memory_size(MEMORY_SIZE_512K);
324 //      analyzer_set_freq(g_freq, g_freq_scale);
325         analyzer_set_trigger_count(1);
326 //      analyzer_set_ramsize_trigger_address((((100 - g_pre_trigger) * get_memory_size(g_memory_size)) / 100) >> 2);
327         analyzer_set_ramsize_trigger_address((100 * get_memory_size(MEMORY_SIZE_512K) / 100) >> 2);
328
329 /*      if (g_double_mode == 1)
330                 analyzer_set_compression(COMPRESSION_DOUBLE);
331         else if (g_compression == 1)
332                 analyzer_set_compression(COMPRESSION_ENABLE);
333         else */
334                 analyzer_set_compression(COMPRESSION_NONE);
335
336         if(cur_samplerate == 0) {
337                 /* sample rate hasn't been set; default to the slowest it has */
338                 if(hw_set_configuration(device_index, HWCAP_SAMPLERATE, &samplerates.low) == SIGROK_ERR)
339                         return SIGROK_ERR;
340         }
341
342         return SIGROK_OK;
343 }
344
345
346 static void hw_closedev(int device_index)
347 {
348         struct sigrok_device_instance *sdi;
349
350         if( (sdi = get_sigrok_device_instance(device_instances, device_index)) )
351                 close_device(sdi);
352
353 }
354
355
356 static void hw_cleanup(void)
357 {
358         GSList *l;
359
360         /* properly close all devices */
361         for(l = device_instances; l; l = l->next)
362                 close_device( (struct sigrok_device_instance *) l->data);
363
364         /* and free all their memory */
365         for(l = device_instances; l; l = l->next)
366                 g_free(l->data);
367         g_slist_free(device_instances);
368         device_instances = NULL;
369
370         if(usb_context)
371                 libusb_exit(usb_context);
372         usb_context = NULL;
373
374 }
375
376
377 static void *hw_get_device_info(int device_index, int device_info_id)
378 {
379         struct sigrok_device_instance *sdi;
380         void *info;
381
382         if( !(sdi = get_sigrok_device_instance(device_instances, device_index)) )
383                 return NULL;
384
385         info = NULL;
386         switch(device_info_id)
387         {
388         case DI_INSTANCE:
389                 info = sdi;
390                 break;
391         case DI_NUM_PROBES:
392                 info = GINT_TO_POINTER(num_channels);
393                 break;
394         case DI_SAMPLERATES:
395                 info = &samplerates;
396                 break;
397         case DI_TRIGGER_TYPES:
398                 info = TRIGGER_TYPES;
399                 break;
400         case DI_CUR_SAMPLERATE:
401                 info = &cur_samplerate;
402                 break;
403         }
404
405         return info;
406 }
407
408
409 static int hw_get_status(int device_index)
410 {
411         struct sigrok_device_instance *sdi;
412
413         sdi = get_sigrok_device_instance(device_instances, device_index);
414         if(sdi)
415                 return sdi->status;
416         else
417                 return ST_NOT_FOUND;
418 }
419
420
421 static int *hw_get_capabilities(void)
422 {
423         return capabilities;
424 }
425
426 // XXX this will set the same samplerate for all devices
427 static int set_configuration_samplerate(uint64_t samplerate)
428 {
429         g_message("%s(%llu)", __FUNCTION__, samplerate);
430         if (samplerate > MHZ(1))
431                 analyzer_set_freq(samplerate / MHZ(1), FREQ_SCALE_MHZ);
432         else if (samplerate > KHZ(1))
433                 analyzer_set_freq(samplerate / KHZ(1), FREQ_SCALE_KHZ);
434         else
435                 analyzer_set_freq(samplerate , FREQ_SCALE_HZ);
436
437         cur_samplerate = samplerate;
438
439         return SIGROK_OK;
440 }
441
442 static int hw_set_configuration(int device_index, int capability, void *value)
443 {
444         struct sigrok_device_instance *sdi;
445         uint64_t *tmp_u64;
446
447         if( !(sdi = get_sigrok_device_instance(device_instances, device_index)) )
448                 return SIGROK_ERR;
449
450         switch (capability) {
451                 case HWCAP_SAMPLERATE:
452                         tmp_u64 = value;
453                         return set_configuration_samplerate(*tmp_u64);
454
455                 case HWCAP_PROBECONFIG:
456                         return configure_probes( (GSList *) value);
457
458                 case HWCAP_LIMIT_SAMPLES:
459                         limit_samples = strtoull(value, NULL, 10);
460                         return SIGROK_OK;
461
462                 default:
463                         return SIGROK_ERR;
464         }
465 }
466
467 static int hw_start_acquisition(int device_index, gpointer session_device_id)
468 {
469         struct sigrok_device_instance *sdi;
470         struct datafeed_packet packet;
471         struct datafeed_header header;
472         int res;
473         unsigned int packet_num;
474         unsigned char *buf;
475
476         if( !(sdi = get_sigrok_device_instance(device_instances, device_index)))
477                 return SIGROK_ERR;
478
479         analyzer_start(sdi->usb->devhdl);
480         g_message("Waiting for data");
481         analyzer_wait_data(sdi->usb->devhdl);
482
483         g_message("Stop address    = 0x%x", analyzer_get_stop_address(sdi->usb->devhdl));
484         g_message("Now address     = 0x%x", analyzer_get_now_address(sdi->usb->devhdl));
485         g_message("Trigger address = 0x%x", analyzer_get_trigger_address(sdi->usb->devhdl));
486
487         packet.type = DF_HEADER;
488         packet.length = sizeof(struct datafeed_header);
489         packet.payload = (unsigned char *) &header;
490         header.feed_version = 1;
491         gettimeofday(&header.starttime, NULL);
492         header.samplerate = cur_samplerate;
493         header.protocol_id = PROTO_RAW;
494         header.num_probes = num_channels;
495         session_bus(session_device_id, &packet);
496
497         buf = g_malloc(PACKET_SIZE);
498         if (!buf)
499                 return SIGROK_ERR;
500         analyzer_read_start(sdi->usb->devhdl);
501         /* send the incoming transfer to the session bus */
502         for(packet_num = 0; packet_num < (memory_size * 4 / PACKET_SIZE); packet_num++) {
503                 res = analyzer_read_data(sdi->usb->devhdl, buf, PACKET_SIZE);
504 //              g_message("Tried to read %llx bytes, actually read %x bytes", PACKET_SIZE, res);
505
506                 packet.type = DF_LOGIC32;
507                 packet.length = PACKET_SIZE;
508                 packet.payload = buf;
509                 session_bus(session_device_id, &packet);                
510         }
511         analyzer_read_stop(sdi->usb->devhdl);
512         g_free(buf);
513
514         packet.type = DF_END;
515         session_bus(session_device_id, &packet);
516
517         return SIGROK_OK;
518 }
519
520
521 /* this stops acquisition on ALL devices, ignoring device_index */
522 static void hw_stop_acquisition(int device_index, gpointer session_device_id)
523 {
524         struct datafeed_packet packet;
525         struct sigrok_device_instance *sdi;
526
527         packet.type = DF_END;
528         session_bus(session_device_id, &packet);
529
530         if( !(sdi = get_sigrok_device_instance(device_instances, device_index)))
531                 return; // XXX cry?
532
533         analyzer_reset(sdi->usb->devhdl);
534         /* TODO: need to cancel and free any queued up transfers */
535 }
536
537
538
539 struct device_plugin zeroplus_logic_cube_plugin_info = {
540         "zeroplus-logic-cube",
541         1,
542         hw_init,
543         hw_cleanup,
544
545         hw_opendev,
546         hw_closedev,
547         hw_get_device_info,
548         hw_get_status,
549         hw_get_capabilities,
550         hw_set_configuration,
551         hw_start_acquisition,
552         hw_stop_acquisition
553 };
554