tools/picctldisplaytest/src/picctldisplaytest.cpp
author slime@unimatrix01.gamma-quadrant.de
Tue, 29 Jan 2008 22:31:52 +0100
changeset 2 2f55e5dd591d
child 31 4567e7bc404c
permissions -rw-r--r--
inital checkin
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
}