diff --git a/ubb-patgen/ubb-patgen.c b/ubb-patgen/ubb-patgen.c index 241ce4e..555761f 100644 --- a/ubb-patgen/ubb-patgen.c +++ b/ubb-patgen/ubb-patgen.c @@ -310,7 +310,7 @@ static void wait_shifted(const struct mmcclk *clk) static void mmc_buffer(const struct mmcclk *clk, - uint8_t first, unsigned long buf, int nibbles, uint32_t mask) + uint8_t first, unsigned long buf, int nibbles, uint32_t mask, int trigger) { /* * If under control of the MMC controller, DATx tri-state until we @@ -355,6 +355,9 @@ static void mmc_buffer(const struct mmcclk *clk, PDFUNS = mask; + if (trigger != -1) + while (PIN(UBB_CLK) != trigger); + /* * Send the pattern with DMA. Note that we still have to send the first * pattern, since the static state we begin from may not have been @@ -380,7 +383,7 @@ 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) + const uint8_t *buf, int nibbles, uint32_t mask, int trigger) { unsigned long phys; @@ -392,12 +395,12 @@ static void send_buffer(const struct mmcclk *clk, asm("sync"); /* flush the write buffer */ phys = physmem_xlat((void *) buf); - mmc_buffer(clk, buf[0] >> 4, phys, nibbles, mask); + mmc_buffer(clk, buf[0] >> 4, phys, nibbles, mask, trigger); } static void dma_pattern(const struct mmcclk *clk, - const char *pattern, uint32_t mask) + const char *pattern, uint32_t mask, int trigger) { const uint8_t *buf; int n; @@ -413,6 +416,11 @@ static void dma_pattern(const struct mmcclk *clk, exit(1); } + if (trigger != -1) { + PDFUNC = UBB_CLK; + IN(UBB_CLK); + } + dma_init(); /* Initial static state: the first pattern. */ @@ -422,7 +430,7 @@ static void dma_pattern(const struct mmcclk *clk, PDDATS = (buf[0] >> 4) << 10; PDDIRS = mask; - send_buffer(clk, buf, n, mask); + send_buffer(clk, buf, n, mask, trigger); /* Final static state: the last pattern. */ @@ -489,14 +497,16 @@ static void usage(const char *name) "usage: %s\n" " %s [-q] -f freq_hz\n" " %s [-q] [-f freq_hz] -c [active_s]\n" -" %s [-q] [-f freq_hz] [-C] [-m mask] [-p] file|pattern\n\n" +" %s [-q] [-f freq_hz] [-C|-t 0|1] [-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" " -f freq_hz set bus clock to the specified frequency (default: 1 MHz)\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" -" differences.\n\n" +" differences.\n" +" -t 0|1 start pattern when trigger/CLK becomes 0 or 1 respectively\n" +" (default: start pattern immediately)\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" @@ -522,11 +532,12 @@ int main(int argc, char **argv) struct timespec active_ns; int keep_clk = 1; uint8_t mask = 0xf; + int trigger = -1; char *end; int c; unsigned long tmp; - while ((c = getopt(argc, argv, "cCf:m:pq")) != EOF) + while ((c = getopt(argc, argv, "cCf:m:pqt:")) != EOF) switch (c) { case 'f': if (!frequency(optarg, &bus_hz, &bus_rel)) @@ -554,18 +565,28 @@ int main(int argc, char **argv) case 'q': quiet = 1; break; + case 't': + if (!strcmp(optarg, "0")) + trigger = 0; + else if (!strcmp(optarg, "1")) + trigger = 1; + else + usage(*argv); + break; default: usage(*argv); } if (clkout && clk_only) usage(*argv); + if ((clkout || clk_only) && trigger != -1) + usage(*argv); switch (argc-optind) { case 0: if (clk_only) break; - if (clkout || force_pattern) + if (clkout || force_pattern || trigger != -1) usage(*argv); ubb_open(UBB_ALL); @@ -629,14 +650,14 @@ int main(int argc, char **argv) mmcclk_start(&clk); if (pattern) - dma_pattern(&clk, pattern, mask << 10); + dma_pattern(&clk, pattern, mask << 10, trigger); if (active_s) if (nanosleep(&active_ns, NULL)) perror("nanosleep"); if (pattern) { mmcclk_stop(); - ubb_close(mask << 10); + ubb_close(mask << 10 | (trigger == -1 ? 0 : UBB_CLK)); } else if (keep_clk) { ubb_close(UBB_CLK); } else {