From 39f4e48f8d98a96f06bcaa75f3032af1d6d1224a Mon Sep 17 00:00:00 2001 From: Werner Almesberger Date: Wed, 16 Jan 2013 01:58:16 -0300 Subject: [PATCH] ubb-patgen/ubb-patgen.c: new option -i to select frequency by cycle time --- ubb-patgen/README | 8 ++++++ ubb-patgen/ubb-patgen.c | 63 ++++++++++++++++++++++++++++++++++++----- 2 files changed, 64 insertions(+), 7 deletions(-) diff --git a/ubb-patgen/README b/ubb-patgen/README index 21c8934..24ee456 100644 --- a/ubb-patgen/README +++ b/ubb-patgen/README @@ -63,6 +63,14 @@ bus clk = 100.962 kHz (+0.96%) This warning can be suppressed with the option -q. +The frequency can also be specified as the cycle time with the +option -i: + +# ubb-patgen -i 10us + +The meaning of an appended + or - changes here, e.g., 10us+ +selects a slower clock (producing an interval of at least 10 us). + Clock output ------------ diff --git a/ubb-patgen/ubb-patgen.c b/ubb-patgen/ubb-patgen.c index bdc2772..e38c50b 100644 --- a/ubb-patgen/ubb-patgen.c +++ b/ubb-patgen/ubb-patgen.c @@ -506,7 +506,7 @@ static int frequency(const char *s, int *hz, int *rel) } -static int duration(const char *s, struct timespec *res) +static int duration(const char *s, double *res, int *rel) { char *end; double d; @@ -539,12 +539,49 @@ static int duration(const char *s, struct timespec *res) if (*end == 'S' || *end == 's') end++; + switch (*end) { + case '+': + *rel = 1; + end++; + break; + case '-': + *rel = -1; + end++; + break; + default: + *rel = 0; + break; + } + if (*end) return 0; + *res = d; + + return 1; +} + + +static int duration_timespec(const char *s, struct timespec *res, int *rel) +{ + double d; + + if (!duration(s, &d, rel)) + return 0; res->tv_sec = d; res->tv_nsec = (d-res->tv_sec)*1e9; + return 1; +} + +static int interval(const char *s, int *hz, int *rel) +{ + double d; + + if (!duration(s, &d, rel)) + return 0; + *hz = 1/d; + *rel = -*rel; return 1; } @@ -553,12 +590,15 @@ static void usage(const char *name) { fprintf(stderr, "usage: %s\n" -" %s [-q] -f freq_hz\n" -" %s [-q] [-f freq_hz] -c [active_s]\n" -" %s [-q] [-f freq_hz] [-C|-t 0|1] [-m mask] [-p] file|pattern\n\n" +" %s [-q] -f freq_hz|-i interval_s\n" +" %s [-q] [-f freq_hz|-i interval_s] -c [active_s]\n" +" %s [-q] [-f freq_hz|-i interval_s] [-C|-t 0|1] [-m mask] [-p]\n" +" file|pattern\n\n" " -c output bus clock on CLK without sending a pattern\n" " -C temporarily output bus clock on CLK (for debugging)\n" " -f freq_hz set bus clock to the specified frequency (default: 1 MHz)\n" +" -i inter_s set bus clock such that one cycle equals the specified " + "interval\n" " -m mask use only the DATx lines specified in the mask (default: 0xf)\n" " -p force interpretation of argument as pattern (and not file)\n" " -q quiet. Don't pretty-print frequencies; don't report clock\n" @@ -574,7 +614,8 @@ static void usage(const char *name) " \"+\" selects a frequency >= the specified one, \"-\" one <=.\n" " Without +/-, the closest available frequency is selected.\n" "Duration: the duration in seconds, optionally followed by \"m\", \"u\", or\n" -" \"n\", optionally followed by \"s\".\n" +" \"n\", optionally followed by \"s\", optionally followed by \"+\" or \"-\"." + "\n" "Pattern: hex digits corresponding to 1 for DAT0, 2 for DAT1, etc.\n" " {n} repeats the preceding digit n times, e.g., 1{3} is equivalent to 111.\n" , name, name, name, name); @@ -589,6 +630,7 @@ int main(int argc, char **argv) const char *pattern = NULL; int quiet = 0, force_pattern = 0; struct timespec active_ns; + int active_rel = 0; int keep_clk = 1; uint8_t mask = 0xf; int trigger = -1; @@ -596,12 +638,16 @@ int main(int argc, char **argv) int c; unsigned long tmp; - while ((c = getopt(argc, argv, "cCf:m:pqt:")) != EOF) + while ((c = getopt(argc, argv, "cCf:i:m:pqt:")) != EOF) switch (c) { case 'f': if (!frequency(optarg, &bus_hz, &bus_rel)) usage(*argv); break; + case 'i': + if (!interval(optarg, &bus_hz, &bus_rel)) + usage(*argv); + break; case 'c': clk_only = 1; break; @@ -664,7 +710,10 @@ int main(int argc, char **argv) if (clk_only) { if (force_pattern) usage(*argv); - if (!duration(argv[optind], &active_ns)) + if (!duration_timespec(argv[optind], + &active_ns, &active_rel)) + usage(*argv); + if (active_rel < 0) usage(*argv); keep_clk = 0; } else {