1 #include "rc5protocol.h"
3 #include "pirexception.h"
6 extern bool commandInFlight;
7 extern QMutex commandIFMutex;
9 RC5Protocol::RC5Protocol(
12 unsigned int sevenBitControl)
13 : PIRProtocol(guiObject, index, 114000, true),
18 setCarrierFrequency(36000);
19 setPreData(sevenBitControl, 7);
23 RC5Protocol::RC5Protocol(
26 : PIRProtocol(guiObject, index, 114000, true),
31 setCarrierFrequency(36000);
35 void RC5Protocol::startSendingCommand(
36 unsigned int threadableID,
39 // Dumping entire method inside of try/catch, to deal with cross-thread
40 // exception handling:
43 // Check if this command is meant for us:
44 if (threadableID != id) return;
48 KeycodeCollection::const_iterator i = keycodes.find(command);
50 // Sanity check, make sure command exists first:
51 if (i == keycodes.end())
53 std::string s = "Tried to send a non-existent command.\n";
54 throw PIRException(s);
57 // Construct the object that communicates with the device driver:
58 PIRRX51Hardware rx51device(carrierFrequency, dutyCycle);
61 int commandDuration = 0;
62 while (repeatCount < MAX_REPEAT_COUNT)
64 // Now, throw together an RC5 protocol command string.
68 // For standard RC5, the "pre-data" contains the control portion,
69 // and the key contains only the 6-bit command portion.
71 // First, construct the control portion:
72 commandDuration += pushControlBits(rx51device);
74 // Next, the key-command portion:
75 commandDuration += pushKeyCommandBits((*i).second, rx51device);
79 // For non-standard RC5, the entire 13 bits are stuffed into the
80 // key portion, as all of them can vary:
81 commandDuration += pushNonStandardRC5((*i).second, rx51device);
84 // Clear out the buffer, if necessary:
87 rx51device.addSingle(buffer);
88 commandDuration += buffer;
90 // probably unnecessary cleanup of buffer:
92 bufferContainsSpace = false;
93 bufferContainsPulse = false;
96 // Now, tell the device to send the whole command:
97 rx51device.sendCommandToDevice();
99 // Sleep for an amount of time. (Need to make this interruptable!)
100 sleepUntilRepeat(commandDuration);
102 // Have we been told to stop yet?
103 if (checkRepeatFlag())
105 // Ok, then we can quit now:
107 QMutexLocker cifLocker(&commandIFMutex);
108 commandInFlight = false;
115 catch (PIRException e)
117 emit commandFailed(e.getError().c_str());
121 QMutexLocker cifLocker(&commandIFMutex);
122 commandInFlight = false;
126 int RC5Protocol::pushControlBits(
127 PIRRX51Hardware &rx51device)
131 // Start off by pushing the lead pulse onto the buffer:
132 buffer = biphaseUnit;
133 bufferContainsPulse = true;
134 bufferContainsSpace = false;
136 CommandSequence::const_iterator i = preData.begin();
138 // Push the first bit:
139 if (i != preData.end())
141 duration += pushBit(*i, rx51device);
145 // Toggle the second bit, if it is time to do so:
146 if (i != preData.end())
148 if (keypressCount % 2)
150 duration += pushBit(!(*i), rx51device);
154 duration += pushBit(*i, rx51device);
160 // Simply push the rest of the bits:
161 while (i != preData.end())
163 pushBit(*i, rx51device);
171 int RC5Protocol::pushKeyCommandBits(
172 const CommandSequence &bits,
173 PIRRX51Hardware &rx51device)
177 // Just push all the bits:
178 CommandSequence::const_iterator i = bits.begin();
179 while (i != bits.end())
181 duration += pushBit(*i, rx51device);
189 int RC5Protocol::pushNonStandardRC5(
190 const CommandSequence &bits,
191 PIRRX51Hardware &rx51device)
195 // Start off by pushing the lead pulse onto the buffer:
196 buffer = biphaseUnit;
197 bufferContainsPulse = true;
198 bufferContainsSpace = false;
200 CommandSequence::const_iterator i = bits.begin();
202 // Push the first bit:
205 duration += pushBit(*i, rx51device);
209 // Toggle the second bit, if it is time to do so:
212 if (keypressCount % 2)
214 duration += pushBit(!(*i), rx51device);
218 duration += pushBit(*i, rx51device);
224 // Simply push the rest of the bits:
225 while (i != bits.end())
227 pushBit(*i, rx51device);
235 int RC5Protocol::pushBit(
237 PIRRX51Hardware &device)
239 unsigned int duration = 0;
240 // RC5 encodes a "0" by using a pulse followed by a space,
241 // and a "1" by using a space followed by a pulse.
245 // We've got a "1". First add a space, then a pulse.
246 if (bufferContainsSpace)
248 // Merge our space with the previous space, and send them to
250 device.addSingle(buffer + biphaseUnit);
251 duration += (buffer + biphaseUnit);
253 bufferContainsSpace = false;
257 if (bufferContainsPulse)
260 device.addSingle(buffer);
263 bufferContainsPulse = false;
266 device.addSingle(biphaseUnit);
267 duration += biphaseUnit;
270 // Put a pulse into the buffer to wait.
271 buffer = biphaseUnit;
272 bufferContainsPulse = true;
276 // We've got a "0". First add a pulse, then a space.
277 if (bufferContainsPulse)
279 // Merge our pulse with the previous one, and send them to the device:
280 device.addSingle(buffer + biphaseUnit);
281 duration += (buffer + biphaseUnit);
283 bufferContainsPulse = false;
287 if (bufferContainsSpace)
289 // Flush out the buffer:
290 device.addSingle(buffer);
293 bufferContainsSpace = false;
297 device.addSingle(biphaseUnit);
298 duration += biphaseUnit;
301 // Put a space into the buffer to wait:
302 buffer = biphaseUnit;
303 bufferContainsSpace = true;