diff --git a/ubb-patgen/README b/ubb-patgen/README index 692bd22..5d74f19 100644 --- a/ubb-patgen/README +++ b/ubb-patgen/README @@ -154,7 +154,10 @@ Likewise, -t 1 waits for CLK to become 1. -t cannot be used with the -C option. ubb-patgen usually starts the pattern about 2-10 us after the -trigger, but this can be delayed by other system activity. +trigger, but this can be delayed by other system activity. An +extra delay can be added with the option -w, e.g., + +# ubb-patgen -t 0 -w 1s 010 The trigger signal can be debounced with the option -d, e.g., diff --git a/ubb-patgen/ubb-patgen.c b/ubb-patgen/ubb-patgen.c index 06afbf6..64bea5a 100644 --- a/ubb-patgen/ubb-patgen.c +++ b/ubb-patgen/ubb-patgen.c @@ -363,7 +363,8 @@ static void wait_trigger(int trigger, int debounce, static void mmc_buffer(const struct mmcclk *clk, uint8_t first, unsigned long buf, int nibbles, uint32_t mask, - int trigger, int debounce, const struct timespec *debounce_ns) + int trigger, int debounce, const struct timespec *debounce_ns, + const struct timespec *wait_ns) { /* * If under control of the MMC controller, DATx tri-state until we @@ -410,6 +411,9 @@ static void mmc_buffer(const struct mmcclk *clk, if (trigger != -1) wait_trigger(trigger, debounce, debounce_ns); + if (wait_ns->tv_sec || wait_ns->tv_nsec) + if (nanosleep(wait_ns, NULL)) + perror("nanosleep"); /* * Send the pattern with DMA. Note that we still have to send the first @@ -437,7 +441,8 @@ static void mmc_buffer(const struct mmcclk *clk, static void send_buffer(const struct mmcclk *clk, const uint8_t *buf, int nibbles, uint32_t mask, - int trigger, int debounce, const struct timespec *debounce_ns) + int trigger, int debounce, const struct timespec *debounce_ns, + const struct timespec *wait_ns) { unsigned long phys; @@ -448,13 +453,14 @@ static void send_buffer(const struct mmcclk *clk, phys = physmem_xlat((void *) buf); mmc_buffer(clk, buf[0] >> 4, phys, nibbles, mask, - trigger, debounce, debounce_ns); + trigger, debounce, debounce_ns, wait_ns); } static void dma_pattern(const struct mmcclk *clk, const char *pattern, uint32_t mask, int trigger, - int debounce, const struct timespec *debounce_ns) + int debounce, const struct timespec *debounce_ns, + const struct timespec *wait_ns) { const uint8_t *buf; int n; @@ -484,7 +490,8 @@ static void dma_pattern(const struct mmcclk *clk, PDDATS = (buf[0] >> 4) << 10; PDDIRS = mask; - send_buffer(clk, buf, n, mask, trigger, debounce, debounce_ns); + send_buffer(clk, buf, n, mask, + trigger, debounce, debounce_ns, wait_ns); /* Final static state: the last pattern. */ @@ -635,7 +642,7 @@ static void usage(const char *name) " %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 [-d debounce_s]]\n" -" [-m mask] [-p] file|pattern\n\n" +" [-w wait_s] [-m mask] [-p] 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" " -d deb_s trigger debounce time (default: no debouncing)\n" @@ -647,7 +654,8 @@ static void usage(const char *name) " -q quiet. Don't pretty-print frequencies; don't report clock\n" " differences.\n" " -t 0|1 start pattern when trigger/CLK becomes 0 or 1 respectively\n" -" (default: start pattern immediately)\n\n" +" (default: start pattern immediately)\n" +" -w wait_s wait between trigger and sending the pattern\n\n" " active_s keep running that many seconds after setting the clock\n" " (default: exit immediately but leave the clock on)\n" " file file containing the pattern\n" @@ -679,11 +687,13 @@ int main(int argc, char **argv) int trigger = -1; struct timespec debounce_ns; int debounce = 0, debounce_rel; + struct timespec wait_ns = { 0, 0 }; + int wait_rel; char *end; int c; unsigned long tmp; - while ((c = getopt(argc, argv, "cCd:f:i:m:pqt:")) != EOF) + while ((c = getopt(argc, argv, "cCd:f:i:m:pqt:w:")) != EOF) switch (c) { case 'f': if (!frequency(optarg, &bus_hz, &bus_rel)) @@ -731,6 +741,13 @@ int main(int argc, char **argv) else usage(*argv); break; + case 'w': + if (!duration_timespec(optarg, + &wait_ns, &wait_rel)) + usage(*argv); + if (wait_rel < 0) + usage(*argv); + break; default: usage(*argv); } @@ -798,7 +815,7 @@ int main(int argc, char **argv) if (pattern) dma_pattern(&clk, pattern, mask << 10, - trigger, debounce, &debounce_ns); + trigger, debounce, &debounce_ns, &wait_ns); if (!keep_clk) if (nanosleep(&active_ns, NULL))