diff --git a/.gitignore b/.gitignore index 2d48ec2..521f1ce 100644 --- a/.gitignore +++ b/.gitignore @@ -6,3 +6,4 @@ deb/ *img +ledBtn diff --git a/doc/State_diagram/state_diagram_v3.odg b/doc/State_diagram/state_diagram_v3.odg new file mode 100644 index 0000000..d17e080 Binary files /dev/null and b/doc/State_diagram/state_diagram_v3.odg differ diff --git a/doc/State_diagram/state_diagram_v3.pdf b/doc/State_diagram/state_diagram_v3.pdf new file mode 100644 index 0000000..78eb300 Binary files /dev/null and b/doc/State_diagram/state_diagram_v3.pdf differ diff --git a/ledButton_controller/Makefile b/ledButton_controller/Makefile new file mode 100755 index 0000000..b6bd8a0 --- /dev/null +++ b/ledButton_controller/Makefile @@ -0,0 +1,2 @@ +ledBtn: ledBtn.c + gcc -o ledBtn ledBtn.c diff --git a/ledButton_controller/ledBtn.c b/ledButton_controller/ledBtn.c new file mode 100644 index 0000000..e52aa16 --- /dev/null +++ b/ledButton_controller/ledBtn.c @@ -0,0 +1,282 @@ +/***************************************************************************************/ +/* */ +/* file : ledBtn.c */ +/* */ +/* synopsis : */ +/* the compiled code should be ran with root privileges to allow for access to */ +/* the GPIO pins through direct GPIO register manipulation in C-code. */ +/* After initialization, the code update the LEDs status according to the commands */ +/* passed on std input (using a pipe). */ +/* It also monitors the push-button and triggers a reboot sequence */ +/* when it is depressed. */ +/* */ +/* */ +/* This code is based on examples from */ +/* http://elinux.org/RPi_Low-level_peripherals#C */ +/* How to access GPIO registers from C-code on the Raspberry-Pi, Example program */ +/* Dom and Gert, 15-January-2012, Revised: 15-Feb-2013 */ +/* */ +/* and from Raphael Vinot (CIRCL.lu) */ +/* */ +/* v 1.00 - 22/02/2015 - initial release (Marc Durvaux) */ +/* v 1.10 - 27/02/2015 - added 'z' command for debugging, improved handling of */ +/* concateneted command sequences */ +/* */ +/* */ +/* */ +/***************************************************************************************/ + +// Includes +#include +#include +#include +#include +#include +#include +#include + +// Constant for low-level access to GPIO +#define BCM2708_PERI_BASE 0x20000000 +#define GPIO_BASE (BCM2708_PERI_BASE + 0x200000) /* GPIO controller */ +#define BLOCK_SIZE (4*1024) + +// global variables related to GPIO +int mem_fd ; +void *gpio_map ; +volatile unsigned *gpio ; // I/O access + +// GPIO setup macros. Always use INP_GPIO(x) before using OUT_GPIO(x) or SET_GPIO_ALT(x,y) +#define INP_GPIO(g) *(gpio+((g)/10)) &= ~(7<<(((g)%10)*3)) +#define OUT_GPIO(g) *(gpio+((g)/10)) |= (1<<(((g)%10)*3)) +#define SET_GPIO_ALT(g,a) *(gpio+(((g)/10))) |= (((a)<=3?(a)+4:(a)==4?3:2)<<(((g)%10)*3)) + +#define GPIO_SET *(gpio+7) // sets bits which are 1 ignores bits which are 0 +#define GPIO_CLR *(gpio+10) // clears bits which are 1 ignores bits which are 0 + +#define GET_GPIO(g) (*(gpio+13)&(1<= 4) { // final state, immediate reboot + close(fd) ; + do_reboot() ; + } + } + if (Btn_press_count == LONG_PUSH) { // trigger forced reboot + state = 10 ; // LED animation before reboot + repeat_count = 0 ; + } + } + Btn_prev_state = Btn_state ; + + nbytes = read(fd, &code, 1) ; + if (nbytes < 0) { + perror("read") ; + exit (2) ; + } + + if (nbytes > 0) { + switch (code) { // codes evaluated at every tic + case 'z' : // clear without restart (for debugging) + GPIO_CLR = 1<= MAX_COUNT) { + count = 0 ; + + switch (state) { // states evaluated after MAX_COUNT tics + case 3 : // green LED flash OFF + GPIO_CLR = 1< 5) { + state = 12 ; + } else { + state = 10 ; + } + break ; + case 12 : // proceed with reboot + close(fd) ; + do_reboot() ; + break ; + } // end switch + } // end if + + // loop delay + nanosleep((struct timespec[]){{0, TIME_TIC}}, NULL) ; + } + + return 0 ; // we should never come here! +} // main + +/***************************************************************************************/ +// +// Set up a memory region to access GPIO +// +void setup_io() { + /* open /dev/mem */ + if ((mem_fd = open("/dev/mem", O_RDWR|O_SYNC) ) < 0) { + printf("can't open /dev/mem \n"); + exit(-1); + } + + /* mmap GPIO */ + gpio_map = mmap( + NULL, //Any adddress in our space will do + BLOCK_SIZE, //Map length + PROT_READ|PROT_WRITE,// Enable reading & writting to mapped memory + MAP_SHARED, //Shared with other processes + mem_fd, //File to map + GPIO_BASE //Offset to GPIO peripheral + ); + + close(mem_fd); //No need to keep mem_fd open after mmap + + if (gpio_map == MAP_FAILED) { + printf("mmap error %d\n", (int)gpio_map);//errno also set! + exit(-1); + } + + // Always use volatile pointer! + gpio = (volatile unsigned *)gpio_map ; + + // initializes the LED and push-button pins + INP_GPIO( GREEN_LED) ; // must use INP_GPIO before we can use OUT_GPIO + OUT_GPIO( GREEN_LED) ; + INP_GPIO( YELLOW_LED) ; + OUT_GPIO( YELLOW_LED) ; + INP_GPIO( RED_LED) ; + OUT_GPIO( RED_LED) ; + INP_GPIO( PUSHBUTTON) ; + + // initializes LEDs to OFF state + GPIO_CLR = 1< $FIFO +#sleep 1 +# send command "PROCESSING" +echo "p" > $FIFO +sleep 1 +# send command "FILE processed" +echo "f" > $FIFO +sleep 3 +# send command "FILE processed" +echo "f" > $FIFO +sleep 3 +# send command "processing successfully COMPLETED" +echo "c" > $FIFO +sleep 2 +# send command "ZERO (clear display and return state to 0)" +echo "z" > $FIFO +sleep 2 +# send command "ERROR" +echo "e" > $FIFO +