diff options
author | Gerhard Sittig <gerhard.sittig@gmx.net> | 2020-02-22 06:20:05 +0000 |
---|---|---|
committer | Gerhard Sittig <gerhard.sittig@gmx.net> | 2020-07-18 15:24:02 +0200 |
commit | 6ea75aa1044ef59ee9074f04f0129a3b66c9a491 (patch) | |
tree | 3986ba90035015082d9039e003f6d6425ea6460b /irmp/irmp.c | |
parent | 4342689729bd3ea70209604b34af0a7c641b80cc (diff) | |
download | libsigrokdecode-6ea75aa1044ef59ee9074f04f0129a3b66c9a491.tar.gz libsigrokdecode-6ea75aa1044ef59ee9074f04f0129a3b66c9a491.zip |
irmp: introduce (part of) upstream IRMP sources
Introduce source files and documentation from the GPL'ed IRMP project.
Commit those files which represent the IRMP core logic (detection of
IR frames), and reference the project's homepage for the remainder.
These files correspond to
svn://mikrocontroller.net/irmp r191
Diffstat (limited to 'irmp/irmp.c')
-rw-r--r-- | irmp/irmp.c | 6146 |
1 files changed, 6146 insertions, 0 deletions
diff --git a/irmp/irmp.c b/irmp/irmp.c new file mode 100644 index 0000000..05380b9 --- /dev/null +++ b/irmp/irmp.c @@ -0,0 +1,6146 @@ +/*--------------------------------------------------------------------------------------------------------------------------------------------------- + * irmp.c - infrared multi-protocol decoder, supports several remote control protocols + * + * Copyright (c) 2009-2019 Frank Meyer - frank(at)fli4l.de + * + * Supported AVR mikrocontrollers: + * + * ATtiny87, ATtiny167 + * ATtiny45, ATtiny85 + * ATtiny44, ATtiny84 + * ATmega8, ATmega16, ATmega32 + * ATmega162 + * ATmega164, ATmega324, ATmega644, ATmega644P, ATmega1284, ATmega1284P + * ATmega88, ATmega88P, ATmega168, ATmega168P, ATmega328P + * + * 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. + *--------------------------------------------------------------------------------------------------------------------------------------------------- + */ + +#include "irmp.h" + +#if IRMP_SUPPORT_GRUNDIG_PROTOCOL == 1 || IRMP_SUPPORT_NOKIA_PROTOCOL == 1 || IRMP_SUPPORT_IR60_PROTOCOL == 1 +# define IRMP_SUPPORT_GRUNDIG_NOKIA_IR60_PROTOCOL 1 +#else +# define IRMP_SUPPORT_GRUNDIG_NOKIA_IR60_PROTOCOL 0 +#endif + +#if IRMP_SUPPORT_SIEMENS_PROTOCOL == 1 || IRMP_SUPPORT_RUWIDO_PROTOCOL == 1 +# define IRMP_SUPPORT_SIEMENS_OR_RUWIDO_PROTOCOL 1 +#else +# define IRMP_SUPPORT_SIEMENS_OR_RUWIDO_PROTOCOL 0 +#endif + +#if IRMP_SUPPORT_RC5_PROTOCOL == 1 || \ + IRMP_SUPPORT_RCII_PROTOCOL == 1 || \ + IRMP_SUPPORT_S100_PROTOCOL == 1 || \ + IRMP_SUPPORT_RC6_PROTOCOL == 1 || \ + IRMP_SUPPORT_GRUNDIG_NOKIA_IR60_PROTOCOL == 1 || \ + IRMP_SUPPORT_SIEMENS_OR_RUWIDO_PROTOCOL == 1 || \ + IRMP_SUPPORT_IR60_PROTOCOL == 1 || \ + IRMP_SUPPORT_A1TVBOX_PROTOCOL == 1 || \ + IRMP_SUPPORT_MERLIN_PROTOCOL == 1 || \ + IRMP_SUPPORT_ORTEK_PROTOCOL == 1 +# define IRMP_SUPPORT_MANCHESTER 1 +#else +# define IRMP_SUPPORT_MANCHESTER 0 +#endif + +#if IRMP_SUPPORT_NETBOX_PROTOCOL == 1 +# define IRMP_SUPPORT_SERIAL 1 +#else +# define IRMP_SUPPORT_SERIAL 0 +#endif + +#define IRMP_KEY_REPETITION_LEN (uint_fast16_t)(F_INTERRUPTS * 150.0e-3 + 0.5) // autodetect key repetition within 150 msec + +#define MIN_TOLERANCE_00 1.0 // -0% +#define MAX_TOLERANCE_00 1.0 // +0% + +#define MIN_TOLERANCE_02 0.98 // -2% +#define MAX_TOLERANCE_02 1.02 // +2% + +#define MIN_TOLERANCE_03 0.97 // -3% +#define MAX_TOLERANCE_03 1.03 // +3% + +#define MIN_TOLERANCE_05 0.95 // -5% +#define MAX_TOLERANCE_05 1.05 // +5% + +#define MIN_TOLERANCE_10 0.9 // -10% +#define MAX_TOLERANCE_10 1.1 // +10% + +#define MIN_TOLERANCE_15 0.85 // -15% +#define MAX_TOLERANCE_15 1.15 // +15% + +#define MIN_TOLERANCE_20 0.8 // -20% +#define MAX_TOLERANCE_20 1.2 // +20% + +#define MIN_TOLERANCE_30 0.7 // -30% +#define MAX_TOLERANCE_30 1.3 // +30% + +#define MIN_TOLERANCE_40 0.6 // -40% +#define MAX_TOLERANCE_40 1.4 // +40% + +#define MIN_TOLERANCE_50 0.5 // -50% +#define MAX_TOLERANCE_50 1.5 // +50% + +#define MIN_TOLERANCE_60 0.4 // -60% +#define MAX_TOLERANCE_60 1.6 // +60% + +#define MIN_TOLERANCE_70 0.3 // -70% +#define MAX_TOLERANCE_70 1.7 // +70% + +#define SIRCS_START_BIT_PULSE_LEN_MIN ((uint_fast8_t)(F_INTERRUPTS * SIRCS_START_BIT_PULSE_TIME * MIN_TOLERANCE_10 + 0.5) - 1) +#define SIRCS_START_BIT_PULSE_LEN_MAX ((uint_fast8_t)(F_INTERRUPTS * SIRCS_START_BIT_PULSE_TIME * MAX_TOLERANCE_10 + 0.5) + 1) +#define SIRCS_START_BIT_PAUSE_LEN_MIN ((uint_fast8_t)(F_INTERRUPTS * SIRCS_START_BIT_PAUSE_TIME * MIN_TOLERANCE_20 + 0.5) - 1) +#if IRMP_SUPPORT_NETBOX_PROTOCOL // only 5% to avoid conflict with NETBOX: +# define SIRCS_START_BIT_PAUSE_LEN_MAX ((uint_fast8_t)(F_INTERRUPTS * SIRCS_START_BIT_PAUSE_TIME * MAX_TOLERANCE_05 + 0.5)) +#else // only 5% + 1 to avoid conflict with RC6: +# define SIRCS_START_BIT_PAUSE_LEN_MAX ((uint_fast8_t)(F_INTERRUPTS * SIRCS_START_BIT_PAUSE_TIME * MAX_TOLERANCE_05 + 0.5) + 1) +#endif +#define SIRCS_1_PULSE_LEN_MIN ((uint_fast8_t)(F_INTERRUPTS * SIRCS_1_PULSE_TIME * MIN_TOLERANCE_10 + 0.5) - 1) +#define SIRCS_1_PULSE_LEN_MAX ((uint_fast8_t)(F_INTERRUPTS * SIRCS_1_PULSE_TIME * MAX_TOLERANCE_10 + 0.5) + 1) +#define SIRCS_0_PULSE_LEN_MIN ((uint_fast8_t)(F_INTERRUPTS * SIRCS_0_PULSE_TIME * MIN_TOLERANCE_10 + 0.5) - 1) +#define SIRCS_0_PULSE_LEN_MAX ((uint_fast8_t)(F_INTERRUPTS * SIRCS_0_PULSE_TIME * MAX_TOLERANCE_10 + 0.5) + 1) +#define SIRCS_PAUSE_LEN_MIN ((uint_fast8_t)(F_INTERRUPTS * SIRCS_PAUSE_TIME * MIN_TOLERANCE_10 + 0.5) - 1) +#define SIRCS_PAUSE_LEN_MAX ((uint_fast8_t)(F_INTERRUPTS * SIRCS_PAUSE_TIME * MAX_TOLERANCE_10 + 0.5) + 1) + +#define NEC_START_BIT_PULSE_LEN_MIN ((uint_fast8_t)(F_INTERRUPTS * NEC_START_BIT_PULSE_TIME * MIN_TOLERANCE_30 + 0.5) - 1) +#define NEC_START_BIT_PULSE_LEN_MAX ((uint_fast8_t)(F_INTERRUPTS * NEC_START_BIT_PULSE_TIME * MAX_TOLERANCE_30 + 0.5) + 1) +#define NEC_START_BIT_PAUSE_LEN_MIN ((uint_fast8_t)(F_INTERRUPTS * NEC_START_BIT_PAUSE_TIME * MIN_TOLERANCE_30 + 0.5) - 1) +#define NEC_START_BIT_PAUSE_LEN_MAX ((uint_fast8_t)(F_INTERRUPTS * NEC_START_BIT_PAUSE_TIME * MAX_TOLERANCE_30 + 0.5) + 1) +#define NEC_REPEAT_START_BIT_PAUSE_LEN_MIN ((uint_fast8_t)(F_INTERRUPTS * NEC_REPEAT_START_BIT_PAUSE_TIME * MIN_TOLERANCE_30 + 0.5) - 1) +#define NEC_REPEAT_START_BIT_PAUSE_LEN_MAX ((uint_fast8_t)(F_INTERRUPTS * NEC_REPEAT_START_BIT_PAUSE_TIME * MAX_TOLERANCE_30 + 0.5) + 1) +#define NEC_PULSE_LEN_MIN ((uint_fast8_t)(F_INTERRUPTS * NEC_PULSE_TIME * MIN_TOLERANCE_30 + 0.5) - 1) +#define NEC_PULSE_LEN_MAX ((uint_fast8_t)(F_INTERRUPTS * NEC_PULSE_TIME * MAX_TOLERANCE_30 + 0.5) + 1) +#define NEC_1_PAUSE_LEN_MIN ((uint_fast8_t)(F_INTERRUPTS * NEC_1_PAUSE_TIME * MIN_TOLERANCE_30 + 0.5) - 1) +#define NEC_1_PAUSE_LEN_MAX ((uint_fast8_t)(F_INTERRUPTS * NEC_1_PAUSE_TIME * MAX_TOLERANCE_30 + 0.5) + 1) +#define NEC_0_PAUSE_LEN_MIN ((uint_fast8_t)(F_INTERRUPTS * NEC_0_PAUSE_TIME * MIN_TOLERANCE_30 + 0.5) - 1) +#define NEC_0_PAUSE_LEN_MAX ((uint_fast8_t)(F_INTERRUPTS * NEC_0_PAUSE_TIME * MAX_TOLERANCE_30 + 0.5) + 1) +// autodetect nec repetition frame within 50 msec: +// NEC seems to send the first repetition frame after 40ms, further repetition frames after 100 ms +#if 0 +#define NEC_FRAME_REPEAT_PAUSE_LEN_MAX (uint_fast16_t)(F_INTERRUPTS * NEC_FRAME_REPEAT_PAUSE_TIME * MAX_TOLERANCE_20 + 0.5) +#else +#define NEC_FRAME_REPEAT_PAUSE_LEN_MAX (uint_fast16_t)(F_INTERRUPTS * 100.0e-3 * MAX_TOLERANCE_20 + 0.5) +#endif + +#define SAMSUNG_START_BIT_PULSE_LEN_MIN ((uint_fast8_t)(F_INTERRUPTS * SAMSUNG_START_BIT_PULSE_TIME * MIN_TOLERANCE_10 + 0.5) - 1) +#define SAMSUNG_START_BIT_PULSE_LEN_MAX ((uint_fast8_t)(F_INTERRUPTS * SAMSUNG_START_BIT_PULSE_TIME * MAX_TOLERANCE_10 + 0.5) + 1) +#define SAMSUNG_START_BIT_PAUSE_LEN_MIN ((uint_fast8_t)(F_INTERRUPTS * SAMSUNG_START_BIT_PAUSE_TIME * MIN_TOLERANCE_10 + 0.5) - 1) +#define SAMSUNG_START_BIT_PAUSE_LEN_MAX ((uint_fast8_t)(F_INTERRUPTS * SAMSUNG_START_BIT_PAUSE_TIME * MAX_TOLERANCE_10 + 0.5) + 1) +#define SAMSUNG_PULSE_LEN_MIN ((uint_fast8_t)(F_INTERRUPTS * SAMSUNG_PULSE_TIME * MIN_TOLERANCE_30 + 0.5) - 1) +#define SAMSUNG_PULSE_LEN_MAX ((uint_fast8_t)(F_INTERRUPTS * SAMSUNG_PULSE_TIME * MAX_TOLERANCE_30 + 0.5) + 1) +#define SAMSUNG_1_PAUSE_LEN_MIN ((uint_fast8_t)(F_INTERRUPTS * SAMSUNG_1_PAUSE_TIME * MIN_TOLERANCE_30 + 0.5) - 1) +#define SAMSUNG_1_PAUSE_LEN_MAX ((uint_fast8_t)(F_INTERRUPTS * SAMSUNG_1_PAUSE_TIME * MAX_TOLERANCE_30 + 0.5) + 1) +#define SAMSUNG_0_PAUSE_LEN_MIN ((uint_fast8_t)(F_INTERRUPTS * SAMSUNG_0_PAUSE_TIME * MIN_TOLERANCE_30 + 0.5) - 1) +#define SAMSUNG_0_PAUSE_LEN_MAX ((uint_fast8_t)(F_INTERRUPTS * SAMSUNG_0_PAUSE_TIME * MAX_TOLERANCE_30 + 0.5) + 1) + +#define SAMSUNGAH_START_BIT_PULSE_LEN_MIN ((uint_fast8_t)(F_INTERRUPTS * SAMSUNGAH_START_BIT_PULSE_TIME * MIN_TOLERANCE_10 + 0.5) - 1) +#define SAMSUNGAH_START_BIT_PULSE_LEN_MAX ((uint_fast8_t)(F_INTERRUPTS * SAMSUNGAH_START_BIT_PULSE_TIME * MAX_TOLERANCE_10 + 0.5) + 1) +#define SAMSUNGAH_START_BIT_PAUSE_LEN_MIN ((uint_fast8_t)(F_INTERRUPTS * SAMSUNGAH_START_BIT_PAUSE_TIME * MIN_TOLERANCE_10 + 0.5) - 1) +#define SAMSUNGAH_START_BIT_PAUSE_LEN_MAX ((uint_fast8_t)(F_INTERRUPTS * SAMSUNGAH_START_BIT_PAUSE_TIME * MAX_TOLERANCE_10 + 0.5) + 1) +#define SAMSUNGAH_PULSE_LEN_MIN ((uint_fast8_t)(F_INTERRUPTS * SAMSUNGAH_PULSE_TIME * MIN_TOLERANCE_30 + 0.5) - 1) +#define SAMSUNGAH_PULSE_LEN_MAX ((uint_fast8_t)(F_INTERRUPTS * SAMSUNGAH_PULSE_TIME * MAX_TOLERANCE_30 + 0.5) + 1) +#define SAMSUNGAH_1_PAUSE_LEN_MIN ((uint_fast8_t)(F_INTERRUPTS * SAMSUNGAH_1_PAUSE_TIME * MIN_TOLERANCE_30 + 0.5) - 1) +#define SAMSUNGAH_1_PAUSE_LEN_MAX ((uint_fast8_t)(F_INTERRUPTS * SAMSUNGAH_1_PAUSE_TIME * MAX_TOLERANCE_30 + 0.5) + 1) +#define SAMSUNGAH_0_PAUSE_LEN_MIN ((uint_fast8_t)(F_INTERRUPTS * SAMSUNGAH_0_PAUSE_TIME * MIN_TOLERANCE_30 + 0.5) - 1) +#define SAMSUNGAH_0_PAUSE_LEN_MAX ((uint_fast8_t)(F_INTERRUPTS * SAMSUNGAH_0_PAUSE_TIME * MAX_TOLERANCE_30 + 0.5) + 1) + +#define MATSUSHITA_START_BIT_PULSE_LEN_MIN ((uint_fast8_t)(F_INTERRUPTS * MATSUSHITA_START_BIT_PULSE_TIME * MIN_TOLERANCE_20 + 0.5) - 1) +#define MATSUSHITA_START_BIT_PULSE_LEN_MAX ((uint_fast8_t)(F_INTERRUPTS * MATSUSHITA_START_BIT_PULSE_TIME * MAX_TOLERANCE_20 + 0.5) + 1) +#define MATSUSHITA_START_BIT_PAUSE_LEN_MIN ((uint_fast8_t)(F_INTERRUPTS * MATSUSHITA_START_BIT_PAUSE_TIME * MIN_TOLERANCE_20 + 0.5) - 1) +#define MATSUSHITA_START_BIT_PAUSE_LEN_MAX ((uint_fast8_t)(F_INTERRUPTS * MATSUSHITA_START_BIT_PAUSE_TIME * MAX_TOLERANCE_20 + 0.5) + 1) +#define MATSUSHITA_PULSE_LEN_MIN ((uint_fast8_t)(F_INTERRUPTS * MATSUSHITA_PULSE_TIME * MIN_TOLERANCE_40 + 0.5) - 1) +#define MATSUSHITA_PULSE_LEN_MAX ((uint_fast8_t)(F_INTERRUPTS * MATSUSHITA_PULSE_TIME * MAX_TOLERANCE_40 + 0.5) + 1) +#define MATSUSHITA_1_PAUSE_LEN_MIN ((uint_fast8_t)(F_INTERRUPTS * MATSUSHITA_1_PAUSE_TIME * MIN_TOLERANCE_40 + 0.5) - 1) +#define MATSUSHITA_1_PAUSE_LEN_MAX ((uint_fast8_t)(F_INTERRUPTS * MATSUSHITA_1_PAUSE_TIME * MAX_TOLERANCE_40 + 0.5) + 1) +#define MATSUSHITA_0_PAUSE_LEN_MIN ((uint_fast8_t)(F_INTERRUPTS * MATSUSHITA_0_PAUSE_TIME * MIN_TOLERANCE_40 + 0.5) - 1) +#define MATSUSHITA_0_PAUSE_LEN_MAX ((uint_fast8_t)(F_INTERRUPTS * MATSUSHITA_0_PAUSE_TIME * MAX_TOLERANCE_40 + 0.5) + 1) + +#define KASEIKYO_START_BIT_PULSE_LEN_MIN ((uint_fast8_t)(F_INTERRUPTS * KASEIKYO_START_BIT_PULSE_TIME * MIN_TOLERANCE_20 + 0.5) - 1) +#define KASEIKYO_START_BIT_PULSE_LEN_MAX ((uint_fast8_t)(F_INTERRUPTS * KASEIKYO_START_BIT_PULSE_TIME * MAX_TOLERANCE_20 + 0.5) + 1) +#define KASEIKYO_START_BIT_PAUSE_LEN_MIN ((uint_fast8_t)(F_INTERRUPTS * KASEIKYO_START_BIT_PAUSE_TIME * MIN_TOLERANCE_20 + 0.5) - 1) +#define KASEIKYO_START_BIT_PAUSE_LEN_MAX ((uint_fast8_t)(F_INTERRUPTS * KASEIKYO_START_BIT_PAUSE_TIME * MAX_TOLERANCE_20 + 0.5) + 1) +#define KASEIKYO_PULSE_LEN_MIN ((uint_fast8_t)(F_INTERRUPTS * KASEIKYO_PULSE_TIME * MIN_TOLERANCE_40 + 0.5) - 1) +#define KASEIKYO_PULSE_LEN_MAX ((uint_fast8_t)(F_INTERRUPTS * KASEIKYO_PULSE_TIME * MAX_TOLERANCE_40 + 0.5) + 1) +#define KASEIKYO_1_PAUSE_LEN_MIN ((uint_fast8_t)(F_INTERRUPTS * KASEIKYO_1_PAUSE_TIME * MIN_TOLERANCE_20 + 0.5) - 1) +#define KASEIKYO_1_PAUSE_LEN_MAX ((uint_fast8_t)(F_INTERRUPTS * KASEIKYO_1_PAUSE_TIME * MAX_TOLERANCE_20 + 0.5) + 1) +#define KASEIKYO_0_PAUSE_LEN_MIN ((uint_fast8_t)(F_INTERRUPTS * KASEIKYO_0_PAUSE_TIME * MIN_TOLERANCE_20 + 0.5) - 1) +#define KASEIKYO_0_PAUSE_LEN_MAX ((uint_fast8_t)(F_INTERRUPTS * KASEIKYO_0_PAUSE_TIME * MAX_TOLERANCE_20 + 0.5) + 1) + +#define MITSU_HEAVY_START_BIT_PULSE_LEN_MIN ((uint_fast8_t)(F_INTERRUPTS * MITSU_HEAVY_START_BIT_PULSE_TIME * MIN_TOLERANCE_10 + 0.5) - 1) +#define MITSU_HEAVY_START_BIT_PULSE_LEN_MAX ((uint_fast8_t)(F_INTERRUPTS * MITSU_HEAVY_START_BIT_PULSE_TIME * MAX_TOLERANCE_10 + 0.5) + 1) +#define MITSU_HEAVY_START_BIT_PAUSE_LEN_MIN ((uint_fast8_t)(F_INTERRUPTS * MITSU_HEAVY_START_BIT_PAUSE_TIME * MIN_TOLERANCE_10 + 0.5) - 1) +#define MITSU_HEAVY_START_BIT_PAUSE_LEN_MAX ((uint_fast8_t)(F_INTERRUPTS * MITSU_HEAVY_START_BIT_PAUSE_TIME * MAX_TOLERANCE_10 + 0.5) + 1) +#define MITSU_HEAVY_PULSE_LEN_MIN ((uint_fast8_t)(F_INTERRUPTS * MITSU_HEAVY_PULSE_TIME * MIN_TOLERANCE_40 + 0.5) - 1) +#define MITSU_HEAVY_PULSE_LEN_MAX ((uint_fast8_t)(F_INTERRUPTS * MITSU_HEAVY_PULSE_TIME * MAX_TOLERANCE_40 + 0.5) + 1) +#define MITSU_HEAVY_1_PAUSE_LEN_MIN ((uint_fast8_t)(F_INTERRUPTS * MITSU_HEAVY_1_PAUSE_TIME * MIN_TOLERANCE_20 + 0.5) - 1) +#define MITSU_HEAVY_1_PAUSE_LEN_MAX ((uint_fast8_t)(F_INTERRUPTS * MITSU_HEAVY_1_PAUSE_TIME * MAX_TOLERANCE_20 + 0.5) + 1) +#define MITSU_HEAVY_0_PAUSE_LEN_MIN ((uint_fast8_t)(F_INTERRUPTS * MITSU_HEAVY_0_PAUSE_TIME * MIN_TOLERANCE_20 + 0.5) - 1) +#define MITSU_HEAVY_0_PAUSE_LEN_MAX ((uint_fast8_t)(F_INTERRUPTS * MITSU_HEAVY_0_PAUSE_TIME * MAX_TOLERANCE_20 + 0.5) + 1) + +#define VINCENT_START_BIT_PULSE_LEN_MIN ((uint_fast8_t)(F_INTERRUPTS * VINCENT_START_BIT_PULSE_TIME * MIN_TOLERANCE_10 + 0.5) - 1) +#define VINCENT_START_BIT_PULSE_LEN_MAX ((uint_fast8_t)(F_INTERRUPTS * VINCENT_START_BIT_PULSE_TIME * MAX_TOLERANCE_10 + 0.5) + 1) +#define VINCENT_START_BIT_PAUSE_LEN_MIN ((uint_fast8_t)(F_INTERRUPTS * VINCENT_START_BIT_PAUSE_TIME * MIN_TOLERANCE_10 + 0.5) - 1) +#define VINCENT_START_BIT_PAUSE_LEN_MAX ((uint_fast8_t)(F_INTERRUPTS * VINCENT_START_BIT_PAUSE_TIME * MAX_TOLERANCE_10 + 0.5) + 1) +#define VINCENT_PULSE_LEN_MIN ((uint_fast8_t)(F_INTERRUPTS * VINCENT_PULSE_TIME * MIN_TOLERANCE_40 + 0.5) - 1) +#define VINCENT_PULSE_LEN_MAX ((uint_fast8_t)(F_INTERRUPTS * VINCENT_PULSE_TIME * MAX_TOLERANCE_40 + 0.5) + 1) +#define VINCENT_1_PAUSE_LEN_MIN ((uint_fast8_t)(F_INTERRUPTS * VINCENT_1_PAUSE_TIME * MIN_TOLERANCE_20 + 0.5) - 1) +#define VINCENT_1_PAUSE_LEN_MAX ((uint_fast8_t)(F_INTERRUPTS * VINCENT_1_PAUSE_TIME * MAX_TOLERANCE_20 + 0.5) + 1) +#define VINCENT_0_PAUSE_LEN_MIN ((uint_fast8_t)(F_INTERRUPTS * VINCENT_0_PAUSE_TIME * MIN_TOLERANCE_20 + 0.5) - 1) +#define VINCENT_0_PAUSE_LEN_MAX ((uint_fast8_t)(F_INTERRUPTS * VINCENT_0_PAUSE_TIME * MAX_TOLERANCE_20 + 0.5) + 1) + +#define PANASONIC_START_BIT_PULSE_LEN_MIN ((uint_fast8_t)(F_INTERRUPTS * PANASONIC_START_BIT_PULSE_TIME * MIN_TOLERANCE_10 + 0.5) - 1) +#define PANASONIC_START_BIT_PULSE_LEN_MAX ((uint_fast8_t)(F_INTERRUPTS * PANASONIC_START_BIT_PULSE_TIME * MAX_TOLERANCE_10 + 0.5) + 1) +#define PANASONIC_START_BIT_PAUSE_LEN_MIN ((uint_fast8_t)(F_INTERRUPTS * PANASONIC_START_BIT_PAUSE_TIME * MIN_TOLERANCE_10 + 0.5) - 1) +#define PANASONIC_START_BIT_PAUSE_LEN_MAX ((uint_fast8_t)(F_INTERRUPTS * PANASONIC_START_BIT_PAUSE_TIME * MAX_TOLERANCE_10 + 0.5) + 1) +#define PANASONIC_PULSE_LEN_MIN ((uint_fast8_t)(F_INTERRUPTS * PANASONIC_PULSE_TIME * MIN_TOLERANCE_40 + 0.5) - 1) +#define PANASONIC_PULSE_LEN_MAX ((uint_fast8_t)(F_INTERRUPTS * PANASONIC_PULSE_TIME * MAX_TOLERANCE_40 + 0.5) + 1) +#define PANASONIC_1_PAUSE_LEN_MIN ((uint_fast8_t)(F_INTERRUPTS * PANASONIC_1_PAUSE_TIME * MIN_TOLERANCE_20 + 0.5) - 1) +#define PANASONIC_1_PAUSE_LEN_MAX ((uint_fast8_t)(F_INTERRUPTS * PANASONIC_1_PAUSE_TIME * MAX_TOLERANCE_20 + 0.5) + 1) +#define PANASONIC_0_PAUSE_LEN_MIN ((uint_fast8_t)(F_INTERRUPTS * PANASONIC_0_PAUSE_TIME * MIN_TOLERANCE_20 + 0.5) - 1) +#define PANASONIC_0_PAUSE_LEN_MAX ((uint_fast8_t)(F_INTERRUPTS * PANASONIC_0_PAUSE_TIME * MAX_TOLERANCE_20 + 0.5) + 1) + +#define RECS80_START_BIT_PULSE_LEN_MIN ((uint_fast8_t)(F_INTERRUPTS * RECS80_START_BIT_PULSE_TIME * MIN_TOLERANCE_20 + 0.5) - 1) +#define RECS80_START_BIT_PULSE_LEN_MAX ((uint_fast8_t)(F_INTERRUPTS * RECS80_START_BIT_PULSE_TIME * MAX_TOLERANCE_20 + 0.5) + 1) +#define RECS80_START_BIT_PAUSE_LEN_MIN ((uint_fast8_t)(F_INTERRUPTS * RECS80_START_BIT_PAUSE_TIME * MIN_TOLERANCE_10 + 0.5) - 1) +#define RECS80_START_BIT_PAUSE_LEN_MAX ((uint_fast8_t)(F_INTERRUPTS * RECS80_START_BIT_PAUSE_TIME * MAX_TOLERANCE_10 + 0.5) + 1) +#define RECS80_PULSE_LEN_MIN ((uint_fast8_t)(F_INTERRUPTS * RECS80_PULSE_TIME * MIN_TOLERANCE_20 + 0.5) - 1) +#define RECS80_PULSE_LEN_MAX ((uint_fast8_t)(F_INTERRUPTS * RECS80_PULSE_TIME * MAX_TOLERANCE_20 + 0.5) + 1) +#define RECS80_1_PAUSE_LEN_MIN ((uint_fast8_t)(F_INTERRUPTS * RECS80_1_PAUSE_TIME * MIN_TOLERANCE_10 + 0.5) - 1) +#define RECS80_1_PAUSE_LEN_MAX ((uint_fast8_t)(F_INTERRUPTS * RECS80_1_PAUSE_TIME * MAX_TOLERANCE_10 + 0.5) + 1) +#define RECS80_0_PAUSE_LEN_MIN ((uint_fast8_t)(F_INTERRUPTS * RECS80_0_PAUSE_TIME * MIN_TOLERANCE_10 + 0.5) - 1) +#define RECS80_0_PAUSE_LEN_MAX ((uint_fast8_t)(F_INTERRUPTS * RECS80_0_PAUSE_TIME * MAX_TOLERANCE_10 + 0.5) + 1) + +#if IRMP_SUPPORT_BOSE_PROTOCOL == 1 // BOSE conflicts with RC5, so keep tolerance for RC5 minimal here: +#define RC5_START_BIT_LEN_MIN ((uint_fast8_t)(F_INTERRUPTS * RC5_BIT_TIME * MIN_TOLERANCE_05 + 0.5) - 1) +#define RC5_START_BIT_LEN_MAX ((uint_fast8_t)(F_INTERRUPTS * RC5_BIT_TIME * MAX_TOLERANCE_05 + 0.5) + 1) +#else +#define RC5_START_BIT_LEN_MIN ((uint_fast8_t)(F_INTERRUPTS * RC5_BIT_TIME * MIN_TOLERANCE_10 + 0.5) - 1) +#define RC5_START_BIT_LEN_MAX ((uint_fast8_t)(F_INTERRUPTS * RC5_BIT_TIME * MAX_TOLERANCE_10 + 0.5) + 1) +#endif + +#define RC5_BIT_LEN_MIN ((uint_fast8_t)(F_INTERRUPTS * RC5_BIT_TIME * MIN_TOLERANCE_10 + 0.5) - 1) +#define RC5_BIT_LEN_MAX ((uint_fast8_t)(F_INTERRUPTS * RC5_BIT_TIME * MAX_TOLERANCE_10 + 0.5) + 1) + +#define RCII_START_BIT_PULSE_LEN_MIN ((uint_fast8_t)(F_INTERRUPTS * RCII_START_BIT_PULSE_TIME * MIN_TOLERANCE_05 + 0.5) - 1) +#define RCII_START_BIT_PULSE_LEN_MAX ((uint_fast8_t)(F_INTERRUPTS * RCII_START_BIT_PULSE_TIME * MAX_TOLERANCE_05 + 0.5) + 1) +#define RCII_START_BIT_PAUSE_LEN_MIN ((uint_fast8_t)(F_INTERRUPTS * RCII_START_BIT_PAUSE_TIME * MIN_TOLERANCE_05 + 0.5) - 1) +#define RCII_START_BIT_PAUSE_LEN_MAX ((uint_fast8_t)(F_INTERRUPTS * RCII_START_BIT_PAUSE_TIME * MAX_TOLERANCE_05 + 0.5) + 1) +#define RCII_START_BIT2_PULSE_LEN_MIN ((uint_fast8_t)(F_INTERRUPTS * RCII_START_BIT2_PULSE_TIME * MIN_TOLERANCE_05 + 0.5) - 1) +#define RCII_START_BIT2_PULSE_LEN_MAX ((uint_fast8_t)(F_INTERRUPTS * RCII_START_BIT2_PULSE_TIME * MAX_TOLERANCE_05 + 0.5) + 1) + +#define RCII_BIT_LEN_MIN ((uint_fast8_t)(F_INTERRUPTS * RCII_BIT_TIME * MIN_TOLERANCE_30 + 0.5) - 1) +#define RCII_BIT_LEN ((uint_fast8_t)(F_INTERRUPTS * RCII_BIT_TIME)) +#define RCII_BIT_LEN_MAX ((uint_fast8_t)(F_INTERRUPTS * RCII_BIT_TIME * MAX_TOLERANCE_30 + 0.5) + 1) + +#if IRMP_SUPPORT_BOSE_PROTOCOL == 1 // BOSE conflicts with S100, so keep tolerance for S100 minimal here: +#define S100_START_BIT_LEN_MIN ((uint_fast8_t)(F_INTERRUPTS * S100_BIT_TIME * MIN_TOLERANCE_05 + 0.5) - 1) +#define S100_START_BIT_LEN_MAX ((uint_fast8_t)(F_INTERRUPTS * S100_BIT_TIME * MAX_TOLERANCE_05 + 0.5) + 1) +#else +#define S100_START_BIT_LEN_MIN ((uint_fast8_t)(F_INTERRUPTS * S100_BIT_TIME * MIN_TOLERANCE_10 + 0.5) - 1) +#define S100_START_BIT_LEN_MAX ((uint_fast8_t)(F_INTERRUPTS * S100_BIT_TIME * MAX_TOLERANCE_10 + 0.5) + 1) +#endif + +#define S100_BIT_LEN_MIN ((uint_fast8_t)(F_INTERRUPTS * S100_BIT_TIME * MIN_TOLERANCE_10 + 0.5) - 1) +#define S100_BIT_LEN_MAX ((uint_fast8_t)(F_INTERRUPTS * S100_BIT_TIME * MAX_TOLERANCE_10 + 0.5) + 1) + +#define DENON_PULSE_LEN_MIN ((uint_fast8_t)(F_INTERRUPTS * DENON_PULSE_TIME * MIN_TOLERANCE_10 + 0.5) - 1) +#define DENON_PULSE_LEN_MAX ((uint_fast8_t)(F_INTERRUPTS * DENON_PULSE_TIME * MAX_TOLERANCE_20 + 0.5) + 1) +#define DENON_1_PAUSE_LEN_MIN ((uint_fast8_t)(F_INTERRUPTS * DENON_1_PAUSE_TIME * MIN_TOLERANCE_10 + 0.5) - 1) +#define DENON_1_PAUSE_LEN_MAX ((uint_fast8_t)(F_INTERRUPTS * DENON_1_PAUSE_TIME * MAX_TOLERANCE_10 + 0.5) + 1) +// RUWIDO (see t-home-mediareceiver-15kHz.txt) conflicts here with DENON +#define DENON_0_PAUSE_LEN_MIN ((uint_fast8_t)(F_INTERRUPTS * DENON_0_PAUSE_TIME * MIN_TOLERANCE_10 + 0.5) - 1) +#define DENON_0_PAUSE_LEN_MAX ((uint_fast8_t)(F_INTERRUPTS * DENON_0_PAUSE_TIME * MAX_TOLERANCE_10 + 0.5) + 1) +#define DENON_AUTO_REPETITION_PAUSE_LEN ((uint_fast16_t)(F_INTERRUPTS * DENON_AUTO_REPETITION_PAUSE_TIME * MAX_TOLERANCE_10 + 0.5) + 1) + +#define THOMSON_PULSE_LEN_MIN ((uint_fast8_t)(F_INTERRUPTS * THOMSON_PULSE_TIME * MIN_TOLERANCE_10 + 0.5) - 1) +#define THOMSON_PULSE_LEN_MAX ((uint_fast8_t)(F_INTERRUPTS * THOMSON_PULSE_TIME * MAX_TOLERANCE_10 + 0.5) + 1) +#define THOMSON_1_PAUSE_LEN_MIN ((uint_fast8_t)(F_INTERRUPTS * THOMSON_1_PAUSE_TIME * MIN_TOLERANCE_10 + 0.5) - 1) +#define THOMSON_1_PAUSE_LEN_MAX ((uint_fast8_t)(F_INTERRUPTS * THOMSON_1_PAUSE_TIME * MAX_TOLERANCE_10 + 0.5) + 1) +#define THOMSON_0_PAUSE_LEN_MIN ((uint_fast8_t)(F_INTERRUPTS * THOMSON_0_PAUSE_TIME * MIN_TOLERANCE_10 + 0.5) - 1) +#define THOMSON_0_PAUSE_LEN_MAX ((uint_fast8_t)(F_INTERRUPTS * THOMSON_0_PAUSE_TIME * MAX_TOLERANCE_10 + 0.5) + 1) + +#define RC6_START_BIT_PULSE_LEN_MIN ((uint_fast8_t)(F_INTERRUPTS * RC6_START_BIT_PULSE_TIME * MIN_TOLERANCE_10 + 0.5) - 1) +#define RC6_START_BIT_PULSE_LEN_MAX ((uint_fast8_t)(F_INTERRUPTS * RC6_START_BIT_PULSE_TIME * MAX_TOLERANCE_10 + 0.5) + 1) +#define RC6_START_BIT_PAUSE_LEN_MIN ((uint_fast8_t)(F_INTERRUPTS * RC6_START_BIT_PAUSE_TIME * MIN_TOLERANCE_10 + 0.5) - 1) +#define RC6_START_BIT_PAUSE_LEN_MAX ((uint_fast8_t)(F_INTERRUPTS * RC6_START_BIT_PAUSE_TIME * MAX_TOLERANCE_10 + 0.5) + 1) +#define RC6_TOGGLE_BIT_LEN_MIN ((uint_fast8_t)(F_INTERRUPTS * RC6_TOGGLE_BIT_TIME * MIN_TOLERANCE_10 + 0.5) - 1) +#define RC6_TOGGLE_BIT_LEN_MAX ((uint_fast8_t)(F_INTERRUPTS * RC6_TOGGLE_BIT_TIME * MAX_TOLERANCE_10 + 0.5) + 1) +#define RC6_BIT_PULSE_LEN_MIN ((uint_fast8_t)(F_INTERRUPTS * RC6_BIT_TIME * MIN_TOLERANCE_10 + 0.5) - 1) +#define RC6_BIT_PULSE_LEN_MAX ((uint_fast8_t)(F_INTERRUPTS * RC6_BIT_TIME * MAX_TOLERANCE_60 + 0.5) + 1) // pulses: 300 - 800 +#define RC6_BIT_PAUSE_LEN_MIN ((uint_fast8_t)(F_INTERRUPTS * RC6_BIT_TIME * MIN_TOLERANCE_10 + 0.5) - 1) +#define RC6_BIT_PAUSE_LEN_MAX ((uint_fast8_t)(F_INTERRUPTS * RC6_BIT_TIME * MAX_TOLERANCE_20 + 0.5) + 1) // pauses: 300 - 600 + +#define RECS80EXT_START_BIT_PULSE_LEN_MIN ((uint_fast8_t)(F_INTERRUPTS * RECS80EXT_START_BIT_PULSE_TIME * MIN_TOLERANCE_20 + 0.5) - 1) +#define RECS80EXT_START_BIT_PULSE_LEN_MAX ((uint_fast8_t)(F_INTERRUPTS * RECS80EXT_START_BIT_PULSE_TIME * MAX_TOLERANCE_20 + 0.5) + 1) +#define RECS80EXT_START_BIT_PAUSE_LEN_MIN ((uint_fast8_t)(F_INTERRUPTS * RECS80EXT_START_BIT_PAUSE_TIME * MIN_TOLERANCE_10 + 0.5) - 1) +#define RECS80EXT_START_BIT_PAUSE_LEN_MAX ((uint_fast8_t)(F_INTERRUPTS * RECS80EXT_START_BIT_PAUSE_TIME * MAX_TOLERANCE_10 + 0.5) + 1) +#define RECS80EXT_PULSE_LEN_MIN ((uint_fast8_t)(F_INTERRUPTS * RECS80EXT_PULSE_TIME * MIN_TOLERANCE_20 + 0.5) - 1) +#define RECS80EXT_PULSE_LEN_MAX ((uint_fast8_t)(F_INTERRUPTS * RECS80EXT_PULSE_TIME * MAX_TOLERANCE_20 + 0.5) + 1) +#define RECS80EXT_1_PAUSE_LEN_MIN ((uint_fast8_t)(F_INTERRUPTS * RECS80EXT_1_PAUSE_TIME * MIN_TOLERANCE_10 + 0.5) - 1) +#define RECS80EXT_1_PAUSE_LEN_MAX ((uint_fast8_t)(F_INTERRUPTS * RECS80EXT_1_PAUSE_TIME * MAX_TOLERANCE_10 + 0.5) + 1) +#define RECS80EXT_0_PAUSE_LEN_MIN ((uint_fast8_t)(F_INTERRUPTS * RECS80EXT_0_PAUSE_TIME * MIN_TOLERANCE_10 + 0.5) - 1) +#define RECS80EXT_0_PAUSE_LEN_MAX ((uint_fast8_t)(F_INTERRUPTS * RECS80EXT_0_PAUSE_TIME * MAX_TOLERANCE_10 + 0.5) + 1) + +#define NUBERT_START_BIT_PULSE_LEN_MIN ((uint_fast8_t)(F_INTERRUPTS * NUBERT_START_BIT_PULSE_TIME * MIN_TOLERANCE_20 + 0.5) - 1) +#define NUBERT_START_BIT_PULSE_LEN_MAX ((uint_fast8_t)(F_INTERRUPTS * NUBERT_START_BIT_PULSE_TIME * MAX_TOLERANCE_20 + 0.5) + 1) +#define NUBERT_START_BIT_PAUSE_LEN_MIN ((uint_fast8_t)(F_INTERRUPTS * NUBERT_START_BIT_PAUSE_TIME * MIN_TOLERANCE_20 + 0.5) - 1) +#define NUBERT_START_BIT_PAUSE_LEN_MAX ((uint_fast8_t)(F_INTERRUPTS * NUBERT_START_BIT_PAUSE_TIME * MAX_TOLERANCE_20 + 0.5) + 1) +#define NUBERT_1_PULSE_LEN_MIN ((uint_fast8_t)(F_INTERRUPTS * NUBERT_1_PULSE_TIME * MIN_TOLERANCE_20 + 0.5) - 1) +#define NUBERT_1_PULSE_LEN_MAX ((uint_fast8_t)(F_INTERRUPTS * NUBERT_1_PULSE_TIME * MAX_TOLERANCE_20 + 0.5) + 1) +#define NUBERT_1_PAUSE_LEN_MIN ((uint_fast8_t)(F_INTERRUPTS * NUBERT_1_PAUSE_TIME * MIN_TOLERANCE_20 + 0.5) - 1) +#define NUBERT_1_PAUSE_LEN_MAX ((uint_fast8_t)(F_INTERRUPTS * NUBERT_1_PAUSE_TIME * MAX_TOLERANCE_20 + 0.5) + 1) +#define NUBERT_0_PULSE_LEN_MIN ((uint_fast8_t)(F_INTERRUPTS * NUBERT_0_PULSE_TIME * MIN_TOLERANCE_20 + 0.5) - 1) +#define NUBERT_0_PULSE_LEN_MAX ((uint_fast8_t)(F_INTERRUPTS * NUBERT_0_PULSE_TIME * MAX_TOLERANCE_20 + 0.5) + 1) +#define NUBERT_0_PAUSE_LEN_MIN ((uint_fast8_t)(F_INTERRUPTS * NUBERT_0_PAUSE_TIME * MIN_TOLERANCE_20 + 0.5) - 1) +#define NUBERT_0_PAUSE_LEN_MAX ((uint_fast8_t)(F_INTERRUPTS * NUBERT_0_PAUSE_TIME * MAX_TOLERANCE_20 + 0.5) + 1) + +#define FAN_START_BIT_PULSE_LEN_MIN ((uint_fast8_t)(F_INTERRUPTS * FAN_START_BIT_PULSE_TIME * MIN_TOLERANCE_20 + 0.5) - 1) +#define FAN_START_BIT_PULSE_LEN_MAX ((uint_fast8_t)(F_INTERRUPTS * FAN_START_BIT_PULSE_TIME * MAX_TOLERANCE_20 + 0.5) + 1) +#define FAN_START_BIT_PAUSE_LEN_MIN ((uint_fast8_t)(F_INTERRUPTS * FAN_START_BIT_PAUSE_TIME * MIN_TOLERANCE_20 + 0.5) - 1) +#define FAN_START_BIT_PAUSE_LEN_MAX ((uint_fast8_t)(F_INTERRUPTS * FAN_START_BIT_PAUSE_TIME * MAX_TOLERANCE_20 + 0.5) + 1) +#define FAN_1_PULSE_LEN_MIN ((uint_fast8_t)(F_INTERRUPTS * FAN_1_PULSE_TIME * MIN_TOLERANCE_20 + 0.5) - 1) +#define FAN_1_PULSE_LEN_MAX ((uint_fast8_t)(F_INTERRUPTS * FAN_1_PULSE_TIME * MAX_TOLERANCE_20 + 0.5) + 1) +#define FAN_1_PAUSE_LEN_MIN ((uint_fast8_t)(F_INTERRUPTS * FAN_1_PAUSE_TIME * MIN_TOLERANCE_20 + 0.5) - 1) +#define FAN_1_PAUSE_LEN_MAX ((uint_fast8_t)(F_INTERRUPTS * FAN_1_PAUSE_TIME * MAX_TOLERANCE_20 + 0.5) + 1) +#define FAN_0_PULSE_LEN_MIN ((uint_fast8_t)(F_INTERRUPTS * FAN_0_PULSE_TIME * MIN_TOLERANCE_20 + 0.5) - 1) +#define FAN_0_PULSE_LEN_MAX ((uint_fast8_t)(F_INTERRUPTS * FAN_0_PULSE_TIME * MAX_TOLERANCE_20 + 0.5) + 1) +#define FAN_0_PAUSE_LEN_MIN ((uint_fast8_t)(F_INTERRUPTS * FAN_0_PAUSE_TIME * MIN_TOLERANCE_20 + 0.5) - 1) +#define FAN_0_PAUSE_LEN_MAX ((uint_fast8_t)(F_INTERRUPTS * FAN_0_PAUSE_TIME * MAX_TOLERANCE_20 + 0.5) + 1) + +#define SPEAKER_START_BIT_PULSE_LEN_MIN ((uint_fast8_t)(F_INTERRUPTS * SPEAKER_START_BIT_PULSE_TIME * MIN_TOLERANCE_20 + 0.5) - 1) +#define SPEAKER_START_BIT_PULSE_LEN_MAX ((uint_fast8_t)(F_INTERRUPTS * SPEAKER_START_BIT_PULSE_TIME * MAX_TOLERANCE_20 + 0.5) + 1) +#define SPEAKER_START_BIT_PAUSE_LEN_MIN ((uint_fast8_t)(F_INTERRUPTS * SPEAKER_START_BIT_PAUSE_TIME * MIN_TOLERANCE_20 + 0.5) - 1) +#define SPEAKER_START_BIT_PAUSE_LEN_MAX ((uint_fast8_t)(F_INTERRUPTS * SPEAKER_START_BIT_PAUSE_TIME * MAX_TOLERANCE_20 + 0.5) + 1) +#define SPEAKER_1_PULSE_LEN_MIN ((uint_fast8_t)(F_INTERRUPTS * SPEAKER_1_PULSE_TIME * MIN_TOLERANCE_20 + 0.5) - 1) +#define SPEAKER_1_PULSE_LEN_MAX ((uint_fast8_t)(F_INTERRUPTS * SPEAKER_1_PULSE_TIME * MAX_TOLERANCE_20 + 0.5) + 1) +#define SPEAKER_1_PAUSE_LEN_MIN ((uint_fast8_t)(F_INTERRUPTS * SPEAKER_1_PAUSE_TIME * MIN_TOLERANCE_20 + 0.5) - 1) +#define SPEAKER_1_PAUSE_LEN_MAX ((uint_fast8_t)(F_INTERRUPTS * SPEAKER_1_PAUSE_TIME * MAX_TOLERANCE_20 + 0.5) + 1) +#define SPEAKER_0_PULSE_LEN_MIN ((uint_fast8_t)(F_INTERRUPTS * SPEAKER_0_PULSE_TIME * MIN_TOLERANCE_20 + 0.5) - 1) +#define SPEAKER_0_PULSE_LEN_MAX ((uint_fast8_t)(F_INTERRUPTS * SPEAKER_0_PULSE_TIME * MAX_TOLERANCE_20 + 0.5) + 1) +#define SPEAKER_0_PAUSE_LEN_MIN ((uint_fast8_t)(F_INTERRUPTS * SPEAKER_0_PAUSE_TIME * MIN_TOLERANCE_20 + 0.5) - 1) +#define SPEAKER_0_PAUSE_LEN_MAX ((uint_fast8_t)(F_INTERRUPTS * SPEAKER_0_PAUSE_TIME * MAX_TOLERANCE_20 + 0.5) + 1) + +#define BANG_OLUFSEN_START_BIT1_PULSE_LEN_MIN ((uint_fast8_t)(F_INTERRUPTS * BANG_OLUFSEN_START_BIT1_PULSE_TIME * MIN_TOLERANCE_10 + 0.5) - 1) +#define BANG_OLUFSEN_START_BIT1_PULSE_LEN_MAX ((uint_fast8_t)(F_INTERRUPTS * BANG_OLUFSEN_START_BIT1_PULSE_TIME * MAX_TOLERANCE_10 + 0.5) + 1) +#define BANG_OLUFSEN_START_BIT1_PAUSE_LEN_MIN ((uint_fast8_t)(F_INTERRUPTS * BANG_OLUFSEN_START_BIT1_PAUSE_TIME * MIN_TOLERANCE_10 + 0.5) - 1) +#define BANG_OLUFSEN_START_BIT1_PAUSE_LEN_MAX ((uint_fast8_t)(F_INTERRUPTS * BANG_OLUFSEN_START_BIT1_PAUSE_TIME * MAX_TOLERANCE_10 + 0.5) + 1) +#define BANG_OLUFSEN_START_BIT2_PULSE_LEN_MIN ((uint_fast8_t)(F_INTERRUPTS * BANG_OLUFSEN_START_BIT2_PULSE_TIME * MIN_TOLERANCE_10 + 0.5) - 1) +#define BANG_OLUFSEN_START_BIT2_PULSE_LEN_MAX ((uint_fast8_t)(F_INTERRUPTS * BANG_OLUFSEN_START_BIT2_PULSE_TIME * MAX_TOLERANCE_10 + 0.5) + 1) +#define BANG_OLUFSEN_START_BIT2_PAUSE_LEN_MIN ((uint_fast8_t)(F_INTERRUPTS * BANG_OLUFSEN_START_BIT2_PAUSE_TIME * MIN_TOLERANCE_10 + 0.5) - 1) +#define BANG_OLUFSEN_START_BIT2_PAUSE_LEN_MAX ((uint_fast8_t)(F_INTERRUPTS * BANG_OLUFSEN_START_BIT2_PAUSE_TIME * MAX_TOLERANCE_10 + 0.5) + 1) +#define BANG_OLUFSEN_START_BIT3_PULSE_LEN_MIN ((uint_fast8_t)(F_INTERRUPTS * BANG_OLUFSEN_START_BIT3_PULSE_TIME * MIN_TOLERANCE_10 + 0.5) - 1) +#define BANG_OLUFSEN_START_BIT3_PULSE_LEN_MAX ((uint_fast8_t)(F_INTERRUPTS * BANG_OLUFSEN_START_BIT3_PULSE_TIME * MAX_TOLERANCE_10 + 0.5) + 1) +#define BANG_OLUFSEN_START_BIT3_PAUSE_LEN_MIN ((uint_fast8_t)(F_INTERRUPTS * BANG_OLUFSEN_START_BIT3_PAUSE_TIME * MIN_TOLERANCE_10 + 0.5) - 1) +#define BANG_OLUFSEN_START_BIT3_PAUSE_LEN_MAX ((PAUSE_LEN)(F_INTERRUPTS * BANG_OLUFSEN_START_BIT3_PAUSE_TIME * MAX_TOLERANCE_05 + 0.5) + 1) // value must be below IRMP_TIMEOUT +#define BANG_OLUFSEN_START_BIT4_PULSE_LEN_MIN ((uint_fast8_t)(F_INTERRUPTS * BANG_OLUFSEN_START_BIT4_PULSE_TIME * MIN_TOLERANCE_10 + 0.5) - 1) +#define BANG_OLUFSEN_START_BIT4_PULSE_LEN_MAX ((uint_fast8_t)(F_INTERRUPTS * BANG_OLUFSEN_START_BIT4_PULSE_TIME * MAX_TOLERANCE_10 + 0.5) + 1) +#define BANG_OLUFSEN_START_BIT4_PAUSE_LEN_MIN ((uint_fast8_t)(F_INTERRUPTS * BANG_OLUFSEN_START_BIT4_PAUSE_TIME * MIN_TOLERANCE_10 + 0.5) - 1) +#define BANG_OLUFSEN_START_BIT4_PAUSE_LEN_MAX ((uint_fast8_t)(F_INTERRUPTS * BANG_OLUFSEN_START_BIT4_PAUSE_TIME * MAX_TOLERANCE_10 + 0.5) + 1) +#define BANG_OLUFSEN_PULSE_LEN_MIN ((uint_fast8_t)(F_INTERRUPTS * BANG_OLUFSEN_PULSE_TIME * MIN_TOLERANCE_10 + 0.5) - 1) +#define BANG_OLUFSEN_PULSE_LEN_MAX ((uint_fast8_t)(F_INTERRUPTS * BANG_OLUFSEN_PULSE_TIME * MAX_TOLERANCE_10 + 0.5) + 1) +#define BANG_OLUFSEN_1_PAUSE_LEN_MIN ((uint_fast8_t)(F_INTERRUPTS * BANG_OLUFSEN_1_PAUSE_TIME * MIN_TOLERANCE_10 + 0.5) - 1) +#define BANG_OLUFSEN_1_PAUSE_LEN_MAX ((uint_fast8_t)(F_INTERRUPTS * BANG_OLUFSEN_1_PAUSE_TIME * MAX_TOLERANCE_10 + 0.5) + 1) +#define BANG_OLUFSEN_0_PAUSE_LEN_MIN ((uint_fast8_t)(F_INTERRUPTS * BANG_OLUFSEN_0_PAUSE_TIME * MIN_TOLERANCE_10 + 0.5) - 1) +#define BANG_OLUFSEN_0_PAUSE_LEN_MAX ((uint_fast8_t)(F_INTERRUPTS * BANG_OLUFSEN_0_PAUSE_TIME * MAX_TOLERANCE_10 + 0.5) + 1) +#define BANG_OLUFSEN_R_PAUSE_LEN_MIN ((uint_fast8_t)(F_INTERRUPTS * BANG_OLUFSEN_R_PAUSE_TIME * MIN_TOLERANCE_10 + 0.5) - 1) +#define BANG_OLUFSEN_R_PAUSE_LEN_MAX ((uint_fast8_t)(F_INTERRUPTS * BANG_OLUFSEN_R_PAUSE_TIME * MAX_TOLERANCE_10 + 0.5) + 1) +#define BANG_OLUFSEN_TRAILER_BIT_PAUSE_LEN_MIN ((uint_fast8_t)(F_INTERRUPTS * BANG_OLUFSEN_TRAILER_BIT_PAUSE_TIME * MIN_TOLERANCE_10 + 0.5) - 1) +#define BANG_OLUFSEN_TRAILER_BIT_PAUSE_LEN_MAX ((uint_fast8_t)(F_INTERRUPTS * BANG_OLUFSEN_TRAILER_BIT_PAUSE_TIME * MAX_TOLERANCE_10 + 0.5) + 1) + +#define IR60_TIMEOUT_LEN ((uint_fast8_t)(F_INTERRUPTS * IR60_TIMEOUT_TIME * 0.5)) +#define GRUNDIG_NOKIA_IR60_START_BIT_LEN_MIN ((uint_fast8_t)(F_INTERRUPTS * GRUNDIG_NOKIA_IR60_BIT_TIME * MIN_TOLERANCE_10 + 0.5) - 1) +#define GRUNDIG_NOKIA_IR60_START_BIT_LEN_MAX ((uint_fast8_t)(F_INTERRUPTS * GRUNDIG_NOKIA_IR60_BIT_TIME * MAX_TOLERANCE_10 + 0.5) + 1) +#define GRUNDIG_NOKIA_IR60_BIT_LEN_MIN ((uint_fast8_t)(F_INTERRUPTS * GRUNDIG_NOKIA_IR60_BIT_TIME * MIN_TOLERANCE_10 + 0.5) - 1) +#define GRUNDIG_NOKIA_IR60_BIT_LEN_MAX ((uint_fast8_t)(F_INTERRUPTS * GRUNDIG_NOKIA_IR60_BIT_TIME * MAX_TOLERANCE_10 + 0.5) + 1) +#define GRUNDIG_NOKIA_IR60_PRE_PAUSE_LEN_MIN ((uint_fast8_t)(F_INTERRUPTS * GRUNDIG_NOKIA_IR60_PRE_PAUSE_TIME * MIN_TOLERANCE_20 + 0.5) + 1) +#define GRUNDIG_NOKIA_IR60_PRE_PAUSE_LEN_MAX ((uint_fast8_t)(F_INTERRUPTS * GRUNDIG_NOKIA_IR60_PRE_PAUSE_TIME * MAX_TOLERANCE_20 + 0.5) + 1) + +#define SIEMENS_OR_RUWIDO_START_BIT_PULSE_LEN_MIN ((uint_fast8_t)(F_INTERRUPTS * SIEMENS_OR_RUWIDO_START_BIT_PULSE_TIME * MIN_TOLERANCE_10 + 0.5) - 1) +#define SIEMENS_OR_RUWIDO_START_BIT_PULSE_LEN_MAX ((uint_fast8_t)(F_INTERRUPTS * SIEMENS_OR_RUWIDO_START_BIT_PULSE_TIME * MAX_TOLERANCE_10 + 0.5) + 1) +#define SIEMENS_OR_RUWIDO_START_BIT_PAUSE_LEN_MIN ((uint_fast8_t)(F_INTERRUPTS * SIEMENS_OR_RUWIDO_START_BIT_PAUSE_TIME * MIN_TOLERANCE_10 + 0.5) - 1) +#define SIEMENS_OR_RUWIDO_START_BIT_PAUSE_LEN_MAX ((uint_fast8_t)(F_INTERRUPTS * SIEMENS_OR_RUWIDO_START_BIT_PAUSE_TIME * MAX_TOLERANCE_10 + 0.5) + 1) +#define SIEMENS_OR_RUWIDO_BIT_PULSE_LEN_MIN ((uint_fast8_t)(F_INTERRUPTS * SIEMENS_OR_RUWIDO_BIT_PULSE_TIME * MIN_TOLERANCE_10 + 0.5) - 1) +#define SIEMENS_OR_RUWIDO_BIT_PULSE_LEN_MAX ((uint_fast8_t)(F_INTERRUPTS * SIEMENS_OR_RUWIDO_BIT_PULSE_TIME * MAX_TOLERANCE_10 + 0.5) + 1) +#define SIEMENS_OR_RUWIDO_BIT_PAUSE_LEN_MIN ((uint_fast8_t)(F_INTERRUPTS * SIEMENS_OR_RUWIDO_BIT_PAUSE_TIME * MIN_TOLERANCE_10 + 0.5) - 1) +#define SIEMENS_OR_RUWIDO_BIT_PAUSE_LEN_MAX ((uint_fast8_t)(F_INTERRUPTS * SIEMENS_OR_RUWIDO_BIT_PAUSE_TIME * MAX_TOLERANCE_10 + 0.5) + 1) + +#define FDC_START_BIT_PULSE_LEN_MIN ((uint_fast8_t)(F_INTERRUPTS * FDC_START_BIT_PULSE_TIME * MIN_TOLERANCE_05 + 0.5) - 1) // 5%: avoid conflict with NETBOX +#define FDC_START_BIT_PULSE_LEN_MAX ((uint_fast8_t)(F_INTERRUPTS * FDC_START_BIT_PULSE_TIME * MAX_TOLERANCE_05 + 0.5)) +#define FDC_START_BIT_PAUSE_LEN_MIN ((uint_fast8_t)(F_INTERRUPTS * FDC_START_BIT_PAUSE_TIME * MIN_TOLERANCE_05 + 0.5) - 1) +#define FDC_START_BIT_PAUSE_LEN_MAX ((uint_fast8_t)(F_INTERRUPTS * FDC_START_BIT_PAUSE_TIME * MAX_TOLERANCE_05 + 0.5)) +#define FDC_PULSE_LEN_MIN ((uint_fast8_t)(F_INTERRUPTS * FDC_PULSE_TIME * MIN_TOLERANCE_40 + 0.5) - 1) +#define FDC_PULSE_LEN_MAX ((uint_fast8_t)(F_INTERRUPTS * FDC_PULSE_TIME * MAX_TOLERANCE_50 + 0.5) + 1) +#define FDC_1_PAUSE_LEN_MIN ((uint_fast8_t)(F_INTERRUPTS * FDC_1_PAUSE_TIME * MIN_TOLERANCE_20 + 0.5) - 1) +#define FDC_1_PAUSE_LEN_MAX ((uint_fast8_t)(F_INTERRUPTS * FDC_1_PAUSE_TIME * MAX_TOLERANCE_20 + 0.5) + 1) +#if 0 +#define FDC_0_PAUSE_LEN_MIN ((uint_fast8_t)(F_INTERRUPTS * FDC_0_PAUSE_TIME * MIN_TOLERANCE_40 + 0.5) - 1) // could be negative: 255 +#else +#define FDC_0_PAUSE_LEN_MIN (1) // simply use 1 +#endif +#define FDC_0_PAUSE_LEN_MAX ((uint_fast8_t)(F_INTERRUPTS * FDC_0_PAUSE_TIME * MAX_TOLERANCE_10 + 0.5) + 1) + +#define RCCAR_START_BIT_PULSE_LEN_MIN ((uint_fast8_t)(F_INTERRUPTS * RCCAR_START_BIT_PULSE_TIME * MIN_TOLERANCE_10 + 0.5) - 1) +#define RCCAR_START_BIT_PULSE_LEN_MAX ((uint_fast8_t)(F_INTERRUPTS * RCCAR_START_BIT_PULSE_TIME * MAX_TOLERANCE_10 + 0.5) + 1) +#define RCCAR_START_BIT_PAUSE_LEN_MIN ((uint_fast8_t)(F_INTERRUPTS * RCCAR_START_BIT_PAUSE_TIME * MIN_TOLERANCE_10 + 0.5) - 1) +#define RCCAR_START_BIT_PAUSE_LEN_MAX ((uint_fast8_t)(F_INTERRUPTS * RCCAR_START_BIT_PAUSE_TIME * MAX_TOLERANCE_10 + 0.5) + 1) +#define RCCAR_PULSE_LEN_MIN ((uint_fast8_t)(F_INTERRUPTS * RCCAR_PULSE_TIME * MIN_TOLERANCE_20 + 0.5) - 1) +#define RCCAR_PULSE_LEN_MAX ((uint_fast8_t)(F_INTERRUPTS * RCCAR_PULSE_TIME * MAX_TOLERANCE_20 + 0.5) + 1) +#define RCCAR_1_PAUSE_LEN_MIN ((uint_fast8_t)(F_INTERRUPTS * RCCAR_1_PAUSE_TIME * MIN_TOLERANCE_30 + 0.5) - 1) +#define RCCAR_1_PAUSE_LEN_MAX ((uint_fast8_t)(F_INTERRUPTS * RCCAR_1_PAUSE_TIME * MAX_TOLERANCE_30 + 0.5) + 1) +#define RCCAR_0_PAUSE_LEN_MIN ((uint_fast8_t)(F_INTERRUPTS * RCCAR_0_PAUSE_TIME * MIN_TOLERANCE_30 + 0.5) - 1) +#define RCCAR_0_PAUSE_LEN_MAX ((uint_fast8_t)(F_INTERRUPTS * RCCAR_0_PAUSE_TIME * MAX_TOLERANCE_30 + 0.5) + 1) + +#define JVC_START_BIT_PULSE_LEN_MIN ((uint_fast8_t)(F_INTERRUPTS * JVC_START_BIT_PULSE_TIME * MIN_TOLERANCE_40 + 0.5) - 1) +#define JVC_START_BIT_PULSE_LEN_MAX ((uint_fast8_t)(F_INTERRUPTS * JVC_START_BIT_PULSE_TIME * MAX_TOLERANCE_40 + 0.5) + 1) +#define JVC_REPEAT_START_BIT_PAUSE_LEN_MIN ((uint_fast8_t)(F_INTERRUPTS * (JVC_FRAME_REPEAT_PAUSE_TIME - IRMP_TIMEOUT_TIME) * MIN_TOLERANCE_40 + 0.5) - 1) // HACK! +#define JVC_REPEAT_START_BIT_PAUSE_LEN_MAX ((uint_fast8_t)(F_INTERRUPTS * (JVC_FRAME_REPEAT_PAUSE_TIME - IRMP_TIMEOUT_TIME) * MAX_TOLERANCE_70 + 0.5) - 1) // HACK! +#define JVC_PULSE_LEN_MIN ((uint_fast8_t)(F_INTERRUPTS * JVC_PULSE_TIME * MIN_TOLERANCE_40 + 0.5) - 1) +#define JVC_PULSE_LEN_MAX ((uint_fast8_t)(F_INTERRUPTS * JVC_PULSE_TIME * MAX_TOLERANCE_40 + 0.5) + 1) +#define JVC_1_PAUSE_LEN_MIN ((uint_fast8_t)(F_INTERRUPTS * JVC_1_PAUSE_TIME * MIN_TOLERANCE_40 + 0.5) - 1) +#define JVC_1_PAUSE_LEN_MAX ((uint_fast8_t)(F_INTERRUPTS * JVC_1_PAUSE_TIME * MAX_TOLERANCE_40 + 0.5) + 1) +#define JVC_0_PAUSE_LEN_MIN ((uint_fast8_t)(F_INTERRUPTS * JVC_0_PAUSE_TIME * MIN_TOLERANCE_40 + 0.5) - 1) +#define JVC_0_PAUSE_LEN_MAX ((uint_fast8_t)(F_INTERRUPTS * JVC_0_PAUSE_TIME * MAX_TOLERANCE_40 + 0.5) + 1) +// autodetect JVC repetition frame within 50 msec: +#define JVC_FRAME_REPEAT_PAUSE_LEN_MAX (uint_fast16_t)(F_INTERRUPTS * JVC_FRAME_REPEAT_PAUSE_TIME * MAX_TOLERANCE_20 + 0.5) + +#define NIKON_START_BIT_PULSE_LEN_MIN ((uint_fast8_t)(F_INTERRUPTS * NIKON_START_BIT_PULSE_TIME * MIN_TOLERANCE_20 + 0.5) - 1) +#define NIKON_START_BIT_PULSE_LEN_MAX ((uint_fast8_t)(F_INTERRUPTS * NIKON_START_BIT_PULSE_TIME * MAX_TOLERANCE_20 + 0.5) + 1) +#define NIKON_START_BIT_PAUSE_LEN_MIN ((uint_fast16_t)(F_INTERRUPTS * NIKON_START_BIT_PAUSE_TIME * MIN_TOLERANCE_20 + 0.5) - 1) +#define NIKON_START_BIT_PAUSE_LEN_MAX ((uint_fast16_t)(F_INTERRUPTS * NIKON_START_BIT_PAUSE_TIME * MAX_TOLERANCE_20 + 0.5) + 1) +#define NIKON_REPEAT_START_BIT_PAUSE_LEN_MIN ((uint_fast8_t)(F_INTERRUPTS * NIKON_REPEAT_START_BIT_PAUSE_TIME * MIN_TOLERANCE_20 + 0.5) - 1) +#define NIKON_REPEAT_START_BIT_PAUSE_LEN_MAX ((uint_fast8_t)(F_INTERRUPTS * NIKON_REPEAT_START_BIT_PAUSE_TIME * MAX_TOLERANCE_20 + 0.5) + 1) +#define NIKON_PULSE_LEN_MIN ((uint_fast8_t)(F_INTERRUPTS * NIKON_PULSE_TIME * MIN_TOLERANCE_20 + 0.5) - 1) +#define NIKON_PULSE_LEN_MAX ((uint_fast8_t)(F_INTERRUPTS * NIKON_PULSE_TIME * MAX_TOLERANCE_20 + 0.5) + 1) +#define NIKON_1_PAUSE_LEN_MIN ((uint_fast8_t)(F_INTERRUPTS * NIKON_1_PAUSE_TIME * MIN_TOLERANCE_20 + 0.5) - 1) +#define NIKON_1_PAUSE_LEN_MAX ((uint_fast8_t)(F_INTERRUPTS * NIKON_1_PAUSE_TIME * MAX_TOLERANCE_20 + 0.5) + 1) +#define NIKON_0_PAUSE_LEN_MIN ((uint_fast8_t)(F_INTERRUPTS * NIKON_0_PAUSE_TIME * MIN_TOLERANCE_20 + 0.5) - 1) +#define NIKON_0_PAUSE_LEN_MAX ((uint_fast8_t)(F_INTERRUPTS * NIKON_0_PAUSE_TIME * MAX_TOLERANCE_20 + 0.5) + 1) +#define NIKON_FRAME_REPEAT_PAUSE_LEN_MAX (uint_fast16_t)(F_INTERRUPTS * NIKON_FRAME_REPEAT_PAUSE_TIME * MAX_TOLERANCE_20 + 0.5) + +#define KATHREIN_START_BIT_PULSE_LEN_MIN ((uint_fast8_t)(F_INTERRUPTS * KATHREIN_START_BIT_PULSE_TIME * MIN_TOLERANCE_10 + 0.5) - 1) +#define KATHREIN_START_BIT_PULSE_LEN_MAX ((uint_fast8_t)(F_INTERRUPTS * KATHREIN_START_BIT_PULSE_TIME * MAX_TOLERANCE_10 + 0.5) + 1) +#define KATHREIN_START_BIT_PAUSE_LEN_MIN ((uint_fast8_t)(F_INTERRUPTS * KATHREIN_START_BIT_PAUSE_TIME * MIN_TOLERANCE_10 + 0.5) - 1) +#define KATHREIN_START_BIT_PAUSE_LEN_MAX ((uint_fast8_t)(F_INTERRUPTS * KATHREIN_START_BIT_PAUSE_TIME * MAX_TOLERANCE_10 + 0.5) + 1) +#define KATHREIN_1_PULSE_LEN_MIN ((uint_fast8_t)(F_INTERRUPTS * KATHREIN_1_PULSE_TIME * MIN_TOLERANCE_10 + 0.5) - 1) +#define KATHREIN_1_PULSE_LEN_MAX ((uint_fast8_t)(F_INTERRUPTS * KATHREIN_1_PULSE_TIME * MAX_TOLERANCE_10 + 0.5) + 1) +#define KATHREIN_1_PAUSE_LEN_MIN ((uint_fast8_t)(F_INTERRUPTS * KATHREIN_1_PAUSE_TIME * MIN_TOLERANCE_10 + 0.5) - 1) +#define KATHREIN_1_PAUSE_LEN_MAX ((uint_fast8_t)(F_INTERRUPTS * KATHREIN_1_PAUSE_TIME * MAX_TOLERANCE_10 + 0.5) + 1) +#define KATHREIN_0_PULSE_LEN_MIN ((uint_fast8_t)(F_INTERRUPTS * KATHREIN_0_PULSE_TIME * MIN_TOLERANCE_10 + 0.5) - 1) +#define KATHREIN_0_PULSE_LEN_MAX ((uint_fast8_t)(F_INTERRUPTS * KATHREIN_0_PULSE_TIME * MAX_TOLERANCE_10 + 0.5) + 1) +#define KATHREIN_0_PAUSE_LEN_MIN ((uint_fast8_t)(F_INTERRUPTS * KATHREIN_0_PAUSE_TIME * MIN_TOLERANCE_10 + 0.5) - 1) +#define KATHREIN_0_PAUSE_LEN_MAX ((uint_fast8_t)(F_INTERRUPTS * KATHREIN_0_PAUSE_TIME * MAX_TOLERANCE_10 + 0.5) + 1) +#define KATHREIN_SYNC_BIT_PAUSE_LEN_MIN ((uint_fast8_t)(F_INTERRUPTS * KATHREIN_SYNC_BIT_PAUSE_LEN_TIME * MIN_TOLERANCE_10 + 0.5) - 1) +#define KATHREIN_SYNC_BIT_PAUSE_LEN_MAX ((uint_fast8_t)(F_INTERRUPTS * KATHREIN_SYNC_BIT_PAUSE_LEN_TIME * MAX_TOLERANCE_10 + 0.5) + 1) + +#define NETBOX_START_BIT_PULSE_LEN_MIN ((uint_fast8_t)(F_INTERRUPTS * NETBOX_START_BIT_PULSE_TIME * MIN_TOLERANCE_10 + 0.5) - 1) +#define NETBOX_START_BIT_PULSE_LEN_MAX ((uint_fast8_t)(F_INTERRUPTS * NETBOX_START_BIT_PULSE_TIME * MAX_TOLERANCE_10 + 0.5) + 1) +#define NETBOX_START_BIT_PAUSE_LEN_MIN ((uint_fast8_t)(F_INTERRUPTS * NETBOX_START_BIT_PAUSE_TIME * MIN_TOLERANCE_10 + 0.5) - 1) +#define NETBOX_START_BIT_PAUSE_LEN_MAX ((uint_fast8_t)(F_INTERRUPTS * NETBOX_START_BIT_PAUSE_TIME * MAX_TOLERANCE_10 + 0.5) + 1) +#define NETBOX_PULSE_LEN ((uint_fast8_t)(F_INTERRUPTS * NETBOX_PULSE_TIME)) +#define NETBOX_PAUSE_LEN ((uint_fast8_t)(F_INTERRUPTS * NETBOX_PAUSE_TIME)) +#define NETBOX_PULSE_REST_LEN ((uint_fast8_t)(F_INTERRUPTS * NETBOX_PULSE_TIME / 4)) +#define NETBOX_PAUSE_REST_LEN ((uint_fast8_t)(F_INTERRUPTS * NETBOX_PAUSE_TIME / 4)) + +#define LEGO_START_BIT_PULSE_LEN_MIN ((uint_fast8_t)(F_INTERRUPTS * LEGO_START_BIT_PULSE_TIME * MIN_TOLERANCE_40 + 0.5) - 1) +#define LEGO_START_BIT_PULSE_LEN_MAX ((uint_fast8_t)(F_INTERRUPTS * LEGO_START_BIT_PULSE_TIME * MAX_TOLERANCE_40 + 0.5) + 1) +#define LEGO_START_BIT_PAUSE_LEN_MIN ((uint_fast8_t)(F_INTERRUPTS * LEGO_START_BIT_PAUSE_TIME * MIN_TOLERANCE_40 + 0.5) - 1) +#define LEGO_START_BIT_PAUSE_LEN_MAX ((uint_fast8_t)(F_INTERRUPTS * LEGO_START_BIT_PAUSE_TIME * MAX_TOLERANCE_40 + 0.5) + 1) +#define LEGO_PULSE_LEN_MIN ((uint_fast8_t)(F_INTERRUPTS * LEGO_PULSE_TIME * MIN_TOLERANCE_40 + 0.5) - 1) +#define LEGO_PULSE_LEN_MAX ((uint_fast8_t)(F_INTERRUPTS * LEGO_PULSE_TIME * MAX_TOLERANCE_40 + 0.5) + 1) +#define LEGO_1_PAUSE_LEN_MIN ((uint_fast8_t)(F_INTERRUPTS * LEGO_1_PAUSE_TIME * MIN_TOLERANCE_40 + 0.5) - 1) +#define LEGO_1_PAUSE_LEN_MAX ((uint_fast8_t)(F_INTERRUPTS * LEGO_1_PAUSE_TIME * MAX_TOLERANCE_40 + 0.5) + 1) +#define LEGO_0_PAUSE_LEN_MIN ((uint_fast8_t)(F_INTERRUPTS * LEGO_0_PAUSE_TIME * MIN_TOLERANCE_40 + 0.5) - 1) +#define LEGO_0_PAUSE_LEN_MAX ((uint_fast8_t)(F_INTERRUPTS * LEGO_0_PAUSE_TIME * MAX_TOLERANCE_40 + 0.5) + 1) + +#define IRMP16_START_BIT_PULSE_LEN_MIN ((uint_fast8_t)(F_INTERRUPTS * IRMP16_START_BIT_PULSE_TIME * MIN_TOLERANCE_20 + 0.5) - 1) +#define IRMP16_START_BIT_PULSE_LEN_MAX ((uint_fast8_t)(F_INTERRUPTS * IRMP16_START_BIT_PULSE_TIME * MAX_TOLERANCE_20 + 0.5) + 1) +#define IRMP16_START_BIT_PAUSE_LEN_MIN ((uint_fast8_t)(F_INTERRUPTS * IRMP16_START_BIT_PAUSE_TIME * MIN_TOLERANCE_20 + 0.5) - 1) +#define IRMP16_START_BIT_PAUSE_LEN_MAX ((uint_fast8_t)(F_INTERRUPTS * IRMP16_START_BIT_PAUSE_TIME * MAX_TOLERANCE_20 + 0.5) + 1) +#define IRMP16_PULSE_LEN_MIN ((uint_fast8_t)(F_INTERRUPTS * IRMP16_PULSE_TIME * MIN_TOLERANCE_20 + 0.5) - 1) +#define IRMP16_PULSE_LEN_MAX ((uint_fast8_t)(F_INTERRUPTS * IRMP16_PULSE_TIME * MAX_TOLERANCE_20 + 0.5) + 1) +#define IRMP16_1_PAUSE_LEN_MIN ((uint_fast8_t)(F_INTERRUPTS * IRMP16_1_PAUSE_TIME * MIN_TOLERANCE_20 + 0.5) - 1) +#define IRMP16_1_PAUSE_LEN_MAX ((uint_fast8_t)(F_INTERRUPTS * IRMP16_1_PAUSE_TIME * MAX_TOLERANCE_20 + 0.5) + 1) +#define IRMP16_0_PAUSE_LEN_MIN ((uint_fast8_t)(F_INTERRUPTS * IRMP16_0_PAUSE_TIME * MIN_TOLERANCE_20 + 0.5) - 1) +#define IRMP16_0_PAUSE_LEN_MAX ((uint_fast8_t)(F_INTERRUPTS * IRMP16_0_PAUSE_TIME * MAX_TOLERANCE_20 + 0.5) + 1) + +#define GREE_START_BIT_PULSE_LEN_MIN ((uint_fast8_t)(F_INTERRUPTS * GREE_START_BIT_PULSE_TIME * MIN_TOLERANCE_20 + 0.5) - 1) +#define GREE_START_BIT_PULSE_LEN_MAX ((uint_fast8_t)(F_INTERRUPTS * GREE_START_BIT_PULSE_TIME * MAX_TOLERANCE_20 + 0.5) + 1) +#define GREE_START_BIT_PAUSE_LEN_MIN ((uint_fast8_t)(F_INTERRUPTS * GREE_START_BIT_PAUSE_TIME * MIN_TOLERANCE_20 + 0.5) - 1) +#define GREE_START_BIT_PAUSE_LEN_MAX ((uint_fast8_t)(F_INTERRUPTS * GREE_START_BIT_PAUSE_TIME * MAX_TOLERANCE_20 + 0.5) + 1) +#define GREE_PULSE_LEN_MIN ((uint_fast8_t)(F_INTERRUPTS * GREE_PULSE_TIME * MIN_TOLERANCE_20 + 0.5) - 1) +#define GREE_PULSE_LEN_MAX ((uint_fast8_t)(F_INTERRUPTS * GREE_PULSE_TIME * MAX_TOLERANCE_20 + 0.5) + 1) +#define GREE_1_PAUSE_LEN_MIN ((uint_fast8_t)(F_INTERRUPTS * GREE_1_PAUSE_TIME * MIN_TOLERANCE_20 + 0.5) - 1) +#define GREE_1_PAUSE_LEN_MAX ((uint_fast8_t)(F_INTERRUPTS * GREE_1_PAUSE_TIME * MAX_TOLERANCE_20 + 0.5) + 1) +#define GREE_0_PAUSE_LEN_MIN ((uint_fast8_t)(F_INTERRUPTS * GREE_0_PAUSE_TIME * MIN_TOLERANCE_20 + 0.5) - 1) +#define GREE_0_PAUSE_LEN_MAX ((uint_fast8_t)(F_INTERRUPTS * GREE_0_PAUSE_TIME * MAX_TOLERANCE_20 + 0.5) + 1) + +#define BOSE_START_BIT_PULSE_LEN_MIN ((uint_fast8_t)(F_INTERRUPTS * BOSE_START_BIT_PULSE_TIME * MIN_TOLERANCE_30 + 0.5) - 1) +#define BOSE_START_BIT_PULSE_LEN_MAX ((uint_fast8_t)(F_INTERRUPTS * BOSE_START_BIT_PULSE_TIME * MAX_TOLERANCE_30 + 0.5) + 1) +#define BOSE_START_BIT_PAUSE_LEN_MIN ((uint_fast8_t)(F_INTERRUPTS * BOSE_START_BIT_PAUSE_TIME * MIN_TOLERANCE_30 + 0.5) - 1) +#define BOSE_START_BIT_PAUSE_LEN_MAX ((uint_fast8_t)(F_INTERRUPTS * BOSE_START_BIT_PAUSE_TIME * MAX_TOLERANCE_30 + 0.5) + 1) +#define BOSE_PULSE_LEN_MIN ((uint_fast8_t)(F_INTERRUPTS * BOSE_PULSE_TIME * MIN_TOLERANCE_30 + 0.5) - 1) +#define BOSE_PULSE_LEN_MAX ((uint_fast8_t)(F_INTERRUPTS * BOSE_PULSE_TIME * MAX_TOLERANCE_30 + 0.5) + 1) +#define BOSE_1_PAUSE_LEN_MIN ((uint_fast8_t)(F_INTERRUPTS * BOSE_1_PAUSE_TIME * MIN_TOLERANCE_30 + 0.5) - 1) +#define BOSE_1_PAUSE_LEN_MAX ((uint_fast8_t)(F_INTERRUPTS * BOSE_1_PAUSE_TIME * MAX_TOLERANCE_30 + 0.5) + 1) +#define BOSE_0_PAUSE_LEN_MIN ((uint_fast8_t)(F_INTERRUPTS * BOSE_0_PAUSE_TIME * MIN_TOLERANCE_30 + 0.5) - 1) +#define BOSE_0_PAUSE_LEN_MAX ((uint_fast8_t)(F_INTERRUPTS * BOSE_0_PAUSE_TIME * MAX_TOLERANCE_30 + 0.5) + 1) +#define BOSE_FRAME_REPEAT_PAUSE_LEN_MAX (uint_fast16_t)(F_INTERRUPTS * 100.0e-3 * MAX_TOLERANCE_20 + 0.5) + +#define A1TVBOX_START_BIT_PULSE_LEN_MIN ((uint_fast8_t)(F_INTERRUPTS * A1TVBOX_START_BIT_PULSE_TIME * MIN_TOLERANCE_10 + 0.5) - 1) +#define A1TVBOX_START_BIT_PULSE_LEN_MAX ((uint_fast8_t)(F_INTERRUPTS * A1TVBOX_START_BIT_PULSE_TIME * MAX_TOLERANCE_10 + 0.5) + 1) +#define A1TVBOX_START_BIT_PAUSE_LEN_MIN ((uint_fast8_t)(F_INTERRUPTS * A1TVBOX_START_BIT_PAUSE_TIME * MIN_TOLERANCE_10 + 0.5) - 1) +#define A1TVBOX_START_BIT_PAUSE_LEN_MAX ((uint_fast8_t)(F_INTERRUPTS * A1TVBOX_START_BIT_PAUSE_TIME * MAX_TOLERANCE_10 + 0.5) + 1) +#define A1TVBOX_BIT_PULSE_LEN_MIN ((uint_fast8_t)(F_INTERRUPTS * A1TVBOX_BIT_PULSE_TIME * MIN_TOLERANCE_30 + 0.5) - 1) +#define A1TVBOX_BIT_PULSE_LEN_MAX ((uint_fast8_t)(F_INTERRUPTS * A1TVBOX_BIT_PULSE_TIME * MAX_TOLERANCE_30 + 0.5) + 1) +#define A1TVBOX_BIT_PAUSE_LEN_MIN ((uint_fast8_t)(F_INTERRUPTS * A1TVBOX_BIT_PAUSE_TIME * MIN_TOLERANCE_30 + 0.5) - 1) +#define A1TVBOX_BIT_PAUSE_LEN_MAX ((uint_fast8_t)(F_INTERRUPTS * A1TVBOX_BIT_PAUSE_TIME * MAX_TOLERANCE_30 + 0.5) + 1) + +#define MERLIN_START_BIT_PULSE_LEN_MIN ((uint_fast8_t)(F_INTERRUPTS * MERLIN_START_BIT_PULSE_TIME * MIN_TOLERANCE_10 + 0.5) - 1) +#define MERLIN_START_BIT_PULSE_LEN_MAX ((uint_fast8_t)(F_INTERRUPTS * MERLIN_START_BIT_PULSE_TIME * MAX_TOLERANCE_10 + 0.5) + 1) +#define MERLIN_START_BIT_PAUSE_LEN_MIN ((uint_fast8_t)(F_INTERRUPTS * MERLIN_START_BIT_PAUSE_TIME * MIN_TOLERANCE_10 + 0.5) - 1) +#define MERLIN_START_BIT_PAUSE_LEN_MAX ((uint_fast8_t)(F_INTERRUPTS * MERLIN_START_BIT_PAUSE_TIME * MAX_TOLERANCE_10 + 0.5) + 1) +#define MERLIN_BIT_PULSE_LEN_MIN ((uint_fast8_t)(F_INTERRUPTS * MERLIN_BIT_PULSE_TIME * MIN_TOLERANCE_30 + 0.5) - 1) +#define MERLIN_BIT_PULSE_LEN_MAX ((uint_fast8_t)(F_INTERRUPTS * MERLIN_BIT_PULSE_TIME * MAX_TOLERANCE_30 + 0.5) + 1) +#define MERLIN_BIT_PAUSE_LEN_MIN ((uint_fast8_t)(F_INTERRUPTS * MERLIN_BIT_PAUSE_TIME * MIN_TOLERANCE_30 + 0.5) - 1) +#define MERLIN_BIT_PAUSE_LEN_MAX ((uint_fast8_t)(F_INTERRUPTS * MERLIN_BIT_PAUSE_TIME * MAX_TOLERANCE_30 + 0.5) + 1) + +#define ORTEK_START_BIT_PULSE_LEN_MIN ((uint_fast8_t)(F_INTERRUPTS * ORTEK_START_BIT_PULSE_TIME * MIN_TOLERANCE_10 + 0.5) - 1) +#define ORTEK_START_BIT_PULSE_LEN_MAX ((uint_fast8_t)(F_INTERRUPTS * ORTEK_START_BIT_PULSE_TIME * MAX_TOLERANCE_10 + 0.5) + 1) +#define ORTEK_START_BIT_PAUSE_LEN_MIN ((uint_fast8_t)(F_INTERRUPTS * ORTEK_START_BIT_PAUSE_TIME * MIN_TOLERANCE_10 + 0.5) - 1) +#define ORTEK_START_BIT_PAUSE_LEN_MAX ((uint_fast8_t)(F_INTERRUPTS * ORTEK_START_BIT_PAUSE_TIME * MAX_TOLERANCE_10 + 0.5) + 1) +#define ORTEK_BIT_PULSE_LEN_MIN ((uint_fast8_t)(F_INTERRUPTS * ORTEK_BIT_TIME * MIN_TOLERANCE_10 + 0.5) - 1) +#define ORTEK_BIT_PULSE_LEN_MAX ((uint_fast8_t)(F_INTERRUPTS * ORTEK_BIT_TIME * MAX_TOLERANCE_10 + 0.5) + 1) +#define ORTEK_BIT_PAUSE_LEN_MIN ((uint_fast8_t)(F_INTERRUPTS * ORTEK_BIT_TIME * MIN_TOLERANCE_10 + 0.5) - 1) +#define ORTEK_BIT_PAUSE_LEN_MAX ((uint_fast8_t)(F_INTERRUPTS * ORTEK_BIT_TIME * MAX_TOLERANCE_10 + 0.5) + 1) + +#define TELEFUNKEN_START_BIT_PULSE_LEN_MIN ((uint_fast8_t)(F_INTERRUPTS * TELEFUNKEN_START_BIT_PULSE_TIME * MIN_TOLERANCE_10 + 0.5) - 1) +#define TELEFUNKEN_START_BIT_PULSE_LEN_MAX ((uint_fast8_t)(F_INTERRUPTS * TELEFUNKEN_START_BIT_PULSE_TIME * MAX_TOLERANCE_10 + 0.5) + 1) +#define TELEFUNKEN_START_BIT_PAUSE_LEN_MIN ((uint_fast8_t)(F_INTERRUPTS * (TELEFUNKEN_START_BIT_PAUSE_TIME) * MIN_TOLERANCE_10 + 0.5) - 1) +#define TELEFUNKEN_START_BIT_PAUSE_LEN_MAX ((uint_fast8_t)(F_INTERRUPTS * (TELEFUNKEN_START_BIT_PAUSE_TIME) * MAX_TOLERANCE_10 + 0.5) - 1) +#define TELEFUNKEN_PULSE_LEN_MIN ((uint_fast8_t)(F_INTERRUPTS * TELEFUNKEN_PULSE_TIME * MIN_TOLERANCE_30 + 0.5) - 1) +#define TELEFUNKEN_PULSE_LEN_MAX ((uint_fast8_t)(F_INTERRUPTS * TELEFUNKEN_PULSE_TIME * MAX_TOLERANCE_30 + 0.5) + 1) +#define TELEFUNKEN_1_PAUSE_LEN_MIN ((uint_fast8_t)(F_INTERRUPTS * TELEFUNKEN_1_PAUSE_TIME * MIN_TOLERANCE_30 + 0.5) - 1) +#define TELEFUNKEN_1_PAUSE_LEN_MAX ((uint_fast8_t)(F_INTERRUPTS * TELEFUNKEN_1_PAUSE_TIME * MAX_TOLERANCE_30 + 0.5) + 1) +#define TELEFUNKEN_0_PAUSE_LEN_MIN ((uint_fast8_t)(F_INTERRUPTS * TELEFUNKEN_0_PAUSE_TIME * MIN_TOLERANCE_30 + 0.5) - 1) +#define TELEFUNKEN_0_PAUSE_LEN_MAX ((uint_fast8_t)(F_INTERRUPTS * TELEFUNKEN_0_PAUSE_TIME * MAX_TOLERANCE_30 + 0.5) + 1) +// autodetect TELEFUNKEN repetition frame within 50 msec: +// #define TELEFUNKEN_FRAME_REPEAT_PAUSE_LEN_MAX (uint_fast16_t)(F_INTERRUPTS * TELEFUNKEN_FRAME_REPEAT_PAUSE_TIME * MAX_TOLERANCE_20 + 0.5) + +#define ROOMBA_START_BIT_PULSE_LEN_MIN ((uint_fast8_t)(F_INTERRUPTS * ROOMBA_START_BIT_PULSE_TIME * MIN_TOLERANCE_10 + 0.5) - 1) +#define ROOMBA_START_BIT_PULSE_LEN_MAX ((uint_fast8_t)(F_INTERRUPTS * ROOMBA_START_BIT_PULSE_TIME * MAX_TOLERANCE_10 + 0.5) + 1) +#define ROOMBA_START_BIT_PAUSE_LEN_MIN ((uint_fast8_t)(F_INTERRUPTS * ROOMBA_START_BIT_PAUSE_TIME * MIN_TOLERANCE_10 + 0.5) - 1) +#define ROOMBA_START_BIT_PAUSE_LEN_MAX ((uint_fast8_t)(F_INTERRUPTS * ROOMBA_START_BIT_PAUSE_TIME * MAX_TOLERANCE_10 + 0.5) + 1) +#define ROOMBA_1_PAUSE_LEN_EXACT ((uint_fast8_t)(F_INTERRUPTS * ROOMBA_1_PAUSE_TIME + 0.5)) +#define ROOMBA_1_PULSE_LEN_MIN ((uint_fast8_t)(F_INTERRUPTS * ROOMBA_1_PULSE_TIME * MIN_TOLERANCE_20 + 0.5) - 1) +#define ROOMBA_1_PULSE_LEN_MAX ((uint_fast8_t)(F_INTERRUPTS * ROOMBA_1_PULSE_TIME * MAX_TOLERANCE_20 + 0.5) + 1) +#define ROOMBA_1_PAUSE_LEN_MIN ((uint_fast8_t)(F_INTERRUPTS * ROOMBA_1_PAUSE_TIME * MIN_TOLERANCE_20 + 0.5) - 1) +#define ROOMBA_1_PAUSE_LEN_MAX ((uint_fast8_t)(F_INTERRUPTS * ROOMBA_1_PAUSE_TIME * MAX_TOLERANCE_20 + 0.5) + 1) +#define ROOMBA_0_PAUSE_LEN ((uint_fast8_t)(F_INTERRUPTS * ROOMBA_0_PAUSE_TIME)) +#define ROOMBA_0_PULSE_LEN_MIN ((uint_fast8_t)(F_INTERRUPTS * ROOMBA_0_PULSE_TIME * MIN_TOLERANCE_20 + 0.5) - 1) +#define ROOMBA_0_PULSE_LEN_MAX ((uint_fast8_t)(F_INTERRUPTS * ROOMBA_0_PULSE_TIME * MAX_TOLERANCE_20 + 0.5) + 1) +#define ROOMBA_0_PAUSE_LEN_MIN ((uint_fast8_t)(F_INTERRUPTS * ROOMBA_0_PAUSE_TIME * MIN_TOLERANCE_20 + 0.5) - 1) +#define ROOMBA_0_PAUSE_LEN_MAX ((uint_fast8_t)(F_INTERRUPTS * ROOMBA_0_PAUSE_TIME * MAX_TOLERANCE_20 + 0.5) + 1) + +#define RCMM32_START_BIT_PULSE_LEN_MIN ((uint_fast8_t)(F_INTERRUPTS * RCMM32_START_BIT_PULSE_TIME * MIN_TOLERANCE_05 + 0.5) - 1) +#define RCMM32_START_BIT_PULSE_LEN_MAX ((uint_fast8_t)(F_INTERRUPTS * RCMM32_START_BIT_PULSE_TIME * MAX_TOLERANCE_05 + 0.5) + 1) +#define RCMM32_START_BIT_PAUSE_LEN_MIN ((uint_fast8_t)(F_INTERRUPTS * RCMM32_START_BIT_PAUSE_TIME * MIN_TOLERANCE_05 + 0.5) - 1) +#define RCMM32_START_BIT_PAUSE_LEN_MAX ((uint_fast8_t)(F_INTERRUPTS * RCMM32_START_BIT_PAUSE_TIME * MAX_TOLERANCE_05 + 0.5) + 1) +#define RCMM32_BIT_PULSE_LEN_MIN ((uint_fast8_t)(F_INTERRUPTS * RCMM32_PULSE_TIME * MIN_TOLERANCE_05 + 0.5) - 1) +#define RCMM32_BIT_PULSE_LEN_MAX ((uint_fast8_t)(F_INTERRUPTS * RCMM32_PULSE_TIME * MAX_TOLERANCE_05 + 0.5) + 1) +#define RCMM32_BIT_00_PAUSE_LEN_MIN ((uint_fast8_t)(F_INTERRUPTS * RCMM32_00_PAUSE_TIME * MIN_TOLERANCE_05 + 0.5) - 1) +#define RCMM32_BIT_00_PAUSE_LEN_MAX ((uint_fast8_t)(F_INTERRUPTS * RCMM32_00_PAUSE_TIME * MAX_TOLERANCE_05 + 0.5) + 1) +#define RCMM32_BIT_01_PAUSE_LEN_MIN ((uint_fast8_t)(F_INTERRUPTS * RCMM32_01_PAUSE_TIME * MIN_TOLERANCE_05 + 0.5) - 1) +#define RCMM32_BIT_01_PAUSE_LEN_MAX ((uint_fast8_t)(F_INTERRUPTS * RCMM32_01_PAUSE_TIME * MAX_TOLERANCE_05 + 0.5) + 1) +#define RCMM32_BIT_10_PAUSE_LEN_MIN ((uint_fast8_t)(F_INTERRUPTS * RCMM32_10_PAUSE_TIME * MIN_TOLERANCE_05 + 0.5) - 1) +#define RCMM32_BIT_10_PAUSE_LEN_MAX ((uint_fast8_t)(F_INTERRUPTS * RCMM32_10_PAUSE_TIME * MAX_TOLERANCE_05 + 0.5) + 1) +#define RCMM32_BIT_11_PAUSE_LEN_MIN ((uint_fast8_t)(F_INTERRUPTS * RCMM32_11_PAUSE_TIME * MIN_TOLERANCE_05 + 0.5) - 1) +#define RCMM32_BIT_11_PAUSE_LEN_MAX ((uint_fast8_t)(F_INTERRUPTS * RCMM32_11_PAUSE_TIME * MAX_TOLERANCE_05 + 0.5) + 1) + +#define PENTAX_START_BIT_PULSE_LEN_MIN ((uint_fast8_t)(F_INTERRUPTS * PENTAX_START_BIT_PULSE_TIME * MIN_TOLERANCE_10 + 0.5) - 1) +#define PENTAX_START_BIT_PULSE_LEN_MAX ((uint_fast8_t)(F_INTERRUPTS * PENTAX_START_BIT_PULSE_TIME * MAX_TOLERANCE_10 + 0.5) + 1) +#define PENTAX_START_BIT_PAUSE_LEN_MIN ((uint_fast8_t)(F_INTERRUPTS * PENTAX_START_BIT_PAUSE_TIME * MIN_TOLERANCE_10 + 0.5) - 1) +#define PENTAX_START_BIT_PAUSE_LEN_MAX ((uint_fast8_t)(F_INTERRUPTS * PENTAX_START_BIT_PAUSE_TIME * MAX_TOLERANCE_10 + 0.5) + 1) +#define PENTAX_1_PAUSE_LEN_EXACT ((uint_fast8_t)(F_INTERRUPTS * PENTAX_1_PAUSE_TIME + 0.5)) +#define PENTAX_PULSE_LEN_MIN ((uint_fast8_t)(F_INTERRUPTS * PENTAX_PULSE_TIME * MIN_TOLERANCE_20 + 0.5) - 1) +#define PENTAX_PULSE_LEN_MAX ((uint_fast8_t)(F_INTERRUPTS * PENTAX_PULSE_TIME * MAX_TOLERANCE_20 + 0.5) + 1) +#define PENTAX_1_PAUSE_LEN_MIN ((uint_fast8_t)(F_INTERRUPTS * PENTAX_1_PAUSE_TIME * MIN_TOLERANCE_20 + 0.5) - 1) +#define PENTAX_1_PAUSE_LEN_MAX ((uint_fast8_t)(F_INTERRUPTS * PENTAX_1_PAUSE_TIME * MAX_TOLERANCE_20 + 0.5) + 1) +#define PENTAX_0_PAUSE_LEN ((uint_fast8_t)(F_INTERRUPTS * PENTAX_0_PAUSE_TIME)) +#define PENTAX_PULSE_LEN_MIN ((uint_fast8_t)(F_INTERRUPTS * PENTAX_PULSE_TIME * MIN_TOLERANCE_20 + 0.5) - 1) +#define PENTAX_PULSE_LEN_MAX ((uint_fast8_t)(F_INTERRUPTS * PENTAX_PULSE_TIME * MAX_TOLERANCE_20 + 0.5) + 1) +#define PENTAX_0_PAUSE_LEN_MIN ((uint_fast8_t)(F_INTERRUPTS * PENTAX_0_PAUSE_TIME * MIN_TOLERANCE_20 + 0.5) - 1) +#define PENTAX_0_PAUSE_LEN_MAX ((uint_fast8_t)(F_INTERRUPTS * PENTAX_0_PAUSE_TIME * MAX_TOLERANCE_20 + 0.5) + 1) + +#define ACP24_START_BIT_PULSE_LEN_MIN ((uint_fast8_t)(F_INTERRUPTS * ACP24_START_BIT_PULSE_TIME * MIN_TOLERANCE_15 + 0.5) - 1) +#define ACP24_START_BIT_PULSE_LEN_MAX ((uint_fast8_t)(F_INTERRUPTS * ACP24_START_BIT_PULSE_TIME * MAX_TOLERANCE_15 + 0.5) + 1) +#define ACP24_START_BIT_PAUSE_LEN_MIN ((uint_fast8_t)(F_INTERRUPTS * ACP24_START_BIT_PAUSE_TIME * MIN_TOLERANCE_15 + 0.5) - 1) +#define ACP24_START_BIT_PAUSE_LEN_MAX ((uint_fast8_t)(F_INTERRUPTS * ACP24_START_BIT_PAUSE_TIME * MAX_TOLERANCE_15 + 0.5) + 1) +#define ACP24_PULSE_LEN_MIN ((uint_fast8_t)(F_INTERRUPTS * ACP24_PULSE_TIME * MIN_TOLERANCE_15 + 0.5) - 1) +#define ACP24_PULSE_LEN_MAX ((uint_fast8_t)(F_INTERRUPTS * ACP24_PULSE_TIME * MAX_TOLERANCE_15 + 0.5) + 1) +#define ACP24_1_PAUSE_LEN_MIN ((uint_fast8_t)(F_INTERRUPTS * ACP24_1_PAUSE_TIME * MIN_TOLERANCE_15 + 0.5) - 1) +#define ACP24_1_PAUSE_LEN_MAX ((uint_fast8_t)(F_INTERRUPTS * ACP24_1_PAUSE_TIME * MAX_TOLERANCE_15 + 0.5) + 1) +#define ACP24_0_PAUSE_LEN_MIN ((uint_fast8_t)(F_INTERRUPTS * ACP24_0_PAUSE_TIME * MIN_TOLERANCE_15 + 0.5) - 1) +#define ACP24_0_PAUSE_LEN_MAX ((uint_fast8_t)(F_INTERRUPTS * ACP24_0_PAUSE_TIME * MAX_TOLERANCE_15 + 0.5) + 1) + +#define METZ_START_BIT_PULSE_LEN_MIN ((uint_fast8_t)(F_INTERRUPTS * METZ_START_BIT_PULSE_TIME * MIN_TOLERANCE_05 + 0.5) - 1) +#define METZ_START_BIT_PULSE_LEN_MAX ((uint_fast8_t)(F_INTERRUPTS * METZ_START_BIT_PULSE_TIME * MAX_TOLERANCE_05 + 0.5) + 1) +#define METZ_START_BIT_PAUSE_LEN_MIN ((uint_fast8_t)(F_INTERRUPTS * METZ_START_BIT_PAUSE_TIME * MIN_TOLERANCE_05 + 0.5) - 1) +#define METZ_START_BIT_PAUSE_LEN_MAX ((uint_fast8_t)(F_INTERRUPTS * METZ_START_BIT_PAUSE_TIME * MAX_TOLERANCE_05 + 0.5) + 1) +#define METZ_PULSE_LEN_MIN ((uint_fast8_t)(F_INTERRUPTS * METZ_PULSE_TIME * MIN_TOLERANCE_20 + 0.5) - 1) +#define METZ_PULSE_LEN_MAX ((uint_fast8_t)(F_INTERRUPTS * METZ_PULSE_TIME * MAX_TOLERANCE_20 + 0.5) + 1) +#define METZ_1_PAUSE_LEN_MIN ((uint_fast8_t)(F_INTERRUPTS * METZ_1_PAUSE_TIME * MIN_TOLERANCE_20 + 0.5) - 1) +#define METZ_1_PAUSE_LEN_MAX ((uint_fast8_t)(F_INTERRUPTS * METZ_1_PAUSE_TIME * MAX_TOLERANCE_20 + 0.5) + 1) +#define METZ_0_PAUSE_LEN_MIN ((uint_fast8_t)(F_INTERRUPTS * METZ_0_PAUSE_TIME * MIN_TOLERANCE_20 + 0.5) - 1) +#define METZ_0_PAUSE_LEN_MAX ((uint_fast8_t)(F_INTERRUPTS * METZ_0_PAUSE_TIME * MAX_TOLERANCE_20 + 0.5) + 1) +#define METZ_FRAME_REPEAT_PAUSE_LEN_MAX (uint_fast16_t)(F_INTERRUPTS * METZ_FRAME_REPEAT_PAUSE_TIME * MAX_TOLERANCE_20 + 0.5) + +#define RADIO1_START_BIT_PULSE_LEN_MIN ((uint_fast8_t)(F_INTERRUPTS * RADIO1_START_BIT_PULSE_TIME * MIN_TOLERANCE_10 + 0.5) - 1) +#define RADIO1_START_BIT_PULSE_LEN_MAX ((uint_fast8_t)(F_INTERRUPTS * RADIO1_START_BIT_PULSE_TIME * MAX_TOLERANCE_10 + 0.5) + 1) +#define RADIO1_START_BIT_PAUSE_LEN_MIN ((uint_fast8_t)(F_INTERRUPTS * RADIO1_START_BIT_PAUSE_TIME * MIN_TOLERANCE_10 + 0.5) - 1) +#define RADIO1_START_BIT_PAUSE_LEN_MAX ((uint_fast8_t)(F_INTERRUPTS * RADIO1_START_BIT_PAUSE_TIME * MAX_TOLERANCE_10 + 0.5) + 1) +#define RADIO1_1_PAUSE_LEN_EXACT ((uint_fast8_t)(F_INTERRUPTS * RADIO1_1_PAUSE_TIME + 0.5)) +#define RADIO1_1_PULSE_LEN_MIN ((uint_fast8_t)(F_INTERRUPTS * RADIO1_1_PULSE_TIME * MIN_TOLERANCE_20 + 0.5) - 1) +#define RADIO1_1_PULSE_LEN_MAX ((uint_fast8_t)(F_INTERRUPTS * RADIO1_1_PULSE_TIME * MAX_TOLERANCE_20 + 0.5) + 1) +#define RADIO1_1_PAUSE_LEN_MIN ((uint_fast8_t)(F_INTERRUPTS * RADIO1_1_PAUSE_TIME * MIN_TOLERANCE_20 + 0.5) - 1) +#define RADIO1_1_PAUSE_LEN_MAX ((uint_fast8_t)(F_INTERRUPTS * RADIO1_1_PAUSE_TIME * MAX_TOLERANCE_20 + 0.5) + 1) +#define RADIO1_0_PAUSE_LEN ((uint_fast8_t)(F_INTERRUPTS * RADIO1_0_PAUSE_TIME)) +#define RADIO1_0_PULSE_LEN_MIN ((uint_fast8_t)(F_INTERRUPTS * RADIO1_0_PULSE_TIME * MIN_TOLERANCE_20 + 0.5) - 1) +#define RADIO1_0_PULSE_LEN_MAX ((uint_fast8_t)(F_INTERRUPTS * RADIO1_0_PULSE_TIME * MAX_TOLERANCE_20 + 0.5) + 1) +#define RADIO1_0_PAUSE_LEN_MIN ((uint_fast8_t)(F_INTERRUPTS * RADIO1_0_PAUSE_TIME * MIN_TOLERANCE_20 + 0.5) - 1) +#define RADIO1_0_PAUSE_LEN_MAX ((uint_fast8_t)(F_INTERRUPTS * RADIO1_0_PAUSE_TIME * MAX_TOLERANCE_20 + 0.5) + 1) + +#define AUTO_FRAME_REPETITION_LEN (uint_fast16_t)(F_INTERRUPTS * AUTO_FRAME_REPETITION_TIME + 0.5) // use uint_fast16_t! + +#ifdef ANALYZE +# define ANALYZE_PUTCHAR(a) { if (! silent) { putchar (a); } } +# define ANALYZE_ONLY_NORMAL_PUTCHAR(a) { if (! silent && !verbose) { putchar (a); } } +# define ANALYZE_PRINTF(...) { if (verbose) { printf (__VA_ARGS__); } } +# define ANALYZE_ONLY_NORMAL_PRINTF(...) { if (! silent && !verbose) { printf (__VA_ARGS__); } } +# define ANALYZE_NEWLINE() { if (verbose) { putchar ('\n'); } } +static int silent; +static int time_counter; +static int verbose; + +/******************************* not every PIC compiler knows variadic macros :-( +#else +# define ANALYZE_PUTCHAR(a) +# define ANALYZE_ONLY_NORMAL_PUTCHAR(a) +# define ANALYZE_PRINTF(...) +# define ANALYZE_ONLY_NORMAL_PRINTF(...) +# endif +# define ANALYZE_NEWLINE() +*********************************/ +#endif + +#if IRMP_USE_CALLBACK == 1 +static void (*irmp_callback_ptr) (uint_fast8_t); +#endif // IRMP_USE_CALLBACK == 1 + +#define PARITY_CHECK_OK 1 +#define PARITY_CHECK_FAILED 0 + +/*--------------------------------------------------------------------------------------------------------------------------------------------------- + * Protocol names + *--------------------------------------------------------------------------------------------------------------------------------------------------- + */ +#if defined(UNIX_OR_WINDOWS) || IRMP_PROTOCOL_NAMES == 1 +static const char proto_unknown[] PROGMEM = "UNKNOWN"; +static const char proto_sircs[] PROGMEM = "SIRCS"; +static const char proto_nec[] PROGMEM = "NEC"; +static const char proto_samsung[] PROGMEM = "SAMSUNG"; +static const char proto_matsushita[] PROGMEM = "MATSUSH"; +static const char proto_kaseikyo[] PROGMEM = "KASEIKYO"; +static const char proto_recs80[] PROGMEM = "RECS80"; +static const char proto_rc5[] PROGMEM = "RC5"; +static const char proto_denon[] PROGMEM = "DENON"; +static const char proto_rc6[] PROGMEM = "RC6"; +static const char proto_samsung32[] PROGMEM = "SAMSG32"; +static const char proto_apple[] PROGMEM = "APPLE"; +static const char proto_recs80ext[] PROGMEM = "RECS80EX"; +static const char proto_nubert[] PROGMEM = "NUBERT"; +static const char proto_bang_olufsen[] PROGMEM = "BANG OLU"; +static const char proto_grundig[] PROGMEM = "GRUNDIG"; +static const char proto_nokia[] PROGMEM = "NOKIA"; +static const char proto_siemens[] PROGMEM = "SIEMENS"; +static const char proto_fdc[] PROGMEM = "FDC"; +static const char proto_rccar[] PROGMEM = "RCCAR"; +static const char proto_jvc[] PROGMEM = "JVC"; +static const char proto_rc6a[] PROGMEM = "RC6A"; +static const char proto_nikon[] PROGMEM = "NIKON"; +static const char proto_ruwido[] PROGMEM = "RUWIDO"; +static const char proto_ir60[] PROGMEM = "IR60"; +static const char proto_kathrein[] PROGMEM = "KATHREIN"; +static const char proto_netbox[] PROGMEM = "NETBOX"; +static const char proto_nec16[] PROGMEM = "NEC16"; +static const char proto_nec42[] PROGMEM = "NEC42"; +static const char proto_lego[] PROGMEM = "LEGO"; +static const char proto_thomson[] PROGMEM = "THOMSON"; +static const char proto_bose[] PROGMEM = "BOSE"; +static const char proto_a1tvbox[] PROGMEM = "A1TVBOX"; +static const char proto_ortek[] PROGMEM = "ORTEK"; +static const char proto_telefunken[] PROGMEM = "TELEFUNKEN"; +static const char proto_roomba[] PROGMEM = "ROOMBA"; +static const char proto_rcmm32[] PROGMEM = "RCMM32"; +static const char proto_rcmm24[] PROGMEM = "RCMM24"; +static const char proto_rcmm12[] PROGMEM = "RCMM12"; +static const char proto_speaker[] PROGMEM = "SPEAKER"; +static const char proto_lgair[] PROGMEM = "LGAIR"; +static const char proto_samsung48[] PROGMEM = "SAMSG48"; +static const char proto_merlin[] PROGMEM = "MERLIN"; +static const char proto_pentax[] PROGMEM = "PENTAX"; +static const char proto_fan[] PROGMEM = "FAN"; +static const char proto_s100[] PROGMEM = "S100"; +static const char proto_acp24[] PROGMEM = "ACP24"; +static const char proto_technics[] PROGMEM = "TECHNICS"; +static const char proto_panasonic[] PROGMEM = "PANASONIC"; +static const char proto_mitsu_heavy[] PROGMEM = "MITSU_HEAVY"; +static const char proto_vincent[] PROGMEM = "VINCENT"; +static const char proto_samsungah[] PROGMEM = "SAMSUNGAH"; +static const char proto_irmp16[] PROGMEM = "IRMP16"; +static const char proto_gree[] PROGMEM = "GREE"; +static const char proto_rcii[] PROGMEM = "RCII"; +static const char proto_metz[] PROGMEM = "METZ"; +static const char proto_onkyo[] PROGMEM = "ONKYO"; + +static const char proto_radio1[] PROGMEM = "RADIO1"; + +const char * const +irmp_protocol_names[IRMP_N_PROTOCOLS + 1] PROGMEM = +{ + proto_unknown, + proto_sircs, + proto_nec, + proto_samsung, + proto_matsushita, + proto_kaseikyo, + proto_recs80, + proto_rc5, + proto_denon, + proto_rc6, + proto_samsung32, + proto_apple, + proto_recs80ext, + proto_nubert, + proto_bang_olufsen, + proto_grundig, + proto_nokia, + proto_siemens, + proto_fdc, + proto_rccar, + proto_jvc, + proto_rc6a, + proto_nikon, + proto_ruwido, + proto_ir60, + proto_kathrein, + proto_netbox, + proto_nec16, + proto_nec42, + proto_lego, + proto_thomson, + proto_bose, + proto_a1tvbox, + proto_ortek, + proto_telefunken, + proto_roomba, + proto_rcmm32, + proto_rcmm24, + proto_rcmm12, + proto_speaker, + proto_lgair, + proto_samsung48, + proto_merlin, + proto_pentax, + proto_fan, + proto_s100, + proto_acp24, + proto_technics, + proto_panasonic, + proto_mitsu_heavy, + proto_vincent, + proto_samsungah, + proto_irmp16, + proto_gree, + proto_rcii, + proto_metz, + proto_onkyo, + + proto_radio1 +}; + +#endif + +/*--------------------------------------------------------------------------------------------------------------------------------------------------- + * Logging + *--------------------------------------------------------------------------------------------------------------------------------------------------- + */ +#if IRMP_LOGGING == 1 // logging via UART + +#if defined(ARM_STM32F4XX) +# define STM32_GPIO_CLOCK RCC_AHB1Periph_GPIOA // UART2 on PA2 +# define STM32_UART_CLOCK RCC_APB1Periph_USART2 +# define STM32_GPIO_PORT GPIOA +# define STM32_GPIO_PIN GPIO_Pin_2 +# define STM32_GPIO_SOURCE GPIO_PinSource2 +# define STM32_UART_AF GPIO_AF_USART2 +# define STM32_UART_COM USART2 +# define STM32_UART_BAUD 115200 // 115200 Baud +# include "stm32f4xx_usart.h" +#elif defined(ARM_STM32F10X) +# define STM32_UART_COM USART3 // UART3 on PB10 +#elif defined(ARDUINO) // Arduino Serial implementation +# if defined(USB_SERIAL) +# include "usb_serial.h" +# else +# error USB_SERIAL not defined in ARDUINO Environment +# endif +#elif defined(_CHIBIOS_HAL_) // ChibiOS HAL +# if IRMP_EXT_LOGGING == 1 +# error IRMP_EXT_LOGGING not implemented for ChibiOS HAL, use regular logging instead +# endif +#else +# if IRMP_EXT_LOGGING == 1 // use external logging +# include "irmpextlog.h" +# else // normal UART log (IRMP_EXT_LOGGING == 0) +# define BAUD 9600L +# ifndef UNIX_OR_WINDOWS +# include <util/setbaud.h> +# endif + +#ifdef UBRR0H + +#define UART0_UBRRH UBRR0H +#define UART0_UBRRL UBRR0L +#define UART0_UCSRA UCSR0A +#define UART0_UCSRB UCSR0B +#define UART0_UCSRC UCSR0C +#define UART0_UDRE_BIT_VALUE (1<<UDRE0) +#define UART0_UCSZ1_BIT_VALUE (1<<UCSZ01) +#define UART0_UCSZ0_BIT_VALUE (1<<UCSZ00) +#ifdef URSEL0 +#define UART0_URSEL_BIT_VALUE (1<<URSEL0) +#else +#define UART0_URSEL_BIT_VALUE (0) +#endif +#define UART0_TXEN_BIT_VALUE (1<<TXEN0) +#define UART0_UDR UDR0 +#define UART0_U2X U2X0 + +#else + +#define UART0_UBRRH UBRRH +#define UART0_UBRRL UBRRL +#define UART0_UCSRA UCSRA +#define UART0_UCSRB UCSRB +#define UART0_UCSRC UCSRC +#define UART0_UDRE_BIT_VALUE (1<<UDRE) +#define UART0_UCSZ1_BIT_VALUE (1<<UCSZ1) +#define UART0_UCSZ0_BIT_VALUE (1<<UCSZ0) +#ifdef URSEL +#define UART0_URSEL_BIT_VALUE (1<<URSEL) +#else +#define UART0_URSEL_BIT_VALUE (0) +#endif +#define UART0_TXEN_BIT_VALUE (1<<TXEN) +#define UART0_UDR UDR +#define UART0_U2X U2X + +#endif //UBRR0H +#endif //IRMP_EXT_LOGGING +#endif //ARM_STM32F4XX + +/*--------------------------------------------------------------------------------------------------------------------------------------------------- + * Initialize UART + * @details Initializes UART + *--------------------------------------------------------------------------------------------------------------------------------------------------- + */ +void +irmp_uart_init (void) +{ +#ifndef UNIX_OR_WINDOWS +#if defined(ARM_STM32F4XX) + GPIO_InitTypeDef GPIO_InitStructure; + USART_InitTypeDef USART_InitStructure; + + // Clock enable vom TX Pin + RCC_AHB1PeriphClockCmd(STM32_GPIO_CLOCK, ENABLE); + + // Clock enable der UART + RCC_APB1PeriphClockCmd(STM32_UART_CLOCK, ENABLE); + + // UART Alternative-Funktion mit dem IO-Pin verbinden + GPIO_PinAFConfig(STM32_GPIO_PORT,STM32_GPIO_SOURCE,STM32_UART_AF); + + // UART als Alternative-Funktion mit PushPull + GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; + GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; + GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; + GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; + + // TX-Pin + GPIO_InitStructure.GPIO_Pin = STM32_GPIO_PIN; + GPIO_Init(STM32_GPIO_PORT, &GPIO_InitStructure); + + // Oversampling + USART_OverSampling8Cmd(STM32_UART_COM, ENABLE); + + // init baud rate, 8 data bits, 1 stop bit, no parity, no RTS+CTS + USART_InitStructure.USART_BaudRate = STM32_UART_BAUD; + USART_InitStructure.USART_WordLength = USART_WordLength_8b; + USART_InitStructure.USART_StopBits = USART_StopBits_1; + USART_InitStructure.USART_Parity = USART_Parity_No; + USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; + USART_InitStructure.USART_Mode = USART_Mode_Tx; + USART_Init(STM32_UART_COM, &USART_InitStructure); + + // UART enable + USART_Cmd(STM32_UART_COM, ENABLE); + +#elif defined(ARM_STM32F10X) + GPIO_InitTypeDef GPIO_InitStructure; + USART_InitTypeDef USART_InitStructure; + + // Clock enable vom TX Pin + RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); // UART3 an PB10 + + // Clock enable der UART + RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3, ENABLE); + + // UART als Alternative-Funktion mit PushPull + GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; + GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; + + // TX-Pin + GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; + GPIO_Init(GPIOB, &GPIO_InitStructure); + + // Oversampling + USART_OverSampling8Cmd(STM32_UART_COM, ENABLE); + + // init baud rate, 8 data bits, 1 stop bit, no parity, no RTS+CTS + USART_InitStructure.USART_BaudRate = 115200; + USART_InitStructure.USART_WordLength = USART_WordLength_8b; + USART_InitStructure.USART_StopBits = USART_StopBits_1; + USART_InitStructure.USART_Parity = USART_Parity_No; + USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; + USART_InitStructure.USART_Mode = USART_Mode_Tx; + USART_Init(STM32_UART_COM, &USART_InitStructure); + + // UART enable + USART_Cmd(STM32_UART_COM, ENABLE); + +#elif defined(ARDUINO) + // we use the Arduino Serial Imlementation + // you have to call Serial.begin(SER_BAUD); in Arduino setup() function + +#elif defined (__AVR_XMEGA__) + + PMIC.CTRL |= PMIC_HILVLEN_bm; + + USARTC1.BAUDCTRLB = 0; + USARTC1.BAUDCTRLA = F_CPU / 153600 - 1; + USARTC1.CTRLA = USART_RXCINTLVL_HI_gc; // high INT level (receive) + USARTC1.CTRLB = USART_TXEN_bm | USART_RXEN_bm; // activated RX and TX + USARTC1.CTRLC = USART_CHSIZE_8BIT_gc; // 8 Bit + PORTC.DIR |= (1<<7); // TXD is output + PORTC.DIR &= ~(1<<6); + +#elif defined (_CHIBIOS_HAL_) + // we use the SD interface for logging, no need to init that here + +#else + +#if (IRMP_EXT_LOGGING == 0) // use UART + UART0_UBRRH = UBRRH_VALUE; // set baud rate + UART0_UBRRL = UBRRL_VALUE; + +#if USE_2X + UART0_UCSRA |= (1<<UART0_U2X); +#else + UART0_UCSRA &= ~(1<<UART0_U2X); +#endif + + UART0_UCSRC = UART0_UCSZ1_BIT_VALUE | UART0_UCSZ0_BIT_VALUE | UART0_URSEL_BIT_VALUE; + UART0_UCSRB |= UART0_TXEN_BIT_VALUE; // enable UART TX +#else // other log method + initextlog(); +#endif //IRMP_EXT_LOGGING +#endif //ARM_STM32F4XX +#endif // UNIX_OR_WINDOWS +} + +/*--------------------------------------------------------------------------------------------------------------------------------------------------- + * Send character + * @details Sends character + * @param ch character to be transmitted + *--------------------------------------------------------------------------------------------------------------------------------------------------- + */ +void +irmp_uart_putc (unsigned char ch) +{ +#ifndef UNIX_OR_WINDOWS +#if defined(ARM_STM32F4XX) || defined(ARM_STM32F10X) + // warten bis altes Byte gesendet wurde + while (USART_GetFlagStatus(STM32_UART_COM, USART_FLAG_TXE) == RESET) + { + ; + } + + USART_SendData(STM32_UART_COM, ch); + + if (ch == '\n') + { + while (USART_GetFlagStatus(STM32_UART_COM, USART_FLAG_TXE) == RESET); + USART_SendData(STM32_UART_COM, '\r'); + } + +#elif defined(ARDUINO) + // we use the Arduino Serial Imlementation + usb_serial_putchar(ch); + +#elif defined(_CHIBIOS_HAL_) + // use the SD interface from HAL, log to IRMP_LOGGING_SD which is defined in irmpconfig.h + sdWriteI(&IRMP_LOGGING_SD,&ch,1); // we are called from interrupt context, so use the ...I version of the function + +#else +#if (IRMP_EXT_LOGGING == 0) + +# if defined (__AVR_XMEGA__) + while (!(USARTC1.STATUS & USART_DREIF_bm)) + { + ; + } + + USARTC1.DATA = ch; + +# else // AVR_MEGA + while (!(UART0_UCSRA & UART0_UDRE_BIT_VALUE)) + { + ; + } + + UART0_UDR = ch; + +# endif // __AVR_XMEGA__ + +#else + + sendextlog(ch); // use external log + +#endif // IRMP_EXT_LOGGING +#endif // ARM_STM32F4XX +#else + fputc (ch, stderr); +#endif // UNIX_OR_WINDOWS +} + +/*--------------------------------------------------------------------------------------------------------------------------------------------------- + * Log IR signal + *--------------------------------------------------------------------------------------------------------------------------------------------------- + */ + +#define STARTCYCLES 2 // min count of zeros before start of logging +#define ENDBITS 1000 // number of sequenced highbits to detect end +#define DATALEN 700 // log buffer size + +static void +irmp_log (uint_fast8_t val) +{ + static uint8_t buf[DATALEN]; // logging buffer + static uint_fast16_t buf_idx; // index + static uint_fast8_t startcycles; // current number of start-zeros + static uint_fast16_t cnt; // counts sequenced highbits - to detect end + static uint_fast8_t last_val = 1; + + if (! val && (startcycles < STARTCYCLES) && !buf_idx) // prevent that single random zeros init logging + { + startcycles++; + } + else + { + startcycles = 0; + + if (! val || buf_idx != 0) // start or continue logging on "0", "1" cannot init logging + { + if (last_val == val) + { + cnt++; + + if (val && cnt > ENDBITS) // if high received then look at log-stop condition + { // if stop condition is true, output on uart + uint_fast8_t i8; + uint_fast16_t i; + uint_fast16_t j; + uint_fast8_t v = '1'; + uint_fast16_t d; + + for (i8 = 0; i8 < STARTCYCLES; i8++) + { + irmp_uart_putc ('0'); // the ignored starting zeros + } + + for (i = 0; i < buf_idx; i++) + { + d = buf[i]; + + if (d == 0xff) + { + i++; + d = buf[i]; + i++; + d |= ((uint_fast16_t) buf[i] << 8); + } + + for (j = 0; j < d; j++) + { + irmp_uart_putc (v); + } + + v = (v == '1') ? '0' : '1'; + } + + for (i8 = 0; i8 < 20; i8++) + { + irmp_uart_putc ('1'); + } + + irmp_uart_putc ('\n'); + buf_idx = 0; + last_val = 1; + cnt = 0; + } + } + else if (buf_idx < DATALEN - 3) + { + if (cnt >= 0xff) + { + buf[buf_idx++] = 0xff; + buf[buf_idx++] = (cnt & 0xff); + buf[buf_idx] = (cnt >> 8); + } + else + { + buf[buf_idx] = cnt; + } + + buf_idx++; + cnt = 1; + last_val = val; + } + } + } +} + +#else +#define irmp_log(val) +#endif //IRMP_LOGGING + +typedef struct +{ + uint_fast8_t protocol; // ir protocol + uint_fast8_t pulse_1_len_min; // minimum length of pulse with bit value 1 + uint_fast8_t pulse_1_len_max; // maximum length of pulse with bit value 1 + uint_fast8_t pause_1_len_min; // minimum length of pause with bit value 1 + uint_fast8_t pause_1_len_max; // maximum length of pause with bit value 1 + uint_fast8_t pulse_0_len_min; // minimum length of pulse with bit value 0 + uint_fast8_t pulse_0_len_max; // maximum length of pulse with bit value 0 + uint_fast8_t pause_0_len_min; // minimum length of pause with bit value 0 + uint_fast8_t pause_0_len_max; // maximum length of pause with bit value 0 + uint_fast8_t address_offset; // address offset + uint_fast8_t address_end; // end of address + uint_fast8_t command_offset; // command offset + uint_fast8_t command_end; // end of command + uint_fast8_t complete_len; // complete length of frame + uint_fast8_t stop_bit; // flag: frame has stop bit + uint_fast8_t lsb_first; // flag: LSB first + uint_fast8_t flags; // some flags +} IRMP_PARAMETER; + +#if IRMP_SUPPORT_SIRCS_PROTOCOL == 1 + +static const PROGMEM IRMP_PARAMETER sircs_param = +{ + IRMP_SIRCS_PROTOCOL, // protocol: ir protocol + SIRCS_1_PULSE_LEN_MIN, // pulse_1_len_min: minimum length of pulse with bit value 1 + SIRCS_1_PULSE_LEN_MAX, // pulse_1_len_max: maximum length of pulse with bit value 1 + SIRCS_PAUSE_LEN_MIN, // pause_1_len_min: minimum length of pause with bit value 1 + SIRCS_PAUSE_LEN_MAX, // pause_1_len_max: maximum length of pause with bit value 1 + SIRCS_0_PULSE_LEN_MIN, // pulse_0_len_min: minimum length of pulse with bit value 0 + SIRCS_0_PULSE_LEN_MAX, // pulse_0_len_max: maximum length of pulse with bit value 0 + SIRCS_PAUSE_LEN_MIN, // pause_0_len_min: minimum length of pause with bit value 0 + SIRCS_PAUSE_LEN_MAX, // pause_0_len_max: maximum length of pause with bit value 0 + SIRCS_ADDRESS_OFFSET, // address_offset: address offset + SIRCS_ADDRESS_OFFSET + SIRCS_ADDRESS_LEN, // address_end: end of address + SIRCS_COMMAND_OFFSET, // command_offset: command offset + SIRCS_COMMAND_OFFSET + SIRCS_COMMAND_LEN, // command_end: end of command + SIRCS_COMPLETE_DATA_LEN, // complete_len: complete length of frame + SIRCS_STOP_BIT, // stop_bit: flag: frame has stop bit + SIRCS_LSB, // lsb_first: flag: LSB first + SIRCS_FLAGS // flags: some flags +}; + +#endif + +#if IRMP_SUPPORT_NEC_PROTOCOL == 1 + +static const PROGMEM IRMP_PARAMETER nec_param = +{ + IRMP_NEC_PROTOCOL, // protocol: ir protocol + NEC_PULSE_LEN_MIN, // pulse_1_len_min: minimum length of pulse with bit value 1 + NEC_PULSE_LEN_MAX, // pulse_1_len_max: maximum length of pulse with bit value 1 + NEC_1_PAUSE_LEN_MIN, // pause_1_len_min: minimum length of pause with bit value 1 + NEC_1_PAUSE_LEN_MAX, // pause_1_len_max: maximum length of pause with bit value 1 + NEC_PULSE_LEN_MIN, // pulse_0_len_min: minimum length of pulse with bit value 0 + NEC_PULSE_LEN_MAX, // pulse_0_len_max: maximum length of pulse with bit value 0 + NEC_0_PAUSE_LEN_MIN, // pause_0_len_min: minimum length of pause with bit value 0 + NEC_0_PAUSE_LEN_MAX, // pause_0_len_max: maximum length of pause with bit value 0 + NEC_ADDRESS_OFFSET, // address_offset: address offset + NEC_ADDRESS_OFFSET + NEC_ADDRESS_LEN, // address_end: end of address + NEC_COMMAND_OFFSET, // command_offset: command offset + NEC_COMMAND_OFFSET + NEC_COMMAND_LEN, // command_end: end of command + NEC_COMPLETE_DATA_LEN, // complete_len: complete length of frame + NEC_STOP_BIT, // stop_bit: flag: frame has stop bit + NEC_LSB, // lsb_first: flag: LSB first + NEC_FLAGS // flags: some flags +}; + +static const PROGMEM IRMP_PARAMETER nec_rep_param = +{ + IRMP_NEC_PROTOCOL, // protocol: ir protocol + NEC_PULSE_LEN_MIN, // pulse_1_len_min: minimum length of pulse with bit value 1 + NEC_PULSE_LEN_MAX, // pulse_1_len_max: maximum length of pulse with bit value 1 + NEC_1_PAUSE_LEN_MIN, // pause_1_len_min: minimum length of pause with bit value 1 + NEC_1_PAUSE_LEN_MAX, // pause_1_len_max: maximum length of pause with bit value 1 + NEC_PULSE_LEN_MIN, // pulse_0_len_min: minimum length of pulse with bit value 0 + NEC_PULSE_LEN_MAX, // pulse_0_len_max: maximum length of pulse with bit value 0 + NEC_0_PAUSE_LEN_MIN, // pause_0_len_min: minimum length of pause with bit value 0 + NEC_0_PAUSE_LEN_MAX, // pause_0_len_max: maximum length of pause with bit value 0 + 0, // address_offset: address offset + 0, // address_end: end of address + 0, // command_offset: command offset + 0, // command_end: end of command + 0, // complete_len: complete length of frame + NEC_STOP_BIT, // stop_bit: flag: frame has stop bit + NEC_LSB, // lsb_first: flag: LSB first + NEC_FLAGS // flags: some flags +}; + +#endif + +#if IRMP_SUPPORT_NEC42_PROTOCOL == 1 + +static const PROGMEM IRMP_PARAMETER nec42_param = +{ + IRMP_NEC42_PROTOCOL, // protocol: ir protocol + NEC_PULSE_LEN_MIN, // pulse_1_len_min: minimum length of pulse with bit value 1 + NEC_PULSE_LEN_MAX, // pulse_1_len_max: maximum length of pulse with bit value 1 + NEC_1_PAUSE_LEN_MIN, // pause_1_len_min: minimum length of pause with bit value 1 + NEC_1_PAUSE_LEN_MAX, // pause_1_len_max: maximum length of pause with bit value 1 + NEC_PULSE_LEN_MIN, // pulse_0_len_min: minimum length of pulse with bit value 0 + NEC_PULSE_LEN_MAX, // pulse_0_len_max: maximum length of pulse with bit value 0 + NEC_0_PAUSE_LEN_MIN, // pause_0_len_min: minimum length of pause with bit value 0 + NEC_0_PAUSE_LEN_MAX, // pause_0_len_max: maximum length of pause with bit value 0 + NEC42_ADDRESS_OFFSET, // address_offset: address offset + NEC42_ADDRESS_OFFSET + NEC42_ADDRESS_LEN, // address_end: end of address + NEC42_COMMAND_OFFSET, // command_offset: command offset + NEC42_COMMAND_OFFSET + NEC42_COMMAND_LEN, // command_end: end of command + NEC42_COMPLETE_DATA_LEN, // complete_len: complete length of frame + NEC_STOP_BIT, // stop_bit: flag: frame has stop bit + NEC_LSB, // lsb_first: flag: LSB first + NEC_FLAGS // flags: some flags +}; + +#endif + +#if IRMP_SUPPORT_LGAIR_PROTOCOL == 1 + +static const PROGMEM IRMP_PARAMETER lgair_param = +{ + IRMP_LGAIR_PROTOCOL, // protocol: ir protocol + NEC_PULSE_LEN_MIN, // pulse_1_len_min: minimum length of pulse with bit value 1 + NEC_PULSE_LEN_MAX, // pulse_1_len_max: maximum length of pulse with bit value 1 + NEC_1_PAUSE_LEN_MIN, // pause_1_len_min: minimum length of pause with bit value 1 + NEC_1_PAUSE_LEN_MAX, // pause_1_len_max: maximum length of pause with bit value 1 + NEC_PULSE_LEN_MIN, // pulse_0_len_min: minimum length of pulse with bit value 0 + NEC_PULSE_LEN_MAX, // pulse_0_len_max: maximum length of pulse with bit value 0 + NEC_0_PAUSE_LEN_MIN, // pause_0_len_min: minimum length of pause with bit value 0 + NEC_0_PAUSE_LEN_MAX, // pause_0_len_max: maximum length of pause with bit value 0 + LGAIR_ADDRESS_OFFSET, // address_offset: address offset + LGAIR_ADDRESS_OFFSET + LGAIR_ADDRESS_LEN, // address_end: end of address + LGAIR_COMMAND_OFFSET, // command_offset: command offset + LGAIR_COMMAND_OFFSET + LGAIR_COMMAND_LEN, // command_end: end of command + LGAIR_COMPLETE_DATA_LEN, // complete_len: complete length of frame + NEC_STOP_BIT, // stop_bit: flag: frame has stop bit + NEC_LSB, // lsb_first: flag: LSB first + NEC_FLAGS // flags: some flags +}; + +#endif + +#if IRMP_SUPPORT_SAMSUNG_PROTOCOL == 1 + +static const PROGMEM IRMP_PARAMETER samsung_param = +{ + IRMP_SAMSUNG_PROTOCOL, // protocol: ir protocol + SAMSUNG_PULSE_LEN_MIN, // pulse_1_len_min: minimum length of pulse with bit value 1 + SAMSUNG_PULSE_LEN_MAX, // pulse_1_len_max: maximum length of pulse with bit value 1 + SAMSUNG_1_PAUSE_LEN_MIN, // pause_1_len_min: minimum length of pause with bit value 1 + SAMSUNG_1_PAUSE_LEN_MAX, // pause_1_len_max: maximum length of pause with bit value 1 + SAMSUNG_PULSE_LEN_MIN, // pulse_0_len_min: minimum length of pulse with bit value 0 + SAMSUNG_PULSE_LEN_MAX, // pulse_0_len_max: maximum length of pulse with bit value 0 + SAMSUNG_0_PAUSE_LEN_MIN, // pause_0_len_min: minimum length of pause with bit value 0 + SAMSUNG_0_PAUSE_LEN_MAX, // pause_0_len_max: maximum length of pause with bit value 0 + SAMSUNG_ADDRESS_OFFSET, // address_offset: address offset + SAMSUNG_ADDRESS_OFFSET + SAMSUNG_ADDRESS_LEN, // address_end: end of address + SAMSUNG_COMMAND_OFFSET, // command_offset: command offset + SAMSUNG_COMMAND_OFFSET + SAMSUNG_COMMAND_LEN, // command_end: end of command + SAMSUNG_COMPLETE_DATA_LEN, // complete_len: complete length of frame + SAMSUNG_STOP_BIT, // stop_bit: flag: frame has stop bit + SAMSUNG_LSB, // lsb_first: flag: LSB first + SAMSUNG_FLAGS // flags: some flags +}; + +#endif + +#if IRMP_SUPPORT_SAMSUNGAH_PROTOCOL == 1 + +static const PROGMEM IRMP_PARAMETER samsungah_param = +{ + IRMP_SAMSUNGAH_PROTOCOL, // protocol: ir protocol + SAMSUNGAH_PULSE_LEN_MIN, // pulse_1_len_min: minimum length of pulse with bit value 1 + SAMSUNGAH_PULSE_LEN_MAX, // pulse_1_len_max: maximum length of pulse with bit value 1 + SAMSUNGAH_1_PAUSE_LEN_MIN, // pause_1_len_min: minimum length of pause with bit value 1 + SAMSUNGAH_1_PAUSE_LEN_MAX, // pause_1_len_max: maximum length of pause with bit value 1 + SAMSUNGAH_PULSE_LEN_MIN, // pulse_0_len_min: minimum length of pulse with bit value 0 + SAMSUNGAH_PULSE_LEN_MAX, // pulse_0_len_max: maximum length of pulse with bit value 0 + SAMSUNGAH_0_PAUSE_LEN_MIN, // pause_0_len_min: minimum length of pause with bit value 0 + SAMSUNGAH_0_PAUSE_LEN_MAX, // pause_0_len_max: maximum length of pause with bit value 0 + SAMSUNGAH_ADDRESS_OFFSET, // address_offset: address offset + SAMSUNGAH_ADDRESS_OFFSET + SAMSUNGAH_ADDRESS_LEN, // address_end: end of address + SAMSUNGAH_COMMAND_OFFSET, // command_offset: command offset + SAMSUNGAH_COMMAND_OFFSET + SAMSUNGAH_COMMAND_LEN, // command_end: end of command + SAMSUNGAH_COMPLETE_DATA_LEN, // complete_len: complete length of frame + SAMSUNGAH_STOP_BIT, // stop_bit: flag: frame has stop bit + SAMSUNGAH_LSB, // lsb_first: flag: LSB first + SAMSUNGAH_FLAGS // flags: some flags +}; + +#endif + +#if IRMP_SUPPORT_TELEFUNKEN_PROTOCOL == 1 + +static const PROGMEM IRMP_PARAMETER telefunken_param = +{ + IRMP_TELEFUNKEN_PROTOCOL, // protocol: ir protocol + TELEFUNKEN_PULSE_LEN_MIN, // pulse_1_len_min: minimum length of pulse with bit value 1 + TELEFUNKEN_PULSE_LEN_MAX, // pulse_1_len_max: maximum length of pulse with bit value 1 + TELEFUNKEN_1_PAUSE_LEN_MIN, // pause_1_len_min: minimum length of pause with bit value 1 + TELEFUNKEN_1_PAUSE_LEN_MAX, // pause_1_len_max: maximum length of pause with bit value 1 + TELEFUNKEN_PULSE_LEN_MIN, // pulse_0_len_min: minimum length of pulse with bit value 0 + TELEFUNKEN_PULSE_LEN_MAX, // pulse_0_len_max: maximum length of pulse with bit value 0 + TELEFUNKEN_0_PAUSE_LEN_MIN, // pause_0_len_min: minimum length of pause with bit value 0 + TELEFUNKEN_0_PAUSE_LEN_MAX, // pause_0_len_max: maximum length of pause with bit value 0 + TELEFUNKEN_ADDRESS_OFFSET, // address_offset: address offset + TELEFUNKEN_ADDRESS_OFFSET + TELEFUNKEN_ADDRESS_LEN, // address_end: end of address + TELEFUNKEN_COMMAND_OFFSET, // command_offset: command offset + TELEFUNKEN_COMMAND_OFFSET + TELEFUNKEN_COMMAND_LEN, // command_end: end of command + TELEFUNKEN_COMPLETE_DATA_LEN, // complete_len: complete length of frame + TELEFUNKEN_STOP_BIT, // stop_bit: flag: frame has stop bit + TELEFUNKEN_LSB, // lsb_first: flag: LSB first + TELEFUNKEN_FLAGS // flags: some flags +}; + +#endif + +#if IRMP_SUPPORT_MATSUSHITA_PROTOCOL == 1 + +static const PROGMEM IRMP_PARAMETER matsushita_param = +{ + IRMP_MATSUSHITA_PROTOCOL, // protocol: ir protocol + MATSUSHITA_PULSE_LEN_MIN, // pulse_1_len_min: minimum length of pulse with bit value 1 + MATSUSHITA_PULSE_LEN_MAX, // pulse_1_len_max: maximum length of pulse with bit value 1 + MATSUSHITA_1_PAUSE_LEN_MIN, // pause_1_len_min: minimum length of pause with bit value 1 + MATSUSHITA_1_PAUSE_LEN_MAX, // pause_1_len_max: maximum length of pause with bit value 1 + MATSUSHITA_PULSE_LEN_MIN, // pulse_0_len_min: minimum length of pulse with bit value 0 + MATSUSHITA_PULSE_LEN_MAX, // pulse_0_len_max: maximum length of pulse with bit value 0 + MATSUSHITA_0_PAUSE_LEN_MIN, // pause_0_len_min: minimum length of pause with bit value 0 + MATSUSHITA_0_PAUSE_LEN_MAX, // pause_0_len_max: maximum length of pause with bit value 0 + MATSUSHITA_ADDRESS_OFFSET, // address_offset: address offset + MATSUSHITA_ADDRESS_OFFSET + MATSUSHITA_ADDRESS_LEN, // address_end: end of address + MATSUSHITA_COMMAND_OFFSET, // command_offset: command offset + MATSUSHITA_COMMAND_OFFSET + MATSUSHITA_COMMAND_LEN, // command_end: end of command + MATSUSHITA_COMPLETE_DATA_LEN, // complete_len: complete length of frame + MATSUSHITA_STOP_BIT, // stop_bit: flag: frame has stop bit + MATSUSHITA_LSB, // lsb_first: flag: LSB first + MATSUSHITA_FLAGS // flags: some flags +}; + +#endif + +#if IRMP_SUPPORT_KASEIKYO_PROTOCOL == 1 + +static const PROGMEM IRMP_PARAMETER kaseikyo_param = +{ + IRMP_KASEIKYO_PROTOCOL, // protocol: ir protocol + KASEIKYO_PULSE_LEN_MIN, // pulse_1_len_min: minimum length of pulse with bit value 1 + KASEIKYO_PULSE_LEN_MAX, // pulse_1_len_max: maximum length of pulse with bit value 1 + KASEIKYO_1_PAUSE_LEN_MIN, // pause_1_len_min: minimum length of pause with bit value 1 + KASEIKYO_1_PAUSE_LEN_MAX, // pause_1_len_max: maximum length of pause with bit value 1 + KASEIKYO_PULSE_LEN_MIN, // pulse_0_len_min: minimum length of pulse with bit value 0 + KASEIKYO_PULSE_LEN_MAX, // pulse_0_len_max: maximum length of pulse with bit value 0 + KASEIKYO_0_PAUSE_LEN_MIN, // pause_0_len_min: minimum length of pause with bit value 0 + KASEIKYO_0_PAUSE_LEN_MAX, // pause_0_len_max: maximum length of pause with bit value 0 + KASEIKYO_ADDRESS_OFFSET, // address_offset: address offset + KASEIKYO_ADDRESS_OFFSET + KASEIKYO_ADDRESS_LEN, // address_end: end of address + KASEIKYO_COMMAND_OFFSET, // command_offset: command offset + KASEIKYO_COMMAND_OFFSET + KASEIKYO_COMMAND_LEN, // command_end: end of command + KASEIKYO_COMPLETE_DATA_LEN, // complete_len: complete length of frame + KASEIKYO_STOP_BIT, // stop_bit: flag: frame has stop bit + KASEIKYO_LSB, // lsb_first: flag: LSB first + KASEIKYO_FLAGS // flags: some flags +}; + +#endif + +#if IRMP_SUPPORT_PANASONIC_PROTOCOL == 1 + +static const PROGMEM IRMP_PARAMETER panasonic_param = +{ + IRMP_PANASONIC_PROTOCOL, // protocol: ir protocol + PANASONIC_PULSE_LEN_MIN, // pulse_1_len_min: minimum length of pulse with bit value 1 + PANASONIC_PULSE_LEN_MAX, // pulse_1_len_max: maximum length of pulse with bit value 1 + PANASONIC_1_PAUSE_LEN_MIN, // pause_1_len_min: minimum length of pause with bit value 1 + PANASONIC_1_PAUSE_LEN_MAX, // pause_1_len_max: maximum length of pause with bit value 1 + PANASONIC_PULSE_LEN_MIN, // pulse_0_len_min: minimum length of pulse with bit value 0 + PANASONIC_PULSE_LEN_MAX, // pulse_0_len_max: maximum length of pulse with bit value 0 + PANASONIC_0_PAUSE_LEN_MIN, // pause_0_len_min: minimum length of pause with bit value 0 + PANASONIC_0_PAUSE_LEN_MAX, // pause_0_len_max: maximum length of pause with bit value 0 + PANASONIC_ADDRESS_OFFSET, // address_offset: address offset + PANASONIC_ADDRESS_OFFSET + PANASONIC_ADDRESS_LEN, // address_end: end of address + PANASONIC_COMMAND_OFFSET, // command_offset: command offset + PANASONIC_COMMAND_OFFSET + PANASONIC_COMMAND_LEN, // command_end: end of command + PANASONIC_COMPLETE_DATA_LEN, // complete_len: complete length of frame + PANASONIC_STOP_BIT, // stop_bit: flag: frame has stop bit + PANASONIC_LSB, // lsb_first: flag: LSB first + PANASONIC_FLAGS // flags: some flags +}; + +#endif + +#if IRMP_SUPPORT_MITSU_HEAVY_PROTOCOL == 1 + +static const PROGMEM IRMP_PARAMETER mitsu_heavy_param = +{ + IRMP_MITSU_HEAVY_PROTOCOL, // protocol: ir protocol + MITSU_HEAVY_PULSE_LEN_MIN, // pulse_1_len_min: minimum length of pulse with bit value 1 + MITSU_HEAVY_PULSE_LEN_MAX, // pulse_1_len_max: maximum length of pulse with bit value 1 + MITSU_HEAVY_1_PAUSE_LEN_MIN, // pause_1_len_min: minimum length of pause with bit value 1 + MITSU_HEAVY_1_PAUSE_LEN_MAX, // pause_1_len_max: maximum length of pause with bit value 1 + MITSU_HEAVY_PULSE_LEN_MIN, // pulse_0_len_min: minimum length of pulse with bit value 0 + MITSU_HEAVY_PULSE_LEN_MAX, // pulse_0_len_max: maximum length of pulse with bit value 0 + MITSU_HEAVY_0_PAUSE_LEN_MIN, // pause_0_len_min: minimum length of pause with bit value 0 + MITSU_HEAVY_0_PAUSE_LEN_MAX, // pause_0_len_max: maximum length of pause with bit value 0 + MITSU_HEAVY_ADDRESS_OFFSET, // address_offset: address offset + MITSU_HEAVY_ADDRESS_OFFSET + MITSU_HEAVY_ADDRESS_LEN, // address_end: end of address + MITSU_HEAVY_COMMAND_OFFSET, // command_offset: command offset + MITSU_HEAVY_COMMAND_OFFSET + MITSU_HEAVY_COMMAND_LEN, // command_end: end of command + MITSU_HEAVY_COMPLETE_DATA_LEN, // complete_len: complete length of frame + MITSU_HEAVY_STOP_BIT, // stop_bit: flag: frame has stop bit + MITSU_HEAVY_LSB, // lsb_first: flag: LSB first + MITSU_HEAVY_FLAGS // flags: some flags +}; + +#endif + +#if IRMP_SUPPORT_VINCENT_PROTOCOL == 1 + +static const PROGMEM IRMP_PARAMETER vincent_param = +{ + IRMP_VINCENT_PROTOCOL, // protocol: ir protocol + VINCENT_PULSE_LEN_MIN, // pulse_1_len_min: minimum length of pulse with bit value 1 + VINCENT_PULSE_LEN_MAX, // pulse_1_len_max: maximum length of pulse with bit value 1 + VINCENT_1_PAUSE_LEN_MIN, // pause_1_len_min: minimum length of pause with bit value 1 + VINCENT_1_PAUSE_LEN_MAX, // pause_1_len_max: maximum length of pause with bit value 1 + VINCENT_PULSE_LEN_MIN, // pulse_0_len_min: minimum length of pulse with bit value 0 + VINCENT_PULSE_LEN_MAX, // pulse_0_len_max: maximum length of pulse with bit value 0 + VINCENT_0_PAUSE_LEN_MIN, // pause_0_len_min: minimum length of pause with bit value 0 + VINCENT_0_PAUSE_LEN_MAX, // pause_0_len_max: maximum length of pause with bit value 0 + VINCENT_ADDRESS_OFFSET, // address_offset: address offset + VINCENT_ADDRESS_OFFSET + VINCENT_ADDRESS_LEN, // address_end: end of address + VINCENT_COMMAND_OFFSET, // command_offset: command offset + VINCENT_COMMAND_OFFSET + VINCENT_COMMAND_LEN, // command_end: end of command + VINCENT_COMPLETE_DATA_LEN, // complete_len: complete length of frame + VINCENT_STOP_BIT, // stop_bit: flag: frame has stop bit + VINCENT_LSB, // lsb_first: flag: LSB first + VINCENT_FLAGS // flags: some flags +}; + +#endif + +#if IRMP_SUPPORT_RECS80_PROTOCOL == 1 + +static const PROGMEM IRMP_PARAMETER recs80_param = +{ + IRMP_RECS80_PROTOCOL, // protocol: ir protocol + RECS80_PULSE_LEN_MIN, // pulse_1_len_min: minimum length of pulse with bit value 1 + RECS80_PULSE_LEN_MAX, // pulse_1_len_max: maximum length of pulse with bit value 1 + RECS80_1_PAUSE_LEN_MIN, // pause_1_len_min: minimum length of pause with bit value 1 + RECS80_1_PAUSE_LEN_MAX, // pause_1_len_max: maximum length of pause with bit value 1 + RECS80_PULSE_LEN_MIN, // pulse_0_len_min: minimum length of pulse with bit value 0 + RECS80_PULSE_LEN_MAX, // pulse_0_len_max: maximum length of pulse with bit value 0 + RECS80_0_PAUSE_LEN_MIN, // pause_0_len_min: minimum length of pause with bit value 0 + RECS80_0_PAUSE_LEN_MAX, // pause_0_len_max: maximum length of pause with bit value 0 + RECS80_ADDRESS_OFFSET, // address_offset: address offset + RECS80_ADDRESS_OFFSET + RECS80_ADDRESS_LEN, // address_end: end of address + RECS80_COMMAND_OFFSET, // command_offset: command offset + RECS80_COMMAND_OFFSET + RECS80_COMMAND_LEN, // command_end: end of command + RECS80_COMPLETE_DATA_LEN, // complete_len: complete length of frame + RECS80_STOP_BIT, // stop_bit: flag: frame has stop bit + RECS80_LSB, // lsb_first: flag: LSB first + RECS80_FLAGS // flags: some flags +}; + +#endif + +#if IRMP_SUPPORT_RC5_PROTOCOL == 1 + +static const PROGMEM IRMP_PARAMETER rc5_param = +{ + IRMP_RC5_PROTOCOL, // protocol: ir protocol + RC5_BIT_LEN_MIN, // pulse_1_len_min: here: minimum length of short pulse + RC5_BIT_LEN_MAX, // pulse_1_len_max: here: maximum length of short pulse + RC5_BIT_LEN_MIN, // pause_1_len_min: here: minimum length of short pause + RC5_BIT_LEN_MAX, // pause_1_len_max: here: maximum length of short pause + 0, // pulse_0_len_min: here: not used + 0, // pulse_0_len_max: here: not used + 0, // pause_0_len_min: here: not used + 0, // pause_0_len_max: here: not used + RC5_ADDRESS_OFFSET, // address_offset: address offset + RC5_ADDRESS_OFFSET + RC5_ADDRESS_LEN, // address_end: end of address + RC5_COMMAND_OFFSET, // command_offset: command offset + RC5_COMMAND_OFFSET + RC5_COMMAND_LEN, // command_end: end of command + RC5_COMPLETE_DATA_LEN, // complete_len: complete length of frame + RC5_STOP_BIT, // stop_bit: flag: frame has stop bit + RC5_LSB, // lsb_first: flag: LSB first + RC5_FLAGS // flags: some flags +}; + +#endif + +#if IRMP_SUPPORT_RCII_PROTOCOL == 1 + +static const PROGMEM IRMP_PARAMETER rcii_param = +{ + IRMP_RCII_PROTOCOL, // protocol: ir protocol + RCII_BIT_LEN_MIN, // pulse_1_len_min: here: minimum length of short pulse + RCII_BIT_LEN_MAX, // pulse_1_len_max: here: maximum length of short pulse + RCII_BIT_LEN_MIN, // pause_1_len_min: here: minimum length of short pause + RCII_BIT_LEN_MAX, // pause_1_len_max: here: maximum length of short pause + RCII_BIT_LEN_MIN, // pulse_0_len_min: here: not used + RCII_BIT_LEN_MAX, // pulse_0_len_max: here: not used + RCII_BIT_LEN_MIN, // pause_0_len_min: here: not used + RCII_BIT_LEN_MAX, // pause_0_len_max: here: not used + RCII_ADDRESS_OFFSET, // address_offset: address offset + RCII_ADDRESS_OFFSET + RCII_ADDRESS_LEN, // address_end: end of address + RCII_COMMAND_OFFSET, // command_offset: command offset + RCII_COMMAND_OFFSET + RCII_COMMAND_LEN, // command_end: end of command + RCII_COMPLETE_DATA_LEN, // complete_len: complete length of frame + RCII_STOP_BIT, // stop_bit: flag: frame has stop bit + RCII_LSB, // lsb_first: flag: LSB first + RCII_FLAGS // flags: some flags +}; + +#endif + +#if IRMP_SUPPORT_S100_PROTOCOL == 1 + +static const PROGMEM IRMP_PARAMETER s100_param = +{ + IRMP_S100_PROTOCOL, // protocol: ir protocol + S100_BIT_LEN_MIN, // pulse_1_len_min: here: minimum length of short pulse + S100_BIT_LEN_MAX, // pulse_1_len_max: here: maximum length of short pulse + S100_BIT_LEN_MIN, // pause_1_len_min: here: minimum length of short pause + S100_BIT_LEN_MAX, // pause_1_len_max: here: maximum length of short pause + 0, // pulse_0_len_min: here: not used + 0, // pulse_0_len_max: here: not used + 0, // pause_0_len_min: here: not used + 0, // pause_0_len_max: here: not used + S100_ADDRESS_OFFSET, // address_offset: address offset + S100_ADDRESS_OFFSET + S100_ADDRESS_LEN, // address_end: end of address + S100_COMMAND_OFFSET, // command_offset: command offset + S100_COMMAND_OFFSET + S100_COMMAND_LEN, // command_end: end of command + S100_COMPLETE_DATA_LEN, // complete_len: complete length of frame + S100_STOP_BIT, // stop_bit: flag: frame has stop bit + S100_LSB, // lsb_first: flag: LSB first + S100_FLAGS // flags: some flags +}; + +#endif + +#if IRMP_SUPPORT_DENON_PROTOCOL == 1 + +static const PROGMEM IRMP_PARAMETER denon_param = +{ + IRMP_DENON_PROTOCOL, // protocol: ir protocol + DENON_PULSE_LEN_MIN, // pulse_1_len_min: minimum length of pulse with bit value 1 + DENON_PULSE_LEN_MAX, // pulse_1_len_max: maximum length of pulse with bit value 1 + DENON_1_PAUSE_LEN_MIN, // pause_1_len_min: minimum length of pause with bit value 1 + DENON_1_PAUSE_LEN_MAX, // pause_1_len_max: maximum length of pause with bit value 1 + DENON_PULSE_LEN_MIN, // pulse_0_len_min: minimum length of pulse with bit value 0 + DENON_PULSE_LEN_MAX, // pulse_0_len_max: maximum length of pulse with bit value 0 + DENON_0_PAUSE_LEN_MIN, // pause_0_len_min: minimum length of pause with bit value 0 + DENON_0_PAUSE_LEN_MAX, // pause_0_len_max: maximum length of pause with bit value 0 + DENON_ADDRESS_OFFSET, // address_offset: address offset + DENON_ADDRESS_OFFSET + DENON_ADDRESS_LEN, // address_end: end of address + DENON_COMMAND_OFFSET, // command_offset: command offset + DENON_COMMAND_OFFSET + DENON_COMMAND_LEN, // command_end: end of command + DENON_COMPLETE_DATA_LEN, // complete_len: complete length of frame + DENON_STOP_BIT, // stop_bit: flag: frame has stop bit + DENON_LSB, // lsb_first: flag: LSB first + DENON_FLAGS // flags: some flags +}; + +#endif + +#if IRMP_SUPPORT_RC6_PROTOCOL == 1 + +static const PROGMEM IRMP_PARAMETER rc6_param = +{ + IRMP_RC6_PROTOCOL, // protocol: ir protocol + + RC6_BIT_PULSE_LEN_MIN, // pulse_1_len_min: here: minimum length of short pulse + RC6_BIT_PULSE_LEN_MAX, // pulse_1_len_max: here: maximum length of short pulse + RC6_BIT_PAUSE_LEN_MIN, // pause_1_len_min: here: minimum length of short pause + RC6_BIT_PAUSE_LEN_MAX, // pause_1_len_max: here: maximum length of short pause + 0, // pulse_0_len_min: here: not used + 0, // pulse_0_len_max: here: not used + 0, // pause_0_len_min: here: not used + 0, // pause_0_len_max: here: not used + RC6_ADDRESS_OFFSET, // address_offset: address offset + RC6_ADDRESS_OFFSET + RC6_ADDRESS_LEN, // address_end: end of address + RC6_COMMAND_OFFSET, // command_offset: command offset + RC6_COMMAND_OFFSET + RC6_COMMAND_LEN, // command_end: end of command + RC6_COMPLETE_DATA_LEN_SHORT, // complete_len: complete length of frame + RC6_STOP_BIT, // stop_bit: flag: frame has stop bit + RC6_LSB, // lsb_first: flag: LSB first + RC6_FLAGS // flags: some flags +}; + +#endif + +#if IRMP_SUPPORT_RECS80EXT_PROTOCOL == 1 + +static const PROGMEM IRMP_PARAMETER recs80ext_param = +{ + IRMP_RECS80EXT_PROTOCOL, // protocol: ir protocol + RECS80EXT_PULSE_LEN_MIN, // pulse_1_len_min: minimum length of pulse with bit value 1 + RECS80EXT_PULSE_LEN_MAX, // pulse_1_len_max: maximum length of pulse with bit value 1 + RECS80EXT_1_PAUSE_LEN_MIN, // pause_1_len_min: minimum length of pause with bit value 1 + RECS80EXT_1_PAUSE_LEN_MAX, // pause_1_len_max: maximum length of pause with bit value 1 + RECS80EXT_PULSE_LEN_MIN, // pulse_0_len_min: minimum length of pulse with bit value 0 + RECS80EXT_PULSE_LEN_MAX, // pulse_0_len_max: maximum length of pulse with bit value 0 + RECS80EXT_0_PAUSE_LEN_MIN, // pause_0_len_min: minimum length of pause with bit value 0 + RECS80EXT_0_PAUSE_LEN_MAX, // pause_0_len_max: maximum length of pause with bit value 0 + RECS80EXT_ADDRESS_OFFSET, // address_offset: address offset + RECS80EXT_ADDRESS_OFFSET + RECS80EXT_ADDRESS_LEN, // address_end: end of address + RECS80EXT_COMMAND_OFFSET, // command_offset: command offset + RECS80EXT_COMMAND_OFFSET + RECS80EXT_COMMAND_LEN, // command_end: end of command + RECS80EXT_COMPLETE_DATA_LEN, // complete_len: complete length of frame + RECS80EXT_STOP_BIT, // stop_bit: flag: frame has stop bit + RECS80EXT_LSB, // lsb_first: flag: LSB first + RECS80EXT_FLAGS // flags: some flags +}; + +#endif + +#if IRMP_SUPPORT_NUBERT_PROTOCOL == 1 + +static const PROGMEM IRMP_PARAMETER nubert_param = +{ + IRMP_NUBERT_PROTOCOL, // protocol: ir protocol + NUBERT_1_PULSE_LEN_MIN, // pulse_1_len_min: minimum length of pulse with bit value 1 + NUBERT_1_PULSE_LEN_MAX, // pulse_1_len_max: maximum length of pulse with bit value 1 + NUBERT_1_PAUSE_LEN_MIN, // pause_1_len_min: minimum length of pause with bit value 1 + NUBERT_1_PAUSE_LEN_MAX, // pause_1_len_max: maximum length of pause with bit value 1 + NUBERT_0_PULSE_LEN_MIN, // pulse_0_len_min: minimum length of pulse with bit value 0 + NUBERT_0_PULSE_LEN_MAX, // pulse_0_len_max: maximum length of pulse with bit value 0 + NUBERT_0_PAUSE_LEN_MIN, // pause_0_len_min: minimum length of pause with bit value 0 + NUBERT_0_PAUSE_LEN_MAX, // pause_0_len_max: maximum length of pause with bit value 0 + NUBERT_ADDRESS_OFFSET, // address_offset: address offset + NUBERT_ADDRESS_OFFSET + NUBERT_ADDRESS_LEN, // address_end: end of address + NUBERT_COMMAND_OFFSET, // command_offset: command offset + NUBERT_COMMAND_OFFSET + NUBERT_COMMAND_LEN, // command_end: end of command + NUBERT_COMPLETE_DATA_LEN, // complete_len: complete length of frame + NUBERT_STOP_BIT, // stop_bit: flag: frame has stop bit + NUBERT_LSB, // lsb_first: flag: LSB first + NUBERT_FLAGS // flags: some flags +}; + +#endif + +#if IRMP_SUPPORT_FAN_PROTOCOL == 1 + +static const PROGMEM IRMP_PARAMETER fan_param = +{ + IRMP_FAN_PROTOCOL, // protocol: ir protocol + FAN_1_PULSE_LEN_MIN, // pulse_1_len_min: minimum length of pulse with bit value 1 + FAN_1_PULSE_LEN_MAX, // pulse_1_len_max: maximum length of pulse with bit value 1 + FAN_1_PAUSE_LEN_MIN, // pause_1_len_min: minimum length of pause with bit value 1 + FAN_1_PAUSE_LEN_MAX, // pause_1_len_max: maximum length of pause with bit value 1 + FAN_0_PULSE_LEN_MIN, // pulse_0_len_min: minimum length of pulse with bit value 0 + FAN_0_PULSE_LEN_MAX, // pulse_0_len_max: maximum length of pulse with bit value 0 + FAN_0_PAUSE_LEN_MIN, // pause_0_len_min: minimum length of pause with bit value 0 + FAN_0_PAUSE_LEN_MAX, // pause_0_len_max: maximum length of pause with bit value 0 + FAN_ADDRESS_OFFSET, // address_offset: address offset + FAN_ADDRESS_OFFSET + FAN_ADDRESS_LEN, // address_end: end of address + FAN_COMMAND_OFFSET, // command_offset: command offset + FAN_COMMAND_OFFSET + FAN_COMMAND_LEN, // command_end: end of command + FAN_COMPLETE_DATA_LEN, // complete_len: complete length of frame + FAN_STOP_BIT, // stop_bit: flag: frame has NO stop bit + FAN_LSB, // lsb_first: flag: LSB first + FAN_FLAGS // flags: some flags +}; + +#endif + +#if IRMP_SUPPORT_SPEAKER_PROTOCOL == 1 + +static const PROGMEM IRMP_PARAMETER speaker_param = +{ + IRMP_SPEAKER_PROTOCOL, // protocol: ir protocol + SPEAKER_1_PULSE_LEN_MIN, // pulse_1_len_min: minimum length of pulse with bit value 1 + SPEAKER_1_PULSE_LEN_MAX, // pulse_1_len_max: maximum length of pulse with bit value 1 + SPEAKER_1_PAUSE_LEN_MIN, // pause_1_len_min: minimum length of pause with bit value 1 + SPEAKER_1_PAUSE_LEN_MAX, // pause_1_len_max: maximum length of pause with bit value 1 + SPEAKER_0_PULSE_LEN_MIN, // pulse_0_len_min: minimum length of pulse with bit value 0 + SPEAKER_0_PULSE_LEN_MAX, // pulse_0_len_max: maximum length of pulse with bit value 0 + SPEAKER_0_PAUSE_LEN_MIN, // pause_0_len_min: minimum length of pause with bit value 0 + SPEAKER_0_PAUSE_LEN_MAX, // pause_0_len_max: maximum length of pause with bit value 0 + SPEAKER_ADDRESS_OFFSET, // address_offset: address offset + SPEAKER_ADDRESS_OFFSET + SPEAKER_ADDRESS_LEN, // address_end: end of address + SPEAKER_COMMAND_OFFSET, // command_offset: command offset + SPEAKER_COMMAND_OFFSET + SPEAKER_COMMAND_LEN, // command_end: end of command + SPEAKER_COMPLETE_DATA_LEN, // complete_len: complete length of frame + SPEAKER_STOP_BIT, // stop_bit: flag: frame has stop bit + SPEAKER_LSB, // lsb_first: flag: LSB first + SPEAKER_FLAGS // flags: some flags +}; + +#endif + +#if IRMP_SUPPORT_BANG_OLUFSEN_PROTOCOL == 1 + +static const PROGMEM IRMP_PARAMETER bang_olufsen_param = +{ + IRMP_BANG_OLUFSEN_PROTOCOL, // protocol: ir protocol + BANG_OLUFSEN_PULSE_LEN_MIN, // pulse_1_len_min: minimum length of pulse with bit value 1 + BANG_OLUFSEN_PULSE_LEN_MAX, // pulse_1_len_max: maximum length of pulse with bit value 1 + BANG_OLUFSEN_1_PAUSE_LEN_MIN, // pause_1_len_min: minimum length of pause with bit value 1 + BANG_OLUFSEN_1_PAUSE_LEN_MAX, // pause_1_len_max: maximum length of pause with bit value 1 + BANG_OLUFSEN_PULSE_LEN_MIN, // pulse_0_len_min: minimum length of pulse with bit value 0 + BANG_OLUFSEN_PULSE_LEN_MAX, // pulse_0_len_max: maximum length of pulse with bit value 0 + BANG_OLUFSEN_0_PAUSE_LEN_MIN, // pause_0_len_min: minimum length of pause with bit value 0 + BANG_OLUFSEN_0_PAUSE_LEN_MAX, // pause_0_len_max: maximum length of pause with bit value 0 + BANG_OLUFSEN_ADDRESS_OFFSET, // address_offset: address offset + BANG_OLUFSEN_ADDRESS_OFFSET + BANG_OLUFSEN_ADDRESS_LEN, // address_end: end of address + BANG_OLUFSEN_COMMAND_OFFSET, // command_offset: command offset + BANG_OLUFSEN_COMMAND_OFFSET + BANG_OLUFSEN_COMMAND_LEN, // command_end: end of command + BANG_OLUFSEN_COMPLETE_DATA_LEN, // complete_len: complete length of frame + BANG_OLUFSEN_STOP_BIT, // stop_bit: flag: frame has stop bit + BANG_OLUFSEN_LSB, // lsb_first: flag: LSB first + BANG_OLUFSEN_FLAGS // flags: some flags +}; + +#endif + +#if IRMP_SUPPORT_GRUNDIG_NOKIA_IR60_PROTOCOL == 1 + +static uint_fast8_t first_bit; + +static const PROGMEM IRMP_PARAMETER grundig_param = +{ + IRMP_GRUNDIG_PROTOCOL, // protocol: ir protocol + + GRUNDIG_NOKIA_IR60_BIT_LEN_MIN, // pulse_1_len_min: here: minimum length of short pulse + GRUNDIG_NOKIA_IR60_BIT_LEN_MAX, // pulse_1_len_max: here: maximum length of short pulse + GRUNDIG_NOKIA_IR60_BIT_LEN_MIN, // pause_1_len_min: here: minimum length of short pause + GRUNDIG_NOKIA_IR60_BIT_LEN_MAX, // pause_1_len_max: here: maximum length of short pause + 0, // pulse_0_len_min: here: not used + 0, // pulse_0_len_max: here: not used + 0, // pause_0_len_min: here: not used + 0, // pause_0_len_max: here: not used + GRUNDIG_ADDRESS_OFFSET, // address_offset: address offset + GRUNDIG_ADDRESS_OFFSET + GRUNDIG_ADDRESS_LEN, // address_end: end of address + GRUNDIG_COMMAND_OFFSET, // command_offset: command offset + GRUNDIG_COMMAND_OFFSET + GRUNDIG_COMMAND_LEN + 1, // command_end: end of command (USE 1 bit MORE to STORE NOKIA DATA!) + NOKIA_COMPLETE_DATA_LEN, // complete_len: complete length of frame, here: NOKIA instead of GRUNDIG! + GRUNDIG_NOKIA_IR60_STOP_BIT, // stop_bit: flag: frame has stop bit + GRUNDIG_NOKIA_IR60_LSB, // lsb_first: flag: LSB first + GRUNDIG_NOKIA_IR60_FLAGS // flags: some flags +}; + +#endif + +#if IRMP_SUPPORT_SIEMENS_OR_RUWIDO_PROTOCOL == 1 + +static const PROGMEM IRMP_PARAMETER ruwido_param = +{ + IRMP_RUWIDO_PROTOCOL, // protocol: ir protocol + SIEMENS_OR_RUWIDO_BIT_PULSE_LEN_MIN, // pulse_1_len_min: here: minimum length of short pulse + SIEMENS_OR_RUWIDO_BIT_PULSE_LEN_MAX, // pulse_1_len_max: here: maximum length of short pulse + SIEMENS_OR_RUWIDO_BIT_PAUSE_LEN_MIN, // pause_1_len_min: here: minimum length of short pause + SIEMENS_OR_RUWIDO_BIT_PAUSE_LEN_MAX, // pause_1_len_max: here: maximum length of short pause + 0, // pulse_0_len_min: here: not used + 0, // pulse_0_len_max: here: not used + 0, // pause_0_len_min: here: not used + 0, // pause_0_len_max: here: not used + RUWIDO_ADDRESS_OFFSET, // address_offset: address offset + RUWIDO_ADDRESS_OFFSET + RUWIDO_ADDRESS_LEN, // address_end: end of address + RUWIDO_COMMAND_OFFSET, // command_offset: command offset + RUWIDO_COMMAND_OFFSET + RUWIDO_COMMAND_LEN, // command_end: end of command + SIEMENS_COMPLETE_DATA_LEN, // complete_len: complete length of frame, here: SIEMENS instead of RUWIDO! + SIEMENS_OR_RUWIDO_STOP_BIT, // stop_bit: flag: frame has stop bit + SIEMENS_OR_RUWIDO_LSB, // lsb_first: flag: LSB first + SIEMENS_OR_RUWIDO_FLAGS // flags: some flags +}; + +#endif + +#if IRMP_SUPPORT_FDC_PROTOCOL == 1 + +static const PROGMEM IRMP_PARAMETER fdc_param = +{ + IRMP_FDC_PROTOCOL, // protocol: ir protocol + FDC_PULSE_LEN_MIN, // pulse_1_len_min: minimum length of pulse with bit value 1 + FDC_PULSE_LEN_MAX, // pulse_1_len_max: maximum length of pulse with bit value 1 + FDC_1_PAUSE_LEN_MIN, // pause_1_len_min: minimum length of pause with bit value 1 + FDC_1_PAUSE_LEN_MAX, // pause_1_len_max: maximum length of pause with bit value 1 + FDC_PULSE_LEN_MIN, // pulse_0_len_min: minimum length of pulse with bit value 0 + FDC_PULSE_LEN_MAX, // pulse_0_len_max: maximum length of pulse with bit value 0 + FDC_0_PAUSE_LEN_MIN, // pause_0_len_min: minimum length of pause with bit value 0 + FDC_0_PAUSE_LEN_MAX, // pause_0_len_max: maximum length of pause with bit value 0 + FDC_ADDRESS_OFFSET, // address_offset: address offset + FDC_ADDRESS_OFFSET + FDC_ADDRESS_LEN, // address_end: end of address + FDC_COMMAND_OFFSET, // command_offset: command offset + FDC_COMMAND_OFFSET + FDC_COMMAND_LEN, // command_end: end of command + FDC_COMPLETE_DATA_LEN, // complete_len: complete length of frame + FDC_STOP_BIT, // stop_bit: flag: frame has stop bit + FDC_LSB, // lsb_first: flag: LSB first + FDC_FLAGS // flags: some flags +}; + +#endif + +#if IRMP_SUPPORT_RCCAR_PROTOCOL == 1 + +static const PROGMEM IRMP_PARAMETER rccar_param = +{ + IRMP_RCCAR_PROTOCOL, // protocol: ir protocol + RCCAR_PULSE_LEN_MIN, // pulse_1_len_min: minimum length of pulse with bit value 1 + RCCAR_PULSE_LEN_MAX, // pulse_1_len_max: maximum length of pulse with bit value 1 + RCCAR_1_PAUSE_LEN_MIN, // pause_1_len_min: minimum length of pause with bit value 1 + RCCAR_1_PAUSE_LEN_MAX, // pause_1_len_max: maximum length of pause with bit value 1 + RCCAR_PULSE_LEN_MIN, // pulse_0_len_min: minimum length of pulse with bit value 0 + RCCAR_PULSE_LEN_MAX, // pulse_0_len_max: maximum length of pulse with bit value 0 + RCCAR_0_PAUSE_LEN_MIN, // pause_0_len_min: minimum length of pause with bit value 0 + RCCAR_0_PAUSE_LEN_MAX, // pause_0_len_max: maximum length of pause with bit value 0 + RCCAR_ADDRESS_OFFSET, // address_offset: address offset + RCCAR_ADDRESS_OFFSET + RCCAR_ADDRESS_LEN, // address_end: end of address + RCCAR_COMMAND_OFFSET, // command_offset: command offset + RCCAR_COMMAND_OFFSET + RCCAR_COMMAND_LEN, // command_end: end of command + RCCAR_COMPLETE_DATA_LEN, // complete_len: complete length of frame + RCCAR_STOP_BIT, // stop_bit: flag: frame has stop bit + RCCAR_LSB, // lsb_first: flag: LSB first + RCCAR_FLAGS // flags: some flags +}; + +#endif + +#if IRMP_SUPPORT_NIKON_PROTOCOL == 1 + +static const PROGMEM IRMP_PARAMETER nikon_param = +{ + IRMP_NIKON_PROTOCOL, // protocol: ir protocol + NIKON_PULSE_LEN_MIN, // pulse_1_len_min: minimum length of pulse with bit value 1 + NIKON_PULSE_LEN_MAX, // pulse_1_len_max: maximum length of pulse with bit value 1 + NIKON_1_PAUSE_LEN_MIN, // pause_1_len_min: minimum length of pause with bit value 1 + NIKON_1_PAUSE_LEN_MAX, // pause_1_len_max: maximum length of pause with bit value 1 + NIKON_PULSE_LEN_MIN, // pulse_0_len_min: minimum length of pulse with bit value 0 + NIKON_PULSE_LEN_MAX, // pulse_0_len_max: maximum length of pulse with bit value 0 + NIKON_0_PAUSE_LEN_MIN, // pause_0_len_min: minimum length of pause with bit value 0 + NIKON_0_PAUSE_LEN_MAX, // pause_0_len_max: maximum length of pause with bit value 0 + NIKON_ADDRESS_OFFSET, // address_offset: address offset + NIKON_ADDRESS_OFFSET + NIKON_ADDRESS_LEN, // address_end: end of address + NIKON_COMMAND_OFFSET, // command_offset: command offset + NIKON_COMMAND_OFFSET + NIKON_COMMAND_LEN, // command_end: end of command + NIKON_COMPLETE_DATA_LEN, // complete_len: complete length of frame + NIKON_STOP_BIT, // stop_bit: flag: frame has stop bit + NIKON_LSB, // lsb_first: flag: LSB first + NIKON_FLAGS // flags: some flags +}; + +#endif + +#if IRMP_SUPPORT_KATHREIN_PROTOCOL == 1 + +static const PROGMEM IRMP_PARAMETER kathrein_param = +{ + IRMP_KATHREIN_PROTOCOL, // protocol: ir protocol + KATHREIN_1_PULSE_LEN_MIN, // pulse_1_len_min: minimum length of pulse with bit value 1 + KATHREIN_1_PULSE_LEN_MAX, // pulse_1_len_max: maximum length of pulse with bit value 1 + KATHREIN_1_PAUSE_LEN_MIN, // pause_1_len_min: minimum length of pause with bit value 1 + KATHREIN_1_PAUSE_LEN_MAX, // pause_1_len_max: maximum length of pause with bit value 1 + KATHREIN_0_PULSE_LEN_MIN, // pulse_0_len_min: minimum length of pulse with bit value 0 + KATHREIN_0_PULSE_LEN_MAX, // pulse_0_len_max: maximum length of pulse with bit value 0 + KATHREIN_0_PAUSE_LEN_MIN, // pause_0_len_min: minimum length of pause with bit value 0 + KATHREIN_0_PAUSE_LEN_MAX, // pause_0_len_max: maximum length of pause with bit value 0 + KATHREIN_ADDRESS_OFFSET, // address_offset: address offset + KATHREIN_ADDRESS_OFFSET + KATHREIN_ADDRESS_LEN, // address_end: end of address + KATHREIN_COMMAND_OFFSET, // command_offset: command offset + KATHREIN_COMMAND_OFFSET + KATHREIN_COMMAND_LEN, // command_end: end of command + KATHREIN_COMPLETE_DATA_LEN, // complete_len: complete length of frame + KATHREIN_STOP_BIT, // stop_bit: flag: frame has stop bit + KATHREIN_LSB, // lsb_first: flag: LSB first + KATHREIN_FLAGS // flags: some flags +}; + +#endif + +#if IRMP_SUPPORT_NETBOX_PROTOCOL == 1 + +static const PROGMEM IRMP_PARAMETER netbox_param = +{ + IRMP_NETBOX_PROTOCOL, // protocol: ir protocol + NETBOX_PULSE_LEN, // pulse_1_len_min: minimum length of pulse with bit value 1, here: exact value + NETBOX_PULSE_REST_LEN, // pulse_1_len_max: maximum length of pulse with bit value 1, here: rest value + NETBOX_PAUSE_LEN, // pause_1_len_min: minimum length of pause with bit value 1, here: exact value + NETBOX_PAUSE_REST_LEN, // pause_1_len_max: maximum length of pause with bit value 1, here: rest value + NETBOX_PULSE_LEN, // pulse_0_len_min: minimum length of pulse with bit value 0, here: exact value + NETBOX_PULSE_REST_LEN, // pulse_0_len_max: maximum length of pulse with bit value 0, here: rest value + NETBOX_PAUSE_LEN, // pause_0_len_min: minimum length of pause with bit value 0, here: exact value + NETBOX_PAUSE_REST_LEN, // pause_0_len_max: maximum length of pause with bit value 0, here: rest value + NETBOX_ADDRESS_OFFSET, // address_offset: address offset + NETBOX_ADDRESS_OFFSET + NETBOX_ADDRESS_LEN, // address_end: end of address + NETBOX_COMMAND_OFFSET, // command_offset: command offset + NETBOX_COMMAND_OFFSET + NETBOX_COMMAND_LEN, // command_end: end of command + NETBOX_COMPLETE_DATA_LEN, // complete_len: complete length of frame + NETBOX_STOP_BIT, // stop_bit: flag: frame has stop bit + NETBOX_LSB, // lsb_first: flag: LSB first + NETBOX_FLAGS // flags: some flags +}; + +#endif + +#if IRMP_SUPPORT_LEGO_PROTOCOL == 1 + +static const PROGMEM IRMP_PARAMETER lego_param = +{ + IRMP_LEGO_PROTOCOL, // protocol: ir protocol + LEGO_PULSE_LEN_MIN, // pulse_1_len_min: minimum length of pulse with bit value 1 + LEGO_PULSE_LEN_MAX, // pulse_1_len_max: maximum length of pulse with bit value 1 + LEGO_1_PAUSE_LEN_MIN, // pause_1_len_min: minimum length of pause with bit value 1 + LEGO_1_PAUSE_LEN_MAX, // pause_1_len_max: maximum length of pause with bit value 1 + LEGO_PULSE_LEN_MIN, // pulse_0_len_min: minimum length of pulse with bit value 0 + LEGO_PULSE_LEN_MAX, // pulse_0_len_max: maximum length of pulse with bit value 0 + LEGO_0_PAUSE_LEN_MIN, // pause_0_len_min: minimum length of pause with bit value 0 + LEGO_0_PAUSE_LEN_MAX, // pause_0_len_max: maximum length of pause with bit value 0 + LEGO_ADDRESS_OFFSET, // address_offset: address offset + LEGO_ADDRESS_OFFSET + LEGO_ADDRESS_LEN, // address_end: end of address + LEGO_COMMAND_OFFSET, // command_offset: command offset + LEGO_COMMAND_OFFSET + LEGO_COMMAND_LEN, // command_end: end of command + LEGO_COMPLETE_DATA_LEN, // complete_len: complete length of frame + LEGO_STOP_BIT, // stop_bit: flag: frame has stop bit + LEGO_LSB, // lsb_first: flag: LSB first + LEGO_FLAGS // flags: some flags +}; + +#endif + +#if IRMP_SUPPORT_IRMP16_PROTOCOL == 1 + +static const PROGMEM IRMP_PARAMETER irmp16_param = +{ + IRMP_IRMP16_PROTOCOL, // protocol: ir protocol + IRMP16_PULSE_LEN_MIN, // pulse_1_len_min: minimum length of pulse with bit value 1 + IRMP16_PULSE_LEN_MAX, // pulse_1_len_max: maximum length of pulse with bit value 1 + IRMP16_1_PAUSE_LEN_MIN, // pause_1_len_min: minimum length of pause with bit value 1 + IRMP16_1_PAUSE_LEN_MAX, // pause_1_len_max: maximum length of pause with bit value 1 + IRMP16_PULSE_LEN_MIN, // pulse_0_len_min: minimum length of pulse with bit value 0 + IRMP16_PULSE_LEN_MAX, // pulse_0_len_max: maximum length of pulse with bit value 0 + IRMP16_0_PAUSE_LEN_MIN, // pause_0_len_min: minimum length of pause with bit value 0 + IRMP16_0_PAUSE_LEN_MAX, // pause_0_len_max: maximum length of pause with bit value 0 + IRMP16_ADDRESS_OFFSET, // address_offset: address offset + IRMP16_ADDRESS_OFFSET + IRMP16_ADDRESS_LEN, // address_end: end of address + IRMP16_COMMAND_OFFSET, // command_offset: command offset + IRMP16_COMMAND_OFFSET + IRMP16_COMMAND_LEN, // command_end: end of command + IRMP16_COMPLETE_DATA_LEN, // complete_len: complete length of frame + IRMP16_STOP_BIT, // stop_bit: flag: frame has stop bit + IRMP16_LSB, // lsb_first: flag: LSB first + IRMP16_FLAGS // flags: some flags +}; + +#endif + +#if IRMP_SUPPORT_GREE_PROTOCOL == 1 + +static const PROGMEM IRMP_PARAMETER gree_param = +{ + IRMP_GREE_PROTOCOL, // protocol: ir protocol + GREE_PULSE_LEN_MIN, // pulse_1_len_min: minimum length of pulse with bit value 1 + GREE_PULSE_LEN_MAX, // pulse_1_len_max: maximum length of pulse with bit value 1 + GREE_1_PAUSE_LEN_MIN, // pause_1_len_min: minimum length of pause with bit value 1 + GREE_1_PAUSE_LEN_MAX, // pause_1_len_max: maximum length of pause with bit value 1 + GREE_PULSE_LEN_MIN, // pulse_0_len_min: minimum length of pulse with bit value 0 + GREE_PULSE_LEN_MAX, // pulse_0_len_max: maximum length of pulse with bit value 0 + GREE_0_PAUSE_LEN_MIN, // pause_0_len_min: minimum length of pause with bit value 0 + GREE_0_PAUSE_LEN_MAX, // pause_0_len_max: maximum length of pause with bit value 0 + GREE_ADDRESS_OFFSET, // address_offset: address offset + GREE_ADDRESS_OFFSET + GREE_ADDRESS_LEN, // address_end: end of address + GREE_COMMAND_OFFSET, // command_offset: command offset + GREE_COMMAND_OFFSET + GREE_COMMAND_LEN, // command_end: end of command + GREE_COMPLETE_DATA_LEN, // complete_len: complete length of frame + GREE_STOP_BIT, // stop_bit: flag: frame has stop bit + GREE_LSB, // lsb_first: flag: LSB first + GREE_FLAGS // flags: some flags +}; + +#endif + +#if IRMP_SUPPORT_THOMSON_PROTOCOL == 1 + +static const PROGMEM IRMP_PARAMETER thomson_param = +{ + IRMP_THOMSON_PROTOCOL, // protocol: ir protocol + THOMSON_PULSE_LEN_MIN, // pulse_1_len_min: minimum length of pulse with bit value 1 + THOMSON_PULSE_LEN_MAX, // pulse_1_len_max: maximum length of pulse with bit value 1 + THOMSON_1_PAUSE_LEN_MIN, // pause_1_len_min: minimum length of pause with bit value 1 + THOMSON_1_PAUSE_LEN_MAX, // pause_1_len_max: maximum length of pause with bit value 1 + THOMSON_PULSE_LEN_MIN, // pulse_0_len_min: minimum length of pulse with bit value 0 + THOMSON_PULSE_LEN_MAX, // pulse_0_len_max: maximum length of pulse with bit value 0 + THOMSON_0_PAUSE_LEN_MIN, // pause_0_len_min: minimum length of pause with bit value 0 + THOMSON_0_PAUSE_LEN_MAX, // pause_0_len_max: maximum length of pause with bit value 0 + THOMSON_ADDRESS_OFFSET, // address_offset: address offset + THOMSON_ADDRESS_OFFSET + THOMSON_ADDRESS_LEN, // address_end: end of address + THOMSON_COMMAND_OFFSET, // command_offset: command offset + THOMSON_COMMAND_OFFSET + THOMSON_COMMAND_LEN, // command_end: end of command + THOMSON_COMPLETE_DATA_LEN, // complete_len: complete length of frame + THOMSON_STOP_BIT, // stop_bit: flag: frame has stop bit + THOMSON_LSB, // lsb_first: flag: LSB first + THOMSON_FLAGS // flags: some flags +}; + +#endif + +#if IRMP_SUPPORT_BOSE_PROTOCOL == 1 + +static const PROGMEM IRMP_PARAMETER bose_param = +{ + IRMP_BOSE_PROTOCOL, // protocol: ir protocol + BOSE_PULSE_LEN_MIN, // pulse_1_len_min: minimum length of pulse with bit value 1 + BOSE_PULSE_LEN_MAX, // pulse_1_len_max: maximum length of pulse with bit value 1 + BOSE_1_PAUSE_LEN_MIN, // pause_1_len_min: minimum length of pause with bit value 1 + BOSE_1_PAUSE_LEN_MAX, // pause_1_len_max: maximum length of pause with bit value 1 + BOSE_PULSE_LEN_MIN, // pulse_0_len_min: minimum length of pulse with bit value 0 + BOSE_PULSE_LEN_MAX, // pulse_0_len_max: maximum length of pulse with bit value 0 + BOSE_0_PAUSE_LEN_MIN, // pause_0_len_min: minimum length of pause with bit value 0 + BOSE_0_PAUSE_LEN_MAX, // pause_0_len_max: maximum length of pause with bit value 0 + BOSE_ADDRESS_OFFSET, // address_offset: address offset + BOSE_ADDRESS_OFFSET + BOSE_ADDRESS_LEN, // address_end: end of address + BOSE_COMMAND_OFFSET, // command_offset: command offset + BOSE_COMMAND_OFFSET + BOSE_COMMAND_LEN, // command_end: end of command + BOSE_COMPLETE_DATA_LEN, // complete_len: complete length of frame + BOSE_STOP_BIT, // stop_bit: flag: frame has stop bit + BOSE_LSB, // lsb_first: flag: LSB first + BOSE_FLAGS // flags: some flags +}; + +#endif + +#if IRMP_SUPPORT_A1TVBOX_PROTOCOL == 1 + +static const PROGMEM IRMP_PARAMETER a1tvbox_param = +{ + IRMP_A1TVBOX_PROTOCOL, // protocol: ir protocol + + A1TVBOX_BIT_PULSE_LEN_MIN, // pulse_1_len_min: here: minimum length of short pulse + A1TVBOX_BIT_PULSE_LEN_MAX, // pulse_1_len_max: here: maximum length of short pulse + A1TVBOX_BIT_PAUSE_LEN_MIN, // pause_1_len_min: here: minimum length of short pause + A1TVBOX_BIT_PAUSE_LEN_MAX, // pause_1_len_max: here: maximum length of short pause + 0, // pulse_0_len_min: here: not used + 0, // pulse_0_len_max: here: not used + 0, // pause_0_len_min: here: not used + 0, // pause_0_len_max: here: not used + A1TVBOX_ADDRESS_OFFSET, // address_offset: address offset + A1TVBOX_ADDRESS_OFFSET + A1TVBOX_ADDRESS_LEN, // address_end: end of address + A1TVBOX_COMMAND_OFFSET, // command_offset: command offset + A1TVBOX_COMMAND_OFFSET + A1TVBOX_COMMAND_LEN, // command_end: end of command + A1TVBOX_COMPLETE_DATA_LEN, // complete_len: complete length of frame + A1TVBOX_STOP_BIT, // stop_bit: flag: frame has stop bit + A1TVBOX_LSB, // lsb_first: flag: LSB first + A1TVBOX_FLAGS // flags: some flags +}; + +#endif + +#if IRMP_SUPPORT_MERLIN_PROTOCOL == 1 + +static const PROGMEM IRMP_PARAMETER merlin_param = +{ + IRMP_MERLIN_PROTOCOL, // protocol: ir protocol + + MERLIN_BIT_PULSE_LEN_MIN, // pulse_1_len_min: here: minimum length of short pulse + MERLIN_BIT_PULSE_LEN_MAX, // pulse_1_len_max: here: maximum length of short pulse + MERLIN_BIT_PAUSE_LEN_MIN, // pause_1_len_min: here: minimum length of short pause + MERLIN_BIT_PAUSE_LEN_MAX, // pause_1_len_max: here: maximum length of short pause + 0, // pulse_0_len_min: here: not used + 0, // pulse_0_len_max: here: not used + 0, // pause_0_len_min: here: not used + 0, // pause_0_len_max: here: not used + MERLIN_ADDRESS_OFFSET, // address_offset: address offset + MERLIN_ADDRESS_OFFSET + MERLIN_ADDRESS_LEN, // address_end: end of address + MERLIN_COMMAND_OFFSET, // command_offset: command offset + MERLIN_COMMAND_OFFSET + MERLIN_COMMAND_LEN, // command_end: end of command + MERLIN_COMPLETE_DATA_LEN, // complete_len: complete length of frame + MERLIN_STOP_BIT, // stop_bit: flag: frame has stop bit + MERLIN_LSB, // lsb_first: flag: LSB first + MERLIN_FLAGS // flags: some flags +}; + +#endif + +#if IRMP_SUPPORT_ORTEK_PROTOCOL == 1 + +static const PROGMEM IRMP_PARAMETER ortek_param = +{ + IRMP_ORTEK_PROTOCOL, // protocol: ir protocol + + ORTEK_BIT_PULSE_LEN_MIN, // pulse_1_len_min: here: minimum length of short pulse + ORTEK_BIT_PULSE_LEN_MAX, // pulse_1_len_max: here: maximum length of short pulse + ORTEK_BIT_PAUSE_LEN_MIN, // pause_1_len_min: here: minimum length of short pause + ORTEK_BIT_PAUSE_LEN_MAX, // pause_1_len_max: here: maximum length of short pause + 0, // pulse_0_len_min: here: not used + 0, // pulse_0_len_max: here: not used + 0, // pause_0_len_min: here: not used + 0, // pause_0_len_max: here: not used + ORTEK_ADDRESS_OFFSET, // address_offset: address offset + ORTEK_ADDRESS_OFFSET + ORTEK_ADDRESS_LEN, // address_end: end of address + ORTEK_COMMAND_OFFSET, // command_offset: command offset + ORTEK_COMMAND_OFFSET + ORTEK_COMMAND_LEN, // command_end: end of command + ORTEK_COMPLETE_DATA_LEN, // complete_len: complete length of frame + ORTEK_STOP_BIT, // stop_bit: flag: frame has stop bit + ORTEK_LSB, // lsb_first: flag: LSB first + ORTEK_FLAGS // flags: some flags +}; + +#endif + +#if IRMP_SUPPORT_ROOMBA_PROTOCOL == 1 + +static const PROGMEM IRMP_PARAMETER roomba_param = +{ + IRMP_ROOMBA_PROTOCOL, // protocol: ir protocol + ROOMBA_1_PULSE_LEN_MIN, // pulse_1_len_min: minimum length of pulse with bit value 1 + ROOMBA_1_PULSE_LEN_MAX, // pulse_1_len_max: maximum length of pulse with bit value 1 + ROOMBA_1_PAUSE_LEN_MIN, // pause_1_len_min: minimum length of pause with bit value 1 + ROOMBA_1_PAUSE_LEN_MAX, // pause_1_len_max: maximum length of pause with bit value 1 + ROOMBA_0_PULSE_LEN_MIN, // pulse_0_len_min: minimum length of pulse with bit value 0 + ROOMBA_0_PULSE_LEN_MAX, // pulse_0_len_max: maximum length of pulse with bit value 0 + ROOMBA_0_PAUSE_LEN_MIN, // pause_0_len_min: minimum length of pause with bit value 0 + ROOMBA_0_PAUSE_LEN_MAX, // pause_0_len_max: maximum length of pause with bit value 0 + ROOMBA_ADDRESS_OFFSET, // address_offset: address offset + ROOMBA_ADDRESS_OFFSET + ROOMBA_ADDRESS_LEN, // address_end: end of address + ROOMBA_COMMAND_OFFSET, // command_offset: command offset + ROOMBA_COMMAND_OFFSET + ROOMBA_COMMAND_LEN, // command_end: end of command + ROOMBA_COMPLETE_DATA_LEN, // complete_len: complete length of frame + ROOMBA_STOP_BIT, // stop_bit: flag: frame has stop bit + ROOMBA_LSB, // lsb_first: flag: LSB first + ROOMBA_FLAGS // flags: some flags +}; + +#endif + +#if IRMP_SUPPORT_RCMM_PROTOCOL == 1 + +static const PROGMEM IRMP_PARAMETER rcmm_param = +{ + IRMP_RCMM32_PROTOCOL, // protocol: ir protocol + + RCMM32_BIT_PULSE_LEN_MIN, // pulse_1_len_min: here: minimum length of short pulse + RCMM32_BIT_PULSE_LEN_MAX, // pulse_1_len_max: here: maximum length of short pulse + 0, // pause_1_len_min: here: minimum length of short pause + 0, // pause_1_len_max: here: maximum length of short pause + RCMM32_BIT_PULSE_LEN_MIN, // pulse_0_len_min: here: not used + RCMM32_BIT_PULSE_LEN_MAX, // pulse_0_len_max: here: not used + 0, // pause_0_len_min: here: not used + 0, // pause_0_len_max: here: not used + RCMM32_ADDRESS_OFFSET, // address_offset: address offset + RCMM32_ADDRESS_OFFSET + RCMM32_ADDRESS_LEN, // address_end: end of address + RCMM32_COMMAND_OFFSET, // command_offset: command offset + RCMM32_COMMAND_OFFSET + RCMM32_COMMAND_LEN, // command_end: end of command + RCMM32_COMPLETE_DATA_LEN, // complete_len: complete length of frame + RCMM32_STOP_BIT, // stop_bit: flag: frame has stop bit + RCMM32_LSB, // lsb_first: flag: LSB first + RCMM32_FLAGS // flags: some flags +}; + +#endif + +#if IRMP_SUPPORT_PENTAX_PROTOCOL == 1 + +static const PROGMEM IRMP_PARAMETER pentax_param = +{ + IRMP_PENTAX_PROTOCOL, // protocol: ir protocol + PENTAX_PULSE_LEN_MIN, // pulse_1_len_min: minimum length of pulse with bit value 1 + PENTAX_PULSE_LEN_MAX, // pulse_1_len_max: maximum length of pulse with bit value 1 + PENTAX_1_PAUSE_LEN_MIN, // pause_1_len_min: minimum length of pause with bit value 1 + PENTAX_1_PAUSE_LEN_MAX, // pause_1_len_max: maximum length of pause with bit value 1 + PENTAX_PULSE_LEN_MIN, // pulse_0_len_min: minimum length of pulse with bit value 0 + PENTAX_PULSE_LEN_MAX, // pulse_0_len_max: maximum length of pulse with bit value 0 + PENTAX_0_PAUSE_LEN_MIN, // pause_0_len_min: minimum length of pause with bit value 0 + PENTAX_0_PAUSE_LEN_MAX, // pause_0_len_max: maximum length of pause with bit value 0 + PENTAX_ADDRESS_OFFSET, // address_offset: address offset + PENTAX_ADDRESS_OFFSET + PENTAX_ADDRESS_LEN, // address_end: end of address + PENTAX_COMMAND_OFFSET, // command_offset: command offset + PENTAX_COMMAND_OFFSET + PENTAX_COMMAND_LEN, // command_end: end of command + PENTAX_COMPLETE_DATA_LEN, // complete_len: complete length of frame + PENTAX_STOP_BIT, // stop_bit: flag: frame has stop bit + PENTAX_LSB, // lsb_first: flag: LSB first + PENTAX_FLAGS // flags: some flags +}; + +#endif + +#if IRMP_SUPPORT_ACP24_PROTOCOL == 1 + +static const PROGMEM IRMP_PARAMETER acp24_param = +{ + IRMP_ACP24_PROTOCOL, // protocol: ir protocol + ACP24_PULSE_LEN_MIN, // pulse_1_len_min: minimum length of pulse with bit value 1 + ACP24_PULSE_LEN_MAX, // pulse_1_len_max: maximum length of pulse with bit value 1 + ACP24_1_PAUSE_LEN_MIN, // pause_1_len_min: minimum length of pause with bit value 1 + ACP24_1_PAUSE_LEN_MAX, // pause_1_len_max: maximum length of pause with bit value 1 + ACP24_PULSE_LEN_MIN, // pulse_0_len_min: minimum length of pulse with bit value 0 + ACP24_PULSE_LEN_MAX, // pulse_0_len_max: maximum length of pulse with bit value 0 + ACP24_0_PAUSE_LEN_MIN, // pause_0_len_min: minimum length of pause with bit value 0 + ACP24_0_PAUSE_LEN_MAX, // pause_0_len_max: maximum length of pause with bit value 0 + ACP24_ADDRESS_OFFSET, // address_offset: address offset + ACP24_ADDRESS_OFFSET + ACP24_ADDRESS_LEN, // address_end: end of address + ACP24_COMMAND_OFFSET, // command_offset: command offset + ACP24_COMMAND_OFFSET + ACP24_COMMAND_LEN, // command_end: end of command + ACP24_COMPLETE_DATA_LEN, // complete_len: complete length of frame + ACP24_STOP_BIT, // stop_bit: flag: frame has stop bit + ACP24_LSB, // lsb_first: flag: LSB first + ACP24_FLAGS // flags: some flags +}; + +#endif + +#if IRMP_SUPPORT_METZ_PROTOCOL == 1 + +static const PROGMEM IRMP_PARAMETER metz_param = +{ + IRMP_METZ_PROTOCOL, // protocol: ir protocol + METZ_PULSE_LEN_MIN, // pulse_1_len_min: minimum length of pulse with bit value 1 + METZ_PULSE_LEN_MAX, // pulse_1_len_max: maximum length of pulse with bit value 1 + METZ_1_PAUSE_LEN_MIN, // pause_1_len_min: minimum length of pause with bit value 1 + METZ_1_PAUSE_LEN_MAX, // pause_1_len_max: maximum length of pause with bit value 1 + METZ_PULSE_LEN_MIN, // pulse_0_len_min: minimum length of pulse with bit value 0 + METZ_PULSE_LEN_MAX, // pulse_0_len_max: maximum length of pulse with bit value 0 + METZ_0_PAUSE_LEN_MIN, // pause_0_len_min: minimum length of pause with bit value 0 + METZ_0_PAUSE_LEN_MAX, // pause_0_len_max: maximum length of pause with bit value 0 + METZ_ADDRESS_OFFSET, // address_offset: address offset + METZ_ADDRESS_OFFSET + METZ_ADDRESS_LEN, // address_end: end of address + METZ_COMMAND_OFFSET, // command_offset: command offset + METZ_COMMAND_OFFSET + METZ_COMMAND_LEN, // command_end: end of command + METZ_COMPLETE_DATA_LEN, // complete_len: complete length of frame + METZ_STOP_BIT, // stop_bit: flag: frame has stop bit + METZ_LSB, // lsb_first: flag: LSB first + METZ_FLAGS // flags: some flags +}; + +#endif + +#if IRMP_SUPPORT_RADIO1_PROTOCOL == 1 + +static const PROGMEM IRMP_PARAMETER radio1_param = +{ + IRMP_RADIO1_PROTOCOL, // protocol: ir protocol + + RADIO1_1_PULSE_LEN_MIN, // pulse_1_len_min: minimum length of pulse with bit value 1 + RADIO1_1_PULSE_LEN_MAX, // pulse_1_len_max: maximum length of pulse with bit value 1 + RADIO1_1_PAUSE_LEN_MIN, // pause_1_len_min: minimum length of pause with bit value 1 + RADIO1_1_PAUSE_LEN_MAX, // pause_1_len_max: maximum length of pause with bit value 1 + RADIO1_0_PULSE_LEN_MIN, // pulse_0_len_min: minimum length of pulse with bit value 0 + RADIO1_0_PULSE_LEN_MAX, // pulse_0_len_max: maximum length of pulse with bit value 0 + RADIO1_0_PAUSE_LEN_MIN, // pause_0_len_min: minimum length of pause with bit value 0 + RADIO1_0_PAUSE_LEN_MAX, // pause_0_len_max: maximum length of pause with bit value 0 + RADIO1_ADDRESS_OFFSET, // address_offset: address offset + RADIO1_ADDRESS_OFFSET + RADIO1_ADDRESS_LEN, // address_end: end of address + RADIO1_COMMAND_OFFSET, // command_offset: command offset + RADIO1_COMMAND_OFFSET + RADIO1_COMMAND_LEN, // command_end: end of command + RADIO1_COMPLETE_DATA_LEN, // complete_len: complete length of frame + RADIO1_STOP_BIT, // stop_bit: flag: frame has stop bit + RADIO1_LSB, // lsb_first: flag: LSB first + RADIO1_FLAGS // flags: some flags +}; + +#endif + +static uint_fast8_t irmp_bit; // current bit position +static IRMP_PARAMETER irmp_param; + +#if IRMP_SUPPORT_RC5_PROTOCOL == 1 && (IRMP_SUPPORT_FDC_PROTOCOL == 1 || IRMP_SUPPORT_RCCAR_PROTOCOL == 1) +static IRMP_PARAMETER irmp_param2; +#endif + +static volatile uint_fast8_t irmp_ir_detected = FALSE; +static volatile uint_fast8_t irmp_protocol; +static volatile uint_fast16_t irmp_address; +#if IRMP_32_BIT == 1 +static volatile uint_fast32_t irmp_command; +#else +static volatile uint_fast16_t irmp_command; +#endif +static volatile uint_fast16_t irmp_id; // only used for SAMSUNG protocol +static volatile uint_fast8_t irmp_flags; +// static volatile uint_fast8_t irmp_busy_flag; + +#if defined(__MBED__) +// DigitalIn inputPin(IRMP_PIN, PullUp); // this requires mbed.h and source to be compiled as cpp +gpio_t gpioIRin; // use low level c function instead +#endif + + +#ifdef ANALYZE +#define input(x) (x) +static uint_fast8_t IRMP_PIN; +static uint_fast8_t radio; +#endif + +/*--------------------------------------------------------------------------------------------------------------------------------------------------- + * Initialize IRMP decoder + * @details Configures IRMP input pin + *--------------------------------------------------------------------------------------------------------------------------------------------------- + */ +#ifndef ANALYZE +void +irmp_init (void) +{ +#if defined(PIC_CCS) || defined(PIC_C18) // PIC: do nothing +#elif defined (ARM_STM32_HAL) // STM32 with Hal Library: do nothing +#elif defined (ARM_STM32) // STM32 + GPIO_InitTypeDef GPIO_InitStructure; + + /* GPIOx clock enable */ +# if defined (ARM_STM32L1XX) + RCC_AHBPeriphClockCmd(IRMP_PORT_RCC, ENABLE); +# elif defined (ARM_STM32F10X) + RCC_APB2PeriphClockCmd(IRMP_PORT_RCC, ENABLE); +# elif defined (ARM_STM32F4XX) + RCC_AHB1PeriphClockCmd(IRMP_PORT_RCC, ENABLE); +# endif + + /* GPIO Configuration */ + GPIO_InitStructure.GPIO_Pin = IRMP_BIT; +# if defined (ARM_STM32L1XX) || defined (ARM_STM32F4XX) + GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN; + GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz; + GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; + GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; +# elif defined (ARM_STM32F10X) + GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz; + GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; +# endif + GPIO_Init(IRMP_PORT, &GPIO_InitStructure); + +#elif defined(STELLARIS_ARM_CORTEX_M4) + // Enable the GPIO port + ROM_SysCtlPeripheralEnable(IRMP_PORT_PERIPH); + + // Set as an input + ROM_GPIODirModeSet(IRMP_PORT_BASE, IRMP_PORT_PIN, GPIO_DIR_MODE_IN); + ROM_GPIOPadConfigSet(IRMP_PORT_BASE, IRMP_PORT_PIN, GPIO_STRENGTH_2MA, GPIO_PIN_TYPE_STD_WPU); + +#elif defined(__SDCC_stm8) // STM8 + IRMP_GPIO_STRUCT->DDR &= ~(1<<IRMP_BIT); // pin is input + IRMP_GPIO_STRUCT->CR1 |= (1<<IRMP_BIT); // activate pullup + +#elif defined (TEENSY_ARM_CORTEX_M4) // TEENSY + pinMode(IRMP_PIN, INPUT); + +#elif defined(__xtensa__) // ESP8266 + pinMode(IRMP_BIT_NUMBER, INPUT); + // select pin function +# if (IRMP_BIT_NUMBER == 12) + PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTDI_U, FUNC_GPIO12); +// doesn't work for me: +// # elif (IRMP_BIT_NUMBER == 13) +// PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTCK_U , FUNC_GPIO13); +# else +# warning Please add PIN_FUNC_SELECT when necessary. +# endif + GPIO_DIS_OUTPUT(IRMP_BIT_NUMBER); + +#elif defined(__MBED__) + gpio_init_in_ex(&gpioIRin, IRMP_PIN, IRMP_PINMODE); // initialize input for IR diode + +#elif defined(_CHIBIOS_HAL_) + // ChibiOS HAL automatically initializes all pins according to the board config file, no need to repeat here + +#else // AVR + IRMP_PORT &= ~(1<<IRMP_BIT); // deactivate pullup + IRMP_DDR &= ~(1<<IRMP_BIT); // set pin to input +#endif + +#if IRMP_LOGGING == 1 + irmp_uart_init (); +#endif +} +#endif +/*--------------------------------------------------------------------------------------------------------------------------------------------------- + * Get IRMP data + * @details gets decoded IRMP data + * @param pointer in order to store IRMP data + * @return TRUE: successful, FALSE: failed + *--------------------------------------------------------------------------------------------------------------------------------------------------- + */ +uint_fast8_t +irmp_get_data (IRMP_DATA * irmp_data_p) +{ + uint_fast8_t rtc = FALSE; +#if IRMP_SUPPORT_MERLIN_PROTOCOL == 1 + uint_fast8_t cmd_len = 0; +#endif + + if (irmp_ir_detected) + { + switch (irmp_protocol) + { +#if IRMP_SUPPORT_SAMSUNG_PROTOCOL == 1 + case IRMP_SAMSUNG_PROTOCOL: + if ((irmp_command >> 8) == (~irmp_command & 0x00FF)) + { + irmp_command &= 0xff; + irmp_command |= irmp_id << 8; + rtc = TRUE; + } + break; + +#if IRMP_SUPPORT_SAMSUNG48_PROTOCOL == 1 + case IRMP_SAMSUNG48_PROTOCOL: + irmp_command = (irmp_command & 0x00FF) | ((irmp_id & 0x00FF) << 8); + rtc = TRUE; + break; +#endif +#endif + +#if IRMP_SUPPORT_NEC_PROTOCOL == 1 + case IRMP_NEC_PROTOCOL: + if ((irmp_command >> 8) == (~irmp_command & 0x00FF)) + { + irmp_command &= 0xff; + rtc = TRUE; + } + else if (irmp_address == 0x87EE) + { +#ifdef ANALYZE + ANALYZE_PRINTF ("Switching to APPLE protocol\n"); +#endif // ANALYZE + irmp_protocol = IRMP_APPLE_PROTOCOL; + irmp_address = (irmp_command & 0xFF00) >> 8; + irmp_command &= 0x00FF; + rtc = TRUE; + } + else + { +#ifdef ANALYZE + ANALYZE_PRINTF ("Switching to ONKYO protocol\n"); +#endif // ANALYZE + irmp_protocol = IRMP_ONKYO_PROTOCOL; + rtc = TRUE; + } + break; +#endif + + +#if IRMP_SUPPORT_NEC_PROTOCOL == 1 + case IRMP_VINCENT_PROTOCOL: + if ((irmp_command >> 8) == (irmp_command & 0x00FF)) + { + irmp_command &= 0xff; + rtc = TRUE; + } + break; +#endif + +#if IRMP_SUPPORT_BOSE_PROTOCOL == 1 + case IRMP_BOSE_PROTOCOL: + if ((irmp_command >> 8) == (~irmp_command & 0x00FF)) + { + irmp_command &= 0xff; + rtc = TRUE; + } + break; +#endif + +#if IRMP_SUPPORT_MERLIN_PROTOCOL == 1 + case IRMP_MERLIN_PROTOCOL: + if (irmp_bit == 10) + { + rtc = TRUE; + } + else if (irmp_bit >= 19 && ((irmp_bit - 3) % 8 == 0)) + { + if (((irmp_command >> 1) & 1) != (irmp_command & 1)) + { + irmp_command >>= 1; + irmp_command |= ((irmp_address & 1) << (irmp_bit - 12)); + irmp_address >>= 1; + cmd_len = (irmp_bit - 11) >> 3; + rtc = TRUE; + } + } + break; +#endif + +#if IRMP_SUPPORT_SIEMENS_OR_RUWIDO_PROTOCOL == 1 + case IRMP_SIEMENS_PROTOCOL: + case IRMP_RUWIDO_PROTOCOL: + if (((irmp_command >> 1) & 0x0001) == (~irmp_command & 0x0001)) + { + irmp_command >>= 1; + rtc = TRUE; + } + break; +#endif +#if IRMP_SUPPORT_KATHREIN_PROTOCOL == 1 + case IRMP_KATHREIN_PROTOCOL: + if (irmp_command != 0x0000) + { + rtc = TRUE; + } + break; +#endif +#if IRMP_SUPPORT_RC5_PROTOCOL == 1 + case IRMP_RC5_PROTOCOL: + irmp_address &= ~0x20; // clear toggle bit + rtc = TRUE; + break; +#endif +#if IRMP_SUPPORT_S100_PROTOCOL == 1 + case IRMP_S100_PROTOCOL: + irmp_address &= ~0x20; // clear toggle bit + rtc = TRUE; + break; +#endif +#if IRMP_SUPPORT_IR60_PROTOCOL == 1 + case IRMP_IR60_PROTOCOL: + if (irmp_command != 0x007d) // 0x007d (== 62<<1 + 1) is start instruction frame + { + rtc = TRUE; + } + else + { +#ifdef ANALYZE + ANALYZE_PRINTF("Info IR60: got start instruction frame\n"); +#endif // ANALYZE + } + break; +#endif +#if IRMP_SUPPORT_RCCAR_PROTOCOL == 1 + case IRMP_RCCAR_PROTOCOL: + // frame in irmp_data: + // Bit 12 11 10 9 8 7 6 5 4 3 2 1 0 + // V D7 D6 D5 D4 D3 D2 D1 D0 A1 A0 C1 C0 // 10 9 8 7 6 5 4 3 2 1 0 + irmp_address = (irmp_command & 0x000C) >> 2; // addr: 0 0 0 0 0 0 0 0 0 A1 A0 + irmp_command = ((irmp_command & 0x1000) >> 2) | // V-Bit: V 0 0 0 0 0 0 0 0 0 0 + ((irmp_command & 0x0003) << 8) | // C-Bits: 0 C1 C0 0 0 0 0 0 0 0 0 + ((irmp_command & 0x0FF0) >> 4); // D-Bits: D7 D6 D5 D4 D3 D2 D1 D0 + rtc = TRUE; // Summe: V C1 C0 D7 D6 D5 D4 D3 D2 D1 D0 + break; +#endif + +#if IRMP_SUPPORT_NETBOX_PROTOCOL == 1 // squeeze code to 8 bit, upper bit indicates release-key + case IRMP_NETBOX_PROTOCOL: + if (irmp_command & 0x1000) // last bit set? + { + if ((irmp_command & 0x1f) == 0x15) // key pressed: 101 01 (LSB) + { + irmp_command >>= 5; + irmp_command &= 0x7F; + rtc = TRUE; + } + else if ((irmp_command & 0x1f) == 0x10) // key released: 000 01 (LSB) + { + irmp_command >>= 5; + irmp_command |= 0x80; + rtc = TRUE; + } + else + { +#ifdef ANALYZE + ANALYZE_PRINTF("error NETBOX: bit6/7 must be 0/1\n"); +#endif // ANALYZE + } + } + else + { +#ifdef ANALYZE + ANALYZE_PRINTF("error NETBOX: last bit not set\n"); +#endif // ANALYZE + } + break; +#endif +#if IRMP_SUPPORT_LEGO_PROTOCOL == 1 + case IRMP_LEGO_PROTOCOL: + { + uint_fast8_t crc = 0x0F ^ ((irmp_command & 0xF000) >> 12) ^ ((irmp_command & 0x0F00) >> 8) ^ ((irmp_command & 0x00F0) >> 4); + + if ((irmp_command & 0x000F) == crc) + { + irmp_command >>= 4; + rtc = TRUE; + } + else + { +#ifdef ANALYZE + ANALYZE_PRINTF ("CRC error in LEGO protocol\n"); +#endif // ANALYZE + // rtc = TRUE; // don't accept codes with CRC errors + } + break; + } +#endif + +#if IRMP_SUPPORT_METZ_PROTOCOL == 1 + case IRMP_METZ_PROTOCOL: + irmp_address &= ~0x40; // clear toggle bit + if (((~irmp_address) & 0x07) == (irmp_address >> 3) && ((~irmp_command) & 0x3f) == (irmp_command >> 6)) + { + irmp_address >>= 3; + irmp_command >>= 6; + rtc = TRUE; + } + break; +#endif + default: + { + rtc = TRUE; + break; + } + } + + if (rtc) + { + irmp_data_p->protocol = irmp_protocol; + irmp_data_p->address = irmp_address; + irmp_data_p->command = irmp_command; + irmp_data_p->flags = irmp_flags; +#if IRMP_SUPPORT_MERLIN_PROTOCOL == 1 + irmp_data_p->flags |= cmd_len; +#endif + } + else + { + irmp_protocol = IRMP_UNKNOWN_PROTOCOL; + } + + irmp_command = 0; // don't reset irmp_protocol here, needed for detection of NEC & JVC repetition frames! + irmp_address = 0; + irmp_flags = 0; + + irmp_ir_detected = FALSE; + } + + return rtc; +} + +#if IRMP_USE_CALLBACK == 1 +void +irmp_set_callback_ptr (void (*cb)(uint_fast8_t)) +{ + irmp_callback_ptr = cb; +} +#endif // IRMP_USE_CALLBACK == 1 + +// these statics must not be volatile, because they are only used by irmp_store_bit(), which is called by irmp_ISR() +static uint_fast16_t irmp_tmp_address; // ir address +#if IRMP_32_BIT == 1 +static uint_fast32_t irmp_tmp_command; // ir command +#else +static uint_fast16_t irmp_tmp_command; // ir command +#endif + +#if (IRMP_SUPPORT_RC5_PROTOCOL == 1 && (IRMP_SUPPORT_FDC_PROTOCOL == 1 || IRMP_SUPPORT_RCCAR_PROTOCOL == 1)) || IRMP_SUPPORT_NEC42_PROTOCOL == 1 +static uint_fast16_t irmp_tmp_address2; // ir address +static uint_fast16_t irmp_tmp_command2; // ir command +#endif + +#if IRMP_SUPPORT_LGAIR_PROTOCOL == 1 +static uint_fast16_t irmp_lgair_address; // ir address +static uint_fast16_t irmp_lgair_command; // ir command +#endif + +#if IRMP_SUPPORT_SAMSUNG_PROTOCOL == 1 +static uint_fast16_t irmp_tmp_id; // ir id (only SAMSUNG) +#endif +#if IRMP_SUPPORT_KASEIKYO_PROTOCOL == 1 +static uint8_t xor_check[6]; // check kaseikyo "parity" bits +static uint_fast8_t genre2; // save genre2 bits here, later copied to MSB in flags +#endif + +#if IRMP_SUPPORT_ORTEK_PROTOCOL == 1 +static uint_fast8_t parity; // number of '1' of the first 14 bits, check if even. +#endif + +#if IRMP_SUPPORT_MITSU_HEAVY_PROTOCOL == 1 +static uint_fast8_t check; // number of '1' of the first 14 bits, check if even. +static uint_fast8_t mitsu_parity; // number of '1' of the first 14 bits, check if even. +#endif + +/*--------------------------------------------------------------------------------------------------------------------------------------------------- + * store bit + * @details store bit in temp address or temp command + * @param value to store: 0 or 1 + *--------------------------------------------------------------------------------------------------------------------------------------------------- + */ +// verhindert, dass irmp_store_bit() inline compiliert wird: +// static void irmp_store_bit (uint_fast8_t) __attribute__ ((noinline)); + +static void +irmp_store_bit (uint_fast8_t value) +{ +#if IRMP_SUPPORT_ACP24_PROTOCOL == 1 + if (irmp_param.protocol == IRMP_ACP24_PROTOCOL) // squeeze 64 bits into 16 bits: + { + if (value) + { + // ACP24-Frame: + // 1 2 3 4 5 6 + // 0123456789012345678901234567890123456789012345678901234567890123456789 + // N VVMMM ? ??? t vmA x y TTTT + // + // irmp_data_p->command: + // + // 5432109876543210 + // NAVVvMMMmtxyTTTT + + switch (irmp_bit) + { + case 0: irmp_tmp_command |= (1<<15); break; // N + case 2: irmp_tmp_command |= (1<<13); break; // V + case 3: irmp_tmp_command |= (1<<12); break; // V + case 4: irmp_tmp_command |= (1<<10); break; // M + case 5: irmp_tmp_command |= (1<< 9); break; // M + case 6: irmp_tmp_command |= (1<< 8); break; // M + case 20: irmp_tmp_command |= (1<< 6); break; // t + case 22: irmp_tmp_command |= (1<<11); break; // v + case 23: irmp_tmp_command |= (1<< 7); break; // m + case 24: irmp_tmp_command |= (1<<14); break; // A + case 26: irmp_tmp_command |= (1<< 5); break; // x + case 44: irmp_tmp_command |= (1<< 4); break; // y + case 66: irmp_tmp_command |= (1<< 3); break; // T + case 67: irmp_tmp_command |= (1<< 2); break; // T + case 68: irmp_tmp_command |= (1<< 1); break; // T + case 69: irmp_tmp_command |= (1<< 0); break; // T + } + } + } + else +#endif // IRMP_SUPPORT_ACP24_PROTOCOL + +#if IRMP_SUPPORT_ORTEK_PROTOCOL == 1 + if (irmp_param.protocol == IRMP_ORTEK_PROTOCOL) + { + if (irmp_bit < 14) + { + if (value) + { + parity++; + } + } + else if (irmp_bit == 14) + { + if (value) // value == 1: even parity + { + if (parity & 0x01) + { + parity = PARITY_CHECK_FAILED; + } + else + { + parity = PARITY_CHECK_OK; + } + } + else + { + if (parity & 0x01) // value == 0: odd parity + { + parity = PARITY_CHECK_OK; + } + else + { + parity = PARITY_CHECK_FAILED; + } + } + } + } + else +#endif + { + ; + } + +#if IRMP_SUPPORT_GRUNDIG_NOKIA_IR60_PROTOCOL == 1 + if (irmp_bit == 0 && irmp_param.protocol == IRMP_GRUNDIG_PROTOCOL) + { + first_bit = value; + } + else +#endif + + if (irmp_bit >= irmp_param.address_offset && irmp_bit < irmp_param.address_end) + { + if (irmp_param.lsb_first) + { + irmp_tmp_address |= (((uint_fast16_t) (value)) << (irmp_bit - irmp_param.address_offset)); // CV wants cast + } + else + { + irmp_tmp_address <<= 1; + irmp_tmp_address |= value; + } + } + else if (irmp_bit >= irmp_param.command_offset && irmp_bit < irmp_param.command_end) + { + if (irmp_param.lsb_first) + { +#if IRMP_SUPPORT_SAMSUNG48_PROTOCOL == 1 + if (irmp_param.protocol == IRMP_SAMSUNG48_PROTOCOL && irmp_bit >= 32) + { + irmp_tmp_id |= (((uint_fast16_t) (value)) << (irmp_bit - 32)); // CV wants cast + } + else +#endif + { + irmp_tmp_command |= (((uint_fast16_t) (value)) << (irmp_bit - irmp_param.command_offset)); // CV wants cast + } + } + else + { + irmp_tmp_command <<= 1; + irmp_tmp_command |= value; + } + } + +#if IRMP_SUPPORT_LGAIR_PROTOCOL == 1 + if (irmp_param.protocol == IRMP_NEC_PROTOCOL || irmp_param.protocol == IRMP_NEC42_PROTOCOL) + { + if (irmp_bit < 8) + { + irmp_lgair_address <<= 1; // LGAIR uses MSB + irmp_lgair_address |= value; + } + else if (irmp_bit < 24) + { + irmp_lgair_command <<= 1; // LGAIR uses MSB + irmp_lgair_command |= value; + } + } + // NO else! +#endif + +#if IRMP_SUPPORT_NEC42_PROTOCOL == 1 + if (irmp_param.protocol == IRMP_NEC42_PROTOCOL && irmp_bit >= 13 && irmp_bit < 26) + { + irmp_tmp_address2 |= (((uint_fast16_t) (value)) << (irmp_bit - 13)); // CV wants cast + } + else +#endif + +#if IRMP_SUPPORT_SAMSUNG_PROTOCOL == 1 + if (irmp_param.protocol == IRMP_SAMSUNG_PROTOCOL && irmp_bit >= SAMSUNG_ID_OFFSET && irmp_bit < SAMSUNG_ID_OFFSET + SAMSUNG_ID_LEN) + { + irmp_tmp_id |= (((uint_fast16_t) (value)) << (irmp_bit - SAMSUNG_ID_OFFSET)); // store with LSB first + } + else +#endif + +#if IRMP_SUPPORT_KASEIKYO_PROTOCOL == 1 + if (irmp_param.protocol == IRMP_KASEIKYO_PROTOCOL) + { + if (irmp_bit >= 20 && irmp_bit < 24) + { + irmp_tmp_command |= (((uint_fast16_t) (value)) << (irmp_bit - 8)); // store 4 system bits (genre 1) in upper nibble with LSB first + } + else if (irmp_bit >= 24 && irmp_bit < 28) + { + genre2 |= (((uint_fast8_t) (value)) << (irmp_bit - 20)); // store 4 system bits (genre 2) in upper nibble with LSB first + } + + if (irmp_bit < KASEIKYO_COMPLETE_DATA_LEN) + { + if (value) + { + xor_check[irmp_bit / 8] |= 1 << (irmp_bit % 8); + } + else + { + xor_check[irmp_bit / 8] &= ~(1 << (irmp_bit % 8)); + } + } + } + else +#endif + +#if IRMP_SUPPORT_MITSU_HEAVY_PROTOCOL == 1 + if (irmp_param.protocol == IRMP_MITSU_HEAVY_PROTOCOL) // squeeze 64 bits into 16 bits: + { + if (irmp_bit == 72 ) + { // irmp_tmp_address, irmp_tmp_command received: check parity & compress + mitsu_parity = PARITY_CHECK_OK; + + check = irmp_tmp_address >> 8; // inverted upper byte == lower byte? + check = ~ check; + + if (check == (irmp_tmp_address & 0xFF)) + { // ok: + irmp_tmp_address <<= 8; // throw away upper byte + } + else + { + mitsu_parity = PARITY_CHECK_FAILED; + } + + check = irmp_tmp_command >> 8; // inverted upper byte == lower byte? + check = ~ check; + if (check == (irmp_tmp_command & 0xFF)) + { // ok: pack together + irmp_tmp_address |= irmp_tmp_command & 0xFF; // byte 1, byte2 in irmp_tmp_address, irmp_tmp_command can be used for byte 3 + } + else + { + mitsu_parity = PARITY_CHECK_FAILED; + } + irmp_tmp_command = 0; + } + + if (irmp_bit >= 72 ) + { // receive 3. word in irmp_tmp_command + irmp_tmp_command <<= 1; + irmp_tmp_command |= value; + } + } + else +#endif // IRMP_SUPPORT_MITSU_HEAVY_PROTOCOL + { + ; + } + + irmp_bit++; +} + +/*--------------------------------------------------------------------------------------------------------------------------------------------------- + * store bit + * @details store bit in temp address or temp command + * @param value to store: 0 or 1 + *--------------------------------------------------------------------------------------------------------------------------------------------------- + */ +#if IRMP_SUPPORT_RC5_PROTOCOL == 1 && (IRMP_SUPPORT_FDC_PROTOCOL == 1 || IRMP_SUPPORT_RCCAR_PROTOCOL == 1) +static void +irmp_store_bit2 (uint_fast8_t value) +{ + uint_fast8_t irmp_bit2; + + if (irmp_param.protocol) + { + irmp_bit2 = irmp_bit - 2; + } + else + { + irmp_bit2 = irmp_bit - 1; + } + + if (irmp_bit2 >= irmp_param2.address_offset && irmp_bit2 < irmp_param2.address_end) + { + irmp_tmp_address2 |= (((uint_fast16_t) (value)) << (irmp_bit2 - irmp_param2.address_offset)); // CV wants cast + } + else if (irmp_bit2 >= irmp_param2.command_offset && irmp_bit2 < irmp_param2.command_end) + { + irmp_tmp_command2 |= (((uint_fast16_t) (value)) << (irmp_bit2 - irmp_param2.command_offset)); // CV wants cast + } +} +#endif // IRMP_SUPPORT_RC5_PROTOCOL == 1 && (IRMP_SUPPORT_FDC_PROTOCOL == 1 || IRMP_SUPPORT_RCCAR_PROTOCOL == 1) + +/*--------------------------------------------------------------------------------------------------------------------------------------------------- + * ISR routine + * @details ISR routine, called 10000 times per second + *--------------------------------------------------------------------------------------------------------------------------------------------------- + */ +uint_fast8_t +irmp_ISR (void) +{ + static uint_fast8_t irmp_start_bit_detected; // flag: start bit detected + static uint_fast8_t wait_for_space; // flag: wait for data bit space + static uint_fast8_t wait_for_start_space; // flag: wait for start bit space + static uint_fast8_t irmp_pulse_time; // count bit time for pulse + static PAUSE_LEN irmp_pause_time; // count bit time for pause + static uint_fast16_t last_irmp_address = 0xFFFF; // save last irmp address to recognize key repetition +#if IRMP_32_BIT == 1 + static uint_fast32_t last_irmp_command = 0xFFFFFFFF; // save last irmp command to recognize key repetition +#else + static uint_fast16_t last_irmp_command = 0xFFFF; // save last irmp command to recognize key repetition +#endif + static uint_fast16_t key_repetition_len; // SIRCS repeats frame 2-5 times with 45 ms pause + static uint_fast8_t repetition_frame_number; +#if IRMP_SUPPORT_DENON_PROTOCOL == 1 + static uint_fast16_t last_irmp_denon_command; // save last irmp command to recognize DENON frame repetition + static uint_fast16_t denon_repetition_len = 0xFFFF; // denon repetition len of 2nd auto generated frame +#endif +#if IRMP_SUPPORT_RC5_PROTOCOL == 1 || IRMP_SUPPORT_S100_PROTOCOL == 1 + static uint_fast8_t rc5_cmd_bit6; // bit 6 of RC5 command is the inverted 2nd start bit +#endif +#if IRMP_SUPPORT_MANCHESTER == 1 + static PAUSE_LEN last_pause; // last pause value +#endif +#if IRMP_SUPPORT_MANCHESTER == 1 || IRMP_SUPPORT_BANG_OLUFSEN_PROTOCOL == 1 + static uint_fast8_t last_value; // last bit value +#endif +#if IRMP_SUPPORT_RCII_PROTOCOL == 1 + static uint_fast8_t waiting_for_2nd_pulse = 0; +#endif + uint_fast8_t irmp_input; // input value + +#ifdef ANALYZE + +#if 0 // only for test + static uint_fast8_t last_irmp_start_bit_detected = 0xFF; + static uint_fast8_t last_irmp_pulse_time = 0xFF; + + if (last_irmp_start_bit_detected != irmp_start_bit_detected || last_irmp_pulse_time != irmp_pulse_time) + { + last_irmp_start_bit_detected = irmp_start_bit_detected; + last_irmp_pulse_time = irmp_pulse_time; + + printf ("%d %d %d\n", time_counter, irmp_start_bit_detected, irmp_pulse_time); + } +#endif // 0 + + time_counter++; +#endif // ANALYZE + +#if defined(__SDCC_stm8) + irmp_input = input(IRMP_GPIO_STRUCT->IDR) +#elif defined(__MBED__) + //irmp_input = inputPin; + irmp_input = gpio_read (&gpioIRin); +#else + irmp_input = input(IRMP_PIN); +#endif + +#if IRMP_USE_CALLBACK == 1 + if (irmp_callback_ptr) + { + static uint_fast8_t last_inverted_input; + + if (last_inverted_input != !irmp_input) + { + (*irmp_callback_ptr) (! irmp_input); + last_inverted_input = !irmp_input; + } + } +#endif // IRMP_USE_CALLBACK == 1 + + irmp_log(irmp_input); // log ir signal, if IRMP_LOGGING defined + + if (! irmp_ir_detected) // ir code already detected? + { // no... + if (! irmp_start_bit_detected) // start bit detected? + { // no... + if (! irmp_input) // receiving burst? + { // yes... +// irmp_busy_flag = TRUE; +#ifdef ANALYZE + if (! irmp_pulse_time) + { + ANALYZE_PRINTF("%8.3fms [starting pulse]\n", (double) (time_counter * 1000) / F_INTERRUPTS); + } +#endif // ANALYZE + irmp_pulse_time++; // increment counter + } + else + { // no... + if (irmp_pulse_time) // it's dark.... + { // set flags for counting the time of darkness... + irmp_start_bit_detected = 1; + wait_for_start_space = 1; + wait_for_space = 0; + irmp_tmp_command = 0; + irmp_tmp_address = 0; +#if IRMP_SUPPORT_KASEIKYO_PROTOCOL == 1 + genre2 = 0; +#endif +#if IRMP_SUPPORT_SAMSUNG_PROTOCOL == 1 + irmp_tmp_id = 0; +#endif + +#if IRMP_SUPPORT_RC5_PROTOCOL == 1 && (IRMP_SUPPORT_FDC_PROTOCOL == 1 || IRMP_SUPPORT_RCCAR_PROTOCOL == 1) || IRMP_SUPPORT_NEC42_PROTOCOL == 1 + irmp_tmp_command2 = 0; + irmp_tmp_address2 = 0; +#endif +#if IRMP_SUPPORT_LGAIR_PROTOCOL == 1 + irmp_lgair_command = 0; + irmp_lgair_address = 0; +#endif + irmp_bit = 0xff; + irmp_pause_time = 1; // 1st pause: set to 1, not to 0! +#if IRMP_SUPPORT_RC5_PROTOCOL == 1 || IRMP_SUPPORT_S100_PROTOCOL == 1 + rc5_cmd_bit6 = 0; // fm 2010-03-07: bugfix: reset it after incomplete RC5 frame! +#endif + } + else + { + if (key_repetition_len < 0xFFFF) // avoid overflow of counter + { + key_repetition_len++; + +#if IRMP_SUPPORT_DENON_PROTOCOL == 1 + if (denon_repetition_len < 0xFFFF) // avoid overflow of counter + { + denon_repetition_len++; + + if (denon_repetition_len >= DENON_AUTO_REPETITION_PAUSE_LEN && last_irmp_denon_command != 0) + { +#ifdef ANALYZE + ANALYZE_PRINTF ("%8.3fms warning: did not receive inverted command repetition\n", + (double) (time_counter * 1000) / F_INTERRUPTS); +#endif // ANALYZE + last_irmp_denon_command = 0; + denon_repetition_len = 0xFFFF; + } + } +#endif // IRMP_SUPPORT_DENON_PROTOCOL == 1 + } + } + } + } + else + { + if (wait_for_start_space) // we have received start bit... + { // ...and are counting the time of darkness + if (irmp_input) // still dark? + { // yes + irmp_pause_time++; // increment counter + +#if IRMP_SUPPORT_NIKON_PROTOCOL == 1 + if (((irmp_pulse_time < NIKON_START_BIT_PULSE_LEN_MIN || irmp_pulse_time > NIKON_START_BIT_PULSE_LEN_MAX) && irmp_pause_time > IRMP_TIMEOUT_LEN) || + irmp_pause_time > IRMP_TIMEOUT_NIKON_LEN) +#else + if (irmp_pause_time > IRMP_TIMEOUT_LEN) // timeout? +#endif + { // yes... +#if IRMP_SUPPORT_JVC_PROTOCOL == 1 + if (irmp_protocol == IRMP_JVC_PROTOCOL) // don't show eror if JVC protocol, irmp_pulse_time has been set below! + { + ; + } + else +#endif // IRMP_SUPPORT_JVC_PROTOCOL == 1 + { +#ifdef ANALYZE + ANALYZE_PRINTF ("%8.3fms error 1: pause after start bit pulse %d too long: %d\n", (double) (time_counter * 1000) / F_INTERRUPTS, irmp_pulse_time, irmp_pause_time); + ANALYZE_ONLY_NORMAL_PUTCHAR ('\n'); +#endif // ANALYZE + } + + irmp_start_bit_detected = 0; // reset flags, let's wait for another start bit + irmp_pulse_time = 0; + irmp_pause_time = 0; + } + } + else + { // receiving first data pulse! + IRMP_PARAMETER * irmp_param_p; + irmp_param_p = (IRMP_PARAMETER *) 0; + +#if IRMP_SUPPORT_RC5_PROTOCOL == 1 && (IRMP_SUPPORT_FDC_PROTOCOL == 1 || IRMP_SUPPORT_RCCAR_PROTOCOL == 1) + irmp_param2.protocol = 0; +#endif + +#ifdef ANALYZE + ANALYZE_PRINTF ("%8.3fms [start-bit: pulse = %2d, pause = %2d]\n", (double) (time_counter * 1000) / F_INTERRUPTS, irmp_pulse_time, irmp_pause_time); +#endif // ANALYZE + +#if IRMP_SUPPORT_SIRCS_PROTOCOL == 1 + if (irmp_pulse_time >= SIRCS_START_BIT_PULSE_LEN_MIN && irmp_pulse_time <= SIRCS_START_BIT_PULSE_LEN_MAX && + irmp_pause_time >= SIRCS_START_BIT_PAUSE_LEN_MIN && irmp_pause_time <= SIRCS_START_BIT_PAUSE_LEN_MAX) + { // it's SIRCS +#ifdef ANALYZE + ANALYZE_PRINTF ("protocol = SIRCS, start bit timings: pulse: %3d - %3d, pause: %3d - %3d\n", + SIRCS_START_BIT_PULSE_LEN_MIN, SIRCS_START_BIT_PULSE_LEN_MAX, + SIRCS_START_BIT_PAUSE_LEN_MIN, SIRCS_START_BIT_PAUSE_LEN_MAX); +#endif // ANALYZE + irmp_param_p = (IRMP_PARAMETER *) &sircs_param; + } + else +#endif // IRMP_SUPPORT_SIRCS_PROTOCOL == 1 + +#if IRMP_SUPPORT_JVC_PROTOCOL == 1 + if (irmp_protocol == IRMP_JVC_PROTOCOL && // last protocol was JVC, awaiting repeat frame + irmp_pulse_time >= JVC_START_BIT_PULSE_LEN_MIN && irmp_pulse_time <= JVC_START_BIT_PULSE_LEN_MAX && + irmp_pause_time >= JVC_REPEAT_START_BIT_PAUSE_LEN_MIN && irmp_pause_time <= JVC_REPEAT_START_BIT_PAUSE_LEN_MAX) + { +#ifdef ANALYZE + ANALYZE_PRINTF ("protocol = NEC or JVC (type 1) repeat frame, start bit timings: pulse: %3d - %3d, pause: %3d - %3d\n", + JVC_START_BIT_PULSE_LEN_MIN, JVC_START_BIT_PULSE_LEN_MAX, + JVC_REPEAT_START_BIT_PAUSE_LEN_MIN, JVC_REPEAT_START_BIT_PAUSE_LEN_MAX); +#endif // ANALYZE + irmp_param_p = (IRMP_PARAMETER *) &nec_param; + } + else +#endif // IRMP_SUPPORT_JVC_PROTOCOL == 1 + +#if IRMP_SUPPORT_NEC_PROTOCOL == 1 + if (irmp_pulse_time >= NEC_START_BIT_PULSE_LEN_MIN && irmp_pulse_time <= NEC_START_BIT_PULSE_LEN_MAX && + irmp_pause_time >= NEC_START_BIT_PAUSE_LEN_MIN && irmp_pause_time <= NEC_START_BIT_PAUSE_LEN_MAX) + { +#if IRMP_SUPPORT_NEC42_PROTOCOL == 1 +#ifdef ANALYZE + ANALYZE_PRINTF ("protocol = NEC42, start bit timings: pulse: %3d - %3d, pause: %3d - %3d\n", + NEC_START_BIT_PULSE_LEN_MIN, NEC_START_BIT_PULSE_LEN_MAX, + NEC_START_BIT_PAUSE_LEN_MIN, NEC_START_BIT_PAUSE_LEN_MAX); +#endif // ANALYZE + irmp_param_p = (IRMP_PARAMETER *) &nec42_param; +#else +#ifdef ANALYZE + ANALYZE_PRINTF ("protocol = NEC, start bit timings: pulse: %3d - %3d, pause: %3d - %3d\n", + NEC_START_BIT_PULSE_LEN_MIN, NEC_START_BIT_PULSE_LEN_MAX, + NEC_START_BIT_PAUSE_LEN_MIN, NEC_START_BIT_PAUSE_LEN_MAX); +#endif // ANALYZE + irmp_param_p = (IRMP_PARAMETER *) &nec_param; +#endif + } + else if (irmp_pulse_time >= NEC_START_BIT_PULSE_LEN_MIN && irmp_pulse_time <= NEC_START_BIT_PULSE_LEN_MAX && + irmp_pause_time >= NEC_REPEAT_START_BIT_PAUSE_LEN_MIN && irmp_pause_time <= NEC_REPEAT_START_BIT_PAUSE_LEN_MAX) + { // it's NEC +#if IRMP_SUPPORT_JVC_PROTOCOL == 1 + if (irmp_protocol == IRMP_JVC_PROTOCOL) // last protocol was JVC, awaiting repeat frame + { // some jvc remote controls use nec repetition frame for jvc repetition frame +#ifdef ANALYZE + ANALYZE_PRINTF ("protocol = JVC repeat frame type 2, start bit timings: pulse: %3d - %3d, pause: %3d - %3d\n", + NEC_START_BIT_PULSE_LEN_MIN, NEC_START_BIT_PULSE_LEN_MAX, + NEC_REPEAT_START_BIT_PAUSE_LEN_MIN, NEC_REPEAT_START_BIT_PAUSE_LEN_MAX); +#endif // ANALYZE + irmp_param_p = (IRMP_PARAMETER *) &nec_param; + } + else +#endif // IRMP_SUPPORT_JVC_PROTOCOL == 1 + { +#ifdef ANALYZE + ANALYZE_PRINTF ("protocol = NEC (repetition frame), start bit timings: pulse: %3d - %3d, pause: %3d - %3d\n", + NEC_START_BIT_PULSE_LEN_MIN, NEC_START_BIT_PULSE_LEN_MAX, + NEC_REPEAT_START_BIT_PAUSE_LEN_MIN, NEC_REPEAT_START_BIT_PAUSE_LEN_MAX); +#endif // ANALYZE + + irmp_param_p = (IRMP_PARAMETER *) &nec_rep_param; + } + } + else + +#if IRMP_SUPPORT_JVC_PROTOCOL == 1 + if (irmp_protocol == IRMP_JVC_PROTOCOL && // last protocol was JVC, awaiting repeat frame + irmp_pulse_time >= NEC_START_BIT_PULSE_LEN_MIN && irmp_pulse_time <= NEC_START_BIT_PULSE_LEN_MAX && + irmp_pause_time >= NEC_0_PAUSE_LEN_MIN && irmp_pause_time <= NEC_0_PAUSE_LEN_MAX) + { // it's JVC repetition type 3 +#ifdef ANALYZE + ANALYZE_PRINTF ("protocol = JVC repeat frame type 3, start bit timings: pulse: %3d - %3d, pause: %3d - %3d\n", + NEC_START_BIT_PULSE_LEN_MIN, NEC_START_BIT_PULSE_LEN_MAX, + NEC_0_PAUSE_LEN_MIN, NEC_0_PAUSE_LEN_MAX); +#endif // ANALYZE + irmp_param_p = (IRMP_PARAMETER *) &nec_param; + } + else +#endif // IRMP_SUPPORT_JVC_PROTOCOL == 1 + +#endif // IRMP_SUPPORT_NEC_PROTOCOL == 1 + +#if IRMP_SUPPORT_TELEFUNKEN_PROTOCOL == 1 + if (irmp_pulse_time >= TELEFUNKEN_START_BIT_PULSE_LEN_MIN && irmp_pulse_time <= TELEFUNKEN_START_BIT_PULSE_LEN_MAX && + irmp_pause_time >= TELEFUNKEN_START_BIT_PAUSE_LEN_MIN && irmp_pause_time <= TELEFUNKEN_START_BIT_PAUSE_LEN_MAX) + { +#ifdef ANALYZE + ANALYZE_PRINTF ("protocol = TELEFUNKEN, start bit timings: pulse: %3d - %3d, pause: %3d - %3d\n", + TELEFUNKEN_START_BIT_PULSE_LEN_MIN, TELEFUNKEN_START_BIT_PULSE_LEN_MAX, + TELEFUNKEN_START_BIT_PAUSE_LEN_MIN, TELEFUNKEN_START_BIT_PAUSE_LEN_MAX); +#endif // ANALYZE + irmp_param_p = (IRMP_PARAMETER *) &telefunken_param; + } + else +#endif // IRMP_SUPPORT_TELEFUNKEN_PROTOCOL == 1 + +#if IRMP_SUPPORT_ROOMBA_PROTOCOL == 1 + if (irmp_pulse_time >= ROOMBA_START_BIT_PULSE_LEN_MIN && irmp_pulse_time <= ROOMBA_START_BIT_PULSE_LEN_MAX && + irmp_pause_time >= ROOMBA_START_BIT_PAUSE_LEN_MIN && irmp_pause_time <= ROOMBA_START_BIT_PAUSE_LEN_MAX) + { +#ifdef ANALYZE + ANALYZE_PRINTF ("protocol = ROOMBA, start bit timings: pulse: %3d - %3d, pause: %3d - %3d\n", + ROOMBA_START_BIT_PULSE_LEN_MIN, ROOMBA_START_BIT_PULSE_LEN_MAX, + ROOMBA_START_BIT_PAUSE_LEN_MIN, ROOMBA_START_BIT_PAUSE_LEN_MAX); +#endif // ANALYZE + irmp_param_p = (IRMP_PARAMETER *) &roomba_param; + } + else +#endif // IRMP_SUPPORT_ROOMBA_PROTOCOL == 1 + +#if IRMP_SUPPORT_ACP24_PROTOCOL == 1 + if (irmp_pulse_time >= ACP24_START_BIT_PULSE_LEN_MIN && irmp_pulse_time <= ACP24_START_BIT_PULSE_LEN_MAX && + irmp_pause_time >= ACP24_START_BIT_PAUSE_LEN_MIN && irmp_pause_time <= ACP24_START_BIT_PAUSE_LEN_MAX) + { +#ifdef ANALYZE + ANALYZE_PRINTF ("protocol = ACP24, start bit timings: pulse: %3d - %3d, pause: %3d - %3d\n", + ACP24_START_BIT_PULSE_LEN_MIN, ACP24_START_BIT_PULSE_LEN_MAX, + ACP24_START_BIT_PAUSE_LEN_MIN, ACP24_START_BIT_PAUSE_LEN_MAX); +#endif // ANALYZE + irmp_param_p = (IRMP_PARAMETER *) &acp24_param; + } + else +#endif // IRMP_SUPPORT_ROOMBA_PROTOCOL == 1 + +#if IRMP_SUPPORT_PENTAX_PROTOCOL == 1 + if (irmp_pulse_time >= PENTAX_START_BIT_PULSE_LEN_MIN && irmp_pulse_time <= PENTAX_START_BIT_PULSE_LEN_MAX && + irmp_pause_time >= PENTAX_START_BIT_PAUSE_LEN_MIN && irmp_pause_time <= PENTAX_START_BIT_PAUSE_LEN_MAX) + { +#ifdef ANALYZE + ANALYZE_PRINTF ("protocol = PENTAX, start bit timings: pulse: %3d - %3d, pause: %3d - %3d\n", + PENTAX_START_BIT_PULSE_LEN_MIN, PENTAX_START_BIT_PULSE_LEN_MAX, + PENTAX_START_BIT_PAUSE_LEN_MIN, PENTAX_START_BIT_PAUSE_LEN_MAX); +#endif // ANALYZE + irmp_param_p = (IRMP_PARAMETER *) &pentax_param; + } + else +#endif // IRMP_SUPPORT_PENTAX_PROTOCOL == 1 + +#if IRMP_SUPPORT_NIKON_PROTOCOL == 1 + if (irmp_pulse_time >= NIKON_START_BIT_PULSE_LEN_MIN && irmp_pulse_time <= NIKON_START_BIT_PULSE_LEN_MAX && + irmp_pause_time >= NIKON_START_BIT_PAUSE_LEN_MIN && irmp_pause_time <= NIKON_START_BIT_PAUSE_LEN_MAX) + { +#ifdef ANALYZE + ANALYZE_PRINTF ("protocol = NIKON, start bit timings: pulse: %3d - %3d, pause: %3d - %3d\n", + NIKON_START_BIT_PULSE_LEN_MIN, NIKON_START_BIT_PULSE_LEN_MAX, + NIKON_START_BIT_PAUSE_LEN_MIN, NIKON_START_BIT_PAUSE_LEN_MAX); +#endif // ANALYZE + irmp_param_p = (IRMP_PARAMETER *) &nikon_param; + } + else +#endif // IRMP_SUPPORT_NIKON_PROTOCOL == 1 + +#if IRMP_SUPPORT_SAMSUNG_PROTOCOL == 1 + if (irmp_pulse_time >= SAMSUNG_START_BIT_PULSE_LEN_MIN && irmp_pulse_time <= SAMSUNG_START_BIT_PULSE_LEN_MAX && + irmp_pause_time >= SAMSUNG_START_BIT_PAUSE_LEN_MIN && irmp_pause_time <= SAMSUNG_START_BIT_PAUSE_LEN_MAX) + { // it's SAMSUNG +#ifdef ANALYZE + ANALYZE_PRINTF ("protocol = SAMSUNG, start bit timings: pulse: %3d - %3d, pause: %3d - %3d\n", + SAMSUNG_START_BIT_PULSE_LEN_MIN, SAMSUNG_START_BIT_PULSE_LEN_MAX, + SAMSUNG_START_BIT_PAUSE_LEN_MIN, SAMSUNG_START_BIT_PAUSE_LEN_MAX); +#endif // ANALYZE + irmp_param_p = (IRMP_PARAMETER *) &samsung_param; + } + else +#endif // IRMP_SUPPORT_SAMSUNG_PROTOCOL == 1 + +#if IRMP_SUPPORT_SAMSUNGAH_PROTOCOL == 1 + if (irmp_pulse_time >= SAMSUNGAH_START_BIT_PULSE_LEN_MIN && irmp_pulse_time <= SAMSUNGAH_START_BIT_PULSE_LEN_MAX && + irmp_pause_time >= SAMSUNGAH_START_BIT_PAUSE_LEN_MIN && irmp_pause_time <= SAMSUNGAH_START_BIT_PAUSE_LEN_MAX) + { // it's SAMSUNGAH +#ifdef ANALYZE + ANALYZE_PRINTF ("protocol = SAMSUNGAH, start bit timings: pulse: %3d - %3d, pause: %3d - %3d\n", + SAMSUNGAH_START_BIT_PULSE_LEN_MIN, SAMSUNGAH_START_BIT_PULSE_LEN_MAX, + SAMSUNGAH_START_BIT_PAUSE_LEN_MIN, SAMSUNGAH_START_BIT_PAUSE_LEN_MAX); +#endif // ANALYZE + irmp_param_p = (IRMP_PARAMETER *) &samsungah_param; + } + else +#endif // IRMP_SUPPORT_SAMSUNGAH_PROTOCOL == 1 + +#if IRMP_SUPPORT_MATSUSHITA_PROTOCOL == 1 + if (irmp_pulse_time >= MATSUSHITA_START_BIT_PULSE_LEN_MIN && irmp_pulse_time <= MATSUSHITA_START_BIT_PULSE_LEN_MAX && + irmp_pause_time >= MATSUSHITA_START_BIT_PAUSE_LEN_MIN && irmp_pause_time <= MATSUSHITA_START_BIT_PAUSE_LEN_MAX) + { // it's MATSUSHITA +#ifdef ANALYZE + ANALYZE_PRINTF ("protocol = MATSUSHITA, start bit timings: pulse: %3d - %3d, pause: %3d - %3d\n", + MATSUSHITA_START_BIT_PULSE_LEN_MIN, MATSUSHITA_START_BIT_PULSE_LEN_MAX, + MATSUSHITA_START_BIT_PAUSE_LEN_MIN, MATSUSHITA_START_BIT_PAUSE_LEN_MAX); +#endif // ANALYZE + irmp_param_p = (IRMP_PARAMETER *) &matsushita_param; + } + else +#endif // IRMP_SUPPORT_MATSUSHITA_PROTOCOL == 1 + +#if IRMP_SUPPORT_KASEIKYO_PROTOCOL == 1 + if (irmp_pulse_time >= KASEIKYO_START_BIT_PULSE_LEN_MIN && irmp_pulse_time <= KASEIKYO_START_BIT_PULSE_LEN_MAX && + irmp_pause_time >= KASEIKYO_START_BIT_PAUSE_LEN_MIN && irmp_pause_time <= KASEIKYO_START_BIT_PAUSE_LEN_MAX) + { // it's KASEIKYO +#ifdef ANALYZE + ANALYZE_PRINTF ("protocol = KASEIKYO, start bit timings: pulse: %3d - %3d, pause: %3d - %3d\n", + KASEIKYO_START_BIT_PULSE_LEN_MIN, KASEIKYO_START_BIT_PULSE_LEN_MAX, + KASEIKYO_START_BIT_PAUSE_LEN_MIN, KASEIKYO_START_BIT_PAUSE_LEN_MAX); +#endif // ANALYZE + irmp_param_p = (IRMP_PARAMETER *) &kaseikyo_param; + } + else +#endif // IRMP_SUPPORT_KASEIKYO_PROTOCOL == 1 + +#if IRMP_SUPPORT_PANASONIC_PROTOCOL == 1 + if (irmp_pulse_time >= PANASONIC_START_BIT_PULSE_LEN_MIN && irmp_pulse_time <= PANASONIC_START_BIT_PULSE_LEN_MAX && + irmp_pause_time >= PANASONIC_START_BIT_PAUSE_LEN_MIN && irmp_pause_time <= PANASONIC_START_BIT_PAUSE_LEN_MAX) + { // it's PANASONIC +#ifdef ANALYZE + ANALYZE_PRINTF ("protocol = PANASONIC, start bit timings: pulse: %3d - %3d, pause: %3d - %3d\n", + PANASONIC_START_BIT_PULSE_LEN_MIN, PANASONIC_START_BIT_PULSE_LEN_MAX, + PANASONIC_START_BIT_PAUSE_LEN_MIN, PANASONIC_START_BIT_PAUSE_LEN_MAX); +#endif // ANALYZE + irmp_param_p = (IRMP_PARAMETER *) &panasonic_param; + } + else +#endif // IRMP_SUPPORT_PANASONIC_PROTOCOL == 1 + +#if IRMP_SUPPORT_MITSU_HEAVY_PROTOCOL == 1 + if (irmp_pulse_time >= MITSU_HEAVY_START_BIT_PULSE_LEN_MIN && irmp_pulse_time <= MITSU_HEAVY_START_BIT_PULSE_LEN_MAX && + irmp_pause_time >= MITSU_HEAVY_START_BIT_PAUSE_LEN_MIN && irmp_pause_time <= MITSU_HEAVY_START_BIT_PAUSE_LEN_MAX) + { // it's MITSU_HEAVY +#ifdef ANALYZE + ANALYZE_PRINTF ("protocol = MITSU_HEAVY, start bit timings: pulse: %3d - %3d, pause: %3d - %3d\n", + MITSU_HEAVY_START_BIT_PULSE_LEN_MIN, MITSU_HEAVY_START_BIT_PULSE_LEN_MAX, + MITSU_HEAVY_START_BIT_PAUSE_LEN_MIN, MITSU_HEAVY_START_BIT_PAUSE_LEN_MAX); +#endif // ANALYZE + irmp_param_p = (IRMP_PARAMETER *) &mitsu_heavy_param; + } + else +#endif // IRMP_SUPPORT_MITSU_HEAVY_PROTOCOL == 1 + +#if IRMP_SUPPORT_VINCENT_PROTOCOL == 1 + if (irmp_pulse_time >= VINCENT_START_BIT_PULSE_LEN_MIN && irmp_pulse_time <= VINCENT_START_BIT_PULSE_LEN_MAX && + irmp_pause_time >= VINCENT_START_BIT_PAUSE_LEN_MIN && irmp_pause_time <= VINCENT_START_BIT_PAUSE_LEN_MAX) + { // it's VINCENT +#ifdef ANALYZE + ANALYZE_PRINTF ("protocol = VINCENT, start bit timings: pulse: %3d - %3d, pause: %3d - %3d\n", + VINCENT_START_BIT_PULSE_LEN_MIN, VINCENT_START_BIT_PULSE_LEN_MAX, + VINCENT_START_BIT_PAUSE_LEN_MIN, VINCENT_START_BIT_PAUSE_LEN_MAX); +#endif // ANALYZE + irmp_param_p = (IRMP_PARAMETER *) &vincent_param; + } + else +#endif // IRMP_SUPPORT_VINCENT_PROTOCOL == 1 + +#if IRMP_SUPPORT_METZ_PROTOCOL == 1 + if (irmp_pulse_time >= METZ_START_BIT_PULSE_LEN_MIN && irmp_pulse_time <= METZ_START_BIT_PULSE_LEN_MAX && + irmp_pause_time >= METZ_START_BIT_PAUSE_LEN_MIN && irmp_pause_time <= METZ_START_BIT_PAUSE_LEN_MAX) + { +#ifdef ANALYZE + ANALYZE_PRINTF ("protocol = METZ, start bit timings: pulse: %3d - %3d, pause: %3d - %3d\n", + METZ_START_BIT_PULSE_LEN_MIN, METZ_START_BIT_PULSE_LEN_MAX, + METZ_START_BIT_PAUSE_LEN_MIN, METZ_START_BIT_PAUSE_LEN_MAX); +#endif // ANALYZE + irmp_param_p = (IRMP_PARAMETER *) &metz_param; + } + else +#endif // IRMP_SUPPORT_METZ_PROTOCOL == 1 + +#if IRMP_SUPPORT_RADIO1_PROTOCOL == 1 + if (irmp_pulse_time >= RADIO1_START_BIT_PULSE_LEN_MIN && irmp_pulse_time <= RADIO1_START_BIT_PULSE_LEN_MAX && + irmp_pause_time >= RADIO1_START_BIT_PAUSE_LEN_MIN && irmp_pause_time <= RADIO1_START_BIT_PAUSE_LEN_MAX) + { +#ifdef ANALYZE + ANALYZE_PRINTF ("protocol = RADIO1, start bit timings: pulse: %3d - %3d, pause: %3d - %3d\n", + RADIO1_START_BIT_PULSE_LEN_MIN, RADIO1_START_BIT_PULSE_LEN_MAX, + RADIO1_START_BIT_PAUSE_LEN_MIN, RADIO1_START_BIT_PAUSE_LEN_MAX); +#endif // ANALYZE + irmp_param_p = (IRMP_PARAMETER *) &radio1_param; + } + else +#endif // IRMP_SUPPORT_RRADIO1_PROTOCOL == 1 + +#if IRMP_SUPPORT_RECS80_PROTOCOL == 1 + if (irmp_pulse_time >= RECS80_START_BIT_PULSE_LEN_MIN && irmp_pulse_time <= RECS80_START_BIT_PULSE_LEN_MAX && + irmp_pause_time >= RECS80_START_BIT_PAUSE_LEN_MIN && irmp_pause_time <= RECS80_START_BIT_PAUSE_LEN_MAX) + { // it's RECS80 +#ifdef ANALYZE + ANALYZE_PRINTF ("protocol = RECS80, start bit timings: pulse: %3d - %3d, pause: %3d - %3d\n", + RECS80_START_BIT_PULSE_LEN_MIN, RECS80_START_BIT_PULSE_LEN_MAX, + RECS80_START_BIT_PAUSE_LEN_MIN, RECS80_START_BIT_PAUSE_LEN_MAX); +#endif // ANALYZE + irmp_param_p = (IRMP_PARAMETER *) &recs80_param; + } + else +#endif // IRMP_SUPPORT_RECS80_PROTOCOL == 1 + +#if IRMP_SUPPORT_S100_PROTOCOL == 1 + if (((irmp_pulse_time >= S100_START_BIT_LEN_MIN && irmp_pulse_time <= S100_START_BIT_LEN_MAX) || + (irmp_pulse_time >= 2 * S100_START_BIT_LEN_MIN && irmp_pulse_time <= 2 * S100_START_BIT_LEN_MAX)) && + ((irmp_pause_time >= S100_START_BIT_LEN_MIN && irmp_pause_time <= S100_START_BIT_LEN_MAX) || + (irmp_pause_time >= 2 * S100_START_BIT_LEN_MIN && irmp_pause_time <= 2 * S100_START_BIT_LEN_MAX))) + { // it's S100 +#ifdef ANALYZE + ANALYZE_PRINTF ("protocol = S100, start bit timings: pulse: %3d - %3d, pause: %3d - %3d or pulse: %3d - %3d, pause: %3d - %3d\n", + S100_START_BIT_LEN_MIN, S100_START_BIT_LEN_MAX, + 2 * S100_START_BIT_LEN_MIN, 2 * S100_START_BIT_LEN_MAX, + S100_START_BIT_LEN_MIN, S100_START_BIT_LEN_MAX, + 2 * S100_START_BIT_LEN_MIN, 2 * S100_START_BIT_LEN_MAX); +#endif // ANALYZE + + irmp_param_p = (IRMP_PARAMETER *) &s100_param; + last_pause = irmp_pause_time; + + if ((irmp_pulse_time > S100_START_BIT_LEN_MAX && irmp_pulse_time <= 2 * S100_START_BIT_LEN_MAX) || + (irmp_pause_time > S100_START_BIT_LEN_MAX && irmp_pause_time <= 2 * S100_START_BIT_LEN_MAX)) + { + last_value = 0; + rc5_cmd_bit6 = 1<<6; + } + else + { + last_value = 1; + } + } + else +#endif // IRMP_SUPPORT_S100_PROTOCOL == 1 + +#if IRMP_SUPPORT_RC5_PROTOCOL == 1 + if (((irmp_pulse_time >= RC5_START_BIT_LEN_MIN && irmp_pulse_time <= RC5_START_BIT_LEN_MAX) || + (irmp_pulse_time >= 2 * RC5_START_BIT_LEN_MIN && irmp_pulse_time <= 2 * RC5_START_BIT_LEN_MAX)) && + ((irmp_pause_time >= RC5_START_BIT_LEN_MIN && irmp_pause_time <= RC5_START_BIT_LEN_MAX) || + (irmp_pause_time >= 2 * RC5_START_BIT_LEN_MIN && irmp_pause_time <= 2 * RC5_START_BIT_LEN_MAX))) + { // it's RC5 +#if IRMP_SUPPORT_FDC_PROTOCOL == 1 + if (irmp_pulse_time >= FDC_START_BIT_PULSE_LEN_MIN && irmp_pulse_time <= FDC_START_BIT_PULSE_LEN_MAX && + irmp_pause_time >= FDC_START_BIT_PAUSE_LEN_MIN && irmp_pause_time <= FDC_START_BIT_PAUSE_LEN_MAX) + { +#ifdef ANALYZE + ANALYZE_PRINTF ("protocol = RC5 or FDC\n"); + ANALYZE_PRINTF ("FDC start bit timings: pulse: %3d - %3d, pause: %3d - %3d\n", + FDC_START_BIT_PULSE_LEN_MIN, FDC_START_BIT_PULSE_LEN_MAX, + FDC_START_BIT_PAUSE_LEN_MIN, FDC_START_BIT_PAUSE_LEN_MAX); + ANALYZE_PRINTF ("RC5 start bit timings: pulse: %3d - %3d, pause: %3d - %3d\n", + RC5_START_BIT_LEN_MIN, RC5_START_BIT_LEN_MAX, + RC5_START_BIT_LEN_MIN, RC5_START_BIT_LEN_MAX); +#endif // ANALYZE + memcpy_P (&irmp_param2, &fdc_param, sizeof (IRMP_PARAMETER)); + } + else +#endif // IRMP_SUPPORT_FDC_PROTOCOL == 1 + +#if IRMP_SUPPORT_RCCAR_PROTOCOL == 1 + if (irmp_pulse_time >= RCCAR_START_BIT_PULSE_LEN_MIN && irmp_pulse_time <= RCCAR_START_BIT_PULSE_LEN_MAX && + irmp_pause_time >= RCCAR_START_BIT_PAUSE_LEN_MIN && irmp_pause_time <= RCCAR_START_BIT_PAUSE_LEN_MAX) + { +#ifdef ANALYZE + ANALYZE_PRINTF ("protocol = RC5 or RCCAR\n"); + ANALYZE_PRINTF ("RCCAR start bit timings: pulse: %3d - %3d, pause: %3d - %3d\n", + RCCAR_START_BIT_PULSE_LEN_MIN, RCCAR_START_BIT_PULSE_LEN_MAX, + RCCAR_START_BIT_PAUSE_LEN_MIN, RCCAR_START_BIT_PAUSE_LEN_MAX); + ANALYZE_PRINTF ("RC5 start bit timings: pulse: %3d - %3d, pause: %3d - %3d\n", + RC5_START_BIT_LEN_MIN, RC5_START_BIT_LEN_MAX, + RC5_START_BIT_LEN_MIN, RC5_START_BIT_LEN_MAX); +#endif // ANALYZE + memcpy_P (&irmp_param2, &rccar_param, sizeof (IRMP_PARAMETER)); + } + else +#endif // IRMP_SUPPORT_RCCAR_PROTOCOL == 1 + { +#ifdef ANALYZE + ANALYZE_PRINTF ("protocol = RC5, start bit timings: pulse: %3d - %3d, pause: %3d - %3d or pulse: %3d - %3d, pause: %3d - %3d\n", + RC5_START_BIT_LEN_MIN, RC5_START_BIT_LEN_MAX, + 2 * RC5_START_BIT_LEN_MIN, 2 * RC5_START_BIT_LEN_MAX, + RC5_START_BIT_LEN_MIN, RC5_START_BIT_LEN_MAX, + 2 * RC5_START_BIT_LEN_MIN, 2 * RC5_START_BIT_LEN_MAX); +#endif // ANALYZE + } + + irmp_param_p = (IRMP_PARAMETER *) &rc5_param; + last_pause = irmp_pause_time; + + if ((irmp_pulse_time > RC5_START_BIT_LEN_MAX && irmp_pulse_time <= 2 * RC5_START_BIT_LEN_MAX) || + (irmp_pause_time > RC5_START_BIT_LEN_MAX && irmp_pause_time <= 2 * RC5_START_BIT_LEN_MAX)) + { + last_value = 0; + rc5_cmd_bit6 = 1<<6; + } + else + { + last_value = 1; + } + } + else +#endif // IRMP_SUPPORT_RC5_PROTOCOL == 1 + +#if IRMP_SUPPORT_RCII_PROTOCOL == 1 + if ((irmp_pulse_time >= RCII_START_BIT_PULSE_LEN_MIN && irmp_pulse_time <= RCII_START_BIT_PULSE_LEN_MAX) && + (irmp_pause_time >= RCII_START_BIT_PAUSE_LEN_MIN && irmp_pause_time <= RCII_START_BIT_PAUSE_LEN_MAX)) + { // it's RCII +#ifdef ANALYZE + ANALYZE_PRINTF ("protocol = RCII, start bit timings: pulse: %3d - %3d, pause: %3d - %3d\n", + RCII_START_BIT_PULSE_LEN_MIN, RCII_START_BIT_PULSE_LEN_MAX, + RCII_START_BIT_PAUSE_LEN_MIN, RCII_START_BIT_PAUSE_LEN_MAX) +#endif // ANALYZE + irmp_param_p = (IRMP_PARAMETER *) &rcii_param; + last_pause = irmp_pause_time; + waiting_for_2nd_pulse = 1; + last_value = 1; + } + else +#endif // IRMP_SUPPORT_RCII_PROTOCOL == 1 + +#if IRMP_SUPPORT_DENON_PROTOCOL == 1 + if ( (irmp_pulse_time >= DENON_PULSE_LEN_MIN && irmp_pulse_time <= DENON_PULSE_LEN_MAX) && + ((irmp_pause_time >= DENON_1_PAUSE_LEN_MIN && irmp_pause_time <= DENON_1_PAUSE_LEN_MAX) || + (irmp_pause_time >= DENON_0_PAUSE_LEN_MIN && irmp_pause_time <= DENON_0_PAUSE_LEN_MAX))) + { // it's DENON +#ifdef ANALYZE + ANALYZE_PRINTF ("protocol = DENON, start bit timings: pulse: %3d - %3d, pause: %3d - %3d or %3d - %3d\n", + DENON_PULSE_LEN_MIN, DENON_PULSE_LEN_MAX, + DENON_1_PAUSE_LEN_MIN, DENON_1_PAUSE_LEN_MAX, + DENON_0_PAUSE_LEN_MIN, DENON_0_PAUSE_LEN_MAX); +#endif // ANALYZE + irmp_param_p = (IRMP_PARAMETER *) &denon_param; + } + else +#endif // IRMP_SUPPORT_DENON_PROTOCOL == 1 + +#if IRMP_SUPPORT_THOMSON_PROTOCOL == 1 + if ( (irmp_pulse_time >= THOMSON_PULSE_LEN_MIN && irmp_pulse_time <= THOMSON_PULSE_LEN_MAX) && + ((irmp_pause_time >= THOMSON_1_PAUSE_LEN_MIN && irmp_pause_time <= THOMSON_1_PAUSE_LEN_MAX) || + (irmp_pause_time >= THOMSON_0_PAUSE_LEN_MIN && irmp_pause_time <= THOMSON_0_PAUSE_LEN_MAX))) + { // it's THOMSON +#ifdef ANALYZE + ANALYZE_PRINTF ("protocol = THOMSON, start bit timings: pulse: %3d - %3d, pause: %3d - %3d or %3d - %3d\n", + THOMSON_PULSE_LEN_MIN, THOMSON_PULSE_LEN_MAX, + THOMSON_1_PAUSE_LEN_MIN, THOMSON_1_PAUSE_LEN_MAX, + THOMSON_0_PAUSE_LEN_MIN, THOMSON_0_PAUSE_LEN_MAX); +#endif // ANALYZE + irmp_param_p = (IRMP_PARAMETER *) &thomson_param; + } + else +#endif // IRMP_SUPPORT_THOMSON_PROTOCOL == 1 + +#if IRMP_SUPPORT_BOSE_PROTOCOL == 1 + if (irmp_pulse_time >= BOSE_START_BIT_PULSE_LEN_MIN && irmp_pulse_time <= BOSE_START_BIT_PULSE_LEN_MAX && + irmp_pause_time >= BOSE_START_BIT_PAUSE_LEN_MIN && irmp_pause_time <= BOSE_START_BIT_PAUSE_LEN_MAX) + { +#ifdef ANALYZE + ANALYZE_PRINTF ("protocol = BOSE, start bit timings: pulse: %3d - %3d, pause: %3d - %3d\n", + BOSE_START_BIT_PULSE_LEN_MIN, BOSE_START_BIT_PULSE_LEN_MAX, + BOSE_START_BIT_PAUSE_LEN_MIN, BOSE_START_BIT_PAUSE_LEN_MAX); +#endif // ANALYZE + irmp_param_p = (IRMP_PARAMETER *) &bose_param; + } + else +#endif // IRMP_SUPPORT_BOSE_PROTOCOL == 1 + +#if IRMP_SUPPORT_RC6_PROTOCOL == 1 + if (irmp_pulse_time >= RC6_START_BIT_PULSE_LEN_MIN && irmp_pulse_time <= RC6_START_BIT_PULSE_LEN_MAX && + irmp_pause_time >= RC6_START_BIT_PAUSE_LEN_MIN && irmp_pause_time <= RC6_START_BIT_PAUSE_LEN_MAX) + { // it's RC6 +#ifdef ANALYZE + ANALYZE_PRINTF ("protocol = RC6, start bit timings: pulse: %3d - %3d, pause: %3d - %3d\n", + RC6_START_BIT_PULSE_LEN_MIN, RC6_START_BIT_PULSE_LEN_MAX, + RC6_START_BIT_PAUSE_LEN_MIN, RC6_START_BIT_PAUSE_LEN_MAX); +#endif // ANALYZE + irmp_param_p = (IRMP_PARAMETER *) &rc6_param; + last_pause = 0; + last_value = 1; + } + else +#endif // IRMP_SUPPORT_RC6_PROTOCOL == 1 + +#if IRMP_SUPPORT_RECS80EXT_PROTOCOL == 1 + if (irmp_pulse_time >= RECS80EXT_START_BIT_PULSE_LEN_MIN && irmp_pulse_time <= RECS80EXT_START_BIT_PULSE_LEN_MAX && + irmp_pause_time >= RECS80EXT_START_BIT_PAUSE_LEN_MIN && irmp_pause_time <= RECS80EXT_START_BIT_PAUSE_LEN_MAX) + { // it's RECS80EXT +#ifdef ANALYZE + ANALYZE_PRINTF ("protocol = RECS80EXT, start bit timings: pulse: %3d - %3d, pause: %3d - %3d\n", + RECS80EXT_START_BIT_PULSE_LEN_MIN, RECS80EXT_START_BIT_PULSE_LEN_MAX, + RECS80EXT_START_BIT_PAUSE_LEN_MIN, RECS80EXT_START_BIT_PAUSE_LEN_MAX); +#endif // ANALYZE + irmp_param_p = (IRMP_PARAMETER *) &recs80ext_param; + } + else +#endif // IRMP_SUPPORT_RECS80EXT_PROTOCOL == 1 + +#if IRMP_SUPPORT_NUBERT_PROTOCOL == 1 + if (irmp_pulse_time >= NUBERT_START_BIT_PULSE_LEN_MIN && irmp_pulse_time <= NUBERT_START_BIT_PULSE_LEN_MAX && + irmp_pause_time >= NUBERT_START_BIT_PAUSE_LEN_MIN && irmp_pause_time <= NUBERT_START_BIT_PAUSE_LEN_MAX) + { // it's NUBERT +#ifdef ANALYZE + ANALYZE_PRINTF ("protocol = NUBERT, start bit timings: pulse: %3d - %3d, pause: %3d - %3d\n", + NUBERT_START_BIT_PULSE_LEN_MIN, NUBERT_START_BIT_PULSE_LEN_MAX, + NUBERT_START_BIT_PAUSE_LEN_MIN, NUBERT_START_BIT_PAUSE_LEN_MAX); +#endif // ANALYZE + irmp_param_p = (IRMP_PARAMETER *) &nubert_param; + } + else +#endif // IRMP_SUPPORT_NUBERT_PROTOCOL == 1 + +#if IRMP_SUPPORT_FAN_PROTOCOL == 1 + if (irmp_pulse_time >= FAN_START_BIT_PULSE_LEN_MIN && irmp_pulse_time <= FAN_START_BIT_PULSE_LEN_MAX && + irmp_pause_time >= FAN_START_BIT_PAUSE_LEN_MIN && irmp_pause_time <= FAN_START_BIT_PAUSE_LEN_MAX) + { // it's FAN +#ifdef ANALYZE + ANALYZE_PRINTF ("protocol = FAN, start bit timings: pulse: %3d - %3d, pause: %3d - %3d\n", + FAN_START_BIT_PULSE_LEN_MIN, FAN_START_BIT_PULSE_LEN_MAX, + FAN_START_BIT_PAUSE_LEN_MIN, FAN_START_BIT_PAUSE_LEN_MAX); +#endif // ANALYZE + irmp_param_p = (IRMP_PARAMETER *) &fan_param; + } + else +#endif // IRMP_SUPPORT_FAN_PROTOCOL == 1 + +#if IRMP_SUPPORT_SPEAKER_PROTOCOL == 1 + if (irmp_pulse_time >= SPEAKER_START_BIT_PULSE_LEN_MIN && irmp_pulse_time <= SPEAKER_START_BIT_PULSE_LEN_MAX && + irmp_pause_time >= SPEAKER_START_BIT_PAUSE_LEN_MIN && irmp_pause_time <= SPEAKER_START_BIT_PAUSE_LEN_MAX) + { // it's SPEAKER +#ifdef ANALYZE + ANALYZE_PRINTF ("protocol = SPEAKER, start bit timings: pulse: %3d - %3d, pause: %3d - %3d\n", + SPEAKER_START_BIT_PULSE_LEN_MIN, SPEAKER_START_BIT_PULSE_LEN_MAX, + SPEAKER_START_BIT_PAUSE_LEN_MIN, SPEAKER_START_BIT_PAUSE_LEN_MAX); +#endif // ANALYZE + irmp_param_p = (IRMP_PARAMETER *) &speaker_param; + } + else +#endif // IRMP_SUPPORT_SPEAKER_PROTOCOL == 1 + +#if IRMP_SUPPORT_BANG_OLUFSEN_PROTOCOL == 1 + if (irmp_pulse_time >= BANG_OLUFSEN_START_BIT1_PULSE_LEN_MIN && irmp_pulse_time <= BANG_OLUFSEN_START_BIT1_PULSE_LEN_MAX && + irmp_pause_time >= BANG_OLUFSEN_START_BIT1_PAUSE_LEN_MIN && irmp_pause_time <= BANG_OLUFSEN_START_BIT1_PAUSE_LEN_MAX) + { // it's BANG_OLUFSEN +#ifdef ANALYZE + ANALYZE_PRINTF ("protocol = BANG_OLUFSEN\n"); + ANALYZE_PRINTF ("start bit 1 timings: pulse: %3d - %3d, pause: %3d - %3d\n", + BANG_OLUFSEN_START_BIT1_PULSE_LEN_MIN, BANG_OLUFSEN_START_BIT1_PULSE_LEN_MAX, + BANG_OLUFSEN_START_BIT1_PAUSE_LEN_MIN, BANG_OLUFSEN_START_BIT1_PAUSE_LEN_MAX); + ANALYZE_PRINTF ("start bit 2 timings: pulse: %3d - %3d, pause: %3d - %3d\n", + BANG_OLUFSEN_START_BIT2_PULSE_LEN_MIN, BANG_OLUFSEN_START_BIT2_PULSE_LEN_MAX, + BANG_OLUFSEN_START_BIT2_PAUSE_LEN_MIN, BANG_OLUFSEN_START_BIT2_PAUSE_LEN_MAX); + ANALYZE_PRINTF ("start bit 3 timings: pulse: %3d - %3d, pause: %3d - %3d\n", + BANG_OLUFSEN_START_BIT3_PULSE_LEN_MIN, BANG_OLUFSEN_START_BIT3_PULSE_LEN_MAX, + BANG_OLUFSEN_START_BIT3_PAUSE_LEN_MIN, BANG_OLUFSEN_START_BIT3_PAUSE_LEN_MAX); + ANALYZE_PRINTF ("start bit 4 timings: pulse: %3d - %3d, pause: %3d - %3d\n", + BANG_OLUFSEN_START_BIT4_PULSE_LEN_MIN, BANG_OLUFSEN_START_BIT4_PULSE_LEN_MAX, + BANG_OLUFSEN_START_BIT4_PAUSE_LEN_MIN, BANG_OLUFSEN_START_BIT4_PAUSE_LEN_MAX); +#endif // ANALYZE + irmp_param_p = (IRMP_PARAMETER *) &bang_olufsen_param; + last_value = 0; + } + else +#endif // IRMP_SUPPORT_BANG_OLUFSEN_PROTOCOL == 1 + +#if IRMP_SUPPORT_GRUNDIG_NOKIA_IR60_PROTOCOL == 1 + if (irmp_pulse_time >= GRUNDIG_NOKIA_IR60_START_BIT_LEN_MIN && irmp_pulse_time <= GRUNDIG_NOKIA_IR60_START_BIT_LEN_MAX && + irmp_pause_time >= GRUNDIG_NOKIA_IR60_PRE_PAUSE_LEN_MIN && irmp_pause_time <= GRUNDIG_NOKIA_IR60_PRE_PAUSE_LEN_MAX) + { // it's GRUNDIG +#ifdef ANALYZE + ANALYZE_PRINTF ("protocol = GRUNDIG, pre bit timings: pulse: %3d - %3d, pause: %3d - %3d\n", + GRUNDIG_NOKIA_IR60_START_BIT_LEN_MIN, GRUNDIG_NOKIA_IR60_START_BIT_LEN_MAX, + GRUNDIG_NOKIA_IR60_PRE_PAUSE_LEN_MIN, GRUNDIG_NOKIA_IR60_PRE_PAUSE_LEN_MAX); +#endif // ANALYZE + irmp_param_p = (IRMP_PARAMETER *) &grundig_param; + last_pause = irmp_pause_time; + last_value = 1; + } + else +#endif // IRMP_SUPPORT_GRUNDIG_NOKIA_IR60_PROTOCOL == 1 + +#if IRMP_SUPPORT_MERLIN_PROTOCOL == 1 // check MERLIN before RUWIDO! + if (irmp_pulse_time >= MERLIN_START_BIT_PULSE_LEN_MIN && irmp_pulse_time <= MERLIN_START_BIT_PULSE_LEN_MAX && + irmp_pause_time >= MERLIN_START_BIT_PAUSE_LEN_MIN && irmp_pause_time <= MERLIN_START_BIT_PAUSE_LEN_MAX) + { // it's MERLIN +#ifdef ANALYZE + ANALYZE_PRINTF ("protocol = MERLIN, start bit timings: pulse: %3d - %3d, pause: %3d - %3d\n", + MERLIN_START_BIT_PULSE_LEN_MIN, MERLIN_START_BIT_PULSE_LEN_MAX, + MERLIN_START_BIT_PAUSE_LEN_MIN, MERLIN_START_BIT_PAUSE_LEN_MAX); +#endif // ANALYZE + irmp_param_p = (IRMP_PARAMETER *) &merlin_param; + last_pause = irmp_pause_time; + last_value = 1; + } + else +#endif // IRMP_SUPPORT_MERLIN_PROTOCOL == 1 + +#if IRMP_SUPPORT_SIEMENS_OR_RUWIDO_PROTOCOL == 1 + if (((irmp_pulse_time >= SIEMENS_OR_RUWIDO_START_BIT_PULSE_LEN_MIN && irmp_pulse_time <= SIEMENS_OR_RUWIDO_START_BIT_PULSE_LEN_MAX) || + (irmp_pulse_time >= 2 * SIEMENS_OR_RUWIDO_START_BIT_PULSE_LEN_MIN && irmp_pulse_time <= 2 * SIEMENS_OR_RUWIDO_START_BIT_PULSE_LEN_MAX)) && + ((irmp_pause_time >= SIEMENS_OR_RUWIDO_START_BIT_PAUSE_LEN_MIN && irmp_pause_time <= SIEMENS_OR_RUWIDO_START_BIT_PAUSE_LEN_MAX) || + (irmp_pause_time >= 2 * SIEMENS_OR_RUWIDO_START_BIT_PAUSE_LEN_MIN && irmp_pause_time <= 2 * SIEMENS_OR_RUWIDO_START_BIT_PAUSE_LEN_MAX))) + { // it's RUWIDO or SIEMENS +#ifdef ANALYZE + ANALYZE_PRINTF ("protocol = RUWIDO, start bit timings: pulse: %3d - %3d or %3d - %3d, pause: %3d - %3d or %3d - %3d\n", + SIEMENS_OR_RUWIDO_START_BIT_PULSE_LEN_MIN, SIEMENS_OR_RUWIDO_START_BIT_PULSE_LEN_MAX, + 2 * SIEMENS_OR_RUWIDO_START_BIT_PULSE_LEN_MIN, 2 * SIEMENS_OR_RUWIDO_START_BIT_PULSE_LEN_MAX, + SIEMENS_OR_RUWIDO_START_BIT_PAUSE_LEN_MIN, SIEMENS_OR_RUWIDO_START_BIT_PAUSE_LEN_MAX, + 2 * SIEMENS_OR_RUWIDO_START_BIT_PAUSE_LEN_MIN, 2 * SIEMENS_OR_RUWIDO_START_BIT_PAUSE_LEN_MAX); +#endif // ANALYZE + irmp_param_p = (IRMP_PARAMETER *) &ruwido_param; + last_pause = irmp_pause_time; + last_value = 1; + } + else +#endif // IRMP_SUPPORT_SIEMENS_OR_RUWIDO_PROTOCOL == 1 + +#if IRMP_SUPPORT_FDC_PROTOCOL == 1 + if (irmp_pulse_time >= FDC_START_BIT_PULSE_LEN_MIN && irmp_pulse_time <= FDC_START_BIT_PULSE_LEN_MAX && + irmp_pause_time >= FDC_START_BIT_PAUSE_LEN_MIN && irmp_pause_time <= FDC_START_BIT_PAUSE_LEN_MAX) + { +#ifdef ANALYZE + ANALYZE_PRINTF ("protocol = FDC, start bit timings: pulse: %3d - %3d, pause: %3d - %3d\n", + FDC_START_BIT_PULSE_LEN_MIN, FDC_START_BIT_PULSE_LEN_MAX, + FDC_START_BIT_PAUSE_LEN_MIN, FDC_START_BIT_PAUSE_LEN_MAX); +#endif // ANALYZE + irmp_param_p = (IRMP_PARAMETER *) &fdc_param; + } + else +#endif // IRMP_SUPPORT_FDC_PROTOCOL == 1 + +#if IRMP_SUPPORT_RCCAR_PROTOCOL == 1 + if (irmp_pulse_time >= RCCAR_START_BIT_PULSE_LEN_MIN && irmp_pulse_time <= RCCAR_START_BIT_PULSE_LEN_MAX && + irmp_pause_time >= RCCAR_START_BIT_PAUSE_LEN_MIN && irmp_pause_time <= RCCAR_START_BIT_PAUSE_LEN_MAX) + { +#ifdef ANALYZE + ANALYZE_PRINTF ("protocol = RCCAR, start bit timings: pulse: %3d - %3d, pause: %3d - %3d\n", + RCCAR_START_BIT_PULSE_LEN_MIN, RCCAR_START_BIT_PULSE_LEN_MAX, + RCCAR_START_BIT_PAUSE_LEN_MIN, RCCAR_START_BIT_PAUSE_LEN_MAX); +#endif // ANALYZE + irmp_param_p = (IRMP_PARAMETER *) &rccar_param; + } + else +#endif // IRMP_SUPPORT_RCCAR_PROTOCOL == 1 + +#if IRMP_SUPPORT_KATHREIN_PROTOCOL == 1 + if (irmp_pulse_time >= KATHREIN_START_BIT_PULSE_LEN_MIN && irmp_pulse_time <= KATHREIN_START_BIT_PULSE_LEN_MAX && + irmp_pause_time >= KATHREIN_START_BIT_PAUSE_LEN_MIN && irmp_pause_time <= KATHREIN_START_BIT_PAUSE_LEN_MAX) + { // it's KATHREIN +#ifdef ANALYZE + ANALYZE_PRINTF ("protocol = KATHREIN, start bit timings: pulse: %3d - %3d, pause: %3d - %3d\n", + KATHREIN_START_BIT_PULSE_LEN_MIN, KATHREIN_START_BIT_PULSE_LEN_MAX, + KATHREIN_START_BIT_PAUSE_LEN_MIN, KATHREIN_START_BIT_PAUSE_LEN_MAX); +#endif // ANALYZE + irmp_param_p = (IRMP_PARAMETER *) &kathrein_param; + } + else +#endif // IRMP_SUPPORT_KATHREIN_PROTOCOL == 1 + +#if IRMP_SUPPORT_NETBOX_PROTOCOL == 1 + if (irmp_pulse_time >= NETBOX_START_BIT_PULSE_LEN_MIN && irmp_pulse_time <= NETBOX_START_BIT_PULSE_LEN_MAX && + irmp_pause_time >= NETBOX_START_BIT_PAUSE_LEN_MIN && irmp_pause_time <= NETBOX_START_BIT_PAUSE_LEN_MAX) + { // it's NETBOX +#ifdef ANALYZE + ANALYZE_PRINTF ("protocol = NETBOX, start bit timings: pulse: %3d - %3d, pause: %3d - %3d\n", + NETBOX_START_BIT_PULSE_LEN_MIN, NETBOX_START_BIT_PULSE_LEN_MAX, + NETBOX_START_BIT_PAUSE_LEN_MIN, NETBOX_START_BIT_PAUSE_LEN_MAX); +#endif // ANALYZE + irmp_param_p = (IRMP_PARAMETER *) &netbox_param; + } + else +#endif // IRMP_SUPPORT_NETBOX_PROTOCOL == 1 + +#if IRMP_SUPPORT_LEGO_PROTOCOL == 1 + if (irmp_pulse_time >= LEGO_START_BIT_PULSE_LEN_MIN && irmp_pulse_time <= LEGO_START_BIT_PULSE_LEN_MAX && + irmp_pause_time >= LEGO_START_BIT_PAUSE_LEN_MIN && irmp_pause_time <= LEGO_START_BIT_PAUSE_LEN_MAX) + { +#ifdef ANALYZE + ANALYZE_PRINTF ("protocol = LEGO, start bit timings: pulse: %3d - %3d, pause: %3d - %3d\n", + LEGO_START_BIT_PULSE_LEN_MIN, LEGO_START_BIT_PULSE_LEN_MAX, + LEGO_START_BIT_PAUSE_LEN_MIN, LEGO_START_BIT_PAUSE_LEN_MAX); +#endif // ANALYZE + irmp_param_p = (IRMP_PARAMETER *) &lego_param; + } + else +#endif // IRMP_SUPPORT_LEGO_PROTOCOL == 1 + +#if IRMP_SUPPORT_IRMP16_PROTOCOL == 1 + if (irmp_pulse_time >= IRMP16_START_BIT_PULSE_LEN_MIN && irmp_pulse_time <= IRMP16_START_BIT_PULSE_LEN_MAX && + irmp_pause_time >= IRMP16_START_BIT_PAUSE_LEN_MIN && irmp_pause_time <= IRMP16_START_BIT_PAUSE_LEN_MAX) + { +#ifdef ANALYZE + ANALYZE_PRINTF ("protocol = IRMP16, start bit timings: pulse: %3d - %3d, pause: %3d - %3d\n", + IRMP16_START_BIT_PULSE_LEN_MIN, IRMP16_START_BIT_PULSE_LEN_MAX, + IRMP16_START_BIT_PAUSE_LEN_MIN, IRMP16_START_BIT_PAUSE_LEN_MAX); +#endif // ANALYZE + irmp_param_p = (IRMP_PARAMETER *) &irmp16_param; + } + else +#endif // IRMP_SUPPORT_IRMP16_PROTOCOL == 1 + +#if IRMP_SUPPORT_GREE_PROTOCOL == 1 + if (irmp_pulse_time >= GREE_START_BIT_PULSE_LEN_MIN && irmp_pulse_time <= GREE_START_BIT_PULSE_LEN_MAX && + irmp_pause_time >= GREE_START_BIT_PAUSE_LEN_MIN && irmp_pause_time <= GREE_START_BIT_PAUSE_LEN_MAX) + { +#ifdef ANALYZE + ANALYZE_PRINTF ("protocol = GREE, start bit timings: pulse: %3d - %3d, pause: %3d - %3d\n", + GREE_START_BIT_PULSE_LEN_MIN, GREE_START_BIT_PULSE_LEN_MAX, + GREE_START_BIT_PAUSE_LEN_MIN, GREE_START_BIT_PAUSE_LEN_MAX); +#endif // ANALYZE + irmp_param_p = (IRMP_PARAMETER *) &gree_param; + } + else +#endif // IRMP_SUPPORT_GREE_PROTOCOL == 1 + +#if IRMP_SUPPORT_A1TVBOX_PROTOCOL == 1 + if (irmp_pulse_time >= A1TVBOX_START_BIT_PULSE_LEN_MIN && irmp_pulse_time <= A1TVBOX_START_BIT_PULSE_LEN_MAX && + irmp_pause_time >= A1TVBOX_START_BIT_PAUSE_LEN_MIN && irmp_pause_time <= A1TVBOX_START_BIT_PAUSE_LEN_MAX) + { // it's A1TVBOX +#ifdef ANALYZE + ANALYZE_PRINTF ("protocol = A1TVBOX, start bit timings: pulse: %3d - %3d, pause: %3d - %3d\n", + A1TVBOX_START_BIT_PULSE_LEN_MIN, A1TVBOX_START_BIT_PULSE_LEN_MAX, + A1TVBOX_START_BIT_PAUSE_LEN_MIN, A1TVBOX_START_BIT_PAUSE_LEN_MAX); +#endif // ANALYZE + irmp_param_p = (IRMP_PARAMETER *) &a1tvbox_param; + last_pause = 0; + last_value = 1; + } + else +#endif // IRMP_SUPPORT_A1TVBOX_PROTOCOL == 1 + +#if IRMP_SUPPORT_ORTEK_PROTOCOL == 1 + if (irmp_pulse_time >= ORTEK_START_BIT_PULSE_LEN_MIN && irmp_pulse_time <= ORTEK_START_BIT_PULSE_LEN_MAX && + irmp_pause_time >= ORTEK_START_BIT_PAUSE_LEN_MIN && irmp_pause_time <= ORTEK_START_BIT_PAUSE_LEN_MAX) + { // it's ORTEK (Hama) +#ifdef ANALYZE + ANALYZE_PRINTF ("protocol = ORTEK, start bit timings: pulse: %3d - %3d, pause: %3d - %3d\n", + ORTEK_START_BIT_PULSE_LEN_MIN, ORTEK_START_BIT_PULSE_LEN_MAX, + ORTEK_START_BIT_PAUSE_LEN_MIN, ORTEK_START_BIT_PAUSE_LEN_MAX); +#endif // ANALYZE + irmp_param_p = (IRMP_PARAMETER *) &ortek_param; + last_pause = 0; + last_value = 1; + parity = 0; + } + else +#endif // IRMP_SUPPORT_ORTEK_PROTOCOL == 1 + +#if IRMP_SUPPORT_RCMM_PROTOCOL == 1 + if (irmp_pulse_time >= RCMM32_START_BIT_PULSE_LEN_MIN && irmp_pulse_time <= RCMM32_START_BIT_PULSE_LEN_MAX && + irmp_pause_time >= RCMM32_START_BIT_PAUSE_LEN_MIN && irmp_pause_time <= RCMM32_START_BIT_PAUSE_LEN_MAX) + { // it's RCMM +#ifdef ANALYZE + ANALYZE_PRINTF ("protocol = RCMM, start bit timings: pulse: %3d - %3d, pause: %3d - %3d\n", + RCMM32_START_BIT_PULSE_LEN_MIN, RCMM32_START_BIT_PULSE_LEN_MAX, + RCMM32_START_BIT_PAUSE_LEN_MIN, RCMM32_START_BIT_PAUSE_LEN_MAX); +#endif // ANALYZE + irmp_param_p = (IRMP_PARAMETER *) &rcmm_param; + } + else +#endif // IRMP_SUPPORT_RCMM_PROTOCOL == 1 + { +#ifdef ANALYZE + ANALYZE_PRINTF ("protocol = UNKNOWN\n"); +#endif // ANALYZE + irmp_start_bit_detected = 0; // wait for another start bit... + } + + if (irmp_start_bit_detected) + { + memcpy_P (&irmp_param, irmp_param_p, sizeof (IRMP_PARAMETER)); + + if (! (irmp_param.flags & IRMP_PARAM_FLAG_IS_MANCHESTER)) + { +#ifdef ANALYZE + ANALYZE_PRINTF ("pulse_1: %3d - %3d\n", irmp_param.pulse_1_len_min, irmp_param.pulse_1_len_max); + ANALYZE_PRINTF ("pause_1: %3d - %3d\n", irmp_param.pause_1_len_min, irmp_param.pause_1_len_max); +#endif // ANALYZE + } + else + { +#ifdef ANALYZE + ANALYZE_PRINTF ("pulse: %3d - %3d or %3d - %3d\n", irmp_param.pulse_1_len_min, irmp_param.pulse_1_len_max, + 2 * irmp_param.pulse_1_len_min, 2 * irmp_param.pulse_1_len_max); + ANALYZE_PRINTF ("pause: %3d - %3d or %3d - %3d\n", irmp_param.pause_1_len_min, irmp_param.pause_1_len_max, + 2 * irmp_param.pause_1_len_min, 2 * irmp_param.pause_1_len_max); +#endif // ANALYZE + } + +#if IRMP_SUPPORT_RC5_PROTOCOL == 1 && (IRMP_SUPPORT_FDC_PROTOCOL == 1 || IRMP_SUPPORT_RCCAR_PROTOCOL == 1) + if (irmp_param2.protocol) + { +#ifdef ANALYZE + ANALYZE_PRINTF ("pulse_0: %3d - %3d\n", irmp_param2.pulse_0_len_min, irmp_param2.pulse_0_len_max); + ANALYZE_PRINTF ("pause_0: %3d - %3d\n", irmp_param2.pause_0_len_min, irmp_param2.pause_0_len_max); + ANALYZE_PRINTF ("pulse_1: %3d - %3d\n", irmp_param2.pulse_1_len_min, irmp_param2.pulse_1_len_max); + ANALYZE_PRINTF ("pause_1: %3d - %3d\n", irmp_param2.pause_1_len_min, irmp_param2.pause_1_len_max); +#endif // ANALYZE + } +#endif + + +#if IRMP_SUPPORT_RC6_PROTOCOL == 1 + if (irmp_param.protocol == IRMP_RC6_PROTOCOL) + { +#ifdef ANALYZE + ANALYZE_PRINTF ("pulse_toggle: %3d - %3d\n", RC6_TOGGLE_BIT_LEN_MIN, RC6_TOGGLE_BIT_LEN_MAX); +#endif // ANALYZE + } +#endif + + if (! (irmp_param.flags & IRMP_PARAM_FLAG_IS_MANCHESTER)) + { +#ifdef ANALYZE + ANALYZE_PRINTF ("pulse_0: %3d - %3d\n", irmp_param.pulse_0_len_min, irmp_param.pulse_0_len_max); + ANALYZE_PRINTF ("pause_0: %3d - %3d\n", irmp_param.pause_0_len_min, irmp_param.pause_0_len_max); +#endif // ANALYZE + } + else + { +#ifdef ANALYZE + ANALYZE_PRINTF ("pulse: %3d - %3d or %3d - %3d\n", irmp_param.pulse_0_len_min, irmp_param.pulse_0_len_max, + 2 * irmp_param.pulse_0_len_min, 2 * irmp_param.pulse_0_len_max); + ANALYZE_PRINTF ("pause: %3d - %3d or %3d - %3d\n", irmp_param.pause_0_len_min, irmp_param.pause_0_len_max, + 2 * irmp_param.pause_0_len_min, 2 * irmp_param.pause_0_len_max); +#endif // ANALYZE + } + +#ifdef ANALYZE +#if IRMP_SUPPORT_BANG_OLUFSEN_PROTOCOL == 1 + if (irmp_param.protocol == IRMP_BANG_OLUFSEN_PROTOCOL) + { + ANALYZE_PRINTF ("pulse_r: %3d - %3d\n", irmp_param.pulse_0_len_min, irmp_param.pulse_0_len_max); + ANALYZE_PRINTF ("pause_r: %3d - %3d\n", BANG_OLUFSEN_R_PAUSE_LEN_MIN, BANG_OLUFSEN_R_PAUSE_LEN_MAX); + } +#endif + + ANALYZE_PRINTF ("command_offset: %2d\n", irmp_param.command_offset); + ANALYZE_PRINTF ("command_len: %3d\n", irmp_param.command_end - irmp_param.command_offset); + ANALYZE_PRINTF ("complete_len: %3d\n", irmp_param.complete_len); + ANALYZE_PRINTF ("stop_bit: %3d\n", irmp_param.stop_bit); +#endif // ANALYZE + } + + irmp_bit = 0; + +#if IRMP_SUPPORT_MANCHESTER == 1 + if ((irmp_param.flags & IRMP_PARAM_FLAG_IS_MANCHESTER) && + irmp_param.protocol != IRMP_RUWIDO_PROTOCOL && // Manchester, but not RUWIDO + irmp_param.protocol != IRMP_RC6_PROTOCOL /*** && // Manchester, but not RC6 + irmp_param.protocol != IRMP_RCII_PROTOCOL ****/) // Manchester, but not RCII + { + if (irmp_pause_time > irmp_param.pulse_1_len_max && irmp_pause_time <= 2 * irmp_param.pulse_1_len_max) + { +#ifdef ANALYZE + ANALYZE_PRINTF ("%8.3fms [bit %2d: pulse = %3d, pause = %3d] ", (double) (time_counter * 1000) / F_INTERRUPTS, irmp_bit, irmp_pulse_time, irmp_pause_time); + ANALYZE_PUTCHAR ((irmp_param.flags & IRMP_PARAM_FLAG_1ST_PULSE_IS_1) ? '0' : '1'); + ANALYZE_NEWLINE (); +#endif // ANALYZE + irmp_store_bit ((irmp_param.flags & IRMP_PARAM_FLAG_1ST_PULSE_IS_1) ? 0 : 1); + } + else if (! last_value) // && irmp_pause_time >= irmp_param.pause_1_len_min && irmp_pause_time <= irmp_param.pause_1_len_max) + { +#ifdef ANALYZE + ANALYZE_PRINTF ("%8.3fms [bit %2d: pulse = %3d, pause = %3d] ", (double) (time_counter * 1000) / F_INTERRUPTS, irmp_bit, irmp_pulse_time, irmp_pause_time); + ANALYZE_PUTCHAR ((irmp_param.flags & IRMP_PARAM_FLAG_1ST_PULSE_IS_1) ? '1' : '0'); + ANALYZE_NEWLINE (); +#endif // ANALYZE + irmp_store_bit ((irmp_param.flags & IRMP_PARAM_FLAG_1ST_PULSE_IS_1) ? 1 : 0); + } + } + else +#endif // IRMP_SUPPORT_MANCHESTER == 1 + +#if IRMP_SUPPORT_SERIAL == 1 + if (irmp_param.flags & IRMP_PARAM_FLAG_IS_SERIAL) + { + ; // do nothing + } + else +#endif // IRMP_SUPPORT_SERIAL == 1 + + +#if IRMP_SUPPORT_DENON_PROTOCOL == 1 + if (irmp_param.protocol == IRMP_DENON_PROTOCOL) + { +#ifdef ANALYZE + ANALYZE_PRINTF ("%8.3fms [bit %2d: pulse = %3d, pause = %3d] ", (double) (time_counter * 1000) / F_INTERRUPTS, irmp_bit, irmp_pulse_time, irmp_pause_time); +#endif // ANALYZE + + if (irmp_pause_time >= DENON_1_PAUSE_LEN_MIN && irmp_pause_time <= DENON_1_PAUSE_LEN_MAX) + { // pause timings correct for "1"? +#ifdef ANALYZE + ANALYZE_PUTCHAR ('1'); // yes, store 1 + ANALYZE_NEWLINE (); +#endif // ANALYZE + irmp_store_bit (1); + } + else // if (irmp_pause_time >= DENON_0_PAUSE_LEN_MIN && irmp_pause_time <= DENON_0_PAUSE_LEN_MAX) + { // pause timings correct for "0"? +#ifdef ANALYZE + ANALYZE_PUTCHAR ('0'); // yes, store 0 + ANALYZE_NEWLINE (); +#endif // ANALYZE + irmp_store_bit (0); + } + } + else +#endif // IRMP_SUPPORT_DENON_PROTOCOL == 1 +#if IRMP_SUPPORT_THOMSON_PROTOCOL == 1 + if (irmp_param.protocol == IRMP_THOMSON_PROTOCOL) + { +#ifdef ANALYZE + ANALYZE_PRINTF ("%8.3fms [bit %2d: pulse = %3d, pause = %3d] ", (double) (time_counter * 1000) / F_INTERRUPTS, irmp_bit, irmp_pulse_time, irmp_pause_time); +#endif // ANALYZE + + if (irmp_pause_time >= THOMSON_1_PAUSE_LEN_MIN && irmp_pause_time <= THOMSON_1_PAUSE_LEN_MAX) + { // pause timings correct for "1"? +#ifdef ANALYZE + ANALYZE_PUTCHAR ('1'); // yes, store 1 + ANALYZE_NEWLINE (); +#endif // ANALYZE + irmp_store_bit (1); + } + else // if (irmp_pause_time >= THOMSON_0_PAUSE_LEN_MIN && irmp_pause_time <= THOMSON_0_PAUSE_LEN_MAX) + { // pause timings correct for "0"? +#ifdef ANALYZE + ANALYZE_PUTCHAR ('0'); // yes, store 0 + ANALYZE_NEWLINE (); +#endif // ANALYZE + irmp_store_bit (0); + } + } + else +#endif // IRMP_SUPPORT_THOMSON_PROTOCOL == 1 + { + ; // else do nothing + } + + irmp_pulse_time = 1; // set counter to 1, not 0 + irmp_pause_time = 0; + wait_for_start_space = 0; + } + } + else if (wait_for_space) // the data section.... + { // counting the time of darkness.... + uint_fast8_t got_light = FALSE; + + if (irmp_input) // still dark? + { // yes... + if (irmp_bit == irmp_param.complete_len && irmp_param.stop_bit == 1) + { + if ( +#if IRMP_SUPPORT_MANCHESTER == 1 + (irmp_param.flags & IRMP_PARAM_FLAG_IS_MANCHESTER) || +#endif +#if IRMP_SUPPORT_SERIAL == 1 + (irmp_param.flags & IRMP_PARAM_FLAG_IS_SERIAL) || +#endif + (irmp_pulse_time >= irmp_param.pulse_0_len_min && irmp_pulse_time <= irmp_param.pulse_0_len_max)) + { +#ifdef ANALYZE + if (! (irmp_param.flags & IRMP_PARAM_FLAG_IS_MANCHESTER)) + { + ANALYZE_PRINTF ("stop bit detected\n"); + } +#endif // ANALYZE + irmp_param.stop_bit = 0; + } + else + { +#ifdef ANALYZE + ANALYZE_PRINTF ("error: stop bit timing wrong, irmp_bit = %d, irmp_pulse_time = %d, pulse_0_len_min = %d, pulse_0_len_max = %d\n", + irmp_bit, irmp_pulse_time, irmp_param.pulse_0_len_min, irmp_param.pulse_0_len_max); +#endif // ANALYZE + irmp_start_bit_detected = 0; // wait for another start bit... + irmp_pulse_time = 0; + irmp_pause_time = 0; + } + } + else + { + irmp_pause_time++; // increment counter + +#if IRMP_SUPPORT_SIRCS_PROTOCOL == 1 + if (irmp_param.protocol == IRMP_SIRCS_PROTOCOL && // Sony has a variable number of bits: + irmp_pause_time > SIRCS_PAUSE_LEN_MAX && // minimum is 12 + irmp_bit >= 12 - 1) // pause too long? + { // yes, break and close this frame + irmp_param.complete_len = irmp_bit + 1; // set new complete length + got_light = TRUE; // this is a lie, but helps (generates stop bit) + irmp_tmp_address |= (irmp_bit - SIRCS_MINIMUM_DATA_LEN + 1) << 8; // new: store number of additional bits in upper byte of address! + irmp_param.command_end = irmp_param.command_offset + irmp_bit + 1; // correct command length + irmp_pause_time = SIRCS_PAUSE_LEN_MAX - 1; // correct pause length + } + else +#endif +#if IRMP_SUPPORT_MERLIN_PROTOCOL == 1 + if (irmp_param.protocol == IRMP_MERLIN_PROTOCOL && // Merlin has a variable number of bits: + irmp_pause_time > MERLIN_START_BIT_PAUSE_LEN_MAX && // minimum is 8 + irmp_bit >= 8 - 1) // pause too long? + { // yes, break and close this frame + irmp_param.complete_len = irmp_bit; // set new complete length + got_light = TRUE; // this is a lie, but helps (generates stop bit) + irmp_pause_time = MERLIN_BIT_PAUSE_LEN_MAX - 1; // correct pause length + } + else +#endif +#if IRMP_SUPPORT_FAN_PROTOCOL == 1 + if (irmp_param.protocol == IRMP_FAN_PROTOCOL && // FAN has no stop bit. + irmp_bit >= FAN_COMPLETE_DATA_LEN - 1) // last bit in frame + { // yes, break and close this frame + if (irmp_pulse_time <= FAN_0_PULSE_LEN_MAX && irmp_pause_time >= FAN_0_PAUSE_LEN_MIN) + { +#ifdef ANALYZE + ANALYZE_PRINTF ("Generating virtual stop bit\n"); +#endif // ANALYZE + got_light = TRUE; // this is a lie, but helps (generates stop bit) + } + else if (irmp_pulse_time >= FAN_1_PULSE_LEN_MIN && irmp_pause_time >= FAN_1_PAUSE_LEN_MIN) + { +#ifdef ANALYZE + ANALYZE_PRINTF ("Generating virtual stop bit\n"); +#endif // ANALYZE + got_light = TRUE; // this is a lie, but helps (generates stop bit) + } + } + else +#endif +#if IRMP_SUPPORT_SERIAL == 1 + // NETBOX generates no stop bit, here is the timeout condition: + if ((irmp_param.flags & IRMP_PARAM_FLAG_IS_SERIAL) && irmp_param.protocol == IRMP_NETBOX_PROTOCOL && + irmp_pause_time >= NETBOX_PULSE_LEN * (NETBOX_COMPLETE_DATA_LEN - irmp_bit)) + { + got_light = TRUE; // this is a lie, but helps (generates stop bit) + } + else +#endif +#if IRMP_SUPPORT_GRUNDIG_NOKIA_IR60_PROTOCOL == 1 + if (irmp_param.protocol == IRMP_GRUNDIG_PROTOCOL && !irmp_param.stop_bit) + { + if (irmp_pause_time > IR60_TIMEOUT_LEN && (irmp_bit == 5 || irmp_bit == 6)) + { +#ifdef ANALYZE + ANALYZE_PRINTF ("Switching to IR60 protocol\n"); +#endif // ANALYZE + got_light = TRUE; // this is a lie, but generates a stop bit ;-) + irmp_param.stop_bit = TRUE; // set flag + + irmp_param.protocol = IRMP_IR60_PROTOCOL; // change protocol + irmp_param.complete_len = IR60_COMPLETE_DATA_LEN; // correct complete len + irmp_param.address_offset = IR60_ADDRESS_OFFSET; + irmp_param.address_end = IR60_ADDRESS_OFFSET + IR60_ADDRESS_LEN; + irmp_param.command_offset = IR60_COMMAND_OFFSET; + irmp_param.command_end = IR60_COMMAND_OFFSET + IR60_COMMAND_LEN; + + irmp_tmp_command <<= 1; + irmp_tmp_command |= first_bit; + } + else if (irmp_pause_time >= 2 * irmp_param.pause_1_len_max && irmp_bit >= GRUNDIG_COMPLETE_DATA_LEN - 2) + { // special manchester decoder + irmp_param.complete_len = GRUNDIG_COMPLETE_DATA_LEN; // correct complete len + got_light = TRUE; // this is a lie, but generates a stop bit ;-) + irmp_param.stop_bit = TRUE; // set flag + } + else if (irmp_bit >= GRUNDIG_COMPLETE_DATA_LEN) + { +#ifdef ANALYZE + ANALYZE_PRINTF ("Switching to NOKIA protocol, irmp_bit = %d\n", irmp_bit); +#endif // ANALYZE + irmp_param.protocol = IRMP_NOKIA_PROTOCOL; // change protocol + irmp_param.address_offset = NOKIA_ADDRESS_OFFSET; + irmp_param.address_end = NOKIA_ADDRESS_OFFSET + NOKIA_ADDRESS_LEN; + irmp_param.command_offset = NOKIA_COMMAND_OFFSET; + irmp_param.command_end = NOKIA_COMMAND_OFFSET + NOKIA_COMMAND_LEN; + + if (irmp_tmp_command & 0x300) + { + irmp_tmp_address = (irmp_tmp_command >> 8); + irmp_tmp_command &= 0xFF; + } + } + } + else +#endif +#if IRMP_SUPPORT_SIEMENS_OR_RUWIDO_PROTOCOL == 1 + if (irmp_param.protocol == IRMP_RUWIDO_PROTOCOL && !irmp_param.stop_bit) + { + if (irmp_pause_time >= 2 * irmp_param.pause_1_len_max && irmp_bit >= RUWIDO_COMPLETE_DATA_LEN - 2) + { // special manchester decoder + irmp_param.complete_len = RUWIDO_COMPLETE_DATA_LEN; // correct complete len + got_light = TRUE; // this is a lie, but generates a stop bit ;-) + irmp_param.stop_bit = TRUE; // set flag + } + else if (irmp_bit >= RUWIDO_COMPLETE_DATA_LEN) + { +#ifdef ANALYZE + ANALYZE_PRINTF ("Switching to SIEMENS protocol\n"); +#endif // ANALYZE + irmp_param.protocol = IRMP_SIEMENS_PROTOCOL; // change protocol + irmp_param.address_offset = SIEMENS_ADDRESS_OFFSET; + irmp_param.address_end = SIEMENS_ADDRESS_OFFSET + SIEMENS_ADDRESS_LEN; + irmp_param.command_offset = SIEMENS_COMMAND_OFFSET; + irmp_param.command_end = SIEMENS_COMMAND_OFFSET + SIEMENS_COMMAND_LEN; + + // 76543210 + // RUWIDO: AAAAAAAAACCCCCCCp + // SIEMENS: AAAAAAAAAAACCCCCCCCCCp + irmp_tmp_address <<= 2; + irmp_tmp_address |= (irmp_tmp_command >> 6); + irmp_tmp_command &= 0x003F; +// irmp_tmp_command <<= 4; + irmp_tmp_command |= last_value; + } + } + else +#endif +#if IRMP_SUPPORT_ROOMBA_PROTOCOL == 1 + if (irmp_param.protocol == IRMP_ROOMBA_PROTOCOL && // Roomba has no stop bit + irmp_bit >= ROOMBA_COMPLETE_DATA_LEN - 1) // it's the last data bit... + { // break and close this frame + if (irmp_pulse_time >= ROOMBA_1_PULSE_LEN_MIN && irmp_pulse_time <= ROOMBA_1_PULSE_LEN_MAX) + { + irmp_pause_time = ROOMBA_1_PAUSE_LEN_EXACT; + } + else if (irmp_pulse_time >= ROOMBA_0_PULSE_LEN_MIN && irmp_pulse_time <= ROOMBA_0_PULSE_LEN_MAX) + { + irmp_pause_time = ROOMBA_0_PAUSE_LEN; + } + + got_light = TRUE; // this is a lie, but helps (generates stop bit) + } + else +#endif +#if IRMP_SUPPORT_MANCHESTER == 1 + if ((irmp_param.flags & IRMP_PARAM_FLAG_IS_MANCHESTER) && + irmp_pause_time >= 2 * irmp_param.pause_1_len_max && irmp_bit >= irmp_param.complete_len - 2 && !irmp_param.stop_bit) + { // special manchester decoder + got_light = TRUE; // this is a lie, but generates a stop bit ;-) + irmp_param.stop_bit = TRUE; // set flag + } + else +#endif // IRMP_SUPPORT_MANCHESTER == 1 + if (irmp_pause_time > IRMP_TIMEOUT_LEN) // timeout? + { // yes... + if (irmp_bit == irmp_param.complete_len - 1 && irmp_param.stop_bit == 0) + { + irmp_bit++; + } +#if IRMP_SUPPORT_NEC_PROTOCOL == 1 + else if ((irmp_param.protocol == IRMP_NEC_PROTOCOL || irmp_param.protocol == IRMP_NEC42_PROTOCOL) && irmp_bit == 0) + { // it was a non-standard repetition frame +#ifdef ANALYZE // with 4500us pause instead of 2250us + ANALYZE_PRINTF ("Detected non-standard repetition frame, switching to NEC repetition\n"); +#endif // ANALYZE + if (key_repetition_len < NEC_FRAME_REPEAT_PAUSE_LEN_MAX) + { + irmp_param.stop_bit = TRUE; // set flag + irmp_param.protocol = IRMP_NEC_PROTOCOL; // switch protocol + irmp_param.complete_len = irmp_bit; // patch length: 16 or 17 + irmp_tmp_address = last_irmp_address; // address is last address + irmp_tmp_command = last_irmp_command; // command is last command + irmp_flags |= IRMP_FLAG_REPETITION; + key_repetition_len = 0; + } + else + { +#ifdef ANALYZE + ANALYZE_PRINTF ("ignoring NEC repetition frame: timeout occured, key_repetition_len = %d > %d\n", + key_repetition_len, NEC_FRAME_REPEAT_PAUSE_LEN_MAX); +#endif // ANALYZE + irmp_ir_detected = FALSE; + } + } +#endif // IRMP_SUPPORT_NEC_PROTOCOL == 1 +#if IRMP_SUPPORT_JVC_PROTOCOL == 1 + else if (irmp_param.protocol == IRMP_NEC_PROTOCOL && (irmp_bit == 16 || irmp_bit == 17)) // it was a JVC stop bit + { +#ifdef ANALYZE + ANALYZE_PRINTF ("Switching to JVC protocol, irmp_bit = %d\n", irmp_bit); +#endif // ANALYZE + irmp_param.stop_bit = TRUE; // set flag + irmp_param.protocol = IRMP_JVC_PROTOCOL; // switch protocol + irmp_param.complete_len = irmp_bit; // patch length: 16 or 17 + irmp_tmp_command = (irmp_tmp_address >> 4); // set command: upper 12 bits are command bits + irmp_tmp_address = irmp_tmp_address & 0x000F; // lower 4 bits are address bits + irmp_start_bit_detected = 1; // tricky: don't wait for another start bit... + } +#endif // IRMP_SUPPORT_JVC_PROTOCOL == 1 +#if IRMP_SUPPORT_LGAIR_PROTOCOL == 1 + else if (irmp_param.protocol == IRMP_NEC_PROTOCOL && (irmp_bit == 28 || irmp_bit == 29)) // it was a LGAIR stop bit + { +#ifdef ANALYZE + ANALYZE_PRINTF ("Switching to LGAIR protocol, irmp_bit = %d\n", irmp_bit); +#endif // ANALYZE + irmp_param.stop_bit = TRUE; // set flag + irmp_param.protocol = IRMP_LGAIR_PROTOCOL; // switch protocol + irmp_param.complete_len = irmp_bit; // patch length: 16 or 17 + irmp_tmp_command = irmp_lgair_command; // set command: upper 8 bits are command bits + irmp_tmp_address = irmp_lgair_address; // lower 4 bits are address bits + irmp_start_bit_detected = 1; // tricky: don't wait for another start bit... + } +#endif // IRMP_SUPPORT_LGAIR_PROTOCOL == 1 + +#if IRMP_SUPPORT_NEC42_PROTOCOL == 1 +#if IRMP_SUPPORT_NEC_PROTOCOL == 1 + else if (irmp_param.protocol == IRMP_NEC42_PROTOCOL && irmp_bit == 32) // it was a NEC stop bit + { +#ifdef ANALYZE + ANALYZE_PRINTF ("Switching to NEC protocol\n"); +#endif // ANALYZE + irmp_param.stop_bit = TRUE; // set flag + irmp_param.protocol = IRMP_NEC_PROTOCOL; // switch protocol + irmp_param.complete_len = irmp_bit; // patch length: 16 or 17 + + // 0123456789ABC0123456789ABC0123456701234567 + // NEC42: AAAAAAAAAAAAAaaaaaaaaaaaaaCCCCCCCCcccccccc + // NEC: AAAAAAAAaaaaaaaaCCCCCCCCcccccccc + irmp_tmp_address |= (irmp_tmp_address2 & 0x0007) << 13; // fm 2012-02-13: 12 -> 13 + irmp_tmp_command = (irmp_tmp_address2 >> 3) | (irmp_tmp_command << 10); + } +#endif // IRMP_SUPPORT_NEC_PROTOCOL == 1 +#if IRMP_SUPPORT_LGAIR_PROTOCOL == 1 + else if (irmp_param.protocol == IRMP_NEC42_PROTOCOL && irmp_bit == 28) // it was a NEC stop bit + { +#ifdef ANALYZE + ANALYZE_PRINTF ("Switching to LGAIR protocol\n"); +#endif // ANALYZE + irmp_param.stop_bit = TRUE; // set flag + irmp_param.protocol = IRMP_LGAIR_PROTOCOL; // switch protocol + irmp_param.complete_len = irmp_bit; // patch length: 16 or 17 + irmp_tmp_address = irmp_lgair_address; + irmp_tmp_command = irmp_lgair_command; + } +#endif // IRMP_SUPPORT_LGAIR_PROTOCOL == 1 +#if IRMP_SUPPORT_JVC_PROTOCOL == 1 + else if (irmp_param.protocol == IRMP_NEC42_PROTOCOL && (irmp_bit == 16 || irmp_bit == 17)) // it was a JVC stop bit + { +#ifdef ANALYZE + ANALYZE_PRINTF ("Switching to JVC protocol, irmp_bit = %d\n", irmp_bit); +#endif // ANALYZE + irmp_param.stop_bit = TRUE; // set flag + irmp_param.protocol = IRMP_JVC_PROTOCOL; // switch protocol + irmp_param.complete_len = irmp_bit; // patch length: 16 or 17 + + // 0123456789ABC0123456789ABC0123456701234567 + // NEC42: AAAAAAAAAAAAAaaaaaaaaaaaaaCCCCCCCCcccccccc + // JVC: AAAACCCCCCCCCCCC + irmp_tmp_command = (irmp_tmp_address >> 4) | (irmp_tmp_address2 << 9); // set command: upper 12 bits are command bits + irmp_tmp_address = irmp_tmp_address & 0x000F; // lower 4 bits are address bits + } +#endif // IRMP_SUPPORT_JVC_PROTOCOL == 1 +#endif // IRMP_SUPPORT_NEC42_PROTOCOL == 1 + +#if IRMP_SUPPORT_SAMSUNG48_PROTOCOL == 1 + else if (irmp_param.protocol == IRMP_SAMSUNG48_PROTOCOL && irmp_bit == 32) // it was a SAMSUNG32 stop bit + { +#ifdef ANALYZE + ANALYZE_PRINTF ("Switching to SAMSUNG32 protocol\n"); +#endif // ANALYZE + irmp_param.protocol = IRMP_SAMSUNG32_PROTOCOL; + irmp_param.command_offset = SAMSUNG32_COMMAND_OFFSET; + irmp_param.command_end = SAMSUNG32_COMMAND_OFFSET + SAMSUNG32_COMMAND_LEN; + irmp_param.complete_len = SAMSUNG32_COMPLETE_DATA_LEN; + } +#endif // IRMP_SUPPORT_SAMSUNG_PROTOCOL == 1 + +#if IRMP_SUPPORT_RCMM_PROTOCOL == 1 + else if (irmp_param.protocol == IRMP_RCMM32_PROTOCOL && (irmp_bit == 12 || irmp_bit == 24)) // it was a RCMM stop bit + { + if (irmp_bit == 12) + { + irmp_tmp_command = (irmp_tmp_address & 0xFF); // set command: lower 8 bits are command bits + irmp_tmp_address >>= 8; // upper 4 bits are address bits + +#ifdef ANALYZE + ANALYZE_PRINTF ("Switching to RCMM12 protocol, irmp_bit = %d\n", irmp_bit); +#endif // ANALYZE + irmp_param.protocol = IRMP_RCMM12_PROTOCOL; // switch protocol + } + else // if ((irmp_bit == 24) + { +#ifdef ANALYZE + ANALYZE_PRINTF ("Switching to RCMM24 protocol, irmp_bit = %d\n", irmp_bit); +#endif // ANALYZE + irmp_param.protocol = IRMP_RCMM24_PROTOCOL; // switch protocol + } + irmp_param.stop_bit = TRUE; // set flag + irmp_param.complete_len = irmp_bit; // patch length + } +#endif // IRMP_SUPPORT_RCMM_PROTOCOL == 1 + +#if IRMP_SUPPORT_TECHNICS_PROTOCOL == 1 + else if (irmp_param.protocol == IRMP_MATSUSHITA_PROTOCOL && irmp_bit == 22) // it was a TECHNICS stop bit + { +#ifdef ANALYZE + ANALYZE_PRINTF ("Switching to TECHNICS protocol, irmp_bit = %d\n", irmp_bit); +#endif // ANALYZE + // Situation: + // The first 12 bits have been stored in irmp_tmp_command (LSB first) + // The following 10 bits have been stored in irmp_tmp_address (LSB first) + // The code of TECHNICS is: + // cccccccccccCCCCCCCCCCC (11 times c and 11 times C) + // ccccccccccccaaaaaaaaaa + // where C is inverted value of c + + irmp_tmp_address <<= 1; + if (irmp_tmp_command & (1<<11)) + { + irmp_tmp_address |= 1; + irmp_tmp_command &= ~(1<<11); + } + + if (irmp_tmp_command == ((~irmp_tmp_address) & 0x07FF)) + { + irmp_tmp_address = 0; + + irmp_param.protocol = IRMP_TECHNICS_PROTOCOL; // switch protocol + irmp_param.complete_len = irmp_bit; // patch length + } + else + { +#ifdef ANALYZE + ANALYZE_PRINTF ("error 8: TECHNICS frame error\n"); + ANALYZE_ONLY_NORMAL_PUTCHAR ('\n'); +#endif // ANALYZE + irmp_start_bit_detected = 0; // wait for another start bit... + irmp_pulse_time = 0; + irmp_pause_time = 0; + } + } +#endif // IRMP_SUPPORT_TECHNICS_PROTOCOL == 1 + else + { +#ifdef ANALYZE + ANALYZE_PRINTF ("error 2: pause %d after data bit %d too long\n", irmp_pause_time, irmp_bit); + ANALYZE_ONLY_NORMAL_PUTCHAR ('\n'); +#endif // ANALYZE + irmp_start_bit_detected = 0; // wait for another start bit... + irmp_pulse_time = 0; + irmp_pause_time = 0; + } + } + } + } + else + { // got light now! + got_light = TRUE; + } + + if (got_light) + { +#ifdef ANALYZE + ANALYZE_PRINTF ("%8.3fms [bit %2d: pulse = %3d, pause = %3d] ", (double) (time_counter * 1000) / F_INTERRUPTS, irmp_bit, irmp_pulse_time, irmp_pause_time); +#endif // ANALYZE + +#if IRMP_SUPPORT_MANCHESTER == 1 + if ((irmp_param.flags & IRMP_PARAM_FLAG_IS_MANCHESTER)) // Manchester + { +#if IRMP_SUPPORT_MERLIN_PROTOCOL == 1 + if (irmp_param.complete_len == irmp_bit && irmp_param.protocol == IRMP_MERLIN_PROTOCOL) + { + if (last_value == 0) + { + if (irmp_pulse_time >= 2 * irmp_param.pulse_1_len_min && irmp_pulse_time <= 2 * irmp_param.pulse_1_len_max && + last_pause >= irmp_param.pause_1_len_min && last_pause <= irmp_param.pulse_1_len_max) + { + irmp_param.complete_len += 2; + irmp_store_bit(0); + irmp_store_bit(1); + } + } + else + { + if (last_pause >= 2 * irmp_param.pause_1_len_min && last_pause <= 2 * irmp_param.pulse_1_len_max) + { + if (irmp_pulse_time >= irmp_param.pulse_1_len_min && irmp_pulse_time <= irmp_param.pulse_1_len_max) + { + irmp_param.complete_len++; + irmp_store_bit(0); + } + else if (irmp_pulse_time >= 2 * irmp_param.pulse_1_len_min && irmp_pulse_time <= 2 * irmp_param.pulse_1_len_max) + { + irmp_param.complete_len += 2; + irmp_store_bit(0); + irmp_store_bit(1); + } + } + } + } + else +#endif +#if 1 + if (irmp_pulse_time > irmp_param.pulse_1_len_max /* && irmp_pulse_time <= 2 * irmp_param.pulse_1_len_max */) +#else // better, but some IR-RCs use asymmetric timings :-/ + if (irmp_pulse_time > irmp_param.pulse_1_len_max && irmp_pulse_time <= 2 * irmp_param.pulse_1_len_max && + irmp_pause_time <= 2 * irmp_param.pause_1_len_max) +#endif + { +#if IRMP_SUPPORT_RC6_PROTOCOL == 1 + if (irmp_param.protocol == IRMP_RC6_PROTOCOL && irmp_bit == 4 && irmp_pulse_time > RC6_TOGGLE_BIT_LEN_MIN) // RC6 toggle bit + { +#ifdef ANALYZE + ANALYZE_PUTCHAR ('T'); +#endif // ANALYZE + if (irmp_param.complete_len == RC6_COMPLETE_DATA_LEN_LONG) // RC6 mode 6A + { + irmp_store_bit (1); + last_value = 1; + } + else // RC6 mode 0 + { + irmp_store_bit (0); + last_value = 0; + } +#ifdef ANALYZE + ANALYZE_NEWLINE (); +#endif // ANALYZE + } + else +#endif // IRMP_SUPPORT_RC6_PROTOCOL == 1 + { +#ifdef ANALYZE + ANALYZE_PUTCHAR ((irmp_param.flags & IRMP_PARAM_FLAG_1ST_PULSE_IS_1) ? '0' : '1'); +#endif // ANALYZE + irmp_store_bit ((irmp_param.flags & IRMP_PARAM_FLAG_1ST_PULSE_IS_1) ? 0 : 1 ); + +#if IRMP_SUPPORT_RC6_PROTOCOL == 1 + if (irmp_param.protocol == IRMP_RC6_PROTOCOL && irmp_bit == 4 && irmp_pulse_time > RC6_TOGGLE_BIT_LEN_MIN) // RC6 toggle bit + { +#ifdef ANALYZE + ANALYZE_PUTCHAR ('T'); +#endif // ANALYZE + irmp_store_bit (1); + + if (irmp_pause_time > 2 * irmp_param.pause_1_len_max) + { + last_value = 0; + } + else + { + last_value = 1; + } +#ifdef ANALYZE + ANALYZE_NEWLINE (); +#endif // ANALYZE + } + else +#endif // IRMP_SUPPORT_RC6_PROTOCOL == 1 + { +#ifdef ANALYZE + ANALYZE_PUTCHAR ((irmp_param.flags & IRMP_PARAM_FLAG_1ST_PULSE_IS_1) ? '1' : '0'); +#endif // ANALYZE + irmp_store_bit ((irmp_param.flags & IRMP_PARAM_FLAG_1ST_PULSE_IS_1) ? 1 : 0 ); + +#if IRMP_SUPPORT_RC5_PROTOCOL == 1 && IRMP_SUPPORT_RCII_PROTOCOL == 1 && (IRMP_SUPPORT_FDC_PROTOCOL == 1 || IRMP_SUPPORT_RCCAR_PROTOCOL == 1) + if (! irmp_param2.protocol) +#endif + { +#ifdef ANALYZE + ANALYZE_NEWLINE (); +#endif // ANALYZE + } + last_value = (irmp_param.flags & IRMP_PARAM_FLAG_1ST_PULSE_IS_1) ? 1 : 0; + } + } + } + else if (irmp_pulse_time >= irmp_param.pulse_1_len_min && irmp_pulse_time <= irmp_param.pulse_1_len_max + /* && irmp_pause_time <= 2 * irmp_param.pause_1_len_max */) + { + uint_fast8_t manchester_value; + + if (last_pause > irmp_param.pause_1_len_max && last_pause <= 2 * irmp_param.pause_1_len_max) + { + manchester_value = last_value ? 0 : 1; + last_value = manchester_value; + } + else + { + manchester_value = last_value; + } + +#ifdef ANALYZE + ANALYZE_PUTCHAR (manchester_value + '0'); +#endif // ANALYZE + +#if IRMP_SUPPORT_RC5_PROTOCOL == 1 && (IRMP_SUPPORT_FDC_PROTOCOL == 1 || IRMP_SUPPORT_RCCAR_PROTOCOL == 1) + if (! irmp_param2.protocol) +#endif + { +#ifdef ANALYZE + ANALYZE_NEWLINE (); +#endif // ANALYZE + } + +#if IRMP_SUPPORT_RC6_PROTOCOL == 1 + if (irmp_param.protocol == IRMP_RC6_PROTOCOL && irmp_bit == 1 && manchester_value == 1) // RC6 mode != 0 ??? + { +#ifdef ANALYZE + ANALYZE_PRINTF ("Switching to RC6A protocol\n"); +#endif // ANALYZE + irmp_param.complete_len = RC6_COMPLETE_DATA_LEN_LONG; + irmp_param.address_offset = 5; + irmp_param.address_end = irmp_param.address_offset + 15; + irmp_param.command_offset = irmp_param.address_end + 1; // skip 1 system bit, changes like a toggle bit + irmp_param.command_end = irmp_param.command_offset + 16 - 1; + irmp_tmp_address = 0; + } +#endif // IRMP_SUPPORT_RC6_PROTOCOL == 1 + + irmp_store_bit (manchester_value); + } + else + { +#if IRMP_SUPPORT_RC5_PROTOCOL == 1 && IRMP_SUPPORT_FDC_PROTOCOL == 1 + if (irmp_param2.protocol == IRMP_FDC_PROTOCOL && + irmp_pulse_time >= FDC_PULSE_LEN_MIN && irmp_pulse_time <= FDC_PULSE_LEN_MAX && + ((irmp_pause_time >= FDC_1_PAUSE_LEN_MIN && irmp_pause_time <= FDC_1_PAUSE_LEN_MAX) || + (irmp_pause_time >= FDC_0_PAUSE_LEN_MIN && irmp_pause_time <= FDC_0_PAUSE_LEN_MAX))) + { +#ifdef ANALYZE + ANALYZE_PUTCHAR ('?'); +#endif // ANALYZE + irmp_param.protocol = 0; // switch to FDC, see below + } + else +#endif // IRMP_SUPPORT_FDC_PROTOCOL == 1 +#if IRMP_SUPPORT_RC5_PROTOCOL == 1 && IRMP_SUPPORT_RCCAR_PROTOCOL == 1 + if (irmp_param2.protocol == IRMP_RCCAR_PROTOCOL && + irmp_pulse_time >= RCCAR_PULSE_LEN_MIN && irmp_pulse_time <= RCCAR_PULSE_LEN_MAX && + ((irmp_pause_time >= RCCAR_1_PAUSE_LEN_MIN && irmp_pause_time <= RCCAR_1_PAUSE_LEN_MAX) || + (irmp_pause_time >= RCCAR_0_PAUSE_LEN_MIN && irmp_pause_time <= RCCAR_0_PAUSE_LEN_MAX))) + { +#ifdef ANALYZE + ANALYZE_PUTCHAR ('?'); +#endif // ANALYZE + irmp_param.protocol = 0; // switch to RCCAR, see below + } + else +#endif // IRMP_SUPPORT_RCCAR_PROTOCOL == 1 + { +#ifdef ANALYZE + ANALYZE_PUTCHAR ('?'); + ANALYZE_NEWLINE (); + ANALYZE_PRINTF ("error 3 manchester: timing not correct: data bit %d, pulse: %d, pause: %d\n", irmp_bit, irmp_pulse_time, irmp_pause_time); + ANALYZE_ONLY_NORMAL_PUTCHAR ('\n'); +#endif // ANALYZE + irmp_start_bit_detected = 0; // reset flags and wait for next start bit + irmp_pause_time = 0; + } + } + +#if IRMP_SUPPORT_RC5_PROTOCOL == 1 && IRMP_SUPPORT_FDC_PROTOCOL == 1 + if (irmp_param2.protocol == IRMP_FDC_PROTOCOL && irmp_pulse_time >= FDC_PULSE_LEN_MIN && irmp_pulse_time <= FDC_PULSE_LEN_MAX) + { + if (irmp_pause_time >= FDC_1_PAUSE_LEN_MIN && irmp_pause_time <= FDC_1_PAUSE_LEN_MAX) + { +#ifdef ANALYZE + ANALYZE_PRINTF (" 1 (FDC)\n"); +#endif // ANALYZE + irmp_store_bit2 (1); + } + else if (irmp_pause_time >= FDC_0_PAUSE_LEN_MIN && irmp_pause_time <= FDC_0_PAUSE_LEN_MAX) + { +#ifdef ANALYZE + ANALYZE_PRINTF (" 0 (FDC)\n"); +#endif // ANALYZE + irmp_store_bit2 (0); + } + + if (! irmp_param.protocol) + { +#ifdef ANALYZE + ANALYZE_PRINTF ("Switching to FDC protocol\n"); +#endif // ANALYZE + memcpy (&irmp_param, &irmp_param2, sizeof (IRMP_PARAMETER)); + irmp_param2.protocol = 0; + irmp_tmp_address = irmp_tmp_address2; + irmp_tmp_command = irmp_tmp_command2; + } + } +#endif // IRMP_SUPPORT_FDC_PROTOCOL == 1 +#if IRMP_SUPPORT_RC5_PROTOCOL == 1 && IRMP_SUPPORT_RCCAR_PROTOCOL == 1 + if (irmp_param2.protocol == IRMP_RCCAR_PROTOCOL && irmp_pulse_time >= RCCAR_PULSE_LEN_MIN && irmp_pulse_time <= RCCAR_PULSE_LEN_MAX) + { + if (irmp_pause_time >= RCCAR_1_PAUSE_LEN_MIN && irmp_pause_time <= RCCAR_1_PAUSE_LEN_MAX) + { +#ifdef ANALYZE + ANALYZE_PRINTF (" 1 (RCCAR)\n"); +#endif // ANALYZE + irmp_store_bit2 (1); + } + else if (irmp_pause_time >= RCCAR_0_PAUSE_LEN_MIN && irmp_pause_time <= RCCAR_0_PAUSE_LEN_MAX) + { +#ifdef ANALYZE + ANALYZE_PRINTF (" 0 (RCCAR)\n"); +#endif // ANALYZE + irmp_store_bit2 (0); + } + + if (! irmp_param.protocol) + { +#ifdef ANALYZE + ANALYZE_PRINTF ("Switching to RCCAR protocol\n"); +#endif // ANALYZE + memcpy (&irmp_param, &irmp_param2, sizeof (IRMP_PARAMETER)); + irmp_param2.protocol = 0; + irmp_tmp_address = irmp_tmp_address2; + irmp_tmp_command = irmp_tmp_command2; + } + } +#endif // IRMP_SUPPORT_RCCAR_PROTOCOL == 1 + + last_pause = irmp_pause_time; + wait_for_space = 0; + } + else +#endif // IRMP_SUPPORT_MANCHESTER == 1 + +#if IRMP_SUPPORT_SERIAL == 1 + if (irmp_param.flags & IRMP_PARAM_FLAG_IS_SERIAL) + { + while (irmp_bit < irmp_param.complete_len && irmp_pulse_time > irmp_param.pulse_1_len_max) + { +#ifdef ANALYZE + ANALYZE_PUTCHAR ('1'); +#endif // ANALYZE + irmp_store_bit (1); + + if (irmp_pulse_time >= irmp_param.pulse_1_len_min) + { + irmp_pulse_time -= irmp_param.pulse_1_len_min; + } + else + { + irmp_pulse_time = 0; + } + } + + while (irmp_bit < irmp_param.complete_len && irmp_pause_time > irmp_param.pause_1_len_max) + { +#ifdef ANALYZE + ANALYZE_PUTCHAR ('0'); +#endif // ANALYZE + irmp_store_bit (0); + + if (irmp_pause_time >= irmp_param.pause_1_len_min) + { + irmp_pause_time -= irmp_param.pause_1_len_min; + } + else + { + irmp_pause_time = 0; + } + } +#ifdef ANALYZE + ANALYZE_NEWLINE (); +#endif // ANALYZE + wait_for_space = 0; + } + else +#endif // IRMP_SUPPORT_SERIAL == 1 + +#if IRMP_SUPPORT_SAMSUNG_PROTOCOL == 1 + if (irmp_param.protocol == IRMP_SAMSUNG_PROTOCOL && irmp_bit == 16) // Samsung: 16th bit + { + if (irmp_pulse_time >= SAMSUNG_PULSE_LEN_MIN && irmp_pulse_time <= SAMSUNG_PULSE_LEN_MAX && + irmp_pause_time >= SAMSUNG_START_BIT_PAUSE_LEN_MIN && irmp_pause_time <= SAMSUNG_START_BIT_PAUSE_LEN_MAX) + { +#ifdef ANALYZE + ANALYZE_PRINTF ("SYNC\n"); +#endif // ANALYZE + wait_for_space = 0; + irmp_bit++; + } + else if (irmp_pulse_time >= SAMSUNG_PULSE_LEN_MIN && irmp_pulse_time <= SAMSUNG_PULSE_LEN_MAX) + { +#if IRMP_SUPPORT_SAMSUNG48_PROTOCOL == 1 +#ifdef ANALYZE + ANALYZE_PRINTF ("Switching to SAMSUNG48 protocol "); +#endif // ANALYZE + irmp_param.protocol = IRMP_SAMSUNG48_PROTOCOL; + irmp_param.command_offset = SAMSUNG48_COMMAND_OFFSET; + irmp_param.command_end = SAMSUNG48_COMMAND_OFFSET + SAMSUNG48_COMMAND_LEN; + irmp_param.complete_len = SAMSUNG48_COMPLETE_DATA_LEN; +#else +#ifdef ANALYZE + ANALYZE_PRINTF ("Switching to SAMSUNG32 protocol "); +#endif // ANALYZE + irmp_param.protocol = IRMP_SAMSUNG32_PROTOCOL; + irmp_param.command_offset = SAMSUNG32_COMMAND_OFFSET; + irmp_param.command_end = SAMSUNG32_COMMAND_OFFSET + SAMSUNG32_COMMAND_LEN; + irmp_param.complete_len = SAMSUNG32_COMPLETE_DATA_LEN; +#endif + if (irmp_pause_time >= SAMSUNG_1_PAUSE_LEN_MIN && irmp_pause_time <= SAMSUNG_1_PAUSE_LEN_MAX) + { +#ifdef ANALYZE + ANALYZE_PUTCHAR ('1'); + ANALYZE_NEWLINE (); +#endif // ANALYZE + irmp_store_bit (1); + wait_for_space = 0; + } + else + { +#ifdef ANALYZE + ANALYZE_PUTCHAR ('0'); + ANALYZE_NEWLINE (); +#endif // ANALYZE + irmp_store_bit (0); + wait_for_space = 0; + } + } + else + { // timing incorrect! +#ifdef ANALYZE + ANALYZE_PRINTF ("error 3 Samsung: timing not correct: data bit %d, pulse: %d, pause: %d\n", irmp_bit, irmp_pulse_time, irmp_pause_time); + ANALYZE_ONLY_NORMAL_PUTCHAR ('\n'); +#endif // ANALYZE + irmp_start_bit_detected = 0; // reset flags and wait for next start bit + irmp_pause_time = 0; + } + } + else +#endif // IRMP_SUPPORT_SAMSUNG_PROTOCOL + +#if IRMP_SUPPORT_NEC16_PROTOCOL +#if IRMP_SUPPORT_NEC42_PROTOCOL == 1 + if (irmp_param.protocol == IRMP_NEC42_PROTOCOL && +#else // IRMP_SUPPORT_NEC_PROTOCOL instead + if (irmp_param.protocol == IRMP_NEC_PROTOCOL && +#endif // IRMP_SUPPORT_NEC42_PROTOCOL == 1 + irmp_bit == 8 && irmp_pause_time >= NEC_START_BIT_PAUSE_LEN_MIN && irmp_pause_time <= NEC_START_BIT_PAUSE_LEN_MAX) + { +#ifdef ANALYZE + ANALYZE_PRINTF ("Switching to NEC16 protocol\n"); +#endif // ANALYZE + irmp_param.protocol = IRMP_NEC16_PROTOCOL; + irmp_param.address_offset = NEC16_ADDRESS_OFFSET; + irmp_param.address_end = NEC16_ADDRESS_OFFSET + NEC16_ADDRESS_LEN; + irmp_param.command_offset = NEC16_COMMAND_OFFSET; + irmp_param.command_end = NEC16_COMMAND_OFFSET + NEC16_COMMAND_LEN; + irmp_param.complete_len = NEC16_COMPLETE_DATA_LEN; + wait_for_space = 0; + } + else +#endif // IRMP_SUPPORT_NEC16_PROTOCOL + +#if IRMP_SUPPORT_BANG_OLUFSEN_PROTOCOL == 1 + if (irmp_param.protocol == IRMP_BANG_OLUFSEN_PROTOCOL) + { + if (irmp_pulse_time >= BANG_OLUFSEN_PULSE_LEN_MIN && irmp_pulse_time <= BANG_OLUFSEN_PULSE_LEN_MAX) + { + if (irmp_bit == 1) // Bang & Olufsen: 3rd bit + { + if (irmp_pause_time >= BANG_OLUFSEN_START_BIT3_PAUSE_LEN_MIN && irmp_pause_time <= BANG_OLUFSEN_START_BIT3_PAUSE_LEN_MAX) + { +#ifdef ANALYZE + ANALYZE_PRINTF ("3rd start bit\n"); +#endif // ANALYZE + wait_for_space = 0; + irmp_bit++; + } + else + { // timing incorrect! +#ifdef ANALYZE + ANALYZE_PRINTF ("error 3a B&O: timing not correct: data bit %d, pulse: %d, pause: %d\n", irmp_bit, irmp_pulse_time, irmp_pause_time); + ANALYZE_ONLY_NORMAL_PUTCHAR ('\n'); +#endif // ANALYZE + irmp_start_bit_detected = 0; // reset flags and wait for next start bit + irmp_pause_time = 0; + } + } + else if (irmp_bit == 19) // Bang & Olufsen: trailer bit + { + if (irmp_pause_time >= BANG_OLUFSEN_TRAILER_BIT_PAUSE_LEN_MIN && irmp_pause_time <= BANG_OLUFSEN_TRAILER_BIT_PAUSE_LEN_MAX) + { +#ifdef ANALYZE + ANALYZE_PRINTF ("trailer bit\n"); +#endif // ANALYZE + wait_for_space = 0; + irmp_bit++; + } + else + { // timing incorrect! +#ifdef ANALYZE + ANALYZE_PRINTF ("error 3b B&O: timing not correct: data bit %d, pulse: %d, pause: %d\n", irmp_bit, irmp_pulse_time, irmp_pause_time); + ANALYZE_ONLY_NORMAL_PUTCHAR ('\n'); +#endif // ANALYZE + irmp_start_bit_detected = 0; // reset flags and wait for next start bit + irmp_pause_time = 0; + } + } + else + { + if (irmp_pause_time >= BANG_OLUFSEN_1_PAUSE_LEN_MIN && irmp_pause_time <= BANG_OLUFSEN_1_PAUSE_LEN_MAX) + { // pulse & pause timings correct for "1"? +#ifdef ANALYZE + ANALYZE_PUTCHAR ('1'); + ANALYZE_NEWLINE (); +#endif // ANALYZE + irmp_store_bit (1); + last_value = 1; + wait_for_space = 0; + } + else if (irmp_pause_time >= BANG_OLUFSEN_0_PAUSE_LEN_MIN && irmp_pause_time <= BANG_OLUFSEN_0_PAUSE_LEN_MAX) + { // pulse & pause timings correct for "0"? +#ifdef ANALYZE + ANALYZE_PUTCHAR ('0'); + ANALYZE_NEWLINE (); +#endif // ANALYZE + irmp_store_bit (0); + last_value = 0; + wait_for_space = 0; + } + else if (irmp_pause_time >= BANG_OLUFSEN_R_PAUSE_LEN_MIN && irmp_pause_time <= BANG_OLUFSEN_R_PAUSE_LEN_MAX) + { +#ifdef ANALYZE + ANALYZE_PUTCHAR (last_value + '0'); + ANALYZE_NEWLINE (); +#endif // ANALYZE + irmp_store_bit (last_value); + wait_for_space = 0; + } + else + { // timing incorrect! +#ifdef ANALYZE + ANALYZE_PRINTF ("error 3c B&O: timing not correct: data bit %d, pulse: %d, pause: %d\n", irmp_bit, irmp_pulse_time, irmp_pause_time); + ANALYZE_ONLY_NORMAL_PUTCHAR ('\n'); +#endif // ANALYZE + irmp_start_bit_detected = 0; // reset flags and wait for next start bit + irmp_pause_time = 0; + } + } + } + else + { // timing incorrect! +#ifdef ANALYZE + ANALYZE_PRINTF ("error 3d B&O: timing not correct: data bit %d, pulse: %d, pause: %d\n", irmp_bit, irmp_pulse_time, irmp_pause_time); + ANALYZE_ONLY_NORMAL_PUTCHAR ('\n'); +#endif // ANALYZE + irmp_start_bit_detected = 0; // reset flags and wait for next start bit + irmp_pause_time = 0; + } + } + else +#endif // IRMP_SUPPORT_BANG_OLUFSEN_PROTOCOL + +#if IRMP_SUPPORT_RCMM_PROTOCOL == 1 + if (irmp_param.protocol == IRMP_RCMM32_PROTOCOL) + { + if (irmp_pause_time >= RCMM32_BIT_00_PAUSE_LEN_MIN && irmp_pause_time <= RCMM32_BIT_00_PAUSE_LEN_MAX) + { +#ifdef ANALYZE + ANALYZE_PUTCHAR ('0'); + ANALYZE_PUTCHAR ('0'); +#endif // ANALYZE + irmp_store_bit (0); + irmp_store_bit (0); + } + else if (irmp_pause_time >= RCMM32_BIT_01_PAUSE_LEN_MIN && irmp_pause_time <= RCMM32_BIT_01_PAUSE_LEN_MAX) + { +#ifdef ANALYZE + ANALYZE_PUTCHAR ('0'); + ANALYZE_PUTCHAR ('1'); +#endif // ANALYZE + irmp_store_bit (0); + irmp_store_bit (1); + } + else if (irmp_pause_time >= RCMM32_BIT_10_PAUSE_LEN_MIN && irmp_pause_time <= RCMM32_BIT_10_PAUSE_LEN_MAX) + { +#ifdef ANALYZE + ANALYZE_PUTCHAR ('1'); + ANALYZE_PUTCHAR ('0'); +#endif // ANALYZE + irmp_store_bit (1); + irmp_store_bit (0); + } + else if (irmp_pause_time >= RCMM32_BIT_11_PAUSE_LEN_MIN && irmp_pause_time <= RCMM32_BIT_11_PAUSE_LEN_MAX) + { +#ifdef ANALYZE + ANALYZE_PUTCHAR ('1'); + ANALYZE_PUTCHAR ('1'); +#endif // ANALYZE + irmp_store_bit (1); + irmp_store_bit (1); + } +#ifdef ANALYZE + ANALYZE_PRINTF ("\n"); +#endif // ANALYZE + wait_for_space = 0; + } + else +#endif + + if (irmp_pulse_time >= irmp_param.pulse_1_len_min && irmp_pulse_time <= irmp_param.pulse_1_len_max && + irmp_pause_time >= irmp_param.pause_1_len_min && irmp_pause_time <= irmp_param.pause_1_len_max) + { // pulse & pause timings correct for "1"? +#ifdef ANALYZE + ANALYZE_PUTCHAR ('1'); + ANALYZE_NEWLINE (); +#endif // ANALYZE + irmp_store_bit (1); + wait_for_space = 0; + } + else if (irmp_pulse_time >= irmp_param.pulse_0_len_min && irmp_pulse_time <= irmp_param.pulse_0_len_max && + irmp_pause_time >= irmp_param.pause_0_len_min && irmp_pause_time <= irmp_param.pause_0_len_max) + { // pulse & pause timings correct for "0"? +#ifdef ANALYZE + ANALYZE_PUTCHAR ('0'); + ANALYZE_NEWLINE (); +#endif // ANALYZE + irmp_store_bit (0); + wait_for_space = 0; + } + else +#if IRMP_SUPPORT_KATHREIN_PROTOCOL + + if (irmp_param.protocol == IRMP_KATHREIN_PROTOCOL && + irmp_pulse_time >= KATHREIN_1_PULSE_LEN_MIN && irmp_pulse_time <= KATHREIN_1_PULSE_LEN_MAX && + (((irmp_bit == 8 || irmp_bit == 6) && + irmp_pause_time >= KATHREIN_SYNC_BIT_PAUSE_LEN_MIN && irmp_pause_time <= KATHREIN_SYNC_BIT_PAUSE_LEN_MAX) || + (irmp_bit == 12 && + irmp_pause_time >= KATHREIN_START_BIT_PAUSE_LEN_MIN && irmp_pause_time <= KATHREIN_START_BIT_PAUSE_LEN_MAX))) + + { + if (irmp_bit == 8) + { + irmp_bit++; +#ifdef ANALYZE + ANALYZE_PUTCHAR ('S'); + ANALYZE_NEWLINE (); +#endif // ANALYZE + irmp_tmp_command <<= 1; + } + else + { +#ifdef ANALYZE + ANALYZE_PUTCHAR ('S'); + ANALYZE_NEWLINE (); +#endif // ANALYZE + irmp_store_bit (1); + } + wait_for_space = 0; + } + else +#endif // IRMP_SUPPORT_KATHREIN_PROTOCOL + { // timing incorrect! +#ifdef ANALYZE + ANALYZE_PRINTF ("error 3: timing not correct: data bit %d, pulse: %d, pause: %d\n", irmp_bit, irmp_pulse_time, irmp_pause_time); + ANALYZE_ONLY_NORMAL_PUTCHAR ('\n'); +#endif // ANALYZE + irmp_start_bit_detected = 0; // reset flags and wait for next start bit + irmp_pause_time = 0; + } + + irmp_pulse_time = 1; // set counter to 1, not 0 + } + } + else + { // counting the pulse length ... + if (! irmp_input) // still light? + { // yes... + irmp_pulse_time++; // increment counter + } + else + { // now it's dark! + wait_for_space = 1; // let's count the time (see above) + irmp_pause_time = 1; // set pause counter to 1, not 0 + +#if IRMP_SUPPORT_RCII_PROTOCOL == 1 + if (irmp_param.protocol == IRMP_RCII_PROTOCOL && waiting_for_2nd_pulse) + { +printf ("fm: %d %d\n", irmp_pulse_time * 1000000 / F_INTERRUPTS, RCII_BIT_LEN * 1000000 / F_INTERRUPTS); // fm: Ausgabe ist "1000 466" oder "1533 466" +#if 0 + if (irmp_pulse_time >= RCII_BIT_LEN) + { + irmp_pulse_time -= RCII_BIT_LEN; + last_value = 0; + } + else + { + last_value = 1; + } +#else // fm: das reicht für RCII + irmp_pulse_time -= RCII_BIT_LEN; + last_value = 0; +#endif + +#ifdef ANALYZE + ANALYZE_PRINTF ("RCII: got 2nd pulse, irmp_pulse_time = %d\n", irmp_pulse_time); +#endif + waiting_for_2nd_pulse = 0; + } +#endif + } + } + + if (irmp_start_bit_detected && irmp_bit == irmp_param.complete_len && irmp_param.stop_bit == 0) // enough bits received? + { + if (last_irmp_command == irmp_tmp_command && key_repetition_len < AUTO_FRAME_REPETITION_LEN) + { + repetition_frame_number++; + } + else + { + repetition_frame_number = 0; + } + +#if IRMP_SUPPORT_SIRCS_PROTOCOL == 1 + // if SIRCS protocol and the code will be repeated within 50 ms, we will ignore 2nd and 3rd repetition frame + if (irmp_param.protocol == IRMP_SIRCS_PROTOCOL && (repetition_frame_number == 1 || repetition_frame_number == 2)) + { +#ifdef ANALYZE + ANALYZE_PRINTF ("code skipped: SIRCS auto repetition frame #%d, counter = %d, auto repetition len = %d\n", + repetition_frame_number + 1, key_repetition_len, AUTO_FRAME_REPETITION_LEN); +#endif // ANALYZE + key_repetition_len = 0; + } + else +#endif + +#if IRMP_SUPPORT_ORTEK_PROTOCOL == 1 + // if ORTEK protocol and the code will be repeated within 50 ms, we will ignore 2nd repetition frame + if (irmp_param.protocol == IRMP_ORTEK_PROTOCOL && repetition_frame_number == 1) + { +#ifdef ANALYZE + ANALYZE_PRINTF ("code skipped: ORTEK auto repetition frame #%d, counter = %d, auto repetition len = %d\n", + repetition_frame_number + 1, key_repetition_len, AUTO_FRAME_REPETITION_LEN); +#endif // ANALYZE + key_repetition_len = 0; + } + else +#endif + +#if 0 && IRMP_SUPPORT_KASEIKYO_PROTOCOL == 1 // fm 2015-12-02: don't ignore every 2nd frame + // if KASEIKYO protocol and the code will be repeated within 50 ms, we will ignore 2nd repetition frame + if (irmp_param.protocol == IRMP_KASEIKYO_PROTOCOL && repetition_frame_number == 1) + { +#ifdef ANALYZE + ANALYZE_PRINTF ("code skipped: KASEIKYO auto repetition frame #%d, counter = %d, auto repetition len = %d\n", + repetition_frame_number + 1, key_repetition_len, AUTO_FRAME_REPETITION_LEN); +#endif // ANALYZE + key_repetition_len = 0; + } + else +#endif + +#if 0 && IRMP_SUPPORT_SAMSUNG_PROTOCOL == 1 // fm 2015-12-02: don't ignore every 2nd frame + // if SAMSUNG32 or SAMSUNG48 protocol and the code will be repeated within 50 ms, we will ignore every 2nd frame + if ((irmp_param.protocol == IRMP_SAMSUNG32_PROTOCOL || irmp_param.protocol == IRMP_SAMSUNG48_PROTOCOL) && (repetition_frame_number & 0x01)) + { +#ifdef ANALYZE + ANALYZE_PRINTF ("code skipped: SAMSUNG32/SAMSUNG48 auto repetition frame #%d, counter = %d, auto repetition len = %d\n", + repetition_frame_number + 1, key_repetition_len, AUTO_FRAME_REPETITION_LEN); +#endif // ANALYZE + key_repetition_len = 0; + } + else +#endif + +#if IRMP_SUPPORT_NUBERT_PROTOCOL == 1 + // if NUBERT protocol and the code will be repeated within 50 ms, we will ignore every 2nd frame + if (irmp_param.protocol == IRMP_NUBERT_PROTOCOL && (repetition_frame_number & 0x01)) + { +#ifdef ANALYZE + ANALYZE_PRINTF ("code skipped: NUBERT auto repetition frame #%d, counter = %d, auto repetition len = %d\n", + repetition_frame_number + 1, key_repetition_len, AUTO_FRAME_REPETITION_LEN); +#endif // ANALYZE + key_repetition_len = 0; + } + else +#endif + +#if IRMP_SUPPORT_SPEAKER_PROTOCOL == 1 + // if SPEAKER protocol and the code will be repeated within 50 ms, we will ignore every 2nd frame + if (irmp_param.protocol == IRMP_SPEAKER_PROTOCOL && (repetition_frame_number & 0x01)) + { +#ifdef ANALYZE + ANALYZE_PRINTF ("code skipped: SPEAKER auto repetition frame #%d, counter = %d, auto repetition len = %d\n", + repetition_frame_number + 1, key_repetition_len, AUTO_FRAME_REPETITION_LEN); +#endif // ANALYZE + key_repetition_len = 0; + } + else +#endif + + { +#ifdef ANALYZE + ANALYZE_PRINTF ("%8.3fms code detected, length = %d\n", (double) (time_counter * 1000) / F_INTERRUPTS, irmp_bit); +#endif // ANALYZE + irmp_ir_detected = TRUE; + +#if IRMP_SUPPORT_DENON_PROTOCOL == 1 + if (irmp_param.protocol == IRMP_DENON_PROTOCOL) + { // check for repetition frame + if ((~irmp_tmp_command & 0x3FF) == last_irmp_denon_command) // command bits must be inverted + { + irmp_tmp_command = last_irmp_denon_command; // use command received before! + last_irmp_denon_command = 0; + + irmp_protocol = irmp_param.protocol; // store protocol + irmp_address = irmp_tmp_address; // store address + irmp_command = irmp_tmp_command; // store command + } + else + { + if ((irmp_tmp_command & 0x01) == 0x00) + { +#ifdef ANALYZE + ANALYZE_PRINTF ("%8.3fms info Denon: waiting for inverted command repetition\n", (double) (time_counter * 1000) / F_INTERRUPTS); +#endif // ANALYZE + last_irmp_denon_command = irmp_tmp_command; + denon_repetition_len = 0; + irmp_ir_detected = FALSE; + } + else + { +#ifdef ANALYZE + ANALYZE_PRINTF ("%8.3fms warning Denon: got unexpected inverted command, ignoring it\n", (double) (time_counter * 1000) / F_INTERRUPTS); +#endif // ANALYZE + last_irmp_denon_command = 0; + irmp_ir_detected = FALSE; + } + } + } + else +#endif // IRMP_SUPPORT_DENON_PROTOCOL + +#if IRMP_SUPPORT_GRUNDIG_PROTOCOL == 1 + if (irmp_param.protocol == IRMP_GRUNDIG_PROTOCOL && irmp_tmp_command == 0x01ff) + { // Grundig start frame? +#ifdef ANALYZE + ANALYZE_PRINTF ("Detected GRUNDIG start frame, ignoring it\n"); +#endif // ANALYZE + irmp_ir_detected = FALSE; + } + else +#endif // IRMP_SUPPORT_GRUNDIG_PROTOCOL + +#if IRMP_SUPPORT_NOKIA_PROTOCOL == 1 + if (irmp_param.protocol == IRMP_NOKIA_PROTOCOL && irmp_tmp_address == 0x00ff && irmp_tmp_command == 0x00fe) + { // Nokia start frame? +#ifdef ANALYZE + ANALYZE_PRINTF ("Detected NOKIA start frame, ignoring it\n"); +#endif // ANALYZE + irmp_ir_detected = FALSE; + } + else +#endif // IRMP_SUPPORT_NOKIA_PROTOCOL + { +#if IRMP_SUPPORT_NEC_PROTOCOL == 1 + if (irmp_param.protocol == IRMP_NEC_PROTOCOL && irmp_bit == 0) // repetition frame + { + if (key_repetition_len < NEC_FRAME_REPEAT_PAUSE_LEN_MAX) + { +#ifdef ANALYZE + ANALYZE_PRINTF ("Detected NEC repetition frame, key_repetition_len = %d\n", key_repetition_len); + ANALYZE_ONLY_NORMAL_PRINTF("REPETETION FRAME "); +#endif // ANALYZE + irmp_tmp_address = last_irmp_address; // address is last address + irmp_tmp_command = last_irmp_command; // command is last command + irmp_flags |= IRMP_FLAG_REPETITION; + key_repetition_len = 0; + } + else + { +#ifdef ANALYZE + ANALYZE_PRINTF ("Detected NEC repetition frame, ignoring it: timeout occured, key_repetition_len = %d > %d\n", + key_repetition_len, NEC_FRAME_REPEAT_PAUSE_LEN_MAX); +#endif // ANALYZE + irmp_ir_detected = FALSE; + } + } +#endif // IRMP_SUPPORT_NEC_PROTOCOL + +#if IRMP_SUPPORT_KASEIKYO_PROTOCOL == 1 + if (irmp_param.protocol == IRMP_KASEIKYO_PROTOCOL) + { + uint_fast8_t xor_value; + + xor_value = (xor_check[0] & 0x0F) ^ ((xor_check[0] & 0xF0) >> 4) ^ (xor_check[1] & 0x0F) ^ ((xor_check[1] & 0xF0) >> 4); + + if (xor_value != (xor_check[2] & 0x0F)) + { +#ifdef ANALYZE + ANALYZE_PRINTF ("error 4: wrong XOR check for customer id: 0x%1x 0x%1x\n", xor_value, xor_check[2] & 0x0F); +#endif // ANALYZE + irmp_ir_detected = FALSE; + } + + xor_value = xor_check[2] ^ xor_check[3] ^ xor_check[4]; + + if (xor_value != xor_check[5]) + { +#ifdef ANALYZE + ANALYZE_PRINTF ("error 5: wrong XOR check for data bits: 0x%02x 0x%02x\n", xor_value, xor_check[5]); +#endif // ANALYZE + irmp_ir_detected = FALSE; + } + + irmp_flags |= genre2; // write the genre2 bits into MSB of the flag byte + } +#endif // IRMP_SUPPORT_KASEIKYO_PROTOCOL == 1 + +#if IRMP_SUPPORT_ORTEK_PROTOCOL == 1 + if (irmp_param.protocol == IRMP_ORTEK_PROTOCOL) + { + if (parity == PARITY_CHECK_FAILED) + { +#ifdef ANALYZE + ANALYZE_PRINTF ("error 6: parity check failed\n"); +#endif // ANALYZE + irmp_ir_detected = FALSE; + } + + if ((irmp_tmp_address & 0x03) == 0x02) + { +#ifdef ANALYZE + ANALYZE_PRINTF ("code skipped: ORTEK end of transmission frame (key release)\n"); +#endif // ANALYZE + irmp_ir_detected = FALSE; + } + irmp_tmp_address >>= 2; + } +#endif // IRMP_SUPPORT_ORTEK_PROTOCOL == 1 + +#if IRMP_SUPPORT_MITSU_HEAVY_PROTOCOL == 1 + if (irmp_param.protocol == IRMP_MITSU_HEAVY_PROTOCOL) + { + check = irmp_tmp_command >> 8; // inverted upper byte == lower byte? + check = ~ check; + if (check == (irmp_tmp_command & 0xFF)) { //ok: + irmp_tmp_command &= 0xFF; + } + else mitsu_parity = PARITY_CHECK_FAILED; + if (mitsu_parity == PARITY_CHECK_FAILED) + { +#ifdef ANALYZE + ANALYZE_PRINTF ("error 7: parity check failed\n"); +#endif // ANALYZE + irmp_ir_detected = FALSE; + } + } +#endif // IRMP_SUPPORT_MITSU_HEAVY_PROTOCOL + +#if IRMP_SUPPORT_RC6_PROTOCOL == 1 + if (irmp_param.protocol == IRMP_RC6_PROTOCOL && irmp_param.complete_len == RC6_COMPLETE_DATA_LEN_LONG) // RC6 mode = 6? + { + irmp_protocol = IRMP_RC6A_PROTOCOL; + } + else +#endif // IRMP_SUPPORT_RC6_PROTOCOL == 1 + { + irmp_protocol = irmp_param.protocol; + } + +#if IRMP_SUPPORT_FDC_PROTOCOL == 1 + if (irmp_param.protocol == IRMP_FDC_PROTOCOL) + { + if (irmp_tmp_command & 0x000F) // released key? + { + irmp_tmp_command = (irmp_tmp_command >> 4) | 0x80; // yes, set bit 7 + } + else + { + irmp_tmp_command >>= 4; // no, it's a pressed key + } + irmp_tmp_command |= (irmp_tmp_address << 2) & 0x0F00; // 000000CCCCAAAAAA -> 0000CCCC00000000 + irmp_tmp_address &= 0x003F; + } +#endif + + irmp_address = irmp_tmp_address; // store address +#if IRMP_SUPPORT_NEC_PROTOCOL == 1 + if (irmp_param.protocol == IRMP_NEC_PROTOCOL) + { + last_irmp_address = irmp_tmp_address; // store as last address, too + } +#endif + +#if IRMP_SUPPORT_RC5_PROTOCOL == 1 + if (irmp_param.protocol == IRMP_RC5_PROTOCOL) + { + irmp_tmp_command |= rc5_cmd_bit6; // store bit 6 + } +#endif +#if IRMP_SUPPORT_S100_PROTOCOL == 1 + if (irmp_param.protocol == IRMP_S100_PROTOCOL) + { + irmp_tmp_command |= rc5_cmd_bit6; // store bit 6 + } +#endif + irmp_command = irmp_tmp_command; // store command + +#if IRMP_SUPPORT_SAMSUNG_PROTOCOL == 1 + irmp_id = irmp_tmp_id; +#endif + } + } + + if (irmp_ir_detected) + { + if (last_irmp_command == irmp_tmp_command && + last_irmp_address == irmp_tmp_address && + key_repetition_len < IRMP_KEY_REPETITION_LEN) + { + irmp_flags |= IRMP_FLAG_REPETITION; + } + + last_irmp_address = irmp_tmp_address; // store as last address, too + last_irmp_command = irmp_tmp_command; // store as last command, too + + key_repetition_len = 0; + } + else + { +#ifdef ANALYZE + ANALYZE_ONLY_NORMAL_PUTCHAR ('\n'); +#endif // ANALYZE + } + + irmp_start_bit_detected = 0; // and wait for next start bit + irmp_tmp_command = 0; + irmp_pulse_time = 0; + irmp_pause_time = 0; + +#if IRMP_SUPPORT_JVC_PROTOCOL == 1 + if (irmp_protocol == IRMP_JVC_PROTOCOL) // the stop bit of JVC frame is also start bit of next frame + { // set pulse time here! + irmp_pulse_time = ((uint_fast8_t)(F_INTERRUPTS * JVC_START_BIT_PULSE_TIME)); + } +#endif // IRMP_SUPPORT_JVC_PROTOCOL == 1 + } + } + } + +#if defined(STELLARIS_ARM_CORTEX_M4) + // Clear the timer interrupt + TimerIntClear(TIMER1_BASE, TIMER_TIMA_TIMEOUT); +#endif + +#if (defined(_CHIBIOS_RT_) || defined(_CHIBIOS_NIL_)) && IRMP_USE_EVENT == 1 + if (IRMP_EVENT_THREAD_PTR != NULL && irmp_ir_detected) + chEvtSignalI(IRMP_EVENT_THREAD_PTR,IRMP_EVENT_BIT); +#endif + +#if IRMP_USE_IDLE_CALL == 1 + // check if there is no ongoing transmission or repetition + if (!irmp_start_bit_detected && !irmp_pulse_time + && key_repetition_len > IRMP_KEY_REPETITION_LEN) + { + // no ongoing transmission + // enough time passed since last decoded signal that a repetition won't affect our output + + irmp_idle(); + } +#endif // IRMP_USE_IDLE_CALL + + return (irmp_ir_detected); +} + +#ifdef ANALYZE + +/*--------------------------------------------------------------------------------------------------------------------------------------------------- + * main functions - for Unix/Linux + Windows only! + * + * AVR: see main.c! + * + * Compile it under linux with: + * cc irmp.c -o irmp + * + * usage: ./irmp [-v|-s|-a|-l] < file + * + * options: + * -v verbose + * -s silent + * -a analyze + * -l list pulse/pauses + *--------------------------------------------------------------------------------------------------------------------------------------------------- + */ + +void +print_spectrum (char * text, int * buf, int is_pulse) +{ + int i; + int j; + int min; + int max; + int max_value = 0; + int value; + int sum = 0; + int counter = 0; + double average = 0; + double tolerance; + + puts ("-----------------------------------------------------------------------------"); + printf ("%s:\n", text); + + for (i = 0; i < 256; i++) + { + if (buf[i] > max_value) + { + max_value = buf[i]; + } + } + + for (i = 1; i < 200; i++) + { + if (buf[i] > 0) + { + printf ("%3d ", i); + value = (buf[i] * 60) / max_value; + + for (j = 0; j < value; j++) + { + putchar ('o'); + } + printf (" %d\n", buf[i]); + + sum += i * buf[i]; + counter += buf[i]; + } + else + { + max = i - 1; + + if (counter > 0) + { + average = (float) sum / (float) counter; + + if (is_pulse) + { + printf ("pulse "); + } + else + { + printf ("pause "); + } + + printf ("avg: %4.1f=%6.1f us, ", average, (1000000. * average) / (float) F_INTERRUPTS); + printf ("min: %2d=%6.1f us, ", min, (1000000. * min) / (float) F_INTERRUPTS); + printf ("max: %2d=%6.1f us, ", max, (1000000. * max) / (float) F_INTERRUPTS); + + tolerance = (max - average); + + if (average - min > tolerance) + { + tolerance = average - min; + } + + tolerance = tolerance * 100 / average; + printf ("tol: %4.1f%%\n", tolerance); + } + + counter = 0; + sum = 0; + min = i + 1; + } + } +} + +#define STATE_LEFT_SHIFT 0x01 +#define STATE_RIGHT_SHIFT 0x02 +#define STATE_LEFT_CTRL 0x04 +#define STATE_LEFT_ALT 0x08 +#define STATE_RIGHT_ALT 0x10 + +#define KEY_ESCAPE 0x1B // keycode = 0x006e +#define KEY_MENUE 0x80 // keycode = 0x0070 +#define KEY_BACK 0x81 // keycode = 0x0071 +#define KEY_FORWARD 0x82 // keycode = 0x0072 +#define KEY_ADDRESS 0x83 // keycode = 0x0073 +#define KEY_WINDOW 0x84 // keycode = 0x0074 +#define KEY_1ST_PAGE 0x85 // keycode = 0x0075 +#define KEY_STOP 0x86 // keycode = 0x0076 +#define KEY_MAIL 0x87 // keycode = 0x0077 +#define KEY_FAVORITES 0x88 // keycode = 0x0078 +#define KEY_NEW_PAGE 0x89 // keycode = 0x0079 +#define KEY_SETUP 0x8A // keycode = 0x007a +#define KEY_FONT 0x8B // keycode = 0x007b +#define KEY_PRINT 0x8C // keycode = 0x007c +#define KEY_ON_OFF 0x8E // keycode = 0x007c + +#define KEY_INSERT 0x90 // keycode = 0x004b +#define KEY_DELETE 0x91 // keycode = 0x004c +#define KEY_LEFT 0x92 // keycode = 0x004f +#define KEY_HOME 0x93 // keycode = 0x0050 +#define KEY_END 0x94 // keycode = 0x0051 +#define KEY_UP 0x95 // keycode = 0x0053 +#define KEY_DOWN 0x96 // keycode = 0x0054 +#define KEY_PAGE_UP 0x97 // keycode = 0x0055 +#define KEY_PAGE_DOWN 0x98 // keycode = 0x0056 +#define KEY_RIGHT 0x99 // keycode = 0x0059 +#define KEY_MOUSE_1 0x9E // keycode = 0x0400 +#define KEY_MOUSE_2 0x9F // keycode = 0x0800 + +static uint_fast8_t +get_fdc_key (uint_fast16_t cmd) +{ + static uint8_t key_table[128] = + { + // 0 1 2 3 4 5 6 7 8 9 A B C D E F + 0, '^', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', 0xDF, '´', 0, '\b', + '\t', 'q', 'w', 'e', 'r', 't', 'z', 'u', 'i', 'o', 'p', 0xFC, '+', 0, 0, 'a', + 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', 0xF6, 0xE4, '#', '\r', 0, '<', 'y', 'x', + 'c', 'v', 'b', 'n', 'm', ',', '.', '-', 0, 0, 0, 0, 0, ' ', 0, 0, + + 0, '°', '!', '"', '§', '$', '%', '&', '/', '(', ')', '=', '?', '`', 0, '\b', + '\t', 'Q', 'W', 'E', 'R', 'T', 'Z', 'U', 'I', 'O', 'P', 0xDC, '*', 0, 0, 'A', + 'S', 'D', 'F', 'G', 'H', 'J', 'K', 'L', 0xD6, 0xC4, '\'', '\r', 0, '>', 'Y', 'X', + 'C', 'V', 'B', 'N', 'M', ';', ':', '_', 0, 0, 0, 0, 0, ' ', 0, 0 + }; + static uint_fast8_t state; + + uint_fast8_t key = 0; + + switch (cmd) + { + case 0x002C: state |= STATE_LEFT_SHIFT; break; // pressed left shift + case 0x00AC: state &= ~STATE_LEFT_SHIFT; break; // released left shift + case 0x0039: state |= STATE_RIGHT_SHIFT; break; // pressed right shift + case 0x00B9: state &= ~STATE_RIGHT_SHIFT; break; // released right shift + case 0x003A: state |= STATE_LEFT_CTRL; break; // pressed left ctrl + case 0x00BA: state &= ~STATE_LEFT_CTRL; break; // released left ctrl + case 0x003C: state |= STATE_LEFT_ALT; break; // pressed left alt + case 0x00BC: state &= ~STATE_LEFT_ALT; break; // released left alt + case 0x003E: state |= STATE_RIGHT_ALT; break; // pressed left alt + case 0x00BE: state &= ~STATE_RIGHT_ALT; break; // released left alt + + case 0x006e: key = KEY_ESCAPE; break; + case 0x004b: key = KEY_INSERT; break; + case 0x004c: key = KEY_DELETE; break; + case 0x004f: key = KEY_LEFT; break; + case 0x0050: key = KEY_HOME; break; + case 0x0051: key = KEY_END; break; + case 0x0053: key = KEY_UP; break; + case 0x0054: key = KEY_DOWN; break; + case 0x0055: key = KEY_PAGE_UP; break; + case 0x0056: key = KEY_PAGE_DOWN; break; + case 0x0059: key = KEY_RIGHT; break; + case 0x0400: key = KEY_MOUSE_1; break; + case 0x0800: key = KEY_MOUSE_2; break; + + default: + { + if (!(cmd & 0x80)) // pressed key + { + if (cmd >= 0x70 && cmd <= 0x7F) // function keys + { + key = cmd + 0x10; // 7x -> 8x + } + else if (cmd < 64) // key listed in key_table + { + if (state & (STATE_LEFT_ALT | STATE_RIGHT_ALT)) + { + switch (cmd) + { + case 0x0003: key = 0xB2; break; // upper 2 + case 0x0008: key = '{'; break; + case 0x0009: key = '['; break; + case 0x000A: key = ']'; break; + case 0x000B: key = '}'; break; + case 0x000C: key = '\\'; break; + case 0x001C: key = '~'; break; + case 0x002D: key = '|'; break; + case 0x0034: key = 0xB5; break; // Mu + } + } + else if (state & (STATE_LEFT_CTRL)) + { + if (key_table[cmd] >= 'a' && key_table[cmd] <= 'z') + { + key = key_table[cmd] - 'a' + 1; + } + else + { + key = key_table[cmd]; + } + } + else + { + int idx = cmd + ((state & (STATE_LEFT_SHIFT | STATE_RIGHT_SHIFT)) ? 64 : 0); + + if (key_table[idx]) + { + key = key_table[idx]; + } + } + } + } + break; + } + } + + return (key); +} + +static int analyze = FALSE; +static int list = FALSE; +static IRMP_DATA irmp_data; +static int expected_protocol; +static int expected_address; +static int expected_command; +static int do_check_expected_values; + +static void +next_tick (void) +{ + if (! analyze && ! list) + { + (void) irmp_ISR (); + + if (irmp_get_data (&irmp_data)) + { + uint_fast8_t key; + + ANALYZE_ONLY_NORMAL_PUTCHAR (' '); + + if (verbose) + { + printf ("%8.3fms ", (double) (time_counter * 1000) / F_INTERRUPTS); + } + + if (irmp_data.protocol == IRMP_ACP24_PROTOCOL) + { + uint16_t temp = (irmp_data.command & 0x000F) + 15; + + printf ("p=%2d (%s), a=0x%04x, c=0x%04x, f=0x%02x, temp=%d", + irmp_data.protocol, irmp_protocol_names[irmp_data.protocol], irmp_data.address, irmp_data.command, irmp_data.flags, temp); + } + else if (irmp_data.protocol == IRMP_FDC_PROTOCOL && (key = get_fdc_key (irmp_data.command)) != 0) + { + if ((key >= 0x20 && key < 0x7F) || key >= 0xA0) + { + printf ("p=%2d (%s), a=0x%04x, c=0x%04x, f=0x%02x, asc=0x%02x, key='%c'", + irmp_data.protocol, irmp_protocol_names[irmp_data.protocol], irmp_data.address, irmp_data.command, irmp_data.flags, key, key); + } + else if (key == '\r' || key == '\t' || key == KEY_ESCAPE || (key >= 0x80 && key <= 0x9F)) // function keys + { + char * p = (char *) NULL; + + switch (key) + { + case '\t' : p = "TAB"; break; + case '\r' : p = "CR"; break; + case KEY_ESCAPE : p = "ESCAPE"; break; + case KEY_MENUE : p = "MENUE"; break; + case KEY_BACK : p = "BACK"; break; + case KEY_FORWARD : p = "FORWARD"; break; + case KEY_ADDRESS : p = "ADDRESS"; break; + case KEY_WINDOW : p = "WINDOW"; break; + case KEY_1ST_PAGE : p = "1ST_PAGE"; break; + case KEY_STOP : p = "STOP"; break; + case KEY_MAIL : p = "MAIL"; break; + case KEY_FAVORITES : p = "FAVORITES"; break; + case KEY_NEW_PAGE : p = "NEW_PAGE"; break; + case KEY_SETUP : p = "SETUP"; break; + case KEY_FONT : p = "FONT"; break; + case KEY_PRINT : p = "PRINT"; break; + case KEY_ON_OFF : p = "ON_OFF"; break; + + case KEY_INSERT : p = "INSERT"; break; + case KEY_DELETE : p = "DELETE"; break; + case KEY_LEFT : p = "LEFT"; break; + case KEY_HOME : p = "HOME"; break; + case KEY_END : p = "END"; break; + case KEY_UP : p = "UP"; break; + case KEY_DOWN : p = "DOWN"; break; + case KEY_PAGE_UP : p = "PAGE_UP"; break; + case KEY_PAGE_DOWN : p = "PAGE_DOWN"; break; + case KEY_RIGHT : p = "RIGHT"; break; + case KEY_MOUSE_1 : p = "KEY_MOUSE_1"; break; + case KEY_MOUSE_2 : p = "KEY_MOUSE_2"; break; + default : p = "<UNKNWON>"; break; + } + + printf ("p=%2d (%s), a=0x%04x, c=0x%04x, f=0x%02x, asc=0x%02x, key=%s", + irmp_data.protocol, irmp_protocol_names[irmp_data.protocol], irmp_data.address, irmp_data.command, irmp_data.flags, key, p); + } + else + { + printf ("p=%2d (%s), a=0x%04x, c=0x%04x, f=0x%02x, asc=0x%02x", + irmp_data.protocol, irmp_protocol_names[irmp_data.protocol], irmp_data.address, irmp_data.command, irmp_data.flags, key); + } + } + else + { + printf ("p=%2d (%s), a=0x%04x, c=0x%04x, f=0x%02x", + irmp_data.protocol, irmp_protocol_names[irmp_data.protocol], irmp_data.address, irmp_data.command, irmp_data.flags); + } + + if (do_check_expected_values) + { + if (irmp_data.protocol != expected_protocol || + irmp_data.address != expected_address || + irmp_data.command != expected_command) + { + printf ("\nerror 7: expected values differ: p=%2d (%s), a=0x%04x, c=0x%04x\n", + expected_protocol, irmp_protocol_names[expected_protocol], expected_address, expected_command); + } + else + { + printf (" checked!\n"); + } + do_check_expected_values = FALSE; // only check 1st frame in a line! + } + else + { + putchar ('\n'); + } + } + } +} + +int +main (int argc, char ** argv) +{ + int i; + int ch; + int last_ch = 0; + int pulse = 0; + int pause = 0; + + int start_pulses[256]; + int start_pauses[256]; + int pulses[256]; + int pauses[256]; + + int first_pulse = TRUE; + int first_pause = TRUE; + + if (argc == 2) + { + if (! strcmp (argv[1], "-v")) + { + verbose = TRUE; + } + else if (! strcmp (argv[1], "-l")) + { + list = TRUE; + } + else if (! strcmp (argv[1], "-a")) + { + analyze = TRUE; + } + else if (! strcmp (argv[1], "-s")) + { + silent = TRUE; + } + else if (! strcmp (argv[1], "-r")) + { + radio = TRUE; + } + } + + for (i = 0; i < 256; i++) + { + start_pulses[i] = 0; + start_pauses[i] = 0; + pulses[i] = 0; + pauses[i] = 0; + } + + IRMP_PIN = 0xFF; + + while ((ch = getchar ()) != EOF) + { + if (ch == '_' || ch == '0') + { + if (last_ch != ch) + { + if (pause > 0) + { + if (list) + { + printf ("pause: %d\n", pause); + } + + if (analyze) + { + if (first_pause) + { + if (pause < 256) + { + start_pauses[pause]++; + } + first_pause = FALSE; + } + else + { + if (pause < 256) + { + pauses[pause]++; + } + } + } + } + pause = 0; + } + pulse++; + IRMP_PIN = 0x00; + } + else if (ch == 0xaf || ch == '-' || ch == '1') + { + if (last_ch != ch) + { + if (list) + { + printf ("pulse: %d ", pulse); + } + + if (analyze) + { + if (first_pulse) + { + if (pulse < 256) + { + start_pulses[pulse]++; + } + first_pulse = FALSE; + } + else + { + if (pulse < 256) + { + pulses[pulse]++; + } + } + } + pulse = 0; + } + + pause++; + IRMP_PIN = 0xff; + } + else if (ch == '\n') + { + IRMP_PIN = 0xff; + time_counter = 0; + + if (list && pause > 0) + { + printf ("pause: %d\n", pause); + } + pause = 0; + + if (! analyze) + { + for (i = 0; i < (int) ((10000.0 * F_INTERRUPTS) / 10000); i++) // newline: long pause of 10000 msec + { + next_tick (); + } + } + first_pulse = TRUE; + first_pause = TRUE; + } + else if (ch == '#') + { + time_counter = 0; + + if (analyze) + { + while ((ch = getchar()) != '\n' && ch != EOF) + { + ; + } + } + else + { + char buf[1024]; + char * p; + int idx = -1; + + puts ("----------------------------------------------------------------------"); + putchar (ch); + + + while ((ch = getchar()) != '\n' && ch != EOF) + { + if (ch != '\r') // ignore CR in DOS/Windows files + { + if (ch == '[' && idx == -1) + { + idx = 0; + } + else if (idx >= 0) + { + if (ch == ']') + { + do_check_expected_values = FALSE; + buf[idx] = '\0'; + idx = -1; + + expected_protocol = atoi (buf); + + if (expected_protocol > 0) + { + p = buf; + while (*p) + { + if (*p == 'x') + { + p++; + + if (sscanf (p, "%x", &expected_address) == 1) + { + do_check_expected_values = TRUE; + } + break; + } + p++; + } + + if (do_check_expected_values) + { + do_check_expected_values = FALSE; + + while (*p) + { + if (*p == 'x') + { + p++; + + if (sscanf (p, "%x", &expected_command) == 1) + { + do_check_expected_values = TRUE; + } + break; + } + p++; + } + + if (do_check_expected_values) + { + // printf ("!%2d %04x %04x!\n", expected_protocol, expected_address, expected_command); + } + } + } + } + else if (idx < 1024 - 2) + { + buf[idx++] = ch; + } + } + putchar (ch); + } + } + putchar ('\n'); + } + + } + + last_ch = ch; + + next_tick (); + } + + if (analyze) + { + print_spectrum ("START PULSES", start_pulses, TRUE); + print_spectrum ("START PAUSES", start_pauses, FALSE); + print_spectrum ("PULSES", pulses, TRUE); + print_spectrum ("PAUSES", pauses, FALSE); + puts ("-----------------------------------------------------------------------------"); + } + return 0; +} + +#endif // ANALYZE |