Add a direct polling method to sample the bits instead

Now with extra debouncing!
This commit is contained in:
Solomon Peachy 2019-02-08 20:22:47 -05:00
parent 5e3d794f8b
commit 393cc52b45
4 changed files with 104 additions and 11 deletions

View file

@ -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

95
aldl.c
View file

@ -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;
}
}

5
aldl.h
View file

@ -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);

View file

@ -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;
}