File: wiegand.cpp

package info (click to toggle)
pigpio 1.78-1.1
  • links: PTS
  • area: main
  • in suites: sid, trixie
  • size: 7,088 kB
  • sloc: ansic: 17,891; python: 4,232; sh: 741; cpp: 281; makefile: 135
file content (116 lines) | stat: -rw-r--r-- 2,335 bytes parent folder | download | duplicates (3)
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
#include <pigpio.h>

#include "wiegand.hpp"

Wiegand::Wiegand(int gpio_0, int gpio_1, WiegandCB_t callback, int timeout)
{
   /*
      Instantiate with the gpio for 0 (green wire), the gpio for 1
      (white wire), the callback function, and the bit timeout in
      milliseconds which indicates the end of a code.

      The callback is passed the code length in bits and the value.
   */

   mygpio_0 = gpio_0;
   mygpio_1 = gpio_1;

   mycallback = callback;

   mytimeout = timeout;

   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, _cbEx, this);
   gpioSetAlertFuncEx(gpio_1, _cbEx, this);
}

void Wiegand::_cb(int gpio, int level, uint32_t tick)
{
   /*
      Accumulate bits until both gpios 0 and 1 timeout.
   */

   if (level == 0) /* a falling edge indicates a new bit */
   {
      if (!in_code)
      {
         bits = 1;
         num = 0;

         in_code = 1;
         code_timeout = 0;

         gpioSetWatchdog(mygpio_0, mytimeout);
         gpioSetWatchdog(mygpio_1, mytimeout);
      }
      else
      {
         bits++;
         num <<= 1;
      }

      if (gpio == mygpio_0)
      {
         code_timeout &= 2; /* clear gpio 0 timeout */
      }
      else
      {
         code_timeout &= 1; /* clear gpio 1 timeout */
         num |= 1;
      }
   }
   else if (level == PI_TIMEOUT)
   {
      if (in_code)
      {
         if (gpio == mygpio_0)
         {
            code_timeout |= 1; /* timeout gpio 0 */
         }
         else
         {
            code_timeout |= 2; /* timeout gpio 1 */
         }

         if (code_timeout == 3) /* both gpios timed out */
         {
            gpioSetWatchdog(mygpio_0, 0);
            gpioSetWatchdog(mygpio_1, 0);

            in_code = 0;

            (mycallback)(bits, num);
         }
      }
   }
}

void Wiegand::_cbEx(int gpio, int level, uint32_t tick, void *user)
{
   /*
      Need a static callback to link with C.
   */

   Wiegand *mySelf = (Wiegand *) user;

   mySelf->_cb(gpio, level, tick); /* Call the instance callback. */
}


void Wiegand::cancel(void)
{
   /*
      Cancel the Wiegand decoder.
   */

   gpioSetAlertFuncEx(mygpio_0, 0, this);
   gpioSetAlertFuncEx(mygpio_1, 0, this);
}