Advanced Settings Panel
[pierogi] / protocols / daewooprotocol.cpp
1 #include "daewooprotocol.h"
2
3 #include "pirrx51hardware.h"
4
5 #include "pirexception.h"
6
7 // Some global communications stuff:
8 #include <QMutex>
9 extern bool commandInFlight;
10 extern QMutex commandIFMutex;
11
12 // Daewoo is using a protocol similar to NEC, but with the distinction that
13 // it does not send inverted copies of the address and command, and it places
14 // a 550 usec pulse / 2000 usec space between the address and the command.
15 // Here are the fine details:
16 // A "zero" is encoded with a 550 usec pulse, 450 usec space.
17 // A "one" is encoded with a 550 usec pulse, and 1450 usec space.
18 // The header is a 8000 usec pulse, 4000 usec space.
19 // There is a mid-way marker of 550 usec pulse, 2000 usec space.
20 // The pulse train ends with a trailing 550 usec pulse.
21 // The entire train is resent for repeats.
22 // Each command runs for 60000 usec before another can be executed.
23 // The carrier frequency is 38 kHz.
24
25 DaewooProtocol::DaewooProtocol(
26   QObject *guiObject,
27   unsigned int index)
28   : SpaceProtocol(
29       guiObject, index,
30       550, 450,
31       550, 1450,
32       8000, 4000,
33       550,
34       60000, true),
35     midPulse(550),
36     midSpace(2000)
37 {
38 }
39
40
41 void DaewooProtocol::startSendingCommand(
42   unsigned int threadableID,
43   PIRKeyName command)
44 {
45   // Exceptions here are problematic; I'll try to weed them out by putting the
46   // whole thing in a try/catch block:
47   try
48   {
49     // First, check if we are meant to be the recipient of this command:
50     if (threadableID != id) return;
51
52     clearRepeatFlag();
53
54     KeycodeCollection::const_iterator i = keycodes.find(command);
55
56     // Do we even have this key defined?
57     if (i == keycodes.end())
58     {
59       QMutexLocker cifLocker(&commandIFMutex);
60       commandInFlight = false;
61       return;
62 //      std::string s = "Tried to send a non-existent command.\n";
63 //      throw PIRException(s);
64     }
65
66     // construct the device:
67     PIRRX51Hardware rx51device(carrierFrequency, dutyCycle);
68
69     int repeatCount = 0;
70     int commandDuration = 0;
71     while (repeatCount < MAX_REPEAT_COUNT)
72     {
73       commandDuration = generateStandardCommand((*i).second, rx51device);
74
75       // Now, tell the device to send the whole command:
76       rx51device.sendCommandToDevice();
77
78       // sleep until the next repetition of command:
79       sleepUntilRepeat(commandDuration);
80
81       // Check whether we've reached the minimum required number of repetitons:
82       if (repeatCount >= minimumRepetitions)
83       {
84         // Check whether we've been asked to stop:
85         if (checkRepeatFlag())
86         {
87           break;
88 /*
89           QMutexLocker cifLocker(&commandIFMutex);
90           commandInFlight = false;
91           return;
92 */
93         }
94       }
95
96       ++repeatCount;
97     }
98
99     QMutexLocker cifLocker(&commandIFMutex);
100     commandInFlight = false;
101   }
102   catch (PIRException e)
103   {
104     // inform the gui:
105     emit commandFailed(e.getError().c_str());
106   }
107 }
108
109
110 int DaewooProtocol::generateStandardCommand(
111   const PIRKeyBits &pkb,
112   PIRRX51Hardware &rx51device)
113 {
114   int duration = 0;
115
116   // First, the "header" pulse:
117   rx51device.addPair(headerPulse, headerSpace);
118   duration += (headerPulse + headerSpace);
119
120   // The address data:
121   duration += pushReverseBits(preData, rx51device);
122
123   // The Daewoo mid-train marker:
124   rx51device.addPair(midPulse, midSpace);
125   duration += (midPulse + midSpace);
126
127   // The command data:
128   duration += pushReverseBits(pkb.firstCode, rx51device);
129
130   // Finally add the "trail":
131   rx51device.addSingle(trailerPulse);
132   duration += trailerPulse;
133
134   return duration;
135 }
136