rtl_433/include/pulse_slicer.h
2023-03-10 16:54:50 +01:00

161 lines
6.8 KiB
C

/** @file
Pulse slicer functions.
Binary slicers (PWM/PPM/Manchester/...) using a pulse data structure as input
Copyright (C) 2015 Tommy Vestermark
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
*/
#ifndef INCLUDE_PULSE_SLICER_H_
#define INCLUDE_PULSE_SLICER_H_
#include "pulse_detect.h"
#include "r_device.h"
/// Demodulate a Pulse Code Modulation signal.
///
/// Demodulate a Pulse Code Modulation (PCM) signal where bit width
/// is fixed and each bit starts with a pulse or not. It may be either
/// Return-to-Zero (RZ) encoding, where pulses are shorter than bit width
/// or Non-Return-to-Zero (NRZ) encoding, where pulses are equal to bit width
/// The presence of a pulse is:
/// - Presence of a pulse equals 1
/// - Absence of a pulse equals 0
///
/// @param pulses The pulse sequence to demodulate
/// @param device Modulation parameters of
/// - short_width: Nominal width of pulse [us]
/// - long_width: Nominal width of bit period [us]
/// - gap_limit: Maximum gap size before new row of bits (optional) [us]
/// - reset_limit: Maximum gap size before End Of Message [us].
/// - tolerance: Maximum deviation from nominal widths (optional, default 25%) [us]
/// @return number of events processed
int pulse_slicer_pcm(pulse_data_t const *pulses, r_device *device);
/// Demodulate a Pulse Position Modulation signal.
///
/// Demodulate a Pulse Position Modulation (PPM) signal consisting of pulses with variable gap.
/// Pulse width may be fixed or variable.
/// Gap between pulses determine the encoding:
/// - Short gap will add a 0 bit
/// - Long gap will add a 1 bit
///
/// @param pulses The pulse sequence to demodulate
/// @param device Modulation parameters of
/// - short_width: Nominal width of '0' [us]
/// - long_width: Nominal width of '1' [us]
/// - reset_limit: Maximum gap size before End Of Message [us].
/// - gap_limit: Maximum gap size before new row of bits [us]
/// - tolerance: Maximum deviation from nominal widths (optional, raw if 0) [us]
/// @return number of events processed
int pulse_slicer_ppm(pulse_data_t const *pulses, r_device *device);
/// Demodulate a Pulse Width Modulation signal.
///
/// Demodulate a Pulse Width Modulation (PWM) signal consisting of short, long, and optional sync pulses.
/// Gap between pulses may be of fixed size or variable (e.g. fixed period)
/// - Short pulse will add a 1 bit
/// - Long pulse will add a 0 bit
/// - Sync pulse (optional) will add a new row to bitbuffer
///
/// @param pulses The pulse sequence to demodulate
/// @param device Modulation parameters of
/// - short_width: Nominal width of '1' [us]
/// - long_width: Nominal width of '0' [us]
/// - reset_limit: Maximum gap size before End Of Message [us].
/// - gap_limit: Maximum gap size before new row of bits [us]
/// - sync_width: Nominal width of sync pulse (optional) [us]
/// - tolerance: Maximum deviation from nominal widths (optional, raw if 0) [us]
/// @return number of events processed
int pulse_slicer_pwm(pulse_data_t const *pulses, r_device *device);
/// Demodulate a Manchester encoded signal with a hardcoded zerobit in front.
///
/// Demodulate a Manchester encoded signal where first rising edge is counted as a databit
/// and therefore always will be zero (Most likely a hardcoded Oregon Scientific peculiarity)
///
/// Clock is recovered from the data based on pulse width. When time since last bit is more
/// than 1.5 times the clock half period (short_width) it is declared a data edge where:
/// - Rising edge means bit = 0
/// - Falling edge means bit = 1
///
/// @param pulses The pulse sequence to demodulate
/// @param device Modulation parameters of
/// - short_width: Nominal width of clock half period [us]
/// - long_width: Not used
/// - reset_limit: Maximum gap size before End Of Message [us].
/// @return number of events processed
int pulse_slicer_manchester_zerobit(pulse_data_t const *pulses, r_device *device);
/// Demodulate a Differential Manchester Coded signal.
///
/// No level shift within the clock cycle translates to a logic 0
/// One level shift within the clock cycle translates to a logic 1
/// Each clock cycle begins with a level shift
///
/// +---+ +---+ +-------+ + high
/// | | | | | | |
/// | | | | | | |
/// + +---+ +---+ +-------+ low
///
/// ^ ^ ^ ^ ^ clock cycle
/// | 1 | 1 | 0 | 0 | translates as
///
/// @param pulses The pulse sequence to demodulate
/// @param device Modulation parameters of
/// - short_width: Width in samples of '1' [us]
/// - long_width: Width in samples of '0' [us]
/// - reset_limit: Maximum gap size before End Of Message [us].
/// - tolerance: Maximum deviation from nominal widths [us]
/// @return number of events processed
int pulse_slicer_dmc(pulse_data_t const *pulses, r_device *device);
/// Demodulate a raw Pulse Interval and Width Modulation signal.
///
/// Each level shift is a new bit.
/// A short interval is a logic 1, a long interval a logic 0
///
/// @param pulses The pulse sequence to demodulate
/// @param device Modulation parameters of
/// - short_width: Nominal width of a bit [us]
/// - long_width: Maximum width of a run of bits [us]
/// - reset_limit: Maximum gap size before End Of Message [us].
/// - tolerance: Maximum deviation from nominal widths [us]
/// @return number of events processed
int pulse_slicer_piwm_raw(pulse_data_t const *pulses, r_device *device);
/// Demodulate a differential Pulse Interval and Width Modulation signal.
///
/// Each level shift is a new bit.
/// A short interval is a logic 1, a long interval a logic 0
///
/// @param pulses The pulse sequence to demodulate
/// @param device Modulation parameters of
/// - short_width: Nominal width of '1' [us]
/// - long_width: Nominal width of '0' [us]
/// - reset_limit: Maximum gap size before End Of Message [us].
/// - tolerance: Maximum deviation from nominal widths [us]
/// @return number of events processed
int pulse_slicer_piwm_dc(pulse_data_t const *pulses, r_device *device);
int pulse_slicer_nrzs(pulse_data_t const *pulses, r_device *device);
int pulse_slicer_osv1(pulse_data_t const *pulses, r_device *device);
/// Simulate demodulation using a given signal code string.
///
/// The (optionally "0x" prefixed) hex code is processed into a bitbuffer_t.
/// Each row is optionally prefixed with a length enclosed in braces "{}" or
/// separated with a slash "/" character. Whitespace is ignored.
///
/// @param code The pulse sequence to demodulate in text format
/// @param device Device params are disregarded.
/// @return number of events processed
int pulse_slicer_string(const char *code, r_device *device);
#endif /* INCLUDE_PULSE_SLICER_H_ */