RemoteIR.

Dependents:   RemoteIR_TestProgram SerialGPS_TestProgram StarBoardOrangeExpansion1 Door_Slamming_Device ... more

Revision:
9:dcfdac59ef74
Parent:
7:9452ba065449
Child:
10:c54fb1204d1e
diff -r 46e34d6ddbe4 -r dcfdac59ef74 ReceiverIR.cpp
--- a/ReceiverIR.cpp	Sat Aug 21 13:28:50 2010 +0000
+++ b/ReceiverIR.cpp	Fri Sep 17 20:22:38 2010 +0000
@@ -1,5 +1,5 @@
 /**
- * IR receiver (Version 0.0.3)
+ * IR receiver (Version 0.0.4)
  *
  * Copyright (C) 2010 Shinichiro Nakamura (CuBeatSystems)
  * http://shinta.main.jp/
@@ -7,40 +7,61 @@
 
 #include "ReceiverIR.h"
 
-#define IRQ_ENABLE()    sem.release(); __enable_irq()
-#define IRQ_DISABLE()   sem.take(); __disable_irq()
+#define LOCK() sem.take()
+#define UNLOCK() sem.release()
 
 #define InRange(x,y)   ((((y) * 0.7) < (x)) && ((x) < ((y) * 1.3)))
 
+/**
+ * Constructor.
+ *
+ * @param rxpin Pin for receive IR signal.
+ */
 ReceiverIR::ReceiverIR(PinName rxpin) : evt(rxpin) {
-    IRQ_DISABLE();
+    init_state();
     evt.fall(this, &ReceiverIR::isr_fall);
     evt.rise(this, &ReceiverIR::isr_rise);
     evt.mode(PullUp);
     ticker.attach_us(this, &ReceiverIR::isr_wdt, 10 * 1000);
-    init_state();
-    IRQ_ENABLE();
 }
 
+/**
+ * Destructor.
+ */
 ReceiverIR::~ReceiverIR() {
 }
 
+/**
+ * Get state.
+ *
+ * @return Current state.
+ */
 ReceiverIR::State ReceiverIR::getState() {
-    IRQ_DISABLE();
-    State s = data.state;
-    IRQ_ENABLE();
+    LOCK();
+    State s = work.state;
+    UNLOCK();
     wait_ms(10);
     return s;
 }
 
+/**
+ * Get data.
+ *
+ * @param format Pointer to format.
+ * @param buf Buffer of a data.
+ * @param bitlength Bit length of the buffer.
+ *
+ * @return Data bit length.
+ */
 int ReceiverIR::getData(RemoteIR::Format *format, uint8_t *buf, int bitlength) {
-    IRQ_DISABLE();
+    LOCK();
 
     if (bitlength < data.bitcount) {
-        IRQ_ENABLE();
+        UNLOCK();
         return -1;
     }
 
+    const int nbits = data.bitcount;
     const int nbytes = data.bitcount / 8 + (((data.bitcount % 8) != 0) ? 1 : 0);
     *format = data.format;
     for (int i = 0; i < nbytes; i++) {
@@ -49,8 +70,8 @@
 
     init_state();
 
-    IRQ_ENABLE();
-    return data.bitcount;
+    UNLOCK();
+    return nbits;
 }
 
 void ReceiverIR::init_state(void) {
@@ -59,7 +80,7 @@
     work.c3 = -1;
     work.d1 = -1;
     work.d2 = -1;
-    data.state = Idle;
+    work.state = Idle;
     data.format = RemoteIR::UNKNOWN;
     data.bitcount = 0;
     timer.stop();
@@ -70,9 +91,9 @@
 }
 
 void ReceiverIR::isr_wdt(void) {
-    IRQ_DISABLE();
+    LOCK();
     static int cnt = 0;
-    if ((Idle != data.state) || ((0 <= work.c1) || (0 <= work.c2) || (0 <= work.c3) || (0 <= work.d1) || (0 <= work.d2))) {
+    if ((Idle != work.state) || ((0 <= work.c1) || (0 <= work.c2) || (0 <= work.c3) || (0 <= work.d1) || (0 <= work.d2))) {
         cnt++;
         if (cnt > 50) {
 #if 1
@@ -82,7 +103,7 @@
                    work.c3,
                    work.d1,
                    work.d2,
-                   data.state,
+                   work.state,
                    data.format,
                    data.bitcount);
 #endif
@@ -92,12 +113,12 @@
     } else {
         cnt = 0;
     }
-    IRQ_ENABLE();
+    UNLOCK();
 }
 
 void ReceiverIR::isr_fall(void) {
-    IRQ_DISABLE();
-    switch (data.state) {
+    LOCK();
+    switch (work.state) {
         case Idle:
             if (work.c1 < 0) {
                 timer.start();
@@ -111,14 +132,14 @@
                      * NEC.
                      */
                     data.format = RemoteIR::NEC;
-                    data.state = Receiving;
+                    work.state = Receiving;
                     data.bitcount = 0;
                 } else if (InRange(a, TUS_NEC * 16) && InRange(b, TUS_NEC * 4)) {
                     /*
                      * NEC Repeat.
                      */
                     data.format = RemoteIR::NEC_REPEAT;
-                    data.state = Received;
+                    work.state = Received;
                     data.bitcount = 0;
                     work.c1 = -1;
                     work.c2 = -1;
@@ -130,14 +151,14 @@
                      * AEHA.
                      */
                     data.format = RemoteIR::AEHA;
-                    data.state = Receiving;
+                    work.state = Receiving;
                     data.bitcount = 0;
                 } else if (InRange(a, TUS_AEHA * 8) && InRange(b, TUS_AEHA * 8)) {
                     /*
                      * AEHA Repeat.
                      */
                     data.format = RemoteIR::AEHA_REPEAT;
-                    data.state = Received;
+                    work.state = Received;
                     data.bitcount = 0;
                     work.c1 = -1;
                     work.c2 = -1;
@@ -216,19 +237,19 @@
         default:
             break;
     }
-    IRQ_ENABLE();
+    UNLOCK();
 }
 
 void ReceiverIR::isr_rise(void) {
-    IRQ_DISABLE();
-    switch (data.state) {
+    LOCK();
+    switch (work.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 = RemoteIR::SONY;
-                    data.state = Receiving;
+                    work.state = Receiving;
                     data.bitcount = 0;
                 } else {
                     static const int MINIMUM_LEADER_WIDTH = 150;
@@ -256,7 +277,7 @@
                 data.bitcount++;
 #if 0
                 /*
-                 * How do we get the correct length? (6bits, 12bits, 15bits, 20bits...)
+                 * How do I know the correct length? (6bits, 12bits, 15bits, 20bits...)
                  * By a model only?
                  * Please check a specification of your remote controller if you find a problem.
                  */
@@ -282,18 +303,29 @@
         default:
             break;
     }
-    IRQ_ENABLE();
+    UNLOCK();
 }
 
 void ReceiverIR::isr_timeout(void) {
-    IRQ_DISABLE();
-    if (data.state == Receiving) {
-        data.state = Received;
+    LOCK();
+#if 0
+    printf("# TIMEOUT [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,
+           work.state,
+           data.format,
+           data.bitcount);
+#endif
+    if (work.state == Receiving) {
+        work.state = Received;
         work.c1 = -1;
         work.c2 = -1;
         work.c3 = -1;
         work.d1 = -1;
         work.d2 = -1;
     }
-    IRQ_ENABLE();
+    UNLOCK();
 }