From cb838e70d6793e06061c43e7c5c6e99f60175fe7 Mon Sep 17 00:00:00 2001
From: Helge Brueger <noreply@fortiss.org>
Date: Tue, 6 Jun 2017 10:34:10 +0000
Subject: [PATCH] Added gamepad sources, added thread, fixed makefile refs 7890

---
 .../trunk/lib/Makedefs                        |   4 +-
 .../trunk/lib/inc/Gamepad.h                   |  81 ++++++++--
 .../trunk/lib/src/Gamepad.c                   | 145 ++++++++++++------
 .../trunk/lib/src/main.c                      |   8 +-
 .../generator/executable/GPOExecutable.java   |   2 +-
 5 files changed, 172 insertions(+), 68 deletions(-)

diff --git a/org.fortiss.af3.platform.raspberry/trunk/lib/Makedefs b/org.fortiss.af3.platform.raspberry/trunk/lib/Makedefs
index bce7e5bb..3d4f565c 100644
--- a/org.fortiss.af3.platform.raspberry/trunk/lib/Makedefs
+++ b/org.fortiss.af3.platform.raspberry/trunk/lib/Makedefs
@@ -19,8 +19,8 @@ ifndef CROSSLD
 endif
 
 # The flags which are passed to the compiler and the linker.
-CCFLAGS+=-std=gnu99 -Wall -pedantic -c ${patsubst %,-I%,${subst :, ,${IPATH}}}
-LDFLAGS+=-std=gnu99 -Wall -pedantic
+CCFLAGS+=-std=gnu99 -Wall -pthread -pedantic -c ${patsubst %,-I%,${subst :, ,${IPATH}}}
+LDFLAGS+=-std=gnu99 -Wall -pthread -lpthread -pedantic
 
 # The default rules, i.e. the entry point.
 all: ${BPATH}
diff --git a/org.fortiss.af3.platform.raspberry/trunk/lib/inc/Gamepad.h b/org.fortiss.af3.platform.raspberry/trunk/lib/inc/Gamepad.h
index 68042e86..0e818c4d 100644
--- a/org.fortiss.af3.platform.raspberry/trunk/lib/inc/Gamepad.h
+++ b/org.fortiss.af3.platform.raspberry/trunk/lib/inc/Gamepad.h
@@ -1,30 +1,65 @@
 #ifndef __GAMEPAD_H
 #define __GAMEPAD_H
 
+#include <stdio.h>
+#include <stdlib.h>
+#include <inttypes.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <unistd.h>
+
 #include "inc-gen/data_dictionary.h"
 
+// constants
+#define JS_EVENT_BUTTON 0x01
+#define JS_EVENT_AXIS   0x02
+#define JS_EVENT_INIT   0x80
+
+extern const char* GP_DEVICE_NAME;
+
+// types etc
+union input_events {
+    struct input_btns {
+        int16_t js1_lr; // LX
+        int16_t js1_ud; // LY
+        int16_t js2_lr; // RX
+        int16_t js2_ud; // RY
+        int16_t gp_lr;  // GPX
+        int16_t gp_ud;  // GPY
+        int16_t bt_tri; // BTN1
+        int16_t bt_cir; // BTN2
+        int16_t bt_x;   // BTN3
+        int16_t bt_sqr; // BTN4
+        int16_t bt_l1;  // L1
+        int16_t bt_r1;  // R1
+        int16_t bt_l2;  // L2
+        int16_t bt_r2;  // R2
+        int16_t bt_sel; // SELECT
+        int16_t bt_strt;// START
+        int16_t js1_bt; // LCLICK
+        int16_t js2_bt; // RCLICK
+    } btns;
+    int16_t inps[18];
+};
+
+struct js_event {
+    uint32_t time;  // event time stamp in millisecons
+    int16_t value;  // value
+    uint8_t type;   // event type
+    uint8_t number; // axis/button number
+};
+
+extern volatile union input_events ie;
+
 // worker
-void gp_worker();
+void* gp_worker(void* pt_args);
 
 // init, term
 void gp_init();
 void gp_term();
 
-// noval
-GEN_TYPE_boolean gp_btn1_is_noval();
-GEN_TYPE_boolean gp_btn2_is_noval();
-GEN_TYPE_boolean gp_btn3_is_noval();
-GEN_TYPE_boolean gp_btn4_is_noval();
-GEN_TYPE_boolean gp_btnL1_is_noval();
-GEN_TYPE_boolean gp_btnL2_is_noval();
-GEN_TYPE_boolean gp_btnR1_is_noval();
-GEN_TYPE_boolean gp_btnR2_is_noval();
-GEN_TYPE_boolean gp_btnLX_is_noval();
-GEN_TYPE_boolean gp_btnLY_is_noval();
-GEN_TYPE_boolean gp_btnRX_is_noval();
-GEN_TYPE_boolean gp_btnRY_is_noval();
-
-
 // readers
 GEN_TYPE_boolean gp_btn1_read();
 GEN_TYPE_boolean gp_btn2_read();
@@ -39,4 +74,18 @@ GEN_TYPE_double gp_btnLY_read();
 GEN_TYPE_double gp_btnRX_read();
 GEN_TYPE_double gp_btnRY_read();
 
+// noval
+GEN_TYPE_boolean gp_btn1_is_noval();
+GEN_TYPE_boolean gp_btn2_is_noval();
+GEN_TYPE_boolean gp_btn3_is_noval();
+GEN_TYPE_boolean gp_btn4_is_noval();
+GEN_TYPE_boolean gp_btnL1_is_noval();
+GEN_TYPE_boolean gp_btnL2_is_noval();
+GEN_TYPE_boolean gp_btnR1_is_noval();
+GEN_TYPE_boolean gp_btnR2_is_noval();
+GEN_TYPE_boolean gp_btnLX_is_noval();
+GEN_TYPE_boolean gp_btnLY_is_noval();
+GEN_TYPE_boolean gp_btnRX_is_noval();
+GEN_TYPE_boolean gp_btnRY_is_noval();
+
 #endif // __GAMEPAD_H
diff --git a/org.fortiss.af3.platform.raspberry/trunk/lib/src/Gamepad.c b/org.fortiss.af3.platform.raspberry/trunk/lib/src/Gamepad.c
index 56c426a2..59f79911 100644
--- a/org.fortiss.af3.platform.raspberry/trunk/lib/src/Gamepad.c
+++ b/org.fortiss.af3.platform.raspberry/trunk/lib/src/Gamepad.c
@@ -1,10 +1,62 @@
 
 #include "inc/Gamepad.h"
 
+// constants
+const char* GP_DEVICE_NAME = "/dev/input/js0";
+
+// variables
+volatile union input_events ie; // stores the button values
+
 // worker
-void gp_worker() {
-    // do background work, read from gamepad, write to variables
-    while(1) {}
+GEN_TYPE_boolean gp_is_running = true;
+
+void* gp_worker(void* pt_args) {
+    int fd;
+    fd = open(GP_DEVICE_NAME, O_RDONLY);
+
+    if(fd <= 0) {
+        perror("Error while connecting to gamepad device");
+        return NULL;
+    }
+
+    struct timeval timeout;
+    struct js_event jse;
+    fd_set read_fds, write_fds, except_fds;
+
+    // loop until terminated...
+    while(gp_is_running) {
+        FD_ZERO(&read_fds);
+        FD_ZERO(&write_fds);
+        FD_ZERO(&except_fds);
+        FD_SET(fd, &read_fds);
+
+        timeout.tv_sec = 0;
+        timeout.tv_usec = 25000;
+
+        if (select(fd + 1, &read_fds, &write_fds, &except_fds, &timeout) == 1) {
+            if(read(fd,&jse,sizeof(jse)) == sizeof(jse)) {
+                jse.type &= ~JS_EVENT_INIT;
+
+                if(jse.type == JS_EVENT_AXIS) {
+                    ie.inps[jse.number] = jse.value;
+
+                    #ifdef DEBUG
+                    printf("Axis %d %d\n", jse.number, jse.value);
+                    #endif // DEBUG
+                }
+
+                if(jse.type == JS_EVENT_BUTTON) {
+                    ie.inps[jse.number + 6] = jse.value;
+
+                    #ifdef DEBUG
+                    printf("Button %d %d\n",jse.number, jse.value);
+                    #endif // DEBUG
+                }
+            }
+        }
+    }
+
+    return NULL;
 }
 
 // init, term
@@ -22,104 +74,105 @@ void gp_term() {
     // important, since all btns are accessing the same method
     if(gp_terminated) return;
 
-    // TODO terminate...
+    gp_terminated = false;
+    gp_is_running = false;
 }
 
-// noval
-GEN_TYPE_boolean gp_btn1_is_noval() {
-    return true;
+// readers
+GEN_TYPE_boolean gp_btn1_read() {
+    return ie.btns.bt_tri;
 }
 
-GEN_TYPE_boolean gp_btn2_is_noval() {
-    return true;
+GEN_TYPE_boolean gp_btn2_read() {
+    return ie.btns.bt_cir;
 }
 
-GEN_TYPE_boolean gp_btn3_is_noval() {
-    return true;
+GEN_TYPE_boolean gp_btn3_read() {
+    return ie.btns.bt_x;
 }
 
-GEN_TYPE_boolean gp_btn4_is_noval() {
-    return true;
+GEN_TYPE_boolean gp_btn4_read() {
+    return ie.btns.bt_sqr;
 }
 
-GEN_TYPE_boolean gp_btnL1_is_noval() {
-    return true;
+GEN_TYPE_boolean gp_btnL1_read() {
+    return ie.btns.bt_l1;
 }
 
-GEN_TYPE_boolean gp_btnL2_is_noval() {
-    return true;
+GEN_TYPE_boolean gp_btnL2_read() {
+    return ie.btns.bt_l2;
 }
 
-GEN_TYPE_boolean gp_btnR1_is_noval() {
-    return true;
+GEN_TYPE_boolean gp_btnR1_read() {
+    return ie.btns.bt_r1;
 }
 
-GEN_TYPE_boolean gp_btnR2_is_noval() {
-    return true;
+GEN_TYPE_boolean gp_btnR2_read() {
+    return ie.btns.bt_r2;
 }
 
-GEN_TYPE_boolean gp_btnLX_is_noval() {
-    return true;
+GEN_TYPE_double gp_btnLX_read() {
+    return 0.0;
 }
 
-GEN_TYPE_boolean gp_btnLY_is_noval() {
-    return true;
+GEN_TYPE_double gp_btnLY_read() {
+    return 0.0;
 }
 
-GEN_TYPE_boolean gp_btnRX_is_noval() {
-    return true;
+GEN_TYPE_double gp_btnRX_read() {
+    return 0.0;
 }
 
-GEN_TYPE_boolean gp_btnRY_is_noval() {
-    return true;
+GEN_TYPE_double gp_btnRY_read() {
+    return 0.0;
 }
 
-// readers
-GEN_TYPE_boolean gp_btn1_read() {
+// noval
+GEN_TYPE_boolean gp_btn1_is_noval() {
     return false;
 }
 
-GEN_TYPE_boolean gp_btn2_read() {
+GEN_TYPE_boolean gp_btn2_is_noval() {
     return false;
 }
 
-GEN_TYPE_boolean gp_btn3_read() {
+GEN_TYPE_boolean gp_btn3_is_noval() {
     return false;
 }
 
-GEN_TYPE_boolean gp_btn4_read() {
+GEN_TYPE_boolean gp_btn4_is_noval() {
     return false;
 }
 
-GEN_TYPE_boolean gp_btnL1_read() {
+GEN_TYPE_boolean gp_btnL1_is_noval() {
     return false;
 }
 
-GEN_TYPE_boolean gp_btnL2_read() {
+GEN_TYPE_boolean gp_btnL2_is_noval() {
     return false;
 }
 
-GEN_TYPE_boolean gp_btnR1_read() {
+GEN_TYPE_boolean gp_btnR1_is_noval() {
     return false;
 }
 
-GEN_TYPE_boolean gp_btnR2_read() {
+GEN_TYPE_boolean gp_btnR2_is_noval() {
     return false;
 }
 
-GEN_TYPE_double gp_btnLX_read() {
-    return 0.0;
+GEN_TYPE_boolean gp_btnLX_is_noval() {
+    return false;
 }
 
-GEN_TYPE_double gp_btnLY_read() {
-    return 0.0;
+GEN_TYPE_boolean gp_btnLY_is_noval() {
+    return false;
 }
 
-GEN_TYPE_double gp_btnRX_read() {
-    return 0.0;
+GEN_TYPE_boolean gp_btnRX_is_noval() {
+    return false;
 }
 
-GEN_TYPE_double gp_btnRY_read() {
-    return 0.0;
+GEN_TYPE_boolean gp_btnRY_is_noval() {
+    return false;
 }
 
diff --git a/org.fortiss.af3.platform.raspberry/trunk/lib/src/main.c b/org.fortiss.af3.platform.raspberry/trunk/lib/src/main.c
index feaad2e4..45c91f7e 100644
--- a/org.fortiss.af3.platform.raspberry/trunk/lib/src/main.c
+++ b/org.fortiss.af3.platform.raspberry/trunk/lib/src/main.c
@@ -4,13 +4,15 @@
 
 #include <stdio.h>
 #include <unistd.h>
+#include <pthread.h>
 
 #include "inc-gen/system.h"
+#include "inc/Gamepad.h"
 
 int main(int argc, char* argv[]) {
-    // start a joystick thread
-    //pthread_t pt_joystick;
-    //pthread_create(&pt_joystick, NULL, joystick_main, NULL);
+    // start a gamepad thread
+    pthread_t pt_gamepad;
+    pthread_create(&pt_gamepad, NULL, gp_worker, NULL);
 
     // start a rover thread
     //pthread_t pt_rover;
diff --git a/org.fortiss.af3.platform.raspberry/trunk/src/org/fortiss/af3/platform/raspberry/generator/executable/GPOExecutable.java b/org.fortiss.af3.platform.raspberry/trunk/src/org/fortiss/af3/platform/raspberry/generator/executable/GPOExecutable.java
index 137e69ae..a7c689ae 100644
--- a/org.fortiss.af3.platform.raspberry/trunk/src/org/fortiss/af3/platform/raspberry/generator/executable/GPOExecutable.java
+++ b/org.fortiss.af3.platform.raspberry/trunk/src/org/fortiss/af3/platform/raspberry/generator/executable/GPOExecutable.java
@@ -64,7 +64,7 @@ public class GPOExecutable extends GenericTransmitterExecutable {
 	/** {@inheritDoc} */
 	@Override
 	public IExpressionTerm getValueWriteAccessor(OutputPort logicalSignal, IExpressionTerm value) {
-		return funcCall("gpio_term", intConst(getPinFromModelElement(modelElement)), value);
+		return funcCall("gpio_write", intConst(getPinFromModelElement(modelElement)), value);
 	}
 
 	private static int getPinFromModelElement(GenericTransmitter modelElement) {
-- 
GitLab