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 QMutexLocker cifLocker(&commandIFMutex);
64 commandInFlight = false;
66 // std::string s = "Tried to send a non-existent command.\n";
67 // throw PIRException(s);
70 // construct the device:
71 PIRRX51Hardware rx51device(carrierFrequency, dutyCycle);
74 int commandDuration = 0;
75 while (repeatCount < MAX_REPEAT_COUNT)
77 commandDuration = generateStandardCommand((*i).second, rx51device);
79 // Now, tell the device to send the whole command:
80 rx51device.sendCommandToDevice();
82 // sleep until the next repetition of command:
83 sleepUntilRepeat(commandDuration);
85 // Check whether we've reached the minimum required number of repetitons:
86 if (repeatCount >= minimumRepetitions)
88 // Check whether we've been asked to stop:
89 if (checkRepeatFlag())
94 QMutexLocker cifLocker(&commandIFMutex);
95 commandInFlight = false;
105 QMutexLocker cifLocker(&commandIFMutex);
106 commandInFlight = false;
108 catch (PIRException e)
111 emit commandFailed(e.getError().c_str());
116 int Nokia32Protocol::generateStandardCommand(
117 const PIRKeyBits &pkb,
118 PIRRX51Hardware &rx51device)
122 // First, the "header" pulse:
123 rx51device.addPair(headerPulse, headerSpace);
124 duration += (headerPulse + headerSpace);
126 // The layout of the Nokia 32 protocol is as follows:
127 // 1) an 8-bit "device code"
128 // 2) an 8-bit "sub-device code"
130 // 4) seven more bits somehow associated with the device
131 // 5) an 8-bit command code.
132 // All are sent in MSB order.
134 // It's a bit of a hack, but I'll store the first 16 bits of address in the
135 // preData, the next 7 bits of address in the postData, and the 8 bits
136 // of command in the firstCode:
138 duration += pushBits(preData, rx51device);
139 duration += pushToggleAndBits(postData, rx51device);
140 duration += pushBits(pkb.firstCode, rx51device);
142 // Finally add the "trail":
143 rx51device.addSingle(trailerPulse);
144 duration += trailerPulse;
150 int Nokia32Protocol::pushBits(
151 const CommandSequence &bits,
152 PIRRX51Hardware &rx51device)
158 CommandSequence::const_iterator i = bits.begin();
159 while (i != bits.end())
163 if (i == bits.end()) break;
166 duration += pushDoubleBit(firstBit, secondBit, rx51device);
175 int Nokia32Protocol::pushToggleAndBits(
176 const CommandSequence &bits,
177 PIRRX51Hardware &rx51device)
183 // The first bit is the toggle bit:
184 if (keypressCount % 2)
193 CommandSequence::const_iterator i = bits.begin();
194 if (i == bits.end()) return 0;
198 duration += pushDoubleBit(firstBit, secondBit, rx51device);
202 while (i != bits.end())
206 if (i == bits.end()) break;
209 duration += pushDoubleBit(firstBit, secondBit, rx51device);
218 int Nokia32Protocol::pushDoubleBit(
221 PIRRX51Hardware &rx51device)
229 // Send the pulse for "Zero":
230 rx51device.addPair(zeroPulse, zeroSpace);
231 duration += (zeroPulse + zeroSpace);
235 // Send the pulse for "One":
236 rx51device.addPair(onePulse, oneSpace);
237 duration += (onePulse + oneSpace);
244 // Send the pulse for "Two":
245 rx51device.addPair(twoPulse, twoSpace);
246 duration += (twoPulse + twoSpace);
250 // Send the pulse for "Three":
251 rx51device.addPair(threePulse, threeSpace);
252 duration += (threePulse + threeSpace);