1 #include "giprotocol.h"
3 #include "pirrx51hardware.h"
5 #include "pirexception.h"
7 // Some global communications stuff:
9 extern bool commandInFlight;
10 extern QMutex commandIFMutex;
12 // This G.I./Motorola protocol appears to have the following specifications:
13 // A "zero" is encoded with a 500 usec pulse, 2250 usec space.
14 // A "one" is encoded with a 500 usec pulse, and 4500 usec space.
15 // The header is a 9000 usec pulse, 4500 usec space.
16 // Commands end with a trailing 500 usec pulse.
17 // A repeat block is a 9000 usec pulse, 2250 usec space, then a trailing pulse.
18 // Each command runs for 100000 usec before another can be executed.
19 // The carrier frequency is 38 kHz.
21 GIProtocol::GIProtocol(
37 void GIProtocol::startSendingCommand(
38 unsigned int threadableID,
41 // Exceptions here are problematic; I'll try to weed them out by putting the
42 // whole thing in a try/catch block:
45 // First, check if we are meant to be the recipient of this command:
46 if (threadableID != id) return;
50 KeycodeCollection::const_iterator i = keycodes.find(command);
52 // Do we even have this key defined?
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 device:
63 PIRRX51Hardware rx51device(carrierFrequency, dutyCycle);
66 int commandDuration = 0;
67 while (repeatCount < MAX_REPEAT_COUNT)
69 // If we are currently repeating, send a repeat block.
72 commandDuration = generateRepeatCommand(rx51device);
76 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())
93 QMutexLocker cifLocker(&commandIFMutex);
94 commandInFlight = false;
103 QMutexLocker cifLocker(&commandIFMutex);
104 commandInFlight = false;
106 catch (PIRException e)
109 emit commandFailed(e.getError().c_str());
114 int GIProtocol::generateStandardCommand(
115 const PIRKeyBits &pkb,
116 PIRRX51Hardware &rx51device)
120 // First, the "header" pulse:
121 rx51device.addPair(headerPulse, headerSpace);
122 duration += (headerPulse + headerSpace);
124 // The GI protocol consists of a 4-bit device code and an 8-bit command.
125 // These are sent in reverse order. Finally, a checksum is added at the
126 // end. I am lacking enough information to calculate the checksum right
127 // now, so I'm going to dump all 16 bits into the "firstCode" in MSB
128 // order, and reverse them here:
130 duration += pushReverseBits(pkb.firstCode, rx51device);
132 // Finally add the "trail":
133 rx51device.addSingle(trailerPulse);
134 duration += trailerPulse;
140 int GIProtocol::generateRepeatCommand(
141 PIRRX51Hardware &rx51device)
145 // Add the repeat pulse:
146 rx51device.addPair(repeatPulse, repeatSpace);
147 duration += (repeatPulse + repeatSpace);
150 rx51device.addSingle(trailerPulse);
151 duration += trailerPulse;