StarBoard Orange - Example application No.2 (Version 0.0.4)

Dependencies:   mbed

Committer:
shintamainjp
Date:
Sun Aug 15 00:27:30 2010 +0000
Revision:
1:9370008ac96b
Parent:
0:5d79cd4ac81d
Child:
2:d4625043c895

        

Who changed what in which revision?

UserRevisionLine numberNew contents of line
shintamainjp 0:5d79cd4ac81d 1 /**
shintamainjp 1:9370008ac96b 2 * IR receiver (Version 0.0.2)
shintamainjp 0:5d79cd4ac81d 3 *
shintamainjp 0:5d79cd4ac81d 4 * Copyright (C) 2010 Shinichiro Nakamura (CuBeatSystems)
shintamainjp 0:5d79cd4ac81d 5 * http://shinta.main.jp/
shintamainjp 0:5d79cd4ac81d 6 */
shintamainjp 0:5d79cd4ac81d 7
shintamainjp 0:5d79cd4ac81d 8 #include "ReceiverIR.h"
shintamainjp 0:5d79cd4ac81d 9
shintamainjp 0:5d79cd4ac81d 10 #define InRange(x,y) ((((y) * 0.7) < (x)) && ((x) < ((y) * 1.3)))
shintamainjp 0:5d79cd4ac81d 11 #define IRQ_ENABLE() sem.release(); __enable_irq()
shintamainjp 0:5d79cd4ac81d 12 #define IRQ_DISABLE() __disable_irq(); sem.take()
shintamainjp 0:5d79cd4ac81d 13
shintamainjp 0:5d79cd4ac81d 14 ReceiverIR::ReceiverIR(PinName rx) : evt(rx) {
shintamainjp 0:5d79cd4ac81d 15 IRQ_DISABLE();
shintamainjp 0:5d79cd4ac81d 16 evt.fall(this, &ReceiverIR::isr_fall);
shintamainjp 0:5d79cd4ac81d 17 evt.rise(this, &ReceiverIR::isr_rise);
shintamainjp 0:5d79cd4ac81d 18 ticker.attach_us(this, &ReceiverIR::isr_wdt, 1 * 1000);
shintamainjp 0:5d79cd4ac81d 19 init_state();
shintamainjp 0:5d79cd4ac81d 20 IRQ_ENABLE();
shintamainjp 0:5d79cd4ac81d 21 }
shintamainjp 0:5d79cd4ac81d 22
shintamainjp 0:5d79cd4ac81d 23 ReceiverIR::~ReceiverIR() {}
shintamainjp 0:5d79cd4ac81d 24
shintamainjp 0:5d79cd4ac81d 25 ReceiverIR::State ReceiverIR::getState() {
shintamainjp 0:5d79cd4ac81d 26 IRQ_DISABLE();
shintamainjp 0:5d79cd4ac81d 27 State s = data.state;
shintamainjp 0:5d79cd4ac81d 28 IRQ_ENABLE();
shintamainjp 0:5d79cd4ac81d 29 return s;
shintamainjp 0:5d79cd4ac81d 30 }
shintamainjp 0:5d79cd4ac81d 31
shintamainjp 0:5d79cd4ac81d 32 int ReceiverIR::getData(ReceiverIR::Format *format, uint8_t *buf, int bufsiz) {
shintamainjp 0:5d79cd4ac81d 33 IRQ_DISABLE();
shintamainjp 0:5d79cd4ac81d 34
shintamainjp 0:5d79cd4ac81d 35 const int bc = data.bitcount;
shintamainjp 0:5d79cd4ac81d 36 if (bufsiz < (bc / 8)) {
shintamainjp 0:5d79cd4ac81d 37 IRQ_ENABLE();
shintamainjp 0:5d79cd4ac81d 38 return -1;
shintamainjp 0:5d79cd4ac81d 39 }
shintamainjp 0:5d79cd4ac81d 40
shintamainjp 0:5d79cd4ac81d 41 *format = data.format;
shintamainjp 0:5d79cd4ac81d 42 for (int i = 0; i < (bc / 8); i++) {
shintamainjp 0:5d79cd4ac81d 43 buf[i] = data.buffer[i];
shintamainjp 0:5d79cd4ac81d 44 }
shintamainjp 0:5d79cd4ac81d 45
shintamainjp 0:5d79cd4ac81d 46 init_state();
shintamainjp 0:5d79cd4ac81d 47
shintamainjp 0:5d79cd4ac81d 48 IRQ_ENABLE();
shintamainjp 0:5d79cd4ac81d 49 return bc;
shintamainjp 0:5d79cd4ac81d 50 }
shintamainjp 0:5d79cd4ac81d 51
shintamainjp 0:5d79cd4ac81d 52 void ReceiverIR::init_state(void) {
shintamainjp 0:5d79cd4ac81d 53 work.c1 = -1;
shintamainjp 0:5d79cd4ac81d 54 work.c2 = -1;
shintamainjp 0:5d79cd4ac81d 55 work.c3 = -1;
shintamainjp 0:5d79cd4ac81d 56 work.d1 = -1;
shintamainjp 0:5d79cd4ac81d 57 work.d2 = -1;
shintamainjp 0:5d79cd4ac81d 58 data.state = Idle;
shintamainjp 0:5d79cd4ac81d 59 data.format = UNKNOWN;
shintamainjp 0:5d79cd4ac81d 60 data.bitcount = 0;
shintamainjp 0:5d79cd4ac81d 61 timer.stop();
shintamainjp 0:5d79cd4ac81d 62 timer.reset();
shintamainjp 0:5d79cd4ac81d 63 for (int i = 0; i < sizeof(data.buffer); i++) {
shintamainjp 0:5d79cd4ac81d 64 data.buffer[i] = 0;
shintamainjp 0:5d79cd4ac81d 65 }
shintamainjp 0:5d79cd4ac81d 66 }
shintamainjp 0:5d79cd4ac81d 67
shintamainjp 0:5d79cd4ac81d 68 void ReceiverIR::isr_wdt(void) {
shintamainjp 0:5d79cd4ac81d 69 IRQ_DISABLE();
shintamainjp 0:5d79cd4ac81d 70 static int cnt = 0;
shintamainjp 0:5d79cd4ac81d 71 if ((Receiving == data.state) || ((0 <= work.c1) || (0 <= work.c2) || (0 <= work.c3))) {
shintamainjp 0:5d79cd4ac81d 72 cnt++;
shintamainjp 0:5d79cd4ac81d 73 if (cnt > 500) {
shintamainjp 0:5d79cd4ac81d 74 printf("# WDT [c1=%d, c2=%d, c3=%d, d1=%d, d2=%d, state=%d, format=%d, bitcount=%d]\n",
shintamainjp 0:5d79cd4ac81d 75 work.c1,
shintamainjp 0:5d79cd4ac81d 76 work.c2,
shintamainjp 0:5d79cd4ac81d 77 work.c3,
shintamainjp 0:5d79cd4ac81d 78 work.d1,
shintamainjp 0:5d79cd4ac81d 79 work.d2,
shintamainjp 0:5d79cd4ac81d 80 data.state,
shintamainjp 0:5d79cd4ac81d 81 data.format,
shintamainjp 0:5d79cd4ac81d 82 data.bitcount);
shintamainjp 0:5d79cd4ac81d 83 init_state();
shintamainjp 0:5d79cd4ac81d 84 cnt = 0;
shintamainjp 0:5d79cd4ac81d 85 }
shintamainjp 0:5d79cd4ac81d 86 } else {
shintamainjp 0:5d79cd4ac81d 87 cnt = 0;
shintamainjp 0:5d79cd4ac81d 88 }
shintamainjp 0:5d79cd4ac81d 89 IRQ_ENABLE();
shintamainjp 0:5d79cd4ac81d 90 }
shintamainjp 0:5d79cd4ac81d 91
shintamainjp 0:5d79cd4ac81d 92 void ReceiverIR::isr_fall(void) {
shintamainjp 0:5d79cd4ac81d 93 IRQ_DISABLE();
shintamainjp 0:5d79cd4ac81d 94 switch (data.state) {
shintamainjp 0:5d79cd4ac81d 95 case Idle:
shintamainjp 0:5d79cd4ac81d 96 if (work.c1 < 0) {
shintamainjp 0:5d79cd4ac81d 97 timer.start();
shintamainjp 0:5d79cd4ac81d 98 work.c1 = timer.read_us();
shintamainjp 0:5d79cd4ac81d 99 } else {
shintamainjp 0:5d79cd4ac81d 100 work.c3 = timer.read_us();
shintamainjp 0:5d79cd4ac81d 101 int a = work.c2 - work.c1;
shintamainjp 0:5d79cd4ac81d 102 int b = work.c3 - work.c2;
shintamainjp 0:5d79cd4ac81d 103 if (InRange(a, TUS_NEC * 16) && InRange(b, TUS_NEC * 8)) {
shintamainjp 0:5d79cd4ac81d 104 /*
shintamainjp 0:5d79cd4ac81d 105 * NEC.
shintamainjp 0:5d79cd4ac81d 106 */
shintamainjp 0:5d79cd4ac81d 107 data.format = NEC;
shintamainjp 0:5d79cd4ac81d 108 data.state = Receiving;
shintamainjp 0:5d79cd4ac81d 109 data.bitcount = 0;
shintamainjp 0:5d79cd4ac81d 110 } else if (InRange(a, TUS_NEC * 16) && InRange(b, TUS_NEC * 4)) {
shintamainjp 0:5d79cd4ac81d 111 /*
shintamainjp 0:5d79cd4ac81d 112 * NEC Repeat.
shintamainjp 0:5d79cd4ac81d 113 */
shintamainjp 0:5d79cd4ac81d 114 data.format = NEC;
shintamainjp 0:5d79cd4ac81d 115 data.state = Received;
shintamainjp 0:5d79cd4ac81d 116 data.bitcount = 0;
shintamainjp 0:5d79cd4ac81d 117 } else if (InRange(a, TUS_AEHA * 8) && InRange(b, TUS_AEHA * 4)) {
shintamainjp 0:5d79cd4ac81d 118 /*
shintamainjp 0:5d79cd4ac81d 119 * AEHA.
shintamainjp 0:5d79cd4ac81d 120 */
shintamainjp 0:5d79cd4ac81d 121 data.format = AEHA;
shintamainjp 0:5d79cd4ac81d 122 data.state = Receiving;
shintamainjp 0:5d79cd4ac81d 123 data.bitcount = 0;
shintamainjp 0:5d79cd4ac81d 124 } else if (InRange(a, TUS_AEHA * 8) && InRange(b, TUS_AEHA * 8)) {
shintamainjp 0:5d79cd4ac81d 125 /*
shintamainjp 0:5d79cd4ac81d 126 * AEHA Repeat.
shintamainjp 0:5d79cd4ac81d 127 */
shintamainjp 0:5d79cd4ac81d 128 data.format = AEHA;
shintamainjp 0:5d79cd4ac81d 129 data.state = Received;
shintamainjp 0:5d79cd4ac81d 130 data.bitcount = 0;
shintamainjp 0:5d79cd4ac81d 131 } else {
shintamainjp 0:5d79cd4ac81d 132 init_state();
shintamainjp 0:5d79cd4ac81d 133 }
shintamainjp 0:5d79cd4ac81d 134 }
shintamainjp 0:5d79cd4ac81d 135 break;
shintamainjp 0:5d79cd4ac81d 136 case Receiving:
shintamainjp 0:5d79cd4ac81d 137 if (NEC == data.format) {
shintamainjp 0:5d79cd4ac81d 138 work.d2 = timer.read_us();
shintamainjp 0:5d79cd4ac81d 139 int a = work.d2 - work.d1;
shintamainjp 0:5d79cd4ac81d 140 if (InRange(a, TUS_NEC * 3)) {
shintamainjp 0:5d79cd4ac81d 141 data.buffer[data.bitcount / 8] |= (1 << (data.bitcount % 8));
shintamainjp 0:5d79cd4ac81d 142 } else if (InRange(a, TUS_NEC * 1)) {
shintamainjp 0:5d79cd4ac81d 143 data.buffer[data.bitcount / 8] &= ~(1 << (data.bitcount % 8));
shintamainjp 0:5d79cd4ac81d 144 }
shintamainjp 0:5d79cd4ac81d 145 data.bitcount++;
shintamainjp 0:5d79cd4ac81d 146 if (32 <= data.bitcount) {
shintamainjp 0:5d79cd4ac81d 147 data.state = Received;
shintamainjp 0:5d79cd4ac81d 148 }
shintamainjp 0:5d79cd4ac81d 149 } else if (AEHA == data.format) {
shintamainjp 0:5d79cd4ac81d 150 work.d2 = timer.read_us();
shintamainjp 0:5d79cd4ac81d 151 int a = work.d2 - work.d1;
shintamainjp 0:5d79cd4ac81d 152 if (InRange(a, TUS_AEHA * 3)) {
shintamainjp 0:5d79cd4ac81d 153 data.buffer[data.bitcount / 8] |= (1 << (data.bitcount % 8));
shintamainjp 0:5d79cd4ac81d 154 } else if (InRange(a, TUS_AEHA * 1)) {
shintamainjp 0:5d79cd4ac81d 155 data.buffer[data.bitcount / 8] &= ~(1 << (data.bitcount % 8));
shintamainjp 0:5d79cd4ac81d 156 }
shintamainjp 0:5d79cd4ac81d 157 data.bitcount++;
shintamainjp 0:5d79cd4ac81d 158 /*
shintamainjp 0:5d79cd4ac81d 159 * Typical length of AEHA is 48 bits.
shintamainjp 0:5d79cd4ac81d 160 * Please check a specification of your remote controller if you find a problem.
shintamainjp 1:9370008ac96b 161 */
shintamainjp 0:5d79cd4ac81d 162 if (48 <= data.bitcount) {
shintamainjp 0:5d79cd4ac81d 163 data.state = Received;
shintamainjp 1:9370008ac96b 164 work.c1 = -1;
shintamainjp 1:9370008ac96b 165 work.c2 = -1;
shintamainjp 1:9370008ac96b 166 work.c3 = -1;
shintamainjp 1:9370008ac96b 167 work.d1 = -1;
shintamainjp 1:9370008ac96b 168 work.d2 = -1;
shintamainjp 0:5d79cd4ac81d 169 }
shintamainjp 0:5d79cd4ac81d 170 } else if (SONY == data.format) {
shintamainjp 0:5d79cd4ac81d 171 work.d1 = timer.read_us();
shintamainjp 0:5d79cd4ac81d 172 }
shintamainjp 0:5d79cd4ac81d 173 break;
shintamainjp 0:5d79cd4ac81d 174 case Received:
shintamainjp 0:5d79cd4ac81d 175 break;
shintamainjp 0:5d79cd4ac81d 176 default:
shintamainjp 0:5d79cd4ac81d 177 break;
shintamainjp 0:5d79cd4ac81d 178 }
shintamainjp 0:5d79cd4ac81d 179 IRQ_ENABLE();
shintamainjp 0:5d79cd4ac81d 180 }
shintamainjp 0:5d79cd4ac81d 181
shintamainjp 0:5d79cd4ac81d 182 void ReceiverIR::isr_rise(void) {
shintamainjp 0:5d79cd4ac81d 183 IRQ_DISABLE();
shintamainjp 0:5d79cd4ac81d 184 switch (data.state) {
shintamainjp 0:5d79cd4ac81d 185 case Idle:
shintamainjp 0:5d79cd4ac81d 186 if (0 <= work.c1) {
shintamainjp 0:5d79cd4ac81d 187 work.c2 = timer.read_us();
shintamainjp 0:5d79cd4ac81d 188 int a = work.c2 - work.c1;
shintamainjp 0:5d79cd4ac81d 189 if (InRange(a, TUS_SONY * 4)) {
shintamainjp 0:5d79cd4ac81d 190 data.format = SONY;
shintamainjp 0:5d79cd4ac81d 191 data.state = Receiving;
shintamainjp 0:5d79cd4ac81d 192 data.bitcount = 0;
shintamainjp 0:5d79cd4ac81d 193 } else {
shintamainjp 0:5d79cd4ac81d 194 static const int MINIMUM_LEADER_WIDTH = 150;
shintamainjp 0:5d79cd4ac81d 195 if (a < MINIMUM_LEADER_WIDTH) {
shintamainjp 0:5d79cd4ac81d 196 init_state();
shintamainjp 0:5d79cd4ac81d 197 }
shintamainjp 0:5d79cd4ac81d 198 }
shintamainjp 0:5d79cd4ac81d 199 } else {
shintamainjp 0:5d79cd4ac81d 200 init_state();
shintamainjp 0:5d79cd4ac81d 201 }
shintamainjp 0:5d79cd4ac81d 202 break;
shintamainjp 0:5d79cd4ac81d 203 case Receiving:
shintamainjp 0:5d79cd4ac81d 204 if (NEC == data.format) {
shintamainjp 0:5d79cd4ac81d 205 work.d1 = timer.read_us();
shintamainjp 0:5d79cd4ac81d 206 } else if (AEHA == data.format) {
shintamainjp 0:5d79cd4ac81d 207 work.d1 = timer.read_us();
shintamainjp 0:5d79cd4ac81d 208 } else if (SONY == data.format) {
shintamainjp 0:5d79cd4ac81d 209 work.d2 = timer.read_us();
shintamainjp 0:5d79cd4ac81d 210 int a = work.d2 - work.d1;
shintamainjp 0:5d79cd4ac81d 211 if (InRange(a, TUS_SONY * 2)) {
shintamainjp 0:5d79cd4ac81d 212 data.buffer[data.bitcount / 8] |= (1 << (data.bitcount % 8));
shintamainjp 0:5d79cd4ac81d 213 } else if (InRange(a, TUS_SONY * 1)) {
shintamainjp 0:5d79cd4ac81d 214 data.buffer[data.bitcount / 8] &= ~(1 << (data.bitcount % 8));
shintamainjp 0:5d79cd4ac81d 215 }
shintamainjp 0:5d79cd4ac81d 216 data.bitcount++;
shintamainjp 0:5d79cd4ac81d 217 /*
shintamainjp 1:9370008ac96b 218 * How do we get the correct length? (12bits, 15bits, 20bits...)
shintamainjp 0:5d79cd4ac81d 219 * By a model only?
shintamainjp 0:5d79cd4ac81d 220 * Please check a specification of your remote controller if you find a problem.
shintamainjp 0:5d79cd4ac81d 221 */
shintamainjp 0:5d79cd4ac81d 222 if (12 <= data.bitcount) {
shintamainjp 0:5d79cd4ac81d 223 data.state = Received;
shintamainjp 1:9370008ac96b 224 work.c1 = -1;
shintamainjp 1:9370008ac96b 225 work.c2 = -1;
shintamainjp 1:9370008ac96b 226 work.c3 = -1;
shintamainjp 1:9370008ac96b 227 work.d1 = -1;
shintamainjp 1:9370008ac96b 228 work.d2 = -1;
shintamainjp 0:5d79cd4ac81d 229 }
shintamainjp 0:5d79cd4ac81d 230 }
shintamainjp 0:5d79cd4ac81d 231 break;
shintamainjp 0:5d79cd4ac81d 232 case Received:
shintamainjp 0:5d79cd4ac81d 233 break;
shintamainjp 0:5d79cd4ac81d 234 default:
shintamainjp 0:5d79cd4ac81d 235 break;
shintamainjp 0:5d79cd4ac81d 236 }
shintamainjp 0:5d79cd4ac81d 237 IRQ_ENABLE();
shintamainjp 0:5d79cd4ac81d 238 }