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