00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include <stdlib.h>
00023 #include <unistd.h>
00024 #include <string.h>
00025 #ifdef _WIN32
00026 #include <io.h>
00027 #include <fcntl.h>
00028 #define pipe(fds) _pipe(fds, 4096, _O_BINARY)
00029 #endif
00030 #include "sigrok.h"
00031 #include "sigrok-internal.h"
00032
00033
00034 #define NUM_PROBES 8
00035
00036 #define DEMONAME "Demo device"
00037
00038
00039
00040 #define BUFSIZE 4096
00041
00042
00043 enum {
00044
00045
00046
00047
00048 PATTERN_SIGROK,
00049
00050
00051 PATTERN_RANDOM,
00052
00053
00054
00055
00056
00057 PATTERN_INC,
00058
00059
00060 PATTERN_ALL_LOW,
00061
00062
00063 PATTERN_ALL_HIGH,
00064 };
00065
00066
00067 SR_PRIV GIOChannel *channels[2];
00068
00069 struct context {
00070 int pipe_fds[2];
00071 uint8_t sample_generator;
00072 uint8_t thread_running;
00073 uint64_t samples_counter;
00074 int dev_index;
00075 void *session_dev_id;
00076 GTimer *timer;
00077 };
00078
00079 static int hwcaps[] = {
00080 SR_HWCAP_LOGIC_ANALYZER,
00081 SR_HWCAP_DEMO_DEV,
00082 SR_HWCAP_SAMPLERATE,
00083 SR_HWCAP_PATTERN_MODE,
00084 SR_HWCAP_LIMIT_SAMPLES,
00085 SR_HWCAP_LIMIT_MSEC,
00086 SR_HWCAP_CONTINUOUS,
00087 };
00088
00089 static struct sr_samplerates samplerates = {
00090 SR_HZ(1),
00091 SR_GHZ(1),
00092 SR_HZ(1),
00093 NULL,
00094 };
00095
00096 static const char *pattern_strings[] = {
00097 "sigrok",
00098 "random",
00099 "incremental",
00100 "all-low",
00101 "all-high",
00102 NULL,
00103 };
00104
00105
00106 static const char *probe_names[NUM_PROBES + 1] = {
00107 "0",
00108 "1",
00109 "2",
00110 "3",
00111 "4",
00112 "5",
00113 "6",
00114 "7",
00115 NULL,
00116 };
00117
00118 static uint8_t pattern_sigrok[] = {
00119 0x4c, 0x92, 0x92, 0x92, 0x64, 0x00, 0x00, 0x00,
00120 0x82, 0xfe, 0xfe, 0x82, 0x00, 0x00, 0x00, 0x00,
00121 0x7c, 0x82, 0x82, 0x92, 0x74, 0x00, 0x00, 0x00,
00122 0xfe, 0x12, 0x12, 0x32, 0xcc, 0x00, 0x00, 0x00,
00123 0x7c, 0x82, 0x82, 0x82, 0x7c, 0x00, 0x00, 0x00,
00124 0xfe, 0x10, 0x28, 0x44, 0x82, 0x00, 0x00, 0x00,
00125 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00126 0xbe, 0xbe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00127 };
00128
00129
00130
00131
00132
00133 static GSList *dev_insts = NULL;
00134 static uint64_t cur_samplerate = SR_KHZ(200);
00135 static uint64_t limit_samples = 0;
00136 static uint64_t limit_msec = 0;
00137 static int default_pattern = PATTERN_SIGROK;
00138 static GThread *my_thread;
00139 static int thread_running;
00140
00141 static int hw_dev_acquisition_stop(int dev_index, void *cb_data);
00142
00143 static int hw_init(const char *devinfo)
00144 {
00145 struct sr_dev_inst *sdi;
00146
00147
00148 (void)devinfo;
00149
00150 sdi = sr_dev_inst_new(0, SR_ST_ACTIVE, DEMONAME, NULL, NULL);
00151 if (!sdi) {
00152 sr_err("demo: %s: sr_dev_inst_new failed", __func__);
00153 return 0;
00154 }
00155
00156 dev_insts = g_slist_append(dev_insts, sdi);
00157
00158 return 1;
00159 }
00160
00161 static int hw_dev_open(int dev_index)
00162 {
00163
00164 (void)dev_index;
00165
00166
00167
00168 return SR_OK;
00169 }
00170
00171 static int hw_dev_close(int dev_index)
00172 {
00173
00174 (void)dev_index;
00175
00176
00177
00178 return SR_OK;
00179 }
00180
00181 static int hw_cleanup(void)
00182 {
00183
00184 return SR_OK;
00185 }
00186
00187 static void *hw_dev_info_get(int dev_index, int dev_info_id)
00188 {
00189 struct sr_dev_inst *sdi;
00190 void *info = NULL;
00191
00192 if (!(sdi = sr_dev_inst_get(dev_insts, dev_index))) {
00193 sr_err("demo: %s: sdi was NULL", __func__);
00194 return NULL;
00195 }
00196
00197 switch (dev_info_id) {
00198 case SR_DI_INST:
00199 info = sdi;
00200 break;
00201 case SR_DI_NUM_PROBES:
00202 info = GINT_TO_POINTER(NUM_PROBES);
00203 break;
00204 case SR_DI_PROBE_NAMES:
00205 info = probe_names;
00206 break;
00207 case SR_DI_SAMPLERATES:
00208 info = &samplerates;
00209 break;
00210 case SR_DI_CUR_SAMPLERATE:
00211 info = &cur_samplerate;
00212 break;
00213 case SR_DI_PATTERNS:
00214 info = &pattern_strings;
00215 break;
00216 }
00217
00218 return info;
00219 }
00220
00221 static int hw_dev_status_get(int dev_index)
00222 {
00223
00224 (void)dev_index;
00225
00226 return SR_ST_ACTIVE;
00227 }
00228
00229 static int *hw_hwcap_get_all(void)
00230 {
00231 return hwcaps;
00232 }
00233
00234 static int hw_dev_config_set(int dev_index, int hwcap, void *value)
00235 {
00236 int ret;
00237 char *stropt;
00238
00239
00240 (void)dev_index;
00241
00242 if (hwcap == SR_HWCAP_PROBECONFIG) {
00243
00244 ret = SR_OK;
00245 } else if (hwcap == SR_HWCAP_SAMPLERATE) {
00246 cur_samplerate = *(uint64_t *)value;
00247 sr_dbg("demo: %s: setting samplerate to %" PRIu64, __func__,
00248 cur_samplerate);
00249 ret = SR_OK;
00250 } else if (hwcap == SR_HWCAP_LIMIT_SAMPLES) {
00251 limit_samples = *(uint64_t *)value;
00252 sr_dbg("demo: %s: setting limit_samples to %" PRIu64, __func__,
00253 limit_samples);
00254 ret = SR_OK;
00255 } else if (hwcap == SR_HWCAP_LIMIT_MSEC) {
00256 limit_msec = *(uint64_t *)value;
00257 sr_dbg("demo: %s: setting limit_msec to %" PRIu64, __func__,
00258 limit_msec);
00259 ret = SR_OK;
00260 } else if (hwcap == SR_HWCAP_PATTERN_MODE) {
00261 stropt = value;
00262 ret = SR_OK;
00263 if (!strcmp(stropt, "sigrok")) {
00264 default_pattern = PATTERN_SIGROK;
00265 } else if (!strcmp(stropt, "random")) {
00266 default_pattern = PATTERN_RANDOM;
00267 } else if (!strcmp(stropt, "incremental")) {
00268 default_pattern = PATTERN_INC;
00269 } else if (!strcmp(stropt, "all-low")) {
00270 default_pattern = PATTERN_ALL_LOW;
00271 } else if (!strcmp(stropt, "all-high")) {
00272 default_pattern = PATTERN_ALL_HIGH;
00273 } else {
00274 ret = SR_ERR;
00275 }
00276 sr_dbg("demo: %s: setting pattern to %d", __func__,
00277 default_pattern);
00278 } else {
00279 ret = SR_ERR;
00280 }
00281
00282 return ret;
00283 }
00284
00285 static void samples_generator(uint8_t *buf, uint64_t size, void *data)
00286 {
00287 static uint64_t p = 0;
00288 struct context *ctx = data;
00289 uint64_t i;
00290
00291
00292 memset(buf, 0, size);
00293
00294 switch (ctx->sample_generator) {
00295 case PATTERN_SIGROK:
00296 for (i = 0; i < size; i++) {
00297 *(buf + i) = ~(pattern_sigrok[p] >> 1);
00298 if (++p == 64)
00299 p = 0;
00300 }
00301 break;
00302 case PATTERN_RANDOM:
00303 for (i = 0; i < size; i++)
00304 *(buf + i) = (uint8_t)(rand() & 0xff);
00305 break;
00306 case PATTERN_INC:
00307 for (i = 0; i < size; i++)
00308 *(buf + i) = i;
00309 break;
00310 case PATTERN_ALL_LOW:
00311 memset(buf, 0x00, size);
00312 break;
00313 case PATTERN_ALL_HIGH:
00314 memset(buf, 0xff, size);
00315 break;
00316 default:
00317 sr_err("demo: %s: unknown pattern %d", __func__,
00318 ctx->sample_generator);
00319 break;
00320 }
00321 }
00322
00323
00324 static void thread_func(void *data)
00325 {
00326 struct context *ctx = data;
00327 uint8_t buf[BUFSIZE];
00328 uint64_t nb_to_send = 0;
00329 int bytes_written;
00330 double time_cur, time_last, time_diff;
00331
00332 time_last = g_timer_elapsed(ctx->timer, NULL);
00333
00334 while (thread_running) {
00335
00336 time_cur = g_timer_elapsed(ctx->timer, NULL);
00337
00338 time_diff = time_cur - time_last;
00339 time_last = time_cur;
00340
00341 nb_to_send = cur_samplerate * time_diff;
00342
00343 if (limit_samples) {
00344 nb_to_send = MIN(nb_to_send,
00345 limit_samples - ctx->samples_counter);
00346 }
00347
00348
00349 nb_to_send = MIN(nb_to_send, BUFSIZE);
00350
00351 if (nb_to_send) {
00352 samples_generator(buf, nb_to_send, data);
00353 ctx->samples_counter += nb_to_send;
00354
00355 g_io_channel_write_chars(channels[1], (gchar *)&buf,
00356 nb_to_send, (gsize *)&bytes_written, NULL);
00357 }
00358
00359
00360 if ((limit_msec && time_cur * 1000 > limit_msec) ||
00361 (limit_samples && ctx->samples_counter >= limit_samples))
00362 {
00363 close(ctx->pipe_fds[1]);
00364 thread_running = 0;
00365 }
00366
00367 g_usleep(10);
00368 }
00369 }
00370
00371
00372 static int receive_data(int fd, int revents, void *cb_data)
00373 {
00374 struct sr_datafeed_packet packet;
00375 struct sr_datafeed_logic logic;
00376 static uint64_t samples_received = 0;
00377 unsigned char c[BUFSIZE];
00378 gsize z;
00379
00380
00381 (void)fd;
00382 (void)revents;
00383
00384 do {
00385 g_io_channel_read_chars(channels[0],
00386 (gchar *)&c, BUFSIZE, &z, NULL);
00387
00388 if (z > 0) {
00389 packet.type = SR_DF_LOGIC;
00390 packet.payload = &logic;
00391 logic.length = z;
00392 logic.unitsize = 1;
00393 logic.data = c;
00394 sr_session_send(cb_data, &packet);
00395 samples_received += z;
00396 }
00397 } while (z > 0);
00398
00399 if (!thread_running && z <= 0) {
00400
00401 g_io_channel_shutdown(channels[0], FALSE, NULL);
00402
00403
00404 packet.type = SR_DF_END;
00405 sr_session_send(cb_data, &packet);
00406
00407 return FALSE;
00408 }
00409
00410 return TRUE;
00411 }
00412
00413 static int hw_dev_acquisition_start(int dev_index, void *cb_data)
00414 {
00415 struct sr_datafeed_packet *packet;
00416 struct sr_datafeed_header *header;
00417 struct context *ctx;
00418
00419
00420 if (!(ctx = g_try_malloc(sizeof(struct context)))) {
00421 sr_err("demo: %s: ctx malloc failed", __func__);
00422 return SR_ERR_MALLOC;
00423 }
00424
00425 ctx->sample_generator = default_pattern;
00426 ctx->session_dev_id = cb_data;
00427 ctx->dev_index = dev_index;
00428 ctx->samples_counter = 0;
00429
00430 if (pipe(ctx->pipe_fds)) {
00431
00432 sr_err("demo: %s: pipe() failed", __func__);
00433 return SR_ERR;
00434 }
00435
00436 channels[0] = g_io_channel_unix_new(ctx->pipe_fds[0]);
00437 channels[1] = g_io_channel_unix_new(ctx->pipe_fds[1]);
00438
00439
00440 g_io_channel_set_encoding(channels[0], NULL, NULL);
00441 g_io_channel_set_encoding(channels[1], NULL, NULL);
00442
00443
00444 g_io_channel_set_buffered(channels[0], FALSE);
00445 g_io_channel_set_buffered(channels[1], FALSE);
00446
00447 sr_source_add(ctx->pipe_fds[0], G_IO_IN | G_IO_ERR, 40,
00448 receive_data, ctx->session_dev_id);
00449
00450
00451 g_thread_init(NULL);
00452
00453 ctx->timer = g_timer_new();
00454 thread_running = 1;
00455 my_thread =
00456 g_thread_create((GThreadFunc)thread_func, ctx, TRUE, NULL);
00457 if (!my_thread) {
00458 sr_err("demo: %s: g_thread_create failed", __func__);
00459 return SR_ERR;
00460 }
00461
00462 if (!(packet = g_try_malloc(sizeof(struct sr_datafeed_packet)))) {
00463 sr_err("demo: %s: packet malloc failed", __func__);
00464 return SR_ERR_MALLOC;
00465 }
00466
00467 if (!(header = g_try_malloc(sizeof(struct sr_datafeed_header)))) {
00468 sr_err("demo: %s: header malloc failed", __func__);
00469 return SR_ERR_MALLOC;
00470 }
00471
00472 packet->type = SR_DF_HEADER;
00473 packet->payload = header;
00474 header->feed_version = 1;
00475 gettimeofday(&header->starttime, NULL);
00476 header->samplerate = cur_samplerate;
00477 header->num_logic_probes = NUM_PROBES;
00478 sr_session_send(ctx->session_dev_id, packet);
00479 g_free(header);
00480 g_free(packet);
00481
00482 return SR_OK;
00483 }
00484
00485
00486 static int hw_dev_acquisition_stop(int dev_index, void *cb_data)
00487 {
00488
00489 (void)dev_index;
00490 (void)cb_data;
00491
00492
00493 thread_running = 0;
00494
00495 return SR_OK;
00496 }
00497
00498 SR_PRIV struct sr_dev_driver demo_driver_info = {
00499 .name = "demo",
00500 .longname = "Demo driver and pattern generator",
00501 .api_version = 1,
00502 .init = hw_init,
00503 .cleanup = hw_cleanup,
00504 .dev_open = hw_dev_open,
00505 .dev_close = hw_dev_close,
00506 .dev_info_get = hw_dev_info_get,
00507 .dev_status_get = hw_dev_status_get,
00508 .hwcap_get_all = hw_hwcap_get_all,
00509 .dev_config_set = hw_dev_config_set,
00510 .dev_acquisition_start = hw_dev_acquisition_start,
00511 .dev_acquisition_stop = hw_dev_acquisition_stop,
00512 };