mirror of
git://projects.qi-hardware.com/ben-blinkenlights.git
synced 2024-11-23 20:33:45 +02:00
ubbctl/: also support decoding and setting of interrupts and alternate functions
This commit is contained in:
parent
3f5c052288
commit
9e223f77e6
@ -30,7 +30,15 @@ respectively.
|
|||||||
pull-up is enabled.
|
pull-up is enabled.
|
||||||
|
|
||||||
"F0" and "F1" indicate that the pin configured as a function (i.e.,
|
"F0" and "F1" indicate that the pin configured as a function (i.e.,
|
||||||
for the MMC controller) and does not operate as GPIO.
|
for the MMC controller) and does not operate as GPIO. If the second
|
||||||
|
function of the pin is selected, "Fb..." is shown instead of "F...".
|
||||||
|
|
||||||
|
"I..." indicates that the pin is configured as an interrupt. The
|
||||||
|
next letter defines the type of interrupt, "r" for rising edge,
|
||||||
|
"f" for falling edge, "h" for high level, and "l" for low level. If
|
||||||
|
the pull-up is enabled, ubbctl adds an "R". Finally, it shows the
|
||||||
|
pin status. E.g., "IfR1" would be an interrupt triggering on the
|
||||||
|
falling edge, with pull-up enabled, and currently inactive.
|
||||||
|
|
||||||
ubbctl can run in continuous mode, in which it updates the status
|
ubbctl can run in continuous mode, in which it updates the status
|
||||||
regularly (currently every 200 ms):
|
regularly (currently every 200 ms):
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
/*
|
/*
|
||||||
* ubbctl.c - Set and query UBB signals
|
* ubbctl.c - Set and query UBB signals
|
||||||
*
|
*
|
||||||
* Written 2013 by Werner Almesberger
|
* Written 2013-2014 by Werner Almesberger
|
||||||
* Copyright 2013 Werner Almesberger
|
* Copyright 2013-2014 Werner Almesberger
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
@ -46,6 +46,23 @@ static void show_pins(void)
|
|||||||
pin = PIN(p->mask);
|
pin = PIN(p->mask);
|
||||||
if (PDFUN & p->mask) {
|
if (PDFUN & p->mask) {
|
||||||
putchar('F');
|
putchar('F');
|
||||||
|
if (PDSEL & p->mask)
|
||||||
|
putchar('b');
|
||||||
|
} else if (PDSEL & p->mask) {
|
||||||
|
putchar('I');
|
||||||
|
if (PDTRG & p->mask) {
|
||||||
|
if (PDDIR & p->mask)
|
||||||
|
putchar('r');
|
||||||
|
else
|
||||||
|
putchar('f');
|
||||||
|
} else {
|
||||||
|
if (PDDIR & p->mask)
|
||||||
|
putchar('h');
|
||||||
|
else
|
||||||
|
putchar('l');
|
||||||
|
}
|
||||||
|
if (!(PDPULL & p->mask))
|
||||||
|
putchar('R');
|
||||||
} else if (PDDIR & p->mask) {
|
} else if (PDDIR & p->mask) {
|
||||||
set = !!(PDDAT & p->mask);
|
set = !!(PDDAT & p->mask);
|
||||||
if (pin != set)
|
if (pin != set)
|
||||||
@ -65,8 +82,10 @@ static void show_pins(void)
|
|||||||
|
|
||||||
static int setup_pin(const char *s, int doit)
|
static int setup_pin(const char *s, int doit)
|
||||||
{
|
{
|
||||||
|
static const char trigger[] = "lhfrLHFR";
|
||||||
const struct pin *p;
|
const struct pin *p;
|
||||||
const char *eq;
|
const char *eq, *t;
|
||||||
|
uint8_t trig;
|
||||||
|
|
||||||
if (!strcasecmp(s, "on"))
|
if (!strcasecmp(s, "on"))
|
||||||
s = "nPWR=0";
|
s = "nPWR=0";
|
||||||
@ -83,36 +102,86 @@ static int setup_pin(const char *s, int doit)
|
|||||||
if (!p->name)
|
if (!p->name)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (!strcasecmp(eq+1, "f")) {
|
if (!strcasecmp(eq+1, "f") || !strcasecmp(eq+1, "fa")) {
|
||||||
if (doit)
|
if (doit) {
|
||||||
PDFUNS = p->mask;
|
PDFUNS = p->mask;
|
||||||
} else if (!strcmp(eq+1, "0")) {
|
PDSELC = p->mask;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
if (!strcasecmp(eq+1, "fb")) {
|
||||||
|
if (doit) {
|
||||||
|
PDFUNS = p->mask;
|
||||||
|
PDSELS = p->mask;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
if (!strcmp(eq+1, "0")) {
|
||||||
if (doit) {
|
if (doit) {
|
||||||
PDDATC = p->mask;
|
PDDATC = p->mask;
|
||||||
PDDIRS = p->mask;
|
PDDIRS = p->mask;
|
||||||
PDFUNC = p->mask;
|
PDFUNC = p->mask;
|
||||||
}
|
}
|
||||||
} else if (!strcmp(eq+1, "1")) {
|
return 1;
|
||||||
|
}
|
||||||
|
if (!strcmp(eq+1, "1")) {
|
||||||
if (doit) {
|
if (doit) {
|
||||||
PDDATS = p->mask;
|
PDDATS = p->mask;
|
||||||
PDDIRS = p->mask;
|
PDDIRS = p->mask;
|
||||||
PDFUNC = p->mask;
|
PDFUNC = p->mask;
|
||||||
}
|
}
|
||||||
} else if (!strcasecmp(eq+1, "r")) {
|
return 1;
|
||||||
|
}
|
||||||
|
if (!strcasecmp(eq+1, "r")) {
|
||||||
if (doit) {
|
if (doit) {
|
||||||
PDPULLC = p->mask;
|
PDPULLC = p->mask;
|
||||||
PDDIRC = p->mask;
|
PDDIRC = p->mask;
|
||||||
PDFUNC = p->mask;
|
PDFUNC = p->mask;
|
||||||
|
PDSELC = p->mask;
|
||||||
}
|
}
|
||||||
} else if (!strcasecmp(eq+1, "z")) {
|
return 1;
|
||||||
|
}
|
||||||
|
if (!strcasecmp(eq+1, "z")) {
|
||||||
if (doit) {
|
if (doit) {
|
||||||
PDPULLS = p->mask;
|
PDPULLS = p->mask;
|
||||||
PDDIRC = p->mask;
|
PDDIRC = p->mask;
|
||||||
PDFUNC = p->mask;
|
PDFUNC = p->mask;
|
||||||
|
PDSELC = p->mask;
|
||||||
}
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
if (eq[1] != 'i' && eq[1] != 'I')
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
t = strchr(trigger, eq[2]);
|
||||||
|
if (!t || !*t)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (!eq[3] || eq[3] == 'z' || eq[3] == 'Z') {
|
||||||
|
if (doit)
|
||||||
|
PDPULLS = p->mask;
|
||||||
|
} else if (eq[3] == 'r' || eq[3] == 'R') {
|
||||||
|
if (doit)
|
||||||
|
PDPULLC = p->mask;
|
||||||
} else {
|
} else {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!doit)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
PDFUNC = p->mask;
|
||||||
|
PDSELS = p->mask;
|
||||||
|
trig = (t-trigger) & 3;
|
||||||
|
if (trig & 1)
|
||||||
|
PDDIRS = p->mask;
|
||||||
|
else
|
||||||
|
PDDIRC = p->mask;
|
||||||
|
if (trig & 2)
|
||||||
|
PDTRGS = p->mask;
|
||||||
|
else
|
||||||
|
PDTRGC = p->mask;
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -124,7 +193,7 @@ static void usage(const char *name)
|
|||||||
" %s name=value|action ...\n\n"
|
" %s name=value|action ...\n\n"
|
||||||
" -c continously update the pin status (until user interrupts)\n\n"
|
" -c continously update the pin status (until user interrupts)\n\n"
|
||||||
"Names: nPWR, CMD, CLK, DAT0, DAT1, DAT2, DAT3\n"
|
"Names: nPWR, CMD, CLK, DAT0, DAT1, DAT2, DAT3\n"
|
||||||
"Values: F, 0, 1, Z, R\n"
|
"Values: F, Fa, Fb, 0, 1, Z, R, Ir[R|Z], If[R|Z], Ih[R|Z], Il[R|Z]\n"
|
||||||
"Actions: ON, OFF\n"
|
"Actions: ON, OFF\n"
|
||||||
, name, name);
|
, name, name);
|
||||||
exit(1);
|
exit(1);
|
||||||
|
Loading…
Reference in New Issue
Block a user