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 std::string s = "Tried to send a non-existent command.\n";
56 throw PIRException(s);
59 // Construct the object that communicates with the device driver:
60 PIRRX51Hardware rx51device(carrierFrequency, dutyCycle);
63 int commandDuration = 0;
64 while (repeatCount < MAX_REPEAT_COUNT)
66 // Now, throw together an RC5 protocol command string.
70 // For standard RC5, the "pre-data" contains the control portion,
71 // and the key contains only the 6-bit command portion.
73 // First, construct the control portion:
74 commandDuration += pushControlBits(rx51device);
76 // Next, the key-command portion:
77 commandDuration += pushKeyCommandBits((*i).second, rx51device);
81 // For non-standard RC5, the entire 13 bits are stuffed into the
82 // key portion, as all of them can vary:
83 commandDuration += pushNonStandardRC5((*i).second, rx51device);
86 // Clear out the buffer, if necessary:
89 rx51device.addSingle(buffer);
90 commandDuration += buffer;
92 // probably unnecessary cleanup of buffer:
94 bufferContainsSpace = false;
95 bufferContainsPulse = false;
98 // Now, tell the device to send the whole command:
99 rx51device.sendCommandToDevice();
101 // Sleep for an amount of time. (Need to make this interruptable!)
102 sleepUntilRepeat(commandDuration);
104 // Have we been told to stop yet?
105 if (checkRepeatFlag())
107 // Ok, then we can quit now:
109 QMutexLocker cifLocker(&commandIFMutex);
110 commandInFlight = false;
117 catch (PIRException e)
119 emit commandFailed(e.getError().c_str());
123 QMutexLocker cifLocker(&commandIFMutex);
124 commandInFlight = false;
128 int RC5Protocol::pushControlBits(
129 PIRRX51Hardware &rx51device)
133 // Start off by pushing the lead pulse onto the buffer:
134 buffer = biphaseUnit;
135 bufferContainsPulse = true;
136 bufferContainsSpace = false;
138 CommandSequence::const_iterator i = preData.begin();
140 // Push the first bit:
141 if (i != preData.end())
143 duration += pushBit(*i, rx51device);
147 // Toggle the second bit, if it is time to do so:
148 if (i != preData.end())
150 if (keypressCount % 2)
152 duration += pushBit(!(*i), rx51device);
156 duration += pushBit(*i, rx51device);
162 // Simply push the rest of the bits:
163 while (i != preData.end())
165 pushBit(*i, rx51device);
173 int RC5Protocol::pushKeyCommandBits(
174 const PIRKeyBits &pkb,
175 PIRRX51Hardware &rx51device)
179 // Just push all the bits:
180 CommandSequence::const_iterator i = pkb.firstCode.begin();
181 while (i != pkb.firstCode.end())
183 duration += pushBit(*i, rx51device);
191 int RC5Protocol::pushNonStandardRC5(
192 const PIRKeyBits &pkb,
193 PIRRX51Hardware &rx51device)
197 // Start off by pushing the lead pulse onto the buffer:
198 buffer = biphaseUnit;
199 bufferContainsPulse = true;
200 bufferContainsSpace = false;
202 CommandSequence::const_iterator i = pkb.firstCode.begin();
204 // Push the first bit:
205 if (i != pkb.firstCode.end())
207 duration += pushBit(*i, rx51device);
211 // Toggle the second bit, if it is time to do so:
212 if (i != pkb.firstCode.end())
214 if (keypressCount % 2)
216 duration += pushBit(!(*i), rx51device);
220 duration += pushBit(*i, rx51device);
226 // Simply push the rest of the bits:
227 while (i != pkb.firstCode.end())
229 pushBit(*i, rx51device);
237 int RC5Protocol::pushBit(
239 PIRRX51Hardware &device)
241 unsigned int duration = 0;
242 // RC5 encodes a "0" by using a pulse followed by a space,
243 // and a "1" by using a space followed by a pulse.
247 // We've got a "1". First add a space, then a pulse.
248 if (bufferContainsSpace)
250 // Merge our space with the previous space, and send them to
252 device.addSingle(buffer + biphaseUnit);
253 duration += (buffer + biphaseUnit);
255 bufferContainsSpace = false;
259 if (bufferContainsPulse)
262 device.addSingle(buffer);
265 bufferContainsPulse = false;
268 device.addSingle(biphaseUnit);
269 duration += biphaseUnit;
272 // Put a pulse into the buffer to wait.
273 buffer = biphaseUnit;
274 bufferContainsPulse = true;
278 // We've got a "0". First add a pulse, then a space.
279 if (bufferContainsPulse)
281 // Merge our pulse with the previous one, and send them to the device:
282 device.addSingle(buffer + biphaseUnit);
283 duration += (buffer + biphaseUnit);
285 bufferContainsPulse = false;
289 if (bufferContainsSpace)
291 // Flush out the buffer:
292 device.addSingle(buffer);
295 bufferContainsSpace = false;
299 device.addSingle(biphaseUnit);
300 duration += biphaseUnit;
303 // Put a space into the buffer to wait:
304 buffer = biphaseUnit;
305 bufferContainsSpace = true;