summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Makefile4
-rw-r--r--aldl.c95
-rw-r--r--aldl.h5
-rw-r--r--aldl_pi.c11
4 files changed, 104 insertions, 11 deletions
diff --git a/Makefile b/Makefile
index b7d4662..90513d9 100644
--- a/Makefile
+++ b/Makefile
@@ -1,6 +1,6 @@
OBJS := aldl.o aldl_pi.o sdldash.o
-LDFLAGS := -lSDL2 -lSDL2_ttf -lwiringPi
-CFLAGS := -Wall
+LDFLAGS := -lSDL2 -lSDL2_ttf -lwiringPi -lpthread
+CFLAGS := -Wall -DPOLLING
# The ALDL datastream we want
OBJS += a179.o
diff --git a/aldl.c b/aldl.c
index e47d063..451033b 100644
--- a/aldl.c
+++ b/aldl.c
@@ -32,10 +32,14 @@
#include <time.h>
#include <unistd.h>
+#include <pthread.h>
+
#include "aldl.h"
/* shift register & sync word */
#define SYNC_WORD 0x1ff
+#define DWELL_TIME 1000 /* microseconds after falling edge */
+#define DEBOUNCE_TIME 200 /* microseconds */
#define MAX_STREAM_WORDS 255
static uint16_t ALDLSR = 0;
static uint8_t bits = 0;
@@ -79,24 +83,21 @@ static void aldl_datalog(uint8_t *data, int datalen)
fprintf(datalog_handle, "\n");
}
-/* ISR */
-void isrfn(void)
+static void process_bit(int val)
{
- int val;
- delayfn(2000); // To handle both variations, minimum of 0.5, max of 1.8ms
- val = readbit();
ALDLSR <<= 1;
ALDLSR |= (val & 1);
if ((ALDLSR & SYNC_WORD) == SYNC_WORD) {
+ /* New sync word, we've finished a sequence */
+ printf(" - %d\n", datalen);
+
/* Received a sync word.. */
ALDLSR = 0;
if (!gotsync) {
gotsync = 1;
return; /* First one, we don't do anything */
}
- /* New sync word, we've finished a sequence */
- printf(" - %d\n", datalen);
/* Process ALDL payload */
if (aldl_callback)
@@ -116,3 +117,83 @@ void isrfn(void)
ALDLSR = 0;
}
}
+
+/* ISR */
+void isrfn(void)
+{
+ int val;
+ delayfn(DWELL_TIME); // To handle both variations, minimum of 0.5, max of 1.8ms
+ val = !readbit(); // If hi, represents ALDL 0; if low, ALDL1.
+ process_bit(val);
+}
+
+#include <sys/time.h>
+
+int run_sampler = 1;
+
+long tv_diff(struct timeval *tv1, struct timeval *tv2)
+{
+ long usecs = (tv2->tv_sec - tv1->tv_sec) * 1000000;
+ usecs += (tv2->tv_usec - tv1->tv_usec);
+ return usecs;
+}
+
+/* Alternatively.. continually poll. */
+void poll_gpio(void)
+{
+ struct timeval tv, last_tv;
+ int pin, last_pin;
+ long total_us = 0;
+
+ gettimeofday(&last_tv, NULL);
+ last_pin = readbit();
+
+ while(run_sampler) {
+ /* Read */
+ gettimeofday(&tv, NULL);
+ pin = readbit();
+
+ /* Work out how long it's been since our last sample */
+ total_us += tv_diff(&last_tv, &tv);
+ last_tv = tv;
+
+ /* No edge.. or possibly false edge. */
+ if (pin == last_pin || total_us < DEBOUNCE_TIME)
+ continue;
+
+ if (pin == 1) { /* ie Rising edge */
+// printf ("%06d\n", total_us);
+ /* Rising edge. tells us when the bit ends */
+ if (total_us > DWELL_TIME)
+ process_bit(0); /* long period high is logical 0 */
+ else
+ process_bit(1); /* short period high is logical 1 */
+ }
+ /* Edge transition, reset time and record new pin */
+ total_us = 0;
+ last_pin = pin;
+ }
+}
+
+static pthread_t poller;
+static int polling = 0;
+
+static void *thread_poller(void *arg)
+{
+ poll_gpio();
+ pthread_exit(NULL);
+}
+
+int thread_start(void)
+{
+ polling = 1;
+ return pthread_create(&poller, NULL, thread_poller, NULL);
+}
+void thread_shutdown(void)
+{
+ if (polling) {
+ run_sampler = 0;
+ pthread_join(poller, NULL);
+ polling = 0;
+ }
+}
diff --git a/aldl.h b/aldl.h
index 70a52ca..5fba9eb 100644
--- a/aldl.h
+++ b/aldl.h
@@ -28,9 +28,12 @@
*/
/* API */
-void isrfn(void);
int readbit(void);
void delayfn(int ms);
+void isrfn(void);
+
+int thread_start(void);
+void thread_shutdown(void);
extern int gotsync;
extern void (*aldl_callback)(uint8_t *data, int datalen);
diff --git a/aldl_pi.c b/aldl_pi.c
index 9e71090..ecffa30 100644
--- a/aldl_pi.c
+++ b/aldl_pi.c
@@ -42,7 +42,7 @@ static char *datalog_fname = "DATALOG.csv";
int readbit(void)
{
- return !digitalRead(ALDL_PIN_IN); /* Logic low is ALDL '1' */
+ return digitalRead(ALDL_PIN_IN); /* Logic low is ALDL '1' */
}
void delayfn(int us)
{
@@ -65,7 +65,12 @@ int main (int argc, char **argv)
/* Set up RPi GPIO */
pinMode(ALDL_PIN_IN, INPUT);
pullUpDnControl(ALDL_PIN_IN, PUD_DOWN);
+
+#if POLLING
+ thread_start();
+#else
wiringPiISR (ALDL_PIN_IN, INT_EDGE_FALLING, &isrfn);
+#endif
/* Initialize datalogging */
datalog_init(datalog_fname);
@@ -82,5 +87,9 @@ int main (int argc, char **argv)
datalog_close();
+#if POLLING
+ thread_start();
+#endif
+
return 0;
}