]> sigrok.org Git - libsigrok.git/blob - src/input/feed_queue.c
output/csv: use intermediate time_t var, silence compiler warning
[libsigrok.git] / src / input / feed_queue.c
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
24 struct feed_queue_logic {
25         const struct sr_dev_inst *sdi;
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
34 SR_API struct feed_queue_logic *feed_queue_logic_alloc(
35         const struct sr_dev_inst *sdi,
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
60 SR_API int feed_queue_logic_submit_one(struct feed_queue_logic *q,
61         const uint8_t *data, size_t repeat_count)
62 {
63         uint8_t *wrptr;
64         int ret;
65
66         wrptr = &q->data_bytes[q->fill_count * q->unit_size];
67         while (repeat_count--) {
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
82 SR_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
111 SR_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
127 SR_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
142 SR_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
152 struct feed_queue_analog {
153         const struct sr_dev_inst *sdi;
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
166 SR_API struct feed_queue_analog *feed_queue_analog_alloc(
167         const struct sr_dev_inst *sdi,
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
194 SR_API int feed_queue_analog_mq_unit(struct feed_queue_analog *q,
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
206         q->meaning.mq = mq;
207         q->meaning.mqflags = mq_flag;
208         q->meaning.unit = unit;
209
210         return SR_OK;
211 }
212
213 SR_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
233 SR_API int feed_queue_analog_submit_one(struct feed_queue_analog *q,
234         float data, size_t repeat_count)
235 {
236         int ret;
237
238         while (repeat_count--) {
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
250 SR_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
266 SR_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 }