Shinichiro Nakamura
/
StarBoardOrangeExample2
StarBoard Orange - Example application No.2 (Version 0.0.4)
Diff: RemoteIR/ReceiverIR.cpp
- Revision:
- 3:469de11d1e1d
- Parent:
- 2:d4625043c895
--- a/RemoteIR/ReceiverIR.cpp Sun Aug 15 10:41:12 2010 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,243 +0,0 @@ -/** - * IR receiver (Version 0.0.2) - * - * Copyright (C) 2010 Shinichiro Nakamura (CuBeatSystems) - * http://shinta.main.jp/ - */ - -#include "ReceiverIR.h" - -#define InRange(x,y) ((((y) * 0.7) < (x)) && ((x) < ((y) * 1.3))) -#define IRQ_ENABLE() sem.release(); __enable_irq() -#define IRQ_DISABLE() __disable_irq(); sem.take() - -ReceiverIR::ReceiverIR(PinName rx) : evt(rx) { - IRQ_DISABLE(); - evt.fall(this, &ReceiverIR::isr_fall); - evt.rise(this, &ReceiverIR::isr_rise); - ticker.attach_us(this, &ReceiverIR::isr_wdt, 1 * 1000); - init_state(); - IRQ_ENABLE(); -} - -ReceiverIR::~ReceiverIR() {} - -ReceiverIR::State ReceiverIR::getState() { - IRQ_DISABLE(); - State s = data.state; - IRQ_ENABLE(); - return s; -} - -int ReceiverIR::getData(ReceiverIR::Format *format, uint8_t *buf, int bufsiz) { - IRQ_DISABLE(); - - const int bc = data.bitcount; - if (bufsiz < (bc / 8)) { - IRQ_ENABLE(); - return -1; - } - - *format = data.format; - for (int i = 0; i < (bc / 8); i++) { - buf[i] = data.buffer[i]; - } - - init_state(); - - IRQ_ENABLE(); - return bc; -} - -void ReceiverIR::init_state(void) { - work.c1 = -1; - work.c2 = -1; - work.c3 = -1; - work.d1 = -1; - work.d2 = -1; - data.state = Idle; - data.format = UNKNOWN; - data.bitcount = 0; - timer.stop(); - timer.reset(); - for (int i = 0; i < sizeof(data.buffer); i++) { - data.buffer[i] = 0; - } -} - -void ReceiverIR::isr_wdt(void) { - IRQ_DISABLE(); - static int cnt = 0; - if ((Receiving == data.state) || ((0 <= work.c1) || (0 <= work.c2) || (0 <= work.c3))) { - cnt++; - if (cnt > 500) { - printf("# WDT [c1=%d, c2=%d, c3=%d, d1=%d, d2=%d, state=%d, format=%d, bitcount=%d]\n", - work.c1, - work.c2, - work.c3, - work.d1, - work.d2, - data.state, - data.format, - data.bitcount); - init_state(); - cnt = 0; - } - } else { - cnt = 0; - } - IRQ_ENABLE(); -} - -void ReceiverIR::isr_fall(void) { - IRQ_DISABLE(); - switch (data.state) { - case Idle: - if (work.c1 < 0) { - timer.start(); - work.c1 = timer.read_us(); - } else { - work.c3 = timer.read_us(); - int a = work.c2 - work.c1; - int b = work.c3 - work.c2; - if (InRange(a, TUS_NEC * 16) && InRange(b, TUS_NEC * 8)) { - /* - * NEC. - */ - data.format = NEC; - data.state = Receiving; - data.bitcount = 0; - } else if (InRange(a, TUS_NEC * 16) && InRange(b, TUS_NEC * 4)) { - /* - * NEC Repeat. - */ - data.format = NEC; - data.state = Received; - data.bitcount = 0; - } else if (InRange(a, TUS_AEHA * 8) && InRange(b, TUS_AEHA * 4)) { - /* - * AEHA. - */ - data.format = AEHA; - data.state = Receiving; - data.bitcount = 0; - } else if (InRange(a, TUS_AEHA * 8) && InRange(b, TUS_AEHA * 8)) { - /* - * AEHA Repeat. - */ - data.format = AEHA; - data.state = Received; - data.bitcount = 0; - } else { - init_state(); - } - } - break; - case Receiving: - if (NEC == data.format) { - work.d2 = timer.read_us(); - int a = work.d2 - work.d1; - if (InRange(a, TUS_NEC * 3)) { - data.buffer[data.bitcount / 8] |= (1 << (data.bitcount % 8)); - } else if (InRange(a, TUS_NEC * 1)) { - data.buffer[data.bitcount / 8] &= ~(1 << (data.bitcount % 8)); - } - data.bitcount++; - if (32 <= data.bitcount) { - data.state = Received; - work.c1 = -1; - work.c2 = -1; - work.c3 = -1; - work.d1 = -1; - work.d2 = -1; - } - } else if (AEHA == data.format) { - work.d2 = timer.read_us(); - int a = work.d2 - work.d1; - if (InRange(a, TUS_AEHA * 3)) { - data.buffer[data.bitcount / 8] |= (1 << (data.bitcount % 8)); - } else if (InRange(a, TUS_AEHA * 1)) { - data.buffer[data.bitcount / 8] &= ~(1 << (data.bitcount % 8)); - } - data.bitcount++; - /* - * Typical length of AEHA is 48 bits. - * Please check a specification of your remote controller if you find a problem. - */ - if (48 <= data.bitcount) { - data.state = Received; - work.c1 = -1; - work.c2 = -1; - work.c3 = -1; - work.d1 = -1; - work.d2 = -1; - } - } else if (SONY == data.format) { - work.d1 = timer.read_us(); - } - break; - case Received: - break; - default: - break; - } - IRQ_ENABLE(); -} - -void ReceiverIR::isr_rise(void) { - IRQ_DISABLE(); - switch (data.state) { - case Idle: - if (0 <= work.c1) { - work.c2 = timer.read_us(); - int a = work.c2 - work.c1; - if (InRange(a, TUS_SONY * 4)) { - data.format = SONY; - data.state = Receiving; - data.bitcount = 0; - } else { - static const int MINIMUM_LEADER_WIDTH = 150; - if (a < MINIMUM_LEADER_WIDTH) { - init_state(); - } - } - } else { - init_state(); - } - break; - case Receiving: - if (NEC == data.format) { - work.d1 = timer.read_us(); - } else if (AEHA == data.format) { - work.d1 = timer.read_us(); - } else if (SONY == data.format) { - work.d2 = timer.read_us(); - int a = work.d2 - work.d1; - if (InRange(a, TUS_SONY * 2)) { - data.buffer[data.bitcount / 8] |= (1 << (data.bitcount % 8)); - } else if (InRange(a, TUS_SONY * 1)) { - data.buffer[data.bitcount / 8] &= ~(1 << (data.bitcount % 8)); - } - data.bitcount++; - /* - * How do we get the correct length? (12bits, 15bits, 20bits...) - * By a model only? - * Please check a specification of your remote controller if you find a problem. - */ - if (12 <= data.bitcount) { - data.state = Received; - work.c1 = -1; - work.c2 = -1; - work.c3 = -1; - work.d1 = -1; - work.d2 = -1; - } - } - break; - case Received: - break; - default: - break; - } - IRQ_ENABLE(); -}