]> sigrok.org Git - libsigrok.git/blob - src/hardware/demo/protocol.c
42348a374f224d234a1bf4d6612bae45a53b43f6
[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         /* FIXME we actually need only one period. A ringbuffer would be
191          * useful here. */
192         /* Make sure the number of samples we put out is an integer
193          * multiple of our period size */
194
195         /* PATTERN_SQUARE */
196         sr_dbg("Generating %s pattern.", analog_pattern_str[PATTERN_SQUARE]);
197         pattern = g_malloc(sizeof(struct analog_pattern));
198         value = amplitude;
199         last_end = 0;
200         for (i = 0; i < num_samples; i++) {
201                 if (i % 5 == 0)
202                         value = -value;
203                 if (i % 10 == 0)
204                         last_end = i;
205                 pattern->data[i] = value + offset;
206         }
207         pattern->num_samples = last_end;
208         devc->analog_patterns[PATTERN_SQUARE] = pattern;
209
210         /*  Readjusting num_samples for all other patterns */
211         while (num_samples % ANALOG_SAMPLES_PER_PERIOD != 0)
212                 num_samples--;
213
214         /* PATTERN_SINE: */
215         sr_dbg("Generating %s pattern.", analog_pattern_str[PATTERN_SINE]);
216         pattern = g_malloc(sizeof(struct analog_pattern));
217         for (i = 0; i < num_samples; i++) {
218                 t = (double) i / (double) devc->cur_samplerate;
219                 pattern->data[i] = sin(2 * G_PI * frequency * t) * amplitude + offset;
220         }
221         pattern->num_samples = last_end;
222         devc->analog_patterns[PATTERN_SINE] = pattern;
223
224         /* PATTERN_TRIANGLE: */
225         sr_dbg("Generating %s pattern.", analog_pattern_str[PATTERN_TRIANGLE]);
226         pattern = g_malloc(sizeof(struct analog_pattern));
227         for (i = 0; i < num_samples; i++) {
228                 t = (double) i / (double) devc->cur_samplerate;
229                 pattern->data[i] = (2 / G_PI) * asin(sin(2 * G_PI * frequency * t)) *
230                         amplitude + offset;
231         }
232         pattern->num_samples = last_end;
233         devc->analog_patterns[PATTERN_TRIANGLE] = pattern;
234
235         /* PATTERN_SAWTOOTH: */
236         sr_dbg("Generating %s pattern.", analog_pattern_str[PATTERN_SAWTOOTH]);
237         pattern = g_malloc(sizeof(struct analog_pattern));
238         for (i = 0; i < num_samples; i++) {
239                 t = (double) i / (double) devc->cur_samplerate;
240                 pattern->data[i] = 2 * ((t * frequency) - floor(0.5f + t * frequency)) *
241                         amplitude + offset;
242         }
243         pattern->num_samples = last_end;
244         devc->analog_patterns[PATTERN_SAWTOOTH] = pattern;
245 }
246
247 static uint64_t encode_number_to_gray(uint64_t nr)
248 {
249         return nr ^ (nr >> 1);
250 }
251
252 static void set_logic_data(uint64_t bits, uint8_t *data, size_t len)
253 {
254         while (len--) {
255                 *data++ = bits & 0xff;
256                 bits >>= 8;
257         }
258 }
259
260 static void logic_generator(struct sr_dev_inst *sdi, uint64_t size)
261 {
262         struct dev_context *devc;
263         uint64_t i, j;
264         uint8_t pat;
265         uint8_t *sample;
266         const uint8_t *image_col;
267         size_t col_count, col_height;
268         uint64_t gray;
269
270         devc = sdi->priv;
271
272         switch (devc->logic_pattern) {
273         case PATTERN_SIGROK:
274                 memset(devc->logic_data, 0x00, size);
275                 for (i = 0; i < size; i += devc->logic_unitsize) {
276                         for (j = 0; j < devc->logic_unitsize; j++) {
277                                 pat = pattern_sigrok[(devc->step + j) % sizeof(pattern_sigrok)] >> 1;
278                                 devc->logic_data[i + j] = ~pat;
279                         }
280                         devc->step++;
281                 }
282                 break;
283         case PATTERN_RANDOM:
284                 for (i = 0; i < size; i++)
285                         devc->logic_data[i] = (uint8_t)(rand() & 0xff);
286                 break;
287         case PATTERN_INC:
288                 for (i = 0; i < size; i++) {
289                         for (j = 0; j < devc->logic_unitsize; j++)
290                                 devc->logic_data[i + j] = devc->step;
291                         devc->step++;
292                 }
293                 break;
294         case PATTERN_WALKING_ONE:
295                 /* j contains the value of the highest bit */
296                 j = 1 << (devc->num_logic_channels - 1);
297                 for (i = 0; i < size; i++) {
298                         devc->logic_data[i] = devc->step;
299                         if (devc->step == 0)
300                                 devc->step = 1;
301                         else
302                                 if (devc->step == j)
303                                         devc->step = 0;
304                                 else
305                                         devc->step <<= 1;
306                 }
307                 break;
308         case PATTERN_WALKING_ZERO:
309                 /* Same as walking one, only with inverted output */
310                 /* j contains the value of the highest bit */
311                 j = 1 << (devc->num_logic_channels - 1);
312                 for (i = 0; i < size; i++) {
313                         devc->logic_data[i] = ~devc->step;
314                         if (devc->step == 0)
315                                 devc->step = 1;
316                         else
317                                 if (devc->step == j)
318                                         devc->step = 0;
319                                 else
320                                         devc->step <<= 1;
321                 }
322                 break;
323         case PATTERN_ALL_LOW:
324         case PATTERN_ALL_HIGH:
325                 /* These were set when the pattern mode was selected. */
326                 break;
327         case PATTERN_SQUID:
328                 memset(devc->logic_data, 0x00, size);
329                 col_count = ARRAY_SIZE(pattern_squid);
330                 col_height = ARRAY_SIZE(pattern_squid[0]);
331                 for (i = 0; i < size; i += devc->logic_unitsize) {
332                         sample = &devc->logic_data[i];
333                         image_col = pattern_squid[devc->step];
334                         for (j = 0; j < devc->logic_unitsize; j++) {
335                                 pat = image_col[j % col_height];
336                                 sample[j] = pat;
337                         }
338                         devc->step++;
339                         devc->step %= col_count;
340                 }
341                 break;
342         case PATTERN_GRAYCODE:
343                 for (i = 0; i < size; i += devc->logic_unitsize) {
344                         devc->step++;
345                         devc->step &= devc->all_logic_channels_mask;
346                         gray = encode_number_to_gray(devc->step);
347                         gray &= devc->all_logic_channels_mask;
348                         set_logic_data(gray, &devc->logic_data[i], devc->logic_unitsize);
349                 }
350                 break;
351         default:
352                 sr_err("Unknown pattern: %d.", devc->logic_pattern);
353                 break;
354         }
355 }
356
357 /*
358  * Fixup a memory image of generated logic data before it gets sent to
359  * the session's datafeed. Mask out content from disabled channels.
360  *
361  * TODO: Need we apply a channel map, and enforce a dense representation
362  * of the enabled channels' data?
363  */
364 static void logic_fixup_feed(struct dev_context *devc,
365                 struct sr_datafeed_logic *logic)
366 {
367         size_t fp_off;
368         uint8_t fp_mask;
369         size_t off, idx;
370         uint8_t *sample;
371
372         fp_off = devc->first_partial_logic_index;
373         fp_mask = devc->first_partial_logic_mask;
374         if (fp_off == logic->unitsize)
375                 return;
376
377         for (off = 0; off < logic->length; off += logic->unitsize) {
378                 sample = logic->data + off;
379                 sample[fp_off] &= fp_mask;
380                 for (idx = fp_off + 1; idx < logic->unitsize; idx++)
381                         sample[idx] = 0x00;
382         }
383 }
384
385 static void send_analog_packet(struct analog_gen *ag,
386                 struct sr_dev_inst *sdi, uint64_t *analog_sent,
387                 uint64_t analog_pos, uint64_t analog_todo)
388 {
389         struct sr_datafeed_packet packet;
390         struct dev_context *devc;
391         struct analog_pattern *pattern;
392         uint64_t sending_now, to_avg;
393         int ag_pattern_pos;
394         unsigned int i;
395         float amplitude, offset, value;
396         float *data;
397
398         if (!ag->ch || !ag->ch->enabled)
399                 return;
400
401         devc = sdi->priv;
402         packet.type = SR_DF_ANALOG;
403         packet.payload = &ag->packet;
404
405         pattern = devc->analog_patterns[ag->pattern];
406
407         ag->packet.meaning->channels = g_slist_append(NULL, ag->ch);
408         ag->packet.meaning->mq = ag->mq;
409         ag->packet.meaning->mqflags = ag->mq_flags;
410
411         /* Set a unit for the given quantity */
412         if (ag->mq == SR_MQ_VOLTAGE)
413                 ag->packet.meaning->unit = SR_UNIT_VOLT;
414         else if (ag->mq == SR_MQ_CURRENT)
415                 ag->packet.meaning->unit = SR_UNIT_AMPERE;
416         else if (ag->mq == SR_MQ_RESISTANCE)
417                 ag->packet.meaning->unit = SR_UNIT_OHM;
418         else if (ag->mq == SR_MQ_CAPACITANCE)
419                 ag->packet.meaning->unit = SR_UNIT_FARAD;
420         else if (ag->mq == SR_MQ_TEMPERATURE)
421                 ag->packet.meaning->unit = SR_UNIT_CELSIUS;
422         else if (ag->mq == SR_MQ_FREQUENCY)
423                 ag->packet.meaning->unit = SR_UNIT_HERTZ;
424         else if (ag->mq == SR_MQ_DUTY_CYCLE)
425                 ag->packet.meaning->unit = SR_UNIT_PERCENTAGE;
426         else if (ag->mq == SR_MQ_CONTINUITY)
427                 ag->packet.meaning->unit = SR_UNIT_OHM;
428         else if (ag->mq == SR_MQ_PULSE_WIDTH)
429                 ag->packet.meaning->unit = SR_UNIT_PERCENTAGE;
430         else if (ag->mq == SR_MQ_CONDUCTANCE)
431                 ag->packet.meaning->unit = SR_UNIT_SIEMENS;
432         else if (ag->mq == SR_MQ_POWER)
433                 ag->packet.meaning->unit = SR_UNIT_WATT;
434         else if (ag->mq == SR_MQ_GAIN)
435                 ag->packet.meaning->unit = SR_UNIT_UNITLESS;
436         else if (ag->mq == SR_MQ_SOUND_PRESSURE_LEVEL)
437                 ag->packet.meaning->unit = SR_UNIT_DECIBEL_SPL;
438         else if (ag->mq == SR_MQ_CARBON_MONOXIDE)
439                 ag->packet.meaning->unit = SR_UNIT_CONCENTRATION;
440         else if (ag->mq == SR_MQ_RELATIVE_HUMIDITY)
441                 ag->packet.meaning->unit = SR_UNIT_HUMIDITY_293K;
442         else if (ag->mq == SR_MQ_TIME)
443                 ag->packet.meaning->unit = SR_UNIT_SECOND;
444         else if (ag->mq == SR_MQ_WIND_SPEED)
445                 ag->packet.meaning->unit = SR_UNIT_METER_SECOND;
446         else if (ag->mq == SR_MQ_PRESSURE)
447                 ag->packet.meaning->unit = SR_UNIT_HECTOPASCAL;
448         else if (ag->mq == SR_MQ_PARALLEL_INDUCTANCE)
449                 ag->packet.meaning->unit = SR_UNIT_HENRY;
450         else if (ag->mq == SR_MQ_PARALLEL_CAPACITANCE)
451                 ag->packet.meaning->unit = SR_UNIT_FARAD;
452         else if (ag->mq == SR_MQ_PARALLEL_RESISTANCE)
453                 ag->packet.meaning->unit = SR_UNIT_OHM;
454         else if (ag->mq == SR_MQ_SERIES_INDUCTANCE)
455                 ag->packet.meaning->unit = SR_UNIT_HENRY;
456         else if (ag->mq == SR_MQ_SERIES_CAPACITANCE)
457                 ag->packet.meaning->unit = SR_UNIT_FARAD;
458         else if (ag->mq == SR_MQ_SERIES_RESISTANCE)
459                 ag->packet.meaning->unit = SR_UNIT_OHM;
460         else if (ag->mq == SR_MQ_DISSIPATION_FACTOR)
461                 ag->packet.meaning->unit = SR_UNIT_UNITLESS;
462         else if (ag->mq == SR_MQ_QUALITY_FACTOR)
463                 ag->packet.meaning->unit = SR_UNIT_UNITLESS;
464         else if (ag->mq == SR_MQ_PHASE_ANGLE)
465                 ag->packet.meaning->unit = SR_UNIT_DEGREE;
466         else if (ag->mq == SR_MQ_DIFFERENCE)
467                 ag->packet.meaning->unit = SR_UNIT_UNITLESS;
468         else if (ag->mq == SR_MQ_COUNT)
469                 ag->packet.meaning->unit = SR_UNIT_PIECE;
470         else if (ag->mq == SR_MQ_POWER_FACTOR)
471                 ag->packet.meaning->unit = SR_UNIT_UNITLESS;
472         else if (ag->mq == SR_MQ_APPARENT_POWER)
473                 ag->packet.meaning->unit = SR_UNIT_VOLT_AMPERE;
474         else if (ag->mq == SR_MQ_MASS)
475                 ag->packet.meaning->unit = SR_UNIT_GRAM;
476         else if (ag->mq == SR_MQ_HARMONIC_RATIO)
477                 ag->packet.meaning->unit = SR_UNIT_UNITLESS;
478         else
479                 ag->packet.meaning->unit = SR_UNIT_UNITLESS;
480
481         if (!devc->avg) {
482                 ag_pattern_pos = analog_pos % pattern->num_samples;
483                 sending_now = MIN(analog_todo, pattern->num_samples - ag_pattern_pos);
484                 if (ag->amplitude != DEFAULT_ANALOG_AMPLITUDE ||
485                         ag->offset != DEFAULT_ANALOG_OFFSET) {
486
487                         /* Amplitude or offset changed, modify each sample */
488                         amplitude = ag->amplitude / DEFAULT_ANALOG_AMPLITUDE;
489                         offset = ag->offset - DEFAULT_ANALOG_OFFSET;
490                         data = ag->packet.data;
491                         for (i = 0; i < sending_now; i++) {
492                                 data[i] = pattern->data[ag_pattern_pos + i] * amplitude + offset;
493                         }
494                 } else {
495                         /* Amplitude and offset not changed, use the fast way */
496                         ag->packet.data = pattern->data + ag_pattern_pos;
497                 }
498                 ag->packet.num_samples = sending_now;
499                 sr_session_send(sdi, &packet);
500
501                 /* Whichever channel group gets there first. */
502                 *analog_sent = MAX(*analog_sent, sending_now);
503         } else {
504                 ag_pattern_pos = analog_pos % pattern->num_samples;
505                 to_avg = MIN(analog_todo, pattern->num_samples - ag_pattern_pos);
506                 amplitude = ag->amplitude / DEFAULT_ANALOG_AMPLITUDE;
507                 offset = ag->offset - DEFAULT_ANALOG_OFFSET;
508
509                 for (i = 0; i < to_avg; i++) {
510                         value = *(pattern->data + ag_pattern_pos + i) * amplitude + offset;
511                         ag->avg_val = (ag->avg_val + value) / 2;
512                         ag->num_avgs++;
513                         /* Time to send averaged data? */
514                         if ((devc->avg_samples > 0) && (ag->num_avgs >= devc->avg_samples))
515                                 goto do_send;
516                 }
517
518                 if (devc->avg_samples == 0) {
519                         /*
520                          * We're averaging all the samples, so wait with
521                          * sending until the very end.
522                          */
523                         *analog_sent = ag->num_avgs;
524                         return;
525                 }
526
527 do_send:
528                 ag->packet.data = &ag->avg_val;
529                 ag->packet.num_samples = 1;
530
531                 sr_session_send(sdi, &packet);
532                 *analog_sent = ag->num_avgs;
533
534                 ag->num_avgs = 0;
535                 ag->avg_val = 0.0f;
536         }
537 }
538
539 /* Callback handling data */
540 SR_PRIV int demo_prepare_data(int fd, int revents, void *cb_data)
541 {
542         struct sr_dev_inst *sdi;
543         struct dev_context *devc;
544         struct sr_datafeed_packet packet;
545         struct sr_datafeed_logic logic;
546         struct analog_gen *ag;
547         GHashTableIter iter;
548         void *value;
549         uint64_t samples_todo, logic_done, analog_done, analog_sent, sending_now;
550         int64_t elapsed_us, limit_us, todo_us;
551         int64_t trigger_offset;
552         int pre_trigger_samples;
553
554         (void)fd;
555         (void)revents;
556
557         sdi = cb_data;
558         devc = sdi->priv;
559
560         /* Just in case. */
561         if (devc->cur_samplerate <= 0
562                         || (devc->num_logic_channels <= 0
563                         && devc->num_analog_channels <= 0)) {
564                 sr_dev_acquisition_stop(sdi);
565                 return G_SOURCE_CONTINUE;
566         }
567
568         /* What time span should we send samples for? */
569         elapsed_us = g_get_monotonic_time() - devc->start_us;
570         limit_us = 1000 * devc->limit_msec;
571         if (limit_us > 0 && limit_us < elapsed_us)
572                 todo_us = MAX(0, limit_us - devc->spent_us);
573         else
574                 todo_us = MAX(0, elapsed_us - devc->spent_us);
575
576         /* How many samples are outstanding since the last round? */
577         samples_todo = (todo_us * devc->cur_samplerate + G_USEC_PER_SEC - 1)
578                         / G_USEC_PER_SEC;
579
580         if (devc->limit_samples > 0) {
581                 if (devc->limit_samples < devc->sent_samples)
582                         samples_todo = 0;
583                 else if (devc->limit_samples - devc->sent_samples < samples_todo)
584                         samples_todo = devc->limit_samples - devc->sent_samples;
585         }
586
587         if (samples_todo == 0)
588                 return G_SOURCE_CONTINUE;
589
590         if (devc->limit_frames) {
591                 /* Never send more samples than a frame can fit... */
592                 samples_todo = MIN(samples_todo, SAMPLES_PER_FRAME);
593                 /* ...or than we need to finish the current frame. */
594                 samples_todo = MIN(samples_todo,
595                         SAMPLES_PER_FRAME - devc->sent_frame_samples);
596         }
597
598         /* Calculate the actual time covered by this run back from the sample
599          * count, rounded towards zero. This avoids getting stuck on a too-low
600          * time delta with no samples being sent due to round-off.
601          */
602         todo_us = samples_todo * G_USEC_PER_SEC / devc->cur_samplerate;
603
604         logic_done = devc->num_logic_channels > 0 ? 0 : samples_todo;
605         if (!devc->enabled_logic_channels)
606                 logic_done = samples_todo;
607
608         analog_done = devc->num_analog_channels > 0 ? 0 : samples_todo;
609         if (!devc->enabled_analog_channels)
610                 analog_done = samples_todo;
611
612         while (logic_done < samples_todo || analog_done < samples_todo) {
613                 /* Logic */
614                 if (logic_done < samples_todo) {
615                         sending_now = MIN(samples_todo - logic_done,
616                                         LOGIC_BUFSIZE / devc->logic_unitsize);
617                         logic_generator(sdi, sending_now * devc->logic_unitsize);
618                         /* Check for trigger and send pre-trigger data if needed */
619                         if (devc->stl && (!devc->trigger_fired)) {
620                                 trigger_offset = soft_trigger_logic_check(devc->stl,
621                                                 devc->logic_data, sending_now * devc->logic_unitsize,
622                                                 &pre_trigger_samples);
623                                 if (trigger_offset > -1) {
624                                         devc->trigger_fired = TRUE;
625                                         logic_done = pre_trigger_samples;
626                                 }
627                         } else
628                                 trigger_offset = 0;
629
630                         /* Send logic samples if needed */
631                         packet.type = SR_DF_LOGIC;
632                         packet.payload = &logic;
633                         logic.unitsize = devc->logic_unitsize;
634
635                         if (devc->stl) {
636                                 if (devc->trigger_fired && (trigger_offset < (int)sending_now)) {
637                                         /* Send after-trigger data */
638                                         logic.length = (sending_now - trigger_offset) * devc->logic_unitsize;
639                                         logic.data = devc->logic_data + trigger_offset * devc->logic_unitsize;
640                                         logic_fixup_feed(devc, &logic);
641                                         sr_session_send(sdi, &packet);
642                                         logic_done += sending_now - trigger_offset;
643                                         /* End acquisition */
644                                         sr_dbg("Triggered, stopping acquisition.");
645                                         sr_dev_acquisition_stop(sdi);
646                                         break;
647                                 } else {
648                                         /* Send nothing */
649                                         logic_done += sending_now;
650                                 }
651                         } else if (!devc->stl) {
652                                 /* No trigger defined, send logic samples */
653                                 logic.length = sending_now * devc->logic_unitsize;
654                                 logic.data = devc->logic_data;
655                                 logic_fixup_feed(devc, &logic);
656                                 sr_session_send(sdi, &packet);
657                                 logic_done += sending_now;
658                         }
659                 }
660
661                 /* Analog, one channel at a time */
662                 if (analog_done < samples_todo) {
663                         analog_sent = 0;
664
665                         g_hash_table_iter_init(&iter, devc->ch_ag);
666                         while (g_hash_table_iter_next(&iter, NULL, &value)) {
667                                 send_analog_packet(value, sdi, &analog_sent,
668                                                 devc->sent_samples + analog_done,
669                                                 samples_todo - analog_done);
670                         }
671                         analog_done += analog_sent;
672                 }
673         }
674
675         uint64_t min = MIN(logic_done, analog_done);
676         devc->sent_samples += min;
677         devc->sent_frame_samples += min;
678         devc->spent_us += todo_us;
679
680         if (devc->limit_frames && devc->sent_frame_samples >= SAMPLES_PER_FRAME) {
681                 std_session_send_frame_end(sdi);
682                 devc->sent_frame_samples = 0;
683                 devc->limit_frames--;
684                 if (!devc->limit_frames) {
685                         sr_dbg("Requested number of frames reached.");
686                         sr_dev_acquisition_stop(sdi);
687                 }
688         }
689
690         if ((devc->limit_samples > 0 && devc->sent_samples >= devc->limit_samples)
691                         || (limit_us > 0 && devc->spent_us >= limit_us)) {
692
693                 /* If we're averaging everything - now is the time to send data */
694                 if (devc->avg && devc->avg_samples == 0) {
695                         g_hash_table_iter_init(&iter, devc->ch_ag);
696                         while (g_hash_table_iter_next(&iter, NULL, &value)) {
697                                 ag = value;
698                                 packet.type = SR_DF_ANALOG;
699                                 packet.payload = &ag->packet;
700                                 ag->packet.data = &ag->avg_val;
701                                 ag->packet.num_samples = 1;
702                                 sr_session_send(sdi, &packet);
703                         }
704                 }
705                 sr_dbg("Requested number of samples reached.");
706                 sr_dev_acquisition_stop(sdi);
707         } else if (devc->limit_frames) {
708                 if (devc->sent_frame_samples == 0)
709                         std_session_send_frame_begin(sdi);
710         }
711
712         return G_SOURCE_CONTINUE;
713 }