src/
Coverage:
low: ≥ 0%
medium: ≥ 75.0%
high: ≥ 90.0%
Lines:
54 / 57
94.7%
Branches:
48 / 59
81.4%
Functions:
1 / 1
100.0%

PulseDecoder.cpp
Line Branch Exec Source
1 #include "PulseDecoder.h"
2 #if defined(ESP32)
3 #include <esp_attr.h>
4 #define PULSE_DECODER_ATTR IRAM_ATTR
5 #else
6 #define PULSE_DECODER_ATTR
7 #endif
8
9 // Each timing is accepted within 30%.
10 #define TOLERANCE_MIN 0.7
11 #define TOLERANCE_MAX 1.3
12 static const uint32_t tempo_wakeup_pulse = 9415;
13 static const uint32_t tempo_wakeup_min = 9415 * TOLERANCE_MIN;
14 static const uint32_t tempo_wakeup_max = 9415 * TOLERANCE_MAX;
15 static const uint32_t tempo_wakeup_silence = 89565;
16 static const uint32_t tempo_wakeup_silence_min = 89565 * TOLERANCE_MIN;
17 static const uint32_t tempo_wakeup_silence_max = 89565 * TOLERANCE_MAX;
18 static const uint32_t tempo_synchro_hw_min = SYMBOL * 4 * TOLERANCE_MIN;
19 static const uint32_t tempo_synchro_hw_max = SYMBOL * 4 * TOLERANCE_MAX;
20 static const uint32_t tempo_synchro_sw_min = 4850 * TOLERANCE_MIN;
21 static const uint32_t tempo_synchro_sw_max = 4850 * TOLERANCE_MAX;
22 static const uint32_t tempo_half_symbol_min = SYMBOL * TOLERANCE_MIN;
23 static const uint32_t tempo_half_symbol_max = SYMBOL * TOLERANCE_MAX;
24 static const uint32_t tempo_symbol_min = SYMBOL * 2 * TOLERANCE_MIN;
25 static const uint32_t tempo_symbol_max = SYMBOL * 2 * TOLERANCE_MAX;
26 static const uint32_t tempo_if_gap = 30415; // Gap between frames
27 static int16_t bitMin = SYMBOL * TOLERANCE_MIN;
28 1021 PULSE_DECODER_ATTR PulseResult decodePulse(somfy_rx_t &rx, uint32_t durationUs) {
29 1021 const unsigned int duration = durationUs;
30
2/2
✓ Branch 0 taken 1 time.
✓ Branch 1 taken 1020 times.
1021 if (duration < bitMin) {
31 // The incoming bit is < 448us so it is probably a glitch so blow it off.
32 // We need to ignore this bit.
33 // REMOVE THIS AFTER WE DETERMINE THAT THE out-of-bounds stuff isn't a problem. If there are bits
34 // from the previous frame then we will capture this data here.
35
2/4
✓ Branch 0 taken 1 time.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 1 time.
1 if(rx.pulseCount < MAX_TIMINGS && rx.cpt_synchro_hw > 0) rx.pulses[rx.pulseCount++] = duration;
36 1 return PulseResult::glitch;
37 }
38
2/3
✓ Branch 0 taken 311 times.
✓ Branch 1 taken 709 times.
✗ Branch 2 not taken.
1020 switch (rx.status) {
39 311 case waiting_synchro:
40
1/2
✓ Branch 0 taken 311 times.
✗ Branch 1 not taken.
311 if(rx.pulseCount < MAX_TIMINGS) rx.pulses[rx.pulseCount++] = duration;
41
4/4
✓ Branch 0 taken 136 times.
✓ Branch 1 taken 175 times.
✓ Branch 2 taken 112 times.
✓ Branch 3 taken 24 times.
311 if (duration > tempo_synchro_hw_min && duration < tempo_synchro_hw_max) {
42 // We have found a hardware sync bit. There should be at least 4 of these.
43 112 ++rx.cpt_synchro_hw;
44 }
45
6/6
✓ Branch 0 taken 24 times.
✓ Branch 1 taken 175 times.
✓ Branch 2 taken 9 times.
✓ Branch 3 taken 15 times.
✓ Branch 4 taken 8 times.
✓ Branch 5 taken 1 time.
199 else if (duration > tempo_synchro_sw_min && duration < tempo_synchro_sw_max && rx.cpt_synchro_hw >= 4) {
46 // If we have a full hardware sync then we should look for the software sync. If we have a software sync
47 // bit and enough hardware sync bits then we should start receiving data. It turns out that a 56 bit packet
48 // with give 4 or 14 bits of hardware sync. An 80 bit packet gives 12, 13 or 24 bits of hw sync. Early on
49 // I had some shorter and longer hw syncs but I can no longer repeat this.
50 8 memset(rx.payload, 0x00, sizeof(rx.payload));
51 8 rx.previous_bit = 0x00;
52 8 rx.waiting_half_symbol = false;
53 8 rx.cpt_bits = 0;
54 // Keep an eye on this as it is possible that we might get fewer or more synchro bits.
55
2/2
✓ Branch 0 taken 1 time.
✓ Branch 1 taken 7 times.
8 if (rx.cpt_synchro_hw <= 7) rx.bit_length = 56;
56
2/2
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 2 times.
7 else if (rx.cpt_synchro_hw == 14) rx.bit_length = 56;
57
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 else if (rx.cpt_synchro_hw == 13) rx.bit_length = 80; // The RS485 device sends this sync.
58
2/2
✓ Branch 0 taken 1 time.
✓ Branch 1 taken 1 time.
2 else if (rx.cpt_synchro_hw == 12) rx.bit_length = 80;
59
1/2
✓ Branch 0 taken 1 time.
✗ Branch 1 not taken.
1 else if (rx.cpt_synchro_hw > 17) rx.bit_length = 80;
60 ✗ else rx.bit_length = 56;
61 //rx.bit_length = 80;
62 8 rx.status = receiving_data;
63 }
64 else {
65 // Reset and start looking for hardware sync again.
66 191 rx.cpt_synchro_hw = 0;
67 // Try to capture the wakeup pulse.
68
4/4
✓ Branch 0 taken 15 times.
✓ Branch 1 taken 176 times.
✓ Branch 2 taken 4 times.
✓ Branch 3 taken 11 times.
191 if(duration > tempo_wakeup_min && duration < tempo_wakeup_max)
69 {
70 4 memset(&rx.payload, 0x00, sizeof(rx.payload));
71 4 rx.previous_bit = 0x00;
72 4 rx.waiting_half_symbol = false;
73 4 rx.cpt_bits = 0;
74 4 rx.bit_length = 56;
75 }
76
4/6
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 179 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 8 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 179 times.
187 else if((rx.pulseCount > 20 && rx.cpt_synchro_hw == 0) || duration > 250000) {
77 8 rx.pulseCount = 0;
78 }
79 }
80 311 break;
81 709 case receiving_data:
82
1/2
✓ Branch 0 taken 709 times.
✗ Branch 1 not taken.
709 if(rx.pulseCount < MAX_TIMINGS) rx.pulses[rx.pulseCount++] = duration;
83 // We should be receiving data at this point.
84
5/6
✓ Branch 0 taken 181 times.
✓ Branch 1 taken 528 times.
✓ Branch 2 taken 180 times.
✓ Branch 3 taken 1 time.
✓ Branch 4 taken 180 times.
✗ Branch 5 not taken.
709 if (duration > tempo_symbol_min && duration < tempo_symbol_max && !rx.waiting_half_symbol) {
85 180 rx.previous_bit = 1 - rx.previous_bit;
86 // Bits come in high order bit first.
87 180 rx.payload[rx.cpt_bits / 8] += rx.previous_bit << (7 - rx.cpt_bits % 8);
88 180 ++rx.cpt_bits;
89 }
90
3/4
✓ Branch 0 taken 529 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 528 times.
✓ Branch 3 taken 1 time.
529 else if (duration > tempo_half_symbol_min && duration < tempo_half_symbol_max) {
91
2/2
✓ Branch 0 taken 264 times.
✓ Branch 1 taken 264 times.
528 if (rx.waiting_half_symbol) {
92 264 rx.waiting_half_symbol = false;
93 264 rx.payload[rx.cpt_bits / 8] += rx.previous_bit << (7 - rx.cpt_bits % 8);
94 264 ++rx.cpt_bits;
95 }
96 else {
97 264 rx.waiting_half_symbol = true;
98 }
99 }
100 else {
101 //++rx.cpt_bits;
102 // Start over we are not within our parameters for bit timing.
103 1 memset(&rx.payload, 0x00, sizeof(rx.payload));
104 1 rx.pulseCount = 1;
105 1 rx.cpt_synchro_hw = 0;
106 1 rx.previous_bit = 0x00;
107 1 rx.waiting_half_symbol = false;
108 1 rx.cpt_bits = 0;
109 1 rx.bit_length = 56;
110 1 rx.status = waiting_synchro;
111 1 rx.pulses[0] = duration;
112 }
113 709 break;
114 ✗ default:
115 ✗ break;
116 }
117
4/4
✓ Branch 0 taken 716 times.
✓ Branch 1 taken 304 times.
✓ Branch 2 taken 7 times.
✓ Branch 3 taken 709 times.
1020 return rx.status == receiving_data && rx.cpt_bits >= rx.bit_length ? PulseResult::frame : PulseResult::more;
118 }
119
120