Преглед на файлове

added sanity check of GPIO expander values after a real interrupt or a timeout

Vincent-FK преди 4 години
родител
ревизия
0cfcca07cc
променени са 6 файла, в които са добавени 401 реда и са изтрити 373 реда
  1. 21 21
      Makefile
  2. 78 78
      funkey_gpio_management.c
  3. 16 13
      funkey_gpio_mapping.conf
  4. 241 241
      gpio-utils.c
  5. 17 17
      gpio-utils.h
  6. 28 3
      gpio_mapping.c

+ 21 - 21
Makefile

@@ -1,21 +1,21 @@
-TOOLS_CFLAGS	:= -Wstrict-prototypes -Wshadow -Wpointer-arith -Wcast-qual \
-		   -Wcast-align -Wwrite-strings -Wnested-externs -Winline \
-		   -W -Wundef -Wmissing-prototypes
-#
-# Programs
-#
-all:	funkey_gpio_management 
-
-funkey_gpio_management:  funkey_gpio_management.o gpio-utils.o uinput.o gpio_mapping.o read_conf_file.o keydefs.o driver_pcal6416a.o
-	$(CC) $(LDFLAGS) -o $@ $^
-
-
-#
-# Objects
-#
-
-%.o: %.c
-	$(CC) $(CFLAGS) $(TOOLS_CFLAGS) -c $< -o $@
-
-clean:
-	rm *.o funkey_gpio_management 
+TOOLS_CFLAGS	:= -Wstrict-prototypes -Wshadow -Wpointer-arith -Wcast-qual \
+		   -Wcast-align -Wwrite-strings -Wnested-externs -Winline \
+		   -W -Wundef -Wmissing-prototypes
+#
+# Programs
+#
+all:	funkey_gpio_management 
+
+funkey_gpio_management:  funkey_gpio_management.o gpio-utils.o uinput.o gpio_mapping.o read_conf_file.o keydefs.o driver_pcal6416a.o
+	$(CC) $(LDFLAGS) -o $@ $^
+
+
+#
+# Objects
+#
+
+%.o: %.c
+	$(CC) $(CFLAGS) $(TOOLS_CFLAGS) -c $< -o $@
+
+clean:
+	rm *.o funkey_gpio_management 

+ 78 - 78
funkey_gpio_management.c

@@ -1,78 +1,78 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <signal.h>	// Defines signal-handling functions (i.e. trap Ctrl-C)
-#include <sys/select.h>
-#include "gpio-utils.h"
-#include <assert.h>
-#include "uinput.h"
-#include "gpio_mapping.h"
-#include "read_conf_file.h"
-
- /****************************************************************
- * Defines
- ****************************************************************/
- 
-/****************************************************************
- * Global variables
- ****************************************************************/
-int keepgoing = 1;	// Set to 0 when ctrl-c is pressed
-
-/****************************************************************
- * signal_handler
- ****************************************************************/
-void signal_handler(int sig);
-// Callback called when SIGINT is sent to the process (Ctrl-C)
-void signal_handler(int sig)
-{
-	printf( "Ctrl-C pressed, cleaning up and exiting..\n" );
-	keepgoing = 0;
-}
-
-/****************************************************************
- * Local functions
- ****************************************************************/
-
-
-/****************************************************************
- * Main
- ****************************************************************/
-int main(int argc, char **argv, char **envp)
-{
-	// Variables
-	STRUCT_MAPPED_GPIO * chained_list_mapping = NULL;
-	int nb_valid_gpios = 0;
-	int * gpio_pins = NULL;
-
-	// Set the signal callback for Ctrl-C
-	signal(SIGINT, signal_handler);
-	
-	// Init uinput device
-	init_uinput();
-
-	// Read Conf File: Get GPIO pins to declare and all valid pin mappings
-	get_mapping_from_conf_file(&chained_list_mapping, &nb_valid_gpios, &gpio_pins);
-
-	// Init GPIOs 
-	init_mapping_gpios(gpio_pins, nb_valid_gpios, chained_list_mapping);
-	
-	// Main Loop
-	while (keepgoing) {
-		listen_gpios_interrupts();
-	}
-
-	// De-Init GPIOs 
-	deinit_mapping_gpios();
-	
-	/*
-    * Give userspace some time to read the events before we destroy the
-    * device with UI_DEV_DESTOY.
-    */
-	close_uinput();
-    
-	return 0;
-}
-
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <signal.h>	// Defines signal-handling functions (i.e. trap Ctrl-C)
+#include <sys/select.h>
+#include "gpio-utils.h"
+#include <assert.h>
+#include "uinput.h"
+#include "gpio_mapping.h"
+#include "read_conf_file.h"
+
+ /****************************************************************
+ * Defines
+ ****************************************************************/
+ 
+/****************************************************************
+ * Global variables
+ ****************************************************************/
+int keepgoing = 1;	// Set to 0 when ctrl-c is pressed
+
+/****************************************************************
+ * signal_handler
+ ****************************************************************/
+void signal_handler(int sig);
+// Callback called when SIGINT is sent to the process (Ctrl-C)
+void signal_handler(int sig)
+{
+	printf( "Ctrl-C pressed, cleaning up and exiting..\n" );
+	keepgoing = 0;
+}
+
+/****************************************************************
+ * Local functions
+ ****************************************************************/
+
+
+/****************************************************************
+ * Main
+ ****************************************************************/
+int main(int argc, char **argv, char **envp)
+{
+	// Variables
+	STRUCT_MAPPED_GPIO * chained_list_mapping = NULL;
+	int nb_valid_gpios = 0;
+	int * gpio_pins = NULL;
+
+	// Set the signal callback for Ctrl-C
+	signal(SIGINT, signal_handler);
+	
+	// Init uinput device
+	init_uinput();
+
+	// Read Conf File: Get GPIO pins to declare and all valid pin mappings
+	get_mapping_from_conf_file(&chained_list_mapping, &nb_valid_gpios, &gpio_pins);
+
+	// Init GPIOs 
+	init_mapping_gpios(gpio_pins, nb_valid_gpios, chained_list_mapping);
+	
+	// Main Loop
+	while (keepgoing) {
+		listen_gpios_interrupts();
+	}
+
+	// De-Init GPIOs 
+	deinit_mapping_gpios();
+	
+	/*
+    * Give userspace some time to read the events before we destroy the
+    * device with UI_DEV_DESTOY.
+    */
+	close_uinput();
+    
+	return 0;
+}
+

+ 16 - 13
funkey_gpio_mapping.conf

@@ -27,29 +27,32 @@
 
 ###################################
 #	Mapping:
-6, KEYBOARD, KEY_S, KEY_S, Start
 7, KEYBOARD, KEY_F, KEY_F, Fn
+6, KEYBOARD, KEY_S, KEY_S, Start
+7+6, KEYBOARD, KEY_K, KEY_K, Select
 3, KEYBOARD, KEY_U, KEY_U, Up
+7+3, KEYBOARD, KEY_P, KEY_P, Quick Save
 4, KEYBOARD, KEY_L, KEY_L, Left
+7+4, KEYBOARD, KEY_J, KEY_J, Aspect ratio factor --
 1, KEYBOARD, KEY_D, KEY_D, Down
+7+1, KEYBOARD, KEY_H, KEY_H, Aspect ratio mode change
 0, KEYBOARD, KEY_R, KEY_R, Right
+7+0, KEYBOARD, KEY_I, KEY_I, Aspect ratio factor ++
 15, KEYBOARD, KEY_N, KEY_N, R1
+# Bypass to remove when button axp working:
+7+15, KEYBOARD, KEY_Q, 7+11, Launch menu
+#7+15, KEYBOARD, KEY_O, KEY_O, R2
 2, KEYBOARD, KEY_M, KEY_M, L1
+7+2, KEYBOARD, KEY_V, KEY_V, L2
 12, KEYBOARD, KEY_B, KEY_B, B
+7+12, KEYBOARD, KEY_G, KEY_G, Brightness++
 14, KEYBOARD, KEY_A, KEY_A, A
+7+14, KEYBOARD, KEY_E, KEY_E, Volume--
 13, KEYBOARD, KEY_X, KEY_X, X
+7+13, KEYBOARD, KEY_W, KEY_W, Brightness--
 11, KEYBOARD, KEY_Y, KEY_Y, Y
-7+7, KEYBOARD, KEY_K, KEY_K, Select
-7+15, KEYBOARD, KEY_V, KEY_V, L2
-7+2, KEYBOARD, KEY_O, KEY_O, R2
-#7+3, SHELL_COMMAND, echo "Volume up", 6+3, Volume up
-#7+1, SHELL_COMMAND, echo "Volume down", 6+1, Volume down
-#7+0, SHELL_COMMAND, echo "Brightness up", 6+0, Brightness up
-#7+4, SHELL_COMMAND, echo "Brightness down", 6+4, Brightness down
-7+3, SHELL_COMMAND, /root/shell_cmds/start_gpsp.sh, 6+3, start gpsp
-7+1, SHELL_COMMAND, /root/shell_cmds/start_pcsx.sh, 6+1, start pcsx
-7+0, SHELL_COMMAND, /root/shell_cmds/start_psnes.sh, 6+0, start psnes
-7+4, SHELL_COMMAND, /root/shell_cmds/start_mednafen.sh, 6+4, start mednafen GBC
-7+11, SHELL_COMMAND, /root/shell_cmds/stop_all_emulators.sh, 6+4, stop all emulators
+7+11, KEYBOARD, KEY_C, KEY_C, Volume++
+
+
 
 

+ 241 - 241
gpio-utils.c

@@ -1,241 +1,241 @@
-/* Copyright (c) 2011, RidgeRun
- * All rights reserved.
- *
-From https://www.ridgerun.com/developer/wiki/index.php/Gpio-int-test.c
-
- * 
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *    This product includes software developed by the RidgeRun.
- * 4. Neither the name of the RidgeRun nor the
- *    names of its contributors may be used to endorse or promote products
- *    derived from this software without specific prior written permission.
- * 
- * THIS SOFTWARE IS PROVIDED BY RIDGERUN ''AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL RIDGERUN BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "gpio-utils.h"
-#include <stdlib.h>
-#include <stdio.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <string.h>
-
-/****************************************************************
- * gpio_export
- ****************************************************************/
-int gpio_export(unsigned int gpio)
-{
-	int fd, len;
-	char buf[MAX_BUF];
- 
-	fd = open(SYSFS_GPIO_DIR "/export", O_WRONLY);
-	if (fd < 0) {
-		perror("gpio/export");
-		return fd;
-	}
- 
-	len = snprintf(buf, sizeof(buf), "%d", gpio);
-	write(fd, buf, len);
-	close(fd);
- 
-	return 0;
-}
-
-/****************************************************************
- * gpio_unexport
- ****************************************************************/
-int gpio_unexport(unsigned int gpio)
-{
-	int fd, len;
-	char buf[MAX_BUF];
- 
-	fd = open(SYSFS_GPIO_DIR "/unexport", O_WRONLY);
-	if (fd < 0) {
-		perror("gpio/export");
-		return fd;
-	}
- 
-	len = snprintf(buf, sizeof(buf), "%d", gpio);
-	write(fd, buf, len);
-	close(fd);
-	return 0;
-}
-
-/****************************************************************
- * gpio_set_dir
- ****************************************************************/
-int gpio_set_dir(unsigned int gpio, const char* dir)
-{
-	int fd, len;
-	char buf[MAX_BUF];
- 
-	len = snprintf(buf, sizeof(buf), SYSFS_GPIO_DIR  "/gpio%d/direction", gpio);
- 
-	fd = open(buf, O_WRONLY);
-	if (fd < 0) {
-		perror("gpio/direction");
-		return fd;
-	}
-
-	write(fd, dir, sizeof(dir)+1);
-
-	close(fd);
-	return 0;
-}
-
-/****************************************************************
- * gpio_set_value
- ****************************************************************/
-int gpio_set_value(unsigned int gpio, unsigned int value)
-{
-	int fd, len;
-	char buf[MAX_BUF];
- 
-	len = snprintf(buf, sizeof(buf), SYSFS_GPIO_DIR "/gpio%d/value", gpio);
- 
-	fd = open(buf, O_WRONLY);
-	if (fd < 0) {
-		perror("gpio/set-value");
-		return fd;
-	}
- 
-	if (value)
-		write(fd, "1", 2);
-	else
-		write(fd, "0", 2);
- 
-	close(fd);
-	return 0;
-}
-
-/****************************************************************
- * gpio_get_value
- ****************************************************************/
-int gpio_get_value(unsigned int gpio, unsigned int *value)
-{
-	int fd, len;
-	char buf[MAX_BUF];
-	char ch;
-
-	len = snprintf(buf, sizeof(buf), SYSFS_GPIO_DIR "/gpio%d/value", gpio);
- 
-	fd = open(buf, O_RDONLY);
-	if (fd < 0) {
-		perror("gpio/get-value");
-		return fd;
-	}
- 
-	read(fd, &ch, 1);
-
-	if (ch != '0') {
-		*value = 1;
-	} else {
-		*value = 0;
-	}
- 
-	close(fd);
-	return 0;
-}
-
-
-/****************************************************************
- * gpio_set_edge
- ****************************************************************/
-
-int gpio_set_edge(unsigned int gpio, const char *edge)
-{
-	int fd, len;
-	char buf[MAX_BUF];
-
-	len = snprintf(buf, sizeof(buf), SYSFS_GPIO_DIR "/gpio%d/edge", gpio);
- 
-	fd = open(buf, O_WRONLY);
-	if (fd < 0) {
-		perror("gpio/set-edge");
-		return fd;
-	}
- 
-	write(fd, edge, strlen(edge) + 1); 
-	close(fd);
-	return 0;
-}
-
-/****************************************************************
- * gpio_fd_open
- ****************************************************************/
-
-int gpio_fd_open(unsigned int gpio, unsigned int dir)
-{
-	int fd, len;
-	char buf[MAX_BUF];
-
-	len = snprintf(buf, sizeof(buf), SYSFS_GPIO_DIR "/gpio%d/value", gpio);
- 
-	fd = open(buf, dir | O_NONBLOCK );
-	if (fd < 0) {
-		perror("gpio/fd_open");
-	}
-	return fd;
-}
-
-/****************************************************************
- * gpio_fd_close
- ****************************************************************/
-
-int gpio_fd_close(int fd)
-{
-	return close(fd);
-}
-
-/****************************************************************
- * ain_get_value (from Mike McDonald)
- * https://groups.google.com/forum/#!topic/beagleboard-ece497/SLJ5nQQ_GoU
- ****************************************************************/
-int ain_get_value(unsigned int ain, unsigned int *value)
-{
-    int fd, len, bytesRead;
-    char buf[MAX_BUF];
-    char adc_in[ADC_BUF];
-
-    len = snprintf(buf, sizeof(buf), SYSFS_AIN_DIR "/AIN%d", ain);
- 
-    fd = open(buf, O_RDONLY);
-    if (fd < 0) {
-        perror(buf);
-        return fd;
-    }
-    
-    // Read from the 
-    bytesRead = read(fd, adc_in, ADC_BUF);
-
-    // Turn the buffer value (a string) into an integer
-    if (bytesRead != -1) {
-        *value = atoi(adc_in);
-        adc_in[bytesRead] = (int)NULL;
-        lseek(fd, 0, SEEK_SET);
-    }
-
-    // Sleep for a little to ensure that we get good ADC values
-    usleep(1000);
- 
-    close(fd);
-    return bytesRead;
-}
-
+/* Copyright (c) 2011, RidgeRun
+ * All rights reserved.
+ *
+From https://www.ridgerun.com/developer/wiki/index.php/Gpio-int-test.c
+
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    This product includes software developed by the RidgeRun.
+ * 4. Neither the name of the RidgeRun nor the
+ *    names of its contributors may be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY RIDGERUN ''AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL RIDGERUN BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "gpio-utils.h"
+#include <stdlib.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <string.h>
+
+/****************************************************************
+ * gpio_export
+ ****************************************************************/
+int gpio_export(unsigned int gpio)
+{
+	int fd, len;
+	char buf[MAX_BUF];
+ 
+	fd = open(SYSFS_GPIO_DIR "/export", O_WRONLY);
+	if (fd < 0) {
+		perror("gpio/export");
+		return fd;
+	}
+ 
+	len = snprintf(buf, sizeof(buf), "%d", gpio);
+	write(fd, buf, len);
+	close(fd);
+ 
+	return 0;
+}
+
+/****************************************************************
+ * gpio_unexport
+ ****************************************************************/
+int gpio_unexport(unsigned int gpio)
+{
+	int fd, len;
+	char buf[MAX_BUF];
+ 
+	fd = open(SYSFS_GPIO_DIR "/unexport", O_WRONLY);
+	if (fd < 0) {
+		perror("gpio/export");
+		return fd;
+	}
+ 
+	len = snprintf(buf, sizeof(buf), "%d", gpio);
+	write(fd, buf, len);
+	close(fd);
+	return 0;
+}
+
+/****************************************************************
+ * gpio_set_dir
+ ****************************************************************/
+int gpio_set_dir(unsigned int gpio, const char* dir)
+{
+	int fd, len;
+	char buf[MAX_BUF];
+ 
+	len = snprintf(buf, sizeof(buf), SYSFS_GPIO_DIR  "/gpio%d/direction", gpio);
+ 
+	fd = open(buf, O_WRONLY);
+	if (fd < 0) {
+		perror("gpio/direction");
+		return fd;
+	}
+
+	write(fd, dir, sizeof(dir)+1);
+
+	close(fd);
+	return 0;
+}
+
+/****************************************************************
+ * gpio_set_value
+ ****************************************************************/
+int gpio_set_value(unsigned int gpio, unsigned int value)
+{
+	int fd, len;
+	char buf[MAX_BUF];
+ 
+	len = snprintf(buf, sizeof(buf), SYSFS_GPIO_DIR "/gpio%d/value", gpio);
+ 
+	fd = open(buf, O_WRONLY);
+	if (fd < 0) {
+		perror("gpio/set-value");
+		return fd;
+	}
+ 
+	if (value)
+		write(fd, "1", 2);
+	else
+		write(fd, "0", 2);
+ 
+	close(fd);
+	return 0;
+}
+
+/****************************************************************
+ * gpio_get_value
+ ****************************************************************/
+int gpio_get_value(unsigned int gpio, unsigned int *value)
+{
+	int fd, len;
+	char buf[MAX_BUF];
+	char ch;
+
+	len = snprintf(buf, sizeof(buf), SYSFS_GPIO_DIR "/gpio%d/value", gpio);
+ 
+	fd = open(buf, O_RDONLY);
+	if (fd < 0) {
+		perror("gpio/get-value");
+		return fd;
+	}
+ 
+	read(fd, &ch, 1);
+
+	if (ch != '0') {
+		*value = 1;
+	} else {
+		*value = 0;
+	}
+ 
+	close(fd);
+	return 0;
+}
+
+
+/****************************************************************
+ * gpio_set_edge
+ ****************************************************************/
+
+int gpio_set_edge(unsigned int gpio, const char *edge)
+{
+	int fd, len;
+	char buf[MAX_BUF];
+
+	len = snprintf(buf, sizeof(buf), SYSFS_GPIO_DIR "/gpio%d/edge", gpio);
+ 
+	fd = open(buf, O_WRONLY);
+	if (fd < 0) {
+		perror("gpio/set-edge");
+		return fd;
+	}
+ 
+	write(fd, edge, strlen(edge) + 1); 
+	close(fd);
+	return 0;
+}
+
+/****************************************************************
+ * gpio_fd_open
+ ****************************************************************/
+
+int gpio_fd_open(unsigned int gpio, unsigned int dir)
+{
+	int fd, len;
+	char buf[MAX_BUF];
+
+	len = snprintf(buf, sizeof(buf), SYSFS_GPIO_DIR "/gpio%d/value", gpio);
+ 
+	fd = open(buf, dir | O_NONBLOCK );
+	if (fd < 0) {
+		perror("gpio/fd_open");
+	}
+	return fd;
+}
+
+/****************************************************************
+ * gpio_fd_close
+ ****************************************************************/
+
+int gpio_fd_close(int fd)
+{
+	return close(fd);
+}
+
+/****************************************************************
+ * ain_get_value (from Mike McDonald)
+ * https://groups.google.com/forum/#!topic/beagleboard-ece497/SLJ5nQQ_GoU
+ ****************************************************************/
+int ain_get_value(unsigned int ain, unsigned int *value)
+{
+    int fd, len, bytesRead;
+    char buf[MAX_BUF];
+    char adc_in[ADC_BUF];
+
+    len = snprintf(buf, sizeof(buf), SYSFS_AIN_DIR "/AIN%d", ain);
+ 
+    fd = open(buf, O_RDONLY);
+    if (fd < 0) {
+        perror(buf);
+        return fd;
+    }
+    
+    // Read from the 
+    bytesRead = read(fd, adc_in, ADC_BUF);
+
+    // Turn the buffer value (a string) into an integer
+    if (bytesRead != -1) {
+        *value = atoi(adc_in);
+        adc_in[bytesRead] = (int)NULL;
+        lseek(fd, 0, SEEK_SET);
+    }
+
+    // Sleep for a little to ensure that we get good ADC values
+    usleep(1000);
+ 
+    close(fd);
+    return bytesRead;
+}
+

+ 17 - 17
gpio-utils.h

@@ -1,17 +1,17 @@
-
-#define SYSFS_GPIO_DIR "/sys/class/gpio"
-#define MAX_BUF 64
-
-int gpio_export(unsigned int gpio);
-int gpio_unexport(unsigned int gpio);
-int gpio_set_dir(unsigned int gpio, const char* dir);
-int gpio_set_value(unsigned int gpio, unsigned int value);
-int gpio_get_value(unsigned int gpio, unsigned int *value);
-int gpio_set_edge(unsigned int gpio, const char *edge);
-int gpio_fd_open(unsigned int gpio, unsigned int dir);
-int gpio_fd_close(int fd);
-
-// Analog in
-#define ADC_BUF 1024
-#define SYSFS_AIN_DIR "/sys/devices/ocp.2/helper.11"
-int ain_get_value(unsigned int ain, unsigned int *value);
+
+#define SYSFS_GPIO_DIR "/sys/class/gpio"
+#define MAX_BUF 64
+
+int gpio_export(unsigned int gpio);
+int gpio_unexport(unsigned int gpio);
+int gpio_set_dir(unsigned int gpio, const char* dir);
+int gpio_set_value(unsigned int gpio, unsigned int value);
+int gpio_get_value(unsigned int gpio, unsigned int *value);
+int gpio_set_edge(unsigned int gpio, const char *edge);
+int gpio_fd_open(unsigned int gpio, unsigned int dir);
+int gpio_fd_close(int fd);
+
+// Analog in
+#define ADC_BUF 1024
+#define SYSFS_AIN_DIR "/sys/devices/ocp.2/helper.11"
+int ain_get_value(unsigned int ain, unsigned int *value);

+ 28 - 3
gpio_mapping.c

@@ -8,6 +8,7 @@
 #include <errno.h>
 #include <assert.h>
 #include <sys/select.h>
+#include <sys/time.h>
 #include <linux/input.h>
 #include "gpio_mapping.h"
 #include "driver_pcal6416a.h"
@@ -35,6 +36,10 @@
 #define GPIO_ERROR_PRINTF(...)
 #endif
 
+// This define forces to perform a gpio sanity check after a timeout. 
+// If not declared, there will be no timeout and no periodical sanity check of GPIO expander values
+#define TIMEOUT_SEC_SANITY_CHECK_GPIO_EXP	2
+
 
 /****************************************************************
  * Static variables
@@ -277,11 +282,23 @@ int listen_gpios_interrupts(void)
 	memset(mask_gpio_value, false, nb_mapped_gpios*sizeof(bool));
 	memset(mask_gpio_current_interrupts, false, nb_mapped_gpios*sizeof(bool));
 
-	// Note the max_fd+1 
-	if (select(max_fd+1, NULL, NULL, &dup, NULL) < 0) {
+	// Waiting for interrupt or timeout, Note the max_fd+1
+#ifdef TIMEOUT_SEC_SANITY_CHECK_GPIO_EXP
+	struct timeval timeout = {TIMEOUT_SEC_SANITY_CHECK_GPIO_EXP, 0};
+	int nb_interrupts = select(max_fd+1, NULL, NULL, &dup, &timeout);
+#else
+	int nb_interrupts = select(max_fd+1, NULL, NULL, &dup, NULL);
+#endif //TIMEOUT_SEC_SANITY_CHECK_GPIO_EXP
+	if(!nb_interrupts){
+		// Timeout case 
+		GPIO_PRINTF("	Timeout, forcing sanity check\n");
+		// Timeout forcing a "Found interrupt" event for sanity check
+		interrupt_found = true;
+	}
+	else if ( nb_interrupts < 0) {
 		perror("select");
 		return -1;
-	} 
+	}
 
 	// Check if interrupt from I2C expander
 	// Check which cur_fd is available for read 
@@ -325,6 +342,14 @@ int listen_gpios_interrupts(void)
 				GPIO_PRINTF("	--> Interrupt GPIO: %d, idx_pin: %d\n", gpio_pins[idx_gpio], idx_gpio);
 				mask_gpio_current_interrupts[idx_gpio] = true;
 			}
+
+			// Sanity check: if we missed an interrupt for some reason, check if the new values are the same
+			if( !mask_gpio_current_interrupts[idx_gpio] && 
+				(mask_gpio_value[idx_gpio] != previous_mask_gpio_value[idx_gpio]) ){
+				// Print information
+				GPIO_PRINTF("	--> No Interrupt (missed) but value has changed on GPIO: %d, idx_pin: %d\n", gpio_pins[idx_gpio], idx_gpio);
+				mask_gpio_current_interrupts[idx_gpio] = true;
+			}
 		}