]> sigrok.org Git - libsigrok.git/blob - hardware/demo/demo.c
Initial, unfinished demo/simulation hardware driver.
[libsigrok.git] / hardware / demo / demo.c
1 /*
2  * This file is part of the sigrok project.
3  *
4  * Copyright (C) 2010 Uwe Hermann <uwe@hermann-uwe.de>
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 2 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, write to the Free Software
18  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
19  */
20
21 #include <stdlib.h>
22 #include <string.h>
23 #include <sigrok.h>
24 #include "config.h"
25
26 #define NUM_PROBES                      8
27 #define NUM_TRIGGER_STAGES              4
28 #define TRIGGER_TYPES                   "01"
29
30 /* Software trigger implementation: positive values indicate trigger stage. */
31 #define TRIGGER_FIRED                   -1
32
33 static int capabilities[] = {
34         HWCAP_LOGIC_ANALYZER,
35         HWCAP_SAMPLERATE,
36         HWCAP_LIMIT_SAMPLES,
37 };
38
39 /* Random selection of samplerates this "device" shall support. */
40 static uint64_t supported_samplerates[] = {
41         KHZ(100),
42         KHZ(500),
43         MHZ(1),
44         MHZ(2),
45         MHZ(12),
46         MHZ(24),
47         0,
48 };
49
50 static struct samplerates samplerates = {
51         KHZ(100),
52         MHZ(24),
53         0,
54         supported_samplerates,
55 };
56
57 /* TODO: All of these should go in a device-specific struct. */
58 static uint64_t cur_samplerate = 0;
59 static uint64_t limit_samples = 0;
60 // static uint8_t probe_mask = 0;
61 // static uint8_t trigger_mask[NUM_TRIGGER_STAGES] = { 0 };
62 // static uint8_t trigger_value[NUM_TRIGGER_STAGES] = { 0 };
63 // static uint8_t trigger_buffer[NUM_TRIGGER_STAGES] = { 0 };
64
65 // static int trigger_stage = TRIGGER_FIRED;
66
67 static int hw_set_configuration(int device_index, int capability, void *value);
68 static void hw_stop_acquisition(int device_index, gpointer session_device_id);
69
70 #if 0
71 static int configure_probes(GSList *probes)
72 {
73         struct probe *probe;
74         GSList *l;
75         int probe_bit, stage, i;
76         char *tc;
77
78         probe_mask = 0;
79         for (i = 0; i < NUM_TRIGGER_STAGES; i++) {
80                 trigger_mask[i] = 0;
81                 trigger_value[i] = 0;
82         }
83
84         stage = -1;
85         for (l = probes; l; l = l->next) {
86                 probe = (struct probe *)l->data;
87                 if (!(probe->enabled))
88                         continue;
89                 probe_bit = 1 << (probe->index - 1);
90                 probe_mask |= probe_bit;
91                 if (!(probe->trigger))
92                         continue;
93
94                 stage = 0;
95                 for (tc = probe->trigger; *tc; tc++) {
96                         trigger_mask[stage] |= probe_bit;
97                         if (*tc == '1')
98                                 trigger_value[stage] |= probe_bit;
99                         stage++;
100                         if (stage > NUM_TRIGGER_STAGES)
101                                 return SIGROK_ERR;
102                 }
103         }
104
105         if (stage == -1)
106                 /*
107                  * We didn't configure any triggers, make sure acquisition
108                  * doesn't wait for any.
109                  */
110                 trigger_stage = TRIGGER_FIRED;
111         else
112                 trigger_stage = 0;
113
114         return SIGROK_OK;
115 }
116 #endif
117
118 static int hw_init(char *deviceinfo)
119 {
120         /* Avoid compiler warning. */
121         deviceinfo = deviceinfo;
122
123         /* Nothing needed so far. */
124         return 1; /* FIXME? */
125 }
126
127 static int hw_opendev(int device_index)
128 {
129         /* Avoid compiler warning. */
130         device_index = device_index;
131
132         /* Nothing needed so far. */
133         return SIGROK_OK;
134 }
135
136 static void hw_closedev(int device_index)
137 {
138         /* Avoid compiler warning. */
139         device_index = device_index;
140
141         /* Nothing needed so far. */
142 }
143
144 static void hw_cleanup(void)
145 {
146         /* Nothing needed so far. */
147 }
148
149 static void *hw_get_device_info(int device_index, int device_info_id)
150 {
151         void *info = NULL;
152
153         /* Avoid compiler warning. */
154         device_index = device_index;
155
156         switch (device_info_id) {
157         case DI_INSTANCE:
158                 /// info = sdi;
159                 /* TODO */
160                 break;
161         case DI_NUM_PROBES:
162                 info = GINT_TO_POINTER(NUM_PROBES);
163                 break;
164         case DI_SAMPLERATES:
165                 info = &samplerates;
166                 break;
167         case DI_TRIGGER_TYPES:
168                 info = TRIGGER_TYPES;
169                 break;
170         case DI_CUR_SAMPLERATE:
171                 info = &cur_samplerate;
172                 break;
173         }
174
175         return info;
176 }
177
178 static int hw_get_status(int device_index)
179 {
180         /* Avoid compiler warning. */
181         device_index = device_index;
182
183         return 0; /* FIXME */
184 }
185
186 static int *hw_get_capabilities(void)
187 {
188         return capabilities;
189 }
190
191 static int hw_set_configuration(int device_index, int capability, void *value)
192 {
193         int ret;
194
195         /* Avoid compiler warning. */
196         device_index = device_index;
197
198         if (capability == HWCAP_SAMPLERATE) {
199                 cur_samplerate = *(uint64_t *)value;
200                 ret = SIGROK_OK;
201         } else if (capability == HWCAP_PROBECONFIG) {
202                 // ret = configure_probes((GSList *) value);
203                 ret = SIGROK_ERR;
204         } else if (capability == HWCAP_LIMIT_SAMPLES) {
205                 limit_samples = strtoull(value, NULL, 10);
206                 ret = SIGROK_OK;
207         } else {
208                 ret = SIGROK_ERR;
209         }
210
211         return ret;
212 }
213
214 static int hw_start_acquisition(int device_index, gpointer session_device_id)
215 {
216         struct datafeed_packet *packet;
217         struct datafeed_header *header;
218         unsigned char *buf;
219
220         /* Avoid compiler warning. */
221         device_index = device_index;
222
223         packet = malloc(sizeof(struct datafeed_packet));
224         header = malloc(sizeof(struct datafeed_header));
225         buf = malloc(2048);
226         if (!packet || !header || !buf)
227                 return SIGROK_ERR_MALLOC;
228
229         /* FIXME */
230         memset(buf, 0x55, 2048);
231
232         packet->type = DF_HEADER;
233         packet->length = sizeof(struct datafeed_header);
234         packet->payload = (unsigned char *)header;
235         header->feed_version = 1;
236         gettimeofday(&header->starttime, NULL);
237         header->samplerate = cur_samplerate;
238         header->protocol_id = PROTO_RAW;
239         header->num_probes = NUM_PROBES;
240         session_bus(session_device_id, packet);
241         free(header);
242         free(packet);
243
244         return SIGROK_OK;
245 }
246
247 #if 0
248 void receive_transfer(struct libusb_transfer *transfer)
249 {
250         static int num_samples = 0;
251         static int empty_transfer_count = 0;
252         struct datafeed_packet packet;
253         void *user_data;
254         int cur_buflen, trigger_offset, i;
255         unsigned char *cur_buf, *new_buf;
256
257         g_message("receive_transfer(): status %d received %d bytes",
258                   transfer->status, transfer->actual_length);
259
260         /* Save incoming transfer before reusing the transfer struct. */
261         cur_buf = transfer->buffer;
262         cur_buflen = transfer->actual_length;
263         user_data = transfer->user_data;
264
265         /* Fire off a new request. */
266         new_buf = g_malloc(4096);
267         transfer->buffer = new_buf;
268         transfer->length = 4096;
269         if (libusb_submit_transfer(transfer) != 0) {
270                 /* TODO: Stop session? */
271                 g_warning("eek");
272         }
273
274         trigger_offset = 0;
275         if (trigger_stage >= 0) {
276                 for (i = 0; i < cur_buflen; i++) {
277                         trigger_helper(i, cur_buf, &packet, user_data,
278                                        &trigger_offset);
279                 }
280         }
281
282         if (trigger_stage == TRIGGER_FIRED) {
283                 /* Send the incoming transfer to the session bus. */
284                 packet.type = DF_LOGIC8;
285                 packet.length = cur_buflen - trigger_offset;
286                 packet.payload = cur_buf + trigger_offset;
287                 session_bus(user_data, &packet);
288                 free(cur_buf);
289
290                 num_samples += cur_buflen;
291                 if ((unsigned int)num_samples > limit_samples) {
292                         hw_stop_acquisition(-1, user_data);
293                 }
294         } else {
295                 /*
296                  * TODO: Buffer pre-trigger data in capture
297                  * ratio-sized buffer.
298                  */
299         }
300 }
301 #endif
302
303 /* This stops acquisition on ALL devices, ignoring device_index. */
304 static void hw_stop_acquisition(int device_index, gpointer session_device_id)
305 {
306         struct datafeed_packet packet;
307
308         /* QUICK HACK */
309         device_index = device_index;
310
311         packet.type = DF_END;
312         session_bus(session_device_id, &packet);
313
314         /// receive_transfer(NULL);
315
316         /* TODO: Need to cancel and free any queued up transfers. */
317 }
318
319 struct device_plugin demo_plugin_info = {
320         "demo",
321         1,
322         hw_init,
323         hw_cleanup,
324         hw_opendev,
325         hw_closedev,
326         hw_get_device_info,
327         hw_get_status,
328         hw_get_capabilities,
329         hw_set_configuration,
330         hw_start_acquisition,
331         hw_stop_acquisition,
332 };