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 IRCommand.h Source File

IRCommand.h

00001 // IR Command Descriptor
00002 //
00003 // This is a common representation for command codes across all of our
00004 // supported IR protocols.  A "command code" generally maps to the data
00005 // sent for one key press on a remote control.  The common format contains:
00006 //
00007 // - The protocol ID.  This represents the mapping between data bits
00008 //   and the physical IR signals.  Each protocol has its own rules for
00009 //   how the individual bits are represented and how the bits making up
00010 //   a single command are arranged into a "command word" unit for
00011 //   transmission.
00012 //
00013 // - An integer with the unique key code.  For most protocols, this is
00014 //   simply the sequence of bits sent by the remote.  If the protocol has
00015 //   the notion of a "toggle bit", we pull that out into the separate toggle
00016 //   bit field (below), and set the bit position in the key code field to
00017 //   zero so that the same key always yields the same code.  If the protocol
00018 //   has a published spec with a defined bit ordering (LSB first or MSB 
00019 //   first), we'll use the same bit ordering to construct the key code
00020 //   value, otherwise the bit order is arbitrary.  We use the canonical bit
00021 //   order when one exists to make it more likely that our codes will match
00022 //   those in published tables for commercial remotes using the protocol.
00023 //   We'll also try to use the same treatment as published tables for any
00024 //   meaningless structural bits, such as start and stop bits, again so that
00025 //   our codes will more closely match published codes.
00026 //
00027 // - A "toggle bit".  Some protocols have the notion of a toggle bit,
00028 //   which is a bit that gets flipped on each key press, but stays the
00029 //   same when the same code is sent repeatedly while the user is holding
00030 //   down a key.  This lets the receiver distinguish two distinct key
00031 //   presses from one long key press, which is important for keys like
00032 //   "power toggle" and "5".
00033 //
00034 // - A "ditto bit".  Some protocols use a special code to indicate an
00035 //   auto-repeat.  Like the toggle bit, this serves to distinguish
00036 //   repeatedly pressing the same key from holding the key down.  Ditto
00037 //   codes in most protocols that use them don't contain any data bits,
00038 //   so the key code will usually be zero if the ditto bit is set.
00039 //
00040 // Note that most of the published protocols have more internal structure
00041 // than this to the bit stream.  E.g., there's often an "address" field of
00042 // some kind that specifies the type of device the code is for (TV, DVD,
00043 // etc), and a "command" field with a key code scoped to the device type.
00044 // We don't try to break down the codes into subfields like this.  (With
00045 // the exception of "toggle" bits, which get special treatment because 
00046 // they'd otherwise make each key look like it had two separate codes.)
00047 //
00048 
00049 #ifndef _IRCOMMAND_H_
00050 #define _IRCOMMAND_H_
00051 
00052 #include <mbed.h>
00053 #include "IRProtocolID.h"
00054 
00055 // Three-state logic for reporting dittos and toggle bits.  "Null"
00056 // means that the bit isn't used at all, which isn't quite the same
00057 // as false.
00058 class bool3
00059 {
00060 public:
00061     enum val { null3, false3, true3 } __attribute__ ((packed));
00062     
00063     static const bool3 null;
00064 
00065     bool3() : v(null3) { }
00066     bool3(val v) : v(v) { }
00067     bool3(bool v) : v(v ? true3 : false3) { }
00068     bool3(int v) : v(v ? true3 : false3) { }
00069     
00070     operator int() { return v == true3; }
00071     operator bool() { return v == true3; }
00072     
00073     bool isNull() const { return v == null3; }
00074         
00075 private:
00076     const val v;
00077 } __attribute__ ((packed));
00078     
00079 
00080 struct IRCommand
00081 {
00082     IRCommand() 
00083     { 
00084         proId = IRPRO_NONE;
00085         code = 0;
00086         toggle = false;
00087         ditto = false;
00088     }
00089 
00090     IRCommand(uint8_t proId, uint64_t code, bool3 toggle, bool3 ditto)
00091     {
00092         this->proId = proId;
00093         this->code = code;
00094         this->toggle = bool(toggle);
00095         this->hasToggle = !toggle.isNull();
00096         this->ditto = bool(ditto);
00097         this->hasDittos = !ditto.isNull();
00098     }
00099 
00100     // 64-bit command code, containing the decoded bits of the command.
00101     // The bits are arranged in LSB-first or MSB-first order, relative
00102     // to the order of IR transmission, according to the conventions of
00103     // the protocol.  This includes all bits from the transmission,
00104     // including things like error detection bits, except for meaningless
00105     // fixed structural elements like header marks, start bits, and stop
00106     // bits.  
00107     //
00108     // If there's a "toggle" bit in the code, its bit position in 'code' 
00109     // is ALWAYS set to zero, but we store the actual bit value in 'toggle'.
00110     // This ensures that clients who don't care about toggle bits will see
00111     // code value every time for a given key press, while still preserving
00112     // the toggle bit information for clients who can use it.
00113     //
00114     // See the individual protocol encoder/decoder classes for the exact 
00115     // mapping between the serial bit stream and the 64-bit code value here.
00116     uint64_t code;
00117     
00118     // Protocol ID - a PRO_xxx value
00119     uint8_t proId;
00120     
00121     // Toggle bit.  Some protocols have a "toggle bit", which the sender
00122     // flips each time a new key is pressed.  This allows receivers to
00123     // distinguish auto-repeat from separate key presses.  For protocols
00124     // that define a toggle bit, we'll store the bit here, and set the
00125     // bit position in 'code' to zero.  That way, the client always sees
00126     // the same code for every key press, regardless of the toggle state,
00127     // but callers who want to make use of the toggle bit can still get
00128     // at the transmitted value by inspecting this field.
00129     uint8_t toggle : 1;
00130     
00131     // Does the protocol use toggle bits?  This is a fixed feature of 
00132     // the protocol, so it doesn't tell us whether the sender is
00133     // actually using toggles properly, only that the bit exists in
00134     // the protocol.  If you want to determine if the sender is using
00135     // toggles for learning remote purposes, ask the user to press the
00136     // same key several times in a row, and observe if the reported
00137     // toggle bits alternate.
00138     uint8_t hasToggle : 1;
00139     
00140     // Ditto bit.  Some protocols send a distinct code to indicate auto-
00141     // repeat when a key is held down.  These protocols will send the 
00142     // normal code for the key first, then send the special "ditto" code
00143     // repeatedly as long as the key is held down.  If this bit is set,
00144     // the command represents one of these auto-repeat messages.  Ditto
00145     // codes usually don't have any data bits, so the 'code' value will
00146     // usually be zero if this is set.
00147     uint8_t ditto : 1;
00148     
00149     // Does the protocol have a ditto format?  This only indicates if
00150     // the protocol has a defined ditto format, not if the sender is
00151     // actually using it.  If you want to determine if the sender uses
00152     // dittos for learning remote purposes, ask the user to hold a key
00153     // down long enough to repeat, and observe the reported codes to
00154     // see if the ditto bit is set after the first repeat.
00155     uint8_t hasDittos : 1;
00156     
00157 } __attribute__ ((packed));
00158 
00159 #endif