1 #include "nokia32protocol.h"
3 #include "pirrx51hardware.h"
5 #include "pirexception.h"
7 // Some global communications stuff:
9 extern bool commandInFlight;
10 extern QMutex commandIFMutex;
12 // The Nokia 32 protocol has a 2-bit space encoding system, and appears to
14 // A "zero" is encoded with a 164 usec pulse, 276 usec space.
15 // A "one" is encoded with a 164 usec pulse, 445 usec space.
16 // A "two" is encoded with a 164 usec pulse, 614 usec space.
17 // A "three" is encoded with a 164 usec pulse, 783 usec space.
18 // The header is a 412 usec pulse, 276 usec space.
19 // Commands end with a trailing 164 usec pulse.
20 // The entire pulse train is re-sent when repeating.
21 // There is a 100000 usec gap between commands. (? not sure here)
22 // The carrier frequency is presumably 36 kHz.
23 // The duty cycle is presumably 1/3.
25 Nokia32Protocol::Nokia32Protocol(
28 : PIRProtocol(guiObject, index, 100000, false),
45 void Nokia32Protocol::startSendingCommand(
46 unsigned int threadableID,
49 // Exceptions here are problematic; I'll try to weed them out by putting the
50 // whole thing in a try/catch block:
53 // First, check if we are meant to be the recipient of this command:
54 if (threadableID != id) return;
58 KeycodeCollection::const_iterator i = keycodes.find(command);
60 // Do we even have this key defined?
61 if (i == keycodes.end())
63 std::string s = "Tried to send a non-existent command.\n";
64 throw PIRException(s);
67 // construct the device:
68 PIRRX51Hardware rx51device(carrierFrequency, dutyCycle);
71 int commandDuration = 0;
72 while (repeatCount < MAX_REPEAT_COUNT)
74 commandDuration = generateStandardCommand((*i).second, rx51device);
76 // Now, tell the device to send the whole command:
77 rx51device.sendCommandToDevice();
79 // sleep until the next repetition of command:
80 sleepUntilRepeat(commandDuration);
82 // Check whether we've reached the minimum required number of repetitons:
83 if (repeatCount >= minimumRepetitions)
85 // Check whether we've been asked to stop:
86 if (checkRepeatFlag())
88 QMutexLocker cifLocker(&commandIFMutex);
89 commandInFlight = false;
98 catch (PIRException e)
101 emit commandFailed(e.getError().c_str());
104 QMutexLocker cifLocker(&commandIFMutex);
105 commandInFlight = false;
110 int Nokia32Protocol::generateStandardCommand(
111 const PIRKeyBits &pkb,
112 PIRRX51Hardware &rx51device)
116 // First, the "header" pulse:
117 rx51device.addPair(headerPulse, headerSpace);
118 duration += (headerPulse + headerSpace);
120 // The layout of the Nokia 32 protocol is as follows:
121 // 1) an 8-bit "device code"
122 // 2) an 8-bit "sub-device code"
124 // 4) seven more bits somehow associated with the device
125 // 5) an 8-bit command code.
126 // All are sent in MSB order.
128 // It's a bit of a hack, but I'll store the first 16 bits of address in the
129 // preData, the next 7 bits of address in the postData, and the 8 bits
130 // of command in the firstCode:
132 duration += pushBits(preData, rx51device);
133 duration += pushToggleAndBits(postData, rx51device);
134 duration += pushBits(pkb.firstCode, rx51device);
136 // Finally add the "trail":
137 rx51device.addSingle(trailerPulse);
138 duration += trailerPulse;
144 int Nokia32Protocol::pushBits(
145 const CommandSequence &bits,
146 PIRRX51Hardware &rx51device)
152 CommandSequence::const_iterator i = bits.begin();
153 while (i != bits.end())
157 if (i == bits.end()) break;
160 duration += pushDoubleBit(firstBit, secondBit, rx51device);
169 int Nokia32Protocol::pushToggleAndBits(
170 const CommandSequence &bits,
171 PIRRX51Hardware &rx51device)
177 // The first bit is the toggle bit:
178 if (keypressCount % 2)
187 CommandSequence::const_iterator i = bits.begin();
188 if (i == bits.end()) return 0;
192 duration += pushDoubleBit(firstBit, secondBit, rx51device);
196 while (i != bits.end())
200 if (i == bits.end()) break;
203 duration += pushDoubleBit(firstBit, secondBit, rx51device);
212 int Nokia32Protocol::pushDoubleBit(
215 PIRRX51Hardware &rx51device)
223 // Send the pulse for "Zero":
224 rx51device.addPair(zeroPulse, zeroSpace);
225 duration += (zeroPulse + zeroSpace);
229 // Send the pulse for "One":
230 rx51device.addPair(onePulse, oneSpace);
231 duration += (onePulse + oneSpace);
238 // Send the pulse for "Two":
239 rx51device.addPair(twoPulse, twoSpace);
240 duration += (twoPulse + twoSpace);
244 // Send the pulse for "Three":
245 rx51device.addPair(threePulse, threeSpace);
246 duration += (threePulse + threeSpace);