/* wrap-led -- Blinks the LEDs on a WRAP board Copyright (C) 2006 Michael Hanselmann This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include #include #include #include #include #define GPIOBASE 0xF400 #define PRINT_BIT(x) { \ write(STDERR_FILENO, #x, strlen(#x)); \ write(STDERR_FILENO, " = ", 3); \ for (int s = 0; s < (8 * sizeof((x))); ++s) { \ if ((x) & (1 << s)) { \ write(STDERR_FILENO, "1", 1); \ } else { \ write(STDERR_FILENO, "0", 1); \ } \ }; \ write(STDERR_FILENO, "\n", 1); \ } #define NONE 0 #define LED1 1 #define LED2 2 #define LED3 4 #define END 255 struct movie { unsigned long pause; uint8_t *steps; }; uint8_t movie_none[] = { NONE, END }; uint8_t movie_blink[] = { LED1 | LED2 | LED3, NONE, END }; uint8_t movie_ltr[] = { LED1, LED2, LED3, END }; uint8_t movie_rtl[] = { LED3, LED2, LED1, END }; uint8_t movie_runlight[] = { LED1, LED2, LED3, LED2, END }; uint8_t movie_special1[] = { NONE, LED1 | LED3, LED1 | LED2 | LED3, LED2, NONE, LED2, LED1 | LED2 | LED3, LED1 | LED3, END }; struct movie movies[] = { { 5000000, movie_ltr }, { 1000000, movie_blink }, { 1000000 / 4, movie_ltr }, { 1000000 / 4, movie_rtl }, { 1000000 / 4, movie_runlight }, { 1000000 / 8, movie_special1 }, { 5000000, movie_none }, { } }; void set_leds(int led1, int led2, int led3) { uint16_t value; value = inw(GPIOBASE); if (led1) value &= ~(1 << 2); else value |= (1 << 2); if (led2) value &= ~(1 << 3); else value |= (1 << 3); outw(value, GPIOBASE); value = inw(GPIOBASE + 0x2); if (led3) value &= ~(1 << 2); else value |= (1 << 2); outw(value, GPIOBASE + 0x2); } int main(int argc, char* argv[]) { int movie = 0, step = 0; uint8_t pressed = 0, started = 1; unsigned long pause = 0; /* Get root permissions (when setuid-root) */ setuid(0); seteuid(0); /* Get permissions for direct I/O */ if(iopl(3)) { char *error = strerror(errno); write(STDOUT_FILENO, error, strlen(error)); exit(1); } while (1) { uint16_t gpio40 = inw(GPIOBASE + 20); uint8_t changed = 0; if ((gpio40 & (1 << 8)) == 0 && !pressed) { pressed = 1; /*PRINT_BIT(pressed);*/ movie++; step = 0; pause = 0; changed = 1; if (!movies[movie].pause) movie = 0; } else { pressed = 0; } if (pause >= movies[movie].pause || changed || started) { uint8_t value = movies[movie].steps[step]; if (value == END) { step = 0; value = movies[movie].steps[step]; } /*PRINT_BIT(value);*/ set_leds(value & LED1, value & LED2, value & LED3); step++; pause = 0; } usleep(1000000 / 10); pause += 1000000 / 10; started = 0; } /* Should never be reached */ return 0; }