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 30 by douglas, 2008-02-28T17:01:10-08:00 vs.
Revision 33 by douglas, 2008-02-29T19:05:18-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 96 | Line 97 | void operator>>(int fd, Display::Packet
97                  std::cerr << _B(">> ") << packet << std::endl;
98   }
99  
100 < Display::Display(const std::string &device) : ucom(Posix::Open(device, O_RDWR | O_NOCTTY))
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 | O_NONBLOCK)), ucomCondition(ucomLock), running(true), responsesCondition(responsesLock), thread(reinterpret_cast<void *(*)(void *)>(::Communicate), this)
106   {
107          ::termios state;
108  
# Line 113 | 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(500);
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 >        _synchronized (ucomLock)
187 >                ucom << packet;
188  
189 <        _forever
189 >        _synchronized (responsesLock)
190          {
191 <                ucom >> response;
191 >                while (responses.empty())
192 >                        responsesCondition.Wait();
193  
194 <                if (packet.command | Packet::Response == response.command)
129 <                        return response;
194 >                Packet response(responses.front());
195  
196 <                switch (response.command)
132 <                {
133 <                case Packet::KeyActivity:
134 <                        keyActivity.push(response);
196 >                responses.pop();
197  
198 <                        break;
199 <                case Packet::FanSpeedReport:
200 <                case Packet::TemperatureSensorReport:
139 <                        break;
140 <                }
198 >                assert ((packet.command | Packet::Response) == response.command);
199 >
200 >                return response;
201          }
202 +
203 +        throw;
204   }
205  
206   bool Display::Ping(const std::string &data)
# Line 155 | Line 217 | void Display::Set(uint8_t column, uint8_
217   {
218          Communicate(Packet::SendDataToLCD, column, row, data);
219   }
220 +
221 + Display::KeyActivity Display::GetKeyActivity()
222 + {
223 +        _synchronized (keyActivityLock)
224 +                if (keyActivity.size())
225 +                {
226 +                        KeyActivity activity(KeyActivity(*keyActivity.front().data));
227 +
228 +                        keyActivity.pop();
229 +
230 +                        return activity;
231 +                }
232 +
233 +        return None;
234 + }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines