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 std::string s = "Tried to send a non-existent command.\n";
56 throw PIRException(s);
59 // construct the device:
60 PIRRX51Hardware rx51device(carrierFrequency, dutyCycle);
63 int commandDuration = 0;
64 while (repeatCount < MAX_REPEAT_COUNT)
66 // If we are currently repeating, send a repeat block.
69 commandDuration = generateRepeatCommand(rx51device);
73 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;
97 catch (PIRException e)
100 emit commandFailed(e.getError().c_str());
103 QMutexLocker cifLocker(&commandIFMutex);
104 commandInFlight = false;
108 int GIProtocol::generateStandardCommand(
109 const PIRKeyBits &pkb,
110 PIRRX51Hardware &rx51device)
114 // First, the "header" pulse:
115 rx51device.addPair(headerPulse, headerSpace);
116 duration += (headerPulse + headerSpace);
118 // The GI protocol consists of a 4-bit device code and an 8-bit command.
119 // These are sent in reverse order. Finally, a checksum is added at the
120 // end. I am lacking enough information to calculate the checksum right
121 // now, so I'm going to dump all 16 bits into the "firstCode" in MSB
122 // order, and reverse them here:
124 duration += pushReverseBits(pkb.firstCode, rx51device);
126 // Finally add the "trail":
127 rx51device.addSingle(trailerPulse);
128 duration += trailerPulse;
134 int GIProtocol::generateRepeatCommand(
135 PIRRX51Hardware &rx51device)
139 // Add the repeat pulse:
140 rx51device.addPair(repeatPulse, repeatSpace);
141 duration += (repeatPulse + repeatSpace);
144 rx51device.addSingle(trailerPulse);
145 duration += trailerPulse;