2 * This file is part of the sigrok project.
4 * Copyright (C) 2010 Uwe Hermann <uwe@hermann-uwe.de>
5 * Copyright (C) 2011 Olivier Fauchon <olivier@aixmarseille.com>
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
29 #define DEMONAME "Demo device"
30 /* size of chunks to send through the session bus */
40 uint8_t sample_generator;
41 uint8_t thread_running;
42 uint64_t samples_counter;
45 gpointer session_device_id;
48 static GThread *my_thread;
49 static int thread_running;
51 static int capabilities[] = {
58 static const char *patternmodes[] = {
64 /* List of struct sigrok_device_instance, maintained by opendev()/closedev(). */
65 static GSList *device_instances = NULL;
66 static uint64_t cur_samplerate = 0;
67 static uint64_t limit_samples = -1;
68 static int default_genmode = GENMODE_RANDOM;
70 static void hw_stop_acquisition(int device_index, gpointer session_device_id);
72 static int hw_init(char *deviceinfo)
74 struct sigrok_device_instance *sdi;
76 /* Avoid compiler warnings. */
77 deviceinfo = deviceinfo;
79 sdi = sigrok_device_instance_new(0, ST_ACTIVE, DEMONAME, NULL, NULL);
83 device_instances = g_slist_append(device_instances, sdi);
88 static int hw_opendev(int device_index)
90 /* Avoid compiler warnings. */
91 device_index = device_index;
93 /* Nothing needed so far. */
97 static void hw_closedev(int device_index)
99 /* Avoid compiler warnings. */
100 device_index = device_index;
102 /* Nothing needed so far. */
105 static void hw_cleanup(void)
107 /* Nothing needed so far. */
110 static void *hw_get_device_info(int device_index, int device_info_id)
112 struct sigrok_device_instance *sdi;
115 if (!(sdi = get_sigrok_device_instance(device_instances, device_index)))
118 switch (device_info_id) {
123 info = GINT_TO_POINTER(NUM_PROBES);
125 case DI_CUR_SAMPLERATE:
126 info = &cur_samplerate;
128 case DI_PATTERNMODES:
129 info = &patternmodes;
136 static int hw_get_status(int device_index)
138 /* Avoid compiler warnings. */
139 device_index = device_index;
144 static int *hw_get_capabilities(void)
149 static int hw_set_configuration(int device_index, int capability, void *value)
155 /* Avoid compiler warnings. */
156 device_index = device_index;
158 if (capability == HWCAP_PROBECONFIG) {
161 } else if (capability == HWCAP_LIMIT_SAMPLES) {
163 limit_samples = *tmp_u64;
165 } else if (capability == HWCAP_PATTERN_MODE) {
167 if (!strcmp(stropt, "random")) {
168 default_genmode = GENMODE_RANDOM;
170 } else if (!strcmp(stropt, "incremental")) {
171 default_genmode = GENMODE_INC;
183 static void samples_generator(uint8_t *buf, uint64_t size, void *data)
185 struct databag *mydata = data;
188 memset(buf, 0, size);
190 switch (mydata->sample_generator) {
191 case GENMODE_RANDOM: /* Random */
192 for (i = 0; i < size; i++)
193 *(buf + i) = (uint8_t)(rand() & 0xff);
195 case GENMODE_INC: /* Simple increment */
196 for (i = 0; i < size; i++)
202 /* Thread function */
203 static void thread_func(void *data)
205 struct databag *mydata = data;
206 uint8_t buf[BUFSIZE];
207 uint64_t nb_to_send = 0;
209 while (thread_running) {
211 nb_to_send = limit_samples - mydata->samples_counter;
213 nb_to_send = BUFSIZE; /* Continuous mode */
215 if (nb_to_send == 0) {
216 close(mydata->pipe_fds[1]);
218 hw_stop_acquisition(mydata->device_index,
219 mydata->session_device_id);
220 } else if (nb_to_send > BUFSIZE) {
221 nb_to_send = BUFSIZE;
224 samples_generator(buf, nb_to_send, data);
225 mydata->samples_counter += nb_to_send;
227 write(mydata->pipe_fds[1], &buf, nb_to_send);
228 g_usleep(mydata->loop_sleep);
232 /* Callback handling data */
233 static int receive_data(int fd, int revents, void *user_data)
235 struct datafeed_packet packet;
239 /* Avoid compiler warnings. */
242 z = read(fd, &c, BUFSIZE);
244 packet.type = DF_LOGIC;
248 session_bus(user_data, &packet);
253 static int hw_start_acquisition(int device_index, gpointer session_device_id)
255 struct datafeed_packet *packet;
256 struct datafeed_header *header;
257 struct databag *mydata;
259 mydata = malloc(sizeof(struct databag));
261 return SIGROK_ERR_MALLOC;
263 mydata->sample_generator = default_genmode;
264 mydata->session_device_id = session_device_id;
265 mydata->device_index = device_index;
266 mydata->samples_counter = 0;
267 mydata->loop_sleep = 100000;
269 if (pipe(mydata->pipe_fds))
272 source_add(mydata->pipe_fds[0], G_IO_IN | G_IO_ERR, 40, receive_data,
275 /* Run the demo thread. */
279 g_thread_create((GThreadFunc)thread_func, mydata, TRUE, NULL);
283 packet = malloc(sizeof(struct datafeed_packet));
284 header = malloc(sizeof(struct datafeed_header));
285 if (!packet || !header)
286 return SIGROK_ERR_MALLOC;
288 packet->type = DF_HEADER;
289 packet->length = sizeof(struct datafeed_header);
290 packet->payload = (unsigned char *)header;
291 header->feed_version = 1;
292 gettimeofday(&header->starttime, NULL);
293 header->samplerate = cur_samplerate;
294 header->protocol_id = PROTO_RAW;
295 header->num_logic_probes = NUM_PROBES;
296 header->num_analog_probes = 0;
297 session_bus(session_device_id, packet);
304 static void hw_stop_acquisition(int device_index, gpointer session_device_id)
306 struct datafeed_packet packet;
308 /* Avoid compiler warnings. */
309 device_index = device_index;
311 /* Send last packet. */
312 packet.type = DF_END;
313 session_bus(session_device_id, &packet);
316 struct device_plugin demo_plugin_info = {
326 hw_set_configuration,
327 hw_start_acquisition,