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 while (repeatCount < MAX_REPEAT_COUNT)
63 int commandDuration = 0;
65 // Now, throw together an RC5 protocol command string.
69 // For standard RC5, the "pre-data" contains the control portion,
70 // and the key contains only the 6-bit command portion.
72 // First, construct the control portion:
73 commandDuration += pushControlBits(rx51device);
75 // Next, the key-command portion:
76 commandDuration += pushKeyCommandBits((*i).second, rx51device);
80 // For non-standard RC5, the entire 13 bits are stuffed into the
81 // key portion, as all of them can vary:
82 commandDuration += pushNonStandardRC5((*i).second, rx51device);
85 // Clear out the buffer, if necessary:
88 rx51device.addSingle(buffer);
89 commandDuration += buffer;
91 // probably unnecessary cleanup of buffer:
93 bufferContainsSpace = false;
94 bufferContainsPulse = false;
97 // Now, tell the device to send the whole command:
98 rx51device.sendCommandToDevice();
100 // Sleep for an amount of time. (Need to make this interruptable!)
101 sleepUntilRepeat(commandDuration);
103 // Have we been told to stop yet?
104 if (checkRepeatFlag())
106 // Ok, then we can quit now:
108 QMutexLocker cifLocker(&commandIFMutex);
109 commandInFlight = false;
116 catch (PIRException e)
118 emit commandFailed(e.getError().c_str());
122 QMutexLocker cifLocker(&commandIFMutex);
123 commandInFlight = false;
127 int RC5Protocol::pushControlBits(
128 PIRRX51Hardware &rx51device)
132 // Start off by pushing the lead pulse onto the buffer:
133 buffer = biphaseUnit;
134 bufferContainsPulse = true;
135 bufferContainsSpace = false;
137 CommandSequence::const_iterator i = preData.begin();
139 // Push the first bit:
140 if (i != preData.end())
142 duration += pushBit(*i, rx51device);
146 // Toggle the second bit, if it is time to do so:
147 if (i != preData.end())
149 if (keypressCount % 2)
151 duration += pushBit(!(*i), rx51device);
155 duration += pushBit(*i, rx51device);
161 // Simply push the rest of the bits:
162 while (i != preData.end())
164 pushBit(*i, rx51device);
172 int RC5Protocol::pushKeyCommandBits(
173 const CommandSequence &bits,
174 PIRRX51Hardware &rx51device)
178 // Just push all the bits:
179 CommandSequence::const_iterator i = bits.begin();
180 while (i != bits.end())
182 duration += pushBit(*i, rx51device);
190 int RC5Protocol::pushNonStandardRC5(
191 const CommandSequence &bits,
192 PIRRX51Hardware &rx51device)
196 // Start off by pushing the lead pulse onto the buffer:
197 buffer = biphaseUnit;
198 bufferContainsPulse = true;
199 bufferContainsSpace = false;
201 CommandSequence::const_iterator i = bits.begin();
203 // Push the first bit:
206 duration += pushBit(*i, rx51device);
210 // Toggle the second bit, if it is time to do so:
213 if (keypressCount % 2)
215 duration += pushBit(!(*i), rx51device);
219 duration += pushBit(*i, rx51device);
225 // Simply push the rest of the bits:
226 while (i != bits.end())
228 pushBit(*i, rx51device);
236 int RC5Protocol::pushBit(
238 PIRRX51Hardware &device)
240 unsigned int duration = 0;
241 // RC5 encodes a "0" by using a pulse followed by a space,
242 // and a "1" by using a space followed by a pulse.
246 // We've got a "1". First add a space, then a pulse.
247 if (bufferContainsSpace)
249 // Merge our space with the previous space, and send them to
251 device.addSingle(buffer + biphaseUnit);
252 duration += (buffer + biphaseUnit);
254 bufferContainsSpace = false;
258 if (bufferContainsPulse)
261 device.addSingle(buffer);
264 bufferContainsPulse = false;
267 device.addSingle(biphaseUnit);
268 duration += biphaseUnit;
271 // Put a pulse into the buffer to wait.
272 buffer = biphaseUnit;
273 bufferContainsPulse = true;
277 // We've got a "0". First add a pulse, then a space.
278 if (bufferContainsPulse)
280 // Merge our pulse with the previous one, and send them to the device:
281 device.addSingle(buffer + biphaseUnit);
282 duration += (buffer + biphaseUnit);
284 bufferContainsPulse = false;
288 if (bufferContainsSpace)
290 // Flush out the buffer:
291 device.addSingle(buffer);
294 bufferContainsSpace = false;
298 device.addSingle(biphaseUnit);
299 duration += biphaseUnit;
302 // Put a space into the buffer to wait:
303 buffer = biphaseUnit;
304 bufferContainsSpace = true;