diff options
-rw-r--r-- | .gitignore | 4 | ||||
-rw-r--r-- | Makefile | 15 | ||||
-rw-r--r-- | README.md | 26 | ||||
-rw-r--r-- | src/.bin2tts.c.swp | bin | 0 -> 16384 bytes | |||
-rw-r--r-- | src/.tts-uart.c.swp | bin | 0 -> 20480 bytes | |||
-rw-r--r-- | src/bin2tts.c | 159 | ||||
-rw-r--r-- | src/tts-uart.c | 270 | ||||
-rw-r--r-- | tests/This_is_a_test-1152008N1.sr | bin | 0 -> 6925 bytes | |||
-rw-r--r-- | tests/This_is_a_test-1152008N1.tts | 375 |
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 Binary files differnew file mode 100644 index 0000000..594c5e1 --- /dev/null +++ b/src/.bin2tts.c.swp diff --git a/src/.tts-uart.c.swp b/src/.tts-uart.c.swp Binary files differnew file mode 100644 index 0000000..73631eb --- /dev/null +++ b/src/.tts-uart.c.swp 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 Binary files differnew file mode 100644 index 0000000..f1e4f2d --- /dev/null +++ b/tests/This_is_a_test-1152008N1.sr 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 |