1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137
|
#include <stdlib.h>
#include <pigpio.h>
#include "wiegand.h"
struct _Pi_Wieg_s
{
int mygpio_0;
int mygpio_1;
int mytimeout;
int in_code;
int bits;
Pi_Wieg_CB_t mycallback;
uint32_t num;
uint32_t code_timeout;
};
void _cb(int gpio, int level, uint32_t tick, void *user)
{
/*
Accumulate bits until both gpios 0 and 1 timeout.
*/
Pi_Wieg_t *wieg;
wieg = user;
if (level == 0) /* a falling edge indicates a new bit */
{
if (!wieg->in_code)
{
wieg->bits = 1;
wieg->num = 0;
wieg->in_code = 1;
wieg->code_timeout = 0;
gpioSetWatchdog(wieg->mygpio_0, wieg->mytimeout);
gpioSetWatchdog(wieg->mygpio_1, wieg->mytimeout);
}
else
{
wieg->bits++;
wieg->num <<= 1;
}
if (gpio == wieg->mygpio_0)
{
wieg->code_timeout &= 2; /* clear gpio 0 timeout */
}
else
{
wieg->code_timeout &= 1; /* clear gpio 1 timeout */
wieg->num |= 1;
}
}
else if (level == PI_TIMEOUT)
{
if (wieg->in_code)
{
if (gpio == wieg->mygpio_0)
{
wieg->code_timeout |= 1; /* timeout gpio 0 */
}
else
{
wieg->code_timeout |= 2; /* timeout gpio 1 */
}
if (wieg->code_timeout == 3) /* both gpios timed out */
{
gpioSetWatchdog(wieg->mygpio_0, 0);
gpioSetWatchdog(wieg->mygpio_1, 0);
wieg->in_code = 0;
(wieg->mycallback)(wieg->bits, wieg->num);
}
}
}
}
Pi_Wieg_t * Pi_Wieg(
int gpio_0,
int gpio_1,
Pi_Wieg_CB_t callback,
int timeout)
{
/*
Instantiate with the gpio for 0 (green wire), the gpio for 1
(white wire), the callback function, and the timeout in
milliseconds which indicates the end of a code.
The callback is passed the code length in bits and the value.
*/
Pi_Wieg_t *wieg;
wieg = malloc(sizeof(Pi_Wieg_t));
wieg->mygpio_0 = gpio_0;
wieg->mygpio_1 = gpio_1;
wieg->mycallback = callback;
wieg->mytimeout = timeout;
wieg->in_code = 0;
gpioSetMode(gpio_0, PI_INPUT);
gpioSetMode(gpio_1, PI_INPUT);
gpioSetPullUpDown(gpio_0, PI_PUD_UP);
gpioSetPullUpDown(gpio_1, PI_PUD_UP);
gpioSetAlertFuncEx(gpio_0, _cb, wieg);
gpioSetAlertFuncEx(gpio_1, _cb, wieg);
return wieg;
}
void Pi_Wieg_cancel(Pi_Wieg_t *wieg)
{
/*
Cancel the Wiegand decoder.
*/
if (wieg)
{
gpioSetAlertFunc(wieg->mygpio_0, 0);
gpioSetAlertFunc(wieg->mygpio_1, 0);
free(wieg);
}
}
|