IRremote
IRProtocol.hpp
Go to the documentation of this file.
1 /*
2  * IRReceive.hpp
3  * This file is exclusively included by IRremote.h to enable easy configuration of library switches
4  *
5  * Contains all protocol functions used by receiver and sender.
6  *
7  * This file is part of Arduino-IRremote https://github.com/Arduino-IRremote/Arduino-IRremote.
8  *
9  ************************************************************************************
10  * MIT License
11  *
12  * Copyright (c) 2009-2026 Ken Shirriff, Rafi Khan, Armin Joachimsmeyer
13  *
14  * Permission is hereby granted, free of charge, to any person obtaining a copy
15  * of this software and associated documentation files (the "Software"), to deal
16  * in the Software without restriction, including without limitation the rights
17  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
18  * copies of the Software, and to permit persons to whom the Software is furnished
19  * to do so, subject to the following conditions:
20  *
21  * The above copyright notice and this permission notice shall be included in all
22  * copies or substantial portions of the Software.
23  *
24  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
25  * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
26  * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
27  * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
28  * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
29  * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
30  *
31  ************************************************************************************
32  */
33 #ifndef _IR_PROTOCOL_HPP
34 #define _IR_PROTOCOL_HPP
35 
40 const char string_Unknown[] PROGMEM = "UNKNOWN";
41 const char string_PulseWidth[] PROGMEM = "PulseWidth";
42 const char string_PulseDistance[] PROGMEM = "PulseDistance";
43 const char string_Apple[] PROGMEM = "Apple";
44 const char string_Denon[] PROGMEM = "Denon";
45 const char string_JVC[] PROGMEM = "JVC";
46 const char string_LG[] PROGMEM = "LG";
47 const char string_LG2[] PROGMEM = "LG2";
48 const char string_NEC[] PROGMEM = "NEC";
49 const char string_NEC2[] PROGMEM = "NEC2";
50 const char string_Onkyo[] PROGMEM = "Onkyo";
51 const char string_Panasonic[] PROGMEM = "Panasonic";
52 const char string_Kaseikyo[] PROGMEM = "Kaseikyo";
53 const char string_Kaseikyo_Denon[] PROGMEM = "Kaseikyo_Denon";
54 const char string_Kaseikyo_Sharp[] PROGMEM = "Kaseikyo_Sharp";
55 const char string_Kaseikyo_JVC[] PROGMEM = "Kaseikyo_JVC";
56 const char string_Kaseikyo_Mitsubishi[] PROGMEM = "Kaseikyo_Mitsubishi";
57 const char string_RC5[] PROGMEM = "RC5";
58 const char string_RC6[] PROGMEM = "RC6";
59 const char string_RC6A[] PROGMEM = "RC6A";
60 const char string_Samsung[] PROGMEM = "Samsung";
61 const char string_SamsungLG[] PROGMEM = "SamsungLG";
62 const char string_Samsung48[] PROGMEM = "Samsung48";
63 const char string_Sharp[] PROGMEM = "Sharp";
64 const char string_Sony[] PROGMEM = "Sony";
65 const char string_BangOlufsen[] PROGMEM = "Bang&Olufsen";
66 const char string_BoseWave[] PROGMEM = "BoseWave";
67 const char string_Lego[] PROGMEM = "Lego";
68 const char string_MagiQuest[] PROGMEM = "MagiQuest";
69 const char string_Whynter[] PROGMEM = "Whynter";
70 const char string_Marantz[] PROGMEM = "Marantz";
71 const char string_FAST[] PROGMEM = "FAST";
72 const char string_OpenLASIR[] PROGMEM = "OpenLASIR";
73 const char string_Other[] PROGMEM = "OTHER";
74 
75 /*
76  * !!Must be the same order as in decode_type_t in IRProtocol.h!!!
77  */
78 const char *const ProtocolNames[]
79 PROGMEM = { string_Unknown, string_PulseWidth, string_PulseDistance, string_Apple, string_Denon, string_JVC, string_LG, string_LG2,
80  string_NEC, string_NEC2, string_Onkyo, string_Panasonic, string_Kaseikyo, string_Kaseikyo_Denon, string_Kaseikyo_Sharp,
81  string_Kaseikyo_JVC, string_Kaseikyo_Mitsubishi, string_RC5, string_RC6, string_RC6A, string_Samsung, string_SamsungLG,
82  string_Samsung48, string_Sharp, string_Sony
83 #if !defined(EXCLUDE_EXOTIC_PROTOCOLS)
84  , string_BangOlufsen, string_BoseWave, string_Lego, string_MagiQuest, string_Whynter, string_Marantz, string_FAST,
85  string_OpenLASIR, string_Other
86 #endif
87  };
88 
89 #if defined(__AVR__)
90 const __FlashStringHelper* getProtocolString(decode_type_t aProtocol) {
91  const char *tProtocolStringPtr = (char*) pgm_read_word(&ProtocolNames[aProtocol]);
92  return ((__FlashStringHelper*) (tProtocolStringPtr));
93 }
94 #else
95 const char* getProtocolString(decode_type_t aProtocol) {
96  return ProtocolNames[aProtocol];
97 }
98 #endif
99 
100 #if (__INT_WIDTH__ >= 32)
101 # if __has_include(<type_traits>)
102 /*
103  * This code to handle the missing print(unsigned long long...) function of seeduino core was contributed by sklott
104  * https://stackoverflow.com/questions/74622227/avoid-calling-of-function-size-t-printprintunsigned-long-long-n-int-base-if
105  */
106 #include <type_traits>
107 
108 // If you have C++17 you can just use std::void_t, or use this for all versions
109 #if __cpp_lib_void_t >= 201411L
110 template<typename T>
111 using void_t = std::void_t<T>;
112 #else
113 template<typename ... Ts> struct make_void {
114  typedef void type;
115 };
116 template<typename ... Ts> using void_t = typename make_void<Ts...>::type;
117 #endif
118 
119 // Detecting if we have print(unsigned long long value, int base) / print(0ull, 0) overload
120 template<typename T, typename = void>
121 struct has_ull_print: std::false_type {
122 };
123 template<typename T>
124 struct has_ull_print<T, void_t<decltype(std::declval<T>().print(0ull, 0))>> : std::true_type {
125 };
126 
127 // Must be namespace, to avoid public and static declarations for class
128 namespace PrintULL {
129 template<typename PrintImplType, typename std::enable_if<!has_ull_print<PrintImplType>::value, bool>::type = true>
130 size_t print(PrintImplType *p, unsigned long long value, int base) {
131  size_t tLength = p->print(static_cast<uint32_t>(value >> 32), base);
132  tLength += p->print(static_cast<uint32_t>(value), base);
133  return tLength;
134 }
135 template<typename PrintImplType, typename std::enable_if<!has_ull_print<PrintImplType>::value, bool>::type = true>
136 size_t println(PrintImplType *p, unsigned long long value, int base) {
137  size_t tLength = p->print(static_cast<uint32_t>(value >> 32), base);
138  tLength += p->println(static_cast<uint32_t>(value), base);
139  return tLength;
140 }
141 
142 template<typename PrintImplType, typename std::enable_if<has_ull_print<PrintImplType>::value, bool>::type = true>
143 size_t print(PrintImplType *p, unsigned long long value, int base) {
144  return p->print(value, base);
145 }
146 template<typename PrintImplType, typename std::enable_if<has_ull_print<PrintImplType>::value, bool>::type = true>
147 size_t println(PrintImplType *p, unsigned long long value, int base) {
148  return p->println(value, base);
149 }
150 }
151 ;
152 # else
153 namespace PrintULL {
154  size_t print(Print *aSerial, unsigned long long n, int base) {
155  return aSerial->print(n, base);
156  }
157  size_t println(Print *aSerial, unsigned long long n, int base) {
158  return aSerial->println(n, base);
159  }
160 };
161 # endif
162 #endif
163 
168 /**********************************************************************************************************************
169  * Function to bit reverse OLD MSB values of e.g. NEC.
170  **********************************************************************************************************************/
171 uint8_t bitreverseOneByte(uint8_t aValue) {
172 // uint8_t tReversedValue;
173 // return __builtin_avr_insert_bits(0x01234567, aValue, tReversedValue);
174 // 76543210
175  aValue = (aValue >> 4) | (aValue << 4); // Swap in groups of 4
176 // 32107654
177  aValue = ((aValue & 0xcc) >> 2) | ((aValue & 0x33) << 2); // Swap in groups of 2
178 // 10325476
179  aValue = ((aValue & 0xaa) >> 1) | ((aValue & 0x55) << 1); // Swap bit pairs
180 // 01234567
181  return aValue;
182 }
183 
184 uint32_t bitreverse32Bit(uint32_t aInput) {
185 // __builtin_avr_insert_bits();
186  LongUnion tValue;
187  tValue.UByte.HighByte = bitreverseOneByte(aInput);
188  tValue.UByte.MidHighByte = bitreverseOneByte(aInput >> 8);
189  tValue.UByte.MidLowByte = bitreverseOneByte(aInput >> 16);
190  tValue.UByte.LowByte = bitreverseOneByte(aInput >> 24);
191  return tValue.ULong;
192 }
193 
196 #endif // _IR_PROTOCOL_HPP
LongUnion
Union to specify parts / manifestations of a 32 bit Long without casts and shifts.
Definition: LongUnion.h:59
LongUnion::UByte
struct LongUnion::@4 UByte
decode_type_t
decode_type_t
An enum consisting of all supported formats.
Definition: IRProtocol.h:97
LongUnion::LowByte
uint8_t LowByte
Definition: LongUnion.h:61
LongUnion::HighByte
uint8_t HighByte
Definition: LongUnion.h:64
LongUnion::MidLowByte
uint8_t MidLowByte
Definition: LongUnion.h:62
ProtocolNames
const char *const ProtocolNames[]
Definition: IRProtocol.hpp:79
bitreverse32Bit
uint32_t bitreverse32Bit(uint32_t aInput)
Definition: IRProtocol.hpp:184
LongUnion::ULong
uint32_t ULong
Definition: LongUnion.h:95
PROGMEM
const char string_Unknown[] PROGMEM
Definition: IRProtocol.hpp:40
LongUnion::MidHighByte
uint8_t MidHighByte
Definition: LongUnion.h:63
bitreverseOneByte
uint8_t bitreverseOneByte(uint8_t aValue)
Definition: IRProtocol.hpp:171
getProtocolString
const char * getProtocolString(decode_type_t aProtocol)
Definition: IRProtocol.hpp:95