Commit | Line | Data |
---|---|---|
9883c3e4 IS |
1 | #include <stdlib.h> |
2 | #include <fcntl.h> | |
3 | #include <signal.h> | |
4 | #include <unistd.h> | |
5 | #include <string.h> | |
6 | #include <stdio.h> | |
3bacb654 | 7 | #include <time.h> |
9883c3e4 IS |
8 | |
9 | #include <sys/types.h> | |
10 | #include <sys/gpio.h> | |
11 | #include <sys/ioctl.h> | |
3bacb654 | 12 | #include <sys/time.h> |
9883c3e4 IS |
13 | |
14 | #define UP(N) set_pin(N, 1) | |
15 | #define DOWN(N) set_pin(N, 0) | |
16 | ||
17 | #define DEL 100000 | |
18 | ||
19 | #define MEM_WR 0x40 | |
20 | #define ADDR_AUTO 0x44 | |
21 | ||
22 | #define DISP_ON 0x8f | |
23 | #define DISP_OFF 0x80 | |
24 | #define DISP_1 0x88 | |
25 | #define DISP_2 0x89 | |
26 | #define DISP_3 0x8a | |
27 | #define DISP_4 0x8b | |
28 | #define DISP_5 0x8c | |
29 | #define DISP_6 0x8d | |
30 | #define DISP_7 0x8e | |
31 | #define DISP_8 0x8f | |
32 | ||
9883c3e4 IS |
33 | volatile int g0, g1, g2; |
34 | ||
3bacb654 IS |
35 | const uint8_t d2seg[] = { |
36 | 0x3F | |
37 | , 0x06 | |
38 | , 0x5B | |
39 | , 0x4F | |
40 | , 0x66 | |
41 | , 0x6D | |
42 | , 0x7D | |
43 | , 0x07 | |
44 | , 0x7F | |
45 | , 0x6F | |
46 | , 0x77 | |
47 | , 0x7C | |
48 | , 0x39 | |
49 | , 0x5E | |
50 | , 0x79 | |
51 | , 0x71 | |
52 | }; | |
53 | ||
54 | uint8_t dig(uint8_t d) { | |
55 | return d2seg[d]; | |
56 | } | |
57 | ||
58 | /*void timer(long usec) { | |
59 | sigset_t sigs; | |
60 | int s; | |
61 | ||
62 | sigemptyset(&sigs); | |
63 | sigaddset(&sigs, SIGALRM); | |
64 | ||
65 | ualarm(usec, 0); | |
66 | sigwait(&sigs, &s); | |
67 | }*/ | |
68 | ||
69 | /*void timer(long usec) { | |
70 | struct timespec t; | |
71 | t.tv_nsec = usec; | |
72 | t.tv_sec = 0; | |
73 | ||
74 | nanosleep(&t, NULL); | |
75 | }*/ | |
76 | ||
9883c3e4 | 77 | void kd() { |
3bacb654 | 78 | |
2b25fa21 IS |
79 | usleep(1); |
80 | /* | |
3bacb654 IS |
81 | asm("movs r0, #0"); |
82 | ||
83 | for(int i = 0; i < 10; i++) { | |
84 | asm("movs r0, #10\n\t" | |
85 | "1: subs r0, r0, #1\n\t" | |
86 | "bne 1b"); | |
2b25fa21 | 87 | }*/ |
3bacb654 IS |
88 | |
89 | /* volatile int t = 0; | |
90 | ||
91 | while(t != 80000) | |
92 | t++; */ | |
9883c3e4 IS |
93 | /* struct timespec ts, rem; |
94 | ||
95 | ts.tv_sec = 0; | |
96 | ts.tv_nsec = DEL; | |
97 | ||
98 | rem.tv_sec = 0; | |
99 | rem.tv_nsec = 0; | |
100 | ||
3bacb654 | 101 | nanosleep(&ts, &rem); */ |
9883c3e4 IS |
102 | } |
103 | ||
104 | int name2dev(char *s) { | |
105 | if (! strncmp(s, "ser", GPIOPINMAXNAME)) | |
106 | return g1; | |
107 | else if (! strncmp(s, "oe", GPIOPINMAXNAME)) | |
108 | return g0; | |
109 | else if (! strncmp(s, "rclk", GPIOPINMAXNAME)) | |
110 | return g1; | |
111 | else if (! strncmp(s, "srclk", GPIOPINMAXNAME)) | |
112 | return g2; | |
113 | else if (! strncmp(s, "srclr", GPIOPINMAXNAME)) | |
114 | return g1; | |
115 | else if (! strncmp(s, "dio", GPIOPINMAXNAME)) | |
116 | return g2; | |
117 | else if (! strncmp(s, "clk", GPIOPINMAXNAME)) | |
118 | return g2; | |
3bacb654 IS |
119 | else if (! strncmp(s, "ser2", GPIOPINMAXNAME)) |
120 | return g1; | |
121 | else if (! strncmp(s, "clk-sr", GPIOPINMAXNAME)) | |
122 | return g1; | |
123 | else if (! strncmp(s, "shld", GPIOPINMAXNAME)) | |
124 | return g1; | |
125 | else if (! strncmp(s, "clr", GPIOPINMAXNAME)) | |
126 | return g0; | |
127 | ||
128 | ||
9883c3e4 IS |
129 | else { |
130 | printf("no gpio pin w/ name %s, exiting..\n", s); | |
131 | exit(2); | |
132 | } | |
133 | } | |
134 | ||
135 | void inth(int f) { | |
136 | close(g0); | |
137 | close(g1); | |
138 | close(g2); | |
139 | ||
140 | exit(9); | |
141 | } | |
142 | ||
143 | void ack_wait() { | |
144 | struct gpio_pin_set p; | |
145 | struct gpio_pin_op o; | |
146 | int read = 0; | |
147 | ||
148 | p.gp_pin = 6; | |
149 | o.gp_pin = 6; | |
150 | p.gp_flags = GPIO_PIN_INPUT | GPIO_PIN_PULLDOWN; | |
151 | o.gp_value = 0; | |
152 | ||
153 | ioctl(name2dev("dio"), GPIOPINWRITE, &o); | |
154 | ioctl(name2dev("dio"), GPIOPINSET, &p); | |
155 | ||
156 | while(!read) { | |
157 | printf("waiting..\n"); | |
158 | ioctl(name2dev("dio"), GPIOPINREAD, &o); | |
159 | read = o.gp_value; | |
160 | } | |
161 | ||
162 | p.gp_flags = GPIO_PIN_OUTPUT; | |
163 | ioctl(name2dev("dio"), GPIOPINREAD, &o); | |
164 | } | |
165 | ||
166 | void set_pin(char *name, int state) { | |
167 | struct gpio_pin_op op; | |
168 | ||
169 | strlcpy(op.gp_name, name, GPIOPINMAXNAME); | |
170 | op.gp_value = state; | |
171 | ||
172 | ioctl(name2dev(name), GPIOPINWRITE, &op); | |
173 | } | |
174 | ||
175 | void config_pins() { | |
176 | struct gpio_pin_set *ser, *oe, *rclk, *srclk, *srclr, *dio, *clk; | |
177 | ||
9f65bf39 IS |
178 | /* ??? XXX wtf */ |
179 | system("gpioctl gpio2 6 set out clk"); | |
180 | system("gpioctl gpio2 8 set out dio"); | |
181 | ||
9883c3e4 IS |
182 | ser = calloc(1, sizeof(struct gpio_pin_set)); |
183 | oe = calloc(1, sizeof(struct gpio_pin_set)); | |
184 | rclk = calloc(1, sizeof(struct gpio_pin_set)); | |
185 | srclk = calloc(1, sizeof(struct gpio_pin_set)); | |
186 | srclr = calloc(1, sizeof(struct gpio_pin_set)); | |
187 | dio = calloc(1, sizeof(struct gpio_pin_set)); | |
188 | clk = calloc(1, sizeof(struct gpio_pin_set)); | |
189 | ||
190 | ser->gp_pin = 12; | |
191 | ser->gp_flags = GPIO_PIN_OUTPUT; | |
192 | strlcpy(ser->gp_name2, "ser", GPIOPINMAXNAME); | |
193 | ||
194 | oe->gp_pin = 26; | |
195 | oe->gp_flags = GPIO_PIN_OUTPUT; | |
196 | strlcpy(oe->gp_name2, "oe", GPIOPINMAXNAME); | |
197 | ||
198 | rclk->gp_pin = 14; | |
199 | rclk->gp_flags = GPIO_PIN_OUTPUT; | |
200 | strlcpy(rclk->gp_name2, "rclk", GPIOPINMAXNAME); | |
201 | ||
202 | srclk->gp_pin = 1; | |
203 | srclk->gp_flags = GPIO_PIN_OUTPUT; | |
204 | strlcpy(srclk->gp_name2, "srclk", GPIOPINMAXNAME); | |
205 | ||
206 | srclr->gp_pin = 31; | |
207 | srclr->gp_flags = GPIO_PIN_OUTPUT; | |
208 | strlcpy(srclr->gp_name2, "srclr", GPIOPINMAXNAME); | |
209 | ||
210 | dio->gp_pin = 8; | |
211 | dio->gp_flags = GPIO_PIN_OUTPUT; | |
212 | strlcpy(dio->gp_name2, "dio", GPIOPINMAXNAME); | |
213 | ||
214 | clk->gp_pin = 6; | |
215 | clk->gp_flags = GPIO_PIN_OUTPUT; | |
216 | strlcpy(clk->gp_name2, "clk", GPIOPINMAXNAME); | |
217 | ||
218 | ioctl(name2dev("ser"), GPIOPINSET, ser); | |
219 | ioctl(name2dev("oe"), GPIOPINSET, oe); | |
220 | ioctl(name2dev("rclk"), GPIOPINSET, rclk); | |
221 | ioctl(name2dev("srclk"), GPIOPINSET, srclk); | |
222 | ioctl(name2dev("srclr"), GPIOPINSET, srclr); | |
223 | ioctl(name2dev("dio"), GPIOPINSET, dio); | |
224 | ioctl(name2dev("clk"), GPIOPINSET, clk); | |
225 | ||
226 | free(ser); | |
227 | free(oe); | |
228 | free(rclk); | |
229 | free(srclk); | |
230 | free(srclr); | |
231 | free(dio); | |
232 | free(clk); | |
233 | } | |
234 | ||
235 | void pincnt() { | |
236 | g0 = open("/dev/gpio0", O_RDWR); | |
237 | g1 = open("/dev/gpio1", O_RDWR); | |
238 | g2 = open("/dev/gpio2", O_RDWR); | |
239 | ||
240 | struct gpio_info *inf0, *inf1, *inf2; | |
241 | inf0 = calloc(1, sizeof(struct gpio_info)); | |
242 | inf1 = calloc(1, sizeof(struct gpio_info)); | |
243 | inf2 = calloc(1, sizeof(struct gpio_info)); | |
244 | ||
245 | ioctl(g0, GPIOINFO, inf0); | |
246 | ioctl(g1, GPIOINFO, inf1); | |
247 | ioctl(g2, GPIOINFO, inf2); | |
248 | ||
249 | printf("gpio0: %d\ngpio1: %d\ngpio2: %d\n", inf0->gpio_npins, inf1->gpio_npins, inf2->gpio_npins); | |
250 | ||
251 | free(inf0); | |
252 | free(inf1); | |
253 | free(inf2); | |
254 | } | |
255 | ||
256 | void start() { | |
257 | DOWN("dio"); | |
258 | kd(); | |
259 | } | |
260 | ||
261 | void stop() { | |
262 | DOWN("dio"); | |
263 | kd(); | |
264 | UP("clk"); | |
265 | kd(); | |
266 | UP("dio"); | |
267 | kd(); | |
268 | } | |
269 | ||
270 | void byte(uint8_t b) { | |
271 | for(int i = 0; i < 8; i++) { | |
272 | DOWN("clk"); | |
273 | kd(); | |
274 | (b & 0x1) ? UP("dio") : DOWN("dio"); | |
275 | kd(); | |
276 | UP("clk"); | |
277 | kd(); | |
278 | b >>= 1; | |
279 | } | |
280 | ||
281 | DOWN("clk"); | |
282 | UP("dio"); | |
283 | kd(); | |
284 | UP("clk"); | |
285 | kd(); | |
286 | DOWN("dio"); | |
287 | kd(); | |
288 | DOWN("clk"); | |
289 | kd(); | |
290 | } | |
291 | ||
292 | void blink(int c, int ms) { | |
293 | for(int i = 0; i < c; i++) { | |
294 | byte(DISP_ON); | |
295 | kd(); | |
296 | byte(DISP_OFF); | |
297 | kd(); | |
298 | } | |
299 | } | |
300 |