forked RemoteIR

Fork of RemoteIR by Shinichiro Nakamura

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