mirror of
git://projects.qi-hardware.com/ben-blinkenlights.git
synced 2024-11-23 18:15:55 +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.
|
||||
|
||||
"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
|
||||
regularly (currently every 200 ms):
|
||||
|
@ -1,8 +1,8 @@
|
||||
/*
|
||||
* ubbctl.c - Set and query UBB signals
|
||||
*
|
||||
* Written 2013 by Werner Almesberger
|
||||
* Copyright 2013 Werner Almesberger
|
||||
* Written 2013-2014 by Werner Almesberger
|
||||
* Copyright 2013-2014 Werner Almesberger
|
||||
*
|
||||
* 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
|
||||
@ -46,6 +46,23 @@ static void show_pins(void)
|
||||
pin = PIN(p->mask);
|
||||
if (PDFUN & p->mask) {
|
||||
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) {
|
||||
set = !!(PDDAT & p->mask);
|
||||
if (pin != set)
|
||||
@ -65,8 +82,10 @@ static void show_pins(void)
|
||||
|
||||
static int setup_pin(const char *s, int doit)
|
||||
{
|
||||
static const char trigger[] = "lhfrLHFR";
|
||||
const struct pin *p;
|
||||
const char *eq;
|
||||
const char *eq, *t;
|
||||
uint8_t trig;
|
||||
|
||||
if (!strcasecmp(s, "on"))
|
||||
s = "nPWR=0";
|
||||
@ -83,36 +102,86 @@ static int setup_pin(const char *s, int doit)
|
||||
if (!p->name)
|
||||
return 0;
|
||||
|
||||
if (!strcasecmp(eq+1, "f")) {
|
||||
if (doit)
|
||||
if (!strcasecmp(eq+1, "f") || !strcasecmp(eq+1, "fa")) {
|
||||
if (doit) {
|
||||
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) {
|
||||
PDDATC = p->mask;
|
||||
PDDIRS = p->mask;
|
||||
PDFUNC = p->mask;
|
||||
}
|
||||
} else if (!strcmp(eq+1, "1")) {
|
||||
return 1;
|
||||
}
|
||||
if (!strcmp(eq+1, "1")) {
|
||||
if (doit) {
|
||||
PDDATS = p->mask;
|
||||
PDDIRS = p->mask;
|
||||
PDFUNC = p->mask;
|
||||
}
|
||||
} else if (!strcasecmp(eq+1, "r")) {
|
||||
return 1;
|
||||
}
|
||||
if (!strcasecmp(eq+1, "r")) {
|
||||
if (doit) {
|
||||
PDPULLC = p->mask;
|
||||
PDDIRC = p->mask;
|
||||
PDFUNC = p->mask;
|
||||
PDSELC = p->mask;
|
||||
}
|
||||
} else if (!strcasecmp(eq+1, "z")) {
|
||||
return 1;
|
||||
}
|
||||
if (!strcasecmp(eq+1, "z")) {
|
||||
if (doit) {
|
||||
PDPULLS = p->mask;
|
||||
PDDIRC = 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 {
|
||||
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;
|
||||
}
|
||||
|
||||
@ -124,7 +193,7 @@ static void usage(const char *name)
|
||||
" %s name=value|action ...\n\n"
|
||||
" -c continously update the pin status (until user interrupts)\n\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"
|
||||
, name, name);
|
||||
exit(1);
|
||||
|
Loading…
Reference in New Issue
Block a user