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.
Fork of RemoteIR by
ReceiverIR.cpp
00001 /** 00002 * IR receiver (Version 0.0.4) 00003 * 00004 * Copyright (C) 2010 Shinichiro Nakamura (CuBeatSystems) 00005 * http://shinta.main.jp/ 00006 */ 00007 00008 #include "ReceiverIR.h" 00009 00010 #define LOCK() 00011 #define UNLOCK() 00012 00013 #define InRange(x,y) ((((y) * 0.7) < (x)) && ((x) < ((y) * 1.3))) 00014 00015 /** 00016 * Constructor. 00017 * 00018 * @param rxpin Pin for receive IR signal. 00019 */ 00020 ReceiverIR::ReceiverIR(PinName rxpin) : evt(rxpin) { 00021 init_state(); 00022 evt.fall(this, &ReceiverIR::isr_fall); 00023 evt.rise(this, &ReceiverIR::isr_rise); 00024 evt.mode(PullUp); 00025 ticker.attach_us(this, &ReceiverIR::isr_wdt, 10 * 1000); 00026 } 00027 00028 /** 00029 * Destructor. 00030 */ 00031 ReceiverIR::~ReceiverIR() { 00032 } 00033 00034 /** 00035 * Get state. 00036 * 00037 * @return Current state. 00038 */ 00039 ReceiverIR::State ReceiverIR::getState() { 00040 LOCK(); 00041 State s = work.state; 00042 UNLOCK(); 00043 return s; 00044 } 00045 00046 /** 00047 * Get data. 00048 * 00049 * @param format Pointer to format. 00050 * @param buf Buffer of a data. 00051 * @param bitlength Bit length of the buffer. 00052 * 00053 * @return Data bit length. 00054 */ 00055 int ReceiverIR::getData(RemoteIR::Format *format, uint8_t *buf, int bitlength) { 00056 LOCK(); 00057 00058 if (bitlength < data.bitcount) { 00059 UNLOCK(); 00060 return -1; 00061 } 00062 00063 const int nbits = data.bitcount; 00064 const int nbytes = data.bitcount / 8 + (((data.bitcount % 8) != 0) ? 1 : 0); 00065 *format = data.format; 00066 for (int i = 0; i < nbytes; i++) { 00067 buf[i] = data.buffer[i]; 00068 } 00069 00070 init_state(); 00071 00072 UNLOCK(); 00073 return nbits; 00074 } 00075 00076 void ReceiverIR::init_state(void) { 00077 work.c1 = -1; 00078 work.c2 = -1; 00079 work.c3 = -1; 00080 work.d1 = -1; 00081 work.d2 = -1; 00082 work.state = Idle; 00083 data.format = RemoteIR::UNKNOWN; 00084 data.bitcount = 0; 00085 timer.stop(); 00086 timer.reset(); 00087 for (int i = 0; i < sizeof(data.buffer); i++) { 00088 data.buffer[i] = 0; 00089 } 00090 } 00091 00092 void ReceiverIR::isr_wdt(void) { 00093 LOCK(); 00094 static int cnt = 0; 00095 if ((Idle != work.state) || ((0 <= work.c1) || (0 <= work.c2) || (0 <= work.c3) || (0 <= work.d1) || (0 <= work.d2))) { 00096 cnt++; 00097 if (cnt > 50) { 00098 #if 0 00099 printf("# WDT [c1=%d, c2=%d, c3=%d, d1=%d, d2=%d, state=%d, format=%d, bitcount=%d]\n", 00100 work.c1, 00101 work.c2, 00102 work.c3, 00103 work.d1, 00104 work.d2, 00105 work.state, 00106 data.format, 00107 data.bitcount); 00108 #endif 00109 init_state(); 00110 cnt = 0; 00111 } 00112 } else { 00113 cnt = 0; 00114 } 00115 UNLOCK(); 00116 } 00117 00118 void ReceiverIR::isr_fall(void) { 00119 LOCK(); 00120 switch (work.state) { 00121 case Idle: 00122 if (work.c1 < 0) { 00123 timer.start(); 00124 work.c1 = timer.read_us(); 00125 } else { 00126 work.c3 = timer.read_us(); 00127 int a = work.c2 - work.c1; 00128 int b = work.c3 - work.c2; 00129 if (InRange(a, RemoteIR::TUS_NEC * 16) && InRange(b, RemoteIR::TUS_NEC * 8)) { 00130 /* 00131 * NEC. 00132 */ 00133 data.format = RemoteIR::NEC; 00134 work.state = Receiving; 00135 data.bitcount = 0; 00136 } else if (InRange(a, RemoteIR::TUS_NEC * 16) && InRange(b, RemoteIR::TUS_NEC * 4)) { 00137 /* 00138 * NEC Repeat. 00139 */ 00140 data.format = RemoteIR::NEC_REPEAT; 00141 work.state = Received; 00142 data.bitcount = 0; 00143 work.c1 = -1; 00144 work.c2 = -1; 00145 work.c3 = -1; 00146 work.d1 = -1; 00147 work.d2 = -1; 00148 } else if (InRange(a, RemoteIR::TUS_AEHA * 8) && InRange(b, RemoteIR::TUS_AEHA * 4)) { 00149 /* 00150 * AEHA. 00151 */ 00152 data.format = RemoteIR::AEHA; 00153 work.state = Receiving; 00154 data.bitcount = 0; 00155 } else if (InRange(a, RemoteIR::TUS_AEHA * 8) && InRange(b, RemoteIR::TUS_AEHA * 8)) { 00156 /* 00157 * AEHA Repeat. 00158 */ 00159 data.format = RemoteIR::AEHA_REPEAT; 00160 work.state = Received; 00161 data.bitcount = 0; 00162 work.c1 = -1; 00163 work.c2 = -1; 00164 work.c3 = -1; 00165 work.d1 = -1; 00166 work.d2 = -1; 00167 } else { 00168 init_state(); 00169 } 00170 } 00171 break; 00172 case Receiving: 00173 if (RemoteIR::NEC == data.format) { 00174 work.d2 = timer.read_us(); 00175 int a = work.d2 - work.d1; 00176 if (InRange(a, RemoteIR::TUS_NEC * 3)) { 00177 data.buffer[data.bitcount / 8] |= (1 << (data.bitcount % 8)); 00178 } else if (InRange(a, RemoteIR::TUS_NEC * 1)) { 00179 data.buffer[data.bitcount / 8] &= ~(1 << (data.bitcount % 8)); 00180 } 00181 data.bitcount++; 00182 #if 0 00183 /* 00184 * Length of NEC is always 32 bits. 00185 */ 00186 if (32 <= data.bitcount) { 00187 data.state = Received; 00188 work.c1 = -1; 00189 work.c2 = -1; 00190 work.c3 = -1; 00191 work.d1 = -1; 00192 work.d2 = -1; 00193 } 00194 #else 00195 /* 00196 * Set timeout for tail detection automatically. 00197 */ 00198 timeout.detach(); 00199 timeout.attach_us(this, &ReceiverIR::isr_timeout, RemoteIR::TUS_NEC * 5); 00200 #endif 00201 } else if (RemoteIR::AEHA == data.format) { 00202 work.d2 = timer.read_us(); 00203 int a = work.d2 - work.d1; 00204 if (InRange(a, RemoteIR::TUS_AEHA * 3)) { 00205 data.buffer[data.bitcount / 8] |= (1 << (data.bitcount % 8)); 00206 } else if (InRange(a, RemoteIR::TUS_AEHA * 1)) { 00207 data.buffer[data.bitcount / 8] &= ~(1 << (data.bitcount % 8)); 00208 } 00209 data.bitcount++; 00210 #if 0 00211 /* 00212 * Typical length of AEHA is 48 bits. 00213 * Please check a specification of your remote controller if you find a problem. 00214 */ 00215 if (48 <= data.bitcount) { 00216 data.state = Received; 00217 work.c1 = -1; 00218 work.c2 = -1; 00219 work.c3 = -1; 00220 work.d1 = -1; 00221 work.d2 = -1; 00222 } 00223 #else 00224 /* 00225 * Set timeout for tail detection automatically. 00226 */ 00227 timeout.detach(); 00228 timeout.attach_us(this, &ReceiverIR::isr_timeout, RemoteIR::TUS_AEHA * 5); 00229 #endif 00230 } else if (RemoteIR::SONY == data.format) { 00231 work.d2 = timer.read_us(); 00232 int a = work.d2 - work.d1; 00233 if (InRange(a, RemoteIR::TUS_SONY * 2)) { 00234 data.buffer[data.bitcount / 8] |= (1 << (data.bitcount % 8)); 00235 } else if (InRange(a, RemoteIR::TUS_SONY * 1)) { 00236 data.buffer[data.bitcount / 8] &= ~(1 << (data.bitcount % 8)); 00237 } 00238 data.bitcount++; 00239 #if 0 00240 /* 00241 * How do I know the correct length? (6bits, 12bits, 15bits, 20bits...) 00242 * By a model only? 00243 * Please check a specification of your remote controller if you find a problem. 00244 */ 00245 if (12 <= data.bitcount) { 00246 data.state = Received; 00247 work.c1 = -1; 00248 work.c2 = -1; 00249 work.c3 = -1; 00250 work.d1 = -1; 00251 work.d2 = -1; 00252 } 00253 #else 00254 /* 00255 * Set timeout for tail detection automatically. 00256 */ 00257 timeout.detach(); 00258 timeout.attach_us(this, &ReceiverIR::isr_timeout, RemoteIR::TUS_SONY * 4); 00259 #endif 00260 } 00261 break; 00262 case Received: 00263 break; 00264 default: 00265 break; 00266 } 00267 UNLOCK(); 00268 } 00269 00270 void ReceiverIR::isr_rise(void) { 00271 LOCK(); 00272 switch (work.state) { 00273 case Idle: 00274 if (0 <= work.c1) { 00275 work.c2 = timer.read_us(); 00276 int a = work.c2 - work.c1; 00277 if (InRange(a, RemoteIR::TUS_SONY * 4)) { 00278 data.format = RemoteIR::SONY; 00279 work.state = Receiving; 00280 data.bitcount = 0; 00281 work.d1 = timer.read_us(); 00282 } else { 00283 static const int MINIMUM_LEADER_WIDTH = 150; 00284 if (a < MINIMUM_LEADER_WIDTH) { 00285 init_state(); 00286 } 00287 } 00288 } else { 00289 init_state(); 00290 } 00291 break; 00292 case Receiving: 00293 if (RemoteIR::NEC == data.format) { 00294 work.d1 = timer.read_us(); 00295 } else if (RemoteIR::AEHA == data.format) { 00296 work.d1 = timer.read_us(); 00297 } else if (RemoteIR::SONY == data.format) { 00298 work.d1 = timer.read_us(); 00299 } 00300 break; 00301 case Received: 00302 break; 00303 default: 00304 break; 00305 } 00306 UNLOCK(); 00307 } 00308 00309 void ReceiverIR::isr_timeout(void) { 00310 LOCK(); 00311 #if 0 00312 printf("# TIMEOUT [c1=%d, c2=%d, c3=%d, d1=%d, d2=%d, state=%d, format=%d, bitcount=%d]\n", 00313 work.c1, 00314 work.c2, 00315 work.c3, 00316 work.d1, 00317 work.d2, 00318 work.state, 00319 data.format, 00320 data.bitcount); 00321 #endif 00322 if (work.state == Receiving) { 00323 work.state = Received; 00324 work.c1 = -1; 00325 work.c2 = -1; 00326 work.c3 = -1; 00327 work.d1 = -1; 00328 work.d2 = -1; 00329 00330 if (RemoteIR::SONY == data.format) { 00331 // Fix for SONY empty bits, for example if 31 bits was sended, we need to fill 32nd bit with "1". 00332 // We need to append unreceived bits with "1"s. 00333 int bitsCount = data.bitcount % 8; 00334 if (bitsCount != 0) { 00335 int bytesCount = data.bitcount / 8; 00336 for (int i = bitsCount; i < 8; i++) { 00337 data.buffer[bytesCount] |= (1 << i); 00338 } 00339 } 00340 } 00341 } 00342 UNLOCK(); 00343 }
Generated on Tue Jul 19 2022 02:44:09 by
1.7.2
