]> sigrok.org Git - libsigrok.git/blob - src/hardware/demo/protocol.c
demo: Minor cosmetics.
[libsigrok.git] / src / hardware / demo / protocol.c
1 /*
2  * This file is part of the libsigrok project.
3  *
4  * Copyright (C) 2010 Uwe Hermann <uwe@hermann-uwe.de>
5  * Copyright (C) 2011 Olivier Fauchon <olivier@aixmarseille.com>
6  * Copyright (C) 2012 Alexandru Gagniuc <mr.nuke.me@gmail.com>
7  * Copyright (C) 2015 Bartosz Golaszewski <bgolaszewski@baylibre.com>
8  * Copyright (C) 2019 Frank Stettner <frank-stettner@gmx.net>
9  *
10  * This program is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License as published by
12  * the Free Software Foundation; either version 2 of the License, or
13  * (at your option) any later version.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with this program; if not, see <http://www.gnu.org/licenses/>.
22  */
23
24 #include <config.h>
25 #include <stdlib.h>
26 #include <string.h>
27 #include <math.h>
28 #include <libsigrok/libsigrok.h>
29 #include "libsigrok-internal.h"
30 #include "protocol.h"
31
32 #define ANALOG_SAMPLES_PER_PERIOD 20
33
34 static const uint8_t pattern_sigrok[] = {
35         0x4c, 0x92, 0x92, 0x92, 0x64, 0x00, 0x00, 0x00,
36         0x82, 0xfe, 0xfe, 0x82, 0x00, 0x00, 0x00, 0x00,
37         0x7c, 0x82, 0x82, 0x92, 0x74, 0x00, 0x00, 0x00,
38         0xfe, 0x12, 0x12, 0x32, 0xcc, 0x00, 0x00, 0x00,
39         0x7c, 0x82, 0x82, 0x82, 0x7c, 0x00, 0x00, 0x00,
40         0xfe, 0x10, 0x28, 0x44, 0x82, 0x00, 0x00, 0x00,
41         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
42         0xbe, 0xbe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
43 };
44
45 static const uint8_t pattern_squid[128][128 / 8] = {
46         { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, },
47         { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, },
48         { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, },
49         { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, },
50         { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, },
51         { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, },
52         { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, },
53         { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, },
54         { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, },
55         { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, },
56         { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, },
57         { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0xe0, 0x00, },
58         { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xe1, 0x01, },
59         { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xe1, 0x01, },
60         { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xe3, 0x03, },
61         { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xe3, 0x03, },
62         { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xc3, 0x03, },
63         { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xcf, 0xc7, 0x03, },
64         { 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8f, 0xc7, 0x03, },
65         { 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8f, 0x87, 0x03, },
66         { 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8f, 0xc7, 0x03, },
67         { 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8f, 0xcf, 0x03, },
68         { 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xcf, 0x03, },
69         { 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xff, 0x03, },
70         { 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0xff, 0x03, },
71         { 0x00, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, 0xfe, 0x01, },
72         { 0x00, 0x00, 0x00, 0x80, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0xfe, 0x01, },
73         { 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0xfc, 0x00, },
74         { 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, },
75         { 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, },
76         { 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, },
77         { 0x00, 0xc0, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, },
78         { 0x00, 0x80, 0x01, 0x00, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0xfe, 0xff, 0x03, },
79         { 0x00, 0x00, 0x07, 0x00, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xfe, 0xff, 0x03, },
80         { 0x00, 0x00, 0x1c, 0x00, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xfe, 0xff, 0x03, },
81         { 0x00, 0x00, 0x78, 0x00, 0xc0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xfe, 0xff, 0x03, },
82         { 0x00, 0x00, 0xe0, 0x00, 0x80, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0xfe, 0xff, 0x03, },
83         { 0x00, 0x00, 0xc0, 0x03, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, },
84         { 0x00, 0x00, 0x00, 0x07, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, },
85         { 0x00, 0x00, 0x00, 0x1c, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, },
86         { 0x00, 0x00, 0x00, 0xf8, 0x00, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x03, 0x00, },
87         { 0x00, 0x00, 0x00, 0xf0, 0x01, 0x38, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x01, 0x00, 0xf0, 0x1f, 0x1c, },
88         { 0x00, 0x00, 0x00, 0xe0, 0x07, 0x70, 0x00, 0x00, 0x00, 0xfe, 0xff, 0x0f, 0x00, 0xfc, 0x3f, 0x3c, },
89         { 0x80, 0x03, 0x00, 0xc0, 0x0f, 0xe0, 0x00, 0x00, 0x80, 0xff, 0xff, 0x3f, 0x00, 0xfc, 0x7f, 0x7c, },
90         { 0x00, 0x1e, 0x00, 0x00, 0x1f, 0xc0, 0x01, 0x00, 0xc0, 0xff, 0xff, 0x7f, 0x00, 0xfe, 0xff, 0x7c, },
91         { 0x00, 0xf0, 0x01, 0x00, 0x7c, 0x80, 0x03, 0x00, 0xc0, 0xff, 0xff, 0xff, 0x00, 0xfe, 0xff, 0x7c, },
92         { 0x00, 0xc0, 0x0f, 0x00, 0xf0, 0x00, 0x07, 0x00, 0xc0, 0xff, 0xff, 0xff, 0x00, 0x3f, 0xf8, 0x78, },
93         { 0x00, 0x00, 0x3e, 0x00, 0xc0, 0x03, 0x0e, 0x00, 0xe0, 0xff, 0xff, 0xff, 0x00, 0x0f, 0xf0, 0xf0, },
94         { 0x00, 0x00, 0xf0, 0x07, 0x80, 0x07, 0x3c, 0x00, 0xe0, 0xff, 0xff, 0xff, 0x00, 0x0f, 0xf0, 0xf0, },
95         { 0x00, 0x00, 0x80, 0x3f, 0x00, 0x1e, 0x78, 0x00, 0xe0, 0xff, 0xff, 0xff, 0x00, 0x0f, 0xe0, 0xf0, },
96         { 0x00, 0x00, 0x00, 0xff, 0x00, 0x7c, 0xe0, 0x01, 0xe0, 0xff, 0xff, 0xff, 0x00, 0x0f, 0xe0, 0xf0, },
97         { 0x00, 0x00, 0x00, 0xfc, 0x03, 0xf0, 0xc1, 0x07, 0xf0, 0xff, 0xff, 0xff, 0x00, 0x0f, 0xf0, 0xf0, },
98         { 0x00, 0x00, 0x00, 0xe0, 0x1f, 0xc0, 0x03, 0x1f, 0xe0, 0xff, 0xff, 0xff, 0x00, 0x0f, 0xf0, 0x78, },
99         { 0x00, 0x00, 0x00, 0x00, 0xfe, 0x00, 0x1f, 0xfc, 0xe0, 0xff, 0xff, 0xff, 0x01, 0xff, 0xff, 0x7f, },
100         { 0xf8, 0x03, 0x00, 0x00, 0xf0, 0x07, 0xfe, 0xf0, 0xff, 0xff, 0xff, 0xff, 0x01, 0xff, 0xff, 0x7f, },
101         { 0x80, 0xff, 0x01, 0x00, 0x80, 0x3f, 0xf0, 0x8f, 0xff, 0xff, 0xff, 0xff, 0x00, 0xfe, 0xff, 0x3f, },
102         { 0x00, 0xf0, 0xff, 0x07, 0x00, 0xfc, 0x83, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0xfe, 0xff, 0x3f, },
103         { 0x00, 0x00, 0xfc, 0x7f, 0x00, 0xe0, 0x7f, 0xfc, 0xff, 0xff, 0xff, 0xff, 0x00, 0xfe, 0xff, 0x1f, },
104         { 0x00, 0x00, 0xc0, 0xff, 0x1f, 0x00, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0xfc, 0xff, 0x03, },
105         { 0x00, 0x00, 0x00, 0xf8, 0xff, 0x07, 0xc0, 0xff, 0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, },
106         { 0x00, 0x00, 0x00, 0x00, 0xf8, 0xff, 0x0f, 0xe0, 0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, },
107         { 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, },
108         { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, },
109         { 0x00, 0x00, 0xf8, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x01, 0xff, 0xff, 0x03, },
110         { 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x01, 0xff, 0xff, 0x03, },
111         { 0x00, 0x10, 0xf8, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0x03, },
112         { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0x03, },
113         { 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0x03, },
114         { 0x00, 0x00, 0x00, 0x00, 0xf8, 0xff, 0x0f, 0xe0, 0xff, 0xff, 0xff, 0xff, 0x00, 0x7c, 0x00, 0x00, },
115         { 0x00, 0x00, 0x00, 0xf8, 0xff, 0x07, 0xc0, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x3c, 0x00, 0x00, },
116         { 0x00, 0x00, 0xc0, 0xff, 0x1f, 0x00, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x1e, 0x00, 0x00, },
117         { 0x00, 0x00, 0xf8, 0x7f, 0x00, 0xe0, 0x7f, 0xfc, 0xff, 0xff, 0xff, 0xff, 0x00, 0x1e, 0x00, 0x00, },
118         { 0x00, 0xf0, 0xff, 0x07, 0x00, 0xfc, 0x83, 0xff, 0xff, 0xff, 0xff, 0xff, 0x01, 0x0f, 0x00, 0x00, },
119         { 0x80, 0xff, 0x01, 0x00, 0x80, 0x3f, 0xf0, 0x8f, 0xff, 0xff, 0xff, 0xff, 0x01, 0x0f, 0x00, 0x00, },
120         { 0xf8, 0x03, 0x00, 0x00, 0xf0, 0x07, 0xfe, 0xf0, 0xff, 0xff, 0xff, 0xff, 0x00, 0x0f, 0x00, 0x00, },
121         { 0x00, 0x00, 0x00, 0x00, 0xfe, 0x00, 0x1f, 0xfc, 0xe0, 0xff, 0xff, 0xff, 0x00, 0x0f, 0x00, 0x00, },
122         { 0x00, 0x00, 0x00, 0xe0, 0x1f, 0xc0, 0x07, 0x1f, 0xf0, 0xff, 0xff, 0xff, 0x00, 0x06, 0x00, 0x00, },
123         { 0x00, 0x00, 0x00, 0xfc, 0x03, 0xf0, 0xc1, 0x07, 0xf0, 0xff, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, },
124         { 0x00, 0x00, 0x00, 0xff, 0x00, 0x7c, 0xe0, 0x01, 0xf0, 0xff, 0xff, 0xff, 0x01, 0xe0, 0x1f, 0x00, },
125         { 0x00, 0x00, 0x80, 0x3f, 0x00, 0x1e, 0x78, 0x00, 0xf0, 0xff, 0xff, 0xff, 0x01, 0xf0, 0x7f, 0x00, },
126         { 0x00, 0x00, 0xf0, 0x0f, 0x80, 0x07, 0x3c, 0x00, 0xe0, 0xff, 0xff, 0xff, 0x01, 0xfc, 0xff, 0x00, },
127         { 0x00, 0x00, 0x3e, 0x00, 0xc0, 0x03, 0x0e, 0x00, 0xe0, 0xff, 0xff, 0xff, 0x01, 0xfc, 0xff, 0x01, },
128         { 0x00, 0xc0, 0x0f, 0x00, 0xf0, 0x00, 0x07, 0x00, 0xe0, 0xff, 0xff, 0xff, 0x01, 0xfe, 0xff, 0x01, },
129         { 0x00, 0xf0, 0x01, 0x00, 0x7c, 0x80, 0x03, 0x00, 0xe0, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0x03, },
130         { 0x00, 0x3e, 0x00, 0x00, 0x1f, 0xc0, 0x01, 0x00, 0x80, 0xff, 0xff, 0xff, 0x00, 0x1f, 0xe0, 0x03, },
131         { 0x80, 0x03, 0x00, 0xc0, 0x0f, 0xe0, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x0f, 0xc0, 0x03, },
132         { 0x00, 0x00, 0x00, 0xe0, 0x07, 0x70, 0x00, 0x00, 0x00, 0xfc, 0xff, 0xff, 0x00, 0x0f, 0xc0, 0x03, },
133         { 0x00, 0x00, 0x00, 0xf0, 0x01, 0x38, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x01, 0x00, 0x0f, 0x80, 0x03, },
134         { 0x00, 0x00, 0x00, 0xf8, 0x00, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xc0, 0x03, },
135         { 0x00, 0x00, 0x00, 0x1c, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xc0, 0x03, },
136         { 0x00, 0x00, 0x00, 0x07, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xe0, 0x03, },
137         { 0x00, 0x00, 0xc0, 0x03, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xf8, 0x03, },
138         { 0x00, 0x00, 0xe0, 0x00, 0x80, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, 0x01, },
139         { 0x00, 0x00, 0x78, 0x00, 0xc0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, 0x01, },
140         { 0x00, 0x00, 0x1c, 0x00, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xff, 0x00, },
141         { 0x00, 0x00, 0x06, 0x00, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x7f, 0x00, },
142         { 0x00, 0x80, 0x03, 0x00, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x1f, 0x00, },
143         { 0x00, 0xc0, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, },
144         { 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, },
145         { 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, },
146         { 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xff, 0xff, 0x01, },
147         { 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xff, 0xff, 0x03, },
148         { 0x00, 0x00, 0x00, 0x80, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xff, 0xff, 0x03, },
149         { 0x00, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xff, 0xff, 0x03, },
150         { 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xff, 0xff, 0x03, },
151         { 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xff, 0xff, 0x03, },
152         { 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x07, 0x00, },
153         { 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x07, 0x00, },
154         { 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x0f, 0x00, },
155         { 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x1f, 0x00, },
156         { 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x3f, 0x00, },
157         { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xff, 0x00, },
158         { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, 0x01, },
159         { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xfc, 0x03, },
160         { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xf8, 0x03, },
161         { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xf0, 0x03, },
162         { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xc0, 0x03, },
163         { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, },
164         { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, },
165         { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, },
166         { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, },
167         { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, },
168         { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, },
169         { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, },
170         { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, },
171         { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, },
172         { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, },
173         { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, },
174 };
175
176 SR_PRIV void demo_generate_analog_pattern(struct dev_context *devc)
177 {
178         double t, frequency;
179         float amplitude, offset;
180         struct analog_pattern *pattern;
181         unsigned int num_samples, i;
182         float value;
183         int last_end;
184
185         num_samples = ANALOG_BUFSIZE / sizeof(float);
186         frequency = (double) devc->cur_samplerate / ANALOG_SAMPLES_PER_PERIOD;
187         amplitude = DEFAULT_ANALOG_AMPLITUDE;
188         offset = DEFAULT_ANALOG_OFFSET;
189
190         /*
191          * FIXME: We actually need only one period. A ringbuffer would be
192          * useful here.
193          * Make sure the number of samples we put out is an integer
194          * multiple of our period size.
195          */
196
197         /* PATTERN_SQUARE: */
198         sr_dbg("Generating %s pattern.", analog_pattern_str[PATTERN_SQUARE]);
199         pattern = g_malloc(sizeof(struct analog_pattern));
200         value = amplitude;
201         last_end = 0;
202         for (i = 0; i < num_samples; i++) {
203                 if (i % 5 == 0)
204                         value = -value;
205                 if (i % 10 == 0)
206                         last_end = i;
207                 pattern->data[i] = value + offset;
208         }
209         pattern->num_samples = last_end;
210         devc->analog_patterns[PATTERN_SQUARE] = pattern;
211
212         /* Readjusting num_samples for all other patterns. */
213         while (num_samples % ANALOG_SAMPLES_PER_PERIOD != 0)
214                 num_samples--;
215
216         /* PATTERN_SINE: */
217         sr_dbg("Generating %s pattern.", analog_pattern_str[PATTERN_SINE]);
218         pattern = g_malloc(sizeof(struct analog_pattern));
219         for (i = 0; i < num_samples; i++) {
220                 t = (double) i / (double) devc->cur_samplerate;
221                 pattern->data[i] = sin(2 * G_PI * frequency * t) * amplitude + offset;
222         }
223         pattern->num_samples = last_end;
224         devc->analog_patterns[PATTERN_SINE] = pattern;
225
226         /* PATTERN_TRIANGLE: */
227         sr_dbg("Generating %s pattern.", analog_pattern_str[PATTERN_TRIANGLE]);
228         pattern = g_malloc(sizeof(struct analog_pattern));
229         for (i = 0; i < num_samples; i++) {
230                 t = (double) i / (double) devc->cur_samplerate;
231                 pattern->data[i] = (2 / G_PI) * asin(sin(2 * G_PI * frequency * t)) *
232                         amplitude + offset;
233         }
234         pattern->num_samples = last_end;
235         devc->analog_patterns[PATTERN_TRIANGLE] = pattern;
236
237         /* PATTERN_SAWTOOTH: */
238         sr_dbg("Generating %s pattern.", analog_pattern_str[PATTERN_SAWTOOTH]);
239         pattern = g_malloc(sizeof(struct analog_pattern));
240         for (i = 0; i < num_samples; i++) {
241                 t = (double) i / (double) devc->cur_samplerate;
242                 pattern->data[i] = 2 * ((t * frequency) - floor(0.5f + t * frequency)) *
243                         amplitude + offset;
244         }
245         pattern->num_samples = last_end;
246         devc->analog_patterns[PATTERN_SAWTOOTH] = pattern;
247 }
248
249 static uint64_t encode_number_to_gray(uint64_t nr)
250 {
251         return nr ^ (nr >> 1);
252 }
253
254 static void set_logic_data(uint64_t bits, uint8_t *data, size_t len)
255 {
256         while (len--) {
257                 *data++ = bits & 0xff;
258                 bits >>= 8;
259         }
260 }
261
262 static void logic_generator(struct sr_dev_inst *sdi, uint64_t size)
263 {
264         struct dev_context *devc;
265         uint64_t i, j;
266         uint8_t pat;
267         uint8_t *sample;
268         const uint8_t *image_col;
269         size_t col_count, col_height;
270         uint64_t gray;
271
272         devc = sdi->priv;
273
274         switch (devc->logic_pattern) {
275         case PATTERN_SIGROK:
276                 memset(devc->logic_data, 0x00, size);
277                 for (i = 0; i < size; i += devc->logic_unitsize) {
278                         for (j = 0; j < devc->logic_unitsize; j++) {
279                                 pat = pattern_sigrok[(devc->step + j) % sizeof(pattern_sigrok)] >> 1;
280                                 devc->logic_data[i + j] = ~pat;
281                         }
282                         devc->step++;
283                 }
284                 break;
285         case PATTERN_RANDOM:
286                 for (i = 0; i < size; i++)
287                         devc->logic_data[i] = (uint8_t)(rand() & 0xff);
288                 break;
289         case PATTERN_INC:
290                 for (i = 0; i < size; i++) {
291                         for (j = 0; j < devc->logic_unitsize; j++)
292                                 devc->logic_data[i + j] = devc->step;
293                         devc->step++;
294                 }
295                 break;
296         case PATTERN_WALKING_ONE:
297                 /* j contains the value of the highest bit */
298                 j = 1 << (devc->num_logic_channels - 1);
299                 for (i = 0; i < size; i++) {
300                         devc->logic_data[i] = devc->step;
301                         if (devc->step == 0)
302                                 devc->step = 1;
303                         else
304                                 if (devc->step == j)
305                                         devc->step = 0;
306                                 else
307                                         devc->step <<= 1;
308                 }
309                 break;
310         case PATTERN_WALKING_ZERO:
311                 /* Same as walking one, only with inverted output */
312                 /* j contains the value of the highest bit */
313                 j = 1 << (devc->num_logic_channels - 1);
314                 for (i = 0; i < size; i++) {
315                         devc->logic_data[i] = ~devc->step;
316                         if (devc->step == 0)
317                                 devc->step = 1;
318                         else
319                                 if (devc->step == j)
320                                         devc->step = 0;
321                                 else
322                                         devc->step <<= 1;
323                 }
324                 break;
325         case PATTERN_ALL_LOW:
326         case PATTERN_ALL_HIGH:
327                 /* These were set when the pattern mode was selected. */
328                 break;
329         case PATTERN_SQUID:
330                 memset(devc->logic_data, 0x00, size);
331                 col_count = ARRAY_SIZE(pattern_squid);
332                 col_height = ARRAY_SIZE(pattern_squid[0]);
333                 for (i = 0; i < size; i += devc->logic_unitsize) {
334                         sample = &devc->logic_data[i];
335                         image_col = pattern_squid[devc->step];
336                         for (j = 0; j < devc->logic_unitsize; j++) {
337                                 pat = image_col[j % col_height];
338                                 sample[j] = pat;
339                         }
340                         devc->step++;
341                         devc->step %= col_count;
342                 }
343                 break;
344         case PATTERN_GRAYCODE:
345                 for (i = 0; i < size; i += devc->logic_unitsize) {
346                         devc->step++;
347                         devc->step &= devc->all_logic_channels_mask;
348                         gray = encode_number_to_gray(devc->step);
349                         gray &= devc->all_logic_channels_mask;
350                         set_logic_data(gray, &devc->logic_data[i], devc->logic_unitsize);
351                 }
352                 break;
353         default:
354                 sr_err("Unknown pattern: %d.", devc->logic_pattern);
355                 break;
356         }
357 }
358
359 /*
360  * Fixup a memory image of generated logic data before it gets sent to
361  * the session's datafeed. Mask out content from disabled channels.
362  *
363  * TODO: Need we apply a channel map, and enforce a dense representation
364  * of the enabled channels' data?
365  */
366 static void logic_fixup_feed(struct dev_context *devc,
367                 struct sr_datafeed_logic *logic)
368 {
369         size_t fp_off;
370         uint8_t fp_mask;
371         size_t off, idx;
372         uint8_t *sample;
373
374         fp_off = devc->first_partial_logic_index;
375         fp_mask = devc->first_partial_logic_mask;
376         if (fp_off == logic->unitsize)
377                 return;
378
379         for (off = 0; off < logic->length; off += logic->unitsize) {
380                 sample = logic->data + off;
381                 sample[fp_off] &= fp_mask;
382                 for (idx = fp_off + 1; idx < logic->unitsize; idx++)
383                         sample[idx] = 0x00;
384         }
385 }
386
387 static void send_analog_packet(struct analog_gen *ag,
388                 struct sr_dev_inst *sdi, uint64_t *analog_sent,
389                 uint64_t analog_pos, uint64_t analog_todo)
390 {
391         struct sr_datafeed_packet packet;
392         struct dev_context *devc;
393         struct analog_pattern *pattern;
394         uint64_t sending_now, to_avg;
395         int ag_pattern_pos;
396         unsigned int i;
397         float amplitude, offset, value;
398         float *data;
399
400         if (!ag->ch || !ag->ch->enabled)
401                 return;
402
403         devc = sdi->priv;
404         packet.type = SR_DF_ANALOG;
405         packet.payload = &ag->packet;
406
407         pattern = devc->analog_patterns[ag->pattern];
408
409         ag->packet.meaning->channels = g_slist_append(NULL, ag->ch);
410         ag->packet.meaning->mq = ag->mq;
411         ag->packet.meaning->mqflags = ag->mq_flags;
412
413         /* Set a unit for the given quantity. */
414         if (ag->mq == SR_MQ_VOLTAGE)
415                 ag->packet.meaning->unit = SR_UNIT_VOLT;
416         else if (ag->mq == SR_MQ_CURRENT)
417                 ag->packet.meaning->unit = SR_UNIT_AMPERE;
418         else if (ag->mq == SR_MQ_RESISTANCE)
419                 ag->packet.meaning->unit = SR_UNIT_OHM;
420         else if (ag->mq == SR_MQ_CAPACITANCE)
421                 ag->packet.meaning->unit = SR_UNIT_FARAD;
422         else if (ag->mq == SR_MQ_TEMPERATURE)
423                 ag->packet.meaning->unit = SR_UNIT_CELSIUS;
424         else if (ag->mq == SR_MQ_FREQUENCY)
425                 ag->packet.meaning->unit = SR_UNIT_HERTZ;
426         else if (ag->mq == SR_MQ_DUTY_CYCLE)
427                 ag->packet.meaning->unit = SR_UNIT_PERCENTAGE;
428         else if (ag->mq == SR_MQ_CONTINUITY)
429                 ag->packet.meaning->unit = SR_UNIT_OHM;
430         else if (ag->mq == SR_MQ_PULSE_WIDTH)
431                 ag->packet.meaning->unit = SR_UNIT_PERCENTAGE;
432         else if (ag->mq == SR_MQ_CONDUCTANCE)
433                 ag->packet.meaning->unit = SR_UNIT_SIEMENS;
434         else if (ag->mq == SR_MQ_POWER)
435                 ag->packet.meaning->unit = SR_UNIT_WATT;
436         else if (ag->mq == SR_MQ_GAIN)
437                 ag->packet.meaning->unit = SR_UNIT_UNITLESS;
438         else if (ag->mq == SR_MQ_SOUND_PRESSURE_LEVEL)
439                 ag->packet.meaning->unit = SR_UNIT_DECIBEL_SPL;
440         else if (ag->mq == SR_MQ_CARBON_MONOXIDE)
441                 ag->packet.meaning->unit = SR_UNIT_CONCENTRATION;
442         else if (ag->mq == SR_MQ_RELATIVE_HUMIDITY)
443                 ag->packet.meaning->unit = SR_UNIT_HUMIDITY_293K;
444         else if (ag->mq == SR_MQ_TIME)
445                 ag->packet.meaning->unit = SR_UNIT_SECOND;
446         else if (ag->mq == SR_MQ_WIND_SPEED)
447                 ag->packet.meaning->unit = SR_UNIT_METER_SECOND;
448         else if (ag->mq == SR_MQ_PRESSURE)
449                 ag->packet.meaning->unit = SR_UNIT_HECTOPASCAL;
450         else if (ag->mq == SR_MQ_PARALLEL_INDUCTANCE)
451                 ag->packet.meaning->unit = SR_UNIT_HENRY;
452         else if (ag->mq == SR_MQ_PARALLEL_CAPACITANCE)
453                 ag->packet.meaning->unit = SR_UNIT_FARAD;
454         else if (ag->mq == SR_MQ_PARALLEL_RESISTANCE)
455                 ag->packet.meaning->unit = SR_UNIT_OHM;
456         else if (ag->mq == SR_MQ_SERIES_INDUCTANCE)
457                 ag->packet.meaning->unit = SR_UNIT_HENRY;
458         else if (ag->mq == SR_MQ_SERIES_CAPACITANCE)
459                 ag->packet.meaning->unit = SR_UNIT_FARAD;
460         else if (ag->mq == SR_MQ_SERIES_RESISTANCE)
461                 ag->packet.meaning->unit = SR_UNIT_OHM;
462         else if (ag->mq == SR_MQ_DISSIPATION_FACTOR)
463                 ag->packet.meaning->unit = SR_UNIT_UNITLESS;
464         else if (ag->mq == SR_MQ_QUALITY_FACTOR)
465                 ag->packet.meaning->unit = SR_UNIT_UNITLESS;
466         else if (ag->mq == SR_MQ_PHASE_ANGLE)
467                 ag->packet.meaning->unit = SR_UNIT_DEGREE;
468         else if (ag->mq == SR_MQ_DIFFERENCE)
469                 ag->packet.meaning->unit = SR_UNIT_UNITLESS;
470         else if (ag->mq == SR_MQ_COUNT)
471                 ag->packet.meaning->unit = SR_UNIT_PIECE;
472         else if (ag->mq == SR_MQ_POWER_FACTOR)
473                 ag->packet.meaning->unit = SR_UNIT_UNITLESS;
474         else if (ag->mq == SR_MQ_APPARENT_POWER)
475                 ag->packet.meaning->unit = SR_UNIT_VOLT_AMPERE;
476         else if (ag->mq == SR_MQ_MASS)
477                 ag->packet.meaning->unit = SR_UNIT_GRAM;
478         else if (ag->mq == SR_MQ_HARMONIC_RATIO)
479                 ag->packet.meaning->unit = SR_UNIT_UNITLESS;
480         else
481                 ag->packet.meaning->unit = SR_UNIT_UNITLESS;
482
483         if (!devc->avg) {
484                 ag_pattern_pos = analog_pos % pattern->num_samples;
485                 sending_now = MIN(analog_todo, pattern->num_samples - ag_pattern_pos);
486                 if (ag->amplitude != DEFAULT_ANALOG_AMPLITUDE ||
487                         ag->offset != DEFAULT_ANALOG_OFFSET) {
488
489                         /* Amplitude or offset changed, modify each sample. */
490                         amplitude = ag->amplitude / DEFAULT_ANALOG_AMPLITUDE;
491                         offset = ag->offset - DEFAULT_ANALOG_OFFSET;
492                         data = ag->packet.data;
493                         for (i = 0; i < sending_now; i++)
494                                 data[i] = pattern->data[ag_pattern_pos + i] * amplitude + offset;
495                 } else {
496                         /* Amplitude and offset unchanged, use the fast way. */
497                         ag->packet.data = pattern->data + ag_pattern_pos;
498                 }
499                 ag->packet.num_samples = sending_now;
500                 sr_session_send(sdi, &packet);
501
502                 /* Whichever channel group gets there first. */
503                 *analog_sent = MAX(*analog_sent, sending_now);
504         } else {
505                 ag_pattern_pos = analog_pos % pattern->num_samples;
506                 to_avg = MIN(analog_todo, pattern->num_samples - ag_pattern_pos);
507                 amplitude = ag->amplitude / DEFAULT_ANALOG_AMPLITUDE;
508                 offset = ag->offset - DEFAULT_ANALOG_OFFSET;
509
510                 for (i = 0; i < to_avg; i++) {
511                         value = *(pattern->data + ag_pattern_pos + i) * amplitude + offset;
512                         ag->avg_val = (ag->avg_val + value) / 2;
513                         ag->num_avgs++;
514                         /* Time to send averaged data? */
515                         if ((devc->avg_samples > 0) && (ag->num_avgs >= devc->avg_samples))
516                                 goto do_send;
517                 }
518
519                 if (devc->avg_samples == 0) {
520                         /*
521                          * We're averaging all the samples, so wait with
522                          * sending until the very end.
523                          */
524                         *analog_sent = ag->num_avgs;
525                         return;
526                 }
527
528 do_send:
529                 ag->packet.data = &ag->avg_val;
530                 ag->packet.num_samples = 1;
531
532                 sr_session_send(sdi, &packet);
533                 *analog_sent = ag->num_avgs;
534
535                 ag->num_avgs = 0;
536                 ag->avg_val = 0.0f;
537         }
538 }
539
540 /* Callback handling data */
541 SR_PRIV int demo_prepare_data(int fd, int revents, void *cb_data)
542 {
543         struct sr_dev_inst *sdi;
544         struct dev_context *devc;
545         struct sr_datafeed_packet packet;
546         struct sr_datafeed_logic logic;
547         struct analog_gen *ag;
548         GHashTableIter iter;
549         void *value;
550         uint64_t samples_todo, logic_done, analog_done, analog_sent, sending_now;
551         int64_t elapsed_us, limit_us, todo_us;
552         int64_t trigger_offset;
553         int pre_trigger_samples;
554
555         (void)fd;
556         (void)revents;
557
558         sdi = cb_data;
559         devc = sdi->priv;
560
561         /* Just in case. */
562         if (devc->cur_samplerate <= 0
563                         || (devc->num_logic_channels <= 0
564                         && devc->num_analog_channels <= 0)) {
565                 sr_dev_acquisition_stop(sdi);
566                 return G_SOURCE_CONTINUE;
567         }
568
569         /* What time span should we send samples for? */
570         elapsed_us = g_get_monotonic_time() - devc->start_us;
571         limit_us = 1000 * devc->limit_msec;
572         if (limit_us > 0 && limit_us < elapsed_us)
573                 todo_us = MAX(0, limit_us - devc->spent_us);
574         else
575                 todo_us = MAX(0, elapsed_us - devc->spent_us);
576
577         /* How many samples are outstanding since the last round? */
578         samples_todo = (todo_us * devc->cur_samplerate + G_USEC_PER_SEC - 1)
579                         / G_USEC_PER_SEC;
580
581         if (devc->limit_samples > 0) {
582                 if (devc->limit_samples < devc->sent_samples)
583                         samples_todo = 0;
584                 else if (devc->limit_samples - devc->sent_samples < samples_todo)
585                         samples_todo = devc->limit_samples - devc->sent_samples;
586         }
587
588         if (samples_todo == 0)
589                 return G_SOURCE_CONTINUE;
590
591         if (devc->limit_frames) {
592                 /* Never send more samples than a frame can fit... */
593                 samples_todo = MIN(samples_todo, SAMPLES_PER_FRAME);
594                 /* ...or than we need to finish the current frame. */
595                 samples_todo = MIN(samples_todo,
596                         SAMPLES_PER_FRAME - devc->sent_frame_samples);
597         }
598
599         /* Calculate the actual time covered by this run back from the sample
600          * count, rounded towards zero. This avoids getting stuck on a too-low
601          * time delta with no samples being sent due to round-off.
602          */
603         todo_us = samples_todo * G_USEC_PER_SEC / devc->cur_samplerate;
604
605         logic_done = devc->num_logic_channels > 0 ? 0 : samples_todo;
606         if (!devc->enabled_logic_channels)
607                 logic_done = samples_todo;
608
609         analog_done = devc->num_analog_channels > 0 ? 0 : samples_todo;
610         if (!devc->enabled_analog_channels)
611                 analog_done = samples_todo;
612
613         while (logic_done < samples_todo || analog_done < samples_todo) {
614                 /* Logic */
615                 if (logic_done < samples_todo) {
616                         sending_now = MIN(samples_todo - logic_done,
617                                         LOGIC_BUFSIZE / devc->logic_unitsize);
618                         logic_generator(sdi, sending_now * devc->logic_unitsize);
619                         /* Check for trigger and send pre-trigger data if needed */
620                         if (devc->stl && (!devc->trigger_fired)) {
621                                 trigger_offset = soft_trigger_logic_check(devc->stl,
622                                                 devc->logic_data, sending_now * devc->logic_unitsize,
623                                                 &pre_trigger_samples);
624                                 if (trigger_offset > -1) {
625                                         devc->trigger_fired = TRUE;
626                                         logic_done = pre_trigger_samples;
627                                 }
628                         } else
629                                 trigger_offset = 0;
630
631                         /* Send logic samples if needed */
632                         packet.type = SR_DF_LOGIC;
633                         packet.payload = &logic;
634                         logic.unitsize = devc->logic_unitsize;
635
636                         if (devc->stl) {
637                                 if (devc->trigger_fired && (trigger_offset < (int)sending_now)) {
638                                         /* Send after-trigger data */
639                                         logic.length = (sending_now - trigger_offset) * devc->logic_unitsize;
640                                         logic.data = devc->logic_data + trigger_offset * devc->logic_unitsize;
641                                         logic_fixup_feed(devc, &logic);
642                                         sr_session_send(sdi, &packet);
643                                         logic_done += sending_now - trigger_offset;
644                                         /* End acquisition */
645                                         sr_dbg("Triggered, stopping acquisition.");
646                                         sr_dev_acquisition_stop(sdi);
647                                         break;
648                                 } else {
649                                         /* Send nothing */
650                                         logic_done += sending_now;
651                                 }
652                         } else if (!devc->stl) {
653                                 /* No trigger defined, send logic samples */
654                                 logic.length = sending_now * devc->logic_unitsize;
655                                 logic.data = devc->logic_data;
656                                 logic_fixup_feed(devc, &logic);
657                                 sr_session_send(sdi, &packet);
658                                 logic_done += sending_now;
659                         }
660                 }
661
662                 /* Analog, one channel at a time */
663                 if (analog_done < samples_todo) {
664                         analog_sent = 0;
665
666                         g_hash_table_iter_init(&iter, devc->ch_ag);
667                         while (g_hash_table_iter_next(&iter, NULL, &value)) {
668                                 send_analog_packet(value, sdi, &analog_sent,
669                                                 devc->sent_samples + analog_done,
670                                                 samples_todo - analog_done);
671                         }
672                         analog_done += analog_sent;
673                 }
674         }
675
676         uint64_t min = MIN(logic_done, analog_done);
677         devc->sent_samples += min;
678         devc->sent_frame_samples += min;
679         devc->spent_us += todo_us;
680
681         if (devc->limit_frames && devc->sent_frame_samples >= SAMPLES_PER_FRAME) {
682                 std_session_send_frame_end(sdi);
683                 devc->sent_frame_samples = 0;
684                 devc->limit_frames--;
685                 if (!devc->limit_frames) {
686                         sr_dbg("Requested number of frames reached.");
687                         sr_dev_acquisition_stop(sdi);
688                 }
689         }
690
691         if ((devc->limit_samples > 0 && devc->sent_samples >= devc->limit_samples)
692                         || (limit_us > 0 && devc->spent_us >= limit_us)) {
693
694                 /* If we're averaging everything - now is the time to send data */
695                 if (devc->avg && devc->avg_samples == 0) {
696                         g_hash_table_iter_init(&iter, devc->ch_ag);
697                         while (g_hash_table_iter_next(&iter, NULL, &value)) {
698                                 ag = value;
699                                 packet.type = SR_DF_ANALOG;
700                                 packet.payload = &ag->packet;
701                                 ag->packet.data = &ag->avg_val;
702                                 ag->packet.num_samples = 1;
703                                 sr_session_send(sdi, &packet);
704                         }
705                 }
706                 sr_dbg("Requested number of samples reached.");
707                 sr_dev_acquisition_stop(sdi);
708         } else if (devc->limit_frames) {
709                 if (devc->sent_frame_samples == 0)
710                         std_session_send_frame_begin(sdi);
711         }
712
713         return G_SOURCE_CONTINUE;
714 }