aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Thompson <daniel.thompson@linaro.org>2016-01-08 12:32:57 +0000
committerDaniel Thompson <daniel.thompson@linaro.org>2016-01-08 12:32:57 +0000
commitdf7c305951917becf071b31ef1461c895da4e411 (patch)
tree852ed0c097f66ae525daebdb3346fb614e803ef7
Initial revisionHEADmaster
-rw-r--r--.gitignore4
-rw-r--r--Makefile15
-rw-r--r--README.md26
-rw-r--r--src/.bin2tts.c.swpbin0 -> 16384 bytes
-rw-r--r--src/.tts-uart.c.swpbin0 -> 20480 bytes
-rw-r--r--src/bin2tts.c159
-rw-r--r--src/tts-uart.c270
-rw-r--r--tests/This_is_a_test-1152008N1.srbin0 -> 6925 bytes
-rw-r--r--tests/This_is_a_test-1152008N1.tts375
9 files changed, 849 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..12b9b59
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,4 @@
+bin2tts
+tts-uart
+*.o
+.*.swp
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..976d89e
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,15 @@
+CC = gcc
+CFLAGS = -g -Os -Wall
+
+APPS = bin2tts tts-uart
+
+all : $(APPS)
+
+bin2tts : src/bin2tts.o
+ $(CC) $(CFLAGS) -o $@ $+
+
+tts-uart : src/tts-uart.o
+ $(CC) $(CFLAGS) -o $@ $+
+
+clean :
+ $(RM) $(APPS) src/*.o
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..407d7bf
--- /dev/null
+++ b/README.md
@@ -0,0 +1,26 @@
+quikgrok - Real-time pipeline protocol decoders
+===============================================
+
+quikgrok is a suite of very simple C based filters designed to used in
+live shell pipes.
+
+Usage
+-----
+
+Offline decode of a capture file:
+
+~~~
+sigrok-cli -i uart_log.sr -O binary | \
+ bin2tts --bits=8 --sample-rate=1000000 | \
+ tts-uart --mask=0x20 --baud-rate=115200
+~~~
+
+Live decode from a running system (decode pin 2 of the FX2 device):
+
+~~~
+sigrok-cli \
+ --driver fx2lafw --config samplerate=1000000 \
+ --time=100000s -O binary | \
+ bin2tts --bits=8 --sample-rate=1000000 --timeout 10000 | \
+ tts-uart --mask=0x20 --baud-rate=115200
+~~~
diff --git a/src/.bin2tts.c.swp b/src/.bin2tts.c.swp
new file mode 100644
index 0000000..594c5e1
--- /dev/null
+++ b/src/.bin2tts.c.swp
Binary files differ
diff --git a/src/.tts-uart.c.swp b/src/.tts-uart.c.swp
new file mode 100644
index 0000000..73631eb
--- /dev/null
+++ b/src/.tts-uart.c.swp
Binary files differ
diff --git a/src/bin2tts.c b/src/bin2tts.c
new file mode 100644
index 0000000..dc04620
--- /dev/null
+++ b/src/bin2tts.c
@@ -0,0 +1,159 @@
+/*
+ * bin2tts.c
+ *
+ * Convert binary file to TTS (transisition/timestamp) format.
+ *
+ * Copyright (C) 2016 Daniel Thompson <daniel.thompson@linaro.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ */
+
+#include <errno.h>
+#include <getopt.h>
+#include <stdbool.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+struct ctx {
+ int bits;
+ int sample_rate;
+ unsigned int timeout;
+};
+
+void timestamp(struct ctx *ctx, FILE *f)
+{
+ size_t sz = (ctx->bits + 7) / 8;
+ uint64_t count = 0;
+ unsigned int timeout = 0;
+ bool hot = false;
+ void *p[2];
+
+ p[0] = malloc(2 * sz);
+ p[1] = (char *) p[0] + sz;
+
+ printf("[");
+
+ while (!feof(f)) {
+ if (1 != fread(p[hot], ctx->bits / 8, 1, f))
+ break;
+
+ if (0 != memcmp(p[hot], p[!hot], sz)) {
+ printf("%5d.%09d] 0x%02x\n[",
+ (int)(count / ctx->sample_rate),
+ (int)(((count % ctx->sample_rate) * 1000000000) /
+ ctx->sample_rate),
+ *((unsigned char *)p[hot]));
+ timeout = ctx->timeout;
+ }
+
+ if (timeout-- == 0) {
+ printf("%5d.%09d] 0x%02x\n[",
+ (int)(count / ctx->sample_rate),
+ (int)(((count % ctx->sample_rate) * 1000000000) /
+ ctx->sample_rate),
+ *((unsigned char *)p[hot]));
+ fflush(stdout);
+
+ }
+
+ hot = !hot;
+ count++;
+ }
+
+ free(p[0]);
+}
+
+void show_usage(bool full)
+{
+ FILE *f = full ? stdout : stderr;
+
+ fprintf(f, "Usage: bin2tts [OPTION]... [FILE]...\n");
+
+ if (!full) {
+ fprintf(f, "Try --help for more information.\n");
+ return;
+ }
+
+ fprintf(f,
+"\n"
+"Mandatory arguments to long options are mandatory for short options too.\n"
+" -b, --bits=BITS number of bits in each data sample\n"
+" -h, --help show this help, then exit\n"
+" -r, --sample-rate=X nominal sample rate of incoming data\n"
+" -t, --timeout=C issue an extra 'timeout' packet after C samples\n"
+ );
+}
+
+int main(int argc, char *argv[])
+{
+ int c;
+ struct ctx ctx = {
+ .bits = 8,
+ .sample_rate = 1000000,
+ .timeout = -1
+ };
+
+ const struct option opts[] = {
+ { "bits", required_argument, 0, 'b' },
+ { "help", no_argument, 0, 'h' },
+ { "sample-rate", required_argument, 0, 'r' },
+ { "timeout", required_argument, 0, 't' },
+ { 0 },
+ };
+
+ while ((c = getopt_long(argc, argv, "b:r:ht:", opts, NULL)) != -1) {
+ switch (c) {
+ case 'b':
+ ctx.bits = strtol(optarg, NULL, 0);
+ break;
+ case 'h':
+ show_usage(true);
+ return 0;
+ case 'r':
+ ctx.sample_rate = strtol(optarg, NULL, 0);
+ break;
+ case 't':
+ ctx.timeout = strtol(optarg, NULL, 0);
+ break;
+ default:
+ fprintf(stderr, "Try --help for more information.\n");
+ return 1;
+ }
+ }
+
+ /*
+ * If we don't have a timeout set then we need to force line
+ * buffering. This tool is often used in pipelines and
+ * terminated by ^C. Line buffering will reduce performance
+ * slightly. To avoid this penalty set a timeout and the
+ * buffers will be flushed whenever the timeout expires.
+ */
+ if (ctx.timeout == -1)
+ setvbuf(stdout, NULL, _IOLBF, 0);
+
+ if (optind >= argc) {
+ timestamp(&ctx, stdin);
+ } else while (optind < argc) {
+ FILE *f = fopen(argv[optind], "rb");
+
+ if (!f) {
+ fprintf(stderr, "Cannot open '%s' (%s)\n", argv[optind],
+ strerror(errno));
+ return 10;
+ }
+
+ timestamp(&ctx, f);
+
+ fclose(f);
+ optind++;
+ }
+
+ return 0;
+}
+
diff --git a/src/tts-uart.c b/src/tts-uart.c
new file mode 100644
index 0000000..32f8ae7
--- /dev/null
+++ b/src/tts-uart.c
@@ -0,0 +1,270 @@
+/*
+ * bin2tts.c
+ *
+ * Convert binary file to TTS (transisition/timestamp) format.
+ *
+ * Copyright (C) 2016 Daniel Thompson <daniel.thompson@linaro.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ */
+
+#include <assert.h>
+#include <errno.h>
+#include <getopt.h>
+#include <stdbool.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+struct ctx {
+ bool auto_baud;
+ int baud_rate;
+ uint32_t mask;
+ bool verbose;
+
+ double t_period;
+
+ double t_start;
+ double t_next;
+ double t_stop;
+ uint16_t frame;
+ int n_bits;
+
+ double t_prev;
+ double t_narrow;
+
+
+ bool prev_pin;
+};
+
+/*
+ *
+ * -------+ +-----+-----+-----+-----+-----+-----+-----+-----+-----+-------
+ * |START| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | P |STOP
+ * +-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+
+ *
+ * ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^
+ */
+
+void handle_start(struct ctx *ctx, double t_now)
+{
+ if (ctx->verbose)
+ fprintf(stderr, "[%10.6f] START\n", t_now);
+
+ ctx->t_start = t_now;
+ ctx->t_next = t_now + 1.501 * ctx->t_period;
+ ctx->t_stop = t_now + 9.409 * ctx->t_period;
+ ctx->frame = 0;
+ ctx->n_bits = 0;
+}
+
+void handle_data(struct ctx *ctx, bool pin, double t_now)
+{
+ while (ctx->t_next < t_now) {
+ if (ctx->verbose)
+ fprintf(stderr, "[%10.6f] D%d -> %d\n", ctx->t_next,
+ ctx->n_bits, pin);
+ ctx->frame = ctx->frame >> 1 | (pin ? 0x80 : 0);
+
+ ctx->t_next += ctx->t_period;
+ ctx->n_bits++;
+ }
+}
+
+void handle_stop(struct ctx *ctx)
+{
+ if (ctx->prev_pin) {
+ if (ctx->verbose) {
+ fprintf(stderr, "[%10.6f] STOP. Got 0x%02x\n", ctx->t_next, ctx->frame);
+ }
+ handle_data(ctx, 1, ctx->prev_pin);
+
+ putchar(ctx->frame);
+ fflush(stdout);
+ } else {
+ fprintf(stderr, "[%10.6f] Framing error\n", ctx->t_next);
+ }
+
+ ctx->t_start = 0;
+}
+
+void handle_error(struct ctx *ctx)
+{
+ fprintf(stderr, "[%10.6f] Framing error\n", ctx->t_stop);
+
+ ctx->t_start = 0;
+}
+
+void handle_edge(struct ctx *ctx, bool pin, double t_now)
+{
+ double t_pulse = t_now - ctx->t_prev;
+
+ assert(t_pulse >= 0);
+ if (pin != ctx->prev_pin)
+ if (t_pulse < ctx->t_narrow || ctx->t_narrow == 0)
+ ctx->t_narrow = t_pulse;
+
+ if (ctx->baud_rate) {
+ if (0 != ctx->t_start && t_now > ctx->t_stop)
+ handle_stop(ctx);
+
+ if (0 == ctx->t_start) {
+ if (!pin)
+ handle_start(ctx, t_now);
+ } else {
+ handle_data(ctx, ctx->prev_pin, t_now);
+ }
+ }
+
+ ctx->prev_pin = pin;
+ ctx->t_prev = t_now;
+}
+
+void do_auto_baud(struct ctx *ctx)
+{
+ int baud_rates[] = { 110, 300, 600, 1200, 2400, 4800,
+ 9600, 14400, 19200, 28800, 38400, 56000,
+ 57600, 115200,
+ 128000, 153600, 230400, 256000, 460800, 921600,
+ 0 };
+
+ /*
+ * At the moment we assume that beating between analyzer s/freq
+ * and baud rate mean that the quantized baud will been rounded
+ * *down* from the true narrowest pulse.
+ */
+ double quantized_baud = 1 / ctx->t_narrow;
+
+ int i;
+
+ for (i=0; baud_rates[i]; i++)
+ if (baud_rates[i] > quantized_baud)
+ break;
+
+ if (i == 0 || !baud_rates[i])
+ printf("Baud rate looks bad (%s signal?). Estimated at %d.\n",
+ i ? "noisy" : "no", (int)quantized_baud);
+ else
+ printf(
+ "Detected baud rate of %d (rounded from estimate of %d)\n",
+ baud_rates[i-1], (int) quantized_baud);
+}
+
+void decode(struct ctx *ctx, FILE *f)
+{
+ uint32_t seconds;
+ uint32_t nanoseconds;
+ double t;
+ uint32_t data;
+
+ ctx->t_period = 1.0 / ctx->baud_rate;
+ ctx->prev_pin = true;
+
+ while (!feof(f)) {
+ int res = fscanf(f, "[%5d.%09d] 0x%02x\n", &seconds,
+ &nanoseconds, &data);
+ if (res != 3) {
+ printf("Can't parse input: %d\n", res);
+ break;
+ }
+
+ t = (double) seconds + nanoseconds / 1000000000.0;
+ bool pin = data & ctx->mask;
+
+ if (ctx->verbose)
+ fprintf(stderr, "[%10.6f] Pin %d -> %d\n", t, ctx->prev_pin, pin);
+
+ handle_edge(ctx, pin, t);
+ }
+
+ if (ctx->auto_baud)
+ do_auto_baud(ctx);
+}
+
+void show_usage(bool full)
+{
+ FILE *f = full ? stdout : stderr;
+
+ fprintf(f, "Usage: tts-uart [OPTION]... [FILE]...\n");
+
+ if (!full) {
+ fprintf(f, "Try --help for more information.\n");
+ return;
+ }
+
+ fprintf(f,
+"\n"
+"Mandatory arguments to long options are mandatory for short options too.\n"
+" --auto-baud try to detect the baud rate\n"
+" -b, --baud-rate=B set the baud rate to B\n"
+" -h, --help show this help, then exit\n"
+" -m, --mask=M used to select the right bit for decoding\n"
+" -v, --verbose show timestamps for each bit\n"
+ );
+}
+
+int main(int argc, char *argv[])
+{
+ int c;
+ struct ctx ctx = {
+ .auto_baud = false,
+ .mask = 0x01,
+ };
+
+ const struct option opts[] = {
+ { "auto-baud", no_argument, 0, 256 },
+ { "baud-rate", required_argument, 0, 'b' },
+ { "help", no_argument, 0, 'h' },
+ { "mask", required_argument, 0, 'm' },
+ { "verbose", no_argument, 0, 'v' },
+ { 0 },
+ };
+
+ while ((c = getopt_long(argc, argv, "b:m:h", opts, NULL)) != -1) {
+ switch (c) {
+ case 256: // --auto-baud
+ ctx.auto_baud = true;
+ break;
+ case 'b':
+ ctx.baud_rate = strtol(optarg, NULL, 0);
+ break;
+ case 'h':
+ show_usage(true);
+ return 0;
+ case 'm':
+ ctx.mask = strtol(optarg, NULL, 0);
+ break;
+ case 'v':
+ ctx.verbose = true;
+ break;
+ default:
+ fprintf(stderr, "Try --help for more information.\n");
+ return 1;
+ }
+ }
+
+ if (optind >= argc) {
+ decode(&ctx, stdin);
+ } else while (optind < argc) {
+ FILE *f = fopen(argv[optind], "rb");
+
+ if (!f) {
+ fprintf(stderr, "Cannot open '%s' (%s)\n", argv[optind],
+ strerror(errno));
+ return 10;
+ }
+
+ decode(&ctx, f);
+
+ fclose(f);
+ optind++;
+ }
+
+ return 0;
+}
+
diff --git a/tests/This_is_a_test-1152008N1.sr b/tests/This_is_a_test-1152008N1.sr
new file mode 100644
index 0000000..f1e4f2d
--- /dev/null
+++ b/tests/This_is_a_test-1152008N1.sr
Binary files differ
diff --git a/tests/This_is_a_test-1152008N1.tts b/tests/This_is_a_test-1152008N1.tts
new file mode 100644
index 0000000..ce0b6e7
--- /dev/null
+++ b/tests/This_is_a_test-1152008N1.tts
@@ -0,0 +1,375 @@
+[ 0.000000000] 0xff
+[ 0.010000000] 0xff
+[ 1.382702000] 0xfd
+[ 1.382728000] 0xff
+[ 1.382737000] 0xfd
+[ 1.382745000] 0xff
+[ 1.382754000] 0xfd
+[ 1.382763000] 0xff
+[ 1.382771000] 0xfd
+[ 1.382780000] 0xff
+[ 1.392780000] 0xff
+[ 1.582790000] 0xfd
+[ 1.582825000] 0xff
+[ 1.582834000] 0xfd
+[ 1.582842000] 0xff
+[ 1.582860000] 0xfd
+[ 1.582868000] 0xff
+[ 1.592868000] 0xff
+[ 1.638754000] 0xfd
+[ 1.638763000] 0xff
+[ 1.638772000] 0xfd
+[ 1.638789000] 0xff
+[ 1.638798000] 0xfd
+[ 1.638806000] 0xff
+[ 1.638824000] 0xfd
+[ 1.638832000] 0xff
+[ 1.648832000] 0xff
+[ 1.782806000] 0xfd
+[ 1.782815000] 0xff
+[ 1.782832000] 0xfd
+[ 1.782849000] 0xff
+[ 1.782875000] 0xfd
+[ 1.782884000] 0xff
+[ 1.792884000] 0xff
+[ 1.886826000] 0xfd
+[ 1.886878000] 0xff
+[ 1.886887000] 0xfd
+[ 1.886904000] 0xff
+[ 1.896904000] 0xff
+[ 2.038795000] 0xfd
+[ 2.038804000] 0xff
+[ 2.038813000] 0xfd
+[ 2.038830000] 0xff
+[ 2.038839000] 0xfd
+[ 2.038847000] 0xff
+[ 2.038865000] 0xfd
+[ 2.038873000] 0xff
+[ 2.048873000] 0xff
+[ 2.118799000] 0xfd
+[ 2.118808000] 0xff
+[ 2.118825000] 0xfd
+[ 2.118842000] 0xff
+[ 2.118868000] 0xfd
+[ 2.118877000] 0xff
+[ 2.128877000] 0xff
+[ 2.238789000] 0xfd
+[ 2.238841000] 0xff
+[ 2.238850000] 0xfd
+[ 2.238867000] 0xff
+[ 2.248867000] 0xff
+[ 2.334798000] 0xfd
+[ 2.334806000] 0xff
+[ 2.334815000] 0xfd
+[ 2.334850000] 0xff
+[ 2.334867000] 0xfd
+[ 2.334876000] 0xff
+[ 2.344876000] 0xff
+[ 2.414892000] 0xfd
+[ 2.414944000] 0xff
+[ 2.414953000] 0xfd
+[ 2.414970000] 0xff
+[ 2.424970000] 0xff
+[ 2.606839000] 0xfd
+[ 2.606864000] 0xff
+[ 2.606873000] 0xfd
+[ 2.606882000] 0xff
+[ 2.606908000] 0xfd
+[ 2.606916000] 0xff
+[ 2.616916000] 0xff
+[ 2.702844000] 0xfd
+[ 2.702852000] 0xff
+[ 2.702861000] 0xfd
+[ 2.702870000] 0xff
+[ 2.702878000] 0xfd
+[ 2.702896000] 0xff
+[ 2.702913000] 0xfd
+[ 2.702922000] 0xff
+[ 2.712922000] 0xff
+[ 2.871609000] 0xfd
+[ 2.871618000] 0xff
+[ 2.871635000] 0xfd
+[ 2.871653000] 0xff
+[ 2.871679000] 0xfd
+[ 2.871687000] 0xff
+[ 2.881687000] 0xff
+[ 3.046872000] 0xfd
+[ 3.046898000] 0xff
+[ 3.046906000] 0xfd
+[ 3.046915000] 0xff
+[ 3.046941000] 0xfd
+[ 3.046950000] 0xff
+[ 3.056950000] 0xff
+[ 3.958983000] 0xfd
+[ 3.958991000] 0xff
+[ 3.959000000] 0xfd
+[ 3.959009000] 0xff
+[ 3.959026000] 0xfd
+[ 3.959061000] 0xff
+[ 3.959069000] 0xfd
+[ 3.959087000] 0xff
+[ 3.959095000] 0xfd
+[ 3.959104000] 0xff
+[ 3.959113000] 0xfd
+[ 3.959147000] 0xff
+[ 3.959156000] 0xfd
+[ 3.959165000] 0xff
+[ 3.959173000] 0xfd
+[ 3.959182000] 0xff
+[ 3.959199000] 0xfd
+[ 3.959234000] 0xff
+[ 3.959243000] 0xfd
+[ 3.959251000] 0xff
+[ 3.959260000] 0xfd
+[ 3.959269000] 0xff
+[ 3.959277000] 0xfd
+[ 3.959286000] 0xff
+[ 3.959295000] 0xfd
+[ 3.959303000] 0xff
+[ 3.959312000] 0xfd
+[ 3.959321000] 0xff
+[ 3.959329000] 0xfd
+[ 3.959347000] 0xff
+[ 3.959373000] 0xfd
+[ 3.959381000] 0xff
+[ 3.959399000] 0xfd
+[ 3.959407000] 0xff
+[ 3.959416000] 0xfd
+[ 3.959425000] 0xff
+[ 3.959442000] 0xfd
+[ 3.959451000] 0xff
+[ 3.959460000] 0xfd
+[ 3.959468000] 0xff
+[ 3.959486000] 0xfd
+[ 3.959494000] 0xff
+[ 3.959503000] 0xfd
+[ 3.959520000] 0xff
+[ 3.959546000] 0xfd
+[ 3.959555000] 0xff
+[ 3.959572000] 0xfd
+[ 3.959581000] 0xff
+[ 3.959590000] 0xfd
+[ 3.959598000] 0xff
+[ 3.959633000] 0xfd
+[ 3.959641000] 0xff
+[ 3.959659000] 0xfd
+[ 3.959667000] 0xff
+[ 3.959676000] 0xfd
+[ 3.959685000] 0xff
+[ 3.959711000] 0xfd
+[ 3.959719000] 0xff
+[ 3.959746000] 0xfd
+[ 3.959754000] 0xff
+[ 3.959763000] 0xfd
+[ 3.959780000] 0xff
+[ 3.959806000] 0xfd
+[ 3.959815000] 0xff
+[ 3.959832000] 0xfd
+[ 3.959841000] 0xff
+[ 3.959850000] 0xfd
+[ 3.959901000] 0xff
+[ 3.959910000] 0xfd
+[ 3.959927000] 0xff
+[ 3.959936000] 0xfd
+[ 3.959945000] 0xff
+[ 3.959962000] 0xfd
+[ 3.959988000] 0xff
+[ 3.960006000] 0xfd
+[ 3.960014000] 0xff
+[ 3.960023000] 0xfd
+[ 3.960032000] 0xff
+[ 3.960066000] 0xfd
+[ 3.960075000] 0xff
+[ 3.960092000] 0xfd
+[ 3.960101000] 0xff
+[ 3.960110000] 0xfd
+[ 3.960118000] 0xff
+[ 3.960127000] 0xfd
+[ 3.960136000] 0xff
+[ 3.960153000] 0xfd
+[ 3.960162000] 0xff
+[ 3.960179000] 0xfd
+[ 3.960188000] 0xff
+[ 3.960196000] 0xfd
+[ 3.960205000] 0xff
+[ 3.960214000] 0xfd
+[ 3.960222000] 0xff
+[ 3.960240000] 0xfd
+[ 3.960248000] 0xff
+[ 3.960266000] 0xfd
+[ 3.960274000] 0xff
+[ 3.960283000] 0xfd
+[ 3.960292000] 0xff
+[ 3.960300000] 0xfd
+[ 3.960335000] 0xff
+[ 3.960352000] 0xfd
+[ 3.960361000] 0xff
+[ 3.960370000] 0xfd
+[ 3.960387000] 0xff
+[ 3.960413000] 0xfd
+[ 3.960422000] 0xff
+[ 3.960439000] 0xfd
+[ 3.960448000] 0xff
+[ 3.960456000] 0xfd
+[ 3.960482000] 0xff
+[ 3.960491000] 0xfd
+[ 3.960508000] 0xff
+[ 3.960526000] 0xfd
+[ 3.960534000] 0xff
+[ 3.960543000] 0xfd
+[ 3.960595000] 0xff
+[ 3.960604000] 0xfd
+[ 3.960621000] 0xff
+[ 3.960630000] 0xfd
+[ 3.960638000] 0xff
+[ 3.960664000] 0xfd
+[ 3.960682000] 0xff
+[ 3.960690000] 0xfd
+[ 3.960708000] 0xff
+[ 3.960716000] 0xfd
+[ 3.960742000] 0xff
+[ 3.960751000] 0xfd
+[ 3.960760000] 0xff
+[ 3.960768000] 0xfd
+[ 3.960777000] 0xff
+[ 3.960786000] 0xfd
+[ 3.960794000] 0xff
+[ 3.960803000] 0xfd
+[ 3.960838000] 0xff
+[ 3.960846000] 0xfd
+[ 3.960855000] 0xff
+[ 3.960872000] 0xfd
+[ 3.960881000] 0xff
+[ 3.960890000] 0xfd
+[ 3.960898000] 0xff
+[ 3.960907000] 0xfd
+[ 3.960924000] 0xff
+[ 3.960933000] 0xfd
+[ 3.960942000] 0xff
+[ 3.960959000] 0xfd
+[ 3.960968000] 0xff
+[ 3.960976000] 0xfd
+[ 3.960985000] 0xff
+[ 3.961002000] 0xfd
+[ 3.961020000] 0xff
+[ 3.961046000] 0xfd
+[ 3.961054000] 0xff
+[ 3.961063000] 0xfd
+[ 3.961072000] 0xff
+[ 3.961098000] 0xfd
+[ 3.961115000] 0xff
+[ 3.961124000] 0xfd
+[ 3.961141000] 0xff
+[ 3.961150000] 0xfd
+[ 3.961202000] 0xff
+[ 3.961210000] 0xfd
+[ 3.961228000] 0xff
+[ 3.961236000] 0xfd
+[ 3.961245000] 0xff
+[ 3.961254000] 0xfd
+[ 3.961262000] 0xff
+[ 3.961280000] 0xfd
+[ 3.961288000] 0xff
+[ 3.961297000] 0xfd
+[ 3.961314000] 0xff
+[ 3.961323000] 0xfd
+[ 3.961375000] 0xff
+[ 3.961384000] 0xfd
+[ 3.961401000] 0xff
+[ 3.961410000] 0xfd
+[ 3.961436000] 0xff
+[ 3.961444000] 0xfd
+[ 3.961453000] 0xff
+[ 3.961479000] 0xfd
+[ 3.961488000] 0xff
+[ 3.961496000] 0xfd
+[ 3.961514000] 0xff
+[ 3.961522000] 0xfd
+[ 3.961540000] 0xff
+[ 3.961566000] 0xfd
+[ 3.961574000] 0xff
+[ 3.961583000] 0xfd
+[ 3.961592000] 0xff
+[ 3.961600000] 0xfd
+[ 3.961618000] 0xff
+[ 3.961652000] 0xfd
+[ 3.961661000] 0xff
+[ 3.961670000] 0xfd
+[ 3.961722000] 0xff
+[ 3.961730000] 0xfd
+[ 3.961748000] 0xff
+[ 3.961756000] 0xfd
+[ 3.961765000] 0xff
+[ 3.961791000] 0xfd
+[ 3.961808000] 0xff
+[ 3.961817000] 0xfd
+[ 3.961834000] 0xff
+[ 3.961843000] 0xfd
+[ 3.961878000] 0xff
+[ 3.961886000] 0xfd
+[ 3.961895000] 0xff
+[ 3.961912000] 0xfd
+[ 3.961921000] 0xff
+[ 3.961930000] 0xfd
+[ 3.961938000] 0xff
+[ 3.961947000] 0xfd
+[ 3.961956000] 0xff
+[ 3.961964000] 0xfd
+[ 3.961982000] 0xff
+[ 3.961999000] 0xfd
+[ 3.962008000] 0xff
+[ 3.962016000] 0xfd
+[ 3.962042000] 0xff
+[ 3.962060000] 0xfd
+[ 3.962068000] 0xff
+[ 3.962086000] 0xfd
+[ 3.962094000] 0xff
+[ 3.962103000] 0xfd
+[ 3.962146000] 0xff
+[ 3.962172000] 0xfd
+[ 3.962181000] 0xff
+[ 3.962190000] 0xfd
+[ 3.962198000] 0xff
+[ 3.962224000] 0xfd
+[ 3.962242000] 0xff
+[ 3.962250000] 0xfd
+[ 3.962268000] 0xff
+[ 3.962276000] 0xfd
+[ 3.962294000] 0xff
+[ 3.962302000] 0xfd
+[ 3.962311000] 0xff
+[ 3.962320000] 0xfd
+[ 3.962354000] 0xff
+[ 3.962363000] 0xfd
+[ 3.962372000] 0xff
+[ 3.962380000] 0xfd
+[ 3.962389000] 0xff
+[ 3.962406000] 0xfd
+[ 3.962441000] 0xff
+[ 3.962450000] 0xfd
+[ 3.962458000] 0xff
+[ 3.962493000] 0xfd
+[ 3.962502000] 0xff
+[ 3.962519000] 0xfd
+[ 3.962528000] 0xff
+[ 3.962536000] 0xfd
+[ 3.962545000] 0xff
+[ 3.962571000] 0xfd
+[ 3.962580000] 0xff
+[ 3.962606000] 0xfd
+[ 3.962614000] 0xff
+[ 3.962623000] 0xfd
+[ 3.962649000] 0xff
+[ 3.962666000] 0xfd
+[ 3.962675000] 0xff
+[ 3.962692000] 0xfd
+[ 3.962701000] 0xff
+[ 3.962710000] 0xfd
+[ 3.962727000] 0xff
+[ 3.962771000] 0xfd
+[ 3.962788000] 0xff
+[ 3.962797000] 0xfd
+[ 3.962848000] 0xff
+[ 3.962857000] 0xfd
+[ 3.962874000] 0xff
+[ 3.972874000] 0xff