RemoteIR.

Dependents:   RemoteIR_TestProgram SerialGPS_TestProgram StarBoardOrangeExpansion1 Door_Slamming_Device ... more

Committer:
shintamainjp
Date:
Sat Aug 21 04:46:14 2010 +0000
Revision:
3:dfed23b157e6
Parent:
2:08836610bd4a
Child:
9:dcfdac59ef74

        

Who changed what in which revision?

UserRevisionLine numberNew contents of line
shintamainjp 0:ec264f4ce158 1 /**
shintamainjp 0:ec264f4ce158 2 * IR transmitter (Version 0.0.3)
shintamainjp 0:ec264f4ce158 3 *
shintamainjp 0:ec264f4ce158 4 * Copyright (C) 2010 Shinichiro Nakamura (CuBeatSystems)
shintamainjp 0:ec264f4ce158 5 * http://shinta.main.jp/
shintamainjp 0:ec264f4ce158 6 */
shintamainjp 0:ec264f4ce158 7
shintamainjp 0:ec264f4ce158 8 #include "TransmitterIR.h"
shintamainjp 0:ec264f4ce158 9
shintamainjp 0:ec264f4ce158 10 #define IRQ_ENABLE() sem.release(); __enable_irq()
shintamainjp 0:ec264f4ce158 11 #define IRQ_DISABLE() sem.take(); __disable_irq()
shintamainjp 0:ec264f4ce158 12
shintamainjp 0:ec264f4ce158 13 TransmitterIR::TransmitterIR(PinName txpin) : tx(txpin) {
shintamainjp 0:ec264f4ce158 14 tx.write(0.0);
shintamainjp 0:ec264f4ce158 15 tx.period_us(26.3);
shintamainjp 0:ec264f4ce158 16
shintamainjp 0:ec264f4ce158 17 work.state = Idle;
shintamainjp 0:ec264f4ce158 18 work.bitcount = 0;
shintamainjp 0:ec264f4ce158 19 work.leader = 0;
shintamainjp 0:ec264f4ce158 20 work.data = 0;
shintamainjp 0:ec264f4ce158 21 work.trailer = 0;
shintamainjp 0:ec264f4ce158 22
shintamainjp 0:ec264f4ce158 23 data.format = RemoteIR::UNKNOWN;
shintamainjp 0:ec264f4ce158 24 data.bitlength = 0;
shintamainjp 0:ec264f4ce158 25 }
shintamainjp 0:ec264f4ce158 26
shintamainjp 2:08836610bd4a 27 TransmitterIR::~TransmitterIR() {
shintamainjp 2:08836610bd4a 28 }
shintamainjp 2:08836610bd4a 29
shintamainjp 0:ec264f4ce158 30 TransmitterIR::State TransmitterIR::getState(void) {
shintamainjp 0:ec264f4ce158 31 IRQ_DISABLE();
shintamainjp 0:ec264f4ce158 32 State s = work.state;
shintamainjp 0:ec264f4ce158 33 IRQ_ENABLE();
shintamainjp 3:dfed23b157e6 34 wait_ms(10);
shintamainjp 0:ec264f4ce158 35 return s;
shintamainjp 0:ec264f4ce158 36 }
shintamainjp 0:ec264f4ce158 37
shintamainjp 0:ec264f4ce158 38 int TransmitterIR::setData(RemoteIR::Format format, uint8_t *buf, int bitlength) {
shintamainjp 0:ec264f4ce158 39 IRQ_DISABLE();
shintamainjp 0:ec264f4ce158 40 if (work.state != Idle) {
shintamainjp 0:ec264f4ce158 41 IRQ_ENABLE();
shintamainjp 0:ec264f4ce158 42 return -1;
shintamainjp 0:ec264f4ce158 43 }
shintamainjp 0:ec264f4ce158 44
shintamainjp 0:ec264f4ce158 45 work.state = Leader;
shintamainjp 0:ec264f4ce158 46 work.bitcount = 0;
shintamainjp 0:ec264f4ce158 47 work.leader = 0;
shintamainjp 0:ec264f4ce158 48 work.data = 0;
shintamainjp 0:ec264f4ce158 49 work.trailer = 0;
shintamainjp 0:ec264f4ce158 50
shintamainjp 0:ec264f4ce158 51 data.format = format;
shintamainjp 0:ec264f4ce158 52 data.bitlength = bitlength;
shintamainjp 0:ec264f4ce158 53 const int n = bitlength / 8 + (((bitlength % 8) != 0) ? 1 : 0);
shintamainjp 0:ec264f4ce158 54 for (int i = 0; i < n; i++) {
shintamainjp 0:ec264f4ce158 55 data.buffer[i] = buf[i];
shintamainjp 0:ec264f4ce158 56 }
shintamainjp 0:ec264f4ce158 57
shintamainjp 0:ec264f4ce158 58 switch (format) {
shintamainjp 0:ec264f4ce158 59 case RemoteIR::NEC:
shintamainjp 0:ec264f4ce158 60 ticker.detach();
shintamainjp 0:ec264f4ce158 61 ticker.attach_us(this, &TransmitterIR::tick, TUS_NEC);
shintamainjp 0:ec264f4ce158 62 break;
shintamainjp 0:ec264f4ce158 63 case RemoteIR::AEHA:
shintamainjp 0:ec264f4ce158 64 ticker.detach();
shintamainjp 0:ec264f4ce158 65 ticker.attach_us(this, &TransmitterIR::tick, TUS_AEHA);
shintamainjp 0:ec264f4ce158 66 break;
shintamainjp 0:ec264f4ce158 67 case RemoteIR::SONY:
shintamainjp 0:ec264f4ce158 68 ticker.detach();
shintamainjp 0:ec264f4ce158 69 ticker.attach_us(this, &TransmitterIR::tick, TUS_SONY);
shintamainjp 0:ec264f4ce158 70 break;
shintamainjp 0:ec264f4ce158 71 }
shintamainjp 0:ec264f4ce158 72
shintamainjp 0:ec264f4ce158 73 IRQ_ENABLE();
shintamainjp 0:ec264f4ce158 74 return bitlength;
shintamainjp 0:ec264f4ce158 75 }
shintamainjp 0:ec264f4ce158 76
shintamainjp 0:ec264f4ce158 77 void TransmitterIR::tick(void) {
shintamainjp 0:ec264f4ce158 78 IRQ_DISABLE();
shintamainjp 0:ec264f4ce158 79 switch (work.state) {
shintamainjp 0:ec264f4ce158 80 case Idle:
shintamainjp 0:ec264f4ce158 81 work.bitcount = 0;
shintamainjp 0:ec264f4ce158 82 work.leader = 0;
shintamainjp 0:ec264f4ce158 83 work.data = 0;
shintamainjp 0:ec264f4ce158 84 work.trailer = 0;
shintamainjp 0:ec264f4ce158 85 break;
shintamainjp 0:ec264f4ce158 86 case Leader:
shintamainjp 0:ec264f4ce158 87 if (data.format == RemoteIR::NEC) {
shintamainjp 0:ec264f4ce158 88 /*
shintamainjp 0:ec264f4ce158 89 * NEC.
shintamainjp 0:ec264f4ce158 90 */
shintamainjp 0:ec264f4ce158 91 static const int LEADER_NEC_HEAD = 16;
shintamainjp 0:ec264f4ce158 92 static const int LEADER_NEC_TAIL = 8;
shintamainjp 0:ec264f4ce158 93 if (work.leader < LEADER_NEC_HEAD) {
shintamainjp 0:ec264f4ce158 94 tx.write(0.5);
shintamainjp 0:ec264f4ce158 95 } else {
shintamainjp 0:ec264f4ce158 96 tx.write(0.0);
shintamainjp 0:ec264f4ce158 97 }
shintamainjp 0:ec264f4ce158 98 work.leader++;
shintamainjp 0:ec264f4ce158 99 if ((LEADER_NEC_HEAD + LEADER_NEC_TAIL) <= work.leader) {
shintamainjp 0:ec264f4ce158 100 work.state = Data;
shintamainjp 0:ec264f4ce158 101 }
shintamainjp 0:ec264f4ce158 102 } else if (data.format == RemoteIR::AEHA) {
shintamainjp 0:ec264f4ce158 103 /*
shintamainjp 0:ec264f4ce158 104 * AEHA.
shintamainjp 0:ec264f4ce158 105 */
shintamainjp 0:ec264f4ce158 106 static const int LEADER_AEHA_HEAD = 8;
shintamainjp 0:ec264f4ce158 107 static const int LEADER_AEHA_TAIL = 4;
shintamainjp 0:ec264f4ce158 108 if (work.leader < LEADER_AEHA_HEAD) {
shintamainjp 0:ec264f4ce158 109 tx.write(0.5);
shintamainjp 0:ec264f4ce158 110 } else {
shintamainjp 0:ec264f4ce158 111 tx.write(0.0);
shintamainjp 0:ec264f4ce158 112 }
shintamainjp 0:ec264f4ce158 113 work.leader++;
shintamainjp 0:ec264f4ce158 114 if ((LEADER_AEHA_HEAD + LEADER_AEHA_TAIL) <= work.leader) {
shintamainjp 0:ec264f4ce158 115 work.state = Data;
shintamainjp 0:ec264f4ce158 116 }
shintamainjp 0:ec264f4ce158 117 } else if (data.format == RemoteIR::SONY) {
shintamainjp 0:ec264f4ce158 118 /*
shintamainjp 0:ec264f4ce158 119 * SONY.
shintamainjp 0:ec264f4ce158 120 */
shintamainjp 0:ec264f4ce158 121 static const int LEADER_SONY_HEAD = 4;
shintamainjp 0:ec264f4ce158 122 static const int LEADER_SONY_TAIL = 0;
shintamainjp 0:ec264f4ce158 123 if (work.leader < LEADER_SONY_HEAD) {
shintamainjp 0:ec264f4ce158 124 tx.write(0.5);
shintamainjp 0:ec264f4ce158 125 } else {
shintamainjp 0:ec264f4ce158 126 tx.write(0.0);
shintamainjp 0:ec264f4ce158 127 }
shintamainjp 0:ec264f4ce158 128 work.leader++;
shintamainjp 0:ec264f4ce158 129 if ((LEADER_SONY_HEAD + LEADER_SONY_TAIL) <= work.leader) {
shintamainjp 0:ec264f4ce158 130 work.state = Data;
shintamainjp 0:ec264f4ce158 131 }
shintamainjp 0:ec264f4ce158 132 } else {
shintamainjp 0:ec264f4ce158 133 }
shintamainjp 0:ec264f4ce158 134 break;
shintamainjp 0:ec264f4ce158 135 case Data:
shintamainjp 0:ec264f4ce158 136 if (data.format == RemoteIR::NEC) {
shintamainjp 0:ec264f4ce158 137 /*
shintamainjp 0:ec264f4ce158 138 * NEC.
shintamainjp 0:ec264f4ce158 139 */
shintamainjp 0:ec264f4ce158 140 if (work.data == 0) {
shintamainjp 0:ec264f4ce158 141 tx.write(0.5);
shintamainjp 0:ec264f4ce158 142 work.data++;
shintamainjp 0:ec264f4ce158 143 } else {
shintamainjp 0:ec264f4ce158 144 tx.write(0.0);
shintamainjp 0:ec264f4ce158 145 if (0 != (data.buffer[work.bitcount / 8] & (1 << work.bitcount % 8))) {
shintamainjp 0:ec264f4ce158 146 if (3 <= work.data) {
shintamainjp 0:ec264f4ce158 147 work.bitcount++;
shintamainjp 0:ec264f4ce158 148 work.data = 0;
shintamainjp 0:ec264f4ce158 149 } else {
shintamainjp 0:ec264f4ce158 150 work.data++;
shintamainjp 0:ec264f4ce158 151 }
shintamainjp 0:ec264f4ce158 152 } else {
shintamainjp 0:ec264f4ce158 153 if (1 <= work.data) {
shintamainjp 0:ec264f4ce158 154 work.bitcount++;
shintamainjp 0:ec264f4ce158 155 work.data = 0;
shintamainjp 0:ec264f4ce158 156 } else {
shintamainjp 0:ec264f4ce158 157 work.data++;
shintamainjp 0:ec264f4ce158 158 }
shintamainjp 0:ec264f4ce158 159 }
shintamainjp 0:ec264f4ce158 160 }
shintamainjp 0:ec264f4ce158 161 if (data.bitlength <= work.bitcount) {
shintamainjp 0:ec264f4ce158 162 work.state = Trailer;
shintamainjp 0:ec264f4ce158 163 }
shintamainjp 0:ec264f4ce158 164 } else if (data.format == RemoteIR::AEHA) {
shintamainjp 0:ec264f4ce158 165 /*
shintamainjp 0:ec264f4ce158 166 * AEHA.
shintamainjp 0:ec264f4ce158 167 */
shintamainjp 0:ec264f4ce158 168 if (work.data == 0) {
shintamainjp 0:ec264f4ce158 169 tx.write(0.5);
shintamainjp 0:ec264f4ce158 170 work.data++;
shintamainjp 0:ec264f4ce158 171 } else {
shintamainjp 0:ec264f4ce158 172 tx.write(0.0);
shintamainjp 0:ec264f4ce158 173 if (0 != (data.buffer[work.bitcount / 8] & (1 << work.bitcount % 8))) {
shintamainjp 0:ec264f4ce158 174 if (3 <= work.data) {
shintamainjp 0:ec264f4ce158 175 work.bitcount++;
shintamainjp 0:ec264f4ce158 176 work.data = 0;
shintamainjp 0:ec264f4ce158 177 } else {
shintamainjp 0:ec264f4ce158 178 work.data++;
shintamainjp 0:ec264f4ce158 179 }
shintamainjp 0:ec264f4ce158 180 } else {
shintamainjp 0:ec264f4ce158 181 if (1 <= work.data) {
shintamainjp 0:ec264f4ce158 182 work.bitcount++;
shintamainjp 0:ec264f4ce158 183 work.data = 0;
shintamainjp 0:ec264f4ce158 184 } else {
shintamainjp 0:ec264f4ce158 185 work.data++;
shintamainjp 0:ec264f4ce158 186 }
shintamainjp 0:ec264f4ce158 187 }
shintamainjp 0:ec264f4ce158 188 }
shintamainjp 0:ec264f4ce158 189 if (data.bitlength <= work.bitcount) {
shintamainjp 0:ec264f4ce158 190 work.state = Trailer;
shintamainjp 0:ec264f4ce158 191 }
shintamainjp 0:ec264f4ce158 192 } else if (data.format == RemoteIR::SONY) {
shintamainjp 0:ec264f4ce158 193 /*
shintamainjp 0:ec264f4ce158 194 * SONY.
shintamainjp 0:ec264f4ce158 195 */
shintamainjp 0:ec264f4ce158 196 if (work.data == 0) {
shintamainjp 0:ec264f4ce158 197 tx.write(0.0);
shintamainjp 0:ec264f4ce158 198 work.data++;
shintamainjp 0:ec264f4ce158 199 } else {
shintamainjp 0:ec264f4ce158 200 tx.write(0.5);
shintamainjp 0:ec264f4ce158 201 if (0 != (data.buffer[work.bitcount / 8] & (1 << work.bitcount % 8))) {
shintamainjp 0:ec264f4ce158 202 if (2 <= work.data) {
shintamainjp 0:ec264f4ce158 203 work.bitcount++;
shintamainjp 0:ec264f4ce158 204 work.data = 0;
shintamainjp 0:ec264f4ce158 205 } else {
shintamainjp 0:ec264f4ce158 206 work.data++;
shintamainjp 0:ec264f4ce158 207 }
shintamainjp 0:ec264f4ce158 208 } else {
shintamainjp 0:ec264f4ce158 209 if (1 <= work.data) {
shintamainjp 0:ec264f4ce158 210 work.bitcount++;
shintamainjp 0:ec264f4ce158 211 work.data = 0;
shintamainjp 0:ec264f4ce158 212 } else {
shintamainjp 0:ec264f4ce158 213 work.data++;
shintamainjp 0:ec264f4ce158 214 }
shintamainjp 0:ec264f4ce158 215 }
shintamainjp 0:ec264f4ce158 216 }
shintamainjp 0:ec264f4ce158 217 if (data.bitlength <= work.bitcount) {
shintamainjp 0:ec264f4ce158 218 work.state = Trailer;
shintamainjp 0:ec264f4ce158 219 }
shintamainjp 0:ec264f4ce158 220 } else {
shintamainjp 0:ec264f4ce158 221 }
shintamainjp 0:ec264f4ce158 222 break;
shintamainjp 0:ec264f4ce158 223 case Trailer:
shintamainjp 0:ec264f4ce158 224 if (data.format == RemoteIR::NEC) {
shintamainjp 0:ec264f4ce158 225 /*
shintamainjp 0:ec264f4ce158 226 * NEC.
shintamainjp 0:ec264f4ce158 227 */
shintamainjp 0:ec264f4ce158 228 static const int TRAILER_NEC_HEAD = 1;
shintamainjp 0:ec264f4ce158 229 static const int TRAILER_NEC_TAIL = 2;
shintamainjp 0:ec264f4ce158 230 if (work.trailer < TRAILER_NEC_HEAD) {
shintamainjp 0:ec264f4ce158 231 tx.write(0.5);
shintamainjp 0:ec264f4ce158 232 } else {
shintamainjp 0:ec264f4ce158 233 tx.write(0.0);
shintamainjp 0:ec264f4ce158 234 }
shintamainjp 0:ec264f4ce158 235 work.trailer++;
shintamainjp 0:ec264f4ce158 236 if ((TRAILER_NEC_HEAD + TRAILER_NEC_TAIL) <= work.trailer) {
shintamainjp 0:ec264f4ce158 237 work.state = Idle;
shintamainjp 0:ec264f4ce158 238 //ticker.detach();
shintamainjp 0:ec264f4ce158 239 }
shintamainjp 0:ec264f4ce158 240 } else if (data.format == RemoteIR::AEHA) {
shintamainjp 0:ec264f4ce158 241 /*
shintamainjp 0:ec264f4ce158 242 * AEHA.
shintamainjp 0:ec264f4ce158 243 */
shintamainjp 0:ec264f4ce158 244 static const int TRAILER_AEHA_HEAD = 1;
shintamainjp 0:ec264f4ce158 245 static const int TRAILER_AEHA_TAIL = 8000 / TUS_AEHA;
shintamainjp 0:ec264f4ce158 246 if (work.trailer < TRAILER_AEHA_HEAD) {
shintamainjp 0:ec264f4ce158 247 tx.write(0.5);
shintamainjp 0:ec264f4ce158 248 } else {
shintamainjp 0:ec264f4ce158 249 tx.write(0.0);
shintamainjp 0:ec264f4ce158 250 }
shintamainjp 0:ec264f4ce158 251 work.trailer++;
shintamainjp 0:ec264f4ce158 252 if ((TRAILER_AEHA_HEAD + TRAILER_AEHA_TAIL) <= work.trailer) {
shintamainjp 0:ec264f4ce158 253 work.state = Idle;
shintamainjp 0:ec264f4ce158 254 //ticker.detach();
shintamainjp 0:ec264f4ce158 255 }
shintamainjp 0:ec264f4ce158 256 } else if (data.format == RemoteIR::SONY) {
shintamainjp 0:ec264f4ce158 257 /*
shintamainjp 0:ec264f4ce158 258 * SONY.
shintamainjp 0:ec264f4ce158 259 */
shintamainjp 0:ec264f4ce158 260 static const int TRAILER_SONY_HEAD = 0;
shintamainjp 0:ec264f4ce158 261 static const int TRAILER_SONY_TAIL = 0;
shintamainjp 0:ec264f4ce158 262 if (work.trailer < TRAILER_SONY_HEAD) {
shintamainjp 0:ec264f4ce158 263 tx.write(0.5);
shintamainjp 0:ec264f4ce158 264 } else {
shintamainjp 0:ec264f4ce158 265 tx.write(0.0);
shintamainjp 0:ec264f4ce158 266 }
shintamainjp 0:ec264f4ce158 267 work.trailer++;
shintamainjp 0:ec264f4ce158 268 if ((TRAILER_SONY_HEAD + TRAILER_SONY_TAIL) <= work.trailer) {
shintamainjp 0:ec264f4ce158 269 work.state = Idle;
shintamainjp 0:ec264f4ce158 270 //ticker.detach();
shintamainjp 0:ec264f4ce158 271 }
shintamainjp 0:ec264f4ce158 272 } else {
shintamainjp 0:ec264f4ce158 273 }
shintamainjp 0:ec264f4ce158 274 break;
shintamainjp 0:ec264f4ce158 275 default:
shintamainjp 0:ec264f4ce158 276 break;
shintamainjp 0:ec264f4ce158 277 }
shintamainjp 0:ec264f4ce158 278 IRQ_ENABLE();
shintamainjp 0:ec264f4ce158 279 }