263 | | /* seconds to block waiting for edge |
264 | | * - this also defines the interval between calls if button is held down |
265 | | */ |
266 | | #define BLOCK_TIME 5 |
267 | | /* seconds held for reboot */ |
268 | | #define REBOOT_TIME 15 |
269 | | /* seconds before press-and-release count is cleared */ |
270 | | #define MIN_REST_TIME 2 |
271 | | |
272 | | /* called when a gpio changes value |
273 | | * @value - 0 is low, 1 is high |
274 | | * |
275 | | * The GSC pushbutton has an internal pullup, thus a 'button' should be |
276 | | * normally open, and when pressed should short to ground. Therefore a 0 |
277 | | * is 'down', and a 1 is 'up' |
278 | | */ |
279 | | time_t held_time = 0; /* num seconds button held down */ |
280 | | time_t last = 0; /* last event time */ |
281 | | int num_releases = 0; /* number of successive press-and-release events */ |
282 | | void gpio_change(int gpio, int value) |
283 | | { |
284 | | time_t now = time(NULL); |
285 | | |
286 | | printf("gpio%d: %d last=%ld\n", gpio, value, (long)(now - last)); |
287 | | if (!value) { /* down */ |
288 | | long held; |
289 | | if (!held_time) |
290 | | held_time = now; |
291 | | |
292 | | held = (long)(now - held_time); |
293 | | printf("held=%ld\n", held); |
294 | | |
295 | | /* if held for more than REBOOT_TIME seconds */ |
296 | | if (held >= REBOOT_TIME) { |
297 | | printf("Powering system down\n"); |
298 | | #ifdef __ANDROID__ |
299 | | /* will perform a safe unmount prior to shutdown */ |
300 | | android_reboot(ANDROID_RB_POWEROFF, 0, 0); |
301 | | #else |
302 | | reboot(RB_POWER_OFF); |
303 | | #endif |
304 | | while (1); |
305 | | } |
306 | | } else { /* up */ |
307 | | /* cancel held time counter */ |
308 | | held_time = 0; |
309 | | /* increment or reset num_releases */ |
310 | | if (now - last < MIN_REST_TIME) { |
311 | | num_releases++; |
312 | | printf("count=%d\n", num_releases); |
313 | | |
314 | | /* perform something on number of presses? */ |
315 | | |
316 | | printf("reset count\n"); |
317 | | num_releases = 0; |
318 | | } |
319 | | |
320 | | last = time(NULL); |
321 | | } |
322 | | } |
323 | | |
373 | | //if (fdset.revents & POLLPRI) |
374 | | { |
375 | | /* show gpio value */ |
376 | | /* Note that both an lseek and read are necessary |
377 | | * in order to clear the interrupt detected by poll |
378 | | */ |
379 | | lseek(fdset.fd, 0, SEEK_SET); |
380 | | rz = read(fdset.fd, buf, sizeof(buf)); |
381 | | buf[rz ? rz - 1 : 0] = 0; |
382 | | gpio_change(gpio, atoi(buf)); |
383 | | } |
| 312 | /* show gpio value */ |
| 313 | /* Note that both an lseek and read are necessary |
| 314 | * in order to clear the interrupt detected by poll |
| 315 | */ |
| 316 | usleep (100000); /*100ms delay to debounce*/ |
| 317 | lseek(fd, 0, SEEK_SET); |
| 318 | rz = read(fd, buf, sizeof(buf)); |
| 319 | buf[rz ? rz - 1 : 0] = 0; |
| 320 | printf("%d: ret=%d gpio%d=%d rz=%d\n", (int)time(NULL),c, gpio, atoi(buf), |
| 321 | rz); |