Commit | Line | Data |
---|---|---|
35647167 FT |
1 | #include <unistd.h> |
2 | #include <stdlib.h> | |
3 | #include <stdio.h> | |
4 | #include <string.h> | |
5 | #include <fcntl.h> | |
6 | #include <errno.h> | |
7 | #include <err.h> | |
8 | ||
cc450aa9 FT |
9 | static const int bmap[] = { |
10 | -1, | |
11 | -1, -1, 2, -1, 3, -1, 4, 14, -1, 15, 17, 18, 27, -1, 22, 23, -1, 24, 10, -1, | |
12 | 9, 25, 11, 8, -1, 7, -1, -1, 5, -1, 6, 12, 13, -1, 19, 16, 21, 20, -1, 21, | |
13 | }; | |
14 | static const int imap[] = { | |
15 | -1, -1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, | |
16 | 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, 27, | |
17 | }; | |
18 | static const int *umap = bmap; | |
19 | static int mapn = sizeof(bmap) / sizeof(*bmap); | |
20 | ||
21 | static int mappin(int num) | |
22 | { | |
23 | if((num < 0) || (num >= mapn)) | |
24 | return(-1); | |
25 | return(umap[num]); | |
26 | } | |
27 | ||
35647167 FT |
28 | static void setport(int p, int v) |
29 | { | |
30 | char path[256], line[256]; | |
31 | FILE *fp; | |
cc450aa9 | 32 | int rv, rp; |
35647167 | 33 | |
cc450aa9 FT |
34 | if((rp = mappin(p)) < 0) { |
35 | fprintf(stderr, "gpio: %i: no such port\n", p); | |
36 | exit(1); | |
37 | } | |
38 | sprintf(path, "/sys/class/gpio/gpio%i/direction", rp); | |
35647167 FT |
39 | if((fp = fopen(path, "r")) == NULL) |
40 | err(1, "%s", path); | |
41 | rv = !!fgets(line, sizeof(line), fp); | |
42 | fclose(fp); | |
43 | if(!rv || strcmp(line, "out\n")) { | |
44 | if((fp = fopen(path, "w")) == NULL) | |
45 | err(1, "%s", path); | |
46 | fprintf(fp, "out\n"); fflush(fp); | |
47 | if(ferror(fp)) | |
cc450aa9 | 48 | errx(1, "gpio%i: could not set to output", rp); |
35647167 FT |
49 | fclose(fp); |
50 | } | |
cc450aa9 | 51 | sprintf(path, "/sys/class/gpio/gpio%i/value", rp); |
35647167 FT |
52 | if((fp = fopen(path, "w")) == NULL) |
53 | err(1, "%s", path); | |
54 | fprintf(fp, "%i\n", v); fflush(fp); | |
55 | if(ferror(fp)) | |
cc450aa9 | 56 | errx(1, "gpio%i: could not set value", rp); |
35647167 FT |
57 | fclose(fp); |
58 | } | |
59 | ||
cc450aa9 FT |
60 | static void usage(FILE *out) |
61 | { | |
62 | fprintf(out, "usage: gpio [-hi] PORT=VAL...\n"); | |
63 | } | |
64 | ||
35647167 FT |
65 | int main(int argc, char **argv) |
66 | { | |
cc450aa9 | 67 | int c, i, port, val; |
35647167 FT |
68 | char *p, *e; |
69 | ||
cc450aa9 FT |
70 | while((c = getopt(argc, argv, "hi")) >= 0) { |
71 | switch(c) { | |
72 | case 'h': | |
73 | usage(stdout); | |
74 | return(0); | |
75 | case 'i': | |
76 | umap = imap; | |
77 | mapn = sizeof(imap) / sizeof(*imap); | |
78 | break; | |
79 | default: | |
80 | usage(stderr); | |
81 | return(1); | |
82 | } | |
83 | } | |
84 | if(optind >= argc) { | |
85 | usage(stderr); | |
86 | return(1); | |
87 | } | |
88 | for(i = optind; i < argc; i++) { | |
35647167 FT |
89 | if((p = strchr(argv[i], '=')) == NULL) { |
90 | fprintf(stderr, "gpio: %s: not of the form PORT=VAL\n", argv[i]); | |
91 | exit(1); | |
92 | } | |
93 | port = strtol(argv[i], &e, 10); | |
94 | if(e != p) { | |
95 | fprintf(stderr, "gpio: %s: not of the form PORT=VAL\n", argv[i]); | |
96 | exit(1); | |
97 | } | |
98 | val = strtol(p + 1, &e, 10); | |
99 | if(*e) { | |
100 | fprintf(stderr, "gpio: %s: not of the form PORT=VAL\n", argv[i]); | |
101 | exit(1); | |
102 | } | |
103 | setport(port, val); | |
104 | } | |
105 | return(0); | |
106 | } | |
cc450aa9 FT |
107 | |
108 | /* | |
109 | * Local Variables: | |
110 | * compile-command: "gcc -Wall -g -O2 -march=native -o gpio gpio.c" | |
111 | * End: | |
112 | */ |