ViewVC Help
View File | Revision Log | Show Annotations | Download File | View Changeset | Root Listing
root/truck/DashInterface/Display.cpp
Revision: 32
Committed: 2008-02-29T12:47:34-08:00 (17 years, 3 months ago) by douglas
File size: 5611 byte(s)
Log Message:
Hmm...

File Contents

# User Rev Content
1 douglas 26 // Display (Crystalfontz CFA-635 USB LCD)
2 douglas 6 //
3     // Douglas Thrift
4     //
5     // $Id$
6    
7 douglas 28 #include <foreach.hpp>
8    
9 douglas 30 #include <iomanip>
10 douglas 25 #include <iostream>
11 douglas 6
12 douglas 26 #include <fcntl.h>
13     #include <termios.h>
14 douglas 25
15 douglas 26 #include "Display.hpp"
16 douglas 25
17 douglas 28 extern bool debug;
18    
19 douglas 26 static uint16_t GetCRC(uint8_t *buffer, size_t length)
20 douglas 25 {
21 douglas 26 static const uint16_t table[256] = {
22 douglas 29 0x00000, 0x01189, 0x02312, 0x0329b, 0x04624, 0x057ad, 0x06536, 0x074bf,
23     0x08C48, 0x09DC1, 0x0AF5A, 0x0BED3, 0x0CA6C, 0x0DBE5, 0x0E97E, 0x0F8F7,
24     0x01081, 0x00108, 0x03393, 0x0221a, 0x056a5, 0x0472c, 0x075b7, 0x0643e,
25     0x09CC9, 0x08D40, 0x0BFDB, 0x0AE52, 0x0DAED, 0x0CB64, 0x0F9FF, 0x0E876,
26     0x02102, 0x0308b, 0x00210, 0x01399, 0x06726, 0x076af, 0x04434, 0x055bd,
27     0x0AD4A, 0x0BCC3, 0x08E58, 0x09FD1, 0x0EB6E, 0x0FAE7, 0x0C87C, 0x0D9F5,
28     0x03183, 0x0200a, 0x01291, 0x00318, 0x077a7, 0x0662e, 0x054b5, 0x0453c,
29     0x0BDCB, 0x0AC42, 0x09ED9, 0x08F50, 0x0FBEF, 0x0EA66, 0x0D8FD, 0x0C974,
30     0x04204, 0x0538d, 0x06116, 0x0709f, 0x00420, 0x015a9, 0x02732, 0x036bb,
31     0x0ce4c, 0x0dfc5, 0x0ed5e, 0x0fcd7, 0x08868, 0x099e1, 0x0ab7a, 0x0baf3,
32     0x05285, 0x0430c, 0x07197, 0x0601e, 0x014a1, 0x00528, 0x037b3, 0x0263a,
33     0x0decd, 0x0cf44, 0x0fddf, 0x0ec56, 0x098e9, 0x08960, 0x0bbfb, 0x0aa72,
34     0x06306, 0x0728f, 0x04014, 0x0519d, 0x02522, 0x034ab, 0x00630, 0x017b9,
35     0x0EF4E, 0x0FEC7, 0x0CC5C, 0x0DDD5, 0x0A96A, 0x0B8E3, 0x08A78, 0x09BF1,
36     0x07387, 0x0620e, 0x05095, 0x0411c, 0x035a3, 0x0242a, 0x016b1, 0x00738,
37     0x0FFCF, 0x0EE46, 0x0DCDD, 0x0CD54, 0x0B9EB, 0x0A862, 0x09AF9, 0x08B70,
38     0x08408, 0x09581, 0x0a71a, 0x0b693, 0x0c22c, 0x0d3a5, 0x0e13e, 0x0f0b7,
39     0x00840, 0x019c9, 0x02b52, 0x03adb, 0x04e64, 0x05fed, 0x06d76, 0x07cff,
40     0x09489, 0x08500, 0x0b79b, 0x0a612, 0x0d2ad, 0x0c324, 0x0f1bf, 0x0e036,
41     0x018c1, 0x00948, 0x03bd3, 0x02a5a, 0x05ee5, 0x04f6c, 0x07df7, 0x06c7e,
42     0x0a50a, 0x0b483, 0x08618, 0x09791, 0x0e32e, 0x0f2a7, 0x0c03c, 0x0d1b5,
43     0x02942, 0x038cb, 0x00a50, 0x01bd9, 0x06f66, 0x07eef, 0x04c74, 0x05dfd,
44     0x0b58b, 0x0a402, 0x09699, 0x08710, 0x0f3af, 0x0e226, 0x0d0bd, 0x0c134,
45     0x039C3, 0x0284A, 0x01AD1, 0x00B58, 0x07FE7, 0x06E6E, 0x05CF5, 0x04D7C,
46     0x0c60c, 0x0d785, 0x0e51e, 0x0f497, 0x08028, 0x091a1, 0x0a33a, 0x0b2b3,
47     0x04a44, 0x05bcd, 0x06956, 0x078df, 0x00c60, 0x01de9, 0x02f72, 0x03efb,
48     0x0d68d, 0x0c704, 0x0f59f, 0x0e416, 0x090a9, 0x08120, 0x0b3bb, 0x0a232,
49     0x05AC5, 0x04B4C, 0x079D7, 0x0685E, 0x01CE1, 0x00D68, 0x03FF3, 0x02E7A,
50     0x0e70e, 0x0f687, 0x0c41c, 0x0d595, 0x0a12a, 0x0b0a3, 0x08238, 0x093b1,
51     0x06b46, 0x07acf, 0x04854, 0x059dd, 0x02d62, 0x03ceb, 0x00e70, 0x01ff9,
52     0x0f78f, 0x0e606, 0x0d49d, 0x0c514, 0x0b1ab, 0x0a022, 0x092b9, 0x08330,
53     0x07BC7, 0x06A4E, 0x058D5, 0x0495C, 0x03DE3, 0x02C6A, 0x01EF1, 0x00F78,
54 douglas 26 };
55     register uint16_t crc(0xffff);
56 douglas 25
57 douglas 26 while (length--)
58     crc = (crc >> 8) ^ table[(crc ^ *buffer++) & 0xff];
59 douglas 25
60 douglas 26 return ~crc;
61     }
62 douglas 25
63 douglas 28 Display::Packet::Packet(Display::Packet::Command command, uint8_t length, const uint8_t *data) : command(command), length(length)
64 douglas 26 {
65     if (length > sizeof (this->data))
66     throw;
67 douglas 25
68 douglas 28 ::memcpy(this->data, data, length);
69 douglas 25
70 douglas 26 crc = GetCRC(reinterpret_cast<uint8_t *>(this), length + 2);
71     }
72 douglas 25
73 douglas 30 std::ostream &operator<<(std::ostream &output, const Display::Packet &packet)
74 douglas 26 {
75 douglas 30 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     }
77    
78     void operator<<(int fd, const Display::Packet &packet)
79     {
80 douglas 26 if (packet.length != sizeof (packet.data))
81     ::memcpy(const_cast<uint8_t *>(packet.data) + packet.length, &packet.crc, 2);
82 douglas 25
83 douglas 30 if (debug)
84     std::cerr << _B("<< ") << packet << std::endl;
85    
86 douglas 26 Posix::Write(fd, &packet, packet.length + 4);
87     }
88 douglas 25
89 douglas 30 void operator>>(int fd, Display::Packet &packet)
90 douglas 26 {
91     Posix::Read(fd, &packet, 2);
92     Posix::Read(fd, packet.data, packet.length);
93     Posix::Read(fd, &packet.crc, 2);
94 douglas 25
95 douglas 28 if (debug)
96 douglas 30 std::cerr << _B(">> ") << packet << std::endl;
97 douglas 25 }
98    
99 douglas 31 void Communicate(Display *display)
100 douglas 25 {
101 douglas 32 while (true)
102     std::cout << _B("Hello!") << std::endl;
103 douglas 31 }
104    
105 douglas 32 Display::Display(const std::string &device) : ucom(Posix::Open(device, O_RDWR | O_NOCTTY)), thread(reinterpret_cast<void *(*)(void *)>(::Communicate), this)
106 douglas 31 {
107 douglas 26 ::termios state;
108 douglas 25
109 douglas 26 Posix::CheckError(::tcgetattr(ucom, &state));
110     Posix::CheckError(::cfsetospeed(&state, B115200));
111     Posix::CheckError(::cfsetispeed(&state, B115200));
112    
113     state.c_iflag &= ~(IGNBRK | BRKINT | PARMRK | INPCK | ISTRIP | INLCR | IGNCR | ICRNL | IXON | IXOFF);
114     state.c_iflag |= IGNPAR;
115     state.c_oflag &= ~(OPOST | ONLCR | ONOCR | ONLRET);
116     state.c_cflag &= ~(CSIZE | PARENB | PARODD | HUPCL | CRTSCTS);
117     state.c_cflag |= CREAD | CS8 | CSTOPB | CLOCAL;
118     state.c_lflag &= ~(ISIG | ICANON | IEXTEN | ECHO);
119     state.c_lflag |= NOFLSH;
120    
121     Posix::CheckError(::tcsetattr(ucom, TCSANOW, &state));
122 douglas 25 }
123    
124 douglas 29 Display::Packet Display::Communicate_(Display::Packet::Command command, uint8_t length, const uint8_t *data)
125 douglas 25 {
126 douglas 28 Packet packet(command, length, data), response;
127 douglas 25
128 douglas 26 ucom << packet;
129    
130 douglas 28 _forever
131 douglas 26 {
132     ucom >> response;
133 douglas 28
134     if (packet.command | Packet::Response == response.command)
135     return response;
136    
137     switch (response.command)
138     {
139     case Packet::KeyActivity:
140     keyActivity.push(response);
141    
142     break;
143     case Packet::FanSpeedReport:
144     case Packet::TemperatureSensorReport:
145     break;
146     }
147 douglas 26 }
148 douglas 28 }
149 douglas 26
150 douglas 28 bool Display::Ping(const std::string &data)
151     {
152 douglas 29 return data == Communicate<const std::string &>(Packet::PingCommand, data).GetData();
153 douglas 25 }
154 douglas 28
155     std::string Display::Version()
156     {
157     return Communicate(Packet::GetHardwareAndFirmwareVersion).GetData();
158     }
159    
160 douglas 29 void Display::Set(uint8_t column, uint8_t row, const std::string &data)
161 douglas 28 {
162 douglas 30 Communicate(Packet::SendDataToLCD, column, row, data);
163 douglas 28 }

Properties

Name Value
svn:keywords Id