Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Diff: ReceiverIR.cpp
- Revision:
- 9:dcfdac59ef74
- Parent:
- 7:9452ba065449
- Child:
- 10:c54fb1204d1e
--- 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();
}