Improved Keyset Selection Window
[pierogi] / pirrx51hardware.cpp
1 #include "pirrx51hardware.h"
2
3 //#define DEBUGGING
4
5 // Needed system includes:
6 #include <sys/ioctl.h>
7 #ifdef DEBUGGING
8 #include <iostream>
9 #include <sys/time.h>
10 timeval previousTime;
11 #else
12 //#ifndef DEBUGGING
13 #include <linux/types.h>
14 #include <linux/ioctl.h>
15 #endif // DEBUGGING
16 #include <fcntl.h>
17
18 // Includes I'm using for error handling stuff:
19 #include "pirexception.h"
20 #include <errno.h>
21 #include <sstream>
22
23 // The N900's IR transmitter is controlled by a device driver created
24 // specifically for the LIRC daemon:
25 #define PATH_TO_LIRC_DEVICE "/dev/lirc0"
26
27 // It appears that the frequency on this device can range between
28 // 20000 on the low end and 500000 on the high end...
29 // 38000 is the default for LIRC:
30 //#define DEFAULT_FREQUENCY 38000
31
32 // The duty cycle is a percentage (0-100), 50 is LIRC's default:
33 //#define DEFAULT_DUTY_CYCLE 50
34
35
36 PIRRX51Hardware::PIRRX51Hardware()
37   : fileDescriptor(-1),
38     index(0)
39 {
40   openLircDevice();
41 }
42
43
44 PIRRX51Hardware::PIRRX51Hardware(
45   unsigned int frequency,
46   unsigned int dutyCycle)
47   : fileDescriptor(-1),
48     index(0)
49 {
50   openLircDevice();
51   setCarrierFrequency(frequency);
52   setDutyCycle(dutyCycle);
53 }
54
55
56 PIRRX51Hardware::~PIRRX51Hardware()
57 {
58   if (fileDescriptor >= 0) close(fileDescriptor);
59 }
60
61
62 void PIRRX51Hardware::openLircDevice()
63 {
64 #ifdef DEBUGGING
65   // check the current time:
66   gettimeofday(&previousTime, NULL);
67 #else
68 //#ifndef DEBUGGING
69   fileDescriptor = open(PATH_TO_LIRC_DEVICE, O_WRONLY);
70
71   if (fileDescriptor == -1)
72   {
73     std::stringstream ss;
74     ss << "Failed to connect to " << PATH_TO_LIRC_DEVICE << "\n";
75     ss << "Error is " << strerror(errno) << "\n";
76     throw PIRException(ss.str());
77   }
78 #endif // DEBUGGING
79 }
80
81
82 void PIRRX51Hardware::addPair(
83   int pulse,
84   int space)
85 {
86   if (index >= (BUFFER_SIZE - 1))
87   {
88     // Needed room for 2 ints, didn't have it.
89     throw PIRException("Buffer overflow in PIRCommandBuffer object.\n");
90   }
91
92   buffer[index] = pulse;
93   ++index;
94   buffer[index] = space;
95   ++index;
96 }
97
98
99 void PIRRX51Hardware::addSingle(
100   int single)
101 {
102   if (index >= BUFFER_SIZE)
103   {
104     throw PIRException("Buffer overflow in PIRCommandBuffer object.\n");
105   }
106
107   buffer[index] = single;
108   ++index;
109 }
110
111
112 void PIRRX51Hardware::sendCommandToDevice()
113 {
114   // Sanity check first:
115   if (!index)
116   {
117     // We have no data!
118     // We should probably complain here, but for now, just return.
119     return;
120   }
121
122   // Note: if the generated command string ends on a "space", we'll just
123   // go ahead and ignore that last value.  Want the light switched off
124   // permanently at the end of the command string, not temporarily.
125   // So, only odd-numbered strings of commands are allowed:
126   if ((index % 2) == 0)
127   {
128     --index;
129   }
130
131 #ifdef DEBUGGING
132   timeval newTime;
133   gettimeofday(&newTime, NULL);
134   long microseconds = newTime.tv_usec - previousTime.tv_usec;
135   microseconds += (newTime.tv_sec - previousTime.tv_sec) * 1000000;
136   std::cout << "Time since last call to device: " << microseconds << std::endl;
137   previousTime = newTime;
138 //#ifdef DEBUGGING
139   std::cout << "Sending array of ints to device:\n";
140   int blah = 0;
141   while (blah < index)
142   {
143     std::cout << "buffer[" << blah << "]: " << buffer[blah] << "\n";
144     ++blah;
145   }
146   std::cout << std::endl;
147 #else
148   if (write(fileDescriptor, buffer, index * sizeof(int)) == -1)
149   {
150     std::stringstream ss;
151     ss << "Failed to send command.\n";
152     ss << "IR device returned error: " << strerror(errno) << "\n";
153     throw PIRException(ss.str());
154   }
155 #endif // DEBUGGING
156
157   // Reset the index:
158   index = 0;
159 }
160
161
162 void PIRRX51Hardware::setCarrierFrequency(
163   unsigned int frequency)
164 {
165 //  if (!frequency) frequency = DEFAULT_FREQUENCY;
166
167 #ifdef DEBUGGING
168   std::cout << "Setting frequency to " << frequency << "\n";
169 #else
170   if (ioctl(fileDescriptor, _IOW('i', 0x13, __u32), &frequency) == -1)
171   {
172     std::stringstream ss;
173     ss << "Failed to set carrier frequency.\n";
174     ss << "IR device returned error: " << strerror(errno) << "\n";
175     throw PIRException(ss.str());
176   }
177 #endif // DEBUGGING
178 }
179
180
181 void PIRRX51Hardware::setDutyCycle(
182   unsigned int dutyCycle)
183 {
184 //  if (dutyCycle > 100) dutyCycle = DEFAULT_DUTY_CYCLE;
185
186 #ifdef DEBUGGING
187   std::cout << "Setting duty cycle to " << dutyCycle << "\n";
188 #else
189   if (ioctl(fileDescriptor, _IOW('i', 0x15, __u32), &dutyCycle) == -1)
190   {
191     std::stringstream ss;
192     ss << "Failed to set duty cycle percentage.\n";
193     ss << "IR device returned error: " << strerror(errno) << "\n";
194     throw PIRException(ss.str());
195   }
196 #endif // DEBUGGING
197 }