2 * Pulse demodulation functions
4 * Binary demodulators (PWM/PPM/Manchester/...) using a pulse data structure as input
6 * Copyright (C) 2015 Tommy Vestermark
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
13 #ifndef INCLUDE_PULSE_DEMOD_H_
14 #define INCLUDE_PULSE_DEMOD_H_
17 #include "pulse_detect.h"
21 /// Demodulate a Pulse Code Modulation signal
23 /// Demodulate a Pulse Code Modulation (PCM) signal where bit width
24 /// is fixed and each bit starts with a pulse or not. It may be either
25 /// Return-to-Zero (RZ) encoding, where pulses are shorter than bit width
26 /// or Non-Return-to-Zero (NRZ) encoding, where pulses are equal to bit width
27 /// The presence of a pulse is:
28 /// - Presence of a pulse equals 1
29 /// - Absence of a pulse equals 0
30 /// @param device->short_limit: Nominal width of pulse [us]
31 /// @param device->long_limit: Nominal width of bit period [us]
32 /// @param device->reset_limit: Maximum gap size before End Of Message [us].
33 /// @return number of events processed
34 int pulse_demod_pcm(const pulse_data_t *pulses, struct protocol_state *device);
37 /// Demodulate a Pulse Position Modulation signal
39 /// Demodulate a Pulse Position Modulation (PPM) signal consisting of pulses with variable gap.
40 /// Pulse width may be fixed or variable.
41 /// Gap between pulses determine the encoding:
42 /// - Short gap will add a 0 bit
43 /// - Long gap will add a 1 bit
44 /// @param device->short_limit: Threshold between short and long gap [us]
45 /// @param device->long_limit: Maximum gap size before new row of bits [us]
46 /// @param device->reset_limit: Maximum gap size before End Of Message [us].
47 /// @return number of events processed
48 int pulse_demod_ppm(const pulse_data_t *pulses, struct protocol_state *device);
51 /// Demodulate a Pulse Width Modulation signal
53 /// Demodulate a Pulse Width Modulation (PWM) signal consisting of short and long high pulses.
54 /// Gap between pulses may be of fixed size or variable (e.g. fixed period)
55 /// - Short pulse will add a 1 bit
56 /// - Long pulse will add a 0 bit
57 /// @param device->short_limit: Threshold between short and long pulse [us]
58 /// @param device->long_limit: Maximum gap size before new row of bits [us]
59 /// @param device->reset_limit: Maximum gap size before End Of Message [us].
60 /// @param device->demod_arg = 0: Do not remove any startbits
61 /// @param device->demod_arg = 1: First bit in each message is considered a startbit and not stored in bitbuffer
62 /// @return number of events processed
63 int pulse_demod_pwm(const pulse_data_t *pulses, struct protocol_state *device);
66 /// Parameters for pulse_demod_pwm_precise
68 int pulse_sync_width; // Width of a sync pulse [samples] (optional, ignored if 0)
69 int pulse_tolerance; // Tolerance of pulse widths [samples]
70 } PWM_Precise_Parameters;
73 /// Demodulate a Pulse Width Modulation signal with precise timing
75 /// Demodulate a Pulse Width Modulation (PWM) signal consisting of short and long high pulses.
76 /// Gap between pulses may be of fixed size or variable (e.g. fixed period)
77 /// - Short pulse will add a 1 bit
78 /// - Long pulse will add a 0 bit
79 /// - Sync pulse will add a new row to bitbuffer
80 /// @param device->short_limit: Width in samples of '1' [us]
81 /// @param device->long_limit: Width in samples of '0' [us]
82 /// @param device->reset_limit: Maximum gap size before End Of Message [us].
83 /// @param device->demod_arg: pointer to PWM_Precise_Parameters
84 /// @return number of events processed
85 int pulse_demod_pwm_precise(const pulse_data_t *pulses, struct protocol_state *device);
88 /// Demodulate a Pulse Width Modulation signal with three pulse widths
90 /// Demodulate a Pulse Width Modulation (PWM) signal consisting of short, middle and long high pulses.
91 /// Gap between pulses may be of fixed size or variable (e.g. fixed period)
92 /// The sync bit will add a new row to the bitbuffer
93 /// @param device->short_limit: Threshold between short and middle pulse [us]
94 /// @param device->long_limit: Threshold between middle and long pulse [us]
95 /// @param device->reset_limit: Maximum gap size before End Of Message [us].
96 /// @param device->demod_arg = 0: Short pulse is sync, middle is 0, long is 1
97 /// @param device->demod_arg = 1: Short pulse is 0, middle is sync, long is 1
98 /// @param device->demod_arg = 2: Short pulse is 0, middle is 1, long is sync
99 /// @return number of events processed
100 int pulse_demod_pwm_ternary(const pulse_data_t *pulses, struct protocol_state *device);
103 /// Demodulate a Manchester encoded signal with a hardcoded zerobit in front
105 /// Demodulate a Manchester encoded signal where first rising edge is counted as a databit
106 /// and therefore always will be zero (Most likely a hardcoded Oregon Scientific peculiarity)
108 /// Clock is recovered from the data based on pulse width. When time since last bit is more
109 /// than 1.5 times the clock half period (short_width) it is declared a data edge where:
110 /// - Rising edge means bit = 0
111 /// - Falling edge means bit = 1
112 /// @param device->short_limit: Nominal width of clock half period [us]
113 /// @param device->long_limit: Not used
114 /// @param device->reset_limit: Maximum gap size before End Of Message [us].
115 /// @return number of events processed
116 int pulse_demod_manchester_zerobit(const pulse_data_t *pulses, struct protocol_state *device);
119 /// No level shift within the clock cycle translates to a logic 0
120 /// One level shift within the clock cycle translates to a logic 1
121 /// Each clock cycle begins with a level shift
123 /// +---+ +---+ +-------+ + high
126 /// + +---+ +---+ +-------+ low
128 /// ^ ^ ^ ^ ^ clock cycle
129 /// | 1 | 1 | 0 | 0 | translates as
131 /// @param device->short_limit: Width in samples of '1' [us]
132 /// @param device->long_limit: Width in samples of '0' [us]
133 /// @param device->reset_limit: Maximum gap size before End Of Message [us].
134 /// @param device->demod_arg: pointer to PWM_Precise_Parameters (only pulse_tolerance used)
135 /// @return number of events processed
136 int pulse_demod_clock_bits(const pulse_data_t *pulses, struct protocol_state *device);
139 int pulse_demod_osv1(const pulse_data_t *pulses, struct protocol_state *device);
141 #endif /* INCLUDE_PULSE_DEMOD_H_ */