summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--README.txt7
-rwxr-xr-xinit_3.4.sh5
-rw-r--r--rotor.c105
3 files changed, 117 insertions, 0 deletions
diff --git a/README.txt b/README.txt
new file mode 100644
index 0000000..b4c028a
--- /dev/null
+++ b/README.txt
@@ -0,0 +1,7 @@
+Simple program, that read from interrupt generated by connecting the
+selected pin to a rotary dial.
+
+Use init_3.4.sh to enable the pin in the kernel, and then run "rotor".
+
+Please note that this program is written for linux-sunxi kernel.
+
diff --git a/init_3.4.sh b/init_3.4.sh
new file mode 100755
index 0000000..9852ddf
--- /dev/null
+++ b/init_3.4.sh
@@ -0,0 +1,5 @@
+modprobe gpio-sunxi
+
+echo 15 > /sys/class/gpio/export
+echo in > /sys/class/gpio/gpio15_pb2/direction
+echo rising > /sys/class/gpio/gpio15_pb2/edge
diff --git a/rotor.c b/rotor.c
new file mode 100644
index 0000000..f6121f4
--- /dev/null
+++ b/rotor.c
@@ -0,0 +1,105 @@
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <poll.h>
+
+#include <sys/time.h>
+#include <time.h>
+
+#define MAX_BUF 64
+
+struct timespec diff(struct timespec start, struct timespec end)
+{
+ struct timespec temp;
+ if ((end.tv_nsec-start.tv_nsec)<0) {
+ temp.tv_sec = end.tv_sec-start.tv_sec-1;
+ temp.tv_nsec = 1000000000+end.tv_nsec-start.tv_nsec;
+ } else {
+ temp.tv_sec = end.tv_sec-start.tv_sec;
+ temp.tv_nsec = end.tv_nsec-start.tv_nsec;
+ }
+ return temp;
+}
+
+int main( int argc, char** argv )
+{
+ struct pollfd fdset[2];
+
+ int nfds = 2;
+ int gpio_fd, timeout, rc;
+ char buf[MAX_BUF];
+ int len;
+ int number=0;
+ struct timespec now_ts, then_ts, diff_ts;
+ bool firstInt; // the next interrupt is the first of the sequence
+
+
+ gpio_fd = open( "/sys/class/gpio/gpio15_pb2/value", O_RDONLY | O_NONBLOCK );
+ timeout = 500;
+
+
+ clock_gettime(CLOCK_MONOTONIC, &then_ts);
+
+ firstInt=true;
+
+ while (1) {
+
+ memset((void*)fdset, 0, sizeof(fdset));
+ memset((void*)buf,0,sizeof(buf));
+
+ fdset[0].fd = 0;
+ fdset[0].events = POLLIN;
+
+ fdset[1].fd = gpio_fd;
+ fdset[1].events = POLLPRI;
+
+ rc = poll(fdset, nfds, timeout);
+
+ if (rc < 0) {
+ fprintf(stderr,"\npoll() failed!\n");
+ return -1;
+ }
+
+ // scaduto il timeout senza interrupt
+ if (rc == 0) {
+ // printf(".");
+ if (number > 0) {
+ printf("%d\n\n", number % 10);
+ number=0;
+ }
+ }
+
+ if (fdset[1].revents & POLLPRI) {
+ clock_gettime(CLOCK_MONOTONIC, &now_ts);
+ // printf("%d %d - ", now_ts.tv_sec, now_ts.tv_nsec);
+ diff_ts = diff(then_ts, now_ts);
+ then_ts = now_ts;
+ lseek(fdset[1].fd,0,SEEK_SET);
+ len = read(fdset[1].fd, buf, MAX_BUF);
+// printf("\npoll() GPIO %d interrupt occurred\n", 34);
+ strtok(buf,"\n");
+
+ int sec=diff_ts.tv_sec;
+ float msec=diff_ts.tv_nsec/1000000.0;
+
+
+ printf("value [%s] sec %d msec %f\n",buf,sec,msec);
+
+ if (firstInt || msec > 90) number++;
+ firstInt=false;
+ }
+
+ if (fdset[0].revents & POLLIN) {
+ (void)read(fdset[0].fd, buf, 1);
+ fprintf(stderr, "\npoll() stdin read 0x%2.2X\n", (unsigned int) buf[0]);
+ }
+
+ fflush(stdout);
+ }
+
+
+}