slime@2
|
1 |
/***************************************************************************
|
slime@2
|
2 |
* Copyright (C) 2008 by Peter Marquardt *
|
slime@2
|
3 |
* p_marquardt@users.sourceforge.net *
|
slime@2
|
4 |
* code base Copyright (C) 2007 by Carsten Presser *
|
slime@2
|
5 |
* *
|
slime@2
|
6 |
* This program is free software; you can redistribute it and/or modify *
|
slime@2
|
7 |
* it under the terms of the GNU General Public License as published by *
|
slime@2
|
8 |
* the Free Software Foundation; either version 2 of the License, or *
|
slime@2
|
9 |
* (at your option) any later version. *
|
slime@2
|
10 |
* *
|
slime@2
|
11 |
* This program is distributed in the hope that it will be useful, *
|
slime@2
|
12 |
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
slime@2
|
13 |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
slime@2
|
14 |
* GNU General Public License for more details. *
|
slime@2
|
15 |
* *
|
slime@2
|
16 |
* You should have received a copy of the GNU General Public License *
|
slime@2
|
17 |
* along with this program; if not, write to the *
|
slime@2
|
18 |
* Free Software Foundation, Inc., *
|
slime@2
|
19 |
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
|
slime@2
|
20 |
***************************************************************************/
|
slime@2
|
21 |
|
slime@2
|
22 |
/*! \file pcctldisplaytest.cpp
|
slime@2
|
23 |
\brief A utility to test the picctl lcd display and interface
|
slime@2
|
24 |
\author Peter Marquardt p_marquardt@users.sourceforge.net
|
slime@2
|
25 |
\author Carsten Presser
|
slime@2
|
26 |
\todo sanitize command line argument parsing
|
slime@2
|
27 |
*/
|
slime@2
|
28 |
|
slime@2
|
29 |
#ifdef HAVE_CONFIG_H
|
slime@2
|
30 |
#include <config.h>
|
slime@2
|
31 |
#endif
|
slime@2
|
32 |
#include <iostream>
|
slime@2
|
33 |
#include <cstdlib>
|
slime@2
|
34 |
#include <termios.h>
|
slime@2
|
35 |
#include <signal.h>
|
slime@2
|
36 |
#include <fcntl.h>
|
slime@2
|
37 |
#include "picctldisplaytest.h"
|
slime@2
|
38 |
|
slime@2
|
39 |
using namespace std;
|
slime@2
|
40 |
config myconfig;
|
slime@2
|
41 |
runtime_flags myflags;
|
slime@2
|
42 |
int fd;
|
slime@2
|
43 |
|
slime@2
|
44 |
int main(int argc, char *argv[])
|
slime@2
|
45 |
{
|
slime@2
|
46 |
bool kill_flag = false;
|
slime@2
|
47 |
struct termios options;
|
slime@2
|
48 |
struct sigaction saio;
|
slime@2
|
49 |
char key;
|
slime@2
|
50 |
|
slime@2
|
51 |
cout << "** picctldisplaytest - simple test utility for picctl lcd displays **" << endl
|
slime@2
|
52 |
<< ">";
|
slime@2
|
53 |
|
slime@2
|
54 |
// setting defaults
|
slime@2
|
55 |
myconfig.debug = false;
|
slime@2
|
56 |
myconfig.verbosity = 0;
|
slime@2
|
57 |
myconfig.modem_device = "/dev/ttyACM0";
|
slime@2
|
58 |
myflags.parse_return_clockram = false;
|
slime@2
|
59 |
|
slime@2
|
60 |
// parsing arguments
|
slime@2
|
61 |
for (int i = 1; i < argc; i++) {
|
slime@2
|
62 |
if (*argv[i] == 'd') {
|
slime@2
|
63 |
i++;
|
slime@2
|
64 |
myconfig.modem_device = argv[i];
|
slime@2
|
65 |
}
|
slime@2
|
66 |
else if (*argv[i] == 'v') {
|
slime@2
|
67 |
i++;
|
slime@2
|
68 |
myconfig.verbosity = atoi(argv[i]);
|
slime@2
|
69 |
}
|
slime@2
|
70 |
else if (*argv[i] == 'D') {
|
slime@2
|
71 |
myconfig.debug =true;
|
slime@2
|
72 |
}
|
slime@2
|
73 |
}
|
slime@2
|
74 |
|
slime@2
|
75 |
if (myconfig.verbosity > 0 || myconfig.debug) {
|
slime@2
|
76 |
cout << "picctldisplaytest called with\n"
|
slime@2
|
77 |
<< "device: " << myconfig.modem_device << endl
|
slime@2
|
78 |
<< "verbosity: " << myconfig.verbosity << endl
|
slime@2
|
79 |
<< "debug mode:" << boolalpha << myconfig.debug << endl;
|
slime@2
|
80 |
}
|
slime@2
|
81 |
|
slime@2
|
82 |
/* open the device to be non-blocking (read will return immediatly) */
|
slime@2
|
83 |
fd = open(myconfig.modem_device, O_RDWR | O_NOCTTY | O_NONBLOCK);
|
slime@2
|
84 |
if (fd <0) {perror(myconfig.modem_device); exit(-1); }
|
slime@2
|
85 |
|
slime@2
|
86 |
/* install the signal handler before making the device asynchronous */
|
slime@2
|
87 |
saio.sa_handler = signal_handler_IO;
|
slime@2
|
88 |
sigemptyset (&saio.sa_mask);
|
slime@2
|
89 |
saio.sa_flags = 0;
|
slime@2
|
90 |
saio.sa_restorer = NULL;
|
slime@2
|
91 |
sigaction(SIGIO,&saio,NULL);
|
slime@2
|
92 |
// allow the process to receive SIGIO
|
slime@2
|
93 |
fcntl(fd, F_SETOWN, getpid());
|
slime@2
|
94 |
// Make the file descriptor asynchronous
|
slime@2
|
95 |
fcntl(fd, F_SETFL, FASYNC);
|
slime@2
|
96 |
|
slime@2
|
97 |
tcgetattr(fd, &options);
|
slime@2
|
98 |
|
slime@2
|
99 |
cfsetispeed(&options, BAUDRATE);
|
slime@2
|
100 |
cfsetospeed(&options, BAUDRATE);
|
slime@2
|
101 |
|
slime@2
|
102 |
options.c_cflag &= ~PARENB;
|
slime@2
|
103 |
options.c_cflag &= ~CSTOPB;
|
slime@2
|
104 |
options.c_cflag &= ~CSIZE;
|
slime@2
|
105 |
options.c_cflag |= CS8;
|
slime@2
|
106 |
|
slime@2
|
107 |
options.c_cflag &= ~CRTSCTS;
|
slime@2
|
108 |
options.c_cflag |= (CLOCAL | CREAD);
|
slime@2
|
109 |
options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);
|
slime@2
|
110 |
options.c_iflag &= ~(IXON | IXOFF | IXANY);
|
slime@2
|
111 |
options.c_oflag &= ~OPOST;
|
slime@2
|
112 |
tcsetattr(fd, TCSANOW, &options);
|
slime@2
|
113 |
|
slime@2
|
114 |
if (myconfig.debug || myconfig.verbosity > 0) print_help();
|
slime@2
|
115 |
|
slime@2
|
116 |
while ( cin.get(key)) {
|
slime@2
|
117 |
switch(key) {
|
slime@2
|
118 |
case 'q':
|
slime@2
|
119 |
cout << "Exiting." << endl;
|
slime@2
|
120 |
return EXIT_SUCCESS;
|
slime@2
|
121 |
break;
|
slime@2
|
122 |
case 'u':
|
slime@2
|
123 |
cout << "Switching to unmanaged mode..." << endl;
|
slime@2
|
124 |
send_data(CMD_SET_MODE_UNMANAGED,(sizeof(CMD_SET_MODE_UNMANAGED)/sizeof(char)));
|
slime@2
|
125 |
break;
|
slime@2
|
126 |
case 'm':
|
slime@2
|
127 |
cout << "Switching to managed mode..." << endl;
|
slime@2
|
128 |
send_data(CMD_SET_MODE_MANAGED,(sizeof(CMD_SET_MODE_MANAGED)/sizeof(char)));
|
slime@2
|
129 |
break;
|
slime@2
|
130 |
case 'c':
|
slime@2
|
131 |
cout << "Sending Clear Display..." << endl;
|
slime@2
|
132 |
send_data(CMD_DISP_CLEAR_SCREEN,(sizeof(CMD_DISP_CLEAR_SCREEN)/sizeof(char)));
|
slime@2
|
133 |
break;
|
slime@2
|
134 |
case 'h':
|
slime@2
|
135 |
print_help();
|
slime@2
|
136 |
break;
|
slime@2
|
137 |
case 'j':
|
slime@2
|
138 |
print_cli_options();
|
slime@2
|
139 |
break;
|
slime@2
|
140 |
case '1':
|
slime@2
|
141 |
cout << "Display CG ROM charset..." << endl;
|
slime@2
|
142 |
send_data(TEST_STRING_1,(sizeof(TEST_STRING_1)/sizeof(char)));
|
slime@2
|
143 |
send_data(TEST_STRING_2,(sizeof(TEST_STRING_2)/sizeof(char)));
|
slime@2
|
144 |
send_data(TEST_STRING_3,(sizeof(TEST_STRING_3)/sizeof(char)));
|
slime@2
|
145 |
break;
|
slime@2
|
146 |
case '2':
|
slime@2
|
147 |
cout << "Filling the Display with CG ROM charset..." << endl;
|
slime@2
|
148 |
send_data(TEST_STRING_1,(sizeof(TEST_STRING_1)/sizeof(char)));
|
slime@2
|
149 |
send_data(TEST_STRING_2,(sizeof(TEST_STRING_2)/sizeof(char)));
|
slime@2
|
150 |
send_data(TEST_STRING_3,(sizeof(TEST_STRING_3)/sizeof(char)));
|
slime@2
|
151 |
send_data(TEST_STRING_4,(sizeof(TEST_STRING_4)/sizeof(char)));
|
slime@2
|
152 |
send_data(TEST_STRING_5,(sizeof(TEST_STRING_5)/sizeof(char)));
|
slime@2
|
153 |
break;
|
slime@2
|
154 |
case '3': {
|
slime@2
|
155 |
cout << "Sending Test String... one line per packet, 8 lines of 30 chars" << endl;
|
slime@2
|
156 |
for (int j = 0; j < 8; j++) {
|
slime@2
|
157 |
const unsigned char cmd[] = {0xAA,0x14,0x00,32,((j*30)),0x08,
|
slime@2
|
158 |
16,17,18,19,20,21,22,23,24,25,
|
slime@2
|
159 |
16,17,18,19,20,21,22,23,24,25,
|
slime@2
|
160 |
16,17,18,19,20,21,22,23,24,25};
|
slime@2
|
161 |
send_data(cmd,(sizeof(cmd)/sizeof(char)));
|
slime@2
|
162 |
}
|
slime@2
|
163 |
}
|
slime@2
|
164 |
break;
|
slime@2
|
165 |
case '4':
|
slime@2
|
166 |
cout << "Sending Test String.. one char per packet,8 lines of 30 chars" << endl;
|
slime@2
|
167 |
for (int j = 0; j < 8; j++) {
|
slime@2
|
168 |
for (int k = 0; k < 30; k++) {
|
slime@2
|
169 |
const unsigned char cmd[] = {0xAA,0x14,0x00,3,k+(j*30),0x08,
|
slime@2
|
170 |
(16+k)};
|
slime@2
|
171 |
send_data(cmd,(sizeof(cmd)/sizeof(char)));
|
slime@2
|
172 |
}
|
slime@2
|
173 |
}
|
slime@2
|
174 |
break;
|
slime@2
|
175 |
|
slime@2
|
176 |
case 'a':
|
slime@2
|
177 |
cout << "Set PWM1 0%..." << endl;
|
slime@2
|
178 |
CMD_SET_PWM1[4] = 0x00;
|
slime@2
|
179 |
send_data(CMD_SET_PWM1,(sizeof(CMD_SET_PWM1)/sizeof(char)));
|
slime@2
|
180 |
break;
|
slime@2
|
181 |
case 's':
|
slime@2
|
182 |
cout << "SetPWM1 25%..." << endl;
|
slime@2
|
183 |
CMD_SET_PWM1[4] = 0x40;
|
slime@2
|
184 |
send_data(CMD_SET_PWM1,(sizeof(CMD_SET_PWM1)/sizeof(char)));
|
slime@2
|
185 |
break;
|
slime@2
|
186 |
case 'd':
|
slime@2
|
187 |
cout << "Set PWM1 50%..." << endl;
|
slime@2
|
188 |
CMD_SET_PWM1[4] = 0x80;
|
slime@2
|
189 |
send_data(CMD_SET_PWM1,(sizeof(CMD_SET_PWM1)/sizeof(char)));
|
slime@2
|
190 |
break;
|
slime@2
|
191 |
case 'f':
|
slime@2
|
192 |
cout << "Set PWM1 75%..." << endl;
|
slime@2
|
193 |
CMD_SET_PWM1[4] = 0xC0;
|
slime@2
|
194 |
send_data(CMD_SET_PWM1,(sizeof(CMD_SET_PWM1)/sizeof(char)));
|
slime@2
|
195 |
break;
|
slime@2
|
196 |
case 'g':
|
slime@2
|
197 |
cout << "Set PWM1 100%..." << endl;
|
slime@2
|
198 |
CMD_SET_PWM1[4] = 0xFF;
|
slime@2
|
199 |
send_data(CMD_SET_PWM1,(sizeof(CMD_SET_PWM1)/sizeof(char)));
|
slime@2
|
200 |
break;
|
slime@2
|
201 |
case 'A':
|
slime@2
|
202 |
cout << "Set PWM2 0%..." << endl;
|
slime@2
|
203 |
CMD_SET_PWM2[4] = 0x00;
|
slime@2
|
204 |
send_data(CMD_SET_PWM2,(sizeof(CMD_SET_PWM2)/sizeof(char)));
|
slime@2
|
205 |
break;
|
slime@2
|
206 |
case 'S':
|
slime@2
|
207 |
cout << "SetPWM2 25%..." << endl;
|
slime@2
|
208 |
CMD_SET_PWM2[4] = 0x40;
|
slime@2
|
209 |
send_data(CMD_SET_PWM2,(sizeof(CMD_SET_PWM2)/sizeof(char)));
|
slime@2
|
210 |
break;
|
slime@2
|
211 |
case 'D':
|
slime@2
|
212 |
cout << "Set PWM2 50%..." << endl;
|
slime@2
|
213 |
CMD_SET_PWM2[4] = 0x80;
|
slime@2
|
214 |
send_data(CMD_SET_PWM2,(sizeof(CMD_SET_PWM2)/sizeof(char)));
|
slime@2
|
215 |
break;
|
slime@2
|
216 |
case 'F':
|
slime@2
|
217 |
cout << "Set PWM2 75%..." << endl;
|
slime@2
|
218 |
CMD_SET_PWM2[4] = 0xC0;
|
slime@2
|
219 |
send_data(CMD_SET_PWM2,(sizeof(CMD_SET_PWM2)/sizeof(char)));
|
slime@2
|
220 |
break;
|
slime@2
|
221 |
case 'G':
|
slime@2
|
222 |
cout << "Set PWM2 100%..." << endl;
|
slime@2
|
223 |
CMD_SET_PWM2[4] = 0xFF;
|
slime@2
|
224 |
send_data(CMD_SET_PWM2,(sizeof(CMD_SET_PWM2)/sizeof(char)));
|
slime@2
|
225 |
break;
|
slime@2
|
226 |
case 'T': {
|
slime@2
|
227 |
cout << "Setting pcf8583 clock memory..." << endl;
|
slime@2
|
228 |
time_t mytime = time(NULL);
|
slime@2
|
229 |
tm * myltime = localtime( &mytime);
|
slime@2
|
230 |
if (myconfig.debug || myconfig.verbosity > 0) cout << "Local Time is: " << myltime->tm_hour << ":" << myltime->tm_min << ":" << myltime->tm_sec << " " << myltime->tm_mday << "." << myltime->tm_mon+1 << endl;
|
slime@2
|
231 |
const unsigned char tcmd[] = {0xAA,0x41,0x00,0x10,
|
slime@2
|
232 |
0x04,0x00,dec2bcd(myltime->tm_sec),dec2bcd(myltime->tm_min),dec2bcd(myltime->tm_hour),dec2bcd(myltime->tm_mday),
|
slime@2
|
233 |
(dec2bcd(myltime->tm_mon+1)),0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
|
slime@2
|
234 |
send_data(tcmd,(sizeof(tcmd)/sizeof(char)));
|
slime@2
|
235 |
}
|
slime@2
|
236 |
break;
|
slime@2
|
237 |
case 't' : {
|
slime@2
|
238 |
cout << "Dumping pcf8583 clock memory..." << endl;
|
slime@2
|
239 |
int oldverbosity = myconfig.verbosity;
|
slime@2
|
240 |
myflags.parse_return_clockram = true;
|
slime@2
|
241 |
if (myconfig.verbosity < 2) {
|
slime@2
|
242 |
myconfig.verbosity = 2;
|
slime@2
|
243 |
}
|
slime@2
|
244 |
send_data(CMD_GET_CLOCK_MEMORY,(sizeof(CMD_GET_CLOCK_MEMORY)/sizeof(char)));
|
slime@2
|
245 |
myconfig.verbosity = oldverbosity;
|
slime@2
|
246 |
myflags.parse_return_clockram = false;
|
slime@2
|
247 |
}
|
slime@2
|
248 |
break;
|
slime@2
|
249 |
case '5': {
|
slime@2
|
250 |
cout << "Showing test picture 1..."<< endl;
|
slime@2
|
251 |
write_gfx_ram( TEST_PICTURE_1,(sizeof(TEST_PICTURE_1)/sizeof(char)));
|
slime@2
|
252 |
}
|
slime@2
|
253 |
break;
|
slime@2
|
254 |
case '6': {
|
slime@2
|
255 |
cout << "Showing test picture 2 - horizontal lines..."<< endl;
|
slime@2
|
256 |
unsigned char mycmd[36] = {0xAA,0x14,0x00,0x20,0x00,0x00,
|
slime@2
|
257 |
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
|
slime@2
|
258 |
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
|
slime@2
|
259 |
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff
|
slime@2
|
260 |
} ;
|
slime@2
|
261 |
for (int i = 0; i <64;i+=2) {
|
slime@2
|
262 |
mycmd[5] = (i*30) / 256;
|
slime@2
|
263 |
mycmd[4] = (i*30) - (256 * mycmd[5]);
|
slime@2
|
264 |
send_data(mycmd, (sizeof(mycmd)/sizeof(char)));
|
slime@2
|
265 |
}
|
slime@2
|
266 |
}
|
slime@2
|
267 |
break;
|
slime@2
|
268 |
case '7': {
|
slime@2
|
269 |
cout << "Showing test picture 3 - vertical lines..."<< endl;
|
slime@2
|
270 |
unsigned char mycmd[36] = {0xAA,0x14,0x00,0x20,0x00,0x00,
|
slime@2
|
271 |
0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
|
slime@2
|
272 |
0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
|
slime@2
|
273 |
0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa
|
slime@2
|
274 |
} ;
|
slime@2
|
275 |
for (int i = 0; i <64;i++) {
|
slime@2
|
276 |
mycmd[5] = (i*30) / 256;
|
slime@2
|
277 |
mycmd[4] = (i*30) - (256 * mycmd[5]);
|
slime@2
|
278 |
send_data(mycmd, (sizeof(mycmd)/sizeof(char)));
|
slime@2
|
279 |
}
|
slime@2
|
280 |
}
|
slime@2
|
281 |
break;
|
slime@2
|
282 |
case '8': {
|
slime@2
|
283 |
cout << "Showing test picture 4...Boxes"<< endl;
|
slime@2
|
284 |
write_gfx_ram(TEST_PICTURE_2,(sizeof(TEST_PICTURE_2)/sizeof(char)));
|
slime@2
|
285 |
}
|
slime@2
|
286 |
break;
|
slime@2
|
287 |
case '9': {
|
slime@2
|
288 |
cout << "Showing test picture 5 - outline + center cross..."<< endl;
|
slime@2
|
289 |
unsigned char mycmd_1[36] = {0xAA,0x14,0x00,0x20,0x00,0x00,
|
slime@2
|
290 |
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
|
slime@2
|
291 |
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
|
slime@2
|
292 |
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff
|
slime@2
|
293 |
} ;
|
slime@2
|
294 |
unsigned char mycmd_2[36] = {0xAA,0x14,0x00,0x20,0x00,0x00,
|
slime@2
|
295 |
0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
slime@2
|
296 |
0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,
|
slime@2
|
297 |
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01
|
slime@2
|
298 |
} ;
|
slime@2
|
299 |
int i = 1;
|
slime@2
|
300 |
for (int j = 0;j<2;j++) {
|
slime@2
|
301 |
send_data(mycmd_1, (sizeof(mycmd_1)/sizeof(char)));
|
slime@2
|
302 |
for ( i = 1; i <31;i++) {
|
slime@2
|
303 |
mycmd_2[5] = ((i*30) + (j*960)) / 256;
|
slime@2
|
304 |
mycmd_2[4] = ((i*30) + (j*960)) - (256 * mycmd_2[5]);
|
slime@2
|
305 |
send_data(mycmd_2, (sizeof(mycmd_2)/sizeof(char)));
|
slime@2
|
306 |
}
|
slime@2
|
307 |
mycmd_1[5] = ((i*30) + (j*960)) / 256;
|
slime@2
|
308 |
mycmd_1[4] = ((i*30) + (j*960)) - (256 * mycmd_1[5]);
|
slime@2
|
309 |
}
|
slime@2
|
310 |
send_data(mycmd_1, (sizeof(mycmd_1)/sizeof(char)));
|
slime@2
|
311 |
}
|
slime@2
|
312 |
break;
|
slime@2
|
313 |
|
slime@2
|
314 |
default:
|
slime@2
|
315 |
break;
|
slime@2
|
316 |
}
|
slime@2
|
317 |
sleep(1);
|
slime@2
|
318 |
if (key != 0x13 && key != '\n') cout << ">";
|
slime@2
|
319 |
}
|
slime@2
|
320 |
close(fd);
|
slime@2
|
321 |
return EXIT_SUCCESS;
|
slime@2
|
322 |
}
|
slime@2
|
323 |
|
slime@2
|
324 |
unsigned char bitendian (unsigned char in)
|
slime@2
|
325 |
{
|
slime@2
|
326 |
unsigned char ret = 0x00;
|
slime@2
|
327 |
if (in & 0x01) ret+=0x80;
|
slime@2
|
328 |
if (in & 0x02) ret+=0x40;
|
slime@2
|
329 |
if (in & 0x04) ret+=0x20;
|
slime@2
|
330 |
if (in & 0x08) ret+=0x10;
|
slime@2
|
331 |
if (in & 0x10) ret+=0x08;
|
slime@2
|
332 |
if (in & 0x20) ret+=0x04;
|
slime@2
|
333 |
if (in & 0x40) ret+=0x02;
|
slime@2
|
334 |
if (in & 0x80) ret+=0x01;
|
slime@2
|
335 |
|
slime@2
|
336 |
return (ret);
|
slime@2
|
337 |
}
|
slime@2
|
338 |
|
slime@2
|
339 |
|
slime@2
|
340 |
bool write_gfx_ram(const unsigned char * buffer, int numbytes) {
|
slime@2
|
341 |
if (numbytes > 1920) {
|
slime@2
|
342 |
cout << "Too much data for gfx RAM, ignoring..." << endl;
|
slime@2
|
343 |
return false;
|
slime@2
|
344 |
}
|
slime@2
|
345 |
int i = 0, offset = 6, memaddr = 0;
|
slime@2
|
346 |
bool all_sent = false;
|
slime@2
|
347 |
unsigned char mycmd[63] = {0xAA,0x14,0x00,0x02,0x00,0x00};
|
slime@2
|
348 |
while (i <numbytes) {
|
slime@2
|
349 |
all_sent = false;
|
slime@2
|
350 |
mycmd[offset] = bitendian(buffer[i]);
|
slime@2
|
351 |
i++;
|
slime@2
|
352 |
offset++;
|
slime@2
|
353 |
if (offset == 63) {
|
slime@2
|
354 |
mycmd[3] = 59;
|
slime@2
|
355 |
send_data(mycmd,63);
|
slime@2
|
356 |
memaddr += 57;
|
slime@2
|
357 |
mycmd[5] = (memaddr / 256);
|
slime@2
|
358 |
mycmd[4] = (memaddr - (mycmd[5]*256));
|
slime@2
|
359 |
offset = 6;
|
slime@2
|
360 |
all_sent = true;
|
slime@2
|
361 |
}
|
slime@2
|
362 |
}
|
slime@2
|
363 |
if (!all_sent) {
|
slime@2
|
364 |
mycmd[3] = (offset-4);
|
slime@2
|
365 |
send_data(mycmd,offset);
|
slime@2
|
366 |
}
|
slime@2
|
367 |
return true;
|
slime@2
|
368 |
}
|
slime@2
|
369 |
|
slime@2
|
370 |
/*! \brief sends size bytes of buffer data to the display
|
slime@2
|
371 |
|
slime@2
|
372 |
\warning send_data doesn't check if buffer really is numbytes big. Expect all kind of weirdness if abused.
|
slime@2
|
373 |
\param buffer pointer to a char buffer conatining the data
|
slime@2
|
374 |
\param numbytes Number of bytes in buffer
|
slime@2
|
375 |
*/
|
slime@2
|
376 |
bool send_data(const unsigned char * buffer, int numbytes) {
|
slime@2
|
377 |
if (numbytes > 64 ) {
|
slime@2
|
378 |
cout << "Buffer size exceeds 64 Bytes, send_data aborted." << endl;
|
slime@2
|
379 |
return false;
|
slime@2
|
380 |
}
|
slime@2
|
381 |
write(fd,buffer,numbytes);
|
slime@2
|
382 |
if (myconfig.debug || myconfig.verbosity > 0) cout << numbytes <<" bytes sent.";
|
slime@2
|
383 |
if (myconfig.debug || myconfig.verbosity > 1) {
|
slime@2
|
384 |
cout <<" Data: " << endl ;
|
slime@2
|
385 |
for ( int i = 0; i <numbytes; i++) {
|
slime@2
|
386 |
cout << " 0x" << ((int) buffer[i] < 10 ? "0" : "") << hex << (int) buffer[i] << dec;
|
slime@2
|
387 |
if (i > 0 && ((i-3)%8 ==0 || i == 3)) cout << endl;
|
slime@2
|
388 |
}
|
slime@2
|
389 |
}
|
slime@2
|
390 |
if (myconfig.debug || myconfig.verbosity > 0) cout << endl;
|
slime@2
|
391 |
usleep(100000);
|
slime@2
|
392 |
return true;
|
slime@2
|
393 |
}
|
slime@2
|
394 |
|
slime@2
|
395 |
/*! \brief prints some help
|
slime@2
|
396 |
*/
|
slime@2
|
397 |
void print_help() {
|
slime@2
|
398 |
cout << endl;
|
slime@2
|
399 |
cout << "Usage:" << endl;
|
slime@2
|
400 |
cout << "u\tset unmanaged mode" << endl;
|
slime@2
|
401 |
cout << "m\tset managed mode" << endl;
|
slime@2
|
402 |
cout << endl;
|
slime@2
|
403 |
cout << "T\tset pcf8583 clock to system time" << endl;
|
slime@2
|
404 |
cout << "t\tdump pcf8583 clock memory" << endl;
|
slime@2
|
405 |
cout << endl;
|
slime@2
|
406 |
cout << "Set PWM:" << endl;
|
slime@2
|
407 |
cout << "PWM1\ta 0%\ts 25%\td 50%\tf 75%\tg 100%" << endl;
|
slime@2
|
408 |
cout << "PWM2\tA 0%\tS 25%\tD 50%\tF 75%\tG 100%" << endl;
|
slime@2
|
409 |
cout << endl;
|
slime@2
|
410 |
cout << "1\tshow ROM charset" << endl;
|
slime@2
|
411 |
cout << "2\tfill Text area with ROM charset" << endl;
|
slime@2
|
412 |
cout << "3\tfill Text area (8 lines / 30 chars, one line per packet)" << endl;
|
slime@2
|
413 |
cout << "4\tfill Text area (8 lines / 30 chars, one char per packet)" << endl;
|
slime@2
|
414 |
cout << endl;
|
slime@2
|
415 |
cout << "5\tshow test picture 1 (240x64px)" << endl;
|
slime@2
|
416 |
cout << "6\tshow test picture 2 - horizontal lines (240x64px)" << endl;
|
slime@2
|
417 |
cout << "7\tshow test picture 3 - vertical lines (240x64px)" << endl;
|
slime@2
|
418 |
cout << "8\tshow test picture 4 - Boxes (240x64px)" << endl;
|
slime@2
|
419 |
cout << "9\tshow test picture 5 - outline + center cross (240x64px)" << endl;
|
slime@2
|
420 |
cout << endl;
|
slime@2
|
421 |
cout << "c\tclear display" << endl;
|
slime@2
|
422 |
cout << endl;
|
slime@2
|
423 |
cout << "h\tprint this help" << endl;
|
slime@2
|
424 |
cout << "j\tprint command line options" << endl;
|
slime@2
|
425 |
cout << "q\tquit" << endl;
|
slime@2
|
426 |
cout << ">";
|
slime@2
|
427 |
}
|
slime@2
|
428 |
|
slime@2
|
429 |
/*! \brief prints command line options
|
slime@2
|
430 |
*/
|
slime@2
|
431 |
void print_cli_options() {
|
slime@2
|
432 |
cout << endl
|
slime@2
|
433 |
<< " Command line options:\n"
|
slime@2
|
434 |
<< endl;
|
slime@2
|
435 |
cout << "d DEVICE\n"
|
slime@2
|
436 |
<< "\tSets the display device to DEVICE, default value is /dev/ttyACM0\n"
|
slime@2
|
437 |
<< "\tExample:\n"
|
slime@2
|
438 |
<< "\tpicctldisplaytest d /dev/ttyACM0\n"
|
slime@2
|
439 |
<< endl;
|
slime@2
|
440 |
cout << "v VERBOSITY\n"
|
slime@2
|
441 |
<< "\tSets verbosity to level VERBOSITY ( Range: 0-2, default 0 )\n"
|
slime@2
|
442 |
<< "\tExample:\n"
|
slime@2
|
443 |
<< "\tpicctldisplaytest v 1\n"
|
slime@2
|
444 |
<< endl;
|
slime@2
|
445 |
cout << "D\n"
|
slime@2
|
446 |
<< "\tRun in debugging mode (aka. very verbose)\n"
|
slime@2
|
447 |
<< "\tExample:\n"
|
slime@2
|
448 |
<< "\tpicctldisplaytest D\n"
|
slime@2
|
449 |
<< endl;
|
slime@2
|
450 |
cout << "Combining command line options\n"
|
slime@2
|
451 |
<< "\tAll command line options can be combined (though some combinations might not prove useful).\n"
|
slime@2
|
452 |
<< "\tExample:\n"
|
slime@2
|
453 |
<< "\tpicctldisplaytest D d /dev/ttyACM0\n"
|
slime@2
|
454 |
<< endl;
|
slime@2
|
455 |
}
|
slime@2
|
456 |
|
slime@2
|
457 |
/*! \brief encodes an integer to a BCD value
|
slime@2
|
458 |
*/
|
slime@2
|
459 |
int dec2bcd(int decimal) {
|
slime@2
|
460 |
return (decimal > 99 ? false : ((decimal/10)<<4)+(decimal%10));
|
slime@2
|
461 |
}
|
slime@2
|
462 |
|
slime@2
|
463 |
/*! \brief decodes a BCD value and returns it as integer
|
slime@2
|
464 |
*/
|
slime@2
|
465 |
int bcd2dec(int bcd) {
|
slime@2
|
466 |
return (((bcd>>4)*10)+bcd%16);
|
slime@2
|
467 |
}
|
slime@2
|
468 |
|
slime@2
|
469 |
/*! \brief handles SIGIO
|
slime@2
|
470 |
*/
|
slime@2
|
471 |
void signal_handler_IO (int status) {
|
slime@2
|
472 |
|
slime@2
|
473 |
unsigned char buf[255];
|
slime@2
|
474 |
int res = read(fd,buf,255);
|
slime@2
|
475 |
|
slime@2
|
476 |
if (myconfig.debug || myconfig.verbosity > 0) {
|
slime@2
|
477 |
//cout << "Received Data\n";
|
slime@2
|
478 |
if (buf[0] == 0x55) {
|
slime@2
|
479 |
switch (buf[1]) {
|
slime@2
|
480 |
case 0x01:
|
slime@2
|
481 |
cout << "Received an ACK packet, payload: " << (int) buf[3] << " bytes." << endl;
|
slime@2
|
482 |
break;
|
slime@2
|
483 |
case 0x02:
|
slime@2
|
484 |
cout << "Received a NACK packet." << endl;
|
slime@2
|
485 |
break;
|
slime@2
|
486 |
case 0xFF:
|
slime@2
|
487 |
cout << "Received COMMAND NOT IMPLEMENTED." << endl;
|
slime@2
|
488 |
break;
|
slime@2
|
489 |
case 0x10:
|
slime@2
|
490 |
cout << "Received IR/Key data." << endl;
|
slime@2
|
491 |
break;
|
slime@2
|
492 |
default:
|
slime@2
|
493 |
cout <<"Unknown Response code 0x" << hex << buf[1] << endl;
|
slime@2
|
494 |
break;
|
slime@2
|
495 |
}
|
slime@2
|
496 |
}
|
slime@2
|
497 |
|
slime@2
|
498 |
}
|
slime@2
|
499 |
if (myflags.parse_return_clockram || myconfig.debug || myconfig.verbosity > 1) {
|
slime@2
|
500 |
for (int i=0; i<res; i++) {
|
slime@2
|
501 |
cout << "0x" << ((int) buf[i] < 10 ? "0" : "") << hex << (int) buf[i] << " ";
|
slime@2
|
502 |
if (myflags.parse_return_clockram && i > 3) {
|
slime@2
|
503 |
switch (i) {
|
slime@2
|
504 |
case 4:
|
slime@2
|
505 |
cout << "(ctrl: " << dec << bcd2dec((int) buf[i]) << ") ";
|
slime@2
|
506 |
break;
|
slime@2
|
507 |
case 5:
|
slime@2
|
508 |
cout << "(1/100s: " << dec << bcd2dec((int) buf[i]) << ") ";
|
slime@2
|
509 |
break;
|
slime@2
|
510 |
case 6:
|
slime@2
|
511 |
cout << "(sec: " << dec << bcd2dec((int) buf[i]) << ") ";
|
slime@2
|
512 |
break;
|
slime@2
|
513 |
case 7:
|
slime@2
|
514 |
cout << "(min: " << dec << bcd2dec((int) buf[i]) << ") ";
|
slime@2
|
515 |
break;
|
slime@2
|
516 |
case 8:
|
slime@2
|
517 |
cout << "(hours: " << dec << bcd2dec((int) buf[i]) << ") ";
|
slime@2
|
518 |
break;
|
slime@2
|
519 |
case 9:
|
slime@2
|
520 |
cout << "(year/date: " << dec << bcd2dec((int) buf[i]) << ") ";
|
slime@2
|
521 |
break;
|
slime@2
|
522 |
case 10:
|
slime@2
|
523 |
cout << "(wday/month: " << dec << bcd2dec((int) buf[i]) << ") ";
|
slime@2
|
524 |
break;
|
slime@2
|
525 |
case 11:
|
slime@2
|
526 |
cout << "(timer day: " << dec << bcd2dec((int) buf[i]) << ") ";
|
slime@2
|
527 |
break;
|
slime@2
|
528 |
case 12:
|
slime@2
|
529 |
cout << "(alarm ctrl: " << dec << bcd2dec((int) buf[i]) << ") ";
|
slime@2
|
530 |
break;
|
slime@2
|
531 |
default:
|
slime@2
|
532 |
cout << "(bcd2int: " << dec << bcd2dec((int) buf[i]) << ") ";
|
slime@2
|
533 |
break;
|
slime@2
|
534 |
}
|
slime@2
|
535 |
}
|
slime@2
|
536 |
if (i == 3 || (i+3)%8==0) cout << endl;
|
slime@2
|
537 |
}
|
slime@2
|
538 |
cout << endl;
|
slime@2
|
539 |
}
|
slime@2
|
540 |
if (myconfig.debug || myconfig.verbosity > 0) cout << dec << res << " bytes received.\n";
|
slime@2
|
541 |
}
|