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 29 by douglas, 2008-02-27T16:09:18-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>
12  
13   #include <fcntl.h>
# Line 69 | Line 71 | Display::Packet::Packet(Display::Packet:
71          crc = GetCRC(reinterpret_cast<uint8_t *>(this), length + 2);
72   }
73  
74 < void operator<<(int fd, const Display::Packet::Packet &packet)
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) << _B(" [") << packet.GetData() << ']';
77 > }
78 >
79 > void operator<<(int fd, const Display::Packet &packet)
80   {
81          if (packet.length != sizeof (packet.data))
82                  ::memcpy(const_cast<uint8_t *>(packet.data) + packet.length, &packet.crc, 2);
83  
84 +        if (debug)
85 +                std::cerr << _B("<< ") << packet << std::endl;
86 +
87          Posix::Write(fd, &packet, packet.length + 4);
88   }
89  
90 < void operator>>(int fd, Display::Packet::Packet &packet)
90 > void operator>>(int fd, Display::Packet &packet)
91   {
92          Posix::Read(fd, &packet, 2);
93          Posix::Read(fd, packet.data, packet.length);
94          Posix::Read(fd, &packet.crc, 2);
95  
96          if (debug)
97 <        {
98 <                char *data;
89 <
90 <                ::asprintf(&data, "0x%02x %i ", packet.command, packet.length);
91 <
92 <                std::cerr << data << '[' << packet.GetData() << ']' << std::endl;
97 >                std::cerr << _B(">> ") << packet << std::endl;
98 > }
99  
100 <                std::free(data);
101 <        }
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))
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 112 | 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)
128 <                        return response;
194 >                Packet response(responses.front());
195  
196 <                switch (response.command)
131 <                {
132 <                case Packet::KeyActivity:
133 <                        keyActivity.push(response);
196 >                responses.pop();
197  
198 <                        break;
199 <                case Packet::FanSpeedReport:
200 <                case Packet::TemperatureSensorReport:
138 <                        break;
139 <                }
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 152 | Line 215 | std::string Display::Version()
215  
216   void Display::Set(uint8_t column, uint8_t row, const std::string &data)
217   {
218 <        Communicate<uint8_t, uint8_t, const std::string &>(Packet::SendDataToLCD, column, row, data);
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