diff options
Diffstat (limited to 'martin/door/src/hcs200.h')
| -rw-r--r-- | martin/door/src/hcs200.h | 97 |
1 files changed, 97 insertions, 0 deletions
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 @@ | |||
| 1 | #pragma once | ||
| 2 | |||
| 3 | #include <functional> | ||
| 4 | #include <Print.h> | ||
| 5 | |||
| 6 | class HCS200_Keycode | ||
| 7 | { | ||
| 8 | public: | ||
| 9 | /** Bit masks to determine which button was pressed on the keyfob. | ||
| 10 | * NOTE: the bit position does not match the button number | ||
| 11 | */ | ||
| 12 | enum ButtonMask | ||
| 13 | : unsigned char | ||
| 14 | { | ||
| 15 | BM_S3 = 0x1, | ||
| 16 | BM_S0 = 0x2, | ||
| 17 | BM_S1 = 0x4, | ||
| 18 | BM_S2 = 0x8 | ||
| 19 | }; | ||
| 20 | |||
| 21 | void print(Print &stream); | ||
| 22 | void send(std::function<void(int)> setOutput); | ||
| 23 | |||
| 24 | private: | ||
| 25 | void send(bool value, std::function<void(int)> setOutput); | ||
| 26 | |||
| 27 | public: | ||
| 28 | uint32_t encrypted; | ||
| 29 | uint32_t serial; | ||
| 30 | unsigned char buttons; | ||
| 31 | bool lowbat; | ||
| 32 | }; | ||
| 33 | |||
| 34 | class HCS200 | ||
| 35 | { | ||
| 36 | public: | ||
| 37 | enum RxState | ||
| 38 | { | ||
| 39 | RS_NOSYNC = 0, // Receiver is inactive | ||
| 40 | RS_PREAMBLE_START, | ||
| 41 | RS_PREAMBLE_LOW, | ||
| 42 | RS_PREAMBLE_HIGH, | ||
| 43 | RS_PREAMBLE_HEADER, | ||
| 44 | RS_DATA, // DATA is being received | ||
| 45 | RS_COMPLETED // Receive complete | ||
| 46 | }; | ||
| 47 | |||
| 48 | void on_isr(uint8_t value); | ||
| 49 | void reset(); | ||
| 50 | bool decode(struct HCS200_Keycode &out); | ||
| 51 | void print_state(Print &stream); | ||
| 52 | |||
| 53 | public: | ||
| 54 | int classify(unsigned pulse); | ||
| 55 | |||
| 56 | /** The state of the code word received, this is 'volatile' since it is | ||
| 57 | * accessed from both the main loop and the interrupt service routine. | ||
| 58 | */ | ||
| 59 | volatile char rx_state = RS_NOSYNC; | ||
| 60 | |||
| 61 | /** Time stamp when the previous interrupt was triggered (when the input pin | ||
| 62 | * transitioned either from 0 to 1 or from 1 to 0. This is the value of | ||
| 63 | * micros() function. | ||
| 64 | */ | ||
| 65 | unsigned long last_timestamp = 0; | ||
| 66 | |||
| 67 | /** The duration of the last pulse width (the time between a transition of the | ||
| 68 | * input pin) | ||
| 69 | */ | ||
| 70 | unsigned last_pulse_width = 0; | ||
| 71 | |||
| 72 | /** Number of changes during preamble | ||
| 73 | */ | ||
| 74 | char preamble_count = 0; | ||
| 75 | |||
| 76 | /** Number of bits received already. | ||
| 77 | */ | ||
| 78 | char rx_bit_count = 0; | ||
| 79 | |||
| 80 | /** Duration of the transmitter clock -- this is determined when the preamble | ||
| 81 | * is received, as the preamble has all the pulse widths the same length. | ||
| 82 | * | ||
| 83 | * The remotes I tested transmit at 2400 bauds, so the tx_clock is always | ||
| 84 | * about 420 micro seconds, however, this code attempts to determine it | ||
| 85 | * dynamically and should adapt to transmitters of different speeds. | ||
| 86 | */ | ||
| 87 | unsigned tx_clock = 0; | ||
| 88 | |||
| 89 | /** Number of bits we expect to receive. The HCS200 data sheet specifies that | ||
| 90 | * 66 bits are transmited. | ||
| 91 | */ | ||
| 92 | const unsigned short MAX_BITS = 66; | ||
| 93 | |||
| 94 | /** Buffer where we store the received bits. HCS sends only 66 | ||
| 95 | */ | ||
| 96 | uint32_t rx_buf[3]; | ||
| 97 | }; | ||
