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

Dependents:   Nucleo_F411RE_OS_Robot_Tank

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers TransmitterIR.cpp Source File

TransmitterIR.cpp

00001 /**
00002  * IR transmitter (Version 0.0.4)
00003  *
00004  * Copyright (C) 2010 Shinichiro Nakamura (CuBeatSystems)
00005  * http://shinta.main.jp/
00006  */
00007 
00008 #include "TransmitterIR.h"
00009 
00010 #define LOCK()
00011 #define UNLOCK()
00012 
00013 /**
00014  * Constructor.
00015  *
00016  * @param txpin Pin for transmit IR signal.
00017  */
00018 TransmitterIR::TransmitterIR(PinName txpin) : tx(txpin) {
00019     tx.write(0.0);
00020     tx.period_us(26.3);
00021 
00022     work.state = Idle;
00023     work.bitcount = 0;
00024     work.leader = 0;
00025     work.data = 0;
00026     work.trailer = 0;
00027 
00028     data.format = RemoteIR::UNKNOWN;
00029     data.bitlength = 0;
00030 }
00031 
00032 /**
00033  * Destructor.
00034  */
00035 TransmitterIR::~TransmitterIR() {
00036 }
00037 
00038 /**
00039  * Get state.
00040  *
00041  * @return Current state.
00042  */
00043 TransmitterIR::State TransmitterIR::getState(void) {
00044     LOCK();
00045     State s = work.state;
00046     UNLOCK();
00047     return s;
00048 }
00049 
00050 /**
00051  * Set data.
00052  *
00053  * @param format Format.
00054  * @param buf Buffer of a data.
00055  * @param bitlength Bit length of the data.
00056  *
00057  * @return Data bit length.
00058  */
00059 int TransmitterIR::setData(RemoteIR::Format format, uint8_t *buf, int bitlength) {
00060     LOCK();
00061     if (work.state != Idle) {
00062         UNLOCK();
00063         return -1;
00064     }
00065 
00066     work.state = Leader;
00067     work.bitcount = 0;
00068     work.leader = 0;
00069     work.data = 0;
00070     work.trailer = 0;
00071 
00072     data.format = format;
00073     data.bitlength = bitlength;
00074     const int n = bitlength / 8 + (((bitlength % 8) != 0) ? 1 : 0);
00075     for (int i = 0; i < n; i++) {
00076         data.buffer[i] = buf[i];
00077     }
00078 
00079     switch (format) {
00080         case RemoteIR::NEC:
00081             ticker.detach();
00082             ticker.attach_us(this, &TransmitterIR::tick, RemoteIR::TUS_NEC);
00083             break;
00084         case RemoteIR::AEHA:
00085             ticker.detach();
00086             ticker.attach_us(this, &TransmitterIR::tick, RemoteIR::TUS_AEHA);
00087             break;
00088         case RemoteIR::SONY:
00089             ticker.detach();
00090             ticker.attach_us(this, &TransmitterIR::tick, RemoteIR::TUS_SONY);
00091             break;
00092     }
00093 
00094     UNLOCK();
00095     return bitlength;
00096 }
00097 
00098 void TransmitterIR::tick(void) {
00099     LOCK();
00100     switch (work.state) {
00101         case Idle:
00102             work.bitcount = 0;
00103             work.leader = 0;
00104             work.data = 0;
00105             work.trailer = 0;
00106             break;
00107         case Leader:
00108             if (data.format == RemoteIR::NEC) {
00109                 /*
00110                  * NEC.
00111                  */
00112                 static const int LEADER_NEC_HEAD = 16;
00113                 static const int LEADER_NEC_TAIL = 8;
00114                 if (work.leader < LEADER_NEC_HEAD) {
00115                     tx.write(0.5);
00116                 } else {
00117                     tx.write(0.0);
00118                 }
00119                 work.leader++;
00120                 if ((LEADER_NEC_HEAD + LEADER_NEC_TAIL) <= work.leader) {
00121                     work.state = Data;
00122                 }
00123             } else if (data.format == RemoteIR::AEHA) {
00124                 /*
00125                  * AEHA.
00126                  */
00127                 static const int LEADER_AEHA_HEAD = 8;
00128                 static const int LEADER_AEHA_TAIL = 4;
00129                 if (work.leader < LEADER_AEHA_HEAD) {
00130                     tx.write(0.5);
00131                 } else {
00132                     tx.write(0.0);
00133                 }
00134                 work.leader++;
00135                 if ((LEADER_AEHA_HEAD + LEADER_AEHA_TAIL) <= work.leader) {
00136                     work.state = Data;
00137                 }
00138             } else if (data.format == RemoteIR::SONY) {
00139                 /*
00140                  * SONY.
00141                  */
00142                 static const int LEADER_SONY_HEAD = 4;
00143                 static const int LEADER_SONY_TAIL = 0;
00144                 if (work.leader < LEADER_SONY_HEAD) {
00145                     tx.write(0.5);
00146                 } else {
00147                     tx.write(0.0);
00148                 }
00149                 work.leader++;
00150                 if ((LEADER_SONY_HEAD + LEADER_SONY_TAIL) <= work.leader) {
00151                     work.state = Data;
00152                 }
00153             } else {
00154             }
00155             break;
00156         case Data:
00157             if (data.format == RemoteIR::NEC) {
00158                 /*
00159                  * NEC.
00160                  */
00161                 if (work.data == 0) {
00162                     tx.write(0.5);
00163                     work.data++;
00164                 } else {
00165                     tx.write(0.0);
00166                     if (0 != (data.buffer[work.bitcount / 8] & (1 << work.bitcount % 8))) {
00167                         if (3 <= work.data) {
00168                             work.bitcount++;
00169                             work.data = 0;
00170                         } else {
00171                             work.data++;
00172                         }
00173                     } else {
00174                         if (1 <= work.data) {
00175                             work.bitcount++;
00176                             work.data = 0;
00177                         } else {
00178                             work.data++;
00179                         }
00180                     }
00181                 }
00182                 if (data.bitlength <= work.bitcount) {
00183                     work.state = Trailer;
00184                 }
00185             } else if (data.format == RemoteIR::AEHA) {
00186                 /*
00187                  * AEHA.
00188                  */
00189                 if (work.data == 0) {
00190                     tx.write(0.5);
00191                     work.data++;
00192                 } else {
00193                     tx.write(0.0);
00194                     if (0 != (data.buffer[work.bitcount / 8] & (1 << work.bitcount % 8))) {
00195                         if (3 <= work.data) {
00196                             work.bitcount++;
00197                             work.data = 0;
00198                         } else {
00199                             work.data++;
00200                         }
00201                     } else {
00202                         if (1 <= work.data) {
00203                             work.bitcount++;
00204                             work.data = 0;
00205                         } else {
00206                             work.data++;
00207                         }
00208                     }
00209                 }
00210                 if (data.bitlength <= work.bitcount) {
00211                     work.state = Trailer;
00212                 }
00213             } else if (data.format == RemoteIR::SONY) {
00214                 /*
00215                  * SONY.
00216                  */
00217                 if (work.data == 0) {
00218                     tx.write(0.0);
00219                     work.data++;
00220                 } else {
00221                     tx.write(0.5);
00222                     if (0 != (data.buffer[work.bitcount / 8] & (1 << work.bitcount % 8))) {
00223                         if (2 <= work.data) {
00224                             work.bitcount++;
00225                             work.data = 0;
00226                         } else {
00227                             work.data++;
00228                         }
00229                     } else {
00230                         if (1 <= work.data) {
00231                             work.bitcount++;
00232                             work.data = 0;
00233                         } else {
00234                             work.data++;
00235                         }
00236                     }
00237                 }
00238                 if (data.bitlength <= work.bitcount) {
00239                     work.state = Trailer;
00240                 }
00241             } else {
00242             }
00243             break;
00244         case Trailer:
00245             if (data.format == RemoteIR::NEC) {
00246                 /*
00247                  * NEC.
00248                  */
00249                 static const int TRAILER_NEC_HEAD = 1;
00250                 static const int TRAILER_NEC_TAIL = 2;
00251                 if (work.trailer < TRAILER_NEC_HEAD) {
00252                     tx.write(0.5);
00253                 } else {
00254                     tx.write(0.0);
00255                 }
00256                 work.trailer++;
00257                 if ((TRAILER_NEC_HEAD + TRAILER_NEC_TAIL) <= work.trailer) {
00258                     work.state = Idle;
00259                     //ticker.detach();
00260                 }
00261             } else if (data.format == RemoteIR::AEHA) {
00262                 /*
00263                  * AEHA.
00264                  */
00265                 static const int TRAILER_AEHA_HEAD = 1;
00266                 static const int TRAILER_AEHA_TAIL = 8000 / RemoteIR::TUS_AEHA;
00267                 if (work.trailer < TRAILER_AEHA_HEAD) {
00268                     tx.write(0.5);
00269                 } else {
00270                     tx.write(0.0);
00271                 }
00272                 work.trailer++;
00273                 if ((TRAILER_AEHA_HEAD + TRAILER_AEHA_TAIL) <= work.trailer) {
00274                     work.state = Idle;
00275                     //ticker.detach();
00276                 }
00277             } else if (data.format == RemoteIR::SONY) {
00278                 /*
00279                  * SONY.
00280                  */
00281                 static const int TRAILER_SONY_HEAD = 0;
00282                 static const int TRAILER_SONY_TAIL = 0;
00283                 if (work.trailer < TRAILER_SONY_HEAD) {
00284                     tx.write(0.5);
00285                 } else {
00286                     tx.write(0.0);
00287                 }
00288                 work.trailer++;
00289                 if ((TRAILER_SONY_HEAD + TRAILER_SONY_TAIL) <= work.trailer) {
00290                     work.state = Idle;
00291                     //ticker.detach();
00292                 }
00293             } else {
00294             }
00295             break;
00296         default:
00297             break;
00298     }
00299     UNLOCK();
00300 }