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 #include +#include + #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 + +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; }