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:
parent
10b0dea29c
commit
0bb711e625
@ -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 {
|
||||||
|
Loading…
Reference in New Issue
Block a user