使用普通IO口作为红外发射和红外接收功能

Dependents:   Nucleo_F411RE_OS_Robot_Tank

Committer:
adaphoto
Date:
Tue Jun 19 12:24:24 2018 +0000
Revision:
0:355a854280cd
??????

Who changed what in which revision?

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