Mirror with some correction
Dependencies: mbed FastIO FastPWM USBDevice
IRRemote/IRCommand.h@77:0b96f6867312, 2017-03-17 (annotated)
- Committer:
- mjr
- Date:
- Fri Mar 17 22:02:08 2017 +0000
- Revision:
- 77:0b96f6867312
New memory pool management; keeping old ones as #ifdefs for now for reference.
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
mjr | 77:0b96f6867312 | 1 | // IR Command Descriptor |
mjr | 77:0b96f6867312 | 2 | // |
mjr | 77:0b96f6867312 | 3 | // This is a common representation for command codes across all of our |
mjr | 77:0b96f6867312 | 4 | // supported IR protocols. A "command code" generally maps to the data |
mjr | 77:0b96f6867312 | 5 | // sent for one key press on a remote control. The common format contains: |
mjr | 77:0b96f6867312 | 6 | // |
mjr | 77:0b96f6867312 | 7 | // - The protocol ID. This represents the mapping between data bits |
mjr | 77:0b96f6867312 | 8 | // and the physical IR signals. Each protocol has its own rules for |
mjr | 77:0b96f6867312 | 9 | // how the individual bits are represented and how the bits making up |
mjr | 77:0b96f6867312 | 10 | // a single command are arranged into a "command word" unit for |
mjr | 77:0b96f6867312 | 11 | // transmission. |
mjr | 77:0b96f6867312 | 12 | // |
mjr | 77:0b96f6867312 | 13 | // - An integer with the unique key code. For most protocols, this is |
mjr | 77:0b96f6867312 | 14 | // simply the sequence of bits sent by the remote. If the protocol has |
mjr | 77:0b96f6867312 | 15 | // the notion of a "toggle bit", we pull that out into the separate toggle |
mjr | 77:0b96f6867312 | 16 | // bit field (below), and set the bit position in the key code field to |
mjr | 77:0b96f6867312 | 17 | // zero so that the same key always yields the same code. If the protocol |
mjr | 77:0b96f6867312 | 18 | // has a published spec with a defined bit ordering (LSB first or MSB |
mjr | 77:0b96f6867312 | 19 | // first), we'll use the same bit ordering to construct the key code |
mjr | 77:0b96f6867312 | 20 | // value, otherwise the bit order is arbitrary. We use the canonical bit |
mjr | 77:0b96f6867312 | 21 | // order when one exists to make it more likely that our codes will match |
mjr | 77:0b96f6867312 | 22 | // those in published tables for commercial remotes using the protocol. |
mjr | 77:0b96f6867312 | 23 | // We'll also try to use the same treatment as published tables for any |
mjr | 77:0b96f6867312 | 24 | // meaningless structural bits, such as start and stop bits, again so that |
mjr | 77:0b96f6867312 | 25 | // our codes will more closely match published codes. |
mjr | 77:0b96f6867312 | 26 | // |
mjr | 77:0b96f6867312 | 27 | // - A "toggle bit". Some protocols have the notion of a toggle bit, |
mjr | 77:0b96f6867312 | 28 | // which is a bit that gets flipped on each key press, but stays the |
mjr | 77:0b96f6867312 | 29 | // same when the same code is sent repeatedly while the user is holding |
mjr | 77:0b96f6867312 | 30 | // down a key. This lets the receiver distinguish two distinct key |
mjr | 77:0b96f6867312 | 31 | // presses from one long key press, which is important for keys like |
mjr | 77:0b96f6867312 | 32 | // "power toggle" and "5". |
mjr | 77:0b96f6867312 | 33 | // |
mjr | 77:0b96f6867312 | 34 | // - A "ditto bit". Some protocols use a special code to indicate an |
mjr | 77:0b96f6867312 | 35 | // auto-repeat. Like the toggle bit, this serves to distinguish |
mjr | 77:0b96f6867312 | 36 | // repeatedly pressing the same key from holding the key down. Ditto |
mjr | 77:0b96f6867312 | 37 | // codes in most protocols that use them don't contain any data bits, |
mjr | 77:0b96f6867312 | 38 | // so the key code will usually be zero if the ditto bit is set. |
mjr | 77:0b96f6867312 | 39 | // |
mjr | 77:0b96f6867312 | 40 | // Note that most of the published protocols have more internal structure |
mjr | 77:0b96f6867312 | 41 | // than this to the bit stream. E.g., there's often an "address" field of |
mjr | 77:0b96f6867312 | 42 | // some kind that specifies the type of device the code is for (TV, DVD, |
mjr | 77:0b96f6867312 | 43 | // etc), and a "command" field with a key code scoped to the device type. |
mjr | 77:0b96f6867312 | 44 | // We don't try to break down the codes into subfields like this. (With |
mjr | 77:0b96f6867312 | 45 | // the exception of "toggle" bits, which get special treatment because |
mjr | 77:0b96f6867312 | 46 | // they'd otherwise make each key look like it had two separate codes.) |
mjr | 77:0b96f6867312 | 47 | // |
mjr | 77:0b96f6867312 | 48 | |
mjr | 77:0b96f6867312 | 49 | #ifndef _IRCOMMAND_H_ |
mjr | 77:0b96f6867312 | 50 | #define _IRCOMMAND_H_ |
mjr | 77:0b96f6867312 | 51 | |
mjr | 77:0b96f6867312 | 52 | #include <mbed.h> |
mjr | 77:0b96f6867312 | 53 | #include "IRProtocolID.h" |
mjr | 77:0b96f6867312 | 54 | |
mjr | 77:0b96f6867312 | 55 | // Three-state logic for reporting dittos and toggle bits. "Null" |
mjr | 77:0b96f6867312 | 56 | // means that the bit isn't used at all, which isn't quite the same |
mjr | 77:0b96f6867312 | 57 | // as false. |
mjr | 77:0b96f6867312 | 58 | class bool3 |
mjr | 77:0b96f6867312 | 59 | { |
mjr | 77:0b96f6867312 | 60 | public: |
mjr | 77:0b96f6867312 | 61 | enum val { null3, false3, true3 } __attribute__ ((packed)); |
mjr | 77:0b96f6867312 | 62 | |
mjr | 77:0b96f6867312 | 63 | static const bool3 null; |
mjr | 77:0b96f6867312 | 64 | |
mjr | 77:0b96f6867312 | 65 | bool3() : v(null3) { } |
mjr | 77:0b96f6867312 | 66 | bool3(val v) : v(v) { } |
mjr | 77:0b96f6867312 | 67 | bool3(bool v) : v(v ? true3 : false3) { } |
mjr | 77:0b96f6867312 | 68 | bool3(int v) : v(v ? true3 : false3) { } |
mjr | 77:0b96f6867312 | 69 | |
mjr | 77:0b96f6867312 | 70 | operator int() { return v == true3; } |
mjr | 77:0b96f6867312 | 71 | operator bool() { return v == true3; } |
mjr | 77:0b96f6867312 | 72 | |
mjr | 77:0b96f6867312 | 73 | bool isNull() const { return v == null3; } |
mjr | 77:0b96f6867312 | 74 | |
mjr | 77:0b96f6867312 | 75 | private: |
mjr | 77:0b96f6867312 | 76 | const val v; |
mjr | 77:0b96f6867312 | 77 | } __attribute__ ((packed)); |
mjr | 77:0b96f6867312 | 78 | |
mjr | 77:0b96f6867312 | 79 | |
mjr | 77:0b96f6867312 | 80 | struct IRCommand |
mjr | 77:0b96f6867312 | 81 | { |
mjr | 77:0b96f6867312 | 82 | IRCommand() |
mjr | 77:0b96f6867312 | 83 | { |
mjr | 77:0b96f6867312 | 84 | proId = IRPRO_NONE; |
mjr | 77:0b96f6867312 | 85 | code = 0; |
mjr | 77:0b96f6867312 | 86 | toggle = false; |
mjr | 77:0b96f6867312 | 87 | ditto = false; |
mjr | 77:0b96f6867312 | 88 | } |
mjr | 77:0b96f6867312 | 89 | |
mjr | 77:0b96f6867312 | 90 | IRCommand(uint8_t proId, uint64_t code, bool3 toggle, bool3 ditto) |
mjr | 77:0b96f6867312 | 91 | { |
mjr | 77:0b96f6867312 | 92 | this->proId = proId; |
mjr | 77:0b96f6867312 | 93 | this->code = code; |
mjr | 77:0b96f6867312 | 94 | this->toggle = bool(toggle); |
mjr | 77:0b96f6867312 | 95 | this->hasToggle = !toggle.isNull(); |
mjr | 77:0b96f6867312 | 96 | this->ditto = bool(ditto); |
mjr | 77:0b96f6867312 | 97 | this->hasDittos = !ditto.isNull(); |
mjr | 77:0b96f6867312 | 98 | } |
mjr | 77:0b96f6867312 | 99 | |
mjr | 77:0b96f6867312 | 100 | // 64-bit command code, containing the decoded bits of the command. |
mjr | 77:0b96f6867312 | 101 | // The bits are arranged in LSB-first or MSB-first order, relative |
mjr | 77:0b96f6867312 | 102 | // to the order of IR transmission, according to the conventions of |
mjr | 77:0b96f6867312 | 103 | // the protocol. This includes all bits from the transmission, |
mjr | 77:0b96f6867312 | 104 | // including things like error detection bits, except for meaningless |
mjr | 77:0b96f6867312 | 105 | // fixed structural elements like header marks, start bits, and stop |
mjr | 77:0b96f6867312 | 106 | // bits. |
mjr | 77:0b96f6867312 | 107 | // |
mjr | 77:0b96f6867312 | 108 | // If there's a "toggle" bit in the code, its bit position in 'code' |
mjr | 77:0b96f6867312 | 109 | // is ALWAYS set to zero, but we store the actual bit value in 'toggle'. |
mjr | 77:0b96f6867312 | 110 | // This ensures that clients who don't care about toggle bits will see |
mjr | 77:0b96f6867312 | 111 | // code value every time for a given key press, while still preserving |
mjr | 77:0b96f6867312 | 112 | // the toggle bit information for clients who can use it. |
mjr | 77:0b96f6867312 | 113 | // |
mjr | 77:0b96f6867312 | 114 | // See the individual protocol encoder/decoder classes for the exact |
mjr | 77:0b96f6867312 | 115 | // mapping between the serial bit stream and the 64-bit code value here. |
mjr | 77:0b96f6867312 | 116 | uint64_t code; |
mjr | 77:0b96f6867312 | 117 | |
mjr | 77:0b96f6867312 | 118 | // Protocol ID - a PRO_xxx value |
mjr | 77:0b96f6867312 | 119 | uint8_t proId; |
mjr | 77:0b96f6867312 | 120 | |
mjr | 77:0b96f6867312 | 121 | // Toggle bit. Some protocols have a "toggle bit", which the sender |
mjr | 77:0b96f6867312 | 122 | // flips each time a new key is pressed. This allows receivers to |
mjr | 77:0b96f6867312 | 123 | // distinguish auto-repeat from separate key presses. For protocols |
mjr | 77:0b96f6867312 | 124 | // that define a toggle bit, we'll store the bit here, and set the |
mjr | 77:0b96f6867312 | 125 | // bit position in 'code' to zero. That way, the client always sees |
mjr | 77:0b96f6867312 | 126 | // the same code for every key press, regardless of the toggle state, |
mjr | 77:0b96f6867312 | 127 | // but callers who want to make use of the toggle bit can still get |
mjr | 77:0b96f6867312 | 128 | // at the transmitted value by inspecting this field. |
mjr | 77:0b96f6867312 | 129 | uint8_t toggle : 1; |
mjr | 77:0b96f6867312 | 130 | |
mjr | 77:0b96f6867312 | 131 | // Does the protocol use toggle bits? This is a fixed feature of |
mjr | 77:0b96f6867312 | 132 | // the protocol, so it doesn't tell us whether the sender is |
mjr | 77:0b96f6867312 | 133 | // actually using toggles properly, only that the bit exists in |
mjr | 77:0b96f6867312 | 134 | // the protocol. If you want to determine if the sender is using |
mjr | 77:0b96f6867312 | 135 | // toggles for learning remote purposes, ask the user to press the |
mjr | 77:0b96f6867312 | 136 | // same key several times in a row, and observe if the reported |
mjr | 77:0b96f6867312 | 137 | // toggle bits alternate. |
mjr | 77:0b96f6867312 | 138 | uint8_t hasToggle : 1; |
mjr | 77:0b96f6867312 | 139 | |
mjr | 77:0b96f6867312 | 140 | // Ditto bit. Some protocols send a distinct code to indicate auto- |
mjr | 77:0b96f6867312 | 141 | // repeat when a key is held down. These protocols will send the |
mjr | 77:0b96f6867312 | 142 | // normal code for the key first, then send the special "ditto" code |
mjr | 77:0b96f6867312 | 143 | // repeatedly as long as the key is held down. If this bit is set, |
mjr | 77:0b96f6867312 | 144 | // the command represents one of these auto-repeat messages. Ditto |
mjr | 77:0b96f6867312 | 145 | // codes usually don't have any data bits, so the 'code' value will |
mjr | 77:0b96f6867312 | 146 | // usually be zero if this is set. |
mjr | 77:0b96f6867312 | 147 | uint8_t ditto : 1; |
mjr | 77:0b96f6867312 | 148 | |
mjr | 77:0b96f6867312 | 149 | // Does the protocol have a ditto format? This only indicates if |
mjr | 77:0b96f6867312 | 150 | // the protocol has a defined ditto format, not if the sender is |
mjr | 77:0b96f6867312 | 151 | // actually using it. If you want to determine if the sender uses |
mjr | 77:0b96f6867312 | 152 | // dittos for learning remote purposes, ask the user to hold a key |
mjr | 77:0b96f6867312 | 153 | // down long enough to repeat, and observe the reported codes to |
mjr | 77:0b96f6867312 | 154 | // see if the ditto bit is set after the first repeat. |
mjr | 77:0b96f6867312 | 155 | uint8_t hasDittos : 1; |
mjr | 77:0b96f6867312 | 156 | |
mjr | 77:0b96f6867312 | 157 | } __attribute__ ((packed)); |
mjr | 77:0b96f6867312 | 158 | |
mjr | 77:0b96f6867312 | 159 | #endif |