Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependents: Lilnija_29012017 NucleoF042K6_IRReceiver
ir_RC5_RC6.cpp
00001 #include "IRremote.h" 00002 #include "IRremoteInt.h" 00003 00004 //+============================================================================= 00005 // Gets one undecoded level at a time from the raw buffer. 00006 // The RC5/6 decoding is easier if the data is broken into time intervals. 00007 // E.g. if the buffer has MARK for 2 time intervals and SPACE for 1, 00008 // successive calls to getRClevel will return MARK, MARK, SPACE. 00009 // offset and used are updated to keep track of the current position. 00010 // t1 is the time interval for a single bit in microseconds. 00011 // Returns -1 for error (measured time interval is not a multiple of t1). 00012 // 00013 #if (DECODE_RC5 || DECODE_RC6) 00014 int IRrecv::getRClevel (decode_results *results, int *offset, int *used, int t1) 00015 { 00016 int width; 00017 int val; 00018 int correction; 00019 int avail; 00020 00021 if (*offset >= results->rawlen) return SPACE ; // After end of recorded buffer, assume SPACE. 00022 width = results->rawbuf[*offset]; 00023 val = ((*offset) % 2) ? MARK : SPACE; 00024 correction = (val == MARK) ? MARK_EXCESS : - MARK_EXCESS; 00025 00026 if (MATCH(width, ( t1) + correction)) avail = 1 ; 00027 else if (MATCH(width, (2*t1) + correction)) avail = 2 ; 00028 else if (MATCH(width, (3*t1) + correction)) avail = 3 ; 00029 else return -1 ; 00030 00031 (*used)++; 00032 if (*used >= avail) { 00033 *used = 0; 00034 (*offset)++; 00035 } 00036 00037 DBG_PRINTLN( (val == MARK) ? "MARK" : "SPACE" ); 00038 00039 return val; 00040 } 00041 #endif 00042 00043 //============================================================================== 00044 // RRRR CCCC 55555 00045 // R R C 5 00046 // RRRR C 5555 00047 // R R C 5 00048 // R R CCCC 5555 00049 // 00050 // NB: First bit must be a one (start bit) 00051 // 00052 #define MIN_RC5_SAMPLES 11 00053 #define RC5_T1 889 00054 #define RC5_RPT_LENGTH 46000 00055 00056 //+============================================================================= 00057 #if SEND_RC5 00058 void IRsend::sendRC5 (unsigned long data, int nbits) 00059 { 00060 // Set IR carrier frequency 00061 enableIROut(36); 00062 00063 // Start 00064 mark(RC5_T1); 00065 space(RC5_T1); 00066 mark(RC5_T1); 00067 00068 // Data 00069 for (unsigned long mask = 1UL << (nbits - 1); mask; mask >>= 1) { 00070 if (data & mask) { 00071 space(RC5_T1); // 1 is space, then mark 00072 mark(RC5_T1); 00073 } else { 00074 mark(RC5_T1); 00075 space(RC5_T1); 00076 } 00077 } 00078 00079 space(0); // Always end with the LED off 00080 } 00081 #endif 00082 00083 //+============================================================================= 00084 #if DECODE_RC5 00085 bool IRrecv::decodeRC5 (decode_results *results) 00086 { 00087 int nbits; 00088 long data = 0; 00089 int used = 0; 00090 int offset = 1; // Skip gap space 00091 00092 if (irparams.rawlen < MIN_RC5_SAMPLES + 2) return false ; 00093 00094 // Get start bits 00095 if (getRClevel(results, &offset, &used, RC5_T1) != MARK) return false ; 00096 if (getRClevel(results, &offset, &used, RC5_T1) != SPACE) return false ; 00097 if (getRClevel(results, &offset, &used, RC5_T1) != MARK) return false ; 00098 00099 for (nbits = 0; offset < irparams.rawlen; nbits++) { 00100 int levelA = getRClevel(results, &offset, &used, RC5_T1); 00101 int levelB = getRClevel(results, &offset, &used, RC5_T1); 00102 00103 if ((levelA == SPACE) && (levelB == MARK )) data = (data << 1) | 1 ; 00104 else if ((levelA == MARK ) && (levelB == SPACE)) data = (data << 1) | 0 ; 00105 else return false ; 00106 } 00107 00108 // Success 00109 results->bits = nbits; 00110 results->value = data; 00111 results->decode_type = RC5; 00112 return true; 00113 } 00114 #endif 00115 00116 //+============================================================================= 00117 // RRRR CCCC 6666 00118 // R R C 6 00119 // RRRR C 6666 00120 // R R C 6 6 00121 // R R CCCC 666 00122 // 00123 // NB : Caller needs to take care of flipping the toggle bit 00124 // 00125 #define MIN_RC6_SAMPLES 1 00126 #define RC6_HDR_MARK 2666 00127 #define RC6_HDR_SPACE 889 00128 #define RC6_T1 444 00129 #define RC6_RPT_LENGTH 46000 00130 00131 #if SEND_RC6 00132 void IRsend::sendRC6 (unsigned long data, int nbits) 00133 { 00134 // Set IR carrier frequency 00135 enableIROut(36); 00136 00137 // Header 00138 mark(RC6_HDR_MARK); 00139 space(RC6_HDR_SPACE); 00140 00141 // Start bit 00142 mark(RC6_T1); 00143 space(RC6_T1); 00144 00145 // Data 00146 for (unsigned long i = 1, mask = 1UL << (nbits - 1); mask; i++, mask >>= 1) { 00147 // The fourth bit we send is a "double width trailer bit" 00148 int t = (i == 4) ? (RC6_T1 * 2) : (RC6_T1) ; 00149 if (data & mask) { 00150 mark(t); 00151 space(t); 00152 } else { 00153 space(t); 00154 mark(t); 00155 } 00156 } 00157 00158 space(0); // Always end with the LED off 00159 } 00160 #endif 00161 00162 //+============================================================================= 00163 #if DECODE_RC6 00164 bool IRrecv::decodeRC6 (decode_results *results) 00165 { 00166 int nbits; 00167 long data = 0; 00168 int used = 0; 00169 int offset = 1; // Skip first space 00170 00171 if (results->rawlen < MIN_RC6_SAMPLES) return false ; 00172 00173 // Initial mark 00174 if (!MATCH_MARK(results->rawbuf[offset++], RC6_HDR_MARK)) return false ; 00175 if (!MATCH_SPACE(results->rawbuf[offset++], RC6_HDR_SPACE)) return false ; 00176 00177 // Get start bit (1) 00178 if (getRClevel(results, &offset, &used, RC6_T1) != MARK) return false ; 00179 if (getRClevel(results, &offset, &used, RC6_T1) != SPACE) return false ; 00180 00181 for (nbits = 0; offset < results->rawlen; nbits++) { 00182 int levelA, levelB; // Next two levels 00183 00184 levelA = getRClevel(results, &offset, &used, RC6_T1); 00185 if (nbits == 3) { 00186 // T bit is double wide; make sure second half matches 00187 if (levelA != getRClevel(results, &offset, &used, RC6_T1)) return false; 00188 } 00189 00190 levelB = getRClevel(results, &offset, &used, RC6_T1); 00191 if (nbits == 3) { 00192 // T bit is double wide; make sure second half matches 00193 if (levelB != getRClevel(results, &offset, &used, RC6_T1)) return false; 00194 } 00195 00196 if ((levelA == MARK ) && (levelB == SPACE)) data = (data << 1) | 1 ; // inverted compared to RC5 00197 else if ((levelA == SPACE) && (levelB == MARK )) data = (data << 1) | 0 ; // ... 00198 else return false ; // Error 00199 } 00200 00201 // Success 00202 results->bits = nbits; 00203 results->value = data; 00204 results->decode_type = RC6; 00205 return true; 00206 } 00207 #endif
Generated on Tue Jul 12 2022 18:56:50 by
