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 37 by douglas, 2008-03-05T02:29:38-08:00

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

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines