1 #include "rc5protocol.h"
3 #include "pirrx51hardware.h"
5 #include "pirexception.h"
8 extern bool commandInFlight;
9 extern QMutex commandIFMutex;
11 RC5Protocol::RC5Protocol(
14 unsigned int sevenBitControl)
15 : PIRProtocol(guiObject, index, 114000, true),
20 setCarrierFrequency(36000);
21 setPreData(sevenBitControl, 7);
25 RC5Protocol::RC5Protocol(
28 : PIRProtocol(guiObject, index, 114000, true),
33 setCarrierFrequency(36000);
37 void RC5Protocol::startSendingCommand(
38 unsigned int threadableID,
41 // Dumping entire method inside of try/catch, to deal with cross-thread
42 // exception handling:
45 // Check if this command is meant for us:
46 if (threadableID != id) return;
50 KeycodeCollection::const_iterator i = keycodes.find(command);
52 // Sanity check, make sure command exists first:
53 if (i == keycodes.end())
55 QMutexLocker cifLocker(&commandIFMutex);
56 commandInFlight = false;
58 // std::string s = "Tried to send a non-existent command.\n";
59 // throw PIRException(s);
62 // Construct the object that communicates with the device driver:
63 PIRRX51Hardware rx51device(carrierFrequency, dutyCycle);
66 int commandDuration = 0;
67 while (repeatCount < MAX_REPEAT_COUNT)
69 // Now, throw together an RC5 protocol command string.
73 // For standard RC5, the "pre-data" contains the control portion,
74 // and the key contains only the 6-bit command portion.
76 // First, construct the control portion:
77 commandDuration += pushControlBits(rx51device);
79 // Next, the key-command portion:
80 commandDuration += pushKeyCommandBits((*i).second, rx51device);
84 // For non-standard RC5, the entire 13 bits are stuffed into the
85 // key portion, as all of them can vary:
86 commandDuration += pushNonStandardRC5((*i).second, rx51device);
89 // Clear out the buffer, if necessary:
92 rx51device.addSingle(buffer);
93 commandDuration += buffer;
95 // probably unnecessary cleanup of buffer:
97 bufferContainsSpace = false;
98 bufferContainsPulse = false;
101 // Now, tell the device to send the whole command:
102 rx51device.sendCommandToDevice();
104 // Sleep for an amount of time. (Need to make this interruptable!)
105 sleepUntilRepeat(commandDuration);
107 // Have we been told to stop yet?
108 if (checkRepeatFlag())
112 // Ok, then we can quit now:
114 QMutexLocker cifLocker(&commandIFMutex);
115 commandInFlight = false;
124 QMutexLocker cifLocker(&commandIFMutex);
125 commandInFlight = false;
127 catch (PIRException e)
129 emit commandFailed(e.getError().c_str());
134 int RC5Protocol::pushControlBits(
135 PIRRX51Hardware &rx51device)
139 // Start off by pushing the lead pulse onto the buffer:
140 buffer = biphaseUnit;
141 bufferContainsPulse = true;
142 bufferContainsSpace = false;
144 CommandSequence::const_iterator i = preData.begin();
146 // Push the first bit:
147 if (i != preData.end())
149 duration += pushBit(*i, rx51device);
153 // Toggle the second bit, if it is time to do so:
154 if (i != preData.end())
156 if (keypressCount % 2)
158 duration += pushBit(!(*i), rx51device);
162 duration += pushBit(*i, rx51device);
168 // Simply push the rest of the bits:
169 while (i != preData.end())
171 duration += pushBit(*i, rx51device);
179 int RC5Protocol::pushKeyCommandBits(
180 const PIRKeyBits &pkb,
181 PIRRX51Hardware &rx51device)
185 // Just push all the bits:
186 CommandSequence::const_iterator i = pkb.firstCode.begin();
187 while (i != pkb.firstCode.end())
189 duration += pushBit(*i, rx51device);
197 int RC5Protocol::pushNonStandardRC5(
198 const PIRKeyBits &pkb,
199 PIRRX51Hardware &rx51device)
203 // Start off by pushing the lead pulse onto the buffer:
204 buffer = biphaseUnit;
205 bufferContainsPulse = true;
206 bufferContainsSpace = false;
208 CommandSequence::const_iterator i = pkb.firstCode.begin();
210 // Push the first bit:
211 if (i != pkb.firstCode.end())
213 duration += pushBit(*i, rx51device);
217 // Toggle the second bit, if it is time to do so:
218 if (i != pkb.firstCode.end())
220 if (keypressCount % 2)
222 duration += pushBit(!(*i), rx51device);
226 duration += pushBit(*i, rx51device);
232 // Simply push the rest of the bits:
233 while (i != pkb.firstCode.end())
235 duration += pushBit(*i, rx51device);
243 int RC5Protocol::pushBit(
245 PIRRX51Hardware &device)
247 unsigned int duration = 0;
248 // RC5 encodes a "0" by using a pulse followed by a space,
249 // and a "1" by using a space followed by a pulse.
253 // We've got a "1". First add a space, then a pulse.
254 if (bufferContainsSpace)
256 // Merge our space with the previous space, and send them to
258 device.addSingle(buffer + biphaseUnit);
259 duration += (buffer + biphaseUnit);
261 bufferContainsSpace = false;
265 if (bufferContainsPulse)
268 device.addSingle(buffer);
271 bufferContainsPulse = false;
274 device.addSingle(biphaseUnit);
275 duration += biphaseUnit;
278 // Put a pulse into the buffer to wait.
279 buffer = biphaseUnit;
280 bufferContainsPulse = true;
284 // We've got a "0". First add a pulse, then a space.
285 if (bufferContainsPulse)
287 // Merge our pulse with the previous one, and send them to the device:
288 device.addSingle(buffer + biphaseUnit);
289 duration += (buffer + biphaseUnit);
291 bufferContainsPulse = false;
295 if (bufferContainsSpace)
297 // Flush out the buffer:
298 device.addSingle(buffer);
301 bufferContainsSpace = false;
305 device.addSingle(biphaseUnit);
306 duration += biphaseUnit;
309 // Put a space into the buffer to wait:
310 buffer = biphaseUnit;
311 bufferContainsSpace = true;