]> sigrok.org Git - libsigrok.git/blame - src/input/feed_queue.c
output/csv: use intermediate time_t var, silence compiler warning
[libsigrok.git] / src / input / feed_queue.c
CommitLineData
47a102f9
GS
1/*
2 * This file is part of the libsigrok project.
3 *
4 * Copyright (C) 2020 Gerhard Sittig <gerhard.sittig@gmx.net>
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 <libsigrok/libsigrok.h>
21#include "libsigrok-internal.h"
22#include <string.h>
23
24struct feed_queue_logic {
57140e5a 25 const struct sr_dev_inst *sdi;
47a102f9
GS
26 size_t unit_size;
27 size_t alloc_count;
28 size_t fill_count;
29 uint8_t *data_bytes;
30 struct sr_datafeed_packet packet;
31 struct sr_datafeed_logic logic;
32};
33
57140e5a
GS
34SR_API struct feed_queue_logic *feed_queue_logic_alloc(
35 const struct sr_dev_inst *sdi,
47a102f9
GS
36 size_t sample_count, size_t unit_size)
37{
38 struct feed_queue_logic *q;
39
40 q = g_malloc0(sizeof(*q));
41 q->sdi = sdi;
42 q->unit_size = unit_size;
43 q->alloc_count = sample_count;
44 q->data_bytes = g_try_malloc(q->alloc_count * q->unit_size);
45 if (!q->data_bytes) {
46 g_free(q);
47 return NULL;
48 }
49
50 memset(&q->packet, 0, sizeof(q->packet));
51 memset(&q->logic, 0, sizeof(q->logic));
52 q->packet.type = SR_DF_LOGIC;
53 q->packet.payload = &q->logic;
54 q->logic.unitsize = q->unit_size;
55 q->logic.data = q->data_bytes;
56
57 return q;
58}
59
f40d8479
GS
60SR_API int feed_queue_logic_submit_one(struct feed_queue_logic *q,
61 const uint8_t *data, size_t repeat_count)
47a102f9
GS
62{
63 uint8_t *wrptr;
64 int ret;
65
66 wrptr = &q->data_bytes[q->fill_count * q->unit_size];
f40d8479 67 while (repeat_count--) {
47a102f9
GS
68 memcpy(wrptr, data, q->unit_size);
69 wrptr += q->unit_size;
70 q->fill_count++;
71 if (q->fill_count == q->alloc_count) {
72 ret = feed_queue_logic_flush(q);
73 if (ret != SR_OK)
74 return ret;
75 wrptr = &q->data_bytes[0];
76 }
77 }
78
79 return SR_OK;
80}
81
f70db77a
GS
82SR_API int feed_queue_logic_submit_many(struct feed_queue_logic *q,
83 const uint8_t *data, size_t samples_count)
84{
85 uint8_t *wrptr;
86 size_t space, copy_count;
87 int ret;
88
89 wrptr = &q->data_bytes[q->fill_count * q->unit_size];
90 while (samples_count) {
91 space = q->alloc_count - q->fill_count;
92 copy_count = samples_count;
93 if (copy_count > space)
94 copy_count = space;
95 memcpy(wrptr, data, copy_count * q->unit_size);
96 data += copy_count * q->unit_size;
97 samples_count -= copy_count;
98 wrptr += copy_count * q->unit_size;
99 q->fill_count += copy_count;
100 if (q->fill_count == q->alloc_count) {
101 ret = feed_queue_logic_flush(q);
102 if (ret != SR_OK)
103 return ret;
104 wrptr = &q->data_bytes[0];
105 }
106 }
107
108 return SR_OK;
109}
110
47a102f9
GS
111SR_API int feed_queue_logic_flush(struct feed_queue_logic *q)
112{
113 int ret;
114
115 if (!q->fill_count)
116 return SR_OK;
117
118 q->logic.length = q->fill_count * q->unit_size;
119 ret = sr_session_send(q->sdi, &q->packet);
120 if (ret != SR_OK)
121 return ret;
122 q->fill_count = 0;
123
124 return SR_OK;
125}
126
f478c3e6
GS
127SR_API int feed_queue_logic_send_trigger(struct feed_queue_logic *q)
128{
129 int ret;
130
131 ret = feed_queue_logic_flush(q);
132 if (ret != SR_OK)
133 return ret;
134
135 ret = std_session_send_df_trigger(q->sdi);
136 if (ret != SR_OK)
137 return ret;
138
139 return SR_OK;
140}
141
47a102f9
GS
142SR_API void feed_queue_logic_free(struct feed_queue_logic *q)
143{
144
145 if (!q)
146 return;
147
148 g_free(q->data_bytes);
149 g_free(q);
150}
151
152struct feed_queue_analog {
57140e5a 153 const struct sr_dev_inst *sdi;
47a102f9
GS
154 size_t alloc_count;
155 size_t fill_count;
156 float *data_values;
157 int digits;
158 struct sr_datafeed_packet packet;
159 struct sr_datafeed_analog analog;
160 struct sr_analog_encoding encoding;
161 struct sr_analog_meaning meaning;
162 struct sr_analog_spec spec;
163 GSList *channels;
164};
165
57140e5a
GS
166SR_API struct feed_queue_analog *feed_queue_analog_alloc(
167 const struct sr_dev_inst *sdi,
47a102f9
GS
168 size_t sample_count, int digits, struct sr_channel *ch)
169{
170 struct feed_queue_analog *q;
171
172 q = g_malloc0(sizeof(*q));
173 q->sdi = sdi;
174 q->alloc_count = sample_count;
175 q->data_values = g_try_malloc(q->alloc_count * sizeof(float));
176 if (!q->data_values) {
177 g_free(q);
178 return NULL;
179 }
180 q->digits = digits;
181 q->channels = g_slist_append(NULL, ch);
182
183 memset(&q->packet, 0, sizeof(q->packet));
184 sr_analog_init(&q->analog, &q->encoding, &q->meaning, &q->spec, digits);
185 q->packet.type = SR_DF_ANALOG;
186 q->packet.payload = &q->analog;
187 q->encoding.is_signed = TRUE;
188 q->meaning.channels = q->channels;
189 q->analog.data = q->data_values;
190
191 return q;
192}
193
cc8b162f 194SR_API int feed_queue_analog_mq_unit(struct feed_queue_analog *q,
43e6f7a7
GS
195 enum sr_mq mq, enum sr_mqflag mq_flag, enum sr_unit unit)
196{
197 int ret;
198
199 if (!q)
200 return SR_ERR_ARG;
201
202 ret = feed_queue_analog_flush(q);
203 if (ret != SR_OK)
204 return ret;
205
69b0005b
GS
206 q->meaning.mq = mq;
207 q->meaning.mqflags = mq_flag;
208 q->meaning.unit = unit;
43e6f7a7
GS
209
210 return SR_OK;
211}
212
cc8b162f
GS
213SR_API int feed_queue_analog_scale_offset(struct feed_queue_analog *q,
214 const struct sr_rational *scale, const struct sr_rational *offset)
215{
216 int ret;
217
218 if (!q)
219 return SR_ERR_ARG;
220
221 ret = feed_queue_analog_flush(q);
222 if (ret != SR_OK)
223 return ret;
224
225 if (scale)
226 q->encoding.scale = *scale;
227 if (offset)
228 q->encoding.offset = *offset;
229
230 return SR_OK;
231}
232
f40d8479
GS
233SR_API int feed_queue_analog_submit_one(struct feed_queue_analog *q,
234 float data, size_t repeat_count)
47a102f9
GS
235{
236 int ret;
237
f40d8479 238 while (repeat_count--) {
47a102f9
GS
239 q->data_values[q->fill_count++] = data;
240 if (q->fill_count == q->alloc_count) {
241 ret = feed_queue_analog_flush(q);
242 if (ret != SR_OK)
243 return ret;
244 }
245 }
246
247 return SR_OK;
248}
249
250SR_API int feed_queue_analog_flush(struct feed_queue_analog *q)
251{
252 int ret;
253
254 if (!q->fill_count)
255 return SR_OK;
256
257 q->analog.num_samples = q->fill_count;
258 ret = sr_session_send(q->sdi, &q->packet);
259 if (ret != SR_OK)
260 return ret;
261 q->fill_count = 0;
262
263 return SR_OK;
264}
265
266SR_API void feed_queue_analog_free(struct feed_queue_analog *q)
267{
268
269 if (!q)
270 return;
271
272 g_free(q->data_values);
273 g_slist_free(q->channels);
274 g_free(q);
275}