RemoteIR.
Dependents: RemoteIR_TestProgram SerialGPS_TestProgram StarBoardOrangeExpansion1 Door_Slamming_Device ... more
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.d1 = timer.read_us(); 00232 } 00233 break; 00234 case Received: 00235 break; 00236 default: 00237 break; 00238 } 00239 UNLOCK(); 00240 } 00241 00242 void ReceiverIR::isr_rise(void) { 00243 LOCK(); 00244 switch (work.state) { 00245 case Idle: 00246 if (0 <= work.c1) { 00247 work.c2 = timer.read_us(); 00248 int a = work.c2 - work.c1; 00249 if (InRange(a, RemoteIR::TUS_SONY * 4)) { 00250 data.format = RemoteIR::SONY; 00251 work.state = Receiving; 00252 data.bitcount = 0; 00253 } else { 00254 static const int MINIMUM_LEADER_WIDTH = 150; 00255 if (a < MINIMUM_LEADER_WIDTH) { 00256 init_state(); 00257 } 00258 } 00259 } else { 00260 init_state(); 00261 } 00262 break; 00263 case Receiving: 00264 if (RemoteIR::NEC == data.format) { 00265 work.d1 = timer.read_us(); 00266 } else if (RemoteIR::AEHA == data.format) { 00267 work.d1 = timer.read_us(); 00268 } else if (RemoteIR::SONY == data.format) { 00269 work.d2 = timer.read_us(); 00270 int a = work.d2 - work.d1; 00271 if (InRange(a, RemoteIR::TUS_SONY * 2)) { 00272 data.buffer[data.bitcount / 8] |= (1 << (data.bitcount % 8)); 00273 } else if (InRange(a, RemoteIR::TUS_SONY * 1)) { 00274 data.buffer[data.bitcount / 8] &= ~(1 << (data.bitcount % 8)); 00275 } 00276 data.bitcount++; 00277 #if 0 00278 /* 00279 * How do I know the correct length? (6bits, 12bits, 15bits, 20bits...) 00280 * By a model only? 00281 * Please check a specification of your remote controller if you find a problem. 00282 */ 00283 if (12 <= data.bitcount) { 00284 data.state = Received; 00285 work.c1 = -1; 00286 work.c2 = -1; 00287 work.c3 = -1; 00288 work.d1 = -1; 00289 work.d2 = -1; 00290 } 00291 #else 00292 /* 00293 * Set timeout for tail detection automatically. 00294 */ 00295 timeout.detach(); 00296 timeout.attach_us(this, &ReceiverIR::isr_timeout, RemoteIR::TUS_SONY * 4); 00297 #endif 00298 } 00299 break; 00300 case Received: 00301 break; 00302 default: 00303 break; 00304 } 00305 UNLOCK(); 00306 } 00307 00308 void ReceiverIR::isr_timeout(void) { 00309 LOCK(); 00310 #if 0 00311 printf("# TIMEOUT [c1=%d, c2=%d, c3=%d, d1=%d, d2=%d, state=%d, format=%d, bitcount=%d]\n", 00312 work.c1, 00313 work.c2, 00314 work.c3, 00315 work.d1, 00316 work.d2, 00317 work.state, 00318 data.format, 00319 data.bitcount); 00320 #endif 00321 if (work.state == Receiving) { 00322 work.state = Received; 00323 work.c1 = -1; 00324 work.c2 = -1; 00325 work.c3 = -1; 00326 work.d1 = -1; 00327 work.d2 = -1; 00328 } 00329 UNLOCK(); 00330 }
Generated on Tue Jul 12 2022 12:35:51 by 1.7.2