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 QMutexLocker cifLocker(&commandIFMutex);
59 commandInFlight = false;
61 // std::string s = "Tried to send a non-existent command.\n";
62 // throw PIRException(s);
65 // construct the device:
66 PIRRX51Hardware rx51device(carrierFrequency, dutyCycle);
69 int commandDuration = 0;
70 while (repeatCount < MAX_REPEAT_COUNT)
72 // If we are currently repeating, send the repeat block:
75 commandDuration = generateRepeatCommand(rx51device);
79 commandDuration = generateStandardCommand((*i).second, rx51device);
82 // Now, tell the device to send the whole command:
83 rx51device.sendCommandToDevice();
85 // sleep until the next repetition of command:
86 sleepUntilRepeat(commandDuration);
88 // Check whether we've reached the minimum required number of repetitons:
89 if (repeatCount >= minimumRepetitions)
91 // Check whether we've been asked to stop:
92 if (checkRepeatFlag())
96 QMutexLocker cifLocker(&commandIFMutex);
97 commandInFlight = false;
106 QMutexLocker cifLocker(&commandIFMutex);
107 commandInFlight = false;
109 catch (PIRException e)
112 emit commandFailed(e.getError().c_str());
117 int AiwaProtocol::generateStandardCommand(
118 const PIRKeyBits &pkb,
119 PIRRX51Hardware &rx51device)
123 // First, the "header" pulse:
124 rx51device.addPair(headerPulse, headerSpace);
125 duration += (headerPulse + headerSpace);
127 // From the information I've got, the "address" portion of the Aiwa protocol
128 // might be split into 8-bit device and 5-bit subdevice subsections, but
129 // for now, I'm just lumping both into a single 13-bit address value.
130 // The command is an 8-bit value.
131 // As with NEC, the address is sent LSB first, then inverted LSB first,
132 // then the command is sent LSB first, then inverted LSB first.
133 duration += pushReverseBits(preData, rx51device);
134 duration += pushInvertedReverseBits(preData, rx51device);
135 duration += pushReverseBits(pkb.firstCode, rx51device);
136 duration += pushInvertedReverseBits(pkb.firstCode, rx51device);
138 // Finally add the "trail":
139 rx51device.addSingle(trailerPulse);
140 duration += trailerPulse;
146 int AiwaProtocol::generateRepeatCommand(
147 PIRRX51Hardware &rx51device)
151 // Add the repeat pulse:
152 rx51device.addPair(repeatPulse, repeatSpace);
153 duration += (repeatPulse + repeatSpace);
155 // Finally add the trailer:
156 rx51device.addSingle(trailerPulse);
157 duration += trailerPulse;