1 #include "rcaprotocol.h"
3 #include "pirrx51hardware.h"
4 #include "pirexception.h"
6 // Some global communications stuff:
8 extern bool commandInFlight;
9 extern QMutex commandIFMutex;
11 // I've found no official data on the RCA protocol yet, but from available
12 // notes and guesswork I'm using the following:
13 // A "zero" is encoded with a 500 usec pulse, 1000 usec space.
14 // A "one" is encoded with a 500 usec pulse, and 2000 usec space.
15 // The header is a 4000 usec pulse, 4000 usec space.
16 // Commands end with a trailing 500 usec pulse.
17 // When holding down a button, the entire command is repeated.
18 // Commands are repeated every 64000 usec.
20 // Each RCA word consists of 4 bits of address data and 8 bits of command data.
21 // The address is sent first, in order of most significant bit to least,
22 // followed by the command, also MSB to LSB. Then, the same data is sent
23 // again, but with all the bits inverted. (This is a bit different from
24 // how the NEC protocol does things.)
26 RCAProtocol::RCAProtocol(
40 void RCAProtocol::startSendingCommand(
41 unsigned int threadableID,
44 // Exceptions here are problematic; I'll try to weed them out by putting the
45 // whole thing in a try/catch block:
48 // First, check if we are meant to be the recipient of this command:
49 if (threadableID != id) return;
51 // An object that helps keep track of the number of commands:
52 // PIRCommandCounter commandCounter;
54 // Ok, we're going to lock down this method and make sure
55 // only one guy at a time passes this point:
56 // QMutexLocker commandLocker(&commandMutex);
60 KeycodeCollection::const_iterator i = keycodes.find(command);
62 // Do we even have this key defined?
63 if (i == keycodes.end())
65 QMutexLocker cifLocker(&commandIFMutex);
66 commandInFlight = false;
68 // std::string s = "Tried to send a non-existent command.\n";
69 // throw PIRException(s);
72 // construct the device:
73 PIRRX51Hardware rx51device(carrierFrequency, dutyCycle);
76 int commandDuration = 0;
77 while (repeatCount < MAX_REPEAT_COUNT)
79 commandDuration = generateStandardCommand((*i).second, rx51device);
81 // Now, tell the device to send the whole command:
82 rx51device.sendCommandToDevice();
84 // sleep until the next repetition of command:
85 sleepUntilRepeat(commandDuration);
87 // Check whether we've reached the minimum required number of repetitons:
88 if (repeatCount >= minimumRepetitions)
90 // Check whether we've been asked to stop:
91 if (checkRepeatFlag())
95 QMutexLocker cifLocker(&commandIFMutex);
96 commandInFlight = false;
105 QMutexLocker cifLocker(&commandIFMutex);
106 commandInFlight = false;
108 catch (PIRException e)
111 emit commandFailed(e.getError().c_str());
116 int RCAProtocol::generateStandardCommand(
117 const PIRKeyBits &pkb,
118 PIRRX51Hardware &rx51device)
122 // First, the "header" pulse:
123 rx51device.addPair(headerPulse, headerSpace);
124 duration += (headerPulse + headerSpace);
126 // Now, set up the address and command bits:
127 duration += pushBits(preData, rx51device);
128 duration += pushBits(pkb.firstCode, rx51device);
129 duration += pushInvertedBits(preData, rx51device);
130 duration += pushInvertedBits(pkb.firstCode, rx51device);
132 // Finally add the "trail":
133 rx51device.addSingle(trailerPulse);
134 duration += trailerPulse;