diff options
Diffstat (limited to 'rotor')
-rw-r--r-- | rotor/README.txt | 7 | ||||
-rwxr-xr-x | rotor/init_3.4.sh | 5 | ||||
-rw-r--r-- | rotor/rotor.c | 105 |
3 files changed, 117 insertions, 0 deletions
diff --git a/rotor/README.txt b/rotor/README.txt new file mode 100644 index 0000000..b4c028a --- /dev/null +++ b/rotor/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/rotor/init_3.4.sh b/rotor/init_3.4.sh new file mode 100755 index 0000000..9852ddf --- /dev/null +++ b/rotor/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/rotor.c b/rotor/rotor.c new file mode 100644 index 0000000..f6121f4 --- /dev/null +++ b/rotor/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); + } + + +} |