An I/O controller for virtual pinball machines: accelerometer nudge sensing, analog plunger input, button input encoding, LedWiz compatible output controls, and more.

Dependencies:   mbed FastIO FastPWM USBDevice

Fork of Pinscape_Controller by Mike R

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers IRReceiver.h Source File


00001 // IR Remote Receiver
00002 //
00003 // This is a multi-protocol receiver for IR remote control signals.  The
00004 // IR signals are physically received through an external sensor.  Our
00005 // reference device is the TSOP384xx, but most other IR remote sensors
00006 // are similar in design and will proably work.  We have two main requirements
00007 // for the sensor: first, it has to demodulate the IR carrier wave; second,
00008 // it has to present a single-wire digital signal representing the demodulated
00009 // IR status.  We assume active low signaling, where 0V on the signal line 
00010 // represents "IR ON" and Vcc represents "IR OFF".  It would be fairly easy
00011 // to adapt the code to the opposite signaling sense, but I haven't bothered
00012 // to parameterize this because I haven't seen any active-high sensors.  The
00013 // sensor also obviously has to be electrically compatible with the KL25Z,
00014 // which mostly means that it runs on a 3.3V supply.  If your sensor uses
00015 // a different supply voltage, it might still be workable, but you might
00016 // need to interpose a voltage level converter on the logic input to make
00017 // sure that the KL25Z GPIO pin doesn't go above 3.3V, as these pins aren't
00018 // tolerant of higher voltages.
00019 //
00020 // How to wire the sensor
00021 //
00022 // To physically wire the sensor, you just need to connect the sensor's
00023 // Vs and GND pins to the the 3.3V out (P3V3) and GND on the KL25Z,
00024 // respectively, and connect its "OUT" or "data" pin (pin 1 on a TSOP384xx)
00025 // to a free, interrupt-capable GPIO on the KL25Z.  On the KL25Z, all PTAxx
00026 // and PTDxx ports are interrupt-capable (and conversely, PTBxx, PTCxx, and
00027 // PTExx ports aren't, so you can't use one of those).  You should check the
00028 // data sheet for the sensor you're using to see if any other external
00029 // components are required; e.g., the TSOP384xx data sheet recommends a 
00030 // capacitor and resistor for ESD protection and power supply conditioning.
00031 // The data sheet will include a diagram showing the suggested application
00032 // wiring if there are any special considerations like that.  Note that the
00033 // TSOP384xx data sheet doesn't specify exact values for the resistor and 
00034 // capacitor, so I'll mention what I'm using in my test setup: 220 ohms for
00035 // the resistor, 150nF for the capacitor.
00036 // 
00037 // How to use it in your application
00038 //
00039 // To use the receiver in an application, first create an IRReceiver object,
00040 // telling it which pin to use as the sensor input, and how big you want the
00041 // raw sample buffer to be.  The raw buffer needs to be big enough to hold
00042 // samples that arrive during each iteration of your main loop, so you need
00043 // approximately one buffer entry per 250us of your main loop's maximum 
00044 // iteration time.  If RAM isn't tight in your app, just pick a fairly large 
00045 // size (maybe 200 entries); if RAM is tight, figure your worst-case main loop
00046 // time, divide by 250us, and add maybe 25% or 50% padding.  Once you create
00047 // the receiver object, call enable() to enable reception.  You can do this
00048 // once at the outset, or you can selectively enable() and disable() it at
00049 // any time if you only need reception at specific times.  Reception takes
00050 // a small amount of CPU time (in interrupt mode) whenever signals arrive,
00051 // so if you have a time-critical task to do at a time when reception isn't
00052 // useful, you can turn it off to avoid any latency from IR interrupts.
00053 //
00054 //    IRReceiver *rx = new IRReceiver(PTA13, 32);
00055 //    rx->enable();
00056 //
00057 // If you're using the companion transmitter class in the same application
00058 // to create a device that's both an IR transmitter and receiver, you might
00059 // want to tell the receiver about the transmitter, via setTransmitter().
00060 // This causes the receiver to ignore incoming signals whenever the
00061 // transmitter is sending, so that you don't receive your own transmissions.
00062 // This isn't necessary if the receiver is positioned so that it can't see
00063 // the transmitter's signals.
00064 //
00065 //    rx->setTransmitter(tx);
00066 //
00067 // Once you have a receiver set up and enabled, you need to call its process()
00068 // method on each iteration of your main loop.  This method takes all of the
00069 // signals that have been received since the last call and runs them through
00070 // the protocol decoders.  To minimize time spent in interrupt handlers, the
00071 // interrupt handlers merely queue the messages internally; this makes them
00072 // return extremely quickly, so that they don't add any significant latency 
00073 // for other hardware or timer interrupts your application might use.
00074 //
00075 //    rx->process();
00076 //
00077 // Also in your main loop, read incoming IR remote codes by calling
00078 // readCommand() on the receiver.  If a command is available, this will read
00079 // it into an IRCommand object, which tells you the protocol the sender used
00080 // (see IRProtocolID.h), and provides a "universal" representation of the
00081 // command.  The universal representation is protocol-specific mapping of
00082 // the raw data bits to an integer value.  We try to do this in a way that's
00083 // most useful per protocol, with two main goals in mind.  First, if there
00084 // are any internal bits that are more structural than meaningful, such as
00085 // checksums or other integrity checks, we generally remove them.  Second,
00086 // if there are published tables of codes from a manufacturer, we try to
00087 // match the format used there, to make it easier to verify that codes are
00088 // as expected and to make it easier to construct apps around specific types
00089 // of remotes.
00090 //
00091 //    IRCommand cmd;
00092 //    while (rx->readCommand(cmd)) { process the command; }
00093 //
00094 // You can also optionally read the raw incoming data, by calling processOne()
00095 // instead of process().  processOne() runs a reading through the protocol
00096 // decoders but also hands it back to you.  Raw samples are simply "IR ON"
00097 // and "IR OFF" signals with the time the IR was continuously on or off.
00098 // The raw samples are useful if you want to build something like a repeater
00099 // that only has to replicate the physical IR signals without regard to the
00100 // underlying data bits.  Raw signals are obviously also very useful if you
00101 // want to analyze an unknown protocol and figure out how to write a new
00102 // encoder/decoder for it.  One thing that raw signals aren't great for,
00103 // somewhat counterintuitively, is for building a learning remote.  Many of
00104 // the protocols have special ways of handling repeated codes (e.g., when 
00105 // holding down a key) that make verbatim repetition of a signal problematic
00106 // for learning remote use.  If you just repeat a raw code, the receiver
00107 // might be confused into thinking that one key press looks like several
00108 // key presses, or vice versa.  It's better when possible to decode a signal
00109 // into a recognized protocol, store the decoded bit data rather than the
00110 // raw signals as the "learned" code, and then reconstruct the appropriate 
00111 // signal for transmission by re-encoding the learned bit code using the 
00112 // protocol's known structure.
00113 //
00114 //
00115 // Internal architecture
00116 //
00117 // The IRReceiver object is simply a coordinator that manages the sensor
00118 // hardware interface, reads the raw signals from the sensor, and passes
00119 // the raw signals to the protocol objects for decoding.  For each protocol
00120 // we recognize, we define a specialized handler class for the protocol.  
00121 // Each protocol handler implements a state machine for decoding signals 
00122 // using its protocol.  When IRReceiver reads a raw signal, it simply passes 
00123 // it to each of the protocol handlers in turn.  They all operate as 
00124 // independent state machines, so in effect we have specialized receivers 
00125 // for all of the protocols operating in parallel, all eavesdropping on the 
00126 // same incoming stream of signals.  When one of the protocol handlers 
00127 // successfully decodes a complete "command" (a key press on a remote, in 
00128 // most cases), it adds the command to our queue, using a universal 
00129 // representation that we define.  Clients can then read the incoming
00130 // commands from the queue without worrying about the raw signal details.
00131 //
00132 // It might sound chaotic to have all of these different protocol decoders
00133 // working on the same data at the same time, but in practice the various 
00134 // protocols have enough internal structure that only the "right" handler
00135 // will be able to do anything with a given signal, and the rest will just
00136 // ignore it, and bide their time until something shows up that they can make 
00137 // sense of.  It might also sound like a lot of overhead, but in practice 
00138 // it's very lightweight: it takes about 4% CPU to service the decoding 
00139 // process while a signal is actually coming in, and essentially 0% when
00140 // the IR airwaves are silent.  What's more, that 4% CPU time is all in
00141 // application context, not in interrupt context, so it doesn't contribute
00142 // any latency to any other hardware interrupts you need to handle in your
00143 // application.
00144 //
00145 // The individual protocol state machines are all very simple, typically 
00146 // doing just a few integer compares on the incoming timing data per signal.
00147 // They also require very little state, usually on the order of a few 'int's 
00148 // per decoder, which translates to a small RAM footprint.  The decoders 
00149 // operate incrementally and decode in near real time, so decoded commands 
00150 // appear essentially at the same time that their signals finish.
00151 //
00152 // Note that, unlike some other MCU IR libraries, we don't any have sort 
00153 // of global receiver state.  In particular, we don't try to guess about
00154 // message boundaries globally.  All of the boundary detection and protocol 
00155 // state is in the individual protocol decoders.  That eliminates the need
00156 // for heuristics or special cases to guess about what "usually" indicates
00157 // a message boundary across all protocols.  There are enough special cases
00158 // to make such guesses problematic, which becomes apparent if you look at
00159 // the code in libraries that work that way.  Since we don't need to know
00160 // about message boundaries globally, we don't need to make such guesses or
00161 // apply such special cases.  We simply deal in the raw pulses and let 
00162 // each decoder separately judge for itself where its own message boundaries 
00163 // are.  This might seem odd, because the implication is that one decoder
00164 // might think we're in the middle of a message while another decoder 
00165 // thinks we're on a boundary.  But that's just fine, and it's exactly
00166 // why we shouldn't be making those judgments globally: if two protocols
00167 // have contradictory rules like that, the way to reconcile it is to accept
00168 // that there really is no correct global judgment, and leave it to the 
00169 // decoders to track their own states independently.
00170 //
00171 // We receive signals from the sensor via interrupts on the input GPIO pin.
00172 // This allows for the most accurate timing possible, which is important
00173 // because IR coding is entirely in the signal timing.  Interrupts gives us
00174 // much more accurate timing than polling would for obvious reasons.  As
00175 // mentioned above, though, we try to minimize the time we spend in IRQ
00176 // context, since time spent in one interrupt handler translates to added
00177 // latency for any other interrupts that occur at the same time.  To 
00178 // accomplish this, the interrupt handlers don't do any decoding at all.
00179 // They simply add the incoming signal data to an internal queue and then
00180 // return.  We do the decoding work back in application context, by having
00181 // the main loop call our process() routine periodically.  This takes signal
00182 // readings off of the queue and runs them through the decoders.  This
00183 // introduces a small amount of lag time between physically receiving a
00184 // signal and decoding it, but the lag time is only on the order of the
00185 // main loop run time.  In most MCU applications this is a very short
00186 // time, perhaps only microseconds or perhaps as long as a few millseconds.
00187 // But in any case it's almost always so short that a user can't perceive
00188 // the delay, so for all practical purposes decoding is done in real time.
00189 //
00190 //
00191 // How IR remotes work in general
00192 //
00193 // IR remote controls work by transmitting timed pulses of infrared light.
00194 // These pulses are modulated in two ways: first, with a "carrier", which
00195 // is a PWM signal operating at a fixed, relatively high frequency; and
00196 // second, with a lower frequency data signal superimposed on the PWM
00197 // signal.  (And I suppose you could say there's a third layer of 
00198 // modulation in the IR light itself, since that's an electromagnetic 
00199 // wave operating at an even higher frequency of around 300 THz.)
00200 //
00201 // Carrier: The PWM carrier uses a fixed frequency, usually around 40kHz.  
00202 // The carrier doesn't encode any data, since it's just constant fixed-length
00203 // pulses.  Its function, rather, is to provide a regular oscillating signal
00204 // that receivers can use to distinguish data signals from ambient light.
00205 // This is necessary because the IR light wavelengths are also contained
00206 // in sunlight and ordinary household lighting.  (Fluourescent lights even
00207 // have their own characteristic oscillating frequencies in the IR band, so
00208 // the receiver not only has to distinguish the signal from constant
00209 // amgient light levels but also from other types of oscillating light
00210 // levels.  The PWM carrier frequencies used in remotes are chosen based
00211 // on the practical need to distinguish remote control signals from the
00212 // common household interference sources.)  Receivers can separate the 
00213 // an oscillating PWM signal at a particular frequency from other signals
00214 // through a process known as demodulation, which is the same mechanism
00215 // that radio receivers use to pluck AM or FM signals from the jumble of 
00216 // background noise in the radio spectrum.
00217 //
00218 // For our purposes, we don't worry about demodulation in the software,
00219 // since the sensor hardware does that part of the job.  Each type of sensor 
00220 // is designed to demodulate a particular carrier frequency, so you should 
00221 // choose a sensor based on the types of remotes you plan to use it with.  
00222 // Most CE manufacturers have more or less standardized on 38kHz, which is
00223 // why we recommend the TSOP384xx series.  Not everyone is at exactly 38kHz,
00224 // but most are within 2kHz plus or minus, and the TSOP seems to demodulate
00225 // signals within a few kHz of its nominal frequency very well.  38kHz seems
00226 // to be a good centerpoint for home electronics devices, which is why we
00227 // recommend the 38kHz part as a "universal" receiver.  If your application
00228 // only needs to receive from one specific remote (rather than act as a 
00229 // universal receiver), you might be better served with a different TSOP
00230 // part that's tuned to your transmitter's carrier frequency, if that's
00231 // something other than 38kHz.
00232 //
00233 // Data signal: The data signal is superimposed on the PWM carrier by 
00234 // turning the PWM'ed IR source on and off at a lower, variable frequency. 
00235 // These longer on/off pulses are of different lengths.  The data bits are 
00236 // encoded in the varying lengths, although there's no one true way of 
00237 // doing this.  Each protocol has its own way of representing bits as
00238 // combinations of on times and off times, which we'll come to shortly.
00239 //
00240 // "On" pulses are called "marks", and "off" pulses are called "spaces".  
00241 // The terms come from wired asynchronous protocols, which share many 
00242 // properties with IR signals at this level.
00243 //
00244 // Note that each pulse has to be long enough to contain some minimum 
00245 // number (maybe 5-10) of PWM pulses, because otherwise the demodulator 
00246 // wouldn't be able to detect the presence or absence of the underlying 
00247 // PWM pulses.  This makes IR remote codes fairly slow in terms of data 
00248 // rate, since the absolute minimum time per bit is the time in the shortest 
00249 // data pulse.  Most codings actually use at least two pulses per bit for 
00250 // the sake of signal integrity, so the effective data rate lower still.  
00251 // Fortunately, this is all rather unimportant, since IR remotes don't 
00252 // need a very high data rate.  They're mostly used to transmit button 
00253 // presses made by hand by a human user, which are at a fairly low rate
00254 // to start with; plus, the amount of data per button is minuscule, 
00255 // usually from 8 to 32 bits.
00256 //
00257 // Encodings
00258 //
00259 // The timing of the marks and spaces carries the information, but exactly
00260 // how it does this is a whole separate matter, known as an encoding.  An
00261 // encoding is a mapping from '0' and '1' bits to a pattern of marks and
00262 // spaces, and vice versa.  At first glance, it might seem that you could
00263 // just use a mark as a '1' and a space as a '0', and in fact some protocols
00264 // do something like this.  But that simple approach has some big drawbacks
00265 // arising from the lack of a shared clock between sender and receiver.
00266 // Most encodings therefore do something to embed a timing signal of some
00267 // sort within the data signal, by using the lengths of the pulses to encode 
00268 // bits rather than just the presence of the pulses.
00269 //
00270 // There are probably an infinite number of possible ways to do this in
00271 // principle.  Fortunately, the CE companies have only put a finite number
00272 // of them into practice.  In fact, it seems that we can cover practically
00273 // all of the remotes out there by considering a small handful of encoding 
00274 // schemes.  Here are the main ones, and the ones we can use in this
00275 // receiver library:
00276 //
00277 //  - Async bit stream.  This is basically the IR equivalent of a wired
00278 //    UART.  Each code word consists of a fixed number of bits.  Each bit
00279 //    is represented by IR ON for '1' and IR OFF for '0', transmitted for
00280 //    a fixed time length.  To transmit, simply turn the IR on and off in
00281 //    sequence for the fixed bit time per bit.  To receive and decode,
00282 //    observe whether the IR signal is on or off in each time window. 
00283 //    This type of protocol looks simple, but it presents some difficulties
00284 //    in implementation, because it doesn't provide any cues embedded in
00285 //    the IR signal to help the receiver synchronize with the sender or
00286 //    recognize the boundaries of code words, as all of the other common
00287 //    protocols do.  That might be why this class seems to be rarely used 
00288 //    in real applications.  Protocols based on simple async bits usually
00289 //    add something at the protocol level that helps the reciever detect
00290 //    word boundaries and check signal integrity.
00291 //
00292 //  - Pulse distance coding, also known as space length coding.  In this 
00293 //    scheme, marks are all of equal length, but spaces come in two lengths, 
00294 //    A and B, where B is much longer than A (usually twice as long, but it
00295 //    could be even longer).  A encodes 0 and B encodes 1.  The marks serve
00296 //    as regular clock signals, allowing the receiver to keep in sync with
00297 //    the sender, and the long and short space times (A and B) are different
00298 //    enough that the receiver can easily distinguish them reliably, even
00299 //    with a low-precision clock.  This scheme is probably the most widely
00300 //    used in CE products, because it's the encoding used by the NEC 
00301 //    protocol, which most Japanese CE companies use.
00302 //
00303 //  - Pulse length coding, also known as mark length coding.  This is simply 
00304 //    the inverse of pulse distance coding: spaces are all of equal length, 
00305 //    and marks come in two lengths, with the short mark encoding 0 and the 
00306 //    long mark encoding 1.  This is practically the same in all meaningful
00307 //    ways as the space length coding; the only reason both kinds exist is
00308 //    probably that either someone had a bad case of NIH or they wanted to
00309 //    avoid paying a patent royalty.  Mark length coding is the scheme Sony
00310 //    uses (in their SIRCS protocol).
00311 //
00312 //  - Manchester coding.  The message is divided into time slices of 
00313 //    equal size, one bit per slice.  Within each slice, the IR is on for 
00314 //    half the window and off for half the window.  The 0 and 1 bits are
00315 //    encoded by the direction of the transition: if a bit window starts
00316 //    with a mark (IR ON) and ends with a space (IR OFF), it's a '1'; if it
00317 //    starts with a space and ends with a mark, it's a '0'.  Or vice versa.
00318 //    Each mark or space therefore lasts for either 1/2 or 1 bit time 
00319 //    length, never longer.  This makes it fairly easy for the receiver to 
00320 //    distinguish the two time lengths, even with a fairly low-precision 
00321 //    clock, since they're so different.  It's also easy for the receiver
00322 //    to distinguish each bit, since there's always at least one transition
00323 //    (mark to space or space to mark) per bit.  What's more, '0' and '1' 
00324 //    bits take the same time to transmit (unlike the mark-length and 
00325 //    space-length protocols), so every code word (assuming a fixed bit 
00326 //    count) takes the same time regardless of the bit values within. 
00327 //    Manchester modulation is used in the Philips RC5 and RC6 protocols, 
00328 //    which are widely used among European CE companies.
00329 //
00330 // Protocols
00331 //
00332 // On top of the encoding scheme, there's another level of structure called
00333 // a protocol.  A given protocol uses a given encoding for the data bits,
00334 // but then also adds some extra structure.  
00335 //
00336 // For starters, the IR protocols all work in terms of "code words".  In 
00337 // computer terms, a code word amounts to a datatype with a fixed number 
00338 // of bits.  For example, the NEC protocol uses a 32-bit code word: each 
00339 // button press is represented by a 32-bit transmission.  A single key 
00340 // press usually maps to a single code word, although not always; the 
00341 // Pioneer protocol, for example, transmits two words for certain buttons, 
00342 // using a special "shift" code for the first word to give a second meaning 
00343 // to the second word, to extend the possible number of commands that would
00344 // be otherwise limited by the number of bits in a single code word.
00346 // Second, most of the IR protocols add special non-data signals that
00347 // mark the beginning and/or end of a code word.  These are usually just
00348 // extra-long marks or spaces, which are distinguishable from the marks
00349 // and spaces within a code word because they're too long to be valid in
00350 // the data encoding scheme.  These are important to reliable communication
00351 // because the sender and receiver don't have any other way to share state 
00352 // with each other.  Consider what would happen if someone walked in the
00353 // way while you were transmitting a remote code: the receiver would miss
00354 // at least a few data bits, so it would be out of sync with the sender.
00355 // If there weren't some way to distinguish the start of a code word from
00356 // the IR pulses themselves, the receiver would now be permanently out
00357 // of sync from the sender by however many bits it missed.  But with the
00358 // special "header" code, the receiver can sync up again as soon as the
00359 // next code word starts, since it can tell from the timing that the
00360 // header can't possibly be a bit in the middle of a code word.
00363 #ifndef _IRRECEIVER_H_
00364 #define _IRRECEIVER_H_
00366 #include <mbed.h>
00368 #include "IRRemote.h"
00369 #include "IRCommand.h"
00370 #include "circbuf.h"
00371 #include "FastInterruptIn.h"
00374 // IR receiver protocol interface.  This contains functions that we only
00375 // want to make accessible to the protocol decoders.
00376 class IRRecvProIfc
00377 {
00378 public:
00379     // write a command to the command queue
00380     void writeCommand(IRCommand &cmd) { commands.write(cmd); }
00382 protected:
00383     // Decoded command queue.  The protocol handlers add commands here
00384     // as soon as they decode them.
00385     CircBuf<IRCommand, 8> commands;
00386 };
00389 // IR Remote Receiver
00390 class IRReceiver : protected IRRecvProIfc
00391 {
00392 public:
00393     // Construct a receiver with the given data input pin.  The receiver
00394     // is initially disabled.  To start receiving signals, call enable().
00395     //
00396     // Choose a raw buffer size according to the longest iteration time
00397     // for your main application loop between the required periodic calls 
00398     // to our process() function.  The interrupt handlers write pulse times
00399     // to the raw buffer as the pulses arrive, and these are held in the 
00400     // buffer until they're removed by process().  The raw buffer only needs
00401     // to be big enough for the "backlog" that occurs between the real-time
00402     // incoming signals and the main loop's processing calls.  The fastest
00403     // IR pulses are about 250us long, so size the buffer according to how
00404     // many 250us intervals will occur in the worst case, that is, the 
00405     // longest main loop iteration.  If the main loop always runs in 2.5ms 
00406     // or shorter, that means you need about a 10-element buffer.  To be
00407     // conservative, size it at perhaps 2x the expected maximum.
00408     //
00409     IRReceiver(PinName rxpin, size_t rawBufCount);
00411     // Destructor
00412     ~IRReceiver();
00414     // Optionally connect to a transmitter, to suppress reception while
00415     // we're transmitting.  This prevents spuriously receiving our own
00416     // transmissions, if our IR LED and sensor are physically close enough
00417     // to one another that our sensor would pick up light from our LED.
00418     // If the two are physically isolated so that we can't receive our
00419     // own transmissions, it's not necessary to connect the transmitter
00420     // here, as there's no restriction on the software side on sending
00421     // and receiving simultaneously - the suppression is only needed to
00422     // avoid self-interference with the physical IR signals.
00423     void setTransmitter(class IRTransmitter *transmitter)
00424     {
00425         this->transmitter = transmitter;
00426     }
00428     // Enable/disable our interrupt handlers.  If the main program
00429     // doesn't need IR input, it can disable the receiver so that
00430     // it doesn't consume any CPU time handling interrupts.
00431     void enable();
00432     void disable();
00434     // Read a command.  Returns true if a command was available, filling
00435     // in 'cmd'.  Returns false (without blocking) if no commands are 
00436     // available.
00437     bool readCommand(IRCommand &cmd) { return; }
00439     // Is a command ready to read?
00440     bool isCommandReady() { return commands.readReady(); }
00442     // Process signals received.  The application main loop must call this
00443     // as frequently as possible to process incoming signals from the raw
00444     // buffer.  This processes all samples in the raw buffer before
00445     // returning.
00446     void process();
00448     // Process and retrieve one raw pulse.  The application main loop can
00449     // optionally call this, instead of process(), if it wants to retrieve
00450     // each raw sample for its own purposes in addition to running them 
00451     // through the protocol state machines.  If no sample is available, we
00452     // immediately return false - the routine doesn't block waiting for a
00453     // sample.  If a sample is available, we fill in 'sample' with the pulse 
00454     // time in microseconds, and set 'mark' to true if the sample was a mark, 
00455     // false if it's a space.  
00456     //
00457     // To use this instead of process(), on each main loop iteration, call 
00458     // this function in an inner loop until it returns false.  That'll ensure 
00459     // that all pending samples have been processed through the protocol 
00460     // state machines and that maximum buffer space is available for the next 
00461     // main loop iteration.
00462     bool processOne(uint32_t &sample, bool &mark);
00464     // Process and retrieve one raw pulse.  This works the same as the
00465     // two-argument version above, but returns the sample in our internal
00466     // format: the sample value is a time reading in 2us units, and the low
00467     // bit is 1 for a mark, 0 for a space.  To convert to a time reading in
00468     // microseconds, mask out the low bit and multiply by 2.
00469     bool processOne(uint16_t &sample);
00471     // Maximum pulse length in microseconds.  Anything longer will simply 
00472     // be represented with this value.  This is long enough that anything
00473     // longer has equivalent meaning in any of our protocols.  Generally,
00474     // space longer than this will only occur in a silent interval between
00475     // transmissions (that is, while no one is sending any codes), and a
00476     // mark longer than this could only be interference or noise.
00477     //
00478     // This value should be chosen so that it's high enough to be readily
00479     // distinguishable (in terms of our error tolerance) from the longest
00480     // *meaningful* space or pulse in any protocol we need to handle, but
00481     // not much higher than that.  It shouldn't be too long because it has
00482     // a role as an inactivity timeout on receive: we can't always know
00483     // that a signal has ended until there's inactivity for this amount
00484     // of time.  If the timeout is too long, it can become noticable as
00485     // lag time in recognizing signals.  In practice, the longest gap time
00486     // between repeating signals in commonly used protocols is in the 
00487     // neighboorhood of 100ms.
00488     //
00489     // This value is chosen to be the largest we can fit into a 16-bit
00490     // int, taking into account our 2X scaling and our use of the low bit
00491     // for a mark/space indicator.  That leaves us with 14 bits and 2X scale.
00492     static const uint32_t MAX_PULSE = 131068;    
00494 private:
00495     // Input pin.  Reads from a TSOP384xx or similar sensor.  Any
00496     // sensor should work that demodulates the carrier wave and 
00497     // gives us an active-low input on the pin.  
00498     //
00499     // Note that we use our FastInterruptIn replacement instead of the
00500     // mbed InterruptIn.  We don't actually need the higher speed here of
00501     // FastInterruptIn, but we have to use it anyway because other parts
00502     // of the system use it.  The two classes don't play nice together:
00503     // the whole app has to use one or the other.
00504     FastInterruptIn pin;
00506     // IR raw data buffer.  The interrupt handlers store the pulse
00507     // timings here as they arrive, and the process() routine reads from
00508     // the buffer.
00509     //
00510     // Samples here are limited to 16 bits, so the longest time that
00511     // can be represented is 65535us.  Anything longer is capped to this.
00512     //
00513     // To keep track of marks vs spaces, we set the low-order bit of
00514     // each sample time to 1 for a mark and 0 for a space.  That means
00515     // that the times are only good to 2us precision, but that's plenty
00516     // of precision for all of the IR protocols, since the shortest time 
00517     // bases are around 250us.
00518     CircBufV<uint16_t> rawbuf;
00520     // Pulse timer.  We reset the timer at the start of each pulse, so
00521     // it tells us the duration thus far of the current pulse at any 
00522     // given time.  We stop the timer (without resetting) any time a
00523     // pulse reaches the maximum length, to ensure that the timer never
00524     // rolls over, even in the indefinite gap between codes.
00525     Timer pulseTimer;
00527     // flag: the pulse timer has reached IR_MAX_PULSE
00528     bool pulseAtMax;
00530     // current pulse state: mark = 1, space = 0
00531     bool pulseState;
00533     // start the pulse timers with the new pulse state (1=mark, 0=space)
00534     void startPulse(bool newPulseState);
00536     // end the current pulse, checking that the pulse state matches the
00537     // current state
00538     void endPulse(bool lastPulseState);
00540     // process a pulse through our protocol handlers
00541     void processProtocols(uint32_t t, bool mark);
00543     // rise and fall interrupt handlers for the input pin
00544     static void cbFall(void *obj) { ((IRReceiver *)obj)->fall(); }
00545     static void cbRise(void *obj) { ((IRReceiver *)obj)->rise(); }
00546     void fall();
00547     void rise();
00549     // timeout for time-limited states
00550     Timeout timeout;
00552     // timeout handler for a pulse (mark or space)
00553     void pulseTimeout(void);
00555     // Connected transmitter.  If this is set, we'll suppress reception
00556     // while the transmitter is sending a signal, to avoid receiving our
00557     // own transmissions.
00558     class IRTransmitter *transmitter;
00559 };
00561 #endif