From 0553b9907f912e56a2cd2a08b03a83ce6f2a75c6 Mon Sep 17 00:00:00 2001 From: manuel Date: Tue, 17 Mar 2020 12:18:56 +0100 Subject: Add martin/door --- martin/door/src/hcs200.h | 97 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 97 insertions(+) create mode 100644 martin/door/src/hcs200.h (limited to 'martin/door/src/hcs200.h') diff --git a/martin/door/src/hcs200.h b/martin/door/src/hcs200.h new file mode 100644 index 0000000..95aa18b --- /dev/null +++ b/martin/door/src/hcs200.h @@ -0,0 +1,97 @@ +#pragma once + +#include +#include + +class HCS200_Keycode +{ + public: + /** Bit masks to determine which button was pressed on the keyfob. + * NOTE: the bit position does not match the button number + */ + enum ButtonMask + : unsigned char + { + BM_S3 = 0x1, + BM_S0 = 0x2, + BM_S1 = 0x4, + BM_S2 = 0x8 + }; + + void print(Print &stream); + void send(std::function setOutput); + + private: + void send(bool value, std::function setOutput); + + public: + uint32_t encrypted; + uint32_t serial; + unsigned char buttons; + bool lowbat; +}; + +class HCS200 +{ + public: + enum RxState + { + RS_NOSYNC = 0, // Receiver is inactive + RS_PREAMBLE_START, + RS_PREAMBLE_LOW, + RS_PREAMBLE_HIGH, + RS_PREAMBLE_HEADER, + RS_DATA, // DATA is being received + RS_COMPLETED // Receive complete + }; + + void on_isr(uint8_t value); + void reset(); + bool decode(struct HCS200_Keycode &out); + void print_state(Print &stream); + + public: + int classify(unsigned pulse); + + /** The state of the code word received, this is 'volatile' since it is + * accessed from both the main loop and the interrupt service routine. + */ + volatile char rx_state = RS_NOSYNC; + + /** Time stamp when the previous interrupt was triggered (when the input pin + * transitioned either from 0 to 1 or from 1 to 0. This is the value of + * micros() function. + */ + unsigned long last_timestamp = 0; + + /** The duration of the last pulse width (the time between a transition of the + * input pin) + */ + unsigned last_pulse_width = 0; + + /** Number of changes during preamble + */ + char preamble_count = 0; + + /** Number of bits received already. + */ + char rx_bit_count = 0; + + /** Duration of the transmitter clock -- this is determined when the preamble + * is received, as the preamble has all the pulse widths the same length. + * + * The remotes I tested transmit at 2400 bauds, so the tx_clock is always + * about 420 micro seconds, however, this code attempts to determine it + * dynamically and should adapt to transmitters of different speeds. + */ + unsigned tx_clock = 0; + + /** Number of bits we expect to receive. The HCS200 data sheet specifies that + * 66 bits are transmited. + */ + const unsigned short MAX_BITS = 66; + + /** Buffer where we store the received bits. HCS sends only 66 + */ + uint32_t rx_buf[3]; +}; -- cgit v1.2.3