ESPHome 2025.5.0
Loading...
Searching...
No Matches
wiegand.cpp
Go to the documentation of this file.
1#include "wiegand.h"
2#include "esphome/core/log.h"
4
5namespace esphome {
6namespace wiegand {
7
8static const char *const TAG = "wiegand";
9static const char *const KEYS = "0123456789*#";
10
11void IRAM_ATTR HOT WiegandStore::d0_gpio_intr(WiegandStore *arg) {
12 if (arg->d0.digital_read())
13 return;
14 arg->count++;
15 arg->value <<= 1;
16 arg->last_bit_time = millis();
17 arg->done = false;
18}
19
20void IRAM_ATTR HOT WiegandStore::d1_gpio_intr(WiegandStore *arg) {
21 if (arg->d1.digital_read())
22 return;
23 arg->count++;
24 arg->value = (arg->value << 1) | 1;
25 arg->last_bit_time = millis();
26 arg->done = false;
27}
28
37
38bool check_eparity(uint64_t value, int start, int length) {
39 int parity = 0;
40 uint64_t mask = 1LL << start;
41 for (int i = 0; i < length; i++, mask <<= 1) {
42 if (value & mask)
43 parity++;
44 }
45 return !(parity & 1);
46}
47
48bool check_oparity(uint64_t value, int start, int length) {
49 int parity = 0;
50 uint64_t mask = 1LL << start;
51 for (int i = 0; i < length; i++, mask <<= 1) {
52 if (value & mask)
53 parity++;
54 }
55 return parity & 1;
56}
57
59 if (this->store_.done)
60 return;
61 if (millis() - this->store_.last_bit_time < 100)
62 return;
63 uint8_t count = this->store_.count;
64 uint64_t value = this->store_.value;
65 this->store_.count = 0;
66 this->store_.value = 0;
67 this->store_.done = true;
68 ESP_LOGV(TAG, "received %d-bit value: %llx", count, value);
69 for (auto *trigger : this->raw_triggers_)
70 trigger->trigger(count, value);
71 if (count == 26) {
72 std::string tag = to_string((value >> 1) & 0xffffff);
73 ESP_LOGD(TAG, "received 26-bit tag: %s", tag.c_str());
74 if (!check_eparity(value, 13, 13) || !check_oparity(value, 0, 13)) {
75 ESP_LOGW(TAG, "invalid parity");
76 return;
77 }
78 for (auto *trigger : this->tag_triggers_)
79 trigger->trigger(tag);
80 } else if (count == 34) {
81 std::string tag = to_string((value >> 1) & 0xffffffff);
82 ESP_LOGD(TAG, "received 34-bit tag: %s", tag.c_str());
83 if (!check_eparity(value, 17, 17) || !check_oparity(value, 0, 17)) {
84 ESP_LOGW(TAG, "invalid parity");
85 return;
86 }
87 for (auto *trigger : this->tag_triggers_)
88 trigger->trigger(tag);
89 } else if (count == 37) {
90 std::string tag = to_string((value >> 1) & 0x7ffffffff);
91 ESP_LOGD(TAG, "received 37-bit tag: %s", tag.c_str());
92 if (!check_eparity(value, 18, 19) || !check_oparity(value, 0, 19)) {
93 ESP_LOGW(TAG, "invalid parity");
94 return;
95 }
96 for (auto *trigger : this->tag_triggers_)
97 trigger->trigger(tag);
98 } else if (count == 4) {
99 for (auto *trigger : this->key_triggers_)
100 trigger->trigger(value);
101 if (value < 12) {
102 uint8_t key = KEYS[value];
103 this->send_key_(key);
104 }
105 } else if (count == 8) {
106 if ((value ^ 0xf0) >> 4 == (value & 0xf)) {
107 value &= 0xf;
108 for (auto *trigger : this->key_triggers_)
109 trigger->trigger(value);
110 if (value < 12) {
111 uint8_t key = KEYS[value];
112 this->send_key_(key);
113 }
114 }
115 } else {
116 ESP_LOGD(TAG, "received unknown %d-bit value: %llx", count, value);
117 }
118}
119
121 ESP_LOGCONFIG(TAG, "Wiegand reader:");
122 LOG_PIN(" D0 pin: ", this->d0_pin_);
123 LOG_PIN(" D1 pin: ", this->d1_pin_);
124}
125
126} // namespace wiegand
127} // namespace esphome
virtual void setup()=0
void attach_interrupt(void(*func)(T *), T *arg, gpio::InterruptType type) const
Definition gpio.h:88
virtual ISRInternalGPIOPin to_isr() const =0
InternalGPIOPin * d1_pin_
Definition wiegand.h:46
void loop() override
Definition wiegand.cpp:58
void dump_config() override
Definition wiegand.cpp:120
std::vector< WiegandKeyTrigger * > key_triggers_
Definition wiegand.h:50
InternalGPIOPin * d0_pin_
Definition wiegand.h:45
void setup() override
Definition wiegand.cpp:29
std::vector< WiegandTagTrigger * > tag_triggers_
Definition wiegand.h:48
std::vector< WiegandRawTrigger * > raw_triggers_
Definition wiegand.h:49
WiegandStore store_
Definition wiegand.h:47
@ INTERRUPT_FALLING_EDGE
Definition gpio.h:42
bool check_eparity(uint64_t value, int start, int length)
Definition wiegand.cpp:38
bool check_oparity(uint64_t value, int start, int length)
Definition wiegand.cpp:48
Providing packet encoding functions for exchanging data with a remote host.
Definition a01nyub.cpp:7
std::string to_string(int value)
Definition helpers.cpp:82
uint32_t IRAM_ATTR HOT millis()
Definition core.cpp:27
ISRInternalGPIOPin d0
Definition wiegand.h:14
static void d0_gpio_intr(WiegandStore *arg)
Definition wiegand.cpp:11
static void d1_gpio_intr(WiegandStore *arg)
Definition wiegand.cpp:20
ISRInternalGPIOPin d1
Definition wiegand.h:15
volatile uint64_t value
Definition wiegand.h:16
volatile uint8_t count
Definition wiegand.h:19
volatile uint32_t last_bit_time
Definition wiegand.h:17
uint16_t length
Definition tt21100.cpp:0