]> sigrok.org Git - libsigrok.git/blame - src/input/feed_queue.c
serial-dmm: Add PeakTech 2025 meter support.
[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 {
25 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
34SR_API struct feed_queue_logic *feed_queue_logic_alloc(struct sr_dev_inst *sdi,
35 size_t sample_count, size_t unit_size)
36{
37 struct feed_queue_logic *q;
38
39 q = g_malloc0(sizeof(*q));
40 q->sdi = sdi;
41 q->unit_size = unit_size;
42 q->alloc_count = sample_count;
43 q->data_bytes = g_try_malloc(q->alloc_count * q->unit_size);
44 if (!q->data_bytes) {
45 g_free(q);
46 return NULL;
47 }
48
49 memset(&q->packet, 0, sizeof(q->packet));
50 memset(&q->logic, 0, sizeof(q->logic));
51 q->packet.type = SR_DF_LOGIC;
52 q->packet.payload = &q->logic;
53 q->logic.unitsize = q->unit_size;
54 q->logic.data = q->data_bytes;
55
56 return q;
57}
58
59SR_API int feed_queue_logic_submit(struct feed_queue_logic *q,
60 const uint8_t *data, size_t count)
61{
62 uint8_t *wrptr;
63 int ret;
64
65 wrptr = &q->data_bytes[q->fill_count * q->unit_size];
66 while (count--) {
67 memcpy(wrptr, data, q->unit_size);
68 wrptr += q->unit_size;
69 q->fill_count++;
70 if (q->fill_count == q->alloc_count) {
71 ret = feed_queue_logic_flush(q);
72 if (ret != SR_OK)
73 return ret;
74 wrptr = &q->data_bytes[0];
75 }
76 }
77
78 return SR_OK;
79}
80
81SR_API int feed_queue_logic_flush(struct feed_queue_logic *q)
82{
83 int ret;
84
85 if (!q->fill_count)
86 return SR_OK;
87
88 q->logic.length = q->fill_count * q->unit_size;
89 ret = sr_session_send(q->sdi, &q->packet);
90 if (ret != SR_OK)
91 return ret;
92 q->fill_count = 0;
93
94 return SR_OK;
95}
96
97SR_API void feed_queue_logic_free(struct feed_queue_logic *q)
98{
99
100 if (!q)
101 return;
102
103 g_free(q->data_bytes);
104 g_free(q);
105}
106
107struct feed_queue_analog {
108 struct sr_dev_inst *sdi;
109 size_t alloc_count;
110 size_t fill_count;
111 float *data_values;
112 int digits;
113 struct sr_datafeed_packet packet;
114 struct sr_datafeed_analog analog;
115 struct sr_analog_encoding encoding;
116 struct sr_analog_meaning meaning;
117 struct sr_analog_spec spec;
118 GSList *channels;
119};
120
121SR_API struct feed_queue_analog *feed_queue_analog_alloc(struct sr_dev_inst *sdi,
122 size_t sample_count, int digits, struct sr_channel *ch)
123{
124 struct feed_queue_analog *q;
125
126 q = g_malloc0(sizeof(*q));
127 q->sdi = sdi;
128 q->alloc_count = sample_count;
129 q->data_values = g_try_malloc(q->alloc_count * sizeof(float));
130 if (!q->data_values) {
131 g_free(q);
132 return NULL;
133 }
134 q->digits = digits;
135 q->channels = g_slist_append(NULL, ch);
136
137 memset(&q->packet, 0, sizeof(q->packet));
138 sr_analog_init(&q->analog, &q->encoding, &q->meaning, &q->spec, digits);
139 q->packet.type = SR_DF_ANALOG;
140 q->packet.payload = &q->analog;
141 q->encoding.is_signed = TRUE;
142 q->meaning.channels = q->channels;
143 q->analog.data = q->data_values;
144
145 return q;
146}
147
148SR_API int feed_queue_analog_submit(struct feed_queue_analog *q,
149 float data, size_t count)
150{
151 int ret;
152
153 while (count--) {
154 q->data_values[q->fill_count++] = data;
155 if (q->fill_count == q->alloc_count) {
156 ret = feed_queue_analog_flush(q);
157 if (ret != SR_OK)
158 return ret;
159 }
160 }
161
162 return SR_OK;
163}
164
165SR_API int feed_queue_analog_flush(struct feed_queue_analog *q)
166{
167 int ret;
168
169 if (!q->fill_count)
170 return SR_OK;
171
172 q->analog.num_samples = q->fill_count;
173 ret = sr_session_send(q->sdi, &q->packet);
174 if (ret != SR_OK)
175 return ret;
176 q->fill_count = 0;
177
178 return SR_OK;
179}
180
181SR_API void feed_queue_analog_free(struct feed_queue_analog *q)
182{
183
184 if (!q)
185 return;
186
187 g_free(q->data_values);
188 g_slist_free(q->channels);
189 g_free(q);
190}