RemotoIR Libraryに、IRC Helicopter Propo の受信処理と、受信パルス幅測定処理を追加したものです。
Dependents: SwiftPropoIR_TestProgram irRawDataDisplay spinner2 LPC1114_ir-spinne_main-propo
Fork of RemoteIR by
ReceiverIR.cpp@13:ec76e93a4d7c, 2013-08-03 (annotated)
- Committer:
- suupen
- Date:
- Sat Aug 03 01:44:43 2013 +0000
- Revision:
- 13:ec76e93a4d7c
- Parent:
- 12:2379e13b8b34
????????????????????????????????(100ms??)???????????????????????????????
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
shintamainjp | 0:ec264f4ce158 | 1 | /** |
shintamainjp | 9:dcfdac59ef74 | 2 | * IR receiver (Version 0.0.4) |
shintamainjp | 0:ec264f4ce158 | 3 | * |
shintamainjp | 0:ec264f4ce158 | 4 | * Copyright (C) 2010 Shinichiro Nakamura (CuBeatSystems) |
shintamainjp | 0:ec264f4ce158 | 5 | * http://shinta.main.jp/ |
suupen | 12:2379e13b8b34 | 6 | * |
suupen | 12:2379e13b8b34 | 7 | * ------------------------------------------------------- |
suupen | 12:2379e13b8b34 | 8 | * 130616 suupen |
suupen | 12:2379e13b8b34 | 9 | * IRC Helicopter "SWIFT" Propo support |
suupen | 13:ec76e93a4d7c | 10 | * Conditional compilation |
suupen | 12:2379e13b8b34 | 11 | * "SWIFT_PROTCOL" |
suupen | 12:2379e13b8b34 | 12 | * "IR_RAW_DATA_ANALYSIS" |
suupen | 12:2379e13b8b34 | 13 | *-------------------------------------------------------- |
shintamainjp | 0:ec264f4ce158 | 14 | */ |
shintamainjp | 0:ec264f4ce158 | 15 | |
shintamainjp | 0:ec264f4ce158 | 16 | #include "ReceiverIR.h" |
shintamainjp | 0:ec264f4ce158 | 17 | |
shintamainjp | 10:c54fb1204d1e | 18 | #define LOCK() |
shintamainjp | 10:c54fb1204d1e | 19 | #define UNLOCK() |
shintamainjp | 0:ec264f4ce158 | 20 | |
shintamainjp | 0:ec264f4ce158 | 21 | #define InRange(x,y) ((((y) * 0.7) < (x)) && ((x) < ((y) * 1.3))) |
shintamainjp | 0:ec264f4ce158 | 22 | |
shintamainjp | 9:dcfdac59ef74 | 23 | /** |
shintamainjp | 9:dcfdac59ef74 | 24 | * Constructor. |
shintamainjp | 9:dcfdac59ef74 | 25 | * |
shintamainjp | 9:dcfdac59ef74 | 26 | * @param rxpin Pin for receive IR signal. |
shintamainjp | 9:dcfdac59ef74 | 27 | */ |
suupen | 13:ec76e93a4d7c | 28 | ReceiverIR::ReceiverIR(PinName rxpin) : evt(rxpin) |
suupen | 13:ec76e93a4d7c | 29 | { |
shintamainjp | 9:dcfdac59ef74 | 30 | init_state(); |
shintamainjp | 0:ec264f4ce158 | 31 | evt.fall(this, &ReceiverIR::isr_fall); |
shintamainjp | 0:ec264f4ce158 | 32 | evt.rise(this, &ReceiverIR::isr_rise); |
shintamainjp | 0:ec264f4ce158 | 33 | evt.mode(PullUp); |
shintamainjp | 0:ec264f4ce158 | 34 | ticker.attach_us(this, &ReceiverIR::isr_wdt, 10 * 1000); |
shintamainjp | 0:ec264f4ce158 | 35 | } |
shintamainjp | 0:ec264f4ce158 | 36 | |
shintamainjp | 9:dcfdac59ef74 | 37 | /** |
shintamainjp | 9:dcfdac59ef74 | 38 | * Destructor. |
shintamainjp | 9:dcfdac59ef74 | 39 | */ |
suupen | 13:ec76e93a4d7c | 40 | ReceiverIR::~ReceiverIR() |
suupen | 13:ec76e93a4d7c | 41 | { |
shintamainjp | 1:4adf16017a0f | 42 | } |
shintamainjp | 1:4adf16017a0f | 43 | |
shintamainjp | 9:dcfdac59ef74 | 44 | /** |
shintamainjp | 9:dcfdac59ef74 | 45 | * Get state. |
shintamainjp | 9:dcfdac59ef74 | 46 | * |
shintamainjp | 9:dcfdac59ef74 | 47 | * @return Current state. |
shintamainjp | 9:dcfdac59ef74 | 48 | */ |
suupen | 13:ec76e93a4d7c | 49 | ReceiverIR::State ReceiverIR::getState() |
suupen | 13:ec76e93a4d7c | 50 | { |
shintamainjp | 9:dcfdac59ef74 | 51 | LOCK(); |
shintamainjp | 9:dcfdac59ef74 | 52 | State s = work.state; |
shintamainjp | 9:dcfdac59ef74 | 53 | UNLOCK(); |
shintamainjp | 0:ec264f4ce158 | 54 | return s; |
shintamainjp | 0:ec264f4ce158 | 55 | } |
shintamainjp | 0:ec264f4ce158 | 56 | |
shintamainjp | 9:dcfdac59ef74 | 57 | /** |
shintamainjp | 9:dcfdac59ef74 | 58 | * Get data. |
shintamainjp | 9:dcfdac59ef74 | 59 | * |
shintamainjp | 9:dcfdac59ef74 | 60 | * @param format Pointer to format. |
shintamainjp | 9:dcfdac59ef74 | 61 | * @param buf Buffer of a data. |
shintamainjp | 9:dcfdac59ef74 | 62 | * @param bitlength Bit length of the buffer. |
shintamainjp | 9:dcfdac59ef74 | 63 | * |
shintamainjp | 9:dcfdac59ef74 | 64 | * @return Data bit length. |
shintamainjp | 9:dcfdac59ef74 | 65 | */ |
suupen | 13:ec76e93a4d7c | 66 | int ReceiverIR::getData(RemoteIR::Format *format, uint8_t *buf, int bitlength) |
suupen | 13:ec76e93a4d7c | 67 | { |
shintamainjp | 9:dcfdac59ef74 | 68 | LOCK(); |
shintamainjp | 0:ec264f4ce158 | 69 | |
shintamainjp | 4:2304646f6ff5 | 70 | if (bitlength < data.bitcount) { |
shintamainjp | 9:dcfdac59ef74 | 71 | UNLOCK(); |
shintamainjp | 0:ec264f4ce158 | 72 | return -1; |
shintamainjp | 0:ec264f4ce158 | 73 | } |
shintamainjp | 0:ec264f4ce158 | 74 | |
shintamainjp | 9:dcfdac59ef74 | 75 | const int nbits = data.bitcount; |
shintamainjp | 6:e57504fc802e | 76 | const int nbytes = data.bitcount / 8 + (((data.bitcount % 8) != 0) ? 1 : 0); |
shintamainjp | 0:ec264f4ce158 | 77 | *format = data.format; |
shintamainjp | 5:e158c85c55ff | 78 | for (int i = 0; i < nbytes; i++) { |
shintamainjp | 0:ec264f4ce158 | 79 | buf[i] = data.buffer[i]; |
shintamainjp | 0:ec264f4ce158 | 80 | } |
shintamainjp | 0:ec264f4ce158 | 81 | |
shintamainjp | 0:ec264f4ce158 | 82 | init_state(); |
shintamainjp | 0:ec264f4ce158 | 83 | |
shintamainjp | 9:dcfdac59ef74 | 84 | UNLOCK(); |
shintamainjp | 9:dcfdac59ef74 | 85 | return nbits; |
shintamainjp | 0:ec264f4ce158 | 86 | } |
shintamainjp | 0:ec264f4ce158 | 87 | |
suupen | 13:ec76e93a4d7c | 88 | void ReceiverIR::init_state(void) |
suupen | 13:ec76e93a4d7c | 89 | { |
shintamainjp | 0:ec264f4ce158 | 90 | work.c1 = -1; |
shintamainjp | 0:ec264f4ce158 | 91 | work.c2 = -1; |
shintamainjp | 0:ec264f4ce158 | 92 | work.c3 = -1; |
shintamainjp | 0:ec264f4ce158 | 93 | work.d1 = -1; |
shintamainjp | 0:ec264f4ce158 | 94 | work.d2 = -1; |
shintamainjp | 9:dcfdac59ef74 | 95 | work.state = Idle; |
shintamainjp | 0:ec264f4ce158 | 96 | data.format = RemoteIR::UNKNOWN; |
shintamainjp | 0:ec264f4ce158 | 97 | data.bitcount = 0; |
shintamainjp | 0:ec264f4ce158 | 98 | timer.stop(); |
shintamainjp | 0:ec264f4ce158 | 99 | timer.reset(); |
shintamainjp | 0:ec264f4ce158 | 100 | for (int i = 0; i < sizeof(data.buffer); i++) { |
shintamainjp | 0:ec264f4ce158 | 101 | data.buffer[i] = 0; |
shintamainjp | 0:ec264f4ce158 | 102 | } |
shintamainjp | 0:ec264f4ce158 | 103 | } |
shintamainjp | 0:ec264f4ce158 | 104 | |
suupen | 13:ec76e93a4d7c | 105 | #ifdef ERRORWAIT |
suupen | 13:ec76e93a4d7c | 106 | void ReceiverIR::errorWait(void) |
suupen | 13:ec76e93a4d7c | 107 | { |
suupen | 13:ec76e93a4d7c | 108 | work.state = ErrorWait; |
suupen | 13:ec76e93a4d7c | 109 | timeout.detach(); |
suupen | 13:ec76e93a4d7c | 110 | timeout.attach_us(this, &ReceiverIR::isr_timeout, 50 * 1000); // 50[ms]wait |
suupen | 13:ec76e93a4d7c | 111 | } |
suupen | 13:ec76e93a4d7c | 112 | #endif //ERRORWAIT |
suupen | 13:ec76e93a4d7c | 113 | |
suupen | 13:ec76e93a4d7c | 114 | void ReceiverIR::isr_wdt(void) |
suupen | 13:ec76e93a4d7c | 115 | { |
shintamainjp | 9:dcfdac59ef74 | 116 | LOCK(); |
shintamainjp | 0:ec264f4ce158 | 117 | static int cnt = 0; |
shintamainjp | 9:dcfdac59ef74 | 118 | if ((Idle != work.state) || ((0 <= work.c1) || (0 <= work.c2) || (0 <= work.c3) || (0 <= work.d1) || (0 <= work.d2))) { |
shintamainjp | 0:ec264f4ce158 | 119 | cnt++; |
shintamainjp | 0:ec264f4ce158 | 120 | if (cnt > 50) { |
shintamainjp | 11:268cc2ab63bd | 121 | #if 0 |
shintamainjp | 0:ec264f4ce158 | 122 | printf("# WDT [c1=%d, c2=%d, c3=%d, d1=%d, d2=%d, state=%d, format=%d, bitcount=%d]\n", |
shintamainjp | 0:ec264f4ce158 | 123 | work.c1, |
shintamainjp | 0:ec264f4ce158 | 124 | work.c2, |
shintamainjp | 0:ec264f4ce158 | 125 | work.c3, |
shintamainjp | 0:ec264f4ce158 | 126 | work.d1, |
shintamainjp | 0:ec264f4ce158 | 127 | work.d2, |
shintamainjp | 9:dcfdac59ef74 | 128 | work.state, |
shintamainjp | 0:ec264f4ce158 | 129 | data.format, |
shintamainjp | 0:ec264f4ce158 | 130 | data.bitcount); |
shintamainjp | 0:ec264f4ce158 | 131 | #endif |
shintamainjp | 0:ec264f4ce158 | 132 | init_state(); |
shintamainjp | 0:ec264f4ce158 | 133 | cnt = 0; |
shintamainjp | 0:ec264f4ce158 | 134 | } |
shintamainjp | 0:ec264f4ce158 | 135 | } else { |
shintamainjp | 0:ec264f4ce158 | 136 | cnt = 0; |
shintamainjp | 0:ec264f4ce158 | 137 | } |
shintamainjp | 9:dcfdac59ef74 | 138 | UNLOCK(); |
shintamainjp | 0:ec264f4ce158 | 139 | } |
shintamainjp | 0:ec264f4ce158 | 140 | |
suupen | 13:ec76e93a4d7c | 141 | void ReceiverIR::isr_fall(void) |
suupen | 13:ec76e93a4d7c | 142 | { |
suupen | 12:2379e13b8b34 | 143 | |
suupen | 12:2379e13b8b34 | 144 | #ifdef IR_RAW_DATA_ANALYSIS |
suupen | 12:2379e13b8b34 | 145 | switch (work.state) { |
suupen | 13:ec76e93a4d7c | 146 | case Idle: |
suupen | 13:ec76e93a4d7c | 147 | if (work.c1 < 0) { |
suupen | 13:ec76e93a4d7c | 148 | check.bitcount = 0; |
suupen | 13:ec76e93a4d7c | 149 | check.timecount[check.bitcount++] = 0; |
suupen | 13:ec76e93a4d7c | 150 | } else { |
suupen | 13:ec76e93a4d7c | 151 | check.timecount[check.bitcount++] = timer.read_us() & ~1; |
suupen | 13:ec76e93a4d7c | 152 | } |
suupen | 13:ec76e93a4d7c | 153 | break; |
suupen | 13:ec76e93a4d7c | 154 | case Receiving: |
suupen | 13:ec76e93a4d7c | 155 | |
suupen | 13:ec76e93a4d7c | 156 | if ((check.bitcount < 1000)) { |
suupen | 13:ec76e93a4d7c | 157 | check.timecount[check.bitcount++] = timer.read_us() & ~1; |
suupen | 13:ec76e93a4d7c | 158 | } |
suupen | 13:ec76e93a4d7c | 159 | break; |
suupen | 13:ec76e93a4d7c | 160 | default: |
suupen | 13:ec76e93a4d7c | 161 | break; |
suupen | 12:2379e13b8b34 | 162 | } |
suupen | 12:2379e13b8b34 | 163 | #endif //IR_RAW_DATA_ANALYSIS |
suupen | 12:2379e13b8b34 | 164 | |
shintamainjp | 9:dcfdac59ef74 | 165 | LOCK(); |
shintamainjp | 9:dcfdac59ef74 | 166 | switch (work.state) { |
shintamainjp | 0:ec264f4ce158 | 167 | case Idle: |
shintamainjp | 0:ec264f4ce158 | 168 | if (work.c1 < 0) { |
shintamainjp | 0:ec264f4ce158 | 169 | timer.start(); |
shintamainjp | 0:ec264f4ce158 | 170 | work.c1 = timer.read_us(); |
shintamainjp | 0:ec264f4ce158 | 171 | } else { |
shintamainjp | 0:ec264f4ce158 | 172 | work.c3 = timer.read_us(); |
shintamainjp | 0:ec264f4ce158 | 173 | int a = work.c2 - work.c1; |
shintamainjp | 0:ec264f4ce158 | 174 | int b = work.c3 - work.c2; |
shintamainjp | 11:268cc2ab63bd | 175 | if (InRange(a, RemoteIR::TUS_NEC * 16) && InRange(b, RemoteIR::TUS_NEC * 8)) { |
shintamainjp | 0:ec264f4ce158 | 176 | /* |
shintamainjp | 0:ec264f4ce158 | 177 | * NEC. |
shintamainjp | 0:ec264f4ce158 | 178 | */ |
shintamainjp | 0:ec264f4ce158 | 179 | data.format = RemoteIR::NEC; |
shintamainjp | 9:dcfdac59ef74 | 180 | work.state = Receiving; |
shintamainjp | 0:ec264f4ce158 | 181 | data.bitcount = 0; |
shintamainjp | 11:268cc2ab63bd | 182 | } else if (InRange(a, RemoteIR::TUS_NEC * 16) && InRange(b, RemoteIR::TUS_NEC * 4)) { |
shintamainjp | 0:ec264f4ce158 | 183 | /* |
shintamainjp | 0:ec264f4ce158 | 184 | * NEC Repeat. |
shintamainjp | 0:ec264f4ce158 | 185 | */ |
shintamainjp | 3:dfed23b157e6 | 186 | data.format = RemoteIR::NEC_REPEAT; |
shintamainjp | 9:dcfdac59ef74 | 187 | work.state = Received; |
shintamainjp | 0:ec264f4ce158 | 188 | data.bitcount = 0; |
shintamainjp | 3:dfed23b157e6 | 189 | work.c1 = -1; |
shintamainjp | 3:dfed23b157e6 | 190 | work.c2 = -1; |
shintamainjp | 3:dfed23b157e6 | 191 | work.c3 = -1; |
shintamainjp | 3:dfed23b157e6 | 192 | work.d1 = -1; |
shintamainjp | 3:dfed23b157e6 | 193 | work.d2 = -1; |
shintamainjp | 11:268cc2ab63bd | 194 | } else if (InRange(a, RemoteIR::TUS_AEHA * 8) && InRange(b, RemoteIR::TUS_AEHA * 4)) { |
shintamainjp | 0:ec264f4ce158 | 195 | /* |
shintamainjp | 0:ec264f4ce158 | 196 | * AEHA. |
shintamainjp | 0:ec264f4ce158 | 197 | */ |
shintamainjp | 0:ec264f4ce158 | 198 | data.format = RemoteIR::AEHA; |
shintamainjp | 9:dcfdac59ef74 | 199 | work.state = Receiving; |
shintamainjp | 0:ec264f4ce158 | 200 | data.bitcount = 0; |
shintamainjp | 11:268cc2ab63bd | 201 | } else if (InRange(a, RemoteIR::TUS_AEHA * 8) && InRange(b, RemoteIR::TUS_AEHA * 8)) { |
shintamainjp | 0:ec264f4ce158 | 202 | /* |
shintamainjp | 0:ec264f4ce158 | 203 | * AEHA Repeat. |
shintamainjp | 0:ec264f4ce158 | 204 | */ |
shintamainjp | 3:dfed23b157e6 | 205 | data.format = RemoteIR::AEHA_REPEAT; |
shintamainjp | 9:dcfdac59ef74 | 206 | work.state = Received; |
shintamainjp | 0:ec264f4ce158 | 207 | data.bitcount = 0; |
shintamainjp | 3:dfed23b157e6 | 208 | work.c1 = -1; |
shintamainjp | 3:dfed23b157e6 | 209 | work.c2 = -1; |
shintamainjp | 3:dfed23b157e6 | 210 | work.c3 = -1; |
shintamainjp | 3:dfed23b157e6 | 211 | work.d1 = -1; |
shintamainjp | 3:dfed23b157e6 | 212 | work.d2 = -1; |
suupen | 12:2379e13b8b34 | 213 | #ifdef SWIFT_PROTCOL |
suupen | 12:2379e13b8b34 | 214 | } else if (InRange(a, RemoteIR::TUS_SWIFT * 10) && InRange(b, RemoteIR::TUS_SWIFT * 3)) { |
suupen | 12:2379e13b8b34 | 215 | /* |
suupen | 12:2379e13b8b34 | 216 | * SWIFT. |
suupen | 12:2379e13b8b34 | 217 | */ |
suupen | 12:2379e13b8b34 | 218 | data.format = RemoteIR::SWIFT; |
suupen | 12:2379e13b8b34 | 219 | work.state = Receiving; |
suupen | 12:2379e13b8b34 | 220 | data.bitcount = 0; |
suupen | 12:2379e13b8b34 | 221 | #endif // SWIFT_PROTCOL |
shintamainjp | 0:ec264f4ce158 | 222 | } else { |
suupen | 12:2379e13b8b34 | 223 | #ifdef IR_RAW_DATA_ANALYSIS |
suupen | 12:2379e13b8b34 | 224 | data.format = RemoteIR::UNKNOWN; |
suupen | 12:2379e13b8b34 | 225 | work.state = Receiving; |
suupen | 12:2379e13b8b34 | 226 | data.bitcount = 0; |
suupen | 13:ec76e93a4d7c | 227 | #else // ~IR_RAW_DATA_ANALYSIS |
suupen | 13:ec76e93a4d7c | 228 | #ifdef ERRORWAIT |
suupen | 13:ec76e93a4d7c | 229 | errorWait(); |
suupen | 13:ec76e93a4d7c | 230 | #else // ~ERRORWAIT |
shintamainjp | 0:ec264f4ce158 | 231 | init_state(); |
suupen | 13:ec76e93a4d7c | 232 | #endif // ERRORWAIT |
suupen | 12:2379e13b8b34 | 233 | #endif // IR_RAW_DATA_ANALYSIS |
suupen | 13:ec76e93a4d7c | 234 | } |
shintamainjp | 0:ec264f4ce158 | 235 | } |
shintamainjp | 0:ec264f4ce158 | 236 | break; |
shintamainjp | 0:ec264f4ce158 | 237 | case Receiving: |
shintamainjp | 0:ec264f4ce158 | 238 | if (RemoteIR::NEC == data.format) { |
shintamainjp | 0:ec264f4ce158 | 239 | work.d2 = timer.read_us(); |
shintamainjp | 0:ec264f4ce158 | 240 | int a = work.d2 - work.d1; |
shintamainjp | 11:268cc2ab63bd | 241 | if (InRange(a, RemoteIR::TUS_NEC * 3)) { |
shintamainjp | 0:ec264f4ce158 | 242 | data.buffer[data.bitcount / 8] |= (1 << (data.bitcount % 8)); |
shintamainjp | 11:268cc2ab63bd | 243 | } else if (InRange(a, RemoteIR::TUS_NEC * 1)) { |
shintamainjp | 0:ec264f4ce158 | 244 | data.buffer[data.bitcount / 8] &= ~(1 << (data.bitcount % 8)); |
shintamainjp | 0:ec264f4ce158 | 245 | } |
shintamainjp | 0:ec264f4ce158 | 246 | data.bitcount++; |
shintamainjp | 3:dfed23b157e6 | 247 | #if 0 |
shintamainjp | 0:ec264f4ce158 | 248 | /* |
shintamainjp | 0:ec264f4ce158 | 249 | * Length of NEC is always 32 bits. |
shintamainjp | 0:ec264f4ce158 | 250 | */ |
shintamainjp | 0:ec264f4ce158 | 251 | if (32 <= data.bitcount) { |
shintamainjp | 0:ec264f4ce158 | 252 | data.state = Received; |
shintamainjp | 0:ec264f4ce158 | 253 | work.c1 = -1; |
shintamainjp | 0:ec264f4ce158 | 254 | work.c2 = -1; |
shintamainjp | 0:ec264f4ce158 | 255 | work.c3 = -1; |
shintamainjp | 0:ec264f4ce158 | 256 | work.d1 = -1; |
shintamainjp | 0:ec264f4ce158 | 257 | work.d2 = -1; |
shintamainjp | 0:ec264f4ce158 | 258 | } |
shintamainjp | 0:ec264f4ce158 | 259 | #else |
shintamainjp | 0:ec264f4ce158 | 260 | /* |
shintamainjp | 0:ec264f4ce158 | 261 | * Set timeout for tail detection automatically. |
shintamainjp | 0:ec264f4ce158 | 262 | */ |
shintamainjp | 0:ec264f4ce158 | 263 | timeout.detach(); |
shintamainjp | 11:268cc2ab63bd | 264 | timeout.attach_us(this, &ReceiverIR::isr_timeout, RemoteIR::TUS_NEC * 5); |
shintamainjp | 0:ec264f4ce158 | 265 | #endif |
shintamainjp | 0:ec264f4ce158 | 266 | } else if (RemoteIR::AEHA == data.format) { |
shintamainjp | 0:ec264f4ce158 | 267 | work.d2 = timer.read_us(); |
shintamainjp | 0:ec264f4ce158 | 268 | int a = work.d2 - work.d1; |
shintamainjp | 11:268cc2ab63bd | 269 | if (InRange(a, RemoteIR::TUS_AEHA * 3)) { |
shintamainjp | 0:ec264f4ce158 | 270 | data.buffer[data.bitcount / 8] |= (1 << (data.bitcount % 8)); |
shintamainjp | 11:268cc2ab63bd | 271 | } else if (InRange(a, RemoteIR::TUS_AEHA * 1)) { |
shintamainjp | 0:ec264f4ce158 | 272 | data.buffer[data.bitcount / 8] &= ~(1 << (data.bitcount % 8)); |
shintamainjp | 0:ec264f4ce158 | 273 | } |
shintamainjp | 0:ec264f4ce158 | 274 | data.bitcount++; |
shintamainjp | 3:dfed23b157e6 | 275 | #if 0 |
shintamainjp | 0:ec264f4ce158 | 276 | /* |
shintamainjp | 0:ec264f4ce158 | 277 | * Typical length of AEHA is 48 bits. |
shintamainjp | 0:ec264f4ce158 | 278 | * Please check a specification of your remote controller if you find a problem. |
shintamainjp | 0:ec264f4ce158 | 279 | */ |
shintamainjp | 0:ec264f4ce158 | 280 | if (48 <= data.bitcount) { |
shintamainjp | 0:ec264f4ce158 | 281 | data.state = Received; |
shintamainjp | 0:ec264f4ce158 | 282 | work.c1 = -1; |
shintamainjp | 0:ec264f4ce158 | 283 | work.c2 = -1; |
shintamainjp | 0:ec264f4ce158 | 284 | work.c3 = -1; |
shintamainjp | 0:ec264f4ce158 | 285 | work.d1 = -1; |
shintamainjp | 0:ec264f4ce158 | 286 | work.d2 = -1; |
shintamainjp | 0:ec264f4ce158 | 287 | } |
shintamainjp | 0:ec264f4ce158 | 288 | #else |
shintamainjp | 0:ec264f4ce158 | 289 | /* |
shintamainjp | 0:ec264f4ce158 | 290 | * Set timeout for tail detection automatically. |
shintamainjp | 0:ec264f4ce158 | 291 | */ |
shintamainjp | 0:ec264f4ce158 | 292 | timeout.detach(); |
shintamainjp | 11:268cc2ab63bd | 293 | timeout.attach_us(this, &ReceiverIR::isr_timeout, RemoteIR::TUS_AEHA * 5); |
shintamainjp | 0:ec264f4ce158 | 294 | #endif |
shintamainjp | 0:ec264f4ce158 | 295 | } else if (RemoteIR::SONY == data.format) { |
shintamainjp | 0:ec264f4ce158 | 296 | work.d1 = timer.read_us(); |
suupen | 13:ec76e93a4d7c | 297 | #ifdef SWIFT_PROTCOL |
suupen | 12:2379e13b8b34 | 298 | } else if (RemoteIR::SWIFT == data.format) { |
suupen | 12:2379e13b8b34 | 299 | work.d2 = timer.read_us(); |
suupen | 12:2379e13b8b34 | 300 | int a = work.d2 - work.d1; |
suupen | 12:2379e13b8b34 | 301 | if (InRange(a, RemoteIR::TUS_SWIFT * 2)) { |
suupen | 12:2379e13b8b34 | 302 | data.buffer[data.bitcount / 8] |= (1 << (7 - (data.bitcount % 8))); |
suupen | 12:2379e13b8b34 | 303 | } else if (InRange(a, RemoteIR::TUS_SWIFT * 1)) { |
suupen | 12:2379e13b8b34 | 304 | data.buffer[data.bitcount / 8] &= ~(1 << (7 - (data.bitcount % 8))); |
suupen | 12:2379e13b8b34 | 305 | } |
suupen | 12:2379e13b8b34 | 306 | data.bitcount++; |
suupen | 12:2379e13b8b34 | 307 | #if 0 |
suupen | 12:2379e13b8b34 | 308 | /* |
suupen | 12:2379e13b8b34 | 309 | * Length of SWIFT is always 32 bits. |
suupen | 12:2379e13b8b34 | 310 | */ |
suupen | 12:2379e13b8b34 | 311 | if (32 <= data.bitcount) { |
suupen | 12:2379e13b8b34 | 312 | work.state = Received; |
suupen | 12:2379e13b8b34 | 313 | work.c1 = -1; |
suupen | 12:2379e13b8b34 | 314 | work.c2 = -1; |
suupen | 12:2379e13b8b34 | 315 | work.c3 = -1; |
suupen | 12:2379e13b8b34 | 316 | work.d1 = -1; |
suupen | 12:2379e13b8b34 | 317 | work.d2 = -1; |
suupen | 12:2379e13b8b34 | 318 | } |
suupen | 12:2379e13b8b34 | 319 | #else |
suupen | 12:2379e13b8b34 | 320 | /* |
suupen | 12:2379e13b8b34 | 321 | * Set timeout for tail detection automatically. |
suupen | 12:2379e13b8b34 | 322 | */ |
suupen | 12:2379e13b8b34 | 323 | timeout.detach(); |
suupen | 12:2379e13b8b34 | 324 | timeout.attach_us(this, &ReceiverIR::isr_timeout, RemoteIR::TUS_SWIFT * 5); |
suupen | 12:2379e13b8b34 | 325 | #endif |
suupen | 12:2379e13b8b34 | 326 | #endif // SWIFT_PROTCOL |
suupen | 12:2379e13b8b34 | 327 | |
suupen | 12:2379e13b8b34 | 328 | #ifdef IR_RAW_DATA_ANALYSIS |
suupen | 12:2379e13b8b34 | 329 | } else if (RemoteIR::SWIFT == data.format) { |
suupen | 13:ec76e93a4d7c | 330 | /* |
suupen | 13:ec76e93a4d7c | 331 | * Set timeout for tail detection automatically. |
suupen | 13:ec76e93a4d7c | 332 | */ |
suupen | 12:2379e13b8b34 | 333 | timeout.detach(); |
suupen | 12:2379e13b8b34 | 334 | timeout.attach_us(this, &ReceiverIR::isr_timeout, (work.c3 - work.c2) * 5); |
suupen | 12:2379e13b8b34 | 335 | #endif // IR_RAW_DATA_ANALYSIS |
shintamainjp | 0:ec264f4ce158 | 336 | } |
shintamainjp | 0:ec264f4ce158 | 337 | break; |
shintamainjp | 0:ec264f4ce158 | 338 | case Received: |
shintamainjp | 0:ec264f4ce158 | 339 | break; |
suupen | 13:ec76e93a4d7c | 340 | #ifdef ERRORWAIT |
suupen | 13:ec76e93a4d7c | 341 | case ErrorWait: |
suupen | 13:ec76e93a4d7c | 342 | errorWait(); |
suupen | 13:ec76e93a4d7c | 343 | break; |
suupen | 13:ec76e93a4d7c | 344 | #endif //ERRORWAIT |
shintamainjp | 0:ec264f4ce158 | 345 | default: |
shintamainjp | 0:ec264f4ce158 | 346 | break; |
shintamainjp | 0:ec264f4ce158 | 347 | } |
shintamainjp | 9:dcfdac59ef74 | 348 | UNLOCK(); |
shintamainjp | 0:ec264f4ce158 | 349 | } |
shintamainjp | 0:ec264f4ce158 | 350 | |
suupen | 13:ec76e93a4d7c | 351 | void ReceiverIR::isr_rise(void) |
suupen | 13:ec76e93a4d7c | 352 | { |
suupen | 12:2379e13b8b34 | 353 | |
suupen | 12:2379e13b8b34 | 354 | #ifdef IR_RAW_DATA_ANALYSIS |
suupen | 12:2379e13b8b34 | 355 | switch (work.state) { |
suupen | 13:ec76e93a4d7c | 356 | case Idle: |
suupen | 13:ec76e93a4d7c | 357 | case Receiving: |
suupen | 13:ec76e93a4d7c | 358 | check.timecount[check.bitcount++] = timer.read_us() | 1; |
suupen | 13:ec76e93a4d7c | 359 | break; |
suupen | 13:ec76e93a4d7c | 360 | #ifdef ERRORWAIT |
suupen | 13:ec76e93a4d7c | 361 | case ErrorWait: |
suupen | 13:ec76e93a4d7c | 362 | // nothing |
suupen | 13:ec76e93a4d7c | 363 | break; |
suupen | 13:ec76e93a4d7c | 364 | #endif //ERRORWAIT |
suupen | 13:ec76e93a4d7c | 365 | default: |
suupen | 13:ec76e93a4d7c | 366 | break; |
suupen | 12:2379e13b8b34 | 367 | } |
suupen | 12:2379e13b8b34 | 368 | #endif //IR_RAW_DATA_ANALYSIS |
suupen | 12:2379e13b8b34 | 369 | |
shintamainjp | 9:dcfdac59ef74 | 370 | LOCK(); |
shintamainjp | 9:dcfdac59ef74 | 371 | switch (work.state) { |
shintamainjp | 0:ec264f4ce158 | 372 | case Idle: |
shintamainjp | 0:ec264f4ce158 | 373 | if (0 <= work.c1) { |
shintamainjp | 0:ec264f4ce158 | 374 | work.c2 = timer.read_us(); |
shintamainjp | 0:ec264f4ce158 | 375 | int a = work.c2 - work.c1; |
shintamainjp | 11:268cc2ab63bd | 376 | if (InRange(a, RemoteIR::TUS_SONY * 4)) { |
shintamainjp | 0:ec264f4ce158 | 377 | data.format = RemoteIR::SONY; |
shintamainjp | 9:dcfdac59ef74 | 378 | work.state = Receiving; |
shintamainjp | 0:ec264f4ce158 | 379 | data.bitcount = 0; |
shintamainjp | 0:ec264f4ce158 | 380 | } else { |
shintamainjp | 0:ec264f4ce158 | 381 | static const int MINIMUM_LEADER_WIDTH = 150; |
shintamainjp | 0:ec264f4ce158 | 382 | if (a < MINIMUM_LEADER_WIDTH) { |
shintamainjp | 0:ec264f4ce158 | 383 | init_state(); |
shintamainjp | 0:ec264f4ce158 | 384 | } |
shintamainjp | 0:ec264f4ce158 | 385 | } |
shintamainjp | 0:ec264f4ce158 | 386 | } else { |
shintamainjp | 0:ec264f4ce158 | 387 | init_state(); |
shintamainjp | 0:ec264f4ce158 | 388 | } |
shintamainjp | 0:ec264f4ce158 | 389 | break; |
shintamainjp | 0:ec264f4ce158 | 390 | case Receiving: |
shintamainjp | 0:ec264f4ce158 | 391 | if (RemoteIR::NEC == data.format) { |
shintamainjp | 0:ec264f4ce158 | 392 | work.d1 = timer.read_us(); |
shintamainjp | 0:ec264f4ce158 | 393 | } else if (RemoteIR::AEHA == data.format) { |
shintamainjp | 0:ec264f4ce158 | 394 | work.d1 = timer.read_us(); |
suupen | 12:2379e13b8b34 | 395 | #ifdef SWIFT_PROTCOL |
suupen | 12:2379e13b8b34 | 396 | } else if (RemoteIR::SWIFT == data.format) { |
suupen | 12:2379e13b8b34 | 397 | work.d1 = timer.read_us(); |
suupen | 12:2379e13b8b34 | 398 | #endif // SWIFT_PROTCOL |
shintamainjp | 0:ec264f4ce158 | 399 | } else if (RemoteIR::SONY == data.format) { |
shintamainjp | 0:ec264f4ce158 | 400 | work.d2 = timer.read_us(); |
shintamainjp | 0:ec264f4ce158 | 401 | int a = work.d2 - work.d1; |
shintamainjp | 11:268cc2ab63bd | 402 | if (InRange(a, RemoteIR::TUS_SONY * 2)) { |
shintamainjp | 0:ec264f4ce158 | 403 | data.buffer[data.bitcount / 8] |= (1 << (data.bitcount % 8)); |
shintamainjp | 11:268cc2ab63bd | 404 | } else if (InRange(a, RemoteIR::TUS_SONY * 1)) { |
shintamainjp | 0:ec264f4ce158 | 405 | data.buffer[data.bitcount / 8] &= ~(1 << (data.bitcount % 8)); |
shintamainjp | 0:ec264f4ce158 | 406 | } |
shintamainjp | 0:ec264f4ce158 | 407 | data.bitcount++; |
shintamainjp | 3:dfed23b157e6 | 408 | #if 0 |
shintamainjp | 0:ec264f4ce158 | 409 | /* |
shintamainjp | 9:dcfdac59ef74 | 410 | * How do I know the correct length? (6bits, 12bits, 15bits, 20bits...) |
shintamainjp | 0:ec264f4ce158 | 411 | * By a model only? |
shintamainjp | 0:ec264f4ce158 | 412 | * Please check a specification of your remote controller if you find a problem. |
shintamainjp | 0:ec264f4ce158 | 413 | */ |
shintamainjp | 0:ec264f4ce158 | 414 | if (12 <= data.bitcount) { |
shintamainjp | 0:ec264f4ce158 | 415 | data.state = Received; |
shintamainjp | 0:ec264f4ce158 | 416 | work.c1 = -1; |
shintamainjp | 0:ec264f4ce158 | 417 | work.c2 = -1; |
shintamainjp | 0:ec264f4ce158 | 418 | work.c3 = -1; |
shintamainjp | 0:ec264f4ce158 | 419 | work.d1 = -1; |
shintamainjp | 0:ec264f4ce158 | 420 | work.d2 = -1; |
shintamainjp | 0:ec264f4ce158 | 421 | } |
shintamainjp | 0:ec264f4ce158 | 422 | #else |
shintamainjp | 0:ec264f4ce158 | 423 | /* |
shintamainjp | 0:ec264f4ce158 | 424 | * Set timeout for tail detection automatically. |
shintamainjp | 0:ec264f4ce158 | 425 | */ |
shintamainjp | 0:ec264f4ce158 | 426 | timeout.detach(); |
shintamainjp | 11:268cc2ab63bd | 427 | timeout.attach_us(this, &ReceiverIR::isr_timeout, RemoteIR::TUS_SONY * 4); |
shintamainjp | 0:ec264f4ce158 | 428 | #endif |
shintamainjp | 0:ec264f4ce158 | 429 | } |
shintamainjp | 0:ec264f4ce158 | 430 | break; |
shintamainjp | 0:ec264f4ce158 | 431 | case Received: |
shintamainjp | 0:ec264f4ce158 | 432 | break; |
suupen | 13:ec76e93a4d7c | 433 | #ifdef ERRORWAIT |
suupen | 13:ec76e93a4d7c | 434 | case ErrorWait: |
suupen | 13:ec76e93a4d7c | 435 | // nothing |
suupen | 13:ec76e93a4d7c | 436 | break; |
suupen | 13:ec76e93a4d7c | 437 | #endif //ERRORWAIT |
shintamainjp | 0:ec264f4ce158 | 438 | default: |
shintamainjp | 0:ec264f4ce158 | 439 | break; |
shintamainjp | 0:ec264f4ce158 | 440 | } |
shintamainjp | 9:dcfdac59ef74 | 441 | UNLOCK(); |
shintamainjp | 0:ec264f4ce158 | 442 | } |
shintamainjp | 0:ec264f4ce158 | 443 | |
suupen | 13:ec76e93a4d7c | 444 | void ReceiverIR::isr_timeout(void) |
suupen | 13:ec76e93a4d7c | 445 | { |
shintamainjp | 9:dcfdac59ef74 | 446 | LOCK(); |
shintamainjp | 9:dcfdac59ef74 | 447 | #if 0 |
shintamainjp | 9:dcfdac59ef74 | 448 | printf("# TIMEOUT [c1=%d, c2=%d, c3=%d, d1=%d, d2=%d, state=%d, format=%d, bitcount=%d]\n", |
shintamainjp | 9:dcfdac59ef74 | 449 | work.c1, |
shintamainjp | 9:dcfdac59ef74 | 450 | work.c2, |
shintamainjp | 9:dcfdac59ef74 | 451 | work.c3, |
shintamainjp | 9:dcfdac59ef74 | 452 | work.d1, |
shintamainjp | 9:dcfdac59ef74 | 453 | work.d2, |
shintamainjp | 9:dcfdac59ef74 | 454 | work.state, |
shintamainjp | 9:dcfdac59ef74 | 455 | data.format, |
shintamainjp | 9:dcfdac59ef74 | 456 | data.bitcount); |
shintamainjp | 9:dcfdac59ef74 | 457 | #endif |
suupen | 12:2379e13b8b34 | 458 | |
suupen | 12:2379e13b8b34 | 459 | #ifdef IR_RAW_DATA_ANALYSIS |
suupen | 12:2379e13b8b34 | 460 | #if 1 //debug |
suupen | 13:ec76e93a4d7c | 461 | for ( int i = 0; i < check.bitcount; i++) { |
suupen | 12:2379e13b8b34 | 462 | printf("%02d : %06d , %06d , %04d \n", |
suupen | 13:ec76e93a4d7c | 463 | i, |
suupen | 13:ec76e93a4d7c | 464 | check.timecount[i], |
suupen | 13:ec76e93a4d7c | 465 | check.timecount[i + 1], |
suupen | 13:ec76e93a4d7c | 466 | (check.timecount[i + 1] - check.timecount[i])); |
suupen | 13:ec76e93a4d7c | 467 | |
suupen | 13:ec76e93a4d7c | 468 | if( (i % 2) != 0) { |
suupen | 13:ec76e93a4d7c | 469 | printf("\n"); |
suupen | 13:ec76e93a4d7c | 470 | } |
suupen | 13:ec76e93a4d7c | 471 | } |
suupen | 12:2379e13b8b34 | 472 | printf("\n"); |
suupen | 12:2379e13b8b34 | 473 | #endif //debug |
suupen | 12:2379e13b8b34 | 474 | #endif //IR_RAW_DATA_ANALYSIS |
suupen | 12:2379e13b8b34 | 475 | |
shintamainjp | 9:dcfdac59ef74 | 476 | if (work.state == Receiving) { |
shintamainjp | 9:dcfdac59ef74 | 477 | work.state = Received; |
shintamainjp | 0:ec264f4ce158 | 478 | work.c1 = -1; |
shintamainjp | 0:ec264f4ce158 | 479 | work.c2 = -1; |
shintamainjp | 0:ec264f4ce158 | 480 | work.c3 = -1; |
shintamainjp | 0:ec264f4ce158 | 481 | work.d1 = -1; |
shintamainjp | 0:ec264f4ce158 | 482 | work.d2 = -1; |
shintamainjp | 0:ec264f4ce158 | 483 | } |
suupen | 13:ec76e93a4d7c | 484 | #ifdef ERRORWAIT |
suupen | 13:ec76e93a4d7c | 485 | else if(work.state == ErrorWait){ |
suupen | 13:ec76e93a4d7c | 486 | init_state(); |
suupen | 13:ec76e93a4d7c | 487 | } |
suupen | 13:ec76e93a4d7c | 488 | #endif // ERRORWAIT |
shintamainjp | 9:dcfdac59ef74 | 489 | UNLOCK(); |
shintamainjp | 0:ec264f4ce158 | 490 | } |
suupen | 12:2379e13b8b34 | 491 | |
suupen | 12:2379e13b8b34 | 492 |