RLE decoding support
[sigrok:sigrok.git] / hardware / openbench-logic-sniffer / ols.c
1 /*
2  *   sigrok - ols.c
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/types.h>
23 #include <sys/stat.h>
24 #include <fcntl.h>
25 #include <unistd.h>
26 #include <termios.h>
27 #include <string.h>
28 #include <poll.h>
29 #include <sys/time.h>
30
31 #include <glib.h>
32
33 #include "sigrok.h"
34 #include "hwplugin.h"
35 #include "hwcommon.h"
36 #include "session.h"
37
38 #define NUM_PROBES                              32
39 #define NUM_TRIGGER_STAGES              4
40 #define TRIGGER_TYPES                   "01"
41 #define SERIAL_SPEED                    B115200
42 /* TODO: SERIAL_ bits, parity, stop bit */
43 #define CLOCK_RATE                              100
44
45
46 /* command opcodes */
47 #define CMD_RESET                                       0x00
48 #define CMD_ID                                          0x02
49 #define CMD_SET_FLAGS                           0x82
50 #define CMD_SET_DIVIDER                 0x80
51 #define CMD_RUN                                 0x01
52 #define CMD_CAPTURE_SIZE                        0x81
53 #define CMD_SET_TRIGGER_MASK_0          0xc0
54 #define CMD_SET_TRIGGER_MASK_1          0xc4
55 #define CMD_SET_TRIGGER_MASK_2          0xc8
56 #define CMD_SET_TRIGGER_MASK_3          0xcc
57 #define CMD_SET_TRIGGER_VALUE_0 0xc1
58 #define CMD_SET_TRIGGER_VALUE_1 0xc5
59 #define CMD_SET_TRIGGER_VALUE_2 0xc9
60 #define CMD_SET_TRIGGER_VALUE_3 0xcd
61 #define CMD_SET_TRIGGER_CONFIG_0        0xc2
62 #define CMD_SET_TRIGGER_CONFIG_1        0xc6
63 #define CMD_SET_TRIGGER_CONFIG_2        0xca
64 #define CMD_SET_TRIGGER_CONFIG_3        0xce
65
66 /* bitmasks for CMD_FLAGS */
67 #define FLAG_DEMUX                              0x01
68 #define FLAG_FILTER                     0x02
69 #define FLAG_CHANNELGROUP_1     0x04
70 #define FLAG_CHANNELGROUP_2     0x08
71 #define FLAG_CHANNELGROUP_3     0x10
72 #define FLAG_CHANNELGROUP_4     0x20
73 #define FLAG_CLOCK_EXTERNAL     0x40
74 #define FLAG_CLOCK_INVERTED     0x80
75 #define FLAG_RLE                                0x0100
76
77
78 int capabilities[] = {
79         HWCAP_LOGIC_ANALYZER,
80         HWCAP_SAMPLERATE,
81         HWCAP_CAPTURE_RATIO,
82         HWCAP_LIMIT_SECONDS,
83         HWCAP_LIMIT_SAMPLES,
84         0
85 };
86
87 float supported_sample_rates[] = {
88         0.2,
89         0.25,
90         0.50,
91         1,
92         2,
93         4,
94         8,
95         10,
96         20,
97         50,
98         70,
99         100,
100         200,
101         0
102 };
103
104 /* list of struct serial_device_instance  */
105 GSList *serial_devices = NULL;
106
107 /* current state of the flag register */
108 uint32_t flag_reg = 0;
109
110 float cur_sample_rate = 0;
111 int limit_seconds = 0;
112 int limit_samples = 0;
113 /* pre/post trigger capture ratio, in percentage. 0 means no pre-trigger data. */
114 int capture_ratio = 0;
115 uint32_t probe_mask = 0, trigger_mask[4] = {0}, trigger_value[4] = {0};
116
117
118
119 int send_longcommand(int fd, uint8_t command, uint32_t data)
120 {
121         char buf[5];
122
123         buf[0] = command;
124         buf[1] = data & 0xff;
125         buf[2] = data & 0xff00 >> 8;
126         buf[3] = data & 0xff0000 >> 16;
127         buf[4] = data & 0xff000000 >> 24;
128         if(write(fd, buf, 5) != 5)
129                 return SIGROK_NOK;
130
131         return SIGROK_OK;
132 }
133
134 int configure_probes(GSList *probes)
135 {
136         struct probe *probe;
137         GSList *l;
138         int probe_bit, changrp_mask, stage, i;
139         char *tc;
140
141         probe_mask = 0;
142         for(i = 0; i < NUM_TRIGGER_STAGES; i++)
143         {
144                 trigger_mask[i] = 0;
145                 trigger_value[i] = 0;
146         }
147
148         for(l = probes; l; l = l->next)
149         {
150                 probe = (struct probe *) l->data;
151                 probe_bit = 1 << (probe->index - 1);
152                 probe_mask |= probe_bit;
153                 if(probe->trigger)
154                 {
155                         stage = 0;
156                         for(tc = probe->trigger; *tc; tc++)
157                         {
158                                 trigger_mask[stage] |= probe_bit;
159                                 if(*tc == '1')
160                                         trigger_value[stage] |= probe_bit;
161                                 stage++;
162                                 if(stage > 3)
163                                 {
164                                         /* only supporting parallel mode, with up to 4 stages */
165                                         return SIGROK_NOK;
166                                 }
167                         }
168                 }
169         }
170
171         /* enable/disable channel groups in the flag register according
172          * to the probe mask we just made. The register stores them backwards,
173          * hence shift right from 1000.
174          */
175         changrp_mask = 0;
176         for(i = 0; i < 4; i++)
177         {
178                 if(probe_mask & (0xff << i))
179                         changrp_mask |= 8 >> i;
180         }
181         /* but the flag register wants them here */
182         flag_reg |= changrp_mask << 2;
183
184         return SIGROK_OK;
185 }
186
187
188 int hw_init(char *deviceinfo)
189 {
190         GSList *ports, *l;
191         struct pollfd *fds;
192         struct termios term, *prev_termios;
193         struct serial_device_instance *dev;
194         int devcnt, final_devcnt, num_ports, fd, i;
195         char buf[8], **device_names;
196
197         if(deviceinfo)
198                 ports = g_slist_append(NULL, g_strdup(deviceinfo));
199         else
200                 /* no specific device given, so scan all serial ports */
201                 ports = list_serial_ports();
202
203         num_ports = g_slist_length(ports);
204         fds = g_malloc0(num_ports * sizeof(struct pollfd));
205         device_names = g_malloc(num_ports * (sizeof(char *)));
206         prev_termios = g_malloc(num_ports * sizeof(struct termios));
207         devcnt = 0;
208         for(l = ports; l; l = l->next)
209         {
210                 /* The discovery procedure is like this: first send the Reset command (0x00) 5 times,
211                  * since the device could be anywhere in a 5-byte command. Then send the ID command
212                  * (0x02). If the device responds with 4 bytes ("OLS1" or "SLA1"), we have a match.
213                  * Since it may take the device a while to respond at 115Kb/s, we do all the sending
214                  * first, then wait for all of them to respond with poll().
215                  */
216                 fd = open(l->data, O_RDWR | O_NONBLOCK);
217                 if(fd != -1)
218                 {
219                         tcgetattr(fd, &prev_termios[devcnt]);
220                         tcgetattr(fd, &term);
221                         cfsetispeed(&term, SERIAL_SPEED);
222                         tcsetattr(fd, TCSADRAIN, &term);
223                         memset(buf, CMD_RESET, 5);
224                         buf[5] = CMD_ID;
225                         if(write(fd, buf, 6) == 6)
226                         {
227                                 fds[devcnt].fd = fd;
228                                 fds[devcnt].events = POLLIN;
229                                 device_names[devcnt] = l->data;
230                                 devcnt++;
231                                 g_message("probed device %s", (char *) l->data);
232                         }
233                         else
234                         {
235                                 tcsetattr(fd, TCSADRAIN, &prev_termios[devcnt]);
236                                 g_free(l->data);
237                         }
238                 }
239         }
240
241         /* 2ms should do it, that's enough time for 28 bytes to go over the bus */
242         usleep(2000);
243         final_devcnt = 0;
244         poll(fds, devcnt, 1);
245         for(i = 0; i < devcnt; i++)
246         {
247                 if(fds[i].revents == POLLIN)
248                 {
249                         if(read(fds[i].fd, buf, 4) == 4)
250                         {
251                                 if(!strncmp(buf, "1SLO", 4) || !strncmp(buf, "1ALS", 4))
252                                 {
253                                         dev = g_malloc(sizeof(struct serial_device_instance));
254                                         dev->index = final_devcnt;
255                                         dev->status = ST_INACTIVE;
256                                         dev->port = g_strdup(device_names[i]);
257                                         dev->fd = -1;
258                                         if(!strncmp(buf, "1SLO", 4))
259                                                 dev->model = g_strdup("OLS v1.0");
260                                         else
261                                                 dev->model = g_strdup("Sump v1.0");
262                                         serial_devices = g_slist_append(serial_devices, dev);
263                                         final_devcnt++;
264                                         fds[i].fd = 0;
265                                 }
266                         }
267                 }
268
269                 if(fds[i].fd != 0)
270                         tcsetattr(fds[i].fd, TCSADRAIN, &prev_termios[i]);
271                 close(fds[i].fd);
272         }
273
274         g_free(fds);
275         g_free(device_names);
276         g_free(prev_termios);
277         g_slist_free(ports);
278
279         return final_devcnt;
280 }
281
282
283 int hw_opendev(int device_index)
284 {
285         struct serial_device_instance *sdi;
286
287         if(!(sdi = get_serial_device_instance(serial_devices, device_index)))
288                 return SIGROK_NOK;
289
290         sdi->fd = open(sdi->port, O_RDWR);
291         if(sdi->fd == -1)
292                 return SIGROK_NOK;
293         sdi->status = ST_ACTIVE;
294
295         return SIGROK_OK;
296 }
297
298
299 void hw_closedev(int device_index)
300 {
301         struct serial_device_instance *sdi;
302
303         if(!(sdi = get_serial_device_instance(serial_devices, device_index)))
304                 return;
305
306         if(sdi->fd != -1)
307         {
308                 close(sdi->fd);
309                 sdi->fd = -1;
310                 sdi->status = ST_INACTIVE;
311         }
312
313 }
314
315
316 void hw_cleanup(void)
317 {
318         GSList *l;
319         struct serial_device_instance *sdi;
320
321         /* properly close all devices */
322         for(l = serial_devices; l; l = l->next)
323         {
324                 sdi = l->data;
325                 if(sdi->fd != -1)
326                         close(sdi->fd);
327                 g_free(sdi->model);
328                 g_free(sdi->port);
329                 g_free(sdi);
330         }
331         g_slist_free(serial_devices);
332         serial_devices = NULL;
333
334 }
335
336
337 char *hw_get_device_info(int device_index, int device_info_id)
338 {
339         char *info;
340
341         info = NULL;
342         switch(device_info_id)
343         {
344         case DI_IDENTIFIER:
345                 info = g_malloc(16);
346                 snprintf(info, 16, "unit %d", device_index);
347                 break;
348         case DI_NUM_PROBES:
349                 info = GINT_TO_POINTER(NUM_PROBES);
350                 break;
351         case DI_SAMPLE_RATES:
352                 info = (char *) supported_sample_rates;
353                 break;
354         case DI_TRIGGER_TYPES:
355                 info = (char *) TRIGGER_TYPES;
356                 break;
357         }
358
359         return info;
360 }
361
362
363 int hw_get_status(int device_index)
364 {
365         struct serial_device_instance *sdi;
366
367         if(!(sdi = get_serial_device_instance(serial_devices, device_index)))
368                 return ST_NOT_FOUND;
369
370         return sdi->status;
371 }
372
373
374 int *hw_get_capabilities(void)
375 {
376
377         return capabilities;
378 }
379
380
381 int set_configuration_samplerate(struct serial_device_instance *sdi, float rate)
382 {
383         uint32_t divider;
384
385         if(rate < 0.00001 || rate > 200)
386                 return SIGROK_ERR_BADVALUE;
387
388         if(rate  > CLOCK_RATE)
389         {
390                 flag_reg |= FLAG_DEMUX;
391                 divider = (uint8_t) (CLOCK_RATE * 2 / rate) - 1;
392         }
393         else
394         {
395                 flag_reg &= FLAG_DEMUX;
396                 divider = (uint8_t) (CLOCK_RATE / rate) - 1;
397         }
398
399         g_message("setting sample rate to %.3f Mhz (divider %d, demux %s)", rate, divider,
400                         flag_reg & FLAG_DEMUX ? "on" : "off");
401         if(send_longcommand(sdi->fd, CMD_SET_DIVIDER, divider) != SIGROK_OK)
402                 return SIGROK_NOK;
403         cur_sample_rate = rate;
404
405         return SIGROK_OK;
406 }
407
408
409 int hw_set_configuration(int device_index, int capability, char *value)
410 {
411         struct serial_device_instance *sdi;
412         int ret;
413
414         if(!(sdi = get_serial_device_instance(serial_devices, device_index)))
415                 return SIGROK_NOK;
416
417         if(sdi->status != ST_ACTIVE)
418                 return SIGROK_NOK;
419
420         if(capability == HWCAP_SAMPLERATE)
421                 ret = set_configuration_samplerate(sdi, atof(value));
422         else if(capability == HWCAP_PROBECONFIG)
423                 ret = configure_probes( (GSList *) value);
424         else if(capability == HWCAP_LIMIT_SECONDS)
425         {
426                 limit_seconds = atoi(value);
427                 ret = SIGROK_OK;
428         }
429         else if(capability == HWCAP_LIMIT_SAMPLES)
430         {
431                 limit_samples = atoi(value);
432                 ret = SIGROK_OK;
433         }
434         else if(capability == HWCAP_CAPTURE_RATIO)
435         {
436                 capture_ratio = atoi(value);
437                 if(capture_ratio < 0 || capture_ratio > 100)
438                 {
439                         capture_ratio = 0;
440                         ret = SIGROK_NOK;
441                 }
442                 else
443                         ret = SIGROK_OK;
444         }
445         else
446                 ret = SIGROK_NOK;
447
448         return ret;
449 }
450
451
452 int receive_data(GSource *source, gpointer user_data)
453 {
454         static char last_sample[4] = {0xff};
455         static int num_bytes = 0;
456         static unsigned char sample[4];
457         int fd, count, buflen, i;
458         struct datafeed_packet packet;
459         unsigned char byte, *buffer;
460
461         /* TODO: need to get a timeout in here -- can the GSource be changed in place? */
462
463         fd = ((struct gsource_fd *) source)->gpfd.fd;
464         if(read(fd, &byte, 1) != 1)
465                 return FALSE;
466
467         sample[num_bytes++] = byte;
468         if(num_bytes == 4)
469         {
470                 /* got a full sample */
471                 if(flag_reg & FLAG_RLE)
472                 {
473                         /* in RLE mode -1 should never come in as a sample, because
474                          * bit 31 is the "count" flag */
475                         /* TODO: endianness may be wrong here, could be sample[3] */
476                         if(sample[0] & 0x80 && !(last_sample[0] & 0x80))
477                         {
478                                 count = (int) (*sample) & 0x7fffffff;
479                                 buffer = g_malloc(count);
480                                 buflen = 0;
481                                 for(i = 0; i < count; i++)
482                                 {
483                                         memcpy(buffer + buflen , last_sample, 4);
484                                         buflen += 4;
485                                 }
486                         }
487                         else
488                         {
489                                 /* just a single sample, next sample will probably be a count
490                                  * referring to this -- but this one is still a part of the stream
491                                  */
492                                 buffer = sample;
493                                 buflen = 4;
494                         }
495                 }
496                 else
497                 {
498                         /* no compression */
499                         buffer = sample;
500                         buflen = 4;
501                 }
502
503                 /* send it all to the session bus */
504                 packet.type = DF_LOGIC32;
505                 packet.length = buflen;
506                 packet.payload = buffer;
507                 session_bus(user_data, &packet);
508                 if(buffer == sample)
509                         memcpy(last_sample, buffer, 4);
510                 else
511                         g_free(buffer);
512
513                 num_bytes = 0;
514         }
515
516         return TRUE;
517 }
518
519
520 int hw_start_acquisition(int device_index, gpointer session_device_id)
521 {
522         struct datafeed_packet *packet;
523         struct datafeed_header *header;
524         struct serial_device_instance *sdi;
525         char buf[5];
526         uint32_t data;
527
528         if(!(sdi = get_serial_device_instance(serial_devices, device_index)))
529                 return SIGROK_NOK;
530
531         if(sdi->status != ST_ACTIVE)
532                 return SIGROK_NOK;
533
534         /* send flag register */
535         data = flag_reg;
536         if(send_longcommand(sdi->fd, CMD_SET_FLAGS, data) != SIGROK_OK)
537                 return SIGROK_NOK;
538
539         /* send sample limit and pre/post-trigger capture ratio */
540         data = limit_samples / 4 << 16;
541         if(capture_ratio)
542                 data |= (limit_samples - (limit_samples / 100 * capture_ratio)) / 4;
543         if(send_longcommand(sdi->fd, CMD_CAPTURE_SIZE, data) != SIGROK_OK)
544                 return SIGROK_NOK;
545
546         /* trigger masks */
547         if(send_longcommand(sdi->fd, CMD_SET_TRIGGER_MASK_0, trigger_mask[0]) != SIGROK_OK)
548                 return SIGROK_NOK;
549         if(send_longcommand(sdi->fd, CMD_SET_TRIGGER_MASK_1, trigger_mask[1]) != SIGROK_OK)
550                 return SIGROK_NOK;
551         if(send_longcommand(sdi->fd, CMD_SET_TRIGGER_MASK_2, trigger_mask[2]) != SIGROK_OK)
552                 return SIGROK_NOK;
553         if(send_longcommand(sdi->fd, CMD_SET_TRIGGER_MASK_3, trigger_mask[3]) != SIGROK_OK)
554                 return SIGROK_NOK;
555
556         if(send_longcommand(sdi->fd, CMD_SET_TRIGGER_VALUE_0, trigger_value[0]) != SIGROK_OK)
557                 return SIGROK_NOK;
558         if(send_longcommand(sdi->fd, CMD_SET_TRIGGER_VALUE_1, trigger_value[1]) != SIGROK_OK)
559                 return SIGROK_NOK;
560         if(send_longcommand(sdi->fd, CMD_SET_TRIGGER_VALUE_2, trigger_value[2]) != SIGROK_OK)
561                 return SIGROK_NOK;
562         if(send_longcommand(sdi->fd, CMD_SET_TRIGGER_VALUE_3, trigger_value[3]) != SIGROK_OK)
563                 return SIGROK_NOK;
564
565         /* trigger configuration */
566         /* TODO: the start flag should only be on the last used stage I think... */
567         if(send_longcommand(sdi->fd, CMD_SET_TRIGGER_CONFIG_0, 0x00000001) != SIGROK_OK)
568                 return SIGROK_NOK;
569         if(send_longcommand(sdi->fd, CMD_SET_TRIGGER_CONFIG_1, 0x00000001) != SIGROK_OK)
570                 return SIGROK_NOK;
571         if(send_longcommand(sdi->fd, CMD_SET_TRIGGER_CONFIG_2, 0x00000001) != SIGROK_OK)
572                 return SIGROK_NOK;
573         if(send_longcommand(sdi->fd, CMD_SET_TRIGGER_CONFIG_3, 0x00000001) != SIGROK_OK)
574                 return SIGROK_NOK;
575
576         /* start acquisition on the device */
577         buf[0] = CMD_RUN;
578         if(write(sdi->fd, buf, 1) != 1)
579                 return SIGROK_NOK;
580
581         add_source_fd(sdi->fd, POLLIN, receive_data, session_device_id);
582
583         /* send header packet to the session bus */
584         packet = g_malloc(sizeof(struct datafeed_packet));
585         header = g_malloc(sizeof(struct datafeed_header));
586         if(!packet || !header)
587                 return SIGROK_NOK;
588         packet->type = DF_HEADER;
589         packet->length = sizeof(struct datafeed_header);
590         packet->payload = (unsigned char *) header;
591         header->feed_version = 1;
592         gettimeofday(&header->starttime, NULL);
593         header->rate = cur_sample_rate;
594         header->protocol_id = PROTO_RAW;
595         header->num_probes = NUM_PROBES;
596         session_bus(session_device_id, packet);
597         g_free(header);
598         g_free(packet);
599
600         return SIGROK_OK;
601 }
602
603
604 void hw_stop_acquisition(int device_index, gpointer session_device_id)
605 {
606         struct datafeed_packet packet;
607
608         packet.type = DF_END;
609         session_bus(session_device_id, &packet);
610
611 }
612
613
614
615 struct device_plugin plugin_info = {
616         "Openbench Logic Sniffer",
617         1,
618         hw_init,
619         hw_cleanup,
620
621         hw_opendev,
622         hw_closedev,
623         hw_get_device_info,
624         hw_get_status,
625         hw_get_capabilities,
626         hw_set_configuration,
627         hw_start_acquisition,
628         hw_stop_acquisition
629 };
630