1 #include "tdcprotocol.h"
3 #include "pirrx51hardware.h"
5 #include "pirexception.h"
8 extern bool commandInFlight;
9 extern QMutex commandIFMutex;
12 // There are apparently two forms of TDC protocol; I'm just focussing on one
13 // for now. As with the Philips protocols, this one is "shift encoded".
14 // The unit biphase pulse length is 315 usec; each command contains 18 bits,
15 // and is followed by an 89000 usec space. The entire pulse train is
16 // re-sent when repeating. The carrier frequency is 38 kHz (the Pierogi
19 // I'm going to count both the "device" and "subdevice" bits as pre-data.
20 // (Both are 5 bits in length.) This may need to be changed...
22 TDCProtocol::TDCProtocol(
25 unsigned int deviceBits,
26 unsigned int subdeviceBits)
27 : PIRProtocol(guiObject, index, 89000, false),
31 // Bit of a hack to get the device and subdevice data in:
32 setPreData(deviceBits, 5);
33 setPostData(subdeviceBits, 5);
37 void TDCProtocol::startSendingCommand(
38 unsigned int threadableID,
41 // Catch any exceptions here before they go up any further:
44 // Check that this command is meant for us:
45 if (threadableID != id) return;
49 KeycodeCollection::const_iterator i = keycodes.find(command);
52 if (i == keycodes.end())
54 QMutexLocker cifLocker(&commandIFMutex);
55 commandInFlight = false;
57 // std::string s = "Tried to send a non-existent command.\n";
58 // throw PIRException(s);
61 // Construct the object that communicates with the device driver:
62 PIRRX51Hardware rx51device(carrierFrequency, dutyCycle);
65 int commandDuration = 0;
66 while (repeatCount < MAX_REPEAT_COUNT)
68 // Construct the actual command string.
69 // The string always starts with a constant "1" bit:
70 commandDuration += pushBit(true, rx51device);
72 // Next, the device bits:
73 commandDuration += pushBits(preData, rx51device);
75 // Then, the subdevice bits:
76 commandDuration += pushBits(postData, rx51device);
78 // Finally, the command bits:
79 commandDuration += pushBits((*i).second.firstCode, rx51device);
81 // Clear out the buffer, if needed:
84 rx51device.addSingle(buffer);
85 commandDuration += buffer;
88 bufferContainsSpace = false;
89 bufferContainsPulse = false;
93 rx51device.sendCommandToDevice();
95 // Sleep for the required amount of time.
96 sleepUntilRepeat(commandDuration);
98 // Check whether we've been told to stop:
99 if (checkRepeatFlag())
104 QMutexLocker cifLocker(&commandIFMutex);
105 commandInFlight = false;
113 QMutexLocker cifLocker(&commandIFMutex);
114 commandInFlight = false;
116 catch (PIRException e)
118 emit commandFailed(e.getError().c_str());
123 int TDCProtocol::pushBits(
124 const CommandSequence &bits,
125 PIRRX51Hardware &rx51device)
129 CommandSequence::const_iterator i = bits.begin();
131 while (i != bits.end())
133 duration += pushBit(*i, rx51device);
141 int TDCProtocol::pushBit(
143 PIRRX51Hardware &device)
145 unsigned int duration = 0;
146 // TDC encodes a "0" by using a space followed by a pulse,
147 // and a "1" by using a pulse followed by a space.
151 // We've got a "1". First add a pulse, then a space.
152 if (bufferContainsPulse)
154 // Merge our pulse with the previous one, and send them to the device:
155 device.addSingle(buffer + biphaseUnit);
156 duration += (buffer + biphaseUnit);
158 bufferContainsPulse = false;
162 if (bufferContainsSpace)
164 // Flush out the buffer:
165 device.addSingle(buffer);
168 bufferContainsSpace = false;
172 device.addSingle(biphaseUnit);
173 duration += biphaseUnit;
176 // Put a space into the buffer to wait:
177 buffer = biphaseUnit;
178 bufferContainsSpace = true;
182 // We've got a "0". First add a space, then a pulse.
183 if (bufferContainsSpace)
185 // Merge our space with the previous space, and send them to
187 device.addSingle(buffer + biphaseUnit);
188 duration += (buffer + biphaseUnit);
190 bufferContainsSpace = false;
194 if (bufferContainsPulse)
197 device.addSingle(buffer);
200 bufferContainsPulse = false;
203 device.addSingle(biphaseUnit);
204 duration += biphaseUnit;
207 // Put a pulse into the buffer to wait.
208 buffer = biphaseUnit;
209 bufferContainsPulse = true;