RoemoteIR

Committer:
shintamainjp
Date:
Fri Sep 17 21:44:01 2010 +0000
Revision:
10:c54fb1204d1e
Parent:
9:dcfdac59ef74
Child:
11:268cc2ab63bd

        

Who changed what in which revision?

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