-
Notifications
You must be signed in to change notification settings - Fork 13
/
WiegandNG.cpp
144 lines (119 loc) · 4.05 KB
/
WiegandNG.cpp
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
138
139
140
141
142
#include <WiegandNG.h>
// pcintbranch
volatile unsigned long WiegandNG::_lastPulseTime; // time last bit pulse received
volatile unsigned int WiegandNG::_bitCounted; // number of bits arrived at Interrupt pins
volatile unsigned char *WiegandNG::_buffer; // buffer for data retention
unsigned int WiegandNG::_bufferSize; // memory (bytes) allocated for buffer
void shift_left(volatile unsigned char *ar, int size, int shift)
{
while (shift--) { // for each bit to shift ...
int carry = 0; // clear the initial carry bit.
int lastElement = size-1;
for (int i = 0; i < size; i++) { // for each element of the array, from low byte to high byte
if (i!=lastElement) {
// condition ? valueIfTrue : valueIfFalse
carry = (ar[i+1] & 0x80) ? 1 : 0;
ar[i] = carry | (ar[i]<<1);
}
else {
ar[i] <<=1;
}
}
}
}
void WiegandNG::clear() { // reset variables to start new capture
_bitCounted=0;
_lastPulseTime = millis();
memset((unsigned char *)_buffer,0,_bufferSize);
interrupts(); // allow interrupt
}
void WiegandNG::pause() {
noInterrupts(); // disable interrupt so that user can process data
}
volatile unsigned char * WiegandNG::getRawData() {
return _buffer; // return pointer of the buffer
}
unsigned int WiegandNG::getPacketGap() {
return _packetGap;
}
unsigned int WiegandNG::getBitAllocated() {
return _bitAllocated;
}
unsigned int WiegandNG::getBitCounted() {
return _bitCounted;
}
unsigned int WiegandNG::getBufferSize() {
return _bufferSize;
}
bool WiegandNG::available() {
bool ret=false;
noInterrupts();
unsigned long tempLastPulseTime = _lastPulseTime;
interrupts();
unsigned long sysTick = millis();
// if ((sysTick - _lastPulseTime) > _packetGap) { // _packetGap (ms) laps
if ((sysTick - tempLastPulseTime) > _packetGap) { // _packetGap (ms) laps
if(_bitCounted>0) { // bits found, must have data, return true
if(_bitCounted<8) {
Serial.print(_bitCounted);
Serial.print(", ");
Serial.print(sysTick);
Serial.print(", ");
Serial.print(_lastPulseTime);
Serial.print(",");
Serial.println(tempLastPulseTime);
}
ret=true;
}
else
{
_lastPulseTime = millis();
}
}
return ret;
}
void WiegandNG::ReadD0 () {
_bitCounted++; // increment bit count for Interrupt connected to D0
shift_left(_buffer,_bufferSize,1); // shift 0 into buffer
_lastPulseTime = millis(); // keep track of time last wiegand bit received
}
void WiegandNG::ReadD1() {
_bitCounted++; // increment bit count for Interrupt connected to D1
if (_bitCounted > (_bufferSize * 8)) {
_bitCounted=0; // overflowed,
} else {
shift_left(_buffer,_bufferSize,1); // shift 1 into buffer
_buffer[_bufferSize-1] |=1; // set last bit 1
_lastPulseTime = millis(); // keep track of time last wiegand bit received
}
}
bool WiegandNG::begin(unsigned int allocateBits, unsigned int packetGap) {
bool ret;
// newer versions of Arduino provide pin to interrupt mapping
ret=begin(2, 3, allocateBits, packetGap);
return ret;
}
bool WiegandNG::begin(uint8_t pinD0, uint8_t pinD1, unsigned int allocateBits, unsigned int packetGap) {
if (_buffer != NULL) {
delete [] _buffer;
}
_packetGap = packetGap;
_bitAllocated = allocateBits;
_bufferSize=(_bitAllocated/8); // calculate the number of bytes required to store wiegand bits
if((_bitAllocated % 8) >0) _bufferSize++; // add 1 extra byte to cater for bits that are not divisible by 8
_buffer = new unsigned char [_bufferSize]; // allocate memory for buffer
if(_buffer == NULL) return false; // not enough memory, return false
clear();
pinMode(pinD0, INPUT); // set D0 pin as input
pinMode(pinD1, INPUT); // set D1 pin as input
attachInterrupt(digitalPinToInterrupt(pinD0), ReadD0, FALLING); // hardware interrupt - high to low pulse
attachInterrupt(digitalPinToInterrupt(pinD1), ReadD1, FALLING); // hardware interrupt - high to low pulse
return true;
}
WiegandNG::WiegandNG() {
}
WiegandNG::~WiegandNG() {
if (_buffer != NULL) {
delete [] _buffer;
}
}