From c124e1a819fc7c5b4662c8ee305df5309a6a4024 Mon Sep 17 00:00:00 2001 From: Werner Almesberger Date: Wed, 16 Jan 2013 01:11:57 -0300 Subject: [PATCH] ubb-patgen/ubb-patgen.c: accept SI suffixes and a unit for durations as well --- ubb-patgen/README | 5 ++++ ubb-patgen/ubb-patgen.c | 58 ++++++++++++++++++++++++++++++++++++----- 2 files changed, 56 insertions(+), 7 deletions(-) diff --git a/ubb-patgen/README b/ubb-patgen/README index 00e7ac3..21c8934 100644 --- a/ubb-patgen/README +++ b/ubb-patgen/README @@ -77,6 +77,11 @@ while and clean up on exit, add the delay in seconds, e.g.: # ubb-patgen -f 500kHz -c 10 +The delay can be followed by "m", "u", or "n" for the respective +multiplier. Furthermore, it can end with an optional "s". Note +that the minimum time ubb-patgen actually spends generating a +clock will typically be in the order of several milliseconds. + To stop the MMC bus clock, run # ubb-patgen -c 0 diff --git a/ubb-patgen/ubb-patgen.c b/ubb-patgen/ubb-patgen.c index d445430..bdc2772 100644 --- a/ubb-patgen/ubb-patgen.c +++ b/ubb-patgen/ubb-patgen.c @@ -465,6 +465,9 @@ static int frequency(const char *s, int *hz, int *rel) f = strtod(s, &end); + if (end == s || f < 0) + return 0; + switch (*end) { case 'M': case 'm': @@ -503,6 +506,49 @@ static int frequency(const char *s, int *hz, int *rel) } +static int duration(const char *s, struct timespec *res) +{ + char *end; + double d; + + d = strtod(s, &end); + + if (end == s || d < 0) + return 0; + + switch (*end) { + case 'M': + case 'm': + d /= 1e3; + end++; + break; + case 'U': + case 'u': + d /= 1e6; + end++; + break; + case 'N': + case 'n': + d /= 1e9; + end++; + break; + default: + break; + } + + if (*end == 'S' || *end == 's') + end++; + + if (*end) + return 0; + + res->tv_sec = d; + res->tv_nsec = (d-res->tv_sec)*1e9; + + return 1; +} + + static void usage(const char *name) { fprintf(stderr, @@ -523,10 +569,12 @@ static void usage(const char *name) " (default: exit immediately but leave the clock on)\n" " file file containing the pattern\n" " pattern send the specified pattern on DAT0 through DAT3\n\n" -"Frequency: the frequency in Hz, optionally followed by \"M\" or \"k\",\n" +"Frequency: the frequency in hertz, optionally followed by \"M\" or \"k\",\n" " optionally followed by \"Hz\", optionally followed by \"+\" or \"-\".\n" " \"+\" 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" "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); @@ -540,7 +588,6 @@ int main(int argc, char **argv) int bus_hz = 0, clk_only = 0, clkout = 0, bus_rel = 0; const char *pattern = NULL; int quiet = 0, force_pattern = 0; - double active_s = 0; struct timespec active_ns; int keep_clk = 1; uint8_t mask = 0xf; @@ -617,11 +664,8 @@ int main(int argc, char **argv) if (clk_only) { if (force_pattern) usage(*argv); - active_s = strtod(argv[argc-1], &end); - if (*end) + if (!duration(argv[optind], &active_ns)) usage(*argv); - active_ns.tv_sec = (int) active_s; - active_ns.tv_nsec = (active_s-(int) active_s)*1e9; keep_clk = 0; } else { pattern = argv[optind]; @@ -653,7 +697,7 @@ int main(int argc, char **argv) if (pattern) dma_pattern(&clk, pattern, mask << 10, trigger); - if (active_s) + if (!keep_clk) if (nanosleep(&active_ns, NULL)) perror("nanosleep"); if (pattern) {