1
0
mirror of git://projects.qi-hardware.com/ben-blinkenlights.git synced 2024-11-27 16:05:20 +02:00

ubb-patgen/ubb-patgen.c: new option -t 0|1 to start pattern on TRIGGER/CLK

The trigger delay is typically in the order of 2 us but, since we're not
disabling interrupts or such, could also be much larger.
This commit is contained in:
Werner Almesberger 2013-01-15 18:40:16 -03:00
parent 10b0dea29c
commit 0bb711e625

View File

@ -310,7 +310,7 @@ static void wait_shifted(const struct mmcclk *clk)
static void mmc_buffer(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 * 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; PDFUNS = mask;
if (trigger != -1)
while (PIN(UBB_CLK) != trigger);
/* /*
* Send the pattern with DMA. Note that we still have to send the first * 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 * 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, 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; unsigned long phys;
@ -392,12 +395,12 @@ static void send_buffer(const struct mmcclk *clk,
asm("sync"); /* flush the write buffer */ asm("sync"); /* flush the write buffer */
phys = physmem_xlat((void *) buf); 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, 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; const uint8_t *buf;
int n; int n;
@ -413,6 +416,11 @@ static void dma_pattern(const struct mmcclk *clk,
exit(1); exit(1);
} }
if (trigger != -1) {
PDFUNC = UBB_CLK;
IN(UBB_CLK);
}
dma_init(); dma_init();
/* Initial static state: the first pattern. */ /* Initial static state: the first pattern. */
@ -422,7 +430,7 @@ static void dma_pattern(const struct mmcclk *clk,
PDDATS = (buf[0] >> 4) << 10; PDDATS = (buf[0] >> 4) << 10;
PDDIRS = mask; PDDIRS = mask;
send_buffer(clk, buf, n, mask); send_buffer(clk, buf, n, mask, trigger);
/* Final static state: the last pattern. */ /* Final static state: the last pattern. */
@ -489,14 +497,16 @@ static void usage(const char *name)
"usage: %s\n" "usage: %s\n"
" %s [-q] -f freq_hz\n" " %s [-q] -f freq_hz\n"
" %s [-q] [-f freq_hz] -c [active_s]\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 output bus clock on CLK without sending a pattern\n"
" -C temporarily output bus clock on CLK (for debugging)\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" " -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" " -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" " -p force interpretation of argument as pattern (and not file)\n"
" -q quiet. Don't pretty-print frequencies; don't report clock\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" " active_s keep running that many seconds after setting the clock\n"
" (default: exit immediately but leave the clock on)\n" " (default: exit immediately but leave the clock on)\n"
" file file containing the pattern\n" " file file containing the pattern\n"
@ -522,11 +532,12 @@ int main(int argc, char **argv)
struct timespec active_ns; struct timespec active_ns;
int keep_clk = 1; int keep_clk = 1;
uint8_t mask = 0xf; uint8_t mask = 0xf;
int trigger = -1;
char *end; char *end;
int c; int c;
unsigned long tmp; unsigned long tmp;
while ((c = getopt(argc, argv, "cCf:m:pq")) != EOF) while ((c = getopt(argc, argv, "cCf:m:pqt:")) != EOF)
switch (c) { switch (c) {
case 'f': case 'f':
if (!frequency(optarg, &bus_hz, &bus_rel)) if (!frequency(optarg, &bus_hz, &bus_rel))
@ -554,18 +565,28 @@ int main(int argc, char **argv)
case 'q': case 'q':
quiet = 1; quiet = 1;
break; break;
case 't':
if (!strcmp(optarg, "0"))
trigger = 0;
else if (!strcmp(optarg, "1"))
trigger = 1;
else
usage(*argv);
break;
default: default:
usage(*argv); usage(*argv);
} }
if (clkout && clk_only) if (clkout && clk_only)
usage(*argv); usage(*argv);
if ((clkout || clk_only) && trigger != -1)
usage(*argv);
switch (argc-optind) { switch (argc-optind) {
case 0: case 0:
if (clk_only) if (clk_only)
break; break;
if (clkout || force_pattern) if (clkout || force_pattern || trigger != -1)
usage(*argv); usage(*argv);
ubb_open(UBB_ALL); ubb_open(UBB_ALL);
@ -629,14 +650,14 @@ int main(int argc, char **argv)
mmcclk_start(&clk); mmcclk_start(&clk);
if (pattern) if (pattern)
dma_pattern(&clk, pattern, mask << 10); dma_pattern(&clk, pattern, mask << 10, trigger);
if (active_s) if (active_s)
if (nanosleep(&active_ns, NULL)) if (nanosleep(&active_ns, NULL))
perror("nanosleep"); perror("nanosleep");
if (pattern) { if (pattern) {
mmcclk_stop(); mmcclk_stop();
ubb_close(mask << 10); ubb_close(mask << 10 | (trigger == -1 ? 0 : UBB_CLK));
} else if (keep_clk) { } else if (keep_clk) {
ubb_close(UBB_CLK); ubb_close(UBB_CLK);
} else { } else {