Log In
New Account
  
Home My Page Project Cloud Code Snippets Project Openings Pierogi
Summary Forums Tracker Lists Tasks Docs News SCM Files
1 #include "pirprotocol.h"
3 #include <QMutex>
4 #include <QMetaType>
6 #include <time.h>
7 #include <sstream>
8 #include <errno.h>
9 #include "pirexception.h"
11 // A flag for communicating with the main thread:
12 extern bool stopRepeatingFlag;
13 extern QMutex stopRepeatingMutex;
15 // From what I understand (mostly from reading LIRC config files), NEC
16 // protocol based remotes mostly use a frequency of 38000 units and a
17 // duty cycle of 50%.  They'll be set to these defaults here, and overridden
18 // as needed by child classes.
20 PIRProtocol::PIRProtocol(
21   QObject *guiObject,
22   unsigned int index,
23   unsigned int gSpace,
24   bool iclflag)
25   : carrierFrequency(38000),
26     dutyCycle(50),
27     isConstantLength(iclflag),
28     gap(gSpace),
29     minimumRepetitions(0),
30     id(index)
31 {
32   qRegisterMetaType<PIRKeyName>("PIRKeyName");
34   QObject::connect(
35     guiObject,
36     SIGNAL(buttonPressed(unsigned int, PIRKeyName)),
37     this,
38     SLOT(startSendingCommand(unsigned int, PIRKeyName)),
39     Qt::QueuedConnection);
41   QObject::connect(
42     this,
43     SIGNAL(commandFailed(const char *)),
44     guiObject,
45     SLOT(receivedExternalWarning(const char *)),
46     Qt::QueuedConnection);
47 }
50 void PIRProtocol::addKey(
51   PIRKeyName key,
52   unsigned long command,
53   unsigned int bits)
54 {
55   appendToBitSeq(keycodes[key], command, bits);
56 }
59 /*
60 void PIRProtocol::setIndex(
61   unsigned int i)
62 {
63   id = i;
64 }
65 */
68 void PIRProtocol::setCarrierFrequency(
69   unsigned int freq)
70 {
71   carrierFrequency = freq;
72 }
75 void PIRProtocol::setDutyCycle(
76   unsigned int dc)
77 {
78   dutyCycle = dc;
79 }
82 void PIRProtocol::setMinimumRepetitions(
83   unsigned int minrep)
84 {
85   minimumRepetitions = minrep;
86 }
89 bool PIRProtocol::isCommandSupported(
90   PIRKeyName command)
91 {
92   return (keycodes.find(command) != keycodes.end());
93 }
96 void PIRProtocol::appendToBitSeq(
97   CommandSequence &sequence,
98   unsigned int bits,
99   int significantBits)
101   if (significantBits == 0)
102   {
103     // This is bad, but just return silently for now...
104     return;
105   }
107   // For each bit in the char, append a 1 or a 0 into the sequence.
108   // Starting with the largest bit, move forward one bit at a time:
109   unsigned int currentBit = 1 << (significantBits - 1);
111   do
112   {
113     if (bits & currentBit)
114     {
115       sequence.push_back(1);
116     }
117     else
118     {
119       sequence.push_back(0);
120     }
122     currentBit = currentBit >> 1;
123   }
124   while (currentBit > 0);
128 void PIRProtocol::clearRepeatFlag()
130   QMutexLocker locker(&stopRepeatingMutex);
131   stopRepeatingFlag = false;
135 bool PIRProtocol::checkRepeatFlag()
137   QMutexLocker locker(&stopRepeatingMutex);
138   return stopRepeatingFlag;
142 // Note that the following routine blindly sleeps for the amount of time
143 // specified by the LIRC config file.  The extra overhead of processing
144 // each command will mean that repeated commands will overshoot the config
145 // time by some amount.  We could improve accuracy by waiting a little less
146 // than the specified time, if we could get a good handle on how long the
147 // overhead is delaying the command...
148 #define PIEROGI_OVERHEAD_HACK 13260
150 void PIRProtocol::sleepUntilRepeat(
151   int commandDuration)
153   int microseconds;
155   // If the LIRC config file specifies the flag "CONST_LENGTH", that means
156   // the "gap" value is the exact amount of time to wait between kicking off
157   // each command.  If not, then the "gap" needs to be added on to the total
158   // time of the previous command to see how long to sleep.
160   if (isConstantLength)
161   {
162     microseconds = (gap - commandDuration) - PIEROGI_OVERHEAD_HACK;
163   }
164   else
165   {
166     microseconds = gap - PIEROGI_OVERHEAD_HACK;
167   }
169   // Don't even bother sleeping if there's only a few microseconds:
170   if (microseconds < 1000)
171   {
172     return;
173   }
175   timespec sleeptime;
176   sleeptime.tv_sec = 0;
177   sleeptime.tv_nsec = microseconds * 1000;
179   timespec remainingtime;
181   if (nanosleep(&sleeptime, &remainingtime) == -1)
182   {
183     std::stringstream ss;
184     ss << "Problem while sleeping.\n";
185     ss << "Trying to sleep for: " << microseconds << "\n";
186     ss << "Nanosleep returned error: " << strerror(errno) << "\n";
187     throw PIRException(ss.str());
188   }

Terms of Use    Privacy Policy    Contribution Guidelines    Feedback

Powered By GForge Collaborative Development Environment