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