ViewVC Help
View File | Revision Log | Show Annotations | Download File | View Changeset | Root Listing
root/truck/DashInterface/Display.cpp
(Generate patch)

Comparing DashInterface/Display.cpp (file contents):
Revision 31 by douglas, 2008-02-28T22:06:06-08:00 vs.
Revision 36 by douglas, 2008-03-04T22:24:35-08:00

# Line 5 | Line 5
5   // $Id$
6  
7   #include <foreach.hpp>
8 + #include <scopes.hpp>
9  
10   #include <iomanip>
11   #include <iostream>
# Line 72 | Line 73 | Display::Packet::Packet(Display::Packet:
73  
74   std::ostream &operator<<(std::ostream &output, const Display::Packet &packet)
75   {
76 <        return output << _B("0x") << std::hex << std::setw(2) << std::setfill('0') << unsigned(packet.command) << std::dec << std::setw(0) << std::setfill(' ') << _B(" [") << packet.GetData() << ']';
76 >        return output << _B("0x") << std::hex << std::setw(2) << std::setfill('0') << unsigned(packet.command) << _B(" [") << packet.GetData() << ']';
77   }
78  
79   void operator<<(int fd, const Display::Packet &packet)
# Line 98 | Line 99 | void operator>>(int fd, Display::Packet
99  
100   void Communicate(Display *display)
101   {
102 +        display->Communicate_();
103   }
104  
105 < Display::Display(const std::string &device) : ucom(Posix::Open(device, O_RDWR | O_NOCTTY)), thread(reinterpret_cast<void *(*)(void *)>(::Communicate))
105 > Display::Display(const std::string &device) : ucom(Posix::Open(device, O_RDWR | O_NOCTTY | O_NONBLOCK)), ucomCondition(ucomLock), running(true), responsesCondition(responsesLock), thread(reinterpret_cast<void *(*)(void *)>(::Communicate), this)
106   {
107          ::termios state;
108  
# Line 117 | Line 119 | Display::Display(const std::string &devi
119          state.c_lflag |= NOFLSH;
120  
121          Posix::CheckError(::tcsetattr(ucom, TCSANOW, &state));
122 +
123 +        _synchronized (ucomLock)
124 +                ucomCondition.Signal();
125 + }
126 +
127 + Display::~Display()
128 + {
129 +        running = false;
130 +
131 +        thread.Join();
132 +
133 +        Posix::Close(ucom);
134 + }
135 +
136 + void Display::Communicate_()
137 + {
138 +        _synchronized (ucomLock)
139 +                ucomCondition.Wait();
140 +
141 +        while (running)
142 +        {
143 +                Packet response;
144 +
145 +                _synchronized (ucomLock)
146 +                        try
147 +                        {
148 +                                ucom >> response;
149 +                        }
150 +                        catch (const Posix::Error error)
151 +                        {
152 +                                if (error.what() != _B("Resource temporarily unavailable"))
153 +                                        throw error;
154 +
155 +                                goto next;
156 +                        }
157 +
158 +                if ((response.command & Packet::Error) == Packet::Error);
159 +                else if ((response.command & Packet::Report) == Packet::Report)
160 +                        switch (response.command)
161 +                        {
162 +                        case Packet::KeyActivity:
163 +                                _synchronized (keyActivityLock)
164 +                                        keyActivity.push(response);
165 +
166 +                                break;
167 +                        case Packet::FanSpeedReport:
168 +                        case Packet::TemperatureSensorReport:
169 +                                break;
170 +                        }
171 +                else if ((response.command & Packet::Response) == Packet::Response)
172 +                        _synchronized (responsesLock)
173 +                        {
174 +                                responses.push(response);
175 +                                responsesCondition.Signal();
176 +                        }
177 +
178 + next:   ::usleep(10000);
179 +        }
180   }
181  
182   Display::Packet Display::Communicate_(Display::Packet::Command command, uint8_t length, const uint8_t *data)
183   {
184 <        Packet packet(command, length, data), response;
184 >        Packet packet(command, length, data);
185  
186 <        ucom << packet;
186 > retry:
187 >        _synchronized (ucomLock)
188 >                ucom << packet;
189  
190 <        _forever
190 >        _synchronized (responsesLock)
191          {
192 <                ucom >> response;
192 >                while (responses.empty())
193 >                        try
194 >                        {
195 >                                timeval when;
196  
197 <                if (packet.command | Packet::Response == response.command)
133 <                        return response;
197 >                                ::gettimeofday(&when, NULL);
198  
199 <                switch (response.command)
136 <                {
137 <                case Packet::KeyActivity:
138 <                        keyActivity.push(response);
199 >                                timespec wait;
200  
201 <                        break;
202 <                case Packet::FanSpeedReport:
203 <                case Packet::TemperatureSensorReport:
204 <                        break;
205 <                }
201 >                                TIMEVAL_TO_TIMESPEC(&when, &wait);
202 >
203 >                                ++wait.tv_sec;
204 >
205 >                                responsesCondition.Wait(wait);
206 >                        }
207 >                        catch (const Posix::Error &error)
208 >                        {
209 >                                if (error.what() != _B("Operation timed out"))
210 >                                        throw error;
211 >
212 >                                goto retry;
213 >                        }
214 >
215 >                Packet response(responses.front());
216 >
217 >                responses.pop();
218 >
219 >                assert ((packet.command | Packet::Response) == response.command);
220 >
221 >                return response;
222          }
223 +
224 +        throw;
225   }
226  
227   bool Display::Ping(const std::string &data)
# Line 159 | Line 238 | void Display::Set(uint8_t column, uint8_
238   {
239          Communicate(Packet::SendDataToLCD, column, row, data);
240   }
241 +
242 + Display::KeyActivity Display::GetKeyActivity()
243 + {
244 +        _synchronized (keyActivityLock)
245 +                if (keyActivity.size())
246 +                {
247 +                        KeyActivity activity(KeyActivity(*keyActivity.front().data));
248 +
249 +                        keyActivity.pop();
250 +
251 +                        return activity;
252 +                }
253 +
254 +        return None;
255 + }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines