RemoteIR.

Dependents:   RemoteIR_TestProgram SerialGPS_TestProgram StarBoardOrangeExpansion1 Door_Slamming_Device ... more

Committer:
shintamainjp
Date:
Mon Sep 20 00:54:59 2010 +0000
Revision:
11:268cc2ab63bd
Parent:
10:c54fb1204d1e

        

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