1 #include "sharpprotocol.h"
3 #include "pirexception.h"
7 // Some global communications stuff:
9 extern bool commandInFlight;
10 extern QMutex commandIFMutex;
12 // Sharp's protocol should have the following attributes:
13 // A "zero" is encoded with a 320 usec pulse, 680 usec space.
14 // A "one" is encoded with a 320 usec pulse, and 1680 usec space.
15 // There is no header pulse.
16 // The pulse train ends with a trailing 320 usec pulse.
17 // For repeating, the entire train is re-sent, except that the command
18 // section (and the last two bits) are inverted in each odd repeat.
19 // There is a 40000 usec delay between the end of one command and the start
21 // The command should be repeated at least once.
22 // The carrier frequency is 38 kHz, duty cycle is 1/3.
24 SharpProtocol::SharpProtocol(
28 : PIRProtocol(guiObject, index, 40000, false),
36 setCarrierFrequency(38000);
41 void SharpProtocol::startSendingCommand(
42 unsigned int threadableID,
45 // Exceptions here are problematic; I'll try to weed them out by putting the
46 // whole thing in a try/catch block:
49 // First, check if we are meant to be the recipient of this command:
50 if (threadableID != id) return;
54 KeycodeCollection::const_iterator i = keycodes.find(command);
56 // Do we even have this key defined?
57 if (i == keycodes.end())
59 std::string s = "Tried to send a non-existent command.\n";
60 throw PIRException(s);
63 // construct the device:
64 PIRRX51Hardware rx51device(carrierFrequency, dutyCycle);
67 int commandDuration = 0;
68 while (repeatCount < MAX_REPEAT_COUNT)
70 // Every other repeat count, we invert everything but the address:
73 commandDuration = generateToggledCommand((*i).second, rx51device);
77 commandDuration = generateStandardCommand((*i).second, rx51device);
80 // Now, tell the device to send the whole command:
81 rx51device.sendCommandToDevice();
83 // sleep until the next repetition of command:
84 sleepUntilRepeat(commandDuration);
86 // Check whether we've reached the minimum required number of repetitons:
87 // if (repeatCount >= minimumRepetitions)
90 // Check whether we've been asked to stop:
91 if (checkRepeatFlag())
93 QMutexLocker cifLocker(&commandIFMutex);
94 commandInFlight = false;
102 catch (PIRException e)
105 emit commandFailed(e.getError().c_str());
108 QMutexLocker cifLocker(&commandIFMutex);
109 commandInFlight = false;
113 int SharpProtocol::generateStandardCommand(
114 const CommandSequence &bits,
115 PIRRX51Hardware &rx51device)
119 // Right now, I've got both the 5-bit address and the 8-bit command
120 // smushed together into the command sequence. Need to pick each of
121 // these out and reverse their bits:
123 // First, push the address:
125 CommandSequence::const_reverse_iterator addressStart = bits.rbegin();
126 // Move past the command's 8 bits:
128 duration += pushBits(addressStart, bits.rend(), rx51device);
130 // Next, push the command:
131 CommandSequence::const_reverse_iterator commandEnd = bits.rbegin();
132 // Again, move past the commands's 8 bits:
134 duration += pushBits(bits.rbegin(), commandEnd, rx51device);
136 // Next, there is an "expansion" bit and a "check" bit. Not entirely sure
137 // what these two do. The check bit is fixed at "1".
140 rx51device.addPair(onePulse, oneSpace);
141 duration += (onePulse + oneSpace);
145 rx51device.addPair(zeroPulse, zeroSpace);
146 duration += (zeroPulse + zeroSpace);
149 rx51device.addPair(zeroPulse, zeroSpace);
150 duration += (zeroPulse + zeroSpace);
152 // Finally add the "trail":
153 rx51device.addSingle(trailerPulse);
154 duration += trailerPulse;
160 // This is the same as the standard command, except all bits but the address
162 int SharpProtocol::generateToggledCommand(
163 const CommandSequence &bits,
164 PIRRX51Hardware &rx51device)
168 CommandSequence::const_reverse_iterator addressStart = bits.rbegin();
170 duration += pushBits(addressStart, bits.rend(), rx51device);
172 CommandSequence::const_reverse_iterator commandEnd = bits.rbegin();
174 // This time we invert the bits:
175 duration += pushInvertedBits(bits.rbegin(), commandEnd, rx51device);
177 // We'll also invert the two administrative bits here:
180 rx51device.addPair(zeroPulse, zeroSpace);
181 duration += (zeroPulse + zeroSpace);
185 rx51device.addPair(onePulse, oneSpace);
186 duration += (onePulse + oneSpace);
189 rx51device.addPair(onePulse, oneSpace);
190 duration += (onePulse + oneSpace);
193 rx51device.addSingle(trailerPulse);
194 duration += trailerPulse;
200 int SharpProtocol::pushBits(
201 CommandSequence::const_reverse_iterator i,
202 CommandSequence::const_reverse_iterator end,
203 PIRRX51Hardware &rx51device)
211 // Send the pulse for "One":
212 rx51device.addPair(onePulse, oneSpace);
213 duration += (onePulse + oneSpace);
217 // Send the pulse for "Zero":
218 rx51device.addPair(zeroPulse, zeroSpace);
219 duration += (zeroPulse + zeroSpace);
228 int SharpProtocol::pushInvertedBits(
229 CommandSequence::const_reverse_iterator i,
230 CommandSequence::const_reverse_iterator end,
231 PIRRX51Hardware &rx51device)
239 // Send the pulse for "Zero":
240 rx51device.addPair(zeroPulse, zeroSpace);
241 duration += (zeroPulse + zeroSpace);
245 // Send the pulse for "One":
246 rx51device.addPair(onePulse, oneSpace);
247 duration += (onePulse + oneSpace);