/* based largely on code from http://www.semicomplete.com/blog/geekery/soekris-gpio.html which did the same thing on a Soerkis box. */ // the GPIO0 pins for the three LEDs on the Alix 2c3 (left-to-right) #define ALIX_LED_0 6 #define ALIX_LED_1 25 #define ALIX_LED_2 27 // config parameters for this program #define LED_TO_PULSE ALIX_LED_2 // we're just going to do the right-most LED #define PULSE_LENGTH 10000 // in microseconds #define PULSE_STEP 100 // in microseconds // rest of source code stuff #define _BSD_SOURCE #include #include #include #include #include #include #include #include #include #include #include #define _PATH_DEV_GPIO "/dev/gpio0" #define DURATION(a, b) ((b.tv_sec - a.tv_sec) * 1000000) + (b.tv_usec - a.tv_usec) #define ON 1 #define OFF 0 char *device = _PATH_DEV_GPIO; int devfd = -1; void led(u_int pin, int state) { /* based on code at OpenBSD/src/usr.sbin/gpioctl/gpioctl.c, from which the following notice is taken: /* $OpenBSD: gpioctl.c,v 1.4 2005/11/17 10:18:18 grange Exp $ * * Copyright (c) 2004 Alexander Yurchenko * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. */ struct gpio_pin_op op; if (state < 0 || state > 2) errx(1, "%d: invalid value", state); bzero(&op, sizeof(op)); op.gp_pin = pin; op.gp_value = (state == 0 ? GPIO_PIN_LOW : GPIO_PIN_HIGH); if (state < 2) { if (ioctl(devfd, GPIOPINWRITE, &op) == -1) err(1, "GPIOPINWRITE"); } else { if (ioctl(devfd, GPIOPINTOGGLE, &op) == -1) err(1, "GPIOPINTOGGLE"); } } /* usleep(3) and select(2) are unreliable. Let's spin wait instead */ void waittime(long duration) { struct timeval start; struct timeval now; gettimeofday(&start, NULL); for (gettimeofday(&now, NULL); DURATION(start, now) < duration; gettimeofday(&now, NULL)) ; } int main() { int fd; int state = ON; if ((devfd = open(device, O_RDWR)) == -1) err(1, "%s", device); int count = 0; int interval = PULSE_LENGTH; int duty_cycle = 0; // duty cycle is how long the 'on' state should be. // Same units as interval (microseconds) int dir = 1; for (count = 0; count <= (2 * PULSE_LENGTH / PULSE_STEP); count++) { duty_cycle += PULSE_STEP * dir; if (duty_cycle >= interval) { duty_cycle = interval; dir = -1; } if (duty_cycle <= 0) { duty_cycle = 0; dir = 1; } state = ON; led(LED_TO_PULSE, state); waittime(duty_cycle); state = OFF; led(LED_TO_PULSE, state); waittime(interval - duty_cycle); } return 0; }