1 #include "aiwaprotocol.h"
3 #include "pirrx51hardware.h"
5 #include "pirexception.h"
8 // Some global communications stuff:
10 extern bool commandInFlight;
11 extern QMutex commandIFMutex;
13 // My information on the Aiwa protocol is that it has the following attributes:
14 // A "zero" is encoded with a 550 usec pulse, 550 usec space.
15 // A "one" is encoded with a 550 usec pulse, 1650 (3 * 550) usec space.
16 // The header has a 8800 usec pulse, 4400 usec space.
17 // There is a 550 usec trailing pulse.
18 // Repeat blocks are 8800 usec pulse, 4400 usec space, then trailing pulse.
19 // Each command lasts for 108000 usec.
20 // Carrier frequency is 38 kHz; I'm using 50% for the duty cycle, for now.
22 AiwaProtocol::AiwaProtocol(
35 setCarrierFrequency(38000);
40 void AiwaProtocol::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;
53 KeycodeCollection::const_iterator i = keycodes.find(command);
55 // Do we even have this key defined?
56 if (i == keycodes.end())
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 the 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())
91 QMutexLocker cifLocker(&commandIFMutex);
92 commandInFlight = false;
100 catch (PIRException e)
103 emit commandFailed(e.getError().c_str());
106 QMutexLocker cifLocker(&commandIFMutex);
107 commandInFlight = false;
111 int AiwaProtocol::generateStandardCommand(
112 const PIRKeyBits &pkb,
113 PIRRX51Hardware &rx51device)
117 // First, the "header" pulse:
118 rx51device.addPair(headerPulse, headerSpace);
119 duration += (headerPulse + headerSpace);
121 // From the information I've got, the "address" portion of the Aiwa protocol
122 // might be split into 8-bit device and 5-bit subdevice subsections, but
123 // for now, I'm just lumping both into a single 13-bit address value.
124 // The command is an 8-bit value.
125 // As with NEC, the address is sent LSB first, then inverted LSB first,
126 // then the command is sent LSB first, then inverted LSB first.
127 duration += pushReverseBits(preData, rx51device);
128 duration += pushInvertedReverseBits(preData, rx51device);
129 duration += pushReverseBits(pkb.firstCode, rx51device);
130 duration += pushInvertedReverseBits(pkb.firstCode, rx51device);
132 // Finally add the "trail":
133 rx51device.addSingle(trailerPulse);
134 duration += trailerPulse;
140 int AiwaProtocol::generateRepeatCommand(
141 PIRRX51Hardware &rx51device)
145 // Add the repeat pulse:
146 rx51device.addPair(repeatPulse, repeatSpace);
147 duration += (repeatPulse + repeatSpace);
149 // Finally add the trailer:
150 rx51device.addSingle(trailerPulse);
151 duration += trailerPulse;