RemoteIR.

Dependents:   RemoteIR_TestProgram SerialGPS_TestProgram StarBoardOrangeExpansion1 Door_Slamming_Device ... more

Committer:
shintamainjp
Date:
Tue Aug 17 08:50:54 2010 +0000
Revision:
0:ec264f4ce158
Child:
2:08836610bd4a

        

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