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