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); | |
7243cbb2 | 20 | static int preserve = 0; |
cc450aa9 FT |
21 | |
22 | static int mappin(int num) | |
23 | { | |
24 | if((num < 0) || (num >= mapn)) | |
25 | return(-1); | |
26 | return(umap[num]); | |
27 | } | |
28 | ||
7243cbb2 FT |
29 | static void export(int p) |
30 | { | |
31 | char path[256]; | |
32 | FILE *fp; | |
33 | int rp; | |
34 | ||
35 | if((rp = mappin(p)) < 0) | |
36 | errx(1, "%i: no such port\n", p); | |
37 | sprintf(path, "/sys/class/gpio/gpio%i", rp); | |
38 | if(!access(path, R_OK | X_OK)) | |
39 | return; | |
40 | if(preserve) | |
41 | errx(2, "gpio%i: not exported", rp); | |
42 | sprintf(path, "/sys/class/gpio/export"); | |
43 | if((fp = fopen(path, "w")) == NULL) | |
44 | err(1, "%s", path); | |
45 | fprintf(fp, "%i\n", rp); fflush(fp); | |
46 | if(ferror(fp)) | |
47 | errx(1, "gpio%i: could not export", rp); | |
48 | fclose(fp); | |
49 | sprintf(path, "/sys/class/gpio/gpio%i", rp); | |
50 | if(access(path, R_OK | X_OK)) | |
51 | errx(1, "gpio%i: still not available after export", rp); | |
52 | } | |
53 | ||
35647167 FT |
54 | static void setport(int p, int v) |
55 | { | |
56 | char path[256], line[256]; | |
57 | FILE *fp; | |
cc450aa9 | 58 | int rv, rp; |
35647167 | 59 | |
7243cbb2 FT |
60 | if((rp = mappin(p)) < 0) |
61 | errx(1, "%i: no such port\n", p); | |
cc450aa9 | 62 | sprintf(path, "/sys/class/gpio/gpio%i/direction", rp); |
35647167 FT |
63 | if((fp = fopen(path, "r")) == NULL) |
64 | err(1, "%s", path); | |
65 | rv = !!fgets(line, sizeof(line), fp); | |
66 | fclose(fp); | |
67 | if(!rv || strcmp(line, "out\n")) { | |
7243cbb2 FT |
68 | if(preserve) |
69 | errx(2, "gpio%i: not set to output", rp); | |
35647167 FT |
70 | if((fp = fopen(path, "w")) == NULL) |
71 | err(1, "%s", path); | |
72 | fprintf(fp, "out\n"); fflush(fp); | |
73 | if(ferror(fp)) | |
cc450aa9 | 74 | errx(1, "gpio%i: could not set to output", rp); |
35647167 FT |
75 | fclose(fp); |
76 | } | |
cc450aa9 | 77 | sprintf(path, "/sys/class/gpio/gpio%i/value", rp); |
35647167 FT |
78 | if((fp = fopen(path, "w")) == NULL) |
79 | err(1, "%s", path); | |
80 | fprintf(fp, "%i\n", v); fflush(fp); | |
81 | if(ferror(fp)) | |
cc450aa9 | 82 | errx(1, "gpio%i: could not set value", rp); |
35647167 FT |
83 | fclose(fp); |
84 | } | |
85 | ||
cc450aa9 FT |
86 | static void usage(FILE *out) |
87 | { | |
7243cbb2 | 88 | fprintf(out, "usage: gpio [-hip] PORT=VAL...\n"); |
cc450aa9 FT |
89 | } |
90 | ||
35647167 FT |
91 | int main(int argc, char **argv) |
92 | { | |
cc450aa9 | 93 | int c, i, port, val; |
35647167 FT |
94 | char *p, *e; |
95 | ||
7243cbb2 | 96 | while((c = getopt(argc, argv, "hip")) >= 0) { |
cc450aa9 FT |
97 | switch(c) { |
98 | case 'h': | |
99 | usage(stdout); | |
100 | return(0); | |
101 | case 'i': | |
102 | umap = imap; | |
103 | mapn = sizeof(imap) / sizeof(*imap); | |
104 | break; | |
7243cbb2 FT |
105 | case 'p': |
106 | preserve = 1; | |
107 | break; | |
cc450aa9 FT |
108 | default: |
109 | usage(stderr); | |
110 | return(1); | |
111 | } | |
112 | } | |
113 | if(optind >= argc) { | |
114 | usage(stderr); | |
115 | return(1); | |
116 | } | |
117 | for(i = optind; i < argc; i++) { | |
35647167 FT |
118 | if((p = strchr(argv[i], '=')) == NULL) { |
119 | fprintf(stderr, "gpio: %s: not of the form PORT=VAL\n", argv[i]); | |
120 | exit(1); | |
121 | } | |
122 | port = strtol(argv[i], &e, 10); | |
123 | if(e != p) { | |
124 | fprintf(stderr, "gpio: %s: not of the form PORT=VAL\n", argv[i]); | |
125 | exit(1); | |
126 | } | |
127 | val = strtol(p + 1, &e, 10); | |
128 | if(*e) { | |
129 | fprintf(stderr, "gpio: %s: not of the form PORT=VAL\n", argv[i]); | |
130 | exit(1); | |
131 | } | |
7243cbb2 | 132 | export(port); |
35647167 FT |
133 | setport(port, val); |
134 | } | |
135 | return(0); | |
136 | } | |
cc450aa9 FT |
137 | |
138 | /* | |
139 | * Local Variables: | |
140 | * compile-command: "gcc -Wall -g -O2 -march=native -o gpio gpio.c" | |
141 | * End: | |
142 | */ |